home *** CD-ROM | disk | FTP | other *** search
- /*
- #error in disk dialog, need to quote string c:\tidisk\disk
- #error move win32 code into winloop.c again
- #error figure out why the startup problems sometimes
- #error why do we need to reparent?
- #error upon parse error, force reset of parser (escapes and such appear to cause this)
- #error propagate closes (v9t9_window)
- #error be sure to use correct log
- */
- #include "winv9t9.h"
- #include "v9t9_common.h"
-
- #include <gtk/gtk.h>
- #include "gtkloop.h"
- #include "gtkinterface.h"
-
- #include "log.h"
- #include "9900.h"
- #include "memory.h"
- #include "vdp.h"
- #include "timer.h"
- #include "v9t9.h"
- #include "video.h"
- #include "system.h"
- #include "command.h"
- #include "resource.h"
- #include "moduleconfig.h"
-
- #include "video_win32.h"
-
- #define _L LOG_INFO | LOG_HOSTOS
-
- static int _argc_;
- static char **_argv_;
-
- extern vmModule win32DirectDrawVideo, win32DrawDibVideo;
- extern vmModule win32KbdModule;
-
- // used by directsound
- HWND hWndApp;
- HWND hWndWindow, hWndStatus; // our windows
- HWND hWndScreen; // DD window
- //HACCEL hAccelerators; // key accelerators
-
- HINSTANCE myHInst, myHPreInst; // startup params for video modules
- int mynCmdShow;
-
- static void
- system_initlog(void);
-
- static void
- system_termlog(void);
-
- int (*frontend_loop)(void) = 0L;
- void (*frontend_getcommands)(void);
- void (*frontend_log)(u32 srcflags, const char *text) = 0L;
- //void (*frontend_statusline)(int line, const char *text) = 0L;
- void (*frontend_report_status)(status_item item, va_list va) = 0L;
- void (*frontend_debugger_enabled)(bool enabled) = 0L;
- void (*frontend_execution_paused)(bool paused) = 0L;
-
-
- static void
- MakeARGV(char *cmd)
- {
- int quoting = 0;
- char *ptr = cmd;
- char *arg = NULL;
-
- while (*ptr && isspace(*ptr))
- ptr++;
-
- _argc_ = 0;
- _argv_ = 0;
-
- _argv_ = (char **) xmalloc(2 * sizeof(char *));
-
- _argv_[_argc_++] = "v9t9";
-
- while (*ptr) {
- if (arg == NULL) {
- _argv_ =
-
- (char **) xrealloc(_argv_, (_argc_ + 2) * sizeof(char *));
- arg = _argv_[_argc_] = ptr;
- _argc_++;
- }
-
- if (quoting && *ptr == '\"') {
- ptr++;
- quoting = 0;
- } else if (quoting)
- *arg++ = *ptr++;
- else if (*ptr == '\"') {
- ptr++;
- quoting = 1;
- } else if (*ptr == ' ') {
- *arg = 0;
- arg = NULL;
- ptr++;
- } else
- *arg++ = *ptr++;
- }
- if (arg)
- *arg = 0;
- _argv_[_argc_] = 0;
- }
-
-
- int win_frontend;
-
- int WINAPI
- WinMain(HINSTANCE hInst, /*Win32 entry-point routine */
- HINSTANCE hPreInst, LPSTR lpszCmdLine, int nCmdShow)
- {
- int ret;
-
- win_frontend = FE_UNKNOWN;
-
- system_initlog();
- initlog();
-
- if (!win_createBitmap())
- return vmInternalError;
-
- MakeARGV(lpszCmdLine);
-
- #define argc v9t9_argc
- #define argv v9t9_argv
-
- v9t9_config(_argc_, _argv_);
-
- /* Look for explicit choice of win_frontend */
- if (argc > 2 && strcmp(argv[1], "-fe") == 0) {
- #if HAS_DDRAW
- if (strcasecmp(argv[2], "ddraw") == 0) {
- win_frontend = FE_DDRAW;
- argv += 2;
- argc -= 2;
- } else
- #endif
- #if HAS_DRAWDIB
- if (strcasecmp(argv[2], "drawdib") == 0 ||
- strcasecmp(argv[2], "win32") == 0) {
- win_frontend = FE_DRAWDIB;
- argv += 2;
- argc -= 2;
- } else
- #endif
- #if HAS_GTK
- if (strcasecmp(argv[2], "gtk") == 0) {
- win_frontend = FE_GTK;
- argv += 2;
- argc -= 2;
- } else
- #endif
- {
- logger(_L|LOG_USER|LOG_ERROR, "Unknown option '%s %s';\n"
- "expected one of "
- #if HAS_DDRAW
- "ddraw|"
- #endif
- #if HAS_DRAWDIB
- "win32|"
- #endif
- #if HAS_GTK
- "gtk"
- #endif
- "\n",
- argv[1], argv[2]);
- return 1;
- }
- }
-
- #if HAS_GTK && HAS_DRAWDIB
- if ((win_frontend == FE_UNKNOWN || win_frontend == FE_GTK) &&
- GTK_system_init()) {
- char *var;
-
- win_frontend = FE_GTK;
- frontend_log = GTK_system_log;
- frontend_getcommands = win32_system_getcommands;
- frontend_report_status = GTK_system_report_status;
- frontend_debugger_enabled = GTK_system_debugger_enabled;
- frontend_execution_paused = GTK_system_execution_paused;
- frontend_loop = win32_gtk_system_loop;
-
- #if HAS_DDRAW
- win32DirectDrawVideo.runtimeflags |= vmRTUnselected;
- #endif
- #if HAS_DRAWDIB
- // win32DrawDibVideo.runtimeflags |= vmRTUnselected;
- #endif
-
- // why why why does the GTK win32 interface suck so bad?
- // I got over the video speed problems but finally
- // hit a dead end when finding that the keyboard events
- // are always on/off right in succession, even with the
- // key held down... sigh...
- gtkVideo.runtimeflags |= vmRTUnselected;
- gtkKeyboard.runtimeflags |= vmRTUnselected;
-
- // don't ask me why, but the presence of this
- // variable causes a MASSIVE startup delay
- var = getenv("HOME");
- if (var) *var = 0;
- SetEnvironmentVariable("HOME", NULL);
-
- logger(_L|LOG_USER, "Using GTK\n");
-
- #if 1
- v9t9_window = create_v9t9_window();
- v9t9_drawing_area = gtk_object_get_data(GTK_OBJECT(v9t9_window),
- "v9t9_drawing_area");
- // don't show this since it's empty! (drawdib puts up separate window)
- // gtk_widget_show(v9t9_window);
- #endif
- } else
- #endif
- #if HAS_DRAWDIB
- if ((win_frontend == FE_UNKNOWN || win_frontend == FE_DRAWDIB) &&
- win32_system_init()) {
- win_frontend = FE_DRAWDIB;
- frontend_log = win32_system_log;
- frontend_getcommands = win32_system_getcommands;
- frontend_report_status = win32_system_report_status;
- frontend_debugger_enabled = win32_system_debugger_enabled;
- frontend_execution_paused = win32_system_execution_paused;
- frontend_loop = win32_system_loop;
-
- #if HAS_DDRAW
- win32DirectDrawVideo.runtimeflags |= vmRTUnselected;
- //win32Keyboard.runtimeflags |= vmRTUnselected;
- #endif
- #if HAS_GTK
- gtkVideo.runtimeflags |= vmRTUnselected;
- gtkKeyboard.runtimeflags |= vmRTUnselected;
- #endif
- logger(_L|LOG_USER, "Using DrawDib\n");
- } else
- #endif
- #if HAS_DDRAW
- if ((win_frontend == FE_UNKNOWN || win_frontend == FE_DDRAW) &&
- win32_system_init()) {
- win_frontend = FE_DDRAW;
- frontend_log = win32_system_log;
- frontend_getcommands = win32_system_getcommands;
- frontend_report_status = win32_system_report_status;
- frontend_debugger_enabled = win32_system_debugger_enabled;
- frontend_execution_paused = win32_system_execution_paused;
- frontend_loop = win32_system_loop;
-
- #if HAS_DRAWDIB
- win32DrawDibVideo.runtimeflags |= vmRTUnselected;
- //win32Keyboard.runtimeflags |= vmRTUnselected;
- #endif
- #if HAS_GTK
- gtkVideo.runtimeflags |= vmRTUnselected;
- gtkKeyboard.runtimeflags |= vmRTUnselected;
- #endif
-
- logger(_L|LOG_USER, "Using DirectDraw\n");
- } else
- #endif
- {
- logger(_L|LOG_FATAL, "Could not find a frontend\n");
- return 2;
- }
-
- #if HAS_GTK
- if (win_frontend == FE_GTK)
- {
- gtk_text_freeze(GTK_TEXT(v9t9_command_log));
- }
- #endif
-
- if (!v9t9_init())
- return 3;
-
- #if HAS_GTK
- if (win_frontend == FE_GTK)
- {
- gtk_text_thaw(GTK_TEXT(v9t9_command_log));
- }
- #endif
-
- if (!v9t9_restart())
- return 4;
-
-
- #undef argc
- #undef argv
-
- ret = frontend_loop();
-
- v9t9_restop();
-
- v9t9_term(ret);
-
- termlog();
- system_termlog();
-
- PostQuitMessage(0);
- exit(ret);
- return TRUE;
- }
-
- ////////////////
- int
- win32_system_init(void)
- {
- return 1;
- }
-
- static int TM_Ticked; /* we can't do jack inside a callback */
-
- int v9t9_return;
-
- int
- win32_system_loop(void)
- {
- int ret;
- MSG lpMsg;
-
- while (1) {
- #if defined(USE_MM_TIMER) || defined(USE_WAITABLE_TIMER)
- while (TM_Ticked) {
- TM_TickHandler(0);
- // TM_Ticked--;
- TM_Ticked = 0;
- }
- #endif
-
- lpMsg.message = WM_NULL;
- while (PeekMessage(&lpMsg, NULL, 0, 0, PM_REMOVE)) {
- if (lpMsg.message == WM_DESTROY || lpMsg.message == WM_CLOSE)
- return 1;
-
- TranslateMessage(&lpMsg);
- DispatchMessage(&lpMsg);
- }
-
- ret = v9t9_execute();
- if (ret == em_TooFast)
- win32_system_pause();
- else if (ret == em_Quitting || ret == em_Dying)
- break;
- }
- return ret == em_Dying;
- }
-
- extern gint gtk_idle_handler(gpointer *data);
-
-
- static int
- win32_system_idle(gpointer *data)
- {
- MSG lpMsg;
- int ret;
-
- #if defined(USE_MM_TIMER) || defined(USE_WAITABLE_TIMER)
- while (TM_Ticked /*1||(++TM_Ticked & 63)==0*/) {
- // logger(LOG_USER, ".");
- TM_TickHandler(0);
- TM_Ticked--;
- }
- #endif
-
- /* window paints, keyboard messages */
- while (PeekMessage(&lpMsg, NULL, 0, 0, PM_REMOVE)) {
- // logger(LOG_USER, "-");
- TranslateMessage(&lpMsg);
- DispatchMessage(&lpMsg);
- }
-
- ret = v9t9_return = v9t9_execute();
- if (ret == em_TooFast)
- win32_system_pause();
- else if (ret == em_Quitting || ret == em_Dying) {
- gtk_main_quit();
- return FALSE;
- }
-
- return TRUE;
- }
-
- int
- win32_gtk_system_loop(void)
- {
- guint idle_id;
-
- idle_id = gtk_idle_add((GtkFunction) win32_system_idle, 0L);
-
- gtk_main();
-
- gtk_idle_remove(idle_id);
-
- gtk_widget_destroy(v9t9_window);
- return v9t9_return == em_Dying;
- }
-
-
- /////////
-
- char statuslines[8][160];
- void
- win_StatusLine(int which, char *text)
- {
- #if 0
- strcpy(statuslines[which], text);
- REDRAWSTATUS;
- #endif
- }
-
- ////////////////
-
- // in Timer.c
- extern HANDLE hTimerTickEvent;
-
- /* The value '1' is almost perfect.
- Don't try zero -- that makes v9t9 hog the processor and the OS
- responds slowly and sluggishly. */
- void
- win32_system_pause(void)
- {
- WaitForSingleObject(hTimerTickEvent, 1);
- //TM_Ticked = 1;
- }
-
- /************************************************/
-
- #if defined(USE_MESSAGE_TIMER)
-
- #define TIMERCODE 0x1
-
- static UINT timer;
- static DWORD tm;
-
- static void CALLBACK
- myHandleTimer(HWND hWnd, UINT uMsg, UINT idEvent, DWORD dwTime)
- {
- if (idEvent == TIMERCODE) {
- static DWORD lastcalled, lasttm;
-
- if (!lastcalled)
- lastcalled = dwTime;
-
- /* this loop is necessary since the timer event is
- not at all prioritizable, and we can miss tons of
- messages (on an unburdened Win98 box, it never goes
- faster than 10Hz!)
- */
- while (lastcalled + 10 < dwTime) {
- tm++;
- lastcalled += 10;
- TM_TickHandler(0);
- }
- }
- }
-
- /*
- static void
- TakeABreak(void)
- {
- stateflag |= ST_STOP;
- }
- */
- void
- system_timer_init(void)
- {
- //TM_SetEvent(TM_UniqueTag(), TM_HZ*100/10, 0, TM_FUNC|TM_REPEAT, TakeABreak);
- }
-
- void
- system_timer_install(void)
- {
- timer = SetTimer(win_GetWindow(), TIMERCODE, 1000 / TM_HZ, myHandleTimer); /* 100 Hz */
- }
-
-
- void
- system_timer_uninstall(void)
- {
- KillTimer(win_GetWindow(), timer);
- }
-
- #elif defined(USE_MM_TIMER)
-
- #define TARGET_RESOLUTION (1000/TM_HZ) /* 100 Hz */
- #define TIMERCODE 0x1
-
- static UINT timer;
- static UINT timerRes;
- static DWORD tm;
-
- HANDLE hTimerTickEvent;
-
- static void CALLBACK
- myHandleTimer(UINT uID, UINT uMsg, DWORD dwUser, DWORD dw1, DWORD dw2)
- {
- if (uID == timer) {
- TM_Ticked++;
- if (TM_Ticked > 10) TM_Ticked = 10;
-
- if (!(stateflag & ST_PAUSE)) stateflag |= ST_STOP;
- tm++;
-
- SetEvent(hTimerTickEvent);
- }
- }
-
- void
- system_timer_init(void)
- {
- TIMECAPS tc;
-
- logger(_L|L_2, "timer init\n");
- if (timeGetDevCaps(&tc, sizeof(TIMECAPS)) != TIMERR_NOERROR) {
- logger(_L | LOG_FATAL, "Could not get timer caps\n");
- ExitThread(-1);
- }
-
- timerRes = min(max(tc.wPeriodMin, TARGET_RESOLUTION), tc.wPeriodMax);
- logger(_L|L_2,"timerRes = %d\n", timerRes);
- }
-
- void
- system_timer_install(void)
- {
- timeBeginPeriod(timerRes);
-
- logger(_L|L_2, "timer install\n");
- timer = timeSetEvent(timerRes, 1, myHandleTimer, 0, TIME_PERIODIC);
- if (timer == 0) {
- logger(_L | LOG_ERROR, "Could not set timer to %d ms\n\n", timerRes);
- ExitThread(-1);
- }
- hTimerTickEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
- if (hTimerTickEvent == 0) {
- logger(_L | LOG_ERROR, "Could not create timer event\n");
- ExitThread(-1);
- }
-
- }
-
-
- void
- system_timer_uninstall(void)
- {
- logger(_L|L_2, "timer uninstall\n");
- timeKillEvent(timer);
- timeEndPeriod(timerRes);
- }
-
- #elif defined(USE_WAITABLE_TIMER)
-
- #define TIMERCODE 0x1
-
- static HANDLE hTimer;
- static DWORD tm;
-
- static VOID APIENTRY
- myHandleTimer(LPVOID lpArgToCompletionRoutine,
- DWORD dwTimerLowValue, DWORD dwTimerHighValue)
- {
- // log("ticked\n");
- TM_Ticked++;
- if (TM_Ticked > 10) TM_Ticked = 10;
- if (!(stateflag & ST_PAUSE)) stateflag |= ST_STOP;
- tm++;
- }
-
- void
- system_timer_init(void)
- {
- hTimer = CreateWaitableTimer(NULL, TRUE, NULL);
- if (hTimer == 0) {
- fatal("Could not create timer\n");
- }
- }
-
- void
- system_timer_install(void)
- {
- LARGE_INTEGER pDue;
-
- pDue.QuadPart = -100;
- if (!SetWaitableTimer
- (hTimer, (LARGE_INTEGER *) & pDue, 10, myHandleTimer, 0, 0))
- fatal("Could not set timer to 10 ms");
- }
-
-
- void
- system_timer_uninstall(void)
- {
- CancelWaitableTimer(hTimer);
- }
-
- #endif
-
- void
- system_getcommands(void)
- {
- if (frontend_getcommands)
- frontend_getcommands();
- else
- win32_system_getcommands();
- }
-
- void
- win32_system_getcommands(void)
- {
- // SetForegroundWindow(hWndStatus);
-
- FILE *cmds = fopen("CONIN$", "r");
-
- logger(_L | L_0, "Entering interactive mode\n\n");
- if (cmds == NULL || feof(cmds)) {
- logger(_L | LOG_USER | LOG_ERROR, "FAILED: could not open stdin\n\n");
- return;
- }
-
- v9t9_restop();
-
- while ((stateflag & ST_INTERACTIVE) && !feof(cmds)) {
- char buf[256];
-
- logger(_L | LOG_USER, "\nEnter a command> ");
- if (fgets(buf, sizeof(buf), cmds) && *buf)
- command_parse_text(buf);
- else
- logger(_L | LOG_USER, "<EOF>\n\n");
- }
-
- v9t9_restart();
- }
-
-
- static FILE *logfile;
- static HANDLE conout;
-
- static void
- system_initlog(void)
- {
- if (logfile == NULL) {
- COORD buf;
- SMALL_RECT rect;
-
- logfile = fopen("log.win.txt", "w");
- if (logfile == NULL)
- FAIL("could not open log.win.txt\n");
- if (!AllocConsole())
- FAIL("Could not create console\n");
- if ((conout = GetStdHandle(STD_OUTPUT_HANDLE)) ==
- INVALID_HANDLE_VALUE) FAIL("Could not get stdout for console\n");
- SetConsoleTitle("V9t9 Log");
- SetConsoleMode(conout, ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT |
- ENABLE_PROCESSED_INPUT | ENABLE_PROCESSED_OUTPUT |
- ENABLE_WRAP_AT_EOL_OUTPUT);
- rect.Left = 0;
- rect.Right = 80;
- rect.Top = 0;
- rect.Bottom = 25;
- SetConsoleWindowInfo(conout, true, &rect);
- buf.X = 80;
- buf.Y = 25;
- SetConsoleScreenBufferSize(conout, buf);
- }
-
- }
-
- static void
- system_termlog(void)
- {
- if (logfile) {
- fclose(logfile);
- FreeConsole();
- }
- }
-
- // emit text to log (do not add newline)
- void
- win32_system_log(u32 srcflags, const char *text)
- {
- int len = strlen(text);
- DWORD writ;
-
- if (LOG_IS_VISIBLE(srcflags)) {
- WriteFile(conout, text, len, &writ, NULL);
- }
- }
-
- void
- system_log(u32 srcflags, const char *text)
- {
- if (logfile) {
- fwrite(text, 1, strlen(text), logfile);
- fflush(logfile);
- }
-
- if (frontend_log)
- frontend_log(srcflags, text);
- }
-
- /*
- // show debugger line
- static void
- system_statusline(int line, const char *text)
- {
- if (logfile) {
- if (!line)
- fputs("\n", logfile);
- fputs(text, logfile);
- fputs("\n", logfile);
- }
-
- if (frontend_statusline)
- frontend_statusline(line, text);
- }
-
- void
- win32_system_statusline(int line, const char *text)
- {
- DWORD writ;
- if (!line)
- WriteFile(conout, "\r\n", 2, &writ, NULL);
- WriteFile(conout, text, strlen(text), &writ, NULL);
- WriteFile(conout, "\r\n", 2, &writ, NULL);
- }
- */
-
- #define ITEM_ON_CODE_LINE(item) \
- ((item) >= STATUS_CPU_PC && \
- (item) <= STATUS_CPU_INSTRUCTION_LAST && \
- (item) != STATUS_CPU_REGISTER_VIEW)
-
- void
- system_report_status(status_item item, va_list va)
- {
- char buffer[1024], *bptr = buffer+1;
- static bool last_item_on_code_line;
- bool item_on_code_line;
-
- report_status_text(item, va, bptr, sizeof(buffer)-1);
-
- if (*bptr)
- {
- item_on_code_line = ITEM_ON_CODE_LINE(item);
- if (last_item_on_code_line != item_on_code_line) {
- buffer[0] = '\n';
- bptr--;
- }
-
- system_log(LOG_USER, bptr);
-
- last_item_on_code_line = item_on_code_line;
- }
-
- if (frontend_report_status)
- frontend_report_status(item, va);
- }
-
- void
- win32_system_report_status(status_item item, va_list va)
- {
- }
-
- void
- system_execution_paused(bool paused)
- {
- if (frontend_execution_paused)
- frontend_execution_paused(paused);
- }
-
- void
- win32_system_execution_paused(bool paused)
- {
- logger(LOG_USER, "Execution is %s\n",
- paused ? "paused" : "resumed");
- }
-
- void
- system_debugger_enabled(bool enabled)
- {
- if (frontend_debugger_enabled)
- frontend_debugger_enabled(enabled);
- }
-
- void
- win32_system_debugger_enabled(bool enabled)
- {
- }
-
- int
- win_command(HWND hWnd, WORD cmd)
- {
- logger(_L | L_1, "win_command: %d\n\n", cmd);
- switch (cmd) {
- case ID_FILE_EXIT:
- v9t9_term(0);
- break;
-
- case ID_MODULES_LOADMODULE:
- return 0;
-
- case ID_VIDEO_FULLSCREEN:
- win_video_switchmodes();
- return 0;
-
- case ID_EMULATOR_RESETCOMPUTER:
- command_parse_text("Reset\n");
- return 0;
-
- case ID_COMMANDS_ENTERINTERACTIVEMODE:
- command_parse_text("Interactive=On\n");
- return 0;
-
- case ID_COMMANDS_RELOADV9T9CNF:
- command_parse_text("#include \"v9t9.cnf\"\n");
- return 0;
-
- case ID_OPEN_CONFIG:
- command_parse_text("#include \"savesession.cnf\"\n");
- return 0;
-
- case ID_SAVE_CONFIG:
- command_parse_text("SaveConfig \"savesession.cnf\"\n");
- return 0;
-
- }
- return 1;
- }
-