/* 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 /* Original GFX code by Vasyl Tsvirkunov */ #include "wince.h" //#include <windows.h> //#include <Aygshell.h> //#include "gx.h" //#include "screen.h" //#include "resource.h" //#include "dynamic_imports.h" #include <tlhelp32.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 const char *getBuildDate(); 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; extern bool high_res; extern NewGui *g_gui; bool toolbar_drawn; bool draw_keyboard; bool wide_screen; bool extra_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; #ifndef NEW_GAPI_CODE UBYTE *noGAPI_video_buffer = NULL; HDC noGAPI_compat; #else UBYTE *noGAPI_buffer; HBITMAP noGAPI_bitmap; BITMAPINFOHEADER noGAPI_bitmap_header; HDC noGAPI_compat; #endif 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<src[i + 1]; j++) decomp[expanded++] = src[i+2]; i += 3; } else decomp[expanded++] = src[i++]; } return decomp; } void SetScreenMode(int mode) { currentScreenMode = mode; if(currentScreenMode > 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) { char tempo[100]; sprintf(tempo, "Unsupported screen geometry %dx%d", w, h); drawError(tempo); exit(1); } */ _geometry_w = w; _geometry_h = h; _saved_geometry_h = h; RestoreScreenGeometry(); } void LimitScreenGeometry() { int limit; if (high_res) { if (wide_screen) limit = 440; else limit = 400; } else limit = 200; if (_geometry_h > limit) { geom[0].lineLimit = _geometry_w*limit; geom[1].lineLimit = _geometry_w*limit; geom[2].lineLimit = _geometry_w*limit; _geometry_h = limit; } } 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; int width = (!high_res ? 320 : 640); int height = (!high_res ? 240 : 480); pCls = noGAPI_Cls; pBlt = noGAPI_Blt; pBlt_part = noGAPI_Blt_part; pSet_565 = noGAPI_Set_565; toolbar_available = 1; hdc = GetDC(hWndMain); noGAPI_compat = CreateCompatibleDC(hdc); ReleaseDC(hWndMain, hdc); #ifndef NEW_GAPI_CODE // Init GDI noGAPI_video_buffer = (UBYTE*)malloc(320 * 240 * 2); #else memset(&noGAPI_bitmap_header, 0, sizeof(BITMAPINFOHEADER)); noGAPI_bitmap_header.biSize = sizeof(BITMAPINFOHEADER); noGAPI_bitmap_header.biWidth = GetSystemMetrics(SM_CXSCREEN); noGAPI_bitmap_header.biHeight = -GetSystemMetrics(SM_CYSCREEN); /* origin = top */ noGAPI_bitmap_header.biPlanes = 1; noGAPI_bitmap_header.biBitCount = 24; noGAPI_bitmap_header.biCompression = BI_RGB; /* paletted fixme Jornada 820 ? */ noGAPI_bitmap = CreateDIBSection(noGAPI_compat, (BITMAPINFO*)&noGAPI_bitmap_header, DIB_RGB_COLORS, (void**)&noGAPI_buffer, NULL, 0); if (!noGAPI_bitmap) exit(1); SelectObject(noGAPI_compat, noGAPI_bitmap); #endif _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<<gxdp.cBPP)-1; colorscale = gxdp.cBPP < 8 ? 8-gxdp.cBPP : 0; if(gxdp.cBPP >= 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; extra_wide_screen = GetSystemMetrics(SM_CYSCREEN) >= 480; 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; i<limit; i++) { /* Manhattan distance for now. Not the best but rather fast */ d = abs(r-palRed[i])+abs(g-palGreen[i])+abs(b-palBlue[i]); if(d < distance) { distance = d; best = i; } } return (UBYTE)best; } void palette_update() { if(gxdp.ffFormat & kfPalette) { LOGPALETTE* ple = (LOGPALETTE*)malloc(sizeof(LOGPALETTE)+sizeof(PALETTEENTRY)*255); ple->palVersion = 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) { int i; 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<geom[0].height*gxdp.cBPP/8; y++) { dst = scraddr+geom[0].startoffset; for(x=0; x<geom[0].width; x++) { *dst = fillcolor; dst += pixelstep; } scraddr += linestep; } dynamicGXEndDraw(); } } void palette_Cls() { int x, y; UBYTE* dst; UBYTE *scraddr; scraddr = (UBYTE*)dynamicGXBeginDraw(); if(scraddr) { for(y=0; y<geom[useMode].height; y++) { dst = scraddr+geom[useMode].startoffset; for(x=0; x<geom[useMode].width; x++) { *dst = 0; dst += geom[useMode].pixelstep; } scraddr += geom[useMode].linestep; } dynamicGXEndDraw(); } } void hicolor_Cls() { int x, y; UBYTE* dst; UBYTE *scraddr; scraddr = (UBYTE*)dynamicGXBeginDraw(); if(scraddr) { for(y=0; y<geom[useMode].height; y++) { dst = scraddr+geom[useMode].startoffset; for(x=0; x<geom[useMode].width; x++) { *(unsigned short*)dst = 0; dst += geom[useMode].pixelstep; } scraddr += geom[useMode].linestep; } dynamicGXEndDraw(); } } void Cls() { pCls(); } int counter = 0; void drawSoundItem(int x, int y) { if (!sound_activated) pBlt_part(image_expand(item_soundOn), x, y, 32, 32, item_soundOn_colors, 0); else pBlt_part(image_expand(item_soundOff), x, y, 32, 32, item_soundOff_colors, 0); } void drawError(char *error) { FILE *file_error; file_error=fopen("scummvm_error.txt", "w"); if (file_error) { fprintf(file_error, "%s\n", error); fclose(file_error); } int current_y = 80; Cls(); pBlt_part(image_expand(item_toolbar), 0, 0, 320, 40, item_toolbar_colors, 0); pBlt_part(image_expand(item_bomb), 0, 0, 64, 67, item_bomb_colors, 0); memset(decomp, 0, sizeof(decomp)); current_y = drawString("SCUMMVM ERROR !", 10, current_y, 2, 1); current_y += 10; current_y = drawString(error, 10, current_y, 8, 1); current_y += 10; current_y = drawString("Exiting in 10 seconds", 10, current_y, 8, 1); Sleep(10 * 1000); } void drawWait() { pBlt_part(image_expand(item_toolbar), 0, 0, 320, 40, item_toolbar_colors, 0); pBlt_part(image_expand(item_loading), 28, 10, 100, 25, item_loading_colors, 0); } void setGameSelectionPalette() { int i; if (_gfx_option != VIDEO_PALETTED) return; for (i=0; i<item_startup_colors_size; i++) SetPalEntry(i, item_startup_colors[3 * i], item_startup_colors[(3 * i) + 1], item_startup_colors[(3 * i) + 2]); palette_update(); } void drawBlankGameSelection() { //int i; image_expand(item_startup); /* Store empty comment */ memcpy(comment_zone, decomp + (206 * 220), 8 * 220); pBlt_part(decomp, _game_selection_X_offset, _game_selection_Y_offset, 220, 250, item_startup_colors, 0); } void drawVideoDevice() { char info[100]; sprintf(info, "Video device : %s %s - CVS %s PPC %s", gfx_device_name[_gfx_device], gfx_device_options_name[_gfx_option], gScummVMVersion, getBuildDate()); drawString(info, 10, 0, 2, 1); /* printString(video_device, 10, 270, 2, 0); pBlt_part(decomp + (270 * 220), 0, 5, 220, 8, item_startup_colors, 1); */ } void drawCommentString(char *comment) { /* Erase old comment */ memcpy(decomp + (206 * 220), comment_zone, 8 * 220); /* Draw new comment */ printString(comment, 24, 206, 2); pBlt_part(decomp + (206 * 220), _game_selection_X_offset, _game_selection_Y_offset + 206, 220, 8, item_startup_colors, 0); } void drawStandardString(char *game, int index) { printString(game, 24, 70 + (15 * index), 2); //pBlt_part(decomp, GAME_SELECTION_X_OFFSET + 24, GAME_SELECTION_Y_OFFSET + 70 + (12 * index), 220, 8, item_startup_colors); pBlt_part(decomp + ((70 + (15 * index)) * 220), _game_selection_X_offset, _game_selection_Y_offset + 70 + (15 * index), 220, 8, item_startup_colors, 0); } void drawHighlightedString(char *game, int index) { /* Replace former highlighted string */ if (_highlighted_index != -1) { memcpy(decomp + ((70 + (15 * _highlighted_index)) * 220), highlighted_zone, 8 * 220); pBlt_part(decomp + ((70 + (15 * _highlighted_index)) * 220), _game_selection_X_offset, _game_selection_Y_offset + 70 + (15 * _highlighted_index), 220, 8, item_startup_colors, 0); } /* Save non highlighted string */ _highlighted_index = index; memcpy(highlighted_zone, decomp + ((70 + (15 * index)) * 220), 8 * 220); /* Draw new highlighted string */ printString(game, 24, 70 + (15 * index), 2, 3); pBlt_part(decomp + ((70 + (15 * index)) * 220), _game_selection_X_offset, _game_selection_Y_offset + 70 + (15 * index), 220, 8, item_startup_colors, 0); } void resetLastHighlighted() { _highlighted_index = -1; } void reducePortraitGeometry() { if (_gfx_mode_switch) memcpy(&geom[0], &portrait_geometry, sizeof(tScreenGeometry)); } void drawAllToolbar() { int x,y; int start_offset; if (high_res && wide_screen) start_offset = 440; else start_offset = 200; if (currentScreenMode || wide_screen) { if (draw_keyboard) { pBlt_part(image_expand(item_keyboard), 0, start_offset, 320, 40, item_keyboard_colors, 0); } else { pBlt_part(image_expand(item_toolbar), 0, start_offset, 320, 40, item_toolbar_colors, 0); x = 10; y = start_offset + 4; if (!is_simon) pBlt_part(image_expand(item_disk), x, y, 32, 32, item_disk_colors, 0); x += 40; pBlt_part(image_expand(item_skip), x, y, 32, 32, item_skip_colors, 0); x += 40; drawSoundItem(x, y); if (_gfx_mode_switch && !high_res) { x += 40; pBlt_part(image_expand(item_monkeyPortrait), x, y, 32, 32, item_monkeyPortrait_colors, 0); } } } else { if (draw_keyboard) { pBlt_part(image_expand(item_keyboardPortrait), 0, 240, 320, 80, item_keyboardPortrait_colors, 0); } else { pBlt_part(image_expand(item_toolbarPortrait), 0, 240, 320, 80, item_toolbarPortrait_colors, 0); /*drawToolbarItem(item_toolbarPortrait_colors, item_toolbarPortrait, 0, 240, 240, 80);*/ x = 10; y = 240; pBlt_part(image_expand(item_disk), x, y, 32, 32, item_disk_colors, 0); x += 40; pBlt_part(image_expand(item_skip), x, y, 32, 32, item_skip_colors, 0); x += 40; drawSoundItem(x, y); if (_gfx_mode_switch && !high_res) { x += 40; pBlt_part(image_expand(item_monkeyLandscape), x, y, 32, 32, item_monkeyLandscape_colors, 0); } } } toolbar_drawn = true; } void redrawSoundItem() { drawSoundItem(10 + 40 + 40, (currentScreenMode || wide_screen ? 204 : 240)); } bool isInBox(int x, int y, int x1, int y1, int x2, int y2) { return ((x >= x1 && y >= y1) && (x <= x2 && y <= y2)); } ToolbarSelected getToolbarSelection (int x, int y) { int test_x, test_y; int offset = 1; /* if (!currentScreenMode) return ToolbarNone; */ if (!high_res && !(x >= 10 && y >= 204)) return ToolbarNone; if (high_res && !(x >= 10 && y >= 444)) return ToolbarNone; if (!high_res) test_y = (currentScreenMode || wide_screen ? 204 : 240); else test_y = 444; if (high_res && !wide_screen) offset = 2; test_x = (10 * offset); if (isInBox(x, y, test_x, test_y, test_x + (32 * offset), test_y + (32 * offset))) return ToolbarSaveLoad; test_x += (40 * offset); if (isInBox(x, y, test_x, test_y, test_x + (32 * offset), test_y + (32 * offset))) return ToolbarSkip; test_x += (40 * offset); if (isInBox(x, y, test_x, test_y, test_x + (32 * offset), test_y + (32 * offset))) return ToolbarSound; if (_gfx_mode_switch && !high_res) { test_x += (40 * offset); if (isInBox(x, y, test_x, test_y, test_x + (32 * offset), test_y + (32 * offset))) 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(); if (y > _geometry_h) return; if (y + height > _geometry_h) height = _geometry_h - y; 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)-1; \ address += step; \ } \ else \ bitmask <<= gxdp.cBPP; #define ADVANCE_REV_PARTIAL(address, step) \ bitshift -= gxdp.cBPP; \ if(bitshift < 0) \ { \ bitshift = 8-gxdp.cBPP; \ bitmask = ((1<<gxdp.cBPP)-1)<<bitshift; \ address += step; \ } \ else \ bitmask >>= 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<<gxdp.cBPP)-1; if(scraddr) { int lines = 0; int current = 0; scraddr += geom[useMode].startoffset; scraddr += y * linestep; while(lines != height) { int i; current = 0; dst = scraddr; /* skip non updated pixels for this line */ for (i=0; i < x; i++) dst += pixelstep; /* Turtle warning !!! */ for (i=0; i<width; i++) { if (skipmask == 0xffffffff || (long)i & skipmask) { *dst = ((*dst)&~bitmask)|(COLORCONVMONO( RED_FROM_565(*(buffer + i)), GREEN_FROM_565(*(buffer + i)), BLUE_FROM_565(*(buffer + i))) << bitshift); dst += pixelstep; } } ADVANCE_PARTIAL(scraddr, linestep); buffer += pitch; lines++; } } dynamicGXEndDraw(); } void mono_Blt(UBYTE *src_ptr) { mono_Blt_part(src_ptr, 0, 0, _geometry_w, _geometry_h, NULL, 0); } void mono_Blt_part(UBYTE * scr_ptr, int x, int y, int width, int height, UBYTE * own_palette, int pitch) { // Mono blit routines contain good deal of voodoo static UBYTE *src; static UBYTE *dst; static UBYTE *scraddr; static UBYTE *scr_ptr_limit; static UBYTE *src_limit; static long pixelstep; static long linestep; static long skipmask; // Special code is used to deal with packed pixels in monochrome mode static UBYTE bitmask; static int bitshift; if(!active) { Sleep(100); return; } /* Update screen mode, also thread protection by doing this */ if(useMode != currentScreenMode) { useMode = currentScreenMode; pCls(); } pixelstep = geom[useMode].pixelstep; linestep = geom[useMode].linestep; skipmask = geom[useMode].xSkipMask; scraddr = (UBYTE*)dynamicGXBeginDraw(); if(pixelstep) { // this will work on mono iPAQ and @migo, don't know about any others linestep = (pixelstep > 0) ? -1 : 1; bitshift = 0; bitmask = (1<<gxdp.cBPP)-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 (scr_ptr_limit > scr_ptr + geom[useMode].lineLimit) scr_ptr_limit = scr_ptr + geom[useMode].lineLimit; */ /* CMI rendering */ if (high_res && !own_palette && !extra_wide_screen) { 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) { *dst = ((*dst)&~bitmask)|(pal[*src]<<bitshift); dst += pixelstep; src +=2; } ADVANCE_PARTIAL(scraddr, linestep); scr_ptr += (pitch ? 2 * pitch : 2 * width); src_limit += (pitch ? 2 * pitch : 2 * width); } } else /* Internal pixel loops */ if(skipmask == 3 && (smooth_filter) && gxdp.cBPP >= 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)<<bitshift); 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; } *dst = (*dst & ~bitmask) | (COLORCONVMONO(r,g,b)<<bitshift); 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; } *dst = (*dst & ~bitmask) | (COLORCONVMONO(r,g,b)<<bitshift); dst += pixelstep; src += 4; } ADVANCE_PARTIAL(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) *dst = ((*dst)&~bitmask)|(pal[*src]<<bitshift); else *dst = ((*dst)&~bitmask)|(COLORCONVMONO( own_palette[3 * *src], own_palette[(3 * *src) + 1], own_palette[(3 * *src) + 2]) << bitshift); dst += pixelstep; } src ++; } ADVANCE_PARTIAL(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) *dst = ((*dst)&~bitmask)|(pal[*src]<<bitshift); else *dst = ((*dst)&~bitmask)|(COLORCONVMONO( own_palette[3 * *src], own_palette[(3 * *src) + 1], own_palette[(3 * *src) + 2]) << bitshift); dst += pixelstep; src ++; } ADVANCE_PARTIAL(scraddr, linestep); scr_ptr += (pitch ? pitch : width); src_limit += (pitch ? pitch : width); } } } } else { // Filtering is not implemented in this mode. Not needed by current devices anyway pixelstep = (linestep > 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 (scr_ptr_limit > scr_ptr + geom[useMode].lineLimit) scr_ptr_limit = scr_ptr + geom[useMode].lineLimit; /* CMI rendering */ if (high_res && !own_palette && !extra_wide_screen) { if(pixelstep > 0) { bitshift = 8-gxdp.cBPP; bitmask = ((1<<gxdp.cBPP)-1)<<bitshift; while(scr_ptr < scr_ptr_limit) { int i; src = scr_ptr; dst = scraddr; dst -= (linestep-pixelstep); /* skip non updated pixels for this line */ for (i=0; i < x; i++) ADVANCE_REV_PARTIAL(dst, pixelstep); while(src < src_limit) { *dst = ((*dst)&~bitmask)|(pal[*src]<<bitshift); ADVANCE_REV_PARTIAL(dst, pixelstep); src += 2; } scraddr += linestep; scr_ptr += (pitch ? 2 * pitch : 2 * width); src_limit += (pitch ? 2 * pitch : 2 * width); } } else { bitshift = 0; bitmask = (1<<gxdp.cBPP)-1; 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++) ADVANCE_PARTIAL(dst, pixelstep); while(src < src_limit) { *dst = ((*dst)&~bitmask)|(pal[*src]<<bitshift); ADVANCE_PARTIAL(dst, pixelstep); src += 2; } scraddr += linestep; scr_ptr += (pitch ? 2 * pitch : 2 * width); src_limit += (pitch ? 2 * pitch : 2 * width); } } } else if(skipmask != 0xffffffff) { if(pixelstep > 0) { bitshift = 8-gxdp.cBPP; bitmask = ((1<<gxdp.cBPP)-1)<<bitshift; while(scr_ptr < scr_ptr_limit) { int i; src = scr_ptr; dst = scraddr; dst -= (linestep-pixelstep); /* skip non updated pixels for this line */ for (i=0; i < x; i++) ADVANCE_REV_PARTIAL(dst, pixelstep); while(src < src_limit) { if((long)src & skipmask) { if (!own_palette) *dst = ((*dst)&~bitmask)|(pal[*src]<<bitshift); else *dst = ((*dst)&~bitmask)|(COLORCONVMONO( own_palette[3 * *src], own_palette[(3 * *src) + 1], own_palette[(3 * *src) + 2]) << bitshift); ADVANCE_REV_PARTIAL(dst, pixelstep); } src ++; } scraddr += linestep; scr_ptr += (pitch ? pitch : width); src_limit += (pitch ? pitch : width); } } else { bitshift = 0; bitmask = (1<<gxdp.cBPP)-1; 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++) ADVANCE_PARTIAL(dst, pixelstep); while(src < src_limit) { if((long)src & skipmask) { if (!own_palette) *dst = ((*dst)&~bitmask)|(pal[*src]<<bitshift); else *dst = ((*dst)&~bitmask)|(COLORCONVMONO( own_palette[3 * *src], own_palette[(3 * *src) + 1], own_palette[(3 * *src) + 2]) << bitshift); ADVANCE_PARTIAL(dst, pixelstep); } src ++; } scraddr += linestep; scr_ptr += (pitch ? pitch : width); src_limit += (pitch ? pitch : width); } } } else { if(pixelstep > 0) { bitshift = 8-gxdp.cBPP; bitmask = ((1<<gxdp.cBPP)-1)<<bitshift; while(scr_ptr < scr_ptr_limit) { int i; src = scr_ptr; dst = scraddr; dst -= (linestep-pixelstep); /* skip non updated pixels for this line */ for (i=0; i < x; i++) ADVANCE_REV_PARTIAL(dst, pixelstep); while(src < src_limit) { if (!own_palette) *dst = ((*dst)&~bitmask)|(pal[*src]<<bitshift); else *dst = ((*dst)&~bitmask)|(COLORCONVMONO( own_palette[3 * *src], own_palette[(3 * *src) + 1], own_palette[(3 * *src) + 2]) << bitshift); ADVANCE_REV_PARTIAL(dst, pixelstep); src ++; } scraddr += linestep; scr_ptr += (pitch ? pitch : width); src_limit += (pitch ? pitch : width); } } else { bitshift = 0; bitmask = (1<<gxdp.cBPP)-1; 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++) ADVANCE_PARTIAL(dst, pixelstep); while(src < src_limit) { if (!own_palette) *dst = ((*dst)&~bitmask)|(pal[*src]<<bitshift); else *dst = ((*dst)&~bitmask)|(COLORCONVMONO( own_palette[3 * *src], own_palette[(3 * *src) + 1], own_palette[(3 * *src) + 2]) << bitshift); ADVANCE_PARTIAL(dst, pixelstep); src ++; } scraddr += linestep; scr_ptr += (pitch ? pitch : width); src_limit += (pitch ? pitch : width); } } } } } dynamicGXEndDraw(); } /* *************************** PALETTED DISPLAY ********************************* */ void palette_Set_565(INT16 *buffer_param, 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; static unsigned char *color_match_2; static UINT16 *buffer; buffer = (UINT16*)buffer_param; scraddr = (UBYTE*)dynamicGXBeginDraw(); pixelstep = geom[useMode].pixelstep; linestep = geom[useMode].linestep; skipmask = geom[useMode].xSkipMask; color_match_2 = (unsigned char*)malloc(0xffff); if (color_match_2) memset(color_match_2, 0xff, 0xffff); if(scraddr) { int lines = 0; int current = 0; scraddr += geom[useMode].startoffset; scraddr += y * linestep; while(lines != height) { int i; current = 0; dst = scraddr; /* skip non updated pixels for this line */ for (i=0; i < x; i++) dst += pixelstep; /* Turtle warning !!! */ for (i=0; i<width; i++) { if (skipmask == 0xffffffff || (long)i & skipmask) { if (color_match_2) { if (color_match_2[*(buffer + i)] == 255) color_match_2[*(buffer + i)] = best_match( RED_FROM_565(*(buffer + i)), GREEN_FROM_565(*(buffer + i)), BLUE_FROM_565(*(buffer + i)), 236) + 10; *dst = color_match_2[*(buffer + i)]; } else { *dst = best_match( RED_FROM_565(*(buffer + i)), GREEN_FROM_565(*(buffer + i)), BLUE_FROM_565(*(buffer + i)), 236) + 10; } dst += pixelstep; } } buffer += pitch; scraddr += linestep; lines++; } } if (color_match_2) free(color_match_2); dynamicGXEndDraw(); } void palette_Blt(UBYTE *src_ptr) { palette_Blt_part(src_ptr, 0, 0, _geometry_w, _geometry_h, NULL, 0); } void palette_Blt_part(UBYTE * scr_ptr,int x, int y, int width, int height, UBYTE * own_palette, int pitch) { static UBYTE *src; static UBYTE *dst; static UBYTE *scraddr; static UBYTE *scr_ptr_limit; static UBYTE *src_limit; static long pixelstep; static long linestep; static long skipmask; // Special code is used to deal with packed pixels in monochrome mode static UBYTE bitmask; static int bitshift; if(!active) { Sleep(100); return; } /* Update screen mode, also thread protection by doing this */ if(useMode != currentScreenMode) { useMode = currentScreenMode; pCls(); } pixelstep = geom[useMode].pixelstep; linestep = geom[useMode].linestep; skipmask = geom[useMode].xSkipMask; scraddr = (UBYTE*)dynamicGXBeginDraw(); 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 (scr_ptr_limit > scr_ptr + geom[useMode].lineLimit) scr_ptr_limit = scr_ptr + geom[useMode].lineLimit; */ /* CMI rendering */ if (high_res && !own_palette && !extra_wide_screen) { 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 (*src < 236) *dst = *src + 10; else *dst = staticTranslate[*src-236]; dst += pixelstep; src += 2; } scraddr += linestep; scr_ptr += (pitch ? 2 * pitch : 2 * width); src_limit += (pitch ? 2 * pitch : 2 * width); } } else /* Internal pixel loops */ 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) { if (*src < 236) *dst = *src + 10; else *dst = staticTranslate[*src-236]; } else { // Turtle warning !!! if (color_match[*src] == 255) color_match[*src] = best_match(own_palette[(3 * *src)], own_palette[(3 * *src) + 1], own_palette[(3 * *src) + 2], 236) + 10; *dst = color_match[*src]; } 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) { if (*src < 236) *dst = *src + 10; else *dst = staticTranslate[*src-236]; } else { // Turtle warning !!! if (color_match[*src] == 255) color_match[*src] = best_match(own_palette[(3 * *src)], own_palette[(3 * *src) + 1], own_palette[(3 * *src) + 2], 236) + 10; *dst = color_match[*src]; } dst += pixelstep; src ++; } scraddr += linestep; scr_ptr += (pitch ? pitch : width); src_limit += (pitch ? pitch : width); } } dynamicGXEndDraw(); } } /* ********************************* 555 DISPLAY ********************************* */ void hicolor555_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; while(lines != height) { int i; current = 0; dst = scraddr; /* skip non updated pixels for this line */ for (i=0; i < x; i++) dst += pixelstep; /* Turtle warning !!! */ for (i=0; i<width; i++) { if (skipmask == 0xffffffff || (long)i & skipmask) { *(unsigned short*)dst = COLORCONV555( RED_FROM_565(*(buffer + i)), GREEN_FROM_565(*(buffer + i)), BLUE_FROM_565(*(buffer + i)) ); dst += pixelstep; } } buffer += pitch; scraddr += linestep; lines++; } } dynamicGXEndDraw(); } void hicolor555_Blt(UBYTE *src_ptr) { hicolor555_Blt_part(src_ptr, 0, 0, _geometry_w, _geometry_h, NULL, 0); } void hicolor555_Blt_part(UBYTE * scr_ptr,int x, int y, int width, int height, UBYTE * own_palette, int pitch) { static UBYTE *src; static UBYTE *dst; static UBYTE *scraddr; static UBYTE *scr_ptr_limit; static UBYTE *src_limit; static long pixelstep; static long linestep; static long skipmask; if(!active) { Sleep(100); return; } /* Update screen mode, also thread protection by doing this */ if(useMode != currentScreenMode) { useMode = currentScreenMode; pCls(); } pixelstep = geom[useMode].pixelstep; linestep = geom[useMode].linestep; skipmask = geom[useMode].xSkipMask; scraddr = (UBYTE*)dynamicGXBeginDraw(); 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; /* if (scr_ptr_limit > scr_ptr + geom[useMode].lineLimit) scr_ptr_limit = scr_ptr + geom[useMode].lineLimit; */ src_limit = scr_ptr + width; /* CMI rendering */ if (high_res && !own_palette && !extra_wide_screen) { 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; 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; *(unsigned short*)dst = COLORCONV555(r,g,b); dst += pixelstep; src += 2; } scraddr += linestep; scr_ptr += (pitch ? 2 * pitch : 2 * width); src_limit += (pitch ? 2 * pitch : 2 * width); } } 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 = 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<width; i+=3) { register UBYTE r,g,b; register currentRed = RED_FROM_565(buffer[i]); register currentGreen = GREEN_FROM_565(buffer[i]); register currentBlue = BLUE_FROM_565(buffer[i]); register currentRed1 = RED_FROM_565(buffer[i+1]); register currentGreen1 = GREEN_FROM_565(buffer[i+1]); register currentBlue1 = BLUE_FROM_565(buffer[i+1]); register currentRed2 = RED_FROM_565(buffer[i+2]); register currentGreen2 = GREEN_FROM_565(buffer[i+2]); register currentBlue2 = BLUE_FROM_565(buffer[i+2]); r = (3 * currentRed + currentRed1)>>2; g = (3 * currentGreen + currentGreen1)>>2; b = (3 * currentBlue + currentBlue1)>>2; *(unsigned short*)dst = COLORCONV565(r, g, b); dst += pixelstep; r = (currentRed1 + currentRed2)>>1; g = (currentGreen1 + currentGreen2)>>1; b = (currentBlue1 + currentBlue2)>>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<width; i++) { if (skipmask == 0xffffffff || (long)i & skipmask) { *(unsigned short*)dst = buffer[i]; dst += pixelstep; } } //memcpy(dst, buffer, width * 2); buffer += pitch; scraddr += linestep; lines++; } } } dynamicGXEndDraw(); } int getColor565 (int color) { return COLORCONV565(palRed[color], palGreen[color], palBlue[color]); } void hicolor565_Blt_part(UBYTE * scr_ptr, int x, int y, int width, int height, UBYTE * own_palette, int pitch) { static UBYTE *src; static UBYTE *dst; static UBYTE *scraddr; static UBYTE *scr_ptr_limit; static UBYTE *src_limit; static long pixelstep; static long linestep; static long skipmask; if(!active) { Sleep(100); return; } /* Update screen mode, also thread protection by doing this */ if(useMode != currentScreenMode) { useMode = currentScreenMode; pCls(); } pixelstep = geom[useMode].pixelstep; linestep = geom[useMode].linestep; skipmask = geom[useMode].xSkipMask; scraddr = (UBYTE*)dynamicGXBeginDraw(); 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; /* if (scr_ptr_limit > scr_ptr + geom[useMode].lineLimit) scr_ptr_limit = scr_ptr + geom[useMode].lineLimit; */ src_limit = scr_ptr + width; /* CMI rendering */ if (high_res && !own_palette && !extra_wide_screen) { 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; 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; *(unsigned short*)dst = COLORCONV565(r,g,b); dst += pixelstep; src += 2; } scraddr += linestep; scr_ptr += (pitch ? 2 * pitch : 2 * width); src_limit += (pitch ? 2 * pitch : 2 * width); } } else /* Special Smartphone implementation */ /* Landscape mode, 2/3 X, 7/8 Y */ if (smartphone && own_palette) { 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 += x * pixelstep; while(src < src_limit) { UBYTE r, g, b; register first = 3 * *(src + 0); register second = 3 * *(src + 1); register third = 3 * *(src + 2); 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; r = (own_palette[second] + own_palette[third]) >> 1; g = (own_palette[second + 1] + own_palette[third + 1]) >> 1; b = (own_palette[second + 2] + own_palette[third + 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 if (smartphone && !own_palette) { 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 += x * pixelstep; while(src < src_limit) { UBYTE r, g, b; register first = *(src + 0); register second = *(src + 1); register third = *(src + 2); r = (3*palRed[first] + palRed[second])>>2; g = (3*palGreen[first] + palGreen[second])>>2; b = (3*palBlue[first] + palBlue[second])>>2; *(unsigned short*)dst = COLORCONV565(r,g,b); dst += pixelstep; r = (palRed[second] + palRed[third])>>1; g = (palGreen[second] + palGreen[third])>>1; b = (palBlue[second] + palBlue[third])>>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 ********************************* */ #ifndef NEW_GAPI_CODE 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<width; i++) { for (j=0; j<height; j++) { work_buffer_2[i * height + j] = buffer[(pitch ? pitch : width) * j + (width - i)]; } } } else { for (i=0; i<height; i++) { for (j=0; j<width; j++) { *(unsigned short*)work_buffer = buffer[(pitch ? pitch : width) * i + j]; work_buffer += 2; } } } if (currentScreenMode && !wide_screen) hb = CreateBitmap(height, width, 1, 16, noGAPI_video_buffer); else hb = CreateBitmap(width, height, 1, 16, noGAPI_video_buffer); old = (HBITMAP)SelectObject(noGAPI_compat, hb); if (currentScreenMode && !wide_screen) BitBlt(hdc, y , 320 - (x + width), height, width, noGAPI_compat, 0, 0, SRCCOPY); else BitBlt(hdc, x, y, width, height, noGAPI_compat, 0, 0, SRCCOPY); SelectObject(noGAPI_compat, old); ReleaseDC(hWndMain, hdc); DeleteObject(hb); } void noGAPI_Blt_part(UBYTE * scr_ptr, int x, int y, int width, int height, UBYTE * own_palette, int pitch) { 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; if (currentScreenMode && !wide_screen) { unsigned short *work_buffer_2 = (unsigned short*)work_buffer; for (i=0; i<width; i++) for (j=0; j<height; j++) if (!own_palette) work_buffer_2[i * height + j] = pal[scr_ptr[(pitch ? pitch : width) * j + (width - i)]]; else work_buffer_2[i * height + j] = COLORCONV565(own_palette[3 * scr_ptr[(pitch ? pitch : width) * j + (width - i)]], own_palette[(3 * scr_ptr[(pitch ? pitch : width) * j + (width - i)]) + 1], own_palette[(3 * scr_ptr[(pitch ? pitch : width) * j + (width - i)]) + 2]); } else { for (i=0; i<height; i++) { for (j=0; j<width; j++) { if (!own_palette) *(unsigned short*)work_buffer = pal[scr_ptr[(pitch ? pitch : width) * i + j]]; else *(unsigned short*)work_buffer = COLORCONV565(own_palette[3 * scr_ptr[(pitch ? pitch : width) * i + j]], own_palette[(3 * scr_ptr[(pitch ? pitch : width) * i + j]) + 1], own_palette[(3 * scr_ptr[(pitch ? pitch : width) * i + j]) + 2]); work_buffer += 2; } } } if (currentScreenMode && !wide_screen) hb = CreateBitmap(height, width, 1, 16, noGAPI_video_buffer); else hb = CreateBitmap(width, height, 1, 16, noGAPI_video_buffer); old = (HBITMAP)SelectObject(noGAPI_compat, hb); if (currentScreenMode && !wide_screen) BitBlt(hdc, y , 320 - (x + width), height, width, noGAPI_compat, 0, 0, SRCCOPY); else BitBlt(hdc, x, y, width, height, noGAPI_compat, 0, 0, SRCCOPY); SelectObject(noGAPI_compat, old); ReleaseDC(hWndMain, hdc); DeleteObject(hb); } #else void noGAPI_Cls() { HBITMAP old; RECT rc; HDC hdc = GetDC(hWndMain); HBITMAP hb; memset(noGAPI_buffer, 0x00, GetSystemMetrics(SM_CXSCREEN) * GetSystemMetrics(SM_CYSCREEN) * 3); BitBlt(hdc, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN), noGAPI_compat, 0, 0, SRCCOPY); ReleaseDC(hWndMain, hdc); } 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 *workBuffer = noGAPI_buffer; INT16 *srcBuffer = buffer; UBYTE *tempBuffer; INT16 *tempSrcBuffer; int i; int j; int startOffset; int lineStep; int pixelStep; if (currentScreenMode && !wide_screen) { startOffset = (GetSystemMetrics(SM_CXSCREEN) * (GetSystemMetrics(SM_CYSCREEN) - 1)) * 3; lineStep = 3; pixelStep = -(GetSystemMetrics(SM_CXSCREEN) * 3); } else { startOffset = 0; lineStep = GetSystemMetrics(SM_CXSCREEN) * 3; pixelStep = 3; } workBuffer += startOffset; workBuffer += y * lineStep; for (i=0; i<height; i++) { tempBuffer = workBuffer; tempSrcBuffer = srcBuffer; tempBuffer += x * pixelStep; for (j=0; j<width; j++) { *tempBuffer = BLUE_FROM_565(*tempSrcBuffer); *(tempBuffer + 1) = GREEN_FROM_565(*tempSrcBuffer); *(tempBuffer + 2) = RED_FROM_565(*tempSrcBuffer); tempBuffer += pixelStep; tempSrcBuffer++; } workBuffer += lineStep; srcBuffer += (pitch ? pitch : width); } if (currentScreenMode && !wide_screen) BitBlt(hdc, y , 320 - (x + width), height, width, noGAPI_compat, y, 320 - (x + width), SRCCOPY); else BitBlt(hdc, x, y, width, height, noGAPI_compat, x, y, SRCCOPY); ReleaseDC(hWndMain, hdc); } void noGAPI_Blt_part(UBYTE * scr_ptr, int x, int y, int width, int height, UBYTE * own_palette, int pitch) { HDC hdc = GetDC(hWndMain); HBITMAP hb; UBYTE *workBuffer = noGAPI_buffer; UBYTE *srcBuffer = scr_ptr; UBYTE *tempBuffer; UBYTE *tempSrcBuffer; int i; int j; //long skipmask; int startOffset; int lineStep; int pixelStep; if (currentScreenMode && !wide_screen) { startOffset = (GetSystemMetrics(SM_CXSCREEN) * (GetSystemMetrics(SM_CYSCREEN) - 1)) * 3; lineStep = 3; pixelStep = -(GetSystemMetrics(SM_CXSCREEN) * 3); } else { startOffset = 0; lineStep = GetSystemMetrics(SM_CXSCREEN) * 3; pixelStep = 3; } if (high_res && !extra_wide_screen) { height /= 2; width /= 2; } workBuffer += startOffset; workBuffer += y * lineStep; for (i=0; i<height; i++) { tempBuffer = workBuffer; tempSrcBuffer = srcBuffer; tempBuffer += x * pixelStep; for (j=0; j<width; j++) { if (!own_palette) { if (high_res && !extra_wide_screen) { *tempBuffer = (3*palBlue[*tempSrcBuffer] + palBlue[*(tempSrcBuffer + 1)]) >> 2; *(tempBuffer + 1) = (3 * palGreen[*tempSrcBuffer] + palGreen[(*tempSrcBuffer + 1)]) >> 2; *(tempBuffer + 2) = (3 * palRed[*tempSrcBuffer] + palRed[*(tempSrcBuffer + 1)]) >> 2; tempBuffer += pixelStep; tempSrcBuffer += 2; } else { *tempBuffer = palBlue[*tempSrcBuffer]; *(tempBuffer + 1) = palGreen[*tempSrcBuffer]; *(tempBuffer + 2) = palRed[*tempSrcBuffer]; tempBuffer += pixelStep; tempSrcBuffer++; } } else { *tempBuffer = own_palette[3 * *tempSrcBuffer + 2]; *(tempBuffer + 1) = own_palette[3 * *tempSrcBuffer + 1]; *(tempBuffer + 2) = own_palette[3 * *tempSrcBuffer]; tempBuffer += pixelStep; tempSrcBuffer++; } } workBuffer += lineStep; if (high_res && !extra_wide_screen) srcBuffer += (pitch ? 2 * pitch : 2 * width); else srcBuffer += (pitch ? pitch : width); } if (currentScreenMode && !wide_screen) BitBlt(hdc, y , 320 - (x + width), height, width, noGAPI_compat, y, 320 - (x + width), SRCCOPY); else BitBlt(hdc, x, y, width, height, noGAPI_compat, x, y, SRCCOPY); ReleaseDC(hWndMain, hdc); } #endif /* ************************** STYLUS TRANSLATION ************************* */ void Translate(int* px, int* py) { int x, y; if ((wide_screen && !high_res) || (wide_screen && extra_wide_screen && high_res)) return; if (wide_screen && high_res) { if (!g_gui->isActive()) { *px = x * 2; *py = y * 2; } else { *px = x; *py = y; } return; } if (high_res) { x = 320 - *py; y = *px; if (!g_gui->isActive()) { *px = x * 2; *py = y * 2; } else { *px = x; *py = y; } return; } switch(currentScreenMode) { case 0: /* portrait */ *px = *px*4/3; break; case 1: /* landscape left */ x = 320 - *py; y = *px; *px = x; *py = y; break; case 2: /* landscape right */ x = *py; y = 240 - *px; *px = x; *py = y; break; } } /* ************************** LAUNCHER FONT STUFF ************************* */ void printChar(const char str, int xx, int yy, int textcolor, int highlight, int width) { unsigned int buffer = 0, mask = 0, x, y; byte *tmp; byte *ptr; tmp = &textfont[0]; tmp += 224 + (str + 1) * 8; ptr = decomp + (yy * width) + xx; for (y = 0; y < 8; y++) { for (x = 0; x < 8; x++) { unsigned char color; if ((mask >>= 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<width; i++) ptr[x] = highlight; } ptr += width; } } void printString(const char *str, int x, int y, int textcolor, int highlight, int width) { for (uint letter = 0; letter < strlen(str); letter++) printChar(str[letter], x + (letter * 8), y, textcolor, highlight, width); } #define MAX_CHARS_PER_LINE 29 int drawString(const char *str, int x, int y, int textcolor, int highlight) { int current_y; unsigned int current_pos = 0; char substring[MAX_CHARS_PER_LINE + 1]; current_y = y; while(current_pos < strlen(str)) { memset(substring, 0, sizeof(substring)); if (strlen(str + current_pos) > 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 if (!(high_res && !wide_screen)) { for (i=0; i<height; i++) { for (j=0; j<width; j++) { *buffer++ = COLORCONV565(palRed[*src], palGreen[*src], palBlue[*src]); src++; } } } else { UBYTE *current; for (i=0; i<height; i++) { current = src; for (j=0; j<width; j++) { *buffer++ = COLORCONV565(palRed[*current], palGreen[*current], palBlue[*current]); current += 2; } src += 2 * 640; } } } void Set_565(INT16 *buffer, int pitch, int x, int y, int width, int height) { pSet_565(buffer, pitch, x, y, width, height); } void NULL_Set_565(INT16 *buffer, int pitch, int x, int y, int width, int height) { } #endif