/* ScummVM - Scumm Interpreter * Copyright (C) 2001/2002 The ScummVM project * * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * $Header$ * */ #ifdef _WIN32_WCE #define POCKETSCUMM_VERSION "CVS build 0.3.1cvs" /* Original GFX code by Vasyl Tsvirkunov */ #include "wince.h" //#include //#include //#include "gx.h" //#include "screen.h" //#include "resource.h" //#include "dynamic_imports.h" #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) #define RED_FROM_565(x) ((((x)>>11)&0x1F) << 3) #define GREEN_FROM_565(x) ((((x)>>5)&0x3F) << 2) #define BLUE_FROM_565(x) (((x)&0x1F) << 3) #define MAX_CLR 0x100 static UBYTE palRed[MAX_CLR]; static UBYTE palGreen[MAX_CLR]; static UBYTE palBlue[MAX_CLR]; static unsigned short pal[MAX_CLR]; /* First 10 and last 10 colors on palettized devices require special treatment */ static UBYTE staticTranslate[20]; static UBYTE invert = 0; static int colorscale = 0; unsigned char color_match[500]; // used for paletted issues extern UBYTE item_toolbar[]; extern UBYTE item_toolbar_colors[]; extern UBYTE item_toolbarPortrait[]; extern UBYTE item_toolbarPortrait_colors[]; extern UBYTE item_disk[]; extern UBYTE item_disk_colors[]; extern UBYTE item_skip[]; extern UBYTE item_skip_colors[]; extern UBYTE item_soundOff[]; extern UBYTE item_soundOff_colors[]; extern UBYTE item_soundOn[]; extern UBYTE item_soundOn_colors[]; extern UBYTE item_monkeyPortrait[]; extern UBYTE item_monkeyPortrait_colors[]; extern UBYTE item_monkeyLandscape[]; extern UBYTE item_monkeyLandscape_colors[]; extern UBYTE item_keyboard[]; extern UBYTE item_keyboard_colors[]; extern UBYTE item_keyboardPortrait[]; extern UBYTE item_keyboardPortrait_colors[]; extern UBYTE item_loading[]; extern UBYTE item_loading_colors[]; extern UBYTE item_startup[]; extern UBYTE item_startup_colors[]; extern int item_startup_colors_size; extern UBYTE item_bomb[]; extern UBYTE item_bomb_colors[]; extern bool sound_activated; extern bool hide_toolbar; extern bool is_simon; extern bool smartphone; bool toolbar_drawn; bool draw_keyboard; bool wide_screen; GXDisplayProperties gxdp; int active; UBYTE decomp[320 * 240]; UBYTE comment_zone[8 * 220]; UBYTE highlighted_zone[8 * 220]; int _highlighted_index = -1; bool _gfx_mode_switch; int _game_selection_X_offset; int _game_selection_Y_offset; float _screen_factor; struct tScreenGeometry { long width; long height; long startoffset; long sourceoffset; long linestep; long pixelstep; long xSkipMask; long xLimit; long lineLimit; }; tScreenGeometry geom[3]; tScreenGeometry portrait_geometry; int currentScreenMode = 0; int useMode = 0; int maxMode = 2; int filter_available; int smooth_filter; int toolbar_available; UBYTE *toolbar = NULL; UBYTE *noGAPI_video_buffer = NULL; HDC noGAPI_compat; char noGAPI = 0; /* Using vectorized function to save on branches */ typedef void (*tCls)(); typedef void (*tBlt)(UBYTE*); typedef void (*tBlt_part)(UBYTE*,int, int, int, int, UBYTE*, int); typedef void (*tSet_565)(INT16 *buffer, int pitch, int x, int y, int width, int height); void mono_Cls(); void mono_Blt(UBYTE*); void mono_Blt_part(UBYTE*, int, int, int, int, UBYTE*, int); void mono_Set_565(INT16*, int, int, int, int, int); void palette_Cls(); void palette_Blt(UBYTE*); void palette_Blt_part(UBYTE*, int, int, int, int, UBYTE*, int); void palette_Set_565(INT16*, int, int, int, int, int); void hicolor_Cls(); void hicolor555_Blt(UBYTE*); void hicolor555_Blt_part(UBYTE*, int, int, int, int, UBYTE*, int); void hicolor555_Set_565(INT16*, int, int, int, int, int); void hicolor565_Blt(UBYTE*); void hicolor565_Blt_part(UBYTE*, int, int, int, int, UBYTE*, int); //void hicolor565_Get_565(INT16*, int, int, int, int, int); void hicolor565_Set_565(INT16*, int, int, int, int, int); void noGAPI_Cls(); void noGAPI_Blt(UBYTE*); void noGAPI_Blt_part(UBYTE*, int, int, int, int, UBYTE*, int); void noGAPI_Set_565(INT16*, int, int, int, int, int); //void NULL_Get_565(INT16*, int, int, int, int, int); void NULL_Set_565(INT16*, int, int, int, int, int); void palette_update(); void printString(const char *, int, int, int, int = -1, int = 220); int drawString(const char *, int, int, int, int = -1); static byte textfont[] = {0,0,99,1,226,8,4,8,6,8,6,0,0,0,0,0,0,0,0,0,0,0,8,2,1,8,0,0,0,0,0,0,0,0,0,0,0,0,4,3,7,8,7,7,8,4,5,5,8,7,4,7,3,8,7,7,7,7,8,7,7,7,7,7,3,4,7,5,7,7,8,7,7,7,7,7,7,7,7,5,7,7, 7,8,7,7,7,7,7,7,7,7,7,8,7,7,7,5,8,5,8,8,7,7,7,6,7,7,7,7,7,5,6,7,5,8,7,7,7,7,7,7,7,7,7,8,7,7,7,5,3,5,0,8,7,7,7,7,7,7,0,6,7,7,7,5,5,5,7,0,6,8,8,7,7,7,7,7,0,7,7,0,0, 0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,1,3,6,12, 24,62,3,0,128,192,96,48,24,124,192,0,0,3,62,24,12,6,3,1,0,192,124,24,48,96,192,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,237,74,72,0,0,0,0,0,128,128,128,0,0,0,0,0,0,0,0,0,0,0,0,0,60,66,153,161,161,153,66,60,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,96,96,96,96,0,0,96,0,102,102,102,0,0,0,0,0,102,102,255,102,255,102,102,0,24,62,96,60,6,124,24,0,98,102,12,24,48,102,70,0,60,102,60,56,103,102,63,0,96,48,16,0,0,0,0,0,24,48,96,96,96,48,24,0,96,48,24,24,24,48,96,0, 0,102,60,255,60,102,0,0,0,24,24,126,24,24,0,0,0,0,0,0,0,48,48,96,0,0,0,126,0,0,0,0,0,0,0,0,0,96,96,0,0,3,6,12,24,48,96,0,60,102,102,102,102,102,60,0,24,24,56,24,24,24,126,0,60,102,6,12,48,96,126,0,60,102,6,28,6,102,60,0,6, 14,30,102,127,6,6,0,126,96,124,6,6,102,60,0,60,102,96,124,102,102,60,0,126,102,12,24,24,24,24,0,60,102,102,60,102,102,60,0,60,102,102,62,6,102,60,0,0,0,96,0,0,96,0,0,0,0,48,0,0,48,48,96,14,24,48,96,48,24,14,0,0,0,120,0,120,0,0,0,112,24, 12,6,12,24,112,0,60,102,6,12,24,0,24,0,0,0,0,255,255,0,0,0,24,60,102,126,102,102,102,0,124,102,102,124,102,102,124,0,60,102,96,96,96,102,60,0,120,108,102,102,102,108,120,0,126,96,96,120,96,96,126,0,126,96,96,120,96,96,96,0,60,102,96,110,102,102,60,0,102,102,102, 126,102,102,102,0,120,48,48,48,48,48,120,0,30,12,12,12,12,108,56,0,102,108,120,112,120,108,102,0,96,96,96,96,96,96,126,0,99,119,127,107,99,99,99,0,102,118,126,126,110,102,102,0,60,102,102,102,102,102,60,0,124,102,102,124,96,96,96,0,60,102,102,102,102,60,14,0,124,102,102,124, 120,108,102,0,60,102,96,60,6,102,60,0,126,24,24,24,24,24,24,0,102,102,102,102,102,102,60,0,102,102,102,102,102,60,24,0,99,99,99,107,127,119,99,0,102,102,60,24,60,102,102,0,102,102,102,60,24,24,24,0,126,6,12,24,48,96,126,0,120,96,96,96,96,96,120,0,3,6,12,24,48, 96,192,0,120,24,24,24,24,24,120,0,0,0,0,0,0,219,219,0,0,0,0,0,0,0,0,255,102,102,102,0,0,0,0,0,0,0,60,6,62,102,62,0,0,96,96,124,102,102,124,0,0,0,60,96,96,96,60,0,0,6,6,62,102,102,62,0,0,0,60,102,126,96,60,0,0,14,24,62,24,24, 24,0,0,0,62,102,102,62,6,124,0,96,96,124,102,102,102,0,0,48,0,112,48,48,120,0,0,12,0,12,12,12,12,120,0,96,96,108,120,108,102,0,0,112,48,48,48,48,120,0,0,0,102,127,127,107,99,0,0,0,124,102,102,102,102,0,0,0,60,102,102,102,60,0,0,0,124,102,102,124,96, 96,0,0,62,102,102,62,6,6,0,0,124,102,96,96,96,0,0,0,62,96,60,6,124,0,0,24,126,24,24,24,14,0,0,0,102,102,102,102,62,0,0,0,102,102,102,60,24,0,0,0,99,107,127,62,54,0,0,0,102,60,24,60,102,0,0,0,102,102,102,62,12,120,0,0,126,12,24,48,126,0, 24,48,48,96,48,48,24,0,96,96,96,0,96,96,96,0,96,48,48,24,48,48,96,0,0,0,0,0,0,0,0,0,8,12,14,255,255,14,12,8,60,102,96,96,102,60,24,56,102,0,102,102,102,102,62,0,12,24,60,102,126,96,60,0,24,36,60,6,62,102,62,0,102,0,60,6,62,102,62,0,48, 24,60,6,62,102,62,0,0,0,0,0,0,0,0,0,0,60,96,96,96,60,24,56,24,36,60,102,126,96,60,0,102,0,60,102,126,96,60,0,48,24,60,102,126,96,60,0,0,216,0,112,48,48,120,0,48,72,0,112,48,48,120,0,96,48,0,112,48,48,120,0,102,24,60,102,126,102,102,0,0,0, 0,0,0,0,0,0,24,48,124,96,120,96,124,0,0,0,108,26,126,216,110,0,30,40,40,126,72,136,142,0,24,36,60,102,102,102,60,0,102,0,60,102,102,102,60,0,48,24,60,102,102,102,60,0,24,36,0,102,102,102,62,0,48,24,102,102,102,102,62,0,0,0,0,0,0,0,0,0,102,60,102, 102,102,102,60,0,102,0,102,102,102,102,60,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,24,60,6,62,102,62,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,28,54,54,124,102,102,124,64,0,0,0}; static tCls pCls = NULL; static tBlt pBlt = NULL; static tBlt_part pBlt_part = NULL; static tSet_565 pSet_565 = NULL; static int _geometry_w; static int _geometry_h; static int _saved_geometry_h; HWND hWndMain; typedef enum { DEVICE_HPC = 0, DEVICE_PPC, DEVICE_SMARTPHONE } pdaDevice; typedef enum { DEVICE_GAPI = 0, DEVICE_VIDEO, DEVICE_GDI } gfxDevice; typedef enum { VIDEO_565 = 0, VIDEO_555, VIDEO_PALETTED, VIDEO_MONO, VIDEO_DONT_CARE } gfxOption; unsigned char* pda_device_name[] = { (unsigned char*)"HPC", (unsigned char*)"PPC", (unsigned char*)"Smartphone" }; unsigned char* gfx_device_name[] = { (unsigned char*)"GAPI", (unsigned char*)"Direct Video", (unsigned char*)"GDI" }; unsigned char* gfx_device_options_name[] = { (unsigned char*)"565", (unsigned char*)"555", (unsigned char*)"paletted", (unsigned char*)"mono", (unsigned char*)"", }; pdaDevice _pda_device; gfxDevice _gfx_device; gfxOption _gfx_option; unsigned char *image_expand(unsigned char *src) { int i = 0; int j; int expanded = 0; for (;;) { if (!src[i]) { if (!src[i + 1]) break; for (j=0; j maxMode) currentScreenMode = 0; } int GetScreenMode() { return currentScreenMode; } void GraphicsSuspend() { if(active) { active = 0; dynamicGXSuspend(); } } void GraphicsResume() { if(!active) { active = 1; dynamicGXResume(); } palette_update(); } void GraphicsOff(void) { dynamicGXCloseDisplay(); active = 0; } void SetScreenGeometry(int w, int h) { // Complain (loudly) if w > 320 and h > 240 ... if (w != 320 || h > 240) { MessageBox(NULL, TEXT("Unsupported screen geometry !"), TEXT("Error"), MB_OK); exit(1); } _geometry_w = w; _geometry_h = h; _saved_geometry_h = h; RestoreScreenGeometry(); } void LimitScreenGeometry() { if (_geometry_h > 200) { geom[0].lineLimit = _geometry_w*200; geom[1].lineLimit = _geometry_w*200; geom[2].lineLimit = _geometry_w*200; _geometry_h = 200; } } void RestoreScreenGeometry() { _geometry_h = _saved_geometry_h; geom[0].lineLimit = _geometry_w * _geometry_h; geom[1].lineLimit = _geometry_w * _geometry_h; geom[2].lineLimit = _geometry_w * _geometry_h; } int GraphicsOn(HWND hWndMain_param, bool gfx_mode_switch) { hWndMain = hWndMain_param; _gfx_device = DEVICE_GAPI; if (!noGAPI && dynamicGXOpenDisplay(hWndMain, GX_FULLSCREEN) == GAPI_SIMU) _gfx_device = DEVICE_VIDEO; _gfx_mode_switch = gfx_mode_switch; if (_gfx_mode_switch) { _game_selection_X_offset = GAME_SELECTION_X_OFFSET; _game_selection_Y_offset = GAME_SELECTION_Y_OFFSET; } else { _game_selection_X_offset = 0; _game_selection_Y_offset = 0; } memset(&gxdp, 0, sizeof(gxdp)); if (!noGAPI) gxdp = dynamicGXGetDisplayProperties(); else { gxdp.cxWidth = GetSystemMetrics(SM_CXSCREEN); gxdp.cyHeight = GetSystemMetrics(SM_CYSCREEN); gxdp.ffFormat = 0xA8; } // Possible Aero problem if (gxdp.cbxPitch == 61440 && gxdp.cbyPitch == -2 && gxdp.ffFormat == 0x18 ) { gxdp.cbxPitch = 640; gxdp.cbyPitch = -2; gxdp.ffFormat = kfDirect | kfDirect565; } if(noGAPI) { HDC hdc; pCls = noGAPI_Cls; pBlt = noGAPI_Blt; pBlt_part = noGAPI_Blt_part; pSet_565 = noGAPI_Set_565; toolbar_available = 1; // Init GDI noGAPI_video_buffer = (UBYTE*)malloc(320 * 240 * 2); hdc = GetDC(hWndMain); noGAPI_compat = CreateCompatibleDC(hdc); ReleaseDC(hWndMain, hdc); _gfx_device = DEVICE_GDI; _gfx_option = VIDEO_DONT_CARE; } else if(gxdp.ffFormat & kfDirect565) { pCls = hicolor_Cls; pBlt = hicolor565_Blt; pBlt_part = hicolor565_Blt_part; pSet_565 = hicolor565_Set_565; filter_available = 1; smooth_filter = 1; toolbar_available = 1; _gfx_option = VIDEO_565; } else if(gxdp.ffFormat & kfDirect555) { pCls = hicolor_Cls; pBlt = hicolor555_Blt; pBlt_part = hicolor555_Blt_part; pSet_565 = hicolor555_Set_565; filter_available = 1; smooth_filter = 1; toolbar_available = 1; _gfx_option = VIDEO_555; } else if((gxdp.ffFormat & kfDirect) && (gxdp.cBPP <= 8)) { pCls = mono_Cls; pBlt = mono_Blt; pBlt_part = mono_Blt_part; pSet_565 = mono_Set_565; if(gxdp.ffFormat & kfDirectInverted) invert = (1<= 4) filter_available = 1; toolbar_available = 1; _gfx_option = VIDEO_MONO; } else if(gxdp.ffFormat & kfPalette) { pCls = palette_Cls; pBlt = palette_Blt; pBlt_part = palette_Blt_part; pSet_565 = palette_Set_565; toolbar_available = 1; _gfx_option = VIDEO_PALETTED; } if(!pCls || !pBlt || (!smartphone && (gxdp.cxWidth < 240 || gxdp.cyHeight < 240)) ) { // I don't believe there are devices that end up here GraphicsOff(); return 1; } if (smartphone) toolbar_available = 0; // compute geometries // portrait portrait_geometry.width = gxdp.cxWidth; // 240 portrait_geometry.height = gxdp.cyHeight; // 320 portrait_geometry.startoffset = 0; portrait_geometry.sourceoffset = 0; portrait_geometry.linestep = gxdp.cbyPitch; portrait_geometry.pixelstep = gxdp.cbxPitch; portrait_geometry.xSkipMask = gxdp.cxWidth < 320 ? 0x00000003 : 0xffffffff; portrait_geometry.xLimit = 320; // skip 1/4 portrait_geometry.lineLimit = 320*200; geom[0].width = gxdp.cxWidth; geom[0].height = gxdp.cyHeight; geom[0].startoffset = 0; geom[0].sourceoffset = 0; geom[0].linestep = gxdp.cbyPitch; geom[0].pixelstep = gxdp.cbxPitch; geom[0].xSkipMask = 0xffffffff; geom[0].xLimit = 240; geom[0].lineLimit = 320*240; _screen_factor = 1/2; // This will be overridden for the Smartphone implementation // left handed landscape geom[1].width = gxdp.cyHeight; // 320 geom[1].height = gxdp.cxWidth; // 240 geom[1].startoffset = gxdp.cbyPitch*(gxdp.cyHeight-1); geom[1].sourceoffset = 0; geom[1].linestep = gxdp.cbxPitch; geom[1].pixelstep = -gxdp.cbyPitch; geom[1].xSkipMask = 0xffffffff; geom[1].xLimit = 320; // no skip geom[1].lineLimit = 320*200; // right handed landscape geom[2].width = gxdp.cyHeight; // 320 geom[2].height = gxdp.cxWidth; // 240 geom[2].startoffset = gxdp.cbxPitch*(gxdp.cxWidth-1); geom[2].sourceoffset = 0; geom[2].linestep = -gxdp.cbxPitch; geom[2].pixelstep = gxdp.cbyPitch; geom[2].xSkipMask = 0xffffffff; geom[2].xLimit = 320; // no skip geom[2].lineLimit = 320*200; if(gxdp.cyHeight < 320 && !smartphone) maxMode = 0; // portrait only! active = 1; wide_screen = GetSystemMetrics(SM_CXSCREEN) >= 320; if (wide_screen) _pda_device = DEVICE_HPC; else { if (smartphone) _pda_device = DEVICE_SMARTPHONE; else _pda_device = DEVICE_PPC; } return 0; } /* Find the best color match in the palette (limited to 'limit' entries) */ UBYTE best_match(UBYTE r, UBYTE g, UBYTE b, int limit) { UBYTE best = 0; int distance = 768; int i, d; for(i=0; ipalVersion = 0x300; ple->palNumEntries = 256; for(int i=0; i<236; i++) // first 10 and last ten belong to the system! { ple->palPalEntry[i+10].peBlue = palBlue[i]; ple->palPalEntry[i+10].peGreen = palGreen[i]; ple->palPalEntry[i+10].peRed = palRed[i]; ple->palPalEntry[i+10].peFlags = PC_RESERVED; } HDC hDC = GetDC(hWndMain); GetSystemPaletteEntries(hDC, 0, 10, &(ple->palPalEntry[0])); GetSystemPaletteEntries(hDC, 246, 10, &(ple->palPalEntry[246])); HPALETTE hpal = CreatePalette(ple); SelectPalette(hDC, hpal, FALSE); RealizePalette(hDC); DeleteObject((HGDIOBJ)hpal); ReleaseDC(hWndMain, hDC); free((void*)ple); for(i=0; i<20; i++) staticTranslate[i] = best_match(palRed[i+236], palGreen[i+236], palBlue[i+236], 236)+10; memset(color_match, 255, sizeof(color_match)); } } void SetPalEntry(int ent, UBYTE r, UBYTE g, UBYTE b) { if (ent >= MAX_CLR) return; palRed[ent] = r; palGreen[ent] = g; palBlue[ent] = b; if(gxdp.ffFormat & kfDirect565) pal[ent] = COLORCONV565(r,g,b); else if(gxdp.ffFormat & kfDirect555) pal[ent] = COLORCONV555(r,g,b); else if(gxdp.ffFormat & kfDirect) pal[ent] = COLORCONVMONO(r,g,b); } /* *************** CLS IMPLEMENTATIONS ****************** */ void mono_Cls() { int x, y; UBYTE* dst; UBYTE *scraddr; int linestep, pixelstep; UBYTE fillcolor; fillcolor = (gxdp.ffFormat & kfDirectInverted) ? 0xff : 0x00; pixelstep = geom[0].pixelstep; if(pixelstep == 0) return; linestep = (pixelstep > 0) ? -1 : 1; scraddr = (UBYTE*)dynamicGXBeginDraw(); if(scraddr) { for(y=0; y= x1 && y >= y1) && (x <= x2 && y <= y2)); } ToolbarSelected getToolbarSelection (int x, int y) { int test_x, test_y; /* if (!currentScreenMode) return ToolbarNone; */ if (!(x >= 10 && y >= 204)) return ToolbarNone; test_x = 10; test_y = (currentScreenMode || wide_screen ? 204 : 240); if (isInBox(x, y, test_x, test_y, test_x + 32, test_y + 32)) return ToolbarSaveLoad; test_x += 40; if (isInBox(x, y, test_x, test_y, test_x + 32, test_y + 32)) return ToolbarSkip; test_x += 40; if (isInBox(x, y, test_x, test_y, test_x + 32, test_y + 32)) return ToolbarSound; if (_gfx_mode_switch) { test_x += 40; if (isInBox(x, y, test_x, test_y, test_x + 32, test_y + 32)) return ToolbarMode; } return ToolbarNone; } /* ************************** BLT IMPLEMENTATION **************************** */ void Blt(UBYTE * scr_ptr) { pBlt(scr_ptr); //if (toolbar_available && currentScreenMode && !toolbar_drawn) if (toolbar_available && !toolbar_drawn && !hide_toolbar) drawAllToolbar(); } void Blt_part(UBYTE * src_ptr, int x, int y, int width, int height, int pitch, bool check) { if (toolbar_available && !toolbar_drawn && !hide_toolbar) drawAllToolbar(); pBlt_part(src_ptr, x, y, width, height, NULL, pitch); if (check && (y > _geometry_h || (y + height) > _geometry_h)) { toolbar_drawn = false; } } void checkToolbar() { if (toolbar_available && !toolbar_drawn && !hide_toolbar) drawAllToolbar(); } /* *************************** MONO DISPLAY ********************************* */ #define ADVANCE_PARTIAL(address, step) \ bitshift += gxdp.cBPP; \ if(bitshift >= 8) \ { \ bitshift = 0; \ bitmask = (1<>= gxdp.cBPP; void mono_Set_565(INT16 *buffer, int pitch, int x, int y, int width, int height) { static UBYTE *scraddr; static UBYTE *dst; static long pixelstep; static long linestep; static UBYTE bitmask; static int bitshift; static long skipmask; scraddr = (UBYTE*)dynamicGXBeginDraw(); pixelstep = geom[useMode].pixelstep; linestep = (pixelstep > 0) ? -1 : 1; skipmask = geom[useMode].xSkipMask; bitshift = 0; bitmask = (1< 0) ? -1 : 1; bitshift = 0; bitmask = (1<= 4) { while(scr_ptr < scr_ptr_limit) { int i; src = scr_ptr; dst = scraddr; /* skip non updated pixels for this line */ for (i=0; i < x; i++) dst += pixelstep; while(src < src_limit) { UBYTE r, g, b; if (!own_palette) { 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; } else { r = (3 * own_palette[3 * *(src + 0)] + own_palette[3 * *(src + 1)]) >> 2; g = (3 * own_palette[3 * *(src + 0) + 1] + own_palette[3 * *(src + 1) + 1]) >> 2; b = (3 * own_palette[3 * *(src + 0) + 2] + own_palette[3 * *(src + 1) + 2]) >> 2; } *dst = (*dst & ~bitmask) | (COLORCONVMONO(r,g,b)<>1; g = (palGreen[*(src+1)] + palGreen[*(src+2)])>>1; b = (palBlue[*(src+1)] + palBlue[*(src+2)])>>1; } else { r = (own_palette[3 * *(src + 1)] + own_palette[3 * *(src + 2)]) >> 2; g = (own_palette[3 * *(src + 1) + 1] + own_palette[3 * *(src + 2) + 1]) >> 2; b = (own_palette[3 * *(src + 1) + 2] + own_palette[3 * *(src + 2) + 2]) >> 2; } *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; } else { r = (own_palette[3 * *(src + 2)] + 3 * own_palette[3 * *(src + 3)]) >> 2; g = (own_palette[3 * *(src + 2) + 1] + 3 * own_palette[3 * *(src + 3) + 1]) >> 2; b = (own_palette[3 * *(src + 2) + 2] + 3 * own_palette[3 * *(src + 3) + 2]) >> 2; } *dst = (*dst & ~bitmask) | (COLORCONVMONO(r,g,b)< 0) ? 1 : -1; if(scraddr) { scraddr += geom[useMode].startoffset; scr_ptr += geom[useMode].sourceoffset; //scr_ptr_limit = scr_ptr + geom[useMode].lineLimit; //src_limit = scr_ptr + geom[useMode].xLimit; /* Update offsets to the current line */ scraddr += y * linestep; scr_ptr_limit = scr_ptr + (pitch ? pitch : width) * height; src_limit = scr_ptr + width; if(skipmask != 0xffffffff) { if(pixelstep > 0) { bitshift = 8-gxdp.cBPP; bitmask = ((1< 0) { bitshift = 8-gxdp.cBPP; bitmask = ((1<>2; g = (3*palGreen[*(src+0)] + palGreen[*(src+1)])>>2; b = (3*palBlue[*(src+0)] + palBlue[*(src+1)])>>2; } else { r = (3 * own_palette[3 * *(src + 0)] + own_palette[3 * *(src + 1)]) >> 2; g = (3 * own_palette[3 * *(src + 0) + 1] + own_palette[3 * *(src + 1) + 1]) >> 2; b = (3 * own_palette[3 * *(src + 0) + 2] + own_palette[3 * *(src + 1) + 2]) >> 2; } *(unsigned short*)dst = COLORCONV555(r,g,b); dst += pixelstep; if (!own_palette) { r = (palRed[*(src+1)] + palRed[*(src+2)])>>1; g = (palGreen[*(src+1)] + palGreen[*(src+2)])>>1; b = (palBlue[*(src+1)] + palBlue[*(src+2)])>>1; } else { r = (own_palette[3 * *(src + 1)] + own_palette[3 * *(src + 2)]) >> 2; g = (own_palette[3 * *(src + 1) + 1] + own_palette[3 * *(src + 2) + 1]) >> 2; b = (own_palette[3 * *(src + 1) + 2] + own_palette[3 * *(src + 2) + 2]) >> 2; } *(unsigned short*)dst = COLORCONV555(r,g,b); dst += pixelstep; if (!own_palette) { r = (palRed[*(src+2)] + 3*palRed[*(src+3)])>>2; g = (palGreen[*(src+2)] + 3*palGreen[*(src+3)])>>2; b = (palBlue[*(src+2)] + 3*palBlue[*(src+3)])>>2; } else { r = (own_palette[3 * *(src + 2)] + 3 * own_palette[3 * *(src + 3)]) >> 2; g = (own_palette[3 * *(src + 2) + 1] + 3 * own_palette[3 * *(src + 3) + 1]) >> 2; b = (own_palette[3 * *(src + 2) + 2] + 3 * own_palette[3 * *(src + 3) + 2]) >> 2; } *(unsigned short*)dst = COLORCONV555(r,g,b); dst += pixelstep; src += 4; } scraddr += linestep; scr_ptr += (pitch ? pitch : width); src_limit += (pitch ? pitch : width); } } else if(skipmask != 0xffffffff) { while(scr_ptr < scr_ptr_limit) { int i; src = scr_ptr; dst = scraddr; /* skip non updated pixels for this line */ for (i=0; i < x; i++) dst += pixelstep; while(src < src_limit) { if((long)src & skipmask) { if (!own_palette) *(unsigned short*)dst = pal[*src]; else *(unsigned short*)dst = COLORCONV555(own_palette[3 * *src], own_palette[(3 * *src) + 1], own_palette[(3 * *src) + 2]); dst += pixelstep; } src ++; } scraddr += linestep; scr_ptr += (pitch ? pitch : width); src_limit += (pitch ? pitch : width); } } else { while(scr_ptr < scr_ptr_limit) { int i; src = scr_ptr; dst = scraddr; /* skip non updated pixels for this line */ for (i=0; i < x; i++) dst += pixelstep; while(src < src_limit) { if (!own_palette) *(unsigned short*)dst = pal[*src]; else *(unsigned short*)dst = COLORCONV555(own_palette[3 * *src], own_palette[(3 * *src) + 1], own_palette[(3 * *src) + 2]); dst += pixelstep; src ++; } scraddr += linestep; scr_ptr += (pitch ? pitch : width); src_limit += (pitch ? pitch : width); } } dynamicGXEndDraw(); } } /* ********************************* 565 DISPLAY ********************************* */ void hicolor565_Blt(UBYTE *src_ptr) { hicolor565_Blt_part(src_ptr, 0, 0, _geometry_w, _geometry_h, NULL, 0); } void hicolor565_Set_565(INT16 *buffer, int pitch, int x, int y, int width, int height) { static UBYTE *scraddr; static UBYTE *dst; static long pixelstep; static long linestep; static long skipmask; scraddr = (UBYTE*)dynamicGXBeginDraw(); pixelstep = geom[useMode].pixelstep; linestep = geom[useMode].linestep; skipmask = geom[useMode].xSkipMask; if(scraddr) { int lines = 0; int current = 0; scraddr += geom[useMode].startoffset; scraddr += y * linestep; if (smartphone) { while(lines != height) { int i; current = 0; dst = scraddr; /* skip non updated pixels for this line */ dst += x * pixelstep; for (i=0; i>2; g = (3 * GREEN_FROM_565(buffer[i]) + GREEN_FROM_565(buffer[i + 1]))>>2; b = (3 * BLUE_FROM_565(buffer[i]) + BLUE_FROM_565(buffer[i + 1]))>>2; *(unsigned short*)dst = COLORCONV565(r, g, b); dst += pixelstep; r = (RED_FROM_565(buffer[i + 1]) + RED_FROM_565(buffer[i + 2]))>>1; g = (GREEN_FROM_565(buffer[i + 1]) + GREEN_FROM_565(buffer[i + 2]))>>1; b = (BLUE_FROM_565(buffer[i + 1]) + BLUE_FROM_565(buffer[i + 2]))>>1; *(unsigned short*)dst = COLORCONV565(r, g, b); dst += pixelstep; } buffer += pitch; scraddr += linestep; lines++; if (lines != 0 && !(lines % 7)) { lines++; buffer += pitch; } } } else { while(lines != height) { int i; current = 0; dst = scraddr; /* skip non updated pixels for this line */ dst += x * pixelstep; for (i=0; i>2; g = (3*palGreen[first] + palGreen[second])>>2; b = (3*palBlue[first] + palBlue[second])>>2; } else { register first = 3 * *(src + 0); register second = 3 * *(src + 1); r = (3 * own_palette[first] + own_palette[second]) >> 2; g = (3 * own_palette[first + 1] + own_palette[second + 1]) >> 2; b = (3 * own_palette[first + 2] + own_palette[second + 2]) >> 2; } *(unsigned short*)dst = COLORCONV565(r,g,b); dst += pixelstep; if (!own_palette) { register first = *(src + 1); register second = *(src + 2); r = (palRed[first] + palRed[second])>>1; g = (palGreen[first] + palGreen[second])>>1; b = (palBlue[first] + palBlue[second])>>1; } else { register first = 3 * *(src + 1); register second = 3 * *(src + 2); r = (own_palette[first] + own_palette[second]) >> 1; g = (own_palette[first + 1] + own_palette[second + 1]) >> 1; b = (own_palette[first + 2] + own_palette[second + 2]) >> 1; } *(unsigned short*)dst = COLORCONV565(r,g,b); dst += pixelstep; src += 3; } scraddr += linestep; scr_ptr += (pitch ? pitch : width); src_limit += (pitch ? pitch : width); line++; if (line == 7) { scr_ptr += (pitch ? pitch : width); src_limit += (pitch ? pitch : width); line = 0; } } } else /* Internal pixel loops */ if(skipmask == 3 && smooth_filter) { while(scr_ptr < scr_ptr_limit) { int i; src = scr_ptr; dst = scraddr; /* skip non updated pixels for this line */ for (i=0; i < x; i++) dst += pixelstep; while(src < src_limit) { UBYTE r, g, b; if (!own_palette) { 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; } else { r = (3 * own_palette[3 * *(src + 0)] + own_palette[3 * *(src + 1)]) >> 2; g = (3 * own_palette[3 * *(src + 0) + 1] + own_palette[3 * *(src + 1) + 1]) >> 2; b = (3 * own_palette[3 * *(src + 0) + 2] + own_palette[3 * *(src + 1) + 2]) >> 2; } *(unsigned short*)dst = COLORCONV565(r,g,b); dst += pixelstep; if (!own_palette) { r = (palRed[*(src+1)] + palRed[*(src+2)])>>1; g = (palGreen[*(src+1)] + palGreen[*(src+2)])>>1; b = (palBlue[*(src+1)] + palBlue[*(src+2)])>>1; } else { r = (own_palette[3 * *(src + 1)] + own_palette[3 * *(src + 2)]) >> 1; g = (own_palette[3 * *(src + 1) + 1] + own_palette[3 * *(src + 2) + 1]) >> 1; b = (own_palette[3 * *(src + 1) + 2] + own_palette[3 * *(src + 2) + 2]) >> 1; } *(unsigned short*)dst = COLORCONV565(r,g,b); dst += pixelstep; if (!own_palette) { r = (palRed[*(src+2)] + 3*palRed[*(src+3)])>>2; g = (palGreen[*(src+2)] + 3*palGreen[*(src+3)])>>2; b = (palBlue[*(src+2)] + 3*palBlue[*(src+3)])>>2; } else { r = (own_palette[3 * *(src + 2)] + 3 * own_palette[3 * *(src + 3)]) >> 2; g = (own_palette[3 * *(src + 2) + 1] + 3 * own_palette[3 * *(src + 3) + 1]) >> 2; b = (own_palette[3 * *(src + 2) + 2] + 3 * own_palette[3 * *(src + 3) + 2]) >> 2; } *(unsigned short*)dst = COLORCONV565(r,g,b); dst += pixelstep; src += 4; } scraddr += linestep; scr_ptr += (pitch ? pitch : width); src_limit += (pitch ? pitch : width); } } else if(skipmask != 0xffffffff) { int line = 0; int toskip = 0; while(scr_ptr < scr_ptr_limit) { int i; src = scr_ptr; dst = scraddr; /* skip non updated pixels for this line */ for (i=0; i < x; i++) dst += pixelstep; while(src < src_limit) { if((long)src & skipmask) { if (!own_palette) *(unsigned short*)dst = pal[*src]; else *(unsigned short*)dst = COLORCONV565(own_palette[3 * *src], own_palette[(3 * *src) + 1], own_palette[(3 * *src) + 2]); dst += pixelstep; } src ++; } scraddr += linestep; scr_ptr += (pitch ? pitch : width); src_limit += (pitch ? pitch : width); } } else { while(scr_ptr < scr_ptr_limit) { int i; src = scr_ptr; dst = scraddr; /* skip non updated pixels for this line */ for (i=0; i < x; i++) dst += pixelstep; while(src < src_limit) { if (!own_palette) *(unsigned short*)dst = pal[*src]; else *(unsigned short*)dst = COLORCONV565(own_palette[3 * *src], own_palette[(3 * *src) + 1], own_palette[(3 * *src) + 2]); dst += pixelstep; src ++; } scraddr += linestep; scr_ptr += (pitch ? pitch : width); src_limit += (pitch ? pitch : width); } } dynamicGXEndDraw(); } } /* ********************************* NO GAPI DISPLAY ********************************* */ void noGAPI_Cls() { HBITMAP old; RECT rc; HDC hdc = GetDC(hWndMain); HBITMAP hb; GetWindowRect(hWndMain, &rc); memset(noGAPI_video_buffer, 0x00, sizeof(noGAPI_video_buffer)); if (currentScreenMode || wide_screen) hb = CreateBitmap(320, 240, 1, 16, noGAPI_video_buffer); else hb = CreateBitmap(240, 320, 1, 16, noGAPI_video_buffer); old = (HBITMAP)SelectObject(noGAPI_compat, hb); if (currentScreenMode || wide_screen) BitBlt(hdc, 0, 0, 320, 240, noGAPI_compat, 0, 0, SRCCOPY); else BitBlt(hdc, 0, 0, 240, 320, noGAPI_compat, 0, 0, SRCCOPY); SelectObject(noGAPI_compat, old); ReleaseDC(hWndMain, hdc); DeleteObject(hb); } void noGAPI_Blt(UBYTE *src_ptr) { noGAPI_Blt_part(src_ptr, 0, 0, _geometry_w, _geometry_h, NULL, 0); } void noGAPI_Set_565(INT16 *buffer, int pitch, int x, int y, int width, int height) { HBITMAP old; RECT rc; HDC hdc = GetDC(hWndMain); HBITMAP hb; UBYTE *work_buffer; int i; int j; //long skipmask; //skipmask = geom[useMode].xSkipMask; GetWindowRect(hWndMain, &rc); work_buffer = noGAPI_video_buffer; unsigned short *work_buffer_2 = (unsigned short*)work_buffer; if (currentScreenMode && !wide_screen) { for (i=0; i>= 1) == 0) { buffer = *tmp++; mask = 0x80; } color = ((buffer & mask) != 0); if (color) ptr[x] = textcolor; else if (highlight > 0) ptr[x] = highlight; } if (highlight > 0) { int i; for (i=9; i MAX_CHARS_PER_LINE) memcpy(substring, str + current_pos, MAX_CHARS_PER_LINE); else strcpy(substring, str + current_pos); printString(substring, x, current_y, textcolor, highlight, 320); pBlt_part(decomp + (current_y * 320), 0, current_y, 320, 8, item_startup_colors, 0); current_pos += MAX_CHARS_PER_LINE; current_y += 10; } return current_y; } /* ************************** DIRECT BLT IMPLEMENTATION ************************* */ void Get_565(UBYTE *src, INT16 *buffer, int pitch, int x, int y, int width, int height) { int i,j; UBYTE *tempo = (UBYTE*)buffer; // Dumb conversion to 565 for (i=0; i