mirror of
https://github.com/doukutsu-rs/doukutsu-rs
synced 2025-03-25 19:40:27 +00:00
initial textscript things
This commit is contained in:
parent
ce1da83cfd
commit
6a84c732b1
|
@ -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" }
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue