timesynk/engine/sdl/interface.c

172 lines
4.9 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);
/* 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_start_time = SDL_GetTicks();
vid_tickrate = (1000/60); // target 60 tickrate
vid_current_time = vid_start_time;
vid_last_time = vid_start_time;
vid_delta = 0;
vid_frames = 0;
/* set up unicode, important to TSEvent */
SDL_EnableUNICODE(SDL_ENABLE);
/* load our global fonts */
g_font_large = newFont();
loadFontFromMemory(g_font_large, badfont_large_png, badfont_large_png_length, 16, 32);
g_font_medium = newFont();
loadFontFromMemory(g_font_medium, badfont_medium_png, badfont_medium_png_length, 16, 32);
/* 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, E_STATE_NORMAL, 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);
dimen.x = g_video_width/2;
dimen.y = g_video_height/2;
struct Element *element = newElement(E_TYPE_TEXT, 1, E_STATE_NORMAL, dimen);
setElementText(element, "TESTING :)");
//setElementValue(element, 10);
setElementFont(element, g_font_large);
element->target = g_screen;
addElementToList(g_elements, element);
/* 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;
/* okay, load up our first state */
g_initState();
return 0;
}
int interfaceRun() {
struct TSEvent ts_event;
SDL_Event event;
/* begin our main loop */
while(g_running) {
vid_current_time = SDL_GetTicks();
int delta = vid_current_time - vid_last_time;
vid_delta = delta;
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;
// 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;
}
}
/* clear out the screen :) */
g_clearScreen();
/* do state processing, includes rendering */
g_processState(delta);
/* draw global elements */
g_renderElements(g_elements);
/* update fps counter */
vid_frames++;
if (vid_current_time - vid_frame_time >= 100) {
float seconds = (vid_current_time - vid_frame_time) / 1000.0f;
int fps = vid_frames / seconds;
vid_frame_time = vid_current_time;
vid_frames = 0;
setElementValue(g_element_fps, fps);
}
/* render updates to screen */
g_renderScreen();
/* delay to framerate cap */
vid_last_time = vid_current_time;
if (vid_delta > vid_tickrate)
vid_delta = vid_tickrate;
SDL_Delay(vid_tickrate - vid_delta);
}
return 0;
}
int interfaceClose() {
SDL_FreeSurface(screen);
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_r_Init = &r_gl_Init;
g_r_Reinit = &r_gl_Init;
g_renderScreen = &r_gl_renderScreen;
g_clearScreen = &r_gl_clearScreen;
return R_OPENGL;
break;
case R_SOFTWARE:
g_renderElements = &r_soft_renderElements;
g_renderElement = &r_soft_renderElement;
g_r_Init = &r_soft_Init;
g_r_Reinit = &r_soft_Init;
g_renderScreen = &r_soft_renderScreen;
g_clearScreen = &r_soft_clearScreen;
return R_SOFTWARE;
break;
default:
return -1;
break;
}
return -2;
}