synced with scummvm to 2011-Apr-13

This commit is contained in:
Pawel Kolodziejski 2011-04-14 12:41:26 +02:00
parent f0a4299aef
commit 0640dcf2c7
347 changed files with 53648 additions and 8521 deletions

View file

@ -0,0 +1,56 @@
/* Residual - A 3D game interpreter
*
* Residual is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the AUTHORS
* 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 "common/sys.h"
#if defined(__amigaos4__)
#include "backends/platform/sdl/amigaos/amigaos.h"
#include "backends/plugins/sdl/sdl-provider.h"
#include "base/main.h"
int main(int argc, char *argv[]) {
// Create our OSystem instance
g_system = new OSystem_AmigaOS();
assert(g_system);
// Pre initialize the backend
((OSystem_AmigaOS *)g_system)->init();
#ifdef DYNAMIC_MODULES
PluginManager::instance().addPluginProvider(new SDLPluginProvider());
#endif
// Invoke the actual Residual main entry point:
int res = residual_main(argc, argv);
// Free OSystem
delete (OSystem_AmigaOS *)g_system;
return res;
}
#endif

View file

@ -0,0 +1,41 @@
/* Residual - A 3D game interpreter
*
* Residual is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the AUTHORS
* 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 "common/scummsys.h"
#ifdef __amigaos4__
#include "backends/platform/sdl/amigaos/amigaos.h"
#include "backends/fs/amigaos4/amigaos4-fs-factory.h"
void OSystem_AmigaOS::init() {
// Initialze File System Factory
_fsFactory = new AmigaOSFilesystemFactory();
// Invoke parent implementation of this method
OSystem_SDL::init();
}
#endif

View file

@ -0,0 +1,39 @@
/* Residual - A 3D game interpreter
*
* Residual is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the AUTHORS
* 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$
*
*/
#ifndef PLATFORM_SDL_AMIGAOS_H
#define PLATFORM_SDL_AMIGAOS_H
#include "backends/platform/sdl/sdl.h"
class OSystem_AmigaOS : public OSystem_SDL {
public:
OSystem_AmigaOS() {}
virtual ~OSystem_AmigaOS() {}
virtual void init();
};
#endif

View file

