From c20aa0ea455c6d4cd544b64c8a49a582a30913bd Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jo=C3=A3o=20Magalh=C3=A3es?= <joamag@gmail.com>
Date: Sun, 6 Aug 2023 12:46:46 +0100
Subject: [PATCH] chore: more flexible handling of name and version

---
 frontends/libretro/src/lib.rs |  5 +++--
 frontends/sdl/src/main.rs     | 16 +++++++---------
 frontends/sdl/src/sdl.rs      |  8 ++++++--
 frontends/web/ts/gb.ts        |  4 ++--
 src/gb.rs                     | 14 ++++++++++++--
 src/state.rs                  |  8 ++++++--
 src/util.rs                   |  9 +++++++++
 7 files changed, 45 insertions(+), 19 deletions(-)

diff --git a/frontends/libretro/src/lib.rs b/frontends/libretro/src/lib.rs
index bae6cf7f..3075aa12 100644
--- a/frontends/libretro/src/lib.rs
+++ b/frontends/libretro/src/lib.rs
@@ -5,10 +5,11 @@ pub mod consts;
 use boytacean::{
     debugln,
     gb::{AudioProvider, GameBoy},
-    gen::VERSION,
+    gen::{NAME, VERSION},
     pad::PadKey,
     ppu::{DISPLAY_HEIGHT, DISPLAY_WIDTH, FRAME_BUFFER_SIZE, XRGB8888_SIZE},
     rom::Cartridge,
+    util::capitalize,
 };
 use consts::{
     REGION_NTSC, RETRO_API_VERSION, RETRO_DEVICE_ID_JOYPAD_A, RETRO_DEVICE_ID_JOYPAD_B,
@@ -173,7 +174,7 @@ pub extern "C" fn retro_reset() {
 #[no_mangle]
 pub unsafe extern "C" fn retro_get_system_info(info: *mut RetroSystemInfo) {
     debugln!("retro_get_system_info()");
-    (*info).library_name = "Boytacean\0".as_ptr() as *const c_char;
+    (*info).library_name = format!("{}\0", capitalize(NAME)).as_ptr() as *const c_char;
     (*info).library_version = format!("v{}\0", VERSION).as_ptr() as *const c_char;
     (*info).valid_extensions = "gb|gbc\0".as_ptr() as *const c_char;
     (*info).need_fullpath = false;
diff --git a/frontends/sdl/src/main.rs b/frontends/sdl/src/main.rs
index ea89dc12..f8cdf8fb 100644
--- a/frontends/sdl/src/main.rs
+++ b/frontends/sdl/src/main.rs
@@ -9,12 +9,13 @@ use audio::Audio;
 use boytacean::{
     devices::{printer::PrinterDevice, stdout::StdoutDevice},
     gb::{AudioProvider, GameBoy, GameBoyMode},
+    gen::{NAME, VERSION},
     pad::PadKey,
     ppu::PaletteInfo,
     rom::Cartridge,
     serial::{NullDevice, SerialDevice},
     state::save_state_file,
-    util::{replace_ext, write_file},
+    util::{capitalize, replace_ext, write_file},
 };
 use chrono::Utc;
 use clap::Parser;
@@ -31,10 +32,7 @@ use std::{
 /// The scale at which the screen is going to be drawn
 /// meaning the ratio between Game Boy resolution and
 /// the window size to be displayed.
-const SCREEN_SCALE: f32 = 2.0;
-
-/// The base title to be used in the window.
-const TITLE: &str = "Boytacean";
+const SCREEN_SCALE: f32 = 2.5;
 
 /// Base audio volume to be used as the basis of the
 /// amplification level of the volume
@@ -77,7 +75,7 @@ pub struct Emulator {
     unlimited: bool,
     sdl: Option<SdlSystem>,
     audio: Option<Audio>,
-    title: &'static str,
+    title: String,
     rom_path: String,
     ram_path: String,
     logic_frequency: u32,
@@ -97,7 +95,7 @@ impl Emulator {
             unlimited: options.unlimited.unwrap_or(false),
             sdl: None,
             audio: None,
-            title: TITLE,
+            title: format!("{} v{}", capitalize(NAME), VERSION),
             rom_path: String::from("invalid"),
             ram_path: String::from("invalid"),
             logic_frequency: GameBoy::CPU_FREQ,
@@ -200,7 +198,7 @@ impl Emulator {
     pub fn start_graphics(&mut self, sdl: &Sdl, screen_scale: f32) {
         self.sdl = Some(SdlSystem::new(
             sdl,
-            self.title,
+            &self.title,
             self.system.display_width() as u32,
             self.system.display_height() as u32,
             screen_scale,
@@ -820,7 +818,7 @@ fn main() {
     save_state_file("tobias.sav", &game_boy);
 
     // prints the current version of the emulator (informational message)
-    println!("========= Boytacean =========\n{}", game_boy);
+    println!("========= {} =========\n{}", capitalize(NAME), game_boy);
 
     // creates a new generic emulator structure then starts
     // both the video and audio sub-systems, loads default
diff --git a/frontends/sdl/src/sdl.rs b/frontends/sdl/src/sdl.rs
index add0f670..9a86ee60 100644
--- a/frontends/sdl/src/sdl.rs
+++ b/frontends/sdl/src/sdl.rs
@@ -21,7 +21,7 @@ impl SdlSystem {
     /// and sound.
     pub fn new(
         sdl: &Sdl,
-        title: &str,
+        title: &String,
         width: u32,
         height: u32,
         scale: f32,
@@ -42,7 +42,11 @@ impl SdlSystem {
         // creates the system window that is going to be used to
         // show the emulator and sets it to the central are o screen
         let window = video_subsystem
-            .window(title, scale as u32 * width, scale as u32 * height)
+            .window(
+                title,
+                (scale * width as f32) as u32,
+                (scale * height as f32) as u32,
+            )
             .resizable()
             .position_centered()
             .opengl()
diff --git a/frontends/web/ts/gb.ts b/frontends/web/ts/gb.ts
index 8126bdf6..1f044191 100644
--- a/frontends/web/ts/gb.ts
+++ b/frontends/web/ts/gb.ts
@@ -485,7 +485,7 @@ export class GameboyEmulator extends EmulatorBase implements Emulator {
     }
 
     get name(): string {
-        return "Boytacean";
+        return this.gameBoy?.name() || info.name;
     }
 
     get device(): Entry {
@@ -501,7 +501,7 @@ export class GameboyEmulator extends EmulatorBase implements Emulator {
 
     get version(): Entry | undefined {
         return {
-            text: info.version,
+            text: this.gameBoy?.version() ?? info.version,
             url: "https://github.com/joamag/boytacean/blob/master/CHANGELOG.md"
         };
     }
diff --git a/src/gb.rs b/src/gb.rs
index 45ab76ed..c3db3aed 100644
--- a/src/gb.rs
+++ b/src/gb.rs
@@ -11,7 +11,7 @@ use crate::{
     data::{BootRom, CGB_BOOT, DMG_BOOT, DMG_BOOTIX, MGB_BOOTIX, SGB_BOOT},
     devices::{printer::PrinterDevice, stdout::StdoutDevice},
     dma::Dma,
-    gen::{COMPILATION_DATE, COMPILATION_TIME, COMPILER, COMPILER_VERSION, VERSION},
+    gen::{COMPILATION_DATE, COMPILATION_TIME, COMPILER, COMPILER_VERSION, NAME, VERSION},
     genie::{GameGenie, GameGenieCode},
     mmu::Mmu,
     pad::{Pad, PadKey},
@@ -22,7 +22,7 @@ use crate::{
     rom::{Cartridge, RamSize},
     serial::{NullDevice, Serial, SerialDevice},
     timer::Timer,
-    util::read_file,
+    util::{capitalize, read_file},
 };
 
 #[cfg(feature = "wasm")]
@@ -701,6 +701,16 @@ impl GameBoy {
         tile.palette_buffer(self.ppu().palette_bg())
     }
 
+    /// Obtains the name of the emulator.
+    pub fn name(&self) -> String {
+        capitalize(NAME)
+    }
+
+    /// Obtains the version of the emulator.
+    pub fn version(&self) -> String {
+        String::from(VERSION)
+    }
+
     /// Obtains the name of the compiler that has been
     /// used in the compilation of the base Boytacean
     /// library. Can be used for diagnostics.
diff --git a/src/state.rs b/src/state.rs
index 72b405aa..507868a4 100644
--- a/src/state.rs
+++ b/src/state.rs
@@ -4,7 +4,11 @@ use std::{
     io::{Cursor, Read, Write},
 };
 
-use crate::{gb::GameBoy, gen::VERSION};
+use crate::{
+    gb::GameBoy,
+    gen::{NAME, VERSION},
+    util::capitalize,
+};
 
 pub trait Serialize {
     fn save(&self, buffer: &mut Vec<u8>);
@@ -152,7 +156,7 @@ pub fn save_state_file(file_path: &str, gb: &GameBoy) {
 pub fn save_state(gb: &GameBoy) -> Vec<u8> {
     let mut data: Vec<u8> = vec![];
 
-    BeesName::new(format!("Boytacean v{}", VERSION)).save(&mut data);
+    BeesName::new(format!("{} v{}", capitalize(NAME), VERSION)).save(&mut data);
 
     data
 }
diff --git a/src/util.rs b/src/util.rs
index 59770ba4..ae0ff7b3 100644
--- a/src/util.rs
+++ b/src/util.rs
@@ -44,6 +44,15 @@ pub fn replace_ext(path: &str, new_extension: &str) -> Option<String> {
     Some(String::from(new_file_path.to_str()?))
 }
 
+/// Capitalizes the first character in the provided string.
+pub fn capitalize(string: &str) -> String {
+    let mut chars = string.chars();
+    match chars.next() {
+        None => String::new(),
+        Some(chr) => chr.to_uppercase().collect::<String>() + chars.as_str(),
+    }
+}
+
 #[cfg(test)]
 mod tests {
     use std::path::Path;
-- 
GitLab