Patch #1432376: "Very basic GP2X Backend"

svn-id: r24144
This commit is contained in:
Eugene Sandulenko 2006-10-06 19:01:39 +00:00
parent e75bea0c8f
commit 3d84f11046
21 changed files with 4134 additions and 10 deletions

View file

@ -43,6 +43,9 @@
#elif defined(__PSP__)
#define SAMPLES_PER_SEC 44100
#elif defined(__GP2X__)
#define SAMPLES_PER_SEC 11025
#elif defined(PALMOS_MODE)
# ifdef PALMOS_ARM
# ifdef COMPILE_ZODIAC

View file

@ -0,0 +1,5 @@
# Build settings for the GP2X backend
MODULES += backends/gp2x
DEFINES += -DUNIX -DGP2X
INCLUDES += `sdl-config --cflags`
LIBS += `sdl-config --libs`

View file

@ -0,0 +1,114 @@
$URL$
$Id$
DO NOT USE THIS FOR ANYTHING OTHER THEN TO TEST A USB MOUSE.
IT'S BUGGY AND ANYTHING OTHER THEN THE 320*2xx LucasArts GAMES
WILL MOST LIGHTLY CRASH YOUR GP2X.
THE README IS BELOW JUST FOR REFERANCE.
ScummVM for the GP2X - UNSTABLE MOUSE TEST - 0.10.0 SVN
-------------------------------------------------------
This is a test release of ScummVM for the GP2X, it would be appreciated if this alpha test distribution was not mirrored and that people be directed to http://www.distant-earth.com/scummvm instead, until the port is a little more mature, to ensure people download the most recent builds.
This build is still in a very heavy state of development and as such no expected behaviour can be guaranteed ;).
I tested with firmware 1.2.1 for reference.
INCLUDED ENGINES:
Scumm - (All games supported by ScummVM should work to some extent, using the hardware scalar if needed)
// Simon - (Simon the Sorcerer one and two)
// Sky - (Beneath a Steel Sky)
// Sword - (Broken Sword 1) - This engine uses the hardware scalar to downsize the graphics to fix on the GP2X. It is NOT very nice to look at.
// Sword2 - (Broken Sword 2) - This engine uses the hardware scalar to downsize the graphics to fix on the GP2X. It is NOT very nice to look at.
// Gob - (Goblins one)
// Queen - Flight of the Amazon Queen
// Kyra - (The Legend of Kyrandia) - This engine is still under heavy development in ScummVM, however the game is playable.
// Lure - (Lure of the Temptress) - This engine is still under heavy development in ScummVM, the game is not yet really playable.
All other game engines are disabled in this release.
SUPPORTED AUDIO OPTIONS:
Raw audio.
MP3 audio.
OGG Vorbis audio (this may be problematic, I just made some big changes to my Tremor code).
RECENT CHANGES:
Refined audio hacks to reduce audio delay a little more.
Enabled hardware scalar code.
Now built using SDL 1.2.9 for the parts of the port that use SDL (some parts now hit the hardware directly).
Enabled new launcher - (Ensure defaulttheme.zip is in the same folder as the executable).
Aspect Ratio Correction can now be disabled per game. When adding a game you can find this option on the GFX tab.
Note: This will cause the game to run with a black border at the bottom as it will be rendered to a 320*200 frame.
HOW TO SAVE:
NOTE: Everything is saved to the SD card, saves are stored in the game folder, and the config file for ScummVM (.scummvmrc) is stored in the same place as the GPE.
Ok, this is for Scumm engine games but the principle is the same for all.
In Game.
1. Right Trigger
2. Select SAVE with B
3. Select a position with B
4. Right trigger puts ? in the name box for some text.
5. Press B to save
Basically the emulated keys you have are what I mapped the buttons to,
I have a virtual keyboard like the GP32 one (left/right on the stick to pick chars) to add in at some point ;-)
CONTROLLER MAPPING:
NOTE: The controller mappings have recently changed somewhat so please review the new setup.
This is subject to change; it still does not feel quite right.
Mouse Emulation:
Stick: Move Pointer
Stick Click: light Left Click
B: Left click
X: Right click
Keyboard Emulation:
Start: Return
Select: Escape
Y: Space Bar (Pause)
Right Trigger: Game Menu (Save, Load, Quit etc.)
Volume Buttons: Increase and Decrease volume (5% per press)
Fancy button combos:
NOTE: To use button combos press and hold the Left Trigger then...
Volume Buttons: Increase and Decrease subtitle speed (In SCUMM games)
Right Trigger: 0 (For skipping the copy protection in Monkey Island 2)
Select: Exit ScummVM completely
(More to add, ideas please)
KNOWN ISSUES:
Possible random crash (well SegFault). I have had this happen twice and have not tracked down the cause.
It happens very infrequently, both times it was in the DOTT CD intro. Saving often is never a bad idea anyhow.
Volume level changes can be a little inconsistent at times.
MAJOR TODOS:
Fix save support when using the Sky engine (Beneath a Steel Sky) - You CAN'T save at the moment but auto save works.
Look into inconsistencies with Simon engine and map Y key to a button combination to allow clean quitting (Simon 1/2).
Add splash-screen and pre-ScummVM config menu (CPU speed, LCD timings etc.) - Partly done.
Fix TV out, maybe make it an option in the pre-ScummVM config menu.
Any help appreciated :).
SOURCE:
Port source is available on request. Note this is development code (and VERY messy).
John Willis

View file

@ -0,0 +1,114 @@
$URL$
$Id$
DO NOT USE THIS FOR ANYTHING OTHER THEN TO TEST A USB MOUSE.
IT'S BUGGY AND ANYTHING OTHER THEN THE 320*2xx LucasArts GAMES
WILL MOST LIGHTLY CRASH YOUR GP2X.
THE README IS BELOW JUST FOR REFERANCE.
ScummVM for the GP2X - UNSTABLE MOUSE TEST - 0.10.0 SVN
-------------------------------------------------------
This is a test release of ScummVM for the GP2X, it would be appreciated if this alpha test distribution was not mirrored and that people be directed to http://www.distant-earth.com/scummvm instead, until the port is a little more mature, to ensure people download the most recent builds.
This build is still in a very heavy state of development and as such no expected behaviour can be guaranteed ;).
I tested with firmware 1.2.1 for reference.
INCLUDED ENGINES:
Scumm - (All games supported by ScummVM should work to some extent, using the hardware scalar if needed)
// Simon - (Simon the Sorcerer one and two)
// Sky - (Beneath a Steel Sky)
// Sword - (Broken Sword 1) - This engine uses the hardware scalar to downsize the graphics to fix on the GP2X. It is NOT very nice to look at.
// Sword2 - (Broken Sword 2) - This engine uses the hardware scalar to downsize the graphics to fix on the GP2X. It is NOT very nice to look at.
// Gob - (Goblins one)
// Queen - Flight of the Amazon Queen
// Kyra - (The Legend of Kyrandia) - This engine is still under heavy development in ScummVM, however the game is playable.
// Lure - (Lure of the Temptress) - This engine is still under heavy development in ScummVM, the game is not yet really playable.
All other game engines are disabled in this release.
SUPPORTED AUDIO OPTIONS:
Raw audio.
MP3 audio.
OGG Vorbis audio (this may be problematic, I just made some big changes to my Tremor code).
RECENT CHANGES:
Refined audio hacks to reduce audio delay a little more.
Enabled hardware scalar code.
Now built using SDL 1.2.9 for the parts of the port that use SDL (some parts now hit the hardware directly).
Enabled new launcher - (Ensure defaulttheme.zip is in the same folder as the executable).
Aspect Ratio Correction can now be disabled per game. When adding a game you can find this option on the GFX tab.
Note: This will cause the game to run with a black border at the bottom as it will be rendered to a 320*200 frame.
HOW TO SAVE:
NOTE: Everything is saved to the SD card, saves are stored in the game folder, and the config file for ScummVM (.scummvmrc) is stored in the same place as the GPE.
Ok, this is for Scumm engine games but the principle is the same for all.
In Game.
1. Right Trigger
2. Select SAVE with B
3. Select a position with B
4. Right trigger puts ? in the name box for some text.
5. Press B to save
Basically the emulated keys you have are what I mapped the buttons to,
I have a virtual keyboard like the GP32 one (left/right on the stick to pick chars) to add in at some point ;-)
CONTROLLER MAPPING:
NOTE: The controller mappings have recently changed somewhat so please review the new setup.
This is subject to change; it still does not feel quite right.
Mouse Emulation:
Stick: Move Pointer
Stick Click: light Left Click
B: Left click
X: Right click
Keyboard Emulation:
Start: Return
Select: Escape
Y: Space Bar (Pause)
Right Trigger: Game Menu (Save, Load, Quit etc.)
Volume Buttons: Increase and Decrease volume (5% per press)
Fancy button combos:
NOTE: To use button combos press and hold the Left Trigger then...
Volume Buttons: Increase and Decrease subtitle speed (In SCUMM games)
Right Trigger: 0 (For skipping the copy protection in Monkey Island 2)
Select: Exit ScummVM completely
(More to add, ideas please)
KNOWN ISSUES:
Possible random crash (well SegFault). I have had this happen twice and have not tracked down the cause.
It happens very infrequently, both times it was in the DOTT CD intro. Saving often is never a bad idea anyhow.
Volume level changes can be a little inconsistent at times.
MAJOR TODOS:
Fix save support when using the Sky engine (Beneath a Steel Sky) - You CAN'T save at the moment but auto save works.
Look into inconsistencies with Simon engine and map Y key to a button combination to allow clean quitting (Simon 1/2).
Add splash-screen and pre-ScummVM config menu (CPU speed, LCD timings etc.) - Partly done.
Fix TV out, maybe make it an option in the pre-ScummVM config menu.
Any help appreciated :).
SOURCE:
Port source is available on request. Note this is development code (and VERY messy).
John Willis

View file

