Path: blob/main/RSDKv4/Script.cpp
817 views
#include "RetroEngine.hpp"1#include <cmath>23#if RETRO_USE_COMPILER4#if !RETRO_REV005#define COMMON_SCRIPT_VAR_COUNT (34)6#else7#define COMMON_SCRIPT_VAR_COUNT (33)8#endif9#endif1011#define SCRIPT_VAR_COUNT (COMMON_SCRIPT_VAR_COUNT + 0x1DF)12int lineID = 0;1314enum ScriptVarType { VAR_ALIAS, VAR_STATICVALUE, VAR_TABLE };15enum ScriptVarAccessModifier { ACCESS_NONE, ACCESS_PUBLIC, ACCESS_PRIVATE };1617struct ScriptVariableInfo {18ScriptVariableInfo()19{20type = VAR_ALIAS;21access = ACCESS_NONE;22StrCopy(name, "");23StrCopy(value, "");24}2526ScriptVariableInfo(byte type, byte access, const char *name, const char *value)27{28this->type = type;29this->access = access;30StrCopy(this->name, name);31StrCopy(this->value, value);32}3334byte type;35byte access;36char name[0x20];37char value[0x20];38};3940struct FunctionInfo {41FunctionInfo()42{43StrCopy(name, "");44opcodeSize = 0;45}46FunctionInfo(const char *functionName, int opSize)47{48StrCopy(name, functionName);49opcodeSize = opSize;50}5152#if RETRO_REV0353char name[0x30];54#else55char name[0x20];56#endif57int opcodeSize;58};5960#if RETRO_USE_COMPILER61const char variableNames[][0x20] = {62// Internal Script Values63"temp0",64"temp1",65"temp2",66"temp3",67"temp4",68"temp5",69"temp6",70"temp7",71"checkResult",72"arrayPos0",73"arrayPos1",74"arrayPos2",75"arrayPos3",76"arrayPos4",77"arrayPos5",78"arrayPos6",79"arrayPos7",80"global",81"local",8283// Object Properties84"object.entityPos",85"object.groupID",86"object.type",87"object.propertyValue",88"object.xpos",89"object.ypos",90"object.ixpos",91"object.iypos",92"object.xvel",93"object.yvel",94"object.speed",95"object.state",96"object.rotation",97"object.scale",98"object.priority",99"object.drawOrder",100"object.direction",101"object.inkEffect",102"object.alpha",103"object.frame",104"object.animation",105"object.prevAnimation",106"object.animationSpeed",107"object.animationTimer",108"object.angle",109"object.lookPosX",110"object.lookPosY",111"object.collisionMode",112"object.collisionPlane",113"object.controlMode",114"object.controlLock",115"object.pushing",116"object.visible",117"object.tileCollisions",118"object.interaction",119"object.gravity",120"object.up",121"object.down",122"object.left",123"object.right",124"object.jumpPress",125"object.jumpHold",126"object.scrollTracking",127"object.floorSensorL",128"object.floorSensorC",129"object.floorSensorR",130#if !RETRO_REV00131"object.floorSensorLC",132"object.floorSensorRC",133#endif134"object.collisionLeft",135"object.collisionTop",136"object.collisionRight",137"object.collisionBottom",138"object.outOfBounds",139"object.spriteSheet",140141// Object Values142"object.value0",143"object.value1",144"object.value2",145"object.value3",146"object.value4",147"object.value5",148"object.value6",149"object.value7",150"object.value8",151"object.value9",152"object.value10",153"object.value11",154"object.value12",155"object.value13",156"object.value14",157"object.value15",158"object.value16",159"object.value17",160"object.value18",161"object.value19",162"object.value20",163"object.value21",164"object.value22",165"object.value23",166"object.value24",167"object.value25",168"object.value26",169"object.value27",170"object.value28",171"object.value29",172"object.value30",173"object.value31",174"object.value32",175"object.value33",176"object.value34",177"object.value35",178"object.value36",179"object.value37",180"object.value38",181"object.value39",182"object.value40",183"object.value41",184"object.value42",185"object.value43",186"object.value44",187"object.value45",188"object.value46",189"object.value47",190191// Stage Properties192"stage.state",193"stage.activeList",194"stage.listPos",195"stage.timeEnabled",196"stage.milliSeconds",197"stage.seconds",198"stage.minutes",199"stage.actNum",200"stage.pauseEnabled",201"stage.listSize",202"stage.newXBoundary1",203"stage.newXBoundary2",204"stage.newYBoundary1",205"stage.newYBoundary2",206"stage.curXBoundary1",207"stage.curXBoundary2",208"stage.curYBoundary1",209"stage.curYBoundary2",210"stage.deformationData0",211"stage.deformationData1",212"stage.deformationData2",213"stage.deformationData3",214"stage.waterLevel",215"stage.activeLayer",216"stage.midPoint",217"stage.playerListPos",218"stage.debugMode",219"stage.entityPos",220221// Screen Properties222"screen.cameraEnabled",223"screen.cameraTarget",224"screen.cameraStyle",225"screen.cameraX",226"screen.cameraY",227"screen.drawListSize",228"screen.xcenter",229"screen.ycenter",230"screen.xsize",231"screen.ysize",232"screen.xoffset",233"screen.yoffset",234"screen.shakeX",235"screen.shakeY",236"screen.adjustCameraY",237238"touchscreen.down",239"touchscreen.xpos",240"touchscreen.ypos",241242// Sound Properties243"music.volume",244"music.currentTrack",245"music.position",246247// Input Properties248"keyDown.up",249"keyDown.down",250"keyDown.left",251"keyDown.right",252"keyDown.buttonA",253"keyDown.buttonB",254"keyDown.buttonC",255"keyDown.buttonX",256"keyDown.buttonY",257"keyDown.buttonZ",258"keyDown.buttonL",259"keyDown.buttonR",260"keyDown.start",261"keyDown.select",262"keyPress.up",263"keyPress.down",264"keyPress.left",265"keyPress.right",266"keyPress.buttonA",267"keyPress.buttonB",268"keyPress.buttonC",269"keyPress.buttonX",270"keyPress.buttonY",271"keyPress.buttonZ",272"keyPress.buttonL",273"keyPress.buttonR",274"keyPress.start",275"keyPress.select",276277// Menu Properties278"menu1.selection",279"menu2.selection",280281// Tile Layer Properties282"tileLayer.xsize",283"tileLayer.ysize",284"tileLayer.type",285"tileLayer.angle",286"tileLayer.xpos",287"tileLayer.ypos",288"tileLayer.zpos",289"tileLayer.parallaxFactor",290"tileLayer.scrollSpeed",291"tileLayer.scrollPos",292"tileLayer.deformationOffset",293"tileLayer.deformationOffsetW",294"hParallax.parallaxFactor",295"hParallax.scrollSpeed",296"hParallax.scrollPos",297"vParallax.parallaxFactor",298"vParallax.scrollSpeed",299"vParallax.scrollPos",300301// 3D Scene Properties302"scene3D.vertexCount",303"scene3D.faceCount",304"scene3D.projectionX",305"scene3D.projectionY",306#if !RETRO_REV00307"scene3D.fogColor",308"scene3D.fogStrength",309#endif310311"vertexBuffer.x",312"vertexBuffer.y",313"vertexBuffer.z",314"vertexBuffer.u",315"vertexBuffer.v",316317"faceBuffer.a",318"faceBuffer.b",319"faceBuffer.c",320"faceBuffer.d",321"faceBuffer.flag",322"faceBuffer.color",323324"saveRAM",325"engine.state",326#if RETRO_REV00327"engine.message",328#endif329"engine.language",330"engine.onlineActive",331"engine.sfxVolume",332"engine.bgmVolume",333#if RETRO_REV00334"engine.platformID",335#endif336"engine.trialMode",337#if !RETRO_REV00338"engine.deviceType",339#endif340341// Extras342#if RETRO_REV03343"screen.currentID",344"camera.enabled",345"camera.target",346"camera.style",347"camera.xpos",348"camera.ypos",349"camera.adjustY",350#endif351352// Haptics353#if RETRO_USE_HAPTICS354"engine.hapticsEnabled",355#endif356};357#endif358359const FunctionInfo functions[] = {360FunctionInfo("End", 0), // End of Script361FunctionInfo("Equal", 2), // Equal362FunctionInfo("Add", 2), // Add363FunctionInfo("Sub", 2), // Subtract364FunctionInfo("Inc", 1), // Increment365FunctionInfo("Dec", 1), // Decrement366FunctionInfo("Mul", 2), // Multiply367FunctionInfo("Div", 2), // Divide368FunctionInfo("ShR", 2), // Bit Shift Right369FunctionInfo("ShL", 2), // Bit Shift Left370FunctionInfo("And", 2), // Bitwise And371FunctionInfo("Or", 2), // Bitwise Or372FunctionInfo("Xor", 2), // Bitwise Xor373FunctionInfo("Mod", 2), // Mod374FunctionInfo("FlipSign", 1), // Flips the Sign of the value375376FunctionInfo("CheckEqual", 2), // compare a=b, return result in CheckResult Variable377FunctionInfo("CheckGreater", 2), // compare a>b, return result in CheckResult Variable378FunctionInfo("CheckLower", 2), // compare a<b, return result in CheckResult Variable379FunctionInfo("CheckNotEqual", 2), // compare a!=b, return result in CheckResult Variable380381FunctionInfo("IfEqual", 3), // compare a=b, jump if condition met382FunctionInfo("IfGreater", 3), // compare a>b, jump if condition met383FunctionInfo("IfGreaterOrEqual", 3), // compare a>=b, jump if condition met384FunctionInfo("IfLower", 3), // compare a<b, jump if condition met385FunctionInfo("IfLowerOrEqual", 3), // compare a<=b, jump if condition met386FunctionInfo("IfNotEqual", 3), // compare a!=b, jump if condition met387FunctionInfo("else", 0), // The else for an if statement388FunctionInfo("endif", 0), // The end if389390FunctionInfo("WEqual", 3), // compare a=b, loop if condition met391FunctionInfo("WGreater", 3), // compare a>b, loop if condition met392FunctionInfo("WGreaterOrEqual", 3), // compare a>=b, loop if condition met393FunctionInfo("WLower", 3), // compare a<b, loop if condition met394FunctionInfo("WLowerOrEqual", 3), // compare a<=b, loop if condition met395FunctionInfo("WNotEqual", 3), // compare a!=b, loop if condition met396FunctionInfo("loop", 0), // While Loop marker397398FunctionInfo("ForEachActive", 3), // foreach loop, iterates through object group lists only if they are active and interaction is true399FunctionInfo("ForEachAll", 3), // foreach loop, iterates through objects matching type400FunctionInfo("next", 0), // foreach loop, next marker401402FunctionInfo("switch", 2), // Switch Statement403FunctionInfo("break", 0), // break404FunctionInfo("endswitch", 0), // endswitch405406// Math Functions407FunctionInfo("Rand", 2),408FunctionInfo("Sin", 2),409FunctionInfo("Cos", 2),410FunctionInfo("Sin256", 2),411FunctionInfo("Cos256", 2),412FunctionInfo("ATan2", 3),413FunctionInfo("Interpolate", 4),414FunctionInfo("InterpolateXY", 7),415416// Graphics Functions417FunctionInfo("LoadSpriteSheet", 1),418FunctionInfo("RemoveSpriteSheet", 1),419FunctionInfo("DrawSprite", 1),420FunctionInfo("DrawSpriteXY", 3),421FunctionInfo("DrawSpriteScreenXY", 3),422FunctionInfo("DrawTintRect", 4),423FunctionInfo("DrawNumbers", 7),424FunctionInfo("DrawActName", 7),425FunctionInfo("DrawMenu", 3),426FunctionInfo("SpriteFrame", 6),427FunctionInfo("EditFrame", 7),428FunctionInfo("LoadPalette", 5),429FunctionInfo("RotatePalette", 4),430FunctionInfo("SetScreenFade", 4),431FunctionInfo("SetActivePalette", 3),432#if RETRO_REV00433FunctionInfo("SetPaletteFade", 7),434#else435FunctionInfo("SetPaletteFade", 6),436#endif437FunctionInfo("SetPaletteEntry", 3),438FunctionInfo("GetPaletteEntry", 3),439FunctionInfo("CopyPalette", 5),440FunctionInfo("ClearScreen", 1),441FunctionInfo("DrawSpriteFX", 4),442FunctionInfo("DrawSpriteScreenFX", 4),443444// More Useful Stuff445FunctionInfo("LoadAnimation", 1),446FunctionInfo("SetupMenu", 4),447FunctionInfo("AddMenuEntry", 3),448FunctionInfo("EditMenuEntry", 4),449FunctionInfo("LoadStage", 0),450FunctionInfo("DrawRect", 8),451FunctionInfo("ResetObjectEntity", 5),452FunctionInfo("BoxCollisionTest", 11),453FunctionInfo("CreateTempObject", 4),454455// Player and Animation Functions456FunctionInfo("ProcessObjectMovement", 0),457FunctionInfo("ProcessObjectControl", 0),458FunctionInfo("ProcessAnimation", 0),459FunctionInfo("DrawObjectAnimation", 0),460461// Music462FunctionInfo("SetMusicTrack", 3),463FunctionInfo("PlayMusic", 1),464FunctionInfo("StopMusic", 0),465FunctionInfo("PauseMusic", 0),466FunctionInfo("ResumeMusic", 0),467FunctionInfo("SwapMusicTrack", 4),468469// Sound FX470FunctionInfo("PlaySfx", 2),471FunctionInfo("StopSfx", 1),472FunctionInfo("SetSfxAttributes", 3),473474// More Collision Stuff475FunctionInfo("ObjectTileCollision", 4),476FunctionInfo("ObjectTileGrip", 4),477478// Bitwise Not479FunctionInfo("Not", 1),480481// 3D Stuff482FunctionInfo("Draw3DScene", 0),483FunctionInfo("SetIdentityMatrix", 1),484FunctionInfo("MatrixMultiply", 2),485FunctionInfo("MatrixTranslateXYZ", 4),486FunctionInfo("MatrixScaleXYZ", 4),487FunctionInfo("MatrixRotateX", 2),488FunctionInfo("MatrixRotateY", 2),489FunctionInfo("MatrixRotateZ", 2),490FunctionInfo("MatrixRotateXYZ", 4),491#if !RETRO_REV00492FunctionInfo("MatrixInverse", 1),493#endif494FunctionInfo("TransformVertices", 3),495496FunctionInfo("CallFunction", 1),497FunctionInfo("return", 0),498499FunctionInfo("SetLayerDeformation", 6),500FunctionInfo("CheckTouchRect", 4),501FunctionInfo("GetTileLayerEntry", 4),502FunctionInfo("SetTileLayerEntry", 4),503504FunctionInfo("GetBit", 3),505FunctionInfo("SetBit", 3),506507FunctionInfo("ClearDrawList", 1),508FunctionInfo("AddDrawListEntityRef", 2),509FunctionInfo("GetDrawListEntityRef", 3),510FunctionInfo("SetDrawListEntityRef", 3),511512FunctionInfo("Get16x16TileInfo", 4),513FunctionInfo("Set16x16TileInfo", 4),514FunctionInfo("Copy16x16Tile", 2),515FunctionInfo("GetAnimationByName", 2),516FunctionInfo("ReadSaveRAM", 0),517FunctionInfo("WriteSaveRAM", 0),518519#if !RETRO_REV02520FunctionInfo("LoadFontFile", 1),521FunctionInfo("LoadTextFile", 3),522#else523FunctionInfo("LoadTextFile", 2),524#endif525FunctionInfo("GetTextInfo", 5),526#if !RETRO_REV02527FunctionInfo("DrawText", 7),528#endif529FunctionInfo("GetVersionNumber", 2),530531FunctionInfo("GetTableValue", 3),532FunctionInfo("SetTableValue", 3),533534FunctionInfo("CheckCurrentStageFolder", 1),535FunctionInfo("Abs", 1),536537FunctionInfo("CallNativeFunction", 1),538FunctionInfo("CallNativeFunction2", 3),539FunctionInfo("CallNativeFunction4", 5),540541FunctionInfo("SetObjectRange", 1),542#if RETRO_REV02543FunctionInfo("GetObjectValue", 3),544FunctionInfo("SetObjectValue", 3),545FunctionInfo("CopyObject", 3),546#endif547FunctionInfo("Print", 3),548549#if RETRO_REV03550// Extras551FunctionInfo("CheckCameraProximity", 4),552FunctionInfo("SetScreenCount", 1),553FunctionInfo("SetScreenVertices", 5),554FunctionInfo("GetInputDeviceID", 2),555FunctionInfo("GetFilteredInputDeviceID", 4),556FunctionInfo("GetInputDeviceType", 2),557FunctionInfo("IsInputDeviceAssigned", 1),558FunctionInfo("AssignInputSlotToDevice", 2),559FunctionInfo("IsInputSlotAssigned", 1),560FunctionInfo("ResetInputSlotAssignments", 0),561#endif562};563564#if RETRO_USE_COMPILER565566int scriptValueListCount = 0;567// clang-format off568ScriptVariableInfo scriptValueList[SCRIPT_VAR_COUNT] = {569ScriptVariableInfo(VAR_ALIAS, ACCESS_PUBLIC, "true", "1"),570ScriptVariableInfo(VAR_ALIAS, ACCESS_PUBLIC, "false", "0"),571ScriptVariableInfo(VAR_ALIAS, ACCESS_PUBLIC, "FX_SCALE", "0"),572ScriptVariableInfo(VAR_ALIAS, ACCESS_PUBLIC, "FX_ROTATE", "1"),573ScriptVariableInfo(VAR_ALIAS, ACCESS_PUBLIC, "FX_ROTOZOOM", "2"),574ScriptVariableInfo(VAR_ALIAS, ACCESS_PUBLIC, "FX_INK", "3"),575ScriptVariableInfo(VAR_ALIAS, ACCESS_PUBLIC, "PRESENTATION_STAGE", "0"),576ScriptVariableInfo(VAR_ALIAS, ACCESS_PUBLIC, "REGULAR_STAGE", "1"),577ScriptVariableInfo(VAR_ALIAS, ACCESS_PUBLIC, "BONUS_STAGE", "2"),578ScriptVariableInfo(VAR_ALIAS, ACCESS_PUBLIC, "SPECIAL_STAGE", "3"),579ScriptVariableInfo(VAR_ALIAS, ACCESS_PUBLIC, "MENU_1", "0"),580ScriptVariableInfo(VAR_ALIAS, ACCESS_PUBLIC, "MENU_2", "1"),581ScriptVariableInfo(VAR_ALIAS, ACCESS_PUBLIC, "C_TOUCH", "0"),582ScriptVariableInfo(VAR_ALIAS, ACCESS_PUBLIC, "C_SOLID", "1"),583ScriptVariableInfo(VAR_ALIAS, ACCESS_PUBLIC, "C_SOLID2", "2"),584ScriptVariableInfo(VAR_ALIAS, ACCESS_PUBLIC, "C_PLATFORM", "3"),585ScriptVariableInfo(VAR_ALIAS, ACCESS_PUBLIC, "C_BOX", "65536"),586ScriptVariableInfo(VAR_ALIAS, ACCESS_PUBLIC, "MAT_WORLD", "0"),587ScriptVariableInfo(VAR_ALIAS, ACCESS_PUBLIC, "MAT_VIEW", "1"),588ScriptVariableInfo(VAR_ALIAS, ACCESS_PUBLIC, "MAT_TEMP", "2"),589ScriptVariableInfo(VAR_ALIAS, ACCESS_PUBLIC, "FX_FLIP", "5"),590ScriptVariableInfo(VAR_ALIAS, ACCESS_PUBLIC, "FACING_LEFT", "1"),591ScriptVariableInfo(VAR_ALIAS, ACCESS_PUBLIC, "FACING_RIGHT", "0"),592#if !RETRO_REV00593ScriptVariableInfo(VAR_ALIAS, ACCESS_PUBLIC, "STAGE_2P_MODE", "4"),594#endif595ScriptVariableInfo(VAR_ALIAS, ACCESS_PUBLIC, "STAGE_FROZEN", "3"),596ScriptVariableInfo(VAR_ALIAS, ACCESS_PUBLIC, "STAGE_PAUSED", "2"),597ScriptVariableInfo(VAR_ALIAS, ACCESS_PUBLIC, "STAGE_RUNNING", "1"),598ScriptVariableInfo(VAR_ALIAS, ACCESS_PUBLIC, "RESET_GAME", "2"),599ScriptVariableInfo(VAR_ALIAS, ACCESS_PUBLIC, "STANDARD", "0"),600ScriptVariableInfo(VAR_ALIAS, ACCESS_PUBLIC, "MOBILE", "1"),601ScriptVariableInfo(VAR_ALIAS, ACCESS_PUBLIC, "DEVICE_XBOX", "2"),602ScriptVariableInfo(VAR_ALIAS, ACCESS_PUBLIC, "DEVICE_PSN", "3"),603ScriptVariableInfo(VAR_ALIAS, ACCESS_PUBLIC, "DEVICE_IOS", "4"),604ScriptVariableInfo(VAR_ALIAS, ACCESS_PUBLIC, "DEVICE_ANDROID", "5"),605};606// clang-format on607608const char scriptEvaluationTokens[][0x4] = { "=", "+=", "-=", "++", "--", "*=", "/=", ">>=", "<<=", "&=",609"|=", "^=", "%=", "==", ">", ">=", "<", "<=", "!=" };610611enum ScriptReadModes { READMODE_NORMAL = 0, READMODE_STRING = 1, READMODE_COMMENTLINE = 2, READMODE_ENDLINE = 3, READMODE_EOF = 4 };612enum ScriptParseModes {613PARSEMODE_SCOPELESS = 0,614PARSEMODE_PLATFORMSKIP = 1,615PARSEMODE_FUNCTION = 2,616PARSEMODE_SWITCHREAD = 3,617PARSEMODE_TABLEREAD = 4,618PARSEMODE_ERROR = 0xFF619};620#endif621622enum ScriptVarTypes { SCRIPTVAR_VAR = 1, SCRIPTVAR_INTCONST = 2, SCRIPTVAR_STRCONST = 3 };623enum ScriptVarArrTypes { VARARR_NONE = 0, VARARR_ARRAY = 1, VARARR_ENTNOPLUS1 = 2, VARARR_ENTNOMINUS1 = 3 };624625enum ScrVar {626VAR_TEMP0,627VAR_TEMP1,628VAR_TEMP2,629VAR_TEMP3,630VAR_TEMP4,631VAR_TEMP5,632VAR_TEMP6,633VAR_TEMP7,634VAR_CHECKRESULT,635VAR_ARRAYPOS0,636VAR_ARRAYPOS1,637VAR_ARRAYPOS2,638VAR_ARRAYPOS3,639VAR_ARRAYPOS4,640VAR_ARRAYPOS5,641VAR_ARRAYPOS6,642VAR_ARRAYPOS7,643VAR_GLOBAL,644VAR_LOCAL,645VAR_OBJECTENTITYPOS,646VAR_OBJECTGROUPID,647VAR_OBJECTTYPE,648VAR_OBJECTPROPERTYVALUE,649VAR_OBJECTXPOS,650VAR_OBJECTYPOS,651VAR_OBJECTIXPOS,652VAR_OBJECTIYPOS,653VAR_OBJECTXVEL,654VAR_OBJECTYVEL,655VAR_OBJECTSPEED,656VAR_OBJECTSTATE,657VAR_OBJECTROTATION,658VAR_OBJECTSCALE,659VAR_OBJECTPRIORITY,660VAR_OBJECTDRAWORDER,661VAR_OBJECTDIRECTION,662VAR_OBJECTINKEFFECT,663VAR_OBJECTALPHA,664VAR_OBJECTFRAME,665VAR_OBJECTANIMATION,666VAR_OBJECTPREVANIMATION,667VAR_OBJECTANIMATIONSPEED,668VAR_OBJECTANIMATIONTIMER,669VAR_OBJECTANGLE,670VAR_OBJECTLOOKPOSX,671VAR_OBJECTLOOKPOSY,672VAR_OBJECTCOLLISIONMODE,673VAR_OBJECTCOLLISIONPLANE,674VAR_OBJECTCONTROLMODE,675VAR_OBJECTCONTROLLOCK,676VAR_OBJECTPUSHING,677VAR_OBJECTVISIBLE,678VAR_OBJECTTILECOLLISIONS,679VAR_OBJECTINTERACTION,680VAR_OBJECTGRAVITY,681VAR_OBJECTUP,682VAR_OBJECTDOWN,683VAR_OBJECTLEFT,684VAR_OBJECTRIGHT,685VAR_OBJECTJUMPPRESS,686VAR_OBJECTJUMPHOLD,687VAR_OBJECTSCROLLTRACKING,688VAR_OBJECTFLOORSENSORL,689VAR_OBJECTFLOORSENSORC,690VAR_OBJECTFLOORSENSORR,691#if !RETRO_REV00692VAR_OBJECTFLOORSENSORLC,693VAR_OBJECTFLOORSENSORRC,694#endif695VAR_OBJECTCOLLISIONLEFT,696VAR_OBJECTCOLLISIONTOP,697VAR_OBJECTCOLLISIONRIGHT,698VAR_OBJECTCOLLISIONBOTTOM,699VAR_OBJECTOUTOFBOUNDS,700VAR_OBJECTSPRITESHEET,701VAR_OBJECTVALUE0,702VAR_OBJECTVALUE1,703VAR_OBJECTVALUE2,704VAR_OBJECTVALUE3,705VAR_OBJECTVALUE4,706VAR_OBJECTVALUE5,707VAR_OBJECTVALUE6,708VAR_OBJECTVALUE7,709VAR_OBJECTVALUE8,710VAR_OBJECTVALUE9,711VAR_OBJECTVALUE10,712VAR_OBJECTVALUE11,713VAR_OBJECTVALUE12,714VAR_OBJECTVALUE13,715VAR_OBJECTVALUE14,716VAR_OBJECTVALUE15,717VAR_OBJECTVALUE16,718VAR_OBJECTVALUE17,719VAR_OBJECTVALUE18,720VAR_OBJECTVALUE19,721VAR_OBJECTVALUE20,722VAR_OBJECTVALUE21,723VAR_OBJECTVALUE22,724VAR_OBJECTVALUE23,725VAR_OBJECTVALUE24,726VAR_OBJECTVALUE25,727VAR_OBJECTVALUE26,728VAR_OBJECTVALUE27,729VAR_OBJECTVALUE28,730VAR_OBJECTVALUE29,731VAR_OBJECTVALUE30,732VAR_OBJECTVALUE31,733VAR_OBJECTVALUE32,734VAR_OBJECTVALUE33,735VAR_OBJECTVALUE34,736VAR_OBJECTVALUE35,737VAR_OBJECTVALUE36,738VAR_OBJECTVALUE37,739VAR_OBJECTVALUE38,740VAR_OBJECTVALUE39,741VAR_OBJECTVALUE40,742VAR_OBJECTVALUE41,743VAR_OBJECTVALUE42,744VAR_OBJECTVALUE43,745VAR_OBJECTVALUE44,746VAR_OBJECTVALUE45,747VAR_OBJECTVALUE46,748VAR_OBJECTVALUE47,749VAR_STAGESTATE,750VAR_STAGEACTIVELIST,751VAR_STAGELISTPOS,752VAR_STAGETIMEENABLED,753VAR_STAGEMILLISECONDS,754VAR_STAGESECONDS,755VAR_STAGEMINUTES,756VAR_STAGEACTNUM,757VAR_STAGEPAUSEENABLED,758VAR_STAGELISTSIZE,759VAR_STAGENEWXBOUNDARY1,760VAR_STAGENEWXBOUNDARY2,761VAR_STAGENEWYBOUNDARY1,762VAR_STAGENEWYBOUNDARY2,763VAR_STAGECURXBOUNDARY1,764VAR_STAGECURXBOUNDARY2,765VAR_STAGECURYBOUNDARY1,766VAR_STAGECURYBOUNDARY2,767VAR_STAGEDEFORMATIONDATA0,768VAR_STAGEDEFORMATIONDATA1,769VAR_STAGEDEFORMATIONDATA2,770VAR_STAGEDEFORMATIONDATA3,771VAR_STAGEWATERLEVEL,772VAR_STAGEACTIVELAYER,773VAR_STAGEMIDPOINT,774VAR_STAGEPLAYERLISTPOS,775VAR_STAGEDEBUGMODE,776VAR_STAGEENTITYPOS,777VAR_SCREENCAMERAENABLED,778VAR_SCREENCAMERATARGET,779VAR_SCREENCAMERASTYLE,780VAR_SCREENCAMERAX,781VAR_SCREENCAMERAY,782VAR_SCREENDRAWLISTSIZE,783VAR_SCREENXCENTER,784VAR_SCREENYCENTER,785VAR_SCREENXSIZE,786VAR_SCREENYSIZE,787VAR_SCREENXOFFSET,788VAR_SCREENYOFFSET,789VAR_SCREENSHAKEX,790VAR_SCREENSHAKEY,791VAR_SCREENADJUSTCAMERAY,792VAR_TOUCHSCREENDOWN,793VAR_TOUCHSCREENXPOS,794VAR_TOUCHSCREENYPOS,795VAR_MUSICVOLUME,796VAR_MUSICCURRENTTRACK,797VAR_MUSICPOSITION,798VAR_KEYDOWNUP,799VAR_KEYDOWNDOWN,800VAR_KEYDOWNLEFT,801VAR_KEYDOWNRIGHT,802VAR_KEYDOWNBUTTONA,803VAR_KEYDOWNBUTTONB,804VAR_KEYDOWNBUTTONC,805VAR_KEYDOWNBUTTONX,806VAR_KEYDOWNBUTTONY,807VAR_KEYDOWNBUTTONZ,808VAR_KEYDOWNBUTTONL,809VAR_KEYDOWNBUTTONR,810VAR_KEYDOWNSTART,811VAR_KEYDOWNSELECT,812VAR_KEYPRESSUP,813VAR_KEYPRESSDOWN,814VAR_KEYPRESSLEFT,815VAR_KEYPRESSRIGHT,816VAR_KEYPRESSBUTTONA,817VAR_KEYPRESSBUTTONB,818VAR_KEYPRESSBUTTONC,819VAR_KEYPRESSBUTTONX,820VAR_KEYPRESSBUTTONY,821VAR_KEYPRESSBUTTONZ,822VAR_KEYPRESSBUTTONL,823VAR_KEYPRESSBUTTONR,824VAR_KEYPRESSSTART,825VAR_KEYPRESSSELECT,826VAR_MENU1SELECTION,827VAR_MENU2SELECTION,828VAR_TILELAYERXSIZE,829VAR_TILELAYERYSIZE,830VAR_TILELAYERTYPE,831VAR_TILELAYERANGLE,832VAR_TILELAYERXPOS,833VAR_TILELAYERYPOS,834VAR_TILELAYERZPOS,835VAR_TILELAYERPARALLAXFACTOR,836VAR_TILELAYERSCROLLSPEED,837VAR_TILELAYERSCROLLPOS,838VAR_TILELAYERDEFORMATIONOFFSET,839VAR_TILELAYERDEFORMATIONOFFSETW,840VAR_HPARALLAXPARALLAXFACTOR,841VAR_HPARALLAXSCROLLSPEED,842VAR_HPARALLAXSCROLLPOS,843VAR_VPARALLAXPARALLAXFACTOR,844VAR_VPARALLAXSCROLLSPEED,845VAR_VPARALLAXSCROLLPOS,846VAR_SCENE3DVERTEXCOUNT,847VAR_SCENE3DFACECOUNT,848VAR_SCENE3DPROJECTIONX,849VAR_SCENE3DPROJECTIONY,850#if !RETRO_REV00851VAR_SCENE3DFOGCOLOR,852VAR_SCENE3DFOGSTRENGTH,853#endif854VAR_VERTEXBUFFERX,855VAR_VERTEXBUFFERY,856VAR_VERTEXBUFFERZ,857VAR_VERTEXBUFFERU,858VAR_VERTEXBUFFERV,859VAR_FACEBUFFERA,860VAR_FACEBUFFERB,861VAR_FACEBUFFERC,862VAR_FACEBUFFERD,863VAR_FACEBUFFERFLAG,864VAR_FACEBUFFERCOLOR,865VAR_SAVERAM,866VAR_ENGINESTATE,867#if RETRO_REV00868VAR_ENGINEMESSAGE,869#endif870VAR_ENGINELANGUAGE,871VAR_ENGINEONLINEACTIVE,872VAR_ENGINESFXVOLUME,873VAR_ENGINEBGMVOLUME,874#if RETRO_REV00875VAR_ENGINEPLATFORMID, // v3-style device type aka Windows/Mac/Android/etc876#endif877VAR_ENGINETRIALMODE,878#if !RETRO_REV00879VAR_ENGINEDEVICETYPE, // v4-style device type aka Standard/Mobile/Etc880#endif881882#if RETRO_REV03883// Extras884VAR_SCREENCURRENTID,885VAR_CAMERAENABLED,886VAR_CAMERATARGET,887VAR_CAMERASTYLE,888VAR_CAMERAXPOS,889VAR_CAMERAYPOS,890VAR_CAMERAADJUSTY,891#endif892893#if RETRO_USE_HAPTICS894VAR_HAPTICSENABLED,895#endif896VAR_MAX_CNT897};898899enum ScrFunc {900FUNC_END,901FUNC_EQUAL,902FUNC_ADD,903FUNC_SUB,904FUNC_INC,905FUNC_DEC,906FUNC_MUL,907FUNC_DIV,908FUNC_SHR,909FUNC_SHL,910FUNC_AND,911FUNC_OR,912FUNC_XOR,913FUNC_MOD,914FUNC_FLIPSIGN,915FUNC_CHECKEQUAL,916FUNC_CHECKGREATER,917FUNC_CHECKLOWER,918FUNC_CHECKNOTEQUAL,919FUNC_IFEQUAL,920FUNC_IFGREATER,921FUNC_IFGREATEROREQUAL,922FUNC_IFLOWER,923FUNC_IFLOWEROREQUAL,924FUNC_IFNOTEQUAL,925FUNC_ELSE,926FUNC_ENDIF,927FUNC_WEQUAL,928FUNC_WGREATER,929FUNC_WGREATEROREQUAL,930FUNC_WLOWER,931FUNC_WLOWEROREQUAL,932FUNC_WNOTEQUAL,933FUNC_LOOP,934FUNC_FOREACHACTIVE,935FUNC_FOREACHALL,936FUNC_NEXT,937FUNC_SWITCH,938FUNC_BREAK,939FUNC_ENDSWITCH,940FUNC_RAND,941FUNC_SIN,942FUNC_COS,943FUNC_SIN256,944FUNC_COS256,945FUNC_ATAN2,946FUNC_INTERPOLATE,947FUNC_INTERPOLATEXY,948FUNC_LOADSPRITESHEET,949FUNC_REMOVESPRITESHEET,950FUNC_DRAWSPRITE,951FUNC_DRAWSPRITEXY,952FUNC_DRAWSPRITESCREENXY,953FUNC_DRAWTINTRECT,954FUNC_DRAWNUMBERS,955FUNC_DRAWACTNAME,956FUNC_DRAWMENU,957FUNC_SPRITEFRAME,958FUNC_EDITFRAME,959FUNC_LOADPALETTE,960FUNC_ROTATEPALETTE,961FUNC_SETSCREENFADE,962FUNC_SETACTIVEPALETTE,963FUNC_SETPALETTEFADE,964FUNC_SETPALETTEENTRY,965FUNC_GETPALETTEENTRY,966FUNC_COPYPALETTE,967FUNC_CLEARSCREEN,968FUNC_DRAWSPRITEFX,969FUNC_DRAWSPRITESCREENFX,970FUNC_LOADANIMATION,971FUNC_SETUPMENU,972FUNC_ADDMENUENTRY,973FUNC_EDITMENUENTRY,974FUNC_LOADSTAGE,975FUNC_DRAWRECT,976FUNC_RESETOBJECTENTITY,977FUNC_BOXCOLLISIONTEST,978FUNC_CREATETEMPOBJECT,979FUNC_PROCESSOBJECTMOVEMENT,980FUNC_PROCESSOBJECTCONTROL,981FUNC_PROCESSANIMATION,982FUNC_DRAWOBJECTANIMATION,983FUNC_SETMUSICTRACK,984FUNC_PLAYMUSIC,985FUNC_STOPMUSIC,986FUNC_PAUSEMUSIC,987FUNC_RESUMEMUSIC,988FUNC_SWAPMUSICTRACK,989FUNC_PLAYSFX,990FUNC_STOPSFX,991FUNC_SETSFXATTRIBUTES,992FUNC_OBJECTTILECOLLISION,993FUNC_OBJECTTILEGRIP,994FUNC_NOT,995FUNC_DRAW3DSCENE,996FUNC_SETIDENTITYMATRIX,997FUNC_MATRIXMULTIPLY,998FUNC_MATRIXTRANSLATEXYZ,999FUNC_MATRIXSCALEXYZ,1000FUNC_MATRIXROTATEX,1001FUNC_MATRIXROTATEY,1002FUNC_MATRIXROTATEZ,1003FUNC_MATRIXROTATEXYZ,1004#if !RETRO_REV001005FUNC_MATRIXINVERSE,1006#endif1007FUNC_TRANSFORMVERTICES,1008FUNC_CALLFUNCTION,1009FUNC_RETURN,1010FUNC_SETLAYERDEFORMATION,1011FUNC_CHECKTOUCHRECT,1012FUNC_GETTILELAYERENTRY,1013FUNC_SETTILELAYERENTRY,1014FUNC_GETBIT,1015FUNC_SETBIT,1016FUNC_CLEARDRAWLIST,1017FUNC_ADDDRAWLISTENTITYREF,1018FUNC_GETDRAWLISTENTITYREF,1019FUNC_SETDRAWLISTENTITYREF,1020FUNC_GET16X16TILEINFO,1021FUNC_SET16X16TILEINFO,1022FUNC_COPY16X16TILE,1023FUNC_GETANIMATIONBYNAME,1024FUNC_READSAVERAM,1025FUNC_WRITESAVERAM,1026#if !RETRO_REV021027FUNC_LOADTEXTFONT,1028#endif1029FUNC_LOADTEXTFILE,1030FUNC_GETTEXTINFO,1031#if !RETRO_REV021032FUNC_DRAWTEXT,1033#endif1034FUNC_GETVERSIONNUMBER,1035FUNC_GETTABLEVALUE,1036FUNC_SETTABLEVALUE,1037FUNC_CHECKCURRENTSTAGEFOLDER,1038FUNC_ABS,1039FUNC_CALLNATIVEFUNCTION,1040FUNC_CALLNATIVEFUNCTION2,1041FUNC_CALLNATIVEFUNCTION4,1042FUNC_SETOBJECTRANGE,1043#if RETRO_REV021044FUNC_GETOBJECTVALUE,1045FUNC_SETOBJECTVALUE,1046FUNC_COPYOBJECT,1047#endif1048FUNC_PRINT,10491050#if RETRO_REV031051// Extras1052FUNC_CHECKCAMERAPROXIMITY,1053FUNC_SETSCREENCOUNT,1054FUNC_SETSCREENVERTICES,1055FUNC_GETINPUTDEVICEID,1056FUNC_GETFILTEREDINPUTDEVICEID,1057FUNC_GETINPUTDEVICETYPE,1058FUNC_ISINPUTDEVICEASSIGNED,1059FUNC_ASSIGNINPUTSLOTTODEVICE,1060FUNC_ISSLOTASSIGNED,1061FUNC_RESETINPUTSLOTASSIGNMENTS,1062#endif1063FUNC_MAX_CNT1064};10651066ObjectScript objectScriptList[OBJECT_COUNT];1067ScriptFunction scriptFunctionList[FUNCTION_COUNT];1068#if RETRO_USE_COMPILER1069int scriptFunctionCount = 0;1070#endif10711072int scriptCode[SCRIPTCODE_COUNT];1073int jumpTable[JUMPTABLE_COUNT];1074int jumpTableStack[JUMPSTACK_COUNT];1075int functionStack[FUNCSTACK_COUNT];1076int foreachStack[FORSTACK_COUNT];10771078int scriptCodePos = 0;1079int scriptCodeOffset = 0;1080int jumpTablePos = 0;1081int jumpTableOffset = 0;1082int jumpTableStackPos = 0;1083int functionStackPos = 0;1084int foreachStackPos = 0;10851086ScriptEngine scriptEng = ScriptEngine();1087char scriptText[0x4000];10881089#if RETRO_USE_COMPILER1090void CheckAliasText(char *text)1091{1092if (FindStringToken(text, "publicalias", 1) == 0) {1093#if !RETRO_USE_ORIGINAL_CODE1094if (scriptValueListCount >= SCRIPT_VAR_COUNT) {1095SetupTextMenu(&gameMenu[0], 0);1096AddTextMenuEntry(&gameMenu[0], "SCRIPT PARSING FAILED");1097AddTextMenuEntry(&gameMenu[0], " ");1098AddTextMenuEntry(&gameMenu[0], "TOO MANY ALIASES, STATIC");1099AddTextMenuEntry(&gameMenu[0], "VALUES, AND TABLES");1100Engine.gameMode = ENGINE_SCRIPTERROR;1101return;1102}1103#endif11041105ScriptVariableInfo *variable = &scriptValueList[scriptValueListCount];1106MEM_ZEROP(variable);11071108int textStrPos = 11;1109int varStrPos = 0;1110int parseMode = 0;11111112while (text[textStrPos]) {1113switch (parseMode) {1114default: break;11151116case 0:1117if (text[textStrPos] == ':') {1118textStrPos++;1119variable->value[varStrPos] = 0;1120varStrPos = 0;1121parseMode = 1;1122}1123else {1124variable->value[varStrPos++] = text[textStrPos++];1125}1126break;11271128case 1: variable->name[varStrPos++] = text[textStrPos++]; break;1129}1130}11311132variable->access = ACCESS_PUBLIC;11331134#if !RETRO_USE_ORIGINAL_CODE1135for (int v = 0; v < scriptValueListCount; ++v) {1136if (StrComp(scriptValueList[v].name, variable->name))1137PrintLog("WARNING: Variable Name '%s' has already been used!", variable->name);1138}1139#endif11401141++scriptValueListCount;1142}1143else if (FindStringToken(text, "privatealias", 1) == 0) {1144#if !RETRO_USE_ORIGINAL_CODE1145if (scriptValueListCount >= SCRIPT_VAR_COUNT) {1146SetupTextMenu(&gameMenu[0], 0);1147AddTextMenuEntry(&gameMenu[0], "SCRIPT PARSING FAILED");1148AddTextMenuEntry(&gameMenu[0], " ");1149AddTextMenuEntry(&gameMenu[0], "TOO MANY ALIASES, STATIC");1150AddTextMenuEntry(&gameMenu[0], "VALUES, AND TABLES");1151Engine.gameMode = ENGINE_SCRIPTERROR;1152return;1153}1154#endif11551156ScriptVariableInfo *variable = &scriptValueList[scriptValueListCount];1157MEM_ZEROP(variable);11581159int textStrPos = 12;1160int varStrPos = 0;1161int parseMode = 0;11621163while (text[textStrPos]) {1164switch (parseMode) {1165default: break;11661167case 0:1168if (text[textStrPos] == ':') {1169textStrPos++;1170variable->value[varStrPos] = 0;1171varStrPos = 0;1172parseMode = 1;1173}1174else {1175variable->value[varStrPos++] = text[textStrPos++];1176}1177break;11781179case 1: variable->name[varStrPos++] = text[textStrPos++]; break;1180}1181}11821183variable->access = ACCESS_PRIVATE;11841185#if !RETRO_USE_ORIGINAL_CODE1186for (int v = 0; v < scriptValueListCount; ++v) {1187if (StrComp(scriptValueList[v].name, variable->name))1188PrintLog("WARNING: Variable Name '%s' has already been used!", variable->name);1189}1190#endif11911192++scriptValueListCount;1193}1194}1195void CheckStaticText(char *text)1196{1197if (FindStringToken(text, "publicvalue", 1) == 0) {1198#if !RETRO_USE_ORIGINAL_CODE1199if (scriptValueListCount >= SCRIPT_VAR_COUNT) {1200SetupTextMenu(&gameMenu[0], 0);1201AddTextMenuEntry(&gameMenu[0], "SCRIPT PARSING FAILED");1202AddTextMenuEntry(&gameMenu[0], " ");1203AddTextMenuEntry(&gameMenu[0], "TOO MANY ALIASES, STATIC");1204AddTextMenuEntry(&gameMenu[0], "VALUES, AND TABLES");1205Engine.gameMode = ENGINE_SCRIPTERROR;1206return;1207}1208#endif12091210ScriptVariableInfo *variable = &scriptValueList[scriptValueListCount];1211MEM_ZEROP(variable);12121213int textStrPos = 11;1214int varStrPos = 0;1215int parseMode = 0;12161217StrCopy(variable->value, "0"); // default value is 01218while (text[textStrPos]) {1219switch (parseMode) {1220default: break;12211222case 0:1223if (text[textStrPos] == '=') {1224textStrPos++;1225variable->name[varStrPos] = 0;1226varStrPos = 0;1227parseMode = 1;1228}1229else {1230variable->name[varStrPos++] = text[textStrPos++];1231}1232break;12331234case 1: variable->value[varStrPos++] = text[textStrPos++]; break;1235}1236}12371238variable->access = ACCESS_PUBLIC;12391240if (!ConvertStringToInteger(variable->value, &scriptCode[scriptCodePos]))1241scriptCode[scriptCodePos] = 0;12421243StrCopy(variable->value, "local[");1244AppendIntegerToString(variable->value, scriptCodePos++);1245StrAdd(variable->value, "]");12461247#if !RETRO_USE_ORIGINAL_CODE1248for (int v = 0; v < scriptValueListCount; ++v) {1249if (StrComp(scriptValueList[v].name, variable->name))1250PrintLog("WARNING: Variable Name '%s' has already been used!", variable->name);1251}1252#endif12531254++scriptValueListCount;1255}1256else if (FindStringToken(text, "privatevalue", 1) == 0) {1257#if !RETRO_USE_ORIGINAL_CODE1258if (scriptValueListCount >= SCRIPT_VAR_COUNT) {1259SetupTextMenu(&gameMenu[0], 0);1260AddTextMenuEntry(&gameMenu[0], "SCRIPT PARSING FAILED");1261AddTextMenuEntry(&gameMenu[0], " ");1262AddTextMenuEntry(&gameMenu[0], "TOO MANY ALIASES, STATIC");1263AddTextMenuEntry(&gameMenu[0], "VALUES, AND TABLES");1264Engine.gameMode = ENGINE_SCRIPTERROR;1265return;1266}1267#endif12681269ScriptVariableInfo *variable = &scriptValueList[scriptValueListCount];1270MEM_ZEROP(variable);12711272int textStrPos = 12;1273int varStrPos = 0;1274int parseMode = 0;12751276StrCopy(variable->value, "0"); // default value is 01277while (text[textStrPos]) {1278switch (parseMode) {1279default: break;12801281case 0:1282if (text[textStrPos] == '=') {1283textStrPos++;1284variable->name[varStrPos] = 0;1285varStrPos = 0;1286parseMode = 1;1287}1288else {1289variable->name[varStrPos++] = text[textStrPos++];1290}1291break;12921293case 1: variable->value[varStrPos++] = text[textStrPos++]; break;1294}1295}12961297variable->access = ACCESS_PRIVATE;12981299if (!ConvertStringToInteger(variable->value, &scriptCode[scriptCodePos]))1300scriptCode[scriptCodePos] = 0;13011302StrCopy(variable->value, "local[");1303AppendIntegerToString(variable->value, scriptCodePos++);1304StrAdd(variable->value, "]");13051306#if !RETRO_USE_ORIGINAL_CODE1307for (int v = 0; v < scriptValueListCount; ++v) {1308if (StrComp(scriptValueList[v].name, variable->name))1309PrintLog("WARNING: Variable Name '%s' has already been used!", variable->name);1310}1311#endif13121313++scriptValueListCount;1314}1315}1316bool CheckTableText(char *text)1317{1318bool hasValues = false;13191320if (FindStringToken(text, "publictable", 1) == 0) {1321#if !RETRO_USE_ORIGINAL_CODE1322if (scriptValueListCount >= SCRIPT_VAR_COUNT) {1323SetupTextMenu(&gameMenu[0], 0);1324AddTextMenuEntry(&gameMenu[0], "SCRIPT PARSING FAILED");1325AddTextMenuEntry(&gameMenu[0], " ");1326AddTextMenuEntry(&gameMenu[0], "TOO MANY ALIASES, STATIC");1327AddTextMenuEntry(&gameMenu[0], "VALUES, AND TABLES");1328Engine.gameMode = ENGINE_SCRIPTERROR;1329return false;1330}1331#endif13321333ScriptVariableInfo *variable = &scriptValueList[scriptValueListCount];1334MEM_ZEROP(variable);13351336int textStrPos = 11;1337int varStrPos = 0;13381339while (text[textStrPos]) {1340if (text[textStrPos] == '[' || text[textStrPos] == ']') {1341variable->name[varStrPos] = 0;1342textStrPos++;1343break;1344}1345else {1346variable->name[varStrPos++] = text[textStrPos++];1347}1348}13491350if (FindStringToken(text, "]", 1) < 1) {1351// has default values, we'll stop here and read stuff in a seperate mode1352scriptCode[scriptCodePos] = 0;1353StrCopy(variable->value, "");1354AppendIntegerToString(variable->value, scriptCodePos);1355scriptCodeOffset = scriptCodePos++;1356hasValues = true;1357}1358else {1359// no default values, just an array size13601361varStrPos = 0;1362while (text[textStrPos]) {1363if (text[textStrPos] == '[' || text[textStrPos] == ']') {1364variable->value[varStrPos] = 0;1365textStrPos++;1366break;1367}1368else {1369variable->value[varStrPos++] = text[textStrPos++];1370}1371}13721373// array size can be an variable (alias), how cool!1374for (int v = 0; v < scriptValueListCount; ++v) {1375if (StrComp(variable->value, scriptValueList[v].name))1376StrCopy(variable->value, scriptValueList[v].value);1377}13781379if (!ConvertStringToInteger(variable->value, &scriptCode[scriptCodePos])) {1380scriptCode[scriptCodePos] = 1;1381#if !RETRO_USE_ORIGINAL_CODE1382PrintLog("WARNING: Unable to parse table size!");1383#endif1384}13851386StrCopy(variable->value, "");1387AppendIntegerToString(variable->value, scriptCodePos);13881389int valueCount = scriptCode[scriptCodePos++];1390for (int v = 0; v < valueCount; ++v) scriptCode[scriptCodePos++] = 0;1391}13921393variable->access = ACCESS_PUBLIC;1394scriptValueListCount++;1395}1396else if (FindStringToken(text, "privatetable", 1) == 0) {1397#if !RETRO_USE_ORIGINAL_CODE1398if (scriptValueListCount >= SCRIPT_VAR_COUNT) {1399SetupTextMenu(&gameMenu[0], 0);1400AddTextMenuEntry(&gameMenu[0], "SCRIPT PARSING FAILED");1401AddTextMenuEntry(&gameMenu[0], " ");1402AddTextMenuEntry(&gameMenu[0], "TOO MANY ALIASES, STATIC");1403AddTextMenuEntry(&gameMenu[0], "VALUES, AND TABLES");1404Engine.gameMode = ENGINE_SCRIPTERROR;1405return false;1406}1407#endif14081409ScriptVariableInfo *variable = &scriptValueList[scriptValueListCount];1410MEM_ZEROP(variable);14111412int textStrPos = 12;1413int varStrPos = 0;14141415while (text[textStrPos]) {1416if (text[textStrPos] == '[' || text[textStrPos] == ']') {1417variable->name[varStrPos] = 0;1418textStrPos++;1419break;1420}1421else {1422variable->name[varStrPos++] = text[textStrPos++];1423}1424}14251426if (FindStringToken(text, "]", 1) < 1) {1427// has default values, we'll stop here and read stuff in a seperate mode1428scriptCode[scriptCodePos] = 0;1429StrCopy(variable->value, "");1430AppendIntegerToString(variable->value, scriptCodePos);1431scriptCodeOffset = scriptCodePos++;1432hasValues = true;1433}1434else {1435// no default values, just an array size14361437varStrPos = 0;1438while (text[textStrPos]) {1439if (text[textStrPos] == '[' || text[textStrPos] == ']') {1440variable->value[varStrPos] = 0;1441textStrPos++;1442break;1443}1444else {1445variable->value[varStrPos++] = text[textStrPos++];1446}1447}14481449// array size can be an variable (alias), how cool!1450for (int v = 0; v < scriptValueListCount; ++v) {1451if (StrComp(variable->value, scriptValueList[v].name))1452StrCopy(variable->value, scriptValueList[v].value);1453}14541455if (!ConvertStringToInteger(variable->value, &scriptCode[scriptCodePos])) {1456scriptCode[scriptCodePos] = 1;1457#if !RETRO_USE_ORIGINAL_CODE1458PrintLog("WARNING: Unable to parse table size!");1459#endif1460}14611462StrCopy(variable->value, "");1463AppendIntegerToString(variable->value, scriptCodePos);14641465int valueCount = scriptCode[scriptCodePos++];1466for (int v = 0; v < valueCount; ++v) scriptCode[scriptCodePos++] = 0;1467}14681469variable->access = ACCESS_PRIVATE;1470scriptValueListCount++;1471}14721473return hasValues;1474}1475void ConvertArithmaticSyntax(char *text)1476{1477int token = 0;1478int offset = 0;1479int findID = 0;1480char dest[260];14811482for (int i = FUNC_EQUAL; i <= FUNC_MOD; ++i) {1483findID = FindStringToken(text, scriptEvaluationTokens[i - 1], 1);1484if (findID > -1) {1485offset = findID;1486token = i;1487}1488}14891490if (token > 0) {1491StrCopy(dest, functions[token].name);1492StrAdd(dest, "(");1493findID = StrLength(dest);1494for (int i = 0; i < offset; ++i) dest[findID++] = text[i];1495if (functions[token].opcodeSize > 1) {1496dest[findID] = ',';1497int len = StrLength(scriptEvaluationTokens[token - 1]);1498offset += len;1499++findID;1500while (text[offset]) dest[findID++] = text[offset++];1501}1502dest[findID] = 0;1503StrAdd(dest, ")");1504StrCopy(text, dest);1505}1506}1507void ConvertConditionalStatement(char *text)1508{1509char dest[260];1510int compareOp = -1;1511int strPos = 0;1512int destStrPos = 0;15131514if (FindStringToken(text, "if", 1) == 0) {1515for (int i = 0; i < 6; ++i) {1516destStrPos = FindStringToken(text, scriptEvaluationTokens[i + FUNC_MOD], 1);1517if (destStrPos > -1) {1518strPos = destStrPos;1519compareOp = i;1520}1521}15221523if (compareOp > -1) {1524text[strPos] = ',';1525StrCopy(dest, functions[compareOp + FUNC_IFEQUAL].name);1526StrAdd(dest, "(");1527AppendIntegerToString(dest, jumpTablePos - jumpTableOffset);1528StrAdd(dest, ",");15291530destStrPos = StrLength(dest);1531for (int i = 2; text[i]; ++i) {1532if (text[i] != '=' && text[i] != '(' && text[i] != ')')1533dest[destStrPos++] = text[i];1534}1535dest[destStrPos] = 0;15361537StrAdd(dest, ")");1538StrCopy(text, dest);15391540jumpTableStack[++jumpTableStackPos] = jumpTablePos;1541jumpTable[jumpTablePos++] = -1;1542jumpTable[jumpTablePos++] = 0;1543}1544}1545else if (FindStringToken(text, "while", 1) == 0) {1546for (int i = 0; i < 6; ++i) {1547destStrPos = FindStringToken(text, scriptEvaluationTokens[i + FUNC_MOD], 1);1548if (destStrPos > -1) {1549strPos = destStrPos;1550compareOp = i;1551}1552}15531554if (compareOp > -1) {1555text[strPos] = ',';1556StrCopy(dest, functions[compareOp + FUNC_WEQUAL].name);1557StrAdd(dest, "(");1558AppendIntegerToString(dest, jumpTablePos - jumpTableOffset);1559StrAdd(dest, ",");15601561destStrPos = StrLength(dest);1562for (int i = 5; text[i]; ++i) {1563if (text[i] != '=' && text[i] != '(' && text[i] != ')')1564dest[destStrPos++] = text[i];1565}1566dest[destStrPos] = 0;15671568StrAdd(dest, ")");1569StrCopy(text, dest);15701571jumpTableStack[++jumpTableStackPos] = jumpTablePos;1572jumpTable[jumpTablePos++] = scriptCodePos - scriptCodeOffset;1573jumpTable[jumpTablePos++] = 0;1574}1575}1576else if (FindStringToken(text, "foreach", 1) == 0) {1577int argStrPos = FindStringToken(text, ",", 2);15781579if (argStrPos > -1) {1580StrCopy(dest, functions[text[argStrPos + 2] == 'C' ? (int)FUNC_FOREACHACTIVE : (int)FUNC_FOREACHALL].name);1581StrAdd(dest, "(");1582AppendIntegerToString(dest, jumpTablePos - jumpTableOffset);1583StrAdd(dest, ",");15841585destStrPos = StrLength(dest);1586for (int i = 7; text[i] && i < argStrPos; ++i) {1587if (text[i] != '(' && text[i] != ')')1588dest[destStrPos++] = text[i];1589}1590dest[destStrPos] = 0;15911592StrAdd(dest, ")");1593StrCopy(text, dest);15941595jumpTableStack[++jumpTableStackPos] = jumpTablePos;1596jumpTable[jumpTablePos++] = scriptCodePos - scriptCodeOffset;1597jumpTable[jumpTablePos++] = 0;1598}1599}1600}1601bool ConvertSwitchStatement(char *text)1602{1603if (FindStringToken(text, "switch", 1) != 0)1604return false;16051606char switchText[260];1607StrCopy(switchText, "switch");1608StrAdd(switchText, "(");1609AppendIntegerToString(switchText, jumpTablePos - jumpTableOffset);1610StrAdd(switchText, ",");1611int pos = StrLength(switchText);1612for (int i = 6; text[i]; ++i) {1613if (text[i] != '=' && text[i] != '(' && text[i] != ')')1614switchText[pos++] = text[i];1615}1616switchText[pos] = 0;1617StrAdd(switchText, ")");1618StrCopy(text, switchText);1619jumpTableStack[++jumpTableStackPos] = jumpTablePos;1620jumpTable[jumpTablePos++] = 0x10000;1621jumpTable[jumpTablePos++] = -0x10000;1622jumpTable[jumpTablePos++] = -1;1623jumpTable[jumpTablePos++] = 0;16241625return true;1626}1627void ConvertFunctionText(char *text)1628{1629char arrayStr[0x80];1630char funcName[132];16311632int opcode = 0;1633int opcodeSize = 0;1634int textPos = 0;1635int namePos = 0;16361637for (namePos = 0; text[namePos] != '(' && text[namePos]; ++namePos) funcName[namePos] = text[namePos];1638funcName[namePos] = 0;16391640for (int i = 0; i < FUNC_MAX_CNT; ++i) {1641if (StrComp(funcName, functions[i].name)) {1642opcode = i;1643opcodeSize = functions[i].opcodeSize;1644textPos = StrLength(functions[i].name);1645i = FUNC_MAX_CNT;1646}1647}16481649if (opcode <= 0) {1650SetupTextMenu(&gameMenu[0], 0);1651AddTextMenuEntry(&gameMenu[0], "SCRIPT PARSING FAILED");1652AddTextMenuEntry(&gameMenu[0], " ");1653AddTextMenuEntry(&gameMenu[0], "OPCODE NOT FOUND");1654AddTextMenuEntry(&gameMenu[0], funcName);1655#if !RETRO_USE_ORIGINAL_CODE1656AddTextMenuEntry(&gameMenu[0], " ");1657AddTextMenuEntry(&gameMenu[0], "LINE NUMBER");1658char buffer[0x10];1659buffer[0] = 0;1660AppendIntegerToString(buffer, lineID);1661AddTextMenuEntry(&gameMenu[0], buffer);1662#endif1663Engine.gameMode = ENGINE_SCRIPTERROR;1664}1665else {1666scriptCode[scriptCodePos++] = opcode;1667if (StrComp("else", functions[opcode].name))1668jumpTable[jumpTableStack[jumpTableStackPos]] = scriptCodePos - scriptCodeOffset;16691670if (StrComp("endif", functions[opcode].name) == 1) {1671int jPos = jumpTableStack[jumpTableStackPos];1672jumpTable[jPos + 1] = scriptCodePos - scriptCodeOffset;1673if (jumpTable[jPos] == -1)1674jumpTable[jPos] = (scriptCodePos - scriptCodeOffset) - 1;1675--jumpTableStackPos;1676}16771678if (StrComp("endswitch", functions[opcode].name)) {1679int jPos = jumpTableStack[jumpTableStackPos];1680jumpTable[jPos + 3] = scriptCodePos - scriptCodeOffset;1681if (jumpTable[jPos + 2] == -1) {1682jumpTable[jPos + 2] = (scriptCodePos - scriptCodeOffset) - 1;1683int caseCnt = abs(jumpTable[jPos + 1] - jumpTable[jPos]) + 1;16841685int jOffset = jPos + 4;1686for (int c = 0; c < caseCnt; ++c) {1687if (jumpTable[jOffset + c] < 0)1688jumpTable[jOffset + c] = jumpTable[jPos + 2];1689}1690}1691--jumpTableStackPos;1692}16931694if (StrComp("loop", functions[opcode].name) || StrComp("next", functions[opcode].name)) {1695jumpTable[jumpTableStack[jumpTableStackPos--] + 1] = scriptCodePos - scriptCodeOffset;1696}16971698for (int i = 0; i < opcodeSize; ++i) {1699++textPos;1700int funcNamePos = 0;1701int mode = 0;1702int prevMode = 0;1703int arrayStrPos = 0;1704while (((text[textPos] != ',' && text[textPos] != ')') || mode == 2) && text[textPos]) {1705switch (mode) {1706case 0: // normal1707if (text[textPos] == '[')1708mode = 1;1709else if (text[textPos] == '"') {1710prevMode = mode;1711mode = 2;1712funcName[funcNamePos++] = '"';1713}1714else1715funcName[funcNamePos++] = text[textPos];1716++textPos;1717break;17181719case 1: // array val1720if (text[textPos] == ']')1721mode = 0;1722else if (text[textPos] == '"') {1723prevMode = mode;1724mode = 2;1725}1726else1727arrayStr[arrayStrPos++] = text[textPos];1728++textPos;1729break;17301731case 2: // string1732if (text[textPos] == '"') {1733mode = prevMode;1734funcName[funcNamePos++] = '"';1735}1736else1737funcName[funcNamePos++] = text[textPos];1738++textPos;1739break;1740}1741}1742funcName[funcNamePos] = 0;1743arrayStr[arrayStrPos] = 0;17441745for (int v = 0; v < scriptValueListCount; ++v) {1746if (StrComp(funcName, scriptValueList[v].name)) {1747CopyAliasStr(funcName, scriptValueList[v].value, 0);1748if (FindStringToken(scriptValueList[v].value, "[", 1) > -1)1749CopyAliasStr(arrayStr, scriptValueList[v].value, 1);1750}1751}17521753if (arrayStr[0]) {1754char arrStrBuf[0x80];1755int arrPos = 0;1756int bufPos = 0;1757if (arrayStr[0] == '+' || arrayStr[0] == '-')1758++arrPos;1759while (arrayStr[arrPos]) arrStrBuf[bufPos++] = arrayStr[arrPos++];1760arrStrBuf[bufPos] = 0;17611762for (int v = 0; v < scriptValueListCount; ++v) {1763if (StrComp(arrStrBuf, scriptValueList[v].name)) {1764char pref = arrayStr[0];1765CopyAliasStr(arrayStr, scriptValueList[v].value, 0);17661767if (pref == '+' || pref == '-') {1768int len = StrLength(arrayStr);1769for (int i = len; i >= 0; --i) arrayStr[i + 1] = arrayStr[i];1770arrayStr[0] = pref;1771}1772}1773}1774}17751776// Eg: temp0 = game.variable1777for (int v = 0; v < globalVariablesCount; ++v) {1778if (StrComp(funcName, globalVariableNames[v])) {1779StrCopy(funcName, "global");1780arrayStr[0] = 0;1781AppendIntegerToString(arrayStr, v);1782}1783}17841785// Eg: temp0 = Function11786for (int f = 0; f < scriptFunctionCount; ++f) {1787if (StrComp(funcName, scriptFunctionList[f].name)) {1788funcName[0] = 0;1789AppendIntegerToString(funcName, f);1790}1791}17921793// Eg: temp0 = TypeName[Player Object]1794if (StrComp(funcName, "TypeName")) {1795funcName[0] = '0';1796funcName[1] = 0;17971798int o = 0;1799for (; o < OBJECT_COUNT; ++o) {1800if (StrComp(arrayStr, typeNames[o])) {1801funcName[0] = 0;1802AppendIntegerToString(funcName, o);1803break;1804}1805}18061807if (o == OBJECT_COUNT)1808PrintLog("WARNING: Unknown typename \"%s\", on line %d", arrayStr, lineID);1809}18101811#if !RETRO_USE_ORIGINAL_CODE1812// Eg: temp0 = SfxName[Jump]1813if (StrComp(funcName, "SfxName")) {1814funcName[0] = '0';1815funcName[1] = 0;18161817int s = 0;1818for (; s < SFX_COUNT; ++s) {1819if (StrComp(arrayStr, sfxNames[s])) {1820funcName[0] = 0;1821AppendIntegerToString(funcName, s);1822break;1823}1824}18251826if (s == SFX_COUNT)1827PrintLog("WARNING: Unknown sfxName \"%s\", on line %d", arrayStr, lineID);1828}18291830// Eg: temp0 = VarName[player.lives]1831if (StrComp(funcName, "VarName")) {1832funcName[0] = '0';1833funcName[1] = 0;18341835int v = 0;1836for (; v < globalVariablesCount; ++v) {1837if (StrComp(arrayStr, globalVariableNames[v])) {1838funcName[0] = 0;1839AppendIntegerToString(funcName, v);1840break;1841}1842}18431844if (v == globalVariablesCount)1845PrintLog("WARNING: Unknown varName \"%s\", on line %d", arrayStr, lineID);1846}18471848// Eg: temp0 = AchievementName[Ring King]1849if (StrComp(funcName, "AchievementName")) {1850funcName[0] = '0';1851funcName[1] = 0;18521853int a = 0;1854for (; a < achievementCount; ++a) {1855char buf[0x40];1856char *str = achievements[a].name;1857int pos = 0;18581859while (*str) {1860if (*str != ' ')1861buf[pos++] = *str;1862str++;1863}1864buf[pos] = 0;18651866if (StrComp(arrayStr, buf)) {1867funcName[0] = 0;1868AppendIntegerToString(funcName, a);1869break;1870}1871}18721873if (a == achievementCount)1874PrintLog("WARNING: Unknown AchievementName \"%s\", on line %d", arrayStr, lineID);1875}18761877// Eg: temp0 = PlayerName[SONIC]1878if (StrComp(funcName, "PlayerName")) {1879funcName[0] = '0';1880funcName[1] = 0;18811882int p = 0;1883for (; p < PLAYER_COUNT; ++p) {1884char buf[0x40];1885char *str = playerNames[p];1886int pos = 0;18871888while (*str) {1889if (*str != ' ')1890buf[pos++] = *str;1891str++;1892}1893buf[pos] = 0;18941895if (StrComp(arrayStr, buf)) {1896funcName[0] = 0;1897AppendIntegerToString(funcName, p);1898break;1899}1900}19011902if (p == PLAYER_COUNT)1903PrintLog("WARNING: Unknown PlayerName \"%s\", on line %d", arrayStr, lineID);1904}19051906// Eg: temp0 = StageName[R - GREEN HILL ZONE 1]1907if (StrComp(funcName, "StageName")) {1908funcName[0] = '0';1909funcName[1] = 0;19101911int s = -1;1912if (StrLength(arrayStr) >= 2) {1913char list = arrayStr[0];1914switch (list) {1915case 'P': list = STAGELIST_PRESENTATION; break;1916case 'R': list = STAGELIST_REGULAR; break;1917case 'S': list = STAGELIST_SPECIAL; break;1918case 'B': list = STAGELIST_BONUS; break;1919}1920s = GetSceneID(list, &arrayStr[2]);1921}19221923if (s == -1) {1924char buf[0x40];1925sprintf(buf, "WARNING: Unknown StageName \"%s\", on line %d", arrayStr, lineID);1926PrintLog(buf);1927s = 0;1928}1929funcName[0] = 0;1930AppendIntegerToString(funcName, s);1931}1932#endif19331934// Storing Values1935int constant = 0;1936if (ConvertStringToInteger(funcName, &constant)) {1937scriptCode[scriptCodePos++] = SCRIPTVAR_INTCONST;1938scriptCode[scriptCodePos++] = constant;1939}1940else if (funcName[0] == '"') {1941scriptCode[scriptCodePos++] = SCRIPTVAR_STRCONST;1942scriptCode[scriptCodePos++] = StrLength(funcName) - 2;19431944int scriptTextPos = 1;1945arrayStrPos = 0;1946while (scriptTextPos > -1) {1947switch (arrayStrPos) {1948case 0:1949scriptCode[scriptCodePos] = funcName[scriptTextPos] << 24;1950++arrayStrPos;1951break;19521953case 1:1954scriptCode[scriptCodePos] += funcName[scriptTextPos] << 16;1955++arrayStrPos;1956break;19571958case 2:1959scriptCode[scriptCodePos] += funcName[scriptTextPos] << 8;1960++arrayStrPos;1961break;19621963case 3:1964scriptCode[scriptCodePos++] += funcName[scriptTextPos];1965arrayStrPos = 0;1966break;19671968default: break;1969}19701971if (funcName[scriptTextPos] == '"') {1972if (arrayStrPos > 0)1973++scriptCodePos;1974scriptTextPos = -1;1975}1976else {1977scriptTextPos++;1978}1979}1980}1981else {1982scriptCode[scriptCodePos++] = SCRIPTVAR_VAR;19831984if (arrayStr[0]) {1985scriptCode[scriptCodePos] = VARARR_ARRAY;19861987if (arrayStr[0] == '+')1988scriptCode[scriptCodePos] = VARARR_ENTNOPLUS1;19891990if (arrayStr[0] == '-')1991scriptCode[scriptCodePos] = VARARR_ENTNOMINUS1;19921993++scriptCodePos;19941995if (arrayStr[0] == '-' || arrayStr[0] == '+') {1996for (int i = 0; i < StrLength(arrayStr); ++i) arrayStr[i] = arrayStr[i + 1];1997}19981999if (ConvertStringToInteger(arrayStr, &constant) == 1) {2000scriptCode[scriptCodePos++] = 0;2001scriptCode[scriptCodePos++] = constant;2002}2003else {2004if (StrComp(arrayStr, "arrayPos0"))2005constant = 0;2006if (StrComp(arrayStr, "arrayPos1"))2007constant = 1;2008if (StrComp(arrayStr, "arrayPos2"))2009constant = 2;2010if (StrComp(arrayStr, "arrayPos3"))2011constant = 3;2012if (StrComp(arrayStr, "arrayPos4"))2013constant = 4;2014if (StrComp(arrayStr, "arrayPos5"))2015constant = 5;2016if (StrComp(arrayStr, "arrayPos6"))2017constant = 6;2018if (StrComp(arrayStr, "arrayPos7"))2019constant = 7;2020if (StrComp(arrayStr, "tempObjectPos"))2021constant = 8;20222023scriptCode[scriptCodePos++] = 1;2024scriptCode[scriptCodePos++] = constant;2025}2026}2027else {2028scriptCode[scriptCodePos++] = VARARR_NONE;2029}20302031constant = -1;2032for (int i = 0; i < VAR_MAX_CNT; ++i) {2033if (StrComp(funcName, variableNames[i]))2034constant = i;2035}20362037if (constant == -1 && Engine.gameMode != ENGINE_SCRIPTERROR) {2038SetupTextMenu(&gameMenu[0], 0);2039AddTextMenuEntry(&gameMenu[0], "SCRIPT PARSING FAILED");2040AddTextMenuEntry(&gameMenu[0], " ");2041AddTextMenuEntry(&gameMenu[0], "OPERAND NOT FOUND");2042AddTextMenuEntry(&gameMenu[0], funcName);2043AddTextMenuEntry(&gameMenu[0], " ");2044AddTextMenuEntry(&gameMenu[0], "LINE NUMBER");2045funcName[0] = 0;2046AppendIntegerToString(funcName, lineID);2047AddTextMenuEntry(&gameMenu[0], funcName);2048Engine.gameMode = ENGINE_SCRIPTERROR;2049constant = 0;2050}20512052scriptCode[scriptCodePos++] = constant;2053}2054}2055}2056}2057void CheckCaseNumber(char *text)2058{2059if (FindStringToken(text, "case", 1) != 0)2060return;20612062char caseString[128];2063char caseChar = text[4];20642065int textPos = 5;2066int caseStrPos = 0;2067while (caseChar) {2068if (caseChar != ':')2069caseString[caseStrPos++] = caseChar;2070caseChar = text[textPos++];2071}2072caseString[caseStrPos] = 0;20732074bool foundValue = false;20752076if (FindStringToken(caseString, "[", 1) >= 0) {2077char caseValue[0x80];2078char arrayStr[0x80];20792080int textPos = 0;2081int funcNamePos = 0;2082int mode = 0;2083int arrayStrPos = 0;2084while (caseString[textPos] != ':' && caseString[textPos]) {2085if (mode) {2086if (caseString[textPos] == ']')2087mode = 0;2088else2089arrayStr[arrayStrPos++] = caseString[textPos];2090++textPos;2091}2092else {2093if (caseString[textPos] == '[')2094mode = 1;2095else2096caseValue[funcNamePos++] = caseString[textPos];2097++textPos;2098}2099}2100caseValue[funcNamePos] = 0;2101arrayStr[arrayStrPos] = 0;21022103// Eg: temp0 = TypeName[Player Object]2104if (StrComp(caseValue, "TypeName")) {2105caseValue[0] = '0';2106caseValue[1] = 0;21072108int o = 0;2109for (; o < OBJECT_COUNT; ++o) {2110if (StrComp(arrayStr, typeNames[o])) {2111caseValue[0] = 0;2112AppendIntegerToString(caseValue, o);2113break;2114}2115}21162117if (o == OBJECT_COUNT)2118PrintLog("WARNING: Unknown typename \"%s\", on line %d", arrayStr, lineID);2119}21202121// Eg: temp0 = SfxName[Jump]2122if (StrComp(caseValue, "SfxName")) {2123caseValue[0] = '0';2124caseValue[1] = 0;21252126int s = 0;2127for (; s < SFX_COUNT; ++s) {2128if (StrComp(arrayStr, sfxNames[s])) {2129caseValue[0] = 0;2130AppendIntegerToString(caseValue, s);2131break;2132}2133}21342135if (s == SFX_COUNT)2136PrintLog("WARNING: Unknown sfxName \"%s\", on line %d", arrayStr, lineID);2137}21382139#if !RETRO_USE_ORIGINAL_CODE2140// Eg: temp0 = VarName[player.lives]2141if (StrComp(caseValue, "VarName")) {2142caseValue[0] = '0';2143caseValue[1] = 0;21442145int v = 0;2146for (; v < globalVariablesCount; ++v) {2147if (StrComp(arrayStr, globalVariableNames[v])) {2148caseValue[0] = 0;2149AppendIntegerToString(caseValue, v);2150break;2151}2152}21532154if (v == globalVariablesCount) {2155PrintLog("WARNING: Unknown varName \"%s\", on line %d", arrayStr, lineID);2156}2157}21582159// Eg: temp0 = AchievementName[Ring King]2160if (StrComp(caseValue, "AchievementName")) {2161caseValue[0] = '0';2162caseValue[1] = 0;21632164int a = 0;2165for (; a < achievementCount; ++a) {2166char buf[0x40];2167char *str = achievements[a].name;2168int pos = 0;21692170while (*str) {2171if (*str != ' ')2172buf[pos++] = *str;2173str++;2174}2175buf[pos] = 0;21762177if (StrComp(arrayStr, buf)) {2178caseValue[0] = 0;2179AppendIntegerToString(caseValue, a);2180break;2181}2182}21832184if (a == achievementCount) {2185PrintLog("WARNING: Unknown AchievementName \"%s\", on line %d", arrayStr, lineID);2186}2187}21882189// Eg: temp0 = PlayerName[SONIC]2190if (StrComp(caseValue, "PlayerName")) {2191caseValue[0] = '0';2192caseValue[1] = 0;21932194int p = 0;2195for (; p < PLAYER_COUNT; ++p) {2196char buf[0x40];2197char *str = playerNames[p];2198int pos = 0;21992200while (*str) {2201if (*str != ' ')2202buf[pos++] = *str;2203str++;2204}2205buf[pos] = 0;22062207if (StrComp(arrayStr, buf)) {2208caseValue[0] = 0;2209AppendIntegerToString(caseValue, p);2210break;2211}2212}22132214if (p == PLAYER_COUNT) {2215PrintLog("WARNING: Unknown PlayerName \"%s\", on line %d", arrayStr, lineID);2216}2217}22182219// Eg: temp0 = StageName[R - GREEN HILL ZONE 1]2220if (StrComp(caseValue, "StageName")) {2221caseValue[0] = '0';2222caseValue[1] = 0;22232224int s = -1;2225if (StrLength(arrayStr) >= 2) {2226char list = arrayStr[0];2227switch (list) {2228case 'P': list = STAGELIST_PRESENTATION; break;2229case 'R': list = STAGELIST_REGULAR; break;2230case 'S': list = STAGELIST_SPECIAL; break;2231case 'B': list = STAGELIST_BONUS; break;2232}2233s = GetSceneID(list, &arrayStr[2]);2234}22352236if (s == -1) {2237PrintLog("WARNING: Unknown StageName \"%s\", on line %d", arrayStr, lineID);2238s = 0;2239}2240caseValue[0] = 0;2241AppendIntegerToString(caseValue, s);2242}2243#endif2244StrCopy(caseString, caseValue);2245foundValue = true;2246}22472248for (int a = 0; a < scriptValueListCount && !foundValue; ++a) {2249if (StrComp(scriptValueList[a].name, caseString)) {2250StrCopy(caseString, scriptValueList[a].value);2251break;2252}2253}22542255int caseID = 0;2256if (ConvertStringToInteger(caseString, &caseID)) {2257int stackValue = jumpTableStack[jumpTableStackPos];2258if (caseID < jumpTable[stackValue])2259jumpTable[stackValue] = caseID;2260stackValue++;2261if (caseID > jumpTable[stackValue])2262jumpTable[stackValue] = caseID;2263}2264else {2265PrintLog("WARNING: unable to convert case string \"%s\" to int, on line %d", caseString, lineID);2266}2267}2268bool ReadSwitchCase(char *text)2269{2270char caseText[0x80];2271if (FindStringToken(text, "case", 1) == 0) {2272int textPos = 4;2273int caseStringPos = 0;2274while (text[textPos]) {2275if (text[textPos] != ':')2276caseText[caseStringPos++] = text[textPos];2277++textPos;2278}2279caseText[caseStringPos] = 0;22802281bool foundValue = false;2282if (FindStringToken(caseText, "[", 1) >= 0) {2283char caseValue[0x80];2284char arrayStr[0x80];22852286int textPos = 0;2287int funcNamePos = 0;2288int mode = 0;2289int arrayStrPos = 0;2290while (caseText[textPos] != ':' && caseText[textPos]) {2291if (mode) {2292if (caseText[textPos] == ']')2293mode = 0;2294else2295arrayStr[arrayStrPos++] = caseText[textPos];2296++textPos;2297}2298else {2299if (caseText[textPos] == '[')2300mode = 1;2301else2302caseValue[funcNamePos++] = caseText[textPos];2303++textPos;2304}2305}2306caseValue[funcNamePos] = 0;2307arrayStr[arrayStrPos] = 0;23082309// Eg: temp0 = TypeName[Player Object]2310if (StrComp(caseValue, "TypeName")) {2311caseValue[0] = '0';2312caseValue[1] = 0;23132314int o = 0;2315for (; o < OBJECT_COUNT; ++o) {2316if (StrComp(arrayStr, typeNames[o])) {2317caseValue[0] = 0;2318AppendIntegerToString(caseValue, o);2319break;2320}2321}23222323if (o == OBJECT_COUNT)2324PrintLog("WARNING: Unknown typename \"%s\", on line %d", arrayStr, lineID);2325}23262327// Eg: temp0 = SfxName[Jump]2328if (StrComp(caseValue, "SfxName")) {2329caseValue[0] = '0';2330caseValue[1] = 0;23312332int s = 0;2333for (; s < SFX_COUNT; ++s) {2334if (StrComp(arrayStr, sfxNames[s])) {2335caseValue[0] = 0;2336AppendIntegerToString(caseValue, s);2337break;2338}2339}23402341if (s == SFX_COUNT)2342PrintLog("WARNING: Unknown sfxName \"%s\", on line %d", arrayStr, lineID);2343}23442345#if !RETRO_USE_ORIGINAL_CODE2346// Eg: temp0 = VarName[player.lives]2347if (StrComp(caseValue, "VarName")) {2348caseValue[0] = '0';2349caseValue[1] = 0;23502351int v = 0;2352for (; v < globalVariablesCount; ++v) {2353if (StrComp(arrayStr, globalVariableNames[v])) {2354caseValue[0] = 0;2355AppendIntegerToString(caseValue, v);2356break;2357}2358}23592360if (v == globalVariablesCount)2361PrintLog("WARNING: Unknown varName \"%s\", on line %d", arrayStr, lineID);2362}23632364// Eg: temp0 = AchievementName[Ring King]2365if (StrComp(caseValue, "AchievementName")) {2366caseValue[0] = '0';2367caseValue[1] = 0;23682369int a = 0;2370for (; a < achievementCount; ++a) {2371char buf[0x40];2372char *str = achievements[a].name;2373int pos = 0;23742375while (*str) {2376if (*str != ' ')2377buf[pos++] = *str;2378str++;2379}2380buf[pos] = 0;23812382if (StrComp(arrayStr, buf)) {2383caseValue[0] = 0;2384AppendIntegerToString(caseValue, a);2385break;2386}2387}23882389if (a == achievementCount)2390PrintLog("WARNING: Unknown AchievementName \"%s\", on line %d", arrayStr, lineID);2391}23922393// Eg: temp0 = PlayerName[SONIC]2394if (StrComp(caseValue, "PlayerName")) {2395caseValue[0] = '0';2396caseValue[1] = 0;23972398int p = 0;2399for (; p < PLAYER_COUNT; ++p) {2400char buf[0x40];2401char *str = playerNames[p];2402int pos = 0;24032404while (*str) {2405if (*str != ' ')2406buf[pos++] = *str;2407str++;2408}2409buf[pos] = 0;24102411if (StrComp(arrayStr, buf)) {2412caseValue[0] = 0;2413AppendIntegerToString(caseValue, p);2414break;2415}2416}24172418if (p == PLAYER_COUNT)2419PrintLog("WARNING: Unknown PlayerName \"%s\", on line %d", arrayStr, lineID);2420}24212422// Eg: temp0 = StageName[R - GREEN HILL ZONE 1]2423if (StrComp(caseValue, "StageName")) {2424caseValue[0] = '0';2425caseValue[1] = 0;24262427int s = -1;2428if (StrLength(arrayStr) >= 2) {2429char list = arrayStr[0];2430switch (list) {2431case 'P': list = STAGELIST_PRESENTATION; break;2432case 'R': list = STAGELIST_REGULAR; break;2433case 'S': list = STAGELIST_SPECIAL; break;2434case 'B': list = STAGELIST_BONUS; break;2435}2436s = GetSceneID(list, &arrayStr[2]);2437}24382439if (s == -1) {2440PrintLog("WARNING: Unknown StageName \"%s\", on line %d", arrayStr, lineID);2441s = 0;2442}2443caseValue[0] = 0;2444AppendIntegerToString(caseValue, s);2445}2446#endif2447StrCopy(caseText, caseValue);2448foundValue = true;2449}24502451for (int v = 0; v < scriptValueListCount && !foundValue; ++v) {2452if (StrComp(caseText, scriptValueList[v].name)) {2453StrCopy(caseText, scriptValueList[v].value);2454break;2455}2456}24572458int val = 0;24592460int jPos = jumpTableStack[jumpTableStackPos];2461int jOffset = jPos + 4;2462if (ConvertStringToInteger(caseText, &val))2463jumpTable[val - jumpTable[jPos] + jOffset] = scriptCodePos - scriptCodeOffset;2464else2465PrintLog("WARNING: unable to read case string \"%s\" as an int, on line %d", caseText, lineID);24662467return true;2468}2469else if (FindStringToken(text, "default", 1) == 0) {2470int jumpTablepos = jumpTableStack[jumpTableStackPos];2471jumpTable[jumpTablepos + 2] = scriptCodePos - scriptCodeOffset;2472int cnt = abs(jumpTable[jumpTablepos + 1] - jumpTable[jumpTablepos]) + 1;24732474int jOffset = jumpTablepos + 4;2475for (int i = 0; i < cnt; ++i) {2476if (jumpTable[jOffset + i] < 0)2477jumpTable[jOffset + i] = scriptCodePos - scriptCodeOffset;2478}24792480return true;2481}24822483return false;2484}2485void ReadTableValues(char *text)2486{2487int textStrPos = 0;24882489char valueBuffer[256];2490int valueBufferPos = 0;24912492while (text[textStrPos]) {2493valueBuffer[valueBufferPos++] = text[textStrPos++];24942495while (text[textStrPos] == ',') {2496valueBuffer[valueBufferPos] = 0;2497++scriptCode[scriptCodeOffset];2498if (!ConvertStringToInteger(valueBuffer, &scriptCode[scriptCodePos])) {2499scriptCode[scriptCodePos] = 0;2500#if !RETRO_USE_ORIGINAL_CODE2501PrintLog("WARNING: unable to parse table value \"%s\" as an int, on line %d", valueBuffer, lineID);2502#endif2503}2504scriptCodePos++;2505valueBufferPos = 0;2506textStrPos++;2507}2508}25092510if (StrLength(valueBuffer)) {2511valueBuffer[valueBufferPos] = 0;2512++scriptCode[scriptCodeOffset];2513if (!ConvertStringToInteger(valueBuffer, &scriptCode[scriptCodePos])) {2514scriptCode[scriptCodePos] = 0;2515#if !RETRO_USE_ORIGINAL_CODE2516PrintLog("WARNING: unable to parse table value \"%s\" as an int, on line %d", valueBuffer, lineID);2517#endif2518}2519scriptCodePos++;2520}2521}2522void AppendIntegerToString(char *text, int value)2523{2524int textPos = 0;2525while (true) {2526if (!text[textPos])2527break;2528++textPos;2529}25302531int cnt = 0;2532int v = value;2533while (v != 0) {2534v /= 10;2535cnt++;2536}25372538v = 0;2539for (int i = cnt - 1; i >= 0; --i) {2540v = value / pow(10, i);2541v %= 10;25422543int strValue = v + '0';2544if (strValue < '0' || strValue > '9') {2545// what2546}2547text[textPos++] = strValue;2548}2549if (value == 0)2550text[textPos++] = '0';2551text[textPos] = 0;2552}2553void AppendIntegerToStringW(ushort *text, int value)2554{2555int textPos = 0;2556while (true) {2557if (!text[textPos])2558break;2559++textPos;2560}25612562int cnt = 0;2563int v = value;2564while (v != 0) {2565v /= 10;2566cnt++;2567}25682569v = 0;2570for (int i = cnt - 1; i >= 0; --i) {2571v = value / pow(10, i);2572v %= 10;25732574int strValue = v + '0';2575if (strValue < '0' || strValue > '9') {2576// what2577}2578text[textPos++] = strValue;2579}2580if (value == 0)2581text[textPos++] = '0';2582text[textPos] = 0;2583}2584#endif25852586bool ConvertStringToInteger(const char *text, int *value)2587{2588int charID = 0;2589bool negative = false;2590int base = 10;2591*value = 0;2592if (*text != '+' && !(*text >= '0' && *text <= '9') && *text != '-')2593return false;2594int strLength = StrLength(text) - 1;2595uint charVal = 0;2596if (*text == '-') {2597negative = true;2598charID = 1;2599--strLength;2600}2601else if (*text == '+') {2602charID = 1;2603--strLength;2604}26052606if (text[charID] == '0') {2607if (text[charID + 1] == 'x' || text[charID + 1] == 'X')2608base = 0x10;2609#if !RETRO_USE_ORIGINAL_CODE2610else if (text[charID + 1] == 'b' || text[charID + 1] == 'B')2611base = 0b10;2612else if (text[charID + 1] == 'o' || text[charID + 1] == 'O')2613base = 0010; // base 82614#endif26152616if (base != 10) {2617charID += 2;2618strLength -= 2;2619}2620}26212622while (strLength > -1) {2623bool flag = text[charID] < '0';2624if (!flag) {2625if (base == 0x10 && text[charID] > 'f')2626flag = true;2627#if !RETRO_USE_ORIGINAL_CODE2628if (base == 0010 && text[charID] > '7')2629flag = true;2630if (base == 0b10 && text[charID] > '1')2631flag = true;2632#endif2633}26342635if (flag) {2636return 0;2637}2638if (strLength <= 0) {2639if (text[charID] >= '0' && text[charID] <= '9') {2640*value = text[charID] + *value - '0';2641}2642else if (text[charID] >= 'a' && text[charID] <= 'f') {2643charVal = text[charID] - 'a';2644charVal += 10;2645*value += charVal;2646}2647else if (text[charID] >= 'A' && text[charID] <= 'F') {2648charVal = text[charID] - 'A';2649charVal += 10;2650*value += charVal;2651}2652}2653else {2654int strlen = strLength + 1;2655charVal = 0;2656if (text[charID] >= '0' && text[charID] <= '9') {2657charVal = text[charID] - '0';2658}2659else if (text[charID] >= 'a' && text[charID] <= 'f') {2660charVal = text[charID] - 'a';2661charVal += 10;2662}2663else if (text[charID] >= 'A' && text[charID] <= 'F') {2664charVal = text[charID] - 'A';2665charVal += 10;2666}2667for (; --strlen; charVal *= base)2668;2669*value += charVal;2670}2671--strLength;2672++charID;2673}26742675if (negative)2676*value = -*value;26772678return true;2679}26802681#if RETRO_USE_COMPILER2682void CopyAliasStr(char *dest, char *text, bool arrayIndex)2683{2684int textPos = 0;2685int destPos = 0;2686bool arrayValue = false;2687if (arrayIndex) {2688while (text[textPos]) {2689if (arrayValue) {2690if (text[textPos] == ']')2691arrayValue = false;2692else2693dest[destPos++] = text[textPos];2694++textPos;2695}2696else {2697if (text[textPos] == '[')2698arrayValue = true;2699++textPos;2700}2701}2702}2703else {2704while (text[textPos]) {2705if (arrayValue) {2706if (text[textPos] == ']')2707arrayValue = false;2708++textPos;2709}2710else {2711if (text[textPos] == '[')2712arrayValue = true;2713else2714dest[destPos++] = text[textPos];2715++textPos;2716}2717}2718}2719dest[destPos] = 0;2720}2721bool CheckOpcodeType(char *text)2722{2723while (true) {2724int c = *text;2725if (!*text)2726break;2727++text;2728if (c == '(')2729return false;2730}2731return true;2732}27332734void ParseScriptFile(char *scriptName, int scriptID)2735{2736jumpTableStackPos = 0;2737lineID = 0;27382739for (int f = 0; f < scriptFunctionCount; ++f) {2740if (scriptFunctionList[f].access != ACCESS_PUBLIC)2741StrCopy(scriptFunctionList[f].name, "");2742}27432744int newScriptValueCount = COMMON_SCRIPT_VAR_COUNT;2745for (int v = COMMON_SCRIPT_VAR_COUNT; v < scriptValueListCount; ++v) {2746if (scriptValueList[v].access != ACCESS_PUBLIC) {2747StrCopy(scriptValueList[v].name, "");2748}2749else {2750if (newScriptValueCount != v)2751memcpy(&scriptValueList[newScriptValueCount], &scriptValueList[v], sizeof(ScriptVariableInfo));27522753newScriptValueCount++;2754}2755}2756scriptValueListCount = newScriptValueCount;27572758for (int v = scriptValueListCount; v < SCRIPT_VAR_COUNT; ++v) {2759MEM_ZERO(scriptValueList[v]);2760}27612762FileInfo info;2763char scriptPath[0x40];27642765// Try the original script folder2766StrCopy(scriptPath, "Data/Scripts/");2767StrAdd(scriptPath, scriptName);2768if (LoadFile(scriptPath, &info)) {2769int readMode = READMODE_NORMAL;2770int parseMode = PARSEMODE_SCOPELESS;2771char prevChar = 0;2772char curChar = 0;2773int switchDeep = 0;27742775while (readMode < READMODE_EOF) {2776int textPos = 0;2777readMode = READMODE_NORMAL;2778bool disableLineIncrement = false;27792780while (readMode < READMODE_ENDLINE) {2781prevChar = curChar;2782FileRead(&curChar, 1);2783if (readMode == READMODE_STRING) {2784if (curChar == '\t' || curChar == '\r' || curChar == '\n' || curChar == ';' || readMode >= READMODE_COMMENTLINE) {2785if ((curChar == '\n' && prevChar != '\r') || (curChar == '\n' && prevChar == '\r')) {2786readMode = READMODE_ENDLINE;2787scriptText[textPos] = 0;2788if (curChar == ';')2789disableLineIncrement = true;2790}2791}2792else if (curChar != '/' || textPos <= 0) {2793scriptText[textPos++] = curChar;2794if (curChar == '"')2795readMode = READMODE_NORMAL;2796}2797else if (curChar == '/' && prevChar == '/') {2798readMode = READMODE_COMMENTLINE;2799scriptText[--textPos] = 0;2800}2801else {2802scriptText[textPos++] = curChar;2803}2804}2805else if (curChar == ' ' || curChar == '\t' || curChar == '\r' || curChar == '\n' || curChar == ';'2806|| readMode >= READMODE_COMMENTLINE) {2807if ((curChar == '\n' && prevChar != '\r') || (curChar == '\n' && prevChar == '\r') || curChar == ';') {2808readMode = READMODE_ENDLINE;2809scriptText[textPos] = 0;2810if (curChar == ';')2811disableLineIncrement = true;2812}2813}2814else if (curChar != '/' || textPos <= 0) {2815scriptText[textPos++] = curChar;2816if (curChar == '"' && !readMode)2817readMode = READMODE_STRING;2818}2819else if (curChar == '/' && prevChar == '/') {2820readMode = READMODE_COMMENTLINE;2821scriptText[--textPos] = 0;2822}2823else {2824scriptText[textPos++] = curChar;2825}2826if (ReachedEndOfFile()) {2827scriptText[textPos] = 0;2828readMode = READMODE_EOF;2829}2830}28312832switch (parseMode) {2833case PARSEMODE_SCOPELESS:2834if (!disableLineIncrement)2835++lineID;28362837CheckAliasText(scriptText);2838CheckStaticText(scriptText);28392840if (CheckTableText(scriptText)) {2841parseMode = PARSEMODE_TABLEREAD;2842StrCopy(scriptText, "");2843}28442845if (StrComp(scriptText, "eventObjectUpdate")) {2846parseMode = PARSEMODE_FUNCTION;2847objectScriptList[scriptID].eventUpdate.scriptCodePtr = scriptCodePos;2848objectScriptList[scriptID].eventUpdate.jumpTablePtr = jumpTablePos;2849scriptCodeOffset = scriptCodePos;2850jumpTableOffset = jumpTablePos;2851}28522853if (StrComp(scriptText, "eventObjectDraw")) {2854parseMode = PARSEMODE_FUNCTION;2855objectScriptList[scriptID].eventDraw.scriptCodePtr = scriptCodePos;2856objectScriptList[scriptID].eventDraw.jumpTablePtr = jumpTablePos;2857scriptCodeOffset = scriptCodePos;2858jumpTableOffset = jumpTablePos;2859}28602861if (StrComp(scriptText, "eventObjectStartup")) {2862parseMode = PARSEMODE_FUNCTION;2863objectScriptList[scriptID].eventStartup.scriptCodePtr = scriptCodePos;2864objectScriptList[scriptID].eventStartup.jumpTablePtr = jumpTablePos;2865scriptCodeOffset = scriptCodePos;2866jumpTableOffset = jumpTablePos;2867}28682869if (FindStringToken(scriptText, "reservefunction", 1) == 0) { // forward decl2870char funcName[0x40];2871for (textPos = 15; scriptText[textPos]; ++textPos) funcName[textPos - 15] = scriptText[textPos];2872funcName[textPos - 15] = 0;2873int funcID = -1;2874for (int f = 0; f < scriptFunctionCount; ++f) {2875if (StrComp(funcName, scriptFunctionList[f].name))2876funcID = f;2877}28782879if (scriptFunctionCount < FUNCTION_COUNT && funcID == -1) {2880StrCopy(scriptFunctionList[scriptFunctionCount++].name, funcName);2881}2882else {2883PrintLog("WARNING: Function %s has already been reserved!", funcName);2884}28852886parseMode = PARSEMODE_SCOPELESS;2887}2888else if (FindStringToken(scriptText, "publicfunction", 1) == 0) { // regular public decl2889char funcName[0x40];2890for (textPos = 14; scriptText[textPos]; ++textPos) funcName[textPos - 14] = scriptText[textPos];28912892funcName[textPos - 14] = 0;2893int funcID = -1;2894for (int f = 0; f < scriptFunctionCount; ++f) {2895if (StrComp(funcName, scriptFunctionList[f].name))2896funcID = f;2897}28982899if (funcID <= -1) {2900if (scriptFunctionCount >= FUNCTION_COUNT) {2901parseMode = PARSEMODE_SCOPELESS;2902}2903else {2904StrCopy(scriptFunctionList[scriptFunctionCount].name, funcName);2905scriptFunctionList[scriptFunctionCount].access = ACCESS_PUBLIC;2906scriptFunctionList[scriptFunctionCount].ptr.scriptCodePtr = scriptCodePos;2907scriptFunctionList[scriptFunctionCount].ptr.jumpTablePtr = jumpTablePos;29082909scriptCodeOffset = scriptCodePos;2910jumpTableOffset = jumpTablePos;2911parseMode = PARSEMODE_FUNCTION;2912++scriptFunctionCount;2913}2914}2915else {2916StrCopy(scriptFunctionList[funcID].name, funcName);2917scriptFunctionList[funcID].access = ACCESS_PUBLIC;2918scriptFunctionList[funcID].ptr.scriptCodePtr = scriptCodePos;2919scriptFunctionList[funcID].ptr.jumpTablePtr = jumpTablePos;29202921scriptCodeOffset = scriptCodePos;2922jumpTableOffset = jumpTablePos;2923parseMode = PARSEMODE_FUNCTION;2924}2925}2926else if (FindStringToken(scriptText, "privatefunction", 1) == 0) { // regular private decl2927char funcName[0x40];2928for (textPos = 15; scriptText[textPos]; ++textPos) funcName[textPos - 15] = scriptText[textPos];29292930funcName[textPos - 15] = 0;2931int funcID = -1;2932for (int f = 0; f < scriptFunctionCount; ++f) {2933if (StrComp(funcName, scriptFunctionList[f].name))2934funcID = f;2935}29362937if (funcID <= -1) {2938if (scriptFunctionCount >= FUNCTION_COUNT) {2939parseMode = PARSEMODE_SCOPELESS;2940}2941else {2942StrCopy(scriptFunctionList[scriptFunctionCount].name, funcName);2943scriptFunctionList[scriptFunctionCount].access = ACCESS_PRIVATE;2944scriptFunctionList[scriptFunctionCount].ptr.scriptCodePtr = scriptCodePos;2945scriptFunctionList[scriptFunctionCount].ptr.jumpTablePtr = jumpTablePos;29462947scriptCodeOffset = scriptCodePos;2948jumpTableOffset = jumpTablePos;2949parseMode = PARSEMODE_FUNCTION;2950++scriptFunctionCount;2951}2952}2953else {2954StrCopy(scriptFunctionList[funcID].name, funcName);2955scriptFunctionList[funcID].access = ACCESS_PRIVATE;2956scriptFunctionList[funcID].ptr.scriptCodePtr = scriptCodePos;2957scriptFunctionList[funcID].ptr.jumpTablePtr = jumpTablePos;29582959scriptCodeOffset = scriptCodePos;2960jumpTableOffset = jumpTablePos;2961parseMode = PARSEMODE_FUNCTION;2962}2963}2964break;29652966case PARSEMODE_PLATFORMSKIP:2967if (!disableLineIncrement)2968++lineID;29692970if (FindStringToken(scriptText, "#endplatform", 1) == 0)2971parseMode = PARSEMODE_FUNCTION;2972break;29732974case PARSEMODE_FUNCTION:2975if (!disableLineIncrement)2976++lineID;29772978if (scriptText[0]) {2979if (StrComp(scriptText, "endevent")) {2980scriptCode[scriptCodePos++] = FUNC_END;2981parseMode = PARSEMODE_SCOPELESS;2982}2983else if (StrComp(scriptText, "endfunction")) {2984scriptCode[scriptCodePos++] = FUNC_RETURN;2985parseMode = PARSEMODE_SCOPELESS;2986}2987else if (FindStringToken(scriptText, "#platform:", 1) == 0) {2988if (FindStringToken(scriptText, Engine.gamePlatform, 1) == -12989&& FindStringToken(scriptText, Engine.gameRenderType, 1) == -12990#if RETRO_USE_HAPTICS2991&& FindStringToken(scriptText, Engine.gameHapticSetting, 1) == -12992#endif2993#if !RETRO_USE_ORIGINAL_CODE && RETRO_REV032994&& FindStringToken(scriptText, Engine.releaseType, 1) == -1 // general flag for standalone/origins content switching2995#endif2996#if !RETRO_USE_ORIGINAL_CODE2997&& FindStringToken(scriptText, "USE_DECOMP", 1) == -1 // general flag for decomp-only stuff2998#endif2999#if RETRO_USE_NETWORKING3000&& FindStringToken(scriptText, "USE_NETWORKING", 1) == -13001#endif3002#if RETRO_USE_MOD_LOADER3003&& FindStringToken(scriptText, "USE_MOD_LOADER", 1) == -13004#endif3005) {3006parseMode = PARSEMODE_PLATFORMSKIP;3007}3008}3009else if (FindStringToken(scriptText, "#endplatform", 1) == -1) {3010ConvertConditionalStatement(scriptText);3011if (ConvertSwitchStatement(scriptText)) {3012parseMode = PARSEMODE_SWITCHREAD;3013info.readPos = (int)GetFilePosition();3014switchDeep = 0;3015}3016ConvertArithmaticSyntax(scriptText);3017if (!ReadSwitchCase(scriptText)) {3018ConvertFunctionText(scriptText);3019if (Engine.gameMode == ENGINE_SCRIPTERROR) {3020AddTextMenuEntry(&gameMenu[0], " ");3021AddTextMenuEntry(&gameMenu[0], "ERROR IN");3022AddTextMenuEntry(&gameMenu[0], scriptName);3023parseMode = PARSEMODE_ERROR;3024}3025}3026}3027}3028break;30293030case PARSEMODE_SWITCHREAD:3031if (FindStringToken(scriptText, "switch", 1) == 0)3032++switchDeep;30333034if (switchDeep) {3035if (FindStringToken(scriptText, "endswitch", 1) == 0)3036--switchDeep;3037}3038else if (FindStringToken(scriptText, "endswitch", 1) == 0) {3039SetFilePosition(info.readPos);3040parseMode = PARSEMODE_FUNCTION;3041int jPos = jumpTableStack[jumpTableStackPos];3042switchDeep = abs(jumpTable[jPos + 1] - jumpTable[jPos]) + 1;3043for (textPos = 0; textPos < switchDeep; ++textPos) jumpTable[jumpTablePos++] = -1;3044}3045else {3046CheckCaseNumber(scriptText);3047}3048break;30493050case PARSEMODE_TABLEREAD:3051if (!disableLineIncrement)3052++lineID;30533054if (FindStringToken(scriptText, "endtable", 1) == 0) {3055parseMode = PARSEMODE_SCOPELESS;3056}3057else {3058if (StrLength(scriptText) >= 1)3059ReadTableValues(scriptText);30603061parseMode = PARSEMODE_TABLEREAD;3062}3063break;30643065default: break;3066}3067}30683069CloseFile();3070}3071}3072#endif30733074void LoadBytecode(int stageListID, int scriptID)3075{3076char scriptPath[0x40];3077switch (stageListID) {3078case STAGELIST_PRESENTATION:3079case STAGELIST_REGULAR:3080case STAGELIST_BONUS:3081case STAGELIST_SPECIAL:3082StrCopy(scriptPath, "Bytecode/");3083StrAdd(scriptPath, stageList[stageListID][stageListPosition].folder);3084StrAdd(scriptPath, ".bin");3085break;3086case 4: StrCopy(scriptPath, "Bytecode/GlobalCode.bin"); break;3087default: break;3088}30893090FileInfo info;3091if (LoadFile(scriptPath, &info)) {3092byte fileBuffer = 0;3093int *scriptCodePtr = &scriptCode[scriptCodePos];3094int *jumpTablePtr = &jumpTable[jumpTablePos];30953096FileRead(&fileBuffer, 1);3097int scriptCodeSize = fileBuffer;3098FileRead(&fileBuffer, 1);3099scriptCodeSize |= fileBuffer << 8;3100FileRead(&fileBuffer, 1);3101scriptCodeSize |= fileBuffer << 16;3102FileRead(&fileBuffer, 1);3103scriptCodeSize |= fileBuffer << 24;31043105while (scriptCodeSize > 0) {3106FileRead(&fileBuffer, 1);3107int blockSize = fileBuffer & 0x7F;3108if (fileBuffer >= 0x80) {3109while (blockSize > 0) {3110FileRead(&fileBuffer, 1);3111*scriptCodePtr = fileBuffer;3112FileRead(&fileBuffer, 1);3113*scriptCodePtr |= fileBuffer << 8;3114FileRead(&fileBuffer, 1);3115*scriptCodePtr |= fileBuffer << 16;3116FileRead(&fileBuffer, 1);3117*scriptCodePtr |= fileBuffer << 24;31183119++scriptCodePtr;3120++scriptCodePos;3121--scriptCodeSize;3122--blockSize;3123}3124}3125else {3126while (blockSize > 0) {3127FileRead(&fileBuffer, 1);3128*scriptCodePtr = fileBuffer;31293130++scriptCodePtr;3131++scriptCodePos;3132--scriptCodeSize;3133--blockSize;3134}3135}3136}31373138FileRead(&fileBuffer, 1);3139int jumpTableSize = fileBuffer;3140FileRead(&fileBuffer, 1);3141jumpTableSize |= fileBuffer << 8;3142FileRead(&fileBuffer, 1);3143jumpTableSize |= fileBuffer << 16;3144FileRead(&fileBuffer, 1);3145jumpTableSize |= fileBuffer << 24;31463147while (jumpTableSize > 0) {3148FileRead(&fileBuffer, 1);3149int blockSize = fileBuffer & 0x7F;31503151if (fileBuffer >= 0x80) {3152while (blockSize > 0) {3153FileRead(&fileBuffer, 1);3154*jumpTablePtr = fileBuffer;3155FileRead(&fileBuffer, 1);3156*jumpTablePtr |= fileBuffer << 8;3157FileRead(&fileBuffer, 1);3158*jumpTablePtr |= fileBuffer << 16;3159FileRead(&fileBuffer, 1);3160*jumpTablePtr |= fileBuffer << 24;31613162++jumpTablePtr;3163++jumpTablePos;3164--jumpTableSize;3165--blockSize;3166}3167}3168else {3169while (blockSize > 0) {3170FileRead(&fileBuffer, 1);3171*jumpTablePtr = fileBuffer;31723173++jumpTablePtr;3174++jumpTablePos;3175--jumpTableSize;3176--blockSize;3177}3178}3179}31803181FileRead(&fileBuffer, 1);3182int scriptCount = fileBuffer;3183FileRead(&fileBuffer, 1);3184scriptCount |= fileBuffer << 8;31853186for (int s = 0; s < scriptCount; ++s) {3187ObjectScript *script = &objectScriptList[scriptID + s];31883189FileRead(&fileBuffer, 1);3190script->eventUpdate.scriptCodePtr = fileBuffer;3191FileRead(&fileBuffer, 1);3192script->eventUpdate.scriptCodePtr |= fileBuffer << 8;3193FileRead(&fileBuffer, 1);3194script->eventUpdate.scriptCodePtr |= fileBuffer << 16;3195FileRead(&fileBuffer, 1);3196script->eventUpdate.scriptCodePtr |= fileBuffer << 24;31973198FileRead(&fileBuffer, 1);3199script->eventDraw.scriptCodePtr = fileBuffer;3200FileRead(&fileBuffer, 1);3201script->eventDraw.scriptCodePtr |= fileBuffer << 8;3202FileRead(&fileBuffer, 1);3203script->eventDraw.scriptCodePtr |= fileBuffer << 16;3204FileRead(&fileBuffer, 1);3205script->eventDraw.scriptCodePtr |= fileBuffer << 24;32063207FileRead(&fileBuffer, 1);3208script->eventStartup.scriptCodePtr = fileBuffer;3209FileRead(&fileBuffer, 1);3210script->eventStartup.scriptCodePtr |= (fileBuffer << 8);3211FileRead(&fileBuffer, 1);3212script->eventStartup.scriptCodePtr |= (fileBuffer << 16);3213FileRead(&fileBuffer, 1);3214script->eventStartup.scriptCodePtr |= fileBuffer << 24;3215}32163217for (int s = 0; s < scriptCount; ++s) {3218ObjectScript *script = &objectScriptList[scriptID + s];32193220FileRead(&fileBuffer, 1);3221script->eventUpdate.jumpTablePtr = fileBuffer;3222FileRead(&fileBuffer, 1);3223script->eventUpdate.jumpTablePtr |= fileBuffer << 8;3224FileRead(&fileBuffer, 1);3225script->eventUpdate.jumpTablePtr |= fileBuffer << 16;3226FileRead(&fileBuffer, 1);3227script->eventUpdate.jumpTablePtr |= fileBuffer << 24;32283229FileRead(&fileBuffer, 1);3230script->eventDraw.jumpTablePtr = fileBuffer;3231FileRead(&fileBuffer, 1);3232script->eventDraw.jumpTablePtr |= fileBuffer << 8;3233FileRead(&fileBuffer, 1);3234script->eventDraw.jumpTablePtr |= fileBuffer << 16;3235FileRead(&fileBuffer, 1);3236script->eventDraw.jumpTablePtr |= fileBuffer << 24;32373238FileRead(&fileBuffer, 1);3239script->eventStartup.jumpTablePtr = fileBuffer;3240FileRead(&fileBuffer, 1);3241script->eventStartup.jumpTablePtr |= fileBuffer << 8;3242FileRead(&fileBuffer, 1);3243script->eventStartup.jumpTablePtr |= fileBuffer << 16;3244FileRead(&fileBuffer, 1);3245script->eventStartup.jumpTablePtr |= fileBuffer << 24;3246}32473248FileRead(&fileBuffer, 1);3249int functionCount = fileBuffer;3250FileRead(&fileBuffer, 1);3251functionCount |= fileBuffer << 8;32523253for (int f = 0; f < functionCount; ++f) {3254ScriptFunction *function = &scriptFunctionList[f];32553256FileRead(&fileBuffer, 1);3257function->ptr.scriptCodePtr = fileBuffer;3258FileRead(&fileBuffer, 1);3259function->ptr.scriptCodePtr |= fileBuffer << 8;3260FileRead(&fileBuffer, 1);3261function->ptr.scriptCodePtr |= fileBuffer << 16;3262FileRead(&fileBuffer, 1);3263function->ptr.scriptCodePtr |= fileBuffer << 24;3264}32653266for (int f = 0; f < functionCount; ++f) {3267ScriptFunction *function = &scriptFunctionList[f];32683269FileRead(&fileBuffer, 1);3270function->ptr.jumpTablePtr = fileBuffer;3271FileRead(&fileBuffer, 1);3272function->ptr.jumpTablePtr |= fileBuffer << 8;3273FileRead(&fileBuffer, 1);3274function->ptr.jumpTablePtr |= fileBuffer << 16;3275FileRead(&fileBuffer, 1);3276function->ptr.jumpTablePtr |= fileBuffer << 24;3277}32783279CloseFile();3280}3281}32823283void ClearScriptData()3284{3285memset(scriptCode, 0, sizeof(scriptCode));3286memset(jumpTable, 0, sizeof(jumpTable));32873288memset(foreachStack, -1, sizeof(foreachStack));3289memset(jumpTableStack, 0, sizeof(jumpTableStack));3290memset(functionStack, 0, sizeof(functionStack));32913292scriptFrameCount = 0;32933294scriptCodePos = 0;3295jumpTablePos = 0;3296jumpTableStackPos = 0;3297functionStackPos = 0;32983299scriptCodePos = 0;3300scriptCodeOffset = 0;3301jumpTablePos = 0;3302jumpTableOffset = 0;33033304#if RETRO_USE_COMPILER3305scriptFunctionCount = 0;33063307lineID = 0;33083309scriptValueListCount = COMMON_SCRIPT_VAR_COUNT;3310for (int v = COMMON_SCRIPT_VAR_COUNT; v < SCRIPT_VAR_COUNT; ++v) {3311MEM_ZERO(scriptValueList[v]);3312}3313#endif33143315ClearAnimationData();33163317for (int o = 0; o < OBJECT_COUNT; ++o) {3318ObjectScript *scriptInfo = &objectScriptList[o];3319scriptInfo->eventUpdate.scriptCodePtr = SCRIPTCODE_COUNT - 1;3320scriptInfo->eventUpdate.jumpTablePtr = JUMPTABLE_COUNT - 1;3321scriptInfo->eventDraw.scriptCodePtr = SCRIPTCODE_COUNT - 1;3322scriptInfo->eventDraw.jumpTablePtr = JUMPTABLE_COUNT - 1;3323scriptInfo->eventStartup.scriptCodePtr = SCRIPTCODE_COUNT - 1;3324scriptInfo->eventStartup.jumpTablePtr = JUMPTABLE_COUNT - 1;3325scriptInfo->frameListOffset = 0;3326scriptInfo->spriteSheetID = 0;3327scriptInfo->animFile = GetDefaultAnimationRef();3328typeNames[o][0] = 0;3329}33303331for (int s = globalSFXCount; s < globalSFXCount + stageSFXCount; ++s) {3332sfxNames[s][0] = 0;3333}33343335for (int f = 0; f < FUNCTION_COUNT; ++f) {3336scriptFunctionList[f].ptr.scriptCodePtr = SCRIPTCODE_COUNT - 1;3337scriptFunctionList[f].ptr.jumpTablePtr = JUMPTABLE_COUNT - 1;3338}33393340SetObjectTypeName("Blank Object", OBJ_TYPE_BLANKOBJECT);3341}33423343void ProcessScript(int scriptCodeStart, int jumpTableStart, byte scriptEvent)3344{3345bool running = true;3346int scriptCodePtr = scriptCodeStart;3347jumpTableStackPos = 0;3348functionStackPos = 0;3349foreachStackPos = 0;33503351while (running) {3352int opcode = scriptCode[scriptCodePtr++];3353int opcodeSize = functions[opcode].opcodeSize;3354int scriptCodeOffset = scriptCodePtr;33553356scriptText[0] = '\0';33573358// Get Values3359for (int i = 0; i < opcodeSize; ++i) {3360int opcodeType = scriptCode[scriptCodePtr++];33613362if (opcodeType == SCRIPTVAR_VAR) {3363int arrayVal = 0;3364switch (scriptCode[scriptCodePtr++]) {3365case VARARR_NONE: arrayVal = objectEntityPos; break;33663367case VARARR_ARRAY:3368if (scriptCode[scriptCodePtr++] == 1)3369arrayVal = scriptEng.arrayPosition[scriptCode[scriptCodePtr++]];3370else3371arrayVal = scriptCode[scriptCodePtr++];3372break;33733374case VARARR_ENTNOPLUS1:3375if (scriptCode[scriptCodePtr++] == 1)3376arrayVal = scriptEng.arrayPosition[scriptCode[scriptCodePtr++]] + objectEntityPos;3377else3378arrayVal = scriptCode[scriptCodePtr++] + objectEntityPos;3379break;33803381case VARARR_ENTNOMINUS1:3382if (scriptCode[scriptCodePtr++] == 1)3383arrayVal = objectEntityPos - scriptEng.arrayPosition[scriptCode[scriptCodePtr++]];3384else3385arrayVal = objectEntityPos - scriptCode[scriptCodePtr++];3386break;33873388default: break;3389}33903391#if RETRO_REV03 && !RETRO_USE_ORIGINAL_CODE3392bool inputCheck = true; // Default to true for mobile bytecode3393// If we're using the scripts or an Origins datafile, check the array value3394if (forceUseScripts || Engine.usingOrigins)3395inputCheck = arrayVal <= 1;3396#endif33973398// Variables3399switch (scriptCode[scriptCodePtr++]) {3400default: break;3401case VAR_TEMP0: scriptEng.operands[i] = scriptEng.temp[0]; break;3402case VAR_TEMP1: scriptEng.operands[i] = scriptEng.temp[1]; break;3403case VAR_TEMP2: scriptEng.operands[i] = scriptEng.temp[2]; break;3404case VAR_TEMP3: scriptEng.operands[i] = scriptEng.temp[3]; break;3405case VAR_TEMP4: scriptEng.operands[i] = scriptEng.temp[4]; break;3406case VAR_TEMP5: scriptEng.operands[i] = scriptEng.temp[5]; break;3407case VAR_TEMP6: scriptEng.operands[i] = scriptEng.temp[6]; break;3408case VAR_TEMP7: scriptEng.operands[i] = scriptEng.temp[7]; break;3409case VAR_CHECKRESULT: scriptEng.operands[i] = scriptEng.checkResult; break;3410case VAR_ARRAYPOS0: scriptEng.operands[i] = scriptEng.arrayPosition[0]; break;3411case VAR_ARRAYPOS1: scriptEng.operands[i] = scriptEng.arrayPosition[1]; break;3412case VAR_ARRAYPOS2: scriptEng.operands[i] = scriptEng.arrayPosition[2]; break;3413case VAR_ARRAYPOS3: scriptEng.operands[i] = scriptEng.arrayPosition[3]; break;3414case VAR_ARRAYPOS4: scriptEng.operands[i] = scriptEng.arrayPosition[4]; break;3415case VAR_ARRAYPOS5: scriptEng.operands[i] = scriptEng.arrayPosition[5]; break;3416case VAR_ARRAYPOS6: scriptEng.operands[i] = scriptEng.arrayPosition[6]; break;3417case VAR_ARRAYPOS7: scriptEng.operands[i] = scriptEng.arrayPosition[7]; break;3418case VAR_GLOBAL: scriptEng.operands[i] = globalVariables[arrayVal]; break;3419case VAR_LOCAL: scriptEng.operands[i] = scriptCode[arrayVal]; break;3420case VAR_OBJECTENTITYPOS: scriptEng.operands[i] = arrayVal; break;3421case VAR_OBJECTGROUPID: {3422scriptEng.operands[i] = objectEntityList[arrayVal].groupID;3423break;3424}3425case VAR_OBJECTTYPE: {3426scriptEng.operands[i] = objectEntityList[arrayVal].type;3427break;3428}3429case VAR_OBJECTPROPERTYVALUE: {3430scriptEng.operands[i] = objectEntityList[arrayVal].propertyValue;3431break;3432}3433case VAR_OBJECTXPOS: {3434scriptEng.operands[i] = objectEntityList[arrayVal].xpos;3435break;3436}3437case VAR_OBJECTYPOS: {3438scriptEng.operands[i] = objectEntityList[arrayVal].ypos;3439break;3440}3441case VAR_OBJECTIXPOS: {3442scriptEng.operands[i] = objectEntityList[arrayVal].xpos >> 16;3443break;3444}3445case VAR_OBJECTIYPOS: {3446scriptEng.operands[i] = objectEntityList[arrayVal].ypos >> 16;3447break;3448}3449case VAR_OBJECTXVEL: {3450scriptEng.operands[i] = objectEntityList[arrayVal].xvel;3451break;3452}3453case VAR_OBJECTYVEL: {3454scriptEng.operands[i] = objectEntityList[arrayVal].yvel;3455break;3456}3457case VAR_OBJECTSPEED: {3458scriptEng.operands[i] = objectEntityList[arrayVal].speed;3459break;3460}3461case VAR_OBJECTSTATE: {3462scriptEng.operands[i] = objectEntityList[arrayVal].state;3463break;3464}3465case VAR_OBJECTROTATION: {3466scriptEng.operands[i] = objectEntityList[arrayVal].rotation;3467break;3468}3469case VAR_OBJECTSCALE: {3470scriptEng.operands[i] = objectEntityList[arrayVal].scale;3471break;3472}3473case VAR_OBJECTPRIORITY: {3474scriptEng.operands[i] = objectEntityList[arrayVal].priority;3475break;3476}3477case VAR_OBJECTDRAWORDER: {3478scriptEng.operands[i] = objectEntityList[arrayVal].drawOrder;3479break;3480}3481case VAR_OBJECTDIRECTION: {3482scriptEng.operands[i] = objectEntityList[arrayVal].direction;3483break;3484}3485case VAR_OBJECTINKEFFECT: {3486scriptEng.operands[i] = objectEntityList[arrayVal].inkEffect;3487break;3488}3489case VAR_OBJECTALPHA: {3490scriptEng.operands[i] = objectEntityList[arrayVal].alpha;3491break;3492}3493case VAR_OBJECTFRAME: {3494scriptEng.operands[i] = objectEntityList[arrayVal].frame;3495break;3496}3497case VAR_OBJECTANIMATION: {3498scriptEng.operands[i] = objectEntityList[arrayVal].animation;3499break;3500}3501case VAR_OBJECTPREVANIMATION: {3502scriptEng.operands[i] = objectEntityList[arrayVal].prevAnimation;3503break;3504}3505case VAR_OBJECTANIMATIONSPEED: {3506scriptEng.operands[i] = objectEntityList[arrayVal].animationSpeed;3507break;3508}3509case VAR_OBJECTANIMATIONTIMER: {3510scriptEng.operands[i] = objectEntityList[arrayVal].animationTimer;3511break;3512}3513case VAR_OBJECTANGLE: {3514scriptEng.operands[i] = objectEntityList[arrayVal].angle;3515break;3516}3517case VAR_OBJECTLOOKPOSX: {3518scriptEng.operands[i] = objectEntityList[arrayVal].lookPosX;3519break;3520}3521case VAR_OBJECTLOOKPOSY: {3522scriptEng.operands[i] = objectEntityList[arrayVal].lookPosY;3523break;3524}3525case VAR_OBJECTCOLLISIONMODE: {3526scriptEng.operands[i] = objectEntityList[arrayVal].collisionMode;3527break;3528}3529case VAR_OBJECTCOLLISIONPLANE: {3530scriptEng.operands[i] = objectEntityList[arrayVal].collisionPlane;3531break;3532}3533case VAR_OBJECTCONTROLMODE: {3534scriptEng.operands[i] = objectEntityList[arrayVal].controlMode;3535break;3536}3537case VAR_OBJECTCONTROLLOCK: {3538scriptEng.operands[i] = objectEntityList[arrayVal].controlLock;3539break;3540}3541case VAR_OBJECTPUSHING: {3542scriptEng.operands[i] = objectEntityList[arrayVal].pushing;3543break;3544}3545case VAR_OBJECTVISIBLE: {3546scriptEng.operands[i] = objectEntityList[arrayVal].visible;3547break;3548}3549case VAR_OBJECTTILECOLLISIONS: {3550scriptEng.operands[i] = objectEntityList[arrayVal].tileCollisions;3551break;3552}3553case VAR_OBJECTINTERACTION: {3554scriptEng.operands[i] = objectEntityList[arrayVal].objectInteractions;3555break;3556}3557case VAR_OBJECTGRAVITY: {3558scriptEng.operands[i] = objectEntityList[arrayVal].gravity;3559break;3560}3561case VAR_OBJECTUP: {3562scriptEng.operands[i] = objectEntityList[arrayVal].up;3563break;3564}3565case VAR_OBJECTDOWN: {3566scriptEng.operands[i] = objectEntityList[arrayVal].down;3567break;3568}3569case VAR_OBJECTLEFT: {3570scriptEng.operands[i] = objectEntityList[arrayVal].left;3571break;3572}3573case VAR_OBJECTRIGHT: {3574scriptEng.operands[i] = objectEntityList[arrayVal].right;3575break;3576}3577case VAR_OBJECTJUMPPRESS: {3578scriptEng.operands[i] = objectEntityList[arrayVal].jumpPress;3579break;3580}3581case VAR_OBJECTJUMPHOLD: {3582scriptEng.operands[i] = objectEntityList[arrayVal].jumpHold;3583break;3584}3585case VAR_OBJECTSCROLLTRACKING: {3586scriptEng.operands[i] = objectEntityList[arrayVal].scrollTracking;3587break;3588}3589case VAR_OBJECTFLOORSENSORL: {3590scriptEng.operands[i] = objectEntityList[arrayVal].floorSensors[0];3591break;3592}3593case VAR_OBJECTFLOORSENSORC: {3594scriptEng.operands[i] = objectEntityList[arrayVal].floorSensors[1];3595break;3596}3597case VAR_OBJECTFLOORSENSORR: {3598scriptEng.operands[i] = objectEntityList[arrayVal].floorSensors[2];3599break;3600}3601#if !RETRO_REV003602case VAR_OBJECTFLOORSENSORLC: {3603scriptEng.operands[i] = objectEntityList[arrayVal].floorSensors[3];3604break;3605}3606case VAR_OBJECTFLOORSENSORRC: {3607scriptEng.operands[i] = objectEntityList[arrayVal].floorSensors[4];3608break;3609}3610#endif3611case VAR_OBJECTCOLLISIONLEFT: {3612AnimationFile *animFile = objectScriptList[objectEntityList[arrayVal].type].animFile;3613Entity *ent = &objectEntityList[arrayVal];3614if (animFile) {3615int h = animFrames[animationList[animFile->aniListOffset + ent->animation].frameListOffset + ent->frame].hitboxID;36163617scriptEng.operands[i] = hitboxList[animFile->hitboxListOffset + h].left[0];3618}3619else {3620scriptEng.operands[i] = 0;3621}3622break;3623}3624case VAR_OBJECTCOLLISIONTOP: {3625AnimationFile *animFile = objectScriptList[objectEntityList[arrayVal].type].animFile;3626Entity *ent = &objectEntityList[arrayVal];3627if (animFile) {3628int h = animFrames[animationList[animFile->aniListOffset + ent->animation].frameListOffset + ent->frame].hitboxID;36293630scriptEng.operands[i] = hitboxList[animFile->hitboxListOffset + h].top[0];3631}3632else {3633scriptEng.operands[i] = 0;3634}3635break;3636}3637case VAR_OBJECTCOLLISIONRIGHT: {3638AnimationFile *animFile = objectScriptList[objectEntityList[arrayVal].type].animFile;3639Entity *ent = &objectEntityList[arrayVal];3640if (animFile) {3641int h = animFrames[animationList[animFile->aniListOffset + ent->animation].frameListOffset + ent->frame].hitboxID;36423643scriptEng.operands[i] = hitboxList[animFile->hitboxListOffset + h].right[0];3644}3645else {3646scriptEng.operands[i] = 0;3647}3648break;3649}3650case VAR_OBJECTCOLLISIONBOTTOM: {3651AnimationFile *animFile = objectScriptList[objectEntityList[arrayVal].type].animFile;3652Entity *ent = &objectEntityList[arrayVal];3653if (animFile) {3654int h = animFrames[animationList[animFile->aniListOffset + ent->animation].frameListOffset + ent->frame].hitboxID;36553656scriptEng.operands[i] = hitboxList[animFile->hitboxListOffset + h].bottom[0];3657}3658else {3659scriptEng.operands[i] = 0;3660}3661break;3662}3663case VAR_OBJECTOUTOFBOUNDS: {3664#if !RETRO_REV003665int boundX1_2P = -(0x200 << 16);3666int boundX2_2P = (0x200 << 16);3667int boundX3_2P = -(0x180 << 16);3668int boundX4_2P = (0x180 << 16);36693670int boundY1_2P = -(0x180 << 16);3671int boundY2_2P = (0x180 << 16);3672int boundY3_2P = -(0x100 << 16);3673int boundY4_2P = (0x100 << 16);36743675Entity *entPtr = &objectEntityList[arrayVal];3676int x = entPtr->xpos >> 16;3677int y = entPtr->ypos >> 16;36783679if (entPtr->priority == PRIORITY_BOUNDS_SMALL || entPtr->priority == PRIORITY_ACTIVE_SMALL) {3680if (stageMode == STAGEMODE_2P) {3681x = entPtr->xpos;3682y = entPtr->ypos;36833684int boundL_P1 = objectEntityList[0].xpos + boundX3_2P;3685int boundR_P1 = objectEntityList[0].xpos + boundX4_2P;3686int boundT_P1 = objectEntityList[0].ypos + boundY3_2P;3687int boundB_P1 = objectEntityList[0].ypos + boundY4_2P;36883689int boundL_P2 = objectEntityList[1].xpos + boundX3_2P;3690int boundR_P2 = objectEntityList[1].xpos + boundX4_2P;3691int boundT_P2 = objectEntityList[1].ypos + boundY3_2P;3692int boundB_P2 = objectEntityList[1].ypos + boundY4_2P;36933694bool oobP1 = scriptEng.operands[i] = x <= boundL_P1 || x >= boundR_P1 || y <= boundT_P1 || y >= boundB_P1;3695bool oobP2 = scriptEng.operands[i] = x <= boundL_P2 || x >= boundR_P2 || y <= boundT_P2 || y >= boundB_P2;36963697scriptEng.operands[i] = oobP1 && oobP2;3698}3699else {3700int boundL = xScrollOffset - OBJECT_BORDER_X3;3701int boundR = xScrollOffset + OBJECT_BORDER_X4;3702int boundT = yScrollOffset - OBJECT_BORDER_Y3;3703int boundB = yScrollOffset + OBJECT_BORDER_Y4;37043705scriptEng.operands[i] = x <= boundL || x >= boundR || y <= boundT || y >= boundB;3706}3707}3708else {3709if (stageMode == STAGEMODE_2P) {3710x = entPtr->xpos;3711y = entPtr->ypos;37123713int boundL_P1 = objectEntityList[0].xpos + boundX1_2P;3714int boundR_P1 = objectEntityList[0].xpos + boundX2_2P;3715int boundT_P1 = objectEntityList[0].ypos + boundY1_2P;3716int boundB_P1 = objectEntityList[0].ypos + boundY2_2P;37173718int boundL_P2 = objectEntityList[1].xpos + boundX1_2P;3719int boundR_P2 = objectEntityList[1].xpos + boundX2_2P;3720int boundT_P2 = objectEntityList[1].ypos + boundY1_2P;3721int boundB_P2 = objectEntityList[1].ypos + boundY2_2P;37223723bool oobP1 = scriptEng.operands[i] = x <= boundL_P1 || x >= boundR_P1 || y <= boundT_P1 || y >= boundB_P1;3724bool oobP2 = scriptEng.operands[i] = x <= boundL_P2 || x >= boundR_P2 || y <= boundT_P2 || y >= boundB_P2;37253726scriptEng.operands[i] = oobP1 && oobP2;3727}3728else {3729int boundL = xScrollOffset - OBJECT_BORDER_X1;3730int boundR = xScrollOffset + OBJECT_BORDER_X2;3731int boundT = yScrollOffset - OBJECT_BORDER_Y1;3732int boundB = yScrollOffset + OBJECT_BORDER_Y2;37333734scriptEng.operands[i] = x <= boundL || x >= boundR || y <= boundT || y >= boundB;3735}3736}3737#else3738int x = objectEntityList[arrayVal].xpos >> 16;3739int y = objectEntityList[arrayVal].ypos >> 16;37403741int boundL = xScrollOffset - OBJECT_BORDER_X1;3742int boundR = xScrollOffset + OBJECT_BORDER_X2;3743int boundT = yScrollOffset - OBJECT_BORDER_Y1;3744int boundB = yScrollOffset + OBJECT_BORDER_Y2;37453746scriptEng.operands[i] = x <= boundL || x >= boundR || y <= boundT || y >= boundB;3747#endif3748break;3749}3750case VAR_OBJECTSPRITESHEET: {3751scriptEng.operands[i] = objectScriptList[objectEntityList[arrayVal].type].spriteSheetID;3752break;3753}3754case VAR_OBJECTVALUE0: {3755scriptEng.operands[i] = objectEntityList[arrayVal].values[0];3756break;3757}3758case VAR_OBJECTVALUE1: {3759scriptEng.operands[i] = objectEntityList[arrayVal].values[1];3760break;3761}3762case VAR_OBJECTVALUE2: {3763scriptEng.operands[i] = objectEntityList[arrayVal].values[2];3764break;3765}3766case VAR_OBJECTVALUE3: {3767scriptEng.operands[i] = objectEntityList[arrayVal].values[3];3768break;3769}3770case VAR_OBJECTVALUE4: {3771scriptEng.operands[i] = objectEntityList[arrayVal].values[4];3772break;3773}3774case VAR_OBJECTVALUE5: {3775scriptEng.operands[i] = objectEntityList[arrayVal].values[5];3776break;3777}3778case VAR_OBJECTVALUE6: {3779scriptEng.operands[i] = objectEntityList[arrayVal].values[6];3780break;3781}3782case VAR_OBJECTVALUE7: {3783scriptEng.operands[i] = objectEntityList[arrayVal].values[7];3784break;3785}3786case VAR_OBJECTVALUE8: {3787scriptEng.operands[i] = objectEntityList[arrayVal].values[8];3788break;3789}3790case VAR_OBJECTVALUE9: {3791scriptEng.operands[i] = objectEntityList[arrayVal].values[9];3792break;3793}3794case VAR_OBJECTVALUE10: {3795scriptEng.operands[i] = objectEntityList[arrayVal].values[10];3796break;3797}3798case VAR_OBJECTVALUE11: {3799scriptEng.operands[i] = objectEntityList[arrayVal].values[11];3800break;3801}3802case VAR_OBJECTVALUE12: {3803scriptEng.operands[i] = objectEntityList[arrayVal].values[12];3804break;3805}3806case VAR_OBJECTVALUE13: {3807scriptEng.operands[i] = objectEntityList[arrayVal].values[13];3808break;3809}3810case VAR_OBJECTVALUE14: {3811scriptEng.operands[i] = objectEntityList[arrayVal].values[14];3812break;3813}3814case VAR_OBJECTVALUE15: {3815scriptEng.operands[i] = objectEntityList[arrayVal].values[15];3816break;3817}3818case VAR_OBJECTVALUE16: {3819scriptEng.operands[i] = objectEntityList[arrayVal].values[16];3820break;3821}3822case VAR_OBJECTVALUE17: {3823scriptEng.operands[i] = objectEntityList[arrayVal].values[17];3824break;3825}3826case VAR_OBJECTVALUE18: {3827scriptEng.operands[i] = objectEntityList[arrayVal].values[18];3828break;3829}3830case VAR_OBJECTVALUE19: {3831scriptEng.operands[i] = objectEntityList[arrayVal].values[19];3832break;3833}3834case VAR_OBJECTVALUE20: {3835scriptEng.operands[i] = objectEntityList[arrayVal].values[20];3836break;3837}3838case VAR_OBJECTVALUE21: {3839scriptEng.operands[i] = objectEntityList[arrayVal].values[21];3840break;3841}3842case VAR_OBJECTVALUE22: {3843scriptEng.operands[i] = objectEntityList[arrayVal].values[22];3844break;3845}3846case VAR_OBJECTVALUE23: {3847scriptEng.operands[i] = objectEntityList[arrayVal].values[23];3848break;3849}3850case VAR_OBJECTVALUE24: {3851scriptEng.operands[i] = objectEntityList[arrayVal].values[24];3852break;3853}3854case VAR_OBJECTVALUE25: {3855scriptEng.operands[i] = objectEntityList[arrayVal].values[25];3856break;3857}3858case VAR_OBJECTVALUE26: {3859scriptEng.operands[i] = objectEntityList[arrayVal].values[26];3860break;3861}3862case VAR_OBJECTVALUE27: {3863scriptEng.operands[i] = objectEntityList[arrayVal].values[27];3864break;3865}3866case VAR_OBJECTVALUE28: {3867scriptEng.operands[i] = objectEntityList[arrayVal].values[28];3868break;3869}3870case VAR_OBJECTVALUE29: {3871scriptEng.operands[i] = objectEntityList[arrayVal].values[29];3872break;3873}3874case VAR_OBJECTVALUE30: {3875scriptEng.operands[i] = objectEntityList[arrayVal].values[30];3876break;3877}3878case VAR_OBJECTVALUE31: {3879scriptEng.operands[i] = objectEntityList[arrayVal].values[31];3880break;3881}3882case VAR_OBJECTVALUE32: {3883scriptEng.operands[i] = objectEntityList[arrayVal].values[32];3884break;3885}3886case VAR_OBJECTVALUE33: {3887scriptEng.operands[i] = objectEntityList[arrayVal].values[33];3888break;3889}3890case VAR_OBJECTVALUE34: {3891scriptEng.operands[i] = objectEntityList[arrayVal].values[34];3892break;3893}3894case VAR_OBJECTVALUE35: {3895scriptEng.operands[i] = objectEntityList[arrayVal].values[35];3896break;3897}3898case VAR_OBJECTVALUE36: {3899scriptEng.operands[i] = objectEntityList[arrayVal].values[36];3900break;3901}3902case VAR_OBJECTVALUE37: {3903scriptEng.operands[i] = objectEntityList[arrayVal].values[37];3904break;3905}3906case VAR_OBJECTVALUE38: {3907scriptEng.operands[i] = objectEntityList[arrayVal].values[38];3908break;3909}3910case VAR_OBJECTVALUE39: {3911scriptEng.operands[i] = objectEntityList[arrayVal].values[39];3912break;3913}3914case VAR_OBJECTVALUE40: {3915scriptEng.operands[i] = objectEntityList[arrayVal].values[40];3916break;3917}3918case VAR_OBJECTVALUE41: {3919scriptEng.operands[i] = objectEntityList[arrayVal].values[41];3920break;3921}3922case VAR_OBJECTVALUE42: {3923scriptEng.operands[i] = objectEntityList[arrayVal].values[42];3924break;3925}3926case VAR_OBJECTVALUE43: {3927scriptEng.operands[i] = objectEntityList[arrayVal].values[43];3928break;3929}3930case VAR_OBJECTVALUE44: {3931scriptEng.operands[i] = objectEntityList[arrayVal].values[44];3932break;3933}3934case VAR_OBJECTVALUE45: {3935scriptEng.operands[i] = objectEntityList[arrayVal].values[45];3936break;3937}3938case VAR_OBJECTVALUE46: {3939scriptEng.operands[i] = objectEntityList[arrayVal].values[46];3940break;3941}3942case VAR_OBJECTVALUE47: {3943scriptEng.operands[i] = objectEntityList[arrayVal].values[47];3944break;3945}3946case VAR_STAGESTATE: scriptEng.operands[i] = stageMode; break;3947case VAR_STAGEACTIVELIST: scriptEng.operands[i] = activeStageList; break;3948case VAR_STAGELISTPOS: scriptEng.operands[i] = stageListPosition; break;3949case VAR_STAGETIMEENABLED: scriptEng.operands[i] = timeEnabled; break;3950case VAR_STAGEMILLISECONDS: scriptEng.operands[i] = stageMilliseconds; break;3951case VAR_STAGESECONDS: scriptEng.operands[i] = stageSeconds; break;3952case VAR_STAGEMINUTES: scriptEng.operands[i] = stageMinutes; break;3953case VAR_STAGEACTNUM: scriptEng.operands[i] = actID; break;3954case VAR_STAGEPAUSEENABLED: scriptEng.operands[i] = pauseEnabled; break;3955case VAR_STAGELISTSIZE: scriptEng.operands[i] = stageListCount[activeStageList]; break;3956case VAR_STAGENEWXBOUNDARY1: scriptEng.operands[i] = newXBoundary1; break;3957case VAR_STAGENEWXBOUNDARY2: scriptEng.operands[i] = newXBoundary2; break;3958case VAR_STAGENEWYBOUNDARY1: scriptEng.operands[i] = newYBoundary1; break;3959case VAR_STAGENEWYBOUNDARY2: scriptEng.operands[i] = newYBoundary2; break;3960case VAR_STAGECURXBOUNDARY1: scriptEng.operands[i] = curXBoundary1; break;3961case VAR_STAGECURXBOUNDARY2: scriptEng.operands[i] = curXBoundary2; break;3962case VAR_STAGECURYBOUNDARY1: scriptEng.operands[i] = curYBoundary1; break;3963case VAR_STAGECURYBOUNDARY2: scriptEng.operands[i] = curYBoundary2; break;3964case VAR_STAGEDEFORMATIONDATA0: scriptEng.operands[i] = bgDeformationData0[arrayVal]; break;3965case VAR_STAGEDEFORMATIONDATA1: scriptEng.operands[i] = bgDeformationData1[arrayVal]; break;3966case VAR_STAGEDEFORMATIONDATA2: scriptEng.operands[i] = bgDeformationData2[arrayVal]; break;3967case VAR_STAGEDEFORMATIONDATA3: scriptEng.operands[i] = bgDeformationData3[arrayVal]; break;3968case VAR_STAGEWATERLEVEL: scriptEng.operands[i] = waterLevel; break;3969case VAR_STAGEACTIVELAYER: scriptEng.operands[i] = activeTileLayers[arrayVal]; break;3970case VAR_STAGEMIDPOINT: scriptEng.operands[i] = tLayerMidPoint; break;3971case VAR_STAGEPLAYERLISTPOS: scriptEng.operands[i] = playerListPos; break;3972case VAR_STAGEDEBUGMODE: scriptEng.operands[i] = debugMode; break;3973case VAR_STAGEENTITYPOS: scriptEng.operands[i] = objectEntityPos; break;3974case VAR_SCREENCAMERAENABLED: scriptEng.operands[i] = cameraEnabled; break;3975case VAR_SCREENCAMERATARGET: scriptEng.operands[i] = cameraTarget; break;3976case VAR_SCREENCAMERASTYLE: scriptEng.operands[i] = cameraStyle; break;3977case VAR_SCREENCAMERAX: scriptEng.operands[i] = cameraXPos; break;3978case VAR_SCREENCAMERAY: scriptEng.operands[i] = cameraYPos; break;3979case VAR_SCREENDRAWLISTSIZE: scriptEng.operands[i] = drawListEntries[arrayVal].listSize; break;3980case VAR_SCREENXCENTER: scriptEng.operands[i] = SCREEN_CENTERX; break;3981case VAR_SCREENYCENTER: scriptEng.operands[i] = SCREEN_CENTERY; break;3982case VAR_SCREENXSIZE: scriptEng.operands[i] = SCREEN_XSIZE; break;3983case VAR_SCREENYSIZE: scriptEng.operands[i] = SCREEN_YSIZE; break;3984case VAR_SCREENXOFFSET: scriptEng.operands[i] = xScrollOffset; break;3985case VAR_SCREENYOFFSET: scriptEng.operands[i] = yScrollOffset; break;3986case VAR_SCREENSHAKEX: scriptEng.operands[i] = cameraShakeX; break;3987case VAR_SCREENSHAKEY: scriptEng.operands[i] = cameraShakeY; break;3988case VAR_SCREENADJUSTCAMERAY: scriptEng.operands[i] = cameraAdjustY; break;3989case VAR_TOUCHSCREENDOWN: scriptEng.operands[i] = touchDown[arrayVal]; break;3990case VAR_TOUCHSCREENXPOS: scriptEng.operands[i] = touchX[arrayVal]; break;3991case VAR_TOUCHSCREENYPOS: scriptEng.operands[i] = touchY[arrayVal]; break;3992case VAR_MUSICVOLUME: scriptEng.operands[i] = masterVolume; break;3993case VAR_MUSICCURRENTTRACK: scriptEng.operands[i] = trackID; break;3994case VAR_MUSICPOSITION: scriptEng.operands[i] = musicPosition; break;3995#if RETRO_REV03 && !RETRO_USE_ORIGINAL_CODE3996case VAR_KEYDOWNUP: scriptEng.operands[i] = keyDown.up && inputCheck; break;3997case VAR_KEYDOWNDOWN: scriptEng.operands[i] = keyDown.down && inputCheck; break;3998case VAR_KEYDOWNLEFT: scriptEng.operands[i] = keyDown.left && inputCheck; break;3999case VAR_KEYDOWNRIGHT: scriptEng.operands[i] = keyDown.right && inputCheck; break;4000case VAR_KEYDOWNBUTTONA: scriptEng.operands[i] = keyDown.A && inputCheck; break;4001case VAR_KEYDOWNBUTTONB: scriptEng.operands[i] = keyDown.B && inputCheck; break;4002case VAR_KEYDOWNBUTTONC: scriptEng.operands[i] = keyDown.C && inputCheck; break;4003case VAR_KEYDOWNBUTTONX: scriptEng.operands[i] = keyDown.X && inputCheck; break;4004case VAR_KEYDOWNBUTTONY: scriptEng.operands[i] = keyDown.Y && inputCheck; break;4005case VAR_KEYDOWNBUTTONZ: scriptEng.operands[i] = keyDown.Z && inputCheck; break;4006case VAR_KEYDOWNBUTTONL: scriptEng.operands[i] = keyDown.L && inputCheck; break;4007case VAR_KEYDOWNBUTTONR: scriptEng.operands[i] = keyDown.R && inputCheck; break;4008case VAR_KEYDOWNSTART: scriptEng.operands[i] = keyDown.start && inputCheck; break;4009case VAR_KEYDOWNSELECT: scriptEng.operands[i] = keyDown.select && inputCheck; break;4010case VAR_KEYPRESSUP: scriptEng.operands[i] = keyPress.up && inputCheck; break;4011case VAR_KEYPRESSDOWN: scriptEng.operands[i] = keyPress.down && inputCheck; break;4012case VAR_KEYPRESSLEFT: scriptEng.operands[i] = keyPress.left && inputCheck; break;4013case VAR_KEYPRESSRIGHT: scriptEng.operands[i] = keyPress.right && inputCheck; break;4014case VAR_KEYPRESSBUTTONA: scriptEng.operands[i] = keyPress.A && inputCheck; break;4015case VAR_KEYPRESSBUTTONB: scriptEng.operands[i] = keyPress.B && inputCheck; break;4016case VAR_KEYPRESSBUTTONC: scriptEng.operands[i] = keyPress.C && inputCheck; break;4017case VAR_KEYPRESSBUTTONX: scriptEng.operands[i] = keyPress.X && inputCheck; break;4018case VAR_KEYPRESSBUTTONY: scriptEng.operands[i] = keyPress.Y && inputCheck; break;4019case VAR_KEYPRESSBUTTONZ: scriptEng.operands[i] = keyPress.Z && inputCheck; break;4020case VAR_KEYPRESSBUTTONL: scriptEng.operands[i] = keyPress.L && inputCheck; break;4021case VAR_KEYPRESSBUTTONR: scriptEng.operands[i] = keyPress.R && inputCheck; break;4022case VAR_KEYPRESSSTART: scriptEng.operands[i] = keyPress.start && inputCheck; break;4023case VAR_KEYPRESSSELECT: scriptEng.operands[i] = keyPress.select && inputCheck; break;4024#else4025case VAR_KEYDOWNUP: scriptEng.operands[i] = keyDown.up; break;4026case VAR_KEYDOWNDOWN: scriptEng.operands[i] = keyDown.down; break;4027case VAR_KEYDOWNLEFT: scriptEng.operands[i] = keyDown.left; break;4028case VAR_KEYDOWNRIGHT: scriptEng.operands[i] = keyDown.right; break;4029case VAR_KEYDOWNBUTTONA: scriptEng.operands[i] = keyDown.A; break;4030case VAR_KEYDOWNBUTTONB: scriptEng.operands[i] = keyDown.B; break;4031case VAR_KEYDOWNBUTTONC: scriptEng.operands[i] = keyDown.C; break;4032case VAR_KEYDOWNBUTTONX: scriptEng.operands[i] = keyDown.X; break;4033case VAR_KEYDOWNBUTTONY: scriptEng.operands[i] = keyDown.Y; break;4034case VAR_KEYDOWNBUTTONZ: scriptEng.operands[i] = keyDown.Z; break;4035case VAR_KEYDOWNBUTTONL: scriptEng.operands[i] = keyDown.L; break;4036case VAR_KEYDOWNBUTTONR: scriptEng.operands[i] = keyDown.R; break;4037case VAR_KEYDOWNSTART: scriptEng.operands[i] = keyDown.start; break;4038case VAR_KEYDOWNSELECT: scriptEng.operands[i] = keyDown.select; break;4039case VAR_KEYPRESSUP: scriptEng.operands[i] = keyPress.up; break;4040case VAR_KEYPRESSDOWN: scriptEng.operands[i] = keyPress.down; break;4041case VAR_KEYPRESSLEFT: scriptEng.operands[i] = keyPress.left; break;4042case VAR_KEYPRESSRIGHT: scriptEng.operands[i] = keyPress.right; break;4043case VAR_KEYPRESSBUTTONA: scriptEng.operands[i] = keyPress.A; break;4044case VAR_KEYPRESSBUTTONB: scriptEng.operands[i] = keyPress.B; break;4045case VAR_KEYPRESSBUTTONC: scriptEng.operands[i] = keyPress.C; break;4046case VAR_KEYPRESSBUTTONX: scriptEng.operands[i] = keyPress.X; break;4047case VAR_KEYPRESSBUTTONY: scriptEng.operands[i] = keyPress.Y; break;4048case VAR_KEYPRESSBUTTONZ: scriptEng.operands[i] = keyPress.Z; break;4049case VAR_KEYPRESSBUTTONL: scriptEng.operands[i] = keyPress.L; break;4050case VAR_KEYPRESSBUTTONR: scriptEng.operands[i] = keyPress.R; break;4051case VAR_KEYPRESSSTART: scriptEng.operands[i] = keyPress.start; break;4052case VAR_KEYPRESSSELECT: scriptEng.operands[i] = keyPress.select; break;4053#endif4054case VAR_MENU1SELECTION: scriptEng.operands[i] = gameMenu[0].selection1; break;4055case VAR_MENU2SELECTION: scriptEng.operands[i] = gameMenu[1].selection1; break;4056case VAR_TILELAYERXSIZE: scriptEng.operands[i] = stageLayouts[arrayVal].xsize; break;4057case VAR_TILELAYERYSIZE: scriptEng.operands[i] = stageLayouts[arrayVal].ysize; break;4058case VAR_TILELAYERTYPE: scriptEng.operands[i] = stageLayouts[arrayVal].type; break;4059case VAR_TILELAYERANGLE: scriptEng.operands[i] = stageLayouts[arrayVal].angle; break;4060case VAR_TILELAYERXPOS: scriptEng.operands[i] = stageLayouts[arrayVal].xpos; break;4061case VAR_TILELAYERYPOS: scriptEng.operands[i] = stageLayouts[arrayVal].ypos; break;4062case VAR_TILELAYERZPOS: scriptEng.operands[i] = stageLayouts[arrayVal].zpos; break;4063case VAR_TILELAYERPARALLAXFACTOR: scriptEng.operands[i] = stageLayouts[arrayVal].parallaxFactor; break;4064case VAR_TILELAYERSCROLLSPEED: scriptEng.operands[i] = stageLayouts[arrayVal].scrollSpeed; break;4065case VAR_TILELAYERSCROLLPOS: scriptEng.operands[i] = stageLayouts[arrayVal].scrollPos; break;4066case VAR_TILELAYERDEFORMATIONOFFSET: scriptEng.operands[i] = stageLayouts[arrayVal].deformationOffset; break;4067case VAR_TILELAYERDEFORMATIONOFFSETW: scriptEng.operands[i] = stageLayouts[arrayVal].deformationOffsetW; break;4068case VAR_HPARALLAXPARALLAXFACTOR: scriptEng.operands[i] = hParallax.parallaxFactor[arrayVal]; break;4069case VAR_HPARALLAXSCROLLSPEED: scriptEng.operands[i] = hParallax.scrollSpeed[arrayVal]; break;4070case VAR_HPARALLAXSCROLLPOS: scriptEng.operands[i] = hParallax.scrollPos[arrayVal]; break;4071case VAR_VPARALLAXPARALLAXFACTOR: scriptEng.operands[i] = vParallax.parallaxFactor[arrayVal]; break;4072case VAR_VPARALLAXSCROLLSPEED: scriptEng.operands[i] = vParallax.scrollSpeed[arrayVal]; break;4073case VAR_VPARALLAXSCROLLPOS: scriptEng.operands[i] = vParallax.scrollPos[arrayVal]; break;4074case VAR_SCENE3DVERTEXCOUNT: scriptEng.operands[i] = vertexCount; break;4075case VAR_SCENE3DFACECOUNT: scriptEng.operands[i] = faceCount; break;4076case VAR_SCENE3DPROJECTIONX: scriptEng.operands[i] = projectionX; break;4077case VAR_SCENE3DPROJECTIONY: scriptEng.operands[i] = projectionY; break;4078#if !RETRO_REV004079case VAR_SCENE3DFOGCOLOR: scriptEng.operands[i] = fogColor; break;4080case VAR_SCENE3DFOGSTRENGTH: scriptEng.operands[i] = fogStrength; break;4081#endif4082case VAR_VERTEXBUFFERX: scriptEng.operands[i] = vertexBuffer[arrayVal].x; break;4083case VAR_VERTEXBUFFERY: scriptEng.operands[i] = vertexBuffer[arrayVal].y; break;4084case VAR_VERTEXBUFFERZ: scriptEng.operands[i] = vertexBuffer[arrayVal].z; break;4085case VAR_VERTEXBUFFERU: scriptEng.operands[i] = vertexBuffer[arrayVal].u; break;4086case VAR_VERTEXBUFFERV: scriptEng.operands[i] = vertexBuffer[arrayVal].v; break;4087case VAR_FACEBUFFERA: scriptEng.operands[i] = faceBuffer[arrayVal].a; break;4088case VAR_FACEBUFFERB: scriptEng.operands[i] = faceBuffer[arrayVal].b; break;4089case VAR_FACEBUFFERC: scriptEng.operands[i] = faceBuffer[arrayVal].c; break;4090case VAR_FACEBUFFERD: scriptEng.operands[i] = faceBuffer[arrayVal].d; break;4091case VAR_FACEBUFFERFLAG: scriptEng.operands[i] = faceBuffer[arrayVal].flag; break;4092case VAR_FACEBUFFERCOLOR: scriptEng.operands[i] = faceBuffer[arrayVal].color; break;4093case VAR_SAVERAM: scriptEng.operands[i] = saveRAM[arrayVal]; break;4094case VAR_ENGINESTATE: scriptEng.operands[i] = Engine.gameMode; break;4095#if RETRO_REV004096case VAR_ENGINEMESSAGE: scriptEng.operands[i] = Engine.message; break;4097#endif4098case VAR_ENGINELANGUAGE: scriptEng.operands[i] = Engine.language; break;4099case VAR_ENGINEONLINEACTIVE: scriptEng.operands[i] = Engine.onlineActive; break;4100case VAR_ENGINESFXVOLUME: scriptEng.operands[i] = sfxVolume; break;4101case VAR_ENGINEBGMVOLUME: scriptEng.operands[i] = bgmVolume; break;4102#if RETRO_REV004103case VAR_ENGINEPLATFORMID: scriptEng.operands[i] = RETRO_GAMEPLATFORMID; break;4104#endif4105case VAR_ENGINETRIALMODE: scriptEng.operands[i] = Engine.trialMode; break;4106#if !RETRO_REV004107case VAR_ENGINEDEVICETYPE: scriptEng.operands[i] = RETRO_DEVICETYPE; break;4108#endif41094110#if RETRO_REV034111// Origins Extras4112// Due to using regular v4, these don't support array values like origins expects, so its always screen[0]4113case VAR_SCREENCURRENTID: scriptEng.operands[i] = 0; break;4114case VAR_CAMERAENABLED:4115if (arrayVal == 0)4116scriptEng.operands[i] = cameraEnabled;4117else4118scriptEng.operands[i] = 0;4119break;4120case VAR_CAMERATARGET:4121if (arrayVal == 0)4122scriptEng.operands[i] = cameraTarget;4123else4124scriptEng.operands[i] = 0;4125break;4126case VAR_CAMERASTYLE:4127if (arrayVal == 0)4128scriptEng.operands[i] = cameraStyle;4129else4130scriptEng.operands[i] = 0;4131break;4132case VAR_CAMERAXPOS:4133if (arrayVal == 0)4134scriptEng.operands[i] = cameraXPos;4135else4136scriptEng.operands[i] = 0;4137break;4138case VAR_CAMERAYPOS:4139if (arrayVal == 0)4140scriptEng.operands[i] = cameraYPos;4141else4142scriptEng.operands[i] = 0;4143break;4144case VAR_CAMERAADJUSTY:4145if (arrayVal == 0)4146scriptEng.operands[i] = cameraAdjustY;4147else4148scriptEng.operands[i] = 0;4149break;4150#endif41514152#if RETRO_USE_HAPTICS4153case VAR_HAPTICSENABLED: scriptEng.operands[i] = Engine.hapticsEnabled; break;4154#endif4155}4156}4157else if (opcodeType == SCRIPTVAR_INTCONST) { // int constant4158scriptEng.operands[i] = scriptCode[scriptCodePtr++];4159}4160else if (opcodeType == SCRIPTVAR_STRCONST) { // string constant4161int strLen = scriptCode[scriptCodePtr++];4162scriptText[strLen] = 0;4163for (int c = 0; c < strLen; ++c) {4164switch (c % 4) {4165case 0:4166scriptText[c] = scriptCode[scriptCodePtr] >> 24;4167break;41684169case 1:4170scriptText[c] = (0xFFFFFF & scriptCode[scriptCodePtr]) >> 16;4171break;41724173case 2:4174scriptText[c] = (0xFFFF & scriptCode[scriptCodePtr]) >> 8;4175break;41764177case 3:4178scriptText[c] = scriptCode[scriptCodePtr++];4179break;41804181default: break;4182}4183}4184scriptCodePtr++;4185}4186}41874188ObjectScript *scriptInfo = &objectScriptList[objectEntityList[objectEntityPos].type];4189Entity *entity = &objectEntityList[objectEntityPos];4190SpriteFrame *spriteFrame = nullptr;41914192// Functions4193switch (opcode) {4194default: break;4195case FUNC_END: running = false; break;4196case FUNC_EQUAL: scriptEng.operands[0] = scriptEng.operands[1]; break;4197case FUNC_ADD: scriptEng.operands[0] += scriptEng.operands[1]; break;4198case FUNC_SUB: scriptEng.operands[0] -= scriptEng.operands[1]; break;4199case FUNC_INC: ++scriptEng.operands[0]; break;4200case FUNC_DEC: --scriptEng.operands[0]; break;4201case FUNC_MUL: scriptEng.operands[0] *= scriptEng.operands[1]; break;4202case FUNC_DIV: scriptEng.operands[0] /= scriptEng.operands[1]; break;4203case FUNC_SHR: scriptEng.operands[0] >>= scriptEng.operands[1]; break;4204case FUNC_SHL: scriptEng.operands[0] <<= scriptEng.operands[1]; break;4205case FUNC_AND: scriptEng.operands[0] &= scriptEng.operands[1]; break;4206case FUNC_OR: scriptEng.operands[0] |= scriptEng.operands[1]; break;4207case FUNC_XOR: scriptEng.operands[0] ^= scriptEng.operands[1]; break;4208case FUNC_MOD: scriptEng.operands[0] %= scriptEng.operands[1]; break;4209case FUNC_FLIPSIGN: scriptEng.operands[0] = -scriptEng.operands[0]; break;4210case FUNC_CHECKEQUAL:4211scriptEng.checkResult = scriptEng.operands[0] == scriptEng.operands[1];4212opcodeSize = 0;4213break;4214case FUNC_CHECKGREATER:4215scriptEng.checkResult = scriptEng.operands[0] > scriptEng.operands[1];4216opcodeSize = 0;4217break;4218case FUNC_CHECKLOWER:4219scriptEng.checkResult = scriptEng.operands[0] < scriptEng.operands[1];4220opcodeSize = 0;4221break;4222case FUNC_CHECKNOTEQUAL:4223scriptEng.checkResult = scriptEng.operands[0] != scriptEng.operands[1];4224opcodeSize = 0;4225break;4226case FUNC_IFEQUAL:4227if (scriptEng.operands[1] != scriptEng.operands[2])4228scriptCodePtr = scriptCodeStart + jumpTable[jumpTableStart + scriptEng.operands[0]];4229jumpTableStack[++jumpTableStackPos] = scriptEng.operands[0];4230opcodeSize = 0;4231break;4232case FUNC_IFGREATER:4233if (scriptEng.operands[1] <= scriptEng.operands[2])4234scriptCodePtr = scriptCodeStart + jumpTable[jumpTableStart + scriptEng.operands[0]];4235jumpTableStack[++jumpTableStackPos] = scriptEng.operands[0];4236opcodeSize = 0;4237break;4238case FUNC_IFGREATEROREQUAL:4239if (scriptEng.operands[1] < scriptEng.operands[2])4240scriptCodePtr = scriptCodeStart + jumpTable[jumpTableStart + scriptEng.operands[0]];4241jumpTableStack[++jumpTableStackPos] = scriptEng.operands[0];4242opcodeSize = 0;4243break;4244case FUNC_IFLOWER:4245if (scriptEng.operands[1] >= scriptEng.operands[2])4246scriptCodePtr = scriptCodeStart + jumpTable[jumpTableStart + scriptEng.operands[0]];4247jumpTableStack[++jumpTableStackPos] = scriptEng.operands[0];4248opcodeSize = 0;4249break;4250case FUNC_IFLOWEROREQUAL:4251if (scriptEng.operands[1] > scriptEng.operands[2])4252scriptCodePtr = scriptCodeStart + jumpTable[jumpTableStart + scriptEng.operands[0]];4253jumpTableStack[++jumpTableStackPos] = scriptEng.operands[0];4254opcodeSize = 0;4255break;4256case FUNC_IFNOTEQUAL:4257if (scriptEng.operands[1] == scriptEng.operands[2])4258scriptCodePtr = scriptCodeStart + jumpTable[jumpTableStart + scriptEng.operands[0]];4259jumpTableStack[++jumpTableStackPos] = scriptEng.operands[0];4260opcodeSize = 0;4261break;4262case FUNC_ELSE:4263opcodeSize = 0;4264scriptCodePtr = scriptCodeStart + jumpTable[jumpTableStart + jumpTableStack[jumpTableStackPos--] + 1];4265break;4266case FUNC_ENDIF:4267opcodeSize = 0;4268--jumpTableStackPos;4269break;4270case FUNC_WEQUAL:4271if (scriptEng.operands[1] != scriptEng.operands[2])4272scriptCodePtr = scriptCodeStart + jumpTable[jumpTableStart + scriptEng.operands[0] + 1];4273else4274jumpTableStack[++jumpTableStackPos] = scriptEng.operands[0];4275opcodeSize = 0;4276break;4277case FUNC_WGREATER:4278if (scriptEng.operands[1] <= scriptEng.operands[2])4279scriptCodePtr = scriptCodeStart + jumpTable[jumpTableStart + scriptEng.operands[0] + 1];4280else4281jumpTableStack[++jumpTableStackPos] = scriptEng.operands[0];4282opcodeSize = 0;4283break;4284case FUNC_WGREATEROREQUAL:4285if (scriptEng.operands[1] < scriptEng.operands[2])4286scriptCodePtr = scriptCodeStart + jumpTable[jumpTableStart + scriptEng.operands[0] + 1];4287else4288jumpTableStack[++jumpTableStackPos] = scriptEng.operands[0];4289opcodeSize = 0;4290break;4291case FUNC_WLOWER:4292if (scriptEng.operands[1] >= scriptEng.operands[2])4293scriptCodePtr = scriptCodeStart + jumpTable[jumpTableStart + scriptEng.operands[0] + 1];4294else4295jumpTableStack[++jumpTableStackPos] = scriptEng.operands[0];4296opcodeSize = 0;4297break;4298case FUNC_WLOWEROREQUAL:4299if (scriptEng.operands[1] > scriptEng.operands[2])4300scriptCodePtr = scriptCodeStart + jumpTable[jumpTableStart + scriptEng.operands[0] + 1];4301else4302jumpTableStack[++jumpTableStackPos] = scriptEng.operands[0];4303opcodeSize = 0;4304break;4305case FUNC_WNOTEQUAL:4306if (scriptEng.operands[1] == scriptEng.operands[2])4307scriptCodePtr = scriptCodeStart + jumpTable[jumpTableStart + scriptEng.operands[0] + 1];4308else4309jumpTableStack[++jumpTableStackPos] = scriptEng.operands[0];4310opcodeSize = 0;4311break;4312case FUNC_LOOP:4313opcodeSize = 0;4314scriptCodePtr = scriptCodeStart + jumpTable[jumpTableStart + jumpTableStack[jumpTableStackPos--]];4315break;4316case FUNC_FOREACHACTIVE: {4317int groupID = scriptEng.operands[1];4318if (groupID < TYPEGROUP_COUNT) {4319int loop = foreachStack[++foreachStackPos] + 1;4320foreachStack[foreachStackPos] = loop;4321if (loop >= objectTypeGroupList[groupID].listSize) {4322opcodeSize = 0;4323foreachStack[foreachStackPos--] = -1;4324scriptCodePtr = scriptCodeStart + jumpTable[jumpTableStart + scriptEng.operands[0] + 1];4325break;4326}4327else {4328scriptEng.operands[2] = objectTypeGroupList[groupID].entityRefs[loop];4329jumpTableStack[++jumpTableStackPos] = scriptEng.operands[0];4330}4331}4332else {4333opcodeSize = 0;4334scriptCodePtr = scriptCodeStart + jumpTable[jumpTableStart + scriptEng.operands[0] + 1];4335}4336break;4337}4338case FUNC_FOREACHALL: {4339int objType = scriptEng.operands[1];4340if (objType < OBJECT_COUNT) {4341int loop = foreachStack[++foreachStackPos] + 1;4342foreachStack[foreachStackPos] = loop;43434344if (scriptEvent == EVENT_SETUP) {4345while (true) {4346if (loop >= TEMPENTITY_START) {4347opcodeSize = 0;4348foreachStack[foreachStackPos--] = -1;4349scriptCodePtr = scriptCodeStart + jumpTable[jumpTableStart + scriptEng.operands[0] + 1];4350break;4351}4352else if (objType == objectEntityList[loop].type) {4353scriptEng.operands[2] = loop;4354jumpTableStack[++jumpTableStackPos] = scriptEng.operands[0];4355break;4356}4357else {4358foreachStack[foreachStackPos] = ++loop;4359}4360}4361}4362else {4363while (true) {4364if (loop >= ENTITY_COUNT) {4365opcodeSize = 0;4366foreachStack[foreachStackPos--] = -1;4367scriptCodePtr = scriptCodeStart + jumpTable[jumpTableStart + scriptEng.operands[0] + 1];4368break;4369}4370else if (objType == objectEntityList[loop].type) {4371scriptEng.operands[2] = loop;4372jumpTableStack[++jumpTableStackPos] = scriptEng.operands[0];4373break;4374}4375else {4376foreachStack[foreachStackPos] = ++loop;4377}4378}4379}4380}4381else {4382opcodeSize = 0;4383scriptCodePtr = scriptCodeStart + jumpTable[jumpTableStart + scriptEng.operands[0] + 1];4384}4385break;4386}4387case FUNC_NEXT:4388opcodeSize = 0;4389scriptCodePtr = scriptCodeStart + jumpTable[jumpTableStart + jumpTableStack[jumpTableStackPos--]];4390--foreachStackPos;4391break;4392case FUNC_SWITCH:4393jumpTableStack[++jumpTableStackPos] = scriptEng.operands[0];4394if (scriptEng.operands[1] < jumpTable[jumpTableStart + scriptEng.operands[0]]4395|| scriptEng.operands[1] > jumpTable[jumpTableStart + scriptEng.operands[0] + 1])4396scriptCodePtr = scriptCodeStart + jumpTable[jumpTableStart + scriptEng.operands[0] + 2];4397else4398scriptCodePtr = scriptCodeStart4399+ jumpTable[jumpTableStart + scriptEng.operands[0] + 44400+ (scriptEng.operands[1] - jumpTable[jumpTableStart + scriptEng.operands[0]])];4401opcodeSize = 0;4402break;4403case FUNC_BREAK:4404opcodeSize = 0;4405scriptCodePtr = scriptCodeStart + jumpTable[jumpTableStart + jumpTableStack[jumpTableStackPos--] + 3];4406break;4407case FUNC_ENDSWITCH:4408opcodeSize = 0;4409--jumpTableStackPos;4410break;4411case FUNC_RAND: scriptEng.operands[0] = rand() % scriptEng.operands[1]; break;4412case FUNC_SIN: {4413scriptEng.operands[0] = Sin512(scriptEng.operands[1]);4414break;4415}4416case FUNC_COS: {4417scriptEng.operands[0] = Cos512(scriptEng.operands[1]);4418break;4419}4420case FUNC_SIN256: {4421scriptEng.operands[0] = Sin256(scriptEng.operands[1]);4422break;4423}4424case FUNC_COS256: {4425scriptEng.operands[0] = Cos256(scriptEng.operands[1]);4426break;4427}4428case FUNC_ATAN2: {4429scriptEng.operands[0] = ArcTanLookup(scriptEng.operands[1], scriptEng.operands[2]);4430break;4431}4432case FUNC_INTERPOLATE:4433scriptEng.operands[0] =4434(scriptEng.operands[2] * (0x100 - scriptEng.operands[3]) + scriptEng.operands[3] * scriptEng.operands[1]) >> 8;4435break;4436case FUNC_INTERPOLATEXY:4437scriptEng.operands[0] =4438(scriptEng.operands[3] * (0x100 - scriptEng.operands[6]) >> 8) + ((scriptEng.operands[6] * scriptEng.operands[2]) >> 8);4439scriptEng.operands[1] =4440(scriptEng.operands[5] * (0x100 - scriptEng.operands[6]) >> 8) + (scriptEng.operands[6] * scriptEng.operands[4] >> 8);4441break;4442case FUNC_LOADSPRITESHEET:4443opcodeSize = 0;4444scriptInfo->spriteSheetID = AddGraphicsFile(scriptText);4445break;4446case FUNC_REMOVESPRITESHEET:4447opcodeSize = 0;4448RemoveGraphicsFile(scriptText, -1);4449break;4450case FUNC_DRAWSPRITE:4451opcodeSize = 0;4452spriteFrame = &scriptFrames[scriptInfo->frameListOffset + scriptEng.operands[0]];4453DrawSprite((entity->xpos >> 16) - xScrollOffset + spriteFrame->pivotX, (entity->ypos >> 16) - yScrollOffset + spriteFrame->pivotY,4454spriteFrame->width, spriteFrame->height, spriteFrame->sprX, spriteFrame->sprY, scriptInfo->spriteSheetID);4455break;4456case FUNC_DRAWSPRITEXY:4457opcodeSize = 0;4458spriteFrame = &scriptFrames[scriptInfo->frameListOffset + scriptEng.operands[0]];4459DrawSprite((scriptEng.operands[1] >> 16) - xScrollOffset + spriteFrame->pivotX,4460(scriptEng.operands[2] >> 16) - yScrollOffset + spriteFrame->pivotY, spriteFrame->width, spriteFrame->height,4461spriteFrame->sprX, spriteFrame->sprY, scriptInfo->spriteSheetID);4462break;4463case FUNC_DRAWSPRITESCREENXY:4464opcodeSize = 0;4465spriteFrame = &scriptFrames[scriptInfo->frameListOffset + scriptEng.operands[0]];4466DrawSprite(scriptEng.operands[1] + spriteFrame->pivotX, scriptEng.operands[2] + spriteFrame->pivotY, spriteFrame->width,4467spriteFrame->height, spriteFrame->sprX, spriteFrame->sprY, scriptInfo->spriteSheetID);4468break;4469case FUNC_DRAWTINTRECT:4470opcodeSize = 0;4471DrawTintRectangle(scriptEng.operands[0], scriptEng.operands[1], scriptEng.operands[2], scriptEng.operands[3]);4472break;4473case FUNC_DRAWNUMBERS: {4474opcodeSize = 0;4475int i = 10;4476if (scriptEng.operands[6]) {4477while (scriptEng.operands[4] > 0) {4478int frameID = scriptEng.operands[3] % i / (i / 10) + scriptEng.operands[0];4479spriteFrame = &scriptFrames[scriptInfo->frameListOffset + frameID];4480DrawSprite(spriteFrame->pivotX + scriptEng.operands[1], spriteFrame->pivotY + scriptEng.operands[2], spriteFrame->width,4481spriteFrame->height, spriteFrame->sprX, spriteFrame->sprY, scriptInfo->spriteSheetID);4482scriptEng.operands[1] -= scriptEng.operands[5];4483i *= 10;4484--scriptEng.operands[4];4485}4486}4487else {4488int extra = 10;4489if (scriptEng.operands[3])4490extra = 10 * scriptEng.operands[3];4491while (scriptEng.operands[4] > 0) {4492if (extra >= i) {4493int frameID = scriptEng.operands[3] % i / (i / 10) + scriptEng.operands[0];4494spriteFrame = &scriptFrames[scriptInfo->frameListOffset + frameID];4495DrawSprite(spriteFrame->pivotX + scriptEng.operands[1], spriteFrame->pivotY + scriptEng.operands[2], spriteFrame->width,4496spriteFrame->height, spriteFrame->sprX, spriteFrame->sprY, scriptInfo->spriteSheetID);4497}4498scriptEng.operands[1] -= scriptEng.operands[5];4499i *= 10;4500--scriptEng.operands[4];4501}4502}4503break;4504}4505case FUNC_DRAWACTNAME: {4506opcodeSize = 0;4507int charID = 0;4508switch (scriptEng.operands[3]) { // Draw Mode4509case 0: // Draw Word 1 (but aligned from the right instead of left)4510charID = 0;45114512for (charID = 0;; ++charID) {4513int nextChar = titleCardText[charID + 1];4514if (nextChar == '-' || !nextChar)4515break;4516}45174518while (charID >= 0) {4519int character = titleCardText[charID];4520if (character == ' ')4521character = -1; // special space char4522if (character == '-')4523character = 0;4524if (character >= '0' && character <= '9')4525character -= 22;4526if (character > '9' && character < 'f')4527character -= 'A';45284529if (character <= -1) {4530scriptEng.operands[1] -= scriptEng.operands[5] + scriptEng.operands[6]; // spaceWidth + spacing4531}4532else {4533character += scriptEng.operands[0];4534spriteFrame = &scriptFrames[scriptInfo->frameListOffset + character];45354536scriptEng.operands[1] -= spriteFrame->width + scriptEng.operands[6];45374538DrawSprite(scriptEng.operands[1] + spriteFrame->pivotX, scriptEng.operands[2] + spriteFrame->pivotY,4539spriteFrame->width, spriteFrame->height, spriteFrame->sprX, spriteFrame->sprY, scriptInfo->spriteSheetID);4540}4541charID--;4542}4543break;45444545case 1: // Draw Word 14546charID = 0;45474548// Draw the first letter as a capital letter, the rest are lowercase (if scriptEng.operands[4] is true, otherwise they're all4549// uppercase)4550if (scriptEng.operands[4] == 1 && titleCardText[charID] != 0) {4551int character = titleCardText[charID];4552if (character == ' ')4553character = -1;4554if (character == '-')4555character = 0;4556if (character >= '0' && character <= '9')4557character -= 22;4558if (character > '9' && character < 'f')4559character -= 'A';45604561if (character <= -1) {4562scriptEng.operands[1] += scriptEng.operands[5] + scriptEng.operands[6]; // spaceWidth + spacing4563}4564else {4565character += scriptEng.operands[0];4566spriteFrame = &scriptFrames[scriptInfo->frameListOffset + character];4567DrawSprite(scriptEng.operands[1] + spriteFrame->pivotX, scriptEng.operands[2] + spriteFrame->pivotY,4568spriteFrame->width, spriteFrame->height, spriteFrame->sprX, spriteFrame->sprY, scriptInfo->spriteSheetID);4569scriptEng.operands[1] += spriteFrame->width + scriptEng.operands[6];4570}45714572scriptEng.operands[0] += 26;4573charID++;4574}45754576while (titleCardText[charID] != 0 && titleCardText[charID] != '-') {4577int character = titleCardText[charID];4578if (character == ' ')4579character = -1;4580if (character == '-')4581character = 0;4582if (character > '/' && character < ':')4583character -= 22;4584if (character > '9' && character < 'f')4585character -= 'A';45864587if (character <= -1) {4588scriptEng.operands[1] += scriptEng.operands[5] + scriptEng.operands[6]; // spaceWidth + spacing4589}4590else {4591character += scriptEng.operands[0];4592spriteFrame = &scriptFrames[scriptInfo->frameListOffset + character];4593DrawSprite(scriptEng.operands[1] + spriteFrame->pivotX, scriptEng.operands[2] + spriteFrame->pivotY,4594spriteFrame->width, spriteFrame->height, spriteFrame->sprX, spriteFrame->sprY, scriptInfo->spriteSheetID);4595scriptEng.operands[1] += spriteFrame->width + scriptEng.operands[6];4596}4597charID++;4598}4599break;46004601case 2: // Draw Word 24602charID = titleCardWord2;46034604// Draw the first letter as a capital letter, the rest are lowercase (if scriptEng.operands[4] is true, otherwise they're all4605// uppercase)4606if (scriptEng.operands[4] == 1 && titleCardText[charID] != 0) {4607int character = titleCardText[charID];4608if (character == ' ')4609character = 0;4610if (character == '-')4611character = 0;4612if (character >= '0' && character <= '9')4613character -= 22;4614if (character > '9' && character < 'f')4615character -= 'A';46164617if (character <= -1) {4618scriptEng.operands[1] += scriptEng.operands[5] + scriptEng.operands[6]; // spaceWidth + spacing4619}4620else {4621character += scriptEng.operands[0];4622spriteFrame = &scriptFrames[scriptInfo->frameListOffset + character];4623DrawSprite(scriptEng.operands[1] + spriteFrame->pivotX, scriptEng.operands[2] + spriteFrame->pivotY,4624spriteFrame->width, spriteFrame->height, spriteFrame->sprX, spriteFrame->sprY, scriptInfo->spriteSheetID);4625scriptEng.operands[1] += spriteFrame->width + scriptEng.operands[6];4626}4627scriptEng.operands[0] += 26;4628charID++;4629}46304631while (titleCardText[charID] != 0) {4632int character = titleCardText[charID];4633if (character == ' ')4634character = 0;4635if (character == '-')4636character = 0;4637if (character >= '0' && character <= '9')4638character -= 22;4639if (character > '9' && character < 'f')4640character -= 'A';46414642if (character <= -1) {4643scriptEng.operands[1] += scriptEng.operands[5] + scriptEng.operands[6]; // spaceWidth + spacing4644}4645else {4646character += scriptEng.operands[0];4647spriteFrame = &scriptFrames[scriptInfo->frameListOffset + character];4648DrawSprite(scriptEng.operands[1] + spriteFrame->pivotX, scriptEng.operands[2] + spriteFrame->pivotY,4649spriteFrame->width, spriteFrame->height, spriteFrame->sprX, spriteFrame->sprY, scriptInfo->spriteSheetID);4650scriptEng.operands[1] += spriteFrame->width + scriptEng.operands[6];4651}4652charID++;4653}4654break;4655}4656break;4657}4658case FUNC_DRAWMENU:4659opcodeSize = 0;4660textMenuSurfaceNo = scriptInfo->spriteSheetID;4661DrawTextMenu(&gameMenu[scriptEng.operands[0]], scriptEng.operands[1], scriptEng.operands[2]);4662break;4663case FUNC_SPRITEFRAME:4664opcodeSize = 0;4665if (scriptEvent == EVENT_SETUP && scriptFrameCount < SPRITEFRAME_COUNT) {4666scriptFrames[scriptFrameCount].pivotX = scriptEng.operands[0];4667scriptFrames[scriptFrameCount].pivotY = scriptEng.operands[1];4668scriptFrames[scriptFrameCount].width = scriptEng.operands[2];4669scriptFrames[scriptFrameCount].height = scriptEng.operands[3];4670scriptFrames[scriptFrameCount].sprX = scriptEng.operands[4];4671scriptFrames[scriptFrameCount].sprY = scriptEng.operands[5];4672++scriptFrameCount;4673}4674break;4675case FUNC_EDITFRAME: {4676opcodeSize = 0;4677spriteFrame = &scriptFrames[scriptInfo->frameListOffset + scriptEng.operands[0]];46784679spriteFrame->pivotX = scriptEng.operands[1];4680spriteFrame->pivotY = scriptEng.operands[2];4681spriteFrame->width = scriptEng.operands[3];4682spriteFrame->height = scriptEng.operands[4];4683spriteFrame->sprX = scriptEng.operands[5];4684spriteFrame->sprY = scriptEng.operands[6];4685} break;4686case FUNC_LOADPALETTE:4687opcodeSize = 0;4688LoadPalette(scriptText, scriptEng.operands[1], scriptEng.operands[2], scriptEng.operands[3], scriptEng.operands[4]);4689break;4690case FUNC_ROTATEPALETTE:4691opcodeSize = 0;4692RotatePalette(scriptEng.operands[0], scriptEng.operands[1], scriptEng.operands[2], scriptEng.operands[3]);4693break;4694case FUNC_SETSCREENFADE:4695opcodeSize = 0;4696SetFade(scriptEng.operands[0], scriptEng.operands[1], scriptEng.operands[2], scriptEng.operands[3]);4697break;4698case FUNC_SETACTIVEPALETTE:4699opcodeSize = 0;4700SetActivePalette(scriptEng.operands[0], scriptEng.operands[1], scriptEng.operands[2]);4701break;4702case FUNC_SETPALETTEFADE:4703#if RETRO_REV004704SetLimitedFade(scriptEng.operands[0], scriptEng.operands[1], scriptEng.operands[2], scriptEng.operands[3], scriptEng.operands[4],4705scriptEng.operands[5], scriptEng.operands[6]);4706#else4707SetPaletteFade(scriptEng.operands[0], scriptEng.operands[1], scriptEng.operands[2], scriptEng.operands[3], scriptEng.operands[4],4708scriptEng.operands[5]);4709#endif4710break;4711case FUNC_SETPALETTEENTRY: SetPaletteEntryPacked(scriptEng.operands[0], scriptEng.operands[1], scriptEng.operands[2]); break;4712case FUNC_GETPALETTEENTRY: scriptEng.operands[2] = GetPaletteEntryPacked(scriptEng.operands[0], scriptEng.operands[1]); break;4713case FUNC_COPYPALETTE:4714opcodeSize = 0;4715CopyPalette(scriptEng.operands[0], scriptEng.operands[1], scriptEng.operands[2], scriptEng.operands[3], scriptEng.operands[4]);4716break;4717case FUNC_CLEARSCREEN:4718opcodeSize = 0;4719ClearScreen(scriptEng.operands[0]);4720break;4721case FUNC_DRAWSPRITEFX:4722opcodeSize = 0;4723spriteFrame = &scriptFrames[scriptInfo->frameListOffset + scriptEng.operands[0]];4724switch (scriptEng.operands[1]) {4725default: break;4726case FX_SCALE:4727DrawSpriteScaled(entity->direction, (scriptEng.operands[2] >> 16) - xScrollOffset,4728(scriptEng.operands[3] >> 16) - yScrollOffset, -spriteFrame->pivotX, -spriteFrame->pivotY, entity->scale,4729entity->scale, spriteFrame->width, spriteFrame->height, spriteFrame->sprX, spriteFrame->sprY,4730scriptInfo->spriteSheetID);4731break;4732case FX_ROTATE:4733DrawSpriteRotated(entity->direction, (scriptEng.operands[2] >> 16) - xScrollOffset,4734(scriptEng.operands[3] >> 16) - yScrollOffset, -spriteFrame->pivotX, -spriteFrame->pivotY,4735spriteFrame->sprX, spriteFrame->sprY, spriteFrame->width, spriteFrame->height, entity->rotation,4736scriptInfo->spriteSheetID);4737break;4738case FX_ROTOZOOM:4739DrawSpriteRotozoom(entity->direction, (scriptEng.operands[2] >> 16) - xScrollOffset,4740(scriptEng.operands[3] >> 16) - yScrollOffset, -spriteFrame->pivotX, -spriteFrame->pivotY,4741spriteFrame->sprX, spriteFrame->sprY, spriteFrame->width, spriteFrame->height, entity->rotation,4742entity->scale, scriptInfo->spriteSheetID);4743break;4744case FX_INK:4745switch (entity->inkEffect) {4746case INK_NONE:4747DrawSprite((scriptEng.operands[2] >> 16) - xScrollOffset + spriteFrame->pivotX,4748(scriptEng.operands[3] >> 16) - yScrollOffset + spriteFrame->pivotY, spriteFrame->width,4749spriteFrame->height, spriteFrame->sprX, spriteFrame->sprY, scriptInfo->spriteSheetID);4750break;4751case INK_BLEND:4752DrawBlendedSprite((scriptEng.operands[2] >> 16) - xScrollOffset + spriteFrame->pivotX,4753(scriptEng.operands[3] >> 16) - yScrollOffset + spriteFrame->pivotY, spriteFrame->width,4754spriteFrame->height, spriteFrame->sprX, spriteFrame->sprY, scriptInfo->spriteSheetID);4755break;4756case INK_ALPHA:4757DrawAlphaBlendedSprite((scriptEng.operands[2] >> 16) - xScrollOffset + spriteFrame->pivotX,4758(scriptEng.operands[3] >> 16) - yScrollOffset + spriteFrame->pivotY, spriteFrame->width,4759spriteFrame->height, spriteFrame->sprX, spriteFrame->sprY, entity->alpha,4760scriptInfo->spriteSheetID);4761break;4762case INK_ADD:4763DrawAdditiveBlendedSprite((scriptEng.operands[2] >> 16) - xScrollOffset + spriteFrame->pivotX,4764(scriptEng.operands[3] >> 16) - yScrollOffset + spriteFrame->pivotY, spriteFrame->width,4765spriteFrame->height, spriteFrame->sprX, spriteFrame->sprY, entity->alpha,4766scriptInfo->spriteSheetID);4767break;4768case INK_SUB:4769DrawSubtractiveBlendedSprite((scriptEng.operands[2] >> 16) - xScrollOffset + spriteFrame->pivotX,4770(scriptEng.operands[3] >> 16) - yScrollOffset + spriteFrame->pivotY, spriteFrame->width,4771spriteFrame->height, spriteFrame->sprX, spriteFrame->sprY, entity->alpha,4772scriptInfo->spriteSheetID);4773break;4774}4775break;4776case FX_TINT:4777if (entity->inkEffect == INK_ALPHA) {4778DrawScaledTintMask(entity->direction, (scriptEng.operands[2] >> 16) - xScrollOffset,4779(scriptEng.operands[3] >> 16) - yScrollOffset, -spriteFrame->pivotX, -spriteFrame->pivotY,4780entity->scale, entity->scale, spriteFrame->width, spriteFrame->height, spriteFrame->sprX,4781spriteFrame->sprY, scriptInfo->spriteSheetID);4782}4783else {4784DrawSpriteScaled(entity->direction, (scriptEng.operands[2] >> 16) - xScrollOffset,4785(scriptEng.operands[3] >> 16) - yScrollOffset, -spriteFrame->pivotX, -spriteFrame->pivotY, entity->scale,4786entity->scale, spriteFrame->width, spriteFrame->height, spriteFrame->sprX, spriteFrame->sprY,4787scriptInfo->spriteSheetID);4788}4789break;4790case FX_FLIP:4791switch (entity->direction) {4792default:4793case FLIP_NONE:4794DrawSpriteFlipped((scriptEng.operands[2] >> 16) - xScrollOffset + spriteFrame->pivotX,4795(scriptEng.operands[3] >> 16) - yScrollOffset + spriteFrame->pivotY, spriteFrame->width,4796spriteFrame->height, spriteFrame->sprX, spriteFrame->sprY, FLIP_NONE, scriptInfo->spriteSheetID);4797break;4798case FLIP_X:4799DrawSpriteFlipped((scriptEng.operands[2] >> 16) - xScrollOffset - spriteFrame->width - spriteFrame->pivotX,4800(scriptEng.operands[3] >> 16) - yScrollOffset + spriteFrame->pivotY, spriteFrame->width,4801spriteFrame->height, spriteFrame->sprX, spriteFrame->sprY, FLIP_X, scriptInfo->spriteSheetID);4802break;4803case FLIP_Y:4804DrawSpriteFlipped((scriptEng.operands[2] >> 16) - xScrollOffset + spriteFrame->pivotX,4805(scriptEng.operands[3] >> 16) - yScrollOffset - spriteFrame->height - spriteFrame->pivotY,4806spriteFrame->width, spriteFrame->height, spriteFrame->sprX, spriteFrame->sprY, FLIP_Y,4807scriptInfo->spriteSheetID);4808break;4809case FLIP_XY:4810DrawSpriteFlipped((scriptEng.operands[2] >> 16) - xScrollOffset - spriteFrame->width - spriteFrame->pivotX,4811(scriptEng.operands[3] >> 16) - yScrollOffset - spriteFrame->height - spriteFrame->pivotY,4812spriteFrame->width, spriteFrame->height, spriteFrame->sprX, spriteFrame->sprY, FLIP_XY,4813scriptInfo->spriteSheetID);4814break;4815}4816break;4817}4818break;4819case FUNC_DRAWSPRITESCREENFX:4820opcodeSize = 0;4821spriteFrame = &scriptFrames[scriptInfo->frameListOffset + scriptEng.operands[0]];4822switch (scriptEng.operands[1]) {4823default: break;4824case FX_SCALE:4825DrawSpriteScaled(entity->direction, scriptEng.operands[2], scriptEng.operands[3], -spriteFrame->pivotX, -spriteFrame->pivotY,4826entity->scale, entity->scale, spriteFrame->width, spriteFrame->height, spriteFrame->sprX, spriteFrame->sprY,4827scriptInfo->spriteSheetID);4828break;4829case FX_ROTATE:4830DrawSpriteRotated(entity->direction, scriptEng.operands[2], scriptEng.operands[3], -spriteFrame->pivotX, -spriteFrame->pivotY,4831spriteFrame->sprX, spriteFrame->sprY, spriteFrame->width, spriteFrame->height, entity->rotation,4832scriptInfo->spriteSheetID);4833break;4834case FX_ROTOZOOM:4835DrawSpriteRotozoom(entity->direction, scriptEng.operands[2], scriptEng.operands[3], -spriteFrame->pivotX,4836-spriteFrame->pivotY, spriteFrame->sprX, spriteFrame->sprY, spriteFrame->width, spriteFrame->height,4837entity->rotation, entity->scale, scriptInfo->spriteSheetID);4838break;4839case FX_INK:4840switch (entity->inkEffect) {4841case INK_NONE:4842DrawSprite(scriptEng.operands[2] + spriteFrame->pivotX, scriptEng.operands[3] + spriteFrame->pivotY,4843spriteFrame->width, spriteFrame->height, spriteFrame->sprX, spriteFrame->sprY, scriptInfo->spriteSheetID);4844break;4845case INK_BLEND:4846DrawBlendedSprite(scriptEng.operands[2] + spriteFrame->pivotX, scriptEng.operands[3] + spriteFrame->pivotY,4847spriteFrame->width, spriteFrame->height, spriteFrame->sprX, spriteFrame->sprY,4848scriptInfo->spriteSheetID);4849break;4850case INK_ALPHA:4851DrawAlphaBlendedSprite(scriptEng.operands[2] + spriteFrame->pivotX, scriptEng.operands[3] + spriteFrame->pivotY,4852spriteFrame->width, spriteFrame->height, spriteFrame->sprX, spriteFrame->sprY, entity->alpha,4853scriptInfo->spriteSheetID);4854break;4855case INK_ADD:4856DrawAdditiveBlendedSprite(scriptEng.operands[2] + spriteFrame->pivotX, scriptEng.operands[3] + spriteFrame->pivotY,4857spriteFrame->width, spriteFrame->height, spriteFrame->sprX, spriteFrame->sprY,4858entity->alpha, scriptInfo->spriteSheetID);4859break;4860case INK_SUB:4861DrawSubtractiveBlendedSprite(scriptEng.operands[2] + spriteFrame->pivotX, scriptEng.operands[3] + spriteFrame->pivotY,4862spriteFrame->width, spriteFrame->height, spriteFrame->sprX, spriteFrame->sprY,4863entity->alpha, scriptInfo->spriteSheetID);4864break;4865}4866break;4867case FX_TINT:4868if (entity->inkEffect == INK_ALPHA) {4869DrawScaledTintMask(entity->direction, scriptEng.operands[2], scriptEng.operands[3], -spriteFrame->pivotX,4870-spriteFrame->pivotY, entity->scale, entity->scale, spriteFrame->width, spriteFrame->height,4871spriteFrame->sprX, spriteFrame->sprY, scriptInfo->spriteSheetID);4872}4873else {4874DrawSpriteScaled(entity->direction, scriptEng.operands[2], scriptEng.operands[3], -spriteFrame->pivotX,4875-spriteFrame->pivotY, entity->scale, entity->scale, spriteFrame->width, spriteFrame->height,4876spriteFrame->sprX, spriteFrame->sprY, scriptInfo->spriteSheetID);4877}4878break;4879case FX_FLIP:4880switch (entity->direction) {4881default:4882case FLIP_NONE:4883DrawSpriteFlipped(scriptEng.operands[2] + spriteFrame->pivotX, scriptEng.operands[3] + spriteFrame->pivotY,4884spriteFrame->width, spriteFrame->height, spriteFrame->sprX, spriteFrame->sprY, FLIP_NONE,4885scriptInfo->spriteSheetID);4886break;4887case FLIP_X:4888DrawSpriteFlipped(scriptEng.operands[2] - spriteFrame->width - spriteFrame->pivotX,4889scriptEng.operands[3] + spriteFrame->pivotY, spriteFrame->width, spriteFrame->height,4890spriteFrame->sprX, spriteFrame->sprY, FLIP_X, scriptInfo->spriteSheetID);4891break;4892case FLIP_Y:4893DrawSpriteFlipped(scriptEng.operands[2] + spriteFrame->pivotX,4894scriptEng.operands[3] - spriteFrame->height - spriteFrame->pivotY, spriteFrame->width,4895spriteFrame->height, spriteFrame->sprX, spriteFrame->sprY, FLIP_Y, scriptInfo->spriteSheetID);4896break;4897case FLIP_XY:4898DrawSpriteFlipped(scriptEng.operands[2] - spriteFrame->width - spriteFrame->pivotX,4899scriptEng.operands[3] - spriteFrame->height - spriteFrame->pivotY, spriteFrame->width,4900spriteFrame->height, spriteFrame->sprX, spriteFrame->sprY, FLIP_XY, scriptInfo->spriteSheetID);4901break;4902}4903break;4904}4905break;4906case FUNC_LOADANIMATION:4907opcodeSize = 0;4908scriptInfo->animFile = AddAnimationFile(scriptText);4909break;4910case FUNC_SETUPMENU: {4911opcodeSize = 0;4912TextMenu *menu = &gameMenu[scriptEng.operands[0]];4913SetupTextMenu(menu, scriptEng.operands[1]);4914menu->selectionCount = scriptEng.operands[2];4915menu->alignment = scriptEng.operands[3];4916break;4917}4918case FUNC_ADDMENUENTRY: {4919opcodeSize = 0;4920TextMenu *menu = &gameMenu[scriptEng.operands[0]];4921menu->entryHighlight[menu->rowCount] = scriptEng.operands[2];4922AddTextMenuEntry(menu, scriptText);4923break;4924}4925case FUNC_EDITMENUENTRY: {4926opcodeSize = 0;4927TextMenu *menu = &gameMenu[scriptEng.operands[0]];4928EditTextMenuEntry(menu, scriptText, scriptEng.operands[2]);4929menu->entryHighlight[scriptEng.operands[2]] = scriptEng.operands[3];4930break;4931}4932case FUNC_LOADSTAGE:4933opcodeSize = 0;4934stageMode = STAGEMODE_LOAD;4935break;4936case FUNC_DRAWRECT:4937opcodeSize = 0;4938DrawRectangle(scriptEng.operands[0], scriptEng.operands[1], scriptEng.operands[2], scriptEng.operands[3], scriptEng.operands[4],4939scriptEng.operands[5], scriptEng.operands[6], scriptEng.operands[7]);4940break;4941case FUNC_RESETOBJECTENTITY: {4942opcodeSize = 0;4943Entity *newEnt = &objectEntityList[scriptEng.operands[0]];4944memset(newEnt, 0, sizeof(Entity));4945newEnt->type = scriptEng.operands[1];4946newEnt->propertyValue = scriptEng.operands[2];4947newEnt->xpos = scriptEng.operands[3];4948newEnt->ypos = scriptEng.operands[4];4949newEnt->direction = FLIP_NONE;4950newEnt->priority = PRIORITY_BOUNDS;4951newEnt->drawOrder = 3;4952newEnt->scale = 512;4953newEnt->inkEffect = INK_NONE;4954newEnt->objectInteractions = true;4955newEnt->visible = true;4956newEnt->tileCollisions = true;4957break;4958}4959case FUNC_BOXCOLLISIONTEST:4960opcodeSize = 0;4961switch (scriptEng.operands[0]) {4962default: break;4963case C_TOUCH:4964TouchCollision(&objectEntityList[scriptEng.operands[1]], scriptEng.operands[2], scriptEng.operands[3], scriptEng.operands[4],4965scriptEng.operands[5], &objectEntityList[scriptEng.operands[6]], scriptEng.operands[7], scriptEng.operands[8],4966scriptEng.operands[9], scriptEng.operands[10]);4967break;4968case C_SOLID:4969BoxCollision(&objectEntityList[scriptEng.operands[1]], scriptEng.operands[2], scriptEng.operands[3], scriptEng.operands[4],4970scriptEng.operands[5], &objectEntityList[scriptEng.operands[6]], scriptEng.operands[7], scriptEng.operands[8],4971scriptEng.operands[9], scriptEng.operands[10]);4972break;4973case C_SOLID2:4974BoxCollision2(&objectEntityList[scriptEng.operands[1]], scriptEng.operands[2], scriptEng.operands[3], scriptEng.operands[4],4975scriptEng.operands[5], &objectEntityList[scriptEng.operands[6]], scriptEng.operands[7], scriptEng.operands[8],4976scriptEng.operands[9], scriptEng.operands[10]);4977break;4978case C_PLATFORM:4979PlatformCollision(&objectEntityList[scriptEng.operands[1]], scriptEng.operands[2], scriptEng.operands[3],4980scriptEng.operands[4], scriptEng.operands[5], &objectEntityList[scriptEng.operands[6]],4981scriptEng.operands[7], scriptEng.operands[8], scriptEng.operands[9], scriptEng.operands[10]);4982break;4983}4984break;4985case FUNC_CREATETEMPOBJECT: {4986opcodeSize = 0;4987if (objectEntityList[scriptEng.arrayPosition[8]].type > OBJ_TYPE_BLANKOBJECT && ++scriptEng.arrayPosition[8] == ENTITY_COUNT)4988scriptEng.arrayPosition[8] = TEMPENTITY_START;4989Entity *temp = &objectEntityList[scriptEng.arrayPosition[8]];4990memset(temp, 0, sizeof(Entity));4991temp->type = scriptEng.operands[0];4992temp->propertyValue = scriptEng.operands[1];4993temp->xpos = scriptEng.operands[2];4994temp->ypos = scriptEng.operands[3];4995temp->direction = FLIP_NONE;4996temp->priority = PRIORITY_ACTIVE;4997temp->drawOrder = 3;4998temp->scale = 512;4999temp->inkEffect = INK_NONE;5000temp->objectInteractions = true;5001temp->visible = true;5002temp->tileCollisions = true;5003break;5004}5005case FUNC_PROCESSOBJECTMOVEMENT:5006opcodeSize = 0;5007if (entity->tileCollisions) {5008ProcessTileCollisions(entity);5009}5010else {5011entity->xpos += entity->xvel;5012entity->ypos += entity->yvel;5013}5014break;5015case FUNC_PROCESSOBJECTCONTROL:5016opcodeSize = 0;5017ProcessObjectControl(entity);5018break;5019case FUNC_PROCESSANIMATION:5020opcodeSize = 0;5021ProcessObjectAnimation(scriptInfo, entity);5022break;5023case FUNC_DRAWOBJECTANIMATION:5024opcodeSize = 0;5025if (entity->visible)5026DrawObjectAnimation(scriptInfo, entity, (entity->xpos >> 16) - xScrollOffset, (entity->ypos >> 16) - yScrollOffset);5027break;5028case FUNC_SETMUSICTRACK:5029opcodeSize = 0;5030if (scriptEng.operands[2] <= 1)5031SetMusicTrack(scriptText, scriptEng.operands[1], scriptEng.operands[2], 0);5032else5033SetMusicTrack(scriptText, scriptEng.operands[1], true, scriptEng.operands[2]);5034break;5035case FUNC_PLAYMUSIC:5036opcodeSize = 0;5037PlayMusic(scriptEng.operands[0], 0);5038break;5039case FUNC_STOPMUSIC:5040opcodeSize = 0;5041StopMusic(true);5042break;5043case FUNC_PAUSEMUSIC:5044opcodeSize = 0;5045PauseSound();5046break;5047case FUNC_RESUMEMUSIC:5048opcodeSize = 0;5049ResumeSound();5050break;5051case FUNC_SWAPMUSICTRACK:5052opcodeSize = 0;5053if (scriptEng.operands[2] <= 1)5054SwapMusicTrack(scriptText, scriptEng.operands[1], 0, scriptEng.operands[3]);5055else5056SwapMusicTrack(scriptText, scriptEng.operands[1], scriptEng.operands[2], scriptEng.operands[3]);5057break;5058case FUNC_PLAYSFX:5059opcodeSize = 0;5060PlaySfx(scriptEng.operands[0], scriptEng.operands[1]);5061break;5062case FUNC_STOPSFX:5063opcodeSize = 0;5064StopSfx(scriptEng.operands[0]);5065break;5066case FUNC_SETSFXATTRIBUTES:5067opcodeSize = 0;5068SetSfxAttributes(scriptEng.operands[0], scriptEng.operands[1], scriptEng.operands[2]);5069break;5070case FUNC_OBJECTTILECOLLISION:5071opcodeSize = 0;5072switch (scriptEng.operands[0]) {5073default: break;5074case CSIDE_FLOOR: ObjectFloorCollision(scriptEng.operands[1], scriptEng.operands[2], scriptEng.operands[3]); break;5075case CSIDE_LWALL: ObjectLWallCollision(scriptEng.operands[1], scriptEng.operands[2], scriptEng.operands[3]); break;5076case CSIDE_RWALL: ObjectRWallCollision(scriptEng.operands[1] - 1, scriptEng.operands[2], scriptEng.operands[3]); break;5077case CSIDE_ROOF: ObjectRoofCollision(scriptEng.operands[1], scriptEng.operands[2] - 1, scriptEng.operands[3]); break;5078#if RETRO_REV035079// Yes, the right side also calls for LWall5080case CSIDE_LENTITY: ObjectLWallCollision(scriptEng.operands[2], 0, objectEntityList[scriptEng.operands[1]].collisionPlane); break;5081case CSIDE_RENTITY: ObjectLWallCollision(scriptEng.operands[2] - 1, 0, objectEntityList[scriptEng.operands[1]].collisionPlane); break;5082#endif5083}5084break;5085case FUNC_OBJECTTILEGRIP:5086opcodeSize = 0;5087switch (scriptEng.operands[0]) {5088default: break;5089case CSIDE_FLOOR: ObjectFloorGrip(scriptEng.operands[1], scriptEng.operands[2], scriptEng.operands[3]); break;5090case CSIDE_LWALL: ObjectLWallGrip(scriptEng.operands[1], scriptEng.operands[2], scriptEng.operands[3]); break;5091case CSIDE_RWALL: ObjectRWallGrip(scriptEng.operands[1] - 1, scriptEng.operands[2], scriptEng.operands[3]); break;5092case CSIDE_ROOF: ObjectRoofGrip(scriptEng.operands[1], scriptEng.operands[2] - 1, scriptEng.operands[3]); break;5093#if RETRO_REV035094case CSIDE_LENTITY: ObjectLEntityGrip(scriptEng.operands[1], scriptEng.operands[2], scriptEng.operands[3]); break;5095case CSIDE_RENTITY: ObjectREntityGrip(scriptEng.operands[1], scriptEng.operands[2], scriptEng.operands[3]); break;5096#endif5097}5098break;5099case FUNC_NOT: scriptEng.operands[0] = ~scriptEng.operands[0]; break;5100case FUNC_DRAW3DSCENE:5101opcodeSize = 0;5102TransformVertexBuffer();5103Sort3DDrawList();5104Draw3DScene(scriptInfo->spriteSheetID);5105break;5106case FUNC_SETIDENTITYMATRIX:5107opcodeSize = 0;5108switch (scriptEng.operands[0]) {5109case MAT_WORLD: SetIdentityMatrix(&matWorld); break;5110case MAT_VIEW: SetIdentityMatrix(&matView); break;5111case MAT_TEMP: SetIdentityMatrix(&matTemp); break;5112}5113break;5114case FUNC_MATRIXMULTIPLY:5115opcodeSize = 0;5116switch (scriptEng.operands[0]) {5117case MAT_WORLD:5118switch (scriptEng.operands[1]) {5119case MAT_WORLD: MatrixMultiply(&matWorld, &matWorld); break;5120case MAT_VIEW: MatrixMultiply(&matWorld, &matView); break;5121case MAT_TEMP: MatrixMultiply(&matWorld, &matTemp); break;5122}5123break;5124case MAT_VIEW:5125switch (scriptEng.operands[1]) {5126case MAT_WORLD: MatrixMultiply(&matView, &matWorld); break;5127case MAT_VIEW: MatrixMultiply(&matView, &matView); break;5128case MAT_TEMP: MatrixMultiply(&matView, &matTemp); break;5129}5130break;5131case MAT_TEMP:5132switch (scriptEng.operands[1]) {5133case MAT_WORLD: MatrixMultiply(&matTemp, &matWorld); break;5134case MAT_VIEW: MatrixMultiply(&matTemp, &matView); break;5135case MAT_TEMP: MatrixMultiply(&matTemp, &matTemp); break;5136}5137break;5138}5139break;5140case FUNC_MATRIXTRANSLATEXYZ:5141opcodeSize = 0;5142switch (scriptEng.operands[0]) {5143case MAT_WORLD: MatrixTranslateXYZ(&matWorld, scriptEng.operands[1], scriptEng.operands[2], scriptEng.operands[3]); break;5144case MAT_VIEW: MatrixTranslateXYZ(&matView, scriptEng.operands[1], scriptEng.operands[2], scriptEng.operands[3]); break;5145case MAT_TEMP: MatrixTranslateXYZ(&matTemp, scriptEng.operands[1], scriptEng.operands[2], scriptEng.operands[3]); break;5146}5147break;5148case FUNC_MATRIXSCALEXYZ:5149opcodeSize = 0;5150switch (scriptEng.operands[0]) {5151case MAT_WORLD: MatrixScaleXYZ(&matWorld, scriptEng.operands[1], scriptEng.operands[2], scriptEng.operands[3]); break;5152case MAT_VIEW: MatrixScaleXYZ(&matView, scriptEng.operands[1], scriptEng.operands[2], scriptEng.operands[3]); break;5153case MAT_TEMP: MatrixScaleXYZ(&matTemp, scriptEng.operands[1], scriptEng.operands[2], scriptEng.operands[3]); break;5154}5155break;5156case FUNC_MATRIXROTATEX:5157opcodeSize = 0;5158switch (scriptEng.operands[0]) {5159case MAT_WORLD: MatrixRotateX(&matWorld, scriptEng.operands[1]); break;5160case MAT_VIEW: MatrixRotateX(&matView, scriptEng.operands[1]); break;5161case MAT_TEMP: MatrixRotateX(&matTemp, scriptEng.operands[1]); break;5162}5163break;5164case FUNC_MATRIXROTATEY:5165opcodeSize = 0;5166switch (scriptEng.operands[0]) {5167case MAT_WORLD: MatrixRotateY(&matWorld, scriptEng.operands[1]); break;5168case MAT_VIEW: MatrixRotateY(&matView, scriptEng.operands[1]); break;5169case MAT_TEMP: MatrixRotateY(&matTemp, scriptEng.operands[1]); break;5170}5171break;5172case FUNC_MATRIXROTATEZ:5173opcodeSize = 0;5174switch (scriptEng.operands[0]) {5175case MAT_WORLD: MatrixRotateZ(&matWorld, scriptEng.operands[1]); break;5176case MAT_VIEW: MatrixRotateZ(&matView, scriptEng.operands[1]); break;5177case MAT_TEMP: MatrixRotateZ(&matTemp, scriptEng.operands[1]); break;5178}5179break;5180case FUNC_MATRIXROTATEXYZ:5181opcodeSize = 0;5182switch (scriptEng.operands[0]) {5183case MAT_WORLD: MatrixRotateXYZ(&matWorld, scriptEng.operands[1], scriptEng.operands[2], scriptEng.operands[3]); break;5184case MAT_VIEW: MatrixRotateXYZ(&matView, scriptEng.operands[1], scriptEng.operands[2], scriptEng.operands[3]); break;5185case MAT_TEMP: MatrixRotateXYZ(&matTemp, scriptEng.operands[1], scriptEng.operands[2], scriptEng.operands[3]); break;5186}5187break;5188#if !RETRO_REV005189case FUNC_MATRIXINVERSE:5190opcodeSize = 0;5191switch (scriptEng.operands[0]) {5192case MAT_WORLD: MatrixInverse(&matWorld); break;5193case MAT_VIEW: MatrixInverse(&matView); break;5194case MAT_TEMP: MatrixInverse(&matTemp); break;5195}5196break;5197#endif5198case FUNC_TRANSFORMVERTICES:5199opcodeSize = 0;5200switch (scriptEng.operands[0]) {5201case MAT_WORLD: TransformVertices(&matWorld, scriptEng.operands[1], scriptEng.operands[2]); break;5202case MAT_VIEW: TransformVertices(&matView, scriptEng.operands[1], scriptEng.operands[2]); break;5203case MAT_TEMP: TransformVertices(&matTemp, scriptEng.operands[1], scriptEng.operands[2]); break;5204}5205break;5206case FUNC_CALLFUNCTION: {5207opcodeSize = 0;5208functionStack[functionStackPos++] = scriptCodePtr;5209functionStack[functionStackPos++] = jumpTableStart;5210functionStack[functionStackPos++] = scriptCodeStart;5211scriptCodeStart = scriptFunctionList[scriptEng.operands[0]].ptr.scriptCodePtr;5212jumpTableStart = scriptFunctionList[scriptEng.operands[0]].ptr.jumpTablePtr;5213scriptCodePtr = scriptCodeStart;5214break;5215}5216case FUNC_RETURN:5217opcodeSize = 0;5218if (!functionStackPos) { // event, stop running5219running = false;5220}5221else { // function, jump out5222scriptCodeStart = functionStack[--functionStackPos];5223jumpTableStart = functionStack[--functionStackPos];5224scriptCodePtr = functionStack[--functionStackPos];5225}5226break;5227case FUNC_SETLAYERDEFORMATION:5228opcodeSize = 0;5229SetLayerDeformation(scriptEng.operands[0], scriptEng.operands[1], scriptEng.operands[2], scriptEng.operands[3], scriptEng.operands[4],5230scriptEng.operands[5]);5231break;5232case FUNC_CHECKTOUCHRECT: opcodeSize = 0; scriptEng.checkResult = -1;5233#if !RETRO_USE_ORIGINAL_CODE5234AddDebugHitbox(H_TYPE_FINGER, NULL, scriptEng.operands[0], scriptEng.operands[1], scriptEng.operands[2], scriptEng.operands[3]);5235#endif5236for (int f = 0; f < touches; ++f) {5237if (touchDown[f] && touchX[f] > scriptEng.operands[0] && touchX[f] < scriptEng.operands[2] && touchY[f] > scriptEng.operands[1]5238&& touchY[f] < scriptEng.operands[3]) {5239scriptEng.checkResult = f;5240}5241}5242break;5243case FUNC_GETTILELAYERENTRY:5244scriptEng.operands[0] = stageLayouts[scriptEng.operands[1]].tiles[scriptEng.operands[2] + 0x100 * scriptEng.operands[3]];5245break;5246case FUNC_SETTILELAYERENTRY:5247stageLayouts[scriptEng.operands[1]].tiles[scriptEng.operands[2] + 0x100 * scriptEng.operands[3]] = scriptEng.operands[0];5248break;5249case FUNC_GETBIT: scriptEng.operands[0] = (scriptEng.operands[1] & (1 << scriptEng.operands[2])) >> scriptEng.operands[2]; break;5250case FUNC_SETBIT:5251if (scriptEng.operands[2] <= 0)5252scriptEng.operands[0] &= ~(1 << scriptEng.operands[1]);5253else5254scriptEng.operands[0] |= 1 << scriptEng.operands[1];5255break;5256case FUNC_CLEARDRAWLIST:5257opcodeSize = 0;5258drawListEntries[scriptEng.operands[0]].listSize = 0;5259break;5260case FUNC_ADDDRAWLISTENTITYREF: {5261opcodeSize = 0;5262drawListEntries[scriptEng.operands[0]].entityRefs[drawListEntries[scriptEng.operands[0]].listSize++] = scriptEng.operands[1];5263break;5264}5265case FUNC_GETDRAWLISTENTITYREF: scriptEng.operands[0] = drawListEntries[scriptEng.operands[1]].entityRefs[scriptEng.operands[2]]; break;5266case FUNC_SETDRAWLISTENTITYREF:5267opcodeSize = 0;5268drawListEntries[scriptEng.operands[1]].entityRefs[scriptEng.operands[2]] = scriptEng.operands[0];5269break;5270case FUNC_GET16X16TILEINFO: {5271scriptEng.operands[4] = scriptEng.operands[1] >> 7;5272scriptEng.operands[5] = scriptEng.operands[2] >> 7;5273scriptEng.operands[6] = stageLayouts[0].tiles[scriptEng.operands[4] + (scriptEng.operands[5] << 8)] << 6;5274scriptEng.operands[6] += ((scriptEng.operands[1] & 0x7F) >> 4) + 8 * ((scriptEng.operands[2] & 0x7F) >> 4);5275int index = tiles128x128.tileIndex[scriptEng.operands[6]];5276switch (scriptEng.operands[3]) {5277case TILEINFO_INDEX: scriptEng.operands[0] = tiles128x128.tileIndex[scriptEng.operands[6]]; break;5278case TILEINFO_DIRECTION: scriptEng.operands[0] = tiles128x128.direction[scriptEng.operands[6]]; break;5279case TILEINFO_VISUALPLANE: scriptEng.operands[0] = tiles128x128.visualPlane[scriptEng.operands[6]]; break;5280case TILEINFO_SOLIDITYA: scriptEng.operands[0] = tiles128x128.collisionFlags[0][scriptEng.operands[6]]; break;5281case TILEINFO_SOLIDITYB: scriptEng.operands[0] = tiles128x128.collisionFlags[1][scriptEng.operands[6]]; break;5282case TILEINFO_FLAGSA: scriptEng.operands[0] = collisionMasks[0].flags[index]; break;5283case TILEINFO_ANGLEA: scriptEng.operands[0] = collisionMasks[0].angles[index]; break;5284case TILEINFO_FLAGSB: scriptEng.operands[0] = collisionMasks[1].flags[index]; break;5285case TILEINFO_ANGLEB: scriptEng.operands[0] = collisionMasks[1].angles[index]; break;5286default: break;5287}5288break;5289}5290case FUNC_SET16X16TILEINFO: {5291scriptEng.operands[4] = scriptEng.operands[1] >> 7;5292scriptEng.operands[5] = scriptEng.operands[2] >> 7;5293scriptEng.operands[6] = stageLayouts[0].tiles[scriptEng.operands[4] + (scriptEng.operands[5] << 8)] << 6;5294scriptEng.operands[6] += ((scriptEng.operands[1] & 0x7F) >> 4) + 8 * ((scriptEng.operands[2] & 0x7F) >> 4);5295switch (scriptEng.operands[3]) {5296case TILEINFO_INDEX:5297tiles128x128.tileIndex[scriptEng.operands[6]] = scriptEng.operands[0];5298tiles128x128.gfxDataPos[scriptEng.operands[6]] = scriptEng.operands[0] << 8;5299break;5300case TILEINFO_DIRECTION: tiles128x128.direction[scriptEng.operands[6]] = scriptEng.operands[0]; break;5301case TILEINFO_VISUALPLANE: tiles128x128.visualPlane[scriptEng.operands[6]] = scriptEng.operands[0]; break;5302case TILEINFO_SOLIDITYA: tiles128x128.collisionFlags[0][scriptEng.operands[6]] = scriptEng.operands[0]; break;5303case TILEINFO_SOLIDITYB: tiles128x128.collisionFlags[1][scriptEng.operands[6]] = scriptEng.operands[0]; break;5304case TILEINFO_FLAGSA: collisionMasks[1].flags[tiles128x128.tileIndex[scriptEng.operands[6]]] = scriptEng.operands[0]; break;5305case TILEINFO_ANGLEA: collisionMasks[1].angles[tiles128x128.tileIndex[scriptEng.operands[6]]] = scriptEng.operands[0]; break;5306default: break;5307}5308break;5309}5310case FUNC_COPY16X16TILE:5311opcodeSize = 0;5312Copy16x16Tile(scriptEng.operands[0], scriptEng.operands[1]);5313break;5314case FUNC_GETANIMATIONBYNAME: {5315AnimationFile *animFile = scriptInfo->animFile;5316scriptEng.operands[0] = -1;5317int id = 0;5318while (scriptEng.operands[0] == -1) {5319SpriteAnimation *anim = &animationList[animFile->aniListOffset + id];5320if (StrComp(scriptText, anim->name))5321scriptEng.operands[0] = id;5322else if (++id == animFile->animCount)5323scriptEng.operands[0] = 0;5324}5325break;5326}5327case FUNC_READSAVERAM:5328opcodeSize = 0;5329scriptEng.checkResult = ReadSaveRAMData();5330break;5331case FUNC_WRITESAVERAM:5332opcodeSize = 0;5333scriptEng.checkResult = WriteSaveRAMData();5334break;5335#if !RETRO_REV025336case FUNC_LOADTEXTFONT: {5337opcodeSize = 0;5338LoadFontFile(scriptText);5339break;5340}5341#endif5342case FUNC_LOADTEXTFILE: {5343opcodeSize = 0;5344TextMenu *menu = &gameMenu[scriptEng.operands[0]];5345#if !RETRO_REV025346LoadTextFile(menu, scriptText, scriptEng.operands[2] != 0);5347#else5348LoadTextFile(menu, scriptText, false);5349#endif5350break;5351}5352case FUNC_GETTEXTINFO: {5353TextMenu *menu = &gameMenu[scriptEng.operands[1]];5354switch (scriptEng.operands[2]) {5355case TEXTINFO_TEXTDATA:5356scriptEng.operands[0] = menu->textData[menu->entryStart[scriptEng.operands[3]] + scriptEng.operands[4]];5357break;5358case TEXTINFO_TEXTSIZE: scriptEng.operands[0] = menu->entrySize[scriptEng.operands[3]]; break;5359case TEXTINFO_ROWCOUNT: scriptEng.operands[0] = menu->rowCount; break;5360}5361break;5362}5363#if !RETRO_REV025364case FUNC_DRAWTEXT: {5365opcodeSize = 0;5366textMenuSurfaceNo = scriptInfo->spriteSheetID;5367TextMenu *menu = &gameMenu[scriptEng.operands[0]];5368DrawBitmapText(menu, scriptEng.operands[1], scriptEng.operands[2], scriptEng.operands[3], scriptEng.operands[4],5369scriptEng.operands[5], scriptEng.operands[6]);5370break;5371}5372#endif5373case FUNC_GETVERSIONNUMBER: {5374opcodeSize = 0;5375TextMenu *menu = &gameMenu[scriptEng.operands[0]];5376menu->entryHighlight[menu->rowCount] = scriptEng.operands[1];5377AddTextMenuEntry(menu, Engine.gameVersion);5378break;5379}5380case FUNC_GETTABLEVALUE: {5381int arrPos = scriptEng.operands[1];5382if (arrPos >= 0) {5383int pos = scriptEng.operands[2];5384int arrSize = scriptCode[pos];5385if (arrPos < arrSize)5386scriptEng.operands[0] = scriptCode[pos + arrPos + 1];5387}5388break;5389}5390case FUNC_SETTABLEVALUE: {5391opcodeSize = 0;5392int arrPos = scriptEng.operands[1];5393if (arrPos >= 0) {5394int pos = scriptEng.operands[2];5395int arrSize = scriptCode[pos];5396if (arrPos < arrSize)5397scriptCode[pos + arrPos + 1] = scriptEng.operands[0];5398}5399break;5400}5401case FUNC_CHECKCURRENTSTAGEFOLDER:5402opcodeSize = 0;5403scriptEng.checkResult = StrComp(stageList[activeStageList][stageListPosition].folder, scriptText);5404#if RETRO_REV035405// Mission Mode stuff5406if (!scriptEng.checkResult) {5407int targetLength = strlen(stageList[activeStageList][stageListPosition].folder);5408int currentLength = strlen(scriptText);5409if (targetLength > currentLength) {5410scriptEng.checkResult =5411StrComp(&stageList[activeStageList][stageListPosition].folder[targetLength - currentLength], scriptText);5412}5413}5414#endif5415break;5416case FUNC_ABS: {5417scriptEng.operands[0] = abs(scriptEng.operands[0]);5418break;5419}5420case FUNC_CALLNATIVEFUNCTION:5421opcodeSize = 0;5422if (scriptEng.operands[0] >= 0 && scriptEng.operands[0] < NATIIVEFUNCTION_COUNT) {5423void (*func)(void) = (void (*)(void))nativeFunction[scriptEng.operands[0]];5424if (func)5425func();5426}5427break;5428case FUNC_CALLNATIVEFUNCTION2:5429if (scriptEng.operands[0] >= 0 && scriptEng.operands[0] < NATIIVEFUNCTION_COUNT) {5430if (StrLength(scriptText)) {5431void (*func)(int *, char *) = (void (*)(int *, char *))nativeFunction[scriptEng.operands[0]];5432if (func)5433func(&scriptEng.operands[2], scriptText);5434}5435else {5436void (*func)(int *, int *) = (void (*)(int *, int *))nativeFunction[scriptEng.operands[0]];5437if (func)5438func(&scriptEng.operands[1], &scriptEng.operands[2]);5439}5440}5441break;5442case FUNC_CALLNATIVEFUNCTION4:5443if (scriptEng.operands[0] >= 0 && scriptEng.operands[0] < NATIIVEFUNCTION_COUNT) {5444if (StrLength(scriptText)) {5445void (*func)(int *, char *, int *, int *) = (void (*)(int *, char *, int *, int *))nativeFunction[scriptEng.operands[0]];5446if (func)5447func(&scriptEng.operands[1], scriptText, &scriptEng.operands[3], &scriptEng.operands[4]);5448}5449else {5450void (*func)(int *, int *, int *, int *) = (void (*)(int *, int *, int *, int *))nativeFunction[scriptEng.operands[0]];5451if (func)5452func(&scriptEng.operands[1], &scriptEng.operands[2], &scriptEng.operands[3], &scriptEng.operands[4]);5453}5454}5455break;5456case FUNC_SETOBJECTRANGE: {5457// FUNCTION PARAMS:5458// scriptEng.operands[0] = range54595460opcodeSize = 0;5461int offset = (scriptEng.operands[0] >> 1) - SCREEN_CENTERX;5462OBJECT_BORDER_X1 = offset + 0x80;5463OBJECT_BORDER_X2 = scriptEng.operands[0] + 0x80 - offset;5464OBJECT_BORDER_X3 = offset + 0x20;5465OBJECT_BORDER_X4 = scriptEng.operands[0] + 0x20 - offset;5466break;5467}5468#if RETRO_REV025469case FUNC_GETOBJECTVALUE: {5470// FUNCTION PARAMS:5471// scriptEng.operands[0] = result5472// scriptEng.operands[1] = valueID5473// scriptEng.operands[2] = entitySlot54745475if (scriptEng.operands[1] < 48)5476scriptEng.operands[0] = objectEntityList[scriptEng.operands[2]].values[scriptEng.operands[1]];5477break;5478}5479case FUNC_SETOBJECTVALUE: {5480// FUNCTION PARAMS:5481// scriptEng.operands[0] = value5482// scriptEng.operands[1] = valueID5483// scriptEng.operands[2] = entitySlot54845485opcodeSize = 0;5486if (scriptEng.operands[1] < 48)5487objectEntityList[scriptEng.operands[2]].values[scriptEng.operands[1]] = scriptEng.operands[0];5488break;5489}5490case FUNC_COPYOBJECT: {5491// FUNCTION PARAMS:5492// scriptEng.operands[0] = destSlot5493// scriptEng.operands[1] = srcSlot5494// scriptEng.operands[2] = count54955496Entity *dstList = &objectEntityList[scriptEng.operands[0]];5497Entity *srcList = &objectEntityList[scriptEng.operands[1]];5498for (int i = 0; i < scriptEng.operands[2]; ++i) memcpy(&dstList[i], &srcList[i], sizeof(Entity));5499break;5500}5501#endif5502case FUNC_PRINT: {5503// FUNCTION PARAMS:5504// scriptEng.operands[0] = message (can be a regular value or a string depending on scriptEng.operands[1])5505// scriptEng.operands[1] = isInt5506// scriptEng.operands[2] = useEndLine55075508endLine = false;5509if (scriptEng.operands[1])5510PrintLog("%d", scriptEng.operands[0]);5511else5512PrintLog("%s", scriptText);55135514if (scriptEng.operands[2])5515PrintLog("\n");5516endLine = true;5517break;5518}55195520#if RETRO_REV035521// Extras for origins 2PVS,5522// most of these aren't (and won't be) implemented here because they rely on v5 tech that isn't part of the scope of this project5523case FUNC_CHECKCAMERAPROXIMITY:5524scriptEng.checkResult = false;55255526// FUNCTION PARAMS:5527// scriptEng.operands[0] = pos.x5528// scriptEng.operands[1] = pos.y5529// scriptEng.operands[2] = range.x5530// scriptEng.operands[3] = range.y5531//5532// FUNCTION NOTES:5533// - Sets scriptEng.checkResult55345535if (scriptEng.operands[2] > 0 && scriptEng.operands[3] > 0) {5536int sx = abs(scriptEng.operands[0] - cameraXPos);5537int sy = abs(scriptEng.operands[1] - cameraYPos);55385539if (sx < scriptEng.operands[2] && sy < scriptEng.operands[3]) {5540scriptEng.checkResult = true;5541break;5542}5543}5544else {5545if (scriptEng.operands[2] > 0) {5546int sx = abs(scriptEng.operands[0] - cameraXPos);55475548if (sx < scriptEng.operands[2]) {5549scriptEng.checkResult = true;5550break;5551}5552}5553else if (scriptEng.operands[3] > 0) {5554int sy = abs(scriptEng.operands[1] - cameraYPos);55555556if (sy < scriptEng.operands[3]) {5557scriptEng.checkResult = true;5558break;5559}5560}5561}5562break;55635564case FUNC_SETSCREENCOUNT:5565// FUNCTION PARAMS:5566// scriptEng.operands[0] = screenCount55675568break;55695570case FUNC_SETSCREENVERTICES:5571// FUNCTION PARAMS:5572// scriptEng.operands[0] = startVert2P_S15573// scriptEng.operands[1] = startVert2P_S25574// scriptEng.operands[2] = startVert3P_S15575// scriptEng.operands[3] = startVert3P_S25576// scriptEng.operands[4] = startVert3P_S355775578break;55795580case FUNC_GETINPUTDEVICEID:5581// FUNCTION PARAMS:5582// scriptEng.operands[0] = deviceID5583// scriptEng.operands[1] = inputSlot5584//5585// FUNCTION NOTES:5586// - Assigns the device's id to scriptEng.operands[0]55875588break;55895590case FUNC_GETFILTEREDINPUTDEVICEID:5591// FUNCTION PARAMS:5592// scriptEng.operands[0] = deviceID5593// scriptEng.operands[1] = confirmOnly5594// scriptEng.operands[2] = unassignedOnly5595// scriptEng.operands[3] = maxInactiveTimer5596//5597// FUNCTION NOTES:5598// - Assigns the filtered device's id to scriptEng.operands[0]55995600break;56015602case FUNC_GETINPUTDEVICETYPE:5603// FUNCTION PARAMS:5604// scriptEng.operands[0] = deviceType5605// scriptEng.operands[1] = deviceID5606//5607// FUNCTION NOTES:5608// - Assigns the device's type to scriptEng.operands[0]56095610break;56115612case FUNC_ISINPUTDEVICEASSIGNED:5613// FUNCTION PARAMS:5614// scriptEng.operands[0] = deviceID56155616break;56175618case FUNC_ASSIGNINPUTSLOTTODEVICE:5619// FUNCTION PARAMS:5620// scriptEng.operands[0] = inputSlot5621// scriptEng.operands[1] = deviceID56225623break;56245625case FUNC_ISSLOTASSIGNED:5626// FUNCTION PARAMS:5627// scriptEng.operands[0] = inputSlot5628//5629// FUNCTION NOTES:5630// - Sets scriptEng.checkResult56315632break;56335634case FUNC_RESETINPUTSLOTASSIGNMENTS:5635// FUNCTION PARAMS:5636// None56375638break;5639#endif5640}56415642// Set Values5643if (opcodeSize > 0)5644scriptCodePtr -= scriptCodePtr - scriptCodeOffset;5645for (int i = 0; i < opcodeSize; ++i) {5646int opcodeType = scriptCode[scriptCodePtr++];5647if (opcodeType == SCRIPTVAR_VAR) {5648int arrayVal = 0;5649switch (scriptCode[scriptCodePtr++]) { // variable5650case VARARR_NONE: arrayVal = objectEntityPos; break;56515652case VARARR_ARRAY:5653if (scriptCode[scriptCodePtr++] == 1)5654arrayVal = scriptEng.arrayPosition[scriptCode[scriptCodePtr++]];5655else5656arrayVal = scriptCode[scriptCodePtr++];5657break;56585659case VARARR_ENTNOPLUS1:5660if (scriptCode[scriptCodePtr++] == 1)5661arrayVal = objectEntityPos + scriptEng.arrayPosition[scriptCode[scriptCodePtr++]];5662else5663arrayVal = objectEntityPos + scriptCode[scriptCodePtr++];5664break;56655666case VARARR_ENTNOMINUS1:5667if (scriptCode[scriptCodePtr++] == 1)5668arrayVal = objectEntityPos - scriptEng.arrayPosition[scriptCode[scriptCodePtr++]];5669else5670arrayVal = objectEntityPos - scriptCode[scriptCodePtr++];5671break;56725673default: break;5674}56755676#if RETRO_REV03 && !RETRO_USE_ORIGINAL_CODE5677bool inputCheck = true; // Default to true for mobile bytecode5678// If we're using the scripts or an Origins datafile, check the array value5679if (forceUseScripts || Engine.usingOrigins)5680inputCheck = arrayVal <= 1;5681#endif56825683// Variables5684switch (scriptCode[scriptCodePtr++]) {5685default: break;5686case VAR_TEMP0: scriptEng.temp[0] = scriptEng.operands[i]; break;5687case VAR_TEMP1: scriptEng.temp[1] = scriptEng.operands[i]; break;5688case VAR_TEMP2: scriptEng.temp[2] = scriptEng.operands[i]; break;5689case VAR_TEMP3: scriptEng.temp[3] = scriptEng.operands[i]; break;5690case VAR_TEMP4: scriptEng.temp[4] = scriptEng.operands[i]; break;5691case VAR_TEMP5: scriptEng.temp[5] = scriptEng.operands[i]; break;5692case VAR_TEMP6: scriptEng.temp[6] = scriptEng.operands[i]; break;5693case VAR_TEMP7: scriptEng.temp[7] = scriptEng.operands[i]; break;5694case VAR_CHECKRESULT: scriptEng.checkResult = scriptEng.operands[i]; break;5695case VAR_ARRAYPOS0: scriptEng.arrayPosition[0] = scriptEng.operands[i]; break;5696case VAR_ARRAYPOS1: scriptEng.arrayPosition[1] = scriptEng.operands[i]; break;5697case VAR_ARRAYPOS2: scriptEng.arrayPosition[2] = scriptEng.operands[i]; break;5698case VAR_ARRAYPOS3: scriptEng.arrayPosition[3] = scriptEng.operands[i]; break;5699case VAR_ARRAYPOS4: scriptEng.arrayPosition[4] = scriptEng.operands[i]; break;5700case VAR_ARRAYPOS5: scriptEng.arrayPosition[5] = scriptEng.operands[i]; break;5701case VAR_ARRAYPOS6: scriptEng.arrayPosition[6] = scriptEng.operands[i]; break;5702case VAR_ARRAYPOS7: scriptEng.arrayPosition[7] = scriptEng.operands[i]; break;5703case VAR_GLOBAL: globalVariables[arrayVal] = scriptEng.operands[i]; break;5704case VAR_LOCAL: scriptCode[arrayVal] = scriptEng.operands[i]; break;5705case VAR_OBJECTENTITYPOS: break;5706case VAR_OBJECTGROUPID: {5707objectEntityList[arrayVal].groupID = scriptEng.operands[i];5708break;5709}5710case VAR_OBJECTTYPE: {5711objectEntityList[arrayVal].type = scriptEng.operands[i];5712break;5713}5714case VAR_OBJECTPROPERTYVALUE: {5715objectEntityList[arrayVal].propertyValue = scriptEng.operands[i];5716break;5717}5718case VAR_OBJECTXPOS: {5719objectEntityList[arrayVal].xpos = scriptEng.operands[i];5720break;5721}5722case VAR_OBJECTYPOS: {5723objectEntityList[arrayVal].ypos = scriptEng.operands[i];5724break;5725}5726case VAR_OBJECTIXPOS: {5727objectEntityList[arrayVal].xpos = scriptEng.operands[i] << 16;5728break;5729}5730case VAR_OBJECTIYPOS: {5731objectEntityList[arrayVal].ypos = scriptEng.operands[i] << 16;5732break;5733}5734case VAR_OBJECTXVEL: {5735objectEntityList[arrayVal].xvel = scriptEng.operands[i];5736break;5737}5738case VAR_OBJECTYVEL: {5739objectEntityList[arrayVal].yvel = scriptEng.operands[i];5740break;5741}5742case VAR_OBJECTSPEED: {5743objectEntityList[arrayVal].speed = scriptEng.operands[i];5744break;5745}5746case VAR_OBJECTSTATE: {5747objectEntityList[arrayVal].state = scriptEng.operands[i];5748break;5749}5750case VAR_OBJECTROTATION: {5751objectEntityList[arrayVal].rotation = scriptEng.operands[i];5752break;5753}5754case VAR_OBJECTSCALE: {5755objectEntityList[arrayVal].scale = scriptEng.operands[i];5756break;5757}5758case VAR_OBJECTPRIORITY: {5759objectEntityList[arrayVal].priority = scriptEng.operands[i];5760break;5761}5762case VAR_OBJECTDRAWORDER: {5763objectEntityList[arrayVal].drawOrder = scriptEng.operands[i];5764break;5765}5766case VAR_OBJECTDIRECTION: {5767objectEntityList[arrayVal].direction = scriptEng.operands[i];5768break;5769}5770case VAR_OBJECTINKEFFECT: {5771objectEntityList[arrayVal].inkEffect = scriptEng.operands[i];5772break;5773}5774case VAR_OBJECTALPHA: {5775objectEntityList[arrayVal].alpha = scriptEng.operands[i];5776break;5777}5778case VAR_OBJECTFRAME: {5779objectEntityList[arrayVal].frame = scriptEng.operands[i];5780break;5781}5782case VAR_OBJECTANIMATION: {5783objectEntityList[arrayVal].animation = scriptEng.operands[i];5784break;5785}5786case VAR_OBJECTPREVANIMATION: {5787objectEntityList[arrayVal].prevAnimation = scriptEng.operands[i];5788break;5789}5790case VAR_OBJECTANIMATIONSPEED: {5791objectEntityList[arrayVal].animationSpeed = scriptEng.operands[i];5792break;5793}5794case VAR_OBJECTANIMATIONTIMER: {5795objectEntityList[arrayVal].animationTimer = scriptEng.operands[i];5796break;5797}5798case VAR_OBJECTANGLE: {5799objectEntityList[arrayVal].angle = scriptEng.operands[i];5800break;5801}5802case VAR_OBJECTLOOKPOSX: {5803objectEntityList[arrayVal].lookPosX = scriptEng.operands[i];5804break;5805}5806case VAR_OBJECTLOOKPOSY: {5807objectEntityList[arrayVal].lookPosY = scriptEng.operands[i];5808break;5809}5810case VAR_OBJECTCOLLISIONMODE: {5811objectEntityList[arrayVal].collisionMode = scriptEng.operands[i];5812break;5813}5814case VAR_OBJECTCOLLISIONPLANE: {5815objectEntityList[arrayVal].collisionPlane = scriptEng.operands[i];5816break;5817}5818case VAR_OBJECTCONTROLMODE: {5819objectEntityList[arrayVal].controlMode = scriptEng.operands[i];5820break;5821}5822case VAR_OBJECTCONTROLLOCK: {5823objectEntityList[arrayVal].controlLock = scriptEng.operands[i];5824break;5825}5826case VAR_OBJECTPUSHING: {5827objectEntityList[arrayVal].pushing = scriptEng.operands[i];5828break;5829}5830case VAR_OBJECTVISIBLE: {5831objectEntityList[arrayVal].visible = scriptEng.operands[i];5832break;5833}5834case VAR_OBJECTTILECOLLISIONS: {5835objectEntityList[arrayVal].tileCollisions = scriptEng.operands[i];5836break;5837}5838case VAR_OBJECTINTERACTION: {5839objectEntityList[arrayVal].objectInteractions = scriptEng.operands[i];5840break;5841}5842case VAR_OBJECTGRAVITY: {5843objectEntityList[arrayVal].gravity = scriptEng.operands[i];5844break;5845}5846case VAR_OBJECTUP: {5847objectEntityList[arrayVal].up = scriptEng.operands[i];5848break;5849}5850case VAR_OBJECTDOWN: {5851objectEntityList[arrayVal].down = scriptEng.operands[i];5852break;5853}5854case VAR_OBJECTLEFT: {5855objectEntityList[arrayVal].left = scriptEng.operands[i];5856break;5857}5858case VAR_OBJECTRIGHT: {5859objectEntityList[arrayVal].right = scriptEng.operands[i];5860break;5861}5862case VAR_OBJECTJUMPPRESS: {5863objectEntityList[arrayVal].jumpPress = scriptEng.operands[i];5864break;5865}5866case VAR_OBJECTJUMPHOLD: {5867objectEntityList[arrayVal].jumpHold = scriptEng.operands[i];5868break;5869}5870case VAR_OBJECTSCROLLTRACKING: {5871objectEntityList[arrayVal].scrollTracking = scriptEng.operands[i];5872break;5873}5874case VAR_OBJECTFLOORSENSORL: {5875objectEntityList[arrayVal].floorSensors[0] = scriptEng.operands[i];5876break;5877}5878case VAR_OBJECTFLOORSENSORC: {5879objectEntityList[arrayVal].floorSensors[1] = scriptEng.operands[i];5880break;5881}5882case VAR_OBJECTFLOORSENSORR: {5883objectEntityList[arrayVal].floorSensors[2] = scriptEng.operands[i];5884break;5885}5886#if !RETRO_REV005887case VAR_OBJECTFLOORSENSORLC: {5888objectEntityList[arrayVal].floorSensors[3] = scriptEng.operands[i];5889break;5890}5891case VAR_OBJECTFLOORSENSORRC: {5892objectEntityList[arrayVal].floorSensors[4] = scriptEng.operands[i];5893break;5894}5895#endif5896case VAR_OBJECTCOLLISIONLEFT: {5897break;5898}5899case VAR_OBJECTCOLLISIONTOP: {5900break;5901}5902case VAR_OBJECTCOLLISIONRIGHT: {5903break;5904}5905case VAR_OBJECTCOLLISIONBOTTOM: {5906break;5907}5908case VAR_OBJECTOUTOFBOUNDS: {5909break;5910}5911case VAR_OBJECTSPRITESHEET: {5912objectScriptList[objectEntityList[arrayVal].type].spriteSheetID = scriptEng.operands[i];5913break;5914}5915case VAR_OBJECTVALUE0: {5916objectEntityList[arrayVal].values[0] = scriptEng.operands[i];5917break;5918}5919case VAR_OBJECTVALUE1: {5920objectEntityList[arrayVal].values[1] = scriptEng.operands[i];5921break;5922}5923case VAR_OBJECTVALUE2: {5924objectEntityList[arrayVal].values[2] = scriptEng.operands[i];5925break;5926}5927case VAR_OBJECTVALUE3: {5928objectEntityList[arrayVal].values[3] = scriptEng.operands[i];5929break;5930}5931case VAR_OBJECTVALUE4: {5932objectEntityList[arrayVal].values[4] = scriptEng.operands[i];5933break;5934}5935case VAR_OBJECTVALUE5: {5936objectEntityList[arrayVal].values[5] = scriptEng.operands[i];5937break;5938}5939case VAR_OBJECTVALUE6: {5940objectEntityList[arrayVal].values[6] = scriptEng.operands[i];5941break;5942}5943case VAR_OBJECTVALUE7: {5944objectEntityList[arrayVal].values[7] = scriptEng.operands[i];5945break;5946}5947case VAR_OBJECTVALUE8: {5948objectEntityList[arrayVal].values[8] = scriptEng.operands[i];5949break;5950}5951case VAR_OBJECTVALUE9: {5952objectEntityList[arrayVal].values[9] = scriptEng.operands[i];5953break;5954}5955case VAR_OBJECTVALUE10: {5956objectEntityList[arrayVal].values[10] = scriptEng.operands[i];5957break;5958}5959case VAR_OBJECTVALUE11: {5960objectEntityList[arrayVal].values[11] = scriptEng.operands[i];5961break;5962}5963case VAR_OBJECTVALUE12: {5964objectEntityList[arrayVal].values[12] = scriptEng.operands[i];5965break;5966}5967case VAR_OBJECTVALUE13: {5968objectEntityList[arrayVal].values[13] = scriptEng.operands[i];5969break;5970}5971case VAR_OBJECTVALUE14: {5972objectEntityList[arrayVal].values[14] = scriptEng.operands[i];5973break;5974}5975case VAR_OBJECTVALUE15: {5976objectEntityList[arrayVal].values[15] = scriptEng.operands[i];5977break;5978}5979case VAR_OBJECTVALUE16: {5980objectEntityList[arrayVal].values[16] = scriptEng.operands[i];5981break;5982}5983case VAR_OBJECTVALUE17: {5984objectEntityList[arrayVal].values[17] = scriptEng.operands[i];5985break;5986}5987case VAR_OBJECTVALUE18: {5988objectEntityList[arrayVal].values[18] = scriptEng.operands[i];5989break;5990}5991case VAR_OBJECTVALUE19: {5992objectEntityList[arrayVal].values[19] = scriptEng.operands[i];5993break;5994}5995case VAR_OBJECTVALUE20: {5996objectEntityList[arrayVal].values[20] = scriptEng.operands[i];5997break;5998}5999case VAR_OBJECTVALUE21: {6000objectEntityList[arrayVal].values[21] = scriptEng.operands[i];6001break;6002}6003case VAR_OBJECTVALUE22: {6004objectEntityList[arrayVal].values[22] = scriptEng.operands[i];6005break;6006}6007case VAR_OBJECTVALUE23: {6008objectEntityList[arrayVal].values[23] = scriptEng.operands[i];6009break;6010}6011case VAR_OBJECTVALUE24: {6012objectEntityList[arrayVal].values[24] = scriptEng.operands[i];6013break;6014}6015case VAR_OBJECTVALUE25: {6016objectEntityList[arrayVal].values[25] = scriptEng.operands[i];6017break;6018}6019case VAR_OBJECTVALUE26: {6020objectEntityList[arrayVal].values[26] = scriptEng.operands[i];6021break;6022}6023case VAR_OBJECTVALUE27: {6024objectEntityList[arrayVal].values[27] = scriptEng.operands[i];6025break;6026}6027case VAR_OBJECTVALUE28: {6028objectEntityList[arrayVal].values[28] = scriptEng.operands[i];6029break;6030}6031case VAR_OBJECTVALUE29: {6032objectEntityList[arrayVal].values[29] = scriptEng.operands[i];6033break;6034}6035case VAR_OBJECTVALUE30: {6036objectEntityList[arrayVal].values[30] = scriptEng.operands[i];6037break;6038}6039case VAR_OBJECTVALUE31: {6040objectEntityList[arrayVal].values[31] = scriptEng.operands[i];6041break;6042}6043case VAR_OBJECTVALUE32: {6044objectEntityList[arrayVal].values[32] = scriptEng.operands[i];6045break;6046}6047case VAR_OBJECTVALUE33: {6048objectEntityList[arrayVal].values[33] = scriptEng.operands[i];6049break;6050}6051case VAR_OBJECTVALUE34: {6052objectEntityList[arrayVal].values[34] = scriptEng.operands[i];6053break;6054}6055case VAR_OBJECTVALUE35: {6056objectEntityList[arrayVal].values[35] = scriptEng.operands[i];6057break;6058}6059case VAR_OBJECTVALUE36: {6060objectEntityList[arrayVal].values[36] = scriptEng.operands[i];6061break;6062}6063case VAR_OBJECTVALUE37: {6064objectEntityList[arrayVal].values[37] = scriptEng.operands[i];6065break;6066}6067case VAR_OBJECTVALUE38: {6068objectEntityList[arrayVal].values[38] = scriptEng.operands[i];6069break;6070}6071case VAR_OBJECTVALUE39: {6072objectEntityList[arrayVal].values[39] = scriptEng.operands[i];6073break;6074}6075case VAR_OBJECTVALUE40: {6076objectEntityList[arrayVal].values[40] = scriptEng.operands[i];6077break;6078}6079case VAR_OBJECTVALUE41: {6080objectEntityList[arrayVal].values[41] = scriptEng.operands[i];6081break;6082}6083case VAR_OBJECTVALUE42: {6084objectEntityList[arrayVal].values[42] = scriptEng.operands[i];6085break;6086}6087case VAR_OBJECTVALUE43: {6088objectEntityList[arrayVal].values[43] = scriptEng.operands[i];6089break;6090}6091case VAR_OBJECTVALUE44: {6092objectEntityList[arrayVal].values[44] = scriptEng.operands[i];6093break;6094}6095case VAR_OBJECTVALUE45: {6096objectEntityList[arrayVal].values[45] = scriptEng.operands[i];6097break;6098}6099case VAR_OBJECTVALUE46: {6100objectEntityList[arrayVal].values[46] = scriptEng.operands[i];6101break;6102}6103case VAR_OBJECTVALUE47: {6104objectEntityList[arrayVal].values[47] = scriptEng.operands[i];6105break;6106}6107case VAR_STAGESTATE: stageMode = scriptEng.operands[i]; break;6108case VAR_STAGEACTIVELIST:6109#if RETRO_REV03 && !RETRO_USE_ORIGINAL_CODE6110// BONUS_STAGE and SPECIAL_STAGE are swapped on Origins bytecode, so correct it here6111if (Engine.usingOrigins && !forceUseScripts) {6112int listSlots[] = { 0, 1, 3, 2 };61136114int listID = scriptEng.operands[i];6115if (listID <= 3)6116listID = listSlots[listID];6117else6118listID = 2; // BONUS_STAGE61196120activeStageList = listID;6121}6122else6123activeStageList = scriptEng.operands[i];6124#else6125activeStageList = scriptEng.operands[i];6126#endif6127break;6128case VAR_STAGELISTPOS: stageListPosition = scriptEng.operands[i]; break;6129case VAR_STAGETIMEENABLED: timeEnabled = scriptEng.operands[i]; break;6130case VAR_STAGEMILLISECONDS: stageMilliseconds = scriptEng.operands[i]; break;6131case VAR_STAGESECONDS: stageSeconds = scriptEng.operands[i]; break;6132case VAR_STAGEMINUTES: stageMinutes = scriptEng.operands[i]; break;6133case VAR_STAGEACTNUM: actID = scriptEng.operands[i]; break;6134case VAR_STAGEPAUSEENABLED: pauseEnabled = scriptEng.operands[i]; break;6135case VAR_STAGELISTSIZE: break;6136case VAR_STAGENEWXBOUNDARY1: newXBoundary1 = scriptEng.operands[i]; break;6137case VAR_STAGENEWXBOUNDARY2: newXBoundary2 = scriptEng.operands[i]; break;6138case VAR_STAGENEWYBOUNDARY1: newYBoundary1 = scriptEng.operands[i]; break;6139case VAR_STAGENEWYBOUNDARY2: newYBoundary2 = scriptEng.operands[i]; break;6140case VAR_STAGECURXBOUNDARY1:6141if (curXBoundary1 != scriptEng.operands[i]) {6142curXBoundary1 = scriptEng.operands[i];6143newXBoundary1 = scriptEng.operands[i];6144}6145break;6146case VAR_STAGECURXBOUNDARY2:6147if (curXBoundary2 != scriptEng.operands[i]) {6148curXBoundary2 = scriptEng.operands[i];6149newXBoundary2 = scriptEng.operands[i];6150}6151break;6152case VAR_STAGECURYBOUNDARY1:6153if (curYBoundary1 != scriptEng.operands[i]) {6154curYBoundary1 = scriptEng.operands[i];6155newYBoundary1 = scriptEng.operands[i];6156}6157break;6158case VAR_STAGECURYBOUNDARY2:6159if (curYBoundary2 != scriptEng.operands[i]) {6160curYBoundary2 = scriptEng.operands[i];6161newYBoundary2 = scriptEng.operands[i];6162}6163break;6164case VAR_STAGEDEFORMATIONDATA0: bgDeformationData0[arrayVal] = scriptEng.operands[i]; break;6165case VAR_STAGEDEFORMATIONDATA1: bgDeformationData1[arrayVal] = scriptEng.operands[i]; break;6166case VAR_STAGEDEFORMATIONDATA2: bgDeformationData2[arrayVal] = scriptEng.operands[i]; break;6167case VAR_STAGEDEFORMATIONDATA3: bgDeformationData3[arrayVal] = scriptEng.operands[i]; break;6168case VAR_STAGEWATERLEVEL: waterLevel = scriptEng.operands[i]; break;6169case VAR_STAGEACTIVELAYER: activeTileLayers[arrayVal] = scriptEng.operands[i]; break;6170case VAR_STAGEMIDPOINT: tLayerMidPoint = scriptEng.operands[i]; break;6171case VAR_STAGEPLAYERLISTPOS: playerListPos = scriptEng.operands[i]; break;6172case VAR_STAGEDEBUGMODE: debugMode = scriptEng.operands[i]; break;6173case VAR_STAGEENTITYPOS: objectEntityPos = scriptEng.operands[i]; break;6174case VAR_SCREENCAMERAENABLED: cameraEnabled = scriptEng.operands[i]; break;6175case VAR_SCREENCAMERATARGET: cameraTarget = scriptEng.operands[i]; break;6176case VAR_SCREENCAMERASTYLE: cameraStyle = scriptEng.operands[i]; break;6177case VAR_SCREENCAMERAX: cameraXPos = scriptEng.operands[i]; break;6178case VAR_SCREENCAMERAY: cameraYPos = scriptEng.operands[i]; break;6179case VAR_SCREENDRAWLISTSIZE: drawListEntries[arrayVal].listSize = scriptEng.operands[i]; break;6180case VAR_SCREENXCENTER: break;6181case VAR_SCREENYCENTER: break;6182case VAR_SCREENXSIZE: break;6183case VAR_SCREENYSIZE: break;6184case VAR_SCREENXOFFSET: xScrollOffset = scriptEng.operands[i]; break;6185case VAR_SCREENYOFFSET: yScrollOffset = scriptEng.operands[i]; break;6186case VAR_SCREENSHAKEX: cameraShakeX = scriptEng.operands[i]; break;6187case VAR_SCREENSHAKEY: cameraShakeY = scriptEng.operands[i]; break;6188case VAR_SCREENADJUSTCAMERAY: cameraAdjustY = scriptEng.operands[i]; break;6189case VAR_TOUCHSCREENDOWN: break;6190case VAR_TOUCHSCREENXPOS: break;6191case VAR_TOUCHSCREENYPOS: break;6192case VAR_MUSICVOLUME: SetMusicVolume(scriptEng.operands[i]); break;6193case VAR_MUSICCURRENTTRACK: break;6194case VAR_MUSICPOSITION: break;6195#if RETRO_REV03 && !RETRO_USE_ORIGINAL_CODE6196case VAR_KEYDOWNUP:6197if (inputCheck)6198keyDown.up = scriptEng.operands[i];6199break;6200case VAR_KEYDOWNDOWN:6201if (inputCheck)6202keyDown.down = scriptEng.operands[i];6203break;6204case VAR_KEYDOWNLEFT:6205if (inputCheck)6206keyDown.left = scriptEng.operands[i];6207break;6208case VAR_KEYDOWNRIGHT:6209if (inputCheck)6210keyDown.right = scriptEng.operands[i];6211break;6212case VAR_KEYDOWNBUTTONA:6213if (inputCheck)6214keyDown.A = scriptEng.operands[i];6215break;6216case VAR_KEYDOWNBUTTONB:6217if (inputCheck)6218keyDown.B = scriptEng.operands[i];6219break;6220case VAR_KEYDOWNBUTTONC:6221if (inputCheck)6222keyDown.C = scriptEng.operands[i];6223break;6224case VAR_KEYDOWNBUTTONX:6225if (inputCheck)6226keyDown.X = scriptEng.operands[i];6227break;6228case VAR_KEYDOWNBUTTONY:6229if (inputCheck)6230keyDown.Y = scriptEng.operands[i];6231break;6232case VAR_KEYDOWNBUTTONZ:6233if (inputCheck)6234keyDown.Z = scriptEng.operands[i];6235break;6236case VAR_KEYDOWNBUTTONL:6237if (inputCheck)6238keyDown.L = scriptEng.operands[i];6239break;6240case VAR_KEYDOWNBUTTONR:6241if (inputCheck)6242keyDown.R = scriptEng.operands[i];6243break;6244case VAR_KEYDOWNSTART:6245if (inputCheck)6246keyDown.start = scriptEng.operands[i];6247break;6248case VAR_KEYDOWNSELECT:6249if (inputCheck)6250keyDown.select = scriptEng.operands[i];6251break;6252case VAR_KEYPRESSUP:6253if (inputCheck)6254keyPress.up = scriptEng.operands[i];6255break;6256case VAR_KEYPRESSDOWN:6257if (inputCheck)6258keyPress.down = scriptEng.operands[i];6259break;6260case VAR_KEYPRESSLEFT:6261if (inputCheck)6262keyPress.left = scriptEng.operands[i];6263break;6264case VAR_KEYPRESSRIGHT:6265if (inputCheck)6266keyPress.right = scriptEng.operands[i];6267break;6268case VAR_KEYPRESSBUTTONA:6269if (inputCheck)6270keyPress.A = scriptEng.operands[i];6271break;6272case VAR_KEYPRESSBUTTONB:6273if (inputCheck)6274keyPress.B = scriptEng.operands[i];6275break;6276case VAR_KEYPRESSBUTTONC:6277if (inputCheck)6278keyPress.C = scriptEng.operands[i];6279break;6280case VAR_KEYPRESSBUTTONX:6281if (inputCheck)6282keyPress.X = scriptEng.operands[i];6283break;6284case VAR_KEYPRESSBUTTONY:6285if (inputCheck)6286keyPress.Y = scriptEng.operands[i];6287break;6288case VAR_KEYPRESSBUTTONZ:6289if (inputCheck)6290keyPress.Z = scriptEng.operands[i];6291break;6292case VAR_KEYPRESSBUTTONL:6293if (inputCheck)6294keyPress.L = scriptEng.operands[i];6295break;6296case VAR_KEYPRESSBUTTONR:6297if (inputCheck)6298keyPress.R = scriptEng.operands[i];6299break;6300case VAR_KEYPRESSSTART:6301if (inputCheck)6302keyPress.start = scriptEng.operands[i];6303break;6304case VAR_KEYPRESSSELECT:6305if (inputCheck)6306keyPress.select = scriptEng.operands[i];6307break;6308#else6309case VAR_KEYDOWNUP: keyDown.up = scriptEng.operands[i]; break;6310case VAR_KEYDOWNDOWN: keyDown.down = scriptEng.operands[i]; break;6311case VAR_KEYDOWNLEFT: keyDown.left = scriptEng.operands[i]; break;6312case VAR_KEYDOWNRIGHT: keyDown.right = scriptEng.operands[i]; break;6313case VAR_KEYDOWNBUTTONA: keyDown.A = scriptEng.operands[i]; break;6314case VAR_KEYDOWNBUTTONB: keyDown.B = scriptEng.operands[i]; break;6315case VAR_KEYDOWNBUTTONC: keyDown.C = scriptEng.operands[i]; break;6316case VAR_KEYDOWNBUTTONX: keyDown.X = scriptEng.operands[i]; break;6317case VAR_KEYDOWNBUTTONY: keyDown.Y = scriptEng.operands[i]; break;6318case VAR_KEYDOWNBUTTONZ: keyDown.Z = scriptEng.operands[i]; break;6319case VAR_KEYDOWNBUTTONL: keyDown.L = scriptEng.operands[i]; break;6320case VAR_KEYDOWNBUTTONR: keyDown.R = scriptEng.operands[i]; break;6321case VAR_KEYDOWNSTART: keyDown.start = scriptEng.operands[i]; break;6322case VAR_KEYDOWNSELECT: keyDown.select = scriptEng.operands[i]; break;6323case VAR_KEYPRESSUP: keyPress.up = scriptEng.operands[i]; break;6324case VAR_KEYPRESSDOWN: keyPress.down = scriptEng.operands[i]; break;6325case VAR_KEYPRESSLEFT: keyPress.left = scriptEng.operands[i]; break;6326case VAR_KEYPRESSRIGHT: keyPress.right = scriptEng.operands[i]; break;6327case VAR_KEYPRESSBUTTONA: keyPress.A = scriptEng.operands[i]; break;6328case VAR_KEYPRESSBUTTONB: keyPress.B = scriptEng.operands[i]; break;6329case VAR_KEYPRESSBUTTONC: keyPress.C = scriptEng.operands[i]; break;6330case VAR_KEYPRESSBUTTONX: keyPress.X = scriptEng.operands[i]; break;6331case VAR_KEYPRESSBUTTONY: keyPress.Y = scriptEng.operands[i]; break;6332case VAR_KEYPRESSBUTTONZ: keyPress.Z = scriptEng.operands[i]; break;6333case VAR_KEYPRESSBUTTONL: keyPress.L = scriptEng.operands[i]; break;6334case VAR_KEYPRESSBUTTONR: keyPress.R = scriptEng.operands[i]; break;6335case VAR_KEYPRESSSTART: keyPress.start = scriptEng.operands[i]; break;6336case VAR_KEYPRESSSELECT: keyPress.select = scriptEng.operands[i]; break;6337#endif6338case VAR_MENU1SELECTION: gameMenu[0].selection1 = scriptEng.operands[i]; break;6339case VAR_MENU2SELECTION: gameMenu[1].selection1 = scriptEng.operands[i]; break;6340case VAR_TILELAYERXSIZE: stageLayouts[arrayVal].xsize = scriptEng.operands[i]; break;6341case VAR_TILELAYERYSIZE: stageLayouts[arrayVal].ysize = scriptEng.operands[i]; break;6342case VAR_TILELAYERTYPE: stageLayouts[arrayVal].type = scriptEng.operands[i]; break;6343case VAR_TILELAYERANGLE: {6344int angle = scriptEng.operands[i] + 0x200;6345if (scriptEng.operands[i] >= 0)6346angle = scriptEng.operands[i];6347stageLayouts[arrayVal].angle = angle & 0x1FF;6348break;6349}6350case VAR_TILELAYERXPOS: stageLayouts[arrayVal].xpos = scriptEng.operands[i]; break;6351case VAR_TILELAYERYPOS: stageLayouts[arrayVal].ypos = scriptEng.operands[i]; break;6352case VAR_TILELAYERZPOS: stageLayouts[arrayVal].zpos = scriptEng.operands[i]; break;6353case VAR_TILELAYERPARALLAXFACTOR: stageLayouts[arrayVal].parallaxFactor = scriptEng.operands[i]; break;6354case VAR_TILELAYERSCROLLSPEED: stageLayouts[arrayVal].scrollSpeed = scriptEng.operands[i]; break;6355case VAR_TILELAYERSCROLLPOS: stageLayouts[arrayVal].scrollPos = scriptEng.operands[i]; break;6356case VAR_TILELAYERDEFORMATIONOFFSET: stageLayouts[arrayVal].deformationOffset = scriptEng.operands[i]; break;6357case VAR_TILELAYERDEFORMATIONOFFSETW: stageLayouts[arrayVal].deformationOffsetW = scriptEng.operands[i]; break;6358case VAR_HPARALLAXPARALLAXFACTOR: hParallax.parallaxFactor[arrayVal] = scriptEng.operands[i]; break;6359case VAR_HPARALLAXSCROLLSPEED: hParallax.scrollSpeed[arrayVal] = scriptEng.operands[i]; break;6360case VAR_HPARALLAXSCROLLPOS: hParallax.scrollPos[arrayVal] = scriptEng.operands[i]; break;6361case VAR_VPARALLAXPARALLAXFACTOR: vParallax.parallaxFactor[arrayVal] = scriptEng.operands[i]; break;6362case VAR_VPARALLAXSCROLLSPEED: vParallax.scrollSpeed[arrayVal] = scriptEng.operands[i]; break;6363case VAR_VPARALLAXSCROLLPOS: vParallax.scrollPos[arrayVal] = scriptEng.operands[i]; break;6364case VAR_SCENE3DVERTEXCOUNT: vertexCount = scriptEng.operands[i]; break;6365case VAR_SCENE3DFACECOUNT: faceCount = scriptEng.operands[i]; break;6366case VAR_SCENE3DPROJECTIONX: projectionX = scriptEng.operands[i]; break;6367case VAR_SCENE3DPROJECTIONY: projectionY = scriptEng.operands[i]; break;6368#if !RETRO_REV006369case VAR_SCENE3DFOGCOLOR: fogColor = scriptEng.operands[i]; break;6370case VAR_SCENE3DFOGSTRENGTH: fogStrength = scriptEng.operands[i]; break;6371#endif6372case VAR_VERTEXBUFFERX: vertexBuffer[arrayVal].x = scriptEng.operands[i]; break;6373case VAR_VERTEXBUFFERY: vertexBuffer[arrayVal].y = scriptEng.operands[i]; break;6374case VAR_VERTEXBUFFERZ: vertexBuffer[arrayVal].z = scriptEng.operands[i]; break;6375case VAR_VERTEXBUFFERU: vertexBuffer[arrayVal].u = scriptEng.operands[i]; break;6376case VAR_VERTEXBUFFERV: vertexBuffer[arrayVal].v = scriptEng.operands[i]; break;6377case VAR_FACEBUFFERA: faceBuffer[arrayVal].a = scriptEng.operands[i]; break;6378case VAR_FACEBUFFERB: faceBuffer[arrayVal].b = scriptEng.operands[i]; break;6379case VAR_FACEBUFFERC: faceBuffer[arrayVal].c = scriptEng.operands[i]; break;6380case VAR_FACEBUFFERD: faceBuffer[arrayVal].d = scriptEng.operands[i]; break;6381case VAR_FACEBUFFERFLAG: faceBuffer[arrayVal].flag = scriptEng.operands[i]; break;6382case VAR_FACEBUFFERCOLOR: faceBuffer[arrayVal].color = scriptEng.operands[i]; break;6383case VAR_SAVERAM: saveRAM[arrayVal] = scriptEng.operands[i]; break;6384case VAR_ENGINESTATE: Engine.gameMode = scriptEng.operands[i]; break;6385#if RETRO_REV006386case VAR_ENGINEMESSAGE: break;6387#endif6388case VAR_ENGINELANGUAGE: Engine.language = scriptEng.operands[i]; break;6389case VAR_ENGINEONLINEACTIVE: Engine.onlineActive = scriptEng.operands[i]; break;6390case VAR_ENGINESFXVOLUME:6391sfxVolume = scriptEng.operands[i];6392SetGameVolumes(bgmVolume, sfxVolume);6393break;6394case VAR_ENGINEBGMVOLUME:6395bgmVolume = scriptEng.operands[i];6396SetGameVolumes(bgmVolume, sfxVolume);6397break;6398#if RETRO_REV006399case VAR_ENGINEPLATFORMID: break;6400#endif6401case VAR_ENGINETRIALMODE: Engine.trialMode = scriptEng.operands[i]; break;6402#if !RETRO_REV006403case VAR_ENGINEDEVICETYPE: break;6404#endif64056406#if RETRO_REV036407// Origins Extras6408// Due to using regular v4, these don't support array values like origins expects, so its always screen[0]6409case VAR_SCREENCURRENTID: break;6410case VAR_CAMERAENABLED:6411if (arrayVal == 0)6412cameraEnabled = scriptEng.operands[i];6413break;6414case VAR_CAMERATARGET:6415if (arrayVal == 0)6416cameraTarget = scriptEng.operands[i];6417break;6418case VAR_CAMERASTYLE:6419if (arrayVal == 0)6420cameraStyle = scriptEng.operands[i];6421break;6422case VAR_CAMERAXPOS:6423if (arrayVal == 0)6424cameraXPos = scriptEng.operands[i];6425break;6426case VAR_CAMERAYPOS:6427if (arrayVal == 0)6428cameraYPos = scriptEng.operands[i];6429break;6430case VAR_CAMERAADJUSTY:6431if (arrayVal == 0)6432cameraAdjustY = scriptEng.operands[i];6433break;6434#endif64356436#if RETRO_USE_HAPTICS6437case VAR_HAPTICSENABLED: Engine.hapticsEnabled = scriptEng.operands[i]; break;6438#endif6439}6440}6441else if (opcodeType == SCRIPTVAR_INTCONST) { // int constant6442scriptCodePtr++;6443}6444else if (opcodeType == SCRIPTVAR_STRCONST) { // string constant6445int strLen = scriptCode[scriptCodePtr++];6446for (int c = 0; c < strLen; ++c) {6447switch (c % 4) {6448case 0: break;6449case 1: break;6450case 2: break;6451case 3: ++scriptCodePtr; break;6452default: break;6453}6454}6455scriptCodePtr++;6456}6457}6458}6459}646064616462