425 lines
14 KiB
C
425 lines
14 KiB
C
#include <SDL/SDL.h>
|
|
#if !defined (__APPLE__)
|
|
#include <SDL/SDL_image.h>
|
|
#else
|
|
#include <SDL_image.h>
|
|
#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);
|
|
}
|