@ -0,0 +1,19 @@
#!/bin/bash
echo Quick script to make building all the time less painful.
# Set the paths up here to support the build.
export PATH=/tools/open2x_gcc/gcc-4.0.2-glibc-2.3.5/arm-open2x-linux/arm-open2x-linux/bin:$PATH
export PATH=/tools/open2x_gcc/gcc-4.0.2-glibc-2.3.5/arm-open2x-linux/bin:$PATH
export CXX=arm-open2x-linux-g++
export CC=arm-open2x-linux-gcc
export CXXFLAGS=-march=armv4t
export LDFLAGS=-static
cd ../../../..
echo Building ScummVM for GP2X.
make
echo Build for GP2X - SDL - complete - Please check build logs.

View file

@ -0,0 +1,30 @@
#!/bin/bash
echo Quick script to make building a distribution of the GP2X port more consistent.
PATH=/tools/open2x_gcc/gcc-4.0.2-glibc-2.3.5/arm-open2x-linux/arm-open2x-linux/bin:$PATH
PATH=/tools/open2x_gcc/gcc-4.0.2-glibc-2.3.5/arm-open2x-linux/bin:$PATH
export CXX=arm-open2x-linux-g++
export CXXFLAGS=-march=armv4t
export CPPFLAGS=-I/tools/open2x_gcc/gcc-4.0.2-glibc-2.3.5/arm-open2x-linux/include
export LDFLAGS=-L/tools/open2x_gcc/gcc-4.0.2-glibc-2.3.5/arm-open2x-linux/lib
echo Collecting files.
mkdir "scummvm-gp2x-`date '+%Y-%m-%d'`"
cp ./scummvm.png ./scummvm-gp2x-`date '+%Y-%m-%d'`/
cp ./README-GP2X.html ./scummvm-gp2x-`date '+%Y-%m-%d'`/
cp ./README-GP2X ./scummvm-gp2x-`date '+%Y-%m-%d'`/
cp ../../../../scummvm.gpe ./scummvm-gp2x-`date '+%Y-%m-%d'`/
cp ../../../../AUTHORS ./scummvm-gp2x-`date '+%Y-%m-%d'`/
cp ../../../../README ./scummvm-gp2x-`date '+%Y-%m-%d'`/
cp ../../../../COPYING ./scummvm-gp2x-`date '+%Y-%m-%d'`/
cp ../../../../gui/themes/modern.ini ./scummvm-gp2x-`date '+%Y-%m-%d'`/
cp ../../../../gui/themes/modern.zip ./scummvm-gp2x-`date '+%Y-%m-%d'`/
echo Making Stripped GPE.
arm-open2x-linux-strip ./scummvm-gp2x-`date '+%Y-%m-%d'`/scummvm.gpe
echo Building ZIP bundle.
echo You should have a "scummvm-gp2x-`date '+%Y-%m-%d'`.zip" for the GP2X port ready to go.

View file

@ -0,0 +1,17 @@
#!/bin/bash
echo Quick script to make building all the time less painful.
# Set the paths up here to support the build.
export PATH=/tools/open2x_gcc/gcc-4.0.2-glibc-2.3.5/arm-open2x-linux/arm-open2x-linux/bin:$PATH
export PATH=/tools/open2x_gcc/gcc-4.0.2-glibc-2.3.5/arm-open2x-linux/bin:$PATH
export CXX=arm-open2x-linux-g++
export CC=arm-open2x-linux-gcc
export CXXFLAGS=-march=armv4t
export LDFLAGS=-static
cd ../../../..
echo Cleaning ScummVM for GP2X.
make clean

View file

@ -0,0 +1,22 @@
#!/bin/bash
echo Quick script to make running configure all the time less painful
echo and let all the build work be done from the backend/build folder.
# Set the paths up here to generate the config.
PATH=/tools/open2x_gcc/gcc-4.0.2-glibc-2.3.5/arm-open2x-linux/arm-open2x-linux/bin:$PATH
PATH=/tools/open2x_gcc/gcc-4.0.2-glibc-2.3.5/arm-open2x-linux/bin:$PATH
# Export the tool names for cross-compiling
export CXX=arm-open2x-linux-g++
export CXXFLAGS=-march=armv4t
export CPPFLAGS=-I/tools/open2x_gcc/gcc-4.0.2-glibc-2.3.5/arm-open2x-linux/include
export LDFLAGS=-L/tools/open2x_gcc/gcc-4.0.2-glibc-2.3.5/arm-open2x-linux/lib
export DEFINES=-DNDEBUG
# Edit the configure line to suit.
cd ../../../..
./configure --backend=gp2x --disable-mt32emu --host=gp2x --disable-mpeg2 --disable-flac --disable-nasm --disable-hq-scalers --with-sdl-prefix=/tools/open2x_gcc/gcc-4.0.2-glibc-2.3.5/arm-open2x-linux/bin --enable-tremor --with-tremor-prefix=/tools/open2x_gcc/gcc-4.0.2-glibc-2.3.5/arm-open2x-linux --enable-zlib --with-zlib-prefix=/tools/open2x_gcc/gcc-4.0.2-glibc-2.3.5/arm-open2x-linux --enable-mad --with-mad-prefix=/tools/open2x_gcc/gcc-4.0.2-glibc-2.3.5/arm-open2x-linux
echo Generating config for GP2X complete. Check for errors.

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

View file

