initial textscript things

This commit is contained in:
Alula 2020-08-23 04:17:45 +02:00
parent ce1da83cfd
commit 6a84c732b1
No known key found for this signature in database
GPG Key ID: 3E00485503A1D8BA
3 changed files with 155 additions and 4 deletions

View File

@ -33,6 +33,7 @@ maplit = "1.0.2"
mint = "0.5"
nalgebra = {version = "0.18", features = ["mint"] }
num-traits = "0.2.12"
owning_ref = "0.4.1"
paste = "1.0.0"
pretty_env_logger = "0.4.0"
serde = "1"
@ -41,5 +42,5 @@ smart-default = "0.5"
strum = "0.18.0"
strum_macros = "0.18.0"
toml = "0.5"
owning_ref = "0.4.1"
varint = "0.9.0"
winit = { version = "0.19.3" }

View File

@ -8,6 +8,7 @@ use log::info;
use crate::ggez::{Context, filesystem, GameResult};
use crate::ggez::GameError::ResourceLoadError;
use crate::map::Map;
use crate::text_script::TextScript;
#[derive(Debug, PartialEq, Eq, Hash)]
pub struct NpcType {
@ -371,17 +372,22 @@ impl StageData {
pub struct Stage {
pub map: Map,
pub data: StageData,
pub text_script: TextScript,
}
impl Stage {
pub fn load(ctx: &mut Context, root: &str, data: &StageData) -> GameResult<Self> {
let map_file = filesystem::open(ctx, [root, "Stage/", &data.map, ".pxm"].join(""))?;
let attrib_file = filesystem::open(ctx, [root, "Stage/", &data.tileset.name, ".pxa"].join(""))?;
let tsc_file = filesystem::open(ctx, [root, "Stage/", &data.tileset.name, ".tsc"].join(""))?;
let map = Map::load_from(map_file, attrib_file)?;
let text_script = TextScript::load_from(tsc_file)?;
let stage = Self {
map,
data: data.clone(),
text_script,
};
Ok(stage)

View File

@ -1,11 +1,155 @@
use crate::ggez::{Context, GameResult};
use std::io;
struct TextScript {
use crate::ggez::GameResult;
/// Engine's internal text script VM operation codes.
/// Based on https://www.cavestory.org/guides/basicmodding/guide/tscnotes.htm and game reverse engineering.
pub enum OpCode {
// ---- Internal opcodes (used by bytecode, no TSC representation)
/// internal: no operation
NOP,
// ---- Official opcodes ----
/// <BOAxxxx, start boss animation
BOA,
/// <BSLxxxx, start boss fight
BSL,
/// <FOBxxxx, Focus on boss
FOB,
FOM,
FON,
FLA,
QUA,
UNI,
HMC,
SMC,
MM0,
MOV,
MYB,
MYD,
TRA,
END,
FRE,
FAI,
FAO,
WAI,
WAS,
KEY,
PRI,
NOD,
CAT,
SAT,
TUR,
CLO,
CLR,
FAC,
GIT,
MS2,
MS3,
MSG,
NUM,
ANP,
CNP,
INP,
MNP,
DNA,
DNP,
SNP,
FLm,
FLp,
MPp,
SKm,
SKp,
EQp,
EQm,
MLp,
ITp,
ITm,
AMp,
AMm,
TAM,
UNJ,
NCJ,
ECJ,
FLJ,
ITJ,
MPJ,
YNJ,
SKJ,
EVE,
AMJ,
MLP,
MNA,
CMP,
SMP,
CRE,
XX1,
CIL,
SIL,
ESC,
INI,
LDP,
PSp,
SLP,
ZAM,
AEp,
LIp,
SVP,
STC,
SOU,
CMU,
FMU,
RMU,
CPS,
SPS,
CSS,
SSS,
// ---- Custom opcodes, for use by modders ----
}
pub struct TextScript {}
impl TextScript {
pub fn load(filename: &str, ctx: &mut Context) -> GameResult<TextScript> {
/// Loads, decrypts and compiles a text script from specified stream.
pub fn load_from<R: io::Read>(mut data: R) -> GameResult<TextScript> {
let mut buf = Vec::new();
data.read_to_end(&mut buf)?;
let half = buf.len() / 2;
let key = if let Some(0) = buf.get(half) {
0xf9
} else {
(-(*buf.get(half).unwrap() as isize)) as u8
};
for (idx, byte) in buf.iter_mut().enumerate() {
if idx == half {
continue;
}
*byte = byte.wrapping_add(key);
}
TextScript::compile(&buf)
}
/// Compiles a decrypted text script data into internal bytecode.
pub fn compile(data: &[u8]) -> GameResult<TextScript> {
println!("data: {}", String::from_utf8(data.to_vec())?);
let tsc = TextScript {};
Ok(tsc)
}