Compare commits

...

1 Commits

Author SHA1 Message Date
de43ac4cfb
Add simple DMG shader 2018-06-09 21:38:05 +02:00
3 changed files with 97 additions and 57 deletions

View File

@ -29,6 +29,7 @@
@"Bilinear", @"Bilinear",
@"SmoothBilinear", @"SmoothBilinear",
@"LCD", @"LCD",
@"DMG",
@"Scale2x", @"Scale2x",
@"Scale4x", @"Scale4x",
@"AAScale2x", @"AAScale2x",
@ -155,7 +156,7 @@
else { else {
[self keyUp:event]; [self keyUp:event];
} }
previousModifiers = event.modifierFlags; previousModifiers = event.modifierFlags;
} }
@ -237,21 +238,21 @@
else if (![joystick_being_configured isEqualToString:joystick_name]) { else if (![joystick_being_configured isEqualToString:joystick_name]) {
return; return;
} }
NSMutableDictionary *all_mappings = [[[NSUserDefaults standardUserDefaults] dictionaryForKey:@"GBJoypadMappings"] mutableCopy]; NSMutableDictionary *all_mappings = [[[NSUserDefaults standardUserDefaults] dictionaryForKey:@"GBJoypadMappings"] mutableCopy];
if (!all_mappings) { if (!all_mappings) {
all_mappings = [[NSMutableDictionary alloc] init]; all_mappings = [[NSMutableDictionary alloc] init];
} }
NSMutableDictionary *mapping = [[all_mappings objectForKey:joystick_name] mutableCopy]; NSMutableDictionary *mapping = [[all_mappings objectForKey:joystick_name] mutableCopy];
if (!mapping) { if (!mapping) {
mapping = [[NSMutableDictionary alloc] init]; mapping = [[NSMutableDictionary alloc] init];
} }
mapping[GBButtonNames[joystick_configuration_state]] = @(button); mapping[GBButtonNames[joystick_configuration_state]] = @(button);
all_mappings[joystick_name] = mapping; all_mappings[joystick_name] = mapping;
[[NSUserDefaults standardUserDefaults] setObject:all_mappings forKey:@"GBJoypadMappings"]; [[NSUserDefaults standardUserDefaults] setObject:all_mappings forKey:@"GBJoypadMappings"];
[self advanceConfigurationStateMachine]; [self advanceConfigurationStateMachine];
@ -267,31 +268,31 @@
else if (![joystick_being_configured isEqualToString:joystick_name]) { else if (![joystick_being_configured isEqualToString:joystick_name]) {
return; return;
} }
if (last_axis == -1) { if (last_axis == -1) {
last_axis = axis; last_axis = axis;
return; return;
} }
if (axis == last_axis) { if (axis == last_axis) {
return; return;
} }
NSMutableDictionary *all_mappings = [[[NSUserDefaults standardUserDefaults] dictionaryForKey:@"GBJoypadMappings"] mutableCopy]; NSMutableDictionary *all_mappings = [[[NSUserDefaults standardUserDefaults] dictionaryForKey:@"GBJoypadMappings"] mutableCopy];
if (!all_mappings) { if (!all_mappings) {
all_mappings = [[NSMutableDictionary alloc] init]; all_mappings = [[NSMutableDictionary alloc] init];
} }
NSMutableDictionary *mapping = [[all_mappings objectForKey:joystick_name] mutableCopy]; NSMutableDictionary *mapping = [[all_mappings objectForKey:joystick_name] mutableCopy];
if (!mapping) { if (!mapping) {
mapping = [[NSMutableDictionary alloc] init]; mapping = [[NSMutableDictionary alloc] init];
} }
mapping[@"XAxis"] = @(MIN(axis, last_axis)); mapping[@"XAxis"] = @(MIN(axis, last_axis));
mapping[@"YAxis"] = @(MAX(axis, last_axis)); mapping[@"YAxis"] = @(MAX(axis, last_axis));
all_mappings[joystick_name] = mapping; all_mappings[joystick_name] = mapping;
[[NSUserDefaults standardUserDefaults] setObject:all_mappings forKey:@"GBJoypadMappings"]; [[NSUserDefaults standardUserDefaults] setObject:all_mappings forKey:@"GBJoypadMappings"];
[self advanceConfigurationStateMachine]; [self advanceConfigurationStateMachine];

