#include #if !defined (__APPLE__) #include #else #include #endif #include "stubs.h" #include "sdl.h" #include "assets.h" #include "elements.h" #include "font.h" int interfaceInit() { // since we use threads, Mac OS 10+ support only. Also threaded os. SDL_Init(SDL_INIT_VIDEO); // Enable Unicode, for later text input SDL_EnableUNICODE(SDL_ENABLE); // Set up our SDL Window if ((screen = SDL_SetVideoMode(320, 480, 32, SDL_SWSURFACE|SDL_DOUBLEBUF|SDL_RESIZABLE)) == NULL) { return -1; } SDL_WM_SetCaption("Tile Editor", NULL); menu_area = SDL_CreateRGBSurface(screen->flags, screen->w, 104, screen->format->BitsPerPixel, screen->format->Rmask, screen->format->Gmask, screen->format->Bmask, screen->format->Amask); tile_area_rect.y = 104; tile_area = SDL_CreateRGBSurface(screen->flags, screen->w, 384, screen->format->BitsPerPixel, screen->format->Rmask, screen->format->Gmask, screen->format->Bmask, screen->format->Amask); loadFont(&font, font_images, font_images_length, 8, 8); first_element = NULL; // load up our elements button_quit = newElement(TYPE_BUTTON); setElementText(button_quit, "QUIT"); setElementPosition(button_quit, screen->w - getElementWidth(button_quit)-2, 2); setElementCallback(button_quit, &Quit); addElement(button_quit, menu_area); text_console = newElement(TYPE_TEXT); setElementPosition(text_console, 0, 0); addElement(text_console, menu_area); /* graphics input */ text_graphics = newElement(TYPE_TEXT); setElementText(text_graphics, "graphics:"); setElementPosition(text_graphics, 2, 2 + font.height*3); addElement(text_graphics, menu_area); input_graphics = newElement(TYPE_TEXT_INPUT); setElementPosition(input_graphics, getElementWidth(text_graphics) + font.width + 4, 2 + font.height*3); setElementSize(input_graphics, 16); addElement(input_graphics, menu_area); button_graphics = newElement(TYPE_BUTTON); setElementText(button_graphics, "load"); setElementPosition(button_graphics, getElementWidth(text_graphics) + getElementWidth(input_graphics) + (font.width*2) + 4, 2 + font.height*3); setElementCallback(button_graphics, &loadGraphicsCallback); addElement(button_graphics, menu_area); /* tileset data input */ text_data = newElement(TYPE_TEXT); setElementText(text_data, "data: "); setElementPosition(text_data, 2, 2 + font.height*5); addElement(text_data, menu_area); input_data = newElement(TYPE_TEXT_INPUT); setElementPosition(input_data, getElementWidth(text_data) + font.width + 4, 2 + font.height*5); setElementSize(input_data, 16); addElement(input_data, menu_area); button_data = newElement(TYPE_BUTTON); setElementText(button_data, "load"); setElementPosition(button_data, getElementWidth(text_data) + getElementWidth(input_data) + (font.width*2) + 4, 2 + font.height*5); setElementCallback(button_data, &loadDataCallback); addElement(button_data, menu_area); button_data_save = newElement(TYPE_BUTTON); setElementText(button_data_save, "save"); setElementPosition(button_data_save, getElementWidth(text_data) + getElementWidth(input_data) + getElementWidth(button_data) + (font.width*3) + 4, 2 + font.height*5); setElementCallback(button_data_save, &saveDataCallback); addElement(button_data_save, menu_area); /* set input */ text_set = newElement(TYPE_TEXT); setElementText(text_set, "set:"); setElementPosition(text_set, 2, 2 + font.height*8); addElement(text_set, menu_area); input_set = newElement(TYPE_TEXT_INPUT); setElementPosition(input_set, getElementWidth(text_set) + font.width + 4, 2 + font.height*8); setElementSize(input_set, 3); addElement(input_set, menu_area); button_set = newElement(TYPE_BUTTON); setElementText(button_set, "ok"); setElementPosition(button_set, getElementWidth(text_set) + getElementWidth(input_set) + (font.width*2) + 4, 2 + font.height*8); setElementCallback(button_set, &setSetCallback); addElement(button_set, menu_area); /* tile id input */ text_id = newElement(TYPE_TEXT); setElementText(text_id, "id: "); setElementPosition(text_id, 2, 2 + font.height*10); addElement(text_id, menu_area); input_id = newElement(TYPE_TEXT_INPUT); setElementPosition(input_id, getElementWidth(text_id) + font.width + 4, 2 + font.height*10); setElementSize(input_id, 3); addElement(input_id, menu_area); button_id = newElement(TYPE_BUTTON); setElementText(button_id, "ok"); setElementPosition(button_id, getElementWidth(text_id) + getElementWidth(input_id) + (font.width*2) + 4, 2 + font.height*10); setElementCallback(button_id, &setIdCallback); addElement(button_id, menu_area); SDL_FillRect(menu_area, NULL, SDL_MapRGB(menu_area->format, 8, 16, 12)); SDL_Rect tile_rect = { getElementWidth(button_id) + getElementWidth(text_id) + getElementWidth(input_id) + (font.width*3) + 4, 2 + font.height*8, 32, 32}; SDL_FillRect(menu_area, &tile_rect, SDL_MapRGB(menu_area->format, 0, 0, 0)); drawElement(button_quit); drawElement(text_graphics); drawElement(input_graphics); drawElement(button_graphics); drawElement(text_data); drawElement(input_data); drawElement(button_data); drawElement(button_data_save); drawElement(text_set); drawElement(input_set); drawElement(button_set); drawElement(text_id); drawElement(input_id); drawElement(button_id); clearElement(text_console); setElementText(text_console, "welcome to the tile editor"); drawElement(text_console); SDL_BlitSurface(menu_area, NULL, screen, NULL); /* now load up our tile area stuff */ text_name = newElement(TYPE_TEXT); setElementText(text_name, "...... name ......"); setElementPosition(text_name, 2, 2); addElement(text_name, tile_area); text_value = newElement(TYPE_TEXT); setElementText(text_value, "...... value ......"); setElementPosition(text_value, 2 + (20 * font.width), 2); addElement(text_value, tile_area); drawElement(text_name); drawElement(text_value); SDL_BlitSurface(tile_area, NULL, screen, &tile_area_rect); SDL_Flip(screen); return 0; } int interfaceLoop() { while (SDL_WaitEvent(&event)) { switch(event.type) { case SDL_QUIT: return 0; break; case SDL_MOUSEBUTTONDOWN: handleMouseDown(&event.button); break; case SDL_MOUSEBUTTONUP: handleMouseUp(&event.button); break; case SDL_MOUSEMOTION: handleMouseMove(&event.motion); break; default: break; } //SDL_BlitSurface(menu_area, &update_rect, screen, &update_rect); SDL_BlitSurface(menu_area, NULL, screen, NULL); SDL_Flip(screen); } return 0; } void interfaceClose() { SDL_FreeSurface(screen); SDL_Quit(); } void Quit() { SDL_Event event; event.type = SDL_QUIT; SDL_PushEvent(&event); } void addElement(struct Element *element, SDL_Surface *surface) { if (first_element == NULL) { first_element = element; } else { struct Element *t_element = first_element; while (t_element->next != NULL) { t_element = t_element->next; } t_element->next = element; } element->user = surface; } /* drawing functions */ void drawElement(const struct Element *element) { if (element != NULL) { SDL_Rect get_rect_son = {element->x, element->y, 0, 0}; switch (element->type) { case TYPE_BUTTON: // clear area get_rect_son.w = (font.width * ((struct ButtonElement*)element->data)->length) + 4; get_rect_son.h = font.height + 4; SDL_FillRect(element->user, &get_rect_son, SDL_MapRGB(((SDL_Surface*)element->user)->format, 8, 16, 12)); if (element->state == STATE_NORMAL) { get_rect_son.w = (font.width * ((struct ButtonElement*)element->data)->length) + 2; get_rect_son.h = font.height + 2; SDL_FillRect(element->user, &get_rect_son, SDL_MapRGB(((SDL_Surface*)element->user)->format, 32, 32, 48)); get_rect_son.x = element->x+2; get_rect_son.y = element->y+2; SDL_FillRect(element->user, &get_rect_son, SDL_MapRGB(((SDL_Surface*)element->user)->format, 48, 48, 64)); drawString(&font, element->user, element->x+3, element->y+3, ((struct ButtonElement*)element->data)->string); } else if (element->state == STATE_PRESSED) { get_rect_son.w = (font.width * ((struct ButtonElement*)element->data)->length) + 2; get_rect_son.h = font.height + 2; SDL_FillRect(element->user, &get_rect_son, SDL_MapRGB(((SDL_Surface*)element->user)->format, 32, 32, 48)); get_rect_son.x = element->x+1; get_rect_son.y = element->y+1; get_rect_son.w = (font.width * ((struct ButtonElement*)element->data)->length) + 2; get_rect_son.h = font.height + 2; SDL_FillRect(element->user, &get_rect_son, SDL_MapRGB(((SDL_Surface*)element->user)->format, 48, 48, 64)); drawString(&font, element->user, element->x+2, element->y+2, ((struct ButtonElement*)element->data)->string); } break; case TYPE_TEXT: get_rect_son.w = (font.width * ((struct TextElement*)element->data)->length) + 2; get_rect_son.h = font.height + 2; SDL_FillRect(element->user, &get_rect_son, SDL_MapRGB(((SDL_Surface*)element->user)->format, 32, 32, 48)); drawString(&font, element->user, element->x+1, element->y+1, ((struct TextElement*)element->data)->string); break; case TYPE_TEXT_INPUT: get_rect_son.x = element->x-1; get_rect_son.y = element->y-1; get_rect_son.w = (font.width * ((struct TextInputElement*)element->data)->size) + 4; get_rect_son.h = font.height + 4; SDL_FillRect(element->user, &get_rect_son, SDL_MapRGB(((SDL_Surface*)element->user)->format, 48, 48, 64)); get_rect_son.x = element->x; get_rect_son.y = element->y; get_rect_son.w = (font.width * ((struct TextInputElement*)element->data)->size) + 2; get_rect_son.h = font.height + 2; SDL_FillRect(element->user, &get_rect_son, SDL_MapRGB(((SDL_Surface*)element->user)->format, 32, 32, 48)); break; } } } void drawChar(const struct Font *font, SDL_Surface *surface, int x, int y, const char ch) { int y_offset = ch / 16; int x_offset = ch - (y_offset*16); SDL_Rect character_offset = { x_offset*font->width, y_offset*font->height, font->width, font->height}; SDL_Rect render_position = {x, y, font->width, font->height}; SDL_BlitSurface(font->surface, &character_offset, surface, &render_position); } void drawString(const struct Font *font, SDL_Surface *surface, int x, int y, const char *string) { int i = 0; while (string[i] != '\0') { drawChar(font, surface, x + (i*font->width), y, string[i]); i++; } } void clearElement(const struct Element* element) { SDL_Rect clear_rect = { element->x, element->y, getElementWidth(element), getElementHeight(element) }; SDL_FillRect(element->user, &clear_rect, SDL_MapRGB(screen->format, 8, 16, 12)); } /* Element information functions */ int getElementWidth(const struct Element* element) { switch (element->type) { case TYPE_TEXT_INPUT: return (font.width * ((struct TextInputElement*)element->data)->size) + 4; break; case TYPE_TEXT: return (font.width * ((struct TextElement*)element->data)->length) + 2; break; case TYPE_BUTTON: return (font.width * ((struct ButtonElement*)element->data)->length) + 4; break; default: break; } return 0; } int getElementHeight(const struct Element* element) { switch (element->type) { case TYPE_TEXT_INPUT: return font.height+4; break; case TYPE_TEXT: return font.height*2; break; case TYPE_BUTTON: return font.height + 4; break; default: break; } return 0; } /* begin handler functions */ void handleMouseDown(const SDL_MouseButtonEvent *event) { struct Element *element = first_element; int t_x, t_y, t_w, t_h = 0; while (element != NULL) { switch (element->type) { case TYPE_BUTTON: t_w = element->x+2 +(font.width * ((struct ButtonElement*)element->data)->length) + 2; t_h = element->y+2 + font.height + 2; t_x = element->x+2; t_y = element->y+2; break; } if ((t_x <= event->x && t_w >= event->x) && (t_y <= event->y && t_h >= event->y)) { element->state = STATE_PRESSED; last_element = element; drawElement(element); break; } element = element->next; } update_rect.x = t_x-2; update_rect.y = t_y-2; update_rect.w = t_w+2; update_rect.h = t_h+2; } void handleMouseUp(const SDL_MouseButtonEvent *event) { if (last_element != NULL) { int t_x, t_y, t_w, t_h = 0; switch (last_element->type) { case TYPE_BUTTON: t_w = last_element->x+2 +(font.width * ((struct ButtonElement*)last_element->data)->length) + 2; t_h = last_element->y+2 + font.height + 2; t_x = last_element->x+2; t_y = last_element->y+2; break; } last_element->state = STATE_NORMAL; drawElement(last_element); if ((t_x <= event->x && t_w >= event->x) && (t_y <= event->y && t_h >= event->y)) { if (last_element->callback != NULL) { last_element->callback(); } } update_rect.x = t_x-2; update_rect.y = t_y-2; update_rect.w = t_w+2; update_rect.h = t_h+2; } } void handleMouseMove(const SDL_MouseMotionEvent *event) { } /* button callback */ void loadGraphicsCallback() { clearElement(text_console); setElementText(text_console, "loading gfx"); drawElement(text_console); } void loadDataCallback() { clearElement(text_console); setElementText(text_console, "loading data"); drawElement(text_console); } void saveDataCallback() { clearElement(text_console); setElementText(text_console, "saving data"); drawElement(text_console); } void setSetCallback() { char temp[16]; sprintf(temp, "OK: using set %s", getElementText(input_set)); clearElement(text_console); setElementText(text_console, temp); drawElement(text_console); } void setIdCallback() { char temp[16]; sprintf(temp, "OK: using id %s", getElementText(input_id)); clearElement(text_console); setElementText(text_console, temp); drawElement(text_console); } /* font stuff */ void loadFont(struct Font *font, unsigned char *memory, unsigned int length, int width, int height) { font->width = width; font->height = height; font->surface = IMG_Load_RW(SDL_RWFromMem(memory, length), 1); } void freeFont(struct Font *font) { SDL_FreeSurface(font->surface); }