#ifndef main_h #define main_h // used for audio and game controllers #include "SDL.h" #include #include #include #include #include #include #include #include "macros.h" #include "settings.h" #include "shader.h" typedef struct GuiData { struct CliOptionData { gchar *config_path; gchar *boot_rom_path; gboolean fullscreen; GB_model_t model; } cli_options; GFile *file; gint sample_rate; bool stopped; GB_model_t prev_model; } GuiData; typedef struct{ int16_t x, y; uint16_t w, h; } Rect; typedef struct LogData { GB_gameboy_t *gb; const char *string; GB_log_attributes attributes; } LogData; #define JOYSTICK_HIGH 0x4000 #define JOYSTICK_LOW 0x3800 #define BUTTON_MASK_A 0x01 #define BUTTON_MASK_B 0x02 #define BUTTON_MASK_START 0x04 #define BUTTON_MASK_SELECT 0x08 #define BUTTON_MASK_UP 0x10 #define BUTTON_MASK_DOWN 0x20 #define BUTTON_MASK_LEFT 0x40 #define BUTTON_MASK_RIGHT 0x80 int main(int argc, char *argv[]); static gint handle_local_options(GApplication *app, GVariantDict *options, gpointer user_data_gptr); // GtkGlArea crash workaround gboolean test_gl_support(void); void gl_check_realize(GtkWidget *w, gpointer user_data_gptr); static gboolean init_controllers(); static gboolean init_audio(); static void gb_audio_callback(GB_gameboy_t *gb, GB_sample_t *sample); static char *sync_console_input(GB_gameboy_t *gb); static char *async_console_input(GB_gameboy_t *gb); static void on_console_log(gpointer user_data_gptr); static void console_log(GB_gameboy_t *gb, const char *string, GB_log_attributes attributes); static GMenuModel *get_menu_model(GApplication *app, const char *id); static void create_fallback_canvas(void); static void setup_menu(GApplication *app); static void set_combo_box_row_separator_func(GtkContainer *container); static gboolean is_separator(GtkTreeModel *model, GtkTreeIter *iter, gpointer data); // Rendering support functions static unsigned char number_of_buffers(void); static uint32_t *get_pixels(void); static uint32_t *get_current_buffer(void); static uint32_t *get_previous_buffer(void); static void flip(void); static void quit_interrupt(int ignored); // GApplication signals static void startup(GApplication *app, gpointer user_data_gptr); static void activate(GApplication *app, gpointer user_data_gptr); static void shutdown(GApplication *app, GFile **files, gint n_files, const gchar *hint, gpointer user_data_gptr); static void open(GApplication *app, GFile **files, gint n_files, const gchar *hint, gpointer user_data_gptr); static void quit(GApplication *app); static gboolean on_key_press(GtkWidget *w, GdkEventKey *event, gpointer data); static void on_window_state_change(GtkWidget *w, GdkEventWindowState *event, gpointer data); // App actions static void activate_about(GSimpleAction *action, GVariant *parameter, gpointer app); static void activate_show_console(GSimpleAction *action, GVariant *parameter, gpointer app); static void activate_open_gtk_debugger(GSimpleAction *action, GVariant *parameter, gpointer app); static void activate_open_memory_viewer(GSimpleAction *action, GVariant *parameter, gpointer app); static void activate_open_vram_viewer(GSimpleAction *action, GVariant *parameter, gpointer app); static void activate_open(GSimpleAction *action, GVariant *parameter, gpointer app); static void activate_preferences(GSimpleAction *action, GVariant *parameter, gpointer app); static void activate_quit(GSimpleAction *action, GVariant *parameter, gpointer app); static void activate_reset(GSimpleAction *action, GVariant *parameter, gpointer app); static void on_model_changed(GSimpleAction *action, GVariant *value, gpointer user_data); static void on_mute_changed(GSimpleAction *action, GVariant *value, gpointer user_data); static void on_pause_changed(GSimpleAction *action, GVariant *value, gpointer user_data); static void on_quit(GtkWidget *w, gpointer app); // Signal callback static void on_quit(GtkWidget *w, gpointer app); // Renderer area bindings static void gl_init(GtkWidget *w); static void gl_draw(); static void gl_finish(); static gboolean on_draw_fallback(GtkWidget *widget, cairo_t *cr, gpointer data); static void resize(); // VRAM viewer bindings static void on_vram_viewer_realize(); static void on_vram_viewer_unrealize(); static gboolean on_draw_vram_viewer_tileset(GtkWidget *widget, cairo_t *cr, gpointer data); static gboolean on_draw_vram_viewer_tilemap(GtkWidget *widget, cairo_t *cr, gpointer data); static gboolean on_motion_vram_viewer_tileset(GtkWidget *widget, GdkEventMotion *event); static gboolean on_motion_vram_viewer_tilemap(GtkWidget *widget, GdkEventMotion *event); static void on_vram_tab_change(GtkWidget *widget, GParamSpec *pspec, GtkStackSwitcher *self); // Option bindings G_MODULE_EXPORT void on_boot_rom_location_changed(GtkWidget *w, gpointer user_data_gptr); G_MODULE_EXPORT void on_cgb_model_changed(GtkWidget *w, gpointer user_data_gptr); G_MODULE_EXPORT void on_color_correction_changed(GtkWidget *w, gpointer user_data_gptr); G_MODULE_EXPORT void on_color_menubar_override_changed(GtkWidget *w, gpointer user_data_gptr); G_MODULE_EXPORT void on_dmg_model_changed(GtkWidget *w, gpointer user_data_gptr); G_MODULE_EXPORT void on_graphic_filter_changed(GtkWidget *w, gpointer user_data_gptr); G_MODULE_EXPORT void on_highpass_filter_changed(GtkWidget *w, gpointer user_data_gptr); G_MODULE_EXPORT void on_keep_aspect_ratio_changed(GtkWidget *w, gpointer user_data_gptr); G_MODULE_EXPORT void on_rewind_duration_changed(GtkWidget *w, gpointer user_data_gptr); G_MODULE_EXPORT void on_sgb_model_changed(GtkWidget *w, gpointer user_data_gptr); G_MODULE_EXPORT void on_use_integer_scaling_changed(GtkWidget *w, gpointer user_data_gptr); G_MODULE_EXPORT void console_on_enter(GtkWidget *w, gpointer user_data_gptr); static uint32_t rgb_encode(GB_gameboy_t *gb, uint8_t r, uint8_t g, uint8_t b); static void render_texture(void *pixels, void *previous); static void update_viewport(void); static void update_window_geometry(); static void run(GuiData *gui_data); static gpointer run_thread(gpointer user_data_gptr); static void init(GuiData *gui_data); static void load_boot_rom(GuiData *gui_data); static void handle_events(GB_gameboy_t *gb); static uint32_t convert_color(uint16_t color); static void palette_color_data_func(GtkTreeViewColumn *col, GtkCellRenderer *renderer, GtkTreeModel *model, GtkTreeIter *iter, gpointer user_data); static void on_vblank(gpointer data); static void vblank(GB_gameboy_t *gb); static void reset(GuiData *gui_data); static void stop(GuiData *gui_data); static void start(GuiData *gui_data); #endif /* main_h */