235 lines
7.2 KiB
C
235 lines
7.2 KiB
C
/******
|
|
******/
|
|
#include "../globals.h"
|
|
#include "interface.h"
|
|
|
|
int interfaceInit() {
|
|
g_video_width = 1024;
|
|
g_video_height = 768;
|
|
g_video_fullscreen = 0;
|
|
#if _WIN32 | _WIN64 | __APPLE__
|
|
SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER);
|
|
#else
|
|
SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER|SDL_INIT_EVENTTHREAD);
|
|
#endif
|
|
|
|
interfaceSetRenderer(R_OPENGL);
|
|
|
|
/* load our global fonts */
|
|
g_font_large = newFont();
|
|
loadFontFromMemory(g_font_large, badfont_large_png, badfont_large_png_length, 16, 32);
|
|
setFontScale(g_font_large, 2.0f, 2.0f);
|
|
g_font_medium = newFont();
|
|
loadFontFromMemory(g_font_medium, badfont_medium_png, badfont_medium_png_length, 16, 32);
|
|
setFontScale(g_font_medium, 2.0f, 2.0f);
|
|
|
|
/* load our ui sprites */
|
|
spritesheet_ui = newSpritesheet();
|
|
loadSpritesheetFromMemory(spritesheet_ui, ui_png, ui_png_length, 64, 64, 8);
|
|
setSpritesheetScale(spritesheet_ui, 2.0f, 2.0f);
|
|
|
|
/* load menu bg */
|
|
menu_bg = newSpritesheet();
|
|
loadSpritesheetFromMemory(menu_bg, menu_bg_png, menu_bg_png_length, 640, 480, 1);
|
|
setSpritesheetScale(menu_bg, 2.0f, 2.0f);
|
|
|
|
/* set up our display */
|
|
g_r_Init();
|
|
g_screen = screen; // for state(s) to access 'em
|
|
SDL_Delay(100);
|
|
g_video_width = (SDL_GetVideoSurface())->w;
|
|
g_video_height = (SDL_GetVideoSurface())->h;
|
|
/* reinit to deal with some window managers on X */
|
|
g_r_Reinit();
|
|
|
|
SDL_WM_SetCaption("timesynk", NULL);
|
|
|
|
/* set our video tickrate/refresh vars */
|
|
vid_tickrate = (1000.0f/60.0f); // target 60 tickrate
|
|
g_tickrate = (1000/30); // update 30 times per second
|
|
g_accumulator = 0;
|
|
vid_frames = 0;
|
|
/* */
|
|
/* set up our tickrate into a PTime structure */
|
|
float tickrate = 1000.0f/60.0f;
|
|
printf("tickrate: %f\n", tickrate);
|
|
ftoi(tickrate, 6, &sleep_time.m, &sleep_time.n);
|
|
getTime(&start_time);
|
|
|
|
/* set up unicode, important to TSEvent */
|
|
SDL_EnableUNICODE(SDL_ENABLE);
|
|
|
|
/* load global elements, i.e., fps counter */
|
|
g_elements = newElementList();
|
|
struct Dimension dimen = { 0, 0, 128, 32 };
|
|
g_element_fps = newElement(E_TYPE_TEXT, 0, g_r_setupElement, dimen);
|
|
|
|
setElementValue(g_element_fps, 0);
|
|
setElementFont(g_element_fps, g_font_medium);
|
|
g_element_fps->target = g_screen;
|
|
addElementToList(g_elements, g_element_fps);
|
|
|
|
/* is it wrong to use function pointers to (vaguely) mimic Object oriented states? */
|
|
g_initState = initMenuState;
|
|
g_freeState = freeMenuState;
|
|
g_handleState = handleMenuState;
|
|
g_processState = processMenuState;
|
|
g_renderState = renderMenuState;
|
|
|
|
/* okay, load up our first state */
|
|
g_initState();
|
|
|
|
return 0;
|
|
}
|
|
|
|
int interfaceRun() {
|
|
struct PTime current_time;
|
|
struct PTime last_time;
|
|
struct PTime delta_time;
|
|
struct TSEvent ts_event;
|
|
SDL_Event event;
|
|
getTime(&last_time);
|
|
/* begin our main loop */
|
|
while(g_running) {
|
|
getTime(¤t_time);
|
|
|
|
delta_time.s = current_time.s - last_time.s;
|
|
delta_time.n = current_time.n - last_time.n;
|
|
delta_time.m = delta_time.n/1000000;
|
|
|
|
g_accumulator += delta_time.m;
|
|
|
|
while(SDL_PollEvent(&event)) {
|
|
switch(event.type) {
|
|
case SDL_KEYDOWN:
|
|
ts_event.type = TS_KEYBOARD;
|
|
ts_event.keyboard.key.scancode = event.key.keysym.scancode;
|
|
ts_event.keyboard.key.mod = event.key.keysym.mod;
|
|
ts_event.keyboard.key.sym = event.key.keysym.sym;
|
|
ts_event.keyboard.key.unicode = event.key.keysym.unicode;
|
|
ts_event.keyboard.state = TS_KEYDOWN;
|
|
g_handleState(ts_event);
|
|
break;
|
|
case SDL_MOUSEBUTTONDOWN:
|
|
case SDL_MOUSEBUTTONUP:
|
|
ts_event.type = TS_MOUSECLICK;
|
|
ts_event.mouseclick.button = event.button.button;
|
|
ts_event.mouseclick.state = event.button.state;
|
|
ts_event.mouseclick.x = event.button.x;
|
|
ts_event.mouseclick.y = event.button.y;
|
|
g_handleState(ts_event);
|
|
break;
|
|
// TODO: USER_EVENT will call here, with a subtype of GAME_TICK as called by subtype of NET_RECEIVE. Within GAME_TICK, we will run game logic (gameTick() or some such) if a game is indeed running.
|
|
case SDL_QUIT:
|
|
g_running = 0;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
/* do state processing */
|
|
g_processState(delta_time.m);
|
|
/* clear out the screen :) */
|
|
g_clearScreen();
|
|
g_renderSprite(menu_bg, screen, 0, 0, 0);
|
|
/* draw state */
|
|
g_renderState();
|
|
/* draw global elements */
|
|
g_renderElements(g_elements);
|
|
/* update fps counter */
|
|
vid_frames++;
|
|
if (current_time.s - count_time.s >= 1) {
|
|
long ms = (current_time.m-count_time.m)+(((float)(current_time.n)/1000000.0f-(float)(count_time.n)/1000000.0f));
|
|
float seconds = ms/1000.0f;
|
|
int fps = vid_frames / seconds;
|
|
count_time = current_time;
|
|
vid_frames = 0;
|
|
setElementValue(g_element_fps, fps);
|
|
}
|
|
/* render updates to screen */
|
|
g_renderScreen();
|
|
/* delay to framerate cap */
|
|
last_time = current_time;
|
|
doSleep(0, sleep_time.m - (delta_time.m-sleep_time.m), sleep_time.n - (delta_time.n-sleep_time.n));
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int interfaceClose() {
|
|
g_freeState();
|
|
g_r_Close();
|
|
SDL_FreeSurface(screen);
|
|
SDL_Quit();
|
|
return 0;
|
|
}
|
|
|
|
int interfaceSetVideo() {
|
|
if ((screen = SDL_SetVideoMode(g_video_width, g_video_height, 32, SDL_HWSURFACE|SDL_DOUBLEBUF|SDL_RESIZABLE|g_video_fullscreen)) == NULL){
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int interfaceSetRenderer(int render_id) {
|
|
switch(render_id) {
|
|
case R_OPENGL:
|
|
g_renderElements = &r_gl_renderElements;
|
|
g_renderElement = &r_gl_renderElement;
|
|
g_renderSprite = &r_gl_renderSprite;
|
|
g_r_Init = &r_gl_Init;
|
|
g_r_Reinit = &r_gl_Init;
|
|
g_r_Close = &r_gl_Close;
|
|
g_renderScreen = &r_gl_renderScreen;
|
|
g_clearScreen = &r_gl_clearScreen;
|
|
g_r_setupElement = &r_gl_setupElement;
|
|
g_r_cleanElement = &r_gl_cleanElement;
|
|
return R_OPENGL;
|
|
break;
|
|
case R_SOFTWARE:
|
|
g_renderElements = &r_soft_renderElements;
|
|
g_renderElement = &r_soft_renderElement;
|
|
g_renderSprite = &r_soft_drawSprite;
|
|
g_r_Init = &r_soft_Init;
|
|
g_r_Reinit = &r_soft_Init;
|
|
g_r_Close = &r_soft_Close;
|
|
g_renderScreen = &r_soft_renderScreen;
|
|
g_clearScreen = &r_soft_clearScreen;
|
|
g_r_setupElement = &r_soft_setupElement;
|
|
g_r_cleanElement = &r_soft_cleanElement;
|
|
return R_SOFTWARE;
|
|
break;
|
|
default:
|
|
return -1;
|
|
break;
|
|
}
|
|
return -2;
|
|
}
|
|
|
|
void genElementDimensions(struct Element *element) {
|
|
if (element == NULL) return;
|
|
int width;
|
|
int height;
|
|
int temp = 0;
|
|
switch(element->type) {
|
|
case E_TYPE_TEXT:
|
|
element->dimen.w = ((struct TextElement *)element->data)->length * ((struct Font*)element->font)->s_width;
|
|
element->dimen.h = ((struct Font*)element->font)->s_height;
|
|
break;
|
|
case E_TYPE_BUTTON:
|
|
width = ((struct TextElement *)element->data)->length * ((struct Font*)element->font)->s_width + (6*spritesheet_ui->scale_x);
|
|
temp = spritesheet_ui->s_width*2; // minimum width
|
|
element->dimen.w = ( temp > width ? temp : width );
|
|
element->dimen.h = spritesheet_ui->s_height;
|
|
break;
|
|
}
|
|
}
|
|
|
|
int getElementX(struct Element *element) {
|
|
return element->dimen.x+(element->sx*(g_video_width/3));
|
|
}
|
|
|
|
int getElementY(struct Element *element) {
|
|
return element->dimen.y+(element->sy*(g_video_height/3));
|
|
}
|