mirror of
https://github.com/scummvm/scummvm.git
synced 2025-04-02 10:52:32 -04:00
1068 lines
34 KiB
C++
1068 lines
34 KiB
C++
/* ScummVM - Graphic Adventure Engine
|
|
*
|
|
* ScummVM is the legal property of its developers, whose names
|
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
|
* file distributed with this source distribution.
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 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, see <http://www.gnu.org/licenses/>.
|
|
*
|
|
*/
|
|
|
|
#include "common/config-manager.h"
|
|
|
|
#include "twp/twp.h"
|
|
#include "twp/callback.h"
|
|
#include "twp/dialog.h"
|
|
#include "twp/object.h"
|
|
#include "twp/resmanager.h"
|
|
#include "twp/room.h"
|
|
#include "twp/savegame.h"
|
|
#include "twp/sqgame.h"
|
|
#include "twp/squtil.h"
|
|
#include "twp/task.h"
|
|
#include "twp/thread.h"
|
|
#include "twp/squirrel/sqvm.h"
|
|
#include "twp/squirrel/sqstring.h"
|
|
#include "twp/squirrel/sqstate.h"
|
|
#include "twp/squirrel/sqtable.h"
|
|
#include "twp/squirrel/sqfuncproto.h"
|
|
#include "twp/squirrel/sqclosure.h"
|
|
|
|
namespace Twp {
|
|
|
|
static SQInteger _startthread(HSQUIRRELVM v, bool global) {
|
|
HSQUIRRELVM vm = g_twp->getVm();
|
|
SQInteger size = sq_gettop(v);
|
|
HSQOBJECT envObj, threadObj, closureObj;
|
|
|
|
sq_resetobject(&envObj);
|
|
if (SQ_FAILED(sq_getstackobj(v, 1, &envObj)))
|
|
return sq_throwerror(v, "Couldn't get environment from stack");
|
|
|
|
// create thread and store it on the stack
|
|
sq_newthread(vm, 1024);
|
|
sq_resetobject(&threadObj);
|
|
if (SQ_FAILED(sq_getstackobj(vm, -1, &threadObj)))
|
|
return sq_throwerror(v, "Couldn't get coroutine thread from stack");
|
|
|
|
Common::Array<HSQOBJECT> args;
|
|
for (int i = 0; i < size - 2; i++) {
|
|
HSQOBJECT arg;
|
|
sq_resetobject(&arg);
|
|
if (SQ_FAILED(sq_getstackobj(v, 3 + i, &arg)))
|
|
return sq_throwerror(v, "Couldn't get coroutine args from stack");
|
|
args.push_back(arg);
|
|
}
|
|
|
|
// get the closure
|
|
sq_resetobject(&closureObj);
|
|
if (SQ_FAILED(sq_getstackobj(v, 2, &closureObj)))
|
|
return sq_throwerror(v, "Couldn't get coroutine thread from stack");
|
|
|
|
const SQChar *name = nullptr;
|
|
if (SQ_SUCCEEDED(sq_getclosurename(v, 2)))
|
|
sq_getstring(v, -1, &name);
|
|
|
|
Common::String threadName = Common::String::format("%s %s (%lld)", name == nullptr ? "<anonymous>" : name, _stringval(_closure(closureObj)->_function->_sourcename), _closure(closureObj)->_function->_lineinfos->_line);
|
|
Common::SharedPtr<Thread> t(new Thread(threadName, global, threadObj, envObj, closureObj, Common::move(args)));
|
|
sq_pop(vm, 1);
|
|
if (name)
|
|
sq_pop(v, 1); // pop name
|
|
sq_pop(v, 1); // pop closure
|
|
|
|
g_twp->_threads.push_back(t);
|
|
|
|
debugC(kDebugSysScript, "create thread %s", t->getName().c_str());
|
|
|
|
// call the closure in the thread
|
|
if (!t->call())
|
|
return sq_throwerror(v, "call failed");
|
|
|
|
sqpush(v, t->getId());
|
|
return 1;
|
|
}
|
|
|
|
static SQInteger breakfunc(HSQUIRRELVM v, void func(Common::SharedPtr<ThreadBase> t, void *data), void *data) {
|
|
Common::SharedPtr<ThreadBase> thread(sqthread(v));
|
|
if (!thread)
|
|
return sq_throwerror(v, "failed to get thread");
|
|
thread->suspend();
|
|
func(thread, data);
|
|
return -666;
|
|
}
|
|
|
|
static SQInteger activeController(HSQUIRRELVM v) {
|
|
warning("TODO: activeController: not implemented");
|
|
// TODO: change harcoded mouse
|
|
sq_pushinteger(v, 1);
|
|
return 1;
|
|
}
|
|
|
|
// Sets a timer of duration seconds.
|
|
//
|
|
// When the timer is up, method will be executed.
|
|
// Use this method so that the callback will get saved.
|
|
// That is, if you set a callback to call method in 30 minutes, play the game for 10 minutes, save and quit;
|
|
// when you return to the game, it will remember that it needs to wait 20 minutes before calling method.
|
|
// If the game is paused, all callback timers are paused.
|
|
// Note, method cannot be code, it must be a defined script or function (otherwise, the game wouldn't be able to save what it needs to do when the timer is up).
|
|
// .. code-block:: Squirrel
|
|
// if (actorTalking()) {
|
|
// addCallback(30, doADance) // Wait another 30 seconds
|
|
// return
|
|
//}
|
|
static SQInteger addCallback(HSQUIRRELVM v) {
|
|
SQInteger count = sq_gettop(v);
|
|
float duration;
|
|
if (SQ_FAILED(sqget(v, 2, duration)))
|
|
return sq_throwerror(v, "failed to get duration");
|
|
HSQOBJECT meth;
|
|
sq_resetobject(&meth);
|
|
if (SQ_FAILED(sq_getstackobj(v, 3, &meth)) || !sq_isclosure(meth))
|
|
return sq_throwerror(v, "failed to get method");
|
|
|
|
Common::String methodName;
|
|
if (SQ_SUCCEEDED(sq_getclosurename(v, 3))) {
|
|
const SQChar *tmpMethodName;
|
|
sq_getstring(v, -1, &tmpMethodName);
|
|
methodName = tmpMethodName;
|
|
}
|
|
|
|
Common::Array<HSQOBJECT> args;
|
|
for (int i = 4; i <= count; i++) {
|
|
HSQOBJECT arg;
|
|
sq_resetobject(&arg);
|
|
if (SQ_FAILED(sq_getstackobj(v, i, &arg)))
|
|
return sq_throwerror(v, Common::String::format("failed to get argument %d", i).c_str());
|
|
args.push_back(arg);
|
|
}
|
|
|
|
Common::SharedPtr<Callback> callback(new Callback(g_twp->_resManager->newCallbackId(), duration, methodName, args));
|
|
g_twp->_callbacks.push_back(callback);
|
|
|
|
sqpush(v, callback->getId());
|
|
return 1;
|
|
}
|
|
|
|
// Registers a folder that assets can appear in.
|
|
//
|
|
// Only used for development builds where the assets are not bundled up.
|
|
// Use in the Boot.nut process.
|
|
// Not necessary for release.
|
|
static SQInteger addFolder(HSQUIRRELVM v) {
|
|
return 0;
|
|
}
|
|
|
|
static void threadFrames(Common::SharedPtr<ThreadBase> tb, void *data) {
|
|
int numFrames = *(int *)data;
|
|
tb->_numFrames = numFrames;
|
|
}
|
|
|
|
static void threadTime(Common::SharedPtr<ThreadBase> tb, void *data) {
|
|
float time = *(float *)data;
|
|
tb->_waitTime = time;
|
|
}
|
|
|
|
// When called in a function started with startthread, execution is suspended for count frames.
|
|
// It is an error to call breakhere in a function that was not started with startthread.
|
|
// Particularly useful instead of breaktime if you just want to wait 1 frame, since not all machines run at the same speed.
|
|
// . code-block:: Squirrel
|
|
// while(isSoundPlaying(soundPhoneBusy)) {
|
|
// breakhere(5)
|
|
//}
|
|
static SQInteger breakhere(HSQUIRRELVM v) {
|
|
SQObjectType t = sq_gettype(v, 2);
|
|
if (t == OT_INTEGER) {
|
|
SQInteger numFrames;
|
|
if (SQ_FAILED(sqget(v, 2, numFrames)))
|
|
return sq_throwerror(v, "failed to get numFrames");
|
|
return breakfunc(v, threadFrames, &numFrames);
|
|
}
|
|
if (t == OT_FLOAT) {
|
|
float time;
|
|
if (SQ_FAILED(sqget(v, 2, time)))
|
|
return sq_throwerror(v, "failed to get time");
|
|
return breakfunc(v, threadTime, &time);
|
|
}
|
|
return sq_throwerror(v, Common::String::format("failed to get numFrames (wrong type = {%d})", t).c_str());
|
|
}
|
|
|
|
// When called in a function started with startthread, execution is suspended for time seconds.
|
|
// It is an error to call breaktime in a function that was not started with startthread.
|
|
//
|
|
// . code-block:: Squirrel
|
|
// for (local x = 1; x < 4; x += 1) {
|
|
// playSound(soundPhoneRinging)
|
|
// breaktime(5.0)
|
|
// }
|
|
static SQInteger breaktime(HSQUIRRELVM v) {
|
|
SQFloat time;
|
|
if (SQ_FAILED(sq_getfloat(v, 2, &time)))
|
|
return sq_throwerror(v, "failed to get time");
|
|
// it can happen to have a negative time, in this case wait for 1 frame
|
|
if (time <= 0.f) {
|
|
int frame = 1;
|
|
return breakfunc(v, threadFrames, &frame);
|
|
}
|
|
return breakfunc(v, threadTime, &time);
|
|
}
|
|
|
|
template<typename Predicate>
|
|
static SQInteger breakwhilecond(HSQUIRRELVM v, Predicate pred, const char *fmt, ...) {
|
|
va_list va;
|
|
va_start(va, fmt);
|
|
Common::String name = Common::String::format(fmt, va);
|
|
va_end(va);
|
|
|
|
Common::SharedPtr<ThreadBase> curThread = sqthread(v);
|
|
if (!curThread)
|
|
return sq_throwerror(v, "Current thread should be created with startthread");
|
|
|
|
debugC(kDebugSysScript, "add breakwhilecond name=%s pid=%d, %s", name.c_str(), curThread->getId(), curThread->getName().c_str());
|
|
g_twp->_tasks.push_back(Common::SharedPtr<Task>(new BreakWhileCond<Predicate>(curThread->getId(), name, Common::move(pred))));
|
|
return SQ_SUSPEND_FLAG;
|
|
}
|
|
|
|
static bool isAnimating(Common::SharedPtr<Object> obj) {
|
|
return obj->_nodeAnim->_anim && !obj->_nodeAnim->_disabled && obj->_animName != obj->getAnimName(STAND_ANIMNAME);
|
|
}
|
|
|
|
struct ObjAnimating {
|
|
explicit ObjAnimating(Common::SharedPtr<Object> obj) : _obj(obj) {}
|
|
bool operator()() {
|
|
return isAnimating(_obj);
|
|
}
|
|
|
|
private:
|
|
Common::SharedPtr<Object> _obj;
|
|
};
|
|
|
|
// When called in a function started with startthread, execution is suspended until animatingItem has completed its animation.
|
|
// Note, animatingItem can be an actor or an object.
|
|
// It is an error to call breakwhileanimating in a function that was not started with `startthread`.
|
|
//
|
|
// . code-block:: Squirrel
|
|
// actorFace(ray, FACE_LEFT)
|
|
// actorCostume(ray, "RayVomit")
|
|
// actorPlayAnimation(ray, "vomit")
|
|
// breakwhileanimating(ray)
|
|
// actorCostume(ray, "RayAnimation")
|
|
static SQInteger breakwhileanimating(HSQUIRRELVM v) {
|
|
Common::SharedPtr<Object> obj = sqobj(v, 2);
|
|
if (!obj)
|
|
return sq_throwerror(v, "failed to get object");
|
|
return breakwhilecond(v, ObjAnimating(obj), "breakwhileanimating(%s)", obj->_key.c_str());
|
|
}
|
|
|
|
struct CameraMoving {
|
|
bool operator()() {
|
|
return g_twp->_camera->isMoving();
|
|
}
|
|
};
|
|
|
|
// Breaks while a camera is moving.
|
|
// Once the thread finishes execution, the method will continue running.
|
|
// It is an error to call breakwhilecamera in a function that was not started with startthread.
|
|
static SQInteger breakwhilecamera(HSQUIRRELVM v) {
|
|
return breakwhilecond(v, CameraMoving(), "breakwhilecamera()");
|
|
}
|
|
|
|
struct CutsceneRunning {
|
|
bool operator()() {
|
|
return g_twp->_cutscene != nullptr;
|
|
}
|
|
};
|
|
|
|
// Breaks while a cutscene is running.
|
|
// Once the thread finishes execution, the method will continue running.
|
|
// It is an error to call breakwhilecutscene in a function that was not started with startthread.
|
|
static SQInteger breakwhilecutscene(HSQUIRRELVM v) {
|
|
return breakwhilecond(v, CutsceneRunning(), "breakwhilecutscene()");
|
|
}
|
|
|
|
struct DialogRunning {
|
|
bool operator()() {
|
|
return g_twp->_dialog->getState() != DialogState::None;
|
|
}
|
|
};
|
|
|
|
// Breaks while a dialog is running.
|
|
// Once the thread finishes execution, the method will continue running.
|
|
// It is an error to call breakwhiledialog in a function that was not started with startthread.
|
|
static SQInteger breakwhiledialog(HSQUIRRELVM v) {
|
|
return breakwhilecond(v, DialogRunning(), "breakwhiledialog()");
|
|
}
|
|
|
|
struct InputOff {
|
|
bool operator()() {
|
|
return !g_twp->_inputState.getInputActive();
|
|
}
|
|
};
|
|
|
|
// Breaks while input is not active.
|
|
// Once the thread finishes execution, the method will continue running.
|
|
// It is an error to call breakwhileinputoff in a function that was not started with startthread.
|
|
static SQInteger breakwhileinputoff(HSQUIRRELVM v) {
|
|
return breakwhilecond(v, InputOff(), "breakwhileinputoff()");
|
|
}
|
|
|
|
// Breaks while the thread referenced by threadId is running.
|
|
// Once the thread finishes execution, the method will continue running.
|
|
// It is an error to call breakwhilerunning in a function that was not started with startthread.
|
|
//
|
|
// . code-block:: Squirrel
|
|
// local waitTID = 0
|
|
//
|
|
// if ( g.in_flashback && HotelElevator.requestedFloor == 13 ) {
|
|
// waitTID = startthread(HotelElevator.avoidPenthouse)
|
|
// breakwhilerunning(waitTID)
|
|
// }
|
|
// waitTID = 0
|
|
// if (HotelElevator.requestedFloor >= 0) {
|
|
// // Continue executing other code
|
|
// }
|
|
static SQInteger breakwhilerunning(HSQUIRRELVM v) {
|
|
SQInteger id = 0;
|
|
if ((sq_gettype(v, 2) == OT_INTEGER) && SQ_FAILED(sqget(v, 2, id)))
|
|
return sq_throwerror(v, "failed to get id");
|
|
debugC(kDebugSysScript, "breakwhilerunning: %lld", id);
|
|
|
|
Common::SharedPtr<ThreadBase> t = sqthread(id);
|
|
if (!t) {
|
|
if (!g_twp->_resManager->isSound(id)) {
|
|
warning("thread and sound not found: %lld", id);
|
|
return 0;
|
|
}
|
|
return breakwhilecond(
|
|
v, [id] { return g_twp->_audio->playing(id); }, "breakwhilerunningsound(%d)", id);
|
|
}
|
|
return breakwhilecond(
|
|
v, [id] { return sqthread(id) != nullptr; }, "breakwhilerunning(%d)", id);
|
|
}
|
|
|
|
struct SomeoneTalking {
|
|
bool operator()() {
|
|
return g_twp->isSomeoneTalking();
|
|
}
|
|
};
|
|
|
|
struct ActorTalking {
|
|
explicit ActorTalking(Common::SharedPtr<Object> obj) : _obj(obj) {}
|
|
|
|
bool operator()() {
|
|
return _obj->getTalking() && _obj->getTalking()->isEnabled() && _obj->_room == g_twp->_room;
|
|
}
|
|
|
|
private:
|
|
Common::SharedPtr<Object> _obj;
|
|
};
|
|
|
|
// If an actor is specified, breaks until actor has finished talking.
|
|
// If no actor is specified, breaks until ALL actors have finished talking.
|
|
// Once talking finishes, the method will continue running.
|
|
// It is an error to call breakwhiletalking in a function that was not started with startthread.
|
|
//
|
|
// . code-block:: Squirrel
|
|
// while(closeToWillie()) {
|
|
// local line = randomfrom(lines)
|
|
// breakwhiletalking(willie)
|
|
// mumbleLine(willie, line)
|
|
// breakwhiletalking(willie)
|
|
// }
|
|
static SQInteger breakwhiletalking(HSQUIRRELVM v) {
|
|
SQInteger nArgs = sq_gettop(v);
|
|
if (nArgs == 1) {
|
|
return breakwhilecond(v, SomeoneTalking(), "breakwhiletalking(all)");
|
|
}
|
|
if (nArgs == 2) {
|
|
Common::SharedPtr<Object> obj = sqobj(v, 2);
|
|
if (!obj)
|
|
return sq_throwerror(v, "failed to get object");
|
|
return breakwhilecond(v, ActorTalking(obj), "breakwhiletalking(%s)", obj->_name.c_str());
|
|
}
|
|
|
|
return sq_throwerror(v, "Invalid number of arguments for breakwhiletalking");
|
|
}
|
|
|
|
struct ActorWalking {
|
|
explicit ActorWalking(Common::SharedPtr<Object> obj) : _obj(obj) {}
|
|
|
|
bool operator()() {
|
|
return _obj->getWalkTo() && _obj->getWalkTo()->isEnabled();
|
|
}
|
|
|
|
private:
|
|
Common::SharedPtr<Object> _obj;
|
|
};
|
|
|
|
// If an actor is specified, breaks until actor has finished walking.
|
|
// Once arrived at destination, the method will continue running.
|
|
// It is an error to call breakwhilewalking in a function that was not started with `startthread`.
|
|
//
|
|
// . code-block:: Squirrel
|
|
// startthread(@(){
|
|
// actorWalkTo(currentActor, Nickel.copyTron)
|
|
// breakwhilewalking(currentActor)
|
|
// pushSentence(VERB_USE, nickel, Nickel.copyTron)
|
|
//})
|
|
static SQInteger breakwhilewalking(HSQUIRRELVM v) {
|
|
Common::SharedPtr<Object> obj = sqobj(v, 2);
|
|
if (!obj)
|
|
return sq_throwerror(v, "failed to get object");
|
|
return breakwhilecond(v, ActorWalking(obj), "breakwhilewalking(%s)", obj->_name.c_str());
|
|
}
|
|
|
|
struct SoundPlaying {
|
|
explicit SoundPlaying(int soundId) : _soundId(soundId) {}
|
|
|
|
bool operator()() {
|
|
return g_twp->_audio->playing(_soundId);
|
|
}
|
|
|
|
private:
|
|
int _soundId;
|
|
};
|
|
|
|
// Breaks until specified sound has finished playing.
|
|
// Once sound finishes, the method will continue running.
|
|
static SQInteger breakwhilesound(HSQUIRRELVM v) {
|
|
SQInteger soundId = 0;
|
|
if (SQ_FAILED(sqget(v, 2, soundId)))
|
|
return sq_throwerror(v, "failed to get sound");
|
|
return breakwhilecond(v, SoundPlaying(soundId), "breakwhilesound(%d)", soundId);
|
|
}
|
|
|
|
static SQInteger cutscene(HSQUIRRELVM v) {
|
|
HSQUIRRELVM vm = g_twp->getVm();
|
|
SQInteger nArgs = sq_gettop(v);
|
|
|
|
HSQOBJECT envObj;
|
|
sq_resetobject(&envObj);
|
|
if (SQ_FAILED(sq_getstackobj(v, 1, &envObj)))
|
|
return sq_throwerror(v, "failed to get environment from stack");
|
|
|
|
// create thread and store it on the stack
|
|
sq_newthread(vm, 1024);
|
|
HSQOBJECT threadObj;
|
|
sq_resetobject(&threadObj);
|
|
if (SQ_FAILED(sq_getstackobj(vm, -1, &threadObj)))
|
|
return sq_throwerror(v, "failed to get coroutine thread from stack");
|
|
|
|
// get the closure
|
|
HSQOBJECT closure;
|
|
sq_resetobject(&closure);
|
|
if (SQ_FAILED(sq_getstackobj(v, 2, &closure)))
|
|
return sq_throwerror(v, "failed to get cutscene closure");
|
|
|
|
// get the cutscene override closure
|
|
HSQOBJECT closureOverride;
|
|
sq_resetobject(&closureOverride);
|
|
if (nArgs == 3) {
|
|
if (SQ_FAILED(sq_getstackobj(v, 3, &closureOverride)))
|
|
return sq_throwerror(v, "failed to get cutscene override closure");
|
|
}
|
|
|
|
Common::SharedPtr<ThreadBase> parentThread = sqthread(v);
|
|
Common::String cutsceneName = Common::String::format("%s (%lld)", _stringval(_closure(closure)->_function->_sourcename), _closure(closure)->_function->_lineinfos->_line);
|
|
Common::SharedPtr<Cutscene> cutscene(new Cutscene(cutsceneName, parentThread->getId(), threadObj, closure, closureOverride, envObj));
|
|
g_twp->_cutscene = cutscene;
|
|
|
|
// call the closure in the thread
|
|
cutscene->update(0.f);
|
|
return breakwhilecutscene(v);
|
|
}
|
|
|
|
static SQInteger cutsceneOverride(HSQUIRRELVM v) {
|
|
debugC(kDebugSysScript, "cutsceneOverride");
|
|
g_twp->_cutscene->cutsceneOverride();
|
|
return 0;
|
|
}
|
|
|
|
static SQInteger dumpvar(HSQUIRRELVM v) {
|
|
warning("TODO: dumpvar: not implemented");
|
|
return 0;
|
|
}
|
|
|
|
static SQInteger exCommand(HSQUIRRELVM v) {
|
|
SQInteger cmd;
|
|
if (SQ_FAILED(sqget(v, 2, cmd)))
|
|
return sq_throwerror(v, "Failed to get command");
|
|
switch (cmd) {
|
|
case EX_AUTOSAVE_STATE: {
|
|
SQInteger enabled;
|
|
if (SQ_FAILED(sqget(v, 3, enabled)))
|
|
return sq_throwerror(v, "Failed to get enabled");
|
|
g_twp->_saveGameManager->_autoSave = enabled != 0;
|
|
} break;
|
|
case EX_AUTOSAVE: {
|
|
if (g_twp->_saveGameManager->_autoSave && g_twp->_saveGameManager->_allowSaveGame) {
|
|
g_twp->saveGameState(0, "", true);
|
|
}
|
|
} break;
|
|
case EX_ALLOW_SAVEGAMES: {
|
|
SQInteger enabled;
|
|
if (SQ_FAILED(sqget(v, 3, enabled)))
|
|
return sq_throwerror(v, "Failed to get enabled");
|
|
g_twp->_saveGameManager->_allowSaveGame = enabled != 0;
|
|
} break;
|
|
case EX_POP_CHARACTER_SELECTION:
|
|
// seems not to be used
|
|
warning("exCommand EX_POP_CHARACTER_SELECTION: not implemented");
|
|
break;
|
|
case EX_CAMERA_TRACKING:
|
|
warning("TODO: exCommand EX_CAMERA_TRACKING: not implemented");
|
|
break;
|
|
case EX_BUTTON_HOVER_SOUND: {
|
|
Common::SharedPtr<SoundDefinition> sound = sqsounddef(v, 3);
|
|
if (!sound)
|
|
return sq_throwerror(v, "failed to get sound for EX_BUTTON_HOVER_SOUND");
|
|
g_twp->_audio->_soundHover = sound;
|
|
} break;
|
|
case EX_RESTART:
|
|
warning("TODO: exCommand EX_RESTART: not implemented");
|
|
break;
|
|
case EX_IDLE_TIME:
|
|
// used in demo only in watchForIdle
|
|
warning("TODO: exCommand EX_IDLE_TIME: not implemented");
|
|
break;
|
|
case EX_DISABLE_SAVESYSTEM:
|
|
// seems not to be used
|
|
warning("exCommand EX_DISABLE_SAVESYSTEM: not implemented");
|
|
break;
|
|
case EX_SHOW_OPTIONS:
|
|
g_twp->openMainMenuDialog();
|
|
break;
|
|
case EX_OPTIONS_MUSIC:
|
|
warning("TODO: exCommand EX_OPTIONS_MUSIC: not implemented");
|
|
break;
|
|
case EX_FORCE_TALKIE_TEXT:
|
|
// seems not to be used
|
|
warning("exCommand EX_FORCE_TALKIE_TEXT: not implemented");
|
|
break;
|
|
case EX_SCREEN_SIZE:
|
|
// only on mobile, used in Bridge.nut: objectScale(text, (exCommand(EX_SCREEN_SIZE) == 3) ? 0.75 : 0.5)
|
|
sqpush(v, 0);
|
|
return 1;
|
|
break;
|
|
default:
|
|
warning("exCommand(%lld) not implemented", cmd);
|
|
break;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
// Returns how long (in seconds) the game has been played for in total (not just this session).
|
|
//// Saved when the game is saved.
|
|
// Also used for testing.
|
|
// The value is a float, so 1 = 1 second, 0.5 = half a second.
|
|
//
|
|
// . code-block:: Squirrel
|
|
// if (gameTime() > (time+testerTronTimeOut)) { // Do something
|
|
// }
|
|
static SQInteger gameTime(HSQUIRRELVM v) {
|
|
sqpush(v, g_twp->_time);
|
|
return 1;
|
|
}
|
|
|
|
static SQInteger sysInclude(HSQUIRRELVM v) {
|
|
const SQChar *filename;
|
|
if (SQ_FAILED(sqget(v, 2, filename))) {
|
|
return sq_throwerror(v, "failed to get filename");
|
|
}
|
|
g_twp->execNutEntry(v, filename);
|
|
return 0;
|
|
}
|
|
|
|
static SQInteger inputController(HSQUIRRELVM v) {
|
|
warning("TODO: inputController: not implemented");
|
|
return 0;
|
|
}
|
|
|
|
static SQInteger inputHUD(HSQUIRRELVM v) {
|
|
bool on;
|
|
if (SQ_FAILED(sqget(v, 2, on)))
|
|
return sq_throwerror(v, "failed to get on");
|
|
g_twp->_inputState.setInputHUD(on);
|
|
return 0;
|
|
}
|
|
|
|
static SQInteger inputOff(HSQUIRRELVM v) {
|
|
if (!g_twp->_cutscene || g_twp->_cutscene->isStopped()) {
|
|
g_twp->_inputState.setInputActive(false);
|
|
g_twp->_inputState.setShowCursor(false);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static SQInteger inputOn(HSQUIRRELVM v) {
|
|
Common::SharedPtr<Cutscene> scene(g_twp->_cutscene);
|
|
if (!scene || scene->isStopped()) {
|
|
g_twp->_inputState.setInputActive(true);
|
|
g_twp->_inputState.setShowCursor(true);
|
|
} else {
|
|
int state = g_twp->_inputState.getState();
|
|
state |= UI_INPUT_ON;
|
|
state &= (~UI_INPUT_OFF);
|
|
state |= UI_CURSOR_ON;
|
|
state &= (~UI_CURSOR_OFF);
|
|
scene->setInputState((InputStateFlag)state);
|
|
scene->setShowCursor(true);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static SQInteger inputSilentOff(HSQUIRRELVM v) {
|
|
g_twp->_inputState.setInputActive(false);
|
|
return 0;
|
|
}
|
|
|
|
static SQInteger sysInputState(HSQUIRRELVM v) {
|
|
SQInteger numArgs = sq_gettop(v);
|
|
if (numArgs == 1) {
|
|
int state = (int)g_twp->_inputState.getState();
|
|
sqpush(v, state);
|
|
return 1;
|
|
}
|
|
if (numArgs == 2) {
|
|
SQInteger state;
|
|
if (SQ_FAILED(sqget(v, 2, state)))
|
|
return sq_throwerror(v, "failed to get state");
|
|
g_twp->_inputState.setState((InputStateFlag)state);
|
|
return 0;
|
|
}
|
|
return sq_throwerror(v, Common::String::format("inputState with %lld arguments not implemented", numArgs).c_str());
|
|
}
|
|
|
|
static SQInteger inputVerbs(HSQUIRRELVM v) {
|
|
bool on;
|
|
if (SQ_FAILED(sqget(v, 2, on)))
|
|
return sq_throwerror(v, "failed to get isActive");
|
|
debugC(kDebugSysScript, "inputVerbs: %s", on ? "yes" : "no");
|
|
g_twp->_inputState.setInputVerbsActive(on);
|
|
return 1;
|
|
}
|
|
|
|
static SQInteger isInputOn(HSQUIRRELVM v) {
|
|
bool isActive = g_twp->_inputState.getInputActive();
|
|
sqpush(v, isActive);
|
|
return 1;
|
|
}
|
|
|
|
static SQInteger logEvent(HSQUIRRELVM v) {
|
|
SQInteger numArgs = sq_gettop(v);
|
|
Common::String msg, event;
|
|
if (SQ_FAILED(sqget(v, 2, event)))
|
|
return sq_throwerror(v, "failed to get event");
|
|
if (numArgs == 3) {
|
|
if (SQ_FAILED(sqget(v, 3, event)))
|
|
return sq_throwerror(v, "failed to get message");
|
|
msg = event + ": " + msg;
|
|
}
|
|
debugC(kDebugSysScript, "%s", msg.c_str());
|
|
return 0;
|
|
}
|
|
|
|
// Like a print statement, but gets sent to the output log file instead.
|
|
// Useful for testing.
|
|
static SQInteger logInfo(HSQUIRRELVM v) {
|
|
Common::String msg;
|
|
if (SQ_FAILED(sqget(v, 2, msg)))
|
|
return sq_throwerror(v, "failed to get message");
|
|
debugC(kDebugSysScript, "%s", msg.c_str());
|
|
return 0;
|
|
}
|
|
|
|
// Sends a warning message to the output log file.
|
|
static SQInteger logWarning(HSQUIRRELVM v) {
|
|
Common::String msg;
|
|
if (SQ_FAILED(sqget(v, 2, msg)))
|
|
return sq_throwerror(v, "failed to get message");
|
|
warning("%s", msg.c_str());
|
|
return 0;
|
|
}
|
|
|
|
// Returns game time in milliseconds.
|
|
// Based on when the machine is booted and runs all the time (not paused or saved).
|
|
// See also gameTime, which is in seconds.
|
|
static SQInteger microTime(HSQUIRRELVM v) {
|
|
sqpush(v, g_twp->_time * 1000.0f);
|
|
return 1;
|
|
}
|
|
|
|
static SQInteger moveCursorTo(HSQUIRRELVM v) {
|
|
SQInteger x, y;
|
|
if (SQ_FAILED(sqget(v, 2, x)))
|
|
return sq_throwerror(v, "Failed to get x");
|
|
if (SQ_FAILED(sqget(v, 3, y)))
|
|
return sq_throwerror(v, "Failed to get y");
|
|
float t;
|
|
if (SQ_FAILED(sqget(v, 4, t)))
|
|
return sq_throwerror(v, "Failed to get time");
|
|
|
|
Math::Vector2d pos;
|
|
if (g_twp->_room) {
|
|
pos = g_twp->roomToScreen(Math::Vector2d(x, y));
|
|
} else {
|
|
pos = g_twp->screenToWin(Math::Vector2d(x, y));
|
|
}
|
|
pos.setX(CLIP(pos.getX(), 0.f, (float)SCREEN_WIDTH));
|
|
pos.setY(CLIP(pos.getY(), 0.f, (float)SCREEN_HEIGHT));
|
|
pos = g_twp->screenToWin(pos);
|
|
g_twp->_moveCursorTo = Common::ScopedPtr<Motor>(new MoveCursorTo(pos, t));
|
|
return 0;
|
|
}
|
|
|
|
// removeCallback(id: int) remove the given callback
|
|
static SQInteger removeCallback(HSQUIRRELVM v) {
|
|
SQInteger id = 0;
|
|
if (SQ_FAILED(sqget(v, 2, id)))
|
|
return sq_throwerror(v, "failed to get callback");
|
|
for (size_t i = 0; i < g_twp->_callbacks.size(); i++) {
|
|
Common::SharedPtr<Callback> cb = g_twp->_callbacks[i];
|
|
if (cb->getId() == id) {
|
|
cb->remove();
|
|
return 0;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static SQInteger startthread(HSQUIRRELVM v) {
|
|
return _startthread(v, false);
|
|
}
|
|
|
|
static SQInteger startglobalthread(HSQUIRRELVM v) {
|
|
return _startthread(v, true);
|
|
}
|
|
|
|
// Stops a thread specified by threadid.
|
|
//
|
|
// If the thread is not running, the command does nothing.
|
|
//
|
|
// See also:
|
|
// * `startthread`
|
|
// * `startglobalthread`
|
|
static SQInteger stopthread(HSQUIRRELVM v) {
|
|
SQInteger id = 0;
|
|
if (SQ_FAILED(sqget(v, 2, id))) {
|
|
sqpush(v, 0);
|
|
return 1;
|
|
}
|
|
|
|
Common::SharedPtr<ThreadBase> t = sqthread(id);
|
|
if (t) {
|
|
t->stop();
|
|
}
|
|
|
|
sqpush(v, 0);
|
|
return 1;
|
|
}
|
|
|
|
// Returns the thread ID of the currently running script/thread.
|
|
//
|
|
// If no thread is running, it will return 0.
|
|
//
|
|
// . code-block:: Squirrel
|
|
// Phone <-
|
|
// {
|
|
// phoneRingingTID = 0
|
|
// script phoneRinging(number) {
|
|
// phoneRingingTID = threadid()
|
|
// ...
|
|
// }
|
|
// function clickedButton(...) {
|
|
// if (!phoneRingingTID) {
|
|
// ...
|
|
// }
|
|
// }
|
|
// }
|
|
static SQInteger threadid(HSQUIRRELVM v) {
|
|
Common::SharedPtr<ThreadBase> t = sqthread(v);
|
|
if (t)
|
|
sqpush(v, t->getId());
|
|
else
|
|
sqpush(v, 0);
|
|
return 1;
|
|
}
|
|
|
|
// Specify whether a thread should be pauseable or not.
|
|
// If a thread is not pauseable, it won't be possible to pause this thread.
|
|
static SQInteger threadpauseable(HSQUIRRELVM v) {
|
|
Common::SharedPtr<ThreadBase> t = sqthread(v, 2);
|
|
if (!t)
|
|
return sq_throwerror(v, "failed to get thread");
|
|
SQInteger pauseable = 0;
|
|
if (SQ_FAILED(sqget(v, 3, pauseable)))
|
|
return sq_throwerror(v, "failed to get pauseable");
|
|
t->_pauseable = pauseable != 0;
|
|
return 0;
|
|
}
|
|
|
|
void sqgame_register_syslib(HSQUIRRELVM v) {
|
|
regFunc(v, startthread, _SC("startthread"));
|
|
regFunc(v, startglobalthread, _SC("startglobalthread"));
|
|
regFunc(v, breaktime, _SC("breaktime"));
|
|
regFunc(v, activeController, _SC("activeController"));
|
|
regFunc(v, addCallback, _SC("addCallback"));
|
|
regFunc(v, addFolder, _SC("addFolder"));
|
|
regFunc(v, breakhere, _SC("breakhere"));
|
|
regFunc(v, breaktime, _SC("breaktime"));
|
|
regFunc(v, breakwhileanimating, _SC("breakwhileanimating"));
|
|
regFunc(v, breakwhilecamera, _SC("breakwhilecamera"));
|
|
regFunc(v, breakwhilecutscene, _SC("breakwhilecutscene"));
|
|
regFunc(v, breakwhiledialog, _SC("breakwhiledialog"));
|
|
regFunc(v, breakwhileinputoff, _SC("breakwhileinputoff"));
|
|
regFunc(v, breakwhilerunning, _SC("breakwhilerunning"));
|
|
regFunc(v, breakwhilesound, _SC("breakwhilesound"));
|
|
regFunc(v, breakwhiletalking, _SC("breakwhiletalking"));
|
|
regFunc(v, breakwhilewalking, _SC("breakwhilewalking"));
|
|
regFunc(v, cutscene, _SC("cutscene"));
|
|
regFunc(v, cutsceneOverride, _SC("cutsceneOverride"));
|
|
regFunc(v, dumpvar, _SC("dumpvar"));
|
|
regFunc(v, exCommand, _SC("exCommand"));
|
|
regFunc(v, gameTime, _SC("gameTime"));
|
|
regFunc(v, sysInclude, _SC("include"));
|
|
regFunc(v, inputController, _SC("inputController"));
|
|
regFunc(v, inputHUD, _SC("inputHUD"));
|
|
regFunc(v, inputOff, _SC("inputOff"));
|
|
regFunc(v, inputOn, _SC("inputOn"));
|
|
regFunc(v, inputSilentOff, _SC("inputSilentOff"));
|
|
regFunc(v, sysInputState, _SC("inputState"));
|
|
regFunc(v, inputVerbs, _SC("inputVerbs"));
|
|
regFunc(v, isInputOn, _SC("isInputOn"));
|
|
regFunc(v, logEvent, _SC("logEvent"));
|
|
regFunc(v, logInfo, _SC("logInfo"));
|
|
regFunc(v, logWarning, _SC("logWarning"));
|
|
regFunc(v, microTime, _SC("microTime"));
|
|
regFunc(v, moveCursorTo, _SC("moveCursorTo"));
|
|
regFunc(v, removeCallback, _SC("removeCallback"));
|
|
regFunc(v, startglobalthread, _SC("startglobalthread"));
|
|
regFunc(v, startthread, _SC("startthread"));
|
|
regFunc(v, stopthread, _SC("stopthread"));
|
|
regFunc(v, threadid, _SC("threadid"));
|
|
regFunc(v, threadpauseable, _SC("threadpauseable"));
|
|
}
|
|
|
|
static void regConst(HSQUIRRELVM v, const char *name, SQInteger value) {
|
|
SQObject obj = sqtoobj(v, value);
|
|
_table(v->_roottable)->NewSlot(sqtoobj(v, name), SQObjectPtr(obj));
|
|
}
|
|
|
|
void sqgame_register_constants(HSQUIRRELVM v) {
|
|
regConst(v, "ALL", ALL);
|
|
regConst(v, "HERE", HERE);
|
|
regConst(v, "GONE", GONE);
|
|
regConst(v, "OFF", OFF);
|
|
regConst(v, "ON", ON);
|
|
regConst(v, "FULL", FULL);
|
|
regConst(v, "EMPTY", EMPTY);
|
|
regConst(v, "OPEN", OPEN);
|
|
regConst(v, "CLOSED", CLOSED);
|
|
regConst(v, "FALSE", FALSE);
|
|
regConst(v, "TRUE", TRUE);
|
|
regConst(v, "MOUSE", MOUSE);
|
|
regConst(v, "CONTROLLER", CONTROLLER);
|
|
regConst(v, "DIRECTDRIVE", DIRECTDRIVE);
|
|
regConst(v, "TOUCH", TOUCH);
|
|
regConst(v, "REMOTE", REMOTE);
|
|
regConst(v, "FADE_IN", FADE_IN);
|
|
regConst(v, "FADE_OUT", FADE_OUT);
|
|
regConst(v, "FADE_WOBBLE", FADE_WOBBLE);
|
|
regConst(v, "FADE_WOBBLE_TO_SEPIA", FADE_WOBBLE_TO_SEPIA);
|
|
regConst(v, "FACE_FRONT", static_cast<int>(Facing::FACE_FRONT));
|
|
regConst(v, "FACE_BACK", static_cast<int>(Facing::FACE_BACK));
|
|
regConst(v, "FACE_LEFT", static_cast<int>(Facing::FACE_LEFT));
|
|
regConst(v, "FACE_RIGHT", static_cast<int>(Facing::FACE_RIGHT));
|
|
regConst(v, "FACE_FLIP", FACE_FLIP);
|
|
regConst(v, "DIR_FRONT", DIR_FRONT);
|
|
regConst(v, "DIR_BACK", DIR_BACK);
|
|
regConst(v, "DIR_LEFT", DIR_LEFT);
|
|
regConst(v, "DIR_RIGHT", DIR_RIGHT);
|
|
regConst(v, "LINEAR", LINEAR);
|
|
regConst(v, "EASE_IN", EASE_IN);
|
|
regConst(v, "EASE_INOUT", EASE_INOUT);
|
|
regConst(v, "EASE_OUT", EASE_OUT);
|
|
regConst(v, "SLOW_EASE_IN", SLOW_EASE_IN);
|
|
regConst(v, "SLOW_EASE_OUT", SLOW_EASE_OUT);
|
|
regConst(v, "LOOPING", LOOPING);
|
|
regConst(v, "SWING", SWING);
|
|
regConst(v, "STOP_LOOPING", STOP_LOOPING);
|
|
regConst(v, "ALIGN_LEFT", ALIGN_LEFT);
|
|
regConst(v, "ALIGN_CENTER", ALIGN_CENTER);
|
|
regConst(v, "ALIGN_RIGHT", ALIGN_RIGHT);
|
|
regConst(v, "ALIGN_TOP", ALIGN_TOP);
|
|
regConst(v, "ALIGN_BOTTOM", ALIGN_BOTTOM);
|
|
regConst(v, "LESS_SPACING", LESS_SPACING);
|
|
regConst(v, "EX_ALLOW_SAVEGAMES", EX_ALLOW_SAVEGAMES);
|
|
regConst(v, "EX_POP_CHARACTER_SELECTION", EX_POP_CHARACTER_SELECTION);
|
|
regConst(v, "EX_CAMERA_TRACKING", EX_CAMERA_TRACKING);
|
|
regConst(v, "EX_BUTTON_HOVER_SOUND", EX_BUTTON_HOVER_SOUND);
|
|
regConst(v, "EX_RESTART", EX_RESTART);
|
|
regConst(v, "EX_IDLE_TIME", EX_IDLE_TIME);
|
|
regConst(v, "EX_AUTOSAVE", EX_AUTOSAVE);
|
|
regConst(v, "EX_AUTOSAVE_STATE", EX_AUTOSAVE_STATE);
|
|
regConst(v, "EX_DISABLE_SAVESYSTEM", EX_DISABLE_SAVESYSTEM);
|
|
regConst(v, "EX_SHOW_OPTIONS", EX_SHOW_OPTIONS);
|
|
regConst(v, "EX_OPTIONS_MUSIC", EX_OPTIONS_MUSIC);
|
|
regConst(v, "EX_FORCE_TALKIE_TEXT", EX_FORCE_TALKIE_TEXT);
|
|
regConst(v, "EX_SCREEN_SIZE", EX_SCREEN_SIZE);
|
|
regConst(v, "GRASS_BACKANDFORTH", GRASS_BACKANDFORTH);
|
|
regConst(v, "EFFECT_NONE", EFFECT_NONE);
|
|
regConst(v, "DOOR", DOOR);
|
|
regConst(v, "DOOR_LEFT", DOOR_LEFT);
|
|
regConst(v, "DOOR_RIGHT", DOOR_RIGHT);
|
|
regConst(v, "DOOR_BACK", DOOR_BACK);
|
|
regConst(v, "DOOR_FRONT", DOOR_FRONT);
|
|
regConst(v, "FAR_LOOK", FAR_LOOK);
|
|
regConst(v, "USE_WITH", USE_WITH);
|
|
regConst(v, "USE_ON", USE_ON);
|
|
regConst(v, "USE_IN", USE_IN);
|
|
regConst(v, "GIVEABLE", GIVEABLE);
|
|
regConst(v, "TALKABLE", TALKABLE);
|
|
regConst(v, "IMMEDIATE", IMMEDIATE);
|
|
regConst(v, "FEMALE", FEMALE);
|
|
regConst(v, "MALE", MALE);
|
|
regConst(v, "PERSON", PERSON);
|
|
regConst(v, "REACH_HIGH", REACH_HIGH);
|
|
regConst(v, "REACH_MED", REACH_MED);
|
|
regConst(v, "REACH_LOW", REACH_LOW);
|
|
regConst(v, "REACH_NONE", REACH_NONE);
|
|
regConst(v, "VERB_WALKTO", VERB_WALKTO);
|
|
regConst(v, "VERB_LOOKAT", VERB_LOOKAT);
|
|
regConst(v, "VERB_TALKTO", VERB_TALKTO);
|
|
regConst(v, "VERB_PICKUP", VERB_PICKUP);
|
|
regConst(v, "VERB_OPEN", VERB_OPEN);
|
|
regConst(v, "VERB_CLOSE", VERB_CLOSE);
|
|
regConst(v, "VERB_PUSH", VERB_PUSH);
|
|
regConst(v, "VERB_PULL", VERB_PULL);
|
|
regConst(v, "VERB_GIVE", VERB_GIVE);
|
|
regConst(v, "VERB_USE", VERB_USE);
|
|
regConst(v, "VERB_DIALOG", VERB_DIALOG);
|
|
regConst(v, "VERBFLAG_INSTANT", VERBFLAG_INSTANT);
|
|
regConst(v, "NO", TWP_NO);
|
|
regConst(v, "YES", TWP_YES);
|
|
regConst(v, "TEMP_UNSELECTABLE", TEMP_UNSELECTABLE);
|
|
regConst(v, "TEMP_SELECTABLE", TEMP_SELECTABLE);
|
|
regConst(v, "MAC", MAC);
|
|
regConst(v, "WIN", WIN);
|
|
regConst(v, "LINUX", LINUX);
|
|
regConst(v, "XBOX", XBOX);
|
|
regConst(v, "IOS", IOS);
|
|
regConst(v, "ANDROID", ANDROID);
|
|
regConst(v, "SWITCH", SWITCH);
|
|
regConst(v, "PS4", PS4);
|
|
regConst(v, "EFFECT_NONE", EFFECT_NONE);
|
|
regConst(v, "EFFECT_SEPIA", EFFECT_SEPIA);
|
|
regConst(v, "EFFECT_EGA", EFFECT_EGA);
|
|
regConst(v, "EFFECT_VHS", EFFECT_VHS);
|
|
regConst(v, "EFFECT_GHOST", EFFECT_GHOST);
|
|
regConst(v, "EFFECT_BLACKANDWHITE", EFFECT_BLACKANDWHITE);
|
|
regConst(v, "UI_INPUT_ON", UI_INPUT_ON);
|
|
regConst(v, "UI_INPUT_OFF", UI_INPUT_OFF);
|
|
regConst(v, "UI_VERBS_ON", UI_VERBS_ON);
|
|
regConst(v, "UI_VERBS_OFF", UI_VERBS_OFF);
|
|
regConst(v, "UI_HUDOBJECTS_ON", UI_HUDOBJECTS_ON);
|
|
regConst(v, "UI_HUDOBJECTS_OFF", UI_HUDOBJECTS_OFF);
|
|
regConst(v, "UI_CURSOR_ON", UI_CURSOR_ON);
|
|
regConst(v, "UI_CURSOR_OFF", UI_CURSOR_OFF);
|
|
regConst(v, "KEY_UP", KEY_UP);
|
|
regConst(v, "KEY_RIGHT", KEY_RIGHT);
|
|
regConst(v, "KEY_DOWN", KEY_DOWN);
|
|
regConst(v, "KEY_LEFT", KEY_LEFT);
|
|
regConst(v, "KEY_PAD1", KEY_PAD1);
|
|
regConst(v, "KEY_PAD2", KEY_PAD2);
|
|
regConst(v, "KEY_PAD3", KEY_PAD3);
|
|
regConst(v, "KEY_PAD4", KEY_PAD4);
|
|
regConst(v, "KEY_PAD5", KEY_PAD5);
|
|
regConst(v, "KEY_PAD6", KEY_PAD6);
|
|
regConst(v, "KEY_PAD7", KEY_PAD7);
|
|
regConst(v, "KEY_PAD8", KEY_PAD8);
|
|
regConst(v, "KEY_PAD9", KEY_PAD9);
|
|
regConst(v, "KEY_ESCAPE", KEY_ESCAPE);
|
|
regConst(v, "KEY_TAB", KEY_TAB);
|
|
regConst(v, "KEY_RETURN", KEY_RETURN);
|
|
regConst(v, "KEY_BACKSPACE", KEY_BACKSPACE);
|
|
regConst(v, "KEY_SPACE", KEY_SPACE);
|
|
regConst(v, "KEY_A", KEY_A);
|
|
regConst(v, "KEY_B", KEY_B);
|
|
regConst(v, "KEY_C", KEY_C);
|
|
regConst(v, "KEY_D", KEY_D);
|
|
regConst(v, "KEY_E", KEY_E);
|
|
regConst(v, "KEY_F", KEY_F);
|
|
regConst(v, "KEY_G", KEY_G);
|
|
regConst(v, "KEY_H", KEY_H);
|
|
regConst(v, "KEY_I", KEY_I);
|
|
regConst(v, "KEY_J", KEY_J);
|
|
regConst(v, "KEY_K", KEY_K);
|
|
regConst(v, "KEY_L", KEY_L);
|
|
regConst(v, "KEY_M", KEY_M);
|
|
regConst(v, "KEY_N", KEY_N);
|
|
regConst(v, "KEY_O", KEY_O);
|
|
regConst(v, "KEY_P", KEY_P);
|
|
regConst(v, "KEY_Q", KEY_Q);
|
|
regConst(v, "KEY_R", KEY_R);
|
|
regConst(v, "KEY_S", KEY_S);
|
|
regConst(v, "KEY_T", KEY_T);
|
|
regConst(v, "KEY_U", KEY_U);
|
|
regConst(v, "KEY_V", KEY_V);
|
|
regConst(v, "KEY_W", KEY_W);
|
|
regConst(v, "KEY_X", KEY_X);
|
|
regConst(v, "KEY_Y", KEY_Y);
|
|
regConst(v, "KEY_Z", KEY_Z);
|
|
regConst(v, "KEY_0", KEY_0);
|
|
regConst(v, "KEY_1", KEY_1);
|
|
regConst(v, "KEY_2", KEY_2);
|
|
regConst(v, "KEY_3", KEY_3);
|
|
regConst(v, "KEY_4", KEY_4);
|
|
regConst(v, "KEY_5", KEY_5);
|
|
regConst(v, "KEY_6", KEY_6);
|
|
regConst(v, "KEY_7", KEY_7);
|
|
regConst(v, "KEY_8", KEY_8);
|
|
regConst(v, "KEY_9", KEY_9);
|
|
regConst(v, "KEY_F1", KEY_F1);
|
|
regConst(v, "KEY_F2", KEY_F2);
|
|
regConst(v, "KEY_F3", KEY_F3);
|
|
regConst(v, "KEY_F4", KEY_F4);
|
|
regConst(v, "KEY_F5", KEY_F5);
|
|
regConst(v, "KEY_F6", KEY_F6);
|
|
regConst(v, "KEY_F7", KEY_F7);
|
|
regConst(v, "KEY_F8", KEY_F8);
|
|
regConst(v, "KEY_F9", KEY_F9);
|
|
regConst(v, "KEY_F10", KEY_F10);
|
|
regConst(v, "KEY_F11", KEY_F11);
|
|
regConst(v, "KEY_F12", KEY_F12);
|
|
regConst(v, "BUTTON_A", BUTTON_A);
|
|
regConst(v, "BUTTON_B", BUTTON_B);
|
|
regConst(v, "BUTTON_X", BUTTON_X);
|
|
regConst(v, "BUTTON_Y", BUTTON_Y);
|
|
regConst(v, "BUTTON_START", BUTTON_START);
|
|
regConst(v, "BUTTON_BACK", BUTTON_BACK);
|
|
regConst(v, "BUTTON_MOUSE_LEFT", BUTTON_MOUSE_LEFT);
|
|
regConst(v, "BUTTON_MOUSE_RIGHT", BUTTON_MOUSE_RIGHT);
|
|
regConst(v, "WAITING_FOR_CHOICE", 2);
|
|
|
|
// convert ScummVM platform to the one expected
|
|
SQInteger platform = MAC;
|
|
const char *platformsSrc[] = {"mac", "windows", "linux", "xbox", "ios", "android", "switch"};
|
|
const SQInteger platformsDst[] = {MAC, WIN, LINUX, XBOX, IOS, ANDROID, SWITCH};
|
|
Common::String platformName(ConfMan.get("platform"));
|
|
for (int i = 0; i < ARRAYSIZE(platformsSrc); i++) {
|
|
if (platformName == platformsSrc[i]) {
|
|
platform = platformsDst[i];
|
|
}
|
|
}
|
|
regConst(v, "PLATFORM", platform);
|
|
}
|
|
|
|
} // namespace Twp
|