@ -1,576 +0,0 @@
/* Residual - A 3D game interpreter
*
* Residual is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the AUTHORS
* 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 "backends/platform/sdl/sdl.h"
#include "common/util.h"
#include "common/events.h"
// FIXME move joystick defines out and replace with confile file options
// we should really allow users to map any key to a joystick button
#define JOY_DEADZONE 3200
#ifndef __SYMBIAN32__ // Symbian wants dialog joystick i.e cursor for movement/selection
#define JOY_ANALOG
#endif
// #define JOY_INVERT_Y
#define JOY_XAXIS 0
#define JOY_YAXIS 1
// buttons
#define JOY_BUT_LMOUSE 0
#define JOY_BUT_RMOUSE 2
#define JOY_BUT_ESCAPE 3
#define JOY_BUT_PERIOD 1
#define JOY_BUT_SPACE 4
#define JOY_BUT_F5 5
static int mapKey(SDLKey key, SDLMod mod, Uint16 unicode) {
if (key >= SDLK_F1 && key <= SDLK_F9) {
return key - SDLK_F1 + Common::ASCII_F1;
} else if (key >= SDLK_KP0 && key <= SDLK_KP9) {
return key - SDLK_KP0 + '0';
} else if (key >= SDLK_UP && key <= SDLK_PAGEDOWN) {
return key;
} else if (unicode) {
return unicode;
} else if (key >= 'a' && key <= 'z' && (mod & KMOD_SHIFT)) {
return key & ~0x20;
} else if (key >= SDLK_NUMLOCK && key <= SDLK_EURO) {
return 0;
}
return key;
}
void OSystem_SDL::fillMouseEvent(Common::Event &event, int x, int y) {
event.mouse.x = x;
event.mouse.y = y;
// Update the "keyboard mouse" coords
_km.x = x;
_km.y = y;
/* Residual doesn't support this
// Adjust for the screen scaling
if (!_overlayVisible) {
event.mouse.x /= _videoMode.scaleFactor;
event.mouse.y /= _videoMode.scaleFactor;
if (_videoMode.aspectRatioCorrection)
event.mouse.y = aspect2Real(event.mouse.y);
}*/
}
void OSystem_SDL::handleKbdMouse() {
uint32 curTime = getMillis();
if (curTime >= _km.last_time + _km.delay_time) {
_km.last_time = curTime;
if (_km.x_down_count == 1) {
_km.x_down_time = curTime;
_km.x_down_count = 2;
}
if (_km.y_down_count == 1) {
_km.y_down_time = curTime;
_km.y_down_count = 2;
}
if (_km.x_vel || _km.y_vel) {
if (_km.x_down_count) {
if (curTime > _km.x_down_time + _km.delay_time * 12) {
if (_km.x_vel > 0)
_km.x_vel++;
else
_km.x_vel--;
} else if (curTime > _km.x_down_time + _km.delay_time * 8) {
if (_km.x_vel > 0)
_km.x_vel = 5;
else
_km.x_vel = -5;
}
}
if (_km.y_down_count) {
if (curTime > _km.y_down_time + _km.delay_time * 12) {
if (_km.y_vel > 0)
_km.y_vel++;
else
_km.y_vel--;
} else if (curTime > _km.y_down_time + _km.delay_time * 8) {
if (_km.y_vel > 0)
_km.y_vel = 5;
else
_km.y_vel = -5;
}
}
_km.x += _km.x_vel;
_km.y += _km.y_vel;
if (_km.x < 0) {
_km.x = 0;
_km.x_vel = -1;
_km.x_down_count = 1;
} else if (_km.x > _km.x_max) {
_km.x = _km.x_max;
_km.x_vel = 1;
_km.x_down_count = 1;
}
if (_km.y < 0) {
_km.y = 0;
_km.y_vel = -1;
_km.y_down_count = 1;
} else if (_km.y > _km.y_max) {
_km.y = _km.y_max;
_km.y_vel = 1;
_km.y_down_count = 1;
}
// Residual: disable wrap mouse for now, it's really annoying
//SDL_WarpMouse((Uint16)_km.x, (Uint16)_km.y);
}
}
}
static void SDLModToOSystemKeyFlags(SDLMod mod, Common::Event &event) {
event.kbd.flags = 0;
#ifdef LINUPY
// Yopy has no ALT key, steal the SHIFT key
// (which isn't used much anyway)
if (mod & KMOD_SHIFT)
event.kbd.flags |= Common::KBD_ALT;
#else
if (mod & KMOD_SHIFT)
event.kbd.flags |= Common::KBD_SHIFT;
if (mod & KMOD_ALT)
event.kbd.flags |= Common::KBD_ALT;
#endif
if (mod & KMOD_CTRL)
event.kbd.flags |= Common::KBD_CTRL;
// Sticky flags
if (mod & KMOD_NUM)
event.kbd.flags |= Common::KBD_NUM;
if (mod & KMOD_CAPS)
event.kbd.flags |= Common::KBD_CAPS;
}
bool OSystem_SDL::pollEvent(Common::Event &event) {
SDL_Event ev;
ev.type = SDL_NOEVENT;
handleKbdMouse();
/* Residual doesn't support this
// If the screen mode changed, send an Common::EVENT_SCREEN_CHANGED
if (_modeChanged) {
_modeChanged = false;
event.type = Common::EVENT_SCREEN_CHANGED;
return true;
}
*/
while (SDL_PollEvent(&ev)) {
preprocessEvents(&ev);
if (dispatchSDLEvent(ev, event))
return true;
}
return false;
}
bool OSystem_SDL::dispatchSDLEvent(SDL_Event &ev, Common::Event &event) {
switch (ev.type) {
case SDL_KEYDOWN:
return handleKeyDown(ev, event);
case SDL_KEYUP:
return handleKeyUp(ev, event);
case SDL_MOUSEMOTION:
return handleMouseMotion(ev, event);
case SDL_MOUSEBUTTONDOWN:
return handleMouseButtonDown(ev, event);
case SDL_MOUSEBUTTONUP:
return handleMouseButtonUp(ev, event);
case SDL_JOYBUTTONDOWN:
return handleJoyButtonDown(ev, event);
case SDL_JOYBUTTONUP:
return handleJoyButtonUp(ev, event);
case SDL_JOYAXISMOTION:
return handleJoyAxisMotion(ev, event);
case SDL_VIDEOEXPOSE:
/* Residual doesn't support this */
//_forceFull = true;
break;
case SDL_QUIT:
event.type = Common::EVENT_QUIT;
return true;
}
return false;
}
bool OSystem_SDL::handleKeyDown(SDL_Event &ev, Common::Event &event) {
SDLModToOSystemKeyFlags(SDL_GetModState(), event);
// Handle scroll lock as a key modifier
if (ev.key.keysym.sym == SDLK_SCROLLOCK)
_scrollLock = !_scrollLock;
if (_scrollLock)
event.kbd.flags |= Common::KBD_SCRL;
// Alt-Return and Alt-Enter toggle full screen mode
/* Residual doesn't support this
if (event.kbd.hasFlags(Common::KBD_ALT) && (ev.key.keysym.sym == SDLK_RETURN || ev.key.keysym.sym == SDLK_KP_ENTER)) {
beginGFXTransaction();
setFullscreenMode(!_videoMode.fullscreen);
endGFXTransaction();
#ifdef USE_OSD
if (_videoMode.fullscreen)
displayMessageOnOSD("Fullscreen mode");
else
displayMessageOnOSD("Windowed mode");
#endif
return false;
}*/
/* // Alt-S: Create a screenshot
if (event.kbd.hasFlags(Common::KBD_ALT) && ev.key.keysym.sym == 's') {
char filename[20];
for (int n = 0;; n++) {
SDL_RWops *file;
sprintf(filename, "residual%05d.bmp", n);
file = SDL_RWFromFile(filename, "r");
if (!file)
break;
SDL_RWclose(file);
}
if (saveScreenshot(filename))
printf("Saved '%s'\n", filename);
else
printf("Could not save screenshot!\n");
return false;
}
*/
// Ctrl-m toggles mouse capture
if (event.kbd.hasFlags(Common::KBD_CTRL) && ev.key.keysym.sym == 'm') {
toggleMouseGrab();
return false;
}
#if defined(MACOSX)
// On Macintosh', Cmd-Q quits
if ((ev.key.keysym.mod & KMOD_META) && ev.key.keysym.sym == 'q') {
event.type = Common::EVENT_QUIT;
return true;
}
#elif defined(UNIX)
// On other unices, Control-Q quits
if ((ev.key.keysym.mod & KMOD_CTRL) && ev.key.keysym.sym == 'q') {
event.type = Common::EVENT_QUIT;
return true;
}
#else
// Ctrl-z and Alt-X quit
if ((event.kbd.hasFlags(Common::KBD_CTRL) && ev.key.keysym.sym == 'z') || (event.kbd.hasFlags(Common::KBD_ALT) && ev.key.keysym.sym == 'x')) {
event.type = Common::EVENT_QUIT;
return true;
}
#endif
if ((ev.key.keysym.mod & KMOD_CTRL) && ev.key.keysym.sym == 'u') {
event.type = Common::EVENT_MUTE;
return true;
}
/* Residual doesn't support this
// Ctrl-Alt-<key> will change the GFX mode
if ((event.kbd.flags & (Common::KBD_CTRL|Common::KBD_ALT)) == (Common::KBD_CTRL|Common::KBD_ALT)) {
if (handleScalerHotkeys(ev.key))
return false;
}*/
if (remapKey(ev, event))
return true;
event.type = Common::EVENT_KEYDOWN;
event.kbd.keycode = (Common::KeyCode)ev.key.keysym.sym;
event.kbd.ascii = mapKey(ev.key.keysym.sym, ev.key.keysym.mod, ev.key.keysym.unicode);
return true;
}
bool OSystem_SDL::handleKeyUp(SDL_Event &ev, Common::Event &event) {
if (remapKey(ev, event))
return true;
event.type = Common::EVENT_KEYUP;
event.kbd.keycode = (Common::KeyCode)ev.key.keysym.sym;
event.kbd.ascii = mapKey(ev.key.keysym.sym, ev.key.keysym.mod, ev.key.keysym.unicode);
// Ctrl-Alt-<key> will change the GFX mode
SDLModToOSystemKeyFlags(SDL_GetModState(), event);
// Set the scroll lock sticky flag
if (_scrollLock)
event.kbd.flags |= Common::KBD_SCRL;
/* Residual doesn't support this
if (isScalerHotkey(event))
// Swallow these key up events
return false;*/
return true;
}
bool OSystem_SDL::handleMouseMotion(SDL_Event &ev, Common::Event &event) {
event.type = Common::EVENT_MOUSEMOVE;
fillMouseEvent(event, ev.motion.x, ev.motion.y);
/* Residual doesn't support this */
//setMousePos(event.mouse.x, event.mouse.y);
return true;
}
bool OSystem_SDL::handleMouseButtonDown(SDL_Event &ev, Common::Event &event) {
if (ev.button.button == SDL_BUTTON_LEFT)
event.type = Common::EVENT_LBUTTONDOWN;
else if (ev.button.button == SDL_BUTTON_RIGHT)
event.type = Common::EVENT_RBUTTONDOWN;
#if defined(SDL_BUTTON_WHEELUP) && defined(SDL_BUTTON_WHEELDOWN)
else if (ev.button.button == SDL_BUTTON_WHEELUP)
event.type = Common::EVENT_WHEELUP;
else if (ev.button.button == SDL_BUTTON_WHEELDOWN)
event.type = Common::EVENT_WHEELDOWN;
#endif
#if defined(SDL_BUTTON_MIDDLE)
else if (ev.button.button == SDL_BUTTON_MIDDLE)
event.type = Common::EVENT_MBUTTONDOWN;
#endif
else
return false;
fillMouseEvent(event, ev.button.x, ev.button.y);
return true;
}
bool OSystem_SDL::handleMouseButtonUp(SDL_Event &ev, Common::Event &event) {
if (ev.button.button == SDL_BUTTON_LEFT)
event.type = Common::EVENT_LBUTTONUP;
else if (ev.button.button == SDL_BUTTON_RIGHT)
event.type = Common::EVENT_RBUTTONUP;
#if defined(SDL_BUTTON_MIDDLE)
else if (ev.button.button == SDL_BUTTON_MIDDLE)
event.type = Common::EVENT_MBUTTONUP;
#endif
else
return false;
fillMouseEvent(event, ev.button.x, ev.button.y);
return true;
}
bool OSystem_SDL::handleJoyButtonDown(SDL_Event &ev, Common::Event &event) {
if (ev.jbutton.button == JOY_BUT_LMOUSE) {
event.type = Common::EVENT_LBUTTONDOWN;
fillMouseEvent(event, _km.x, _km.y);
} else if (ev.jbutton.button == JOY_BUT_RMOUSE) {
event.type = Common::EVENT_RBUTTONDOWN;
fillMouseEvent(event, _km.x, _km.y);
} else {
event.type = Common::EVENT_KEYDOWN;
switch (ev.jbutton.button) {
case JOY_BUT_ESCAPE:
event.kbd.keycode = Common::KEYCODE_ESCAPE;
event.kbd.ascii = mapKey(SDLK_ESCAPE, ev.key.keysym.mod, 0);
break;
case JOY_BUT_PERIOD:
event.kbd.keycode = Common::KEYCODE_PERIOD;
event.kbd.ascii = mapKey(SDLK_PERIOD, ev.key.keysym.mod, 0);
break;
case JOY_BUT_SPACE:
event.kbd.keycode = Common::KEYCODE_SPACE;
event.kbd.ascii = mapKey(SDLK_SPACE, ev.key.keysym.mod, 0);
break;
case JOY_BUT_F5:
event.kbd.keycode = Common::KEYCODE_F5;
event.kbd.ascii = mapKey(SDLK_F5, ev.key.keysym.mod, 0);
break;
}
}
return true;
}
bool OSystem_SDL::handleJoyButtonUp(SDL_Event &ev, Common::Event &event) {
if (ev.jbutton.button == JOY_BUT_LMOUSE) {
event.type = Common::EVENT_LBUTTONUP;
fillMouseEvent(event, _km.x, _km.y);
} else if (ev.jbutton.button == JOY_BUT_RMOUSE) {
event.type = Common::EVENT_RBUTTONUP;
fillMouseEvent(event, _km.x, _km.y);
} else {
event.type = Common::EVENT_KEYUP;
switch (ev.jbutton.button) {
case JOY_BUT_ESCAPE:
event.kbd.keycode = Common::KEYCODE_ESCAPE;
event.kbd.ascii = mapKey(SDLK_ESCAPE, ev.key.keysym.mod, 0);
break;
case JOY_BUT_PERIOD:
event.kbd.keycode = Common::KEYCODE_PERIOD;
event.kbd.ascii = mapKey(SDLK_PERIOD, ev.key.keysym.mod, 0);
break;
case JOY_BUT_SPACE:
event.kbd.keycode = Common::KEYCODE_SPACE;
event.kbd.ascii = mapKey(SDLK_SPACE, ev.key.keysym.mod, 0);
break;
case JOY_BUT_F5:
event.kbd.keycode = Common::KEYCODE_F5;
event.kbd.ascii = mapKey(SDLK_F5, ev.key.keysym.mod, 0);
break;
}
}
return true;
}
bool OSystem_SDL::handleJoyAxisMotion(SDL_Event &ev, Common::Event &event) {
int axis = ev.jaxis.value;
if ( axis > JOY_DEADZONE) {
axis -= JOY_DEADZONE;
event.type = Common::EVENT_MOUSEMOVE;
} else if ( axis < -JOY_DEADZONE ) {
axis += JOY_DEADZONE;
event.type = Common::EVENT_MOUSEMOVE;
} else
axis = 0;
if ( ev.jaxis.axis == JOY_XAXIS) {
#ifdef JOY_ANALOG
_km.x_vel = axis/2000;
_km.x_down_count = 0;
#else
if (axis != 0) {
_km.x_vel = (axis > 0) ? 1:-1;
_km.x_down_count = 1;
} else {
_km.x_vel = 0;
_km.x_down_count = 0;
}
#endif
} else if (ev.jaxis.axis == JOY_YAXIS) {
#ifndef JOY_INVERT_Y
axis = -axis;
#endif
#ifdef JOY_ANALOG
_km.y_vel = -axis / 2000;
_km.y_down_count = 0;
#else
if (axis != 0) {
_km.y_vel = (-axis > 0) ? 1: -1;
_km.y_down_count = 1;
} else {
_km.y_vel = 0;
_km.y_down_count = 0;
}
#endif
}
fillMouseEvent(event, _km.x, _km.y);
return true;
}
bool OSystem_SDL::remapKey(SDL_Event &ev, Common::Event &event) {
#ifdef LINUPY
// On Yopy map the End button to quit
if ((ev.key.keysym.sym == 293)) {
event.type = Common::EVENT_QUIT;
return true;
}
// Map menu key to f5 (scumm menu)
if (ev.key.keysym.sym == 306) {
event.type = Common::EVENT_KEYDOWN;
event.kbd.keycode = Common::KEYCODE_F5;
event.kbd.ascii = mapKey(SDLK_F5, ev.key.keysym.mod, 0);
return true;
}
// Map action key to action
if (ev.key.keysym.sym == 291) {
event.type = Common::EVENT_KEYDOWN;
event.kbd.keycode = Common::KEYCODE_TAB;
event.kbd.ascii = mapKey(SDLK_TAB, ev.key.keysym.mod, 0);
return true;
}
// Map OK key to skip cinematic
if (ev.key.keysym.sym == 292) {
event.type = Common::EVENT_KEYDOWN;
event.kbd.keycode = Common::KEYCODE_ESCAPE;
event.kbd.ascii = mapKey(SDLK_ESCAPE, ev.key.keysym.mod, 0);
return true;
}
#endif
#ifdef QTOPIA
// Quit on fn+backspace on zaurus
if (ev.key.keysym.sym == 127) {
event.type = Common::EVENT_QUIT;
return true;
}
// Map menu key (f11) to f5 (scumm menu)
if (ev.key.keysym.sym == SDLK_F11) {
event.type = Common::EVENT_KEYDOWN;
event.kbd.keycode = Common::KEYCODE_F5;
event.kbd.ascii = mapKey(SDLK_F5, ev.key.keysym.mod, 0);
}
// Nap center (space) to tab (default action )
// I wanted to map the calendar button but the calendar comes up
//
else if (ev.key.keysym.sym == SDLK_SPACE) {
event.type = Common::EVENT_KEYDOWN;
event.kbd.keycode = Common::KEYCODE_TAB;
event.kbd.ascii = mapKey(SDLK_TAB, ev.key.keysym.mod, 0);
}
// Since we stole space (pause) above we'll rebind it to the tab key on the keyboard
else if (ev.key.keysym.sym == SDLK_TAB) {
event.type = Common::EVENT_KEYDOWN;
event.kbd.keycode = Common::KEYCODE_SPACE;
event.kbd.ascii = mapKey(SDLK_SPACE, ev.key.keysym.mod, 0);
} else {
// Let the events fall through if we didn't change them, this may not be the best way to
// set it up, but i'm not sure how sdl would like it if we let if fall through then redid it though.
// and yes i have an huge terminal size so i dont wrap soon enough.
event.type = Common::EVENT_KEYDOWN;
event.kbd.keycode = ev.key.keysym.sym;
event.kbd.ascii = mapKey(ev.key.keysym.sym, ev.key.keysym.mod, ev.key.keysym.unicode);
}
#endif
return false;
}

View file