@ -0,0 +1,657 @@
/* ScummVM - Scumm Interpreter
* Copyright (C) 2001 Ludvig Strigeus
* Copyright (C) 2001-2006 The ScummVM project
* Copyright (C) 2005-2006 John Willis (Portions of the GP2X Backend)
*
* 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$
*
*/
/*
* GP2X: Event Handling.
*
*/
#include "backends/platform/gp2x/gp2x-common.h"
#include "backends/platform/gp2x/gp2x-hw.h"
#include "common/util.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 2200
// #define JOY_INVERT_Y
#define JOY_XAXIS 0
#define JOY_YAXIS 1
// GP2X Stick Buttons (Note: The Stick is read as a set of buttons not a HAT type of setup).
#define JOY_BUT_LMOUSE 0x0D
#define JOY_BUT_RMOUSE 0x0E
#define JOY_BUT_RETURN 0x08
#define JOY_BUT_ESCAPE 0x09
#define JOY_BUT_F5 0x0B
#define JOY_BUT_SPACE 0x0F
#define JOY_BUT_TALKUP 0x10
#define JOY_BUT_TALKDN 0x11
#define JOY_BUT_ZERO 0x12
#define JOY_BUT_COMB 0x0A
#define JOY_BUT_EXIT 0x12
#define JOY_BUT_PERIOD 0x0C
//TODO: Quick hack 101 ;-) Clean this up,
#define TRUE 1
#define FALSE 0
static int mapKey(SDLKey key, SDLMod mod, Uint16 unicode)
{
if (key >= SDLK_F1 && key <= SDLK_F9) {
return key - SDLK_F1 + 315;
} 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_GP2X::fillMouseEvent(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;
// Adjust for the screen scaling
if (!_overlayVisible) {
event.mouse.x /= _scaleFactor;
event.mouse.y /= _scaleFactor;
if (_adjustAspectRatio)
event.mouse.y = aspect2Real(event.mouse.y);
}
}
void OSystem_GP2X::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;
}
SDL_WarpMouse(_km.x, _km.y);
}
}
}
static byte SDLModToOSystemKeyFlags(SDLMod mod) {
byte b = 0;
#ifdef LINUPY
// Yopy has no ALT key, steal the SHIFT key
// (which isn't used much anyway)
if (mod & KMOD_SHIFT)
b |= OSystem::KBD_ALT;
#else
if (mod & KMOD_SHIFT)
b |= OSystem::KBD_SHIFT;
if (mod & KMOD_ALT)
b |= OSystem::KBD_ALT;
#endif
if (mod & KMOD_CTRL)
b |= OSystem::KBD_CTRL;
return b;
}
void OSystem_GP2X::moveStick() {
bool stickBtn[32];
memcpy(stickBtn, _stickBtn, sizeof(stickBtn));
if((stickBtn[0])||(stickBtn[2])||(stickBtn[4])||(stickBtn[6]))
stickBtn[1] = stickBtn[3] = stickBtn[5] = stickBtn[7] = 0;
if((stickBtn[1])||(stickBtn[2])||(stickBtn[3])){
if(_km.x_down_count!=2){
_km.x_vel = -1;
_km.x_down_count = 1;
}else
_km.x_vel = -4;
} else if((stickBtn[5])||(stickBtn[6])||(stickBtn[7])){
if(_km.x_down_count!=2){
_km.x_vel = 1;
_km.x_down_count = 1;
}else
_km.x_vel = 4;
}
else{
_km.x_vel = 0;
_km.x_down_count = 0;
}
if((stickBtn[0])||(stickBtn[1])||(stickBtn[7])){
if(_km.y_down_count!=2){
_km.y_vel = -1;
_km.y_down_count = 1;
}else
_km.y_vel = -4;
} else if((stickBtn[3])||(stickBtn[4])||(stickBtn[5])){
if(_km.y_down_count!=2){
_km.y_vel = 1;
_km.y_down_count = 1;
}else
_km.y_vel = 4;
}
else{
_km.y_vel = 0;
_km.y_down_count = 0;
}
}
//Quick default button states for modifier.
//int GP2X_BUTTON_STATE_UP = FALSE;
//int GP2X_BUTTON_STATE_DOWN = FALSE;
//int GP2X_BUTTON_STATE_LEFT = FALSE;
//int GP2X_BUTTON_STATE_RIGHT = FALSE;
//int GP2X_BUTTON_STATE_UPLEFT = FALSE;
//int GP2X_BUTTON_STATE_UPRIGHT = FALSE;
//int GP2X_BUTTON_STATE_DOWNLEFT = FALSE;
//int GP2X_BUTTON_STATE_DOWNRIGHT = FALSE;
//int GP2X_BUTTON_STATE_CLICK = FALSE;
//int GP2X_BUTTON_STATE_A = FALSE;
//int GP2X_BUTTON_STATE_B = FALSE;
//int GP2X_BUTTON_STATE_Y = FALSE;
//int GP2X_BUTTON_STATE_X = FALSE;
int GP2X_BUTTON_STATE_L = FALSE;
//int GP2X_BUTTON_STATE_R = FALSE;
//int GP2X_BUTTON_STATE_START = FALSE;
//int GP2X_BUTTON_STATE_SELECT = FALSE;
//int GP2X_BUTTON_STATE_VOLUP = FALSE;
//int GP2X_BUTTON_STATE_VOLDOWN = FALSE;
bool OSystem_GP2X::pollEvent(Event &event) {
SDL_Event ev;
int axis;
byte b = 0;
handleKbdMouse();
// If the screen mode changed, send an EVENT_SCREEN_CHANGED
if (_modeChanged) {
_modeChanged = false;
event.type = EVENT_SCREEN_CHANGED;
_screenChangeCount++;
return true;
}
// GP2X Input mappings.
/*
Single Button
Movement:
GP2X_BUTTON_UP Cursor Up
GP2X_BUTTON_DOWN Cursor Down
GP2X_BUTTON_LEFT Cursor Left
GP2X_BUTTON_RIGHT Cursor Right
TODO: Add extra directions to cursor mappings.
GP2X_BUTTON_UPLEFT Cursor Up Left
GP2X_BUTTON_UPRIGHT Cursor Up Right
GP2X_BUTTON_DOWNLEFT Cursor Down Left
GP2X_BUTTON_DOWNRIGHT Cursor Down Right
Button Emulation:
GP2X_BUTTON_CLICK Left Mouse Click
GP2X_BUTTON_A . (Period)
GP2X_BUTTON_B Left Mouse Click
GP2X_BUTTON_Y Space Bar
GP2X_BUTTON_X Right Mouse Click
GP2X_BUTTON_L Combo Modifier (Left Trigger)
GP2X_BUTTON_R F5 (Right Trigger)
GP2X_BUTTON_START Return
GP2X_BUTTON_SELECT Escape
GP2X_BUTTON_VOLUP /dev/mixer Global Volume Up
GP2X_BUTTON_VOLDOWN /dev/mixer Global Volume Down
Combos:
GP2X_BUTTON_VOLUP & GP2X_BUTTON_VOLDOWN 0 (For Monkey 2 CP)
GP2X_BUTTON_L & GP2X_BUTTON_SELECT EVENT_QUIT (Calls Sync() to make sure SD is flushed)
GP2X_BUTTON_L & GP2X_BUTTON_Y Toggles setZoomOnMouse() for larger then 320*240 games to scale to the point + raduis.
*/
while(SDL_PollEvent(&ev)) {
switch(ev.type) {
case SDL_KEYDOWN:{
b = event.kbd.flags = SDLModToOSystemKeyFlags(SDL_GetModState());
// Alt-Return and Alt-Enter toggle full screen mode
if (b == KBD_ALT && (ev.key.keysym.sym == SDLK_RETURN
|| ev.key.keysym.sym == SDLK_KP_ENTER)) {
setFullscreenMode(!_fullscreen);
break;
}
// Alt-S: Create a screenshot
if (b == KBD_ALT && ev.key.keysym.sym == 's') {
char filename[20];
for (int n = 0;; n++) {
SDL_RWops *file;
sprintf(filename, "scummvm%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");
break;
}
// Ctrl-m toggles mouse capture
//if (b == KBD_CTRL && ev.key.keysym.sym == 'm') {
// toggleMouseGrab();
// break;
//}
//#ifdef MACOSX
// // On Macintosh', Cmd-Q quits
// if ((ev.key.keysym.mod & KMOD_META) && ev.key.keysym.sym == 'q') {
// event.type = 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 = EVENT_QUIT;
// return true;
// }
//#else
// // Ctrl-z and Alt-X quit
// if ((b == KBD_CTRL && ev.key.keysym.sym == 'z') || (b == KBD_ALT && ev.key.keysym.sym == 'x')) {
// event.type = EVENT_QUIT;
// return true;
// }
//#endif
//
// // Ctrl-Alt-<key> will change the GFX mode
// if ((b & (KBD_CTRL|KBD_ALT)) == (KBD_CTRL|KBD_ALT)) {
//
// handleScalerHotkeys(ev.key);
// break;
// }
const bool event_complete = remapKey(ev,event);
if (event_complete)
return true;
event.type = 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);
return true;
}
case SDL_KEYUP:
{
const bool event_complete = remapKey(ev,event);
if (event_complete)
return true;
event.type = EVENT_KEYUP;
event.kbd.keycode = ev.key.keysym.sym;
event.kbd.ascii = mapKey(ev.key.keysym.sym, ev.key.keysym.mod, ev.key.keysym.unicode);
b = event.kbd.flags = SDLModToOSystemKeyFlags(SDL_GetModState());
// Ctrl-Alt-<key> will change the GFX mode
if ((b & (KBD_CTRL|KBD_ALT)) == (KBD_CTRL|KBD_ALT)) {
// Swallow these key up events
break;
}
return true;
}
case SDL_MOUSEMOTION:
event.type = EVENT_MOUSEMOVE;
fillMouseEvent(event, ev.motion.x, ev.motion.y);
setMousePos(event.mouse.x, event.mouse.y);
return true;
case SDL_MOUSEBUTTONDOWN:
if (ev.button.button == SDL_BUTTON_LEFT)
event.type = EVENT_LBUTTONDOWN;
else if (ev.button.button == SDL_BUTTON_RIGHT)
event.type = EVENT_RBUTTONDOWN;
#if defined(SDL_BUTTON_WHEELUP) && defined(SDL_BUTTON_WHEELDOWN)
else if (ev.button.button == SDL_BUTTON_WHEELUP)
event.type = EVENT_WHEELUP;
else if (ev.button.button == SDL_BUTTON_WHEELDOWN)
event.type = EVENT_WHEELDOWN;
#endif
else
break;
fillMouseEvent(event, ev.button.x, ev.button.y);
return true;
case SDL_MOUSEBUTTONUP:
if (ev.button.button == SDL_BUTTON_LEFT)
event.type = EVENT_LBUTTONUP;
else if (ev.button.button == SDL_BUTTON_RIGHT)
event.type = EVENT_RBUTTONUP;
else
break;
fillMouseEvent(event, ev.button.x, ev.button.y);
return true;
// GP2X Button mapings. Main code
case SDL_JOYBUTTONDOWN:
_stickBtn[ev.jbutton.button] = 1;
if (ev.jbutton.button == JOY_BUT_LMOUSE) {
event.type = EVENT_LBUTTONDOWN;
fillMouseEvent(event, _km.x, _km.y);
} else if (ev.jbutton.button == GP2X_BUTTON_CLICK) {
event.type = EVENT_LBUTTONDOWN;
fillMouseEvent(event, _km.x, _km.y);
} else if (ev.jbutton.button == JOY_BUT_RMOUSE) {
event.type = EVENT_RBUTTONDOWN;
fillMouseEvent(event, _km.x, _km.y);
} else if (_stickBtn[JOY_BUT_COMB] && (ev.jbutton.button == JOY_BUT_EXIT)) {
event.type = EVENT_QUIT;
} else if (ev.jbutton.button < 8) {
moveStick();
event.type = EVENT_MOUSEMOVE;
fillMouseEvent(event, _km.x, _km.y);
} else {
event.type = EVENT_KEYDOWN;
event.kbd.flags = 0;
switch (ev.jbutton.button) {
case GP2X_BUTTON_L:
GP2X_BUTTON_STATE_L = TRUE;
break;
case GP2X_BUTTON_R:
if (GP2X_BUTTON_STATE_L == TRUE) {
event.kbd.keycode = SDLK_0;
event.kbd.ascii = mapKey(SDLK_0, ev.key.keysym.mod, 0);
} else {
event.kbd.keycode = SDLK_F5;
event.kbd.ascii = mapKey(SDLK_F5, ev.key.keysym.mod, 0);
}
break;
case GP2X_BUTTON_SELECT:
if (GP2X_BUTTON_STATE_L == TRUE) {
event.type = EVENT_QUIT;
} else {
event.kbd.keycode = SDLK_ESCAPE;
event.kbd.ascii = mapKey(SDLK_ESCAPE, ev.key.keysym.mod, 0);
}
break;
case GP2X_BUTTON_A:
event.kbd.keycode = SDLK_PERIOD;
event.kbd.ascii = mapKey(SDLK_PERIOD, ev.key.keysym.mod, 0);
break;
case GP2X_BUTTON_Y:
if (GP2X_BUTTON_STATE_L == TRUE) {
setZoomOnMouse();
} else {
event.kbd.keycode = SDLK_SPACE;
event.kbd.ascii = mapKey(SDLK_SPACE, ev.key.keysym.mod, 0);
}
break;
case JOY_BUT_RETURN:
event.kbd.keycode = SDLK_RETURN;
event.kbd.ascii = mapKey(SDLK_RETURN, ev.key.keysym.mod, 0);
break;
case JOY_BUT_ZERO:
event.kbd.keycode = SDLK_0;
event.kbd.ascii = mapKey(SDLK_0, ev.key.keysym.mod, 0);
break;
//case GP2X_BUTTON_R:
// if ((ev.jbutton.button == GP2X_BUTTON_L) && (ev.jbutton.button == GP2X_BUTTON_R)) {
// displayMessageOnOSD("Exiting ScummVM");
// //Sync();
// event.type = EVENT_QUIT;
// break;
// } else if ((ev.jbutton.button == GP2X_BUTTON_L) && (ev.jbutton.button != GP2X_BUTTON_R)) {
// displayMessageOnOSD("Left Trigger Pressed");
// break;
// } else if ((ev.jbutton.button == GP2X_BUTTON_R) && (ev.jbutton.button != GP2X_BUTTON_L)) {
// event.kbd.keycode = SDLK_F5;
// event.kbd.ascii = mapKey(SDLK_F5, ev.key.keysym.mod, 0);
// break;
// } else {
// break;
// }
// break;
case GP2X_BUTTON_VOLUP:
if (GP2X_BUTTON_STATE_L == TRUE) {
displayMessageOnOSD("Setting CPU Speed at 230MHz");
GP2X_setCpuspeed(200);
//event.kbd.keycode = SDLK_PLUS;
//event.kbd.ascii = mapKey(SDLK_PLUS, ev.key.keysym.mod, 0);
} else {
GP2X_mixer_move_volume(1);
displayMessageOnOSD("Increasing Volume");
}
break;
case GP2X_BUTTON_VOLDOWN:
if (GP2X_BUTTON_STATE_L == TRUE) {
displayMessageOnOSD("Setting CPU Speed at 60MHz");
GP2X_setCpuspeed(60);
//event.kbd.keycode = SDLK_MINUS;
//event.kbd.ascii = mapKey(SDLK_MINUS, ev.key.keysym.mod, 0);
} else {
GP2X_mixer_move_volume(0);
displayMessageOnOSD("Decreasing Volume");
}
break;
}
}
return true;
case SDL_JOYBUTTONUP:
_stickBtn[ev.jbutton.button] = 0;
if (ev.jbutton.button == JOY_BUT_LMOUSE) {
event.type = EVENT_LBUTTONUP;
fillMouseEvent(event, _km.x, _km.y);
} else if (ev.jbutton.button == JOY_BUT_RMOUSE) {
event.type = EVENT_RBUTTONUP;
fillMouseEvent(event, _km.x, _km.y);
} else if (ev.jbutton.button < 8) {
moveStick();
event.type = EVENT_MOUSEMOVE;
fillMouseEvent(event, _km.x, _km.y);
} else {
event.type = EVENT_KEYUP;
event.kbd.flags = 0;
switch (ev.jbutton.button) {
case GP2X_BUTTON_SELECT:
event.kbd.keycode = SDLK_ESCAPE;
event.kbd.ascii = mapKey(SDLK_ESCAPE, ev.key.keysym.mod, 0);
break;
case GP2X_BUTTON_A:
event.kbd.keycode = SDLK_PERIOD;
event.kbd.ascii = mapKey(SDLK_PERIOD, ev.key.keysym.mod, 0);
break;
case GP2X_BUTTON_Y:
// event.kbd.keycode = SDLK_SPACE;
// event.kbd.ascii = mapKey(SDLK_SPACE, ev.key.keysym.mod, 0);
break;
case GP2X_BUTTON_START:
event.kbd.keycode = SDLK_RETURN;
event.kbd.ascii = mapKey(SDLK_RETURN, ev.key.keysym.mod, 0);
break;
case GP2X_BUTTON_L:
GP2X_BUTTON_STATE_L = FALSE;
break;
case GP2X_BUTTON_R:
event.kbd.keycode = SDLK_F5;
event.kbd.ascii = mapKey(SDLK_F5, ev.key.keysym.mod, 0);
break;
case GP2X_BUTTON_VOLUP:
break;
case GP2X_BUTTON_VOLDOWN:
break;
}
}
return true;
case SDL_JOYAXISMOTION:
axis = ev.jaxis.value;
if ( axis > JOY_DEADZONE) {
axis -= JOY_DEADZONE;
event.type = EVENT_MOUSEMOVE;
} else if ( axis < -JOY_DEADZONE ) {
axis += JOY_DEADZONE;
event.type = 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;
case SDL_VIDEOEXPOSE:
_forceFull = true;
break;
case SDL_QUIT:
event.type = EVENT_QUIT;
return true;
}
}
return false;
}
bool OSystem_GP2X::remapKey(SDL_Event &ev,Event &event) {
return false;
}

View file

@ -0,0 +1,402 @@
/* ScummVM - Scumm Interpreter
* Copyright (C) 2001 Ludvig Strigeus
* Copyright (C) 2001-2006 The ScummVM project
* Copyright (C) 2005-2006 John Willis (Portions of the GP2X Backend)
*
* 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 GP2X_COMMON_H
#define GP2X_COMMON_H
#define __GP2X__
#define USE_OSD
#include "common/stdafx.h"
#include "common/scummsys.h"
#include "common/system.h"
#include "graphics/scaler.h"
#include "backends/intern.h"
#include <SDL.h>
#include <SDL_gp2x.h>
//#define DISABLE_SCALERS
enum {
GFX_NORMAL = 0,
GFX_DOUBLESIZE = 1,
GFX_TRIPLESIZE = 2,
GFX_2XSAI = 3,
GFX_SUPER2XSAI = 4,
GFX_SUPEREAGLE = 5,
GFX_ADVMAME2X = 6,
GFX_ADVMAME3X = 7,
GFX_HQ2X = 8,
GFX_HQ3X = 9,
GFX_TV2X = 10,
GFX_DOTMATRIX = 11
};
class OSystem_GP2X : public OSystem {
public:
OSystem_GP2X();
virtual ~OSystem_GP2X();
virtual void initBackend();
void beginGFXTransaction(void);
void endGFXTransaction(void);
// Set the size of the video bitmap.
// Typically, 320x200
void initSize(uint w, uint h);
int getScreenChangeID() const { return _screenChangeCount; }
// Set colors of the palette
void setPalette(const byte *colors, uint start, uint num);
// Get colors of the palette
void grabPalette(byte *colors, uint start, uint num);
// Draw a bitmap to screen.
// The screen will not be updated to reflect the new bitmap
void copyRectToScreen(const byte *src, int pitch, int x, int y, int w, int h);
// Copies the screen to a buffer
bool grabRawScreen(Graphics::Surface *surf);
// Clear the screen
void clearScreen();
// 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.
void warpMouse(int x, int y);
// Set the bitmap that's used when drawing the cursor.
void setMouseCursor(const byte *buf, uint w, uint h, int hotspot_x, int hotspot_y, byte keycolor, int cursorTargetScale);
// Set colors of cursor palette
void setCursorPalette(const byte *colors, uint start, uint num);
// Disables or enables cursor palette
void disableCursorPalette(bool disable) {
_cursorPaletteDisabled = disable;
blitCursor();
};
// Shaking is used in SCUMM. Set current shake position.
void setShakePos(int shake_pos);
// 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(Event &event); // overloaded by CE backend
// Set function that generates samples
virtual bool setSoundCallback(SoundProc proc, void *param); // overloaded by CE backend
void clearSoundCallback();
// 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
// Add a callback timer
void setTimerCallback(TimerProc callback, int timer);
// Mutex handling
MutexRef createMutex();
void lockMutex(MutexRef mutex);
void unlockMutex(MutexRef mutex);
void deleteMutex(MutexRef mutex);
// Overlay
void showOverlay();
void hideOverlay();
void clearOverlay();
void grabOverlay(OverlayColor *buf, int pitch);
void copyRectToOverlay(const OverlayColor *buf, int pitch, int x, int y, int w, int h); // WinCE FIXME
int16 getHeight();
int16 getWidth();
int16 getOverlayHeight() { return _overlayHeight; }
int16 getOverlayWidth() { return _overlayWidth; }
// Methods that convert RGB to/from colors suitable for the overlay.
OverlayColor RGBToColor(uint8 r, uint8 g, uint8 b);
void colorToRGB(OverlayColor color, uint8 &r, uint8 &g, uint8 &b);
virtual const GraphicsMode *getSupportedGraphicsModes() const;
virtual int getDefaultGraphicsMode() const;
virtual bool setGraphicsMode(int mode);
virtual int getGraphicsMode() const;
//virtual void setWindowCaption(const char *caption);
virtual bool openCD(int drive);
virtual int getOutputSampleRate() const;
virtual bool hasFeature(Feature f);
virtual void setFeatureState(Feature f, bool enable);
virtual bool getFeatureState(Feature f);
void displayMessageOnOSD(const char *msg);
protected:
bool _inited;
SDL_Surface *_osdSurface;
Uint8 _osdAlpha; // Transparency level of the OSD
uint32 _osdFadeStartTime; // When to start the fade out
enum {
kOSDFadeOutDelay = 2 * 1000, // Delay before the OSD is faded out (in milliseconds)
kOSDFadeOutDuration = 500, // Duration of the OSD fade out (in milliseconds)
kOSDColorKey = 1,
kOSDInitialAlpha = 80 // Initial alpha level, in percent
};
// hardware screen
SDL_Surface *_hwscreen;
// unseen game screen
SDL_Surface *_screen;
int _screenWidth, _screenHeight;
// temporary screen (for scalers)
SDL_Surface *_tmpscreen;
SDL_Surface *_tmpscreen2;
// overlay
SDL_Surface *_overlayscreen;
int _overlayWidth, _overlayHeight;
bool _overlayVisible;
// Audio
int _samplesPerSec;
// CD Audio
SDL_CD *_cdrom;
int _cdTrack, _cdNumLoops, _cdStartFrame, _cdDuration;
uint32 _cdEndTime, _cdStopTime;
enum {
DF_WANT_RECT_OPTIM = 1 << 0,
DF_UPDATE_EXPAND_1_PIXEL = 1 << 1
};
enum {
kTransactionNone = 0,
kTransactionCommit = 1,
kTransactionActive = 2
};
struct TransactionDetails {
int mode;
bool modeChanged;
int w;
int h;
bool sizeChanged;
bool fs;
bool fsChanged;
bool ar;
bool arChanged;
bool needHotswap;
bool needUpdatescreen;
bool needUnload;
bool needToggle;
bool normal1xScaler;
};
TransactionDetails _transactionDetails;
/** Force full redraw on next updateScreen */
bool _forceFull;
ScalerProc *_scalerProc;
int _scalerType;
int _scaleFactor;
int _mode;
int _transactionMode;
bool _fullscreen;
/** Current video mode flags (see DF_* constants) */
uint32 _modeFlags;
bool _modeChanged;
int _screenChangeCount;
/** True if aspect ratio correction is enabled. */
bool _adjustAspectRatio;
/** True if zoom on mouse is enabled. (only set by > 240 high games) */
bool _adjustZoomOnMouse;
//_adjustZoomOnMouse = false;
enum {
NUM_DIRTY_RECT = 100,
MAX_MOUSE_W = 80,
MAX_MOUSE_H = 80,
MAX_SCALING = 3
};
// Dirty rect management
SDL_Rect _dirtyRectList[NUM_DIRTY_RECT];
int _numDirtyRects;
uint32 *_dirtyChecksums;
bool _cksumValid;
int _cksumNum;
// 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;
};
struct MousePos {
// The mouse position, using either virtual (game) or real
// (overlay) coordinates.
int16 x, y;
// The size and hotspot of the original cursor image.
int16 w, h;
int16 hotX, hotY;
// The size and hotspot of the pre-scaled cursor image, in real
// coordinates.
int16 rW, rH;
int16 rHotX, rHotY;
// The size and hotspot of the pre-scaled cursor image, in game
// coordinates.
int16 vW, vH;
int16 vHotX, vHotY;
MousePos() : x(0), y(0), w(0), h(0), hotX(0), hotY(0),
rW(0), rH(0), rHotX(0), rHotY(0), vW(0), vH(0),
vHotX(0), vHotY(0)
{ }
};
// mouse
KbdMouse _km;
bool _mouseVisible;
bool _mouseDrawn;
byte *_mouseData;
SDL_Rect _mouseBackup;
MousePos _mouseCurState;
//int16 _mouseHotspotX;
//int16 _mouseHotspotY;
byte _mouseKeyColor;
int _cursorTargetScale;
//bool _cursorHasOwnPalette;
bool _cursorPaletteDisabled;
SDL_Surface *_mouseOrigSurface;
SDL_Surface *_mouseSurface;
enum {
kMouseColorKey = 1
};
// joystick
SDL_Joystick *_joystick;
bool _stickBtn[32];
// Shake mode
int _currentShakePos;
int _newShakePos;
// Palette data
SDL_Color *_currentPalette;
uint _paletteDirtyStart, _paletteDirtyEnd;
// Cursor palette data
SDL_Color *_cursorPalette;
/**
* Mutex which prevents multiple threads from interfering with each other
* when accessing the screen.
*/
MutexRef _graphicsMutex;
void addDirtyRgnAuto(const byte *buf);
void makeChecksums(const byte *buf);
virtual void addDirtyRect(int x, int y, int w, int h, bool realCoordinates = false);
void drawMouse();
virtual void undrawMouse();
virtual void blitCursor();
/** Set the position of the virtual mouse cursor. */
void setMousePos(int x, int y);
virtual void fillMouseEvent(Event &event, int x, int y);
//void toggleMouseGrab();
virtual void internUpdateScreen();
virtual void loadGFXMode();
virtual void unloadGFXMode();
virtual void hotswapGFXMode();
void setFullscreenMode(bool enable);
void setAspectRatioCorrection(bool enable);
void setZoomOnMouse(); // GP2X: On > 240 high games zooms on the mouse + radius.
virtual bool saveScreenshot(const char *filename);
int effectiveScreenHeight() const { return (_adjustAspectRatio ? 240 : _screenHeight) * _scaleFactor; }
void setupIcon();
void handleKbdMouse();
virtual bool remapKey(SDL_Event &ev, Event &event);
void handleScalerHotkeys(const SDL_KeyboardEvent &key);
void moveStick();
};
#endif // GP2X_COMMON_H

