From 866f353353415781087895b6ae6d605b9a178263 Mon Sep 17 00:00:00 2001 From: G2-Games Date: Tue, 17 Sep 2024 17:29:29 -0500 Subject: [PATCH] Initial framework for script parsing --- .gitignore | 1 + Cargo.toml | 2 +- luca_script/Cargo.toml | 11 ++ luca_script/src/main.rs | 307 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 320 insertions(+), 1 deletion(-) create mode 100644 luca_script/Cargo.toml create mode 100644 luca_script/src/main.rs diff --git a/.gitignore b/.gitignore index 90faac4..4b834df 100644 --- a/.gitignore +++ b/.gitignore @@ -19,6 +19,7 @@ Cargo.lock *.png *.ttf *.otf +*.lscr # Ignore PAK files *.PAK diff --git a/Cargo.toml b/Cargo.toml index c2ad45d..1ea6e2a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,7 +3,7 @@ resolver = "2" members = [ "cz", "pak_explorer", - "luca_pak", "utils", + "luca_pak", "utils", "luca_script", ] [workspace.package] diff --git a/luca_script/Cargo.toml b/luca_script/Cargo.toml new file mode 100644 index 0000000..e5c2110 --- /dev/null +++ b/luca_script/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "luca_script" +version = "0.1.0" +edition = "2021" +authors.workspace = true + +[dependencies] +int-enum = "1.1.2" + +[lints] +workspace = true diff --git a/luca_script/src/main.rs b/luca_script/src/main.rs new file mode 100644 index 0000000..3d4fbd9 --- /dev/null +++ b/luca_script/src/main.rs @@ -0,0 +1,307 @@ +use std::{fs::File, io::Read}; + +#[allow(non_camel_case_types)] +#[repr(u8)] +#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)] +enum Opcode { + EQU, + EQUN, + EQUV, + ADD, + SUB, + MUL, + DIV, + MOD, + AND, + OR, + RANDOM, + VARSTR, + VARSTR_ADD, + SET, + FLAGCLR, + GOTO, + ONGOTO, + GOSUB, + IFY, + IFN, + RETURN, + JUMP, + FARCALL, + FARRETURN, + JUMPPOINT, + END, + STARTUP_BEGIN, + STARTUP_END, + TASKSCRVAR, + VARSTR_SET, + VARSTR_ALLOC, + ARFLAGSET, + COLORBG_SET, + SPLINE_SET, + SHAKELIST_SET, + SCISSOR_TRIANGLELIST_SET, + MESSAGE, + MESSAGE_CLEAR, + MESSAGE_WAIT, + MESSAGE_AR_SET, + SELECT, + CLOSE_WINDOW, + FADE_WINDOW, + LOG_BEGIN, + LOG_PAUSE, + LOG_END, + VOICE, + VOICE_STOP, + WAIT_COUNT, + WAIT_TIME, + WAIT_TEXTFEED, + FFSTOP, + INIT, + STOP, + IMAGELOAD, + IMAGEUPDATE, + ARC, + MOVE, + MOVE_SKIP, + ROT, + PEND, + FADE, + SCALE, + SHAKE, + SHAKELIST, + BASE, + MCMOVE, + MCARC, + MCROT, + MCSHAKE, + MCFADE, + WAIT, + WAIT_BSKIP, + DRAW, + WIPE, + FRAMEON, + FRAMEOFF, + FW, + SCISSOR, + DELAY, + RASTER, + TONE, + SCALECOSSIN, + BMODE, + SIZE, + SPLINE, + DISP, + MASK, + FACE, + SEPIA, + SEPIA_COLOR, + CUSTOMMOVE, + SWAP, + ADDCOLOR, + SUBCOLOR, + SATURATION, + CONTRAST, + PRIORITY, + UVWH, + EVSCROLL, + COLORLEVEL, + NEGA, + TONECURVE, + SKIP_SCOPE_BEGIN, + SKIP_SCOPE_END, + QUAKE, + BGM, + BGM_WAIT_START, + BGM_WAIT_FADE, + BGM_PUSH, + BGM_POP, + SE, + SE_STOP, + SE_WAIT, + SE_WAIT_COUNT, + SE_WAIT_FADE, + VOLUME, + MOVIE, + SETCGFLAG, + EX, + TROPHY, + SETBGMFLAG, + TASK, + PRINTF, + DIALOG, + VIB_PLAY, + VIB_FILE, + VIB_STOP, + CHAR_VOLUME, + SCENE_REPLAY_END, + SAVE_THUMBNAIL, + MANPU, + SCENARIO, + SCRIPTLINE, + COUNTER_SET, + COUNTER_WAIT, + UNKNOWN +} + +impl TryFrom for Opcode { + type Error = (); + + fn try_from(value: u8) -> Result { + let val = match value { + 0 => Opcode::EQU, + 1 => Opcode::EQUN, + 2 => Opcode::EQUV, + 3 => Opcode::ADD, + 4 => Opcode::SUB, + 5 => Opcode::MUL, + 6 => Opcode::DIV, + 7 => Opcode::MOD, + 8 => Opcode::AND, + 9 => Opcode::OR, + 10 => Opcode::RANDOM, + 11 => Opcode::VARSTR, + 12 => Opcode::VARSTR_ADD, + 13 => Opcode::SET, + 14 => Opcode::FLAGCLR, + 15 => Opcode::GOTO, + 16 => Opcode::ONGOTO, + 17 => Opcode::GOSUB, + 18 => Opcode::IFY, + 19 => Opcode::IFN, + 20 => Opcode::RETURN, + 21 => Opcode::JUMP, + 22 => Opcode::FARCALL, + 23 => Opcode::FARRETURN, + 24 => Opcode::JUMPPOINT, + 25 => Opcode::END, + 26 => Opcode::STARTUP_BEGIN, + 27 => Opcode::STARTUP_END, + 28 => Opcode::TASKSCRVAR, + 29 => Opcode::VARSTR_SET, + 30 => Opcode::VARSTR_ALLOC, + 31 => Opcode::ARFLAGSET, + 32 => Opcode::COLORBG_SET, + 33 => Opcode::SPLINE_SET, + 34 => Opcode::SHAKELIST_SET, + 35 => Opcode::SCISSOR_TRIANGLELIST_SET, + 36 => Opcode::MESSAGE, + 37 => Opcode::MESSAGE_CLEAR, + 38 => Opcode::MESSAGE_WAIT, + 39 => Opcode::MESSAGE_AR_SET, + 40 => Opcode::SELECT, + 41 => Opcode::CLOSE_WINDOW, + 42 => Opcode::FADE_WINDOW, + 43 => Opcode::LOG_BEGIN, + 44 => Opcode::LOG_PAUSE, + 45 => Opcode::LOG_END, + 46 => Opcode::VOICE, + 47 => Opcode::VOICE_STOP, + 48 => Opcode::WAIT_COUNT, + 49 => Opcode::WAIT_TIME, + 50 => Opcode::WAIT_TEXTFEED, + 51 => Opcode::FFSTOP, + 52 => Opcode::INIT, + 53 => Opcode::STOP, + 54 => Opcode::IMAGELOAD, + 55 => Opcode::IMAGEUPDATE, + 56 => Opcode::ARC, + 57 => Opcode::MOVE, + 58 => Opcode::MOVE_SKIP, + 59 => Opcode::ROT, + 60 => Opcode::PEND, + 61 => Opcode::FADE, + 62 => Opcode::SCALE, + 63 => Opcode::SHAKE, + 64 => Opcode::SHAKELIST, + 65 => Opcode::BASE, + 66 => Opcode::MCMOVE, + 67 => Opcode::MCARC, + 68 => Opcode::MCROT, + 69 => Opcode::MCSHAKE, + 70 => Opcode::MCFADE, + 71 => Opcode::WAIT, + 72 => Opcode::WAIT_BSKIP, + 73 => Opcode::DRAW, + 74 => Opcode::WIPE, + 75 => Opcode::FRAMEON, + 76 => Opcode::FRAMEOFF, + 77 => Opcode::FW, + 78 => Opcode::SCISSOR, + 79 => Opcode::DELAY, + 80 => Opcode::RASTER, + 81 => Opcode::TONE, + 82 => Opcode::SCALECOSSIN, + 83 => Opcode::BMODE, + 84 => Opcode::SIZE, + 85 => Opcode::SPLINE, + 86 => Opcode::DISP, + 87 => Opcode::MASK, + 88 => Opcode::FACE, + 89 => Opcode::SEPIA, + 90 => Opcode::SEPIA_COLOR, + 91 => Opcode::CUSTOMMOVE, + 92 => Opcode::SWAP, + 93 => Opcode::ADDCOLOR, + 94 => Opcode::SUBCOLOR, + 95 => Opcode::SATURATION, + 96 => Opcode::CONTRAST, + 97 => Opcode::PRIORITY, + 98 => Opcode::UVWH, + 99 => Opcode::EVSCROLL, + 100 => Opcode::COLORLEVEL, + 101 => Opcode::NEGA, + 102 => Opcode::TONECURVE, + 103 => Opcode::SKIP_SCOPE_BEGIN, + 104 => Opcode::SKIP_SCOPE_END, + 105 => Opcode::QUAKE, + 106 => Opcode::BGM, + 107 => Opcode::BGM_WAIT_START, + 108 => Opcode::BGM_WAIT_FADE, + 109 => Opcode::BGM_PUSH, + 110 => Opcode::BGM_POP, + 111 => Opcode::SE, + 112 => Opcode::SE_STOP, + 113 => Opcode::SE_WAIT, + 114 => Opcode::SE_WAIT_COUNT, + 115 => Opcode::SE_WAIT_FADE, + 116 => Opcode::VOLUME, + 117 => Opcode::MOVIE, + 118 => Opcode::SETCGFLAG, + 119 => Opcode::EX, + 120 => Opcode::TROPHY, + 121 => Opcode::SETBGMFLAG, + 122 => Opcode::TASK, + 123 => Opcode::PRINTF, + 124 => Opcode::DIALOG, + 125 => Opcode::VIB_PLAY, + 126 => Opcode::VIB_FILE, + 127 => Opcode::VIB_STOP, + 128 => Opcode::CHAR_VOLUME, + 129 => Opcode::SCENE_REPLAY_END, + 130 => Opcode::SAVE_THUMBNAIL, + 131 => Opcode::MANPU, + 132 => Opcode::SCENARIO, + 133 => Opcode::SCRIPTLINE, + 134 => Opcode::COUNTER_SET, + 135 => Opcode::COUNTER_WAIT, + _ => return Err(()), + }; + + Ok(val) + } +} + +fn main() { + let script = File::open("LOOPERS_scenario_01").unwrap(); + + for byte in script.bytes().enumerate() { + match Opcode::try_from(byte.1.unwrap()) { + Ok(v) => { + if v == Opcode::MESSAGE { + println!("{:0X?}: {:?}", byte.0, v) + } + }, + Err(e) => (), + } + } +}