Back in 2012/2013 I was writing the C/C++/C# column for About.com and I was doing games tutorials with SDL. This is an Empire type game, much like the Z80 game I mentioned in yesterday’s post except coded in C and with hexagons instead of squares.
It is not complete but includes a working map generator and a simple GUI that I devised based on a very crude OOP type of coding using function pointers and macros.
I’ve put it on the C Games repository and In the empire9src.zip (in the aboutempire.zip) file you’ll see sdlgui.h and c. These implement it and (years ahead of Flutter and Dart!) it redraws the GUI at 60 fps. The controls are built in a linked list of sdlcontrols. This is a sdlbase which is the base for all controls.
#define sdlbase enum controltype ctype;\
int x,y,width,height,color,clickable;\
SDL_Color textcolor;\
void (*pRender)(struct sdlcontrol * self);\
void (*pFree)(struct sdlcontrol * self);\
void (*pClick)(struct sdlcontrol * self);\
void (*pPreClick)(struct sdlcontrol * self);\
struct sdlcontrol * nextcontrol
The four void (*..) are the function pointers. The pRender function draws the controls, pFree frees it up.. pClick handles clicks and PreClick provides extra functionality.
struct sdlcontrol { sdlbase; };
typedef struct sdlcontrol * psdlcontrol;
typedef char * pchar;
struct sdlbutton {
sdlbase;
pchar labeltext;
int isDown;
int countDown;
};
struct sdllabel {
sdlbase;
pchar labeltext;
};
Those are the definitions for sdlbutton and sdllabel and all controls have sdlbase (Everything in the big macro) and additional info.
This is the code that rendered a label.
void RenderLabel(psdlcontrol self) {
int result,x,y;
char buff[60];
struct sdllabel * label= (struct sdllabel *)self;
SDL_Rect rect = {(Sint16)self->x,(Sint16)self->y,(Uint16)self->width,(Uint16)self->height};
x= self->x;
y=self->y;
result=SDL_FillRect( screen, &rect, self->color );
sprintf(buff,"%s",label->labeltext);
ttf_print(x+2,y+2,buff,self->textcolor);
}
So every frame, the program would render all controls to the off-screen buffer by walking the linked list of controls and calling the pRender pointer for each. For buttons this would include a simple animation to show the button being clicked down and then released etc.
If you’ve ever wondered how a GUI is implemented take a look at the code. The sdlgui.c is less than 600 lines but manages to do panels, buttons, labels, checkbox, listbox and images.