From 5a137ce644bc002a8b768dae1b239899f82f6c2d Mon Sep 17 00:00:00 2001 From: jaby Date: Sat, 22 Apr 2023 15:44:21 +0200 Subject: [PATCH 001/588] Add colored output to most tools; Make mkoverlay more tolerant for missing overlay files; Make psxcdgen_ex emit a warning when no license file is specified --- src/Tools/cpp_out/Cargo.toml | 2 +- src/Tools/cpp_out/src/main.rs | 6 +++--- src/Tools/jaby_engine_fconv/Cargo.toml | 2 +- src/Tools/jaby_engine_fconv/src/main.rs | 7 +++---- src/Tools/mkoverlay/Cargo.toml | 2 +- src/Tools/mkoverlay/src/main.rs | 23 +++++++++++++++++------ src/Tools/psxcdgen_ex/Cargo.toml | 3 ++- src/Tools/psxcdgen_ex/src/encoder/psx.rs | 4 +++- src/Tools/psxcdgen_ex/src/main.rs | 8 ++++---- src/Tools/tool_helper/Cargo.toml | 3 ++- src/Tools/tool_helper/src/lib.rs | 16 +++++++++++++++- 11 files changed, 52 insertions(+), 24 deletions(-) diff --git a/src/Tools/cpp_out/Cargo.toml b/src/Tools/cpp_out/Cargo.toml index b0964cec..22684519 100644 --- a/src/Tools/cpp_out/Cargo.toml +++ b/src/Tools/cpp_out/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cpp_out" -version = "1.0.1" +version = "1.0.2" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/src/Tools/cpp_out/src/main.rs b/src/Tools/cpp_out/src/main.rs index e4c8ffc4..78947958 100644 --- a/src/Tools/cpp_out/src/main.rs +++ b/src/Tools/cpp_out/src/main.rs @@ -1,6 +1,7 @@ use clap::{Parser}; -use std::path::PathBuf; use cpp_out::{Configuration, Error, FileType}; +use std::path::PathBuf; +use tool_helper::exit_with_error; #[derive(Parser)] #[clap(about = "Output a file content or stdin to a c++ header/source file", long_about = None)] @@ -48,8 +49,7 @@ fn main() { match run_main() { Ok(_) => (), Err(error) => { - eprintln!("{}", error); - std::process::exit(error.exit_code); + exit_with_error(error) } } } \ No newline at end of file diff --git a/src/Tools/jaby_engine_fconv/Cargo.toml b/src/Tools/jaby_engine_fconv/Cargo.toml index 1f992c77..0877a876 100644 --- a/src/Tools/jaby_engine_fconv/Cargo.toml +++ b/src/Tools/jaby_engine_fconv/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "jaby_engine_fconv" -version = "0.1.2" +version = "0.1.3" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/src/Tools/jaby_engine_fconv/src/main.rs b/src/Tools/jaby_engine_fconv/src/main.rs index 8db9f729..10b3e819 100644 --- a/src/Tools/jaby_engine_fconv/src/main.rs +++ b/src/Tools/jaby_engine_fconv/src/main.rs @@ -1,7 +1,7 @@ -use jaby_engine_fconv::images::{*}; use clap::{Parser, Subcommand}; +use jaby_engine_fconv::images::*; use std::path::PathBuf; -use tool_helper::Error; +use tool_helper::{Error, exit_with_error}; #[derive(Parser)] #[clap(about = "Converts files to various JabyEngine related file formats", long_about = None)] @@ -69,7 +69,6 @@ fn run_main() -> Result<(), Error> { fn main() { if let Err(error) = run_main() { - eprintln!("{}", error.text); - std::process::exit(error.exit_code); + exit_with_error(error); } } \ No newline at end of file diff --git a/src/Tools/mkoverlay/Cargo.toml b/src/Tools/mkoverlay/Cargo.toml index 5ae6d8a8..ce960207 100644 --- a/src/Tools/mkoverlay/Cargo.toml +++ b/src/Tools/mkoverlay/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "mkoverlay" -version = "1.1.0" +version = "1.1.1" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/src/Tools/mkoverlay/src/main.rs b/src/Tools/mkoverlay/src/main.rs index 315fdfd5..f7fd6224 100644 --- a/src/Tools/mkoverlay/src/main.rs +++ b/src/Tools/mkoverlay/src/main.rs @@ -1,6 +1,7 @@ use clap::Parser; -use tool_helper::{Error, format_if_error, open_input, open_output}; +use mkoverlay::types::OverlayDesc; use std::path::PathBuf; +use tool_helper::{Error, exit_with_error, format_if_error, open_input, open_output}; #[derive(Parser)] #[clap(about = "Creates a linker script and makefile part for the JabyEngine toolchain", long_about = None)] @@ -12,12 +13,22 @@ struct CommandLine { ld_file_output: Option, #[clap(value_parser, help="Input JSON for creating the files")] - input: PathBuf + input: Option +} + +fn parse_input(input: Option) -> Result { + if let Some(input) = input { + let input = format_if_error!(open_input(Some(input)), "Opening input file failed with: {error_text}")?; + format_if_error!(mkoverlay::types::json_reader::read_config(input), "Parsing JSON file failed with: {error_text}") + } + + else { + Ok(OverlayDesc::new()) + } } fn run_main(cmd_line: CommandLine) -> Result<(), Error> { - let input = format_if_error!(open_input(Some(cmd_line.input)), "Opening input file failed with: {error_text}")?; - let input = format_if_error!(mkoverlay::types::json_reader::read_config(input), "Parsing JSON file failed with: {error_text}")?; + let input = parse_input(cmd_line.input)?; let mut mk_output = format_if_error!(open_output(cmd_line.mk_file_output), "Opening file for writing makefile failed with: {error_text}")?; let mut ld_output = format_if_error!(open_output(cmd_line.ld_file_output), "Opening file for writing linkerfile failed with: {error_text}")?; @@ -30,11 +41,11 @@ fn main() { Ok(cmd_line) => { match run_main(cmd_line) { Ok(_) => (), - Err(error) => eprintln!("{}", error) + Err(error) => exit_with_error(error) } }, Err(error) => { - eprintln!("{}", error); + exit_with_error(Error::from_error(error)); } } } \ No newline at end of file diff --git a/src/Tools/psxcdgen_ex/Cargo.toml b/src/Tools/psxcdgen_ex/Cargo.toml index 5805d87c..be3566a6 100644 --- a/src/Tools/psxcdgen_ex/Cargo.toml +++ b/src/Tools/psxcdgen_ex/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "psxcdgen_ex" -version = "0.2.0" +version = "0.2.1" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html @@ -8,6 +8,7 @@ edition = "2021" [dependencies] cdtypes = {path = "../cdtypes"} clap = {version = "*", features = ["derive"]} +colored = "*" no-comment = "*" paste = "*" roxmltree = "*" diff --git a/src/Tools/psxcdgen_ex/src/encoder/psx.rs b/src/Tools/psxcdgen_ex/src/encoder/psx.rs index bf10aef1..9d492144 100644 --- a/src/Tools/psxcdgen_ex/src/encoder/psx.rs +++ b/src/Tools/psxcdgen_ex/src/encoder/psx.rs @@ -2,6 +2,7 @@ use super::{*, SectorWriter, {CDDesc, Error}}; use super::super::types::{helper::{DirectoryRecordMember, PathTableMember}, layout::Layout, *}; use builder::SubModeBuilder; use cdtypes::types::{cdstring::{AString, DString}, date::*, dir_record::*, helper::{round_bytes_mode2_form1, sector_count_mode2_form1}, path_table::*, pvd as cd_pvd, lsb_msb::*, sector::Mode2Form1}; +use colored::*; use tool_helper::{BufferedInputFile, format_if_error, open_input_file_buffered}; use std::io::{Read, Seek, SeekFrom}; @@ -197,7 +198,8 @@ fn process_system_area(system_area: &SystemArea, sec_writer: &mut dyn SectorWrit } else { - // No license specified - filling it with zeros + // No license specified - filling it with zeros + eprintln!("{}", "WARNING: No license file provided. Some emulators (like No$PSX) will not boot this CD.".yellow()); for _ in 0..SYSTEM_AREA_SECTOR_COUNT { sec_writer.write_cd_xa_data(builder::create_xa_data_zero())?; } diff --git a/src/Tools/psxcdgen_ex/src/main.rs b/src/Tools/psxcdgen_ex/src/main.rs index 0f606515..280d2852 100644 --- a/src/Tools/psxcdgen_ex/src/main.rs +++ b/src/Tools/psxcdgen_ex/src/main.rs @@ -1,7 +1,7 @@ use clap::{Parser, ValueEnum}; use psxcdgen_ex::{encoder::{EncodingFunctions, psx::{calculate_psx_lbas, calculate_psx_length_for, encode_psx_image}}, file_writer::{ImageType, write_image}, config_reader}; -use std::{path::PathBuf, }; -use tool_helper::Error; +use std::{path::PathBuf}; +use tool_helper::{Error, exit_with_error}; #[derive(Parser)] #[clap(about = "Creates an ISO image from a description file", long_about = None)] @@ -57,11 +57,11 @@ fn main() { Ok(cmd_line) => { match run_main(cmd_line) { Ok(_) => (), - Err(error) => eprintln!("{}", error) + Err(error) => exit_with_error(error) } }, Err(error) => { - eprintln!("{}", error); + exit_with_error(Error::from_error(error)) } } } \ No newline at end of file diff --git a/src/Tools/tool_helper/Cargo.toml b/src/Tools/tool_helper/Cargo.toml index 4a0c80a7..eda5d603 100644 --- a/src/Tools/tool_helper/Cargo.toml +++ b/src/Tools/tool_helper/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "tool_helper" -version = "0.7.0" +version = "0.8.0" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html @@ -8,6 +8,7 @@ edition = "2021" [dependencies] byteorder = "*" cdtypes = {path = "../cdtypes"} +colored = "*" envmnt = "*" lz4 = "*" paste = "*" \ No newline at end of file diff --git a/src/Tools/tool_helper/src/lib.rs b/src/Tools/tool_helper/src/lib.rs index bc5bc548..59a6075c 100644 --- a/src/Tools/tool_helper/src/lib.rs +++ b/src/Tools/tool_helper/src/lib.rs @@ -1,5 +1,6 @@ -use std::{boxed::Box, io::{BufReader, BufWriter, Read, Write}, path::PathBuf}; +use colored::*; use envmnt::{ExpandOptions, ExpansionType}; +use std::{boxed::Box, io::{BufReader, BufWriter, Read, Write}, path::PathBuf}; pub mod bits; pub mod compress; @@ -79,6 +80,14 @@ impl Error { pub fn ok_or_new(option: Option, error_text: F) -> Result where F: Fn () -> String{ Ok(option.ok_or(Error::from_callback(error_text))?) } + + pub fn print_generic_to_std_err(object: &T) { + eprintln!("{}", format!("ERROR: {}", object).red()); + } + + pub fn print_to_std_err(&self) { + Self::print_generic_to_std_err(self) + } } impl std::fmt::Display for Error { @@ -105,6 +114,11 @@ impl std::convert::From for Error { } } +pub fn exit_with_error(error: Error) { + error.print_to_std_err(); + std::process::exit(error.exit_code); +} + pub fn prefix_if_error(prefix: &str, result: Result) -> Result { match result { Ok(value) => Ok(value), From 6a4c9c5e17c46dabd2a66a7ff4483b4ad91d1974 Mon Sep 17 00:00:00 2001 From: jaby Date: Sat, 22 Apr 2023 15:45:07 +0200 Subject: [PATCH 002/588] Update template with latest tools; Add install batch file for easy usage with VSCode addon --- .../#{ProjectName}.code-workspace | 24 +++++++++++---- template/JabyEngine-PSX_Game/.gitignore | 1 + .../JabyEngine-PSX_Game/application/Makefile | 4 ++- .../application/Overlays.json | 12 ++++++++ .../application/src/main.cpp | 6 ++-- template/JabyEngine-PSX_Game/iso/Config.xml | 29 +++++++------------ template/JabyEngine-PSX_Game/iso/System.cnf | 2 +- template/install.bat | 6 ++++ 8 files changed, 56 insertions(+), 28 deletions(-) create mode 100644 template/JabyEngine-PSX_Game/application/Overlays.json create mode 100644 template/install.bat diff --git a/template/JabyEngine-PSX_Game/#{ProjectName}.code-workspace b/template/JabyEngine-PSX_Game/#{ProjectName}.code-workspace index 9ee08666..1e6f6d38 100644 --- a/template/JabyEngine-PSX_Game/#{ProjectName}.code-workspace +++ b/template/JabyEngine-PSX_Game/#{ProjectName}.code-workspace @@ -11,19 +11,22 @@ { "label": "build", "type": "shell", - "command": "wsl make ${input:target} BUILD_PROFILE=${input:build profile} JABY_ENGINE_DIR=../${config:jaby_engine_path}", + "command": "wsl make ${input:target} BUILD_PROFILE=${input:build profile} JABY_ENGINE_DIR=$(wslpath ${env:JABY_ENGINE_PATH})", "group": { "kind": "build", "isDefault": true }, "options": { - "cwd": "application" + "cwd": "application", + "env": { + "PATH": "${env:JABY_ENGINE_PATH}/bin;${env:PATH}" + } } }, { "label": "cdgen", "type": "shell", - "command": "${config:jaby_engine_path}/bin/psxcdgen.exe iso/Config.xml", + "command": "${env:JABY_ENGINE_PATH}/bin/psxcdgen_ex.exe --list iso/#{ProjectName}.lba -o iso/#{ProjectName} psx bin-cue iso/Config.xml", "group": { "kind": "build", "isDefault": true @@ -46,7 +49,7 @@ "type": "pickString", "options": ["debug", "release"], "default": "release", - "description": "the build profile for #{ProjectName}" + "description": "The build profile for #{ProjectName}" }, { "id": "target", @@ -58,6 +61,17 @@ ] }, "settings": { - "jaby_engine_path": "#{JabyEnginePath}", + "C_Cpp.default.includePath": [ + "${env:JABY_ENGINE_PATH}/include" + ], + "C_Cpp.default.compilerPath": "", + "C_Cpp.default.cStandard": "c17", + "C_Cpp.default.cppStandard": "c++20", + "C_Cpp.default.intelliSenseMode": "linux-gcc-x86", + "C_Cpp.default.compilerArgs": [ + ], + "C_Cpp.default.defines": [ + "JABYENGINE_PAL" + ], } } \ No newline at end of file diff --git a/template/JabyEngine-PSX_Game/.gitignore b/template/JabyEngine-PSX_Game/.gitignore index 5fb16184..fa0401e8 100644 --- a/template/JabyEngine-PSX_Game/.gitignore +++ b/template/JabyEngine-PSX_Game/.gitignore @@ -2,4 +2,5 @@ *.cue *.d *.o +*.lba **/bin \ No newline at end of file diff --git a/template/JabyEngine-PSX_Game/application/Makefile b/template/JabyEngine-PSX_Game/application/Makefile index e05edbb7..16bd0518 100644 --- a/template/JabyEngine-PSX_Game/application/Makefile +++ b/template/JabyEngine-PSX_Game/application/Makefile @@ -1,10 +1,12 @@ ARTIFACT = #{ProjectName} BUILD_DIR = bin +#OVERLAY_CONFIG = Overlays.json + include $(JABY_ENGINE_DIR)/lib/Wildcard.mk SRCS = $(call rwildcard, src, c cpp) -LIBS = -L$(JABY_ENGINE_DIR)/lib/PSX-$(BUILD_PROFILE) -lJabyEngine +INCLUDES += -I$(JABY_ENGINE_DIR)/include include $(JABY_ENGINE_DIR)/lib/Makefile include $(JABY_ENGINE_DIR)/lib/PSEXETarget.mk diff --git a/template/JabyEngine-PSX_Game/application/Overlays.json b/template/JabyEngine-PSX_Game/application/Overlays.json new file mode 100644 index 00000000..5e779d49 --- /dev/null +++ b/template/JabyEngine-PSX_Game/application/Overlays.json @@ -0,0 +1,12 @@ +{ + "slot_0": { + "main_area": { + "pattern": "bin/*/src/MainState/*.o" + } + }, + "slot_1": { + "main_area2": { + "pattern": "bin/*/src/MainState2/*.o" + } + } +} \ No newline at end of file diff --git a/template/JabyEngine-PSX_Game/application/src/main.cpp b/template/JabyEngine-PSX_Game/application/src/main.cpp index e9cdae16..64bee7d0 100644 --- a/template/JabyEngine-PSX_Game/application/src/main.cpp +++ b/template/JabyEngine-PSX_Game/application/src/main.cpp @@ -1,3 +1,5 @@ -int main() { - return 0; +#include + +void main() { + printf("Hello Planschbecken!\n"); } \ No newline at end of file diff --git a/template/JabyEngine-PSX_Game/iso/Config.xml b/template/JabyEngine-PSX_Game/iso/Config.xml index 258c9a74..307f94fd 100644 --- a/template/JabyEngine-PSX_Game/iso/Config.xml +++ b/template/JabyEngine-PSX_Game/iso/Config.xml @@ -1,19 +1,10 @@ - - - - - - - - - - - + + + + + + + iso/System.cnf +
application/bin/PSX-release/#{ProjectName}.psexe
+ +
\ No newline at end of file diff --git a/template/JabyEngine-PSX_Game/iso/System.cnf b/template/JabyEngine-PSX_Game/iso/System.cnf index 22d980e8..bf22c6f7 100644 --- a/template/JabyEngine-PSX_Game/iso/System.cnf +++ b/template/JabyEngine-PSX_Game/iso/System.cnf @@ -1,4 +1,4 @@ -BOOT=cdrom:\SCES_003.90;1 +BOOT=cdrom:\XXXX_AAA.AA;1 TCB=4 EVENT=10 STACK=801FFFF0 \ No newline at end of file diff --git a/template/install.bat b/template/install.bat new file mode 100644 index 00000000..2a89868b --- /dev/null +++ b/template/install.bat @@ -0,0 +1,6 @@ +echo off +set dst_name=JabyEngine-PSX_Game +set dst="%APPDATA%\Code\User\ProjectTemplates\%dst_name%" + +mkdir %dst% +xcopy /s %dst_name% %dst% \ No newline at end of file From daab984faa610f5cc07075844f136f50bfa34c69 Mon Sep 17 00:00:00 2001 From: jaby Date: Tue, 25 Apr 2023 18:11:19 +0200 Subject: [PATCH 003/588] Use more generic enviroment variable name --- template/JabyEngine-PSX_Game/iso/Config.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/template/JabyEngine-PSX_Game/iso/Config.xml b/template/JabyEngine-PSX_Game/iso/Config.xml index 307f94fd..d52996a1 100644 --- a/template/JabyEngine-PSX_Game/iso/Config.xml +++ b/template/JabyEngine-PSX_Game/iso/Config.xml @@ -1,7 +1,7 @@ - + iso/System.cnf From a1ca69094ec1e0ecee559c1d1beb1ac1a9f0a5cc Mon Sep 17 00:00:00 2001 From: jaby Date: Tue, 25 Apr 2023 18:12:42 +0200 Subject: [PATCH 004/588] Create PoolBox project --- examples/PoolBox/.gitignore | 6 ++ examples/PoolBox/PoolBox.code-workspace | 77 ++++++++++++++++++++++ examples/PoolBox/application/Makefile | 17 +++++ examples/PoolBox/application/Overlays.json | 12 ++++ examples/PoolBox/application/src/main.cpp | 5 ++ examples/PoolBox/iso/Config.xml | 10 +++ examples/PoolBox/iso/System.cnf | 4 ++ 7 files changed, 131 insertions(+) create mode 100644 examples/PoolBox/.gitignore create mode 100644 examples/PoolBox/PoolBox.code-workspace create mode 100644 examples/PoolBox/application/Makefile create mode 100644 examples/PoolBox/application/Overlays.json create mode 100644 examples/PoolBox/application/src/main.cpp create mode 100644 examples/PoolBox/iso/Config.xml create mode 100644 examples/PoolBox/iso/System.cnf diff --git a/examples/PoolBox/.gitignore b/examples/PoolBox/.gitignore new file mode 100644 index 00000000..fa0401e8 --- /dev/null +++ b/examples/PoolBox/.gitignore @@ -0,0 +1,6 @@ +*.bin +*.cue +*.d +*.o +*.lba +**/bin \ No newline at end of file diff --git a/examples/PoolBox/PoolBox.code-workspace b/examples/PoolBox/PoolBox.code-workspace new file mode 100644 index 00000000..b7f04eff --- /dev/null +++ b/examples/PoolBox/PoolBox.code-workspace @@ -0,0 +1,77 @@ +{ + "folders": [ + { + "path": ".", + "name": "PoolBox" + } + ], + "tasks": { + "version": "2.0.0", + "tasks": [ + { + "label": "build", + "type": "shell", + "command": "wsl make ${input:target} BUILD_PROFILE=${input:build profile} JABY_ENGINE_DIR=$(wslpath ${env:JABY_ENGINE_PATH})", + "group": { + "kind": "build", + "isDefault": true + }, + "options": { + "cwd": "application", + "env": { + "PATH": "${env:JABY_ENGINE_PATH}/bin;${env:PATH}" + } + } + }, + { + "label": "cdgen", + "type": "shell", + "command": "${env:JABY_ENGINE_PATH}/bin/psxcdgen_ex.exe --list iso/PoolBox.lba -o iso/PoolBox psx bin-cue iso/Config.xml", + "group": { + "kind": "build", + "isDefault": true + } + }, + { + "label": "build & generate cd", + "type": "shell", + "dependsOn": ["build", "cdgen"], + "dependsOrder": "sequence", + "group": { + "kind": "build", + "isDefault": true + } + } + ], + "inputs": [ + { + "id": "build profile", + "type": "pickString", + "options": ["debug", "release"], + "default": "release", + "description": "The build profile for PoolBox" + }, + { + "id": "target", + "type": "pickString", + "options": ["all", "clean", "rebuild"], + "default": "all", + "description": "the build target" + } + ] + }, + "settings": { + "C_Cpp.default.includePath": [ + "${env:JABY_ENGINE_PATH}/include" + ], + "C_Cpp.default.compilerPath": "", + "C_Cpp.default.cStandard": "c17", + "C_Cpp.default.cppStandard": "c++20", + "C_Cpp.default.intelliSenseMode": "linux-gcc-x86", + "C_Cpp.default.compilerArgs": [ + ], + "C_Cpp.default.defines": [ + "JABYENGINE_PAL" + ], + } +} \ No newline at end of file diff --git a/examples/PoolBox/application/Makefile b/examples/PoolBox/application/Makefile new file mode 100644 index 00000000..efec30b8 --- /dev/null +++ b/examples/PoolBox/application/Makefile @@ -0,0 +1,17 @@ +ARTIFACT = PoolBox +BUILD_DIR = bin + +#OVERLAY_CONFIG = Overlays.json + +include $(JABY_ENGINE_DIR)/lib/Wildcard.mk +SRCS = $(call rwildcard, src, c cpp) + +INCLUDES += -I$(JABY_ENGINE_DIR)/include + +include $(JABY_ENGINE_DIR)/lib/Makefile +include $(JABY_ENGINE_DIR)/lib/PSEXETarget.mk + +clean: + rm -fr $(OUTPUT_DIR) + rm -fr ../iso/*.bin + rm -fr ../iso/*.cue \ No newline at end of file diff --git a/examples/PoolBox/application/Overlays.json b/examples/PoolBox/application/Overlays.json new file mode 100644 index 00000000..5e779d49 --- /dev/null +++ b/examples/PoolBox/application/Overlays.json @@ -0,0 +1,12 @@ +{ + "slot_0": { + "main_area": { + "pattern": "bin/*/src/MainState/*.o" + } + }, + "slot_1": { + "main_area2": { + "pattern": "bin/*/src/MainState2/*.o" + } + } +} \ No newline at end of file diff --git a/examples/PoolBox/application/src/main.cpp b/examples/PoolBox/application/src/main.cpp new file mode 100644 index 00000000..64bee7d0 --- /dev/null +++ b/examples/PoolBox/application/src/main.cpp @@ -0,0 +1,5 @@ +#include + +void main() { + printf("Hello Planschbecken!\n"); +} \ No newline at end of file diff --git a/examples/PoolBox/iso/Config.xml b/examples/PoolBox/iso/Config.xml new file mode 100644 index 00000000..9c58e342 --- /dev/null +++ b/examples/PoolBox/iso/Config.xml @@ -0,0 +1,10 @@ + + + Jaby + %PSX_LICENSE_PATH%/LICENSEE.DAT + + + iso/System.cnf +
application/bin/PSX-release/PoolBox.psexe
+ +
\ No newline at end of file diff --git a/examples/PoolBox/iso/System.cnf b/examples/PoolBox/iso/System.cnf new file mode 100644 index 00000000..bf22c6f7 --- /dev/null +++ b/examples/PoolBox/iso/System.cnf @@ -0,0 +1,4 @@ +BOOT=cdrom:\XXXX_AAA.AA;1 +TCB=4 +EVENT=10 +STACK=801FFFF0 \ No newline at end of file From 9dc25e469cf874eacb84beacbcd2e696458813c8 Mon Sep 17 00:00:00 2001 From: jaby Date: Wed, 26 Apr 2023 19:09:07 +0200 Subject: [PATCH 005/588] Add busy loop code and make HighResTimer work on demand rather automatically or ifdefed --- include/PSX/Timer/high_res_timer.hpp | 87 ++++++++++++----------- include/PSX/jabyengine_config.hpp | 8 --- include/PSX/jabyengine_defines.h | 1 - lib/Makefile | 10 +-- src/Library/Makefile | 3 +- src/Library/src/BootLoader/start_boot.cpp | 5 -- src/Library/src/BootLoader/timer_boot.cpp | 62 +++++++--------- src/Library/src/Timer/high_res_timer.cpp | 60 ++++++++-------- src/Library/src/busyloop.s | 26 +++++++ src/Library/src/syscall_printf.s | 2 +- 10 files changed, 131 insertions(+), 133 deletions(-) delete mode 100644 include/PSX/jabyengine_config.hpp create mode 100644 src/Library/src/busyloop.s diff --git a/include/PSX/Timer/high_res_timer.hpp b/include/PSX/Timer/high_res_timer.hpp index 9ae8141d..1621838f 100644 --- a/include/PSX/Timer/high_res_timer.hpp +++ b/include/PSX/Timer/high_res_timer.hpp @@ -1,6 +1,7 @@ #ifndef __JABYENGINE_HIGH_RES_TIMER_HPP__ #define __JABYENGINE_HIGH_RES_TIMER_HPP__ #include "../jabyengine_defines.h" +#include #include namespace JabyEngine { @@ -24,51 +25,57 @@ namespace JabyEngine { } }; - #ifdef JABYENGINE_USE_HIGH_PERCISION_TIMER - class HighResTime { - public: - class TimeStamp { - private: - uint16_t counter_10ms_value; - uint16_t fraction; - - constexpr TimeStamp(uint16_t counter_10ms_value, uint16_t fraction) : counter_10ms_value(counter_10ms_value), fraction(fraction) { - } - - constexpr static size_t to_us(uint16_t counter_10ms_value, uint16_t fraction) { - return counter_10ms_value*(10*1000) + ((fraction/HighResTime::TicksFor100us)*100); - } - - constexpr static size_t to_ms(uint16_t counter_10ms_value, uint16_t fraction) { - return counter_10ms_value*10 + (fraction/HighResTime::TicksFor1ms); - } - - public: - constexpr size_t microseconds_to(const TimeStamp& end) const { - return TimeStamp::to_us((end.counter_10ms_value - this->counter_10ms_value), (end.fraction - this->fraction)); - } - - constexpr size_t milliseconds_to(const TimeStamp& end) const { - return TimeStamp::to_ms((end.counter_10ms_value - this->counter_10ms_value), (end.fraction - this->fraction)); - } - friend class HighResTime; - }; - + class HighResTime { + public: + class TimeStamp { private: - static constexpr uint16_t TicksFor100us = CPUTicks::ticks_per_us(CPUTicks::Frequency_Hz_Div8, 100.0); - static constexpr uint16_t TicksFor1ms = CPUTicks::ticks_per_ms(CPUTicks::Frequency_Hz_Div8, 1.0); - static constexpr uint16_t TicksFor10ms = CPUTicks::ticks_per_ms(CPUTicks::Frequency_Hz_Div8, 10.0); + uint16_t counter_10ms_value; + uint16_t fraction; - static volatile uint16_t global_counter_10ms; + constexpr TimeStamp(uint16_t counter_10ms_value, uint16_t fraction) : counter_10ms_value(counter_10ms_value), fraction(fraction) { + } + + constexpr static size_t to_us(uint16_t counter_10ms_value, uint16_t fraction) { + return counter_10ms_value*(10*1000) + ((fraction/HighResTime::TicksFor100us)*100); + } + + constexpr static size_t to_ms(uint16_t counter_10ms_value, uint16_t fraction) { + return counter_10ms_value*10 + (fraction/HighResTime::TicksFor1ms); + } public: - HighResTime() = delete; - ~HighResTime() = delete; - - static TimeStamp get_time_stamp() { - return TimeStamp(HighResTime::global_counter_10ms, Timer_IO::Counter2.get_current_value()); + constexpr size_t microseconds_to(const TimeStamp& end) const { + return TimeStamp::to_us((end.counter_10ms_value - this->counter_10ms_value), (end.fraction - this->fraction)); } + + constexpr size_t milliseconds_to(const TimeStamp& end) const { + return TimeStamp::to_ms((end.counter_10ms_value - this->counter_10ms_value), (end.fraction - this->fraction)); + } + friend class HighResTime; }; - #endif //JABYENGINE_USE_HIGH_PERCISION_TIMER + + private: + static constexpr uint16_t TicksFor100us = CPUTicks::ticks_per_us(CPUTicks::Frequency_Hz_Div8, 100.0); + static constexpr uint16_t TicksFor1ms = CPUTicks::ticks_per_ms(CPUTicks::Frequency_Hz_Div8, 1.0); + static constexpr uint16_t TicksFor10ms = CPUTicks::ticks_per_ms(CPUTicks::Frequency_Hz_Div8, 10.0); + + static volatile uint16_t global_counter_10ms; + + public: + HighResTime() = delete; + ~HighResTime() = delete; + + static void enable() { + Interrupt::enable_irq(Interrupt::Timer2); + } + + static void disable() { + Interrupt::disable_irq(Interrupt::Timer2); + } + + static TimeStamp get_time_stamp() { + return TimeStamp(HighResTime::global_counter_10ms, Timer_IO::Counter2.get_current_value()); + } + }; } #endif //!__JABYENGINE_HIGH_RES_TIMER_HPP__ \ No newline at end of file diff --git a/include/PSX/jabyengine_config.hpp b/include/PSX/jabyengine_config.hpp deleted file mode 100644 index 5d2ed50d..00000000 --- a/include/PSX/jabyengine_config.hpp +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef __JABYENGINE_CONFIG_HPP__ -#define __JABYENGINE_CONFIG_HPP__ - #ifdef USE_CUSTOM_CONFIG - #include - #else - #define JABYENGINE_USE_HIGH_PERCISION_TIMER - #endif //USE_CUSTOM_CONFIG -#endif //!__JABYENGINE_CONFIG_HPP__ \ No newline at end of file diff --git a/include/PSX/jabyengine_defines.h b/include/PSX/jabyengine_defines.h index 8c838cb7..224f1708 100644 --- a/include/PSX/jabyengine_defines.h +++ b/include/PSX/jabyengine_defines.h @@ -1,6 +1,5 @@ #ifndef __JABYENGINE_DEFINES__H__ #define __JABYENGINE_DEFINES__H__ -#include "jabyengine_config.hpp" #include "../stddef.h" #define __used __attribute__((used)) diff --git a/lib/Makefile b/lib/Makefile index 5b262c51..b0d342f8 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -46,11 +46,7 @@ CCFLAGS_debug += -O0 CXXFLAGS += -fno-exceptions -fno-rtti -USE_FUNCTION_SECTIONS ?= true -ifeq ($(USE_FUNCTION_SECTIONS),true) -CCFLAGS += -ffunction-sections -endif -CCFLAGS += -mno-gpopt -fomit-frame-pointer +CCFLAGS += -mno-gpopt -fomit-frame-pointer -ffunction-sections CCFLAGS += -fno-builtin -fno-strict-aliasing -Wno-attributes CCFLAGS += -std=c++20 CCFLAGS += $(ARCHFLAGS) @@ -76,11 +72,11 @@ OBJS = $(addprefix $(OUTPUT_DIR)/,$(addsuffix .o, $(subst ..,!super,$(basename $ #Compiling rule $(OUTPUT_DIR)/%.o: %.s @mkdir -p $(dir $@) - $(CC) -c $(DEPS) -o $@ $(CCFLAGS) $(CCFLAGS) $< + $(CC) -c $(DEPS) -o $@ $(CCFLAGS) $< $(OUTPUT_DIR)/%.o: %.c @mkdir -p $(dir $@) - $(CC) -c $(DEPS) -o $@ $(CCFLAGS) $(CCFLAGS) $< + $(CC) -c $(DEPS) -o $@ $(CCFLAGS) $< $(OUTPUT_DIR)/%.o: %.cpp @mkdir -p $(dir $@) diff --git a/src/Library/Makefile b/src/Library/Makefile index 4183fabe..d4563cd1 100644 --- a/src/Library/Makefile +++ b/src/Library/Makefile @@ -10,8 +10,7 @@ CCFLAGS += -Iinclude -I../../include CCFLAGS += -save-temps=obj include ../../lib/Wildcard.mk -SRCS = $(call rwildcard, src, c cpp) -SRCS += src/syscall_printf.asm +SRCS = $(call rwildcard, src, c cpp s) include ../../lib/Makefile LIB_DIR = ../../lib/$(CONFIG_NAME) diff --git a/src/Library/src/BootLoader/start_boot.cpp b/src/Library/src/BootLoader/start_boot.cpp index 111c5fbf..cc0e4629 100644 --- a/src/Library/src/BootLoader/start_boot.cpp +++ b/src/Library/src/BootLoader/start_boot.cpp @@ -21,15 +21,10 @@ namespace JabyEngine { CD::setup(); Timer::setup(); - const auto start = HighResTime::get_time_stamp(); - printf("Start...\n"); GPU::setup(); GPU::display_logo(); - const auto end = HighResTime::get_time_stamp(); - printf("GPU setup took %ims %ius\n", start.milliseconds_to(end), start.microseconds_to(end)); //Pause?? - SPU::setup(); } } diff --git a/src/Library/src/BootLoader/timer_boot.cpp b/src/Library/src/BootLoader/timer_boot.cpp index 201e41ba..c0a8a492 100644 --- a/src/Library/src/BootLoader/timer_boot.cpp +++ b/src/Library/src/BootLoader/timer_boot.cpp @@ -1,46 +1,34 @@ -#include -#ifdef JABYENGINE_USE_HIGH_PERCISION_TIMER - #include - #include - #define private public - #include - #undef private +#include +#include +#define private public +#include +#undef private - namespace JabyEngine { +namespace JabyEngine { + namespace Timer { + extern InterrupCallback IRQCallback; + } + + namespace boot { namespace Timer { - extern InterrupCallback IRQCallback; - } + using namespace JabyEngine::Timer; + + void setup() { + using namespace Timer_IO; - namespace boot { - namespace Timer { - using namespace JabyEngine::Timer; - - void setup() { - using namespace Timer_IO; + static constexpr auto Mode = CounterMode_t::from(CounterMode_t::FreeRun, Counter2_v::SyncMode::FreeRun, CounterMode_t::ResetAfterTarget, CounterMode_t::IRQAtTarget, CounterMode_t::IRQEveryTime, CounterMode_t::IRQPulse, Counter2_v::Source::System_Clock_Div_8); - static constexpr auto Mode = CounterMode_t::from(CounterMode_t::FreeRun, Counter2_v::SyncMode::FreeRun, CounterMode_t::ResetAfterTarget, CounterMode_t::IRQAtTarget, CounterMode_t::IRQEveryTime, CounterMode_t::IRQPulse, Counter2_v::Source::System_Clock_Div_8); + // We disable the IRQ here so it can be enabled by user demand later + // Having the interrupt fire every 10ms will slow us down slightly so we only do it on demand + Interrupt::disable_irq(Interrupt::Timer2); - Interrupt::disable_irq(Interrupt::Timer2); + __syscall_EnterCriticalSection(); + __syscall_SysEnqIntRP(Timer2Irq, &IRQCallback); + __syscall_ExitCriticalSection(); - __syscall_EnterCriticalSection(); - __syscall_SysEnqIntRP(Timer2Irq, &IRQCallback); - __syscall_ExitCriticalSection(); - - Counter2.set_target_value(HighResTime::TicksFor10ms); - Counter2.set_mode(Mode); - - Interrupt::enable_irq(Interrupt::Timer2); - } + Counter2.set_target_value(HighResTime::TicksFor10ms); + Counter2.set_mode(Mode); } } } -#else - namespace JabyEngine { - namespace boot { - namespace Timer { - void setup() { - } - } - } - } -#endif //JABYENGINE_USE_HIGH_PERCISION_TIMER \ No newline at end of file +} \ No newline at end of file diff --git a/src/Library/src/Timer/high_res_timer.cpp b/src/Library/src/Timer/high_res_timer.cpp index 7a7fd3d9..45f5d650 100644 --- a/src/Library/src/Timer/high_res_timer.cpp +++ b/src/Library/src/Timer/high_res_timer.cpp @@ -1,38 +1,34 @@ -#include -#ifdef JABYENGINE_USE_HIGH_PERCISION_TIMER - #define private public - #include - #include - #include - #include - #undef private +#define private public +#include +#include +#include +#undef private - namespace JabyEngine { - volatile uint16_t HighResTime :: global_counter_10ms = 0; +namespace JabyEngine { + volatile uint16_t HighResTime :: global_counter_10ms = 0; - namespace Timer { - static InterruptVerifierResult interrupt_verifier() { - if(Interrupt::is_irq(Interrupt::Timer2)) { - return InterruptVerifierResult::ExecuteHandler; - } - - else { - return InterruptVerifierResult::SkipHandler; - } + namespace Timer { + static InterruptVerifierResult interrupt_verifier() { + if(Interrupt::is_irq(Interrupt::Timer2)) { + return InterruptVerifierResult::ExecuteHandler; } - - static void interrupt_handler(uint32_t) { - HighResTime::global_counter_10ms = HighResTime::global_counter_10ms + 1; - - Interrupt::ack_irq(Interrupt::Timer2); - __syscall_ReturnFromException(); + + else { + return InterruptVerifierResult::SkipHandler; } - - InterrupCallback IRQCallback = { - .next = nullptr, - .handler_function = reinterpret_cast(interrupt_handler), - .verifier_function = interrupt_verifier - }; } + + static void interrupt_handler(uint32_t) { + HighResTime::global_counter_10ms = HighResTime::global_counter_10ms + 1; + + Interrupt::ack_irq(Interrupt::Timer2); + __syscall_ReturnFromException(); + } + + InterrupCallback IRQCallback = { + .next = nullptr, + .handler_function = reinterpret_cast(interrupt_handler), + .verifier_function = interrupt_verifier + }; } -#endif //JABYENGINE_USE_HIGH_PERCISION_TIMER \ No newline at end of file +} \ No newline at end of file diff --git a/src/Library/src/busyloop.s b/src/Library/src/busyloop.s new file mode 100644 index 00000000..91e5daad --- /dev/null +++ b/src/Library/src/busyloop.s @@ -0,0 +1,26 @@ + .set noreorder + .section .text, "ax", @progbits + .align 2 + .global busy_loop + .type busy_loop, @function + +busy_loop: + sw $a0, 0($sp) + lw $v0, 0($sp) + lw $v1, 0($sp) + nop + addiu $v1, -1 + beqz $v0, early_exit + sw $v1, 0($sp) + +busy_loop_loop: + lw $v0, 0($sp) + lw $v1, 0($sp) + nop + addiu $v1, -1 + bnez $v0, busy_loop_loop + sw $v1, 0($sp) + +early_exit: + jr $ra + nop diff --git a/src/Library/src/syscall_printf.s b/src/Library/src/syscall_printf.s index 08d7c540..eaf86b84 100644 --- a/src/Library/src/syscall_printf.s +++ b/src/Library/src/syscall_printf.s @@ -1,6 +1,6 @@ .set push .set noreorder -#.section .ramtext, "ax", @progbits + .section .text, "ax", @progbits .align 2 .global __syscall_printf .type __syscall_printf, @function From 7845ac2034796400d6c6b24271707b48abd14439 Mon Sep 17 00:00:00 2001 From: jaby Date: Wed, 26 Apr 2023 19:09:49 +0200 Subject: [PATCH 006/588] Measure the busy loop for real hardware later --- examples/PoolBox/application/src/main.cpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/examples/PoolBox/application/src/main.cpp b/examples/PoolBox/application/src/main.cpp index 64bee7d0..0ce2fba7 100644 --- a/examples/PoolBox/application/src/main.cpp +++ b/examples/PoolBox/application/src/main.cpp @@ -1,5 +1,21 @@ +#include #include +extern "C" void busy_loop(int count); + +static void mesaure_busy_loop() { + static constexpr auto Counts = 500; + + JabyEngine::HighResTime::enable(); + const auto start = JabyEngine::HighResTime::get_time_stamp(); + busy_loop(Counts); + const auto end = JabyEngine::HighResTime::get_time_stamp(); + JabyEngine::HighResTime::disable(); + + printf("Busy loop of %i took %ims %ins\n", Counts, start.milliseconds_to(end), start.microseconds_to(end)); +} + void main() { printf("Hello Planschbecken!\n"); + mesaure_busy_loop(); } \ No newline at end of file From f5663834676a70eb8e8d601615a0d74dbdd0784c Mon Sep 17 00:00:00 2001 From: jaby Date: Wed, 26 Apr 2023 20:42:44 +0200 Subject: [PATCH 007/588] Cleanup GPU code more --- include/PSX/GPU/gpu.hpp | 6 ++--- .../internal-include/GPU/gpu_internal.hpp | 27 +++++++++---------- src/Library/src/BootLoader/gpu_boot.cpp | 10 +++++-- src/Library/src/GPU/gpu.cpp | 21 +++++---------- 4 files changed, 28 insertions(+), 36 deletions(-) diff --git a/include/PSX/GPU/gpu.hpp b/include/PSX/GPU/gpu.hpp index 6f026a8f..af26db57 100644 --- a/include/PSX/GPU/gpu.hpp +++ b/include/PSX/GPU/gpu.hpp @@ -21,6 +21,8 @@ namespace JabyEngine { static constexpr size_t Height = 240; #endif + static uint8_t current_id; + static void enable() { GPU_IO::GP1 = GPU_IO::Command::SetDisplayState(GPU_IO::DisplayState::On); } @@ -28,10 +30,6 @@ namespace JabyEngine { static void disable() { GPU_IO::GP1 = GPU_IO::Command::SetDisplayState(GPU_IO::DisplayState::Off); } - }; - - struct Screen { - static uint8_t CurrentDisplayAreaID; static void set_offset(uint16_t x, uint16_t y); }; diff --git a/src/Library/internal-include/GPU/gpu_internal.hpp b/src/Library/internal-include/GPU/gpu_internal.hpp index 9903400b..1b04be47 100644 --- a/src/Library/internal-include/GPU/gpu_internal.hpp +++ b/src/Library/internal-include/GPU/gpu_internal.hpp @@ -7,22 +7,19 @@ namespace JabyEngine { namespace GPU { namespace internal { - struct Screen { - static void configurate() { - static constexpr uint16_t FirstVisiblePixelH = 0x260; + struct Display { + typedef ::JabyEngine::GPU::Display PublicDisplay; - #ifdef JABYENGINE_PAL - static constexpr uint16_t FirstVisiblePixelV = 0xA3; - - GPU_IO::GP1 = GPU_IO::Command::DisplayMode(GPU_IO::DisplayMode_t::PAL()); - GPU::Screen::set_offset(0, 0); - #else - static constexpr uint16_t FirstVisiblePixelV = 0x88; - - GPU_IO::GP1 = GPU_IO::Command::DisplayMode(GPU_IO::DisplayMode_t::NTSC()); - GPU::Screen::set_offset(0, 5); //< Random values - #endif - } + static constexpr auto Width = PublicDisplay::Width; + static constexpr auto Height = PublicDisplay::Height; + + #ifdef JABYENGINE_PAL + static constexpr auto DisplayMode = GPU_IO::DisplayMode_t::PAL(); + static constexpr uint16_t ScanlinesV = 288; + #else + static constexpr auto DisplayMode = GPU_IO::DisplayMode_t::NTSC(); + static constexpr uint16_t ScanlinesV = 240; + #endif //JABYENGINE_PAL static void exchange_buffer_and_display(); }; diff --git a/src/Library/src/BootLoader/gpu_boot.cpp b/src/Library/src/BootLoader/gpu_boot.cpp index 5f38475e..4720d0f9 100644 --- a/src/Library/src/BootLoader/gpu_boot.cpp +++ b/src/Library/src/BootLoader/gpu_boot.cpp @@ -16,6 +16,12 @@ namespace JabyEngine { namespace boot { namespace GPU { using namespace JabyEngine::GPU; + + static void configurate_display() { + // Ideal I hope that an offset of 0,0 will produce a well enough centered picture for every TV + GPU_IO::GP1 = GPU_IO::Command::DisplayMode(internal::Display::DisplayMode); + GPU::Display::set_offset(0, 0); + } static size_t decompress_logo() { LZ4Decompressor lz4_decomp(reinterpret_cast(&__boot_loader_end)); @@ -50,8 +56,8 @@ namespace JabyEngine { void setup() { GPU_IO::GP1 = GPU_IO::Command::Reset(); - internal::Screen::configurate(); - internal::Screen::exchange_buffer_and_display(); + configurate_display(); + internal::Display::exchange_buffer_and_display(); GPU::internal::wait_ready_for_CMD(); GPU::internal::quick_fill_fast(Color24::Black(), PositionU16(32, 0), SizeU16(Display::Width, Display::Height)); diff --git a/src/Library/src/GPU/gpu.cpp b/src/Library/src/GPU/gpu.cpp index b4004e80..8597cfeb 100644 --- a/src/Library/src/GPU/gpu.cpp +++ b/src/Library/src/GPU/gpu.cpp @@ -2,26 +2,18 @@ namespace JabyEngine { namespace GPU { - uint8_t Screen :: CurrentDisplayAreaID = 1; //< Setup will call exchange and set it to 0 + uint8_t Display :: current_id = 1; //< Setup will call exchange and set it to 0 namespace internal { - typedef ::JabyEngine::GPU::Screen PublicScreenClass; - - #ifdef JABYENGINE_PAL - static constexpr uint16_t ScanlinesV = 288; - #else - static constexpr uint16_t ScanlinesV = 240; - #endif //JABYENGINE_PAL - - void Screen :: exchange_buffer_and_display() { - GPU::internal::set_draw_area(0, (Display::Height*PublicScreenClass::CurrentDisplayAreaID)); - PublicScreenClass::CurrentDisplayAreaID ^= 1; - GPU_IO::GP1 = GPU_IO::Command::DisplayArea(0, (Display::Height*PublicScreenClass::CurrentDisplayAreaID)); + void Display :: exchange_buffer_and_display() { + GPU::internal::set_draw_area(0, (PublicDisplay::Height*PublicDisplay::current_id)); + PublicDisplay::current_id ^= 1; + GPU_IO::GP1 = GPU_IO::Command::DisplayArea(0, (PublicDisplay::Height*PublicDisplay::current_id)); } } #ifndef USE_NO$PSX - void Screen :: set_offset(uint16_t x, uint16_t y) { + void Display :: set_offset(uint16_t x, uint16_t y) { x += 78; y += 43; @@ -35,5 +27,4 @@ namespace JabyEngine { } #endif //USE_NO$PSX } - } \ No newline at end of file From a2c735f1584a846ee3f59ce0f4688c8d4ec68f2c Mon Sep 17 00:00:00 2001 From: jaby Date: Wed, 26 Apr 2023 22:06:47 +0200 Subject: [PATCH 008/588] Create a frame rate --- examples/PoolBox/application/src/main.cpp | 8 ++- include/PSX/GPU/gpu.hpp | 2 + .../internal-include/GPU/gpu_internal.hpp | 2 + src/Library/src/BootLoader/cd_boot.cpp | 1 + src/Library/src/BootLoader/gpu_boot.cpp | 14 ++++- src/Library/src/BootLoader/start_boot.cpp | 8 ++- src/Library/src/GPU/gpu.cpp | 52 ++++++++++++++++++- 7 files changed, 79 insertions(+), 8 deletions(-) diff --git a/examples/PoolBox/application/src/main.cpp b/examples/PoolBox/application/src/main.cpp index 0ce2fba7..d5ddf32b 100644 --- a/examples/PoolBox/application/src/main.cpp +++ b/examples/PoolBox/application/src/main.cpp @@ -1,4 +1,5 @@ #include +#include #include extern "C" void busy_loop(int count); @@ -16,6 +17,11 @@ static void mesaure_busy_loop() { } void main() { - printf("Hello Planschbecken!\n"); + printf("Hello PoolBox!\n"); mesaure_busy_loop(); + + while(true) { + printf("Doing stuff...\n"); + JabyEngine::GPU::swap_buffers_vsync(2); + } } \ No newline at end of file diff --git a/include/PSX/GPU/gpu.hpp b/include/PSX/GPU/gpu.hpp index af26db57..c864052c 100644 --- a/include/PSX/GPU/gpu.hpp +++ b/include/PSX/GPU/gpu.hpp @@ -33,6 +33,8 @@ namespace JabyEngine { static void set_offset(uint16_t x, uint16_t y); }; + + uint8_t swap_buffers_vsync(uint8_t syncs); } } #endif //!__JABYENGINE_GPU_HPP__ \ No newline at end of file diff --git a/src/Library/internal-include/GPU/gpu_internal.hpp b/src/Library/internal-include/GPU/gpu_internal.hpp index 1b04be47..68c1d03d 100644 --- a/src/Library/internal-include/GPU/gpu_internal.hpp +++ b/src/Library/internal-include/GPU/gpu_internal.hpp @@ -24,6 +24,8 @@ namespace JabyEngine { static void exchange_buffer_and_display(); }; + void wait_vsync(uint8_t syncs); + static void set_draw_area(uint16_t x, uint16_t y) { GPU_IO::GP0 = GPU_IO::Command::DrawAreaTopLeft(x, y); GPU_IO::GP0 = GPU_IO::Command::DrawAreaBottomRight((x + Display::Width), (y + Display::Height)); diff --git a/src/Library/src/BootLoader/cd_boot.cpp b/src/Library/src/BootLoader/cd_boot.cpp index 24da5b48..b10ae087 100644 --- a/src/Library/src/BootLoader/cd_boot.cpp +++ b/src/Library/src/BootLoader/cd_boot.cpp @@ -10,6 +10,7 @@ namespace JabyEngine { extern InterrupCallback callback; } } + namespace boot { namespace CD { using JabyEngine::CD::internal::Command; diff --git a/src/Library/src/BootLoader/gpu_boot.cpp b/src/Library/src/BootLoader/gpu_boot.cpp index 4720d0f9..22390d12 100644 --- a/src/Library/src/BootLoader/gpu_boot.cpp +++ b/src/Library/src/BootLoader/gpu_boot.cpp @@ -1,6 +1,7 @@ #include "../../internal-include/GPU/gpu_internal.hpp" -#include +#include #include +#include #include #include @@ -13,6 +14,12 @@ extern "C" uint32_t __boot_loader_end; namespace JabyEngine { + namespace GPU { + namespace internal { + extern InterrupCallback callback; + } + } + namespace boot { namespace GPU { using namespace JabyEngine::GPU; @@ -61,6 +68,11 @@ namespace JabyEngine { GPU::internal::wait_ready_for_CMD(); GPU::internal::quick_fill_fast(Color24::Black(), PositionU16(32, 0), SizeU16(Display::Width, Display::Height)); + + __syscall_EnterCriticalSection(); + __syscall_SysEnqIntRP(VblankIrq, &::JabyEngine::GPU::internal::callback); + Interrupt::enable_irq(Interrupt::VBlank); + __syscall_ExitCriticalSection(); } } } diff --git a/src/Library/src/BootLoader/start_boot.cpp b/src/Library/src/BootLoader/start_boot.cpp index cc0e4629..11fb9a3a 100644 --- a/src/Library/src/BootLoader/start_boot.cpp +++ b/src/Library/src/BootLoader/start_boot.cpp @@ -1,14 +1,11 @@ #include "../../internal-include/BootLoader/boot_loader.hpp" -#include - -// 2x For setup timing -#include +#include "../../internal-include/GPU/gpu_internal.hpp" +#include #include namespace JabyEngine { namespace boot { namespace Start { - //This should become part of the bootloader later static void enable_DMA() { DMA_IO::DPCR = DMA_IO::DPCR_t(DMA_IO::DPCR).set(DMA_IO::DPCR_t::SPUEnable).set(DMA_IO::DPCR_t::GPUEnable).set(DMA_IO::DPCR_t::CDROMEnable); } @@ -35,6 +32,7 @@ namespace JabyEngine { boot::Start::setup(); printf("Running main...\n"); + GPU::internal::wait_vsync(0); run(); } } \ No newline at end of file diff --git a/src/Library/src/GPU/gpu.cpp b/src/Library/src/GPU/gpu.cpp index 8597cfeb..94ffa438 100644 --- a/src/Library/src/GPU/gpu.cpp +++ b/src/Library/src/GPU/gpu.cpp @@ -1,15 +1,58 @@ #include "../../internal-include/GPU/gpu_internal.hpp" +#include +#include namespace JabyEngine { namespace GPU { uint8_t Display :: current_id = 1; //< Setup will call exchange and set it to 0 namespace internal { + static uint8_t vsync_count = 0; + + static InterruptVerifierResult interrupt_verifier(); + static void interrupt_handler(uint32_t); + + InterrupCallback callback = { + .next = nullptr, + .handler_function = reinterpret_cast(interrupt_handler), + .verifier_function = interrupt_verifier + }; + + static InterruptVerifierResult interrupt_verifier() { + if(Interrupt::is_irq(Interrupt::VBlank)) { + return InterruptVerifierResult::ExecuteHandler; + } + + else { + return InterruptVerifierResult::SkipHandler; + } + } + + static void interrupt_handler(uint32_t) { + if(vsync_count != 0xFF) { + vsync_count++; + } + + Interrupt::ack_irq(Interrupt::VBlank); + __syscall_ReturnFromException(); + } + void Display :: exchange_buffer_and_display() { GPU::internal::set_draw_area(0, (PublicDisplay::Height*PublicDisplay::current_id)); PublicDisplay::current_id ^= 1; GPU_IO::GP1 = GPU_IO::Command::DisplayArea(0, (PublicDisplay::Height*PublicDisplay::current_id)); } + + void wait_vsync(uint8_t syncs) { + volatile uint8_t& vsync_count = reinterpret_cast(internal::vsync_count); + + if(internal::vsync_count >= syncs) { + syncs = internal::vsync_count + 1; + } + + while(vsync_count < syncs); + vsync_count = 0; + } } #ifndef USE_NO$PSX @@ -21,10 +64,17 @@ namespace JabyEngine { GPU_IO::GP1 = GPU_IO::Command::VerticalDisplayRange(y, y + Display::Height); } #else - void Screen :: set_offset(uint16_t x, uint16_t y) { + void Display :: set_offset(uint16_t x, uint16_t y) { GPU_IO::GP1 = GPU_IO::Command::HorizontalDisplayRange(x, (x + Display::Width*8)); GPU_IO::GP1 = GPU_IO::Command::VerticalDisplayRange(y - (ScanlinesV/2), y + (ScanlinesV/2)); } #endif //USE_NO$PSX + + uint8_t swap_buffers_vsync(uint8_t syncs) { + // Wait finish draw + internal::wait_vsync(syncs); + internal::Display::exchange_buffer_and_display(); + return Display::current_id; + } } } \ No newline at end of file From 49a6873ad5fac71c8c3c0baddb621e36002277f9 Mon Sep 17 00:00:00 2001 From: jaby Date: Wed, 26 Apr 2023 22:07:38 +0200 Subject: [PATCH 009/588] Remove printf --- examples/PoolBox/application/src/main.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/examples/PoolBox/application/src/main.cpp b/examples/PoolBox/application/src/main.cpp index d5ddf32b..a24f83f9 100644 --- a/examples/PoolBox/application/src/main.cpp +++ b/examples/PoolBox/application/src/main.cpp @@ -21,7 +21,6 @@ void main() { mesaure_busy_loop(); while(true) { - printf("Doing stuff...\n"); JabyEngine::GPU::swap_buffers_vsync(2); } } \ No newline at end of file From ad18c89c0b8aa5837fc8a664ec9835189fbe18a3 Mon Sep 17 00:00:00 2001 From: jaby Date: Thu, 27 Apr 2023 21:23:06 +0200 Subject: [PATCH 010/588] Fix broken DisplayArea --- include/PSX/System/IOPorts/gpu_io.hpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/PSX/System/IOPorts/gpu_io.hpp b/include/PSX/System/IOPorts/gpu_io.hpp index 43d93dfb..37307d49 100644 --- a/include/PSX/System/IOPorts/gpu_io.hpp +++ b/include/PSX/System/IOPorts/gpu_io.hpp @@ -2,6 +2,7 @@ #define __JABYENGINE_GPU_IO_HPP__ #include "ioport.hpp" #include "../../GPU/gpu_types.hpp" +#include namespace JabyEngine { namespace GPU_IO { @@ -141,7 +142,7 @@ namespace JabyEngine { return {Helper::construct_cmd(0x04, static_cast(dir))}; } - static constexpr GP1_t DisplayArea(uint16_t x, uint16_t y) { + static constexpr GP1_t DisplayArea(uint32_t x, uint32_t y) { constexpr auto X = BitRange::from_to(0, 9); constexpr auto Y = BitRange::from_to(10, 18); From 73a0245b0dc81ea0d925d78013668332741897af Mon Sep 17 00:00:00 2001 From: jaby Date: Sun, 30 Apr 2023 14:18:11 +0200 Subject: [PATCH 011/588] Add BootImage to second DisplayBuffer during boot --- include/PSX/GPU/gpu_types.hpp | 15 +++++++++++++++ include/PSX/System/IOPorts/gpu_io.hpp | 4 ++++ src/Library/internal-include/GPU/gpu_internal.hpp | 13 ++++++++++--- src/Library/src/BootLoader/gpu_boot.cpp | 5 ++++- 4 files changed, 33 insertions(+), 4 deletions(-) diff --git a/include/PSX/GPU/gpu_types.hpp b/include/PSX/GPU/gpu_types.hpp index 48bfc0ca..187b9f9f 100644 --- a/include/PSX/GPU/gpu_types.hpp +++ b/include/PSX/GPU/gpu_types.hpp @@ -92,11 +92,26 @@ namespace JabyEngine { } }; + template + struct Area { + Position position; + Size size; + + constexpr Area() = default; + constexpr Area(Position position, Size size) : position(position), size(size) { + } + constexpr Area(T position_x, T position_y, T size_width, T size_height) : position{position_x, position_y}, size{size_width, size_height} { + } + }; + typedef Position PositionI16; typedef Position PositionU16; typedef Size SizeI16; typedef Size SizeU16; + + typedef Area AreaI16; + typedef Area AreaU16; } } #endif //!__JABYENGINE_GPU_TYPES_HPP__ \ No newline at end of file diff --git a/include/PSX/System/IOPorts/gpu_io.hpp b/include/PSX/System/IOPorts/gpu_io.hpp index 37307d49..b26059c3 100644 --- a/include/PSX/System/IOPorts/gpu_io.hpp +++ b/include/PSX/System/IOPorts/gpu_io.hpp @@ -106,6 +106,10 @@ namespace JabyEngine { return {(0x02 << 24) | color.raw()}; } + static constexpr GP0_t VRAM2VRAM_Blitting() { + return {(0b100u << 29)}; + } + static constexpr GP0_t CPU2VRAM_Blitting() { return {(0b101u << 29)}; } diff --git a/src/Library/internal-include/GPU/gpu_internal.hpp b/src/Library/internal-include/GPU/gpu_internal.hpp index 68c1d03d..74b57864 100644 --- a/src/Library/internal-include/GPU/gpu_internal.hpp +++ b/src/Library/internal-include/GPU/gpu_internal.hpp @@ -31,10 +31,17 @@ namespace JabyEngine { GPU_IO::GP0 = GPU_IO::Command::DrawAreaBottomRight((x + Display::Width), (y + Display::Height)); } - static void quick_fill_fast(const Color24& color, const PositionU16& pos, const SizeU16& size) { + static void copy_vram_to_vram(const AreaU16& dst, const PositionU16& src) { + GPU_IO::GP0 = GPU_IO::Command::VRAM2VRAM_Blitting(); + GPU_IO::GP0 = GPU_IO::Command::TopLeftPosition(src.x, src.y); + GPU_IO::GP0 = GPU_IO::Command::TopLeftPosition(dst.position.x, dst.position.y); + GPU_IO::GP0 = GPU_IO::Command::WidthHeight(dst.size.width, dst.size.height); + } + + static void quick_fill_fast(const Color24& color, const AreaU16& area) { GPU_IO::GP0 = GPU_IO::Command::QuickFill(color); - GPU_IO::GP0 = GPU_IO::Command::TopLeftPosition(pos.x, pos.y); - GPU_IO::GP0 = GPU_IO::Command::WidthHeight(size.width, size.height); + GPU_IO::GP0 = GPU_IO::Command::TopLeftPosition(area.position.x, area.position.y); + GPU_IO::GP0 = GPU_IO::Command::WidthHeight(area.size.width, area.size.height); } static void reset_cmd_buffer() { diff --git a/src/Library/src/BootLoader/gpu_boot.cpp b/src/Library/src/BootLoader/gpu_boot.cpp index 22390d12..3c1f3fde 100644 --- a/src/Library/src/BootLoader/gpu_boot.cpp +++ b/src/Library/src/BootLoader/gpu_boot.cpp @@ -58,6 +58,9 @@ namespace JabyEngine { auto state = FileProcessor::create(&__boot_loader_end, SimpleTIM(32, 0, 0, 0)); state.process(bytes_ready); + // Duplicate DisplayBuffer content + internal::copy_vram_to_vram({PositionU16(0, Display::Height), SizeU16(Display::Width, Display::Height)}, PositionU16(0, 0)); + Display::enable(); } @@ -67,7 +70,7 @@ namespace JabyEngine { internal::Display::exchange_buffer_and_display(); GPU::internal::wait_ready_for_CMD(); - GPU::internal::quick_fill_fast(Color24::Black(), PositionU16(32, 0), SizeU16(Display::Width, Display::Height)); + GPU::internal::quick_fill_fast(Color24::Black(), {PositionU16(32, 0), SizeU16(Display::Width, Display::Height)}); __syscall_EnterCriticalSection(); __syscall_SysEnqIntRP(VblankIrq, &::JabyEngine::GPU::internal::callback); From 4b3c969a9a25d8b413d5471840ae4d944d99dc7a Mon Sep 17 00:00:00 2001 From: jaby Date: Sun, 30 Apr 2023 15:31:55 +0200 Subject: [PATCH 012/588] Create Test TileMap --- examples/PoolBox/assets/Makefile | 13 +++++++++++++ examples/PoolBox/assets/TexturePage.png | 3 +++ 2 files changed, 16 insertions(+) create mode 100644 examples/PoolBox/assets/Makefile create mode 100644 examples/PoolBox/assets/TexturePage.png diff --git a/examples/PoolBox/assets/Makefile b/examples/PoolBox/assets/Makefile new file mode 100644 index 00000000..ed4344e0 --- /dev/null +++ b/examples/PoolBox/assets/Makefile @@ -0,0 +1,13 @@ +include $(JABY_ENGINE_DIR)/lib/ExportPath.mk +include $(JABY_ENGINE_DIR)/lib/RebuildTarget.mk + +OUTPUT_DIR = bin + +$(OUTPUT_DIR)/TexturePage.bin: TexturePage.png + @mkdir -p $(OUTPUT_DIR) + jaby_engine_fconv --lz4 $< -o $@ simple-tim clut4 + +all: $(OUTPUT_DIR)/TexturePage.bin + +clean: + rm -fr $(OUTPUT_DIR) \ No newline at end of file diff --git a/examples/PoolBox/assets/TexturePage.png b/examples/PoolBox/assets/TexturePage.png new file mode 100644 index 00000000..e6d6439f --- /dev/null +++ b/examples/PoolBox/assets/TexturePage.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:14e167b003e1335945cf53ea2a1dc38e75e52b429900e745546cef0a91e5036e +size 350 From a57e1694d04749256aeeda1114af7b65de5511c2 Mon Sep 17 00:00:00 2001 From: jaby Date: Sun, 30 Apr 2023 15:33:12 +0200 Subject: [PATCH 013/588] Put RebuildTarget into own file --- examples/PoolBox/PoolBox.code-workspace | 12 ++++++++++++ lib/Makefile | 5 +---- lib/RebuildTarget.mk | 3 +++ 3 files changed, 16 insertions(+), 4 deletions(-) create mode 100644 lib/RebuildTarget.mk diff --git a/examples/PoolBox/PoolBox.code-workspace b/examples/PoolBox/PoolBox.code-workspace index b7f04eff..dd3880a7 100644 --- a/examples/PoolBox/PoolBox.code-workspace +++ b/examples/PoolBox/PoolBox.code-workspace @@ -23,6 +23,18 @@ } } }, + { + "label": "build assets", + "type": "shell", + "command": "wsl make ${input:target} BUILD_PROFILE=${input:build profile} JABY_ENGINE_DIR=$(wslpath ${env:JABY_ENGINE_PATH})", + "group": "build", + "options": { + "cwd": "assets", + "env": { + "PATH": "${env:JABY_ENGINE_PATH}/bin;${env:PATH}" + } + } + }, { "label": "cdgen", "type": "shell", diff --git a/lib/Makefile b/lib/Makefile index b0d342f8..51db17ba 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -87,10 +87,7 @@ $(OUTPUT_DIR)/%.o: $$(subst !super,..,%.s) @mkdir -p $(dir $@) $(CC) $(ARCHFLAGS) -I$(PCSX_REDUX) -g -c -o $@ $< -#Rules section for default compilation and linking -rebuild: - $(MAKE) clean - $(MAKE) all +include $(SELF_DIR)RebuildTarget.mk #Inclusion of dependencies (object files to source and includes) -include $(OBJS:%.o=%.d) \ No newline at end of file diff --git a/lib/RebuildTarget.mk b/lib/RebuildTarget.mk new file mode 100644 index 00000000..c180f356 --- /dev/null +++ b/lib/RebuildTarget.mk @@ -0,0 +1,3 @@ +rebuild: + $(MAKE) clean + $(MAKE) all \ No newline at end of file From 27c8ab71a05e14e96adfa0b812daf752481888af Mon Sep 17 00:00:00 2001 From: jaby Date: Sun, 30 Apr 2023 15:33:32 +0200 Subject: [PATCH 014/588] Do not display the help in red for fconv --- src/Tools/jaby_engine_fconv/src/main.rs | 71 ++++++++++++------------- 1 file changed, 33 insertions(+), 38 deletions(-) diff --git a/src/Tools/jaby_engine_fconv/src/main.rs b/src/Tools/jaby_engine_fconv/src/main.rs index 10b3e819..8605bc01 100644 --- a/src/Tools/jaby_engine_fconv/src/main.rs +++ b/src/Tools/jaby_engine_fconv/src/main.rs @@ -25,50 +25,45 @@ enum SubCommands { SimpleTIM(reduced_tim::Arguments) } -fn run_main() -> Result<(), Error> { - match CommandLine::try_parse() { - Ok(cmd) => { - let mut input = tool_helper::open_input(cmd.input_file)?; - let mut buffer = Vec::::new(); - let mut output_file = tool_helper::open_output(cmd.output_file)?; - let dst_buffer = { - if cmd.compress_lz4 { - &mut buffer as &mut dyn std::io::Write - } +fn run_main(cmd: CommandLine) -> Result<(), Error> { + let mut input = tool_helper::open_input(cmd.input_file)?; + let mut buffer = Vec::::new(); + let mut output_file = tool_helper::open_output(cmd.output_file)?; + let dst_buffer = { + if cmd.compress_lz4 { + &mut buffer as &mut dyn std::io::Write + } - else { - &mut output_file as &mut dyn std::io::Write - } - }; + else { + &mut output_file as &mut dyn std::io::Write + } + }; - match cmd.sub_command { - SubCommands::Nothing => { - std::io::copy(&mut input, dst_buffer)?; - }, - SubCommands::SimpleTIM(args) => { - reduced_tim::convert(args, input, dst_buffer)?; - } - } - - // We encoded the file to a temporary buffer and now need to write it - if cmd.compress_lz4 { - let buffer = tool_helper::compress::psx_default::lz4(&buffer)?; - output_file.write(&buffer)?; - } - - Ok(()) + match cmd.sub_command { + SubCommands::Nothing => { + std::io::copy(&mut input, dst_buffer)?; }, - Err(error) => Err({ - let mut error = Error::from_error(error); + SubCommands::SimpleTIM(args) => { + reduced_tim::convert(args, input, dst_buffer)?; + } + } - error.exit_code = 0; - error - }) - } + // We encoded the file to a temporary buffer and now need to write it + if cmd.compress_lz4 { + let buffer = tool_helper::compress::psx_default::lz4(&buffer)?; + output_file.write(&buffer)?; + } + + Ok(()) } fn main() { - if let Err(error) = run_main() { - exit_with_error(error); + match CommandLine::try_parse() { + Ok(cmd) => { + if let Err(error) = run_main(cmd) { + exit_with_error(error); + } + }, + Err(error) => eprintln!("{}", error) } } \ No newline at end of file From 1f39f08dc9118fa20b632811a6f173047b1da8a8 Mon Sep 17 00:00:00 2001 From: jaby Date: Sun, 30 Apr 2023 15:46:47 +0200 Subject: [PATCH 015/588] Do not display help in red --- src/Tools/cpp_out/src/main.rs | 27 ++++++++++++--------------- src/Tools/psxcdgen_ex/src/main.rs | 7 +++---- 2 files changed, 15 insertions(+), 19 deletions(-) diff --git a/src/Tools/cpp_out/src/main.rs b/src/Tools/cpp_out/src/main.rs index 78947958..819fbe71 100644 --- a/src/Tools/cpp_out/src/main.rs +++ b/src/Tools/cpp_out/src/main.rs @@ -32,24 +32,21 @@ fn configurate(cmd: &mut CommandLine) -> Result { Ok(Configuration{file_name, data_name: std::mem::take(&mut cmd.data_name), line_feed: cpp_out::LineFeed::Windows, file_type}) } -fn run_main() -> Result<(), Error> { - match CommandLine::try_parse() { - Ok(mut cmd) => { - let cfg = configurate(&mut cmd)?; - let input = tool_helper::open_input(cmd.input_file)?; - let output = tool_helper::open_output(Some(cmd.output_file))?; +fn run_main(mut cmd: CommandLine) -> Result<(), Error> { + let cfg = configurate(&mut cmd)?; + let input = tool_helper::open_input(cmd.input_file)?; + let output = tool_helper::open_output(Some(cmd.output_file))?; - return cpp_out::convert(cfg, input, output); - }, - Err(error) => Err(tool_helper::Error::from_error(error)) - } + return cpp_out::convert(cfg, input, output); } fn main() { - match run_main() { - Ok(_) => (), - Err(error) => { - exit_with_error(error) - } + match CommandLine::try_parse() { + Ok(cmd) => { + if let Err(error) = run_main(cmd) { + exit_with_error(error) + } + }, + Err(error) => eprintln!("{}", error) } } \ No newline at end of file diff --git a/src/Tools/psxcdgen_ex/src/main.rs b/src/Tools/psxcdgen_ex/src/main.rs index 280d2852..cf1a4a49 100644 --- a/src/Tools/psxcdgen_ex/src/main.rs +++ b/src/Tools/psxcdgen_ex/src/main.rs @@ -55,13 +55,12 @@ fn run_main(cmd_line: CommandLine) -> Result<(), Error> { fn main() { match CommandLine::try_parse() { Ok(cmd_line) => { - match run_main(cmd_line) { - Ok(_) => (), - Err(error) => exit_with_error(error) + if let Err(error) = run_main(cmd_line) { + exit_with_error(error) } }, Err(error) => { - exit_with_error(Error::from_error(error)) + eprintln!("{}", error) } } } \ No newline at end of file From 77dc4c2235e10044b12341345ae1dbd9c3855fae Mon Sep 17 00:00:00 2001 From: jaby Date: Sun, 30 Apr 2023 16:31:07 +0200 Subject: [PATCH 016/588] Try loading TexturePage --- examples/PoolBox/application/Makefile | 2 +- examples/PoolBox/application/Overlays.json | 9 +--- .../src/TimerTests/timer_tests.cpp | 17 +++++++ examples/PoolBox/application/src/main.cpp | 45 ++++++++++++++----- examples/PoolBox/iso/Config.xml | 7 ++- 5 files changed, 58 insertions(+), 22 deletions(-) create mode 100644 examples/PoolBox/application/src/TimerTests/timer_tests.cpp diff --git a/examples/PoolBox/application/Makefile b/examples/PoolBox/application/Makefile index efec30b8..a35a6de4 100644 --- a/examples/PoolBox/application/Makefile +++ b/examples/PoolBox/application/Makefile @@ -1,7 +1,7 @@ ARTIFACT = PoolBox BUILD_DIR = bin -#OVERLAY_CONFIG = Overlays.json +OVERLAY_CONFIG = Overlays.json include $(JABY_ENGINE_DIR)/lib/Wildcard.mk SRCS = $(call rwildcard, src, c cpp) diff --git a/examples/PoolBox/application/Overlays.json b/examples/PoolBox/application/Overlays.json index 5e779d49..0e5d7be0 100644 --- a/examples/PoolBox/application/Overlays.json +++ b/examples/PoolBox/application/Overlays.json @@ -1,12 +1,7 @@ { "slot_0": { - "main_area": { - "pattern": "bin/*/src/MainState/*.o" - } - }, - "slot_1": { - "main_area2": { - "pattern": "bin/*/src/MainState2/*.o" + "timer_tests": { + "pattern": "bin/*/src/TimerTests/*.o" } } } \ No newline at end of file diff --git a/examples/PoolBox/application/src/TimerTests/timer_tests.cpp b/examples/PoolBox/application/src/TimerTests/timer_tests.cpp new file mode 100644 index 00000000..e62774eb --- /dev/null +++ b/examples/PoolBox/application/src/TimerTests/timer_tests.cpp @@ -0,0 +1,17 @@ +#include +#include + +extern "C" void busy_loop(int count); +namespace Overlay { + void mesaure_busy_loop() { + static constexpr auto Counts = 500; + + JabyEngine::HighResTime::enable(); + const auto start = JabyEngine::HighResTime::get_time_stamp(); + busy_loop(Counts); + const auto end = JabyEngine::HighResTime::get_time_stamp(); + JabyEngine::HighResTime::disable(); + + printf("Busy loop of %i took %ims %ins\n", Counts, start.milliseconds_to(end), start.microseconds_to(end)); + } +} \ No newline at end of file diff --git a/examples/PoolBox/application/src/main.cpp b/examples/PoolBox/application/src/main.cpp index a24f83f9..ecf17d07 100644 --- a/examples/PoolBox/application/src/main.cpp +++ b/examples/PoolBox/application/src/main.cpp @@ -1,26 +1,47 @@ -#include +#include +#include #include #include -extern "C" void busy_loop(int count); +enum LBA { + __jabyengine_start_lba_request + __jabyengine_request_lba_for(FONT, "ASSETS/FONT.BIN"), + __jabyengine_end_lba_request +}; -static void mesaure_busy_loop() { - static constexpr auto Counts = 500; +static void load_assets() { + static const JabyEngine::CDFile Assets[] = { + JabyEngine::CDFileBuilder::simple_tim(LBA::FONT, JabyEngine::SimpleTIM(320, 0, 320, 256)), + }; - JabyEngine::HighResTime::enable(); - const auto start = JabyEngine::HighResTime::get_time_stamp(); - busy_loop(Counts); - const auto end = JabyEngine::HighResTime::get_time_stamp(); - JabyEngine::HighResTime::disable(); + const auto buffer_cfg = JabyEngine::CDFileProcessor::BufferConfiguration::new_default(); + JabyEngine::CDFileProcessor file_processor; - printf("Busy loop of %i took %ims %ins\n", Counts, start.milliseconds_to(end), start.microseconds_to(end)); + file_processor.setup(lba, Assets, buffer_cfg); + while(true) { + switch(file_processor.process()) { + case JabyEngine::Progress::InProgress: + break; + + case JabyEngine::Progress::Done: + if(!file_processor.next(lba, buffer_cfg)) { + return; + } + break; + + case JabyEngine::Progress::Error: + printf("Error detected! Aborting load\n"); + return; + } + } } void main() { printf("Hello PoolBox!\n"); - mesaure_busy_loop(); + load_assets(); while(true) { JabyEngine::GPU::swap_buffers_vsync(2); } -} \ No newline at end of file +} +__declare_lba_header(LBA); \ No newline at end of file diff --git a/examples/PoolBox/iso/Config.xml b/examples/PoolBox/iso/Config.xml index 9c58e342..2c265b3c 100644 --- a/examples/PoolBox/iso/Config.xml +++ b/examples/PoolBox/iso/Config.xml @@ -4,7 +4,10 @@ %PSX_LICENSE_PATH%/LICENSEE.DAT - iso/System.cnf -
application/bin/PSX-release/PoolBox.psexe
+ iso/System.cnf +
application/bin/PSX-release/PoolBox.psexe
+ + assets/bin/TexturePage.bin +
\ No newline at end of file From 1b35ab2a3f22c4a5a42d6d020f845bc3fd061002 Mon Sep 17 00:00:00 2001 From: jaby Date: Sun, 30 Apr 2023 16:40:01 +0200 Subject: [PATCH 017/588] Fix small bug --- examples/PoolBox/application/src/main.cpp | 1 + src/Library/src/BootLoader/gpu_boot.cpp | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/PoolBox/application/src/main.cpp b/examples/PoolBox/application/src/main.cpp index ecf17d07..8c498a8c 100644 --- a/examples/PoolBox/application/src/main.cpp +++ b/examples/PoolBox/application/src/main.cpp @@ -34,6 +34,7 @@ static void load_assets() { return; } } + printf("Done loading assets!\n"); } void main() { diff --git a/src/Library/src/BootLoader/gpu_boot.cpp b/src/Library/src/BootLoader/gpu_boot.cpp index 3c1f3fde..0af9922b 100644 --- a/src/Library/src/BootLoader/gpu_boot.cpp +++ b/src/Library/src/BootLoader/gpu_boot.cpp @@ -70,7 +70,7 @@ namespace JabyEngine { internal::Display::exchange_buffer_and_display(); GPU::internal::wait_ready_for_CMD(); - GPU::internal::quick_fill_fast(Color24::Black(), {PositionU16(32, 0), SizeU16(Display::Width, Display::Height)}); + GPU::internal::quick_fill_fast(Color24::Black(), {PositionU16(0, 0), SizeU16(Display::Width, Display::Height)}); __syscall_EnterCriticalSection(); __syscall_SysEnqIntRP(VblankIrq, &::JabyEngine::GPU::internal::callback); From 5dc83be87f72c0a015a5f4a73af65cb48c49958e Mon Sep 17 00:00:00 2001 From: jaby Date: Mon, 1 May 2023 11:02:07 +0200 Subject: [PATCH 018/588] Fix fconv for clut images --- src/Tools/jaby_engine_fconv/Cargo.toml | 2 +- .../src/images/reduced_tim/mod.rs | 17 ++++++++++++----- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/src/Tools/jaby_engine_fconv/Cargo.toml b/src/Tools/jaby_engine_fconv/Cargo.toml index 0877a876..023b2b6e 100644 --- a/src/Tools/jaby_engine_fconv/Cargo.toml +++ b/src/Tools/jaby_engine_fconv/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "jaby_engine_fconv" -version = "0.1.3" +version = "0.1.4" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/src/Tools/jaby_engine_fconv/src/images/reduced_tim/mod.rs b/src/Tools/jaby_engine_fconv/src/images/reduced_tim/mod.rs index 3e4c6715..53a80907 100644 --- a/src/Tools/jaby_engine_fconv/src/images/reduced_tim/mod.rs +++ b/src/Tools/jaby_engine_fconv/src/images/reduced_tim/mod.rs @@ -33,8 +33,15 @@ pub struct Arguments { clut_align: ClutAlignment } -fn encode(image: T, clut_align: ClutAlignment, output: &mut dyn Write) -> Result<(), Error> { - let width = image.width(); +fn encode(image: T, color_depth: ColorType, clut_align: ClutAlignment, output: &mut dyn Write) -> Result<(), Error> { + let width = { + let width = image.width(); + match color_depth { + ColorType::Clut4 => width/4, + ColorType::Clut8 => width/2, + ColorType::Full16 => width + } + }; let height = image.height(); let palette = image.get_palette(); let (pal_width, pal_height) = { @@ -78,8 +85,8 @@ fn convert_full16(input: Input, output: &mut dyn Write) -> Result<(), Error> { match ImageReader::new(Cursor::new(tool_helper::input_to_vec(input)?)).with_guessed_format()?.decode() { Ok(image) => { match image { - DynamicImage::ImageRgb8(image) => encode(RgbImage::new(image), ClutAlignment::None, output), - DynamicImage::ImageRgba8(image) => encode(RgbaImage::new(image), ClutAlignment::None, output), + DynamicImage::ImageRgb8(image) => encode(RgbImage::new(image), ColorType::Full16, ClutAlignment::None, output), + DynamicImage::ImageRgba8(image) => encode(RgbaImage::new(image), ColorType::Full16, ClutAlignment::None, output), _ => Err(Error::from_str("Only RGB and RGBA images are supported for 16bit encoding")) } @@ -98,7 +105,7 @@ fn convert_palette_based(input: Input, output: &mut dyn Write, color_type: Color _ => return Err(Error::from_str("ColorType not supported")) } }; - encode(IndexedImage::new(reader, output_type)?, clut_align, output) + encode(IndexedImage::new(reader, output_type)?, color_type, clut_align, output) }, Err(error) => Err(Error::from_error(error)) } From 904509a65e8640dcb01f5bb5f243d2fda22ebae2 Mon Sep 17 00:00:00 2001 From: jaby Date: Mon, 1 May 2023 11:02:33 +0200 Subject: [PATCH 019/588] Include asset build into makefile --- examples/PoolBox/Makefile | 5 +++++ examples/PoolBox/PoolBox.code-workspace | 13 ------------- 2 files changed, 5 insertions(+), 13 deletions(-) create mode 100644 examples/PoolBox/Makefile diff --git a/examples/PoolBox/Makefile b/examples/PoolBox/Makefile new file mode 100644 index 00000000..95a833c7 --- /dev/null +++ b/examples/PoolBox/Makefile @@ -0,0 +1,5 @@ +all clean rebuild: always + $(MAKE) $(MAKECMDGOALS) -C assets + $(MAKE) $(MAKECMDGOALS) -C application + +always: ; \ No newline at end of file diff --git a/examples/PoolBox/PoolBox.code-workspace b/examples/PoolBox/PoolBox.code-workspace index dd3880a7..b6a16f43 100644 --- a/examples/PoolBox/PoolBox.code-workspace +++ b/examples/PoolBox/PoolBox.code-workspace @@ -17,19 +17,6 @@ "isDefault": true }, "options": { - "cwd": "application", - "env": { - "PATH": "${env:JABY_ENGINE_PATH}/bin;${env:PATH}" - } - } - }, - { - "label": "build assets", - "type": "shell", - "command": "wsl make ${input:target} BUILD_PROFILE=${input:build profile} JABY_ENGINE_DIR=$(wslpath ${env:JABY_ENGINE_PATH})", - "group": "build", - "options": { - "cwd": "assets", "env": { "PATH": "${env:JABY_ENGINE_PATH}/bin;${env:PATH}" } From 513275fba8826acedc7dc2ef1cbd6b9bad178e22 Mon Sep 17 00:00:00 2001 From: jaby Date: Mon, 1 May 2023 22:37:41 +0200 Subject: [PATCH 020/588] Fix image conversion and CLUT placement --- include/PSX/File/file_types.hpp | 19 ++++++--- .../src/File/Processor/tim_processor.cpp | 41 ++++++++++++------- .../src/images/reduced_tim/mod.rs | 6 +-- .../src/images/reduced_tim/types.rs | 4 ++ src/Tools/tool_helper/Cargo.toml | 2 +- src/Tools/tool_helper/src/bits.rs | 2 +- 6 files changed, 50 insertions(+), 24 deletions(-) diff --git a/include/PSX/File/file_types.hpp b/include/PSX/File/file_types.hpp index bba6c5f5..fe077595 100644 --- a/include/PSX/File/file_types.hpp +++ b/include/PSX/File/file_types.hpp @@ -1,6 +1,7 @@ #ifndef __JABYENGINE_FILE_TYPES_HPP__ #define __JABYENGINE_FILE_TYPES_HPP__ #include "../Auxiliary/bits.hpp" +#include "../GPU/gpu_types.hpp" #include "../jabyengine_defines.h" namespace JabyEngine { @@ -19,24 +20,32 @@ namespace JabyEngine { this->raw = 0; } - constexpr SimpleTIM(uint16_t texX, uint16_t texY, uint16_t clutX, uint16_t clutY) : raw(TextureX.as_value(texX >> 1) | TextureY.as_value(texY >> 1) | ClutX.as_value(clutX >> 4) | ClutY.as_value(clutY)) { + constexpr SimpleTIM(uint16_t texX, uint16_t texY, uint16_t clutX, uint16_t clutY) : raw(TextureX.as_value(texX >> 1) | TextureY.as_value(texY >> 1) | ClutX.as_value(clutX >> 4) | ClutY.as_value(static_cast(clutY))) { } - constexpr uint16_t getTextureX() const { + constexpr uint16_t get_texture_x() const { return bit::value::get_normalized(this->raw, TextureX) << 1; } - constexpr uint16_t getTextureY() const { + constexpr uint16_t get_texture_y() const { return bit::value::get_normalized(this->raw, TextureY) << 1; } - constexpr uint16_t getClutX() const { + constexpr GPU::PositionU16 get_texture_position() const { + return {SimpleTIM::get_texture_x(), SimpleTIM::get_texture_y()}; + } + + constexpr uint16_t get_clut_x() const { return bit::value::get_normalized(this->raw, SimpleTIM::ClutX) << 4; } - constexpr uint16_t getClutY() const { + constexpr uint16_t get_clut_y() const { return bit::value::get_normalized(this->raw, ClutY); } + + constexpr GPU::PositionU16 get_clut_position() const { + return {SimpleTIM::get_clut_x(), SimpleTIM::get_clut_y()}; + } }; struct __no_align CopyTo { diff --git a/src/Library/src/File/Processor/tim_processor.cpp b/src/Library/src/File/Processor/tim_processor.cpp index f0528270..0ff40dbf 100644 --- a/src/Library/src/File/Processor/tim_processor.cpp +++ b/src/Library/src/File/Processor/tim_processor.cpp @@ -1,10 +1,12 @@ #include "../../../internal-include/GPU/gpu_internal.hpp" #include "simplehelper.hpp" +#include #include #include namespace JabyEngine { namespace FileProcessor { + using GPU::AreaU16; using GPU::PositionU16; using GPU::SizeU16; @@ -12,20 +14,28 @@ namespace JabyEngine { constexpr SimpleTIMSize() { } - constexpr uint16_t getTextureWidth() const { - return SimpleTIM::getTextureX(); + constexpr uint16_t get_texture_width() const { + return SimpleTIM::get_texture_x(); } - constexpr uint16_t getTextureHeight() const { - return SimpleTIM::getTextureY(); + constexpr uint16_t get_texture_height() const { + return SimpleTIM::get_texture_y(); } - constexpr uint16_t getClutWidth() const { - return SimpleTIM::getClutX(); + constexpr SizeU16 get_texture_size() const { + return {SimpleTIMSize::get_texture_width(), SimpleTIMSize::get_texture_height()}; } - constexpr uint16_t getClutHeight() const { - return SimpleTIM::getClutY(); + constexpr uint16_t get_clut_width() const { + return SimpleTIM::get_clut_x(); + } + + constexpr uint16_t get_clut_height() const { + return SimpleTIM::get_clut_y(); + } + + constexpr SizeU16 get_clut_size() const { + return {SimpleTIMSize::get_clut_width(), SimpleTIMSize::get_clut_height()}; } }; @@ -44,9 +54,12 @@ namespace JabyEngine { GPU::internal::DMA::Receive::set_src(reinterpret_cast(src)); } - static void set_gpu_receive_data(const uint32_t* src, SimpleTIMState& state, uint16_t width, uint16_t height) { - state.words_left = (width*height)/2; - set_gpu_receive(src, state.dst_info.getTextureX(), state.dst_info.getTextureY(), width, height); + static size_t set_gpu_receive_data(const uint32_t* src, const AreaU16& dst) { + const auto width = dst.size.width; + const auto height = dst.size.height; + + set_gpu_receive(src, dst.position.x, dst.position.y, width, height); + return (width*height)/2; } static Progress parse_data(State::Configuration& config, SimpleTIMState& state) { @@ -91,7 +104,7 @@ namespace JabyEngine { } static Progress switch_state_parse_data(State::Configuration& config, SimpleTIMState& state) { - set_gpu_receive_data(reinterpret_cast(config.data_adr), state, state.size_info.getTextureWidth(), state.size_info.getTextureHeight()); + state.words_left = set_gpu_receive_data(reinterpret_cast(config.data_adr), {state.dst_info.get_texture_position(), state.size_info.get_texture_size()}); return Helper::exchange_and_execute_process_function(parse_data, config, state); } @@ -110,9 +123,9 @@ namespace JabyEngine { Helper::simple_read(state.size_info, config); //Check if we have a clut to care about - if(state.size_info.getClutWidth() > 0) { + if(state.size_info.get_clut_width() > 0) { //CLUTs are 16bit full color anyway - set_gpu_receive_data(reinterpret_cast(config.data_adr), state, state.size_info.getClutWidth(), state.size_info.getClutHeight()); + state.words_left = set_gpu_receive_data(reinterpret_cast(config.data_adr), {state.dst_info.get_clut_position(), state.size_info.get_clut_size()}); return Helper::exchange_and_execute_process_function(parse_clut, config, state); } diff --git a/src/Tools/jaby_engine_fconv/src/images/reduced_tim/mod.rs b/src/Tools/jaby_engine_fconv/src/images/reduced_tim/mod.rs index 53a80907..415105c6 100644 --- a/src/Tools/jaby_engine_fconv/src/images/reduced_tim/mod.rs +++ b/src/Tools/jaby_engine_fconv/src/images/reduced_tim/mod.rs @@ -64,18 +64,18 @@ fn encode(image: T, color_depth: ColorType, clut_align: Cl if let Some(palette) = palette { let mut color_count = pal_width*pal_height; for color in palette { - tool_helper::raw::write_generic(output, color)?; + tool_helper::raw::write_generic(output, color.get_raw())?; color_count -= 1; } while color_count > 0 { - tool_helper::raw::write_generic(output, PSXColor::black())?; + tool_helper::raw::write_generic(output, PSXColor::black().get_raw())?; color_count -= 1; } } for color in image { - tool_helper::raw::write_generic(output, color)?; + tool_helper::raw::write_generic(output, color.get_raw())?; } Ok(()) diff --git a/src/Tools/jaby_engine_fconv/src/images/reduced_tim/types.rs b/src/Tools/jaby_engine_fconv/src/images/reduced_tim/types.rs index 5da937e0..e9600a38 100644 --- a/src/Tools/jaby_engine_fconv/src/images/reduced_tim/types.rs +++ b/src/Tools/jaby_engine_fconv/src/images/reduced_tim/types.rs @@ -102,6 +102,10 @@ impl Color { Color{value} } + pub const fn get_raw(&self) -> u16 { + self.value.to_le() + } + const fn new(stp: u8, red: u8, green: u8, blue: u8) -> Color { let value = set_member_value!(set_member_value!(set_member_value!(set_member_value!(0, stp, 0, u16), diff --git a/src/Tools/tool_helper/Cargo.toml b/src/Tools/tool_helper/Cargo.toml index eda5d603..ae2fa4c8 100644 --- a/src/Tools/tool_helper/Cargo.toml +++ b/src/Tools/tool_helper/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "tool_helper" -version = "0.8.0" +version = "0.8.1" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/src/Tools/tool_helper/src/bits.rs b/src/Tools/tool_helper/src/bits.rs index 7dec95a7..f68fc377 100644 --- a/src/Tools/tool_helper/src/bits.rs +++ b/src/Tools/tool_helper/src/bits.rs @@ -57,7 +57,7 @@ macro_rules! create_bit_functions { } pub const fn [< get_value_ $type_val >](src: $type_val, range: &BitRange) -> $type_val { - (src & [< get_mask_ $type_val >](range)) >> range.start + (src & ([< get_mask_ $type_val >](range) << (range.start as $type_val))) >> range.start } pub const fn [< bit_set_ $type_val >](src: $type_val, bit: usize) -> bool { From a50e0ec5447effc9a28e3974f02dbcb06238b106 Mon Sep 17 00:00:00 2001 From: jaby Date: Mon, 1 May 2023 23:01:35 +0200 Subject: [PATCH 021/588] Replace unsafe code with raw trait --- .../src/images/reduced_tim/mod.rs | 10 +++++----- .../src/images/reduced_tim/types.rs | 18 +++++++++++++----- src/Tools/tool_helper/Cargo.toml | 2 +- src/Tools/tool_helper/src/raw.rs | 8 +++++--- 4 files changed, 24 insertions(+), 14 deletions(-) diff --git a/src/Tools/jaby_engine_fconv/src/images/reduced_tim/mod.rs b/src/Tools/jaby_engine_fconv/src/images/reduced_tim/mod.rs index 415105c6..6deb8357 100644 --- a/src/Tools/jaby_engine_fconv/src/images/reduced_tim/mod.rs +++ b/src/Tools/jaby_engine_fconv/src/images/reduced_tim/mod.rs @@ -59,23 +59,23 @@ fn encode(image: T, color_depth: ColorType, clut_align: Cl }; let header = Header::encode(width, height, pal_width, pal_height).ok_or(Error::from_callback(|| {format!("Image size (width: {}, height: {}) needs to be even", width, height)}))?; - - tool_helper::raw::write_generic(output, header)?; + + tool_helper::raw::write_raw(output, &header)?; if let Some(palette) = palette { let mut color_count = pal_width*pal_height; for color in palette { - tool_helper::raw::write_generic(output, color.get_raw())?; + tool_helper::raw::write_raw(output, color)?; color_count -= 1; } while color_count > 0 { - tool_helper::raw::write_generic(output, PSXColor::black().get_raw())?; + tool_helper::raw::write_raw(output, &PSXColor::black())?; color_count -= 1; } } for color in image { - tool_helper::raw::write_generic(output, color.get_raw())?; + tool_helper::raw::write_raw(output, &color)?; } Ok(()) diff --git a/src/Tools/jaby_engine_fconv/src/images/reduced_tim/types.rs b/src/Tools/jaby_engine_fconv/src/images/reduced_tim/types.rs index e9600a38..44f356d2 100644 --- a/src/Tools/jaby_engine_fconv/src/images/reduced_tim/types.rs +++ b/src/Tools/jaby_engine_fconv/src/images/reduced_tim/types.rs @@ -1,4 +1,4 @@ -use tool_helper::{*, bits::BitRange}; +use tool_helper::{*, bits::BitRange, raw::RawConversion}; #[repr(packed(1))] #[allow(dead_code)] @@ -102,10 +102,6 @@ impl Color { Color{value} } - pub const fn get_raw(&self) -> u16 { - self.value.to_le() - } - const fn new(stp: u8, red: u8, green: u8, blue: u8) -> Color { let value = set_member_value!(set_member_value!(set_member_value!(set_member_value!(0, stp, 0, u16), @@ -122,6 +118,12 @@ impl Color { make_member_getter_setter!(blue, Self::COLOR_SHIFT, u16); } +impl RawConversion<2> for Color { + fn convert_to_raw(&self) -> [u8; 2] { + self.value.to_le_bytes() + } +} + #[allow(dead_code)] impl Header { const TEX_WIDTH_BIT_RANGE: BitRange = BitRange::from_to(0, 8); @@ -146,6 +148,12 @@ impl Header { } } +impl RawConversion<4> for Header { + fn convert_to_raw(&self) -> [u8; 4] { + self.value.to_le_bytes() + } +} + pub trait PSXImageConverter: std::iter::Iterator { fn width(&self) -> u16; fn height(&self) -> u16; diff --git a/src/Tools/tool_helper/Cargo.toml b/src/Tools/tool_helper/Cargo.toml index ae2fa4c8..1373c636 100644 --- a/src/Tools/tool_helper/Cargo.toml +++ b/src/Tools/tool_helper/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "tool_helper" -version = "0.8.1" +version = "0.9.0" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/src/Tools/tool_helper/src/raw.rs b/src/Tools/tool_helper/src/raw.rs index 3350213a..29875eb0 100644 --- a/src/Tools/tool_helper/src/raw.rs +++ b/src/Tools/tool_helper/src/raw.rs @@ -1,7 +1,9 @@ use super::{Error, Write}; -pub fn write_generic(output: &mut dyn Write, value: T) -> Result { - let raw = unsafe {std::slice::from_raw_parts(&value as *const _ as *const u8, std::mem::size_of_val(&value))}; +pub trait RawConversion { + fn convert_to_raw(&self) -> [u8; COUNT]; +} - Error::try_or_new(output.write(raw)) +pub fn write_raw, const COUNT:usize>(output: &mut dyn Write, value: &T) -> Result { + Error::try_or_new(output.write(&value.convert_to_raw())) } \ No newline at end of file From 3831c3a3eb7751b82dd9aa8c3c36c4ea503ae51f Mon Sep 17 00:00:00 2001 From: jaby Date: Sun, 7 May 2023 00:07:20 +0200 Subject: [PATCH 022/588] Draw first triangle --- examples/PoolBox/application/src/main.cpp | 8 ++ include/PSX/Auxiliary/type_traits.hpp | 14 +++ include/PSX/File/file_types.hpp | 4 +- include/PSX/GPU/gpu.hpp | 13 ++- include/PSX/GPU/gpu_primitives.hpp | 90 +++++++++++++++++++ include/PSX/GPU/gpu_types.hpp | 1 + include/PSX/System/IOPorts/gpu_io.hpp | 33 ++++--- lib/Makefile | 4 +- .../internal-include/GPU/gpu_internal.hpp | 26 ++++-- .../src/File/Processor/tim_processor.cpp | 2 +- src/Library/src/GPU/gpu.cpp | 26 ++++-- src/Library/src/run.cpp | 1 + 12 files changed, 190 insertions(+), 32 deletions(-) create mode 100644 include/PSX/Auxiliary/type_traits.hpp create mode 100644 include/PSX/GPU/gpu_primitives.hpp diff --git a/examples/PoolBox/application/src/main.cpp b/examples/PoolBox/application/src/main.cpp index 8c498a8c..5ca09653 100644 --- a/examples/PoolBox/application/src/main.cpp +++ b/examples/PoolBox/application/src/main.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include enum LBA { @@ -38,10 +39,17 @@ static void load_assets() { } void main() { + const JabyEngine::GPU::POLY_F3 triangle( + JabyEngine::GPU::Color24(0x0, 0xFF, 0xFF), + { + {0, 0}, {320*2, 127}, {0, 255} + } + ); printf("Hello PoolBox!\n"); load_assets(); while(true) { + JabyEngine::GPU::render(triangle); JabyEngine::GPU::swap_buffers_vsync(2); } } diff --git a/include/PSX/Auxiliary/type_traits.hpp b/include/PSX/Auxiliary/type_traits.hpp new file mode 100644 index 00000000..5b667ef1 --- /dev/null +++ b/include/PSX/Auxiliary/type_traits.hpp @@ -0,0 +1,14 @@ +#ifndef __JABYENGINE_TYPE_TRAITS_HPP__ +#define __JABYENGINE_TYPE_TRAITS_HPP__ + +namespace JabyEngine { + template + struct enable_if {}; + + template + struct enable_if { + typedef T type; + }; +} + +#endif //! __JABYENGINE_TYPE_TRAITS_HPP__ \ No newline at end of file diff --git a/include/PSX/File/file_types.hpp b/include/PSX/File/file_types.hpp index fe077595..c2df1d56 100644 --- a/include/PSX/File/file_types.hpp +++ b/include/PSX/File/file_types.hpp @@ -16,9 +16,7 @@ namespace JabyEngine { uint32_t raw; - constexpr SimpleTIM() { - this->raw = 0; - } + constexpr SimpleTIM() : raw(0) {} constexpr SimpleTIM(uint16_t texX, uint16_t texY, uint16_t clutX, uint16_t clutY) : raw(TextureX.as_value(texX >> 1) | TextureY.as_value(texY >> 1) | ClutX.as_value(clutX >> 4) | ClutY.as_value(static_cast(clutY))) { } diff --git a/include/PSX/GPU/gpu.hpp b/include/PSX/GPU/gpu.hpp index c864052c..1ac7fa16 100644 --- a/include/PSX/GPU/gpu.hpp +++ b/include/PSX/GPU/gpu.hpp @@ -1,6 +1,8 @@ #ifndef __JABYENGINE_GPU_HPP__ #define __JABYENGINE_GPU_HPP__ +#include "../Auxiliary/type_traits.hpp" #include "../System/IOPorts/gpu_io.hpp" +#include "gpu_primitives.hpp" #if !defined(JABYENGINE_NTSC) && !defined(JABYENGINE_PAL) #error "JABYENGINE_NTSC or JABYENGINE_PAL must be defined" @@ -34,7 +36,16 @@ namespace JabyEngine { static void set_offset(uint16_t x, uint16_t y); }; - uint8_t swap_buffers_vsync(uint8_t syncs); + namespace internal { + void render(const uint32_t* data, size_t words); + } + + template + static enable_if::type render(const T& primitive) { + internal::render(reinterpret_cast(&primitive), sizeof(T)/sizeof(uint32_t)); + } + + uint8_t swap_buffers_vsync(uint8_t syncs, bool clear_screen = true); } } #endif //!__JABYENGINE_GPU_HPP__ \ No newline at end of file diff --git a/include/PSX/GPU/gpu_primitives.hpp b/include/PSX/GPU/gpu_primitives.hpp new file mode 100644 index 00000000..5c890324 --- /dev/null +++ b/include/PSX/GPU/gpu_primitives.hpp @@ -0,0 +1,90 @@ +#ifndef __JABYENGINE_GPU_PRIMITIVES_HPP__ +#define __JABYENGINE_GPU_PRIMITIVES_HPP__ +#include "gpu_types.hpp" + +namespace JabyEngine { + namespace GPU { + namespace internal { + struct Code { + static constexpr uint8_t CmdValue = 0b001; + static constexpr auto BitCorrection = 24; + + static constexpr auto CmdID = BitRange::from_to(29 - BitCorrection, 31 - BitCorrection); + static constexpr auto GouraudShading = Bit(28 - BitCorrection); + static constexpr auto FlatShading = !GouraudShading; + static constexpr auto QuardVertics = Bit(27 - BitCorrection); + static constexpr auto TriVertics = !QuardVertics; + static constexpr auto Textured = Bit(26 - BitCorrection); + static constexpr auto Untextured = !Textured; + static constexpr auto SemiTransparent = Bit(25 - BitCorrection); + static constexpr auto NonTransparent = !SemiTransparent; + static constexpr auto BlendTexture = Bit(24 - BitCorrection); + static constexpr auto NoBlendTexture = !BlendTexture; + + uint8_t value = bit::value::set_normalized(0u, CmdID.with(CmdValue)); + + constexpr Code() = default; + + constexpr Code& set(Bit bit) { + this->value = bit::set(this->value, bit); + return *this; + } + + constexpr Code& set(ClearBit bit) { + this->value = bit::set(this->value, bit); + return *this; + } + }; + + struct IsPrimitive { + static constexpr bool is_primitive = true; + }; + + template + struct CodeInterface { + constexpr T& set_semi_transparent() { + static_cast(this)->code.set(Code::SemiTransparent); + return *static_cast(this); + } + + constexpr T& set_non_transparent() { + static_cast(this)->code.set(Code::NonTransparent); + return *static_cast(this); + } + + constexpr T& set_texture_blending() { + static_cast(this)->code.set(Code::BlendTexture); + return *static_cast(this); + } + + constexpr T& set_non_texture_blening() { + static_cast(this)->code.set(Code::NoBlendTexture); + return *static_cast(this); + } + }; + + // Concept for now + template + struct Hooked { + uint32_t hook; + T primitive; + }; + } + + struct POLY_F3 : public internal::IsPrimitive, public internal::CodeInterface { + static constexpr auto IdentityCode = internal::Code().set(internal::Code::FlatShading).set(internal::Code::TriVertics).set(internal::Code::Untextured).set(internal::Code::NonTransparent).set(internal::Code::NoBlendTexture); + + Color24 color; + internal::Code code = IdentityCode; + PositionI16 vertex[3]; + + constexpr POLY_F3() = default; + constexpr POLY_F3(Color24 color, const PositionI16 (&verticies)[3]) : color(color), code(IdentityCode), vertex{verticies[0], verticies[1], verticies[2]} { + } + }; + + static_assert(sizeof(POLY_F3) == 16); + } +} + +#endif // !__JABYENGINE_GPU_PRIMITIVES_HPP__ \ No newline at end of file diff --git a/include/PSX/GPU/gpu_types.hpp b/include/PSX/GPU/gpu_types.hpp index 187b9f9f..302cf55d 100644 --- a/include/PSX/GPU/gpu_types.hpp +++ b/include/PSX/GPU/gpu_types.hpp @@ -1,5 +1,6 @@ #ifndef __JABYENGINE_GPU_TYPES_HPP__ #define __JABYENGINE_GPU_TYPES_HPP__ +#include "../Auxiliary/bits.hpp" #include "../jabyengine_defines.h" namespace JabyEngine { diff --git a/include/PSX/System/IOPorts/gpu_io.hpp b/include/PSX/System/IOPorts/gpu_io.hpp index b26059c3..a6473a9d 100644 --- a/include/PSX/System/IOPorts/gpu_io.hpp +++ b/include/PSX/System/IOPorts/gpu_io.hpp @@ -89,16 +89,16 @@ namespace JabyEngine { struct Command { struct Helper { + static constexpr uint32_t construct_cmd(uint8_t cmd, uint32_t value) { + return ((cmd << 24) | value); + } + static constexpr GP0_t DrawAreaTemplate(uint8_t code, uint16_t x, uint16_t y) { constexpr auto Command = BitRange::from_to(24, 31); constexpr auto Y = BitRange::from_to(10, 18); constexpr auto X = BitRange::from_to(0, 9); - return GP0_t::from(Command.with(code), Y.with(y), X.with(x)); - } - - static constexpr uint32_t construct_cmd(uint8_t cmd, uint32_t value) { - return ((cmd << 24) | value); + return {construct_cmd(code, Y.as_value(static_cast(y)) | X.as_value(static_cast(x)))}; } }; @@ -122,12 +122,19 @@ namespace JabyEngine { return Helper::DrawAreaTemplate(0xE4, x, y); } + static GP0_t SetDrawOffset(int16_t x, int16_t y) { + constexpr auto X = BitRange::from_to(0, 10); + constexpr auto Y = BitRange::from_to(11, 21); + + return {Helper::construct_cmd(0xE5, X.as_value(static_cast(x)) | Y.as_value(static_cast(y)))}; + } + static constexpr GP0_t TopLeftPosition(uint16_t x, uint16_t y) { - return {static_cast((y << 16u) | x)}; + return {(static_cast(y) << 16u) | x}; } static constexpr GP0_t WidthHeight(uint16_t w, uint16_t h) { - return {static_cast((h << 16u) | w)}; + return {(static_cast(h) << 16u) | w}; } static constexpr GP1_t Reset() { @@ -146,25 +153,25 @@ namespace JabyEngine { return {Helper::construct_cmd(0x04, static_cast(dir))}; } - static constexpr GP1_t DisplayArea(uint32_t x, uint32_t y) { + static constexpr GP1_t DisplayArea(uint16_t x, uint16_t y) { constexpr auto X = BitRange::from_to(0, 9); constexpr auto Y = BitRange::from_to(10, 18); - return {Helper::construct_cmd(0x05, X.as_value(x) | Y.as_value(y))}; + return {Helper::construct_cmd(0x05, X.as_value(static_cast(x)) | Y.as_value(static_cast(y)))}; } - static constexpr GP1_t HorizontalDisplayRange(uint32_t x1, uint32_t x2) { + static constexpr GP1_t HorizontalDisplayRange(uint16_t x1, uint16_t x2) { constexpr auto X1 = BitRange::from_to(0, 11); constexpr auto X2 = BitRange::from_to(12, 23); - return {Helper::construct_cmd(0x06, X1.as_value(x1) | X2.as_value(x2))}; + return {Helper::construct_cmd(0x06, X1.as_value(static_cast(x1)) | X2.as_value(static_cast(x2)))}; } - static constexpr GP1_t VerticalDisplayRange(uint32_t y1, uint32_t y2) { + static constexpr GP1_t VerticalDisplayRange(uint16_t y1, uint16_t y2) { constexpr auto Y1 = BitRange::from_to(0, 9); constexpr auto Y2 = BitRange::from_to(10, 19); - return {Helper::construct_cmd(0x07, Y1.as_value(y1) | Y2.as_value(y2))}; + return {Helper::construct_cmd(0x07, Y1.as_value(static_cast(y1)) | Y2.as_value(static_cast(y2)))}; } static constexpr GP1_t DisplayMode(DisplayMode_t mode) { diff --git a/lib/Makefile b/lib/Makefile index 51db17ba..f59f3bd0 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -37,7 +37,7 @@ LD = $(CXX) AR = ar #architecture flags -ARCHFLAGS = -march=mips1 -mabi=32 -EL -fno-pic -mno-shared -nostdinc -nostdinc++ -mno-abicalls -mfp32 +ARCHFLAGS = -march=r2000 -mtune=r2000 -mabi=32 -EL -fno-pic -mno-shared -nostdinc -nostdinc++ -mno-abicalls -mfp32 -mno-llsc ARCHFLAGS += -fno-stack-protector -nostdlib -ffreestanding #Compiler flags for build profiles @@ -46,7 +46,7 @@ CCFLAGS_debug += -O0 CXXFLAGS += -fno-exceptions -fno-rtti -CCFLAGS += -mno-gpopt -fomit-frame-pointer -ffunction-sections +CCFLAGS += -mno-gpopt -fomit-frame-pointer -ffunction-sections -fdata-sections CCFLAGS += -fno-builtin -fno-strict-aliasing -Wno-attributes CCFLAGS += -std=c++20 CCFLAGS += $(ARCHFLAGS) diff --git a/src/Library/internal-include/GPU/gpu_internal.hpp b/src/Library/internal-include/GPU/gpu_internal.hpp index 74b57864..2bacb80b 100644 --- a/src/Library/internal-include/GPU/gpu_internal.hpp +++ b/src/Library/internal-include/GPU/gpu_internal.hpp @@ -21,17 +21,27 @@ namespace JabyEngine { static constexpr uint16_t ScanlinesV = 240; #endif //JABYENGINE_PAL - static void exchange_buffer_and_display(); + static uint32_t exchange_buffer_and_display(); }; void wait_vsync(uint8_t syncs); + static void wait_ready_for_CMD() { + while(!GPU_IO::GPUSTAT.is_set(GPU_IO::GPUSTAT_t::GP0ReadyForCMD)); + } + static void set_draw_area(uint16_t x, uint16_t y) { - GPU_IO::GP0 = GPU_IO::Command::DrawAreaTopLeft(x, y); - GPU_IO::GP0 = GPU_IO::Command::DrawAreaBottomRight((x + Display::Width), (y + Display::Height)); + const auto top_left = GPU_IO::Command::DrawAreaTopLeft(x, y); + const auto bottom_right = GPU_IO::Command::DrawAreaBottomRight((x + Display::Width - 1), (y + Display::Height - 1)); + + wait_ready_for_CMD(); + GPU_IO::GP0 = top_left; + wait_ready_for_CMD(); + GPU_IO::GP0 = bottom_right; } static void copy_vram_to_vram(const AreaU16& dst, const PositionU16& src) { + wait_ready_for_CMD(); GPU_IO::GP0 = GPU_IO::Command::VRAM2VRAM_Blitting(); GPU_IO::GP0 = GPU_IO::Command::TopLeftPosition(src.x, src.y); GPU_IO::GP0 = GPU_IO::Command::TopLeftPosition(dst.position.x, dst.position.y); @@ -39,17 +49,19 @@ namespace JabyEngine { } static void quick_fill_fast(const Color24& color, const AreaU16& area) { + wait_ready_for_CMD(); GPU_IO::GP0 = GPU_IO::Command::QuickFill(color); GPU_IO::GP0 = GPU_IO::Command::TopLeftPosition(area.position.x, area.position.y); GPU_IO::GP0 = GPU_IO::Command::WidthHeight(area.size.width, area.size.height); } - static void reset_cmd_buffer() { - GPU_IO::GP1 = GPU_IO::Command::ResetCMDBufer(); + static void set_draw_offset(int16_t x, int16_t y) { + wait_ready_for_CMD(); + GPU_IO::GP0 = GPU_IO::Command::SetDrawOffset(x, y); } - static void wait_ready_for_CMD() { - while(!GPU_IO::GPUSTAT.is_set(GPU_IO::GPUSTAT_t::GP0ReadyForCMD)); + static void reset_cmd_buffer() { + GPU_IO::GP1 = GPU_IO::Command::ResetCMDBufer(); } namespace DMA { diff --git a/src/Library/src/File/Processor/tim_processor.cpp b/src/Library/src/File/Processor/tim_processor.cpp index 0ff40dbf..d8fe3caf 100644 --- a/src/Library/src/File/Processor/tim_processor.cpp +++ b/src/Library/src/File/Processor/tim_processor.cpp @@ -44,7 +44,7 @@ namespace JabyEngine { SimpleTIMSize size_info; size_t words_left; //32bit values - constexpr SimpleTIMState(const SimpleTIM& dst_info) : dst_info(dst_info) { + constexpr SimpleTIMState(const SimpleTIM& dst_info) : dst_info(dst_info), words_left(0) { } }; diff --git a/src/Library/src/GPU/gpu.cpp b/src/Library/src/GPU/gpu.cpp index 94ffa438..c8cadcc1 100644 --- a/src/Library/src/GPU/gpu.cpp +++ b/src/Library/src/GPU/gpu.cpp @@ -37,10 +37,13 @@ namespace JabyEngine { __syscall_ReturnFromException(); } - void Display :: exchange_buffer_and_display() { - GPU::internal::set_draw_area(0, (PublicDisplay::Height*PublicDisplay::current_id)); + uint32_t Display :: exchange_buffer_and_display() { + const auto draw_area_y = (PublicDisplay::Height*PublicDisplay::current_id); + + GPU::internal::set_draw_area(0, draw_area_y); PublicDisplay::current_id ^= 1; GPU_IO::GP1 = GPU_IO::Command::DisplayArea(0, (PublicDisplay::Height*PublicDisplay::current_id)); + return draw_area_y; } void wait_vsync(uint8_t syncs) { @@ -53,6 +56,13 @@ namespace JabyEngine { while(vsync_count < syncs); vsync_count = 0; } + + void render(const uint32_t* data, size_t words) { + wait_ready_for_CMD(); + for(size_t n = 0; n < words; n++) { + GPU_IO::GP0 = data[n]; + } + } } #ifndef USE_NO$PSX @@ -70,10 +80,16 @@ namespace JabyEngine { } #endif //USE_NO$PSX - uint8_t swap_buffers_vsync(uint8_t syncs) { - // Wait finish draw + uint8_t swap_buffers_vsync(uint8_t syncs, bool clear_screen) { + // Waits for finish FIFO + internal::wait_ready_for_CMD(); + internal::wait_vsync(syncs); - internal::Display::exchange_buffer_and_display(); + const auto draw_offset_y = internal::Display::exchange_buffer_and_display(); + internal::set_draw_offset(0, draw_offset_y); + if(clear_screen) { + internal::quick_fill_fast(Color24::Black(), AreaU16{0, static_cast(draw_offset_y), Display::Width, Display::Height}); + } return Display::current_id; } } diff --git a/src/Library/src/run.cpp b/src/Library/src/run.cpp index 37038004..d0c9940e 100644 --- a/src/Library/src/run.cpp +++ b/src/Library/src/run.cpp @@ -1,3 +1,4 @@ +#include #include extern void main(); From d7e4330868b38f9dbeceb08f4a268cbb3dbc2813 Mon Sep 17 00:00:00 2001 From: jaby Date: Mon, 15 May 2023 21:14:37 +0200 Subject: [PATCH 023/588] Support textured triangles --- examples/PoolBox/application/src/main.cpp | 16 ++-- include/PSX/GPU/gpu_primitives.hpp | 97 ++++++++++++++++++----- include/PSX/GPU/gpu_types.hpp | 13 +++ 3 files changed, 101 insertions(+), 25 deletions(-) diff --git a/examples/PoolBox/application/src/main.cpp b/examples/PoolBox/application/src/main.cpp index 5ca09653..6c7efab9 100644 --- a/examples/PoolBox/application/src/main.cpp +++ b/examples/PoolBox/application/src/main.cpp @@ -39,17 +39,19 @@ static void load_assets() { } void main() { - const JabyEngine::GPU::POLY_F3 triangle( - JabyEngine::GPU::Color24(0x0, 0xFF, 0xFF), - { - {0, 0}, {320*2, 127}, {0, 255} - } - ); - printf("Hello PoolBox!\n"); + const JabyEngine::GPU::POLY_F3 triangle({{0, 0}, {64, 64}, {0, 64}}, JabyEngine::GPU::Color24(0x0, 0xFF, 0xFF)); + const JabyEngine::GPU::POLY_FT3 triangle2( + {{0, 0}, {64, 0}, {64, 64}}, {{0, 0}, {64, 0}, {64, 64}}, + JabyEngine::GPU::TPage(320, 0, JabyEngine::GPU::SemiTransparency::B_Half_add_F_Half, JabyEngine::GPU::TexturePageColor::$4bit), + JabyEngine::GPU::PageClut(320, 256), + JabyEngine::GPU::Color24(0xFF, 0xFF, 0xFF)); + load_assets(); while(true) { JabyEngine::GPU::render(triangle); + JabyEngine::GPU::render(triangle2); + JabyEngine::GPU::swap_buffers_vsync(2); } } diff --git a/include/PSX/GPU/gpu_primitives.hpp b/include/PSX/GPU/gpu_primitives.hpp index 5c890324..35f16e48 100644 --- a/include/PSX/GPU/gpu_primitives.hpp +++ b/include/PSX/GPU/gpu_primitives.hpp @@ -1,13 +1,14 @@ #ifndef __JABYENGINE_GPU_PRIMITIVES_HPP__ #define __JABYENGINE_GPU_PRIMITIVES_HPP__ #include "gpu_types.hpp" +#include namespace JabyEngine { namespace GPU { namespace internal { struct Code { - static constexpr uint8_t CmdValue = 0b001; - static constexpr auto BitCorrection = 24; + static constexpr uint8_t CmdValue = 0b001; + static constexpr auto BitCorrection = 24; static constexpr auto CmdID = BitRange::from_to(29 - BitCorrection, 31 - BitCorrection); static constexpr auto GouraudShading = Bit(28 - BitCorrection); @@ -24,6 +25,8 @@ namespace JabyEngine { uint8_t value = bit::value::set_normalized(0u, CmdID.with(CmdValue)); constexpr Code() = default; + constexpr Code(const Code& code) : value(code.value) { + } constexpr Code& set(Bit bit) { this->value = bit::set(this->value, bit); @@ -36,8 +39,11 @@ namespace JabyEngine { } }; - struct IsPrimitive { - static constexpr bool is_primitive = true; + // Concept for now + template + struct Hooked { + uint32_t hook; + T primitive; }; template @@ -63,27 +69,82 @@ namespace JabyEngine { } }; - // Concept for now - template - struct Hooked { - uint32_t hook; - T primitive; + struct IsPrimitive { + static constexpr bool is_primitive = true; + + typedef JabyEngine::GPU::internal::Code Code; }; } - struct POLY_F3 : public internal::IsPrimitive, public internal::CodeInterface { - static constexpr auto IdentityCode = internal::Code().set(internal::Code::FlatShading).set(internal::Code::TriVertics).set(internal::Code::Untextured).set(internal::Code::NonTransparent).set(internal::Code::NoBlendTexture); - - Color24 color; - internal::Code code = IdentityCode; - PositionI16 vertex[3]; + // Reexport for easier use + typedef JabyEngine::GPU_IO::SemiTransparency SemiTransparency; + typedef JabyEngine::GPU_IO::TexturePageColor TexturePageColor; - constexpr POLY_F3() = default; - constexpr POLY_F3(Color24 color, const PositionI16 (&verticies)[3]) : color(color), code(IdentityCode), vertex{verticies[0], verticies[1], verticies[2]} { + struct PageClut { + uint16_t value = 0; + + constexpr PageClut() = default; + constexpr PageClut(uint16_t x, uint16_t y) : value((y <<6 ) | ((x >> 4) & 0x3f)) { } }; - static_assert(sizeof(POLY_F3) == 16); + + struct TPage { + static constexpr auto TexturePageX = BitRange::from_to(0, 3); + static constexpr auto TexturePageY = BitRange::from_to(4, 4); + static constexpr auto SemiTransparency = BitRange::from_to(5, 6); + static constexpr auto TextureClut = BitRange::from_to(7, 8); + + uint16_t value = 0; + + constexpr TPage() = default; + constexpr TPage(uint16_t x, uint16_t y, ::JabyEngine::GPU::SemiTransparency transparency, TexturePageColor clut_color) : value(TexturePageX.as_value(x >> 6) | TexturePageY.as_value(y >> 8) | SemiTransparency.as_value(static_cast(transparency)) | TextureClut.as_value(static_cast(clut_color))) { + } + }; + + /* + 1 + / \ + 3 - 2 + */ + struct POLY_F3 : public internal::IsPrimitive, public internal::CodeInterface { + static constexpr auto IdentityCode = Code().set(Code::FlatShading).set(Code::TriVertics).set(Code::Untextured).set(Code::NonTransparent).set(Code::NoBlendTexture); + + Color24 color; + Code code = IdentityCode; + Vertex vertex0; + Vertex vertex1; + Vertex vertex2; + + constexpr POLY_F3() = default; + constexpr POLY_F3(const PositionI16 (&verticies)[3], Color24 color) : color(color), code(IdentityCode), vertex0(verticies[0]), vertex1(verticies[1]), vertex2(verticies[2]) { + } + }; + + struct POLY_FT3 : public internal::IsPrimitive, public internal::CodeInterface { + static constexpr auto IdentityCode = Code(POLY_F3::IdentityCode).set(Code::Textured); + + Color24 color; + Code code = IdentityCode; + Vertex vertex0; + PagePosition page0; + PageClut page_clut; + Vertex vertex1; + PagePosition page1; + TPage tpage; + Vertex vertex2; + PagePosition page2; + uint16_t padded; + + constexpr POLY_FT3() = default; + constexpr POLY_FT3(const PositionI16 (&verticies)[3], const PagePosition (&page_pos)[3], TPage tpage, PageClut clut, Color24 color) + : color(color), code(IdentityCode), vertex0(verticies[0]), page0(page_pos[0]), page_clut(clut), + vertex1(verticies[1]), page1(page_pos[1]), tpage(tpage), vertex2(verticies[2]), page2(page_pos[2]) { + } + }; + + static_assert(sizeof(POLY_F3) == 16); + static_assert(sizeof(POLY_FT3) == 28); } } diff --git a/include/PSX/GPU/gpu_types.hpp b/include/PSX/GPU/gpu_types.hpp index 302cf55d..f2318882 100644 --- a/include/PSX/GPU/gpu_types.hpp +++ b/include/PSX/GPU/gpu_types.hpp @@ -105,6 +105,16 @@ namespace JabyEngine { } }; + // Type used for primitives + struct PagePosition { + uint8_t u = 0; + uint8_t v = 0; + + constexpr PagePosition() = default; + constexpr PagePosition(uint8_t u, uint8_t v) : u(u), v(v) { + } + }; + typedef Position PositionI16; typedef Position PositionU16; @@ -113,6 +123,9 @@ namespace JabyEngine { typedef Area AreaI16; typedef Area AreaU16; + + // Type used for primitives + typedef PositionI16 Vertex; } } #endif //!__JABYENGINE_GPU_TYPES_HPP__ \ No newline at end of file From ef08bac90e64585a517ef0b95d62942637a01e8d Mon Sep 17 00:00:00 2001 From: jaby Date: Mon, 15 May 2023 21:59:06 +0200 Subject: [PATCH 024/588] Support Gouraud Shading --- examples/PoolBox/application/src/main.cpp | 6 ++ include/PSX/GPU/gpu_primitives.hpp | 84 +++++++++++++++++------ 2 files changed, 69 insertions(+), 21 deletions(-) diff --git a/examples/PoolBox/application/src/main.cpp b/examples/PoolBox/application/src/main.cpp index 6c7efab9..50f3028e 100644 --- a/examples/PoolBox/application/src/main.cpp +++ b/examples/PoolBox/application/src/main.cpp @@ -39,18 +39,24 @@ static void load_assets() { } void main() { + static constexpr auto FirstOffsetX = 64; const JabyEngine::GPU::POLY_F3 triangle({{0, 0}, {64, 64}, {0, 64}}, JabyEngine::GPU::Color24(0x0, 0xFF, 0xFF)); const JabyEngine::GPU::POLY_FT3 triangle2( {{0, 0}, {64, 0}, {64, 64}}, {{0, 0}, {64, 0}, {64, 64}}, JabyEngine::GPU::TPage(320, 0, JabyEngine::GPU::SemiTransparency::B_Half_add_F_Half, JabyEngine::GPU::TexturePageColor::$4bit), JabyEngine::GPU::PageClut(320, 256), JabyEngine::GPU::Color24(0xFF, 0xFF, 0xFF)); + const JabyEngine::GPU::POLY_G3 triangle3({ + {{0 + FirstOffsetX, 0}, {0xFF, 0x0, 0x0}}, + {{64 + FirstOffsetX, 64}, {0x0, 0xFF, 0x0}}, + {{0 + FirstOffsetX, 64}, {0x0, 0x0, 0xFF}}}); load_assets(); while(true) { JabyEngine::GPU::render(triangle); JabyEngine::GPU::render(triangle2); + JabyEngine::GPU::render(triangle3); JabyEngine::GPU::swap_buffers_vsync(2); } diff --git a/include/PSX/GPU/gpu_primitives.hpp b/include/PSX/GPU/gpu_primitives.hpp index 35f16e48..ec7ec4b8 100644 --- a/include/PSX/GPU/gpu_primitives.hpp +++ b/include/PSX/GPU/gpu_primitives.hpp @@ -110,41 +110,83 @@ namespace JabyEngine { struct POLY_F3 : public internal::IsPrimitive, public internal::CodeInterface { static constexpr auto IdentityCode = Code().set(Code::FlatShading).set(Code::TriVertics).set(Code::Untextured).set(Code::NonTransparent).set(Code::NoBlendTexture); - Color24 color; - Code code = IdentityCode; - Vertex vertex0; - Vertex vertex1; - Vertex vertex2; + Color24 color; // a + Code code = IdentityCode; // a + Vertex vertex0; // b + Vertex vertex1; // c + Vertex vertex2; // d constexpr POLY_F3() = default; - constexpr POLY_F3(const PositionI16 (&verticies)[3], Color24 color) : color(color), code(IdentityCode), vertex0(verticies[0]), vertex1(verticies[1]), vertex2(verticies[2]) { + constexpr POLY_F3(const Vertex (&verticies)[3], Color24 color) : color(color), code(IdentityCode), vertex0(verticies[0]), vertex1(verticies[1]), vertex2(verticies[2]) { } }; struct POLY_FT3 : public internal::IsPrimitive, public internal::CodeInterface { + struct VertexEx { + Vertex position; + PagePosition page; + }; static constexpr auto IdentityCode = Code(POLY_F3::IdentityCode).set(Code::Textured); - Color24 color; - Code code = IdentityCode; - Vertex vertex0; - PagePosition page0; - PageClut page_clut; - Vertex vertex1; - PagePosition page1; - TPage tpage; - Vertex vertex2; - PagePosition page2; - uint16_t padded; + Color24 color; // a + Code code = IdentityCode; // a + Vertex vertex0; // b + PagePosition page0; // c + PageClut page_clut; // c + Vertex vertex1; // d + PagePosition page1; // e + TPage tpage; // e + Vertex vertex2; // f + PagePosition page2; // g + uint16_t padded; // g constexpr POLY_FT3() = default; - constexpr POLY_FT3(const PositionI16 (&verticies)[3], const PagePosition (&page_pos)[3], TPage tpage, PageClut clut, Color24 color) - : color(color), code(IdentityCode), vertex0(verticies[0]), page0(page_pos[0]), page_clut(clut), - vertex1(verticies[1]), page1(page_pos[1]), tpage(tpage), vertex2(verticies[2]), page2(page_pos[2]) { - } + constexpr POLY_FT3(const Vertex (&verticies)[3], const PagePosition (&page_pos)[3], TPage tpage, PageClut clut, Color24 color) : + color(color), code(IdentityCode), + vertex0(verticies[0]), page0(page_pos[0]), page_clut(clut), + vertex1(verticies[1]), page1(page_pos[1]), tpage(tpage), + vertex2(verticies[2]), page2(page_pos[2]) {} + constexpr POLY_FT3(const VertexEx (&vertices_ex)[3], TPage tpage, PageClut clut, Color24 color) : + color(color), code(IdentityCode), + vertex0(vertices_ex[0].position), page0(vertices_ex[0].page), page_clut(clut), + vertex1(vertices_ex[1].position), page1(vertices_ex[1].page), tpage(tpage), + vertex2(vertices_ex[2].position), page2(vertices_ex[2].page) {} }; + struct POLY_G3 : public internal::IsPrimitive, public internal::CodeInterface { + struct VertexEx { + Vertex position; + Color24 color; + }; + static constexpr auto IdentityCode = Code(POLY_F3::IdentityCode).set(Code::GouraudShading); + + Color24 color0; // a + Code code = IdentityCode; // a + Vertex vertex0; // b + Color24 color1; // c + uint8_t pad1; // c + Vertex vertex1; // d + Color24 color2; // e + uint8_t pad2; // e + Vertex vertex2; // f + + constexpr POLY_G3() = default; + constexpr POLY_G3(const Vertex (&verticies)[3], const Color24 (&color)[3]) : + color0(color[0]), code(IdentityCode), vertex0(verticies[0]), + color1(color[1]), vertex1(verticies[1]), + color2(color[2]), vertex2(verticies[2]) {} + constexpr POLY_G3(const VertexEx (&verticies_ex)[3]) : + color0(verticies_ex[0].color), code(IdentityCode), vertex0(verticies_ex[0].position), + color1(verticies_ex[1].color), vertex1(verticies_ex[1].position), + color2(verticies_ex[2].color), vertex2(verticies_ex[2].position) {} + }; + + typedef POLY_F3 FlatTriangle; + typedef POLY_FT3 FlatTexturedTriangle; + static_assert(sizeof(POLY_F3) == 16); static_assert(sizeof(POLY_FT3) == 28); + static_assert(sizeof(POLY_G3) == 24); } } From cc9e91bebbf1d00268d0460468e3ef8cf26a1167 Mon Sep 17 00:00:00 2001 From: jaby Date: Wed, 17 May 2023 22:59:21 +0200 Subject: [PATCH 025/588] Support more primitives --- examples/PoolBox/application/src/main.cpp | 7 +++++ include/PSX/GPU/gpu_primitives.hpp | 38 +++++++++++++++++++++++ 2 files changed, 45 insertions(+) diff --git a/examples/PoolBox/application/src/main.cpp b/examples/PoolBox/application/src/main.cpp index 50f3028e..3ed8043a 100644 --- a/examples/PoolBox/application/src/main.cpp +++ b/examples/PoolBox/application/src/main.cpp @@ -50,6 +50,12 @@ void main() { {{0 + FirstOffsetX, 0}, {0xFF, 0x0, 0x0}}, {{64 + FirstOffsetX, 64}, {0x0, 0xFF, 0x0}}, {{0 + FirstOffsetX, 64}, {0x0, 0x0, 0xFF}}}); + const JabyEngine::GPU::POLY_GT3 triangle4({ + {{0 + FirstOffsetX, 0}, {0, 0}, {0xFF, 0x0, 0x0}}, + {{64 + FirstOffsetX, 64}, {64, 64}, {0x0, 0x0, 0xFF}}, + {{64 + FirstOffsetX, 0}, {64, 0}, {0x0, 0xFF, 0x0}}}, + JabyEngine::GPU::TPage(320, 0, JabyEngine::GPU::SemiTransparency::B_Half_add_F_Half, JabyEngine::GPU::TexturePageColor::$4bit), + JabyEngine::GPU::PageClut(320, 256)); load_assets(); @@ -57,6 +63,7 @@ void main() { JabyEngine::GPU::render(triangle); JabyEngine::GPU::render(triangle2); JabyEngine::GPU::render(triangle3); + JabyEngine::GPU::render(triangle4); JabyEngine::GPU::swap_buffers_vsync(2); } diff --git a/include/PSX/GPU/gpu_primitives.hpp b/include/PSX/GPU/gpu_primitives.hpp index ec7ec4b8..5bd49e69 100644 --- a/include/PSX/GPU/gpu_primitives.hpp +++ b/include/PSX/GPU/gpu_primitives.hpp @@ -181,12 +181,50 @@ namespace JabyEngine { color2(verticies_ex[2].color), vertex2(verticies_ex[2].position) {} }; + struct POLY_GT3 : public internal::IsPrimitive, public internal::CodeInterface { + struct VertexEx { + Vertex position; + PagePosition page; + Color24 color; + }; + static constexpr auto IdentityCode = Code(POLY_G3::IdentityCode).set(Code::Textured); + + Color24 color0; // a + Code code = IdentityCode; // a + Vertex vertex0; // b + PagePosition page0; // c + PageClut page_clut; // c + Color24 color1; // d + uint8_t padded1; // d + Vertex vertex1; // e + PagePosition page1; // f + TPage tpage; // f + Color24 color2; // g + uint8_t padded2; // g + Vertex vertex2; // h + PagePosition page2; // i + uint16_t padded3; // i + + constexpr POLY_GT3() = default; + constexpr POLY_GT3(const Vertex (&verticies)[3], const PagePosition (&page_pos)[3], const Color24 (&color)[3], TPage tpage, PageClut clut) : + color0(color[0]), code(IdentityCode), vertex0(verticies[0]), page0(page_pos[0]), page_clut(clut), + color1(color[1]), vertex1(verticies[1]), page1(page_pos[1]), tpage(tpage), + color2(color[2]), vertex2(verticies[2]), page2(page_pos[2]) {} + constexpr POLY_GT3(const VertexEx (&verticies_ex)[3], TPage tpage, PageClut clut) : + color0(verticies_ex[0].color), code(IdentityCode), vertex0(verticies_ex[0].position), page0(verticies_ex[0].page), page_clut(clut), + color1(verticies_ex[1].color), vertex1(verticies_ex[1].position), page1(verticies_ex[1].page), tpage(tpage), + color2(verticies_ex[2].color), vertex2(verticies_ex[2].position), page2(verticies_ex[2].page) {} + }; + typedef POLY_F3 FlatTriangle; typedef POLY_FT3 FlatTexturedTriangle; + typedef POLY_G3 GouraudTriangle; + typedef POLY_GT3 GouraudTexturedTriangle; static_assert(sizeof(POLY_F3) == 16); static_assert(sizeof(POLY_FT3) == 28); static_assert(sizeof(POLY_G3) == 24); + static_assert(sizeof(POLY_GT3) == 36); } } From 0cd9d0983a45a5c40d7e0e15b04338ff8be33c5f Mon Sep 17 00:00:00 2001 From: jaby Date: Thu, 18 May 2023 21:24:40 +0200 Subject: [PATCH 026/588] Prepare for quads --- examples/PoolBox/application/src/main.cpp | 8 +++++--- examples/PoolBox/assets/IconTexture.png | 3 +++ examples/PoolBox/assets/Makefile | 6 +++++- examples/PoolBox/iso/Config.xml | 1 + 4 files changed, 14 insertions(+), 4 deletions(-) create mode 100644 examples/PoolBox/assets/IconTexture.png diff --git a/examples/PoolBox/application/src/main.cpp b/examples/PoolBox/application/src/main.cpp index 3ed8043a..a3d61dc3 100644 --- a/examples/PoolBox/application/src/main.cpp +++ b/examples/PoolBox/application/src/main.cpp @@ -7,12 +7,14 @@ enum LBA { __jabyengine_start_lba_request __jabyengine_request_lba_for(FONT, "ASSETS/FONT.BIN"), + __jabyengine_request_lba_for(ICON, "ASSETS/ICON.BIN"), __jabyengine_end_lba_request }; static void load_assets() { static const JabyEngine::CDFile Assets[] = { - JabyEngine::CDFileBuilder::simple_tim(LBA::FONT, JabyEngine::SimpleTIM(320, 0, 320, 256)), + JabyEngine::CDFileBuilder::simple_tim(LBA::FONT, JabyEngine::SimpleTIM(320, 0, 320, 510)), + JabyEngine::CDFileBuilder::simple_tim(LBA::ICON, JabyEngine::SimpleTIM(320, 256, 320, 511)), }; const auto buffer_cfg = JabyEngine::CDFileProcessor::BufferConfiguration::new_default(); @@ -44,7 +46,7 @@ void main() { const JabyEngine::GPU::POLY_FT3 triangle2( {{0, 0}, {64, 0}, {64, 64}}, {{0, 0}, {64, 0}, {64, 64}}, JabyEngine::GPU::TPage(320, 0, JabyEngine::GPU::SemiTransparency::B_Half_add_F_Half, JabyEngine::GPU::TexturePageColor::$4bit), - JabyEngine::GPU::PageClut(320, 256), + JabyEngine::GPU::PageClut(320, 510), JabyEngine::GPU::Color24(0xFF, 0xFF, 0xFF)); const JabyEngine::GPU::POLY_G3 triangle3({ {{0 + FirstOffsetX, 0}, {0xFF, 0x0, 0x0}}, @@ -55,7 +57,7 @@ void main() { {{64 + FirstOffsetX, 64}, {64, 64}, {0x0, 0x0, 0xFF}}, {{64 + FirstOffsetX, 0}, {64, 0}, {0x0, 0xFF, 0x0}}}, JabyEngine::GPU::TPage(320, 0, JabyEngine::GPU::SemiTransparency::B_Half_add_F_Half, JabyEngine::GPU::TexturePageColor::$4bit), - JabyEngine::GPU::PageClut(320, 256)); + JabyEngine::GPU::PageClut(320, 510)); load_assets(); diff --git a/examples/PoolBox/assets/IconTexture.png b/examples/PoolBox/assets/IconTexture.png new file mode 100644 index 00000000..3fefb9c8 --- /dev/null +++ b/examples/PoolBox/assets/IconTexture.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f607226a3415638de7e65be597dd6e9e7049addc69334f88bcb94f4611454246 +size 28329 diff --git a/examples/PoolBox/assets/Makefile b/examples/PoolBox/assets/Makefile index ed4344e0..d898dbb8 100644 --- a/examples/PoolBox/assets/Makefile +++ b/examples/PoolBox/assets/Makefile @@ -7,7 +7,11 @@ $(OUTPUT_DIR)/TexturePage.bin: TexturePage.png @mkdir -p $(OUTPUT_DIR) jaby_engine_fconv --lz4 $< -o $@ simple-tim clut4 -all: $(OUTPUT_DIR)/TexturePage.bin +$(OUTPUT_DIR)/IconTexture.bin: IconTexture.png + @mkdir -p $(OUTPUT_DIR) + jaby_engine_fconv --lz4 $< -o $@ simple-tim clut4 + +all: $(OUTPUT_DIR)/TexturePage.bin $(OUTPUT_DIR)/IconTexture.bin clean: rm -fr $(OUTPUT_DIR) \ No newline at end of file diff --git a/examples/PoolBox/iso/Config.xml b/examples/PoolBox/iso/Config.xml index 2c265b3c..c2ef9bf9 100644 --- a/examples/PoolBox/iso/Config.xml +++ b/examples/PoolBox/iso/Config.xml @@ -8,6 +8,7 @@
application/bin/PSX-release/PoolBox.psexe
assets/bin/TexturePage.bin + assets/bin/IconTexture.bin \ No newline at end of file From 5d2404c8bf6d38f5ba6d5a1a39ca741ab5edccb4 Mon Sep 17 00:00:00 2001 From: jaby Date: Thu, 18 May 2023 22:14:09 +0200 Subject: [PATCH 027/588] Support POLY_F4 --- include/PSX/GPU/gpu_primitives.hpp | 39 +++++++++++++++++++++++++++--- include/PSX/GPU/gpu_types.hpp | 11 +++++++++ 2 files changed, 47 insertions(+), 3 deletions(-) diff --git a/include/PSX/GPU/gpu_primitives.hpp b/include/PSX/GPU/gpu_primitives.hpp index 5bd49e69..c61f229b 100644 --- a/include/PSX/GPU/gpu_primitives.hpp +++ b/include/PSX/GPU/gpu_primitives.hpp @@ -13,8 +13,8 @@ namespace JabyEngine { static constexpr auto CmdID = BitRange::from_to(29 - BitCorrection, 31 - BitCorrection); static constexpr auto GouraudShading = Bit(28 - BitCorrection); static constexpr auto FlatShading = !GouraudShading; - static constexpr auto QuardVertics = Bit(27 - BitCorrection); - static constexpr auto TriVertics = !QuardVertics; + static constexpr auto QuadVertics = Bit(27 - BitCorrection); + static constexpr auto TriVertics = !QuadVertics; static constexpr auto Textured = Bit(26 - BitCorrection); static constexpr auto Untextured = !Textured; static constexpr auto SemiTransparent = Bit(25 - BitCorrection); @@ -117,7 +117,11 @@ namespace JabyEngine { Vertex vertex2; // d constexpr POLY_F3() = default; - constexpr POLY_F3(const Vertex (&verticies)[3], Color24 color) : color(color), code(IdentityCode), vertex0(verticies[0]), vertex1(verticies[1]), vertex2(verticies[2]) { + constexpr POLY_F3(const Vertex (&verticies)[3], Color24 color) : + color(color), code(IdentityCode), + vertex0(verticies[0]), + vertex1(verticies[1]), + vertex2(verticies[2]) { } }; @@ -216,15 +220,44 @@ namespace JabyEngine { color2(verticies_ex[2].color), vertex2(verticies_ex[2].position), page2(verticies_ex[2].page) {} }; + struct POLY_F4 : public internal::IsPrimitive, public internal::CodeInterface { + static constexpr auto IdentityCode = Code(POLY_F3::IdentityCode).set(Code::QuadVertics); + + Color24 color; // a + Code code = IdentityCode; // a + Vertex vertex0; // b + Vertex vertex1; // c + Vertex vertex2; // d + Vertex vertex3; // e + + constexpr POLY_F4() = default; + constexpr POLY_F4(const Vertex (&verticies)[4], Color24 color) : + color(color), code(IdentityCode), + vertex0(verticies[0]), + vertex1(verticies[1]), + vertex2(verticies[2]), + vertex3(verticies[3]) {} + constexpr POLY_F4(const AreaI16& area, Color24 color) : POLY_F4({ + area.position, + area.position.move(area.size.width, 0), + area.position.move(0, area.size.height), + area.position.move(area.size.width, area.size.height)}, + color) {} + }; + typedef POLY_F3 FlatTriangle; typedef POLY_FT3 FlatTexturedTriangle; typedef POLY_G3 GouraudTriangle; typedef POLY_GT3 GouraudTexturedTriangle; + typedef POLY_F4 FlatRectangle; + static_assert(sizeof(POLY_F3) == 16); static_assert(sizeof(POLY_FT3) == 28); static_assert(sizeof(POLY_G3) == 24); static_assert(sizeof(POLY_GT3) == 36); + + static_assert(sizeof(POLY_F4) == 20); } } diff --git a/include/PSX/GPU/gpu_types.hpp b/include/PSX/GPU/gpu_types.hpp index f2318882..2219b1cc 100644 --- a/include/PSX/GPU/gpu_types.hpp +++ b/include/PSX/GPU/gpu_types.hpp @@ -81,6 +81,17 @@ namespace JabyEngine { constexpr Position() = default; constexpr Position(T x, T y) : x(x), y(y) { } + + constexpr Position& move(T dx, T dy) { + this->x += dx; + this->y += dy; + + return *this; + } + + constexpr Position move(T dx, T dy) const { + return Position(this->x, this->y).move(dx, dy); + } }; template From 1e0ba605b76519cb1d51f78a3e0796930780ddd3 Mon Sep 17 00:00:00 2001 From: jaby Date: Thu, 18 May 2023 22:14:38 +0200 Subject: [PATCH 028/588] Use POLY_F4 and clean up code --- examples/PoolBox/application/src/main.cpp | 59 +++++++++++++++++------ examples/PoolBox/assets/IconTexture.png | 4 +- 2 files changed, 45 insertions(+), 18 deletions(-) diff --git a/examples/PoolBox/application/src/main.cpp b/examples/PoolBox/application/src/main.cpp index a3d61dc3..cc0d3653 100644 --- a/examples/PoolBox/application/src/main.cpp +++ b/examples/PoolBox/application/src/main.cpp @@ -41,32 +41,59 @@ static void load_assets() { } void main() { - static constexpr auto FirstOffsetX = 64; - const JabyEngine::GPU::POLY_F3 triangle({{0, 0}, {64, 64}, {0, 64}}, JabyEngine::GPU::Color24(0x0, 0xFF, 0xFF)); - const JabyEngine::GPU::POLY_FT3 triangle2( - {{0, 0}, {64, 0}, {64, 64}}, {{0, 0}, {64, 0}, {64, 64}}, - JabyEngine::GPU::TPage(320, 0, JabyEngine::GPU::SemiTransparency::B_Half_add_F_Half, JabyEngine::GPU::TexturePageColor::$4bit), - JabyEngine::GPU::PageClut(320, 510), - JabyEngine::GPU::Color24(0xFF, 0xFF, 0xFF)); + static constexpr auto TriangleColor = JabyEngine::GPU::Color24(0x0, 0xFF, 0xFF); + static constexpr auto TriangleArea = JabyEngine::GPU::AreaI16({0, 0}, {64, 64}); + static constexpr auto TriangleTPage = JabyEngine::GPU::TPage(320, 0, JabyEngine::GPU::SemiTransparency::B_Half_add_F_Half, JabyEngine::GPU::TexturePageColor::$4bit); + static constexpr auto TriangleClut = JabyEngine::GPU::PageClut(320, 510); + + static constexpr auto RectangleColor = JabyEngine::GPU::Color24(0x80, 0x80, 0xFF); + static constexpr auto RectangleArea = JabyEngine::GPU::AreaI16({0, TriangleArea.size.height}, {80, 80}); + static constexpr auto RectangleTPage = JabyEngine::GPU::TPage(320, 256, JabyEngine::GPU::SemiTransparency::B_Half_add_F_Half, JabyEngine::GPU::TexturePageColor::$4bit); + static constexpr auto RectangleClut = JabyEngine::GPU::PageClut(320, 511); + + const JabyEngine::GPU::POLY_F3 triangle1({ + {TriangleArea.position.x, TriangleArea.position.y}, + {TriangleArea.size.width, TriangleArea.size.height}, + {TriangleArea.position.x, TriangleArea.size.height}}, + TriangleColor + ); + const JabyEngine::GPU::POLY_FT3 triangle2({ + {TriangleArea.position.x, TriangleArea.position.y}, + {TriangleArea.size.width, TriangleArea.position.y}, + {TriangleArea.size.width, TriangleArea.size.height}},{ + // Texture + {TriangleArea.position.x, TriangleArea.position.y}, + {TriangleArea.size.width, TriangleArea.position.y}, + {TriangleArea.size.width, TriangleArea.size.height}}, + TriangleTPage, + TriangleClut, + JabyEngine::GPU::Color24::White() + ); const JabyEngine::GPU::POLY_G3 triangle3({ - {{0 + FirstOffsetX, 0}, {0xFF, 0x0, 0x0}}, - {{64 + FirstOffsetX, 64}, {0x0, 0xFF, 0x0}}, - {{0 + FirstOffsetX, 64}, {0x0, 0x0, 0xFF}}}); + {triangle1.vertex0.move(TriangleArea.size.width, 0), JabyEngine::GPU::Color24::Red()}, + {triangle1.vertex1.move(TriangleArea.size.width, 0), JabyEngine::GPU::Color24::Green()}, + {triangle1.vertex2.move(TriangleArea.size.width, 0), JabyEngine::GPU::Color24::Blue()}} + ); const JabyEngine::GPU::POLY_GT3 triangle4({ - {{0 + FirstOffsetX, 0}, {0, 0}, {0xFF, 0x0, 0x0}}, - {{64 + FirstOffsetX, 64}, {64, 64}, {0x0, 0x0, 0xFF}}, - {{64 + FirstOffsetX, 0}, {64, 0}, {0x0, 0xFF, 0x0}}}, - JabyEngine::GPU::TPage(320, 0, JabyEngine::GPU::SemiTransparency::B_Half_add_F_Half, JabyEngine::GPU::TexturePageColor::$4bit), - JabyEngine::GPU::PageClut(320, 510)); + {triangle2.vertex0.move(TriangleArea.size.width, 0), triangle2.page0, JabyEngine::GPU::Color24::Red()}, + {triangle2.vertex1.move(TriangleArea.size.width, 0), triangle2.page1, JabyEngine::GPU::Color24::Blue()}, + {triangle2.vertex2.move(TriangleArea.size.width, 0), triangle2.page2, JabyEngine::GPU::Color24::Green()}}, + TriangleTPage, + TriangleClut + ); + + const JabyEngine::GPU::POLY_F4 rectangle(RectangleArea, RectangleColor); load_assets(); while(true) { - JabyEngine::GPU::render(triangle); + JabyEngine::GPU::render(triangle1); JabyEngine::GPU::render(triangle2); JabyEngine::GPU::render(triangle3); JabyEngine::GPU::render(triangle4); + JabyEngine::GPU::render(rectangle); + JabyEngine::GPU::swap_buffers_vsync(2); } } diff --git a/examples/PoolBox/assets/IconTexture.png b/examples/PoolBox/assets/IconTexture.png index 3fefb9c8..d1af743b 100644 --- a/examples/PoolBox/assets/IconTexture.png +++ b/examples/PoolBox/assets/IconTexture.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f607226a3415638de7e65be597dd6e9e7049addc69334f88bcb94f4611454246 -size 28329 +oid sha256:4ab27c037b82e661ec89c8275635bd585b1199848744894a200158b05e76783f +size 26787 From cc2c01138cbfe6ff3f3f9dbdc1004c71b00c8940 Mon Sep 17 00:00:00 2001 From: jaby Date: Fri, 19 May 2023 22:26:53 +0200 Subject: [PATCH 029/588] Support POLY_FT4 --- examples/PoolBox/application/src/main.cpp | 21 +++++--- include/PSX/GPU/gpu_primitives.hpp | 58 +++++++++++++++++++++-- include/PSX/GPU/gpu_types.hpp | 56 ++++++++++++++++------ 3 files changed, 109 insertions(+), 26 deletions(-) diff --git a/examples/PoolBox/application/src/main.cpp b/examples/PoolBox/application/src/main.cpp index cc0d3653..4f7be4fd 100644 --- a/examples/PoolBox/application/src/main.cpp +++ b/examples/PoolBox/application/src/main.cpp @@ -13,8 +13,8 @@ enum LBA { static void load_assets() { static const JabyEngine::CDFile Assets[] = { - JabyEngine::CDFileBuilder::simple_tim(LBA::FONT, JabyEngine::SimpleTIM(320, 0, 320, 510)), - JabyEngine::CDFileBuilder::simple_tim(LBA::ICON, JabyEngine::SimpleTIM(320, 256, 320, 511)), + JabyEngine::CDFileBuilder::simple_tim(LBA::FONT, JabyEngine::SimpleTIM(320, 0, 320, 511)), + JabyEngine::CDFileBuilder::simple_tim(LBA::ICON, JabyEngine::SimpleTIM(320, 256, 320, 510)), }; const auto buffer_cfg = JabyEngine::CDFileProcessor::BufferConfiguration::new_default(); @@ -44,12 +44,12 @@ void main() { static constexpr auto TriangleColor = JabyEngine::GPU::Color24(0x0, 0xFF, 0xFF); static constexpr auto TriangleArea = JabyEngine::GPU::AreaI16({0, 0}, {64, 64}); static constexpr auto TriangleTPage = JabyEngine::GPU::TPage(320, 0, JabyEngine::GPU::SemiTransparency::B_Half_add_F_Half, JabyEngine::GPU::TexturePageColor::$4bit); - static constexpr auto TriangleClut = JabyEngine::GPU::PageClut(320, 510); + static constexpr auto TriangleClut = JabyEngine::GPU::PageClut(320, 511); static constexpr auto RectangleColor = JabyEngine::GPU::Color24(0x80, 0x80, 0xFF); static constexpr auto RectangleArea = JabyEngine::GPU::AreaI16({0, TriangleArea.size.height}, {80, 80}); static constexpr auto RectangleTPage = JabyEngine::GPU::TPage(320, 256, JabyEngine::GPU::SemiTransparency::B_Half_add_F_Half, JabyEngine::GPU::TexturePageColor::$4bit); - static constexpr auto RectangleClut = JabyEngine::GPU::PageClut(320, 511); + static constexpr auto RectangleClut = JabyEngine::GPU::PageClut(320, 510); const JabyEngine::GPU::POLY_F3 triangle1({ {TriangleArea.position.x, TriangleArea.position.y}, @@ -67,7 +67,7 @@ void main() { {TriangleArea.size.width, TriangleArea.size.height}}, TriangleTPage, TriangleClut, - JabyEngine::GPU::Color24::White() + JabyEngine::GPU::Color24::Grey() ); const JabyEngine::GPU::POLY_G3 triangle3({ {triangle1.vertex0.move(TriangleArea.size.width, 0), JabyEngine::GPU::Color24::Red()}, @@ -82,7 +82,13 @@ void main() { TriangleClut ); - const JabyEngine::GPU::POLY_F4 rectangle(RectangleArea, RectangleColor); + const JabyEngine::GPU::POLY_F4 rectangle1(RectangleArea, RectangleColor); + const JabyEngine::GPU::POLY_FT4 rectangle2({ + RectangleArea.position.move(RectangleArea.size.width, 0), RectangleArea.size}, {0, 0}, + RectangleTPage, + RectangleClut, + JabyEngine::GPU::Color24::Grey() + ); load_assets(); @@ -92,7 +98,8 @@ void main() { JabyEngine::GPU::render(triangle3); JabyEngine::GPU::render(triangle4); - JabyEngine::GPU::render(rectangle); + JabyEngine::GPU::render(rectangle1); + JabyEngine::GPU::render(rectangle2); JabyEngine::GPU::swap_buffers_vsync(2); } diff --git a/include/PSX/GPU/gpu_primitives.hpp b/include/PSX/GPU/gpu_primitives.hpp index c61f229b..db0e357f 100644 --- a/include/PSX/GPU/gpu_primitives.hpp +++ b/include/PSX/GPU/gpu_primitives.hpp @@ -84,7 +84,7 @@ namespace JabyEngine { uint16_t value = 0; constexpr PageClut() = default; - constexpr PageClut(uint16_t x, uint16_t y) : value((y <<6 ) | ((x >> 4) & 0x3f)) { + constexpr PageClut(uint16_t x, uint16_t y) : value((y << 6) | ((x >> 4) & 0x3f)) { } }; @@ -142,7 +142,7 @@ namespace JabyEngine { TPage tpage; // e Vertex vertex2; // f PagePosition page2; // g - uint16_t padded; // g + uint16_t padded2; // g constexpr POLY_FT3() = default; constexpr POLY_FT3(const Vertex (&verticies)[3], const PagePosition (&page_pos)[3], TPage tpage, PageClut clut, Color24 color) : @@ -220,6 +220,13 @@ namespace JabyEngine { color2(verticies_ex[2].color), vertex2(verticies_ex[2].position), page2(verticies_ex[2].page) {} }; + + + /* + 1 - 2 + | | + 3 - 4 + */ struct POLY_F4 : public internal::IsPrimitive, public internal::CodeInterface { static constexpr auto IdentityCode = Code(POLY_F3::IdentityCode).set(Code::QuadVertics); @@ -245,19 +252,62 @@ namespace JabyEngine { color) {} }; + struct POLY_FT4 : public internal::IsPrimitive, public internal::CodeInterface { + typedef POLY_FT3::VertexEx VertexEx; + static constexpr auto IdentityCode = Code(POLY_FT3::IdentityCode).set(Code::QuadVertics); + + Color24 color; // a + Code code = IdentityCode; // a + Vertex vertex0; // b + PagePosition page0; // c + PageClut page_clut; // c + Vertex vertex1; // d + PagePosition page1; // e + TPage tpage; // e + Vertex vertex2; // f + PagePosition page2; // g + uint16_t padded2; // g + Vertex vertex3; // h + PagePosition page3; // i + uint16_t padded3; // i + + constexpr POLY_FT4() = default; + constexpr POLY_FT4(const Vertex (&verticies)[4], const PagePosition (&page_pos)[4], TPage tpage, PageClut clut, Color24 color) : + color(color), code(IdentityCode), + vertex0(verticies[0]), page0(page_pos[0]), page_clut(clut), + vertex1(verticies[1]), page1(page_pos[1]), tpage(tpage), + vertex2(verticies[2]), page2(page_pos[2]), + vertex3(verticies[3]), page3(page_pos[3]) {} + constexpr POLY_FT4(const VertexEx (&vertices_ex)[4], TPage tpage, PageClut clut, Color24 color) : + color(color), code(IdentityCode), + vertex0(vertices_ex[0].position), page0(vertices_ex[0].page), page_clut(clut), + vertex1(vertices_ex[1].position), page1(vertices_ex[1].page), tpage(tpage), + vertex2(vertices_ex[2].position), page2(vertices_ex[2].page), + vertex3(vertices_ex[3].position), page3(vertices_ex[3].page) {} + constexpr POLY_FT4(const AreaI16& area, const PagePosition& texture_pos, TPage tpage, PageClut clut, Color24 color) : POLY_FT4({ + {area.position, texture_pos}, + {area.position.move(area.size.width, 0), texture_pos.move(area.size.width, 0)}, + {area.position.move(0, area.size.height), texture_pos.move(0, area.size.height)}, + {area.position.move(area.size.width, area.size.height), texture_pos.move(area.size.width, area.size.height)}}, + tpage, clut, color + ) {} + }; + typedef POLY_F3 FlatTriangle; typedef POLY_FT3 FlatTexturedTriangle; typedef POLY_G3 GouraudTriangle; typedef POLY_GT3 GouraudTexturedTriangle; - typedef POLY_F4 FlatRectangle; + typedef POLY_F4 FlatRectangle; + typedef POLY_FT4 FlatTexturedRectangle; static_assert(sizeof(POLY_F3) == 16); static_assert(sizeof(POLY_FT3) == 28); static_assert(sizeof(POLY_G3) == 24); static_assert(sizeof(POLY_GT3) == 36); - static_assert(sizeof(POLY_F4) == 20); + static_assert(sizeof(POLY_F4) == 20); + static_assert(sizeof(POLY_FT4) == 36); } } diff --git a/include/PSX/GPU/gpu_types.hpp b/include/PSX/GPU/gpu_types.hpp index 2219b1cc..c03cc3c9 100644 --- a/include/PSX/GPU/gpu_types.hpp +++ b/include/PSX/GPU/gpu_types.hpp @@ -5,6 +5,33 @@ namespace JabyEngine { namespace GPU { + namespace internal { + template + struct XYMovement { + constexpr T& add(S dx, S dy) { + static_cast(this)->x += dx; + static_cast(this)->y += dy; + + return *static_cast(this); + } + + constexpr T& sub(S dx, S dy) { + static_cast(this)->x -= dx; + static_cast(this)->y -= dy; + + return *static_cast(this); + } + + constexpr T& move(S dx, S dy) { + return this->add(dx, dy); + } + + constexpr T move(S dx, S dy) const { + return T(static_cast(this)->x, static_cast(this)->y).move(dx, dy); + } + }; + } + struct Color24 { uint8_t red = 0; uint8_t green = 0; @@ -22,6 +49,10 @@ namespace JabyEngine { return Color24(0, 0, 0); } + static constexpr Color24 Grey() { + return Color24(0x80, 0x80, 0x80); + } + static constexpr Color24 White() { return Color24(0xFF, 0xFF, 0xFF); } @@ -74,24 +105,13 @@ namespace JabyEngine { }; template - struct Position { + struct Position : public internal::XYMovement, T> { T x = 0; T y = 0; constexpr Position() = default; constexpr Position(T x, T y) : x(x), y(y) { } - - constexpr Position& move(T dx, T dy) { - this->x += dx; - this->y += dy; - - return *this; - } - - constexpr Position move(T dx, T dy) const { - return Position(this->x, this->y).move(dx, dy); - } }; template @@ -117,9 +137,15 @@ namespace JabyEngine { }; // Type used for primitives - struct PagePosition { - uint8_t u = 0; - uint8_t v = 0; + struct PagePosition : public internal::XYMovement { + union { + uint8_t u = 0; + uint8_t x; + }; + union { + uint8_t v = 0; + uint8_t y; + }; constexpr PagePosition() = default; constexpr PagePosition(uint8_t u, uint8_t v) : u(u), v(v) { From e8bd3f9fb65528ac7b427c2b712bcce58636a076 Mon Sep 17 00:00:00 2001 From: jaby Date: Tue, 23 May 2023 20:39:11 +0200 Subject: [PATCH 030/588] Support gouraud rectangle --- examples/PoolBox/application/src/main.cpp | 7 ++++ include/PSX/GPU/gpu_primitives.hpp | 42 +++++++++++++++++++++-- 2 files changed, 47 insertions(+), 2 deletions(-) diff --git a/examples/PoolBox/application/src/main.cpp b/examples/PoolBox/application/src/main.cpp index 4f7be4fd..4f843be5 100644 --- a/examples/PoolBox/application/src/main.cpp +++ b/examples/PoolBox/application/src/main.cpp @@ -89,6 +89,12 @@ void main() { RectangleClut, JabyEngine::GPU::Color24::Grey() ); + const JabyEngine::GPU::POLY_G4 rectangle3( + {RectangleArea.position.move(RectangleArea.size.width*2, 0), RectangleArea.size}, { + JabyEngine::GPU::Color24::Red(), + JabyEngine::GPU::Color24::Blue(), + JabyEngine::GPU::Color24::Green(), + JabyEngine::GPU::Color24::White()}); load_assets(); @@ -100,6 +106,7 @@ void main() { JabyEngine::GPU::render(rectangle1); JabyEngine::GPU::render(rectangle2); + JabyEngine::GPU::render(rectangle3); JabyEngine::GPU::swap_buffers_vsync(2); } diff --git a/include/PSX/GPU/gpu_primitives.hpp b/include/PSX/GPU/gpu_primitives.hpp index db0e357f..dc2c3fbd 100644 --- a/include/PSX/GPU/gpu_primitives.hpp +++ b/include/PSX/GPU/gpu_primitives.hpp @@ -145,7 +145,7 @@ namespace JabyEngine { uint16_t padded2; // g constexpr POLY_FT3() = default; - constexpr POLY_FT3(const Vertex (&verticies)[3], const PagePosition (&page_pos)[3], TPage tpage, PageClut clut, Color24 color) : + constexpr POLY_FT3(const Vertex (&verticies)[3], const PagePosition (&page_pos)[3], TPage tpage, PageClut clut, Color24 color = Color24::Grey()) : color(color), code(IdentityCode), vertex0(verticies[0]), page0(page_pos[0]), page_clut(clut), vertex1(verticies[1]), page1(page_pos[1]), tpage(tpage), @@ -278,7 +278,7 @@ namespace JabyEngine { vertex1(verticies[1]), page1(page_pos[1]), tpage(tpage), vertex2(verticies[2]), page2(page_pos[2]), vertex3(verticies[3]), page3(page_pos[3]) {} - constexpr POLY_FT4(const VertexEx (&vertices_ex)[4], TPage tpage, PageClut clut, Color24 color) : + constexpr POLY_FT4(const VertexEx (&vertices_ex)[4], TPage tpage, PageClut clut, Color24 color = Color24::Grey()) : color(color), code(IdentityCode), vertex0(vertices_ex[0].position), page0(vertices_ex[0].page), page_clut(clut), vertex1(vertices_ex[1].position), page1(vertices_ex[1].page), tpage(tpage), @@ -293,6 +293,42 @@ namespace JabyEngine { ) {} }; + struct POLY_G4 : public internal::IsPrimitive, public internal::CodeInterface { + typedef POLY_G3::VertexEx VertexEx; + static constexpr auto IdentityCode = Code(POLY_G3::IdentityCode).set(Code::QuadVertics); + + Color24 color0; // a + Code code = IdentityCode; // a + Vertex vertex0; // b + Color24 color1; // c + uint8_t pad1; // c + Vertex vertex1; // d + Color24 color2; // e + uint8_t pad2; // e + Vertex vertex2; // f + Color24 color3; // g + uint8_t pad3; // g + Vertex vertex3; // h + + constexpr POLY_G4() = default; + constexpr POLY_G4(const Vertex (&verticies)[4], const Color24 (&color)[4]) : + color0(color[0]), code(IdentityCode), vertex0(verticies[0]), + color1(color[1]), vertex1(verticies[1]), + color2(color[2]), vertex2(verticies[2]), + color3(color[3]), vertex3(verticies[3]) {} + constexpr POLY_G4(const VertexEx (&verticies_ex)[4]) : + color0(verticies_ex[0].color), code(IdentityCode), vertex0(verticies_ex[0].position), + color1(verticies_ex[1].color), vertex1(verticies_ex[1].position), + color2(verticies_ex[2].color), vertex2(verticies_ex[2].position), + color3(verticies_ex[3].color), vertex3(verticies_ex[3].position) {} + constexpr POLY_G4(const AreaI16& area, const Color24 (&color)[4]) : POLY_G4({ + {area.position, color[0]}, + {area.position.move(area.size.width, 0), color[1]}, + {area.position.move(0, area.size.height), color[2]}, + {area.position.move(area.size.width, area.size.height), color[3]}} + ) {} + }; + typedef POLY_F3 FlatTriangle; typedef POLY_FT3 FlatTexturedTriangle; typedef POLY_G3 GouraudTriangle; @@ -300,6 +336,7 @@ namespace JabyEngine { typedef POLY_F4 FlatRectangle; typedef POLY_FT4 FlatTexturedRectangle; + typedef POLY_G4 GouraudRectangle; static_assert(sizeof(POLY_F3) == 16); static_assert(sizeof(POLY_FT3) == 28); @@ -308,6 +345,7 @@ namespace JabyEngine { static_assert(sizeof(POLY_F4) == 20); static_assert(sizeof(POLY_FT4) == 36); + static_assert(sizeof(POLY_G4) == 32); } } From a16f12a5ce9ee8cf261736bb70149bb99ad44279 Mon Sep 17 00:00:00 2001 From: jaby Date: Tue, 23 May 2023 21:11:01 +0200 Subject: [PATCH 031/588] Support POLY_GT4 --- examples/PoolBox/application/src/main.cpp | 10 +++++ include/PSX/GPU/gpu_primitives.hpp | 46 +++++++++++++++++++++++ 2 files changed, 56 insertions(+) diff --git a/examples/PoolBox/application/src/main.cpp b/examples/PoolBox/application/src/main.cpp index 4f843be5..4737a380 100644 --- a/examples/PoolBox/application/src/main.cpp +++ b/examples/PoolBox/application/src/main.cpp @@ -95,6 +95,15 @@ void main() { JabyEngine::GPU::Color24::Blue(), JabyEngine::GPU::Color24::Green(), JabyEngine::GPU::Color24::White()}); + const JabyEngine::GPU::POLY_GT4 rectangle4( + {RectangleArea.position.move(RectangleArea.size.width*3, 0), RectangleArea.size}, {0, 0}, + RectangleTPage, + RectangleClut, { + JabyEngine::GPU::Color24::Red(), + JabyEngine::GPU::Color24::Blue(), + JabyEngine::GPU::Color24::Green(), + JabyEngine::GPU::Color24::White()} + ); load_assets(); @@ -107,6 +116,7 @@ void main() { JabyEngine::GPU::render(rectangle1); JabyEngine::GPU::render(rectangle2); JabyEngine::GPU::render(rectangle3); + JabyEngine::GPU::render(rectangle4); JabyEngine::GPU::swap_buffers_vsync(2); } diff --git a/include/PSX/GPU/gpu_primitives.hpp b/include/PSX/GPU/gpu_primitives.hpp index dc2c3fbd..7192a811 100644 --- a/include/PSX/GPU/gpu_primitives.hpp +++ b/include/PSX/GPU/gpu_primitives.hpp @@ -329,6 +329,50 @@ namespace JabyEngine { ) {} }; + struct POLY_GT4 : public internal::IsPrimitive, public internal::CodeInterface { + typedef POLY_GT3::VertexEx VertexEx; + static constexpr auto IdentityCode = Code(POLY_GT3::IdentityCode).set(Code::QuadVertics); + + Color24 color0; // a + Code code = IdentityCode; // a + Vertex vertex0; // b + PagePosition page0; // c + PageClut page_clut; // c + Color24 color1; // d + uint8_t padded1; // d + Vertex vertex1; // e + PagePosition page1; // f + TPage tpage; // f + Color24 color2; // g + uint8_t padded2; // g + Vertex vertex2; // h + PagePosition page2; // i + uint16_t padded3; // i + Color24 color3; // j + uint8_t padded4; // j + Vertex vertex3; // k + PagePosition page3; // l + uint16_t padded5; // l + + constexpr POLY_GT4() = default; + constexpr POLY_GT4(const Vertex (&verticies)[4], const PagePosition (&page_pos)[4], const Color24 (&color)[4], TPage tpage, PageClut clut) : + color0(color[0]), code(IdentityCode), vertex0(verticies[0]), page0(page_pos[0]), page_clut(clut), + color1(color[1]), vertex1(verticies[1]), page1(page_pos[1]), tpage(tpage), + color2(color[2]), vertex2(verticies[2]), page2(page_pos[2]), + color3(color[3]), vertex3(verticies[3]), page3(page_pos[3]) {} + constexpr POLY_GT4(const VertexEx (&verticies_ex)[4], TPage tpage, PageClut clut) : + color0(verticies_ex[0].color), code(IdentityCode), vertex0(verticies_ex[0].position), page0(verticies_ex[0].page), page_clut(clut), + color1(verticies_ex[1].color), vertex1(verticies_ex[1].position), page1(verticies_ex[1].page), tpage(tpage), + color2(verticies_ex[2].color), vertex2(verticies_ex[2].position), page2(verticies_ex[2].page), + color3(verticies_ex[3].color), vertex3(verticies_ex[3].position), page3(verticies_ex[3].page) {} + constexpr POLY_GT4(const AreaI16& area, const PagePosition& texture_pos, TPage tpage, PageClut clut, const Color24 (&color)[4]) : POLY_GT4({ + {area.position, texture_pos, color[0]}, + {area.position.move(area.size.width, 0), texture_pos.move(area.size.width, 0), color[1]}, + {area.position.move(0, area.size.height), texture_pos.move(0, area.size.height), color[2]}, + {area.position.move(area.size.width, area.size.height), texture_pos.move(area.size.width, area.size.height), color[3]} + }, tpage, clut) {} + }; + typedef POLY_F3 FlatTriangle; typedef POLY_FT3 FlatTexturedTriangle; typedef POLY_G3 GouraudTriangle; @@ -337,6 +381,7 @@ namespace JabyEngine { typedef POLY_F4 FlatRectangle; typedef POLY_FT4 FlatTexturedRectangle; typedef POLY_G4 GouraudRectangle; + typedef POLY_GT4 GouraudTexturedRectangle; static_assert(sizeof(POLY_F3) == 16); static_assert(sizeof(POLY_FT3) == 28); @@ -346,6 +391,7 @@ namespace JabyEngine { static_assert(sizeof(POLY_F4) == 20); static_assert(sizeof(POLY_FT4) == 36); static_assert(sizeof(POLY_G4) == 32); + static_assert(sizeof(POLY_GT4) == 48); } } From 6d6396ad16cad71d6e57b89ad068a005b3574f40 Mon Sep 17 00:00:00 2001 From: jaby Date: Wed, 24 May 2023 20:55:43 +0200 Subject: [PATCH 032/588] Support GPU Primitives as constexpr --- examples/PoolBox/application/Makefile | 1 + examples/PoolBox/application/src/main.cpp | 129 +++++++++++----------- include/PSX/GPU/gpu_primitives.hpp | 104 ++++++++--------- include/PSX/GPU/gpu_types.hpp | 11 +- 4 files changed, 124 insertions(+), 121 deletions(-) diff --git a/examples/PoolBox/application/Makefile b/examples/PoolBox/application/Makefile index a35a6de4..efce152f 100644 --- a/examples/PoolBox/application/Makefile +++ b/examples/PoolBox/application/Makefile @@ -7,6 +7,7 @@ include $(JABY_ENGINE_DIR)/lib/Wildcard.mk SRCS = $(call rwildcard, src, c cpp) INCLUDES += -I$(JABY_ENGINE_DIR)/include +#CCFLAGS += -save-temps=obj include $(JABY_ENGINE_DIR)/lib/Makefile include $(JABY_ENGINE_DIR)/lib/PSEXETarget.mk diff --git a/examples/PoolBox/application/src/main.cpp b/examples/PoolBox/application/src/main.cpp index 4737a380..7739b392 100644 --- a/examples/PoolBox/application/src/main.cpp +++ b/examples/PoolBox/application/src/main.cpp @@ -11,6 +11,71 @@ enum LBA { __jabyengine_end_lba_request }; +// Some default values for the objects +static constexpr auto TriangleColor = JabyEngine::GPU::Color24(0x0, 0xFF, 0xFF); +static constexpr auto TriangleArea = JabyEngine::GPU::AreaI16({0, 0}, {64, 64}); +static constexpr auto TriangleTPage = JabyEngine::GPU::TPage(320, 0, JabyEngine::GPU::SemiTransparency::B_Half_add_F_Half, JabyEngine::GPU::TexturePageColor::$4bit); +static constexpr auto TriangleClut = JabyEngine::GPU::PageClut(320, 511); + +static constexpr auto RectangleColor = JabyEngine::GPU::Color24(0x80, 0x80, 0xFF); +static constexpr auto RectangleArea = JabyEngine::GPU::AreaI16({0, TriangleArea.size.height}, {80, 80}); +static constexpr auto RectangleTPage = JabyEngine::GPU::TPage(320, 256, JabyEngine::GPU::SemiTransparency::B_Half_add_F_Half, JabyEngine::GPU::TexturePageColor::$4bit); +static constexpr auto RectangleClut = JabyEngine::GPU::PageClut(320, 510); + +static constexpr const JabyEngine::GPU::POLY_F3 triangle1({ + {TriangleArea.position.x, TriangleArea.position.y}, + {TriangleArea.size.width, TriangleArea.size.height}, + {TriangleArea.position.x, TriangleArea.size.height}}, + TriangleColor +); +static constexpr const JabyEngine::GPU::POLY_FT3 triangle2({ + {TriangleArea.position.x, TriangleArea.position.y}, + {TriangleArea.size.width, TriangleArea.position.y}, + {TriangleArea.size.width, TriangleArea.size.height}},{ + // Texture + {TriangleArea.position.x, TriangleArea.position.y}, + {TriangleArea.size.width, TriangleArea.position.y}, + {TriangleArea.size.width, TriangleArea.size.height}}, + TriangleTPage, + TriangleClut, + JabyEngine::GPU::Color24::Grey() +); +static constexpr const JabyEngine::GPU::POLY_G3 triangle3({ + {triangle1.vertex0.move(TriangleArea.size.width, 0), JabyEngine::GPU::Color24::Red()}, + {triangle1.vertex1.move(TriangleArea.size.width, 0), JabyEngine::GPU::Color24::Green()}, + {triangle1.vertex2.move(TriangleArea.size.width, 0), JabyEngine::GPU::Color24::Blue()}} +); +static constexpr const JabyEngine::GPU::POLY_GT3 triangle4({ + {triangle2.vertex0.move(TriangleArea.size.width, 0), triangle2.page0, JabyEngine::GPU::Color24::Red()}, + {triangle2.vertex1.move(TriangleArea.size.width, 0), triangle2.page1, JabyEngine::GPU::Color24::Blue()}, + {triangle2.vertex2.move(TriangleArea.size.width, 0), triangle2.page2, JabyEngine::GPU::Color24::Green()}}, + TriangleTPage, + TriangleClut +); + +static constexpr const JabyEngine::GPU::POLY_F4 rectangle1(RectangleArea, RectangleColor); +static constexpr const JabyEngine::GPU::POLY_FT4 rectangle2({ + RectangleArea.position.move(RectangleArea.size.width, 0), RectangleArea.size}, {0, 0}, + RectangleTPage, + RectangleClut, + JabyEngine::GPU::Color24::Grey() +); +static constexpr const JabyEngine::GPU::POLY_G4 rectangle3( + {RectangleArea.position.move(RectangleArea.size.width*2, 0), RectangleArea.size}, { + JabyEngine::GPU::Color24::Red(), + JabyEngine::GPU::Color24::Blue(), + JabyEngine::GPU::Color24::Green(), + JabyEngine::GPU::Color24::White()}); +static constexpr const JabyEngine::GPU::POLY_GT4 rectangle4( + {RectangleArea.position.move(RectangleArea.size.width*3, 0), RectangleArea.size}, {0, 0}, + RectangleTPage, + RectangleClut, { + JabyEngine::GPU::Color24::Red(), + JabyEngine::GPU::Color24::Blue(), + JabyEngine::GPU::Color24::Green(), + JabyEngine::GPU::Color24::White()} +); + static void load_assets() { static const JabyEngine::CDFile Assets[] = { JabyEngine::CDFileBuilder::simple_tim(LBA::FONT, JabyEngine::SimpleTIM(320, 0, 320, 511)), @@ -41,70 +106,6 @@ static void load_assets() { } void main() { - static constexpr auto TriangleColor = JabyEngine::GPU::Color24(0x0, 0xFF, 0xFF); - static constexpr auto TriangleArea = JabyEngine::GPU::AreaI16({0, 0}, {64, 64}); - static constexpr auto TriangleTPage = JabyEngine::GPU::TPage(320, 0, JabyEngine::GPU::SemiTransparency::B_Half_add_F_Half, JabyEngine::GPU::TexturePageColor::$4bit); - static constexpr auto TriangleClut = JabyEngine::GPU::PageClut(320, 511); - - static constexpr auto RectangleColor = JabyEngine::GPU::Color24(0x80, 0x80, 0xFF); - static constexpr auto RectangleArea = JabyEngine::GPU::AreaI16({0, TriangleArea.size.height}, {80, 80}); - static constexpr auto RectangleTPage = JabyEngine::GPU::TPage(320, 256, JabyEngine::GPU::SemiTransparency::B_Half_add_F_Half, JabyEngine::GPU::TexturePageColor::$4bit); - static constexpr auto RectangleClut = JabyEngine::GPU::PageClut(320, 510); - - const JabyEngine::GPU::POLY_F3 triangle1({ - {TriangleArea.position.x, TriangleArea.position.y}, - {TriangleArea.size.width, TriangleArea.size.height}, - {TriangleArea.position.x, TriangleArea.size.height}}, - TriangleColor - ); - const JabyEngine::GPU::POLY_FT3 triangle2({ - {TriangleArea.position.x, TriangleArea.position.y}, - {TriangleArea.size.width, TriangleArea.position.y}, - {TriangleArea.size.width, TriangleArea.size.height}},{ - // Texture - {TriangleArea.position.x, TriangleArea.position.y}, - {TriangleArea.size.width, TriangleArea.position.y}, - {TriangleArea.size.width, TriangleArea.size.height}}, - TriangleTPage, - TriangleClut, - JabyEngine::GPU::Color24::Grey() - ); - const JabyEngine::GPU::POLY_G3 triangle3({ - {triangle1.vertex0.move(TriangleArea.size.width, 0), JabyEngine::GPU::Color24::Red()}, - {triangle1.vertex1.move(TriangleArea.size.width, 0), JabyEngine::GPU::Color24::Green()}, - {triangle1.vertex2.move(TriangleArea.size.width, 0), JabyEngine::GPU::Color24::Blue()}} - ); - const JabyEngine::GPU::POLY_GT3 triangle4({ - {triangle2.vertex0.move(TriangleArea.size.width, 0), triangle2.page0, JabyEngine::GPU::Color24::Red()}, - {triangle2.vertex1.move(TriangleArea.size.width, 0), triangle2.page1, JabyEngine::GPU::Color24::Blue()}, - {triangle2.vertex2.move(TriangleArea.size.width, 0), triangle2.page2, JabyEngine::GPU::Color24::Green()}}, - TriangleTPage, - TriangleClut - ); - - const JabyEngine::GPU::POLY_F4 rectangle1(RectangleArea, RectangleColor); - const JabyEngine::GPU::POLY_FT4 rectangle2({ - RectangleArea.position.move(RectangleArea.size.width, 0), RectangleArea.size}, {0, 0}, - RectangleTPage, - RectangleClut, - JabyEngine::GPU::Color24::Grey() - ); - const JabyEngine::GPU::POLY_G4 rectangle3( - {RectangleArea.position.move(RectangleArea.size.width*2, 0), RectangleArea.size}, { - JabyEngine::GPU::Color24::Red(), - JabyEngine::GPU::Color24::Blue(), - JabyEngine::GPU::Color24::Green(), - JabyEngine::GPU::Color24::White()}); - const JabyEngine::GPU::POLY_GT4 rectangle4( - {RectangleArea.position.move(RectangleArea.size.width*3, 0), RectangleArea.size}, {0, 0}, - RectangleTPage, - RectangleClut, { - JabyEngine::GPU::Color24::Red(), - JabyEngine::GPU::Color24::Blue(), - JabyEngine::GPU::Color24::Green(), - JabyEngine::GPU::Color24::White()} - ); - load_assets(); while(true) { diff --git a/include/PSX/GPU/gpu_primitives.hpp b/include/PSX/GPU/gpu_primitives.hpp index 7192a811..91850805 100644 --- a/include/PSX/GPU/gpu_primitives.hpp +++ b/include/PSX/GPU/gpu_primitives.hpp @@ -145,16 +145,15 @@ namespace JabyEngine { uint16_t padded2; // g constexpr POLY_FT3() = default; - constexpr POLY_FT3(const Vertex (&verticies)[3], const PagePosition (&page_pos)[3], TPage tpage, PageClut clut, Color24 color = Color24::Grey()) : - color(color), code(IdentityCode), - vertex0(verticies[0]), page0(page_pos[0]), page_clut(clut), - vertex1(verticies[1]), page1(page_pos[1]), tpage(tpage), - vertex2(verticies[2]), page2(page_pos[2]) {} + constexpr POLY_FT3(const Vertex (&verticies)[3], const PagePosition (&page_pos)[3], TPage tpage, PageClut clut, Color24 color = Color24::Grey()) : POLY_FT3({ + {verticies[0], page_pos[0]}, + {verticies[1], page_pos[1]}, + {verticies[2], page_pos[2]}}, tpage, clut, color) {} constexpr POLY_FT3(const VertexEx (&vertices_ex)[3], TPage tpage, PageClut clut, Color24 color) : color(color), code(IdentityCode), vertex0(vertices_ex[0].position), page0(vertices_ex[0].page), page_clut(clut), vertex1(vertices_ex[1].position), page1(vertices_ex[1].page), tpage(tpage), - vertex2(vertices_ex[2].position), page2(vertices_ex[2].page) {} + vertex2(vertices_ex[2].position), page2(vertices_ex[2].page), padded2(0) {} }; struct POLY_G3 : public internal::IsPrimitive, public internal::CodeInterface { @@ -175,14 +174,14 @@ namespace JabyEngine { Vertex vertex2; // f constexpr POLY_G3() = default; - constexpr POLY_G3(const Vertex (&verticies)[3], const Color24 (&color)[3]) : - color0(color[0]), code(IdentityCode), vertex0(verticies[0]), - color1(color[1]), vertex1(verticies[1]), - color2(color[2]), vertex2(verticies[2]) {} + constexpr POLY_G3(const Vertex (&verticies)[3], const Color24 (&color)[3]) : POLY_G3({ + {verticies[0], color[0]}, + {verticies[1], color[1]}, + {verticies[2], color[2]}}) {} constexpr POLY_G3(const VertexEx (&verticies_ex)[3]) : color0(verticies_ex[0].color), code(IdentityCode), vertex0(verticies_ex[0].position), - color1(verticies_ex[1].color), vertex1(verticies_ex[1].position), - color2(verticies_ex[2].color), vertex2(verticies_ex[2].position) {} + color1(verticies_ex[1].color), pad1(0), vertex1(verticies_ex[1].position), + color2(verticies_ex[2].color), pad2(0), vertex2(verticies_ex[2].position) {} }; struct POLY_GT3 : public internal::IsPrimitive, public internal::CodeInterface { @@ -199,25 +198,25 @@ namespace JabyEngine { PagePosition page0; // c PageClut page_clut; // c Color24 color1; // d - uint8_t padded1; // d + uint8_t pad1; // d Vertex vertex1; // e PagePosition page1; // f TPage tpage; // f Color24 color2; // g - uint8_t padded2; // g + uint8_t pad2; // g Vertex vertex2; // h PagePosition page2; // i - uint16_t padded3; // i + uint16_t pad3; // i constexpr POLY_GT3() = default; - constexpr POLY_GT3(const Vertex (&verticies)[3], const PagePosition (&page_pos)[3], const Color24 (&color)[3], TPage tpage, PageClut clut) : - color0(color[0]), code(IdentityCode), vertex0(verticies[0]), page0(page_pos[0]), page_clut(clut), - color1(color[1]), vertex1(verticies[1]), page1(page_pos[1]), tpage(tpage), - color2(color[2]), vertex2(verticies[2]), page2(page_pos[2]) {} + constexpr POLY_GT3(const Vertex (&verticies)[3], const PagePosition (&page_pos)[3], const Color24 (&color)[3], TPage tpage, PageClut clut) : POLY_GT3({ + {verticies[0], page_pos[0], color[0]}, + {verticies[1], page_pos[1], color[1]}, + {verticies[2], page_pos[2], color[2]}}, tpage, clut) {} constexpr POLY_GT3(const VertexEx (&verticies_ex)[3], TPage tpage, PageClut clut) : color0(verticies_ex[0].color), code(IdentityCode), vertex0(verticies_ex[0].position), page0(verticies_ex[0].page), page_clut(clut), - color1(verticies_ex[1].color), vertex1(verticies_ex[1].position), page1(verticies_ex[1].page), tpage(tpage), - color2(verticies_ex[2].color), vertex2(verticies_ex[2].position), page2(verticies_ex[2].page) {} + color1(verticies_ex[1].color), pad1(0), vertex1(verticies_ex[1].position), page1(verticies_ex[1].page), tpage(tpage), + color2(verticies_ex[2].color), pad2(0), vertex2(verticies_ex[2].position), page2(verticies_ex[2].page), pad3(0) {} }; @@ -266,24 +265,23 @@ namespace JabyEngine { TPage tpage; // e Vertex vertex2; // f PagePosition page2; // g - uint16_t padded2; // g + uint16_t pad2; // g Vertex vertex3; // h PagePosition page3; // i - uint16_t padded3; // i + uint16_t pad3; // i constexpr POLY_FT4() = default; - constexpr POLY_FT4(const Vertex (&verticies)[4], const PagePosition (&page_pos)[4], TPage tpage, PageClut clut, Color24 color) : - color(color), code(IdentityCode), - vertex0(verticies[0]), page0(page_pos[0]), page_clut(clut), - vertex1(verticies[1]), page1(page_pos[1]), tpage(tpage), - vertex2(verticies[2]), page2(page_pos[2]), - vertex3(verticies[3]), page3(page_pos[3]) {} + constexpr POLY_FT4(const Vertex (&verticies)[4], const PagePosition (&page_pos)[4], TPage tpage, PageClut clut, Color24 color) : POLY_FT4({ + {verticies[0], page_pos[0]}, + {verticies[1], page_pos[1]}, + {verticies[2], page_pos[2]}, + {verticies[3], page_pos[3]}}, tpage, clut, color) {} constexpr POLY_FT4(const VertexEx (&vertices_ex)[4], TPage tpage, PageClut clut, Color24 color = Color24::Grey()) : color(color), code(IdentityCode), vertex0(vertices_ex[0].position), page0(vertices_ex[0].page), page_clut(clut), vertex1(vertices_ex[1].position), page1(vertices_ex[1].page), tpage(tpage), - vertex2(vertices_ex[2].position), page2(vertices_ex[2].page), - vertex3(vertices_ex[3].position), page3(vertices_ex[3].page) {} + vertex2(vertices_ex[2].position), page2(vertices_ex[2].page), pad2(0), + vertex3(vertices_ex[3].position), page3(vertices_ex[3].page), pad3(0) {} constexpr POLY_FT4(const AreaI16& area, const PagePosition& texture_pos, TPage tpage, PageClut clut, Color24 color) : POLY_FT4({ {area.position, texture_pos}, {area.position.move(area.size.width, 0), texture_pos.move(area.size.width, 0)}, @@ -311,16 +309,17 @@ namespace JabyEngine { Vertex vertex3; // h constexpr POLY_G4() = default; - constexpr POLY_G4(const Vertex (&verticies)[4], const Color24 (&color)[4]) : - color0(color[0]), code(IdentityCode), vertex0(verticies[0]), - color1(color[1]), vertex1(verticies[1]), - color2(color[2]), vertex2(verticies[2]), - color3(color[3]), vertex3(verticies[3]) {} + constexpr POLY_G4(const Vertex (&verticies)[4], const Color24 (&color)[4]) : POLY_G4({ + {verticies[0], color[0]}, + {verticies[1], color[1]}, + {verticies[2], color[2]}, + {verticies[3], color[3]} + }) {} constexpr POLY_G4(const VertexEx (&verticies_ex)[4]) : color0(verticies_ex[0].color), code(IdentityCode), vertex0(verticies_ex[0].position), - color1(verticies_ex[1].color), vertex1(verticies_ex[1].position), - color2(verticies_ex[2].color), vertex2(verticies_ex[2].position), - color3(verticies_ex[3].color), vertex3(verticies_ex[3].position) {} + color1(verticies_ex[1].color), pad1(0), vertex1(verticies_ex[1].position), + color2(verticies_ex[2].color), pad2(0), vertex2(verticies_ex[2].position), + color3(verticies_ex[3].color), pad3(0), vertex3(verticies_ex[3].position) {} constexpr POLY_G4(const AreaI16& area, const Color24 (&color)[4]) : POLY_G4({ {area.position, color[0]}, {area.position.move(area.size.width, 0), color[1]}, @@ -339,32 +338,33 @@ namespace JabyEngine { PagePosition page0; // c PageClut page_clut; // c Color24 color1; // d - uint8_t padded1; // d + uint8_t pad1; // d Vertex vertex1; // e PagePosition page1; // f TPage tpage; // f Color24 color2; // g - uint8_t padded2; // g + uint8_t pad2; // g Vertex vertex2; // h PagePosition page2; // i - uint16_t padded3; // i + uint16_t pad3; // i Color24 color3; // j - uint8_t padded4; // j + uint8_t pad4; // j Vertex vertex3; // k PagePosition page3; // l - uint16_t padded5; // l + uint16_t pad5; // l constexpr POLY_GT4() = default; - constexpr POLY_GT4(const Vertex (&verticies)[4], const PagePosition (&page_pos)[4], const Color24 (&color)[4], TPage tpage, PageClut clut) : - color0(color[0]), code(IdentityCode), vertex0(verticies[0]), page0(page_pos[0]), page_clut(clut), - color1(color[1]), vertex1(verticies[1]), page1(page_pos[1]), tpage(tpage), - color2(color[2]), vertex2(verticies[2]), page2(page_pos[2]), - color3(color[3]), vertex3(verticies[3]), page3(page_pos[3]) {} + constexpr POLY_GT4(const Vertex (&verticies)[4], const PagePosition (&page_pos)[4], const Color24 (&color)[4], TPage tpage, PageClut clut) : POLY_GT4({ + {verticies[0], page_pos[0], color[0]}, + {verticies[1], page_pos[1], color[1]}, + {verticies[2], page_pos[2], color[2]}, + {verticies[3], page_pos[3], color[3]}, + }, tpage, clut) {} constexpr POLY_GT4(const VertexEx (&verticies_ex)[4], TPage tpage, PageClut clut) : color0(verticies_ex[0].color), code(IdentityCode), vertex0(verticies_ex[0].position), page0(verticies_ex[0].page), page_clut(clut), - color1(verticies_ex[1].color), vertex1(verticies_ex[1].position), page1(verticies_ex[1].page), tpage(tpage), - color2(verticies_ex[2].color), vertex2(verticies_ex[2].position), page2(verticies_ex[2].page), - color3(verticies_ex[3].color), vertex3(verticies_ex[3].position), page3(verticies_ex[3].page) {} + color1(verticies_ex[1].color), pad1(0), vertex1(verticies_ex[1].position), page1(verticies_ex[1].page), tpage(tpage), + color2(verticies_ex[2].color), pad2(0), vertex2(verticies_ex[2].position), page2(verticies_ex[2].page), pad3(0), + color3(verticies_ex[3].color), pad4(0), vertex3(verticies_ex[3].position), page3(verticies_ex[3].page), pad5(0) {} constexpr POLY_GT4(const AreaI16& area, const PagePosition& texture_pos, TPage tpage, PageClut clut, const Color24 (&color)[4]) : POLY_GT4({ {area.position, texture_pos, color[0]}, {area.position.move(area.size.width, 0), texture_pos.move(area.size.width, 0), color[1]}, diff --git a/include/PSX/GPU/gpu_types.hpp b/include/PSX/GPU/gpu_types.hpp index c03cc3c9..c1caeb13 100644 --- a/include/PSX/GPU/gpu_types.hpp +++ b/include/PSX/GPU/gpu_types.hpp @@ -139,16 +139,17 @@ namespace JabyEngine { // Type used for primitives struct PagePosition : public internal::XYMovement { union { - uint8_t u = 0; - uint8_t x; + uint8_t x = 0; + uint8_t u; }; + union { - uint8_t v = 0; - uint8_t y; + uint8_t y = 0; + uint8_t v; }; constexpr PagePosition() = default; - constexpr PagePosition(uint8_t u, uint8_t v) : u(u), v(v) { + constexpr PagePosition(uint8_t u, uint8_t v) : x(u), y(v) { //< Activate x and y to use XYMovement during constexpr } }; From 1832f6b066aec177b2a0621fcd8aca8087fd6a8a Mon Sep 17 00:00:00 2001 From: jaby Date: Wed, 24 May 2023 22:06:56 +0200 Subject: [PATCH 033/588] Cleaned up primitives --- examples/PoolBox/application/src/main.cpp | 18 +- .../GPU/Primitives/primitive_poly_types.hpp | 339 +++++++++++++++ .../Primitives/primitive_support_types.hpp | 70 ++++ include/PSX/GPU/gpu_primitives.hpp | 396 +----------------- 4 files changed, 419 insertions(+), 404 deletions(-) create mode 100644 include/PSX/GPU/Primitives/primitive_poly_types.hpp create mode 100644 include/PSX/GPU/Primitives/primitive_support_types.hpp diff --git a/examples/PoolBox/application/src/main.cpp b/examples/PoolBox/application/src/main.cpp index 7739b392..e8de2b71 100644 --- a/examples/PoolBox/application/src/main.cpp +++ b/examples/PoolBox/application/src/main.cpp @@ -22,13 +22,13 @@ static constexpr auto RectangleArea = JabyEngine::GPU::AreaI16({0, TriangleArea static constexpr auto RectangleTPage = JabyEngine::GPU::TPage(320, 256, JabyEngine::GPU::SemiTransparency::B_Half_add_F_Half, JabyEngine::GPU::TexturePageColor::$4bit); static constexpr auto RectangleClut = JabyEngine::GPU::PageClut(320, 510); -static constexpr const JabyEngine::GPU::POLY_F3 triangle1({ +static constexpr const auto triangle1 = JabyEngine::GPU::POLY_F3({ {TriangleArea.position.x, TriangleArea.position.y}, {TriangleArea.size.width, TriangleArea.size.height}, {TriangleArea.position.x, TriangleArea.size.height}}, TriangleColor ); -static constexpr const JabyEngine::GPU::POLY_FT3 triangle2({ +static constexpr const auto triangle2 = JabyEngine::GPU::POLY_FT3({ {TriangleArea.position.x, TriangleArea.position.y}, {TriangleArea.size.width, TriangleArea.position.y}, {TriangleArea.size.width, TriangleArea.size.height}},{ @@ -40,12 +40,12 @@ static constexpr const JabyEngine::GPU::POLY_FT3 triangle2({ TriangleClut, JabyEngine::GPU::Color24::Grey() ); -static constexpr const JabyEngine::GPU::POLY_G3 triangle3({ +static constexpr const auto triangle3 = JabyEngine::GPU::POLY_G3({ {triangle1.vertex0.move(TriangleArea.size.width, 0), JabyEngine::GPU::Color24::Red()}, {triangle1.vertex1.move(TriangleArea.size.width, 0), JabyEngine::GPU::Color24::Green()}, {triangle1.vertex2.move(TriangleArea.size.width, 0), JabyEngine::GPU::Color24::Blue()}} ); -static constexpr const JabyEngine::GPU::POLY_GT3 triangle4({ +static constexpr const auto triangle4 = JabyEngine::GPU::POLY_GT3({ {triangle2.vertex0.move(TriangleArea.size.width, 0), triangle2.page0, JabyEngine::GPU::Color24::Red()}, {triangle2.vertex1.move(TriangleArea.size.width, 0), triangle2.page1, JabyEngine::GPU::Color24::Blue()}, {triangle2.vertex2.move(TriangleArea.size.width, 0), triangle2.page2, JabyEngine::GPU::Color24::Green()}}, @@ -53,20 +53,20 @@ static constexpr const JabyEngine::GPU::POLY_GT3 triangle4({ TriangleClut ); -static constexpr const JabyEngine::GPU::POLY_F4 rectangle1(RectangleArea, RectangleColor); -static constexpr const JabyEngine::GPU::POLY_FT4 rectangle2({ +static constexpr const auto rectangle1 = JabyEngine::GPU::POLY_F4(RectangleArea, RectangleColor); +static constexpr const auto rectangle2 = JabyEngine::GPU::POLY_FT4({ RectangleArea.position.move(RectangleArea.size.width, 0), RectangleArea.size}, {0, 0}, RectangleTPage, RectangleClut, JabyEngine::GPU::Color24::Grey() ); -static constexpr const JabyEngine::GPU::POLY_G4 rectangle3( +static constexpr const auto rectangle3 = JabyEngine::GPU::POLY_G4( {RectangleArea.position.move(RectangleArea.size.width*2, 0), RectangleArea.size}, { JabyEngine::GPU::Color24::Red(), JabyEngine::GPU::Color24::Blue(), JabyEngine::GPU::Color24::Green(), JabyEngine::GPU::Color24::White()}); -static constexpr const JabyEngine::GPU::POLY_GT4 rectangle4( +static constexpr const auto rectangle4 = JabyEngine::GPU::POLY_GT4( {RectangleArea.position.move(RectangleArea.size.width*3, 0), RectangleArea.size}, {0, 0}, RectangleTPage, RectangleClut, { @@ -107,7 +107,7 @@ static void load_assets() { void main() { load_assets(); - + while(true) { JabyEngine::GPU::render(triangle1); JabyEngine::GPU::render(triangle2); diff --git a/include/PSX/GPU/Primitives/primitive_poly_types.hpp b/include/PSX/GPU/Primitives/primitive_poly_types.hpp new file mode 100644 index 00000000..8b02ff88 --- /dev/null +++ b/include/PSX/GPU/Primitives/primitive_poly_types.hpp @@ -0,0 +1,339 @@ +#ifndef __JABYENGINE_PRIMITIVE_POLY_TYPES_HPP__ +#define __JABYENGINE_PRIMITIVE_POLY_TYPES_HPP__ +#include "primitive_support_types.hpp" + +namespace JabyEngine { + namespace GPU { + namespace internal { + struct Code : public CodeBase { + static constexpr uint8_t CmdValue = 0b001; + + static constexpr auto GouraudShading = Bit(28 - BitCorrection); + static constexpr auto FlatShading = !GouraudShading; + static constexpr auto QuadVertics = Bit(27 - BitCorrection); + static constexpr auto TriVertics = !QuadVertics; + static constexpr auto Textured = Bit(26 - BitCorrection); + static constexpr auto Untextured = !Textured; + static constexpr auto SemiTransparent = Bit(25 - BitCorrection); + static constexpr auto NonTransparent = !SemiTransparent; + static constexpr auto NoBlendTexture = Bit(24 - BitCorrection); + static constexpr auto BlendTexture = !NoBlendTexture; + }; + + template + struct CodeInterface { + typedef ::JabyEngine::GPU::internal::Code Code; + + constexpr T& set_semi_transparent(bool set = true) { + if(set) { + static_cast(this)->code.set(Code::SemiTransparent); + } + else { + static_cast(this)->code.set(Code::NonTransparent); + } + return *static_cast(this); + } + + constexpr T& set_texture_blending(bool set = true) { + if(set) { + static_cast(this)->code.set(Code::BlendTexture); + } + else { + static_cast(this)->code.set(Code::NoBlendTexture); + } + return *static_cast(this); + } + }; + } + + /* + 1 + / \ + 3 - 2 + */ + struct POLY_F3 : public internal::IsPrimitive, public internal::CodeInterface { + static constexpr auto IdentityCode = Code().set(Code::FlatShading).set(Code::TriVertics).set(Code::Untextured).set(Code::NonTransparent); + + Color24 color; // a + Code code = IdentityCode; // a + Vertex vertex0; // b + Vertex vertex1; // c + Vertex vertex2; // d + + constexpr POLY_F3() = default; + constexpr POLY_F3(const Vertex (&verticies)[3], Color24 color) : + color(color), code(IdentityCode), + vertex0(verticies[0]), + vertex1(verticies[1]), + vertex2(verticies[2]) { + } + }; + + struct POLY_FT3 : public internal::IsPrimitive, public internal::CodeInterface { + struct VertexEx { + Vertex position; + PagePosition page; + }; + static constexpr auto IdentityCode = Code(POLY_F3::IdentityCode).set(Code::Textured); + + Color24 color; // a + Code code = IdentityCode; // a + Vertex vertex0; // b + PagePosition page0; // c + PageClut page_clut; // c + Vertex vertex1; // d + PagePosition page1; // e + TPage tpage; // e + Vertex vertex2; // f + PagePosition page2; // g + uint16_t padded2; // g + + constexpr POLY_FT3() = default; + constexpr POLY_FT3(const Vertex (&verticies)[3], const PagePosition (&page_pos)[3], TPage tpage, PageClut clut, Color24 color = Color24::Grey()) : POLY_FT3({ + {verticies[0], page_pos[0]}, + {verticies[1], page_pos[1]}, + {verticies[2], page_pos[2]}}, tpage, clut, color) {} + constexpr POLY_FT3(const VertexEx (&vertices_ex)[3], TPage tpage, PageClut clut, Color24 color) : + color(color), code(IdentityCode), + vertex0(vertices_ex[0].position), page0(vertices_ex[0].page), page_clut(clut), + vertex1(vertices_ex[1].position), page1(vertices_ex[1].page), tpage(tpage), + vertex2(vertices_ex[2].position), page2(vertices_ex[2].page), padded2(0) {} + }; + + struct POLY_G3 : public internal::IsPrimitive, public internal::CodeInterface { + struct VertexEx { + Vertex position; + Color24 color; + }; + static constexpr auto IdentityCode = Code(POLY_F3::IdentityCode).set(Code::GouraudShading); + + Color24 color0; // a + Code code = IdentityCode; // a + Vertex vertex0; // b + Color24 color1; // c + uint8_t pad1; // c + Vertex vertex1; // d + Color24 color2; // e + uint8_t pad2; // e + Vertex vertex2; // f + + constexpr POLY_G3() = default; + constexpr POLY_G3(const Vertex (&verticies)[3], const Color24 (&color)[3]) : POLY_G3({ + {verticies[0], color[0]}, + {verticies[1], color[1]}, + {verticies[2], color[2]}}) {} + constexpr POLY_G3(const VertexEx (&verticies_ex)[3]) : + color0(verticies_ex[0].color), code(IdentityCode), vertex0(verticies_ex[0].position), + color1(verticies_ex[1].color), pad1(0), vertex1(verticies_ex[1].position), + color2(verticies_ex[2].color), pad2(0), vertex2(verticies_ex[2].position) {} + }; + + struct POLY_GT3 : public internal::IsPrimitive, public internal::CodeInterface { + struct VertexEx { + Vertex position; + PagePosition page; + Color24 color; + }; + static constexpr auto IdentityCode = Code(POLY_G3::IdentityCode).set(Code::Textured); + + Color24 color0; // a + Code code = IdentityCode; // a + Vertex vertex0; // b + PagePosition page0; // c + PageClut page_clut; // c + Color24 color1; // d + uint8_t pad1; // d + Vertex vertex1; // e + PagePosition page1; // f + TPage tpage; // f + Color24 color2; // g + uint8_t pad2; // g + Vertex vertex2; // h + PagePosition page2; // i + uint16_t pad3; // i + + constexpr POLY_GT3() = default; + constexpr POLY_GT3(const Vertex (&verticies)[3], const PagePosition (&page_pos)[3], const Color24 (&color)[3], TPage tpage, PageClut clut) : POLY_GT3({ + {verticies[0], page_pos[0], color[0]}, + {verticies[1], page_pos[1], color[1]}, + {verticies[2], page_pos[2], color[2]}}, tpage, clut) {} + constexpr POLY_GT3(const VertexEx (&verticies_ex)[3], TPage tpage, PageClut clut) : + color0(verticies_ex[0].color), code(IdentityCode), vertex0(verticies_ex[0].position), page0(verticies_ex[0].page), page_clut(clut), + color1(verticies_ex[1].color), pad1(0), vertex1(verticies_ex[1].position), page1(verticies_ex[1].page), tpage(tpage), + color2(verticies_ex[2].color), pad2(0), vertex2(verticies_ex[2].position), page2(verticies_ex[2].page), pad3(0) {} + }; + + /* + 1 - 2 + | | + 3 - 4 + */ + struct POLY_F4 : public internal::IsPrimitive, public internal::CodeInterface { + static constexpr auto IdentityCode = Code(POLY_F3::IdentityCode).set(Code::QuadVertics); + + Color24 color; // a + Code code = IdentityCode; // a + Vertex vertex0; // b + Vertex vertex1; // c + Vertex vertex2; // d + Vertex vertex3; // e + + constexpr POLY_F4() = default; + constexpr POLY_F4(const Vertex (&verticies)[4], Color24 color) : + color(color), code(IdentityCode), + vertex0(verticies[0]), + vertex1(verticies[1]), + vertex2(verticies[2]), + vertex3(verticies[3]) {} + constexpr POLY_F4(const AreaI16& area, Color24 color) : POLY_F4({ + area.position, + area.position.move(area.size.width, 0), + area.position.move(0, area.size.height), + area.position.move(area.size.width, area.size.height)}, + color) {} + }; + + struct POLY_FT4 : public internal::IsPrimitive, public internal::CodeInterface { + typedef POLY_FT3::VertexEx VertexEx; + static constexpr auto IdentityCode = Code(POLY_FT3::IdentityCode).set(Code::QuadVertics); + + Color24 color; // a + Code code = IdentityCode; // a + Vertex vertex0; // b + PagePosition page0; // c + PageClut page_clut; // c + Vertex vertex1; // d + PagePosition page1; // e + TPage tpage; // e + Vertex vertex2; // f + PagePosition page2; // g + uint16_t pad2; // g + Vertex vertex3; // h + PagePosition page3; // i + uint16_t pad3; // i + + constexpr POLY_FT4() = default; + constexpr POLY_FT4(const Vertex (&verticies)[4], const PagePosition (&page_pos)[4], TPage tpage, PageClut clut, Color24 color) : POLY_FT4({ + {verticies[0], page_pos[0]}, + {verticies[1], page_pos[1]}, + {verticies[2], page_pos[2]}, + {verticies[3], page_pos[3]}}, tpage, clut, color) {} + constexpr POLY_FT4(const VertexEx (&vertices_ex)[4], TPage tpage, PageClut clut, Color24 color = Color24::Grey()) : + color(color), code(IdentityCode), + vertex0(vertices_ex[0].position), page0(vertices_ex[0].page), page_clut(clut), + vertex1(vertices_ex[1].position), page1(vertices_ex[1].page), tpage(tpage), + vertex2(vertices_ex[2].position), page2(vertices_ex[2].page), pad2(0), + vertex3(vertices_ex[3].position), page3(vertices_ex[3].page), pad3(0) {} + constexpr POLY_FT4(const AreaI16& area, const PagePosition& texture_pos, TPage tpage, PageClut clut, Color24 color) : POLY_FT4({ + {area.position, texture_pos}, + {area.position.move(area.size.width, 0), texture_pos.move(area.size.width, 0)}, + {area.position.move(0, area.size.height), texture_pos.move(0, area.size.height)}, + {area.position.move(area.size.width, area.size.height), texture_pos.move(area.size.width, area.size.height)}}, + tpage, clut, color + ) {} + }; + + struct POLY_G4 : public internal::IsPrimitive, public internal::CodeInterface { + typedef POLY_G3::VertexEx VertexEx; + static constexpr auto IdentityCode = Code(POLY_G3::IdentityCode).set(Code::QuadVertics); + + Color24 color0; // a + Code code = IdentityCode; // a + Vertex vertex0; // b + Color24 color1; // c + uint8_t pad1; // c + Vertex vertex1; // d + Color24 color2; // e + uint8_t pad2; // e + Vertex vertex2; // f + Color24 color3; // g + uint8_t pad3; // g + Vertex vertex3; // h + + constexpr POLY_G4() = default; + constexpr POLY_G4(const Vertex (&verticies)[4], const Color24 (&color)[4]) : POLY_G4({ + {verticies[0], color[0]}, + {verticies[1], color[1]}, + {verticies[2], color[2]}, + {verticies[3], color[3]} + }) {} + constexpr POLY_G4(const VertexEx (&verticies_ex)[4]) : + color0(verticies_ex[0].color), code(IdentityCode), vertex0(verticies_ex[0].position), + color1(verticies_ex[1].color), pad1(0), vertex1(verticies_ex[1].position), + color2(verticies_ex[2].color), pad2(0), vertex2(verticies_ex[2].position), + color3(verticies_ex[3].color), pad3(0), vertex3(verticies_ex[3].position) {} + constexpr POLY_G4(const AreaI16& area, const Color24 (&color)[4]) : POLY_G4({ + {area.position, color[0]}, + {area.position.move(area.size.width, 0), color[1]}, + {area.position.move(0, area.size.height), color[2]}, + {area.position.move(area.size.width, area.size.height), color[3]}} + ) {} + }; + + struct POLY_GT4 : public internal::IsPrimitive, public internal::CodeInterface { + typedef POLY_GT3::VertexEx VertexEx; + static constexpr auto IdentityCode = Code(POLY_GT3::IdentityCode).set(Code::QuadVertics); + + Color24 color0; // a + Code code = IdentityCode; // a + Vertex vertex0; // b + PagePosition page0; // c + PageClut page_clut; // c + Color24 color1; // d + uint8_t pad1; // d + Vertex vertex1; // e + PagePosition page1; // f + TPage tpage; // f + Color24 color2; // g + uint8_t pad2; // g + Vertex vertex2; // h + PagePosition page2; // i + uint16_t pad3; // i + Color24 color3; // j + uint8_t pad4; // j + Vertex vertex3; // k + PagePosition page3; // l + uint16_t pad5; // l + + constexpr POLY_GT4() = default; + constexpr POLY_GT4(const Vertex (&verticies)[4], const PagePosition (&page_pos)[4], const Color24 (&color)[4], TPage tpage, PageClut clut) : POLY_GT4({ + {verticies[0], page_pos[0], color[0]}, + {verticies[1], page_pos[1], color[1]}, + {verticies[2], page_pos[2], color[2]}, + {verticies[3], page_pos[3], color[3]}, + }, tpage, clut) {} + constexpr POLY_GT4(const VertexEx (&verticies_ex)[4], TPage tpage, PageClut clut) : + color0(verticies_ex[0].color), code(IdentityCode), vertex0(verticies_ex[0].position), page0(verticies_ex[0].page), page_clut(clut), + color1(verticies_ex[1].color), pad1(0), vertex1(verticies_ex[1].position), page1(verticies_ex[1].page), tpage(tpage), + color2(verticies_ex[2].color), pad2(0), vertex2(verticies_ex[2].position), page2(verticies_ex[2].page), pad3(0), + color3(verticies_ex[3].color), pad4(0), vertex3(verticies_ex[3].position), page3(verticies_ex[3].page), pad5(0) {} + constexpr POLY_GT4(const AreaI16& area, const PagePosition& texture_pos, TPage tpage, PageClut clut, const Color24 (&color)[4]) : POLY_GT4({ + {area.position, texture_pos, color[0]}, + {area.position.move(area.size.width, 0), texture_pos.move(area.size.width, 0), color[1]}, + {area.position.move(0, area.size.height), texture_pos.move(0, area.size.height), color[2]}, + {area.position.move(area.size.width, area.size.height), texture_pos.move(area.size.width, area.size.height), color[3]} + }, tpage, clut) {} + }; + + typedef POLY_F3 FlatTriangle; + typedef POLY_FT3 FlatTexturedTriangle; + typedef POLY_G3 GouraudTriangle; + typedef POLY_GT3 GouraudTexturedTriangle; + + typedef POLY_F4 FlatRectangle; + typedef POLY_FT4 FlatTexturedRectangle; + typedef POLY_G4 GouraudRectangle; + typedef POLY_GT4 GouraudTexturedRectangle; + + static_assert(sizeof(POLY_F3) == 16); + static_assert(sizeof(POLY_FT3) == 28); + static_assert(sizeof(POLY_G3) == 24); + static_assert(sizeof(POLY_GT3) == 36); + + static_assert(sizeof(POLY_F4) == 20); + static_assert(sizeof(POLY_FT4) == 36); + static_assert(sizeof(POLY_G4) == 32); + static_assert(sizeof(POLY_GT4) == 48); + } +} +#endif // !__JABYENGINE_PRIMITIVE_POLY_TYPES_HPP__ \ No newline at end of file diff --git a/include/PSX/GPU/Primitives/primitive_support_types.hpp b/include/PSX/GPU/Primitives/primitive_support_types.hpp new file mode 100644 index 00000000..a12a5c7d --- /dev/null +++ b/include/PSX/GPU/Primitives/primitive_support_types.hpp @@ -0,0 +1,70 @@ +#ifndef __JABYENGINE_PRIMITIVE_SUPPORT_TYPES_HPP__ +#define __JABYENGINE_PRIMITIVE_SUPPORT_TYPES_HPP__ +#include "../gpu_types.hpp" +#include "../../System/IOPorts/gpu_io.hpp" + +namespace JabyEngine { + namespace GPU { + namespace internal { + template + struct CodeBase { + static constexpr auto BitCorrection = 24; + static constexpr auto CmdID = BitRange::from_to(29 - BitCorrection, 31 - BitCorrection); + + uint8_t value = bit::value::set_normalized(0u, CmdID.with(T::CmdValue)); + + constexpr CodeBase() = default; + constexpr CodeBase(const T& code) : value(code.value) { + } + + constexpr T& set(Bit bit) { + this->value = bit::set(this->value, bit); + return static_cast(*this); + } + + constexpr T& set(ClearBit bit) { + this->value = bit::set(this->value, bit); + return static_cast(*this); + } + }; + + // Concept for now + template + struct Hooked { + uint32_t hook; + T primitive; + }; + + struct IsPrimitive { + static constexpr bool is_primitive = true; + }; + } + + // Reexport for easier use + typedef JabyEngine::GPU_IO::SemiTransparency SemiTransparency; + typedef JabyEngine::GPU_IO::TexturePageColor TexturePageColor; + + struct PageClut { + uint16_t value = 0; + + constexpr PageClut() = default; + constexpr PageClut(uint16_t x, uint16_t y) : value((y << 6) | ((x >> 4) & 0x3f)) { + } + }; + + struct TPage { + static constexpr auto TexturePageX = BitRange::from_to(0, 3); + static constexpr auto TexturePageY = BitRange::from_to(4, 4); + static constexpr auto SemiTransparency = BitRange::from_to(5, 6); + static constexpr auto TextureClut = BitRange::from_to(7, 8); + + uint16_t value = 0; + + constexpr TPage() = default; + constexpr TPage(uint16_t x, uint16_t y, ::JabyEngine::GPU::SemiTransparency transparency, TexturePageColor clut_color) : value(TexturePageX.as_value(x >> 6) | TexturePageY.as_value(y >> 8) | SemiTransparency.as_value(static_cast(transparency)) | TextureClut.as_value(static_cast(clut_color))) { + } + }; + } +} + +#endif //!__JABYENGINE_PRIMITIVE_SUPPORT_TYPES_HPP__ \ No newline at end of file diff --git a/include/PSX/GPU/gpu_primitives.hpp b/include/PSX/GPU/gpu_primitives.hpp index 91850805..80a96602 100644 --- a/include/PSX/GPU/gpu_primitives.hpp +++ b/include/PSX/GPU/gpu_primitives.hpp @@ -1,398 +1,4 @@ #ifndef __JABYENGINE_GPU_PRIMITIVES_HPP__ #define __JABYENGINE_GPU_PRIMITIVES_HPP__ -#include "gpu_types.hpp" -#include - -namespace JabyEngine { - namespace GPU { - namespace internal { - struct Code { - static constexpr uint8_t CmdValue = 0b001; - static constexpr auto BitCorrection = 24; - - static constexpr auto CmdID = BitRange::from_to(29 - BitCorrection, 31 - BitCorrection); - static constexpr auto GouraudShading = Bit(28 - BitCorrection); - static constexpr auto FlatShading = !GouraudShading; - static constexpr auto QuadVertics = Bit(27 - BitCorrection); - static constexpr auto TriVertics = !QuadVertics; - static constexpr auto Textured = Bit(26 - BitCorrection); - static constexpr auto Untextured = !Textured; - static constexpr auto SemiTransparent = Bit(25 - BitCorrection); - static constexpr auto NonTransparent = !SemiTransparent; - static constexpr auto BlendTexture = Bit(24 - BitCorrection); - static constexpr auto NoBlendTexture = !BlendTexture; - - uint8_t value = bit::value::set_normalized(0u, CmdID.with(CmdValue)); - - constexpr Code() = default; - constexpr Code(const Code& code) : value(code.value) { - } - - constexpr Code& set(Bit bit) { - this->value = bit::set(this->value, bit); - return *this; - } - - constexpr Code& set(ClearBit bit) { - this->value = bit::set(this->value, bit); - return *this; - } - }; - - // Concept for now - template - struct Hooked { - uint32_t hook; - T primitive; - }; - - template - struct CodeInterface { - constexpr T& set_semi_transparent() { - static_cast(this)->code.set(Code::SemiTransparent); - return *static_cast(this); - } - - constexpr T& set_non_transparent() { - static_cast(this)->code.set(Code::NonTransparent); - return *static_cast(this); - } - - constexpr T& set_texture_blending() { - static_cast(this)->code.set(Code::BlendTexture); - return *static_cast(this); - } - - constexpr T& set_non_texture_blening() { - static_cast(this)->code.set(Code::NoBlendTexture); - return *static_cast(this); - } - }; - - struct IsPrimitive { - static constexpr bool is_primitive = true; - - typedef JabyEngine::GPU::internal::Code Code; - }; - } - - // Reexport for easier use - typedef JabyEngine::GPU_IO::SemiTransparency SemiTransparency; - typedef JabyEngine::GPU_IO::TexturePageColor TexturePageColor; - - struct PageClut { - uint16_t value = 0; - - constexpr PageClut() = default; - constexpr PageClut(uint16_t x, uint16_t y) : value((y << 6) | ((x >> 4) & 0x3f)) { - } - }; - - - struct TPage { - static constexpr auto TexturePageX = BitRange::from_to(0, 3); - static constexpr auto TexturePageY = BitRange::from_to(4, 4); - static constexpr auto SemiTransparency = BitRange::from_to(5, 6); - static constexpr auto TextureClut = BitRange::from_to(7, 8); - - uint16_t value = 0; - - constexpr TPage() = default; - constexpr TPage(uint16_t x, uint16_t y, ::JabyEngine::GPU::SemiTransparency transparency, TexturePageColor clut_color) : value(TexturePageX.as_value(x >> 6) | TexturePageY.as_value(y >> 8) | SemiTransparency.as_value(static_cast(transparency)) | TextureClut.as_value(static_cast(clut_color))) { - } - }; - - /* - 1 - / \ - 3 - 2 - */ - struct POLY_F3 : public internal::IsPrimitive, public internal::CodeInterface { - static constexpr auto IdentityCode = Code().set(Code::FlatShading).set(Code::TriVertics).set(Code::Untextured).set(Code::NonTransparent).set(Code::NoBlendTexture); - - Color24 color; // a - Code code = IdentityCode; // a - Vertex vertex0; // b - Vertex vertex1; // c - Vertex vertex2; // d - - constexpr POLY_F3() = default; - constexpr POLY_F3(const Vertex (&verticies)[3], Color24 color) : - color(color), code(IdentityCode), - vertex0(verticies[0]), - vertex1(verticies[1]), - vertex2(verticies[2]) { - } - }; - - struct POLY_FT3 : public internal::IsPrimitive, public internal::CodeInterface { - struct VertexEx { - Vertex position; - PagePosition page; - }; - static constexpr auto IdentityCode = Code(POLY_F3::IdentityCode).set(Code::Textured); - - Color24 color; // a - Code code = IdentityCode; // a - Vertex vertex0; // b - PagePosition page0; // c - PageClut page_clut; // c - Vertex vertex1; // d - PagePosition page1; // e - TPage tpage; // e - Vertex vertex2; // f - PagePosition page2; // g - uint16_t padded2; // g - - constexpr POLY_FT3() = default; - constexpr POLY_FT3(const Vertex (&verticies)[3], const PagePosition (&page_pos)[3], TPage tpage, PageClut clut, Color24 color = Color24::Grey()) : POLY_FT3({ - {verticies[0], page_pos[0]}, - {verticies[1], page_pos[1]}, - {verticies[2], page_pos[2]}}, tpage, clut, color) {} - constexpr POLY_FT3(const VertexEx (&vertices_ex)[3], TPage tpage, PageClut clut, Color24 color) : - color(color), code(IdentityCode), - vertex0(vertices_ex[0].position), page0(vertices_ex[0].page), page_clut(clut), - vertex1(vertices_ex[1].position), page1(vertices_ex[1].page), tpage(tpage), - vertex2(vertices_ex[2].position), page2(vertices_ex[2].page), padded2(0) {} - }; - - struct POLY_G3 : public internal::IsPrimitive, public internal::CodeInterface { - struct VertexEx { - Vertex position; - Color24 color; - }; - static constexpr auto IdentityCode = Code(POLY_F3::IdentityCode).set(Code::GouraudShading); - - Color24 color0; // a - Code code = IdentityCode; // a - Vertex vertex0; // b - Color24 color1; // c - uint8_t pad1; // c - Vertex vertex1; // d - Color24 color2; // e - uint8_t pad2; // e - Vertex vertex2; // f - - constexpr POLY_G3() = default; - constexpr POLY_G3(const Vertex (&verticies)[3], const Color24 (&color)[3]) : POLY_G3({ - {verticies[0], color[0]}, - {verticies[1], color[1]}, - {verticies[2], color[2]}}) {} - constexpr POLY_G3(const VertexEx (&verticies_ex)[3]) : - color0(verticies_ex[0].color), code(IdentityCode), vertex0(verticies_ex[0].position), - color1(verticies_ex[1].color), pad1(0), vertex1(verticies_ex[1].position), - color2(verticies_ex[2].color), pad2(0), vertex2(verticies_ex[2].position) {} - }; - - struct POLY_GT3 : public internal::IsPrimitive, public internal::CodeInterface { - struct VertexEx { - Vertex position; - PagePosition page; - Color24 color; - }; - static constexpr auto IdentityCode = Code(POLY_G3::IdentityCode).set(Code::Textured); - - Color24 color0; // a - Code code = IdentityCode; // a - Vertex vertex0; // b - PagePosition page0; // c - PageClut page_clut; // c - Color24 color1; // d - uint8_t pad1; // d - Vertex vertex1; // e - PagePosition page1; // f - TPage tpage; // f - Color24 color2; // g - uint8_t pad2; // g - Vertex vertex2; // h - PagePosition page2; // i - uint16_t pad3; // i - - constexpr POLY_GT3() = default; - constexpr POLY_GT3(const Vertex (&verticies)[3], const PagePosition (&page_pos)[3], const Color24 (&color)[3], TPage tpage, PageClut clut) : POLY_GT3({ - {verticies[0], page_pos[0], color[0]}, - {verticies[1], page_pos[1], color[1]}, - {verticies[2], page_pos[2], color[2]}}, tpage, clut) {} - constexpr POLY_GT3(const VertexEx (&verticies_ex)[3], TPage tpage, PageClut clut) : - color0(verticies_ex[0].color), code(IdentityCode), vertex0(verticies_ex[0].position), page0(verticies_ex[0].page), page_clut(clut), - color1(verticies_ex[1].color), pad1(0), vertex1(verticies_ex[1].position), page1(verticies_ex[1].page), tpage(tpage), - color2(verticies_ex[2].color), pad2(0), vertex2(verticies_ex[2].position), page2(verticies_ex[2].page), pad3(0) {} - }; - - - - /* - 1 - 2 - | | - 3 - 4 - */ - struct POLY_F4 : public internal::IsPrimitive, public internal::CodeInterface { - static constexpr auto IdentityCode = Code(POLY_F3::IdentityCode).set(Code::QuadVertics); - - Color24 color; // a - Code code = IdentityCode; // a - Vertex vertex0; // b - Vertex vertex1; // c - Vertex vertex2; // d - Vertex vertex3; // e - - constexpr POLY_F4() = default; - constexpr POLY_F4(const Vertex (&verticies)[4], Color24 color) : - color(color), code(IdentityCode), - vertex0(verticies[0]), - vertex1(verticies[1]), - vertex2(verticies[2]), - vertex3(verticies[3]) {} - constexpr POLY_F4(const AreaI16& area, Color24 color) : POLY_F4({ - area.position, - area.position.move(area.size.width, 0), - area.position.move(0, area.size.height), - area.position.move(area.size.width, area.size.height)}, - color) {} - }; - - struct POLY_FT4 : public internal::IsPrimitive, public internal::CodeInterface { - typedef POLY_FT3::VertexEx VertexEx; - static constexpr auto IdentityCode = Code(POLY_FT3::IdentityCode).set(Code::QuadVertics); - - Color24 color; // a - Code code = IdentityCode; // a - Vertex vertex0; // b - PagePosition page0; // c - PageClut page_clut; // c - Vertex vertex1; // d - PagePosition page1; // e - TPage tpage; // e - Vertex vertex2; // f - PagePosition page2; // g - uint16_t pad2; // g - Vertex vertex3; // h - PagePosition page3; // i - uint16_t pad3; // i - - constexpr POLY_FT4() = default; - constexpr POLY_FT4(const Vertex (&verticies)[4], const PagePosition (&page_pos)[4], TPage tpage, PageClut clut, Color24 color) : POLY_FT4({ - {verticies[0], page_pos[0]}, - {verticies[1], page_pos[1]}, - {verticies[2], page_pos[2]}, - {verticies[3], page_pos[3]}}, tpage, clut, color) {} - constexpr POLY_FT4(const VertexEx (&vertices_ex)[4], TPage tpage, PageClut clut, Color24 color = Color24::Grey()) : - color(color), code(IdentityCode), - vertex0(vertices_ex[0].position), page0(vertices_ex[0].page), page_clut(clut), - vertex1(vertices_ex[1].position), page1(vertices_ex[1].page), tpage(tpage), - vertex2(vertices_ex[2].position), page2(vertices_ex[2].page), pad2(0), - vertex3(vertices_ex[3].position), page3(vertices_ex[3].page), pad3(0) {} - constexpr POLY_FT4(const AreaI16& area, const PagePosition& texture_pos, TPage tpage, PageClut clut, Color24 color) : POLY_FT4({ - {area.position, texture_pos}, - {area.position.move(area.size.width, 0), texture_pos.move(area.size.width, 0)}, - {area.position.move(0, area.size.height), texture_pos.move(0, area.size.height)}, - {area.position.move(area.size.width, area.size.height), texture_pos.move(area.size.width, area.size.height)}}, - tpage, clut, color - ) {} - }; - - struct POLY_G4 : public internal::IsPrimitive, public internal::CodeInterface { - typedef POLY_G3::VertexEx VertexEx; - static constexpr auto IdentityCode = Code(POLY_G3::IdentityCode).set(Code::QuadVertics); - - Color24 color0; // a - Code code = IdentityCode; // a - Vertex vertex0; // b - Color24 color1; // c - uint8_t pad1; // c - Vertex vertex1; // d - Color24 color2; // e - uint8_t pad2; // e - Vertex vertex2; // f - Color24 color3; // g - uint8_t pad3; // g - Vertex vertex3; // h - - constexpr POLY_G4() = default; - constexpr POLY_G4(const Vertex (&verticies)[4], const Color24 (&color)[4]) : POLY_G4({ - {verticies[0], color[0]}, - {verticies[1], color[1]}, - {verticies[2], color[2]}, - {verticies[3], color[3]} - }) {} - constexpr POLY_G4(const VertexEx (&verticies_ex)[4]) : - color0(verticies_ex[0].color), code(IdentityCode), vertex0(verticies_ex[0].position), - color1(verticies_ex[1].color), pad1(0), vertex1(verticies_ex[1].position), - color2(verticies_ex[2].color), pad2(0), vertex2(verticies_ex[2].position), - color3(verticies_ex[3].color), pad3(0), vertex3(verticies_ex[3].position) {} - constexpr POLY_G4(const AreaI16& area, const Color24 (&color)[4]) : POLY_G4({ - {area.position, color[0]}, - {area.position.move(area.size.width, 0), color[1]}, - {area.position.move(0, area.size.height), color[2]}, - {area.position.move(area.size.width, area.size.height), color[3]}} - ) {} - }; - - struct POLY_GT4 : public internal::IsPrimitive, public internal::CodeInterface { - typedef POLY_GT3::VertexEx VertexEx; - static constexpr auto IdentityCode = Code(POLY_GT3::IdentityCode).set(Code::QuadVertics); - - Color24 color0; // a - Code code = IdentityCode; // a - Vertex vertex0; // b - PagePosition page0; // c - PageClut page_clut; // c - Color24 color1; // d - uint8_t pad1; // d - Vertex vertex1; // e - PagePosition page1; // f - TPage tpage; // f - Color24 color2; // g - uint8_t pad2; // g - Vertex vertex2; // h - PagePosition page2; // i - uint16_t pad3; // i - Color24 color3; // j - uint8_t pad4; // j - Vertex vertex3; // k - PagePosition page3; // l - uint16_t pad5; // l - - constexpr POLY_GT4() = default; - constexpr POLY_GT4(const Vertex (&verticies)[4], const PagePosition (&page_pos)[4], const Color24 (&color)[4], TPage tpage, PageClut clut) : POLY_GT4({ - {verticies[0], page_pos[0], color[0]}, - {verticies[1], page_pos[1], color[1]}, - {verticies[2], page_pos[2], color[2]}, - {verticies[3], page_pos[3], color[3]}, - }, tpage, clut) {} - constexpr POLY_GT4(const VertexEx (&verticies_ex)[4], TPage tpage, PageClut clut) : - color0(verticies_ex[0].color), code(IdentityCode), vertex0(verticies_ex[0].position), page0(verticies_ex[0].page), page_clut(clut), - color1(verticies_ex[1].color), pad1(0), vertex1(verticies_ex[1].position), page1(verticies_ex[1].page), tpage(tpage), - color2(verticies_ex[2].color), pad2(0), vertex2(verticies_ex[2].position), page2(verticies_ex[2].page), pad3(0), - color3(verticies_ex[3].color), pad4(0), vertex3(verticies_ex[3].position), page3(verticies_ex[3].page), pad5(0) {} - constexpr POLY_GT4(const AreaI16& area, const PagePosition& texture_pos, TPage tpage, PageClut clut, const Color24 (&color)[4]) : POLY_GT4({ - {area.position, texture_pos, color[0]}, - {area.position.move(area.size.width, 0), texture_pos.move(area.size.width, 0), color[1]}, - {area.position.move(0, area.size.height), texture_pos.move(0, area.size.height), color[2]}, - {area.position.move(area.size.width, area.size.height), texture_pos.move(area.size.width, area.size.height), color[3]} - }, tpage, clut) {} - }; - - typedef POLY_F3 FlatTriangle; - typedef POLY_FT3 FlatTexturedTriangle; - typedef POLY_G3 GouraudTriangle; - typedef POLY_GT3 GouraudTexturedTriangle; - - typedef POLY_F4 FlatRectangle; - typedef POLY_FT4 FlatTexturedRectangle; - typedef POLY_G4 GouraudRectangle; - typedef POLY_GT4 GouraudTexturedRectangle; - - static_assert(sizeof(POLY_F3) == 16); - static_assert(sizeof(POLY_FT3) == 28); - static_assert(sizeof(POLY_G3) == 24); - static_assert(sizeof(POLY_GT3) == 36); - - static_assert(sizeof(POLY_F4) == 20); - static_assert(sizeof(POLY_FT4) == 36); - static_assert(sizeof(POLY_G4) == 32); - static_assert(sizeof(POLY_GT4) == 48); - } -} - +#include "Primitives/primitive_poly_types.hpp" #endif // !__JABYENGINE_GPU_PRIMITIVES_HPP__ \ No newline at end of file From 6f735eeefbbefb4a81314eadac1f3feffdbb7f8b Mon Sep 17 00:00:00 2001 From: jaby Date: Fri, 26 May 2023 22:20:43 +0200 Subject: [PATCH 034/588] Support transparency --- examples/PoolBox/application/src/main.cpp | 13 ++++++- examples/PoolBox/assets/Makefile | 2 +- .../src/images/reduced_tim/color_clut.rs | 12 +++--- .../src/images/reduced_tim/mod.rs | 37 +++++++++++++++++-- 4 files changed, 52 insertions(+), 12 deletions(-) diff --git a/examples/PoolBox/application/src/main.cpp b/examples/PoolBox/application/src/main.cpp index e8de2b71..e42f1ed7 100644 --- a/examples/PoolBox/application/src/main.cpp +++ b/examples/PoolBox/application/src/main.cpp @@ -75,6 +75,15 @@ static constexpr const auto rectangle4 = JabyEngine::GPU::POLY_GT4( JabyEngine::GPU::Color24::Green(), JabyEngine::GPU::Color24::White()} ); +static constexpr const auto rectangle5 = JabyEngine::GPU::POLY_GT4( + {RectangleArea.position.move(0, RectangleArea.size.height), RectangleArea.size}, {0, 0}, + RectangleTPage, + RectangleClut, { + JabyEngine::GPU::Color24::Red(), + JabyEngine::GPU::Color24::Blue(), + JabyEngine::GPU::Color24::Green(), + JabyEngine::GPU::Color24::White()} +).set_semi_transparent(true); static void load_assets() { static const JabyEngine::CDFile Assets[] = { @@ -107,7 +116,8 @@ static void load_assets() { void main() { load_assets(); - + printf("Dino: 0x%02X\n", rectangle4.code.value); + while(true) { JabyEngine::GPU::render(triangle1); JabyEngine::GPU::render(triangle2); @@ -118,6 +128,7 @@ void main() { JabyEngine::GPU::render(rectangle2); JabyEngine::GPU::render(rectangle3); JabyEngine::GPU::render(rectangle4); + JabyEngine::GPU::render(rectangle5); JabyEngine::GPU::swap_buffers_vsync(2); } diff --git a/examples/PoolBox/assets/Makefile b/examples/PoolBox/assets/Makefile index d898dbb8..15b5e4ca 100644 --- a/examples/PoolBox/assets/Makefile +++ b/examples/PoolBox/assets/Makefile @@ -9,7 +9,7 @@ $(OUTPUT_DIR)/TexturePage.bin: TexturePage.png $(OUTPUT_DIR)/IconTexture.bin: IconTexture.png @mkdir -p $(OUTPUT_DIR) - jaby_engine_fconv --lz4 $< -o $@ simple-tim clut4 + jaby_engine_fconv --lz4 $< -o $@ simple-tim clut4 --semi-trans --color-trans all: $(OUTPUT_DIR)/TexturePage.bin $(OUTPUT_DIR)/IconTexture.bin diff --git a/src/Tools/jaby_engine_fconv/src/images/reduced_tim/color_clut.rs b/src/Tools/jaby_engine_fconv/src/images/reduced_tim/color_clut.rs index 660e4387..63b3d9fa 100644 --- a/src/Tools/jaby_engine_fconv/src/images/reduced_tim/color_clut.rs +++ b/src/Tools/jaby_engine_fconv/src/images/reduced_tim/color_clut.rs @@ -12,12 +12,12 @@ enum IndexPerByte { } pub struct IndexedImage { - palette: Vec, - raw_data: std::vec::IntoIter, - index_byte: IndexPerByte, - next_func: fn(&mut Self) -> Option, - width: u16, - height: u16, + pub palette: Vec, + raw_data: std::vec::IntoIter, + index_byte: IndexPerByte, + next_func: fn(&mut Self) -> Option, + width: u16, + height: u16, } impl IndexedImage { diff --git a/src/Tools/jaby_engine_fconv/src/images/reduced_tim/mod.rs b/src/Tools/jaby_engine_fconv/src/images/reduced_tim/mod.rs index 6deb8357..d6745e6c 100644 --- a/src/Tools/jaby_engine_fconv/src/images/reduced_tim/mod.rs +++ b/src/Tools/jaby_engine_fconv/src/images/reduced_tim/mod.rs @@ -30,7 +30,35 @@ pub struct Arguments { color_depth: ColorType, #[clap(value_enum, value_parser, default_value_t=ClutAlignment::None)] - clut_align: ClutAlignment + clut_align: ClutAlignment, + + #[clap(long="semi-trans", default_value_t=false)] + semi_transparent: bool, + #[clap(long="color-trans", default_value_t=false)] + transparent_palette: bool +} + +fn modify_palette(mut image: IndexedImage, clut_align: ClutAlignment, semi_transparent: bool, transparent_palette: bool) -> IndexedImage { + if semi_transparent { + for color in image.palette.iter_mut() { + *color = PSXColor::semi_transparent(color.get_red(), color.get_green(), color.get_blue()); + } + } + + if transparent_palette { + if clut_align == ClutAlignment::Block { + for color in image.palette.iter_mut().step_by(16) { + *color = PSXColor::transparent(); + } + } + + else { + if let Some(first_color) = image.palette.get_mut(0) { + *first_color = PSXColor::transparent(); + } + } + } + image } fn encode(image: T, color_depth: ColorType, clut_align: ClutAlignment, output: &mut dyn Write) -> Result<(), Error> { @@ -95,7 +123,7 @@ fn convert_full16(input: Input, output: &mut dyn Write) -> Result<(), Error> { } } -fn convert_palette_based(input: Input, output: &mut dyn Write, color_type: ColorType, clut_align: ClutAlignment) -> Result<(), Error> { +fn convert_palette_based(input: Input, output: &mut dyn Write, color_type: ColorType, clut_align: ClutAlignment, semi_transparent: bool, transparent_palette: bool) -> Result<(), Error> { match png::Decoder::new(input).read_info() { Ok(reader) => { let output_type = { @@ -105,7 +133,8 @@ fn convert_palette_based(input: Input, output: &mut dyn Write, color_type: Color _ => return Err(Error::from_str("ColorType not supported")) } }; - encode(IndexedImage::new(reader, output_type)?, color_type, clut_align, output) + + encode(modify_palette(IndexedImage::new(reader, output_type)?, clut_align, semi_transparent, transparent_palette), color_type, clut_align, output) }, Err(error) => Err(Error::from_error(error)) } @@ -114,6 +143,6 @@ fn convert_palette_based(input: Input, output: &mut dyn Write, color_type: Color pub fn convert(args: Arguments, input: Input, output: &mut dyn Write) -> Result<(), Error> { match args.color_depth { ColorType::Full16 => convert_full16(input, output), - _ => convert_palette_based(input, output, args.color_depth, args.clut_align), + _ => convert_palette_based(input, output, args.color_depth, args.clut_align, args.semi_transparent, args.transparent_palette), } } \ No newline at end of file From 4914e3b9b4c46da26a5668580c1f5d3352b300e7 Mon Sep 17 00:00:00 2001 From: jaby Date: Sat, 27 May 2023 15:14:19 +0200 Subject: [PATCH 035/588] Support LINE_F --- examples/PoolBox/application/src/main.cpp | 10 +++ .../GPU/Primitives/primitive_line_types.hpp | 73 +++++++++++++++++++ .../GPU/Primitives/primitive_poly_types.hpp | 22 +++--- include/PSX/GPU/gpu.hpp | 5 ++ include/PSX/GPU/gpu_primitives.hpp | 1 + 5 files changed, 100 insertions(+), 11 deletions(-) create mode 100644 include/PSX/GPU/Primitives/primitive_line_types.hpp diff --git a/examples/PoolBox/application/src/main.cpp b/examples/PoolBox/application/src/main.cpp index e42f1ed7..e2675cb3 100644 --- a/examples/PoolBox/application/src/main.cpp +++ b/examples/PoolBox/application/src/main.cpp @@ -22,6 +22,8 @@ static constexpr auto RectangleArea = JabyEngine::GPU::AreaI16({0, TriangleArea static constexpr auto RectangleTPage = JabyEngine::GPU::TPage(320, 256, JabyEngine::GPU::SemiTransparency::B_Half_add_F_Half, JabyEngine::GPU::TexturePageColor::$4bit); static constexpr auto RectangleClut = JabyEngine::GPU::PageClut(320, 510); +static constexpr auto LineColor = JabyEngine::GPU::Color24(0xFF, 0x0, 0x0); + static constexpr const auto triangle1 = JabyEngine::GPU::POLY_F3({ {TriangleArea.position.x, TriangleArea.position.y}, {TriangleArea.size.width, TriangleArea.size.height}, @@ -85,6 +87,12 @@ static constexpr const auto rectangle5 = JabyEngine::GPU::POLY_GT4( JabyEngine::GPU::Color24::White()} ).set_semi_transparent(true); +static constexpr const JabyEngine::GPU::LINE_F line1[] = { + JabyEngine::GPU::LINE_F::new_line(LineColor, false), + JabyEngine::GPU::LINE_F::new_point({0, 0}), + JabyEngine::GPU::LINE_F::new_point({JabyEngine::GPU::Display::Width, JabyEngine::GPU::Display::Height}) +}; + static void load_assets() { static const JabyEngine::CDFile Assets[] = { JabyEngine::CDFileBuilder::simple_tim(LBA::FONT, JabyEngine::SimpleTIM(320, 0, 320, 511)), @@ -130,6 +138,8 @@ void main() { JabyEngine::GPU::render(rectangle4); JabyEngine::GPU::render(rectangle5); + JabyEngine::GPU::render(line1); + JabyEngine::GPU::swap_buffers_vsync(2); } } diff --git a/include/PSX/GPU/Primitives/primitive_line_types.hpp b/include/PSX/GPU/Primitives/primitive_line_types.hpp new file mode 100644 index 00000000..3ceabe6b --- /dev/null +++ b/include/PSX/GPU/Primitives/primitive_line_types.hpp @@ -0,0 +1,73 @@ +#ifndef __JABY_ENGINE_PRIMITIVE_LINE_TYPES_HPP__ +#define __JABY_ENGINE_PRIMITIVE_LINE_TYPES_HPP__ +#include "primitive_support_types.hpp" + +namespace JabyEngine { + namespace GPU { + namespace internal { + struct LineCode : public CodeBase { + static constexpr uint8_t CmdValue = 0b010; + + static constexpr auto GouraudShading = Bit(28 - BitCorrection); + static constexpr auto FlatShading = !GouraudShading; + static constexpr auto PolyLine = Bit(27 - BitCorrection); + static constexpr auto SingleLine = !PolyLine; + static constexpr auto SemiTransparent = Bit(25 - BitCorrection); + static constexpr auto NonTransparent = !SemiTransparent; + }; + + template + struct LineCodeInterface { + typedef ::JabyEngine::GPU::internal::LineCode Code; + + constexpr T& set_poly_line(bool set = true) { + if(set) { + static_cast(this)->head.code.set(Code::PolyLine); + } + else { + static_cast(this)->head.code.set(Code::SingleLine); + } + return *static_cast(this); + } + + constexpr T& set_semi_transparent(bool set = true) { + if(set) { + static_cast(this)->head.code.set(Code::SemiTransparent); + } + else { + static_cast(this)->head.code.set(Code::NonTransparent); + } + return *static_cast(this); + } + }; + } + + struct LINE_F : public internal::IsPrimitive, public internal::LineCodeInterface { + struct Head { + static constexpr auto IdentityCode = Code().set(Code::FlatShading).set(Code::SingleLine).set(Code::NonTransparent); + + Color24 color; + Code code = IdentityCode; + }; + + union { + Head head; + Vertex vertex; + }; + + static constexpr LINE_F new_line(const Color24& color, bool is_poly) { + return LINE_F{.head = {.color = color, .code = Head::IdentityCode}}.set_poly_line(is_poly); + } + + static constexpr LINE_F new_point(const Vertex& vertex) { + return {.vertex = vertex}; + } + + static constexpr LINE_F new_terminate() { + return {.vertex = {static_cast(0xF000), static_cast(0xF000u)}}; + } + }; + } +} + +#endif //!__JABY_ENGINE_PRIMITIVE_LINE_TYPES_HPP__ \ No newline at end of file diff --git a/include/PSX/GPU/Primitives/primitive_poly_types.hpp b/include/PSX/GPU/Primitives/primitive_poly_types.hpp index 8b02ff88..59b0965d 100644 --- a/include/PSX/GPU/Primitives/primitive_poly_types.hpp +++ b/include/PSX/GPU/Primitives/primitive_poly_types.hpp @@ -5,7 +5,7 @@ namespace JabyEngine { namespace GPU { namespace internal { - struct Code : public CodeBase { + struct PolyCode : public CodeBase { static constexpr uint8_t CmdValue = 0b001; static constexpr auto GouraudShading = Bit(28 - BitCorrection); @@ -21,8 +21,8 @@ namespace JabyEngine { }; template - struct CodeInterface { - typedef ::JabyEngine::GPU::internal::Code Code; + struct PolyCodeInterface { + typedef ::JabyEngine::GPU::internal::PolyCode Code; constexpr T& set_semi_transparent(bool set = true) { if(set) { @@ -51,7 +51,7 @@ namespace JabyEngine { / \ 3 - 2 */ - struct POLY_F3 : public internal::IsPrimitive, public internal::CodeInterface { + struct POLY_F3 : public internal::IsPrimitive, public internal::PolyCodeInterface { static constexpr auto IdentityCode = Code().set(Code::FlatShading).set(Code::TriVertics).set(Code::Untextured).set(Code::NonTransparent); Color24 color; // a @@ -69,7 +69,7 @@ namespace JabyEngine { } }; - struct POLY_FT3 : public internal::IsPrimitive, public internal::CodeInterface { + struct POLY_FT3 : public internal::IsPrimitive, public internal::PolyCodeInterface { struct VertexEx { Vertex position; PagePosition page; @@ -100,7 +100,7 @@ namespace JabyEngine { vertex2(vertices_ex[2].position), page2(vertices_ex[2].page), padded2(0) {} }; - struct POLY_G3 : public internal::IsPrimitive, public internal::CodeInterface { + struct POLY_G3 : public internal::IsPrimitive, public internal::PolyCodeInterface { struct VertexEx { Vertex position; Color24 color; @@ -128,7 +128,7 @@ namespace JabyEngine { color2(verticies_ex[2].color), pad2(0), vertex2(verticies_ex[2].position) {} }; - struct POLY_GT3 : public internal::IsPrimitive, public internal::CodeInterface { + struct POLY_GT3 : public internal::IsPrimitive, public internal::PolyCodeInterface { struct VertexEx { Vertex position; PagePosition page; @@ -168,7 +168,7 @@ namespace JabyEngine { | | 3 - 4 */ - struct POLY_F4 : public internal::IsPrimitive, public internal::CodeInterface { + struct POLY_F4 : public internal::IsPrimitive, public internal::PolyCodeInterface { static constexpr auto IdentityCode = Code(POLY_F3::IdentityCode).set(Code::QuadVertics); Color24 color; // a @@ -193,7 +193,7 @@ namespace JabyEngine { color) {} }; - struct POLY_FT4 : public internal::IsPrimitive, public internal::CodeInterface { + struct POLY_FT4 : public internal::IsPrimitive, public internal::PolyCodeInterface { typedef POLY_FT3::VertexEx VertexEx; static constexpr auto IdentityCode = Code(POLY_FT3::IdentityCode).set(Code::QuadVertics); @@ -233,7 +233,7 @@ namespace JabyEngine { ) {} }; - struct POLY_G4 : public internal::IsPrimitive, public internal::CodeInterface { + struct POLY_G4 : public internal::IsPrimitive, public internal::PolyCodeInterface { typedef POLY_G3::VertexEx VertexEx; static constexpr auto IdentityCode = Code(POLY_G3::IdentityCode).set(Code::QuadVertics); @@ -270,7 +270,7 @@ namespace JabyEngine { ) {} }; - struct POLY_GT4 : public internal::IsPrimitive, public internal::CodeInterface { + struct POLY_GT4 : public internal::IsPrimitive, public internal::PolyCodeInterface { typedef POLY_GT3::VertexEx VertexEx; static constexpr auto IdentityCode = Code(POLY_GT3::IdentityCode).set(Code::QuadVertics); diff --git a/include/PSX/GPU/gpu.hpp b/include/PSX/GPU/gpu.hpp index 1ac7fa16..75344e05 100644 --- a/include/PSX/GPU/gpu.hpp +++ b/include/PSX/GPU/gpu.hpp @@ -45,6 +45,11 @@ namespace JabyEngine { internal::render(reinterpret_cast(&primitive), sizeof(T)/sizeof(uint32_t)); } + template + static void render(const LINE_F (&line)[N]) { + internal::render(reinterpret_cast(&line), N); + } + uint8_t swap_buffers_vsync(uint8_t syncs, bool clear_screen = true); } } diff --git a/include/PSX/GPU/gpu_primitives.hpp b/include/PSX/GPU/gpu_primitives.hpp index 80a96602..9c6ba90b 100644 --- a/include/PSX/GPU/gpu_primitives.hpp +++ b/include/PSX/GPU/gpu_primitives.hpp @@ -1,4 +1,5 @@ #ifndef __JABYENGINE_GPU_PRIMITIVES_HPP__ #define __JABYENGINE_GPU_PRIMITIVES_HPP__ +#include "Primitives/primitive_line_types.hpp" #include "Primitives/primitive_poly_types.hpp" #endif // !__JABYENGINE_GPU_PRIMITIVES_HPP__ \ No newline at end of file From 81bb8c76fad793c553f9017645d958f65c35c05f Mon Sep 17 00:00:00 2001 From: jaby Date: Sat, 27 May 2023 16:40:59 +0200 Subject: [PATCH 036/588] Introduce is_render_primitive type_trait --- .../GPU/Primitives/primitive_line_types.hpp | 2 +- .../GPU/Primitives/primitive_poly_types.hpp | 28 +++++++++++++------ .../Primitives/primitive_support_types.hpp | 11 ++++++-- include/PSX/GPU/gpu.hpp | 2 +- 4 files changed, 31 insertions(+), 12 deletions(-) diff --git a/include/PSX/GPU/Primitives/primitive_line_types.hpp b/include/PSX/GPU/Primitives/primitive_line_types.hpp index 3ceabe6b..9c002124 100644 --- a/include/PSX/GPU/Primitives/primitive_line_types.hpp +++ b/include/PSX/GPU/Primitives/primitive_line_types.hpp @@ -42,7 +42,7 @@ namespace JabyEngine { }; } - struct LINE_F : public internal::IsPrimitive, public internal::LineCodeInterface { + struct LINE_F : public internal::LineCodeInterface { struct Head { static constexpr auto IdentityCode = Code().set(Code::FlatShading).set(Code::SingleLine).set(Code::NonTransparent); diff --git a/include/PSX/GPU/Primitives/primitive_poly_types.hpp b/include/PSX/GPU/Primitives/primitive_poly_types.hpp index 59b0965d..5a51786e 100644 --- a/include/PSX/GPU/Primitives/primitive_poly_types.hpp +++ b/include/PSX/GPU/Primitives/primitive_poly_types.hpp @@ -51,7 +51,7 @@ namespace JabyEngine { / \ 3 - 2 */ - struct POLY_F3 : public internal::IsPrimitive, public internal::PolyCodeInterface { + struct POLY_F3 : public internal::PolyCodeInterface { static constexpr auto IdentityCode = Code().set(Code::FlatShading).set(Code::TriVertics).set(Code::Untextured).set(Code::NonTransparent); Color24 color; // a @@ -69,7 +69,7 @@ namespace JabyEngine { } }; - struct POLY_FT3 : public internal::IsPrimitive, public internal::PolyCodeInterface { + struct POLY_FT3 : public internal::PolyCodeInterface { struct VertexEx { Vertex position; PagePosition page; @@ -100,7 +100,7 @@ namespace JabyEngine { vertex2(vertices_ex[2].position), page2(vertices_ex[2].page), padded2(0) {} }; - struct POLY_G3 : public internal::IsPrimitive, public internal::PolyCodeInterface { + struct POLY_G3 : public internal::PolyCodeInterface { struct VertexEx { Vertex position; Color24 color; @@ -128,7 +128,7 @@ namespace JabyEngine { color2(verticies_ex[2].color), pad2(0), vertex2(verticies_ex[2].position) {} }; - struct POLY_GT3 : public internal::IsPrimitive, public internal::PolyCodeInterface { + struct POLY_GT3 : public internal::PolyCodeInterface { struct VertexEx { Vertex position; PagePosition page; @@ -168,7 +168,7 @@ namespace JabyEngine { | | 3 - 4 */ - struct POLY_F4 : public internal::IsPrimitive, public internal::PolyCodeInterface { + struct POLY_F4 : public internal::PolyCodeInterface { static constexpr auto IdentityCode = Code(POLY_F3::IdentityCode).set(Code::QuadVertics); Color24 color; // a @@ -193,7 +193,7 @@ namespace JabyEngine { color) {} }; - struct POLY_FT4 : public internal::IsPrimitive, public internal::PolyCodeInterface { + struct POLY_FT4 : public internal::PolyCodeInterface { typedef POLY_FT3::VertexEx VertexEx; static constexpr auto IdentityCode = Code(POLY_FT3::IdentityCode).set(Code::QuadVertics); @@ -233,7 +233,7 @@ namespace JabyEngine { ) {} }; - struct POLY_G4 : public internal::IsPrimitive, public internal::PolyCodeInterface { + struct POLY_G4 : public internal::PolyCodeInterface { typedef POLY_G3::VertexEx VertexEx; static constexpr auto IdentityCode = Code(POLY_G3::IdentityCode).set(Code::QuadVertics); @@ -270,7 +270,7 @@ namespace JabyEngine { ) {} }; - struct POLY_GT4 : public internal::IsPrimitive, public internal::PolyCodeInterface { + struct POLY_GT4 : public internal::PolyCodeInterface { typedef POLY_GT3::VertexEx VertexEx; static constexpr auto IdentityCode = Code(POLY_GT3::IdentityCode).set(Code::QuadVertics); @@ -325,6 +325,18 @@ namespace JabyEngine { typedef POLY_G4 GouraudRectangle; typedef POLY_GT4 GouraudTexturedRectangle; + namespace internal { + __jaby_engine_declare_render_primitive(POLY_F3); + __jaby_engine_declare_render_primitive(POLY_FT3); + __jaby_engine_declare_render_primitive(POLY_G3); + __jaby_engine_declare_render_primitive(POLY_GT3); + + __jaby_engine_declare_render_primitive(POLY_F4); + __jaby_engine_declare_render_primitive(POLY_FT4); + __jaby_engine_declare_render_primitive(POLY_G4); + __jaby_engine_declare_render_primitive(POLY_GT4); + } + static_assert(sizeof(POLY_F3) == 16); static_assert(sizeof(POLY_FT3) == 28); static_assert(sizeof(POLY_G3) == 24); diff --git a/include/PSX/GPU/Primitives/primitive_support_types.hpp b/include/PSX/GPU/Primitives/primitive_support_types.hpp index a12a5c7d..98e47810 100644 --- a/include/PSX/GPU/Primitives/primitive_support_types.hpp +++ b/include/PSX/GPU/Primitives/primitive_support_types.hpp @@ -35,9 +35,16 @@ namespace JabyEngine { T primitive; }; - struct IsPrimitive { - static constexpr bool is_primitive = true; + template + struct is_render_primitive { + static constexpr bool value = false; }; + + #define __jaby_engine_declare_render_primitive(type) \ + template<> \ + struct is_render_primitive { \ + static constexpr bool value = true; \ + } } // Reexport for easier use diff --git a/include/PSX/GPU/gpu.hpp b/include/PSX/GPU/gpu.hpp index 75344e05..f11e449a 100644 --- a/include/PSX/GPU/gpu.hpp +++ b/include/PSX/GPU/gpu.hpp @@ -41,7 +41,7 @@ namespace JabyEngine { } template - static enable_if::type render(const T& primitive) { + static enable_if::value>::type render(const T& primitive) { internal::render(reinterpret_cast(&primitive), sizeof(T)/sizeof(uint32_t)); } From f67361c62b0a02d8d737498bacf9b0fcb1a633ee Mon Sep 17 00:00:00 2001 From: jaby Date: Sat, 27 May 2023 17:07:15 +0200 Subject: [PATCH 037/588] Bound line type --- examples/PoolBox/application/src/main.cpp | 8 +++----- .../PSX/GPU/Primitives/primitive_line_types.hpp | 15 +++++++++++++++ include/PSX/GPU/gpu.hpp | 5 +++++ 3 files changed, 23 insertions(+), 5 deletions(-) diff --git a/examples/PoolBox/application/src/main.cpp b/examples/PoolBox/application/src/main.cpp index e2675cb3..6a914f76 100644 --- a/examples/PoolBox/application/src/main.cpp +++ b/examples/PoolBox/application/src/main.cpp @@ -87,11 +87,9 @@ static constexpr const auto rectangle5 = JabyEngine::GPU::POLY_GT4( JabyEngine::GPU::Color24::White()} ).set_semi_transparent(true); -static constexpr const JabyEngine::GPU::LINE_F line1[] = { - JabyEngine::GPU::LINE_F::new_line(LineColor, false), - JabyEngine::GPU::LINE_F::new_point({0, 0}), - JabyEngine::GPU::LINE_F::new_point({JabyEngine::GPU::Display::Width, JabyEngine::GPU::Display::Height}) -}; +static constexpr const auto line1 = JabyEngine::GPU::LineMaker::new_line_f(LineColor, { + {0, 0}, + {JabyEngine::GPU::Display::Width, JabyEngine::GPU::Display::Height}}); static void load_assets() { static const JabyEngine::CDFile Assets[] = { diff --git a/include/PSX/GPU/Primitives/primitive_line_types.hpp b/include/PSX/GPU/Primitives/primitive_line_types.hpp index 9c002124..b9cf74e5 100644 --- a/include/PSX/GPU/Primitives/primitive_line_types.hpp +++ b/include/PSX/GPU/Primitives/primitive_line_types.hpp @@ -50,6 +50,8 @@ namespace JabyEngine { Code code = IdentityCode; }; + typedef Vertex Body; + union { Head head; Vertex vertex; @@ -67,6 +69,19 @@ namespace JabyEngine { return {.vertex = {static_cast(0xF000), static_cast(0xF000u)}}; } }; + + struct LineMaker { + // Make this it's own outside type?? + template + struct Type { + T head; + T body[N]; + }; + + static constexpr Type new_line_f(const Color24& color, const Vertex (&vertices)[2]) { + return Type{.head = LINE_F::new_line(color, false), .body = {LINE_F::new_point(vertices[0]), LINE_F::new_point(vertices[1])}}; + } + }; } } diff --git a/include/PSX/GPU/gpu.hpp b/include/PSX/GPU/gpu.hpp index f11e449a..17630838 100644 --- a/include/PSX/GPU/gpu.hpp +++ b/include/PSX/GPU/gpu.hpp @@ -50,6 +50,11 @@ namespace JabyEngine { internal::render(reinterpret_cast(&line), N); } + template + static void render(const LineMaker::Type& line_type) { + internal::render(reinterpret_cast(&line_type), sizeof(line_type)/sizeof(uint32_t)); + } + uint8_t swap_buffers_vsync(uint8_t syncs, bool clear_screen = true); } } From 3d0a5b81c2166372f70c238d84ee368c4040eafc Mon Sep 17 00:00:00 2001 From: jaby Date: Sat, 27 May 2023 22:21:02 +0200 Subject: [PATCH 038/588] Improve LINE_F code --- examples/PoolBox/application/src/main.cpp | 14 +++- include/PSX/Auxiliary/type_traits.hpp | 44 ++++++++++ .../GPU/Primitives/primitive_line_types.hpp | 82 +++++++++++-------- include/PSX/GPU/gpu.hpp | 11 +-- include/PSX/GPU/gpu_types.hpp | 4 + 5 files changed, 108 insertions(+), 47 deletions(-) diff --git a/examples/PoolBox/application/src/main.cpp b/examples/PoolBox/application/src/main.cpp index 6a914f76..883d7bf6 100644 --- a/examples/PoolBox/application/src/main.cpp +++ b/examples/PoolBox/application/src/main.cpp @@ -87,9 +87,17 @@ static constexpr const auto rectangle5 = JabyEngine::GPU::POLY_GT4( JabyEngine::GPU::Color24::White()} ).set_semi_transparent(true); -static constexpr const auto line1 = JabyEngine::GPU::LineMaker::new_line_f(LineColor, { +static constexpr const auto line1 = JabyEngine::GPU::LINE_F::create(LineColor, { {0, 0}, - {JabyEngine::GPU::Display::Width, JabyEngine::GPU::Display::Height}}); + {JabyEngine::GPU::Display::Width, JabyEngine::GPU::Display::Height} +}); + +static constexpr const auto line2 = JabyEngine::GPU::LINE_F::create(LineColor.invert(), + JabyEngine::GPU::Vertex(0, 0), + JabyEngine::GPU::Vertex(16, 0), + JabyEngine::GPU::Vertex(16, 16), + JabyEngine::GPU::Vertex(0, 0) +); static void load_assets() { static const JabyEngine::CDFile Assets[] = { @@ -122,7 +130,6 @@ static void load_assets() { void main() { load_assets(); - printf("Dino: 0x%02X\n", rectangle4.code.value); while(true) { JabyEngine::GPU::render(triangle1); @@ -137,6 +144,7 @@ void main() { JabyEngine::GPU::render(rectangle5); JabyEngine::GPU::render(line1); + JabyEngine::GPU::render(line2); JabyEngine::GPU::swap_buffers_vsync(2); } diff --git a/include/PSX/Auxiliary/type_traits.hpp b/include/PSX/Auxiliary/type_traits.hpp index 5b667ef1..b1a78bb2 100644 --- a/include/PSX/Auxiliary/type_traits.hpp +++ b/include/PSX/Auxiliary/type_traits.hpp @@ -9,6 +9,50 @@ namespace JabyEngine { struct enable_if { typedef T type; }; + + // ############################################# + + template + struct is_same { + static constexpr bool value = false; + }; + + template + struct is_same { + static constexpr bool value = true; + }; + + // ############################################# + + template + struct conditional { + using type = T; + }; + + template + struct conditional { + using type = F; + }; + + // ############################################# + + template + struct conjunction { + static constexpr bool value = true; + }; + + template + struct conjunction : B1 { + }; + + template + struct conjunction : conditional, B1>::type { + }; + + // ############################################# + + template + using variadic_force_same = enable_if...>::value>::type; } #endif //! __JABYENGINE_TYPE_TRAITS_HPP__ \ No newline at end of file diff --git a/include/PSX/GPU/Primitives/primitive_line_types.hpp b/include/PSX/GPU/Primitives/primitive_line_types.hpp index b9cf74e5..ce58ad8b 100644 --- a/include/PSX/GPU/Primitives/primitive_line_types.hpp +++ b/include/PSX/GPU/Primitives/primitive_line_types.hpp @@ -22,66 +22,76 @@ namespace JabyEngine { constexpr T& set_poly_line(bool set = true) { if(set) { - static_cast(this)->head.code.set(Code::PolyLine); + static_cast(this)->code.set(Code::PolyLine); } else { - static_cast(this)->head.code.set(Code::SingleLine); + static_cast(this)->code.set(Code::SingleLine); } return *static_cast(this); } constexpr T& set_semi_transparent(bool set = true) { if(set) { - static_cast(this)->head.code.set(Code::SemiTransparent); + static_cast(this)->code.set(Code::SemiTransparent); } else { - static_cast(this)->head.code.set(Code::NonTransparent); + static_cast(this)->code.set(Code::NonTransparent); } return *static_cast(this); } }; + + struct LineHead : public LineCodeInterface { + Color24 color; + Code code; + }; + + union LineUnion { + LineHead head; + Vertex vertex; + Color24 color; + + static constexpr LineUnion create_head(const Color24& color, const LineCode& code, bool is_poly) { + return LineUnion{.head = LineHead{.color = color, .code = code}.set_poly_line(is_poly)}; + } + + static constexpr LineUnion create_vertex(const Vertex& vertex) { + return LineUnion{.vertex = {vertex.x, vertex.y}}; + } + + static constexpr LineUnion create_terminate() { + return LineUnion{.vertex = {static_cast(0x5000), static_cast(0x5000)}}; + } + }; + + template + struct Line { + LineUnion data[N]; + }; } - struct LINE_F : public internal::LineCodeInterface { - struct Head { - static constexpr auto IdentityCode = Code().set(Code::FlatShading).set(Code::SingleLine).set(Code::NonTransparent); - - Color24 color; - Code code = IdentityCode; - }; + struct LINE_F { + typedef ::JabyEngine::GPU::internal::LineCode Code; + typedef ::JabyEngine::GPU::internal::LineUnion LineUnion; - typedef Vertex Body; + static constexpr auto IdentityCode = Code().set(Code::FlatShading).set(Code::SingleLine).set(Code::NonTransparent); - union { - Head head; - Vertex vertex; - }; - - static constexpr LINE_F new_line(const Color24& color, bool is_poly) { - return LINE_F{.head = {.color = color, .code = Head::IdentityCode}}.set_poly_line(is_poly); + static constexpr internal::Line<3> create(const Color24& color, const Vertex (&vertices)[2]) { + return internal::Line<3>{LineUnion::create_head(color, IdentityCode, false), LineUnion::create_vertex(vertices[0]), LineUnion::create_vertex(vertices[1])}; } - static constexpr LINE_F new_point(const Vertex& vertex) { - return {.vertex = vertex}; - } - - static constexpr LINE_F new_terminate() { - return {.vertex = {static_cast(0xF000), static_cast(0xF000u)}}; + template + static constexpr internal::Line create(const Color24& color, const ARGS&...args) { + return internal::Line{LineUnion::create_head(color, IdentityCode, true), LineUnion::create_vertex(args)..., LineUnion::create_terminate()}; } }; - struct LineMaker { - // Make this it's own outside type?? - template - struct Type { - T head; - T body[N]; + namespace internal { + template + struct is_render_primitive> { + static constexpr bool value = true; }; - - static constexpr Type new_line_f(const Color24& color, const Vertex (&vertices)[2]) { - return Type{.head = LINE_F::new_line(color, false), .body = {LINE_F::new_point(vertices[0]), LINE_F::new_point(vertices[1])}}; - } - }; + } } } diff --git a/include/PSX/GPU/gpu.hpp b/include/PSX/GPU/gpu.hpp index 17630838..782c8a58 100644 --- a/include/PSX/GPU/gpu.hpp +++ b/include/PSX/GPU/gpu.hpp @@ -45,14 +45,9 @@ namespace JabyEngine { internal::render(reinterpret_cast(&primitive), sizeof(T)/sizeof(uint32_t)); } - template - static void render(const LINE_F (&line)[N]) { - internal::render(reinterpret_cast(&line), N); - } - - template - static void render(const LineMaker::Type& line_type) { - internal::render(reinterpret_cast(&line_type), sizeof(line_type)/sizeof(uint32_t)); + template + static enable_if::value>::type render(const LINE_F (&primitives)[N]) { + internal::render(reinterpret_cast(&primitives), (sizeof(T)/sizeof(uint32_t))*N); } uint8_t swap_buffers_vsync(uint8_t syncs, bool clear_screen = true); diff --git a/include/PSX/GPU/gpu_types.hpp b/include/PSX/GPU/gpu_types.hpp index c1caeb13..407dbf47 100644 --- a/include/PSX/GPU/gpu_types.hpp +++ b/include/PSX/GPU/gpu_types.hpp @@ -68,6 +68,10 @@ namespace JabyEngine { static constexpr Color24 Blue() { return Color24(0x0, 0x0, 0xFF); } + + constexpr Color24 invert() const { + return Color24(0xFF - this->red, 0xFF - this->green, 0xFF - this->blue); + } }; class Color { From ad7a6c2210d339c1dff6a2a8bfbe2b51da128ed0 Mon Sep 17 00:00:00 2001 From: jaby Date: Sun, 28 May 2023 10:36:24 +0200 Subject: [PATCH 039/588] Support all the line types in a somewhat decent way --- examples/PoolBox/application/Makefile | 2 +- examples/PoolBox/application/src/main.cpp | 17 ++- .../GPU/Primitives/primitive_line_types.hpp | 104 +++++++++++------- .../GPU/Primitives/primitive_poly_types.hpp | 9 +- include/PSX/GPU/gpu_types.hpp | 10 ++ 5 files changed, 93 insertions(+), 49 deletions(-) diff --git a/examples/PoolBox/application/Makefile b/examples/PoolBox/application/Makefile index efce152f..71f4711e 100644 --- a/examples/PoolBox/application/Makefile +++ b/examples/PoolBox/application/Makefile @@ -7,7 +7,7 @@ include $(JABY_ENGINE_DIR)/lib/Wildcard.mk SRCS = $(call rwildcard, src, c cpp) INCLUDES += -I$(JABY_ENGINE_DIR)/include -#CCFLAGS += -save-temps=obj +CCFLAGS += -save-temps=obj include $(JABY_ENGINE_DIR)/lib/Makefile include $(JABY_ENGINE_DIR)/lib/PSEXETarget.mk diff --git a/examples/PoolBox/application/src/main.cpp b/examples/PoolBox/application/src/main.cpp index 883d7bf6..3cb85b96 100644 --- a/examples/PoolBox/application/src/main.cpp +++ b/examples/PoolBox/application/src/main.cpp @@ -87,17 +87,26 @@ static constexpr const auto rectangle5 = JabyEngine::GPU::POLY_GT4( JabyEngine::GPU::Color24::White()} ).set_semi_transparent(true); -static constexpr const auto line1 = JabyEngine::GPU::LINE_F::create(LineColor, { +static constexpr const auto line1 = JabyEngine::GPU::LINE_F::create(LineColor, {0, 0}, {JabyEngine::GPU::Display::Width, JabyEngine::GPU::Display::Height} -}); - +); static constexpr const auto line2 = JabyEngine::GPU::LINE_F::create(LineColor.invert(), JabyEngine::GPU::Vertex(0, 0), JabyEngine::GPU::Vertex(16, 0), JabyEngine::GPU::Vertex(16, 16), JabyEngine::GPU::Vertex(0, 0) ); +static constexpr const auto line3 = JabyEngine::GPU::LINE_G::create( + {LineColor, {JabyEngine::GPU::Display::Width, 0}}, + {LineColor.invert(), {0, JabyEngine::GPU::Display::Height}} +); +static constexpr const auto line4 = JabyEngine::GPU::LINE_G::create( + JabyEngine::GPU::ColorVertex{JabyEngine::GPU::Color24::Red(), {0, 0}}, + JabyEngine::GPU::ColorVertex{JabyEngine::GPU::Color24::Green(), {0, 16}}, + JabyEngine::GPU::ColorVertex{JabyEngine::GPU::Color24::Blue(), {16, 16}}, + JabyEngine::GPU::ColorVertex{JabyEngine::GPU::Color24::White(), {0, 0}} +); static void load_assets() { static const JabyEngine::CDFile Assets[] = { @@ -145,6 +154,8 @@ void main() { JabyEngine::GPU::render(line1); JabyEngine::GPU::render(line2); + JabyEngine::GPU::render(line3); + JabyEngine::GPU::render(line4); JabyEngine::GPU::swap_buffers_vsync(2); } diff --git a/include/PSX/GPU/Primitives/primitive_line_types.hpp b/include/PSX/GPU/Primitives/primitive_line_types.hpp index ce58ad8b..d80c8b85 100644 --- a/include/PSX/GPU/Primitives/primitive_line_types.hpp +++ b/include/PSX/GPU/Primitives/primitive_line_types.hpp @@ -20,75 +20,103 @@ namespace JabyEngine { struct LineCodeInterface { typedef ::JabyEngine::GPU::internal::LineCode Code; - constexpr T& set_poly_line(bool set = true) { - if(set) { - static_cast(this)->code.set(Code::PolyLine); - } - else { - static_cast(this)->code.set(Code::SingleLine); - } - return *static_cast(this); - } - constexpr T& set_semi_transparent(bool set = true) { if(set) { - static_cast(this)->code.set(Code::SemiTransparent); + static_cast(this)->head.code.set(Code::SemiTransparent); } else { - static_cast(this)->code.set(Code::NonTransparent); + static_cast(this)->head.code.set(Code::NonTransparent); } return *static_cast(this); } }; - struct LineHead : public LineCodeInterface { - Color24 color; - Code code; - }; - - union LineUnion { - LineHead head; - Vertex vertex; + struct LineHead { Color24 color; + LineCode code; - static constexpr LineUnion create_head(const Color24& color, const LineCode& code, bool is_poly) { - return LineUnion{.head = LineHead{.color = color, .code = code}.set_poly_line(is_poly)}; + static constexpr LineHead create(const Color24& color, const LineCode& code, bool is_poly) { + return LineHead{.color = color, .code = code}.set_poly_line(is_poly); } - static constexpr LineUnion create_vertex(const Vertex& vertex) { - return LineUnion{.vertex = {vertex.x, vertex.y}}; - } + constexpr LineHead& set_poly_line(bool set = true) { + if(set) { + this->code.set(LineCode::PolyLine); + } - static constexpr LineUnion create_terminate() { - return LineUnion{.vertex = {static_cast(0x5000), static_cast(0x5000)}}; + else { + this->code.set(LineCode::SingleLine); + } + return *this; } }; - template - struct Line { - LineUnion data[N]; + struct Termination { + Vertex value; + + static constexpr Termination create() { + return {.value = {static_cast(0x5000), static_cast(0x5000)}}; + } + }; + + template + struct SingleLine : public LineCodeInterface> { + LineHead head; + Vertex start_point; + Body end_point; + }; + + template + struct MultiLine : public LineCodeInterface> { + LineHead head; + Vertex start_point; + Body points[N]; + Termination end; }; } struct LINE_F { - typedef ::JabyEngine::GPU::internal::LineCode Code; - typedef ::JabyEngine::GPU::internal::LineUnion LineUnion; + typedef internal::LineCode Code; static constexpr auto IdentityCode = Code().set(Code::FlatShading).set(Code::SingleLine).set(Code::NonTransparent); - static constexpr internal::Line<3> create(const Color24& color, const Vertex (&vertices)[2]) { - return internal::Line<3>{LineUnion::create_head(color, IdentityCode, false), LineUnion::create_vertex(vertices[0]), LineUnion::create_vertex(vertices[1])}; + static constexpr internal::SingleLine create(const Color24& color, const Vertex& start_point, const Vertex& end_point) { + using namespace internal; + return {.head = LineHead::create(color, IdentityCode, false), .start_point = start_point, .end_point = end_point}; } template - static constexpr internal::Line create(const Color24& color, const ARGS&...args) { - return internal::Line{LineUnion::create_head(color, IdentityCode, true), LineUnion::create_vertex(args)..., LineUnion::create_terminate()}; + static constexpr internal::MultiLine create(const Color24& color, const Vertex& start_point, const ARGS&...rest) { + using namespace internal; + return {.head = LineHead::create(color, IdentityCode, true), .start_point = start_point, .points = {rest...}, .end = Termination::create()}; + } + }; + + struct LINE_G { + typedef LINE_F::Code Code; + + static constexpr auto IdentityCode = Code(LINE_F::IdentityCode).set(Code::GouraudShading); + + static constexpr internal::SingleLine create(const ColorVertex& start_point, const ColorVertex& end_point) { + using namespace internal; + return {.head = LineHead::create(start_point.color, IdentityCode, false), .start_point = start_point.position, .end_point = end_point}; + } + + template + static constexpr internal::MultiLine create(const ColorVertex& start_point, const ARGS&...rest) { + using namespace internal; + return {.head = LineHead::create(start_point.color, IdentityCode, true), .start_point = start_point.position, .points = {rest...}, .end = Termination::create()}; } }; namespace internal { - template - struct is_render_primitive> { + template + struct is_render_primitive> { + static constexpr bool value = true; + }; + + template + struct is_render_primitive> { static constexpr bool value = true; }; } diff --git a/include/PSX/GPU/Primitives/primitive_poly_types.hpp b/include/PSX/GPU/Primitives/primitive_poly_types.hpp index 5a51786e..3081842d 100644 --- a/include/PSX/GPU/Primitives/primitive_poly_types.hpp +++ b/include/PSX/GPU/Primitives/primitive_poly_types.hpp @@ -101,10 +101,6 @@ namespace JabyEngine { }; struct POLY_G3 : public internal::PolyCodeInterface { - struct VertexEx { - Vertex position; - Color24 color; - }; static constexpr auto IdentityCode = Code(POLY_F3::IdentityCode).set(Code::GouraudShading); Color24 color0; // a @@ -122,7 +118,7 @@ namespace JabyEngine { {verticies[0], color[0]}, {verticies[1], color[1]}, {verticies[2], color[2]}}) {} - constexpr POLY_G3(const VertexEx (&verticies_ex)[3]) : + constexpr POLY_G3(const VertexColor (&verticies_ex)[3]) : color0(verticies_ex[0].color), code(IdentityCode), vertex0(verticies_ex[0].position), color1(verticies_ex[1].color), pad1(0), vertex1(verticies_ex[1].position), color2(verticies_ex[2].color), pad2(0), vertex2(verticies_ex[2].position) {} @@ -234,7 +230,6 @@ namespace JabyEngine { }; struct POLY_G4 : public internal::PolyCodeInterface { - typedef POLY_G3::VertexEx VertexEx; static constexpr auto IdentityCode = Code(POLY_G3::IdentityCode).set(Code::QuadVertics); Color24 color0; // a @@ -257,7 +252,7 @@ namespace JabyEngine { {verticies[2], color[2]}, {verticies[3], color[3]} }) {} - constexpr POLY_G4(const VertexEx (&verticies_ex)[4]) : + constexpr POLY_G4(const VertexColor (&verticies_ex)[4]) : color0(verticies_ex[0].color), code(IdentityCode), vertex0(verticies_ex[0].position), color1(verticies_ex[1].color), pad1(0), vertex1(verticies_ex[1].position), color2(verticies_ex[2].color), pad2(0), vertex2(verticies_ex[2].position), diff --git a/include/PSX/GPU/gpu_types.hpp b/include/PSX/GPU/gpu_types.hpp index 407dbf47..bb9c5684 100644 --- a/include/PSX/GPU/gpu_types.hpp +++ b/include/PSX/GPU/gpu_types.hpp @@ -168,6 +168,16 @@ namespace JabyEngine { // Type used for primitives typedef PositionI16 Vertex; + + struct VertexColor { + Vertex position; + Color24 color; + }; + + struct ColorVertex { + Color24 color; + alignas(2) Vertex position; + }; } } #endif //!__JABYENGINE_GPU_TYPES_HPP__ \ No newline at end of file From 1ff636791844940b86ad8359b4c6f75635fdd039 Mon Sep 17 00:00:00 2001 From: jaby Date: Tue, 30 May 2023 22:06:38 +0200 Subject: [PATCH 040/588] Support RectF --- examples/PoolBox/application/src/main.cpp | 162 ++++++++++-------- .../GPU/Primitives/primitive_line_types.hpp | 15 +- .../GPU/Primitives/primitive_poly_types.hpp | 20 +-- .../Primitives/primitive_rectangle_types.hpp | 65 +++++++ .../Primitives/primitive_support_types.hpp | 24 +++ include/PSX/GPU/gpu_primitives.hpp | 1 + include/PSX/GPU/gpu_types.hpp | 4 + 7 files changed, 187 insertions(+), 104 deletions(-) create mode 100644 include/PSX/GPU/Primitives/primitive_rectangle_types.hpp diff --git a/examples/PoolBox/application/src/main.cpp b/examples/PoolBox/application/src/main.cpp index 3cb85b96..a788a404 100644 --- a/examples/PoolBox/application/src/main.cpp +++ b/examples/PoolBox/application/src/main.cpp @@ -11,26 +11,28 @@ enum LBA { __jabyengine_end_lba_request }; +using namespace JabyEngine; + // Some default values for the objects -static constexpr auto TriangleColor = JabyEngine::GPU::Color24(0x0, 0xFF, 0xFF); -static constexpr auto TriangleArea = JabyEngine::GPU::AreaI16({0, 0}, {64, 64}); -static constexpr auto TriangleTPage = JabyEngine::GPU::TPage(320, 0, JabyEngine::GPU::SemiTransparency::B_Half_add_F_Half, JabyEngine::GPU::TexturePageColor::$4bit); -static constexpr auto TriangleClut = JabyEngine::GPU::PageClut(320, 511); +static constexpr auto TriangleColor = GPU::Color24(0x0, 0xFF, 0xFF); +static constexpr auto TriangleArea = GPU::AreaI16({0, 0}, {64, 64}); +static constexpr auto TriangleTPage = GPU::TPage(320, 0, GPU::SemiTransparency::B_Half_add_F_Half, GPU::TexturePageColor::$4bit); +static constexpr auto TriangleClut = GPU::PageClut(320, 511); -static constexpr auto RectangleColor = JabyEngine::GPU::Color24(0x80, 0x80, 0xFF); -static constexpr auto RectangleArea = JabyEngine::GPU::AreaI16({0, TriangleArea.size.height}, {80, 80}); -static constexpr auto RectangleTPage = JabyEngine::GPU::TPage(320, 256, JabyEngine::GPU::SemiTransparency::B_Half_add_F_Half, JabyEngine::GPU::TexturePageColor::$4bit); -static constexpr auto RectangleClut = JabyEngine::GPU::PageClut(320, 510); +static constexpr auto RectangleColor = GPU::Color24(0x80, 0x80, 0xFF); +static constexpr auto RectangleArea = GPU::AreaI16({0, TriangleArea.size.height}, {80, 80}); +static constexpr auto RectangleTPage = GPU::TPage(320, 256, GPU::SemiTransparency::B_Half_add_F_Half, GPU::TexturePageColor::$4bit); +static constexpr auto RectangleClut = GPU::PageClut(320, 510); -static constexpr auto LineColor = JabyEngine::GPU::Color24(0xFF, 0x0, 0x0); +static constexpr auto LineColor = GPU::Color24(0xFF, 0x0, 0x0); -static constexpr const auto triangle1 = JabyEngine::GPU::POLY_F3({ +static constexpr const auto triangle1 = GPU::POLY_F3({ {TriangleArea.position.x, TriangleArea.position.y}, {TriangleArea.size.width, TriangleArea.size.height}, {TriangleArea.position.x, TriangleArea.size.height}}, TriangleColor ); -static constexpr const auto triangle2 = JabyEngine::GPU::POLY_FT3({ +static constexpr const auto triangle2 = GPU::POLY_FT3({ {TriangleArea.position.x, TriangleArea.position.y}, {TriangleArea.size.width, TriangleArea.position.y}, {TriangleArea.size.width, TriangleArea.size.height}},{ @@ -40,96 +42,101 @@ static constexpr const auto triangle2 = JabyEngine::GPU::POLY_FT3({ {TriangleArea.size.width, TriangleArea.size.height}}, TriangleTPage, TriangleClut, - JabyEngine::GPU::Color24::Grey() + GPU::Color24::Grey() ); -static constexpr const auto triangle3 = JabyEngine::GPU::POLY_G3({ - {triangle1.vertex0.move(TriangleArea.size.width, 0), JabyEngine::GPU::Color24::Red()}, - {triangle1.vertex1.move(TriangleArea.size.width, 0), JabyEngine::GPU::Color24::Green()}, - {triangle1.vertex2.move(TriangleArea.size.width, 0), JabyEngine::GPU::Color24::Blue()}} +static constexpr const auto triangle3 = GPU::POLY_G3({ + {triangle1.vertex0.move(TriangleArea.size.width, 0), GPU::Color24::Red()}, + {triangle1.vertex1.move(TriangleArea.size.width, 0), GPU::Color24::Green()}, + {triangle1.vertex2.move(TriangleArea.size.width, 0), GPU::Color24::Blue()}} ); -static constexpr const auto triangle4 = JabyEngine::GPU::POLY_GT3({ - {triangle2.vertex0.move(TriangleArea.size.width, 0), triangle2.page0, JabyEngine::GPU::Color24::Red()}, - {triangle2.vertex1.move(TriangleArea.size.width, 0), triangle2.page1, JabyEngine::GPU::Color24::Blue()}, - {triangle2.vertex2.move(TriangleArea.size.width, 0), triangle2.page2, JabyEngine::GPU::Color24::Green()}}, +static constexpr const auto triangle4 = GPU::POLY_GT3({ + {triangle2.vertex0.move(TriangleArea.size.width, 0), triangle2.page0, GPU::Color24::Red()}, + {triangle2.vertex1.move(TriangleArea.size.width, 0), triangle2.page1, GPU::Color24::Blue()}, + {triangle2.vertex2.move(TriangleArea.size.width, 0), triangle2.page2, GPU::Color24::Green()}}, TriangleTPage, TriangleClut ); -static constexpr const auto rectangle1 = JabyEngine::GPU::POLY_F4(RectangleArea, RectangleColor); -static constexpr const auto rectangle2 = JabyEngine::GPU::POLY_FT4({ +static constexpr const auto rectangle1 = GPU::POLY_F4(RectangleArea, RectangleColor); +static constexpr const auto rectangle2 = GPU::POLY_FT4({ RectangleArea.position.move(RectangleArea.size.width, 0), RectangleArea.size}, {0, 0}, RectangleTPage, RectangleClut, - JabyEngine::GPU::Color24::Grey() + GPU::Color24::Grey() ); -static constexpr const auto rectangle3 = JabyEngine::GPU::POLY_G4( +static constexpr const auto rectangle3 = GPU::POLY_G4( {RectangleArea.position.move(RectangleArea.size.width*2, 0), RectangleArea.size}, { - JabyEngine::GPU::Color24::Red(), - JabyEngine::GPU::Color24::Blue(), - JabyEngine::GPU::Color24::Green(), - JabyEngine::GPU::Color24::White()}); -static constexpr const auto rectangle4 = JabyEngine::GPU::POLY_GT4( + GPU::Color24::Red(), + GPU::Color24::Blue(), + GPU::Color24::Green(), + GPU::Color24::White()}); +static constexpr const auto rectangle4 = GPU::POLY_GT4( {RectangleArea.position.move(RectangleArea.size.width*3, 0), RectangleArea.size}, {0, 0}, RectangleTPage, RectangleClut, { - JabyEngine::GPU::Color24::Red(), - JabyEngine::GPU::Color24::Blue(), - JabyEngine::GPU::Color24::Green(), - JabyEngine::GPU::Color24::White()} + GPU::Color24::Red(), + GPU::Color24::Blue(), + GPU::Color24::Green(), + GPU::Color24::White()} ); -static constexpr const auto rectangle5 = JabyEngine::GPU::POLY_GT4( +static constexpr const auto rectangle5 = GPU::POLY_GT4( {RectangleArea.position.move(0, RectangleArea.size.height), RectangleArea.size}, {0, 0}, RectangleTPage, RectangleClut, { - JabyEngine::GPU::Color24::Red(), - JabyEngine::GPU::Color24::Blue(), - JabyEngine::GPU::Color24::Green(), - JabyEngine::GPU::Color24::White()} + GPU::Color24::Red(), + GPU::Color24::Blue(), + GPU::Color24::Green(), + GPU::Color24::White()} ).set_semi_transparent(true); -static constexpr const auto line1 = JabyEngine::GPU::LINE_F::create(LineColor, +static constexpr const auto line1 = GPU::LINE_F::create(LineColor, {0, 0}, - {JabyEngine::GPU::Display::Width, JabyEngine::GPU::Display::Height} + {GPU::Display::Width, GPU::Display::Height} ); -static constexpr const auto line2 = JabyEngine::GPU::LINE_F::create(LineColor.invert(), - JabyEngine::GPU::Vertex(0, 0), - JabyEngine::GPU::Vertex(16, 0), - JabyEngine::GPU::Vertex(16, 16), - JabyEngine::GPU::Vertex(0, 0) +static constexpr const auto line2 = GPU::LINE_F::create(LineColor.invert(), + GPU::Vertex(0, 0), + GPU::Vertex(16, 0), + GPU::Vertex(16, 16), + GPU::Vertex(0, 0) ); -static constexpr const auto line3 = JabyEngine::GPU::LINE_G::create( - {LineColor, {JabyEngine::GPU::Display::Width, 0}}, - {LineColor.invert(), {0, JabyEngine::GPU::Display::Height}} +static constexpr const auto line3 = GPU::LINE_G::create( + {LineColor, {GPU::Display::Width, 0}}, + {LineColor.invert(), {0, GPU::Display::Height}} ); -static constexpr const auto line4 = JabyEngine::GPU::LINE_G::create( - JabyEngine::GPU::ColorVertex{JabyEngine::GPU::Color24::Red(), {0, 0}}, - JabyEngine::GPU::ColorVertex{JabyEngine::GPU::Color24::Green(), {0, 16}}, - JabyEngine::GPU::ColorVertex{JabyEngine::GPU::Color24::Blue(), {16, 16}}, - JabyEngine::GPU::ColorVertex{JabyEngine::GPU::Color24::White(), {0, 0}} +static constexpr const auto line4 = GPU::LINE_G::create( + GPU::ColorVertex{GPU::Color24::Red(), {0, 0}}, + GPU::ColorVertex{GPU::Color24::Green(), {0, 16}}, + GPU::ColorVertex{GPU::Color24::Blue(), {16, 16}}, + GPU::ColorVertex{GPU::Color24::White(), {0, 0}} ); +static constexpr const auto rect1 = GPU::RECT_FVAR(GPU::Color24::Green(), GPU::AreaI16({GPU::Display::Width - 32, GPU::Display::Height - 32}, {32, 32})); +static constexpr const auto rect2 = GPU::RECT_F16(GPU::Color24::Blue(), {GPU::Display::Width - 16, GPU::Display::Height - 16}); +static constexpr const auto rect3 = GPU::RECT_F8(GPU::Color24::Yellow(), {GPU::Display::Width - 8, GPU::Display::Height - 8}); +static constexpr const auto rect4 = GPU::RECT_F1(GPU::Color24::Red(), {GPU::Display::Width - 1, GPU::Display::Height - 1}); + static void load_assets() { - static const JabyEngine::CDFile Assets[] = { - JabyEngine::CDFileBuilder::simple_tim(LBA::FONT, JabyEngine::SimpleTIM(320, 0, 320, 511)), - JabyEngine::CDFileBuilder::simple_tim(LBA::ICON, JabyEngine::SimpleTIM(320, 256, 320, 510)), + static const CDFile Assets[] = { + CDFileBuilder::simple_tim(LBA::FONT, SimpleTIM(320, 0, 320, 511)), + CDFileBuilder::simple_tim(LBA::ICON, SimpleTIM(320, 256, 320, 510)), }; - const auto buffer_cfg = JabyEngine::CDFileProcessor::BufferConfiguration::new_default(); - JabyEngine::CDFileProcessor file_processor; + const auto buffer_cfg = CDFileProcessor::BufferConfiguration::new_default(); + CDFileProcessor file_processor; file_processor.setup(lba, Assets, buffer_cfg); while(true) { switch(file_processor.process()) { - case JabyEngine::Progress::InProgress: + case Progress::InProgress: break; - case JabyEngine::Progress::Done: + case Progress::Done: if(!file_processor.next(lba, buffer_cfg)) { return; } break; - case JabyEngine::Progress::Error: + case Progress::Error: printf("Error detected! Aborting load\n"); return; } @@ -141,23 +148,28 @@ void main() { load_assets(); while(true) { - JabyEngine::GPU::render(triangle1); - JabyEngine::GPU::render(triangle2); - JabyEngine::GPU::render(triangle3); - JabyEngine::GPU::render(triangle4); + GPU::render(triangle1); + GPU::render(triangle2); + GPU::render(triangle3); + GPU::render(triangle4); - JabyEngine::GPU::render(rectangle1); - JabyEngine::GPU::render(rectangle2); - JabyEngine::GPU::render(rectangle3); - JabyEngine::GPU::render(rectangle4); - JabyEngine::GPU::render(rectangle5); + GPU::render(rectangle1); + GPU::render(rectangle2); + GPU::render(rectangle3); + GPU::render(rectangle4); + GPU::render(rectangle5); - JabyEngine::GPU::render(line1); - JabyEngine::GPU::render(line2); - JabyEngine::GPU::render(line3); - JabyEngine::GPU::render(line4); + GPU::render(rect1); + GPU::render(rect2); + GPU::render(rect3); + GPU::render(rect4); - JabyEngine::GPU::swap_buffers_vsync(2); + GPU::render(line1); + GPU::render(line2); + GPU::render(line3); + GPU::render(line4); + + GPU::swap_buffers_vsync(2); } } __declare_lba_header(LBA); \ No newline at end of file diff --git a/include/PSX/GPU/Primitives/primitive_line_types.hpp b/include/PSX/GPU/Primitives/primitive_line_types.hpp index d80c8b85..5cb254e3 100644 --- a/include/PSX/GPU/Primitives/primitive_line_types.hpp +++ b/include/PSX/GPU/Primitives/primitive_line_types.hpp @@ -1,5 +1,5 @@ -#ifndef __JABY_ENGINE_PRIMITIVE_LINE_TYPES_HPP__ -#define __JABY_ENGINE_PRIMITIVE_LINE_TYPES_HPP__ +#ifndef __JABYENGINE_PRIMITIVE_LINE_TYPES_HPP__ +#define __JABYENGINE_PRIMITIVE_LINE_TYPES_HPP__ #include "primitive_support_types.hpp" namespace JabyEngine { @@ -12,8 +12,6 @@ namespace JabyEngine { static constexpr auto FlatShading = !GouraudShading; static constexpr auto PolyLine = Bit(27 - BitCorrection); static constexpr auto SingleLine = !PolyLine; - static constexpr auto SemiTransparent = Bit(25 - BitCorrection); - static constexpr auto NonTransparent = !SemiTransparent; }; template @@ -21,12 +19,7 @@ namespace JabyEngine { typedef ::JabyEngine::GPU::internal::LineCode Code; constexpr T& set_semi_transparent(bool set = true) { - if(set) { - static_cast(this)->head.code.set(Code::SemiTransparent); - } - else { - static_cast(this)->head.code.set(Code::NonTransparent); - } + static_cast(this)->head.code.set_tenary(set, Code::SemiTransparent, Code::NonTransparent); return *static_cast(this); } }; @@ -123,4 +116,4 @@ namespace JabyEngine { } } -#endif //!__JABY_ENGINE_PRIMITIVE_LINE_TYPES_HPP__ \ No newline at end of file +#endif //!__JABYENGINE_PRIMITIVE_LINE_TYPES_HPP__ \ No newline at end of file diff --git a/include/PSX/GPU/Primitives/primitive_poly_types.hpp b/include/PSX/GPU/Primitives/primitive_poly_types.hpp index 3081842d..65520a77 100644 --- a/include/PSX/GPU/Primitives/primitive_poly_types.hpp +++ b/include/PSX/GPU/Primitives/primitive_poly_types.hpp @@ -12,12 +12,6 @@ namespace JabyEngine { static constexpr auto FlatShading = !GouraudShading; static constexpr auto QuadVertics = Bit(27 - BitCorrection); static constexpr auto TriVertics = !QuadVertics; - static constexpr auto Textured = Bit(26 - BitCorrection); - static constexpr auto Untextured = !Textured; - static constexpr auto SemiTransparent = Bit(25 - BitCorrection); - static constexpr auto NonTransparent = !SemiTransparent; - static constexpr auto NoBlendTexture = Bit(24 - BitCorrection); - static constexpr auto BlendTexture = !NoBlendTexture; }; template @@ -25,22 +19,12 @@ namespace JabyEngine { typedef ::JabyEngine::GPU::internal::PolyCode Code; constexpr T& set_semi_transparent(bool set = true) { - if(set) { - static_cast(this)->code.set(Code::SemiTransparent); - } - else { - static_cast(this)->code.set(Code::NonTransparent); - } + static_cast(this)->code.set_tenary(set, Code::SemiTransparent, Code::NonTransparent); return *static_cast(this); } constexpr T& set_texture_blending(bool set = true) { - if(set) { - static_cast(this)->code.set(Code::BlendTexture); - } - else { - static_cast(this)->code.set(Code::NoBlendTexture); - } + static_cast(this)->code.set_tenary(set, Code::BlendTexture, Code::NoBlendTexture); return *static_cast(this); } }; diff --git a/include/PSX/GPU/Primitives/primitive_rectangle_types.hpp b/include/PSX/GPU/Primitives/primitive_rectangle_types.hpp new file mode 100644 index 00000000..a74e67a9 --- /dev/null +++ b/include/PSX/GPU/Primitives/primitive_rectangle_types.hpp @@ -0,0 +1,65 @@ +#ifndef __JABYENGINE_PRIMITIVE_RECTANGLE_TYPES_HPP__ +#define __JABYENGINE_PRIMITIVE_RECTANGLE_TYPES_HPP__ +#include "primitive_support_types.hpp" + +namespace JabyEngine { + namespace GPU { + namespace internal { + struct RectCode : public CodeBase { + enum struct Size : uint8_t { + Variable = 0, + Pixel1x1 = 1, + Sprite8x8 = 2, + Sprite16x16 = 3 + }; + static constexpr uint8_t CmdValue = 0b011; + + static constexpr auto Size = BitRange::from_to(27 - BitCorrection, 28 - BitCorrection); + }; + + template + struct RectCodeInterface { + typedef typename ::JabyEngine::GPU::internal::RectCode Code; + + constexpr T& set_semi_transparent(bool set = true) { + static_cast(this)->code.set_tenary(set, Code::SemiTransparent, Code::NonTransparent); + return *static_cast(this); + } + }; + + template + struct RECT_F : public RectCodeInterface> { + typedef RECT_F::Code Code; + static constexpr auto IdentityCode = Code().set(Code::Size.with(static_cast(Size))).set(Code::Untextured).set(Code::NonTransparent); + + Color24 color; + Code code; + Vertex position; + + constexpr RECT_F() = default; + constexpr RECT_F(const Color24& color, const Vertex& position) : color(color), code(IdentityCode), position(position) { + } + }; + } + + typedef internal::RECT_F RECT_F1; + typedef internal::RECT_F RECT_F8; + typedef internal::RECT_F RECT_F16; + struct RECT_FVAR : public internal::RECT_F { + Vertex position_bottom_right; + + constexpr RECT_FVAR() = default; + constexpr RECT_FVAR(const Color24& color, const AreaI16& area) : RECT_F(color, area.position), position_bottom_right(area.position.move(area.size.width, area.size.height)) { + } + }; + + namespace internal { + __jaby_engine_declare_render_primitive(RECT_F1); + __jaby_engine_declare_render_primitive(RECT_F8); + __jaby_engine_declare_render_primitive(RECT_F16); + __jaby_engine_declare_render_primitive(RECT_FVAR); + } + } +} + +#endif //!__JABYENGINE_PRIMITIVE_RECTANGLE_TYPES_HPP__ \ No newline at end of file diff --git a/include/PSX/GPU/Primitives/primitive_support_types.hpp b/include/PSX/GPU/Primitives/primitive_support_types.hpp index 98e47810..d8ba0ade 100644 --- a/include/PSX/GPU/Primitives/primitive_support_types.hpp +++ b/include/PSX/GPU/Primitives/primitive_support_types.hpp @@ -13,6 +13,14 @@ namespace JabyEngine { uint8_t value = bit::value::set_normalized(0u, CmdID.with(T::CmdValue)); + // Common values for all the primitves + static constexpr auto Textured = Bit(26 - BitCorrection); + static constexpr auto Untextured = !Textured; + static constexpr auto SemiTransparent = Bit(25 - BitCorrection); + static constexpr auto NonTransparent = !SemiTransparent; + static constexpr auto NoBlendTexture = Bit(24 - BitCorrection); + static constexpr auto BlendTexture = !NoBlendTexture; + constexpr CodeBase() = default; constexpr CodeBase(const T& code) : value(code.value) { } @@ -26,6 +34,22 @@ namespace JabyEngine { this->value = bit::set(this->value, bit); return static_cast(*this); } + + constexpr T& set(BitRange::RangeValuePair value_pair) { + this->value = bit::value::set_normalized(this->value, value_pair); + return static_cast(*this); + } + + template + constexpr T& set_tenary(bool use_first, const S& first, const R& second) { + if(use_first) { + return this->set(first); + } + + else { + return this->set(second); + } + } }; // Concept for now diff --git a/include/PSX/GPU/gpu_primitives.hpp b/include/PSX/GPU/gpu_primitives.hpp index 9c6ba90b..f0415ef5 100644 --- a/include/PSX/GPU/gpu_primitives.hpp +++ b/include/PSX/GPU/gpu_primitives.hpp @@ -1,5 +1,6 @@ #ifndef __JABYENGINE_GPU_PRIMITIVES_HPP__ #define __JABYENGINE_GPU_PRIMITIVES_HPP__ #include "Primitives/primitive_line_types.hpp" +#include "Primitives/primitive_rectangle_types.hpp" #include "Primitives/primitive_poly_types.hpp" #endif // !__JABYENGINE_GPU_PRIMITIVES_HPP__ \ No newline at end of file diff --git a/include/PSX/GPU/gpu_types.hpp b/include/PSX/GPU/gpu_types.hpp index bb9c5684..1271a052 100644 --- a/include/PSX/GPU/gpu_types.hpp +++ b/include/PSX/GPU/gpu_types.hpp @@ -69,6 +69,10 @@ namespace JabyEngine { return Color24(0x0, 0x0, 0xFF); } + static constexpr Color24 Yellow() { + return Color24(0xFF, 0xFF, 0x0); + } + constexpr Color24 invert() const { return Color24(0xFF - this->red, 0xFF - this->green, 0xFF - this->blue); } From d99b7445be7e1598dd241f312d66bf8ac676b70a Mon Sep 17 00:00:00 2001 From: jaby Date: Wed, 31 May 2023 22:29:19 +0200 Subject: [PATCH 041/588] Prepare for textured sprites; better integration of GPU types --- .../Primitives/primitive_rectangle_types.hpp | 33 ++++++++++++++++++- include/PSX/GPU/gpu_types.hpp | 4 +++ include/PSX/System/IOPorts/gpu_io.hpp | 28 +++++++++------- .../internal-include/GPU/gpu_internal.hpp | 24 +++++++------- src/Library/src/GPU/gpu.cpp | 10 +++--- 5 files changed, 69 insertions(+), 30 deletions(-) diff --git a/include/PSX/GPU/Primitives/primitive_rectangle_types.hpp b/include/PSX/GPU/Primitives/primitive_rectangle_types.hpp index a74e67a9..b45cdfe5 100644 --- a/include/PSX/GPU/Primitives/primitive_rectangle_types.hpp +++ b/include/PSX/GPU/Primitives/primitive_rectangle_types.hpp @@ -40,6 +40,21 @@ namespace JabyEngine { constexpr RECT_F(const Color24& color, const Vertex& position) : color(color), code(IdentityCode), position(position) { } }; + + template + struct RECT_T : public RectCodeInterface> { + typedef RECT_T::Code Code; + static constexpr auto IdentityCode = Code(RECT_F::IdentityCode).set(Code::Textured); + + Color24 color; + Code code; + Vertex position; + PagePosition page; + + constexpr RECT_T() = default; + constexpr RECT_T(const Color24& color, const Vertex& position, const PagePosition& page) : color(color), code(IdentityCode), position(position), page(page) { + } + }; } typedef internal::RECT_F RECT_F1; @@ -49,7 +64,18 @@ namespace JabyEngine { Vertex position_bottom_right; constexpr RECT_FVAR() = default; - constexpr RECT_FVAR(const Color24& color, const AreaI16& area) : RECT_F(color, area.position), position_bottom_right(area.position.move(area.size.width, area.size.height)) { + constexpr RECT_FVAR(const Color24& color, const AreaI16& area) : RECT_F(color, area.position), position_bottom_right(area.get_bottom_left()) { + } + }; + + typedef internal::RECT_T RECT_T1; + typedef internal::RECT_T RECT_T8; + typedef internal::RECT_T RECT_T16; + struct RECT_TVAR : public internal::RECT_T { + Vertex position_bottom_right; + + constexpr RECT_TVAR() = default; + constexpr RECT_TVAR(const Color24& color, const AreaI16& area, const PagePosition& page) : RECT_T(color, area.position, page), position_bottom_right(area.get_bottom_left()) { } }; @@ -58,6 +84,11 @@ namespace JabyEngine { __jaby_engine_declare_render_primitive(RECT_F8); __jaby_engine_declare_render_primitive(RECT_F16); __jaby_engine_declare_render_primitive(RECT_FVAR); + + __jaby_engine_declare_render_primitive(RECT_T1); + __jaby_engine_declare_render_primitive(RECT_T8); + __jaby_engine_declare_render_primitive(RECT_T16); + __jaby_engine_declare_render_primitive(RECT_TVAR); } } } diff --git a/include/PSX/GPU/gpu_types.hpp b/include/PSX/GPU/gpu_types.hpp index 1271a052..d09387a8 100644 --- a/include/PSX/GPU/gpu_types.hpp +++ b/include/PSX/GPU/gpu_types.hpp @@ -142,6 +142,10 @@ namespace JabyEngine { } constexpr Area(T position_x, T position_y, T size_width, T size_height) : position{position_x, position_y}, size{size_width, size_height} { } + + constexpr Position get_bottom_left() const { + return this->position.move(this->size.width, this->size.height); + } }; // Type used for primitives diff --git a/include/PSX/System/IOPorts/gpu_io.hpp b/include/PSX/System/IOPorts/gpu_io.hpp index a6473a9d..1213ba90 100644 --- a/include/PSX/System/IOPorts/gpu_io.hpp +++ b/include/PSX/System/IOPorts/gpu_io.hpp @@ -114,27 +114,31 @@ namespace JabyEngine { return {(0b101u << 29)}; } - static constexpr GP0_t DrawAreaTopLeft(uint16_t x, uint16_t y) { - return Helper::DrawAreaTemplate(0xE3, x, y); + /*static constexpr GP0_t DrawMode(const GPU::PositionU16& page_pos, SemiTransparency transparency, TexturePageColor tex_color, bool dither) { + + }*/ + + static constexpr GP0_t DrawAreaTopLeft(const GPU::PositionU16& position) { + return Helper::DrawAreaTemplate(0xE3, position.x, position.y); } - static constexpr GP0_t DrawAreaBottomRight(uint16_t x, uint16_t y) { - return Helper::DrawAreaTemplate(0xE4, x, y); + static constexpr GP0_t DrawAreaBottomRight(const GPU::PositionU16& position) { + return Helper::DrawAreaTemplate(0xE4, position.x, position.y); } - static GP0_t SetDrawOffset(int16_t x, int16_t y) { + static GP0_t SetDrawOffset(const GPU::PositionI16& offset) { constexpr auto X = BitRange::from_to(0, 10); constexpr auto Y = BitRange::from_to(11, 21); - return {Helper::construct_cmd(0xE5, X.as_value(static_cast(x)) | Y.as_value(static_cast(y)))}; + return {Helper::construct_cmd(0xE5, X.as_value(static_cast(offset.x)) | Y.as_value(static_cast(offset.y)))}; } - static constexpr GP0_t TopLeftPosition(uint16_t x, uint16_t y) { - return {(static_cast(y) << 16u) | x}; + static constexpr GP0_t TopLeftPosition(const GPU::PositionU16& position) { + return {(static_cast(position.y) << 16u) | position.x}; } - static constexpr GP0_t WidthHeight(uint16_t w, uint16_t h) { - return {(static_cast(h) << 16u) | w}; + static constexpr GP0_t WidthHeight(const GPU::SizeU16& size) { + return {(static_cast(size.height) << 16u) | size.width}; } static constexpr GP1_t Reset() { @@ -153,11 +157,11 @@ namespace JabyEngine { return {Helper::construct_cmd(0x04, static_cast(dir))}; } - static constexpr GP1_t DisplayArea(uint16_t x, uint16_t y) { + static constexpr GP1_t DisplayArea(const GPU::PositionU16& position) { constexpr auto X = BitRange::from_to(0, 9); constexpr auto Y = BitRange::from_to(10, 18); - return {Helper::construct_cmd(0x05, X.as_value(static_cast(x)) | Y.as_value(static_cast(y)))}; + return {Helper::construct_cmd(0x05, X.as_value(static_cast(position.x)) | Y.as_value(static_cast(position.y)))}; } static constexpr GP1_t HorizontalDisplayRange(uint16_t x1, uint16_t x2) { diff --git a/src/Library/internal-include/GPU/gpu_internal.hpp b/src/Library/internal-include/GPU/gpu_internal.hpp index 2bacb80b..891abf77 100644 --- a/src/Library/internal-include/GPU/gpu_internal.hpp +++ b/src/Library/internal-include/GPU/gpu_internal.hpp @@ -30,9 +30,9 @@ namespace JabyEngine { while(!GPU_IO::GPUSTAT.is_set(GPU_IO::GPUSTAT_t::GP0ReadyForCMD)); } - static void set_draw_area(uint16_t x, uint16_t y) { - const auto top_left = GPU_IO::Command::DrawAreaTopLeft(x, y); - const auto bottom_right = GPU_IO::Command::DrawAreaBottomRight((x + Display::Width - 1), (y + Display::Height - 1)); + static void set_draw_area(const PositionU16& pos) { + const auto top_left = GPU_IO::Command::DrawAreaTopLeft(pos); + const auto bottom_right = GPU_IO::Command::DrawAreaBottomRight(pos.move((Display::Width - 1), (Display::Height - 1))); wait_ready_for_CMD(); GPU_IO::GP0 = top_left; @@ -43,21 +43,21 @@ namespace JabyEngine { static void copy_vram_to_vram(const AreaU16& dst, const PositionU16& src) { wait_ready_for_CMD(); GPU_IO::GP0 = GPU_IO::Command::VRAM2VRAM_Blitting(); - GPU_IO::GP0 = GPU_IO::Command::TopLeftPosition(src.x, src.y); - GPU_IO::GP0 = GPU_IO::Command::TopLeftPosition(dst.position.x, dst.position.y); - GPU_IO::GP0 = GPU_IO::Command::WidthHeight(dst.size.width, dst.size.height); + GPU_IO::GP0 = GPU_IO::Command::TopLeftPosition(src); + GPU_IO::GP0 = GPU_IO::Command::TopLeftPosition(dst.position); + GPU_IO::GP0 = GPU_IO::Command::WidthHeight(dst.size); } static void quick_fill_fast(const Color24& color, const AreaU16& area) { wait_ready_for_CMD(); GPU_IO::GP0 = GPU_IO::Command::QuickFill(color); - GPU_IO::GP0 = GPU_IO::Command::TopLeftPosition(area.position.x, area.position.y); - GPU_IO::GP0 = GPU_IO::Command::WidthHeight(area.size.width, area.size.height); + GPU_IO::GP0 = GPU_IO::Command::TopLeftPosition(area.position); + GPU_IO::GP0 = GPU_IO::Command::WidthHeight(area.size); } - static void set_draw_offset(int16_t x, int16_t y) { + static void set_draw_offset(const PositionI16& offset) { wait_ready_for_CMD(); - GPU_IO::GP0 = GPU_IO::Command::SetDrawOffset(x, y); + GPU_IO::GP0 = GPU_IO::Command::SetDrawOffset(offset); } static void reset_cmd_buffer() { @@ -86,8 +86,8 @@ namespace JabyEngine { static void set_dst(const PositionU16& position, const SizeU16& size) { wait_ready_for_CMD(); GPU_IO::GP0 = GPU_IO::Command::CPU2VRAM_Blitting(); - GPU_IO::GP0 = GPU_IO::Command::TopLeftPosition(position.x, position.y); - GPU_IO::GP0 = GPU_IO::Command::WidthHeight(size.width, size.height); + GPU_IO::GP0 = GPU_IO::Command::TopLeftPosition(position); + GPU_IO::GP0 = GPU_IO::Command::WidthHeight(size); } static void start(uint16_t blockCount, uint16_t wordsPerBlock = 0x10) { diff --git a/src/Library/src/GPU/gpu.cpp b/src/Library/src/GPU/gpu.cpp index c8cadcc1..56808ad2 100644 --- a/src/Library/src/GPU/gpu.cpp +++ b/src/Library/src/GPU/gpu.cpp @@ -38,11 +38,11 @@ namespace JabyEngine { } uint32_t Display :: exchange_buffer_and_display() { - const auto draw_area_y = (PublicDisplay::Height*PublicDisplay::current_id); + const uint16_t draw_area_y = (PublicDisplay::Height*PublicDisplay::current_id); - GPU::internal::set_draw_area(0, draw_area_y); + GPU::internal::set_draw_area({0, draw_area_y}); PublicDisplay::current_id ^= 1; - GPU_IO::GP1 = GPU_IO::Command::DisplayArea(0, (PublicDisplay::Height*PublicDisplay::current_id)); + GPU_IO::GP1 = GPU_IO::Command::DisplayArea({0, static_cast((PublicDisplay::Height*PublicDisplay::current_id))}); return draw_area_y; } @@ -85,8 +85,8 @@ namespace JabyEngine { internal::wait_ready_for_CMD(); internal::wait_vsync(syncs); - const auto draw_offset_y = internal::Display::exchange_buffer_and_display(); - internal::set_draw_offset(0, draw_offset_y); + const int16_t draw_offset_y = internal::Display::exchange_buffer_and_display(); + internal::set_draw_offset({0, draw_offset_y}); if(clear_screen) { internal::quick_fill_fast(Color24::Black(), AreaU16{0, static_cast(draw_offset_y), Display::Width, Display::Height}); } From fd9e3523557976bc267c813103f5498b3cc6a67b Mon Sep 17 00:00:00 2001 From: jaby Date: Mon, 5 Jun 2023 22:44:45 +0200 Subject: [PATCH 042/588] Support all primitives --- examples/PoolBox/application/src/main.cpp | 19 +++++-- .../GPU/Primitives/primitive_gpu_commands.hpp | 21 ++++++++ .../Primitives/primitive_rectangle_types.hpp | 50 +++++++++++-------- .../Primitives/primitive_support_types.hpp | 4 -- include/PSX/GPU/gpu_primitives.hpp | 1 + include/PSX/GPU/gpu_types.hpp | 13 +++++ include/PSX/System/IOPorts/gpu_io.hpp | 30 ++++++----- 7 files changed, 92 insertions(+), 46 deletions(-) create mode 100644 include/PSX/GPU/Primitives/primitive_gpu_commands.hpp diff --git a/examples/PoolBox/application/src/main.cpp b/examples/PoolBox/application/src/main.cpp index a788a404..0eedd2b7 100644 --- a/examples/PoolBox/application/src/main.cpp +++ b/examples/PoolBox/application/src/main.cpp @@ -110,10 +110,16 @@ static constexpr const auto line4 = GPU::LINE_G::create( GPU::ColorVertex{GPU::Color24::White(), {0, 0}} ); -static constexpr const auto rect1 = GPU::RECT_FVAR(GPU::Color24::Green(), GPU::AreaI16({GPU::Display::Width - 32, GPU::Display::Height - 32}, {32, 32})); -static constexpr const auto rect2 = GPU::RECT_F16(GPU::Color24::Blue(), {GPU::Display::Width - 16, GPU::Display::Height - 16}); -static constexpr const auto rect3 = GPU::RECT_F8(GPU::Color24::Yellow(), {GPU::Display::Width - 8, GPU::Display::Height - 8}); -static constexpr const auto rect4 = GPU::RECT_F1(GPU::Color24::Red(), {GPU::Display::Width - 1, GPU::Display::Height - 1}); +static constexpr const auto rect1 = GPU::TILE(GPU::AreaI16({GPU::Display::Width - 32, GPU::Display::Height - 32}, {32, 32}), GPU::Color24::Green()); +static constexpr const auto rect2 = GPU::TILE_16({GPU::Display::Width - 16, GPU::Display::Height - 16}, GPU::Color24::Blue()); +static constexpr const auto rect3 = GPU::TILE_8({GPU::Display::Width - 8, GPU::Display::Height - 8}, GPU::Color24::Yellow()); +static constexpr const auto rect4 = GPU::TILE_1({GPU::Display::Width - 1, GPU::Display::Height - 1}, GPU::Color24::Red()); + +static constexpr const auto texpage = GPU::TexPage({320, 0}, GPU::TexturePageColor::$4bit); +static constexpr const auto rect5 = GPU::SPRT(GPU::AreaI16({0, GPU::Display::Height - 32}, {32, 32}), {{0, 0}, TriangleClut}, GPU::Color24::Green()); +static constexpr const auto rect6 = GPU::SPRT_16({0, GPU::Display::Height - 16}, {{0, 0}, TriangleClut}, GPU::Color24::Blue()); +static constexpr const auto rect7 = GPU::SPRT_8({0, GPU::Display::Height - 8}, {{0, 0}, TriangleClut}, GPU::Color24::Yellow()); +static constexpr const auto rect8 = GPU::SPRT_1({0, GPU::Display::Height - 1}, {{0, 0}, TriangleClut}, GPU::Color24::Red()); static void load_assets() { static const CDFile Assets[] = { @@ -163,6 +169,11 @@ void main() { GPU::render(rect2); GPU::render(rect3); GPU::render(rect4); + GPU::render(texpage); + GPU::render(rect5); + GPU::render(rect6); + GPU::render(rect7); + GPU::render(rect8); GPU::render(line1); GPU::render(line2); diff --git a/include/PSX/GPU/Primitives/primitive_gpu_commands.hpp b/include/PSX/GPU/Primitives/primitive_gpu_commands.hpp new file mode 100644 index 00000000..693855a2 --- /dev/null +++ b/include/PSX/GPU/Primitives/primitive_gpu_commands.hpp @@ -0,0 +1,21 @@ +#ifndef __JABYENGINE_PRIMITIVE_GPU_COMMANDS_HPP__ +#define __JABYENGINE_PRIMITIVE_GPU_COMMANDS_HPP__ +#include "../../System/IOPorts/gpu_io.hpp" +#include "primitive_support_types.hpp" + +namespace JabyEngine { + namespace GPU { + struct TexPage { + GPU_IO::GP0_t value; + + constexpr TexPage(const PositionU16& tex_pos, TexturePageColor tex_color, SemiTransparency transparency = SemiTransparency::B_Half_add_F_Half, bool dither = false) : value{ + GPU_IO::Command::TexPage(tex_pos, transparency, tex_color, dither, false)} {} + }; + + namespace internal { + __jaby_engine_declare_render_primitive(TexPage); + } + } +} + +#endif // !__JABYENGINE_PRIMITIVE_GPU_COMMANDS_HPP__ \ No newline at end of file diff --git a/include/PSX/GPU/Primitives/primitive_rectangle_types.hpp b/include/PSX/GPU/Primitives/primitive_rectangle_types.hpp index b45cdfe5..6e43b9a5 100644 --- a/include/PSX/GPU/Primitives/primitive_rectangle_types.hpp +++ b/include/PSX/GPU/Primitives/primitive_rectangle_types.hpp @@ -4,6 +4,11 @@ namespace JabyEngine { namespace GPU { + struct PagePositionClut { + PagePosition page; + PageClut clut; + }; + namespace internal { struct RectCode : public CodeBase { enum struct Size : uint8_t { @@ -37,7 +42,7 @@ namespace JabyEngine { Vertex position; constexpr RECT_F() = default; - constexpr RECT_F(const Color24& color, const Vertex& position) : color(color), code(IdentityCode), position(position) { + constexpr RECT_F(const Vertex& position, const Color24& color) : color(color), code(IdentityCode), position(position) { } }; @@ -50,45 +55,46 @@ namespace JabyEngine { Code code; Vertex position; PagePosition page; + PageClut clut; constexpr RECT_T() = default; - constexpr RECT_T(const Color24& color, const Vertex& position, const PagePosition& page) : color(color), code(IdentityCode), position(position), page(page) { + constexpr RECT_T(const Vertex& position, const PagePositionClut& page, const Color24& color = Color24::Grey()) : color(color), code(IdentityCode), position(position), page(page.page), clut(page.clut) { } }; } - typedef internal::RECT_F RECT_F1; - typedef internal::RECT_F RECT_F8; - typedef internal::RECT_F RECT_F16; - struct RECT_FVAR : public internal::RECT_F { + typedef internal::RECT_F TILE_1; + typedef internal::RECT_F TILE_8; + typedef internal::RECT_F TILE_16; + struct TILE : public internal::RECT_F { Vertex position_bottom_right; - constexpr RECT_FVAR() = default; - constexpr RECT_FVAR(const Color24& color, const AreaI16& area) : RECT_F(color, area.position), position_bottom_right(area.get_bottom_left()) { + constexpr TILE() = default; + constexpr TILE(const AreaI16& area, const Color24& color) : RECT_F(area.position, color), position_bottom_right(area.get_bottom_left()) { } }; - typedef internal::RECT_T RECT_T1; - typedef internal::RECT_T RECT_T8; - typedef internal::RECT_T RECT_T16; - struct RECT_TVAR : public internal::RECT_T { + typedef internal::RECT_T SPRT_1; + typedef internal::RECT_T SPRT_8; + typedef internal::RECT_T SPRT_16; + struct SPRT : public internal::RECT_T { Vertex position_bottom_right; - constexpr RECT_TVAR() = default; - constexpr RECT_TVAR(const Color24& color, const AreaI16& area, const PagePosition& page) : RECT_T(color, area.position, page), position_bottom_right(area.get_bottom_left()) { + constexpr SPRT() = default; + constexpr SPRT(const AreaI16& area, const PagePositionClut& page, const Color24& color = Color24::Grey()) : RECT_T(area.position, page, color), position_bottom_right(area.get_bottom_left()) { } }; namespace internal { - __jaby_engine_declare_render_primitive(RECT_F1); - __jaby_engine_declare_render_primitive(RECT_F8); - __jaby_engine_declare_render_primitive(RECT_F16); - __jaby_engine_declare_render_primitive(RECT_FVAR); + __jaby_engine_declare_render_primitive(TILE_1); + __jaby_engine_declare_render_primitive(TILE_8); + __jaby_engine_declare_render_primitive(TILE_16); + __jaby_engine_declare_render_primitive(TILE); - __jaby_engine_declare_render_primitive(RECT_T1); - __jaby_engine_declare_render_primitive(RECT_T8); - __jaby_engine_declare_render_primitive(RECT_T16); - __jaby_engine_declare_render_primitive(RECT_TVAR); + __jaby_engine_declare_render_primitive(SPRT_1); + __jaby_engine_declare_render_primitive(SPRT_8); + __jaby_engine_declare_render_primitive(SPRT_16); + __jaby_engine_declare_render_primitive(SPRT); } } } diff --git a/include/PSX/GPU/Primitives/primitive_support_types.hpp b/include/PSX/GPU/Primitives/primitive_support_types.hpp index d8ba0ade..315c4fe5 100644 --- a/include/PSX/GPU/Primitives/primitive_support_types.hpp +++ b/include/PSX/GPU/Primitives/primitive_support_types.hpp @@ -71,10 +71,6 @@ namespace JabyEngine { } } - // Reexport for easier use - typedef JabyEngine::GPU_IO::SemiTransparency SemiTransparency; - typedef JabyEngine::GPU_IO::TexturePageColor TexturePageColor; - struct PageClut { uint16_t value = 0; diff --git a/include/PSX/GPU/gpu_primitives.hpp b/include/PSX/GPU/gpu_primitives.hpp index f0415ef5..2cbf3ff2 100644 --- a/include/PSX/GPU/gpu_primitives.hpp +++ b/include/PSX/GPU/gpu_primitives.hpp @@ -1,5 +1,6 @@ #ifndef __JABYENGINE_GPU_PRIMITIVES_HPP__ #define __JABYENGINE_GPU_PRIMITIVES_HPP__ +#include "Primitives/primitive_gpu_commands.hpp" #include "Primitives/primitive_line_types.hpp" #include "Primitives/primitive_rectangle_types.hpp" #include "Primitives/primitive_poly_types.hpp" diff --git a/include/PSX/GPU/gpu_types.hpp b/include/PSX/GPU/gpu_types.hpp index d09387a8..68e320e0 100644 --- a/include/PSX/GPU/gpu_types.hpp +++ b/include/PSX/GPU/gpu_types.hpp @@ -32,6 +32,19 @@ namespace JabyEngine { }; } + enum struct SemiTransparency { + B_Half_add_F_Half = 0, + B_add_F = 1, + B_sub_F = 2, + B_add_F_Quarter = 3, + }; + + enum struct TexturePageColor { + $4bit = 0, + $8bit = 1, + $15bit = 2, + }; + struct Color24 { uint8_t red = 0; uint8_t green = 0; diff --git a/include/PSX/System/IOPorts/gpu_io.hpp b/include/PSX/System/IOPorts/gpu_io.hpp index 1213ba90..c916fafa 100644 --- a/include/PSX/System/IOPorts/gpu_io.hpp +++ b/include/PSX/System/IOPorts/gpu_io.hpp @@ -6,24 +6,11 @@ namespace JabyEngine { namespace GPU_IO { - enum struct SemiTransparency { - B_Half_add_F_Half = 0, - B_add_F = 1, - B_sub_F = 2, - B_add_F_Quarter = 3, - }; - enum struct DisplayAreaColorDepth { $15bit = 0, $24bit = 1, }; - enum struct TexturePageColor { - $4bit = 0, - $8bit = 1, - $15bit = 2, - }; - enum struct HorizontalResolution { $256 = 0, $320 = 1, @@ -114,9 +101,20 @@ namespace JabyEngine { return {(0b101u << 29)}; } - /*static constexpr GP0_t DrawMode(const GPU::PositionU16& page_pos, SemiTransparency transparency, TexturePageColor tex_color, bool dither) { + static constexpr GP0_t TexPage(const GPU::PositionU16& page_pos, GPU::SemiTransparency transparency, GPU::TexturePageColor tex_color, bool dither, bool draw_on_display_area) { + constexpr auto TexXRange = BitRange::from_to(0, 3); + constexpr auto TexYRange = BitRange::from_to(4, 4); + constexpr auto TransparencyRange = BitRange::from_to(5, 6); + constexpr auto TextureColorRange = BitRange::from_to(7, 8); + constexpr auto DitherBit = BitRange::from_to(9, 9); + constexpr auto DrawOnDisplayAreaBit = BitRange::from_to(10, 10); - }*/ + return {Helper::construct_cmd(0xE1, + TexXRange.as_value(page_pos.x >> 6) | TexYRange.as_value(page_pos.y >> 7) | + TransparencyRange.as_value(static_cast(transparency)) | TextureColorRange.as_value(static_cast(tex_color)) | + DitherBit.as_value(static_cast(dither)) | DrawOnDisplayAreaBit.as_value(static_cast(draw_on_display_area)) + )}; + } static constexpr GP0_t DrawAreaTopLeft(const GPU::PositionU16& position) { return Helper::DrawAreaTemplate(0xE3, position.x, position.y); @@ -126,7 +124,7 @@ namespace JabyEngine { return Helper::DrawAreaTemplate(0xE4, position.x, position.y); } - static GP0_t SetDrawOffset(const GPU::PositionI16& offset) { + static constexpr GP0_t SetDrawOffset(const GPU::PositionI16& offset) { constexpr auto X = BitRange::from_to(0, 10); constexpr auto Y = BitRange::from_to(11, 21); From 04fa09e7e74360e57337ce8b91ba63e142dff630 Mon Sep 17 00:00:00 2001 From: jaby Date: Mon, 12 Jun 2023 21:47:56 +0200 Subject: [PATCH 043/588] Support basic linked elements --- examples/PoolBox/application/src/main.cpp | 4 ++ .../PSX/GPU/Primitives/linked_elements.hpp | 56 +++++++++++++++++++ .../Primitives/primitive_rectangle_types.hpp | 11 ++-- .../Primitives/primitive_support_types.hpp | 7 --- include/PSX/GPU/gpu.hpp | 6 ++ include/PSX/GPU/gpu_types.hpp | 12 ++++ include/PSX/System/IOPorts/dma_io.hpp | 4 ++ src/Library/src/GPU/gpu.cpp | 9 +++ 8 files changed, 97 insertions(+), 12 deletions(-) create mode 100644 include/PSX/GPU/Primitives/linked_elements.hpp diff --git a/examples/PoolBox/application/src/main.cpp b/examples/PoolBox/application/src/main.cpp index 0eedd2b7..40f3bd06 100644 --- a/examples/PoolBox/application/src/main.cpp +++ b/examples/PoolBox/application/src/main.cpp @@ -121,6 +121,8 @@ static constexpr const auto rect6 = GPU::SPRT_16({0, GPU::Display::Height - 16 static constexpr const auto rect7 = GPU::SPRT_8({0, GPU::Display::Height - 8}, {{0, 0}, TriangleClut}, GPU::Color24::Yellow()); static constexpr const auto rect8 = GPU::SPRT_1({0, GPU::Display::Height - 1}, {{0, 0}, TriangleClut}, GPU::Color24::Red()); +static constexpr const auto rect9 = GPU::SPRT(GPU::AreaI16({GPU::Display::Width/2, GPU::Display::Height/2}, {32, 32}).centered(), {{0, 0}, TriangleClut}, GPU::Color24::Grey()).linked(); + static void load_assets() { static const CDFile Assets[] = { CDFileBuilder::simple_tim(LBA::FONT, SimpleTIM(320, 0, 320, 511)), @@ -180,6 +182,8 @@ void main() { GPU::render(line3); GPU::render(line4); + GPU::render(rect9); + GPU::swap_buffers_vsync(2); } } diff --git a/include/PSX/GPU/Primitives/linked_elements.hpp b/include/PSX/GPU/Primitives/linked_elements.hpp new file mode 100644 index 00000000..bc5f513a --- /dev/null +++ b/include/PSX/GPU/Primitives/linked_elements.hpp @@ -0,0 +1,56 @@ +#ifndef __JABYENGINE_LINKED_ELEMENTS_HPP__ +#define __JABYENGINE_LINKED_ELEMENTS_HPP__ +#include "../../Auxiliary/bits.hpp" + +namespace JabyEngine { + namespace GPU { + struct Link { + static constexpr auto AdrRange = BitRange::from_to(0, 23); + static constexpr auto SizeRange = BitRange::from_to(24, 31); + + static constexpr uint32_t TerminationValue = 0x00FFFFFF; + + uint32_t value = TerminationValue; + + constexpr Link() = default; + constexpr Link(size_t size) : value(SizeRange.as_value(size >> 2) | TerminationValue) { + } + + //void add + + constexpr void terminate() { + this->value |= TerminationValue; + } + }; + + template + struct LinkedElement : public Link { + T element; + + constexpr LinkedElement() : Link(sizeof(T)), element() { + } + + constexpr LinkedElement(const T& element) : Link(sizeof(T)), element(element) { + } + + constexpr const T* operator->() const { + return &this->element; + } + + constexpr T* operator->() { + return &this->element; + } + }; + + namespace internal { + template + struct LinkedElementCreator { + constexpr LinkedElement linked() { + return LinkedElement(*static_cast(this)); + } + }; + } + } +} + +#endif // !__JABYENGINE_LINKED_ELEMENTS_HPP__ \ No newline at end of file diff --git a/include/PSX/GPU/Primitives/primitive_rectangle_types.hpp b/include/PSX/GPU/Primitives/primitive_rectangle_types.hpp index 6e43b9a5..775702b6 100644 --- a/include/PSX/GPU/Primitives/primitive_rectangle_types.hpp +++ b/include/PSX/GPU/Primitives/primitive_rectangle_types.hpp @@ -1,5 +1,6 @@ #ifndef __JABYENGINE_PRIMITIVE_RECTANGLE_TYPES_HPP__ #define __JABYENGINE_PRIMITIVE_RECTANGLE_TYPES_HPP__ +#include "linked_elements.hpp" #include "primitive_support_types.hpp" namespace JabyEngine { @@ -67,21 +68,21 @@ namespace JabyEngine { typedef internal::RECT_F TILE_8; typedef internal::RECT_F TILE_16; struct TILE : public internal::RECT_F { - Vertex position_bottom_right; + SizeI16 size; constexpr TILE() = default; - constexpr TILE(const AreaI16& area, const Color24& color) : RECT_F(area.position, color), position_bottom_right(area.get_bottom_left()) { + constexpr TILE(const AreaI16& area, const Color24& color) : RECT_F(area.position, color), size(area.size) { } }; typedef internal::RECT_T SPRT_1; typedef internal::RECT_T SPRT_8; typedef internal::RECT_T SPRT_16; - struct SPRT : public internal::RECT_T { - Vertex position_bottom_right; + struct SPRT : public internal::RECT_T, public internal::LinkedElementCreator { + SizeI16 size; constexpr SPRT() = default; - constexpr SPRT(const AreaI16& area, const PagePositionClut& page, const Color24& color = Color24::Grey()) : RECT_T(area.position, page, color), position_bottom_right(area.get_bottom_left()) { + constexpr SPRT(const AreaI16& area, const PagePositionClut& page, const Color24& color = Color24::Grey()) : RECT_T(area.position, page, color), size(area.size) { } }; diff --git a/include/PSX/GPU/Primitives/primitive_support_types.hpp b/include/PSX/GPU/Primitives/primitive_support_types.hpp index 315c4fe5..da3f3ae7 100644 --- a/include/PSX/GPU/Primitives/primitive_support_types.hpp +++ b/include/PSX/GPU/Primitives/primitive_support_types.hpp @@ -52,13 +52,6 @@ namespace JabyEngine { } }; - // Concept for now - template - struct Hooked { - uint32_t hook; - T primitive; - }; - template struct is_render_primitive { static constexpr bool value = false; diff --git a/include/PSX/GPU/gpu.hpp b/include/PSX/GPU/gpu.hpp index 782c8a58..62cf6f15 100644 --- a/include/PSX/GPU/gpu.hpp +++ b/include/PSX/GPU/gpu.hpp @@ -38,6 +38,12 @@ namespace JabyEngine { namespace internal { void render(const uint32_t* data, size_t words); + void render_dma(const uint32_t* data); + } + + template + static void render(const LinkedElement& linked_primitives) { + internal::render_dma(&linked_primitives.value); } template diff --git a/include/PSX/GPU/gpu_types.hpp b/include/PSX/GPU/gpu_types.hpp index 68e320e0..0ef84a80 100644 --- a/include/PSX/GPU/gpu_types.hpp +++ b/include/PSX/GPU/gpu_types.hpp @@ -15,6 +15,10 @@ namespace JabyEngine { return *static_cast(this); } + constexpr T add(S dx, S dy) const { + return T(static_cast(this)->x, static_cast(this)->y).add(dx, dy); + } + constexpr T& sub(S dx, S dy) { static_cast(this)->x -= dx; static_cast(this)->y -= dy; @@ -22,6 +26,10 @@ namespace JabyEngine { return *static_cast(this); } + constexpr T sub(S dx, S dy) const { + return T(static_cast(this)->x, static_cast(this)->y).sub(dx, dy); + } + constexpr T& move(S dx, S dy) { return this->add(dx, dy); } @@ -156,6 +164,10 @@ namespace JabyEngine { constexpr Area(T position_x, T position_y, T size_width, T size_height) : position{position_x, position_y}, size{size_width, size_height} { } + constexpr Area centered() const { + return Area(this->position.sub(this->size.width/2, this->size.height/2), this->size); + } + constexpr Position get_bottom_left() const { return this->position.move(this->size.width, this->size.height); } diff --git a/include/PSX/System/IOPorts/dma_io.hpp b/include/PSX/System/IOPorts/dma_io.hpp index 7f7a1e69..9092e8a3 100644 --- a/include/PSX/System/IOPorts/dma_io.hpp +++ b/include/PSX/System/IOPorts/dma_io.hpp @@ -68,6 +68,10 @@ namespace JabyEngine { return Self{0x01000201}; } + static constexpr Self StartGPULinked() { + return Self{0x01000401}; + } + static constexpr Self StartCDROM() { return Self{0x11000000}; } diff --git a/src/Library/src/GPU/gpu.cpp b/src/Library/src/GPU/gpu.cpp index 56808ad2..fd2f7578 100644 --- a/src/Library/src/GPU/gpu.cpp +++ b/src/Library/src/GPU/gpu.cpp @@ -63,6 +63,15 @@ namespace JabyEngine { GPU_IO::GP0 = data[n]; } } + + void render_dma(const uint32_t* data) { + wait_ready_for_CMD(); + // DPCR already enabled + GPU_IO::GP1 = GPU_IO::Command::DMADirection(GPU_IO::DMADirection::CPU2GPU); + DMA_IO::GPU.set_adr(reinterpret_cast(data)); + DMA_IO::GPU.block_ctrl = 0; + DMA_IO::GPU.channel_ctrl = DMA_IO::CHCHR_t::StartGPULinked(); + } } #ifndef USE_NO$PSX From 50a2fc312866fcb2340d80a0cad2bc779f291238 Mon Sep 17 00:00:00 2001 From: jaby Date: Tue, 13 Jun 2023 21:21:02 +0200 Subject: [PATCH 044/588] Support linking primitives --- examples/PoolBox/application/src/main.cpp | 5 ++- .../PSX/GPU/Primitives/linked_elements.hpp | 25 ++++++++++++- .../GPU/Primitives/primitive_gpu_commands.hpp | 3 +- .../GPU/Primitives/primitive_line_types.hpp | 5 +-- .../GPU/Primitives/primitive_poly_types.hpp | 17 ++++----- .../Primitives/primitive_rectangle_types.hpp | 36 ++++++++++++------- 6 files changed, 65 insertions(+), 26 deletions(-) diff --git a/examples/PoolBox/application/src/main.cpp b/examples/PoolBox/application/src/main.cpp index 40f3bd06..ca776915 100644 --- a/examples/PoolBox/application/src/main.cpp +++ b/examples/PoolBox/application/src/main.cpp @@ -121,7 +121,8 @@ static constexpr const auto rect6 = GPU::SPRT_16({0, GPU::Display::Height - 16 static constexpr const auto rect7 = GPU::SPRT_8({0, GPU::Display::Height - 8}, {{0, 0}, TriangleClut}, GPU::Color24::Yellow()); static constexpr const auto rect8 = GPU::SPRT_1({0, GPU::Display::Height - 1}, {{0, 0}, TriangleClut}, GPU::Color24::Red()); -static constexpr const auto rect9 = GPU::SPRT(GPU::AreaI16({GPU::Display::Width/2, GPU::Display::Height/2}, {32, 32}).centered(), {{0, 0}, TriangleClut}, GPU::Color24::Grey()).linked(); +static auto rect9 = GPU::SPRT(GPU::AreaI16({GPU::Display::Width/2, GPU::Display::Height/2}, {32, 32}).centered(), {{0, 0}, TriangleClut}, GPU::Color24::Grey()).linked(); +static auto rect10 = GPU::SPRT(GPU::AreaI16({GPU::Display::Width/2, GPU::Display::Height/2 - 32}, {32, 32}).centered(), {{0, 0}, TriangleClut}, GPU::Color24::Grey()).linked(); static void load_assets() { static const CDFile Assets[] = { @@ -155,6 +156,8 @@ static void load_assets() { void main() { load_assets(); + rect9.concat(rect10); + while(true) { GPU::render(triangle1); GPU::render(triangle2); diff --git a/include/PSX/GPU/Primitives/linked_elements.hpp b/include/PSX/GPU/Primitives/linked_elements.hpp index bc5f513a..5a1b2c13 100644 --- a/include/PSX/GPU/Primitives/linked_elements.hpp +++ b/include/PSX/GPU/Primitives/linked_elements.hpp @@ -16,7 +16,28 @@ namespace JabyEngine { constexpr Link(size_t size) : value(SizeRange.as_value(size >> 2) | TerminationValue) { } - //void add + void set_adr(const void* adr) { + this->value = bit::value::set_normalized(this->value, AdrRange.with(reinterpret_cast(adr))); + } + + void* get_adr() const { + return reinterpret_cast(bit::value::get_normalized(this->value, AdrRange)); + } + + template + T& insert_after(T& obj) { + const auto adr = Link::get_adr(); + + Link::set_adr(&obj); + obj.set_adr(adr); + return obj; + } + + template + const T& concat(const T& obj) { + Link::set_adr(&obj); + return obj; + } constexpr void terminate() { this->value |= TerminationValue; @@ -45,6 +66,8 @@ namespace JabyEngine { namespace internal { template struct LinkedElementCreator { + typedef LinkedElement Linked; + constexpr LinkedElement linked() { return LinkedElement(*static_cast(this)); } diff --git a/include/PSX/GPU/Primitives/primitive_gpu_commands.hpp b/include/PSX/GPU/Primitives/primitive_gpu_commands.hpp index 693855a2..275d6cc9 100644 --- a/include/PSX/GPU/Primitives/primitive_gpu_commands.hpp +++ b/include/PSX/GPU/Primitives/primitive_gpu_commands.hpp @@ -1,11 +1,12 @@ #ifndef __JABYENGINE_PRIMITIVE_GPU_COMMANDS_HPP__ #define __JABYENGINE_PRIMITIVE_GPU_COMMANDS_HPP__ #include "../../System/IOPorts/gpu_io.hpp" +#include "linked_elements.hpp" #include "primitive_support_types.hpp" namespace JabyEngine { namespace GPU { - struct TexPage { + struct TexPage : public internal::LinkedElementCreator { GPU_IO::GP0_t value; constexpr TexPage(const PositionU16& tex_pos, TexturePageColor tex_color, SemiTransparency transparency = SemiTransparency::B_Half_add_F_Half, bool dither = false) : value{ diff --git a/include/PSX/GPU/Primitives/primitive_line_types.hpp b/include/PSX/GPU/Primitives/primitive_line_types.hpp index 5cb254e3..2a8ce37c 100644 --- a/include/PSX/GPU/Primitives/primitive_line_types.hpp +++ b/include/PSX/GPU/Primitives/primitive_line_types.hpp @@ -1,5 +1,6 @@ #ifndef __JABYENGINE_PRIMITIVE_LINE_TYPES_HPP__ #define __JABYENGINE_PRIMITIVE_LINE_TYPES_HPP__ +#include "linked_elements.hpp" #include "primitive_support_types.hpp" namespace JabyEngine { @@ -53,14 +54,14 @@ namespace JabyEngine { }; template - struct SingleLine : public LineCodeInterface> { + struct SingleLine : public LineCodeInterface>, public internal::LinkedElementCreator> { LineHead head; Vertex start_point; Body end_point; }; template - struct MultiLine : public LineCodeInterface> { + struct MultiLine : public LineCodeInterface>, public internal::LinkedElementCreator> { LineHead head; Vertex start_point; Body points[N]; diff --git a/include/PSX/GPU/Primitives/primitive_poly_types.hpp b/include/PSX/GPU/Primitives/primitive_poly_types.hpp index 65520a77..efbc5a06 100644 --- a/include/PSX/GPU/Primitives/primitive_poly_types.hpp +++ b/include/PSX/GPU/Primitives/primitive_poly_types.hpp @@ -1,5 +1,6 @@ #ifndef __JABYENGINE_PRIMITIVE_POLY_TYPES_HPP__ #define __JABYENGINE_PRIMITIVE_POLY_TYPES_HPP__ +#include "linked_elements.hpp" #include "primitive_support_types.hpp" namespace JabyEngine { @@ -35,7 +36,7 @@ namespace JabyEngine { / \ 3 - 2 */ - struct POLY_F3 : public internal::PolyCodeInterface { + struct POLY_F3 : public internal::PolyCodeInterface, public internal::LinkedElementCreator { static constexpr auto IdentityCode = Code().set(Code::FlatShading).set(Code::TriVertics).set(Code::Untextured).set(Code::NonTransparent); Color24 color; // a @@ -53,7 +54,7 @@ namespace JabyEngine { } }; - struct POLY_FT3 : public internal::PolyCodeInterface { + struct POLY_FT3 : public internal::PolyCodeInterface, public internal::LinkedElementCreator { struct VertexEx { Vertex position; PagePosition page; @@ -84,7 +85,7 @@ namespace JabyEngine { vertex2(vertices_ex[2].position), page2(vertices_ex[2].page), padded2(0) {} }; - struct POLY_G3 : public internal::PolyCodeInterface { + struct POLY_G3 : public internal::PolyCodeInterface, public internal::LinkedElementCreator { static constexpr auto IdentityCode = Code(POLY_F3::IdentityCode).set(Code::GouraudShading); Color24 color0; // a @@ -108,7 +109,7 @@ namespace JabyEngine { color2(verticies_ex[2].color), pad2(0), vertex2(verticies_ex[2].position) {} }; - struct POLY_GT3 : public internal::PolyCodeInterface { + struct POLY_GT3 : public internal::PolyCodeInterface, public internal::LinkedElementCreator { struct VertexEx { Vertex position; PagePosition page; @@ -148,7 +149,7 @@ namespace JabyEngine { | | 3 - 4 */ - struct POLY_F4 : public internal::PolyCodeInterface { + struct POLY_F4 : public internal::PolyCodeInterface, public internal::LinkedElementCreator { static constexpr auto IdentityCode = Code(POLY_F3::IdentityCode).set(Code::QuadVertics); Color24 color; // a @@ -173,7 +174,7 @@ namespace JabyEngine { color) {} }; - struct POLY_FT4 : public internal::PolyCodeInterface { + struct POLY_FT4 : public internal::PolyCodeInterface, public internal::LinkedElementCreator { typedef POLY_FT3::VertexEx VertexEx; static constexpr auto IdentityCode = Code(POLY_FT3::IdentityCode).set(Code::QuadVertics); @@ -213,7 +214,7 @@ namespace JabyEngine { ) {} }; - struct POLY_G4 : public internal::PolyCodeInterface { + struct POLY_G4 : public internal::PolyCodeInterface, public internal::LinkedElementCreator { static constexpr auto IdentityCode = Code(POLY_G3::IdentityCode).set(Code::QuadVertics); Color24 color0; // a @@ -249,7 +250,7 @@ namespace JabyEngine { ) {} }; - struct POLY_GT4 : public internal::PolyCodeInterface { + struct POLY_GT4 : public internal::PolyCodeInterface, public internal::LinkedElementCreator { typedef POLY_GT3::VertexEx VertexEx; static constexpr auto IdentityCode = Code(POLY_GT3::IdentityCode).set(Code::QuadVertics); diff --git a/include/PSX/GPU/Primitives/primitive_rectangle_types.hpp b/include/PSX/GPU/Primitives/primitive_rectangle_types.hpp index 775702b6..247ab38e 100644 --- a/include/PSX/GPU/Primitives/primitive_rectangle_types.hpp +++ b/include/PSX/GPU/Primitives/primitive_rectangle_types.hpp @@ -34,23 +34,23 @@ namespace JabyEngine { }; template - struct RECT_F : public RectCodeInterface> { - typedef RECT_F::Code Code; + struct RECT_BASE_F : public RectCodeInterface> { + typedef RECT_BASE_F::Code Code; static constexpr auto IdentityCode = Code().set(Code::Size.with(static_cast(Size))).set(Code::Untextured).set(Code::NonTransparent); Color24 color; Code code; Vertex position; - constexpr RECT_F() = default; - constexpr RECT_F(const Vertex& position, const Color24& color) : color(color), code(IdentityCode), position(position) { + constexpr RECT_BASE_F() = default; + constexpr RECT_BASE_F(const Vertex& position, const Color24& color) : color(color), code(IdentityCode), position(position) { } }; template - struct RECT_T : public RectCodeInterface> { - typedef RECT_T::Code Code; - static constexpr auto IdentityCode = Code(RECT_F::IdentityCode).set(Code::Textured); + struct RECT_BASE_T : public RectCodeInterface> { + typedef RECT_BASE_T::Code Code; + static constexpr auto IdentityCode = Code(RECT_BASE_F::IdentityCode).set(Code::Textured); Color24 color; Code code; @@ -58,31 +58,41 @@ namespace JabyEngine { PagePosition page; PageClut clut; - constexpr RECT_T() = default; - constexpr RECT_T(const Vertex& position, const PagePositionClut& page, const Color24& color = Color24::Grey()) : color(color), code(IdentityCode), position(position), page(page.page), clut(page.clut) { + constexpr RECT_BASE_T() = default; + constexpr RECT_BASE_T(const Vertex& position, const PagePositionClut& page, const Color24& color = Color24::Grey()) : color(color), code(IdentityCode), position(position), page(page.page), clut(page.clut) { } }; + + template + struct RECT_F : public RECT_BASE_F, public internal::LinkedElementCreator> { + using RECT_BASE_F::RECT_BASE_F; + }; + + template + struct RECT_T : public RECT_BASE_T, public internal::LinkedElementCreator> { + using RECT_BASE_T::RECT_BASE_T; + }; } typedef internal::RECT_F TILE_1; typedef internal::RECT_F TILE_8; typedef internal::RECT_F TILE_16; - struct TILE : public internal::RECT_F { + struct TILE : public internal::RECT_BASE_F, public internal::LinkedElementCreator { SizeI16 size; constexpr TILE() = default; - constexpr TILE(const AreaI16& area, const Color24& color) : RECT_F(area.position, color), size(area.size) { + constexpr TILE(const AreaI16& area, const Color24& color) : RECT_BASE_F(area.position, color), size(area.size) { } }; typedef internal::RECT_T SPRT_1; typedef internal::RECT_T SPRT_8; typedef internal::RECT_T SPRT_16; - struct SPRT : public internal::RECT_T, public internal::LinkedElementCreator { + struct SPRT : public internal::RECT_BASE_T, public internal::LinkedElementCreator { SizeI16 size; constexpr SPRT() = default; - constexpr SPRT(const AreaI16& area, const PagePositionClut& page, const Color24& color = Color24::Grey()) : RECT_T(area.position, page, color), size(area.size) { + constexpr SPRT(const AreaI16& area, const PagePositionClut& page, const Color24& color = Color24::Grey()) : RECT_BASE_T(area.position, page, color), size(area.size) { } }; From 4b02b9a7d27a1bff662cbbfbc6df836da19152aa Mon Sep 17 00:00:00 2001 From: jaby Date: Wed, 14 Jun 2023 21:39:48 +0200 Subject: [PATCH 045/588] Move GPU tests into an Overlay --- examples/PoolBox/application/Makefile | 2 +- examples/PoolBox/application/Overlays.json | 3 + .../application/src/GPUTests/gpu_tests.cpp | 193 ++++++++++++++++++ examples/PoolBox/application/src/main.cpp | 192 +---------------- examples/PoolBox/iso/Config.xml | 2 +- 5 files changed, 200 insertions(+), 192 deletions(-) create mode 100644 examples/PoolBox/application/src/GPUTests/gpu_tests.cpp diff --git a/examples/PoolBox/application/Makefile b/examples/PoolBox/application/Makefile index 71f4711e..efce152f 100644 --- a/examples/PoolBox/application/Makefile +++ b/examples/PoolBox/application/Makefile @@ -7,7 +7,7 @@ include $(JABY_ENGINE_DIR)/lib/Wildcard.mk SRCS = $(call rwildcard, src, c cpp) INCLUDES += -I$(JABY_ENGINE_DIR)/include -CCFLAGS += -save-temps=obj +#CCFLAGS += -save-temps=obj include $(JABY_ENGINE_DIR)/lib/Makefile include $(JABY_ENGINE_DIR)/lib/PSEXETarget.mk diff --git a/examples/PoolBox/application/Overlays.json b/examples/PoolBox/application/Overlays.json index 0e5d7be0..9a450a0e 100644 --- a/examples/PoolBox/application/Overlays.json +++ b/examples/PoolBox/application/Overlays.json @@ -2,6 +2,9 @@ "slot_0": { "timer_tests": { "pattern": "bin/*/src/TimerTests/*.o" + }, + "gpu_tests": { + "pattern": "bin/*/src/GPUTests/*.o" } } } \ No newline at end of file diff --git a/examples/PoolBox/application/src/GPUTests/gpu_tests.cpp b/examples/PoolBox/application/src/GPUTests/gpu_tests.cpp new file mode 100644 index 00000000..0d4966b3 --- /dev/null +++ b/examples/PoolBox/application/src/GPUTests/gpu_tests.cpp @@ -0,0 +1,193 @@ +#include +#include +#include +#include +#include + +enum LBA { + __jabyengine_start_lba_request + __jabyengine_request_lba_for(FONT, "ASSETS/FONT.BIN"), + __jabyengine_request_lba_for(ICON, "ASSETS/ICON.BIN"), + __jabyengine_end_lba_request +}; + +using namespace JabyEngine; + +// Some default values for the objects +static constexpr auto TriangleColor = GPU::Color24(0x0, 0xFF, 0xFF); +static constexpr auto TriangleArea = GPU::AreaI16({0, 0}, {64, 64}); +static constexpr auto TriangleTPage = GPU::TPage(320, 0, GPU::SemiTransparency::B_Half_add_F_Half, GPU::TexturePageColor::$4bit); +static constexpr auto TriangleClut = GPU::PageClut(320, 511); + +static constexpr auto RectangleColor = GPU::Color24(0x80, 0x80, 0xFF); +static constexpr auto RectangleArea = GPU::AreaI16({0, TriangleArea.size.height}, {80, 80}); +static constexpr auto RectangleTPage = GPU::TPage(320, 256, GPU::SemiTransparency::B_Half_add_F_Half, GPU::TexturePageColor::$4bit); +static constexpr auto RectangleClut = GPU::PageClut(320, 510); + +static constexpr auto LineColor = GPU::Color24(0xFF, 0x0, 0x0); + +static constexpr const auto triangle1 = GPU::POLY_F3({ + {TriangleArea.position.x, TriangleArea.position.y}, + {TriangleArea.size.width, TriangleArea.size.height}, + {TriangleArea.position.x, TriangleArea.size.height}}, + TriangleColor +); +static constexpr const auto triangle2 = GPU::POLY_FT3({ + {TriangleArea.position.x, TriangleArea.position.y}, + {TriangleArea.size.width, TriangleArea.position.y}, + {TriangleArea.size.width, TriangleArea.size.height}},{ + // Texture + {TriangleArea.position.x, TriangleArea.position.y}, + {TriangleArea.size.width, TriangleArea.position.y}, + {TriangleArea.size.width, TriangleArea.size.height}}, + TriangleTPage, + TriangleClut, + GPU::Color24::Grey() +); +static constexpr const auto triangle3 = GPU::POLY_G3({ + {triangle1.vertex0.move(TriangleArea.size.width, 0), GPU::Color24::Red()}, + {triangle1.vertex1.move(TriangleArea.size.width, 0), GPU::Color24::Green()}, + {triangle1.vertex2.move(TriangleArea.size.width, 0), GPU::Color24::Blue()}} +); +static constexpr const auto triangle4 = GPU::POLY_GT3({ + {triangle2.vertex0.move(TriangleArea.size.width, 0), triangle2.page0, GPU::Color24::Red()}, + {triangle2.vertex1.move(TriangleArea.size.width, 0), triangle2.page1, GPU::Color24::Blue()}, + {triangle2.vertex2.move(TriangleArea.size.width, 0), triangle2.page2, GPU::Color24::Green()}}, + TriangleTPage, + TriangleClut +); + +static constexpr const auto rectangle1 = GPU::POLY_F4(RectangleArea, RectangleColor); +static constexpr const auto rectangle2 = GPU::POLY_FT4({ + RectangleArea.position.move(RectangleArea.size.width, 0), RectangleArea.size}, {0, 0}, + RectangleTPage, + RectangleClut, + GPU::Color24::Grey() +); +static constexpr const auto rectangle3 = GPU::POLY_G4( + {RectangleArea.position.move(RectangleArea.size.width*2, 0), RectangleArea.size}, { + GPU::Color24::Red(), + GPU::Color24::Blue(), + GPU::Color24::Green(), + GPU::Color24::White()}); +static constexpr const auto rectangle4 = GPU::POLY_GT4( + {RectangleArea.position.move(RectangleArea.size.width*3, 0), RectangleArea.size}, {0, 0}, + RectangleTPage, + RectangleClut, { + GPU::Color24::Red(), + GPU::Color24::Blue(), + GPU::Color24::Green(), + GPU::Color24::White()} +); +static constexpr const auto rectangle5 = GPU::POLY_GT4( + {RectangleArea.position.move(0, RectangleArea.size.height), RectangleArea.size}, {0, 0}, + RectangleTPage, + RectangleClut, { + GPU::Color24::Red(), + GPU::Color24::Blue(), + GPU::Color24::Green(), + GPU::Color24::White()} +).set_semi_transparent(true); + +static constexpr const auto line1 = GPU::LINE_F::create(LineColor, + {0, 0}, + {GPU::Display::Width, GPU::Display::Height} +); +static constexpr const auto line2 = GPU::LINE_F::create(LineColor.invert(), + GPU::Vertex(0, 0), + GPU::Vertex(16, 0), + GPU::Vertex(16, 16), + GPU::Vertex(0, 0) +); +static constexpr const auto line3 = GPU::LINE_G::create( + {LineColor, {GPU::Display::Width, 0}}, + {LineColor.invert(), {0, GPU::Display::Height}} +); +static constexpr const auto line4 = GPU::LINE_G::create( + GPU::ColorVertex{GPU::Color24::Red(), {0, 0}}, + GPU::ColorVertex{GPU::Color24::Green(), {0, 16}}, + GPU::ColorVertex{GPU::Color24::Blue(), {16, 16}}, + GPU::ColorVertex{GPU::Color24::White(), {0, 0}} +); + +static constexpr const auto rect1 = GPU::TILE(GPU::AreaI16({GPU::Display::Width - 32, GPU::Display::Height - 32}, {32, 32}), GPU::Color24::Green()); +static constexpr const auto rect2 = GPU::TILE_16({GPU::Display::Width - 16, GPU::Display::Height - 16}, GPU::Color24::Blue()); +static constexpr const auto rect3 = GPU::TILE_8({GPU::Display::Width - 8, GPU::Display::Height - 8}, GPU::Color24::Yellow()); +static constexpr const auto rect4 = GPU::TILE_1({GPU::Display::Width - 1, GPU::Display::Height - 1}, GPU::Color24::Red()); + +static constexpr const auto texpage = GPU::TexPage({320, 0}, GPU::TexturePageColor::$4bit); +static constexpr const auto rect5 = GPU::SPRT(GPU::AreaI16({0, GPU::Display::Height - 32}, {32, 32}), {{0, 0}, TriangleClut}, GPU::Color24::Green()); +static constexpr const auto rect6 = GPU::SPRT_16({0, GPU::Display::Height - 16}, {{0, 0}, TriangleClut}, GPU::Color24::Blue()); +static constexpr const auto rect7 = GPU::SPRT_8({0, GPU::Display::Height - 8}, {{0, 0}, TriangleClut}, GPU::Color24::Yellow()); +static constexpr const auto rect8 = GPU::SPRT_1({0, GPU::Display::Height - 1}, {{0, 0}, TriangleClut}, GPU::Color24::Red()); + +static auto rect9 = GPU::SPRT(GPU::AreaI16({GPU::Display::Width/2, GPU::Display::Height/2}, {32, 32}).centered(), {{0, 0}, TriangleClut}, GPU::Color24::Grey()).linked(); +static auto rect10 = GPU::SPRT(GPU::AreaI16({GPU::Display::Width/2, GPU::Display::Height/2 - 32}, {32, 32}).centered(), {{0, 0}, TriangleClut}, GPU::Color24::Grey()).linked(); + +static void load_assets() { + static const CDFile Assets[] = { + CDFileBuilder::simple_tim(LBA::FONT, SimpleTIM(320, 0, 320, 511)), + CDFileBuilder::simple_tim(LBA::ICON, SimpleTIM(320, 256, 320, 510)), + }; + + const auto buffer_cfg = CDFileProcessor::BufferConfiguration::new_default(); + CDFileProcessor file_processor; + + file_processor.setup(lba, Assets, buffer_cfg); + while(true) { + switch(file_processor.process()) { + case Progress::InProgress: + break; + + case Progress::Done: + if(!file_processor.next(lba, buffer_cfg)) { + return; + } + break; + + case Progress::Error: + printf("Error detected! Aborting load\n"); + return; + } + } + printf("Done loading assets!\n"); +} + +void test_gpu() { + load_assets(); + + rect9.concat(rect10); + + while(true) { + GPU::render(triangle1); + GPU::render(triangle2); + GPU::render(triangle3); + GPU::render(triangle4); + + GPU::render(rectangle1); + GPU::render(rectangle2); + GPU::render(rectangle3); + GPU::render(rectangle4); + GPU::render(rectangle5); + + GPU::render(rect1); + GPU::render(rect2); + GPU::render(rect3); + GPU::render(rect4); + GPU::render(texpage); + GPU::render(rect5); + GPU::render(rect6); + GPU::render(rect7); + GPU::render(rect8); + + GPU::render(line1); + GPU::render(line2); + GPU::render(line3); + GPU::render(line4); + + GPU::render(rect9); + + GPU::swap_buffers_vsync(2); + } +} +__declare_lba_header(LBA); \ No newline at end of file diff --git a/examples/PoolBox/application/src/main.cpp b/examples/PoolBox/application/src/main.cpp index ca776915..ef5c08a2 100644 --- a/examples/PoolBox/application/src/main.cpp +++ b/examples/PoolBox/application/src/main.cpp @@ -1,193 +1,5 @@ -#include -#include -#include -#include #include -enum LBA { - __jabyengine_start_lba_request - __jabyengine_request_lba_for(FONT, "ASSETS/FONT.BIN"), - __jabyengine_request_lba_for(ICON, "ASSETS/ICON.BIN"), - __jabyengine_end_lba_request -}; - -using namespace JabyEngine; - -// Some default values for the objects -static constexpr auto TriangleColor = GPU::Color24(0x0, 0xFF, 0xFF); -static constexpr auto TriangleArea = GPU::AreaI16({0, 0}, {64, 64}); -static constexpr auto TriangleTPage = GPU::TPage(320, 0, GPU::SemiTransparency::B_Half_add_F_Half, GPU::TexturePageColor::$4bit); -static constexpr auto TriangleClut = GPU::PageClut(320, 511); - -static constexpr auto RectangleColor = GPU::Color24(0x80, 0x80, 0xFF); -static constexpr auto RectangleArea = GPU::AreaI16({0, TriangleArea.size.height}, {80, 80}); -static constexpr auto RectangleTPage = GPU::TPage(320, 256, GPU::SemiTransparency::B_Half_add_F_Half, GPU::TexturePageColor::$4bit); -static constexpr auto RectangleClut = GPU::PageClut(320, 510); - -static constexpr auto LineColor = GPU::Color24(0xFF, 0x0, 0x0); - -static constexpr const auto triangle1 = GPU::POLY_F3({ - {TriangleArea.position.x, TriangleArea.position.y}, - {TriangleArea.size.width, TriangleArea.size.height}, - {TriangleArea.position.x, TriangleArea.size.height}}, - TriangleColor -); -static constexpr const auto triangle2 = GPU::POLY_FT3({ - {TriangleArea.position.x, TriangleArea.position.y}, - {TriangleArea.size.width, TriangleArea.position.y}, - {TriangleArea.size.width, TriangleArea.size.height}},{ - // Texture - {TriangleArea.position.x, TriangleArea.position.y}, - {TriangleArea.size.width, TriangleArea.position.y}, - {TriangleArea.size.width, TriangleArea.size.height}}, - TriangleTPage, - TriangleClut, - GPU::Color24::Grey() -); -static constexpr const auto triangle3 = GPU::POLY_G3({ - {triangle1.vertex0.move(TriangleArea.size.width, 0), GPU::Color24::Red()}, - {triangle1.vertex1.move(TriangleArea.size.width, 0), GPU::Color24::Green()}, - {triangle1.vertex2.move(TriangleArea.size.width, 0), GPU::Color24::Blue()}} -); -static constexpr const auto triangle4 = GPU::POLY_GT3({ - {triangle2.vertex0.move(TriangleArea.size.width, 0), triangle2.page0, GPU::Color24::Red()}, - {triangle2.vertex1.move(TriangleArea.size.width, 0), triangle2.page1, GPU::Color24::Blue()}, - {triangle2.vertex2.move(TriangleArea.size.width, 0), triangle2.page2, GPU::Color24::Green()}}, - TriangleTPage, - TriangleClut -); - -static constexpr const auto rectangle1 = GPU::POLY_F4(RectangleArea, RectangleColor); -static constexpr const auto rectangle2 = GPU::POLY_FT4({ - RectangleArea.position.move(RectangleArea.size.width, 0), RectangleArea.size}, {0, 0}, - RectangleTPage, - RectangleClut, - GPU::Color24::Grey() -); -static constexpr const auto rectangle3 = GPU::POLY_G4( - {RectangleArea.position.move(RectangleArea.size.width*2, 0), RectangleArea.size}, { - GPU::Color24::Red(), - GPU::Color24::Blue(), - GPU::Color24::Green(), - GPU::Color24::White()}); -static constexpr const auto rectangle4 = GPU::POLY_GT4( - {RectangleArea.position.move(RectangleArea.size.width*3, 0), RectangleArea.size}, {0, 0}, - RectangleTPage, - RectangleClut, { - GPU::Color24::Red(), - GPU::Color24::Blue(), - GPU::Color24::Green(), - GPU::Color24::White()} -); -static constexpr const auto rectangle5 = GPU::POLY_GT4( - {RectangleArea.position.move(0, RectangleArea.size.height), RectangleArea.size}, {0, 0}, - RectangleTPage, - RectangleClut, { - GPU::Color24::Red(), - GPU::Color24::Blue(), - GPU::Color24::Green(), - GPU::Color24::White()} -).set_semi_transparent(true); - -static constexpr const auto line1 = GPU::LINE_F::create(LineColor, - {0, 0}, - {GPU::Display::Width, GPU::Display::Height} -); -static constexpr const auto line2 = GPU::LINE_F::create(LineColor.invert(), - GPU::Vertex(0, 0), - GPU::Vertex(16, 0), - GPU::Vertex(16, 16), - GPU::Vertex(0, 0) -); -static constexpr const auto line3 = GPU::LINE_G::create( - {LineColor, {GPU::Display::Width, 0}}, - {LineColor.invert(), {0, GPU::Display::Height}} -); -static constexpr const auto line4 = GPU::LINE_G::create( - GPU::ColorVertex{GPU::Color24::Red(), {0, 0}}, - GPU::ColorVertex{GPU::Color24::Green(), {0, 16}}, - GPU::ColorVertex{GPU::Color24::Blue(), {16, 16}}, - GPU::ColorVertex{GPU::Color24::White(), {0, 0}} -); - -static constexpr const auto rect1 = GPU::TILE(GPU::AreaI16({GPU::Display::Width - 32, GPU::Display::Height - 32}, {32, 32}), GPU::Color24::Green()); -static constexpr const auto rect2 = GPU::TILE_16({GPU::Display::Width - 16, GPU::Display::Height - 16}, GPU::Color24::Blue()); -static constexpr const auto rect3 = GPU::TILE_8({GPU::Display::Width - 8, GPU::Display::Height - 8}, GPU::Color24::Yellow()); -static constexpr const auto rect4 = GPU::TILE_1({GPU::Display::Width - 1, GPU::Display::Height - 1}, GPU::Color24::Red()); - -static constexpr const auto texpage = GPU::TexPage({320, 0}, GPU::TexturePageColor::$4bit); -static constexpr const auto rect5 = GPU::SPRT(GPU::AreaI16({0, GPU::Display::Height - 32}, {32, 32}), {{0, 0}, TriangleClut}, GPU::Color24::Green()); -static constexpr const auto rect6 = GPU::SPRT_16({0, GPU::Display::Height - 16}, {{0, 0}, TriangleClut}, GPU::Color24::Blue()); -static constexpr const auto rect7 = GPU::SPRT_8({0, GPU::Display::Height - 8}, {{0, 0}, TriangleClut}, GPU::Color24::Yellow()); -static constexpr const auto rect8 = GPU::SPRT_1({0, GPU::Display::Height - 1}, {{0, 0}, TriangleClut}, GPU::Color24::Red()); - -static auto rect9 = GPU::SPRT(GPU::AreaI16({GPU::Display::Width/2, GPU::Display::Height/2}, {32, 32}).centered(), {{0, 0}, TriangleClut}, GPU::Color24::Grey()).linked(); -static auto rect10 = GPU::SPRT(GPU::AreaI16({GPU::Display::Width/2, GPU::Display::Height/2 - 32}, {32, 32}).centered(), {{0, 0}, TriangleClut}, GPU::Color24::Grey()).linked(); - -static void load_assets() { - static const CDFile Assets[] = { - CDFileBuilder::simple_tim(LBA::FONT, SimpleTIM(320, 0, 320, 511)), - CDFileBuilder::simple_tim(LBA::ICON, SimpleTIM(320, 256, 320, 510)), - }; - - const auto buffer_cfg = CDFileProcessor::BufferConfiguration::new_default(); - CDFileProcessor file_processor; - - file_processor.setup(lba, Assets, buffer_cfg); - while(true) { - switch(file_processor.process()) { - case Progress::InProgress: - break; - - case Progress::Done: - if(!file_processor.next(lba, buffer_cfg)) { - return; - } - break; - - case Progress::Error: - printf("Error detected! Aborting load\n"); - return; - } - } - printf("Done loading assets!\n"); -} - void main() { - load_assets(); - - rect9.concat(rect10); - - while(true) { - GPU::render(triangle1); - GPU::render(triangle2); - GPU::render(triangle3); - GPU::render(triangle4); - - GPU::render(rectangle1); - GPU::render(rectangle2); - GPU::render(rectangle3); - GPU::render(rectangle4); - GPU::render(rectangle5); - - GPU::render(rect1); - GPU::render(rect2); - GPU::render(rect3); - GPU::render(rect4); - GPU::render(texpage); - GPU::render(rect5); - GPU::render(rect6); - GPU::render(rect7); - GPU::render(rect8); - - GPU::render(line1); - GPU::render(line2); - GPU::render(line3); - GPU::render(line4); - - GPU::render(rect9); - - GPU::swap_buffers_vsync(2); - } -} -__declare_lba_header(LBA); \ No newline at end of file + printf("Planschbecken c:\n"); +} \ No newline at end of file diff --git a/examples/PoolBox/iso/Config.xml b/examples/PoolBox/iso/Config.xml index c2ef9bf9..cad8f163 100644 --- a/examples/PoolBox/iso/Config.xml +++ b/examples/PoolBox/iso/Config.xml @@ -5,7 +5,7 @@ iso/System.cnf -
application/bin/PSX-release/PoolBox.psexe
+
application/bin/PSX-release/PoolBox.psexe
assets/bin/TexturePage.bin assets/bin/IconTexture.bin From 501ed1cd35d4217270f5a312c014b0195f6f37b7 Mon Sep 17 00:00:00 2001 From: jaby Date: Wed, 14 Jun 2023 22:04:01 +0200 Subject: [PATCH 046/588] Convert Yoshi font and setup auto lba --- examples/PoolBox/application/Overlays.json | 4 ++-- .../src/{ => Overlay}/GPUTests/gpu_tests.cpp | 0 .../{ => Overlay}/TimerTests/timer_tests.cpp | 0 examples/PoolBox/application/src/assets.hpp | 8 ++++++++ examples/PoolBox/application/src/main.cpp | 2 ++ .../PoolBox/application/src/main_assets.cpp | 18 ++++++++++++++++++ examples/PoolBox/assets/Makefile | 5 ++++- examples/PoolBox/assets/YoshiFont.png | 3 +++ examples/PoolBox/iso/Config.xml | 7 +++++-- 9 files changed, 42 insertions(+), 5 deletions(-) rename examples/PoolBox/application/src/{ => Overlay}/GPUTests/gpu_tests.cpp (100%) rename examples/PoolBox/application/src/{ => Overlay}/TimerTests/timer_tests.cpp (100%) create mode 100644 examples/PoolBox/application/src/assets.hpp create mode 100644 examples/PoolBox/application/src/main_assets.cpp create mode 100644 examples/PoolBox/assets/YoshiFont.png diff --git a/examples/PoolBox/application/Overlays.json b/examples/PoolBox/application/Overlays.json index 9a450a0e..7103e778 100644 --- a/examples/PoolBox/application/Overlays.json +++ b/examples/PoolBox/application/Overlays.json @@ -1,10 +1,10 @@ { "slot_0": { "timer_tests": { - "pattern": "bin/*/src/TimerTests/*.o" + "pattern": "bin/*/src/Overlay/TimerTests/*.o" }, "gpu_tests": { - "pattern": "bin/*/src/GPUTests/*.o" + "pattern": "bin/*/src/Overlay/GPUTests/*.o" } } } \ No newline at end of file diff --git a/examples/PoolBox/application/src/GPUTests/gpu_tests.cpp b/examples/PoolBox/application/src/Overlay/GPUTests/gpu_tests.cpp similarity index 100% rename from examples/PoolBox/application/src/GPUTests/gpu_tests.cpp rename to examples/PoolBox/application/src/Overlay/GPUTests/gpu_tests.cpp diff --git a/examples/PoolBox/application/src/TimerTests/timer_tests.cpp b/examples/PoolBox/application/src/Overlay/TimerTests/timer_tests.cpp similarity index 100% rename from examples/PoolBox/application/src/TimerTests/timer_tests.cpp rename to examples/PoolBox/application/src/Overlay/TimerTests/timer_tests.cpp diff --git a/examples/PoolBox/application/src/assets.hpp b/examples/PoolBox/application/src/assets.hpp new file mode 100644 index 00000000..000ae349 --- /dev/null +++ b/examples/PoolBox/application/src/assets.hpp @@ -0,0 +1,8 @@ +#ifndef __ASSETS_HPP__ +#define __ASSETS_HPP__ + +namespace Assets { + void load_for_main(); +} + +#endif //!__ASSETS_HPP__ \ No newline at end of file diff --git a/examples/PoolBox/application/src/main.cpp b/examples/PoolBox/application/src/main.cpp index ef5c08a2..9bc34324 100644 --- a/examples/PoolBox/application/src/main.cpp +++ b/examples/PoolBox/application/src/main.cpp @@ -1,5 +1,7 @@ +#include "assets.hpp" #include void main() { + Assets::load_for_main(); printf("Planschbecken c:\n"); } \ No newline at end of file diff --git a/examples/PoolBox/application/src/main_assets.cpp b/examples/PoolBox/application/src/main_assets.cpp new file mode 100644 index 00000000..050c9162 --- /dev/null +++ b/examples/PoolBox/application/src/main_assets.cpp @@ -0,0 +1,18 @@ +#include "assets.hpp" +#include +#include +#include + +namespace Assets { + enum LBA { + __jabyengine_start_lba_request + __jabyengine_request_lba_for(FONT, "ASSETS/MAIN/FONT.BIN"), + __jabyengine_end_lba_request + }; + + __declare_lba_header(LBA); + + void load_for_main() { + printf("Loading assets! %i\n", lba[LBA::FONT].get_lba()); + } +} \ No newline at end of file diff --git a/examples/PoolBox/assets/Makefile b/examples/PoolBox/assets/Makefile index 15b5e4ca..ba1dc0ad 100644 --- a/examples/PoolBox/assets/Makefile +++ b/examples/PoolBox/assets/Makefile @@ -11,7 +11,10 @@ $(OUTPUT_DIR)/IconTexture.bin: IconTexture.png @mkdir -p $(OUTPUT_DIR) jaby_engine_fconv --lz4 $< -o $@ simple-tim clut4 --semi-trans --color-trans -all: $(OUTPUT_DIR)/TexturePage.bin $(OUTPUT_DIR)/IconTexture.bin +$(OUTPUT_DIR)/YoshiFont.bin: YoshiFont.png + jaby_engine_fconv --lz4 $< -o $@ simple-tim clut4 --color-trans + +all: $(OUTPUT_DIR)/TexturePage.bin $(OUTPUT_DIR)/IconTexture.bin $(OUTPUT_DIR)/YoshiFont.bin clean: rm -fr $(OUTPUT_DIR) \ No newline at end of file diff --git a/examples/PoolBox/assets/YoshiFont.png b/examples/PoolBox/assets/YoshiFont.png new file mode 100644 index 00000000..653e8ff8 --- /dev/null +++ b/examples/PoolBox/assets/YoshiFont.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8d195c708c5642d2705039f1115c24c5d16bef6ec5ba332a6a6bbf9fa7e7bcaf +size 4452 diff --git a/examples/PoolBox/iso/Config.xml b/examples/PoolBox/iso/Config.xml index cad8f163..a12f195b 100644 --- a/examples/PoolBox/iso/Config.xml +++ b/examples/PoolBox/iso/Config.xml @@ -5,8 +5,11 @@ iso/System.cnf -
application/bin/PSX-release/PoolBox.psexe
- +
application/bin/PSX-release/PoolBox.psexe
+ From d40486a308aac20797b7709d0436eac6a9bd3737 Mon Sep 17 00:00:00 2001 From: jaby Date: Thu, 15 Jun 2023 20:48:25 +0200 Subject: [PATCH 047/588] Testing font and color font --- examples/PoolBox/application/src/assets.hpp | 4 +++ examples/PoolBox/application/src/main.cpp | 20 +++++++++++++- .../PoolBox/application/src/main_assets.cpp | 26 +++++++++++++++++-- .../PSX/GPU/Primitives/linked_elements.hpp | 7 ++++- include/PSX/GPU/gpu_types.hpp | 16 ++++++------ 5 files changed, 61 insertions(+), 12 deletions(-) diff --git a/examples/PoolBox/application/src/assets.hpp b/examples/PoolBox/application/src/assets.hpp index 000ae349..a92673eb 100644 --- a/examples/PoolBox/application/src/assets.hpp +++ b/examples/PoolBox/application/src/assets.hpp @@ -1,7 +1,11 @@ #ifndef __ASSETS_HPP__ #define __ASSETS_HPP__ +#include namespace Assets { + using namespace JabyEngine; + + static constexpr auto FontTIM = SimpleTIM(960, 0, 960, 511); void load_for_main(); } diff --git a/examples/PoolBox/application/src/main.cpp b/examples/PoolBox/application/src/main.cpp index 9bc34324..277b9103 100644 --- a/examples/PoolBox/application/src/main.cpp +++ b/examples/PoolBox/application/src/main.cpp @@ -1,7 +1,25 @@ #include "assets.hpp" +#include +#include #include +using namespace JabyEngine; +static auto FontPage = GPU::TexPage({Assets::FontTIM.get_texture_x(), Assets::FontTIM.get_texture_y()}, GPU::TexturePageColor::$4bit).linked(); +static auto FontTest = GPU::SPRT( + GPU::AreaI16({0, 0}, {256, 96}), {GPU::PagePosition(0, 0), GPU::PageClut(Assets::FontTIM.get_clut_x(), Assets::FontTIM.get_clut_y())}, + GPU::Color24::Grey() +).linked(); +static auto FontTestColor = GPU::SPRT( + GPU::AreaI16({0, 96}, {256, 96}), {GPU::PagePosition(0, 0), GPU::PageClut(Assets::FontTIM.get_clut_x(), Assets::FontTIM.get_clut_y())}, + GPU::Color24(0x0, 0x0, 0xA0) +).linked(); + void main() { Assets::load_for_main(); - printf("Planschbecken c:\n"); + + FontPage.concat(FontTest).concat(FontTestColor); + while(true) { + GPU::swap_buffers_vsync(1); + GPU::render(FontPage); + } } \ No newline at end of file diff --git a/examples/PoolBox/application/src/main_assets.cpp b/examples/PoolBox/application/src/main_assets.cpp index 050c9162..b3ea8041 100644 --- a/examples/PoolBox/application/src/main_assets.cpp +++ b/examples/PoolBox/application/src/main_assets.cpp @@ -1,5 +1,4 @@ #include "assets.hpp" -#include #include #include @@ -13,6 +12,29 @@ namespace Assets { __declare_lba_header(LBA); void load_for_main() { - printf("Loading assets! %i\n", lba[LBA::FONT].get_lba()); + static const CDFile Assets[] = { + CDFileBuilder::simple_tim(LBA::FONT, FontTIM), + }; + + const auto buffer_cfg = CDFileProcessor::BufferConfiguration::new_default(); + CDFileProcessor file_processor; + + file_processor.setup(lba, Assets, buffer_cfg); + while(true) { + switch(file_processor.process()) { + case Progress::InProgress: + break; + + case Progress::Done: + if(!file_processor.next(lba, buffer_cfg)) { + return; + } + break; + + case Progress::Error: + printf("Error detected! Aborting load\n"); + return; + } + } } } \ No newline at end of file diff --git a/include/PSX/GPU/Primitives/linked_elements.hpp b/include/PSX/GPU/Primitives/linked_elements.hpp index 5a1b2c13..45c8f49e 100644 --- a/include/PSX/GPU/Primitives/linked_elements.hpp +++ b/include/PSX/GPU/Primitives/linked_elements.hpp @@ -34,11 +34,16 @@ namespace JabyEngine { } template - const T& concat(const T& obj) { + T& concat(T& obj) { Link::set_adr(&obj); return obj; } + template + const T& concat(const T& obj) { + return concat(const_cast(obj)); + } + constexpr void terminate() { this->value |= TerminationValue; } diff --git a/include/PSX/GPU/gpu_types.hpp b/include/PSX/GPU/gpu_types.hpp index 0ef84a80..6900da29 100644 --- a/include/PSX/GPU/gpu_types.hpp +++ b/include/PSX/GPU/gpu_types.hpp @@ -78,20 +78,20 @@ namespace JabyEngine { return Color24(0xFF, 0xFF, 0xFF); } - static constexpr Color24 Red() { - return Color24(0xFF, 0x0, 0x0); + static constexpr Color24 Red(uint8_t base = 0xFF) { + return Color24(base, 0x0, 0x0); } - static constexpr Color24 Green() { - return Color24(0x0, 0xFF, 0x0); + static constexpr Color24 Green(uint8_t base = 0xFF) { + return Color24(0x0, base, 0x0); } - static constexpr Color24 Blue() { - return Color24(0x0, 0x0, 0xFF); + static constexpr Color24 Blue(uint8_t base = 0xFF) { + return Color24(0x0, 0x0, base); } - static constexpr Color24 Yellow() { - return Color24(0xFF, 0xFF, 0x0); + static constexpr Color24 Yellow(uint8_t base = 0xFF) { + return Color24(base, base, 0x0); } constexpr Color24 invert() const { From 075c7685dfda83082eeebcd458ec52be42a7c826 Mon Sep 17 00:00:00 2001 From: jaby Date: Mon, 19 Jun 2023 22:30:52 +0200 Subject: [PATCH 048/588] Fix default constructor for rectangle types --- include/PSX/GPU/Primitives/primitive_rectangle_types.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/PSX/GPU/Primitives/primitive_rectangle_types.hpp b/include/PSX/GPU/Primitives/primitive_rectangle_types.hpp index 247ab38e..94efdcd0 100644 --- a/include/PSX/GPU/Primitives/primitive_rectangle_types.hpp +++ b/include/PSX/GPU/Primitives/primitive_rectangle_types.hpp @@ -39,7 +39,7 @@ namespace JabyEngine { static constexpr auto IdentityCode = Code().set(Code::Size.with(static_cast(Size))).set(Code::Untextured).set(Code::NonTransparent); Color24 color; - Code code; + Code code = IdentityCode; Vertex position; constexpr RECT_BASE_F() = default; @@ -53,7 +53,7 @@ namespace JabyEngine { static constexpr auto IdentityCode = Code(RECT_BASE_F::IdentityCode).set(Code::Textured); Color24 color; - Code code; + Code code = IdentityCode; Vertex position; PagePosition page; PageClut clut; From 3be39c410b4103228d5c648319fa87f6c276feb8 Mon Sep 17 00:00:00 2001 From: jaby Date: Wed, 21 Jun 2023 21:45:15 +0200 Subject: [PATCH 049/588] Use BSS default constructor --- include/PSX/Auxiliary/type_traits.hpp | 23 ++ .../GPU/Primitives/primitive_gpu_commands.hpp | 6 +- .../GPU/Primitives/primitive_line_types.hpp | 22 +- .../GPU/Primitives/primitive_poly_types.hpp | 218 +++++++++--------- .../Primitives/primitive_rectangle_types.hpp | 26 +-- .../Primitives/primitive_support_types.hpp | 22 +- include/PSX/GPU/gpu.hpp | 4 +- 7 files changed, 160 insertions(+), 161 deletions(-) diff --git a/include/PSX/Auxiliary/type_traits.hpp b/include/PSX/Auxiliary/type_traits.hpp index b1a78bb2..255696df 100644 --- a/include/PSX/Auxiliary/type_traits.hpp +++ b/include/PSX/Auxiliary/type_traits.hpp @@ -2,6 +2,27 @@ #define __JABYENGINE_TYPE_TRAITS_HPP__ namespace JabyEngine { + template + struct integral_constant { + static constexpr T value = v; + + typedef T value_type; + typedef integral_constant type; + + constexpr operator T() const { + return v; + } + + constexpr T operator()() const { + return v; + } + }; + + typedef integral_constant true_type; + typedef integral_constant false_type; + + // ############################################# + template struct enable_if {}; @@ -53,6 +74,8 @@ namespace JabyEngine { template using variadic_force_same = enable_if...>::value>::type; + + // ############################################# } #endif //! __JABYENGINE_TYPE_TRAITS_HPP__ \ No newline at end of file diff --git a/include/PSX/GPU/Primitives/primitive_gpu_commands.hpp b/include/PSX/GPU/Primitives/primitive_gpu_commands.hpp index 275d6cc9..d2bad645 100644 --- a/include/PSX/GPU/Primitives/primitive_gpu_commands.hpp +++ b/include/PSX/GPU/Primitives/primitive_gpu_commands.hpp @@ -7,15 +7,13 @@ namespace JabyEngine { namespace GPU { struct TexPage : public internal::LinkedElementCreator { + static constexpr bool is_render_primitive = true; + GPU_IO::GP0_t value; constexpr TexPage(const PositionU16& tex_pos, TexturePageColor tex_color, SemiTransparency transparency = SemiTransparency::B_Half_add_F_Half, bool dither = false) : value{ GPU_IO::Command::TexPage(tex_pos, transparency, tex_color, dither, false)} {} }; - - namespace internal { - __jaby_engine_declare_render_primitive(TexPage); - } } } diff --git a/include/PSX/GPU/Primitives/primitive_line_types.hpp b/include/PSX/GPU/Primitives/primitive_line_types.hpp index 2a8ce37c..c950b155 100644 --- a/include/PSX/GPU/Primitives/primitive_line_types.hpp +++ b/include/PSX/GPU/Primitives/primitive_line_types.hpp @@ -13,6 +13,10 @@ namespace JabyEngine { static constexpr auto FlatShading = !GouraudShading; static constexpr auto PolyLine = Bit(27 - BitCorrection); static constexpr auto SingleLine = !PolyLine; + + static constexpr LineCode create() { + return LineCode(CmdValue); + } }; template @@ -54,14 +58,14 @@ namespace JabyEngine { }; template - struct SingleLine : public LineCodeInterface>, public internal::LinkedElementCreator> { + struct SingleLine : public internal::RenderPrimitive>, public LineCodeInterface>, public internal::LinkedElementCreator> { LineHead head; Vertex start_point; Body end_point; }; template - struct MultiLine : public LineCodeInterface>, public internal::LinkedElementCreator> { + struct MultiLine : public internal::RenderPrimitive>, public LineCodeInterface>, public internal::LinkedElementCreator> { LineHead head; Vertex start_point; Body points[N]; @@ -72,7 +76,7 @@ namespace JabyEngine { struct LINE_F { typedef internal::LineCode Code; - static constexpr auto IdentityCode = Code().set(Code::FlatShading).set(Code::SingleLine).set(Code::NonTransparent); + static constexpr auto IdentityCode = Code::create().set(Code::FlatShading).set(Code::SingleLine).set(Code::NonTransparent); static constexpr internal::SingleLine create(const Color24& color, const Vertex& start_point, const Vertex& end_point) { using namespace internal; @@ -102,18 +106,6 @@ namespace JabyEngine { return {.head = LineHead::create(start_point.color, IdentityCode, true), .start_point = start_point.position, .points = {rest...}, .end = Termination::create()}; } }; - - namespace internal { - template - struct is_render_primitive> { - static constexpr bool value = true; - }; - - template - struct is_render_primitive> { - static constexpr bool value = true; - }; - } } } diff --git a/include/PSX/GPU/Primitives/primitive_poly_types.hpp b/include/PSX/GPU/Primitives/primitive_poly_types.hpp index efbc5a06..57996b6a 100644 --- a/include/PSX/GPU/Primitives/primitive_poly_types.hpp +++ b/include/PSX/GPU/Primitives/primitive_poly_types.hpp @@ -13,6 +13,10 @@ namespace JabyEngine { static constexpr auto FlatShading = !GouraudShading; static constexpr auto QuadVertics = Bit(27 - BitCorrection); static constexpr auto TriVertics = !QuadVertics; + + static constexpr PolyCode create() { + return PolyCode(CmdValue); + } }; template @@ -36,14 +40,14 @@ namespace JabyEngine { / \ 3 - 2 */ - struct POLY_F3 : public internal::PolyCodeInterface, public internal::LinkedElementCreator { - static constexpr auto IdentityCode = Code().set(Code::FlatShading).set(Code::TriVertics).set(Code::Untextured).set(Code::NonTransparent); + struct POLY_F3 : public internal::RenderPrimitive, public internal::PolyCodeInterface, public internal::LinkedElementCreator { + static constexpr auto IdentityCode = Code::create().set(Code::FlatShading).set(Code::TriVertics).set(Code::Untextured).set(Code::NonTransparent); - Color24 color; // a - Code code = IdentityCode; // a - Vertex vertex0; // b - Vertex vertex1; // c - Vertex vertex2; // d + Color24 color; // a + Code code; // a + Vertex vertex0; // b + Vertex vertex1; // c + Vertex vertex2; // d constexpr POLY_F3() = default; constexpr POLY_F3(const Vertex (&verticies)[3], Color24 color) : @@ -54,24 +58,24 @@ namespace JabyEngine { } }; - struct POLY_FT3 : public internal::PolyCodeInterface, public internal::LinkedElementCreator { + struct POLY_FT3 : public internal::RenderPrimitive, public internal::PolyCodeInterface, public internal::LinkedElementCreator { struct VertexEx { Vertex position; PagePosition page; }; static constexpr auto IdentityCode = Code(POLY_F3::IdentityCode).set(Code::Textured); - Color24 color; // a - Code code = IdentityCode; // a - Vertex vertex0; // b - PagePosition page0; // c - PageClut page_clut; // c - Vertex vertex1; // d - PagePosition page1; // e - TPage tpage; // e - Vertex vertex2; // f - PagePosition page2; // g - uint16_t padded2; // g + Color24 color; // a + Code code; // a + Vertex vertex0; // b + PagePosition page0; // c + PageClut page_clut; // c + Vertex vertex1; // d + PagePosition page1; // e + TPage tpage; // e + Vertex vertex2; // f + PagePosition page2; // g + uint16_t padded2; // g constexpr POLY_FT3() = default; constexpr POLY_FT3(const Vertex (&verticies)[3], const PagePosition (&page_pos)[3], TPage tpage, PageClut clut, Color24 color = Color24::Grey()) : POLY_FT3({ @@ -85,18 +89,18 @@ namespace JabyEngine { vertex2(vertices_ex[2].position), page2(vertices_ex[2].page), padded2(0) {} }; - struct POLY_G3 : public internal::PolyCodeInterface, public internal::LinkedElementCreator { + struct POLY_G3 : public internal::RenderPrimitive, public internal::PolyCodeInterface, public internal::LinkedElementCreator { static constexpr auto IdentityCode = Code(POLY_F3::IdentityCode).set(Code::GouraudShading); - Color24 color0; // a - Code code = IdentityCode; // a - Vertex vertex0; // b - Color24 color1; // c - uint8_t pad1; // c - Vertex vertex1; // d - Color24 color2; // e - uint8_t pad2; // e - Vertex vertex2; // f + Color24 color0; // a + Code code; // a + Vertex vertex0; // b + Color24 color1; // c + uint8_t pad1; // c + Vertex vertex1; // d + Color24 color2; // e + uint8_t pad2; // e + Vertex vertex2; // f constexpr POLY_G3() = default; constexpr POLY_G3(const Vertex (&verticies)[3], const Color24 (&color)[3]) : POLY_G3({ @@ -109,7 +113,7 @@ namespace JabyEngine { color2(verticies_ex[2].color), pad2(0), vertex2(verticies_ex[2].position) {} }; - struct POLY_GT3 : public internal::PolyCodeInterface, public internal::LinkedElementCreator { + struct POLY_GT3 : public internal::RenderPrimitive, public internal::PolyCodeInterface, public internal::LinkedElementCreator { struct VertexEx { Vertex position; PagePosition page; @@ -117,21 +121,21 @@ namespace JabyEngine { }; static constexpr auto IdentityCode = Code(POLY_G3::IdentityCode).set(Code::Textured); - Color24 color0; // a - Code code = IdentityCode; // a - Vertex vertex0; // b - PagePosition page0; // c - PageClut page_clut; // c - Color24 color1; // d - uint8_t pad1; // d - Vertex vertex1; // e - PagePosition page1; // f - TPage tpage; // f - Color24 color2; // g - uint8_t pad2; // g - Vertex vertex2; // h - PagePosition page2; // i - uint16_t pad3; // i + Color24 color0; // a + Code code; // a + Vertex vertex0; // b + PagePosition page0; // c + PageClut page_clut; // c + Color24 color1; // d + uint8_t pad1; // d + Vertex vertex1; // e + PagePosition page1; // f + TPage tpage; // f + Color24 color2; // g + uint8_t pad2; // g + Vertex vertex2; // h + PagePosition page2; // i + uint16_t pad3; // i constexpr POLY_GT3() = default; constexpr POLY_GT3(const Vertex (&verticies)[3], const PagePosition (&page_pos)[3], const Color24 (&color)[3], TPage tpage, PageClut clut) : POLY_GT3({ @@ -149,15 +153,15 @@ namespace JabyEngine { | | 3 - 4 */ - struct POLY_F4 : public internal::PolyCodeInterface, public internal::LinkedElementCreator { + struct POLY_F4 : public internal::RenderPrimitive, public internal::PolyCodeInterface, public internal::LinkedElementCreator { static constexpr auto IdentityCode = Code(POLY_F3::IdentityCode).set(Code::QuadVertics); - Color24 color; // a - Code code = IdentityCode; // a - Vertex vertex0; // b - Vertex vertex1; // c - Vertex vertex2; // d - Vertex vertex3; // e + Color24 color; // a + Code code; // a + Vertex vertex0; // b + Vertex vertex1; // c + Vertex vertex2; // d + Vertex vertex3; // e constexpr POLY_F4() = default; constexpr POLY_F4(const Vertex (&verticies)[4], Color24 color) : @@ -174,24 +178,24 @@ namespace JabyEngine { color) {} }; - struct POLY_FT4 : public internal::PolyCodeInterface, public internal::LinkedElementCreator { + struct POLY_FT4 : public internal::RenderPrimitive, public internal::PolyCodeInterface, public internal::LinkedElementCreator { typedef POLY_FT3::VertexEx VertexEx; static constexpr auto IdentityCode = Code(POLY_FT3::IdentityCode).set(Code::QuadVertics); - Color24 color; // a - Code code = IdentityCode; // a - Vertex vertex0; // b - PagePosition page0; // c - PageClut page_clut; // c - Vertex vertex1; // d - PagePosition page1; // e - TPage tpage; // e - Vertex vertex2; // f - PagePosition page2; // g - uint16_t pad2; // g - Vertex vertex3; // h - PagePosition page3; // i - uint16_t pad3; // i + Color24 color; // a + Code code; // a + Vertex vertex0; // b + PagePosition page0; // c + PageClut page_clut; // c + Vertex vertex1; // d + PagePosition page1; // e + TPage tpage; // e + Vertex vertex2; // f + PagePosition page2; // g + uint16_t pad2; // g + Vertex vertex3; // h + PagePosition page3; // i + uint16_t pad3; // i constexpr POLY_FT4() = default; constexpr POLY_FT4(const Vertex (&verticies)[4], const PagePosition (&page_pos)[4], TPage tpage, PageClut clut, Color24 color) : POLY_FT4({ @@ -214,21 +218,21 @@ namespace JabyEngine { ) {} }; - struct POLY_G4 : public internal::PolyCodeInterface, public internal::LinkedElementCreator { + struct POLY_G4 : public internal::RenderPrimitive, public internal::PolyCodeInterface, public internal::LinkedElementCreator { static constexpr auto IdentityCode = Code(POLY_G3::IdentityCode).set(Code::QuadVertics); - Color24 color0; // a - Code code = IdentityCode; // a - Vertex vertex0; // b - Color24 color1; // c - uint8_t pad1; // c - Vertex vertex1; // d - Color24 color2; // e - uint8_t pad2; // e - Vertex vertex2; // f - Color24 color3; // g - uint8_t pad3; // g - Vertex vertex3; // h + Color24 color0; // a + Code code; // a + Vertex vertex0; // b + Color24 color1; // c + uint8_t pad1; // c + Vertex vertex1; // d + Color24 color2; // e + uint8_t pad2; // e + Vertex vertex2; // f + Color24 color3; // g + uint8_t pad3; // g + Vertex vertex3; // h constexpr POLY_G4() = default; constexpr POLY_G4(const Vertex (&verticies)[4], const Color24 (&color)[4]) : POLY_G4({ @@ -250,30 +254,30 @@ namespace JabyEngine { ) {} }; - struct POLY_GT4 : public internal::PolyCodeInterface, public internal::LinkedElementCreator { + struct POLY_GT4 : public internal::RenderPrimitive, public internal::PolyCodeInterface, public internal::LinkedElementCreator { typedef POLY_GT3::VertexEx VertexEx; static constexpr auto IdentityCode = Code(POLY_GT3::IdentityCode).set(Code::QuadVertics); - Color24 color0; // a - Code code = IdentityCode; // a - Vertex vertex0; // b - PagePosition page0; // c - PageClut page_clut; // c - Color24 color1; // d - uint8_t pad1; // d - Vertex vertex1; // e - PagePosition page1; // f - TPage tpage; // f - Color24 color2; // g - uint8_t pad2; // g - Vertex vertex2; // h - PagePosition page2; // i - uint16_t pad3; // i - Color24 color3; // j - uint8_t pad4; // j - Vertex vertex3; // k - PagePosition page3; // l - uint16_t pad5; // l + Color24 color0; // a + Code code; // a + Vertex vertex0; // b + PagePosition page0; // c + PageClut page_clut; // c + Color24 color1; // d + uint8_t pad1; // d + Vertex vertex1; // e + PagePosition page1; // f + TPage tpage; // f + Color24 color2; // g + uint8_t pad2; // g + Vertex vertex2; // h + PagePosition page2; // i + uint16_t pad3; // i + Color24 color3; // j + uint8_t pad4; // j + Vertex vertex3; // k + PagePosition page3; // l + uint16_t pad5; // l constexpr POLY_GT4() = default; constexpr POLY_GT4(const Vertex (&verticies)[4], const PagePosition (&page_pos)[4], const Color24 (&color)[4], TPage tpage, PageClut clut) : POLY_GT4({ @@ -305,18 +309,6 @@ namespace JabyEngine { typedef POLY_G4 GouraudRectangle; typedef POLY_GT4 GouraudTexturedRectangle; - namespace internal { - __jaby_engine_declare_render_primitive(POLY_F3); - __jaby_engine_declare_render_primitive(POLY_FT3); - __jaby_engine_declare_render_primitive(POLY_G3); - __jaby_engine_declare_render_primitive(POLY_GT3); - - __jaby_engine_declare_render_primitive(POLY_F4); - __jaby_engine_declare_render_primitive(POLY_FT4); - __jaby_engine_declare_render_primitive(POLY_G4); - __jaby_engine_declare_render_primitive(POLY_GT4); - } - static_assert(sizeof(POLY_F3) == 16); static_assert(sizeof(POLY_FT3) == 28); static_assert(sizeof(POLY_G3) == 24); diff --git a/include/PSX/GPU/Primitives/primitive_rectangle_types.hpp b/include/PSX/GPU/Primitives/primitive_rectangle_types.hpp index 247ab38e..48547ca7 100644 --- a/include/PSX/GPU/Primitives/primitive_rectangle_types.hpp +++ b/include/PSX/GPU/Primitives/primitive_rectangle_types.hpp @@ -21,6 +21,10 @@ namespace JabyEngine { static constexpr uint8_t CmdValue = 0b011; static constexpr auto Size = BitRange::from_to(27 - BitCorrection, 28 - BitCorrection); + + static constexpr RectCode create() { + return RectCode(CmdValue); + } }; template @@ -36,7 +40,7 @@ namespace JabyEngine { template struct RECT_BASE_F : public RectCodeInterface> { typedef RECT_BASE_F::Code Code; - static constexpr auto IdentityCode = Code().set(Code::Size.with(static_cast(Size))).set(Code::Untextured).set(Code::NonTransparent); + static constexpr auto IdentityCode = Code::create().set(Code::Size.with(static_cast(Size))).set(Code::Untextured).set(Code::NonTransparent); Color24 color; Code code; @@ -64,12 +68,12 @@ namespace JabyEngine { }; template - struct RECT_F : public RECT_BASE_F, public internal::LinkedElementCreator> { + struct RECT_F : public RECT_BASE_F, public internal::RenderPrimitive>, public internal::LinkedElementCreator> { using RECT_BASE_F::RECT_BASE_F; }; template - struct RECT_T : public RECT_BASE_T, public internal::LinkedElementCreator> { + struct RECT_T : public RECT_BASE_T, public internal::RenderPrimitive>, public internal::LinkedElementCreator> { using RECT_BASE_T::RECT_BASE_T; }; } @@ -77,7 +81,7 @@ namespace JabyEngine { typedef internal::RECT_F TILE_1; typedef internal::RECT_F TILE_8; typedef internal::RECT_F TILE_16; - struct TILE : public internal::RECT_BASE_F, public internal::LinkedElementCreator { + struct TILE : public internal::RECT_BASE_F, public internal::RenderPrimitive, public internal::LinkedElementCreator { SizeI16 size; constexpr TILE() = default; @@ -88,25 +92,13 @@ namespace JabyEngine { typedef internal::RECT_T SPRT_1; typedef internal::RECT_T SPRT_8; typedef internal::RECT_T SPRT_16; - struct SPRT : public internal::RECT_BASE_T, public internal::LinkedElementCreator { + struct SPRT : public internal::RECT_BASE_T, public internal::RenderPrimitive, public internal::LinkedElementCreator { SizeI16 size; constexpr SPRT() = default; constexpr SPRT(const AreaI16& area, const PagePositionClut& page, const Color24& color = Color24::Grey()) : RECT_BASE_T(area.position, page, color), size(area.size) { } }; - - namespace internal { - __jaby_engine_declare_render_primitive(TILE_1); - __jaby_engine_declare_render_primitive(TILE_8); - __jaby_engine_declare_render_primitive(TILE_16); - __jaby_engine_declare_render_primitive(TILE); - - __jaby_engine_declare_render_primitive(SPRT_1); - __jaby_engine_declare_render_primitive(SPRT_8); - __jaby_engine_declare_render_primitive(SPRT_16); - __jaby_engine_declare_render_primitive(SPRT); - } } } diff --git a/include/PSX/GPU/Primitives/primitive_support_types.hpp b/include/PSX/GPU/Primitives/primitive_support_types.hpp index da3f3ae7..85a05381 100644 --- a/include/PSX/GPU/Primitives/primitive_support_types.hpp +++ b/include/PSX/GPU/Primitives/primitive_support_types.hpp @@ -1,7 +1,9 @@ #ifndef __JABYENGINE_PRIMITIVE_SUPPORT_TYPES_HPP__ #define __JABYENGINE_PRIMITIVE_SUPPORT_TYPES_HPP__ -#include "../gpu_types.hpp" +#include "../../Auxiliary/type_traits.hpp" #include "../../System/IOPorts/gpu_io.hpp" +#include "../gpu_types.hpp" + namespace JabyEngine { namespace GPU { @@ -11,7 +13,7 @@ namespace JabyEngine { static constexpr auto BitCorrection = 24; static constexpr auto CmdID = BitRange::from_to(29 - BitCorrection, 31 - BitCorrection); - uint8_t value = bit::value::set_normalized(0u, CmdID.with(T::CmdValue)); + uint8_t value; // Common values for all the primitves static constexpr auto Textured = Bit(26 - BitCorrection); @@ -22,6 +24,8 @@ namespace JabyEngine { static constexpr auto BlendTexture = !NoBlendTexture; constexpr CodeBase() = default; + constexpr CodeBase(uint8_t value) : value(bit::value::set_normalized(0u, CmdID.with(value))) { + } constexpr CodeBase(const T& code) : value(code.value) { } @@ -53,15 +57,13 @@ namespace JabyEngine { }; template - struct is_render_primitive { - static constexpr bool value = false; - }; + struct RenderPrimitive { + static constexpr bool is_render_primitive = true; - #define __jaby_engine_declare_render_primitive(type) \ - template<> \ - struct is_render_primitive { \ - static constexpr bool value = true; \ - } + void set_identitiy() { + static_cast(*this).code = T::IdentityCode; + } + }; } struct PageClut { diff --git a/include/PSX/GPU/gpu.hpp b/include/PSX/GPU/gpu.hpp index 62cf6f15..83540ec7 100644 --- a/include/PSX/GPU/gpu.hpp +++ b/include/PSX/GPU/gpu.hpp @@ -47,12 +47,12 @@ namespace JabyEngine { } template - static enable_if::value>::type render(const T& primitive) { + static enable_if::type render(const T& primitive) { internal::render(reinterpret_cast(&primitive), sizeof(T)/sizeof(uint32_t)); } template - static enable_if::value>::type render(const LINE_F (&primitives)[N]) { + static enable_if::type render(const LINE_F (&primitives)[N]) { internal::render(reinterpret_cast(&primitives), (sizeof(T)/sizeof(uint32_t))*N); } From 378196d422e4a454634b63c61aa5cad856f7c452 Mon Sep 17 00:00:00 2001 From: jaby Date: Wed, 21 Jun 2023 22:36:31 +0200 Subject: [PATCH 050/588] Support simple sentances --- .../src/FontWriter/font_writer.cpp | 77 +++++++++++++++++++ .../src/FontWriter/font_writer.hpp | 14 ++++ examples/PoolBox/application/src/main.cpp | 24 +++--- 3 files changed, 102 insertions(+), 13 deletions(-) create mode 100644 examples/PoolBox/application/src/FontWriter/font_writer.cpp create mode 100644 examples/PoolBox/application/src/FontWriter/font_writer.hpp diff --git a/examples/PoolBox/application/src/FontWriter/font_writer.cpp b/examples/PoolBox/application/src/FontWriter/font_writer.cpp new file mode 100644 index 00000000..1d524acb --- /dev/null +++ b/examples/PoolBox/application/src/FontWriter/font_writer.cpp @@ -0,0 +1,77 @@ +#include "../assets.hpp" +#include "font_writer.hpp" +#include +#include + +namespace FontWriter { + using namespace JabyEngine; + static GPU::TexPage::Linked CharTexPage[2] = { + GPU::TexPage({Assets::FontTIM.get_texture_x(), Assets::FontTIM.get_texture_y()}, GPU::TexturePageColor::$4bit).linked(), + GPU::TexPage({Assets::FontTIM.get_texture_x(), Assets::FontTIM.get_texture_y()}, GPU::TexturePageColor::$4bit).linked() + }; + static GPU::SPRT_16::Linked TextBuffer[2][TextBufferSize]; + static GPU::Link* TextLink; + static GPU::SPRT_16::Linked* TextPtr; + + static void reset_links() { + TextLink = &CharTexPage[GPU::Display::current_id]; + TextPtr = TextBuffer[GPU::Display::current_id]; + } + + void setup() { + reset_links(); + for(auto& char_array : TextBuffer) { + for(auto& single_char : char_array) { + single_char->set_identitiy(); + single_char->clut = GPU::PageClut(Assets::FontTIM.get_clut_x(), Assets::FontTIM.get_clut_y()); + } + } + } + + void write(int16_t x, int16_t y, const char* text) { + const auto* cur_text_end = &TextBuffer[GPU::Display::current_id][TextBufferSize]; + const auto org_x = x; + + while(TextPtr < cur_text_end) { + const char cur_char = *text; + text++; + + (*TextPtr)->position = {x, y}; + switch(cur_char) { + case '\0': + return; + case '\n': + y += 16; + x = org_x; + continue; + + case 'i': + case '!': + x += 12; + break; + + default: + x += 16; + } + + if(cur_char == '\0') { + break; + } + + const uint8_t char_id = cur_char - '!'; + (*TextPtr)->page = {static_cast((char_id & 0xF) << 4), static_cast((char_id >> 4) << 4)}; + (*TextPtr)->color = GPU::Color24::Grey(); + + TextLink = &TextLink->concat(*TextPtr); + TextPtr++; + } + } + + void render() { + const auto render_id = GPU::Display::current_id ^ 1; + + TextLink->terminate(); + GPU::render(CharTexPage[render_id]); + reset_links(); + } +} diff --git a/examples/PoolBox/application/src/FontWriter/font_writer.hpp b/examples/PoolBox/application/src/FontWriter/font_writer.hpp new file mode 100644 index 00000000..372cad4e --- /dev/null +++ b/examples/PoolBox/application/src/FontWriter/font_writer.hpp @@ -0,0 +1,14 @@ +#ifndef __FONT_WRITER_HPP__ +#define __FONT_WRITER_HPP__ +#include + +namespace FontWriter { + static constexpr auto TextBufferSize = 1024; + + void setup(); + + void write(int16_t x, int16_t y, const char* text); + void render(); +} + +#endif //!__FONT_WRITER_HPP__ \ No newline at end of file diff --git a/examples/PoolBox/application/src/main.cpp b/examples/PoolBox/application/src/main.cpp index 277b9103..c792bc21 100644 --- a/examples/PoolBox/application/src/main.cpp +++ b/examples/PoolBox/application/src/main.cpp @@ -1,25 +1,23 @@ +#include "FontWriter/font_writer.hpp" #include "assets.hpp" #include #include #include using namespace JabyEngine; -static auto FontPage = GPU::TexPage({Assets::FontTIM.get_texture_x(), Assets::FontTIM.get_texture_y()}, GPU::TexturePageColor::$4bit).linked(); -static auto FontTest = GPU::SPRT( - GPU::AreaI16({0, 0}, {256, 96}), {GPU::PagePosition(0, 0), GPU::PageClut(Assets::FontTIM.get_clut_x(), Assets::FontTIM.get_clut_y())}, - GPU::Color24::Grey() -).linked(); -static auto FontTestColor = GPU::SPRT( - GPU::AreaI16({0, 96}, {256, 96}), {GPU::PagePosition(0, 0), GPU::PageClut(Assets::FontTIM.get_clut_x(), Assets::FontTIM.get_clut_y())}, - GPU::Color24(0x0, 0x0, 0xA0) -).linked(); + +static void setup() { + Assets::load_for_main(); + FontWriter::setup(); +} void main() { - Assets::load_for_main(); - - FontPage.concat(FontTest).concat(FontTestColor); + setup(); + while(true) { + FontWriter::write(0, 32, "Cody is cute\n&\na BAAAAABY!!!"); + GPU::swap_buffers_vsync(1); - GPU::render(FontPage); + FontWriter::render(); } } \ No newline at end of file From dded028da2b1e23cbfac9a6ce87e563f09004b1c Mon Sep 17 00:00:00 2001 From: jaby Date: Thu, 22 Jun 2023 21:52:34 +0200 Subject: [PATCH 051/588] Support color in text --- .../src/FontWriter/font_writer.cpp | 41 +++++++++++++------ .../src/FontWriter/font_writer.hpp | 7 +++- examples/PoolBox/application/src/main.cpp | 3 +- include/PSX/Auxiliary/types.hpp | 18 ++++++++ 4 files changed, 53 insertions(+), 16 deletions(-) diff --git a/examples/PoolBox/application/src/FontWriter/font_writer.cpp b/examples/PoolBox/application/src/FontWriter/font_writer.cpp index 1d524acb..bf80eb3a 100644 --- a/examples/PoolBox/application/src/FontWriter/font_writer.cpp +++ b/examples/PoolBox/application/src/FontWriter/font_writer.cpp @@ -28,43 +28,58 @@ namespace FontWriter { } } - void write(int16_t x, int16_t y, const char* text) { + Position write(Position pos, const char* text) { + static const auto parse_esc = [](const char* text, const GPU::Color24& color) -> pair { + static const auto char_to_color = [](char number) constexpr -> uint8_t { + return (1 << (number - '0')) - 1; + }; + if(text[0] != '[' || text[2] != ';' || text[4] != ';' || text[6] != 'm') { + return {text, color}; + } + + return {text + 7, GPU::Color24(char_to_color(text[1]), char_to_color(text[3]), char_to_color(text[5]))}; + }; const auto* cur_text_end = &TextBuffer[GPU::Display::current_id][TextBufferSize]; - const auto org_x = x; + const auto org_x = pos.x; + auto font_color = GPU::Color24::Grey(); while(TextPtr < cur_text_end) { const char cur_char = *text; text++; - (*TextPtr)->position = {x, y}; + (*TextPtr)->position = pos; switch(cur_char) { case '\0': - return; + goto end; + case '\n': - y += 16; - x = org_x; + pos.y += 16; + pos.x = org_x; continue; + case '\x1b': + tie(text, font_color) = parse_esc(text, font_color); + continue; + case 'i': case '!': - x += 12; + pos.x += 12; break; default: - x += 16; - } - - if(cur_char == '\0') { - break; + pos.x += 16; } const uint8_t char_id = cur_char - '!'; (*TextPtr)->page = {static_cast((char_id & 0xF) << 4), static_cast((char_id >> 4) << 4)}; - (*TextPtr)->color = GPU::Color24::Grey(); + (*TextPtr)->color = font_color; TextLink = &TextLink->concat(*TextPtr); TextPtr++; } + + end: + return pos; } void render() { diff --git a/examples/PoolBox/application/src/FontWriter/font_writer.hpp b/examples/PoolBox/application/src/FontWriter/font_writer.hpp index 372cad4e..8df03c4e 100644 --- a/examples/PoolBox/application/src/FontWriter/font_writer.hpp +++ b/examples/PoolBox/application/src/FontWriter/font_writer.hpp @@ -1,14 +1,17 @@ #ifndef __FONT_WRITER_HPP__ #define __FONT_WRITER_HPP__ +#include #include namespace FontWriter { + using Position = JabyEngine::GPU::PositionI16; + static constexpr auto TextBufferSize = 1024; void setup(); - void write(int16_t x, int16_t y, const char* text); - void render(); + Position write(Position pos, const char* text); + void render(); } #endif //!__FONT_WRITER_HPP__ \ No newline at end of file diff --git a/examples/PoolBox/application/src/main.cpp b/examples/PoolBox/application/src/main.cpp index c792bc21..1f8d9abc 100644 --- a/examples/PoolBox/application/src/main.cpp +++ b/examples/PoolBox/application/src/main.cpp @@ -15,7 +15,8 @@ void main() { setup(); while(true) { - FontWriter::write(0, 32, "Cody is cute\n&\na BAAAAABY!!!"); + const auto end_pos = FontWriter::write({0, 32}, "Cody is cute\n&\na \x1b[8;0;0mBAAAAABY!!!"); + FontWriter::write(end_pos, "\x1b[0;7;7mJaby was\nhere c:"); GPU::swap_buffers_vsync(1); FontWriter::render(); diff --git a/include/PSX/Auxiliary/types.hpp b/include/PSX/Auxiliary/types.hpp index 0bcd6a34..38de46fb 100644 --- a/include/PSX/Auxiliary/types.hpp +++ b/include/PSX/Auxiliary/types.hpp @@ -8,6 +8,24 @@ namespace JabyEngine { S second; }; + template + struct cplx_pair { + T first; + S second; + + template + constexpr cplx_pair& operator=(const pair& obj) { + this->first = obj.first; + this->second = obj.second; + return *this; + } + }; + + template + constexpr cplx_pair tie(Args&... args) { + return {args...}; + } + enum struct Progress { InProgress = 0, Done, From 1a54249a29fa8ca3e7ebe03d7e4b0a9ee1e7ad47 Mon Sep 17 00:00:00 2001 From: jaby Date: Sun, 25 Jun 2023 14:37:16 +0200 Subject: [PATCH 052/588] Create readmap tool --- src/Tools/readmap/Cargo.toml | 8 ++++++++ src/Tools/readmap/src/lib.rs | 14 ++++++++++++++ src/Tools/readmap/src/main.rs | 0 3 files changed, 22 insertions(+) create mode 100644 src/Tools/readmap/Cargo.toml create mode 100644 src/Tools/readmap/src/lib.rs create mode 100644 src/Tools/readmap/src/main.rs diff --git a/src/Tools/readmap/Cargo.toml b/src/Tools/readmap/Cargo.toml new file mode 100644 index 00000000..7788a76d --- /dev/null +++ b/src/Tools/readmap/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "readmap" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/src/Tools/readmap/src/lib.rs b/src/Tools/readmap/src/lib.rs new file mode 100644 index 00000000..7d12d9af --- /dev/null +++ b/src/Tools/readmap/src/lib.rs @@ -0,0 +1,14 @@ +pub fn add(left: usize, right: usize) -> usize { + left + right +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn it_works() { + let result = add(2, 2); + assert_eq!(result, 4); + } +} diff --git a/src/Tools/readmap/src/main.rs b/src/Tools/readmap/src/main.rs new file mode 100644 index 00000000..e69de29b From 660faeb1a2605cde8431784e4b0882bf878b7806 Mon Sep 17 00:00:00 2001 From: jaby Date: Sun, 25 Jun 2023 15:58:23 +0200 Subject: [PATCH 053/588] Introduce types for readmap --- src/Tools/Tools.code-workspace | 2 +- src/Tools/readmap/Cargo.toml | 2 ++ src/Tools/readmap/src/lib.rs | 16 ++++------- src/Tools/readmap/src/main.rs | 31 ++++++++++++++++++++ src/Tools/readmap/src/types/mod.rs | 45 ++++++++++++++++++++++++++++++ 5 files changed, 84 insertions(+), 12 deletions(-) create mode 100644 src/Tools/readmap/src/types/mod.rs diff --git a/src/Tools/Tools.code-workspace b/src/Tools/Tools.code-workspace index a1732433..dd890969 100644 --- a/src/Tools/Tools.code-workspace +++ b/src/Tools/Tools.code-workspace @@ -59,7 +59,7 @@ { "id": "project", "type": "pickString", - "options": ["cdtypes", "cpp_out", "jaby_engine_fconv", "mkoverlay", "psxcdgen", "psxcdgen_ex", "psxcdread", "tool_helper", "wslpath"], + "options": ["cdtypes", "cpp_out", "jaby_engine_fconv", "mkoverlay", "psxcdgen", "psxcdgen_ex", "psxcdread", "readmap", "tool_helper", "wslpath"], "description": "project to build" }, { diff --git a/src/Tools/readmap/Cargo.toml b/src/Tools/readmap/Cargo.toml index 7788a76d..2dc9112b 100644 --- a/src/Tools/readmap/Cargo.toml +++ b/src/Tools/readmap/Cargo.toml @@ -6,3 +6,5 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +clap = {version = "*", features = ["derive"]} +tool_helper = {path = "../tool_helper"} \ No newline at end of file diff --git a/src/Tools/readmap/src/lib.rs b/src/Tools/readmap/src/lib.rs index 7d12d9af..0b8d4e9c 100644 --- a/src/Tools/readmap/src/lib.rs +++ b/src/Tools/readmap/src/lib.rs @@ -1,14 +1,8 @@ -pub fn add(left: usize, right: usize) -> usize { - left + right -} +pub mod types; -#[cfg(test)] -mod tests { - use super::*; +use tool_helper::{Error, Input}; +use types::Section; - #[test] - fn it_works() { - let result = add(2, 2); - assert_eq!(result, 4); - } +pub fn scan(input: Input) -> Result, Error> { + Err(Error::not_implemented("readmap::scan")) } diff --git a/src/Tools/readmap/src/main.rs b/src/Tools/readmap/src/main.rs index e69de29b..bbc4b0e9 100644 --- a/src/Tools/readmap/src/main.rs +++ b/src/Tools/readmap/src/main.rs @@ -0,0 +1,31 @@ +use clap::Parser; +use tool_helper::{Error, exit_with_error}; +use std::path::PathBuf; + +#[derive(Parser)] +#[clap(about = "Opens and scans a MAP file to print extended information", long_about = None)] +struct CommandLine { + #[clap(value_parser, help="Input MAP file for scannning")] + input: Option +} + +fn run_main(cmd: CommandLine) -> Result<(), Error> { + let _sections = readmap::scan(tool_helper::open_input(cmd.input)?)?; + + println!("Found sections!"); + Ok(()) +} + +pub fn main() { + match CommandLine::try_parse() { + Ok(cmd_line) => { + match run_main(cmd_line) { + Ok(_) => (), + Err(error) => exit_with_error(error) + } + }, + Err(error) => { + exit_with_error(Error::from_error(error)); + } + } +} \ No newline at end of file diff --git a/src/Tools/readmap/src/types/mod.rs b/src/Tools/readmap/src/types/mod.rs new file mode 100644 index 00000000..d599e196 --- /dev/null +++ b/src/Tools/readmap/src/types/mod.rs @@ -0,0 +1,45 @@ +use std::default::Default; + +#[derive(Default)] +pub struct Section { + name: String, + adr: u64, + size: usize, + content: Vec +} + +#[derive(Default)] +pub struct Symbol { + name: String, + adr: u64, +} + +#[derive(Default)] +pub struct Fill { + adr: u64, + size: usize, +} + +pub enum Content { + Fill, + Section(Section), + Symbol(Symbol), +} + +impl Section { + pub fn new(name: String, adr: u64, size: usize) -> Section { + Section{name, adr, size, content: Vec::new()} + } +} + +impl Symbol { + pub fn new(name: String, adr: u64) -> Symbol { + Symbol{name, adr} + } +} + +impl Fill { + pub fn new(adr: u64, size: usize) -> Fill { + Fill{adr, size} + } +} \ No newline at end of file From 5937bbd7635b462cb158206d0321e8d3b949b54d Mon Sep 17 00:00:00 2001 From: jaby Date: Sun, 25 Jun 2023 16:38:29 +0200 Subject: [PATCH 054/588] Detect sections; Unify printing help across the tools --- src/Tools/Tools.code-workspace | 7 ++++++- src/Tools/cpp_out/src/main.rs | 2 +- src/Tools/jaby_engine_fconv/src/main.rs | 2 +- src/Tools/mkoverlay/src/main.rs | 2 +- src/Tools/psxcdgen_ex/src/main.rs | 2 +- src/Tools/readmap/src/lib.rs | 9 +++++++++ src/Tools/readmap/src/main.rs | 2 +- src/Tools/tool_helper/src/lib.rs | 4 ++-- src/Tools/wslpath/src/main.rs | 2 +- 9 files changed, 23 insertions(+), 9 deletions(-) diff --git a/src/Tools/Tools.code-workspace b/src/Tools/Tools.code-workspace index dd890969..aed8c246 100644 --- a/src/Tools/Tools.code-workspace +++ b/src/Tools/Tools.code-workspace @@ -78,7 +78,12 @@ { "id": "cargo run args", "type": "pickString", - "options": ["", "--help", "--list -o ../Tests/Test_Planschbecken psx bin-cue ../Tests/ISO_Planschbecken.xml"], + "options": [ + "", + "--help", + "--list -o ../Tests/Test_Planschbecken psx bin-cue ../Tests/ISO_Planschbecken.xml", + "${workspaceFolder}/../../examples/PoolBox/application/bin/PSX-release/PoolBox.map" + ], "default": "", "description": "Argument options to pass to cargo run" } diff --git a/src/Tools/cpp_out/src/main.rs b/src/Tools/cpp_out/src/main.rs index 819fbe71..2c21a29f 100644 --- a/src/Tools/cpp_out/src/main.rs +++ b/src/Tools/cpp_out/src/main.rs @@ -47,6 +47,6 @@ fn main() { exit_with_error(error) } }, - Err(error) => eprintln!("{}", error) + Err(error) => println!("{}", error) } } \ No newline at end of file diff --git a/src/Tools/jaby_engine_fconv/src/main.rs b/src/Tools/jaby_engine_fconv/src/main.rs index 8605bc01..6c43534b 100644 --- a/src/Tools/jaby_engine_fconv/src/main.rs +++ b/src/Tools/jaby_engine_fconv/src/main.rs @@ -64,6 +64,6 @@ fn main() { exit_with_error(error); } }, - Err(error) => eprintln!("{}", error) + Err(error) => println!("{}", error) } } \ No newline at end of file diff --git a/src/Tools/mkoverlay/src/main.rs b/src/Tools/mkoverlay/src/main.rs index f7fd6224..a0997b86 100644 --- a/src/Tools/mkoverlay/src/main.rs +++ b/src/Tools/mkoverlay/src/main.rs @@ -45,7 +45,7 @@ fn main() { } }, Err(error) => { - exit_with_error(Error::from_error(error)); + println!("{}", error) } } } \ No newline at end of file diff --git a/src/Tools/psxcdgen_ex/src/main.rs b/src/Tools/psxcdgen_ex/src/main.rs index cf1a4a49..186e7790 100644 --- a/src/Tools/psxcdgen_ex/src/main.rs +++ b/src/Tools/psxcdgen_ex/src/main.rs @@ -60,7 +60,7 @@ fn main() { } }, Err(error) => { - eprintln!("{}", error) + println!("{}", error) } } } \ No newline at end of file diff --git a/src/Tools/readmap/src/lib.rs b/src/Tools/readmap/src/lib.rs index 0b8d4e9c..e1bf80e3 100644 --- a/src/Tools/readmap/src/lib.rs +++ b/src/Tools/readmap/src/lib.rs @@ -1,8 +1,17 @@ pub mod types; use tool_helper::{Error, Input}; +use std::io::BufRead; use types::Section; pub fn scan(input: Input) -> Result, Error> { + let lines = input.lines().map(|l| l.unwrap()); + + for line in lines { + if line.starts_with('.') { + println!("Found section \"{}\"", line); + } + } + Err(Error::not_implemented("readmap::scan")) } diff --git a/src/Tools/readmap/src/main.rs b/src/Tools/readmap/src/main.rs index bbc4b0e9..99045765 100644 --- a/src/Tools/readmap/src/main.rs +++ b/src/Tools/readmap/src/main.rs @@ -25,7 +25,7 @@ pub fn main() { } }, Err(error) => { - exit_with_error(Error::from_error(error)); + println!("{}", error) } } } \ No newline at end of file diff --git a/src/Tools/tool_helper/src/lib.rs b/src/Tools/tool_helper/src/lib.rs index 59a6075c..12d8c1a6 100644 --- a/src/Tools/tool_helper/src/lib.rs +++ b/src/Tools/tool_helper/src/lib.rs @@ -1,6 +1,6 @@ use colored::*; use envmnt::{ExpandOptions, ExpansionType}; -use std::{boxed::Box, io::{BufReader, BufWriter, Read, Write}, path::PathBuf}; +use std::{boxed::Box, io::{BufRead, BufReader, BufWriter, Read, Write}, path::PathBuf}; pub mod bits; pub mod compress; @@ -8,7 +8,7 @@ pub mod raw; pub type BufferedInputFile = BufReader; pub type Output = Box; -pub type Input = Box; +pub type Input = Box; #[macro_export] macro_rules! format_if_error { diff --git a/src/Tools/wslpath/src/main.rs b/src/Tools/wslpath/src/main.rs index c9f05efe..18017545 100644 --- a/src/Tools/wslpath/src/main.rs +++ b/src/Tools/wslpath/src/main.rs @@ -13,7 +13,7 @@ fn main() { print!("{}", wslpath::convert(cmd_line.path_string)); }, Err(error) => { - eprintln!("{}", error); + println!("{}", error); } } } \ No newline at end of file From 63aa467962dc37ad6c3bf899ded7ca2de8464e8e Mon Sep 17 00:00:00 2001 From: jaby Date: Sun, 25 Jun 2023 16:39:07 +0200 Subject: [PATCH 055/588] Missed cmmits --- examples/PoolBox/application/Makefile | 2 +- include/PSX/GPU/Primitives/primitive_rectangle_types.hpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/PoolBox/application/Makefile b/examples/PoolBox/application/Makefile index efce152f..71f4711e 100644 --- a/examples/PoolBox/application/Makefile +++ b/examples/PoolBox/application/Makefile @@ -7,7 +7,7 @@ include $(JABY_ENGINE_DIR)/lib/Wildcard.mk SRCS = $(call rwildcard, src, c cpp) INCLUDES += -I$(JABY_ENGINE_DIR)/include -#CCFLAGS += -save-temps=obj +CCFLAGS += -save-temps=obj include $(JABY_ENGINE_DIR)/lib/Makefile include $(JABY_ENGINE_DIR)/lib/PSEXETarget.mk diff --git a/include/PSX/GPU/Primitives/primitive_rectangle_types.hpp b/include/PSX/GPU/Primitives/primitive_rectangle_types.hpp index 6e82efa0..48547ca7 100644 --- a/include/PSX/GPU/Primitives/primitive_rectangle_types.hpp +++ b/include/PSX/GPU/Primitives/primitive_rectangle_types.hpp @@ -43,7 +43,7 @@ namespace JabyEngine { static constexpr auto IdentityCode = Code::create().set(Code::Size.with(static_cast(Size))).set(Code::Untextured).set(Code::NonTransparent); Color24 color; - Code code = IdentityCode; + Code code; Vertex position; constexpr RECT_BASE_F() = default; @@ -57,7 +57,7 @@ namespace JabyEngine { static constexpr auto IdentityCode = Code(RECT_BASE_F::IdentityCode).set(Code::Textured); Color24 color; - Code code = IdentityCode; + Code code; Vertex position; PagePosition page; PageClut clut; From 75ab477fff4bc0b2137e2436edfa8b9f4fe981b3 Mon Sep 17 00:00:00 2001 From: jaby Date: Mon, 26 Jun 2023 20:40:30 +0200 Subject: [PATCH 056/588] Make Linked elements BSS conform --- .../src/FontWriter/font_writer.cpp | 1 + .../PSX/GPU/Primitives/linked_elements.hpp | 22 ++++++++++++++----- include/PSX/GPU/gpu.hpp | 2 +- 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/examples/PoolBox/application/src/FontWriter/font_writer.cpp b/examples/PoolBox/application/src/FontWriter/font_writer.cpp index bf80eb3a..9f0705b3 100644 --- a/examples/PoolBox/application/src/FontWriter/font_writer.cpp +++ b/examples/PoolBox/application/src/FontWriter/font_writer.cpp @@ -22,6 +22,7 @@ namespace FontWriter { reset_links(); for(auto& char_array : TextBuffer) { for(auto& single_char : char_array) { + single_char.set_link_identitiy(); single_char->set_identitiy(); single_char->clut = GPU::PageClut(Assets::FontTIM.get_clut_x(), Assets::FontTIM.get_clut_y()); } diff --git a/include/PSX/GPU/Primitives/linked_elements.hpp b/include/PSX/GPU/Primitives/linked_elements.hpp index 45c8f49e..b9bb661a 100644 --- a/include/PSX/GPU/Primitives/linked_elements.hpp +++ b/include/PSX/GPU/Primitives/linked_elements.hpp @@ -10,18 +10,26 @@ namespace JabyEngine { static constexpr uint32_t TerminationValue = 0x00FFFFFF; - uint32_t value = TerminationValue; + static constexpr uint32_t default_link_value(size_t size) { + return SizeRange.as_value(size >> 2) | TerminationValue; + } + + uint32_t link_value; constexpr Link() = default; - constexpr Link(size_t size) : value(SizeRange.as_value(size >> 2) | TerminationValue) { + constexpr Link(size_t size) : link_value(default_link_value(size)) { + } + + constexpr void set_link_identitiy(size_t size) { + this->link_value = default_link_value(size); } void set_adr(const void* adr) { - this->value = bit::value::set_normalized(this->value, AdrRange.with(reinterpret_cast(adr))); + this->link_value = bit::value::set_normalized(this->link_value, AdrRange.with(reinterpret_cast(adr))); } void* get_adr() const { - return reinterpret_cast(bit::value::get_normalized(this->value, AdrRange)); + return reinterpret_cast(bit::value::get_normalized(this->link_value, AdrRange)); } template @@ -45,7 +53,7 @@ namespace JabyEngine { } constexpr void terminate() { - this->value |= TerminationValue; + this->link_value |= TerminationValue; } }; @@ -59,6 +67,10 @@ namespace JabyEngine { constexpr LinkedElement(const T& element) : Link(sizeof(T)), element(element) { } + constexpr void set_link_identitiy() { + Link::set_link_identitiy(sizeof(T)); + } + constexpr const T* operator->() const { return &this->element; } diff --git a/include/PSX/GPU/gpu.hpp b/include/PSX/GPU/gpu.hpp index 83540ec7..2bc00fff 100644 --- a/include/PSX/GPU/gpu.hpp +++ b/include/PSX/GPU/gpu.hpp @@ -43,7 +43,7 @@ namespace JabyEngine { template static void render(const LinkedElement& linked_primitives) { - internal::render_dma(&linked_primitives.value); + internal::render_dma(&linked_primitives.link_value); } template From ef233d5d07532736b540bce9f7f2cbdbbe736a7e Mon Sep 17 00:00:00 2001 From: jaby Date: Thu, 29 Jun 2023 20:18:02 +0200 Subject: [PATCH 057/588] Print top-level sections --- src/Tools/readmap/src/lib.rs | 52 +++++++++++++++++++++++++----- src/Tools/readmap/src/types/mod.rs | 10 +++--- 2 files changed, 49 insertions(+), 13 deletions(-) diff --git a/src/Tools/readmap/src/lib.rs b/src/Tools/readmap/src/lib.rs index e1bf80e3..396edc04 100644 --- a/src/Tools/readmap/src/lib.rs +++ b/src/Tools/readmap/src/lib.rs @@ -2,16 +2,52 @@ pub mod types; use tool_helper::{Error, Input}; use std::io::BufRead; -use types::Section; +use types::{Section}; pub fn scan(input: Input) -> Result, Error> { - let lines = input.lines().map(|l| l.unwrap()); - - for line in lines { - if line.starts_with('.') { - println!("Found section \"{}\"", line); - } - } + process(input.lines().map(|l| l.unwrap()).into_iter()); Err(Error::not_implemented("readmap::scan")) } + +fn process>(mut line_iter:F) { + while let Some(line) = line_iter.next() { + if line.starts_with(".") { + process_section(line, &mut line_iter); + } + } +} + +macro_rules! force_next { + ($split_line:ident, $line_iter:ident, $line:ident) => { + { + if let Some(value) = $split_line.next() { + value + } + + else { + $line = $line_iter.next().unwrap(); + $split_line = $line.split_whitespace(); + + $split_line.next().unwrap() + } + } + }; +} + +fn process_section>(mut line: String, line_iter:&mut F) { + let mut split_line = line.split_whitespace(); + let name = split_line.next().unwrap().to_string(); + let adr = u64::from_str_radix(force_next!(split_line, line_iter, line).trim_start_matches("0x"), 16).ok(); + let size = { // If adr is already empty we do not need to check for a size + if adr.is_some() { + usize::from_str_radix(force_next!(split_line, line_iter, line).trim_start_matches("0x"), 16).ok() + } + + else { + None + } + }; + + println!("Section: {} @{:?} {:?}", name, adr, size); +} \ No newline at end of file diff --git a/src/Tools/readmap/src/types/mod.rs b/src/Tools/readmap/src/types/mod.rs index d599e196..e2976a2f 100644 --- a/src/Tools/readmap/src/types/mod.rs +++ b/src/Tools/readmap/src/types/mod.rs @@ -2,10 +2,10 @@ use std::default::Default; #[derive(Default)] pub struct Section { - name: String, - adr: u64, - size: usize, - content: Vec + pub name: String, + pub adr: Option, + pub size: Option, + pub content: Vec } #[derive(Default)] @@ -27,7 +27,7 @@ pub enum Content { } impl Section { - pub fn new(name: String, adr: u64, size: usize) -> Section { + pub fn new(name: String, adr: Option, size: Option) -> Section { Section{name, adr, size, content: Vec::new()} } } From a77c8aae8d2fced17b12fa12def1092a1e256e66 Mon Sep 17 00:00:00 2001 From: jaby Date: Thu, 29 Jun 2023 21:32:49 +0200 Subject: [PATCH 058/588] Improve reading sections in --- src/Tools/readmap/Cargo.toml | 1 + src/Tools/readmap/src/lib.rs | 74 +++++++++++++++++++++--------------- 2 files changed, 45 insertions(+), 30 deletions(-) diff --git a/src/Tools/readmap/Cargo.toml b/src/Tools/readmap/Cargo.toml index 2dc9112b..be1a86cc 100644 --- a/src/Tools/readmap/Cargo.toml +++ b/src/Tools/readmap/Cargo.toml @@ -7,4 +7,5 @@ edition = "2021" [dependencies] clap = {version = "*", features = ["derive"]} +num-traits = "*" tool_helper = {path = "../tool_helper"} \ No newline at end of file diff --git a/src/Tools/readmap/src/lib.rs b/src/Tools/readmap/src/lib.rs index 396edc04..fe547c15 100644 --- a/src/Tools/readmap/src/lib.rs +++ b/src/Tools/readmap/src/lib.rs @@ -5,49 +5,63 @@ use std::io::BufRead; use types::{Section}; pub fn scan(input: Input) -> Result, Error> { - process(input.lines().map(|l| l.unwrap()).into_iter()); + process(input.lines().map(|l| l.unwrap()).into_iter())?; Err(Error::not_implemented("readmap::scan")) } -fn process>(mut line_iter:F) { +fn process>(mut line_iter:F) -> Result<(), Error> { while let Some(line) = line_iter.next() { if line.starts_with(".") { - process_section(line, &mut line_iter); + process_section(line, &mut line_iter)?; } } + + Ok(()) } -macro_rules! force_next { - ($split_line:ident, $line_iter:ident, $line:ident) => { - { - if let Some(value) = $split_line.next() { - value - } - - else { - $line = $line_iter.next().unwrap(); - $split_line = $line.split_whitespace(); - - $split_line.next().unwrap() - } - } - }; +fn process_section>(line: String, line_iter:&mut F) -> Result<(), Error> { + let (section, _line) = read_section(line, || { + line_iter.next().ok_or(Error::from_str("")) + })?; + + println!("Section: {} @{:?} {:?}", section.name, section.adr, section.size); + Ok(()) } -fn process_section>(mut line: String, line_iter:&mut F) { +fn read_section Result>(mut line: String, mut next_line: F) -> Result<(Section, Option), Error> { let mut split_line = line.split_whitespace(); - let name = split_line.next().unwrap().to_string(); - let adr = u64::from_str_radix(force_next!(split_line, line_iter, line).trim_start_matches("0x"), 16).ok(); - let size = { // If adr is already empty we do not need to check for a size - if adr.is_some() { - usize::from_str_radix(force_next!(split_line, line_iter, line).trim_start_matches("0x"), 16).ok() - } + let name = split_line.next().ok_or(Error::from_str(""))?.to_string(); + let need_new_line = name.chars().count() > 16; - else { - None - } - }; + if need_new_line { + line = next_line()?; + split_line = line.split_whitespace(); + } - println!("Section: {} @{:?} {:?}", name, adr, size); + let adr = read_as::(split_line.next()); + if adr.is_none() { + return Ok((Section::new(name, None, None), { + if need_new_line { + Some(line) + } + + else { + None + } + })); + } + + let size = read_as::(split_line.next()); + Ok((Section::new(name, adr, size), None)) +} + +fn read_as(str: Option<&str>) -> Option { + if let Some(str) = str { + F::from_str_radix(str.trim_start_matches("0x"), 16).ok() + } + + else { + None + } } \ No newline at end of file From 3133b03759f192d1c90a2457c6ea3817670620e4 Mon Sep 17 00:00:00 2001 From: jaby Date: Thu, 29 Jun 2023 22:18:31 +0200 Subject: [PATCH 059/588] Parse sub section --- src/Tools/readmap/src/lib.rs | 60 ++++++++++++++++++++++++++++++------ 1 file changed, 50 insertions(+), 10 deletions(-) diff --git a/src/Tools/readmap/src/lib.rs b/src/Tools/readmap/src/lib.rs index fe547c15..aeca727d 100644 --- a/src/Tools/readmap/src/lib.rs +++ b/src/Tools/readmap/src/lib.rs @@ -11,27 +11,67 @@ pub fn scan(input: Input) -> Result, Error> { } fn process>(mut line_iter:F) -> Result<(), Error> { - while let Some(line) = line_iter.next() { - if line.starts_with(".") { - process_section(line, &mut line_iter)?; + while let Some(mut line) = line_iter.next() { + loop { + if line.starts_with(".") { + line = process_section(line, &mut line_iter)?; + } + + else { + break; + } } } Ok(()) } -fn process_section>(line: String, line_iter:&mut F) -> Result<(), Error> { - let (section, _line) = read_section(line, || { - line_iter.next().ok_or(Error::from_str("")) - })?; +fn process_section>(line: String, line_iter:&mut F) -> Result { + let mut next_line_closure = || { + line_iter.next().ok_or(Error::from_str("Unexpected end of file")) + }; + let (mut section, line) = read_section(line, &mut next_line_closure)?; println!("Section: {} @{:?} {:?}", section.name, section.adr, section.size); - Ok(()) + process_subsection(&mut section, line, &mut next_line_closure) } -fn read_section Result>(mut line: String, mut next_line: F) -> Result<(Section, Option), Error> { +fn process_subsection Result>(_section: &mut Section, line: Option, next_line: &mut F) -> Result { + let mut line = { + if let Some(line) = line { + line + } + + else { + next_line()? + } + }; + + loop { + if line.starts_with(" .") { + println!(">>> SubSection: {}", line); + } + + else if line.is_empty() { + return Ok(line); + } + + line = { + if let Ok(line) = next_line() { + line + } + + else { + // EOF + return Ok(String::from("")); + } + }; + } +} + +fn read_section Result>(mut line: String, next_line: &mut F) -> Result<(Section, Option), Error> { let mut split_line = line.split_whitespace(); - let name = split_line.next().ok_or(Error::from_str(""))?.to_string(); + let name = split_line.next().ok_or(Error::from_str("Couldn't locate section name"))?.to_string(); let need_new_line = name.chars().count() > 16; if need_new_line { From eb34dd2e451e4dfdd5da1ee7a40c2a67beb44414 Mon Sep 17 00:00:00 2001 From: jaby Date: Mon, 3 Jul 2023 22:17:44 +0200 Subject: [PATCH 060/588] Read sub sections --- src/Tools/readmap/src/lib.rs | 66 +++++++++++++++++++++--------- src/Tools/readmap/src/types/mod.rs | 5 ++- 2 files changed, 50 insertions(+), 21 deletions(-) diff --git a/src/Tools/readmap/src/lib.rs b/src/Tools/readmap/src/lib.rs index aeca727d..f66a5dba 100644 --- a/src/Tools/readmap/src/lib.rs +++ b/src/Tools/readmap/src/lib.rs @@ -2,7 +2,7 @@ pub mod types; use tool_helper::{Error, Input}; use std::io::BufRead; -use types::{Section}; +use types::{Content, Section}; pub fn scan(input: Input) -> Result, Error> { process(input.lines().map(|l| l.unwrap()).into_iter())?; @@ -32,11 +32,16 @@ fn process_section>(line: String, line_iter: }; let (mut section, line) = read_section(line, &mut next_line_closure)?; - println!("Section: {} @{:?} {:?}", section.name, section.adr, section.size); + println!("Section: {} @{:?} {:?} \"{:?}\"", section.name, section.adr, section.size, section.file); process_subsection(&mut section, line, &mut next_line_closure) } -fn process_subsection Result>(_section: &mut Section, line: Option, next_line: &mut F) -> Result { +fn process_subsection Result>(section: &mut Section, line: Option, next_line: &mut F) -> Result { + fn push_sub_section(section: &mut Section, sub_section: Option
) { + if let Some(sub_section) = sub_section { + section.content.push(Content::Section(sub_section)); + } + } let mut line = { if let Some(line) = line { line @@ -47,25 +52,39 @@ fn process_subsection Result>(_section: &mut Section, } }; - loop { - if line.starts_with(" .") { - println!(">>> SubSection: {}", line); - } - - else if line.is_empty() { + let mut next_line_closure = || -> Result { + if let Ok(line) = next_line() { return Ok(line); } - line = { - if let Ok(line) = next_line() { - line - } + else { + // EOF + return Ok(String::from("")); + } + }; - else { - // EOF - return Ok(String::from("")); + let mut sub_section = None; + + loop { + if line.starts_with(" .") { + push_sub_section(section, sub_section); + let (section, new_line) = read_section(line, &mut next_line_closure)?; + + println!("\t>>>>> {:?} {:?} {:?} {:?}", section.name, section.adr, section.size, section.file); + sub_section = Some(section); + + if let Some(new_line) = new_line { + line = new_line; + continue; } - }; + } + + else if line.is_empty() { + push_sub_section(section, sub_section); + return Ok(line); + } + + line = next_line_closure()?; } } @@ -81,7 +100,7 @@ fn read_section Result>(mut line: String, next_line: let adr = read_as::(split_line.next()); if adr.is_none() { - return Ok((Section::new(name, None, None), { + return Ok((Section::new(name, None, None, None), { if need_new_line { Some(line) } @@ -93,7 +112,16 @@ fn read_section Result>(mut line: String, next_line: } let size = read_as::(split_line.next()); - Ok((Section::new(name, adr, size), None)) + let file = { + if let Some(file) = split_line.next() { + Some(file.to_string()) + } + + else { + None + } + }; + Ok((Section::new(name, adr, size, file), None)) } fn read_as(str: Option<&str>) -> Option { diff --git a/src/Tools/readmap/src/types/mod.rs b/src/Tools/readmap/src/types/mod.rs index e2976a2f..03b06a44 100644 --- a/src/Tools/readmap/src/types/mod.rs +++ b/src/Tools/readmap/src/types/mod.rs @@ -5,6 +5,7 @@ pub struct Section { pub name: String, pub adr: Option, pub size: Option, + pub file: Option, pub content: Vec } @@ -27,8 +28,8 @@ pub enum Content { } impl Section { - pub fn new(name: String, adr: Option, size: Option) -> Section { - Section{name, adr, size, content: Vec::new()} + pub fn new(name: String, adr: Option, size: Option, file: Option) -> Section { + Section{name, adr, size, file, content: Vec::new()} } } From 26ea6c38383ba5fafcd567cdb60666d6fe17d897 Mon Sep 17 00:00:00 2001 From: jaby Date: Tue, 4 Jul 2023 21:58:15 +0200 Subject: [PATCH 061/588] Read in map file --- src/Tools/readmap/src/lib.rs | 64 +++++++++++++++++++++++++----- src/Tools/readmap/src/types/mod.rs | 10 ++--- 2 files changed, 59 insertions(+), 15 deletions(-) diff --git a/src/Tools/readmap/src/lib.rs b/src/Tools/readmap/src/lib.rs index f66a5dba..83c7c243 100644 --- a/src/Tools/readmap/src/lib.rs +++ b/src/Tools/readmap/src/lib.rs @@ -5,16 +5,20 @@ use std::io::BufRead; use types::{Content, Section}; pub fn scan(input: Input) -> Result, Error> { - process(input.lines().map(|l| l.unwrap()).into_iter())?; + let sections = process(input.lines().map(|l| l.unwrap()).into_iter())?; - Err(Error::not_implemented("readmap::scan")) + Ok(sections) } -fn process>(mut line_iter:F) -> Result<(), Error> { +fn process>(mut line_iter:F) -> Result, Error> { + let mut sections = Vec::new(); while let Some(mut line) = line_iter.next() { loop { if line.starts_with(".") { - line = process_section(line, &mut line_iter)?; + let (new_line, new_section) = process_section(line, &mut line_iter)?; + + sections.push(new_section); + line = new_line; } else { @@ -23,17 +27,16 @@ fn process>(mut line_iter:F) -> Result<(), E } } - Ok(()) + Ok(sections) } -fn process_section>(line: String, line_iter:&mut F) -> Result { +fn process_section>(line: String, line_iter:&mut F) -> Result<(String, Section), Error> { let mut next_line_closure = || { line_iter.next().ok_or(Error::from_str("Unexpected end of file")) }; let (mut section, line) = read_section(line, &mut next_line_closure)?; - println!("Section: {} @{:?} {:?} \"{:?}\"", section.name, section.adr, section.size, section.file); - process_subsection(&mut section, line, &mut next_line_closure) + Ok((process_subsection(&mut section, line, &mut next_line_closure)?, section)) } fn process_subsection Result>(section: &mut Section, line: Option, next_line: &mut F) -> Result { @@ -42,6 +45,18 @@ fn process_subsection Result>(section: &mut Section, section.content.push(Content::Section(sub_section)); } } + fn add_element(sub_section: Option
, section: &mut Section, value: T, callback: fn(&mut Section, T)) -> Option
{ + if let Some(mut sub_section) = sub_section { + callback(&mut sub_section, value); + Some(sub_section) + } + + else { + callback(section, value); + None + } + } + let mut line = { if let Some(line) = line { line @@ -69,8 +84,7 @@ fn process_subsection Result>(section: &mut Section, if line.starts_with(" .") { push_sub_section(section, sub_section); let (section, new_line) = read_section(line, &mut next_line_closure)?; - - println!("\t>>>>> {:?} {:?} {:?} {:?}", section.name, section.adr, section.size, section.file); + sub_section = Some(section); if let Some(new_line) = new_line { @@ -79,6 +93,20 @@ fn process_subsection Result>(section: &mut Section, } } + else if line.starts_with(" *fill*") { + let fill = read_fill(line)?; + sub_section = add_element(sub_section, section, fill, |section, fill| { + section.content.push(Content::Fill(fill)); + }); + } + + else if line.starts_with(" 0x") { + let symbol = read_symbol(line)?; + sub_section = add_element(sub_section, section, symbol, |section, symbol| { + section.content.push(Content::Symbol(symbol)); + }); + } + else if line.is_empty() { push_sub_section(section, sub_section); return Ok(line); @@ -124,6 +152,22 @@ fn read_section Result>(mut line: String, next_line: Ok((Section::new(name, adr, size, file), None)) } +fn read_fill(line: String) -> Result { + let mut split_line = line.split_whitespace().skip(1); + let adr = read_as::(split_line.next()).ok_or_else(|| {return Error::from_str("*fill* statement requires an address")})?; + let size = read_as::(split_line.next()).ok_or_else(|| {return Error::from_str("*fill* statement requires a size")})?; + + Ok(types::Fill::new(adr, size)) +} + +fn read_symbol(line: String) -> Result { + let mut split_line = line.split_whitespace(); + let adr = read_as::(split_line.next()).ok_or_else(|| {return Error::from_str("Symbol statement requires an address")})?; + let name = split_line.next().ok_or_else(|| {return Error::from_str("Symbol statement requires a symbol name")})?.to_string(); + + Ok(types::Symbol::new(name, adr)) +} + fn read_as(str: Option<&str>) -> Option { if let Some(str) = str { F::from_str_radix(str.trim_start_matches("0x"), 16).ok() diff --git a/src/Tools/readmap/src/types/mod.rs b/src/Tools/readmap/src/types/mod.rs index 03b06a44..8d4b1493 100644 --- a/src/Tools/readmap/src/types/mod.rs +++ b/src/Tools/readmap/src/types/mod.rs @@ -11,18 +11,18 @@ pub struct Section { #[derive(Default)] pub struct Symbol { - name: String, - adr: u64, + pub name: String, + pub adr: u64, } #[derive(Default)] pub struct Fill { - adr: u64, - size: usize, + pub adr: u64, + pub size: usize, } pub enum Content { - Fill, + Fill(Fill), Section(Section), Symbol(Symbol), } From 3108990266a1d509ef733bfd5737e4f1b9adf6e5 Mon Sep 17 00:00:00 2001 From: jaby Date: Wed, 5 Jul 2023 21:36:12 +0200 Subject: [PATCH 062/588] Parse map and write to file --- src/Tools/readmap/src/lib.rs | 28 ++++++++++++++++------ src/Tools/readmap/src/main.rs | 44 ++++++++++++++++++++++++++++++++--- 2 files changed, 62 insertions(+), 10 deletions(-) diff --git a/src/Tools/readmap/src/lib.rs b/src/Tools/readmap/src/lib.rs index 83c7c243..0151c99d 100644 --- a/src/Tools/readmap/src/lib.rs +++ b/src/Tools/readmap/src/lib.rs @@ -101,10 +101,11 @@ fn process_subsection Result>(section: &mut Section, } else if line.starts_with(" 0x") { - let symbol = read_symbol(line)?; - sub_section = add_element(sub_section, section, symbol, |section, symbol| { - section.content.push(Content::Symbol(symbol)); - }); + if let Some(symbol) = parse_symbol(read_symbol(line)?) { + sub_section = add_element(sub_section, section, symbol, |section, symbol| { + section.content.push(Content::Symbol(symbol)); + }); + } } else if line.is_empty() { @@ -161,13 +162,26 @@ fn read_fill(line: String) -> Result { } fn read_symbol(line: String) -> Result { - let mut split_line = line.split_whitespace(); - let adr = read_as::(split_line.next()).ok_or_else(|| {return Error::from_str("Symbol statement requires an address")})?; - let name = split_line.next().ok_or_else(|| {return Error::from_str("Symbol statement requires a symbol name")})?.to_string(); + let mut split_line = line.split_whitespace(); + let adr = read_as::(split_line.next()).ok_or_else(|| {return Error::from_str("Symbol statement requires an address")})?; + let mut name = split_line.next().ok_or_else(|| {return Error::from_str("Symbol statement requires a symbol name")})?.to_string(); + + for fragment in split_line { + name += fragment; + } Ok(types::Symbol::new(name, adr)) } +fn parse_symbol(mut symbol: types::Symbol) -> Option { + if symbol.name.starts_with(".") { + return None; + } + + symbol.name = symbol.name.split('=').next().unwrap().to_owned(); + Some(symbol) +} + fn read_as(str: Option<&str>) -> Option { if let Some(str) = str { F::from_str_radix(str.trim_start_matches("0x"), 16).ok() diff --git a/src/Tools/readmap/src/main.rs b/src/Tools/readmap/src/main.rs index 99045765..91445a6f 100644 --- a/src/Tools/readmap/src/main.rs +++ b/src/Tools/readmap/src/main.rs @@ -1,6 +1,7 @@ use clap::Parser; +use readmap::types::{Content::*, Section}; use tool_helper::{Error, exit_with_error}; -use std::path::PathBuf; +use std::{fs::File, io::{BufWriter, Write}, path::PathBuf}; #[derive(Parser)] #[clap(about = "Opens and scans a MAP file to print extended information", long_about = None)] @@ -10,9 +11,46 @@ struct CommandLine { } fn run_main(cmd: CommandLine) -> Result<(), Error> { - let _sections = readmap::scan(tool_helper::open_input(cmd.input)?)?; + fn value_to_hex(value: T) -> String { + return format!("0x{:X}", value); + } - println!("Found sections!"); + fn option_to_hex(value: Option) -> String { + if let Some(value) = value { + return value_to_hex(value); + } + + else { + return String::from(""); + } + } + + let sections = readmap::scan(tool_helper::open_input(cmd.input)?)?; + let mut file = tool_helper::open_output_file(&PathBuf::from("./planschi.txt"))?; + + for section in sections { + fn print_content(tab_level: usize, file: &mut BufWriter, section: Section) -> Result<(), Error> { + for content in section.content { + match content { + Fill(fill) => { + writeln!(file, "{:>tab_level$}*fill* @{}, {}", ' ', value_to_hex(fill.adr), value_to_hex(fill.size), tab_level=tab_level*4)?; + }, + Section(section) => { + writeln!(file, "{:>tab_level$} {} @{}, {}", ' ', section.name, option_to_hex(section.adr), option_to_hex(section.size), tab_level=tab_level*4)?; + print_content(tab_level + 1, file, section)?; + }, + Symbol(symbol) => { + writeln!(file, "{:>tab_level$}{} @{}", ' ', symbol.name, value_to_hex(symbol.adr), tab_level=tab_level*4)?; + } + } + } + + Ok(()) + } + + writeln!(file, "{}: @{}, {}", section.name, option_to_hex(section.adr), option_to_hex(section.size))?; + print_content(1, &mut file, section)?; + } Ok(()) } From 4298bf3208b97f493c1330afa34ff52b048a91f1 Mon Sep 17 00:00:00 2001 From: jaby Date: Thu, 6 Jul 2023 19:56:28 +0200 Subject: [PATCH 063/588] Sort addresses --- src/Tools/readmap/src/lib.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Tools/readmap/src/lib.rs b/src/Tools/readmap/src/lib.rs index 0151c99d..abde9b95 100644 --- a/src/Tools/readmap/src/lib.rs +++ b/src/Tools/readmap/src/lib.rs @@ -27,6 +27,9 @@ fn process>(mut line_iter:F) -> Result Date: Sun, 9 Jul 2023 13:31:02 +0200 Subject: [PATCH 064/588] Create psxreadmap and move readmap project into it --- src/Tools/Tools.code-workspace | 2 +- src/Tools/psxreadmap/Cargo.toml | 11 +++++++++++ src/Tools/{ => psxreadmap}/readmap/Cargo.toml | 3 +-- src/Tools/{ => psxreadmap}/readmap/src/lib.rs | 0 src/Tools/{ => psxreadmap}/readmap/src/types/mod.rs | 0 src/Tools/{readmap => psxreadmap}/src/main.rs | 0 6 files changed, 13 insertions(+), 3 deletions(-) create mode 100644 src/Tools/psxreadmap/Cargo.toml rename src/Tools/{ => psxreadmap}/readmap/Cargo.toml (67%) rename src/Tools/{ => psxreadmap}/readmap/src/lib.rs (100%) rename src/Tools/{ => psxreadmap}/readmap/src/types/mod.rs (100%) rename src/Tools/{readmap => psxreadmap}/src/main.rs (100%) diff --git a/src/Tools/Tools.code-workspace b/src/Tools/Tools.code-workspace index aed8c246..0bea2d6e 100644 --- a/src/Tools/Tools.code-workspace +++ b/src/Tools/Tools.code-workspace @@ -59,7 +59,7 @@ { "id": "project", "type": "pickString", - "options": ["cdtypes", "cpp_out", "jaby_engine_fconv", "mkoverlay", "psxcdgen", "psxcdgen_ex", "psxcdread", "readmap", "tool_helper", "wslpath"], + "options": ["cdtypes", "cpp_out", "jaby_engine_fconv", "mkoverlay", "psxreadmap", "psxcdgen", "psxcdgen_ex", "psxcdread", "tool_helper", "wslpath"], "description": "project to build" }, { diff --git a/src/Tools/psxreadmap/Cargo.toml b/src/Tools/psxreadmap/Cargo.toml new file mode 100644 index 00000000..47575be5 --- /dev/null +++ b/src/Tools/psxreadmap/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "psxreadmap" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +clap = {version = "*", features = ["derive"]} +readmap = {version = "*", path = "readmap"} +tool_helper = {version = "*", path = "../tool_helper"} \ No newline at end of file diff --git a/src/Tools/readmap/Cargo.toml b/src/Tools/psxreadmap/readmap/Cargo.toml similarity index 67% rename from src/Tools/readmap/Cargo.toml rename to src/Tools/psxreadmap/readmap/Cargo.toml index be1a86cc..9fe0b23e 100644 --- a/src/Tools/readmap/Cargo.toml +++ b/src/Tools/psxreadmap/readmap/Cargo.toml @@ -6,6 +6,5 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -clap = {version = "*", features = ["derive"]} num-traits = "*" -tool_helper = {path = "../tool_helper"} \ No newline at end of file +tool_helper = {version = "*", path = "../../tool_helper"} \ No newline at end of file diff --git a/src/Tools/readmap/src/lib.rs b/src/Tools/psxreadmap/readmap/src/lib.rs similarity index 100% rename from src/Tools/readmap/src/lib.rs rename to src/Tools/psxreadmap/readmap/src/lib.rs diff --git a/src/Tools/readmap/src/types/mod.rs b/src/Tools/psxreadmap/readmap/src/types/mod.rs similarity index 100% rename from src/Tools/readmap/src/types/mod.rs rename to src/Tools/psxreadmap/readmap/src/types/mod.rs diff --git a/src/Tools/readmap/src/main.rs b/src/Tools/psxreadmap/src/main.rs similarity index 100% rename from src/Tools/readmap/src/main.rs rename to src/Tools/psxreadmap/src/main.rs From ceb275cf22264a3226ed06e93fa335d6d95e0f00 Mon Sep 17 00:00:00 2001 From: jaby Date: Sun, 9 Jul 2023 14:40:44 +0200 Subject: [PATCH 065/588] Setup of update and render loop for CUI --- src/Tools/psxreadmap/Cargo.toml | 4 +- src/Tools/psxreadmap/src/lib.rs | 54 +++++++++++++++++ src/Tools/psxreadmap/src/main.rs | 101 +++++++++++++++++-------------- src/Tools/tool_helper/src/lib.rs | 6 ++ 4 files changed, 118 insertions(+), 47 deletions(-) create mode 100644 src/Tools/psxreadmap/src/lib.rs diff --git a/src/Tools/psxreadmap/Cargo.toml b/src/Tools/psxreadmap/Cargo.toml index 47575be5..de0875f9 100644 --- a/src/Tools/psxreadmap/Cargo.toml +++ b/src/Tools/psxreadmap/Cargo.toml @@ -7,5 +7,7 @@ edition = "2021" [dependencies] clap = {version = "*", features = ["derive"]} +crossterm = "*" readmap = {version = "*", path = "readmap"} -tool_helper = {version = "*", path = "../tool_helper"} \ No newline at end of file +tool_helper = {version = "*", path = "../tool_helper"} +tui = "*" \ No newline at end of file diff --git a/src/Tools/psxreadmap/src/lib.rs b/src/Tools/psxreadmap/src/lib.rs new file mode 100644 index 00000000..5b3ba1ae --- /dev/null +++ b/src/Tools/psxreadmap/src/lib.rs @@ -0,0 +1,54 @@ +use crossterm::event::KeyCode; +use readmap::types::Section; +use std::path::PathBuf; +use tool_helper::Error; + +pub type EventReceiver = std::sync::mpsc::Receiver>; +pub type Terminal = tui::Terminal>; + +pub enum Event { + Input(I), + Tick, +} + +pub enum UIState { + Alive, + Terminated +} + +pub struct ConsoleUI { + rx: EventReceiver, + terminal: Terminal +} + +impl ConsoleUI { + pub fn new(rx: EventReceiver, terminal: Terminal) -> ConsoleUI { + ConsoleUI{rx, terminal} + } + + pub fn update(&self) -> Result { + match self.rx.recv()? { + Event::Input(event) => { + match event.code { + KeyCode::Char('q') => Ok(UIState::Terminated), + _ => Ok(UIState::Alive) + } + }, + Event::Tick => Ok(UIState::Alive) + } + } + + pub fn render(&self) {} + + pub fn close(mut self) -> Result<(), Error> { + crossterm::terminal::disable_raw_mode()?; + self.terminal.show_cursor()?; + self.terminal.clear()?; + + Ok(()) + } +} + +pub fn load_memory_map(file_path: Option) -> Result, Error> { + readmap::scan(tool_helper::open_input(file_path)?) +} \ No newline at end of file diff --git a/src/Tools/psxreadmap/src/main.rs b/src/Tools/psxreadmap/src/main.rs index 91445a6f..9fc61015 100644 --- a/src/Tools/psxreadmap/src/main.rs +++ b/src/Tools/psxreadmap/src/main.rs @@ -1,7 +1,9 @@ use clap::Parser; -use readmap::types::{Content::*, Section}; +use crossterm::{event::{self, Event as CEvent}, terminal}; +use psxreadmap::{ConsoleUI, Event, EventReceiver, Terminal, load_memory_map}; +use std::{io, path::PathBuf, sync::mpsc, thread, time::{Duration, Instant}}; use tool_helper::{Error, exit_with_error}; -use std::{fs::File, io::{BufWriter, Write}, path::PathBuf}; +use tui::backend::CrosstermBackend; #[derive(Parser)] #[clap(about = "Opens and scans a MAP file to print extended information", long_about = None)] @@ -10,50 +12,6 @@ struct CommandLine { input: Option } -fn run_main(cmd: CommandLine) -> Result<(), Error> { - fn value_to_hex(value: T) -> String { - return format!("0x{:X}", value); - } - - fn option_to_hex(value: Option) -> String { - if let Some(value) = value { - return value_to_hex(value); - } - - else { - return String::from(""); - } - } - - let sections = readmap::scan(tool_helper::open_input(cmd.input)?)?; - let mut file = tool_helper::open_output_file(&PathBuf::from("./planschi.txt"))?; - - for section in sections { - fn print_content(tab_level: usize, file: &mut BufWriter, section: Section) -> Result<(), Error> { - for content in section.content { - match content { - Fill(fill) => { - writeln!(file, "{:>tab_level$}*fill* @{}, {}", ' ', value_to_hex(fill.adr), value_to_hex(fill.size), tab_level=tab_level*4)?; - }, - Section(section) => { - writeln!(file, "{:>tab_level$} {} @{}, {}", ' ', section.name, option_to_hex(section.adr), option_to_hex(section.size), tab_level=tab_level*4)?; - print_content(tab_level + 1, file, section)?; - }, - Symbol(symbol) => { - writeln!(file, "{:>tab_level$}{} @{}", ' ', symbol.name, value_to_hex(symbol.adr), tab_level=tab_level*4)?; - } - } - } - - Ok(()) - } - - writeln!(file, "{}: @{}, {}", section.name, option_to_hex(section.adr), option_to_hex(section.size))?; - print_content(1, &mut file, section)?; - } - Ok(()) -} - pub fn main() { match CommandLine::try_parse() { Ok(cmd_line) => { @@ -66,4 +24,55 @@ pub fn main() { println!("{}", error) } } +} + +fn run_main(cmd: CommandLine) -> Result<(), Error> { + let _sections = load_memory_map(cmd.input)?; + let rx = start_event_loop(); + let terminal = setup_console()?; + let console_ui = ConsoleUI::new(rx, terminal); + + while matches!(console_ui.update()?, psxreadmap::UIState::Alive) { + console_ui.render(); + } + + console_ui.close() +} + +fn start_event_loop() -> EventReceiver { + // Set up a mpsc (multiproducer, single consumer) channel to communicate between the input handler and the rendering loop. + let (tx, rx) = mpsc::channel(); + let tick_rate = Duration::from_millis(200); + thread::spawn(move || { + let mut last_tick = Instant::now(); + loop { + let timeout = tick_rate.checked_sub(last_tick.elapsed()).unwrap_or_else(|| Duration::from_secs(0)); + + if event::poll(timeout).expect("Event poll working") { + if let CEvent::Key(key) = event::read().expect("Can read key input") { + tx.send(Event::Input(key)).expect("Can send KeyInput"); + } + } + + if last_tick.elapsed() >= tick_rate { + if let Ok(_) = tx.send(Event::Tick) { + last_tick = Instant::now(); + } + } + } + }); + + rx +} + +fn setup_console() -> Result { + terminal::enable_raw_mode()?; + + // Setup Crossterm for the Terminal + let stdout = io::stdout(); + let backend = CrosstermBackend::new(stdout); + let mut terminal = Terminal::new(backend)?; + + terminal.clear()?; + Ok(terminal) } \ No newline at end of file diff --git a/src/Tools/tool_helper/src/lib.rs b/src/Tools/tool_helper/src/lib.rs index 12d8c1a6..e76d919c 100644 --- a/src/Tools/tool_helper/src/lib.rs +++ b/src/Tools/tool_helper/src/lib.rs @@ -114,6 +114,12 @@ impl std::convert::From for Error { } } +impl std::convert::From for Error { + fn from(error: std::sync::mpsc::RecvError) -> Self { + Error::from_error(error) + } +} + pub fn exit_with_error(error: Error) { error.print_to_std_err(); std::process::exit(error.exit_code); From b15281f702255024cad580937d7ab63fcb952d12 Mon Sep 17 00:00:00 2001 From: jaby Date: Sun, 9 Jul 2023 15:38:55 +0200 Subject: [PATCH 066/588] Display titel --- src/Tools/psxreadmap/src/lib.rs | 47 +++++++++++++++++++++++++++++--- src/Tools/psxreadmap/src/main.rs | 12 ++++---- 2 files changed, 49 insertions(+), 10 deletions(-) diff --git a/src/Tools/psxreadmap/src/lib.rs b/src/Tools/psxreadmap/src/lib.rs index 5b3ba1ae..a65b3c43 100644 --- a/src/Tools/psxreadmap/src/lib.rs +++ b/src/Tools/psxreadmap/src/lib.rs @@ -2,6 +2,11 @@ use crossterm::event::KeyCode; use readmap::types::Section; use std::path::PathBuf; use tool_helper::Error; +use tui::{ + layout::{Alignment, Constraint, Direction, Layout, Rect}, + style::{Color, Style}, + widgets::{Block, Borders, BorderType, Paragraph} +}; pub type EventReceiver = std::sync::mpsc::Receiver>; pub type Terminal = tui::Terminal>; @@ -17,13 +22,15 @@ pub enum UIState { } pub struct ConsoleUI { - rx: EventReceiver, - terminal: Terminal + rx: EventReceiver, + terminal: Terminal, + frame: Rect, + sub_frames: Vec } impl ConsoleUI { pub fn new(rx: EventReceiver, terminal: Terminal) -> ConsoleUI { - ConsoleUI{rx, terminal} + ConsoleUI{rx, terminal, frame: Rect::default(), sub_frames: Vec::default()} } pub fn update(&self) -> Result { @@ -38,7 +45,17 @@ impl ConsoleUI { } } - pub fn render(&self) {} + pub fn render(&mut self) -> Result<(), Error> { + self.terminal.draw(|frame| { + Self::update_sub_frames(&mut self.sub_frames, &mut self.frame, frame.size()); + + frame.render_widget(Self::create_titel(), self.sub_frames[0]); + frame.render_widget(Self::create_titel(), self.sub_frames[1]); + frame.render_widget(Self::create_titel(), self.sub_frames[2]); + })?; + + Ok(()) + } pub fn close(mut self) -> Result<(), Error> { crossterm::terminal::disable_raw_mode()?; @@ -47,6 +64,28 @@ impl ConsoleUI { Ok(()) } + + fn update_sub_frames(sub_frames: &mut Vec, frame: &mut Rect, new_frame: Rect) { + if new_frame != *frame { + *sub_frames = Layout::default().direction(Direction::Vertical).constraints([ + Constraint::Length(3), + Constraint::Length(3), + Constraint::Min(3) + ]).split(new_frame); + *frame = new_frame; + } + } + + fn create_titel<'a>() -> Paragraph<'a> { + Paragraph::new("psxreadmap") + .style(Style::default().fg(Color::White)) + .alignment(Alignment::Center) + .block(Block::default() + .borders(Borders::ALL) + .style(Style::default().fg(Color::White)) + .border_type(BorderType::Plain) + ) + } } pub fn load_memory_map(file_path: Option) -> Result, Error> { diff --git a/src/Tools/psxreadmap/src/main.rs b/src/Tools/psxreadmap/src/main.rs index 9fc61015..2e1a742f 100644 --- a/src/Tools/psxreadmap/src/main.rs +++ b/src/Tools/psxreadmap/src/main.rs @@ -9,7 +9,7 @@ use tui::backend::CrosstermBackend; #[clap(about = "Opens and scans a MAP file to print extended information", long_about = None)] struct CommandLine { #[clap(value_parser, help="Input MAP file for scannning")] - input: Option + input: PathBuf } pub fn main() { @@ -27,13 +27,13 @@ pub fn main() { } fn run_main(cmd: CommandLine) -> Result<(), Error> { - let _sections = load_memory_map(cmd.input)?; - let rx = start_event_loop(); - let terminal = setup_console()?; - let console_ui = ConsoleUI::new(rx, terminal); + let _sections = load_memory_map(Some(cmd.input))?; + let rx = start_event_loop(); + let terminal = setup_console()?; + let mut console_ui = ConsoleUI::new(rx, terminal); while matches!(console_ui.update()?, psxreadmap::UIState::Alive) { - console_ui.render(); + console_ui.render()?; } console_ui.close() From 131405962be9a54880b8ea85a19d50bdff8dc7dc Mon Sep 17 00:00:00 2001 From: jaby Date: Sun, 9 Jul 2023 16:16:28 +0200 Subject: [PATCH 067/588] Implemented QUIT window --- src/Tools/psxreadmap/src/lib.rs | 107 +++++++++++++++++++++++++++---- src/Tools/psxreadmap/src/main.rs | 12 +++- 2 files changed, 103 insertions(+), 16 deletions(-) diff --git a/src/Tools/psxreadmap/src/lib.rs b/src/Tools/psxreadmap/src/lib.rs index a65b3c43..86e02c48 100644 --- a/src/Tools/psxreadmap/src/lib.rs +++ b/src/Tools/psxreadmap/src/lib.rs @@ -4,8 +4,9 @@ use std::path::PathBuf; use tool_helper::Error; use tui::{ layout::{Alignment, Constraint, Direction, Layout, Rect}, - style::{Color, Style}, - widgets::{Block, Borders, BorderType, Paragraph} + style::{Color, Modifier, Style}, + text::{Span, Spans}, + widgets::{Block, Borders, BorderType, Paragraph, Tabs} }; pub type EventReceiver = std::sync::mpsc::Receiver>; @@ -14,34 +15,79 @@ pub type Terminal = tui::Terminal { Input(I), Tick, + ForceRender, } pub enum UIState { Alive, + Render, Terminated } +pub enum MenuSelection { + Stats, + Quit, +} + +impl MenuSelection { + fn next(&self) -> MenuSelection { + match self { + Self::Stats => Self::Quit, + Self::Quit => Self::Stats + } + } + + fn prev(&self) -> MenuSelection { + self.next() + } + + fn get_id(&self) -> usize { + match self { + MenuSelection::Stats => 0, + MenuSelection::Quit => 1, + } + } +} + pub struct ConsoleUI { - rx: EventReceiver, - terminal: Terminal, - frame: Rect, - sub_frames: Vec + rx: EventReceiver, + terminal: Terminal, + frame: Rect, + sub_frames: Vec, + menu_selection: MenuSelection, } impl ConsoleUI { pub fn new(rx: EventReceiver, terminal: Terminal) -> ConsoleUI { - ConsoleUI{rx, terminal, frame: Rect::default(), sub_frames: Vec::default()} + ConsoleUI{rx, terminal, frame: Rect::default(), sub_frames: Vec::default(), menu_selection: MenuSelection::Stats} } - pub fn update(&self) -> Result { + pub fn update(&mut self) -> Result { match self.rx.recv()? { Event::Input(event) => { match event.code { KeyCode::Char('q') => Ok(UIState::Terminated), + KeyCode::Left => { + self.menu_selection = self.menu_selection.prev(); + Ok(UIState::Render) + }, + KeyCode::Right => { + self.menu_selection = self.menu_selection.next(); + Ok(UIState::Render) + }, + KeyCode::Enter => { + if matches!(self.menu_selection, MenuSelection::Quit) { + Ok(UIState::Terminated) + } + else { + Ok(UIState::Alive) + } + }, _ => Ok(UIState::Alive) } }, - Event::Tick => Ok(UIState::Alive) + Event::Tick => Ok(UIState::Alive), + Event::ForceRender => Ok(UIState::Render) } } @@ -49,11 +95,15 @@ impl ConsoleUI { self.terminal.draw(|frame| { Self::update_sub_frames(&mut self.sub_frames, &mut self.frame, frame.size()); - frame.render_widget(Self::create_titel(), self.sub_frames[0]); - frame.render_widget(Self::create_titel(), self.sub_frames[1]); - frame.render_widget(Self::create_titel(), self.sub_frames[2]); + frame.render_widget(Self::create_titel(), self.sub_frames[0]); + frame.render_widget(Self::create_menu(&self.menu_selection), self.sub_frames[1]); + frame.render_widget({ + match self.menu_selection { + MenuSelection::Stats => Self::create_titel(), + MenuSelection::Quit => Self::create_exit_message(), + } + }, self.sub_frames[2]); })?; - Ok(()) } @@ -86,6 +136,37 @@ impl ConsoleUI { .border_type(BorderType::Plain) ) } + + fn create_menu<'a>(menu_selection: &MenuSelection) -> Tabs<'a> { + const MENU_TITLES: &'static [&'static str] = &["Stats", "Quit"]; + + let menu = MENU_TITLES.iter().map(|t| { + let (first, rest) = t.split_at(1); + Spans::from(vec![ + Span::styled(first, Style::default().fg(Color::Yellow).add_modifier(Modifier::UNDERLINED),), + Span::styled(rest, Style::default().fg(Color::White)), + ]) + }).collect(); + + Tabs::new(menu).select(menu_selection.get_id()).block( + Block::default() + .title("Menu").borders(Borders::ALL)) + .style(Style::default().fg(Color::White)) + .highlight_style(Style::default().bg(Color::LightYellow)) + .divider(Span::raw("|") + ) + } + + fn create_exit_message<'a>() -> Paragraph<'a> { + Paragraph::new("Press \"ENTER\" to exit") + .style(Style::default().fg(Color::White)) + .alignment(Alignment::Center) + .block(Block::default() + .borders(Borders::ALL) + .style(Style::default().fg(Color::White)) + .border_type(BorderType::Plain).title("QUIT") + ) + } } pub fn load_memory_map(file_path: Option) -> Result, Error> { diff --git a/src/Tools/psxreadmap/src/main.rs b/src/Tools/psxreadmap/src/main.rs index 2e1a742f..2117ea29 100644 --- a/src/Tools/psxreadmap/src/main.rs +++ b/src/Tools/psxreadmap/src/main.rs @@ -1,6 +1,6 @@ use clap::Parser; use crossterm::{event::{self, Event as CEvent}, terminal}; -use psxreadmap::{ConsoleUI, Event, EventReceiver, Terminal, load_memory_map}; +use psxreadmap::{ConsoleUI, Event, EventReceiver, Terminal, load_memory_map, UIState}; use std::{io, path::PathBuf, sync::mpsc, thread, time::{Duration, Instant}}; use tool_helper::{Error, exit_with_error}; use tui::backend::CrosstermBackend; @@ -32,8 +32,12 @@ fn run_main(cmd: CommandLine) -> Result<(), Error> { let terminal = setup_console()?; let mut console_ui = ConsoleUI::new(rx, terminal); - while matches!(console_ui.update()?, psxreadmap::UIState::Alive) { - console_ui.render()?; + loop { + match console_ui.update()? { + UIState::Alive => (), + UIState::Render => {console_ui.render()?;} + UIState::Terminated => break + } } console_ui.close() @@ -45,6 +49,8 @@ fn start_event_loop() -> EventReceiver { let tick_rate = Duration::from_millis(200); thread::spawn(move || { let mut last_tick = Instant::now(); + + tx.send(Event::ForceRender).expect("Send ForceRender command!"); loop { let timeout = tick_rate.checked_sub(last_tick.elapsed()).unwrap_or_else(|| Duration::from_secs(0)); From 6e85fdc29cf3faacb329fcffb29f849d01e65ebd Mon Sep 17 00:00:00 2001 From: jaby Date: Sun, 9 Jul 2023 16:46:49 +0200 Subject: [PATCH 068/588] Prepare memory usage --- src/Tools/psxreadmap/src/lib.rs | 72 +++++++++++++++++++++++++------- src/Tools/psxreadmap/src/main.rs | 2 +- 2 files changed, 58 insertions(+), 16 deletions(-) diff --git a/src/Tools/psxreadmap/src/lib.rs b/src/Tools/psxreadmap/src/lib.rs index 86e02c48..1d948188 100644 --- a/src/Tools/psxreadmap/src/lib.rs +++ b/src/Tools/psxreadmap/src/lib.rs @@ -5,12 +5,14 @@ use tool_helper::Error; use tui::{ layout::{Alignment, Constraint, Direction, Layout, Rect}, style::{Color, Modifier, Style}, + symbols, text::{Span, Spans}, - widgets::{Block, Borders, BorderType, Paragraph, Tabs} + widgets::{Block, Borders, BorderType, LineGauge, Paragraph, Tabs} }; pub type EventReceiver = std::sync::mpsc::Receiver>; pub type Terminal = tui::Terminal>; +type ConsoleFrame<'a> = tui::Frame<'a, tui::backend::CrosstermBackend>; pub enum Event { Input(I), @@ -50,16 +52,17 @@ impl MenuSelection { } pub struct ConsoleUI { - rx: EventReceiver, - terminal: Terminal, - frame: Rect, - sub_frames: Vec, - menu_selection: MenuSelection, + rx: EventReceiver, + terminal: Terminal, + frame: Rect, + sub_frames: Vec, + stat_sub_frames: Vec, + menu_selection: MenuSelection, } impl ConsoleUI { pub fn new(rx: EventReceiver, terminal: Terminal) -> ConsoleUI { - ConsoleUI{rx, terminal, frame: Rect::default(), sub_frames: Vec::default(), menu_selection: MenuSelection::Stats} + ConsoleUI{rx, terminal, frame: Rect::default(), sub_frames: Vec::default(), stat_sub_frames: Vec::default(), menu_selection: MenuSelection::Stats} } pub fn update(&mut self) -> Result { @@ -86,23 +89,33 @@ impl ConsoleUI { _ => Ok(UIState::Alive) } }, - Event::Tick => Ok(UIState::Alive), + Event::Tick => { + if self.terminal.size().expect("Getting size of terminal") != self.frame { + Ok(UIState::Render) + } + + else { + Ok(UIState::Alive) + } + }, Event::ForceRender => Ok(UIState::Render) } } pub fn render(&mut self) -> Result<(), Error> { self.terminal.draw(|frame| { - Self::update_sub_frames(&mut self.sub_frames, &mut self.frame, frame.size()); + Self::update_sub_frames(&mut self.sub_frames, &mut self.stat_sub_frames, &mut self.frame, frame.size()); frame.render_widget(Self::create_titel(), self.sub_frames[0]); frame.render_widget(Self::create_menu(&self.menu_selection), self.sub_frames[1]); - frame.render_widget({ - match self.menu_selection { - MenuSelection::Stats => Self::create_titel(), - MenuSelection::Quit => Self::create_exit_message(), + match self.menu_selection { + MenuSelection::Stats => { + Self::render_stats(frame, &self.stat_sub_frames); + }, + MenuSelection::Quit => { + frame.render_widget(Self::create_exit_message(), self.sub_frames[2]); } - }, self.sub_frames[2]); + } })?; Ok(()) } @@ -115,13 +128,19 @@ impl ConsoleUI { Ok(()) } - fn update_sub_frames(sub_frames: &mut Vec, frame: &mut Rect, new_frame: Rect) { + fn update_sub_frames(sub_frames: &mut Vec, stats_frames: &mut Vec, frame: &mut Rect, new_frame: Rect) { if new_frame != *frame { *sub_frames = Layout::default().direction(Direction::Vertical).constraints([ Constraint::Length(3), Constraint::Length(3), Constraint::Min(3) ]).split(new_frame); + + *stats_frames = Layout::default().direction(Direction::Vertical).constraints([ + Constraint::Min(3), + Constraint::Length(3) + ]).split(sub_frames[2]); + *frame = new_frame; } } @@ -157,6 +176,29 @@ impl ConsoleUI { ) } + fn render_stats(frame: &mut ConsoleFrame, frames: &Vec) { + let content_text = Paragraph::new("") + .style(Style::default().fg(Color::White)) + .alignment(Alignment::Center) + .block(Block::default() + .borders(Borders::ALL) + .style(Style::default().fg(Color::White)) + .border_type(BorderType::Plain) + ); + let mem_gauge = Self::create_overall_mem_gauge(); + + frame.render_widget(content_text, frames[0]); + frame.render_widget(mem_gauge, frames[1]); + } + + fn create_overall_mem_gauge<'a>() -> LineGauge<'a> { + + LineGauge::default().block(Block::default().borders(Borders::ALL).title("Progress")) + .gauge_style(Style::default().fg(Color::White).bg(Color::Black).add_modifier(Modifier::BOLD)) + .line_set(symbols::line::THICK) + .ratio(0.4) + } + fn create_exit_message<'a>() -> Paragraph<'a> { Paragraph::new("Press \"ENTER\" to exit") .style(Style::default().fg(Color::White)) diff --git a/src/Tools/psxreadmap/src/main.rs b/src/Tools/psxreadmap/src/main.rs index 2117ea29..4414e92f 100644 --- a/src/Tools/psxreadmap/src/main.rs +++ b/src/Tools/psxreadmap/src/main.rs @@ -26,7 +26,7 @@ pub fn main() { } } -fn run_main(cmd: CommandLine) -> Result<(), Error> { +fn run_main(_cmd: CommandLine) -> Result<(), Error> { let _sections = load_memory_map(Some(cmd.input))?; let rx = start_event_loop(); let terminal = setup_console()?; From 5db7dfc622e809cfc08825de2f35c61be7e0e6a4 Mon Sep 17 00:00:00 2001 From: jaby Date: Sun, 9 Jul 2023 16:49:53 +0200 Subject: [PATCH 069/588] Some cleanup --- src/Tools/psxreadmap/src/lib.rs | 26 +++++++++++++------------- src/Tools/psxreadmap/src/main.rs | 2 +- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/Tools/psxreadmap/src/lib.rs b/src/Tools/psxreadmap/src/lib.rs index 1d948188..4da0477e 100644 --- a/src/Tools/psxreadmap/src/lib.rs +++ b/src/Tools/psxreadmap/src/lib.rs @@ -52,17 +52,17 @@ impl MenuSelection { } pub struct ConsoleUI { - rx: EventReceiver, - terminal: Terminal, - frame: Rect, - sub_frames: Vec, - stat_sub_frames: Vec, - menu_selection: MenuSelection, + rx: EventReceiver, + terminal: Terminal, + cur_size: Rect, + main_chunks: Vec, + stats_chunks: Vec, + menu_selection: MenuSelection, } impl ConsoleUI { pub fn new(rx: EventReceiver, terminal: Terminal) -> ConsoleUI { - ConsoleUI{rx, terminal, frame: Rect::default(), sub_frames: Vec::default(), stat_sub_frames: Vec::default(), menu_selection: MenuSelection::Stats} + ConsoleUI{rx, terminal, cur_size: Rect::default(), main_chunks: Vec::default(), stats_chunks: Vec::default(), menu_selection: MenuSelection::Stats} } pub fn update(&mut self) -> Result { @@ -90,7 +90,7 @@ impl ConsoleUI { } }, Event::Tick => { - if self.terminal.size().expect("Getting size of terminal") != self.frame { + if self.terminal.size().expect("Getting size of terminal") != self.cur_size { Ok(UIState::Render) } @@ -104,16 +104,16 @@ impl ConsoleUI { pub fn render(&mut self) -> Result<(), Error> { self.terminal.draw(|frame| { - Self::update_sub_frames(&mut self.sub_frames, &mut self.stat_sub_frames, &mut self.frame, frame.size()); + Self::update_sub_frames(&mut self.main_chunks, &mut self.stats_chunks, &mut self.cur_size, frame.size()); - frame.render_widget(Self::create_titel(), self.sub_frames[0]); - frame.render_widget(Self::create_menu(&self.menu_selection), self.sub_frames[1]); + frame.render_widget(Self::create_titel(), self.main_chunks[0]); + frame.render_widget(Self::create_menu(&self.menu_selection), self.main_chunks[1]); match self.menu_selection { MenuSelection::Stats => { - Self::render_stats(frame, &self.stat_sub_frames); + Self::render_stats(frame, &self.stats_chunks); }, MenuSelection::Quit => { - frame.render_widget(Self::create_exit_message(), self.sub_frames[2]); + frame.render_widget(Self::create_exit_message(), self.main_chunks[2]); } } })?; diff --git a/src/Tools/psxreadmap/src/main.rs b/src/Tools/psxreadmap/src/main.rs index 4414e92f..2117ea29 100644 --- a/src/Tools/psxreadmap/src/main.rs +++ b/src/Tools/psxreadmap/src/main.rs @@ -26,7 +26,7 @@ pub fn main() { } } -fn run_main(_cmd: CommandLine) -> Result<(), Error> { +fn run_main(cmd: CommandLine) -> Result<(), Error> { let _sections = load_memory_map(Some(cmd.input))?; let rx = start_event_loop(); let terminal = setup_console()?; From 5db0b7472032cf4a4643381d2d6dd2b037934138 Mon Sep 17 00:00:00 2001 From: jaby Date: Sun, 9 Jul 2023 19:24:43 +0200 Subject: [PATCH 070/588] Only read key press --- src/Tools/psxreadmap/src/main.rs | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/Tools/psxreadmap/src/main.rs b/src/Tools/psxreadmap/src/main.rs index 2117ea29..bc18d7c4 100644 --- a/src/Tools/psxreadmap/src/main.rs +++ b/src/Tools/psxreadmap/src/main.rs @@ -1,5 +1,5 @@ use clap::Parser; -use crossterm::{event::{self, Event as CEvent}, terminal}; +use crossterm::{event::{self, Event as CEvent, KeyboardEnhancementFlags, KeyEventKind, PushKeyboardEnhancementFlags}, execute, terminal}; use psxreadmap::{ConsoleUI, Event, EventReceiver, Terminal, load_memory_map, UIState}; use std::{io, path::PathBuf, sync::mpsc, thread, time::{Duration, Instant}}; use tool_helper::{Error, exit_with_error}; @@ -53,10 +53,11 @@ fn start_event_loop() -> EventReceiver { tx.send(Event::ForceRender).expect("Send ForceRender command!"); loop { let timeout = tick_rate.checked_sub(last_tick.elapsed()).unwrap_or_else(|| Duration::from_secs(0)); - if event::poll(timeout).expect("Event poll working") { if let CEvent::Key(key) = event::read().expect("Can read key input") { - tx.send(Event::Input(key)).expect("Can send KeyInput"); + if key.kind == KeyEventKind::Press { + tx.send(Event::Input(key)).expect("Can send KeyInput"); + } } } @@ -75,9 +76,15 @@ fn setup_console() -> Result { terminal::enable_raw_mode()?; // Setup Crossterm for the Terminal - let stdout = io::stdout(); + let stdout = { + let mut stdout = io::stdout(); + if let Err(_) = execute!(stdout, PushKeyboardEnhancementFlags(KeyboardEnhancementFlags::REPORT_EVENT_TYPES)) { + // When this fails it fails + } + stdout + }; let backend = CrosstermBackend::new(stdout); - let mut terminal = Terminal::new(backend)?; + let mut terminal = Terminal::new(backend)?; terminal.clear()?; Ok(terminal) From 9f20537352b9de205aaa977ec4a01bb138cb6d58 Mon Sep 17 00:00:00 2001 From: jaby Date: Tue, 11 Jul 2023 19:00:59 +0200 Subject: [PATCH 071/588] Collect highest address --- src/Tools/psxreadmap/readmap/src/lib.rs | 28 +++++++++++-------- src/Tools/psxreadmap/readmap/src/types/mod.rs | 5 ++++ src/Tools/psxreadmap/src/lib.rs | 4 +-- 3 files changed, 24 insertions(+), 13 deletions(-) diff --git a/src/Tools/psxreadmap/readmap/src/lib.rs b/src/Tools/psxreadmap/readmap/src/lib.rs index abde9b95..cc0be234 100644 --- a/src/Tools/psxreadmap/readmap/src/lib.rs +++ b/src/Tools/psxreadmap/readmap/src/lib.rs @@ -2,20 +2,22 @@ pub mod types; use tool_helper::{Error, Input}; use std::io::BufRead; -use types::{Content, Section}; +use types::{Content, MemoryMapInfo, Section}; -pub fn scan(input: Input) -> Result, Error> { - let sections = process(input.lines().map(|l| l.unwrap()).into_iter())?; +pub fn scan(input: Input) -> Result { + let (sections, highest_address) = process(input.lines().map(|l| l.unwrap()).into_iter())?; - Ok(sections) + Ok(MemoryMapInfo{sections, highest_address: highest_address}) } -fn process>(mut line_iter:F) -> Result, Error> { - let mut sections = Vec::new(); +fn process>(mut line_iter:F) -> Result<(Vec
, u64), Error> { + let mut sections = Vec::new(); + let mut highest_address = 0u64; + while let Some(mut line) = line_iter.next() { loop { if line.starts_with(".") { - let (new_line, new_section) = process_section(line, &mut line_iter)?; + let (new_line, new_section) = process_section(&mut highest_address, line, &mut line_iter)?; sections.push(new_section); line = new_line; @@ -30,19 +32,19 @@ fn process>(mut line_iter:F) -> Result>(line: String, line_iter:&mut F) -> Result<(String, Section), Error> { +fn process_section>(highest_address: &mut u64, line: String, line_iter:&mut F) -> Result<(String, Section), Error> { let mut next_line_closure = || { line_iter.next().ok_or(Error::from_str("Unexpected end of file")) }; let (mut section, line) = read_section(line, &mut next_line_closure)?; - Ok((process_subsection(&mut section, line, &mut next_line_closure)?, section)) + Ok((process_subsection(&mut section, highest_address, line, &mut next_line_closure)?, section)) } -fn process_subsection Result>(section: &mut Section, line: Option, next_line: &mut F) -> Result { +fn process_subsection Result>(section: &mut Section, highest_address: &mut u64, line: Option, next_line: &mut F) -> Result { fn push_sub_section(section: &mut Section, sub_section: Option
) { if let Some(sub_section) = sub_section { section.content.push(Content::Section(sub_section)); @@ -105,6 +107,10 @@ fn process_subsection Result>(section: &mut Section, else if line.starts_with(" 0x") { if let Some(symbol) = parse_symbol(read_symbol(line)?) { + if symbol.adr > *highest_address { + *highest_address = symbol.adr; + } + sub_section = add_element(sub_section, section, symbol, |section, symbol| { section.content.push(Content::Symbol(symbol)); }); diff --git a/src/Tools/psxreadmap/readmap/src/types/mod.rs b/src/Tools/psxreadmap/readmap/src/types/mod.rs index 8d4b1493..962c2db7 100644 --- a/src/Tools/psxreadmap/readmap/src/types/mod.rs +++ b/src/Tools/psxreadmap/readmap/src/types/mod.rs @@ -1,5 +1,10 @@ use std::default::Default; +pub struct MemoryMapInfo { + pub sections: Vec
, + pub highest_address: u64, +} + #[derive(Default)] pub struct Section { pub name: String, diff --git a/src/Tools/psxreadmap/src/lib.rs b/src/Tools/psxreadmap/src/lib.rs index 4da0477e..8ebdc101 100644 --- a/src/Tools/psxreadmap/src/lib.rs +++ b/src/Tools/psxreadmap/src/lib.rs @@ -1,5 +1,5 @@ use crossterm::event::KeyCode; -use readmap::types::Section; +use readmap::types::MemoryMapInfo; use std::path::PathBuf; use tool_helper::Error; use tui::{ @@ -211,6 +211,6 @@ impl ConsoleUI { } } -pub fn load_memory_map(file_path: Option) -> Result, Error> { +pub fn load_memory_map(file_path: Option) -> Result { readmap::scan(tool_helper::open_input(file_path)?) } \ No newline at end of file From f3aebbcf8162ea03c3134119bdef9bdac573ba4a Mon Sep 17 00:00:00 2001 From: jaby Date: Tue, 11 Jul 2023 20:26:33 +0200 Subject: [PATCH 072/588] Present memory usage --- lib/psexe.ld | 2 +- src/Tools/psxreadmap/src/lib.rs | 44 +++++++++++++++++++----- src/Tools/psxreadmap/src/main.rs | 59 ++++++++++++++++++++++++++++---- 3 files changed, 89 insertions(+), 16 deletions(-) diff --git a/lib/psexe.ld b/lib/psexe.ld index 2c1638e6..aa5c6e7d 100644 --- a/lib/psexe.ld +++ b/lib/psexe.ld @@ -237,6 +237,6 @@ SECTIONS { __bss_end = .; __heap_start = __heap_base; - . = ADDR(.text) - 0x800; + /*. = ADDR(.text) - 0x800;*/ __end = .; } diff --git a/src/Tools/psxreadmap/src/lib.rs b/src/Tools/psxreadmap/src/lib.rs index 8ebdc101..3c0cbea9 100644 --- a/src/Tools/psxreadmap/src/lib.rs +++ b/src/Tools/psxreadmap/src/lib.rs @@ -70,6 +70,10 @@ impl ConsoleUI { Event::Input(event) => { match event.code { KeyCode::Char('q') => Ok(UIState::Terminated), + KeyCode::Char('s') => { + self.menu_selection = MenuSelection::Stats; + Ok(UIState::Render) + }, KeyCode::Left => { self.menu_selection = self.menu_selection.prev(); Ok(UIState::Render) @@ -102,7 +106,7 @@ impl ConsoleUI { } } - pub fn render(&mut self) -> Result<(), Error> { + pub fn render(&mut self, data: &ConsoleUIData) -> Result<(), Error> { self.terminal.draw(|frame| { Self::update_sub_frames(&mut self.main_chunks, &mut self.stats_chunks, &mut self.cur_size, frame.size()); @@ -110,7 +114,7 @@ impl ConsoleUI { frame.render_widget(Self::create_menu(&self.menu_selection), self.main_chunks[1]); match self.menu_selection { MenuSelection::Stats => { - Self::render_stats(frame, &self.stats_chunks); + Self::render_stats(frame, &self.stats_chunks, data); }, MenuSelection::Quit => { frame.render_widget(Self::create_exit_message(), self.main_chunks[2]); @@ -176,7 +180,7 @@ impl ConsoleUI { ) } - fn render_stats(frame: &mut ConsoleFrame, frames: &Vec) { + fn render_stats(frame: &mut ConsoleFrame, frames: &Vec, data: &ConsoleUIData) { let content_text = Paragraph::new("") .style(Style::default().fg(Color::White)) .alignment(Alignment::Center) @@ -185,18 +189,18 @@ impl ConsoleUI { .style(Style::default().fg(Color::White)) .border_type(BorderType::Plain) ); - let mem_gauge = Self::create_overall_mem_gauge(); + let mem_gauge = Self::create_overall_mem_gauge(data.highest_adr); frame.render_widget(content_text, frames[0]); - frame.render_widget(mem_gauge, frames[1]); + frame.render_widget(mem_gauge, frames[1]); } - fn create_overall_mem_gauge<'a>() -> LineGauge<'a> { - - LineGauge::default().block(Block::default().borders(Borders::ALL).title("Progress")) + fn create_overall_mem_gauge<'a>(highest_adr: u64) -> LineGauge<'a> { + LineGauge::default().block(Block::default().borders(Borders::ALL) + .title(format!("Memory Usage (0x{:x}/0x{:x})", highest_adr, ConsoleUIData::HIGHEST_RAM_ADDRESS))) .gauge_style(Style::default().fg(Color::White).bg(Color::Black).add_modifier(Modifier::BOLD)) .line_set(symbols::line::THICK) - .ratio(0.4) + .ratio(highest_adr as f64/ConsoleUIData::HIGHEST_RAM_ADDRESS as f64) } fn create_exit_message<'a>() -> Paragraph<'a> { @@ -211,6 +215,28 @@ impl ConsoleUI { } } +#[derive(Default)] +pub struct ConsoleUIData { + highest_adr: u64 +} + +impl ConsoleUIData { + pub const HIGHEST_RAM_ADDRESS:u64 = 0x80000000 + (2*1024*1024); + + pub fn new(memory_map: &MemoryMapInfo) -> Result { + let mut ui_data = ConsoleUIData::default(); + + ui_data.update(memory_map)?; + Ok(ui_data) + } + + pub fn update(&mut self, memory_map: &MemoryMapInfo) -> Result<(), Error> { + + self.highest_adr = memory_map.highest_address; + Ok(()) + } +} + pub fn load_memory_map(file_path: Option) -> Result { readmap::scan(tool_helper::open_input(file_path)?) } \ No newline at end of file diff --git a/src/Tools/psxreadmap/src/main.rs b/src/Tools/psxreadmap/src/main.rs index bc18d7c4..16ba99bb 100644 --- a/src/Tools/psxreadmap/src/main.rs +++ b/src/Tools/psxreadmap/src/main.rs @@ -1,6 +1,6 @@ use clap::Parser; use crossterm::{event::{self, Event as CEvent, KeyboardEnhancementFlags, KeyEventKind, PushKeyboardEnhancementFlags}, execute, terminal}; -use psxreadmap::{ConsoleUI, Event, EventReceiver, Terminal, load_memory_map, UIState}; +use psxreadmap::{ConsoleUI, ConsoleUIData, Event, EventReceiver, Terminal, load_memory_map, UIState}; use std::{io, path::PathBuf, sync::mpsc, thread, time::{Duration, Instant}}; use tool_helper::{Error, exit_with_error}; use tui::backend::CrosstermBackend; @@ -27,15 +27,16 @@ pub fn main() { } fn run_main(cmd: CommandLine) -> Result<(), Error> { - let _sections = load_memory_map(Some(cmd.input))?; + let memory_map = load_memory_map(Some(cmd.input))?; let rx = start_event_loop(); let terminal = setup_console()?; + let ui_data = ConsoleUIData::new(&memory_map)?; let mut console_ui = ConsoleUI::new(rx, terminal); loop { match console_ui.update()? { UIState::Alive => (), - UIState::Render => {console_ui.render()?;} + UIState::Render => {console_ui.render(&ui_data)?;} UIState::Terminated => break } } @@ -55,7 +56,7 @@ fn start_event_loop() -> EventReceiver { let timeout = tick_rate.checked_sub(last_tick.elapsed()).unwrap_or_else(|| Duration::from_secs(0)); if event::poll(timeout).expect("Event poll working") { if let CEvent::Key(key) = event::read().expect("Can read key input") { - if key.kind == KeyEventKind::Press { + if key.kind == KeyEventKind::Release { tx.send(Event::Input(key)).expect("Can send KeyInput"); } } @@ -79,7 +80,7 @@ fn setup_console() -> Result { let stdout = { let mut stdout = io::stdout(); if let Err(_) = execute!(stdout, PushKeyboardEnhancementFlags(KeyboardEnhancementFlags::REPORT_EVENT_TYPES)) { - // When this fails it fails + // This fails under Windows but is required for Linux } stdout }; @@ -88,4 +89,50 @@ fn setup_console() -> Result { terminal.clear()?; Ok(terminal) -} \ No newline at end of file +} + +use std::{fs::File, io::{BufWriter, Write}}; +use readmap::types::{Content::*, Section}; +fn _write_main(cmd: CommandLine) -> Result<(), Error> { + fn value_to_hex(value: T) -> String { + return format!("0x{:X}", value); + } + + fn option_to_hex(value: Option) -> String { + if let Some(value) = value { + return value_to_hex(value); + } + + else { + return String::from(""); + } + } + + let memory_map = load_memory_map(Some(cmd.input))?; + let mut file = tool_helper::open_output_file(&PathBuf::from("./planschi.d"))?; + + for section in memory_map.sections { + fn print_content(tab_level: usize, file: &mut BufWriter, section: Section) -> Result<(), Error> { + for content in section.content { + match content { + Fill(fill) => { + writeln!(file, "{:>tab_level$}*fill* @{}, {}", ' ', value_to_hex(fill.adr), value_to_hex(fill.size), tab_level=tab_level*4)?; + }, + Section(section) => { + writeln!(file, "{:>tab_level$} {} @{}, {}", ' ', section.name, option_to_hex(section.adr), option_to_hex(section.size), tab_level=tab_level*4)?; + print_content(tab_level + 1, file, section)?; + }, + Symbol(symbol) => { + writeln!(file, "{:>tab_level$}{} @{}", ' ', symbol.name, value_to_hex(symbol.adr), tab_level=tab_level*4)?; + } + } + } + + Ok(()) + } + + writeln!(file, "{}: @{}, {}", section.name, option_to_hex(section.adr), option_to_hex(section.size))?; + print_content(1, &mut file, section)?; + } + Ok(()) +} From 9b1f2e11f6283025e8b626c13a5d54bc77ce467f Mon Sep 17 00:00:00 2001 From: jaby Date: Tue, 11 Jul 2023 21:37:37 +0200 Subject: [PATCH 073/588] Create objdump file --- src/Tools/Tools.code-workspace | 2 +- src/Tools/readmap/src/main.rs | 45 +++++++++++++++++++++++++++++++--- 2 files changed, 42 insertions(+), 5 deletions(-) diff --git a/src/Tools/Tools.code-workspace b/src/Tools/Tools.code-workspace index aed8c246..77ceba0c 100644 --- a/src/Tools/Tools.code-workspace +++ b/src/Tools/Tools.code-workspace @@ -82,7 +82,7 @@ "", "--help", "--list -o ../Tests/Test_Planschbecken psx bin-cue ../Tests/ISO_Planschbecken.xml", - "${workspaceFolder}/../../examples/PoolBox/application/bin/PSX-release/PoolBox.map" + "--wsl ../../../examples/PoolBox/application/bin/PSX-release/PoolBox.elf" ], "default": "", "description": "Argument options to pass to cargo run" diff --git a/src/Tools/readmap/src/main.rs b/src/Tools/readmap/src/main.rs index 91445a6f..f380a065 100644 --- a/src/Tools/readmap/src/main.rs +++ b/src/Tools/readmap/src/main.rs @@ -1,16 +1,53 @@ use clap::Parser; use readmap::types::{Content::*, Section}; use tool_helper::{Error, exit_with_error}; -use std::{fs::File, io::{BufWriter, Write}, path::PathBuf}; +use std::{fs::File, io::{BufRead, BufReader, BufWriter, Write}, path::PathBuf, process::{Child, Command, Stdio}}; #[derive(Parser)] #[clap(about = "Opens and scans a MAP file to print extended information", long_about = None)] struct CommandLine { #[clap(value_parser, help="Input MAP file for scannning")] - input: Option + input: PathBuf, + #[clap(long="wsl", default_value_t=false)] + use_wsl: bool, +} + +fn run_objdump(use_wsl: bool, input: PathBuf) -> Result { + let command_list = ["wsl", "objdump", "-x"]; + let start_idx = { + if use_wsl { + 0 + } + + else { + 1 + } + }; + let mut process = Command::new(command_list[start_idx]); + + for arg in command_list.iter().skip(start_idx + 1) { + process.arg(arg); + } + process.arg(input.to_str().ok_or_else(||{Error::from_str("Failed converting input string")})?); + + println!("Miau: {:?}", process); + Ok(process.stdout(Stdio::piped()).spawn()?) } fn run_main(cmd: CommandLine) -> Result<(), Error> { + let mut child = run_objdump(cmd.use_wsl, cmd.input)?; + if let Some(stdout) = &mut child.stdout { + for line in BufReader::new(stdout).lines() { + if let Ok(line) = line { + println!("{}", line); + } + } + } + + Ok(()) +} + +fn _run_main(cmd: CommandLine) -> Result<(), Error> { fn value_to_hex(value: T) -> String { return format!("0x{:X}", value); } @@ -25,8 +62,8 @@ fn run_main(cmd: CommandLine) -> Result<(), Error> { } } - let sections = readmap::scan(tool_helper::open_input(cmd.input)?)?; - let mut file = tool_helper::open_output_file(&PathBuf::from("./planschi.txt"))?; + let sections = readmap::scan(tool_helper::open_input(Some(cmd.input))?)?; + let mut file = tool_helper::open_output_file(&PathBuf::from("./planschi.d"))?; for section in sections { fn print_content(tab_level: usize, file: &mut BufWriter, section: Section) -> Result<(), Error> { From 4b9a2e46fd54284ed79d62e724fd04f0b40550f5 Mon Sep 17 00:00:00 2001 From: jaby Date: Tue, 11 Jul 2023 22:00:57 +0200 Subject: [PATCH 074/588] Support scan stdout of objdump --- src/Tools/readmap/src/lib.rs | 196 +---------------------------- src/Tools/readmap/src/main.rs | 70 ++--------- src/Tools/readmap/src/types/mod.rs | 43 +++---- 3 files changed, 30 insertions(+), 279 deletions(-) diff --git a/src/Tools/readmap/src/lib.rs b/src/Tools/readmap/src/lib.rs index abde9b95..03810f6d 100644 --- a/src/Tools/readmap/src/lib.rs +++ b/src/Tools/readmap/src/lib.rs @@ -1,196 +1,8 @@ pub mod types; -use tool_helper::{Error, Input}; -use std::io::BufRead; -use types::{Content, Section}; +use tool_helper::Error; +use types::MemoryMap; -pub fn scan(input: Input) -> Result, Error> { - let sections = process(input.lines().map(|l| l.unwrap()).into_iter())?; - - Ok(sections) -} - -fn process>(mut line_iter:F) -> Result, Error> { - let mut sections = Vec::new(); - while let Some(mut line) = line_iter.next() { - loop { - if line.starts_with(".") { - let (new_line, new_section) = process_section(line, &mut line_iter)?; - - sections.push(new_section); - line = new_line; - } - - else { - break; - } - } - } - - sections.sort_by(|left, right| { - left.adr.cmp(&right.adr) - }); - Ok(sections) -} - -fn process_section>(line: String, line_iter:&mut F) -> Result<(String, Section), Error> { - let mut next_line_closure = || { - line_iter.next().ok_or(Error::from_str("Unexpected end of file")) - }; - let (mut section, line) = read_section(line, &mut next_line_closure)?; - - Ok((process_subsection(&mut section, line, &mut next_line_closure)?, section)) -} - -fn process_subsection Result>(section: &mut Section, line: Option, next_line: &mut F) -> Result { - fn push_sub_section(section: &mut Section, sub_section: Option
) { - if let Some(sub_section) = sub_section { - section.content.push(Content::Section(sub_section)); - } - } - fn add_element(sub_section: Option
, section: &mut Section, value: T, callback: fn(&mut Section, T)) -> Option
{ - if let Some(mut sub_section) = sub_section { - callback(&mut sub_section, value); - Some(sub_section) - } - - else { - callback(section, value); - None - } - } - - let mut line = { - if let Some(line) = line { - line - } - - else { - next_line()? - } - }; - - let mut next_line_closure = || -> Result { - if let Ok(line) = next_line() { - return Ok(line); - } - - else { - // EOF - return Ok(String::from("")); - } - }; - - let mut sub_section = None; - - loop { - if line.starts_with(" .") { - push_sub_section(section, sub_section); - let (section, new_line) = read_section(line, &mut next_line_closure)?; - - sub_section = Some(section); - - if let Some(new_line) = new_line { - line = new_line; - continue; - } - } - - else if line.starts_with(" *fill*") { - let fill = read_fill(line)?; - sub_section = add_element(sub_section, section, fill, |section, fill| { - section.content.push(Content::Fill(fill)); - }); - } - - else if line.starts_with(" 0x") { - if let Some(symbol) = parse_symbol(read_symbol(line)?) { - sub_section = add_element(sub_section, section, symbol, |section, symbol| { - section.content.push(Content::Symbol(symbol)); - }); - } - } - - else if line.is_empty() { - push_sub_section(section, sub_section); - return Ok(line); - } - - line = next_line_closure()?; - } -} - -fn read_section Result>(mut line: String, next_line: &mut F) -> Result<(Section, Option), Error> { - let mut split_line = line.split_whitespace(); - let name = split_line.next().ok_or(Error::from_str("Couldn't locate section name"))?.to_string(); - let need_new_line = name.chars().count() > 16; - - if need_new_line { - line = next_line()?; - split_line = line.split_whitespace(); - } - - let adr = read_as::(split_line.next()); - if adr.is_none() { - return Ok((Section::new(name, None, None, None), { - if need_new_line { - Some(line) - } - - else { - None - } - })); - } - - let size = read_as::(split_line.next()); - let file = { - if let Some(file) = split_line.next() { - Some(file.to_string()) - } - - else { - None - } - }; - Ok((Section::new(name, adr, size, file), None)) -} - -fn read_fill(line: String) -> Result { - let mut split_line = line.split_whitespace().skip(1); - let adr = read_as::(split_line.next()).ok_or_else(|| {return Error::from_str("*fill* statement requires an address")})?; - let size = read_as::(split_line.next()).ok_or_else(|| {return Error::from_str("*fill* statement requires a size")})?; - - Ok(types::Fill::new(adr, size)) -} - -fn read_symbol(line: String) -> Result { - let mut split_line = line.split_whitespace(); - let adr = read_as::(split_line.next()).ok_or_else(|| {return Error::from_str("Symbol statement requires an address")})?; - let mut name = split_line.next().ok_or_else(|| {return Error::from_str("Symbol statement requires a symbol name")})?.to_string(); - - for fragment in split_line { - name += fragment; - } - - Ok(types::Symbol::new(name, adr)) -} - -fn parse_symbol(mut symbol: types::Symbol) -> Option { - if symbol.name.starts_with(".") { - return None; - } - - symbol.name = symbol.name.split('=').next().unwrap().to_owned(); - Some(symbol) -} - -fn read_as(str: Option<&str>) -> Option { - if let Some(str) = str { - F::from_str_radix(str.trim_start_matches("0x"), 16).ok() - } - - else { - None - } +pub fn scan Option>(_next_line: F) -> Result { + Err(Error::not_implemented("scan")) } \ No newline at end of file diff --git a/src/Tools/readmap/src/main.rs b/src/Tools/readmap/src/main.rs index f380a065..bbc3954d 100644 --- a/src/Tools/readmap/src/main.rs +++ b/src/Tools/readmap/src/main.rs @@ -1,7 +1,6 @@ use clap::Parser; -use readmap::types::{Content::*, Section}; use tool_helper::{Error, exit_with_error}; -use std::{fs::File, io::{BufRead, BufReader, BufWriter, Write}, path::PathBuf, process::{Child, Command, Stdio}}; +use std::{io::{BufRead, BufReader}, path::PathBuf, process::{Child, Command, Stdio}}; #[derive(Parser)] #[clap(about = "Opens and scans a MAP file to print extended information", long_about = None)] @@ -15,13 +14,8 @@ struct CommandLine { fn run_objdump(use_wsl: bool, input: PathBuf) -> Result { let command_list = ["wsl", "objdump", "-x"]; let start_idx = { - if use_wsl { - 0 - } - - else { - 1 - } + if use_wsl {0} + else {1} }; let mut process = Command::new(command_list[start_idx]); @@ -30,65 +24,23 @@ fn run_objdump(use_wsl: bool, input: PathBuf) -> Result { } process.arg(input.to_str().ok_or_else(||{Error::from_str("Failed converting input string")})?); - println!("Miau: {:?}", process); Ok(process.stdout(Stdio::piped()).spawn()?) } fn run_main(cmd: CommandLine) -> Result<(), Error> { let mut child = run_objdump(cmd.use_wsl, cmd.input)?; if let Some(stdout) = &mut child.stdout { - for line in BufReader::new(stdout).lines() { - if let Ok(line) = line { - println!("{}", line); - } - } + let mut line_iter = BufReader::new(stdout).lines().map(|l| l.unwrap()).into_iter(); + + readmap::scan(|| { + line_iter.next() + })?; + Ok(()) } - Ok(()) -} - -fn _run_main(cmd: CommandLine) -> Result<(), Error> { - fn value_to_hex(value: T) -> String { - return format!("0x{:X}", value); + else { + Err(Error::from_str("Failed opening \"stdout\" for objdump")) } - - fn option_to_hex(value: Option) -> String { - if let Some(value) = value { - return value_to_hex(value); - } - - else { - return String::from(""); - } - } - - let sections = readmap::scan(tool_helper::open_input(Some(cmd.input))?)?; - let mut file = tool_helper::open_output_file(&PathBuf::from("./planschi.d"))?; - - for section in sections { - fn print_content(tab_level: usize, file: &mut BufWriter, section: Section) -> Result<(), Error> { - for content in section.content { - match content { - Fill(fill) => { - writeln!(file, "{:>tab_level$}*fill* @{}, {}", ' ', value_to_hex(fill.adr), value_to_hex(fill.size), tab_level=tab_level*4)?; - }, - Section(section) => { - writeln!(file, "{:>tab_level$} {} @{}, {}", ' ', section.name, option_to_hex(section.adr), option_to_hex(section.size), tab_level=tab_level*4)?; - print_content(tab_level + 1, file, section)?; - }, - Symbol(symbol) => { - writeln!(file, "{:>tab_level$}{} @{}", ' ', symbol.name, value_to_hex(symbol.adr), tab_level=tab_level*4)?; - } - } - } - - Ok(()) - } - - writeln!(file, "{}: @{}, {}", section.name, option_to_hex(section.adr), option_to_hex(section.size))?; - print_content(1, &mut file, section)?; - } - Ok(()) } pub fn main() { diff --git a/src/Tools/readmap/src/types/mod.rs b/src/Tools/readmap/src/types/mod.rs index 8d4b1493..80b60f7c 100644 --- a/src/Tools/readmap/src/types/mod.rs +++ b/src/Tools/readmap/src/types/mod.rs @@ -1,12 +1,23 @@ use std::default::Default; +#[derive(Default)] +pub struct MemoryMap { + pub global: Vec, + pub sections: Vec
+} + #[derive(Default)] pub struct Section { pub name: String, - pub adr: Option, - pub size: Option, - pub file: Option, - pub content: Vec + pub adr: u64, + pub size: usize, + pub symbols: Vec +} + +impl Section { + pub fn new(name: String, adr: u64, size: usize) -> Section { + Section{name, adr, size, symbols: Vec::new()} + } } #[derive(Default)] @@ -15,32 +26,8 @@ pub struct Symbol { pub adr: u64, } -#[derive(Default)] -pub struct Fill { - pub adr: u64, - pub size: usize, -} - -pub enum Content { - Fill(Fill), - Section(Section), - Symbol(Symbol), -} - -impl Section { - pub fn new(name: String, adr: Option, size: Option, file: Option) -> Section { - Section{name, adr, size, file, content: Vec::new()} - } -} - impl Symbol { pub fn new(name: String, adr: u64) -> Symbol { Symbol{name, adr} } -} - -impl Fill { - pub fn new(adr: u64, size: usize) -> Fill { - Fill{adr, size} - } } \ No newline at end of file From 5fba2a82b136d6a506e56756a392a29e12920379 Mon Sep 17 00:00:00 2001 From: jaby Date: Tue, 11 Jul 2023 23:05:20 +0200 Subject: [PATCH 075/588] Parse with weird printf bug --- src/Tools/readmap/src/lib.rs | 42 ++++++++++++++++++++++++++++++++++-- 1 file changed, 40 insertions(+), 2 deletions(-) diff --git a/src/Tools/readmap/src/lib.rs b/src/Tools/readmap/src/lib.rs index 03810f6d..543bd42a 100644 --- a/src/Tools/readmap/src/lib.rs +++ b/src/Tools/readmap/src/lib.rs @@ -1,8 +1,46 @@ pub mod types; use tool_helper::Error; -use types::MemoryMap; +use types::{MemoryMap, Section}; -pub fn scan Option>(_next_line: F) -> Result { +pub fn scan Option>(mut next_line: F) -> Result { + const SECTION_IDENTIFIER:&'static str = "Sections:"; + const SYMBOL_TABLE_IDENTIFIER:&'static str = "SYMBOL TABLE:"; + + while let Some(line) = next_line() { + if line == SECTION_IDENTIFIER { + scan_sections(&mut next_line)?; + } + + if line == SYMBOL_TABLE_IDENTIFIER {} + } Err(Error::not_implemented("scan")) +} + +fn scan_sections Option>(next_line: &mut F) -> Result, Error> { + while let Some(_) = next_line() { + // We read every other line + let line = next_line().ok_or(Error::from_str("Failed skipping section line"))?; + let mut split_line = line.split_whitespace(); + if let Ok(_) = split_line_radix(&mut split_line, 10, "") { + let name = split_line.next().ok_or(Error::from_str("Failed reading Section Name"))?; + let size = split_line_radix(&mut split_line, 16, "Section Size")?; + let adr = split_line_radix(&mut split_line, 16, "Section Address")?; + + println!("\"{}\" @0x{:X} -> 0x{:X}", name, adr, (adr + size)); + } + + else { + return Err(Error::from_str("")); + } + } + + Err(Error::not_implemented("scan")) +} + +fn split_line_radix<'a>(split_line: &mut std::str::SplitWhitespace<'a>, radix: u32, value_name: &str) -> Result { + match u64::from_str_radix(split_line.next().ok_or(Error::from_text(format!("Failed reading: {}", value_name)))?, radix) { + Ok(value) => Ok(value), + Err(error) => Err(Error::from_text(format!("Converting value for {} failed with: {}", value_name, error))) + } } \ No newline at end of file From 6e088716b8ccef126fff734ca240b86b6f6ec8fc Mon Sep 17 00:00:00 2001 From: jaby Date: Mon, 17 Jul 2023 18:41:15 +0200 Subject: [PATCH 076/588] Scan and print sections - prepare for SymbolTable --- src/Tools/readmap/src/lib.rs | 33 ++++++++++++++++++++++++--------- 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/src/Tools/readmap/src/lib.rs b/src/Tools/readmap/src/lib.rs index 543bd42a..932a58d9 100644 --- a/src/Tools/readmap/src/lib.rs +++ b/src/Tools/readmap/src/lib.rs @@ -7,17 +7,32 @@ pub fn scan Option>(mut next_line: F) -> Result Option>(next_line: &mut F) -> Result, Error> { +fn scan_sections Option>(next_line: &mut F, sections: &mut Vec
) -> Result { while let Some(_) = next_line() { // We read every other line let line = next_line().ok_or(Error::from_str("Failed skipping section line"))?; @@ -27,15 +42,15 @@ fn scan_sections Option>(next_line: &mut F) -> Result 0x{:X}", name, adr, (adr + size)); + sections.push(Section::new(name.to_string(), adr, size as usize)); } else { - return Err(Error::from_str("")); + return Ok(line); } } - Err(Error::not_implemented("scan")) + Err(Error::not_implemented("Failed obtaining complete section")) } fn split_line_radix<'a>(split_line: &mut std::str::SplitWhitespace<'a>, radix: u32, value_name: &str) -> Result { From dc69edbab3cecb2609ad875a9613c7fbd6f48e7c Mon Sep 17 00:00:00 2001 From: jaby Date: Thu, 20 Jul 2023 20:31:25 +0200 Subject: [PATCH 077/588] Collect Symbols --- src/Tools/readmap/src/lib.rs | 65 +++++++++++++++++++++++++++--- src/Tools/readmap/src/types/mod.rs | 9 ++++- 2 files changed, 66 insertions(+), 8 deletions(-) diff --git a/src/Tools/readmap/src/lib.rs b/src/Tools/readmap/src/lib.rs index 932a58d9..9dfd3c51 100644 --- a/src/Tools/readmap/src/lib.rs +++ b/src/Tools/readmap/src/lib.rs @@ -1,7 +1,7 @@ pub mod types; use tool_helper::Error; -use types::{MemoryMap, Section}; +use types::{MemoryMap, Section, Symbol}; pub fn scan Option>(mut next_line: F) -> Result { const SECTION_IDENTIFIER:&'static str = "Sections:"; @@ -19,23 +19,76 @@ pub fn scan Option>(mut next_line: F) -> Result ({})", memory_map.global.len()); for section in memory_map.sections { - println!("Name: {}", section.name); + println!("Name: {} ({})", section.name, section.symbols.len()); } - Err(Error::not_implemented("scan")) + Err(Error::from_str("Symbols should be sorted by address now - not implemented yet")) +} + +fn scan_symbols Option>(next_line: &mut F, memory_map: &mut MemoryMap) -> Result { + fn find_section<'a>(name: &str, memory_map: &'a mut MemoryMap) -> Option<&'a mut Section> { + for section in &mut memory_map.sections { + if section.name == name { + return Some(section); + } + } + + None + } + + fn skip_symbol(name: &str, section_name: &str) -> bool { + name == section_name || name.ends_with(".cpp") || name.ends_with(".c") || name.ends_with(".cxx") + } + + while let Some(line) = next_line() { + if line.chars().all(char::is_whitespace) { + return Ok(line); + } + + let split_count = line.split_whitespace().count(); + let mut split_line = line.split_whitespace(); + let adr = split_line_radix(&mut split_line, 16, "Address of Symbol")?; + let _type = split_line.next().ok_or(Error::from_str("Failed obtaining type of symbol"))?; + if split_count > 5 { + let _flag = split_line.next().ok_or(Error::from_str("Failed obtaining flag of symbol"))?; + } + let section = split_line.next().ok_or(Error::from_str("Failed obtaining section of symbol"))?; + let size = split_line_radix(&mut split_line, 16, "Size of Symbol")? as usize; + let name = split_line.next().ok_or(Error::from_str("Failed obtaining name of symbol"))?; + + if skip_symbol(name, section) { + // Not of interest + continue; + } + + let symbol = Symbol::new(name.to_string(), adr, size); + if let Some(section) = find_section(section, memory_map) { + if section.contains_adr(adr) { + section.symbols.push(symbol); + // Do not add to global cause they have a section + continue; + } + } + + memory_map.global.push(symbol); + } + + Err(Error::from_str("Failed obtaining all Symbols")) } fn scan_sections Option>(next_line: &mut F, sections: &mut Vec
) -> Result { while let Some(_) = next_line() { // We read every other line - let line = next_line().ok_or(Error::from_str("Failed skipping section line"))?; + let line = next_line().ok_or(Error::from_str("Failed skipping to next section"))?; let mut split_line = line.split_whitespace(); if let Ok(_) = split_line_radix(&mut split_line, 10, "") { let name = split_line.next().ok_or(Error::from_str("Failed reading Section Name"))?; @@ -50,7 +103,7 @@ fn scan_sections Option>(next_line: &mut F, sections: &mut } } - Err(Error::not_implemented("Failed obtaining complete section")) + Err(Error::from_str("Failed obtaining complete section")) } fn split_line_radix<'a>(split_line: &mut std::str::SplitWhitespace<'a>, radix: u32, value_name: &str) -> Result { diff --git a/src/Tools/readmap/src/types/mod.rs b/src/Tools/readmap/src/types/mod.rs index 80b60f7c..0509eda3 100644 --- a/src/Tools/readmap/src/types/mod.rs +++ b/src/Tools/readmap/src/types/mod.rs @@ -18,16 +18,21 @@ impl Section { pub fn new(name: String, adr: u64, size: usize) -> Section { Section{name, adr, size, symbols: Vec::new()} } + + pub fn contains_adr(&self, adr: u64) -> bool { + adr >= self.adr && adr < (self.adr + self.size as u64) + } } #[derive(Default)] pub struct Symbol { pub name: String, pub adr: u64, + pub size: usize } impl Symbol { - pub fn new(name: String, adr: u64) -> Symbol { - Symbol{name, adr} + pub fn new(name: String, adr: u64, size: usize) -> Symbol { + Symbol{name, adr, size} } } \ No newline at end of file From cc70e97021a18af184ac8872840312929eb7e977 Mon Sep 17 00:00:00 2001 From: jaby Date: Mon, 24 Jul 2023 20:41:38 +0200 Subject: [PATCH 078/588] Sort map --- src/Tools/readmap/src/lib.rs | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/src/Tools/readmap/src/lib.rs b/src/Tools/readmap/src/lib.rs index 9dfd3c51..17e7c1d7 100644 --- a/src/Tools/readmap/src/lib.rs +++ b/src/Tools/readmap/src/lib.rs @@ -26,12 +26,28 @@ pub fn scan Option>(mut next_line: F) -> Result ({})", memory_map.global.len()); - for section in memory_map.sections { - println!("Name: {} ({})", section.name, section.symbols.len()); + sort_memory_map(&mut memory_map); + Ok(memory_map) +} + +fn sort_memory_map(memory_map: &mut MemoryMap) { + fn sort_symbol_vec(symbol_vec: &mut Vec) { + symbol_vec.sort_by(|a, b| { + a.adr.cmp(&b.adr) + }); + } + + fn sort_section_vec(section_vec: &mut Vec
) { + section_vec.sort_by(|a, b| { + a.adr.cmp(&b.adr) + }); + } + + sort_section_vec(&mut memory_map.sections); + sort_symbol_vec(&mut memory_map.global); + for section in &mut memory_map.sections { + sort_symbol_vec(&mut section.symbols); } - Err(Error::from_str("Symbols should be sorted by address now - not implemented yet")) } fn scan_symbols Option>(next_line: &mut F, memory_map: &mut MemoryMap) -> Result { From 990fcb8548b3b466981956ab7eff861e535643e7 Mon Sep 17 00:00:00 2001 From: jaby Date: Mon, 24 Jul 2023 22:22:17 +0200 Subject: [PATCH 079/588] Print memory map --- src/Tools/readmap/src/dump/mod.rs | 32 ++++++++++++++++++++ src/Tools/readmap/src/lib.rs | 1 + src/Tools/readmap/src/main.rs | 50 ++++++++++++++++++------------- 3 files changed, 63 insertions(+), 20 deletions(-) create mode 100644 src/Tools/readmap/src/dump/mod.rs diff --git a/src/Tools/readmap/src/dump/mod.rs b/src/Tools/readmap/src/dump/mod.rs new file mode 100644 index 00000000..c5bb163b --- /dev/null +++ b/src/Tools/readmap/src/dump/mod.rs @@ -0,0 +1,32 @@ +use super::Error; +use super::types::{MemoryMap, Symbol}; +use tool_helper::Output; + +pub fn write(mut out: Output, memory_map: &MemoryMap) -> Result { + const NAME_WIDTH:usize = 64; + fn print_symbols(out: &mut Output, symbols: &Vec) -> Result<(), Error> { + for symbol in symbols { + let mut name = symbol.name.as_str(); + + if name.len() > NAME_WIDTH { + writeln!(out, "\t{}", name)?; + name = " "; + } + + writeln!(out, "\t{::")?; + print_symbols(&mut out, &memory_map.global)?; + for section in &memory_map.sections { + let section_end = section.adr + section.size as u64; + + writeln!(out, "{}: @0x{:X} - 0x{:X}", section.name, section.adr, section_end)?; + print_symbols(&mut out, §ion.symbols)?; + } + + Ok(out) +} \ No newline at end of file diff --git a/src/Tools/readmap/src/lib.rs b/src/Tools/readmap/src/lib.rs index 17e7c1d7..4bf8b38e 100644 --- a/src/Tools/readmap/src/lib.rs +++ b/src/Tools/readmap/src/lib.rs @@ -1,4 +1,5 @@ pub mod types; +pub mod dump; use tool_helper::Error; use types::{MemoryMap, Section, Symbol}; diff --git a/src/Tools/readmap/src/main.rs b/src/Tools/readmap/src/main.rs index bbc3954d..8f121ac1 100644 --- a/src/Tools/readmap/src/main.rs +++ b/src/Tools/readmap/src/main.rs @@ -1,14 +1,31 @@ use clap::Parser; use tool_helper::{Error, exit_with_error}; +use readmap::types::MemoryMap; use std::{io::{BufRead, BufReader}, path::PathBuf, process::{Child, Command, Stdio}}; #[derive(Parser)] #[clap(about = "Opens and scans a MAP file to print extended information", long_about = None)] struct CommandLine { #[clap(value_parser, help="Input MAP file for scannning")] - input: PathBuf, + input: PathBuf, #[clap(long="wsl", default_value_t=false)] - use_wsl: bool, + use_wsl: bool, + #[clap(short='o')] + output: Option +} + +pub fn main() { + match CommandLine::try_parse() { + Ok(cmd_line) => { + match run_main(cmd_line) { + Ok(_) => (), + Err(error) => exit_with_error(error) + } + }, + Err(error) => { + println!("{}", error) + } + } } fn run_objdump(use_wsl: bool, input: PathBuf) -> Result { @@ -28,31 +45,24 @@ fn run_objdump(use_wsl: bool, input: PathBuf) -> Result { } fn run_main(cmd: CommandLine) -> Result<(), Error> { - let mut child = run_objdump(cmd.use_wsl, cmd.input)?; + let output = tool_helper::open_output(cmd.output)?; + let memory_map = generate_memory_map(cmd.use_wsl, cmd.input)?; + + readmap::dump::write(output, &memory_map)?; + Ok(()) +} + +fn generate_memory_map(use_wsl: bool, input: PathBuf) -> Result { + let mut child = run_objdump(use_wsl, input)?; if let Some(stdout) = &mut child.stdout { let mut line_iter = BufReader::new(stdout).lines().map(|l| l.unwrap()).into_iter(); readmap::scan(|| { line_iter.next() - })?; - Ok(()) + }) } else { Err(Error::from_str("Failed opening \"stdout\" for objdump")) - } + } } - -pub fn main() { - match CommandLine::try_parse() { - Ok(cmd_line) => { - match run_main(cmd_line) { - Ok(_) => (), - Err(error) => exit_with_error(error) - } - }, - Err(error) => { - println!("{}", error) - } - } -} \ No newline at end of file From 23000d1d177906eae6b1723cc2932736d2ea140b Mon Sep 17 00:00:00 2001 From: jaby Date: Wed, 26 Jul 2023 20:37:35 +0200 Subject: [PATCH 080/588] Integrated new code into GUI --- src/Tools/psxreadmap/readmap/src/types/mod.rs | 5 -- src/Tools/psxreadmap/src/lib.rs | 13 ++--- src/Tools/psxreadmap/src/main.rs | 54 ++----------------- .../psxreadmap/src/readmap_helper/mod.rs | 34 ++++++++++++ 4 files changed, 46 insertions(+), 60 deletions(-) create mode 100644 src/Tools/psxreadmap/src/readmap_helper/mod.rs diff --git a/src/Tools/psxreadmap/readmap/src/types/mod.rs b/src/Tools/psxreadmap/readmap/src/types/mod.rs index af47a9ef..0509eda3 100644 --- a/src/Tools/psxreadmap/readmap/src/types/mod.rs +++ b/src/Tools/psxreadmap/readmap/src/types/mod.rs @@ -1,10 +1,5 @@ use std::default::Default; -pub struct MemoryMapInfo { - pub sections: Vec
, - pub highest_address: u64, -} - #[derive(Default)] pub struct MemoryMap { pub global: Vec, diff --git a/src/Tools/psxreadmap/src/lib.rs b/src/Tools/psxreadmap/src/lib.rs index 3c0cbea9..ae0b58fe 100644 --- a/src/Tools/psxreadmap/src/lib.rs +++ b/src/Tools/psxreadmap/src/lib.rs @@ -1,5 +1,6 @@ +mod readmap_helper; use crossterm::event::KeyCode; -use readmap::types::MemoryMapInfo; +use readmap::types::MemoryMap; use std::path::PathBuf; use tool_helper::Error; use tui::{ @@ -223,20 +224,20 @@ pub struct ConsoleUIData { impl ConsoleUIData { pub const HIGHEST_RAM_ADDRESS:u64 = 0x80000000 + (2*1024*1024); - pub fn new(memory_map: &MemoryMapInfo) -> Result { + pub fn new(memory_map: &MemoryMap) -> Result { let mut ui_data = ConsoleUIData::default(); ui_data.update(memory_map)?; Ok(ui_data) } - pub fn update(&mut self, memory_map: &MemoryMapInfo) -> Result<(), Error> { + pub fn update(&mut self, _memory_map: &MemoryMap) -> Result<(), Error> { - self.highest_adr = memory_map.highest_address; + self.highest_adr = 0; Ok(()) } } -pub fn load_memory_map(file_path: Option) -> Result { - readmap::scan(tool_helper::open_input(file_path)?) +pub fn load_memory_map(use_wsl: bool, input: PathBuf) -> Result { + readmap_helper::generate_memory_map(use_wsl, input) } \ No newline at end of file diff --git a/src/Tools/psxreadmap/src/main.rs b/src/Tools/psxreadmap/src/main.rs index 16ba99bb..089a10a0 100644 --- a/src/Tools/psxreadmap/src/main.rs +++ b/src/Tools/psxreadmap/src/main.rs @@ -9,7 +9,9 @@ use tui::backend::CrosstermBackend; #[clap(about = "Opens and scans a MAP file to print extended information", long_about = None)] struct CommandLine { #[clap(value_parser, help="Input MAP file for scannning")] - input: PathBuf + input: PathBuf, + #[clap(long="wsl", default_value_t=false)] + use_wsl: bool } pub fn main() { @@ -27,7 +29,7 @@ pub fn main() { } fn run_main(cmd: CommandLine) -> Result<(), Error> { - let memory_map = load_memory_map(Some(cmd.input))?; + let memory_map = load_memory_map(cmd.use_wsl, cmd.input)?; let rx = start_event_loop(); let terminal = setup_console()?; let ui_data = ConsoleUIData::new(&memory_map)?; @@ -89,50 +91,4 @@ fn setup_console() -> Result { terminal.clear()?; Ok(terminal) -} - -use std::{fs::File, io::{BufWriter, Write}}; -use readmap::types::{Content::*, Section}; -fn _write_main(cmd: CommandLine) -> Result<(), Error> { - fn value_to_hex(value: T) -> String { - return format!("0x{:X}", value); - } - - fn option_to_hex(value: Option) -> String { - if let Some(value) = value { - return value_to_hex(value); - } - - else { - return String::from(""); - } - } - - let memory_map = load_memory_map(Some(cmd.input))?; - let mut file = tool_helper::open_output_file(&PathBuf::from("./planschi.d"))?; - - for section in memory_map.sections { - fn print_content(tab_level: usize, file: &mut BufWriter, section: Section) -> Result<(), Error> { - for content in section.content { - match content { - Fill(fill) => { - writeln!(file, "{:>tab_level$}*fill* @{}, {}", ' ', value_to_hex(fill.adr), value_to_hex(fill.size), tab_level=tab_level*4)?; - }, - Section(section) => { - writeln!(file, "{:>tab_level$} {} @{}, {}", ' ', section.name, option_to_hex(section.adr), option_to_hex(section.size), tab_level=tab_level*4)?; - print_content(tab_level + 1, file, section)?; - }, - Symbol(symbol) => { - writeln!(file, "{:>tab_level$}{} @{}", ' ', symbol.name, value_to_hex(symbol.adr), tab_level=tab_level*4)?; - } - } - } - - Ok(()) - } - - writeln!(file, "{}: @{}, {}", section.name, option_to_hex(section.adr), option_to_hex(section.size))?; - print_content(1, &mut file, section)?; - } - Ok(()) -} +} \ No newline at end of file diff --git a/src/Tools/psxreadmap/src/readmap_helper/mod.rs b/src/Tools/psxreadmap/src/readmap_helper/mod.rs new file mode 100644 index 00000000..a202febc --- /dev/null +++ b/src/Tools/psxreadmap/src/readmap_helper/mod.rs @@ -0,0 +1,34 @@ +use tool_helper::Error; +use readmap::types::MemoryMap; +use std::{io::{BufRead, BufReader}, path::PathBuf, process::{Child, Command, Stdio}}; + +pub fn generate_memory_map(use_wsl: bool, input: PathBuf) -> Result { + let mut child = run_objdump(use_wsl, input)?; + if let Some(stdout) = &mut child.stdout { + let mut line_iter = BufReader::new(stdout).lines().map(|l| l.unwrap()).into_iter(); + + readmap::scan(|| { + line_iter.next() + }) + } + + else { + Err(Error::from_str("Failed opening \"stdout\" for objdump")) + } +} + +fn run_objdump(use_wsl: bool, input: PathBuf) -> Result { + let command_list = ["wsl", "objdump", "-x"]; + let start_idx = { + if use_wsl {0} + else {1} + }; + let mut process = Command::new(command_list[start_idx]); + + for arg in command_list.iter().skip(start_idx + 1) { + process.arg(arg); + } + process.arg(input.to_str().ok_or_else(||{Error::from_str("Failed converting input string")})?); + + Ok(process.stdout(Stdio::piped()).spawn()?) +} \ No newline at end of file From 5fcb0c83308512521faeec9f8b80ac64abbe64a8 Mon Sep 17 00:00:00 2001 From: jaby Date: Wed, 26 Jul 2023 21:49:47 +0200 Subject: [PATCH 081/588] Display memory usage --- src/Tools/Tools.code-workspace | 2 +- src/Tools/psxreadmap/src/lib.rs | 23 ++++++++++++++++++----- src/Tools/psxreadmap/src/main.rs | 16 ++++++++++++++-- 3 files changed, 33 insertions(+), 8 deletions(-) diff --git a/src/Tools/Tools.code-workspace b/src/Tools/Tools.code-workspace index e3442ac0..2fb9ea1b 100644 --- a/src/Tools/Tools.code-workspace +++ b/src/Tools/Tools.code-workspace @@ -82,7 +82,7 @@ "", "--help", "--list -o ../Tests/Test_Planschbecken psx bin-cue ../Tests/ISO_Planschbecken.xml", - "--wsl ../../../examples/PoolBox/application/bin/PSX-release/PoolBox.elf" + "--wsl -o Planschbecken.bin ../../../examples/PoolBox/application/bin/PSX-release/PoolBox.elf" ], "default": "", "description": "Argument options to pass to cargo run" diff --git a/src/Tools/psxreadmap/src/lib.rs b/src/Tools/psxreadmap/src/lib.rs index ae0b58fe..a9fdb518 100644 --- a/src/Tools/psxreadmap/src/lib.rs +++ b/src/Tools/psxreadmap/src/lib.rs @@ -197,11 +197,16 @@ impl ConsoleUI { } fn create_overall_mem_gauge<'a>(highest_adr: u64) -> LineGauge<'a> { + const RAM_TOP:u64 = ConsoleUIData::HIGHEST_RAM_ADDRESS & !ConsoleUIData::RAM_BASE_ADDRESS; + + let highest_adr_masked = highest_adr & !ConsoleUIData::RAM_BASE_ADDRESS; + let adr_ratio = (highest_adr_masked as f64)/RAM_TOP as f64; + LineGauge::default().block(Block::default().borders(Borders::ALL) - .title(format!("Memory Usage (0x{:x}/0x{:x})", highest_adr, ConsoleUIData::HIGHEST_RAM_ADDRESS))) + .title(format!("Memory Usage: {}% [0x{:x}/0x{:x}]", adr_ratio*100.0f64, highest_adr, ConsoleUIData::HIGHEST_RAM_ADDRESS))) .gauge_style(Style::default().fg(Color::White).bg(Color::Black).add_modifier(Modifier::BOLD)) .line_set(symbols::line::THICK) - .ratio(highest_adr as f64/ConsoleUIData::HIGHEST_RAM_ADDRESS as f64) + .ratio(adr_ratio) } fn create_exit_message<'a>() -> Paragraph<'a> { @@ -222,7 +227,8 @@ pub struct ConsoleUIData { } impl ConsoleUIData { - pub const HIGHEST_RAM_ADDRESS:u64 = 0x80000000 + (2*1024*1024); + pub const RAM_BASE_ADDRESS:u64 = 0x80000000; + pub const HIGHEST_RAM_ADDRESS:u64 = Self::RAM_BASE_ADDRESS + (2*1024*1024); pub fn new(memory_map: &MemoryMap) -> Result { let mut ui_data = ConsoleUIData::default(); @@ -231,9 +237,16 @@ impl ConsoleUIData { Ok(ui_data) } - pub fn update(&mut self, _memory_map: &MemoryMap) -> Result<(), Error> { + pub fn update(&mut self, memory_map: &MemoryMap) -> Result<(), Error> { + fn get_last_section_end_adr(memory_map: &MemoryMap) -> u64 { + if let Some(section) = memory_map.sections.last() { + return section.adr + section.size as u64; + } - self.highest_adr = 0; + 0u64 + } + + self.highest_adr = get_last_section_end_adr(memory_map); Ok(()) } } diff --git a/src/Tools/psxreadmap/src/main.rs b/src/Tools/psxreadmap/src/main.rs index 089a10a0..e2667df5 100644 --- a/src/Tools/psxreadmap/src/main.rs +++ b/src/Tools/psxreadmap/src/main.rs @@ -11,7 +11,9 @@ struct CommandLine { #[clap(value_parser, help="Input MAP file for scannning")] input: PathBuf, #[clap(long="wsl", default_value_t=false)] - use_wsl: bool + use_wsl: bool, + #[clap(short='o')] + output: Option } pub fn main() { @@ -29,7 +31,7 @@ pub fn main() { } fn run_main(cmd: CommandLine) -> Result<(), Error> { - let memory_map = load_memory_map(cmd.use_wsl, cmd.input)?; + let memory_map = load_memory_map(cmd.use_wsl, cmd.input)?; dump_memory_map(cmd.output, &memory_map)?; let rx = start_event_loop(); let terminal = setup_console()?; let ui_data = ConsoleUIData::new(&memory_map)?; @@ -46,6 +48,16 @@ fn run_main(cmd: CommandLine) -> Result<(), Error> { console_ui.close() } +fn dump_memory_map(output: Option, memory_map: &readmap::types::MemoryMap) -> Result<(), Error> { + if let Some(output) = output { + let output = tool_helper::open_output(Some(output))?; + + readmap::dump::write(output, &memory_map)?; + } + + Ok(()) +} + fn start_event_loop() -> EventReceiver { // Set up a mpsc (multiproducer, single consumer) channel to communicate between the input handler and the rendering loop. let (tx, rx) = mpsc::channel(); From 76b22fed4b7f30beb1d1cd871b828cedbbc022de Mon Sep 17 00:00:00 2001 From: jaby Date: Wed, 26 Jul 2023 21:50:20 +0200 Subject: [PATCH 082/588] Forgot gitignore --- src/Tools/.gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Tools/.gitignore b/src/Tools/.gitignore index cc8e0b0d..79637d92 100644 --- a/src/Tools/.gitignore +++ b/src/Tools/.gitignore @@ -3,4 +3,5 @@ Input/** Output/** *.lock -**/Tests/Test_*.* \ No newline at end of file +**/Tests/Test_*.* +**/Planschbecken.bin \ No newline at end of file From c8e86dcea4f910a1ca15ca065f6de496f48a5487 Mon Sep 17 00:00:00 2001 From: jaby Date: Wed, 26 Jul 2023 22:08:10 +0200 Subject: [PATCH 083/588] Improve Gauge usage --- src/Tools/psxreadmap/src/lib.rs | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/Tools/psxreadmap/src/lib.rs b/src/Tools/psxreadmap/src/lib.rs index a9fdb518..aa108164 100644 --- a/src/Tools/psxreadmap/src/lib.rs +++ b/src/Tools/psxreadmap/src/lib.rs @@ -6,9 +6,8 @@ use tool_helper::Error; use tui::{ layout::{Alignment, Constraint, Direction, Layout, Rect}, style::{Color, Modifier, Style}, - symbols, text::{Span, Spans}, - widgets::{Block, Borders, BorderType, LineGauge, Paragraph, Tabs} + widgets::{Block, Borders, BorderType, Gauge, Paragraph, Tabs} }; pub type EventReceiver = std::sync::mpsc::Receiver>; @@ -196,16 +195,15 @@ impl ConsoleUI { frame.render_widget(mem_gauge, frames[1]); } - fn create_overall_mem_gauge<'a>(highest_adr: u64) -> LineGauge<'a> { + fn create_overall_mem_gauge<'a>(highest_adr: u64) -> Gauge<'a> { const RAM_TOP:u64 = ConsoleUIData::HIGHEST_RAM_ADDRESS & !ConsoleUIData::RAM_BASE_ADDRESS; let highest_adr_masked = highest_adr & !ConsoleUIData::RAM_BASE_ADDRESS; let adr_ratio = (highest_adr_masked as f64)/RAM_TOP as f64; - LineGauge::default().block(Block::default().borders(Borders::ALL) + Gauge::default().block(Block::default().borders(Borders::ALL) .title(format!("Memory Usage: {}% [0x{:x}/0x{:x}]", adr_ratio*100.0f64, highest_adr, ConsoleUIData::HIGHEST_RAM_ADDRESS))) - .gauge_style(Style::default().fg(Color::White).bg(Color::Black).add_modifier(Modifier::BOLD)) - .line_set(symbols::line::THICK) + .gauge_style(Style::default().fg(Color::Cyan).bg(Color::Black).add_modifier(Modifier::BOLD)) .ratio(adr_ratio) } From f26b4ad7b0e35322a3ca894ff83da14c118c1fd5 Mon Sep 17 00:00:00 2001 From: jaby Date: Wed, 26 Jul 2023 22:16:09 +0200 Subject: [PATCH 084/588] Migrate to ratatui --- src/Tools/psxreadmap/Cargo.toml | 2 +- src/Tools/psxreadmap/src/lib.rs | 14 +++++++------- src/Tools/psxreadmap/src/main.rs | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/Tools/psxreadmap/Cargo.toml b/src/Tools/psxreadmap/Cargo.toml index de0875f9..e57d7caa 100644 --- a/src/Tools/psxreadmap/Cargo.toml +++ b/src/Tools/psxreadmap/Cargo.toml @@ -10,4 +10,4 @@ clap = {version = "*", features = ["derive"]} crossterm = "*" readmap = {version = "*", path = "readmap"} tool_helper = {version = "*", path = "../tool_helper"} -tui = "*" \ No newline at end of file +ratatui = "*" \ No newline at end of file diff --git a/src/Tools/psxreadmap/src/lib.rs b/src/Tools/psxreadmap/src/lib.rs index aa108164..055517d5 100644 --- a/src/Tools/psxreadmap/src/lib.rs +++ b/src/Tools/psxreadmap/src/lib.rs @@ -3,16 +3,16 @@ use crossterm::event::KeyCode; use readmap::types::MemoryMap; use std::path::PathBuf; use tool_helper::Error; -use tui::{ +use ratatui::{ layout::{Alignment, Constraint, Direction, Layout, Rect}, style::{Color, Modifier, Style}, - text::{Span, Spans}, + text::{Line, Span}, widgets::{Block, Borders, BorderType, Gauge, Paragraph, Tabs} }; pub type EventReceiver = std::sync::mpsc::Receiver>; -pub type Terminal = tui::Terminal>; -type ConsoleFrame<'a> = tui::Frame<'a, tui::backend::CrosstermBackend>; +pub type Terminal = ratatui::Terminal>; +type ConsoleFrame<'a> = ratatui::Frame<'a, ratatui::backend::CrosstermBackend>; pub enum Event { Input(I), @@ -138,12 +138,12 @@ impl ConsoleUI { Constraint::Length(3), Constraint::Length(3), Constraint::Min(3) - ]).split(new_frame); + ]).split(new_frame).to_vec(); *stats_frames = Layout::default().direction(Direction::Vertical).constraints([ Constraint::Min(3), Constraint::Length(3) - ]).split(sub_frames[2]); + ]).split(sub_frames[2]).to_vec(); *frame = new_frame; } @@ -165,7 +165,7 @@ impl ConsoleUI { let menu = MENU_TITLES.iter().map(|t| { let (first, rest) = t.split_at(1); - Spans::from(vec![ + Line::from(vec![ Span::styled(first, Style::default().fg(Color::Yellow).add_modifier(Modifier::UNDERLINED),), Span::styled(rest, Style::default().fg(Color::White)), ]) diff --git a/src/Tools/psxreadmap/src/main.rs b/src/Tools/psxreadmap/src/main.rs index e2667df5..519b1e8a 100644 --- a/src/Tools/psxreadmap/src/main.rs +++ b/src/Tools/psxreadmap/src/main.rs @@ -3,7 +3,7 @@ use crossterm::{event::{self, Event as CEvent, KeyboardEnhancementFlags, KeyEven use psxreadmap::{ConsoleUI, ConsoleUIData, Event, EventReceiver, Terminal, load_memory_map, UIState}; use std::{io, path::PathBuf, sync::mpsc, thread, time::{Duration, Instant}}; use tool_helper::{Error, exit_with_error}; -use tui::backend::CrosstermBackend; +use ratatui::backend::CrosstermBackend; #[derive(Parser)] #[clap(about = "Opens and scans a MAP file to print extended information", long_about = None)] From b98cbf9514bdbd0a3cdfb107a27c4d4145932ade Mon Sep 17 00:00:00 2001 From: jaby Date: Wed, 2 Aug 2023 22:31:40 +0200 Subject: [PATCH 085/588] Update to latest Rust --- src/Tools/cdtypes/src/types/bcd.rs | 2 +- src/Tools/cdtypes/src/types/date.rs | 2 +- src/Tools/cdtypes/src/types/error_correction/mod.rs | 4 ++-- src/Tools/cdtypes/src/types/sector.rs | 10 +++++----- src/Tools/psxcdgen_ex/src/encoder/psx.rs | 2 +- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/Tools/cdtypes/src/types/bcd.rs b/src/Tools/cdtypes/src/types/bcd.rs index 095905d1..66ffbbc2 100644 --- a/src/Tools/cdtypes/src/types/bcd.rs +++ b/src/Tools/cdtypes/src/types/bcd.rs @@ -1,5 +1,5 @@ #[derive(Debug)] -#[derive(Clone)] +#[derive(Clone, Copy)] pub struct BCDValue { value: u8 } diff --git a/src/Tools/cdtypes/src/types/date.rs b/src/Tools/cdtypes/src/types/date.rs index b149944f..2f54e208 100644 --- a/src/Tools/cdtypes/src/types/date.rs +++ b/src/Tools/cdtypes/src/types/date.rs @@ -128,7 +128,7 @@ impl Date { let mut value = ['0' as u8;SIZE]; for i in 0..SIZE { - value[(SIZE - 1 - i)] = ('0' as u32 + (number%10)) as u8; + value[SIZE - 1 - i] = ('0' as u32 + (number%10)) as u8; number /= 10; } value diff --git a/src/Tools/cdtypes/src/types/error_correction/mod.rs b/src/Tools/cdtypes/src/types/error_correction/mod.rs index e64c2d0b..e1a885de 100644 --- a/src/Tools/cdtypes/src/types/error_correction/mod.rs +++ b/src/Tools/cdtypes/src/types/error_correction/mod.rs @@ -4,13 +4,13 @@ use super::{sector::SECTOR_SIZE, lsb_msb::{ReadWriteEndian, LittleEndianU32}}; type RawSector = [u8; SECTOR_SIZE]; #[repr(packed(1))] -#[derive(Clone, Default)] +#[derive(Clone, Copy, Default)] pub struct EDC { data: LittleEndianU32 } #[repr(packed(1))] -#[derive(Clone)] +#[derive(Clone, Copy)] pub struct ECC { data: [u8; 276] } diff --git a/src/Tools/cdtypes/src/types/sector.rs b/src/Tools/cdtypes/src/types/sector.rs index c8e49cff..3357f06c 100644 --- a/src/Tools/cdtypes/src/types/sector.rs +++ b/src/Tools/cdtypes/src/types/sector.rs @@ -37,7 +37,7 @@ pub enum SubHeaderForm { } #[repr(packed(1))] -#[derive(Clone)] +#[derive(Clone, Copy)] pub struct Sync { value: [u8; 12], } @@ -59,7 +59,7 @@ impl std::fmt::Display for Sync { } #[repr(packed(1))] -#[derive(Clone)] +#[derive(Clone, Copy)] pub struct Header { minute: BCDValue, second: BCDValue, @@ -107,7 +107,7 @@ impl Default for Header { } #[repr(packed(1))] -#[derive(Clone)] +#[derive(Clone, Copy)] pub struct SubHeader { pub file_number: u8, pub channel_number: u8, @@ -156,7 +156,7 @@ impl Default for SubHeader { } #[repr(packed(1))] -#[derive(Clone)] +#[derive(Clone, Copy)] pub struct SubMode { value: u8 } @@ -202,7 +202,7 @@ impl Default for SubMode { } #[repr(packed(1))] -#[derive(Clone)] +#[derive(Clone, Copy)] pub struct CodingInfo { value: u8 } diff --git a/src/Tools/psxcdgen_ex/src/encoder/psx.rs b/src/Tools/psxcdgen_ex/src/encoder/psx.rs index 9d492144..3cc2e7e6 100644 --- a/src/Tools/psxcdgen_ex/src/encoder/psx.rs +++ b/src/Tools/psxcdgen_ex/src/encoder/psx.rs @@ -401,7 +401,7 @@ fn create_dir_record_raw<'a>(dst: &'a mut [u8], name: &str, track_rel_lba: u32, } unsafe { - let mut dir_record = std::mem::transmute::<&mut u8, &mut DirectoryRecord>(&mut dst[0]); + let dir_record = std::mem::transmute::<&mut u8, &mut DirectoryRecord>(&mut dst[0]); dir_record.new(name, has_system_use); dir_record.data_block_number.write(track_rel_lba); From 282db4e91eed9459dc165d027b70258cac626814 Mon Sep 17 00:00:00 2001 From: jaby Date: Sun, 6 Aug 2023 10:46:12 +0200 Subject: [PATCH 086/588] =?UTF-8?q?Support=20a=20list=20with=20Schwimmfl?= =?UTF-8?q?=C3=BCgel?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Tools/psxreadmap/src/lib.rs | 141 ++++++++++++++++++++++++++----- src/Tools/psxreadmap/src/main.rs | 6 +- 2 files changed, 121 insertions(+), 26 deletions(-) diff --git a/src/Tools/psxreadmap/src/lib.rs b/src/Tools/psxreadmap/src/lib.rs index 055517d5..c4f1737e 100644 --- a/src/Tools/psxreadmap/src/lib.rs +++ b/src/Tools/psxreadmap/src/lib.rs @@ -7,7 +7,7 @@ use ratatui::{ layout::{Alignment, Constraint, Direction, Layout, Rect}, style::{Color, Modifier, Style}, text::{Line, Span}, - widgets::{Block, Borders, BorderType, Gauge, Paragraph, Tabs} + widgets::{Block, Borders, BorderType, Gauge, List, ListItem, ListState, Paragraph, Tabs} }; pub type EventReceiver = std::sync::mpsc::Receiver>; @@ -51,21 +51,76 @@ impl MenuSelection { } } +pub struct ListSelection { + pub selection: Option +} + +impl ListSelection { + fn change_value(&mut self, max: usize, f: fn(usize)->usize) { + if let Some(cur_selection) = self.selection { + self.selection = Some(f(cur_selection)%max); + } + } + + pub fn increment(&mut self, max: usize) { + fn add_one(value: usize) -> usize { + value + 1 + } + self.change_value(max, add_one) + } + + pub fn decrement(&mut self, max: usize) { + fn sub_one(value: usize) -> usize { + value - 1 + } + self.change_value(max, sub_one) + } + + pub fn activate(&mut self) { + self.selection = Some(0); + } + + pub fn deactivate(&mut self) { + self.selection = None; + } + + pub fn is_active(&self) -> bool { + self.selection.is_some() + } +} + +impl Default for ListSelection { + fn default() -> Self { + Self{selection: None} + } +} + pub struct ConsoleUI { - rx: EventReceiver, - terminal: Terminal, - cur_size: Rect, - main_chunks: Vec, - stats_chunks: Vec, - menu_selection: MenuSelection, + rx: EventReceiver, + terminal: Terminal, + cur_size: Rect, + main_chunks: Vec, + stats_chunks: Vec, + menu_selection: MenuSelection, + content_selection: ListSelection, } impl ConsoleUI { pub fn new(rx: EventReceiver, terminal: Terminal) -> ConsoleUI { - ConsoleUI{rx, terminal, cur_size: Rect::default(), main_chunks: Vec::default(), stats_chunks: Vec::default(), menu_selection: MenuSelection::Stats} + ConsoleUI{rx, terminal, cur_size: Rect::default(), main_chunks: Vec::default(), stats_chunks: Vec::default(), menu_selection: MenuSelection::Stats, content_selection: ListSelection::default()} } - pub fn update(&mut self) -> Result { + pub fn update(&mut self, data: &ConsoleUIData) -> Result { + if data.list.len() > 0 { + if !self.content_selection.is_active() { + self.content_selection.activate(); + } + } + + else { + self.content_selection.deactivate(); + } + match self.rx.recv()? { Event::Input(event) => { match event.code { @@ -82,6 +137,26 @@ impl ConsoleUI { self.menu_selection = self.menu_selection.next(); Ok(UIState::Render) }, + KeyCode::Down => { + if matches!(self.menu_selection, MenuSelection::Stats) { + self.content_selection.increment(data.list.len()); + Ok(UIState::Render) + } + + else { + Ok(UIState::Alive) + } + }, + KeyCode::Up => { + if matches!(self.menu_selection, MenuSelection::Stats) { + self.content_selection.decrement(data.list.len()); + Ok(UIState::Render) + } + + else { + Ok(UIState::Alive) + } + }, KeyCode::Enter => { if matches!(self.menu_selection, MenuSelection::Quit) { Ok(UIState::Terminated) @@ -106,7 +181,7 @@ impl ConsoleUI { } } - pub fn render(&mut self, data: &ConsoleUIData) -> Result<(), Error> { + pub fn render(&mut self, data: &mut ConsoleUIData) -> Result<(), Error> { self.terminal.draw(|frame| { Self::update_sub_frames(&mut self.main_chunks, &mut self.stats_chunks, &mut self.cur_size, frame.size()); @@ -114,7 +189,7 @@ impl ConsoleUI { frame.render_widget(Self::create_menu(&self.menu_selection), self.main_chunks[1]); match self.menu_selection { MenuSelection::Stats => { - Self::render_stats(frame, &self.stats_chunks, data); + Self::render_stats(frame, &self.stats_chunks, &self.content_selection, data); }, MenuSelection::Quit => { frame.render_widget(Self::create_exit_message(), self.main_chunks[2]); @@ -180,18 +255,27 @@ impl ConsoleUI { ) } - fn render_stats(frame: &mut ConsoleFrame, frames: &Vec, data: &ConsoleUIData) { - let content_text = Paragraph::new("") - .style(Style::default().fg(Color::White)) - .alignment(Alignment::Center) - .block(Block::default() - .borders(Borders::ALL) - .style(Style::default().fg(Color::White)) - .border_type(BorderType::Plain) - ); - let mem_gauge = Self::create_overall_mem_gauge(data.highest_adr); + fn render_stats(frame: &mut ConsoleFrame, frames: &Vec, content_selection: &ListSelection, data: &mut ConsoleUIData) { + let content_list = List::new({ + let mut vec = Vec::new(); - frame.render_widget(content_text, frames[0]); + for item in &data.list { + vec.push(ListItem::new(item.as_str())) + } + vec + }).style(Style::default().fg(Color::White)) + .block(Block::default() + .borders(Borders::ALL) + .style(Style::default().fg(Color::White)) + .border_type(BorderType::Plain) + ) + .highlight_style(Style::default().bg(Color::Yellow)); + let mem_gauge = Self::create_overall_mem_gauge(data.highest_adr); + let mut list_state = ListState::default(); + + list_state.select(content_selection.selection); + + frame.render_stateful_widget(content_list, frames[0], &mut list_state); frame.render_widget(mem_gauge, frames[1]); } @@ -221,7 +305,8 @@ impl ConsoleUI { #[derive(Default)] pub struct ConsoleUIData { - highest_adr: u64 + highest_adr: u64, + list: Vec } impl ConsoleUIData { @@ -245,6 +330,16 @@ impl ConsoleUIData { } self.highest_adr = get_last_section_end_adr(memory_map); + self.list = vec![ + String::from("Schwimmflugel 0"), + String::from("Schwimmflugel 1"), + String::from("Schwimmflugel 2"), + String::from("Schwimmflugel 3"), + String::from("Schwimmflugel 4"), + String::from("Schwimmflugel 5"), + String::from("Schwimmflugel 6"), + String::from("Schwimmflugel 7"), + ]; Ok(()) } } diff --git a/src/Tools/psxreadmap/src/main.rs b/src/Tools/psxreadmap/src/main.rs index 519b1e8a..069dd6d6 100644 --- a/src/Tools/psxreadmap/src/main.rs +++ b/src/Tools/psxreadmap/src/main.rs @@ -34,13 +34,13 @@ fn run_main(cmd: CommandLine) -> Result<(), Error> { let memory_map = load_memory_map(cmd.use_wsl, cmd.input)?; dump_memory_map(cmd.output, &memory_map)?; let rx = start_event_loop(); let terminal = setup_console()?; - let ui_data = ConsoleUIData::new(&memory_map)?; + let mut ui_data = ConsoleUIData::new(&memory_map)?; let mut console_ui = ConsoleUI::new(rx, terminal); loop { - match console_ui.update()? { + match console_ui.update(&ui_data)? { UIState::Alive => (), - UIState::Render => {console_ui.render(&ui_data)?;} + UIState::Render => {console_ui.render(&mut ui_data)?;} UIState::Terminated => break } } From 520f0d028a74bf64475d0d64bc8dbab5f13641b2 Mon Sep 17 00:00:00 2001 From: jaby Date: Sat, 12 Aug 2023 11:38:51 +0200 Subject: [PATCH 087/588] Cleanup code --- src/Tools/psxreadmap/src/lib.rs | 153 +++++++++++++++---------------- src/Tools/psxreadmap/src/main.rs | 8 +- 2 files changed, 80 insertions(+), 81 deletions(-) diff --git a/src/Tools/psxreadmap/src/lib.rs b/src/Tools/psxreadmap/src/lib.rs index c4f1737e..2887dadb 100644 --- a/src/Tools/psxreadmap/src/lib.rs +++ b/src/Tools/psxreadmap/src/lib.rs @@ -96,22 +96,23 @@ impl Default for ListSelection { } pub struct ConsoleUI { + data: ConsoleUIData, rx: EventReceiver, terminal: Terminal, - cur_size: Rect, - main_chunks: Vec, - stats_chunks: Vec, + console_size: Rect, menu_selection: MenuSelection, content_selection: ListSelection, } impl ConsoleUI { pub fn new(rx: EventReceiver, terminal: Terminal) -> ConsoleUI { - ConsoleUI{rx, terminal, cur_size: Rect::default(), main_chunks: Vec::default(), stats_chunks: Vec::default(), menu_selection: MenuSelection::Stats, content_selection: ListSelection::default()} + ConsoleUI{data: ConsoleUIData::default(), rx, terminal, console_size: Rect::default(), menu_selection: MenuSelection::Stats, content_selection: ListSelection::default()} } - pub fn update(&mut self, data: &ConsoleUIData) -> Result { - if data.list.len() > 0 { + pub fn update_data(&mut self, memory_map: &MemoryMap) -> Result<(), Error> { + self.data.update(memory_map)?; + + if self.data.list.len() > 0 { if !self.content_selection.is_active() { self.content_selection.activate(); } @@ -120,7 +121,10 @@ impl ConsoleUI { else { self.content_selection.deactivate(); } + Ok(()) + } + pub fn update(&mut self) -> Result { match self.rx.recv()? { Event::Input(event) => { match event.code { @@ -129,17 +133,17 @@ impl ConsoleUI { self.menu_selection = MenuSelection::Stats; Ok(UIState::Render) }, - KeyCode::Left => { + KeyCode::Left => { self.menu_selection = self.menu_selection.prev(); Ok(UIState::Render) }, - KeyCode::Right => { + KeyCode::Right => { self.menu_selection = self.menu_selection.next(); Ok(UIState::Render) }, KeyCode::Down => { if matches!(self.menu_selection, MenuSelection::Stats) { - self.content_selection.increment(data.list.len()); + self.content_selection.increment(self.data.list.len()); Ok(UIState::Render) } @@ -147,9 +151,9 @@ impl ConsoleUI { Ok(UIState::Alive) } }, - KeyCode::Up => { + KeyCode::Up => { if matches!(self.menu_selection, MenuSelection::Stats) { - self.content_selection.decrement(data.list.len()); + self.content_selection.decrement(self.data.list.len()); Ok(UIState::Render) } @@ -157,7 +161,7 @@ impl ConsoleUI { Ok(UIState::Alive) } }, - KeyCode::Enter => { + KeyCode::Enter => { if matches!(self.menu_selection, MenuSelection::Quit) { Ok(UIState::Terminated) } @@ -168,8 +172,10 @@ impl ConsoleUI { _ => Ok(UIState::Alive) } }, - Event::Tick => { - if self.terminal.size().expect("Getting size of terminal") != self.cur_size { + Event::Tick => { + let terminal_size = self.terminal.size().expect("Getting size of terminal"); + if terminal_size != self.console_size { + self.console_size = terminal_size; Ok(UIState::Render) } @@ -181,18 +187,59 @@ impl ConsoleUI { } } - pub fn render(&mut self, data: &mut ConsoleUIData) -> Result<(), Error> { + pub fn render(&mut self) -> Result<(), Error> { self.terminal.draw(|frame| { - Self::update_sub_frames(&mut self.main_chunks, &mut self.stats_chunks, &mut self.cur_size, frame.size()); + // Create layout elements + let main_layout = Layout::default().direction(Direction::Vertical).constraints([ + Constraint::Length(3), + Constraint::Length(3), + Constraint::Min(3) + ]).split(frame.size()).to_vec(); + let stats_layout = Layout::default().direction(Direction::Vertical).constraints([ + Constraint::Min(3), + Constraint::Length(3) + ]).split(main_layout[2]).to_vec(); - frame.render_widget(Self::create_titel(), self.main_chunks[0]); - frame.render_widget(Self::create_menu(&self.menu_selection), self.main_chunks[1]); + // Elements + let titel_bar = { + Paragraph::new("psxreadmap") + .style(Style::default().fg(Color::White)) + .alignment(Alignment::Center) + .block(Block::default() + .borders(Borders::ALL) + .style(Style::default().fg(Color::White)) + .border_type(BorderType::Plain) + ) + }; + let menu_bar = { + const MENU_TITLES: &'static [&'static str] = &["Stats", "Quit"]; + + let menu = MENU_TITLES.iter().map(|t| { + let (first, rest) = t.split_at(1); + Line::from(vec![ + Span::styled(first, Style::default().fg(Color::Yellow).add_modifier(Modifier::UNDERLINED),), + Span::styled(rest, Style::default().fg(Color::White)), + ]) + }).collect(); + + Tabs::new(menu).select(self.menu_selection.get_id()).block( + Block::default() + .title("Menu").borders(Borders::ALL)) + .style(Style::default().fg(Color::White)) + .highlight_style(Style::default().bg(Color::LightYellow)) + .divider(Span::raw("|") + ) + }; + + // Render screen + frame.render_widget(titel_bar, main_layout[0]); + frame.render_widget(menu_bar, main_layout[1]); match self.menu_selection { MenuSelection::Stats => { - Self::render_stats(frame, &self.stats_chunks, &self.content_selection, data); + Self::render_stats(frame, &stats_layout, &self.content_selection, &mut self.data); }, MenuSelection::Quit => { - frame.render_widget(Self::create_exit_message(), self.main_chunks[2]); + frame.render_widget(Self::create_exit_message(), main_layout[2]); } } })?; @@ -207,54 +254,6 @@ impl ConsoleUI { Ok(()) } - fn update_sub_frames(sub_frames: &mut Vec, stats_frames: &mut Vec, frame: &mut Rect, new_frame: Rect) { - if new_frame != *frame { - *sub_frames = Layout::default().direction(Direction::Vertical).constraints([ - Constraint::Length(3), - Constraint::Length(3), - Constraint::Min(3) - ]).split(new_frame).to_vec(); - - *stats_frames = Layout::default().direction(Direction::Vertical).constraints([ - Constraint::Min(3), - Constraint::Length(3) - ]).split(sub_frames[2]).to_vec(); - - *frame = new_frame; - } - } - - fn create_titel<'a>() -> Paragraph<'a> { - Paragraph::new("psxreadmap") - .style(Style::default().fg(Color::White)) - .alignment(Alignment::Center) - .block(Block::default() - .borders(Borders::ALL) - .style(Style::default().fg(Color::White)) - .border_type(BorderType::Plain) - ) - } - - fn create_menu<'a>(menu_selection: &MenuSelection) -> Tabs<'a> { - const MENU_TITLES: &'static [&'static str] = &["Stats", "Quit"]; - - let menu = MENU_TITLES.iter().map(|t| { - let (first, rest) = t.split_at(1); - Line::from(vec![ - Span::styled(first, Style::default().fg(Color::Yellow).add_modifier(Modifier::UNDERLINED),), - Span::styled(rest, Style::default().fg(Color::White)), - ]) - }).collect(); - - Tabs::new(menu).select(menu_selection.get_id()).block( - Block::default() - .title("Menu").borders(Borders::ALL)) - .style(Style::default().fg(Color::White)) - .highlight_style(Style::default().bg(Color::LightYellow)) - .divider(Span::raw("|") - ) - } - fn render_stats(frame: &mut ConsoleFrame, frames: &Vec, content_selection: &ListSelection, data: &mut ConsoleUIData) { let content_list = List::new({ let mut vec = Vec::new(); @@ -270,7 +269,7 @@ impl ConsoleUI { .border_type(BorderType::Plain) ) .highlight_style(Style::default().bg(Color::Yellow)); - let mem_gauge = Self::create_overall_mem_gauge(data.highest_adr); + let mem_gauge = Self::create_mem_gauge("Overall memory usage", data.highest_adr, Color::Cyan); let mut list_state = ListState::default(); list_state.select(content_selection.selection); @@ -279,16 +278,16 @@ impl ConsoleUI { frame.render_widget(mem_gauge, frames[1]); } - fn create_overall_mem_gauge<'a>(highest_adr: u64) -> Gauge<'a> { + fn create_mem_gauge<'a>(name: &str, adr: u64, color: Color) -> Gauge<'a> { const RAM_TOP:u64 = ConsoleUIData::HIGHEST_RAM_ADDRESS & !ConsoleUIData::RAM_BASE_ADDRESS; - let highest_adr_masked = highest_adr & !ConsoleUIData::RAM_BASE_ADDRESS; - let adr_ratio = (highest_adr_masked as f64)/RAM_TOP as f64; + let adr_masked = adr & !ConsoleUIData::RAM_BASE_ADDRESS; + let adr_ratio = (adr_masked as f64)/RAM_TOP as f64; Gauge::default().block(Block::default().borders(Borders::ALL) - .title(format!("Memory Usage: {}% [0x{:x}/0x{:x}]", adr_ratio*100.0f64, highest_adr, ConsoleUIData::HIGHEST_RAM_ADDRESS))) - .gauge_style(Style::default().fg(Color::Cyan).bg(Color::Black).add_modifier(Modifier::BOLD)) - .ratio(adr_ratio) + .title(format!("{} [0x{:x}/0x{:x}]", name, adr, ConsoleUIData::HIGHEST_RAM_ADDRESS))) + .gauge_style(Style::default().fg(color).bg(Color::Black).add_modifier(Modifier::BOLD)) + .ratio(adr_ratio).label(format!("{}%", adr_ratio*100.0f64)) } fn create_exit_message<'a>() -> Paragraph<'a> { @@ -304,7 +303,7 @@ impl ConsoleUI { } #[derive(Default)] -pub struct ConsoleUIData { +struct ConsoleUIData { highest_adr: u64, list: Vec } @@ -313,7 +312,7 @@ impl ConsoleUIData { pub const RAM_BASE_ADDRESS:u64 = 0x80000000; pub const HIGHEST_RAM_ADDRESS:u64 = Self::RAM_BASE_ADDRESS + (2*1024*1024); - pub fn new(memory_map: &MemoryMap) -> Result { + fn _new(memory_map: &MemoryMap) -> Result { let mut ui_data = ConsoleUIData::default(); ui_data.update(memory_map)?; diff --git a/src/Tools/psxreadmap/src/main.rs b/src/Tools/psxreadmap/src/main.rs index 069dd6d6..d75e7d3e 100644 --- a/src/Tools/psxreadmap/src/main.rs +++ b/src/Tools/psxreadmap/src/main.rs @@ -1,6 +1,6 @@ use clap::Parser; use crossterm::{event::{self, Event as CEvent, KeyboardEnhancementFlags, KeyEventKind, PushKeyboardEnhancementFlags}, execute, terminal}; -use psxreadmap::{ConsoleUI, ConsoleUIData, Event, EventReceiver, Terminal, load_memory_map, UIState}; +use psxreadmap::{ConsoleUI, Event, EventReceiver, Terminal, load_memory_map, UIState}; use std::{io, path::PathBuf, sync::mpsc, thread, time::{Duration, Instant}}; use tool_helper::{Error, exit_with_error}; use ratatui::backend::CrosstermBackend; @@ -34,13 +34,13 @@ fn run_main(cmd: CommandLine) -> Result<(), Error> { let memory_map = load_memory_map(cmd.use_wsl, cmd.input)?; dump_memory_map(cmd.output, &memory_map)?; let rx = start_event_loop(); let terminal = setup_console()?; - let mut ui_data = ConsoleUIData::new(&memory_map)?; let mut console_ui = ConsoleUI::new(rx, terminal); + console_ui.update_data(&memory_map)?; loop { - match console_ui.update(&ui_data)? { + match console_ui.update()? { UIState::Alive => (), - UIState::Render => {console_ui.render(&mut ui_data)?;} + UIState::Render => {console_ui.render()?;} UIState::Terminated => break } } From 331c55f572e491c706fedcea5662ddd6eada2955 Mon Sep 17 00:00:00 2001 From: jaby Date: Sat, 12 Aug 2023 12:03:57 +0200 Subject: [PATCH 088/588] Introduce second memory gauge --- src/Tools/psxreadmap/src/lib.rs | 41 +++++++++++++-------------------- 1 file changed, 16 insertions(+), 25 deletions(-) diff --git a/src/Tools/psxreadmap/src/lib.rs b/src/Tools/psxreadmap/src/lib.rs index 2887dadb..7d6c187c 100644 --- a/src/Tools/psxreadmap/src/lib.rs +++ b/src/Tools/psxreadmap/src/lib.rs @@ -191,26 +191,11 @@ impl ConsoleUI { self.terminal.draw(|frame| { // Create layout elements let main_layout = Layout::default().direction(Direction::Vertical).constraints([ - Constraint::Length(3), Constraint::Length(3), Constraint::Min(3) ]).split(frame.size()).to_vec(); - let stats_layout = Layout::default().direction(Direction::Vertical).constraints([ - Constraint::Min(3), - Constraint::Length(3) - ]).split(main_layout[2]).to_vec(); // Elements - let titel_bar = { - Paragraph::new("psxreadmap") - .style(Style::default().fg(Color::White)) - .alignment(Alignment::Center) - .block(Block::default() - .borders(Borders::ALL) - .style(Style::default().fg(Color::White)) - .border_type(BorderType::Plain) - ) - }; let menu_bar = { const MENU_TITLES: &'static [&'static str] = &["Stats", "Quit"]; @@ -224,7 +209,7 @@ impl ConsoleUI { Tabs::new(menu).select(self.menu_selection.get_id()).block( Block::default() - .title("Menu").borders(Borders::ALL)) + .title("psxreadmap - Menu").borders(Borders::ALL)) .style(Style::default().fg(Color::White)) .highlight_style(Style::default().bg(Color::LightYellow)) .divider(Span::raw("|") @@ -232,14 +217,13 @@ impl ConsoleUI { }; // Render screen - frame.render_widget(titel_bar, main_layout[0]); - frame.render_widget(menu_bar, main_layout[1]); + frame.render_widget(menu_bar, main_layout[0]); match self.menu_selection { MenuSelection::Stats => { - Self::render_stats(frame, &stats_layout, &self.content_selection, &mut self.data); + Self::render_stats(frame, main_layout[1], &self.content_selection, &mut self.data); }, MenuSelection::Quit => { - frame.render_widget(Self::create_exit_message(), main_layout[2]); + frame.render_widget(Self::create_exit_message(), main_layout[1]); } } })?; @@ -254,7 +238,12 @@ impl ConsoleUI { Ok(()) } - fn render_stats(frame: &mut ConsoleFrame, frames: &Vec, content_selection: &ListSelection, data: &mut ConsoleUIData) { + fn render_stats(frame: &mut ConsoleFrame, layout: Rect, content_selection: &ListSelection, data: &mut ConsoleUIData) { + let layout = Layout::default().direction(Direction::Vertical).constraints([ + Constraint::Min(3), + Constraint::Min(3), + Constraint::Length(3), + ]).split(layout).to_vec(); let content_list = List::new({ let mut vec = Vec::new(); @@ -268,14 +257,16 @@ impl ConsoleUI { .style(Style::default().fg(Color::White)) .border_type(BorderType::Plain) ) - .highlight_style(Style::default().bg(Color::Yellow)); - let mem_gauge = Self::create_mem_gauge("Overall memory usage", data.highest_adr, Color::Cyan); + .highlight_style(Style::default().bg(Color::Cyan)); + let first_mem_gauge = Self::create_mem_gauge("Overall memory usage", data.highest_adr, Color::Cyan); + let second_mem_gauge = Self::create_mem_gauge("Overall memory usage", data.highest_adr, Color::Red); let mut list_state = ListState::default(); list_state.select(content_selection.selection); - frame.render_stateful_widget(content_list, frames[0], &mut list_state); - frame.render_widget(mem_gauge, frames[1]); + frame.render_stateful_widget(content_list, layout[0], &mut list_state); + frame.render_widget(first_mem_gauge, layout[1]); + frame.render_widget(second_mem_gauge, layout[2]); } fn create_mem_gauge<'a>(name: &str, adr: u64, color: Color) -> Gauge<'a> { From 3a736419519277e2555e1fc2ee3be1d0f853e618 Mon Sep 17 00:00:00 2001 From: jaby Date: Sat, 12 Aug 2023 12:43:00 +0200 Subject: [PATCH 089/588] Fix rollover of list selection --- src/Tools/psxreadmap/src/lib.rs | 59 ++++++++++++++++++--------------- 1 file changed, 33 insertions(+), 26 deletions(-) diff --git a/src/Tools/psxreadmap/src/lib.rs b/src/Tools/psxreadmap/src/lib.rs index 7d6c187c..097f2ee4 100644 --- a/src/Tools/psxreadmap/src/lib.rs +++ b/src/Tools/psxreadmap/src/lib.rs @@ -56,24 +56,38 @@ pub struct ListSelection { } impl ListSelection { - fn change_value(&mut self, max: usize, f: fn(usize)->usize) { - if let Some(cur_selection) = self.selection { - self.selection = Some(f(cur_selection)%max); - } - } - pub fn increment(&mut self, max: usize) { - fn add_one(value: usize) -> usize { - value + 1 + if let Some(cur_selection) = self.selection { + self.selection = Some({ + if cur_selection + 1 >= max { + 0 + } + + else { + cur_selection + 1 + } + }); } - self.change_value(max, add_one) } pub fn decrement(&mut self, max: usize) { - fn sub_one(value: usize) -> usize { - value - 1 + if let Some(cur_selection) = self.selection { + self.selection = Some({ + if cur_selection - 1 >= max { + if max - 1 > 0 { + max - 1 + } + + else { + 0 + } + } + + else { + cur_selection - 1 + } + }); } - self.change_value(max, sub_one) } pub fn activate(&mut self) { @@ -169,7 +183,7 @@ impl ConsoleUI { Ok(UIState::Alive) } }, - _ => Ok(UIState::Alive) + _ => Ok(UIState::Alive) } }, Event::Tick => { @@ -240,9 +254,9 @@ impl ConsoleUI { fn render_stats(frame: &mut ConsoleFrame, layout: Rect, content_selection: &ListSelection, data: &mut ConsoleUIData) { let layout = Layout::default().direction(Direction::Vertical).constraints([ - Constraint::Min(3), - Constraint::Min(3), Constraint::Length(3), + Constraint::Max(3), + Constraint::Max(3), ]).split(layout).to_vec(); let content_list = List::new({ let mut vec = Vec::new(); @@ -315,21 +329,14 @@ impl ConsoleUIData { if let Some(section) = memory_map.sections.last() { return section.adr + section.size as u64; } - 0u64 } self.highest_adr = get_last_section_end_adr(memory_map); - self.list = vec![ - String::from("Schwimmflugel 0"), - String::from("Schwimmflugel 1"), - String::from("Schwimmflugel 2"), - String::from("Schwimmflugel 3"), - String::from("Schwimmflugel 4"), - String::from("Schwimmflugel 5"), - String::from("Schwimmflugel 6"), - String::from("Schwimmflugel 7"), - ]; + self.list = vec![String::from("")]; + for section in &memory_map.sections { + self.list.push(section.name.clone()); + } Ok(()) } } From f2328601edbf8443e6231cc3ffbaf86b617ce3f6 Mon Sep 17 00:00:00 2001 From: jaby Date: Sat, 12 Aug 2023 19:13:38 +0200 Subject: [PATCH 090/588] Introduce new gauge type --- src/Tools/psxreadmap/src/lib.rs | 80 ++++++++++++++++++++++----------- 1 file changed, 54 insertions(+), 26 deletions(-) diff --git a/src/Tools/psxreadmap/src/lib.rs b/src/Tools/psxreadmap/src/lib.rs index 097f2ee4..9d6c2628 100644 --- a/src/Tools/psxreadmap/src/lib.rs +++ b/src/Tools/psxreadmap/src/lib.rs @@ -71,20 +71,15 @@ impl ListSelection { } pub fn decrement(&mut self, max: usize) { - if let Some(cur_selection) = self.selection { + if let Some(mut cur_selection) = self.selection { self.selection = Some({ - if cur_selection - 1 >= max { - if max - 1 > 0 { + cur_selection = cur_selection - 1; + if cur_selection > max - 1 { max - 1 - } - - else { - 0 - } } else { - cur_selection - 1 + cur_selection } }); } @@ -124,7 +119,7 @@ impl ConsoleUI { } pub fn update_data(&mut self, memory_map: &MemoryMap) -> Result<(), Error> { - self.data.update(memory_map)?; + self.data = ConsoleUIData::from(memory_map)?; if self.data.list.len() > 0 { if !self.content_selection.is_active() { @@ -273,7 +268,7 @@ impl ConsoleUI { ) .highlight_style(Style::default().bg(Color::Cyan)); let first_mem_gauge = Self::create_mem_gauge("Overall memory usage", data.highest_adr, Color::Cyan); - let second_mem_gauge = Self::create_mem_gauge("Overall memory usage", data.highest_adr, Color::Red); + let second_mem_gauge = Self::create_mem_gauge_from(&data.overall_info, Color::Red); let mut list_state = ListState::default(); list_state.select(content_selection.selection); @@ -295,6 +290,15 @@ impl ConsoleUI { .ratio(adr_ratio).label(format!("{}%", adr_ratio*100.0f64)) } + fn create_mem_gauge_from<'a>(section_info: &SectionInfo, color: Color) -> Gauge<'a> { + let adr_ratio = section_info.get_size_ratio(); + Gauge::default().block(Block::default().borders(Borders::ALL) + .title(format!("{} @0x{:x} - 0x{:x} [{}b/{}b]", + section_info.name, section_info.start_adr, section_info.get_end_adr(), section_info.size, section_info.max_size))) + .gauge_style(Style::default().fg(color).bg(Color::Black).add_modifier(Modifier::BOLD)) + .ratio(adr_ratio).label(format!("{}%", adr_ratio*100.0f64)) + } + fn create_exit_message<'a>() -> Paragraph<'a> { Paragraph::new("Press \"ENTER\" to exit") .style(Style::default().fg(Color::White)) @@ -309,22 +313,17 @@ impl ConsoleUI { #[derive(Default)] struct ConsoleUIData { - highest_adr: u64, - list: Vec + highest_adr: u64, + overall_info: SectionInfo, + list: Vec } impl ConsoleUIData { pub const RAM_BASE_ADDRESS:u64 = 0x80000000; - pub const HIGHEST_RAM_ADDRESS:u64 = Self::RAM_BASE_ADDRESS + (2*1024*1024); + pub const RAM_SIZE:usize = 2*1024*1024; + pub const HIGHEST_RAM_ADDRESS:u64 = Self::RAM_BASE_ADDRESS + Self::RAM_SIZE as u64; - fn _new(memory_map: &MemoryMap) -> Result { - let mut ui_data = ConsoleUIData::default(); - - ui_data.update(memory_map)?; - Ok(ui_data) - } - - pub fn update(&mut self, memory_map: &MemoryMap) -> Result<(), Error> { + pub fn from(memory_map: &MemoryMap) -> Result { fn get_last_section_end_adr(memory_map: &MemoryMap) -> u64 { if let Some(section) = memory_map.sections.last() { return section.adr + section.size as u64; @@ -332,12 +331,41 @@ impl ConsoleUIData { 0u64 } - self.highest_adr = get_last_section_end_adr(memory_map); - self.list = vec![String::from("")]; + let mut new_self = ConsoleUIData::default(); + + new_self.highest_adr = get_last_section_end_adr(memory_map); + new_self.list = vec![String::from("")]; for section in &memory_map.sections { - self.list.push(section.name.clone()); + new_self.list.push(section.name.clone()); } - Ok(()) + + // Testing new data type + new_self.overall_info = SectionInfo{ + name: "Schwimmflügel".to_string(), + start_adr: Self::RAM_BASE_ADDRESS, + size: (new_self.highest_adr - Self::RAM_BASE_ADDRESS) as usize, + max_size: Self::RAM_SIZE + }; + + Ok(new_self) + } +} + +#[derive(Default)] +struct SectionInfo { + pub name: String, + pub start_adr: u64, + pub size: usize, + pub max_size: usize, +} + +impl SectionInfo { + fn get_end_adr(&self) -> u64 { + self.start_adr + self.size as u64 + } + + fn get_size_ratio(&self) -> f64 { + self.size as f64 / self.max_size as f64 } } From 94e015229f30ea42f5976961f410405cb86b4c85 Mon Sep 17 00:00:00 2001 From: jaby Date: Sat, 12 Aug 2023 19:37:15 +0200 Subject: [PATCH 091/588] Support sections now --- src/Tools/psxreadmap/src/lib.rs | 201 +++++++++++++++++--------------- 1 file changed, 104 insertions(+), 97 deletions(-) diff --git a/src/Tools/psxreadmap/src/lib.rs b/src/Tools/psxreadmap/src/lib.rs index 9d6c2628..77055180 100644 --- a/src/Tools/psxreadmap/src/lib.rs +++ b/src/Tools/psxreadmap/src/lib.rs @@ -110,90 +110,106 @@ pub struct ConsoleUI { terminal: Terminal, console_size: Rect, menu_selection: MenuSelection, - content_selection: ListSelection, + section_selection: ListSelection, + first_section_id: usize, + second_section_id: usize, } impl ConsoleUI { pub fn new(rx: EventReceiver, terminal: Terminal) -> ConsoleUI { - ConsoleUI{data: ConsoleUIData::default(), rx, terminal, console_size: Rect::default(), menu_selection: MenuSelection::Stats, content_selection: ListSelection::default()} + ConsoleUI{data: ConsoleUIData::default(), rx, terminal, console_size: Rect::default(), menu_selection: MenuSelection::Stats, section_selection: ListSelection::default(), first_section_id: 0, second_section_id: 0} } pub fn update_data(&mut self, memory_map: &MemoryMap) -> Result<(), Error> { self.data = ConsoleUIData::from(memory_map)?; - if self.data.list.len() > 0 { - if !self.content_selection.is_active() { - self.content_selection.activate(); + if self.data.section_info.len() > 0 { + if !self.section_selection.is_active() { + self.section_selection.activate(); } } else { - self.content_selection.deactivate(); + self.section_selection.deactivate(); } Ok(()) } pub fn update(&mut self) -> Result { - match self.rx.recv()? { - Event::Input(event) => { - match event.code { - KeyCode::Char('q') => Ok(UIState::Terminated), - KeyCode::Char('s') => { - self.menu_selection = MenuSelection::Stats; - Ok(UIState::Render) - }, - KeyCode::Left => { - self.menu_selection = self.menu_selection.prev(); - Ok(UIState::Render) - }, - KeyCode::Right => { - self.menu_selection = self.menu_selection.next(); - Ok(UIState::Render) - }, - KeyCode::Down => { - if matches!(self.menu_selection, MenuSelection::Stats) { - self.content_selection.increment(self.data.list.len()); + let input_result = { + match self.rx.recv()? { + Event::Input(event) => { + match event.code { + KeyCode::Char('q') => Ok(UIState::Terminated), + KeyCode::Char('s') => { + self.menu_selection = MenuSelection::Stats; Ok(UIState::Render) - } - - else { - Ok(UIState::Alive) - } - }, - KeyCode::Up => { - if matches!(self.menu_selection, MenuSelection::Stats) { - self.content_selection.decrement(self.data.list.len()); + }, + KeyCode::Left => { + self.menu_selection = self.menu_selection.prev(); Ok(UIState::Render) - } + }, + KeyCode::Right => { + self.menu_selection = self.menu_selection.next(); + Ok(UIState::Render) + }, + KeyCode::Down => { + if matches!(self.menu_selection, MenuSelection::Stats) { + self.section_selection.increment(self.data.section_info.len()); + Ok(UIState::Render) + } - else { - Ok(UIState::Alive) - } - }, - KeyCode::Enter => { - if matches!(self.menu_selection, MenuSelection::Quit) { - Ok(UIState::Terminated) - } - else { - Ok(UIState::Alive) - } - }, - _ => Ok(UIState::Alive) - } - }, - Event::Tick => { - let terminal_size = self.terminal.size().expect("Getting size of terminal"); - if terminal_size != self.console_size { - self.console_size = terminal_size; - Ok(UIState::Render) - } + else { + Ok(UIState::Alive) + } + }, + KeyCode::Up => { + if matches!(self.menu_selection, MenuSelection::Stats) { + self.section_selection.decrement(self.data.section_info.len()); + Ok(UIState::Render) + } - else { - Ok(UIState::Alive) - } - }, - Event::ForceRender => Ok(UIState::Render) - } + else { + Ok(UIState::Alive) + } + }, + KeyCode::Enter => { + if matches!(self.menu_selection, MenuSelection::Quit) { + Ok(UIState::Terminated) + } + else { + Ok(UIState::Alive) + } + }, + _ => Ok(UIState::Alive) + } + }, + Event::Tick => { + let terminal_size = self.terminal.size().expect("Getting size of terminal"); + if terminal_size != self.console_size { + self.console_size = terminal_size; + Ok(UIState::Render) + } + + else { + Ok(UIState::Alive) + } + }, + Event::ForceRender => Ok(UIState::Render) + } + }; + + self.first_section_id = { + if let Some(selection) = self.section_selection.selection { + selection + } + + else { + 0 + } + }; + + input_result } pub fn render(&mut self) -> Result<(), Error> { @@ -229,7 +245,8 @@ impl ConsoleUI { frame.render_widget(menu_bar, main_layout[0]); match self.menu_selection { MenuSelection::Stats => { - Self::render_stats(frame, main_layout[1], &self.content_selection, &mut self.data); + // ToDo: v This is the same and we always have elements now + Self::render_stats(frame, main_layout[1], (&self.section_selection, self.first_section_id), &mut self.data); }, MenuSelection::Quit => { frame.render_widget(Self::create_exit_message(), main_layout[1]); @@ -247,7 +264,7 @@ impl ConsoleUI { Ok(()) } - fn render_stats(frame: &mut ConsoleFrame, layout: Rect, content_selection: &ListSelection, data: &mut ConsoleUIData) { + fn render_stats(frame: &mut ConsoleFrame, layout: Rect, content_selection: (&ListSelection, usize), data: &mut ConsoleUIData) { let layout = Layout::default().direction(Direction::Vertical).constraints([ Constraint::Length(3), Constraint::Max(3), @@ -256,8 +273,8 @@ impl ConsoleUI { let content_list = List::new({ let mut vec = Vec::new(); - for item in &data.list { - vec.push(ListItem::new(item.as_str())) + for section in &data.section_info { + vec.push(ListItem::new(section.name.clone())) } vec }).style(Style::default().fg(Color::White)) @@ -267,29 +284,18 @@ impl ConsoleUI { .border_type(BorderType::Plain) ) .highlight_style(Style::default().bg(Color::Cyan)); - let first_mem_gauge = Self::create_mem_gauge("Overall memory usage", data.highest_adr, Color::Cyan); - let second_mem_gauge = Self::create_mem_gauge_from(&data.overall_info, Color::Red); + + let first_mem_gauge = Self::create_mem_gauge_from(&data.section_info[content_selection.1], Color::Cyan); + let second_mem_gauge = Self::create_mem_gauge_from(&data.section_info[0], Color::Red); let mut list_state = ListState::default(); - list_state.select(content_selection.selection); + list_state.select(content_selection.0.selection); frame.render_stateful_widget(content_list, layout[0], &mut list_state); frame.render_widget(first_mem_gauge, layout[1]); frame.render_widget(second_mem_gauge, layout[2]); } - fn create_mem_gauge<'a>(name: &str, adr: u64, color: Color) -> Gauge<'a> { - const RAM_TOP:u64 = ConsoleUIData::HIGHEST_RAM_ADDRESS & !ConsoleUIData::RAM_BASE_ADDRESS; - - let adr_masked = adr & !ConsoleUIData::RAM_BASE_ADDRESS; - let adr_ratio = (adr_masked as f64)/RAM_TOP as f64; - - Gauge::default().block(Block::default().borders(Borders::ALL) - .title(format!("{} [0x{:x}/0x{:x}]", name, adr, ConsoleUIData::HIGHEST_RAM_ADDRESS))) - .gauge_style(Style::default().fg(color).bg(Color::Black).add_modifier(Modifier::BOLD)) - .ratio(adr_ratio).label(format!("{}%", adr_ratio*100.0f64)) - } - fn create_mem_gauge_from<'a>(section_info: &SectionInfo, color: Color) -> Gauge<'a> { let adr_ratio = section_info.get_size_ratio(); Gauge::default().block(Block::default().borders(Borders::ALL) @@ -313,15 +319,12 @@ impl ConsoleUI { #[derive(Default)] struct ConsoleUIData { - highest_adr: u64, - overall_info: SectionInfo, - list: Vec + section_info: Vec } impl ConsoleUIData { pub const RAM_BASE_ADDRESS:u64 = 0x80000000; pub const RAM_SIZE:usize = 2*1024*1024; - pub const HIGHEST_RAM_ADDRESS:u64 = Self::RAM_BASE_ADDRESS + Self::RAM_SIZE as u64; pub fn from(memory_map: &MemoryMap) -> Result { fn get_last_section_end_adr(memory_map: &MemoryMap) -> u64 { @@ -331,21 +334,25 @@ impl ConsoleUIData { 0u64 } - let mut new_self = ConsoleUIData::default(); + let mut new_self = ConsoleUIData::default(); + let highest_adr = get_last_section_end_adr(memory_map); + let program_size = (highest_adr - Self::RAM_BASE_ADDRESS) as usize; - new_self.highest_adr = get_last_section_end_adr(memory_map); - new_self.list = vec![String::from("")]; - for section in &memory_map.sections { - new_self.list.push(section.name.clone()); - } - - // Testing new data type - new_self.overall_info = SectionInfo{ - name: "Schwimmflügel".to_string(), + new_self.section_info.push(SectionInfo{ + name: String::from(""), start_adr: Self::RAM_BASE_ADDRESS, - size: (new_self.highest_adr - Self::RAM_BASE_ADDRESS) as usize, + size: program_size, max_size: Self::RAM_SIZE - }; + }); + + for section in &memory_map.sections { + new_self.section_info.push(SectionInfo{ + name: section.name.clone(), + start_adr: section.adr, + size: section.size, + max_size: program_size + }); + } Ok(new_self) } From b5427e3cecbcb26ac7e768d3eaed458809120b88 Mon Sep 17 00:00:00 2001 From: jaby Date: Tue, 15 Aug 2023 15:21:10 +0200 Subject: [PATCH 092/588] Cleanup selection code --- src/Tools/psxreadmap/src/lib.rs | 85 +++++++++++---------------------- 1 file changed, 27 insertions(+), 58 deletions(-) diff --git a/src/Tools/psxreadmap/src/lib.rs b/src/Tools/psxreadmap/src/lib.rs index 77055180..626f5d5a 100644 --- a/src/Tools/psxreadmap/src/lib.rs +++ b/src/Tools/psxreadmap/src/lib.rs @@ -52,55 +52,42 @@ impl MenuSelection { } pub struct ListSelection { - pub selection: Option + pub id: usize } impl ListSelection { pub fn increment(&mut self, max: usize) { - if let Some(cur_selection) = self.selection { - self.selection = Some({ - if cur_selection + 1 >= max { - 0 - } + let new_selection = self.id + 1; - else { - cur_selection + 1 - } - }); - } + self.id = { + if new_selection >= max { + 0 + } + + else { + new_selection + } + } } pub fn decrement(&mut self, max: usize) { - if let Some(mut cur_selection) = self.selection { - self.selection = Some({ - cur_selection = cur_selection - 1; - if cur_selection > max - 1 { - max - 1 - } + let new_selection = self.id - 1; - else { - cur_selection - } - }); + self.id = { + if new_selection >= max { + max - 1 + } + + else { + new_selection + } } } - - pub fn activate(&mut self) { - self.selection = Some(0); - } - - pub fn deactivate(&mut self) { - self.selection = None; - } - - pub fn is_active(&self) -> bool { - self.selection.is_some() - } } impl Default for ListSelection { fn default() -> Self { - Self{selection: None} + Self{id: 0} } } @@ -122,16 +109,8 @@ impl ConsoleUI { pub fn update_data(&mut self, memory_map: &MemoryMap) -> Result<(), Error> { self.data = ConsoleUIData::from(memory_map)?; + self.section_selection = ListSelection::default(); - if self.data.section_info.len() > 0 { - if !self.section_selection.is_active() { - self.section_selection.activate(); - } - } - - else { - self.section_selection.deactivate(); - } Ok(()) } @@ -199,16 +178,7 @@ impl ConsoleUI { } }; - self.first_section_id = { - if let Some(selection) = self.section_selection.selection { - selection - } - - else { - 0 - } - }; - + self.first_section_id = self.section_selection.id; input_result } @@ -245,8 +215,7 @@ impl ConsoleUI { frame.render_widget(menu_bar, main_layout[0]); match self.menu_selection { MenuSelection::Stats => { - // ToDo: v This is the same and we always have elements now - Self::render_stats(frame, main_layout[1], (&self.section_selection, self.first_section_id), &mut self.data); + Self::render_stats(frame, main_layout[1], &self.section_selection, &mut self.data); }, MenuSelection::Quit => { frame.render_widget(Self::create_exit_message(), main_layout[1]); @@ -264,7 +233,7 @@ impl ConsoleUI { Ok(()) } - fn render_stats(frame: &mut ConsoleFrame, layout: Rect, content_selection: (&ListSelection, usize), data: &mut ConsoleUIData) { + fn render_stats(frame: &mut ConsoleFrame, layout: Rect, content_selection: &ListSelection, data: &mut ConsoleUIData) { let layout = Layout::default().direction(Direction::Vertical).constraints([ Constraint::Length(3), Constraint::Max(3), @@ -285,11 +254,11 @@ impl ConsoleUI { ) .highlight_style(Style::default().bg(Color::Cyan)); - let first_mem_gauge = Self::create_mem_gauge_from(&data.section_info[content_selection.1], Color::Cyan); + let first_mem_gauge = Self::create_mem_gauge_from(&data.section_info[content_selection.id], Color::Cyan); let second_mem_gauge = Self::create_mem_gauge_from(&data.section_info[0], Color::Red); let mut list_state = ListState::default(); - list_state.select(content_selection.0.selection); + list_state.select(Some(content_selection.id)); frame.render_stateful_widget(content_list, layout[0], &mut list_state); frame.render_widget(first_mem_gauge, layout[1]); From d102ecc3d06de5b9a70ad06ea20e7d16688fe636 Mon Sep 17 00:00:00 2001 From: jaby Date: Wed, 16 Aug 2023 11:21:10 +0200 Subject: [PATCH 093/588] Reduce percision for display --- src/Tools/psxreadmap/src/lib.rs | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/src/Tools/psxreadmap/src/lib.rs b/src/Tools/psxreadmap/src/lib.rs index 626f5d5a..2f1e1964 100644 --- a/src/Tools/psxreadmap/src/lib.rs +++ b/src/Tools/psxreadmap/src/lib.rs @@ -266,12 +266,34 @@ impl ConsoleUI { } fn create_mem_gauge_from<'a>(section_info: &SectionInfo, color: Color) -> Gauge<'a> { + const PERCISION:usize = 5; + const FLOAT_DISPLAY_LIMIT:f64 = { + let mut base = 1.0f64; + let mut i = 0; + + while i < PERCISION { + base = base/10.0f64; + i += 1; + + } + base + }; + let adr_ratio = section_info.get_size_ratio(); Gauge::default().block(Block::default().borders(Borders::ALL) .title(format!("{} @0x{:x} - 0x{:x} [{}b/{}b]", section_info.name, section_info.start_adr, section_info.get_end_adr(), section_info.size, section_info.max_size))) .gauge_style(Style::default().fg(color).bg(Color::Black).add_modifier(Modifier::BOLD)) - .ratio(adr_ratio).label(format!("{}%", adr_ratio*100.0f64)) + .ratio(adr_ratio).label({ + let adr_ratio = adr_ratio*100.0f64; + if adr_ratio > FLOAT_DISPLAY_LIMIT { + format!("{:.width$}%", adr_ratio, width=PERCISION) + } + + else { + format!("< {:.width$}%", FLOAT_DISPLAY_LIMIT, width=PERCISION) + } + }) } fn create_exit_message<'a>() -> Paragraph<'a> { From 38b49ad75b7b87faebedfca690689de71fa9ae2c Mon Sep 17 00:00:00 2001 From: jaby Date: Wed, 16 Aug 2023 15:15:39 +0200 Subject: [PATCH 094/588] Switch between selections --- src/Tools/psxreadmap/src/lib.rs | 122 ++++++++++++++++++++------------ 1 file changed, 78 insertions(+), 44 deletions(-) diff --git a/src/Tools/psxreadmap/src/lib.rs b/src/Tools/psxreadmap/src/lib.rs index 2f1e1964..5eca68e4 100644 --- a/src/Tools/psxreadmap/src/lib.rs +++ b/src/Tools/psxreadmap/src/lib.rs @@ -26,7 +26,7 @@ pub enum UIState { Terminated } -pub enum MenuSelection { +enum MenuSelection { Stats, Quit, } @@ -51,15 +51,32 @@ impl MenuSelection { } } -pub struct ListSelection { - pub id: usize +#[derive(Copy, Clone)] +enum SectionMode { + UpperSection, + LowerSection, } -impl ListSelection { - pub fn increment(&mut self, max: usize) { - let new_selection = self.id + 1; +impl SectionMode { + pub fn as_id(&self) -> usize { + match self { + SectionMode::UpperSection => 0, + SectionMode::LowerSection => 1, + } + } +} - self.id = { +struct SectionSelection { + mode: SectionMode, + id: [usize; 2] +} + +impl SectionSelection { + fn increment(&mut self, max: usize) { + let cur_id = &mut self.id[self.mode.as_id()]; + let new_selection = *cur_id + 1; + + *cur_id = { if new_selection >= max { 0 } @@ -70,10 +87,11 @@ impl ListSelection { } } - pub fn decrement(&mut self, max: usize) { - let new_selection = self.id - 1; + fn decrement(&mut self, max: usize) { + let cur_id = &mut self.id[self.mode.as_id()]; + let new_selection = *cur_id - 1; - self.id = { + *cur_id = { if new_selection >= max { max - 1 } @@ -83,11 +101,27 @@ impl ListSelection { } } } + + fn switch_section_to(&mut self, section_mode: SectionMode) { + self.mode = section_mode; + } + + fn get_section_mode_id(&self) -> usize { + self.mode.as_id() + } + + fn get_selection_for(&self, section_mode: SectionMode) -> usize { + self.id[section_mode.as_id()] + } + + fn get_current_selection(&self) -> usize { + self.get_selection_for(self.mode) + } } -impl Default for ListSelection { +impl Default for SectionSelection { fn default() -> Self { - Self{id: 0} + Self{mode: SectionMode::UpperSection, id: [0, 0]} } } @@ -97,19 +131,17 @@ pub struct ConsoleUI { terminal: Terminal, console_size: Rect, menu_selection: MenuSelection, - section_selection: ListSelection, - first_section_id: usize, - second_section_id: usize, + section_selection: SectionSelection, } impl ConsoleUI { pub fn new(rx: EventReceiver, terminal: Terminal) -> ConsoleUI { - ConsoleUI{data: ConsoleUIData::default(), rx, terminal, console_size: Rect::default(), menu_selection: MenuSelection::Stats, section_selection: ListSelection::default(), first_section_id: 0, second_section_id: 0} + ConsoleUI{data: ConsoleUIData::default(), rx, terminal, console_size: Rect::default(), menu_selection: MenuSelection::Stats, section_selection: SectionSelection::default()} } pub fn update_data(&mut self, memory_map: &MemoryMap) -> Result<(), Error> { - self.data = ConsoleUIData::from(memory_map)?; - self.section_selection = ListSelection::default(); + self.data = ConsoleUIData::from(memory_map)?; + self.section_selection = SectionSelection::default(); Ok(()) } @@ -118,6 +150,28 @@ impl ConsoleUI { let input_result = { match self.rx.recv()? { Event::Input(event) => { + if matches!(self.menu_selection, MenuSelection::Stats) { + match event.code { + KeyCode::Down => { + self.section_selection.increment(self.data.section_info.len()); + return Ok(UIState::Render); + }, + KeyCode::Up => { + self.section_selection.decrement(self.data.section_info.len()); + return Ok(UIState::Render); + }, + KeyCode::Char('a') => { + self.section_selection.switch_section_to(SectionMode::UpperSection); + return Ok(UIState::Render); + }, + KeyCode::Char('s') => { + self.section_selection.switch_section_to(SectionMode::LowerSection); + return Ok(UIState::Render); + }, + _ => () + } + } + match event.code { KeyCode::Char('q') => Ok(UIState::Terminated), KeyCode::Char('s') => { @@ -132,26 +186,6 @@ impl ConsoleUI { self.menu_selection = self.menu_selection.next(); Ok(UIState::Render) }, - KeyCode::Down => { - if matches!(self.menu_selection, MenuSelection::Stats) { - self.section_selection.increment(self.data.section_info.len()); - Ok(UIState::Render) - } - - else { - Ok(UIState::Alive) - } - }, - KeyCode::Up => { - if matches!(self.menu_selection, MenuSelection::Stats) { - self.section_selection.decrement(self.data.section_info.len()); - Ok(UIState::Render) - } - - else { - Ok(UIState::Alive) - } - }, KeyCode::Enter => { if matches!(self.menu_selection, MenuSelection::Quit) { Ok(UIState::Terminated) @@ -178,7 +212,6 @@ impl ConsoleUI { } }; - self.first_section_id = self.section_selection.id; input_result } @@ -233,7 +266,8 @@ impl ConsoleUI { Ok(()) } - fn render_stats(frame: &mut ConsoleFrame, layout: Rect, content_selection: &ListSelection, data: &mut ConsoleUIData) { + fn render_stats(frame: &mut ConsoleFrame, layout: Rect, section_selection: &SectionSelection, data: &mut ConsoleUIData) { + const HIGHLIGHT_COLOR:[Color;2] = [Color::Cyan, Color::Red]; let layout = Layout::default().direction(Direction::Vertical).constraints([ Constraint::Length(3), Constraint::Max(3), @@ -252,13 +286,13 @@ impl ConsoleUI { .style(Style::default().fg(Color::White)) .border_type(BorderType::Plain) ) - .highlight_style(Style::default().bg(Color::Cyan)); + .highlight_style(Style::default().bg(HIGHLIGHT_COLOR[section_selection.get_section_mode_id()])); - let first_mem_gauge = Self::create_mem_gauge_from(&data.section_info[content_selection.id], Color::Cyan); - let second_mem_gauge = Self::create_mem_gauge_from(&data.section_info[0], Color::Red); + let first_mem_gauge = Self::create_mem_gauge_from(&data.section_info[section_selection.get_selection_for(SectionMode::UpperSection)], HIGHLIGHT_COLOR[0]); + let second_mem_gauge = Self::create_mem_gauge_from(&data.section_info[section_selection.get_selection_for(SectionMode::LowerSection)], HIGHLIGHT_COLOR[1]); let mut list_state = ListState::default(); - list_state.select(Some(content_selection.id)); + list_state.select(Some(section_selection.get_current_selection())); frame.render_stateful_widget(content_list, layout[0], &mut list_state); frame.render_widget(first_mem_gauge, layout[1]); From 644da679eef456a6ab4e1888c889c4805b497c5f Mon Sep 17 00:00:00 2001 From: jaby Date: Wed, 16 Aug 2023 15:31:16 +0200 Subject: [PATCH 095/588] Add help charcters --- src/Tools/psxreadmap/src/lib.rs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/Tools/psxreadmap/src/lib.rs b/src/Tools/psxreadmap/src/lib.rs index 5eca68e4..7ca33157 100644 --- a/src/Tools/psxreadmap/src/lib.rs +++ b/src/Tools/psxreadmap/src/lib.rs @@ -288,8 +288,8 @@ impl ConsoleUI { ) .highlight_style(Style::default().bg(HIGHLIGHT_COLOR[section_selection.get_section_mode_id()])); - let first_mem_gauge = Self::create_mem_gauge_from(&data.section_info[section_selection.get_selection_for(SectionMode::UpperSection)], HIGHLIGHT_COLOR[0]); - let second_mem_gauge = Self::create_mem_gauge_from(&data.section_info[section_selection.get_selection_for(SectionMode::LowerSection)], HIGHLIGHT_COLOR[1]); + let first_mem_gauge = Self::create_mem_gauge_from(&data.section_info[section_selection.get_selection_for(SectionMode::UpperSection)], "a", HIGHLIGHT_COLOR[0]); + let second_mem_gauge = Self::create_mem_gauge_from(&data.section_info[section_selection.get_selection_for(SectionMode::LowerSection)], "s", HIGHLIGHT_COLOR[1]); let mut list_state = ListState::default(); list_state.select(Some(section_selection.get_current_selection())); @@ -299,7 +299,7 @@ impl ConsoleUI { frame.render_widget(second_mem_gauge, layout[2]); } - fn create_mem_gauge_from<'a>(section_info: &SectionInfo, color: Color) -> Gauge<'a> { + fn create_mem_gauge_from<'a>(section_info: &SectionInfo, string: &'a str, color: Color) -> Gauge<'a> { const PERCISION:usize = 5; const FLOAT_DISPLAY_LIMIT:f64 = { let mut base = 1.0f64; @@ -315,8 +315,11 @@ impl ConsoleUI { let adr_ratio = section_info.get_size_ratio(); Gauge::default().block(Block::default().borders(Borders::ALL) - .title(format!("{} @0x{:x} - 0x{:x} [{}b/{}b]", - section_info.name, section_info.start_adr, section_info.get_end_adr(), section_info.size, section_info.max_size))) + .title(Line::from(vec![ + Span::styled(string, Style::default().fg(color)), + Span::raw(format!(": {} @0x{:x} - 0x{:x} [{}b/{}b]", + section_info.name, section_info.start_adr, section_info.get_end_adr(), section_info.size, section_info.max_size)), + ]))) .gauge_style(Style::default().fg(color).bg(Color::Black).add_modifier(Modifier::BOLD)) .ratio(adr_ratio).label({ let adr_ratio = adr_ratio*100.0f64; From 310519203ae06578b951247cae12db6cfe477d0e Mon Sep 17 00:00:00 2001 From: jaby Date: Sun, 20 Aug 2023 08:10:18 +0200 Subject: [PATCH 096/588] Introduce new 'List' entry --- src/Tools/psxreadmap/src/lib.rs | 203 ++++++++++++++++++++------------ 1 file changed, 125 insertions(+), 78 deletions(-) diff --git a/src/Tools/psxreadmap/src/lib.rs b/src/Tools/psxreadmap/src/lib.rs index 7ca33157..89f87e2a 100644 --- a/src/Tools/psxreadmap/src/lib.rs +++ b/src/Tools/psxreadmap/src/lib.rs @@ -1,7 +1,7 @@ mod readmap_helper; -use crossterm::event::KeyCode; +use crossterm::event::{KeyCode, KeyEvent}; use readmap::types::MemoryMap; -use std::path::PathBuf; +use std::{convert::From, path::PathBuf}; use tool_helper::Error; use ratatui::{ layout::{Alignment, Constraint, Direction, Layout, Rect}, @@ -26,27 +26,40 @@ pub enum UIState { Terminated } +#[derive(Copy, Clone)] enum MenuSelection { Stats, + List, Quit, } impl MenuSelection { + const ENUM_LENGTH:i32 = 3; + fn next(&self) -> MenuSelection { - match self { - Self::Stats => Self::Quit, - Self::Quit => Self::Stats - } + Self::from(*self as i32 + 1) } fn prev(&self) -> MenuSelection { - self.next() + Self::from(*self as i32 - 1) } fn get_id(&self) -> usize { - match self { - MenuSelection::Stats => 0, - MenuSelection::Quit => 1, + *self as usize + } +} + +impl From for MenuSelection { + fn from(value: i32) -> Self { + if value < 0 { + return Self::from(value + Self::ENUM_LENGTH); + } + + match value%Self::ENUM_LENGTH { + x if x == MenuSelection::Stats as i32 => MenuSelection::Stats, + x if x == MenuSelection::List as i32 => MenuSelection::List, + x if x == MenuSelection::Quit as i32 => MenuSelection::Quit, + _ => MenuSelection::Quit } } } @@ -58,7 +71,7 @@ enum SectionMode { } impl SectionMode { - pub fn as_id(&self) -> usize { + pub fn get_id(&self) -> usize { match self { SectionMode::UpperSection => 0, SectionMode::LowerSection => 1, @@ -73,7 +86,7 @@ struct SectionSelection { impl SectionSelection { fn increment(&mut self, max: usize) { - let cur_id = &mut self.id[self.mode.as_id()]; + let cur_id = &mut self.id[self.mode.get_id()]; let new_selection = *cur_id + 1; *cur_id = { @@ -88,7 +101,7 @@ impl SectionSelection { } fn decrement(&mut self, max: usize) { - let cur_id = &mut self.id[self.mode.as_id()]; + let cur_id = &mut self.id[self.mode.get_id()]; let new_selection = *cur_id - 1; *cur_id = { @@ -107,11 +120,11 @@ impl SectionSelection { } fn get_section_mode_id(&self) -> usize { - self.mode.as_id() + self.mode.get_id() } fn get_selection_for(&self, section_mode: SectionMode) -> usize { - self.id[section_mode.as_id()] + self.id[section_mode.get_id()] } fn get_current_selection(&self) -> usize { @@ -150,51 +163,39 @@ impl ConsoleUI { let input_result = { match self.rx.recv()? { Event::Input(event) => { - if matches!(self.menu_selection, MenuSelection::Stats) { - match event.code { - KeyCode::Down => { - self.section_selection.increment(self.data.section_info.len()); - return Ok(UIState::Render); - }, - KeyCode::Up => { - self.section_selection.decrement(self.data.section_info.len()); - return Ok(UIState::Render); - }, - KeyCode::Char('a') => { - self.section_selection.switch_section_to(SectionMode::UpperSection); - return Ok(UIState::Render); - }, - KeyCode::Char('s') => { - self.section_selection.switch_section_to(SectionMode::LowerSection); - return Ok(UIState::Render); - }, - _ => () + let state_update = { + match self.menu_selection { + MenuSelection::Stats => self.update_stats(event), + MenuSelection::List => self.update_list(event), + MenuSelection::Quit => self.update_quit(event), } + }; + + if let Some(result) = state_update { + Ok(result) } - match event.code { - KeyCode::Char('q') => Ok(UIState::Terminated), - KeyCode::Char('s') => { - self.menu_selection = MenuSelection::Stats; - Ok(UIState::Render) - }, - KeyCode::Left => { - self.menu_selection = self.menu_selection.prev(); - Ok(UIState::Render) - }, - KeyCode::Right => { - self.menu_selection = self.menu_selection.next(); - Ok(UIState::Render) - }, - KeyCode::Enter => { - if matches!(self.menu_selection, MenuSelection::Quit) { - Ok(UIState::Terminated) - } - else { - Ok(UIState::Alive) - } - }, - _ => Ok(UIState::Alive) + else { + match event.code { + KeyCode::Char('l') => { + self.menu_selection = MenuSelection::List; + Ok(UIState::Render) + }, + KeyCode::Char('s') => { + self.menu_selection = MenuSelection::Stats; + Ok(UIState::Render) + }, + KeyCode::Char('q') => Ok(UIState::Terminated), + KeyCode::Left => { + self.menu_selection = self.menu_selection.prev(); + Ok(UIState::Render) + }, + KeyCode::Right => { + self.menu_selection = self.menu_selection.next(); + Ok(UIState::Render) + }, + _ => Ok(UIState::Alive) + } } }, Event::Tick => { @@ -225,7 +226,7 @@ impl ConsoleUI { // Elements let menu_bar = { - const MENU_TITLES: &'static [&'static str] = &["Stats", "Quit"]; + const MENU_TITLES: &'static [&'static str] = &["Stats", "List", "Quit"]; let menu = MENU_TITLES.iter().map(|t| { let (first, rest) = t.split_at(1); @@ -250,8 +251,11 @@ impl ConsoleUI { MenuSelection::Stats => { Self::render_stats(frame, main_layout[1], &self.section_selection, &mut self.data); }, + MenuSelection::List => { + Self::render_list(frame, main_layout[1]); + }, MenuSelection::Quit => { - frame.render_widget(Self::create_exit_message(), main_layout[1]); + Self::render_quit(frame, main_layout[1]); } } })?; @@ -266,6 +270,39 @@ impl ConsoleUI { Ok(()) } + fn update_stats(&mut self, key: KeyEvent) -> Option { + match key.code { + KeyCode::Down => { + self.section_selection.increment(self.data.section_info.len()); + return Some(UIState::Render); + }, + KeyCode::Up => { + self.section_selection.decrement(self.data.section_info.len()); + return Some(UIState::Render); + }, + KeyCode::Char('a') => { + self.section_selection.switch_section_to(SectionMode::UpperSection); + return Some(UIState::Render); + }, + KeyCode::Char('s') => { + self.section_selection.switch_section_to(SectionMode::LowerSection); + return Some(UIState::Render); + }, + _ => None + } + } + + fn update_list(&mut self, _key: KeyEvent) -> Option { + None + } + + fn update_quit(&mut self, key: KeyEvent) -> Option { + match key.code { + KeyCode::Enter => Some(UIState::Terminated), + _ => None, + } + } + fn render_stats(frame: &mut ConsoleFrame, layout: Rect, section_selection: &SectionSelection, data: &mut ConsoleUIData) { const HIGHLIGHT_COLOR:[Color;2] = [Color::Cyan, Color::Red]; let layout = Layout::default().direction(Direction::Vertical).constraints([ @@ -273,14 +310,9 @@ impl ConsoleUI { Constraint::Max(3), Constraint::Max(3), ]).split(layout).to_vec(); - let content_list = List::new({ - let mut vec = Vec::new(); - - for section in &data.section_info { - vec.push(ListItem::new(section.name.clone())) - } - vec - }).style(Style::default().fg(Color::White)) + let content_list = List::new(data.section_info.iter().map(|section| { + ListItem::new(section.name.clone()) + }).collect::>()).style(Style::default().fg(Color::White)) .block(Block::default() .borders(Borders::ALL) .style(Style::default().fg(Color::White)) @@ -299,6 +331,32 @@ impl ConsoleUI { frame.render_widget(second_mem_gauge, layout[2]); } + fn render_list(frame: &mut ConsoleFrame, layout: Rect) { + let text = Paragraph::new("Comming soon") + .style(Style::default().fg(Color::White)) + .alignment(Alignment::Center) + .block(Block::default() + .borders(Borders::ALL) + .style(Style::default().fg(Color::White)) + .border_type(BorderType::Plain).title("QUIT") + ); + + frame.render_widget(text, layout); + } + + fn render_quit(frame: &mut ConsoleFrame, layout: Rect) { + let text = Paragraph::new("Press \"ENTER\" to exit") + .style(Style::default().fg(Color::White)) + .alignment(Alignment::Center) + .block(Block::default() + .borders(Borders::ALL) + .style(Style::default().fg(Color::White)) + .border_type(BorderType::Plain).title("QUIT") + ); + + frame.render_widget(text, layout); + } + fn create_mem_gauge_from<'a>(section_info: &SectionInfo, string: &'a str, color: Color) -> Gauge<'a> { const PERCISION:usize = 5; const FLOAT_DISPLAY_LIMIT:f64 = { @@ -332,17 +390,6 @@ impl ConsoleUI { } }) } - - fn create_exit_message<'a>() -> Paragraph<'a> { - Paragraph::new("Press \"ENTER\" to exit") - .style(Style::default().fg(Color::White)) - .alignment(Alignment::Center) - .block(Block::default() - .borders(Borders::ALL) - .style(Style::default().fg(Color::White)) - .border_type(BorderType::Plain).title("QUIT") - ) - } } #[derive(Default)] From 2261735ef39491cc87cb7cbefc073b19e5163c89 Mon Sep 17 00:00:00 2001 From: jaby Date: Sun, 20 Aug 2023 08:36:08 +0200 Subject: [PATCH 097/588] Create Layout for List mode --- src/Tools/psxreadmap/src/lib.rs | 32 +++++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/src/Tools/psxreadmap/src/lib.rs b/src/Tools/psxreadmap/src/lib.rs index 89f87e2a..ada4d42c 100644 --- a/src/Tools/psxreadmap/src/lib.rs +++ b/src/Tools/psxreadmap/src/lib.rs @@ -332,16 +332,30 @@ impl ConsoleUI { } fn render_list(frame: &mut ConsoleFrame, layout: Rect) { - let text = Paragraph::new("Comming soon") - .style(Style::default().fg(Color::White)) - .alignment(Alignment::Center) - .block(Block::default() - .borders(Borders::ALL) - .style(Style::default().fg(Color::White)) - .border_type(BorderType::Plain).title("QUIT") - ); + let (info_layout, list_layout) = { + let layout = Layout::default().direction(Direction::Vertical).constraints([ + Constraint::Min(5), + Constraint::Max(5), + ]).split(layout); - frame.render_widget(text, layout); + (layout[1], Layout::default().direction(Direction::Horizontal).constraints([ + Constraint::Percentage(50), + Constraint::Percentage(50) + ]).split(layout[0])) + }; + + let text = Paragraph::new("Schwimmflügel") + .style(Style::default().fg(Color::White)) + .alignment(Alignment::Center) + .block(Block::default() + .borders(Borders::ALL) + .style(Style::default().fg(Color::White)) + .border_type(BorderType::Plain).title("Wuffi") + ); + + frame.render_widget(text.clone(), info_layout); + frame.render_widget(text.clone(), list_layout[0]); + frame.render_widget(text, list_layout[1]); } fn render_quit(frame: &mut ConsoleFrame, layout: Rect) { From 882e91c92045fa00058ecf548db99622d1351b2b Mon Sep 17 00:00:00 2001 From: jaby Date: Sun, 20 Aug 2023 09:15:24 +0200 Subject: [PATCH 098/588] Display top level section information --- src/Tools/psxreadmap/src/lib.rs | 136 ++++++++++++++++++++++---------- 1 file changed, 93 insertions(+), 43 deletions(-) diff --git a/src/Tools/psxreadmap/src/lib.rs b/src/Tools/psxreadmap/src/lib.rs index ada4d42c..402ab37e 100644 --- a/src/Tools/psxreadmap/src/lib.rs +++ b/src/Tools/psxreadmap/src/lib.rs @@ -70,21 +70,42 @@ enum SectionMode { LowerSection, } -impl SectionMode { - pub fn get_id(&self) -> usize { - match self { - SectionMode::UpperSection => 0, - SectionMode::LowerSection => 1, - } +impl ID for SectionMode { + fn get_id(&self) -> usize { + *self as usize } } -struct SectionSelection { - mode: SectionMode, +impl Default for SectionMode { + fn default() -> Self { + SectionMode::UpperSection + } +} + +#[derive(Copy, Clone)] +enum ListSectionMode { + TopSection, + Section, +} + +impl ID for ListSectionMode { + fn get_id(&self) -> usize { + *self as usize + } +} + +impl Default for ListSectionMode { + fn default() -> Self { + ListSectionMode::TopSection + } +} + +struct DualSelection { + mode: T, id: [usize; 2] } -impl SectionSelection { +impl DualSelection { fn increment(&mut self, max: usize) { let cur_id = &mut self.id[self.mode.get_id()]; let new_selection = *cur_id + 1; @@ -101,7 +122,7 @@ impl SectionSelection { } fn decrement(&mut self, max: usize) { - let cur_id = &mut self.id[self.mode.get_id()]; + let cur_id = &mut self.id[self.mode.get_id()%2]; let new_selection = *cur_id - 1; *cur_id = { @@ -115,7 +136,7 @@ impl SectionSelection { } } - fn switch_section_to(&mut self, section_mode: SectionMode) { + fn switch_section_to(&mut self, section_mode: T) { self.mode = section_mode; } @@ -123,38 +144,47 @@ impl SectionSelection { self.mode.get_id() } - fn get_selection_for(&self, section_mode: SectionMode) -> usize { + fn get_selection_for(&self, section_mode: T) -> usize { self.id[section_mode.get_id()] } - fn get_current_selection(&self) -> usize { - self.get_selection_for(self.mode) + fn get_current_selection(&self) -> ListState { + let mut state = ListState::default(); + + state.select(Some(self.get_selection_for(self.mode))); + state } } -impl Default for SectionSelection { +impl Default for DualSelection { fn default() -> Self { - Self{mode: SectionMode::UpperSection, id: [0, 0]} + Self{mode: T::default(), id: [0, 0]} } } +trait ID { + fn get_id(&self) -> usize; +} + pub struct ConsoleUI { - data: ConsoleUIData, - rx: EventReceiver, - terminal: Terminal, - console_size: Rect, - menu_selection: MenuSelection, - section_selection: SectionSelection, + data: ConsoleUIData, + rx: EventReceiver, + terminal: Terminal, + console_size: Rect, + menu_selection: MenuSelection, + section_selection: DualSelection, + list_section_selection: DualSelection, } impl ConsoleUI { pub fn new(rx: EventReceiver, terminal: Terminal) -> ConsoleUI { - ConsoleUI{data: ConsoleUIData::default(), rx, terminal, console_size: Rect::default(), menu_selection: MenuSelection::Stats, section_selection: SectionSelection::default()} + ConsoleUI{data: ConsoleUIData::default(), rx, terminal, console_size: Rect::default(), menu_selection: MenuSelection::Stats, section_selection: DualSelection::default(), list_section_selection: DualSelection::default()} } pub fn update_data(&mut self, memory_map: &MemoryMap) -> Result<(), Error> { - self.data = ConsoleUIData::from(memory_map)?; - self.section_selection = SectionSelection::default(); + self.data = ConsoleUIData::from(memory_map)?; + self.section_selection = DualSelection::default(); + self.list_section_selection = DualSelection::default(); Ok(()) } @@ -249,10 +279,10 @@ impl ConsoleUI { frame.render_widget(menu_bar, main_layout[0]); match self.menu_selection { MenuSelection::Stats => { - Self::render_stats(frame, main_layout[1], &self.section_selection, &mut self.data); + Self::render_stats(frame, main_layout[1], &self.section_selection, &self.data); }, MenuSelection::List => { - Self::render_list(frame, main_layout[1]); + Self::render_list(frame, main_layout[1], &self.list_section_selection, &self.data); }, MenuSelection::Quit => { Self::render_quit(frame, main_layout[1]); @@ -292,8 +322,19 @@ impl ConsoleUI { } } - fn update_list(&mut self, _key: KeyEvent) -> Option { - None + fn update_list(&mut self, key: KeyEvent) -> Option { + let length = self.data.section_info.len() - 1; + match key.code { + KeyCode::Down => { + self.list_section_selection.increment(length); + return Some(UIState::Render); + }, + KeyCode::Up => { + self.list_section_selection.decrement(length); + return Some(UIState::Render); + }, + _ => None + } } fn update_quit(&mut self, key: KeyEvent) -> Option { @@ -303,7 +344,7 @@ impl ConsoleUI { } } - fn render_stats(frame: &mut ConsoleFrame, layout: Rect, section_selection: &SectionSelection, data: &mut ConsoleUIData) { + fn render_stats(frame: &mut ConsoleFrame, layout: Rect, section_selection: &DualSelection, data: &ConsoleUIData) { const HIGHLIGHT_COLOR:[Color;2] = [Color::Cyan, Color::Red]; let layout = Layout::default().direction(Direction::Vertical).constraints([ Constraint::Length(3), @@ -322,16 +363,13 @@ impl ConsoleUI { let first_mem_gauge = Self::create_mem_gauge_from(&data.section_info[section_selection.get_selection_for(SectionMode::UpperSection)], "a", HIGHLIGHT_COLOR[0]); let second_mem_gauge = Self::create_mem_gauge_from(&data.section_info[section_selection.get_selection_for(SectionMode::LowerSection)], "s", HIGHLIGHT_COLOR[1]); - let mut list_state = ListState::default(); - - list_state.select(Some(section_selection.get_current_selection())); - - frame.render_stateful_widget(content_list, layout[0], &mut list_state); + + frame.render_stateful_widget(content_list, layout[0], &mut section_selection.get_current_selection()); frame.render_widget(first_mem_gauge, layout[1]); frame.render_widget(second_mem_gauge, layout[2]); } - fn render_list(frame: &mut ConsoleFrame, layout: Rect) { + fn render_list(frame: &mut ConsoleFrame, layout: Rect, section_selection: &DualSelection, data: &ConsoleUIData) { let (info_layout, list_layout) = { let layout = Layout::default().direction(Direction::Vertical).constraints([ Constraint::Min(5), @@ -343,19 +381,31 @@ impl ConsoleUI { Constraint::Percentage(50) ]).split(layout[0])) }; - - let text = Paragraph::new("Schwimmflügel") + + let section_list = List::new(data.section_info.iter().skip(1).map(|section| { + ListItem::new(section.name.clone()) + }).collect::>()).style(Style::default().fg(Color::White)) + .block(Block::default() + .borders(Borders::ALL) .style(Style::default().fg(Color::White)) - .alignment(Alignment::Center) + .border_type(BorderType::Plain) + .title("Section") + ) + .highlight_style(Style::default().bg(Color::White)); + + let top_section = &data.section_info[section_selection.get_selection_for(ListSectionMode::TopSection) + 1]; + let info_text = Paragraph::new(format!("Name: {}", top_section.name)) + .style(Style::default().fg(Color::White)) + .alignment(Alignment::Left) .block(Block::default() .borders(Borders::ALL) .style(Style::default().fg(Color::White)) - .border_type(BorderType::Plain).title("Wuffi") + .border_type(BorderType::Plain).title("Information") ); - frame.render_widget(text.clone(), info_layout); - frame.render_widget(text.clone(), list_layout[0]); - frame.render_widget(text, list_layout[1]); + frame.render_widget(info_text, info_layout); + frame.render_stateful_widget(section_list, list_layout[0], &mut section_selection.get_current_selection()); + //frame.render_widget(text, list_layout[1]); } fn render_quit(frame: &mut ConsoleFrame, layout: Rect) { From ae1221de81328f6f26cd3f502221315b8b40698a Mon Sep 17 00:00:00 2001 From: jaby Date: Sun, 20 Aug 2023 14:27:15 +0200 Subject: [PATCH 099/588] Support section infos in list mode --- src/Tools/psxreadmap/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Tools/psxreadmap/src/lib.rs b/src/Tools/psxreadmap/src/lib.rs index 402ab37e..311fcc26 100644 --- a/src/Tools/psxreadmap/src/lib.rs +++ b/src/Tools/psxreadmap/src/lib.rs @@ -394,7 +394,7 @@ impl ConsoleUI { .highlight_style(Style::default().bg(Color::White)); let top_section = &data.section_info[section_selection.get_selection_for(ListSectionMode::TopSection) + 1]; - let info_text = Paragraph::new(format!("Name: {}", top_section.name)) + let info_text = Paragraph::new(format!("Name: {}\nAdr: 0x{:X} - 0x{:X}\nSize: {} Bytes", top_section.name, top_section.start_adr, top_section.get_end_adr(), top_section.size)) .style(Style::default().fg(Color::White)) .alignment(Alignment::Left) .block(Block::default() From f24d993e82ec4f86d3ac2539e24ad3b3df58ea2a Mon Sep 17 00:00:00 2001 From: jaby Date: Sun, 20 Aug 2023 15:29:21 +0200 Subject: [PATCH 100/588] Preear Symbol list --- src/Tools/psxreadmap/src/lib.rs | 112 ++++++++++++++++++++----------- src/Tools/psxreadmap/src/main.rs | 2 +- 2 files changed, 74 insertions(+), 40 deletions(-) diff --git a/src/Tools/psxreadmap/src/lib.rs b/src/Tools/psxreadmap/src/lib.rs index 311fcc26..03afd65e 100644 --- a/src/Tools/psxreadmap/src/lib.rs +++ b/src/Tools/psxreadmap/src/lib.rs @@ -1,13 +1,13 @@ mod readmap_helper; use crossterm::event::{KeyCode, KeyEvent}; -use readmap::types::MemoryMap; +use readmap::types::{MemoryMap, Symbol}; use std::{convert::From, path::PathBuf}; use tool_helper::Error; use ratatui::{ layout::{Alignment, Constraint, Direction, Layout, Rect}, style::{Color, Modifier, Style}, text::{Line, Span}, - widgets::{Block, Borders, BorderType, Gauge, List, ListItem, ListState, Paragraph, Tabs} + widgets::{Block, Borders, BorderType, Gauge, List, ListItem, ListState, Paragraph, Tabs, block::Title} }; pub type EventReceiver = std::sync::mpsc::Receiver>; @@ -136,7 +136,7 @@ impl DualSelection { } } - fn switch_section_to(&mut self, section_mode: T) { + fn switch_mode_to(&mut self, section_mode: T) { self.mode = section_mode; } @@ -148,12 +148,16 @@ impl DualSelection { self.id[section_mode.get_id()] } - fn get_current_selection(&self) -> ListState { + fn get_selection_state_for(&self, section_mode: T) -> ListState { let mut state = ListState::default(); - state.select(Some(self.get_selection_for(self.mode))); + state.select(Some(self.get_selection_for(section_mode))); state } + + fn get_current_selection_state(&self) -> ListState { + self.get_selection_state_for(self.mode) + } } impl Default for DualSelection { @@ -181,7 +185,7 @@ impl ConsoleUI { ConsoleUI{data: ConsoleUIData::default(), rx, terminal, console_size: Rect::default(), menu_selection: MenuSelection::Stats, section_selection: DualSelection::default(), list_section_selection: DualSelection::default()} } - pub fn update_data(&mut self, memory_map: &MemoryMap) -> Result<(), Error> { + pub fn update_data(&mut self, memory_map: MemoryMap) -> Result<(), Error> { self.data = ConsoleUIData::from(memory_map)?; self.section_selection = DualSelection::default(); self.list_section_selection = DualSelection::default(); @@ -311,11 +315,11 @@ impl ConsoleUI { return Some(UIState::Render); }, KeyCode::Char('a') => { - self.section_selection.switch_section_to(SectionMode::UpperSection); + self.section_selection.switch_mode_to(SectionMode::UpperSection); return Some(UIState::Render); }, KeyCode::Char('s') => { - self.section_selection.switch_section_to(SectionMode::LowerSection); + self.section_selection.switch_mode_to(SectionMode::LowerSection); return Some(UIState::Render); }, _ => None @@ -333,6 +337,14 @@ impl ConsoleUI { self.list_section_selection.decrement(length); return Some(UIState::Render); }, + KeyCode::Enter => { + self.list_section_selection.switch_mode_to(ListSectionMode::Section); + return Some(UIState::Render); + } + KeyCode::Esc => { + self.list_section_selection.switch_mode_to(ListSectionMode::TopSection); + return Some(UIState::Render); + } _ => None } } @@ -354,17 +366,13 @@ impl ConsoleUI { let content_list = List::new(data.section_info.iter().map(|section| { ListItem::new(section.name.clone()) }).collect::>()).style(Style::default().fg(Color::White)) - .block(Block::default() - .borders(Borders::ALL) - .style(Style::default().fg(Color::White)) - .border_type(BorderType::Plain) - ) + .block(Self::create_default_border("")) .highlight_style(Style::default().bg(HIGHLIGHT_COLOR[section_selection.get_section_mode_id()])); let first_mem_gauge = Self::create_mem_gauge_from(&data.section_info[section_selection.get_selection_for(SectionMode::UpperSection)], "a", HIGHLIGHT_COLOR[0]); let second_mem_gauge = Self::create_mem_gauge_from(&data.section_info[section_selection.get_selection_for(SectionMode::LowerSection)], "s", HIGHLIGHT_COLOR[1]); - frame.render_stateful_widget(content_list, layout[0], &mut section_selection.get_current_selection()); + frame.render_stateful_widget(content_list, layout[0], &mut section_selection.get_current_selection_state()); frame.render_widget(first_mem_gauge, layout[1]); frame.render_widget(second_mem_gauge, layout[2]); } @@ -382,45 +390,68 @@ impl ConsoleUI { ]).split(layout[0])) }; - let section_list = List::new(data.section_info.iter().skip(1).map(|section| { + let section_list = List::new(data.section_info.iter().skip(1).map( + |section| { ListItem::new(section.name.clone()) }).collect::>()).style(Style::default().fg(Color::White)) - .block(Block::default() - .borders(Borders::ALL) - .style(Style::default().fg(Color::White)) - .border_type(BorderType::Plain) - .title("Section") - ) + .block(Self::create_default_border("Section")) .highlight_style(Style::default().bg(Color::White)); - let top_section = &data.section_info[section_selection.get_selection_for(ListSectionMode::TopSection) + 1]; - let info_text = Paragraph::new(format!("Name: {}\nAdr: 0x{:X} - 0x{:X}\nSize: {} Bytes", top_section.name, top_section.start_adr, top_section.get_end_adr(), top_section.size)) + let current_selection = section_selection.get_selection_for(ListSectionMode::TopSection); + let top_section = &data.section_info[current_selection + 1]; + let info_text = Paragraph::new(format!("Name: {}\nAdr: 0x{:X} - 0x{:X}\nSize: {} Bytes", top_section.name, top_section.start_adr, top_section.get_end_adr(), top_section.size)) .style(Style::default().fg(Color::White)) .alignment(Alignment::Left) - .block(Block::default() - .borders(Borders::ALL) - .style(Style::default().fg(Color::White)) - .border_type(BorderType::Plain).title("Information") - ); + .block(Self::create_default_border("Information")); frame.render_widget(info_text, info_layout); - frame.render_stateful_widget(section_list, list_layout[0], &mut section_selection.get_current_selection()); - //frame.render_widget(text, list_layout[1]); + frame.render_stateful_widget(section_list, list_layout[0], &mut section_selection.get_selection_state_for(ListSectionMode::TopSection)); + + if matches!(section_selection.mode, ListSectionMode::TopSection) { + let text = Paragraph::new("Press \"ENTER\" to display") + .style(Style::default().fg(Color::White)) + .alignment(Alignment::Center) + .block(Self::create_default_border("Symbols")); + + frame.render_widget(text, list_layout[1]); + } + + else { + let text = Paragraph::new("Press \"ESC\" to leave") + .style(Style::default().fg(Color::White)) + .alignment(Alignment::Center) + .block(Self::create_default_border(format!("Symbols in {}", top_section.name))); + + frame.render_widget(text, list_layout[1]); + + + /*let symbol_list = List::new(data.section_info.iter().skip(1).map( + |section| { + ListItem::new(section.name.clone()) + }).collect::>()).style(Style::default().fg(Color::White)) + .block(Self::create_default_border("Section")) + .highlight_style(Style::default().bg(Color::White));*/ + + } } fn render_quit(frame: &mut ConsoleFrame, layout: Rect) { let text = Paragraph::new("Press \"ENTER\" to exit") .style(Style::default().fg(Color::White)) .alignment(Alignment::Center) - .block(Block::default() - .borders(Borders::ALL) - .style(Style::default().fg(Color::White)) - .border_type(BorderType::Plain).title("QUIT") - ); + .block(Self::create_default_border("QUIT")); frame.render_widget(text, layout); } + fn create_default_border<'a, T: Into>>(title: T) -> Block<'a> { + Block::default() + .borders(Borders::ALL) + .style(Style::default().fg(Color::White)) + .border_type(BorderType::Plain) + .title(title) + } + fn create_mem_gauge_from<'a>(section_info: &SectionInfo, string: &'a str, color: Color) -> Gauge<'a> { const PERCISION:usize = 5; const FLOAT_DISPLAY_LIMIT:f64 = { @@ -465,7 +496,7 @@ impl ConsoleUIData { pub const RAM_BASE_ADDRESS:u64 = 0x80000000; pub const RAM_SIZE:usize = 2*1024*1024; - pub fn from(memory_map: &MemoryMap) -> Result { + pub fn from(memory_map: MemoryMap) -> Result { fn get_last_section_end_adr(memory_map: &MemoryMap) -> u64 { if let Some(section) = memory_map.sections.last() { return section.adr + section.size as u64; @@ -474,19 +505,21 @@ impl ConsoleUIData { } let mut new_self = ConsoleUIData::default(); - let highest_adr = get_last_section_end_adr(memory_map); + let highest_adr = get_last_section_end_adr(&memory_map); let program_size = (highest_adr - Self::RAM_BASE_ADDRESS) as usize; new_self.section_info.push(SectionInfo{ name: String::from(""), + symbols: memory_map.global, start_adr: Self::RAM_BASE_ADDRESS, size: program_size, max_size: Self::RAM_SIZE }); - for section in &memory_map.sections { + for section in memory_map.sections { new_self.section_info.push(SectionInfo{ - name: section.name.clone(), + name: section.name, + symbols: section.symbols, start_adr: section.adr, size: section.size, max_size: program_size @@ -500,6 +533,7 @@ impl ConsoleUIData { #[derive(Default)] struct SectionInfo { pub name: String, + pub symbols: Vec, pub start_adr: u64, pub size: usize, pub max_size: usize, diff --git a/src/Tools/psxreadmap/src/main.rs b/src/Tools/psxreadmap/src/main.rs index d75e7d3e..69bb489f 100644 --- a/src/Tools/psxreadmap/src/main.rs +++ b/src/Tools/psxreadmap/src/main.rs @@ -36,7 +36,7 @@ fn run_main(cmd: CommandLine) -> Result<(), Error> { let terminal = setup_console()?; let mut console_ui = ConsoleUI::new(rx, terminal); - console_ui.update_data(&memory_map)?; + console_ui.update_data(memory_map)?; loop { match console_ui.update()? { UIState::Alive => (), From 38cf7c1305e09fe420aae34e3ad8925029d52587 Mon Sep 17 00:00:00 2001 From: jaby Date: Sun, 20 Aug 2023 16:21:42 +0200 Subject: [PATCH 101/588] Support different sized lists --- src/Tools/psxreadmap/src/lib.rs | 170 +++++++++++++++++--------------- 1 file changed, 91 insertions(+), 79 deletions(-) diff --git a/src/Tools/psxreadmap/src/lib.rs b/src/Tools/psxreadmap/src/lib.rs index 03afd65e..35505780 100644 --- a/src/Tools/psxreadmap/src/lib.rs +++ b/src/Tools/psxreadmap/src/lib.rs @@ -102,50 +102,49 @@ impl Default for ListSectionMode { struct DualSelection { mode: T, - id: [usize; 2] + idx: [i64; 2] } impl DualSelection { - fn increment(&mut self, max: usize) { - let cur_id = &mut self.id[self.mode.get_id()]; - let new_selection = *cur_id + 1; - - *cur_id = { - if new_selection >= max { - 0 - } - - else { - new_selection - } - } + fn increment(&mut self) { + self.idx[self.mode.get_id()] += 1; } - fn decrement(&mut self, max: usize) { - let cur_id = &mut self.id[self.mode.get_id()%2]; - let new_selection = *cur_id - 1; + fn decrement(&mut self) { + self.idx[self.mode.get_id()] -= 1; + } - *cur_id = { - if new_selection >= max { - max - 1 - } + fn normalize_with(&mut self, max: i64) { + let mut cur_idx = self.idx[self.mode.get_id()]; - else { - new_selection - } + while cur_idx < 0 { + cur_idx += max; } + + if cur_idx >= max { + cur_idx %= max; + } + + self.idx[self.mode.get_id()] = cur_idx; } fn switch_mode_to(&mut self, section_mode: T) { self.mode = section_mode; } + fn reset_mode_to(&mut self, section_mode: T) { + let cur_id = &mut self.idx[self.mode.get_id()%2]; + + *cur_id = 0; + self.switch_mode_to(section_mode) + } + fn get_section_mode_id(&self) -> usize { self.mode.get_id() } fn get_selection_for(&self, section_mode: T) -> usize { - self.id[section_mode.get_id()] + self.idx[section_mode.get_id()] as usize } fn get_selection_state_for(&self, section_mode: T) -> ListState { @@ -162,7 +161,7 @@ impl DualSelection { impl Default for DualSelection { fn default() -> Self { - Self{mode: T::default(), id: [0, 0]} + Self{mode: T::default(), idx: [0, 0]} } } @@ -305,48 +304,64 @@ impl ConsoleUI { } fn update_stats(&mut self, key: KeyEvent) -> Option { - match key.code { - KeyCode::Down => { - self.section_selection.increment(self.data.section_info.len()); - return Some(UIState::Render); - }, - KeyCode::Up => { - self.section_selection.decrement(self.data.section_info.len()); - return Some(UIState::Render); - }, - KeyCode::Char('a') => { - self.section_selection.switch_mode_to(SectionMode::UpperSection); - return Some(UIState::Render); - }, - KeyCode::Char('s') => { - self.section_selection.switch_mode_to(SectionMode::LowerSection); - return Some(UIState::Render); - }, - _ => None - } + let result = { + match key.code { + KeyCode::Down => { + self.section_selection.increment(); + Some(UIState::Render) + }, + KeyCode::Up => { + self.section_selection.decrement(); + Some(UIState::Render) + }, + KeyCode::Char('a') => { + self.section_selection.switch_mode_to(SectionMode::UpperSection); + Some(UIState::Render) + }, + KeyCode::Char('s') => { + self.section_selection.switch_mode_to(SectionMode::LowerSection); + Some(UIState::Render) + }, + _ => None + } + }; + + self.section_selection.normalize_with(self.data.section_info.len() as i64); + result } fn update_list(&mut self, key: KeyEvent) -> Option { - let length = self.data.section_info.len() - 1; - match key.code { - KeyCode::Down => { - self.list_section_selection.increment(length); - return Some(UIState::Render); - }, - KeyCode::Up => { - self.list_section_selection.decrement(length); - return Some(UIState::Render); - }, - KeyCode::Enter => { - self.list_section_selection.switch_mode_to(ListSectionMode::Section); - return Some(UIState::Render); + let result = { + match key.code { + KeyCode::Down => { + self.list_section_selection.increment(); + Some(UIState::Render) + }, + KeyCode::Up => { + self.list_section_selection.decrement(); + Some(UIState::Render) + }, + KeyCode::Enter => { + self.list_section_selection.switch_mode_to(ListSectionMode::Section); + Some(UIState::Render) + } + KeyCode::Esc => { + self.list_section_selection.reset_mode_to(ListSectionMode::TopSection); + Some(UIState::Render) + } + _ => None } - KeyCode::Esc => { - self.list_section_selection.switch_mode_to(ListSectionMode::TopSection); - return Some(UIState::Render); - } - _ => None + }; + + if matches!(self.list_section_selection.mode, ListSectionMode::TopSection) { + self.list_section_selection.normalize_with(self.data.section_info.len() as i64); } + + else { + let length = Self::get_selected_top_section(&self.list_section_selection, &self.data).symbols.len(); + self.list_section_selection.normalize_with(length as i64); + } + result } fn update_quit(&mut self, key: KeyEvent) -> Option { @@ -390,15 +405,14 @@ impl ConsoleUI { ]).split(layout[0])) }; - let section_list = List::new(data.section_info.iter().skip(1).map( + let section_list = List::new(data.section_info.iter().map( |section| { ListItem::new(section.name.clone()) }).collect::>()).style(Style::default().fg(Color::White)) .block(Self::create_default_border("Section")) .highlight_style(Style::default().bg(Color::White)); - let current_selection = section_selection.get_selection_for(ListSectionMode::TopSection); - let top_section = &data.section_info[current_selection + 1]; + let top_section = Self::get_selected_top_section(section_selection, data); let info_text = Paragraph::new(format!("Name: {}\nAdr: 0x{:X} - 0x{:X}\nSize: {} Bytes", top_section.name, top_section.start_adr, top_section.get_end_adr(), top_section.size)) .style(Style::default().fg(Color::White)) .alignment(Alignment::Left) @@ -417,21 +431,14 @@ impl ConsoleUI { } else { - let text = Paragraph::new("Press \"ESC\" to leave") - .style(Style::default().fg(Color::White)) - .alignment(Alignment::Center) - .block(Self::create_default_border(format!("Symbols in {}", top_section.name))); - - frame.render_widget(text, list_layout[1]); - - - /*let symbol_list = List::new(data.section_info.iter().skip(1).map( - |section| { - ListItem::new(section.name.clone()) + let symbol_list = List::new(top_section.symbols.iter().map( + |symbol| { + ListItem::new(symbol.name.clone()) }).collect::>()).style(Style::default().fg(Color::White)) - .block(Self::create_default_border("Section")) - .highlight_style(Style::default().bg(Color::White));*/ + .block(Self::create_default_border(format!("Symbols in {}", top_section.name))) + .highlight_style(Style::default().bg(Color::White)); + frame.render_stateful_widget(symbol_list, list_layout[1], &mut section_selection.get_selection_state_for(ListSectionMode::Section)); } } @@ -485,6 +492,11 @@ impl ConsoleUI { } }) } + + fn get_selected_top_section<'a>(section_selection: &DualSelection, data: &'a ConsoleUIData) -> &'a SectionInfo { + let current_selection = section_selection.get_selection_for(ListSectionMode::TopSection); + &data.section_info[current_selection] + } } #[derive(Default)] From 5b82dba5ecbcf85d2d97be6ab160d92042d74aa0 Mon Sep 17 00:00:00 2001 From: jaby Date: Sun, 20 Aug 2023 16:45:22 +0200 Subject: [PATCH 102/588] Display Symbol information --- src/Tools/psxreadmap/readmap/src/types/mod.rs | 38 +++++++++ src/Tools/psxreadmap/src/lib.rs | 79 ++++++++++++------- 2 files changed, 89 insertions(+), 28 deletions(-) diff --git a/src/Tools/psxreadmap/readmap/src/types/mod.rs b/src/Tools/psxreadmap/readmap/src/types/mod.rs index 0509eda3..9010a12c 100644 --- a/src/Tools/psxreadmap/readmap/src/types/mod.rs +++ b/src/Tools/psxreadmap/readmap/src/types/mod.rs @@ -24,6 +24,20 @@ impl Section { } } +impl NamedMemoryArea for Section { + fn get_name(&self) -> &str { + self.name.as_str() + } + + fn get_adr(&self) -> u64 { + self.adr + } + + fn get_size(&self) -> usize { + self.size + } +} + #[derive(Default)] pub struct Symbol { pub name: String, @@ -35,4 +49,28 @@ impl Symbol { pub fn new(name: String, adr: u64, size: usize) -> Symbol { Symbol{name, adr, size} } +} + +impl NamedMemoryArea for Symbol { + fn get_name(&self) -> &str { + self.name.as_str() + } + + fn get_adr(&self) -> u64 { + self.adr + } + + fn get_size(&self) -> usize { + self.size + } +} + +pub trait NamedMemoryArea { + fn get_name(&self) -> &str; + fn get_adr(&self) -> u64; + fn get_size(&self) -> usize; + + fn get_end_adr(&self) -> u64 { + self.get_adr() + self.get_size() as u64 + } } \ No newline at end of file diff --git a/src/Tools/psxreadmap/src/lib.rs b/src/Tools/psxreadmap/src/lib.rs index 35505780..95577ff8 100644 --- a/src/Tools/psxreadmap/src/lib.rs +++ b/src/Tools/psxreadmap/src/lib.rs @@ -1,6 +1,6 @@ mod readmap_helper; use crossterm::event::{KeyCode, KeyEvent}; -use readmap::types::{MemoryMap, Symbol}; +use readmap::types::{MemoryMap, NamedMemoryArea, Symbol}; use std::{convert::From, path::PathBuf}; use tool_helper::Error; use ratatui::{ @@ -115,17 +115,23 @@ impl DualSelection { } fn normalize_with(&mut self, max: i64) { - let mut cur_idx = self.idx[self.mode.get_id()]; - - while cur_idx < 0 { - cur_idx += max; - } - - if cur_idx >= max { - cur_idx %= max; + if max == 0 { + self.idx[self.mode.get_id()] = 0; } - self.idx[self.mode.get_id()] = cur_idx; + else { + let mut cur_idx = self.idx[self.mode.get_id()]; + + while cur_idx < 0 { + cur_idx += max; + } + + if cur_idx >= max { + cur_idx %= max; + } + + self.idx[self.mode.get_id()] = cur_idx; + } } fn switch_mode_to(&mut self, section_mode: T) { @@ -353,14 +359,14 @@ impl ConsoleUI { } }; - if matches!(self.list_section_selection.mode, ListSectionMode::TopSection) { - self.list_section_selection.normalize_with(self.data.section_info.len() as i64); - } - - else { - let length = Self::get_selected_top_section(&self.list_section_selection, &self.data).symbols.len(); - self.list_section_selection.normalize_with(length as i64); - } + let length = { + match self.list_section_selection.mode { + ListSectionMode::TopSection => self.data.section_info.len() as i64, + ListSectionMode::Section => Self::get_selected_top_section(&self.list_section_selection, &self.data).symbols.len() as i64 + } + }; + + self.list_section_selection.normalize_with(length); result } @@ -412,13 +418,9 @@ impl ConsoleUI { .block(Self::create_default_border("Section")) .highlight_style(Style::default().bg(Color::White)); - let top_section = Self::get_selected_top_section(section_selection, data); - let info_text = Paragraph::new(format!("Name: {}\nAdr: 0x{:X} - 0x{:X}\nSize: {} Bytes", top_section.name, top_section.start_adr, top_section.get_end_adr(), top_section.size)) - .style(Style::default().fg(Color::White)) - .alignment(Alignment::Left) - .block(Self::create_default_border("Information")); + let top_section = Self::get_selected_top_section(section_selection, data); + let mut info_data: &dyn NamedMemoryArea = top_section; - frame.render_widget(info_text, info_layout); frame.render_stateful_widget(section_list, list_layout[0], &mut section_selection.get_selection_state_for(ListSectionMode::TopSection)); if matches!(section_selection.mode, ListSectionMode::TopSection) { @@ -438,8 +440,19 @@ impl ConsoleUI { .block(Self::create_default_border(format!("Symbols in {}", top_section.name))) .highlight_style(Style::default().bg(Color::White)); + let current_selection = section_selection.get_selection_for(ListSectionMode::Section); + if top_section.symbols.len() > 0 { + info_data = &top_section.symbols[current_selection]; + } + frame.render_stateful_widget(symbol_list, list_layout[1], &mut section_selection.get_selection_state_for(ListSectionMode::Section)); } + + let info_text = Paragraph::new(format!("Name: {}\nAdr: 0x{:X} - 0x{:X}\nSize: {} Bytes", info_data.get_name(), info_data.get_adr(), info_data.get_end_adr(), info_data.get_size())) + .style(Style::default().fg(Color::White)) + .alignment(Alignment::Left) + .block(Self::create_default_border("Information")); + frame.render_widget(info_text, info_layout); } fn render_quit(frame: &mut ConsoleFrame, layout: Rect) { @@ -552,15 +565,25 @@ struct SectionInfo { } impl SectionInfo { - fn get_end_adr(&self) -> u64 { - self.start_adr + self.size as u64 - } - fn get_size_ratio(&self) -> f64 { self.size as f64 / self.max_size as f64 } } +impl NamedMemoryArea for SectionInfo { + fn get_name(&self) -> &str { + self.name.as_str() + } + + fn get_adr(&self) -> u64 { + self.start_adr + } + + fn get_size(&self) -> usize { + self.size + } +} + pub fn load_memory_map(use_wsl: bool, input: PathBuf) -> Result { readmap_helper::generate_memory_map(use_wsl, input) } \ No newline at end of file From e07d144da329ef5ffbbb13d78ab265fdba38aaad Mon Sep 17 00:00:00 2001 From: jaby Date: Sun, 20 Aug 2023 17:32:10 +0200 Subject: [PATCH 103/588] Color encode OVERLAPPED sections and set version to 1.0 --- src/Tools/psxreadmap/Cargo.toml | 2 +- src/Tools/psxreadmap/src/lib.rs | 69 ++++++++++++++++++++++++--------- 2 files changed, 52 insertions(+), 19 deletions(-) diff --git a/src/Tools/psxreadmap/Cargo.toml b/src/Tools/psxreadmap/Cargo.toml index e57d7caa..f3b95e30 100644 --- a/src/Tools/psxreadmap/Cargo.toml +++ b/src/Tools/psxreadmap/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "psxreadmap" -version = "0.1.0" +version = "1.0.0" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/src/Tools/psxreadmap/src/lib.rs b/src/Tools/psxreadmap/src/lib.rs index 95577ff8..f0e70241 100644 --- a/src/Tools/psxreadmap/src/lib.rs +++ b/src/Tools/psxreadmap/src/lib.rs @@ -413,10 +413,15 @@ impl ConsoleUI { let section_list = List::new(data.section_info.iter().map( |section| { - ListItem::new(section.name.clone()) + let mut new_item = ListItem::new(section.name.clone()); + + if let Some(color) = section.color_share { + new_item = new_item.style(Style::default().fg(color)); + } + new_item }).collect::>()).style(Style::default().fg(Color::White)) .block(Self::create_default_border("Section")) - .highlight_style(Style::default().bg(Color::White)); + .highlight_style(Style::default().add_modifier(Modifier::REVERSED|Modifier::BOLD)); let top_section = Self::get_selected_top_section(section_selection, data); let mut info_data: &dyn NamedMemoryArea = top_section; @@ -522,6 +527,7 @@ impl ConsoleUIData { pub const RAM_SIZE:usize = 2*1024*1024; pub fn from(memory_map: MemoryMap) -> Result { + const COLORS:[Color;4] = [Color::Red, Color::Green, Color::Blue, Color::Yellow]; fn get_last_section_end_adr(memory_map: &MemoryMap) -> u64 { if let Some(section) = memory_map.sections.last() { return section.adr + section.size as u64; @@ -530,38 +536,65 @@ impl ConsoleUIData { } let mut new_self = ConsoleUIData::default(); + let mut color_idx = 0; let highest_adr = get_last_section_end_adr(&memory_map); let program_size = (highest_adr - Self::RAM_BASE_ADDRESS) as usize; new_self.section_info.push(SectionInfo{ - name: String::from(""), - symbols: memory_map.global, - start_adr: Self::RAM_BASE_ADDRESS, - size: program_size, - max_size: Self::RAM_SIZE + name: String::from(""), + symbols: memory_map.global, + start_adr: Self::RAM_BASE_ADDRESS, + size: program_size, + max_size: Self::RAM_SIZE, + color_share: None, }); for section in memory_map.sections { new_self.section_info.push(SectionInfo{ - name: section.name, - symbols: section.symbols, - start_adr: section.adr, - size: section.size, - max_size: program_size + name: section.name, + symbols: section.symbols, + start_adr: section.adr, + size: section.size, + max_size: program_size, + color_share: None, }); } + let mut iter = new_self.section_info.iter_mut().peekable(); + while let Some(section) = iter.next() { + if let Some(next_section) = iter.peek_mut() { + if section.start_adr == next_section.start_adr { + let color = { + if let Some(color) = section.color_share { + color + } + + else { + // next color + let color = COLORS[color_idx]; + + color_idx = (color_idx + 1)%COLORS.len(); + color + } + }; + + section.color_share = Some(color); + next_section.color_share = Some(color); + } + } + } + Ok(new_self) } } -#[derive(Default)] struct SectionInfo { - pub name: String, - pub symbols: Vec, - pub start_adr: u64, - pub size: usize, - pub max_size: usize, + pub name: String, + pub symbols: Vec, + pub start_adr: u64, + pub size: usize, + pub max_size: usize, + pub color_share: Option } impl SectionInfo { From 41c6b693d3b08b756e39bfc10087402be4da4246 Mon Sep 17 00:00:00 2001 From: jaby Date: Thu, 24 Aug 2023 00:06:03 +0200 Subject: [PATCH 104/588] Advance version number and introduce conditional compiled code --- src/Tools/psxreadmap/readmap/Cargo.toml | 2 +- src/Tools/psxreadmap/readmap/src/main.rs | 10 ++++---- src/Tools/psxreadmap/src/main.rs | 30 ++++++++++++++---------- 3 files changed, 24 insertions(+), 18 deletions(-) diff --git a/src/Tools/psxreadmap/readmap/Cargo.toml b/src/Tools/psxreadmap/readmap/Cargo.toml index 9fe0b23e..fc882b61 100644 --- a/src/Tools/psxreadmap/readmap/Cargo.toml +++ b/src/Tools/psxreadmap/readmap/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "readmap" -version = "0.1.0" +version = "1.0.0" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/src/Tools/psxreadmap/readmap/src/main.rs b/src/Tools/psxreadmap/readmap/src/main.rs index 8f121ac1..a8d7e855 100644 --- a/src/Tools/psxreadmap/readmap/src/main.rs +++ b/src/Tools/psxreadmap/readmap/src/main.rs @@ -3,14 +3,16 @@ use tool_helper::{Error, exit_with_error}; use readmap::types::MemoryMap; use std::{io::{BufRead, BufReader}, path::PathBuf, process::{Child, Command, Stdio}}; +pub const RUN_DUMP_TOOL_IN_WSL:bool = cfg!(windows); + #[derive(Parser)] -#[clap(about = "Opens and scans a MAP file to print extended information", long_about = None)] +#[clap(about = "Opens and scans an ELF file to print extended information", long_about = None)] struct CommandLine { - #[clap(value_parser, help="Input MAP file for scannning")] + #[clap(value_parser, help="Input ELF file for scannning")] input: PathBuf, - #[clap(long="wsl", default_value_t=false)] + #[clap(long="wsl", help="Run \"objdump\" in WSL", default_value_t=RUN_DUMP_TOOL_IN_WSL)] use_wsl: bool, - #[clap(short='o')] + #[clap(short='o', help="Output a memory map file with running the tool")] output: Option } diff --git a/src/Tools/psxreadmap/src/main.rs b/src/Tools/psxreadmap/src/main.rs index 69bb489f..83fa81df 100644 --- a/src/Tools/psxreadmap/src/main.rs +++ b/src/Tools/psxreadmap/src/main.rs @@ -1,18 +1,20 @@ use clap::Parser; use crossterm::{event::{self, Event as CEvent, KeyboardEnhancementFlags, KeyEventKind, PushKeyboardEnhancementFlags}, execute, terminal}; use psxreadmap::{ConsoleUI, Event, EventReceiver, Terminal, load_memory_map, UIState}; -use std::{io, path::PathBuf, sync::mpsc, thread, time::{Duration, Instant}}; +use std::{io::{self, Stdout}, path::PathBuf, sync::mpsc, thread, time::{Duration, Instant}}; use tool_helper::{Error, exit_with_error}; use ratatui::backend::CrosstermBackend; +pub const RUN_DUMP_TOOL_IN_WSL:bool = cfg!(windows); + #[derive(Parser)] -#[clap(about = "Opens and scans a MAP file to print extended information", long_about = None)] +#[clap(about = "Opens and scans an ELF file to print extended memory information", long_about = None)] struct CommandLine { - #[clap(value_parser, help="Input MAP file for scannning")] + #[clap(value_parser, help="Input ELF file for scannning")] input: PathBuf, - #[clap(long="wsl", default_value_t=false)] + #[clap(long="wsl", help="Run \"objdump\" in WSL", default_value_t=RUN_DUMP_TOOL_IN_WSL)] use_wsl: bool, - #[clap(short='o')] + #[clap(short='o', help="Output a memory map file with running the tool")] output: Option } @@ -25,7 +27,7 @@ pub fn main() { } }, Err(error) => { - println!("{}", error) + println!("{})", error) } } } @@ -88,16 +90,18 @@ fn start_event_loop() -> EventReceiver { } fn setup_console() -> Result { + fn open_stdout() -> Result { + let mut stdout = io::stdout(); + if cfg!(unix) { + execute!(stdout, PushKeyboardEnhancementFlags(KeyboardEnhancementFlags::REPORT_EVENT_TYPES))?; + } + Ok(stdout) + } + terminal::enable_raw_mode()?; // Setup Crossterm for the Terminal - let stdout = { - let mut stdout = io::stdout(); - if let Err(_) = execute!(stdout, PushKeyboardEnhancementFlags(KeyboardEnhancementFlags::REPORT_EVENT_TYPES)) { - // This fails under Windows but is required for Linux - } - stdout - }; + let stdout = open_stdout()?; let backend = CrosstermBackend::new(stdout); let mut terminal = Terminal::new(backend)?; From a20483f51d2ccd605d0d617d71696def4d42ff29 Mon Sep 17 00:00:00 2001 From: jaby Date: Thu, 24 Aug 2023 00:24:20 +0200 Subject: [PATCH 105/588] Improve identification of Overlays --- src/Tools/psxreadmap/src/lib.rs | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/src/Tools/psxreadmap/src/lib.rs b/src/Tools/psxreadmap/src/lib.rs index f0e70241..a52e66b5 100644 --- a/src/Tools/psxreadmap/src/lib.rs +++ b/src/Tools/psxreadmap/src/lib.rs @@ -413,12 +413,24 @@ impl ConsoleUI { let section_list = List::new(data.section_info.iter().map( |section| { - let mut new_item = ListItem::new(section.name.clone()); - - if let Some(color) = section.color_share { - new_item = new_item.style(Style::default().fg(color)); - } - new_item + ListItem::new(Line::from(vec![{ + if let Some(color) = section.color_share { + Span::styled("*", Style::default().fg(color)) + } + else { + Span::raw("") + } + }, + Span::raw( + if section.is_global { + String::from("") + } + + else { + section.name.clone() + } + ) + ])) }).collect::>()).style(Style::default().fg(Color::White)) .block(Self::create_default_border("Section")) .highlight_style(Style::default().add_modifier(Modifier::REVERSED|Modifier::BOLD)); @@ -547,6 +559,7 @@ impl ConsoleUIData { size: program_size, max_size: Self::RAM_SIZE, color_share: None, + is_global: true }); for section in memory_map.sections { @@ -557,6 +570,7 @@ impl ConsoleUIData { size: section.size, max_size: program_size, color_share: None, + is_global: false }); } @@ -594,7 +608,8 @@ struct SectionInfo { pub start_adr: u64, pub size: usize, pub max_size: usize, - pub color_share: Option + pub color_share: Option, + pub is_global: bool, } impl SectionInfo { From 5c944dcb0a88d44250aa890968c3e84fca96ae21 Mon Sep 17 00:00:00 2001 From: jaby Date: Thu, 24 Aug 2023 00:31:36 +0200 Subject: [PATCH 106/588] Add psxreadmap to list for PSX tools --- src/Tools/.config_build_all/recommended.bat | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Tools/.config_build_all/recommended.bat b/src/Tools/.config_build_all/recommended.bat index 4779c8f0..34ed0956 100644 --- a/src/Tools/.config_build_all/recommended.bat +++ b/src/Tools/.config_build_all/recommended.bat @@ -1,4 +1,4 @@ -set bin_projects=psxcdgen psxcdread psxcdgen_ex wslpath +set bin_projects=psxcdgen psxcdgen_ex psxcdread psxreadmap wslpath set bin_linux_projects=cpp_out jaby_engine_fconv mkoverlay set clean_projects=cdtypes set clean_projects_linux=tool_helper \ No newline at end of file From d919f4fbd5b06299ee5b630043916d03d3703b4e Mon Sep 17 00:00:00 2001 From: jaby Date: Fri, 25 Aug 2023 05:15:23 +0200 Subject: [PATCH 107/588] Use psxcdgen_ex under WSL and improve wslpath and makefiles --- examples/PoolBox/Makefile | 22 ++++++++++++-- examples/PoolBox/PoolBox.code-workspace | 28 +++++------------- examples/PoolBox/application/Makefile | 8 +---- examples/PoolBox/iso/Config.xml | 10 +++---- lib/ISOTarget.mk | 14 +++++++++ lib/PSEXETarget.mk | 9 ++++-- src/Tools/.config_build_all/recommended.bat | 2 +- src/Tools/psxcdgen_ex/src/main.rs | 6 ++-- src/Tools/wslpath/src/lib.rs | 6 ++++ .../#{ProjectName}.code-workspace | 29 +++++-------------- template/JabyEngine-PSX_Game/Makefile | 23 +++++++++++++++ .../JabyEngine-PSX_Game/application/Makefile | 8 +---- template/JabyEngine-PSX_Game/assets/Makefile | 14 +++++++++ template/JabyEngine-PSX_Game/iso/Config.xml | 4 +-- 14 files changed, 113 insertions(+), 70 deletions(-) create mode 100644 lib/ISOTarget.mk create mode 100644 template/JabyEngine-PSX_Game/Makefile create mode 100644 template/JabyEngine-PSX_Game/assets/Makefile diff --git a/examples/PoolBox/Makefile b/examples/PoolBox/Makefile index 95a833c7..f379550a 100644 --- a/examples/PoolBox/Makefile +++ b/examples/PoolBox/Makefile @@ -1,5 +1,23 @@ +ARTIFACT = PoolBox +make_assets = $(MAKE) $(1) ARTIFACT=$(ARTIFACT) -C assets +make_application = $(MAKE) $(1) ARTIFACT=$(ARTIFACT) -C application +make_cd = $(MAKE) $(1) ARTIFACT=$(ARTIFACT) -f $(JABY_ENGINE_DIR)/lib/ISOTarget.mk -C iso + all clean rebuild: always - $(MAKE) $(MAKECMDGOALS) -C assets - $(MAKE) $(MAKECMDGOALS) -C application + $(call make_assets,$(MAKECMDGOALS)) + $(call make_application,$(MAKECMDGOALS)) + $(call make_cd,$(MAKECMDGOALS)) + +all_%: always + $(call make_assets,$*) + $(call make_application,$*) + $(call make_cd,$*) + +assets_%: always + $(call make_assets,$*) +application_%: always + $(call make_application,$*) +cd_%: always + $(call make_cd,$*) always: ; \ No newline at end of file diff --git a/examples/PoolBox/PoolBox.code-workspace b/examples/PoolBox/PoolBox.code-workspace index b6a16f43..17e82659 100644 --- a/examples/PoolBox/PoolBox.code-workspace +++ b/examples/PoolBox/PoolBox.code-workspace @@ -11,7 +11,7 @@ { "label": "build", "type": "shell", - "command": "wsl make ${input:target} BUILD_PROFILE=${input:build profile} JABY_ENGINE_DIR=$(wslpath ${env:JABY_ENGINE_PATH})", + "command": "wsl make ${input:project}_${input:target} BUILD_PROFILE=${input:build profile} PSX_LICENSE_PATH=$(wslpath ${env:PSX_LICENSE_PATH}) JABY_ENGINE_DIR=$(wslpath ${env:JABY_ENGINE_PATH})", "group": { "kind": "build", "isDefault": true @@ -22,25 +22,6 @@ } } }, - { - "label": "cdgen", - "type": "shell", - "command": "${env:JABY_ENGINE_PATH}/bin/psxcdgen_ex.exe --list iso/PoolBox.lba -o iso/PoolBox psx bin-cue iso/Config.xml", - "group": { - "kind": "build", - "isDefault": true - } - }, - { - "label": "build & generate cd", - "type": "shell", - "dependsOn": ["build", "cdgen"], - "dependsOrder": "sequence", - "group": { - "kind": "build", - "isDefault": true - } - } ], "inputs": [ { @@ -50,6 +31,13 @@ "default": "release", "description": "The build profile for PoolBox" }, + { + "id": "project", + "type": "pickString", + "options": ["all", "assets", "application", "cd"], + "default": "all", + "description": "Project to build" + }, { "id": "target", "type": "pickString", diff --git a/examples/PoolBox/application/Makefile b/examples/PoolBox/application/Makefile index 71f4711e..5b712e86 100644 --- a/examples/PoolBox/application/Makefile +++ b/examples/PoolBox/application/Makefile @@ -1,4 +1,3 @@ -ARTIFACT = PoolBox BUILD_DIR = bin OVERLAY_CONFIG = Overlays.json @@ -10,9 +9,4 @@ INCLUDES += -I$(JABY_ENGINE_DIR)/include CCFLAGS += -save-temps=obj include $(JABY_ENGINE_DIR)/lib/Makefile -include $(JABY_ENGINE_DIR)/lib/PSEXETarget.mk - -clean: - rm -fr $(OUTPUT_DIR) - rm -fr ../iso/*.bin - rm -fr ../iso/*.cue \ No newline at end of file +include $(JABY_ENGINE_DIR)/lib/PSEXETarget.mk \ No newline at end of file diff --git a/examples/PoolBox/iso/Config.xml b/examples/PoolBox/iso/Config.xml index a12f195b..0211a1f3 100644 --- a/examples/PoolBox/iso/Config.xml +++ b/examples/PoolBox/iso/Config.xml @@ -4,14 +4,14 @@ %PSX_LICENSE_PATH%/LICENSEE.DAT - iso/System.cnf -
application/bin/PSX-release/PoolBox.psexe
+ System.cnf +
../application/bin/PSX-release/PoolBox.psexe
\ No newline at end of file diff --git a/lib/ISOTarget.mk b/lib/ISOTarget.mk new file mode 100644 index 00000000..f37fe9f0 --- /dev/null +++ b/lib/ISOTarget.mk @@ -0,0 +1,14 @@ +include $(JABY_ENGINE_DIR)/lib/RebuildTarget.mk +CD_OUTPUT ?= $(ARTIFACT).bin + +$(CD_OUTPUT): always + psxcdgen_ex --list $(ARTIFACT).lba -o $(ARTIFACT) psx bin-cue Config.xml + +all: $(CD_OUTPUT) + +clean: + rm -fr *.bin + rm -fr *.cue + rm -fr *.lba + +always: ; \ No newline at end of file diff --git a/lib/PSEXETarget.mk b/lib/PSEXETarget.mk index 7445dd7d..6776709d 100644 --- a/lib/PSEXETarget.mk +++ b/lib/PSEXETarget.mk @@ -7,6 +7,8 @@ include $(AUTO_OVERLAY_DIR)/Overlays.mk JABY_ENGINE_LIB_DIR = $(JABY_ENGINE_DIR)/lib/PSX-$(BUILD_PROFILE) JABY_ENGINE_LIB_NAME = JabyEngine_$(TV_FORMAT) +OVERLAY_TARGET = $(foreach ovl, $(OVERLAYSECTION), $(OUTPUT_DIR)/Overlay$(ovl)) + #Linking rule $(TARGET).elf: $(OBJS) $(JABY_ENGINE_LIB_DIR)/lib$(JABY_ENGINE_LIB_NAME).a $(AUTO_OVERLAY_DIR)/Overlays.ld $(LD) -o $(TARGET).elf $(LDFLAGS_all) $(LDFLAGS) $(OBJS) -L$(JABY_ENGINE_LIB_DIR) -l$(JABY_ENGINE_LIB_NAME) $(LIBS) @@ -16,7 +18,7 @@ $(TARGET).psexe: $(TARGET).elf $(PREFIX)-objcopy $(addprefix -R , $(OVERLAYSECTION)) -O binary $< $@ #Create overlays -$(foreach ovl, $(OVERLAYSECTION), $(OUTPUT_DIR)/Overlay$(ovl)): $(TARGET).elf +$(OVERLAY_TARGET): $(TARGET).elf $(PREFIX)-objcopy -j $(suffix $@) -O binary $< $@ #Create overlay makefile @@ -25,4 +27,7 @@ $(AUTO_OVERLAY_DIR)/Overlays.mk: $(OVERLAY_CONFIG) mkoverlay --mk-file $(AUTO_OVERLAY_DIR)/Overlays.mk --ld-script $(AUTO_OVERLAY_DIR)/Overlays.ld $< #Rules section for default compilation and linking -all: $(TARGET).psexe $(foreach ovl, $(OVERLAYSECTION), $(OUTPUT_DIR)/Overlay$(ovl)) \ No newline at end of file +all: $(TARGET).psexe $(OVERLAY_TARGET) + +clean: + rm -fr $(OUTPUT_DIR) \ No newline at end of file diff --git a/src/Tools/.config_build_all/recommended.bat b/src/Tools/.config_build_all/recommended.bat index 34ed0956..8d991c09 100644 --- a/src/Tools/.config_build_all/recommended.bat +++ b/src/Tools/.config_build_all/recommended.bat @@ -1,4 +1,4 @@ set bin_projects=psxcdgen psxcdgen_ex psxcdread psxreadmap wslpath -set bin_linux_projects=cpp_out jaby_engine_fconv mkoverlay +set bin_linux_projects=cpp_out psxcdgen_ex jaby_engine_fconv mkoverlay wslpath set clean_projects=cdtypes set clean_projects_linux=tool_helper \ No newline at end of file diff --git a/src/Tools/psxcdgen_ex/src/main.rs b/src/Tools/psxcdgen_ex/src/main.rs index 186e7790..2ac38219 100644 --- a/src/Tools/psxcdgen_ex/src/main.rs +++ b/src/Tools/psxcdgen_ex/src/main.rs @@ -1,7 +1,7 @@ use clap::{Parser, ValueEnum}; use psxcdgen_ex::{encoder::{EncodingFunctions, psx::{calculate_psx_lbas, calculate_psx_length_for, encode_psx_image}}, file_writer::{ImageType, write_image}, config_reader}; -use std::{path::PathBuf}; -use tool_helper::{Error, exit_with_error}; +use std::path::PathBuf; +use tool_helper::{Error, exit_with_error, read_file_to_string}; #[derive(Parser)] #[clap(about = "Creates an ISO image from a description file", long_about = None)] @@ -37,7 +37,7 @@ impl SystemType { fn run_main(cmd_line: CommandLine) -> Result<(), Error> { let encoding_functions = cmd_line.system_type.get_encoding_functions(); - let (desc, lba_embedded_files) = psxcdgen_ex::process(config_reader::parse_xml(std::fs::read_to_string(cmd_line.input_file)?)?, encoding_functions.lba_calculator)?; + let (desc, lba_embedded_files) = psxcdgen_ex::process(config_reader::parse_xml(read_file_to_string(&cmd_line.input_file)?)?, encoding_functions.lba_calculator)?; let file_map = desc.create_file_map(); psxcdgen_ex::process_files(file_map, lba_embedded_files, encoding_functions.length_calculator)?; diff --git a/src/Tools/wslpath/src/lib.rs b/src/Tools/wslpath/src/lib.rs index 28b2a23e..66402776 100644 --- a/src/Tools/wslpath/src/lib.rs +++ b/src/Tools/wslpath/src/lib.rs @@ -6,6 +6,7 @@ fn convert_slashes(path: String) -> String { path.replace('\\', "/") } +#[cfg(target_os = "windows")] fn replace_drive_letter(mut path: String) -> String { let has_drive_letter = { let drive_letter = path.get(0..2); @@ -35,5 +36,10 @@ fn replace_drive_letter(mut path: String) -> String { path.insert_str(0, "/mnt/"); } + path +} + +#[cfg(not(target_os = "windows"))] +fn replace_drive_letter(path: String) -> String { path } \ No newline at end of file diff --git a/template/JabyEngine-PSX_Game/#{ProjectName}.code-workspace b/template/JabyEngine-PSX_Game/#{ProjectName}.code-workspace index 1e6f6d38..843a8d0a 100644 --- a/template/JabyEngine-PSX_Game/#{ProjectName}.code-workspace +++ b/template/JabyEngine-PSX_Game/#{ProjectName}.code-workspace @@ -11,37 +11,17 @@ { "label": "build", "type": "shell", - "command": "wsl make ${input:target} BUILD_PROFILE=${input:build profile} JABY_ENGINE_DIR=$(wslpath ${env:JABY_ENGINE_PATH})", + "command": "wsl make ${input:project}_${input:target} BUILD_PROFILE=${input:build profile} PSX_LICENSE_PATH=$(wslpath ${env:PSX_LICENSE_PATH}) JABY_ENGINE_DIR=$(wslpath ${env:JABY_ENGINE_PATH})", "group": { "kind": "build", "isDefault": true }, "options": { - "cwd": "application", "env": { "PATH": "${env:JABY_ENGINE_PATH}/bin;${env:PATH}" } } }, - { - "label": "cdgen", - "type": "shell", - "command": "${env:JABY_ENGINE_PATH}/bin/psxcdgen_ex.exe --list iso/#{ProjectName}.lba -o iso/#{ProjectName} psx bin-cue iso/Config.xml", - "group": { - "kind": "build", - "isDefault": true - } - }, - { - "label": "build & generate cd", - "type": "shell", - "dependsOn": ["build", "cdgen"], - "dependsOrder": "sequence", - "group": { - "kind": "build", - "isDefault": true - } - } ], "inputs": [ { @@ -51,6 +31,13 @@ "default": "release", "description": "The build profile for #{ProjectName}" }, + { + "id": "project", + "type": "pickString", + "options": ["all", "assets", "application", "cd"], + "default": "all", + "description": "Project to build" + }, { "id": "target", "type": "pickString", diff --git a/template/JabyEngine-PSX_Game/Makefile b/template/JabyEngine-PSX_Game/Makefile new file mode 100644 index 00000000..6acbd708 --- /dev/null +++ b/template/JabyEngine-PSX_Game/Makefile @@ -0,0 +1,23 @@ +ARTIFACT = #{ProjectName} +make_assets = $(MAKE) $(1) ARTIFACT=$(ARTIFACT) -C assets +make_application = $(MAKE) $(1) ARTIFACT=$(ARTIFACT) -C application +make_cd = $(MAKE) $(1) ARTIFACT=$(ARTIFACT) -f $(JABY_ENGINE_DIR)/lib/ISOTarget.mk -C iso + +all clean rebuild: always + $(call make_assets,$(MAKECMDGOALS)) + $(call make_application,$(MAKECMDGOALS)) + $(call make_cd,$(MAKECMDGOALS)) + +all_%: always + $(call make_assets,$*) + $(call make_application,$*) + $(call make_cd,$*) + +assets_%: always + $(call make_assets,$*) +application_%: always + $(call make_application,$*) +cd_%: always + $(call make_cd,$*) + +always: ; \ No newline at end of file diff --git a/template/JabyEngine-PSX_Game/application/Makefile b/template/JabyEngine-PSX_Game/application/Makefile index 16bd0518..f0ac70ea 100644 --- a/template/JabyEngine-PSX_Game/application/Makefile +++ b/template/JabyEngine-PSX_Game/application/Makefile @@ -1,4 +1,3 @@ -ARTIFACT = #{ProjectName} BUILD_DIR = bin #OVERLAY_CONFIG = Overlays.json @@ -9,9 +8,4 @@ SRCS = $(call rwildcard, src, c cpp) INCLUDES += -I$(JABY_ENGINE_DIR)/include include $(JABY_ENGINE_DIR)/lib/Makefile -include $(JABY_ENGINE_DIR)/lib/PSEXETarget.mk - -clean: - rm -fr $(OUTPUT_DIR) - rm -fr ../iso/*.bin - rm -fr ../iso/*.cue \ No newline at end of file +include $(JABY_ENGINE_DIR)/lib/PSEXETarget.mk \ No newline at end of file diff --git a/template/JabyEngine-PSX_Game/assets/Makefile b/template/JabyEngine-PSX_Game/assets/Makefile new file mode 100644 index 00000000..56da6521 --- /dev/null +++ b/template/JabyEngine-PSX_Game/assets/Makefile @@ -0,0 +1,14 @@ +include $(JABY_ENGINE_DIR)/lib/ExportPath.mk +include $(JABY_ENGINE_DIR)/lib/RebuildTarget.mk + +OUTPUT_DIR = bin + +# Create build targets like +# $(OUTPUT_DIR)/TexturePage.bin: TexturePage.png +# @mkdir -p $(OUTPUT_DIR) +# jaby_engine_fconv --lz4 $< -o $@ simple-tim clut4 + +all: #$(OUTPUT_DIR)/TexturePage.bin + +clean: + rm -fr $(OUTPUT_DIR) \ No newline at end of file diff --git a/template/JabyEngine-PSX_Game/iso/Config.xml b/template/JabyEngine-PSX_Game/iso/Config.xml index d52996a1..3210deef 100644 --- a/template/JabyEngine-PSX_Game/iso/Config.xml +++ b/template/JabyEngine-PSX_Game/iso/Config.xml @@ -4,7 +4,7 @@ - iso/System.cnf -
application/bin/PSX-release/#{ProjectName}.psexe
+ System.cnf +
../application/bin/PSX-release/#{ProjectName}.psexe
\ No newline at end of file From da80e99b913e937537911d1075f4ff3003056a41 Mon Sep 17 00:00:00 2001 From: jaby Date: Fri, 25 Aug 2023 05:44:14 +0200 Subject: [PATCH 108/588] Change panic behaviour of tools --- src/Tools/cdtypes/Cargo.toml | 3 ++- src/Tools/cpp_out/Cargo.toml | 3 ++- src/Tools/jaby_engine_fconv/Cargo.toml | 3 ++- src/Tools/mkoverlay/Cargo.toml | 3 ++- src/Tools/psxcdgen/Cargo.toml | 3 ++- src/Tools/psxcdgen_ex/Cargo.toml | 3 ++- src/Tools/psxcdread/Cargo.toml | 3 ++- src/Tools/psxreadmap/Cargo.toml | 3 ++- src/Tools/tool_helper/Cargo.toml | 3 ++- src/Tools/wslpath/Cargo.toml | 3 ++- 10 files changed, 20 insertions(+), 10 deletions(-) diff --git a/src/Tools/cdtypes/Cargo.toml b/src/Tools/cdtypes/Cargo.toml index b6ef204c..f174bd26 100644 --- a/src/Tools/cdtypes/Cargo.toml +++ b/src/Tools/cdtypes/Cargo.toml @@ -3,7 +3,8 @@ name = "cdtypes" version = "0.5.5" edition = "2021" -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +[profile.release] +panic = "abort" [dependencies] byteorder = "*" diff --git a/src/Tools/cpp_out/Cargo.toml b/src/Tools/cpp_out/Cargo.toml index 22684519..3a541ba9 100644 --- a/src/Tools/cpp_out/Cargo.toml +++ b/src/Tools/cpp_out/Cargo.toml @@ -3,7 +3,8 @@ name = "cpp_out" version = "1.0.2" edition = "2021" -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +[profile.release] +panic = "abort" [dependencies] clap = {version = "*", features = ["derive"]} diff --git a/src/Tools/jaby_engine_fconv/Cargo.toml b/src/Tools/jaby_engine_fconv/Cargo.toml index 023b2b6e..b2418f82 100644 --- a/src/Tools/jaby_engine_fconv/Cargo.toml +++ b/src/Tools/jaby_engine_fconv/Cargo.toml @@ -3,7 +3,8 @@ name = "jaby_engine_fconv" version = "0.1.4" edition = "2021" -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +[profile.release] +panic = "abort" [dependencies] clap = {version = "*", features = ["derive"]} diff --git a/src/Tools/mkoverlay/Cargo.toml b/src/Tools/mkoverlay/Cargo.toml index ce960207..b13fa1dc 100644 --- a/src/Tools/mkoverlay/Cargo.toml +++ b/src/Tools/mkoverlay/Cargo.toml @@ -3,7 +3,8 @@ name = "mkoverlay" version = "1.1.1" edition = "2021" -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +[profile.release] +panic = "abort" [dependencies] clap = {version = "*", features = ["derive"]} diff --git a/src/Tools/psxcdgen/Cargo.toml b/src/Tools/psxcdgen/Cargo.toml index 32353835..29296c70 100644 --- a/src/Tools/psxcdgen/Cargo.toml +++ b/src/Tools/psxcdgen/Cargo.toml @@ -3,7 +3,8 @@ name = "psxcdgen" version = "0.5.5" edition = "2021" -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +[profile.release] +panic = "abort" [dependencies] cdtypes = {path = "../cdtypes"} diff --git a/src/Tools/psxcdgen_ex/Cargo.toml b/src/Tools/psxcdgen_ex/Cargo.toml index be3566a6..fa28fb6b 100644 --- a/src/Tools/psxcdgen_ex/Cargo.toml +++ b/src/Tools/psxcdgen_ex/Cargo.toml @@ -3,7 +3,8 @@ name = "psxcdgen_ex" version = "0.2.1" edition = "2021" -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +[profile.release] +panic = "abort" [dependencies] cdtypes = {path = "../cdtypes"} diff --git a/src/Tools/psxcdread/Cargo.toml b/src/Tools/psxcdread/Cargo.toml index 137cf17c..ef0022a3 100644 --- a/src/Tools/psxcdread/Cargo.toml +++ b/src/Tools/psxcdread/Cargo.toml @@ -3,7 +3,8 @@ name = "psxcdread" version = "0.5.0" edition = "2021" -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +[profile.release] +panic = "abort" [dependencies] cdtypes = {path = "../cdtypes"} \ No newline at end of file diff --git a/src/Tools/psxreadmap/Cargo.toml b/src/Tools/psxreadmap/Cargo.toml index f3b95e30..5e61c914 100644 --- a/src/Tools/psxreadmap/Cargo.toml +++ b/src/Tools/psxreadmap/Cargo.toml @@ -3,7 +3,8 @@ name = "psxreadmap" version = "1.0.0" edition = "2021" -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +[profile.release] +panic = "abort" [dependencies] clap = {version = "*", features = ["derive"]} diff --git a/src/Tools/tool_helper/Cargo.toml b/src/Tools/tool_helper/Cargo.toml index 1373c636..4f4a2227 100644 --- a/src/Tools/tool_helper/Cargo.toml +++ b/src/Tools/tool_helper/Cargo.toml @@ -3,7 +3,8 @@ name = "tool_helper" version = "0.9.0" edition = "2021" -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +[profile.release] +panic = "abort" [dependencies] byteorder = "*" diff --git a/src/Tools/wslpath/Cargo.toml b/src/Tools/wslpath/Cargo.toml index 38c5a00d..74fca504 100644 --- a/src/Tools/wslpath/Cargo.toml +++ b/src/Tools/wslpath/Cargo.toml @@ -3,7 +3,8 @@ name = "wslpath" version = "1.0.0" edition = "2021" -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +[profile.release] +panic = "abort" [dependencies] clap = {version = "*", features = ["derive"]} \ No newline at end of file From 09e6aef6062d6d397917a10e98c7ee4200395bc4 Mon Sep 17 00:00:00 2001 From: jaby Date: Fri, 25 Aug 2023 06:31:00 +0200 Subject: [PATCH 109/588] Integrate psxreadmap --- examples/PoolBox/PoolBox.code-workspace | 18 ++++++++++++++++++ src/Tools/psxreadmap/readmap/src/types/mod.rs | 6 ++++++ src/Tools/psxreadmap/src/lib.rs | 10 +++++++++- .../#{ProjectName}.code-workspace | 18 ++++++++++++++++++ 4 files changed, 51 insertions(+), 1 deletion(-) diff --git a/examples/PoolBox/PoolBox.code-workspace b/examples/PoolBox/PoolBox.code-workspace index 17e82659..0bcf8bd0 100644 --- a/examples/PoolBox/PoolBox.code-workspace +++ b/examples/PoolBox/PoolBox.code-workspace @@ -22,6 +22,17 @@ } } }, + { + "label": "read memory map", + "type": "shell", + "command": "psxreadmap.exe ${input:output memory map} application/bin/PSX-${input:build profile}/PoolBox.elf", + "problemMatcher": [], + "options": { + "env": { + "PATH": "${env:JABY_ENGINE_PATH}/bin;${env:PATH}" + } + } + } ], "inputs": [ { @@ -44,6 +55,13 @@ "options": ["all", "clean", "rebuild"], "default": "all", "description": "the build target" + }, + { + "id": "output memory map", + "type": "pickString", + "options": ["", "-o application/bin/PoolBox.map"], + "default": "", + "description": "Output a memory map" } ] }, diff --git a/src/Tools/psxreadmap/readmap/src/types/mod.rs b/src/Tools/psxreadmap/readmap/src/types/mod.rs index 9010a12c..4f0fd510 100644 --- a/src/Tools/psxreadmap/readmap/src/types/mod.rs +++ b/src/Tools/psxreadmap/readmap/src/types/mod.rs @@ -6,6 +6,12 @@ pub struct MemoryMap { pub sections: Vec
} +impl MemoryMap { + pub fn is_empty(&self) -> bool { + self.global.is_empty() && self.sections.is_empty() + } +} + #[derive(Default)] pub struct Section { pub name: String, diff --git a/src/Tools/psxreadmap/src/lib.rs b/src/Tools/psxreadmap/src/lib.rs index a52e66b5..cc89f836 100644 --- a/src/Tools/psxreadmap/src/lib.rs +++ b/src/Tools/psxreadmap/src/lib.rs @@ -633,5 +633,13 @@ impl NamedMemoryArea for SectionInfo { } pub fn load_memory_map(use_wsl: bool, input: PathBuf) -> Result { - readmap_helper::generate_memory_map(use_wsl, input) + let memory_map = readmap_helper::generate_memory_map(use_wsl, input)?; + + if memory_map.is_empty() { + Err(Error::from_str("Failed reading memory map. Is the path correct?")) + } + + else { + Ok(memory_map) + } } \ No newline at end of file diff --git a/template/JabyEngine-PSX_Game/#{ProjectName}.code-workspace b/template/JabyEngine-PSX_Game/#{ProjectName}.code-workspace index 843a8d0a..fc06fe28 100644 --- a/template/JabyEngine-PSX_Game/#{ProjectName}.code-workspace +++ b/template/JabyEngine-PSX_Game/#{ProjectName}.code-workspace @@ -22,6 +22,17 @@ } } }, + { + "label": "read memory map", + "type": "shell", + "command": "psxreadmap.exe ${input:output memory map} application/bin/PSX-${input:build profile}/#{ProjectName}.elf", + "problemMatcher": [], + "options": { + "env": { + "PATH": "${env:JABY_ENGINE_PATH}/bin;${env:PATH}" + } + } + } ], "inputs": [ { @@ -44,6 +55,13 @@ "options": ["all", "clean", "rebuild"], "default": "all", "description": "the build target" + }, + { + "id": "output memory map", + "type": "pickString", + "options": ["", "-o application/bin/#{ProjectName}.map"], + "default": "", + "description": "Output a memory map" } ] }, From 54c7a2f8fe81b8a23c83c0b696081131017c3492 Mon Sep 17 00:00:00 2001 From: jaby Date: Fri, 25 Aug 2023 15:31:06 +0200 Subject: [PATCH 110/588] Improve rebuild behaviour --- examples/PoolBox/Makefile | 5 +---- lib/ISOTarget.mk | 2 +- lib/Makefile | 2 -- lib/PSEXETarget.mk | 6 +++++- lib/RebuildTarget.mk | 4 +--- template/JabyEngine-PSX_Game/Makefile | 5 +---- 6 files changed, 9 insertions(+), 15 deletions(-) diff --git a/examples/PoolBox/Makefile b/examples/PoolBox/Makefile index f379550a..6061d128 100644 --- a/examples/PoolBox/Makefile +++ b/examples/PoolBox/Makefile @@ -3,10 +3,7 @@ make_assets = $(MAKE) $(1) ARTIFACT=$(ARTIFACT) -C assets make_application = $(MAKE) $(1) ARTIFACT=$(ARTIFACT) -C application make_cd = $(MAKE) $(1) ARTIFACT=$(ARTIFACT) -f $(JABY_ENGINE_DIR)/lib/ISOTarget.mk -C iso -all clean rebuild: always - $(call make_assets,$(MAKECMDGOALS)) - $(call make_application,$(MAKECMDGOALS)) - $(call make_cd,$(MAKECMDGOALS)) +all clean rebuild: |assets_$(MAKECMDGOALS) application_$(MAKECMDGOALS) cd_$(MAKECMDGOALS) all_%: always $(call make_assets,$*) diff --git a/lib/ISOTarget.mk b/lib/ISOTarget.mk index f37fe9f0..1fa1a984 100644 --- a/lib/ISOTarget.mk +++ b/lib/ISOTarget.mk @@ -6,7 +6,7 @@ $(CD_OUTPUT): always all: $(CD_OUTPUT) -clean: +clean: rm -fr *.bin rm -fr *.cue rm -fr *.lba diff --git a/lib/Makefile b/lib/Makefile index f59f3bd0..4b9d388f 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -87,7 +87,5 @@ $(OUTPUT_DIR)/%.o: $$(subst !super,..,%.s) @mkdir -p $(dir $@) $(CC) $(ARCHFLAGS) -I$(PCSX_REDUX) -g -c -o $@ $< -include $(SELF_DIR)RebuildTarget.mk - #Inclusion of dependencies (object files to source and includes) -include $(OBJS:%.o=%.d) \ No newline at end of file diff --git a/lib/PSEXETarget.mk b/lib/PSEXETarget.mk index 6776709d..6f16adbd 100644 --- a/lib/PSEXETarget.mk +++ b/lib/PSEXETarget.mk @@ -30,4 +30,8 @@ $(AUTO_OVERLAY_DIR)/Overlays.mk: $(OVERLAY_CONFIG) all: $(TARGET).psexe $(OVERLAY_TARGET) clean: - rm -fr $(OUTPUT_DIR) \ No newline at end of file + rm -fr $(OUTPUT_DIR) + +# For mkoverlay to function correctly this is required (otherwise Overlays.mk is not re-generated) +rebuild: clean + $(MAKE) all diff --git a/lib/RebuildTarget.mk b/lib/RebuildTarget.mk index c180f356..59c7d2a0 100644 --- a/lib/RebuildTarget.mk +++ b/lib/RebuildTarget.mk @@ -1,3 +1 @@ -rebuild: - $(MAKE) clean - $(MAKE) all \ No newline at end of file +rebuild: |clean all \ No newline at end of file diff --git a/template/JabyEngine-PSX_Game/Makefile b/template/JabyEngine-PSX_Game/Makefile index 6acbd708..66b3d67a 100644 --- a/template/JabyEngine-PSX_Game/Makefile +++ b/template/JabyEngine-PSX_Game/Makefile @@ -3,10 +3,7 @@ make_assets = $(MAKE) $(1) ARTIFACT=$(ARTIFACT) -C assets make_application = $(MAKE) $(1) ARTIFACT=$(ARTIFACT) -C application make_cd = $(MAKE) $(1) ARTIFACT=$(ARTIFACT) -f $(JABY_ENGINE_DIR)/lib/ISOTarget.mk -C iso -all clean rebuild: always - $(call make_assets,$(MAKECMDGOALS)) - $(call make_application,$(MAKECMDGOALS)) - $(call make_cd,$(MAKECMDGOALS)) +all clean rebuild: |assets_$(MAKECMDGOALS) application_$(MAKECMDGOALS) cd_$(MAKECMDGOALS) all_%: always $(call make_assets,$*) From 2c3e0d2a59db7b2afe2e9cf52b8e5ff083926042 Mon Sep 17 00:00:00 2001 From: jaby Date: Sun, 27 Aug 2023 02:43:01 +0200 Subject: [PATCH 111/588] Improve reliablitity of psxreadmap --- src/Tools/psxreadmap/readmap/src/lib.rs | 60 +++++++++++-------- src/Tools/psxreadmap/src/lib.rs | 2 + src/Tools/psxreadmap/src/main.rs | 9 ++- .../psxreadmap/src/readmap_helper/mod.rs | 18 +++++- 4 files changed, 61 insertions(+), 28 deletions(-) diff --git a/src/Tools/psxreadmap/readmap/src/lib.rs b/src/Tools/psxreadmap/readmap/src/lib.rs index 4bf8b38e..1a1d9586 100644 --- a/src/Tools/psxreadmap/readmap/src/lib.rs +++ b/src/Tools/psxreadmap/readmap/src/lib.rs @@ -67,36 +67,43 @@ fn scan_symbols Option>(next_line: &mut F, memory_map: &mu } while let Some(line) = next_line() { + fn read_symbol(line: String) -> Result, Error> { + let split_count = line.split_whitespace().count(); + let mut split_line = line.split_whitespace(); + let adr = split_line_radix(&mut split_line, 16, "Address of Symbol")?; + let _type = split_line.next().ok_or(Error::from_str("Failed obtaining type of symbol"))?; + if split_count > 5 { + let _flag = split_line.next().ok_or(Error::from_str("Failed obtaining flag of symbol"))?; + } + let section = split_line.next().ok_or(Error::from_str("Failed obtaining section of symbol"))?; + let size = split_line_radix(&mut split_line, 16, "Size of Symbol")? as usize; + let name = split_line.next().ok_or(Error::from_str("Failed obtaining name of symbol"))?; + + if skip_symbol(name, section) { + // Not of interest + Ok(None) + } + + else { + Ok(Some((Symbol::new(name.to_string(), adr, size), section.to_owned()))) + } + } + if line.chars().all(char::is_whitespace) { return Ok(line); } - let split_count = line.split_whitespace().count(); - let mut split_line = line.split_whitespace(); - let adr = split_line_radix(&mut split_line, 16, "Address of Symbol")?; - let _type = split_line.next().ok_or(Error::from_str("Failed obtaining type of symbol"))?; - if split_count > 5 { - let _flag = split_line.next().ok_or(Error::from_str("Failed obtaining flag of symbol"))?; - } - let section = split_line.next().ok_or(Error::from_str("Failed obtaining section of symbol"))?; - let size = split_line_radix(&mut split_line, 16, "Size of Symbol")? as usize; - let name = split_line.next().ok_or(Error::from_str("Failed obtaining name of symbol"))?; - - if skip_symbol(name, section) { - // Not of interest - continue; - } - - let symbol = Symbol::new(name.to_string(), adr, size); - if let Some(section) = find_section(section, memory_map) { - if section.contains_adr(adr) { - section.symbols.push(symbol); - // Do not add to global cause they have a section - continue; + if let Ok(Some((symbol, section))) = read_symbol(line) { + if let Some(section) = find_section(section.as_str(), memory_map) { + if section.contains_adr(symbol.adr) { + section.symbols.push(symbol); + // Do not add to global cause they have a section + continue; + } } - } - memory_map.global.push(symbol); + memory_map.global.push(symbol); + } } Err(Error::from_str("Failed obtaining all Symbols")) @@ -124,8 +131,9 @@ fn scan_sections Option>(next_line: &mut F, sections: &mut } fn split_line_radix<'a>(split_line: &mut std::str::SplitWhitespace<'a>, radix: u32, value_name: &str) -> Result { - match u64::from_str_radix(split_line.next().ok_or(Error::from_text(format!("Failed reading: {}", value_name)))?, radix) { + let text = split_line.next().ok_or(Error::from_text(format!("Failed reading: {}", value_name)))?; + match u64::from_str_radix(text, radix) { Ok(value) => Ok(value), - Err(error) => Err(Error::from_text(format!("Converting value for {} failed with: {}", value_name, error))) + Err(error) => Err(Error::from_text(format!("Converting value ({}) for {} failed with: {}", text, value_name, error))) } } \ No newline at end of file diff --git a/src/Tools/psxreadmap/src/lib.rs b/src/Tools/psxreadmap/src/lib.rs index cc89f836..9e4f11b2 100644 --- a/src/Tools/psxreadmap/src/lib.rs +++ b/src/Tools/psxreadmap/src/lib.rs @@ -10,6 +10,8 @@ use ratatui::{ widgets::{Block, Borders, BorderType, Gauge, List, ListItem, ListState, Paragraph, Tabs, block::Title} }; +pub use readmap_helper::get_tool_output; + pub type EventReceiver = std::sync::mpsc::Receiver>; pub type Terminal = ratatui::Terminal>; type ConsoleFrame<'a> = ratatui::Frame<'a, ratatui::backend::CrosstermBackend>; diff --git a/src/Tools/psxreadmap/src/main.rs b/src/Tools/psxreadmap/src/main.rs index 83fa81df..a3a60ef1 100644 --- a/src/Tools/psxreadmap/src/main.rs +++ b/src/Tools/psxreadmap/src/main.rs @@ -2,7 +2,7 @@ use clap::Parser; use crossterm::{event::{self, Event as CEvent, KeyboardEnhancementFlags, KeyEventKind, PushKeyboardEnhancementFlags}, execute, terminal}; use psxreadmap::{ConsoleUI, Event, EventReceiver, Terminal, load_memory_map, UIState}; use std::{io::{self, Stdout}, path::PathBuf, sync::mpsc, thread, time::{Duration, Instant}}; -use tool_helper::{Error, exit_with_error}; +use tool_helper::{Error, exit_with_error, open_output}; use ratatui::backend::CrosstermBackend; pub const RUN_DUMP_TOOL_IN_WSL:bool = cfg!(windows); @@ -14,6 +14,8 @@ struct CommandLine { input: PathBuf, #[clap(long="wsl", help="Run \"objdump\" in WSL", default_value_t=RUN_DUMP_TOOL_IN_WSL)] use_wsl: bool, + #[clap(long="raw", default_value_t=false)] + raw_dump: bool, #[clap(short='o', help="Output a memory map file with running the tool")] output: Option } @@ -33,6 +35,11 @@ pub fn main() { } fn run_main(cmd: CommandLine) -> Result<(), Error> { + if cmd.raw_dump { + psxreadmap::get_tool_output(cmd.use_wsl, cmd.input, open_output(cmd.output)?)?; + return Ok(()); + } + let memory_map = load_memory_map(cmd.use_wsl, cmd.input)?; dump_memory_map(cmd.output, &memory_map)?; let rx = start_event_loop(); let terminal = setup_console()?; diff --git a/src/Tools/psxreadmap/src/readmap_helper/mod.rs b/src/Tools/psxreadmap/src/readmap_helper/mod.rs index a202febc..1318929c 100644 --- a/src/Tools/psxreadmap/src/readmap_helper/mod.rs +++ b/src/Tools/psxreadmap/src/readmap_helper/mod.rs @@ -1,4 +1,4 @@ -use tool_helper::Error; +use tool_helper::{Error, Output}; use readmap::types::MemoryMap; use std::{io::{BufRead, BufReader}, path::PathBuf, process::{Child, Command, Stdio}}; @@ -17,6 +17,22 @@ pub fn generate_memory_map(use_wsl: bool, input: PathBuf) -> Result Result { + let mut child = run_objdump(use_wsl, input)?; + if let Some(stdout) = &mut child.stdout { + let line_iter = BufReader::new(stdout).lines().map(|l| l.unwrap()).into_iter(); + + for line in line_iter { + writeln!(output, "{}", line)?; + } + Ok(output) + } + + else { + Err(Error::from_str("Failed opening \"stdout\" for objdump")) + } +} + fn run_objdump(use_wsl: bool, input: PathBuf) -> Result { let command_list = ["wsl", "objdump", "-x"]; let start_idx = { From 83cdade874fb90ff77a6374b0256522df5dac8f7 Mon Sep 17 00:00:00 2001 From: jaby Date: Sun, 27 Aug 2023 02:43:59 +0200 Subject: [PATCH 112/588] Share bss section with planschi section --- .../PSX/File/Processor/cd_file_processor.hpp | 4 +- lib/Makefile | 2 +- lib/PSEXETarget.mk | 2 +- lib/psexe.ld | 110 ++++++++++-------- src/Library/Makefile | 1 + src/Library/src/BootLoader/start_boot.cpp | 10 ++ src/Tools/mkoverlay/Cargo.toml | 2 +- src/Tools/mkoverlay/src/creator/ldscript.rs | 40 ++----- 8 files changed, 87 insertions(+), 84 deletions(-) diff --git a/include/PSX/File/Processor/cd_file_processor.hpp b/include/PSX/File/Processor/cd_file_processor.hpp index 42b408c5..19e42136 100644 --- a/include/PSX/File/Processor/cd_file_processor.hpp +++ b/include/PSX/File/Processor/cd_file_processor.hpp @@ -7,7 +7,7 @@ #include "../cd_file_types.hpp" #include "file_processor.hpp" -extern "C" uint32_t __heap_base; +extern "C" uint32_t __heap_start; namespace JabyEngine { class CDFileProcessor { @@ -20,7 +20,7 @@ namespace JabyEngine { size_t sector_count = 0; static constexpr BufferConfiguration new_default() { - return {&__heap_base, BufferConfiguration::MediumSectorCount}; + return {&__heap_start, BufferConfiguration::MediumSectorCount}; } }; diff --git a/lib/Makefile b/lib/Makefile index 4b9d388f..01616051 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -58,7 +58,7 @@ CCFLAGS += -DJABYENGINE_$(TV_FORMAT) #Linker flags LDFLAGS_release += -Os -LDFLAGS_all += -Wl,-Map=$(TARGET).map -nostdlib -T$(AUTO_OVERLAY_DIR)/Overlays.ld -T$(JABY_ENGINE_DIR)/lib/psexe.ld -static -Wl,--gc-sections -Wl,--build-id=none -Wl,--no-check-sections +LDFLAGS_all += -Wl,-Map=$(TARGET).map -nostdlib -T$(JABY_ENGINE_DIR)/lib/psexe.ld -static -Wl,--gc-sections -Wl,--build-id=none -Wl,--no-check-sections LDFLAGS_all += $(ARCHFLAGS) -Wl,--oformat=$(FORMAT) LDFLAGS_all += $(LDFLAGS_$(BUILD_PROFILE)) diff --git a/lib/PSEXETarget.mk b/lib/PSEXETarget.mk index 6f16adbd..ceef5f28 100644 --- a/lib/PSEXETarget.mk +++ b/lib/PSEXETarget.mk @@ -11,7 +11,7 @@ OVERLAY_TARGET = $(foreach ovl, $(OVERLAYSECTION), $(OUTPUT_DIR)/Overlay$(ovl)) #Linking rule $(TARGET).elf: $(OBJS) $(JABY_ENGINE_LIB_DIR)/lib$(JABY_ENGINE_LIB_NAME).a $(AUTO_OVERLAY_DIR)/Overlays.ld - $(LD) -o $(TARGET).elf $(LDFLAGS_all) $(LDFLAGS) $(OBJS) -L$(JABY_ENGINE_LIB_DIR) -l$(JABY_ENGINE_LIB_NAME) $(LIBS) + $(LD) -o $(TARGET).elf $(LDFLAGS_all) $(LDFLAGS) $(OBJS) -L$(JABY_ENGINE_LIB_DIR) -L$(AUTO_OVERLAY_DIR) -l$(JABY_ENGINE_LIB_NAME) $(LIBS) #Strips the psexe $(TARGET).psexe: $(TARGET).elf diff --git a/lib/psexe.ld b/lib/psexe.ld index aa5c6e7d..bdec0f2f 100644 --- a/lib/psexe.ld +++ b/lib/psexe.ld @@ -25,7 +25,6 @@ SOFTWARE. */ OUTPUT_FORMAT("binary") - EXTERN(_ZN10JabyEngine5startEv) ENTRY(_ZN10JabyEngine5startEv) @@ -34,7 +33,6 @@ TLOAD_ADDR = DEFINED(TLOAD_ADDR) ? TLOAD_ADDR : 0x80010000; MEMORY { loader : ORIGIN = (TLOAD_ADDR - 0x800), LENGTH = 2048 ram (rwx) : ORIGIN = 0x80010000, LENGTH = 2M - 0x10000 - ram2 (rwx) : ORIGIN = 0x80010000, LENGTH = 2M - 0x10000 dcache : ORIGIN = 0x1f800000, LENGTH = 0x400 } @@ -62,38 +60,39 @@ SECTIONS { } /*Overlay sections created by mkoverlay*/ +INCLUDE Overlays.ld SECTIONS { - .planschi __bss_end : SUBALIGN(4) + .planschi __engine_bss_end : SUBALIGN(4) { __planschi_start = .; __boot_loader_start = .; - *libJabyEngine.a:*_boot.o(.text.startup._GLOBAL__*) + *libJabyEngine_*.a:*_boot.o(.text.startup._GLOBAL__*) *_boot.o(.text.startup._GLOBAL__*) - *libJabyEngine.a:*_boot.o(.ctors) + *libJabyEngine_*.a:*_boot.o(.ctors) *_boot.o(.ctors) - *libJabyEngine.a:*_boot.o(.text.*) + *libJabyEngine_*.a:*_boot.o(.text.*) *_boot.o(.text.*) - *libJabyEngine.a:*_boot.o(.rodata*) + *libJabyEngine_*.a:*_boot.o(.rodata*) *_boot.o(.rodata*) - *libJabyEngine.a:*_boot.o(.sdata*) + *libJabyEngine_*.a:*_boot.o(.sdata*) *_boot.o(.sdata*) - *libJabyEngine.a:*_boot.o(.data*) + *libJabyEngine_*.a:*_boot.o(.data*) *_boot.o(.data*) - *libJabyEngine.a:*_boot.o(.sbss*) + *libJabyEngine_*.a:*_boot.o(.sbss*) *_boot.o(.sbss*) - *libJabyEngine.a:*_boot.o(.bss*) + *libJabyEngine_*.a:*_boot.o(.bss*) *_boot.o(.bss*) - *libJabyEngine.a:*_boot.o(*) + *libJabyEngine_*.a:*_boot.o(*) *_boot.o(*) . = ALIGN(4); __boot_loader_end = .; /*Only needed for the PSX BIOS to load the entire game*/ . = ALIGN(2048); - __planschi_end = .; - } + __planschi_end = .; + } } SECTIONS { @@ -141,37 +140,36 @@ SECTIONS { . = . + 1992; } > loader - __persistent_lbas_start = ABSOLUTE(.); .persistent_lbas TLOAD_ADDR : { - __persistent_lbas = .; - KEEP(*(.header.lbas)) + __persistent_lbas_start = .; + __persistent_lbas = .; + KEEP(*(.header.lbas)) + . = ALIGN(4); + __persistent_lbas_end = .; } > ram - . = ALIGN(4); - __persistent_lbas_end = ABSOLUTE(.); __ftext_start = ABSOLUTE(.); .text : { - *(.start) - *(.init) - KEEP (*(SORT_NONE(.fini))) - *(.text.unlikely .text.*_unlikely .text.unlikely.*) - *(.text.exit .text.exit.*) - *(.text.startup .text.startup.*) - *(.text.hot .text.hot.*) - *(.text .stub .text.* .gnu.linkonce.t.*) + __text_start = .; + *(.start) + *(.init) + KEEP (*(SORT_NONE(.fini))) + *(.text.unlikely .text.*_unlikely .text.unlikely.*) + *(.text.exit .text.exit.*) + *(.text.startup .text.startup.*) + *(.text.hot .text.hot.*) + *(.text .stub .text.* .gnu.linkonce.t.*) + . = ALIGN(16); + KEEP(*(.init)) + . = ALIGN(16); + KEEP(*(.fini)) . = ALIGN(16); - KEEP(*(.init)) - . = ALIGN(16); - KEEP(*(.fini)) + __text_end = .; } > ram - - . = ALIGN(16); - __text_end = .; __ftext_end = ABSOLUTE(.); __fdata_start = ABSOLUTE(.); - .rodata : { *(.rodata .rodata.* .rdata .rdata.* .gnu.linkonce.r.*) . = ALIGN(16); @@ -210,33 +208,43 @@ SECTIONS { *(.rodata1) } > ram - __data_start = .; .data : { - *(.a0table) - *(.data .data.* .gnu.linkonce.d.*) - *(.data1) - *(.sdata .sdata.* .gnu.linkonce.s.*) - *(.sdata2 .sdata2.* .gnu.linkonce.s2.*) - *(.got.plt) - *(.got) + __data_start = .; + *(.a0table) + *(.data .data.* .gnu.linkonce.d.*) + *(.data1) + *(.sdata .sdata.* .gnu.linkonce.s.*) + *(.sdata2 .sdata2.* .gnu.linkonce.s2.*) + *(.got.plt) + *(.got) + __data_end = .; } > ram - __data_end = .; + .engine_bss : { + __engine_bss_start = .; + *libJabyEngine_*.a:*(.dynsbss) + *libJabyEngine_*.a:*(.sbss .sbss.* .gnu.linkonce.sb.*) + *libJabyEngine_*.a:*(.scommon) + *libJabyEngine_*.a:*(.dynbss) + *libJabyEngine_*.a:*(.bss .bss.* .gnu.linkonce.b.*) + *libJabyEngine_*.a:*(COMMON) + . = ALIGN(4); + __engine_bss_end = .; + } > ram __fdata_end = .; - __bss_start = .; - .bss : { + + .bss __persistent_overlay_end (NOLOAD) : { + __bss_start = .; *(.dynsbss) *(.sbss .sbss.* .gnu.linkonce.sb.*) *(.scommon) *(.dynbss) *(.bss .bss.* .gnu.linkonce.b.*) *(COMMON) + . = ALIGN(4); + __bss_end = .; } > ram - . = ALIGN(4); - __bss_end = .; - __heap_start = __heap_base; - - /*. = ADDR(.text) - 0x800;*/ + __heap_start = __bss_end; __end = .; -} +} \ No newline at end of file diff --git a/src/Library/Makefile b/src/Library/Makefile index d4563cd1..2b77b4c8 100644 --- a/src/Library/Makefile +++ b/src/Library/Makefile @@ -1,3 +1,4 @@ +include ../../lib/RebuildTarget.mk JABY_ENGINE_DIR = ../../ ARTIFACT = libJabyEngine_$(TV_FORMAT) diff --git a/src/Library/src/BootLoader/start_boot.cpp b/src/Library/src/BootLoader/start_boot.cpp index 11fb9a3a..f3e8ea9b 100644 --- a/src/Library/src/BootLoader/start_boot.cpp +++ b/src/Library/src/BootLoader/start_boot.cpp @@ -3,6 +3,13 @@ #include #include +extern "C" uint32_t __heap_start; +extern "C" uint32_t __bss_start; +extern "C" uint32_t __bss_end; +extern "C" uint32_t __bss_len; +extern "C" uint32_t __planschi_start; +extern "C" uint32_t __planschi_end; + namespace JabyEngine { namespace boot { namespace Start { @@ -29,6 +36,9 @@ namespace JabyEngine { void start() { printf("Starting Planschbecken\n"); + printf("Heap starts @0x%p\n", &__heap_start); + printf("BSS from 0x%p to 0x%p (%u)\n", &__bss_start, &__bss_end, __bss_len); + printf("PLANSCHI from 0x%p to 0x%p\n", &__planschi_start, &__planschi_end); boot::Start::setup(); printf("Running main...\n"); diff --git a/src/Tools/mkoverlay/Cargo.toml b/src/Tools/mkoverlay/Cargo.toml index b13fa1dc..569ece16 100644 --- a/src/Tools/mkoverlay/Cargo.toml +++ b/src/Tools/mkoverlay/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "mkoverlay" -version = "1.1.1" +version = "1.5.0" edition = "2021" [profile.release] diff --git a/src/Tools/mkoverlay/src/creator/ldscript.rs b/src/Tools/mkoverlay/src/creator/ldscript.rs index 7e636375..a553987a 100644 --- a/src/Tools/mkoverlay/src/creator/ldscript.rs +++ b/src/Tools/mkoverlay/src/creator/ldscript.rs @@ -1,9 +1,7 @@ use super::super::types::{OverlayDesc, OverlaySection}; -use tool_helper::{Error, format_if_error, Output}; +use tool_helper::{Error, Output}; use std::io::Write; -const OVERLAY_DEFAULT_START:&'static str = "__planschi_start"; // < will probably be "__boot_loader_start" later - macro_rules! section_end_name_template { () => { "__{}_end" @@ -11,25 +9,8 @@ macro_rules! section_end_name_template { } pub fn write(output: &mut Output, overlay_desc: &OverlayDesc) -> Result<(), Error> { - fn create_heap_base(overlay_desc: &OverlayDesc) -> String { - let (first_entry, additional_slots_iter) = (&overlay_desc[0].name, overlay_desc.iter().skip(1)); - - let mut heap_start = format!(concat!("MAX({}, ", section_end_name_template!(), ")"), OVERLAY_DEFAULT_START, first_entry); - for slot in additional_slots_iter { - heap_start = format!(concat!("MAX(", section_end_name_template!(), ", {})"), slot.name, heap_start); - } - heap_start - } - - if overlay_desc.is_empty() { - write_heap_base(output, OVERLAY_DEFAULT_START)?; - } - - else { - write_heap_base(output, &create_heap_base(&overlay_desc))?; - } - - let mut slot_start_adr = format!(section_end_name_template!(), "bss"); + let has_overlays = !overlay_desc.is_empty(); + let mut slot_start_adr = format!(section_end_name_template!(), "engine_bss"); writeln!(output, "")?; writeln!(output, "SECTIONS {{")?; @@ -38,22 +19,25 @@ pub fn write(output: &mut Output, overlay_desc: &OverlayDesc) -> Result<(), Erro writeln!(output, "\t/*{}*/", slot.name)?; writeln!(output, "\tOVERLAY {} : NOCROSSREFS SUBALIGN(4) {{", slot_start_adr)?; write_section(output, &slot.sections, false)?; - writeln!(output, "\t}}")?; + writeln!(output, "\t}} > ram")?; writeln!(output, "\t. = ALIGN(4);")?; writeln!(output, concat!("\t", section_end_name_template!(), " = .;"), slot.name)?; writeln!(output, "")?; slot_start_adr = format!(section_end_name_template!(), slot.name); } + + if has_overlays { + writeln!(output, "\t__persistent_overlay_end = .;")?; + } + + else { + writeln!(output, "\t__persistent_overlay_end =__engine_bss_end;")?; + } writeln!(output, "}}")?; return Ok(()); } -fn write_heap_base(output: &mut Output, heap_base: &str) -> Result<(), Error> { - format_if_error!(writeln!(output, "__heap_base = {};", heap_base), "Writing default LD Script failed with: {error_text}")?; - Ok(()) -} - fn write_section(output: &mut Output, sections: &Vec, add_end_name: bool) -> Result<(), Error> { for section in sections { writeln!(output, "\t\t.{} {{", section.name)?; From db2e5543df5d19b16597583c6e2c067f16361ad7 Mon Sep 17 00:00:00 2001 From: jaby Date: Sun, 27 Aug 2023 16:45:56 +0200 Subject: [PATCH 113/588] Finalize linker script --- lib/psexe.ld | 9 +++++---- src/Tools/mkoverlay/Cargo.toml | 2 +- src/Tools/mkoverlay/src/creator/ldscript.rs | 2 +- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/lib/psexe.ld b/lib/psexe.ld index bdec0f2f..441541ec 100644 --- a/lib/psexe.ld +++ b/lib/psexe.ld @@ -31,9 +31,10 @@ ENTRY(_ZN10JabyEngine5startEv) TLOAD_ADDR = DEFINED(TLOAD_ADDR) ? TLOAD_ADDR : 0x80010000; MEMORY { - loader : ORIGIN = (TLOAD_ADDR - 0x800), LENGTH = 2048 - ram (rwx) : ORIGIN = 0x80010000, LENGTH = 2M - 0x10000 - dcache : ORIGIN = 0x1f800000, LENGTH = 0x400 + loader : ORIGIN = (TLOAD_ADDR - 0x800), LENGTH = 2048 + ram(rwx) : ORIGIN = 0x80010000, LENGTH = 2M - 0x10000 + ram_alt(rwx) : ORIGIN = 0x80010000, LENGTH = 2M - 0x10000 + dcache : ORIGIN = 0x1f800000, LENGTH = 0x400 } __ram_top = ORIGIN(ram) + LENGTH(ram); @@ -92,7 +93,7 @@ SECTIONS { /*Only needed for the PSX BIOS to load the entire game*/ . = ALIGN(2048); __planschi_end = .; - } + } > ram_alt } SECTIONS { diff --git a/src/Tools/mkoverlay/Cargo.toml b/src/Tools/mkoverlay/Cargo.toml index 569ece16..89fc9d9e 100644 --- a/src/Tools/mkoverlay/Cargo.toml +++ b/src/Tools/mkoverlay/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "mkoverlay" -version = "1.5.0" +version = "1.5.1" edition = "2021" [profile.release] diff --git a/src/Tools/mkoverlay/src/creator/ldscript.rs b/src/Tools/mkoverlay/src/creator/ldscript.rs index a553987a..e276e860 100644 --- a/src/Tools/mkoverlay/src/creator/ldscript.rs +++ b/src/Tools/mkoverlay/src/creator/ldscript.rs @@ -19,7 +19,7 @@ pub fn write(output: &mut Output, overlay_desc: &OverlayDesc) -> Result<(), Erro writeln!(output, "\t/*{}*/", slot.name)?; writeln!(output, "\tOVERLAY {} : NOCROSSREFS SUBALIGN(4) {{", slot_start_adr)?; write_section(output, &slot.sections, false)?; - writeln!(output, "\t}} > ram")?; + writeln!(output, "\t}} > ram_alt")?; writeln!(output, "\t. = ALIGN(4);")?; writeln!(output, concat!("\t", section_end_name_template!(), " = .;"), slot.name)?; writeln!(output, "")?; From c40a8f44a57183facbdcdedf68f7aafe75cea38d Mon Sep 17 00:00:00 2001 From: jaby Date: Sun, 27 Aug 2023 21:29:43 +0200 Subject: [PATCH 114/588] Introduce new timer based on vsync --- examples/PoolBox/application/src/main.cpp | 27 +++++++++-- include/PSX/GPU/gpu.hpp | 10 ++-- include/PSX/Timer/frame_time_helper.hpp | 25 ++++++++++ include/PSX/Timer/frame_timer.hpp | 59 +++++++++++++++++++++++ src/Library/src/GPU/gpu.cpp | 25 +++++----- src/Library/src/Timer/frame_timer.cpp | 5 ++ 6 files changed, 129 insertions(+), 22 deletions(-) create mode 100644 include/PSX/Timer/frame_time_helper.hpp create mode 100644 include/PSX/Timer/frame_timer.hpp create mode 100644 src/Library/src/Timer/frame_timer.cpp diff --git a/examples/PoolBox/application/src/main.cpp b/examples/PoolBox/application/src/main.cpp index 1f8d9abc..f29aee5e 100644 --- a/examples/PoolBox/application/src/main.cpp +++ b/examples/PoolBox/application/src/main.cpp @@ -2,23 +2,40 @@ #include "assets.hpp" #include #include +#include #include using namespace JabyEngine; +static SimpleTimer timer; + static void setup() { Assets::load_for_main(); FontWriter::setup(); + + timer.reset(); +} + +static void update() { + const auto end_pos = FontWriter::write({0, 32}, "Cody is cute\n&\na \x1b[8;0;0mBAAAAABY!!!"); + FontWriter::write(end_pos, "\x1b[0;7;7mJaby was\nhere c:"); + + if(timer.is_expired_for(1000_ms)) { + printf("Dino\n"); + timer.reset(); + } +} + +static void render() { + GPU::swap_buffers_vsync(1); + FontWriter::render(); } void main() { setup(); while(true) { - const auto end_pos = FontWriter::write({0, 32}, "Cody is cute\n&\na \x1b[8;0;0mBAAAAABY!!!"); - FontWriter::write(end_pos, "\x1b[0;7;7mJaby was\nhere c:"); - - GPU::swap_buffers_vsync(1); - FontWriter::render(); + update(); + render(); } } \ No newline at end of file diff --git a/include/PSX/GPU/gpu.hpp b/include/PSX/GPU/gpu.hpp index 2bc00fff..0381425c 100644 --- a/include/PSX/GPU/gpu.hpp +++ b/include/PSX/GPU/gpu.hpp @@ -16,11 +16,13 @@ namespace JabyEngine { namespace GPU { struct Display { #ifdef JABYENGINE_PAL - static constexpr size_t Width = 320; - static constexpr size_t Height = 256; + static constexpr size_t Width = 320; + static constexpr size_t Height = 256; + static constexpr uint32_t frames_per_sec = 50; #else - static constexpr size_t Width = 320; - static constexpr size_t Height = 240; + static constexpr size_t Width = 320; + static constexpr size_t Height = 240; + static constexpr uint32_t frames_per_sec = 50; #endif static uint8_t current_id; diff --git a/include/PSX/Timer/frame_time_helper.hpp b/include/PSX/Timer/frame_time_helper.hpp new file mode 100644 index 00000000..d6c32913 --- /dev/null +++ b/include/PSX/Timer/frame_time_helper.hpp @@ -0,0 +1,25 @@ +#ifndef __JABYENGINE_FRAME_TIME_HELPER_HPP__ +#define __JABYENGINE_FRAME_TIME_HELPER_HPP__ +#include +#include + +namespace JabyEngine { + static constexpr double ms_per_frame = 1000.0/static_cast(GPU::Display::frames_per_sec); + + template + static constexpr T ms_to_vsync_ticks(T time_ms) { + return static_cast(static_cast(time_ms)/ms_per_frame); + } + + static constexpr uint32_t operator ""_ms(unsigned long long time) { + return static_cast(ms_to_vsync_ticks(time)); + } + + static constexpr size_t max_ms_time_u8 = UI8_MAX*ms_per_frame; + static constexpr size_t max_ms_time_u16 = UI16_MAX*ms_per_frame; + static constexpr size_t max_ms_time_u32 = UI32_MAX; + + #undef literal_operator_template +} +using JabyEngine::operator""_ms; +#endif //!__JABYENGINE_FRAME_TIME_HELPER_HPP__ \ No newline at end of file diff --git a/include/PSX/Timer/frame_timer.hpp b/include/PSX/Timer/frame_timer.hpp new file mode 100644 index 00000000..251f644f --- /dev/null +++ b/include/PSX/Timer/frame_timer.hpp @@ -0,0 +1,59 @@ +#ifndef __JABYENGINE_FRAME_TIMER_HPP__ +#define __JABYENGINE_FRAME_TIMER_HPP__ +#include "frame_time_helper.hpp" +#include + +namespace JabyEngine { + class MasterTime { + private: + static uint32_t value; + + public: + static uint32_t read() { + return reinterpret_cast(MasterTime::value); + } + + template + static T read_as() { + return static_cast(MasterTime::read()); + } + }; + + template + class SimpleTimer { + protected: + T value = 0; + + public: + constexpr SimpleTimer() = default; + + bool is_expired_for(T time) const { + return static_cast((MasterTime::read_as() - this->value)) >= time; + } + + void reset() { + this->value = MasterTime::read_as(); + } + }; + + template + class IntervalTimer : public SimpleTimer { + private: + T interval = 0; + + public: + constexpr IntervalTimer() = default; + constexpr IntervalTimer(T interval) : SimpleTimer(), interval(interval) { + } + + void set_interval(T interval) { + this->interval = interval; + } + + bool is_expired() const { + return SimpleTimer::is_expired_for(this->interval); + } + }; +} + +#endif //!__JABYENGINE_FRAME_TIMER_HPP__ \ No newline at end of file diff --git a/src/Library/src/GPU/gpu.cpp b/src/Library/src/GPU/gpu.cpp index fd2f7578..8d1a6a24 100644 --- a/src/Library/src/GPU/gpu.cpp +++ b/src/Library/src/GPU/gpu.cpp @@ -1,4 +1,8 @@ #include "../../internal-include/GPU/gpu_internal.hpp" +// We need to access the master time +#define private public +#include +#undef private #include #include @@ -7,12 +11,12 @@ namespace JabyEngine { uint8_t Display :: current_id = 1; //< Setup will call exchange and set it to 0 namespace internal { - static uint8_t vsync_count = 0; - static InterruptVerifierResult interrupt_verifier(); static void interrupt_handler(uint32_t); - InterrupCallback callback = { + static uint8_t vsync_counter = 0; + + InterrupCallback callback = { .next = nullptr, .handler_function = reinterpret_cast(interrupt_handler), .verifier_function = interrupt_verifier @@ -29,9 +33,8 @@ namespace JabyEngine { } static void interrupt_handler(uint32_t) { - if(vsync_count != 0xFF) { - vsync_count++; - } + vsync_counter++; + MasterTime::value++; Interrupt::ack_irq(Interrupt::VBlank); __syscall_ReturnFromException(); @@ -47,14 +50,10 @@ namespace JabyEngine { } void wait_vsync(uint8_t syncs) { - volatile uint8_t& vsync_count = reinterpret_cast(internal::vsync_count); + volatile auto& vsync_count = reinterpret_cast(vsync_counter); + const uint8_t dst_value = vsync_count + syncs; - if(internal::vsync_count >= syncs) { - syncs = internal::vsync_count + 1; - } - - while(vsync_count < syncs); - vsync_count = 0; + while(vsync_count != dst_value); } void render(const uint32_t* data, size_t words) { diff --git a/src/Library/src/Timer/frame_timer.cpp b/src/Library/src/Timer/frame_timer.cpp new file mode 100644 index 00000000..1c085633 --- /dev/null +++ b/src/Library/src/Timer/frame_timer.cpp @@ -0,0 +1,5 @@ +#include + +namespace JabyEngine { + uint32_t MasterTime :: value = 0; +} \ No newline at end of file From ad0144fd4c0e374beb05e6bbbdd2ccc5821b2395 Mon Sep 17 00:00:00 2001 From: jaby Date: Sun, 27 Aug 2023 21:55:16 +0200 Subject: [PATCH 115/588] Clear bss section --- src/Library/src/run.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/Library/src/run.cpp b/src/Library/src/run.cpp index d0c9940e..5484ced3 100644 --- a/src/Library/src/run.cpp +++ b/src/Library/src/run.cpp @@ -1,11 +1,24 @@ #include #include +extern "C" uint32_t __bss_start; +extern "C" uint32_t __bss_end; extern void main(); namespace JabyEngine { + static void clear_bss() { + uint32_t* bss_adr = &__bss_start; + while(bss_adr < &__bss_end) { + printf("Free: 0x%p\n", bss_adr); + *bss_adr = 0; + bss_adr++; + } + } + // Executes the game void __no_return run() { + clear_bss(); + main(); printf("Stop!!\n"); while(true); From 98395df9295d4882f5bb8e91c45b9f3a7296d4e9 Mon Sep 17 00:00:00 2001 From: jaby Date: Mon, 28 Aug 2023 16:48:26 +0200 Subject: [PATCH 116/588] Fix bss init --- src/Library/src/run.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Library/src/run.cpp b/src/Library/src/run.cpp index 5484ced3..9f9503c8 100644 --- a/src/Library/src/run.cpp +++ b/src/Library/src/run.cpp @@ -9,7 +9,6 @@ namespace JabyEngine { static void clear_bss() { uint32_t* bss_adr = &__bss_start; while(bss_adr < &__bss_end) { - printf("Free: 0x%p\n", bss_adr); *bss_adr = 0; bss_adr++; } From c6c92316700dfe54d352f74fca2079b1adda12f1 Mon Sep 17 00:00:00 2001 From: jaby Date: Mon, 28 Aug 2023 16:48:42 +0200 Subject: [PATCH 117/588] Display Pacos art --- examples/PoolBox/application/src/assets.hpp | 1 + examples/PoolBox/application/src/main.cpp | 14 +++++++++++++- examples/PoolBox/application/src/main_assets.cpp | 2 ++ examples/PoolBox/assets/Makefile | 6 +++++- examples/PoolBox/assets/Paco.png | 3 +++ examples/PoolBox/iso/Config.xml | 1 + 6 files changed, 25 insertions(+), 2 deletions(-) create mode 100644 examples/PoolBox/assets/Paco.png diff --git a/examples/PoolBox/application/src/assets.hpp b/examples/PoolBox/application/src/assets.hpp index a92673eb..c70f17dc 100644 --- a/examples/PoolBox/application/src/assets.hpp +++ b/examples/PoolBox/application/src/assets.hpp @@ -6,6 +6,7 @@ namespace Assets { using namespace JabyEngine; static constexpr auto FontTIM = SimpleTIM(960, 0, 960, 511); + static constexpr auto PacoTIM = SimpleTIM(896, 0, 960, 510); void load_for_main(); } diff --git a/examples/PoolBox/application/src/main.cpp b/examples/PoolBox/application/src/main.cpp index f29aee5e..03ebc201 100644 --- a/examples/PoolBox/application/src/main.cpp +++ b/examples/PoolBox/application/src/main.cpp @@ -1,19 +1,30 @@ #include "FontWriter/font_writer.hpp" #include "assets.hpp" -#include #include +#include #include #include using namespace JabyEngine; static SimpleTimer timer; +static auto paco_texpage = GPU::TexPage( + {Assets::PacoTIM.get_texture_x(), Assets::PacoTIM.get_texture_y()}, + GPU::TexturePageColor::$4bit +).linked(); +static auto paco = GPU::SPRT( + // This pic used to be 122px (file size) and every tool would except it - however the display would be corrupt. Try it!! + GPU::AreaI16({0, 100}, {120, 128}), + GPU::PagePositionClut({0, 0}, GPU::PageClut(Assets::PacoTIM.get_clut_x(), Assets::PacoTIM.get_clut_y())), + GPU::Color24::Grey() +).linked(); static void setup() { Assets::load_for_main(); FontWriter::setup(); timer.reset(); + paco_texpage.concat(paco); } static void update() { @@ -28,6 +39,7 @@ static void update() { static void render() { GPU::swap_buffers_vsync(1); + GPU::render(paco_texpage); FontWriter::render(); } diff --git a/examples/PoolBox/application/src/main_assets.cpp b/examples/PoolBox/application/src/main_assets.cpp index b3ea8041..241d59e1 100644 --- a/examples/PoolBox/application/src/main_assets.cpp +++ b/examples/PoolBox/application/src/main_assets.cpp @@ -6,6 +6,7 @@ namespace Assets { enum LBA { __jabyengine_start_lba_request __jabyengine_request_lba_for(FONT, "ASSETS/MAIN/FONT.BIN"), + __jabyengine_request_lba_for(PACO, "ASSETS/MAIN/PACO.BIN"), __jabyengine_end_lba_request }; @@ -14,6 +15,7 @@ namespace Assets { void load_for_main() { static const CDFile Assets[] = { CDFileBuilder::simple_tim(LBA::FONT, FontTIM), + CDFileBuilder::simple_tim(LBA::PACO, PacoTIM), }; const auto buffer_cfg = CDFileProcessor::BufferConfiguration::new_default(); diff --git a/examples/PoolBox/assets/Makefile b/examples/PoolBox/assets/Makefile index ba1dc0ad..012b4b7a 100644 --- a/examples/PoolBox/assets/Makefile +++ b/examples/PoolBox/assets/Makefile @@ -2,6 +2,7 @@ include $(JABY_ENGINE_DIR)/lib/ExportPath.mk include $(JABY_ENGINE_DIR)/lib/RebuildTarget.mk OUTPUT_DIR = bin +INPUT = $(OUTPUT_DIR)/TexturePage.bin $(OUTPUT_DIR)/IconTexture.bin $(OUTPUT_DIR)/YoshiFont.bin $(OUTPUT_DIR)/Paco.bin $(OUTPUT_DIR)/TexturePage.bin: TexturePage.png @mkdir -p $(OUTPUT_DIR) @@ -14,7 +15,10 @@ $(OUTPUT_DIR)/IconTexture.bin: IconTexture.png $(OUTPUT_DIR)/YoshiFont.bin: YoshiFont.png jaby_engine_fconv --lz4 $< -o $@ simple-tim clut4 --color-trans -all: $(OUTPUT_DIR)/TexturePage.bin $(OUTPUT_DIR)/IconTexture.bin $(OUTPUT_DIR)/YoshiFont.bin +$(OUTPUT_DIR)/Paco.bin: Paco.png + jaby_engine_fconv --lz4 $< -o $@ simple-tim clut4 + +all: $(INPUT) clean: rm -fr $(OUTPUT_DIR) \ No newline at end of file diff --git a/examples/PoolBox/assets/Paco.png b/examples/PoolBox/assets/Paco.png new file mode 100644 index 00000000..05db9e67 --- /dev/null +++ b/examples/PoolBox/assets/Paco.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7ffd5f19946196768be2c2b14a7b7de2c3d7e0016969c58c4366799d4c4a4dd5 +size 5127 diff --git a/examples/PoolBox/iso/Config.xml b/examples/PoolBox/iso/Config.xml index 0211a1f3..c36a0ab5 100644 --- a/examples/PoolBox/iso/Config.xml +++ b/examples/PoolBox/iso/Config.xml @@ -9,6 +9,7 @@