From 218ee05167cda8c925c72be7569d719f40927a3f Mon Sep 17 00:00:00 2001 From: Nat Quayle Nelson Date: Mon, 22 Sep 2025 16:24:58 -0500 Subject: [PATCH] lay the foundation for interpreted scripts --- haxe_libraries/hollywoo.hxml | 6 +- haxe_libraries/kiss-flixel.hxml | 4 +- haxe_libraries/kiss-tools.hxml | 4 +- haxe_libraries/kiss.hxml | 6 +- src/hollywoo_flixel/FlxDirector.hx | 360 ++++++++++----------- src/hollywoo_flixel/FlxDirector.kiss | 3 +- src/hollywoo_flixel/HollywooFlixelDSL.kiss | 46 ++- src/hollywoo_flixel/HollywooInterp.hx | 126 +++++++- 8 files changed, 361 insertions(+), 194 deletions(-) diff --git a/haxe_libraries/hollywoo.hxml b/haxe_libraries/hollywoo.hxml index 806f207..8cf0715 100644 --- a/haxe_libraries/hollywoo.hxml +++ b/haxe_libraries/hollywoo.hxml @@ -1,6 +1,6 @@ -# @install: lix --silent download "git:https://k7izh9.gitea.cloud/kiss-lang/hollywoo#cc261b3a72b6b4d3512486bc3be6aaf4f0683562" into hollywoo/0.0.0/git/cc261b3a72b6b4d3512486bc3be6aaf4f0683562 -# @run: haxelib run-dir hollywoo "${HAXE_LIBCACHE}/hollywoo/0.0.0/git/cc261b3a72b6b4d3512486bc3be6aaf4f0683562" +# @install: lix --silent download "git:https://k7izh9.gitea.cloud/kiss-lang/hollywoo#4916a6d24ec836f3e9c766b0771099aa278048d5" into hollywoo/0.0.0/git/4916a6d24ec836f3e9c766b0771099aa278048d5 +# @run: haxelib run-dir hollywoo "${HAXE_LIBCACHE}/hollywoo/0.0.0/git/4916a6d24ec836f3e9c766b0771099aa278048d5" -lib kiss -lib kiss-tools --cp ${HAXE_LIBCACHE}/hollywoo/0.0.0/git/cc261b3a72b6b4d3512486bc3be6aaf4f0683562/src/ +-cp ${HAXE_LIBCACHE}/hollywoo/0.0.0/git/4916a6d24ec836f3e9c766b0771099aa278048d5/src/ -D hollywoo=0.0.0 \ No newline at end of file diff --git a/haxe_libraries/kiss-flixel.hxml b/haxe_libraries/kiss-flixel.hxml index 8c548f6..1c394d0 100644 --- a/haxe_libraries/kiss-flixel.hxml +++ b/haxe_libraries/kiss-flixel.hxml @@ -1,4 +1,4 @@ -# @install: lix --silent download "git:https://k7izh9.gitea.cloud/kiss-lang/kiss-flixel#454f39781eb3afcc71181aa2088a017660fcee4f" into kiss-flixel/0.0.0/git/454f39781eb3afcc71181aa2088a017660fcee4f +# @install: lix --silent download "git:https://k7izh9.gitea.cloud/kiss-lang/kiss-flixel#81dd066ebe275c5a6aab49d0aef8ac63068322a7" into kiss-flixel/0.0.0/git/81dd066ebe275c5a6aab49d0aef8ac63068322a7 -lib flixel -lib flixel-addons -lib flixel-ui @@ -6,6 +6,6 @@ -lib kiss-tools -lib lime -lib openfl --cp ${HAXE_LIBCACHE}/kiss-flixel/0.0.0/git/454f39781eb3afcc71181aa2088a017660fcee4f/src/ +-cp ${HAXE_LIBCACHE}/kiss-flixel/0.0.0/git/81dd066ebe275c5a6aab49d0aef8ac63068322a7/src/ -D kiss-flixel=0.0.0 --macro kiss_flixel.ShaderFrontend.use() \ No newline at end of file diff --git a/haxe_libraries/kiss-tools.hxml b/haxe_libraries/kiss-tools.hxml index 63aecb3..f6a109e 100644 --- a/haxe_libraries/kiss-tools.hxml +++ b/haxe_libraries/kiss-tools.hxml @@ -1,4 +1,4 @@ -# @install: lix --silent download "git:https://k7izh9.gitea.cloud/kiss-lang/kiss-tools#5a19e61489e61cdc721af4b44584b642b25b6ad2" into kiss-tools/0.0.0/git/5a19e61489e61cdc721af4b44584b642b25b6ad2 +# @install: lix --silent download "git:https://k7izh9.gitea.cloud/kiss-lang/kiss-tools#e1323fb0b64ef3532bce137d128aa2fb62e26329" into kiss-tools/0.0.0/git/e1323fb0b64ef3532bce137d128aa2fb62e26329 -lib kiss --cp ${HAXE_LIBCACHE}/kiss-tools/0.0.0/git/5a19e61489e61cdc721af4b44584b642b25b6ad2/src/ +-cp ${HAXE_LIBCACHE}/kiss-tools/0.0.0/git/e1323fb0b64ef3532bce137d128aa2fb62e26329/src/ -D kiss-tools=0.0.0 \ No newline at end of file diff --git a/haxe_libraries/kiss.hxml b/haxe_libraries/kiss.hxml index d956a63..43e205c 100644 --- a/haxe_libraries/kiss.hxml +++ b/haxe_libraries/kiss.hxml @@ -1,12 +1,12 @@ -# @install: lix --silent download "git:https://k7izh9.gitea.cloud/kiss-lang/kiss#84b09821f2f2e4b055038af3609170fbdf71cbd9" into kiss/0.0.1/git/84b09821f2f2e4b055038af3609170fbdf71cbd9 -# @run: haxelib run-dir kiss "${HAXE_LIBCACHE}/kiss/0.0.1/git/84b09821f2f2e4b055038af3609170fbdf71cbd9" +# @install: lix --silent download "git:https://k7izh9.gitea.cloud/kiss-lang/kiss#5da754d5ab24b69afefee18cf3b464bd80896d2c" into kiss/0.0.1/git/5da754d5ab24b69afefee18cf3b464bd80896d2c +# @run: haxelib run-dir kiss "${HAXE_LIBCACHE}/kiss/0.0.1/git/5da754d5ab24b69afefee18cf3b464bd80896d2c" -lib haxe-strings -lib hscript -lib tink_json -lib tink_macro -lib tink_syntaxhub -lib uuid --cp ${HAXE_LIBCACHE}/kiss/0.0.1/git/84b09821f2f2e4b055038af3609170fbdf71cbd9/src +-cp ${HAXE_LIBCACHE}/kiss/0.0.1/git/5da754d5ab24b69afefee18cf3b464bd80896d2c/src -D kiss=0.0.1 -w -WUnusedPattern --macro kiss.KissFrontend.use() \ No newline at end of file diff --git a/src/hollywoo_flixel/FlxDirector.hx b/src/hollywoo_flixel/FlxDirector.hx index 5e88845..e992bbc 100644 --- a/src/hollywoo_flixel/FlxDirector.hx +++ b/src/hollywoo_flixel/FlxDirector.hx @@ -70,14 +70,14 @@ class FlxDirector implements Director; public static function get_lastSceneLabels():Map return { if (Prelude.truthy({ - final _6W7oc3M6xwrzSHgtjRALx:Dynamic = sys.FileSystem.exists(".FlxDirector.json"); + final _9hKvHu2hUrbv3SBdbUpF5v:Dynamic = sys.FileSystem.exists(".FlxDirector.json"); { - if (Prelude.truthy(_6W7oc3M6xwrzSHgtjRALx)) { - final _paW4tq9PLe9Wnrm8TQejiF:Dynamic = !Prelude.truthy(sys.FileSystem.isDirectory(".FlxDirector.json")); + if (Prelude.truthy(_9hKvHu2hUrbv3SBdbUpF5v)) { + final _riVPNGq5L9ms51ZA9jEmZS:Dynamic = !Prelude.truthy(sys.FileSystem.isDirectory(".FlxDirector.json")); { - _paW4tq9PLe9Wnrm8TQejiF; + _riVPNGq5L9ms51ZA9jEmZS; }; - } else _6W7oc3M6xwrzSHgtjRALx; + } else _9hKvHu2hUrbv3SBdbUpF5v; }; })) { final content = sys.io.File.getContent(".FlxDirector.json"); final json:haxe.DynamicAccess = haxe.Json.parse(content); @@ -93,14 +93,14 @@ class FlxDirector implements Director):Map return { if (Prelude.truthy({ - final _jPTpPcp7jmu7tzTUYWrQQc:Dynamic = sys.FileSystem.exists(".FlxDirector.json"); + final _kCpwNaA1sswtR4d9pnGo2w:Dynamic = sys.FileSystem.exists(".FlxDirector.json"); { - if (Prelude.truthy(_jPTpPcp7jmu7tzTUYWrQQc)) { - final _nPhEdyFWZ4rZ8d6RyFKc4a:Dynamic = !Prelude.truthy(sys.FileSystem.isDirectory(".FlxDirector.json")); + if (Prelude.truthy(_kCpwNaA1sswtR4d9pnGo2w)) { + final _qx4G79pPJYE1sSZBKwb4dn:Dynamic = !Prelude.truthy(sys.FileSystem.isDirectory(".FlxDirector.json")); { - _nPhEdyFWZ4rZ8d6RyFKc4a; + _qx4G79pPJYE1sSZBKwb4dn; }; - } else _jPTpPcp7jmu7tzTUYWrQQc; + } else _kCpwNaA1sswtR4d9pnGo2w; }; })) { final content = sys.io.File.getContent(".FlxDirector.json"); final json:haxe.DynamicAccess = haxe.Json.parse(content); @@ -125,23 +125,23 @@ class FlxDirector implements Director>)) { - final _aVq547xCteR7EUauCrhrPz = _eUF74RxfWgTRE11hKzounJ; final action:FlxActionDigital = _aVq547xCteR7EUauCrhrPz[0]; final trigger:FlxInputState = _aVq547xCteR7EUauCrhrPz[1]; + for (_aLebU1T9ZaYCGtrgqRhDFT in (Prelude.zipThrow(new kiss.List([continueAction, fastForwardAction]), new kiss.List([JUST_PRESSED, PRESSED])) : Array>)) { + final _nNGXZHmcEHW9KAkt1GHnLW = _aLebU1T9ZaYCGtrgqRhDFT; final action:FlxActionDigital = _nNGXZHmcEHW9KAkt1GHnLW[0]; final trigger:FlxInputState = _nNGXZHmcEHW9KAkt1GHnLW[1]; { action.addKey(SPACE, trigger); action.addKey(ENTER, trigger); @@ -230,13 +230,13 @@ class FlxDirector implements Director) return { switch type { - case _eRMU5rHn3TJidmo7ih2sYC if (Prelude.truthy(Prelude.isNull(_eRMU5rHn3TJidmo7ih2sYC))):{ + case _5qUDuLanjwQ5bE987hMqVG if (Prelude.truthy(Prelude.isNull(_5qUDuLanjwQ5bE987hMqVG))):{ { name; }; @@ -528,7 +528,7 @@ class FlxDirector implements Director = haxe.Json.parse(content); @@ -799,14 +799,14 @@ class FlxDirector implements Director = haxe.Json.parse(content); @@ -833,14 +833,14 @@ class FlxDirector implements Director = haxe.Json.parse(content); @@ -856,14 +856,14 @@ class FlxDirector implements Director = haxe.Json.parse(content); @@ -890,14 +890,14 @@ class FlxDirector implements Director = haxe.Json.parse(content); @@ -913,14 +913,14 @@ class FlxDirector implements Director = haxe.Json.parse(content); @@ -946,12 +946,12 @@ class FlxDirector implements Director, submit:(String)->Void, ?xButton:Bool, ?xKey:String):Void { pauseMenu = kiss_flixel.SimpleWindow.promptForChoiceV2(prompt, choices, submit, { bgColor : flixel.util.FlxColor.BLACK, titleColor : textColor, choiceColor : buttonColor, percentWidth : 0.8, percentHeight : 0.8, xButton : Prelude.truthy(xButton), xKey : { - final _mnTZ1YNr7uyNWq9FyYbPpZ:Dynamic = xKey; + final _ee21z26qqKctMd9tRU1FVi:Dynamic = xKey; { - if (Prelude.truthy(_mnTZ1YNr7uyNWq9FyYbPpZ)) _mnTZ1YNr7uyNWq9FyYbPpZ else { - final _gZcXRfQAt4K3PYbfGbuMB:Dynamic = ""; + if (Prelude.truthy(_ee21z26qqKctMd9tRU1FVi)) _ee21z26qqKctMd9tRU1FVi else { + final _tzuzwTipiVeBY8qAm7hNmR:Dynamic = ""; { - _gZcXRfQAt4K3PYbfGbuMB; + _tzuzwTipiVeBY8qAm7hNmR; }; }; }; @@ -1025,12 +1025,12 @@ class FlxDirector implements Director, appearance:Appearance, camera:flixel.FlxCamera, cc:Continuation):Void { { - final _v6anR1vrz1C1LZ5eVXDUfB = appearance; + final _szeECTeeVUJJ1eTWuBX9Hg = appearance; { - if (Prelude.truthy(Prelude.isNotNull(_v6anR1vrz1C1LZ5eVXDUfB))) switch _v6anR1vrz1C1LZ5eVXDUfB { - case _6Fum6NoxPirge3ox4L6yiT if (Prelude.truthy(Prelude.isNull(_6Fum6NoxPirge3ox4L6yiT))):{ + if (Prelude.truthy(_szeECTeeVUJJ1eTWuBX9Hg)) switch _szeECTeeVUJJ1eTWuBX9Hg { + case _iqXe8LShYhpoJhVr9ET1ra if (Prelude.truthy(Prelude.isNull(_iqXe8LShYhpoJhVr9ET1ra))):{ { null; }; @@ -1299,10 +1299,10 @@ class FlxDirector implements Director; public function onContinue(continueAction:FlxActionDigital) return { { - final _mc7ovV4JdbqCQPgGeC9WpE = nextCC; + final _ouyVJKoxnB21CUMwg3YFyL = nextCC; { - if (Prelude.truthy(Prelude.isNotNull(_mc7ovV4JdbqCQPgGeC9WpE))) switch _mc7ovV4JdbqCQPgGeC9WpE { - case _hX61VXPeWaaDmDTuzCmCco if (Prelude.truthy(Prelude.isNull(_hX61VXPeWaaDmDTuzCmCco))):{ + if (Prelude.truthy(_ouyVJKoxnB21CUMwg3YFyL)) switch _ouyVJKoxnB21CUMwg3YFyL { + case _hpts2oUxdcjYc12K9wyY8D if (Prelude.truthy(Prelude.isNull(_hpts2oUxdcjYc12K9wyY8D))):{ { null; }; @@ -1407,12 +1407,12 @@ class FlxDirector implements Director, wryly:String, text:String, cc:Continuation) return { var speakerNameX:Float = -1; switch type { - case _t2CcEJPbTcb3CJAMQTXSJD if (Prelude.truthy(Prelude.isNull(_t2CcEJPbTcb3CJAMQTXSJD))):{ + case _doWeVZk9CXPTFa58xGgzY1 if (Prelude.truthy(Prelude.isNull(_doWeVZk9CXPTFa58xGgzY1))):{ { }; }; case Super:{ @@ -1596,14 +1596,14 @@ class FlxDirector implements Director = haxe.Json.parse(content); @@ -1619,14 +1619,14 @@ class FlxDirector implements Director = haxe.Json.parse(content); @@ -1649,14 +1649,14 @@ class FlxDirector implements Director = haxe.Json.parse(content); @@ -1672,14 +1672,14 @@ class FlxDirector implements Director = haxe.Json.parse(content); @@ -1746,7 +1746,7 @@ class FlxDirector implements Director = haxe.Json.parse(content); @@ -1828,14 +1828,14 @@ class FlxDirector implements Director = haxe.Json.parse(content); @@ -1905,14 +1905,14 @@ class FlxDirector implements Director = haxe.Json.parse(content); @@ -1928,14 +1928,14 @@ class FlxDirector implements Director = haxe.Json.parse(content); @@ -1997,7 +1997,7 @@ class FlxDirector implements Director _propKeys (new Map)) + (var &mut anonProps 0) (function _propKey [:FlxSprite prop] (ifLet [key (dictGet _propKeys prop)] key - (dictSet _propKeys prop (or prop.graphic.assetsKey "anonProp#${anonProps++}")))) + (dictSet _propKeys prop (or prop.graphic?.assetsKey "anonProp#${anonProps++}")))) (method :Void hideProp [:FlxSprite prop :FlxCamera camera cc] (FlxG.state.remove prop true) diff --git a/src/hollywoo_flixel/HollywooFlixelDSL.kiss b/src/hollywoo_flixel/HollywooFlixelDSL.kiss index 0cfa23e..5fd662b 100644 --- a/src/hollywoo_flixel/HollywooFlixelDSL.kiss +++ b/src/hollywoo_flixel/HollywooFlixelDSL.kiss @@ -147,6 +147,7 @@ }))) // When skipping through, don't add the camera until skipping ends + (hollywooMethod addTempCamera [:Bool skipping :FlxCamera camera &opt :Bool defaultDrawTarget :Bool bg :Continuation cc] (dictSet (if bg tempBgCameras tempCameras) camera ?defaultDrawTarget) (let [order (if bg tempBgCamerasOrder tempCamerasOrder)] @@ -242,15 +243,19 @@ exps [(read nextLineStream) (read nextLineStream) (read nextLineStream) (readOr nextLineStream `null) (readOr nextLineStream `null) (readOr nextLineStream `[])]] `(_linearMotionTo ,withMacro ,await ,@exps))) +// TODO interp reader macro -- very difficult (defReaderMacro "AWAITLINEARMOTIONACTORTO" [stream &builder b] (awaitLMTReaderMacro stream `withActorCC true)) +// TODO interp reader macro -- very difficult (defReaderMacro "AWAITLINEARMOTIONPROPTO" [stream &builder b] (awaitLMTReaderMacro stream `withPropCC true)) +// TODO interp reader macro -- very difficult (defReaderMacro "LINEARMOTIONACTORTO" [stream &builder b] (awaitLMTReaderMacro stream `withActorCC false)) +// TODO interp reader macro -- very difficult (defReaderMacro "LINEARMOTIONPROPTO" [stream &builder b] (awaitLMTReaderMacro stream `withPropCC false)) @@ -278,23 +283,29 @@ exps [(read nextLineStream) (read nextLineStream) (read nextLineStream) (read nextLineStream) (readOr nextLineStream `null) (readOr nextLineStream `null) (readOr nextLineStream `[])]] `(_linearMotion ,withMacro ,await ,@exps))) +// TODO interp reader macro -- very difficult (defReaderMacro "AWAITLINEARMOTIONACTOR" [stream &builder b] (awaitLMReaderMacro stream `withActorCC true)) +// TODO interp reader macro -- very difficult (defReaderMacro "AWAITLINEARMOTIONPROP" [stream &builder b] (awaitLMReaderMacro stream `withPropCC true)) +// TODO interp reader macro -- very difficult (defReaderMacro "LINEARMOTIONACTOR" [stream &builder b] (awaitLMReaderMacro stream `withActorCC false)) +// TODO interp reader macro -- very difficult (defReaderMacro "LINEARMOTIONPROP" [stream &builder b] (awaitLMReaderMacro stream `withPropCC false)) +// TODO make this a hollywooMethod & interp reader macro (defReaderMacro "ACTORPLAYANIMATION" [stream &builder b] (let [actor (read stream) anim (read stream)] `(withActor ,actor a (a.playAnimation ,anim)))) +// TODO make this a hollywooMethod & interp reader macro (defReaderMacro "ASSERTLOGSPRITES" [stream &builder b] `(#when debug (when skipping @@ -303,6 +314,7 @@ (when skipping (FlxG.state.remove flxDirector.spriteLayers true)) (cc))) +// TODO make this a hollywooMethod & interp reader macro (defReaderMacro "ASSERTLOGSPRITESCC" [stream &builder b] `(#when debug (when skipping @@ -310,6 +322,7 @@ (kiss_flixel.SpriteTools.assertLogSprites ,(read stream)) (when skipping (FlxG.state.remove flxDirector.spriteLayers true)))) +// TODO make this a hollywooMethod & interp reader macro (defReaderMacro "WARNLOGSPRITES" [stream &builder b] `(#when debug (when skipping @@ -318,6 +331,7 @@ (when skipping (FlxG.state.remove flxDirector.spriteLayers true)) (cc))) +// TODO make this a hollywooMethod & interp reader macro (defReaderMacro "WARNLOGSPRITESCC" [stream &builder b] `(#when debug (when skipping @@ -327,6 +341,7 @@ (FlxG.state.remove flxDirector.spriteLayers true)))) @:keep +// TODO make this a hollywooMethod & interp reader macro (method :Void scaleTo [:Bool skipping :FlxSprite sprite :Float scale :Float duration &opt :Void->Void cc] (when skipping (sprite.scale.set scale scale) @@ -336,6 +351,7 @@ // Reusable effect: Scan a slightly transparent line side-to-side across a FlxSprite like a scanner @:keep +// TODO make this a hollywooMethod & interp reader macro (method :Void scanLineEffect [:Bool skipping :FlxSprite sprite :FlxColor lineColor :Int lineThickness :Float alpha :Bool vertical :Float speed &opt :Bool repeat :Void->Void cc :String soundLoop :Float volumeMod] (when skipping (cc) @@ -371,6 +387,7 @@ } soundLoop volumeMod))) +// TODO make this a hollywooMethod & interp reader macro (method :Void rotateTo [:Bool skipping :FlxSprite sprite :Float angle :Float duration &opt :Void->Void cc :String soundLoop :Float volumeMod] (when skipping (set sprite.angle angle) @@ -482,6 +499,7 @@ (new StagePosition x y layer))) (prop &mut :Array plates) +// TODO make this a hollywooMethod & interp reader macro (method namePlates [:Bool skipping :Array names :Dynamic delayLength :Bool delayWhileShown :Void->Void cc] (when skipping (cc) @@ -677,6 +695,7 @@ (prop &mut :Int barProgress 0) (prop &mut :Int barMax 0) (prop &mut :Bool skippedBar false) +// TODO make this a hollywooMethod & interp reader macro (method fakeLoadingBar [:Bool skipping :Dynamic position :Dynamic delayV :Int steps :Int width :Int height :FlxColor full :FlxColor empty :Void->Void cc] (when skipping (cc) @@ -931,7 +950,30 @@ }) (method expandInstructions [scriptFile] - (let [stream (kiss.Stream.fromFile scriptFile) + (let [&mut idx (+ currentInstructionPointer 1) + stream (kiss.Stream.fromFile scriptFile) interp (new hollywoo_flixel.HollywooInterp)] + + (dictSet interp.globals "movie" this) + + (doFor =>key position stagePositions + (dictSet interp.globals key position)) + (dictSet interp.globals "FacingLeft" FacingLeft) + (dictSet interp.globals "FacingRight" FacingRight) + + (dictSet interp.globals "Read" hollywoo.Movie.PlayMode.Read) + (dictSet interp.globals "Watch" hollywoo.Movie.PlayMode.Watch) + (until (stream.isEmpty) - (interp.evalCC stream ->v {})))) \ No newline at end of file + (let [exp (interp.read stream)] + (case exp.def + ((CallExp (object def (Symbol "label")) [(object def (StrExp label))]) + (dictSet labels label idx)) + (otherwise + // TODO add more automatic labels + (instructions.insert idx++ ->[self skipping cc] { + (dictSet interp.globals "skipping" skipping) + (dictSet interp.globals "cc" cc) + (print (kiss.Reader.toString exp.def)) + (interp.evalCC exp ->_ {}) + }))))))) \ No newline at end of file diff --git a/src/hollywoo_flixel/HollywooInterp.hx b/src/hollywoo_flixel/HollywooInterp.hx index a5aaa66..6b5ed85 100644 --- a/src/hollywoo_flixel/HollywooInterp.hx +++ b/src/hollywoo_flixel/HollywooInterp.hx @@ -1,6 +1,130 @@ package hollywoo_flixel; import kiss.Prelude; +import kiss.Stream; +import kiss.Reader; + +using StringTools; +using hx.strings.Strings; @:build(kiss.KissInterp2.build()) -class HollywooInterp {} \ No newline at end of file +class HollywooInterp { + function readString(stream:Stream) { + var strExp = read(stream); + switch(strExp.def) { + case StrExp(str): return str; + default: throw 'bad'; + } + } + function new() { + globals["Assets"] = openfl.utils.Assets; + readTable["SETSCENE "] = (stream, self:HasReadTables) -> { + var name = readString(stream); + return read('(movie.setScene skipping "$name" cc)').def; + }; + readTable["THEMEDROLLCREDITS "] = (stream, self:HasReadTables) -> { + var creditsTSV = read(stream); + var songKey = readString(stream); + return read('(movie.themedRollCredits skipping ${Reader.toString(creditsTSV.def)} "$songKey" cc)').def; + // TODO optional volumeMod after + }; + + + function quickReaderMacro(form:String) { + var numToRead = form.countMatches("$$"); + return (stream, self:HasReadTables) -> { + var transformed = form; + for(i in 0...numToRead) { + // Optional arguments + var exp = try { + read(stream); + } catch (e) { + null; + }; + var code = if (exp != null) Reader.toString(exp.def) else "null"; + transformed = transformed.replace("$$" + (i+1), code); + } + return read(transformed).def; + } + } + + readTable["VAR "] = quickReaderMacro("{(var $$1 $$2) (cc)}"); + readTable["PRINT "] = quickReaderMacro("{(print $$1) (cc)}"); + + readTable["SUPERTEXT "] = quickReaderMacro("(movie.superText skipping $$1 cc)"); + readTable["TIMEDSUPERTEXT "] = quickReaderMacro("(movie.timedSuperText skipping $$1 $$2 cc)"); + + readTable["NORMALSPEECH "] = quickReaderMacro("(movie.normalSpeech skipping $$1 $$2 $$3 cc)"); + readTable["INTERRUPTEDSPEECH "] = quickReaderMacro("(movie.interruptedSpeech skipping $$1 $$2 $$3 cc)"); + readTable["OFFSCREENSPEECH "] = quickReaderMacro("(movie.offScreenSpeech skipping $$1 $$2 $$3 cc)"); + readTable["VOICEOVER "] = quickReaderMacro("(movie.voiceOver skipping $$1 $$2 $$3 cc)"); + readTable["ONPHONESPEECH "] = quickReaderMacro("(movie.onPhoneSpeech skipping $$1 $$2 $$3 cc)"); + + readTable["ADDPROP "] = quickReaderMacro("(movie.addProp $$1 $$2 cc)"); + readTable["REMOVEPROP "] = quickReaderMacro("(movie.removeProp $$1 cc)"); + readTable["CLEARPROPS\n"] = quickReaderMacro("(movie.clearProps cc)"); + + readTable["DELAY "] = quickReaderMacro("(movie.delay skipping $$1 cc $$2)"); + + readTable["ADDCHARACTER "] = quickReaderMacro("(movie.addCharacter $$1 $$2 $$3 cc)"); + readTable["MOVECHARACTER "] = quickReaderMacro("(movie.moveCharacter $$1 $$2 $$3 cc)"); + readTable["SWAPCHARACTERS "] = quickReaderMacro("(movie.swapCharacters $$1 $$2 cc)"); + readTable["REMOVECHARACTER "] = quickReaderMacro("(movie.removeCharacter $$1 cc)"); + readTable["CLEARCHARACTERS\n"] = quickReaderMacro("(movie.clearCharacters cc)"); + + readTable["RESTOREPLAYMODE\n"] = quickReaderMacro("(movie.restorePlayMode cc)"); + readTable["OVERRIDEPLAYMODE "] = quickReaderMacro("(movie.overridePlayMode $$1 cc)"); + + readTable["HIDECUSTOMDIALOG\n"] = quickReaderMacro("(movie.hideCustomDialog cc)"); + + readTable["WATCHMODEDELAY "] = quickReaderMacro("(movie.watchModeDelay skipping $$1 cc)"); + readTable["OVERRIDEDELAY "] = quickReaderMacro("(movie.overridePlayMode Watch + ->(movie.delay skipping $$1 + ->(movie.restorePlayMode cc)))"); + readTable["SETSCENESONG "] = quickReaderMacro("(movie.setSceneSong $$1 $$2 $$3 cc)"); + readTable["SETCURRENTSCENESONG "] = quickReaderMacro("(movie.setCurrentSceneSong skipping $$1 cc $$2)"); + + readTable["MOVETOSCENE "] = quickReaderMacro("(movie.moveToScene skipping $$1 cc)"); + + readTable["PLAYSOUND "] = quickReaderMacro("(movie.playSound skipping $$1 cc $$2 $$3 $$4)"); + readTable["AWAITPLAYSOUND "] = quickReaderMacro("(movie.awaitPlaySound skipping $$1 cc $$2)"); + readTable["AWAITPLAYSOUNDS "] = quickReaderMacro("(movie.awaitPlaySounds skipping $$1 cc $$2)"); + readTable["STOPSOUND "] = quickReaderMacro("(movie.stopSound skipping $$1 cc)"); + readTable["LOOPSOUND "] = quickReaderMacro("(movie.loopSound skipping $$1 cc $$2 $$3)"); + + readTable["PLAYSONG "] = quickReaderMacro("(movie.playSong skipping $$1 cc $$2 $$3 $$4)"); + readTable["CHANGESONGVOLUME "] = quickReaderMacro("(movie.changeSongVolume skipping $$1 cc)"); + + readTable["AWAITPLAYSONG "] = quickReaderMacro("(movie.awaitPlaySong skipping $$1 cc $$2)"); + readTable["LOOPSONG "] = quickReaderMacro("(movie.loopSong skipping $$1 cc $$2)"); + readTable["STOPSONG\n"] = quickReaderMacro("(movie.stopSong skipping cc)"); + + readTable["AUTOZPROCESS "] = quickReaderMacro("(movie.autoZProcess $$1 cc)"); + + readTable["STROBECHARACTER "] = quickReaderMacro("(movie.strobeCharacter skipping $$1 $$2 $$3 cc)"); + readTable["STROBEPROP "] = quickReaderMacro("(movie.strobeProp skipping $$1 $$2 $$3 cc)"); + readTable["AWAITSTROBECHARACTER "] = quickReaderMacro("(movie.awaitStrobeCharacter skipping $$1 $$2 $$3 cc)"); + readTable["AWAITSTROBEPROP "] = quickReaderMacro("(movie.awaitStrobeProp skipping $$1 $$2 $$3 cc)"); + + // TODO implement KissInterp evaluating map literal + readTable["INTERCUT "] = quickReaderMacro("(movie.intercut $$1 cc)"); + readTable["ENDINTERCUT\n"] = quickReaderMacro("(movie.endIntercut cc)"); + + readTable["SHOWTITLECARD "] = quickReaderMacro("(movie.showTitleCard $$1 cc)"); + readTable["HIDETITLECARD\n"] = quickReaderMacro("(movie.hideTitleCard cc)"); + + readTable["CUSTOMSPEECH "] = quickReaderMacro("(movie.customSpeech skipping $$1 $$2 $$3 $$4 $$5 cc)"); + + readTable["TIMEDCUTTOBLACK "] = quickReaderMacro("(movie.timedCutToBlack skipping $$1 cc)"); + readTable["CUTTOBLACK\n"] = quickReaderMacro("(movie.cutToBlack cc)"); + readTable["ENDCUTTOBLACK\n"] = quickReaderMacro("(movie.endCutToBlack cc)"); + + readTable["ROLLCREDITS "] = quickReaderMacro("(movie.rollCredits skipping $$1 cc $$2)"); + + + // HollywooFlixel-specific: + readTable["ADDTEMPCAMERA "] = quickReaderMacro("movie.addTempCamera skipping $$1 $$2 $$3 cc)"); + readTable["REMOVETEMPCAMERA "] = quickReaderMacro("movie.removeTempCamera $$1 $$2 cc)"); + + } +} \ No newline at end of file