feat(renaser): Fase 17 — bitácora, el editor que recuerda
memoriosa (Fase 7c) demostró que un app podía persistir su huella. Esta fase la lleva al gesto natural: un editor de texto. Tecleas, reinicias renaser, el texto sigue ahí. La huella vive en el grafo de objetos como todo lo demás. - Nuevo crate `apps/bitacora/`: lienzo 480×280, tipografía 8×8 embebida (`font8x8 = "0.3"`) escalada x2 a 16×16, render pixel a pixel desde la memoria del propio app. Buffer 512 bytes con wrap automático a 28 columnas; `Enter` salta línea, Backspace borra; al desbordar el buffer se descartan los 64 primeros para amortizar la mudanza. Cada cambio invoca `sys_estado_guardar`; al arrancar, `init` llama a `sys_estado_cargar` y reconstruye. - Mapeo de scancodes US a ASCII (letras, dígitos, puntuación básica, espacio). Sin shift ni mayúsculas — minimalismo. - `GENESIS` crece de 7 a 8 apps; `bitacora` es la PRIMERA — gana la celda maestra al arrancar y te invita a teclear. - `CELDA_TASKBAR_ANCHO` baja de 150 a 130 px para que las ocho pestañas + lanzador + reloj quepan holgadas en 1280 px. Verificado en QEMU: tras escribir "hola renaser" y reiniciar el kernel con el mismo disk.img, bitácora muestra el texto donde lo dejó. El `almacen` reporta 24 objetos en el grafo (frente a 9 antes de escribir) y `raiz presente` — cada `guardar` anexó una versión al log direccionado por contenido. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -1085,3 +1085,37 @@ a la derecha, y le pone el reloj a latir cada segundo.
|
||||
reloj `0:17` a la derecha (el tiempo que el kernel lleva vivo al capturar).
|
||||
Diez segundos después, el reloj marca `0:29` — la barra se ha refrescado
|
||||
doce veces sin intervención del ratón ni del teclado.
|
||||
|
||||
## Fase 17 — `bitacora` :: el editor que recuerda — 2026-05-23
|
||||
|
||||
`memoriosa` (Fase 7c) demostró que un app podía persistir un contador a
|
||||
través de los reinicios. `bitacora` extiende esa demostración a un EDITOR de
|
||||
texto: tecleas, los caracteres aparecen; reinicias el kernel, el texto
|
||||
sigue ahí. La huella vive en el grafo de objetos, como todo lo demás.
|
||||
|
||||
### Añadido — app `bitacora` (`apps/bitacora/`)
|
||||
- **Lienzo 480×280** con título "bitacora :: el texto persiste" en índigo
|
||||
arriba y, debajo, las últimas líneas del buffer. Wrap automático a 28
|
||||
columnas; `Enter` salta de línea; Backspace borra el último carácter.
|
||||
- **Tipografía 8×8** embebida (crate `font8x8 = "0.3"`), escalada x2 a 16×16.
|
||||
El app rasteriza cada glifo pixel a pixel desde su propia memoria lineal.
|
||||
- **Persistencia automática**: cada cambio invoca `sys_estado_guardar`. Al
|
||||
arrancar, `init` llama a `sys_estado_cargar` y restaura el buffer.
|
||||
- Buffer de 512 bytes; al desbordarse descarta los 64 primeros para hacer
|
||||
hueco (amortiza el coste — no es una mudanza por cada pulsación).
|
||||
- Mapeo de scancodes US a ASCII para letras, dígitos y puntuación común;
|
||||
Enter genera `\n`, Backspace borra. Sin mayúsculas ni modificadores.
|
||||
|
||||
### Cambiado
|
||||
- **`GENESIS` crece de 7 a 8 apps** con `bitacora` como la PRIMERA — gana
|
||||
la celda maestra al arrancar, así que la primera ventana grande del
|
||||
escritorio te invita a teclear.
|
||||
- **`CELDA_TASKBAR_ANCHO`** baja de 150 a 130 píxeles para que las ocho
|
||||
pestañas + el lanzador + el reloj quepan holgadas en 1280 px.
|
||||
|
||||
### Verificado
|
||||
- QEMU (`sendkey` del monitor): tras escribir `hola renaser` y `quit` →
|
||||
relanzar QEMU con el mismo `disk.img`, la `bitacora` muestra de nuevo el
|
||||
texto justo donde quedó. El `almacen` reporta 24 objetos en el grafo
|
||||
(frente a 9 antes de escribir) y `raiz presente`: cada `guardar` anexó
|
||||
una versión al log direccionado por contenido.
|
||||
|
||||
+5
-3
@@ -28,7 +28,7 @@ Reconstruir una app WASM del userspace tras tocarla. Los `.wasm` viven en
|
||||
modulo `hello_wasm` se copia como `app.wasm`, el resto conserva su nombre:
|
||||
|
||||
```sh
|
||||
cd apps/<app> # hello_wasm, discola, glotona, cronista, memoriosa, pulso, tonada
|
||||
cd apps/<app> # hello_wasm, discola, glotona, cronista, memoriosa, pulso, tonada, bitacora
|
||||
cargo build --target wasm32-unknown-unknown --release
|
||||
cp target/wasm32-unknown-unknown/release/<app>.wasm ../../kernel/assets/<app>.wasm
|
||||
# (hello_wasm es la excepcion: su destino es kernel/assets/app.wasm)
|
||||
@@ -87,9 +87,11 @@ infraestructura `memory::mmio` (mapeador propio de regiones MMIO en la tabla
|
||||
L4), la Fase 14 COMPLETA —nombres en cada ventana y barra de tareas con
|
||||
clic-para-enfocar—, la Fase 15 COMPLETA —la voz del sistema: acorde al
|
||||
arrancar, repique al lanzar o cerrar, bajo al desalojar, con prioridad
|
||||
sobre `sys_tono`— y la Fase 16 COMPLETA —la barra viva: botón «+»
|
||||
sobre `sys_tono`— la Fase 16 COMPLETA —la barra viva: botón «+»
|
||||
lanzador a la izquierda y reloj `mm:ss` a la derecha que late cada
|
||||
segundo—. Todo verificado en QEMU. Ver `ROADMAP.md`.
|
||||
segundo— y la Fase 17 COMPLETA —`bitacora`, editor de texto que persiste
|
||||
entre arranques en el grafo de objetos (tipografía 8×8 embebida)—.
|
||||
Todo verificado en QEMU. Ver `ROADMAP.md`.
|
||||
|
||||
## Flujo de trabajo
|
||||
|
||||
|
||||
@@ -547,6 +547,27 @@ reloj LATE: cada vez que pasa un segundo nuevo —y sólo entonces, ni una vez
|
||||
de más—, la casa recompone el zócalo para mostrar la cifra siguiente. El
|
||||
resto del tiempo, el zócalo descansa.
|
||||
|
||||
## La bitácora — escribir y volver a encontrarlo
|
||||
|
||||
Hace tiempo que la casa permitía a sus inquilinos guardar pequeños recuerdos
|
||||
en sus paredes —`memoriosa` lo había estrenado contando teclas a través de
|
||||
los amaneceres—. Pero un cuaderno de notas, no había. Hoy llegó uno.
|
||||
|
||||
«bitácora» se asoma al despertar como el inquilino más importante: ocupa la
|
||||
celda más grande del escritorio, con un título índigo y un papel limpio
|
||||
debajo. Donde el cursor apuntaba, va apareciendo lo que se teclea, letra a
|
||||
letra. Cuando llega al borde derecho del papel, salta de línea solo;
|
||||
con Enter, también; con Backspace, retrocede y borra. Hasta aquí, nada
|
||||
nuevo bajo el sol.
|
||||
|
||||
Lo nuevo es lo que ocurre al apagar la casa. Habitualmente, lo que se
|
||||
escribe en un papel desaparece cuando el papel se quema. En la casa de
|
||||
renaser no: cada letra que la bitácora recibe queda anclada en su mapa
|
||||
secreto de objetos —el mismo árbol en el que viven los inquilinos—. Al
|
||||
apagar y volver a encender, el papel vuelve a su sitio con cada palabra
|
||||
intacta. Apaga, enciende, sigue escribiendo. La casa no olvida lo que se
|
||||
le confía.
|
||||
|
||||
---
|
||||
|
||||
*El diario continúa. La próxima página la escribirá la próxima jornada.*
|
||||
|
||||
@@ -289,6 +289,20 @@ tiempo: el reloj avanza de `0:17` a `0:29`.
|
||||
`pintar_taskbar` dibuja la cruz del lanzador como dos rectángulos
|
||||
cruzados (sin depender de la tipografía) y rotula el reloj.
|
||||
|
||||
## Fase 17 — `bitacora`, el editor que recuerda (completada)
|
||||
|
||||
`memoriosa` (Fase 7c) demostró que un app podía persistir su huella. La Fase 17
|
||||
lo lleva al gesto natural: un editor de texto. Tecleas, reinicias renaser, el
|
||||
texto sigue ahí. Verificada en QEMU.
|
||||
|
||||
- Nuevo crate `apps/bitacora/`: lienzo 480×280, tipografía 8×8 (crate `font8x8`)
|
||||
escalada x2 a 16×16, render pixel a pixel desde la memoria del propio app.
|
||||
Buffer 512 bytes, wrap a 28 columnas, Enter / Backspace, persiste cada
|
||||
cambio con `sys_estado_guardar`. Mapeo de scancodes US a ASCII (minúsculas).
|
||||
- `GENESIS` crece de 7 a 8 apps; `bitacora` es la maestra al arrancar.
|
||||
- `CELDA_TASKBAR_ANCHO` baja de 150 a 130 px para que las ocho pestañas
|
||||
quepan holgadas con el lanzador y el reloj.
|
||||
|
||||
Líneas abiertas posteriores: reciclado de las ranuras de ventana cerradas;
|
||||
audio con varias voces (PCM) más allá del tono único de la bocina.
|
||||
|
||||
|
||||
Generated
+16
@@ -0,0 +1,16 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 4
|
||||
|
||||
[[package]]
|
||||
name = "bitacora"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"font8x8",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "font8x8"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "875488b8711a968268c7cf5d139578713097ca4635a76044e8fe8eedf831d07e"
|
||||
@@ -0,0 +1,31 @@
|
||||
# =============================================================================
|
||||
# renaser :: apps/bitacora — Fase 17 :: un editor de texto que persiste
|
||||
# -----------------------------------------------------------------------------
|
||||
# Tecleas, los caracteres se quedan. Y al reiniciar siguen ahi, porque viven en
|
||||
# el grafo de objetos (Fase 7c, `sys_estado_*`). Renderizado con la tipografia
|
||||
# 8x8 clasica (font8x8), embebida en el binario WASM — no depende del kernel.
|
||||
# =============================================================================
|
||||
|
||||
[package]
|
||||
name = "bitacora"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
description = "renaser :: app WASM — un editor de texto que persiste entre arranques"
|
||||
|
||||
[workspace]
|
||||
|
||||
[dependencies]
|
||||
# Tipografia 8x8 pixel-perfect, public domain. La crate es `no_std` y compila
|
||||
# limpiamente para `wasm32-unknown-unknown` con `default-features = false`.
|
||||
font8x8 = { version = "0.3", default-features = false, features = ["unicode"] }
|
||||
|
||||
[lib]
|
||||
crate-type = ["cdylib"]
|
||||
|
||||
[profile.dev]
|
||||
panic = "abort"
|
||||
|
||||
[profile.release]
|
||||
panic = "abort"
|
||||
opt-level = "s"
|
||||
lto = true
|
||||
@@ -0,0 +1,289 @@
|
||||
// =============================================================================
|
||||
// renaser :: apps/bitacora — Fase 17 :: un editor que recuerda
|
||||
// -----------------------------------------------------------------------------
|
||||
// La fase 7c le dio a las apps memoria mas alla del arranque: `sys_estado_*`
|
||||
// ancla la huella de un app en el grafo, y al reiniciar el kernel se la
|
||||
// devuelve. `memoriosa` lo demostro contando teclas. `bitacora` lo lleva al
|
||||
// siguiente paso natural: ofrecer un editor de texto.
|
||||
//
|
||||
// La pantalla muestra un titulo en indigo y debajo el texto que el usuario va
|
||||
// tecleando, con salto de linea automatico al llegar al margen y con `Enter`.
|
||||
// Backspace borra el ultimo. Cada cambio se persiste de inmediato, asi que la
|
||||
// apagada brusca no pierde nada — la proxima vida del kernel retoma exacto.
|
||||
//
|
||||
// Tipografia: la 8x8 clasica (font8x8), escalada x2 a 16x16. Cabe en su propia
|
||||
// memoria lineal y se renderiza pixel a pixel — el app no toca el lienzo del
|
||||
// kernel, solo entrega su propio fotograma.
|
||||
// =============================================================================
|
||||
|
||||
#![no_std]
|
||||
|
||||
use font8x8::legacy::BASIC_LEGACY;
|
||||
|
||||
#[link(wasm_import_module = "renaser")]
|
||||
extern "C" {
|
||||
fn sys_render_frame(ptr: u32, len: u32);
|
||||
fn sys_get_scancode() -> u32;
|
||||
fn sys_estado_cargar(salida: u32, capacidad: u32) -> i32;
|
||||
fn sys_estado_guardar(datos: u32, datos_len: u32) -> i32;
|
||||
}
|
||||
|
||||
#[panic_handler]
|
||||
fn al_fallar(_: &core::panic::PanicInfo) -> ! {
|
||||
loop {}
|
||||
}
|
||||
|
||||
// --- Geometria ----------------------------------------------------------------
|
||||
|
||||
/// Tamaño del lienzo natural — debe coincidir con `region` del manifiesto.
|
||||
const ANCHO: usize = 480;
|
||||
const ALTO: usize = 280;
|
||||
/// Pixeles por celda de glifo (8x8 escalado x2).
|
||||
const PASO: usize = 16;
|
||||
/// Margen horizontal para el cuerpo del texto.
|
||||
const MARGEN_X: usize = 16;
|
||||
/// Y de la linea base del titulo.
|
||||
const Y_LABEL: usize = 6;
|
||||
/// Y de la linea base de la primera fila de texto.
|
||||
const Y_TEXTO: usize = 38;
|
||||
/// Cuantas columnas caben.
|
||||
const COLUMNAS: usize = (ANCHO - 2 * MARGEN_X) / PASO;
|
||||
/// Cuantas filas caben bajo el titulo.
|
||||
const FILAS: usize = (ALTO - Y_TEXTO) / PASO;
|
||||
|
||||
// --- Estado -------------------------------------------------------------------
|
||||
|
||||
/// Capacidad del buffer de texto. Al desbordarse se descarta una porcion del
|
||||
/// principio (el texto mas viejo) para dejar sitio al nuevo — un cuaderno con
|
||||
/// memoria finita, no un agujero negro.
|
||||
const CAPACIDAD: usize = 512;
|
||||
|
||||
const FONDO: u32 = 0x0A_18_30;
|
||||
const TINTA: u32 = 0xE8_EC_F4;
|
||||
const ETIQUETA: u32 = 0x8B_5C_F6;
|
||||
|
||||
static mut BUFFER: [u8; CAPACIDAD] = [0; CAPACIDAD];
|
||||
static mut LEN: usize = 0;
|
||||
static mut LIENZO: [u32; ANCHO * ALTO] = [0; ANCHO * ALTO];
|
||||
|
||||
// --- ABI del userspace --------------------------------------------------------
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn init() {
|
||||
// Cargar el texto persistido — si no hay nada, `n` es 0 y empezamos vacios.
|
||||
let buffer = unsafe { &mut *core::ptr::addr_of_mut!(BUFFER) };
|
||||
// SEGURIDAD: `sys_estado_cargar` es una capacidad del host; (ptr, len) cae
|
||||
// dentro de nuestra propia memoria lineal y el host lo valida sin piedad.
|
||||
let n = unsafe { sys_estado_cargar(buffer.as_mut_ptr() as u32, CAPACIDAD as u32) };
|
||||
if n > 0 {
|
||||
// SEGURIDAD: lectura/escritura escalar; LEN es nuestro propio cursor.
|
||||
unsafe {
|
||||
LEN = (n as usize).min(CAPACIDAD);
|
||||
}
|
||||
}
|
||||
pintar();
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn tick() {
|
||||
let mut cambio = false;
|
||||
// Drenar TODOS los scancodes acumulados desde el ultimo fotograma. La cola
|
||||
// es propia de este app — la inscribio la fase 5 en la IRQ1 — asi que
|
||||
// mirarla aqui no le quita nada a nadie.
|
||||
loop {
|
||||
let sc = unsafe { sys_get_scancode() } as u8;
|
||||
if sc == 0 {
|
||||
break;
|
||||
}
|
||||
if sc & 0x80 != 0 {
|
||||
// Codigo de KEY-UP (release). Lo ignoramos: tecleamos al pulsar.
|
||||
continue;
|
||||
}
|
||||
match sc {
|
||||
0x0E => {
|
||||
// Backspace — borrar el ultimo caracter, si lo hay.
|
||||
unsafe {
|
||||
if LEN > 0 {
|
||||
LEN -= 1;
|
||||
cambio = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
0x1C => {
|
||||
// Enter — salto de linea explicito.
|
||||
anexar(b'\n');
|
||||
cambio = true;
|
||||
}
|
||||
otro => {
|
||||
let c = scancode_a_caracter(otro);
|
||||
if c != 0 {
|
||||
anexar(c);
|
||||
cambio = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if cambio {
|
||||
guardar();
|
||||
}
|
||||
pintar();
|
||||
}
|
||||
|
||||
// --- Estado: buffer -----------------------------------------------------------
|
||||
|
||||
/// Anexa un caracter al final del buffer. Si el buffer esta lleno descarta los
|
||||
/// 64 primeros bytes para hacer hueco (amortiza el coste; no es una mudanza por
|
||||
/// cada pulsacion).
|
||||
fn anexar(c: u8) {
|
||||
unsafe {
|
||||
if LEN >= CAPACIDAD {
|
||||
let buffer = &mut *core::ptr::addr_of_mut!(BUFFER);
|
||||
buffer.copy_within(64.., 0);
|
||||
LEN = CAPACIDAD - 64;
|
||||
}
|
||||
let buffer = &mut *core::ptr::addr_of_mut!(BUFFER);
|
||||
buffer[LEN] = c;
|
||||
LEN += 1;
|
||||
}
|
||||
}
|
||||
|
||||
/// Persiste el buffer en el grafo. La huella sobrevive a la siguiente arrancada.
|
||||
fn guardar() {
|
||||
unsafe {
|
||||
let buffer = &*core::ptr::addr_of!(BUFFER);
|
||||
// SEGURIDAD: (ptr, len) describe nuestra propia memoria; el host lo
|
||||
// verifica y nunca lee fuera del rango entregado.
|
||||
let _ = sys_estado_guardar(buffer.as_ptr() as u32, LEN as u32);
|
||||
}
|
||||
}
|
||||
|
||||
// --- Renderizado --------------------------------------------------------------
|
||||
|
||||
fn pintar() {
|
||||
let lienzo = unsafe { &mut *core::ptr::addr_of_mut!(LIENZO) };
|
||||
// Fondo limpio.
|
||||
for pixel in lienzo.iter_mut() {
|
||||
*pixel = FONDO;
|
||||
}
|
||||
// Titulo.
|
||||
pintar_texto(lienzo, b"bitacora :: el texto persiste", MARGEN_X, Y_LABEL, ETIQUETA);
|
||||
// Linea sutil bajo el titulo.
|
||||
let y_linea = Y_LABEL + PASO + 4;
|
||||
for x in MARGEN_X..(ANCHO - MARGEN_X) {
|
||||
lienzo[y_linea * ANCHO + x] = ETIQUETA;
|
||||
lienzo[(y_linea + 1) * ANCHO + x] = ETIQUETA;
|
||||
}
|
||||
|
||||
// Cuerpo: mostrar las ultimas `FILAS` lineas del buffer, con wrap en
|
||||
// `COLUMNAS`. Dos pasadas para saltarse las filas viejas con elegancia.
|
||||
let buffer = unsafe { &*core::ptr::addr_of!(BUFFER) };
|
||||
let len = unsafe { LEN };
|
||||
|
||||
// Pasada 1: contar filas totales (con wrap).
|
||||
let mut filas_total = 1usize;
|
||||
let mut col = 0usize;
|
||||
for i in 0..len {
|
||||
let c = buffer[i];
|
||||
if c == b'\n' {
|
||||
filas_total += 1;
|
||||
col = 0;
|
||||
} else {
|
||||
if col >= COLUMNAS {
|
||||
filas_total += 1;
|
||||
col = 0;
|
||||
}
|
||||
col += 1;
|
||||
}
|
||||
}
|
||||
let skip = filas_total.saturating_sub(FILAS);
|
||||
|
||||
// Pasada 2: renderizar solo a partir de la fila `skip`.
|
||||
let mut fila_actual = 0usize;
|
||||
let mut col2 = 0usize;
|
||||
for i in 0..len {
|
||||
let c = buffer[i];
|
||||
if c == b'\n' {
|
||||
fila_actual += 1;
|
||||
col2 = 0;
|
||||
continue;
|
||||
}
|
||||
if col2 >= COLUMNAS {
|
||||
fila_actual += 1;
|
||||
col2 = 0;
|
||||
}
|
||||
if fila_actual >= skip {
|
||||
let rfila = fila_actual - skip;
|
||||
if rfila < FILAS {
|
||||
let x = MARGEN_X + col2 * PASO;
|
||||
let y = Y_TEXTO + rfila * PASO;
|
||||
pintar_glifo(lienzo, c, x, y, TINTA);
|
||||
}
|
||||
}
|
||||
col2 += 1;
|
||||
}
|
||||
|
||||
// SEGURIDAD: `sys_render_frame` valida (ptr, len) contra nuestra memoria.
|
||||
unsafe {
|
||||
sys_render_frame(lienzo.as_ptr() as u32, (ANCHO * ALTO * 4) as u32);
|
||||
}
|
||||
}
|
||||
|
||||
/// Pinta una cadena ASCII en (x, y_base), avanzando un PASO por glifo. Se
|
||||
/// detiene si el siguiente glifo no cabria dentro del lienzo.
|
||||
fn pintar_texto(lienzo: &mut [u32], texto: &[u8], x: usize, y: usize, color: u32) {
|
||||
let mut cx = x;
|
||||
for &c in texto {
|
||||
if cx + PASO > ANCHO {
|
||||
break;
|
||||
}
|
||||
pintar_glifo(lienzo, c, cx, y, color);
|
||||
cx += PASO;
|
||||
}
|
||||
}
|
||||
|
||||
/// Pinta un solo glifo 8x8 escalado a 16x16 en (x, y). Los caracteres no ASCII
|
||||
/// se renderizan como `?`.
|
||||
fn pintar_glifo(lienzo: &mut [u32], c: u8, x: usize, y: usize, color: u32) {
|
||||
let glifo = if (c as usize) < 128 {
|
||||
BASIC_LEGACY[c as usize]
|
||||
} else {
|
||||
BASIC_LEGACY[b'?' as usize]
|
||||
};
|
||||
for row in 0..8 {
|
||||
for col in 0..8 {
|
||||
if glifo[row] & (1 << col) != 0 {
|
||||
let px = x + col * 2;
|
||||
let py = y + row * 2;
|
||||
if px + 1 >= ANCHO || py + 1 >= ALTO {
|
||||
continue;
|
||||
}
|
||||
lienzo[py * ANCHO + px] = color;
|
||||
lienzo[py * ANCHO + px + 1] = color;
|
||||
lienzo[(py + 1) * ANCHO + px] = color;
|
||||
lienzo[(py + 1) * ANCHO + px + 1] = color;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// --- Teclado: scancode -> caracter --------------------------------------------
|
||||
|
||||
/// Traduce un MAKE-code del set 1 (US layout) a su caracter ASCII en minuscula.
|
||||
/// Devuelve 0 para los scancodes que no producen texto — modificadores,
|
||||
/// extendidos, etc.: el llamante los descarta sin gritar.
|
||||
fn scancode_a_caracter(sc: u8) -> u8 {
|
||||
match sc {
|
||||
0x02 => b'1', 0x03 => b'2', 0x04 => b'3', 0x05 => b'4', 0x06 => b'5',
|
||||
0x07 => b'6', 0x08 => b'7', 0x09 => b'8', 0x0A => b'9', 0x0B => b'0',
|
||||
0x10 => b'q', 0x11 => b'w', 0x12 => b'e', 0x13 => b'r', 0x14 => b't',
|
||||
0x15 => b'y', 0x16 => b'u', 0x17 => b'i', 0x18 => b'o', 0x19 => b'p',
|
||||
0x1E => b'a', 0x1F => b's', 0x20 => b'd', 0x21 => b'f', 0x22 => b'g',
|
||||
0x23 => b'h', 0x24 => b'j', 0x25 => b'k', 0x26 => b'l',
|
||||
0x2C => b'z', 0x2D => b'x', 0x2E => b'c', 0x2F => b'v', 0x30 => b'b',
|
||||
0x31 => b'n', 0x32 => b'm',
|
||||
0x33 => b',', 0x34 => b'.', 0x35 => b'/',
|
||||
0x27 => b';', 0x28 => b'\'',
|
||||
0x39 => b' ',
|
||||
_ => 0,
|
||||
}
|
||||
}
|
||||
@@ -107,12 +107,14 @@ struct AppGenesis {
|
||||
region: (u32, u32, u32, u32),
|
||||
}
|
||||
|
||||
/// El userspace de genesis — las siete aplicaciones que pueblan un disco recien
|
||||
/// forjado. La melodia visual `tonada` (Fase 12), el compas visual `pulso`
|
||||
/// (Fase 11), un saludo (`hola`), la `memoriosa` interactiva que recuerda entre
|
||||
/// sesiones (Fase 7c), y tres demos de los guardarrailes del kernel: `discola`
|
||||
/// (combustible), `glotona` (memoria) y `cronista` (la cronica de los arranques).
|
||||
const GENESIS: [AppGenesis; 7] = [
|
||||
/// El userspace de genesis — las ocho aplicaciones que pueblan un disco recien
|
||||
/// forjado. La `bitacora` (Fase 17, editor que persiste), la melodia visual
|
||||
/// `tonada` (Fase 12), el compas visual `pulso` (Fase 11), un saludo (`hola`),
|
||||
/// la `memoriosa` interactiva que recuerda entre sesiones (Fase 7c), y tres
|
||||
/// demos de los guardarrailes del kernel: `discola` (combustible), `glotona`
|
||||
/// (memoria) y `cronista` (la cronica de los arranques).
|
||||
const GENESIS: [AppGenesis; 8] = [
|
||||
AppGenesis { nombre: "bitacora", archivo: "bitacora.wasm", region: (100, 120, 480, 280) },
|
||||
AppGenesis { nombre: "tonada", archivo: "tonada.wasm", region: (100, 120, 360, 120) },
|
||||
AppGenesis { nombre: "pulso", archivo: "pulso.wasm", region: (100, 120, 360, 120) },
|
||||
AppGenesis { nombre: "hola", archivo: "app.wasm", region: (100, 120, 480, 560) },
|
||||
|
||||
Executable
BIN
Binary file not shown.
@@ -67,8 +67,10 @@ const FRANJA_CONSOLA: usize = 296;
|
||||
/// ahi una pestaña con su nombre, que el clic enfoca.
|
||||
const FRANJA_TASKBAR: usize = 40;
|
||||
|
||||
/// Anchura de cada celda de la barra de tareas, en pixeles.
|
||||
const CELDA_TASKBAR_ANCHO: usize = 150;
|
||||
/// Anchura de cada celda de la barra de tareas, en pixeles. Dimensionada para
|
||||
/// que las ocho apps de genesis + el lanzador + el reloj caben holgados en una
|
||||
/// pantalla de 1280 px.
|
||||
const CELDA_TASKBAR_ANCHO: usize = 130;
|
||||
/// Hueco entre celdas adyacentes de la barra.
|
||||
const CELDA_TASKBAR_HUECO: usize = 6;
|
||||
/// Margen izquierdo y derecho de la barra de tareas.
|
||||
|
||||
Reference in New Issue
Block a user