/* Hey EMACS -*- linux-c -*- */ /* TiEmu - Tiemu Is an EMUlator * * Copyright (c) 2000-2001, Thomas Corvazier, Romain Lievin * Copyright (c) 2001-2003, Romain Lievin * Copyright (c) 2003, Julien Blache * Copyright (c) 2004, Romain Liévin * Copyright (c) 2005-2007, Romain Liévin, Kevin Kofler * Copyright (c) 2007, Peter Fernandes * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include #include #include #ifdef __WIN32__ #undef setjmp extern int asm_setjmp(jmp_buf b); #define setjmp asm_setjmp #include "oleaut_c.h" #endif #if WITH_KDE #include "kde.h" #endif #if WITH_DBUS #include "dbus_ipc.h" #endif #include "intl.h" #include "cflibs.h" #include "struct.h" #include "calc.h" #include "cmdline.h" #include "files.h" #include "rcfile.h" #include "ti68k_int.h" #include "logging.h" #include "engine.h" #include "refresh.h" #include "calc.h" #include "wizard.h" #include "popup.h" #include "splash.h" #include "tie_error.h" #include "dboxes.h" #include "dbg_all.h" #include "romversion.h" #include "fs_misc.h" #ifndef NO_SOUND #include "audio.h" #endif #ifndef NO_GDB #include "gdbcall.h" #include "../gdb/gdb/main.h" #include "../gdb/gdb/gdb_string.h" #ifndef PARAMS #define PARAMS(x) x #endif #define READLINE_LIBRARY #include "../gdb/readline/readline.h" void gdbtk_hide_insight(void); void gdbtk_delete_interp(void); static void start_insight_timer(void); static void stop_insight_timer(void); static gint gdbtk_hide_insight_and_run_wrapper(gpointer data); #endif ScrOptions options2; TieOptions options; // general tiemu options jmp_buf quit_gdb; // longjmp target used when quitting GDB /* Special */ static gint exit_loop = 0; void exit_main_loop(void) { exit_loop = !0; } static void my_log_handler (const gchar *log_domain, GLogLevelFlags log_level, const gchar *message, gpointer user_data) {} /* Main function */ extern char *file_to_send; int main(int argc, char **argv) { int err; /* Do primary initializations */ /* Display program version */ tiemu_version(); /* Initialize platform independant paths */ initialize_paths(); /* Init i18n support */ #ifdef ENABLE_NLS tiemu_info("setlocale: <%s>", setlocale(LC_ALL, "")); tiemu_info("bindtextdomain: <%s>", bindtextdomain(PACKAGE, inst_paths.locale_dir)); bind_textdomain_codeset(PACKAGE, "UTF-8"/*"ISO-8859-15"*/); tiemu_info("textdomain: <%s>", textdomain(PACKAGE)); #endif /* Initialize/reload config */ rcfile_default(); // (step 2) rcfile_read(); /* Scan and modify command line */ scan_cmdline(argc, argv); #ifndef NO_SOUND //init audio lib if(audio_init()) { tiemu_warning(_("Unable to initialize audio, sound will not play\n")); audioerr=1; } #endif /* Init GTK+ toolkit */ gtk_init(&argc, &argv); add_pixmap_directory(inst_paths.pixmap_dir); /* Get rid of glib, gdk, gtk warnings when compiled in Release mode */ #if !defined(_DEBUG) g_log_set_handler ("GLib", G_LOG_LEVEL_WARNING | G_LOG_LEVEL_MESSAGE | G_LOG_LEVEL_INFO | G_LOG_LEVEL_DEBUG, my_log_handler, NULL); g_log_set_handler ("Gdk", G_LOG_LEVEL_WARNING | G_LOG_LEVEL_MESSAGE | G_LOG_LEVEL_INFO | G_LOG_LEVEL_DEBUG, my_log_handler, NULL); g_log_set_handler ("Gtk", G_LOG_LEVEL_WARNING | G_LOG_LEVEL_MESSAGE | G_LOG_LEVEL_INFO | G_LOG_LEVEL_DEBUG, my_log_handler, NULL); g_log_set_handler ("GLib", G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION, my_log_handler, NULL); #endif /* Set splash screen */ #ifndef __IPAQ__ splash_screen_start(); splash_screen_set_label(_("Initializing GTK+...")); #endif #if WITH_KDE splash_screen_set_label(_("Initializing KDE...")); sp_kde_init(argc, argv, "tiemu", _("TiEmu"), VERSION, _("TI calculator emulator"), "Copyright (c) 2000, Thomas Corvazier, Romain Lievin\nCopyright (c) 2001-2002, Romain Lievin, Julien Blache\nCopyright (c) 2003-2004, Romain Lievin\nCopyright (c) 2005-2007, Romain Lievin, Kevin Kofler\nCopyright (c) 2007, Peter Fernandes", "http://lpg.ticalc.org/prj_tiemu/", "gtktiemu-users@lists.sf.net"); atexit(sp_kde_finish); g_timeout_add(26, sp_kde_process_qt_events, NULL); #endif #if WITH_DBUS splash_screen_set_label(_("Initializing D-Bus...")); dbus_init(); atexit(dbus_finish); #endif #ifdef __WIN32__ splash_screen_set_label(_("Initializing OLE...")); oleaut_init(); atexit(oleaut_finish); #endif /* Check the version of libraries */ splash_screen_set_label(_("Initializing TiLP framework...")); /* Search for dumps or upgrades to convert (in the image directory) */ splash_screen_set_label(_("Searching for ROM dumps...")); err = ti68k_scan_files(inst_paths.img_dir, inst_paths.img_dir, !0); handle_error(); /* Attempt to load an image (step 3) */ while(!exit_loop) { /* Windows follows the locale settings even for basic stdio I/O functions. This is an annoyance for floating-point numbers in GDB, so we override it here. Unfortunately, this disease seems to have spread to glibc as well recently. */ setlocale(LC_NUMERIC, "C"); err = ti68k_load_image(params.rom_file); if(err) { rescan: if(ti68k_find_image(inst_paths.img_dir, NULL)) { // search for an available image to use if(display_romversion_dbox(TRUE) == -1) goto wizard; } else { // launch wizard wizard: display_wizard_dbox(); while(!wizard_ok) GTK_REFRESH(); if(wizard_ok == 2) goto rescan; g_free(params.rom_file); params.rom_file = g_strdup(wizard_rom); g_free(wizard_rom); } splash_screen_set_label(_("Loading image...")); err = ti68k_load_image(params.rom_file); handle_error(); } /* Initialize emulation engine (step 4) */ splash_screen_set_label(_("Initializing m68k emulation engine...")); err = ti68k_init(); handle_error(); if(err) return -1; err = hid_init(); handle_error(); if(err) return -1; /* Load FLASH upgrade (if any) */ if(params.tib_file != NULL) { err = ti68k_load_upgrade(params.tib_file); handle_error(); } /* Override refresh functions of the libcalcprotocols library (must be done after init of ti68k engine) */ tiemu_update_set_gtk(); /* Reset emulation engine (step 5) */ ti68k_reset(); /* Load calculator state image */ splash_screen_set_label(_("Loading previously saved state...")); if(params.sav_file != NULL) { err = ti68k_state_load(params.sav_file); handle_error(); } /* Cache debugger windows to speed-up display and install custom event */ #ifndef __IPAQ__ splash_screen_set_label(_("Pre-loading debugger...")); gtk_debugger_preload(); #endif /* Check for a file to send */ if(file_to_send) { if(!img_loaded || !ti68k_linkport_ready()) break; fs_send_file(file_to_send); g_free(file_to_send); } /* Start emulation engine and run main loop */ splash_screen_stop(); #ifdef NO_GDB engine_start(); gtk_main(); engine_stop(); #else /* Run Insight GDB */ start_insight_timer(); if (setjmp(quit_gdb) == 0) { struct captured_main_args args; memset (&args, 0, sizeof args); args.argc = argc; args.argv = argv; args.use_windows = 1; args.interpreter_p = "insight"; g_idle_add(gdbtk_hide_insight_and_run_wrapper, NULL); gdb_main (&args); } stop_insight_timer(); /* Clean up in case we interrupted GDB during command-line parsing */ rl_callback_handler_remove(); #endif err = hid_exit(); handle_error(); err = ti68k_exit(); handle_error(); ti68k_unload_image_or_upgrade(); } #ifndef NO_GDB gdbtk_delete_interp(); #endif return 0; } /* These functions are used by Insight to enable/disable its UI hook. */ #ifndef NO_GDB int x_event(int); static guint gdbtk_timer_id = 0; static gint tiemu_x_event_wrapper(gpointer data) { x_event(0); return TRUE; } static void start_insight_timer(void) { if (!gdbtk_timer_id) gdbtk_timer_id = g_timeout_add(25, tiemu_x_event_wrapper, NULL); /* 25 ms */ } static void stop_insight_timer(void) { if (gdbtk_timer_id) { g_source_remove(gdbtk_timer_id); gdbtk_timer_id = 0; } } static gint gdbtk_hide_insight_and_run_wrapper(gpointer data) { gdbtk_hide_insight(); gdbcall_run(); return FALSE; } #endif /* If GtkTiEmu is compiled in console mode (_CONSOLE), then we use the 'main' entry point. If GtkTiEmu is compiled as a windowed application (_WINDOWS), then we use the 'WinMain' entry point. */ #if defined(__WIN32__) && defined(_WINDOWS)// && !defined(_CONSOLE) #ifdef __MINGW32__ #include #endif int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { return main(__argc, __argv); } #endif