[GTK3] Add Game Boy Printer support
This commit is contained in:
parent
39ad93210c
commit
1201b8928f
2
Makefile
2
Makefile
@ -134,7 +134,7 @@ ifneq ($(findstring gtk3,$(MAKECMDGOALS)),)
|
||||
$(error The gtk3 target requires pkg-config)
|
||||
endif
|
||||
else
|
||||
GTK_OPTIONS := -DGTK_DISABLE_DEPRECATED=1 -DG_DISABLE_DEPRECATED=1 -DG_LOG_DOMAIN=\"SameBoy\" -DRESOURCE_PREFIX=\"/io/github/sameboy/\" -DAPP_ID=\"io.github.sameboy\"
|
||||
GTK_OPTIONS := -DGDK_DISABLE_DEPRECATED=1 -DGTK_DISABLE_DEPRECATED=1 -DG_DISABLE_DEPRECATED=1 -DG_LOG_DOMAIN=\"SameBoy\" -DRESOURCE_PREFIX=\"/io/github/sameboy/\" -DAPP_ID=\"io.github.sameboy\"
|
||||
|
||||
ifeq ($(SDL_AUDIO_DRIVER),sdl)
|
||||
GTK_OPTIONS += -DUSE_SDL_AUDIO
|
||||
|
69
gtk3/main.c
69
gtk3/main.c
@ -17,6 +17,7 @@
|
||||
#include "console_window.h"
|
||||
#include "preferences_window.h"
|
||||
#include "vram_viewer_window.h"
|
||||
#include "printer_window.h"
|
||||
|
||||
// used for audio and game controllers
|
||||
#include "SDL.h"
|
||||
@ -784,6 +785,11 @@ static void reset(void) {
|
||||
GB_load_battery(&gb, gui_data.battery_save_path);
|
||||
GB_load_cheats(&gb, gui_data.cheats_save_path);
|
||||
|
||||
size_t path_length = strlen(path);
|
||||
char printer_suggestion_prefix[path_length];
|
||||
replace_extension(path, path_length, printer_suggestion_prefix, "");
|
||||
printer_window_set_suggestion_prefix(gui_data.printer, printer_suggestion_prefix);
|
||||
|
||||
GError *error = NULL;
|
||||
GBytes *register_sym_f = g_resources_lookup_data(RESOURCE_PREFIX "Misc/registers.sym", G_RESOURCE_LOOKUP_FLAGS_NONE, &error);
|
||||
if (register_sym_f) {
|
||||
@ -793,7 +799,6 @@ static void reset(void) {
|
||||
g_bytes_unref(register_sym_f);
|
||||
}
|
||||
|
||||
size_t path_length = strlen(path);
|
||||
char sym_file_path[path_length + 5];
|
||||
replace_extension(path, path_length, sym_file_path, ".sym");
|
||||
GB_debugger_load_symbol_file(&gb, sym_file_path);
|
||||
@ -844,6 +849,24 @@ static void start(void) {
|
||||
// Prevent dependency loop
|
||||
static void run(void);
|
||||
|
||||
gpointer perform_atomic(gpointer (*fn)(gpointer args), gpointer args) {
|
||||
while (!GB_is_inited(&gb));
|
||||
bool was_running = gui_data.running && !GB_debugger_is_stopped(&gb);
|
||||
|
||||
if (was_running) {
|
||||
stop();
|
||||
}
|
||||
|
||||
// run the callback
|
||||
gpointer ret_val = (*fn)(args);
|
||||
|
||||
if (was_running) {
|
||||
run();
|
||||
}
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
// app.reset GAction
|
||||
// Resets the emulation
|
||||
static void activate_reset(GSimpleAction *action, GVariant *parameter, gpointer app) {
|
||||
@ -1017,9 +1040,9 @@ static void startup(GApplication *app, gpointer null_ptr) {
|
||||
gui_data.console = console_window_new(&gb);
|
||||
gui_data.preferences = preferences_window_new(&gb);
|
||||
gui_data.vram_viewer = vram_viewer_window_new();
|
||||
gui_data.memory_viewer = GTK_WINDOW(get_object("memory_viewer"));
|
||||
gui_data.printer = printer_window_new();
|
||||
|
||||
gui_data.printer = GTK_WINDOW(get_object("printer"));
|
||||
gui_data.memory_viewer = GTK_WINDOW(get_object("memory_viewer"));
|
||||
|
||||
if (config.audio.sample_rate == -1) {
|
||||
gui_data.sample_rate = GB_audio_default_sample_rate();
|
||||
@ -1084,8 +1107,46 @@ G_MODULE_EXPORT void on_quit_activate(GtkWidget *w, gpointer user_data_ptr) {
|
||||
quit();
|
||||
}
|
||||
|
||||
static gboolean draw_printer_image(struct PrinterData *data) {
|
||||
printer_window_update(gui_data.printer, data);
|
||||
|
||||
g_free(data->image);
|
||||
g_slice_free(struct PrinterData, data);
|
||||
return false;
|
||||
}
|
||||
|
||||
static void print_image(GB_gameboy_t *gb, uint32_t *image, uint8_t height, uint8_t top_margin, uint8_t bottom_margin, uint8_t exposure) {
|
||||
struct PrinterData *data = g_slice_alloc(sizeof(struct PrinterData));
|
||||
|
||||
data->image = g_malloc0(160 * height * sizeof(image[0]));
|
||||
memcpy(data->image, image, 160 * height * sizeof(image[0]));
|
||||
|
||||
data->height = height;
|
||||
data->top_margin = top_margin;
|
||||
data->bottom_margin = bottom_margin;
|
||||
data->exposure = exposure;
|
||||
|
||||
g_idle_add((GSourceFunc) draw_printer_image, data);
|
||||
}
|
||||
|
||||
gpointer change_serial_device(gpointer ptr) {
|
||||
gchar *device_id = ptr;
|
||||
|
||||
if (g_strcmp0(device_id, "NONE") == 0) {
|
||||
g_debug("Disconnecting serial device");
|
||||
GB_disconnect_serial(&gb);
|
||||
}
|
||||
else if (g_strcmp0(device_id, "PRINTER") == 0) {
|
||||
g_debug("Connecting printer");
|
||||
GB_connect_printer(&gb, print_image);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool on_change_linked_device(GtkWidget *widget, gpointer user_data) {
|
||||
GtkCheckMenuItem *check_menu_item = GTK_CHECK_MENU_ITEM(widget);
|
||||
gchar *device_id = (gchar *) user_data;
|
||||
|
||||
if (!gtk_check_menu_item_get_active(check_menu_item)) {
|
||||
return true;
|
||||
@ -1094,7 +1155,7 @@ bool on_change_linked_device(GtkWidget *widget, gpointer user_data) {
|
||||
return false;
|
||||
}
|
||||
|
||||
g_message("Not yet implemented");
|
||||
perform_atomic(change_serial_device, device_id);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
213
gtk3/printer_window.c
Normal file
213
gtk3/printer_window.c
Normal file
@ -0,0 +1,213 @@
|
||||
#include "printer_window.h"
|
||||
#include <stdbool.h>
|
||||
#include "util.h"
|
||||
|
||||
struct _PrinterWindow {
|
||||
GtkWindowClass parent_class;
|
||||
|
||||
GtkDrawingArea *printer_canvas;
|
||||
GtkButton *printer_save_button;
|
||||
GtkButton *printer_clear_button;
|
||||
|
||||
uint32_t *current_image;
|
||||
size_t current_height;
|
||||
|
||||
cairo_surface_t *surface;
|
||||
GMutex surface_mutex;
|
||||
|
||||
char *suggestion_prefix;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE(PrinterWindow, printer_window, GTK_TYPE_WINDOW);
|
||||
|
||||
static gboolean on_printer_draw(GtkWidget *widget, cairo_t *cr, PrinterWindow *window) {
|
||||
GtkStyleContext *context = gtk_widget_get_style_context(widget);
|
||||
g_mutex_lock(&window->surface_mutex);
|
||||
|
||||
int width = cairo_image_surface_get_width(window->surface);
|
||||
int height = cairo_image_surface_get_height(window->surface);
|
||||
|
||||
gtk_render_background(context, cr, 0, 0, width, height);
|
||||
gtk_render_frame(context, cr, 0, 0, width, height);
|
||||
|
||||
cairo_scale(cr, 2.0, 2.0);
|
||||
cairo_set_source_surface(cr, window->surface, 0, 0);
|
||||
cairo_pattern_set_filter(cairo_get_source(cr), CAIRO_FILTER_NEAREST);
|
||||
cairo_paint(cr);
|
||||
|
||||
g_mutex_unlock(&window->surface_mutex);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void on_printer_save(GtkWidget *w, PrinterWindow *self) {
|
||||
// This function is defined in `main.c` ...
|
||||
gpointer perform_atomic(gpointer (*fn)(gpointer args), gpointer args);
|
||||
|
||||
// This is ugly, yup.
|
||||
bool success = perform_atomic((gpointer)(*printer_window_save), self);
|
||||
g_debug("File saving status: %d", success);
|
||||
}
|
||||
|
||||
static void on_printer_clear(GtkWidget *w, PrinterWindow *self) {
|
||||
printer_window_clear(self);
|
||||
}
|
||||
|
||||
static void printer_window_init(PrinterWindow *window) {
|
||||
gtk_widget_init_template(GTK_WIDGET(window));
|
||||
|
||||
set_combo_box_row_separator_func(GTK_CONTAINER(window));
|
||||
|
||||
printer_window_clear(window);
|
||||
}
|
||||
|
||||
static void printer_window_finalize(GObject *object) {
|
||||
PrinterWindow *window = (PrinterWindow *) object;
|
||||
|
||||
g_free(window->current_image);
|
||||
cairo_surface_destroy(window->surface);
|
||||
|
||||
G_OBJECT_CLASS(printer_window_parent_class)->finalize(object);
|
||||
}
|
||||
|
||||
static void printer_window_class_init(PrinterWindowClass *class) {
|
||||
gtk_widget_class_set_template_from_resource(GTK_WIDGET_CLASS(class), RESOURCE_PREFIX "ui/printer_window.ui");
|
||||
|
||||
gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), PrinterWindow, printer_canvas);
|
||||
gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), PrinterWindow, printer_save_button);
|
||||
gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), PrinterWindow, printer_clear_button);
|
||||
|
||||
gtk_widget_class_bind_template_callback(GTK_WIDGET_CLASS(class), on_printer_draw);
|
||||
gtk_widget_class_bind_template_callback(GTK_WIDGET_CLASS(class), on_printer_save);
|
||||
gtk_widget_class_bind_template_callback(GTK_WIDGET_CLASS(class), on_printer_clear);
|
||||
|
||||
G_OBJECT_CLASS(class)->finalize = printer_window_finalize;
|
||||
}
|
||||
|
||||
PrinterWindow *printer_window_new(void) {
|
||||
return g_object_new(PRINTER_WINDOW_TYPE, NULL);
|
||||
}
|
||||
|
||||
void printer_window_update(PrinterWindow *self, struct PrinterData *data) {
|
||||
g_mutex_lock(&self->surface_mutex);
|
||||
|
||||
size_t current_size = self->current_height * 160;
|
||||
size_t new_height = self->current_height
|
||||
+ data->top_margin * 8
|
||||
+ data->height
|
||||
+ data->bottom_margin * 8;
|
||||
size_t new_size = new_height * 160 * sizeof(uint32_t);
|
||||
uint32_t *new_image = g_malloc(new_size);
|
||||
|
||||
memset(new_image, 0xFF, new_size); // fill with white
|
||||
memcpy(new_image, self->current_image, current_size * sizeof(uint32_t)); // copy old image
|
||||
memcpy(new_image + current_size + (data->top_margin * 160 * 8), data->image, data->height * 160 * sizeof(uint32_t)); // copy new image
|
||||
|
||||
g_free(self->current_image);
|
||||
self->current_image = new_image;
|
||||
self->current_height = new_height;
|
||||
|
||||
self->surface = cairo_image_surface_create_for_data(
|
||||
(unsigned char*)self->current_image,
|
||||
CAIRO_FORMAT_RGB24,
|
||||
160,
|
||||
self->current_height,
|
||||
cairo_format_stride_for_width(CAIRO_FORMAT_RGB24, 160)
|
||||
);
|
||||
|
||||
// cairo_surface_finish(self->surface);
|
||||
|
||||
g_mutex_unlock(&self->surface_mutex);
|
||||
|
||||
gtk_widget_set_size_request(GTK_WIDGET(self->printer_canvas), 160 * 2, self->current_height * 2);
|
||||
|
||||
gtk_window_present_with_time(GTK_WINDOW(self), time(NULL));
|
||||
}
|
||||
|
||||
void printer_window_clear(PrinterWindow *self) {
|
||||
g_mutex_lock(&self->surface_mutex);
|
||||
|
||||
self->surface = cairo_image_surface_create(CAIRO_FORMAT_RGB24, 160, 0);
|
||||
self->current_image = NULL;
|
||||
self->current_height = 0;
|
||||
|
||||
gtk_widget_set_size_request(GTK_WIDGET(self->printer_canvas), 160 * 2, 0);
|
||||
|
||||
g_mutex_unlock(&self->surface_mutex);
|
||||
}
|
||||
|
||||
bool printer_window_save(PrinterWindow *self) {
|
||||
GtkFileChooserNative *native = gtk_file_chooser_native_new("Save Printed Image", GTK_WINDOW(self), GTK_FILE_CHOOSER_ACTION_SAVE, "_Save", "_Cancel");
|
||||
|
||||
gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(native), true);
|
||||
gtk_file_chooser_set_create_folders(GTK_FILE_CHOOSER(native), true);
|
||||
|
||||
if (self->suggestion_prefix == NULL) {
|
||||
gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(native), "print.png");
|
||||
}
|
||||
else {
|
||||
GString *suggestion = g_string_new(self->suggestion_prefix);
|
||||
|
||||
#if GLIB_CHECK_VERSION(2,62,0)
|
||||
gchar *date = g_date_time_format_iso8601(g_date_time_new_now_local());
|
||||
#else
|
||||
GTimeVal tv;
|
||||
g_get_current_time(&tv);
|
||||
gchar *date = g_time_val_to_iso8601(&tv);
|
||||
#endif
|
||||
|
||||
g_string_append_printf(suggestion, "_printout_%s.png", date);
|
||||
|
||||
for (gsize i = 0; i < suggestion->len; i++) {
|
||||
if (suggestion->str[i] == ':') {
|
||||
suggestion->str[i] = '-';
|
||||
}
|
||||
}
|
||||
|
||||
gchar *basename = g_path_get_basename(suggestion->str);
|
||||
gchar *dirname = g_path_get_dirname(suggestion->str);
|
||||
|
||||
gtk_file_chooser_select_filename(GTK_FILE_CHOOSER(native), suggestion->str);
|
||||
gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(native), basename);
|
||||
|
||||
g_free(dirname);
|
||||
g_free(basename);
|
||||
g_string_free(suggestion, true);
|
||||
g_free(date);
|
||||
}
|
||||
|
||||
GtkFileFilter *filter = gtk_file_filter_new();
|
||||
gtk_file_filter_add_pattern(filter, "*.png");
|
||||
gtk_file_filter_add_mime_type(filter, "image/png");
|
||||
gtk_file_filter_set_name(filter, "PNG");
|
||||
gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(native), filter);
|
||||
|
||||
gint res = gtk_native_dialog_run(GTK_NATIVE_DIALOG(native));
|
||||
|
||||
if (res == GTK_RESPONSE_ACCEPT) {
|
||||
const char* path = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(native));
|
||||
|
||||
g_mutex_lock(&self->surface_mutex);
|
||||
cairo_status_t status = cairo_surface_write_to_png(self->surface, path);
|
||||
g_mutex_unlock(&self->surface_mutex);
|
||||
|
||||
return status == CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
g_object_unref(native);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void printer_window_set_suggestion_prefix(PrinterWindow *self, char* prefix) {
|
||||
if (self->suggestion_prefix != NULL) {
|
||||
g_free(self->suggestion_prefix);
|
||||
}
|
||||
|
||||
if (prefix != NULL) {
|
||||
self->suggestion_prefix = g_strdup(prefix);
|
||||
}
|
||||
else {
|
||||
self->suggestion_prefix = NULL;
|
||||
}
|
||||
}
|
25
gtk3/printer_window.h
Normal file
25
gtk3/printer_window.h
Normal file
@ -0,0 +1,25 @@
|
||||
#ifndef printer_window_h
|
||||
#define printer_window_h
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include <Core/gb.h>
|
||||
#include <stdint.h>
|
||||
|
||||
struct PrinterData {
|
||||
uint32_t *image;
|
||||
uint8_t height;
|
||||
uint8_t top_margin;
|
||||
uint8_t bottom_margin;
|
||||
uint8_t exposure;
|
||||
};
|
||||
|
||||
#define PRINTER_WINDOW_TYPE (printer_window_get_type())
|
||||
G_DECLARE_FINAL_TYPE(PrinterWindow, printer_window, SAMEBOY, PRINTER_WINDOW, GtkWindow)
|
||||
|
||||
PrinterWindow *printer_window_new(void);
|
||||
void printer_window_clear(PrinterWindow *self);
|
||||
bool printer_window_save(PrinterWindow *self);
|
||||
void printer_window_update(PrinterWindow *self, struct PrinterData *data);
|
||||
void printer_window_set_suggestion_prefix(PrinterWindow *self, char* prefix);
|
||||
|
||||
#endif
|
@ -1,9 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Generated with glade 3.36.0
|
||||
<!--
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015-2019 Lior Halphon
|
||||
Copyright (c) 2015-2021 Lior Halphon
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
@ -31,7 +31,7 @@ Author: Maximilian Mader
|
||||
<!-- interface-license-type mit -->
|
||||
<!-- interface-name SameBoy -->
|
||||
<!-- interface-description SameBoy is an open source Game Boy (DMG) and Game Boy Color (CGB) emulator, written in portable C. -->
|
||||
<!-- interface-copyright 2015-2019 Lior Halphon -->
|
||||
<!-- interface-copyright 2015-2021 Lior Halphon -->
|
||||
<!-- interface-authors Maximilian Mader -->
|
||||
<template class="ConsoleWindow">
|
||||
<property name="can_focus">False</property>
|
||||
|
@ -1,9 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Generated with glade 3.36.0
|
||||
<!--
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015-2019 Lior Halphon
|
||||
Copyright (c) 2015-2021 Lior Halphon
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
@ -31,7 +31,7 @@ Author: Maximilian Mader
|
||||
<!-- interface-license-type mit -->
|
||||
<!-- interface-name SameBoy -->
|
||||
<!-- interface-description SameBoy is an open source Game Boy (DMG) and Game Boy Color (CGB) emulator, written in portable C. -->
|
||||
<!-- interface-copyright 2015-2019 Lior Halphon -->
|
||||
<!-- interface-copyright 2015-2021 Lior Halphon -->
|
||||
<!-- interface-authors Maximilian Mader -->
|
||||
<template class="PreferencesWindow">
|
||||
<property name="can_focus">False</property>
|
||||
|
103
gtk3/resources/ui/printer_window.ui
Normal file
103
gtk3/resources/ui/printer_window.ui
Normal file
@ -0,0 +1,103 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015-2019 Lior Halphon
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
Author: Maximilian Mader
|
||||
|
||||
-->
|
||||
<interface>
|
||||
<requires lib="gtk+" version="3.22"/>
|
||||
<!-- interface-license-type mit -->
|
||||
<!-- interface-name SameBoy -->
|
||||
<!-- interface-description SameBoy is an open source Game Boy (DMG) and Game Boy Color (CGB) emulator, written in portable C. -->
|
||||
<!-- interface-copyright 2015-2021 Lior Halphon -->
|
||||
<!-- interface-authors Maximilian Mader -->
|
||||
<template class="PrinterWindow">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="resizable">False</property>
|
||||
<property name="default_width">320</property>
|
||||
<property name="default_height">432</property>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow">
|
||||
<property name="min-content-height">432</property>
|
||||
<property name="max-content-height">432</property>
|
||||
<property name="hexpand">0</property>
|
||||
<property name="vexpand">1</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="shadow_type">in</property>
|
||||
<child>
|
||||
<object class="GtkViewport">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="shadow_type">none</property>
|
||||
<child>
|
||||
<object class="GtkDrawingArea" id="printer_canvas">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<signal name="draw" handler="on_printer_draw" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child type="titlebar">
|
||||
<object class="GtkHeaderBar">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="title" translatable="yes">Printer</property>
|
||||
<property name="has_subtitle">False</property>
|
||||
<property name="show_close_button">True</property>
|
||||
<child>
|
||||
<object class="GtkButton" id="printer_save_button">
|
||||
<property name="label">gtk-save</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="use_stock">True</property>
|
||||
<signal name="clicked" handler="on_printer_save" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="pack_type">end</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="printer_clear_button">
|
||||
<property name="label">gtk-delete</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="use_stock">True</property>
|
||||
<signal name="clicked" handler="on_printer_clear" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="pack_type">end</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</template>
|
||||
</interface>
|
@ -1,9 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Generated with glade 3.36.0
|
||||
<!--
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015-2019 Lior Halphon
|
||||
Copyright (c) 2015-2021 Lior Halphon
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
@ -31,7 +31,7 @@ Author: Maximilian Mader
|
||||
<!-- interface-license-type mit -->
|
||||
<!-- interface-name SameBoy -->
|
||||
<!-- interface-description SameBoy is an open source Game Boy (DMG) and Game Boy Color (CGB) emulator, written in portable C. -->
|
||||
<!-- interface-copyright 2015-2019 Lior Halphon -->
|
||||
<!-- interface-copyright 2015-2021 Lior Halphon -->
|
||||
<!-- interface-authors Maximilian Mader -->
|
||||
<template class="VramViewerWindow">
|
||||
<property name="can_focus">False</property>
|
||||
|
@ -1,9 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Generated with glade 3.36.0
|
||||
<!--
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015-2019 Lior Halphon
|
||||
Copyright (c) 2015-2021 Lior Halphon
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
@ -31,7 +31,7 @@ Author: Maximilian Mader
|
||||
<!-- interface-license-type mit -->
|
||||
<!-- interface-name SameBoy -->
|
||||
<!-- interface-description SameBoy is an open source Game Boy (DMG) and Game Boy Color (CGB) emulator, written in portable C. -->
|
||||
<!-- interface-copyright 2015-2019 Lior Halphon -->
|
||||
<!-- interface-copyright 2015-2021 Lior Halphon -->
|
||||
<!-- interface-authors Maximilian Mader -->
|
||||
<object class="GtkAboutDialog" id="about_dialog">
|
||||
<property name="can_focus">False</property>
|
||||
@ -123,66 +123,6 @@ Maximilian Mader https://github.com/max-m</property>
|
||||
<placeholder/>
|
||||
</child>
|
||||
</object>
|
||||
<object class="GtkWindow" id="printer">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="resizable">False</property>
|
||||
<property name="default_width">320</property>
|
||||
<property name="default_height">432</property>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="shadow_type">in</property>
|
||||
<child>
|
||||
<object class="GtkViewport">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="shadow_type">none</property>
|
||||
<child>
|
||||
<object class="GtkDrawingArea" id="printer_canvas">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child type="titlebar">
|
||||
<object class="GtkHeaderBar">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="title" translatable="yes">Printer</property>
|
||||
<property name="has_subtitle">False</property>
|
||||
<property name="show_close_button">True</property>
|
||||
<child>
|
||||
<object class="GtkButton" id="printer_save_button">
|
||||
<property name="label">gtk-save</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="use_stock">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="pack_type">end</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="printer_clear_button">
|
||||
<property name="label">gtk-delete</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="use_stock">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="pack_type">end</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<object class="GtkRecentFilter" id="recent_files_filter">
|
||||
<mime-types>
|
||||
<mime-type>application/x-gameboy-rom</mime-type>
|
||||
|
@ -5,11 +5,7 @@
|
||||
<file preprocess="xml-stripblanks" compressed="true">ui/console_window.ui</file>
|
||||
<file preprocess="xml-stripblanks" compressed="true">ui/preferences_window.ui</file>
|
||||
<file preprocess="xml-stripblanks" compressed="true">ui/vram_viewer_window.ui</file>
|
||||
<!--
|
||||
<file preprocess="xml-stripblanks">gtk/menus.ui</file>
|
||||
<file preprocess="xml-stripblanks">gtk/menus-common.ui</file>
|
||||
<file preprocess="xml-stripblanks">gtk/menus-traditional.ui</file>
|
||||
-->
|
||||
<file preprocess="xml-stripblanks" compressed="true">ui/printer_window.ui</file>
|
||||
|
||||
<file compressed="true">css/main.css</file>
|
||||
<file compressed="true" alias="gamecontrollerdb.txt">gamecontrollerdb_d3f1cea1.txt</file>
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include "console_window.h"
|
||||
#include "preferences_window.h"
|
||||
#include "vram_viewer_window.h"
|
||||
#include "printer_window.h"
|
||||
|
||||
typedef struct{
|
||||
int16_t x, y;
|
||||
@ -45,9 +46,9 @@ typedef struct GuiData {
|
||||
ConsoleWindow *console;
|
||||
PreferencesWindow *preferences;
|
||||
VramViewerWindow *vram_viewer;
|
||||
PrinterWindow *printer;
|
||||
|
||||
GtkWindow *memory_viewer;
|
||||
GtkWindow *printer;
|
||||
|
||||
// Audio and video
|
||||
bool audio_initialized;
|
||||
|
Loading…
Reference in New Issue
Block a user