Basic SGB support in the SDL port
This commit is contained in:
parent
3ee2c64899
commit
3e724afb0a
@ -798,12 +798,12 @@ uint32_t GB_get_clock_rate(GB_gameboy_t *gb)
|
|||||||
return CPU_FREQUENCY * gb->clock_multiplier;
|
return CPU_FREQUENCY * gb->clock_multiplier;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t GB_get_screen_width(GB_gameboy_t *gb)
|
unsigned GB_get_screen_width(GB_gameboy_t *gb)
|
||||||
{
|
{
|
||||||
return GB_is_sgb(gb)? 256 : 160;
|
return GB_is_sgb(gb)? 256 : 160;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t GB_get_screen_height(GB_gameboy_t *gb)
|
unsigned GB_get_screen_height(GB_gameboy_t *gb)
|
||||||
{
|
{
|
||||||
return GB_is_sgb(gb)? 224 : 144;
|
return GB_is_sgb(gb)? 224 : 144;
|
||||||
}
|
}
|
||||||
|
@ -689,8 +689,8 @@ uint32_t GB_get_clock_rate(GB_gameboy_t *gb);
|
|||||||
#endif
|
#endif
|
||||||
void GB_set_clock_multiplier(GB_gameboy_t *gb, double multiplier);
|
void GB_set_clock_multiplier(GB_gameboy_t *gb, double multiplier);
|
||||||
|
|
||||||
size_t GB_get_screen_width(GB_gameboy_t *gb);
|
unsigned GB_get_screen_width(GB_gameboy_t *gb);
|
||||||
size_t GB_get_screen_height(GB_gameboy_t *gb);
|
unsigned GB_get_screen_height(GB_gameboy_t *gb);
|
||||||
|
|
||||||
unsigned GB_get_player_count(GB_gameboy_t *gb);
|
unsigned GB_get_player_count(GB_gameboy_t *gb);
|
||||||
|
|
||||||
|
94
SDL/gui.c
94
SDL/gui.c
@ -44,7 +44,9 @@ void render_texture(void *pixels, void *previous)
|
|||||||
}
|
}
|
||||||
glClearColor(0, 0, 0, 1);
|
glClearColor(0, 0, 0, 1);
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
render_bitmap_with_shader(&shader, _pixels, previous, rect.x, rect.y, rect.w, rect.h);
|
render_bitmap_with_shader(&shader, _pixels, previous,
|
||||||
|
GB_get_screen_width(&gb), GB_get_screen_height(&gb),
|
||||||
|
rect.x, rect.y, rect.w, rect.h);
|
||||||
SDL_GL_SwapWindow(window);
|
SDL_GL_SwapWindow(window);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -116,8 +118,8 @@ void update_viewport(void)
|
|||||||
{
|
{
|
||||||
int win_width, win_height;
|
int win_width, win_height;
|
||||||
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 / (double) GB_get_screen_width(&gb);
|
||||||
double y_factor = win_height / 144.0;
|
double y_factor = win_height / (double) GB_get_screen_height(&gb);
|
||||||
|
|
||||||
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);
|
||||||
@ -133,8 +135,8 @@ void update_viewport(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned new_width = x_factor * 160;
|
unsigned new_width = x_factor * GB_get_screen_width(&gb);
|
||||||
unsigned new_height = y_factor * 144;
|
unsigned new_height = y_factor * GB_get_screen_height(&gb);
|
||||||
|
|
||||||
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};
|
||||||
@ -148,7 +150,7 @@ void update_viewport(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Does NOT check for bounds! */
|
/* Does NOT check for bounds! */
|
||||||
static void draw_char(uint32_t *buffer, unsigned char ch, uint32_t color)
|
static void draw_char(uint32_t *buffer, unsigned width, unsigned height, unsigned char ch, uint32_t color)
|
||||||
{
|
{
|
||||||
if (ch < ' ' || ch > font_max) {
|
if (ch < ' ' || ch > font_max) {
|
||||||
ch = '?';
|
ch = '?';
|
||||||
@ -163,11 +165,11 @@ static void draw_char(uint32_t *buffer, unsigned char ch, uint32_t color)
|
|||||||
}
|
}
|
||||||
buffer++;
|
buffer++;
|
||||||
}
|
}
|
||||||
buffer += 160 - GLYPH_WIDTH;
|
buffer += width - GLYPH_WIDTH;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void draw_unbordered_text(uint32_t *buffer, unsigned x, unsigned y, const char *string, uint32_t color)
|
static void draw_unbordered_text(uint32_t *buffer, unsigned width, unsigned height, unsigned x, unsigned y, const char *string, uint32_t color)
|
||||||
{
|
{
|
||||||
unsigned orig_x = x;
|
unsigned orig_x = x;
|
||||||
while (*string) {
|
while (*string) {
|
||||||
@ -178,23 +180,23 @@ static void draw_unbordered_text(uint32_t *buffer, unsigned x, unsigned y, const
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (x > 160 - GLYPH_WIDTH || y == 0 || y > 144 - GLYPH_HEIGHT) {
|
if (x > width - GLYPH_WIDTH || y == 0 || y > height - GLYPH_HEIGHT) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
draw_char(&buffer[x + 160 * y], *string, color);
|
draw_char(&buffer[x + width * y], width, height, *string, color);
|
||||||
x += GLYPH_WIDTH;
|
x += GLYPH_WIDTH;
|
||||||
string++;
|
string++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void draw_text(uint32_t *buffer, unsigned x, unsigned y, const char *string, uint32_t color, uint32_t border)
|
static void draw_text(uint32_t *buffer, unsigned width, unsigned height, unsigned x, unsigned y, const char *string, uint32_t color, uint32_t border)
|
||||||
{
|
{
|
||||||
draw_unbordered_text(buffer, x - 1, y, string, border);
|
draw_unbordered_text(buffer, width, height, x - 1, y, string, border);
|
||||||
draw_unbordered_text(buffer, x + 1, y, string, border);
|
draw_unbordered_text(buffer, width, height, x + 1, y, string, border);
|
||||||
draw_unbordered_text(buffer, x, y - 1, string, border);
|
draw_unbordered_text(buffer, width, height, x, y - 1, string, border);
|
||||||
draw_unbordered_text(buffer, x, y + 1, string, border);
|
draw_unbordered_text(buffer, width, height, x, y + 1, string, border);
|
||||||
draw_unbordered_text(buffer, x, y, string, color);
|
draw_unbordered_text(buffer, width, height, x, y, string, color);
|
||||||
}
|
}
|
||||||
|
|
||||||
enum decoration {
|
enum decoration {
|
||||||
@ -203,17 +205,17 @@ enum decoration {
|
|||||||
DECORATION_ARROWS,
|
DECORATION_ARROWS,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void draw_text_centered(uint32_t *buffer, unsigned y, const char *string, uint32_t color, uint32_t border, enum decoration decoration)
|
static void draw_text_centered(uint32_t *buffer, unsigned width, unsigned height, unsigned y, const char *string, uint32_t color, uint32_t border, enum decoration decoration)
|
||||||
{
|
{
|
||||||
unsigned x = 160 / 2 - (unsigned) strlen(string) * GLYPH_WIDTH / 2;
|
unsigned x = width / 2 - (unsigned) strlen(string) * GLYPH_WIDTH / 2;
|
||||||
draw_text(buffer, x, y, string, color, border);
|
draw_text(buffer, width, height, x, y, string, color, border);
|
||||||
switch (decoration) {
|
switch (decoration) {
|
||||||
case DECORATION_SELECTION:
|
case DECORATION_SELECTION:
|
||||||
draw_text(buffer, x - GLYPH_WIDTH, y, SELECTION_STRING, color, border);
|
draw_text(buffer, width, height, x - GLYPH_WIDTH, y, SELECTION_STRING, color, border);
|
||||||
break;
|
break;
|
||||||
case DECORATION_ARROWS:
|
case DECORATION_ARROWS:
|
||||||
draw_text(buffer, x - GLYPH_WIDTH, y, LEFT_ARROW_STRING, color, border);
|
draw_text(buffer, width, height, x - GLYPH_WIDTH, y, LEFT_ARROW_STRING, color, border);
|
||||||
draw_text(buffer, 160 - x, y, RIGHT_ARROW_STRING, color, border);
|
draw_text(buffer, width, height, width - x, y, RIGHT_ARROW_STRING, color, border);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DECORATION_NONE:
|
case DECORATION_NONE:
|
||||||
@ -301,7 +303,7 @@ static void cycle_model_backwards(unsigned index)
|
|||||||
|
|
||||||
const char *current_model_string(unsigned index)
|
const char *current_model_string(unsigned index)
|
||||||
{
|
{
|
||||||
return (const char *[]){"Game Boy", "Game Boy Color", "Game Boy Advance"}
|
return (const char *[]){"Game Boy", "Game Boy Color", "Game Boy Advance" , "Super Game Boy"}
|
||||||
[configuration.model];
|
[configuration.model];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -764,7 +766,18 @@ void run_gui(bool is_running)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t pixels[160 * 144];
|
unsigned width = GB_get_screen_width(&gb);
|
||||||
|
unsigned height = GB_get_screen_height(&gb);
|
||||||
|
unsigned x_offset = (width - 160) / 2;
|
||||||
|
unsigned y_offset = (height - 144) / 2;
|
||||||
|
uint32_t pixels[width * height];
|
||||||
|
|
||||||
|
if (width != 160 || height != 144) {
|
||||||
|
for (unsigned i = 0; i < width * height; i++) {
|
||||||
|
pixels[i] = gui_palette_native[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
SDL_Event event = {0,};
|
SDL_Event event = {0,};
|
||||||
gui_state = is_running? SHOWING_MENU : SHOWING_DROP_MESSAGE;
|
gui_state = is_running? SHOWING_MENU : SHOWING_DROP_MESSAGE;
|
||||||
bool should_render = true;
|
bool should_render = true;
|
||||||
@ -994,32 +1007,39 @@ void run_gui(bool is_running)
|
|||||||
|
|
||||||
if (should_render) {
|
if (should_render) {
|
||||||
should_render = false;
|
should_render = false;
|
||||||
memcpy(pixels, converted_background->pixels, sizeof(pixels));
|
if (width == 160 && height == 144) {
|
||||||
|
memcpy(pixels, converted_background->pixels, sizeof(pixels));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
for (unsigned y = 0; y < 144; y++) {
|
||||||
|
memcpy(pixels + x_offset + width * (y + y_offset), ((uint32_t *)converted_background->pixels) + 160 * y, 160 * 4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
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, width, height, 8 + y_offset, "Press ESC for menu", gui_palette_native[3], gui_palette_native[0], false);
|
||||||
draw_text_centered(pixels, 116, "Drop a GB or GBC", gui_palette_native[3], gui_palette_native[0], false);
|
draw_text_centered(pixels, width, height, 116 + y_offset, "Drop a GB or GBC", gui_palette_native[3], gui_palette_native[0], false);
|
||||||
draw_text_centered(pixels, 128, "file to play", gui_palette_native[3], gui_palette_native[0], false);
|
draw_text_centered(pixels, width, height, 128 + y_offset, "file to play", gui_palette_native[3], gui_palette_native[0], false);
|
||||||
break;
|
break;
|
||||||
case SHOWING_MENU:
|
case SHOWING_MENU:
|
||||||
draw_text_centered(pixels, 8, "SameBoy", gui_palette_native[3], gui_palette_native[0], false);
|
draw_text_centered(pixels, width, height, 8 + y_offset, "SameBoy", gui_palette_native[3], gui_palette_native[0], false);
|
||||||
unsigned i = 0, y = 24;
|
unsigned i = 0, y = 24;
|
||||||
for (const struct menu_item *item = current_menu; item->string; item++, i++) {
|
for (const struct menu_item *item = current_menu; item->string; item++, i++) {
|
||||||
if (item->value_getter && !item->backwards_handler) {
|
if (item->value_getter && !item->backwards_handler) {
|
||||||
char line[25];
|
char line[25];
|
||||||
snprintf(line, sizeof(line), "%s%*s", item->string, 24 - (int)strlen(item->string), item->value_getter(i));
|
snprintf(line, sizeof(line), "%s%*s", item->string, 24 - (int)strlen(item->string), item->value_getter(i));
|
||||||
draw_text_centered(pixels, y, line, gui_palette_native[3], gui_palette_native[0],
|
draw_text_centered(pixels, width, height, y + y_offset, 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, width, height, y + y_offset, item->string, gui_palette_native[3], gui_palette_native[0],
|
||||||
i == current_selection && !item->value_getter ? DECORATION_SELECTION : DECORATION_NONE);
|
i == current_selection && !item->value_getter ? DECORATION_SELECTION : DECORATION_NONE);
|
||||||
y += 12;
|
y += 12;
|
||||||
if (item->value_getter) {
|
if (item->value_getter) {
|
||||||
draw_text_centered(pixels, y, item->value_getter(i), gui_palette_native[3], gui_palette_native[0],
|
draw_text_centered(pixels, width, height, y + y_offset, item->value_getter(i), gui_palette_native[3], gui_palette_native[0],
|
||||||
i == current_selection ? DECORATION_ARROWS : DECORATION_NONE);
|
i == current_selection ? DECORATION_ARROWS : DECORATION_NONE);
|
||||||
y += 12;
|
y += 12;
|
||||||
}
|
}
|
||||||
@ -1027,16 +1047,16 @@ void run_gui(bool is_running)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SHOWING_HELP:
|
case SHOWING_HELP:
|
||||||
draw_text(pixels, 2, 2, help[current_help_page], gui_palette_native[3], gui_palette_native[0]);
|
draw_text(pixels, width, height, 2 + x_offset, 2 + y_offset, help[current_help_page], gui_palette_native[3], gui_palette_native[0]);
|
||||||
break;
|
break;
|
||||||
case WAITING_FOR_KEY:
|
case WAITING_FOR_KEY:
|
||||||
draw_text_centered(pixels, 68, "Press a Key", gui_palette_native[3], gui_palette_native[0], DECORATION_NONE);
|
draw_text_centered(pixels, width, height, 68 + y_offset, "Press a Key", gui_palette_native[3], gui_palette_native[0], DECORATION_NONE);
|
||||||
break;
|
break;
|
||||||
case WAITING_FOR_JBUTTON:
|
case WAITING_FOR_JBUTTON:
|
||||||
draw_text_centered(pixels, 68,
|
draw_text_centered(pixels, width, height, 68 + y_offset,
|
||||||
joypad_configuration_progress != JOYPAD_BUTTONS_MAX ? "Press button for" : "Move the Analog Stick",
|
joypad_configuration_progress != JOYPAD_BUTTONS_MAX ? "Press button for" : "Move the Analog Stick",
|
||||||
gui_palette_native[3], gui_palette_native[0], DECORATION_NONE);
|
gui_palette_native[3], gui_palette_native[0], DECORATION_NONE);
|
||||||
draw_text_centered(pixels, 80,
|
draw_text_centered(pixels, width, height, 80 + y_offset,
|
||||||
(const char *[])
|
(const char *[])
|
||||||
{
|
{
|
||||||
"Right",
|
"Right",
|
||||||
@ -1054,7 +1074,7 @@ void run_gui(bool is_running)
|
|||||||
"",
|
"",
|
||||||
} [joypad_configuration_progress],
|
} [joypad_configuration_progress],
|
||||||
gui_palette_native[3], gui_palette_native[0], DECORATION_NONE);
|
gui_palette_native[3], gui_palette_native[0], DECORATION_NONE);
|
||||||
draw_text_centered(pixels, 104, "Press Enter to skip", gui_palette_native[3], gui_palette_native[0], DECORATION_NONE);
|
draw_text_centered(pixels, width, height, 104 + y_offset, "Press Enter to skip", gui_palette_native[3], gui_palette_native[0], DECORATION_NONE);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,6 +77,7 @@ typedef struct {
|
|||||||
MODEL_DMG,
|
MODEL_DMG,
|
||||||
MODEL_CGB,
|
MODEL_CGB,
|
||||||
MODEL_AGB,
|
MODEL_AGB,
|
||||||
|
MODEL_SGB,
|
||||||
MODEL_MAX,
|
MODEL_MAX,
|
||||||
} model;
|
} model;
|
||||||
|
|
||||||
|
18
SDL/main.c
18
SDL/main.c
@ -24,7 +24,7 @@
|
|||||||
|
|
||||||
GB_gameboy_t gb;
|
GB_gameboy_t gb;
|
||||||
static bool paused = false;
|
static bool paused = false;
|
||||||
static uint32_t pixel_buffer_1[160*144], pixel_buffer_2[160*144];
|
static uint32_t pixel_buffer_1[256 * 224], pixel_buffer_2[256 * 224];
|
||||||
static uint32_t *active_pixel_buffer = pixel_buffer_1, *previous_pixel_buffer = pixel_buffer_2;
|
static uint32_t *active_pixel_buffer = pixel_buffer_1, *previous_pixel_buffer = pixel_buffer_2;
|
||||||
static bool underclock_down = false, rewind_down = false, do_rewind = false, rewind_paused = false, turbo_down = false;
|
static bool underclock_down = false, rewind_down = false, do_rewind = false, rewind_paused = false, turbo_down = false;
|
||||||
static double clock_mutliplier = 1.0;
|
static double clock_mutliplier = 1.0;
|
||||||
@ -39,7 +39,8 @@ static const GB_model_t sdl_to_internal_model[] =
|
|||||||
{
|
{
|
||||||
[MODEL_DMG] = GB_MODEL_DMG_B,
|
[MODEL_DMG] = GB_MODEL_DMG_B,
|
||||||
[MODEL_CGB] = GB_MODEL_CGB_E,
|
[MODEL_CGB] = GB_MODEL_CGB_E,
|
||||||
[MODEL_AGB] = GB_MODEL_AGB
|
[MODEL_AGB] = GB_MODEL_AGB,
|
||||||
|
[MODEL_SGB] = GB_MODEL_SGB,
|
||||||
};
|
};
|
||||||
|
|
||||||
void set_filename(const char *new_filename, bool new_should_free)
|
void set_filename(const char *new_filename, bool new_should_free)
|
||||||
@ -423,9 +424,16 @@ restart:
|
|||||||
GB_set_rewind_length(&gb, configuration.rewind_length);
|
GB_set_rewind_length(&gb, configuration.rewind_length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SDL_DestroyTexture(texture);
|
||||||
|
texture = SDL_CreateTexture(renderer, SDL_GetWindowPixelFormat(window), SDL_TEXTUREACCESS_STREAMING,
|
||||||
|
GB_get_screen_width(&gb), GB_get_screen_height(&gb));
|
||||||
|
|
||||||
|
SDL_SetWindowMinimumSize(window, GB_get_screen_width(&gb), GB_get_screen_height(&gb));
|
||||||
|
|
||||||
|
|
||||||
bool error = false;
|
bool error = false;
|
||||||
start_capturing_logs();
|
start_capturing_logs();
|
||||||
const char * const boot_roms[] = {"dmg_boot.bin", "cgb_boot.bin", "agb_boot.bin"};
|
const char * const boot_roms[] = {"dmg_boot.bin", "cgb_boot.bin", "agb_boot.bin", "sgb_boot.bin"};
|
||||||
error = GB_load_boot_rom(&gb, resource_path(boot_roms[configuration.model]));
|
error = GB_load_boot_rom(&gb, resource_path(boot_roms[configuration.model]));
|
||||||
end_capturing_logs(true, error);
|
end_capturing_logs(true, error);
|
||||||
|
|
||||||
@ -447,7 +455,9 @@ restart:
|
|||||||
char symbols_path[path_length + 5];
|
char symbols_path[path_length + 5];
|
||||||
replace_extension(filename, path_length, symbols_path, ".sym");
|
replace_extension(filename, path_length, symbols_path, ".sym");
|
||||||
GB_debugger_load_symbol_file(&gb, symbols_path);
|
GB_debugger_load_symbol_file(&gb, symbols_path);
|
||||||
|
|
||||||
|
update_viewport();
|
||||||
|
|
||||||
/* Run emulation */
|
/* Run emulation */
|
||||||
while (true) {
|
while (true) {
|
||||||
if (paused || rewind_paused) {
|
if (paused || rewind_paused) {
|
||||||
|
@ -162,20 +162,22 @@ bool init_shader_with_name(shader_t *shader, const char *name)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void render_bitmap_with_shader(shader_t *shader, void *bitmap, void *previous,unsigned x, unsigned y, unsigned w, unsigned h)
|
void render_bitmap_with_shader(shader_t *shader, void *bitmap, void *previous,
|
||||||
|
unsigned source_width, unsigned source_height,
|
||||||
|
unsigned x, unsigned y, unsigned w, unsigned h)
|
||||||
{
|
{
|
||||||
glUseProgram(shader->program);
|
glUseProgram(shader->program);
|
||||||
glUniform2f(shader->origin_uniform, x, y);
|
glUniform2f(shader->origin_uniform, x, y);
|
||||||
glUniform2f(shader->resolution_uniform, w, h);
|
glUniform2f(shader->resolution_uniform, w, h);
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
glBindTexture(GL_TEXTURE_2D, shader->texture);
|
glBindTexture(GL_TEXTURE_2D, shader->texture);
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 160, 144, 0, GL_RGBA, GL_UNSIGNED_BYTE, bitmap);
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, source_width, source_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, bitmap);
|
||||||
glUniform1i(shader->texture_uniform, 0);
|
glUniform1i(shader->texture_uniform, 0);
|
||||||
glUniform1i(shader->mix_previous_uniform, previous != NULL);
|
glUniform1i(shader->mix_previous_uniform, previous != NULL);
|
||||||
if (previous) {
|
if (previous) {
|
||||||
glActiveTexture(GL_TEXTURE1);
|
glActiveTexture(GL_TEXTURE1);
|
||||||
glBindTexture(GL_TEXTURE_2D, shader->previous_texture);
|
glBindTexture(GL_TEXTURE_2D, shader->previous_texture);
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 160, 144, 0, GL_RGBA, GL_UNSIGNED_BYTE, previous);
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, source_width, source_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, previous);
|
||||||
glUniform1i(shader->previous_texture_uniform, 1);
|
glUniform1i(shader->previous_texture_uniform, 1);
|
||||||
}
|
}
|
||||||
glBindFragDataLocation(shader->program, 0, "frag_color");
|
glBindFragDataLocation(shader->program, 0, "frag_color");
|
||||||
|
@ -17,7 +17,9 @@ typedef struct shader_s {
|
|||||||
} shader_t;
|
} shader_t;
|
||||||
|
|
||||||
bool init_shader_with_name(shader_t *shader, const char *name);
|
bool init_shader_with_name(shader_t *shader, const char *name);
|
||||||
void render_bitmap_with_shader(shader_t *shader, void *bitmap, void *previous,unsigned x, unsigned y, unsigned w, unsigned h);
|
void render_bitmap_with_shader(shader_t *shader, void *bitmap, void *previous,
|
||||||
|
unsigned source_width, unsigned source_height,
|
||||||
|
unsigned x, unsigned y, unsigned w, unsigned h);
|
||||||
void free_shader(struct shader_s *shader);
|
void free_shader(struct shader_s *shader);
|
||||||
|
|
||||||
#endif /* shader_h */
|
#endif /* shader_h */
|
||||||
|
@ -5,7 +5,6 @@ uniform bool mix_previous;
|
|||||||
|
|
||||||
uniform vec2 output_resolution;
|
uniform vec2 output_resolution;
|
||||||
uniform vec2 origin;
|
uniform vec2 origin;
|
||||||
const vec2 input_resolution = vec2(160, 144);
|
|
||||||
|
|
||||||
#define equal(x, y) ((x) == (y))
|
#define equal(x, y) ((x) == (y))
|
||||||
#define inequal(x, y) ((x) != (y))
|
#define inequal(x, y) ((x) != (y))
|
||||||
|
Loading…
Reference in New Issue
Block a user