189 lines
4.9 KiB
C
189 lines
4.9 KiB
C
#include <stdio.h>
|
|
#include <stdbool.h>
|
|
|
|
// don't use sdl's redefinition of main
|
|
#define SDL_MAIN_HANDLED
|
|
#include "sdl/include/SDL.h"
|
|
#include "device/device.h"
|
|
#include "game/game.h"
|
|
|
|
void sdl_host_suggest_dimensions(uint32_t* window_w, uint32_t* window_h);
|
|
void sdl_host_loop();
|
|
void sdl_host_handle_keyboard_event(SDL_KeyboardEvent event);
|
|
|
|
SDL_Window* sdl_host_window;
|
|
SDL_Renderer* sdl_host_renderer;
|
|
SDL_Texture* sdl_host_target;
|
|
|
|
int main(int argc, char** argv) {
|
|
int result = 0;
|
|
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER)) {
|
|
printf("could not initialize SDL! sdl error: %s\n", SDL_GetError());
|
|
result = 1;
|
|
goto sdl_done;
|
|
}
|
|
|
|
uint32_t window_w, window_h;
|
|
sdl_host_suggest_dimensions(&window_w, &window_h);
|
|
|
|
// create window
|
|
sdl_host_window = SDL_CreateWindow(
|
|
game_title(),
|
|
SDL_WINDOWPOS_CENTERED,
|
|
SDL_WINDOWPOS_CENTERED,
|
|
(int) window_w, (int) window_h,
|
|
SDL_WINDOW_SHOWN
|
|
);
|
|
|
|
if (sdl_host_window == NULL) {
|
|
printf("could not create window! sdl error: %s\n", SDL_GetError());
|
|
result = 1;
|
|
goto window_done;
|
|
}
|
|
|
|
// create renderer
|
|
sdl_host_renderer = SDL_CreateRenderer(sdl_host_window, -1, 0);
|
|
if (sdl_host_renderer == NULL) {
|
|
printf("could not create renderer! sdl error: %s\n", SDL_GetError());
|
|
result = 1;
|
|
goto renderer_done;
|
|
}
|
|
|
|
// create target
|
|
sdl_host_target = SDL_CreateTexture(
|
|
sdl_host_renderer,
|
|
SDL_PIXELFORMAT_RGBA8888,
|
|
SDL_TEXTUREACCESS_STREAMING,
|
|
DEVICE_W, DEVICE_H
|
|
);
|
|
|
|
if (sdl_host_target == NULL) {
|
|
printf("could not create target texture! sdl error: %s\n", SDL_GetError());
|
|
result = 1;
|
|
goto target_done;
|
|
}
|
|
|
|
sdl_host_loop();
|
|
|
|
// target_cleanup:
|
|
SDL_DestroyTexture(sdl_host_target);
|
|
sdl_host_target = NULL;
|
|
target_done: ;
|
|
|
|
// renderer_cleanup:
|
|
SDL_DestroyRenderer(sdl_host_renderer);
|
|
sdl_host_renderer = NULL;
|
|
renderer_done: ;
|
|
|
|
// window_cleanup:
|
|
SDL_DestroyWindow(sdl_host_window);
|
|
sdl_host_window = NULL;
|
|
window_done: ;
|
|
|
|
// sdl_cleanup:
|
|
SDL_Quit();
|
|
sdl_done: ;
|
|
|
|
return result;
|
|
}
|
|
|
|
void sdl_host_suggest_dimensions(uint32_t* window_w, uint32_t* window_h) {
|
|
SDL_DisplayMode dm;
|
|
if (SDL_GetCurrentDisplayMode(0, &dm) != 0) {
|
|
printf("could not get current display mode: %s\n", SDL_GetError());
|
|
dm.w = 0;
|
|
dm.h = 0;
|
|
}
|
|
|
|
for (int scalar = 4; scalar >= 1; scalar--) {
|
|
uint32_t w = DEVICE_W * scalar;
|
|
uint32_t h = DEVICE_H * scalar;
|
|
if (w <= dm.w && h <= dm.h) {
|
|
*window_w = w;
|
|
*window_h = h;
|
|
return;
|
|
}
|
|
}
|
|
|
|
for (int scalar = 1; scalar <= 5; scalar++) {
|
|
uint32_t w = DEVICE_W / scalar;
|
|
uint32_t h = DEVICE_H / scalar;
|
|
if (w <= dm.w && h <= dm.h) {
|
|
*window_w = w;
|
|
*window_h = h;
|
|
return;
|
|
}
|
|
}
|
|
|
|
*window_w = DEVICE_W;
|
|
*window_h = DEVICE_H;
|
|
}
|
|
|
|
void sdl_host_loop() {
|
|
uint32_t ticks_per_frame = 1000/60;
|
|
uint32_t real_pixels[DEVICE_H][DEVICE_W];
|
|
|
|
game_init();
|
|
while (true) {
|
|
uint32_t frame_start = SDL_GetTicks();
|
|
uint32_t next_frame_start = frame_start + ticks_per_frame;
|
|
|
|
SDL_Event e;
|
|
while (SDL_PollEvent(&e)) {
|
|
if (e.type == SDL_QUIT) { goto quit; }
|
|
if (e.type == SDL_KEYDOWN || e.type == SDL_KEYUP) {
|
|
sdl_host_handle_keyboard_event(e.key);
|
|
}
|
|
}
|
|
|
|
// trigger game logic
|
|
game_update();
|
|
game_draw();
|
|
|
|
for (int x = 0; x < DEVICE_W; x++) {
|
|
for (int y = 0; y < DEVICE_H; y++) {
|
|
real_pixels[y][x] = device_palette[device_pixels[y][x]];
|
|
}
|
|
}
|
|
|
|
SDL_UpdateTexture(sdl_host_target, NULL, &real_pixels, sizeof(real_pixels[0]));
|
|
SDL_RenderClear(sdl_host_renderer);
|
|
SDL_RenderCopy(sdl_host_renderer, sdl_host_target, NULL, NULL);
|
|
SDL_RenderPresent(sdl_host_renderer);
|
|
|
|
// hold off until next frame
|
|
while (SDL_GetTicks() < next_frame_start) {
|
|
SDL_Delay(1);
|
|
}
|
|
}
|
|
quit: ;
|
|
}
|
|
|
|
void sdl_host_handle_keyboard_event(SDL_KeyboardEvent event) {
|
|
bool is_down;
|
|
switch (event.type) {
|
|
case SDL_KEYDOWN: is_down = true; break;
|
|
case SDL_KEYUP: is_down = false; break;
|
|
default: return;
|
|
}
|
|
|
|
if (event.repeat) {
|
|
return;
|
|
}
|
|
|
|
DeviceButton db;
|
|
|
|
switch (event.keysym.sym) {
|
|
case SDLK_LEFT: db = DEVICE_BUTTON_L; break;
|
|
case SDLK_RIGHT: db = DEVICE_BUTTON_R; break;
|
|
case SDLK_UP: db = DEVICE_BUTTON_U; break;
|
|
case SDLK_DOWN: db = DEVICE_BUTTON_D; break;
|
|
case SDLK_z: db = DEVICE_BUTTON_0; break;
|
|
case SDLK_x: db = DEVICE_BUTTON_1; break;
|
|
case SDLK_c: db = DEVICE_BUTTON_2; break;
|
|
case SDLK_v: db = DEVICE_BUTTON_3; break;
|
|
default: return;
|
|
}
|
|
|
|
device_buttons[db] = is_down;
|
|
} |