diff options
author | Norbert Lange | 2009-07-17 21:23:54 +0000 |
---|---|---|
committer | Norbert Lange | 2009-07-17 21:23:54 +0000 |
commit | bb64bf008d03e01760a468d0df8cacb164725d41 (patch) | |
tree | d73710df5b07f3fa1ca30e719c1c1f58ebe0b107 /backends | |
parent | 81ac29ebca30c352646a5b21de512087cb96a672 (diff) | |
parent | 53756ef1d022a959b24c041e18f55eef34e60dd3 (diff) | |
download | scummvm-rg350-bb64bf008d03e01760a468d0df8cacb164725d41.tar.gz scummvm-rg350-bb64bf008d03e01760a468d0df8cacb164725d41.tar.bz2 scummvm-rg350-bb64bf008d03e01760a468d0df8cacb164725d41.zip |
merge with trunk
svn-id: r42574
Diffstat (limited to 'backends')
33 files changed, 1979 insertions, 1410 deletions
diff --git a/backends/events/default/default-events.h b/backends/events/default/default-events.h index 5841318fd4..9d47104608 100644 --- a/backends/events/default/default-events.h +++ b/backends/events/default/default-events.h @@ -143,6 +143,9 @@ public: virtual int shouldQuit() const { return _shouldQuit; } virtual int shouldRTL() const { return _shouldRTL; } virtual void resetRTL() { _shouldRTL = false; } +#ifdef FORCE_RTL + virtual void resetQuit() { _shouldQuit = false; } +#endif #ifdef ENABLE_KEYMAPPER virtual Common::Keymapper *getKeymapper() { return _keymapper; } diff --git a/backends/midi/timidity.cpp b/backends/midi/timidity.cpp index c813441724..d533dab770 100644 --- a/backends/midi/timidity.cpp +++ b/backends/midi/timidity.cpp @@ -99,7 +99,7 @@ private: int connect_to_server(const char* hostname, unsigned short tcp_port); /* send command to the server; printf-like; returns reply string */ - char *timidity_ctl_command(const char *fmt, ...); + char *timidity_ctl_command(const char *fmt, ...) GCC_PRINTF(2, 3); /* timidity data socket-related stuff */ void timidity_meta_seq(int p1, int p2, int p3); diff --git a/backends/platform/dc/dc.h b/backends/platform/dc/dc.h index f86a2c6065..b67bbb51a1 100644 --- a/backends/platform/dc/dc.h +++ b/backends/platform/dc/dc.h @@ -194,7 +194,7 @@ class OSystem_Dreamcast : private DCHardware, public BaseBackend, public Filesys SoftKeyboard _softkbd; int _ms_cur_x, _ms_cur_y, _ms_cur_w, _ms_cur_h, _ms_old_x, _ms_old_y; - int _ms_hotspot_x, _ms_hotspot_y, _ms_visible, _devpoll; + int _ms_hotspot_x, _ms_hotspot_y, _ms_visible, _devpoll, _last_screen_refresh; int _current_shake_pos, _screen_w, _screen_h; int _overlay_x, _overlay_y; unsigned char *_ms_buf; @@ -220,11 +220,15 @@ class OSystem_Dreamcast : private DCHardware, public BaseBackend, public Filesys uint initSound(); void checkSound(); + void updateScreenTextures(void); + void updateScreenPolygons(void); + void maybeRefreshScreen(void); void drawMouse(int xdraw, int ydraw, int w, int h, unsigned char *buf, bool visible); void setScaling(); + Common::SaveFileManager *createSavefileManager(); }; diff --git a/backends/platform/dc/display.cpp b/backends/platform/dc/display.cpp index ba8e1ba04f..d1e95c6a91 100644 --- a/backends/platform/dc/display.cpp +++ b/backends/platform/dc/display.cpp @@ -285,11 +285,8 @@ void OSystem_Dreamcast::setShakePos(int shake_pos) _current_shake_pos = shake_pos; } -void OSystem_Dreamcast::updateScreen(void) +void OSystem_Dreamcast::updateScreenTextures(void) { - struct polygon_list mypoly; - struct packed_colour_vertex_list myvertex; - if (_screen_dirty) { _screen_buffer++; @@ -328,6 +325,12 @@ void OSystem_Dreamcast::updateScreen(void) _overlay_dirty = false; } +} + +void OSystem_Dreamcast::updateScreenPolygons(void) +{ + struct polygon_list mypoly; + struct packed_colour_vertex_list myvertex; // *((volatile unsigned int *)(void*)0xa05f8040) = 0x00ff00; @@ -448,6 +451,21 @@ void OSystem_Dreamcast::updateScreen(void) ta_commit_frame(); // *((volatile unsigned int *)(void*)0xa05f8040) = 0x0; + + _last_screen_refresh = Timer(); +} + +void OSystem_Dreamcast::updateScreen(void) +{ + updateScreenTextures(); + updateScreenPolygons(); +} + +void OSystem_Dreamcast::maybeRefreshScreen(void) +{ + unsigned int t = Timer(); + if((int)(t-_last_screen_refresh) > USEC_TO_TIMER(30000)) + updateScreenPolygons(); } void OSystem_Dreamcast::drawMouse(int xdraw, int ydraw, int w, int h, diff --git a/backends/platform/dc/input.cpp b/backends/platform/dc/input.cpp index 1b85f601a6..5d4ed7ce96 100644 --- a/backends/platform/dc/input.cpp +++ b/backends/platform/dc/input.cpp @@ -202,6 +202,8 @@ bool OSystem_Dreamcast::pollEvent(Common::Event &event) if (((int)(t-_devpoll))>=0) _devpoll = t + USEC_TO_TIMER(17000); + maybeRefreshScreen(); + int mask = getimask(); setimask(15); checkSound(); diff --git a/backends/platform/ds/arm7/Makefile b/backends/platform/ds/arm7/Makefile index 82637845db..a8dc0efe6e 100644 --- a/backends/platform/ds/arm7/Makefile +++ b/backends/platform/ds/arm7/Makefile @@ -151,13 +151,12 @@ $(OUTPUT).elf : $(OFILES) #--------------------------------------------------------------------------------- %.bin: %.elf @echo built ... $(notdir $@) - @$(OBJCOPY) -O binary $(TARGET).elf $@ + $(OBJCOPY) -O binary $(TARGET).elf $@ #--------------------------------------------------------------------------------- %.elf: echo ELF - @echo $(LD) $(LDFLAGS) -specs=ds_arm7.specs $(OFILES) $(LIBPATHS) $(LIBS) -o $(TARGET).elf - @$(LD) $(LDFLAGS) -specs=ds_arm7.specs $(OFILES) $(LIBPATHS) $(LIBS) -o $(TARGET).elf + $(LD) $(LDFLAGS) -specs=ds_arm7.specs $(OFILES) $(LIBPATHS) $(LIBS) -o $(TARGET).elf 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/ps2/Gs2dScreen.cpp b/backends/platform/ps2/Gs2dScreen.cpp index e9a846f659..a9f1d7c51d 100644 --- a/backends/platform/ps2/Gs2dScreen.cpp +++ b/backends/platform/ps2/Gs2dScreen.cpp @@ -337,6 +337,7 @@ void Gs2dScreen::newScreenSize(uint16 width, uint16 height) { memset(_screenBuf, 0, _width * height); memset(_overlayBuf, 0, _width * height * 2); memset(_clut, 0, 256 * sizeof(uint32)); + _clut[1] = GS_RGBA(0xC0, 0xC0, 0xC0, 0); // clear video ram _dmaPipe->uploadTex(_clutPtrs[MOUSE], 64, 0, 0, GS_PSMCT32, _clut, 16, 16); @@ -345,7 +346,8 @@ void Gs2dScreen::newScreenSize(uint16 width, uint16 height) { _dmaPipe->flush(); _dmaPipe->waitForDma(); - _clutChanged = _screenChanged = _overlayChanged = false; + /*_clutChanged = */ _screenChanged = _overlayChanged = false; + _clutChanged = true; // reload palette on scr change _texCoords[1].u = SCALE(_width); _texCoords[1].v = SCALE(_height); @@ -396,6 +398,13 @@ void Gs2dScreen::clearScreen(void) { SignalSema(g_DmacSema); } +void Gs2dScreen::fillScreen(uint32 col) { + WaitSema(g_DmacSema); + memset(_screenBuf, col, _width * _height); + _screenChanged = true; + SignalSema(g_DmacSema); +} + Graphics::Surface *Gs2dScreen::lockScreen() { WaitSema(g_DmacSema); @@ -541,11 +550,11 @@ Graphics::PixelFormat Gs2dScreen::getOverlayFormat(void) { } int16 Gs2dScreen::getOverlayWidth(void) { - return _videoMode.overlayWidth; + return _width; // _videoMode.overlayWidth; } int16 Gs2dScreen::getOverlayHeight(void) { - return _videoMode.overlayHeight; + return _height; // _videoMode.overlayHeight; } void Gs2dScreen::setShakePos(int shake) { diff --git a/backends/platform/ps2/Gs2dScreen.h b/backends/platform/ps2/Gs2dScreen.h index 91dfc9d327..4657ab02d9 100644 --- a/backends/platform/ps2/Gs2dScreen.h +++ b/backends/platform/ps2/Gs2dScreen.h @@ -61,6 +61,7 @@ public: void copyPrintfOverlay(const uint8* buf); void clearPrintfOverlay(void); void clearScreen(void); + void fillScreen(uint32 col); Graphics::Surface *lockScreen(); void unlockScreen(); diff --git a/backends/platform/ps2/Makefile.gdb b/backends/platform/ps2/Makefile.gdb new file mode 100644 index 0000000000..7177275830 --- /dev/null +++ b/backends/platform/ps2/Makefile.gdb @@ -0,0 +1,94 @@ +# $Header: Exp $ + include $(PS2SDK)/Defs.make + +PS2_EXTRA = /media/disk/nw8240/extras/scummvm/ports +PS2_EXTRA_INCS = /zlib/include /libmad/ee/include /SjPcm/ee/src /tremor +PS2_EXTRA_LIBS = /zlib/lib /libmad/ee/lib /SjPcm/ee/lib /tremor/tremor + +ENABLED=STATIC_PLUGIN + +#control build +DISABLE_SCALERS = true +DISABLE_HQ_SCALERS = true + +ENABLE_SCUMM = $(ENABLED) +ENABLE_SCUMM_7_8 = $(ENABLED) +#ENABLE_HE = $(ENABLED) +#ENABLE_AGI = $(ENABLED) +#ENABLE_AGOS = $(ENABLED) +#ENABLE_CINE = $(ENABLED) +#ENABLE_CRUISE = $(ENABLED) +#ENABLE_DRASCULA = $(ENABLED) +#ENABLE_GOB = $(ENABLED) +#ENABLE_IGOR = $(ENABLED) +#ENABLE_KYRA = $(ENABLED) +#ENABLE_LURE = $(ENABLED) + # ENABLE_M4 = $(ENABLED) +#ENABLE_MADE = $(ENABLED) +#ENABLE_PARALLACTION = $(ENABLED) +#ENABLE_QUEEN = $(ENABLED) +#ENABLE_SAGA = $(ENABLED) +#ENABLE_SAGA2 = $(ENABLED) +#ENABLE_IHNM = $(ENABLED) +#ENABLE_SKY = $(ENABLED) +#ENABLE_SWORD1 = $(ENABLED) +#ENABLE_SWORD2 = $(ENABLED) + # ENABLE_TINSEL = $(ENABLED) +#ENABLE_TOUCHE = $(ENABLED) + +HAVE_GCC3 = true + +CC = ee-gcc +CXX = ee-g++ +AS = ee-gcc +LD = ee-gcc +AR = ee-ar cru +RANLIB = ee-ranlib +STRIP = ee-strip +MKDIR = mkdir -p +RM = rm -f + +srcdir = ../../.. +VPATH = $(srcdir) +INCDIR = ../../../ +# DEPDIR = .deps + +DEFINES = -DUSE_VORBIS -DUSE_TREMOR -DUSE_MAD -DUSE_ZLIB -DFORCE_RTL -D_EE -D__PLAYSTATION2__ -D__PS2_DEBUG__ -g -Wall -Wno-multichar + + +INCLUDES = $(addprefix -I$(PS2_EXTRA),$(PS2_EXTRA_INCS)) +INCLUDES += -I $(PS2GDB)/ee -I $(PS2SDK)/ee/include -I $(PS2SDK)/common/include -I ./common -I . -I $(srcdir) -I $(srcdir)/engines + +TARGET = elf/scummvm.elf + +OBJS := backends/platform/ps2/DmaPipe.o \ + backends/platform/ps2/Gs2dScreen.o \ + backends/platform/ps2/irxboot.o \ + backends/platform/ps2/ps2input.o \ + backends/platform/ps2/ps2pad.o \ + backends/platform/ps2/savefilemgr.o \ + backends/platform/ps2/fileio.o \ + backends/platform/ps2/asyncfio.o \ + backends/platform/ps2/icon.o \ + backends/platform/ps2/cd.o \ + backends/platform/ps2/eecodyvdfs.o \ + backends/platform/ps2/rpckbd.o \ + backends/platform/ps2/systemps2.o \ + backends/platform/ps2/ps2mutex.o \ + backends/platform/ps2/ps2time.o \ + backends/platform/ps2/ps2debug.o + +MODULE_DIRS += . + +include $(srcdir)/Makefile.common + +LDFLAGS += -mno-crt0 $(PS2SDK)/ee/startup/crt0.o -T $(PS2SDK)/ee/startup/linkfile +LDFLAGS += -L $(PS2GDB)/lib -L $(PS2SDK)/ee/lib -L . +LDFLAGS += $(addprefix -L$(PS2_EXTRA),$(PS2_EXTRA_LIBS)) +LDFLAGS += -lmc -lpad -lmouse -lhdd -lpoweroff -lsjpcm -lmad -ltremor -lz -lm -lc -lfileXio -lps2gdbStub -lps2ip -ldebug -lkernel -lstdc++ + +all: $(TARGET) + +$(TARGET): $(OBJS) + $(LD) $^ $(LDFLAGS) -o $@ + diff --git a/backends/platform/ps2/Makefile.ps2 b/backends/platform/ps2/Makefile.ps2 index 812599d0c0..5abeae5fb5 100644 --- a/backends/platform/ps2/Makefile.ps2 +++ b/backends/platform/ps2/Makefile.ps2 @@ -1,7 +1,7 @@ # $Header: Exp $ include $(PS2SDK)/Defs.make -PS2_EXTRA = /media/disk-1/nw8240/extras/scummvm/ports +PS2_EXTRA = /media/disk/nw8240/extras/scummvm/ports PS2_EXTRA_INCS = /zlib/include /libmad/ee/include /SjPcm/ee/src /tremor PS2_EXTRA_LIBS = /zlib/lib /libmad/ee/lib /SjPcm/ee/lib /tremor/tremor @@ -45,15 +45,15 @@ LD = ee-gcc AR = ee-ar cru RANLIB = ee-ranlib STRIP = ee-strip -MKDIR = mkdir -p -RM = rm -f +MKDIR = mkdir -p +RM = rm -f srcdir = ../../.. VPATH = $(srcdir) INCDIR = ../../../ # DEPDIR = .deps -DEFINES = -DUSE_VORBIS -DUSE_TREMOR -DUSE_MAD -DUSE_ZLIB -D_EE -D__PLAYSTATION2__ -O2 -Wall -Wno-multichar +DEFINES = -DUSE_VORBIS -DUSE_TREMOR -DUSE_MAD -DUSE_ZLIB -DFORCE_RTL -D_EE -D__PLAYSTATION2__ -O2 -Wall -Wno-multichar INCLUDES = $(addprefix -I$(PS2_EXTRA),$(PS2_EXTRA_INCS)) @@ -86,7 +86,7 @@ LDFLAGS += -mno-crt0 $(PS2SDK)/ee/startup/crt0.o -T $(PS2SDK)/ee/startup/linkfil LDFLAGS += -L $(PS2SDK)/ee/lib -L . LDFLAGS += $(addprefix -L$(PS2_EXTRA),$(PS2_EXTRA_LIBS)) LDFLAGS += -lmc -lpad -lmouse -lhdd -lpoweroff -lsjpcm -lmad -ltremor -lz -lm -lc -lfileXio -lkernel -lstdc++ -# LDFLAGS += -s +LDFLAGS += -s all: $(TARGET) diff --git a/backends/platform/ps2/fileio.cpp b/backends/platform/ps2/fileio.cpp index fc35306907..017286dc45 100644 --- a/backends/platform/ps2/fileio.cpp +++ b/backends/platform/ps2/fileio.cpp @@ -58,10 +58,11 @@ Ps2File::Ps2File(void) { _cacheSize = 0; _cachePos = 0; _eof = false; + _err = false; // _cache = (uint8 *)malloc(PS2_CACHE_MAX); - _cacheBuf = (uint8*)memalign(64, CACHE_SIZE); + _cacheBuf = (uint8*)memalign(64, CACHE_SIZE * 2); _cacheOpRunning = 0; _filePos = _physFilePos = _cachePos = 0; @@ -80,7 +81,16 @@ Ps2File::Ps2File(void) { } Ps2File::~Ps2File(void) { + uint32 w; if (_fd >= 0) { + + if (_mode != O_RDONLY) { + fio.seek(_fd, 0, SEEK_SET); + fio.write(_fd, _cacheBuf, _filePos); + w = fio.sync(_fd); + printf("flushed wbuf: %x of %x\n", w, _filePos); + } + fio.close(_fd); uint32 r = fio.sync(_fd); printf("close [%d] - sync'd = %d\n", _fd, r); @@ -95,24 +105,87 @@ Ps2File::~Ps2File(void) { } bool Ps2File::open(const char *name, int mode) { - assert(_fd < 0); - +#if 1 _fd = fio.open(name, mode); printf("open %s [%d]\n", name, _fd); if (_fd >= 0) { - _fileSize = fio.seek(_fd, 0, SEEK_END); - if (mode == O_RDONLY) - // if (!(mode & O_APPEND)) + _mode = mode; + _filePos = 0; + + if (_mode == O_RDONLY) { + _fileSize = fio.seek(_fd, 0, SEEK_END); fio.seek(_fd, 0, SEEK_SET); + } + else + _fileSize = 0; + printf(" _mode = %x\n", _mode); + printf(" _fileSize = %d\n", _fileSize); + // printf(" _filePos = %d\n", _filePos); + + return true; + } + + return false; +#else + uint32 r; + + // hack: FIO does not reports size for RW (?) + _fd = fio.open(name, O_RDONLY); + if (_fd >= 0) { + _fileSize = fio.seek(_fd, 0, SEEK_END); + fio.seek(_fd, 0, SEEK_SET); /* rewind ! */ + + if (_fileSize && mode != O_RDONLY) { + fio.read(_fd, _cacheBuf, _fileSize); + r = fio.sync(_fd); + printf(" sz=%d, read=%d\n", _fileSize, r); + assert(r == _fileSize); + } + + fio.close(_fd); + } + else + _fileSize = 0; /* new file */ + + _fd = fio.open(name, mode); + + printf("open %s [%d]\n", name, _fd); + + if (_fd >= 0) { + _mode = mode; + _filePos = 0; + + if (_fileSize) { /* existing data */ + if (mode == O_RDONLY) { + /* DANGER: for w* modes it will truncate your fine files */ + fio.seek(_fd, 0, SEEK_SET); + } + else if (_mode & O_APPEND) { + fio.seek(_fd, 0, _fileSize); + _filePos = _fileSize; + } + #if 0 /* file already trunc'd when opened as w* -> moved up */ + if (mode != O_RDONLY) { + fio.read(_fd, _cacheBuf, _fileSize); + r = fio.sync(_fd); + printf(" sz=%d, read=%d\n", _fileSize, r); + assert(r == _fileSize); + // _fileSize = fio.seek(_fd, 0, SEEK_END); + } + #endif + } + + printf(" _mode = %x\n", _mode); printf(" _fileSize = %d\n", _fileSize); printf(" _filePos = %d\n", _filePos); return true; } else return false; +#endif } int32 Ps2File::tell(void) { @@ -152,10 +225,11 @@ bool Ps2File::eof(void) { } bool Ps2File::getErr(void) { - return _eof; + return _err; } void Ps2File::setErr(bool err) { + _err = err; _eof = err; } @@ -189,7 +263,9 @@ int Ps2File::seek(int32 offset, int origin) { _eof = false; res = 0; } - else _eof = true; + else { + _eof = true; + } // printf("seek [%d] %d %d\n", _fd, offset, origin); // printf(" res = %d\n", res); @@ -225,7 +301,7 @@ void Ps2File::cacheReadAhead(void) { _cachePos = cachePosEnd = _filePos & ~READ_ALIGN_MASK; assert(_filePos == _physFilePos); } else { - uint32 cacheDiff = _filePos - _cachePos; + uint32 cacheDiff = _filePos - _cachePos; assert(_bytesInCache >= cacheDiff); cacheDiff &= ~READ_ALIGN_MASK; _bytesInCache -= cacheDiff; @@ -278,10 +354,17 @@ uint32 Ps2File::read(void *dest, uint32 len) { printf("read (1) : _cachePos = %d\n", _cachePos); #endif + if (len == 0) { +#ifdef __PS2_FILE_SEMA__ + SignalSema(_sema); +#endif + return 0; + } + if (_filePos >= _fileSize) { _eof = true; #ifdef __PS2_FILE_SEMA__ - SignalSema(_sema); + SignalSema(_sema); #endif return 0; } @@ -344,32 +427,18 @@ uint32 Ps2File::read(void *dest, uint32 len) { } uint32 Ps2File::write(const void *src, uint32 len) { - uint32 w; #ifdef __PS2_FILE_SEMA__ WaitSema(_sema); #endif - _cacheSize = 0; - - w = fio.sync(_fd); - assert(w==0); - fio.seek(_fd, _filePos, SEEK_SET); - fio.write(_fd, src, len); - - w = fio.sync(_fd); + memcpy(&_cacheBuf[_filePos], src, len); + _filePos += len; #ifdef __PS2_FILE_SEMA__ SignalSema(_sema); #endif - if (w) { - _filePos += w; - if (w < len) - _eof = true; - return w; - } - - return 0; + return len; } FILE *ps2_fopen(const char *fname, const char *mode) { @@ -438,6 +507,13 @@ int ps2_fputc(int c, FILE *stream) { int ps2_fputs(const char *s, FILE *stream) { int len = strlen(s); + + if (stream == stderr || stream == stdout) { + printf("%s", s); + sioprintf("%s", s); + return len; + } + if (ps2_fwrite(s, 1, len, stream) == (size_t)len) return len; else @@ -468,8 +544,9 @@ int ps2_fflush(FILE *stream) { int ps2_ferror(FILE *stream) { int err = ((Ps2File*)stream)->getErr(); - if (err) + if (err) { printf("ferror -> %d\n", err); + } return err; } diff --git a/backends/platform/ps2/fileio.h b/backends/platform/ps2/fileio.h index e793c29d4b..6838162e06 100644 --- a/backends/platform/ps2/fileio.h +++ b/backends/platform/ps2/fileio.h @@ -62,15 +62,16 @@ private: void cacheReadSync(void); int _fd; + uint32 _mode; uint32 _fileSize; uint32 _filePos; uint32 _cacheSize; uint32 _cachePos; - // uint8 cache[2048]; uint8 *_cache; - int _eof; + bool _eof; + bool _err; int _sema; diff --git a/backends/platform/ps2/irxboot.cpp b/backends/platform/ps2/irxboot.cpp index daa592522a..15cb816c31 100644 --- a/backends/platform/ps2/irxboot.cpp +++ b/backends/platform/ps2/irxboot.cpp @@ -55,15 +55,16 @@ IrxFile irxFiles[] = { { "USB_MASS.IRX", USB | OPTIONAL, MASS_DRIVER, NULL, 0 }, { "PS2MOUSE.IRX", USB | OPTIONAL, MOUSE_DRIVER, NULL, 0 }, { "RPCKBD.IRX", USB | OPTIONAL, KBD_DRIVER, NULL, 0 }, - +#ifndef NO_ADAPTOR { "POWEROFF.IRX", HDD | OPTIONAL | NOT_HOST | DEPENDANCY, HDD_DRIVER, NULL, 0 }, { "PS2DEV9.IRX", HDD | OPTIONAL | NOT_HOST | DEPENDANCY, HDD_DRIVER, NULL, 0 }, { "PS2ATAD.IRX", HDD | OPTIONAL | DEPENDANCY, HDD_DRIVER, NULL, 0 }, { "PS2HDD.IRX", HDD | OPTIONAL | DEPENDANCY, HDD_DRIVER, hddArg, sizeof(hddArg) }, { "PS2FS.IRX", HDD | OPTIONAL | DEPENDANCY, HDD_DRIVER, pfsArg, sizeof(pfsArg) }, - { "PS2IP.IRX", NET | NOT_HOST, NET_DRIVER, NULL, 0 }, - { "PS2SMAP.IRX", NET | NOT_HOST, NET_DRIVER, netArg, sizeof(netArg) }, - { "PS2HOST.IRX", NET | NOT_HOST, NET_DRIVER, NULL, 0 } + { "PS2IP.IRX", NET | OPTIONAL | NOT_HOST | DEPENDANCY, NET_DRIVER, NULL, 0 }, + { "PS2SMAP.IRX", NET | OPTIONAL | NOT_HOST | DEPENDANCY, NET_DRIVER, netArg, sizeof(netArg) }, + { "PS2HOST.IRX", NET | OPTIONAL | NOT_HOST | DEPENDANCY, NET_DRIVER, NULL, 0 } +#endif }; static const int numIrxFiles = sizeof(irxFiles) / sizeof(irxFiles[0]); diff --git a/backends/platform/ps2/ps2input.cpp b/backends/platform/ps2/ps2input.cpp index c320e79eed..964a773f7e 100644 --- a/backends/platform/ps2/ps2input.cpp +++ b/backends/platform/ps2/ps2input.cpp @@ -510,22 +510,22 @@ const Common::KeyCode Ps2Input::_usbToSdlk[0x100] = { }; const Common::KeyCode Ps2Input::_padCodes[16] = { - Common::KEYCODE_1, // Select - Common::KEYCODE_INVALID, // L3 - Common::KEYCODE_INVALID, // R3 - Common::KEYCODE_F5, // Start - Common::KEYCODE_INVALID, // Up - Common::KEYCODE_INVALID, // Right - Common::KEYCODE_INVALID, // Down - Common::KEYCODE_INVALID, // Left - Common::KEYCODE_KP0, // L2 - Common::KEYCODE_INVALID, // R2 - Common::KEYCODE_n, // L1 - Common::KEYCODE_y, // R1 - Common::KEYCODE_ESCAPE, // Triangle - Common::KEYCODE_INVALID, // Circle => Right mouse button - Common::KEYCODE_INVALID, // Cross => Left mouse button - Common::KEYCODE_RETURN // Square + Common::KEYCODE_1, // Select + Common::KEYCODE_INVALID, // L3 + Common::KEYCODE_INVALID, // R3 + Common::KEYCODE_F5, // Start + Common::KEYCODE_INVALID, // Up + Common::KEYCODE_INVALID, // Right + Common::KEYCODE_INVALID, // Down + Common::KEYCODE_INVALID, // Left + Common::KEYCODE_KP0, // L2 + Common::KEYCODE_PERIOD, // R2 + Common::KEYCODE_n, // L1 + Common::KEYCODE_y, // R1 + Common::KEYCODE_ESCAPE, // Triangle + Common::KEYCODE_INVALID, // Circle => Right mouse button + Common::KEYCODE_INVALID, // Cross => Left mouse button + Common::KEYCODE_RETURN // Square }; const Common::KeyCode Ps2Input::_padFlags[16] = { @@ -544,7 +544,7 @@ const Common::KeyCode Ps2Input::_padFlags[16] = { Common::KEYCODE_INVALID, // Triangle Common::KEYCODE_INVALID, // Circle Common::KEYCODE_INVALID, // Cross - Common::KEYCODE_INVALID // Square + Common::KEYCODE_INVALID // Square }; diff --git a/backends/platform/ps2/savefilemgr.cpp b/backends/platform/ps2/savefilemgr.cpp index 1271a43d42..1613863530 100644 --- a/backends/platform/ps2/savefilemgr.cpp +++ b/backends/platform/ps2/savefilemgr.cpp @@ -239,10 +239,10 @@ Common::StringList Ps2SaveFileManager::listSavefiles(const Common::String &patte if (!savePath.exists() || !savePath.isDirectory()) return Common::StringList(); - printf("listSavefiles = %s\n", pattern); + printf("listSavefiles = %s\n", pattern.c_str()); if (_mc) { - strcpy(temp, pattern); + strcpy(temp, pattern.c_str()); // mcSplit(temp, game, ext); game = strdup(strtok(temp, ".")); @@ -255,7 +255,7 @@ Common::StringList Ps2SaveFileManager::listSavefiles(const Common::String &patte } else { _dir = Common::String(savePath.getPath()); - search = Common::String(pattern); + search = pattern; } Common::FSDirectory dir(_dir); diff --git a/backends/platform/ps2/systemps2.cpp b/backends/platform/ps2/systemps2.cpp index f29caf2279..57a03f777d 100644 --- a/backends/platform/ps2/systemps2.cpp +++ b/backends/platform/ps2/systemps2.cpp @@ -66,6 +66,10 @@ #include "icon.h" #include "ps2temp.h" +#ifdef __PS2_DEBUG__ +#include <debug.h> +#endif + // asm("mfc0 %0, $9\n" : "=r"(tickStart)); extern void *_gp; @@ -95,6 +99,11 @@ PS2Device detectBootPath(const char *elfPath, char *bootPath); extern AsyncFio fio; +#ifdef __PS2_DEBUG__ +extern "C" int gdb_stub_main(int argc, char *argv[]); +extern "C" void breakpoint(void); +#endif + extern "C" int scummvm_main(int argc, char *argv[]); extern "C" int main(int argc, char *argv[]) { @@ -117,6 +126,10 @@ extern "C" int main(int argc, char *argv[]) { sioprintf("Result = %d\n", res); } +#ifdef __PS2_DEBUG__ + gdb_stub_main(argc, argv); +#endif + sioprintf("Creating system\n"); g_system = g_systemPs2 = new OSystem_PS2(argv[0]); @@ -241,6 +254,8 @@ OSystem_PS2::OSystem_PS2(const char *elfPath) { _printY = 0; _msgClearTime = 0; _systemQuit = false; + _modeChanged = false; + _screenChangeCount = 0; _screen = new Gs2dScreen(320, 200, TV_DONT_CARE); @@ -327,9 +342,8 @@ OSystem_PS2::OSystem_PS2(const char *elfPath) { void OSystem_PS2::init(void) { sioprintf("Timer...\n"); _scummTimerManager = new DefaultTimerManager(); - _scummEventManager = new DefaultEventManager(); _scummMixer = new Audio::MixerImpl(this); - _scummMixer->setOutputRate(44100); + _scummMixer->setOutputRate(48000); _scummMixer->setReady(true); initTimer(); @@ -520,6 +534,9 @@ void OSystem_PS2::initSize(uint width, uint height) { _oldMouseX = width / 2; _oldMouseY = height / 2; + + _modeChanged = true; + _screenChangeCount++; printf("done\n"); } @@ -574,11 +591,11 @@ void OSystem_PS2::delayMillis(uint msecs) { Common::TimerManager *OSystem_PS2::getTimerManager() { return _scummTimerManager; } - +/* Common::EventManager *OSystem_PS2::getEventManager() { - return _scummEventManager; + return getEventManager(); } - +*/ Audio::Mixer *OSystem_PS2::getMixer() { return _scummMixer; } @@ -661,7 +678,7 @@ int16 OSystem_PS2::getOverlayHeight(void) { return _screen->getOverlayHeight(); } -Graphics::Surface *OSystem_PS2::lockScreen() { +Graphics::Surface *OSystem_PS2::lockScreen(void) { return _screen->lockScreen(); } @@ -669,6 +686,10 @@ void OSystem_PS2::unlockScreen(void) { _screen->unlockScreen(); } +void OSystem_PS2::fillScreen(uint32 col) { + _screen->fillScreen(col); +} + const OSystem::GraphicsMode OSystem_PS2::_graphicsMode = { NULL, NULL, 0 }; const OSystem::GraphicsMode *OSystem_PS2::getSupportedGraphicsModes(void) const { @@ -688,7 +709,16 @@ int OSystem_PS2::getDefaultGraphicsMode(void) const { } bool OSystem_PS2::pollEvent(Common::Event &event) { - bool res = _input->pollEvent(&event); + bool res; + + if (_modeChanged) { + _modeChanged = false; + event.type = Common::EVENT_SCREEN_CHANGED; + return true; + } + + res = _input->pollEvent(&event); + if (res && (event.type == Common::EVENT_MOUSEMOVE)) _screen->setMouseXy(event.mouse.x, event.mouse.y); return res; diff --git a/backends/platform/ps2/systemps2.h b/backends/platform/ps2/systemps2.h index ab27d93574..24cd94f503 100644 --- a/backends/platform/ps2/systemps2.h +++ b/backends/platform/ps2/systemps2.h @@ -27,9 +27,9 @@ #define SYSTEMPS2_H #include "common/system.h" +#include "backends/base-backend.h" class DefaultTimerManager; -class DefaultEventManager; class DefaultSaveFileManager; class Gs2dScreen; @@ -54,7 +54,7 @@ namespace Audio { class MixerImpl; }; -class OSystem_PS2 : public OSystem { +class OSystem_PS2 : public BaseBackend { public: OSystem_PS2(const char *elfPath); virtual ~OSystem_PS2(void); @@ -72,6 +72,7 @@ public: virtual Graphics::Surface *lockScreen(); virtual void unlockScreen(); virtual void updateScreen(); + virtual void fillScreen(uint32); /* TODO : check */ virtual void displayMessageOnOSD(const char *msg) { printf("displayMessageOnOSD: %s\n", msg); }; /* */ @@ -92,7 +93,7 @@ public: virtual uint32 getMillis(); virtual void delayMillis(uint msecs); virtual Common::TimerManager *getTimerManager(); - virtual Common::EventManager *getEventManager(); +// virtual Common::EventManager *getEventManager(); virtual bool pollEvent(Common::Event &event); virtual Audio::Mixer *getMixer(); @@ -112,14 +113,14 @@ public: virtual int getDefaultGraphicsMode() const; virtual bool setGraphicsMode(int mode); virtual int getGraphicsMode() const; + virtual int getScreenChangeID() const { return _screenChangeCount; } virtual void quit(); virtual Common::SeekableReadStream *createConfigReadStream(); virtual Common::WriteStream *createConfigWriteStream(); - virtual Graphics::PixelFormat getOverlayFormat() const; - + virtual Graphics::PixelFormat getOverlayFormat() const; virtual Common::SaveFileManager *getSavefileManager(); virtual FilesystemFactory *getFilesystemFactory(); @@ -149,7 +150,6 @@ private: void readRtcTime(void); DefaultTimerManager *_scummTimerManager; - DefaultEventManager *_scummEventManager; Audio::MixerImpl *_scummMixer; bool _mouseVisible; @@ -163,6 +163,8 @@ private: uint16 _oldMouseX, _oldMouseY; uint32 _msgClearTime; uint16 _printY; + bool _modeChanged; + int _screenChangeCount; int _mutexSema; Ps2Mutex _mutex[MAX_MUTEXES]; @@ -179,4 +181,3 @@ private: }; #endif // SYSTEMPS2_H - diff --git a/backends/platform/symbian/src/SymbianActions.cpp b/backends/platform/symbian/src/SymbianActions.cpp index c45cef32bd..995b03f200 100644 --- a/backends/platform/symbian/src/SymbianActions.cpp +++ b/backends/platform/symbian/src/SymbianActions.cpp @@ -102,8 +102,15 @@ SymbianActions::SymbianActions() } void SymbianActions::initInstanceMain(OSystem *mainSystem) { + int i; + Actions::initInstanceMain(mainSystem); + // Disable all mappings before setting main mappings again + for (i = 0; i < ACTION_LAST; i++) { + _action_enabled[i] = false; + } + // Mouse Up _action_enabled[ACTION_UP] = true; diff --git a/backends/platform/symbian/src/SymbianOS.cpp b/backends/platform/symbian/src/SymbianOS.cpp index 6a8a46df07..7af1cade8c 100644 --- a/backends/platform/symbian/src/SymbianOS.cpp +++ b/backends/platform/symbian/src/SymbianOS.cpp @@ -471,8 +471,16 @@ bool OSystem_SDL_Symbian::remapKey(SDL_Event &ev, Common::Event &event) { void OSystem_SDL_Symbian::setWindowCaption(const char *caption) { OSystem_SDL::setWindowCaption(caption); +} + +void OSystem_SDL_Symbian::engineInit() { + // Check mappings for the engine just started check_mappings(); -FIXME: move check_mappings() call to engineInit() & engineDone() +} + +void OSystem_SDL_Symbian::engineDone() { + // Need to reset engine to basic state after an engine has been running + GUI::Actions::Instance()->initInstanceMain(this); } void OSystem_SDL_Symbian::check_mappings() { diff --git a/backends/platform/symbian/src/SymbianOS.h b/backends/platform/symbian/src/SymbianOS.h index efca94b706..b873b503be 100644 --- a/backends/platform/symbian/src/SymbianOS.h +++ b/backends/platform/symbian/src/SymbianOS.h @@ -107,6 +107,18 @@ protected: void setWindowCaption(const char *caption); + /** + * Allows the backend to perform engine specific init. + * Called just before the engine is run. + */ + virtual void engineInit(); + + /** + * Allows the backend to perform engine specific de-init. + * Called after the engine finishes. + */ + virtual void engineDone(); + // // Used to intialized special game mappings // 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 b8261d029e..8b2e0848f8 100644 --- a/backends/platform/wince/wince-sdl.cpp +++ b/backends/platform/wince/wince-sdl.cpp @@ -908,18 +908,13 @@ int OSystem_WINCE3::getOutputSampleRate() const { return _sampleRate; } -void OSystem_WINCE3::setWindowCaption(const char *caption) { +void OSystem_WINCE3::engineInit() { check_mappings(); // called here to initialize virtual keys handling //update_game_settings(); // finalize mixer init compute_sample_rate(); setupMixer(); - -FIXME: move check_mappings() etc. calls to engineInit() & engineDone() - - // handle the actual event - OSystem_SDL::setWindowCaption(caption); } bool OSystem_WINCE3::openCD(int drive) { @@ -1214,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/backends/platform/wince/wince-sdl.h b/backends/platform/wince/wince-sdl.h index 13f20ecccf..cc2948f93d 100644 --- a/backends/platform/wince/wince-sdl.h +++ b/backends/platform/wince/wince-sdl.h @@ -84,7 +84,7 @@ public: // Overloaded from SDL backend (master volume and sample rate subtleties) void setupMixer(); // Overloaded from OSystem - //void engineInit(); + void engineInit(); void getTimeAndDate(struct tm &t) const; virtual Common::SeekableReadStream *createConfigReadStream(); virtual Common::WriteStream *createConfigWriteStream(); @@ -145,7 +145,6 @@ protected: //int getGraphicsMode() const; int getDefaultGraphicsMode() const; - void setWindowCaption(const char *caption); bool openCD(int drive); int getOutputSampleRate() const; diff --git a/backends/saves/default/default-saves.cpp b/backends/saves/default/default-saves.cpp index 69af78404d..70b9977d8f 100644 --- a/backends/saves/default/default-saves.cpp +++ b/backends/saves/default/default-saves.cpp @@ -55,11 +55,14 @@ void DefaultSaveFileManager::checkPath(const Common::FSNode &dir) { } Common::StringList DefaultSaveFileManager::listSavefiles(const Common::String &pattern) { - Common::FSNode savePath(getSavePath()); - checkPath(savePath); + Common::String savePathName = getSavePath(); + checkPath(Common::FSNode(savePathName)); if (getError() != Common::kNoError) return Common::StringList(); + // recreate FSNode since checkPath may have changed/created the directory + Common::FSNode savePath(savePathName); + Common::FSDirectory dir(savePath); Common::ArchiveMemberList savefiles; Common::StringList results; @@ -76,11 +79,14 @@ Common::StringList DefaultSaveFileManager::listSavefiles(const Common::String &p Common::InSaveFile *DefaultSaveFileManager::openForLoading(const Common::String &filename) { // Ensure that the savepath is valid. If not, generate an appropriate error. - Common::FSNode savePath(getSavePath()); - checkPath(savePath); + Common::String savePathName = getSavePath(); + checkPath(Common::FSNode(savePathName)); if (getError() != Common::kNoError) return 0; + // recreate FSNode since checkPath may have changed/created the directory + Common::FSNode savePath(savePathName); + Common::FSNode file = savePath.getChild(filename); if (!file.exists()) return 0; @@ -93,11 +99,14 @@ Common::InSaveFile *DefaultSaveFileManager::openForLoading(const Common::String Common::OutSaveFile *DefaultSaveFileManager::openForSaving(const Common::String &filename) { // Ensure that the savepath is valid. If not, generate an appropriate error. - Common::FSNode savePath(getSavePath()); - checkPath(savePath); + Common::String savePathName = getSavePath(); + checkPath(Common::FSNode(savePathName)); if (getError() != Common::kNoError) return 0; + // recreate FSNode since checkPath may have changed/created the directory + Common::FSNode savePath(savePathName); + Common::FSNode file = savePath.getChild(filename); // Open the file for saving @@ -107,13 +116,14 @@ Common::OutSaveFile *DefaultSaveFileManager::openForSaving(const Common::String } bool DefaultSaveFileManager::removeSavefile(const Common::String &filename) { - clearError(); - - Common::FSNode savePath(getSavePath()); - checkPath(savePath); + Common::String savePathName = getSavePath(); + checkPath(Common::FSNode(savePathName)); if (getError() != Common::kNoError) return false; + // recreate FSNode since checkPath may have changed/created the directory + Common::FSNode savePath(savePathName); + Common::FSNode file = savePath.getChild(filename); // FIXME: remove does not exist on all systems. If your port fails to |