View file

@ -0,0 +1,248 @@
/* ScummVM - Scumm Interpreter
* Copyright (C) 2001 Ludvig Strigeus
* Copyright (C) 2001-2006 The ScummVM project
* Copyright (C) 2005-2006 John Willis (Portions of the GP2X Backend)
*
* 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$
*
*/
/*
* GP2X: Hardware Stuff.
* Thanks to Rlyeh, Snaff, Squidge, Hermes, PS2Reality and RobBrown
* for there help with us all getting to grips with this.
*
*/
#include "gp2x-common.h"
#include "gp2x-hw.h"
// Linux includes to let us goof about with the system.
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <sys/soundcard.h>
static unsigned long gp2x_dev[8]={0,0,0,0,0,0,0,0};//, gp2x_ticks_per_second;
static volatile unsigned short *gp2x_memregs;
/* system registers */
static struct
{
unsigned short SYSCLKENREG,SYSCSETREG,FPLLVSETREG,DUALINT920,DUALINT940,DUALCTRL940;
}
system_reg;
static unsigned short dispclockdiv;
static volatile unsigned short *MEM_REG;
#define SYS_CLK_FREQ 7372800
void GP2X_device_init() {
// Open devices
if(!gp2x_dev[0]) gp2x_dev[0] = open("/dev/mixer", O_RDWR);
if(!gp2x_dev[1]) gp2x_dev[1] = open("/dev/batt", O_RDONLY);
if(!gp2x_dev[2]) gp2x_dev[2] = open("/dev/mem", O_RDWR);
}
void GP2X_device_deinit() {
// Close devices
if (gp2x_dev[0]) close(gp2x_dev[0]);
if (gp2x_dev[1]) close(gp2x_dev[1]);
if (gp2x_dev[2]) close(gp2x_dev[2]);
MEM_REG[0x91c>>1]=system_reg.SYSCSETREG;
MEM_REG[0x910>>1]=system_reg.FPLLVSETREG;
MEM_REG[0x3B40>>1]=system_reg.DUALINT920;
MEM_REG[0x3B42>>1]=system_reg.DUALINT940;
MEM_REG[0x3B48>>1]=system_reg.DUALCTRL940;
MEM_REG[0x904>>1]=system_reg.SYSCLKENREG;
MEM_REG[0x924>>1]=dispclockdiv;
}
// Vairous mixer level fudges.
// TODO: Clean up and merge quick hacks.
void GP2X_mixer_set_volume(int L /*0..100*/, int R /*0..100*/) {
/* Set an arbitrary percentage value for the hardware mixer volume.
Parameters:
L (0..100) - volume percentage for the left channel
R (0..100) - volume percentage for the right channel
Note:
- A higher percentage than 100 will distort your sound.
*/
unsigned char temp[4];
if (L < 0) L = 0;
if (L > GP2X_MAXVOL) L = GP2X_MAXVOL;
if (R < 0) R = 0;
if (R > GP2X_MAXVOL) R = GP2X_MAXVOL;
temp[0]=(unsigned char)L;
temp[1]=(unsigned char)R;
temp[2]=temp[3]=0;
//warning("GP2X_mixer_set_volume is about to set %d %d", L, R);
ioctl(gp2x_dev[0], SOUND_MIXER_WRITE_PCM, temp);
}
int GP2X_mixer_get_volume() {
int vol;
ioctl(gp2x_dev[0], SOUND_MIXER_READ_PCM, &vol);
//warning("GP2X_mixer_get_volume returned %d %d", (int)((vol & 0xff)), (int)((vol >> 8) & 0xff));
return (int)((vol & 0xff));
}
void GP2X_mixer_move_volume(int UpDown) {
// Raise volume 5% if 1 passed, lower 5% if 0.
int curvol, newvol;
ioctl(gp2x_dev[0], SOUND_MIXER_READ_PCM, &curvol);
curvol = ((int)((curvol & 0xff)));
newvol = ((int)((curvol & 0xff)));
//warning("GP2X_mixer_move_volume got current volume @ %d", curvol);
if (UpDown == 1) {
newvol = (curvol + 5);
} else if (UpDown == 0) {
newvol = (curvol - 5);
}
//warning("GP2X_mixer_move_volume is about to set volume @ %d", newvol);
GP2X_mixer_set_volume(newvol, newvol);
return;
}
void GP2X_setCpuspeed(unsigned int mhz)
{
set_FCLK(mhz);
set_DCLK_Div(0);
set_920_Div(0);
}
void set_display_clock_div(unsigned div)
{
div=((div & 63) | 64)<<8;
MEM_REG[0x924>>1]=(MEM_REG[0x924>>1] & ~(255<<8)) | div;
}
void set_FCLK(unsigned MHZ)
{
unsigned v;
unsigned mdiv,pdiv=3,scale=0;
MHZ*=1000000;
mdiv=(MHZ*pdiv)/SYS_CLK_FREQ;
mdiv=((mdiv-8)<<8) & 0xff00;
pdiv=((pdiv-2)<<2) & 0xfc;
scale&=3;
v=mdiv | pdiv | scale;
MEM_REG[0x910>>1]=v;
}
void set_920_Div(unsigned short div)
{
unsigned short v;
v = MEM_REG[0x91c>>1] & (~0x3);
MEM_REG[0x91c>>1] = (div & 0x7) | v;
}
void set_DCLK_Div( unsigned short div )
{
unsigned short v;
v = (unsigned short)( MEM_REG[0x91c>>1] & (~(0x7 << 6)) );
MEM_REG[0x91c>>1] = ((div & 0x7) << 6) | v;
}
void Disable_940(void)
{
MEM_REG[0x3B42>>1];
MEM_REG[0x3B42>>1]=0;
MEM_REG[0x3B46>>1]=0xffff;
MEM_REG[0x3B48>>1]|= (1 << 7);
MEM_REG[0x904>>1]&=0xfffe;
}
void gp2x_video_wait_vsync(void)
{
MEM_REG[0x2846>>1]=(MEM_REG[0x2846>>1] | 0x20) & ~2;
while(!(MEM_REG[0x2846>>1] & 2));
}
//char GP2X_get_battery_level() {
// Returns string of level in English for use in displayMessageOnOSD() to show battery level.
//
//if (gp2x_dev[1] == -1)
//{
// warning("Error occured getting voltage status");
// return "Unable to read battery level.";
//}
//
//int i;
//int battval;
//unsigned short cbv;
//int v;
//
//battval = 0;
//for (i = 0; i < 1000; i ++)
//{
// if (read (gp2x_dev[1], &cbv, 2) == 2)
// battval += cbv;
// if (gp2x_joystick_read() & GP2X_START)
// {
// needexit = 1;
// break;
// }
//}
//if (needexit) break;
//
//battval /= 1000;
// Do a very rough translation
//if (battval > 1016) v = 37;
//else if (battval > 974) v = 33;
//else if (battval > 943) v = 32;
//else if (battval > 915) v = 31;
//else if (battval > 896) v = 30;
//else if (battval > 837) v = 29;
//else if (battval > 815) v = 28;
//else if (battval > 788) v = 27;
//else if (battval > 745) v = 26;
//else if (battval > 708) v = 25;
//else if (battval > 678) v = 24;
//else if (battval > 649) v = 23;
//else if (battval > 605) v = 22;
//else if (battval > 573) v = 21;
//else if (battval > 534) v = 20;
//else if (battval > 496) v = 19;
//else if (battval > 448) v = 18;
//else v = 17;
//gp2x_printf (NULL, 0, 0, "Voltage: ~%d.%dV (%s)", v/10, v%10, v>26?"Battery Full" : v>24?"Battery Medium" : "Battery Empty");
//gp2x_video_RGB_flip(0);
//}
//close (gp2x_dev[1]);
//return "Voltage: ~%d.%dV (%s)", v/10, v%10, v>26?"Battery Full" : v>24?"Battery Medium" : "Battery Empty";
//}

