use crate::frontends::pbs::types::PbsType; use std::collections::HashMap; pub struct ContractMethod { pub id: u32, pub params: Vec, pub return_type: PbsType, } pub struct ContractRegistry { mappings: HashMap>, } 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 { 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)) } }