271 lines
8.4 KiB
C
271 lines
8.4 KiB
C
#include <SDL2/SDL.h>
|
|
#include <SDL2/SDL_ttf.h>
|
|
#include <SDL2/SDL_mixer.h>
|
|
#include "opengl.h"
|
|
#include <SDL2/SDL_opengl.h>
|
|
#include <stdlib.h>
|
|
#include "globals.h"
|
|
#include "PTime.h"
|
|
#include "state.h"
|
|
#include "State_Intro.h"
|
|
#include "report.h"
|
|
#include "Resource.h"
|
|
#include "sprite.h"
|
|
#include "AnimData.h"
|
|
#include "EntityManager.h"
|
|
#include "Text.h"
|
|
#include "Ui.h"
|
|
#include "Music.h"
|
|
|
|
int main(int argc, char *argv[]) {
|
|
setReportLevel(REPORT_ERROR|REPORT_DEBUG|REPORT_WARNING|REPORT_GENERIC|REPORT_SEVERE|REPORT_NIL);
|
|
if (SDL_Init(SDL_INIT_EVERYTHING) != 0) {
|
|
report(ERROR, "main", "SDL_INIT: %s", SDL_GetError());
|
|
return 1;
|
|
}
|
|
// load up TTF
|
|
g_header_font = NULL;
|
|
g_large_font = NULL;
|
|
g_medium_font = NULL;
|
|
g_small_font = NULL;
|
|
if (TTF_Init() != 0) {
|
|
report(ERROR, "main", "TTF_Init: %s", SDL_GetError());
|
|
return 1;
|
|
} else {
|
|
g_large_font = TTF_OpenFont("fonts/Anonymous_Pro.ttf", 24);
|
|
if (g_large_font == NULL) {
|
|
report(ERROR, "main", "could not load font %s %s", "fonts/default.ttf", TTF_GetError());
|
|
return 1;
|
|
}
|
|
g_medium_font = TTF_OpenFont("fonts/Anonymous_Pro.ttf", 16);
|
|
if (g_medium_font == NULL) {
|
|
report(ERROR, "main", "could not load font %s %s", "fonts/default.ttf", TTF_GetError());
|
|
return 1;
|
|
}
|
|
g_header_font = TTF_OpenFont("fonts/watchtv.ttf", 96);
|
|
if (g_header_font == NULL) {
|
|
report(ERROR, "main", "could not load font %s %s", "fonts/default.ttf", TTF_GetError());
|
|
return 1;
|
|
}
|
|
g_small_font = TTF_OpenFont("fonts/ProggyTinySZ.ttf", 16);
|
|
if (g_small_font == NULL) {
|
|
report(ERROR, "main", "could not load font %s %s", "fonts/default.ttf", TTF_GetError());
|
|
return 1;
|
|
}
|
|
}
|
|
// load up audio
|
|
//if (Mix_OpenAudio(22050, AUDIO_S16, 2, 4096)) {
|
|
if (Mix_OpenAudio(44100, MIX_DEFAULT_FORMAT, 2, 4096)) {
|
|
report(ERROR, "main", "Mix_OpenAudio failed");
|
|
}
|
|
Mix_AllocateChannels(16);
|
|
//
|
|
int flags = MIX_INIT_OGG | MIX_INIT_FLAC;
|
|
int init = Mix_Init(flags);
|
|
if ((init & flags) != flags) {
|
|
report(ERROR, "main", "could not load OGG support: %s", Mix_GetError());
|
|
// bummer
|
|
}
|
|
// open up Audio
|
|
|
|
//
|
|
g_v_width = 1024;
|
|
g_v_height = 768;
|
|
g_v_framecap = 0;
|
|
g_v_vsync = 1;
|
|
g_v_zoom = 1.0f;
|
|
g_tile_w = 64;
|
|
g_tile_h = 48;
|
|
// load up dat display~
|
|
if ((g_window = SDL_CreateWindow(TITLE, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, g_v_width, g_v_height, SDL_WINDOW_OPENGL|SDL_WINDOW_RESIZABLE)) == NULL) {
|
|
report(ERROR, "main", "SDL_CreateWindow: %s", SDL_GetError());
|
|
return 2;
|
|
}
|
|
|
|
if ((g_context = SDL_GL_CreateContext(g_window)) == NULL) {
|
|
report(ERROR, "main", "SDL_GL_CreateContext: %s", SDL_GetError());
|
|
return 3;
|
|
}
|
|
SDL_GL_MakeCurrent(g_window, g_context);
|
|
//
|
|
/*SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
|
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);*/
|
|
/*int glewExperimental = GL_TRUE;
|
|
GLenum glew_status = glewInit();
|
|
if (glew_status != 0) {
|
|
report(ERROR, "main", "glewInit: %s", glewGetErrorString(glew_status));
|
|
return 1;
|
|
}*/
|
|
|
|
g_running = 1;
|
|
// rolling with OpenGL
|
|
reinitDisplay();
|
|
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
|
|
glEnable(GL_TEXTURE_2D);
|
|
glEnable(GL_TEXTURE_1D);
|
|
//glClearColor(0.02f, 0.05f, 0.02f, 0.0f);
|
|
glClearColor(0.00f, 0.00f, 0.00f, 0.0f);
|
|
glViewport(0, 0, g_v_width, g_v_height);
|
|
glClear(GL_COLOR_BUFFER_BIT);
|
|
|
|
glMatrixMode(GL_PROJECTION);
|
|
glLoadIdentity();
|
|
glOrtho(0.0f, g_v_width*g_v_zoom, g_v_height*g_v_zoom, 1.0f, -1.0f, 1.0f);
|
|
|
|
glMatrixMode(GL_MODELVIEW);
|
|
glLoadIdentity();
|
|
|
|
// transparency, bb
|
|
glEnable(GL_BLEND);
|
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
|
|
|
// load in glyphs
|
|
loadGlyphs(&g_header_glyphs, g_header_font);
|
|
loadGlyphs(&g_large_glyphs, g_large_font);
|
|
loadGlyphs(&g_medium_glyphs, g_medium_font);
|
|
loadGlyphs(&g_small_glyphs, g_small_font);
|
|
|
|
// set up our default colors
|
|
ui_colors = malloc(sizeof(struct Ui_Colors));
|
|
ui_colors->fg.r = 128;
|
|
ui_colors->fg.g = 196;
|
|
ui_colors->fg.b = 164;
|
|
ui_colors->bg.r = 24;
|
|
ui_colors->bg.b = 24;
|
|
ui_colors->bg.g = 24;
|
|
ui_colors->a_fg.r = 128;
|
|
ui_colors->a_fg.g = 196;
|
|
ui_colors->a_fg.b = 164;
|
|
ui_colors->a_bg.r = 16;
|
|
ui_colors->a_bg.g = 24;
|
|
ui_colors->a_bg.b = 32;
|
|
ui_colors->f_fg = ui_colors->fg;
|
|
ui_colors->f_bg = ui_colors->bg;
|
|
button_colors = malloc(sizeof(struct Ui_Colors));
|
|
*button_colors = *ui_colors;
|
|
button_colors->a_bg.r = 18;
|
|
button_colors->a_bg.g = 20;
|
|
button_colors->a_bg.b = 18;
|
|
button_colors->bg.r = 20;
|
|
button_colors->bg.g = 28;
|
|
button_colors->bg.b = 24;
|
|
hint_colors = malloc(sizeof(struct Ui_Colors));
|
|
*hint_colors = *ui_colors;
|
|
hint_colors->fg.r = 96;
|
|
hint_colors->fg.g = 164;
|
|
hint_colors->fg.b = 32;
|
|
message_colors = malloc(sizeof(struct Ui_Colors));
|
|
*message_colors = *ui_colors;
|
|
message_colors->bg.r = 16;
|
|
message_colors->bg.g = 32;
|
|
message_colors->bg.b = 64;
|
|
// our main, bb
|
|
g_state_manager = newStateManager();
|
|
g_music = newResources(3, 16);
|
|
g_music->loadResource_func = (void*)loadMusic;
|
|
g_music->freeResource_func = (void*)freeMusic;
|
|
|
|
g_sound = newResources(4, 32);
|
|
g_sound->loadResource_func = (void*)loadSound;
|
|
g_sound->freeResource_func = (void*)freeSound;
|
|
|
|
g_sprites = newResources(0, 256);
|
|
g_sprites->loadResource_func = (void*)createSpriteFromFile;
|
|
g_sprites->freeResource_func = (void*)freeSprite;
|
|
/*g_animdata = newResources(1, 32);
|
|
g_animdata->loadResource_func = (void*)loadAnimData;
|
|
g_animdata->freeResource_func = (void*)freeAnimData;*/
|
|
|
|
//initEntityManager(&g_entity_manager);
|
|
//g_entity_manager.sprites = g_sprites;
|
|
//g_entity_manager.animations = g_animdata;
|
|
|
|
// Let's set up our starting State. kinda gross
|
|
//pushState(g_state_manager, newState(STATE_PASS, openTestState, closeTestState, handleTestState, processTestState, renderTestState));
|
|
struct Text *fps_text = newText(g_large_font, "fps");
|
|
|
|
setPTime(&g_tickrate, 0, 0, 1000000000/60);
|
|
report(DEBUG, "main", "g_tickrate is %ldns, %ldms", g_tickrate.n, g_tickrate.m);
|
|
|
|
accumulator = g_tickrate;
|
|
getPTime(¤t_time);
|
|
struct PTime count_time;
|
|
count_time = current_time;
|
|
pushState(g_state_manager, newState(STATE_DEFAULT, openIntroState, closeIntroState, NULL, processIntroState, renderIntroState));
|
|
int v_frames = 0;
|
|
int last_fps = 0;
|
|
while(g_running) {
|
|
last_time = current_time;
|
|
getPTime(¤t_time);
|
|
SDL_Event event;
|
|
addPTime(&accumulator, 0, 0, getPTimeDiff(&g_delta, ¤t_time, &last_time));
|
|
while(accumulator.n >= g_tickrate.n) {
|
|
// open, close, free, etc.
|
|
cleanStates(g_state_manager);
|
|
while (SDL_PollEvent(&event)) {
|
|
// y'know
|
|
handleStates(g_state_manager, LAST, event);
|
|
switch(event.type) {
|
|
case SDL_QUIT:
|
|
g_running = 0;
|
|
break;
|
|
case SDL_WINDOWEVENT:
|
|
switch(event.window.event) {
|
|
case SDL_WINDOWEVENT_CLOSE:
|
|
event.type = SDL_QUIT;
|
|
SDL_PushEvent(&event);
|
|
break;
|
|
case SDL_WINDOWEVENT_SIZE_CHANGED:
|
|
case SDL_WINDOWEVENT_RESIZED:
|
|
g_v_width = event.window.data1;
|
|
g_v_height = event.window.data2;
|
|
reinitGl();
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
// run state logic :)
|
|
processStates(g_state_manager, LAST);
|
|
subPTime(&accumulator, 0, 0, g_tickrate.n);
|
|
}
|
|
|
|
// TODO: unlimited frames? :D probably option to lock y'know (nil-noms)
|
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
|
|
|
renderStates(g_state_manager, FIRST);
|
|
v_frames++;
|
|
if (current_time.s - count_time.s >= 1) {
|
|
struct PTime delta_fps;
|
|
getPTimeDiff(&delta_fps, ¤t_time, &count_time);
|
|
int fps = v_frames / delta_fps.s;
|
|
count_time = current_time;
|
|
v_frames = 0;
|
|
if (last_fps != fps) {
|
|
changeText(fps_text, "%d fps", fps);
|
|
last_fps = fps;
|
|
}
|
|
}
|
|
renderText(fps_text, fps_text->width/2, fps_text->height/2);
|
|
// nom nom cpus
|
|
SDL_GL_SwapWindow(g_window);
|
|
//doNanoSleep(g_tickrate.n-g_delta.n); // sync fps to tickrate, sorta
|
|
}
|
|
report(DEBUG, "main", "freed %d state(s)", closeStateManager(g_state_manager));
|
|
freeStateManager(g_state_manager);
|
|
|
|
freeResources(g_sprites);
|
|
freeResources(g_music);
|
|
|
|
freeText(fps_text);
|
|
SDL_GL_DeleteContext(g_context);
|
|
while(Mix_Init(0)) Mix_Quit();
|
|
SDL_DestroyWindow(g_window);
|
|
SDL_Quit();
|
|
return 0;
|
|
}
|