Initial framework for script parsing

This commit is contained in:
G2-Games 2024-09-17 17:29:29 -05:00
parent c6404f6a09
commit 866f353353
4 changed files with 320 additions and 1 deletions

1
.gitignore vendored
View file

@ -19,6 +19,7 @@ Cargo.lock
*.png *.png
*.ttf *.ttf
*.otf *.otf
*.lscr
# Ignore PAK files # Ignore PAK files
*.PAK *.PAK

View file

@ -3,7 +3,7 @@ resolver = "2"
members = [ members = [
"cz", "cz",
"pak_explorer", "pak_explorer",
"luca_pak", "utils", "luca_pak", "utils", "luca_script",
] ]
[workspace.package] [workspace.package]

11
luca_script/Cargo.toml Normal file
View file

@ -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

307
luca_script/src/main.rs Normal file
View file

@ -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<u8> for Opcode {
type Error = ();
fn try_from(value: u8) -> Result<Self, Self::Error> {
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) => (),
}
}
}