517 lines
13 KiB
C++
517 lines
13 KiB
C++
/* ScummVM - Scumm Interpreter
|
||
* Copyright (C) 2001 Ludvig Strigeus
|
||
* Copyright (C) 2001-2006 The ScummVM project
|
||
* Copyright (C) 2002-2006 Chris Apers - PalmOS 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$
|
||
*
|
||
*/
|
||
|
||
#include <PalmOS.h>
|
||
#include "StarterRsc.h"
|
||
|
||
#include "games.h"
|
||
#include "start.h"
|
||
#include "rumble.h"
|
||
#include "extend.h"
|
||
#include "globals.h"
|
||
#include "features.h"
|
||
#include "formUtil.h"
|
||
#include "formCards.h"
|
||
#include "palmdefs.h"
|
||
|
||
#include "init_palmos.h"
|
||
#include "init_stuffs.h"
|
||
|
||
#include "modules.h"
|
||
#include "args.h"
|
||
|
||
|
||
#define BUILD_ERROR(m) \
|
||
{ StrCopy(msg, m); \
|
||
StrCat(msg, "\n\nPlease check that all required files are installed on your card, and you have enough free storage memory."); \
|
||
goto onError; }
|
||
|
||
#define BUILD_FILE(h,m) \
|
||
StrCopy(filename, "/Palm/Programs/ScummVM/Mods/"); \
|
||
StrCat(filename, h); \
|
||
StrCat(filename, m);
|
||
|
||
#define CHECK_FILE(m) \
|
||
e = VFSFileOpen(volRefNum, filename, vfsModeRead, &file); \
|
||
if (e) \
|
||
BUILD_ERROR(m) \
|
||
else \
|
||
VFSFileClose(file);
|
||
|
||
#define IMPRT_FILE(m) \
|
||
e = VFSImportDatabaseFromFile(volRefNum, filename, &cardNo, &dbID); \
|
||
if (e) \
|
||
BUILD_ERROR(m)
|
||
|
||
#define DELET_FILE(f) \
|
||
del_dbID = DmFindDatabase(0, f); \
|
||
if (del_dbID) \
|
||
DmDeleteDatabase(0, del_dbID);
|
||
|
||
void ModDelete() {
|
||
LocalID del_dbID;
|
||
|
||
DELET_FILE("Glbs::Common");
|
||
DELET_FILE("Glbs::Engine");
|
||
DELET_FILE("ScummVM-Engine");
|
||
}
|
||
|
||
static void ModSetStack(UInt32 newSize, UInt16 cardNo, LocalID dbID) {
|
||
DmOpenRef dbRef = DmOpenDatabase(cardNo, dbID, dmModeReadWrite);
|
||
|
||
if (dbRef) {
|
||
MemHandle pref = DmGetResource('pref',0);
|
||
UInt32 size = 0;
|
||
|
||
if (pref) {
|
||
SysAppPrefsType *data = (SysAppPrefsType *)MemHandleLock(pref);
|
||
size = data->stackSize;
|
||
|
||
if (newSize) {
|
||
SysAppPrefsType newData;
|
||
MemMove(&newData, data, sizeof(SysAppPrefsType));
|
||
newData.stackSize = newSize;
|
||
DmWrite(data, 0, &newData, sizeof(SysAppPrefsType));
|
||
}
|
||
|
||
MemPtrUnlock(data);
|
||
DmReleaseResource(pref);
|
||
}
|
||
|
||
DmCloseDatabase(dbRef);
|
||
}
|
||
}
|
||
|
||
static Err ModImport(UInt16 volRefNum, UInt8 engine, Boolean *armP) {
|
||
#ifndef _DEBUG_ENGINE
|
||
char filename[256];
|
||
UInt16 cardNo;
|
||
LocalID dbID;
|
||
UInt32 result;
|
||
FileRef file;
|
||
#endif
|
||
char msg[256];
|
||
FormPtr ofmP, frmP;
|
||
Err e = errNone;
|
||
|
||
ofmP = FrmGetActiveForm();
|
||
frmP = FrmInitForm(ImportForm);
|
||
FrmSetActiveForm(frmP);
|
||
FrmDrawForm(frmP);
|
||
|
||
// In debug mode, the engine files are directly uploaded to the simulator
|
||
#ifndef _DEBUG_ENGINE
|
||
// engine file ?
|
||
BUILD_FILE(engines[engine].fileP, ".engine");
|
||
CHECK_FILE("ScummVM engine file was not found !");
|
||
IMPRT_FILE("Cannot import engine file !");
|
||
|
||
// need more files ?
|
||
dbID = DmFindDatabase(0, "ScummVM-Engine"); // be sure to have the correct dbID
|
||
e = SysAppLaunch(cardNo, dbID, 0, sysAppLaunchCustomEngineGetInfo, 0, &result);
|
||
*armP = ((result & GET_MODEARM) == GET_MODEARM);
|
||
|
||
// common file ?
|
||
if (!e && (result & GET_DATACOMMON)) {
|
||
BUILD_FILE("common", ".data");
|
||
CHECK_FILE("Common data file was not found !");
|
||
IMPRT_FILE("Cannot import common data file !");
|
||
}
|
||
// data file ?
|
||
if (!e && (result & GET_DATAENGINE)) {
|
||
BUILD_FILE(engines[engine].fileP, ".data");
|
||
CHECK_FILE("Engine data file was not found !");
|
||
IMPRT_FILE("Cannot import engine data file !");
|
||
}
|
||
#endif
|
||
// if error, cleanup
|
||
if (e) ModDelete();
|
||
|
||
onError:
|
||
FrmEraseForm(frmP);
|
||
FrmDeleteForm(frmP);
|
||
if (e) {
|
||
if (ofmP) FrmSetActiveForm(ofmP);
|
||
FrmCustomAlert(FrmErrorAlert, msg, 0, 0);
|
||
}
|
||
|
||
return e;
|
||
}
|
||
|
||
#undef DELET_FILE
|
||
#undef CHECK_FILE
|
||
#undef BUILD_FILE
|
||
|
||
Boolean StartScummVM() {
|
||
Char **argvP;
|
||
UInt8 lightspeed, argc = 0;
|
||
UInt32 stackSize;
|
||
Boolean toLauncher, direct, isARM;
|
||
UInt8 engine;
|
||
Char num[6];
|
||
|
||
UInt16 index = GamGetSelected();
|
||
|
||
argvP = ArgsInit();
|
||
direct = false;
|
||
|
||
// start command line (exec name)
|
||
ArgsAdd(&argvP[argc], "-", NULL, &argc);
|
||
|
||
// no game selected
|
||
if (index == dmMaxRecordIndex) {
|
||
ListPtr listP;
|
||
UInt16 whichButton;
|
||
|
||
// init form
|
||
FormPtr frmP = FrmInitForm(EngineForm);
|
||
listP = (ListType *)FrmGetObjectPtr(frmP, FrmGetObjectIndex(frmP, EngineListList));
|
||
itemsText = (Char **)MemPtrNew(ENGINE_COUNT * sizeof(Char *));
|
||
|
||
for (int i = 0; i < ENGINE_COUNT; i++)
|
||
itemsText[i] = (Char *)engines[i].nameP;
|
||
|
||
LstSetListChoices (listP, itemsText, ENGINE_COUNT);
|
||
LstSetSelection(listP, 0);
|
||
|
||
whichButton = FrmDoDialog(frmP);
|
||
engine = LstGetSelection(listP);
|
||
|
||
FrmDeleteForm(frmP);
|
||
MemPtrFree(itemsText);
|
||
itemsText = NULL;
|
||
|
||
if (whichButton == EngineCancelButton) {
|
||
if (bDirectMode) {
|
||
// and force exit if nothing selected
|
||
EventType event;
|
||
event.eType = keyDownEvent;
|
||
event.data.keyDown.chr = vchrLaunch;
|
||
event.data.keyDown.modifiers = commandKeyMask;
|
||
EvtAddUniqueEventToQueue(&event, 0, true);
|
||
}
|
||
// free args
|
||
ArgsFree(argvP);
|
||
return false;
|
||
}
|
||
|
||
// default values
|
||
if (bDirectMode)
|
||
gPrefs->card.volRefNum = parseCards(); // always use the first removable card available (?)
|
||
gVars->filter = true;
|
||
gVars->palmVolume = 50;
|
||
gVars->fmQuality = FM_QUALITY_INI;
|
||
direct = true;
|
||
|
||
// somthing selected
|
||
} else {
|
||
Char pathP[256];
|
||
MemHandle recordH;
|
||
GameInfoType *gameInfoP;
|
||
|
||
recordH = DmQueryRecord(gameDB,index);
|
||
gameInfoP = (GameInfoType *)MemHandleLock(recordH);
|
||
engine = gameInfoP->engine;
|
||
|
||
// build path
|
||
StrCopy(pathP,"/Palm/Programs/ScummVM/Games/");
|
||
if (gameInfoP->pathP[0] == '/')
|
||
StrCopy(pathP, gameInfoP->pathP);
|
||
else if (!(gameInfoP->pathP[0] == '.' && StrLen(gameInfoP->pathP) == 1))
|
||
StrCat(pathP, gameInfoP->pathP);
|
||
|
||
// path
|
||
ArgsAdd(&argvP[argc], "-p", pathP, &argc);
|
||
|
||
// language
|
||
if (gameInfoP->language > 0) {
|
||
const Char *lang = "zh\0cz\0gb\0en\0fr\0de\0hb\0it\0jp\0kr\0pl\0pt\0ru\0es\0se\0";
|
||
ArgsAdd(&argvP[argc], "-q", (lang + (gameInfoP->language - 1) * 3), &argc);
|
||
}
|
||
|
||
// fullscreen ?
|
||
if (gameInfoP->fullscreen)
|
||
ArgsAdd(&argvP[argc], "-f", NULL, &argc);
|
||
|
||
// aspect-ratio ?
|
||
ArgsAdd(&argvP[argc], (gameInfoP->aspectRatio ? "--aspect-ratio" : "--no-aspect-ratio"), NULL, &argc);
|
||
|
||
// gfx mode
|
||
gVars->filter = gameInfoP->filter;
|
||
|
||
switch (gameInfoP->renderMode) {
|
||
case 1:
|
||
ArgsAdd(&argvP[argc], "--render-mode=", "amiga", &argc);
|
||
break;
|
||
case 2:
|
||
ArgsAdd(&argvP[argc], "--render-mode=", "cga", &argc);
|
||
break;
|
||
case 3:
|
||
ArgsAdd(&argvP[argc], "--render-mode=", "ega", &argc);
|
||
break;
|
||
case 4:
|
||
ArgsAdd(&argvP[argc], "--render-mode=", "hercAmber", &argc);
|
||
break;
|
||
case 5:
|
||
ArgsAdd(&argvP[argc], "--render-mode=", "hercGreen", &argc);
|
||
break;
|
||
}
|
||
|
||
switch (gameInfoP->gfxMode) {
|
||
case 1:
|
||
ArgsAdd(&argvP[argc], "-g", "wide", &argc);
|
||
break;
|
||
default:
|
||
ArgsAdd(&argvP[argc], "-g", "1x", &argc);
|
||
break;
|
||
}
|
||
|
||
// load state
|
||
if (gameInfoP->autoLoad) {
|
||
StrIToA(num, gameInfoP->loadSlot);
|
||
ArgsAdd(&argvP[argc], "-x", num, &argc);
|
||
}
|
||
// boot script parameter
|
||
if (gameInfoP->bootParam) {
|
||
StrIToA(num, gameInfoP->bootValue);
|
||
ArgsAdd(&argvP[argc], "-b", num, &argc);
|
||
}
|
||
// not a PC version
|
||
if (gameInfoP->setPlatform) {
|
||
static const char *platform[] = {
|
||
"3do",
|
||
"acorn",
|
||
"amiga",
|
||
"atari",
|
||
"c64",
|
||
"pc",
|
||
"fmtowns",
|
||
"linux",
|
||
"mac",
|
||
"nes",
|
||
"segacd",
|
||
"windows"
|
||
};
|
||
ArgsAdd(&argvP[argc], "--platform=", platform[gameInfoP->platform], &argc);
|
||
}
|
||
|
||
// subtitles
|
||
if (gameInfoP->subtitles)
|
||
ArgsAdd(&argvP[argc], "-n", NULL, &argc);
|
||
|
||
// multi midi ?
|
||
if (gameInfoP->musicInfo.sound.multiMidi)
|
||
ArgsAdd(&argvP[argc], "--multi-midi", NULL, &argc);
|
||
|
||
if (engine == ENGINE_SCUMM) {
|
||
// music tempo
|
||
StrIToA(num, gameInfoP->musicInfo.sound.tempo);
|
||
ArgsAdd(&argvP[argc], "--tempo=", num, &argc);
|
||
}
|
||
|
||
// talk speed
|
||
if (gameInfoP->talkSpeed) {
|
||
StrIToA(num, gameInfoP->talkValue);
|
||
ArgsAdd(&argvP[argc], "--talkspeed=", num, &argc);
|
||
}
|
||
|
||
// music driver
|
||
if (gameInfoP->musicInfo.sound.music) {
|
||
static char *drv[] = {
|
||
"auto",
|
||
"null",
|
||
"adlib",
|
||
"towns",
|
||
"pcjr",
|
||
"native",
|
||
"pcspk"
|
||
};
|
||
|
||
if (StrCompare(drv[gameInfoP->musicInfo.sound.drvMusic], "native") == 0) {
|
||
if (OPTIONS_TST(kOptDeviceZodiac))
|
||
ArgsAdd(&argvP[argc], "-e", "zodiac", &argc); // Tapwave Zodiac
|
||
else if (OPTIONS_TST(kOptSonyPa1LibAPI))
|
||
ArgsAdd(&argvP[argc], "-e", "ypa1", &argc); // Pa1Lib devices
|
||
else
|
||
ArgsAdd(&argvP[argc], "-e", "auto", &argc); // no driver, switch to auto
|
||
} else {
|
||
ArgsAdd(&argvP[argc], "-e", drv[gameInfoP->musicInfo.sound.drvMusic], &argc);
|
||
}
|
||
|
||
// output rate
|
||
UInt32 rates[] = {4000, 8000, 11025, 22050, 44100};
|
||
StrIToA(num, rates[gameInfoP->musicInfo.sound.rate]);
|
||
ArgsAdd(&argvP[argc], "--output-rate=", num, &argc);
|
||
|
||
// FM quality
|
||
gVars->fmQuality = gameInfoP->fmQuality;
|
||
|
||
} else {
|
||
ArgsAdd(&argvP[argc], "-e", "null", &argc);
|
||
}
|
||
|
||
// volume control
|
||
StrIToA(num, gameInfoP->musicInfo.volume.sfx);
|
||
ArgsAdd(&argvP[argc], "-s", num, &argc);
|
||
StrIToA(num, gameInfoP->musicInfo.volume.music);
|
||
ArgsAdd(&argvP[argc], "-m", num, &argc);
|
||
StrIToA(num, gameInfoP->musicInfo.volume.speech);
|
||
ArgsAdd(&argvP[argc], "-r", num, &argc);
|
||
|
||
// game name
|
||
ArgsAdd(&argvP[argc], gameInfoP->gameP, NULL, &argc);
|
||
|
||
// others globals data
|
||
gVars->CD.enable = gameInfoP->musicInfo.sound.CD;
|
||
gVars->CD.driver = gameInfoP->musicInfo.sound.drvCD;
|
||
gVars->CD.format = gameInfoP->musicInfo.sound.frtCD;
|
||
gVars->CD.volume = gameInfoP->musicInfo.volume.audiocd;
|
||
gVars->CD.defaultTrackLength = gameInfoP->musicInfo.sound.defaultTrackLength;
|
||
gVars->CD.firstTrack = gameInfoP->musicInfo.sound.firstTrack;
|
||
gVars->palmVolume = gameInfoP->musicInfo.sound.music ? gameInfoP->musicInfo.volume.palm : 0;
|
||
|
||
MemHandleUnlock(recordH);
|
||
} // end no game / game selected
|
||
|
||
// common command line options
|
||
|
||
// debug level
|
||
if (gPrefs->debug) {
|
||
StrIToA(num, gPrefs->debugLevel);
|
||
ArgsAdd(&argvP[argc], "-d", num, &argc);
|
||
}
|
||
|
||
if (engine == ENGINE_QUEEN || engine == ENGINE_SKY) {
|
||
// alternative intro ?
|
||
if (gPrefs->altIntro)
|
||
ArgsAdd(&argvP[argc], "--alt-intro", NULL, &argc);
|
||
}
|
||
|
||
if (engine == ENGINE_SCUMM) {
|
||
// demo mode ?
|
||
if (gPrefs->demoMode)
|
||
ArgsAdd(&argvP[argc], "--demo-mode", NULL, &argc);
|
||
}
|
||
|
||
// copy protection ?
|
||
if (gPrefs->copyProtection)
|
||
ArgsAdd(&argvP[argc], "--copy-protection", NULL, &argc);
|
||
|
||
// exceed max args ?
|
||
if (argc > MAX_ARG)
|
||
FrmCustomAlert(FrmErrorAlert, "Too many parameters.",0,0);
|
||
|
||
// set some common options
|
||
stackSize = (gPrefs->setStack ? STACK_LARGER : STACK_DEFAULT);
|
||
lightspeed= (gPrefs->lightspeed.enable ? gPrefs->lightspeed.mode : 255);
|
||
toLauncher= (gPrefs->exitLauncher);
|
||
|
||
// gVars values
|
||
// (gVars->HRrefNum defined in checkHRmode on Cli<6C>)
|
||
gVars->VFS.volRefNum = gPrefs->card.volRefNum;
|
||
gVars->vibrator = gPrefs->vibrator;
|
||
gVars->stdPalette = gPrefs->stdPalette;
|
||
gVars->VFS.cacheSize = (gPrefs->card.useCache ? gPrefs->card.cacheSize : 0);
|
||
gVars->indicator.showLED= gPrefs->card.showLED;
|
||
gVars->stylusClick = gPrefs->stylusClick;
|
||
gVars->autoSave = (gPrefs->autoSave ? gPrefs->autoSavePeriod : -1);
|
||
gVars->advancedMode = gPrefs->advancedMode;
|
||
gVars->arrowKeys = gPrefs->arrowKeys;
|
||
|
||
// user params
|
||
HWR_RSTALL();
|
||
|
||
if (gPrefs->goLCD)
|
||
HWR_SET(INIT_GOLCD);
|
||
else
|
||
OPTIONS_RST(kOptGoLcdAPI);
|
||
|
||
if (!gPrefs->autoOff)
|
||
HWR_SET(INIT_AUTOOFF);
|
||
|
||
if (gVars->vibrator)
|
||
HWR_SET(INIT_VIBRATOR);
|
||
/* ????
|
||
if ( musicDriver == 1 ||
|
||
musicDriver == 3 ||
|
||
musicDriver == 4 ||
|
||
musicDriver == sysInvalidRefNum) {
|
||
HWR_SET(INIT_PA1LIB);
|
||
}
|
||
*/
|
||
if (ModImport(gVars->VFS.volRefNum, engine, &isARM) != errNone) {
|
||
if (bDirectMode) {
|
||
// and force exit if nothing selected
|
||
EventType event;
|
||
event.eType = keyDownEvent;
|
||
event.data.keyDown.chr = vchrLaunch;
|
||
event.data.keyDown.modifiers = commandKeyMask;
|
||
EvtAddUniqueEventToQueue(&event, 0, true);
|
||
}
|
||
ArgsFree(argvP);
|
||
return false;
|
||
}
|
||
|
||
// reset mode if screen rotation occured (DIA only)
|
||
if (!direct && OPTIONS_TST(kOptCollapsible)) {
|
||
UInt8 mode = PalmScreenSize(0,0, &(gVars->screenFullWidth), &(gVars->screenFullHeight));
|
||
OPTIONS_RST(kOptModeLandscape);
|
||
OPTIONS_SET((mode == PALM_LANDSCAPE) ? kOptModeLandscape : kOptNone);
|
||
}
|
||
|
||
// free and save globals pref memory
|
||
GamCloseDatabase(false);
|
||
FrmCloseAllForms();
|
||
SavePrefs();
|
||
|
||
{
|
||
UInt16 cardNo;
|
||
UInt32 dbID;
|
||
|
||
LaunchParamType *cmdPBP = (LaunchParamType *)MemPtrNew(sizeof(LaunchParamType));
|
||
|
||
MemPtrSetOwner(cmdPBP, 0);
|
||
MemPtrSetOwner(gVars, 0);
|
||
ArgsSetOwner(argvP, 0);
|
||
|
||
cardNo = 0;
|
||
dbID = DmFindDatabase(0, "ScummVM-Engine");
|
||
|
||
if (isARM)
|
||
FtrSet(appFileCreator, ftrStack , (stackSize * 4));
|
||
else
|
||
ModSetStack(stackSize, cardNo, dbID);
|
||
|
||
cmdPBP->args.argc = argc;
|
||
cmdPBP->args.argv = argvP;
|
||
cmdPBP->gVars = gVars;
|
||
cmdPBP->lightspeed = lightspeed;
|
||
cmdPBP->exitLauncher = toLauncher;
|
||
|
||
SysUIAppSwitch(cardNo, dbID, sysAppLaunchCmdNormalLaunch, cmdPBP);
|
||
bLaunched = true;
|
||
}
|
||
|
||
return false;
|
||
}
|