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))
}
}