@ -1,516 +0,0 @@
/* Residual - A 3D game interpreter
*
* Residual is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the AUTHORS
* 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 "backends/platform/sdl/sdl.h"
#include "common/mutex.h"
#include "common/translation.h"
#include "common/util.h"
#ifdef USE_RGB_COLOR
#include "common/list.h"
#endif
#include "graphics/font.h"
#include "graphics/fontman.h"
#include "graphics/scaler.h"
#include "graphics/surface.h"
void OSystem_SDL::launcherInitSize(uint w, uint h) {
closeOverlay();
setupScreen(w, h, false, false);
}
byte *OSystem_SDL::setupScreen(int screenW, int screenH, bool fullscreen, bool accel3d) {
uint32 sdlflags;
int bpp;
closeOverlay();
#ifdef USE_OPENGL
_opengl = accel3d;
#endif
_fullscreen = fullscreen;
#ifdef USE_OPENGL
if (_opengl) {
SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
sdlflags = SDL_OPENGL;
bpp = 24;
} else
#endif
{
bpp = 16;
sdlflags = SDL_HWSURFACE;
}
if (_fullscreen)
sdlflags |= SDL_FULLSCREEN;
_screen = SDL_SetVideoMode(screenW, screenH, bpp, sdlflags);
#ifdef USE_OPENGL
if (!_screen && _opengl) {
warning("Couldn't create 32-bit visual, trying 16-bit");
SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5);
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 5);
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5);
SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 1);
_screen = SDL_SetVideoMode(screenW, screenH, 0, sdlflags);
}
#endif
if (!_screen)
error("Could not initialize video: %s", SDL_GetError());
#ifdef USE_OPENGL
if (_opengl) {
int glflag;
// apply atribute again for sure based on SDL docs
SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
SDL_GL_GetAttribute(SDL_GL_RED_SIZE, &glflag);
warning("INFO: GL RED bits: %d", glflag);
SDL_GL_GetAttribute(SDL_GL_GREEN_SIZE, &glflag);
warning("INFO: GL GREEN bits: %d", glflag);
SDL_GL_GetAttribute(SDL_GL_BLUE_SIZE, &glflag);
warning("INFO: GL BLUE bits: %d", glflag);
SDL_GL_GetAttribute(SDL_GL_ALPHA_SIZE, &glflag);
warning("INFO: GL APLHA bits: %d", glflag);
SDL_GL_GetAttribute(SDL_GL_DEPTH_SIZE, &glflag);
warning("INFO: GL Z buffer depth bits: %d", glflag);
SDL_GL_GetAttribute(SDL_GL_DOUBLEBUFFER, &glflag);
warning("INFO: GL Double Buffer: %d", glflag);
SDL_GL_GetAttribute(SDL_GL_STENCIL_SIZE, &glflag);
warning("INFO: GL Stencil buffer bits: %d", glflag);
}
#endif
_overlayWidth = screenW;
_overlayHeight = screenH;
#ifdef USE_OPENGL
if (_opengl) {
uint32 rmask, gmask, bmask, amask;
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
rmask = 0x00001f00;
gmask = 0x000007e0;
bmask = 0x000000f8;
amask = 0x00000000;
#else
rmask = 0x0000f800;
gmask = 0x000007e0;
bmask = 0x0000001f;
amask = 0x00000000;
#endif
_overlayscreen = SDL_CreateRGBSurface(SDL_SWSURFACE, _overlayWidth, _overlayHeight, 16,
rmask, gmask, bmask, amask);
} else
#endif
{
_overlayscreen = SDL_CreateRGBSurface(SDL_SWSURFACE, _overlayWidth, _overlayHeight, 16,
_screen->format->Rmask, _screen->format->Gmask, _screen->format->Bmask, _screen->format->Amask);
}
if (!_overlayscreen)
error("allocating _overlayscreen failed");
_overlayFormat.bytesPerPixel = _overlayscreen->format->BytesPerPixel;
_overlayFormat.rLoss = _overlayscreen->format->Rloss;
_overlayFormat.gLoss = _overlayscreen->format->Gloss;
_overlayFormat.bLoss = _overlayscreen->format->Bloss;
_overlayFormat.aLoss = _overlayscreen->format->Aloss;
_overlayFormat.rShift = _overlayscreen->format->Rshift;
_overlayFormat.gShift = _overlayscreen->format->Gshift;
_overlayFormat.bShift = _overlayscreen->format->Bshift;
_overlayFormat.aShift = _overlayscreen->format->Ashift;
return (byte *)_screen->pixels;
}
#define BITMAP_TEXTURE_SIZE 256
void OSystem_SDL::updateScreen() {
#ifdef USE_OPENGL
if (_opengl) {
if (_overlayVisible) {
if (_overlayDirty) {
// remove if already exist
if (_overlayNumTex > 0) {
glDeleteTextures(_overlayNumTex, _overlayTexIds);
delete[] _overlayTexIds;
_overlayNumTex = 0;
}
_overlayNumTex = ((_overlayWidth + (BITMAP_TEXTURE_SIZE - 1)) / BITMAP_TEXTURE_SIZE) *
((_overlayHeight + (BITMAP_TEXTURE_SIZE - 1)) / BITMAP_TEXTURE_SIZE);
_overlayTexIds = new GLuint[_overlayNumTex];
glGenTextures(_overlayNumTex, _overlayTexIds);
for (int i = 0; i < _overlayNumTex; i++) {
glBindTexture(GL_TEXTURE_2D, _overlayTexIds[i]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, BITMAP_TEXTURE_SIZE, BITMAP_TEXTURE_SIZE, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, NULL);
}
glPixelStorei(GL_UNPACK_ALIGNMENT, 2);
glPixelStorei(GL_UNPACK_ROW_LENGTH, _overlayWidth);
int curTexIdx = 0;
for (int y = 0; y < _overlayHeight; y += BITMAP_TEXTURE_SIZE) {
for (int x = 0; x < _overlayWidth; x += BITMAP_TEXTURE_SIZE) {
int t_width = (x + BITMAP_TEXTURE_SIZE >= _overlayWidth) ? (_overlayWidth - x) : BITMAP_TEXTURE_SIZE;
int t_height = (y + BITMAP_TEXTURE_SIZE >= _overlayHeight) ? (_overlayHeight - y) : BITMAP_TEXTURE_SIZE;
glBindTexture(GL_TEXTURE_2D, _overlayTexIds[curTexIdx]);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, t_width, t_height, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, (byte *)_overlayscreen->pixels + (y * 2 * _overlayWidth) + (2 * x));
curTexIdx++;
}
}
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
}
// prepare view
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, _overlayWidth, _overlayHeight, 0, 0, 1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glMatrixMode(GL_TEXTURE);
glLoadIdentity();
glDisable(GL_LIGHTING);
glEnable(GL_TEXTURE_2D);
glDisable(GL_DEPTH_TEST);
glDepthMask(GL_FALSE);
glEnable(GL_SCISSOR_TEST);
glScissor(0, 0, _overlayWidth, _overlayHeight);
int curTexIdx = 0;
for (int y = 0; y < _overlayHeight; y += BITMAP_TEXTURE_SIZE) {
for (int x = 0; x < _overlayWidth; x += BITMAP_TEXTURE_SIZE) {
glBindTexture(GL_TEXTURE_2D, _overlayTexIds[curTexIdx]);
glBegin(GL_QUADS);
glTexCoord2f(0, 0);
glVertex2i(x, y);
glTexCoord2f(1.0f, 0.0f);
glVertex2i(x + BITMAP_TEXTURE_SIZE, y);
glTexCoord2f(1.0f, 1.0f);
glVertex2i(x + BITMAP_TEXTURE_SIZE, y + BITMAP_TEXTURE_SIZE);
glTexCoord2f(0.0f, 1.0f);
glVertex2i(x, y + BITMAP_TEXTURE_SIZE);
glEnd();
curTexIdx++;
}
}
glDisable(GL_SCISSOR_TEST);
glDisable(GL_TEXTURE_2D);
glDepthMask(GL_TRUE);
glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHTING);
}
SDL_GL_SwapBuffers();
} else
#endif
{
if (_overlayVisible) {
SDL_LockSurface(_screen);
SDL_LockSurface(_overlayscreen);
byte *src = (byte *)_overlayscreen->pixels;
byte *buf = (byte *)_screen->pixels;
int h = _overlayHeight;
do {
memcpy(buf, src, _overlayWidth * _overlayscreen->format->BytesPerPixel);
src += _overlayscreen->pitch;
buf += _screen->pitch;
} while (--h);
SDL_UnlockSurface(_screen);
SDL_UnlockSurface(_overlayscreen);
}
SDL_Flip(_screen);
}
}
int16 OSystem_SDL::getHeight() {
return _screen->h;
}
int16 OSystem_SDL::getWidth() {
return _screen->w;
}
#pragma mark -
#pragma mark --- Overlays ---
#pragma mark -
void OSystem_SDL::showOverlay() {
if (_overlayVisible)
return;
_overlayVisible = true;
clearOverlay();
}
void OSystem_SDL::hideOverlay() {
if (!_overlayVisible)
return;
_overlayVisible = false;
clearOverlay();
}
void OSystem_SDL::clearOverlay() {
if (!_overlayVisible)
return;
#ifdef USE_OPENGL
if (_opengl) {
SDL_LockSurface(_overlayscreen);
glReadPixels(0, 0, _overlayWidth, _overlayWidth, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, _overlayscreen->pixels);
SDL_UnlockSurface(_overlayscreen);
} else
#endif
{
SDL_LockSurface(_screen);
SDL_LockSurface(_overlayscreen);
byte *src = (byte *)_screen->pixels;
byte *buf = (byte *)_overlayscreen->pixels;
int h = _overlayHeight;
do {
memcpy(buf, src, _overlayWidth * _overlayscreen->format->BytesPerPixel);
src += _screen->pitch;
buf += _overlayscreen->pitch;
} while (--h);
SDL_UnlockSurface(_screen);
SDL_UnlockSurface(_overlayscreen);
}
_overlayDirty = true;
}
void OSystem_SDL::grabOverlay(OverlayColor *buf, int pitch) {
if (_overlayscreen == NULL)
return;
if (SDL_LockSurface(_overlayscreen) == -1)
error("SDL_LockSurface failed: %s", SDL_GetError());
byte *src = (byte *)_overlayscreen->pixels;
int h = _overlayHeight;
do {
memcpy(buf, src, _overlayWidth * _overlayscreen->format->BytesPerPixel);
src += _overlayscreen->pitch;
buf += pitch;
} while (--h);
SDL_UnlockSurface(_overlayscreen);
}
void OSystem_SDL::copyRectToOverlay(const OverlayColor *buf, int pitch, int x, int y, int w, int h) {
if (_overlayscreen == NULL)
return;
// Clip the coordinates
if (x < 0) {
w += x;
buf -= x;
x = 0;
}
if (y < 0) {
h += y;
buf -= y * pitch;
y = 0;
}
if (w > _overlayWidth - x) {
w = _overlayWidth - x;
}
if (h > _overlayHeight - y) {
h = _overlayHeight - y;
}
if (w <= 0 || h <= 0)
return;
if (SDL_LockSurface(_overlayscreen) == -1)
error("SDL_LockSurface failed: %s", SDL_GetError());
byte *dst = (byte *)_overlayscreen->pixels + y * _overlayscreen->pitch + x * _overlayscreen->format->BytesPerPixel;
do {
memcpy(dst, buf, w * _overlayscreen->format->BytesPerPixel);
dst += _overlayscreen->pitch;
buf += pitch;
} while (--h);
SDL_UnlockSurface(_overlayscreen);
}
#pragma mark -
#pragma mark --- Mouse ---
#pragma mark -
bool OSystem_SDL::showMouse(bool visible) {
return false;
}
void OSystem_SDL::closeOverlay() {
if (_overlayscreen) {
SDL_FreeSurface(_overlayscreen);
_overlayscreen = NULL;
#ifdef USE_OPENGL
if (_overlayNumTex > 0) {
glDeleteTextures(_overlayNumTex, _overlayTexIds);
delete[] _overlayTexIds;
_overlayNumTex = 0;
}
#endif
}
}
void OSystem_SDL::warpMouse(int x, int y) {
SDL_WarpMouse(x, y);
/* Residual doesn't support this
int y1 = y;
// Don't change mouse position, when mouse is outside of our window (in case of windowed mode)
if (!(SDL_GetAppState( ) & SDL_APPMOUSEFOCUS))
return;
if (_videoMode.aspectRatioCorrection && !_overlayVisible)
y1 = real2Aspect(y);
if (_mouseCurState.x != x || _mouseCurState.y != y) {
if (!_overlayVisible)
SDL_WarpMouse(x * _videoMode.scaleFactor, y1 * _videoMode.scaleFactor);
else
SDL_WarpMouse(x, y1);
// SDL_WarpMouse() generates a mouse movement event, so
// setMousePos() would be called eventually. However, the
// cannon script in CoMI calls this function twice each time
// the cannon is reloaded. Unless we update the mouse position
// immediately the second call is ignored, causing the cannon
// to change its aim.
setMousePos(x, y);
}*/
}
void OSystem_SDL::setMouseCursor(const byte *buf, uint w, uint h, int hotspot_x, int hotspot_y, uint32 keycolor, int cursorTargetScale, const Graphics::PixelFormat *format) {
#ifdef USE_RGB_COLOR
if (!format)
_cursorFormat = Graphics::PixelFormat::createFormatCLUT8();
else if (format->bytesPerPixel <= _screenFormat.bytesPerPixel)
_cursorFormat = *format;
if (_cursorFormat.bytesPerPixel < 4)
assert(keycolor < (uint)(1 << (_cursorFormat.bytesPerPixel << 3)));
#else
assert(keycolor <= 0xFF);
#endif
if (w == 0 || h == 0)
return;
/* Residual doesn't support this
_mouseCurState.hotX = hotspot_x;
_mouseCurState.hotY = hotspot_y;
_mouseKeyColor = keycolor;
_cursorTargetScale = cursorTargetScale;
_mouseTextureId = new GLuint[1];
glGenTextures(1, _mouseTextureId);
glBindTexture(GL_TEXTURE_2D, _overlayTexIds[i]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, BITMAP_TEXTURE_SIZE, BITMAP_TEXTURE_SIZE, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, NULL);
glPixelStorei(GL_UNPACK_ALIGNMENT, 2);
glPixelStorei(GL_UNPACK_ROW_LENGTH, _overlayWidth);
glBindTexture(GL_TEXTURE_2D, _overlayTexIds[curTexIdx]);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, _mouseWidth, _mouseHeight, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, (byte *)buf + (y * 2 * _mouseWidth) + (2 * x));
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
if (_mouseCurState.w != (int)w || _mouseCurState.h != (int)h) {
_mouseCurState.w = w;
_mouseCurState.h = h;
if (_mouseOrigSurface)
SDL_FreeSurface(_mouseOrigSurface);
_mouseOrigSurface = SDL_CreateRGBSurface(SDL_SWSURFACE | SDL_RLEACCEL | SDL_SRCCOLORKEY | SDL_SRCALPHA,
_mouseCurState.w,
_mouseCurState.h,
16,
_hwscreen->format->Rmask,
_hwscreen->format->Gmask,
_hwscreen->format->Bmask,
_hwscreen->format->Amask);
if (_mouseOrigSurface == NULL)
error("allocating _mouseOrigSurface failed");
SDL_SetColorKey(_mouseOrigSurface, SDL_RLEACCEL | SDL_SRCCOLORKEY | SDL_SRCALPHA, kMouseColorKey);
}
free(_mouseData);
#ifdef USE_RGB_COLOR
_mouseData = (byte *)malloc(w * h * _cursorFormat.bytesPerPixel);
memcpy(_mouseData, buf, w * h * _cursorFormat.bytesPerPixel);
#else
_mouseData = (byte *)malloc(w * h);
memcpy(_mouseData, buf, w * h);
#endif
blitCursor();*/
}
void OSystem_SDL::toggleMouseGrab() {
if (SDL_WM_GrabInput(SDL_GRAB_QUERY) == SDL_GRAB_OFF)
SDL_WM_GrabInput(SDL_GRAB_ON);
else
SDL_WM_GrabInput(SDL_GRAB_OFF);
}