View File

@ -95,12 +95,12 @@ void update_viewport(void)
SDL_GL_GetDrawableSize(window, &win_width, &win_height); SDL_GL_GetDrawableSize(window, &win_width, &win_height);
double x_factor = win_width / 160.0; double x_factor = win_width / 160.0;
double y_factor = win_height / 144.0; double y_factor = win_height / 144.0;
if (configuration.scaling_mode == GB_SDL_SCALING_INTEGER_FACTOR) { if (configuration.scaling_mode == GB_SDL_SCALING_INTEGER_FACTOR) {
x_factor = (int)(x_factor); x_factor = (int)(x_factor);
y_factor = (int)(y_factor); y_factor = (int)(y_factor);
} }
if (configuration.scaling_mode != GB_SDL_SCALING_ENTIRE_WINDOW) { if (configuration.scaling_mode != GB_SDL_SCALING_ENTIRE_WINDOW) {
if (x_factor > y_factor) { if (x_factor > y_factor) {
x_factor = y_factor; x_factor = y_factor;
@ -109,13 +109,13 @@ void update_viewport(void)
y_factor = x_factor; y_factor = x_factor;
} }
} }
unsigned new_width = x_factor * 160; unsigned new_width = x_factor * 160;
unsigned new_height = y_factor * 144; unsigned new_height = y_factor * 144;
rect = (SDL_Rect){(win_width - new_width) / 2, (win_height - new_height) /2, rect = (SDL_Rect){(win_width - new_width) / 2, (win_height - new_height) /2,
new_width, new_height}; new_width, new_height};
if (renderer) { if (renderer) {
SDL_RenderSetViewport(renderer, &rect); SDL_RenderSetViewport(renderer, &rect);
} }
@ -130,9 +130,9 @@ static void draw_char(uint32_t *buffer, unsigned char ch, uint32_t color)
if (ch < ' ' || ch > font_max) { if (ch < ' ' || ch > font_max) {
ch = '?'; ch = '?';
} }
uint8_t *data = &font[(ch - ' ') * GLYPH_WIDTH * GLYPH_HEIGHT]; uint8_t *data = &font[(ch - ' ') * GLYPH_WIDTH * GLYPH_HEIGHT];
for (unsigned y = GLYPH_HEIGHT; y--;) { for (unsigned y = GLYPH_HEIGHT; y--;) {
for (unsigned x = GLYPH_WIDTH; x--;) { for (unsigned x = GLYPH_WIDTH; x--;) {
if (*(data++)) { if (*(data++)) {
@ -154,11 +154,11 @@ static void draw_unbordered_text(uint32_t *buffer, unsigned x, unsigned y, const
string++; string++;
continue; continue;
} }
if (x > 160 - GLYPH_WIDTH || y == 0 || y > 144 - GLYPH_HEIGHT) { if (x > 160 - GLYPH_WIDTH || y == 0 || y > 144 - GLYPH_HEIGHT) {
break; break;
} }
draw_char(&buffer[x + 160 * y], *string, color); draw_char(&buffer[x + 160 * y], *string, color);
x += GLYPH_WIDTH; x += GLYPH_WIDTH;
string++; string++;
@ -192,7 +192,7 @@ static void draw_text_centered(uint32_t *buffer, unsigned y, const char *string,
draw_text(buffer, x - GLYPH_WIDTH, y, LEFT_ARROW_STRING, color, border); draw_text(buffer, x - GLYPH_WIDTH, y, LEFT_ARROW_STRING, color, border);
draw_text(buffer, 160 - x, y, RIGHT_ARROW_STRING, color, border); draw_text(buffer, 160 - x, y, RIGHT_ARROW_STRING, color, border);
break; break;
case DECORATION_NONE: case DECORATION_NONE:
break; break;
} }
@ -259,7 +259,7 @@ static void return_to_root_menu(unsigned index)
static void cycle_model(unsigned index) static void cycle_model(unsigned index)
{ {
configuration.model++; configuration.model++;
if (configuration.model == MODEL_MAX) { if (configuration.model == MODEL_MAX) {
configuration.model = 0; configuration.model = 0;
@ -357,6 +357,7 @@ struct shader_name {
{"Bilinear", "Bilinear"}, {"Bilinear", "Bilinear"},
{"SmoothBilinear", "Smooth Bilinear"}, {"SmoothBilinear", "Smooth Bilinear"},
{"LCD", "LCD Display"}, {"LCD", "LCD Display"},
{"DMG", "DMG Display"},
{"Scale2x", "Scale2x"}, {"Scale2x", "Scale2x"},
{"Scale4x", "Scale4x"}, {"Scale4x", "Scale4x"},
{"AAScale2x", "Anti-aliased Scale2x"}, {"AAScale2x", "Anti-aliased Scale2x"},
@ -375,13 +376,13 @@ static void cycle_filter(unsigned index)
break; break;
} }
} }
i += 1; i += 1;
if (i >= sizeof(shaders) / sizeof(shaders[0])) { if (i >= sizeof(shaders) / sizeof(shaders[0])) {
i -= sizeof(shaders) / sizeof(shaders[0]); i -= sizeof(shaders) / sizeof(shaders[0]);
} }
strcpy(configuration.filter, shaders[i].file_name); strcpy(configuration.filter, shaders[i].file_name);
free_shader(&shader); free_shader(&shader);
if (!init_shader_with_name(&shader, configuration.filter)) { if (!init_shader_with_name(&shader, configuration.filter)) {
@ -397,12 +398,12 @@ static void cycle_filter_backwards(unsigned index)
break; break;
} }
} }
i -= 1; i -= 1;
if (i >= sizeof(shaders) / sizeof(shaders[0])) { if (i >= sizeof(shaders) / sizeof(shaders[0])) {
i = sizeof(shaders) / sizeof(shaders[0]) - 1; i = sizeof(shaders) / sizeof(shaders[0]) - 1;
} }
strcpy(configuration.filter, shaders[i].file_name); strcpy(configuration.filter, shaders[i].file_name);
free_shader(&shader); free_shader(&shader);
if (!init_shader_with_name(&shader, configuration.filter)) { if (!init_shader_with_name(&shader, configuration.filter)) {
@ -418,11 +419,11 @@ const char *current_filter_name(unsigned index)
break; break;
} }
} }
if (i == sizeof(shaders) / sizeof(shaders[0])) { if (i == sizeof(shaders) / sizeof(shaders[0])) {
i = 0; i = 0;
} }
return shaders[i].display_name; return shaders[i].display_name;
} }
@ -525,7 +526,7 @@ const char *current_joypad_name(unsigned index)
const char *orig_name = joystick? SDL_JoystickName(joystick) : NULL; const char *orig_name = joystick? SDL_JoystickName(joystick) : NULL;
if (!orig_name) return "Not Found"; if (!orig_name) return "Not Found";
unsigned i = 0; unsigned i = 0;
// SDL returns a name with repeated and trailing spaces // SDL returns a name with repeated and trailing spaces
while (*orig_name && i < sizeof(name) - 2) { while (*orig_name && i < sizeof(name) - 2) {
if (orig_name[0] != ' ' || orig_name[1] != ' ') { if (orig_name[0] != ' ' || orig_name[1] != ' ') {
@ -537,7 +538,7 @@ const char *current_joypad_name(unsigned index)
i--; i--;
} }
name[i] = 0; name[i] = 0;
return name; return name;
} }
@ -598,12 +599,12 @@ unsigned fix_joypad_axis(unsigned axis)
} }
return -1; return -1;
} }
if (configuration.div_joystick) { if (configuration.div_joystick) {
axis >>= 1; axis >>= 1;
} }
return axis & 1; return axis & 1;
} }
@ -619,7 +620,7 @@ unsigned fix_joypad_button(unsigned button)
if (i == 9) { if (i == 9) {
return SDL_CONTROLLER_BUTTON_START; return SDL_CONTROLLER_BUTTON_START;
} }
if (i == SDL_CONTROLLER_BUTTON_BACK) { if (i == SDL_CONTROLLER_BUTTON_BACK) {
return 8; return 8;
} }
@ -631,22 +632,22 @@ unsigned fix_joypad_button(unsigned button)
} }
return -1; return -1;
} }
if (configuration.div_joystick) { if (configuration.div_joystick) {
button >>= 1; button >>= 1;
} }
if (button < 4) { if (button < 4) {
if (configuration.swap_joysticks_bits_1_and_2) { if (configuration.swap_joysticks_bits_1_and_2) {
button = (int[]){0, 2, 1, 3}[button]; button = (int[]){0, 2, 1, 3}[button];
} }
if (configuration.flip_joystick_bit_1) { if (configuration.flip_joystick_bit_1) {
button ^= 1; button ^= 1;
} }
} }
return button; return button;
} }
@ -699,7 +700,7 @@ void run_gui(bool is_running)
converted_background = SDL_ConvertSurface(background, pixel_format, 0); converted_background = SDL_ConvertSurface(background, pixel_format, 0);
SDL_LockSurface(converted_background); SDL_LockSurface(converted_background);
SDL_FreeSurface(background); SDL_FreeSurface(background);
for (unsigned i = 4; i--; ) { for (unsigned i = 4; i--; ) {
gui_palette_native[i] = SDL_MapRGB(pixel_format, gui_palette[i].r, gui_palette[i].g, gui_palette[i].b); gui_palette_native[i] = SDL_MapRGB(pixel_format, gui_palette[i].r, gui_palette[i].g, gui_palette[i].b);
} }
@ -745,8 +746,8 @@ void run_gui(bool is_running)
event.key.keysym.scancode = scancode; event.key.keysym.scancode = scancode;
} }
} }
} }
case SDL_JOYAXISMOTION: { case SDL_JOYAXISMOTION: {
static bool axis_active[2] = {false, false}; static bool axis_active[2] = {false, false};
event.jaxis.axis = fix_joypad_axis(event.jaxis.axis); event.jaxis.axis = fix_joypad_axis(event.jaxis.axis);
@ -800,7 +801,7 @@ void run_gui(bool is_running)
pending_command = GB_SDL_QUIT_COMMAND; pending_command = GB_SDL_QUIT_COMMAND;
return; return;
} }
} }
case SDL_WINDOWEVENT: { case SDL_WINDOWEVENT: {
if (event.window.event == SDL_WINDOWEVENT_RESIZED) { if (event.window.event == SDL_WINDOWEVENT_RESIZED) {
@ -821,25 +822,25 @@ void run_gui(bool is_running)
auto_detect_inputs[auto_detect_progress++] = event.jbutton.button; auto_detect_inputs[auto_detect_progress++] = event.jbutton.button;
if (auto_detect_progress == 3) { if (auto_detect_progress == 3) {
gui_state = SHOWING_MENU; gui_state = SHOWING_MENU;
configuration.div_joystick = configuration.div_joystick =
((auto_detect_inputs[0] | auto_detect_inputs[1] | auto_detect_inputs[2]) & 1) == 0 && ((auto_detect_inputs[0] | auto_detect_inputs[1] | auto_detect_inputs[2]) & 1) == 0 &&
auto_detect_inputs[0] > 9; auto_detect_inputs[0] > 9;
if (configuration.div_joystick) { if (configuration.div_joystick) {
auto_detect_inputs[0] >>= 1; auto_detect_inputs[0] >>= 1;
auto_detect_inputs[1] >>= 1; auto_detect_inputs[1] >>= 1;
auto_detect_inputs[2] >>= 1; auto_detect_inputs[2] >>= 1;
} }
configuration.swap_joysticks_bits_1_and_2 = configuration.swap_joysticks_bits_1_and_2 =
(auto_detect_inputs[1] & 1) == (auto_detect_inputs[2] & 1); (auto_detect_inputs[1] & 1) == (auto_detect_inputs[2] & 1);
if (configuration.swap_joysticks_bits_1_and_2) { if (configuration.swap_joysticks_bits_1_and_2) {
auto_detect_inputs[1] = (int[]){0, 2, 1, 3}[auto_detect_inputs[1]]; auto_detect_inputs[1] = (int[]){0, 2, 1, 3}[auto_detect_inputs[1]];
auto_detect_inputs[2] = (int[]){0, 2, 1, 3}[auto_detect_inputs[2]]; auto_detect_inputs[2] = (int[]){0, 2, 1, 3}[auto_detect_inputs[2]];
} }
configuration.flip_joystick_bit_1 = auto_detect_inputs[2] & 1; configuration.flip_joystick_bit_1 = auto_detect_inputs[2] & 1;
} }
} }
@ -861,7 +862,7 @@ void run_gui(bool is_running)
should_render = true; should_render = true;
} }
} }
if (gui_state == SHOWING_MENU) { if (gui_state == SHOWING_MENU) {
if (event.key.keysym.scancode == SDL_SCANCODE_DOWN && current_menu[current_selection + 1].string) { if (event.key.keysym.scancode == SDL_SCANCODE_DOWN && current_menu[current_selection + 1].string) {
current_selection++; current_selection++;
@ -912,11 +913,11 @@ void run_gui(bool is_running)
} }
break; break;
} }
if (should_render) { if (should_render) {
should_render = false; should_render = false;
memcpy(pixels, converted_background->pixels, sizeof(pixels)); memcpy(pixels, converted_background->pixels, sizeof(pixels));
switch (gui_state) { switch (gui_state) {
case SHOWING_DROP_MESSAGE: case SHOWING_DROP_MESSAGE:
draw_text_centered(pixels, 8, "Press ESC for menu", gui_palette_native[3], gui_palette_native[0], false); draw_text_centered(pixels, 8, "Press ESC for menu", gui_palette_native[3], gui_palette_native[0], false);
@ -933,7 +934,7 @@ void run_gui(bool is_running)
draw_text_centered(pixels, y, line, gui_palette_native[3], gui_palette_native[0], draw_text_centered(pixels, y, line, gui_palette_native[3], gui_palette_native[0],
i == current_selection ? DECORATION_SELECTION : DECORATION_NONE); i == current_selection ? DECORATION_SELECTION : DECORATION_NONE);
y += 12; y += 12;
} }
else { else {
draw_text_centered(pixels, y, item->string, gui_palette_native[3], gui_palette_native[0], draw_text_centered(pixels, y, item->string, gui_palette_native[3], gui_palette_native[0],
@ -963,7 +964,7 @@ void run_gui(bool is_running)
gui_palette_native[3], gui_palette_native[0], DECORATION_NONE); gui_palette_native[3], gui_palette_native[0], DECORATION_NONE);
break; break;
} }
render_texture(pixels, NULL); render_texture(pixels, NULL);
} }
} while (SDL_WaitEvent(&event)); } while (SDL_WaitEvent(&event));

38
Shaders/DMG.fsh Normal file
View File

@ -0,0 +1,38 @@
vec4 pixelize(vec4 image, vec2 scaleVec, vec2 texCoord) {
float scale = max(scaleVec.x, scaleVec.y);
float x = fract(texCoord.x * 160.0) * scale;
float y = fract(texCoord.y * 144.0) * scale;
float border = 1.0;
if (scale > 5.0) {
border = 2.0;
}
if (x < border || x > scale - border || y < border || y > scale - border) {
return vec4(.95, .95, .95, 1);
}
return image;
}
vec4 scale(sampler2D image) {
vec2 displayScale = uResolution / vec2(160.0, 144.0);
vec2 texCoord = vec2(gl_FragCoord.x, uResolution.y - gl_FragCoord.y) / uResolution;
vec4 sampled = texture(image, texCoord);
if (displayScale.x < 3.0 || displayScale.y < 3.0) {
return sampled;
}
float mixValue = 1.0;
if (displayScale.x >= 5.0 && displayScale.y >= 5.0) {
mixValue = 0.5;
}
else if (displayScale.x >= 3.0 && displayScale.y >= 3.0) {
mixValue = 0.8;
}
return mix(pixelize(sampled, displayScale, texCoord), sampled, mixValue);
}