Building custom widgets with the Zinzala SDK - page 4
The final touch to img2res
What's left to do in img2res is to use the 2 functions we implemented above:
int main(int argc,char **argv)
{
tColor lPalette[256];
tChar lFilename[256];
cBitmap* lBitmap;
cFile lHeader;
cFile lCode;
tChar* lName;
tErr lErr;
if(argc<3)
{
printf("Usage : <filename> (<image> <label>)+\n");
return 1;
}
lName = argv[1];
// create header file
sprintf(lFilename,"%s.h",lName);
lErr = lHeader.Open(lFilename,kFileWrite | kFileTrunc);
if(lErr)
return 1;
// create code file
sprintf(lFilename,"%s.cpp",lName);
lErr = lCode.Open(lFilename,kFileWrite | kFileTrunc);
if(lErr)
{
lHeader.Close();
return 1;
}
To create and fill both C++ and header files, we use the class cFile. This class provides writing and/or reading in a file.
lHeader.Write("#ifndef _RES_%s\n",lName);
lHeader.Write("#define _RES_%s\n\n",lName);
lHeader.Write("#include <Cincinella/Types.h>\n\n");
lHeader.Write("using namespace zSDK::Cincinella;\n\n");
lHeader.Write("typedef struct tBitmapResource {\n");
lHeader.Write("\ttUint32 iWidth;\n");
lHeader.Write("\ttUint32 iHeight;\n");
lHeader.Write("\ttUint32 iIndex;\n");
lHeader.Write("\ttUint16 iColors;\n");
lHeader.Write("\ttUint32 iLength;\n");
lHeader.Write("\ttUint8* iBits;\n");
lHeader.Write("\ttUint32* iPalette;\n");
lHeader.Write("} tBitmapResource;\n\n");
In the header file we output the definition of the type tBitmapResource.
lCode.Write("#include <Cincinella/Types.h>\n\n");
lCode.Write("#include <%s.h>\n\n",lName);
lCode.Write("using namespace zSDK::Cincinella;\n\n");
for(int i=2;i<argc;i+=2)
{
printf("loading %s ...\n",argv[i]);
lBitmap = LoadBitmap(argv[i]);
For each graphic file given in the command line, we will try to load it. If this is successful and the bitmap is palette-based, then we will process it further:
if(lBitmap)
{
if(lBitmap->GetColorSpace() == eSpaceColor8Bit)
{
tUint16 lWidth,lHeight;
tUint16 lColors = lBitmap->CountColors();
lBitmap->GetSize(lWidth,lHeight);
printf("bitmap is %dx%d pixels and have %d colors\n",lWidth,lHeight,lColors);
if(!lBitmap->GetPalette(lPalette))
{
DumpBitmapToFile(lHeader,lCode,lBitmap,lPalette,lColors,argv[i+1]);
printf("dumped\n");
}
else
printf("failed to get the colors palette\n");
}
else
printf("sorry this isn't a palette based image!\n");
}
else
printf("failed\n");
}
// fill files with closing stuff
lHeader.Write("\n");
lHeader.Write("#endif\n");
// and close them
lHeader.Close();
lCode.Close();
return 0;
}
To simplify things, I created a simple shell script to rebuild a C++ file from the graphics whenever we needed to. We would need to do this when the graphic team modifies some of them, or when we create a new skin:
#/bin/sh
img2res Bitmaps \
Images/background.gif Background \
Images/dimmed.gif Dimmed \
Images/normal.gif Normal \
Images/pressed.gif Pressed \
Images/animate2.gif Animate1 \
Images/animate3.gif Animate2 \
Images/animate4.gif Animate3 \
Images/forward.gif ForwardN \
Images/forward_dim.gif ForwardD \
Images/pause.gif PauseN \
Images/pause_dim.gif PauseD \
Images/play.gif PlayN \
Images/play_dim.gif PlayD \
Images/rewind.gif BackwardN \
Images/rewind_dim.gif BackwardD \
Images/stop.gif StopN \
Images/stop_dim.gif StopD
When creating a new skin, even if the name of each graphic file needs to be changed, the resource name should stay the same in order to keep the necessary adaptations from a skin to another as small as possible.
You can have a look at the complete source code of img2res, as well as an example of the header and source file generated by this tool.
Skin as shared object
Now that we have all our graphics neatly packed away in a C++ file, it is time to see how we are going to integrate it to a shared object. To help us load a shared object later on, we will be using the class cAddOn, provided by the Zinzala SDK. This class is more or less a simple wrapper around the famous function dlopen().
Previous | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | Next
Print version