/* Sarien - A Sierra AGI resource interpreter engine * Copyright (C) 1999-2001 Stuart George and Claudio Matsuoka * * $Id: wince.cpp,v 1.3.2.1 2001/11/10 12:13:54 cmatsuoka Exp $ * * 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; see docs/COPYING for further details. */ /* * Win32 port by Felipe Rosinha */ /* * Massively modified by Vasyl Tsvirkunov for * Pocket PC/WinCE port */ #include #include #include #include #include #include #include #include #include "gx.h" #include "sarien.h" #include "graphics.h" #include "keyboard.h" #include "console.h" #include "text.h" /* Prevent name conflict */ #undef snprintf #include "win32.h" #include "resource.h" #define USE_F_KEYS #define SMOOTH static LPTSTR szAppName = TEXT("Pocket Sarien"); static GXDisplayProperties gxdp; static GXKeyList gxkl; static bool active = true; static HWND hwndMB = NULL; typedef unsigned char UBYTE; static UBYTE* screen; #ifdef SMOOTH static UBYTE* palRed; static UBYTE* palGreen; static UBYTE* palBlue; #else static unsigned short* pal; #endif static bool bmono; static bool b565; static bool b555; static UBYTE invert = 0; static int colorscale = 0; #define COLORCONV565(r,g,b) (((r&0xf8)<<(11-3))|((g&0xfc)<<(5-2))|((b&0xf8)>>3)) #define COLORCONV555(r,g,b) (((r&0xf8)<<(10-3))|((g&0xf8)<<(5-2))|((b&0xf8)>>3)) #define COLORCONVMONO(r,g,b) ((((3*r>>3)+(g>>1)+(b>>3))>>colorscale)^invert) static int wince_init_vidmode (void); static int wince_deinit_vidmode(void); static void wince_put_block (int, int, int, int); static void wince_put_pixels (int, int, int, BYTE *); static int wince_keypress (void); static int wince_get_key (void); static void wince_new_timer (void); LRESULT CALLBACK WindowProc(HWND hwnd, UINT nMsg, WPARAM wParam, LPARAM lParam); #ifdef USE_F_KEYS void setup_extra_windows(HWND hwndTop); void adjust_extra_windows(); HWND hwndFKeys; #endif static struct gfx_driver gfx_wince = { wince_init_vidmode, wince_deinit_vidmode, wince_put_block, wince_put_pixels, wince_new_timer, wince_keypress, wince_get_key }; extern "C" struct gfx_driver *gfx; int init_machine(int argc, char **argv) { gfx = &gfx_wince; return err_OK; } int deinit_machine() { return err_OK; } void set_palette(int ent, UBYTE r, UBYTE g, UBYTE b) { if (ent >= 256) return; #ifdef SMOOTH palRed[ent] = r; palGreen[ent] = g; palBlue[ent] = b; #else if(b565) pal[ent] = COLORCONV565(r,g,b); else if(b555) pal[ent] = COLORCONV555(r,g,b); else if(bmono) pal[ent] = COLORCONVMONO(r,g,b); #endif } static int wince_init_vidmode() { WNDCLASS wc; wc.style = CS_HREDRAW | CS_VREDRAW; wc.lpfnWndProc = WindowProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = GetModuleHandle(NULL); wc.hIcon = (HICON)LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_SARIEN)); wc.hCursor = NULL; wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); wc.lpszMenuName = NULL; wc.lpszClassName = szAppName; RegisterClass(&wc); hwndMain = CreateWindow(szAppName, szAppName, WS_VISIBLE, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN), NULL, NULL, GetModuleHandle(NULL), NULL); if(!hwndMain) return err_Unk; SHMENUBARINFO smbi; smbi.cbSize = sizeof(smbi); smbi.hwndParent = hwndMain; smbi.dwFlags = 0; smbi.nToolBarId = IDM_MENU; smbi.hInstRes = GetModuleHandle(NULL); smbi.nBmpId = 0; smbi.cBmpImages = 0; smbi.hwndMB = NULL; BOOL res = SHCreateMenuBar(&smbi); hwndMB = smbi.hwndMB; screen = new UBYTE[GFX_WIDTH*GFX_HEIGHT]; #ifdef SMOOTH palRed = new UBYTE[256]; palGreen = new UBYTE[256]; palBlue = new UBYTE[256]; if(!palRed || !palGreen || !palBlue) return err_Unk; #else pal = new unsigned short[256]; if(!pal) return err_Unk; #endif if(!screen) return err_Unk; memset(screen, 0, GFX_WIDTH*GFX_HEIGHT); GXOpenDisplay(hwndMain, GX_FULLSCREEN); GXOpenInput(); SetWindowPos(hwndMain, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE); SetForegroundWindow(hwndMain); SHFullScreen(hwndMain, SHFS_SHOWSIPBUTTON); SHFullScreen(hwndMain, SHFS_HIDETASKBAR); gxdp = GXGetDisplayProperties(); gxkl = GXGetDefaultKeys(GX_NORMALKEYS); bmono = (gxdp.ffFormat & kfDirect) && (gxdp.cBPP <= 8); b565 = (gxdp.ffFormat & kfDirect565) != 0; b555 = (gxdp.ffFormat & kfDirect555) != 0; if(bmono) { if(gxdp.ffFormat & kfDirectInverted) invert = (1< 319) x2 = 319; if(y2 > 199) y2 = 199; static UBYTE *src; static UBYTE *dst; static UBYTE *scraddr; static UBYTE *scr_ptr; static UBYTE *scr_ptr_limit; static UBYTE *src_limit; static long pixelstep; static long linestep; // Special code is used to deal with packed pixels in monochrome mode static UBYTE bitmask; static int bitshift; #ifdef SMOOTH x1 &= ~3; #endif scr_ptr = screen + x1 + y1*GFX_WIDTH; scr_ptr_limit = screen + x2 + y2*GFX_WIDTH; linestep = gxdp.cbyPitch; pixelstep = gxdp.cbxPitch; if(bmono) { if(pixelstep == 0) return; // unsupported screen geometry // this will work on mono iPAQ and @migo, don't know about any others bitshift = 0; bitmask = (1< 0) ? -1 : 1; } scraddr = (UBYTE*)GXBeginDraw(); if(scraddr) { if(bmono) { // Some partial pixel voodoo. I don't know if this works in all cases. scraddr += (x1*3/4)*pixelstep; int full = (y1*gxdp.cBPP)>>3; int partial = (y1*gxdp.cBPP)&7; scraddr += full*linestep; bitshift += gxdp.cBPP*partial; bitmask <<= gxdp.cBPP*partial; if(linestep < 0) scraddr += (pixelstep-1); } else scraddr += (x1*3/4)*pixelstep + y1*linestep; src_limit = scr_ptr + x2-x1+1; while(scr_ptr < scr_ptr_limit) { src = scr_ptr; dst = scraddr; while(src < src_limit) { #ifdef SMOOTH /* Let's see how fast that CPU is */ UBYTE r, g, b; r = (3*palRed[*(src+0)] + palRed[*(src+1)])>>2; g = (3*palGreen[*(src+0)] + palGreen[*(src+1)])>>2; b = (3*palBlue[*(src+0)] + palBlue[*(src+1)])>>2; if(b565) *(unsigned short*)dst = COLORCONV565(r,g,b); else if(b555) *(unsigned short*)dst = COLORCONV555(r,g,b); else if(bmono) *dst = (*dst & ~bitmask) | (COLORCONVMONO(r,g,b)<>1; g = (palGreen[*(src+1)] + palGreen[*(src+2)])>>1; b = (palBlue[*(src+1)] + palBlue[*(src+2)])>>1; if(b565) *(unsigned short*)dst = COLORCONV565(r,g,b); else if(b555) *(unsigned short*)dst = COLORCONV555(r,g,b); else if(bmono) *dst = (*dst & ~bitmask) | (COLORCONVMONO(r,g,b)<>2; g = (palGreen[*(src+2)] + 3*palGreen[*(src+3)])>>2; b = (palBlue[*(src+2)] + 3*palBlue[*(src+3)])>>2; if(b565) *(unsigned short*)dst = COLORCONV565(r,g,b); else if(b555) *(unsigned short*)dst = COLORCONV555(r,g,b); else if(bmono) *dst = (*dst & ~bitmask) | (COLORCONVMONO(r,g,b)<= 8) { bitshift = 0; bitmask = (1<