View file

@ -0,0 +1,56 @@
/* Residual - A 3D game interpreter
*
* Residual is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the AUTHORS
* 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 "common/scummsys.h"
#ifdef MACOSX
#include "backends/platform/sdl/macosx/macosx.h"
#include "backends/plugins/sdl/sdl-provider.h"
#include "base/main.h"
int main(int argc, char *argv[]) {
// Create our OSystem instance
g_system = new OSystem_MacOSX();
assert(g_system);
// Pre initialize the backend
((OSystem_MacOSX *)g_system)->init();
#ifdef DYNAMIC_MODULES
PluginManager::instance().addPluginProvider(new SDLPluginProvider());
#endif
// Invoke the actual Residual main entry point:
int res = residual_main(argc, argv);
// Free OSystem
delete (OSystem_MacOSX *)g_system;
return res;
}
#endif

View file

@ -0,0 +1,81 @@
/* Residual - A 3D game interpreter
*
* Residual is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the AUTHORS
* 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$
*
*/
// Disable symbol overrides so that we can use system headers.
#define FORBIDDEN_SYMBOL_ALLOW_ALL
#include "common/scummsys.h"
#ifdef MACOSX
#include "backends/platform/sdl/macosx/macosx.h"
#include "backends/mixer/doublebuffersdl/doublebuffersdl-mixer.h"
#include "common/archive.h"
#include "common/fs.h"
#include "CoreFoundation/CoreFoundation.h"
OSystem_MacOSX::OSystem_MacOSX()
:
OSystem_POSIX("Library/Preferences/Residual Preferences") {
}
void OSystem_MacOSX::initBackend() {
// Create the mixer manager
if (_mixer == 0) {
_mixerManager = new DoubleBufferSDLMixerManager();
// Setup and start mixer
_mixerManager->init();
}
// Invoke parent implementation of this method
OSystem_POSIX::initBackend();
}
void OSystem_MacOSX::addSysArchivesToSearchSet(Common::SearchSet &s, int priority) {
// Invoke parent implementation of this method
OSystem_POSIX::addSysArchivesToSearchSet(s, 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 OSystem_MacOSX::setupIcon() {
// Don't set icon on OS X, as we use a nicer external icon there.
}
#endif

View file

@ -0,0 +1,40 @@
/* Residual - A 3D game interpreter
*
* Residual is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the AUTHORS
* 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$
*
*/
#ifndef PLATFORM_SDL_MACOSX_H
#define PLATFORM_SDL_MACOSX_H
#include "backends/platform/sdl/posix/posix.h"
class OSystem_MacOSX : public OSystem_POSIX {
public:
OSystem_MacOSX();
virtual void initBackend();
virtual void addSysArchivesToSearchSet(Common::SearchSet &s, int priority = 0);
virtual void setupIcon();
};
#endif

View file

@ -23,47 +23,44 @@
*
*/
// Fix for bug #2895217 "MSVC compilation broken with r47595":
// We need to keep this on top of the "common/scummsys.h" include,
// otherwise we will get errors about the windows headers redefining
// "ARRAYSIZE" for example.
#if defined(WIN32) && !defined(__SYMBIAN32__)
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
// winnt.h defines ARRAYSIZE, but we want our own one...
#undef ARRAYSIZE
#endif
#include "common/sys.h"
// Several SDL based ports use a custom main, and hence do not want to compile
// of this file. The following "#if" ensures that.
#if !defined(__MAEMO__) && !defined(_WIN32_WCE) && !defined(CAANOO) && !defined(GP2XWIZ) && !defined(LINUXMOTO) && !defined(OPENPANDORA) && !defined(__SYMBIAN32__) && !defined(DINGUX)
#if !defined(UNIX) && \
!defined(WIN32) && \
!defined(__MAEMO__) && \
!defined(__SYMBIAN32__) && \
!defined(_WIN32_WCE) && \
!defined(__amigaos4__) && \
!defined(DINGUX) && \
!defined(CAANOO) && \
!defined(LINUXMOTO) && \
!defined(OPENPANDORA)
#include "backends/platform/sdl/sdl.h"
#include "backends/plugins/sdl/sdl-provider.h"
#include "base/main.h"
#ifdef WIN32
int __stdcall WinMain(HINSTANCE /*hInst*/, HINSTANCE /*hPrevInst*/, LPSTR /*lpCmdLine*/, int /*iShowCmd*/) {
SDL_SetModuleHandle(GetModuleHandle(NULL));
return main(__argc, __argv);
}
#endif
int main(int argc, char *argv[]) {
// Create our OSystem instance
g_system = new OSystem_SDL();
assert(g_system);
// Pre initialize the backend
((OSystem_SDL *)g_system)->init();
#ifdef DYNAMIC_MODULES
PluginManager::instance().addPluginProvider(new SDLPluginProvider());
#endif
// Invoke the actual Residual main entry point:
int res = residual_main(argc, argv);
// Free OSystem
delete (OSystem_SDL *)g_system;
return res;
}

View file

@ -1,12 +1,34 @@
MODULE := backends/platform/sdl
MODULE_OBJS := \
events.o \
graphics.o \
hardwarekeys.o \
main.o \
sdl.o
ifdef UNIX
MODULE_OBJS += \
posix/posix-main.o \
posix/posix.o
endif
ifdef MACOSX
MODULE_OBJS += \
macosx/macosx-main.o \
macosx/macosx.o
endif
ifdef WIN32
MODULE_OBJS += \
win32/win32-main.o \
win32/win32.o
endif
ifdef AMIGAOS
MODULE_OBJS += \
amigaos/amigaos-main.o \
amigaos/amigaos.o
endif
# We don't use rules.mk but rather manually update OBJS and MODULE_DIRS.
MODULE_OBJS := $(addprefix $(MODULE)/, $(MODULE_OBJS))
OBJS := $(MODULE_OBJS) $(OBJS)

View file

@ -0,0 +1,56 @@
/* Residual - A 3D game interpreter
*
* Residual is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the AUTHORS
* 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 "common/scummsys.h"
#if defined(UNIX) && !defined(MACOSX) && !defined(SAMSUNGTV) && !defined(WEBOS) && !defined(LINUXMOTO) && !defined(GPH_DEVICE) && !defined(GP2X) && !defined(DINGUX) && !defined(OPENPANDORA)
#include "backends/platform/sdl/posix/posix.h"
#include "backends/plugins/sdl/sdl-provider.h"
#include "base/main.h"
int main(int argc, char *argv[]) {
// Create our OSystem instance
g_system = new OSystem_POSIX();
assert(g_system);
// Pre initialize the backend
((OSystem_POSIX *)g_system)->init();
#ifdef DYNAMIC_MODULES
PluginManager::instance().addPluginProvider(new SDLPluginProvider());
#endif
// Invoke the actual Residual main entry point:
int res = residual_main(argc, argv);
// Free OSystem
delete (OSystem_POSIX *)g_system;
return res;
}
#endif

View file

@ -0,0 +1,129 @@
/* Residual - A 3D game interpreter
*
* Residual is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the AUTHORS
* 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 "common/scummsys.h"
#ifdef UNIX
#include "backends/platform/sdl/posix/posix.h"
#include "backends/saves/posix/posix-saves.h"
#include "backends/fs/posix/posix-fs-factory.h"
#include <errno.h>
#include <sys/stat.h>
OSystem_POSIX::OSystem_POSIX(Common::String baseConfigName)
:
_baseConfigName(baseConfigName) {
}
void OSystem_POSIX::init() {
// Initialze File System Factory
_fsFactory = new POSIXFilesystemFactory();
// Invoke parent implementation of this method
OSystem_SDL::init();
}
void OSystem_POSIX::initBackend() {
// Create the savefile manager
if (_savefileManager == 0)
_savefileManager = new POSIXSaveFileManager();
// Invoke parent implementation of this method
OSystem_SDL::initBackend();
}
Common::String OSystem_POSIX::getDefaultConfigFileName() {
char configFile[MAXPATHLEN];
// On UNIX type systems, by default we store the config file inside
// to the HOME directory of the user.
const char *home = getenv("HOME");
if (home != NULL && strlen(home) < MAXPATHLEN)
snprintf(configFile, MAXPATHLEN, "%s/%s", home, _baseConfigName.c_str());
else
strcpy(configFile, _baseConfigName.c_str());
return configFile;
}
Common::WriteStream *OSystem_POSIX::createLogFile() {
const char *home = getenv("HOME");
if (home == NULL)
return 0;
Common::String logFile(home);
#ifdef MACOSX
logFile += "/Library";
#else
logFile += "/.residual";
#endif
struct stat sb;
// Check whether the dir exists
if (stat(logFile.c_str(), &sb) == -1) {
// The dir does not exist, or stat failed for some other reason.
if (errno != ENOENT)
return 0;
// If the problem was that the path pointed to nothing, try
// to create the dir.
if (mkdir(logFile.c_str(), 0755) != 0)
return 0;
} else if (!S_ISDIR(sb.st_mode)) {
// Path is no directory. Oops
return 0;
}
#ifdef MACOSX
logFile += "/Logs";
#else
logFile += "/logs";
#endif
// Check whether the dir exists
if (stat(logFile.c_str(), &sb) == -1) {
// The dir does not exist, or stat failed for some other reason.
if (errno != ENOENT)
return 0;
// If the problem was that the path pointed to nothing, try
// to create the dir.
if (mkdir(logFile.c_str(), 0755) != 0)
return 0;
} else if (!S_ISDIR(sb.st_mode)) {
// Path is no directory. Oops
return 0;
}
logFile += "/residual.log";
Common::FSNode file(logFile);
return file.createWriteStream();
}
#endif

View file

@ -0,0 +1,50 @@
/* Residual - A 3D game interpreter
*
* Residual is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the AUTHORS
* 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$
*
*/
#ifndef PLATFORM_SDL_POSIX_H
#define PLATFORM_SDL_POSIX_H
#include "backends/platform/sdl/sdl.h"
class OSystem_POSIX : public OSystem_SDL {
public:
// Let the subclasses be able to change _baseConfigName in the constructor
OSystem_POSIX(Common::String baseConfigName = ".residualrc");
virtual ~OSystem_POSIX() {}
virtual void init();
virtual void initBackend();
protected:
// Base string for creating the default path and filename
// for the configuration file
Common::String _baseConfigName;
virtual Common::String getDefaultConfigFileName();
virtual Common::WriteStream *createLogFile();
};
#endif

View file

@ -0,0 +1,57 @@
/* Residual - A 3D game interpreter
*
* Residual is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the AUTHORS
* 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$
*
*/
#ifndef BACKEND_SDL_SYS_H
#define BACKEND_SDL_SYS_H
// The purpose of this header is to include the SDL headers in a uniform
// fashion, even on the Symbian port.
// Moreover, it contains a workaround for the fact that SDL_rwops.h uses
// a FILE pointer in one place, which conflicts with common/forbidden.h.
#include "common/sys.h"
// Remove FILE override from common/forbidden.h, and replace
// it with an alternate slightly less unfriendly override.
#if !defined(FORBIDDEN_SYMBOL_ALLOW_ALL) && !defined(FORBIDDEN_SYMBOL_EXCEPTION_FILE)
#undef FILE
typedef struct { int FAKE; } FAKE_FILE;
#define FILE FAKE_FILE
#endif
#if defined(__SYMBIAN32__)
#include <esdl\SDL.h>
#else
#include <SDL.h>
#endif
// Finally forbid FILE again (if it was forbidden to start with)
#if !defined(FORBIDDEN_SYMBOL_ALLOW_ALL) && !defined(FORBIDDEN_SYMBOL_EXCEPTION_FILE)
#undef FILE
#define FILE FORBIDDEN_SYMBOL_REPLACEMENT
#endif
#endif

View file

@ -23,234 +23,166 @@
*
*/
#if defined(WIN32)
#ifdef WIN32
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
// winnt.h defines ARRAYSIZE, but we want our own one... - this is needed before including util.h
#undef ARRAYSIZE
#undef ARRAYSIZE // winnt.h defines ARRAYSIZE, but we want our own one...
#endif
#include "backends/platform/sdl/sdl.h"
#include "common/archive.h"
#include "common/config-manager.h"
#include "common/debug.h"
#include "common/EventRecorder.h"
#include "common/util.h"
#ifdef UNIX
#include "backends/saves/posix/posix-saves.h"
#else
#include "backends/saves/default/default-saves.h"
#endif
#include "backends/timer/default/default-timer.h"
#include "sound/mixer_intern.h"
#include "backends/saves/default/default-saves.h"
#include "backends/audiocd/sdl/sdl-audiocd.h"
#include "backends/events/sdl/sdl-events.h"
#include "backends/mutex/sdl/sdl-mutex.h"
#include "backends/timer/sdl/sdl-timer.h"
#include "backends/graphics/sdl/sdl-graphics.h"
#include "icons/residual.xpm"
#include <time.h> // for getTimeAndDate()
//#define SAMPLES_PER_SEC 11025
#define SAMPLES_PER_SEC 22050
//#define SAMPLES_PER_SEC 44100
/*
* Include header files needed for the getFilesystemFactory() method.
*/
#if defined(__amigaos4__)
#include "backends/fs/amigaos4/amigaos4-fs-factory.h"
#elif defined(UNIX)
#include "backends/fs/posix/posix-fs-factory.h"
#elif defined(WIN32)
#include "backends/fs/windows/windows-fs-factory.h"
#ifdef USE_DETECTLANG
#ifndef WIN32
#include <locale.h>
#endif // !WIN32
#endif
OSystem_SDL::OSystem_SDL()
:
_inited(false),
_initedSDL(false),
_logger(0),
_mixerManager(0),
_eventSource(0) {
#if defined(UNIX)
#ifdef MACOSX
#define DEFAULT_CONFIG_FILE "Library/Preferences/Residual Preferences"
#elif defined(SAMSUNGTV)
#define DEFAULT_CONFIG_FILE "/dtv/usb/sda1/.residualrc"
#else
#define DEFAULT_CONFIG_FILE ".residualrc"
#endif
#else
#define DEFAULT_CONFIG_FILE "residual.ini"
#endif
}
#if defined(MACOSX) || defined(IPHONE)
#include "CoreFoundation/CoreFoundation.h"
#endif
OSystem_SDL::~OSystem_SDL() {
SDL_ShowCursor(SDL_ENABLE);
// Delete the various managers here. Note that the ModularBackend
// destructor would also take care of this for us. However, various
// of our managers must be deleted *before* we call SDL_Quit().
// Hence, we perform the destruction on our own.
delete _savefileManager;
_savefileManager = 0;
delete _graphicsManager;
_graphicsManager = 0;
delete _eventManager;
_eventManager = 0;
delete _eventSource;
_eventSource = 0;
delete _audiocdManager;
_audiocdManager = 0;
delete _mixerManager;
_mixerManager = 0;
delete _timerManager;
_timerManager = 0;
delete _mutexManager;
_mutexManager = 0;
delete _logger;
_logger = 0;
SDL_Quit();
}
void OSystem_SDL::init() {
// Initialize SDL
initSDL();
if (!_logger)
_logger = new Backends::Log::Log(this);
if (_logger) {
Common::WriteStream *logFile = createLogFile();
if (logFile)
_logger->open(logFile);
}
static Uint32 timer_handler(Uint32 interval, void *param) {
((DefaultTimerManager *)param)->handler();
return interval;
// Creates the early needed managers, if they don't exist yet
// (we check for this to allow subclasses to provide their own).
if (_mutexManager == 0)
_mutexManager = new SdlMutexManager();
if (_timerManager == 0)
_timerManager = new SdlTimerManager();
}
void OSystem_SDL::initBackend() {
// Check if backend has not been initialized
assert(!_inited);
int joystick_num = ConfMan.getInt("joystick_num");
uint32 sdlFlags = SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER;
// Create the default event source, in case a custom backend
// manager didn't provide one yet.
if (_eventSource == 0)
_eventSource = new SdlEventSource();
if (ConfMan.hasKey("disable_sdl_parachute"))
sdlFlags |= SDL_INIT_NOPARACHUTE;
int graphicsManagerType = 0;
#ifdef _WIN32_WCE
if (ConfMan.hasKey("use_GDI") && ConfMan.getBool("use_GDI")) {
SDL_VideoInit("windib", 0);
sdlFlags ^= SDL_INIT_VIDEO;
}
#endif
if (joystick_num > -1)
sdlFlags |= SDL_INIT_JOYSTICK;
if (SDL_Init(sdlFlags) == -1) {
error("Could not initialize SDL: %s", SDL_GetError());
if (_graphicsManager == 0) {
if (_graphicsManager == 0) {
_graphicsManager = new SdlGraphicsManager(_eventSource);
graphicsManagerType = 0;
}
}
// disabled for now in Residual
//SDL_ShowCursor(SDL_DISABLE);
// Creates the backend managers, if they don't exist yet (we check
// for this to allow subclasses to provide their own).
if (_eventManager == 0)
_eventManager = new DefaultEventManager(_eventSource);
// Enable unicode support if possible
SDL_EnableUNICODE(1);
// We have to initialize the graphics manager before the event manager
// so the virtual keyboard can be initialized, but we have to add the
// graphics manager as an event observer after initializing the event
// manager.
if (graphicsManagerType == 0)
((SdlGraphicsManager *)_graphicsManager)->initEventObserver();
#if !defined(MACOSX) && !defined(__SYMBIAN32__)
if (_savefileManager == 0)
_savefileManager = new DefaultSaveFileManager();
if (_mixerManager == 0) {
_mixerManager = new SdlMixerManager();
// Setup and start mixer
_mixerManager->init();
}
if (_audiocdManager == 0)
_audiocdManager = new SdlAudioCDManager();
// Setup a custom program icon.
// Don't set icon on OS X, as we use a nicer external icon there.
// Don't for Symbian: it uses the EScummVM.aif file for the icon.
setupIcon();
#endif
// enable joystick
if (joystick_num > -1 && SDL_NumJoysticks() > 0) {
printf("Using joystick: %s\n", SDL_JoystickName(0));
_joystick = SDL_JoystickOpen(joystick_num);
}
// Create the savefile manager, if none exists yet (we check for this to
// allow subclasses to provide their own).
if (_savefile == 0) {
#ifdef UNIX
_savefile = new POSIXSaveFileManager();
#else
_savefile = new DefaultSaveFileManager();
#endif
}
// Create and hook up the mixer, if none exists yet (we check for this to
// allow subclasses to provide their own).
if (_mixer == 0) {
setupMixer();
}
// Create and hook up the timer manager, if none exists yet (we check for
// this to allow subclasses to provide their own).
if (_timer == 0) {
// Note: We could implement a custom SDLTimerManager by using
// SDL_AddTimer. That might yield better timer resolution, but it would
// also change the semantics of a timer: Right now, ScummVM timers
// *never* run in parallel, due to the way they are implemented. If we
// switched to SDL_AddTimer, each timer might run in a separate thread.
// However, not all our code is prepared for that, so we can't just
// switch. Still, it's a potential future change to keep in mind.
_timer = new DefaultTimerManager();
_timerID = SDL_AddTimer(10, &timer_handler, _timer);
}
// Invoke parent implementation of this method
OSystem::initBackend();
_inited = true;
}
OSystem_SDL::OSystem_SDL()
:
_screen(0),
_overlayVisible(false),
_overlayscreen(0),
_overlayWidth(0), _overlayHeight(0),
_overlayDirty(true), _overlayNumTex(0),
#ifdef USE_OPENGL
_overlayTexIds(0),
void OSystem_SDL::initSDL() {
// Check if SDL has not been initialized
if (!_initedSDL) {
uint32 sdlFlags = 0;
if (ConfMan.hasKey("disable_sdl_parachute"))
sdlFlags |= SDL_INIT_NOPARACHUTE;
#ifdef WEBOS
// WebOS needs this flag or otherwise the application won't start
sdlFlags |= SDL_INIT_VIDEO;
#endif
_cdrom(0),
_joystick(0),
#if MIXER_DOUBLE_BUFFERING
_soundMutex(0), _soundCond(0), _soundThread(0),
_soundThreadIsRunning(false), _soundThreadShouldQuit(false),
#endif
_fsFactory(0),
_savefile(0),
_mixer(0),
_timer(0) {
// Initialize SDL (SDL Subsystems are initiliazed in the corresponding sdl managers)
if (SDL_Init(sdlFlags) == -1)
error("Could not initialize SDL: %s", SDL_GetError());
// reset mouse state
memset(&_km, 0, sizeof(_km));
// Enable unicode support if possible
SDL_EnableUNICODE(1);
_inited = false;
#if defined(__amigaos4__)
_fsFactory = new AmigaOSFilesystemFactory();
#elif defined(UNIX)
_fsFactory = new POSIXFilesystemFactory();
#elif defined(WIN32)
_fsFactory = new WindowsFilesystemFactory();
#elif defined(__SYMBIAN32__)
// Do nothing since its handled by the Symbian SDL inheritance
#else
#error Unknown and unsupported FS backend
#endif
}
OSystem_SDL::~OSystem_SDL() {
SDL_RemoveTimer(_timerID);
closeMixer();
closeOverlay();
delete _savefile;
delete _timer;
}
uint32 OSystem_SDL::getMillis() {
uint32 millis = SDL_GetTicks();
g_eventRec.processMillis(millis);
return millis;
}
void OSystem_SDL::delayMillis(uint msecs) {
SDL_Delay(msecs);
}
void OSystem_SDL::getTimeAndDate(TimeDate &td) const {
time_t curTime = time(0);
struct tm t = *localtime(&curTime);
td.tm_sec = t.tm_sec;
td.tm_min = t.tm_min;
td.tm_hour = t.tm_hour;
td.tm_mday = t.tm_mday;
td.tm_mon = t.tm_mon;
td.tm_year = t.tm_year;
}
Common::TimerManager *OSystem_SDL::getTimerManager() {
assert(_timer);
return _timer;
}
Common::SaveFileManager *OSystem_SDL::getSavefileManager() {
assert(_savefile);
return _savefile;
}
FilesystemFactory *OSystem_SDL::getFilesystemFactory() {
assert(_fsFactory);
return _fsFactory;
_initedSDL = true;
}
}
void OSystem_SDL::addSysArchivesToSearchSet(Common::SearchSet &s, int priority) {
@ -264,88 +196,10 @@ void OSystem_SDL::addSysArchivesToSearchSet(Common::SearchSet &s, int priority)
}
#endif
#ifdef MACOSX
// 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);
}
#endif
}
static Common::String getDefaultConfigFileName() {
char configFile[MAXPATHLEN];
#if defined (WIN32) && !defined(_WIN32_WCE) && !defined(__SYMBIAN32__)
OSVERSIONINFO win32OsVersion;
ZeroMemory(&win32OsVersion, sizeof(OSVERSIONINFO));
win32OsVersion.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
GetVersionEx(&win32OsVersion);
// Check for non-9X version of Windows.
if (win32OsVersion.dwPlatformId != VER_PLATFORM_WIN32_WINDOWS) {
// Use the Application Data directory of the user profile.
if (win32OsVersion.dwMajorVersion >= 5) {
if (!GetEnvironmentVariable("APPDATA", configFile, sizeof(configFile)))
error("Unable to access application data directory");
} else {
if (!GetEnvironmentVariable("USERPROFILE", configFile, sizeof(configFile)))
error("Unable to access user profile directory");
strcat(configFile, "\\Application Data");
CreateDirectory(configFile, NULL);
}
strcat(configFile, "\\Residual");
CreateDirectory(configFile, NULL);
strcat(configFile, "\\" DEFAULT_CONFIG_FILE);
FILE *tmp = NULL;
if ((tmp = fopen(configFile, "r")) == NULL) {
// Check windows directory
char oldConfigFile[MAXPATHLEN];
GetWindowsDirectory(oldConfigFile, MAXPATHLEN);
strcat(oldConfigFile, "\\" DEFAULT_CONFIG_FILE);
if ((tmp = fopen(oldConfigFile, "r"))) {
strcpy(configFile, oldConfigFile);
fclose(tmp);
}
} else {
fclose(tmp);
}
} else {
// Check windows directory
GetWindowsDirectory(configFile, MAXPATHLEN);
strcat(configFile, "\\" DEFAULT_CONFIG_FILE);
}
#elif defined(UNIX)
// On UNIX type systems, by default we store the config file inside
// to the HOME directory of the user.
//
// GP2X is Linux based but Home dir can be read only so do not use
// it and put the config in the executable dir.
//
// On the iPhone, the home dir of the user when you launch the app
// from the Springboard, is /. Which we don't want.
const char *home = getenv("HOME");
if (home != NULL && strlen(home) < MAXPATHLEN)
snprintf(configFile, MAXPATHLEN, "%s/%s", home, DEFAULT_CONFIG_FILE);
else
strcpy(configFile, DEFAULT_CONFIG_FILE);
#else
strcpy(configFile, DEFAULT_CONFIG_FILE);
#endif
return configFile;
Common::String OSystem_SDL::getDefaultConfigFileName() {
return "residual.ini";
}
Common::SeekableReadStream *OSystem_SDL::createConfigReadStream() {
@ -376,81 +230,102 @@ void OSystem_SDL::setWindowCaption(const char *caption) {
SDL_WM_SetCaption(cap.c_str(), cap.c_str());
}
bool OSystem_SDL::hasFeature(Feature f) {
return
#ifdef USE_OPENGL
(f == kFeatureOpenGL);
#else
false;
#endif
}
void OSystem_SDL::setFeatureState(Feature f, bool enable) {
switch (f) {
case kFeatureFullscreenMode:
//setFullscreenMode(enable);
break;
/* case kFeatureAspectRatioCorrection:
//setAspectRatioCorrection(enable);
break;
case kFeatureAutoComputeDirtyRects:
if (enable)
_modeFlags |= DF_WANT_RECT_OPTIM;
else
_modeFlags &= ~DF_WANT_RECT_OPTIM;
break;
case kFeatureIconifyWindow:
if (enable)
SDL_WM_IconifyWindow();*/
break;
default:
break;
}
}
bool OSystem_SDL::getFeatureState(Feature f) {
switch (f) {
case kFeatureFullscreenMode:
return _fullscreen;
/* case kFeatureAspectRatioCorrection:
return _videoMode.aspectRatioCorrection;
case kFeatureAutoComputeDirtyRects:
return _modeFlags & DF_WANT_RECT_OPTIM;*/
default:
return false;
}
}
void OSystem_SDL::deinit() {
if (_cdrom) {
SDL_CDStop(_cdrom);
SDL_CDClose(_cdrom);
}
if (_joystick)
SDL_JoystickClose(_joystick);
SDL_ShowCursor(SDL_ENABLE);
SDL_RemoveTimer(_timerID);
closeMixer();
delete _timer;
SDL_Quit();
// Event Manager requires save manager for storing
// recorded events
delete getEventManager();
delete _savefile;
}
void OSystem_SDL::quit() {
deinit();
#if !defined(SAMSUNGTV)
delete this;
exit(0);
}
void OSystem_SDL::fatalError() {
delete this;
exit(1);
}
void OSystem_SDL::logMessage(LogMessageType::Type type, const char *message) {
ModularBackend::logMessage(type, message);
if (_logger)
_logger->print(message);
#if defined( USE_WINDBG )
#if defined( _WIN32_WCE )
TCHAR buf_unicode[1024];
MultiByteToWideChar(CP_ACP, 0, message, strlen(message) + 1, buf_unicode, sizeof(buf_unicode));
OutputDebugString(buf_unicode);
if (type == LogMessageType::kError) {
#ifndef DEBUG
drawError(message);
#else
int cmon_break_into_the_debugger_if_you_please = *(int *)(message + 1); // bus error
printf("%d", cmon_break_into_the_debugger_if_you_please); // don't optimize the int out
#endif
}
#else
OutputDebugString(message);
#endif
#endif
}
Common::String OSystem_SDL::getSystemLanguage() const {
#ifdef USE_DETECTLANG
#ifdef WIN32
// We can not use "setlocale" (at least not for MSVC builds), since it
// will return locales like: "English_USA.1252", thus we need a special
// way to determine the locale string for Win32.
char langName[9];
char ctryName[9];
const LCID languageIdentifier = GetThreadLocale();
// GetLocalInfo is only supported starting from Windows 2000, according to this:
// http://msdn.microsoft.com/en-us/library/dd318101%28VS.85%29.aspx
// On the other hand the locale constants used, seem to exist on Windows 98 too,
// check this for that: http://msdn.microsoft.com/en-us/library/dd464799%28v=VS.85%29.aspx
//
// I am not exactly sure what is the truth now, it might be very well that this breaks
// support for systems older than Windows 2000....
//
// TODO: Check whether this (or ScummVM at all ;-) works on a system with Windows 98 for
// example and if it does not and we still want Windows 9x support, we should definitly
// think of another solution.
if (GetLocaleInfo(languageIdentifier, LOCALE_SISO639LANGNAME, langName, sizeof(langName)) != 0 &&
GetLocaleInfo(languageIdentifier, LOCALE_SISO3166CTRYNAME, ctryName, sizeof(ctryName)) != 0) {
Common::String localeName = langName;
localeName += "_";
localeName += ctryName;
return localeName;
} else {
return ModularBackend::getSystemLanguage();
}
#else // WIN32
// Activating current locale settings
const char *locale = setlocale(LC_ALL, "");
// Detect the language from the locale
if (!locale) {
return ModularBackend::getSystemLanguage();
} else {
int length = 0;
// Strip out additional information, like
// ".UTF-8" or the like. We do this, since
// our translation languages are usually
// specified without any charset information.
for (int i = 0; locale[i]; ++i, ++length) {
// TODO: Check whether "@" should really be checked
// here.
if (locale[i] == '.' || locale[i] == ' ' || locale[i] == '@')
break;
}
return Common::String(locale, length);
}
#endif // WIN32
#else // USE_DETECTLANG
return ModularBackend::getSystemLanguage();
#endif // USE_DETECTLANG
}
void OSystem_SDL::setupIcon() {
@ -505,289 +380,34 @@ void OSystem_SDL::setupIcon() {
free(icon);
}
OSystem::MutexRef OSystem_SDL::createMutex() {
return (MutexRef) SDL_CreateMutex();
uint32 OSystem_SDL::getMillis() {
uint32 millis = SDL_GetTicks();
g_eventRec.processMillis(millis);
return millis;
}
void OSystem_SDL::lockMutex(MutexRef mutex) {
SDL_mutexP((SDL_mutex *) mutex);
void OSystem_SDL::delayMillis(uint msecs) {
SDL_Delay(msecs);
}
void OSystem_SDL::unlockMutex(MutexRef mutex) {
SDL_mutexV((SDL_mutex *) mutex);
}
void OSystem_SDL::deleteMutex(MutexRef mutex) {
SDL_DestroyMutex((SDL_mutex *) mutex);
}
#pragma mark -
#pragma mark --- Audio ---
#pragma mark -
#if MIXER_DOUBLE_BUFFERING
void OSystem_SDL::mixerProducerThread() {
byte nextSoundBuffer;
SDL_LockMutex(_soundMutex);
while (true) {
// Wait till we are allowed to produce data
SDL_CondWait(_soundCond, _soundMutex);
if (_soundThreadShouldQuit)
break;
// Generate samples and put them into the next buffer
nextSoundBuffer = _activeSoundBuf ^ 1;
_mixer->mixCallback(_soundBuffers[nextSoundBuffer], _soundBufSize);
// Swap buffers
_activeSoundBuf = nextSoundBuffer;
}
SDL_UnlockMutex(_soundMutex);
}
int SDLCALL OSystem_SDL::mixerProducerThreadEntry(void *arg) {
OSystem_SDL *this_ = (OSystem_SDL *)arg;
assert(this_);
this_->mixerProducerThread();
return 0;
}
void OSystem_SDL::initThreadedMixer(Audio::MixerImpl *mixer, uint bufSize) {
_soundThreadIsRunning = false;
_soundThreadShouldQuit = false;
// Create mutex and condition variable
_soundMutex = SDL_CreateMutex();
_soundCond = SDL_CreateCond();
// Create two sound buffers
_activeSoundBuf = 0;
_soundBufSize = bufSize;
_soundBuffers[0] = (byte *)calloc(1, bufSize);
_soundBuffers[1] = (byte *)calloc(1, bufSize);
_soundThreadIsRunning = true;
// Finally start the thread
_soundThread = SDL_CreateThread(mixerProducerThreadEntry, this);
}
void OSystem_SDL::deinitThreadedMixer() {
// Kill thread?? _soundThread
if (_soundThreadIsRunning) {
// Signal the producer thread to end, and wait for it to actually finish.
_soundThreadShouldQuit = true;
SDL_CondBroadcast(_soundCond);
SDL_WaitThread(_soundThread, NULL);
// Kill the mutex & cond variables.
// Attention: AT this point, the mixer callback must not be running
// anymore, else we will crash!
SDL_DestroyMutex(_soundMutex);
SDL_DestroyCond(_soundCond);
_soundThreadIsRunning = false;
free(_soundBuffers[0]);
free(_soundBuffers[1]);
}
}
void OSystem_SDL::mixCallback(void *arg, byte *samples, int len) {
OSystem_SDL *this_ = (OSystem_SDL *)arg;
assert(this_);
assert(this_->_mixer);
assert((int)this_->_soundBufSize == len);
// Lock mutex, to ensure our data is not overwritten by the producer thread
SDL_LockMutex(this_->_soundMutex);
// Copy data from the current sound buffer
memcpy(samples, this_->_soundBuffers[this_->_activeSoundBuf], len);
// Unlock mutex and wake up the produced thread
SDL_UnlockMutex(this_->_soundMutex);
SDL_CondSignal(this_->_soundCond);
}
#else
void OSystem_SDL::mixCallback(void *sys, byte *samples, int len) {
OSystem_SDL *this_ = (OSystem_SDL *)sys;
assert(this_);
assert(this_->_mixer);
this_->_mixer->mixCallback(samples, len);
}
#endif
void OSystem_SDL::setupMixer() {
SDL_AudioSpec desired;
// Determine the desired output sampling frequency.
uint32 samplesPerSec = 0;
if (ConfMan.hasKey("output_rate"))
samplesPerSec = ConfMan.getInt("output_rate");
if (samplesPerSec <= 0)
samplesPerSec = SAMPLES_PER_SEC;
// Determine the sample buffer size. We want it to store enough data for
// at least 1/16th of a second (though at most 8192 samples). Note
// that it must be a power of two. So e.g. at 22050 Hz, we request a
// sample buffer size of 2048.
uint32 samples = 8192;
while (samples * 16 > samplesPerSec * 2)
samples >>= 1;
memset(&desired, 0, sizeof(desired));
desired.freq = samplesPerSec;
desired.format = AUDIO_S16SYS;
desired.channels = 2;
desired.samples = (uint16)samples;
desired.callback = mixCallback;
desired.userdata = this;
assert(!_mixer);
if (SDL_OpenAudio(&desired, &_obtainedRate) != 0) {
warning("Could not open audio device: %s", SDL_GetError());
_mixer = new Audio::MixerImpl(this, samplesPerSec);
assert(_mixer);
_mixer->setReady(false);
} else {
// 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 = _obtainedRate.freq;
debug(1, "Output sample rate: %d Hz", samplesPerSec);
// Create the mixer instance and start the sound processing
_mixer = new Audio::MixerImpl(this, samplesPerSec);
assert(_mixer);
_mixer->setReady(true);
#if MIXER_DOUBLE_BUFFERING
initThreadedMixer(_mixer, _obtainedRate.samples * 4);
#endif
// start the sound system
SDL_PauseAudio(0);
}
}
void OSystem_SDL::closeMixer() {
if (_mixer)
_mixer->setReady(false);
SDL_CloseAudio();
delete _mixer;
_mixer = 0;
#if MIXER_DOUBLE_BUFFERING
deinitThreadedMixer();
#endif
void OSystem_SDL::getTimeAndDate(TimeDate &td) const {
time_t curTime = time(0);
struct tm t = *localtime(&curTime);
td.tm_sec = t.tm_sec;
td.tm_min = t.tm_min;
td.tm_hour = t.tm_hour;
td.tm_mday = t.tm_mday;
td.tm_mon = t.tm_mon;
td.tm_year = t.tm_year;
}
Audio::Mixer *OSystem_SDL::getMixer() {
assert(_mixer);
return _mixer;
assert(_mixerManager);
return _mixerManager->getMixer();
}
#pragma mark -
#pragma mark --- CD Audio ---
#pragma mark -
bool OSystem_SDL::openCD(int drive) {
if (SDL_InitSubSystem(SDL_INIT_CDROM) == -1)
_cdrom = NULL;
else {
_cdrom = SDL_CDOpen(drive);
// Did it open? Check if _cdrom is NULL
if (!_cdrom) {
warning("Couldn't open drive: %s", SDL_GetError());
} else {
_cdNumLoops = 0;
_cdStopTime = 0;
_cdEndTime = 0;
}
}
return (_cdrom != NULL);
SdlMixerManager *OSystem_SDL::getMixerManager() {
assert(_mixerManager);
return _mixerManager;
}
void OSystem_SDL::stopCD() { /* Stop CD Audio in 1/10th of a second */
_cdStopTime = SDL_GetTicks() + 100;
_cdNumLoops = 0;
}
void OSystem_SDL::playCD(int track, int num_loops, int start_frame, int duration) {
if (!num_loops && !start_frame)
return;
if (!_cdrom)
return;
if (duration > 0)
duration += 5;
_cdTrack = track;
_cdNumLoops = num_loops;
_cdStartFrame = start_frame;
SDL_CDStatus(_cdrom);
if (start_frame == 0 && duration == 0)
SDL_CDPlayTracks(_cdrom, track, 0, 1, 0);
else
SDL_CDPlayTracks(_cdrom, track, start_frame, 0, duration);
_cdDuration = duration;
_cdStopTime = 0;
_cdEndTime = SDL_GetTicks() + _cdrom->track[track].length * 1000 / CD_FPS;
}
bool OSystem_SDL::pollCD() {
if (!_cdrom)
return false;
return (_cdNumLoops != 0 && (SDL_GetTicks() < _cdEndTime || SDL_CDStatus(_cdrom) == CD_PLAYING));
}
void OSystem_SDL::updateCD() {
if (!_cdrom)
return;
if (_cdStopTime != 0 && SDL_GetTicks() >= _cdStopTime) {
SDL_CDStop(_cdrom);
_cdNumLoops = 0;
_cdStopTime = 0;
return;
}
if (_cdNumLoops == 0 || SDL_GetTicks() < _cdEndTime)
return;
if (_cdNumLoops != 1 && SDL_CDStatus(_cdrom) != CD_STOPPED) {
// Wait another second for it to be done
_cdEndTime += 1000;
return;
}
if (_cdNumLoops > 0)
_cdNumLoops--;
if (_cdNumLoops != 0) {
if (_cdStartFrame == 0 && _cdDuration == 0)
SDL_CDPlayTracks(_cdrom, _cdTrack, 0, 1, 0);
else
SDL_CDPlayTracks(_cdrom, _cdTrack, _cdStartFrame, 0, _cdDuration);
_cdEndTime = SDL_GetTicks() + _cdrom->track[_cdTrack].length * 1000 / CD_FPS;
}
}

View file

@ -23,239 +23,101 @@
*
*/
#ifndef SDL_COMMON_H
#define SDL_COMMON_H
#ifndef PLATFORM_SDL_H
#define PLATFORM_SDL_H
#if defined(__SYMBIAN32__)
#include <esdl\SDL.h>
#else
#include <SDL.h>
#include "backends/platform/sdl/sdl-sys.h"
#ifdef USE_OPENGL
#include <SDL_opengl.h>
#endif
#endif
#include "backends/base-backend.h"
#include "graphics/scaler.h"
#include "backends/modular-backend.h"
#include "backends/mixer/sdl/sdl-mixer.h"
#include "backends/events/sdl/sdl-events.h"
#include "backends/log/log.h"
namespace Audio {
class MixerImpl;
}
#if defined(MACOSX)
// On Mac OS X, we need to double buffer the audio buffer, else anything
// which produces sampled data with high latency (like the MT-32 emulator)
// will sound terribly.
// This could be enabled for more / most ports in the future, but needs some
// testing.
#define MIXER_DOUBLE_BUFFERING 1
#endif
class OSystem_SDL : public BaseBackend {
/**
* Base OSystem class for all SDL ports.
*/
class OSystem_SDL : public ModularBackend {
public:
OSystem_SDL();
virtual ~OSystem_SDL();
/**
* Pre-initialize backend. It should be called after
* instantiating the backend. Early needed managers are
* created here.
*/
virtual void init();
/**
* Get the Mixer Manager instance. Not to confuse with getMixer(),
* that returns Audio::Mixer. The Mixer Manager is a SDL wrapper class
* for the Audio::Mixer. Used by other managers.
*/
virtual SdlMixerManager *getMixerManager();
// Override functions from ModularBackend and OSystem
virtual void initBackend();
// Set the size of the video bitmap.
// Typically, 320x200
virtual void launcherInitSize(uint w, uint h);
virtual byte *setupScreen(int screenW, int screenH, bool fullscreen, bool accel3d);
// Update the dirty areas of the screen
void updateScreen();
// Either show or hide the mouse cursor
bool showMouse(bool visible);
// Warp the mouse cursor. Where set_mouse_pos() only informs the
// backend of the mouse cursor's current position, this function
// actually moves the cursor to the specified position.
virtual void warpMouse(int x, int y); // overloaded by CE backend (FIXME)
// Set the bitmap that's used when drawing the cursor.
virtual void setMouseCursor(const byte *buf, uint w, uint h, int hotspot_x, int hotspot_y, uint32 keycolor, int cursorTargetScale, const Graphics::PixelFormat *format); // overloaded by CE backend (FIXME)
// Get the number of milliseconds since the program was started.
uint32 getMillis();
// Delay for a specified amount of milliseconds
void delayMillis(uint msecs);
// Get the next event.
// Returns true if an event was retrieved.
virtual bool pollEvent(Common::Event &event); // overloaded by CE backend
protected:
virtual bool dispatchSDLEvent(SDL_Event &ev, Common::Event &event);
// Handlers for specific SDL events, called by pollEvent.
// This way, if a backend inherits fromt the SDL backend, it can
// change the behavior of only a single event, without having to override all
// of pollEvent.
virtual bool handleKeyDown(SDL_Event &ev, Common::Event &event);
virtual bool handleKeyUp(SDL_Event &ev, Common::Event &event);
virtual bool handleMouseMotion(SDL_Event &ev, Common::Event &event);
virtual bool handleMouseButtonDown(SDL_Event &ev, Common::Event &event);
virtual bool handleMouseButtonUp(SDL_Event &ev, Common::Event &event);
virtual bool handleJoyButtonDown(SDL_Event &ev, Common::Event &event);
virtual bool handleJoyButtonUp(SDL_Event &ev, Common::Event &event);
virtual bool handleJoyAxisMotion(SDL_Event &ev, Common::Event &event);
public:
// Define all hardware keys for keymapper
virtual Common::HardwareKeySet *getHardwareKeySet();
virtual void quit();
virtual void fatalError();
// Set function that generates samples
virtual void setupMixer();
static void mixCallback(void *s, byte *samples, int len);
// Logging
virtual void logMessage(LogMessageType::Type type, const char *message);
virtual void closeMixer();
virtual Audio::Mixer *getMixer();
// Poll CD status
// Returns true if cd audio is playing
bool pollCD();
// Play CD audio track
void playCD(int track, int num_loops, int start_frame, int duration);
// Stop CD audio track
void stopCD();
// Update CD audio status
void updateCD();
// Quit
virtual void quit(); // overloaded by CE backend
void deinit();
virtual void getTimeAndDate(TimeDate &t) const;
virtual Common::TimerManager *getTimerManager();
// Mutex handling
MutexRef createMutex();
void lockMutex(MutexRef mutex);
void unlockMutex(MutexRef mutex);
void deleteMutex(MutexRef mutex);
// Overlay
virtual Graphics::PixelFormat getOverlayFormat() const { return _overlayFormat; }
virtual void showOverlay();
virtual void hideOverlay();
virtual void clearOverlay();
virtual void grabOverlay(OverlayColor *buf, int pitch);
virtual void copyRectToOverlay(const OverlayColor *buf, int pitch, int x, int y, int w, int h);
virtual int16 getHeight();
virtual int16 getWidth();
virtual int16 getOverlayHeight() { return _overlayHeight; }
virtual int16 getOverlayWidth() { return _overlayWidth; }
virtual Common::String getSystemLanguage() const;
virtual void setWindowCaption(const char *caption);
virtual bool openCD(int drive);
virtual bool hasFeature(Feature f);
virtual void setFeatureState(Feature f, bool enable);
virtual bool getFeatureState(Feature f);
virtual void preprocessEvents(SDL_Event *event) {}
virtual Common::SaveFileManager *getSavefileManager();
virtual FilesystemFactory *getFilesystemFactory();
virtual void addSysArchivesToSearchSet(Common::SearchSet &s, int priority = 0);
virtual Common::SeekableReadStream *createConfigReadStream();
virtual Common::WriteStream *createConfigWriteStream();
virtual uint32 getMillis();
virtual void delayMillis(uint msecs);
virtual void getTimeAndDate(TimeDate &td) const;
virtual Audio::Mixer *getMixer();
// HACK: Special SDL events types
enum SdlEvent {
kSdlEventExpose = 100,
kSdlEventResize = 101
};
protected:
bool _inited;
SDL_AudioSpec _obtainedRate;
bool _initedSDL;
/**
* Mixer manager that configures and setups SDL for
* the wrapped Audio::Mixer, the true mixer.
*/
SdlMixerManager *_mixerManager;
#ifdef USE_OPENGL
bool _opengl;
#endif
bool _fullscreen;
SDL_Surface *_screen;
/**
* The event source we use for obtaining SDL events.
*/
SdlEventSource *_eventSource;
// overlay
SDL_Surface *_overlayscreen;
bool _overlayVisible;
Graphics::PixelFormat _overlayFormat;
int _overlayWidth, _overlayHeight;
bool _overlayDirty;
int _overlayNumTex;
#ifdef USE_OPENGL
GLuint *_overlayTexIds;
#endif
/**
* Initialze the SDL library.
*/
virtual void initSDL();
void closeOverlay();
/**
* Setup the window icon.
*/
virtual void setupIcon();
// CD Audio
SDL_CD *_cdrom;
int _cdTrack, _cdNumLoops, _cdStartFrame, _cdDuration;
uint32 _cdEndTime, _cdStopTime;
/**
* Get the file path where the user configuration
* of ScummVM will be saved.
*/
virtual Common::String getDefaultConfigFileName();
// Keyboard mouse emulation. Disabled by fingolfin 2004-12-18.
// I am keeping the rest of the code in for now, since the joystick
// code (or rather, "hack") uses it, too.
struct KbdMouse {
int16 x, y, x_vel, y_vel, x_max, y_max, x_down_count, y_down_count;
uint32 last_time, delay_time, x_down_time, y_down_time;
};
// mouse
KbdMouse _km;
// Scroll lock state - since SDL doesn't track it
bool _scrollLock;
// joystick
SDL_Joystick *_joystick;
#ifdef MIXER_DOUBLE_BUFFERING
SDL_mutex *_soundMutex;
SDL_cond *_soundCond;
SDL_Thread *_soundThread;
bool _soundThreadIsRunning;
bool _soundThreadShouldQuit;
byte _activeSoundBuf;
uint _soundBufSize;
byte *_soundBuffers[2];
void mixerProducerThread();
static int SDLCALL mixerProducerThreadEntry(void *arg);
void initThreadedMixer(Audio::MixerImpl *mixer, uint bufSize);
void deinitThreadedMixer();
#endif
FilesystemFactory *_fsFactory;
Common::SaveFileManager *_savefile;
Audio::MixerImpl *_mixer;
SDL_TimerID _timerID;
Common::TimerManager *_timer;
protected:
/** Set the position of the virtual mouse cursor. */
void setMousePos(int x, int y);
virtual void fillMouseEvent(Common::Event &event, int x, int y); // overloaded by CE backend
void toggleMouseGrab();
void setupIcon();
void handleKbdMouse();
virtual bool remapKey(SDL_Event &ev, Common::Event &event);
bool handleScalerHotkeys(const SDL_KeyboardEvent &key);
// Logging
virtual Common::WriteStream *createLogFile() { return 0; }
Backends::Log::Log *_logger;
};
#endif

View file

@ -0,0 +1,71 @@
/* Residual - A 3D game interpreter
*
* Residual is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the AUTHORS
* 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$
*
*/
// Disable symbol overrides so that we can use system headers.
#define FORBIDDEN_SYMBOL_ALLOW_ALL
#include "common/sys.h"
#ifdef WIN32
// Fix for bug #2895217 "MSVC compilation broken with r47595":
// We need to keep this on top of the "common/scummsys.h"(base/main.h) include,
// otherwise we will get errors about the windows headers redefining
// "ARRAYSIZE" for example.
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#undef ARRAYSIZE // winnt.h defines ARRAYSIZE, but we want our own one...
#include "backends/platform/sdl/win32/win32.h"
#include "backends/plugins/sdl/sdl-provider.h"
#include "base/main.h"
int __stdcall WinMain(HINSTANCE /*hInst*/, HINSTANCE /*hPrevInst*/, LPSTR /*lpCmdLine*/, int /*iShowCmd*/) {
SDL_SetModuleHandle(GetModuleHandle(NULL));
return main(__argc, __argv);
}
int main(int argc, char *argv[]) {
// Create our OSystem instance
g_system = new OSystem_Win32();
assert(g_system);
// Pre initialize the backend
((OSystem_Win32 *)g_system)->init();
#ifdef DYNAMIC_MODULES
PluginManager::instance().addPluginProvider(new SDLPluginProvider());
#endif
// Invoke the actual Residual main entry point:
int res = residual_main(argc, argv);
// Free OSystem
delete (OSystem_Win32 *)g_system;
return res;
}
#endif

View file

@ -0,0 +1,171 @@
/* Residual - A 3D game interpreter
*
* Residual is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the AUTHORS
* 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$
*
*/
// Disable symbol overrides so that we can use system headers.
#define FORBIDDEN_SYMBOL_ALLOW_ALL
#include "common/sys.h"
#ifdef WIN32
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#undef ARRAYSIZE // winnt.h defines ARRAYSIZE, but we want our own one...
#include "backends/platform/sdl/win32/win32.h"
#include "backends/fs/windows/windows-fs-factory.h"
#define DEFAULT_CONFIG_FILE "residual.ini"
//#define HIDE_CONSOLE
#ifdef HIDE_CONSOLE
struct SdlConsoleHidingWin32 {
DWORD myPid;
DWORD myTid;
HWND consoleHandle;
};
// console hiding for win32
static BOOL CALLBACK initBackendFindConsoleWin32Proc(HWND hWnd, LPARAM lParam) {
DWORD pid, tid;
SdlConsoleHidingWin32 *variables = (SdlConsoleHidingWin32 *)lParam;
tid = GetWindowThreadProcessId(hWnd, &pid);
if ((tid == variables->myTid) && (pid == variables->myPid)) {
variables->consoleHandle = hWnd;
return FALSE;
}
return TRUE;
}
#endif
void OSystem_Win32::init() {
#ifdef HIDE_CONSOLE
// console hiding for win32
SdlConsoleHidingWin32 consoleHidingWin32;
consoleHidingWin32.consoleHandle = 0;
consoleHidingWin32.myPid = GetCurrentProcessId();
consoleHidingWin32.myTid = GetCurrentThreadId();
EnumWindows (initBackendFindConsoleWin32Proc, (LPARAM)&consoleHidingWin32);
if (!ConfMan.getBool("show_console")) {
if (consoleHidingWin32.consoleHandle) {
// We won't find a window with our TID/PID in case we were started from command-line
ShowWindow(consoleHidingWin32.consoleHandle, SW_HIDE);
}
}
#endif
// Initialze File System Factory
_fsFactory = new WindowsFilesystemFactory();
// Invoke parent implementation of this method
OSystem_SDL::init();
}
Common::String OSystem_Win32::getDefaultConfigFileName() {
char configFile[MAXPATHLEN];
OSVERSIONINFO win32OsVersion;
ZeroMemory(&win32OsVersion, sizeof(OSVERSIONINFO));
win32OsVersion.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
GetVersionEx(&win32OsVersion);
// Check for non-9X version of Windows.
if (win32OsVersion.dwPlatformId != VER_PLATFORM_WIN32_WINDOWS) {
// Use the Application Data directory of the user profile.
if (win32OsVersion.dwMajorVersion >= 5) {
if (!GetEnvironmentVariable("APPDATA", configFile, sizeof(configFile)))
error("Unable to access application data directory");
} else {
if (!GetEnvironmentVariable("USERPROFILE", configFile, sizeof(configFile)))
error("Unable to access user profile directory");
strcat(configFile, "\\Application Data");
CreateDirectory(configFile, NULL);
}
strcat(configFile, "\\Residual");
CreateDirectory(configFile, NULL);
strcat(configFile, "\\" DEFAULT_CONFIG_FILE);
FILE *tmp = NULL;
if ((tmp = fopen(configFile, "r")) == NULL) {
// Check windows directory
char oldConfigFile[MAXPATHLEN];
GetWindowsDirectory(oldConfigFile, MAXPATHLEN);
strcat(oldConfigFile, "\\" DEFAULT_CONFIG_FILE);
if ((tmp = fopen(oldConfigFile, "r"))) {
strcpy(configFile, oldConfigFile);
fclose(tmp);
}
} else {
fclose(tmp);
}
} else {
// Check windows directory
GetWindowsDirectory(configFile, MAXPATHLEN);
strcat(configFile, "\\" DEFAULT_CONFIG_FILE);
}
return configFile;
}
Common::WriteStream *OSystem_Win32::createLogFile() {
char logFile[MAXPATHLEN];
OSVERSIONINFO win32OsVersion;
ZeroMemory(&win32OsVersion, sizeof(OSVERSIONINFO));
win32OsVersion.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
GetVersionEx(&win32OsVersion);
// Check for non-9X version of Windows.
if (win32OsVersion.dwPlatformId != VER_PLATFORM_WIN32_WINDOWS) {
// Use the Application Data directory of the user profile.
if (win32OsVersion.dwMajorVersion >= 5) {
if (!GetEnvironmentVariable("APPDATA", logFile, sizeof(logFile)))
error("Unable to access application data directory");
} else {
if (!GetEnvironmentVariable("USERPROFILE", logFile, sizeof(logFile)))
error("Unable to access user profile directory");
strcat(logFile, "\\Application Data");
CreateDirectory(logFile, NULL);
}
strcat(logFile, "\\Residual");
CreateDirectory(logFile, NULL);
strcat(logFile, "\\Logs");
CreateDirectory(logFile, NULL);
strcat(logFile, "\\residual.log");
Common::FSNode file(logFile);
return file.createWriteStream();
} else {
return 0;
}
}
#endif

View file

@ -0,0 +1,40 @@
/* Residual - A 3D game interpreter
*
* Residual is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the AUTHORS
* 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$
*
*/
#ifndef PLATFORM_SDL_WIN32_H
#define PLATFORM_SDL_WIN32_H
#include "backends/platform/sdl/sdl.h"
class OSystem_Win32 : public OSystem_SDL {
public:
virtual void init();
protected:
virtual Common::String getDefaultConfigFileName();
virtual Common::WriteStream *createLogFile();
};
#endif