aboutsummaryrefslogtreecommitdiff
path: root/backends
diff options
context:
space:
mode:
authorChris Apers2004-05-25 14:33:45 +0000
committerChris Apers2004-05-25 14:33:45 +0000
commit9db22d76bc9e3d979f47383ed4cb3f94462a53f8 (patch)
treea5304eeaa3638888048734a5139d68a52ce51b23 /backends
parentfa80884b09b7d3a5a59ca9170a230623f8d383b1 (diff)
downloadscummvm-rg350-9db22d76bc9e3d979f47383ed4cb3f94462a53f8.tar.gz
scummvm-rg350-9db22d76bc9e3d979f47383ed4cb3f94462a53f8.tar.bz2
scummvm-rg350-9db22d76bc9e3d979f47383ed4cb3f94462a53f8.zip
New file : OSystem gfx stuffs, added hotswap capability and new Osystem functions
svn-id: r13886
Diffstat (limited to 'backends')
-rw-r--r--backends/PalmOS/Src/palm.h105
-rw-r--r--backends/PalmOS/Src/palmgfx.cpp690
2 files changed, 759 insertions, 36 deletions
diff --git a/backends/PalmOS/Src/palm.h b/backends/PalmOS/Src/palm.h
index 8b93aa1b46..5401f04384 100644
--- a/backends/PalmOS/Src/palm.h
+++ b/backends/PalmOS/Src/palm.h
@@ -25,29 +25,47 @@
#include <SonyClie.h>
#include "common/system.h"
+#include "ArmNative.h"
#include "cdaudio.h"
-#include "PNOLoader.h"
-
-
-Err HwrDisplayPalette(UInt8 operation, Int16 startIndex,
- UInt16 paletteEntries, RGBColorType *tableP)
- SYS_TRAP(sysTrapHwrDisplayPalette);
-
-typedef struct {
- OSystem::SoundProc proc;
- void *param;
+// OSD resource id
+#define kDrawKeyState 3000
+#define kDrawNumPad 3010
+#define kDrawBatLow 3020
+
+// OSD key state
+enum {
+ MD_NONE = 0,
+ MD_CMD,
+ MD_ALT,
+ MD_CTRL
+};
- SndStreamRef sndRefNum;
- bool active, useHandler;
- void *dataP;
-} SoundDataType;
+// gfx modes
+enum {
+ GFX_FLIPPING = 100, // Palmos
+ GFX_BUFFERED = 101, // Palmos
+ GFX_WIDE = 102 // palmos
+};
class OSystem_PALMOS : public OSystem {
public:
// Set colors of the palette
void setPalette(const byte *colors, uint start, uint num);
+ const GraphicsMode *getSupportedGraphicsModes() const;
+ bool setGraphicsMode(int mode);
+ int getGraphicsMode() const;
+ int getDefaultGraphicsMode() const;
+
+ int getOutputSampleRate() const;
+ bool openCD(int drive);
+ void setWindowCaption(const char *caption); // TODO : _inGame = true = don't set
+
+ bool hasFeature(Feature f);
+ void setFeatureState(Feature f, bool enable);
+ bool getFeatureState(Feature f);
+
// Set the size of the video bitmap.
// Typically, 320x200
void initSize(uint w, uint h);
@@ -100,7 +118,6 @@ public:
* Currently, only the 16-bit signed mode is ever used for Simon & Scumm
* @param proc pointer to the callback.
* @param param an arbitrary parameter which is stored and passed to proc.
- * @param format the sample type format.
*/
bool setSoundCallback(SoundProc proc, void *param);
@@ -150,20 +167,14 @@ public:
int16 getHeight();
byte RGBToColor(uint8 r, uint8 g, uint8 b);
void ColorToRGB(byte color, uint8 &r, uint8 &g, uint8 &b);
- // Set a parameter
- uint32 property(int param, Property *value);
// Savefile management
SaveFileManager *get_savefile_manager();
- static OSystem *create(UInt16 gfx_mode);
-
-// UInt8 _sndHandle;
-// Boolean _isSndPlaying;
-// UInt8 *convP;
+ static OSystem *create();
protected:
- byte *_tmpScreenP, *_tmpBackupP;
+ byte *_tmpScreenP, *_tmpBackupP, *_tmpHotSwapP; // TODO : rename _tmpScreenP
bool _overlayVisible;
private:
@@ -179,17 +190,15 @@ private:
void *ptrP[5]; // various ptr
- WinHandle _screenH;
- WinHandle _offScreenH;
- Boolean _fullscreen, _adjustAspectRatio;
+ WinHandle _screenH, _offScreenH;
+ Boolean _fullscreen, _adjustAspectRatio, _wide;
struct {
Coord x;
Coord y;
UInt32 addr;
} _screenOffset;
- byte *_screenP;
- byte *_offScreenP;
+ byte *_screenP, *_offScreenP;
int _offScreenPitch;
int _screenPitch;
@@ -208,16 +217,17 @@ private:
int16 x,y,w,h;
};
- UInt16 _mode;
+ UInt16 _mode, _initMode, _setMode;
+ Boolean _modeChanged, _gfxLoaded;
byte *_mouseDataP;
byte *_mouseBackupP;
MousePos _mouseCurState;
MousePos _mouseOldState;
int16 _mouseHotspotX;
int16 _mouseHotspotY;
- byte _mouseKeycolor;
int _current_shake_pos;
int _new_shake_pos;
+ byte _mouseKeyColor;
Boolean _vibrate;
UInt32 _exit_delay;
@@ -234,7 +244,6 @@ private:
RGBColorType *_currentPalette;
uint _paletteDirtyStart, _paletteDirtyEnd;
-
void draw_mouse();
void undraw_mouse();
@@ -242,17 +251,32 @@ private:
void timer_handler(UInt32 current_msecs);
void getCoordinates(EventPtr event, Coord *x, Coord *y);
- void draw1BitGfx(UInt16 id, UInt32 x, UInt32 y, Boolean clear);
+ void draw1BitGfx(UInt16 id, Int32 x, Int32 y, Boolean clear);
void load_gfx_mode();
+ void hotswap_gfx_mode(int mode);
void unload_gfx_mode();
- static void autosave();
+ // Battery
+ Boolean _showBatLow;
+ void battery_handler();
+
+ // Alarm
+/* Boolean _alarmRaised;
+ void alarm_handler();
+*/
// ARM
+ enum {
+ PNO_COPY = 0,
+ PNO_WIDE,
+ PNO_SNDSTREAM,
+ PNO_COUNT
+ };
+
struct {
PnoDescriptor pnoDesc;
MemPtr pnoPtr;
- } _arm;
+ } _arm[PNO_COUNT];
CDAudio *_cdPlayer;
// PALM spec
@@ -282,7 +306,16 @@ private:
eventsEnum _lastEvent;
OSystem_PALMOS();
- void init_intern(UInt16 gfx_mode);
+ void init_intern();
};
-#endif
+Err HwrDisplayPalette(UInt8 operation, Int16 startIndex,
+ UInt16 paletteEntries, RGBColorType *tableP)
+ SYS_TRAP(sysTrapHwrDisplayPalette);
+
+// Sound
+void pcm2adpcm(Int16 *src, UInt8 *dst, UInt32 length);
+Err sndCallback(void* UserDataP, SndStreamRef stream, void* bufferP, UInt32 *bufferSizeP);
+void ClearScreen();
+
+#endif \ No newline at end of file
diff --git a/backends/PalmOS/Src/palmgfx.cpp b/backends/PalmOS/Src/palmgfx.cpp
new file mode 100644
index 0000000000..65c3336e47
--- /dev/null
+++ b/backends/PalmOS/Src/palmgfx.cpp
@@ -0,0 +1,690 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2001 Ludvig Strigeus
+ * Copyright (C) 2001-2004 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$
+ *
+ */
+#include "stdafx.h"
+#include "palm.h"
+
+#include "common/scaler.h"
+#include "common/util.h"
+#include "common/config-manager.h"
+
+#include <BmpGlue.h>
+#include "start.h" // appFileCreator
+#include "globals.h"
+
+#ifndef DISABLE_TAPWAVE
+// Tapwave code will come here
+#endif
+
+enum {
+ ftrBufferOverlay = 1000,
+ ftrBufferBackup,
+ ftrBufferHotSwap
+};
+
+static const OSystem::GraphicsMode s_supportedGraphicsModes[] = {
+ {"normal", "Normal (no scaling)", GFX_NORMAL},
+ {"flipping", "Page Flipping", GFX_FLIPPING},
+ {"buffered", "Buffered", GFX_BUFFERED},
+ {"wide", "Wide (HiRes+ only)", GFX_WIDE},
+ {0, 0, 0}
+};
+
+int OSystem_PALMOS::getDefaultGraphicsMode() const {
+ return GFX_NORMAL;
+}
+
+const OSystem::GraphicsMode *OSystem_PALMOS::getSupportedGraphicsModes() const {
+ return s_supportedGraphicsModes;
+}
+
+int OSystem_PALMOS::getGraphicsMode() const {
+ return _mode;
+}
+
+bool OSystem_PALMOS::setGraphicsMode(int mode) {
+ switch(mode) {
+ case GFX_NORMAL:
+ case GFX_FLIPPING:
+ case GFX_BUFFERED:
+ case GFX_WIDE:
+ _setMode = mode;
+ break;
+
+ default:
+ warning("unknown gfx mode %d", mode);
+ _setMode = GFX_NORMAL;
+ return false;
+ }
+
+ return true;
+}
+
+void OSystem_PALMOS::initSize(uint w, uint h) {
+ _screenWidth = w;
+ _screenHeight = h;
+ _offScreenPitch = gVars->screenPitch; // direct screen / flipping use this, reset later if buffered
+ _screenPitch = gVars->screenPitch;
+
+ _overlayVisible = false;
+ _quitCount = 0;
+
+ // 640x480 only on Zodiac and in GFX_WIDE mode
+ if (h == 480)
+ if (!(_mode == GFX_WIDE && OPTIONS_TST(kOptDeviceZodiac)))
+ error("640x480 game can only be run on Zodiac in wide mode.");
+
+ // lock the graffiti sizer
+ if (gVars->slkRefNum != sysInvalidRefNum) {
+ if (gVars->slkVersion == vskVersionNum1)
+ SilkLibDisableResize(gVars->slkRefNum);
+ else
+ VskSetState(gVars->slkRefNum, vskStateEnable, vskResizeDisable);
+
+ // Tapwave Zodiac and other DIA compatible devices
+ } else if (OPTIONS_TST(kOptModeWide)) {
+ PINSetInputTriggerState(pinInputTriggerDisabled);
+ }
+
+ // don't allow orientation change
+ if (OPTIONS_TST(kOptCollapsible))
+ SysSetOrientationTriggerState(sysOrientationTriggerDisabled);
+
+ set_mouse_pos(200,150);
+
+ unload_gfx_mode();
+ _mode = _setMode;
+ _initMode = _mode;
+ load_gfx_mode();
+}
+
+int16 OSystem_PALMOS::getHeight() {
+ return _screenHeight;
+}
+
+int16 OSystem_PALMOS::getWidth() {
+ return _screenWidth;
+}
+
+static void HotSwap16bitMode(Boolean swap) {
+ UInt32 width = hrWidth;
+ UInt32 height= hrHeight;
+ UInt32 depth = swap ? 16 : 8;
+ Boolean color = true;
+
+ if (OPTIONS_TST(kOptMode16Bit)) {
+ WinScreenMode(winScreenModeSet, &width, &height, &depth, &color);
+ ClearScreen();
+ OPTIONS_SET(kOptDisableOnScrDisp);
+ }
+}
+
+void OSystem_PALMOS::load_gfx_mode() {
+ Err e;
+
+ if (!_modeChanged) {
+ // get command line config
+ _fullscreen = (ConfMan.getBool("fullscreen") && OPTIONS_TST(kOptModeWide));
+ _adjustAspectRatio = ConfMan.getBool("aspect_ratio");
+
+ // get the actual palette
+ WinPalette(winPaletteGet, 0, 256, _currentPalette);
+
+ // set only if _mode not changed
+ const byte startupPalette[] = {
+ 0 ,0 ,0 ,0,
+ 0 ,0 ,171,0,
+ 0 ,171, 0 ,0,
+ 0 ,171,171,0,
+ 171 ,0 ,0 ,0,
+ 171 ,0 ,171,0,
+ 171 ,87 ,0 ,0,
+ 171 ,171,171,0,
+ 87 ,87 ,87 ,0,
+ 87 ,87 ,255,0,
+ 87 ,255,87 ,0,
+ 87 ,255,255,0,
+ 255 ,87 ,87 ,0,
+ 255 ,87 ,255,0,
+ 255 ,255,87 ,0,
+ 255 ,255,255,0
+ };
+
+ // palette for preload dialog
+ setPalette(startupPalette, 0, 16);
+ }
+
+ // check HiRes+
+ if (_mode == GFX_WIDE) {
+ if (OPTIONS_TST(kOptModeWide)) {
+ Boolean std = true;
+
+#ifndef DISABLE_TAPWAVE
+// Tapwave code will come here
+#endif
+ if (std) {
+ // only for 320x200 games
+ if (!(_screenWidth == 320 && _screenHeight == 200)) {
+ warning("Wide display not avalaible for this game, switching to GFX_NORMAL mode.");
+ _mode = GFX_NORMAL;
+ }
+ }
+
+ } else {
+ warning("HiRes+ not avalaible on this device, switching to GFX_NORMAL mode.");
+ _mode = GFX_NORMAL;
+ }
+ }
+
+ if (_fullscreen || _mode == GFX_WIDE) {
+ // Sony wide
+ if (gVars->slkRefNum != sysInvalidRefNum) {
+ if (gVars->slkVersion == vskVersionNum1) {
+ SilkLibEnableResize (gVars->slkRefNum);
+ SilkLibResizeDispWin(gVars->slkRefNum, silkResizeMax);
+ SilkLibDisableResize(gVars->slkRefNum);
+ } else {
+ VskSetState(gVars->slkRefNum, vskStateEnable, (gVars->slkVersion != vskVersionNum3 ? vskResizeVertically : vskResizeHorizontally));
+ VskSetState(gVars->slkRefNum, vskStateResize, vskResizeNone);
+ VskSetState(gVars->slkRefNum, vskStateEnable, vskResizeDisable);
+ }
+
+ // Tapwave Zodiac and other DIA compatible devices
+ } else if (OPTIONS_TST(kOptModeWide)) {
+ PINSetInputAreaState(pinInputAreaClosed);
+ StatHide();
+ }
+ }
+
+ if (_modeChanged) {
+ WinSetBackColor(RGBToColor(0,0,0));
+ WinEraseWindow();
+ }
+
+ if (_mode == GFX_WIDE) {
+ OPTIONS_SET(kOptDisableOnScrDisp);
+ _fullscreen = false;
+ _wide = true;
+
+ if (OPTIONS_TST(kOptDeviceZodiac)) {
+ // landscape
+ _screenOffset.x = 0;
+ _screenOffset.y = (_adjustAspectRatio) ? 10 : 0;
+ _screenOffset.addr = _screenOffset.y * _screenPitch;
+
+ // others only for 320x200
+ } else {
+ _wide = false;
+
+ _screenOffset.x = 0;
+ _screenOffset.y = 10;
+ _screenOffset.addr = (OPTIONS_TST(kOptModeLandscape) ? _screenOffset.y : _screenOffset.x) * _screenPitch;
+ }
+
+ } else {
+ OPTIONS_RST(kOptDisableOnScrDisp);
+
+ _screenOffset.x = ((_fullscreen ? gVars->screenFullWidth : gVars->screenWidth) - _screenWidth) >> 1;
+ _screenOffset.y = ((_fullscreen ? gVars->screenFullHeight : gVars->screenHeight) - _screenHeight) >> 1;
+ _screenOffset.addr = _screenOffset.x + _screenOffset.y * _screenPitch;
+ }
+
+ if (OPTIONS_TST(kOptModeHiDensity))
+ WinSetCoordinateSystem(kCoordinatesNative);
+
+ // init screens
+ switch(_mode) {
+ case GFX_FLIPPING:
+ gVars->screenLocked = true;
+ _offScreenP = WinScreenLock(winLockErase) + _screenOffset.addr;
+ _screenP = _offScreenP;
+ _offScreenH = WinGetDisplayWindow();
+ _screenH = _offScreenH;
+ _renderer_proc = &OSystem_PALMOS::updateScreen__flipping;
+ break;
+ case GFX_WIDE:
+ case GFX_BUFFERED:
+ _screenH = WinGetDisplayWindow();
+ _offScreenH = WinCreateOffscreenWindow(_screenWidth, _screenHeight, nativeFormat, &e);
+ _offScreenP = (byte *)(BmpGetBits(WinGetBitmap(_offScreenH)));
+
+ if (_mode == GFX_WIDE) {
+#ifndef DISABLE_TAPWAVE
+// Tapwave code will come here
+#endif
+ {
+ gVars->screenLocked = true;
+ _screenP = WinScreenLock(winLockErase) + _screenOffset.addr;
+
+ if (OPTIONS_TST(kOptDeviceARM))
+ _arm[PNO_WIDE].pnoPtr = _PnoInit((OPTIONS_TST(kOptModeLandscape) ? ARM_OWIDELS : ARM_OWIDEPT), &_arm[PNO_WIDE].pnoDesc);
+
+ _renderer_proc = (OPTIONS_TST(kOptModeLandscape)) ?
+ &OSystem_PALMOS::updateScreen__wide_landscape :
+ &OSystem_PALMOS::updateScreen__wide_portrait;
+ }
+
+ } else {
+ _screenP = (byte *)(BmpGetBits(WinGetBitmap(_screenH))) + _screenOffset.addr;
+ _renderer_proc = &OSystem_PALMOS::updateScreen__buffered;
+ }
+ _offScreenPitch = _screenWidth;
+ break;
+
+ case GFX_NORMAL:
+ default:
+ _offScreenH = WinGetDisplayWindow();
+ _screenH = _offScreenH;
+ _offScreenP = (byte *)(BmpGetBits(WinGetBitmap(_offScreenH))) + _screenOffset.addr;
+ _screenP = _offScreenP;
+ _renderer_proc = &OSystem_PALMOS::updateScreen__direct;
+ break;
+ }
+
+ if (!_modeChanged) {
+ // try to allocate on storage heap, TODO : error if failed
+ FtrPtrNew(appFileCreator, ftrBufferOverlay, _screenWidth * _screenHeight, (void **)&_tmpScreenP);
+ FtrPtrNew(appFileCreator, ftrBufferBackup, _screenWidth * _screenHeight, (void **)&_tmpBackupP);
+ // only if wide mode avalaible
+ if OPTIONS_TST(kOptModeWide)
+ FtrPtrNew(appFileCreator, ftrBufferHotSwap, _screenWidth * _screenHeight, (void **)&_tmpHotSwapP);
+
+ _gfxLoaded = true;
+ }
+
+}
+
+void OSystem_PALMOS::unload_gfx_mode() {
+ if (!_gfxLoaded)
+ return;
+
+ WinSetDrawWindow(WinGetDisplayWindow());
+
+ if (OPTIONS_TST(kOptModeHiDensity))
+ WinSetCoordinateSystem(kCoordinatesStandard);
+
+ switch (_mode) {
+ case GFX_FLIPPING:
+ WinScreenUnlock();
+ gVars->screenLocked = false;
+ break;
+
+ case GFX_WIDE:
+#ifndef DISABLE_TAPWAVE
+// Tapwave code will come here
+#endif
+ {
+ WinScreenUnlock();
+ gVars->screenLocked = false;
+
+ if (OPTIONS_TST(kOptDeviceARM) && _arm[PNO_WIDE].pnoPtr)
+ _PnoFree(&_arm[PNO_WIDE].pnoDesc, _arm[PNO_WIDE].pnoPtr);
+ }
+ // continue to GFX_BUFFERED
+
+ case GFX_BUFFERED:
+ WinDeleteWindow(_offScreenH, false);
+ break;
+ }
+
+ // restore silkarea
+ // -- Sony wide
+ if (gVars->slkRefNum != sysInvalidRefNum) {
+ if (gVars->slkVersion == vskVersionNum1) {
+ SilkLibEnableResize (gVars->slkRefNum);
+ SilkLibResizeDispWin(gVars->slkRefNum, silkResizeNormal);
+ SilkLibDisableResize(gVars->slkRefNum);
+ } else {
+ VskSetState(gVars->slkRefNum, vskStateEnable, (gVars->slkVersion != vskVersionNum3 ? vskResizeVertically : vskResizeHorizontally));
+ VskSetState(gVars->slkRefNum, vskStateResize, vskResizeMax);
+ VskSetState(gVars->slkRefNum, vskStateEnable, vskResizeDisable);
+ }
+
+ // -- Tapwave Zodiac and other DIA compatible devices
+ } else if (OPTIONS_TST(kOptModeWide)) {
+ StatShow();
+ PINSetInputAreaState(pinInputAreaOpen);
+ }
+
+ if (!_modeChanged) {
+ // free only if _mode not changed
+ if (_tmpScreenP)
+ FtrPtrFree(appFileCreator, ftrBufferOverlay);
+
+ if (_tmpBackupP)
+ FtrPtrFree(appFileCreator, ftrBufferBackup);
+
+ if OPTIONS_TST(kOptModeWide)
+ if (_tmpHotSwapP)
+ FtrPtrFree(appFileCreator, ftrBufferHotSwap);
+ }
+}
+
+void OSystem_PALMOS::hotswap_gfx_mode(int mode) {
+ // save current offscreen
+ byte *src = _offScreenP;
+ byte *dst = _tmpHotSwapP;
+ int h = _screenHeight;
+
+ UInt32 offset = 0;
+ do {
+ DmWrite(dst, offset, src, _screenWidth);
+ offset += _screenWidth;
+ src += _offScreenPitch;
+ } while (--h);
+ _modeChanged = true;
+
+ // reset offscreen pitch
+ _offScreenPitch = gVars->screenPitch;
+
+ // free old mode memory
+ unload_gfx_mode();
+
+ // load new gfx mode
+ _mode = mode;
+ load_gfx_mode();
+
+ // restore offscreen
+ copyRectToScreen(_tmpHotSwapP, _screenWidth, 0, 0, _screenWidth, _screenHeight);
+ _modeChanged = false;
+
+ // force palette update
+ _paletteDirtyStart = 0;
+ _paletteDirtyEnd = 256;
+
+ updateScreen();
+}
+
+
+// TODO : move GFX functions here
+
+void OSystem_PALMOS::setPalette(const byte *colors, uint start, uint num) {
+ if (_quitCount)
+ return;
+
+ const byte *b = colors;
+ uint i;
+ RGBColorType *base = _currentPalette + start;
+ for(i=0; i < num; i++) {
+ base[i].r = b[0];
+ base[i].g = b[1];
+ base[i].b = b[2];
+ b += 4;
+ }
+
+ if (start < _paletteDirtyStart)
+ _paletteDirtyStart = start;
+
+ if (start + num > _paletteDirtyEnd)
+ _paletteDirtyEnd = start + num;
+}
+
+byte OSystem_PALMOS::RGBToColor(uint8 r, uint8 g, uint8 b) {
+ byte color;
+
+ if (gVars->stdPalette) {
+ RGBColorType rgb = {0, r, g, b};
+ color = WinRGBToIndex(&rgb);
+
+ } else {
+ byte nearest = 255;
+ byte check;
+ byte r2, g2, b2;
+
+ color = 255;
+
+ for (int i = 0; i < 256; i++)
+ {
+ r2 = _currentPalette[i].r;
+ g2 = _currentPalette[i].g;
+ b2 = _currentPalette[i].b;
+
+ check = (ABS(r2 - r) + ABS(g2 - g) + ABS(b2 - b)) / 3;
+
+ if (check == 0) // perfect match
+ return i;
+ else if (check < nearest) { // else save and continue
+ color = i;
+ nearest = check;
+ }
+ }
+ }
+
+ return color;
+}
+
+void OSystem_PALMOS::ColorToRGB(byte color, uint8 &r, uint8 &g, uint8 &b) {
+ r = _currentPalette[color].r;
+ g = _currentPalette[color].g;
+ b = _currentPalette[color].b;
+}
+
+void OSystem_PALMOS::copyRectToScreen(const byte *buf, int pitch, int x, int y, int w, int h) {
+ /* Clip the coordinates */
+ if (x < 0) {
+ w += x;
+ buf -= x;
+ x = 0;
+ }
+
+ if (y < 0) {
+ h += y;
+ buf -= y * pitch;
+ y = 0;
+ }
+
+ if (w > _screenWidth - x)
+ w = _screenWidth - x;
+
+ if (h > _screenHeight - y)
+ h = _screenHeight - y;
+
+ if (w <= 0 || h <= 0)
+ return;
+
+ /* FIXME: undraw mouse only if the draw rect intersects with the mouse rect */
+ if (_mouseDrawn)
+ undraw_mouse();
+
+ byte *dst = _offScreenP + y * _offScreenPitch + x;
+
+#ifndef DISABLE_ARM
+ if (OPTIONS_TST(kOptDeviceARM)) {
+ OSysCopyType userData = { dst, buf, pitch, _offScreenPitch, w, h };
+ _PnoCall(&_arm[PNO_COPY].pnoDesc, &userData);
+ return;
+ }
+#ifdef DEBUG_ARM
+ if (OPTIONS_TST(kOptDeviceProcX86)) {
+ OSysCopyType userData = { dst, buf, pitch, _offScreenPitch, w, h };
+ UInt32 result = PceNativeCall((NativeFuncType*)"ARMlet.dll\0ARMlet_Main", &userData);
+ return;
+ }
+#endif
+#endif
+ // if no ARM
+ if (_offScreenPitch == pitch && pitch == w) {
+ MemMove(dst, buf, h * w);
+ } else {
+ do {
+ MemMove(dst, buf, w);
+ dst += _offScreenPitch;
+ buf += pitch;
+ } while (--h);
+ }
+}
+
+void OSystem_PALMOS::updateScreen() {
+ if(_quitCount)
+ return;
+
+ // Make sure the mouse is drawn, if it should be drawn.
+ draw_mouse();
+
+ // Check whether the palette was changed in the meantime and update the
+ // screen surface accordingly.
+ if (_paletteDirtyEnd != 0) {
+ UInt8 oldCol;
+
+ if (gVars->stdPalette) {
+ WinSetDrawWindow(WinGetDisplayWindow()); // hack by Doug
+ WinPalette(winPaletteSet, _paletteDirtyStart, _paletteDirtyEnd - _paletteDirtyStart,_currentPalette + _paletteDirtyStart);
+ } else {
+ HwrDisplayPalette(winPaletteSet, _paletteDirtyStart, _paletteDirtyEnd - _paletteDirtyStart,_currentPalette + _paletteDirtyStart);
+ }
+ _paletteDirtyEnd = 0;
+ oldCol = gVars->indicator.on;
+ gVars->indicator.on = RGBToColor(0,255,0);
+
+ if (oldCol != gVars->indicator.on) {
+ // redraw if needed
+ if (_lastKeyModifier)
+ draw1BitGfx((kDrawKeyState + _lastKeyModifier - 1), 2, getHeight() + 2, true);
+
+ if(_useNumPad)
+ draw1BitGfx(kDrawNumPad, (getWidth() >> 1) - 32, getHeight() + 2, true);
+
+ if (_showBatLow)
+ draw1BitGfx(kDrawBatLow, (getWidth() >> 1), -16, true);
+ }
+ }
+
+ if (_overlayVisible) {
+ byte *src = _tmpScreenP;
+ byte *dst = _offScreenP;
+ UInt16 h = _screenHeight;
+
+ do {
+ memcpy(dst, src, _screenWidth);
+ dst += _offScreenPitch;
+ src += _screenWidth;
+ } while (--h);
+ }
+
+ // redraw the screen
+ ((this)->*(_renderer_proc))();
+}
+
+void OSystem_PALMOS::move_screen(int dx, int dy, int height) {
+ // Short circuit check - do we have to do anything anyway?
+ if ((dx == 0 && dy == 0) || height <= 0)
+ return;
+
+ // Hide the mouse
+ if (_mouseDrawn)
+ undraw_mouse();
+
+ RectangleType r, dummy;
+ WinSetDrawWindow(_offScreenH);
+ RctSetRectangle(&r, ((_offScreenH != _screenH) ? 0 : _screenOffset.x), ((_offScreenH != _screenH) ? 0 : _screenOffset.y), _screenWidth, _screenHeight);
+
+ // vertical movement
+ if (dy > 0) {
+ // move down - copy from bottom to top
+ if (_useHRmode) {
+ // need to set the draw window
+ HRWinScrollRectangle(gVars->HRrefNum, &r, winDown, dy, &dummy);
+ } else {
+ WinScrollRectangle(&r, winDown, dy, &dummy);
+ }
+ } else if (dy < 0) {
+ // move up - copy from top to bottom
+ dy = -dy;
+ if (_useHRmode) {
+ // need to set the draw window
+ HRWinScrollRectangle(gVars->HRrefNum, &r, winUp, dy, &dummy);
+ } else {
+ WinScrollRectangle(&r, winUp, dy, &dummy);
+ }
+ }
+
+ // horizontal movement
+ if (dx > 0) {
+ // move right - copy from right to left
+ if (_useHRmode) {
+ // need to set the draw window
+ HRWinScrollRectangle(gVars->HRrefNum, &r, winRight, dx, &dummy);
+ } else {
+ WinScrollRectangle(&r, winRight, dx, &dummy);
+ }
+ } else if (dx < 0) {
+ // move left - copy from left to right
+ dx = -dx;
+ if (_useHRmode) {
+ // need to set the draw window
+ HRWinScrollRectangle(gVars->HRrefNum, &r, winLeft, dx, &dummy);
+ } else {
+ WinScrollRectangle(&r, winLeft, dx, &dummy);
+ }
+ }
+
+
+ WinSetDrawWindow(_screenH);
+ // Prevent crash on Clie device using successive [HR]WinScrollRectangle !
+ SysTaskDelay(1);
+}
+
+void OSystem_PALMOS::draw1BitGfx(UInt16 id, Int32 x, Int32 y, Boolean show) {
+ if (OPTIONS_TST(kOptDisableOnScrDisp))
+ return;
+
+ MemHandle hTemp = DmGetResource(bitmapRsc, id);
+
+ if (hTemp) {
+ BitmapType *bmTemp;
+ UInt32 *bmData;
+ UInt8 ih, iw, ib;
+ Coord w, h;
+ Int16 blocks, next;
+
+ UInt8 *scr = _screenP + x + _screenPitch * y;
+
+ bmTemp = (BitmapType *)MemHandleLock(hTemp);
+ bmData = (UInt32 *)BmpGetBits(bmTemp);
+ BmpGlueGetDimensions(bmTemp, &w, &h, 0);
+
+ blocks = w >> 5;
+ next = w - (blocks << 5);
+
+ if (next)
+ blocks++;
+
+ for (ih = 0; ih < h; ih++) { // line
+ for (ib = 0; ib < blocks; ib++) { // 32pix block
+ next = w - (ib << 5);
+ next = MIN(next, (Coord)32);
+
+ for (iw = 0; iw < next; iw++) { // row
+
+ *scr++ = ((*bmData & (1 << (31 - iw))) && show) ?
+ gVars->indicator.on :
+ gVars->indicator.off;
+ }
+
+ bmData++;
+ }
+ scr += _screenPitch - w;
+ }
+
+ MemPtrUnlock(bmTemp);
+ DmReleaseResource(hTemp);
+ }
+} \ No newline at end of file