View file

@ -0,0 +1,74 @@
/* ScummVM - Scumm Interpreter
* Copyright (C) 2001 Ludvig Strigeus
* Copyright (C) 2001-2006 The ScummVM project
* Copyright (C) 2005-2006 John Willis (Portions of the GP2X Backend)
*
* 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$
*
*/
/*
* GP2X: Hardware Stuff.
*
*/
#ifndef GP2X_HW_H
#define GP2X_HW_H
//GP2X Main Joystick Mappings
//TODO: Use these more standard mappings over the custom ones.
#define GP2X_BUTTON_UP (0)
#define GP2X_BUTTON_UPLEFT (1)
#define GP2X_BUTTON_LEFT (2)
#define GP2X_BUTTON_DOWNLEFT (3)
#define GP2X_BUTTON_DOWN (4)
#define GP2X_BUTTON_DOWNRIGHT (5)
#define GP2X_BUTTON_RIGHT (6)
#define GP2X_BUTTON_UPRIGHT (7)
#define GP2X_BUTTON_START (8)
#define GP2X_BUTTON_SELECT (9)
#define GP2X_BUTTON_L (10)
#define GP2X_BUTTON_R (11)
#define GP2X_BUTTON_A (12)
#define GP2X_BUTTON_B (13)
#define GP2X_BUTTON_X (14)
#define GP2X_BUTTON_Y (15)
#define GP2X_BUTTON_VOLUP (16)
#define GP2X_BUTTON_VOLDOWN (17)
#define GP2X_BUTTON_CLICK (18)
#define GP2X_MAXVOL 100 // Highest level permitted by GP2X's mixer
#define SYS_CLK_FREQ 7372800 // Clock Frequency
extern void GP2X_device_init();
extern void GP2X_device_deinit();
extern void GP2X_mixer_set_volume(int, int);
extern int GP2X_mixer_get_volume();
extern void GP2X_mixer_move_volume(int);
extern void GP2X_setCpuspeed(unsigned int cpuspeed);
extern void save_system_regs(void); /* save some registers */
extern void set_display_clock_div(unsigned div);
extern void set_FCLK(unsigned MHZ); /* adjust the clock frequency (in Mhz units) */
extern void set_920_Div(unsigned short div); /* 0 to 7 divider (freq=FCLK/(1+div)) */
extern void set_DCLK_Div(unsigned short div); /* 0 to 7 divider (freq=FCLK/(1+div)) */
extern void Disable_940(void); /* 940t down */
extern void gp2x_video_wait_vsync(void);
#endif //GP2X_HW_H

