PR002: implement gfx status-first contract for set_sprite
This commit is contained in:
parent
b241db7011
commit
fe6931d420
@ -80,7 +80,7 @@ pub(crate) const ENTRIES: &[SyscallRegistryEntry] = &[
|
|||||||
"set_sprite",
|
"set_sprite",
|
||||||
1,
|
1,
|
||||||
10,
|
10,
|
||||||
0,
|
1,
|
||||||
caps::GFX,
|
caps::GFX,
|
||||||
Determinism::Deterministic,
|
Determinism::Deterministic,
|
||||||
false,
|
false,
|
||||||
|
|||||||
@ -10,6 +10,11 @@ use prometeu_hal::vm_fault::VmFault;
|
|||||||
use prometeu_hal::{HostContext, HostReturn, NativeInterface, SyscallId, expect_bool, expect_int};
|
use prometeu_hal::{HostContext, HostReturn, NativeInterface, SyscallId, expect_bool, expect_int};
|
||||||
|
|
||||||
impl VirtualMachineRuntime {
|
impl VirtualMachineRuntime {
|
||||||
|
const GFX_STATUS_OK: i64 = 0;
|
||||||
|
const GFX_STATUS_ASSET_NOT_FOUND: i64 = 1;
|
||||||
|
const GFX_STATUS_INVALID_SPRITE_INDEX: i64 = 2;
|
||||||
|
const GFX_STATUS_INVALID_ARG_RANGE: i64 = 3;
|
||||||
|
|
||||||
fn syscall_log_write(&mut self, level_val: i64, tag: u16, msg: String) -> Result<(), VmFault> {
|
fn syscall_log_write(&mut self, level_val: i64, tag: u16, msg: String) -> Result<(), VmFault> {
|
||||||
let level = match level_val {
|
let level = match level_val {
|
||||||
0 => LogLevel::Trace,
|
0 => LogLevel::Trace,
|
||||||
@ -147,21 +152,30 @@ impl NativeInterface for VirtualMachineRuntime {
|
|||||||
let flip_y = expect_bool(args, 8)?;
|
let flip_y = expect_bool(args, 8)?;
|
||||||
let priority = expect_int(args, 9)? as u8;
|
let priority = expect_int(args, 9)? as u8;
|
||||||
|
|
||||||
let bank_id =
|
if index >= 512 {
|
||||||
hw.assets().find_slot_by_name(&asset_name, BankType::TILES).unwrap_or(0);
|
ret.push_int(Self::GFX_STATUS_INVALID_SPRITE_INDEX);
|
||||||
|
return Ok(());
|
||||||
if index < 512 {
|
|
||||||
*hw.gfx_mut().sprite_mut(index) = Sprite {
|
|
||||||
tile: Tile { id: tile_id, flip_x: false, flip_y: false, palette_id },
|
|
||||||
x,
|
|
||||||
y,
|
|
||||||
bank_id,
|
|
||||||
active,
|
|
||||||
flip_x,
|
|
||||||
flip_y,
|
|
||||||
priority,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
if palette_id >= 64 || priority >= 5 {
|
||||||
|
ret.push_int(Self::GFX_STATUS_INVALID_ARG_RANGE);
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
let Some(bank_id) = hw.assets().find_slot_by_name(&asset_name, BankType::TILES) else {
|
||||||
|
ret.push_int(Self::GFX_STATUS_ASSET_NOT_FOUND);
|
||||||
|
return Ok(());
|
||||||
|
};
|
||||||
|
|
||||||
|
*hw.gfx_mut().sprite_mut(index) = Sprite {
|
||||||
|
tile: Tile { id: tile_id, flip_x: false, flip_y: false, palette_id },
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
bank_id,
|
||||||
|
active,
|
||||||
|
flip_x,
|
||||||
|
flip_y,
|
||||||
|
priority,
|
||||||
|
};
|
||||||
|
ret.push_int(Self::GFX_STATUS_OK);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
Syscall::GfxDrawText => {
|
Syscall::GfxDrawText => {
|
||||||
|
|||||||
@ -511,3 +511,32 @@ The system can measure:
|
|||||||
- `palettes_referenced_this_frame`
|
- `palettes_referenced_this_frame`
|
||||||
- `tiles_drawn_by_palette_id`
|
- `tiles_drawn_by_palette_id`
|
||||||
- `sprites_drawn_by_palette_id`
|
- `sprites_drawn_by_palette_id`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 19. Syscall Return and Fault Policy
|
||||||
|
|
||||||
|
`gfx` follows status-first policy for operations with operational failure modes.
|
||||||
|
|
||||||
|
Fault boundary:
|
||||||
|
|
||||||
|
- `Trap`: structural ABI misuse (type/arity/capability/shape mismatch);
|
||||||
|
- `status`: operational failure;
|
||||||
|
- `Panic`: internal runtime invariant break only.
|
||||||
|
|
||||||
|
### 19.1 `gfx.set_sprite`
|
||||||
|
|
||||||
|
`gfx.set_sprite` returns `status:int`.
|
||||||
|
|
||||||
|
Minimum status table:
|
||||||
|
|
||||||
|
- `0` = `OK`
|
||||||
|
- `1` = `ASSET_NOT_FOUND`
|
||||||
|
- `2` = `INVALID_SPRITE_INDEX`
|
||||||
|
- `3` = `INVALID_ARG_RANGE`
|
||||||
|
|
||||||
|
Operational notes:
|
||||||
|
|
||||||
|
- no fallback to default bank when the sprite asset name cannot be resolved;
|
||||||
|
- no silent no-op for invalid index/range;
|
||||||
|
- `palette_id` and `priority` must be validated against runtime-supported ranges.
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user