timesynk/engine/sdl/r_soft.c

171 lines
6.2 KiB
C

/******
SDL "software" renderer functions
******/
#include "../ui/elements.h"
#include "r_soft.h"
#include "interface.h"
#include "../globals.h"
void r_soft_Init() {
if ((screen = SDL_SetVideoMode(g_video_width, g_video_height, 32, SDL_HWSURFACE|SDL_DOUBLEBUF|SDL_RESIZABLE|g_video_fullscreen)) == NULL)
return;
}
void r_soft_Reinit() {
if ((screen = SDL_SetVideoMode(g_video_width, g_video_height, 32, SDL_HWSURFACE|SDL_DOUBLEBUF|SDL_RESIZABLE|g_video_fullscreen)) == NULL)
return;
}
void r_soft_Close() {
SDL_FreeSurface(screen);
}
void r_soft_clearScreen() {
/* struct Element *current = g_elements->first;
while(current) {
struct Element *next = current->next;
if (current->flags & E_FLAG_UPDATE) {
SDL_Rect rect = { current->dimen.x, current->dimen.y, current->dimen.w, current->dimen.h };
SDL_FillRect(screen, &rect, SDL_MapRGB(screen->format, 32, 128, 64));
}
current = next;
}*/
SDL_FillRect(screen, NULL, 0); // clear our surface
}
void r_soft_renderScreen() {
if (SDL_Flip(screen) != 0) {
printf("ERROR: %s\n", SDL_GetError());
}
}
/* the blit functions blit the Element's self surface to the surface pointed to by target. */
void r_soft_renderElements(struct ElementList *list) {
if (list == NULL)
return;
struct Element *current = list->first;
while(current != NULL) {
struct Element *next = current->next;
r_soft_renderElement(current);
current = next;
}
}
void r_soft_renderElement(struct Element *element) {
if (element == NULL)
return;
if (element->flags & E_FLAG_HIDE || element->target == NULL)
return;
if (element->flags & E_FLAG_UPDATE)
r_soft_drawElement(element);
int start_x = element->sx*(g_video_width/3);
int start_y = element->sy*(g_video_height/3);
SDL_Rect rect = { element->dimen.x+start_x, element->dimen.y+start_y, element->dimen.w, element->dimen.h };
SDL_BlitSurface(element->self, NULL, element->target, &rect);
}
/* draw functions. Creates an SDL_Surface pointed to by the Element's self void pointer then draws to that surface */
void r_soft_drawElement(struct Element *element) {
//int x_start = element->sx*(g_video_width/3);
//int y_start = element->sy*(g_video_height/3);
int sprite_id = 0;
int x_offset = 0;
//int y_offset = 0;
/* free surface if already created */
if (element->self != NULL)
SDL_FreeSurface(element->self);
/* create new surface according to dimensions */
SDL_Surface *e_surface = element->target;
element->self = SDL_CreateRGBSurface(e_surface->flags, element->dimen.w, element->dimen.h, e_surface->format->BitsPerPixel, e_surface->format->Rmask, e_surface->format->Gmask, e_surface->format->Bmask, screen->format->Amask);
SDL_SetColorKey(element->self, SDL_SRCCOLORKEY, 0xFF00FF);
/* clear surface */
SDL_FillRect(element->self, NULL, 0XFF00FF);
/* draw our element's surface based upon type and state */
switch (element->type) {
case E_TYPE_TEXT:
r_soft_drawText(element->self, element->font, ((struct TextElement*)element->data)->string, 0, 0);
break;
case E_TYPE_BUTTON:
switch (element->state) {
case E_STATE_NORMAL:
break;
case E_STATE_ACTIVE:
sprite_id += spritesheet_ui->columns;
break;
}
int width = (element->dimen.w/spritesheet_ui->s_width-2);
r_soft_drawSprite(spritesheet_ui, element->self, sprite_id, x_offset, 0);
x_offset += spritesheet_ui->s_width;
for(width = (element->dimen.w/spritesheet_ui->s_width)-2; width > 0; width-=2) {
r_soft_drawSprite(spritesheet_ui, element->self, sprite_id+1, x_offset, 0);
x_offset += spritesheet_ui->s_width;
}
//r_soft_drawSprite(spritesheet_ui, element->self, sprite_id+1, x_offset, 0);
//x_offset += spritesheet_ui->s_width;
r_soft_drawSprite(spritesheet_ui, element->self, sprite_id+2, x_offset, 0);
//r_soft_drawText(element->self, element->font, ((struct ButtonElement*)element->data)->string, 6*spritesheet_ui->scale_x, 14*spritesheet_ui->scale_y);
r_soft_drawText(element->self, element->font, ((struct TextElement*)element->data)->string, ( (element->dimen.w/2) - (((struct Font*)element->font)->s_width * ((struct TextElement*)element->data)->length)/2 ), 14*spritesheet_ui->scale_y);
break;
default:
break;
}
/* now that we've redrawn the element, remove update flag */
element->flags &= ~(E_FLAG_UPDATE);
}
void r_soft_drawText(SDL_Surface *surface, struct Font *font, const char *string, int x, int y) {
if (font == NULL) return;
int i = 0;
int x_offset;
int y_offset;
int x_render = x;
int y_render = y;
//SDL_SetColorKey(font->s_surface, SDL_SRCCOLORKEY, 0xFF00FF);
while(string[i] != '\0') {
switch(string[i]) {
case '\n':
y_render += font->s_height;
x_render = x;
break;
default:
y_offset = string[i] / 16;
x_offset = string[i] - (y_offset*16);
SDL_Rect character_offset = { x_offset * font->s_width, y_offset * font->s_height, font->s_width, font->s_height };
SDL_Rect render_position = { x_render, y_render, font->s_width, font->s_height };
SDL_BlitSurface(font->s_surface, &character_offset, surface, &render_position);
x_render += font->s_width;
break;
}
i++;
}
}
void r_soft_drawSprite(struct Spritesheet *sheet, void *surface, int id, int x, int y) {
if (sheet == NULL) return;
int y_offset = id / sheet->columns;
int x_offset = id - (y_offset*sheet->columns);
SDL_Rect sprite_offset = { x_offset * sheet->s_width, y_offset * sheet->s_height, sheet->s_width, sheet->s_height };
SDL_Rect render_position = { x, y, sheet->s_width, sheet->s_height };
SDL_BlitSurface(sheet->s_surface, &sprite_offset, surface, &render_position);
}
/**** Callbacks for Elements ****/
void r_soft_setupElement(struct Element *element) {
// set default target surface to global screen
element->target = g_screen;
// set default font
setElementFont(element, g_font_medium);
// set our element's free/clean event function
setElementEvent(element, E_EVENT_FREE, &r_soft_cleanElement);
setElementEvent(element, E_EVENT_CHANGE, &genElementDimensions);
}
void r_soft_cleanElement(struct Element *element) {
}
void r_soft_changeElement(struct Element *element) {
}