SDL port: Resizing, resizing modes, and pause support
This commit is contained in:
parent
00439f4d49
commit
52e99adc32
110
SDL/main.c
110
SDL/main.c
@ -5,6 +5,7 @@
|
|||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <SDL2/SDL.h>
|
#include <SDL2/SDL.h>
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
#define AUDIO_FREQUENCY 96000
|
#define AUDIO_FREQUENCY 96000
|
||||||
#else
|
#else
|
||||||
@ -28,6 +29,8 @@ static SDL_Texture *texture = NULL;
|
|||||||
static SDL_PixelFormat *pixel_format = NULL;
|
static SDL_PixelFormat *pixel_format = NULL;
|
||||||
static SDL_AudioSpec want_aspec, have_aspec;
|
static SDL_AudioSpec want_aspec, have_aspec;
|
||||||
|
|
||||||
|
static bool paused = false;
|
||||||
|
|
||||||
static uint32_t pixels[160*144];
|
static uint32_t pixels[160*144];
|
||||||
GB_gameboy_t gb;
|
GB_gameboy_t gb;
|
||||||
|
|
||||||
@ -39,8 +42,54 @@ static enum {
|
|||||||
GB_SDL_NEW_FILE_COMMAND,
|
GB_SDL_NEW_FILE_COMMAND,
|
||||||
GB_SDL_TOGGLE_MODEL_COMMAND,
|
GB_SDL_TOGGLE_MODEL_COMMAND,
|
||||||
} pending_command;
|
} pending_command;
|
||||||
|
|
||||||
|
static enum {
|
||||||
|
GB_SDL_SCALING_ENTIRE_WINDOW,
|
||||||
|
GB_SDL_SCALING_KEEP_RATIO,
|
||||||
|
GB_SDL_SCALING_INTEGER_FACTOR,
|
||||||
|
GB_SDL_SCALING_MAX,
|
||||||
|
} scaling_mode = GB_SDL_SCALING_INTEGER_FACTOR;
|
||||||
static unsigned command_parameter;
|
static unsigned command_parameter;
|
||||||
|
|
||||||
|
static void update_viewport(void)
|
||||||
|
{
|
||||||
|
int win_width, win_height;
|
||||||
|
SDL_GetWindowSize(window, &win_width, &win_height);
|
||||||
|
double x_factor = win_width / 160.0;
|
||||||
|
double y_factor = win_height / 144.0;
|
||||||
|
|
||||||
|
if (scaling_mode == GB_SDL_SCALING_INTEGER_FACTOR) {
|
||||||
|
x_factor = floor(x_factor);
|
||||||
|
y_factor = floor(y_factor);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (scaling_mode != GB_SDL_SCALING_ENTIRE_WINDOW) {
|
||||||
|
if (x_factor > y_factor) {
|
||||||
|
x_factor = y_factor;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
y_factor = x_factor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned new_width = x_factor * 160;
|
||||||
|
unsigned new_height = y_factor * 144;
|
||||||
|
|
||||||
|
SDL_Rect rect = (SDL_Rect){(win_width - new_width) / 2, (win_height - new_height) /2,
|
||||||
|
new_width, new_height};
|
||||||
|
SDL_RenderSetViewport(renderer, &rect);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void cycle_scaling(void)
|
||||||
|
{
|
||||||
|
scaling_mode++;
|
||||||
|
scaling_mode %= GB_SDL_SCALING_MAX;
|
||||||
|
update_viewport();
|
||||||
|
SDL_RenderClear(renderer);
|
||||||
|
SDL_RenderCopy(renderer, texture, NULL, NULL);
|
||||||
|
SDL_RenderPresent(renderer);
|
||||||
|
}
|
||||||
|
|
||||||
static void handle_events(GB_gameboy_t *gb)
|
static void handle_events(GB_gameboy_t *gb)
|
||||||
{
|
{
|
||||||
static bool ctrl = false;
|
static bool ctrl = false;
|
||||||
@ -54,7 +103,7 @@ static void handle_events(GB_gameboy_t *gb)
|
|||||||
SDL_Event event;
|
SDL_Event event;
|
||||||
while (SDL_PollEvent(&event))
|
while (SDL_PollEvent(&event))
|
||||||
{
|
{
|
||||||
switch( event.type ){
|
switch (event.type) {
|
||||||
case SDL_QUIT:
|
case SDL_QUIT:
|
||||||
GB_save_battery(gb, battery_save_path_ptr);
|
GB_save_battery(gb, battery_save_path_ptr);
|
||||||
exit(0);
|
exit(0);
|
||||||
@ -69,6 +118,12 @@ static void handle_events(GB_gameboy_t *gb)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case SDL_WINDOWEVENT: {
|
||||||
|
if (event.window.event == SDL_WINDOWEVENT_RESIZED) {
|
||||||
|
update_viewport();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
case SDL_KEYDOWN:
|
case SDL_KEYDOWN:
|
||||||
switch (event.key.keysym.sym) {
|
switch (event.key.keysym.sym) {
|
||||||
case SDLK_c:
|
case SDLK_c:
|
||||||
@ -90,6 +145,12 @@ static void handle_events(GB_gameboy_t *gb)
|
|||||||
pending_command = GB_SDL_TOGGLE_MODEL_COMMAND;
|
pending_command = GB_SDL_TOGGLE_MODEL_COMMAND;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case SDLK_p:
|
||||||
|
if (MODIFIER) {
|
||||||
|
paused = !paused;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case SDLK_m:
|
case SDLK_m:
|
||||||
if (MODIFIER) {
|
if (MODIFIER) {
|
||||||
@ -103,6 +164,10 @@ static void handle_events(GB_gameboy_t *gb)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case SDLK_TAB:
|
||||||
|
cycle_scaling();
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
/* Save states */
|
/* Save states */
|
||||||
if (event.key.keysym.sym >= SDLK_0 && event.key.keysym.sym <= SDLK_9) {
|
if (event.key.keysym.sym >= SDLK_0 && event.key.keysym.sym <= SDLK_9) {
|
||||||
@ -330,7 +395,13 @@ restart:
|
|||||||
|
|
||||||
/* Run emulation */
|
/* Run emulation */
|
||||||
while (true) {
|
while (true) {
|
||||||
GB_run(&gb);
|
if (paused) {
|
||||||
|
SDL_WaitEvent(NULL);
|
||||||
|
handle_events(&gb);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
GB_run(&gb);
|
||||||
|
}
|
||||||
switch (pending_command) {
|
switch (pending_command) {
|
||||||
case GB_SDL_LOAD_STATE_COMMAND:
|
case GB_SDL_LOAD_STATE_COMMAND:
|
||||||
case GB_SDL_SAVE_STATE_COMMAND: {
|
case GB_SDL_SAVE_STATE_COMMAND: {
|
||||||
@ -400,7 +471,8 @@ usage:
|
|||||||
SDL_Init( SDL_INIT_EVERYTHING );
|
SDL_Init( SDL_INIT_EVERYTHING );
|
||||||
|
|
||||||
window = SDL_CreateWindow("SameBoy v" xstr(VERSION), SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
|
window = SDL_CreateWindow("SameBoy v" xstr(VERSION), SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
|
||||||
160, 144, SDL_WINDOW_OPENGL);
|
160 * 2, 144 * 2, SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE);
|
||||||
|
SDL_SetWindowMinimumSize(window, 160, 144);
|
||||||
renderer = SDL_CreateRenderer(window, -1, 0);
|
renderer = SDL_CreateRenderer(window, -1, 0);
|
||||||
|
|
||||||
texture = SDL_CreateTexture(renderer, SDL_GetWindowPixelFormat(window), SDL_TEXTUREACCESS_STREAMING, 160, 144);
|
texture = SDL_CreateTexture(renderer, SDL_GetWindowPixelFormat(window), SDL_TEXTUREACCESS_STREAMING, 160, 144);
|
||||||
@ -437,17 +509,33 @@ usage:
|
|||||||
SDL_Event event;
|
SDL_Event event;
|
||||||
while (SDL_WaitEvent(&event))
|
while (SDL_WaitEvent(&event))
|
||||||
{
|
{
|
||||||
if (event.type == SDL_QUIT) {
|
switch (event.type) {
|
||||||
exit(0);
|
case SDL_QUIT: {
|
||||||
}
|
exit(0);
|
||||||
else if (event.type == SDL_DROPFILE) {
|
}
|
||||||
filename = event.drop.file;
|
case SDL_WINDOWEVENT: {
|
||||||
should_free_filename = true;
|
if (event.window.event == SDL_WINDOWEVENT_RESIZED) {
|
||||||
break;
|
update_viewport();
|
||||||
|
SDL_RenderClear(renderer);
|
||||||
|
SDL_RenderCopy(renderer, texture, NULL, NULL);
|
||||||
|
SDL_RenderPresent(renderer);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SDL_DROPFILE: {
|
||||||
|
filename = event.drop.file;
|
||||||
|
should_free_filename = true;
|
||||||
|
goto start;
|
||||||
|
}
|
||||||
|
case SDL_KEYDOWN:
|
||||||
|
if (event.key.keysym.sym == SDLK_TAB) {
|
||||||
|
cycle_scaling();
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
start:
|
||||||
run(); // Never returns
|
run(); // Never returns
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user