/****** 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) { }