aboutsummaryrefslogtreecommitdiff
path: root/backends/platform/symbian/src/SymbianOS.cpp
diff options
context:
space:
mode:
authorMax Horn2006-07-06 21:44:48 +0000
committerMax Horn2006-07-06 21:44:48 +0000
commit1d8d9f5510dc5f574e926bd6fadb9d20337daede (patch)
tree5cdcf6c8a233159776be9d90f3f39885222f65eb /backends/platform/symbian/src/SymbianOS.cpp
parent9269ebe9f5a281f452594f1e8108e31c88a398fb (diff)
downloadscummvm-rg350-1d8d9f5510dc5f574e926bd6fadb9d20337daede.tar.gz
scummvm-rg350-1d8d9f5510dc5f574e926bd6fadb9d20337daede.tar.bz2
scummvm-rg350-1d8d9f5510dc5f574e926bd6fadb9d20337daede.zip
Moving remaining platform/backends code, as previously threatened
svn-id: r23380
Diffstat (limited to 'backends/platform/symbian/src/SymbianOS.cpp')
-rw-r--r--backends/platform/symbian/src/SymbianOS.cpp419
1 files changed, 419 insertions, 0 deletions
diff --git a/backends/platform/symbian/src/SymbianOS.cpp b/backends/platform/symbian/src/SymbianOS.cpp
new file mode 100644
index 0000000000..b0b4486418
--- /dev/null
+++ b/backends/platform/symbian/src/SymbianOS.cpp
@@ -0,0 +1,419 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL
+ * Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
+ * Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
+ * Copyright (C) 2005-2006 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$
+ */
+
+#include "backends/symbian/src/SymbianOS.h"
+#include "backends/symbian/src/SymbianActions.h"
+#include "common/config-manager.h"
+#include "gui/Actions.h"
+#include "gui/Key.h"
+#include "gui/message.h"
+
+#include <eikenv.h> // for CEikonEnv::Static() @ Symbian::FatalError()
+#include "ESDL/sdlapp.h" // for CSDLApp::GetExecutablePathCStr() @ Symbian::GetExecutablePath()
+
+////////// extern "C" ///////////////////////////////////////////////////
+
+extern Common::ConfigManager *g_config;
+
+namespace Symbian {
+
+// Show a simple Symbian Info win with Msg & exit
+void FatalError(const char *msg) {
+ TPtrC8 msgPtr((const TUint8 *)msg);
+ TBuf<512> msg16Bit;
+ msg16Bit.Copy(msgPtr);
+ CEikonEnv::Static()->InfoWinL(_L("ScummVM Fatal Error"), msg16Bit);
+
+ if (g_system)
+ g_system->quit();
+}
+
+// make this easily available everywhere
+char* GetExecutablePath()
+{
+ return CSDLApp::GetExecutablePathCStr();
+}
+
+} // namespace Symbian {
+
+////////// OSystem_SDL_Symbian //////////////////////////////////////////
+
+static const OSystem::GraphicsMode s_supportedGraphicsModes[] = {
+ {"1x", "Fullscreen", GFX_NORMAL},
+ {0, 0, 0}
+};
+
+bool OSystem_SDL_Symbian::hasFeature(Feature f) {
+ switch(f) {
+ case kFeatureFullscreenMode:
+ case kFeatureAspectRatioCorrection:
+ case kFeatureAutoComputeDirtyRects:
+ case kFeatureCursorHasPalette:
+#ifdef USE_VIBRA_SE_PXXX
+ case kFeatureVibration:
+#endif
+ return true;
+
+ default:
+ return false;
+ }
+}
+
+OSystem_SDL_Symbian::zoneDesc OSystem_SDL_Symbian::_zones[TOTAL_ZONES] = {
+ { 0, 0, 320, 145 },
+ { 0, 145, 150, 55 },
+ { 150, 145, 170, 55 }
+};
+OSystem_SDL_Symbian::OSystem_SDL_Symbian() :_channels(0),_stereo_mix_buffer(0) {
+}
+
+void OSystem_SDL_Symbian::initBackend() {
+ ConfMan.setBool("FM_high_quality", false);
+#if !defined(S60) || defined(S60V3) // S60 has low quality as default
+ ConfMan.setBool("FM_medium_quality", true);
+#else
+ ConfMan.setBool("FM_medium_quality", false);
+#endif
+ ConfMan.setInt("joystick_num", 0); // Symbian OS should have joystick_num set to 0 in the ini file , but uiq devices might refuse opening the joystick
+ ConfMan.flushToDisk();
+
+ GUI::Actions::init();
+
+ OSystem_SDL::initBackend();
+
+ // Initialize global key mapping for Smartphones
+ GUI::Actions* actions = GUI::Actions::Instance();
+
+ actions->initInstanceMain(this);
+ actions->loadMapping();
+ initZones();
+}
+
+OSystem_SDL_Symbian::~OSystem_SDL_Symbian() {
+ delete []_stereo_mix_buffer;
+}
+
+int OSystem_SDL_Symbian::getDefaultGraphicsMode() const {
+ return GFX_NORMAL;
+}
+
+const OSystem::GraphicsMode *OSystem_SDL_Symbian::getSupportedGraphicsModes() const {
+ return s_supportedGraphicsModes;
+}
+
+// make sure we always go to normal, even if the string might be set wrong!
+bool OSystem_SDL_Symbian::setGraphicsMode(const char * /*name*/) {
+ // let parent OSystem_SDL handle it
+ return OSystem_SDL::setGraphicsMode(getDefaultGraphicsMode());
+}
+
+void OSystem_SDL_Symbian::quitWithErrorMsg(const char *msg) {
+
+ CEikonEnv::Static()->AlertWin(_L("quitWithErrorMsg()")) ;
+
+ if (g_system)
+ g_system->quit();
+}
+
+/*
+ * SumthinWicked says: the stuff below is copied from common/scaler.cpp,
+ * so we can skip compiling the scalers. ESDL still needs 1x and the scaler
+ * architecture because we inherit from OSystem_SDL.
+ */
+int gBitFormat = 565;
+void InitScalers(uint32 /*BitFormat*/) {} // called by OSystem_SDL functions, not relevant for ESDL
+
+/**
+ * Trivial 'scaler' - in fact it doesn't do any scaling but just copies the
+ * source to the destination.
+ */
+void Normal1x(const uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch,
+ int width, int height) {
+ while (height--) {
+ memcpy(dstPtr, srcPtr, 2 * width);
+ srcPtr += srcPitch;
+ dstPtr += dstPitch;
+ }
+}
+
+bool OSystem_SDL_Symbian::setSoundCallback(SoundProc proc, void *param) {
+
+ // First save the proc and param
+ _sound_proc_param = param;
+ _sound_proc = proc;
+ SDL_AudioSpec desired;
+ SDL_AudioSpec obtained;
+
+ memset(&desired, 0, sizeof(desired));
+
+ _samplesPerSec = 0;
+
+ if (ConfMan.hasKey("output_rate"))
+ _samplesPerSec = ConfMan.getInt("output_rate");
+
+ if (_samplesPerSec <= 0)
+ _samplesPerSec = SAMPLES_PER_SEC;
+
+ // Originally, we always used 2048 samples. This loop will produce the
+ // same result at 22050 Hz, and should hopefully produce something
+ // sensible for other frequencies. Note that it must be a power of two.
+
+ uint32 samples = 0x8000;
+
+ for (;;) {
+ if ((1000 * samples) / _samplesPerSec < 100)
+ break;
+ samples >>= 1;
+ }
+
+ desired.freq = _samplesPerSec;
+ desired.format = AUDIO_S16SYS;
+ desired.channels = 2;
+ desired.samples = (uint16)samples;
+#ifdef S60
+ desired.callback = symbianMixCallback;
+ desired.userdata = this;
+#else
+ desired.callback = proc;
+ desired.userdata = param;
+#endif
+ if (SDL_OpenAudio(&desired, &obtained) != 0) {
+ warning("Could not open audio device: %s", SDL_GetError());
+ return false;
+ }
+ // Note: This should be the obtained output rate, but it seems that at
+ // least on some platforms SDL will lie and claim it did get the rate
+ // even if it didn't. Probably only happens for "weird" rates, though.
+ _samplesPerSec = obtained.freq;
+ _channels = obtained.channels;
+
+ // Need to create mixbuffer for stereo mix to downmix
+ if(_channels != 2) {
+ _stereo_mix_buffer = new byte [obtained.size*2];//*2 for stereo values
+ }
+
+ SDL_PauseAudio(0);
+ return true;
+}
+
+/**
+ * The mixer callback function, passed on to OSystem::setSoundCallback().
+ * This simply calls the mix() method.
+ */
+void OSystem_SDL_Symbian::symbianMixCallback(void *s, byte *samples, int len) {
+ static_cast <OSystem_SDL_Symbian*>(s)->symbianMix(samples,len);
+}
+
+
+/**
+ * Actual mixing implementation
+ */
+void OSystem_SDL_Symbian::symbianMix(byte *samples, int len) {
+ // If not stereo then we need to downmix
+ if (_channels != 2) {
+ _sound_proc(_sound_proc_param, _stereo_mix_buffer, len * 2);
+ int16 *bitmixDst = (int16 *)samples;
+ int16 *bitmixSrc = (int16 *)_stereo_mix_buffer;
+
+ for (int loop = len / 2; loop >= 0; loop --) {
+ *bitmixDst = (*bitmixSrc + *(bitmixSrc + 1)) >> 1;
+ bitmixDst++;
+ bitmixSrc += 2;
+ }
+ } else
+ _sound_proc(_sound_proc_param, samples, len);
+}
+
+/**
+ * This is an implementation by the remapKey function
+ * @param SDL_Event to remap
+ * @param ScumVM event to modify if special result is requested
+ * @return true if Event has a valid return status
+ */
+bool OSystem_SDL_Symbian::remapKey(SDL_Event &ev, Event &event) {
+ if (GUI::Actions::Instance()->mappingActive() || ev.key.keysym.sym <= SDLK_UNKNOWN)
+ return false;
+
+ for (TInt loop = 0; loop < GUI::ACTION_LAST; loop++) {
+ if (GUI::Actions::Instance()->getMapping(loop) == ev.key.keysym.sym &&
+ GUI::Actions::Instance()->isEnabled(loop)) {
+ // Create proper event instead
+ switch(loop) {
+ case GUI::ACTION_UP:
+ if (ev.type == SDL_KEYDOWN) {
+ _km.y_vel = -1;
+ _km.y_down_count = 1;
+ } else {
+ _km.y_vel = 0;
+ _km.y_down_count = 0;
+ }
+ event.type = EVENT_MOUSEMOVE;
+ fillMouseEvent(event, _km.x, _km.y);
+
+ return true;
+
+ case GUI::ACTION_DOWN:
+ if(ev.type == SDL_KEYDOWN) {
+ _km.y_vel = 1;
+ _km.y_down_count = 1;
+ } else {
+ _km.y_vel = 0;
+ _km.y_down_count = 0;
+ }
+ event.type = EVENT_MOUSEMOVE;
+ fillMouseEvent(event, _km.x, _km.y);
+
+ return true;
+
+ case GUI::ACTION_LEFT:
+ if(ev.type == SDL_KEYDOWN) {
+ _km.x_vel = -1;
+ _km.x_down_count = 1;
+ } else {
+ _km.x_vel = 0;
+ _km.x_down_count = 0;
+ }
+ event.type = EVENT_MOUSEMOVE;
+ fillMouseEvent(event, _km.x, _km.y);
+
+ return true;
+
+ case GUI::ACTION_RIGHT:
+ if(ev.type == SDL_KEYDOWN) {
+ _km.x_vel = 1;
+ _km.x_down_count = 1;
+ } else {
+ _km.x_vel = 0;
+ _km.x_down_count = 0;
+ }
+ event.type = EVENT_MOUSEMOVE;
+ fillMouseEvent(event, _km.x, _km.y);
+
+ return true;
+
+ case GUI::ACTION_LEFTCLICK:
+ event.type = (ev.type == SDL_KEYDOWN ? EVENT_LBUTTONDOWN : EVENT_LBUTTONUP);
+ fillMouseEvent(event, _km.x, _km.y);
+
+ return true;
+
+ case GUI::ACTION_RIGHTCLICK:
+ event.type = (ev.type == SDL_KEYDOWN ? EVENT_RBUTTONDOWN : EVENT_RBUTTONUP);
+ fillMouseEvent(event, _km.x, _km.y);
+
+ return true;
+
+ case GUI::ACTION_ZONE:
+ if(ev.type == SDL_KEYDOWN) {
+ int i;
+
+ for (i=0; i < TOTAL_ZONES; i++)
+ if (_km.x >= _zones[i].x && _km.y >= _zones[i].y &&
+ _km.x <= _zones[i].x + _zones[i].width && _km.y <= _zones[i].y + _zones[i].height
+ ) {
+ _mouseXZone[i] = _km.x;
+ _mouseYZone[i] = _km.y;
+ break;
+ }
+ _currentZone++;
+ if (_currentZone >= TOTAL_ZONES)
+ _currentZone = 0;
+ event.type = EVENT_MOUSEMOVE;
+ fillMouseEvent(event, _mouseXZone[_currentZone], _mouseYZone[_currentZone]);
+ SDL_WarpMouse(event.mouse.x, event.mouse.y);
+ }
+
+ return true;
+
+ case GUI::ACTION_SAVE:
+ case GUI::ACTION_SKIP:
+ case GUI::ACTION_FT_CHEAT:
+ case GUI::ACTION_SKIP_TEXT:
+ case GUI::ACTION_PAUSE:
+ {
+ GUI::Key &key = GUI::Actions::Instance()->getKeyAction(loop);
+ ev.key.keysym.sym = (SDLKey)key.ascii();
+ ev.key.keysym.scancode= key.keycode();
+ ev.key.keysym.mod = (SDLMod)key.flags();
+
+ return false;
+ }
+
+ case GUI::ACTION_QUIT:
+ {
+ GUI::MessageDialog alert("Do you want to quit ?", "Yes", "No");
+ if (alert.runModal() == GUI::kMessageOK)
+ quit();
+
+ return true;
+ }
+ }
+ }
+ }
+
+ return false;
+}
+
+void OSystem_SDL_Symbian::setWindowCaption(const char *caption) {
+ OSystem_SDL::setWindowCaption(caption);
+ check_mappings();
+}
+
+void OSystem_SDL_Symbian::check_mappings() {
+ if (ConfMan.get("gameid").empty() || GUI::Actions::Instance()->initialized())
+ return;
+
+ GUI::Actions::Instance()->initInstanceGame();
+}
+
+void OSystem_SDL_Symbian::initZones() {
+ int i;
+
+ _currentZone = 0;
+
+ for (i = 0; i < TOTAL_ZONES; i++) {
+ _mouseXZone[i] = (_zones[i].x + (_zones[i].width / 2));
+ _mouseYZone[i] = (_zones[i].y + (_zones[i].height / 2));
+ }
+}
+
+
+/** Vibration support */
+#ifdef USE_VIBRA_SE_PXXX
+void OSystem_SDL_Symbian::initializeVibration() {
+ _vibrationApi = SonyEricsson::CVibration::NewL();
+}
+
+void OSystem_SDL_Symbian::vibrationOn(int vibraLength) {
+ // initialize?
+ if (!_vibrationApi) _vibrationApi = SonyEricsson::CVibration::NewL();
+ // do it!
+ _vibrationApi->VibrationOn(1, 1, vibraLength);
+}
+
+void OSystem_SDL_Symbian::vibrationOff() {
+ _vibrationApi->VibrationOff();
+}
+#endif // USE_SE_PXX_VIBRA
+