/* OSGLUGTK.c Copyright (C) 2009 Paul C. Pratt You can redistribute this file and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. You should have received a copy of the license along with this file; see the file COPYING. This file 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 license for more details.*/ /* Operating System GLUe for GTK All operating system dependent code for the GIMP Toolkit should go here.*/ #include "CNFGRAPI.h"#include "SYSDEPNS.h"#include "ENDIANAC.h" #include "MYOSGLUE.h" #include "STRCONST.h" #include "COMOSGLU.h" /* --- some simple utilities --- */ GLOBALOSGLUPROC MyMoveBytes(anyp srcPtr, anyp destPtr, si5b byteCount){ (void) memcpy((char *)destPtr, (char *)srcPtr, byteCount);} /* --- control mode and internationalization --- */ #define NeedCell2PlainAsciiMap 1 #include "INTLCHAR.h" #include "CONTROLM.h" /* --- sending debugging info to file --- */ #if dbglog_HAVE #define dbglog_ToStdErr 0 #if ! dbglog_ToStdErrLOCALVAR FILE *dbglog_File = NULL;#endif LOCALFUNC blnr dbglog_open0(void){#if dbglog_ToStdErr return trueblnr;#else dbglog_File = fopen("dbglog.txt", "w"); return (NULL != dbglog_File);#endif} LOCALPROC dbglog_write0(char *s, uimr L){#if dbglog_ToStdErr (void) fwrite(s, 1, L, stderr);#else if (dbglog_File != NULL) { (void) fwrite(s, 1, L, dbglog_File); }#endif} LOCALPROC dbglog_close0(void){#if ! dbglog_ToStdErr if (dbglog_File != NULL) { fclose(dbglog_File); dbglog_File = NULL; }#endif} #endif /* --- debug settings and utilities --- */ #define MyDbgEvents (dbglog_HAVE && 1) #if ! dbglog_HAVE#define WriteExtraErr(s)#elseLOCALPROC WriteExtraErr(char *s){ dbglog_writeCStr("*** error: "); dbglog_writeCStr(s); dbglog_writeReturn();}#endif /* --- text translation --- */ LOCALPROC NativeStrFromCStr(char *r, char *s, blnr AddEllipsis){ ui3b ps[ClStrMaxLength]; int i; int L; ClStrFromSubstCStr(&L, ps, s); for (i = 0; i < L; ++i) { r[i] = Cell2PlainAsciiMap[ps[i]]; } if (AddEllipsis) { r[L] = '.'; ++L; r[L] = '.'; ++L; r[L] = '.'; ++L; } r[L] = 0;} /* --- drives --- */ #define NotAfileRef NULL LOCALVAR FILE *Drives[NumDrives]; /* open disk image files */ LOCALPROC InitDrives(void){ /* This isn't really needed, Drives[i] and DriveNames[i] need not have valid values when not vSonyIsInserted[i]. */ tDrive i; for (i = 0; i < NumDrives; ++i) { Drives[i] = NotAfileRef; }} GLOBALOSGLUFUNC tMacErr vSonyTransfer(blnr IsWrite, ui3p Buffer, tDrive Drive_No, ui5r Sony_Start, ui5r Sony_Count, ui5r *Sony_ActCount){ ui5r NewSony_Count = Sony_Count; fseek(Drives[Drive_No], Sony_Start, SEEK_SET); if (IsWrite) { fwrite(Buffer, 1, NewSony_Count, Drives[Drive_No]); } else { fread(Buffer, 1, NewSony_Count, Drives[Drive_No]); } if (nullpr != Sony_ActCount) { *Sony_ActCount = NewSony_Count; } return mnvm_noErr; /*& figure out what really to return &*/} GLOBALOSGLUFUNC tMacErr vSonyGetSize(tDrive Drive_No, ui5r *Sony_Count){ fseek(Drives[Drive_No], 0, SEEK_END); *Sony_Count = ftell(Drives[Drive_No]); return mnvm_noErr; /*& figure out what really to return &*/} LOCALFUNC tMacErr vSonyEject0(tDrive Drive_No, blnr deleteit){ DiskEjectedNotify(Drive_No); fclose(Drives[Drive_No]); Drives[Drive_No] = NotAfileRef; /* not really needed */ return mnvm_noErr;} GLOBALOSGLUFUNC tMacErr vSonyEject(tDrive Drive_No){ return vSonyEject0(Drive_No, falseblnr);} LOCALPROC UnInitDrives(void){ tDrive i; for (i = 0; i < NumDrives; ++i) { if (vSonyIsInserted(i)) { (void) vSonyEject(i); } }} LOCALFUNC blnr Sony_Insert0(FILE *refnum, blnr locked, char *drivepath){ tDrive Drive_No; if (! FirstFreeDisk(&Drive_No)) { fclose(refnum); MacMsg(kStrTooManyImagesTitle, kStrTooManyImagesMessage, falseblnr); return falseblnr; } else { /* printf("Sony_Insert0 %d\n", (int)Drive_No); */ Drives[Drive_No] = refnum; DiskInsertNotify(Drive_No, locked); return trueblnr; }} LOCALFUNC blnr Sony_Insert1(char *drivepath, blnr silentfail){ blnr locked = falseblnr; /* printf("Sony_Insert1 %s\n", drivepath); */ FILE *refnum = fopen(drivepath, "rb+"); if (NULL == refnum) { locked = trueblnr; refnum = fopen(drivepath, "rb"); } if (NULL == refnum) { if (! silentfail) { MacMsg(kStrOpenFailTitle, kStrOpenFailMessage, falseblnr); } } else { return Sony_Insert0(refnum, locked, drivepath); } return falseblnr;} LOCALFUNC tMacErr LoadMacRomFrom(char *path){ tMacErr err; FILE *ROM_File; int File_Size; ROM_File = fopen(path, "rb"); if (NULL == ROM_File) { err = mnvm_fnfErr; } else { File_Size = fread(ROM, 1, kROM_Size, ROM_File); if (kROM_Size != File_Size) { if (feof(ROM_File)) { MacMsgOverride(kStrShortROMTitle, kStrShortROMMessage); err = mnvm_eofErr; } else { MacMsgOverride(kStrNoReadROMTitle, kStrNoReadROMMessage); err = mnvm_miscErr; } } else { err = ROM_IsValid(); } fclose(ROM_File); } return err;} LOCALFUNC blnr Sony_Insert1a(char *drivepath, blnr silentfail){ blnr v; if (! ROM_loaded) { v = (mnvm_noErr == LoadMacRomFrom(drivepath)); } else { v = Sony_Insert1(drivepath, silentfail); } return v;} LOCALFUNC blnr Sony_InsertIth(int i){ blnr v; if ((i > 9) || ! FirstFreeDisk(nullpr)) { v = falseblnr; } else { char s[] = "disk?.dsk"; s[4] = '0' + i; v = Sony_Insert1(s, trueblnr); } return v;} LOCALFUNC blnr LoadInitialImages(void){ int i; for (i = 1; Sony_InsertIth(i); ++i) { /* stop on first error (including file not found) */ } return trueblnr;} /* --- ROM --- */ LOCALVAR char *rom_path = NULL; LOCALFUNC blnr LoadMacRom(void){ tMacErr err; if ((NULL == rom_path) || (mnvm_fnfErr == (err = LoadMacRomFrom(rom_path)))) if (mnvm_fnfErr == (err = LoadMacRomFrom(RomFileName))) { } return trueblnr;} /* --- video out --- */ static GtkWidget *drawing_area; LOCALVAR blnr gBackgroundFlag = falseblnr;LOCALVAR blnr gTrueBackgroundFlag = falseblnr;LOCALVAR blnr CurSpeedStopped = trueblnr; LOCALPROC HaveChangedScreenBuff(si4b top, si4b left, si4b bottom, si4b right){ guchar graybuf[vMacScreenWidth * vMacScreenHeight]; { int i; int j; int k; ui3b *p1 = GetCurDrawBuff() + (ui5r)vMacScreenWidth / 8 * top; ui3b *p2 = (ui3b *)graybuf + (ui5r)vMacScreenWidth * top; ui5b t0; UnusedParam(left); UnusedParam(right); for (i = bottom - top; --i >= 0; ) { for (j = vMacScreenWidth / 8; --j >= 0; ) { t0 = *p1++; for (k = 8; --k >= 0; ) { *p2++ = ((t0 >> k) & 0x01) - 1; } } } } gdk_draw_gray_image(drawing_area->window, drawing_area->style->fg_gc[GTK_WIDGET_STATE(drawing_area)], left /* x */, top /* y */, right - left /* width */, bottom - top /* height */, GDK_RGB_DITHER_NONE, graybuf + left + (ui5r)vMacScreenWidth * top, vMacScreenWidth);} LOCALPROC MyDrawChangesAndClear(void){ if (ScreenChangedBottom > ScreenChangedTop) { HaveChangedScreenBuff(ScreenChangedTop, ScreenChangedLeft, ScreenChangedBottom, ScreenChangedRight); ScreenClearChanges(); }} GLOBALOSGLUPROC DoneWithDrawingForTick(void){ MyDrawChangesAndClear();} /* --- mouse --- */ LOCALVAR blnr HaveCursorHidden = falseblnr;LOCALVAR blnr WantCursorHidden = falseblnr; static GdkCursor *blank_cursor;static GtkWidget *window = NULL; LOCALPROC ForceShowCursor(void){ if (HaveCursorHidden) { HaveCursorHidden = falseblnr; if (window) { gdk_window_set_cursor(window->window, NULL); } }} /* cursor state */ LOCALPROC MousePositionNotify(int NewMousePosh, int NewMousePosv){ blnr ShouldHaveCursorHidden = trueblnr; { if (NewMousePosh < 0) { NewMousePosh = 0; ShouldHaveCursorHidden = falseblnr; } else if (NewMousePosh >= vMacScreenWidth) { NewMousePosh = vMacScreenWidth - 1; ShouldHaveCursorHidden = falseblnr; } if (NewMousePosv < 0) { NewMousePosv = 0; ShouldHaveCursorHidden = falseblnr; } else if (NewMousePosv >= vMacScreenHeight) { NewMousePosv = vMacScreenHeight - 1; ShouldHaveCursorHidden = falseblnr; } /* if (ShouldHaveCursorHidden || CurMouseButton) */ /* for a game like arkanoid, would like mouse to still move even when outside window in one direction */ MyMousePositionSet(NewMousePosh, NewMousePosv); } WantCursorHidden = ShouldHaveCursorHidden;} LOCALPROC CheckMouseState(void){#if 0 gint x; gint y; gint x0; gint y0; gdk_display_get_pointer(gdk_drawable_get_display(window), NULL, &x, &y, NULL); (void) gdk_window_get_origin(window, &x0, &y0); MousePositionNotify(x - x0, y - y0);#endif gint x; gint y; gtk_widget_get_pointer(drawing_area, &x, &y); /* (void) gdk_window_get_pointer(window, &x, &y, NULL); */ MousePositionNotify(x, y);} /* --- keyboard input --- */ #define MaxNumKeycode 256#define KeyCodeMask (MaxNumKeycode - 1) /* assume keycodes >= 0 and < MaxNumKeycode, which isn't promised by gtk documentation. */ LOCALVAR ui3b KC2MKC[MaxNumKeycode]; LOCALPROC KC2MKCAssignOne(guint keyval, ui3r key){ GdkKeymapKey *keys; gint n_keys; int i; if (gdk_keymap_get_entries_for_keyval(NULL, keyval, &keys, &n_keys)) { for (i = 0; i < n_keys; i++) { KC2MKC[keys[i].keycode & KeyCodeMask] = key; } g_free(keys); }#if 0 fprintf(stderr, "%d %d %d\n", (int)ks, key, (int)code);#endif} LOCALFUNC blnr KC2MKCInit(void){ int i; Lines 1–500 of 1764. Load more
/* OSGLUGTK.c Copyright (C) 2009 Paul C. Pratt You can redistribute this file and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. You should have received a copy of the license along with this file; see the file COPYING. This file 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 license for more details. */ /* Operating System GLUe for GTK All operating system dependent code for the GIMP Toolkit should go here. */ #include "CNFGRAPI.h" #include "SYSDEPNS.h" #include "ENDIANAC.h" #include "MYOSGLUE.h" #include "STRCONST.h" #include "COMOSGLU.h" /* --- some simple utilities --- */ GLOBALOSGLUPROC MyMoveBytes(anyp srcPtr, anyp destPtr, si5b byteCount) { (void) memcpy((char *)destPtr, (char *)srcPtr, byteCount); } /* --- control mode and internationalization --- */ #define NeedCell2PlainAsciiMap 1 #include "INTLCHAR.h" #include "CONTROLM.h" /* --- sending debugging info to file --- */ #if dbglog_HAVE #define dbglog_ToStdErr 0 #if ! dbglog_ToStdErr LOCALVAR FILE *dbglog_File = NULL; #endif LOCALFUNC blnr dbglog_open0(void) { #if dbglog_ToStdErr return trueblnr; #else dbglog_File = fopen("dbglog.txt", "w"); return (NULL != dbglog_File); #endif } LOCALPROC dbglog_write0(char *s, uimr L) { #if dbglog_ToStdErr (void) fwrite(s, 1, L, stderr); #else if (dbglog_File != NULL) { (void) fwrite(s, 1, L, dbglog_File); } #endif } LOCALPROC dbglog_close0(void) { #if ! dbglog_ToStdErr if (dbglog_File != NULL) { fclose(dbglog_File); dbglog_File = NULL; } #endif } #endif /* --- debug settings and utilities --- */ #define MyDbgEvents (dbglog_HAVE && 1) #if ! dbglog_HAVE #define WriteExtraErr(s) #else LOCALPROC WriteExtraErr(char *s) { dbglog_writeCStr("*** error: "); dbglog_writeCStr(s); dbglog_writeReturn(); } #endif /* --- text translation --- */ LOCALPROC NativeStrFromCStr(char *r, char *s, blnr AddEllipsis) { ui3b ps[ClStrMaxLength]; int i; int L; ClStrFromSubstCStr(&L, ps, s); for (i = 0; i < L; ++i) { r[i] = Cell2PlainAsciiMap[ps[i]]; } if (AddEllipsis) { r[L] = '.'; ++L; r[L] = '.'; ++L; r[L] = '.'; ++L; } r[L] = 0; } /* --- drives --- */ #define NotAfileRef NULL LOCALVAR FILE *Drives[NumDrives]; /* open disk image files */ LOCALPROC InitDrives(void) { /* This isn't really needed, Drives[i] and DriveNames[i] need not have valid values when not vSonyIsInserted[i]. */ tDrive i; for (i = 0; i < NumDrives; ++i) { Drives[i] = NotAfileRef; } } GLOBALOSGLUFUNC tMacErr vSonyTransfer(blnr IsWrite, ui3p Buffer, tDrive Drive_No, ui5r Sony_Start, ui5r Sony_Count, ui5r *Sony_ActCount) { ui5r NewSony_Count = Sony_Count; fseek(Drives[Drive_No], Sony_Start, SEEK_SET); if (IsWrite) { fwrite(Buffer, 1, NewSony_Count, Drives[Drive_No]); } else { fread(Buffer, 1, NewSony_Count, Drives[Drive_No]); } if (nullpr != Sony_ActCount) { *Sony_ActCount = NewSony_Count; } return mnvm_noErr; /*& figure out what really to return &*/ } GLOBALOSGLUFUNC tMacErr vSonyGetSize(tDrive Drive_No, ui5r *Sony_Count) { fseek(Drives[Drive_No], 0, SEEK_END); *Sony_Count = ftell(Drives[Drive_No]); return mnvm_noErr; /*& figure out what really to return &*/ } LOCALFUNC tMacErr vSonyEject0(tDrive Drive_No, blnr deleteit) { DiskEjectedNotify(Drive_No); fclose(Drives[Drive_No]); Drives[Drive_No] = NotAfileRef; /* not really needed */ return mnvm_noErr; } GLOBALOSGLUFUNC tMacErr vSonyEject(tDrive Drive_No) { return vSonyEject0(Drive_No, falseblnr); } LOCALPROC UnInitDrives(void) { tDrive i; for (i = 0; i < NumDrives; ++i) { if (vSonyIsInserted(i)) { (void) vSonyEject(i); } } } LOCALFUNC blnr Sony_Insert0(FILE *refnum, blnr locked, char *drivepath) { tDrive Drive_No; if (! FirstFreeDisk(&Drive_No)) { fclose(refnum); MacMsg(kStrTooManyImagesTitle, kStrTooManyImagesMessage, falseblnr); return falseblnr; } else { /* printf("Sony_Insert0 %d\n", (int)Drive_No); */ Drives[Drive_No] = refnum; DiskInsertNotify(Drive_No, locked); return trueblnr; } } LOCALFUNC blnr Sony_Insert1(char *drivepath, blnr silentfail) { blnr locked = falseblnr; /* printf("Sony_Insert1 %s\n", drivepath); */ FILE *refnum = fopen(drivepath, "rb+"); if (NULL == refnum) { locked = trueblnr; refnum = fopen(drivepath, "rb"); } if (NULL == refnum) { if (! silentfail) { MacMsg(kStrOpenFailTitle, kStrOpenFailMessage, falseblnr); } } else { return Sony_Insert0(refnum, locked, drivepath); } return falseblnr; } LOCALFUNC tMacErr LoadMacRomFrom(char *path) { tMacErr err; FILE *ROM_File; int File_Size; ROM_File = fopen(path, "rb"); if (NULL == ROM_File) { err = mnvm_fnfErr; } else { File_Size = fread(ROM, 1, kROM_Size, ROM_File); if (kROM_Size != File_Size) { if (feof(ROM_File)) { MacMsgOverride(kStrShortROMTitle, kStrShortROMMessage); err = mnvm_eofErr; } else { MacMsgOverride(kStrNoReadROMTitle, kStrNoReadROMMessage); err = mnvm_miscErr; } } else { err = ROM_IsValid(); } fclose(ROM_File); } return err; } LOCALFUNC blnr Sony_Insert1a(char *drivepath, blnr silentfail) { blnr v; if (! ROM_loaded) { v = (mnvm_noErr == LoadMacRomFrom(drivepath)); } else { v = Sony_Insert1(drivepath, silentfail); } return v; } LOCALFUNC blnr Sony_InsertIth(int i) { blnr v; if ((i > 9) || ! FirstFreeDisk(nullpr)) { v = falseblnr; } else { char s[] = "disk?.dsk"; s[4] = '0' + i; v = Sony_Insert1(s, trueblnr); } return v; } LOCALFUNC blnr LoadInitialImages(void) { int i; for (i = 1; Sony_InsertIth(i); ++i) { /* stop on first error (including file not found) */ } return trueblnr; } /* --- ROM --- */ LOCALVAR char *rom_path = NULL; LOCALFUNC blnr LoadMacRom(void) { tMacErr err; if ((NULL == rom_path) || (mnvm_fnfErr == (err = LoadMacRomFrom(rom_path)))) if (mnvm_fnfErr == (err = LoadMacRomFrom(RomFileName))) { } return trueblnr; } /* --- video out --- */ static GtkWidget *drawing_area; LOCALVAR blnr gBackgroundFlag = falseblnr; LOCALVAR blnr gTrueBackgroundFlag = falseblnr; LOCALVAR blnr CurSpeedStopped = trueblnr; LOCALPROC HaveChangedScreenBuff(si4b top, si4b left, si4b bottom, si4b right) { guchar graybuf[vMacScreenWidth * vMacScreenHeight]; { int i; int j; int k; ui3b *p1 = GetCurDrawBuff() + (ui5r)vMacScreenWidth / 8 * top; ui3b *p2 = (ui3b *)graybuf + (ui5r)vMacScreenWidth * top; ui5b t0; UnusedParam(left); UnusedParam(right); for (i = bottom - top; --i >= 0; ) { for (j = vMacScreenWidth / 8; --j >= 0; ) { t0 = *p1++; for (k = 8; --k >= 0; ) { *p2++ = ((t0 >> k) & 0x01) - 1; } } } } gdk_draw_gray_image(drawing_area->window, drawing_area->style->fg_gc[GTK_WIDGET_STATE(drawing_area)], left /* x */, top /* y */, right - left /* width */, bottom - top /* height */, GDK_RGB_DITHER_NONE, graybuf + left + (ui5r)vMacScreenWidth * top, vMacScreenWidth); } LOCALPROC MyDrawChangesAndClear(void) { if (ScreenChangedBottom > ScreenChangedTop) { HaveChangedScreenBuff(ScreenChangedTop, ScreenChangedLeft, ScreenChangedBottom, ScreenChangedRight); ScreenClearChanges(); } } GLOBALOSGLUPROC DoneWithDrawingForTick(void) { MyDrawChangesAndClear(); } /* --- mouse --- */ LOCALVAR blnr HaveCursorHidden = falseblnr; LOCALVAR blnr WantCursorHidden = falseblnr; static GdkCursor *blank_cursor; static GtkWidget *window = NULL; LOCALPROC ForceShowCursor(void) { if (HaveCursorHidden) { HaveCursorHidden = falseblnr; if (window) { gdk_window_set_cursor(window->window, NULL); } } } /* cursor state */ LOCALPROC MousePositionNotify(int NewMousePosh, int NewMousePosv) { blnr ShouldHaveCursorHidden = trueblnr; { if (NewMousePosh < 0) { NewMousePosh = 0; ShouldHaveCursorHidden = falseblnr; } else if (NewMousePosh >= vMacScreenWidth) { NewMousePosh = vMacScreenWidth - 1; ShouldHaveCursorHidden = falseblnr; } if (NewMousePosv < 0) { NewMousePosv = 0; ShouldHaveCursorHidden = falseblnr; } else if (NewMousePosv >= vMacScreenHeight) { NewMousePosv = vMacScreenHeight - 1; ShouldHaveCursorHidden = falseblnr; } /* if (ShouldHaveCursorHidden || CurMouseButton) */ /* for a game like arkanoid, would like mouse to still move even when outside window in one direction */ MyMousePositionSet(NewMousePosh, NewMousePosv); } WantCursorHidden = ShouldHaveCursorHidden; } LOCALPROC CheckMouseState(void) { #if 0 gint x; gint y; gint x0; gint y0; gdk_display_get_pointer(gdk_drawable_get_display(window), NULL, &x, &y, NULL); (void) gdk_window_get_origin(window, &x0, &y0); MousePositionNotify(x - x0, y - y0); #endif gint x; gint y; gtk_widget_get_pointer(drawing_area, &x, &y); /* (void) gdk_window_get_pointer(window, &x, &y, NULL); */ MousePositionNotify(x, y); } /* --- keyboard input --- */ #define MaxNumKeycode 256 #define KeyCodeMask (MaxNumKeycode - 1) /* assume keycodes >= 0 and < MaxNumKeycode, which isn't promised by gtk documentation. */ LOCALVAR ui3b KC2MKC[MaxNumKeycode]; LOCALPROC KC2MKCAssignOne(guint keyval, ui3r key) { GdkKeymapKey *keys; gint n_keys; int i; if (gdk_keymap_get_entries_for_keyval(NULL, keyval, &keys, &n_keys)) { for (i = 0; i < n_keys; i++) { KC2MKC[keys[i].keycode & KeyCodeMask] = key; } g_free(keys); } #if 0 fprintf(stderr, "%d %d %d\n", (int)ks, key, (int)code); #endif } LOCALFUNC blnr KC2MKCInit(void) { int i;