View file

@ -0,0 +1,300 @@
/* ScummVM - Scumm Interpreter
* Copyright (C) 2001 Ludvig Strigeus
* Copyright (C) 2001-2006 The ScummVM project
* Copyright (C) 2005-2006 John Willis (Portions of the GP2X Backend)
*
* 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$
*
*/
/*
* GP2X: Memory tweaking stuff.
*
*/
#include <stdio.h>
#include <signal.h>
#include <setjmp.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <unistd.h>
#include <string.h>
#include "gp2x-mem.h"
void InitRam (void)
{
if(!gp2x_dev)
{
gp2x_dev = open("/dev/mem", O_RDWR);
gp2x_ram = (unsigned short *)mmap(0, 0x10000, 3, 1, gp2x_dev, 0x03000000);
gp2x_memregs = (unsigned short *)mmap(0, 0x10000, 3, 1, gp2x_dev, 0xc0000000);
}
}
void CloseRam (void)
{
if(gp2x_dev) close(gp2x_dev);
}
/*
****** [BEGIN] Squidge's MMU hack code ******
*/
int myuname(char *buffer)
{
asm volatile ("swi #0x90007a");
}
void DecodeCoarse (unsigned int indx, unsigned int sa)
{
unsigned int cpt[256];
unsigned int temp;
unsigned int i = 0;
unsigned int wb = 0;
sa &= 0xfffffc00;
indx *= 1048576;
//printf (" > %08X\n", sa);
//printf ("%d\n",
lseek (gp2x_dev, sa, SEEK_SET);
memset (cpt, 0, 256*4);
temp = read (gp2x_dev, cpt, 256*4);
//printf ("%d\n", temp);
if (temp != 256*4)
{
printf (" # Bad read\n");
return;
}
//printf ("%08X %08X %08X %08X\n", cpt[0], cpt[4], cpt[8], cpt[12]);
for (i = 0; i < 256; i ++)
{
if (cpt[i])
{
switch (cpt[i] & 3)
{
case 0:
//printf (" -- [%08X] Invalid --\n", cpt[i]);
break;
case 1:
/*
printf (" VA: %08X PA: %08X - %08X A: %d %d %d %d D: %d C: %d B: %d\n", indx,
cpt[i] & 0xFFFF0000, (cpt[i] & 0xFFFF0000) | 0xFFFF,
(cpt[i] >> 10) & 3, (cpt[i] >> 8) & 3, (cpt[i] >> 6) & 3,
(cpt[i] >> 4) & 3, dom, (cpt[i] >> 3) & 1, (cpt[i] >> 2) & 1);
*/
break;
case 2:
//a=((cpt[i] & 0xff000000)>>24);
/*printf (" VA: %08X PA: %08X - %08X A: %d %d %d %d D: %d C: %d B: %d\n", indx,
cpt[i] & 0xfffff000, (cpt[i] & 0xfffff000) | 0xFFF,
(cpt[i] >> 10) & 3, (cpt[i] >> 8) & 3, (cpt[i] >> 6) & 3,
(cpt[i] >> 4) & 3, dom, (cpt[i] >> 3) & 1, (cpt[i] >> 2) & 1);
*/
// This is where we look for any virtual addresses that map to physical address 0x03000000 and
// alter the cachable and bufferable bits...
if (((cpt[i] & 0xff000000) == 0x02000000) )
{
//printf("SOUND c and b bits not set, overwriting\n");
if((cpt[i] & 12)==0) {
cpt[i] |= 0xFFC;
wb++;
}
}
//if ((a>=0x31 && a<=0x36) && ((cpt[i] & 12)==0))
if (((cpt[i] & 0xff000000) == 0x03000000) )
{
//printf("SDL c and b bits not set, overwriting\n");
if((cpt[i] & 12)==0) {
cpt[i] |= 0xFFC;
wb++;
}
}
break;
case 3:
//printf (" -- [%08X/%d] Unsupported --\n", cpt[i],cpt[i] & 3);
break;
default:
//printf (" -- [%08X/%d] Unknown --\n", cpt[i], cpt[i] & 3);
break;
}
}
indx += 4096;
}
//printf ("%08X %08X %08X %08X\n", cpt[0], cpt[4], cpt[8], cpt[12]);
if (wb)
{
//printf("Hacking cpt\n");
lseek (gp2x_dev, sa, SEEK_SET);
temp = write (gp2x_dev, cpt, 256*4);
printf("%d bytes written, %s\n", temp, temp == 1024 ? "yay!" : "oh fooble :(!");
}
}
void dumppgtable (unsigned int ttb)
{
unsigned int pgtable[4096];
char *desctypes[] = {"Invalid", "Coarse", "Section", "Fine"};
memset (pgtable, 0, 4096*4);
lseek (gp2x_dev, ttb, SEEK_SET);
read (gp2x_dev, pgtable, 4096*4);
int i;
for (i = 0; i < 4096; i ++)
{
int temp;
if (pgtable[i])
{
//printf ("Indx: %d VA: %08X Type: %d [%s] \n", i, i * 1048576, pgtable[i] & 3, desctypes[pgtable[i]&3]);
switch (pgtable[i]&3)
{
case 0:
//printf (" -- Invalid --\n");
break;
case 1:
DecodeCoarse(i, pgtable[i]);
break;
case 2:
temp = pgtable[i] & 0xFFF00000;
//printf (" PA: %08X - %08X A: %d D: %d C: %d B: %d\n", temp, temp | 0xFFFFF,
// (pgtable[i] >> 10) & 3, (pgtable[i] >> 5) & 15, (pgtable[i] >> 3) & 1,
// (pgtable[i] >> 2) & 1);
break;
case 3:
printf (" -- Unsupported! --\n");
break;
}
}
}
}
int hackpgtable (void)
{
unsigned int oldc1, oldc2, oldc3, oldc4;
unsigned int newc1 = 0xee120f10, newc2 = 0xe12fff1e;
unsigned int ttb, ttx;
int a=0;int try=0;
// We need to execute a "MRC p15, 0, r0, c2, c0, 0", to get the pointer to the translation table base, but we can't
// do this in user mode, so we have to patch the kernel to get it to run it for us in supervisor mode. We dothis
// at the moment by overwriting the sys_newuname function and then calling it.
lseek (gp2x_dev, 0x6ec00, SEEK_SET); // fixme: We should ask the kernel for this address rather than assuming it...
read (gp2x_dev, &oldc1, 4);
read (gp2x_dev, &oldc2, 4);
read (gp2x_dev, &oldc3, 4);
read (gp2x_dev, &oldc4, 4);
printf ("0:%08X %08X - %08X %08X\n", oldc1, oldc2, newc1, newc2);
printf ("point1 %d\n",a);
do {
lseek (gp2x_dev, 0x6ec00, SEEK_SET);
a+=write (gp2x_dev, &newc1, 4);
a+=write (gp2x_dev, &newc2, 4);
SDL_Delay(200);
try++;
ttb = myuname(name);
printf ("2:%08X try %d\n", ttb,try);
} while (ttb==0 && try<4);
lseek (gp2x_dev, 0x6ec00, SEEK_SET);
a+=write (gp2x_dev, &oldc1, 4);
a+=write (gp2x_dev, &oldc2, 4);
printf ("2:%08X %d\n", ttb,a);
if (ttb!=0) {
//printf ("Restored contents\n");
// We now have the translation table base ! Walk the table looking for our allocation and hack it :)
dumppgtable(ttb);
// Now drain the write buffer and flush the tlb caches. Something else we can't do in user mode...
unsigned int tlbc1 = 0xe3a00000; // mov r0, #0
unsigned int tlbc2 = 0xee070f9a; // mcr 15, 0, r0, cr7, cr10, 4
unsigned int tlbc3 = 0xee080f17; // mcr 15, 0, r0, cr8, cr7, 0
unsigned int tlbc4 = 0xe1a0f00e; // mov pc, lr
lseek (gp2x_dev, 0x6ec00, SEEK_SET);
write (gp2x_dev, &tlbc1, 4);
write (gp2x_dev, &tlbc2, 4);
write (gp2x_dev, &tlbc3, 4);
write (gp2x_dev, &tlbc4, 4);
SDL_Delay(200);
ttx = myuname(name);
printf ("Return from uname: %08X\n", ttx);
lseek (gp2x_dev, 0x6ec00, SEEK_SET);
write (gp2x_dev, &oldc1, 4);
write (gp2x_dev, &oldc2, 4);
write (gp2x_dev, &oldc3, 4);
write (gp2x_dev, &oldc4, 4);
lseek (gp2x_dev, 0x0, SEEK_SET);
return 0;
}
lseek (gp2x_dev, 0x0, SEEK_SET);
return 1;
//printf ("Restored contents\n");
//printf ("Pagetable after modification!\n");
//printf ("-------------------------------\n");
//dumppgtable(ttb);
}
/*
****** [END] Squidge's MMU hack code ******
*/
void SetClock (unsigned c)
{
unsigned v;
unsigned mdiv,pdiv=3,scale=0;
// Set ARM920t clock
c *= 1000000;
mdiv = (c*pdiv) / SYS_CLK_FREQ;
mdiv = ((mdiv-8)<<8) & 0xff00;
pdiv = ((pdiv-2)<<2) & 0xfc;
scale &= 3;
v = mdiv | pdiv | scale;
gp2x_memregs[0x910>>1] = v;
}
void MMUpatch (void)
{
volatile unsigned int *secbuf = (unsigned int *)malloc (204800);
// Squidge's MMU hack
hackpgtable();
}

