diff options
99 files changed, 3028 insertions, 2334 deletions
@@ -230,10 +230,19 @@ GOB Games by Coktel Vision: and the Schnibble [woodruff] Ween: The Prophecy [ween] +MADE Games by Activision: + Leather Goddesses of Phobos 2 [lgop2] + Return to Zork [rtz] + Rodney's Funscreen [rodney] + The Manhole [manhole] + Other Games: Beneath a Steel Sky [sky] Broken Sword 1: The Shadow of the Templars [sword1] Broken Sword 2: The Smoking Mirror [sword2] + Cruise for a Corpse [cruise] + Discworld [dw] + Discworld 2: Missing Presumed ...!? [dw2] Drascula: The Vampire Strikes Back [drascula] Flight of the Amazon Queen [queen] Future Wars [fw] @@ -297,6 +306,7 @@ and view the compatibility chart. Backyard Baseball [baseball] Backyard Soccer [soccer] Blue's Birthday Adventure [BluesBirthday] + Blue's Treasure Hunt [BluesTreasureHunt] SPY Fox 3: Operation Ozone [spyozon] The following games are based on the SCUMM engine, but NOT supported diff --git a/backends/platform/iphone/module.mk b/backends/platform/iphone/module.mk index a3c9a012fe..28bc8d3ac7 100644 --- a/backends/platform/iphone/module.mk +++ b/backends/platform/iphone/module.mk @@ -1,7 +1,10 @@ MODULE := backends/platform/iphone MODULE_OBJS := \ - osys_iphone.o \ + osys_main.o \ + osys_events.o \ + osys_sound.o \ + osys_video.o \ iphone_main.o \ iphone_video.o \ iphone_keyboard.o \ diff --git a/backends/platform/iphone/osys_events.cpp b/backends/platform/iphone/osys_events.cpp new file mode 100644 index 0000000000..a190f68189 --- /dev/null +++ b/backends/platform/iphone/osys_events.cpp @@ -0,0 +1,514 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#include "gui/message.h" + +#include "osys_main.h" + + +bool OSystem_IPHONE::pollEvent(Common::Event &event) { + //printf("pollEvent()\n"); + + long curTime = getMillis(); + + if (_timerCallback && (curTime >= _timerCallbackNext)) { + _timerCallback(_timerCallbackTimer); + _timerCallbackNext = curTime + _timerCallbackTimer; + } + + if (_needEventRestPeriod) { + // Workaround: Some engines can't handle mouse-down and mouse-up events + // appearing right after each other, without a call returning no input in between. + _needEventRestPeriod = false; + return false; + } + + if (_queuedInputEvent.type != (Common::EventType)0) { + event = _queuedInputEvent; + _queuedInputEvent.type = (Common::EventType)0; + return true; + } + + int eventType; + float xUnit, yUnit; + + if (iPhone_fetchEvent(&eventType, &xUnit, &yUnit)) { + int x = 0; + int y = 0; + switch (_screenOrientation) { + case kScreenOrientationPortrait: + x = (int)(xUnit * _screenWidth); + y = (int)(yUnit * _screenHeight); + break; + case kScreenOrientationLandscape: + x = (int)(yUnit * _screenWidth); + y = (int)((1.0 - xUnit) * _screenHeight); + break; + case kScreenOrientationFlippedLandscape: + x = (int)((1.0 - yUnit) * _screenWidth); + y = (int)(xUnit * _screenHeight); + break; + } + + switch ((InputEvent)eventType) { + case kInputMouseDown: + if (!handleEvent_mouseDown(event, x, y)) + return false; + break; + + case kInputMouseUp: + if (!handleEvent_mouseUp(event, x, y)) + return false; + break; + + case kInputMouseDragged: + if (!handleEvent_mouseDragged(event, x, y)) + return false; + break; + case kInputMouseSecondDragged: + if (!handleEvent_mouseSecondDragged(event, x, y)) + return false; + break; + case kInputMouseSecondDown: + _secondaryTapped = true; + if (!handleEvent_secondMouseDown(event, x, y)) + return false; + break; + case kInputMouseSecondUp: + _secondaryTapped = false; + if (!handleEvent_secondMouseUp(event, x, y)) + return false; + break; + case kInputOrientationChanged: + handleEvent_orientationChanged((int)xUnit); + return false; + break; + + case kInputApplicationSuspended: + suspendLoop(); + return false; + break; + + case kInputKeyPressed: + handleEvent_keyPressed(event, (int)xUnit); + break; + + case kInputSwipe: + if (!handleEvent_swipe(event, (int)xUnit)) + return false; + break; + + default: + break; + } + + return true; + } + return false; +} + +bool OSystem_IPHONE::handleEvent_mouseDown(Common::Event &event, int x, int y) { + //printf("Mouse down at (%u, %u)\n", x, y); + + // Workaround: kInputMouseSecondToggled isn't always sent when the + // secondary finger is lifted. Need to make sure we get out of that mode. + _secondaryTapped = false; + + if (_touchpadModeEnabled) { + _lastPadX = x; + _lastPadY = y; + } else + warpMouse(x, y); + + if (_mouseClickAndDragEnabled) { + event.type = Common::EVENT_LBUTTONDOWN; + event.mouse.x = _mouseX; + event.mouse.y = _mouseY; + return true; + } else { + _lastMouseDown = getMillis(); + } + return false; +} + +bool OSystem_IPHONE::handleEvent_mouseUp(Common::Event &event, int x, int y) { + //printf("Mouse up at (%u, %u)\n", x, y); + + if (_secondaryTapped) { + _secondaryTapped = false; + if (!handleEvent_secondMouseUp(event, x, y)) + return false; + } + else if (_mouseClickAndDragEnabled) { + event.type = Common::EVENT_LBUTTONUP; + event.mouse.x = _mouseX; + event.mouse.y = _mouseY; + } else { + if (getMillis() - _lastMouseDown < 250) { + event.type = Common::EVENT_LBUTTONDOWN; + event.mouse.x = _mouseX; + event.mouse.y = _mouseY; + + _queuedInputEvent.type = Common::EVENT_LBUTTONUP; + _queuedInputEvent.mouse.x = _mouseX; + _queuedInputEvent.mouse.y = _mouseY; + _lastMouseTap = getMillis(); + _needEventRestPeriod = true; + } else + return false; + } + + return true; +} + +bool OSystem_IPHONE::handleEvent_secondMouseDown(Common::Event &event, int x, int y) { + _lastSecondaryDown = getMillis(); + _gestureStartX = x; + _gestureStartY = y; + + if (_mouseClickAndDragEnabled) { + event.type = Common::EVENT_LBUTTONUP; + event.mouse.x = _mouseX; + event.mouse.y = _mouseY; + + _queuedInputEvent.type = Common::EVENT_RBUTTONDOWN; + _queuedInputEvent.mouse.x = _mouseX; + _queuedInputEvent.mouse.y = _mouseY; + } + else + return false; + + return true; +} + +bool OSystem_IPHONE::handleEvent_secondMouseUp(Common::Event &event, int x, int y) { + int curTime = getMillis(); + + if (curTime - _lastSecondaryDown < 400 ) { + //printf("Right tap!\n"); + if (curTime - _lastSecondaryTap < 400 && !_overlayVisible) { + //printf("Right escape!\n"); + event.type = Common::EVENT_KEYDOWN; + _queuedInputEvent.type = Common::EVENT_KEYUP; + + event.kbd.flags = _queuedInputEvent.kbd.flags = 0; + event.kbd.keycode = _queuedInputEvent.kbd.keycode = Common::KEYCODE_ESCAPE; + event.kbd.ascii = _queuedInputEvent.kbd.ascii = Common::ASCII_ESCAPE; + _needEventRestPeriod = true; + _lastSecondaryTap = 0; + } else if (!_mouseClickAndDragEnabled) { + //printf("Rightclick!\n"); + event.type = Common::EVENT_RBUTTONDOWN; + event.mouse.x = _mouseX; + event.mouse.y = _mouseY; + _queuedInputEvent.type = Common::EVENT_RBUTTONUP; + _queuedInputEvent.mouse.x = _mouseX; + _queuedInputEvent.mouse.y = _mouseY; + _lastSecondaryTap = curTime; + _needEventRestPeriod = true; + } else { + //printf("Right nothing!\n"); + return false; + } + } + if (_mouseClickAndDragEnabled) { + event.type = Common::EVENT_RBUTTONUP; + event.mouse.x = _mouseX; + event.mouse.y = _mouseY; + } + + return true; +} + +bool OSystem_IPHONE::handleEvent_mouseDragged(Common::Event &event, int x, int y) { + if (_lastDragPosX == x && _lastDragPosY == y) + return false; + + _lastDragPosX = x; + _lastDragPosY = y; + + //printf("Mouse dragged at (%u, %u)\n", x, y); + int mouseNewPosX; + int mouseNewPosY; + if (_touchpadModeEnabled ) { + int deltaX = _lastPadX - x; + int deltaY = _lastPadY - y; + _lastPadX = x; + _lastPadY = y; + + mouseNewPosX = (int)(_mouseX - deltaX / 0.5f); + mouseNewPosY = (int)(_mouseY - deltaY / 0.5f); + + if (mouseNewPosX < 0) + mouseNewPosX = 0; + else if (mouseNewPosX > _screenWidth) + mouseNewPosX = _screenWidth; + + if (mouseNewPosY < 0) + mouseNewPosY = 0; + else if (mouseNewPosY > _screenHeight) + mouseNewPosY = _screenHeight; + + } else { + mouseNewPosX = x; + mouseNewPosY = y; + } + + event.type = Common::EVENT_MOUSEMOVE; + event.mouse.x = mouseNewPosX; + event.mouse.y = mouseNewPosY; + warpMouse(mouseNewPosX, mouseNewPosY); + + return true; +} + +bool OSystem_IPHONE::handleEvent_mouseSecondDragged(Common::Event &event, int x, int y) { + if (_gestureStartX == -1 || _gestureStartY == -1) { + return false; + } + + static const int kNeededLength = 100; + static const int kMaxDeviation = 20; + + int vecX = (x - _gestureStartX); + int vecY = (y - _gestureStartY); + + int absX = abs(vecX); + int absY = abs(vecY); + + //printf("(%d, %d)\n", vecX, vecY); + + if (absX >= kNeededLength || absY >= kNeededLength) { // Long enough gesture to react upon. + _gestureStartX = -1; + _gestureStartY = -1; + + if (absX < kMaxDeviation && vecY >= kNeededLength) { + // Swipe down + event.type = Common::EVENT_KEYDOWN; + _queuedInputEvent.type = Common::EVENT_KEYUP; + + event.kbd.flags = _queuedInputEvent.kbd.flags = 0; + event.kbd.keycode = _queuedInputEvent.kbd.keycode = Common::KEYCODE_F5; + event.kbd.ascii = _queuedInputEvent.kbd.ascii = Common::ASCII_F5; + _needEventRestPeriod = true; + return true; + } + + if (absX < kMaxDeviation && -vecY >= kNeededLength) { + // Swipe up + _mouseClickAndDragEnabled = !_mouseClickAndDragEnabled; + const char *dialogMsg; + if (_mouseClickAndDragEnabled) { + _touchpadModeEnabled = false; + dialogMsg = "Mouse-click-and-drag mode enabled."; + } else + dialogMsg = "Mouse-click-and-drag mode disabled."; + GUI::TimedMessageDialog dialog(dialogMsg, 1500); + dialog.runModal(); + return false; + } + + if (absY < kMaxDeviation && vecX >= kNeededLength) { + // Swipe right + _touchpadModeEnabled = !_touchpadModeEnabled; + const char *dialogMsg; + if (_touchpadModeEnabled) + dialogMsg = "Touchpad mode enabled."; + else + dialogMsg = "Touchpad mode disabled."; + GUI::TimedMessageDialog dialog(dialogMsg, 1500); + dialog.runModal(); + return false; + + } + + if (absY < kMaxDeviation && -vecX >= kNeededLength) { + // Swipe left + return false; + } + } + + return false; +} + +void OSystem_IPHONE::handleEvent_orientationChanged(int orientation) { + //printf("Orientation: %i\n", orientation); + + ScreenOrientation newOrientation; + switch (orientation) { + case 1: + newOrientation = kScreenOrientationPortrait; + break; + case 3: + newOrientation = kScreenOrientationLandscape; + break; + case 4: + newOrientation = kScreenOrientationFlippedLandscape; + break; + default: + return; + } + + + if (_screenOrientation != newOrientation) { + _screenOrientation = newOrientation; + iPhone_initSurface(_screenWidth, _screenHeight); + + dirtyFullScreen(); + if (_overlayVisible) + dirtyFullOverlayScreen(); + updateScreen(); + } +} + +void OSystem_IPHONE::handleEvent_keyPressed(Common::Event &event, int keyPressed) { + int ascii = keyPressed; + //printf("key: %i\n", keyPressed); + + // We remap some of the iPhone keyboard keys. + // The first ten here are the row of symbols below the numeric keys. + switch (keyPressed) { + case 45: + keyPressed = Common::KEYCODE_F1; + ascii = Common::ASCII_F1; + break; + case 47: + keyPressed = Common::KEYCODE_F2; + ascii = Common::ASCII_F2; + break; + case 58: + keyPressed = Common::KEYCODE_F3; + ascii = Common::ASCII_F3; + break; + case 59: + keyPressed = Common::KEYCODE_F4; + ascii = Common::ASCII_F4; + break; + case 40: + keyPressed = Common::KEYCODE_F5; + ascii = Common::ASCII_F5; + break; + case 41: + keyPressed = Common::KEYCODE_F6; + ascii = Common::ASCII_F6; + break; + case 36: + keyPressed = Common::KEYCODE_F7; + ascii = Common::ASCII_F7; + break; + case 38: + keyPressed = Common::KEYCODE_F8; + ascii = Common::ASCII_F8; + break; + case 64: + keyPressed = Common::KEYCODE_F9; + ascii = Common::ASCII_F9; + break; + case 34: + keyPressed = Common::KEYCODE_F10; + ascii = Common::ASCII_F10; + break; + case 10: + keyPressed = Common::KEYCODE_RETURN; + ascii = Common::ASCII_RETURN; + break; + } + event.type = Common::EVENT_KEYDOWN; + _queuedInputEvent.type = Common::EVENT_KEYUP; + + event.kbd.flags = _queuedInputEvent.kbd.flags = 0; + event.kbd.keycode = _queuedInputEvent.kbd.keycode = (Common::KeyCode)keyPressed; + event.kbd.ascii = _queuedInputEvent.kbd.ascii = ascii; + _needEventRestPeriod = true; +} + +bool OSystem_IPHONE::handleEvent_swipe(Common::Event &event, int direction) { + Common::KeyCode keycode = Common::KEYCODE_INVALID; + switch (_screenOrientation) { + case kScreenOrientationPortrait: + switch ((UIViewSwipeDirection)direction) { + case kUIViewSwipeUp: + keycode = Common::KEYCODE_UP; + break; + case kUIViewSwipeDown: + keycode = Common::KEYCODE_DOWN; + break; + case kUIViewSwipeLeft: + keycode = Common::KEYCODE_LEFT; + break; + case kUIViewSwipeRight: + keycode = Common::KEYCODE_RIGHT; + break; + default: + return false; + } + break; + case kScreenOrientationLandscape: + switch ((UIViewSwipeDirection)direction) { + case kUIViewSwipeUp: + keycode = Common::KEYCODE_LEFT; + break; + case kUIViewSwipeDown: + keycode = Common::KEYCODE_RIGHT; + break; + case kUIViewSwipeLeft: + keycode = Common::KEYCODE_DOWN; + break; + case kUIViewSwipeRight: + keycode = Common::KEYCODE_UP; + break; + default: + return false; + } + break; + case kScreenOrientationFlippedLandscape: + switch ((UIViewSwipeDirection)direction) { + case kUIViewSwipeUp: + keycode = Common::KEYCODE_RIGHT; + break; + case kUIViewSwipeDown: + keycode = Common::KEYCODE_LEFT; + break; + case kUIViewSwipeLeft: + keycode = Common::KEYCODE_UP; + break; + case kUIViewSwipeRight: + keycode = Common::KEYCODE_DOWN; + break; + default: + return false; + } + break; + } + + event.kbd.keycode = _queuedInputEvent.kbd.keycode = keycode; + event.kbd.ascii = _queuedInputEvent.kbd.ascii = 0; + event.type = Common::EVENT_KEYDOWN; + _queuedInputEvent.type = Common::EVENT_KEYUP; + event.kbd.flags = _queuedInputEvent.kbd.flags = 0; + _needEventRestPeriod = true; + + return true; +} diff --git a/backends/platform/iphone/osys_iphone.cpp b/backends/platform/iphone/osys_iphone.cpp deleted file mode 100644 index 7f30c0caaf..0000000000 --- a/backends/platform/iphone/osys_iphone.cpp +++ /dev/null @@ -1,1303 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#include <unistd.h> -#include <pthread.h> - -#include <sys/time.h> - -#include "common/scummsys.h" -#include "common/util.h" -#include "common/rect.h" -#include "common/file.h" -#include "common/fs.h" - -#include "base/main.h" - -#include "backends/saves/default/default-saves.h" -#include "backends/timer/default/default-timer.h" -#include "sound/mixer.h" -#include "sound/mixer_intern.h" -#include "gui/message.h" - -#include "osys_iphone.h" - - -const OSystem::GraphicsMode OSystem_IPHONE::s_supportedGraphicsModes[] = { - {0, 0, 0} -}; - -AQCallbackStruct OSystem_IPHONE::s_AudioQueue; -SoundProc OSystem_IPHONE::s_soundCallback = NULL; -void *OSystem_IPHONE::s_soundParam = NULL; - -OSystem_IPHONE::OSystem_IPHONE() : - _savefile(NULL), _mixer(NULL), _timer(NULL), _offscreen(NULL), - _overlayVisible(false), _overlayBuffer(NULL), _fullscreen(NULL), - _mouseHeight(0), _mouseWidth(0), _mouseBuf(NULL), _lastMouseTap(0), - _secondaryTapped(false), _lastSecondaryTap(0), _screenOrientation(kScreenOrientationFlippedLandscape), - _needEventRestPeriod(false), _mouseClickAndDragEnabled(false), _touchpadModeEnabled(true), - _gestureStartX(-1), _gestureStartY(-1), _fullScreenIsDirty(false), _fullScreenOverlayIsDirty(false), - _mouseDirty(false), _timeSuspended(0), _lastDragPosX(-1), _lastDragPosY(-1), _screenChangeCount(0) - -{ - _queuedInputEvent.type = (Common::EventType)0; - _lastDrawnMouseRect = Common::Rect(0, 0, 0, 0); - - _fsFactory = new POSIXFilesystemFactory(); -} - -OSystem_IPHONE::~OSystem_IPHONE() { - AudioQueueDispose(s_AudioQueue.queue, true); - - delete _fsFactory; - delete _savefile; - delete _mixer; - delete _timer; - delete _offscreen; - delete _fullscreen; -} - -int OSystem_IPHONE::timerHandler(int t) { - DefaultTimerManager *tm = (DefaultTimerManager *)g_system->getTimerManager(); - tm->handler(); - return t; -} - -void OSystem_IPHONE::initBackend() { -#ifdef IPHONE_OFFICIAL - _savefile = new DefaultSaveFileManager(iPhone_getDocumentsDir()); -#else - _savefile = new DefaultSaveFileManager(SCUMMVM_SAVE_PATH); -#endif - - _timer = new DefaultTimerManager(); - - gettimeofday(&_startTime, NULL); - - setupMixer(); - - setTimerCallback(&OSystem_IPHONE::timerHandler, 10); - - OSystem::initBackend(); -} - -bool OSystem_IPHONE::hasFeature(Feature f) { - return false; -} - -void OSystem_IPHONE::setFeatureState(Feature f, bool enable) { -} - -bool OSystem_IPHONE::getFeatureState(Feature f) { - return false; -} - -const OSystem::GraphicsMode* OSystem_IPHONE::getSupportedGraphicsModes() const { - return s_supportedGraphicsModes; -} - - -int OSystem_IPHONE::getDefaultGraphicsMode() const { - return -1; -} - -bool OSystem_IPHONE::setGraphicsMode(const char *mode) { - return true; -} - -bool OSystem_IPHONE::setGraphicsMode(int mode) { - return true; -} - -int OSystem_IPHONE::getGraphicsMode() const { - return -1; -} - -void OSystem_IPHONE::initSize(uint width, uint height) { - //printf("initSize(%i, %i)\n", width, height); - - _screenWidth = width; - _screenHeight = height; - - free(_offscreen); - - _offscreen = (byte *)malloc(width * height); - bzero(_offscreen, width * height); - - free(_overlayBuffer); - - int fullSize = _screenWidth * _screenHeight * sizeof(OverlayColor); - _overlayBuffer = (OverlayColor *)malloc(fullSize); - clearOverlay(); - - free(_fullscreen); - - _fullscreen = (uint16 *)malloc(fullSize); - bzero(_fullscreen, fullSize); - - iPhone_initSurface(width, height); - - _fullScreenIsDirty = false; - dirtyFullScreen(); - _mouseVisible = false; - _screenChangeCount++; - updateScreen(); -} - -int16 OSystem_IPHONE::getHeight() { - return _screenHeight; -} - -int16 OSystem_IPHONE::getWidth() { - return _screenWidth; -} - -void OSystem_IPHONE::setPalette(const byte *colors, uint start, uint num) { - //printf("setPalette()\n"); - const byte *b = colors; - - for (uint i = start; i < start + num; ++i) { - _palette[i] = Graphics::RGBToColor<Graphics::ColorMasks<565> >(b[0], b[1], b[2]); - b += 4; - } - - dirtyFullScreen(); -} - -void OSystem_IPHONE::grabPalette(byte *colors, uint start, uint num) { - //printf("grabPalette()\n"); -} - -void OSystem_IPHONE::copyRectToScreen(const byte *buf, int pitch, int x, int y, int w, int h) { - //printf("copyRectToScreen(%i, %i, %i, %i)\n", x, y, w, 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; - - if (!_fullScreenIsDirty) { - _dirtyRects.push_back(Common::Rect(x, y, x + w, y + h)); - } - - - byte *dst = _offscreen + y * _screenWidth + x; - if (_screenWidth == pitch && pitch == w) - memcpy(dst, buf, h * w); - else { - do { - memcpy(dst, buf, w); - buf += pitch; - dst += _screenWidth; - } while (--h); - } -} - -void OSystem_IPHONE::clipRectToScreen(int16 &x, int16 &y, int16 &w, int16 &h) { - if (x < 0) { - w += x; - x = 0; - } - - if (y < 0) { - h += y; - y = 0; - } - - if (w > _screenWidth - x) - w = _screenWidth - x; - - if (h > _screenHeight - y) - h = _screenHeight - y; - - if (w < 0) { - w = 0; - } - - if (h < 0) { - h = 0; - } -} - -void OSystem_IPHONE::updateScreen() { - //printf("updateScreen(): %i dirty rects.\n", _dirtyRects.size()); - - if (_dirtyRects.size() == 0 && _dirtyOverlayRects.size() == 0 && !_mouseDirty) - return; - - internUpdateScreen(); - _fullScreenIsDirty = false; - _fullScreenOverlayIsDirty = false; - - iPhone_updateScreen(); -} - -void OSystem_IPHONE::internUpdateScreen() { - int16 mouseX = _mouseX - _mouseHotspotX; - int16 mouseY = _mouseY - _mouseHotspotY; - int16 mouseWidth = _mouseWidth; - int16 mouseHeight = _mouseHeight; - - clipRectToScreen(mouseX, mouseY, mouseWidth, mouseHeight); - - Common::Rect mouseRect(mouseX, mouseY, mouseX + mouseWidth, mouseY + mouseHeight); - - if (_mouseDirty) { - if (!_fullScreenIsDirty) { - _dirtyRects.push_back(_lastDrawnMouseRect); - _dirtyRects.push_back(mouseRect); - } - if (!_fullScreenOverlayIsDirty && _overlayVisible) { - _dirtyOverlayRects.push_back(_lastDrawnMouseRect); - _dirtyOverlayRects.push_back(mouseRect); - } - _mouseDirty = false; - _lastDrawnMouseRect = mouseRect; - } - - while (_dirtyRects.size()) { - Common::Rect dirtyRect = _dirtyRects.remove_at(_dirtyRects.size() - 1); - - //printf("Drawing: (%i, %i) -> (%i, %i)\n", dirtyRect.left, dirtyRect.top, dirtyRect.right, dirtyRect.bottom); - - drawDirtyRect(dirtyRect); - - if (_overlayVisible) - drawDirtyOverlayRect(dirtyRect); - - drawMouseCursorOnRectUpdate(dirtyRect, mouseRect); - updateHardwareSurfaceForRect(dirtyRect); - } - - if (_overlayVisible) { - while (_dirtyOverlayRects.size()) { - Common::Rect dirtyRect = _dirtyOverlayRects.remove_at(_dirtyOverlayRects.size() - 1); - - //printf("Drawing: (%i, %i) -> (%i, %i)\n", dirtyRect.left, dirtyRect.top, dirtyRect.right, dirtyRect.bottom); - - drawDirtyOverlayRect(dirtyRect); - drawMouseCursorOnRectUpdate(dirtyRect, mouseRect); - updateHardwareSurfaceForRect(dirtyRect); - } - } -} - -void OSystem_IPHONE::drawDirtyRect(const Common::Rect& dirtyRect) { - int h = dirtyRect.bottom - dirtyRect.top; - int w = dirtyRect.right - dirtyRect.left; - - byte *src = &_offscreen[dirtyRect.top * _screenWidth + dirtyRect.left]; - uint16 *dst = &_fullscreen[dirtyRect.top * _screenWidth + dirtyRect.left]; - for (int y = h; y > 0; y--) { - for (int x = w; x > 0; x--) - *dst++ = _palette[*src++]; - - dst += _screenWidth - w; - src += _screenWidth - w; - } -} - -void OSystem_IPHONE::drawDirtyOverlayRect(const Common::Rect& dirtyRect) { - int h = dirtyRect.bottom - dirtyRect.top; - - uint16 *src = (uint16 *)&_overlayBuffer[dirtyRect.top * _screenWidth + dirtyRect.left]; - uint16 *dst = &_fullscreen[dirtyRect.top * _screenWidth + dirtyRect.left]; - int x = (dirtyRect.right - dirtyRect.left) * 2; - for (int y = h; y > 0; y--) { - memcpy(dst, src, x); - src += _screenWidth; - dst += _screenWidth; - } -} - -void OSystem_IPHONE::drawMouseCursorOnRectUpdate(const Common::Rect& updatedRect, const Common::Rect& mouseRect) { - //draw mouse on top - if (_mouseVisible && (updatedRect.intersects(mouseRect))) { - int srcX = 0; - int srcY = 0; - int left = _mouseX - _mouseHotspotX; - if (left < 0) { - srcX -= left; - left = 0; - } - int top = _mouseY - _mouseHotspotY; - if (top < 0) { - srcY -= top; - top = 0; - } - //int right = left + _mouseWidth; - int bottom = top + _mouseHeight; - if (bottom > _screenWidth) - bottom = _screenWidth; - int displayWidth = _mouseWidth; - if (_mouseWidth + left > _screenWidth) - displayWidth = _screenWidth - left; - int displayHeight = _mouseHeight; - if (_mouseHeight + top > _screenHeight) - displayHeight = _screenHeight - top; - byte *src = &_mouseBuf[srcY * _mouseWidth + srcX]; - uint16 *dst = &_fullscreen[top * _screenWidth + left]; - for (int y = displayHeight; y > srcY; y--) { - for (int x = displayWidth; x > srcX; x--) { - if (*src != _mouseKeyColour) - *dst = _palette[*src]; - dst++; - src++; - } - dst += _screenWidth - displayWidth + srcX; - src += _mouseWidth - displayWidth + srcX; - } - } -} - -void OSystem_IPHONE::updateHardwareSurfaceForRect(const Common::Rect& updatedRect) { - iPhone_updateScreenRect(_fullscreen, updatedRect.left, updatedRect.top, updatedRect.right, updatedRect.bottom ); -} - -Graphics::Surface *OSystem_IPHONE::lockScreen() { - //printf("lockScreen()\n"); - - _framebuffer.pixels = _offscreen; - _framebuffer.w = _screenWidth; - _framebuffer.h = _screenHeight; - _framebuffer.pitch = _screenWidth; - _framebuffer.bytesPerPixel = 1; - - return &_framebuffer; -} - -void OSystem_IPHONE::unlockScreen() { - //printf("unlockScreen()\n"); - dirtyFullScreen(); -} - -void OSystem_IPHONE::setShakePos(int shakeOffset) { - //printf("setShakePos(%i)\n", shakeOffset); -} - -void OSystem_IPHONE::showOverlay() { - //printf("showOverlay()\n"); - _overlayVisible = true; - dirtyFullOverlayScreen(); -} - -void OSystem_IPHONE::hideOverlay() { - //printf("hideOverlay()\n"); - _overlayVisible = false; - _dirtyOverlayRects.clear(); - dirtyFullScreen(); -} - -void OSystem_IPHONE::clearOverlay() { - //printf("clearOverlay()\n"); - bzero(_overlayBuffer, _screenWidth * _screenHeight * sizeof(OverlayColor)); - dirtyFullOverlayScreen(); -} - -void OSystem_IPHONE::grabOverlay(OverlayColor *buf, int pitch) { - //printf("grabOverlay()\n"); - int h = _screenHeight; - OverlayColor *src = _overlayBuffer; - - do { - memcpy(buf, src, _screenWidth * sizeof(OverlayColor)); - src += _screenWidth; - buf += pitch; - } while (--h); -} - -void OSystem_IPHONE::copyRectToOverlay(const OverlayColor *buf, int pitch, int x, int y, int w, int h) { - //printf("copyRectToOverlay(buf, pitch=%i, x=%i, y=%i, w=%i, h=%i)\n", pitch, x, y, w, 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; - - if (!_fullScreenOverlayIsDirty) { - _dirtyOverlayRects.push_back(Common::Rect(x, y, x + w, y + h)); - } - - OverlayColor *dst = _overlayBuffer + (y * _screenWidth + x); - if (_screenWidth == pitch && pitch == w) - memcpy(dst, buf, h * w * sizeof(OverlayColor)); - else { - do { - memcpy(dst, buf, w * sizeof(OverlayColor)); - buf += pitch; - dst += _screenWidth; - } while (--h); - } -} - -int16 OSystem_IPHONE::getOverlayHeight() { - return _screenHeight; -} - -int16 OSystem_IPHONE::getOverlayWidth() { - return _screenWidth; -} - -bool OSystem_IPHONE::showMouse(bool visible) { - bool last = _mouseVisible; - _mouseVisible = visible; - _mouseDirty = true; - - return last; -} - -void OSystem_IPHONE::warpMouse(int x, int y) { - //printf("warpMouse()\n"); - - _mouseX = x; - _mouseY = y; - _mouseDirty = true; -} - -void OSystem_IPHONE::dirtyFullScreen() { - if (!_fullScreenIsDirty) { - _dirtyRects.clear(); - _dirtyRects.push_back(Common::Rect(0, 0, _screenWidth, _screenHeight)); - _fullScreenIsDirty = true; - } -} - -void OSystem_IPHONE::dirtyFullOverlayScreen() { - if (!_fullScreenOverlayIsDirty) { - _dirtyOverlayRects.clear(); - _dirtyOverlayRects.push_back(Common::Rect(0, 0, _screenWidth, _screenHeight)); - _fullScreenOverlayIsDirty = true; - } -} - -void OSystem_IPHONE::setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, byte keycolor, int cursorTargetScale) { - //printf("setMouseCursor(%i, %i)\n", hotspotX, hotspotY); - - if (_mouseBuf != NULL && (_mouseWidth != w || _mouseHeight != h)) { - free(_mouseBuf); - _mouseBuf = NULL; - } - - if (_mouseBuf == NULL) - _mouseBuf = (byte *)malloc(w * h); - - _mouseWidth = w; - _mouseHeight = h; - - _mouseHotspotX = hotspotX; - _mouseHotspotY = hotspotY; - - _mouseKeyColour = keycolor; - - memcpy(_mouseBuf, buf, w * h); - - _mouseDirty = true; -} - -bool OSystem_IPHONE::pollEvent(Common::Event &event) { - //printf("pollEvent()\n"); - - long curTime = getMillis(); - - if (_timerCallback && (curTime >= _timerCallbackNext)) { - _timerCallback(_timerCallbackTimer); - _timerCallbackNext = curTime + _timerCallbackTimer; - } - - if (_needEventRestPeriod) { - // Workaround: Some engines can't handle mouse-down and mouse-up events - // appearing right after each other, without a call returning no input in between. - _needEventRestPeriod = false; - return false; - } - - if (_queuedInputEvent.type != (Common::EventType)0) { - event = _queuedInputEvent; - _queuedInputEvent.type = (Common::EventType)0; - return true; - } - - int eventType; - float xUnit, yUnit; - - if (iPhone_fetchEvent(&eventType, &xUnit, &yUnit)) { - int x = 0; - int y = 0; - switch (_screenOrientation) { - case kScreenOrientationPortrait: - x = (int)(xUnit * _screenWidth); - y = (int)(yUnit * _screenHeight); - break; - case kScreenOrientationLandscape: - x = (int)(yUnit * _screenWidth); - y = (int)((1.0 - xUnit) * _screenHeight); - break; - case kScreenOrientationFlippedLandscape: - x = (int)((1.0 - yUnit) * _screenWidth); - y = (int)(xUnit * _screenHeight); - break; - } - - switch ((InputEvent)eventType) { - case kInputMouseDown: - if (!handleEvent_mouseDown(event, x, y)) - return false; - break; - - case kInputMouseUp: - if (!handleEvent_mouseUp(event, x, y)) - return false; - break; - - case kInputMouseDragged: - if (!handleEvent_mouseDragged(event, x, y)) - return false; - break; - case kInputMouseSecondDragged: - if (!handleEvent_mouseSecondDragged(event, x, y)) - return false; - break; - case kInputMouseSecondDown: - _secondaryTapped = true; - if (!handleEvent_secondMouseDown(event, x, y)) - return false; - break; - case kInputMouseSecondUp: - _secondaryTapped = false; - if (!handleEvent_secondMouseUp(event, x, y)) - return false; - break; - case kInputOrientationChanged: - handleEvent_orientationChanged((int)xUnit); - return false; - break; - - case kInputApplicationSuspended: - suspendLoop(); - return false; - break; - - case kInputKeyPressed: - handleEvent_keyPressed(event, (int)xUnit); - break; - - case kInputSwipe: - if (!handleEvent_swipe(event, (int)xUnit)) - return false; - break; - - default: - break; - } - - return true; - } - return false; -} - -bool OSystem_IPHONE::handleEvent_mouseDown(Common::Event &event, int x, int y) { - //printf("Mouse down at (%u, %u)\n", x, y); - - // Workaround: kInputMouseSecondToggled isn't always sent when the - // secondary finger is lifted. Need to make sure we get out of that mode. - _secondaryTapped = false; - - if (_touchpadModeEnabled) { - _lastPadX = x; - _lastPadY = y; - } else - warpMouse(x, y); - - if (_mouseClickAndDragEnabled) { - event.type = Common::EVENT_LBUTTONDOWN; - event.mouse.x = _mouseX; - event.mouse.y = _mouseY; - return true; - } else { - _lastMouseDown = getMillis(); - } - return false; -} - -bool OSystem_IPHONE::handleEvent_mouseUp(Common::Event &event, int x, int y) { - //printf("Mouse up at (%u, %u)\n", x, y); - - if (_secondaryTapped) { - _secondaryTapped = false; - if (!handleEvent_secondMouseUp(event, x, y)) - return false; - } - else if (_mouseClickAndDragEnabled) { - event.type = Common::EVENT_LBUTTONUP; - event.mouse.x = _mouseX; - event.mouse.y = _mouseY; - } else { - if (getMillis() - _lastMouseDown < 250) { - event.type = Common::EVENT_LBUTTONDOWN; - event.mouse.x = _mouseX; - event.mouse.y = _mouseY; - - _queuedInputEvent.type = Common::EVENT_LBUTTONUP; - _queuedInputEvent.mouse.x = _mouseX; - _queuedInputEvent.mouse.y = _mouseY; - _lastMouseTap = getMillis(); - _needEventRestPeriod = true; - } else - return false; - } - - return true; -} - -bool OSystem_IPHONE::handleEvent_secondMouseDown(Common::Event &event, int x, int y) { - _lastSecondaryDown = getMillis(); - _gestureStartX = x; - _gestureStartY = y; - - if (_mouseClickAndDragEnabled) { - event.type = Common::EVENT_LBUTTONUP; - event.mouse.x = _mouseX; - event.mouse.y = _mouseY; - - _queuedInputEvent.type = Common::EVENT_RBUTTONDOWN; - _queuedInputEvent.mouse.x = _mouseX; - _queuedInputEvent.mouse.y = _mouseY; - } - else - return false; - - return true; -} - -bool OSystem_IPHONE::handleEvent_secondMouseUp(Common::Event &event, int x, int y) { - int curTime = getMillis(); - - if (curTime - _lastSecondaryDown < 400 ) { - //printf("Right tap!\n"); - if (curTime - _lastSecondaryTap < 400 && !_overlayVisible) { - //printf("Right escape!\n"); - event.type = Common::EVENT_KEYDOWN; - _queuedInputEvent.type = Common::EVENT_KEYUP; - - event.kbd.flags = _queuedInputEvent.kbd.flags = 0; - event.kbd.keycode = _queuedInputEvent.kbd.keycode = Common::KEYCODE_ESCAPE; - event.kbd.ascii = _queuedInputEvent.kbd.ascii = Common::ASCII_ESCAPE; - _needEventRestPeriod = true; - _lastSecondaryTap = 0; - } else if (!_mouseClickAndDragEnabled) { - //printf("Rightclick!\n"); - event.type = Common::EVENT_RBUTTONDOWN; - event.mouse.x = _mouseX; - event.mouse.y = _mouseY; - _queuedInputEvent.type = Common::EVENT_RBUTTONUP; - _queuedInputEvent.mouse.x = _mouseX; - _queuedInputEvent.mouse.y = _mouseY; - _lastSecondaryTap = curTime; - _needEventRestPeriod = true; - } else { - //printf("Right nothing!\n"); - return false; - } - } - if (_mouseClickAndDragEnabled) { - event.type = Common::EVENT_RBUTTONUP; - event.mouse.x = _mouseX; - event.mouse.y = _mouseY; - } - - return true; -} - -bool OSystem_IPHONE::handleEvent_mouseDragged(Common::Event &event, int x, int y) { - if (_lastDragPosX == x && _lastDragPosY == y) - return false; - - _lastDragPosX = x; - _lastDragPosY = y; - - //printf("Mouse dragged at (%u, %u)\n", x, y); - int mouseNewPosX; - int mouseNewPosY; - if (_touchpadModeEnabled ) { - int deltaX = _lastPadX - x; - int deltaY = _lastPadY - y; - _lastPadX = x; - _lastPadY = y; - - mouseNewPosX = (int)(_mouseX - deltaX / 0.5f); - mouseNewPosY = (int)(_mouseY - deltaY / 0.5f); - - if (mouseNewPosX < 0) - mouseNewPosX = 0; - else if (mouseNewPosX > _screenWidth) - mouseNewPosX = _screenWidth; - - if (mouseNewPosY < 0) - mouseNewPosY = 0; - else if (mouseNewPosY > _screenHeight) - mouseNewPosY = _screenHeight; - - } else { - mouseNewPosX = x; - mouseNewPosY = y; - } - - event.type = Common::EVENT_MOUSEMOVE; - event.mouse.x = mouseNewPosX; - event.mouse.y = mouseNewPosY; - warpMouse(mouseNewPosX, mouseNewPosY); - - return true; -} - -bool OSystem_IPHONE::handleEvent_mouseSecondDragged(Common::Event &event, int x, int y) { - if (_gestureStartX == -1 || _gestureStartY == -1) { - return false; - } - - static const int kNeededLength = 100; - static const int kMaxDeviation = 20; - - int vecX = (x - _gestureStartX); - int vecY = (y - _gestureStartY); - - int absX = abs(vecX); - int absY = abs(vecY); - - //printf("(%d, %d)\n", vecX, vecY); - - if (absX >= kNeededLength || absY >= kNeededLength) { // Long enough gesture to react upon. - _gestureStartX = -1; - _gestureStartY = -1; - - if (absX < kMaxDeviation && vecY >= kNeededLength) { - // Swipe down - event.type = Common::EVENT_KEYDOWN; - _queuedInputEvent.type = Common::EVENT_KEYUP; - - event.kbd.flags = _queuedInputEvent.kbd.flags = 0; - event.kbd.keycode = _queuedInputEvent.kbd.keycode = Common::KEYCODE_F5; - event.kbd.ascii = _queuedInputEvent.kbd.ascii = Common::ASCII_F5; - _needEventRestPeriod = true; - return true; - } - - if (absX < kMaxDeviation && -vecY >= kNeededLength) { - // Swipe up - _mouseClickAndDragEnabled = !_mouseClickAndDragEnabled; - const char *dialogMsg; - if (_mouseClickAndDragEnabled) { - _touchpadModeEnabled = false; - dialogMsg = "Mouse-click-and-drag mode enabled."; - } else - dialogMsg = "Mouse-click-and-drag mode disabled."; - GUI::TimedMessageDialog dialog(dialogMsg, 1500); - dialog.runModal(); - return false; - } - - if (absY < kMaxDeviation && vecX >= kNeededLength) { - // Swipe right - _touchpadModeEnabled = !_touchpadModeEnabled; - const char *dialogMsg; - if (_touchpadModeEnabled) - dialogMsg = "Touchpad mode enabled."; - else - dialogMsg = "Touchpad mode disabled."; - GUI::TimedMessageDialog dialog(dialogMsg, 1500); - dialog.runModal(); - return false; - - } - - if (absY < kMaxDeviation && -vecX >= kNeededLength) { - // Swipe left - return false; - } - } - - return false; -} - -void OSystem_IPHONE::handleEvent_orientationChanged(int orientation) { - //printf("Orientation: %i\n", orientation); - - ScreenOrientation newOrientation; - switch (orientation) { - case 1: - newOrientation = kScreenOrientationPortrait; - break; - case 3: - newOrientation = kScreenOrientationLandscape; - break; - case 4: - newOrientation = kScreenOrientationFlippedLandscape; - break; - default: - return; - } - - - if (_screenOrientation != newOrientation) { - _screenOrientation = newOrientation; - iPhone_initSurface(_screenWidth, _screenHeight); - - dirtyFullScreen(); - if (_overlayVisible) - dirtyFullOverlayScreen(); - updateScreen(); - } -} - -void OSystem_IPHONE::handleEvent_keyPressed(Common::Event &event, int keyPressed) { - int ascii = keyPressed; - //printf("key: %i\n", keyPressed); - - // We remap some of the iPhone keyboard keys. - // The first ten here are the row of symbols below the numeric keys. - switch (keyPressed) { - case 45: - keyPressed = Common::KEYCODE_F1; - ascii = Common::ASCII_F1; - break; - case 47: - keyPressed = Common::KEYCODE_F2; - ascii = Common::ASCII_F2; - break; - case 58: - keyPressed = Common::KEYCODE_F3; - ascii = Common::ASCII_F3; - break; - case 59: - keyPressed = Common::KEYCODE_F4; - ascii = Common::ASCII_F4; - break; - case 40: - keyPressed = Common::KEYCODE_F5; - ascii = Common::ASCII_F5; - break; - case 41: - keyPressed = Common::KEYCODE_F6; - ascii = Common::ASCII_F6; - break; - case 36: - keyPressed = Common::KEYCODE_F7; - ascii = Common::ASCII_F7; - break; - case 38: - keyPressed = Common::KEYCODE_F8; - ascii = Common::ASCII_F8; - break; - case 64: - keyPressed = Common::KEYCODE_F9; - ascii = Common::ASCII_F9; - break; - case 34: - keyPressed = Common::KEYCODE_F10; - ascii = Common::ASCII_F10; - break; - case 10: - keyPressed = Common::KEYCODE_RETURN; - ascii = Common::ASCII_RETURN; - break; - } - event.type = Common::EVENT_KEYDOWN; - _queuedInputEvent.type = Common::EVENT_KEYUP; - - event.kbd.flags = _queuedInputEvent.kbd.flags = 0; - event.kbd.keycode = _queuedInputEvent.kbd.keycode = (Common::KeyCode)keyPressed; - event.kbd.ascii = _queuedInputEvent.kbd.ascii = ascii; - _needEventRestPeriod = true; -} - -bool OSystem_IPHONE::handleEvent_swipe(Common::Event &event, int direction) { - Common::KeyCode keycode = Common::KEYCODE_INVALID; - switch (_screenOrientation) { - case kScreenOrientationPortrait: - switch ((UIViewSwipeDirection)direction) { - case kUIViewSwipeUp: - keycode = Common::KEYCODE_UP; - break; - case kUIViewSwipeDown: - keycode = Common::KEYCODE_DOWN; - break; - case kUIViewSwipeLeft: - keycode = Common::KEYCODE_LEFT; - break; - case kUIViewSwipeRight: - keycode = Common::KEYCODE_RIGHT; - break; - default: - return false; - } - break; - case kScreenOrientationLandscape: - switch ((UIViewSwipeDirection)direction) { - case kUIViewSwipeUp: - keycode = Common::KEYCODE_LEFT; - break; - case kUIViewSwipeDown: - keycode = Common::KEYCODE_RIGHT; - break; - case kUIViewSwipeLeft: - keycode = Common::KEYCODE_DOWN; - break; - case kUIViewSwipeRight: - keycode = Common::KEYCODE_UP; - break; - default: - return false; - } - break; - case kScreenOrientationFlippedLandscape: - switch ((UIViewSwipeDirection)direction) { - case kUIViewSwipeUp: - keycode = Common::KEYCODE_RIGHT; - break; - case kUIViewSwipeDown: - keycode = Common::KEYCODE_LEFT; - break; - case kUIViewSwipeLeft: - keycode = Common::KEYCODE_UP; - break; - case kUIViewSwipeRight: - keycode = Common::KEYCODE_DOWN; - break; - default: - return false; - } - break; - } - - event.kbd.keycode = _queuedInputEvent.kbd.keycode = keycode; - event.kbd.ascii = _queuedInputEvent.kbd.ascii = 0; - event.type = Common::EVENT_KEYDOWN; - _queuedInputEvent.type = Common::EVENT_KEYUP; - event.kbd.flags = _queuedInputEvent.kbd.flags = 0; - _needEventRestPeriod = true; - - return true; -} - -void OSystem_IPHONE::suspendLoop() { - bool done = false; - int eventType; - float xUnit, yUnit; - uint32 startTime = getMillis(); - - stopSoundsystem(); - - while (!done) { - if (iPhone_fetchEvent(&eventType, &xUnit, &yUnit)) - if ((InputEvent)eventType == kInputApplicationResumed) - done = true; - usleep(100000); - } - - startSoundsystem(); - - _timeSuspended += getMillis() - startTime; -} - -uint32 OSystem_IPHONE::getMillis() { - //printf("getMillis()\n"); - - struct timeval currentTime; - gettimeofday(¤tTime, NULL); - return (uint32)(((currentTime.tv_sec - _startTime.tv_sec) * 1000) + - ((currentTime.tv_usec - _startTime.tv_usec) / 1000)) - _timeSuspended; -} - -void OSystem_IPHONE::delayMillis(uint msecs) { - //printf("delayMillis(%d)\n", msecs); - usleep(msecs * 1000); -} - -OSystem::MutexRef OSystem_IPHONE::createMutex(void) { - pthread_mutexattr_t attr; - pthread_mutexattr_init(&attr); - pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); - - pthread_mutex_t *mutex = (pthread_mutex_t *) malloc(sizeof(pthread_mutex_t)); - if (pthread_mutex_init(mutex, &attr) != 0) { - printf("pthread_mutex_init() failed!\n"); - free(mutex); - return NULL; - } - - return (MutexRef)mutex; -} - -void OSystem_IPHONE::lockMutex(MutexRef mutex) { - if (pthread_mutex_lock((pthread_mutex_t *) mutex) != 0) { - printf("pthread_mutex_lock() failed!\n"); - } -} - -void OSystem_IPHONE::unlockMutex(MutexRef mutex) { - if (pthread_mutex_unlock((pthread_mutex_t *) mutex) != 0) { - printf("pthread_mutex_unlock() failed!\n"); - } -} - -void OSystem_IPHONE::deleteMutex(MutexRef mutex) { - if (pthread_mutex_destroy((pthread_mutex_t *) mutex) != 0) { - printf("pthread_mutex_destroy() failed!\n"); - } else { - free(mutex); - } -} - -void OSystem_IPHONE::AQBufferCallback(void *in, AudioQueueRef inQ, AudioQueueBufferRef outQB) { - //printf("AQBufferCallback()\n"); - if (s_AudioQueue.frameCount > 0 && s_soundCallback != NULL) { - outQB->mAudioDataByteSize = 4 * s_AudioQueue.frameCount; - s_soundCallback(s_soundParam, (byte *)outQB->mAudioData, outQB->mAudioDataByteSize); - AudioQueueEnqueueBuffer(inQ, outQB, 0, NULL); - } else { - AudioQueueStop(s_AudioQueue.queue, false); - } -} - -void OSystem_IPHONE::mixCallback(void *sys, byte *samples, int len) { - OSystem_IPHONE *this_ = (OSystem_IPHONE *)sys; - assert(this_); - - if (this_->_mixer) { - this_->_mixer->mixCallback(samples, len); - } -} - -void OSystem_IPHONE::setupMixer() { - //printf("setSoundCallback()\n"); - _mixer = new Audio::MixerImpl(this); - - s_soundCallback = mixCallback; - s_soundParam = this; - - startSoundsystem(); -} - -void OSystem_IPHONE::startSoundsystem() { - s_AudioQueue.dataFormat.mSampleRate = AUDIO_SAMPLE_RATE; - s_AudioQueue.dataFormat.mFormatID = kAudioFormatLinearPCM; - s_AudioQueue.dataFormat.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked; - s_AudioQueue.dataFormat.mBytesPerPacket = 4; - s_AudioQueue.dataFormat.mFramesPerPacket = 1; - s_AudioQueue.dataFormat.mBytesPerFrame = 4; - s_AudioQueue.dataFormat.mChannelsPerFrame = 2; - s_AudioQueue.dataFormat.mBitsPerChannel = 16; - s_AudioQueue.frameCount = WAVE_BUFFER_SIZE; - - if (AudioQueueNewOutput(&s_AudioQueue.dataFormat, AQBufferCallback, &s_AudioQueue, 0, kCFRunLoopCommonModes, 0, &s_AudioQueue.queue)) { - printf("Couldn't set the AudioQueue callback!\n"); - _mixer->setReady(false); - return; - } - - uint32 bufferBytes = s_AudioQueue.frameCount * s_AudioQueue.dataFormat.mBytesPerFrame; - - for (int i = 0; i < AUDIO_BUFFERS; i++) { - if (AudioQueueAllocateBuffer(s_AudioQueue.queue, bufferBytes, &s_AudioQueue.buffers[i])) { - printf("Error allocating AudioQueue buffer!\n"); - _mixer->setReady(false); - return; - } - - AQBufferCallback(&s_AudioQueue, s_AudioQueue.queue, s_AudioQueue.buffers[i]); - } - - AudioQueueSetParameter(s_AudioQueue.queue, kAudioQueueParam_Volume, 1.0); - if (AudioQueueStart(s_AudioQueue.queue, NULL)) { - printf("Error starting the AudioQueue!\n"); - _mixer->setReady(false); - return; - } - - _mixer->setOutputRate(AUDIO_SAMPLE_RATE); - _mixer->setReady(true); -} - -void OSystem_IPHONE::stopSoundsystem() { - AudioQueueStop(s_AudioQueue.queue, true); - - for (int i = 0; i < AUDIO_BUFFERS; i++) { - AudioQueueFreeBuffer(s_AudioQueue.queue, s_AudioQueue.buffers[i]); - } - - AudioQueueDispose(s_AudioQueue.queue, true); - _mixer->setReady(false); -} - -int OSystem_IPHONE::getOutputSampleRate() const { - return AUDIO_SAMPLE_RATE; -} - -void OSystem_IPHONE::setTimerCallback(TimerProc callback, int interval) { - //printf("setTimerCallback()\n"); - - if (callback != NULL) { - _timerCallbackTimer = interval; - _timerCallbackNext = getMillis() + interval; - _timerCallback = callback; - } else - _timerCallback = NULL; -} - -void OSystem_IPHONE::quit() { -} - -void OSystem_IPHONE::getTimeAndDate(struct tm &t) const { - time_t curTime = time(0); - t = *localtime(&curTime); -} - -Common::SaveFileManager *OSystem_IPHONE::getSavefileManager() { - assert(_savefile); - return _savefile; -} - -Audio::Mixer *OSystem_IPHONE::getMixer() { - assert(_mixer); - return _mixer; -} - -Common::TimerManager *OSystem_IPHONE::getTimerManager() { - assert(_timer); - return _timer; -} - -OSystem *OSystem_IPHONE_create() { - return new OSystem_IPHONE(); -} - -Common::SeekableReadStream *OSystem_IPHONE::createConfigReadStream() { -#ifdef IPHONE_OFFICIAL - char buf[256]; - strncpy(buf, iPhone_getDocumentsDir(), 256); - strncat(buf, "/Preferences", 256 - strlen(buf) ); - Common::FSNode file(buf); -#else - Common::FSNode file(SCUMMVM_PREFS_PATH); -#endif - return file.createReadStream(); -} - -Common::WriteStream *OSystem_IPHONE::createConfigWriteStream() { -#ifdef IPHONE_OFFICIAL - char buf[256]; - strncpy(buf, iPhone_getDocumentsDir(), 256); - strncat(buf, "/Preferences", 256 - strlen(buf) ); - Common::FSNode file(buf); -#else - Common::FSNode file(SCUMMVM_PREFS_PATH); -#endif - return file.createWriteStream(); -} - -void OSystem_IPHONE::addSysArchivesToSearchSet(Common::SearchSet &s, int priority) { - // Get URL of the Resource directory of the .app bundle - CFURLRef fileUrl = CFBundleCopyResourcesDirectoryURL(CFBundleGetMainBundle()); - if (fileUrl) { - // Try to convert the URL to an absolute path - UInt8 buf[MAXPATHLEN]; - if (CFURLGetFileSystemRepresentation(fileUrl, true, buf, sizeof(buf))) { - // Success: Add it to the search path - Common::String bundlePath((const char *)buf); - s.add("__OSX_BUNDLE__", new Common::FSDirectory(bundlePath), priority); - } - CFRelease(fileUrl); - } -} - -void iphone_main(int argc, char *argv[]) { - - //OSystem_IPHONE::migrateApp(); - - FILE *newfp = fopen("/var/mobile/.scummvm.log", "a"); - if (newfp != NULL) { - fclose(stdout); - fclose(stderr); - *stdout = *newfp; - *stderr = *newfp; - setbuf(stdout, NULL); - setbuf(stderr, NULL); - - //extern int gDebugLevel; - //gDebugLevel = 10; - } - -#ifdef IPHONE_OFFICIAL - chdir( iPhone_getDocumentsDir() ); -#else - system("mkdir " SCUMMVM_ROOT_PATH); - system("mkdir " SCUMMVM_SAVE_PATH); - - chdir("/var/mobile/"); -#endif - - g_system = OSystem_IPHONE_create(); - assert(g_system); - - // Invoke the actual ScummVM main entry point: - scummvm_main(argc, argv); - g_system->quit(); // TODO: Consider removing / replacing this! -} diff --git a/backends/platform/iphone/osys_main.cpp b/backends/platform/iphone/osys_main.cpp new file mode 100644 index 0000000000..eb2ecf8769 --- /dev/null +++ b/backends/platform/iphone/osys_main.cpp @@ -0,0 +1,296 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#include <unistd.h> +#include <pthread.h> + +#include <sys/time.h> + +#include "common/scummsys.h" +#include "common/util.h" +#include "common/rect.h" +#include "common/file.h" +#include "common/fs.h" + +#include "base/main.h" + +#include "backends/saves/default/default-saves.h" +#include "backends/timer/default/default-timer.h" +#include "sound/mixer.h" +#include "sound/mixer_intern.h" + +#include "osys_main.h" + + +const OSystem::GraphicsMode OSystem_IPHONE::s_supportedGraphicsModes[] = { + {0, 0, 0} +}; + +AQCallbackStruct OSystem_IPHONE::s_AudioQueue; +SoundProc OSystem_IPHONE::s_soundCallback = NULL; +void *OSystem_IPHONE::s_soundParam = NULL; + +OSystem_IPHONE::OSystem_IPHONE() : + _savefile(NULL), _mixer(NULL), _timer(NULL), _offscreen(NULL), + _overlayVisible(false), _overlayBuffer(NULL), _fullscreen(NULL), + _mouseHeight(0), _mouseWidth(0), _mouseBuf(NULL), _lastMouseTap(0), + _secondaryTapped(false), _lastSecondaryTap(0), _screenOrientation(kScreenOrientationFlippedLandscape), + _needEventRestPeriod(false), _mouseClickAndDragEnabled(false), _touchpadModeEnabled(true), + _gestureStartX(-1), _gestureStartY(-1), _fullScreenIsDirty(false), _fullScreenOverlayIsDirty(false), + _mouseDirty(false), _timeSuspended(0), _lastDragPosX(-1), _lastDragPosY(-1), _screenChangeCount(0) + +{ + _queuedInputEvent.type = (Common::EventType)0; + _lastDrawnMouseRect = Common::Rect(0, 0, 0, 0); + + _fsFactory = new POSIXFilesystemFactory(); +} + +OSystem_IPHONE::~OSystem_IPHONE() { + AudioQueueDispose(s_AudioQueue.queue, true); + + delete _fsFactory; + delete _savefile; + delete _mixer; + delete _timer; + delete _offscreen; + delete _fullscreen; +} + +int OSystem_IPHONE::timerHandler(int t) { + DefaultTimerManager *tm = (DefaultTimerManager *)g_system->getTimerManager(); + tm->handler(); + return t; +} + +void OSystem_IPHONE::initBackend() { +#ifdef IPHONE_OFFICIAL + _savefile = new DefaultSaveFileManager(iPhone_getDocumentsDir()); +#else + _savefile = new DefaultSaveFileManager(SCUMMVM_SAVE_PATH); +#endif + + _timer = new DefaultTimerManager(); + + gettimeofday(&_startTime, NULL); + + setupMixer(); + + setTimerCallback(&OSystem_IPHONE::timerHandler, 10); + + OSystem::initBackend(); +} + +bool OSystem_IPHONE::hasFeature(Feature f) { + return false; +} + +void OSystem_IPHONE::setFeatureState(Feature f, bool enable) { +} + +bool OSystem_IPHONE::getFeatureState(Feature f) { + return false; +} + +void OSystem_IPHONE::suspendLoop() { + bool done = false; + int eventType; + float xUnit, yUnit; + uint32 startTime = getMillis(); + + stopSoundsystem(); + + while (!done) { + if (iPhone_fetchEvent(&eventType, &xUnit, &yUnit)) + if ((InputEvent)eventType == kInputApplicationResumed) + done = true; + usleep(100000); + } + + startSoundsystem(); + + _timeSuspended += getMillis() - startTime; +} + +uint32 OSystem_IPHONE::getMillis() { + //printf("getMillis()\n"); + + struct timeval currentTime; + gettimeofday(¤tTime, NULL); + return (uint32)(((currentTime.tv_sec - _startTime.tv_sec) * 1000) + + ((currentTime.tv_usec - _startTime.tv_usec) / 1000)) - _timeSuspended; +} + +void OSystem_IPHONE::delayMillis(uint msecs) { + //printf("delayMillis(%d)\n", msecs); + usleep(msecs * 1000); +} + +OSystem::MutexRef OSystem_IPHONE::createMutex(void) { + pthread_mutexattr_t attr; + pthread_mutexattr_init(&attr); + pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); + + pthread_mutex_t *mutex = (pthread_mutex_t *) malloc(sizeof(pthread_mutex_t)); + if (pthread_mutex_init(mutex, &attr) != 0) { + printf("pthread_mutex_init() failed!\n"); + free(mutex); + return NULL; + } + + return (MutexRef)mutex; +} + +void OSystem_IPHONE::lockMutex(MutexRef mutex) { + if (pthread_mutex_lock((pthread_mutex_t *) mutex) != 0) { + printf("pthread_mutex_lock() failed!\n"); + } +} + +void OSystem_IPHONE::unlockMutex(MutexRef mutex) { + if (pthread_mutex_unlock((pthread_mutex_t *) mutex) != 0) { + printf("pthread_mutex_unlock() failed!\n"); + } +} + +void OSystem_IPHONE::deleteMutex(MutexRef mutex) { + if (pthread_mutex_destroy((pthread_mutex_t *) mutex) != 0) { + printf("pthread_mutex_destroy() failed!\n"); + } else { + free(mutex); + } +} + + +void OSystem_IPHONE::setTimerCallback(TimerProc callback, int interval) { + //printf("setTimerCallback()\n"); + + if (callback != NULL) { + _timerCallbackTimer = interval; + _timerCallbackNext = getMillis() + interval; + _timerCallback = callback; + } else + _timerCallback = NULL; +} + +void OSystem_IPHONE::quit() { +} + +void OSystem_IPHONE::getTimeAndDate(struct tm &t) const { + time_t curTime = time(0); + t = *localtime(&curTime); +} + +Common::SaveFileManager *OSystem_IPHONE::getSavefileManager() { + assert(_savefile); + return _savefile; +} + +Audio::Mixer *OSystem_IPHONE::getMixer() { + assert(_mixer); + return _mixer; +} + +Common::TimerManager *OSystem_IPHONE::getTimerManager() { + assert(_timer); + return _timer; +} + +OSystem *OSystem_IPHONE_create() { + return new OSystem_IPHONE(); +} + +Common::SeekableReadStream *OSystem_IPHONE::createConfigReadStream() { +#ifdef IPHONE_OFFICIAL + char buf[256]; + strncpy(buf, iPhone_getDocumentsDir(), 256); + strncat(buf, "/Preferences", 256 - strlen(buf) ); + Common::FSNode file(buf); +#else + Common::FSNode file(SCUMMVM_PREFS_PATH); +#endif + return file.createReadStream(); +} + +Common::WriteStream *OSystem_IPHONE::createConfigWriteStream() { +#ifdef IPHONE_OFFICIAL + char buf[256]; + strncpy(buf, iPhone_getDocumentsDir(), 256); + strncat(buf, "/Preferences", 256 - strlen(buf) ); + Common::FSNode file(buf); +#else + Common::FSNode file(SCUMMVM_PREFS_PATH); +#endif + return file.createWriteStream(); +} + +void OSystem_IPHONE::addSysArchivesToSearchSet(Common::SearchSet &s, int priority) { + // Get URL of the Resource directory of the .app bundle + CFURLRef fileUrl = CFBundleCopyResourcesDirectoryURL(CFBundleGetMainBundle()); + if (fileUrl) { + // Try to convert the URL to an absolute path + UInt8 buf[MAXPATHLEN]; + if (CFURLGetFileSystemRepresentation(fileUrl, true, buf, sizeof(buf))) { + // Success: Add it to the search path + Common::String bundlePath((const char *)buf); + s.add("__OSX_BUNDLE__", new Common::FSDirectory(bundlePath), priority); + } + CFRelease(fileUrl); + } +} + +void iphone_main(int argc, char *argv[]) { + + //OSystem_IPHONE::migrateApp(); + + FILE *newfp = fopen("/var/mobile/.scummvm.log", "a"); + if (newfp != NULL) { + fclose(stdout); + fclose(stderr); + *stdout = *newfp; + *stderr = *newfp; + setbuf(stdout, NULL); + setbuf(stderr, NULL); + + //extern int gDebugLevel; + //gDebugLevel = 10; + } + +#ifdef IPHONE_OFFICIAL + chdir( iPhone_getDocumentsDir() ); +#else + system("mkdir " SCUMMVM_ROOT_PATH); + system("mkdir " SCUMMVM_SAVE_PATH); + + chdir("/var/mobile/"); +#endif + + g_system = OSystem_IPHONE_create(); + assert(g_system); + + // Invoke the actual ScummVM main entry point: + scummvm_main(argc, argv); + g_system->quit(); // TODO: Consider removing / replacing this! +} diff --git a/backends/platform/iphone/osys_iphone.h b/backends/platform/iphone/osys_main.h index 705f89319a..705f89319a 100644 --- a/backends/platform/iphone/osys_iphone.h +++ b/backends/platform/iphone/osys_main.h diff --git a/backends/platform/iphone/osys_sound.cpp b/backends/platform/iphone/osys_sound.cpp new file mode 100644 index 0000000000..60b8d04a9b --- /dev/null +++ b/backends/platform/iphone/osys_sound.cpp @@ -0,0 +1,111 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#include "osys_main.h" + +void OSystem_IPHONE::AQBufferCallback(void *in, AudioQueueRef inQ, AudioQueueBufferRef outQB) { + //printf("AQBufferCallback()\n"); + if (s_AudioQueue.frameCount > 0 && s_soundCallback != NULL) { + outQB->mAudioDataByteSize = 4 * s_AudioQueue.frameCount; + s_soundCallback(s_soundParam, (byte *)outQB->mAudioData, outQB->mAudioDataByteSize); + AudioQueueEnqueueBuffer(inQ, outQB, 0, NULL); + } else { + AudioQueueStop(s_AudioQueue.queue, false); + } +} + +void OSystem_IPHONE::mixCallback(void *sys, byte *samples, int len) { + OSystem_IPHONE *this_ = (OSystem_IPHONE *)sys; + assert(this_); + + if (this_->_mixer) { + this_->_mixer->mixCallback(samples, len); + } +} + +void OSystem_IPHONE::setupMixer() { + //printf("setSoundCallback()\n"); + _mixer = new Audio::MixerImpl(this); + + s_soundCallback = mixCallback; + s_soundParam = this; + + startSoundsystem(); +} + +void OSystem_IPHONE::startSoundsystem() { + s_AudioQueue.dataFormat.mSampleRate = AUDIO_SAMPLE_RATE; + s_AudioQueue.dataFormat.mFormatID = kAudioFormatLinearPCM; + s_AudioQueue.dataFormat.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked; + s_AudioQueue.dataFormat.mBytesPerPacket = 4; + s_AudioQueue.dataFormat.mFramesPerPacket = 1; + s_AudioQueue.dataFormat.mBytesPerFrame = 4; + s_AudioQueue.dataFormat.mChannelsPerFrame = 2; + s_AudioQueue.dataFormat.mBitsPerChannel = 16; + s_AudioQueue.frameCount = WAVE_BUFFER_SIZE; + + if (AudioQueueNewOutput(&s_AudioQueue.dataFormat, AQBufferCallback, &s_AudioQueue, 0, kCFRunLoopCommonModes, 0, &s_AudioQueue.queue)) { + printf("Couldn't set the AudioQueue callback!\n"); + _mixer->setReady(false); + return; + } + + uint32 bufferBytes = s_AudioQueue.frameCount * s_AudioQueue.dataFormat.mBytesPerFrame; + + for (int i = 0; i < AUDIO_BUFFERS; i++) { + if (AudioQueueAllocateBuffer(s_AudioQueue.queue, bufferBytes, &s_AudioQueue.buffers[i])) { + printf("Error allocating AudioQueue buffer!\n"); + _mixer->setReady(false); + return; + } + + AQBufferCallback(&s_AudioQueue, s_AudioQueue.queue, s_AudioQueue.buffers[i]); + } + + AudioQueueSetParameter(s_AudioQueue.queue, kAudioQueueParam_Volume, 1.0); + if (AudioQueueStart(s_AudioQueue.queue, NULL)) { + printf("Error starting the AudioQueue!\n"); + _mixer->setReady(false); + return; + } + + _mixer->setOutputRate(AUDIO_SAMPLE_RATE); + _mixer->setReady(true); +} + +void OSystem_IPHONE::stopSoundsystem() { + AudioQueueStop(s_AudioQueue.queue, true); + + for (int i = 0; i < AUDIO_BUFFERS; i++) { + AudioQueueFreeBuffer(s_AudioQueue.queue, s_AudioQueue.buffers[i]); + } + + AudioQueueDispose(s_AudioQueue.queue, true); + _mixer->setReady(false); +} + +int OSystem_IPHONE::getOutputSampleRate() const { + return AUDIO_SAMPLE_RATE; +} diff --git a/backends/platform/iphone/osys_video.cpp b/backends/platform/iphone/osys_video.cpp new file mode 100644 index 0000000000..641c341f50 --- /dev/null +++ b/backends/platform/iphone/osys_video.cpp @@ -0,0 +1,463 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#include "osys_main.h" + +const OSystem::GraphicsMode* OSystem_IPHONE::getSupportedGraphicsModes() const { + return s_supportedGraphicsModes; +} + + +int OSystem_IPHONE::getDefaultGraphicsMode() const { + return -1; +} + +bool OSystem_IPHONE::setGraphicsMode(const char *mode) { + return true; +} + +bool OSystem_IPHONE::setGraphicsMode(int mode) { + return true; +} + +int OSystem_IPHONE::getGraphicsMode() const { + return -1; +} + +void OSystem_IPHONE::initSize(uint width, uint height) { + //printf("initSize(%i, %i)\n", width, height); + + _screenWidth = width; + _screenHeight = height; + + free(_offscreen); + + _offscreen = (byte *)malloc(width * height); + bzero(_offscreen, width * height); + + free(_overlayBuffer); + + int fullSize = _screenWidth * _screenHeight * sizeof(OverlayColor); + _overlayBuffer = (OverlayColor *)malloc(fullSize); + clearOverlay(); + + free(_fullscreen); + + _fullscreen = (uint16 *)malloc(fullSize); + bzero(_fullscreen, fullSize); + + iPhone_initSurface(width, height); + + _fullScreenIsDirty = false; + dirtyFullScreen(); + _mouseVisible = false; + _screenChangeCount++; + updateScreen(); +} + +int16 OSystem_IPHONE::getHeight() { + return _screenHeight; +} + +int16 OSystem_IPHONE::getWidth() { + return _screenWidth; +} + +void OSystem_IPHONE::setPalette(const byte *colors, uint start, uint num) { + //printf("setPalette()\n"); + const byte *b = colors; + + for (uint i = start; i < start + num; ++i) { + _palette[i] = Graphics::RGBToColor<Graphics::ColorMasks<565> >(b[0], b[1], b[2]); + b += 4; + } + + dirtyFullScreen(); +} + +void OSystem_IPHONE::grabPalette(byte *colors, uint start, uint num) { + //printf("grabPalette()\n"); +} + +void OSystem_IPHONE::copyRectToScreen(const byte *buf, int pitch, int x, int y, int w, int h) { + //printf("copyRectToScreen(%i, %i, %i, %i)\n", x, y, w, 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; + + if (!_fullScreenIsDirty) { + _dirtyRects.push_back(Common::Rect(x, y, x + w, y + h)); + } + + + byte *dst = _offscreen + y * _screenWidth + x; + if (_screenWidth == pitch && pitch == w) + memcpy(dst, buf, h * w); + else { + do { + memcpy(dst, buf, w); + buf += pitch; + dst += _screenWidth; + } while (--h); + } +} + +void OSystem_IPHONE::clipRectToScreen(int16 &x, int16 &y, int16 &w, int16 &h) { + if (x < 0) { + w += x; + x = 0; + } + + if (y < 0) { + h += y; + y = 0; + } + + if (w > _screenWidth - x) + w = _screenWidth - x; + + if (h > _screenHeight - y) + h = _screenHeight - y; + + if (w < 0) { + w = 0; + } + + if (h < 0) { + h = 0; + } +} + +void OSystem_IPHONE::updateScreen() { + //printf("updateScreen(): %i dirty rects.\n", _dirtyRects.size()); + + if (_dirtyRects.size() == 0 && _dirtyOverlayRects.size() == 0 && !_mouseDirty) + return; + + internUpdateScreen(); + _fullScreenIsDirty = false; + _fullScreenOverlayIsDirty = false; + + iPhone_updateScreen(); +} + +void OSystem_IPHONE::internUpdateScreen() { + int16 mouseX = _mouseX - _mouseHotspotX; + int16 mouseY = _mouseY - _mouseHotspotY; + int16 mouseWidth = _mouseWidth; + int16 mouseHeight = _mouseHeight; + + clipRectToScreen(mouseX, mouseY, mouseWidth, mouseHeight); + + Common::Rect mouseRect(mouseX, mouseY, mouseX + mouseWidth, mouseY + mouseHeight); + + if (_mouseDirty) { + if (!_fullScreenIsDirty) { + _dirtyRects.push_back(_lastDrawnMouseRect); + _dirtyRects.push_back(mouseRect); + } + if (!_fullScreenOverlayIsDirty && _overlayVisible) { + _dirtyOverlayRects.push_back(_lastDrawnMouseRect); + _dirtyOverlayRects.push_back(mouseRect); + } + _mouseDirty = false; + _lastDrawnMouseRect = mouseRect; + } + + while (_dirtyRects.size()) { + Common::Rect dirtyRect = _dirtyRects.remove_at(_dirtyRects.size() - 1); + + //printf("Drawing: (%i, %i) -> (%i, %i)\n", dirtyRect.left, dirtyRect.top, dirtyRect.right, dirtyRect.bottom); + + drawDirtyRect(dirtyRect); + + if (_overlayVisible) + drawDirtyOverlayRect(dirtyRect); + + drawMouseCursorOnRectUpdate(dirtyRect, mouseRect); + updateHardwareSurfaceForRect(dirtyRect); + } + + if (_overlayVisible) { + while (_dirtyOverlayRects.size()) { + Common::Rect dirtyRect = _dirtyOverlayRects.remove_at(_dirtyOverlayRects.size() - 1); + + //printf("Drawing: (%i, %i) -> (%i, %i)\n", dirtyRect.left, dirtyRect.top, dirtyRect.right, dirtyRect.bottom); + + drawDirtyOverlayRect(dirtyRect); + drawMouseCursorOnRectUpdate(dirtyRect, mouseRect); + updateHardwareSurfaceForRect(dirtyRect); + } + } +} + +void OSystem_IPHONE::drawDirtyRect(const Common::Rect& dirtyRect) { + int h = dirtyRect.bottom - dirtyRect.top; + int w = dirtyRect.right - dirtyRect.left; + + byte *src = &_offscreen[dirtyRect.top * _screenWidth + dirtyRect.left]; + uint16 *dst = &_fullscreen[dirtyRect.top * _screenWidth + dirtyRect.left]; + for (int y = h; y > 0; y--) { + for (int x = w; x > 0; x--) + *dst++ = _palette[*src++]; + + dst += _screenWidth - w; + src += _screenWidth - w; + } +} + +void OSystem_IPHONE::drawDirtyOverlayRect(const Common::Rect& dirtyRect) { + int h = dirtyRect.bottom - dirtyRect.top; + + uint16 *src = (uint16 *)&_overlayBuffer[dirtyRect.top * _screenWidth + dirtyRect.left]; + uint16 *dst = &_fullscreen[dirtyRect.top * _screenWidth + dirtyRect.left]; + int x = (dirtyRect.right - dirtyRect.left) * 2; + for (int y = h; y > 0; y--) { + memcpy(dst, src, x); + src += _screenWidth; + dst += _screenWidth; + } +} + +void OSystem_IPHONE::drawMouseCursorOnRectUpdate(const Common::Rect& updatedRect, const Common::Rect& mouseRect) { + //draw mouse on top + if (_mouseVisible && (updatedRect.intersects(mouseRect))) { + int srcX = 0; + int srcY = 0; + int left = _mouseX - _mouseHotspotX; + if (left < 0) { + srcX -= left; + left = 0; + } + int top = _mouseY - _mouseHotspotY; + if (top < 0) { + srcY -= top; + top = 0; + } + //int right = left + _mouseWidth; + int bottom = top + _mouseHeight; + if (bottom > _screenWidth) + bottom = _screenWidth; + int displayWidth = _mouseWidth; + if (_mouseWidth + left > _screenWidth) + displayWidth = _screenWidth - left; + int displayHeight = _mouseHeight; + if (_mouseHeight + top > _screenHeight) + displayHeight = _screenHeight - top; + byte *src = &_mouseBuf[srcY * _mouseWidth + srcX]; + uint16 *dst = &_fullscreen[top * _screenWidth + left]; + for (int y = displayHeight; y > srcY; y--) { + for (int x = displayWidth; x > srcX; x--) { + if (*src != _mouseKeyColour) + *dst = _palette[*src]; + dst++; + src++; + } + dst += _screenWidth - displayWidth + srcX; + src += _mouseWidth - displayWidth + srcX; + } + } +} + +void OSystem_IPHONE::updateHardwareSurfaceForRect(const Common::Rect& updatedRect) { + iPhone_updateScreenRect(_fullscreen, updatedRect.left, updatedRect.top, updatedRect.right, updatedRect.bottom ); +} + +Graphics::Surface *OSystem_IPHONE::lockScreen() { + //printf("lockScreen()\n"); + + _framebuffer.pixels = _offscreen; + _framebuffer.w = _screenWidth; + _framebuffer.h = _screenHeight; + _framebuffer.pitch = _screenWidth; + _framebuffer.bytesPerPixel = 1; + + return &_framebuffer; +} + +void OSystem_IPHONE::unlockScreen() { + //printf("unlockScreen()\n"); + dirtyFullScreen(); +} + +void OSystem_IPHONE::setShakePos(int shakeOffset) { + //printf("setShakePos(%i)\n", shakeOffset); +} + +void OSystem_IPHONE::showOverlay() { + //printf("showOverlay()\n"); + _overlayVisible = true; + dirtyFullOverlayScreen(); +} + +void OSystem_IPHONE::hideOverlay() { + //printf("hideOverlay()\n"); + _overlayVisible = false; + _dirtyOverlayRects.clear(); + dirtyFullScreen(); +} + +void OSystem_IPHONE::clearOverlay() { + //printf("clearOverlay()\n"); + bzero(_overlayBuffer, _screenWidth * _screenHeight * sizeof(OverlayColor)); + dirtyFullOverlayScreen(); +} + +void OSystem_IPHONE::grabOverlay(OverlayColor *buf, int pitch) { + //printf("grabOverlay()\n"); + int h = _screenHeight; + OverlayColor *src = _overlayBuffer; + + do { + memcpy(buf, src, _screenWidth * sizeof(OverlayColor)); + src += _screenWidth; + buf += pitch; + } while (--h); +} + +void OSystem_IPHONE::copyRectToOverlay(const OverlayColor *buf, int pitch, int x, int y, int w, int h) { + //printf("copyRectToOverlay(buf, pitch=%i, x=%i, y=%i, w=%i, h=%i)\n", pitch, x, y, w, 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; + + if (!_fullScreenOverlayIsDirty) { + _dirtyOverlayRects.push_back(Common::Rect(x, y, x + w, y + h)); + } + + OverlayColor *dst = _overlayBuffer + (y * _screenWidth + x); + if (_screenWidth == pitch && pitch == w) + memcpy(dst, buf, h * w * sizeof(OverlayColor)); + else { + do { + memcpy(dst, buf, w * sizeof(OverlayColor)); + buf += pitch; + dst += _screenWidth; + } while (--h); + } +} + +int16 OSystem_IPHONE::getOverlayHeight() { + return _screenHeight; +} + +int16 OSystem_IPHONE::getOverlayWidth() { + return _screenWidth; +} + +bool OSystem_IPHONE::showMouse(bool visible) { + bool last = _mouseVisible; + _mouseVisible = visible; + _mouseDirty = true; + + return last; +} + +void OSystem_IPHONE::warpMouse(int x, int y) { + //printf("warpMouse()\n"); + + _mouseX = x; + _mouseY = y; + _mouseDirty = true; +} + +void OSystem_IPHONE::dirtyFullScreen() { + if (!_fullScreenIsDirty) { + _dirtyRects.clear(); + _dirtyRects.push_back(Common::Rect(0, 0, _screenWidth, _screenHeight)); + _fullScreenIsDirty = true; + } +} + +void OSystem_IPHONE::dirtyFullOverlayScreen() { + if (!_fullScreenOverlayIsDirty) { + _dirtyOverlayRects.clear(); + _dirtyOverlayRects.push_back(Common::Rect(0, 0, _screenWidth, _screenHeight)); + _fullScreenOverlayIsDirty = true; + } +} + +void OSystem_IPHONE::setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, byte keycolor, int cursorTargetScale) { + //printf("setMouseCursor(%i, %i)\n", hotspotX, hotspotY); + + if (_mouseBuf != NULL && (_mouseWidth != w || _mouseHeight != h)) { + free(_mouseBuf); + _mouseBuf = NULL; + } + + if (_mouseBuf == NULL) + _mouseBuf = (byte *)malloc(w * h); + + _mouseWidth = w; + _mouseHeight = h; + + _mouseHotspotX = hotspotX; + _mouseHotspotY = hotspotY; + + _mouseKeyColour = keycolor; + + memcpy(_mouseBuf, buf, w * h); + + _mouseDirty = true; +} diff --git a/backends/platform/wince/CEScaler.cpp b/backends/platform/wince/CEScaler.cpp index 4cc675e006..bfdb74319d 100644 --- a/backends/platform/wince/CEScaler.cpp +++ b/backends/platform/wince/CEScaler.cpp @@ -53,6 +53,15 @@ void PocketPCPortraitTemplate(const uint8 *srcPtr, uint32 srcPitch, uint8 *dstPt } MAKE_WRAPPER(PocketPCPortrait) +void PocketPCRawPortrait(const uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height) { + + while (height--) { + memcpy(dstPtr, srcPtr, width*sizeof(uint16_t)); + srcPtr += srcPitch; + dstPtr += dstPitch; + } +} + // Our version of an aspect scaler. Main difference is the out-of-place // operation, omitting a straight blit step the sdl backend does. Also, // tests show unaligned access errors with the stock aspect scaler. @@ -117,6 +126,7 @@ void PocketPCLandscapeAspect(const uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr #ifdef ARM extern "C" { void PocketPCHalfARM(const uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height, int mask, int round); + void SmartphoneLandscapeARM(const uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height, int mask); // Rounding constants and masks used for different pixel formats int roundingconstants[] = { 0x00200802, 0x00201002 }; int redbluegreenMasks[] = { 0x03E07C1F, 0x07E0F81F }; @@ -156,7 +166,7 @@ void PocketPCHalf(const uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 ds if (gBitFormat == 565) PocketPCHalfTemplate<565>(srcPtr, srcPitch, dstPtr, dstPitch, width, height); else - PocketPCHalfTemplate<565>(srcPtr, srcPitch, dstPtr, dstPitch, width, height); + PocketPCHalfTemplate<555>(srcPtr, srcPitch, dstPtr, dstPitch, width, height); #endif } @@ -217,4 +227,15 @@ void SmartphoneLandscapeTemplate(const uint8 *srcPtr, uint32 srcPitch, uint8 *ds } } } -MAKE_WRAPPER(SmartphoneLandscape) + +void SmartphoneLandscape(const uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height) { +#ifdef ARM + int maskUsed = (gBitFormat == 565); + SmartphoneLandscapeARM(srcPtr, srcPitch, dstPtr, dstPitch, width, height, redbluegreenMasks[maskUsed]); +#else + if (gBitFormat == 565) + SmartphoneLandscape<565>(srcPtr, srcPitch, dstPtr, dstPitch, width, height); + else + SmartphoneLandscape<555>(srcPtr, srcPitch, dstPtr, dstPitch, width, height); +#endif +} diff --git a/backends/platform/wince/Makefile b/backends/platform/wince/Makefile index 532bc69ef4..1846029469 100644 --- a/backends/platform/wince/Makefile +++ b/backends/platform/wince/Makefile @@ -186,6 +186,7 @@ OBJS += $(srcdir)/gui/Actions.o $(srcdir)/gui/Key.o $(srcdir)/gui/KeysDialog.o OBJS += ../sdl/sdl.o ../sdl/graphics.o ../sdl/events.o ../sdl/hardwarekeys.o OBJS += missing/missing.o OBJS += ARMscaler.o +OBJS += smartLandScale.o ifndef DYNAMIC_MODULES OBJS += PocketSCUMM.o endif diff --git a/backends/platform/wince/smartLandScale.s b/backends/platform/wince/smartLandScale.s new file mode 100755 index 0000000000..deeb093329 --- /dev/null +++ b/backends/platform/wince/smartLandScale.s @@ -0,0 +1,187 @@ +@ ScummVM Scumm Interpreter +@ Copyright (C) 2009 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +@ +@ $URL$ +@ $Id$ +@ +@ @author Robin Watts (robin@wss.co.uk) + + @ For 16 source pixels 0123456789ABCDEF, we want to produce 11 output + @ pixels. + + @0000000000011111111111222222222223333333333344444444444555555555 + @<------||------><------||------><------||------><------||------> + + @5566666666666777777777778888888888899999999999AAAAAAAAAAABBBBBBB + @<------||------><------||------><------||------><------||------> + + @BBBBCCCCCCCCCCCDDDDDDDDDDDEEEEEEEEEEEFFFFFFFFFFF + @<------||------><------||------><------||------> + + @ So, use the following weights (approximately right) + + @ d0 = (3*s0 + 1*s1)>>2 Every source pixel constitutes + @ d1 = (2*s1 + 2*s2)>>2 3/4 of a destination pixel, + @ d2 = (1*s2 + 3*s3)>>2 except for s4,s5,sA and sB which + @ d3 = (2*s4 + 2*s5)>>2 constitute 1/2 each. + @ d4 = (3*s6 + 1*s7)>>2 + @ d5 = (2*s7 + 2*s8)>>2 + @ d6 = (1*s8 + 3*s9)>>2 + @ d7 = (2*sA + 2*sB)>>2 + @ d8 = (3*sC + 1*sD)>>2 + @ d9 = (2*sD + 2*sE)>>2 + @ dA = (1*sE + 3*sF)>>2 + + .text + + .global SmartphoneLandscapeARM + + @ scales a width x height block of 16bpp pixels from srcPtr to dstPtr, + @ scaling each scanline down by 11/16ths. Every 8th scanline is dropped + @ srcPitch and dstPitch identify how to reach subsequent lines. + @ mask allows for one routine to do both 565 and 565 formats. + +SmartphoneLandscapeARM: + @ r0 = srcPtr + @ r1 = srcSpan + @ r2 = dstPtr + @ r3 = dstSpan + @ <> = width + @ <> = height + @ <> = mask + MOV r12,r13 + STMFD r13!,{r4-r11,r14} + LDMFD r12,{r4,r5,r11} @ r4 = width + @ r5 = height + @ r11= mask + MOV r7, #7 @ r7 = line + SUB r8, r1, r4, LSL #1 @ r8 = srcSpan - width*2 +y_loop: + MOV r6, r4 @ r6 = i + MOV r9, r2 @ r9 = dstPtr +x_loop: + LDRH r14,[r0],#2 @ r14 = s0 + LDRH r12,[r0],#2 @ r12 = s1 + LDRH r10,[r0],#2 @ r10 = s2 + ORR r14,r14,r14,LSL #16 @ r14 = s0s0 + ORR r12,r12,r12,LSL #16 @ r12 = s1s1 + AND r14,r14,r11 @ r14 = s0 as g_b_r + AND r12,r12,r11 @ r12 = s1 as g_b_r + ADD r14,r14,r14,LSL #1 @ r14 = s0*3 as g_b_r + ORR r10,r10,r10,LSL #16 @ r10 = s2s2 + ADD r14,r14,r12 @ r14 = (s0*3 + s1) as g_b_r + AND r10,r10,r11 @ r10 = s2 as g_b_r + AND r14,r11,r14,LSR #2 @ r14 = d0 as g_b_r + ORR r14,r14,r14,LSR #16 @ r14 = d0 + STRH r14,[r9],#2 @ store d0 + ADD r12,r12,r10 @ r12 = (s1 + s2) as g_b_r + LDRH r14,[r0],#2 @ r14 = s3 + AND r12,r11,r12,LSR #1 @ r12 = d1 as g_b_r + ORR r12,r12,r12,LSR #16 @ r12 = d1 + STRH r12,[r9],#2 @ store d1 + ORR r14,r14,r14,LSL #16 @ r14 = s3s3 + AND r14,r14,r11 @ r14 = s3 as g_b_r + ADD r10,r10,r14 @ r10 = (s2 + s3) as g_b_r + ADD r10,r10,r14,LSL #1 @ r10 = (s2 + s3*3) as g_b_r + LDRH r14,[r0],#2 @ r14 = s4 + LDRH r12,[r0],#2 @ r12 = s5 + AND r10,r11,r10,LSR #2 @ r10 = d2 as g_b_r + ORR r10,r10,r10,LSR #16 @ r10 = d2 + STRH r10,[r9],#2 @ store d2 + ORR r14,r14,r14,LSL #16 @ r14 = s4s4 + ORR r12,r12,r12,LSL #16 @ r12 = s5s5 + AND r14,r14,r11 @ r14 = s4 as g_b_r + AND r12,r12,r11 @ r12 = s5 as g_b_r + ADD r14,r14,r12 @ r14 = (s4 + s5) as g_b_r + LDRH r12,[r0],#2 @ r12 = s6 + LDRH r10,[r0],#2 @ r10 = s7 + AND r14,r11,r14,LSR #1 @ r14 = d3 as g_b_r + ORR r14,r14,r14,LSR #16 @ r14 = d3 + STRH r14,[r9],#2 @ store d3 + ORR r12,r12,r12,LSL #16 @ r12 = s6s6 + ORR r10,r10,r10,LSL #16 @ r10 = s7s7 + LDRH r14,[r0],#2 @ r14 = s8 + AND r12,r12,r11 @ r12 = s6 as g_b_r + AND r10,r10,r11 @ r10 = s7 as g_b_r + ORR r14,r14,r14,LSL #16 @ r14 = s8s8 + ADD r12,r12,r12,LSL #1 @ r12 = 3*s6 as g_b_r + AND r14,r14,r11 @ r14 = s8 as g_b_r + ADD r12,r12,r10 @ r12 = (3*s6+s7) as g_b_r + AND r12,r11,r12,LSR #2 @ r12 = d4 as g_b_r + ORR r12,r12,r12,LSR #16 @ r12 = d4 + STRH r12,[r9],#2 @ store d4 + ADD r10,r10,r14 @ r10 = (s7+s8) as g_b_r + AND r10,r11,r10,LSR #1 @ r10 = d5 as g_b_r + LDRH r12,[r0],#2 @ r12 = s9 + ORR r10,r10,r10,LSR #16 @ r10 = d5 + STRH r10,[r9],#2 @ store d5 + ORR r12,r12,r12,LSL #16 @ r12 = s9s9 + AND r12,r12,r11 @ r12 = s9 as g_b_r + ADD r12,r12,r12,LSL #1 @ r12 = s9*3 as g_b_r + ADD r12,r12,r14 @ r12 = (s8+s9*3) as g_b_r + AND r12,r11,r12,LSR #2 @ r12 = d6 as g_b_r + LDRH r14,[r0],#2 @ r14 = sA + LDRH r10,[r0],#2 @ r10 = sB + ORR r12,r12,r12,LSR #16 @ r12 = d6 + STRH r12,[r9],#2 @ store d6 + ORR r14,r14,r14,LSL #16 @ r14 = sAsA + ORR r10,r10,r10,LSL #16 @ r10 = sBsB + LDRH r12,[r0],#2 @ r12 = sC + AND r14,r14,r11 @ r14 = sA as g_b_r + AND r10,r10,r11 @ r10 = sB as g_b_r + ORR r12,r12,r12,LSL #16 @ r12 = sCsC + ADD r14,r14,r10 @ r14 = (sA + sB) as g_b_r + LDRH r10,[r0],#2 @ r10 = sD + AND r14,r11,r14,LSR #1 @ r14 = d7 as g_b_r + AND r12,r12,r11 @ r12 = sC as g_b_r + ORR r14,r14,r14,LSR #16 @ r14 = d7 + ORR r10,r10,r10,LSL #16 @ r10 = sDsD + STRH r14,[r9],#2 @ store d7 + AND r10,r10,r11 @ r10 = sD as g_b_r + ADD r12,r12,r12,LSL #1 @ r12 = 3*sC as g_b_r + LDRH r14,[r0],#2 @ r14 = sE + ADD r12,r12,r10 @ r12 = (3*sC+sD) as g_b_r + AND r12,r11,r12,LSR #2 @ r12 = d8 as g_b_r + ORR r14,r14,r14,LSL #16 @ r14 = sEsE + ORR r12,r12,r12,LSR #16 @ r12 = d8 + AND r14,r14,r11 @ r14 = sE as g_b_r + STRH r12,[r9],#2 @ store d8 + ADD r10,r10,r14 @ r10 = (sD+sE) as g_b_r + LDRH r12,[r0],#2 @ r12 = sF + AND r10,r11,r10,LSR #1 @ r10 = d9 as g_b_r + ORR r10,r10,r10,LSR #16 @ r10 = d9 + STRH r10,[r9],#2 @ store d9 + ORR r12,r12,r12,LSL #16 @ r12 = sFsF + AND r12,r12,r11 @ r12 = sF as g_b_r + ADD r12,r12,r12,LSL #1 @ r12 = 3*sF as g_b_r + ADD r12,r12,r14 @ r12 = (sE+3*sF) as g_b_r + AND r12,r11,r12,LSR #2 @ r12 = dA as g_b_r + ORR r12,r12,r12,LSR #16 @ r12 = dA + SUBS r6,r6,#16 @ width -= 16 + STRH r12,[r9],#2 @ store dA + BGT x_loop + + ADD r0, r0, r8 @ srcPtr += srcSpan + ADD r2, r2, r3 @ dstPtr += dstSpan + SUBS r7, r7, #1 + ADDEQ r0, r0, r1 + MOVEQ r7, #7 + SUBEQ r5, r5, #1 + SUBS r5, r5, #1 + BGT y_loop + + LDMFD r13!,{r4-r11,PC} diff --git a/backends/platform/wince/wince-sdl.cpp b/backends/platform/wince/wince-sdl.cpp index 9a4b312631..8b2e0848f8 100644 --- a/backends/platform/wince/wince-sdl.cpp +++ b/backends/platform/wince/wince-sdl.cpp @@ -1209,8 +1209,13 @@ bool OSystem_WINCE3::update_scalers() { if (CEDevice::hasSmartphoneResolution()) { if (_videoMode.screenWidth > 320) error("Game resolution not supported on Smartphone"); +#ifdef ARM + _scaleFactorXm = 11; + _scaleFactorXd = 16; +#else _scaleFactorXm = 2; _scaleFactorXd = 3; +#endif _scaleFactorYm = 7; _scaleFactorYd = 8; _scalerProc = SmartphoneLandscape; diff --git a/common/system.h b/common/system.h index 2dd4293690..0f265ea2be 100644 --- a/common/system.h +++ b/common/system.h @@ -466,10 +466,10 @@ public: */ enum TransactionError { kTransactionSuccess = 0, /**< Everything fine (use EQUAL check for this one!) */ - kTransactionAspectRatioFailed = (1 << 0), /**< Failed switchting aspect ratio correction mode */ - kTransactionFullscreenFailed = (1 << 1), /**< Failed switchting fullscreen mode */ - kTransactionModeSwitchFailed = (1 << 2), /**< Failed switchting the GFX graphics mode (setGraphicsMode) */ - kTransactionSizeChangeFailed = (1 << 3), /**< Failed switchting the screen dimensions (initSize) */ + kTransactionAspectRatioFailed = (1 << 0), /**< Failed switching aspect ratio correction mode */ + kTransactionFullscreenFailed = (1 << 1), /**< Failed switching fullscreen mode */ + kTransactionModeSwitchFailed = (1 << 2), /**< Failed switching the GFX graphics mode (setGraphicsMode) */ + kTransactionSizeChangeFailed = (1 << 3), /**< Failed switching the screen dimensions (initSize) */ kTransactionFormatNotSupported = (1 << 4) /**< Failed setting the color format */ }; diff --git a/common/xmlparser.cpp b/common/xmlparser.cpp index 1385af795b..534007b03d 100644 --- a/common/xmlparser.cpp +++ b/common/xmlparser.cpp @@ -276,126 +276,126 @@ bool XMLParser::parse() { continue; switch (_state) { - case kParserNeedHeader: - case kParserNeedKey: - if (_char != '<') { - parserError("Parser expecting key start."); - break; - } + case kParserNeedHeader: + case kParserNeedKey: + if (_char != '<') { + parserError("Parser expecting key start."); + break; + } + + if ((_char = _stream->readByte()) == 0) { + parserError("Unexpected end of file."); + break; + } - if ((_char = _stream->readByte()) == 0) { - parserError("Unexpected end of file."); + if (_state == kParserNeedHeader) { + if (_char != '?') { + parserError("Expecting XML header."); break; } - if (_state == kParserNeedHeader) { - if (_char != '?') { - parserError("Expecting XML header."); - break; - } + _char = _stream->readByte(); + activeHeader = true; + } else if (_char == '/') { + _char = _stream->readByte(); + activeClosure = true; + } else if (_char == '?') { + parserError("Unexpected header. There may only be one XML header per file."); + break; + } - _char = _stream->readByte(); - activeHeader = true; - } else if (_char == '/') { - _char = _stream->readByte(); - activeClosure = true; - } else if (_char == '?') { - parserError("Unexpected header. There may only be one XML header per file."); - break; - } + _state = kParserNeedKeyName; + break; - _state = kParserNeedKeyName; + case kParserNeedKeyName: + if (!parseToken()) { + parserError("Invalid key name."); break; + } - case kParserNeedKeyName: - if (!parseToken()) { - parserError("Invalid key name."); + if (activeClosure) { + if (_activeKey.empty() || _token != _activeKey.top()->name) { + parserError("Unexpected closure."); break; } - - if (activeClosure) { - if (_activeKey.empty() || _token != _activeKey.top()->name) { - parserError("Unexpected closure."); - break; - } - } else { - ParserNode *node = allocNode(); //new ParserNode; - node->name = _token; - node->ignore = false; - node->header = activeHeader; - node->depth = _activeKey.size(); - node->layout = 0; - _activeKey.push(node); + } else { + ParserNode *node = allocNode(); //new ParserNode; + node->name = _token; + node->ignore = false; + node->header = activeHeader; + node->depth = _activeKey.size(); + node->layout = 0; + _activeKey.push(node); + } + + _state = kParserNeedPropertyName; + break; + + case kParserNeedPropertyName: + if (activeClosure) { + if (!closeKey()) { + parserError("Missing data when closing key '%s'.", _activeKey.top()->name.c_str()); + break; } - _state = kParserNeedPropertyName; - break; - - case kParserNeedPropertyName: - if (activeClosure) { - if (!closeKey()) { - parserError("Missing data when closing key '%s'.", _activeKey.top()->name.c_str()); - break; - } + activeClosure = false; - activeClosure = false; + if (_char != '>') + parserError("Invalid syntax in key closure."); + else + _state = kParserNeedKey; - if (_char != '>') - parserError("Invalid syntax in key closure."); - else - _state = kParserNeedKey; + _char = _stream->readByte(); + break; + } - _char = _stream->readByte(); - break; - } + selfClosure = false; - selfClosure = false; + if (_char == '/' || (_char == '?' && activeHeader)) { + selfClosure = true; + _char = _stream->readByte(); + } - if (_char == '/' || (_char == '?' && activeHeader)) { - selfClosure = true; + if (_char == '>') { + if (activeHeader && !selfClosure) { + parserError("XML Header must be self-closed."); + } else if (parseActiveKey(selfClosure)) { _char = _stream->readByte(); + _state = kParserNeedKey; } - if (_char == '>') { - if (activeHeader && !selfClosure) { - parserError("XML Header must be self-closed."); - } else if (parseActiveKey(selfClosure)) { - _char = _stream->readByte(); - _state = kParserNeedKey; - } + activeHeader = false; + break; + } - activeHeader = false; - break; - } + if (selfClosure) + parserError("Expecting key closure after '/' symbol."); + else if (!parseToken()) + parserError("Error when parsing key value."); + else + _state = kParserNeedPropertyOperator; - if (selfClosure) - parserError("Expecting key closure after '/' symbol."); - else if (!parseToken()) - parserError("Error when parsing key value."); - else - _state = kParserNeedPropertyOperator; + break; - break; + case kParserNeedPropertyOperator: + if (_char != '=') + parserError("Syntax error after key name."); + else + _state = kParserNeedPropertyValue; - case kParserNeedPropertyOperator: - if (_char != '=') - parserError("Syntax error after key name."); - else - _state = kParserNeedPropertyValue; - - _char = _stream->readByte(); - break; + _char = _stream->readByte(); + break; - case kParserNeedPropertyValue: - if (!parseKeyValue(_token)) - parserError("Invalid key value."); - else - _state = kParserNeedPropertyName; + case kParserNeedPropertyValue: + if (!parseKeyValue(_token)) + parserError("Invalid key value."); + else + _state = kParserNeedPropertyName; - break; + break; - default: - break; + default: + break; } } diff --git a/dists/iphone/scummvm.xcodeproj/project.pbxproj b/dists/iphone/scummvm.xcodeproj/project.pbxproj index 9d8b74628a..96c8aa2431 100755 --- a/dists/iphone/scummvm.xcodeproj/project.pbxproj +++ b/dists/iphone/scummvm.xcodeproj/project.pbxproj @@ -91,7 +91,6 @@ DF093EBC0F63CB26002D821E /* audiostream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE477CD0D81F4E900B6D1FB /* audiostream.cpp */; }; DF093EBD0F63CB26002D821E /* flac.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE477CF0D81F4E900B6D1FB /* flac.cpp */; }; DF093EBE0F63CB26002D821E /* fmopl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE477D10D81F4E900B6D1FB /* fmopl.cpp */; }; - DF093EBF0F63CB26002D821E /* iff.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE477D30D81F4E900B6D1FB /* iff.cpp */; }; DF093EC00F63CB26002D821E /* mididrv.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE477D50D81F4E900B6D1FB /* mididrv.cpp */; }; DF093EC10F63CB26002D821E /* midiparser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE477D70D81F4E900B6D1FB /* midiparser.cpp */; }; DF093EC20F63CB26002D821E /* midiparser_smf.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE477D90D81F4E900B6D1FB /* midiparser_smf.cpp */; }; @@ -272,8 +271,6 @@ DF093F740F63CB26002D821E /* draw_v2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421220E7BA6A700F5680E /* draw_v2.cpp */; }; DF093F750F63CB26002D821E /* driver_vga.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421230E7BA6A700F5680E /* driver_vga.cpp */; }; DF093F760F63CB26002D821E /* game.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421250E7BA6A700F5680E /* game.cpp */; }; - DF093F770F63CB26002D821E /* game_v1.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421270E7BA6A700F5680E /* game_v1.cpp */; }; - DF093F780F63CB26002D821E /* game_v2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421280E7BA6A700F5680E /* game_v2.cpp */; }; DF093F790F63CB26002D821E /* global.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421290E7BA6A700F5680E /* global.cpp */; }; DF093F7A0F63CB26002D821E /* gob.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84212B0E7BA6A700F5680E /* gob.cpp */; }; DF093F7B0F63CB26002D821E /* goblin.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84212D0E7BA6A700F5680E /* goblin.cpp */; }; @@ -301,7 +298,6 @@ DF093F910F63CB26002D821E /* mult_v1.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421490E7BA6A700F5680E /* mult_v1.cpp */; }; DF093F920F63CB26002D821E /* mult_v2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84214A0E7BA6A700F5680E /* mult_v2.cpp */; }; DF093F930F63CB26002D821E /* palanim.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84214C0E7BA6A700F5680E /* palanim.cpp */; }; - DF093F940F63CB26002D821E /* parse.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84214E0E7BA6A700F5680E /* parse.cpp */; }; DF093F9B0F63CB26002D821E /* scenery.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421570E7BA6A700F5680E /* scenery.cpp */; }; DF093F9C0F63CB26002D821E /* scenery_v1.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421590E7BA6A700F5680E /* scenery_v1.cpp */; }; DF093F9D0F63CB26002D821E /* scenery_v2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84215A0E7BA6A700F5680E /* scenery_v2.cpp */; }; @@ -813,7 +809,6 @@ DF09419C0F63CB26002D821E /* sequences_lol.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFC320F48628A0006E566 /* sequences_lol.cpp */; }; DF09419D0F63CB26002D821E /* sound_midi.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFC330F48628A0006E566 /* sound_midi.cpp */; }; DF09419E0F63CB26002D821E /* util.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFC360F48628A0006E566 /* util.cpp */; }; - DF09419F0F63CB26002D821E /* game_v6.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFC400F4862D90006E566 /* game_v6.cpp */; }; DF0941A20F63CB26002D821E /* scene_lol.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFC490F4863100006E566 /* scene_lol.cpp */; }; DF0941A30F63CB26002D821E /* advancedDetector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFC4C0F4863560006E566 /* advancedDetector.cpp */; }; DF0941A40F63CB26002D821E /* base-backend.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFC5B0F4866E70006E566 /* base-backend.cpp */; }; @@ -923,13 +918,11 @@ DF09CC110FAC4E1900A5AFD7 /* demoplayer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF09CC090FAC4E1900A5AFD7 /* demoplayer.cpp */; }; DF09CC120FAC4E1900A5AFD7 /* scnplayer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF09CC0B0FAC4E1900A5AFD7 /* scnplayer.cpp */; }; DF09CC130FAC4E1900A5AFD7 /* draw_fascin.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF09CC0D0FAC4E1900A5AFD7 /* draw_fascin.cpp */; }; - DF09CC140FAC4E1900A5AFD7 /* game_fascin.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF09CC0E0FAC4E1900A5AFD7 /* game_fascin.cpp */; }; DF09CC150FAC4E1900A5AFD7 /* inter_fascin.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF09CC0F0FAC4E1900A5AFD7 /* inter_fascin.cpp */; }; DF09CC160FAC4E1900A5AFD7 /* batplayer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF09CC070FAC4E1900A5AFD7 /* batplayer.cpp */; }; DF09CC170FAC4E1900A5AFD7 /* demoplayer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF09CC090FAC4E1900A5AFD7 /* demoplayer.cpp */; }; DF09CC180FAC4E1900A5AFD7 /* scnplayer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF09CC0B0FAC4E1900A5AFD7 /* scnplayer.cpp */; }; DF09CC190FAC4E1900A5AFD7 /* draw_fascin.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF09CC0D0FAC4E1900A5AFD7 /* draw_fascin.cpp */; }; - DF09CC1A0FAC4E1900A5AFD7 /* game_fascin.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF09CC0E0FAC4E1900A5AFD7 /* game_fascin.cpp */; }; DF09CC1B0FAC4E1900A5AFD7 /* inter_fascin.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF09CC0F0FAC4E1900A5AFD7 /* inter_fascin.cpp */; }; DF09CC280FAC4EAB00A5AFD7 /* script_v3.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF09CC260FAC4EAB00A5AFD7 /* script_v3.cpp */; }; DF09CC290FAC4EAB00A5AFD7 /* script_v4.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF09CC270FAC4EAB00A5AFD7 /* script_v4.cpp */; }; @@ -953,7 +946,6 @@ DF2FFC3B0F48628A0006E566 /* sequences_lol.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFC320F48628A0006E566 /* sequences_lol.cpp */; }; DF2FFC3C0F48628A0006E566 /* sound_midi.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFC330F48628A0006E566 /* sound_midi.cpp */; }; DF2FFC3E0F48628A0006E566 /* util.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFC360F48628A0006E566 /* util.cpp */; }; - DF2FFC450F4862D90006E566 /* game_v6.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFC400F4862D90006E566 /* game_v6.cpp */; }; DF2FFC4A0F4863100006E566 /* scene_lol.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFC490F4863100006E566 /* scene_lol.cpp */; }; DF2FFC4E0F4863560006E566 /* advancedDetector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFC4C0F4863560006E566 /* advancedDetector.cpp */; }; DF2FFC5D0F4866E70006E566 /* base-backend.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFC5B0F4866E70006E566 /* base-backend.cpp */; }; @@ -1117,6 +1109,44 @@ DF6118D10FE3AB560042AD3F /* mame.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF6118CF0FE3AB560042AD3F /* mame.cpp */; }; DF6118D20FE3AB560042AD3F /* mame.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF6118CF0FE3AB560042AD3F /* mame.cpp */; }; DF6118D30FE3AB560042AD3F /* mame.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF6118CF0FE3AB560042AD3F /* mame.cpp */; }; + DF7585CE100CB66E00CC3324 /* expression.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7585C3100CB66E00CC3324 /* expression.cpp */; }; + DF7585CF100CB66E00CC3324 /* hotspots.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7585C5100CB66E00CC3324 /* hotspots.cpp */; }; + DF7585D0100CB66E00CC3324 /* init_v6.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7585C7100CB66E00CC3324 /* init_v6.cpp */; }; + DF7585D1100CB66E00CC3324 /* resources.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7585C8100CB66E00CC3324 /* resources.cpp */; }; + DF7585D2100CB66E00CC3324 /* script.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7585CA100CB66E00CC3324 /* script.cpp */; }; + DF7585D3100CB66E00CC3324 /* totfile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7585CC100CB66E00CC3324 /* totfile.cpp */; }; + DF7585D4100CB66E00CC3324 /* expression.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7585C3100CB66E00CC3324 /* expression.cpp */; }; + DF7585D5100CB66E00CC3324 /* hotspots.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7585C5100CB66E00CC3324 /* hotspots.cpp */; }; + DF7585D6100CB66E00CC3324 /* init_v6.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7585C7100CB66E00CC3324 /* init_v6.cpp */; }; + DF7585D7100CB66E00CC3324 /* resources.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7585C8100CB66E00CC3324 /* resources.cpp */; }; + DF7585D8100CB66E00CC3324 /* script.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7585CA100CB66E00CC3324 /* script.cpp */; }; + DF7585D9100CB66E00CC3324 /* totfile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7585CC100CB66E00CC3324 /* totfile.cpp */; }; + DF7585DA100CB66E00CC3324 /* expression.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7585C3100CB66E00CC3324 /* expression.cpp */; }; + DF7585DB100CB66E00CC3324 /* hotspots.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7585C5100CB66E00CC3324 /* hotspots.cpp */; }; + DF7585DC100CB66E00CC3324 /* init_v6.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7585C7100CB66E00CC3324 /* init_v6.cpp */; }; + DF7585DD100CB66E00CC3324 /* resources.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7585C8100CB66E00CC3324 /* resources.cpp */; }; + DF7585DE100CB66E00CC3324 /* script.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7585CA100CB66E00CC3324 /* script.cpp */; }; + DF7585DF100CB66E00CC3324 /* totfile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7585CC100CB66E00CC3324 /* totfile.cpp */; }; + DF7585E6100CB69F00CC3324 /* iff_sound.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7585E4100CB69F00CC3324 /* iff_sound.cpp */; }; + DF7585E7100CB69F00CC3324 /* iff_sound.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7585E4100CB69F00CC3324 /* iff_sound.cpp */; }; + DF7585E8100CB69F00CC3324 /* iff_sound.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7585E4100CB69F00CC3324 /* iff_sound.cpp */; }; + DF7585EC100CB6EA00CC3324 /* sjis.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7585EA100CB6EA00CC3324 /* sjis.cpp */; }; + DF7585ED100CB6EA00CC3324 /* sjis.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7585EA100CB6EA00CC3324 /* sjis.cpp */; }; + DF7585EE100CB6EA00CC3324 /* sjis.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7585EA100CB6EA00CC3324 /* sjis.cpp */; }; + DF7585F1100CB70600CC3324 /* saveload_playtoons.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7585F0100CB70600CC3324 /* saveload_playtoons.cpp */; }; + DF7585F2100CB70600CC3324 /* saveload_playtoons.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7585F0100CB70600CC3324 /* saveload_playtoons.cpp */; }; + DF7585F3100CB70600CC3324 /* saveload_playtoons.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7585F0100CB70600CC3324 /* saveload_playtoons.cpp */; }; + DF7585F7100CB75800CC3324 /* static_selectors.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7585F6100CB75800CC3324 /* static_selectors.cpp */; }; + DF7585F8100CB75800CC3324 /* static_selectors.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7585F6100CB75800CC3324 /* static_selectors.cpp */; }; + DF7585F9100CB75800CC3324 /* static_selectors.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7585F6100CB75800CC3324 /* static_selectors.cpp */; }; + DF758619100CBA0200CC3324 /* osys_events.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF758614100CBA0200CC3324 /* osys_events.cpp */; }; + DF75861A100CBA0200CC3324 /* osys_main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF758615100CBA0200CC3324 /* osys_main.cpp */; }; + DF75861B100CBA0200CC3324 /* osys_sound.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF758617100CBA0200CC3324 /* osys_sound.cpp */; }; + DF75861C100CBA0200CC3324 /* osys_video.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF758618100CBA0200CC3324 /* osys_video.cpp */; }; + DF75861D100CBA0200CC3324 /* osys_events.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF758614100CBA0200CC3324 /* osys_events.cpp */; }; + DF75861E100CBA0200CC3324 /* osys_main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF758615100CBA0200CC3324 /* osys_main.cpp */; }; + DF75861F100CBA0200CC3324 /* osys_sound.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF758617100CBA0200CC3324 /* osys_sound.cpp */; }; + DF758620100CBA0200CC3324 /* osys_video.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF758618100CBA0200CC3324 /* osys_video.cpp */; }; DF7A40330FB6E8960094E50F /* gfx_pixmap_scale.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7A40320FB6E8960094E50F /* gfx_pixmap_scale.cpp */; }; DF7A40340FB6E8960094E50F /* gfx_pixmap_scale.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7A40320FB6E8960094E50F /* gfx_pixmap_scale.cpp */; }; DF7A40350FB6E8960094E50F /* gfx_pixmap_scale.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7A40320FB6E8960094E50F /* gfx_pixmap_scale.cpp */; }; @@ -1281,8 +1311,6 @@ DF8425E20E7BA6AC00F5680E /* draw_v2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421220E7BA6A700F5680E /* draw_v2.cpp */; }; DF8425E30E7BA6AC00F5680E /* driver_vga.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421230E7BA6A700F5680E /* driver_vga.cpp */; }; DF8425E40E7BA6AC00F5680E /* game.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421250E7BA6A700F5680E /* game.cpp */; }; - DF8425E50E7BA6AC00F5680E /* game_v1.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421270E7BA6A700F5680E /* game_v1.cpp */; }; - DF8425E60E7BA6AC00F5680E /* game_v2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421280E7BA6A700F5680E /* game_v2.cpp */; }; DF8425E70E7BA6AC00F5680E /* global.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421290E7BA6A700F5680E /* global.cpp */; }; DF8425E80E7BA6AC00F5680E /* gob.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84212B0E7BA6A700F5680E /* gob.cpp */; }; DF8425E90E7BA6AC00F5680E /* goblin.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84212D0E7BA6A700F5680E /* goblin.cpp */; }; @@ -1310,7 +1338,6 @@ DF8426000E7BA6AC00F5680E /* mult_v1.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421490E7BA6A700F5680E /* mult_v1.cpp */; }; DF8426010E7BA6AC00F5680E /* mult_v2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84214A0E7BA6A700F5680E /* mult_v2.cpp */; }; DF8426030E7BA6AC00F5680E /* palanim.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84214C0E7BA6A700F5680E /* palanim.cpp */; }; - DF8426040E7BA6AC00F5680E /* parse.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84214E0E7BA6A700F5680E /* parse.cpp */; }; DF84260B0E7BA6AC00F5680E /* scenery.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421570E7BA6A700F5680E /* scenery.cpp */; }; DF84260C0E7BA6AC00F5680E /* scenery_v1.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421590E7BA6A700F5680E /* scenery_v1.cpp */; }; DF84260D0E7BA6AC00F5680E /* scenery_v2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84215A0E7BA6A700F5680E /* scenery_v2.cpp */; }; @@ -1863,7 +1890,6 @@ DFE4782B0D81F4E900B6D1FB /* default-events.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE470D80D81F4E700B6D1FB /* default-events.cpp */; }; DFE478380D81F4E900B6D1FB /* posix-fs-factory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE470F60D81F4E700B6D1FB /* posix-fs-factory.cpp */; }; DFE478C50D81F4E900B6D1FB /* iphone_main.m in Sources */ = {isa = PBXBuildFile; fileRef = DFE471E10D81F4E700B6D1FB /* iphone_main.m */; }; - DFE478C90D81F4E900B6D1FB /* osys_iphone.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE471E60D81F4E700B6D1FB /* osys_iphone.cpp */; }; DFE479B60D81F4E900B6D1FB /* posix-provider.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE473810D81F4E800B6D1FB /* posix-provider.cpp */; }; DFE479BA0D81F4E900B6D1FB /* default-saves.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE4738E0D81F4E800B6D1FB /* default-saves.cpp */; }; DFE479BB0D81F4E900B6D1FB /* savefile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE473900D81F4E800B6D1FB /* savefile.cpp */; }; @@ -1918,7 +1944,6 @@ DFE47C3F0D81F4E900B6D1FB /* audiostream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE477CD0D81F4E900B6D1FB /* audiostream.cpp */; }; DFE47C400D81F4E900B6D1FB /* flac.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE477CF0D81F4E900B6D1FB /* flac.cpp */; }; DFE47C410D81F4E900B6D1FB /* fmopl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE477D10D81F4E900B6D1FB /* fmopl.cpp */; }; - DFE47C420D81F4E900B6D1FB /* iff.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE477D30D81F4E900B6D1FB /* iff.cpp */; }; DFE47C430D81F4E900B6D1FB /* mididrv.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE477D50D81F4E900B6D1FB /* mididrv.cpp */; }; DFE47C440D81F4E900B6D1FB /* midiparser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE477D70D81F4E900B6D1FB /* midiparser.cpp */; }; DFE47C450D81F4E900B6D1FB /* midiparser_smf.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE477D90D81F4E900B6D1FB /* midiparser_smf.cpp */; }; @@ -1975,7 +2000,6 @@ DFF9591B0FB22D5700A3EC78 /* default-events.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE470D80D81F4E700B6D1FB /* default-events.cpp */; }; DFF9591C0FB22D5700A3EC78 /* posix-fs-factory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE470F60D81F4E700B6D1FB /* posix-fs-factory.cpp */; }; DFF9591D0FB22D5700A3EC78 /* iphone_main.m in Sources */ = {isa = PBXBuildFile; fileRef = DFE471E10D81F4E700B6D1FB /* iphone_main.m */; }; - DFF9591E0FB22D5700A3EC78 /* osys_iphone.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE471E60D81F4E700B6D1FB /* osys_iphone.cpp */; }; DFF9591F0FB22D5700A3EC78 /* posix-provider.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE473810D81F4E800B6D1FB /* posix-provider.cpp */; }; DFF959200FB22D5700A3EC78 /* default-saves.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE4738E0D81F4E800B6D1FB /* default-saves.cpp */; }; DFF959210FB22D5700A3EC78 /* savefile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE473900D81F4E800B6D1FB /* savefile.cpp */; }; @@ -2030,7 +2054,6 @@ DFF959520FB22D5700A3EC78 /* audiostream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE477CD0D81F4E900B6D1FB /* audiostream.cpp */; }; DFF959530FB22D5700A3EC78 /* flac.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE477CF0D81F4E900B6D1FB /* flac.cpp */; }; DFF959540FB22D5700A3EC78 /* fmopl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE477D10D81F4E900B6D1FB /* fmopl.cpp */; }; - DFF959550FB22D5700A3EC78 /* iff.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE477D30D81F4E900B6D1FB /* iff.cpp */; }; DFF959560FB22D5700A3EC78 /* mididrv.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE477D50D81F4E900B6D1FB /* mididrv.cpp */; }; DFF959570FB22D5700A3EC78 /* midiparser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE477D70D81F4E900B6D1FB /* midiparser.cpp */; }; DFF959580FB22D5700A3EC78 /* midiparser_smf.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE477D90D81F4E900B6D1FB /* midiparser_smf.cpp */; }; @@ -2213,8 +2236,6 @@ DFF95A0A0FB22D5700A3EC78 /* draw_v2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421220E7BA6A700F5680E /* draw_v2.cpp */; }; DFF95A0B0FB22D5700A3EC78 /* driver_vga.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421230E7BA6A700F5680E /* driver_vga.cpp */; }; DFF95A0C0FB22D5700A3EC78 /* game.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421250E7BA6A700F5680E /* game.cpp */; }; - DFF95A0D0FB22D5700A3EC78 /* game_v1.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421270E7BA6A700F5680E /* game_v1.cpp */; }; - DFF95A0E0FB22D5700A3EC78 /* game_v2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421280E7BA6A700F5680E /* game_v2.cpp */; }; DFF95A0F0FB22D5700A3EC78 /* global.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421290E7BA6A700F5680E /* global.cpp */; }; DFF95A100FB22D5700A3EC78 /* gob.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84212B0E7BA6A700F5680E /* gob.cpp */; }; DFF95A110FB22D5700A3EC78 /* goblin.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84212D0E7BA6A700F5680E /* goblin.cpp */; }; @@ -2242,7 +2263,6 @@ DFF95A270FB22D5700A3EC78 /* mult_v1.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421490E7BA6A700F5680E /* mult_v1.cpp */; }; DFF95A280FB22D5700A3EC78 /* mult_v2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84214A0E7BA6A700F5680E /* mult_v2.cpp */; }; DFF95A290FB22D5700A3EC78 /* palanim.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84214C0E7BA6A700F5680E /* palanim.cpp */; }; - DFF95A2A0FB22D5700A3EC78 /* parse.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84214E0E7BA6A700F5680E /* parse.cpp */; }; DFF95A310FB22D5700A3EC78 /* scenery.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421570E7BA6A700F5680E /* scenery.cpp */; }; DFF95A320FB22D5700A3EC78 /* scenery_v1.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421590E7BA6A700F5680E /* scenery_v1.cpp */; }; DFF95A330FB22D5700A3EC78 /* scenery_v2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84215A0E7BA6A700F5680E /* scenery_v2.cpp */; }; @@ -2755,7 +2775,6 @@ DFF95C310FB22D5700A3EC78 /* sequences_lol.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFC320F48628A0006E566 /* sequences_lol.cpp */; }; DFF95C320FB22D5700A3EC78 /* sound_midi.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFC330F48628A0006E566 /* sound_midi.cpp */; }; DFF95C330FB22D5700A3EC78 /* util.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFC360F48628A0006E566 /* util.cpp */; }; - DFF95C340FB22D5700A3EC78 /* game_v6.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFC400F4862D90006E566 /* game_v6.cpp */; }; DFF95C370FB22D5700A3EC78 /* scene_lol.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFC490F4863100006E566 /* scene_lol.cpp */; }; DFF95C380FB22D5700A3EC78 /* advancedDetector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFC4C0F4863560006E566 /* advancedDetector.cpp */; }; DFF95C390FB22D5700A3EC78 /* base-backend.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFC5B0F4866E70006E566 /* base-backend.cpp */; }; @@ -2859,7 +2878,6 @@ DFF95CAF0FB22D5700A3EC78 /* demoplayer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF09CC090FAC4E1900A5AFD7 /* demoplayer.cpp */; }; DFF95CB00FB22D5700A3EC78 /* scnplayer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF09CC0B0FAC4E1900A5AFD7 /* scnplayer.cpp */; }; DFF95CB10FB22D5700A3EC78 /* draw_fascin.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF09CC0D0FAC4E1900A5AFD7 /* draw_fascin.cpp */; }; - DFF95CB20FB22D5700A3EC78 /* game_fascin.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF09CC0E0FAC4E1900A5AFD7 /* game_fascin.cpp */; }; DFF95CB30FB22D5700A3EC78 /* inter_fascin.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF09CC0F0FAC4E1900A5AFD7 /* inter_fascin.cpp */; }; DFF95CB40FB22D5700A3EC78 /* script_v3.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF09CC260FAC4EAB00A5AFD7 /* script_v3.cpp */; }; DFF95CB50FB22D5700A3EC78 /* script_v4.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF09CC270FAC4EAB00A5AFD7 /* script_v4.cpp */; }; @@ -2959,7 +2977,6 @@ DF09CC0B0FAC4E1900A5AFD7 /* scnplayer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = scnplayer.cpp; sourceTree = "<group>"; }; DF09CC0C0FAC4E1900A5AFD7 /* scnplayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = scnplayer.h; sourceTree = "<group>"; }; DF09CC0D0FAC4E1900A5AFD7 /* draw_fascin.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = draw_fascin.cpp; sourceTree = "<group>"; }; - DF09CC0E0FAC4E1900A5AFD7 /* game_fascin.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = game_fascin.cpp; sourceTree = "<group>"; }; DF09CC0F0FAC4E1900A5AFD7 /* inter_fascin.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = inter_fascin.cpp; sourceTree = "<group>"; }; DF09CC1D0FAC4E6200A5AFD7 /* scumm_v0.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = scumm_v0.h; sourceTree = "<group>"; }; DF09CC1E0FAC4E6200A5AFD7 /* scumm_v2.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = scumm_v2.h; sourceTree = "<group>"; }; @@ -3004,7 +3021,6 @@ DF2FFC330F48628A0006E566 /* sound_midi.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sound_midi.cpp; sourceTree = "<group>"; }; DF2FFC360F48628A0006E566 /* util.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = util.cpp; sourceTree = "<group>"; }; DF2FFC370F48628A0006E566 /* util.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = util.h; sourceTree = "<group>"; }; - DF2FFC400F4862D90006E566 /* game_v6.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = game_v6.cpp; sourceTree = "<group>"; }; DF2FFC490F4863100006E566 /* scene_lol.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = scene_lol.cpp; sourceTree = "<group>"; }; DF2FFC4C0F4863560006E566 /* advancedDetector.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = advancedDetector.cpp; sourceTree = "<group>"; }; DF2FFC4D0F4863560006E566 /* advancedDetector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = advancedDetector.h; sourceTree = "<group>"; }; @@ -3162,6 +3178,28 @@ DF6118CB0FE3AAFD0042AD3F /* hardwarekeys.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = hardwarekeys.cpp; sourceTree = "<group>"; }; DF6118CF0FE3AB560042AD3F /* mame.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = mame.cpp; sourceTree = "<group>"; }; DF6118D00FE3AB560042AD3F /* mame.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mame.h; sourceTree = "<group>"; }; + DF7585C3100CB66E00CC3324 /* expression.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = expression.cpp; sourceTree = "<group>"; }; + DF7585C4100CB66E00CC3324 /* expression.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = expression.h; sourceTree = "<group>"; }; + DF7585C5100CB66E00CC3324 /* hotspots.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = hotspots.cpp; sourceTree = "<group>"; }; + DF7585C6100CB66E00CC3324 /* hotspots.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = hotspots.h; sourceTree = "<group>"; }; + DF7585C7100CB66E00CC3324 /* init_v6.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = init_v6.cpp; sourceTree = "<group>"; }; + DF7585C8100CB66E00CC3324 /* resources.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = resources.cpp; sourceTree = "<group>"; }; + DF7585C9100CB66E00CC3324 /* resources.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = resources.h; sourceTree = "<group>"; }; + DF7585CA100CB66E00CC3324 /* script.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = script.cpp; sourceTree = "<group>"; }; + DF7585CB100CB66E00CC3324 /* script.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = script.h; sourceTree = "<group>"; }; + DF7585CC100CB66E00CC3324 /* totfile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = totfile.cpp; sourceTree = "<group>"; }; + DF7585CD100CB66E00CC3324 /* totfile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = totfile.h; sourceTree = "<group>"; }; + DF7585E4100CB69F00CC3324 /* iff_sound.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = iff_sound.cpp; sourceTree = "<group>"; }; + DF7585E5100CB69F00CC3324 /* iff_sound.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = iff_sound.h; sourceTree = "<group>"; }; + DF7585EA100CB6EA00CC3324 /* sjis.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sjis.cpp; sourceTree = "<group>"; }; + DF7585EB100CB6EA00CC3324 /* sjis.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sjis.h; sourceTree = "<group>"; }; + DF7585F0100CB70600CC3324 /* saveload_playtoons.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = saveload_playtoons.cpp; sourceTree = "<group>"; }; + DF7585F6100CB75800CC3324 /* static_selectors.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = static_selectors.cpp; sourceTree = "<group>"; }; + DF758614100CBA0200CC3324 /* osys_events.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = osys_events.cpp; sourceTree = "<group>"; }; + DF758615100CBA0200CC3324 /* osys_main.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = osys_main.cpp; sourceTree = "<group>"; }; + DF758616100CBA0200CC3324 /* osys_main.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = osys_main.h; sourceTree = "<group>"; }; + DF758617100CBA0200CC3324 /* osys_sound.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = osys_sound.cpp; sourceTree = "<group>"; }; + DF758618100CBA0200CC3324 /* osys_video.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = osys_video.cpp; sourceTree = "<group>"; }; DF7A40320FB6E8960094E50F /* gfx_pixmap_scale.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = gfx_pixmap_scale.cpp; sourceTree = "<group>"; }; DF7E8BF00ED5FC77001CB19F /* saveload.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = saveload.cpp; sourceTree = "<group>"; }; DF7E8BF10ED5FC77001CB19F /* saveload.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = saveload.h; sourceTree = "<group>"; }; @@ -3412,8 +3450,6 @@ DF8421240E7BA6A700F5680E /* driver_vga.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = driver_vga.h; sourceTree = "<group>"; }; DF8421250E7BA6A700F5680E /* game.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = game.cpp; sourceTree = "<group>"; }; DF8421260E7BA6A700F5680E /* game.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = game.h; sourceTree = "<group>"; }; - DF8421270E7BA6A700F5680E /* game_v1.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = game_v1.cpp; sourceTree = "<group>"; }; - DF8421280E7BA6A700F5680E /* game_v2.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = game_v2.cpp; sourceTree = "<group>"; }; DF8421290E7BA6A700F5680E /* global.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = global.cpp; sourceTree = "<group>"; }; DF84212A0E7BA6A700F5680E /* global.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = global.h; sourceTree = "<group>"; }; DF84212B0E7BA6A700F5680E /* gob.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = gob.cpp; sourceTree = "<group>"; }; @@ -3449,8 +3485,6 @@ DF84214A0E7BA6A700F5680E /* mult_v2.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = mult_v2.cpp; sourceTree = "<group>"; }; DF84214C0E7BA6A700F5680E /* palanim.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = palanim.cpp; sourceTree = "<group>"; }; DF84214D0E7BA6A700F5680E /* palanim.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = palanim.h; sourceTree = "<group>"; }; - DF84214E0E7BA6A700F5680E /* parse.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = parse.cpp; sourceTree = "<group>"; }; - DF84214F0E7BA6A700F5680E /* parse.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = parse.h; sourceTree = "<group>"; }; DF8421570E7BA6A700F5680E /* scenery.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = scenery.cpp; sourceTree = "<group>"; }; DF8421580E7BA6A700F5680E /* scenery.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = scenery.h; sourceTree = "<group>"; }; DF8421590E7BA6A700F5680E /* scenery_v1.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = scenery_v1.cpp; sourceTree = "<group>"; }; @@ -4402,8 +4436,6 @@ DFE471DE0D81F4E700B6D1FB /* iphone_common.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = iphone_common.h; sourceTree = "<group>"; }; DFE471DF0D81F4E700B6D1FB /* iphone_keyboard.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = iphone_keyboard.h; sourceTree = "<group>"; }; DFE471E10D81F4E700B6D1FB /* iphone_main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = iphone_main.m; sourceTree = "<group>"; }; - DFE471E60D81F4E700B6D1FB /* osys_iphone.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = osys_iphone.cpp; sourceTree = "<group>"; }; - DFE471E70D81F4E700B6D1FB /* osys_iphone.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = osys_iphone.h; sourceTree = "<group>"; }; DFE4737F0D81F4E800B6D1FB /* dynamic-plugin.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "dynamic-plugin.h"; sourceTree = "<group>"; }; DFE473810D81F4E800B6D1FB /* posix-provider.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "posix-provider.cpp"; sourceTree = "<group>"; }; DFE473820D81F4E800B6D1FB /* posix-provider.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "posix-provider.h"; sourceTree = "<group>"; }; @@ -4532,8 +4564,6 @@ DFE477D00D81F4E900B6D1FB /* flac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = flac.h; sourceTree = "<group>"; }; DFE477D10D81F4E900B6D1FB /* fmopl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = fmopl.cpp; sourceTree = "<group>"; }; DFE477D20D81F4E900B6D1FB /* fmopl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fmopl.h; sourceTree = "<group>"; }; - DFE477D30D81F4E900B6D1FB /* iff.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = iff.cpp; sourceTree = "<group>"; }; - DFE477D40D81F4E900B6D1FB /* iff.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = iff.h; sourceTree = "<group>"; }; DFE477D50D81F4E900B6D1FB /* mididrv.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = mididrv.cpp; sourceTree = "<group>"; }; DFE477D60D81F4E900B6D1FB /* mididrv.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mididrv.h; sourceTree = "<group>"; }; DFE477D70D81F4E900B6D1FB /* midiparser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = midiparser.cpp; sourceTree = "<group>"; }; @@ -4852,6 +4882,7 @@ DF6118780FE3A9AA0042AD3F /* save */ = { isa = PBXGroup; children = ( + DF7585F0100CB70600CC3324 /* saveload_playtoons.cpp */, DF6118790FE3A9AA0042AD3F /* saveconverter.cpp */, DF61187A0FE3A9AA0042AD3F /* saveconverter.h */, DF61187B0FE3A9AA0042AD3F /* saveconverter_v2.cpp */, @@ -5171,13 +5202,22 @@ DF8421170E7BA6A700F5680E /* gob */ = { isa = PBXGroup; children = ( + DF7585C3100CB66E00CC3324 /* expression.cpp */, + DF7585C4100CB66E00CC3324 /* expression.h */, + DF7585C5100CB66E00CC3324 /* hotspots.cpp */, + DF7585C6100CB66E00CC3324 /* hotspots.h */, + DF7585C7100CB66E00CC3324 /* init_v6.cpp */, + DF7585C8100CB66E00CC3324 /* resources.cpp */, + DF7585C9100CB66E00CC3324 /* resources.h */, + DF7585CA100CB66E00CC3324 /* script.cpp */, + DF7585CB100CB66E00CC3324 /* script.h */, + DF7585CC100CB66E00CC3324 /* totfile.cpp */, + DF7585CD100CB66E00CC3324 /* totfile.h */, DF6118780FE3A9AA0042AD3F /* save */, DF6118590FE3A9020042AD3F /* helper.h */, DF09CC060FAC4E1900A5AFD7 /* demos */, DF09CC0D0FAC4E1900A5AFD7 /* draw_fascin.cpp */, - DF09CC0E0FAC4E1900A5AFD7 /* game_fascin.cpp */, DF09CC0F0FAC4E1900A5AFD7 /* inter_fascin.cpp */, - DF2FFC400F4862D90006E566 /* game_v6.cpp */, DF84211B0E7BA6A700F5680E /* dataio.cpp */, DF84211C0E7BA6A700F5680E /* dataio.h */, DF84211D0E7BA6A700F5680E /* detection.cpp */, @@ -5190,8 +5230,6 @@ DF8421240E7BA6A700F5680E /* driver_vga.h */, DF8421250E7BA6A700F5680E /* game.cpp */, DF8421260E7BA6A700F5680E /* game.h */, - DF8421270E7BA6A700F5680E /* game_v1.cpp */, - DF8421280E7BA6A700F5680E /* game_v2.cpp */, DF8421290E7BA6A700F5680E /* global.cpp */, DF84212A0E7BA6A700F5680E /* global.h */, DF84212B0E7BA6A700F5680E /* gob.cpp */, @@ -5227,8 +5265,6 @@ DF84214A0E7BA6A700F5680E /* mult_v2.cpp */, DF84214C0E7BA6A700F5680E /* palanim.cpp */, DF84214D0E7BA6A700F5680E /* palanim.h */, - DF84214E0E7BA6A700F5680E /* parse.cpp */, - DF84214F0E7BA6A700F5680E /* parse.h */, DF8421570E7BA6A700F5680E /* scenery.cpp */, DF8421580E7BA6A700F5680E /* scenery.h */, DF8421590E7BA6A700F5680E /* scenery_v1.cpp */, @@ -6317,6 +6353,7 @@ DFC8301B0F48AF18005EF03C /* engine */ = { isa = PBXGroup; children = ( + DF7585F6100CB75800CC3324 /* static_selectors.cpp */, DF6118380FE3A8080042AD3F /* kmisc.cpp */, DF6118390FE3A8080042AD3F /* memobj.cpp */, DF61183A0FE3A8080042AD3F /* memobj.h */, @@ -6572,6 +6609,11 @@ DFE471D70D81F4E700B6D1FB /* iphone */ = { isa = PBXGroup; children = ( + DF758614100CBA0200CC3324 /* osys_events.cpp */, + DF758615100CBA0200CC3324 /* osys_main.cpp */, + DF758616100CBA0200CC3324 /* osys_main.h */, + DF758617100CBA0200CC3324 /* osys_sound.cpp */, + DF758618100CBA0200CC3324 /* osys_video.cpp */, DF8428960E7BAAAB00F5680E /* blit.cpp */, DF841FD90E7BA61800F5680E /* iphone_keyboard.m */, DF841FDA0E7BA61800F5680E /* iphone_video.h */, @@ -6580,8 +6622,6 @@ DFE471DE0D81F4E700B6D1FB /* iphone_common.h */, DFE471DF0D81F4E700B6D1FB /* iphone_keyboard.h */, DFE471E10D81F4E700B6D1FB /* iphone_main.m */, - DFE471E60D81F4E700B6D1FB /* osys_iphone.cpp */, - DFE471E70D81F4E700B6D1FB /* osys_iphone.h */, ); path = iphone; sourceTree = "<group>"; @@ -6709,6 +6749,8 @@ DFE477520D81F4E900B6D1FB /* graphics */ = { isa = PBXGroup; children = ( + DF7585EA100CB6EA00CC3324 /* sjis.cpp */, + DF7585EB100CB6EA00CC3324 /* sjis.h */, DF2FFB940F485D950006E566 /* video */, DF2FFB900F485D890006E566 /* dither.cpp */, DF2FFB910F485D890006E566 /* dither.h */, @@ -6830,6 +6872,8 @@ DFE477C60D81F4E900B6D1FB /* sound */ = { isa = PBXGroup; children = ( + DF7585E4100CB69F00CC3324 /* iff_sound.cpp */, + DF7585E5100CB69F00CC3324 /* iff_sound.h */, DF5CEB350F7553E000DEA624 /* vag.cpp */, DF5CEB360F7553E000DEA624 /* vag.h */, DF89C2B60F62D91000D756B6 /* shorten.cpp */, @@ -6850,8 +6894,6 @@ DFE477D00D81F4E900B6D1FB /* flac.h */, DFE477D10D81F4E900B6D1FB /* fmopl.cpp */, DFE477D20D81F4E900B6D1FB /* fmopl.h */, - DFE477D30D81F4E900B6D1FB /* iff.cpp */, - DFE477D40D81F4E900B6D1FB /* iff.h */, DFE477D50D81F4E900B6D1FB /* mididrv.cpp */, DFE477D60D81F4E900B6D1FB /* mididrv.h */, DFE477D70D81F4E900B6D1FB /* midiparser.cpp */, @@ -7087,7 +7129,6 @@ DFE4782B0D81F4E900B6D1FB /* default-events.cpp in Sources */, DFE478380D81F4E900B6D1FB /* posix-fs-factory.cpp in Sources */, DFE478C50D81F4E900B6D1FB /* iphone_main.m in Sources */, - DFE478C90D81F4E900B6D1FB /* osys_iphone.cpp in Sources */, DFE479B60D81F4E900B6D1FB /* posix-provider.cpp in Sources */, DFE479BA0D81F4E900B6D1FB /* default-saves.cpp in Sources */, DFE479BB0D81F4E900B6D1FB /* savefile.cpp in Sources */, @@ -7142,7 +7183,6 @@ DFE47C3F0D81F4E900B6D1FB /* audiostream.cpp in Sources */, DFE47C400D81F4E900B6D1FB /* flac.cpp in Sources */, DFE47C410D81F4E900B6D1FB /* fmopl.cpp in Sources */, - DFE47C420D81F4E900B6D1FB /* iff.cpp in Sources */, DFE47C430D81F4E900B6D1FB /* mididrv.cpp in Sources */, DFE47C440D81F4E900B6D1FB /* midiparser.cpp in Sources */, DFE47C450D81F4E900B6D1FB /* midiparser_smf.cpp in Sources */, @@ -7325,8 +7365,6 @@ DF8425E20E7BA6AC00F5680E /* draw_v2.cpp in Sources */, DF8425E30E7BA6AC00F5680E /* driver_vga.cpp in Sources */, DF8425E40E7BA6AC00F5680E /* game.cpp in Sources */, - DF8425E50E7BA6AC00F5680E /* game_v1.cpp in Sources */, - DF8425E60E7BA6AC00F5680E /* game_v2.cpp in Sources */, DF8425E70E7BA6AC00F5680E /* global.cpp in Sources */, DF8425E80E7BA6AC00F5680E /* gob.cpp in Sources */, DF8425E90E7BA6AC00F5680E /* goblin.cpp in Sources */, @@ -7354,7 +7392,6 @@ DF8426000E7BA6AC00F5680E /* mult_v1.cpp in Sources */, DF8426010E7BA6AC00F5680E /* mult_v2.cpp in Sources */, DF8426030E7BA6AC00F5680E /* palanim.cpp in Sources */, - DF8426040E7BA6AC00F5680E /* parse.cpp in Sources */, DF84260B0E7BA6AC00F5680E /* scenery.cpp in Sources */, DF84260C0E7BA6AC00F5680E /* scenery_v1.cpp in Sources */, DF84260D0E7BA6AC00F5680E /* scenery_v2.cpp in Sources */, @@ -7867,7 +7904,6 @@ DF2FFC3B0F48628A0006E566 /* sequences_lol.cpp in Sources */, DF2FFC3C0F48628A0006E566 /* sound_midi.cpp in Sources */, DF2FFC3E0F48628A0006E566 /* util.cpp in Sources */, - DF2FFC450F4862D90006E566 /* game_v6.cpp in Sources */, DF2FFC4A0F4863100006E566 /* scene_lol.cpp in Sources */, DF2FFC4E0F4863560006E566 /* advancedDetector.cpp in Sources */, DF2FFC5D0F4866E70006E566 /* base-backend.cpp in Sources */, @@ -7971,7 +8007,6 @@ DF09CC170FAC4E1900A5AFD7 /* demoplayer.cpp in Sources */, DF09CC180FAC4E1900A5AFD7 /* scnplayer.cpp in Sources */, DF09CC190FAC4E1900A5AFD7 /* draw_fascin.cpp in Sources */, - DF09CC1A0FAC4E1900A5AFD7 /* game_fascin.cpp in Sources */, DF09CC1B0FAC4E1900A5AFD7 /* inter_fascin.cpp in Sources */, DF09CC2A0FAC4EAB00A5AFD7 /* script_v3.cpp in Sources */, DF09CC2B0FAC4EAB00A5AFD7 /* script_v4.cpp in Sources */, @@ -8011,6 +8046,20 @@ DF6118BF0FE3AA280042AD3F /* text_lol.cpp in Sources */, DF6118C80FE3AABD0042AD3F /* player_v2cms.cpp in Sources */, DF6118D30FE3AB560042AD3F /* mame.cpp in Sources */, + DF7585DA100CB66E00CC3324 /* expression.cpp in Sources */, + DF7585DB100CB66E00CC3324 /* hotspots.cpp in Sources */, + DF7585DC100CB66E00CC3324 /* init_v6.cpp in Sources */, + DF7585DD100CB66E00CC3324 /* resources.cpp in Sources */, + DF7585DE100CB66E00CC3324 /* script.cpp in Sources */, + DF7585DF100CB66E00CC3324 /* totfile.cpp in Sources */, + DF7585E8100CB69F00CC3324 /* iff_sound.cpp in Sources */, + DF7585EE100CB6EA00CC3324 /* sjis.cpp in Sources */, + DF7585F3100CB70600CC3324 /* saveload_playtoons.cpp in Sources */, + DF7585F9100CB75800CC3324 /* static_selectors.cpp in Sources */, + DF75861D100CBA0200CC3324 /* osys_events.cpp in Sources */, + DF75861E100CBA0200CC3324 /* osys_main.cpp in Sources */, + DF75861F100CBA0200CC3324 /* osys_sound.cpp in Sources */, + DF758620100CBA0200CC3324 /* osys_video.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -8078,7 +8127,6 @@ DF093EBC0F63CB26002D821E /* audiostream.cpp in Sources */, DF093EBD0F63CB26002D821E /* flac.cpp in Sources */, DF093EBE0F63CB26002D821E /* fmopl.cpp in Sources */, - DF093EBF0F63CB26002D821E /* iff.cpp in Sources */, DF093EC00F63CB26002D821E /* mididrv.cpp in Sources */, DF093EC10F63CB26002D821E /* midiparser.cpp in Sources */, DF093EC20F63CB26002D821E /* midiparser_smf.cpp in Sources */, @@ -8259,8 +8307,6 @@ DF093F740F63CB26002D821E /* draw_v2.cpp in Sources */, DF093F750F63CB26002D821E /* driver_vga.cpp in Sources */, DF093F760F63CB26002D821E /* game.cpp in Sources */, - DF093F770F63CB26002D821E /* game_v1.cpp in Sources */, - DF093F780F63CB26002D821E /* game_v2.cpp in Sources */, DF093F790F63CB26002D821E /* global.cpp in Sources */, DF093F7A0F63CB26002D821E /* gob.cpp in Sources */, DF093F7B0F63CB26002D821E /* goblin.cpp in Sources */, @@ -8288,7 +8334,6 @@ DF093F910F63CB26002D821E /* mult_v1.cpp in Sources */, DF093F920F63CB26002D821E /* mult_v2.cpp in Sources */, DF093F930F63CB26002D821E /* palanim.cpp in Sources */, - DF093F940F63CB26002D821E /* parse.cpp in Sources */, DF093F9B0F63CB26002D821E /* scenery.cpp in Sources */, DF093F9C0F63CB26002D821E /* scenery_v1.cpp in Sources */, DF093F9D0F63CB26002D821E /* scenery_v2.cpp in Sources */, @@ -8800,7 +8845,6 @@ DF09419C0F63CB26002D821E /* sequences_lol.cpp in Sources */, DF09419D0F63CB26002D821E /* sound_midi.cpp in Sources */, DF09419E0F63CB26002D821E /* util.cpp in Sources */, - DF09419F0F63CB26002D821E /* game_v6.cpp in Sources */, DF0941A20F63CB26002D821E /* scene_lol.cpp in Sources */, DF0941A30F63CB26002D821E /* advancedDetector.cpp in Sources */, DF0941A40F63CB26002D821E /* base-backend.cpp in Sources */, @@ -8911,7 +8955,6 @@ DF09CC110FAC4E1900A5AFD7 /* demoplayer.cpp in Sources */, DF09CC120FAC4E1900A5AFD7 /* scnplayer.cpp in Sources */, DF09CC130FAC4E1900A5AFD7 /* draw_fascin.cpp in Sources */, - DF09CC140FAC4E1900A5AFD7 /* game_fascin.cpp in Sources */, DF09CC150FAC4E1900A5AFD7 /* inter_fascin.cpp in Sources */, DF09CC280FAC4EAB00A5AFD7 /* script_v3.cpp in Sources */, DF09CC290FAC4EAB00A5AFD7 /* script_v4.cpp in Sources */, @@ -8952,6 +8995,16 @@ DF6118C70FE3AABD0042AD3F /* player_v2cms.cpp in Sources */, DF6118CC0FE3AAFD0042AD3F /* hardwarekeys.cpp in Sources */, DF6118D10FE3AB560042AD3F /* mame.cpp in Sources */, + DF7585CE100CB66E00CC3324 /* expression.cpp in Sources */, + DF7585CF100CB66E00CC3324 /* hotspots.cpp in Sources */, + DF7585D0100CB66E00CC3324 /* init_v6.cpp in Sources */, + DF7585D1100CB66E00CC3324 /* resources.cpp in Sources */, + DF7585D2100CB66E00CC3324 /* script.cpp in Sources */, + DF7585D3100CB66E00CC3324 /* totfile.cpp in Sources */, + DF7585E6100CB69F00CC3324 /* iff_sound.cpp in Sources */, + DF7585EC100CB6EA00CC3324 /* sjis.cpp in Sources */, + DF7585F1100CB70600CC3324 /* saveload_playtoons.cpp in Sources */, + DF7585F7100CB75800CC3324 /* static_selectors.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -8966,7 +9019,6 @@ DFF9591B0FB22D5700A3EC78 /* default-events.cpp in Sources */, DFF9591C0FB22D5700A3EC78 /* posix-fs-factory.cpp in Sources */, DFF9591D0FB22D5700A3EC78 /* iphone_main.m in Sources */, - DFF9591E0FB22D5700A3EC78 /* osys_iphone.cpp in Sources */, DFF9591F0FB22D5700A3EC78 /* posix-provider.cpp in Sources */, DFF959200FB22D5700A3EC78 /* default-saves.cpp in Sources */, DFF959210FB22D5700A3EC78 /* savefile.cpp in Sources */, @@ -9021,7 +9073,6 @@ DFF959520FB22D5700A3EC78 /* audiostream.cpp in Sources */, DFF959530FB22D5700A3EC78 /* flac.cpp in Sources */, DFF959540FB22D5700A3EC78 /* fmopl.cpp in Sources */, - DFF959550FB22D5700A3EC78 /* iff.cpp in Sources */, DFF959560FB22D5700A3EC78 /* mididrv.cpp in Sources */, DFF959570FB22D5700A3EC78 /* midiparser.cpp in Sources */, DFF959580FB22D5700A3EC78 /* midiparser_smf.cpp in Sources */, @@ -9204,8 +9255,6 @@ DFF95A0A0FB22D5700A3EC78 /* draw_v2.cpp in Sources */, DFF95A0B0FB22D5700A3EC78 /* driver_vga.cpp in Sources */, DFF95A0C0FB22D5700A3EC78 /* game.cpp in Sources */, - DFF95A0D0FB22D5700A3EC78 /* game_v1.cpp in Sources */, - DFF95A0E0FB22D5700A3EC78 /* game_v2.cpp in Sources */, DFF95A0F0FB22D5700A3EC78 /* global.cpp in Sources */, DFF95A100FB22D5700A3EC78 /* gob.cpp in Sources */, DFF95A110FB22D5700A3EC78 /* goblin.cpp in Sources */, @@ -9233,7 +9282,6 @@ DFF95A270FB22D5700A3EC78 /* mult_v1.cpp in Sources */, DFF95A280FB22D5700A3EC78 /* mult_v2.cpp in Sources */, DFF95A290FB22D5700A3EC78 /* palanim.cpp in Sources */, - DFF95A2A0FB22D5700A3EC78 /* parse.cpp in Sources */, DFF95A310FB22D5700A3EC78 /* scenery.cpp in Sources */, DFF95A320FB22D5700A3EC78 /* scenery_v1.cpp in Sources */, DFF95A330FB22D5700A3EC78 /* scenery_v2.cpp in Sources */, @@ -9746,7 +9794,6 @@ DFF95C310FB22D5700A3EC78 /* sequences_lol.cpp in Sources */, DFF95C320FB22D5700A3EC78 /* sound_midi.cpp in Sources */, DFF95C330FB22D5700A3EC78 /* util.cpp in Sources */, - DFF95C340FB22D5700A3EC78 /* game_v6.cpp in Sources */, DFF95C370FB22D5700A3EC78 /* scene_lol.cpp in Sources */, DFF95C380FB22D5700A3EC78 /* advancedDetector.cpp in Sources */, DFF95C390FB22D5700A3EC78 /* base-backend.cpp in Sources */, @@ -9850,7 +9897,6 @@ DFF95CAF0FB22D5700A3EC78 /* demoplayer.cpp in Sources */, DFF95CB00FB22D5700A3EC78 /* scnplayer.cpp in Sources */, DFF95CB10FB22D5700A3EC78 /* draw_fascin.cpp in Sources */, - DFF95CB20FB22D5700A3EC78 /* game_fascin.cpp in Sources */, DFF95CB30FB22D5700A3EC78 /* inter_fascin.cpp in Sources */, DFF95CB40FB22D5700A3EC78 /* script_v3.cpp in Sources */, DFF95CB50FB22D5700A3EC78 /* script_v4.cpp in Sources */, @@ -9890,6 +9936,20 @@ DF6118C30FE3AA280042AD3F /* text_lol.cpp in Sources */, DF6118C90FE3AABD0042AD3F /* player_v2cms.cpp in Sources */, DF6118D20FE3AB560042AD3F /* mame.cpp in Sources */, + DF7585D4100CB66E00CC3324 /* expression.cpp in Sources */, + DF7585D5100CB66E00CC3324 /* hotspots.cpp in Sources */, + DF7585D6100CB66E00CC3324 /* init_v6.cpp in Sources */, + DF7585D7100CB66E00CC3324 /* resources.cpp in Sources */, + DF7585D8100CB66E00CC3324 /* script.cpp in Sources */, + DF7585D9100CB66E00CC3324 /* totfile.cpp in Sources */, + DF7585E7100CB69F00CC3324 /* iff_sound.cpp in Sources */, + DF7585ED100CB6EA00CC3324 /* sjis.cpp in Sources */, + DF7585F2100CB70600CC3324 /* saveload_playtoons.cpp in Sources */, + DF7585F8100CB75800CC3324 /* static_selectors.cpp in Sources */, + DF758619100CBA0200CC3324 /* osys_events.cpp in Sources */, + DF75861A100CBA0200CC3324 /* osys_main.cpp in Sources */, + DF75861B100CBA0200CC3324 /* osys_sound.cpp in Sources */, + DF75861C100CBA0200CC3324 /* osys_video.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/engines/agi/graphics.cpp b/engines/agi/graphics.cpp index ad2c264184..3461bb473e 100644 --- a/engines/agi/graphics.cpp +++ b/engines/agi/graphics.cpp @@ -846,7 +846,7 @@ void GfxMgr::setAGIPal(int p0) { //Chunks4-7 are duplicates of chunks0-3 - if (agipal.ioFailed()) { + if (agipal.eos() || agipal.err()) { warning("Couldn't read AGIPAL palette from '%s'. Not changing palette", filename); return; } diff --git a/engines/agi/op_cmd.cpp b/engines/agi/op_cmd.cpp index 97255097bc..7012174c20 100644 --- a/engines/agi/op_cmd.cpp +++ b/engines/agi/op_cmd.cpp @@ -1256,7 +1256,7 @@ cmd(restart_game) { int sel; g_sound->stopSound(); - sel = g_agi->getflag(fAutoRestart) ? 1 : + sel = g_agi->getflag(fAutoRestart) ? 0 : g_agi->selectionBox(" Restart game, or continue? \n\n\n", buttons); if (sel == 0) { diff --git a/engines/agi/sound.cpp b/engines/agi/sound.cpp index fb73c6b71f..5a39b663a5 100644 --- a/engines/agi/sound.cpp +++ b/engines/agi/sound.cpp @@ -133,7 +133,7 @@ bool IIgsEnvelope::read(Common::SeekableReadStream &stream) { seg[segNum].inc = stream.readUint16LE(); } - return !stream.ioFailed(); + return !(stream.eos() || stream.err()); } /** Reads an Apple IIGS wave information structure from the given stream. */ @@ -154,7 +154,7 @@ bool IIgsWaveInfo::read(Common::SeekableReadStream &stream, bool ignoreAddr) { if (ignoreAddr) addr = 0; - return !stream.ioFailed(); + return !(stream.eos() || stream.err()); } bool IIgsWaveInfo::finalize(Common::SeekableReadStream &uint8Wave) { @@ -219,7 +219,7 @@ bool IIgsInstrumentHeader::read(Common::SeekableReadStream &stream, bool ignoreA byte wac = stream.readByte(); // Read A wave count byte wbc = stream.readByte(); // Read B wave count oscList.read(stream, wac, ignoreAddr); // Read the oscillators - return (wac == wbc) && !stream.ioFailed(); // A and B wave counts must match + return (wac == wbc) && !(stream.eos() || stream.err()); // A and B wave counts must match } bool IIgsInstrumentHeader::finalize(Common::SeekableReadStream &uint8Wave) { @@ -1158,7 +1158,7 @@ bool SoundMgr::convertWave(Common::SeekableReadStream &source, int8 *dest, uint // Convert the wave from 8-bit unsigned to 8-bit signed format for (uint i = 0; i < length; i++) dest[i] = (int8) ((int) source.readByte() - 128); - return !source.ioFailed(); + return !(source.eos() || source.err()); } bool IIgsSoundMgr::loadWaveFile(const Common::FSNode &wavePath, const IIgsExeInfo &exeInfo) { diff --git a/engines/agi/wagparser.cpp b/engines/agi/wagparser.cpp index e6ed5345e0..d243439dff 100644 --- a/engines/agi/wagparser.cpp +++ b/engines/agi/wagparser.cpp @@ -70,7 +70,7 @@ bool WagProperty::read(Common::SeekableReadStream &stream) { _propNum = stream.readByte(); _propSize = stream.readUint16LE(); - if (stream.ioFailed()) { // Check that we got the whole header + if (stream.eos() || stream.err()) { // Check that we got the whole header _readOk = false; return _readOk; } diff --git a/engines/agos/agos.h b/engines/agos/agos.h index 093f7bb039..263811b78a 100644 --- a/engines/agos/agos.h +++ b/engines/agos/agos.h @@ -1265,8 +1265,8 @@ protected: #ifdef ENABLE_PN class AGOSEngine_PN : public AGOSEngine { - struct stackframe { - struct stackframe *nextframe; + struct StackFrame { + StackFrame *nextframe; int16 flag[6]; int16 param[8]; int16 classnum; @@ -1276,7 +1276,7 @@ class AGOSEngine_PN : public AGOSEngine { int16 linenum; int16 process; jmp_buf *savearea; - stackframe() { memset(this, 0, sizeof(*this)); } + StackFrame() { memset(this, 0, sizeof(*this)); } }; @@ -1284,6 +1284,7 @@ class AGOSEngine_PN : public AGOSEngine { void demoSeq(); void introSeq(); void setupBoxes(); + int readfromline(); public: AGOSEngine_PN(OSystem *system); ~AGOSEngine_PN(); @@ -1297,10 +1298,10 @@ public: int actCallD(int n); void opn_opcode00(); - void opn_opcode01(); - void opn_opcode02(); - void opn_opcode03(); - void opn_opcode04(); + void opn_add(); + void opn_sub(); + void opn_mul(); + void opn_div(); void opn_opcode05(); void opn_opcode06(); void opn_opcode07(); @@ -1313,10 +1314,10 @@ public: void opn_opcode14(); void opn_opcode15(); void opn_opcode16(); - void opn_opcode17(); - void opn_opcode18(); - void opn_opcode19(); - void opn_opcode20(); + void opn_lt(); + void opn_gt(); + void opn_eq(); + void opn_neq(); void opn_opcode21(); void opn_opcode22(); void opn_opcode23(); @@ -1357,14 +1358,14 @@ public: void opn_opcode62(); void opn_opcode63(); - stackframe *_stackbase; + StackFrame *_stackbase; byte *_dataBase, *_textBase; uint32 _dataBaseSize, _textBaseSize; HitArea _invHitAreas[45]; - char _buffer[80]; + char _buffer[80]; char _inputline[61]; char _saveFile[20]; char _sb[80]; @@ -1390,7 +1391,7 @@ public: uint16 _objects; int16 _objectCountS; - int16 _bp; + int16 _bp; int16 _xofs; int16 _havinit; uint16 _seed; diff --git a/engines/agos/draw.cpp b/engines/agos/draw.cpp index d09f02c76d..45443aa335 100644 --- a/engines/agos/draw.cpp +++ b/engines/agos/draw.cpp @@ -503,7 +503,7 @@ void AGOSEngine::saveBackGround(VgaSprite *vsp) { animTable->y = y; animTable->width = READ_BE_UINT16(ptr + 6) / 16; - if (vsp->flags & 40) { + if (vsp->flags & 0x40) { animTable->width++; } diff --git a/engines/agos/event.cpp b/engines/agos/event.cpp index b9c16d3d86..cbb09e1ec7 100644 --- a/engines/agos/event.cpp +++ b/engines/agos/event.cpp @@ -484,7 +484,7 @@ void AGOSEngine::delay(uint amount) { _fastMode ^= 1; } else if (event.kbd.keycode == Common::KEYCODE_d) { _debugger->attach(); - } else if (event.kbd.keycode == Common::KEYCODE_u) { + } else if (event.kbd.keycode == Common::KEYCODE_s) { dumpAllSubroutines(); } else if (event.kbd.keycode == Common::KEYCODE_i) { dumpAllVgaImageFiles(); diff --git a/engines/agos/pn.cpp b/engines/agos/pn.cpp index fd88d63ec3..d92efa9077 100644 --- a/engines/agos/pn.cpp +++ b/engines/agos/pn.cpp @@ -269,16 +269,16 @@ void AGOSEngine_PN::processor() { _variableArray[16] = _quickshort[6]; _variableArray[17] = _quickshort[7]; _variableArray[19] = getptr(55L); + + // q indicates the process to run and is 0 the first time, + // but 1 later on (i.e., when we are "called" from badload()). setposition(q, 0); doline(0); } void AGOSEngine_PN::setqptrs() { - int a = 0; - - while (a < 11) { - _quickptr[a] = getlong(3L * a); - a++; + for (int i = 0; i < 11; ++i) { + _quickptr[i] = getlong(3 * i); } _quickptr[11] = getlong(58L); _quickptr[12] = getlong(61L); diff --git a/engines/agos/res_snd.cpp b/engines/agos/res_snd.cpp index 810f953bd7..e85440d8e1 100644 --- a/engines/agos/res_snd.cpp +++ b/engines/agos/res_snd.cpp @@ -332,7 +332,7 @@ void AGOSEngine::playSting(uint16 soundId) { mus_file.seek(soundId * 2, SEEK_SET); mus_offset = mus_file.readUint16LE(); - if (mus_file.ioFailed()) + if (mus_file.err()) error("playSting: Can't read sting %d offset", soundId); mus_file.seek(mus_offset, SEEK_SET); diff --git a/engines/agos/script_pn.cpp b/engines/agos/script_pn.cpp index 62ca94e387..4f9aab2965 100644 --- a/engines/agos/script_pn.cpp +++ b/engines/agos/script_pn.cpp @@ -30,17 +30,21 @@ namespace AGOS { +enum { + kJmpClassNum = -1 +}; + #define OPCODE(x) _OPCODE(AGOSEngine_PN, x) void AGOSEngine_PN::setupOpcodes() { static const OpcodeEntryPN opcodes[] = { /* 00 */ OPCODE(opn_opcode00), - OPCODE(opn_opcode01), - OPCODE(opn_opcode02), - OPCODE(opn_opcode03), + OPCODE(opn_add), + OPCODE(opn_sub), + OPCODE(opn_mul), /* 04 */ - OPCODE(opn_opcode04), + OPCODE(opn_div), OPCODE(opn_opcode05), OPCODE(opn_opcode06), OPCODE(opn_opcode07), @@ -56,11 +60,11 @@ void AGOSEngine_PN::setupOpcodes() { OPCODE(opn_opcode15), /* 16 */ OPCODE(opn_opcode16), - OPCODE(opn_opcode17), - OPCODE(opn_opcode18), - OPCODE(opn_opcode19), + OPCODE(opn_lt), + OPCODE(opn_gt), + OPCODE(opn_eq), /* 20 */ - OPCODE(opn_opcode20), + OPCODE(opn_neq), OPCODE(opn_opcode21), OPCODE(opn_opcode22), OPCODE(opn_opcode23), @@ -122,13 +126,14 @@ void AGOSEngine_PN::setupOpcodes() { void AGOSEngine_PN::executeOpcode(int opcode) { OpcodeProcPN op = _opcodesPN[opcode].proc; - (this->*op) (); + (this->*op)(); } -#define readfromline() (_linct-- ? (int)*_workptr++ : readoverr()) - -int readoverr() { - error("readfromline: Internal Error - Line Over-run"); +int AGOSEngine_PN::readfromline() { + if (!_linct) + error("readfromline: Internal Error - Line Over-run"); + _linct--; + return *_workptr++; } // ----------------------------------------------------------------------- @@ -142,30 +147,30 @@ void AGOSEngine_PN::opn_opcode00() { setScriptReturn(true); } -void AGOSEngine_PN::opn_opcode01() { +void AGOSEngine_PN::opn_add() { uint8 *str = _workptr; int32 sp = varval() + varval(); _variableArray[12] = sp % 65536; _variableArray[13] = sp / 65536; if (sp > 65535) - sp=65535; + sp = 65535; writeval(str, (int)sp); setScriptReturn(true); } -void AGOSEngine_PN::opn_opcode02() { +void AGOSEngine_PN::opn_sub() { uint8 *str = _workptr; int32 sp = varval(); sp -= varval(); _variableArray[12] = sp % 65536; _variableArray[13] = sp / 65536; - if(sp < 0) + if (sp < 0) sp = 0; writeval(str, (int)sp); setScriptReturn(true); } -void AGOSEngine_PN::opn_opcode03() { +void AGOSEngine_PN::opn_mul() { uint8 *str = _workptr; int32 sp = varval() * varval(); _variableArray[12] = sp % 65536; @@ -176,12 +181,12 @@ void AGOSEngine_PN::opn_opcode03() { setScriptReturn(true); } -void AGOSEngine_PN::opn_opcode04() { +void AGOSEngine_PN::opn_div() { uint8 *str = _workptr; int32 sp = varval(); int32 sp2 = varval(); if (sp2 == 0) - error("Division by 0"); + error("opn_div: Division by 0"); sp = sp / sp2; _variableArray[12] = sp % 65536; _variableArray[13] = sp / 65536; @@ -234,7 +239,7 @@ void AGOSEngine_PN::opn_opcode12() { char bf[8]; int a = 0; sprintf(bf,"%d", varval()); - while(bf[a]) + while (bf[a]) pcf(bf[a++]); setScriptReturn(true); } @@ -243,7 +248,7 @@ void AGOSEngine_PN::opn_opcode13() { char bf[8]; int a = 0; sprintf(bf,"%d", varval()); - while(bf[a]) + while (bf[a]) pcf(bf[a++]); pcf((uint8)'\n'); setScriptReturn(true); @@ -271,25 +276,25 @@ void AGOSEngine_PN::opn_opcode16() { setScriptReturn((sp >= 0 && sp <= 4)); } -void AGOSEngine_PN::opn_opcode17() { +void AGOSEngine_PN::opn_lt() { int16 v1 = varval(); int16 v2 = varval(); setScriptReturn(v1 < v2); } -void AGOSEngine_PN::opn_opcode18() { +void AGOSEngine_PN::opn_gt() { int16 v1 = varval(); int16 v2 = varval(); setScriptReturn(v1 > v2); } -void AGOSEngine_PN::opn_opcode19() { +void AGOSEngine_PN::opn_eq() { int16 v1 = varval(); int16 v2 = varval(); setScriptReturn(v1 == v2); } -void AGOSEngine_PN::opn_opcode20() { +void AGOSEngine_PN::opn_neq() { int16 v1 = varval(); int16 v2 = varval(); setScriptReturn(v1 != v2); @@ -302,11 +307,10 @@ void AGOSEngine_PN::opn_opcode21() { void AGOSEngine_PN::opn_opcode22() { int pf[8]; - int a; - a = varval(); - funcentry(pf, a); + int n = varval(); + funcentry(pf, n); funccpy(pf); - setposition(a, 0); + setposition(n, 0); setScriptReturn(true); } @@ -315,19 +319,27 @@ void AGOSEngine_PN::opn_opcode23() { } void AGOSEngine_PN::opn_opcode24() { - popstack(-1); + popstack(kJmpClassNum); + // Jump back to the last doline, which will return 2-1=1. + // That value then is returned to actCallD, which once again + // returns it. In the end, this amounts to a setScriptReturn(true) + // (but possibly in a different level than the current one). longjmp(*(_stackbase->savearea), 2); setScriptReturn(false); } void AGOSEngine_PN::opn_opcode25() { - popstack(-1); + popstack(kJmpClassNum); + // Jump back to the last doline, which will return 1-1=0. + // That value then is returned to actCallD, which once again + // returns it. In the end, this amounts to a setScriptReturn(false) + // (but possibly in a different level than the current one). longjmp(*(_stackbase->savearea), 1); setScriptReturn(false); } void AGOSEngine_PN::opn_opcode26() { - while ((_stackbase->classnum != -1) && (_stackbase != NULL)) + while ((_stackbase != NULL) && (_stackbase->classnum != kJmpClassNum)) junkstack(); dumpstack(); setScriptReturn(true); @@ -347,6 +359,8 @@ void AGOSEngine_PN::opn_opcode28() { void AGOSEngine_PN::opn_opcode29() { popstack(varval()); + // Jump back to the last doline indicated by the top stackfram. + // The -1 tells it to simply go on with its business. longjmp(*(_stackbase->savearea), -1); setScriptReturn(false); } @@ -395,7 +409,8 @@ void AGOSEngine_PN::opn_opcode32() { char bf[60]; int a, slot; - if ((a = varval()) > 2) { + a = varval(); + if (a > 2) { setScriptReturn(true); return; } @@ -451,10 +466,8 @@ void AGOSEngine_PN::opn_opcode35() { } void AGOSEngine_PN::opn_opcode36() { - int ct = 0; - while (ct < _dataBase[57] + 1) - _wordcp[ct++] = 0; - ct = 1; + for (int i = 0; i < _dataBase[57] + 1; ++i) + _wordcp[i] = 0; if (isspace(*_inpp)) while ((*_inpp) && (isspace(*_inpp))) _inpp++; @@ -468,6 +481,8 @@ void AGOSEngine_PN::opn_opcode36() { setScriptReturn(true); return; } + + int ct = 1; while ((*_inpp != '.') && (*_inpp != ',') && (!isspace(*_inpp)) && (*_inpp != '\0') && (*_inpp!='"')) { if (ct < _dataBase[57]) @@ -734,37 +749,38 @@ int AGOSEngine_PN::varval() { int a; int b; - if ((a = readfromline()) < 247) { + a = readfromline(); + if (a < 247) { return a; } switch (a) { case 249: b = readfromline(); - return((int)(b + 256 * readfromline())); + return (int)(b + 256 * readfromline()); break; case 250: - return(readfromline()); + return readfromline(); case 251: - return((int)_variableArray[varval()]); + return (int)_variableArray[varval()]; case 252: b = varval(); - return((int)_dataBase[_quickptr[0] + b * _quickshort[0] + varval()]); + return (int)_dataBase[_quickptr[0] + b * _quickshort[0] + varval()]; case 254: b = varval(); - return((int)_dataBase[_quickptr[3] + b * _quickshort[2] + varval()]); + return (int)_dataBase[_quickptr[3] + b * _quickshort[2] + varval()]; case 247: b = varval(); - return((int)getptr(_quickptr[11] + (b * _quickshort[4]) + (2 * varval()))); + return (int)getptr(_quickptr[11] + (b * _quickshort[4]) + (2 * varval())); case 248: b = varval(); - return((int)getptr(_quickptr[12] + (b * _quickshort[5]) + (2 * varval()))); + return (int)getptr(_quickptr[12] + (b * _quickshort[5]) + (2 * varval())); case 253: b = varval(); - return(bitextract((int32)_quickptr[1] + b * _quickshort[1], varval())); + return bitextract((int32)_quickptr[1] + b * _quickshort[1], varval()); case 255: b = varval(); - return(bitextract((int32)_quickptr[4] + b * _quickshort[3], varval())); + return bitextract((int32)_quickptr[4] + b * _quickshort[3], varval()); default: error("VARVAL : Illegal code %d encountered", a); } @@ -834,10 +850,10 @@ void AGOSEngine_PN::setbitf(uint32 ptr, int offs, int val) { int AGOSEngine_PN::actCallD(int n) { int pf[8]; funcentry(pf, n); - addstack(-1); + addstack(kJmpClassNum); funccpy(pf); setposition(n, 0); - return(doline(1)); + return doline(1); } int AGOSEngine_PN::doaction() { @@ -859,47 +875,59 @@ int AGOSEngine_PN::doaction() { int AGOSEngine_PN::doline(int needsave) { int x; - jmp_buf *ljmpbuff = NULL; + jmp_buf *old_jmpbuf = NULL; jmp_buf *mybuf; mybuf = (jmp_buf *)malloc(sizeof(jmp_buf)); if (mybuf == NULL) error("doline: Out of memory - stack overflow"); - if ((x = setjmp(*mybuf)) > 0) { + x = setjmp(*mybuf); + // Looking at the longjmp calls below, x can be -1, 1 or 2 + // (and of course 0 when it returns directly, as always). + if (x > 0) { dumpstack(); - _cjmpbuff = ljmpbuff; + // Restore the active jmpbuf to its previous value, + // then return the longjmp value (will be 2-1=1 or 1-1=0). + _cjmpbuff = old_jmpbuf; free((char *)mybuf); return (x - 1); } if (x == -1) { + // Make this doline instance the active one (again). + // This is used to "return" over possibly multiple + // layers of nested script invocations. + // Kind of like throwing an exception. _cjmpbuff = mybuf; goto carryon; } - ljmpbuff = _cjmpbuff; + + // Remember the previous active jmpbuf (gets restored + // above when a longjmp with a positive param occurs). + old_jmpbuf = _cjmpbuff; _cjmpbuff = mybuf; if (needsave) _stackbase->savearea = mybuf; -nln: _linct = ((*_linebase) & 127) - 1; - _workptr = _linebase + 1; - if (*_linebase > 127) { - x = varval(); - if (x != (int)_variableArray[1]) - goto skipln; - } - -carryon: do { - x = doaction(); - } while (x && !shouldQuit()); + _linct = ((*_linebase) & 127) - 1; + _workptr = _linebase + 1; + if (*_linebase > 127) { + x = varval(); + if (x != (int)_variableArray[1]) + goto skipln; + } -skipln: _linebase += 127 & *_linebase; - _linembr++; +carryon: + do { + x = doaction(); + } while (x && !shouldQuit()); - if (!shouldQuit()) - goto nln; +skipln: + _linebase += 127 & *_linebase; + _linembr++; + } while (!shouldQuit()); return 0; } @@ -951,23 +979,15 @@ int AGOSEngine_PN::findset() { } void AGOSEngine_PN::funccpy(int *store) { - int a = 0; - int b = 24; - - while (a < 8) { - _variableArray[b++] = *store++; - a++; + for (int i = 24; i < 32; ++i) { + _variableArray[i] = *store++; } } void AGOSEngine_PN::funcentry(int *store, int procn) { - int ct = 0; - int nprm; - - nprm = _dataBase[getlong(_quickptr[6] + 3L * procn)]; - while (ct < nprm) { + int numParams = _dataBase[getlong(_quickptr[6] + 3 * procn)]; + for (int i = 0; i < numParams; ++i) { *store++ = varval(); - ct++; } } @@ -990,23 +1010,28 @@ int AGOSEngine_PN::gvwrd(uint8 *wptr, int mask) { int AGOSEngine_PN::setposition(int process, int line) { uint8 *ourptr; int np; - int ct = 0; - ourptr = _dataBase + getlong(_quickptr[6] + 3L * process); + int ct; + + ourptr = _dataBase + getlong(_quickptr[6] + 3 * process); np = *ourptr++; - while (ct < line) { + for (ct = 0; ct < line; ++ct) { ourptr += (127 & *ourptr); - ct++; } -x1: _linebase = ourptr; - _linct = (127 & (*ourptr)) - 1; - if (*ourptr++ > 127) { + + while (true) { + _linebase = ourptr; + _linct = (127 & *ourptr) - 1; + if (*ourptr++ <= 127) + break; + ct = varval(); - if (ct != (int)_variableArray[1]) { - ourptr += _linct - 1; - line++; - goto x1; - } + if (ct == (int)_variableArray[1]) + break; + + ourptr += _linct - 1; + line++; } + _linembr = line; _procnum = process; _variableArray[0] = process; @@ -1035,22 +1060,20 @@ int AGOSEngine_PN::wrdmatch(uint8 *word1, int mask1, uint8 *word2, int mask2) { // ----------------------------------------------------------------------- void AGOSEngine_PN::addstack(int type) { - struct stackframe *a; - int pt, ct = 0; + StackFrame *a; + int i; - a = (struct stackframe *)malloc(sizeof(struct stackframe)); + a = (StackFrame *)malloc(sizeof(StackFrame)); if (a == NULL) error("addstack: Out of memory - stack overflow"); a->nextframe = _stackbase; _stackbase = a; - pt = 0; - while (ct < 6) - a->flag[ct++] = _variableArray[pt++]; - ct = 0; - pt = 24; - while (ct < 8) - a->param[ct++] = _variableArray[pt++]; + + for (i = 0; i < 6; ++i) + a->flag[i] = _variableArray[i]; + for (i = 0; i < 8; ++i) + a->param[i] = _variableArray[24 + i]; a->classnum = type; a->ll = _linct; a->linenum = _linembr; @@ -1060,7 +1083,7 @@ void AGOSEngine_PN::addstack(int type) { } void AGOSEngine_PN::dumpstack() { - struct stackframe *a; + StackFrame *a; if (_stackbase == NULL) error("dumpstack: Stack underflow or unknown longjmp"); @@ -1071,20 +1094,20 @@ void AGOSEngine_PN::dumpstack() { } void AGOSEngine_PN::junkstack() { - struct stackframe *a; + StackFrame *a; if (_stackbase == NULL) error("junkstack: Stack underflow or unknown longjmp"); a = _stackbase->nextframe; - if (_stackbase->classnum == -1) + if (_stackbase->classnum == kJmpClassNum) free((char *)_stackbase->savearea); free((char *)_stackbase); _stackbase = a; } void AGOSEngine_PN::popstack(int type) { - int a = 0, b; + int i; while ((_stackbase != NULL) && (_stackbase->classnum != type)) junkstack(); @@ -1097,13 +1120,10 @@ void AGOSEngine_PN::popstack(int type) { _workptr = _stackbase->linpos; _procnum = _stackbase->process; _linembr = _stackbase->linenum; - b = 0; - while (a < 6) - _variableArray[b++] = _stackbase->flag[a++]; - b = 24; - a = 0; - while (a < 8) - _variableArray[b++] = _stackbase->param[a++]; + for (i = 0; i < 6; ++i) + _variableArray[i] = _stackbase->flag[i]; + for (i = 0; i < 8; ++i) + _variableArray[24 + i] = _stackbase->param[i]; } } // End of namespace AGOS diff --git a/engines/agos/string.cpp b/engines/agos/string.cpp index a466be796f..3773b1fa10 100644 --- a/engines/agos/string.cpp +++ b/engines/agos/string.cpp @@ -136,6 +136,20 @@ const byte *AGOSEngine::getStringPtrByID(uint16 stringId, bool upperCase) { strcpy((char *)dst, (const char *)stringPtr); } + // WORKAROUND bug #1538873: The French version of Simon 1 and the + // Polish version of Simon 2 used excess spaces, at the end of many + // messages, so we strip off those excess spaces. + if ((getGameType() == GType_SIMON1 && _language == Common::FR_FRA) || + (getGameType() == GType_SIMON2 && _language == Common::PL_POL)) { + uint16 len = strlen((const char *)dst) - 1; + + while (len && dst[len] == 32) { + dst[len] = 0; + len--; + } + + } + if (upperCase && *dst) { if (islower(*dst)) *dst = toupper(*dst); diff --git a/engines/agos/vga.cpp b/engines/agos/vga.cpp index d2e620d86e..d37681508e 100644 --- a/engines/agos/vga.cpp +++ b/engines/agos/vga.cpp @@ -1186,7 +1186,8 @@ void AGOSEngine::vc32_saveScreen() { byte *src = (byte *)screen->pixels; for (int i = 0; i < _screenHeight; i++) { memcpy(dst, src, _screenWidth); - dst += screen->pitch; + dst += _backGroundBuf->pitch; + src += screen->pitch; } _system->unlockScreen(); } else { diff --git a/engines/agos/vga_e2.cpp b/engines/agos/vga_e2.cpp index 7f02398e13..f6e6630d43 100644 --- a/engines/agos/vga_e2.cpp +++ b/engines/agos/vga_e2.cpp @@ -207,6 +207,7 @@ void AGOSEngine::vc53_dissolveIn() { uint16 speed = vcReadNextWord() + 1; byte *src, *dst, *srcOffs, *srcOffs2, *dstOffs, *dstOffs2; + int16 xoffs, yoffs; uint8 color = 0; // Only uses Video Window 4 @@ -218,15 +219,13 @@ void AGOSEngine::vc53_dissolveIn() { uint16 dissolveDelay = dissolveCheck * 2 / speed; uint16 dissolveCount = dissolveCheck * 2 / speed; - Graphics::Surface *screen = _system->lockScreen(); - - int16 xoffs = _videoWindows[num * 4 + 0] * 16; - int16 yoffs = _videoWindows[num * 4 + 1]; - int16 offs = xoffs + yoffs * screen->pitch; + int16 x = _videoWindows[num * 4 + 0] * 16; + int16 y = _videoWindows[num * 4 + 1]; uint16 count = dissolveCheck * 2; while (count--) { - byte *dstPtr = (byte *)screen->pixels + offs; + Graphics::Surface *screen = _system->lockScreen(); + byte *dstPtr = (byte *)screen->pixels + x + y * screen->pitch; yoffs = _rnd.getRandomNumber(dissolveY); dst = dstPtr + yoffs * screen->pitch; @@ -285,6 +284,7 @@ void AGOSEngine::vc54_dissolveOut() { uint16 speed = vcReadNextWord() + 1; byte *dst, *dstOffs; + int16 xoffs, yoffs; uint16 dissolveX = _videoWindows[num * 4 + 2] * 8; uint16 dissolveY = (_videoWindows[num * 4 + 3] + 1) / 2; @@ -292,15 +292,13 @@ void AGOSEngine::vc54_dissolveOut() { uint16 dissolveDelay = dissolveCheck * 2 / speed; uint16 dissolveCount = dissolveCheck * 2 / speed; - Graphics::Surface *screen = _system->lockScreen(); - - int16 xoffs = _videoWindows[num * 4 + 0] * 16; - int16 yoffs = _videoWindows[num * 4 + 1]; - int16 offs = xoffs + yoffs * screen->pitch; + int16 x = _videoWindows[num * 4 + 0] * 16; + int16 y = _videoWindows[num * 4 + 1]; uint16 count = dissolveCheck * 2; while (count--) { - byte *dstPtr = (byte *)screen->pixels + offs; + Graphics::Surface *screen = _system->lockScreen(); + byte *dstPtr = (byte *)screen->pixels + x + y * screen->pitch; color |= dstPtr[0] & 0xF0; yoffs = _rnd.getRandomNumber(dissolveY); diff --git a/engines/agos/vga_pn.cpp b/engines/agos/vga_pn.cpp index 32c6e15f00..12846b08f1 100644 --- a/engines/agos/vga_pn.cpp +++ b/engines/agos/vga_pn.cpp @@ -129,7 +129,6 @@ void AGOSEngine::vc36_pause() { _keyPressed.reset(); windowPutChar(_windowArray[2], 13); - windowPutChar(_windowArray[2], 128); _wiped = oldWiped; _videoLockOut &= ~8; diff --git a/engines/cine/saveload.cpp b/engines/cine/saveload.cpp index ea0ff0079b..be1e19b229 100644 --- a/engines/cine/saveload.cpp +++ b/engines/cine/saveload.cpp @@ -49,7 +49,7 @@ bool loadChunkHeader(Common::SeekableReadStream &in, ChunkHeader &header) { header.id = in.readUint32BE(); header.version = in.readUint32BE(); header.size = in.readUint32BE(); - return !in.ioFailed(); + return !(in.eos() || in.err()); } /*! \brief Savegame format detector @@ -240,21 +240,21 @@ bool loadObjectTable(Common::SeekableReadStream &in) { in.read(objectTable[i].name, 20); objectTable[i].part = in.readUint16BE(); } - return !in.ioFailed(); + return !(in.eos() || in.err()); } bool loadZoneData(Common::SeekableReadStream &in) { for (int i = 0; i < 16; i++) { zoneData[i] = in.readUint16BE(); } - return !in.ioFailed(); + return !(in.eos() || in.err()); } bool loadCommandVariables(Common::SeekableReadStream &in) { for (int i = 0; i < 4; i++) { commandVar3[i] = in.readUint16BE(); } - return !in.ioFailed(); + return !(in.eos() || in.err()); } bool loadScreenParams(Common::SeekableReadStream &in) { @@ -265,7 +265,7 @@ bool loadScreenParams(Common::SeekableReadStream &in) { in.readUint16BE(); in.readUint16BE(); in.readUint16BE(); - return !in.ioFailed(); + return !(in.eos() || in.err()); } bool loadGlobalScripts(Common::SeekableReadStream &in) { @@ -273,7 +273,7 @@ bool loadGlobalScripts(Common::SeekableReadStream &in) { for (int i = 0; i < size; i++) { loadScriptFromSave(in, true); } - return !in.ioFailed(); + return !(in.eos() || in.err()); } bool loadObjectScripts(Common::SeekableReadStream &in) { @@ -281,7 +281,7 @@ bool loadObjectScripts(Common::SeekableReadStream &in) { for (int i = 0; i < size; i++) { loadScriptFromSave(in, false); } - return !in.ioFailed(); + return !(in.eos() || in.err()); } bool loadOverlayList(Common::SeekableReadStream &in) { @@ -289,7 +289,7 @@ bool loadOverlayList(Common::SeekableReadStream &in) { for (int i = 0; i < size; i++) { loadOverlayFromSave(in); } - return !in.ioFailed(); + return !(in.eos() || in.err()); } bool loadSeqList(Common::SeekableReadStream &in) { @@ -312,14 +312,14 @@ bool loadSeqList(Common::SeekableReadStream &in) { tmp.var1E = in.readSint16BE(); seqList.push_back(tmp); } - return !in.ioFailed(); + return !(in.eos() || in.err()); } bool loadZoneQuery(Common::SeekableReadStream &in) { for (int i = 0; i < 16; i++) { zoneQuery[i] = in.readUint16BE(); } - return !in.ioFailed(); + return !(in.eos() || in.err()); } void saveObjectTable(Common::OutSaveFile &out) { @@ -632,7 +632,7 @@ bool CineEngine::loadTempSaveOS(Common::SeekableReadStream &in) { warning("loadTempSaveOS: Loaded the savefile but didn't exhaust it completely. Something was left over"); } - return !in.ioFailed(); + return !(in.eos() || in.err()); } bool CineEngine::loadPlainSaveFW(Common::SeekableReadStream &in, CineSaveGameFormat saveGameFormat) { @@ -755,7 +755,7 @@ bool CineEngine::loadPlainSaveFW(Common::SeekableReadStream &in, CineSaveGameFor } } - return !in.ioFailed(); + return !(in.eos() || in.err()); } bool CineEngine::makeLoad(char *saveName) { diff --git a/engines/cruise/actor.cpp b/engines/cruise/actor.cpp index 969be96573..845867409e 100644 --- a/engines/cruise/actor.cpp +++ b/engines/cruise/actor.cpp @@ -528,7 +528,7 @@ void valide_noeud(int16 table[], int16 p, int *nclick, int16 solution0[20 + 3][2 return; } - /****** COUPE LE CHEMIN ******/ + /****** Trim down any un-necessary walk points ******/ i++; d = 0; diff --git a/engines/cruise/cruise_main.cpp b/engines/cruise/cruise_main.cpp index 711f7bdf94..e5864ebb31 100644 --- a/engines/cruise/cruise_main.cpp +++ b/engines/cruise/cruise_main.cpp @@ -1626,11 +1626,14 @@ int currentMouseButton = 0; bool bFastMode = false; -void manageEvents() { +bool manageEvents() { Common::Event event; + bool result = false; Common::EventManager * eventMan = g_system->getEventManager(); - while (eventMan->pollEvent(event)) { + while (eventMan->pollEvent(event) && !result) { + result = true; + switch (event.type) { case Common::EVENT_LBUTTONDOWN: currentMouseButton |= MB_LEFT; @@ -1647,11 +1650,12 @@ void manageEvents() { case Common::EVENT_MOUSEMOVE: currentMouseX = event.mouse.x; currentMouseY = event.mouse.y; + result = false; break; case Common::EVENT_QUIT: case Common::EVENT_RTL: playerDontAskQuit = 1; - return; + break; case Common::EVENT_KEYUP: switch (event.kbd.keycode) { case Common::KEYCODE_ESCAPE: @@ -1671,72 +1675,6 @@ void manageEvents() { break; } - /* - * switch (event.kbd.keycode) { - * case '\n': - * case '\r': - * case 261: // Keypad 5 - * if (allowPlayerInput) { - * mouseLeft = 1; - * } - * break; - * case 27: // ESC - * if (allowPlayerInput) { - * mouseRight = 1; - * } - * break; - * case 282: // F1 - * if (allowPlayerInput) { - * playerCommand = 0; // EXAMINE - * makeCommandLine(); - * } - * break; - * case 283: // F2 - * if (allowPlayerInput) { - * playerCommand = 1; // TAKE - * makeCommandLine(); - * } - * break; - * case 284: // F3 - * if (allowPlayerInput) { - * playerCommand = 2; // INVENTORY - * makeCommandLine(); - * } - * break; - * case 285: // F4 - * if (allowPlayerInput) { - * playerCommand = 3; // USE - * makeCommandLine(); - * } - * break; - * case 286: // F5 - * if (allowPlayerInput) { - * playerCommand = 4; // ACTIVATE - * makeCommandLine(); - * } - * break; - * case 287: // F6 - * if (allowPlayerInput) { - * playerCommand = 5; // SPEAK - * makeCommandLine(); - * } - * break; - * case 290: // F9 - * if (allowPlayerInput && !inMenu) { - * makeActionMenu(); - * makeCommandLine(); - * } - * break; - * case 291: // F10 - * if (!disableSystemMenu && !inMenu) { - * g_cine->makeSystemMenu(); - * } - * break; - * default: - * //lastKeyStroke = event.kbd.keycode; - * break; - * } - * break; */ if (event.kbd.flags == Common::KBD_CTRL) { if (event.kbd.keycode == Common::KEYCODE_d) { // Start the debugger @@ -1753,17 +1691,10 @@ void manageEvents() { } } - /*if (count) { - * mouseData.left = mouseLeft; - * mouseData.right = mouseRight; - * mouseLeft = 0; - * mouseRight = 0; - * } - */ + return result; } void getMouseStatus(int16 *pMouseVar, int16 *pMouseX, int16 *pMouseButton, int16 *pMouseY) { - manageEvents(); *pMouseX = currentMouseX; *pMouseY = currentMouseY; *pMouseButton = currentMouseButton; @@ -1806,11 +1737,15 @@ void CruiseEngine::mainLoop(void) { if (!bFastMode) { // Delay for the specified amount of time, but still respond to events + bool skipEvents = false; + while (currentTick < lastTick + _gameSpeed) { g_system->delayMillis(10); currentTick = g_system->getMillis(); - manageEvents(); + if (!skipEvents) + skipEvents = manageEvents(); + if (playerDontAskQuit) break; if (_vm->getDebugger()->isAttached()) @@ -1906,7 +1841,7 @@ void CruiseEngine::mainLoop(void) { getMouseStatus(&main10, &mouseX, &mouseButton, &mouseY); - if (mouseX != oldMouseX && mouseY != oldMouseY) { + if (mouseX != oldMouseX || mouseY != oldMouseY) { int objectType; int newCursor1; int newCursor2; diff --git a/engines/cruise/ctp.cpp b/engines/cruise/ctp.cpp index 11d5f582ed..aa2a6c7772 100644 --- a/engines/cruise/ctp.cpp +++ b/engines/cruise/ctp.cpp @@ -106,7 +106,7 @@ void renderCTPWalkBox(int16 *walkboxData, int hotPointX, int hotPointY, int X, i int16 *destination; int startX = X - ((upscaleValue(hotPointX, scale) + 0x8000) >> 16); -// int startY = Y - ((upscaleValue(hotPointY, scale) + 0x8000) >> 16); + int startY = Y - ((upscaleValue(hotPointY, scale) + 0x8000) >> 16); numPoints = *(walkboxData++); @@ -117,7 +117,7 @@ void renderCTPWalkBox(int16 *walkboxData, int hotPointX, int hotPointY, int X, i int pointY = *(walkboxData++); int scaledX = ((upscaleValue(pointX, scale) + 0x8000) >> 16) + startX; - int scaledY = ((upscaleValue(pointY, scale) + 0x8000) >> 16) + startX; + int scaledY = ((upscaleValue(pointY, scale) + 0x8000) >> 16) + startY; *(destination++) = scaledX; *(destination++) = scaledY; diff --git a/engines/cruise/menu.cpp b/engines/cruise/menu.cpp index 0e9ab55c82..54f686f32a 100644 --- a/engines/cruise/menu.cpp +++ b/engines/cruise/menu.cpp @@ -146,7 +146,7 @@ void updateMenuMouse(int mouseX, int mouseY, menuStruct *pMenu) { } } -void manageEvents(); +bool manageEvents(); int processMenu(menuStruct *pMenu) { int16 mouseX; diff --git a/engines/gob/detection.cpp b/engines/gob/detection.cpp index 3827c3635c..61c17b16f8 100644 --- a/engines/gob/detection.cpp +++ b/engines/gob/detection.cpp @@ -68,6 +68,7 @@ static const PlainGameDescriptor gobGames[] = { {"playtoons5", "Playtoons 5 - The Stone of Wakan"}, {"playtnck1", "Playtoons Construction Kit 1 - Monsters"}, {"playtnck2", "Playtoons Construction Kit 2 - Knights"}, + {"playtnck3", "Playtoons Construction Kit 3 - Far West"}, {"bambou", "Playtoons Limited Edition - Bambou le sauveur de la jungle"}, {"fascination", "Fascination"}, {"geisha", "Geisha"}, @@ -3560,7 +3561,6 @@ static const GOBGameDescription gameDescriptions[] = { kFeatures640, "intro2.stk", 0, 0 }, - { { "playtoons4", @@ -3579,6 +3579,24 @@ static const GOBGameDescription gameDescriptions[] = { kFeatures640, "intro2.stk", 0, 0 }, + { //Supplied by goodoldgeorg in bug report #2820006 + { + "playtoons4", + "", + { + {"playtoon.stk", 0, "9e513e993a5b0e2496add3f50c08764b", 30448506}, + {"manda.stk", 0, "69a79c9f61b2618e482726f2ff68078d", 6499208}, + {0, 0, 0, 0} + }, + EN_ANY, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH + }, + kGameTypePlaytoon, + kFeatures640, + "intro2.stk", 0, 0 + }, { { "playtoons5", @@ -3653,6 +3671,24 @@ static const GOBGameDescription gameDescriptions[] = { }, { { + "playtnck3", + "", + { + {"playtoon.stk", 0, "5f9aae29265f1f105ad8ec195dff81de", 68382024}, + {"dan.itk", 0, "9a8f62809eca5a52f429b5b6a8e70f8f", 2861056}, + {0, 0, 0, 0} + }, + FR_FRA, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH + }, + kGameTypePlaytnCk, + kFeatures640, + "intro2.stk", 0, 0 + }, + { + { "magicstones", "", { diff --git a/engines/gob/resources.cpp b/engines/gob/resources.cpp index 20427e547b..c52b65f0d7 100644 --- a/engines/gob/resources.cpp +++ b/engines/gob/resources.cpp @@ -158,29 +158,29 @@ bool Resources::load(const Common::String &fileName) { _extFile = fileBase + ".ext"; - if (!loadTOTResourceTable()) { - unload(); - return false; - } + bool hasTOTRes = loadTOTResourceTable(); + bool hasEXTRes = loadEXTResourceTable(); - if (!loadEXTResourceTable()) { - unload(); + if (!hasTOTRes && !hasEXTRes) return false; - } - if (!loadTOTTextTable(fileBase)) { - unload(); - return false; - } + if (hasTOTRes) { + if (!loadTOTTextTable(fileBase)) { + unload(); + return false; + } - if (!loadIMFile()) { - unload(); - return false; + if (!loadIMFile()) { + unload(); + return false; + } } - if (!loadEXFile()) { - unload(); - return false; + if (hasEXTRes) { + if (!loadEXFile()) { + unload(); + return false; + } } return true; @@ -255,7 +255,7 @@ bool Resources::loadTOTResourceTable() { TOTResourceItem &item = _totResourceTable->items[i]; item.offset = stream->readSint32LE(); - item.size = stream->readSint16LE(); + item.size = stream->readUint16LE(); item.width = stream->readSint16LE(); item.height = stream->readSint16LE(); @@ -286,7 +286,7 @@ bool Resources::loadEXTResourceTable() { DataStream *stream = _vm->_dataIO->getDataStream(_extFile.c_str()); if (!stream) - return true; + return false; _extResourceTable->itemsCount = stream->readSint16LE(); _extResourceTable->unknown = stream->readByte(); @@ -588,15 +588,22 @@ Resource *Resources::getTOTResource(uint16 id) const { if (totItem.type == kResourceTOT) data = getTOTData(totItem); - if (!data) + if (!data) { + warning("Failed to load TOT resource (%s, %d/%d, %d)", + _totFile.c_str(), id, _totResourceTable->itemsCount - 1, totItem.type); return 0; + } return new Resource(data, totItem.size, false, totItem.width, totItem.height); } Resource *Resources::getEXTResource(uint16 id) const { - if (!_extResourceTable || (id > _extResourceTable->itemsCount)) + if (!_extResourceTable || (id > _extResourceTable->itemsCount)) { + warning("Trying to load non-existent EXT resource (%s, %d/%d)", + _totFile.c_str(), id, + _extResourceTable ? (_extResourceTable->itemsCount - 1) : -1); return 0; + } EXTResourceItem &extItem = _extResourceTable->items[id]; @@ -617,8 +624,11 @@ Resource *Resources::getEXTResource(uint16 id) const { if (extItem.type == kResourceEX) data = getEXData(extItem, size); - if (!data) + if (!data) { + warning("Failed to load EXT resource (%s, %d/%d, %d)", + _totFile.c_str(), id, _extResourceTable->itemsCount - 1, extItem.type); return 0; + } if (extItem.packed) { byte *packedData = data; @@ -635,7 +645,7 @@ Resource *Resources::getEXTResource(uint16 id) const { } byte *Resources::getTOTData(TOTResourceItem &totItem) const { - if (totItem.size < 0) + if (totItem.size == 0) return 0; int32 offset = _totResourceTable->dataOffset + totItem.offset - _totResStart; @@ -647,7 +657,7 @@ byte *Resources::getTOTData(TOTResourceItem &totItem) const { } byte *Resources::getIMData(TOTResourceItem &totItem) const { - if (totItem.size < 0) + if (totItem.size == 0) return 0; int32 indexOffset = totItem.index * 4; diff --git a/engines/gob/resources.h b/engines/gob/resources.h index 80acef645c..d316be83e5 100644 --- a/engines/gob/resources.h +++ b/engines/gob/resources.h @@ -109,7 +109,7 @@ private: struct TOTResourceItem { ResourceType type; - int16 size; + uint16 size; int16 width; int16 height; union { diff --git a/engines/gob/videoplayer.cpp b/engines/gob/videoplayer.cpp index da552d7202..f708729fd8 100644 --- a/engines/gob/videoplayer.cpp +++ b/engines/gob/videoplayer.cpp @@ -156,6 +156,7 @@ VideoPlayer::VideoPlayer(GobEngine *vm) : _vm(vm) { _backSurf = false; _needBlit = false; _noCursorSwitch = false; + _woodruffCohCottWorkaround = false; } VideoPlayer::~VideoPlayer() { @@ -248,6 +249,14 @@ bool VideoPlayer::primaryOpen(const char *videoFile, int16 x, int16 y, _noCursorSwitch = true; } + // WORKAROUND: In Woodruff, Coh Cott vanished in one video on her party. + // This is a bug in video, so we work around it. + _woodruffCohCottWorkaround = false; + if (_vm->getGameType() == kGameTypeWoodruff) { + if (!scumm_stricmp(fileName, "SQ32-03.VMD")) + _woodruffCohCottWorkaround = true; + } + _ownSurf = false; if (!(flags & kFlagNoVideo)) { @@ -316,6 +325,7 @@ bool VideoPlayer::primaryPlay(int16 startFrame, int16 lastFrame, int16 breakKey, endFrame = lastFrame; palCmd &= 0x3F; + int16 realStartFrame = startFrame; if (video.getCurrentFrame() != startFrame) { if (!forceSeek && (video.getFeatures() & Graphics::CoktelVideo::kFeaturesSound)) startFrame = video.getCurrentFrame(); @@ -331,7 +341,9 @@ bool VideoPlayer::primaryPlay(int16 startFrame, int16 lastFrame, int16 breakKey, bool canceled = false; while (startFrame <= lastFrame) { - if (doPlay(startFrame, breakKey, palCmd, palStart, palEnd, palFrame, endFrame)) { + if (doPlay(startFrame, breakKey, + palCmd, palStart, palEnd, palFrame, endFrame, startFrame < realStartFrame)) { + canceled = true; break; } @@ -621,7 +633,7 @@ Common::MemoryReadStream *VideoPlayer::getExtraData(const char *fileName, int sl void VideoPlayer::playFrame(int16 frame, int16 breakKey, uint16 palCmd, int16 palStart, int16 palEnd, - int16 palFrame, int16 endFrame) { + int16 palFrame, int16 endFrame, bool noRetrace) { if (!_primaryVideo) return; @@ -657,6 +669,12 @@ void VideoPlayer::playFrame(int16 frame, int16 breakKey, Graphics::CoktelVideo::State state = video.nextFrame(); WRITE_VAR(11, frame); + if (_woodruffCohCottWorkaround && (frame == 32)) { + // WORKAROUND: This frame mistakenly masks Coh Cott, making her vanish + // To prevent that, we'll never draw that part + state.left += 50; + } + if (_needBlit) _vm->_draw->forceBlit(true); @@ -688,7 +706,9 @@ void VideoPlayer::playFrame(int16 frame, int16 breakKey, _vm->_draw->blitInvalidated(); } else _vm->_video->dirtyRectsAdd(state.left, state.top, state.right, state.bottom); - _vm->_video->retrace(); + + if (!noRetrace) + _vm->_video->retrace(); } @@ -698,9 +718,9 @@ void VideoPlayer::playFrame(int16 frame, int16 breakKey, bool VideoPlayer::doPlay(int16 frame, int16 breakKey, uint16 palCmd, int16 palStart, int16 palEnd, - int16 palFrame, int16 endFrame) { + int16 palFrame, int16 endFrame, bool noRetrace) { - playFrame(frame, breakKey, palCmd, palStart, palEnd, palFrame, endFrame); + playFrame(frame, breakKey, palCmd, palStart, palEnd, palFrame, endFrame, noRetrace); _vm->_util->processInput(); diff --git a/engines/gob/videoplayer.h b/engines/gob/videoplayer.h index ead752d446..532d216d7e 100644 --- a/engines/gob/videoplayer.h +++ b/engines/gob/videoplayer.h @@ -70,7 +70,7 @@ public: void playFrame(int16 frame, int16 breakKey = kShortKeyEscape, uint16 palCmd = 8, int16 palStart = 0, int16 palEnd = 255, - int16 palFrame = -1 , int16 endFrame = -1); + int16 palFrame = -1 , int16 endFrame = -1, bool noRetrace = false); int slotOpen(const char *videoFile, Type which = kVideoTypeTry); void slotPlay(int slot, int16 frame = -1); @@ -152,6 +152,8 @@ private: bool _needBlit; bool _noCursorSwitch; + bool _woodruffCohCottWorkaround; + bool findFile(char *fileName, Type &which); const Video *getVideoBySlot(int slot = -1) const; @@ -162,7 +164,7 @@ private: void copyPalette(Graphics::CoktelVideo &video, int16 palStart = -1, int16 palEnd = -1); bool doPlay(int16 frame, int16 breakKey, uint16 palCmd, int16 palStart, int16 palEnd, - int16 palFrame, int16 endFrame); + int16 palFrame, int16 endFrame, bool noRetrace = false); void evalBgShading(Graphics::CoktelVideo &video); }; diff --git a/engines/groovie/resource.cpp b/engines/groovie/resource.cpp index eda3f0bec0..148fa9c451 100644 --- a/engines/groovie/resource.cpp +++ b/engines/groovie/resource.cpp @@ -98,7 +98,7 @@ uint16 ResMan_t7g::getRef(Common::String name, Common::String scriptname) { uint16 resNum; bool found = false; - for (resNum = 0; !found && !rlFile.ioFailed(); resNum++) { + for (resNum = 0; !found && !rlFile.err() && !rlFile.eos(); resNum++) { // Read the resource name char readname[12]; rlFile.read(readname, 12); diff --git a/engines/kyra/kyra_lok.cpp b/engines/kyra/kyra_lok.cpp index e5ca52abcc..a3a249de18 100644 --- a/engines/kyra/kyra_lok.cpp +++ b/engines/kyra/kyra_lok.cpp @@ -434,7 +434,7 @@ void KyraEngine_LoK::mainLoop() { // FIXME: Why is this here? _screen->showMouse(); - int inputFlag = checkInput(_buttonList, true); + int inputFlag = checkInput(_buttonList, _currentCharacter->sceneId != 210); removeInputTop(); updateMousePointer(); diff --git a/engines/kyra/kyra_v1.cpp b/engines/kyra/kyra_v1.cpp index 80872877d5..258d0c402f 100644 --- a/engines/kyra/kyra_v1.cpp +++ b/engines/kyra/kyra_v1.cpp @@ -115,7 +115,6 @@ Common::Error KyraEngine_v1::init() { _sound = new SoundTownsPC98_v2(this, _mixer); } else if (midiDriver == MD_ADLIB) { _sound = new SoundAdlibPC(this, _mixer); - assert(_sound); } else { Sound::kType type; @@ -126,7 +125,6 @@ Common::Error KyraEngine_v1::init() { else type = Sound::kMidiGM; - MidiDriver *driver = 0; if (midiDriver == MD_PCSPK) { @@ -151,9 +149,10 @@ Common::Error KyraEngine_v1::init() { assert(adlib); _sound = new MixedSoundDriver(this, _mixer, soundMidiPc, adlib); - assert(_sound); } } + + assert(_sound); } if (_sound) diff --git a/engines/kyra/saveload.cpp b/engines/kyra/saveload.cpp index a1aaf77d51..83230d6e3b 100644 --- a/engines/kyra/saveload.cpp +++ b/engines/kyra/saveload.cpp @@ -126,7 +126,7 @@ KyraEngine_v1::kReadSaveHeaderError KyraEngine_v1::readSaveHeader(Common::Seekab } } - return (in->ioFailed() ? kRSHEIoError : kRSHENoError); + return ((in->err() || in->eos()) ? kRSHEIoError : kRSHENoError); } Common::SeekableReadStream *KyraEngine_v1::openSaveForReading(const char *filename, SaveHeader &header) { diff --git a/engines/kyra/scene_v2.cpp b/engines/kyra/scene_v2.cpp index 9ffaf5515d..3def71a076 100644 --- a/engines/kyra/scene_v2.cpp +++ b/engines/kyra/scene_v2.cpp @@ -73,7 +73,7 @@ void KyraEngine_v2::runSceneScript6() { _sceneScriptState.regs[0] = _mainCharacter.sceneId; _sceneScriptState.regs[1] = _mouseX; _sceneScriptState.regs[2] = _mouseY; - _sceneScriptState.regs[3] = _itemInHand; + _sceneScriptState.regs[4] = _itemInHand; _emc->start(&_sceneScriptState, 6); while (_emc->isValid(&_sceneScriptState)) diff --git a/engines/kyra/script_lol.cpp b/engines/kyra/script_lol.cpp index 611ad8f9ef..e4b77f6a07 100644 --- a/engines/kyra/script_lol.cpp +++ b/engines/kyra/script_lol.cpp @@ -2345,8 +2345,8 @@ int LoLEngine::tlol_processWsaFrame(const TIM *tim, const uint16 *param) { int h2 = (h1 * factor) / 100; anim->wsa->displayFrame(frame, 2, x1, y1, anim->wsaCopyParams & 0xF0FF, 0, 0); - _screen->wsaFrameAnimationStep(x1, y1, x2, y2, w1, h1, w2, h2, 2, _flags.isDemo ? 0 : 8, 0); - if (!_flags.isDemo) + _screen->wsaFrameAnimationStep(x1, y1, x2, y2, w1, h1, w2, h2, 2, _flags.isDemo && _flags.platform != Common::kPlatformPC98 ? 0 : 8, 0); + if (!_flags.isDemo && _flags.platform != Common::kPlatformPC98) _screen->checkedPageUpdate(8, 4); _screen->updateScreen(); diff --git a/engines/kyra/script_tim.cpp b/engines/kyra/script_tim.cpp index bc62e5bd6a..731b8d206f 100644 --- a/engines/kyra/script_tim.cpp +++ b/engines/kyra/script_tim.cpp @@ -98,7 +98,10 @@ TIMInterpreter::TIMInterpreter(KyraEngine_v1 *engine, Screen_v2 *screen_v2, OSys _textDisplayed = false; _textAreaBuffer = new uint8[320*40]; assert(_textAreaBuffer); - _drawPage2 = (_vm->gameFlags().isDemo && _vm->gameFlags().gameID == GI_LOL) ? 0 : 8; + if ((_vm->gameFlags().platform == Common::kPlatformPC98 || _vm->gameFlags().isDemo) && _vm->gameFlags().gameID == GI_LOL) + _drawPage2 = 0; + else + _drawPage2 = 8; _palDelayInc = _palDiff = _palDelayAcc = 0; _abortFlag = 0; @@ -461,7 +464,10 @@ TIMInterpreter::Animation *TIMInterpreter::initAnimStruct(int index, const char anim->wsaCopyParams = wsaFlags; const bool isLoLDemo = _vm->gameFlags().isDemo && _vm->gameFlags().gameID == GI_LOL; - _drawPage2 = (isLoLDemo || _currentTim->isLoLOutro) ? 0 : 8; + if (isLoLDemo || _vm->gameFlags().platform == Common::kPlatformPC98 || _currentTim->isLoLOutro) + _drawPage2 = 0; + else + _drawPage2 = 8; uint16 wsaOpenFlags = 0; if (isLoLDemo) { diff --git a/engines/kyra/sequences_lol.cpp b/engines/kyra/sequences_lol.cpp index beea129f66..5826b2b09e 100644 --- a/engines/kyra/sequences_lol.cpp +++ b/engines/kyra/sequences_lol.cpp @@ -224,7 +224,7 @@ void LoLEngine::showIntro() { while (!_tim->finished() && !shouldQuit() && !skipFlag()) { updateInput(); _tim->exec(intro, false); - if (!_flags.isDemo) + if (!_flags.isDemo && _flags.platform != Common::kPlatformPC98) _screen->checkedPageUpdate(8, 4); if (_tim->_palDiff) { diff --git a/engines/kyra/sound.h b/engines/kyra/sound.h index f393ae15ba..263cd586f7 100644 --- a/engines/kyra/sound.h +++ b/engines/kyra/sound.h @@ -8,32 +8,16 @@ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * - * LGPL License - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - - * This library 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 - * Lesser General Public License for more details. - - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * * $URL$ * $Id$ * diff --git a/engines/kyra/sound_adlib.h b/engines/kyra/sound_adlib.h new file mode 100644 index 0000000000..f384113af7 --- /dev/null +++ b/engines/kyra/sound_adlib.h @@ -0,0 +1,113 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * LGPL License + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * $URL$ + * $Id$ + * + */ + +#ifndef KYRA_SOUND_ADLIB_H +#define KYRA_SOUND_ADLIB_H + +#include "kyra/sound.h" + +#include "common/mutex.h" + +namespace Kyra { +class AdlibDriver; + +/** + * AdLib implementation of the sound output device. + * + * It uses a special sound file format special to + * Dune II, Kyrandia 1 and 2. While Dune II and + * Kyrandia 1 are using exact the same format, the + * one of Kyrandia 2 slightly differs. + * + * See AdlibDriver for more information. + * @see AdlibDriver + */ +class SoundAdlibPC : public Sound { +public: + SoundAdlibPC(KyraEngine_v1 *vm, Audio::Mixer *mixer); + ~SoundAdlibPC(); + + kType getMusicType() const { return kAdlib; } + + bool init(); + void process(); + + void loadSoundFile(uint file); + void loadSoundFile(Common::String file); + + void playTrack(uint8 track); + void haltTrack(); + bool isPlaying(); + + void playSoundEffect(uint8 track); + + void beginFadeOut(); +private: + void internalLoadFile(Common::String file); + + void play(uint8 track); + + void unk1(); + void unk2(); + + AdlibDriver *_driver; + + bool _v2; + uint8 _trackEntries[500]; + uint8 *_soundDataPtr; + int _sfxPlayingSound; + + Common::String _soundFileLoaded; + + uint8 _sfxPriority; + uint8 _sfxFourthByteOfSong; + + int _numSoundTriggers; + const int *_soundTriggers; + + static const int _kyra1NumSoundTriggers; + static const int _kyra1SoundTriggers[]; +}; + +} // end of namespace Kyra + +#endif + diff --git a/engines/kyra/sound_intern.h b/engines/kyra/sound_intern.h index 8792c14815..975672b76a 100644 --- a/engines/kyra/sound_intern.h +++ b/engines/kyra/sound_intern.h @@ -8,12 +8,12 @@ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. @@ -27,6 +27,7 @@ #define KYRA_SOUND_INTERN_H #include "kyra/sound.h" +#include "kyra/sound_adlib.h" #include "common/mutex.h" @@ -39,66 +40,6 @@ class PCSpeaker; } // end of namespace Audio namespace Kyra { -class AdlibDriver; - -/** - * AdLib implementation of the sound output device. - * - * It uses a special sound file format special to - * Dune II, Kyrandia 1 and 2. While Dune II and - * Kyrandia 1 are using exact the same format, the - * one of Kyrandia 2 slightly differs. - * - * See AdlibDriver for more information. - * @see AdlibDriver - */ -class SoundAdlibPC : public Sound { -public: - SoundAdlibPC(KyraEngine_v1 *vm, Audio::Mixer *mixer); - ~SoundAdlibPC(); - - kType getMusicType() const { return kAdlib; } - - bool init(); - void process(); - - void loadSoundFile(uint file); - void loadSoundFile(Common::String file); - - void playTrack(uint8 track); - void haltTrack(); - bool isPlaying(); - - void playSoundEffect(uint8 track); - - void beginFadeOut(); -private: - void internalLoadFile(Common::String file); - - void play(uint8 track); - - void unk1(); - void unk2(); - - AdlibDriver *_driver; - - bool _v2; - uint8 _trackEntries[500]; - uint8 *_soundDataPtr; - int _sfxPlayingSound; - - Common::String _soundFileLoaded; - - uint8 _sfxPriority; - uint8 _sfxFourthByteOfSong; - - int _numSoundTriggers; - const int *_soundTriggers; - - static const int _kyra1NumSoundTriggers; - static const int _kyra1SoundTriggers[]; -}; - class MidiOutput; /** diff --git a/engines/kyra/sound_pcspk.cpp b/engines/kyra/sound_pcspk.cpp index 22c24bf56c..2afed22a80 100644 --- a/engines/kyra/sound_pcspk.cpp +++ b/engines/kyra/sound_pcspk.cpp @@ -1,25 +1,22 @@ -/* - * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +/* ScummVM - Graphic Adventure Engine * - * LGPL License + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * 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 library is distributed in the hope that it will be useful, + * 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 - * Lesser General Public License for more details. + * 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 Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * $URL$ * $Id$ diff --git a/engines/sci/detection.cpp b/engines/sci/detection.cpp index 566d82405a..7118eb682d 100644 --- a/engines/sci/detection.cpp +++ b/engines/sci/detection.cpp @@ -1149,6 +1149,25 @@ static const struct SciGameDescription SciGameDescriptions[] = { SCI_VERSION_1 }, + // King's Quest 5 - French DOS Floppy (from the King's Quest Collector's Edition 1994) + // Supplied by aroenai in bug report #2812611 + // VERSION file reports "1.000", SCI interpreter version 1.000.784 + {{"kq5", "", { + {"resource.map", 0, "eb7853832f3bb10900b13b421a0bbe7f", 8283}, + {"resource.000", 0, "f063775b279208c14a83eda47073be90", 332806}, + {"resource.001", 0, "3e6add38564250fd1a5bb10593007530", 1136827}, + {"resource.002", 0, "d9a97a9cf6c79bbe8f19378f6dea45d5", 1343738}, + {"resource.003", 0, "bef90d755076c110e67ee3e635503f82", 1324811}, + {"resource.004", 0, "c14dbafcfbe00855ac6b2f2701058047", 1332216}, + {"resource.005", 0, "f4b31cafc5defac75125c5f7b7f9a31a", 1268334}, + {"resource.006", 0, "f7dc85307632ef657ceb1651204f6f51", 1210081}, + {"resource.007", 0, "7db4d0a1d8d547c0019cb7d2a6acbdd4", 1338473}, + {NULL, 0, NULL, 0}}, Common::FR_FRA, Common::kPlatformPC, 0, GUIO_NOSPEECH}, + 0, + SCI_VERSION_AUTODETECT, + SCI_VERSION_1 + }, + // King's Quest 5 - Italian DOS Floppy (from glorifindel) // SCI interpreter version 1.000.060 {{"kq5", "", { @@ -2203,6 +2222,17 @@ static const struct SciGameDescription SciGameDescriptions[] = { }, #endif // ENABLE_SCI32 + // Pepper's Adventure In Time 1.000 English + // Executable scanning reports "1.001.072", VERSION file reports "1.000" + {{"pepper", "", { + {"resource.map", 0, "72726dc81c1b4c1110c486be77369bc8", 5179}, + {"resource.000", 0, "670d0c53622429f4b11275caf7f8d292", 5459574}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, + 0, + SCI_VERSION_AUTODETECT, + SCI_VERSION_1_1 + }, + // Pepper - English DOS Non-Interactive Demo // Executable scanning reports "1.001.060", VERSION file reports "1.000" {{"pepper", "Demo", { diff --git a/engines/sci/gfx/gfx_resmgr.cpp b/engines/sci/gfx/gfx_resmgr.cpp index b8c005b620..cd5b1be431 100644 --- a/engines/sci/gfx/gfx_resmgr.cpp +++ b/engines/sci/gfx/gfx_resmgr.cpp @@ -341,7 +341,7 @@ gfxr_pic_t *GfxResManager::getPic(int num, int maps, int flags, int default_pale res = resMap.contains(num) ? resMap[num] : NULL; if (!res || res->mode != hash) { - gfxr_pic_t *pic; + gfxr_pic_t *pic = NULL; gfxr_pic_t *unscaled_pic = NULL; #ifdef CUSTOM_GRAPHICS_OPTIONS diff --git a/engines/sci/gfx/gfx_resmgr.h b/engines/sci/gfx/gfx_resmgr.h index fc4e0b3d6f..5cd5d018cc 100644 --- a/engines/sci/gfx/gfx_resmgr.h +++ b/engines/sci/gfx/gfx_resmgr.h @@ -270,8 +270,7 @@ public: /** * Retrieves a color from the static palette */ - const PaletteEntry &getColor(int color) - { + const PaletteEntry &getColor(int color) { return _staticPalette->getColor(color); } @@ -313,6 +312,11 @@ public: return _staticPalette ? _staticPalette->size() : 0; } + /** + * Returns the resource version that the resource manager is using + */ + int getVersion() { return _version; } + private: int _version; gfx_options_t *_options; diff --git a/engines/sci/gfx/gfx_system.h b/engines/sci/gfx/gfx_system.h index fe93922e21..0f5292aedf 100644 --- a/engines/sci/gfx/gfx_system.h +++ b/engines/sci/gfx/gfx_system.h @@ -192,7 +192,7 @@ struct gfx_pixmap_t { * As a special exception, 256 colors are allowed for background pictures * (which do not use transparency) */ - int colors_nr() const { return palette ? palette->size() : 0; } + int colors_nr() const { return palette ? MIN<int>(palette->size(), 256) : 0; } uint32 flags; /* @} */ diff --git a/engines/sci/gfx/operations.cpp b/engines/sci/gfx/operations.cpp index 77b887778b..5604166794 100644 --- a/engines/sci/gfx/operations.cpp +++ b/engines/sci/gfx/operations.cpp @@ -1715,9 +1715,10 @@ static int _gfxop_set_pic(GfxState *state) { // FIXME: The _gfxop_install_pixmap call below updates the OSystem palette. // This is too soon, since it causes brief palette corruption until the // screen is updated too. (Possibly related: EngineState::pic_not_valid .) - if (state->driver->getMode()->palette) + if (state->pic->visual_map->palette && state->driver->getMode()->palette) { state->pic->visual_map->palette->forceInto(state->driver->getMode()->palette); - _gfxop_install_pixmap(state->driver, state->pic->visual_map); + _gfxop_install_pixmap(state->driver, state->pic->visual_map); + } #ifdef CUSTOM_GRAPHICS_OPTIONS if (state->options->pic0_unscaled) diff --git a/engines/sci/gfx/res_pal.cpp b/engines/sci/gfx/res_pal.cpp index 97e7297d43..d686220453 100644 --- a/engines/sci/gfx/res_pal.cpp +++ b/engines/sci/gfx/res_pal.cpp @@ -44,6 +44,11 @@ Palette *gfxr_read_pal11(int id, byte *resource, int size) { int entry_size = (format == SCI_PAL_FORMAT_VARIABLE_FLAGS) ? 4 : 3; byte *pal_data = resource + 37; int _colors_nr = READ_LE_UINT16(resource + 29); + + // Happens at the beginning of Pepper + if (_colors_nr > 256) + return NULL; + Palette *retval = new Palette(_colors_nr + start_color); int i; diff --git a/engines/scumm/dialogs.cpp b/engines/scumm/dialogs.cpp index 9fb107f9fc..880fab04a5 100644 --- a/engines/scumm/dialogs.cpp +++ b/engines/scumm/dialogs.cpp @@ -641,6 +641,8 @@ HelpDialog::HelpDialog(const GameSettings &game) new GUI::ButtonWidget(this, "ScummHelp.Close", "Close", kCloseCmd, 'C'); _prevButton->clearFlags(WIDGET_ENABLED); + _numLines = HELP_NUM_LINES; + // Dummy entries for (int i = 0; i < HELP_NUM_LINES; i++) { _key[i] = new StaticTextWidget(this, 0, 0, 10, 10, "", Graphics::kTextAlignRight); @@ -658,22 +660,25 @@ void HelpDialog::reflowLayout() { g_gui.xmlEval()->getWidgetData("ScummHelp.HelpText", x, y, w, h); + // Make sure than we don't have more lines than what we can fit + // on the space that the layout reserves for text + _numLines = MIN(HELP_NUM_LINES, (int)(h / lineHeight)); + int keyW = w * 20 / 100; int dscX = x + keyW + 32; int dscW = w * 80 / 100; int xoff = (_w >> 1) - (w >> 1); - for (int i = 0; i < HELP_NUM_LINES; i++) { - _key[i]->resize(xoff + x, y + lineHeight * i, keyW, lineHeight + 2); - _dsc[i]->resize(xoff + dscX, y + lineHeight * i, dscW, lineHeight + 2); + for (int i = 0; i < _numLines; i++) { + _key[i]->resize(xoff + x, y + lineHeight * i, keyW, lineHeight); + _dsc[i]->resize(xoff + dscX, y + lineHeight * i, dscW, lineHeight); } displayKeyBindings(); } void HelpDialog::displayKeyBindings() { - String titleStr, *keyStr, *dscStr; #ifndef __DS__ @@ -684,7 +689,7 @@ void HelpDialog::displayKeyBindings() { #endif _title->setLabel(titleStr); - for (int i = 0; i < HELP_NUM_LINES; i++) { + for (int i = 0; i < _numLines; i++) { _key[i]->setLabel(keyStr[i]); _dsc[i]->setLabel(dscStr[i]); } diff --git a/engines/scumm/dialogs.h b/engines/scumm/dialogs.h index 290b3450dc..af844272fa 100644 --- a/engines/scumm/dialogs.h +++ b/engines/scumm/dialogs.h @@ -124,6 +124,7 @@ protected: int _page; int _numPages; + int _numLines; const GameSettings _game; diff --git a/engines/scumm/imuse_digi/dimuse_track.cpp b/engines/scumm/imuse_digi/dimuse_track.cpp index 6ded6d23b2..a389c0e7e7 100644 --- a/engines/scumm/imuse_digi/dimuse_track.cpp +++ b/engines/scumm/imuse_digi/dimuse_track.cpp @@ -22,6 +22,7 @@ * $Id$ */ +#include "common/config-manager.h" #include "common/timer.h" #include "scumm/actor.h" @@ -136,6 +137,11 @@ void IMuseDigital::startSound(int soundId, const char *soundName, int soundType, track->pan = a->_talkPan; track->vol = a->_talkVolume * 1000; } + + // The volume is set to zero, when using subtitles only setting in COMI + if (ConfMan.getBool("speech_mute") || _vm->VAR(_vm->VAR_VOICE_MODE) == 2) { + track->vol = 0; + } } assert(bits == 8 || bits == 12 || bits == 16); diff --git a/engines/scumm/input.cpp b/engines/scumm/input.cpp index 42b48a3f3d..61b714a3e2 100644 --- a/engines/scumm/input.cpp +++ b/engines/scumm/input.cpp @@ -258,6 +258,18 @@ void ScummEngine_v0::processInput() { ScummEngine::processInput(); } +#ifdef ENABLE_SCUMM_7_8 +void ScummEngine_v7::processInput() { + ScummEngine::processInput(); + + if (_skipVideo && !_smushActive) { + abortCutscene(); + _mouseAndKeyboardStat = Common::ASCII_ESCAPE; + _skipVideo = false; + } +} +#endif + void ScummEngine::processInput() { Common::KeyState lastKeyHit = _keyPressed; _keyPressed.reset(); @@ -392,9 +404,10 @@ void ScummEngine_v7::processKeyboard(Common::KeyState lastKeyHit) { _insane->escapeKeyHandler(); else _smushVideoShouldFinish = true; - } - if (!_smushActive || _smushVideoShouldFinish) + _skipVideo = true; + } else { abortCutscene(); + } _mouseAndKeyboardStat = Common::ASCII_ESCAPE; diff --git a/engines/scumm/player_v2.h b/engines/scumm/player_v2.h index f0e14cdde3..5b375fb1e5 100644 --- a/engines/scumm/player_v2.h +++ b/engines/scumm/player_v2.h @@ -242,8 +242,8 @@ protected: Voice2 _cmsVoices[8]; MusicChip _cmsChips[2]; - char _tempo; - char _tempoSum; + int8 _tempo; + int8 _tempoSum; byte _looping; byte _octaveMask; int16 _midiDelay; diff --git a/engines/scumm/script.cpp b/engines/scumm/script.cpp index 78f7fb0453..4d9447bee5 100644 --- a/engines/scumm/script.cpp +++ b/engines/scumm/script.cpp @@ -1367,17 +1367,6 @@ void ScummEngine::abortCutscene() { VAR(VAR_OVERRIDE) = 1; vm.cutScenePtr[idx] = 0; - - // HACK to fix issues with SMUSH and the way it does keyboard handling. - // In particular, normally abortCutscene() is being called while no - // scripts are active. But SMUSH runs from *inside* the script engine. - // And it calls abortCutscene() if ESC is pressed... not good. - // Proper fix might be to let SMUSH/INSANE run from outside the script - // engine but that would require lots of changes and may actually have - // negative effects, too. So we cheat here, to fix bug #751670. - if (_game.version == 7) - getScriptEntryPoint(); - } } diff --git a/engines/scumm/script_v6.cpp b/engines/scumm/script_v6.cpp index c23a64be5b..dcd60352c7 100644 --- a/engines/scumm/script_v6.cpp +++ b/engines/scumm/script_v6.cpp @@ -1396,6 +1396,7 @@ void ScummEngine_v6::o6_getVerbFromXY() { void ScummEngine_v6::o6_beginOverride() { beginOverride(); + _skipVideo = 0; } void ScummEngine_v6::o6_endOverride() { @@ -2457,7 +2458,7 @@ void ScummEngine_v7::o6_kernelSetFunctions() { break; case 6: { // SMUSH movie playback - if (args[1] == 0) { + if (args[1] == 0 && !_skipVideo) { const char *videoname = (const char *)getStringAddressVar(VAR_VIDEONAME); assert(videoname); @@ -2474,7 +2475,7 @@ void ScummEngine_v7::o6_kernelSetFunctions() { if (_game.id == GID_DIG) { _disableFadeInEffect = true; } - } else if (_game.id == GID_FT) { + } else if (_game.id == GID_FT && !_skipVideo) { const int insaneVarNum = ((_game.features & GF_DEMO) && (_game.platform == Common::kPlatformPC)) ? 232 : 233; diff --git a/engines/scumm/scumm.cpp b/engines/scumm/scumm.cpp index a00ace1f49..70b2d7285e 100644 --- a/engines/scumm/scumm.cpp +++ b/engines/scumm/scumm.cpp @@ -687,6 +687,7 @@ ScummEngine_v6::ScummEngine_v6(OSystem *syst, const DetectorResult &dr) _curVerbSlot = 0; _forcedWaitForMessage = false; + _skipVideo = false; VAR_VIDEONAME = 0xFF; VAR_RANDOM_NR = 0xFF; diff --git a/engines/scumm/scumm_v6.h b/engines/scumm/scumm_v6.h index d4768a7e92..eb55b83596 100644 --- a/engines/scumm/scumm_v6.h +++ b/engines/scumm/scumm_v6.h @@ -93,6 +93,7 @@ protected: int _curVerbSlot; bool _forcedWaitForMessage; + bool _skipVideo; public: ScummEngine_v6(OSystem *syst, const DetectorResult &dr); diff --git a/engines/scumm/scumm_v7.h b/engines/scumm/scumm_v7.h index fdc1d6de9c..fcadadb04d 100644 --- a/engines/scumm/scumm_v7.h +++ b/engines/scumm/scumm_v7.h @@ -103,6 +103,7 @@ protected: virtual void scummLoop_handleSound(); virtual void scummLoop_handleDrawing(); + virtual void processInput(); virtual void processKeyboard(Common::KeyState lastKeyHit); virtual void setupScumm(); diff --git a/engines/scumm/string.cpp b/engines/scumm/string.cpp index d40bbb9aaa..f00f4ff33b 100644 --- a/engines/scumm/string.cpp +++ b/engines/scumm/string.cpp @@ -1415,6 +1415,9 @@ void ScummEngine_v7::loadLanguageBundle() { } void ScummEngine_v7::playSpeech(const byte *ptr) { + if (_game.id == GID_DIG && (ConfMan.getBool("speech_mute") || VAR(VAR_VOICE_MODE) == 2)) + return; + if ((_game.id == GID_DIG || _game.id == GID_CMI) && ptr[0]) { char pointer[20]; strcpy(pointer, (const char *)ptr); diff --git a/engines/sky/grid.cpp b/engines/sky/grid.cpp index d9b7a17351..7b473c7934 100644 --- a/engines/sky/grid.cpp +++ b/engines/sky/grid.cpp @@ -255,8 +255,10 @@ void Grid::removeGrid(uint32 x, uint32 y, uint32 width, Compact *cpt) { } uint8 *Grid::giveGrid(uint32 pScreen) { - assert((_gridConvertTable[pScreen] >= 0) && (_gridConvertTable[pScreen] < TOT_NO_GRIDS)); - return _gameGrids[_gridConvertTable[pScreen]]; + if ((_gridConvertTable[pScreen] >= 0) && (_gridConvertTable[pScreen] < TOT_NO_GRIDS)) { + return _gameGrids[_gridConvertTable[pScreen]]; + } + return 0; } } // End of namespace Sky diff --git a/engines/sky/logic.cpp b/engines/sky/logic.cpp index ccfbfbbd62..991fbe19d0 100644 --- a/engines/sky/logic.cpp +++ b/engines/sky/logic.cpp @@ -1702,6 +1702,15 @@ bool Logic::fnQuit(uint32 a, uint32 b, uint32 c) { } bool Logic::fnSpeakMe(uint32 targetId, uint32 mesgNum, uint32 animNum) { + /* WORKAROUND for #2687172: When Mrs. Piermont is talking + on the phone in her apartment, ignore her fnSpeakMe calls + on other screens, as the lack of speech files for these lines + will cause Foster's speech to be aborted if the timing is bad. + */ + if (targetId == 0x4039 && animNum == 0x9B && Logic::_scriptVariables[SCREEN] != 38) { + return false; + } + stdSpeak(_skyCompact->fetchCpt(targetId), mesgNum, animNum, 0); return false; //drop out of script } diff --git a/engines/sky/sky.cpp b/engines/sky/sky.cpp index 47cc65e96d..e85da6297a 100644 --- a/engines/sky/sky.cpp +++ b/engines/sky/sky.cpp @@ -208,8 +208,11 @@ Common::Error SkyEngine::go() { _skyScreen->recreate(); _skyScreen->spriteEngine(); if (_debugger->showGrid()) { - _skyScreen->showGrid(_skyLogic->_skyGrid->giveGrid(Logic::_scriptVariables[SCREEN])); - _skyScreen->forceRefresh(); + uint8 *grid = _skyLogic->_skyGrid->giveGrid(Logic::_scriptVariables[SCREEN]); + if (grid) { + _skyScreen->showGrid(grid); + _skyScreen->forceRefresh(); + } } _skyScreen->flip(); diff --git a/engines/sword1/sound.cpp b/engines/sword1/sound.cpp index b3fa1aa0fd..b23bf71445 100644 --- a/engines/sword1/sound.cpp +++ b/engines/sword1/sound.cpp @@ -77,11 +77,11 @@ void Sound::checkSpeechFileEndianness() { // little endian assumption. The one with the smallest sum should be the // correct one (the sound wave is supposed to be relatively smooth). // It needs at least 1000 samples to get stable result (the code below is - // using the first 2000 samples of the wav sound. + // using the first 2000 samples of the wav sound). - // Init speach file if not already done. + // Init speech file if not already done. if (!_currentCowFile) { - // Open one of the speech file. It uses SwordEngine::_systemVars.currentCD + // Open one of the speech files. It uses SwordEngine::_systemVars.currentCD // to decide which file to open, therefore if it is currently set to zero // we have to set it to either 1 or 2 (I decided to set it to 1 as this is // more likely to be the first file that will be needed). @@ -92,22 +92,22 @@ void Sound::checkSpeechFileEndianness() { } initCowSystem(); if (no_current_cd) { - // In case it fails with CD1 retyr with CD2 + // In case it fails with CD1 retry with CD2 if (!_currentCowFile) { SwordEngine::_systemVars.currentCD = 2; initCowSystem(); } - // Reset curentCD flag + // Reset currentCD flag SwordEngine::_systemVars.currentCD = 0; } } - // Testing for endianness makes sense only if using the nom compressed files. + // Testing for endianness makes sense only if using the uncompressed files. if (_cowHeader == NULL || (_cowMode != CowWave && _cowMode != CowDemo)) return; // I picked the sample to use randomly (I just made sure it is long enough so that there is - // a fair change of the heuristic to have a stable result and work for every languages). + // a fair change of the heuristic to have a stable result and work for every language). int roomNo = _currentCowFile == 1 ? 1 : 129; int localNo = _currentCowFile == 1 ? 2 : 933; // Get the speech data and apply the heuristic @@ -119,7 +119,7 @@ void Sound::checkSpeechFileEndianness() { double be_diff_sum = 0., le_diff_sum = 0.; _bigEndianSpeech = false; int16 *data = uncompressSpeech(index + _cowHeaderSize, sampleSize, &size); - // Compute average of differecen between two consecutive samples for both BE and LE + // Compute average of difference between two consecutive samples for both BE and LE if (data) { if (size > 4000) size = 2000; diff --git a/engines/tinsel/handle.cpp b/engines/tinsel/handle.cpp index 9a0e1f37f8..5ef5bea702 100644 --- a/engines/tinsel/handle.cpp +++ b/engines/tinsel/handle.cpp @@ -207,9 +207,7 @@ void OpenCDGraphFile(void) { // As the theory goes, the right CD will be in there! - cdGraphStream.clearIOFailed(); - cdGraphStream.open(szCdPlayFile); - if (cdGraphStream.ioFailed()) + if (!cdGraphStream.open(szCdPlayFile)) error(CANNOT_FIND_FILE, szCdPlayFile); } diff --git a/engines/tinsel/pcode.cpp b/engines/tinsel/pcode.cpp index a9c6f43d85..1d73411e13 100644 --- a/engines/tinsel/pcode.cpp +++ b/engines/tinsel/pcode.cpp @@ -112,6 +112,43 @@ static INT_CONTEXT *icList = 0; static uint32 hMasterScript; +//----------------- SCRIPT BUGS WORKAROUNDS -------------- + +const byte fragment1[] = {OP_ZERO, OP_GSTORE | OPSIZE16, 206, 0}; +const int fragment1_size = 4; +const byte fragment2[] = {OP_LIBCALL | OPSIZE8, 110}; +const int fragment2_size = 2; +const byte fragment3[] = {OP_ZERO, OP_GSTORE | OPSIZE16, 490 % 256, 490 / 256}; +const int fragment3_size = 4; + +const WorkaroundEntry workaroundList[] = { + // DW1-SCN: Global 206 is whether Rincewind is trying to take the book back to the present. + // In the GRA version, it was global 373, and was reset when he is returned to the past, but + // was forgotten in the SCN version, so this ensures the flag is properly reset + {TINSEL_V1, true, 427942095, 1, fragment1_size, fragment1}, + + // DW1-GRA: Rincewind exiting the Inn is blocked by the luggage. Whilst you can then move + // into walkable areas, saving and restoring the game, it will error if you try to move. + // This fragment turns off NPC blocking for the Outside Inn rooms so that the luggage won't block + // Past Outside Inn + {TINSEL_V1, false, 444622076, 0, fragment2_size, fragment2}, + // Present Outside Inn + {TINSEL_V1, false, 352600876, 0, fragment2_size, fragment2}, + + // DW2: In the garden, global #490 is set when the bees begin their 'out of hive' animation, and reset when done. + // But if the game is saved/restored during it, the animation sequence is reset without the global being cleared. + // This causes bugs in several actions which try to disable the bees animation, since they wait indefinitely for + // the global to be cleared, incorrectly believing the animation is currently playing. This includes + // * Giving the brochure to the beekeeper + // * Stealing the mallets from the wizards + // This fix ensures that the global is reset when the Garden scene is loaded (both entering and restoring a game) + {TINSEL_V2, true, 2888147476U, 0, fragment3_size, fragment3}, + + {TINSEL_V0, false, 0, 0, 0, NULL} +}; + +//----------------- LOCAL GLOBAL DATA -------------------- + /** * Keeps the code array pointer up to date. */ @@ -398,38 +435,93 @@ void SaveInterpretContexts(INT_CONTEXT *sICInfo) { } /** - * Fetch (and sign extend, if necessary) a 8/16/32 bit value from the code - * stream and advance the instruction pointer accordingly. + * Fetches up to 4 bytes from the code script */ -static int32 Fetch(byte opcode, byte *code, int &ip) { - int32 tmp; - if (TinselV0) { - // Fetch a 32 bit value. - tmp = (int32)READ_LE_UINT32(code + ip++ * 4); - } else if (opcode & OPSIZE8) { +static int32 GetBytes(const byte *scriptCode, const WorkaroundEntry* &wkEntry, int &ip, uint numBytes) { + assert(numBytes <= 4 && numBytes != 3); + const byte *code = scriptCode; + + if (wkEntry != NULL) { + if (ip >= wkEntry->numBytes) { + // Finished the workaround + ip = wkEntry->ip; + wkEntry = NULL; + } else { + code = wkEntry->script; + } + } + + uint32 tmp; + switch (numBytes) { + case 0: + // Instruction byte + tmp = code[ip++ * (TinselV0 ? 4 : 1)]; + break; + case 1: // Fetch and sign extend a 8 bit value to 32 bits. - tmp = *(int8 *)(code + ip); - ip += 1; - } else if (opcode & OPSIZE16) { + tmp = (int8)code[ip++]; + break; + case 2: // Fetch and sign extend a 16 bit value to 32 bits. tmp = (int16)READ_LE_UINT16(code + ip); ip += 2; - } else { - // Fetch a 32 bit value. - tmp = (int32)READ_LE_UINT32(code + ip); - ip += 4; + break; + default: + if (TinselV0) + tmp = (int32)READ_LE_UINT32(code + ip++ * 4); + else { + tmp = (int32)READ_LE_UINT32(code + ip); + ip += 4; + } + break; } + return tmp; } /** + * Fetch (and sign extend, if necessary) a 8/16/32 bit value from the code + * stream and advance the instruction pointer accordingly. + */ +static int32 Fetch(byte opcode, const byte *code, const WorkaroundEntry* &wkEntry, int &ip) { + if (TinselV0) + // Fetch a 32 bit value. + return GetBytes(code, wkEntry, ip, 4); + else if (opcode & OPSIZE8) + // Fetch and sign extend a 8 bit value to 32 bits. + return GetBytes(code, wkEntry, ip, 1); + else if (opcode & OPSIZE16) + return GetBytes(code, wkEntry, ip, 2); + + return GetBytes(code, wkEntry, ip, 4); +} + +/** * Interprets the PCODE instructions in the code array. */ void Interpret(CORO_PARAM, INT_CONTEXT *ic) { do { int tmp, tmp2; int ip = ic->ip; - byte opcode = ic->code[ip++ * (TinselV0 ? 4 : 1)]; + const WorkaroundEntry *wkEntry = ic->fragmentPtr; + + if (wkEntry == NULL) { + // Check to see if a workaround fragment needs to be executed + for (wkEntry = workaroundList; wkEntry->script != NULL; ++wkEntry) { + if ((wkEntry->version == TinselVersion) && + (wkEntry->hCode == ic->hCode) && + (wkEntry->ip == ip) && + (!TinselV1 || (wkEntry->scnFlag == ((_vm->getFeatures() & GF_SCNFILES) != 0)))) { + // Point to start of workaround fragment + ip = 0; + break; + } + } + if (wkEntry->script == NULL) + wkEntry = NULL; + } + + byte opcode = (byte)GetBytes(ic->code, wkEntry, ip, 0); if (TinselV0 && ((opcode & OPMASK) > OP_IMM)) opcode += 3; @@ -447,7 +539,7 @@ void Interpret(CORO_PARAM, INT_CONTEXT *ic) { case OP_FONT: // loads font handle onto stack case OP_PAL: // loads palette handle onto stack - ic->stack[++ic->sp] = Fetch(opcode, ic->code, ip); + ic->stack[++ic->sp] = Fetch(opcode, ic->code, wkEntry, ip); break; case OP_ZERO: // loads zero onto stack @@ -464,31 +556,31 @@ void Interpret(CORO_PARAM, INT_CONTEXT *ic) { case OP_LOAD: // loads local variable onto stack - ic->stack[++ic->sp] = ic->stack[ic->bp + Fetch(opcode, ic->code, ip)]; + ic->stack[++ic->sp] = ic->stack[ic->bp + Fetch(opcode, ic->code, wkEntry, ip)]; break; case OP_GLOAD: // loads global variable onto stack - tmp = Fetch(opcode, ic->code, ip); + tmp = Fetch(opcode, ic->code, wkEntry, ip); assert(0 <= tmp && tmp < numGlobals); ic->stack[++ic->sp] = pGlobals[tmp]; break; case OP_STORE: // pops stack and stores in local variable - ic->stack[ic->bp + Fetch(opcode, ic->code, ip)] = ic->stack[ic->sp--]; + ic->stack[ic->bp + Fetch(opcode, ic->code, wkEntry, ip)] = ic->stack[ic->sp--]; break; case OP_GSTORE: // pops stack and stores in global variable - tmp = Fetch(opcode, ic->code, ip); + tmp = Fetch(opcode, ic->code, wkEntry, ip); assert(0 <= tmp && tmp < numGlobals); pGlobals[tmp] = ic->stack[ic->sp--]; break; case OP_CALL: // procedure call - tmp = Fetch(opcode, ic->code, ip); + tmp = Fetch(opcode, ic->code, wkEntry, ip); //assert(0 <= tmp && tmp < codeSize); // TODO: Verify jumps are not out of bounds ic->stack[ic->sp + 1] = 0; // static link ic->stack[ic->sp + 2] = ic->bp; // dynamic link @@ -499,7 +591,7 @@ void Interpret(CORO_PARAM, INT_CONTEXT *ic) { case OP_LIBCALL: // library procedure or function call - tmp = Fetch(opcode, ic->code, ip); + tmp = Fetch(opcode, ic->code, wkEntry, ip); // NOTE: Interpret() itself is not using the coroutine facilities, // but still accepts a CORO_PARAM, so from the outside it looks // like a coroutine. In fact it may still acts as a kind of "proxy" @@ -538,17 +630,17 @@ void Interpret(CORO_PARAM, INT_CONTEXT *ic) { case OP_ALLOC: // allocate storage on stack - ic->sp += (int32)Fetch(opcode, ic->code, ip); + ic->sp += (int32)Fetch(opcode, ic->code, wkEntry, ip); break; case OP_JUMP: // unconditional jump - ip = Fetch(opcode, ic->code, ip); + ip = Fetch(opcode, ic->code, wkEntry, ip); break; case OP_JMPFALSE: // conditional jump - tmp = Fetch(opcode, ic->code, ip); + tmp = Fetch(opcode, ic->code, wkEntry, ip); if (ic->stack[ic->sp--] == 0) { // condition satisfied - do the jump ip = tmp; @@ -557,7 +649,7 @@ void Interpret(CORO_PARAM, INT_CONTEXT *ic) { case OP_JMPTRUE: // conditional jump - tmp = Fetch(opcode, ic->code, ip); + tmp = Fetch(opcode, ic->code, wkEntry, ip); if (ic->stack[ic->sp--] != 0) { // condition satisfied - do the jump ip = tmp; @@ -660,6 +752,7 @@ void Interpret(CORO_PARAM, INT_CONTEXT *ic) { // check for stack under-overflow assert(ic->sp >= 0 && ic->sp < PCODE_STACK_SIZE); ic->ip = ip; + ic->fragmentPtr = wkEntry; } while (!ic->bHalt); // make sure stack is unwound diff --git a/engines/tinsel/pcode.h b/engines/tinsel/pcode.h index 4bdfcf5626..fad50cdb9d 100644 --- a/engines/tinsel/pcode.h +++ b/engines/tinsel/pcode.h @@ -54,6 +54,17 @@ enum GSORT { enum RESCODE {RES_WAITING, RES_FINISHED, RES_CUTSHORT}; +// The following structure is used to introduce bug fixes into the scripts used by the games + +struct WorkaroundEntry { + TinselEngineVersion version; + bool scnFlag; // Only applicable for Tinsel 1 (DW 1) + SCNHANDLE hCode; // Script to apply fragment to + int ip; // Script offset to run this fragment before + int numBytes; // Number of bytes in the script + const byte *script; // Instruction(s) to execute +}; + struct INT_CONTEXT { // Elements for interpret context management @@ -82,6 +93,9 @@ struct INT_CONTEXT { RESCODE resumeCode; RESUME_STATE resumeState; + // Used to store execution state within a script workaround fragment + const WorkaroundEntry *fragmentPtr; + void syncWithSerializer(Common::Serializer &s); }; typedef INT_CONTEXT *PINT_CONTEXT; diff --git a/engines/touche/saveload.cpp b/engines/touche/saveload.cpp index 69b8f9ba43..73817a5a1a 100644 --- a/engines/touche/saveload.cpp +++ b/engines/touche/saveload.cpp @@ -355,10 +355,10 @@ Common::Error ToucheEngine::loadGameState(int num) { } else { f->skip(2 + kGameStateDescriptionLen); loadGameStateData(f); - if (!f->ioFailed()) { - loadOk = true; - } else { + if (f->err() || f->eos()) { warning("Can't read file '%s'", gameStateFileName.c_str()); + } else { + loadOk = true; } } delete f; diff --git a/engines/tucker/saveload.cpp b/engines/tucker/saveload.cpp index cf7f985416..83533a90c3 100644 --- a/engines/tucker/saveload.cpp +++ b/engines/tucker/saveload.cpp @@ -88,7 +88,7 @@ Common::Error TuckerEngine::loadGameState(int num) { } else { f->skip(2); saveOrLoadGameStateData(*f); - if (f->ioFailed()) { + if (f->err() || f->eos()) { warning("Can't read file '%s'", gameStateFileName.c_str()); ret = Common::kReadingFailed; } else { diff --git a/graphics/VectorRendererSpec.cpp b/graphics/VectorRendererSpec.cpp index 49dc2c0ef0..b68f4822d8 100644 --- a/graphics/VectorRendererSpec.cpp +++ b/graphics/VectorRendererSpec.cpp @@ -600,12 +600,12 @@ drawRoundedSquare(int x, int y, int r, int w, int h) { w <= 0 || h <= 0 || x < 0 || y < 0 || r <= 0) return; - if ((r << 1) > w || (r << 1) > h) - r = MIN(w >> 1, h >> 1); + if ((r * 2) > w || (r * 2) > h) + r = MIN(w /2, h / 2); if (Base::_fillMode != kFillDisabled && Base::_shadowOffset - && x + w + Base::_shadowOffset < Base::_activeSurface->w - && y + h + Base::_shadowOffset < Base::_activeSurface->h) { + && x + w + Base::_shadowOffset + 1 < Base::_activeSurface->w + && y + h + Base::_shadowOffset + 1 < Base::_activeSurface->h) { drawRoundedSquareShadow(x, y, r, w, h, Base::_shadowOffset); } @@ -919,10 +919,12 @@ drawBevelSquareAlg(int x, int y, int w, int h, int bevel, PixelType top_color, P } int i, j; + x = MAX(x - bevel, 0); y = MAX(y - bevel, 0); - h += bevel << 1; - w += bevel << 1; + + w = MIN(w + (bevel * 2), (int)_activeSurface->w); + h = MIN(h + (bevel * 2), (int)_activeSurface->h); PixelType *ptr_left = (PixelType *)_activeSurface->getBasePtr(x, y); diff --git a/graphics/font.cpp b/graphics/font.cpp index 1c958f3c3c..4d322be081 100644 --- a/graphics/font.cpp +++ b/graphics/font.cpp @@ -572,8 +572,10 @@ bitmap_t bdf_hexval(unsigned char *buf) { NewFont *NewFont::loadFont(Common::SeekableReadStream &stream) { NewFontData *data = bdf_read_font(stream); - if (!data) + if (!data || stream.err()) { + free_font(data); return 0; + } FontDesc desc; desc.name = data->name; @@ -673,7 +675,7 @@ NewFont *NewFont::loadFromCache(Common::SeekableReadStream &stream) { data->defaultchar = stream.readUint16BE(); data->bits_size = stream.readUint32BE(); - data->bits = (bitmap_t*)malloc(sizeof(bitmap_t)*data->bits_size); + data->bits = (bitmap_t *)malloc(sizeof(bitmap_t) * data->bits_size); if (!data->bits) { free(data); return 0; @@ -685,7 +687,7 @@ NewFont *NewFont::loadFromCache(Common::SeekableReadStream &stream) { bool hasOffsetTable = (stream.readByte() != 0); if (hasOffsetTable) { - data->offset = (unsigned long*)malloc(sizeof(unsigned long)*data->size); + data->offset = (unsigned long *)malloc(sizeof(unsigned long) * data->size); if (!data->offset) { free(data->bits); free(data); @@ -699,7 +701,7 @@ NewFont *NewFont::loadFromCache(Common::SeekableReadStream &stream) { bool hasWidthTable = (stream.readByte() != 0); if (hasWidthTable) { - data->width = (unsigned char*)malloc(sizeof(unsigned char)*data->size); + data->width = (unsigned char *)malloc(sizeof(unsigned char) * data->size); if (!data->width) { free(data->bits); free(data->offset); @@ -714,7 +716,7 @@ NewFont *NewFont::loadFromCache(Common::SeekableReadStream &stream) { bool hasBBXTable = (stream.readByte() != 0); if (hasBBXTable) { - data->bbx = (BBX *)malloc(sizeof(BBX)*data->size); + data->bbx = (BBX *)malloc(sizeof(BBX) * data->size); if (!data->bbx) { free(data->bits); free(data->offset); @@ -731,6 +733,14 @@ NewFont *NewFont::loadFromCache(Common::SeekableReadStream &stream) { } } + if (stream.err() || stream.eos()) { + free(data->bits); + free(data->offset); + free(data->width); + free(data); + return 0; + } + FontDesc desc; desc.name = data->name; desc.maxwidth = data->maxwidth; @@ -750,7 +760,7 @@ NewFont *NewFont::loadFromCache(Common::SeekableReadStream &stream) { desc.bits_size = data->bits_size; font = new NewFont(desc, data); - if (!font || stream.ioFailed()) { + if (!font) { free(data->bits); free(data->offset); free(data->width); diff --git a/graphics/video/coktelvideo/coktelvideo.cpp b/graphics/video/coktelvideo/coktelvideo.cpp index d18e727a35..c88c5beee2 100644 --- a/graphics/video/coktelvideo/coktelvideo.cpp +++ b/graphics/video/coktelvideo/coktelvideo.cpp @@ -1820,16 +1820,18 @@ Common::MemoryReadStream *Vmd::getExtraData(const char *fileName) { return 0; } - byte *data = (byte *) malloc(_extraData[i].realSize); - - _stream->seek(_extraData[i].offset); - if (_stream->ioFailed() || (((uint32) _stream->pos()) != _extraData[i].offset)) { - warning("Vmd::getExtraData(): Can't seek to offset %d to get extra data file \"%s\"", + if (!_stream->seek(_extraData[i].offset)) { + warning("Vmd::getExtraData(): Can't seek to offset %d to (file \"%s\")", _extraData[i].offset, fileName); return 0; } - _stream->read(data, _extraData[i].realSize); + byte *data = (byte *) malloc(_extraData[i].realSize); + if (_stream->read(data, _extraData[i].realSize) != _extraData[i].realSize) { + free(data); + warning("Vmd::getExtraData(): Couldn't read %d bytes (file \"%s\")", + _extraData[i].realSize, fileName); + } Common::MemoryReadStream *stream = new Common::MemoryReadStream(data, _extraData[i].realSize, true); diff --git a/graphics/video/mpeg_player.cpp b/graphics/video/mpeg_player.cpp index 1910babce4..5b7b3eb607 100644 --- a/graphics/video/mpeg_player.cpp +++ b/graphics/video/mpeg_player.cpp @@ -86,13 +86,10 @@ bool BaseAnimationState::init(const char *name) { } p = 0; - while (1) { + while (!f.eos()) { _palettes[p].end = f.readUint16LE(); _palettes[p].cnt = f.readUint16LE(); - if (f.ioFailed()) - break; - for (i = 0; i < _palettes[p].cnt; i++) { _palettes[p].pal[4 * i] = f.readByte(); _palettes[p].pal[4 * i + 1] = f.readByte(); diff --git a/gui/EditTextWidget.cpp b/gui/EditTextWidget.cpp index f38f9f5b94..658ac21117 100644 --- a/gui/EditTextWidget.cpp +++ b/gui/EditTextWidget.cpp @@ -84,7 +84,7 @@ void EditTextWidget::drawWidget() { // Draw the text adjustOffset(); - g_gui.theme()->drawText(Common::Rect(_x+2+ _leftPadding,_y+2, _x+_leftPadding+getEditRect().width()+2, _y+_h-2), _editString, _state, Graphics::kTextAlignLeft, false, -_editScrollOffset, false, _font); + g_gui.theme()->drawText(Common::Rect(_x+2+ _leftPadding,_y+2, _x+_leftPadding+getEditRect().width()+2, _y+_h-2), _editString, _state, Graphics::kTextAlignLeft, ThemeEngine::kTextInversionNone, -_editScrollOffset, false, _font); } Common::Rect EditTextWidget::getEditRect() const { diff --git a/gui/ListWidget.cpp b/gui/ListWidget.cpp index 8661444cf3..3d4c10859f 100644 --- a/gui/ListWidget.cpp +++ b/gui/ListWidget.cpp @@ -105,6 +105,22 @@ Widget *ListWidget::findWidget(int x, int y) { } void ListWidget::setSelected(int item) { + // HACK/FIXME: If our _listIndex has a non zero size, + // we will need to look up, whether the user selected + // item is present in that list + if (_listIndex.size()) { + int filteredItem = -1; + + for (uint i = 0; i < _listIndex.size(); ++i) { + if (_listIndex[i] == item) { + filteredItem = i; + break; + } + } + + item = filteredItem; + } + assert(item >= -1 && item < (int)_list.size()); // We only have to do something if the widget is enabled and the selection actually changes @@ -131,6 +147,7 @@ void ListWidget::setList(const StringList &list) { _dataList = list; _list = list; _filter.clear(); + _listIndex.clear(); int size = list.size(); if (_currentPos >= size) @@ -387,15 +404,14 @@ void ListWidget::drawWidget() { for (i = 0, pos = _currentPos; i < _entriesPerPage && pos < len; i++, pos++) { const int y = _y + _topPadding + kLineHeight * i; const int fontHeight = kLineHeight; - bool inverted = false; + ThemeEngine::TextInversionState inverted = ThemeEngine::kTextInversionNone; // Draw the selected item inverted, on a highlighted background. if (_selectedItem == pos) { if (_hasFocus) - inverted = true; + inverted = ThemeEngine::kTextInversionFocus; else - g_gui.theme()->drawWidgetBackground(Common::Rect(_x, y - 1, _x + _w - 1, y + fontHeight - 1), - 0, ThemeEngine::kWidgetBackgroundBorderSmall); + inverted = ThemeEngine::kTextInversion; } Common::Rect r(getEditRect()); @@ -560,6 +576,7 @@ void ListWidget::setFilter(const String &filter, bool redraw) { if (_filter.empty()) { // No filter -> display everything _list = _dataList; + _listIndex.clear(); } else { // Restrict the list to everything which contains all words in _filter // as substrings, ignoring case. diff --git a/gui/PopUpWidget.cpp b/gui/PopUpWidget.cpp index cc756a96b6..35cfaf6d4a 100644 --- a/gui/PopUpWidget.cpp +++ b/gui/PopUpWidget.cpp @@ -345,7 +345,7 @@ void PopUpDialog::drawMenuEntry(int entry, bool hilite) { g_gui.theme()->drawLineSeparator(Common::Rect(x, y, x+w, y+kLineHeight)); } else { g_gui.theme()->drawText(Common::Rect(x+1, y+2, x+w, y+2+kLineHeight), name, hilite ? ThemeEngine::kStateHighlight : ThemeEngine::kStateEnabled, - Graphics::kTextAlignLeft, false, _leftPadding); + Graphics::kTextAlignLeft, ThemeEngine::kTextInversionNone, _leftPadding); } } diff --git a/gui/ThemeEngine.cpp b/gui/ThemeEngine.cpp index a25c111da3..81453be356 100644 --- a/gui/ThemeEngine.cpp +++ b/gui/ThemeEngine.cpp @@ -167,6 +167,7 @@ static const DrawDataInfo kDrawDataDefaults[] = { {kDDPlainColorBackground, "plain_bg", true, kDDNone}, {kDDDefaultBackground, "default_bg", true, kDDNone}, {kDDTextSelectionBackground, "text_selection", false, kDDNone}, + {kDDTextSelectionFocusBackground, "text_selection_focus", false, kDDNone}, {kDDWidgetBackgroundDefault, "widget_default", true, kDDNone}, {kDDWidgetBackgroundSmall, "widget_small", true, kDDNone}, @@ -911,21 +912,21 @@ void ThemeEngine::drawDialogBackground(const Common::Rect &r, DialogBackground b return; switch (bgtype) { - case kDialogBackgroundMain: - queueDD(kDDMainDialogBackground, r); - break; + case kDialogBackgroundMain: + queueDD(kDDMainDialogBackground, r); + break; - case kDialogBackgroundSpecial: - queueDD(kDDSpecialColorBackground, r); - break; + case kDialogBackgroundSpecial: + queueDD(kDDSpecialColorBackground, r); + break; - case kDialogBackgroundPlain: - queueDD(kDDPlainColorBackground, r); - break; + case kDialogBackgroundPlain: + queueDD(kDDPlainColorBackground, r); + break; - case kDialogBackgroundDefault: - queueDD(kDDDefaultBackground, r); - break; + case kDialogBackgroundDefault: + queueDD(kDDDefaultBackground, r); + break; } } @@ -995,60 +996,66 @@ void ThemeEngine::drawTab(const Common::Rect &r, int tabHeight, int tabWidth, co if (!ready()) return; - const int tabOffset = 2; - tabWidth -= tabOffset; - queueDD(kDDTabBackground, Common::Rect(r.left, r.top, r.right, r.top + tabHeight)); for (int i = 0; i < (int)tabs.size(); ++i) { if (i == active) continue; - Common::Rect tabRect(r.left + i * (tabWidth + tabOffset), r.top, r.left + i * (tabWidth + tabOffset) + tabWidth, r.top + tabHeight); + Common::Rect tabRect(r.left + i * tabWidth, r.top, r.left + (i + 1) * tabWidth, r.top + tabHeight); queueDD(kDDTabInactive, tabRect); queueDDText(getTextData(kDDTabInactive), tabRect, tabs[i], false, false, _widgets[kDDTabInactive]->_textAlignH, _widgets[kDDTabInactive]->_textAlignV); } if (active >= 0) { - Common::Rect tabRect(r.left + active * (tabWidth + tabOffset), r.top, r.left + active * (tabWidth + tabOffset) + tabWidth, r.top + tabHeight); - const uint16 tabLeft = active * (tabWidth + tabOffset); + Common::Rect tabRect(r.left + active * tabWidth, r.top, r.left + (active + 1) * tabWidth, r.top + tabHeight); + const uint16 tabLeft = active * tabWidth; const uint16 tabRight = MAX(r.right - tabRect.right, 0); queueDD(kDDTabActive, tabRect, (tabLeft << 16) | (tabRight & 0xFFFF)); queueDDText(getTextData(kDDTabActive), tabRect, tabs[active], false, false, _widgets[kDDTabActive]->_textAlignH, _widgets[kDDTabActive]->_textAlignV); } } -void ThemeEngine::drawText(const Common::Rect &r, const Common::String &str, WidgetStateInfo state, Graphics::TextAlign align, bool inverted, int deltax, bool useEllipsis, FontStyle font) { +void ThemeEngine::drawText(const Common::Rect &r, const Common::String &str, WidgetStateInfo state, Graphics::TextAlign align, TextInversionState inverted, int deltax, bool useEllipsis, FontStyle font) { if (!ready()) return; - if (inverted) { + switch (inverted) { + case kTextInversion: queueDD(kDDTextSelectionBackground, r); queueDDText(kTextDataInverted, r, str, false, useEllipsis, align, kTextAlignVCenter, deltax); return; + + case kTextInversionFocus: + queueDD(kDDTextSelectionFocusBackground, r); + queueDDText(kTextDataInverted, r, str, false, useEllipsis, align, kTextAlignVCenter, deltax); + return; + + default: + break; } switch (font) { - case kFontStyleNormal: - queueDDText(kTextDataNormalFont, r, str, true, useEllipsis, align, kTextAlignVCenter, deltax); - return; + case kFontStyleNormal: + queueDDText(kTextDataNormalFont, r, str, true, useEllipsis, align, kTextAlignVCenter, deltax); + return; - default: - break; + default: + break; } switch (state) { - case kStateDisabled: - queueDDText(kTextDataDisabled, r, str, true, useEllipsis, align, kTextAlignVCenter, deltax); - return; + case kStateDisabled: + queueDDText(kTextDataDisabled, r, str, true, useEllipsis, align, kTextAlignVCenter, deltax); + return; - case kStateHighlight: - queueDDText(kTextDataHover, r, str, true, useEllipsis, align, kTextAlignVCenter, deltax); - return; + case kStateHighlight: + queueDDText(kTextDataHover, r, str, true, useEllipsis, align, kTextAlignVCenter, deltax); + return; - case kStateEnabled: - queueDDText(kTextDataDefault, r, str, true, useEllipsis, align, kTextAlignVCenter, deltax); - return; + case kStateEnabled: + queueDDText(kTextDataDefault, r, str, true, useEllipsis, align, kTextAlignVCenter, deltax); + return; } } diff --git a/gui/ThemeEngine.h b/gui/ThemeEngine.h index f9226a81d8..c5758392a7 100644 --- a/gui/ThemeEngine.h +++ b/gui/ThemeEngine.h @@ -62,6 +62,7 @@ enum DrawData { kDDPlainColorBackground, kDDDefaultBackground, kDDTextSelectionBackground, + kDDTextSelectionFocusBackground, kDDWidgetBackgroundDefault, kDDWidgetBackgroundSmall, @@ -156,6 +157,13 @@ public: typedef State WidgetStateInfo; + //! Text inversion state of the text to be draw + enum TextInversionState { + kTextInversionNone, //!< Indicates that the text should not be drawn inverted + kTextInversion, //!< Indicates that the text should be drawn inverted, but not focused + kTextInversionFocus //!< Indicates thte the test should be drawn inverted, and focused + }; + enum ScrollbarState { kScrollbarStateNo, kScrollbarStateUp, @@ -302,7 +310,7 @@ public: void drawDialogBackground(const Common::Rect &r, DialogBackground type, WidgetStateInfo state = kStateEnabled); - void drawText(const Common::Rect &r, const Common::String &str, WidgetStateInfo state = kStateEnabled, Graphics::TextAlign align = Graphics::kTextAlignCenter, bool inverted = false, int deltax = 0, bool useEllipsis = true, FontStyle font = kFontStyleBold); + void drawText(const Common::Rect &r, const Common::String &str, WidgetStateInfo state = kStateEnabled, Graphics::TextAlign align = Graphics::kTextAlignCenter, TextInversionState inverted = kTextInversionNone, int deltax = 0, bool useEllipsis = true, FontStyle font = kFontStyleBold); void drawChar(const Common::Rect &r, byte ch, const Graphics::Font *font, WidgetStateInfo state = kStateEnabled); diff --git a/gui/about.cpp b/gui/about.cpp index fb30f5f296..03927e6a40 100644 --- a/gui/about.cpp +++ b/gui/about.cpp @@ -247,7 +247,7 @@ void AboutDialog::drawDialog() { str++; if (*str && y > _y && y + g_gui.theme()->getFontHeight() < _y + _h) - g_gui.theme()->drawText(Common::Rect(_x + _xOff, y, _x + _w - _xOff, y + g_gui.theme()->getFontHeight()), str, state, align, false, 0, false); + g_gui.theme()->drawText(Common::Rect(_x + _xOff, y, _x + _w - _xOff, y + g_gui.theme()->getFontHeight()), str, state, align, ThemeEngine::kTextInversionNone, 0, false); y += _lineHeight; } } diff --git a/gui/console.cpp b/gui/console.cpp index e33aa9d9fe..498d1767a6 100644 --- a/gui/console.cpp +++ b/gui/console.cpp @@ -112,6 +112,7 @@ void ConsoleDialog::init() { _w = _w - _w / 20; _h = _h * kConsoleLineHeight + 2; + _x = _w / 40; // Set scrollbar dimensions int scrollBarWidth = g_gui.xmlEval()->getVar("Globals.Scrollbar.Width", 0); @@ -149,8 +150,8 @@ void ConsoleDialog::open() { if (_w != w || _h != h) init(); - _x = _w / 40; _y = -_h; + _slideTime = g_system->getMillis(); _slideMode = kDownSlideMode; diff --git a/gui/launcher.cpp b/gui/launcher.cpp index da49c1ccfd..1ab4728072 100644 --- a/gui/launcher.cpp +++ b/gui/launcher.cpp @@ -641,6 +641,10 @@ void LauncherDialog::updateListing() { // Select the last entry if the list has been reduced _list->setSelected(_list->getList().size() - 1); updateButtons(); + + // Update the filter settings, those are lost when "setList" + // is called. + _list->setFilter(_searchWidget->getEditString()); } void LauncherDialog::addGame() { diff --git a/gui/themes/default.inc b/gui/themes/default.inc index d2fe7dade5..0331c90fbb 100644 --- a/gui/themes/default.inc +++ b/gui/themes/default.inc @@ -1,329 +1,4 @@ "<?xml version = '1.0'?>" -"<render_info> " -"<palette> " -"<color name='black' " -"rgb='0,0,0' " -"/> " -"<color name='lightgrey' " -"rgb='104,104,104' " -"/> " -"<color name='darkgrey' " -"rgb='64,64,64' " -"/> " -"<color name='green' " -"rgb='32,160,32' " -"/> " -"<color name='green2' " -"rgb='0,255,0' " -"/> " -"</palette> " -"<fonts> " -"<font id='text_default' " -"file='default' " -"color='green' " -"/> " -"<font id='text_hover' " -"file='default' " -"color='green2' " -"/> " -"<font id='text_disabled' " -"file='default' " -"color='lightgrey' " -"/> " -"<font id='text_inverted' " -"file='default' " -"color='black' " -"/> " -"<font id='text_button' " -"file='default' " -"color='green' " -"/> " -"<font id='text_button_hover' " -"file='default' " -"color='green2' " -"/> " -"<font id='text_normal' " -"file='default' " -"color='green' " -"/> " -"</fonts> " -"<defaults fill='foreground' fg_color='darkgrey' bg_color='black' shadow='0' bevel_color='lightgrey'/> " -"<drawdata id='text_selection' cache='false'> " -"<drawstep func='square' " -"fill='foreground' " -"fg_color='green' " -"/> " -"</drawdata> " -"<drawdata id='mainmenu_bg' cache='false'> " -"<drawstep func='fill' " -"fill='foreground' " -"fg_color='black' " -"/> " -"</drawdata> " -"<drawdata id='special_bg' cache='false'> " -"<drawstep func='bevelsq' " -"bevel='2' " -"/> " -"</drawdata> " -"<drawdata id='separator' cache='false'> " -"<drawstep func='square' " -"fill='foreground' " -"height='2' " -"ypos='center' " -"fg_color='lightgrey' " -"/> " -"</drawdata> " -"<drawdata id='scrollbar_base' cache='false'> " -"<drawstep func='bevelsq' " -"bevel='2' " -"/> " -"</drawdata> " -"<drawdata id='scrollbar_handle_hover' cache='false'> " -"<drawstep func='square' " -"fill='foreground' " -"fg_color='green2' " -"/> " -"</drawdata> " -"<drawdata id='scrollbar_handle_idle' cache='false'> " -"<drawstep func='square' " -"fill='foreground' " -"fg_color='green' " -"/> " -"</drawdata> " -"<drawdata id='scrollbar_button_idle' cache='false'> " -"<drawstep func='bevelsq' " -"bevel='2' " -"fill='none' " -"/> " -"<drawstep func='triangle' " -"fg_color='green' " -"fill='foreground' " -"width='auto' " -"height='auto' " -"xpos='center' " -"ypos='center' " -"orientation='top' " -"/> " -"</drawdata> " -"<drawdata id='scrollbar_button_hover' cache='false'> " -"<drawstep func='bevelsq' " -"bevel='2' " -"fill='none' " -"/> " -"<drawstep func='triangle' " -"fg_color='green2' " -"fill='foreground' " -"width='auto' " -"height='auto' " -"xpos='center' " -"ypos='center' " -"orientation='top' " -"/> " -"</drawdata> " -"<drawdata id='tab_active' cache='false'> " -"<text font='text_hover' " -"vertical_align='center' " -"horizontal_align='center' " -"/> " -"<drawstep func='tab' " -"bevel='2' " -"radius='0' " -"fill='none' " -"/> " -"</drawdata> " -"<drawdata id='tab_inactive' cache='false'> " -"<text font='text_default' " -"vertical_align='center' " -"horizontal_align='center' " -"/> " -"<drawstep func='tab' " -"bevel='2' " -"radius='0' " -"fill='none' " -"/> " -"</drawdata> " -"<drawdata id='tab_background' cache='false'> " -"</drawdata> " -"<drawdata id='widget_slider' cache='false'> " -"<drawstep func='bevelsq' " -"bevel='2' " -"fill='none' " -"/> " -"</drawdata> " -"<drawdata id='slider_disabled' cache='false'> " -"<drawstep func='square' " -"fill='foreground' " -"fg_color='lightgrey' " -"/> " -"</drawdata> " -"<drawdata id='slider_full' cache='false'> " -"<drawstep func='square' " -"fill='foreground' " -"fg_color='green' " -"/> " -"</drawdata> " -"<drawdata id='slider_hover' cache='false'> " -"<drawstep func='square' " -"fill='foreground' " -"fg_color='green2' " -"/> " -"</drawdata> " -"<drawdata id='widget_small' cache='false'> " -"<drawstep func='bevelsq' " -"bevel='2' " -"fill='none' " -"/> " -"</drawdata> " -"<drawdata id='popup_idle' cache='false'> " -"<drawstep func='bevelsq' " -"bevel='2' " -"fill='none' " -"/> " -"<drawstep func='triangle' " -"fg_color='green' " -"fill='foreground' " -"width='height' " -"height='auto' " -"xpos='right' " -"ypos='center' " -"orientation='bottom' " -"/> " -"<text font='text_default' " -"vertical_align='center' " -"horizontal_align='left' " -"/> " -"</drawdata> " -"<drawdata id='popup_disabled' cache='false'> " -"<drawstep func='bevelsq' " -"bevel='2' " -"fill='none' " -"/> " -"<drawstep func='triangle' " -"fg_color='lightgrey' " -"fill='foreground' " -"width='height' " -"height='auto' " -"xpos='right' " -"ypos='center' " -"orientation='bottom' " -"/> " -"<text font='text_disabled' " -"vertical_align='center' " -"horizontal_align='left' " -"/> " -"</drawdata> " -"<drawdata id='popup_hover' cache='false'> " -"<drawstep func='bevelsq' " -"bevel='2' " -"fill='none' " -"/> " -"<drawstep func='triangle' " -"fg_color='green2' " -"fill='foreground' " -"width='height' " -"height='auto' " -"xpos='right' " -"ypos='center' " -"orientation='bottom' " -"/> " -"<text font='text_hover' " -"vertical_align='center' " -"horizontal_align='left' " -"/> " -"</drawdata> " -"<drawdata id='widget_textedit' cache='false'> " -"<drawstep func='bevelsq' " -"bevel='2' " -"fill='none' " -"/> " -"</drawdata> " -"<drawdata id='plain_bg' cache='false'> " -"<drawstep func='bevelsq' " -"bevel='2' " -"/> " -"</drawdata> " -"<drawdata id='caret' cache='false'> " -"<drawstep func='square' " -"fill='foreground' " -"fg_color='lightgrey' " -"/> " -"</drawdata> " -"<drawdata id='default_bg' cache='false'> " -"<drawstep func='bevelsq' " -"bevel='2' " -"/> " -"</drawdata> " -"<drawdata id='button_idle' cache='false'> " -"<text font='text_button' " -"vertical_align='center' " -"horizontal_align='center' " -"/> " -"<drawstep func='bevelsq' " -"bevel='2' " -"fill='none' " -"/> " -"</drawdata> " -"<drawdata id='button_hover' cache='false'> " -"<text font='text_button_hover' " -"vertical_align='center' " -"horizontal_align='center' " -"/> " -"<drawstep func='bevelsq' " -"bevel='2' " -"fill='none' " -"/> " -"</drawdata> " -"<drawdata id='button_disabled' cache='false'> " -"<text font='text_disabled' " -"vertical_align='center' " -"horizontal_align='center' " -"/> " -"<drawstep func='bevelsq' " -"bevel='2' " -"fill='none' " -"/> " -"</drawdata> " -"<drawdata id='checkbox_disabled' cache='false'> " -"<text font='text_disabled' " -"vertical_align='top' " -"horizontal_align='left' " -"/> " -"<drawstep func='bevelsq' " -"bevel='2' " -"fill='none' " -"/> " -"</drawdata> " -"<drawdata id='checkbox_selected' cache='false'> " -"<text font='text_default' " -"vertical_align='top' " -"horizontal_align='left' " -"/> " -"<drawstep func='bevelsq' " -"bevel='2' " -"fill='none' " -"/> " -"<drawstep func='cross' " -"fill='foreground' " -"stroke='2' " -"fg_color='green' " -"/> " -"</drawdata> " -"<drawdata id='checkbox_default' cache='false'> " -"<text font='text_default' " -"vertical_align='top' " -"horizontal_align='left' " -"/> " -"<drawstep func='bevelsq' " -"bevel='2' " -"fill='none' " -"/> " -"</drawdata> " -"<drawdata id='widget_default' cache='false'> " -"<drawstep func='bevelsq' " -"bevel='2' " -"/> " -"</drawdata> " -"</render_info> " "<layout_info resolution='-320xY,-256x240'> " "<globals> " "<def var='Line.Height' value='16' /> " @@ -1015,7 +690,7 @@ "height='Globals.Line.Height' " "/> " "<widget name='HelpText' " -"height='220' " +"height='200' " "/> " "<layout type='horizontal' padding='0,0,16,0'> " "<widget name='Prev' " @@ -1077,6 +752,337 @@ "</layout> " "</dialog> " "</layout_info> " +"<render_info> " +"<palette> " +"<color name='black' " +"rgb='0,0,0' " +"/> " +"<color name='lightgrey' " +"rgb='104,104,104' " +"/> " +"<color name='darkgrey' " +"rgb='64,64,64' " +"/> " +"<color name='green' " +"rgb='32,160,32' " +"/> " +"<color name='green2' " +"rgb='0,255,0' " +"/> " +"</palette> " +"<fonts> " +"<font id='text_default' " +"file='default' " +"color='green' " +"/> " +"<font id='text_hover' " +"file='default' " +"color='green2' " +"/> " +"<font id='text_disabled' " +"file='default' " +"color='lightgrey' " +"/> " +"<font id='text_inverted' " +"file='default' " +"color='black' " +"/> " +"<font id='text_button' " +"file='default' " +"color='green' " +"/> " +"<font id='text_button_hover' " +"file='default' " +"color='green2' " +"/> " +"<font id='text_normal' " +"file='default' " +"color='green' " +"/> " +"</fonts> " +"<defaults fill='foreground' fg_color='darkgrey' bg_color='black' shadow='0' bevel_color='lightgrey'/> " +"<drawdata id='text_selection' cache='false'> " +"<drawstep func='square' " +"fill='foreground' " +"fg_color='lightgrey' " +"/> " +"</drawdata> " +"<drawdata id='text_selection_focus' cache='false'> " +"<drawstep func='square' " +"fill='foreground' " +"fg_color='green' " +"/> " +"</drawdata> " +"<drawdata id='mainmenu_bg' cache='false'> " +"<drawstep func='fill' " +"fill='foreground' " +"fg_color='black' " +"/> " +"</drawdata> " +"<drawdata id='special_bg' cache='false'> " +"<drawstep func='bevelsq' " +"bevel='2' " +"/> " +"</drawdata> " +"<drawdata id='separator' cache='false'> " +"<drawstep func='square' " +"fill='foreground' " +"height='2' " +"ypos='center' " +"fg_color='lightgrey' " +"/> " +"</drawdata> " +"<drawdata id='scrollbar_base' cache='false'> " +"<drawstep func='bevelsq' " +"bevel='2' " +"/> " +"</drawdata> " +"<drawdata id='scrollbar_handle_hover' cache='false'> " +"<drawstep func='square' " +"fill='foreground' " +"fg_color='green2' " +"/> " +"</drawdata> " +"<drawdata id='scrollbar_handle_idle' cache='false'> " +"<drawstep func='square' " +"fill='foreground' " +"fg_color='green' " +"/> " +"</drawdata> " +"<drawdata id='scrollbar_button_idle' cache='false'> " +"<drawstep func='bevelsq' " +"bevel='2' " +"fill='none' " +"/> " +"<drawstep func='triangle' " +"fg_color='green' " +"fill='foreground' " +"width='auto' " +"height='auto' " +"xpos='center' " +"ypos='center' " +"orientation='top' " +"/> " +"</drawdata> " +"<drawdata id='scrollbar_button_hover' cache='false'> " +"<drawstep func='bevelsq' " +"bevel='2' " +"fill='none' " +"/> " +"<drawstep func='triangle' " +"fg_color='green2' " +"fill='foreground' " +"width='auto' " +"height='auto' " +"xpos='center' " +"ypos='center' " +"orientation='top' " +"/> " +"</drawdata> " +"<drawdata id='tab_active' cache='false'> " +"<text font='text_hover' " +"vertical_align='center' " +"horizontal_align='center' " +"/> " +"<drawstep func='tab' " +"bevel='2' " +"radius='0' " +"fill='none' " +"/> " +"</drawdata> " +"<drawdata id='tab_inactive' cache='false'> " +"<text font='text_default' " +"vertical_align='center' " +"horizontal_align='center' " +"/> " +"<drawstep func='tab' " +"bevel='2' " +"radius='0' " +"fill='none' " +"/> " +"</drawdata> " +"<drawdata id='tab_background' cache='false'> " +"</drawdata> " +"<drawdata id='widget_slider' cache='false'> " +"<drawstep func='bevelsq' " +"bevel='2' " +"fill='none' " +"/> " +"</drawdata> " +"<drawdata id='slider_disabled' cache='false'> " +"<drawstep func='square' " +"fill='foreground' " +"fg_color='lightgrey' " +"/> " +"</drawdata> " +"<drawdata id='slider_full' cache='false'> " +"<drawstep func='square' " +"fill='foreground' " +"fg_color='green' " +"/> " +"</drawdata> " +"<drawdata id='slider_hover' cache='false'> " +"<drawstep func='square' " +"fill='foreground' " +"fg_color='green2' " +"/> " +"</drawdata> " +"<drawdata id='widget_small' cache='false'> " +"<drawstep func='bevelsq' " +"bevel='2' " +"fill='none' " +"/> " +"</drawdata> " +"<drawdata id='popup_idle' cache='false'> " +"<drawstep func='bevelsq' " +"bevel='2' " +"fill='none' " +"/> " +"<drawstep func='triangle' " +"fg_color='green' " +"fill='foreground' " +"width='height' " +"height='auto' " +"xpos='right' " +"ypos='center' " +"orientation='bottom' " +"/> " +"<text font='text_default' " +"vertical_align='center' " +"horizontal_align='left' " +"/> " +"</drawdata> " +"<drawdata id='popup_disabled' cache='false'> " +"<drawstep func='bevelsq' " +"bevel='2' " +"fill='none' " +"/> " +"<drawstep func='triangle' " +"fg_color='lightgrey' " +"fill='foreground' " +"width='height' " +"height='auto' " +"xpos='right' " +"ypos='center' " +"orientation='bottom' " +"/> " +"<text font='text_disabled' " +"vertical_align='center' " +"horizontal_align='left' " +"/> " +"</drawdata> " +"<drawdata id='popup_hover' cache='false'> " +"<drawstep func='bevelsq' " +"bevel='2' " +"fill='none' " +"/> " +"<drawstep func='triangle' " +"fg_color='green2' " +"fill='foreground' " +"width='height' " +"height='auto' " +"xpos='right' " +"ypos='center' " +"orientation='bottom' " +"/> " +"<text font='text_hover' " +"vertical_align='center' " +"horizontal_align='left' " +"/> " +"</drawdata> " +"<drawdata id='widget_textedit' cache='false'> " +"<drawstep func='bevelsq' " +"bevel='2' " +"fill='none' " +"/> " +"</drawdata> " +"<drawdata id='plain_bg' cache='false'> " +"<drawstep func='bevelsq' " +"bevel='2' " +"/> " +"</drawdata> " +"<drawdata id='caret' cache='false'> " +"<drawstep func='square' " +"fill='foreground' " +"fg_color='lightgrey' " +"/> " +"</drawdata> " +"<drawdata id='default_bg' cache='false'> " +"<drawstep func='bevelsq' " +"bevel='2' " +"/> " +"</drawdata> " +"<drawdata id='button_idle' cache='false'> " +"<text font='text_button' " +"vertical_align='center' " +"horizontal_align='center' " +"/> " +"<drawstep func='bevelsq' " +"bevel='2' " +"fill='none' " +"/> " +"</drawdata> " +"<drawdata id='button_hover' cache='false'> " +"<text font='text_button_hover' " +"vertical_align='center' " +"horizontal_align='center' " +"/> " +"<drawstep func='bevelsq' " +"bevel='2' " +"fill='none' " +"/> " +"</drawdata> " +"<drawdata id='button_disabled' cache='false'> " +"<text font='text_disabled' " +"vertical_align='center' " +"horizontal_align='center' " +"/> " +"<drawstep func='bevelsq' " +"bevel='2' " +"fill='none' " +"/> " +"</drawdata> " +"<drawdata id='checkbox_disabled' cache='false'> " +"<text font='text_disabled' " +"vertical_align='top' " +"horizontal_align='left' " +"/> " +"<drawstep func='bevelsq' " +"bevel='2' " +"fill='none' " +"/> " +"</drawdata> " +"<drawdata id='checkbox_selected' cache='false'> " +"<text font='text_default' " +"vertical_align='top' " +"horizontal_align='left' " +"/> " +"<drawstep func='bevelsq' " +"bevel='2' " +"fill='none' " +"/> " +"<drawstep func='cross' " +"fill='foreground' " +"stroke='2' " +"fg_color='green' " +"/> " +"</drawdata> " +"<drawdata id='checkbox_default' cache='false'> " +"<text font='text_default' " +"vertical_align='top' " +"horizontal_align='left' " +"/> " +"<drawstep func='bevelsq' " +"bevel='2' " +"fill='none' " +"/> " +"</drawdata> " +"<drawdata id='widget_default' cache='false'> " +"<drawstep func='bevelsq' " +"bevel='2' " +"/> " +"</drawdata> " +"</render_info> " "<layout_info resolution='320xY,256x240,Xx272'> " "<globals> " "<def var='Line.Height' value='12' /> " @@ -1766,7 +1772,7 @@ "</layout> " "</dialog> " "<dialog name='ScummHelp' overlays='screen'> " -"<layout type='vertical' padding='8,8,0,0'> " +"<layout type='vertical' padding='8,8,8,8'> " "<widget name='Title' " "width='180' " "height='Globals.Line.Height' " diff --git a/gui/themes/scummclassic.zip b/gui/themes/scummclassic.zip Binary files differindex cd686aaf1e..ce21ea5487 100644 --- a/gui/themes/scummclassic.zip +++ b/gui/themes/scummclassic.zip diff --git a/gui/themes/scummclassic/classic_gfx.stx b/gui/themes/scummclassic/classic_gfx.stx index 911ef585aa..f6c06e2c80 100644 --- a/gui/themes/scummclassic/classic_gfx.stx +++ b/gui/themes/scummclassic/classic_gfx.stx @@ -78,6 +78,13 @@ <drawdata id = 'text_selection' cache = 'false'> <drawstep func = 'square' fill = 'foreground' + fg_color = 'lightgrey' + /> + </drawdata> + + <drawdata id = 'text_selection_focus' cache = 'false'> + <drawstep func = 'square' + fill = 'foreground' fg_color = 'green' /> </drawdata> diff --git a/gui/themes/scummclassic/classic_layout.stx b/gui/themes/scummclassic/classic_layout.stx index 0256fc7dd6..e886a1a2f0 100644 --- a/gui/themes/scummclassic/classic_layout.stx +++ b/gui/themes/scummclassic/classic_layout.stx @@ -745,7 +745,7 @@ height = 'Globals.Line.Height' /> <widget name = 'HelpText' - height = '220' + height = '200' /> <layout type = 'horizontal' padding = '0, 0, 16, 0'> <widget name = 'Prev' diff --git a/gui/themes/scummclassic/classic_layout_lowres.stx b/gui/themes/scummclassic/classic_layout_lowres.stx index d4a92b831e..b4143964af 100644 --- a/gui/themes/scummclassic/classic_layout_lowres.stx +++ b/gui/themes/scummclassic/classic_layout_lowres.stx @@ -744,7 +744,7 @@ </dialog> <dialog name = 'ScummHelp' overlays = 'screen'> - <layout type = 'vertical' padding = '8, 8, 0, 0'> + <layout type = 'vertical' padding = '8, 8, 8, 8'> <widget name = 'Title' width = '180' height = 'Globals.Line.Height' diff --git a/gui/themes/scummmodern.zip b/gui/themes/scummmodern.zip Binary files differindex a133723d99..b38ee79e84 100644 --- a/gui/themes/scummmodern.zip +++ b/gui/themes/scummmodern.zip diff --git a/gui/themes/scummmodern/scummmodern_gfx.stx b/gui/themes/scummmodern/scummmodern_gfx.stx index b0bba89bfe..f74d0f0d2f 100644 --- a/gui/themes/scummmodern/scummmodern_gfx.stx +++ b/gui/themes/scummmodern/scummmodern_gfx.stx @@ -142,6 +142,13 @@ <drawdata id = 'text_selection' cache = 'false'> <drawstep func = 'square' fill = 'foreground' + fg_color = 'darkgray' + /> + </drawdata> + + <drawdata id = 'text_selection_focus' cache = 'false'> + <drawstep func = 'square' + fill = 'foreground' fg_color = 'bgreen' /> </drawdata> @@ -264,7 +271,7 @@ radius = '4' stroke = '0' fill = 'background' - bg_color = '248, 228, 152' + bg_color = '248, 232, 168' shadow = '3' /> </drawdata> diff --git a/gui/themes/scummmodern/scummmodern_layout_lowres.stx b/gui/themes/scummmodern/scummmodern_layout_lowres.stx index 13346a1d6f..693efaaca9 100644 --- a/gui/themes/scummmodern/scummmodern_layout_lowres.stx +++ b/gui/themes/scummmodern/scummmodern_layout_lowres.stx @@ -732,14 +732,14 @@ </layout> </dialog> - <dialog name = 'ScummHelp' overlays = 'screen'> - <layout type = 'vertical' padding = '8, 8, 0, 0'> + <dialog name = 'ScummHelp' overlays = 'screen' inset = '8'> + <layout type = 'vertical' padding = '8, 8, 8, 8'> <widget name = 'Title' width = '180' height = 'Globals.Line.Height' /> <widget name = 'HelpText' - height = '140' + height = '130' /> <layout type = 'horizontal' padding = '0, 0, 0, 0'> <widget name = 'Prev' diff --git a/sound/aiff.cpp b/sound/aiff.cpp index 884becb212..3c8a7f02a4 100644 --- a/sound/aiff.cpp +++ b/sound/aiff.cpp @@ -94,7 +94,7 @@ bool loadAIFFFromStream(Common::SeekableReadStream &stream, int &size, int &rate uint16 numChannels = 0, bitsPerSample = 0; uint32 numSampleFrames = 0, offset = 0, blockSize = 0, soundOffset = 0; - while ((!foundCOMM || !foundSSND) && !stream.ioFailed()) { + while (!(foundCOMM && foundSSND) && !stream.err() && !stream.eos()) { uint32 length, pos; stream.read(buf, 4); diff --git a/sound/flac.cpp b/sound/flac.cpp index 5b6a04b726..bb633b8352 100644 --- a/sound/flac.cpp +++ b/sound/flac.cpp @@ -402,21 +402,23 @@ int FlacInputStream::readBuffer(int16 *buffer, const int numSamples) { } inline ::FLAC__SeekableStreamDecoderReadStatus FlacInputStream::callbackRead(FLAC__byte buffer[], FLAC_size_t *bytes) { - if (*bytes == 0) + if (*bytes == 0) { #ifdef LEGACY_FLAC return FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_ERROR; /* abort to avoid a deadlock */ #else return FLAC__STREAM_DECODER_READ_STATUS_ABORT; /* abort to avoid a deadlock */ #endif + } const uint32 bytesRead = _inStream->read(buffer, *bytes); - if (bytesRead == 0 && _inStream->ioFailed()) + if (bytesRead == 0) { #ifdef LEGACY_FLAC - return FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_ERROR; + return _inStream->eos() ? FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_OK : FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_ERROR; #else - return FLAC__STREAM_DECODER_READ_STATUS_ABORT; + return _inStream->eos() ? FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM : FLAC__STREAM_DECODER_READ_STATUS_ABORT; #endif + } *bytes = static_cast<uint>(bytesRead); #ifdef LEGACY_FLAC |