/* GSPLUS - Advanced Apple IIGS Emulator Environment Based on the KEGS emulator written by Kent Dickey See COPYRIGHT.txt for Copyright information See LICENSE.txt for license (GPL v2) */ #include "../../defc.h" #include "../../protos.h" #define INCL_WIN #define INCL_GPI #include /* PM header file */ #include #include "gsportos2.h" /* Resource symbolic identifiers*/ HAB g_hab; /* PM anchor block handle */ PSZ pszErrMsg; QMSG qmsg; /* Message from message queue */ HWND g_hwnd_frame = NULLHANDLE; /* Frame window handle */ HWND g_hwnd_client = NULLHANDLE; /* Client area window handle */ HMQ g_hmq; /* Message queue handle */ extern int Verbose; extern int g_warp_pointer; extern int g_screen_depth; extern int g_force_depth; int g_screen_mdepth = 0; extern int g_quit_sim_now; int g_use_shmem = 1; int g_has_focus = 0; int g_auto_repeat_on = -1; extern Kimage g_mainwin_kimage; int g_main_height = 0; int g_win_capslock_down = 0; extern int g_border_sides_refresh_needed; extern int g_border_special_refresh_needed; extern int g_status_refresh_needed; extern int g_needfullrefreshfornextframe; extern int g_lores_colors[]; extern int g_cur_a2_stat; extern int g_a2vid_palette; extern int g_installed_full_superhires_colormap; extern int g_screen_redraw_skip_amt; extern word32 g_a2_screen_buffer_changed; BITMAPINFO2 *g_bmapinfo_ptr = 0; volatile BITMAPINFOHEADER2 *g_bmaphdr_ptr = 0; HDC g_hdc_screen, g_hdc_memory; HPS g_hps_screen, g_hps_memory; extern word32 g_palette_8to1624[256]; extern word32 g_a2palette_8to1624[256]; extern char *g_status_ptrs[MAX_STATUS_LINES]; VOID DispErrorMessage(); int win_nonblock_read_stdin(int fd, char *bufptr, int len) { return 0; } void x_dialog_create_gsport_conf(const char *str) { } int x_show_alert(int is_fatal, const char *str) { return 0; } int main(int argc, char **argv) { DEVOPENSTRUC pszData; ULONG flCreate; /* Window creation control flags*/ int height; SIZEL sizel; if ((g_hab = WinInitialize(0)) == 0L) /* Initialize PM */ os2_abort(g_hwnd_frame, g_hwnd_client); /* Terminate the application */ if ((g_hmq = WinCreateMsgQueue( g_hab, 0 )) == 0L) /* Create a msg queue */ os2_abort(g_hwnd_frame, g_hwnd_client); /* Terminate the application */ if (!WinRegisterClass( /* Register window class */ g_hab, /* Anchor block handle */ (PSZ)"MyWindow", /* Window class name */ (PFNWP)MyWindowProc, /* Address of window procedure */ CS_SIZEREDRAW, /* Class style */ 0 /* No extra window words */ )) os2_abort(g_hwnd_frame, g_hwnd_client); /* Terminate the application */ height = X_A2_WINDOW_HEIGHT + (MAX_STATUS_LINES*16); g_main_height = height; flCreate = FCF_STANDARD & /* Set frame control flags to */ ~FCF_SHELLPOSITION; /* standard except for shell */ /* positioning. */ if ((g_hwnd_frame = WinCreateStdWindow( HWND_DESKTOP, /* Desktop window is parent */ 0, /* STD. window styles */ &flCreate, /* Frame control flag */ "MyWindow", /* Client window class name */ "", /* No window text */ 0, /* No special class style */ (HMODULE)0L, /* Resource is in .EXE file */ ID_WINDOW, /* Frame window identifier */ &g_hwnd_client /* Client window handle */ )) == 0L) os2_abort(HWND_DESKTOP, HWND_DESKTOP); /* Terminate the application */ WinSetWindowText(g_hwnd_frame, "GSport"); if (!WinSetWindowPos( g_hwnd_frame, /* Shows and activates frame */ HWND_TOP, /* window at position 100, 100, */ 100, 100, X_A2_WINDOW_WIDTH, height, /* and size 200, 200. */ SWP_SIZE | SWP_MOVE | SWP_ACTIVATE | SWP_SHOW )) os2_abort(g_hwnd_frame, g_hwnd_client); /* Terminate the application */ g_hdc_screen = WinOpenWindowDC(g_hwnd_client); sizel.cx = X_A2_WINDOW_WIDTH; sizel.cy = height; g_hps_screen = GpiCreatePS(g_hab,g_hdc_screen, &sizel, PU_PELS | GPIF_LONG | GPIA_ASSOC); g_hdc_memory = DevOpenDC(g_hab, OD_MEMORY, "*", 4, (PDEVOPENDATA)&pszData, NULL); g_hps_memory = GpiCreatePS(g_hab,g_hdc_memory, &sizel, PU_ARBITRARY | GPIT_MICRO | GPIA_ASSOC); // Call gsplusmain return gsplusmain(argc, argv); } /************************************************************************** * * Name : MyWindowProc * * Description: The window procedure associated with the client area in * the standard frame window. It processes all messages * either sent or posted to the client area, depending on * the message command and parameters. * *************************************************************************/ MRESULT EXPENTRY MyWindowProc( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 ) { HPS hps; RECTL rcl; switch( msg ) { case WM_CREATE: /* * Window initialization is performed here in WM_CREATE processing * WinLoadString loads strings from the resource file. */ break; case WM_COMMAND: /* * When the user chooses option 1, 2, or 3 from the Options pull- * down, the text string is set to 1, 2, or 3, and * WinInvalidateRegion sends a WM_PAINT message. * When Exit is chosen, the application posts itself a WM_CLOSE * message. */ { USHORT command; /* WM_COMMAND command value */ command = SHORT1FROMMP(mp1); /* Extract the command value */ switch (command) { case ID_EXITPROG: WinPostMsg( hwnd, WM_CLOSE, (MPARAM)0, (MPARAM)0 ); break; default: return WinDefWindowProc( hwnd, msg, mp1, mp2 ); } break; } case WM_ERASEBACKGROUND: /* * Return TRUE to request PM to paint the window background * in SYSCLR_WINDOW. */ return (MRESULT)( TRUE ); case WM_PAINT: /* * Window contents are drawn here in WM_PAINT processing. */ hps = WinBeginPaint(hwnd, NULLHANDLE, &rcl); WinEndPaint(hps); g_needfullrefreshfornextframe = 1; break; case WM_CLOSE: /* * This is the place to put your termination routines */ WinPostMsg( hwnd, WM_QUIT, (MPARAM)0,(MPARAM)0 ); /* Cause termination*/ exit(0); break; default: /* * Everything else comes here. This call MUST exist * in your window procedure. */ return WinDefWindowProc( hwnd, msg, mp1, mp2 ); } return (MRESULT)FALSE; } /* End of MyWindowProc */ void check_input_events() { /* * Get and dispatch messages from the application message queue * until WinGetMsg returns FALSE, indicating a WM_QUIT message. */ while(WinPeekMsg(g_hab, &qmsg, g_hwnd_frame, 0, 0, PM_NOREMOVE)) { if(WinGetMsg(g_hab, &qmsg, 0L, 0, 0) > 0) { //TranslateMessage(&qmsg); WinDispatchMsg(g_hab, &qmsg); } else { printf("GetMessage returned <= 0\n"); my_exit(2); } } } void x_update_color(int col_num, int red, int green, int blue, word32 rgb) { } void x_update_physical_colormap() { } void show_xcolor_array() { } void xdriver_end() { printf("OS/2 driver_end\n"); } void x_get_kimage(Kimage *kimage_ptr) { byte *ptr; int width; int height; int depth, mdepth; int size; width = kimage_ptr->width_req; height = kimage_ptr->height; depth = kimage_ptr->depth; mdepth = kimage_ptr->mdepth; size = 0; if(depth == g_screen_depth) { /* Use g_bmapinfo_ptr, adjusting width, height */ g_bmaphdr_ptr->cx = width; g_bmaphdr_ptr->cy = height; kimage_ptr->dev_handle = GpiCreateBitmap( (HPS)g_hps_memory, (PBITMAPINFOHEADER2)g_bmaphdr_ptr, 0L, (PBYTE)kimage_ptr->data_ptr, (PBITMAPINFO2)g_bmapinfo_ptr); size = (width*height*mdepth) >> 3; ptr = (byte *)malloc(size); if(ptr == 0) { printf("malloc for data failed, mdepth: %d\n", mdepth); exit(2); } kimage_ptr->data_ptr = ptr; } else { /* allocate buffers for video.c to draw into */ size = (width*height*mdepth) >> 3; ptr = (byte *)malloc(size); if(ptr == 0) { printf("malloc for data failed, mdepth: %d\n", mdepth); exit(2); } kimage_ptr->data_ptr = ptr; kimage_ptr->dev_handle = (void *)-1; } return; } void dev_video_init() { int lores_col; int i; printf("Preparing graphics system\n"); g_screen_depth = 24; g_screen_mdepth = 32; g_bmapinfo_ptr = (BITMAPINFO2 *)malloc(sizeof(BITMAPINFOHEADER2)); g_bmaphdr_ptr = (BITMAPINFOHEADER2 *)g_bmapinfo_ptr; g_bmaphdr_ptr->cbFix = sizeof(BITMAPINFOHEADER2); g_bmaphdr_ptr->cx = A2_WINDOW_WIDTH; g_bmaphdr_ptr->cy = A2_WINDOW_HEIGHT; g_bmaphdr_ptr->cPlanes = 1; g_bmaphdr_ptr->cBitCount = g_screen_mdepth; g_bmaphdr_ptr->ulCompression = BCA_UNCOMP; g_bmaphdr_ptr->cclrUsed = 0; video_get_kimages(); if(g_screen_depth != 8) { // Allocate g_mainwin_kimage video_get_kimage(&g_mainwin_kimage, 0, g_screen_depth, g_screen_mdepth); } for(i = 0; i < 256; i++) { lores_col = g_lores_colors[i & 0xf]; video_update_color_raw(i, lores_col); g_a2palette_8to1624[i] = g_palette_8to1624[i]; } g_installed_full_superhires_colormap = 1; printf("Done with dev_video_init\n"); fflush(stdout); } void x_redraw_status_lines() { int line,len,height; POINTL pt; char *buf; printf("x_redraw_status_lines() called\n"); /* if (g_status_ptrs[0] != NULL) { height = 16; pt.x = 5; pt.y = 0; GpiSetColor( g_hps_screen, CLR_NEUTRAL ); GpiSetBackColor( g_hps_screen, CLR_BACKGROUND ); GpiSetBackMix( g_hps_screen, BM_OVERPAINT ); for (line = 0; line < MAX_STATUS_LINES; line++) { buf = g_status_ptrs[line]; if (buf != 0) { pt.y = height * (line+1); len = strlen(buf); GpiCharStringAt( g_hps_screen, &pt, (LONG)strlen( buf ), buf ); } } } */ } void x_push_kimage(Kimage *kimage_ptr, int destx, int desty, int srcx, int srcy, int width, int height) { RECTL rc; POINTL pt[4]; HBITMAP hbmOld, hbmNew; char *szString = "Hello, world!\0"; printf("x_push_kimage() called: Src: (%d,%d) Dest: (%d,%d) Width: %d Height: %d\n",srcx,srcy,destx,desty,width,height); pt[0].x = destx; /* Target X1 */ pt[0].y = desty+(MAX_STATUS_LINES*16); /* Target Y1 */ pt[1].x = destx+width; /* Target X2 */ pt[1].y = desty+height+(MAX_STATUS_LINES*16); /* Target Y2: Translate up, make room for status border */ pt[2].x = srcx; /* Source X */ pt[2].y = srcy; /* Source Y */ pt[3].x = srcx+width; pt[3].y = srcy+height; if (width == 560) { /* Paint a known-good bitmap until we can figure out why images aren't showing up */ hbmNew = GpiLoadBitmap(g_hps_memory,NULLHANDLE,ID_BITMAP,560,400); hbmOld = GpiSetBitmap(g_hps_memory, hbmNew); GpiBitBlt(g_hps_screen,g_hps_memory,4L,pt,ROP_SRCCOPY, BBO_IGNORE); GpiSetBitmap(g_hps_memory, hbmOld); GpiDeleteBitmap(hbmNew); } else { hbmOld = GpiSetBitmap(g_hps_memory, (HBITMAP)kimage_ptr->dev_handle); GpiBitBlt(g_hps_screen,g_hps_memory,4L,pt,ROP_SRCCOPY, BBO_IGNORE); GpiSetBitmap(g_hps_memory, hbmOld); } } // OG Adding release void x_release_kimage(Kimage* kimage_ptr) { if (kimage_ptr->dev_handle == (void*)-1) { free(kimage_ptr->data_ptr); kimage_ptr->data_ptr = NULL; } else { } } void x_push_done() { } void x_auto_repeat_on(int must) { } void x_auto_repeat_off(int must) { } void x_hide_pointer(int do_hide) { } void x_full_screen(int do_full) { return; } int x_calc_ratio(float ratiox,float ratioy) { return 0; // not stretched } /**************************************************************************/ /* DispErrorMsg -- report an error returned from an API service. */ /* */ /* The error message is displayed using a message box */ /* */ /**************************************************************************/ VOID DispErrorMessage() { PERRINFO pErrInfoBlk; PSZ pszOffSet, pszErrMsg; ERRORID ErrorId; PCH ErrorStr; ErrorId = WinGetLastError(g_hab); if ((pErrInfoBlk = WinGetErrorInfo(g_hab)) != (PERRINFO)NULL) { pszOffSet = ((PSZ)pErrInfoBlk) + pErrInfoBlk->offaoffszMsg; pszErrMsg = ((PSZ)pErrInfoBlk) + *((PULONG)pszOffSet); WinMessageBox(HWND_DESKTOP, /* Parent window is desk top */ g_hwnd_frame, /* Owner window is our frame */ pszErrMsg, /* PMWIN Error message */ "Error", /* Title bar message */ 0, /* Message identifier */ MB_MOVEABLE | MB_CANCEL ); /* Flags */ WinFreeErrorInfo(pErrInfoBlk); } } void os2_abort(HWND g_hwnd_frame, HWND g_hwnd_client) { exit(-1); }