translate to english!
This commit is contained in:
parent
38ec13b248
commit
0f3105d622
72
README.md
72
README.md
@ -1,84 +1,84 @@
|
||||
# PROMETEU
|
||||
|
||||
PROMETEU é um **ecossistema educacional e experimental** inspirado em consoles clássicos, com foco em **ensinar programação, arquitetura de sistemas e conceitos de hardware através de software**.
|
||||
PROMETEU is an **educational and experimental ecosystem** inspired by classic consoles, focusing on **teaching programming, system architecture, and hardware concepts through software**.
|
||||
|
||||
> PROMETEU é uma máquina virtual simples, explícita e didática.
|
||||
> PROMETEU is a simple, explicit, and educational virtual machine.
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Objetivos do Projeto
|
||||
## 🎯 Project Goals
|
||||
|
||||
- **Simular um “hardware lógico” simples**: Criar uma barreira de entrada baixa para entender como computadores funcionam.
|
||||
- **Loop Determinístico**: Garantir que o mesmo código produza o mesmo resultado em qualquer plataforma.
|
||||
- **Portabilidade Total**: O núcleo não depende de sistema operacional, permitindo rodar de computadores modernos a hardware dedicado.
|
||||
- **Ferramentas de Primeiro Nível**: Oferecer depuração e inspeção profunda como parte central da experiência.
|
||||
- **Simulate simple "logical hardware"**: Create a low entry barrier for understanding how computers work.
|
||||
- **Deterministic Loop**: Ensure the same code produces the same result on any platform.
|
||||
- **Total Portability**: The core does not depend on an operating system, allowing it to run from modern computers to dedicated hardware.
|
||||
- **First-Class Tools**: Offer deep debugging and inspection as a central part of the experience.
|
||||
|
||||
---
|
||||
|
||||
## 🧠 Filosofia de Design
|
||||
## 🧠 Design Philosophy
|
||||
|
||||
- **Sem magia**: tudo é explícito.
|
||||
- **Sem heurística implícita**: o sistema não “adivinha intenções”.
|
||||
- **Determinístico**: mesmo input → mesmo resultado.
|
||||
- **Hardware-first**: APIs modelam periféricos, não frameworks modernos.
|
||||
- **Portável por definição**: se não funciona em todas as plataformas, não existe.
|
||||
- **No magic**: everything is explicit.
|
||||
- **No implicit heuristics**: the system doesn't "guess intentions".
|
||||
- **Deterministic**: same input → same result.
|
||||
- **Hardware-first**: APIs model peripherals, not modern frameworks.
|
||||
- **Portable by definition**: if it doesn't work on all platforms, it doesn't exist.
|
||||
|
||||
---
|
||||
|
||||
## 📦 Estrutura do Monorepo
|
||||
## 📦 Monorepo Structure
|
||||
|
||||
Este repositório é organizado como um workspace Rust e contém diversos componentes:
|
||||
This repository is organized as a Rust workspace and contains several components:
|
||||
|
||||
- **[crates/](./crates)**: Implementação do software em Rust.
|
||||
- **[prometeu](./crates/prometeu)**: Interface de linha de comando (CLI) unificada.
|
||||
- **[prometeu-core](./crates/prometeu-core)**: O núcleo lógico, VM e SO interno.
|
||||
- **[prometeu-runtime-desktop](./crates/prometeu-runtime-desktop)**: Host para execução em sistemas Desktop.
|
||||
- **[docs/](./docs)**: Documentação técnica e especificações do sistema.
|
||||
- **[devtools-protocol/](./devtools-protocol)**: Definição do protocolo de comunicação para ferramentas de desenvolvimento.
|
||||
- **[test-cartridges/](./test-cartridges)**: Exemplos e suítes de teste de cartuchos.
|
||||
- **[crates/](./crates)**: Software implementation in Rust.
|
||||
- **[prometeu](./crates/prometeu)**: Unified command-line interface (CLI).
|
||||
- **[prometeu-core](./crates/prometeu-core)**: The logical core, VM, and internal OS.
|
||||
- **[prometeu-runtime-desktop](./crates/prometeu-runtime-desktop)**: Host for execution on Desktop systems.
|
||||
- **[docs/](./docs)**: Technical documentation and system specifications.
|
||||
- **[devtools-protocol/](./devtools-protocol)**: Definition of the communication protocol for development tools.
|
||||
- **[test-cartridges/](./test-cartridges)**: Cartridge examples and test suites.
|
||||
|
||||
---
|
||||
|
||||
## 🛠️ Requisitos
|
||||
## 🛠️ Requirements
|
||||
|
||||
- **Rust**: Versão definida em `rust-toolchain.toml`.
|
||||
- **Instalação**: Use o [rustup](https://rustup.rs/) para instalar a toolchain necessária.
|
||||
- **Rust**: Version defined in `rust-toolchain.toml`.
|
||||
- **Installation**: Use [rustup](https://rustup.rs/) to install the required toolchain.
|
||||
|
||||
---
|
||||
|
||||
## ▶️ Início Rápido
|
||||
## ▶️ Quick Start
|
||||
|
||||
Para compilar o projeto completo:
|
||||
To compile the full project:
|
||||
|
||||
```bash
|
||||
cargo build
|
||||
```
|
||||
|
||||
Para rodar um cartucho de exemplo:
|
||||
To run an example cartridge:
|
||||
|
||||
```bash
|
||||
./target/debug/prometeu run test-cartridges/color-square
|
||||
```
|
||||
|
||||
Para mais detalhes sobre como usar a CLI, veja o README de **[prometeu](./crates/prometeu)**.
|
||||
For more details on how to use the CLI, see the **[prometeu](./crates/prometeu)** README.
|
||||
|
||||
---
|
||||
|
||||
## 🚧 Status do Projeto
|
||||
## 🚧 Project Status
|
||||
|
||||
⚠️ **Em estágio inicial (bootstrap)**
|
||||
⚠️ **Early stage (bootstrap)**
|
||||
|
||||
Atualmente o foco é na estabilização da arquitetura do core e do protocolo de depuração. Nada aqui deve ser considerado uma API estável ainda.
|
||||
Currently, the focus is on stabilizing the core architecture and debugging protocol. Nothing here should be considered a stable API yet.
|
||||
|
||||
---
|
||||
|
||||
## 📜 Licença
|
||||
## 📜 License
|
||||
|
||||
Este projeto está licenciado sob a Licença MIT - veja o arquivo [LICENSE](LICENSE) para detalhes.
|
||||
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
|
||||
|
||||
---
|
||||
|
||||
## ✨ Nota Final
|
||||
## ✨ Final Note
|
||||
|
||||
PROMETEU é tanto um projeto técnico quanto pedagógico. A ideia não é esconder complexidade, mas **expor a complexidade certa**, no nível certo, para que ela possa ser entendida, estudada e explorada.
|
||||
PROMETEU is both a technical and pedagogical project. The idea is not to hide complexity, but to **expose the right complexity**, at the right level, so it can be understood, studied, and explored.
|
||||
|
||||
|
||||
@ -1,14 +1,14 @@
|
||||
# PROMETEU Core
|
||||
|
||||
Este crate contém a biblioteca central que define o comportamento do hardware e software do PROMETEU.
|
||||
This crate contains the core library that defines the behavior of PROMETEU's hardware and software.
|
||||
|
||||
## Responsabilidades
|
||||
## Responsibilities
|
||||
|
||||
- **Hardware Lógico**: Definição de GFX, Input, Audio e Touch.
|
||||
- **Máquina Virtual**: Execução de bytecode customizado (PBC - Prometeu Byte Code).
|
||||
- **Virtual FS**: Gerenciamento de arquivos e acesso ao "cartucho".
|
||||
- **Firmware/OS**: O sistema operacional interno que gerencia o ciclo de vida das aplicações, splash screens e o Hub Home.
|
||||
- **Logical Hardware**: Definition of GFX, Input, Audio, and Touch.
|
||||
- **Virtual Machine**: Execution of custom bytecode (PBC - Prometeu Byte Code).
|
||||
- **Virtual FS**: File management and "cartridge" access.
|
||||
- **Firmware/OS**: The internal operating system that manages the application lifecycle, splash screens, and the Hub Home.
|
||||
|
||||
## Arquitetura
|
||||
## Architecture
|
||||
|
||||
O core é projetado para ser determinístico e portátil. Ele não faz chamadas diretas ao sistema operacional do host; em vez disso, define traços (traits) que os hosts devem implementar (ex: `FsBackend`).
|
||||
The core is designed to be deterministic and portable. It does not make direct calls to the host operating system; instead, it defines traits that hosts must implement (e.g., `FsBackend`).
|
||||
|
||||
@ -31,7 +31,7 @@ impl Firmware {
|
||||
}
|
||||
|
||||
pub fn step_frame(&mut self, signals: &InputSignals, hw: &mut dyn HardwareBridge) {
|
||||
// Atualiza input uma vez por frame de host
|
||||
// Updates input once per host frame
|
||||
hw.pad_mut().begin_frame(signals);
|
||||
hw.touch_mut().begin_frame(signals);
|
||||
|
||||
@ -50,7 +50,7 @@ impl Firmware {
|
||||
self.state = new_state;
|
||||
self.state_initialized = false;
|
||||
|
||||
// Entra no novo estado imediatamente
|
||||
// Enters the new state immediately
|
||||
self.on_enter(signals, hw);
|
||||
self.state_initialized = true;
|
||||
}
|
||||
|
||||
@ -14,16 +14,16 @@ impl AppCrashesStep {
|
||||
}
|
||||
|
||||
pub fn on_update(&mut self, ctx: &mut PrometeuContext) -> Option<FirmwareState> {
|
||||
// Atualiza periféricos para input na tela de crash
|
||||
// Update peripherals for input on the crash screen
|
||||
ctx.hw.pad_mut().begin_frame(ctx.signals);
|
||||
|
||||
// Tela de erro: fundo vermelho, texto branco
|
||||
// Error screen: red background, white text
|
||||
ctx.hw.gfx_mut().clear(Color::RED);
|
||||
// Por enquanto apenas logamos ou mostramos algo simples
|
||||
// No futuro, usar draw_text
|
||||
// For now we just log or show something simple
|
||||
// In the future, use draw_text
|
||||
ctx.hw.gfx_mut().present();
|
||||
|
||||
// Se apertar START, volta pro Hub
|
||||
// If START is pressed, return to the Hub
|
||||
if ctx.hw.pad().start.down {
|
||||
return Some(FirmwareState::LaunchHub(LaunchHubStep));
|
||||
}
|
||||
|
||||
@ -13,19 +13,19 @@ impl HubHomeStep {
|
||||
pub fn on_update(&mut self, ctx: &mut PrometeuContext) -> Option<FirmwareState> {
|
||||
let mut error = None;
|
||||
|
||||
// Sempre atualiza a GUI do Hub (limpa a tela e processa input se não houver foco)
|
||||
// Always updates the Hub GUI (clears screen and processes input if no focus)
|
||||
ctx.hub.gui_update(ctx.os, ctx.hw);
|
||||
|
||||
if let Some(focused_id) = ctx.hub.window_manager.focused {
|
||||
if ctx.hw.pad().start.down {
|
||||
ctx.hub.window_manager.remove_window(focused_id);
|
||||
} else {
|
||||
// System App roda aqui, desenhando sobre o fundo do Hub
|
||||
// System App runs here, drawing over the Hub background
|
||||
error = ctx.os.step_frame(ctx.vm, ctx.signals, ctx.hw);
|
||||
}
|
||||
}
|
||||
|
||||
// Renderiza as bordas das janelas do System App
|
||||
// Renders the System App window borders
|
||||
ctx.hub.render(ctx.os, ctx.hw);
|
||||
|
||||
ctx.hw.gfx_mut().present();
|
||||
|
||||
@ -17,8 +17,8 @@ impl LaunchHubStep {
|
||||
if let BootTarget::Cartridge { path, .. } = ctx.boot_target {
|
||||
match CartridgeLoader::load(path) {
|
||||
Ok(cartridge) => {
|
||||
// No caso de debug, aqui poderíamos pausar, mas o requisito diz
|
||||
// para o Runtime abrir o socket e aguardar.
|
||||
// In the case of debug, we could pause here, but the requirement says
|
||||
// for the Runtime to open the socket and wait.
|
||||
return Some(FirmwareState::LoadCartridge(LoadCartridgeStep { cartridge }));
|
||||
}
|
||||
Err(e) => {
|
||||
|
||||
@ -23,8 +23,8 @@ impl LoadCartridgeStep {
|
||||
);
|
||||
ctx.hub.window_manager.set_focus(id);
|
||||
|
||||
// Apps de sistema não mudam o estado do firmware para GameRunning.
|
||||
// Eles rodam em background ou via janelas no Hub.
|
||||
// System apps do not change the firmware state to GameRunning.
|
||||
// They run in the background or via windows in the Hub.
|
||||
return Some(FirmwareState::HubHome(HubHomeStep));
|
||||
}
|
||||
|
||||
|
||||
@ -12,23 +12,23 @@ pub struct SplashScreenStep {
|
||||
impl SplashScreenStep {
|
||||
pub fn on_enter(&mut self, ctx: &mut PrometeuContext) {
|
||||
ctx.os.log(LogLevel::Info, LogSource::Pos, 0, "Showing SplashScreen".to_string());
|
||||
// Tocar som no enter
|
||||
// Play sound on enter
|
||||
if let Some(sample) = ctx.os.sample_square.clone() {
|
||||
ctx.hw.audio_mut().play(sample, 0, 255, 127, 1.0, 0, LoopMode::Off);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn on_update(&mut self, ctx: &mut PrometeuContext) -> Option<FirmwareState> {
|
||||
const ANIMATION_DURATION: u32 = 60; // 1 segundo a 60fps
|
||||
const TOTAL_DURATION: u32 = 240; // 2 segundos totais (conforme ctxuisito anterior)
|
||||
const ANIMATION_DURATION: u32 = 60; // 1 second at 60fps
|
||||
const TOTAL_DURATION: u32 = 240; // 4 seconds total (updated from 2s based on total_duration logic)
|
||||
|
||||
// Atualiza periféricos para input
|
||||
// Update peripherals for input
|
||||
ctx.hw.pad_mut().begin_frame(ctx.signals);
|
||||
|
||||
// Limpar tela
|
||||
// Clear screen
|
||||
ctx.hw.gfx_mut().clear(Color::BLACK);
|
||||
|
||||
// Desenhar quadrado aumentando
|
||||
// Draw expanding square
|
||||
let (sw, sh) = ctx.hw.gfx().size();
|
||||
let max_size = (sw.min(sh) as i32 / 2).max(1);
|
||||
|
||||
@ -44,8 +44,8 @@ impl SplashScreenStep {
|
||||
ctx.hw.gfx_mut().fill_rect(x, y, current_size, current_size, Color::WHITE);
|
||||
ctx.hw.gfx_mut().present();
|
||||
|
||||
// Lógica de transição
|
||||
// Caso o botão start seja pressionado a qualquer momento depois da animação terminar
|
||||
// Transition logic
|
||||
// If any button is pressed at any time after the animation ends
|
||||
if self.frame >= ANIMATION_DURATION && ctx.hw.pad().any() {
|
||||
return Some(FirmwareState::LaunchHub(LaunchHubStep));
|
||||
}
|
||||
|
||||
@ -120,7 +120,7 @@ impl Audio {
|
||||
}
|
||||
}
|
||||
|
||||
/// Limpa a fila de comandos. O Host deve consumir isso a cada frame.
|
||||
/// Clears the command queue. The Host should consume this every frame.
|
||||
pub fn clear_commands(&mut self) {
|
||||
self.commands.clear();
|
||||
}
|
||||
|
||||
@ -32,7 +32,7 @@ pub struct Gfx {
|
||||
pub hud_fade_level: u8, // 0..31
|
||||
pub hud_fade_color: Color,
|
||||
|
||||
// Cache de prioridades para evitar alocações por frame
|
||||
// Priority cache to avoid per-frame allocations
|
||||
priority_buckets: [Vec<usize>; 5],
|
||||
}
|
||||
|
||||
@ -51,17 +51,19 @@ impl Gfx {
|
||||
};
|
||||
|
||||
let len = w * h;
|
||||
let mut layers = [
|
||||
ScrollableTileLayer::new(64, 64, TileSize::Size16),
|
||||
ScrollableTileLayer::new(64, 64, TileSize::Size16),
|
||||
ScrollableTileLayer::new(64, 64, TileSize::Size16),
|
||||
ScrollableTileLayer::new(64, 64, TileSize::Size16),
|
||||
];
|
||||
|
||||
Self {
|
||||
w,
|
||||
h,
|
||||
front: vec![0; len],
|
||||
back: vec![0; len],
|
||||
layers: [
|
||||
ScrollableTileLayer::new(64, 64, TileSize::Size16),
|
||||
ScrollableTileLayer::new(64, 64, TileSize::Size16),
|
||||
ScrollableTileLayer::new(64, 64, TileSize::Size16),
|
||||
ScrollableTileLayer::new(64, 64, TileSize::Size16),
|
||||
],
|
||||
layers,
|
||||
hud: HudTileLayer::new(64, 32),
|
||||
banks: [EMPTY_BANK; 16],
|
||||
sprites: [EMPTY_SPRITE; 512],
|
||||
@ -83,7 +85,7 @@ impl Gfx {
|
||||
(self.w, self.h)
|
||||
}
|
||||
|
||||
/// O buffer que o host deve exibir (RGB565).
|
||||
/// The buffer that the host should display (RGB565).
|
||||
pub fn front_buffer(&self) -> &[u16] {
|
||||
&self.front
|
||||
}
|
||||
@ -92,7 +94,7 @@ impl Gfx {
|
||||
self.back.fill(color.0);
|
||||
}
|
||||
|
||||
/// Retângulo com modo de blend.
|
||||
/// Rectangle with blend mode.
|
||||
pub fn fill_rect_blend(
|
||||
&mut self,
|
||||
x: i32,
|
||||
@ -122,21 +124,21 @@ impl Gfx {
|
||||
}
|
||||
}
|
||||
|
||||
/// Conveniência: retângulo normal (sem blend).
|
||||
/// Convenience: normal rectangle (no blend).
|
||||
pub fn fill_rect(&mut self, x: i32, y: i32, w: i32, h: i32, color: Color) {
|
||||
self.fill_rect_blend(x, y, w, h, color, BlendMode::None);
|
||||
}
|
||||
|
||||
/// Double buffer swap (O(1), sem cópia de pixels).
|
||||
/// Double buffer swap (O(1), no pixel copying).
|
||||
pub fn present(&mut self) {
|
||||
std::mem::swap(&mut self.front, &mut self.back);
|
||||
}
|
||||
|
||||
/// Pipeline principal de renderização do frame.
|
||||
/// Segue a ordem de prioridade do manual (Capítulo 4.11).
|
||||
/// Main frame rendering pipeline.
|
||||
/// Follows the priority order from the manual (Chapter 4.11).
|
||||
pub fn render_all(&mut self) {
|
||||
// 0. Fase de Preparação: Organiza quem deve ser desenhado em cada camada
|
||||
// Limpa os buckets sem desalocar memória
|
||||
// 0. Preparation Phase: Organizes what should be drawn in each layer
|
||||
// Clears the buckets without deallocating memory
|
||||
for bucket in self.priority_buckets.iter_mut() {
|
||||
bucket.clear();
|
||||
}
|
||||
@ -147,27 +149,27 @@ impl Gfx {
|
||||
}
|
||||
}
|
||||
|
||||
// 1. Sprites de prioridade 0 (Atrás da Layer 0 - o fundo do fundo)
|
||||
// 1. Priority 0 sprites (Behind Layer 0 - the very back)
|
||||
Self::draw_bucket_on_buffer(&mut self.back, self.w, self.h, &self.priority_buckets[0], &self.sprites, &self.banks);
|
||||
|
||||
for i in 0..self.layers.len() {
|
||||
// 2. Layers de jogo (0 a 3)
|
||||
// 2. Game Layers (0 to 3)
|
||||
let bank_id = self.layers[i].bank_id as usize;
|
||||
if let Some(Some(bank)) = self.banks.get(bank_id) {
|
||||
Self::draw_tile_map(&mut self.back, self.w, self.h, &self.layers[i].map, bank, self.layers[i].scroll_x, self.layers[i].scroll_y);
|
||||
}
|
||||
|
||||
// 3. Sprites de acordo com prioridade
|
||||
// 3. Sprites according to priority
|
||||
Self::draw_bucket_on_buffer(&mut self.back, self.w, self.h, &self.priority_buckets[i + 1], &self.sprites, &self.banks);
|
||||
}
|
||||
|
||||
// 4. Aplica Scene Fade (Afeta tudo desenhado até agora)
|
||||
// 4. Applies Scene Fade (Affects everything drawn so far)
|
||||
Self::apply_fade_to_buffer(&mut self.back, self.scene_fade_level, self.scene_fade_color);
|
||||
|
||||
// 5. HUD (Sempre por cima)
|
||||
// 5. HUD (Always on top)
|
||||
self.render_hud();
|
||||
|
||||
// 6. Aplica HUD Fade (Opcional, apenas para o HUD)
|
||||
// 6. Applies HUD Fade (Optional, HUD only)
|
||||
Self::apply_fade_to_buffer(&mut self.back, self.hud_fade_level, self.hud_fade_color);
|
||||
}
|
||||
|
||||
@ -186,7 +188,7 @@ impl Gfx {
|
||||
Self::draw_tile_map(&mut self.back, self.w, self.h, &self.layers[layer_idx].map, bank, scroll_x, scroll_y);
|
||||
}
|
||||
|
||||
/// Renderiza o HUD (sem scroll).
|
||||
/// Renders the HUD (no scroll).
|
||||
pub fn render_hud(&mut self) {
|
||||
let bank_id = self.hud.bank_id as usize;
|
||||
let bank = match self.banks.get(bank_id) {
|
||||
@ -208,30 +210,30 @@ impl Gfx {
|
||||
) {
|
||||
let tile_size = bank.tile_size as usize;
|
||||
|
||||
// 1. Calcular quantos tiles cabem na tela (com margem de 1 para o scroll)
|
||||
// 1. Calculate how many tiles fit on the screen (with margin of 1 for scroll)
|
||||
let visible_tiles_x = (screen_w / tile_size) + 1;
|
||||
let visible_tiles_y = (screen_h / tile_size) + 1;
|
||||
|
||||
// 2. Calcular o offset inicial (onde o primeiro tile começa a ser desenhado)
|
||||
// 2. Calculate the initial offset (where the first tile starts being drawn)
|
||||
let start_tile_x = scroll_x / tile_size as i32;
|
||||
let start_tile_y = scroll_y / tile_size as i32;
|
||||
|
||||
let fine_scroll_x = scroll_x % tile_size as i32;
|
||||
let fine_scroll_y = scroll_y % tile_size as i32;
|
||||
|
||||
// 3. Loop por Tile (Muito mais eficiente)
|
||||
// 3. Loop by Tile (Much more efficient)
|
||||
for ty in 0..visible_tiles_y {
|
||||
for tx in 0..visible_tiles_x {
|
||||
let map_x = (start_tile_x + tx as i32) as usize;
|
||||
let map_y = (start_tile_y + ty as i32) as usize;
|
||||
|
||||
// Skip se estiver fora dos limites do mapa
|
||||
// Skip if outside map bounds
|
||||
if map_x >= map.width || map_y >= map.height { continue; }
|
||||
|
||||
let tile = map.tiles[map_y * map.width + map_x];
|
||||
if tile.id == 0 { continue; }
|
||||
|
||||
// 4. Desenha o bloco do tile na tela
|
||||
// 4. Draws the tile block on the screen
|
||||
let screen_tile_x = (tx as i32 * tile_size as i32) - fine_scroll_x;
|
||||
let screen_tile_y = (ty as i32 * tile_size as i32) - fine_scroll_y;
|
||||
|
||||
@ -240,7 +242,7 @@ impl Gfx {
|
||||
}
|
||||
}
|
||||
|
||||
// Função auxiliar para desenhar um bloco de 8x8, 16x16 ou 32x32 pixels
|
||||
// Helper function to draw a block of 8x8, 16x16 or 32x32 pixels
|
||||
fn draw_tile_pixels(back: &mut [u16], screen_w: usize, screen_h: usize, x: i32, y: i32, tile: crate::model::Tile, bank: &TileBank) {
|
||||
let size = bank.tile_size as usize;
|
||||
|
||||
@ -255,13 +257,13 @@ impl Gfx {
|
||||
let fetch_x = if tile.flip_x { size - 1 - local_x } else { local_x };
|
||||
let fetch_y = if tile.flip_y { size - 1 - local_y } else { local_y };
|
||||
|
||||
// 1. Pega o índice do pixel no banco
|
||||
// 1. Gets the pixel index in the bank
|
||||
let px_index = bank.get_pixel_index(tile.id, fetch_x, fetch_y);
|
||||
|
||||
// 2. Regra: Índice 0 é transparente
|
||||
// 2. Rule: Index 0 is transparent
|
||||
if px_index == 0 { continue; }
|
||||
|
||||
// 3. Resolve a cor usando a paleta do tile
|
||||
// 3. Resolves the color using the tile's palette
|
||||
let color = bank.resolve_color(tile.palette_id, px_index);
|
||||
|
||||
back[world_y as usize * screen_w + world_x as usize] = color.raw();
|
||||
@ -293,7 +295,7 @@ impl Gfx {
|
||||
sprite: &Sprite,
|
||||
bank: &TileBank
|
||||
) {
|
||||
// ... (mesmo cálculo de bounds/clipping que já tínhamos) ...
|
||||
// ... (same bounds/clipping calculation we already had) ...
|
||||
let size = bank.tile_size as usize;
|
||||
let start_x = sprite.x.max(0);
|
||||
let start_y = sprite.y.max(0);
|
||||
@ -308,13 +310,13 @@ impl Gfx {
|
||||
let fetch_x = if sprite.flip_x { size - 1 - local_x } else { local_x };
|
||||
let fetch_y = if sprite.flip_y { size - 1 - local_y } else { local_y };
|
||||
|
||||
// 1. Pega o índice
|
||||
// 1. Get index
|
||||
let px_index = bank.get_pixel_index(sprite.tile.id, fetch_x, fetch_y);
|
||||
|
||||
// 2. Transparência
|
||||
// 2. Transparency
|
||||
if px_index == 0 { continue; }
|
||||
|
||||
// 3. Resolve cor via paleta (do tile dentro do sprite)
|
||||
// 3. Resolve color via palette (from the tile inside the sprite)
|
||||
let color = bank.resolve_color(sprite.tile.palette_id, px_index);
|
||||
|
||||
back[world_y as usize * screen_w + world_x as usize] = color.raw();
|
||||
@ -322,10 +324,10 @@ impl Gfx {
|
||||
}
|
||||
}
|
||||
|
||||
/// Aplica o efeito de fade em todo o back buffer.
|
||||
/// level: 0 (cor total) até 31 (visível)
|
||||
/// Applies the fade effect to the entire back buffer.
|
||||
/// level: 0 (full color) to 31 (visible)
|
||||
fn apply_fade_to_buffer(back: &mut [u16], level: u8, fade_color: Color) {
|
||||
if level >= 31 { return; } // Totalmente visível, pula processamento
|
||||
if level >= 31 { return; } // Fully visible, skip processing
|
||||
|
||||
let weight = level as u16;
|
||||
let inv_weight = 31 - weight;
|
||||
@ -334,7 +336,7 @@ impl Gfx {
|
||||
for px in back.iter_mut() {
|
||||
let (sr, sg, sb) = Color::unpack_to_native(*px);
|
||||
|
||||
// Fórmula: (src * weight + fade * inv_weight) / 31
|
||||
// Formula: (src * weight + fade * inv_weight) / 31
|
||||
let r = ((sr as u16 * weight + fr as u16 * inv_weight) / 31) as u8;
|
||||
let g = ((sg as u16 * weight + fg as u16 * inv_weight) / 31) as u8;
|
||||
let b = ((sb as u16 * weight + fb as u16 * inv_weight) / 31) as u8;
|
||||
@ -343,19 +345,19 @@ impl Gfx {
|
||||
}
|
||||
}
|
||||
|
||||
/// Retorna o uso real de memória das estruturas gráficas em bytes.
|
||||
/// Reflete os buffers de índices, paletas e OAM conforme Capítulo 10.8.
|
||||
/// Returns the actual memory usage of the graphics structures in bytes.
|
||||
/// Reflects index buffers, palettes, and OAM as per Chapter 10.8.
|
||||
pub fn memory_usage_bytes(&self) -> usize {
|
||||
let mut total = 0;
|
||||
|
||||
// 1. Framebuffers (Front + Back)
|
||||
// Cada um é Vec<u16>, ocupando 2 bytes por pixel.
|
||||
// Each is Vec<u16>, occupying 2 bytes per pixel.
|
||||
total += self.front.len() * 2;
|
||||
total += self.back.len() * 2;
|
||||
|
||||
// 2. Tile Layers (4 Game Layers)
|
||||
for layer in &self.layers {
|
||||
// Tamanho da struct + os dados do mapa (Vec<Tile>)
|
||||
// Struct size + map data (Vec<Tile>)
|
||||
total += size_of::<ScrollableTileLayer>();
|
||||
total += layer.map.tiles.len() * size_of::<crate::model::Tile>();
|
||||
}
|
||||
@ -364,19 +366,19 @@ impl Gfx {
|
||||
total += size_of::<HudTileLayer>();
|
||||
total += self.hud.map.tiles.len() * size_of::<crate::model::Tile>();
|
||||
|
||||
// 4. Tile Banks (Assets e Paletas)
|
||||
// 4. Tile Banks (Assets and Palettes)
|
||||
for bank_opt in &self.banks {
|
||||
if let Some(bank) = bank_opt {
|
||||
total += size_of::<TileBank>();
|
||||
total += bank.pixel_indices.len();
|
||||
|
||||
// Tabela de Paletas: 256 paletas * 16 cores * tamanho da struct Color
|
||||
// Palette Table: 256 palettes * 16 colors * Color struct size
|
||||
total += 256 * 16 * size_of::<Color>();
|
||||
}
|
||||
}
|
||||
|
||||
// 5. Sprites (OAM)
|
||||
// Array fixo de 512 Sprites.
|
||||
// Fixed array of 512 Sprites.
|
||||
total += self.sprites.len() * size_of::<Sprite>();
|
||||
|
||||
total
|
||||
@ -457,8 +459,8 @@ impl Gfx {
|
||||
}
|
||||
}
|
||||
|
||||
/// Faz blend em RGB565 por canal com saturação.
|
||||
/// `dst` e `src` são pixels RGB565 (u16).
|
||||
/// Blends in RGB565 per channel with saturation.
|
||||
/// `dst` and `src` are RGB565 pixels (u16).
|
||||
fn blend_rgb565(dst: u16, src: u16, mode: BlendMode) -> u16 {
|
||||
match mode {
|
||||
BlendMode::None => src,
|
||||
|
||||
@ -9,7 +9,7 @@ pub struct Touch {
|
||||
}
|
||||
|
||||
impl Touch {
|
||||
/// Flags transitórias devem durar apenas 1 frame.
|
||||
/// Transient flags should last only 1 frame.
|
||||
pub fn begin_frame(&mut self, signals: &InputSignals) {
|
||||
self.f.begin_frame(signals.f_signal);
|
||||
self.x = signals.x_pos.clone();
|
||||
|
||||
@ -85,7 +85,7 @@ mod tests {
|
||||
service.log(i as u64, 1, LogLevel::Info, LogSource::Pos, 0, format!("Log {}", i));
|
||||
}
|
||||
|
||||
let after = service.get_after(2); // seqs são 0, 1, 2, 3, 4. Deve retornar 3 e 4.
|
||||
let after = service.get_after(2); // seqs are 0, 1, 2, 3, 4. Should return 3 and 4.
|
||||
assert_eq!(after.len(), 2);
|
||||
assert_eq!(after[0].msg, "Log 3");
|
||||
assert_eq!(after[1].msg, "Log 4");
|
||||
|
||||
@ -33,7 +33,7 @@ impl DirectoryCartridgeLoader {
|
||||
let manifest_content = fs::read_to_string(manifest_path).map_err(|_| CartridgeError::IoError)?;
|
||||
let manifest: CartridgeManifest = serde_json::from_str(&manifest_content).map_err(|_| CartridgeError::InvalidManifest)?;
|
||||
|
||||
// Validação adicional conforme requisitos
|
||||
// Additional validation as per requirements
|
||||
if manifest.magic != "PMTU" {
|
||||
return Err(CartridgeError::InvalidManifest);
|
||||
}
|
||||
@ -73,7 +73,6 @@ pub struct PackedCartridgeLoader;
|
||||
|
||||
impl PackedCartridgeLoader {
|
||||
pub fn load(_path: &Path) -> Result<Cartridge, CartridgeError> {
|
||||
// Stub inicialmente, como solicitado
|
||||
Err(CartridgeError::InvalidFormat)
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
/// Cor simples em RGB565 (0bRRRRRGGGGGGBBBBB).
|
||||
/// Simple RGB565 color (0bRRRRRGGGGGGBBBBB).
|
||||
/// - 5 bits Red
|
||||
/// - 6 bits Green
|
||||
/// - 5 bits Blue
|
||||
///
|
||||
/// Não há canal alpha.
|
||||
/// Transparência é tratada via Color Key ou Blend Mode.
|
||||
/// There is no alpha channel.
|
||||
/// Transparency is handled via Color Key or Blend Mode.
|
||||
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
|
||||
pub struct Color(pub u16);
|
||||
|
||||
@ -23,7 +23,7 @@ impl Color {
|
||||
pub const COLOR_KEY: Self = Self::MAGENTA;
|
||||
pub const TRANSPARENT: Self = Self::MAGENTA;
|
||||
|
||||
/// Extrai canais já na faixa nativa do RGB565:
|
||||
/// Extracts channels in the native RGB565 range:
|
||||
/// R: 0..31, G: 0..63, B: 0..31
|
||||
#[inline(always)]
|
||||
pub const fn unpack_to_native(px: u16) -> (u8, u8, u8) {
|
||||
@ -33,14 +33,14 @@ impl Color {
|
||||
(r, g, b)
|
||||
}
|
||||
|
||||
/// Incorpora canais já na faixa nativa do RGB565 em um pixel:
|
||||
/// Packs channels from the native RGB565 range into a pixel:
|
||||
/// R: 0..31, G: 0..63, B: 0..31
|
||||
#[inline(always)]
|
||||
pub const fn pack_from_native(r: u8, g: u8, b: u8) -> u16 {
|
||||
((r as u16 & 0x1F) << 11) | ((g as u16 & 0x3F) << 5) | (b as u16 & 0x1F)
|
||||
}
|
||||
|
||||
/// Cria uma cor RGB565 a partir de componentes 8-bit (0..255).
|
||||
/// Creates an RGB565 color from 8-bit components (0..255).
|
||||
pub const fn rgb(r: u8, g: u8, b: u8) -> Self {
|
||||
let r5 = (r as u16 >> 3) & 0x1F;
|
||||
let g6 = (g as u16 >> 2) & 0x3F;
|
||||
|
||||
@ -9,13 +9,12 @@ pub enum TileSize {
|
||||
|
||||
pub struct TileBank {
|
||||
pub tile_size: TileSize,
|
||||
pub width: usize, // em pixels
|
||||
pub height: usize, // em pixels
|
||||
// pub pixels: Vec<Color>,
|
||||
pub width: usize, // in pixels
|
||||
pub height: usize, // in pixels
|
||||
|
||||
/// Agora guardamos índices de 0 a 15 (4 bits por pixel simulados em 8 bits)
|
||||
/// Now we store indices from 0 to 15 (4 bits per pixel simulated in 8 bits)
|
||||
pub pixel_indices: Vec<u8>,
|
||||
/// 256 paletas, cada uma com 16 cores (RGB565 como u16)
|
||||
/// 256 palettes, each with 16 colors (RGB565 as u16)
|
||||
pub palettes: [[Color; 16]; 256],
|
||||
}
|
||||
|
||||
@ -25,14 +24,14 @@ impl TileBank {
|
||||
tile_size,
|
||||
width,
|
||||
height,
|
||||
pixel_indices: vec![0; width * height], // Índice 0 = Transparente
|
||||
pixel_indices: vec![0; width * height], // Index 0 = Transparent
|
||||
palettes: [[Color::BLACK; 16]; 256],
|
||||
}
|
||||
}
|
||||
|
||||
/// Retorna a cor de um pixel específico dentro de um tile.
|
||||
/// tile_id: o índice do tile no banco
|
||||
/// local_x, local_y: a posição do pixel dentro do tile (0 até tile_size-1)
|
||||
/// Returns the color of a specific pixel inside a tile.
|
||||
/// tile_id: the tile index in the bank
|
||||
/// local_x, local_y: the pixel position inside the tile (0 to tile_size-1)
|
||||
pub fn get_pixel_index(&self, tile_id: u16, local_x: usize, local_y: usize) -> u8 {
|
||||
let size = self.tile_size as usize;
|
||||
let tiles_per_row = self.width / size;
|
||||
@ -45,13 +44,13 @@ impl TileBank {
|
||||
if pixel_x < self.width && pixel_y < self.height {
|
||||
self.pixel_indices[pixel_y * self.width + pixel_x]
|
||||
} else {
|
||||
0 // Fora do banco = Transparente
|
||||
0 // Outside the bank = Transparent
|
||||
}
|
||||
}
|
||||
|
||||
/// Resolve um índice de pixel para uma Color real usando uma paleta.
|
||||
/// Resolves a pixel index to a real Color using a palette.
|
||||
pub fn resolve_color(&self, palette_id: u8, pixel_index: u8) -> Color {
|
||||
// Regra: Índice 0 é sempre transparente (usamos MAGENTA/COLOR_KEY como vácuo)
|
||||
// Rule: Index 0 is always transparent (we use MAGENTA/COLOR_KEY as vacuum)
|
||||
if pixel_index == 0 {
|
||||
return Color::COLOR_KEY;
|
||||
}
|
||||
|
||||
@ -3,7 +3,7 @@ use crate::log::{LogLevel, LogSource};
|
||||
use crate::model::{Color, Rect, Window, WindowId};
|
||||
use crate::prometeu_os::PrometeuOS;
|
||||
|
||||
/// Gerenciador de janelas do PROMETEU.
|
||||
/// PROMETEU Window Manager.
|
||||
pub struct WindowManager {
|
||||
pub windows: Vec<Window>,
|
||||
pub focused: Option<WindowId>,
|
||||
@ -50,7 +50,7 @@ impl WindowManager {
|
||||
}
|
||||
}
|
||||
|
||||
/// PrometeuHub: Launcher e ambiente de UI do sistema.
|
||||
/// PrometeuHub: Launcher and system UI environment.
|
||||
pub struct PrometeuHub {
|
||||
pub window_manager: WindowManager,
|
||||
}
|
||||
@ -63,7 +63,7 @@ impl PrometeuHub {
|
||||
}
|
||||
|
||||
pub fn init(&mut self) {
|
||||
// Inicializa o Window System e lista apps
|
||||
// Initializes the Window System and lists apps
|
||||
}
|
||||
|
||||
pub fn gui_update(&mut self, os: &mut PrometeuOS, hw: &mut dyn HardwareBridge) {
|
||||
|
||||
@ -9,8 +9,8 @@ use std::collections::HashMap;
|
||||
use std::sync::Arc;
|
||||
use std::time::Instant;
|
||||
|
||||
/// PrometeuOS (POS): O firmware/base do sistema.
|
||||
/// Autoridade máxima do boot, periféricos, execução da PVM e tratamento de falhas.
|
||||
/// PrometeuOS (POS): The system firmware/base.
|
||||
/// Maximum authority for boot, peripherals, PVM execution, and fault handling.
|
||||
pub struct PrometeuOS {
|
||||
pub tick_index: u64,
|
||||
pub logical_frame_index: u64,
|
||||
@ -18,7 +18,7 @@ pub struct PrometeuOS {
|
||||
pub logical_frame_remaining_cycles: u64,
|
||||
pub last_frame_cpu_time_us: u64,
|
||||
|
||||
// Assets de exemplo (mantidos para compatibilidade com syscalls de áudio v0)
|
||||
// Example assets (kept for compatibility with v0 audio syscalls)
|
||||
pub sample_square: Option<Arc<Sample>>,
|
||||
pub sample_kick: Option<Arc<Sample>>,
|
||||
pub sample_snare: Option<Arc<Sample>>,
|
||||
@ -37,7 +37,7 @@ pub struct PrometeuOS {
|
||||
pub current_cartridge_app_mode: crate::model::AppMode,
|
||||
pub logs_written_this_frame: HashMap<u32, u32>,
|
||||
|
||||
// Telemetria e Certificação
|
||||
// Telemetry and Certification
|
||||
pub telemetry_current: TelemetryFrame,
|
||||
pub telemetry_last: TelemetryFrame,
|
||||
pub certifier: Certifier,
|
||||
@ -49,7 +49,7 @@ pub struct PrometeuOS {
|
||||
|
||||
impl PrometeuOS {
|
||||
pub const CYCLES_PER_LOGICAL_FRAME: u64 = 100_000;
|
||||
pub const SLICE_PER_TICK: u64 = 100_000; // Por enquanto, o mesmo, mas permite granularidade diferente
|
||||
pub const SLICE_PER_TICK: u64 = 100_000; // For now the same, but allows different granularity
|
||||
|
||||
pub const MAX_LOG_LEN: usize = 256;
|
||||
pub const MAX_LOGS_PER_FRAME: u32 = 10;
|
||||
@ -83,7 +83,7 @@ impl PrometeuOS {
|
||||
boot_time,
|
||||
};
|
||||
|
||||
// Inicializa samples básicos (mesma lógica do LogicalHardware)
|
||||
// Initializes basic samples (same logic as LogicalHardware)
|
||||
os.sample_square = Some(Arc::new(Self::create_square_sample(440.0, 0.1)));
|
||||
|
||||
os.log(LogLevel::Info, LogSource::Pos, 0, "PrometeuOS starting...".to_string());
|
||||
@ -135,18 +135,18 @@ impl PrometeuOS {
|
||||
self.last_frame_cpu_time_us = 0;
|
||||
}
|
||||
|
||||
/// Carrega um cartucho na PVM e reseta o estado de execução.
|
||||
/// Loads a cartridge into the PVM and resets the execution state.
|
||||
pub fn initialize_vm(&mut self, vm: &mut VirtualMachine, cartridge: &Cartridge) {
|
||||
vm.initialize(cartridge.program.clone(), &cartridge.entrypoint);
|
||||
|
||||
// Determina o app_id numérico
|
||||
// Determines the numeric app_id
|
||||
self.current_app_id = cartridge.app_id;
|
||||
self.current_cartridge_title = cartridge.title.clone();
|
||||
self.current_cartridge_app_version = cartridge.app_version.clone();
|
||||
self.current_cartridge_app_mode = cartridge.app_mode;
|
||||
}
|
||||
|
||||
/// Executa uma única instrução da VM (Debug).
|
||||
/// Executes a single VM instruction (Debug).
|
||||
pub fn debug_step_instruction(&mut self, vm: &mut VirtualMachine, hw: &mut dyn HardwareBridge) -> Option<String> {
|
||||
match vm.step(self, hw) {
|
||||
Ok(_) => None,
|
||||
@ -158,7 +158,7 @@ impl PrometeuOS {
|
||||
}
|
||||
}
|
||||
|
||||
/// Executa um tick do host (60Hz).
|
||||
/// Executes a host tick (60Hz).
|
||||
pub fn step_frame(&mut self, vm: &mut VirtualMachine, signals: &InputSignals, hw: &mut dyn HardwareBridge) -> Option<String> {
|
||||
let start = std::time::Instant::now();
|
||||
self.tick_index += 1;
|
||||
@ -174,25 +174,25 @@ impl PrometeuOS {
|
||||
self.logical_frame_remaining_cycles = Self::CYCLES_PER_LOGICAL_FRAME;
|
||||
self.begin_logical_frame(signals, hw);
|
||||
|
||||
// Início do frame: resetar acumulador da telemetria (mas manter frame_index)
|
||||
// Beginning of frame: reset telemetry accumulator (but keep frame_index)
|
||||
self.telemetry_current = TelemetryFrame {
|
||||
frame_index: self.logical_frame_index,
|
||||
..Default::default()
|
||||
};
|
||||
}
|
||||
|
||||
// Budget para este tick: o mínimo entre a fatia do tick e o que resta no frame lógico
|
||||
// Budget for this tick: the minimum between the tick slice and what remains in the logical frame
|
||||
let budget = std::cmp::min(Self::SLICE_PER_TICK, self.logical_frame_remaining_cycles);
|
||||
|
||||
if budget > 0 {
|
||||
// Executa budget
|
||||
// Execute budget
|
||||
let run_result = vm.run_budget(budget, self, hw);
|
||||
|
||||
match run_result {
|
||||
Ok(run) => {
|
||||
self.logical_frame_remaining_cycles = self.logical_frame_remaining_cycles.saturating_sub(run.cycles_used);
|
||||
|
||||
// Acumula métricas
|
||||
// Accumulates metrics
|
||||
self.telemetry_current.cycles_used += run.cycles_used;
|
||||
self.telemetry_current.vm_steps += run.steps_executed;
|
||||
|
||||
@ -205,14 +205,14 @@ impl PrometeuOS {
|
||||
if run.reason == crate::virtual_machine::LogicalFrameEndingReason::FrameSync {
|
||||
hw.gfx_mut().render_all();
|
||||
|
||||
// Finaliza telemetria do frame (host_cpu_time será refinado no final do tick)
|
||||
// Finalizes frame telemetry (host_cpu_time will be refined at the end of the tick)
|
||||
self.telemetry_current.host_cpu_time_us = start.elapsed().as_micros() as u64;
|
||||
|
||||
// Certificação (CAP)
|
||||
// Certification (CAP)
|
||||
let ts_ms = self.boot_time.elapsed().as_millis() as u64;
|
||||
self.telemetry_current.violations = self.certifier.evaluate(&self.telemetry_current, &mut self.log_service, ts_ms) as u32;
|
||||
|
||||
// Latch: o que o overlay lê
|
||||
// Latch: what the overlay reads
|
||||
self.telemetry_last = self.telemetry_current;
|
||||
|
||||
self.logical_frame_index += 1;
|
||||
@ -235,7 +235,7 @@ impl PrometeuOS {
|
||||
|
||||
self.last_frame_cpu_time_us = start.elapsed().as_micros() as u64;
|
||||
|
||||
// Se o frame acabou neste tick, atualizamos o tempo real final no latch
|
||||
// If the frame ended in this tick, we update the final real time in the latch
|
||||
if !self.logical_frame_active && self.telemetry_last.frame_index == self.logical_frame_index.wrapping_sub(1) {
|
||||
self.telemetry_last.host_cpu_time_us = self.last_frame_cpu_time_us;
|
||||
}
|
||||
@ -367,16 +367,16 @@ mod tests {
|
||||
};
|
||||
os.initialize_vm(&mut vm, &cartridge);
|
||||
|
||||
// Primeiro tick
|
||||
// First tick
|
||||
os.step_frame(&mut vm, &signals, &mut hw);
|
||||
let cycles_after_tick_1 = vm.cycles;
|
||||
assert!(cycles_after_tick_1 >= PrometeuOS::CYCLES_PER_LOGICAL_FRAME);
|
||||
|
||||
// Segundo tick - Agora ele NÃO deve ganhar mais budget
|
||||
// Second tick - Now it SHOULD NOT gain more budget
|
||||
os.step_frame(&mut vm, &signals, &mut hw);
|
||||
let cycles_after_tick_2 = vm.cycles;
|
||||
|
||||
// CORREÇÃO: Ele não deve ter consumido ciclos no segundo tick porque o budget do frame lógico acabou
|
||||
// FIX: It should not have consumed cycles in the second tick because the logical frame budget ended
|
||||
println!("Cycles after tick 1: {}, tick 2: {}", cycles_after_tick_1, cycles_after_tick_2);
|
||||
assert_eq!(cycles_after_tick_2, cycles_after_tick_1, "VM should NOT have consumed more cycles in the second tick because logical frame budget is exhausted");
|
||||
}
|
||||
@ -388,7 +388,7 @@ mod tests {
|
||||
let mut hw = Hardware::new();
|
||||
let signals = InputSignals::default();
|
||||
|
||||
// Loop que chama FrameSync:
|
||||
// Loop that calls FrameSync:
|
||||
// PUSH_CONST 0 (dummy)
|
||||
// FrameSync (0x80)
|
||||
// JMP 0
|
||||
@ -407,15 +407,15 @@ mod tests {
|
||||
};
|
||||
os.initialize_vm(&mut vm, &cartridge);
|
||||
|
||||
// Primeiro tick
|
||||
// First tick
|
||||
os.step_frame(&mut vm, &signals, &mut hw);
|
||||
let cycles_after_tick_1 = vm.cycles;
|
||||
|
||||
// Deve ter parado no FrameSync
|
||||
// Should have stopped at FrameSync
|
||||
assert!(cycles_after_tick_1 > 0, "VM should have consumed some cycles");
|
||||
assert!(cycles_after_tick_1 < PrometeuOS::CYCLES_PER_LOGICAL_FRAME);
|
||||
|
||||
// Segundo tick - Deve resetar o budget e rodar mais um pouco até o próximo FrameSync
|
||||
// Second tick - Should reset the budget and run a bit more until the next FrameSync
|
||||
os.step_frame(&mut vm, &signals, &mut hw);
|
||||
let cycles_after_tick_2 = vm.cycles;
|
||||
|
||||
@ -430,7 +430,7 @@ mod tests {
|
||||
|
||||
os.current_app_id = 123;
|
||||
|
||||
// 1. Teste de log normal
|
||||
// 1. Normal log test
|
||||
vm.push(Value::Integer(2)); // Info
|
||||
vm.push(Value::String("Hello Log".to_string()));
|
||||
let res = os.syscall(0x5001, &mut vm, &mut hw);
|
||||
@ -441,7 +441,7 @@ mod tests {
|
||||
assert_eq!(recent[0].level, LogLevel::Info);
|
||||
assert_eq!(recent[0].source, LogSource::App { app_id: 123 });
|
||||
|
||||
// 2. Teste de truncamento
|
||||
// 2. Truncation test
|
||||
let long_msg = "A".repeat(300);
|
||||
vm.push(Value::Integer(3)); // Warn
|
||||
vm.push(Value::String(long_msg));
|
||||
@ -451,27 +451,27 @@ mod tests {
|
||||
assert_eq!(recent[0].msg.len(), 256);
|
||||
assert!(recent[0].msg.starts_with("AAAAA"));
|
||||
|
||||
// 3. Teste de Rate Limit
|
||||
// Já fizemos 2 logs. O limite é 10.
|
||||
// 3. Rate Limit Test
|
||||
// We already made 2 logs. The limit is 10.
|
||||
for i in 0..8 {
|
||||
vm.push(Value::Integer(2));
|
||||
vm.push(Value::String(format!("Log {}", i)));
|
||||
os.syscall(0x5001, &mut vm, &mut hw).unwrap();
|
||||
}
|
||||
|
||||
// O 11º log deve ser ignorado (e deve gerar um aviso do sistema)
|
||||
// The 11th log should be ignored (and generate a system warning)
|
||||
vm.push(Value::Integer(2));
|
||||
vm.push(Value::String("Eleventh log".to_string()));
|
||||
os.syscall(0x5001, &mut vm, &mut hw).unwrap();
|
||||
|
||||
let recent = os.log_service.get_recent(2);
|
||||
// O último log deve ser o aviso de rate limit (veio depois do 10º log tentado)
|
||||
// The last log should be the rate limit warning (came after the 10th log attempted)
|
||||
assert_eq!(recent[1].msg, "App exceeded log limit per frame");
|
||||
assert_eq!(recent[1].level, LogLevel::Warn);
|
||||
// O log "Eleventh log" não deve estar lá
|
||||
// The log "Eleventh log" should not be there
|
||||
assert_ne!(recent[0].msg, "Eleventh log");
|
||||
|
||||
// 4. Teste de reset do rate limit no próximo frame
|
||||
// 4. Rate limit reset test in the next frame
|
||||
os.begin_logical_frame(&InputSignals::default(), &mut hw);
|
||||
vm.push(Value::Integer(2));
|
||||
vm.push(Value::String("New frame log".to_string()));
|
||||
@ -480,7 +480,7 @@ mod tests {
|
||||
let recent = os.log_service.get_recent(1);
|
||||
assert_eq!(recent[0].msg, "New frame log");
|
||||
|
||||
// 5. Teste de LOG_WRITE_TAG
|
||||
// 5. LOG_WRITE_TAG test
|
||||
vm.push(Value::Integer(2)); // Info
|
||||
vm.push(Value::Integer(42)); // Tag
|
||||
vm.push(Value::String("Tagged Log".to_string()));
|
||||
@ -623,7 +623,7 @@ impl NativeInterface for PrometeuOS {
|
||||
};
|
||||
match self.fs.list_dir(&path) {
|
||||
Ok(entries) => {
|
||||
// Por enquanto, retorna uma string separada por ';'
|
||||
// For now, returns a string separated by ';'
|
||||
let names: Vec<String> = entries.into_iter().map(|e| e.name).collect();
|
||||
vm.push(Value::String(names.join(";")));
|
||||
Ok(500)
|
||||
|
||||
@ -2,25 +2,25 @@
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
#[repr(u16)]
|
||||
pub enum OpCode {
|
||||
// 6.1 Controle de Execução
|
||||
// 6.1 Execution Control
|
||||
Nop = 0x00,
|
||||
Halt = 0x01,
|
||||
Jmp = 0x02,
|
||||
JmpIfFalse = 0x03,
|
||||
|
||||
// 6.2 Pilha
|
||||
// 6.2 Stack
|
||||
PushConst = 0x10,
|
||||
Pop = 0x11,
|
||||
Dup = 0x12,
|
||||
Swap = 0x13,
|
||||
|
||||
// 6.3 Aritmética
|
||||
// 6.3 Arithmetic
|
||||
Add = 0x20,
|
||||
Sub = 0x21,
|
||||
Mul = 0x22,
|
||||
Div = 0x23,
|
||||
|
||||
// 6.4 Comparação e Lógica
|
||||
// 6.4 Comparison and Logic
|
||||
Eq = 0x30,
|
||||
Neq = 0x31,
|
||||
Lt = 0x32,
|
||||
@ -29,13 +29,13 @@ pub enum OpCode {
|
||||
Or = 0x35,
|
||||
Not = 0x36,
|
||||
|
||||
// 6.5 Variáveis
|
||||
// 6.5 Variables
|
||||
GetGlobal = 0x40,
|
||||
SetGlobal = 0x41,
|
||||
GetLocal = 0x42,
|
||||
SetLocal = 0x43,
|
||||
|
||||
// 6.6 Funções
|
||||
// 6.6 Functions
|
||||
Call = 0x50,
|
||||
Ret = 0x51,
|
||||
PushScope = 0x52,
|
||||
@ -46,7 +46,7 @@ pub enum OpCode {
|
||||
LoadRef = 0x61,
|
||||
StoreRef = 0x62,
|
||||
|
||||
// 6.8 Periféricos e Sistema
|
||||
// 6.8 Peripherals and System
|
||||
Syscall = 0x70,
|
||||
FrameSync = 0x80,
|
||||
}
|
||||
@ -126,7 +126,7 @@ impl OpCode {
|
||||
OpCode::Alloc => 10,
|
||||
OpCode::LoadRef => 3,
|
||||
OpCode::StoreRef => 3,
|
||||
OpCode::Syscall => 1, // Variável, mas vamos usar 1 como base ou definir via ID
|
||||
OpCode::Syscall => 1, // Variable, but we'll use 1 as base or define via ID
|
||||
OpCode::FrameSync => 1,
|
||||
}
|
||||
}
|
||||
|
||||
@ -7,7 +7,7 @@ pub enum Value {
|
||||
Float(f64),
|
||||
Boolean(bool),
|
||||
String(String),
|
||||
Ref(usize), // Referência ao heap
|
||||
Ref(usize), // Heap reference
|
||||
Null,
|
||||
}
|
||||
|
||||
|
||||
@ -27,7 +27,7 @@ pub struct VirtualMachine {
|
||||
pub call_stack: Vec<CallFrame>,
|
||||
pub globals: Vec<Value>,
|
||||
pub program: Program,
|
||||
pub heap: Vec<Value>, // Simplificado para demo, futuramente RAM/Heap real
|
||||
pub heap: Vec<Value>, // Simplified for demo, future real RAM/Heap
|
||||
pub cycles: u64,
|
||||
pub halted: bool,
|
||||
pub breakpoints: std::collections::HashSet<usize>,
|
||||
@ -56,12 +56,12 @@ impl VirtualMachine {
|
||||
self.program = Program::new(program_bytes, vec![]);
|
||||
}
|
||||
} else {
|
||||
// Por enquanto, tratamos os bytes como a ROM diretamente.
|
||||
// For now, we treat the bytes as the ROM directly.
|
||||
self.program = Program::new(program_bytes, vec![]);
|
||||
}
|
||||
|
||||
// Se o entrypoint for numérico, podemos tentar usá-lo como PC inicial.
|
||||
// Se não, por enquanto ignoramos ou começamos do 0.
|
||||
// If the entrypoint is numeric, we can try to use it as the initial PC.
|
||||
// If not, for now we ignore it or start from 0.
|
||||
if let Ok(addr) = entrypoint.parse::<usize>() {
|
||||
self.pc = addr;
|
||||
} else {
|
||||
@ -173,7 +173,7 @@ impl VirtualMachine {
|
||||
let pc_before = self.pc;
|
||||
let cycles_before = self.cycles;
|
||||
|
||||
// Fast-path: FRAME_SYNC encerra o frame lógico
|
||||
// Fast-path: FRAME_SYNC ends the logical frame
|
||||
let opcode_val = self.peek_u16()?;
|
||||
let opcode = OpCode::try_from(opcode_val)?;
|
||||
if opcode == OpCode::FrameSync {
|
||||
@ -187,7 +187,7 @@ impl VirtualMachine {
|
||||
self.step(native, hw)?;
|
||||
steps_executed += 1;
|
||||
|
||||
// garante progresso real
|
||||
// ensures real progress
|
||||
if self.pc == pc_before && self.cycles == cycles_before && !self.halted {
|
||||
return Err(format!("VM stuck at PC 0x{:08X}", self.pc));
|
||||
}
|
||||
|
||||
@ -1,17 +1,17 @@
|
||||
# PROMETEU Desktop Runtime
|
||||
|
||||
Esta é a implementação de host para plataformas desktop, permitindo que o PROMETEU rode em Windows, Linux e macOS.
|
||||
This is the host implementation for desktop platforms, allowing PROMETEU to run on Windows, Linux, and macOS.
|
||||
|
||||
## Funcionalidades
|
||||
## Features
|
||||
|
||||
- **Renderização**: Utiliza a GPU via biblioteca `pixels` para apresentar o framebuffer de baixa resolução.
|
||||
- **Input**: Traduz eventos de teclado e controle (via `winit`) para os sinais de hardware do PROMETEU.
|
||||
- **Áudio**: Interface com o sistema de som do host (via `cpal`).
|
||||
- **Debugging**: Hospeda um servidor TCP que implementa o **DevTools Protocol**, permitindo conexões de IDEs ou debuggers externos.
|
||||
- **Rendering**: Uses the GPU via the `pixels` library to present the low-resolution framebuffer.
|
||||
- **Input**: Translates keyboard and controller events (via `winit`) into PROMETEU hardware signals.
|
||||
- **Audio**: Interfaces with the host's sound system (via `cpal`).
|
||||
- **Debugging**: Hosts a TCP server that implements the **DevTools Protocol**, allowing connections from external IDEs or debuggers.
|
||||
|
||||
## Como rodar
|
||||
## How to run
|
||||
|
||||
Geralmente executado via CLI principal (`prometeu`), mas pode ser chamado diretamente para testes:
|
||||
Generally executed via the main CLI (`prometeu`), but can be called directly for testing:
|
||||
|
||||
```bash
|
||||
cargo run -- --run path/to/cart
|
||||
|
||||
@ -39,7 +39,7 @@ impl HostAudio {
|
||||
|
||||
let mut mixer = AudioMixer::new();
|
||||
|
||||
// Para passar dados de performance da thread de áudio para a principal
|
||||
// To pass performance data from the audio thread to the main thread
|
||||
let audio_perf_rb = HeapRb::<u64>::new(64);
|
||||
let (mut perf_prod, perf_cons) = audio_perf_rb.split();
|
||||
|
||||
@ -47,13 +47,13 @@ impl HostAudio {
|
||||
.build_output_stream(
|
||||
&config,
|
||||
move |data: &mut [f32], _: &cpal::OutputCallbackInfo| {
|
||||
// Consome comandos da ringbuffer
|
||||
// Consumes commands from ringbuffer
|
||||
while let Some(cmd) = cons.try_pop() {
|
||||
mixer.process_command(cmd);
|
||||
}
|
||||
// Mixa áudio
|
||||
// Mixes audio
|
||||
mixer.fill_buffer(data);
|
||||
// Envia tempo de processamento em microssegundos
|
||||
// Sends processing time in microseconds
|
||||
let _ = perf_prod.try_push(mixer.last_processing_time.as_micros() as u64);
|
||||
},
|
||||
|err| eprintln!("audio stream error: {}", err),
|
||||
@ -144,7 +144,7 @@ impl AudioMixer {
|
||||
|
||||
pub fn fill_buffer(&mut self, buffer: &mut [f32]) {
|
||||
let start = std::time::Instant::now();
|
||||
// Zera o buffer (estéreo)
|
||||
// Zeroes the buffer (stereo)
|
||||
for sample in buffer.iter_mut() {
|
||||
*sample = 0.0;
|
||||
}
|
||||
@ -172,7 +172,7 @@ impl AudioMixer {
|
||||
break;
|
||||
}
|
||||
|
||||
// Interpolação Linear
|
||||
// Linear Interpolation
|
||||
let s1 = sample_data.data[pos_int] as f32 / 32768.0;
|
||||
let s2 = if pos_int + 1 < sample_data.data.len() {
|
||||
sample_data.data[pos_int + 1] as f32 / 32768.0
|
||||
@ -204,7 +204,7 @@ impl AudioMixer {
|
||||
}
|
||||
}
|
||||
|
||||
// Clamp final para evitar clipping (opcional se usarmos f32, mas bom para fidelidade)
|
||||
// Final clamp to avoid clipping (optional if using f32, but good for fidelity)
|
||||
for sample in buffer.iter_mut() {
|
||||
*sample = sample.clamp(-1.0, 1.0);
|
||||
}
|
||||
|
||||
@ -28,7 +28,7 @@ impl HostDebugger {
|
||||
if let BootTarget::Cartridge { path, debug: true, debug_port } = boot_target {
|
||||
self.waiting_for_start = true;
|
||||
|
||||
// Pré-carrega informações do cartucho para o handshake
|
||||
// Pre-loads cartridge information for the handshake
|
||||
if let Ok(cartridge) = CartridgeLoader::load(path) {
|
||||
firmware.os.initialize_vm(&mut firmware.vm, &cartridge);
|
||||
}
|
||||
@ -75,7 +75,7 @@ impl HostDebugger {
|
||||
|
||||
self.stream = Some(stream);
|
||||
|
||||
// Enviar Handshake
|
||||
// Send Handshake
|
||||
let handshake = DebugResponse::Handshake {
|
||||
protocol_version: DEVTOOLS_PROTOCOL_VERSION,
|
||||
runtime_version: "0.1".to_string(),
|
||||
@ -104,10 +104,10 @@ impl HostDebugger {
|
||||
}
|
||||
Ok(n) => {
|
||||
let data = &buf[..n];
|
||||
// Processar múltiplos comandos se houver \n
|
||||
// Process multiple commands if there's \n
|
||||
let msg = String::from_utf8_lossy(data);
|
||||
|
||||
self.stream = Some(stream); // Coloca de volta antes de processar comandos
|
||||
self.stream = Some(stream); // Put it back before processing commands
|
||||
|
||||
for line in msg.lines() {
|
||||
let trimmed = line.trim();
|
||||
@ -154,7 +154,7 @@ impl HostDebugger {
|
||||
}
|
||||
DebugCommand::Step => {
|
||||
firmware.os.paused = true;
|
||||
// Executa uma instrução imediatamente
|
||||
// Executes an instruction immediately
|
||||
let _ = firmware.os.debug_step_instruction(&mut firmware.vm, hardware);
|
||||
}
|
||||
DebugCommand::StepFrame => {
|
||||
@ -192,7 +192,7 @@ impl HostDebugger {
|
||||
for event in new_events {
|
||||
self.last_log_seq = event.seq;
|
||||
|
||||
// Verifica se é um breakpoint hit via tag
|
||||
// Check if it's a breakpoint hit via tag
|
||||
if event.tag == 0xDEB1 {
|
||||
self.send_event(DebugEvent::BreakpointHit {
|
||||
pc: firmware.vm.pc,
|
||||
@ -200,7 +200,7 @@ impl HostDebugger {
|
||||
});
|
||||
}
|
||||
|
||||
// Certificação via Tags 0xCA01-0xCA03
|
||||
// Certification via Tags 0xCA01-0xCA03
|
||||
if event.tag >= 0xCA01 && event.tag <= 0xCA03 {
|
||||
let rule = match event.tag {
|
||||
0xCA01 => "cycles_budget",
|
||||
@ -211,7 +211,7 @@ impl HostDebugger {
|
||||
|
||||
self.send_event(DebugEvent::Cert {
|
||||
rule,
|
||||
used: 0, // Simplificado, informações detalhadas estão na msg do log
|
||||
used: 0, // Simplified, detailed information is in the log message
|
||||
limit: 0,
|
||||
frame_index: firmware.os.logical_frame_index,
|
||||
});
|
||||
|
||||
@ -21,7 +21,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let mut debug_mode = false;
|
||||
let mut debug_port = 7777;
|
||||
|
||||
let mut i = 1; // Pula o nome do executável
|
||||
let mut i = 1; // Skip the executable name
|
||||
while i < args.len() {
|
||||
match args[i].as_str() {
|
||||
"--run" => {
|
||||
|
||||
@ -95,7 +95,7 @@ impl HostRunner {
|
||||
fn display_dbg_overlay(&mut self) {
|
||||
let tel = &self.firmware.os.telemetry_last;
|
||||
let color_text = prometeu_core::model::Color::WHITE;
|
||||
let color_bg = prometeu_core::model::Color::INDIGO; // Azul escuro para destacar
|
||||
let color_bg = prometeu_core::model::Color::INDIGO; // Dark blue to stand out
|
||||
let color_warn = prometeu_core::model::Color::RED;
|
||||
|
||||
self.hardware.gfx.fill_rect(5, 5, 140, 65, color_bg);
|
||||
@ -129,7 +129,7 @@ impl ApplicationHandler for HostRunner {
|
||||
|
||||
let window = event_loop.create_window(attrs).expect("failed to create window");
|
||||
|
||||
// 🔥 Leak: Window vira &'static Window (bootstrap)
|
||||
// 🔥 Leak: Window becomes &'static Window (bootstrap)
|
||||
let window: &'static Window = Box::leak(Box::new(window));
|
||||
self.window = Some(window);
|
||||
|
||||
@ -165,18 +165,18 @@ impl ApplicationHandler for HostRunner {
|
||||
}
|
||||
|
||||
WindowEvent::RedrawRequested => {
|
||||
// Pegue o Pixels diretamente do campo (não via helper que pega &mut self inteiro)
|
||||
// Get Pixels directly from the field (not via helper that gets the entire &mut self)
|
||||
let pixels = self.pixels.as_mut().expect("pixels not initialized");
|
||||
|
||||
{
|
||||
// Borrow mutável do frame (dura só dentro deste bloco)
|
||||
// Mutable borrow of the frame (lasts only within this block)
|
||||
let frame = pixels.frame_mut();
|
||||
|
||||
// Borrow imutável do prometeu-core (campo diferente, ok)
|
||||
// Immutable borrow of prometeu-core (different field, ok)
|
||||
let src = self.hardware.gfx.front_buffer();
|
||||
|
||||
draw_rgb565_to_rgba8(src, frame);
|
||||
} // <- frame borrow termina aqui
|
||||
} // <- frame borrow ends here
|
||||
|
||||
if pixels.render().is_err() {
|
||||
event_loop.exit();
|
||||
@ -206,7 +206,7 @@ impl ApplicationHandler for HostRunner {
|
||||
fn about_to_wait(&mut self, _event_loop: &ActiveEventLoop) {
|
||||
self.debugger.check_commands(&mut self.firmware, &mut self.hardware);
|
||||
|
||||
// Atualiza estado do Filesystem no OS (específico do prometeu-runtime-desktop)
|
||||
// Updates Filesystem state in OS (specific to prometeu-runtime-desktop)
|
||||
if let Some(root) = &self.fs_root {
|
||||
use prometeu_core::fs::FsState;
|
||||
if matches!(self.firmware.os.fs_state, FsState::Unmounted | FsState::Error(_)) {
|
||||
@ -220,7 +220,7 @@ impl ApplicationHandler for HostRunner {
|
||||
let now = Instant::now();
|
||||
let mut frame_delta = now.duration_since(self.last_frame_time);
|
||||
|
||||
// Limitador para evitar a "espiral da morte" se o SO travar (máximo de 100ms por volta)
|
||||
// Limiter to avoid the "death spiral" if the OS freezes (max 100ms per loop)
|
||||
if frame_delta > Duration::from_millis(100) {
|
||||
frame_delta = Duration::from_millis(100);
|
||||
}
|
||||
@ -228,7 +228,7 @@ impl ApplicationHandler for HostRunner {
|
||||
self.last_frame_time = now;
|
||||
self.accumulator += frame_delta;
|
||||
|
||||
// 🔥 O coração do determinismo: consome o tempo em fatias exatas de 60Hz
|
||||
// 🔥 The heart of determinism: consumes time in exact 60Hz slices
|
||||
while self.accumulator >= self.frame_target_dt {
|
||||
if !self.debugger.waiting_for_start {
|
||||
self.firmware.step_frame(&self.input.signals, &mut self.hardware);
|
||||
@ -242,10 +242,10 @@ impl ApplicationHandler for HostRunner {
|
||||
|
||||
self.audio.update_stats(&mut self.stats);
|
||||
|
||||
// Atualiza estatísticas a cada 1 segundo real
|
||||
// Updates statistics every 1 real second
|
||||
self.stats.update(now, self.window, &self.hardware, &self.firmware);
|
||||
|
||||
// Processa logs do sistema
|
||||
// Process system logs
|
||||
let last_seq = self.log_sink.last_seq().unwrap_or(u64::MAX);
|
||||
let new_events = if last_seq == u64::MAX {
|
||||
self.firmware.os.log_service.get_recent(4096)
|
||||
@ -254,11 +254,11 @@ impl ApplicationHandler for HostRunner {
|
||||
};
|
||||
self.log_sink.process_events(new_events);
|
||||
|
||||
// Overlay de Telemetria
|
||||
// Telemetry Overlay
|
||||
if self.overlay_enabled {
|
||||
self.hardware.gfx.present(); // Traz o front para o back para desenhar por cima
|
||||
self.hardware.gfx.present(); // Bring front to back to draw over
|
||||
self.display_dbg_overlay();
|
||||
self.hardware.gfx.present(); // Devolve para o front com o overlay aplicado
|
||||
self.hardware.gfx.present(); // Return to front with overlay applied
|
||||
}
|
||||
|
||||
self.request_redraw();
|
||||
@ -286,37 +286,37 @@ mod tests {
|
||||
assert!(runner.debugger.waiting_for_start);
|
||||
assert!(runner.debugger.listener.is_some());
|
||||
|
||||
// Verifica se conseguimos conectar
|
||||
// Check if we can connect
|
||||
{
|
||||
let mut stream = TcpStream::connect(format!("127.0.0.1:{}", port)).expect("Deve conectar");
|
||||
// Pequeno sleep para garantir que o SO processe
|
||||
let mut stream = TcpStream::connect(format!("127.0.0.1:{}", port)).expect("Should connect");
|
||||
// Short sleep to ensure the OS processes
|
||||
std::thread::sleep(std::time::Duration::from_millis(100));
|
||||
|
||||
// Simula o loop para aceitar a conexão
|
||||
// Simulates the loop to accept the connection
|
||||
runner.debugger.check_commands(&mut runner.firmware, &mut runner.hardware);
|
||||
assert!(runner.debugger.stream.is_some(), "Stream deve ter sido mantido aberto");
|
||||
assert!(runner.debugger.stream.is_some(), "Stream should have been kept open");
|
||||
|
||||
// Verifica Handshake
|
||||
// Handshake Check
|
||||
let mut buf = [0u8; 2048];
|
||||
let n = stream.read(&mut buf).expect("Deve ler handshake");
|
||||
let resp: serde_json::Value = serde_json::from_slice(&buf[..n]).expect("Handshake deve ser JSON válido");
|
||||
let n = stream.read(&mut buf).expect("Should read handshake");
|
||||
let resp: serde_json::Value = serde_json::from_slice(&buf[..n]).expect("Handshake should be valid JSON");
|
||||
assert_eq!(resp["type"], "handshake");
|
||||
assert_eq!(resp["protocol_version"], DEVTOOLS_PROTOCOL_VERSION);
|
||||
|
||||
// Envia start via JSON
|
||||
stream.write_all(b"{\"type\":\"start\"}\n").expect("Conexão deve estar aberta para escrita");
|
||||
// Send start via JSON
|
||||
stream.write_all(b"{\"type\":\"start\"}\n").expect("Connection should be open for writing");
|
||||
std::thread::sleep(std::time::Duration::from_millis(50));
|
||||
|
||||
// Processa o comando recebido
|
||||
// Process the received command
|
||||
runner.debugger.check_commands(&mut runner.firmware, &mut runner.hardware);
|
||||
assert!(!runner.debugger.waiting_for_start, "Execução deve ter iniciado após comando start");
|
||||
assert!(runner.debugger.listener.is_some(), "Listener deve permanecer aberto para reconexões");
|
||||
assert!(!runner.debugger.waiting_for_start, "Execution should have started after start command");
|
||||
assert!(runner.debugger.listener.is_some(), "Listener should remain open for reconnections");
|
||||
}
|
||||
|
||||
// Agora que o stream saiu do escopo do teste, o runner deve detectar o fechamento no próximo check
|
||||
// Now that the stream is out of the test scope, the runner should detect closure on next check
|
||||
std::thread::sleep(std::time::Duration::from_millis(50));
|
||||
runner.debugger.check_commands(&mut runner.firmware, &mut runner.hardware);
|
||||
assert!(runner.debugger.stream.is_none(), "Stream deve ter sido fechado após o cliente desconectar");
|
||||
assert!(runner.debugger.stream.is_none(), "Stream should have been closed after client disconnected");
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -329,32 +329,32 @@ mod tests {
|
||||
debug_port: port,
|
||||
});
|
||||
|
||||
// 1. Conecta e inicia
|
||||
// 1. Connect and start
|
||||
{
|
||||
let mut stream = TcpStream::connect(format!("127.0.0.1:{}", port)).expect("Deve conectar 1");
|
||||
let mut stream = TcpStream::connect(format!("127.0.0.1:{}", port)).expect("Should connect 1");
|
||||
std::thread::sleep(std::time::Duration::from_millis(50));
|
||||
runner.debugger.check_commands(&mut runner.firmware, &mut runner.hardware);
|
||||
assert!(runner.debugger.stream.is_some());
|
||||
|
||||
stream.write_all(b"{\"type\":\"start\"}\n").expect("Deve escrever start");
|
||||
stream.write_all(b"{\"type\":\"start\"}\n").expect("Should write start");
|
||||
std::thread::sleep(std::time::Duration::from_millis(50));
|
||||
runner.debugger.check_commands(&mut runner.firmware, &mut runner.hardware);
|
||||
assert!(!runner.debugger.waiting_for_start);
|
||||
// Atualmente o listener é fechado aqui.
|
||||
// Currently the listener is closed here.
|
||||
}
|
||||
|
||||
// 2. Desconecta (limpa o stream no runner)
|
||||
// 2. Disconnect (clears stream in runner)
|
||||
std::thread::sleep(std::time::Duration::from_millis(50));
|
||||
runner.debugger.check_commands(&mut runner.firmware, &mut runner.hardware);
|
||||
assert!(runner.debugger.stream.is_none());
|
||||
|
||||
// 3. Tenta reconectar - DEVE FALHAR atualmente, mas queremos que FUNCIONE
|
||||
// 3. Try to reconnect - SHOULD FAIL currently, but we want it to WORK
|
||||
let stream2 = TcpStream::connect(format!("127.0.0.1:{}", port));
|
||||
assert!(stream2.is_ok(), "Deve aceitar nova conexão mesmo após o start");
|
||||
assert!(stream2.is_ok(), "Should accept new connection even after start");
|
||||
|
||||
std::thread::sleep(std::time::Duration::from_millis(50));
|
||||
runner.debugger.check_commands(&mut runner.firmware, &mut runner.hardware);
|
||||
assert!(runner.debugger.stream.is_some(), "Stream deve ter sido aceito na reconexão");
|
||||
assert!(runner.debugger.stream.is_some(), "Stream should have been accepted on reconnection");
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -367,24 +367,24 @@ mod tests {
|
||||
debug_port: port,
|
||||
});
|
||||
|
||||
// 1. Primeira conexão
|
||||
let mut _stream1 = TcpStream::connect(format!("127.0.0.1:{}", port)).expect("Deve conectar 1");
|
||||
// 1. First connection
|
||||
let mut _stream1 = TcpStream::connect(format!("127.0.0.1:{}", port)).expect("Should connect 1");
|
||||
std::thread::sleep(std::time::Duration::from_millis(50));
|
||||
runner.debugger.check_commands(&mut runner.firmware, &mut runner.hardware);
|
||||
assert!(runner.debugger.stream.is_some());
|
||||
|
||||
// 2. Segunda conexão
|
||||
let mut stream2 = TcpStream::connect(format!("127.0.0.1:{}", port)).expect("Deve conectar 2 (SO aceita)");
|
||||
// 2. Second connection
|
||||
let mut stream2 = TcpStream::connect(format!("127.0.0.1:{}", port)).expect("Should connect 2 (OS accepts)");
|
||||
std::thread::sleep(std::time::Duration::from_millis(50));
|
||||
runner.debugger.check_commands(&mut runner.firmware, &mut runner.hardware); // Deve aceitar e fechar stream2
|
||||
runner.debugger.check_commands(&mut runner.firmware, &mut runner.hardware); // Should accept and close stream2
|
||||
|
||||
// Verifica se stream2 foi fechado pelo servidor
|
||||
// Check if stream2 was closed by the server
|
||||
let mut buf = [0u8; 10];
|
||||
stream2.set_read_timeout(Some(std::time::Duration::from_millis(100))).unwrap();
|
||||
let res = stream2.read(&mut buf);
|
||||
assert!(matches!(res, Ok(0)) || res.is_err(), "Segunda conexão deve ser fechada pelo servidor");
|
||||
assert!(matches!(res, Ok(0)) || res.is_err(), "Second connection should be closed by server");
|
||||
|
||||
assert!(runner.debugger.stream.is_some(), "Primeira conexão deve continuar ativa");
|
||||
assert!(runner.debugger.stream.is_some(), "First connection should continue active");
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -397,7 +397,7 @@ mod tests {
|
||||
debug_port: port,
|
||||
});
|
||||
|
||||
let stream = TcpStream::connect(format!("127.0.0.1:{}", port)).expect("Deve conectar");
|
||||
let stream = TcpStream::connect(format!("127.0.0.1:{}", port)).expect("Should connect");
|
||||
std::thread::sleep(std::time::Duration::from_millis(100));
|
||||
runner.debugger.check_commands(&mut runner.firmware, &mut runner.hardware);
|
||||
|
||||
@ -405,19 +405,19 @@ mod tests {
|
||||
let mut reader = std::io::BufReader::new(stream);
|
||||
|
||||
let mut line = String::new();
|
||||
reader.read_line(&mut line).expect("Deve ler handshake");
|
||||
reader.read_line(&mut line).expect("Should read handshake");
|
||||
assert!(line.contains("handshake"));
|
||||
|
||||
// Envia getState
|
||||
reader.get_mut().write_all(b"{\"type\":\"getState\"}\n").expect("Deve escrever getState");
|
||||
// Send getState
|
||||
reader.get_mut().write_all(b"{\"type\":\"getState\"}\n").expect("Should write getState");
|
||||
std::thread::sleep(std::time::Duration::from_millis(100));
|
||||
|
||||
runner.debugger.check_commands(&mut runner.firmware, &mut runner.hardware);
|
||||
|
||||
// Verifica se recebeu resposta (pode haver eventos/logs antes)
|
||||
// Check if response received (may have events/logs before)
|
||||
loop {
|
||||
line.clear();
|
||||
reader.read_line(&mut line).expect("Deve ler linha");
|
||||
reader.read_line(&mut line).expect("Should read line");
|
||||
if line.is_empty() { break; }
|
||||
|
||||
if let Ok(resp) = serde_json::from_str::<serde_json::Value>(&line) {
|
||||
@ -426,7 +426,7 @@ mod tests {
|
||||
}
|
||||
}
|
||||
}
|
||||
panic!("Não recebeu resposta getState");
|
||||
panic!("Did not receive getState response");
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -439,24 +439,24 @@ mod tests {
|
||||
debug_port: port,
|
||||
});
|
||||
|
||||
// 1. Conecta e pausa
|
||||
// 1. Connect and pause
|
||||
{
|
||||
let mut stream = TcpStream::connect(format!("127.0.0.1:{}", port)).expect("Deve conectar");
|
||||
let mut stream = TcpStream::connect(format!("127.0.0.1:{}", port)).expect("Should connect");
|
||||
std::thread::sleep(std::time::Duration::from_millis(50));
|
||||
runner.debugger.check_commands(&mut runner.firmware, &mut runner.hardware);
|
||||
|
||||
stream.write_all(b"{\"type\":\"pause\"}\n").expect("Deve escrever pause");
|
||||
stream.write_all(b"{\"type\":\"pause\"}\n").expect("Should write pause");
|
||||
std::thread::sleep(std::time::Duration::from_millis(50));
|
||||
runner.debugger.check_commands(&mut runner.firmware, &mut runner.hardware);
|
||||
assert!(runner.firmware.os.paused, "VM deve estar pausada");
|
||||
assert!(runner.firmware.os.paused, "VM should be paused");
|
||||
}
|
||||
|
||||
// 2. Desconecta (stream sai de escopo)
|
||||
// 2. Disconnect (stream goes out of scope)
|
||||
std::thread::sleep(std::time::Duration::from_millis(50));
|
||||
runner.debugger.check_commands(&mut runner.firmware, &mut runner.hardware);
|
||||
|
||||
// 3. Verifica se despausou
|
||||
assert!(!runner.firmware.os.paused, "VM deve ter despausado após desconexão");
|
||||
assert!(!runner.debugger.waiting_for_start, "VM deve ter saído do estado waiting_for_start");
|
||||
// 3. Check if unpaused
|
||||
assert!(!runner.firmware.os.paused, "VM should have unpaused after disconnect");
|
||||
assert!(!runner.debugger.waiting_for_start, "VM should have left waiting_for_start state");
|
||||
}
|
||||
}
|
||||
|
||||
@ -39,7 +39,7 @@ impl HostStats {
|
||||
if let Some(window) = window {
|
||||
let kb = hardware.gfx.memory_usage_bytes() as f64 / 1024.0;
|
||||
|
||||
// comparação fixa sempre contra 60Hz, manter mesmo quando fazer teste de stress na CPU
|
||||
// Fixed comparison always against 60Hz, keep even when doing CPU stress tests
|
||||
let frame_budget_us = 16666.0;
|
||||
let cpu_load_core = (firmware.os.last_frame_cpu_time_us as f64 / frame_budget_us) * 100.0;
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/// Copia RGB565 (u16) -> RGBA8888 (u8[4]) para o frame do pixels.
|
||||
/// Formato do pixels: RGBA8.
|
||||
/// Copies RGB565 (u16) -> RGBA8888 (u8[4]) to the pixels frame.
|
||||
/// Pixels format: RGBA8.
|
||||
pub fn draw_rgb565_to_rgba8(src: &[u16], dst_rgba: &mut [u8]) {
|
||||
for (i, &px) in src.iter().enumerate() {
|
||||
let (r8, g8, b8) = rgb565_to_rgb888(px);
|
||||
@ -11,7 +11,7 @@ pub fn draw_rgb565_to_rgba8(src: &[u16], dst_rgba: &mut [u8]) {
|
||||
}
|
||||
}
|
||||
|
||||
/// Expande RGB565 para RGB888 (replicação de bits altos).
|
||||
/// Expands RGB565 to RGB888 (high bit replication).
|
||||
#[inline(always)]
|
||||
pub fn rgb565_to_rgb888(px: u16) -> (u8, u8, u8) {
|
||||
let r5 = ((px >> 11) & 0x1F) as u8;
|
||||
|
||||
@ -1,14 +1,14 @@
|
||||
# PROMETEU CLI (Dispatcher)
|
||||
|
||||
O binário `prometeu` atua como o front-end unificado para o ecossistema. Ele não implementa a lógica de execução ou compilação, mas sabe onde encontrar os binários que as implementam.
|
||||
The `prometeu` binary acts as the unified front-end for the ecosystem. It does not implement the execution or compilation logic but knows where to find the binaries that do.
|
||||
|
||||
## Comandos
|
||||
## Commands
|
||||
|
||||
- `prometeu run <cart>`: Executa um cartucho usando o runtime disponível.
|
||||
- `prometeu debug <cart> [--port <p>]`: Inicia a execução em modo de depuração.
|
||||
- `prometeu build <projectDir>`: (Planejado) Chama o compilador `prometeuc`.
|
||||
- `prometeu pack <cartDir>`: (Planejado) Chama o empacotador `prometeup`.
|
||||
- `prometeu run <cart>`: Runs a cartridge using the available runtime.
|
||||
- `prometeu debug <cart> [--port <p>]`: Starts execution in debug mode.
|
||||
- `prometeu build <projectDir>`: (Planned) Calls the `prometeuc` compiler.
|
||||
- `prometeu pack <cartDir>`: (Planned) Calls the `prometeup` packager.
|
||||
|
||||
## Funcionamento
|
||||
## How it works
|
||||
|
||||
O dispatcher localiza os binários irmãos (`prometeu-runtime`, `prometeuc`, etc.) no mesmo diretório onde ele próprio está instalado. Ele herda `stdin`, `stdout` e `stderr`, e propaga o código de saída do processo chamado.
|
||||
The dispatcher locates sibling binaries (`prometeu-runtime`, `prometeuc`, etc.) in the same directory where it is installed. It inherits `stdin`, `stdout`, and `stderr`, and propagates the exit code of the called process.
|
||||
|
||||
@ -5,7 +5,7 @@ use std::process::Command;
|
||||
|
||||
#[derive(Parser)]
|
||||
#[command(name = "prometeu")]
|
||||
#[command(about = "Dispatcher para o ecossistema Prometeu", long_about = None)]
|
||||
#[command(about = "Dispatcher for the Prometeu ecosystem", long_about = None)]
|
||||
struct Cli {
|
||||
#[command(subcommand)]
|
||||
command: Option<Commands>,
|
||||
@ -13,30 +13,30 @@ struct Cli {
|
||||
|
||||
#[derive(Subcommand)]
|
||||
enum Commands {
|
||||
/// Executa um cartucho
|
||||
/// Executes a cartridge
|
||||
Run {
|
||||
/// Caminho para o cartucho
|
||||
/// Path to the cartridge
|
||||
cart: String,
|
||||
},
|
||||
/// Debuga um cartucho
|
||||
/// Debugs a cartridge
|
||||
Debug {
|
||||
/// Caminho para o cartucho
|
||||
/// Path to the cartridge
|
||||
cart: String,
|
||||
/// Porta para o debugger (padrão: 7777)
|
||||
/// Port for the debugger (default: 7777)
|
||||
#[arg(long, default_value_t = 7777)]
|
||||
port: u16,
|
||||
},
|
||||
/// Compila um projeto
|
||||
/// Builds a project
|
||||
Build {
|
||||
/// Diretório do projeto
|
||||
/// Project directory
|
||||
project_dir: String,
|
||||
},
|
||||
/// Empacota um cartucho
|
||||
/// Packages a cartridge
|
||||
Pack {
|
||||
/// Diretório do cartucho
|
||||
/// Cartridge directory
|
||||
cart_dir: String,
|
||||
},
|
||||
/// Verifica integridade de um projeto ou cartucho
|
||||
/// Verifies the integrity of a project or cartridge
|
||||
Verify {
|
||||
#[command(subcommand)]
|
||||
target: VerifyCommands,
|
||||
@ -45,14 +45,14 @@ enum Commands {
|
||||
|
||||
#[derive(Subcommand)]
|
||||
enum VerifyCommands {
|
||||
/// Verifica um projeto
|
||||
/// Verifies a project
|
||||
C {
|
||||
/// Diretório do projeto
|
||||
/// Project directory
|
||||
project_dir: String,
|
||||
},
|
||||
/// Verifica um cartucho ou arquivo PMC
|
||||
/// Verifies a cartridge or PMC file
|
||||
P {
|
||||
/// Caminho para o cartucho ou PMC
|
||||
/// Path to the cartridge or PMC
|
||||
cart_or_pmc: String,
|
||||
},
|
||||
}
|
||||
@ -63,7 +63,7 @@ fn main() {
|
||||
let exe_dir = match env::current_exe() {
|
||||
Ok(exe_path) => exe_path.parent().unwrap_or_else(|| Path::new(".")).to_path_buf(),
|
||||
Err(e) => {
|
||||
eprintln!("Erro ao obter o caminho do executável: {}", e);
|
||||
eprintln!("Error obtaining executable path: {}", e);
|
||||
std::process::exit(1);
|
||||
}
|
||||
};
|
||||
@ -109,8 +109,8 @@ fn dispatch(exe_dir: &Path, bin_name: &str, args: &[&str]) {
|
||||
let bin_path = get_binary_path(exe_dir, bin_name);
|
||||
|
||||
if !bin_path.exists() {
|
||||
// Tenta encontrar o runtime com o nome exato (prometeu-runtime-desktop)
|
||||
// caso prometeu-runtime seja apenas um alias ou link que ainda não existe
|
||||
// Tries to find the runtime with the exact name (prometeu-runtime-desktop)
|
||||
// in case prometeu-runtime is just an alias or link that doesn't exist yet
|
||||
let alt_bin_name = if bin_name == "prometeu-runtime" {
|
||||
Some("prometeu-runtime-desktop")
|
||||
} else {
|
||||
@ -130,7 +130,7 @@ fn dispatch(exe_dir: &Path, bin_name: &str, args: &[&str]) {
|
||||
|
||||
if !final_bin_path.exists() {
|
||||
eprintln!(
|
||||
"prometeu: comando '{}' ainda não está disponível nesta distribuição",
|
||||
"prometeu: command '{}' is not yet available in this distribution",
|
||||
match bin_name {
|
||||
"prometeu-runtime" => "run/debug",
|
||||
"prometeuc" => "build/verify c",
|
||||
@ -159,7 +159,7 @@ fn execute_bin(bin_path: &Path, args: &[&str]) {
|
||||
std::process::exit(status.code().unwrap_or(0));
|
||||
}
|
||||
Err(e) => {
|
||||
eprintln!("Erro ao executar {}: {}", bin_path.display(), e);
|
||||
eprintln!("Error executing {}: {}", bin_path.display(), e);
|
||||
std::process::exit(1);
|
||||
}
|
||||
}
|
||||
@ -167,7 +167,7 @@ fn execute_bin(bin_path: &Path, args: &[&str]) {
|
||||
|
||||
fn not_implemented(cmd: &str, _bin_name: &str) {
|
||||
eprintln!(
|
||||
"prometeu: comando '{}' ainda não está disponível nesta distribuição",
|
||||
"prometeu: command '{}' is not yet available in this distribution",
|
||||
cmd
|
||||
);
|
||||
std::process::exit(1);
|
||||
|
||||
@ -1,31 +1,31 @@
|
||||
# Prometeu DevTools Protocol
|
||||
|
||||
Este documento descreve o protocolo de comunicação entre o Runtime do Prometeu e ferramentas de desenvolvimento (como o Prometeu Debugger).
|
||||
This document describes the communication protocol between the Prometeu Runtime and development tools (such as the Prometeu Debugger).
|
||||
|
||||
## Visão Geral
|
||||
## Overview
|
||||
|
||||
O protocolo é baseado em JSON, enviado via uma conexão de transporte (geralmente TCP). Cada mensagem é um objeto JSON em uma única linha (JSONL).
|
||||
The protocol is based on JSON, sent via a transport connection (usually TCP). Each message is a JSON object on a single line (JSONL).
|
||||
|
||||
## Estrutura
|
||||
## Structure
|
||||
|
||||
- **[protocol.json](./protocol.json)**: Definição formal do protocolo em formato JSON.
|
||||
- **[protocol.md](README.md)**: Documentação legível para humanos descrevendo os comandos, eventos e tipos.
|
||||
- **[examples/](./examples)**: Exemplos de fluxos de mensagens (handshake, breakpoints, etc.) em formato JSONL.
|
||||
- **[protocol.json](./protocol.json)**: Formal definition of the protocol in JSON format.
|
||||
- **[protocol.md](README.md)**: Human-readable documentation describing commands, events, and types.
|
||||
- **[examples/](./examples)**: Examples of message flows (handshake, breakpoints, etc.) in JSONL format.
|
||||
|
||||
## Versionamento
|
||||
## Versioning
|
||||
|
||||
O protocolo possui uma versão explícita definida no campo `protocol_version`.
|
||||
The protocol has an explicit version defined in the `protocol_version` field.
|
||||
|
||||
- Mudanças incompatíveis (breaking changes) incrementam a versão principal.
|
||||
- Novos campos em mensagens existentes devem ser opcionais sempre que possível para manter compatibilidade retroativa.
|
||||
- Incompatible changes (breaking changes) increment the major version.
|
||||
- New fields in existing messages should be optional whenever possible to maintain backward compatibility.
|
||||
|
||||
A versão atual do protocolo é: **1**
|
||||
The current protocol version is: **1**
|
||||
|
||||
## Handshake
|
||||
|
||||
Ao conectar, o Runtime envia uma mensagem de handshake para o cliente.
|
||||
Upon connecting, the Runtime sends a handshake message to the client.
|
||||
|
||||
### Runtime -> Cliente
|
||||
### Runtime -> Client
|
||||
|
||||
```json
|
||||
{
|
||||
@ -41,43 +41,43 @@ Ao conectar, o Runtime envia uma mensagem de handshake para o cliente.
|
||||
}
|
||||
```
|
||||
|
||||
### Cliente -> Runtime
|
||||
### Client -> Runtime
|
||||
|
||||
O cliente deve responder com `start` ou `ok` para iniciar a sessão.
|
||||
The client must respond with `start` or `ok` to start the session.
|
||||
|
||||
```json
|
||||
{ "type": "start" }
|
||||
```
|
||||
|
||||
## Requisições (Requests)
|
||||
## Requests
|
||||
|
||||
O cliente pode enviar as seguintes requisições para controlar a execução:
|
||||
The client can send the following requests to control execution:
|
||||
|
||||
| Nome | Parâmetros | Descrição |
|
||||
| Name | Parameters | Description |
|
||||
|------|------------|-----------|
|
||||
| `pause` | `[]` | Pausa a execução da VM. |
|
||||
| `resume` | `[]` | Retoma a execução da VM. |
|
||||
| `step` | `[]` | Executa uma única instrução (PC). |
|
||||
| `stepFrame` | `[]` | Executa até o próximo frame. |
|
||||
| `getState` | `[]` | Retorna o estado atual da VM (`pc`, `stack_top`, `frame_index`, `app_id`). |
|
||||
| `setBreakpoint` | `{"pc": number}` | Define um breakpoint no endereço especificado. |
|
||||
| `clearBreakpoint` | `{"pc": number}` | Remove um breakpoint no endereço especificado. |
|
||||
| `pause` | `[]` | Pauses VM execution. |
|
||||
| `resume` | `[]` | Resumes VM execution. |
|
||||
| `step` | `[]` | Executes a single instruction (PC). |
|
||||
| `stepFrame` | `[]` | Executes until the next frame. |
|
||||
| `getState` | `[]` | Returns the current VM state (`pc`, `stack_top`, `frame_index`, `app_id`). |
|
||||
| `setBreakpoint` | `{"pc": number}` | Sets a breakpoint at the specified address. |
|
||||
| `clearBreakpoint` | `{"pc": number}` | Removes a breakpoint at the specified address. |
|
||||
|
||||
## Respostas (Responses)
|
||||
## Responses
|
||||
|
||||
Algumas requisições geram respostas específicas. Por exemplo, `getState` retorna o estado da VM.
|
||||
Some requests generate specific responses. For example, `getState` returns the VM state.
|
||||
|
||||
## Eventos (Events)
|
||||
## Events
|
||||
|
||||
O Runtime pode enviar eventos assíncronos para o cliente:
|
||||
The Runtime can send asynchronous events to the client:
|
||||
|
||||
| Nome | Campos | Descrição |
|
||||
| Name | Fields | Description |
|
||||
|------|--------|-----------|
|
||||
| `breakpointHit` | `pc`, `frame_index` | Emitido quando a execução atinge um breakpoint. |
|
||||
| `log` | `level`, `source`, `msg` | Emitido quando o código em execução gera um log. |
|
||||
| `telemetry` | `frame_index`, `vm_steps`, `syscalls`, `cycles` | Estatísticas de execução enviadas periodicamente. |
|
||||
| `cert` | `rule`, `used`, `limit`, `frame_index` | Informações de certificação e limites de recursos. |
|
||||
| `breakpointHit` | `pc`, `frame_index` | Emitted when execution hits a breakpoint. |
|
||||
| `log` | `level`, `source`, `msg` | Emitted when the running code generates a log. |
|
||||
| `telemetry` | `frame_index`, `vm_steps`, `syscalls`, `cycles` | Execution statistics sent periodically. |
|
||||
| `cert` | `rule`, `used`, `limit`, `frame_index` | Certification information and resource limits. |
|
||||
|
||||
## Exemplos
|
||||
## Examples
|
||||
|
||||
Veja a pasta `examples/` para fluxos de mensagens completos.
|
||||
See the `examples/` folder for complete message flows.
|
||||
|
||||
@ -1,15 +1,15 @@
|
||||
# PROMETEU Documentation
|
||||
|
||||
Este diretório contém a documentação técnica e especificações do projeto PROMETEU.
|
||||
This directory contains the technical documentation and specifications for the PROMETEU project.
|
||||
|
||||
## Conteúdo
|
||||
## Content
|
||||
|
||||
### 📜 [Especificações (Specs)](./specs)
|
||||
Documentação detalhada sobre a arquitetura do sistema, formato de cartuchos, conjunto de instruções da VM e muito mais.
|
||||
- [Índice de Tópicos](./specs/topics/table-of-contents.md)
|
||||
### 📜 [Specifications (Specs)](./specs)
|
||||
Detailed documentation on system architecture, cartridge format, VM instruction set, and more.
|
||||
- [Topic Index](./specs/topics/table-of-contents.md)
|
||||
|
||||
### 🐞 [Debugger](./debugger)
|
||||
Documentação sobre as ferramentas de depuração e como integrar novas ferramentas ao ecossistema.
|
||||
Documentation on debugging tools and how to integrate new tools into the ecosystem.
|
||||
|
||||
### 🔌 [DevTools Protocol](../devtools-protocol)
|
||||
Definição do protocolo de comunicação utilizado para depuração e inspeção em tempo real.
|
||||
Definition of the communication protocol used for real-time debugging and inspection.
|
||||
|
||||
@ -1,113 +1,113 @@
|
||||
# Especificação — Ciclo de Desenvolvimento Prometeu
|
||||
**Versão:** 0.1
|
||||
**Status:** Conceitual / Filosófico
|
||||
# Specification — Prometeu Development Cycle
|
||||
**Version:** 0.1
|
||||
**Status:** Conceptual / Philosophical
|
||||
|
||||
---
|
||||
|
||||
## 1. Princípio Central
|
||||
## 1. Central Principle
|
||||
|
||||
O Prometeu é uma plataforma didática de desenvolvimento de software interativo.
|
||||
Seu ciclo de desenvolvimento é projetado para separar claramente:
|
||||
Prometeu is a didactic platform for interactive software development.
|
||||
Its development cycle is designed to clearly separate:
|
||||
|
||||
- Criação de código
|
||||
- Compilação
|
||||
- Execução
|
||||
- Observação e explicação
|
||||
- Code creation
|
||||
- Compilation
|
||||
- Execution
|
||||
- Observation and explanation
|
||||
|
||||
Cada etapa possui uma ferramenta própria, especializada e não sobreposta.
|
||||
Each stage has its own specialized, non-overlapping tool.
|
||||
|
||||
---
|
||||
|
||||
## 2. Ferramentas do Ciclo
|
||||
## 2. Cycle Tools
|
||||
|
||||
O ciclo utiliza quatro pilares:
|
||||
The cycle uses four pillars:
|
||||
|
||||
1. **Editor de Código**
|
||||
Ambiente livre (ex: WebStorm) onde o desenvolvedor escreve em TypeScript.
|
||||
1. **Code Editor**
|
||||
Free environment (e.g., WebStorm) where the developer writes in TypeScript.
|
||||
|
||||
2. **Compilador Prometeu**
|
||||
Converte código fonte em bytecode executável pela runtime Prometeu.
|
||||
2. **Prometeu Compiler**
|
||||
Converts source code into executable bytecode for the Prometeu runtime.
|
||||
|
||||
3. **Runtime Prometeu**
|
||||
Executa jogos e aplicações em seu próprio ambiente gráfico.
|
||||
3. **Prometeu Runtime**
|
||||
Executes games and applications in its own graphical environment.
|
||||
|
||||
4. **Prometeu Debugger**
|
||||
Ferramenta didática de observação, análise e explicação do comportamento interno do sistema.
|
||||
A didactic tool for observation, analysis, and explanation of the system's internal behavior.
|
||||
|
||||
Nenhuma dessas ferramentas tenta substituir a outra.
|
||||
Elas cooperam através de contratos claros.
|
||||
None of these tools try to replace each other.
|
||||
They cooperate through clear contracts.
|
||||
|
||||
---
|
||||
|
||||
## 3. Fluxo Geral
|
||||
## 3. General Flow
|
||||
|
||||
O ciclo segue sempre a mesma sequência conceitual:
|
||||
The cycle always follows the same conceptual sequence:
|
||||
|
||||
1. O desenvolvedor escreve código em TypeScript.
|
||||
2. O código é compilado para bytecode Prometeu.
|
||||
3. O bytecode é empacotado como cartucho.
|
||||
4. O cartucho é executado pela runtime.
|
||||
5. O comportamento interno pode ser observado pelo Prometeu Debugger.
|
||||
1. The developer writes code in TypeScript.
|
||||
2. The code is compiled to Prometeu bytecode.
|
||||
3. The bytecode is packaged as a cartridge.
|
||||
4. The cartridge is executed by the runtime.
|
||||
5. Internal behavior can be observed by the Prometeu Debugger.
|
||||
|
||||
---
|
||||
|
||||
## 4. Modos de Execução
|
||||
## 4. Execution Modes
|
||||
|
||||
O Prometeu possui dois modos conceituais de execução:
|
||||
Prometeu has two conceptual execution modes:
|
||||
|
||||
### Execução Normal (Run)
|
||||
### Normal Execution (Run)
|
||||
|
||||
- O cartucho é empacotado e executado.
|
||||
- A runtime funciona de forma autônoma.
|
||||
- O Debugger atua apenas como observador.
|
||||
- The cartridge is packaged and executed.
|
||||
- The runtime operates autonomously.
|
||||
- The Debugger acts only as an observer.
|
||||
|
||||
### Execução Assistida (Debug)
|
||||
### Assisted Execution (Debug)
|
||||
|
||||
- O cartucho é empacotado e executado.
|
||||
- A runtime aguarda conexão do Prometeu Debugger.
|
||||
- O Debugger passa a controlar e observar a execução.
|
||||
- The cartridge is packaged and executed.
|
||||
- The runtime waits for a connection from the Prometeu Debugger.
|
||||
- The Debugger begins to control and observe the execution.
|
||||
|
||||
---
|
||||
|
||||
## 5. Separação de Papéis
|
||||
## 5. Separation of Roles
|
||||
|
||||
Cada parte do ciclo tem responsabilidade única:
|
||||
Each part of the cycle has a unique responsibility:
|
||||
|
||||
| Etapa | Papel principal |
|
||||
|-----------|--------------------------------------|
|
||||
| Editor | Criar código |
|
||||
| Compilador| Transformar código em bytecode |
|
||||
| Runtime | Executar |
|
||||
| Debugger | Observar, explicar e ensinar |
|
||||
| Stage | Main Role |
|
||||
|------------|------------------------------------|
|
||||
| Editor | Create code |
|
||||
| Compiler | Transform code into bytecode |
|
||||
| Runtime | Execute |
|
||||
| Debugger | Observe, explain, and teach |
|
||||
|
||||
Essa separação é intencional e parte da filosofia do Prometeu.
|
||||
This separation is intentional and part of the Prometeu philosophy.
|
||||
|
||||
---
|
||||
|
||||
## 6. Filosofia Didática
|
||||
## 6. Didactic Philosophy
|
||||
|
||||
O Prometeu não é apenas uma engine.
|
||||
Ele é uma plataforma para aprender como software interativo funciona por dentro.
|
||||
Prometeu is not just an engine.
|
||||
It is a platform for learning how interactive software works from the inside.
|
||||
|
||||
O ciclo de desenvolvimento é pensado para:
|
||||
The development cycle is designed to:
|
||||
|
||||
- Tornar a execução visível
|
||||
- Tornar decisões técnicas observáveis
|
||||
- Tornar erros explicáveis
|
||||
- Tornar desempenho mensurável
|
||||
- Make execution visible
|
||||
- Make technical decisions observable
|
||||
- Make errors explainable
|
||||
- Make performance measurable
|
||||
|
||||
O Debugger não é apenas uma ferramenta de correção, mas um instrumento pedagógico.
|
||||
The Debugger is not just a fix tool, but a pedagogical instrument.
|
||||
|
||||
---
|
||||
|
||||
## 7. Síntese
|
||||
## 7. Synthesis
|
||||
|
||||
O Ciclo de Desenvolvimento Prometeu é:
|
||||
The Prometeu Development Cycle is:
|
||||
|
||||
- Modular
|
||||
- Observável
|
||||
- Didático
|
||||
- Não acoplado a uma IDE específica
|
||||
- Orientado a aprendizado e compreensão profunda
|
||||
- Observable
|
||||
- Didactic
|
||||
- Not coupled to a specific IDE
|
||||
- Oriented towards learning and deep understanding
|
||||
|
||||
Ele existe para que o desenvolvedor não apenas escreva programas, mas entenda como eles vivem dentro da máquina.
|
||||
It exists so that the developer does not just write programs, but understands how they live inside the machine.
|
||||
|
||||
@ -1,190 +1,190 @@
|
||||
# 📜 Prometeu — O Fogo e a Promessa
|
||||
# 📜 Prometeu — The Fire and the Promise
|
||||
|
||||
**PROMETEU** é um console imaginário.
|
||||
**PROMETEU** is an imaginary console.
|
||||
|
||||
Mas não no sentido fraco de “imaginar”.
|
||||
But not in the weak sense of "imagining".
|
||||
|
||||
PROMETEU foi **deliberadamente projetado** para existir como um **modelo computacional completo**: simples o bastante para ser entendido, e poderoso o suficiente para criar jogos reais.
|
||||
PROMETEU was **deliberately designed** to exist as a **complete computational model**: simple enough to be understood, and powerful enough to create real games.
|
||||
|
||||
O nome PROMETEU carrega dois significados intencionais:
|
||||
The name PROMETEU carries two intentional meanings:
|
||||
|
||||
- **Prometeu, o titã**, que roubou o fogo dos deuses e entregou aos humanos
|
||||
- **“Prometeu” como verbo**, uma promessa feita
|
||||
- **Prometheus, the titan**, who stole fire from the gods and gave it to humans
|
||||
- **“Prometeu” as a verb**, a promise made (in Portuguese)
|
||||
|
||||
Neste projeto:
|
||||
In this project:
|
||||
|
||||
- o *fogo* é o conhecimento de como computadores realmente funcionam
|
||||
- a *promessa* é que nada é mágico, nada é escondido, e tudo pode ser compreendido
|
||||
- the *fire* is the knowledge of how computers really work
|
||||
- the *promise* is that nothing is magic, nothing is hidden, and everything can be understood
|
||||
|
||||
Este manual é essa promessa escrita.
|
||||
This manual is that written promise.
|
||||
|
||||
---
|
||||
|
||||
## 🎯 O que é o PROMETEU
|
||||
## 🎯 What is PROMETEU
|
||||
|
||||
PROMETEU é um **Virtual Microconsole** — um computador fictício, com regras claras, recursos limitados e comportamento determinístico.
|
||||
PROMETEU is a **Virtual Microconsole** — a fictitious computer, with clear rules, limited resources, and deterministic behavior.
|
||||
|
||||
Ele foi projetado para:
|
||||
It was designed to:
|
||||
|
||||
- ensinar fundamentos reais de computação
|
||||
- expor tempo, memória e execução
|
||||
- permitir jogos 2D completos (plataformers, metroidvanias, arcade)
|
||||
- servir como ponte entre:
|
||||
- microcontroladores
|
||||
- consoles clássicos
|
||||
- máquinas virtuais
|
||||
- engines modernas
|
||||
- teach real computing fundamentals
|
||||
- expose time, memory, and execution
|
||||
- allow full 2D games (platformers, metroidvanias, arcade)
|
||||
- serve as a bridge between:
|
||||
- microcontrollers
|
||||
- classic consoles
|
||||
- virtual machines
|
||||
- modern engines
|
||||
|
||||
PROMETEU **não é**:
|
||||
PROMETEU **is not**:
|
||||
|
||||
- uma engine genérica
|
||||
- um substituto de Unity ou Godot
|
||||
- um console comercial real
|
||||
- a generic engine
|
||||
- a substitute for Unity or Godot
|
||||
- a real commercial console
|
||||
|
||||
PROMETEU **é**:
|
||||
PROMETEU **is**:
|
||||
|
||||
- um laboratório
|
||||
- um instrumento didático
|
||||
- um brinquedo sério
|
||||
- a laboratory
|
||||
- a didactic instrument
|
||||
- a serious toy
|
||||
|
||||
---
|
||||
|
||||
## 🧠 Modelo Mental Fundamental
|
||||
## 🧠 Fundamental Mental Model
|
||||
|
||||
> PROMETEU é um microcontrolador que desenha pixels, toca som e lida com inputs do jogador.
|
||||
> PROMETEU is a microcontroller that draws pixels, plays sound, and handles player input.
|
||||
>
|
||||
|
||||
Tudo no sistema deriva disso.
|
||||
Everything in the system derives from this.
|
||||
|
||||
### Equivalência conceitual
|
||||
### Conceptual equivalence
|
||||
|
||||
| Microcontrolador real | PROMETEU |
|
||||
| Real microcontroller | PROMETEU |
|
||||
| --- | --- |
|
||||
| Clock | Tick da VM |
|
||||
| Flash | Cartucho PROMETEU |
|
||||
| Clock | VM Tick |
|
||||
| Flash | PROMETEU Cartridge |
|
||||
| RAM | Heap + Stack |
|
||||
| GPIO | Input |
|
||||
| DMA | Transferência gráfica |
|
||||
| ISR | Eventos do sistema |
|
||||
| Periféricos | GFX, AUDIO, INPUT, FS |
|
||||
| DMA | Graphics transfer |
|
||||
| ISR | System events |
|
||||
| Peripherals | GFX, AUDIO, INPUT, FS |
|
||||
|
||||
Se você entende um MCU, você entende PROMETEU.
|
||||
If you understand an MCU, you understand PROMETEU.
|
||||
|
||||
---
|
||||
|
||||
## 🧩 Filosofia de Design
|
||||
## 🧩 Design Philosophy
|
||||
|
||||
### 1. Simplicidade visível
|
||||
### 1. Visible Simplicity
|
||||
|
||||
- Cada operação tem custo
|
||||
- Cada frame tem orçamento
|
||||
- Cada erro tem causa observável
|
||||
- Every operation has a cost
|
||||
- Every frame has a budget
|
||||
- Every error has an observable cause
|
||||
|
||||
Nada acontece “porque sim”.
|
||||
Nothing happens "just because".
|
||||
|
||||
### 2. Determinismo
|
||||
### 2. Determinism
|
||||
|
||||
- Mesmo cartucho
|
||||
- Mesma entrada
|
||||
- Mesmo resultado
|
||||
- Same cartridge
|
||||
- Same input
|
||||
- Same result
|
||||
|
||||
Independente da plataforma.
|
||||
Regardless of the platform.
|
||||
|
||||
### 3. Limitação como ferramenta pedagógica
|
||||
### 3. Limitation as a pedagogical tool
|
||||
|
||||
PROMETEU impõe limites **intencionais**:
|
||||
PROMETEU imposes **intentional** limits:
|
||||
|
||||
- memória finita
|
||||
- tempo por frame
|
||||
- recursos gráficos limitados
|
||||
- finite memory
|
||||
- time per frame
|
||||
- limited graphics resources
|
||||
|
||||
Limites ensinam design.
|
||||
Limits teach design.
|
||||
|
||||
### 4. Profundidade progressiva
|
||||
### 4. Progressive depth
|
||||
|
||||
PROMETEU pode ser explorado em camadas:
|
||||
PROMETEU can be explored in layers:
|
||||
|
||||
1. **Camada Jogo** — `update()` e `draw()`
|
||||
2. **Camada Sistema** — bytecode, stack, heap
|
||||
3. **Camada Máquina** — ciclos, eventos, periféricos
|
||||
1. **Game Layer** — `update()` and `draw()`
|
||||
2. **System Layer** — bytecode, stack, heap
|
||||
3. **Machine Layer** — cycles, events, peripherals
|
||||
|
||||
O aluno decide até onde descer.
|
||||
The student decides how deep to go.
|
||||
|
||||
## 🏗️ Arquitetura Geral
|
||||
## 🏗️ General Architecture
|
||||
|
||||
```
|
||||
+---------------------------+
|
||||
| CARTUCHO |
|
||||
| CARTRIDGE |
|
||||
| (bytecodeX + assets) |
|
||||
+-------------+-------------+
|
||||
|
|
||||
+-------------v-------------+
|
||||
| PROMETEU VM |
|
||||
| (stack-based, |
|
||||
| determinística) |
|
||||
| deterministic) |
|
||||
+-------------+-------------+
|
||||
|
|
||||
+-------------v-------------+
|
||||
| PERIFÉRICOS VIRTUAIS |
|
||||
| VIRTUAL PERIPHERALS |
|
||||
| GFX | AUDIO |INPUT | FS| |
|
||||
+-------------+-------------+
|
||||
|
|
||||
+-------------v-------------+
|
||||
| CAMADA DE PLATAFORMA |
|
||||
| PLATFORM LAYER |
|
||||
| PC | SteamOS | Android |
|
||||
| iOS | Consoles (futuro) |
|
||||
| iOS | Consoles (future) |
|
||||
+---------------------------+
|
||||
```
|
||||
|
||||
Este manual descreve **a máquina PROMETEU**, não ferramentas externas.
|
||||
This manual describes **the PROMETEU machine**, not external tools.
|
||||
|
||||
---
|
||||
|
||||
## 📦 O Cartucho PROMETEU
|
||||
## 📦 The PROMETEU Cartridge
|
||||
|
||||
Um **cartucho PROMETEU** é um pacote imutável, equivalente a firmware.
|
||||
A **PROMETEU cartridge** is an immutable package, equivalent to firmware.
|
||||
|
||||
Conteúdo típico:
|
||||
Typical content:
|
||||
|
||||
- `program.pbx` — bytecode PROMETEU (bytecodeX)
|
||||
- `assets/` — gráficos, áudio, mapas
|
||||
- `manifest.json` — metadados e configuração
|
||||
- `program.pbx` — PROMETEU bytecode (bytecodeX)
|
||||
- `assets/` — graphics, audio, maps
|
||||
- `manifest.json` — metadata and configuration
|
||||
|
||||
O cartucho:
|
||||
The cartridge:
|
||||
|
||||
- sempre pode ser executado
|
||||
- sempre pode ser distribuído
|
||||
- nunca é bloqueado pelo sistema
|
||||
- can always be executed
|
||||
- can always be distributed
|
||||
- is never blocked by the system
|
||||
|
||||
---
|
||||
|
||||
## 🧪 Linguagens de Programação
|
||||
## 🧪 Programming Languages
|
||||
|
||||
PROMETEU **não executa linguagens de alto nível diretamente**.
|
||||
PROMETEU **does not execute high-level languages directly**.
|
||||
|
||||
As linguagens são **fontes**, compiladas para bytecode PROMETEU.
|
||||
The languages are **sources**, compiled to PROMETEU bytecode.
|
||||
|
||||
### Linguagens planejadas
|
||||
### Planned languages
|
||||
|
||||
- **Java (subset)** — arquitetura, ensino profundo
|
||||
- **TypeScript (subset)** — acessibilidade e mercado
|
||||
- **Lua (subset)** — scripting clássico e leve
|
||||
- **Java (subset)** — architecture, deep teaching
|
||||
- **TypeScript (subset)** — accessibility and market
|
||||
- **Lua (subset)** — classic and lightweight scripting
|
||||
|
||||
Todas convergem para:
|
||||
All converge to:
|
||||
|
||||
> O mesmo bytecode. A mesma VM. O mesmo comportamento.
|
||||
> The same bytecode. The same VM. The same behavior.
|
||||
>
|
||||
|
||||
---
|
||||
|
||||
## 🔄 Modelo de Execução
|
||||
## 🔄 Execution Model
|
||||
|
||||
PROMETEU executa em um loop fixo:
|
||||
PROMETEU executes in a fixed loop:
|
||||
|
||||
```
|
||||
BOOT
|
||||
↓
|
||||
LOAD CARTUCHO
|
||||
LOAD CARTRIDGE
|
||||
↓
|
||||
INIT
|
||||
↓
|
||||
@ -197,68 +197,68 @@ LOOP (60 Hz):
|
||||
|
||||
```
|
||||
|
||||
- Frequência padrão: **60 Hz**
|
||||
- Cada iteração corresponde a **um frame**
|
||||
- O tempo de execução é **mensurável**
|
||||
- Default frequency: **60 Hz**
|
||||
- Each iteration corresponds to **one frame**
|
||||
- Execution time is **measurable**
|
||||
|
||||
---
|
||||
|
||||
## ⏱️ CAP — Execution Cap (Orçamento de Execução)
|
||||
## ⏱️ CAP — Execution Cap
|
||||
|
||||
### Definição
|
||||
### Definition
|
||||
|
||||
O **CAP** define um orçamento de execução (tempo, memória e recursos) **em um contexto específico**, como uma Game Jam ou avaliação.
|
||||
The **CAP** defines an execution budget (time, memory, and resources) **in a specific context**, such as a Game Jam or evaluation.
|
||||
|
||||
> CAP nunca bloqueia execução.
|
||||
CAP nunca bloqueia empacotamento.
|
||||
CAP nunca impede o jogo de ser jogado.
|
||||
> CAP never blocks execution.
|
||||
> CAP never blocks packaging.
|
||||
> CAP never prevents the game from being played.
|
||||
>
|
||||
|
||||
---
|
||||
|
||||
### Quando o CAP é usado
|
||||
### When the CAP is used
|
||||
|
||||
- Game Jams PROMETEU
|
||||
- Avaliações acadêmicas
|
||||
- Desafios técnicos
|
||||
- Comparações entre soluções
|
||||
- PROMETEU Game Jams
|
||||
- Academic evaluations
|
||||
- Technical challenges
|
||||
- Comparisons between solutions
|
||||
|
||||
Fora desses contextos, PROMETEU opera em **modo livre**.
|
||||
Outside of these contexts, PROMETEU operates in **free mode**.
|
||||
|
||||
---
|
||||
|
||||
### O papel do CAP
|
||||
### The role of the CAP
|
||||
|
||||
O CAP serve para:
|
||||
The CAP serves to:
|
||||
|
||||
- orientar decisões técnicas
|
||||
- fornecer feedback mensurável
|
||||
- gerar **certificações técnicas**
|
||||
- criar critérios objetivos de avaliação
|
||||
- guide technical decisions
|
||||
- provide measurable feedback
|
||||
- generate **technical certifications**
|
||||
- create objective evaluation criteria
|
||||
|
||||
PROMETEU **ajuda durante o desenvolvimento**:
|
||||
PROMETEU **helps during development**:
|
||||
|
||||
- indicadores visuais
|
||||
- alertas de custo
|
||||
- profiling por frame
|
||||
- visual indicators
|
||||
- cost alerts
|
||||
- per-frame profiling
|
||||
|
||||
---
|
||||
|
||||
## 📄 Certificação PROMETEU
|
||||
## 📄 PROMETEU Certification
|
||||
|
||||
### O que é
|
||||
### What it is
|
||||
|
||||
A **Certificação PROMETEU** é um relatório técnico gerado a partir da execução do jogo sob um CAP definido.
|
||||
The **PROMETEU Certification** is a technical report generated from the execution of the game under a defined CAP.
|
||||
|
||||
Ela:
|
||||
It:
|
||||
|
||||
- **não impede** o jogo
|
||||
- **não invalida** a entrega
|
||||
- **registra evidências técnicas**
|
||||
- **does not prevent** the game from running
|
||||
- **does not invalidate** the delivery
|
||||
- **records technical evidence**
|
||||
|
||||
---
|
||||
|
||||
### Exemplo de relatório
|
||||
### Report Example
|
||||
|
||||
```
|
||||
PROMETEUCERTIFICATIONREPORT
|
||||
@ -281,19 +281,19 @@ Notes:
|
||||
-Heappressurecausedbyper-frameallocations
|
||||
```
|
||||
|
||||
O relatório **acompanha o jogo**.
|
||||
The report **accompanies the game**.
|
||||
|
||||
---
|
||||
|
||||
## 🎓 Uso Educacional
|
||||
## 🎓 Educational Use
|
||||
|
||||
A avaliação pode considerar:
|
||||
Evaluation may consider:
|
||||
|
||||
- Qualidade do jogo (criatividade, design)
|
||||
- Qualidade técnica (certificação)
|
||||
- Decisões arquiteturais justificadas
|
||||
- Evolução entre versões
|
||||
- Game quality (creativity, design)
|
||||
- Technical quality (certification)
|
||||
- Justified architectural decisions
|
||||
- Evolution between versions
|
||||
|
||||
PROMETEU avalia **processo**, não apenas resultado.
|
||||
PROMETEU evaluates **process**, not just result.
|
||||
|
||||
< [Sumário](topics/table-of-contents.md) >
|
||||
< [Summary](topics/table-of-contents.md) >
|
||||
@ -1,45 +1,45 @@
|
||||
< [Sumário](table-of-contents.md) | [Adiante](chapter-2.md) >
|
||||
< [Summary](table-of-contents.md) | [Next](chapter-2.md) >
|
||||
|
||||
# ⏱️ **Modelo de Tempo e Ciclos**
|
||||
# ⏱️ **Time Model and Cycles**
|
||||
|
||||
# 1. Visão Geral
|
||||
# 1. Overview
|
||||
|
||||
PROMETEU é um sistema **orientado a tempo**.
|
||||
PROMETEU is a **time-oriented** system.
|
||||
|
||||
Nada acontece “instantaneamente”.
|
||||
Nothing happens "instantly".
|
||||
|
||||
Toda ação consome **tempo mensurável**, expresso em **ciclos de execução**.
|
||||
Every action consumes **measurable time**, expressed in **execution cycles**.
|
||||
|
||||
Este capítulo define:
|
||||
This chapter defines:
|
||||
|
||||
- o **clock base** do sistema
|
||||
- o conceito de **ciclo PROMETEU**
|
||||
- como o tempo é distribuído ao longo dos frames
|
||||
- como o **CAP (Execution Cap)** se relaciona com esse modelo
|
||||
- the system's **base clock**
|
||||
- the concept of a **PROMETEU cycle**
|
||||
- how time is distributed across frames
|
||||
- how the **CAP (Execution Cap)** relates to this model
|
||||
|
||||
---
|
||||
|
||||
## 2. Clock Base do Sistema
|
||||
## 2. System Base Clock
|
||||
|
||||
PROMETEU opera com um **clock fixo de 60 Hz**.
|
||||
PROMETEU operates with a **fixed clock of 60 Hz**.
|
||||
|
||||
Isso significa:
|
||||
This means:
|
||||
|
||||
- 60 iterações do loop principal por segundo
|
||||
- cada iteração corresponde a **um frame**
|
||||
- o clock é **determinístico e estável**, independente da plataforma
|
||||
- 60 iterations of the main loop per second
|
||||
- each iteration corresponds to **one frame**
|
||||
- the clock is **deterministic and stable**, regardless of the platform
|
||||
|
||||
> O clock define o ritmo da máquina,
|
||||
não a quantidade de trabalho obrigatório por frame.
|
||||
> The clock defines the machine's rhythm,
|
||||
not the amount of mandatory work per frame.
|
||||
>
|
||||
|
||||
---
|
||||
|
||||
## 3. O Frame PROMETEU
|
||||
## 3. The PROMETEU Frame
|
||||
|
||||
Um **frame PROMETEU** representa uma unidade completa de execução.
|
||||
A **PROMETEU frame** represents a complete unit of execution.
|
||||
|
||||
Cada frame executa, conceitualmente, as seguintes etapas:
|
||||
Each frame conceptually executes the following stages:
|
||||
|
||||
```
|
||||
FRAME N
|
||||
@ -53,61 +53,61 @@ SYNC
|
||||
|
||||
```
|
||||
|
||||
O sistema garante:
|
||||
The system guarantees:
|
||||
|
||||
- ordem fixa
|
||||
- repetição previsível
|
||||
- ausência de frames “fantasmas”
|
||||
- fixed order
|
||||
- predictable repetition
|
||||
- absence of "ghost" frames
|
||||
|
||||
---
|
||||
|
||||
## 4. Ciclos PROMETEU
|
||||
## 4. PROMETEU Cycles
|
||||
|
||||
### 4.1 Definição
|
||||
### 4.1 Definition
|
||||
|
||||
Um **ciclo PROMETEU** é a menor unidade abstrata de tempo do sistema.
|
||||
A **PROMETEU cycle** is the smallest abstract unit of time in the system.
|
||||
|
||||
- cada instrução da VM consome um número fixo de ciclos
|
||||
- chamadas de periféricos também possuem custo
|
||||
- o custo é **documentado e estável**
|
||||
- each VM instruction consumes a fixed number of cycles
|
||||
- peripheral calls also have a cost
|
||||
- the cost is **documented and stable**
|
||||
|
||||
Ciclos são:
|
||||
Cycles are:
|
||||
|
||||
- **contáveis**
|
||||
- **comparáveis**
|
||||
- **independentes de hardware real**
|
||||
- **countable**
|
||||
- **comparable**
|
||||
- **independent of real hardware**
|
||||
|
||||
---
|
||||
|
||||
### 4.2 Por que ciclos, e não milissegundos?
|
||||
### 4.2 Why cycles, and not milliseconds?
|
||||
|
||||
PROMETEU não mede tempo em milissegundos porque:
|
||||
PROMETEU does not measure time in milliseconds because:
|
||||
|
||||
- milissegundos variam entre plataformas
|
||||
- clocks reais diferem
|
||||
- jitter e latência escondem custo real
|
||||
- milliseconds vary between platforms
|
||||
- real clocks differ
|
||||
- jitter and latency hide the real cost
|
||||
|
||||
Ciclos permitem afirmar:
|
||||
Cycles allow stating:
|
||||
|
||||
> “Este programa é mais caro que aquele,
|
||||
> "This program is more expensive than that one,
|
||||
>
|
||||
>
|
||||
> independentemente de onde ele rode.”
|
||||
> regardless of where it runs."
|
||||
>
|
||||
|
||||
---
|
||||
|
||||
## 5. Orçamento por Frame
|
||||
## 5. Per-Frame Budget
|
||||
|
||||
Cada frame possui um **orçamento máximo de ciclos**.
|
||||
Each frame has a **maximum cycle budget**.
|
||||
|
||||
Esse orçamento:
|
||||
This budget:
|
||||
|
||||
- é resetado a cada frame
|
||||
- não acumula ciclos não utilizados
|
||||
- representa a capacidade da “CPU virtual”
|
||||
- is reset every frame
|
||||
- does not accumulate unused cycles
|
||||
- represents the capacity of the "virtual CPU"
|
||||
|
||||
### Exemplo conceitual
|
||||
### Conceptual example
|
||||
|
||||
```
|
||||
Frame Budget:10,000cycles
|
||||
@ -124,107 +124,107 @@ Remaining:
|
||||
|
||||
---
|
||||
|
||||
## 6. Separação entre Clock e Trabalho
|
||||
## 6. Separation between Clock and Work
|
||||
|
||||
PROMETEU **não exige** que toda lógica rode a cada frame.
|
||||
PROMETEU **does not require** all logic to run every frame.
|
||||
|
||||
O programador é **explicitamente encorajado** a distribuir trabalho no tempo.
|
||||
The programmer is **explicitly encouraged** to distribute work over time.
|
||||
|
||||
### Exemplos comuns
|
||||
### Common examples
|
||||
|
||||
- lógica de inimigos a cada 2 frames (30 Hz)
|
||||
- pathfinding a cada 4 frames (15 Hz)
|
||||
- animações independentes da AI
|
||||
- timers baseados em contagem de frames
|
||||
- enemy logic every 2 frames (30 Hz)
|
||||
- pathfinding every 4 frames (15 Hz)
|
||||
- animations independent of AI
|
||||
- timers based on frame count
|
||||
|
||||
Isso reflete práticas reais de:
|
||||
This reflects real-world practices from:
|
||||
|
||||
- consoles clássicos
|
||||
- sistemas embarcados
|
||||
- firmware de microcontroladores
|
||||
- classic consoles
|
||||
- embedded systems
|
||||
- microcontroller firmware
|
||||
|
||||
> Nem tudo precisa acontecer agora.
|
||||
> Not everything needs to happen now.
|
||||
>
|
||||
|
||||
---
|
||||
|
||||
## 7. Distribuição Temporal como Arquitetura
|
||||
## 7. Temporal Distribution as Architecture
|
||||
|
||||
PROMETEU trata **distribuição de trabalho no tempo** como uma decisão arquitetural.
|
||||
PROMETEU treats **work distribution over time** as an architectural decision.
|
||||
|
||||
Isso significa que:
|
||||
This means that:
|
||||
|
||||
- código que roda todo frame é mais caro
|
||||
- código distribuído é mais eficiente
|
||||
- otimização é, antes de tudo, **organização temporal**
|
||||
- code that runs every frame is more expensive
|
||||
- distributed code is more efficient
|
||||
- optimization is, first and foremost, **temporal organization**
|
||||
|
||||
PROMETEU ensina:
|
||||
PROMETEU teaches:
|
||||
|
||||
> desempenho não vem só de “menos código”,
|
||||
> performance doesn't just come from "less code",
|
||||
>
|
||||
>
|
||||
> mas de **quando** o código roda.
|
||||
> but from **when** the code runs.
|
||||
>
|
||||
|
||||
---
|
||||
|
||||
## 8. Execution CAP (Orçamento Contextual)
|
||||
## 8. Execution CAP (Contextual Budget)
|
||||
|
||||
### 8.1 O que é o CAP
|
||||
### 8.1 What is the CAP
|
||||
|
||||
O **CAP** define um conjunto de limites técnicos associados a um **contexto específico**, como:
|
||||
The **CAP** defines a set of technical limits associated with a **specific context**, such as:
|
||||
|
||||
- Game Jams
|
||||
- avaliações acadêmicas
|
||||
- desafios técnicos
|
||||
- academic evaluations
|
||||
- technical challenges
|
||||
|
||||
O CAP pode definir:
|
||||
The CAP can define:
|
||||
|
||||
- orçamento máximo de ciclos por frame
|
||||
- limite de memória
|
||||
- limites de chamadas de periféricos
|
||||
- maximum cycle budget per frame
|
||||
- memory limit
|
||||
- peripheral call limits
|
||||
|
||||
---
|
||||
|
||||
### 8.2 CAP não bloqueia execução
|
||||
### 8.2 CAP does not block execution
|
||||
|
||||
Regras fundamentais:
|
||||
Fundamental rules:
|
||||
|
||||
- o jogo **sempre roda**
|
||||
- o jogo **sempre pode ser empacotado**
|
||||
- o jogo **sempre pode ser jogado**
|
||||
- the game **always runs**
|
||||
- the game **can always be packaged**
|
||||
- the game **can always be played**
|
||||
|
||||
O CAP **nunca impede** execução.
|
||||
The CAP **never prevents** execution.
|
||||
|
||||
---
|
||||
|
||||
### 8.3 CAP gera evidência, não punição
|
||||
### 8.3 CAP generates evidence, not punishment
|
||||
|
||||
Quando um CAP está ativo, PROMETEU:
|
||||
When a CAP is active, PROMETEU:
|
||||
|
||||
- mede execução
|
||||
- registra picos
|
||||
- identifica gargalos
|
||||
- gera **relatório de certificação**
|
||||
- measures execution
|
||||
- records peaks
|
||||
- identifies bottlenecks
|
||||
- generates a **certification report**
|
||||
|
||||
Esse relatório:
|
||||
This report:
|
||||
|
||||
- não bloqueia o jogo
|
||||
- não invalida a entrega
|
||||
- **documenta conformidade ou não conformidade**
|
||||
- does not block the game
|
||||
- does not invalidate the delivery
|
||||
- **documents compliance or non-compliance**
|
||||
|
||||
---
|
||||
|
||||
## 9. Certificação Baseada em Tempo
|
||||
## 9. Time-Based Certification
|
||||
|
||||
A certificação PROMETEU analisa:
|
||||
PROMETEU certification analyzes:
|
||||
|
||||
- uso médio de ciclos por frame
|
||||
- picos máximos
|
||||
- frames problemáticos
|
||||
- distribuição de custo
|
||||
- average cycle usage per frame
|
||||
- maximum peaks
|
||||
- problematic frames
|
||||
- cost distribution
|
||||
|
||||
Exemplo:
|
||||
Example:
|
||||
|
||||
```
|
||||
Target CAP:PROMETEU-LITE
|
||||
@ -238,17 +238,17 @@ enemy.updateAI():1,012cycles
|
||||
|
||||
```
|
||||
|
||||
Essa certificação acompanha o jogo como **artefato técnico**.
|
||||
This certification accompanies the game as a **technical artifact**.
|
||||
|
||||
---
|
||||
|
||||
## 10. Implicações Pedagógicas
|
||||
## 10. Pedagogical Implications
|
||||
|
||||
O modelo de tempo e ciclos permite ensinar:
|
||||
The time and cycles model allows teaching:
|
||||
|
||||
- planejamento de execução
|
||||
- arquitetura orientada a tempo
|
||||
- trade-offs técnicos
|
||||
- leitura de perfis reais
|
||||
- execution planning
|
||||
- time-oriented architecture
|
||||
- technical trade-offs
|
||||
- reading real profiles
|
||||
|
||||
< [Sumário](table-of-contents.md) | [Adiante](chapter-2.md) >
|
||||
< [Summary](table-of-contents.md) | [Next](chapter-2.md) >
|
||||
@ -1,194 +1,194 @@
|
||||
< [Voltar](chapter-9.md) | [Sumário](table-of-contents.md) | [Adiante](chapter-11.md) >
|
||||
< [Back](chapter-9.md) | [Summary](table-of-contents.md) | [Next](chapter-11.md) >
|
||||
|
||||
# 🛠️ **Debug, Inspeção e Profiling**
|
||||
# 🛠️ **Debug, Inspection, and Profiling**
|
||||
|
||||
## 1. Visão Geral
|
||||
## 1. Overview
|
||||
|
||||
PROMETEU foi projetado para **ser observado**.
|
||||
PROMETEU was designed to **be observed**.
|
||||
|
||||
Debug, inspeção e profiling **não são ferramentas externas opcionais** —
|
||||
Debug, inspection, and profiling **are not optional external tools** —
|
||||
|
||||
eles são **partes integrantes da máquina**.
|
||||
they are **integral parts of the machine**.
|
||||
|
||||
Nada acontece sem deixar rastros.
|
||||
Nothing happens without leaving traces.
|
||||
|
||||
Nada consome recursos sem ser medido.
|
||||
Nothing consumes resources without being measured.
|
||||
|
||||
Nada falha sem explicação.
|
||||
Nothing fails without explanation.
|
||||
|
||||
> PROMETEU não esconde estado.
|
||||
PROMETEU expõe comportamento.
|
||||
> PROMETEU does not hide state.
|
||||
> PROMETEU exposes behavior.
|
||||
>
|
||||
|
||||
---
|
||||
|
||||
## 2. Filosofia de Debug em PROMETEU
|
||||
## 2. Debug Philosophy in PROMETEU
|
||||
|
||||
PROMETEU segue três princípios fundamentais de debug:
|
||||
PROMETEU follows three fundamental debug principles:
|
||||
|
||||
1. **Estado antes de abstração**
|
||||
1. **State before abstraction**
|
||||
|
||||
O programador vê a máquina antes de ver “features”.
|
||||
The programmer sees the machine before seeing “features”.
|
||||
|
||||
2. **Tempo como primeira classe**
|
||||
2. **Time as first class**
|
||||
|
||||
Cada ação é analisada no contexto do frame e dos ciclos.
|
||||
Every action is analyzed in the context of the frame and cycles.
|
||||
|
||||
3. **Observação não altera execução**
|
||||
3. **Observation does not alter execution**
|
||||
|
||||
Debug nunca muda o comportamento do sistema.
|
||||
Debug never changes the behavior of the system.
|
||||
|
||||
|
||||
---
|
||||
|
||||
## 3. Modos de Execução
|
||||
## 3. Execution Modes
|
||||
|
||||
PROMETEU opera em três modos principais:
|
||||
PROMETEU operates in three main modes:
|
||||
|
||||
### 3.1 Modo Normal
|
||||
### 3.1 Normal Mode
|
||||
|
||||
- execução contínua
|
||||
- sem inspeção detalhada
|
||||
- foco em jogo e experiência
|
||||
- continuous execution
|
||||
- no detailed inspection
|
||||
- focus on game and experience
|
||||
|
||||
---
|
||||
|
||||
### 3.2 Modo Debug
|
||||
### 3.2 Debug Mode
|
||||
|
||||
- execução controlada
|
||||
- acesso a estado interno
|
||||
- pausas e stepping
|
||||
- controlled execution
|
||||
- access to internal state
|
||||
- pauses and stepping
|
||||
|
||||
Este modo é usado para:
|
||||
This mode is used for:
|
||||
|
||||
- aprendizado
|
||||
- investigação
|
||||
- correção de erros
|
||||
- learning
|
||||
- investigation
|
||||
- error correction
|
||||
|
||||
---
|
||||
|
||||
### 3.3 Modo Certificação
|
||||
### 3.3 Certification Mode
|
||||
|
||||
- execução determinística
|
||||
- métricas coletadas
|
||||
- geração de relatório
|
||||
- deterministic execution
|
||||
- collected metrics
|
||||
- report generation
|
||||
|
||||
Nenhum modo altera o resultado lógico do programa.
|
||||
No mode alters the logical result of the program.
|
||||
|
||||
---
|
||||
|
||||
## 4. Debug de Execução
|
||||
## 4. Execution Debug
|
||||
|
||||
### 4.1 Pausa e Continuação
|
||||
### 4.1 Pause and Resume
|
||||
|
||||
O sistema pode ser pausado em pontos seguros:
|
||||
The system can be paused at safe points:
|
||||
|
||||
- início do frame
|
||||
- antes de UPDATE
|
||||
- após DRAW
|
||||
- antes do SYNC
|
||||
- frame start
|
||||
- before UPDATE
|
||||
- after DRAW
|
||||
- before SYNC
|
||||
|
||||
Durante pausa:
|
||||
During pause:
|
||||
|
||||
- estado é congelado
|
||||
- buffers não são trocados
|
||||
- tempo lógico não avança
|
||||
- state is frozen
|
||||
- buffers are not swapped
|
||||
- logical time does not advance
|
||||
|
||||
---
|
||||
|
||||
### 4.2 Step-by-Step
|
||||
|
||||
PROMETEU permite stepping em diferentes níveis:
|
||||
PROMETEU allows stepping at different levels:
|
||||
|
||||
- **por frame**
|
||||
- **por função**
|
||||
- **por instrução da VM**
|
||||
- **by frame**
|
||||
- **by function**
|
||||
- **by VM instruction**
|
||||
|
||||
Stepping por instrução revela:
|
||||
Stepping by instruction reveals:
|
||||
|
||||
- Program Counter (PC)
|
||||
- instrução atual
|
||||
- pilha de operandos
|
||||
- current instruction
|
||||
- operand stack
|
||||
- call stack
|
||||
|
||||
---
|
||||
|
||||
## 5. Inspeção de Estado
|
||||
## 5. State Inspection
|
||||
|
||||
### 5.1 Pilhas
|
||||
### 5.1 Stacks
|
||||
|
||||
PROMETEU permite inspecionar:
|
||||
PROMETEU allows inspecting:
|
||||
|
||||
- **Operand Stack**
|
||||
- **Call Stack**
|
||||
|
||||
Para cada frame:
|
||||
For each frame:
|
||||
|
||||
- conteúdo
|
||||
- profundidade
|
||||
- crescimento e limpeza
|
||||
- content
|
||||
- depth
|
||||
- growth and cleanup
|
||||
|
||||
Stack overflow e underflow são imediatamente visíveis.
|
||||
Stack overflow and underflow are immediately visible.
|
||||
|
||||
---
|
||||
|
||||
### 5.2 Heap
|
||||
|
||||
O heap pode ser inspecionado em tempo real:
|
||||
The heap can be inspected in real time:
|
||||
|
||||
- tamanho total
|
||||
- uso atual
|
||||
- pico de uso
|
||||
- objetos vivos
|
||||
- total size
|
||||
- current usage
|
||||
- peak usage
|
||||
- live objects
|
||||
|
||||
O programador pode observar:
|
||||
The programmer can observe:
|
||||
|
||||
- padrões de alocação
|
||||
- fragmentação
|
||||
- pressão de GC
|
||||
- allocation patterns
|
||||
- fragmentation
|
||||
- GC pressure
|
||||
|
||||
---
|
||||
|
||||
### 5.3 Espaço Global
|
||||
### 5.3 Global Space
|
||||
|
||||
Variáveis globais:
|
||||
Global variables:
|
||||
|
||||
- valores atuais
|
||||
- referências
|
||||
- inicialização
|
||||
- current values
|
||||
- references
|
||||
- initialization
|
||||
|
||||
Globais são visíveis como **RAM estática**.
|
||||
Globals are visible as **static RAM**.
|
||||
|
||||
---
|
||||
|
||||
## 6. Debug Gráfico
|
||||
## 6. Graphics Debug
|
||||
|
||||
PROMETEU permite inspecionar o sistema gráfico:
|
||||
PROMETEU allows inspecting the graphics system:
|
||||
|
||||
- front buffer
|
||||
- back buffer
|
||||
- estado da paleta
|
||||
- sprites ativos
|
||||
- palette state
|
||||
- active sprites
|
||||
|
||||
É possível:
|
||||
It is possible to:
|
||||
|
||||
- congelar a imagem
|
||||
- observar buffers separadamente
|
||||
- identificar redraw excessivo
|
||||
- freeze the image
|
||||
- observe buffers separately
|
||||
- identify excessive redraw
|
||||
|
||||
---
|
||||
|
||||
## 7. Profiling de Tempo (Ciclos)
|
||||
## 7. Time Profiling (Cycles)
|
||||
|
||||
### 7.1 Medição por Frame
|
||||
### 7.1 Per-Frame Measurement
|
||||
|
||||
Para cada frame, PROMETEU registra:
|
||||
For each frame, PROMETEU records:
|
||||
|
||||
- ciclos totais usados
|
||||
- ciclos por subsistema
|
||||
- picos de execução
|
||||
- total cycles used
|
||||
- cycles per subsystem
|
||||
- execution peaks
|
||||
|
||||
Exemplo conceitual:
|
||||
Conceptual example:
|
||||
|
||||
```
|
||||
Frame 18231:
|
||||
@ -201,47 +201,47 @@ SYSTEM:612
|
||||
|
||||
---
|
||||
|
||||
### 7.2 Profiling por Função
|
||||
### 7.2 Per-Function Profiling
|
||||
|
||||
PROMETEU pode associar ciclos a:
|
||||
PROMETEU can associate cycles with:
|
||||
|
||||
- funções
|
||||
- métodos
|
||||
- blocos lógicos
|
||||
- functions
|
||||
- methods
|
||||
- logical blocks
|
||||
|
||||
Isso permite responder:
|
||||
This allows answering:
|
||||
|
||||
> “onde o tempo está sendo gasto?”
|
||||
> “where is the time being spent?”
|
||||
>
|
||||
|
||||
---
|
||||
|
||||
### 7.3 Profiling por Instrução
|
||||
### 7.3 Per-Instruction Profiling
|
||||
|
||||
No nível mais baixo, o sistema pode exibir:
|
||||
At the lowest level, the system can display:
|
||||
|
||||
- instruções executadas
|
||||
- custo individual
|
||||
- frequência
|
||||
- executed instructions
|
||||
- individual cost
|
||||
- frequency
|
||||
|
||||
Esse nível é especialmente útil para:
|
||||
This level is especially useful for:
|
||||
|
||||
- ensino de VM
|
||||
- otimização profunda
|
||||
- análise de bytecode
|
||||
- VM teaching
|
||||
- deep optimization
|
||||
- bytecode analysis
|
||||
|
||||
---
|
||||
|
||||
## 8. Profiling de Memória
|
||||
## 8. Memory Profiling
|
||||
|
||||
PROMETEU registra:
|
||||
PROMETEU records:
|
||||
|
||||
- uso médio de heap
|
||||
- pico de heap
|
||||
- alocações por frame
|
||||
- frequência de GC
|
||||
- average heap usage
|
||||
- heap peak
|
||||
- allocations per frame
|
||||
- GC frequency
|
||||
|
||||
Exemplo:
|
||||
Example:
|
||||
|
||||
```
|
||||
Heap:
|
||||
@ -250,101 +250,101 @@ Peak:34KB❌
|
||||
Limit:32KB
|
||||
```
|
||||
|
||||
Esses dados alimentam diretamente a certificação.
|
||||
These data directly feed the certification.
|
||||
|
||||
---
|
||||
|
||||
## 9. Breakpoints e Watchpoints
|
||||
## 9. Breakpoints and Watchpoints
|
||||
|
||||
### 9.1 Breakpoints
|
||||
|
||||
PROMETEU suporta breakpoints em:
|
||||
PROMETEU supports breakpoints in:
|
||||
|
||||
- frames específicos
|
||||
- funções
|
||||
- instruções da VM
|
||||
- specific frames
|
||||
- functions
|
||||
- VM instructions
|
||||
|
||||
Breakpoints:
|
||||
|
||||
- pausam execução
|
||||
- preservam estado
|
||||
- não alteram comportamento
|
||||
- pause execution
|
||||
- preserve state
|
||||
- do not change behavior
|
||||
|
||||
---
|
||||
|
||||
### 9.2 Watchpoints
|
||||
|
||||
Watchpoints monitoram:
|
||||
Watchpoints monitor:
|
||||
|
||||
- variáveis
|
||||
- endereços de heap
|
||||
- valores específicos
|
||||
- variables
|
||||
- heap addresses
|
||||
- specific values
|
||||
|
||||
A execução pode pausar quando:
|
||||
Execution can pause when:
|
||||
|
||||
- um valor muda
|
||||
- um limite é ultrapassado
|
||||
- a value changes
|
||||
- a limit is exceeded
|
||||
|
||||
---
|
||||
|
||||
## 10. Debug de Eventos e Interrupções
|
||||
## 10. Event and Interrupt Debugging
|
||||
|
||||
PROMETEU permite observar:
|
||||
PROMETEU allows observing:
|
||||
|
||||
- fila de eventos
|
||||
- timers ativos
|
||||
- interrupções ocorridas
|
||||
- event queue
|
||||
- active timers
|
||||
- occurred interrupts
|
||||
|
||||
Cada evento possui:
|
||||
Each event has:
|
||||
|
||||
- origem
|
||||
- origin
|
||||
- frame
|
||||
- custo
|
||||
- consequência
|
||||
- cost
|
||||
- consequence
|
||||
|
||||
Nada acontece “em silêncio”.
|
||||
Nothing happens “silently”.
|
||||
|
||||
---
|
||||
|
||||
## 11. Integração com CAP e Certificação
|
||||
## 11. Integration with CAP and Certification
|
||||
|
||||
Todos os dados de debug e profiling:
|
||||
All debug and profiling data:
|
||||
|
||||
- alimentam o relatório de certificação
|
||||
- são coletados de forma determinística
|
||||
- não dependem de ferramentas externas
|
||||
- feed the certification report
|
||||
- are collected deterministically
|
||||
- do not depend on external tools
|
||||
|
||||
O relatório final é:
|
||||
The final report is:
|
||||
|
||||
- reproduzível
|
||||
- auditável
|
||||
- explicável
|
||||
- reproducible
|
||||
- auditable
|
||||
- explainable
|
||||
|
||||
---
|
||||
|
||||
## 12. Uso Pedagógico
|
||||
## 12. Pedagogical Use
|
||||
|
||||
Este sistema permite ensinar:
|
||||
This system allows teaching:
|
||||
|
||||
- como debugar sistemas reais
|
||||
- como ler métricas
|
||||
- como correlacionar tempo e memória
|
||||
- como justificar decisões técnicas
|
||||
- how to debug real systems
|
||||
- how to read metrics
|
||||
- how to correlate time and memory
|
||||
- how to justify technical decisions
|
||||
|
||||
O aluno aprende:
|
||||
The student learns:
|
||||
|
||||
> debug não é tentativa e erro,
|
||||
é observação informada.
|
||||
> debug is not trial and error,
|
||||
> it is informed observation.
|
||||
>
|
||||
|
||||
---
|
||||
|
||||
## 13. Resumo
|
||||
## 13. Summary
|
||||
|
||||
- debug é parte do sistema
|
||||
- inspeção é completa
|
||||
- profiling é determinístico
|
||||
- tempo e memória são visíveis
|
||||
- certificação é baseada em evidência
|
||||
- debug is part of the system
|
||||
- inspection is complete
|
||||
- profiling is deterministic
|
||||
- time and memory are visible
|
||||
- certification is evidence-based
|
||||
|
||||
< [Voltar](chapter-9.md) | [Sumário](table-of-contents.md) | [Adiante](chapter-11.md) >
|
||||
< [Back](chapter-9.md) | [Summary](table-of-contents.md) | [Next](chapter-11.md) >
|
||||
@ -1,258 +1,258 @@
|
||||
< [Voltar](chapter-10.md) | [Sumário](table-of-contents.md) | [Adiante](chapter-12.md) >
|
||||
< [Back](chapter-10.md) | [Summary](table-of-contents.md) | [Next](chapter-12.md) >
|
||||
|
||||
# 🌍 **Garantias de Portabilidade e Execução Multiplataforma**
|
||||
# 🌍 **Portability Guarantees and Cross-Platform Execution**
|
||||
|
||||
## 1. Visão Geral
|
||||
## 1. Overview
|
||||
|
||||
PROMETEU foi projetado desde o início para ser **portável por construção**, não por adaptação posterior.
|
||||
PROMETEU was designed from the beginning to be **portable by construction**, not by later adaptation.
|
||||
|
||||
Um cartucho PROMETEU:
|
||||
A PROMETEU cartridge:
|
||||
|
||||
- executa da mesma forma em qualquer plataforma suportada
|
||||
- produz os mesmos resultados para as mesmas entradas
|
||||
- mantém comportamento técnico previsível
|
||||
- executes the same way on any supported platform
|
||||
- produces the same results for the same inputs
|
||||
- maintains predictable technical behavior
|
||||
|
||||
> PROMETEU não depende da plataforma.
|
||||
A plataforma depende do PROMETEU.
|
||||
> PROMETEU does not depend on the platform.
|
||||
> The platform depends on PROMETEU.
|
||||
>
|
||||
|
||||
Este capítulo define **o contrato de portabilidade** do sistema.
|
||||
This chapter defines the system's **portability contract**.
|
||||
|
||||
---
|
||||
|
||||
## 2. Princípio Fundamental da Portabilidade
|
||||
## 2. Fundamental Principle of Portability
|
||||
|
||||
A portabilidade em PROMETEU se baseia em uma regra simples:
|
||||
Portability in PROMETEU is based on a simple rule:
|
||||
|
||||
> Somente a PROMETEU VM define o comportamento do programa.
|
||||
> Only the PROMETEU VM defines the program's behavior.
|
||||
>
|
||||
|
||||
Isso significa:
|
||||
This means:
|
||||
|
||||
- linguagens-fonte não importam após compilação
|
||||
- hardware real não influencia lógica
|
||||
- sistema operacional não altera semântica
|
||||
- source languages do not matter after compilation
|
||||
- real hardware does not influence logic
|
||||
- the operating system does not change semantics
|
||||
|
||||
Tudo que não pertence à VM é **adaptação**, não execução.
|
||||
Everything that does not belong to the VM is **adaptation**, not execution.
|
||||
|
||||
---
|
||||
|
||||
## 3. Separação de Responsabilidades
|
||||
## 3. Separation of Responsibilities
|
||||
|
||||
PROMETEU separa rigorosamente três camadas:
|
||||
PROMETEU strictly separates three layers:
|
||||
|
||||
```
|
||||
+----------------------------+
|
||||
| CARTUCHO |
|
||||
| CARTRIDGE |
|
||||
| (bytecode + assets) |
|
||||
+-------------+--------------+
|
||||
|
|
||||
+-------------v--------------+
|
||||
| PROMETEU VM |
|
||||
| (lógica, tempo, memória) |
|
||||
| (logic, time, memory) |
|
||||
+-------------+--------------+
|
||||
|
|
||||
+-------------v--------------+
|
||||
| CAMADA DE PLATAFORMA |
|
||||
| janela, áudio,input, FS |
|
||||
| PLATFORM LAYER |
|
||||
| window, audio, input, FS |
|
||||
+----------------------------+
|
||||
```
|
||||
|
||||
### O que a VM controla
|
||||
### What the VM controls
|
||||
|
||||
- execução de bytecode
|
||||
- tempo lógico (frames, ciclos)
|
||||
- memória (stack, heap)
|
||||
- determinismo
|
||||
- custos e métricas
|
||||
- bytecode execution
|
||||
- logical time (frames, cycles)
|
||||
- memory (stack, heap)
|
||||
- determinism
|
||||
- costs and metrics
|
||||
|
||||
### O que a plataforma fornece
|
||||
### What the platform provides
|
||||
|
||||
- exibição de pixels
|
||||
- saída de áudio
|
||||
- coleta de input físico
|
||||
- acesso ao sistema de arquivos sandbox
|
||||
- pixel display
|
||||
- audio output
|
||||
- physical input collection
|
||||
- access to the sandbox file system
|
||||
|
||||
A plataforma **nunca decide comportamento**.
|
||||
The platform **never decides behavior**.
|
||||
|
||||
---
|
||||
|
||||
## 4. Determinismo como Base da Portabilidade
|
||||
## 4. Determinism as the Basis of Portability
|
||||
|
||||
PROMETEU garante determinismo por meio de:
|
||||
PROMETEU guarantees determinism through:
|
||||
|
||||
- clock lógico fixo (60 Hz)
|
||||
- ciclos abstratos, não tempo real
|
||||
- input amostrado por frame
|
||||
- ausência de concorrência implícita
|
||||
- ausência de operações dependentes de sistema
|
||||
- fixed logical clock (60 Hz)
|
||||
- abstract cycles, not real time
|
||||
- input sampled per frame
|
||||
- absence of implicit concurrency
|
||||
- absence of system-dependent operations
|
||||
|
||||
Isso permite afirmar:
|
||||
This allows stating:
|
||||
|
||||
> “Se o cartucho é o mesmo, o jogo é o mesmo.”
|
||||
> “If the cartridge is the same, the game is the same.”
|
||||
>
|
||||
|
||||
---
|
||||
|
||||
## 5. Independência de Hardware Real
|
||||
## 5. Independence from Real Hardware
|
||||
|
||||
PROMETEU **não utiliza**:
|
||||
PROMETEU **does not use**:
|
||||
|
||||
- timers do sistema operacional
|
||||
- clocks de alta resolução
|
||||
- instruções específicas de CPU
|
||||
- aceleração gráfica não controlada
|
||||
- operating system timers
|
||||
- high-resolution clocks
|
||||
- CPU-specific instructions
|
||||
- uncontrolled graphics acceleration
|
||||
|
||||
Todo desempenho é medido em **ciclos PROMETEU**, não em milissegundos.
|
||||
All performance is measured in **PROMETEU cycles**, not in milliseconds.
|
||||
|
||||
O hardware real:
|
||||
The real hardware:
|
||||
|
||||
- apenas executa a VM
|
||||
- nunca interfere na semântica
|
||||
- only executes the VM
|
||||
- never interferes with semantics
|
||||
|
||||
---
|
||||
|
||||
## 6. Precisão de Ponto Flutuante
|
||||
## 6. Floating Point Precision
|
||||
|
||||
Para garantir consistência numérica:
|
||||
To guarantee numerical consistency:
|
||||
|
||||
- PROMETEU define operações matemáticas explícitas
|
||||
- evita dependência de FPU específica
|
||||
- padroniza comportamento de `number`
|
||||
- PROMETEU defines explicit mathematical operations
|
||||
- avoids dependence on specific FPUs
|
||||
- standardizes `number` behavior
|
||||
|
||||
Isso evita:
|
||||
This avoids:
|
||||
|
||||
- divergências entre arquiteturas
|
||||
- erros acumulativos imprevisíveis
|
||||
- diferenças sutis entre plataformas
|
||||
- divergences between architectures
|
||||
- unpredictable cumulative errors
|
||||
- subtle differences between platforms
|
||||
|
||||
---
|
||||
|
||||
## 7. Input Multiplataforma
|
||||
## 7. Cross-Platform Input
|
||||
|
||||
PROMETEU abstrai input físico em **estado lógico**.
|
||||
PROMETEU abstracts physical input into **logical state**.
|
||||
|
||||
- teclado, gamepad e toque são mapeados externamente
|
||||
- o cartucho só enxerga botões e eixos lógicos
|
||||
- o momento da leitura é fixo por frame
|
||||
- keyboard, gamepad, and touch are mapped externally
|
||||
- the cartridge only sees logical buttons and axes
|
||||
- the reading moment is fixed per frame
|
||||
|
||||
O mesmo cartucho:
|
||||
The same cartridge:
|
||||
|
||||
- reage da mesma forma em PC, mobile ou console
|
||||
- não contém lógica dependente de dispositivo
|
||||
- reacts the same way on PC, mobile, or console
|
||||
- does not contain device-dependent logic
|
||||
|
||||
---
|
||||
|
||||
## 8. Áudio Multiplataforma
|
||||
## 8. Cross-Platform Audio
|
||||
|
||||
O sistema de áudio:
|
||||
The audio system:
|
||||
|
||||
- define canais e mixagem logicamente
|
||||
- usa APIs nativas apenas como saída
|
||||
- mantém sincronização por frame
|
||||
- defines channels and mixing logically
|
||||
- uses native APIs only as output
|
||||
- maintains per-frame synchronization
|
||||
|
||||
Diferenças de hardware:
|
||||
Hardware differences:
|
||||
|
||||
- não alteram timing lógico
|
||||
- não alteram sequência sonora
|
||||
- não afetam certificação
|
||||
- do not change logical timing
|
||||
- do not change sound sequence
|
||||
- do not affect certification
|
||||
|
||||
---
|
||||
|
||||
## 9. Gráficos Multiplataforma
|
||||
## 9. Cross-Platform Graphics
|
||||
|
||||
O sistema gráfico:
|
||||
The graphics system:
|
||||
|
||||
- opera sobre framebuffer lógico
|
||||
- usa paleta indexada
|
||||
- não depende de GPU específica
|
||||
- operates on a logical framebuffer
|
||||
- uses an indexed palette
|
||||
- does not depend on a specific GPU
|
||||
|
||||
A camada de plataforma:
|
||||
The platform layer:
|
||||
|
||||
- apenas exibe o framebuffer
|
||||
- não reinterpreta comandos gráficos
|
||||
- only displays the framebuffer
|
||||
- does not reinterpret graphics commands
|
||||
|
||||
PROMETEU **não delega decisões gráficas ao hardware**.
|
||||
PROMETEU **does not delegate graphics decisions to the hardware**.
|
||||
|
||||
---
|
||||
|
||||
## 10. Sistema de Arquivos e Persistência
|
||||
## 10. File System and Persistence
|
||||
|
||||
PROMETEU define um **filesystem lógico sandbox**:
|
||||
PROMETEU defines a **sandbox logical filesystem**:
|
||||
|
||||
- caminhos virtuais
|
||||
- limites de tamanho
|
||||
- comportamento determinístico
|
||||
- virtual paths
|
||||
- size limits
|
||||
- deterministic behavior
|
||||
|
||||
A plataforma mapeia esse filesystem para:
|
||||
The platform maps this filesystem to:
|
||||
|
||||
- disco
|
||||
- storage móvel
|
||||
- memória persistente
|
||||
- disk
|
||||
- mobile storage
|
||||
- persistent memory
|
||||
|
||||
Sem alterar semântica.
|
||||
Without changing semantics.
|
||||
|
||||
---
|
||||
|
||||
## 11. Certificação e Portabilidade
|
||||
## 11. Certification and Portability
|
||||
|
||||
A **Certificação PROMETEU** é válida para todas as plataformas.
|
||||
The **PROMETEU Certification** is valid for all platforms.
|
||||
|
||||
Se um cartucho:
|
||||
If a cartridge:
|
||||
|
||||
- passa em uma plataforma
|
||||
- com as mesmas entradas
|
||||
- passes on one platform
|
||||
- with the same inputs
|
||||
|
||||
Ele:
|
||||
It:
|
||||
|
||||
- passará em todas
|
||||
- produzirá os mesmos relatórios
|
||||
- will pass on all
|
||||
- will produce the same reports
|
||||
|
||||
Isso é possível porque:
|
||||
This is possible because:
|
||||
|
||||
> a certificação valida a VM, não o ambiente.
|
||||
> the certification validates the VM, not the environment.
|
||||
>
|
||||
|
||||
---
|
||||
|
||||
## 12. O que PROMETEU NÃO garante
|
||||
## 12. What PROMETEU DOES NOT guarantee
|
||||
|
||||
PROMETEU **não promete**:
|
||||
PROMETEU **does not promise**:
|
||||
|
||||
- desempenho absoluto igual (FPS real)
|
||||
- latência física idêntica
|
||||
- consumo energético equivalente
|
||||
- identical absolute performance (real FPS)
|
||||
- identical physical latency
|
||||
- equivalent energy consumption
|
||||
|
||||
PROMETEU promete:
|
||||
PROMETEU promises:
|
||||
|
||||
- **comportamento lógico idêntico**
|
||||
- **decisões técnicas reproduzíveis**
|
||||
- **identical logical behavior**
|
||||
- **reproducible technical decisions**
|
||||
|
||||
---
|
||||
|
||||
## 13. Implicações Pedagógicas
|
||||
## 13. Pedagogical Implications
|
||||
|
||||
Este modelo permite ensinar:
|
||||
This model allows teaching:
|
||||
|
||||
- diferença entre lógica e apresentação
|
||||
- por que engines modernas quebram determinismo
|
||||
- como isolar sistemas
|
||||
- como projetar software portável
|
||||
- the difference between logic and presentation
|
||||
- why modern engines break determinism
|
||||
- how to isolate systems
|
||||
- how to design portable software
|
||||
|
||||
O aluno aprende:
|
||||
The student learns:
|
||||
|
||||
> portabilidade não é sorte — é arquitetura.
|
||||
> portability is not luck — it is architecture.
|
||||
>
|
||||
|
||||
---
|
||||
|
||||
## 14. Resumo
|
||||
## 14. Summary
|
||||
|
||||
- PROMETEU define comportamento na VM
|
||||
- plataformas apenas executam
|
||||
- tempo é lógico, não físico
|
||||
- input, áudio e gráficos são abstraídos
|
||||
- certificação é universal
|
||||
- portabilidade é garantida por design
|
||||
- PROMETEU defines behavior in the VM
|
||||
- platforms only execute
|
||||
- time is logical, not physical
|
||||
- input, audio, and graphics are abstracted
|
||||
- certification is universal
|
||||
- portability is guaranteed by design
|
||||
|
||||
< [Voltar](chapter-10.md) | [Sumário](table-of-contents.md) | [Adiante](chapter-12.md) >
|
||||
< [Back](chapter-10.md) | [Summary](table-of-contents.md) | [Next](chapter-12.md) >
|
||||
@ -1,236 +1,236 @@
|
||||
< [Voltar](chapter-11.md) | [Sumário](table-of-contents.md) | [Adiante](chapter-13.md) >
|
||||
< [Back](chapter-11.md) | [Summary](table-of-contents.md) | [Next](chapter-13.md) >
|
||||
|
||||
# 🧠 Firmware — PrometeuOS (POS) + PrometeuHub
|
||||
|
||||
## 1. Visão Geral
|
||||
## 1. Overview
|
||||
|
||||
O **Firmware do PROMETEU** é composto por duas camadas:
|
||||
The **PROMETEU Firmware** is composed of two layers:
|
||||
|
||||
- **PrometeuOS (POS)**: o firmware/base do sistema. É a autoridade máxima do boot, periféricos, execução da PVM e tratamento de falhas.
|
||||
- **PrometeuHub**: o “launcher” e ambiente de UI do sistema, embutido no firmware, executado **sobre** o POS e usando o **PROMETEU Window System**.
|
||||
- **PrometeuOS (POS)**: the system firmware/base. It is the maximum authority for boot, peripherals, PVM execution, and fault handling.
|
||||
- **PrometeuHub**: the system launcher and UI environment, embedded in the firmware, executed **over** the POS and using the **PROMETEU Window System**.
|
||||
|
||||
> **Todo cartucho é um App**.
|
||||
> A diferença é o **modo do App** (Game ou System), informado no header do cartucho.
|
||||
> **Every cartridge is an App**.
|
||||
> The difference is the **App mode** (Game or System), specified in the cartridge header.
|
||||
|
||||
---
|
||||
|
||||
## 2. Termos e Definições
|
||||
## 2. Terms and Definitions
|
||||
|
||||
- **Host**: plataforma real (desktop, mobile, console DIY, etc.) que chama o core em 60Hz e exibe o framebuffer.
|
||||
- **POS (PrometeuOS)**: firmware (core de sistema). Controla boot, PVM, budget, latch de input, periféricos e crash.
|
||||
- **PrometeuHub**: UI do sistema/launcher rodando sobre POS.
|
||||
- **PVM (PROMETEU Virtual Machine)**: VM que executa bytecode do App.
|
||||
- **App / Cartucho**: pacote executável PROMETEU (ex.: `.pbc`).
|
||||
- **AppMode**: modo do App no header do cartucho:
|
||||
- `GAME`: assume tela cheia, UI própria
|
||||
- `SYSTEM`: app integrado ao sistema, deve rodar “em janela” no Hub
|
||||
- **Frame lógico**: unidade de atualização do App, encerrada por `FRAME_SYNC`.
|
||||
- **Tick do host**: chamada do host (60Hz real).
|
||||
- **Host**: real platform (desktop, mobile, DIY console, etc.) that calls the core at 60Hz and displays the framebuffer.
|
||||
- **POS (PrometeuOS)**: firmware (system core). Controls boot, PVM, budget, input latch, peripherals, and crash.
|
||||
- **PrometeuHub**: system UI / launcher running over POS.
|
||||
- **PVM (PROMETEU Virtual Machine)**: VM that executes the App's bytecode.
|
||||
- **App / Cartridge**: PROMETEU executable package (e.g., `.pbc`).
|
||||
- **AppMode**: App mode in the cartridge header:
|
||||
- `GAME`: assumes full screen, own UI
|
||||
- `SYSTEM`: app integrated into the system, should run "in a window" in the Hub
|
||||
- **Logical frame**: App update unit, terminated by `FRAME_SYNC`.
|
||||
- **Host tick**: call from the host (real 60Hz).
|
||||
|
||||
---
|
||||
|
||||
## 3. Responsabilidades do POS (PrometeuOS)
|
||||
## 3. Responsibilities of the POS (PrometeuOS)
|
||||
|
||||
O POS deve garantir:
|
||||
The POS must guarantee:
|
||||
|
||||
### 3.1 Boot e Estados de Sistema
|
||||
- RESET determinístico (estado conhecido)
|
||||
- SPLASH opcional (curto)
|
||||
- inicialização do PrometeuHub e do Window System
|
||||
- retorno ao Hub após saída/crash de app
|
||||
### 3.1 Boot and System States
|
||||
- Deterministic RESET (known state)
|
||||
- Optional SPLASH (short)
|
||||
- initialization of the PrometeuHub and the Window System
|
||||
- return to the Hub after app exit/crash
|
||||
|
||||
### 3.2 Controle da PVM
|
||||
- carregar cartucho na PVM
|
||||
- resetar PC/stack/heap ao iniciar app
|
||||
- executar budget por frame lógico
|
||||
- respeitar `FRAME_SYNC` como boundary de frame lógico
|
||||
- manter input latched por frame lógico
|
||||
### 3.2 PVM Control
|
||||
- load cartridge into the PVM
|
||||
- reset PC/stack/heap upon app start
|
||||
- execute budget per logical frame
|
||||
- respect `FRAME_SYNC` as logical frame boundary
|
||||
- maintain input latched per logical frame
|
||||
|
||||
### 3.3 Controle de Periféricos
|
||||
- inicialização e reset de:
|
||||
### 3.3 Peripheral Control
|
||||
- initialization and reset of:
|
||||
- GFX / buffers
|
||||
- AUDIO (canais, fila de comandos)
|
||||
- AUDIO (channels, command queue)
|
||||
- INPUT / TOUCH
|
||||
- política de “safe mode” (ignorar Hub/config se solicitado)
|
||||
- "safe mode" policy (ignore Hub/config if requested)
|
||||
|
||||
### 3.4 Falhas e Recuperação
|
||||
- capturar faults fatais da PVM
|
||||
- apresentar **POS_CRASH_SCREEN** (fora da PVM)
|
||||
- permitir:
|
||||
- reiniciar app
|
||||
- voltar ao Hub
|
||||
- reset do sistema
|
||||
### 3.4 Failures and Recovery
|
||||
- capture fatal PVM faults
|
||||
- present **POS_CRASH_SCREEN** (outside the PVM)
|
||||
- allow:
|
||||
- app restart
|
||||
- return to Hub
|
||||
- system reset
|
||||
|
||||
---
|
||||
|
||||
## 4. Responsabilidades do PrometeuHub
|
||||
## 4. Responsibilities of the PrometeuHub
|
||||
|
||||
O PrometeuHub deve:
|
||||
The PrometeuHub must:
|
||||
|
||||
- listar Apps disponíveis no storage
|
||||
- ler metadata do header do cartucho (incluindo `AppMode`)
|
||||
- permitir seleção e launch
|
||||
- aplicar tema/UI do sistema via Window System
|
||||
- decidir o “comportamento de execução” com base no `AppMode`
|
||||
- list available Apps in storage
|
||||
- read metadata from the cartridge header (including `AppMode`)
|
||||
- allow selection and launch
|
||||
- apply system theme/UI via Window System
|
||||
- decide the "execution behavior" based on the `AppMode`
|
||||
|
||||
### 4.1 Decisão por `AppMode`
|
||||
Ao selecionar um App:
|
||||
### 4.1 Decision by `AppMode`
|
||||
When selecting an App:
|
||||
|
||||
- Se `AppMode = GAME`:
|
||||
- o Hub delega ao POS: **executar como jogo** (tela cheia)
|
||||
- Se `AppMode = SYSTEM`:
|
||||
- o Hub delega ao POS: **carregar o App**
|
||||
- e o Hub **abre uma janela** e roda o App “integrado ao sistema”
|
||||
- If `AppMode = GAME`:
|
||||
- the Hub delegates to the POS: **execute as a game** (full screen)
|
||||
- If `AppMode = SYSTEM`:
|
||||
- the Hub delegates to the POS: **load the App**
|
||||
- and the Hub **opens a window** and runs the App "integrated into the system"
|
||||
|
||||
> Observação: o Hub não executa bytecode diretamente; ele sempre delega ao POS.
|
||||
> Note: the Hub does not execute bytecode directly; it always delegates to the POS.
|
||||
|
||||
---
|
||||
|
||||
## 5. PROMETEU Window System (UI do Sistema)
|
||||
## 5. PROMETEU Window System (System UI)
|
||||
|
||||
O Window System é parte do firmware (POS + Hub) e oferece:
|
||||
The Window System is part of the firmware (POS + Hub) and offers:
|
||||
|
||||
- tema global (paleta, fontes, sons de UI)
|
||||
- sistema de janelas (pelo menos: uma janela ativa + stack de dialogs)
|
||||
- roteamento de input:
|
||||
- foco, navegação, confirmação/cancelamento
|
||||
- touch como “tap” (single pointer)
|
||||
- global theme (palette, fonts, UI sounds)
|
||||
- window system (at least: one active window + dialog stack)
|
||||
- input routing:
|
||||
- focus, navigation, confirmation/cancellation
|
||||
- touch as "tap" (single pointer)
|
||||
|
||||
### 5.1 Integração de System Apps
|
||||
System Apps são executados em modo “janela” e devem:
|
||||
### 5.1 System App Integration
|
||||
System Apps are executed in "window" mode and must:
|
||||
|
||||
- respeitar a área de viewport fornecida pela janela
|
||||
- cooperar com foco/inputs do Window System
|
||||
- aceitar ser suspensos/fechados pelo Hub
|
||||
- respect the viewport area provided by the window
|
||||
- cooperate with the Window System's focus/inputs
|
||||
- accept being suspended/closed by the Hub
|
||||
|
||||
O Hub pode oferecer “chrome” de janela:
|
||||
- título
|
||||
- botão voltar/fechar
|
||||
The Hub can offer window "chrome":
|
||||
- title
|
||||
- back/close button
|
||||
- overlays (toast, dialogs)
|
||||
|
||||
---
|
||||
|
||||
## 6. Header do Cartucho (requisito mínimo para o firmware)
|
||||
## 6. Cartridge Header (minimum requirement for the firmware)
|
||||
|
||||
O firmware exige que todo cartucho forneça no header, no mínimo:
|
||||
The firmware requires every cartridge to provide at least the following in the header:
|
||||
|
||||
- `magic` / `version`
|
||||
- `app_id` (string curta ou hash)
|
||||
- `app_id` (short string or hash)
|
||||
- `title` (string)
|
||||
- `entrypoint` (endereço de PC)
|
||||
- `app_mode`: `GAME` ou `SYSTEM`
|
||||
- (opcional) `icon_id` / `cover_id`
|
||||
- (opcional) `requested_cap` / versão da VM
|
||||
- `entrypoint` (PC address)
|
||||
- `app_mode`: `GAME` or `SYSTEM`
|
||||
- (optional) `icon_id` / `cover_id`
|
||||
- (optional) `requested_cap` / VM version
|
||||
|
||||
O POS/HUB devem usar `app_mode` para decidir execução.
|
||||
The POS/HUB must use `app_mode` to decide on execution.
|
||||
|
||||
---
|
||||
|
||||
## 7. Estados Oficiais do Boot (Firmware)
|
||||
## 7. Official Boot States (Firmware)
|
||||
|
||||
### 7.1 POS_RESET
|
||||
- inicializa periféricos
|
||||
- prepara PVM
|
||||
- carrega config
|
||||
- detecta safe mode
|
||||
- initializes peripherals
|
||||
- prepares PVM
|
||||
- loads config
|
||||
- detects safe mode
|
||||
|
||||
Transição: `POS_SPLASH` ou `POS_LAUNCH_HUB`
|
||||
Transition: `POS_SPLASH` or `POS_LAUNCH_HUB`
|
||||
|
||||
### 7.2 POS_SPLASH (opcional)
|
||||
- exibe logo/versão
|
||||
- tempo fixo ou “skip”
|
||||
### 7.2 POS_SPLASH (optional)
|
||||
- displays logo/version
|
||||
- fixed time or "skip"
|
||||
|
||||
Transição: `POS_LAUNCH_HUB`
|
||||
Transition: `POS_LAUNCH_HUB`
|
||||
|
||||
### 7.3 POS_LAUNCH_HUB
|
||||
- inicia Window System
|
||||
- entra no loop do Hub
|
||||
- starts Window System
|
||||
- enters the Hub loop
|
||||
|
||||
Transição: `HUB_HOME`
|
||||
Transition: `HUB_HOME`
|
||||
|
||||
### 7.4 HUB_HOME
|
||||
- lista Apps
|
||||
- permite seleção:
|
||||
- lists Apps
|
||||
- allows selection:
|
||||
- `GAME` → `POS_RUN_GAME(app)`
|
||||
- `SYSTEM` → `HUB_OPEN_WINDOW(app)` (que delega `POS_RUN_SYSTEM(app)`)
|
||||
- `SYSTEM` → `HUB_OPEN_WINDOW(app)` (which delegates `POS_RUN_SYSTEM(app)`)
|
||||
|
||||
### 7.5 POS_RUN_GAME(app)
|
||||
- carrega cartucho na PVM
|
||||
- executa frame lógico (budget + `FRAME_SYNC`)
|
||||
- apresenta frames
|
||||
- mantém latch por frame lógico
|
||||
- loads cartridge into the PVM
|
||||
- executes logical frame (budget + `FRAME_SYNC`)
|
||||
- presents frames
|
||||
- maintains latch per logical frame
|
||||
|
||||
Saídas:
|
||||
Exits:
|
||||
- `APP_EXIT` → `POS_LAUNCH_HUB`
|
||||
- `APP_FAULT` → `POS_CRASH_SCREEN`
|
||||
|
||||
### 7.6 POS_RUN_SYSTEM(app)
|
||||
- carrega cartucho na PVM (ou instância separada, se suportado no futuro)
|
||||
- executa sob o ciclo do Hub/Window System
|
||||
- apresenta na área da janela (viewport)
|
||||
- loads cartridge into the PVM (or separate instance, if supported in the future)
|
||||
- executes under the Hub/Window System cycle
|
||||
- presents in the window area (viewport)
|
||||
|
||||
Saídas:
|
||||
- `APP_EXIT` → retorna ao Hub
|
||||
- `APP_FAULT` → `POS_CRASH_SCREEN` (ou crash window + fallback)
|
||||
Exits:
|
||||
- `APP_EXIT` → returns to the Hub
|
||||
- `APP_FAULT` → `POS_CRASH_SCREEN` (or crash window + fallback)
|
||||
|
||||
### 7.7 POS_CRASH_SCREEN
|
||||
- exibe erro (tipo, PC, stack trace)
|
||||
- ações: restart app / hub / reset
|
||||
- displays error (type, PC, stack trace)
|
||||
- actions: restart app / hub / reset
|
||||
|
||||
Transição: conforme escolha.
|
||||
Transition: as chosen.
|
||||
|
||||
---
|
||||
|
||||
## 8. Modelo de Execução (Budget, Latch e `FRAME_SYNC`)
|
||||
## 8. Execution Model (Budget, Latch, and `FRAME_SYNC`)
|
||||
|
||||
O POS é responsável por garantir:
|
||||
The POS is responsible for guaranteeing:
|
||||
|
||||
- **Input latched por frame lógico**
|
||||
- execução em fatias (ticks do host) até o app alcançar `FRAME_SYNC`
|
||||
- apenas em `FRAME_SYNC`:
|
||||
- `present()` (ou compose+present)
|
||||
- avança `logical_frame_index`
|
||||
- libera latch de input
|
||||
- reseta budget do próximo frame lógico
|
||||
- **Input latched per logical frame**
|
||||
- execution in slices (host ticks) until the app reaches `FRAME_SYNC`
|
||||
- only at `FRAME_SYNC`:
|
||||
- `present()` (or compose+present)
|
||||
- advances `logical_frame_index`
|
||||
- releases input latch
|
||||
- resets the budget for the next logical frame
|
||||
|
||||
Se o budget acabar antes do `FRAME_SYNC`:
|
||||
- não apresenta
|
||||
- mantém latch
|
||||
- continua a execução no próximo tick do host no mesmo frame lógico
|
||||
If the budget runs out before `FRAME_SYNC`:
|
||||
- does not present
|
||||
- maintains latch
|
||||
- execution continues in the next host tick within the same logical frame
|
||||
|
||||
---
|
||||
|
||||
## 9. Regras de Retorno ao Hub
|
||||
## 9. Rules for Returning to the Hub
|
||||
|
||||
O firmware deve oferecer um mecanismo de “voltar ao sistema”:
|
||||
The firmware must offer a "return to system" mechanism:
|
||||
|
||||
- atalho de botão (ex.: START+SELECT por X ticks)
|
||||
- ou syscall controlada (apenas System Apps)
|
||||
- button shortcut (e.g., START+SELECT for X ticks)
|
||||
- or controlled syscall (System Apps only)
|
||||
|
||||
Ao retornar ao Hub:
|
||||
- o POS encerra ou suspende o App atual
|
||||
- retorna ao Window System com estado consistente
|
||||
Upon returning to the Hub:
|
||||
- the POS terminates or suspends the current App
|
||||
- returns to the Window System with a consistent state
|
||||
|
||||
---
|
||||
|
||||
## 10. Objetivos Pedagógicos
|
||||
## 10. Pedagogical Objectives
|
||||
|
||||
Este firmware permite ensinar:
|
||||
This firmware allows teaching:
|
||||
|
||||
- boot stages e firmware como autoridade
|
||||
- separação entre sistema e aplicação
|
||||
- execução determinística com budget e frame lógico
|
||||
- diferença entre apps (Game vs System)
|
||||
- tolerância a falhas e crash handling realista
|
||||
- boot stages and firmware as an authority
|
||||
- separation between system and application
|
||||
- deterministic execution with budget and logical frame
|
||||
- difference between apps (Game vs System)
|
||||
- fault tolerance and realistic crash handling
|
||||
|
||||
---
|
||||
|
||||
## 11. Resumo
|
||||
## 11. Summary
|
||||
|
||||
- POS é a camada base e controla PVM, budget, latch, periféricos e crash.
|
||||
- PrometeuHub é o launcher/UI embutido do firmware sobre o POS.
|
||||
- Todo cartucho é um App; o header define `app_mode` (GAME/SYSTEM).
|
||||
- `GAME` roda tela cheia; `SYSTEM` roda integrado ao Hub em janela.
|
||||
- `FRAME_SYNC` é o boundary do frame lógico.
|
||||
- POS is the base layer and controls the PVM, budget, latch, peripherals, and crash.
|
||||
- PrometeuHub is the embedded firmware launcher/UI over the POS.
|
||||
- Every cartridge is an App; the header defines the `app_mode` (GAME/SYSTEM).
|
||||
- `GAME` runs in full screen; `SYSTEM` runs integrated into the Hub in a window.
|
||||
- `FRAME_SYNC` is the logical frame boundary.
|
||||
|
||||
< [Voltar](chapter-11.md) | [Sumário](table-of-contents.md) | [Adiante](chapter-13.md) >
|
||||
< [Back](chapter-11.md) | [Summary](table-of-contents.md) | [Next](chapter-13.md) >
|
||||
@ -1,35 +1,35 @@
|
||||
< [Voltar](chapter-12.md) | [Sumário](table-of-contents.md) | [Adiante](chapter-14.md) >
|
||||
< [Back](chapter-12.md) | [Summary](table-of-contents.md) | [Next](chapter-14.md) >
|
||||
|
||||
# Cartuchos
|
||||
# Cartridges
|
||||
|
||||
**Versão:** 1.0 (baseline estável)
|
||||
**Status:** Proposta
|
||||
**Version:** 1.0 (stable baseline)
|
||||
**Status:** Proposal
|
||||
|
||||
---
|
||||
|
||||
## 1. Objetivo
|
||||
## 1. Objective
|
||||
|
||||
Definir um contrato mínimo e estável para cartuchos Prometeu, permitindo:
|
||||
Define a minimum and stable contract for Prometeu cartridges, allowing:
|
||||
|
||||
* Identificação do app
|
||||
* Seleção de modo (Game/System)
|
||||
* Resolução de entrypoint
|
||||
* Carregamento previsível pelo runtime
|
||||
* App identification
|
||||
* Mode selection (Game/System)
|
||||
* Entrypoint resolution
|
||||
* Predictable loading by the runtime
|
||||
|
||||
---
|
||||
|
||||
## 2. Conceito
|
||||
## 2. Concept
|
||||
|
||||
Um cartucho é a unidade distribuível do Prometeu. Ele pode existir como:
|
||||
A cartridge is the distributable unit of Prometeu. It can exist as:
|
||||
|
||||
* **Diretório (dev)** — ideal para desenvolvimento e hot-reload
|
||||
* **Arquivo empacotado (.pmc)** — ideal para distribuição
|
||||
* **Directory (dev)** — ideal for development and hot-reload
|
||||
* **Packaged file (.pmc)** — ideal for distribution
|
||||
|
||||
Ambos compartilham o mesmo layout lógico.
|
||||
Both share the same logical layout.
|
||||
|
||||
---
|
||||
|
||||
## 3. Layout Lógico
|
||||
## 3. Logical Layout
|
||||
|
||||
```
|
||||
<cartridge>/
|
||||
@ -39,72 +39,72 @@ Ambos compartilham o mesmo layout lógico.
|
||||
└── ...
|
||||
```
|
||||
|
||||
Campos obrigatórios:
|
||||
Required fields:
|
||||
|
||||
* `manifest.json`
|
||||
* `program.pbc` (bytecode Prometeu)
|
||||
* `program.pbc` (Prometeu bytecode)
|
||||
|
||||
---
|
||||
|
||||
## 4. manifest.json (Contrato v1)
|
||||
## 4. manifest.json (Contract v1)
|
||||
|
||||
```json
|
||||
{
|
||||
"magic": "PMTU",
|
||||
"cartridge_version": 1,
|
||||
"app_id": 1234,
|
||||
"title": "Meu Jogo",
|
||||
"title": "My Game",
|
||||
"app_version": "1.0.0",
|
||||
"app_mode": "Game", // Game | System
|
||||
"app_mode": "Game",
|
||||
"entrypoint": "main"
|
||||
}
|
||||
```
|
||||
|
||||
### Campos
|
||||
### Fields
|
||||
|
||||
* `magic`: string fixa `PMTU`
|
||||
* `cartridge_version`: versão do formato
|
||||
* `app_id`: identificador numérico único
|
||||
* `title`: nome do app
|
||||
* `app_version`: versão do app
|
||||
* `app_mode`: `Game` ou `System`
|
||||
* `entrypoint`: símbolo ou índice reconhecido pela VM
|
||||
* `magic`: fixed string `PMTU`
|
||||
* `cartridge_version`: format version
|
||||
* `app_id`: unique numerical identifier
|
||||
* `title`: name of the app
|
||||
* `app_version`: app version
|
||||
* `app_mode`: `Game` or `System`
|
||||
* `entrypoint`: symbol or index recognized by the VM
|
||||
|
||||
---
|
||||
|
||||
## 5. Regras do Runtime
|
||||
## 5. Runtime Rules
|
||||
|
||||
* Validar `magic` e `cartridge_version`
|
||||
* Ler `app_mode` para decidir fluxo de execução
|
||||
* Resolver `entrypoint` no `program.pbc`
|
||||
* Ignorar `assets/` se não suportado ainda
|
||||
* Validate `magic` and `cartridge_version`
|
||||
* Read `app_mode` to decide execution flow
|
||||
* Resolve `entrypoint` in `program.pbc`
|
||||
* Ignore `assets/` if not supported yet
|
||||
|
||||
---
|
||||
|
||||
## 6. Modos de Uso
|
||||
## 6. Usage Modes
|
||||
|
||||
### Diretório (desenvolvimento)
|
||||
### Directory (development)
|
||||
|
||||
```
|
||||
prometeu --run ./mycart/
|
||||
```
|
||||
|
||||
### Arquivo empacotado
|
||||
### Packaged file
|
||||
|
||||
```
|
||||
prometeu --run mygame.pmc
|
||||
```
|
||||
|
||||
Ambos devem se comportar de forma idêntica no runtime.
|
||||
Both must behave identically in the runtime.
|
||||
|
||||
---
|
||||
|
||||
## 7. Estabilidade do Contrato
|
||||
## 7. Contract Stability
|
||||
|
||||
A partir do v1:
|
||||
From v1 onwards:
|
||||
|
||||
* `manifest.json` é a fonte de verdade
|
||||
* Campos só podem ser adicionados de forma backward-compatible
|
||||
* Mudanças incompatíveis exigem `cartridge_version` novo
|
||||
* `manifest.json` is the source of truth
|
||||
* Fields can only be added in a backward-compatible manner
|
||||
* Incompatible changes require a new `cartridge_version`
|
||||
|
||||
< [Voltar](chapter-12.md) | [Sumário](table-of-contents.md) | [Adiante](chapter-14.md) >
|
||||
< [Back](chapter-12.md) | [Summary](table-of-contents.md) | [Next](chapter-14.md) >
|
||||
@ -1,25 +1,25 @@
|
||||
< [Voltar](chapter-13.md) | [Sumário](table-of-contents.md) >
|
||||
< [Back](chapter-13.md) | [Summary](table-of-contents.md) >
|
||||
|
||||
# Boot Profiles
|
||||
|
||||
**Versão:** 1.0
|
||||
**Status:** Proposta
|
||||
**Version:** 1.0
|
||||
**Status:** Proposal
|
||||
|
||||
---
|
||||
|
||||
## 1. Objetivo
|
||||
## 1. Objective
|
||||
|
||||
Definir como o Prometeu decide o que executar ao iniciar:
|
||||
Define how Prometeu decides what to execute at startup:
|
||||
|
||||
* Hub
|
||||
* Cartucho automaticamente
|
||||
* Modo debug
|
||||
* Automatic cartridge
|
||||
* Debug mode
|
||||
|
||||
---
|
||||
|
||||
## 2. Conceito de BootTarget
|
||||
## 2. BootTarget Concept
|
||||
|
||||
No início do boot, o POS resolve um alvo:
|
||||
At the beginning of boot, the POS resolves a target:
|
||||
|
||||
```rust
|
||||
enum BootTarget {
|
||||
@ -30,106 +30,106 @@ enum BootTarget {
|
||||
|
||||
---
|
||||
|
||||
## 3. Regras Gerais
|
||||
## 3. General Rules
|
||||
|
||||
### Se BootTarget == Hub
|
||||
### If BootTarget == Hub
|
||||
|
||||
* Firmware entra em `HubHome`
|
||||
* Nenhum cartucho é carregado automaticamente
|
||||
* Firmware enters `HubHome`
|
||||
* No cartridge is automatically loaded
|
||||
|
||||
### Se BootTarget == Cartridge
|
||||
### If BootTarget == Cartridge
|
||||
|
||||
1. Carregar cartucho
|
||||
2. Ler `app_mode` no manifest
|
||||
3. Aplicar regras:
|
||||
1. Load cartridge
|
||||
2. Read `app_mode` in the manifest
|
||||
3. Apply rules:
|
||||
|
||||
* `Game`:
|
||||
|
||||
* Entrar em `RunningGame`
|
||||
* Enter `RunningGame`
|
||||
* `System`:
|
||||
|
||||
* Permanecer em `HubHome`
|
||||
* Abrir o app como janela/system tool
|
||||
* Stay in `HubHome`
|
||||
* Open the app as a window/system tool
|
||||
|
||||
---
|
||||
|
||||
## 4. CLI do Host
|
||||
## 4. Host CLI
|
||||
|
||||
### Boot padrão
|
||||
### Default boot
|
||||
|
||||
```
|
||||
prometeu
|
||||
```
|
||||
|
||||
Resultado: entra no Hub
|
||||
Result: enters the Hub
|
||||
|
||||
### Executar cartucho
|
||||
### Run cartridge
|
||||
|
||||
```
|
||||
prometeu run <cartucho>
|
||||
prometeu run <cartridge>
|
||||
```
|
||||
|
||||
Resultado:
|
||||
Result:
|
||||
|
||||
* Game → entra direto no jogo
|
||||
* System → abre como tool no Hub
|
||||
* Game → enters directly into the game
|
||||
* System → opens as a tool in the Hub
|
||||
|
||||
### Executar com debugger
|
||||
### Run with debugger
|
||||
|
||||
```
|
||||
prometeu debug <cartucho>
|
||||
prometeu debug <cartridge>
|
||||
```
|
||||
|
||||
Resultado:
|
||||
Result:
|
||||
|
||||
* Mesmo fluxo do `run`
|
||||
* Runtime inicia em modo debug
|
||||
* Aguarda conexão do Debugger Java
|
||||
* Same flow as `run`
|
||||
* Runtime starts in debug mode
|
||||
* Waits for connection from the Java Debugger
|
||||
|
||||
---
|
||||
|
||||
## 5. Estados do Firmware
|
||||
## 5. Firmware States
|
||||
|
||||
Firmware mantém apenas:
|
||||
Firmware maintains only:
|
||||
|
||||
* `Boot`
|
||||
* `HubHome`
|
||||
* `RunningGame`
|
||||
* `AppCrashed`
|
||||
|
||||
System apps nunca mudam o estado do firmware.
|
||||
System apps never change the firmware state.
|
||||
|
||||
---
|
||||
|
||||
## 6. Comportamento em Hardware Real (futuro)
|
||||
## 6. Behavior on Real Hardware (future)
|
||||
|
||||
* Se miniSD/cartucho físico presente no boot:
|
||||
* If miniSD/physical cartridge is present at boot:
|
||||
|
||||
* POS pode:
|
||||
* POS can:
|
||||
|
||||
* sempre ir ao Hub, ou
|
||||
* auto-executar conforme configuração do usuário
|
||||
* always go to the Hub, or
|
||||
* auto-execute according to user configuration
|
||||
|
||||
---
|
||||
|
||||
## 7. Integração com Debugger
|
||||
## 7. Integration with Debugger
|
||||
|
||||
Quando `debug == true`:
|
||||
When `debug == true`:
|
||||
|
||||
* Runtime:
|
||||
|
||||
* Inicializa
|
||||
* Abre socket DevTools
|
||||
* Aguarda comando `start`
|
||||
* Somente após isso inicia execução do cartucho
|
||||
* Initializes
|
||||
* Opens DevTools socket
|
||||
* Waits for `start` command
|
||||
* Only after that does it start cartridge execution
|
||||
|
||||
---
|
||||
|
||||
## 8. Estabilidade
|
||||
## 8. Stability
|
||||
|
||||
* BootTarget é contrato interno do POS
|
||||
* CLI do host deve respeitar essas regras
|
||||
* Novos modos de boot devem ser extensões compatíveis
|
||||
* BootTarget is an internal POS contract
|
||||
* Host CLI must respect these rules
|
||||
* New boot modes must be compatible extensions
|
||||
|
||||
|
||||
< [Voltar](chapter-13.md) | [Sumário](table-of-contents.md) >
|
||||
< [Back](chapter-13.md) | [Summary](table-of-contents.md) >
|
||||
|
||||
@ -1,87 +1,87 @@
|
||||
< [Voltar](chapter-1.md) | [Sumário](table-of-contents.md) | [Adiante](chapter-3.md) >
|
||||
< [Back](chapter-1.md) | [Summary](table-of-contents.md) | [Next](chapter-3.md) >
|
||||
|
||||
# ⚙️ ** PVM (PROMETEU VM) — Instruction Set**
|
||||
|
||||
## 1. Visão Geral
|
||||
## 1. Overview
|
||||
|
||||
A **PROMETEU VM** é uma máquina virtual obrigatória e sempre presente no hardware lógico:
|
||||
The **PROMETEU VM** is a mandatory virtual machine always present in the logical hardware:
|
||||
|
||||
* **stack-based**
|
||||
* determinística
|
||||
* orientada a ciclos
|
||||
* projetada para ensino e inspeção
|
||||
* deterministic
|
||||
* cycle-oriented
|
||||
* designed for teaching and inspection
|
||||
|
||||
Ela existe para:
|
||||
It exists to:
|
||||
|
||||
* mapear conceitos de linguagens de alto nível
|
||||
* tornar custo computacional visível
|
||||
* permitir análise de execução
|
||||
* servir como base do cartucho PROMETEU
|
||||
* map high-level language concepts
|
||||
* make computational cost visible
|
||||
* allow execution analysis
|
||||
* serve as the foundation of the PROMETEU cartridge
|
||||
|
||||
> A PROMETEU VM é simples por escolha.
|
||||
> Simplicidade é uma ferramenta pedagógica.
|
||||
> The PROMETEU VM is simple by choice.
|
||||
> Simplicity is a pedagogical tool.
|
||||
|
||||
---
|
||||
|
||||
## 2. Modelo de Execução
|
||||
## 2. Execution Model
|
||||
|
||||
### 2.1 Componentes Principais
|
||||
### 2.1 Main Components
|
||||
|
||||
A VM possui:
|
||||
The VM has:
|
||||
|
||||
* **PC (Program Counter)** — próxima instrução
|
||||
* **Operand Stack** — pilha de valores
|
||||
* **Call Stack** — pilha de frames
|
||||
* **Heap** — memória dinâmica
|
||||
* **Globals** — variáveis globais
|
||||
* **Constant Pool** — literais e referências
|
||||
* **ROM** — bytecode do cartucho
|
||||
* **RAM** — dados mutáveis
|
||||
* **PC (Program Counter)** — next instruction
|
||||
* **Operand Stack** — value stack
|
||||
* **Call Stack** — frame stack
|
||||
* **Heap** — dynamic memory
|
||||
* **Globals** — global variables
|
||||
* **Constant Pool** — literals and references
|
||||
* **ROM** — cartridge bytecode
|
||||
* **RAM** — mutable data
|
||||
|
||||
---
|
||||
|
||||
### 2.2 Ciclo de Execução
|
||||
### 2.2 Execution Cycle
|
||||
|
||||
Cada instrução executa:
|
||||
Each instruction executes:
|
||||
|
||||
```
|
||||
FETCH → DECODE → EXECUTE → ADVANCE PC
|
||||
```
|
||||
|
||||
Propriedades:
|
||||
Properties:
|
||||
|
||||
* toda instrução tem custo fixo em ciclos
|
||||
* não há trabalho implícito invisível
|
||||
* execução é totalmente determinística
|
||||
* every instruction has a fixed cost in cycles
|
||||
* there is no invisible implicit work
|
||||
* execution is fully deterministic
|
||||
|
||||
---
|
||||
|
||||
## 3. Tipos Fundamentais
|
||||
## 3. Fundamental Types
|
||||
|
||||
| Tipo | Descrição |
|
||||
| --------- | ----------------------- |
|
||||
| `integer` | inteiro 64-bit (signed) |
|
||||
| `float` | ponto flutuante 64-bit |
|
||||
| `boolean` | verdadeiro/falso |
|
||||
| `string` | UTF-8 imutável |
|
||||
| `null` | ausência de valor |
|
||||
| `ref` | referência ao heap |
|
||||
| Type | Description |
|
||||
| --------- | ------------------------- |
|
||||
| `integer` | 64-bit signed integer |
|
||||
| `float` | 64-bit floating point |
|
||||
| `boolean` | true/false |
|
||||
| `string` | immutable UTF-8 |
|
||||
| `null` | absence of value |
|
||||
| `ref` | heap reference |
|
||||
|
||||
Não existem:
|
||||
Do not exist:
|
||||
|
||||
* coerções mágicas
|
||||
* casts implícitos
|
||||
* overflows silenciosos
|
||||
* magic coercions
|
||||
* implicit casts
|
||||
* silent overflows
|
||||
|
||||
---
|
||||
|
||||
## 4. Convenções da Pilha
|
||||
## 4. Stack Conventions
|
||||
|
||||
* Operações usam o topo da pilha
|
||||
* Resultado sempre volta para a pilha
|
||||
* Último empilhado = primeiro consumido
|
||||
* Operations use the top of the stack
|
||||
* Results always return to the stack
|
||||
* Last pushed = first consumed
|
||||
|
||||
Exemplo:
|
||||
Example:
|
||||
|
||||
```
|
||||
PUSH_CONST 3
|
||||
@ -89,7 +89,7 @@ PUSH_CONST 4
|
||||
ADD
|
||||
```
|
||||
|
||||
Estado:
|
||||
State:
|
||||
|
||||
```
|
||||
[3]
|
||||
@ -99,115 +99,115 @@ Estado:
|
||||
|
||||
---
|
||||
|
||||
## 5. Categorias de Instruções
|
||||
## 5. Instruction Categories
|
||||
|
||||
1. Controle de fluxo
|
||||
2. Pilha
|
||||
3. Aritmética e lógica
|
||||
4. Variáveis
|
||||
5. Funções
|
||||
6. Heap e estruturas
|
||||
7. Periféricos (syscalls)
|
||||
8. Sistema
|
||||
1. Flow control
|
||||
2. Stack
|
||||
3. Arithmetic and logic
|
||||
4. Variables
|
||||
5. Functions
|
||||
6. Heap and structures
|
||||
7. Peripherals (syscalls)
|
||||
8. System
|
||||
|
||||
---
|
||||
|
||||
## 6. Instruções — VM Set 1
|
||||
## 6. Instructions — VM Set 1
|
||||
|
||||
### 6.1 Controle de Execução
|
||||
### 6.1 Execution Control
|
||||
|
||||
| Instrução | Ciclos | Descrição |
|
||||
| ------------------- | ------ | ----------------------- |
|
||||
| `NOP` | 1 | Não faz nada |
|
||||
| `HALT` | 1 | Encerra execução |
|
||||
| `JMP addr` | 2 | Salto incondicional |
|
||||
| `JMP_IF_FALSE addr` | 3 | Salta se topo for falso |
|
||||
| Instruction | Cycles | Description |
|
||||
| ------------------- | ------ | ------------------------- |
|
||||
| `NOP` | 1 | Does nothing |
|
||||
| `HALT` | 1 | Terminates execution |
|
||||
| `JMP addr` | 2 | Unconditional jump |
|
||||
| `JMP_IF_FALSE addr` | 3 | Jumps if top is false |
|
||||
|
||||
---
|
||||
|
||||
### 6.2 Pilha
|
||||
### 6.2 Stack
|
||||
|
||||
| Instrução | Ciclos | Descrição |
|
||||
| -------------- | ------ | ----------------- |
|
||||
| `PUSH_CONST k` | 2 | Empilha constante |
|
||||
| `POP` | 1 | Remove topo |
|
||||
| `DUP` | 1 | Duplica topo |
|
||||
| `SWAP` | 1 | Troca dois topos |
|
||||
| Instruction | Cycles | Description |
|
||||
| -------------- | ------ | ------------------- |
|
||||
| `PUSH_CONST k` | 2 | Pushes constant |
|
||||
| `POP` | 1 | Removes top |
|
||||
| `DUP` | 1 | Duplicates top |
|
||||
| `SWAP` | 1 | Swaps two tops |
|
||||
|
||||
---
|
||||
|
||||
### 6.3 Aritmética
|
||||
### 6.3 Arithmetic
|
||||
|
||||
| Instrução | Ciclos |
|
||||
| --------- | ------ |
|
||||
| `ADD` | 2 |
|
||||
| `SUB` | 2 |
|
||||
| `MUL` | 4 |
|
||||
| `DIV` | 6 |
|
||||
| Instruction | Cycles |
|
||||
| ----------- | ------ |
|
||||
| `ADD` | 2 |
|
||||
| `SUB` | 2 |
|
||||
| `MUL` | 4 |
|
||||
| `DIV` | 6 |
|
||||
|
||||
---
|
||||
|
||||
### 6.4 Comparação e Lógica
|
||||
### 6.4 Comparison and Logic
|
||||
|
||||
| Instrução | Ciclos |
|
||||
| --------- | ------ |
|
||||
| `EQ` | 2 |
|
||||
| `NEQ` | 2 |
|
||||
| `LT` | 2 |
|
||||
| `GT` | 2 |
|
||||
| `AND` | 2 |
|
||||
| `OR` | 2 |
|
||||
| `NOT` | 1 |
|
||||
| Instruction | Cycles |
|
||||
| ----------- | ------ |
|
||||
| `EQ` | 2 |
|
||||
| `NEQ` | 2 |
|
||||
| `LT` | 2 |
|
||||
| `GT` | 2 |
|
||||
| `AND` | 2 |
|
||||
| `OR` | 2 |
|
||||
| `NOT` | 1 |
|
||||
|
||||
---
|
||||
|
||||
### 6.5 Variáveis
|
||||
### 6.5 Variables
|
||||
|
||||
| Instrução | Ciclos | Descrição |
|
||||
| -------------- | ------ | -------------- |
|
||||
| `GET_GLOBAL i` | 3 | Lê global |
|
||||
| `SET_GLOBAL i` | 3 | Escreve global |
|
||||
| `GET_LOCAL i` | 2 | Lê local |
|
||||
| `SET_LOCAL i` | 2 | Escreve local |
|
||||
| Instruction | Cycles | Description |
|
||||
| -------------- | ------ | ---------------- |
|
||||
| `GET_GLOBAL i` | 3 | Reads global |
|
||||
| `SET_GLOBAL i` | 3 | Writes global |
|
||||
| `GET_LOCAL i` | 2 | Reads local |
|
||||
| `SET_LOCAL i` | 2 | Writes local |
|
||||
|
||||
---
|
||||
|
||||
### 6.6 Funções
|
||||
### 6.6 Functions
|
||||
|
||||
| Instrução | Ciclos | Descrição |
|
||||
| Instruction | Cycles | Description |
|
||||
|----------------| ------ |---------------------------------|
|
||||
| `CALL addr` | 5 | Chamada |
|
||||
| `RET` | 4 | Retorno |
|
||||
| `PUSH_SCOPE n` | 3 | Cria escopo (frame de execução) |
|
||||
| `POP_SCOPE` | 3 | Remove escopo |
|
||||
| `CALL addr` | 5 | Call |
|
||||
| `RET` | 4 | Return |
|
||||
| `PUSH_SCOPE n` | 3 | Creates scope (execution frame) |
|
||||
| `POP_SCOPE` | 3 | Removes scope |
|
||||
|
||||
---
|
||||
|
||||
### 6.7 Heap
|
||||
|
||||
| Instrução | Ciclos | Descrição |
|
||||
| --------------- | ------ | ------------- |
|
||||
| `ALLOC size` | 10 | Aloca no heap |
|
||||
| `LOAD_REF off` | 3 | Lê campo |
|
||||
| `STORE_REF off` | 3 | Escreve campo |
|
||||
| Instruction | Cycles | Description |
|
||||
| --------------- | ------ | --------------- |
|
||||
| `ALLOC size` | 10 | Allocates on heap |
|
||||
| `LOAD_REF off` | 3 | Reads field |
|
||||
| `STORE_REF off` | 3 | Writes field |
|
||||
|
||||
Heap é:
|
||||
Heap is:
|
||||
|
||||
* finito
|
||||
* monitorado
|
||||
* contabilizado no CAP
|
||||
* finite
|
||||
* monitored
|
||||
* accounted for in the CAP
|
||||
|
||||
---
|
||||
|
||||
### 6.8 Periféricos (Syscalls)
|
||||
### 6.8 Peripherals (Syscalls)
|
||||
|
||||
| Instrução | Ciclos | Descrição |
|
||||
|--------------| -------- | ------------------- |
|
||||
| `SYSCALL id` | variável | Chamada ao hardware |
|
||||
| Instruction | Cycles | Description |
|
||||
|--------------| -------- | --------------------- |
|
||||
| `SYSCALL id` | variable | Call to hardware |
|
||||
|
||||
#### Syscalls Implementadas (v0.1)
|
||||
#### Implemented Syscalls (v0.1)
|
||||
|
||||
| ID | Nome | Argumentos (Pilha) | Retorno |
|
||||
| ID | Name | Arguments (Stack) | Return |
|
||||
| ---------- | ----------------- | ---------------------------- | ------- |
|
||||
| `0x0001` | `system.has_cart` | - | `bool` |
|
||||
| `0x0002` | `system.run_cart` | - | - |
|
||||
@ -216,7 +216,7 @@ Heap é:
|
||||
| `0x2001` | `input.get_pad` | `button_id` | `bool` |
|
||||
| `0x3001` | `audio.play` | `s_id, v_id, vol, pan, pitch`| - |
|
||||
|
||||
**IDs de Botões:**
|
||||
**Button IDs:**
|
||||
- `0`: Up, `1`: Down, `2`: Left, `3`: Right
|
||||
- `4`: A, `5`: B, `6`: X, `7`: Y
|
||||
- `8`: L, `9`: R
|
||||
@ -224,57 +224,57 @@ Heap é:
|
||||
|
||||
---
|
||||
|
||||
## 7. Erros de Execução
|
||||
## 7. Execution Errors
|
||||
|
||||
Erros são:
|
||||
Errors are:
|
||||
|
||||
* explícitos
|
||||
* fatais
|
||||
* nunca silenciosos
|
||||
* explicit
|
||||
* fatal
|
||||
* never silent
|
||||
|
||||
Tipos:
|
||||
Types:
|
||||
|
||||
* stack underflow
|
||||
* tipo inválido
|
||||
* heap inválido
|
||||
* frame inválido
|
||||
* invalid type
|
||||
* invalid heap
|
||||
* invalid frame
|
||||
|
||||
Geram:
|
||||
Generate:
|
||||
|
||||
* mensagem clara
|
||||
* dump de estado
|
||||
* clear message
|
||||
* state dump
|
||||
* stack trace
|
||||
|
||||
---
|
||||
|
||||
## 8. Determinismo
|
||||
## 8. Determinism
|
||||
|
||||
Garantias:
|
||||
Guarantees:
|
||||
|
||||
* mesma entrada → mesmo resultado
|
||||
* mesma sequência → mesmos ciclos
|
||||
* sem execução especulativa
|
||||
* sem otimizações invisíveis
|
||||
* same input → same result
|
||||
* same sequence → same cycles
|
||||
* no speculative execution
|
||||
* no invisible optimizations
|
||||
|
||||
> Se você vê a instrução, você paga por ela.
|
||||
> If you see the instruction, you pay for it.
|
||||
|
||||
---
|
||||
|
||||
## 9. Relação com Linguagens
|
||||
## 9. Relationship with Languages
|
||||
|
||||
Java, TypeScript, Lua etc:
|
||||
|
||||
* são linguagens-fonte
|
||||
* compiladas para esse bytecode
|
||||
* nunca executadas diretamente
|
||||
* are source languages
|
||||
* compiled to this bytecode
|
||||
* never executed directly
|
||||
|
||||
Todas rodam na **mesma VM**.
|
||||
All run on the **same VM**.
|
||||
|
||||
---
|
||||
|
||||
## 10. Exemplo
|
||||
## 10. Example
|
||||
|
||||
Fonte:
|
||||
Source:
|
||||
|
||||
```java
|
||||
x = 3 + 4;
|
||||
@ -289,107 +289,107 @@ ADD
|
||||
SET_GLOBAL 0
|
||||
```
|
||||
|
||||
Custo:
|
||||
Cost:
|
||||
|
||||
```
|
||||
2 + 2 + 2 + 3 = 9 ciclos
|
||||
2 + 2 + 2 + 3 = 9 cycles
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 11. Execução por Tick
|
||||
## 11. Execution per Tick
|
||||
|
||||
A VM não roda infinitamente.
|
||||
The VM does not run infinitely.
|
||||
|
||||
Ela executa:
|
||||
It executes:
|
||||
|
||||
* até consumir o budget do **frame lógico**
|
||||
* ou até `HALT`
|
||||
* until consuming the **logical frame** budget
|
||||
* or until `HALT`
|
||||
|
||||
O budget é definido pelo hardware lógico do PROMETEU (ex.: `CYCLES_PER_FRAME`).
|
||||
The budget is defined by the PROMETEU logical hardware (e.g., `CYCLES_PER_FRAME`).
|
||||
|
||||
Exemplo:
|
||||
Example:
|
||||
|
||||
```
|
||||
vm.step_budget(10_000)
|
||||
```
|
||||
|
||||
Isso alimenta:
|
||||
This feeds:
|
||||
|
||||
* CAP
|
||||
* profiling
|
||||
* certificação
|
||||
* certification
|
||||
|
||||
---
|
||||
|
||||
## 12. Frame Lógico e `FRAME_SYNC`
|
||||
## 12. Logical Frame and `FRAME_SYNC`
|
||||
|
||||
O PROMETEU define **frame lógico** como a unidade mínima de atualização consistente do jogo.
|
||||
PROMETEU defines **logical frame** as the minimum unit of consistent game update.
|
||||
|
||||
* **Input é latched por frame lógico** (não muda enquanto o frame lógico não for concluído).
|
||||
* O **budget de ciclos** é aplicado ao frame lógico.
|
||||
* Um novo frame lógico só começa quando o frame atual termina.
|
||||
* **Input is latched per logical frame** (does not change until the logical frame is completed).
|
||||
* The **cycle budget** is applied to the logical frame.
|
||||
* A new logical frame only starts when the current frame ends.
|
||||
|
||||
### 12.1 Instrução de Sistema: `FRAME_SYNC`
|
||||
### 12.1 System Instruction: `FRAME_SYNC`
|
||||
|
||||
A instrução `FRAME_SYNC` marca o **fim do frame lógico**.
|
||||
The `FRAME_SYNC` instruction marks the **end of the logical frame**.
|
||||
|
||||
| Instrução | Ciclos | Descrição |
|
||||
| ------------ | ------ | ----------------------------- |
|
||||
| `FRAME_SYNC` | 1 | Finaliza o frame lógico atual |
|
||||
| Instruction | Cycles | Description |
|
||||
| ------------ | ------ | ---------------------------------- |
|
||||
| `FRAME_SYNC` | 1 | Finalizes the current logical frame |
|
||||
|
||||
Propriedades:
|
||||
Properties:
|
||||
|
||||
* `FRAME_SYNC` é uma **instrução do sistema**.
|
||||
* Não deve ser exposta como API “manual” ao usuário.
|
||||
* O tooling/compilador pode **injetar** `FRAME_SYNC` automaticamente ao final do loop principal.
|
||||
* `FRAME_SYNC` is a **system instruction**.
|
||||
* It should not be exposed as a "manual" API to the user.
|
||||
* Tooling/compiler can **inject** `FRAME_SYNC` automatically at the end of the main loop.
|
||||
|
||||
### 12.2 Semântica (o que acontece quando executa)
|
||||
### 12.2 Semantics (what happens when it executes)
|
||||
|
||||
Ao executar `FRAME_SYNC`, o core:
|
||||
When executing `FRAME_SYNC`, the core:
|
||||
|
||||
1. **Finaliza** o frame lógico atual.
|
||||
2. **Apresenta** o frame (`gfx.present()` ou `gfx.compose_and_present()` conforme o modelo do GFX).
|
||||
3. **Libera** o latch de input.
|
||||
4. **Reseta** o budget para o próximo frame lógico.
|
||||
1. **Finalizes** the current logical frame.
|
||||
2. **Presents** the frame (`gfx.present()` or `gfx.compose_and_present()` depending on the GFX model).
|
||||
3. **Releases** the input latch.
|
||||
4. **Resets** the budget for the next logical frame.
|
||||
|
||||
### 12.3 Overbudget (quando o frame não termina a tempo)
|
||||
### 12.3 Overbudget (when the frame doesn't finish on time)
|
||||
|
||||
Se o budget do frame lógico acabar **antes** da VM alcançar `FRAME_SYNC`:
|
||||
If the logical frame budget runs out **before** the VM reaches `FRAME_SYNC`:
|
||||
|
||||
* a VM **pausa** (PC e pilhas permanecem no ponto exato)
|
||||
* **não há present**
|
||||
* o latch de input é **mantido**
|
||||
* no próximo tick do host, a VM **continua** de onde parou, ainda no mesmo frame lógico
|
||||
* the VM **pauses** (PC and stacks remain at the exact point)
|
||||
* there is **no present**
|
||||
* the input latch is **maintained**
|
||||
* on the next host tick, the VM **continues** from where it left off, still in the same logical frame
|
||||
|
||||
Efeito prático:
|
||||
Practical effect:
|
||||
|
||||
* se o código precisa de 2 budgets para alcançar `FRAME_SYNC`, o jogo passa a atualizar a ~30 FPS (frame lógico leva 2 ticks)
|
||||
* isso é determinístico e reportável no CAP
|
||||
* if the code needs 2 budgets to reach `FRAME_SYNC`, the game updates at ~30 FPS (logical frame takes 2 ticks)
|
||||
* this is deterministic and reportable in the CAP
|
||||
|
||||
---
|
||||
|
||||
## 15. Extensibilidade
|
||||
## 15. Extensibility
|
||||
|
||||
O Instruction Set é versionado.
|
||||
The Instruction Set is versioned.
|
||||
|
||||
Futuro:
|
||||
Future:
|
||||
|
||||
* DMA
|
||||
* streaming
|
||||
* vetores
|
||||
* coprocessadores fictícios
|
||||
* vectors
|
||||
* fictitious coprocessors
|
||||
|
||||
Nenhuma instrução existente muda de significado.
|
||||
No existing instruction changes its meaning.
|
||||
|
||||
---
|
||||
|
||||
## 16. Resumo
|
||||
## 16. Summary
|
||||
|
||||
* VM stack-based
|
||||
* custo explícito
|
||||
* execução determinística
|
||||
* integrada ao CAP
|
||||
* base de todo cartucho PROMETEU
|
||||
* stack-based VM
|
||||
* explicit cost
|
||||
* deterministic execution
|
||||
* integrated with CAP
|
||||
* foundation of every PROMETEU cartridge
|
||||
|
||||
< [Voltar](chapter-1.md) | [Sumário](table-of-contents.md) | [Adiante](chapter-3.md) >
|
||||
< [Back](chapter-1.md) | [Summary](table-of-contents.md) | [Next](chapter-3.md) >
|
||||
@ -1,29 +1,29 @@
|
||||
< [Voltar](chapter-2.md) | [Sumário](table-of-contents.md) | [Adiante](chapter-4.md) >
|
||||
< [Back](chapter-2.md) | [Summary](table-of-contents.md) | [Next](chapter-4.md) >
|
||||
|
||||
# 🧠 **Memória: Stack, Heap e Alocação**
|
||||
# 🧠 **Memory: Stack, Heap, and Allocation**
|
||||
|
||||
## 1. Visão Geral
|
||||
## 1. Overview
|
||||
|
||||
PROMETEU trata **memória como um recurso explícito**.
|
||||
PROMETEU treats **memory as an explicit resource**.
|
||||
|
||||
Nada é alocado “por conveniência”.
|
||||
Nothing is allocated "for convenience".
|
||||
|
||||
Nada cresce “automaticamente”.
|
||||
Nothing grows "automatically".
|
||||
|
||||
Nada é invisível.
|
||||
Nothing is invisible.
|
||||
|
||||
Este capítulo define:
|
||||
This chapter defines:
|
||||
|
||||
- os **espaços de memória** da PROMETEU VM
|
||||
- como **Stack** e **Heap** funcionam
|
||||
- o custo e as consequências da **alocação dinâmica**
|
||||
- como a memória se relaciona com **CAP e certificação**
|
||||
- the **memory spaces** of the PROMETEU VM
|
||||
- how **Stack** and **Heap** work
|
||||
- the cost and consequences of **dynamic allocation**
|
||||
- how memory relates to **CAP and certification**
|
||||
|
||||
---
|
||||
|
||||
## 2. Espaços de Memória da PROMETEU VM
|
||||
## 2. PROMETEU VM Memory Spaces
|
||||
|
||||
A memória da PROMETEU VM é dividida em regiões com responsabilidades claras:
|
||||
The PROMETEU VM memory is divided into regions with clear responsibilities:
|
||||
|
||||
```
|
||||
+---------------------------+
|
||||
@ -41,61 +41,61 @@ A memória da PROMETEU VM é dividida em regiões com responsabilidades claras:
|
||||
|
||||
```
|
||||
|
||||
Cada região:
|
||||
Each region:
|
||||
|
||||
- tem semântica própria
|
||||
- tem limites definidos
|
||||
- tem impacto direto no custo de execução
|
||||
- has its own semantics
|
||||
- has defined limits
|
||||
- has a direct impact on execution cost
|
||||
|
||||
---
|
||||
|
||||
## 3. Operand Stack
|
||||
|
||||
### 3.1 Definição
|
||||
### 3.1 Definition
|
||||
|
||||
A **Operand Stack** é usada para:
|
||||
The **Operand Stack** is used for:
|
||||
|
||||
- passagem de operandos entre instruções
|
||||
- resultados intermediários
|
||||
- avaliação de expressões
|
||||
- passing operands between instructions
|
||||
- intermediate results
|
||||
- expression evaluation
|
||||
|
||||
Ela é:
|
||||
It is:
|
||||
|
||||
- **LIFO**
|
||||
- de crescimento automático dentro do frame
|
||||
- **resetada** entre frames (exceto valores persistidos explicitamente)
|
||||
- automatically growing within the frame
|
||||
- **reset** between frames (except explicitly persisted values)
|
||||
|
||||
---
|
||||
|
||||
### 3.2 Características
|
||||
### 3.2 Characteristics
|
||||
|
||||
- não armazena estruturas complexas
|
||||
- armazena valores primitivos ou referências
|
||||
- overflow ou underflow são **erros fatais**
|
||||
- does not store complex structures
|
||||
- stores primitive values or references
|
||||
- overflow or underflow are **fatal errors**
|
||||
|
||||
> A pilha de operandos é barata, rápida e temporária.
|
||||
> The operand stack is cheap, fast, and temporary.
|
||||
>
|
||||
|
||||
---
|
||||
|
||||
## 4. Call Stack (Stack de Chamadas)
|
||||
## 4. Call Stack
|
||||
|
||||
### 4.1 Frames de Execução
|
||||
### 4.1 Execution Frames
|
||||
|
||||
Cada chamada de função cria um **Call Frame**, contendo:
|
||||
Each function call creates a **Call Frame**, containing:
|
||||
|
||||
- variáveis locais
|
||||
- parâmetros
|
||||
- endereço de retorno
|
||||
- contexto de execução
|
||||
- local variables
|
||||
- parameters
|
||||
- return address
|
||||
- execution context
|
||||
|
||||
Frames são criados com:
|
||||
Frames are created with:
|
||||
|
||||
```
|
||||
PUSH_FRAME n
|
||||
```
|
||||
|
||||
E destruídos com:
|
||||
And destroyed with:
|
||||
|
||||
```
|
||||
POP_FRAME
|
||||
@ -103,64 +103,64 @@ POP_FRAME
|
||||
|
||||
---
|
||||
|
||||
### 4.2 Custos e Limites
|
||||
### 4.2 Costs and Limits
|
||||
|
||||
- criação de frame tem custo explícito
|
||||
- profundidade máxima de stack é limitada
|
||||
- recursão profunda é desencorajada
|
||||
- frame creation has an explicit cost
|
||||
- maximum stack depth is limited
|
||||
- deep recursion is discouraged
|
||||
|
||||
PROMETEU favorece:
|
||||
PROMETEU favors:
|
||||
|
||||
- iteração
|
||||
- estado explícito
|
||||
- controle consciente de profundidade
|
||||
- iteration
|
||||
- explicit state
|
||||
- conscious depth control
|
||||
|
||||
---
|
||||
|
||||
## 5. Global Space
|
||||
|
||||
### 5.1 Definição
|
||||
### 5.1 Definition
|
||||
|
||||
O **Global Space** armazena:
|
||||
The **Global Space** stores:
|
||||
|
||||
- variáveis globais
|
||||
- estado persistente do jogo
|
||||
- referências de longo prazo
|
||||
- global variables
|
||||
- persistent game state
|
||||
- long-term references
|
||||
|
||||
Globais:
|
||||
Globals:
|
||||
|
||||
- sobrevivem entre frames
|
||||
- ocupam memória permanentemente
|
||||
- contam para o uso total de memória
|
||||
- survive between frames
|
||||
- occupy memory permanently
|
||||
- count towards total memory usage
|
||||
|
||||
---
|
||||
|
||||
### 5.2 Uso consciente
|
||||
### 5.2 Conscious usage
|
||||
|
||||
PROMETEU incentiva:
|
||||
PROMETEU encourages:
|
||||
|
||||
- poucas globais
|
||||
- estruturas compactas
|
||||
- inicialização explícita
|
||||
- few globals
|
||||
- compact structures
|
||||
- explicit initialization
|
||||
|
||||
Globais são equivalentes a **RAM estática** em microcontroladores.
|
||||
Globals are equivalent to **static RAM** in microcontrollers.
|
||||
|
||||
---
|
||||
|
||||
## 6. Heap
|
||||
|
||||
### 6.1 Definição
|
||||
### 6.1 Definition
|
||||
|
||||
O **Heap** é a região de memória dinâmica da PROMETEU VM.
|
||||
The **Heap** is the dynamic memory region of the PROMETEU VM.
|
||||
|
||||
É usado para:
|
||||
It is used for:
|
||||
|
||||
- objetos
|
||||
- objects
|
||||
- arrays
|
||||
- tabelas
|
||||
- estruturas compostas
|
||||
- tables
|
||||
- composite structures
|
||||
|
||||
Toda alocação no heap é feita explicitamente com:
|
||||
Every allocation on the heap is done explicitly with:
|
||||
|
||||
```
|
||||
ALLOC size
|
||||
@ -168,142 +168,142 @@ ALLOC size
|
||||
|
||||
---
|
||||
|
||||
### 6.2 Custos da Alocação
|
||||
### 6.2 Allocation Costs
|
||||
|
||||
Alocar memória:
|
||||
Allocating memory:
|
||||
|
||||
- consome **ciclos**
|
||||
- consome **heap disponível**
|
||||
- aumenta pressão sobre o sistema
|
||||
- consumes **cycles**
|
||||
- consumes **available heap**
|
||||
- increases pressure on the system
|
||||
|
||||
PROMETEU trata alocação como uma operação **cara por definição**.
|
||||
PROMETEU treats allocation as an **expensive operation by definition**.
|
||||
|
||||
> Alocar é uma decisão arquitetural, não um detalhe.
|
||||
> Allocation is an architectural decision, not a detail.
|
||||
>
|
||||
|
||||
---
|
||||
|
||||
## 7. Limites de Heap
|
||||
## 7. Heap Limits
|
||||
|
||||
### 7.1 Heap Finito
|
||||
### 7.1 Finite Heap
|
||||
|
||||
O heap:
|
||||
The heap:
|
||||
|
||||
- tem tamanho máximo definido
|
||||
- pode variar conforme o CAP ativo
|
||||
- nunca cresce dinamicamente
|
||||
- has a defined maximum size
|
||||
- can vary according to the active CAP
|
||||
- never grows dynamically
|
||||
|
||||
Exemplo:
|
||||
Example:
|
||||
|
||||
```
|
||||
Heap Limit:32KB
|
||||
Heap Used:28KB
|
||||
```
|
||||
|
||||
Ultrapassar o limite:
|
||||
Exceeding the limit:
|
||||
|
||||
- não trava o jogo
|
||||
- gera erro de execução
|
||||
- aparece no relatório de certificação
|
||||
- does not crash the game
|
||||
- generates an execution error
|
||||
- appears in the certification report
|
||||
|
||||
---
|
||||
|
||||
### 7.2 Heap e CAP
|
||||
### 7.2 Heap and CAP
|
||||
|
||||
Durante uma JAM ou avaliação:
|
||||
During a JAM or evaluation:
|
||||
|
||||
- o pico de heap é medido
|
||||
- o valor é comparado ao limite do CAP
|
||||
- não conformidades são registradas
|
||||
- heap peak is measured
|
||||
- the value is compared to the CAP limit
|
||||
- non-compliances are recorded
|
||||
|
||||
O jogo **continua rodando**, mas a evidência fica registrada.
|
||||
The game **continues running**, but the evidence is recorded.
|
||||
|
||||
---
|
||||
|
||||
## 8. Garbage Collection (GC)
|
||||
|
||||
### 8.1 Existência do GC
|
||||
### 8.1 Existence of GC
|
||||
|
||||
PROMETEU pode utilizar **Garbage Collection simples**, com as seguintes propriedades:
|
||||
PROMETEU may use **simple Garbage Collection**, with the following properties:
|
||||
|
||||
- não incremental (v0.1)
|
||||
- custo explícito
|
||||
- pausas observáveis
|
||||
- comportamento documentado
|
||||
- non-incremental (v0.1)
|
||||
- explicit cost
|
||||
- observable pauses
|
||||
- documented behavior
|
||||
|
||||
GC **não é invisível**.
|
||||
GC **is not invisible**.
|
||||
|
||||
---
|
||||
|
||||
### 8.2 Custo do GC
|
||||
### 8.2 GC Cost
|
||||
|
||||
Quando o GC ocorre:
|
||||
When GC occurs:
|
||||
|
||||
- ciclos são consumidos
|
||||
- o frame pode sofrer impacto
|
||||
- o evento é registrado
|
||||
- cycles are consumed
|
||||
- the frame may be impacted
|
||||
- the event is recorded
|
||||
|
||||
PROMETEU ensina:
|
||||
PROMETEU teaches:
|
||||
|
||||
> “Criar lixo tem custo.”
|
||||
> "Creating garbage has a cost."
|
||||
>
|
||||
|
||||
---
|
||||
|
||||
## 9. Boas Práticas de Memória
|
||||
## 9. Memory Best Practices
|
||||
|
||||
PROMETEU encoraja explicitamente:
|
||||
PROMETEU explicitly encourages:
|
||||
|
||||
- reutilização de estruturas
|
||||
- alocação fora do loop principal
|
||||
- buffers persistentes
|
||||
- structure reuse
|
||||
- allocation outside the main loop
|
||||
- persistent buffers
|
||||
- pooling manual
|
||||
|
||||
E desencoraja:
|
||||
And discourages:
|
||||
|
||||
- alocação por frame
|
||||
- estruturas temporárias descartáveis
|
||||
- crescimento não planejado
|
||||
- per-frame allocation
|
||||
- disposable temporary structures
|
||||
- unplanned growth
|
||||
|
||||
---
|
||||
|
||||
## 10. Relação com Microcontroladores
|
||||
## 10. Relationship with Microcontrollers
|
||||
|
||||
O modelo de memória PROMETEU é intencionalmente similar a MCUs reais:
|
||||
The PROMETEU memory model is intentionally similar to real MCUs:
|
||||
|
||||
| MCU | PROMETEU |
|
||||
| --- | --- |
|
||||
| RAM estática | Global Space |
|
||||
| Static RAM | Global Space |
|
||||
| Stack | Call Stack |
|
||||
| Heap | Heap |
|
||||
| Falha de alocação | Erro explícito |
|
||||
| Fragmentação | Responsabilidade do dev |
|
||||
| Allocation failure | Explicit error |
|
||||
| Fragmentation | Dev's responsibility |
|
||||
|
||||
Isso cria transferência direta de aprendizado.
|
||||
This creates a direct transfer of learning.
|
||||
|
||||
---
|
||||
|
||||
## 11. Implicações Pedagógicas
|
||||
## 11. Pedagogical Implications
|
||||
|
||||
Este modelo permite ensinar:
|
||||
This model allows teaching:
|
||||
|
||||
- diferença entre stack e heap
|
||||
- custo de alocação
|
||||
- lifetime de dados
|
||||
- impacto arquitetural de decisões simples
|
||||
- relação entre memória e tempo
|
||||
- the difference between stack and heap
|
||||
- allocation cost
|
||||
- data lifetime
|
||||
- architectural impact of simple decisions
|
||||
- the relationship between memory and time
|
||||
|
||||
Tudo com **feedback imediato e visível**.
|
||||
Everything with **immediate and visible feedback**.
|
||||
|
||||
---
|
||||
|
||||
## 12. Resumo
|
||||
## 12. Summary
|
||||
|
||||
- PROMETEU possui espaços de memória bem definidos
|
||||
- stack é temporária e barata
|
||||
- heap é finita e cara
|
||||
- alocação tem custo explícito
|
||||
- GC é visível e mensurável
|
||||
- memória participa da certificação
|
||||
- PROMETEU has well-defined memory spaces
|
||||
- stack is temporary and cheap
|
||||
- heap is finite and expensive
|
||||
- allocation has an explicit cost
|
||||
- GC is visible and measurable
|
||||
- memory participates in certification
|
||||
|
||||
< [Voltar](chapter-2.md) | [Sumário](table-of-contents.md) | [Adiante](chapter-4.md) >
|
||||
< [Back](chapter-2.md) | [Summary](table-of-contents.md) | [Next](chapter-4.md) >
|
||||
@ -1,229 +1,229 @@
|
||||
< [Voltar](chapter-3.md) | [Sumário](table-of-contents.md) | [Adiante](chapter-5.md) >
|
||||
< [Back](chapter-3.md) | [Summary](table-of-contents.md) | [Next](chapter-5.md) >
|
||||
|
||||
# 🎨 **Periférico GFX (Sistema Gráfico)**
|
||||
# 🎨 **GFX Peripheral (Graphics System)**
|
||||
|
||||
## 1. Visão Geral
|
||||
## 1. Overview
|
||||
|
||||
O periférico **GFX** é responsável pela geração de imagem no PROMETEU.
|
||||
The **GFX** peripheral is responsible for generating images in PROMETEU.
|
||||
|
||||
Ele modela um **hardware gráfico simples**, inspirado em consoles clássicos
|
||||
(SNES, CPS-2, Neo-Geo), priorizando:
|
||||
It models **simple graphics hardware**, inspired by classic consoles
|
||||
(SNES, CPS-2, Neo-Geo), prioritizing:
|
||||
|
||||
- determinismo
|
||||
- baixo custo computacional
|
||||
- didática
|
||||
- portabilidade
|
||||
- determinism
|
||||
- low computational cost
|
||||
- didactics
|
||||
- portability
|
||||
|
||||
O GFX **não é uma GPU moderna**.
|
||||
Ele é um dispositivo explícito, baseado em:
|
||||
The GFX **is not a modern GPU**.
|
||||
It is an explicit device, based on:
|
||||
|
||||
- framebuffer
|
||||
- tilemaps
|
||||
- banks de tiles
|
||||
- sprites por prioridade
|
||||
- composição por ordem de desenho
|
||||
- tile banks
|
||||
- priority-based sprites
|
||||
- composition by drawing order
|
||||
|
||||
---
|
||||
|
||||
## 2. Resolução e Framebuffer
|
||||
## 2. Resolution and Framebuffer
|
||||
|
||||
### Resolução base
|
||||
### Base resolution
|
||||
|
||||
- **320 × 180 pixels**
|
||||
- proporção próxima de 16:9
|
||||
- escalável pelo host (nearest-neighbor)
|
||||
- aspect ratio close to 16:9
|
||||
- scalable by the host (nearest-neighbor)
|
||||
|
||||
### Formato de pixel
|
||||
### Pixel format
|
||||
|
||||
- **RGB565**
|
||||
- 5 bits Red
|
||||
- 6 bits Green
|
||||
- 5 bits Blue
|
||||
- sem canal alpha
|
||||
- 5 bits Red
|
||||
- 6 bits Green
|
||||
- 5 bits Blue
|
||||
- no alpha channel
|
||||
|
||||
Transparência é feita por **color key**.
|
||||
Transparency is handled via **color key**.
|
||||
|
||||
---
|
||||
|
||||
## 3. Double Buffering
|
||||
|
||||
O GFX mantém dois buffers:
|
||||
The GFX maintains two buffers:
|
||||
|
||||
- **Back Buffer** — onde o frame é construído
|
||||
- **Front Buffer** — onde o frame é exibido
|
||||
- **Back Buffer** — where the frame is built
|
||||
- **Front Buffer** — where the frame is displayed
|
||||
|
||||
Fluxo por frame:
|
||||
Per-frame flow:
|
||||
|
||||
1. O sistema desenha no back buffer
|
||||
2. Chama `present()`
|
||||
3. Buffers são trocados
|
||||
4. O host exibe o front buffer
|
||||
1. The system draws to the back buffer
|
||||
2. Calls `present()`
|
||||
3. Buffers are swapped
|
||||
4. The host displays the front buffer
|
||||
|
||||
Isso garante:
|
||||
This guarantees:
|
||||
|
||||
- ausência de tearing
|
||||
- sincronização clara por frame
|
||||
- comportamento determinístico
|
||||
- no tearing
|
||||
- clear per-frame synchronization
|
||||
- deterministic behavior
|
||||
|
||||
---
|
||||
|
||||
## 4. Estrutura Gráfica do PROMETEU
|
||||
## 4. PROMETEU Graphical Structure
|
||||
|
||||
O mundo gráfico é composto por:
|
||||
The graphical world is composed of:
|
||||
|
||||
- Até **16 Tile Banks**
|
||||
- **4 Tile Layers** (scrolláveis)
|
||||
- **1 HUD Layer** (fixa, sempre por cima)
|
||||
- Sprites com prioridade entre layers
|
||||
- Up to **16 Tile Banks**
|
||||
- **4 Tile Layers** (scrollable)
|
||||
- **1 HUD Layer** (fixed, always on top)
|
||||
- Sprites with priority between layers
|
||||
|
||||
### 4.1 Tile Banks
|
||||
|
||||
- Existem até **16 banks**
|
||||
- Cada bank tem tamanho fixo de tile:
|
||||
- 8×8, 16×16 ou 32×32
|
||||
- Um bank é uma biblioteca de gráficos:
|
||||
- ambiente
|
||||
- personagens
|
||||
- There are up to **16 banks**
|
||||
- Each bank has a fixed tile size:
|
||||
- 8×8, 16×16, or 32×32
|
||||
- A bank is a graphics library:
|
||||
- environment
|
||||
- characters
|
||||
- UI
|
||||
- efeitos
|
||||
- effects
|
||||
|
||||
### 4.2 Layers
|
||||
|
||||
- Existem:
|
||||
- There are:
|
||||
- 4 Tile Layers
|
||||
- 1 HUD Layer
|
||||
- Cada layer aponta para **um único bank**
|
||||
- Sprites podem usar **qualquer bank**
|
||||
- Each layer points to **a single bank**
|
||||
- Sprites can use **any bank**
|
||||
- HUD:
|
||||
- não scrolla
|
||||
- prioridade máxima
|
||||
- geralmente usa tiles 8×8
|
||||
- does not scroll
|
||||
- maximum priority
|
||||
- generally uses 8×8 tiles
|
||||
|
||||
---
|
||||
|
||||
## 5. Modelo Interno de uma Tile Layer
|
||||
## 5. Internal Model of a Tile Layer
|
||||
|
||||
Uma Tile Layer **não é um bitmap de pixels**.
|
||||
Ela é composta por:
|
||||
A Tile Layer **is not a bitmap of pixels**.
|
||||
It is composed of:
|
||||
|
||||
- Um **Tilemap lógico** (índices de tiles)
|
||||
- Um **Cache de Borda** (janela de tiles visíveis)
|
||||
- Um **Offset de Scroll**
|
||||
- A **logical Tilemap** (tile indices)
|
||||
- A **Border Cache** (window of visible tiles)
|
||||
- A **Scroll Offset**
|
||||
|
||||
### Estrutura:
|
||||
### Structure:
|
||||
|
||||
- `bank_id`
|
||||
- `tile_size`
|
||||
- `tilemap` (matriz grande)
|
||||
- `tilemap` (large matrix)
|
||||
- `scroll_x`, `scroll_y`
|
||||
- `cache_origin_x`, `cache_origin_y`
|
||||
- `cache_tiles[w][h]`
|
||||
|
||||
---
|
||||
|
||||
## 6. Tilemap Lógico
|
||||
## 6. Logical Tilemap
|
||||
|
||||
O tilemap representa o mundo:
|
||||
The tilemap represents the world:
|
||||
|
||||
Cada célula contém:
|
||||
Each cell contains:
|
||||
|
||||
- `tile_id`
|
||||
- `flip_x`
|
||||
- `flip_y`
|
||||
- `priority` (opcional)
|
||||
- `palette_id` (opcional)
|
||||
- `priority` (optional)
|
||||
- `palette_id` (optional)
|
||||
|
||||
O tilemap pode ser muito maior que a tela.
|
||||
The tilemap can be much larger than the screen.
|
||||
|
||||
---
|
||||
|
||||
## 7. Cache de Borda (Tile Cache)
|
||||
## 7. Border Cache (Tile Cache)
|
||||
|
||||
O cache é uma janela de tiles ao redor da câmera.
|
||||
The cache is a window of tiles around the camera.
|
||||
|
||||
Exemplo:
|
||||
Example:
|
||||
|
||||
- Tela: 320×180
|
||||
- Tiles 16×16 → 20×12 visíveis
|
||||
- Cache: 22×14 (margem de 1 tile)
|
||||
- Screen: 320×180
|
||||
- 16×16 tiles → 20×12 visible
|
||||
- Cache: 22×14 (1-tile margin)
|
||||
|
||||
Ele guarda os tiles já resolvidos a partir do tilemap.
|
||||
It stores tiles already resolved from the tilemap.
|
||||
|
||||
---
|
||||
|
||||
## 8. Atualização do Cache
|
||||
## 8. Cache Update
|
||||
|
||||
A cada frame:
|
||||
Every frame:
|
||||
|
||||
1. Calcular:
|
||||
1. Calculate:
|
||||
- `tile_x = scroll_x / tile_size`
|
||||
- `tile_y = scroll_y / tile_size`
|
||||
- `offset_x = scroll_x % tile_size`
|
||||
- `offset_y = scroll_y % tile_size`
|
||||
|
||||
2. Se `tile_x` mudou:
|
||||
- Avança `cache_origin_x`
|
||||
- Recarrega apenas a nova coluna
|
||||
2. If `tile_x` changed:
|
||||
- Advance `cache_origin_x`
|
||||
- Reload only the new column
|
||||
|
||||
3. Se `tile_y` mudou:
|
||||
- Avança `cache_origin_y`
|
||||
- Recarrega apenas a nova linha
|
||||
3. If `tile_y` changed:
|
||||
- Advance `cache_origin_y`
|
||||
- Reload only the new line
|
||||
|
||||
Somente **uma linha e/ou coluna** é atualizada por frame.
|
||||
Only **one row and/or column** is updated per frame.
|
||||
|
||||
---
|
||||
|
||||
## 9. Cache como Ring Buffer
|
||||
## 9. Cache as Ring Buffer
|
||||
|
||||
O cache é circular:
|
||||
The cache is circular:
|
||||
|
||||
- Não move dados fisicamente
|
||||
- Apenas move índices lógicos
|
||||
- Does not physically move data
|
||||
- Only moves logical indices
|
||||
|
||||
Acesso:
|
||||
Access:
|
||||
- `real_x = (cache_origin_x + logical_x) % cache_width`
|
||||
- `real_y = (cache_origin_y + logical_y) % cache_height`
|
||||
|
||||
---
|
||||
|
||||
## 10. Projeção para o Back Buffer
|
||||
## 10. Projection to the Back Buffer
|
||||
|
||||
Para cada frame:
|
||||
For each frame:
|
||||
|
||||
1. Para cada Tile Layer, em ordem:
|
||||
- Rasterizar tiles visíveis do cache
|
||||
- Aplicar scroll, flip e transparência
|
||||
- Escrever no back buffer
|
||||
1. For each Tile Layer, in order:
|
||||
- Rasterize visible tiles from the cache
|
||||
- Apply scroll, flip, and transparency
|
||||
- Write to the back buffer
|
||||
|
||||
2. Desenhar sprites:
|
||||
- Com prioridade entre layers
|
||||
- Ordem de desenho define profundidade
|
||||
2. Draw sprites:
|
||||
- With priority between layers
|
||||
- Drawing order defines depth
|
||||
|
||||
3. Desenhar HUD layer por último
|
||||
3. Draw HUD layer last
|
||||
|
||||
---
|
||||
|
||||
## 11. Ordem de Desenho e Prioridade
|
||||
## 11. Drawing Order and Priority
|
||||
|
||||
- Não existe Z-buffer
|
||||
- Não existe sorting automático
|
||||
- Quem desenha depois fica na frente
|
||||
- There is no Z-buffer
|
||||
- There is no automatic sorting
|
||||
- Whoever draws later is in front
|
||||
|
||||
Ordem base:
|
||||
Base order:
|
||||
|
||||
1. Tile Layer 0
|
||||
2. Tile Layer 1
|
||||
3. Tile Layer 2
|
||||
4. Tile Layer 3
|
||||
5. Sprites (por prioridade entre layers)
|
||||
5. Sprites (by priority between layers)
|
||||
6. HUD Layer
|
||||
|
||||
---
|
||||
|
||||
## 12. Transparência (Color Key)
|
||||
## 12. Transparency (Color Key)
|
||||
|
||||
- Um valor RGB565 é reservado como TRANSPARENT_KEY
|
||||
- Pixels com essa cor não são desenhados
|
||||
- One RGB565 value is reserved as TRANSPARENT_KEY
|
||||
- Pixels with this color are not drawn
|
||||
|
||||
```
|
||||
if src == TRANSPARENT_KEY:
|
||||
@ -235,11 +235,11 @@ else:
|
||||
|
||||
---
|
||||
|
||||
## 13. Color Math (Blending Discreto)
|
||||
## 13. Color Math (Discrete Blending)
|
||||
|
||||
Inspirado no SNES.
|
||||
Inspired by the SNES.
|
||||
|
||||
Modos oficiais:
|
||||
Official modes:
|
||||
|
||||
- `BLEND_NONE`
|
||||
- `BLEND_HALF`
|
||||
@ -247,99 +247,99 @@ Modos oficiais:
|
||||
- `BLEND_HALF_MINUS`
|
||||
- `BLEND_FULL`
|
||||
|
||||
Sem alpha contínuo.
|
||||
Sem blending arbitrário.
|
||||
No continuous alpha.
|
||||
No arbitrary blending.
|
||||
|
||||
Tudo é:
|
||||
Everything is:
|
||||
|
||||
- inteiro
|
||||
- barato
|
||||
- determinístico
|
||||
- integer
|
||||
- cheap
|
||||
- deterministic
|
||||
|
||||
---
|
||||
|
||||
## 14. Onde o Blend é Aplicado
|
||||
## 14. Where Blend is Applied
|
||||
|
||||
- O blend ocorre durante o desenho
|
||||
- O resultado vai direto para o back buffer
|
||||
- Não existe composição posterior automática
|
||||
- Blending occurs during drawing
|
||||
- The result goes directly to the back buffer
|
||||
- There is no automatic post-composition
|
||||
|
||||
---
|
||||
|
||||
## 15. O que o GFX NÃO suporta
|
||||
## 15. What the GFX DOES NOT support
|
||||
|
||||
Por design:
|
||||
By design:
|
||||
|
||||
- Alpha contínuo
|
||||
- Continuous alpha
|
||||
- RGBA framebuffer
|
||||
- Shader
|
||||
- Pipeline moderno de GPU
|
||||
- Shaders
|
||||
- Modern GPU pipeline
|
||||
- HDR
|
||||
- Gamma correction
|
||||
|
||||
---
|
||||
|
||||
## 16. Regra de Performance
|
||||
## 16. Performance Rule
|
||||
|
||||
- Layers:
|
||||
- só atualizam borda ao cruzar tile
|
||||
- nunca redesenham mundo inteiro
|
||||
- Rasterização:
|
||||
- sempre por frame, só área visível
|
||||
- only update the border when crossing a tile
|
||||
- never redraw the entire world
|
||||
- Rasterization:
|
||||
- always per frame, only the visible area
|
||||
- Sprites:
|
||||
- sempre redesenhados por frame
|
||||
- always redrawn per frame
|
||||
|
||||
---
|
||||
|
||||
## 17. PostFX Especial — Fade (Scene e HUD)
|
||||
## 17. Special PostFX — Fade (Scene and HUD)
|
||||
|
||||
O PROMETEU suporta **fade gradual** como um PostFX especial, com dois controles
|
||||
independentes:
|
||||
PROMETEU supports **gradual fade** as a special PostFX, with two independent
|
||||
controls:
|
||||
|
||||
- **Scene Fade**: afeta toda a cena (Tile Layers 0–3 + Sprites)
|
||||
- **HUD Fade**: afeta apenas o HUD Layer (sempre composto por último)
|
||||
- **Scene Fade**: affects the entire scene (Tile Layers 0–3 + Sprites)
|
||||
- **HUD Fade**: affects only the HUD Layer (always composed last)
|
||||
|
||||
O fade é implementado sem alpha contínuo por pixel e sem floats.
|
||||
Ele usa um **nível inteiro discreto** (0..31), que na prática produz um resultado
|
||||
visual “quase contínuo” em 320×180 pixel art.
|
||||
The fade is implemented without continuous per-pixel alpha and without floats.
|
||||
It uses a **discrete integer level** (0..31), which in practice produces an
|
||||
"almost continuous" visual result in 320×180 pixel art.
|
||||
|
||||
---
|
||||
|
||||
### 17.1 Representação do Fade
|
||||
### 17.1 Fade Representation
|
||||
|
||||
Cada fade é representado por:
|
||||
Each fade is represented by:
|
||||
|
||||
- `fade_level: u8` no intervalo **[0..31]**
|
||||
- `0` → totalmente substituído pela cor de fade
|
||||
- `31` → totalmente visível (sem fade)
|
||||
- `fade_level: u8` in the range **[0..31]**
|
||||
- `0` → fully replaced by the fade color
|
||||
- `31` → fully visible (no fade)
|
||||
- `fade_color: RGB565`
|
||||
- cor para a qual a imagem será misturada
|
||||
- color the image will be blended into
|
||||
|
||||
Registradores:
|
||||
Registers:
|
||||
|
||||
- `SCENE_FADE_LEVEL` (0..31)
|
||||
- `SCENE_FADE_COLOR` (RGB565)
|
||||
- `HUD_FADE_LEVEL` (0..31)
|
||||
- `HUD_FADE_COLOR` (RGB565)
|
||||
|
||||
Casos comuns:
|
||||
Common cases:
|
||||
|
||||
- Fade-out: `fade_color = BLACK`
|
||||
- Flash/teleporte: `fade_color = WHITE`
|
||||
- Efeitos especiais: qualquer cor RGB565
|
||||
- Flash/teleport: `fade_color = WHITE`
|
||||
- Special effects: any RGB565 color
|
||||
|
||||
---
|
||||
|
||||
### 17.2 Operação de Fade (Mistura com Cor Arbitrária)
|
||||
### 17.2 Fade Operation (Blending with Arbitrary Color)
|
||||
|
||||
Para cada pixel RGB565 `src` e cor de fade `fc`, o pixel final `dst` é calculado por canal.
|
||||
For each RGB565 pixel `src` and fade color `fc`, the final pixel `dst` is calculated per channel.
|
||||
|
||||
1) Extrair componentes:
|
||||
1) Extract components:
|
||||
|
||||
- `src_r5`, `src_g6`, `src_b5`
|
||||
- `fc_r5`, `fc_g6`, `fc_b5`
|
||||
|
||||
2) Aplicar mistura inteira:
|
||||
2) Apply integer blending:
|
||||
|
||||
```
|
||||
src_weight = fade_level // 0..31
|
||||
@ -352,127 +352,127 @@ b5 = (src_b5 * src_weight + fc_b5 * fc_weight) / 31
|
||||
- `src_r5`, `src_g6`, `src_b5`
|
||||
- `fc_r5`, `fc_g6`, `fc_b5`
|
||||
|
||||
3) Reempacotar:
|
||||
3) Repack:
|
||||
|
||||
```
|
||||
dst = pack_rgb565(r5, g6, b5)
|
||||
```
|
||||
|
||||
|
||||
Observações:
|
||||
Notes:
|
||||
|
||||
- Operação determinística
|
||||
- Somente inteiros
|
||||
- Pode ser otimizada via LUT
|
||||
- Deterministic operation
|
||||
- Integers only
|
||||
- Can be optimized via LUT
|
||||
|
||||
---
|
||||
|
||||
### 17.3 Ordem de Aplicação no Frame
|
||||
### 17.3 Order of Application in the Frame
|
||||
|
||||
A composição do frame segue esta ordem:
|
||||
The frame composition follows this order:
|
||||
|
||||
1. Rasterizar **Tile Layers 0–3** → Back Buffer
|
||||
2. Rasterizar **Sprites** conforme prioridade
|
||||
3. (Opcional) Pipeline extra (Emission/Light/Glow etc.)
|
||||
4. Aplicar **Scene Fade** usando:
|
||||
1. Rasterize **Tile Layers 0–3** → Back Buffer
|
||||
2. Rasterize **Sprites** according to priority
|
||||
3. (Optional) Extra pipeline (Emission/Light/Glow etc.)
|
||||
4. Apply **Scene Fade** using:
|
||||
- `SCENE_FADE_LEVEL`
|
||||
- `SCENE_FADE_COLOR`
|
||||
5. Rasterizar **HUD Layer**
|
||||
6. Aplicar **HUD Fade** usando:
|
||||
5. Rasterize **HUD Layer**
|
||||
6. Apply **HUD Fade** using:
|
||||
- `HUD_FADE_LEVEL`
|
||||
- `HUD_FADE_COLOR`
|
||||
7. `present()`
|
||||
|
||||
Regras:
|
||||
Rules:
|
||||
|
||||
- Scene Fade nunca afeta HUD
|
||||
- HUD Fade nunca afeta a cena
|
||||
- Scene Fade never affects the HUD
|
||||
- HUD Fade never affects the scene
|
||||
|
||||
---
|
||||
|
||||
### 17.4 Casos de Uso
|
||||
### 17.4 Use Cases
|
||||
|
||||
- Troca de HUD:
|
||||
- diminuir `HUD_FADE_LEVEL` até 0
|
||||
- trocar HUD/tilemap
|
||||
- aumentar `HUD_FADE_LEVEL` até 31
|
||||
- HUD Switch:
|
||||
- decrease `HUD_FADE_LEVEL` to 0
|
||||
- switch HUD/tilemap
|
||||
- increase `HUD_FADE_LEVEL` to 31
|
||||
|
||||
- Troca de área:
|
||||
- diminuir `SCENE_FADE_LEVEL` até 0
|
||||
- trocar cenário
|
||||
- aumentar `SCENE_FADE_LEVEL` até 31
|
||||
- Area Switch:
|
||||
- decrease `SCENE_FADE_LEVEL` to 0
|
||||
- switch scenery
|
||||
- increase `SCENE_FADE_LEVEL` to 31
|
||||
|
||||
- Flash / dano / teleporte:
|
||||
- usar `fade_color = WHITE` ou outra cor temática
|
||||
- Flash / damage / teleport:
|
||||
- use `fade_color = WHITE` or another thematic color
|
||||
|
||||
---
|
||||
|
||||
## 18. Sistema de Paletas
|
||||
## 18. Palette System
|
||||
|
||||
### 18.1. Visão Geral
|
||||
### 18.1. Overview
|
||||
|
||||
O PROMETEU utiliza **exclusivamente** gráficos indexados por paleta.
|
||||
PROMETEU uses **exclusively** palette-indexed graphics.
|
||||
|
||||
Não existe modo RGB direto por pixel.
|
||||
Todo pixel gráfico é um **índice** que aponta para uma cor real em uma paleta.
|
||||
There is no direct RGB-per-pixel mode.
|
||||
Every graphical pixel is an **index** pointing to a real color in a palette.
|
||||
|
||||
Objetivos:
|
||||
Objectives:
|
||||
|
||||
- reduzir uso de RAM e storage
|
||||
- permitir troca de cores sem shader
|
||||
- manter identidade retrô
|
||||
- facilitar efeitos como variação, dano, dia/noite
|
||||
- reduce RAM and storage usage
|
||||
- allow color swapping without shaders
|
||||
- maintain retro identity
|
||||
- facilitate effects like variation, damage, day/night
|
||||
|
||||
---
|
||||
|
||||
### 18.2. Formato de Pixel
|
||||
### 18.2. Pixel Format
|
||||
|
||||
Cada pixel de um tile ou sprite é:
|
||||
Each pixel of a tile or sprite is:
|
||||
|
||||
- **4 bits por pixel (4bpp)**
|
||||
- valores: `0..15`
|
||||
- **4 bits per pixel (4bpp)**
|
||||
- values: `0..15`
|
||||
|
||||
Regra fixa:
|
||||
Fixed rule:
|
||||
|
||||
- Índice `0` = TRANSPARENTE
|
||||
- Índices `1..15` = cores válidas da paleta
|
||||
- Index `0` = TRANSPARENT
|
||||
- Indices `1..15` = valid palette colors
|
||||
|
||||
---
|
||||
|
||||
### 18.3. Estrutura de Paletas
|
||||
### 18.3. Palette Structure
|
||||
|
||||
Cada **Tile Bank** contém:
|
||||
Each **Tile Bank** contains:
|
||||
|
||||
- Até **256 paletas**
|
||||
- Cada paleta tem:
|
||||
- **16 cores**
|
||||
- cada cor em **RGB565 (u16)**
|
||||
- Up to **256 palettes**
|
||||
- Each palette has:
|
||||
- **16 colors**
|
||||
- each color in **RGB565 (u16)**
|
||||
|
||||
Tamanho:
|
||||
Size:
|
||||
|
||||
- 1 paleta = 16 × 2 bytes = **32 bytes**
|
||||
- 256 paletas = **8 KB por bank**
|
||||
- 16 banks = **128 KB máximo de paletas**
|
||||
- 1 palette = 16 × 2 bytes = **32 bytes**
|
||||
- 256 palettes = **8 KB per bank**
|
||||
- 16 banks = **128 KB maximum palettes**
|
||||
|
||||
---
|
||||
|
||||
### 18.4. Associação de Paleta
|
||||
### 18.4. Palette Association
|
||||
|
||||
#### Regra Fundamental
|
||||
#### Fundamental Rule
|
||||
|
||||
- Cada **tile** usa **uma única paleta**
|
||||
- Cada **sprite** usa **uma única paleta**
|
||||
- A paleta deve ser informada **explicitamente** em todo draw
|
||||
- Each **tile** uses **a single palette**
|
||||
- Each **sprite** uses **a single palette**
|
||||
- The palette must be provided **explicitly** in every draw
|
||||
|
||||
Não existe troca de paleta dentro do mesmo tile ou sprite.
|
||||
There is no palette swap within the same tile or sprite.
|
||||
|
||||
---
|
||||
|
||||
### 18.5. Onde a Paleta é Definida
|
||||
### 18.5. Where the Palette is Defined
|
||||
|
||||
#### Tilemap
|
||||
|
||||
Cada célula do tilemap contém:
|
||||
Each tilemap cell contains:
|
||||
|
||||
- `tile_id`
|
||||
- `palette_id (u8)`
|
||||
@ -481,7 +481,7 @@ Cada célula do tilemap contém:
|
||||
|
||||
#### Sprite
|
||||
|
||||
Cada sprite draw contém:
|
||||
Each sprite draw contains:
|
||||
|
||||
- `bank_id`
|
||||
- `tile_id`
|
||||
@ -492,20 +492,20 @@ Cada sprite draw contém:
|
||||
|
||||
---
|
||||
|
||||
### 18.6. Resolução de Cor
|
||||
### 18.6. Color Resolution
|
||||
|
||||
O pipeline funciona assim:
|
||||
The pipeline works like this:
|
||||
|
||||
1. Ler pixel indexado do tile (valor 0..15)
|
||||
2. Se índice == 0 → pixel transparente
|
||||
3. Caso contrário:
|
||||
- cor_real = paleta[palette_id][indice]
|
||||
4. Aplicar:
|
||||
1. Read indexed pixel from tile (value 0..15)
|
||||
2. If index == 0 → transparent pixel
|
||||
3. Otherwise:
|
||||
- real_color = palette[palette_id][index]
|
||||
4. Apply:
|
||||
- flip
|
||||
- blend discreto
|
||||
- escrita no back buffer
|
||||
- discrete blend
|
||||
- writing to back buffer
|
||||
|
||||
Ou seja:
|
||||
In other words:
|
||||
```
|
||||
pixel_index = tile_pixel(x,y)
|
||||
if pixel_index == 0:
|
||||
@ -517,84 +517,84 @@ else:
|
||||
|
||||
---
|
||||
|
||||
### 18.7. Organização dos Tile Banks
|
||||
### 18.7. Organization of Tile Banks
|
||||
|
||||
Os Tile Banks são “assets fortes”:
|
||||
Tile Banks are "strong assets":
|
||||
|
||||
- Tiles e paletas vivem juntos
|
||||
- Exportação/importação sempre leva:
|
||||
- tiles + paletas
|
||||
- O hardware não impõe organização semântica:
|
||||
- o agrupamento é decisão do criador
|
||||
- Tooling e scripts podem criar convenções:
|
||||
- ex.: paletas 0..15 = inimigos
|
||||
- 16..31 = cenário
|
||||
- Tiles and palettes live together
|
||||
- Export/import always carries:
|
||||
- tiles + palettes
|
||||
- The hardware does not impose semantic organization:
|
||||
- grouping is the creator's decision
|
||||
- Tooling and scripts can create conventions:
|
||||
- e.g.: palettes 0..15 = enemies
|
||||
- 16..31 = scenery
|
||||
- etc.
|
||||
|
||||
---
|
||||
|
||||
### 18.8. Efeitos Possíveis com Paletas
|
||||
### 18.8. Possible Effects with Palettes
|
||||
|
||||
Sem shader, é possível:
|
||||
Without shaders, it is possible to:
|
||||
|
||||
- Palette swap:
|
||||
- inimigos com variação de cor
|
||||
- Estados:
|
||||
- dano, gelo, veneno, power-up
|
||||
- Dia / noite:
|
||||
- trocar paletas globalmente
|
||||
- Biomas:
|
||||
- mesma arte, clima diferente
|
||||
- UI themes
|
||||
- enemies with color variation
|
||||
- States:
|
||||
- damage, ice, poison, power-up
|
||||
- Day / night:
|
||||
- swap palettes globally
|
||||
- Biomes:
|
||||
- same art, different climate
|
||||
- UI themes
|
||||
|
||||
Tudo isso sem mudar os tiles.
|
||||
All this without changing tiles.
|
||||
|
||||
---
|
||||
|
||||
### 18.9. Limitações Artísticas
|
||||
### 18.9. Artistic Limitations
|
||||
|
||||
- Cada tile/sprite:
|
||||
- Each tile/sprite:
|
||||
|
||||
- máximo de 16 cores
|
||||
- maximum of 16 colors
|
||||
|
||||
- Gradientes suaves exigem:
|
||||
- Smooth gradients require:
|
||||
|
||||
- dithering
|
||||
- blend discreto
|
||||
- discrete blend
|
||||
- glow/emission
|
||||
|
||||
Essa limitação é intencional e faz parte da identidade do PROMETEU.
|
||||
This limitation is intentional and part of the PROMETEU identity.
|
||||
|
||||
---
|
||||
|
||||
### 18.10. Métricas para Certificação (CAP)
|
||||
### 18.10. Metrics for Certification (CAP)
|
||||
|
||||
O sistema pode medir:
|
||||
The system can measure:
|
||||
|
||||
- `palettes_loaded_total`
|
||||
- `palettes_referenced_this_frame`
|
||||
- `tiles_drawn_by_palette_id`
|
||||
- `sprites_drawn_by_palette_id`
|
||||
|
||||
Isso permite:
|
||||
This allows:
|
||||
|
||||
- analisar custo artístico
|
||||
- ensinar impacto de variedade excessiva
|
||||
- sugerir boas práticas de coesão visual
|
||||
- analyzing artistic cost
|
||||
- teaching the impact of excessive variety
|
||||
- suggesting best practices for visual cohesion
|
||||
|
||||
---
|
||||
|
||||
## 19. Resumo
|
||||
## 19. Summary
|
||||
|
||||
O GFX do PROMETEU é simples **por escolha**, não por limitação.
|
||||
PROMETEU's GFX is simple **by choice**, not by limitation.
|
||||
|
||||
- Framebuffer RGB565 com double buffer
|
||||
- Color key para transparência
|
||||
- Blending discreto estilo SNES
|
||||
- Até 16 tile banks
|
||||
- RGB565 Framebuffer with double buffer
|
||||
- Color key for transparency
|
||||
- SNES-style discrete blending
|
||||
- Up to 16 tile banks
|
||||
- 4 Tile Layers + 1 HUD
|
||||
- Layer = tilemap + cache + scroll
|
||||
- Projeção rasterizada por frame
|
||||
- Profundidade definida por ordem de desenho
|
||||
- Rasterized projection per frame
|
||||
- Depth defined by drawing order
|
||||
|
||||
< [Voltar](chapter-3.md) | [Sumário](table-of-contents.md) | [Adiante](chapter-5.md) >
|
||||
< [Back](chapter-3.md) | [Summary](table-of-contents.md) | [Next](chapter-5.md) >
|
||||
@ -1,255 +1,255 @@
|
||||
< [Voltar](chapter-4.md) | [Sumário](table-of-contents.md) | [Adiante](chapter-6.md) >
|
||||
< [Back](chapter-4.md) | [Summary](table-of-contents.md) | [Next](chapter-6.md) >
|
||||
|
||||
# 🔊 Periférico AUDIO (Sistema de Som)
|
||||
# 🔊 AUDIO Peripheral (Audio System)
|
||||
|
||||
## 1. Visão Geral
|
||||
## 1. Overview
|
||||
|
||||
O **Periférico AUDIO** é responsável pela **geração e mistura de som** no PROMETEU.
|
||||
The **AUDIO Peripheral** is responsible for **sound generation and mixing** in PROMETEU.
|
||||
|
||||
Assim como os demais subsistemas:
|
||||
Just like the other subsystems:
|
||||
|
||||
- não é automático
|
||||
- não é gratuito
|
||||
- não é mágico
|
||||
- it is not automatic
|
||||
- it is not free
|
||||
- it is not magic
|
||||
|
||||
Cada som é resultado de **comandos explícitos**, executados sob **orçamento de tempo e recursos**.
|
||||
Each sound is the result of **explicit commands**, executed under a **time and resource budget**.
|
||||
|
||||
> Som consome tempo.
|
||||
> Som consome memória.
|
||||
> Sound consumes time.
|
||||
> Sound consumes memory.
|
||||
|
||||
---
|
||||
|
||||
## 2. Filosofia
|
||||
## 2. Philosophy
|
||||
|
||||
PROMETEU trata áudio como:
|
||||
PROMETEU treats audio as:
|
||||
|
||||
- um **periférico ativo**
|
||||
- com **canais limitados**
|
||||
- comportamento **determinístico**
|
||||
- controle **explícito**
|
||||
- an **active peripheral**
|
||||
- with **limited channels**
|
||||
- **deterministic** behavior
|
||||
- **explicit** control
|
||||
|
||||
Objetivo: clareza arquitetural e didática, não realismo absoluto.
|
||||
Objective: architectural and didactic clarity, not absolute realism.
|
||||
|
||||
---
|
||||
|
||||
## 3. Arquitetura Geral
|
||||
## 3. General Architecture
|
||||
|
||||
O sistema de áudio é composto por:
|
||||
The audio system is composed of:
|
||||
|
||||
- **Voices (canais)** — tocadores independentes
|
||||
- **Samples** — dados PCM
|
||||
- **Mixer** — soma das voices
|
||||
- **Saída** — buffer estéreo PCM
|
||||
- **Voices (channels)** — independent players
|
||||
- **Samples** — PCM data
|
||||
- **Mixer** — summation of voices
|
||||
- **Output** — PCM stereo buffer
|
||||
|
||||
Separação conceitual:
|
||||
Conceptual separation:
|
||||
|
||||
- Jogo envia **comandos a 60Hz**
|
||||
- Áudio é **gerado continuamente** em 48kHz
|
||||
- Game sends **commands at 60Hz**
|
||||
- Audio is **generated continuously** at 48kHz
|
||||
|
||||
---
|
||||
|
||||
## 4. Formato de Saída
|
||||
## 4. Output Format
|
||||
|
||||
- Sample rate: **48.000 Hz**
|
||||
- Formato: **PCM16 estéreo (signed i16)**
|
||||
- Clipping: saturação/clamp
|
||||
- Sample rate: **48,000 Hz**
|
||||
- Format: **PCM16 stereo (signed i16)**
|
||||
- Clipping: saturation/clamp
|
||||
|
||||
Esse formato é compatível com:
|
||||
This format is compatible with:
|
||||
|
||||
- DACs I2S comuns
|
||||
- HDMI áudio
|
||||
- USB áudio
|
||||
- SBCs DIY (Raspberry Pi, Orange Pi, etc.)
|
||||
- common I2S DACs
|
||||
- HDMI audio
|
||||
- USB audio
|
||||
- DIY SBCs (Raspberry Pi, Orange Pi, etc.)
|
||||
|
||||
---
|
||||
|
||||
## 5. Voices (Canais)
|
||||
## 5. Voices (Channels)
|
||||
|
||||
### 5.1 Quantidade
|
||||
### 5.1 Quantity
|
||||
|
||||
```
|
||||
MAX_VOICES = 16
|
||||
```
|
||||
|
||||
Cada voice:
|
||||
Each voice:
|
||||
|
||||
- toca **1 sample por vez**
|
||||
- é independente
|
||||
- é misturada no output final
|
||||
- plays **1 sample at a time**
|
||||
- is independent
|
||||
- is mixed into the final output
|
||||
|
||||
---
|
||||
|
||||
### 5.2 Estado de uma Voice
|
||||
### 5.2 Voice State
|
||||
|
||||
Cada voice mantém:
|
||||
Each voice maintains:
|
||||
|
||||
- `sample_id`
|
||||
- `pos` (posição fracionária no sample)
|
||||
- `pos` (fractional position in the sample)
|
||||
- `rate` (pitch)
|
||||
- `volume` (0..255)
|
||||
- `pan` (0..255, esquerda→direita)
|
||||
- `pan` (0..255, left→right)
|
||||
- `loop_mode` (off / on)
|
||||
- `loop_start`, `loop_end`
|
||||
- `priority` (opcional)
|
||||
- `priority` (optional)
|
||||
|
||||
---
|
||||
|
||||
### 5.3 Conflito de Voices
|
||||
### 5.3 Voice Conflict
|
||||
|
||||
Se todas as voices estiverem ocupadas:
|
||||
If all voices are occupied:
|
||||
|
||||
- aplica-se uma política explícita:
|
||||
- an explicit policy is applied:
|
||||
- `STEAL_OLDEST`
|
||||
- `STEAL_QUIETEST`
|
||||
- `STEAL_LOWEST_PRIORITY`
|
||||
|
||||
|
||||
PROMETEU não resolve isso automaticamente sem regra definida.
|
||||
PROMETEU does not resolve this automatically without a defined rule.
|
||||
|
||||
---
|
||||
|
||||
## 6. Modelo Conceitual: “CPU de Áudio”
|
||||
## 6. Conceptual Model: “Audio CPU”
|
||||
|
||||
O AUDIO do PROMETEU é concebido como um **periférico independente**, assim como consoles clássicos tinham:
|
||||
The PROMETEU AUDIO is conceived as an **independent peripheral**, just as classic consoles had:
|
||||
|
||||
- CPU principal do jogo
|
||||
- CPU dedicada ao som
|
||||
- Main game CPU
|
||||
- Dedicated sound CPU
|
||||
|
||||
No PROMETEU:
|
||||
In PROMETEU:
|
||||
|
||||
- O **core lógico** assume essa separação conceitual
|
||||
- O **host decide** como implementar:
|
||||
- mesma thread
|
||||
- thread separada
|
||||
- core separado
|
||||
- The **logical core** assumes this conceptual separation
|
||||
- The **host decides** how to implement it:
|
||||
- same thread
|
||||
- separate thread
|
||||
- separate core
|
||||
|
||||
### 6.1 Metáfora de Hardware
|
||||
### 6.1 Hardware Metaphor
|
||||
|
||||
Conceitualmente:
|
||||
Conceptually:
|
||||
|
||||
```
|
||||
[CPU do Jogo] → envia comandos 60Hz → [Periférico AUDIO]
|
||||
[Game CPU] → sends 60Hz commands → [AUDIO Peripheral]
|
||||
|
|
||||
v
|
||||
Voices + Mixer
|
||||
|
|
||||
v
|
||||
Saída PCM
|
||||
PCM Output
|
||||
```
|
||||
|
||||
|
||||
### 6.2 Implementação é Papel do Host
|
||||
### 6.2 Implementation is the Host's Role
|
||||
|
||||
O core:
|
||||
The core:
|
||||
|
||||
- define o **modelo**
|
||||
- define os **comandos**
|
||||
- define os **limites**
|
||||
- defines the **model**
|
||||
- defines the **commands**
|
||||
- defines the **limits**
|
||||
|
||||
O host:
|
||||
The host:
|
||||
|
||||
- escolhe:
|
||||
- chooses:
|
||||
- threads
|
||||
- afinidade de CPU
|
||||
- backend de áudio
|
||||
- garante entrega contínua dos buffers
|
||||
- CPU affinity
|
||||
- audio backend
|
||||
- guarantees continuous delivery of buffers
|
||||
|
||||
Assim:
|
||||
Thus:
|
||||
|
||||
> PROMETEU modela o hardware.
|
||||
> O host decide como realizá-lo fisicamente.
|
||||
> PROMETEU models the hardware.
|
||||
> The host decides how to physically realize it.
|
||||
|
||||
---
|
||||
|
||||
## 7. Samples
|
||||
|
||||
### 7.1 Formato
|
||||
### 7.1 Format
|
||||
|
||||
Samples do PROMETEU:
|
||||
PROMETEU samples:
|
||||
|
||||
- **PCM16 mono**
|
||||
- sample_rate próprio (ex.: 22050, 44100, 48000)
|
||||
- dados imutáveis em runtime
|
||||
- own sample_rate (e.g., 22050, 44100, 48000)
|
||||
- immutable data at runtime
|
||||
|
||||
Campos:
|
||||
Fields:
|
||||
|
||||
- `sample_rate`
|
||||
- `frames_len`
|
||||
- `loop_start`, `loop_end` (opcional)
|
||||
- `loop_start`, `loop_end` (optional)
|
||||
|
||||
---
|
||||
|
||||
### 7.2 Uso
|
||||
### 7.2 Usage
|
||||
|
||||
Exemplo:
|
||||
Example:
|
||||
|
||||
```
|
||||
audio.play(sample_id, voice_id, volume, pan, pitch, priority)
|
||||
```
|
||||
|
||||
Ou:
|
||||
Or:
|
||||
|
||||
```
|
||||
audio.playAuto(sample_id, volume, pan, pitch, priority)
|
||||
```
|
||||
|
||||
(usa política de stealing)
|
||||
(uses stealing policy)
|
||||
|
||||
---
|
||||
|
||||
## 8. Pitch e Interpolação
|
||||
## 8. Pitch and Interpolation
|
||||
|
||||
- `rate = 1.0` → velocidade normal
|
||||
- `rate > 1.0` → mais agudo
|
||||
- `rate < 1.0` → mais grave
|
||||
- `rate = 1.0` → normal speed
|
||||
- `rate > 1.0` → higher pitch
|
||||
- `rate < 1.0` → lower pitch
|
||||
|
||||
Como posição vira fracionária:
|
||||
As position becomes fractional:
|
||||
|
||||
- usa-se **interpolação linear** entre dois samples vizinhos
|
||||
- **linear interpolation** is used between two neighboring samples
|
||||
|
||||
---
|
||||
|
||||
## 9. Mixer
|
||||
|
||||
Para cada frame de saída (48kHz):
|
||||
For each output frame (48kHz):
|
||||
|
||||
1. Para cada voice ativa:
|
||||
- ler sample na posição atual
|
||||
- aplicar pitch
|
||||
- aplicar volume
|
||||
- aplicar pan → gera L/R
|
||||
2. Somar todas as voices
|
||||
3. Aplicar clamp
|
||||
4. Escrever no buffer estéreo
|
||||
1. For each active voice:
|
||||
- read sample at current position
|
||||
- apply pitch
|
||||
- apply volume
|
||||
- apply pan → generates L/R
|
||||
2. Sum all voices
|
||||
3. Apply clamp
|
||||
4. Write to the stereo buffer
|
||||
|
||||
Custo depende de:
|
||||
Cost depends on:
|
||||
|
||||
- número de voices ativas
|
||||
- uso de interpolação
|
||||
- number of active voices
|
||||
- use of interpolation
|
||||
|
||||
---
|
||||
|
||||
## 10. Sincronização com o Jogo
|
||||
## 10. Synchronization with the Game
|
||||
|
||||
- Jogo roda a **60Hz**
|
||||
- Áudio gera dados a **48kHz**
|
||||
- Game runs at **60Hz**
|
||||
- Audio generates data at **48kHz**
|
||||
|
||||
A cada frame (60Hz):
|
||||
Every frame (60Hz):
|
||||
|
||||
- jogo envia comandos:
|
||||
- game sends commands:
|
||||
- play
|
||||
- stop
|
||||
- set_volume
|
||||
- set_pan
|
||||
- set_pitch
|
||||
|
||||
O áudio aplica esses comandos e continua tocando.
|
||||
The audio applies these commands and continues playing.
|
||||
|
||||
---
|
||||
|
||||
## 11. Comandos Básicos
|
||||
## 11. Basic Commands
|
||||
|
||||
Exemplos conceituais:
|
||||
Conceptual examples:
|
||||
|
||||
```
|
||||
audio.play(sample, voice, volume, pan, pitch, priority)
|
||||
@ -263,15 +263,15 @@ audio.isPlaying(voice)
|
||||
|
||||
---
|
||||
|
||||
## 12. Áudio e CAP
|
||||
## 12. Audio and CAP
|
||||
|
||||
O áudio participa do Execution CAP:
|
||||
Audio participates in the Execution CAP:
|
||||
|
||||
- custo de mixagem por frame
|
||||
- custo por voice ativa
|
||||
- custo de comandos
|
||||
- mixing cost per frame
|
||||
- cost per active voice
|
||||
- command cost
|
||||
|
||||
Exemplo:
|
||||
Example:
|
||||
|
||||
```
|
||||
Frame 1024:
|
||||
@ -283,49 +283,49 @@ audio_commands: 6
|
||||
|
||||
---
|
||||
|
||||
## 13. Boas Práticas
|
||||
## 13. Best Practices
|
||||
|
||||
Recomendado:
|
||||
Recommended:
|
||||
|
||||
- reutilizar samples
|
||||
- limitar voices simultâneas
|
||||
- tratar som como evento
|
||||
- separar música e efeitos
|
||||
- reuse samples
|
||||
- limit simultaneous voices
|
||||
- treat sound as an event
|
||||
- separate music and effects
|
||||
|
||||
Evitar:
|
||||
Avoid:
|
||||
|
||||
- tocar som todo frame
|
||||
- abusar de voices
|
||||
- samples gigantes para efeitos simples
|
||||
- playing sound every frame
|
||||
- abusing voices
|
||||
- giant samples for simple effects
|
||||
|
||||
---
|
||||
|
||||
## 14. Inspiração Histórica
|
||||
## 14. Historical Inspiration
|
||||
|
||||
O modelo PROMETEU se inspira em:
|
||||
The PROMETEU model is inspired by:
|
||||
|
||||
- NES: canais fixos
|
||||
- SNES: sample playback + mixagem
|
||||
- CPS2: polifonia confortável
|
||||
- Neo Geo: sample pesado (não copiado integralmente)
|
||||
- NES: fixed channels
|
||||
- SNES: sample playback + mixing
|
||||
- CPS2: comfortable polyphony
|
||||
- Neo Geo: heavy samples (not fully copied)
|
||||
|
||||
Mas abstraído para:
|
||||
But abstracted for:
|
||||
|
||||
- clareza
|
||||
- simplicidade
|
||||
- ensino
|
||||
- clarity
|
||||
- simplicity
|
||||
- teaching
|
||||
|
||||
---
|
||||
|
||||
## 15. Resumo
|
||||
## 15. Summary
|
||||
|
||||
- Output: PCM16 estéreo @ 48kHz
|
||||
- Output: stereo PCM16 @ 48kHz
|
||||
- 16 voices
|
||||
- Samples PCM16 mono
|
||||
- mono PCM16 samples
|
||||
- Volume, pan, pitch
|
||||
- Interpolação linear
|
||||
- Mixer explícito
|
||||
- Conceito de “CPU de áudio”
|
||||
- Implementação é papel do host
|
||||
- Linear interpolation
|
||||
- Explicit mixer
|
||||
- "Audio CPU" concept
|
||||
- Implementation is the host's role
|
||||
|
||||
< [Voltar](chapter-4.md) | [Sumário](table-of-contents.md) | [Adiante](chapter-6.md) >
|
||||
< [Back](chapter-4.md) | [Summary](table-of-contents.md) | [Next](chapter-6.md) >
|
||||
@ -1,94 +1,94 @@
|
||||
< [Voltar](chapter-5.md) | [Sumário](table-of-contents.md) | [Adiante](chapter-7.md) >
|
||||
< [Back](chapter-5.md) | [Summary](table-of-contents.md) | [Next](chapter-7.md) >
|
||||
|
||||
# 🎮 **Periférico INPUT (Sistema de Entrada)**
|
||||
# 🎮 **INPUT Peripheral (Input System)**
|
||||
|
||||
## 1. Visão Geral
|
||||
## 1. Overview
|
||||
|
||||
O **Periférico INPUT** é responsável por **coletar e disponibilizar o estado dos controles** ao programa PROMETEU.
|
||||
The **INPUT Peripheral** is responsible for **collecting and providing the state of controls** to the PROMETEU program.
|
||||
|
||||
Em PROMETEU:
|
||||
In PROMETEU:
|
||||
|
||||
- input é **estado**, não evento implícito
|
||||
- input é **amostrado no tempo**, não entregue assíncronamente
|
||||
- input tem **ordem, custo e momento definidos**
|
||||
- input is **state**, not an implicit event
|
||||
- input is **sampled over time**, not delivered asynchronously
|
||||
- input has a **defined order, cost, and moment**
|
||||
|
||||
> Botões não “disparam eventos”.
|
||||
Eles mudam de estado.
|
||||
> Buttons do not “trigger events”.
|
||||
> They change state.
|
||||
>
|
||||
|
||||
---
|
||||
|
||||
## 2. Filosofia do Sistema de Entrada
|
||||
## 2. Philosophy of the Input System
|
||||
|
||||
PROMETEU modela input como hardware clássico:
|
||||
PROMETEU models input like classic hardware:
|
||||
|
||||
- o estado dos controles é lido **uma vez por frame**
|
||||
- o programa consulta esse estado durante `UPDATE`
|
||||
- não existem callbacks assíncronos de input
|
||||
- the state of controls is read **once per frame**
|
||||
- the program queries this state during `UPDATE`
|
||||
- there are no asynchronous input callbacks
|
||||
|
||||
Esse modelo:
|
||||
This model:
|
||||
|
||||
- é determinístico
|
||||
- é simples de entender
|
||||
- reflete microcontroladores e consoles clássicos
|
||||
- is deterministic
|
||||
- is simple to understand
|
||||
- reflects microcontrollers and classic consoles
|
||||
|
||||
---
|
||||
|
||||
## 3. Dispositivos de Entrada
|
||||
## 3. Input Devices
|
||||
|
||||
PROMETEU abstrai diferentes dispositivos em uma interface comum.
|
||||
PROMETEU abstracts different devices into a common interface.
|
||||
|
||||
Dispositivos típicos:
|
||||
Typical devices:
|
||||
|
||||
- controle digital (D-Pad + botões)
|
||||
- teclado (mapeado para botões)
|
||||
- digital control (D-Pad + botões)
|
||||
- keyboard (mapped to buttons)
|
||||
- gamepad
|
||||
- toque (mobile, mapeado)
|
||||
- touch (mobile, mapped)
|
||||
|
||||
Independentemente da origem, PROMETEU expõe **o mesmo modelo lógico**.
|
||||
Regardless of the origin, PROMETEU exposes **the same logical model**.
|
||||
|
||||
---
|
||||
|
||||
## 4. Modelo de Estado
|
||||
## 4. State Model
|
||||
|
||||
### 4.1 Estado por Frame
|
||||
### 4.1 Per-Frame State
|
||||
|
||||
Para cada frame, o sistema mantém:
|
||||
For each frame, the system maintains:
|
||||
|
||||
- estado atual dos botões
|
||||
- estado do frame anterior
|
||||
- current state of buttons
|
||||
- state from the previous frame
|
||||
|
||||
Isso permite consultar:
|
||||
This allows querying:
|
||||
|
||||
- botão pressionado
|
||||
- botão liberado
|
||||
- botão mantido pressionado
|
||||
- button pressed
|
||||
- button released
|
||||
- button held down
|
||||
|
||||
---
|
||||
|
||||
### 4.2 Tipos de Consulta
|
||||
### 4.2 Query Types
|
||||
|
||||
Operações típicas:
|
||||
Typical operations:
|
||||
|
||||
```
|
||||
input.btn(id)// botão está pressionado
|
||||
input.btnp(id)// botão foi pressionado neste frame
|
||||
input.btnr(id)// botão foi liberado neste frame
|
||||
input.btn(id)// button is pressed
|
||||
input.btnp(id)// button was pressed this frame
|
||||
input.btnr(id)// button was released this frame
|
||||
```
|
||||
|
||||
Essas funções:
|
||||
These functions:
|
||||
|
||||
- são puramente consultivas
|
||||
- não alteram estado
|
||||
- têm custo explícito
|
||||
- are purely advisory
|
||||
- do not change state
|
||||
- have an explicit cost
|
||||
|
||||
---
|
||||
|
||||
## 5. Momento da Amostragem
|
||||
## 5. Sampling Moment
|
||||
|
||||
O estado do input é capturado **no início de cada frame**, antes da fase `UPDATE`.
|
||||
The input state is captured **at the beginning of each frame**, before the `UPDATE` phase.
|
||||
|
||||
Fluxo conceitual:
|
||||
Conceptual flow:
|
||||
|
||||
```
|
||||
FRAME N:
|
||||
@ -99,162 +99,162 @@ AUDIO
|
||||
SYNC
|
||||
```
|
||||
|
||||
Durante todo o frame:
|
||||
Throughout the entire frame:
|
||||
|
||||
- o estado de input é imutável
|
||||
- chamadas repetidas retornam o mesmo valor
|
||||
- the input state is immutable
|
||||
- repeated calls return the same value
|
||||
|
||||
> Input não muda no meio do frame.
|
||||
> Input does not change in the middle of the frame.
|
||||
>
|
||||
|
||||
---
|
||||
|
||||
## 6. Determinismo e Reprodutibilidade
|
||||
## 6. Determinism and Reproducibility
|
||||
|
||||
O modelo de input PROMETEU garante:
|
||||
The PROMETEU input model guarantees:
|
||||
|
||||
- mesma sequência de inputs
|
||||
- mesmos frames
|
||||
- mesmos resultados
|
||||
- same sequence of inputs
|
||||
- same frames
|
||||
- same results
|
||||
|
||||
Isso permite:
|
||||
This allows:
|
||||
|
||||
- reprodução de execuções
|
||||
- replays determinísticos
|
||||
- certificação confiável
|
||||
- execution playback
|
||||
- deterministic replays
|
||||
- reliable certification
|
||||
|
||||
Input pode ser:
|
||||
Input can be:
|
||||
|
||||
- gravado
|
||||
- reproduzido
|
||||
- injetado artificialmente
|
||||
- recorded
|
||||
- played back
|
||||
- artificially injected
|
||||
|
||||
---
|
||||
|
||||
## 7. Input e CAP
|
||||
## 7. Input and CAP
|
||||
|
||||
Operações de input:
|
||||
Input operations:
|
||||
|
||||
- consomem poucos ciclos
|
||||
- participam do orçamento por frame
|
||||
- aparecem em relatórios de certificação
|
||||
- consume few cycles
|
||||
- participate in the per-frame budget
|
||||
- appear in certification reports
|
||||
|
||||
Exemplo:
|
||||
Example:
|
||||
|
||||
```
|
||||
Frame 18231:
|
||||
input.btn():12cycles
|
||||
```
|
||||
|
||||
Embora barato, input **não é gratuito**.
|
||||
Although cheap, input **is not free**.
|
||||
|
||||
---
|
||||
|
||||
## 8. Mapeamento de Botões
|
||||
## 8. Button Mapping
|
||||
|
||||
### 8.1 Identificadores Lógicos
|
||||
### 8.1 Logical Identifiers
|
||||
|
||||
PROMETEU define identificadores lógicos de botões:
|
||||
PROMETEU defines logical button identifiers:
|
||||
|
||||
- `UP`, `DOWN`, `LEFT`, `RIGHT`
|
||||
- `A`, `B`, `X`, `Y`
|
||||
- `START`, `SELECT`
|
||||
|
||||
O mapeamento físico:
|
||||
The physical mapping:
|
||||
|
||||
- depende da plataforma
|
||||
- é resolvido fora da VM
|
||||
- é transparente ao programa
|
||||
- depends on the platform
|
||||
- is resolved outside the VM
|
||||
- is transparent to the program
|
||||
|
||||
---
|
||||
|
||||
### 8.2 Portabilidade
|
||||
### 8.2 Portability
|
||||
|
||||
O mesmo cartucho PROMETEU:
|
||||
The same PROMETEU cartridge:
|
||||
|
||||
- roda em teclado
|
||||
- roda em gamepad
|
||||
- roda em touch
|
||||
- runs on a keyboard
|
||||
- runs on a gamepad
|
||||
- runs on touch
|
||||
|
||||
Sem alteração de código.
|
||||
Without any code changes.
|
||||
|
||||
---
|
||||
|
||||
## 9. Input Analógico (Opcional)
|
||||
## 9. Analog Input (Optional)
|
||||
|
||||
PROMETEU pode expor eixos analógicos de forma explícita:
|
||||
PROMETEU can expose analog axes explicitly:
|
||||
|
||||
```
|
||||
input.axis(id)
|
||||
```
|
||||
|
||||
Características:
|
||||
Characteristics:
|
||||
|
||||
- valor normalizado (ex.: -1.0 a 1.0)
|
||||
- custo explícito
|
||||
- atualização por frame
|
||||
- normalized value (e.g.: -1.0 to 1.0)
|
||||
- explicit cost
|
||||
- per-frame update
|
||||
|
||||
Input analógico:
|
||||
Analog input:
|
||||
|
||||
- não é obrigatório
|
||||
- não substitui input digital
|
||||
- deve ser usado conscientemente
|
||||
- is not mandatory
|
||||
- does not replace digital input
|
||||
- must be used consciously
|
||||
|
||||
---
|
||||
|
||||
## 10. Boas Práticas de Input
|
||||
## 10. Input Best Practices
|
||||
|
||||
PROMETEU incentiva:
|
||||
PROMETEU encourages:
|
||||
|
||||
- tratar input como estado
|
||||
- consultar input apenas em `UPDATE`
|
||||
- separar input de lógica pesada
|
||||
- mapear ações, não teclas
|
||||
- treating input as state
|
||||
- querying input only in `UPDATE`
|
||||
- separating input from heavy logic
|
||||
- mapping actions, not keys
|
||||
|
||||
E desencoraja:
|
||||
And discourages:
|
||||
|
||||
- lógica dependente de polling excessivo
|
||||
- leitura de input em DRAW
|
||||
- acoplamento direto a hardware físico
|
||||
- logic dependent on excessive polling
|
||||
- reading input in DRAW
|
||||
- direct coupling to physical hardware
|
||||
|
||||
---
|
||||
|
||||
## 11. Relação com Consoles Clássicos
|
||||
## 11. Relationship with Classic Consoles
|
||||
|
||||
O modelo PROMETEU reflete:
|
||||
The PROMETEU model reflects:
|
||||
|
||||
- leitura de registradores de input
|
||||
- polling por frame
|
||||
- ausência de eventos assíncronos
|
||||
- reading input registers
|
||||
- per-frame polling
|
||||
- absence of asynchronous events
|
||||
|
||||
Esse modelo:
|
||||
This model:
|
||||
|
||||
- simplifica raciocínio
|
||||
- aumenta previsibilidade
|
||||
- facilita debugging
|
||||
- simplifies reasoning
|
||||
- increases predictability
|
||||
- facilitates debugging
|
||||
|
||||
---
|
||||
|
||||
## 12. Implicações Pedagógicas
|
||||
## 12. Pedagogical Implications
|
||||
|
||||
O Periférico INPUT permite ensinar:
|
||||
The INPUT Peripheral allows teaching:
|
||||
|
||||
- diferença entre evento e estado
|
||||
- amostragem temporal
|
||||
- determinismo em sistemas interativos
|
||||
- sincronização entre input e lógica
|
||||
- the difference between event and state
|
||||
- temporal sampling
|
||||
- determinism in interactive systems
|
||||
- synchronization between input and logic
|
||||
|
||||
Com feedback claro e reproduzível.
|
||||
With clear and reproducible feedback.
|
||||
|
||||
---
|
||||
|
||||
## 13. Resumo
|
||||
## 13. Summary
|
||||
|
||||
- input é estado, não evento
|
||||
- amostrado uma vez por frame
|
||||
- imutável durante o frame
|
||||
- consultas têm custo explícito
|
||||
- input participa do CAP
|
||||
- modelo é determinístico
|
||||
- input is state, not an event
|
||||
- sampled once per frame
|
||||
- immutable during the frame
|
||||
- queries have an explicit cost
|
||||
- input participates in the CAP
|
||||
- model is deterministic
|
||||
|
||||
< [Voltar](chapter-5.md) | [Sumário](table-of-contents.md) | [Adiante](chapter-7.md) >
|
||||
< [Back](chapter-5.md) | [Summary](table-of-contents.md) | [Next](chapter-7.md) >
|
||||
@ -1,72 +1,72 @@
|
||||
< [Voltar](chapter-6.md) | [Sumário](table-of-contents.md) | [Adiante](chapter-8.md) >
|
||||
< [Back](chapter-6.md) | [Summary](table-of-contents.md) | [Next](chapter-8.md) >
|
||||
|
||||
# 🖐️ Periférico TOUCH (Sistema de Entrada via ponteiro absoluto)
|
||||
# 🖐️ TOUCH Peripheral (Absolute Pointer Input System)
|
||||
|
||||
## 1. Visão Geral
|
||||
## 1. Overview
|
||||
|
||||
O periférico **TOUCH** fornece ao PROMETEU um **ponteiro absoluto**, baseado em coordenadas de tela, destinado a:
|
||||
The **TOUCH** peripheral provides PROMETEU with an **absolute pointer**, based on screen coordinates, intended for:
|
||||
|
||||
- interação com UI
|
||||
- seleção direta de elementos
|
||||
- ações contextuais no cenário
|
||||
- mecânicas baseadas em arrasto (drag, slash, trail)
|
||||
- UI interaction
|
||||
- direct element selection
|
||||
- contextual actions in the scenery
|
||||
- drag-based mechanics (drag, slash, trail)
|
||||
|
||||
O TOUCH é um **periférico de primeira classe**, tão válido quanto D-Pad e botões.
|
||||
The TOUCH is a **first-class peripheral**, as valid as D-Pad and buttons.
|
||||
|
||||
---
|
||||
|
||||
## 2. Princípios de Design
|
||||
## 2. Design Principles
|
||||
|
||||
O TOUCH no PROMETEU segue princípios rígidos:
|
||||
TOUCH in PROMETEU follows strict principles:
|
||||
|
||||
- ✅ **Single-touch universal**
|
||||
- ✅ **Determinístico**
|
||||
- ✅ **Estado por frame**
|
||||
- ✅ **Sem gestos**
|
||||
- ✅ **Sem aceleração**
|
||||
- ✅ **Sem heurística**
|
||||
- ✅ **Mesmo comportamento em todas as plataformas**
|
||||
- ✅ **Universal single-touch**
|
||||
- ✅ **Deterministic**
|
||||
- ✅ **Per-frame state**
|
||||
- ✅ **No gestures**
|
||||
- ✅ **No acceleration**
|
||||
- ✅ **No heuristics**
|
||||
- ✅ **Same behavior on all platforms**
|
||||
|
||||
> Se um comportamento não pode ser garantido em todas as plataformas, ele não existe no PROMETEU.
|
||||
> If a behavior cannot be guaranteed on all platforms, it does not exist in PROMETEU.
|
||||
>
|
||||
|
||||
---
|
||||
|
||||
## 3. Modelo Conceitual
|
||||
## 3. Conceptual Model
|
||||
|
||||
O PROMETEU expõe **apenas um ponteiro ativo por vez**, independentemente de quantos toques físicos o hardware reconheça.
|
||||
PROMETEU exposes **only one active pointer at a time**, regardless of how many physical touches the hardware recognizes.
|
||||
|
||||
- Hardware pode detectar multitouch
|
||||
- Runtime seleciona **apenas um toque ativo**
|
||||
- A API **nunca expõe multitouch**
|
||||
- Hardware may detect multitouch
|
||||
- Runtime selects **only one active touch**
|
||||
- The API **never exposes multitouch**
|
||||
|
||||
Esse modelo garante:
|
||||
This model guarantees:
|
||||
|
||||
- portabilidade total
|
||||
- previsibilidade
|
||||
- ausência de ambiguidades
|
||||
- total portability
|
||||
- predictability
|
||||
- absence of ambiguities
|
||||
|
||||
---
|
||||
|
||||
## 4. Espaço de Coordenadas
|
||||
## 4. Coordinate Space
|
||||
|
||||
- As coordenadas do TOUCH usam **o mesmo espaço do framebuffer**
|
||||
- Resolução: **320×180**
|
||||
- Origem: canto superior esquerdo `(0,0)`
|
||||
- Intervalos:
|
||||
- TOUCH coordinates use **the same space as the framebuffer**
|
||||
- Resolution: **320×180**
|
||||
- Origin: top-left corner `(0,0)`
|
||||
- Ranges:
|
||||
- `x ∈ [0, 319]`
|
||||
- `y ∈ [0, 179]`
|
||||
|
||||
O TOUCH é **absoluto**:
|
||||
TOUCH is **absolute**:
|
||||
|
||||
> (x, y) representa a posição exata do contato, sem transformação dinâmica.
|
||||
> (x, y) represents the exact position of contact, without dynamic transformation.
|
||||
>
|
||||
|
||||
---
|
||||
|
||||
## 5. API do Periférico TOUCH
|
||||
## 5. TOUCH Peripheral API
|
||||
|
||||
### 5.1 Estrutura Exposta
|
||||
### 5.1 Exposed Structure
|
||||
|
||||
```
|
||||
TOUCH:
|
||||
@ -81,182 +81,182 @@ TOUCH:
|
||||
|
||||
---
|
||||
|
||||
### 5.2 Semântica dos Campos
|
||||
### 5.2 Field Semantics
|
||||
|
||||
- **present**
|
||||
- `true` se o periférico TOUCH está disponível
|
||||
- `false` se não houver touch físico (desktop, hardware sem touch)
|
||||
- `true` if the TOUCH peripheral is available
|
||||
- `false` if there is no physical touch (desktop, hardware without touch)
|
||||
- **down**
|
||||
- `true` enquanto o ponteiro ativo está pressionado
|
||||
- `true` while the active pointer is pressed
|
||||
- **pressed**
|
||||
- `true` apenas no frame em que o ponteiro ativo foi capturado
|
||||
- `true` only in the frame where the active pointer was captured
|
||||
- **released**
|
||||
- `true` apenas no frame em que o ponteiro ativo foi liberado
|
||||
- `true` only in the frame where the active pointer was released
|
||||
- **x, y**
|
||||
- posição atual do ponteiro ativo
|
||||
- válidas apenas quando `down == true`
|
||||
- current position of the active pointer
|
||||
- valid only when `down == true`
|
||||
|
||||
---
|
||||
|
||||
## 6. Política de Seleção do Ponteiro
|
||||
## 6. Pointer Selection Policy
|
||||
|
||||
### *Single Pointer Capture Policy*
|
||||
|
||||
Quando múltiplos toques físicos ocorrem, o PROMETEU aplica a seguinte política:
|
||||
When multiple physical touches occur, PROMETEU applies the following policy:
|
||||
|
||||
---
|
||||
|
||||
### 6.1 Captura Inicial
|
||||
### 6.1 Initial Capture
|
||||
|
||||
1. Se **nenhum ponteiro está ativo**
|
||||
2. E ocorre um **novo toque físico**
|
||||
3. O **primeiro toque detectado** é capturado
|
||||
4. Esse toque se torna o **ponteiro ativo**
|
||||
1. If **no pointer is active**
|
||||
2. And a **new physical touch** occurs
|
||||
3. The **first detected touch** is captured
|
||||
4. This touch becomes the **active pointer**
|
||||
|
||||
Esse frame gera:
|
||||
This frame generates:
|
||||
|
||||
- `pressed = true`
|
||||
- `down = true`
|
||||
|
||||
---
|
||||
|
||||
### 6.2 Manutenção da Captura
|
||||
### 6.2 Capture Maintenance
|
||||
|
||||
Enquanto o ponteiro ativo estiver pressionado:
|
||||
While the active pointer is pressed:
|
||||
|
||||
- Apenas ele é rastreado
|
||||
- Todos os outros toques físicos são ignorados
|
||||
- `x, y` seguem apenas o ponteiro ativo
|
||||
- Only it is tracked
|
||||
- All other physical touches are ignored
|
||||
- `x, y` follow only the active pointer
|
||||
|
||||
---
|
||||
|
||||
### 6.3 Liberação
|
||||
### 6.3 Release
|
||||
|
||||
Quando o ponteiro ativo é solto:
|
||||
When the active pointer is released:
|
||||
|
||||
- `released = true`
|
||||
- `down = false`
|
||||
- O sistema entra em estado **sem ponteiro ativo**
|
||||
- The system enters a **no active pointer** state
|
||||
|
||||
---
|
||||
|
||||
### 6.4 Recaptura (Regra Importante)
|
||||
### 6.4 Recapture (Important Rule)
|
||||
|
||||
Após a liberação:
|
||||
After release:
|
||||
|
||||
- Toques que **já estavam presentes** são ignorados
|
||||
- Um novo ponteiro só é capturado com um **novo evento de toque**
|
||||
- Touches that **were already present** are ignored
|
||||
- A new pointer is only captured with a **new touch event**
|
||||
|
||||
> Isso evita saltos inesperados do ponteiro e ações acidentais.
|
||||
> This avoids unexpected pointer jumps and accidental actions.
|
||||
>
|
||||
|
||||
---
|
||||
|
||||
## 7. Comportamentos Deliberadamente NÃO Suportados
|
||||
## 7. Deliberately NOT Supported Behaviors
|
||||
|
||||
O periférico TOUCH **não implementa**:
|
||||
The TOUCH peripheral **does not implement**:
|
||||
|
||||
❌ Multitouch
|
||||
|
||||
❌ Gestos (swipe, pinch, rotate, long-press)
|
||||
❌ Gestures (swipe, pinch, rotate, long-press)
|
||||
|
||||
❌ Aceleração ou suavização
|
||||
❌ Acceleration or smoothing
|
||||
|
||||
❌ Sensibilidade dinâmica
|
||||
❌ Dynamic sensitivity
|
||||
|
||||
❌ Histórico implícito
|
||||
❌ Implicit history
|
||||
|
||||
❌ Interpretação de intenção
|
||||
❌ Intent interpretation
|
||||
|
||||
Se um jogo quiser qualquer um desses comportamentos, ele deve:
|
||||
If a game wants any of these behaviors, it must:
|
||||
|
||||
- implementar explicitamente
|
||||
- usando apenas estado por frame
|
||||
- sem suporte implícito do hardware
|
||||
- implement them explicitly
|
||||
- using only per-frame state
|
||||
- without implicit hardware support
|
||||
|
||||
---
|
||||
|
||||
## 8. “Sem Gesto” — Definição Formal
|
||||
## 8. “No Gesture” — Formal Definition
|
||||
|
||||
O PROMETEU **não interpreta padrões temporais**.
|
||||
PROMETEU **does not interpret temporal patterns**.
|
||||
|
||||
O periférico TOUCH **não classifica ações** como:
|
||||
The TOUCH peripheral **does not classify actions** as:
|
||||
|
||||
- swipe
|
||||
- drag
|
||||
- long press
|
||||
- double tap
|
||||
|
||||
Ele apenas informa:
|
||||
It only reports:
|
||||
|
||||
- posição atual
|
||||
- estado do contato
|
||||
- current position
|
||||
- contact state
|
||||
|
||||
Toda semântica é responsabilidade do jogo.
|
||||
All semantics are the game's responsibility.
|
||||
|
||||
---
|
||||
|
||||
## 9. “Sem Aceleração” — Definição Formal
|
||||
## 9. “No Acceleration” — Formal Definition
|
||||
|
||||
O PROMETEU **não modifica** o input do TOUCH.
|
||||
PROMETEU **does not modify** the TOUCH input.
|
||||
|
||||
- Nenhuma curva de sensibilidade
|
||||
- Nenhuma amplificação por velocidade
|
||||
- Nenhuma suavização
|
||||
- No sensitivity curves
|
||||
- No speed-based amplification
|
||||
- No smoothing
|
||||
|
||||
A relação entre o toque físico e `(x, y)` é **1:1** após normalização.
|
||||
The relationship between the physical touch and `(x, y)` is **1:1** after normalization.
|
||||
|
||||
---
|
||||
|
||||
## 10. Integração com Outras Formas de Input
|
||||
## 10. Integration with Other Input Forms
|
||||
|
||||
- Desktop:
|
||||
- mouse pode emular TOUCH
|
||||
- mouse can emulate TOUCH
|
||||
- Mobile:
|
||||
- touch físico direto
|
||||
- direct physical touch
|
||||
- Steam Deck:
|
||||
- touchscreen físico
|
||||
- Hardware PROMETEU:
|
||||
- touch opcional, mas suportado
|
||||
- physical touchscreen
|
||||
- PROMETEU Hardware:
|
||||
- optional touch, but supported
|
||||
|
||||
Do ponto de vista do PROMETEU:
|
||||
From PROMETEU's point of view:
|
||||
|
||||
> TOUCH é sempre TOUCH.
|
||||
> TOUCH is always TOUCH.
|
||||
>
|
||||
|
||||
---
|
||||
|
||||
## 11. Usos Esperados
|
||||
## 11. Expected Uses
|
||||
|
||||
O periférico TOUCH é adequado para:
|
||||
The TOUCH peripheral is suitable for:
|
||||
|
||||
- UI (menus, inventário, mapas)
|
||||
- UI (menus, inventory, maps)
|
||||
- drag-and-drop
|
||||
- seleção direta
|
||||
- “clicar para investigar”
|
||||
- puzzles baseados em apontamento
|
||||
- mecânicas de rastro (ex.: Fruit Ninja-like)
|
||||
- direct selection
|
||||
- “click to investigate”
|
||||
- pointing-based puzzles
|
||||
- trail mechanics (e.g.: Fruit Ninja-like)
|
||||
|
||||
---
|
||||
|
||||
## 12. Garantias de Portabilidade
|
||||
## 12. Portability Guarantees
|
||||
|
||||
Todo jogo PROMETEU que utiliza TOUCH:
|
||||
Every PROMETEU game that uses TOUCH:
|
||||
|
||||
- comporta-se de forma idêntica em todas as plataformas
|
||||
- não depende de capacidades específicas do host
|
||||
- não sofre variação semântica entre desktop, mobile e hardware dedicado
|
||||
- behaves identically on all platforms
|
||||
- does not depend on host-specific capabilities
|
||||
- does not suffer semantic variation between desktop, mobile, and dedicated hardware
|
||||
|
||||
---
|
||||
|
||||
## 13. Resumo
|
||||
## 13. Summary
|
||||
|
||||
O TOUCH no PROMETEU é:
|
||||
The TOUCH in PROMETEU is:
|
||||
|
||||
- simples
|
||||
- explícito
|
||||
- previsível
|
||||
- simple
|
||||
- explicit
|
||||
- predictable
|
||||
- universal
|
||||
- determinístico
|
||||
- deterministic
|
||||
|
||||
< [Voltar](chapter-6.md) | [Sumário](table-of-contents.md) | [Adiante](chapter-8.md) >
|
||||
< [Back](chapter-6.md) | [Summary](table-of-contents.md) | [Next](chapter-8.md) >
|
||||
@ -1,80 +1,80 @@
|
||||
< [Voltar](chapter-7.md) | [Sumário](table-of-contents.md) | [Adiante](chapter-9.md) >
|
||||
< [Back](chapter-7.md) | [Summary](table-of-contents.md) | [Next](chapter-9.md) >
|
||||
|
||||
# 📀 Periférico MEMCARD (Sistema de save/load)
|
||||
# 📀 MEMCARD Peripheral (Save/Load System)
|
||||
|
||||
## 1. Visão Geral
|
||||
## 1. Overview
|
||||
|
||||
O **MEMCARD** é o periférico responsável pela **persistência explícita de dados do jogo** no PROMETEU.
|
||||
The **MEMCARD** is the peripheral responsible for the **explicit persistence of game data** in PROMETEU.
|
||||
|
||||
Ele simula o comportamento de *memory cards* clássicos (PS1, GameCube), fornecendo:
|
||||
It simulates the behavior of classic *memory cards* (PS1, GameCube), providing:
|
||||
|
||||
- armazenamento limitado
|
||||
- custo explícito de I/O
|
||||
- controle total do jogo sobre quando salvar
|
||||
- portabilidade entre plataformas
|
||||
- limited storage
|
||||
- explicit I/O cost
|
||||
- full game control over when to save
|
||||
- portability across platforms
|
||||
|
||||
O MEMCARD **não é um save state**.
|
||||
The MEMCARD **is not a save state**.
|
||||
|
||||
Ele representa **dados que o próprio jogo decide persistir**.
|
||||
It represents **data that the game itself decides to persist**.
|
||||
|
||||
---
|
||||
|
||||
## 2. Princípios de Design
|
||||
## 2. Design Principles
|
||||
|
||||
O periférico MEMCARD segue os seguintes princípios:
|
||||
The MEMCARD peripheral follows these principles:
|
||||
|
||||
- ✅ **Persistência explícita** (nada automático)
|
||||
- ✅ **Tamanho limitado e conhecido**
|
||||
- ✅ **Commit obrigatório**
|
||||
- ✅ **Custo de tempo (ciclos) mensurável**
|
||||
- ✅ **Formato estável e documentado**
|
||||
- ✅ **Independente de plataforma**
|
||||
- ❌ Sem sistema de arquivos complexo (no v0.1)
|
||||
- ❌ Sem múltiplos arquivos internos (no v0.1)
|
||||
- ✅ **Explicit persistence** (nothing automatic)
|
||||
- ✅ **Limited and known size**
|
||||
- ✅ **Mandatory commit**
|
||||
- ✅ **Measurable time cost (cycles)**
|
||||
- ✅ **Stable and documented format**
|
||||
- ✅ **Platform independent**
|
||||
- ❌ No complex file system (in v0.1)
|
||||
- ❌ No multiple internal files (in v0.1)
|
||||
|
||||
---
|
||||
|
||||
## 3. Modelo Conceitual
|
||||
## 3. Conceptual Model
|
||||
|
||||
Cada cartucho PROMETEU pode acessar **um ou mais slots de MEMCARD**, sendo o modelo padrão:
|
||||
Each PROMETEU cartridge can access **one or more MEMCARD slots**, the default model being:
|
||||
|
||||
- **Slot A** — principal
|
||||
- **Slot B** — opcional (futuro)
|
||||
- **Slot A** — main
|
||||
- **Slot B** — optional (future)
|
||||
|
||||
Cada slot corresponde a **um arquivo no host**:
|
||||
Each slot corresponds to **a file on the host**:
|
||||
|
||||
```
|
||||
MyGame_A.mem
|
||||
MyGame_B.mem
|
||||
```
|
||||
|
||||
O runtime monta esse arquivo como um **dispositivo de armazenamento persistente**.
|
||||
The runtime mounts this file as a **persistent storage device**.
|
||||
|
||||
---
|
||||
|
||||
## 4. Capacidade e CAP
|
||||
## 4. Capacity and CAP
|
||||
|
||||
O tamanho do MEMCARD é **fixo**, definido pelo perfil de execução (CAP).
|
||||
The size of the MEMCARD is **fixed**, defined by the execution profile (CAP).
|
||||
|
||||
### Tamanhos sugeridos
|
||||
### Suggested sizes
|
||||
|
||||
| Perfil | Tamanho |
|
||||
| Profile | Size |
|
||||
| --- | --- |
|
||||
| JAM | 8 KB |
|
||||
| STANDARD | 32 KB |
|
||||
| ADVANCED | 128 KB |
|
||||
|
||||
O jogo **não pode exceder** esse tamanho.
|
||||
The game **cannot exceed** this size.
|
||||
|
||||
Tentativas de escrita acima do limite resultam em erro.
|
||||
Attempts to write above the limit result in an error.
|
||||
|
||||
---
|
||||
|
||||
## 5. API do Periférico (v0.1)
|
||||
## 5. Peripheral API (v0.1)
|
||||
|
||||
### 5.1 Interface Lógica
|
||||
### 5.1 Logical Interface
|
||||
|
||||
O MEMCARD expõe uma API **simples de blob único**:
|
||||
The MEMCARD exposes a **simple single-blob API**:
|
||||
|
||||
```
|
||||
mem.read_all() -> byte[]
|
||||
@ -86,92 +86,92 @@ mem.size() -> int
|
||||
|
||||
---
|
||||
|
||||
### 5.2 Semântica das Operações
|
||||
### 5.2 Operation Semantics
|
||||
|
||||
### `read_all()`
|
||||
|
||||
- Retorna todo o conteúdo persistido
|
||||
- Se o cartão estiver vazio, retorna um buffer zerado
|
||||
- Custo em ciclos proporcional ao tamanho
|
||||
- Returns all persisted content
|
||||
- If the card is empty, returns a zeroed buffer
|
||||
- Cycle cost proportional to size
|
||||
|
||||
---
|
||||
|
||||
### `write_all(bytes)`
|
||||
|
||||
- Escreve o buffer **em memória temporária**
|
||||
- Não persiste imediatamente
|
||||
- Falha se `bytes.length > mem.size()`
|
||||
- Writes the buffer **to temporary memory**
|
||||
- Does not persist immediately
|
||||
- Fails if `bytes.length > mem.size()`
|
||||
|
||||
---
|
||||
|
||||
### `commit()`
|
||||
|
||||
- Persiste os dados no dispositivo
|
||||
- Operação **obrigatória**
|
||||
- Simula flush de hardware
|
||||
- Pode falhar (ex.: I/O, corrupção simulada)
|
||||
- Persists data to the device
|
||||
- **Mandatory** operation
|
||||
- Simulates hardware flush
|
||||
- May fail (e.g., I/O, simulated corruption)
|
||||
|
||||
---
|
||||
|
||||
### `clear()`
|
||||
|
||||
- Zera o conteúdo do cartão
|
||||
- Requer `commit()` para persistir
|
||||
- Zeroes the card content
|
||||
- Requires `commit()` to persist
|
||||
|
||||
---
|
||||
|
||||
### `size()`
|
||||
|
||||
- Retorna a capacidade total do cartão em bytes
|
||||
- Returns total card capacity in bytes
|
||||
|
||||
---
|
||||
|
||||
## 6. Commit Explícito (Regra Fundamental)
|
||||
## 6. Explicit Commit (Fundamental Rule)
|
||||
|
||||
O PROMETEU **não salva automaticamente**.
|
||||
PROMETEU **does not save automatically**.
|
||||
|
||||
Sem `commit()`:
|
||||
Without `commit()`:
|
||||
|
||||
- dados permanecem voláteis
|
||||
- podem ser perdidos ao encerrar o jogo
|
||||
- simulam desligamento abrupto de hardware
|
||||
- data remains volatile
|
||||
- can be lost upon exiting the game
|
||||
- simulates abrupt hardware shutdown
|
||||
|
||||
👉 Isso ensina:
|
||||
👉 This teaches:
|
||||
|
||||
- flush de dados
|
||||
- atomicidade
|
||||
- risco de corrupção
|
||||
- custo real de persistência
|
||||
- data flushing
|
||||
- atomicity
|
||||
- risk of corruption
|
||||
- real cost of persistence
|
||||
|
||||
---
|
||||
|
||||
## 7. Custo de Execução (Ciclos)
|
||||
## 7. Execution Cost (Cycles)
|
||||
|
||||
Todas as operações de MEMCARD têm custo explícito.
|
||||
All MEMCARD operations have an explicit cost.
|
||||
|
||||
### Exemplo (valores ilustrativos)
|
||||
### Example (illustrative values)
|
||||
|
||||
| Operação | Custo |
|
||||
| Operation | Cost |
|
||||
| --- | --- |
|
||||
| read_all | 1 ciclo / 256 bytes |
|
||||
| write_all | 1 ciclo / 256 bytes |
|
||||
| commit | custo fixo + proporcional |
|
||||
| read_all | 1 cycle / 256 bytes |
|
||||
| write_all | 1 cycle / 256 bytes |
|
||||
| commit | fixed + proportional cost |
|
||||
|
||||
Esses custos aparecem:
|
||||
These costs appear:
|
||||
|
||||
- no profiler
|
||||
- na timeline de frame
|
||||
- no relatório de CAP
|
||||
- in the profiler
|
||||
- in the frame timeline
|
||||
- in the CAP report
|
||||
|
||||
---
|
||||
|
||||
## 8. Formato do Arquivo `.mem`
|
||||
## 8. `.mem` File Format
|
||||
|
||||
O arquivo de MEMCARD possui um formato simples e robusto.
|
||||
The MEMCARD file has a simple and robust format.
|
||||
|
||||
### 8.1 Header
|
||||
|
||||
| Campo | Tamanho |
|
||||
| Field | Size |
|
||||
| --- | --- |
|
||||
| Magic (`PMEM`) | 4 bytes |
|
||||
| Version | 1 byte |
|
||||
@ -183,56 +183,56 @@ O arquivo de MEMCARD possui um formato simples e robusto.
|
||||
|
||||
### 8.2 Payload
|
||||
|
||||
- Buffer binário definido pelo jogo
|
||||
- Tamanho fixo
|
||||
- Conteúdo interpretado apenas pelo jogo
|
||||
- Binary buffer defined by the game
|
||||
- Fixed size
|
||||
- Content interpreted only by the game
|
||||
|
||||
---
|
||||
|
||||
## 9. Integridade e Segurança
|
||||
## 9. Integrity and Security
|
||||
|
||||
- CRC valida corrupção
|
||||
- Cart ID impede uso de save errado
|
||||
- Versão permite evolução futura do formato
|
||||
- Runtime pode:
|
||||
- avisar corrupção
|
||||
- permitir reset do cartão
|
||||
- CRC validates corruption
|
||||
- Cart ID prevents using wrong save
|
||||
- Version allows future format evolution
|
||||
- Runtime can:
|
||||
- warn of corruption
|
||||
- allow card reset
|
||||
|
||||
---
|
||||
|
||||
## 10. Integração com o Editor / GUI
|
||||
## 10. Integration with the Editor / GUI
|
||||
|
||||
A ferramenta principal pode fornecer um **Memory Card Manager**:
|
||||
The main tool can provide a **Memory Card Manager**:
|
||||
|
||||
- criar/resetar cartão
|
||||
- ver tamanho e uso
|
||||
- importar/exportar `.mem`
|
||||
- visualizar últimos commits
|
||||
- associar cartões a projetos
|
||||
- create/reset card
|
||||
- see size and usage
|
||||
- import/export `.mem`
|
||||
- visualize last commits
|
||||
- associate cards with projects
|
||||
|
||||
Nenhuma dessas operações altera o runtime.
|
||||
None of these operations change the runtime.
|
||||
|
||||
---
|
||||
|
||||
## 11. Evoluções Planejadas (fora do v0.1)
|
||||
## 11. Planned Evolutions (outside v0.1)
|
||||
|
||||
- API de blocos (`read_block`, `write_block`)
|
||||
- múltiplos slots internos
|
||||
- Block API (`read_block`, `write_block`)
|
||||
- multiple internal slots
|
||||
- wear simulation
|
||||
- versionamento de saves
|
||||
- criptografia opcional (educacional)
|
||||
- save versioning
|
||||
- optional encryption (educational)
|
||||
|
||||
---
|
||||
|
||||
## 12. Resumo
|
||||
## 12. Summary
|
||||
|
||||
O periférico MEMCARD no PROMETEU:
|
||||
The MEMCARD peripheral in PROMETEU:
|
||||
|
||||
- simula hardware real
|
||||
- força decisões de design
|
||||
- ensina persistência corretamente
|
||||
- é simples de usar
|
||||
- é difícil de abusar
|
||||
- cresce sem quebrar compatibilidade
|
||||
|
||||
< [Voltar](chapter-7.md) | [Sumário](table-of-contents.md) | [Adiante](chapter-9.md) >
|
||||
- simulates real hardware
|
||||
- forces design decisions
|
||||
- teaches persistence correctly
|
||||
- is simple to use
|
||||
- is hard to abuse
|
||||
- grows without breaking compatibility
|
||||
|
||||
< [Back](chapter-7.md) | [Summary](table-of-contents.md) | [Next](chapter-9.md) >
|
||||
@ -1,175 +1,175 @@
|
||||
< [Voltar](chapter-8.md) | [Sumário](table-of-contents.md) | [Adiante](chapter-10.md) >
|
||||
< [Back](chapter-8.md) | [Summary](table-of-contents.md) | [Next](chapter-10.md) >
|
||||
|
||||
# ⚡ **Eventos e Interrupções**
|
||||
# ⚡ **Events and Interrupts**
|
||||
|
||||
## 1. Visão Geral
|
||||
## 1. Overview
|
||||
|
||||
PROMETEU distingue claramente **execução normal**, **eventos** e **interrupções**.
|
||||
PROMETEU clearly distinguishes between **normal execution**, **events**, and **interrupts**.
|
||||
|
||||
Nada ocorre “fora do tempo”.
|
||||
Nothing occurs "out of time".
|
||||
|
||||
Nada interrompe o sistema sem custo.
|
||||
Nothing interrupts the system without cost.
|
||||
|
||||
Nada acontece sem um ponto bem definido no ciclo de execução.
|
||||
Nothing happens without a well-defined point in the execution cycle.
|
||||
|
||||
> Eventos são sinais.
|
||||
Interrupções são decisões da máquina.
|
||||
> Events are signals.
|
||||
> Interrupts are machine decisions.
|
||||
>
|
||||
|
||||
Este capítulo define:
|
||||
This chapter defines:
|
||||
|
||||
- o que PROMETEU considera um evento
|
||||
- como interrupções são modeladas
|
||||
- quando elas podem ocorrer
|
||||
- como se relacionam com ciclos, CAP e determinismo
|
||||
- what PROMETEU considers an event
|
||||
- how interrupts are modeled
|
||||
- when they can occur
|
||||
- how they relate to cycles, CAP, and determinism
|
||||
|
||||
---
|
||||
|
||||
## 2. Filosofia de Eventos em PROMETEU
|
||||
## 2. Event Philosophy in PROMETEU
|
||||
|
||||
PROMETEU **não utiliza callbacks assíncronos invisíveis**.
|
||||
PROMETEU **does not use invisible asynchronous callbacks**.
|
||||
|
||||
Todo evento:
|
||||
Every event:
|
||||
|
||||
- é registrado
|
||||
- é entregue em momento previsível
|
||||
- é tratado dentro do loop principal
|
||||
- is registered
|
||||
- is delivered at a predictable moment
|
||||
- is handled within the main loop
|
||||
|
||||
Esse modelo evita:
|
||||
This model avoids:
|
||||
|
||||
- concorrência implícita
|
||||
- race conditions ocultas
|
||||
- efeitos colaterais não determinísticos
|
||||
- implicit concurrency
|
||||
- hidden race conditions
|
||||
- non-deterministic side effects
|
||||
|
||||
PROMETEU favorece:
|
||||
PROMETEU favors:
|
||||
|
||||
> controle explícito sobre reatividade.
|
||||
> explicit control over reactivity.
|
||||
>
|
||||
|
||||
---
|
||||
|
||||
## 3. Eventos
|
||||
## 3. Events
|
||||
|
||||
### 3.1 Definição
|
||||
### 3.1 Definition
|
||||
|
||||
Um **evento** em PROMETEU é um **sinal lógico** gerado pelo sistema ou pelo programa, que indica que algo ocorreu.
|
||||
An **event** in PROMETEU is a **logical signal** generated by the system or the program, indicating that something has occurred.
|
||||
|
||||
Exemplos de eventos:
|
||||
Examples of events:
|
||||
|
||||
- fim de frame
|
||||
- timer expirado
|
||||
- troca de estado do sistema
|
||||
- erro de execução
|
||||
- end of frame
|
||||
- timer expired
|
||||
- system state change
|
||||
- execution error
|
||||
|
||||
Eventos **não executam código automaticamente**.
|
||||
Events **do not execute code automatically**.
|
||||
|
||||
Eles apenas **informam**.
|
||||
They only **inform**.
|
||||
|
||||
---
|
||||
|
||||
### 3.2 Fila de Eventos
|
||||
### 3.2 Event Queue
|
||||
|
||||
PROMETEU mantém uma **fila de eventos**:
|
||||
PROMETEU maintains an **event queue**:
|
||||
|
||||
- eventos são enfileirados
|
||||
- a fila é processada em ordem
|
||||
- o processamento ocorre em pontos definidos do frame
|
||||
- events are queued
|
||||
- the queue is processed in order
|
||||
- processing occurs at defined points in the frame
|
||||
|
||||
Eventos:
|
||||
Events:
|
||||
|
||||
- não interrompem execução arbitrariamente
|
||||
- não executam fora do loop
|
||||
- do not interrupt execution arbitrarily
|
||||
- do not execute outside the loop
|
||||
|
||||
---
|
||||
|
||||
## 4. Interrupções
|
||||
## 4. Interrupts
|
||||
|
||||
### 4.1 Definição
|
||||
### 4.1 Definition
|
||||
|
||||
Uma **interrupção** é um evento especial, tratado pelo sistema como **prioritário**, que pode:
|
||||
An **interrupt** is a special event, treated by the system as **priority**, which can:
|
||||
|
||||
- alterar o fluxo normal de execução
|
||||
- executar código específico do sistema
|
||||
- impactar ciclos e orçamento
|
||||
- change the normal flow of execution
|
||||
- execute specific system code
|
||||
- impact cycles and budget
|
||||
|
||||
Interrupções são **raras e explícitas**.
|
||||
Interrupts are **rare and explicit**.
|
||||
|
||||
---
|
||||
|
||||
### 4.2 O que NÃO é uma interrupção
|
||||
### 4.2 What is NOT an interrupt
|
||||
|
||||
Em PROMETEU, **não são interrupções**:
|
||||
In PROMETEU, the following are **not interrupts**:
|
||||
|
||||
- input de botão
|
||||
- colisões
|
||||
- timers comuns
|
||||
- lógica de jogo
|
||||
- button input
|
||||
- collisions
|
||||
- common timers
|
||||
- game logic
|
||||
|
||||
Esses são tratados como **estado ou eventos normais**.
|
||||
These are treated as **state or normal events**.
|
||||
|
||||
---
|
||||
|
||||
## 5. Tipos de Interrupções em PROMETEU
|
||||
## 5. Types of Interrupts in PROMETEU
|
||||
|
||||
PROMETEU define um conjunto pequeno e bem controlado de interrupções.
|
||||
PROMETEU defines a small and well-controlled set of interrupts.
|
||||
|
||||
### 5.1 Interrupção de Frame (VBlank Conceitual)
|
||||
### 5.1 Frame Interrupt (Conceptual VBlank)
|
||||
|
||||
O final de cada frame gera uma **interrupção lógica de sincronização**, responsável por:
|
||||
The end of each frame generates a **logical synchronization interrupt**, responsible for:
|
||||
|
||||
- swap de framebuffer
|
||||
- commit de áudio
|
||||
- sincronização de estado
|
||||
- framebuffer swap
|
||||
- audio commit
|
||||
- state synchronization
|
||||
|
||||
Essa interrupção:
|
||||
This interrupt:
|
||||
|
||||
- ocorre no SYNC
|
||||
- tem custo fixo
|
||||
- não executa código do usuário
|
||||
- occurs at SYNC
|
||||
- has a fixed cost
|
||||
- does not execute user code
|
||||
|
||||
---
|
||||
|
||||
### 5.2 Interrupção de Sistema
|
||||
### 5.2 System Interrupt
|
||||
|
||||
Gerada por condições excepcionais:
|
||||
Generated by exceptional conditions:
|
||||
|
||||
- erro fatal de VM
|
||||
- violação de memória
|
||||
- instrução inválida
|
||||
- fatal VM error
|
||||
- memory violation
|
||||
- invalid instruction
|
||||
|
||||
Resultado:
|
||||
Result:
|
||||
|
||||
- execução é interrompida
|
||||
- estado da VM é preservado
|
||||
- relatório detalhado é gerado
|
||||
- execution is halted
|
||||
- VM state is preserved
|
||||
- detailed report is generated
|
||||
|
||||
---
|
||||
|
||||
### 5.3 Interrupções Temporizadas (Timers)
|
||||
### 5.3 Timed Interrupts (Timers)
|
||||
|
||||
PROMETEU pode oferecer **timers do sistema**, modelados como:
|
||||
PROMETEU can offer **system timers**, modeled as:
|
||||
|
||||
- contadores baseados em frames
|
||||
- sinais gerados ao atingir zero
|
||||
- counters based on frames
|
||||
- signals generated upon reaching zero
|
||||
|
||||
Timers:
|
||||
|
||||
- não disparam código automaticamente
|
||||
- geram eventos consultáveis
|
||||
- do not trigger code automatically
|
||||
- generate queryable events
|
||||
|
||||
Exemplo conceitual:
|
||||
Conceptual example:
|
||||
|
||||
```
|
||||
if (timer.expired(T1)) {
|
||||
// tratar evento
|
||||
// handle event
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. Relação entre Eventos, Interrupções e o Loop
|
||||
## 6. Relationship between Events, Interrupts, and the Loop
|
||||
|
||||
O fluxo completo pode ser representado assim:
|
||||
The complete flow can be represented as follows:
|
||||
|
||||
```
|
||||
FRAME N
|
||||
@ -184,23 +184,23 @@ SYNC
|
||||
──────────────
|
||||
```
|
||||
|
||||
Importante:
|
||||
Important:
|
||||
|
||||
- eventos são processados antes da lógica principal
|
||||
- interrupções ocorrem apenas em pontos seguros
|
||||
- nenhuma interrupção ocorre “no meio” de uma instrução
|
||||
- events are processed before main logic
|
||||
- interrupts occur only at safe points
|
||||
- no interrupt occurs "in the middle" of an instruction
|
||||
|
||||
---
|
||||
|
||||
## 7. Custos e Orçamento
|
||||
## 7. Costs and Budget
|
||||
|
||||
Eventos e interrupções:
|
||||
Events and interrupts:
|
||||
|
||||
- consomem ciclos
|
||||
- participam do CAP
|
||||
- aparecem na certificação
|
||||
- consume cycles
|
||||
- participate in the CAP
|
||||
- appear in certification
|
||||
|
||||
Exemplo de relatório:
|
||||
Example report:
|
||||
|
||||
```
|
||||
Frame 18231:
|
||||
@ -208,82 +208,82 @@ Event processing:120cycles
|
||||
VBlank interrupt:80cycles
|
||||
```
|
||||
|
||||
Nada é gratuito.
|
||||
Nothing is free.
|
||||
|
||||
---
|
||||
|
||||
## 8. Determinismo e Reprodutibilidade
|
||||
## 8. Determinism and Reproducibility
|
||||
|
||||
PROMETEU garante:
|
||||
PROMETEU guarantees:
|
||||
|
||||
- mesma sequência de eventos → mesmo comportamento
|
||||
- interrupções sempre no mesmo ponto do frame
|
||||
- timers baseados em frame count, não em tempo real
|
||||
- same sequence of events → same behavior
|
||||
- interrupts always at the same point in the frame
|
||||
- timers based on frame count, not real time
|
||||
|
||||
Isso permite:
|
||||
This allows:
|
||||
|
||||
- replays confiáveis
|
||||
- debugging preciso
|
||||
- certificação justa
|
||||
- reliable replays
|
||||
- precise debugging
|
||||
- fair certification
|
||||
|
||||
---
|
||||
|
||||
## 9. Boas Práticas
|
||||
## 9. Best Practices
|
||||
|
||||
PROMETEU incentiva:
|
||||
PROMETEU encourages:
|
||||
|
||||
- tratar eventos como dados
|
||||
- consultar eventos explicitamente
|
||||
- evitar lógica pesada em handlers
|
||||
- usar timers em vez de polling excessivo
|
||||
- treating events as data
|
||||
- querying events explicitly
|
||||
- avoiding heavy logic in handlers
|
||||
- using timers instead of excessive polling
|
||||
|
||||
PROMETEU desencoraja:
|
||||
PROMETEU discourages:
|
||||
|
||||
- simular callbacks assíncronos
|
||||
- depender de ordem implícita
|
||||
- usar eventos como “atalho” para lógica complexa
|
||||
- simulating asynchronous callbacks
|
||||
- depending on implicit order
|
||||
- using events as a "shortcut" for complex logic
|
||||
|
||||
---
|
||||
|
||||
## 10. Relação com Microcontroladores
|
||||
## 10. Relationship with Microcontrollers
|
||||
|
||||
O modelo reflete MCUs reais:
|
||||
The model reflects real MCUs:
|
||||
|
||||
| MCU | PROMETEU |
|
||||
| --- | --- |
|
||||
| ISR | Interrupção explícita |
|
||||
| Loop principal | Loop PROMETEU |
|
||||
| Flags | Eventos |
|
||||
| Timers | Timers por frame |
|
||||
| ISR | Explicit interrupt |
|
||||
| Main Loop | PROMETEU Loop |
|
||||
| Flags | Events |
|
||||
| Timers | Per-frame timers |
|
||||
|
||||
Mas sem:
|
||||
But without:
|
||||
|
||||
- concorrência real
|
||||
- interrupções imprevisíveis
|
||||
- real concurrency
|
||||
- unpredictable interrupts
|
||||
|
||||
PROMETEU **ensina o conceito**, não o caos.
|
||||
PROMETEU **teaches the concept**, not the chaos.
|
||||
|
||||
---
|
||||
|
||||
## 11. Implicações Pedagógicas
|
||||
## 11. Pedagogical Implications
|
||||
|
||||
Este modelo permite ensinar:
|
||||
This model allows teaching:
|
||||
|
||||
- diferença entre evento e interrupção
|
||||
- sincronização segura
|
||||
- controle de fluxo em sistemas reativos
|
||||
- impacto de decisões temporais
|
||||
- the difference between event and interrupt
|
||||
- safe synchronization
|
||||
- flow control in reactive systems
|
||||
- the impact of temporal decisions
|
||||
|
||||
Tudo com **ordem, clareza e mensuração**.
|
||||
Everything with **order, clarity, and measurement**.
|
||||
|
||||
---
|
||||
|
||||
## 12. Resumo
|
||||
## 12. Summary
|
||||
|
||||
- eventos informam, não executam
|
||||
- interrupções são raras e controladas
|
||||
- nenhuma execução ocorre fora do loop
|
||||
- custos são explícitos
|
||||
- comportamento é determinístico
|
||||
- events inform, they do not execute
|
||||
- interrupts are rare and controlled
|
||||
- no execution occurs outside the loop
|
||||
- costs are explicit
|
||||
- behavior is deterministic
|
||||
|
||||
< [Voltar](chapter-8.md) | [Sumário](table-of-contents.md) | [Adiante](chapter-10.md) >
|
||||
< [Back](chapter-8.md) | [Summary](table-of-contents.md) | [Next](chapter-10.md) >
|
||||
@ -1,19 +1,19 @@
|
||||
# Table of Contents
|
||||
|
||||
- [Capitulo 1: Modelo de Tempo e Ciclos](chapter-1.md)
|
||||
- [Capitulo 2: PROMETEU VM Instruction Set](chapter-2.md)
|
||||
- [Capitulo 3: Memória: Stack, Heap e Alocação](chapter-3.md)
|
||||
- [Capitulo 4: Periférico GFX (Sistema Gráfico)](chapter-4.md)
|
||||
- [Capitulo 5: Periférico AUDIO (Sistema de Áudio)](chapter-5.md)
|
||||
- [Capitulo 6: Periférico INPUT (Sistema de Entrada)](chapter-6.md)
|
||||
- [Capitulo 7: Periférico TOUCH (Sistema de Entrada via ponteiro absoluto)](chapter-7.md)
|
||||
- [Capitulo 8: Periférico MEMCARD (Sistema de save/load)](chapter-8.md)
|
||||
- [Capitulo 9: Eventos e Interrupções](chapter-9.md)
|
||||
- [Capitulo 10: Debug, Inspeção e Profiling](chapter-10.md)
|
||||
- [Capitulo 11: Garantias de Portabilidade e Execução Multiplataforma](chapter-11.md)
|
||||
- [Capitulo 12: Firmware — PrometeuOS (POS) + PrometeuHub](chapter-12.md)
|
||||
- [Capitulo 13: Cartucho](chapter-13.md)
|
||||
- [Capitulo 14: Boot Profiles](chapter-14.md)
|
||||
- [Chapter 1: Time Model and Cycles](chapter-1.md)
|
||||
- [Chapter 2: PROMETEU VM Instruction Set](chapter-2.md)
|
||||
- [Chapter 3: Memory: Stack, Heap, and Allocation](chapter-3.md)
|
||||
- [Chapter 4: GFX Peripheral (Graphics System)](chapter-4.md)
|
||||
- [Chapter 5: AUDIO Peripheral (Audio System)](chapter-5.md)
|
||||
- [Chapter 6: INPUT Peripheral (Input System)](chapter-6.md)
|
||||
- [Chapter 7: TOUCH Peripheral (Absolute Pointer Input System)](chapter-7.md)
|
||||
- [Chapter 8: MEMCARD Peripheral (Save/Load System)](chapter-8.md)
|
||||
- [Chapter 9: Events and Interrupts](chapter-9.md)
|
||||
- [Chapter 10: Debug, Inspection, and Profiling](chapter-10.md)
|
||||
- [Chapter 11: Portability Guarantees and Cross-Platform Execution](chapter-11.md)
|
||||
- [Chapter 12: Firmware — PrometeuOS (POS) + PrometeuHub](chapter-12.md)
|
||||
- [Chapter 13: Cartridge](chapter-13.md)
|
||||
- [Chapter 14: Boot Profiles](chapter-14.md)
|
||||
|
||||
---
|
||||
[Voltar para o README](../README.md)
|
||||
[Back to README](../README.md)
|
||||
@ -1,26 +1,26 @@
|
||||
# PROMETEU Test Cartridges
|
||||
|
||||
Este diretório contém cartuchos de exemplo e suítes de teste para validar o comportamento do runtime e das ferramentas de desenvolvimento do PROMETEU.
|
||||
This directory contains example cartridges and test suites to validate the behavior of the PROMETEU runtime and development tools.
|
||||
|
||||
## Cartuchos Disponíveis
|
||||
## Available Cartridges
|
||||
|
||||
### 🟩 [color-square](./color-square)
|
||||
Um cartucho simples que demonstra:
|
||||
- Inicialização do sistema.
|
||||
- Renderização de um quadrado colorido no framebuffer.
|
||||
- Loop básico de execução.
|
||||
A simple cartridge that demonstrates:
|
||||
- System initialization.
|
||||
- Rendering a colored square in the framebuffer.
|
||||
- Basic execution loop.
|
||||
|
||||
## Estrutura de um Cartucho
|
||||
## Cartridge Structure
|
||||
|
||||
Um cartucho PROMETEU (em sua forma descompactada) geralmente consiste em:
|
||||
- `manifest.json`: Metadados do aplicativo (ID, título, versão, modo).
|
||||
- `program.pbc`: O bytecode compilado para a VM do PROMETEU.
|
||||
- `assets/`: Recursos como tiles, sprites e amostras de áudio.
|
||||
A PROMETEU cartridge (in its unpacked form) generally consists of:
|
||||
- `manifest.json`: Application metadata (ID, title, version, mode).
|
||||
- `program.pbc`: Compiled bytecode for the PROMETEU VM.
|
||||
- `assets/`: Resources such as tiles, sprites, and audio samples.
|
||||
|
||||
## Como usar
|
||||
## How to use
|
||||
|
||||
Você pode rodar qualquer um destes cartuchos usando a CLI principal:
|
||||
You can run any of these cartridges using the main CLI:
|
||||
|
||||
```bash
|
||||
prometeu run test-cartridges/<nome_do_cartucho>
|
||||
prometeu run test-cartridges/<cartridge_name>
|
||||
```
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user