[GTK3] Prototype rendering of tilemap and tileset

This commit is contained in:
Maximilian Mader 2019-09-25 22:47:33 +02:00
parent 3984359008
commit 1f7cd57df8
Signed by: Max
GPG Key ID: F71D56A3151C4FB3
3 changed files with 242 additions and 130 deletions

View File

@ -29,8 +29,14 @@ static void run(UserData *user_data);
static GtkApplication *main_application; static GtkApplication *main_application;
static GtkBuilder *builder; static GtkBuilder *builder;
static GtkApplicationWindow *main_window;
static GtkGLArea *gl_area; static GtkGLArea *gl_area;
static GtkApplicationWindow *main_window;
static GtkWindow *vram_viewer;
static GtkWindow *memory_viewer;
static GtkWindow *console;
static GtkWindow *printer;
static shader_t shader; static shader_t shader;
static GB_gameboy_t gb; static GB_gameboy_t gb;
@ -42,9 +48,20 @@ static bool underclock_down = false, rewind_down = false, do_rewind = false, rew
static double clock_mutliplier = 1.0; static double clock_mutliplier = 1.0;
static char *battery_save_path_ptr; static char *battery_save_path_ptr;
static Rect rect; static Rect rect;
static bool vram_viewer_visible = false;
static bool running = true; static bool running = true;
static const size_t tileset_buffer_length = 256 * 192 * 4;
static uint32_t tileset_buffer[tileset_buffer_length] = {0};
static const size_t tilemap_buffer_length = 256 * 256 * 4;
static uint32_t tilemap_buffer[tilemap_buffer_length] = {0};
// Returns a GObject by ID from our GtkBuilder instance
static GObject *get_object(gchararray id) {
return gtk_builder_get_object(builder, id);
}
static unsigned char number_of_buffers(void) { static unsigned char number_of_buffers(void) {
bool should_blend = true; bool should_blend = true;
@ -85,6 +102,15 @@ static void vblank(GB_gameboy_t *gb) {
// Queue drawing of the current frame // Queue drawing of the current frame
gtk_gl_area_queue_render(gl_area); gtk_gl_area_queue_render(gl_area);
if (vram_viewer_visible) {
// TODO: Only update what is needed
GB_draw_tileset(gb, tileset_buffer, GB_PALETTE_NONE, 0);
GB_draw_tilemap(gb, tilemap_buffer, GB_PALETTE_AUTO, 0, GB_MAP_AUTO, GB_TILESET_AUTO);
// Queue a redraw of the VRAM viewer
gtk_widget_queue_draw(GTK_WIDGET(vram_viewer));
}
while (gtk_events_pending()) { while (gtk_events_pending()) {
gtk_main_iteration(); gtk_main_iteration();
@ -158,17 +184,18 @@ static void set_combo_box_row_separator_func(GtkContainer *container) {
// Returns true if the application should show a menubar // Returns true if the application should show a menubar
static gboolean show_menubar(void) { static gboolean show_menubar(void) {
GtkSettings *settings = gtk_settings_get_default(); switch (get_show_menubar()) {
gboolean result; case MENUBAR_AUTO: {
GtkSettings *settings = gtk_settings_get_default();
gboolean result;
g_object_get(settings, "gtk-shell-shows-menubar", &result, NULL); g_object_get(settings, "gtk-shell-shows-menubar", &result, NULL);
return result; return result;
} }
case MENUBAR_SHOW: return true;
// Returns a GObject by ID from our GtkBuilder instance case MENUBAR_HIDE: return false;
static GObject *get_object(gchararray id) { }
return gtk_builder_get_object(builder, id);
} }
// Returns a `GApplication`s `GMenuModel` by ID // Returns a `GApplication`s `GMenuModel` by ID
@ -212,12 +239,26 @@ static void activate_preferences(GSimpleAction *action, GVariant *parameter, gpo
gtk_widget_show_all(GTK_WIDGET(get_object("preferences"))); gtk_widget_show_all(GTK_WIDGET(get_object("preferences")));
} }
// app.open_vram_viewer GAction
// Opens the VRAM viewer window
static void activate_open_vram_viewer(GSimpleAction *action, GVariant *parameter, gpointer user_data) {
gtk_widget_show_all(GTK_WIDGET(vram_viewer));
}
// app.open_memory_viewer GAction
// Opens the memory viewer window
static void activate_open_memory_viewer(GSimpleAction *action, GVariant *parameter, gpointer user_data) {
gtk_widget_show_all(GTK_WIDGET(memory_viewer));
}
// List of GActions for the `app` prefix // List of GActions for the `app` prefix
static GActionEntry app_entries[] = { static GActionEntry app_entries[] = {
{ "quit", activate_quit, NULL, NULL, NULL }, { "quit", activate_quit, NULL, NULL, NULL },
{ "about", activate_about, NULL, NULL, NULL }, { "about", activate_about, NULL, NULL, NULL },
{ "open_gtk_debugger", activate_open_gtk_debugger, NULL, NULL, NULL }, { "open_gtk_debugger", activate_open_gtk_debugger, NULL, NULL, NULL },
{ "preferences", activate_preferences, NULL, NULL, NULL }, { "preferences", activate_preferences, NULL, NULL, NULL },
{ "open_vram_viewer", activate_open_vram_viewer, NULL, NULL, NULL },
{ "open_memory_viewer", activate_open_memory_viewer, NULL, NULL, NULL },
}; };
G_MODULE_EXPORT void on_quit(GtkWidget *w, gpointer app) { G_MODULE_EXPORT void on_quit(GtkWidget *w, gpointer app) {
@ -228,12 +269,6 @@ G_MODULE_EXPORT void on_show_window(GtkWidget *w, gpointer window) {
gtk_widget_show_all(GTK_WIDGET(window)); gtk_widget_show_all(GTK_WIDGET(window));
} }
G_MODULE_EXPORT void on_boot_rom_location_changed(GtkWidget *w, gpointer user_data_gptr) {
GtkComboBox *box = GTK_COMBO_BOX(w);
g_print("Active: %s", gtk_combo_box_get_active_id(box));
}
G_MODULE_EXPORT void gl_init() { G_MODULE_EXPORT void gl_init() {
const char *renderer; const char *renderer;
@ -260,12 +295,66 @@ G_MODULE_EXPORT void gl_draw() {
G_MODULE_EXPORT void gl_finish() { } G_MODULE_EXPORT void gl_finish() { }
G_MODULE_EXPORT void on_vram_viewer_realize(gpointer visible) {
vram_viewer_visible = true;
}
G_MODULE_EXPORT void on_vram_viewer_unrealize(gpointer visible) {
vram_viewer_visible = false;
}
G_MODULE_EXPORT gboolean on_draw_vram_viewer_tileset(GtkWidget *widget, cairo_t *cr, gpointer data) {
guint width, height;
GtkStyleContext *context;
context = gtk_widget_get_style_context(widget);
width = gtk_widget_get_allocated_width(widget);
height = gtk_widget_get_allocated_height(widget);
gtk_render_background(context, cr, 0, 0, width, height);
cairo_surface_t *surface = cairo_image_surface_create_for_data(
(unsigned char *) tileset_buffer,
CAIRO_FORMAT_RGB24,
256,
192,
cairo_format_stride_for_width(CAIRO_FORMAT_RGB24, 256)
);
cairo_set_source_surface(cr, surface, 0, 0);
cairo_paint(cr);
return FALSE;
}
G_MODULE_EXPORT gboolean on_vram_viewer_tilemap(GtkWidget *widget, cairo_t *cr, gpointer data) {
guint width, height;
GtkStyleContext *context;
context = gtk_widget_get_style_context(widget);
width = gtk_widget_get_allocated_width(widget);
height = gtk_widget_get_allocated_height(widget);
gtk_render_background(context, cr, 0, 0, width, height);
cairo_surface_t *surface = cairo_image_surface_create_for_data(
(unsigned char *) tilemap_buffer,
CAIRO_FORMAT_RGB24,
256,
256,
cairo_format_stride_for_width(CAIRO_FORMAT_RGB24, 256)
);
cairo_set_source_surface(cr, surface, 0, 0);
cairo_paint(cr);
return FALSE;
}
// This functions gets called immediately after registration of the GApplication // This functions gets called immediately after registration of the GApplication
static void startup(GApplication *app, gpointer user_data_gptr) { static void startup(GApplication *app, gpointer user_data_gptr) {
UserData *user_data = user_data_gptr; UserData *user_data = user_data_gptr;
init_settings(user_data->config_path);
builder = gtk_builder_new_from_resource(RESOURCE_PREFIX "ui/window.ui"); builder = gtk_builder_new_from_resource(RESOURCE_PREFIX "ui/window.ui");
gtk_builder_connect_signals(builder, NULL); gtk_builder_connect_signals(builder, NULL);
@ -274,9 +363,17 @@ static void startup(GApplication *app, gpointer user_data_gptr) {
GtkWindow *preferences = GTK_WINDOW(get_object("preferences")); GtkWindow *preferences = GTK_WINDOW(get_object("preferences"));
set_combo_box_row_separator_func(GTK_CONTAINER(preferences)); set_combo_box_row_separator_func(GTK_CONTAINER(preferences));
GtkWindow *vram_viewer = GTK_WINDOW(get_object("vram_viewer")); init_settings(user_data->config_path, preferences);
vram_viewer = GTK_WINDOW(get_object("vram_viewer"));
set_combo_box_row_separator_func(GTK_CONTAINER(vram_viewer)); set_combo_box_row_separator_func(GTK_CONTAINER(vram_viewer));
memory_viewer = GTK_WINDOW(get_object("memory_viewer"));
set_combo_box_row_separator_func(GTK_CONTAINER(memory_viewer));
console = GTK_WINDOW(get_object("console"));
printer = GTK_WINDOW(get_object("printer"));
// setup main window // setup main window
main_window = GTK_APPLICATION_WINDOW(gtk_application_window_new(GTK_APPLICATION(app))); main_window = GTK_APPLICATION_WINDOW(gtk_application_window_new(GTK_APPLICATION(app)));
gtk_application_window_set_show_menubar(main_window, true); gtk_application_window_set_show_menubar(main_window, true);
@ -284,11 +381,26 @@ static void startup(GApplication *app, gpointer user_data_gptr) {
// create our renderer area // create our renderer area
gl_area = GTK_GL_AREA(gtk_gl_area_new()); gl_area = GTK_GL_AREA(gtk_gl_area_new());
gtk_gl_area_set_auto_render(gl_area, false); gtk_gl_area_set_auto_render(gl_area, false);
g_signal_connect(gl_area, "realize", G_CALLBACK(gl_init), NULL);
g_signal_connect(gl_area, "render", G_CALLBACK(gl_draw), NULL); // Connect signal handlers
g_signal_connect(gl_area, "resize", G_CALLBACK(gl_resize), NULL); g_signal_connect(gl_area, "realize", G_CALLBACK(gl_init), NULL);
g_signal_connect(gl_area, "render", G_CALLBACK(gl_draw), NULL);
g_signal_connect(gl_area, "resize", G_CALLBACK(gl_resize), NULL);
g_signal_connect(gl_area, "unrealize", G_CALLBACK(gl_finish), NULL); g_signal_connect(gl_area, "unrealize", G_CALLBACK(gl_finish), NULL);
g_signal_connect(vram_viewer, "realize", G_CALLBACK(on_vram_viewer_realize), NULL);
g_signal_connect(vram_viewer, "unrealize", G_CALLBACK(on_vram_viewer_unrealize), NULL);
// Just hide our sub-windows when closing them
g_signal_connect(preferences, "delete-event", G_CALLBACK(gtk_widget_hide_on_delete), NULL);
g_signal_connect(vram_viewer, "delete-event", G_CALLBACK(gtk_widget_hide_on_delete), NULL);
g_signal_connect(memory_viewer, "delete-event", G_CALLBACK(gtk_widget_hide_on_delete), NULL);
g_signal_connect(console, "delete-event", G_CALLBACK(gtk_widget_hide_on_delete), NULL);
g_signal_connect(printer, "delete-event", G_CALLBACK(gtk_widget_hide_on_delete), NULL);
g_signal_connect(get_object("vram_viewer_tileset_canvas"), "draw", G_CALLBACK(on_draw_vram_viewer_tileset), NULL);
g_signal_connect(get_object("vram_viewer_tilemap_canvas"), "draw", G_CALLBACK(on_vram_viewer_tilemap), NULL);
gtk_container_add(GTK_CONTAINER(main_window), GTK_WIDGET(gl_area)); gtk_container_add(GTK_CONTAINER(main_window), GTK_WIDGET(gl_area));
// Handle the whole menubar situation … // Handle the whole menubar situation …
@ -311,7 +423,7 @@ static void startup(GApplication *app, gpointer user_data_gptr) {
gtk_menu_button_set_menu_model(hamburger_button, hamburger_menu); gtk_menu_button_set_menu_model(hamburger_button, hamburger_menu);
} }
gtk_window_set_title(GTK_WINDOW(main_window), "SameBoy v" xstr(VERSION)); gtk_window_set_title(GTK_WINDOW(main_window), "SameBoy");
// Define a set of window icons // Define a set of window icons
GList *icon_list = NULL; GList *icon_list = NULL;

View File

@ -71,7 +71,7 @@ Author: Maximilian Mader
<attribute name="id">file-section-0</attribute> <attribute name="id">file-section-0</attribute>
<item> <item>
<attribute name="label" translatable="yes">_Open</attribute> <attribute name="label" translatable="yes">_Open</attribute>
<attribute name="action">win.open</attribute> <attribute name="action">app.open</attribute>
</item> </item>
<submenu> <submenu>
<attribute name="label" translatable="yes">Open _Recent</attribute> <attribute name="label" translatable="yes">Open _Recent</attribute>
@ -85,7 +85,7 @@ Author: Maximilian Mader
<attribute name="id">file-section-1</attribute> <attribute name="id">file-section-1</attribute>
<item> <item>
<attribute name="label" translatable="yes">Close</attribute> <attribute name="label" translatable="yes">Close</attribute>
<attribute name="action">win.close</attribute> <attribute name="action">app.close</attribute>
</item> </item>
</section> </section>
</submenu> </submenu>
@ -96,11 +96,11 @@ Author: Maximilian Mader
<attribute name="id">edit-section-0</attribute> <attribute name="id">edit-section-0</attribute>
<item> <item>
<attribute name="label" translatable="yes">Undo</attribute> <attribute name="label" translatable="yes">Undo</attribute>
<attribute name="action">win.undo</attribute> <attribute name="action">app.undo</attribute>
</item> </item>
<item> <item>
<attribute name="label" translatable="yes">Redo</attribute> <attribute name="label" translatable="yes">Redo</attribute>
<attribute name="action">win.redo</attribute> <attribute name="action">app.redo</attribute>
</item> </item>
</section> </section>
@ -108,23 +108,23 @@ Author: Maximilian Mader
<attribute name="id">edit-section-1</attribute> <attribute name="id">edit-section-1</attribute>
<item> <item>
<attribute name="label" translatable="yes">Cut</attribute> <attribute name="label" translatable="yes">Cut</attribute>
<attribute name="action">win.cut</attribute> <attribute name="action">app.cut</attribute>
</item> </item>
<item> <item>
<attribute name="label" translatable="yes">Copy</attribute> <attribute name="label" translatable="yes">Copy</attribute>
<attribute name="action">win.copy</attribute> <attribute name="action">app.copy</attribute>
</item> </item>
<item> <item>
<attribute name="label" translatable="yes">Paste</attribute> <attribute name="label" translatable="yes">Paste</attribute>
<attribute name="action">win.paste</attribute> <attribute name="action">app.paste</attribute>
</item> </item>
<item> <item>
<attribute name="label" translatable="yes">Delete</attribute> <attribute name="label" translatable="yes">Delete</attribute>
<attribute name="action">win.delete</attribute> <attribute name="action">app.delete</attribute>
</item> </item>
<item> <item>
<attribute name="label" translatable="yes">Select All</attribute> <attribute name="label" translatable="yes">Select All</attribute>
<attribute name="action">win.select_all</attribute> <attribute name="action">app.select_all</attribute>
</item> </item>
</section> </section>
@ -135,23 +135,23 @@ Author: Maximilian Mader
<attribute name="id">find-section-0</attribute> <attribute name="id">find-section-0</attribute>
<item> <item>
<attribute name="label" translatable="yes">Find…</attribute> <attribute name="label" translatable="yes">Find…</attribute>
<attribute name="action">win.find</attribute> <attribute name="action">app.find</attribute>
</item> </item>
<item> <item>
<attribute name="label" translatable="yes">Find Next</attribute> <attribute name="label" translatable="yes">Find Next</attribute>
<attribute name="action">win.find_next</attribute> <attribute name="action">app.find_next</attribute>
</item> </item>
<item> <item>
<attribute name="label" translatable="yes">Find Previous</attribute> <attribute name="label" translatable="yes">Find Previous</attribute>
<attribute name="action">win.find_previous</attribute> <attribute name="action">app.find_previous</attribute>
</item> </item>
<item> <item>
<attribute name="label" translatable="yes">Use Selection for Find</attribute> <attribute name="label" translatable="yes">Use Selection for Find</attribute>
<attribute name="action">win.find_selection</attribute> <attribute name="action">app.find_selection</attribute>
</item> </item>
<item> <item>
<attribute name="label" translatable="yes">Jump to Selection</attribute> <attribute name="label" translatable="yes">Jump to Selection</attribute>
<attribute name="action">win.jump_selection</attribute> <attribute name="action">app.jump_selection</attribute>
</item> </item>
</section> </section>
</submenu> </submenu>
@ -164,11 +164,11 @@ Author: Maximilian Mader
<attribute name="id">emulation-section-0</attribute> <attribute name="id">emulation-section-0</attribute>
<item> <item>
<attribute name="label" translatable="yes">Reset</attribute> <attribute name="label" translatable="yes">Reset</attribute>
<attribute name="action">win.reset</attribute> <attribute name="action">app.reset</attribute>
</item> </item>
<item> <item>
<attribute name="label" translatable="yes">Pause</attribute> <attribute name="label" translatable="yes">Pause</attribute>
<attribute name="action">win.pause</attribute> <attribute name="action">app.pause</attribute>
</item> </item>
</section> </section>
@ -178,53 +178,53 @@ Author: Maximilian Mader
<attribute name="label" translatable="yes">Save State</attribute> <attribute name="label" translatable="yes">Save State</attribute>
<item> <item>
<attribute name="label" translatable="yes">Slot 1</attribute> <attribute name="label" translatable="yes">Slot 1</attribute>
<attribute name="save_slot">0</attribute> <attribute name="save-slot">0</attribute>
<attribute name="action">win.save_state</attribute> <attribute name="action">app.save_state</attribute>
</item> </item>
<item> <item>
<attribute name="label" translatable="yes">Slot 2</attribute> <attribute name="label" translatable="yes">Slot 2</attribute>
<attribute name="save_slot">1</attribute> <attribute name="save-slot">1</attribute>
<attribute name="action">win.save_state</attribute> <attribute name="action">app.save_state</attribute>
</item> </item>
<item> <item>
<attribute name="label" translatable="yes">Slot 3</attribute> <attribute name="label" translatable="yes">Slot 3</attribute>
<attribute name="save_slot">2</attribute> <attribute name="save-slot">2</attribute>
<attribute name="action">win.save_state</attribute> <attribute name="action">app.save_state</attribute>
</item> </item>
<item> <item>
<attribute name="label" translatable="yes">Slot 4</attribute> <attribute name="label" translatable="yes">Slot 4</attribute>
<attribute name="save_slot">3</attribute> <attribute name="save-slot">3</attribute>
<attribute name="action">win.save_state</attribute> <attribute name="action">app.save_state</attribute>
</item> </item>
<item> <item>
<attribute name="label" translatable="yes">Slot 5</attribute> <attribute name="label" translatable="yes">Slot 5</attribute>
<attribute name="save_slot">4</attribute> <attribute name="save-slot">4</attribute>
<attribute name="action">win.save_state</attribute> <attribute name="action">app.save_state</attribute>
</item> </item>
<item> <item>
<attribute name="label" translatable="yes">Slot 6</attribute> <attribute name="label" translatable="yes">Slot 6</attribute>
<attribute name="save_slot">5</attribute> <attribute name="save-slot">5</attribute>
<attribute name="action">win.save_state</attribute> <attribute name="action">app.save_state</attribute>
</item> </item>
<item> <item>
<attribute name="label" translatable="yes">Slot 7</attribute> <attribute name="label" translatable="yes">Slot 7</attribute>
<attribute name="save_slot">6</attribute> <attribute name="save-slot">6</attribute>
<attribute name="action">win.save_state</attribute> <attribute name="action">app.save_state</attribute>
</item> </item>
<item> <item>
<attribute name="label" translatable="yes">Slot 8</attribute> <attribute name="label" translatable="yes">Slot 8</attribute>
<attribute name="save_slot">7</attribute> <attribute name="save-slot">7</attribute>
<attribute name="action">win.save_state</attribute> <attribute name="action">app.save_state</attribute>
</item> </item>
<item> <item>
<attribute name="label" translatable="yes">Slot 9</attribute> <attribute name="label" translatable="yes">Slot 9</attribute>
<attribute name="save_slot">8</attribute> <attribute name="save-slot">8</attribute>
<attribute name="action">win.save_state</attribute> <attribute name="action">app.save_state</attribute>
</item> </item>
<item> <item>
<attribute name="label" translatable="yes">Slot 10</attribute> <attribute name="label" translatable="yes">Slot 10</attribute>
<attribute name="save_slot">9</attribute> <attribute name="save-slot">9</attribute>
<attribute name="action">win.save_state</attribute> <attribute name="action">app.save_state</attribute>
</item> </item>
</submenu> </submenu>
@ -232,53 +232,53 @@ Author: Maximilian Mader
<attribute name="label" translatable="yes">Save State</attribute> <attribute name="label" translatable="yes">Save State</attribute>
<item> <item>
<attribute name="label" translatable="yes">Slot 1</attribute> <attribute name="label" translatable="yes">Slot 1</attribute>
<attribute name="save_slot">0</attribute> <attribute name="save-slot">0</attribute>
<attribute name="action">win.load_state</attribute> <attribute name="action">app.load_state</attribute>
</item> </item>
<item> <item>
<attribute name="label" translatable="yes">Slot 2</attribute> <attribute name="label" translatable="yes">Slot 2</attribute>
<attribute name="save_slot">1</attribute> <attribute name="save-slot">1</attribute>
<attribute name="action">win.load_state</attribute> <attribute name="action">app.load_state</attribute>
</item> </item>
<item> <item>
<attribute name="label" translatable="yes">Slot 3</attribute> <attribute name="label" translatable="yes">Slot 3</attribute>
<attribute name="save_slot">2</attribute> <attribute name="save-slot">2</attribute>
<attribute name="action">win.load_state</attribute> <attribute name="action">app.load_state</attribute>
</item> </item>
<item> <item>
<attribute name="label" translatable="yes">Slot 4</attribute> <attribute name="label" translatable="yes">Slot 4</attribute>
<attribute name="save_slot">3</attribute> <attribute name="save-slot">3</attribute>
<attribute name="action">win.load_state</attribute> <attribute name="action">app.load_state</attribute>
</item> </item>
<item> <item>
<attribute name="label" translatable="yes">Slot 5</attribute> <attribute name="label" translatable="yes">Slot 5</attribute>
<attribute name="save_slot">4</attribute> <attribute name="save-slot">4</attribute>
<attribute name="action">win.load_state</attribute> <attribute name="action">app.load_state</attribute>
</item> </item>
<item> <item>
<attribute name="label" translatable="yes">Slot 6</attribute> <attribute name="label" translatable="yes">Slot 6</attribute>
<attribute name="save_slot">5</attribute> <attribute name="save-slot">5</attribute>
<attribute name="action">win.load_state</attribute> <attribute name="action">app.load_state</attribute>
</item> </item>
<item> <item>
<attribute name="label" translatable="yes">Slot 7</attribute> <attribute name="label" translatable="yes">Slot 7</attribute>
<attribute name="save_slot">6</attribute> <attribute name="save-slot">6</attribute>
<attribute name="action">win.load_state</attribute> <attribute name="action">app.load_state</attribute>
</item> </item>
<item> <item>
<attribute name="label" translatable="yes">Slot 8</attribute> <attribute name="label" translatable="yes">Slot 8</attribute>
<attribute name="save_slot">7</attribute> <attribute name="save-slot">7</attribute>
<attribute name="action">win.load_state</attribute> <attribute name="action">app.load_state</attribute>
</item> </item>
<item> <item>
<attribute name="label" translatable="yes">Slot 9</attribute> <attribute name="label" translatable="yes">Slot 9</attribute>
<attribute name="save_slot">8</attribute> <attribute name="save-slot">8</attribute>
<attribute name="action">win.load_state</attribute> <attribute name="action">app.load_state</attribute>
</item> </item>
<item> <item>
<attribute name="label" translatable="yes">Slot 10</attribute> <attribute name="label" translatable="yes">Slot 10</attribute>
<attribute name="save_slot">9</attribute> <attribute name="save-slot">9</attribute>
<attribute name="action">win.load_state</attribute> <attribute name="action">app.load_state</attribute>
</item> </item>
</submenu> </submenu>
</section> </section>
@ -287,22 +287,22 @@ Author: Maximilian Mader
<attribute name="id">emulation-section-2</attribute> <attribute name="id">emulation-section-2</attribute>
<item> <item>
<attribute name="label" translatable="yes">Game Boy</attribute> <attribute name="label" translatable="yes">Game Boy</attribute>
<attribute name="action">win.change_model</attribute> <attribute name="action">app.change_model</attribute>
<attribute name="model">DMG</attribute> <attribute name="model">DMG</attribute>
</item> </item>
<item> <item>
<attribute name="label" translatable="yes">Super Game Boy</attribute> <attribute name="label" translatable="yes">Super Game Boy</attribute>
<attribute name="action">win.change_model</attribute> <attribute name="action">app.change_model</attribute>
<attribute name="model">SGB</attribute> <attribute name="model">SGB</attribute>
</item> </item>
<item> <item>
<attribute name="label" translatable="yes">Game Boy Color</attribute> <attribute name="label" translatable="yes">Game Boy Color</attribute>
<attribute name="action">win.change_model</attribute> <attribute name="action">app.change_model</attribute>
<attribute name="model">CGB</attribute> <attribute name="model">CGB</attribute>
</item> </item>
<item> <item>
<attribute name="label" translatable="yes">Game Boy Advance</attribute> <attribute name="label" translatable="yes">Game Boy Advance</attribute>
<attribute name="action">win.change_model</attribute> <attribute name="action">app.change_model</attribute>
<attribute name="model">AGB</attribute> <attribute name="model">AGB</attribute>
</item> </item>
</section> </section>
@ -311,7 +311,7 @@ Author: Maximilian Mader
<attribute name="id">emulation-section-3</attribute> <attribute name="id">emulation-section-3</attribute>
<item> <item>
<attribute name="label" translatable="yes">Mute Sound</attribute> <attribute name="label" translatable="yes">Mute Sound</attribute>
<attribute name="action">win.toggle_mute</attribute> <attribute name="action">app.toggle_mute</attribute>
</item> </item>
</section> </section>
@ -319,7 +319,7 @@ Author: Maximilian Mader
<attribute name="id">emulation-section-4</attribute> <attribute name="id">emulation-section-4</attribute>
<item> <item>
<attribute name="label" translatable="yes">Blend Frames</attribute> <attribute name="label" translatable="yes">Blend Frames</attribute>
<attribute name="action">win.toggle_blend_frames</attribute> <attribute name="action">app.toggle_blend_frames</attribute>
</item> </item>
</section> </section>
</submenu> </submenu>
@ -330,13 +330,13 @@ Author: Maximilian Mader
<attribute name="id">connectivity-section-0</attribute> <attribute name="id">connectivity-section-0</attribute>
<item> <item>
<attribute name="label" translatable="yes">None</attribute> <attribute name="label" translatable="yes">None</attribute>
<attribute name="action">win.change_serial_device</attribute> <attribute name="action">app.change_serial_device</attribute>
<attribute name="serial_device">none</attribute> <attribute name="serial-device">none</attribute>
</item> </item>
<item> <item>
<attribute name="label" translatable="yes">Game Boy Printer</attribute> <attribute name="label" translatable="yes">Game Boy Printer</attribute>
<attribute name="action">win.change_serial_device</attribute> <attribute name="action">app.change_serial_device</attribute>
<attribute name="serial_device">gb_printer</attribute> <attribute name="serial-device">gb_printer</attribute>
</item> </item>
</section> </section>
</submenu> </submenu>
@ -347,7 +347,7 @@ Author: Maximilian Mader
<attribute name="id">developer-section-0</attribute> <attribute name="id">developer-section-0</attribute>
<item> <item>
<attribute name="label" translatable="yes">Developer Mode</attribute> <attribute name="label" translatable="yes">Developer Mode</attribute>
<attribute name="action">win.toggle_developer_mode</attribute> <attribute name="action">app.toggle_developer_mode</attribute>
</item> </item>
</section> </section>
@ -355,11 +355,11 @@ Author: Maximilian Mader
<attribute name="id">developer-section-1</attribute> <attribute name="id">developer-section-1</attribute>
<item> <item>
<attribute name="label" translatable="yes">Show Console</attribute> <attribute name="label" translatable="yes">Show Console</attribute>
<attribute name="action">win.show_console</attribute> <attribute name="action">app.show_console</attribute>
</item> </item>
<item> <item>
<attribute name="label" translatable="yes">Clear Console</attribute> <attribute name="label" translatable="yes">Clear Console</attribute>
<attribute name="action">win.clear_console</attribute> <attribute name="action">app.clear_console</attribute>
</item> </item>
</section> </section>
@ -367,7 +367,7 @@ Author: Maximilian Mader
<attribute name="id">developer-section-2</attribute> <attribute name="id">developer-section-2</attribute>
<item> <item>
<attribute name="label" translatable="yes">Break Debugger</attribute> <attribute name="label" translatable="yes">Break Debugger</attribute>
<attribute name="action">win.break_debugger</attribute> <attribute name="action">app.break_debugger</attribute>
</item> </item>
</section> </section>
@ -375,11 +375,11 @@ Author: Maximilian Mader
<attribute name="id">developer-section-3</attribute> <attribute name="id">developer-section-3</attribute>
<item> <item>
<attribute name="label" translatable="yes">Show Memory Viewer</attribute> <attribute name="label" translatable="yes">Show Memory Viewer</attribute>
<attribute name="action">win.open_memory_viewer</attribute> <attribute name="action">app.open_memory_viewer</attribute>
</item> </item>
<item> <item>
<attribute name="label" translatable="yes">Show VRAM Viewer</attribute> <attribute name="label" translatable="yes">Show VRAM Viewer</attribute>
<attribute name="action">win.open_vram_viewer</attribute> <attribute name="action">app.open_vram_viewer</attribute>
</item> </item>
</section> </section>
@ -398,11 +398,11 @@ Author: Maximilian Mader
<attribute name="id">window-section-0</attribute> <attribute name="id">window-section-0</attribute>
<item> <item>
<attribute name="label" translatable="yes">Minimize</attribute> <attribute name="label" translatable="yes">Minimize</attribute>
<attribute name="action">win.minimize</attribute> <attribute name="action">app.minimize</attribute>
</item> </item>
<item> <item>
<attribute name="label" translatable="yes">Zoom</attribute> <attribute name="label" translatable="yes">Zoom</attribute>
<attribute name="action">win.zoom</attribute> <attribute name="action">app.zoom</attribute>
</item> </item>
</section> </section>
@ -410,7 +410,7 @@ Author: Maximilian Mader
<attribute name="id">window-section-1</attribute> <attribute name="id">window-section-1</attribute>
<item> <item>
<attribute name="label" translatable="yes">Bring All to Front</attribute> <attribute name="label" translatable="yes">Bring All to Front</attribute>
<attribute name="action">win.bring_to_front</attribute> <attribute name="action">app.bring_to_front</attribute>
</item> </item>
</section> </section>
</submenu> </submenu>
@ -421,7 +421,7 @@ Author: Maximilian Mader
<attribute name="id">help-section-0</attribute> <attribute name="id">help-section-0</attribute>
<item> <item>
<attribute name="label" translatable="yes">SameBoy Help</attribute> <attribute name="label" translatable="yes">SameBoy Help</attribute>
<attribute name="action">win.help</attribute> <attribute name="action">app.help</attribute>
</item> </item>
</section> </section>
</submenu> </submenu>

View File

@ -612,24 +612,6 @@ Maximilian Mader https://github.com/max-m</property>
<property name="position">3</property> <property name="position">3</property>
</packing> </packing>
</child> </child>
<child>
<object class="GtkCheckButton">
<property name="label" translatable="yes">Keep Aspect Ratio</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="margin_top">5</property>
<property name="margin_bottom">10</property>
<property name="active">True</property>
<property name="draw_indicator">True</property>
<signal name="toggled" handler="on_keep_aspect_ratio_changed" swapped="no"/>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">4</property>
</packing>
</child>
<child> <child>
<object class="GtkCheckButton"> <object class="GtkCheckButton">
<property name="label" translatable="yes">Use Integer Scaling</property> <property name="label" translatable="yes">Use Integer Scaling</property>
@ -648,6 +630,24 @@ Maximilian Mader https://github.com/max-m</property>
<property name="position">4</property> <property name="position">4</property>
</packing> </packing>
</child> </child>
<child>
<object class="GtkCheckButton">
<property name="label" translatable="yes">Keep Aspect Ratio</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="margin_top">5</property>
<property name="margin_bottom">10</property>
<property name="active">True</property>
<property name="draw_indicator">True</property>
<signal name="toggled" handler="on_keep_aspect_ratio_changed" swapped="no"/>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">4</property>
</packing>
</child>
</object> </object>
<packing> <packing>
<property name="position">1</property> <property name="position">1</property>
@ -1258,18 +1258,6 @@ Maximilian Mader https://github.com/max-m</property>
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="orientation">vertical</property> <property name="orientation">vertical</property>
<child>
<object class="GtkDrawingArea" id="vram_viewer_tilemap_canvas">
<property name="visible">True</property>
<property name="app_paintable">True</property>
<property name="can_focus">False</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child> <child>
<object class="GtkBox"> <object class="GtkBox">
<property name="visible">True</property> <property name="visible">True</property>
@ -1384,6 +1372,18 @@ Maximilian Mader https://github.com/max-m</property>
<packing> <packing>
<property name="expand">False</property> <property name="expand">False</property>
<property name="fill">True</property> <property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkDrawingArea" id="vram_viewer_tilemap_canvas">
<property name="visible">True</property>
<property name="app_paintable">True</property>
<property name="can_focus">False</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property> <property name="position">1</property>
</packing> </packing>
</child> </child>