View file

@ -0,0 +1,57 @@
/* ScummVM - Scumm Interpreter
* Copyright (C) 2001 Ludvig Strigeus
* Copyright (C) 2001-2006 The ScummVM project
* Copyright (C) 2005-2006 John Willis (Portions of the GP2X Backend)
*
* 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$
*
*/
/*
* GP2X: Memory Stuff.
*
*/
#ifndef GP2X_MEM_H
#define GP2X_MEM_H
#ifdef __cplusplus
extern "C" {
#endif
// Use Squidge's MMU patch rather then myown (his is neater).
// The effect if not that great but cacheing the upper RAM is no bad thing (tm) ;).
void InitRam (void);
void CloseRam (void);
// Set ARM920t clock frequency
void SetClock (unsigned c);
void MMUpatch (void);
#define SYS_CLK_FREQ 7372800
char name[256];
unsigned long gp2x_dev;
volatile unsigned short *gp2x_ram, *gp2x_memregs;
#ifdef __cplusplus
}
#endif
#endif //GP2X_MEM_H

View file

@ -0,0 +1,298 @@
/* ScummVM - Scumm Interpreter
* Copyright (C) 2001 Ludvig Strigeus
* Copyright (C) 2001-2006 The ScummVM project
* Copyright (C) 2005-2006 John Willis (Portions of the GP2X Backend)
*
* 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$
*
*/
/*
* GP2X: Main backend.
*
*/
#include "backends/platform/gp2x/gp2x-common.h"
#include "backends/platform/gp2x/gp2x-hw.h"
#include "backends/platform/gp2x/gp2x-mem.h"
#include "common/config-manager.h"
#include "common/util.h"
#include "base/main.h"
#if defined(HAVE_CONFIG_H)
#include "config.h"
#endif
int main(int argc, char *argv[]) {
// Setup GP2X upper 32MB caching
//InitRam();
//MMUpatch();
extern OSystem *OSystem_GP2X_create();
g_system = OSystem_GP2X_create();
assert(g_system);
// Invoke the actual ScummVM main entry point:
int res = scummvm_main(argc, argv);
g_system->quit();
return res;
}
OSystem *OSystem_GP2X_create() {
return new OSystem_GP2X();
}
void OSystem_GP2X::initBackend() {
assert(!_inited);
ConfMan.set("joystick_num", 0);
int joystick_num = ConfMan.getInt("joystick_num");
uint32 sdlFlags = SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER;
if (ConfMan.hasKey("disable_sdl_parachute"))
sdlFlags |= SDL_INIT_NOPARACHUTE;
if (joystick_num > -1)
sdlFlags |= SDL_INIT_JOYSTICK;
if (SDL_Init(sdlFlags) == -1) {
error("Could not initialize SDL: %s", SDL_GetError());
}
// TODO: Clean way of flushing the file on every write without resorting to this or hacking the POSIX FS code.
//system("/bin/mount -t vfat -o remount,sync,iocharset=utf8 /dev/mmcsd/disc0/part1 /mnt/sd");
_graphicsMutex = createMutex();
_cksumValid = false;
_mode = GFX_NORMAL;
_scaleFactor = 0;
_scalerProc = Normal1x;
_fullscreen = true;
_adjustAspectRatio = ConfMan.getBool("aspect_ratio");
_scalerType = 0;
_modeFlags = 0;
_adjustZoomOnMouse = false;
ConfMan.setBool("FM_low_quality", true);
// enable joystick
if (joystick_num > -1 && SDL_NumJoysticks() > 0) {
printf("Using joystick: %s\n", SDL_JoystickName(0));
_joystick = SDL_JoystickOpen(joystick_num);
}
// Initialise any GP2X specific stuff we may want (Volume, Batt Status etc.)
GP2X_device_init();
// Set Default hardware mixer volume to a plesent level.
// This is done to 'reset' volume level if set by other apps.
GP2X_mixer_set_volume(70, 70);
SDL_ShowCursor(SDL_DISABLE);
_inited = true;
}
OSystem_GP2X::OSystem_GP2X()
:
_osdSurface(0), _osdAlpha(SDL_ALPHA_TRANSPARENT), _osdFadeStartTime(0),
_hwscreen(0), _screen(0), _screenWidth(0), _screenHeight(0),
_tmpscreen(0), _overlayWidth(0), _overlayHeight(0),
_overlayVisible(false),
_overlayscreen(0), _tmpscreen2(0),
_samplesPerSec(0),
_cdrom(0), _scalerProc(0), _modeChanged(false), _screenChangeCount(0), _dirtyChecksums(0),
_mouseVisible(false), _mouseDrawn(false), _mouseData(0), _mouseSurface(0),
_mouseOrigSurface(0), _cursorTargetScale(1), _cursorPaletteDisabled(true),
_joystick(0),
_currentShakePos(0), _newShakePos(0),
_paletteDirtyStart(0), _paletteDirtyEnd(0),
_graphicsMutex(0), _transactionMode(kTransactionNone) {
// allocate palette storage
_currentPalette = (SDL_Color *)calloc(sizeof(SDL_Color), 256);
_cursorPalette = (SDL_Color *)calloc(sizeof(SDL_Color), 256);
_mouseBackup.x = _mouseBackup.y = _mouseBackup.w = _mouseBackup.h = 0;
// reset mouse state
memset(&_km, 0, sizeof(_km));
memset(&_mouseCurState, 0, sizeof(_mouseCurState));
_inited = false;
}
OSystem_GP2X::~OSystem_GP2X() {
free(_dirtyChecksums);
free(_currentPalette);
free(_cursorPalette);
free(_mouseData);
}
uint32 OSystem_GP2X::getMillis() {
return SDL_GetTicks();
}
void OSystem_GP2X::delayMillis(uint msecs) {
SDL_Delay(msecs);
}
void OSystem_GP2X::setTimerCallback(TimerProc callback, int timer) {
SDL_SetTimer(timer, (SDL_TimerCallback) callback);
}
bool OSystem_GP2X::hasFeature(Feature f) {
return
(f == kFeatureFullscreenMode) ||
(f == kFeatureAspectRatioCorrection) ||
(f == kFeatureAutoComputeDirtyRects) ||
(f == kFeatureCursorHasPalette);
}
void OSystem_GP2X::setFeatureState(Feature f, bool enable) {
switch (f) {
case kFeatureFullscreenMode:
return;
case kFeatureAspectRatioCorrection:
setAspectRatioCorrection(enable);
break;
case kFeatureAutoComputeDirtyRects:
if (enable)
_modeFlags |= DF_WANT_RECT_OPTIM;
else
_modeFlags &= ~DF_WANT_RECT_OPTIM;
break;
default:
break;
}
}
bool OSystem_GP2X::getFeatureState(Feature f) {
assert (_transactionMode == kTransactionNone);
switch (f) {
case kFeatureFullscreenMode:
return false;
//case kFeatureFullscreenMode:
// return _fullscreen;
case kFeatureAspectRatioCorrection:
return _adjustAspectRatio;
case kFeatureAutoComputeDirtyRects:
return _modeFlags & DF_WANT_RECT_OPTIM;
default:
return false;
}
}
void OSystem_GP2X::quit() {
unloadGFXMode();
deleteMutex(_graphicsMutex);
if (_joystick)
SDL_JoystickClose(_joystick);
//CloseRam();
GP2X_device_deinit();
SDL_Quit();
chdir("/usr/gp2x");
execl("/usr/gp2x/gp2xmenu", "/usr/gp2x/gp2xmenu", NULL);
}
OSystem::MutexRef OSystem_GP2X::createMutex(void) {
return (MutexRef) SDL_CreateMutex();
}
void OSystem_GP2X::lockMutex(MutexRef mutex) {
SDL_mutexP((SDL_mutex *) mutex);
}
void OSystem_GP2X::unlockMutex(MutexRef mutex) {
SDL_mutexV((SDL_mutex *) mutex);
}
void OSystem_GP2X::deleteMutex(MutexRef mutex) {
SDL_DestroyMutex((SDL_mutex *) mutex);
}
#pragma mark -
#pragma mark --- Audio ---
#pragma mark -
bool OSystem_GP2X::setSoundCallback(SoundProc proc, void *param) {
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;
//Quick EVIL Hack - DJWillis
_samplesPerSec = 11025;
desired.freq = _samplesPerSec;
desired.format = AUDIO_S16SYS;
desired.channels = 2;
//desired.samples = (uint16)samples;
desired.samples = 128; // Samples hack
desired.callback = proc;
desired.userdata = param;
if (SDL_OpenAudio(&desired, &obtained) != 0) {
warning("Could not open audio device: %s", SDL_GetError());
return false;
}
_samplesPerSec = obtained.freq;
SDL_PauseAudio(0);
return true;
}
void OSystem_GP2X::clearSoundCallback() {
SDL_CloseAudio();
}
int OSystem_GP2X::getOutputSampleRate() const {
return _samplesPerSec;
}
#pragma mark -
#pragma mark --- CD Audio ---
#pragma mark -
bool OSystem_GP2X::openCD(int drive) {
return (_cdrom = NULL);
}
void OSystem_GP2X::stopCD() {
}
void OSystem_GP2X::playCD(int track, int num_loops, int start_frame, int duration) {
return;
}
bool OSystem_GP2X::pollCD() {
return false;
}
void OSystem_GP2X::updateCD() {
return;
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,15 @@
MODULE := backends/platform/gp2x
MODULE_OBJS := \
gp2x-hw.o \
gp2x-mem.o \
events.o \
graphics.o \
gp2x.o
# overload_help.o
MODULE_DIRS += \
backends/platform/gp2x/
# We don't use the common.rules here on purpose
OBJS := $(addprefix $(MODULE)/, $(MODULE_OBJS)) $(OBJS)

View file

@ -89,7 +89,7 @@ ConfigManager::ConfigManager()
void ConfigManager::loadDefaultConfigFile() {
char configFile[MAXPATHLEN];
#if defined(UNIX)
#if defined(UNIX) && !defined(GP2X) // GP2X is Linux based but Home dir can be read only so do not use it and put the config in the executable dir.
const char *home = getenv("HOME");
if (home != NULL && strlen(home) < MAXPATHLEN)
snprintf(configFile, MAXPATHLEN, "%s/%s", home, DEFAULT_CONFIG_FILE);
@ -335,7 +335,7 @@ void ConfigManager::writeDomain(FILE *file, const String &name, const Domain &do
const ConfigManager::Domain *ConfigManager::getDomain(const String &domName) const {
assert(!domName.empty());
assert(isValidDomainName(domName));
if (domName == kTransientDomain)
return &_transientDomain;
if (domName == kApplicationDomain)
@ -349,7 +349,7 @@ const ConfigManager::Domain *ConfigManager::getDomain(const String &domName) con
ConfigManager::Domain *ConfigManager::getDomain(const String &domName) {
assert(!domName.empty());
assert(isValidDomainName(domName));
if (domName == kTransientDomain)
return &_transientDomain;
if (domName == kApplicationDomain)
@ -527,7 +527,7 @@ void ConfigManager::set(const String &key, const String &value, const String &do
key.c_str(), value.c_str(), domName.c_str());
(*domain)[key] = value;
// TODO/FIXME: We used to erase the given key from the transient domain
// here. Do we still want to do that?
// It was probably there to simplify the options dialogs code:

29
configure vendored
View file

@ -303,7 +303,7 @@ Usage: $0 [OPTIONS]...
Configuration:
-h, --help display this help and exit
--backend=BACKEND backend to build (sdl, x11, morphos, dc, gp32, null) [sdl]
--backend=BACKEND backend to build (sdl, x11, morphos, dc, gp32, gp2x, null) [sdl]
Installation directories:
--prefix=DIR use this prefix for installing ScummVM [/usr/local]
@ -527,6 +527,10 @@ ppc-amigaos)
_host_os=amigaos
_host_cpu=ppc
;;
gp2x)
_host_os=gp2x-linux
_host_cpu=arm
;;
*)
guessed_host=`$_srcdir/config.guess`
_host_cpu=`echo $guessed_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
@ -545,6 +549,9 @@ mingw* | cygwin* | os2-emx*)
arm-riscos)
EXEEXT=",ff8"
;;
gp2x-linux)
EXEEXT=".gpe"
;;
*)
EXEEXT=""
;;
@ -704,6 +711,18 @@ if test -n "$_host"; then
type_2_byte='short'
type_4_byte='int'
;;
gp2x)
echo "Cross-compiling to $_host, forcing endianness, alignment and type sizes"
DEFINES="$DEFINES -DUNIX -DGP2X"
_def_endianness='#define SCUMM_LITTLE_ENDIAN'
_def_align='#define SCUMM_NEED_ALIGNMENT'
type_1_byte='char'
type_2_byte='short'
type_4_byte='int'
_backend="gp2x"
_mak_hq_scalers='DISABLE_HQ_SCALERS = 1'
_build_hq_scalers="no"
;;
ppc-amigaos)
echo "Cross-compiling to $_host, forcing endianness, alignment and type sizes"
_def_endianness='#define SCUMM_BIG_ENDIAN'
@ -1288,6 +1307,14 @@ case $_backend in
LIBS="$LIBS `$_sdlconfig --libs`"
MODULES="$MODULES backends/platform/sdl"
;;
gp2x)
find_sdlconfig
INCLUDES="$INCLUDES `$_sdlconfig --cflags`"
LIBS="$LIBS `$_sdlconfig --libs`"
LDFLAGS="$LDFLAGS -static"
CXXFLAGS="$CXXFLAGS -march=armv4t"
MODULES="$MODULES backends/platform/gp2x"
;;
x11)
INCLUDES="$INCLUDES -I/usr/X11R6/include"
LIBS="$LIBS -lpthread -lXext -lX11"

View file

@ -35,7 +35,7 @@
#include "common/util.h"
#if defined (_WIN32_WCE) || defined (__SYMBIAN32__) || defined(PALMOS_MODE) || defined(__GP32__) || defined (__MAEMO__) || defined(__DS__)
#if defined (_WIN32_WCE) || defined (__SYMBIAN32__) || defined(PALMOS_MODE) || defined(__GP32__) || defined(__GP2X__) || defined (__MAEMO__) || defined(__DS__)
#include "common/config-manager.h"
#endif
@ -477,7 +477,7 @@ inline void OPL_CALC_CH(OPL_CH *CH) {
env_out=OPL_CALC_SLOT(SLOT);
if(env_out < (uint)(EG_ENT - 1)) {
/* PG */
if(SLOT->vib)
if(SLOT->vib)
SLOT->Cnt += (SLOT->Incr * vib / VIB_RATE);
else
SLOT->Cnt += SLOT->Incr;
@ -512,7 +512,7 @@ inline void OPL_CALC_CH(OPL_CH *CH) {
inline void OPL_CALC_RH(OPL_CH *CH) {
uint env_tam, env_sd, env_top, env_hh;
int whitenoise = int(oplRnd.getRandomNumber(1) * (WHITE_NOISE_db / EG_STEP));
int tone8;
OPL_SLOT *SLOT;
@ -609,7 +609,7 @@ static void init_timetables(FM_OPL *OPL, int ARRATE, int DRRATE) {
OPL->AR_TABLE[i] = OPL->DR_TABLE[i] = 0;
for (i = 4; i <= 60; i++) {
rate = OPL->freqbase; /* frequency rate */
if(i < 60)
if(i < 60)
rate *= 1.0 + (i & 3) * 0.25; /* b0-1 : x1 , x1.25 , x1.5 , x1.75 */
rate *= 1 << ((i >> 2) - 1); /* b2-5 : shift bit */
rate *= (double)(EG_ENT << ENV_BITS);
@ -1177,7 +1177,7 @@ FM_OPL *makeAdlibOPL(int rate) {
// We need to emulate one YM3812 chip
int env_bits = FMOPL_ENV_BITS_HQ;
int eg_ent = FMOPL_EG_ENT_HQ;
#if defined (_WIN32_WCE) || defined(__SYMBIAN32__) || defined(PALMOS_MODE) || defined(__GP32__) || defined(__MAEMO__) || defined(__DS__)
#if defined (_WIN32_WCE) || defined(__SYMBIAN32__) || defined(PALMOS_MODE) || defined(__GP32__) || defined (GP2X) || defined(__MAEMO__) || defined(__DS__)
if (ConfMan.hasKey("FM_high_quality") && ConfMan.getBool("FM_high_quality")) {
env_bits = FMOPL_ENV_BITS_HQ;
eg_ent = FMOPL_EG_ENT_HQ;