257 lines
		
	
	
		
			8.3 KiB
		
	
	
	
		
			C
		
	
	
			
		
		
	
	
			257 lines
		
	
	
		
			8.3 KiB
		
	
	
	
		
			C
		
	
	
/******
 | 
						|
******/
 | 
						|
#include "../globals.h"
 | 
						|
#include "interface.h"
 | 
						|
#include "r_gl.h"
 | 
						|
#include "r_soft.h"
 | 
						|
 | 
						|
int interfaceInit() {
 | 
						|
  g_video_width = getTablePairValueInt(g_settings, "v_width");
 | 
						|
  g_video_height = getTablePairValueInt(g_settings, "v_height");
 | 
						|
  g_video_fullscreen = getTablePairValueInt(g_settings, "v_fullscreen");
 | 
						|
  #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(getTablePairValueInt(g_settings, "v_renderer"));
 | 
						|
 | 
						|
  /* 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, 1280, 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 / getTablePairValueFloat(g_settings, "v_fps")); // target 60 tickrate
 | 
						|
  g_cap_framerate = getTablePairValueInt(g_settings, "v_framecap");
 | 
						|
  setPTime(&g_tick_time, 0, 0, getTablePairValueInt(g_settings, "tickrate"));
 | 
						|
 | 
						|
  vid_frames = 0;
 | 
						|
  /* */
 | 
						|
  /* set up our tickrate into a PTime structure */
 | 
						|
  sleep_time.n = (1000000000/53);
 | 
						|
  sleep_time.m = sleep_time.n/1000000;
 | 
						|
  printf("tickrate: %ld\n", sleep_time.n);
 | 
						|
 | 
						|
  /* 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 = initModulesState;
 | 
						|
  g_freeState = freeModulesState;
 | 
						|
  g_handleState = handleModulesState;
 | 
						|
  g_processState = processModulesState;
 | 
						|
  g_renderState = renderModulesState;
 | 
						|
  g_switch_state = 0;
 | 
						|
 | 
						|
  return 0;
 | 
						|
}
 | 
						|
 | 
						|
int interfaceRun() {
 | 
						|
  struct PTime current_time; // time at start of loop
 | 
						|
  struct PTime last_time; // time at end of last loop
 | 
						|
  struct PTime delta_time; // difference between current_time and last_time
 | 
						|
  getPTime(¤t_time);
 | 
						|
 | 
						|
  SDL_Event event;
 | 
						|
  struct TSEvent ts_event; // SDL->TS event structure
 | 
						|
  /* begin our main loop */
 | 
						|
  g_initState();
 | 
						|
  while(g_running) {
 | 
						|
    last_time = current_time;
 | 
						|
    getPTime(¤t_time);
 | 
						|
    getPTimeDiff(&delta_time, ¤t_time, &last_time);
 | 
						|
 | 
						|
    // handle input and pass to state
 | 
						|
    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_KEYUP:
 | 
						|
          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_KEYUP;
 | 
						|
          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.n);
 | 
						|
    // now we move on to rendering
 | 
						|
    // clear out the screen :)
 | 
						|
    g_clearScreen();
 | 
						|
    // draw state
 | 
						|
    g_renderState();
 | 
						|
    // draw global elements
 | 
						|
    g_renderElements(g_elements);
 | 
						|
    // update fps counter
 | 
						|
    vid_frames++;
 | 
						|
    if (current_time.s - count_time.s >= 1) {
 | 
						|
      struct PTime delta_fps_time;
 | 
						|
      getPTimeDiff(&delta_fps_time, ¤t_time, &count_time);
 | 
						|
      int fps = vid_frames / delta_fps_time.s;
 | 
						|
      count_time = current_time;
 | 
						|
      vid_frames = 0;
 | 
						|
      setElementValue(g_element_fps, fps);
 | 
						|
    }
 | 
						|
    // render updates to screen
 | 
						|
    g_renderScreen();
 | 
						|
    // cap framerate if bool is set!
 | 
						|
    if (g_cap_framerate) {
 | 
						|
      int64_t delay_ns = sleep_time.n - delta_time.n;
 | 
						|
      if (delay_ns < 0) {
 | 
						|
        printf("uhoh, delay took %ld, so we wait for %ld\n", delta_time.n, delay_ns);
 | 
						|
        delay_ns = 0;
 | 
						|
      }
 | 
						|
      doNanoSleep(delay_ns);
 | 
						|
    }
 | 
						|
    // switch states if running state requested it.
 | 
						|
    if (g_switch_state == 1) {
 | 
						|
      g_freeState(); // free old state
 | 
						|
      g_initState(); // init new state, setting up state pointers
 | 
						|
      g_switch_state = 0;
 | 
						|
    }
 | 
						|
  }
 | 
						|
  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_loadSpritesheet = &r_gl_loadSpritesheet;
 | 
						|
      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_loadSpritesheet = &loadSpritesheetFromFile;
 | 
						|
      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));
 | 
						|
}
 |