This commit is contained in:
2026-02-09 15:13:50 +01:00
commit fb87c0639c
22 changed files with 530 additions and 0 deletions

1
platforms/cli/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
/target

8
platforms/cli/Cargo.toml Normal file
View File

@@ -0,0 +1,8 @@
[package]
name = "cli"
version = "0.1.0"
edition = "2024"
default-run = "cli"
[dependencies]
game-core = { path = "../../game-core" }

View File

@@ -0,0 +1,23 @@
use game_core::assets::AssetLoader;
pub struct DiskLoader;
impl AssetLoader for DiskLoader {
fn load_chunk(&mut self, offset: u32, length: usize, dest: &mut [u8]) -> Result<usize, ()> {
// In a real implementation, this would read from disk.
// For this example, we'll just fill the buffer with dummy data.
let dummy_data = vec![0u8; length];
dest[..length].copy_from_slice(&dummy_data);
Ok(length)
}
fn load_map(&mut self, map_id: u8, buffer: &mut [u8]) -> Result<usize, ()> {
let map_data = [
5, 5, 2, 2, 2, 2, 2, 2, 1, 1, 4, 2, 2, 1, 3, 1, 2, 2, 1, 1, 1, 2, 2, 2, 2, 2, 2,
];
let len = map_data.len();
buffer[..len].copy_from_slice(&map_data);
Ok(len)
}
}

93
platforms/cli/src/main.rs Normal file
View File

@@ -0,0 +1,93 @@
use std::io::{self, Write};
use game_core::{input::InputEvent, render::RenderRequest, state::Game, types::Direction};
use crate::disk_loader::DiskLoader;
mod disk_loader;
fn main() {
let mut game = Game::new();
let mut loader = DiskLoader;
loop {
let mut input_str = String::new();
print!("> ");
io::stdout().flush().unwrap();
io::stdin().read_line(&mut input_str).unwrap();
let input = match input_str.trim() {
"w" => InputEvent::Move(Direction::North),
"s" => InputEvent::Move(Direction::South),
"a" => InputEvent::Move(Direction::West),
"d" => InputEvent::Move(Direction::East),
"e" => InputEvent::Action,
_ => InputEvent::None,
};
let render = game.tick(input, &mut loader);
print!("{}[2J", 27 as char); // Clear screen
match render {
RenderRequest::MainMenu => {
println!("Welcome to the Twillight Island! Press 'e' to start.")
}
RenderRequest::CharacterCreation { prompt, .. } => {
println!("Creating Char: {}", prompt)
}
RenderRequest::Exploration {
tiles,
width,
player_idx,
message,
} => {
println!("STATUS: {}", message);
let w = width as usize;
// skip header (2 bytes)
let map_tiles = &tiles[2..];
for (i, &tile_byte) in map_tiles.iter().enumerate() {
if i % w == 0 {
println!();
}
if i == player_idx {
print!("@");
} else {
let char = match tile_byte {
1 => '.', // Grass
2 => '~', // Water
3 => '#', // Wall
4 => 'E', // Enemy
_ => ' ',
};
print!("{}", char);
}
}
println!();
}
RenderRequest::Combat {
player_stats,
enemy_stats,
log,
} => {
println!("COMBAT!");
println!(
"Player HP: {}/{}",
player_stats.hp_current, player_stats.hp_max
);
println!(
"Enemy HP: {}/{}",
enemy_stats.hp_current, enemy_stats.hp_max
);
println!("{}", log);
}
RenderRequest::Dialogue { text, options } => {
println!("{}", text);
for (i, option) in options.iter().enumerate() {
println!("{}: {}", i + 1, option);
}
}
}
}
}

1
platforms/web/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
/target

6
platforms/web/Cargo.toml Normal file
View File

@@ -0,0 +1,6 @@
[package]
name = "web"
version = "0.1.0"
edition = "2024"
[dependencies]

View File

@@ -0,0 +1,3 @@
fn main() {
println!("Hello, world!");
}