295 lines
11 KiB
Rust
295 lines
11 KiB
Rust
use crate::frontends::pbs::types::PbsType;
|
|
use std::collections::HashMap;
|
|
|
|
pub struct ContractMethod {
|
|
pub id: u32,
|
|
pub params: Vec<PbsType>,
|
|
pub return_type: PbsType,
|
|
}
|
|
|
|
pub struct ContractRegistry {
|
|
mappings: HashMap<String, HashMap<String, ContractMethod>>,
|
|
}
|
|
|
|
impl ContractRegistry {
|
|
pub fn new() -> Self {
|
|
let mut mappings = HashMap::new();
|
|
|
|
// GFX mappings
|
|
let mut gfx = HashMap::new();
|
|
gfx.insert("clear".to_string(), ContractMethod {
|
|
id: 0x1010,
|
|
params: vec![PbsType::Struct("Color".to_string())],
|
|
return_type: PbsType::Void,
|
|
});
|
|
gfx.insert("fillRect".to_string(), ContractMethod {
|
|
id: 0x1002,
|
|
params: vec![PbsType::Int, PbsType::Int, PbsType::Int, PbsType::Int, PbsType::Struct("Color".to_string())],
|
|
return_type: PbsType::Void,
|
|
});
|
|
gfx.insert("drawLine".to_string(), ContractMethod {
|
|
id: 0x1003,
|
|
params: vec![PbsType::Int, PbsType::Int, PbsType::Int, PbsType::Int, PbsType::Struct("Color".to_string())],
|
|
return_type: PbsType::Void,
|
|
});
|
|
gfx.insert("drawCircle".to_string(), ContractMethod {
|
|
id: 0x1004,
|
|
params: vec![PbsType::Int, PbsType::Int, PbsType::Int, PbsType::Struct("Color".to_string())],
|
|
return_type: PbsType::Void,
|
|
});
|
|
gfx.insert("drawDisc".to_string(), ContractMethod {
|
|
id: 0x1005,
|
|
params: vec![PbsType::Int, PbsType::Int, PbsType::Int, PbsType::Struct("Color".to_string())],
|
|
return_type: PbsType::Void,
|
|
});
|
|
gfx.insert("drawSquare".to_string(), ContractMethod {
|
|
id: 0x1006,
|
|
params: vec![PbsType::Int, PbsType::Int, PbsType::Int, PbsType::Struct("Color".to_string())],
|
|
return_type: PbsType::Void,
|
|
});
|
|
gfx.insert("setSprite".to_string(), ContractMethod {
|
|
id: 0x1007,
|
|
params: vec![PbsType::Int, PbsType::Int, PbsType::Int],
|
|
return_type: PbsType::Void,
|
|
});
|
|
gfx.insert("drawText".to_string(), ContractMethod {
|
|
id: 0x1008,
|
|
params: vec![PbsType::Int, PbsType::Int, PbsType::String, PbsType::Struct("Color".to_string())],
|
|
return_type: PbsType::Void,
|
|
});
|
|
mappings.insert("Gfx".to_string(), gfx);
|
|
|
|
// Input legacy mappings (kept for backward compatibility)
|
|
let mut input = HashMap::new();
|
|
input.insert("pad".to_string(), ContractMethod {
|
|
id: 0x2010,
|
|
params: vec![],
|
|
return_type: PbsType::Struct("Pad".to_string()),
|
|
});
|
|
input.insert("touch".to_string(), ContractMethod {
|
|
id: 0x2011,
|
|
params: vec![],
|
|
return_type: PbsType::Struct("Touch".to_string()),
|
|
});
|
|
mappings.insert("Input".to_string(), input);
|
|
|
|
// New Pad service-based mappings (each button as a method returning Button)
|
|
let mut pad = HashMap::new();
|
|
// NOTE: The syscalls for per-button access must be handled by the runtime.
|
|
// We reserve the 0x2200..0x220B range for Pad buttons returning a Button struct (6 bytes).
|
|
pad.insert("up".to_string(), ContractMethod {
|
|
id: 0x2200,
|
|
params: vec![],
|
|
return_type: PbsType::Struct("Button".to_string()),
|
|
});
|
|
pad.insert("down".to_string(), ContractMethod {
|
|
id: 0x2201,
|
|
params: vec![],
|
|
return_type: PbsType::Struct("Button".to_string()),
|
|
});
|
|
pad.insert("left".to_string(), ContractMethod {
|
|
id: 0x2202,
|
|
params: vec![],
|
|
return_type: PbsType::Struct("Button".to_string()),
|
|
});
|
|
pad.insert("right".to_string(), ContractMethod {
|
|
id: 0x2203,
|
|
params: vec![],
|
|
return_type: PbsType::Struct("Button".to_string()),
|
|
});
|
|
pad.insert("a".to_string(), ContractMethod {
|
|
id: 0x2204,
|
|
params: vec![],
|
|
return_type: PbsType::Struct("Button".to_string()),
|
|
});
|
|
pad.insert("b".to_string(), ContractMethod {
|
|
id: 0x2205,
|
|
params: vec![],
|
|
return_type: PbsType::Struct("Button".to_string()),
|
|
});
|
|
pad.insert("x".to_string(), ContractMethod {
|
|
id: 0x2206,
|
|
params: vec![],
|
|
return_type: PbsType::Struct("Button".to_string()),
|
|
});
|
|
pad.insert("y".to_string(), ContractMethod {
|
|
id: 0x2207,
|
|
params: vec![],
|
|
return_type: PbsType::Struct("Button".to_string()),
|
|
});
|
|
pad.insert("l".to_string(), ContractMethod {
|
|
id: 0x2208,
|
|
params: vec![],
|
|
return_type: PbsType::Struct("Button".to_string()),
|
|
});
|
|
pad.insert("r".to_string(), ContractMethod {
|
|
id: 0x2209,
|
|
params: vec![],
|
|
return_type: PbsType::Struct("Button".to_string()),
|
|
});
|
|
pad.insert("start".to_string(), ContractMethod {
|
|
id: 0x220A,
|
|
params: vec![],
|
|
return_type: PbsType::Struct("Button".to_string()),
|
|
});
|
|
pad.insert("select".to_string(), ContractMethod {
|
|
id: 0x220B,
|
|
params: vec![],
|
|
return_type: PbsType::Struct("Button".to_string()),
|
|
});
|
|
mappings.insert("Pad".to_string(), pad);
|
|
|
|
// Touch mappings (service-based)
|
|
let mut touch = HashMap::new();
|
|
// SDK agora expõe screen_x/screen_y/finger()
|
|
touch.insert("screen_x".to_string(), ContractMethod {
|
|
id: 0x2101,
|
|
params: vec![],
|
|
return_type: PbsType::Int,
|
|
});
|
|
touch.insert("screen_y".to_string(), ContractMethod {
|
|
id: 0x2102,
|
|
params: vec![],
|
|
return_type: PbsType::Int,
|
|
});
|
|
// Novo syscall dedicado para retornar Button completo do touch (dedo)
|
|
touch.insert("finger".to_string(), ContractMethod {
|
|
id: 0x2107,
|
|
params: vec![],
|
|
return_type: PbsType::Struct("Button".to_string()),
|
|
});
|
|
mappings.insert("Touch".to_string(), touch);
|
|
|
|
// Audio mappings
|
|
let mut audio = HashMap::new();
|
|
audio.insert("playSample".to_string(), ContractMethod {
|
|
id: 0x3001,
|
|
params: vec![PbsType::Int],
|
|
return_type: PbsType::Void,
|
|
});
|
|
audio.insert("play".to_string(), ContractMethod {
|
|
id: 0x3002,
|
|
params: vec![PbsType::Int],
|
|
return_type: PbsType::Void,
|
|
});
|
|
mappings.insert("Audio".to_string(), audio);
|
|
|
|
// FS mappings
|
|
let mut fs = HashMap::new();
|
|
fs.insert("open".to_string(), ContractMethod {
|
|
id: 0x4001,
|
|
params: vec![PbsType::String, PbsType::String],
|
|
return_type: PbsType::Int,
|
|
});
|
|
fs.insert("read".to_string(), ContractMethod {
|
|
id: 0x4002,
|
|
params: vec![PbsType::Int],
|
|
return_type: PbsType::String,
|
|
});
|
|
fs.insert("write".to_string(), ContractMethod {
|
|
id: 0x4003,
|
|
params: vec![PbsType::Int, PbsType::String],
|
|
return_type: PbsType::Int,
|
|
});
|
|
fs.insert("close".to_string(), ContractMethod {
|
|
id: 0x4004,
|
|
params: vec![PbsType::Int],
|
|
return_type: PbsType::Void,
|
|
});
|
|
fs.insert("listDir".to_string(), ContractMethod {
|
|
id: 0x4005,
|
|
params: vec![PbsType::String],
|
|
return_type: PbsType::String,
|
|
});
|
|
fs.insert("exists".to_string(), ContractMethod {
|
|
id: 0x4006,
|
|
params: vec![PbsType::String],
|
|
return_type: PbsType::Bool,
|
|
});
|
|
fs.insert("delete".to_string(), ContractMethod {
|
|
id: 0x4007,
|
|
params: vec![PbsType::String],
|
|
return_type: PbsType::Bool,
|
|
});
|
|
mappings.insert("Fs".to_string(), fs);
|
|
|
|
// Log mappings (host)
|
|
let mut log = HashMap::new();
|
|
log.insert("write".to_string(), ContractMethod {
|
|
id: 0x5001,
|
|
params: vec![PbsType::Int, PbsType::String],
|
|
// Log syscalls não retornam valor (void) — evita lixo de pilha
|
|
return_type: PbsType::Void,
|
|
});
|
|
log.insert("writeTag".to_string(), ContractMethod {
|
|
id: 0x5002,
|
|
params: vec![PbsType::Int, PbsType::Int, PbsType::String],
|
|
return_type: PbsType::Void,
|
|
});
|
|
// O contrato host exposto no SDK é LogHost (não-público)
|
|
mappings.insert("LogHost".to_string(), log);
|
|
|
|
// System mappings
|
|
let mut system = HashMap::new();
|
|
system.insert("hasCart".to_string(), ContractMethod {
|
|
id: 0x0001,
|
|
params: vec![],
|
|
return_type: PbsType::Bool,
|
|
});
|
|
system.insert("runCart".to_string(), ContractMethod {
|
|
id: 0x0002,
|
|
params: vec![],
|
|
return_type: PbsType::Void,
|
|
});
|
|
mappings.insert("System".to_string(), system);
|
|
|
|
// Asset mappings
|
|
let mut asset = HashMap::new();
|
|
asset.insert("load".to_string(), ContractMethod {
|
|
id: 0x6001,
|
|
params: vec![PbsType::String],
|
|
return_type: PbsType::Int,
|
|
});
|
|
asset.insert("status".to_string(), ContractMethod {
|
|
id: 0x6002,
|
|
params: vec![PbsType::Int],
|
|
return_type: PbsType::Int,
|
|
});
|
|
asset.insert("commit".to_string(), ContractMethod {
|
|
id: 0x6003,
|
|
params: vec![PbsType::Int],
|
|
return_type: PbsType::Void,
|
|
});
|
|
asset.insert("cancel".to_string(), ContractMethod {
|
|
id: 0x6004,
|
|
params: vec![PbsType::Int],
|
|
return_type: PbsType::Void,
|
|
});
|
|
mappings.insert("Asset".to_string(), asset);
|
|
|
|
// Bank mappings
|
|
let mut bank = HashMap::new();
|
|
bank.insert("info".to_string(), ContractMethod {
|
|
id: 0x6101,
|
|
params: vec![PbsType::Int],
|
|
return_type: PbsType::String,
|
|
});
|
|
bank.insert("slotInfo".to_string(), ContractMethod {
|
|
id: 0x6102,
|
|
params: vec![PbsType::Int, PbsType::Int],
|
|
return_type: PbsType::String,
|
|
});
|
|
mappings.insert("Bank".to_string(), bank);
|
|
|
|
Self { mappings }
|
|
}
|
|
|
|
pub fn resolve(&self, contract: &str, method: &str) -> Option<u32> {
|
|
self.mappings.get(contract).and_then(|m| m.get(method)).map(|m| m.id)
|
|
}
|
|
|
|
pub fn get_method(&self, contract: &str, method: &str) -> Option<&ContractMethod> {
|
|
self.mappings.get(contract).and_then(|m| m.get(method))
|
|
}
|
|
}
|