Merge pull request 'Fix inconsistent EOL' (#11) from feature/jb/eol into main

Reviewed-on: #11
This commit is contained in:
cody 2025-01-08 21:31:36 +00:00
commit 40b0ad105f
184 changed files with 13686 additions and 13685 deletions

3
.gitattributes vendored
View File

@ -2,4 +2,5 @@
*.wav filter=lfs diff=lfs merge=lfs -text *.wav filter=lfs diff=lfs merge=lfs -text
*.png filter=lfs diff=lfs merge=lfs -text *.png filter=lfs diff=lfs merge=lfs -text
*.mp3 filter=lfs diff=lfs merge=lfs -text *.mp3 filter=lfs diff=lfs merge=lfs -text
*.TMD filter=lfs diff=lfs merge=lfs -text *.TMD filter=lfs diff=lfs merge=lfs -text
* text=auto eol=lf

38
.gitignore vendored
View File

@ -1,20 +1,20 @@
# For now we ignore what is in root # For now we ignore what is in root
**/build **/build
**/bin **/bin
**/gcm.cache **/gcm.cache
**/iso/Info **/iso/Info
/iso /iso
# Custom configs should not be part of JabyEngine # Custom configs should not be part of JabyEngine
**/config **/config
.lfsconfig .lfsconfig
*.d *.d
*.a *.a
*.o *.o
*.ii *.ii
*.xa *.xa
# TODO: Remove later # TODO: Remove later
examples/PoolBox/assets/tmp.VAG examples/PoolBox/assets/tmp.VAG

View File

@ -1,6 +1,6 @@
#include "../dummy_default_config.hpp" #include "../dummy_default_config.hpp"
struct CustomConfiguration : public DefaultConfiguration { struct CustomConfiguration : public DefaultConfiguration {
}; };
#define __USE_DEBUG_COLOR__ #define __USE_DEBUG_COLOR__

View File

@ -1,48 +1,48 @@
# How to create custom configurations # How to create custom configurations
1. Create folder with name of custom configuration 1. Create folder with name of custom configuration
1. Add `jabyengine_custom_config.hpp` to folder 1. Add `jabyengine_custom_config.hpp` to folder
1. Follow [guidelines](#jabyengine_custom_confighpp) 1. Follow [guidelines](#jabyengine_custom_confighpp)
1. Build JabyEngine and select your configuration 1. Build JabyEngine and select your configuration
1. Build your application and select your configuration 1. Build your application and select your configuration
## jabyengine_custom_config.hpp ## jabyengine_custom_config.hpp
### Default configuration file ### Default configuration file
```c++ ```c++
// Fix IntelliSense // Fix IntelliSense
#include "../dummy_default_config.hpp" #include "../dummy_default_config.hpp"
// Overwrite various configurations // Overwrite various configurations
struct CustomConfiguration : public DefaultConfiguration { struct CustomConfiguration : public DefaultConfiguration {
}; };
// Define macros here // Define macros here
``` ```
### `CustomConfiguration` options ### `CustomConfiguration` options
When overriding an option make sure to mark the function as `override` When overriding an option make sure to mark the function as `override`
```c++ ```c++
struct DefaultConfiguration { struct DefaultConfiguration {
struct BIOSFont { struct BIOSFont {
// VRAM position and CLUT position to load the BIOS font too // VRAM position and CLUT position to load the BIOS font too
static constexpr GPU::PositionU16 texture_load_pos(); static constexpr GPU::PositionU16 texture_load_pos();
static constexpr GPU::PositionU16 CLUT_load_pos(); static constexpr GPU::PositionU16 CLUT_load_pos();
}; };
// Offsets the default origin of the screen by the specified value // Offsets the default origin of the screen by the specified value
static constexpr auto DisplayDefaultOffset; static constexpr auto DisplayDefaultOffset;
struct Periphery { struct Periphery {
// Turns on the second controller port and enables multi tap support // Turns on the second controller port and enables multi tap support
static constexpr bool include_portB(); static constexpr bool include_portB();
static constexpr bool use_multi_tap(); static constexpr bool use_multi_tap();
}; };
}; };
``` ```
### `CustomConfiguration` macros ### `CustomConfiguration` macros
```c++ ```c++
// Turns on debug information of the SPU MMU (on by default [for now]) // Turns on debug information of the SPU MMU (on by default [for now])
#define __DEBUG_SPU_MMU__ #define __DEBUG_SPU_MMU__
// Turns on colored rectangles during boot (off by default) // Turns on colored rectangles during boot (off by default)
#define __USE_DEBUG_COLOR__ #define __USE_DEBUG_COLOR__
// Turns on PS3 support (on by default) // Turns on PS3 support (on by default)
#define __SUPPORT_PS3__ #define __SUPPORT_PS3__
``` ```

View File

@ -1,7 +1,7 @@
#pragma once #pragma once
#ifdef __INTELLISENSE__ #ifdef __INTELLISENSE__
// This provides a dummy struct so IntelliSense is happy // This provides a dummy struct so IntelliSense is happy
struct DefaultConfiguration { struct DefaultConfiguration {
}; };
#endif //! __INTELLISENSE__ #endif //! __INTELLISENSE__

View File

@ -1,6 +1,6 @@
# Observed bugs # Observed bugs
- [Observed bugs](#observed-bugs) - [Observed bugs](#observed-bugs)
- [Deadlock](#deadlock) - [Deadlock](#deadlock)
## Deadlock ## Deadlock
It was observed in `PoolBox` when loading the `FontCycler` overlay that a deadlock occurred. This error has not been observed since. The current theory is that accidentally an old save state in the emulator was loaded. It was observed in `PoolBox` when loading the `FontCycler` overlay that a deadlock occurred. This error has not been observed since. The current theory is that accidentally an old save state in the emulator was loaded.

View File

@ -1,52 +1,52 @@
ARTIFACT = PoolBox ARTIFACT = PoolBox
make_assets = $(MAKE) $(1) ARTIFACT=$(ARTIFACT) -C assets make_assets = $(MAKE) $(1) ARTIFACT=$(ARTIFACT) -C assets
make_application = $(MAKE) $(1) ARTIFACT=$(ARTIFACT) -C application make_application = $(MAKE) $(1) ARTIFACT=$(ARTIFACT) -C application
make_cd = $(MAKE) $(1) ARTIFACT=$(ARTIFACT) -C iso make_cd = $(MAKE) $(1) ARTIFACT=$(ARTIFACT) -C iso
ifndef REGION ifndef REGION
$(error REGION has to be set!) $(error REGION has to be set!)
endif endif
# Add regions on your own # Add regions on your own
# Extend them with what you need # Extend them with what you need
ifeq ($(REGION),SCEE) ifeq ($(REGION),SCEE)
export PSX_TV_FORMAT=PAL export PSX_TV_FORMAT=PAL
export PSX_LICENSE=LICENSEE export PSX_LICENSE=LICENSEE
export PSX_BOOT_FILE=SLES_AAA.AA export PSX_BOOT_FILE=SLES_AAA.AA
endif endif
ifeq ($(REGION),SCEA) ifeq ($(REGION),SCEA)
export PSX_TV_FORMAT=NTSC export PSX_TV_FORMAT=NTSC
export PSX_LICENSE=LICENSEA export PSX_LICENSE=LICENSEA
export PSX_BOOT_FILE=SLUS_AAA.AA export PSX_BOOT_FILE=SLUS_AAA.AA
endif endif
ifeq ($(REGION),SCEI) ifeq ($(REGION),SCEI)
export PSX_TV_FORMAT=NTSC export PSX_TV_FORMAT=NTSC
export PSX_LICENSE=LICENSEJ export PSX_LICENSE=LICENSEJ
export PSX_BOOT_FILE=SLJS_AAA.AA export PSX_BOOT_FILE=SLJS_AAA.AA
endif endif
ifndef PSX_TV_FORMAT ifndef PSX_TV_FORMAT
$(error PSX_TV_FORMAT has not be set! REGION not specified?) $(error PSX_TV_FORMAT has not be set! REGION not specified?)
endif endif
ifndef PSX_LICENSE ifndef PSX_LICENSE
$(error PSX_LICENSE has not be set! REGION not specified?) $(error PSX_LICENSE has not be set! REGION not specified?)
endif endif
all clean rebuild: |assets_$(MAKECMDGOALS) application_$(MAKECMDGOALS) cd_$(MAKECMDGOALS) all clean rebuild: |assets_$(MAKECMDGOALS) application_$(MAKECMDGOALS) cd_$(MAKECMDGOALS)
all_%: always all_%: always
$(call make_assets,$*) $(call make_assets,$*)
$(call make_application,$*) $(call make_application,$*)
$(call make_cd,$*) $(call make_cd,$*)
assets_%: always assets_%: always
$(call make_assets,$*) $(call make_assets,$*)
application_%: always application_%: always
$(call make_application,$*) $(call make_application,$*)
cd_%: always cd_%: always
$(call make_cd,$*) $(call make_cd,$*)
pkg_%: always pkg_%: always
$(call make_cd,pkg_$*) $(call make_cd,pkg_$*)
always: ; always: ;

View File

@ -1,93 +1,93 @@
{ {
"folders": [ "folders": [
{ {
"path": ".", "path": ".",
"name": "PoolBox" "name": "PoolBox"
} }
], ],
"tasks": { "tasks": {
"version": "2.0.0", "version": "2.0.0",
"tasks": [ "tasks": [
{ {
"label": "build", "label": "build",
"type": "shell", "type": "shell",
"command": "${env:JABY_ENGINE_PATH}/scripts/podman_jaby_engine.sh ${workspaceFolder}:. make ${input:project}_${input:target} BUILD_PROFILE=${input:build profile} REGION=${input:region} CUSTOM_CONFIG=${input:custom config}", "command": "${env:JABY_ENGINE_PATH}/scripts/podman_jaby_engine.sh ${workspaceFolder}:. make ${input:project}_${input:target} BUILD_PROFILE=${input:build profile} REGION=${input:region} CUSTOM_CONFIG=${input:custom config}",
"group": { "group": {
"kind": "build", "kind": "build",
"isDefault": true "isDefault": true
}, },
}, },
{ {
"label": "read memory map", "label": "read memory map",
"type": "shell", "type": "shell",
"command": "${env:JABY_ENGINE_PATH}/bin/psxreadmap ${input:output memory map} application/bin/${input:tv format}/PSX-${input:build profile}/PoolBox.elf", "command": "${env:JABY_ENGINE_PATH}/bin/psxreadmap ${input:output memory map} application/bin/${input:tv format}/PSX-${input:build profile}/PoolBox.elf",
"problemMatcher": [], "problemMatcher": [],
} }
], ],
"inputs": [ "inputs": [
{ {
"id": "build profile", "id": "build profile",
"type": "pickString", "type": "pickString",
"options": ["debug", "release"], "options": ["debug", "release"],
"default": "release", "default": "release",
"description": "The build profile for PoolBox" "description": "The build profile for PoolBox"
}, },
{ {
"id": "project", "id": "project",
"type": "pickString", "type": "pickString",
"options": ["all", "assets", "application", "cd", "pkg"], "options": ["all", "assets", "application", "cd", "pkg"],
"default": "all", "default": "all",
"description": "Project to build" "description": "Project to build"
}, },
{ {
"id": "target", "id": "target",
"type": "pickString", "type": "pickString",
"options": ["all", "clean", "rebuild"], "options": ["all", "clean", "rebuild"],
"default": "all", "default": "all",
"description": "the build target" "description": "the build target"
}, },
{ {
"id": "region", "id": "region",
"type": "pickString", "type": "pickString",
"options": ["SCEE", "SCEA", "SCEI"], "options": ["SCEE", "SCEA", "SCEI"],
"default": "SCEE", "default": "SCEE",
"description": "Region profile to use" "description": "Region profile to use"
}, },
{ {
"id": "custom config", "id": "custom config",
"type": "command", "type": "command",
"command": "shellCommand.execute", "command": "shellCommand.execute",
"args": { "args": {
"command": "echo \"|<Default>\" && ls -d */", "command": "echo \"|<Default>\" && ls -d */",
"cwd": "${env:JABY_ENGINE_PATH}/config", "cwd": "${env:JABY_ENGINE_PATH}/config",
"fieldSeparator": "|" "fieldSeparator": "|"
} }
}, },
{ {
"id": "output memory map", "id": "output memory map",
"type": "pickString", "type": "pickString",
"options": ["", "-o application/bin/PoolBox.map"], "options": ["", "-o application/bin/PoolBox.map"],
"default": "", "default": "",
"description": "Output a memory map" "description": "Output a memory map"
} }
] ]
}, },
"extensions": { "extensions": {
"recommendations": ["augustocdias.tasks-shell-input"] "recommendations": ["augustocdias.tasks-shell-input"]
}, },
"settings": { "settings": {
"C_Cpp.default.includePath": [ "C_Cpp.default.includePath": [
"${env:JABY_ENGINE_PATH}/include", "${env:JABY_ENGINE_PATH}/include",
"${env:JABY_ENGINE_PATH}/support/include" "${env:JABY_ENGINE_PATH}/support/include"
], ],
"C_Cpp.default.compilerPath": "", "C_Cpp.default.compilerPath": "",
"C_Cpp.default.cStandard": "c17", "C_Cpp.default.cStandard": "c17",
"C_Cpp.default.cppStandard": "c++20", "C_Cpp.default.cppStandard": "c++20",
"C_Cpp.default.intelliSenseMode": "linux-gcc-x86", "C_Cpp.default.intelliSenseMode": "linux-gcc-x86",
"C_Cpp.default.compilerArgs": [ "C_Cpp.default.compilerArgs": [
], ],
"C_Cpp.default.defines": [ "C_Cpp.default.defines": [
"JABYENGINE_PAL" "JABYENGINE_PAL"
], ],
} }
} }

View File

@ -1,12 +1,12 @@
OVERLAY_CONFIG = Overlays.json OVERLAY_CONFIG = Overlays.json
include $(JABY_ENGINE_DIR)/mkfile/common/Wildcard.mk include $(JABY_ENGINE_DIR)/mkfile/common/Wildcard.mk
SRCS = $(call rwildcard, src, c cpp) SRCS = $(call rwildcard, src, c cpp)
INCLUDES += -I$(JABY_ENGINE_DIR)/support/include -I$(JABY_ENGINE_DIR)/include INCLUDES += -I$(JABY_ENGINE_DIR)/support/include -I$(JABY_ENGINE_DIR)/include
CCFLAGS += -save-temps=obj CCFLAGS += -save-temps=obj
SUPPORT_LIBS += FontWriter SUPPORT_LIBS += FontWriter
include $(JABY_ENGINE_DIR)/mkfile/Makefile include $(JABY_ENGINE_DIR)/mkfile/Makefile
include $(JABY_ENGINE_DIR)/mkfile/PSEXETarget.mk include $(JABY_ENGINE_DIR)/mkfile/PSEXETarget.mk

View File

@ -1,22 +1,22 @@
{ {
"slot_0": { "slot_0": {
"bios_info": { "bios_info": {
"pattern": "bin/*/src/Overlay/BIOSInfo/*.o" "pattern": "bin/*/src/Overlay/BIOSInfo/*.o"
}, },
"controller_tests": { "controller_tests": {
"pattern": "bin/*/src/Overlay/ControllerTest/*.o" "pattern": "bin/*/src/Overlay/ControllerTest/*.o"
}, },
"gpu_tests": { "gpu_tests": {
"pattern": "bin/*/src/Overlay/GPUTest/*.o" "pattern": "bin/*/src/Overlay/GPUTest/*.o"
}, },
"gte_tests": { "gte_tests": {
"pattern": "bin/*/src/Overlay/GTETest/*.o" "pattern": "bin/*/src/Overlay/GTETest/*.o"
}, },
"font_cycler": { "font_cycler": {
"pattern": "bin/*/src/Overlay/FontCycler/*.o" "pattern": "bin/*/src/Overlay/FontCycler/*.o"
}, },
"screen_center": { "screen_center": {
"pattern": "bin/*/src/Overlay/ScreenCenter/*.o" "pattern": "bin/*/src/Overlay/ScreenCenter/*.o"
} }
} }
} }

View File

@ -1,41 +1,41 @@
#pragma once #pragma once
#include <PSX/File/cd_file_types.hpp> #include <PSX/File/cd_file_types.hpp>
namespace Assets { namespace Assets {
using namespace JabyEngine; using namespace JabyEngine;
namespace Main { namespace Main {
struct ImageInfo { struct ImageInfo {
SimpleTIM tim; SimpleTIM tim;
GPU::SizeI16 size; GPU::SizeI16 size;
}; };
static constexpr auto PacoTIM = SimpleTIM::create(896, 0, 960, 510); static constexpr auto PacoTIM = SimpleTIM::create(896, 0, 960, 510);
static constexpr auto DoenerFishInfo = ImageInfo{ static constexpr auto DoenerFishInfo = ImageInfo{
.tim = SimpleTIM::create(896 + 30, 0, 960 + 16, 510), .tim = SimpleTIM::create(896 + 30, 0, 960 + 16, 510),
.size = GPU::SizeI16::create(128, 64) .size = GPU::SizeI16::create(128, 64)
}; };
namespace JabyLoader { namespace JabyLoader {
static constexpr auto TIMLoaction = SimpleTIM::create(PacoTIM.get_texture_x(), PacoTIM.get_texture_y() + 128, 960 + 48, 510); static constexpr auto TIMLoaction = SimpleTIM::create(PacoTIM.get_texture_x(), PacoTIM.get_texture_y() + 128, 960 + 48, 510);
static constexpr auto JabyFrame = GPU::AreaI16::create(0, 0, 32, 44); static constexpr auto JabyFrame = GPU::AreaI16::create(0, 0, 32, 44);
static constexpr auto FontFrame = GPU::AreaI16::create(0, 45, 186, 32); static constexpr auto FontFrame = GPU::AreaI16::create(0, 45, 186, 32);
}; };
void load(); void load();
} }
namespace Overlay { namespace Overlay {
void load_bios_info(); void load_bios_info();
void load_controller_test(); void load_controller_test();
void load_gpu_test(); void load_gpu_test();
void load_large_gpu_test(); void load_large_gpu_test();
void load_gte_test(); void load_gte_test();
void load_font_cycler(); void load_font_cycler();
void load_screen_center(); void load_screen_center();
} }
namespace XAAudio { namespace XAAudio {
void play_mix(); void play_mix();
} }
} }

View File

@ -1,10 +1,10 @@
#pragma once #pragma once
#include "../src/include/menu.hpp" #include "../src/include/menu.hpp"
#include "../src/include/font_writer.hpp" #include "../src/include/font_writer.hpp"
#include <PSX/GPU/gpu_types.hpp> #include <PSX/GPU/gpu_types.hpp>
namespace Shared { namespace Shared {
extern Menu::BackMenu back_menu; extern Menu::BackMenu back_menu;
extern JabyEngine::GPU::POLY_G4 background; extern JabyEngine::GPU::POLY_G4 background;
extern bool load_test; extern bool load_test;
} }

View File

@ -1,13 +1,13 @@
#pragma once #pragma once
#include <PSX/File/cd_file_types.hpp> #include <PSX/File/cd_file_types.hpp>
enum struct FileType : JabyEngine::CDFileType_t { enum struct FileType : JabyEngine::CDFileType_t {
Jingle, Jingle,
}; };
struct CustomCDFileBuilder { struct CustomCDFileBuilder {
static constexpr JabyEngine::CDFile jingle(uint32_t sfx_id) { static constexpr JabyEngine::CDFile jingle(uint32_t sfx_id) {
// v we reload Paco // v we reload Paco
return JabyEngine::CDFile::custom(0, FileType::Jingle, sfx_id); return JabyEngine::CDFile::custom(0, FileType::Jingle, sfx_id);
} }
}; };

View File

@ -1,26 +1,26 @@
#include "custom_files.hpp" #include "custom_files.hpp"
#include <PSX/File/file_processor_helper.hpp> #include <PSX/File/file_processor_helper.hpp>
#include <stdio.hpp> #include <stdio.hpp>
namespace JabyEngine { namespace JabyEngine {
namespace FileProcessor { namespace FileProcessor {
struct JingleState { struct JingleState {
uint32_t sfx_id; uint32_t sfx_id;
}; };
static Progress parse_jingle(State::CDDataProcessor& data_proc, JingleState& jingle) { static Progress parse_jingle(State::CDDataProcessor& data_proc, JingleState& jingle) {
SPU::voice[jingle.sfx_id].play(); SPU::voice[jingle.sfx_id].play();
return Progress::Done; return Progress::Done;
} }
State create_custom(const uint32_t* data_adr, const CDFileType_t& file_type, const CDFile::Payload& payload) { State create_custom(const uint32_t* data_adr, const CDFileType_t& file_type, const CDFile::Payload& payload) {
switch(static_cast<FileType>(file_type)) { switch(static_cast<FileType>(file_type)) {
case FileType::Jingle: case FileType::Jingle:
return State::from(JingleState{.sfx_id = payload.raw}, data_adr, parse_jingle); return State::from(JingleState{.sfx_id = payload.raw}, data_adr, parse_jingle);
default: default:
return FileProcessor::create(data_adr, Nothing()); return FileProcessor::create(data_adr, Nothing());
} }
} }
} }
} }

View File

@ -1,148 +1,148 @@
#include "../../../include/asset_mgr.hpp" #include "../../../include/asset_mgr.hpp"
#include "../../../include/shared.hpp" #include "../../../include/shared.hpp"
#include <PSX/Auxiliary/types.hpp> #include <PSX/Auxiliary/types.hpp>
#include <PSX/Periphery/periphery.hpp> #include <PSX/Periphery/periphery.hpp>
#include <PSX/System/syscalls.hpp> #include <PSX/System/syscalls.hpp>
#include <PSX/Timer/frame_timer.hpp> #include <PSX/Timer/frame_timer.hpp>
#include <FontWriter/fonts.hpp> #include <FontWriter/fonts.hpp>
#include <string.hpp> #include <string.hpp>
namespace BIOSInfo { namespace BIOSInfo {
using namespace JabyEngine; using namespace JabyEngine;
static constexpr auto TextOffset = Make::PositionI16(16, 16); static constexpr auto TextOffset = Make::PositionI16(16, 16);
using NameColorPair = pair<const char*, GPU::Color24>; using NameColorPair = pair<const char*, GPU::Color24>;
struct FontSlider { struct FontSlider {
static constexpr auto MoveTimeout = static_cast<uint8_t>(300_ms); static constexpr auto MoveTimeout = static_cast<uint8_t>(300_ms);
static constexpr auto WaitTimeout = static_cast<uint8_t>(1000_ms); static constexpr auto WaitTimeout = static_cast<uint8_t>(1000_ms);
int16_t count; int16_t count;
int16_t max; int16_t max;
int8_t delta; int8_t delta;
IntervalTimer<uint8_t> wait_timer; IntervalTimer<uint8_t> wait_timer;
static FontSlider create_for(const FontWriter::FontInfo& font_info, const char* str) { static FontSlider create_for(const FontWriter::FontInfo& font_info, const char* str) {
const auto max = static_cast<int16_t>((strlen(str)*font_info.get_kern_size().width) - GPU::Display::Width + (TextOffset.x << 1)); const auto max = static_cast<int16_t>((strlen(str)*font_info.get_kern_size().width) - GPU::Display::Width + (TextOffset.x << 1));
return FontSlider{ return FontSlider{
.count = 0, .count = 0,
.max = max, .max = max,
.delta = static_cast<int8_t>(max < 0 ? 0 : font_info.get_kern_size().width/2), .delta = static_cast<int8_t>(max < 0 ? 0 : font_info.get_kern_size().width/2),
.wait_timer = IntervalTimer<uint8_t>::create(FontSlider::MoveTimeout) .wait_timer = IntervalTimer<uint8_t>::create(FontSlider::MoveTimeout)
}; };
} }
void advance() { void advance() {
if(this->wait_timer.is_expired()) { if(this->wait_timer.is_expired()) {
this->wait_timer.reset(); this->wait_timer.reset();
this->count += delta; this->count += delta;
if(this->count <= 0 || this->count >= this->max) { if(this->count <= 0 || this->count >= this->max) {
this->delta *= -1; this->delta *= -1;
this->wait_timer.set_interval(FontSlider::WaitTimeout); this->wait_timer.set_interval(FontSlider::WaitTimeout);
} }
else { else {
this->wait_timer.set_interval(FontSlider::MoveTimeout); this->wait_timer.set_interval(FontSlider::MoveTimeout);
} }
} }
} }
}; };
static struct { static struct {
using BIOSStringOffset = const char*const (BIOS::Version::*); using BIOSStringOffset = const char*const (BIOS::Version::*);
const BIOSStringOffset bios_str_offset; const BIOSStringOffset bios_str_offset;
const char*const display_str; const char*const display_str;
FontSlider font_slider; FontSlider font_slider;
} BIOSStringInfo[] = { } BIOSStringInfo[] = {
{.bios_str_offset = &BIOS::Version::kernel_maker, .display_str = "Kernel-Maker"}, {.bios_str_offset = &BIOS::Version::kernel_maker, .display_str = "Kernel-Maker"},
{.bios_str_offset = &BIOS::Version::version_str, .display_str = "Version"}, {.bios_str_offset = &BIOS::Version::version_str, .display_str = "Version"},
{.bios_str_offset = &BIOS::Version::gui_version, .display_str = "GUI-Version"}, {.bios_str_offset = &BIOS::Version::gui_version, .display_str = "GUI-Version"},
{.bios_str_offset = &BIOS::Version::copyright, .display_str = "Copyright"}, {.bios_str_offset = &BIOS::Version::copyright, .display_str = "Copyright"},
}; };
static GPU::TILE::Linked border_tiles[2] = { static GPU::TILE::Linked border_tiles[2] = {
Make::TILE(Make::AreaI16(0, 0, TextOffset.x, GPU::Display::Height - 32), GPU::Color24::Black()).linked(), Make::TILE(Make::AreaI16(0, 0, TextOffset.x, GPU::Display::Height - 32), GPU::Color24::Black()).linked(),
Make::TILE(Make::AreaI16(GPU::Display::Width - TextOffset.x, 0, TextOffset.x, GPU::Display::Height - 32), GPU::Color24::Black()).linked() Make::TILE(Make::AreaI16(GPU::Display::Width - TextOffset.x, 0, TextOffset.x, GPU::Display::Height - 32), GPU::Color24::Black()).linked()
}; };
static NameColorPair bios_name; static NameColorPair bios_name;
static FontSlider bios_name_slider; static FontSlider bios_name_slider;
static NameColorPair get_bios_name() { static NameColorPair get_bios_name() {
switch(BIOS::version.type) { switch(BIOS::version.type) {
case BIOS::Version::Devboard: case BIOS::Version::Devboard:
return {"DevBoard", GPU::Color24::Green()}; return {"DevBoard", GPU::Color24::Green()};
case BIOS::Version::PS1: case BIOS::Version::PS1:
return {"PS1", GPU::Color24::Red()}; return {"PS1", GPU::Color24::Red()};
case BIOS::Version::PS2: case BIOS::Version::PS2:
return {"PS2", GPU::Color24::Blue()}; return {"PS2", GPU::Color24::Blue()};
case BIOS::Version::PS3: case BIOS::Version::PS3:
return {"PS3", GPU::Color24::Yellow()}; return {"PS3", GPU::Color24::Yellow()};
case BIOS::Version::PSCompatible: case BIOS::Version::PSCompatible:
return {"Unkown PS compatible BIOS", GPU::Color24::Grey()}; return {"Unkown PS compatible BIOS", GPU::Color24::Grey()};
case BIOS::Version::No$psx: case BIOS::Version::No$psx:
return {"NO$PSX", GPU::Color24::Purple()}; return {"NO$PSX", GPU::Color24::Purple()};
case BIOS::Version::XEBRA: case BIOS::Version::XEBRA:
return {"XEBRA", GPU::Color24::Turquoise()}; return {"XEBRA", GPU::Color24::Turquoise()};
default: default:
return {"Unkown", GPU::Color24::White()}; return {"Unkown", GPU::Color24::White()};
} }
} }
static void setup() { static void setup() {
bios_name = get_bios_name(); bios_name = get_bios_name();
Shared::back_menu.reset(); Shared::back_menu.reset();
for(auto& bios_str_info : BIOSStringInfo) { for(auto& bios_str_info : BIOSStringInfo) {
bios_str_info.font_slider = FontSlider::create_for(FontWriter::BIOSFont::Info, BIOS::version.*(bios_str_info.bios_str_offset)); bios_str_info.font_slider = FontSlider::create_for(FontWriter::BIOSFont::Info, BIOS::version.*(bios_str_info.bios_str_offset));
} }
bios_name_slider = FontSlider::create_for(FontWriter::BIOSFont::Info, bios_name.first); bios_name_slider = FontSlider::create_for(FontWriter::BIOSFont::Info, bios_name.first);
border_tiles[0].concat(border_tiles[1]); border_tiles[0].concat(border_tiles[1]);
} }
static bool update_or_exit() { static bool update_or_exit() {
static const auto move_cursor = [](JabyEngine::Cursor& cursor, int16_t dx, int16_t old_x) -> JabyEngine::Cursor& { static const auto move_cursor = [](JabyEngine::Cursor& cursor, int16_t dx, int16_t old_x) -> JabyEngine::Cursor& {
cursor.pos.x = (old_x - dx); cursor.pos.x = (old_x - dx);
return cursor; return cursor;
}; };
Periphery::query_controller(); Periphery::query_controller();
if(Shared::back_menu.update(Make::PositionI16(0, GPU::Display::Height - 32))) { if(Shared::back_menu.update(Make::PositionI16(0, GPU::Display::Height - 32))) {
return true; return true;
} }
auto cursor = FontWriter::update(TextOffset); auto cursor = FontWriter::update(TextOffset);
FontWriter::bios_font_writer.write(cursor, "BIOS INFORMATION\n----------------\nDate (day/month/year):\n%i/%i/%i\n", BIOS::version.date.day, BIOS::version.date.month, BIOS::version.date.year); FontWriter::bios_font_writer.write(cursor, "BIOS INFORMATION\n----------------\nDate (day/month/year):\n%i/%i/%i\n", BIOS::version.date.day, BIOS::version.date.month, BIOS::version.date.year);
const auto old_pos_x = cursor.pos.x; const auto old_pos_x = cursor.pos.x;
for(auto& bios_str_info : BIOSStringInfo) { for(auto& bios_str_info : BIOSStringInfo) {
bios_str_info.font_slider.advance(); bios_str_info.font_slider.advance();
FontWriter::bios_font_writer.write(move_cursor(cursor, 0, old_pos_x), "%s:\n", bios_str_info.display_str); FontWriter::bios_font_writer.write(move_cursor(cursor, 0, old_pos_x), "%s:\n", bios_str_info.display_str);
FontWriter::bios_font_writer.write(move_cursor(cursor, bios_str_info.font_slider.count, old_pos_x), "%s\n", BIOS::version.*(bios_str_info.bios_str_offset)); FontWriter::bios_font_writer.write(move_cursor(cursor, bios_str_info.font_slider.count, old_pos_x), "%s\n", BIOS::version.*(bios_str_info.bios_str_offset));
} }
FontWriter::bios_font_writer.write(move_cursor(cursor, 0, old_pos_x), "BIOS Type:\n"); FontWriter::bios_font_writer.write(move_cursor(cursor, 0, old_pos_x), "BIOS Type:\n");
FontWriter::bios_font_writer.write(move_cursor(cursor, bios_name_slider.count, old_pos_x), "%s\n", bios_name.second, bios_name.first); FontWriter::bios_font_writer.write(move_cursor(cursor, bios_name_slider.count, old_pos_x), "%s\n", bios_name.second, bios_name.first);
FontWriter::bios_font_writer.write(move_cursor(cursor, 0, old_pos_x), "----------------\n"); FontWriter::bios_font_writer.write(move_cursor(cursor, 0, old_pos_x), "----------------\n");
return false; return false;
} }
static void render() { static void render() {
Shared::back_menu.render(); Shared::back_menu.render();
FontWriter::bios_font_writer.render(); FontWriter::bios_font_writer.render();
GPU::render(border_tiles[0]); GPU::render(border_tiles[0]);
} }
void main() { void main() {
setup(); setup();
while(true) { while(true) {
if(update_or_exit()) { if(update_or_exit()) {
break; break;
} }
GPU::swap_buffers_vsync(1); GPU::swap_buffers_vsync(1);
render(); render();
} }
} }
} }

View File

@ -1,110 +1,110 @@
#include "include/controller_state.hpp" #include "include/controller_state.hpp"
#include <PSX/GPU/gpu.hpp> #include <PSX/GPU/gpu.hpp>
#include <PSX/SPU/spu.hpp> #include <PSX/SPU/spu.hpp>
namespace ControllerTest { namespace ControllerTest {
using DigitalButton = Periphery::AnalogeController::Button; using DigitalButton = Periphery::AnalogeController::Button;
using namespace JabyEngine; using namespace JabyEngine;
static void set_active(GPU::SPRT_16::Linked& sprt, bool is_active) { static void set_active(GPU::SPRT_16::Linked& sprt, bool is_active) {
sprt->tex_offset.y = is_active ? 16 : 0; sprt->tex_offset.y = is_active ? 16 : 0;
if(is_active) { if(is_active) {
SPU::voice[1].play_if_end(); SPU::voice[1].play_if_end();
} }
} }
static void set_active(GPU::POLY_FT4::Linked& poly, bool is_active) { static void set_active(GPU::POLY_FT4::Linked& poly, bool is_active) {
poly->tex_offset0.y = is_active ? 16 : 0; poly->tex_offset0.y = is_active ? 16 : 0;
poly->tex_offset1.y = is_active ? 16 : 0; poly->tex_offset1.y = is_active ? 16 : 0;
poly->tex_offset2.y = is_active ? 32 : 16; poly->tex_offset2.y = is_active ? 32 : 16;
poly->tex_offset3.y = is_active ? 32 : 16; poly->tex_offset3.y = is_active ? 32 : 16;
if(is_active) { if(is_active) {
SPU::voice[1].play_if_end(); SPU::voice[1].play_if_end();
} }
} }
static const char* get_type_name(Periphery::ControllerType type) { static const char* get_type_name(Periphery::ControllerType type) {
switch(type) { switch(type) {
case Periphery::ControllerType::Unkown: case Periphery::ControllerType::Unkown:
return "Unkown"; return "Unkown";
case Periphery::ControllerType::Mouse: case Periphery::ControllerType::Mouse:
return "Mouse"; return "Mouse";
case Periphery::ControllerType::NegCon: case Periphery::ControllerType::NegCon:
return "NegCon"; return "NegCon";
case Periphery::ControllerType::HyperBlaster: case Periphery::ControllerType::HyperBlaster:
return "HyperBlaster"; return "HyperBlaster";
case Periphery::ControllerType::Controller: case Periphery::ControllerType::Controller:
return "Digital Controller"; return "Digital Controller";
case Periphery::ControllerType::ArcadeFlightStick: case Periphery::ControllerType::ArcadeFlightStick:
return "Flight Stick"; return "Flight Stick";
case Periphery::ControllerType::GCon: case Periphery::ControllerType::GCon:
return "GCon"; return "GCon";
case Periphery::ControllerType::DualShock: case Periphery::ControllerType::DualShock:
return "DualShock"; return "DualShock";
case Periphery::ControllerType::MultiTap: case Periphery::ControllerType::MultiTap:
return "MultiTap"; return "MultiTap";
default: default:
return "???"; return "???";
} }
} }
void ControllerState :: setup() { void ControllerState :: setup() {
for(size_t n = 0; n < 2; n++) { for(size_t n = 0; n < 2; n++) {
GPU::LinkHelper::link_array(GPU::LinkHelper::link_array(&this->tex_page[n], this->buttons[n]), this->arrows[n]); GPU::LinkHelper::link_array(GPU::LinkHelper::link_array(&this->tex_page[n], this->buttons[n]), this->arrows[n]);
} }
} }
void ControllerState :: update(const Periphery::AnalogeController* controller, JabyEngine::FontWriter& font_writer) { void ControllerState :: update(const Periphery::AnalogeController* controller, JabyEngine::FontWriter& font_writer) {
static const DigitalButton ButtonSprtMap[] = { static const DigitalButton ButtonSprtMap[] = {
DigitalButton::Triangle, DigitalButton::Circle, DigitalButton::Cross, DigitalButton::Square, DigitalButton::Triangle, DigitalButton::Circle, DigitalButton::Cross, DigitalButton::Square,
DigitalButton::ST, DigitalButton::SEL, DigitalButton::L1, DigitalButton::L2, DigitalButton::R1, DigitalButton::R2, DigitalButton::ST, DigitalButton::SEL, DigitalButton::L1, DigitalButton::L2, DigitalButton::R1, DigitalButton::R2,
DigitalButton::L3, DigitalButton::R3 DigitalButton::L3, DigitalButton::R3
}; };
static const DigitalButton ArrowPolyMap[] = { static const DigitalButton ArrowPolyMap[] = {
DigitalButton::Up, DigitalButton::Right, DigitalButton::Down, DigitalButton::Left DigitalButton::Up, DigitalButton::Right, DigitalButton::Down, DigitalButton::Left
}; };
auto& cur_button_sprts = this->buttons[GPU::update_id()]; auto& cur_button_sprts = this->buttons[GPU::update_id()];
auto& cur_arrow_poly = this->arrows[GPU::update_id()]; auto& cur_arrow_poly = this->arrows[GPU::update_id()];
if(controller) { if(controller) {
for(size_t n = 0; n < sizeof(ButtonSprtMap)/sizeof(ButtonSprtMap[0]); n++) { for(size_t n = 0; n < sizeof(ButtonSprtMap)/sizeof(ButtonSprtMap[0]); n++) {
set_active(cur_button_sprts[n], controller->button.is_down(ButtonSprtMap[n])); set_active(cur_button_sprts[n], controller->button.is_down(ButtonSprtMap[n]));
} }
for(size_t n = 0; n < sizeof(ArrowPolyMap)/sizeof(ArrowPolyMap[0]); n++) { for(size_t n = 0; n < sizeof(ArrowPolyMap)/sizeof(ArrowPolyMap[0]); n++) {
set_active(cur_arrow_poly[n], controller->button.is_down(ArrowPolyMap[n])); set_active(cur_arrow_poly[n], controller->button.is_down(ArrowPolyMap[n]));
} }
set_active(cur_button_sprts[12], controller->header.state == Periphery::RawController::State::Disconnected); set_active(cur_button_sprts[12], controller->header.state == Periphery::RawController::State::Disconnected);
// Text stuff down here // Text stuff down here
const auto offset_point = cur_button_sprts[1]->position; const auto offset_point = cur_button_sprts[1]->position;
const auto left_stick = controller->get_left_stick_pos(); const auto left_stick = controller->get_left_stick_pos();
const auto right_stick = controller->get_right_stick_pos(); const auto right_stick = controller->get_right_stick_pos();
auto cursor = Cursor::create(offset_point.move(16, 0), 0); auto cursor = Cursor::create(offset_point.move(16, 0), 0);
font_writer.write(cursor, "Right: %i, %i\nLeft : %i, %i\n", right_stick.x, right_stick.y, left_stick.x, left_stick.y); font_writer.write(cursor, "Right: %i, %i\nLeft : %i, %i\n", right_stick.x, right_stick.y, left_stick.x, left_stick.y);
font_writer.write(cursor, "[%s]", get_type_name(static_cast<Periphery::ControllerType>(controller->get_type()))); font_writer.write(cursor, "[%s]", get_type_name(static_cast<Periphery::ControllerType>(controller->get_type())));
} }
else { else {
auto cursor = Cursor::create(Make::PositionI16(cur_arrow_poly[3]->vertex0.x, cur_button_sprts[0]->position.y), 0); auto cursor = Cursor::create(Make::PositionI16(cur_arrow_poly[3]->vertex0.x, cur_button_sprts[0]->position.y), 0);
font_writer.write(cursor, "!!This Port is not\nenabled in JabyEngine!!", GPU::Color24::Red()); font_writer.write(cursor, "!!This Port is not\nenabled in JabyEngine!!", GPU::Color24::Red());
this->tex_page[GPU::update_id()].terminate(); this->tex_page[GPU::update_id()].terminate();
} }
} }
void ControllerState :: render() { void ControllerState :: render() {
GPU::render(this->tex_page[GPU::render_id()]); GPU::render(this->tex_page[GPU::render_id()]);
} }
} }

View File

@ -1,47 +1,47 @@
#include "../../../include/shared.hpp" #include "../../../include/shared.hpp"
#include "include/controller_state.hpp" #include "include/controller_state.hpp"
#include <PSX/Periphery/periphery.hpp> #include <PSX/Periphery/periphery.hpp>
namespace ControllerTest { namespace ControllerTest {
using namespace JabyEngine; using namespace JabyEngine;
static auto controller_state0 = ControllerState::create(Make::PositionI16(0, 0)); static auto controller_state0 = ControllerState::create(Make::PositionI16(0, 0));
static auto controller_state1 = ControllerState::create(Make::PositionI16(0, 76)); static auto controller_state1 = ControllerState::create(Make::PositionI16(0, 76));
static void setup() { static void setup() {
Shared::back_menu.reset(); Shared::back_menu.reset();
controller_state0.setup(); controller_state0.setup();
controller_state1.setup(); controller_state1.setup();
} }
static bool update_or_exit() { static bool update_or_exit() {
Periphery::query_controller(); Periphery::query_controller();
if(Shared::back_menu.update(Make::PositionI16(0, GPU::Display::Height - 32))) { if(Shared::back_menu.update(Make::PositionI16(0, GPU::Display::Height - 32))) {
return true; return true;
} }
controller_state0.update(&Periphery::get_primary_controller_as<JabyEngine::Periphery::AnalogeController>(), FontWriter::bios_font_writer); controller_state0.update(&Periphery::get_primary_controller_as<JabyEngine::Periphery::AnalogeController>(), FontWriter::bios_font_writer);
controller_state1.update(Periphery::PortCount > 1 ? &Periphery::get_controller_as<JabyEngine::Periphery::AnalogeController>(1, 0) : nullptr, FontWriter::bios_font_writer); controller_state1.update(Periphery::PortCount > 1 ? &Periphery::get_controller_as<JabyEngine::Periphery::AnalogeController>(1, 0) : nullptr, FontWriter::bios_font_writer);
return false; return false;
} }
static void render() { static void render() {
GPU::render(Shared::background); GPU::render(Shared::background);
controller_state0.render(); controller_state0.render();
controller_state1.render(); controller_state1.render();
FontWriter::bios_font_writer.render(); FontWriter::bios_font_writer.render();
Shared::back_menu.render(); Shared::back_menu.render();
} }
void main() { void main() {
setup(); setup();
while(true) { while(true) {
if(update_or_exit()) { if(update_or_exit()) {
break; break;
} }
GPU::swap_buffers_vsync(1); GPU::swap_buffers_vsync(1);
render(); render();
} }
} }
} }

View File

@ -1,18 +1,18 @@
#include "include/controller_test_assets.hpp" #include "include/controller_test_assets.hpp"
#include <PSX/File/Processor/cd_file_processor.hpp> #include <PSX/File/Processor/cd_file_processor.hpp>
#include <PSX/AutoLBA/auto_lba_declaration.hpp> #include <PSX/AutoLBA/auto_lba_declaration.hpp>
namespace ControllerTest { namespace ControllerTest {
using namespace JabyEngine; using namespace JabyEngine;
enum LBA { enum LBA {
__jabyengine_start_lba_request __jabyengine_start_lba_request
__jabyengine_request_lba_for(CONT, "ASSETS/CONT/CONT.IMG"), __jabyengine_request_lba_for(CONT, "ASSETS/CONT/CONT.IMG"),
__jabyengine_end_lba_request __jabyengine_end_lba_request
}; };
__declare_lba_header(LBA); __declare_lba_header(LBA);
CDFile Assets[1] = { CDFile Assets[1] = {
CDFileBuilder::simple_tim(LBA::CONT, ControllerButtonTIM), CDFileBuilder::simple_tim(LBA::CONT, ControllerButtonTIM),
}; };
} }

View File

@ -1,67 +1,67 @@
#pragma once #pragma once
#include "controller_test_assets.hpp" #include "controller_test_assets.hpp"
#include <FontWriter/font_writer.hpp> #include <FontWriter/font_writer.hpp>
#include <PSX/GPU/make_gpu_primitives.hpp> #include <PSX/GPU/make_gpu_primitives.hpp>
#include <PSX/Periphery/controller.hpp> #include <PSX/Periphery/controller.hpp>
namespace ControllerTest { namespace ControllerTest {
using namespace JabyEngine; using namespace JabyEngine;
class ControllerState { class ControllerState {
private: private:
GPU::TexPage::Linked tex_page[2]; GPU::TexPage::Linked tex_page[2];
GPU::SPRT_16::Linked buttons[2][13]; GPU::SPRT_16::Linked buttons[2][13];
GPU::POLY_FT4::Linked arrows[2][4]; GPU::POLY_FT4::Linked arrows[2][4];
public: public:
static constexpr ControllerState create(GPU::PositionI16 offset = Make::PositionI16(0, 0)) { static constexpr ControllerState create(GPU::PositionI16 offset = Make::PositionI16(0, 0)) {
ControllerState state; ControllerState state;
for(auto& tex_page : state.tex_page) { for(auto& tex_page : state.tex_page) {
tex_page = Make::TexPage(ControllerButtonTIM.get_texture_position(), GPU::TextureColorMode::clut4).linked(); tex_page = Make::TexPage(ControllerButtonTIM.get_texture_position(), GPU::TextureColorMode::clut4).linked();
} }
for(auto& buttons : state.buttons) { for(auto& buttons : state.buttons) {
// Triangle // Triangle
buttons[0] = Make::SPRT_16(Make::Vertex(71, 0).move(offset.x, offset.y), Make::OffsetPageWithClut(GPU::PageOffset::from_tile_id16(0, Make::SizeI16(16, 16)), Make::PageClut(ControllerButtonTIM.get_clut_position()))).linked(); buttons[0] = Make::SPRT_16(Make::Vertex(71, 0).move(offset.x, offset.y), Make::OffsetPageWithClut(GPU::PageOffset::from_tile_id16(0, Make::SizeI16(16, 16)), Make::PageClut(ControllerButtonTIM.get_clut_position()))).linked();
// Circle // Circle
buttons[1] = Make::SPRT_16(Make::Vertex(82, 12).move(offset.x, offset.y), Make::OffsetPageWithClut(GPU::PageOffset::from_tile_id16(1, Make::SizeI16(16, 16)), Make::PageClut(ControllerButtonTIM.get_clut_position()))).linked(); buttons[1] = Make::SPRT_16(Make::Vertex(82, 12).move(offset.x, offset.y), Make::OffsetPageWithClut(GPU::PageOffset::from_tile_id16(1, Make::SizeI16(16, 16)), Make::PageClut(ControllerButtonTIM.get_clut_position()))).linked();
// Cross // Cross
buttons[2] = Make::SPRT_16(Make::Vertex(71, 23).move(offset.x, offset.y), Make::OffsetPageWithClut(GPU::PageOffset::from_tile_id16(2, Make::SizeI16(16, 16)), Make::PageClut(ControllerButtonTIM.get_clut_position()))).linked(); buttons[2] = Make::SPRT_16(Make::Vertex(71, 23).move(offset.x, offset.y), Make::OffsetPageWithClut(GPU::PageOffset::from_tile_id16(2, Make::SizeI16(16, 16)), Make::PageClut(ControllerButtonTIM.get_clut_position()))).linked();
// Square // Square
buttons[3] = Make::SPRT_16(Make::Vertex(60, 11).move(offset.x, offset.y), Make::OffsetPageWithClut(GPU::PageOffset::from_tile_id16(3, Make::SizeI16(16, 16)), Make::PageClut(ControllerButtonTIM.get_clut_position()))).linked(); buttons[3] = Make::SPRT_16(Make::Vertex(60, 11).move(offset.x, offset.y), Make::OffsetPageWithClut(GPU::PageOffset::from_tile_id16(3, Make::SizeI16(16, 16)), Make::PageClut(ControllerButtonTIM.get_clut_position()))).linked();
// Play // Play
buttons[4] = Make::SPRT_16(Make::Vertex(51, 21).move(offset.x, offset.y), Make::OffsetPageWithClut(GPU::PageOffset::from_tile_id16(4, Make::SizeI16(16, 16)), Make::PageClut(ControllerButtonTIM.get_clut_position()))).linked(); buttons[4] = Make::SPRT_16(Make::Vertex(51, 21).move(offset.x, offset.y), Make::OffsetPageWithClut(GPU::PageOffset::from_tile_id16(4, Make::SizeI16(16, 16)), Make::PageClut(ControllerButtonTIM.get_clut_position()))).linked();
// Block // Block
buttons[5] = Make::SPRT_16(Make::Vertex(24, 21).move(offset.x, offset.y), Make::OffsetPageWithClut(GPU::PageOffset::from_tile_id16(5, Make::SizeI16(16, 16)), Make::PageClut(ControllerButtonTIM.get_clut_position()))).linked(); buttons[5] = Make::SPRT_16(Make::Vertex(24, 21).move(offset.x, offset.y), Make::OffsetPageWithClut(GPU::PageOffset::from_tile_id16(5, Make::SizeI16(16, 16)), Make::PageClut(ControllerButtonTIM.get_clut_position()))).linked();
// L1 // L1
buttons[6] = Make::SPRT_16(Make::Vertex(7, 39).move(offset.x, offset.y), Make::OffsetPageWithClut(GPU::PageOffset::from_tile_id16(7, Make::SizeI16(16, 16)), Make::PageClut(ControllerButtonTIM.get_clut_position()))).linked(); buttons[6] = Make::SPRT_16(Make::Vertex(7, 39).move(offset.x, offset.y), Make::OffsetPageWithClut(GPU::PageOffset::from_tile_id16(7, Make::SizeI16(16, 16)), Make::PageClut(ControllerButtonTIM.get_clut_position()))).linked();
// L2 // L2
buttons[7] = Make::SPRT_16(Make::Vertex(7, 49).move(offset.x, offset.y), Make::OffsetPageWithClut(GPU::PageOffset::from_tile_id16(8, Make::SizeI16(16, 16)), Make::PageClut(ControllerButtonTIM.get_clut_position()))).linked(); buttons[7] = Make::SPRT_16(Make::Vertex(7, 49).move(offset.x, offset.y), Make::OffsetPageWithClut(GPU::PageOffset::from_tile_id16(8, Make::SizeI16(16, 16)), Make::PageClut(ControllerButtonTIM.get_clut_position()))).linked();
// R1 // R1
buttons[8] = Make::SPRT_16(Make::Vertex(71, 39).move(offset.x, offset.y), Make::OffsetPageWithClut(GPU::PageOffset::from_tile_id16(7, Make::SizeI16(16, 16)), Make::PageClut(ControllerButtonTIM.get_clut_position()))).linked(); buttons[8] = Make::SPRT_16(Make::Vertex(71, 39).move(offset.x, offset.y), Make::OffsetPageWithClut(GPU::PageOffset::from_tile_id16(7, Make::SizeI16(16, 16)), Make::PageClut(ControllerButtonTIM.get_clut_position()))).linked();
// R2 // R2
buttons[9] = Make::SPRT_16(Make::Vertex(71, 49).move(offset.x, offset.y), Make::OffsetPageWithClut(GPU::PageOffset::from_tile_id16(8, Make::SizeI16(16, 16)), Make::PageClut(ControllerButtonTIM.get_clut_position()))).linked(); buttons[9] = Make::SPRT_16(Make::Vertex(71, 49).move(offset.x, offset.y), Make::OffsetPageWithClut(GPU::PageOffset::from_tile_id16(8, Make::SizeI16(16, 16)), Make::PageClut(ControllerButtonTIM.get_clut_position()))).linked();
// L3 // L3
buttons[10] = Make::SPRT_16(Make::Vertex(24, 34).move(offset.x, offset.y), Make::OffsetPageWithClut(GPU::PageOffset::from_tile_id16(9, Make::SizeI16(16, 16)), Make::PageClut(ControllerButtonTIM.get_clut_position()))).linked(); buttons[10] = Make::SPRT_16(Make::Vertex(24, 34).move(offset.x, offset.y), Make::OffsetPageWithClut(GPU::PageOffset::from_tile_id16(9, Make::SizeI16(16, 16)), Make::PageClut(ControllerButtonTIM.get_clut_position()))).linked();
// R3 // R3
buttons[11] = Make::SPRT_16(Make::Vertex(52, 34).move(offset.x, offset.y), Make::OffsetPageWithClut(GPU::PageOffset::from_tile_id16(9, Make::SizeI16(16, 16)), Make::PageClut(ControllerButtonTIM.get_clut_position()))).linked(); buttons[11] = Make::SPRT_16(Make::Vertex(52, 34).move(offset.x, offset.y), Make::OffsetPageWithClut(GPU::PageOffset::from_tile_id16(9, Make::SizeI16(16, 16)), Make::PageClut(ControllerButtonTIM.get_clut_position()))).linked();
// Connection Symbol // Connection Symbol
buttons[12] = Make::SPRT_16(Make::Vertex(37, 9).move(offset.x, offset.y), Make::OffsetPageWithClut(GPU::PageOffset::from_tile_id16(10, Make::SizeI16(16, 16)), Make::PageClut(ControllerButtonTIM.get_clut_position()))).linked(); buttons[12] = Make::SPRT_16(Make::Vertex(37, 9).move(offset.x, offset.y), Make::OffsetPageWithClut(GPU::PageOffset::from_tile_id16(10, Make::SizeI16(16, 16)), Make::PageClut(ControllerButtonTIM.get_clut_position()))).linked();
} }
for(auto& arrows : state.arrows) { for(auto& arrows : state.arrows) {
arrows[0] = Make::POLY_FT4(__jabyengine_polyFT4_vertex_rect( Make::AreaI16(Make::PositionI16( 7, 5).move(offset.x, offset.y), Make::SizeI16(16, 16)), Make::PositionI16(6*16, 0)), Make::TPage(ControllerButtonTIM.get_texture_position(), GPU::SemiTransparency::B_Half_add_F_Half, GPU::TextureColorMode::clut4), Make::PageClut(ControllerButtonTIM.get_clut_position())).linked(); arrows[0] = Make::POLY_FT4(__jabyengine_polyFT4_vertex_rect( Make::AreaI16(Make::PositionI16( 7, 5).move(offset.x, offset.y), Make::SizeI16(16, 16)), Make::PositionI16(6*16, 0)), Make::TPage(ControllerButtonTIM.get_texture_position(), GPU::SemiTransparency::B_Half_add_F_Half, GPU::TextureColorMode::clut4), Make::PageClut(ControllerButtonTIM.get_clut_position())).linked();
arrows[1] = Make::POLY_FT4(__jabyengine_polyFT4_vertex_rect270(Make::AreaI16(Make::PositionI16(14, 11).move(offset.x, offset.y), Make::SizeI16(16, 16)), Make::PositionI16(6*16, 0)), Make::TPage(ControllerButtonTIM.get_texture_position(), GPU::SemiTransparency::B_Half_add_F_Half, GPU::TextureColorMode::clut4), Make::PageClut(ControllerButtonTIM.get_clut_position())).linked(); arrows[1] = Make::POLY_FT4(__jabyengine_polyFT4_vertex_rect270(Make::AreaI16(Make::PositionI16(14, 11).move(offset.x, offset.y), Make::SizeI16(16, 16)), Make::PositionI16(6*16, 0)), Make::TPage(ControllerButtonTIM.get_texture_position(), GPU::SemiTransparency::B_Half_add_F_Half, GPU::TextureColorMode::clut4), Make::PageClut(ControllerButtonTIM.get_clut_position())).linked();
arrows[2] = Make::POLY_FT4(__jabyengine_polyFT4_vertex_rect180(Make::AreaI16(Make::PositionI16( 7, 17).move(offset.x, offset.y), Make::SizeI16(16, 16)), Make::PositionI16(6*16, 0)), Make::TPage(ControllerButtonTIM.get_texture_position(), GPU::SemiTransparency::B_Half_add_F_Half, GPU::TextureColorMode::clut4), Make::PageClut(ControllerButtonTIM.get_clut_position())).linked(); arrows[2] = Make::POLY_FT4(__jabyengine_polyFT4_vertex_rect180(Make::AreaI16(Make::PositionI16( 7, 17).move(offset.x, offset.y), Make::SizeI16(16, 16)), Make::PositionI16(6*16, 0)), Make::TPage(ControllerButtonTIM.get_texture_position(), GPU::SemiTransparency::B_Half_add_F_Half, GPU::TextureColorMode::clut4), Make::PageClut(ControllerButtonTIM.get_clut_position())).linked();
arrows[3] = Make::POLY_FT4(__jabyengine_polyFT4_vertex_rect90( Make::AreaI16(Make::PositionI16( 0, 11).move(offset.x, offset.y), Make::SizeI16(16, 16)), Make::PositionI16(6*16, 0)), Make::TPage(ControllerButtonTIM.get_texture_position(), GPU::SemiTransparency::B_Half_add_F_Half, GPU::TextureColorMode::clut4), Make::PageClut(ControllerButtonTIM.get_clut_position())).linked(); arrows[3] = Make::POLY_FT4(__jabyengine_polyFT4_vertex_rect90( Make::AreaI16(Make::PositionI16( 0, 11).move(offset.x, offset.y), Make::SizeI16(16, 16)), Make::PositionI16(6*16, 0)), Make::TPage(ControllerButtonTIM.get_texture_position(), GPU::SemiTransparency::B_Half_add_F_Half, GPU::TextureColorMode::clut4), Make::PageClut(ControllerButtonTIM.get_clut_position())).linked();
} }
return state; return state;
} }
void setup(); void setup();
void update(const Periphery::AnalogeController* controller, JabyEngine::FontWriter& font_writer); void update(const Periphery::AnalogeController* controller, JabyEngine::FontWriter& font_writer);
void render(); void render();
}; };
} }

View File

@ -1,8 +1,8 @@
#pragma once #pragma once
#include <PSX/File/cd_file_types.hpp> #include <PSX/File/cd_file_types.hpp>
namespace ControllerTest { namespace ControllerTest {
using namespace JabyEngine; using namespace JabyEngine;
static constexpr auto ControllerButtonTIM = SimpleTIM::create(384, 0, 384, 511); static constexpr auto ControllerButtonTIM = SimpleTIM::create(384, 0, 384, 511);
} }

View File

@ -1,78 +1,78 @@
#include "../../../include/shared.hpp" #include "../../../include/shared.hpp"
#include <PSX/GPU/gpu.hpp> #include <PSX/GPU/gpu.hpp>
#include <PSX/Periphery/periphery.hpp> #include <PSX/Periphery/periphery.hpp>
namespace FontCycler { namespace FontCycler {
using namespace JabyEngine; using namespace JabyEngine;
static const char*const ASCII = "!\"#$%&'()*+,-./0\n123456789:;<=>?@\nABCDEFGHIJKLMNOP\nQRSTUVWXYZ[\\]^_`\nabcdefghijklmnop\nqrstuvwxyz{|}~\n"; static const char*const ASCII = "!\"#$%&'()*+,-./0\n123456789:;<=>?@\nABCDEFGHIJKLMNOP\nQRSTUVWXYZ[\\]^_`\nabcdefghijklmnop\nqrstuvwxyz{|}~\n";
static JabyEngine::FontWriter*const FontWriters[] = { static JabyEngine::FontWriter*const FontWriters[] = {
&FontWriter::bios_font_writer, &FontWriter::bios_font_writer,
&FontWriter::new_font_writer, &FontWriter::new_font_writer,
}; };
static constexpr auto MaxFontSelector = (sizeof(FontWriters)/sizeof(FontWriters[0])) - 1; static constexpr auto MaxFontSelector = (sizeof(FontWriters)/sizeof(FontWriters[0])) - 1;
static uint8_t font_selector = 0; static uint8_t font_selector = 0;
static void increment_font_selector() { static void increment_font_selector() {
if(font_selector == MaxFontSelector) { if(font_selector == MaxFontSelector) {
font_selector = 0; font_selector = 0;
} }
else { else {
font_selector++; font_selector++;
} }
} }
static void decrement_font_selector() { static void decrement_font_selector() {
if(font_selector == 0) { if(font_selector == 0) {
font_selector = MaxFontSelector; font_selector = MaxFontSelector;
} }
else { else {
font_selector--; font_selector--;
} }
} }
static void setup() { static void setup() {
Shared::back_menu.reset(); Shared::back_menu.reset();
font_selector = 0; font_selector = 0;
} }
static bool update_or_exit() { static bool update_or_exit() {
Periphery::query_controller(); Periphery::query_controller();
if(Shared::back_menu.update(Make::PositionI16(0, GPU::Display::Height - 32))) { if(Shared::back_menu.update(Make::PositionI16(0, GPU::Display::Height - 32))) {
return true; return true;
} }
const auto& controller = Periphery::get_primary_controller_as<Periphery::GenericController>(); const auto& controller = Periphery::get_primary_controller_as<Periphery::GenericController>();
if(controller.button.went_up(Periphery::GenericController::Button::L1)) { if(controller.button.went_up(Periphery::GenericController::Button::L1)) {
decrement_font_selector(); decrement_font_selector();
} }
if(controller.button.went_up(Periphery::GenericController::Button::R1)) { if(controller.button.went_up(Periphery::GenericController::Button::R1)) {
increment_font_selector(); increment_font_selector();
} }
auto cursor = FontWriter::update(Make::PositionI16(8, 8)); auto cursor = FontWriter::update(Make::PositionI16(8, 8));
FontWriters[font_selector]->write(cursor, ASCII); FontWriters[font_selector]->write(cursor, ASCII);
FontWriters[font_selector]->write(cursor, "\nPress L1 or R1 to cycle\nthrough fonts"); FontWriters[font_selector]->write(cursor, "\nPress L1 or R1 to cycle\nthrough fonts");
return false; return false;
} }
static void render() { static void render() {
FontWriters[font_selector]->render(); FontWriters[font_selector]->render();
Shared::back_menu.render(); Shared::back_menu.render();
} }
void main() { void main() {
setup(); setup();
while(true) { while(true) {
if(update_or_exit()) { if(update_or_exit()) {
break; break;
} }
GPU::swap_buffers_vsync(1); GPU::swap_buffers_vsync(1);
render(); render();
} }
} }
} }

View File

@ -1,174 +1,174 @@
#include "../../../include/shared.hpp" #include "../../../include/shared.hpp"
#include "include/gpu_test_assets.hpp" #include "include/gpu_test_assets.hpp"
#include <PSX/GPU/gpu.hpp> #include <PSX/GPU/gpu.hpp>
#include <PSX/GPU/make_gpu_primitives.hpp> #include <PSX/GPU/make_gpu_primitives.hpp>
#include <PSX/Periphery/periphery.hpp> #include <PSX/Periphery/periphery.hpp>
#include <PSX/Timer/high_res_timer.hpp> #include <PSX/Timer/high_res_timer.hpp>
namespace GPUTest { namespace GPUTest {
using namespace JabyEngine; using namespace JabyEngine;
// Some default values for the objects // Some default values for the objects
static constexpr auto TriangleColor = GPU::Color24::from_rgb(0x0, 0xFF, 0xFF); static constexpr auto TriangleColor = GPU::Color24::from_rgb(0x0, 0xFF, 0xFF);
static constexpr auto TriangleArea = Make::AreaI16(Make::PositionI16(0, 0), Make::SizeI16(64, 64)); static constexpr auto TriangleArea = Make::AreaI16(Make::PositionI16(0, 0), Make::SizeI16(64, 64));
static constexpr auto TriangleTPage = Make::TPage(TexPageTIM.get_texture_position(), GPU::SemiTransparency::B_Half_add_F_Half, GPU::TextureColorMode::clut4); static constexpr auto TriangleTPage = Make::TPage(TexPageTIM.get_texture_position(), GPU::SemiTransparency::B_Half_add_F_Half, GPU::TextureColorMode::clut4);
static constexpr auto TriangleClut = Make::PageClut(TexPageTIM.get_clut_position()); static constexpr auto TriangleClut = Make::PageClut(TexPageTIM.get_clut_position());
static constexpr auto RectangleColor = GPU::Color24::from_rgb(0x80, 0x80, 0xFF); static constexpr auto RectangleColor = GPU::Color24::from_rgb(0x80, 0x80, 0xFF);
static constexpr auto RectangleArea = Make::AreaI16(Make::PositionI16(0, TriangleArea.size.height), Make::SizeI16(80, 80)); static constexpr auto RectangleArea = Make::AreaI16(Make::PositionI16(0, TriangleArea.size.height), Make::SizeI16(80, 80));
static constexpr auto RectangleTPage = Make::TPage(IconTIM.get_texture_position(), GPU::SemiTransparency::B_Half_add_F_Half, GPU::TextureColorMode::clut4); static constexpr auto RectangleTPage = Make::TPage(IconTIM.get_texture_position(), GPU::SemiTransparency::B_Half_add_F_Half, GPU::TextureColorMode::clut4);
static constexpr auto RectangleClut = Make::PageClut(IconTIM.get_clut_position()); static constexpr auto RectangleClut = Make::PageClut(IconTIM.get_clut_position());
static constexpr auto LineColor = GPU::Color24::from_rgb(0xFF, 0x0, 0x0); static constexpr auto LineColor = GPU::Color24::from_rgb(0xFF, 0x0, 0x0);
static constexpr const auto triangle1 = Make::POLY_F3({ static constexpr const auto triangle1 = Make::POLY_F3({
Make::Vertex(TriangleArea.position.x, TriangleArea.position.y), Make::Vertex(TriangleArea.position.x, TriangleArea.position.y),
Make::Vertex(TriangleArea.size.width, TriangleArea.size.height), Make::Vertex(TriangleArea.size.width, TriangleArea.size.height),
Make::Vertex(TriangleArea.position.x, TriangleArea.size.height) Make::Vertex(TriangleArea.position.x, TriangleArea.size.height)
}, TriangleColor }, TriangleColor
); );
static constexpr const auto triangle2 = Make::POLY_FT3({ static constexpr const auto triangle2 = Make::POLY_FT3({
Make::Vertex(TriangleArea.position.x, TriangleArea.position.y), Make::Vertex(TriangleArea.position.x, TriangleArea.position.y),
Make::Vertex(TriangleArea.size.width, TriangleArea.position.y), Make::Vertex(TriangleArea.size.width, TriangleArea.position.y),
Make::Vertex(TriangleArea.size.width, TriangleArea.size.height) Make::Vertex(TriangleArea.size.width, TriangleArea.size.height)
},{ },{
// Texture // Texture
Make::PageOffset(TriangleArea.position.x, TriangleArea.position.y), Make::PageOffset(TriangleArea.position.x, TriangleArea.position.y),
Make::PageOffset(TriangleArea.size.width, TriangleArea.position.y), Make::PageOffset(TriangleArea.size.width, TriangleArea.position.y),
Make::PageOffset(TriangleArea.size.width, TriangleArea.size.height) Make::PageOffset(TriangleArea.size.width, TriangleArea.size.height)
}, TriangleTPage, TriangleClut, GPU::Color24::Grey() }, TriangleTPage, TriangleClut, GPU::Color24::Grey()
); );
static constexpr const auto triangle3 = Make::POLY_G3({ static constexpr const auto triangle3 = Make::POLY_G3({
{triangle1.vertex0.move(TriangleArea.size.width, 0), GPU::Color24::Red()}, {triangle1.vertex0.move(TriangleArea.size.width, 0), GPU::Color24::Red()},
{triangle1.vertex1.move(TriangleArea.size.width, 0), GPU::Color24::Green()}, {triangle1.vertex1.move(TriangleArea.size.width, 0), GPU::Color24::Green()},
{triangle1.vertex2.move(TriangleArea.size.width, 0), GPU::Color24::Blue()}} {triangle1.vertex2.move(TriangleArea.size.width, 0), GPU::Color24::Blue()}}
); );
static constexpr const auto triangle4 = Make::POLY_GT3({ static constexpr const auto triangle4 = Make::POLY_GT3({
{triangle2.vertex0.move(TriangleArea.size.width, 0), triangle2.tex_offset0, GPU::Color24::Red()}, {triangle2.vertex0.move(TriangleArea.size.width, 0), triangle2.tex_offset0, GPU::Color24::Red()},
{triangle2.vertex1.move(TriangleArea.size.width, 0), triangle2.tex_offset1, GPU::Color24::Blue()}, {triangle2.vertex1.move(TriangleArea.size.width, 0), triangle2.tex_offset1, GPU::Color24::Blue()},
{triangle2.vertex2.move(TriangleArea.size.width, 0), triangle2.tex_offset2, GPU::Color24::Green()}}, {triangle2.vertex2.move(TriangleArea.size.width, 0), triangle2.tex_offset2, GPU::Color24::Green()}},
TriangleTPage, TriangleTPage,
TriangleClut TriangleClut
); );
static constexpr const auto rectangle1 = Make::POLY_F4(RectangleArea, RectangleColor); static constexpr const auto rectangle1 = Make::POLY_F4(RectangleArea, RectangleColor);
static constexpr const auto rectangle2 = Make::POLY_FT4(Make::AreaI16( static constexpr const auto rectangle2 = Make::POLY_FT4(Make::AreaI16(
RectangleArea.position.move(RectangleArea.size.width, 0), RectangleArea.size), Make::PageOffset(0, 0), RectangleArea.position.move(RectangleArea.size.width, 0), RectangleArea.size), Make::PageOffset(0, 0),
RectangleTPage, RectangleTPage,
RectangleClut, RectangleClut,
GPU::Color24::Grey() GPU::Color24::Grey()
); );
static constexpr const auto rectangle3 = Make::POLY_G4( static constexpr const auto rectangle3 = Make::POLY_G4(
{RectangleArea.position.move(RectangleArea.size.width*2, 0), RectangleArea.size}, { {RectangleArea.position.move(RectangleArea.size.width*2, 0), RectangleArea.size}, {
GPU::Color24::Red(), GPU::Color24::Red(),
GPU::Color24::Blue(), GPU::Color24::Blue(),
GPU::Color24::Green(), GPU::Color24::Green(),
GPU::Color24::White()}); GPU::Color24::White()});
static constexpr const auto rectangle4 = Make::POLY_GT4(Make::AreaI16( static constexpr const auto rectangle4 = Make::POLY_GT4(Make::AreaI16(
RectangleArea.position.move(RectangleArea.size.width*3, 0), RectangleArea.size), Make::PageOffset(0, 0), RectangleArea.position.move(RectangleArea.size.width*3, 0), RectangleArea.size), Make::PageOffset(0, 0),
RectangleTPage, RectangleTPage,
RectangleClut, { RectangleClut, {
GPU::Color24::Red(), GPU::Color24::Red(),
GPU::Color24::Blue(), GPU::Color24::Blue(),
GPU::Color24::Green(), GPU::Color24::Green(),
GPU::Color24::White()} GPU::Color24::White()}
); );
static constexpr const auto rectangle5 = Make::POLY_GT4(Make::AreaI16( static constexpr const auto rectangle5 = Make::POLY_GT4(Make::AreaI16(
RectangleArea.position.move(0, RectangleArea.size.height), RectangleArea.size), Make::PageOffset(0, 0), RectangleArea.position.move(0, RectangleArea.size.height), RectangleArea.size), Make::PageOffset(0, 0),
RectangleTPage, RectangleTPage,
RectangleClut, { RectangleClut, {
GPU::Color24::Red(), GPU::Color24::Red(),
GPU::Color24::Blue(), GPU::Color24::Blue(),
GPU::Color24::Green(), GPU::Color24::Green(),
GPU::Color24::White()} GPU::Color24::White()}
).set_semi_transparent(true); ).set_semi_transparent(true);
static constexpr const auto line1 = Make::LINE_F(LineColor, static constexpr const auto line1 = Make::LINE_F(LineColor,
Make::Vertex(0, 0), Make::Vertex(0, 0),
Make::Vertex(GPU::Display::Width, GPU::Display::Height) Make::Vertex(GPU::Display::Width, GPU::Display::Height)
); );
static constexpr const auto line2 = Make::LINE_F(LineColor.invert(), static constexpr const auto line2 = Make::LINE_F(LineColor.invert(),
Make::Vertex(0, 0), Make::Vertex(0, 0),
Make::Vertex(16, 0), Make::Vertex(16, 0),
Make::Vertex(16, 16), Make::Vertex(16, 16),
Make::Vertex(0, 0) Make::Vertex(0, 0)
); );
static constexpr const auto line3 = Make::LINE_G( static constexpr const auto line3 = Make::LINE_G(
GPU::ColorVertex{LineColor, Make::Vertex(GPU::Display::Width, 0)}, GPU::ColorVertex{LineColor, Make::Vertex(GPU::Display::Width, 0)},
GPU::ColorVertex{LineColor.invert(), Make::Vertex(0, GPU::Display::Height)} GPU::ColorVertex{LineColor.invert(), Make::Vertex(0, GPU::Display::Height)}
); );
static constexpr const auto line4 = Make::LINE_G( static constexpr const auto line4 = Make::LINE_G(
GPU::ColorVertex{GPU::Color24::Red(), Make::Vertex(0, 0)}, GPU::ColorVertex{GPU::Color24::Red(), Make::Vertex(0, 0)},
GPU::ColorVertex{GPU::Color24::Green(), Make::Vertex(0, 16)}, GPU::ColorVertex{GPU::Color24::Green(), Make::Vertex(0, 16)},
GPU::ColorVertex{GPU::Color24::Blue(), Make::Vertex(16, 16)}, GPU::ColorVertex{GPU::Color24::Blue(), Make::Vertex(16, 16)},
GPU::ColorVertex{GPU::Color24::White(), Make::Vertex(0, 0)} GPU::ColorVertex{GPU::Color24::White(), Make::Vertex(0, 0)}
); );
static constexpr const auto rect1 = Make::TILE(Make::AreaI16(Make::PositionI16(GPU::Display::Width - 32, GPU::Display::Height - 32), Make::SizeI16(32, 32)), GPU::Color24::Green()); static constexpr const auto rect1 = Make::TILE(Make::AreaI16(Make::PositionI16(GPU::Display::Width - 32, GPU::Display::Height - 32), Make::SizeI16(32, 32)), GPU::Color24::Green());
static constexpr const auto rect2 = Make::TILE_16(Make::PositionI16(GPU::Display::Width - 16, GPU::Display::Height - 16), GPU::Color24::Blue()); static constexpr const auto rect2 = Make::TILE_16(Make::PositionI16(GPU::Display::Width - 16, GPU::Display::Height - 16), GPU::Color24::Blue());
static constexpr const auto rect3 = Make::TILE_8(Make::PositionI16(GPU::Display::Width - 8, GPU::Display::Height - 8), GPU::Color24::Yellow()); static constexpr const auto rect3 = Make::TILE_8(Make::PositionI16(GPU::Display::Width - 8, GPU::Display::Height - 8), GPU::Color24::Yellow());
static constexpr const auto rect4 = Make::TILE_1(Make::PositionI16(GPU::Display::Width - 1, GPU::Display::Height - 1), GPU::Color24::Red()); static constexpr const auto rect4 = Make::TILE_1(Make::PositionI16(GPU::Display::Width - 1, GPU::Display::Height - 1), GPU::Color24::Red());
static constexpr const auto texpage = Make::TexPage(TexPageTIM.get_texture_position(), GPU::TextureColorMode::clut4); static constexpr const auto texpage = Make::TexPage(TexPageTIM.get_texture_position(), GPU::TextureColorMode::clut4);
static constexpr const auto rect5 = Make::SPRT(Make::AreaI16(Make::PositionI16(0, GPU::Display::Height - 32), Make::SizeI16(32, 32)), {Make::PageOffset(0, 0), TriangleClut}, GPU::Color24::Green()); static constexpr const auto rect5 = Make::SPRT(Make::AreaI16(Make::PositionI16(0, GPU::Display::Height - 32), Make::SizeI16(32, 32)), {Make::PageOffset(0, 0), TriangleClut}, GPU::Color24::Green());
static constexpr const auto rect6 = Make::SPRT_16(Make::Vertex(0, GPU::Display::Height - 16), Make::OffsetPageWithClut(Make::PageOffset(0, 0), TriangleClut), GPU::Color24::Blue()); static constexpr const auto rect6 = Make::SPRT_16(Make::Vertex(0, GPU::Display::Height - 16), Make::OffsetPageWithClut(Make::PageOffset(0, 0), TriangleClut), GPU::Color24::Blue());
static constexpr const auto rect7 = Make::SPRT_8(Make::Vertex(0, GPU::Display::Height - 8), Make::OffsetPageWithClut(Make::PageOffset(0, 0), TriangleClut), GPU::Color24::Yellow()); static constexpr const auto rect7 = Make::SPRT_8(Make::Vertex(0, GPU::Display::Height - 8), Make::OffsetPageWithClut(Make::PageOffset(0, 0), TriangleClut), GPU::Color24::Yellow());
static constexpr const auto rect8 = Make::SPRT_1(Make::Vertex(0, GPU::Display::Height - 1), Make::OffsetPageWithClut(Make::PageOffset(0, 0), TriangleClut), GPU::Color24::Red()); static constexpr const auto rect8 = Make::SPRT_1(Make::Vertex(0, GPU::Display::Height - 1), Make::OffsetPageWithClut(Make::PageOffset(0, 0), TriangleClut), GPU::Color24::Red());
static auto rect9 = Make::SPRT(Make::AreaI16(Make::PositionI16(GPU::Display::Width/2, GPU::Display::Height/2), Make::SizeI16(32, 32)).centered(), Make::OffsetPageWithClut(Make::PageOffset(0, 0), TriangleClut), GPU::Color24::Grey()).linked(); static auto rect9 = Make::SPRT(Make::AreaI16(Make::PositionI16(GPU::Display::Width/2, GPU::Display::Height/2), Make::SizeI16(32, 32)).centered(), Make::OffsetPageWithClut(Make::PageOffset(0, 0), TriangleClut), GPU::Color24::Grey()).linked();
static auto rect10 = Make::SPRT(Make::AreaI16(Make::PositionI16(GPU::Display::Width/2, GPU::Display::Height/2 - 32), Make::SizeI16(32, 32)).centered(), Make::OffsetPageWithClut(Make::PageOffset(0, 0), TriangleClut), GPU::Color24::Grey()).linked(); static auto rect10 = Make::SPRT(Make::AreaI16(Make::PositionI16(GPU::Display::Width/2, GPU::Display::Height/2 - 32), Make::SizeI16(32, 32)).centered(), Make::OffsetPageWithClut(Make::PageOffset(0, 0), TriangleClut), GPU::Color24::Grey()).linked();
void main() { void main() {
rect9.concat(rect10); rect9.concat(rect10);
Shared::back_menu.reset(); Shared::back_menu.reset();
HighResTime::enable(); HighResTime::enable();
auto start_time = HighResTime::get_time_stamp(); auto start_time = HighResTime::get_time_stamp();
auto time_passed = 0; auto time_passed = 0;
while(true) { while(true) {
// Update Phase // Update Phase
Periphery::query_controller(); Periphery::query_controller();
if(Shared::back_menu.update(Make::PositionI16(0, GPU::Display::Height - 32))) { if(Shared::back_menu.update(Make::PositionI16(0, GPU::Display::Height - 32))) {
break; break;
} }
auto cursor = FontWriter::update(Make::PositionI16((GPU::Display::Width - 160)/2, GPU::Display::Height - 32)); auto cursor = FontWriter::update(Make::PositionI16((GPU::Display::Width - 160)/2, GPU::Display::Height - 32));
FontWriter::bios_font_writer.write(cursor, "Time: %ims", GPU::Color24::Blue(), time_passed); FontWriter::bios_font_writer.write(cursor, "Time: %ims", GPU::Color24::Blue(), time_passed);
GPU::swap_buffers_vsync(1); GPU::swap_buffers_vsync(1);
const auto end_time = HighResTime::get_time_stamp(); const auto end_time = HighResTime::get_time_stamp();
time_passed = start_time.milliseconds_to(end_time); time_passed = start_time.milliseconds_to(end_time);
start_time = end_time; start_time = end_time;
GPU::render(triangle1); GPU::render(triangle1);
GPU::render(triangle2); GPU::render(triangle2);
GPU::render(triangle3); GPU::render(triangle3);
GPU::render(triangle4); GPU::render(triangle4);
GPU::render(rectangle1); GPU::render(rectangle1);
GPU::render(rectangle2); GPU::render(rectangle2);
GPU::render(rectangle3); GPU::render(rectangle3);
GPU::render(rectangle4); GPU::render(rectangle4);
GPU::render(rectangle5); GPU::render(rectangle5);
GPU::render(rect1); GPU::render(rect1);
GPU::render(rect2); GPU::render(rect2);
GPU::render(rect3); GPU::render(rect3);
GPU::render(rect4); GPU::render(rect4);
GPU::render(texpage); GPU::render(texpage);
GPU::render(rect5); GPU::render(rect5);
GPU::render(rect6); GPU::render(rect6);
GPU::render(rect7); GPU::render(rect7);
GPU::render(rect8); GPU::render(rect8);
GPU::render(line1); GPU::render(line1);
GPU::render(line2); GPU::render(line2);
GPU::render(line3); GPU::render(line3);
GPU::render(line4); GPU::render(line4);
GPU::render(rect9); GPU::render(rect9);
Shared::back_menu.render(); Shared::back_menu.render();
} }
HighResTime::disable(); HighResTime::disable();
} }
} }

View File

@ -1,60 +1,60 @@
#include "include/gpu_test_assets.hpp" #include "include/gpu_test_assets.hpp"
#include <PSX/File/Processor/cd_file_processor.hpp> #include <PSX/File/Processor/cd_file_processor.hpp>
#include <PSX/AutoLBA/auto_lba_declaration.hpp> #include <PSX/AutoLBA/auto_lba_declaration.hpp>
namespace GPUTest { namespace GPUTest {
using namespace JabyEngine; using namespace JabyEngine;
enum LBA { enum LBA {
__jabyengine_start_lba_request __jabyengine_start_lba_request
__jabyengine_request_lba_for(TEX, "ASSETS/TEX.IMG"), __jabyengine_request_lba_for(TEX, "ASSETS/TEX.IMG"),
__jabyengine_request_lba_for(ICON, "ASSETS/ICON.IMG"), __jabyengine_request_lba_for(ICON, "ASSETS/ICON.IMG"),
__jabyengine_request_lba_for(ALL_THE_JABY, "ASSETS/ATJ.TIM"), __jabyengine_request_lba_for(ALL_THE_JABY, "ASSETS/ATJ.TIM"),
__jabyengine_end_lba_request __jabyengine_end_lba_request
}; };
__declare_lba_header(LBA); __declare_lba_header(LBA);
CDFile Assets[2] = { CDFile Assets[2] = {
CDFileBuilder::simple_tim(LBA::TEX, TexPageTIM), CDFileBuilder::simple_tim(LBA::TEX, TexPageTIM),
CDFileBuilder::simple_tim(LBA::ICON, IconTIM), CDFileBuilder::simple_tim(LBA::ICON, IconTIM),
}; };
CDFile LargeAssets[36] = { CDFile LargeAssets[36] = {
CDFileBuilder::sony_tim(LBA::ALL_THE_JABY, TIM::create()), CDFileBuilder::sony_tim(LBA::ALL_THE_JABY, TIM::create()),
CDFileBuilder::sony_tim(LBA::ALL_THE_JABY, TIM::create()), CDFileBuilder::sony_tim(LBA::ALL_THE_JABY, TIM::create()),
CDFileBuilder::sony_tim(LBA::ALL_THE_JABY, TIM::create()), CDFileBuilder::sony_tim(LBA::ALL_THE_JABY, TIM::create()),
CDFileBuilder::sony_tim(LBA::ALL_THE_JABY, TIM::create()), CDFileBuilder::sony_tim(LBA::ALL_THE_JABY, TIM::create()),
CDFileBuilder::sony_tim(LBA::ALL_THE_JABY, TIM::create()), CDFileBuilder::sony_tim(LBA::ALL_THE_JABY, TIM::create()),
CDFileBuilder::sony_tim(LBA::ALL_THE_JABY, TIM::create()), CDFileBuilder::sony_tim(LBA::ALL_THE_JABY, TIM::create()),
CDFileBuilder::sony_tim(LBA::ALL_THE_JABY, TIM::create()), CDFileBuilder::sony_tim(LBA::ALL_THE_JABY, TIM::create()),
CDFileBuilder::sony_tim(LBA::ALL_THE_JABY, TIM::create()), CDFileBuilder::sony_tim(LBA::ALL_THE_JABY, TIM::create()),
CDFileBuilder::sony_tim(LBA::ALL_THE_JABY, TIM::create()), CDFileBuilder::sony_tim(LBA::ALL_THE_JABY, TIM::create()),
CDFileBuilder::sony_tim(LBA::ALL_THE_JABY, TIM::create()), CDFileBuilder::sony_tim(LBA::ALL_THE_JABY, TIM::create()),
CDFileBuilder::sony_tim(LBA::ALL_THE_JABY, TIM::create()), CDFileBuilder::sony_tim(LBA::ALL_THE_JABY, TIM::create()),
CDFileBuilder::sony_tim(LBA::ALL_THE_JABY, TIM::create()), CDFileBuilder::sony_tim(LBA::ALL_THE_JABY, TIM::create()),
CDFileBuilder::sony_tim(LBA::ALL_THE_JABY, TIM::create()), CDFileBuilder::sony_tim(LBA::ALL_THE_JABY, TIM::create()),
CDFileBuilder::sony_tim(LBA::ALL_THE_JABY, TIM::create()), CDFileBuilder::sony_tim(LBA::ALL_THE_JABY, TIM::create()),
CDFileBuilder::sony_tim(LBA::ALL_THE_JABY, TIM::create()), CDFileBuilder::sony_tim(LBA::ALL_THE_JABY, TIM::create()),
CDFileBuilder::sony_tim(LBA::ALL_THE_JABY, TIM::create()), CDFileBuilder::sony_tim(LBA::ALL_THE_JABY, TIM::create()),
CDFileBuilder::sony_tim(LBA::ALL_THE_JABY, TIM::create()), CDFileBuilder::sony_tim(LBA::ALL_THE_JABY, TIM::create()),
CDFileBuilder::sony_tim(LBA::ALL_THE_JABY, TIM::create()), CDFileBuilder::sony_tim(LBA::ALL_THE_JABY, TIM::create()),
CDFileBuilder::sony_tim(LBA::ALL_THE_JABY, TIM::create()), CDFileBuilder::sony_tim(LBA::ALL_THE_JABY, TIM::create()),
CDFileBuilder::sony_tim(LBA::ALL_THE_JABY, TIM::create()), CDFileBuilder::sony_tim(LBA::ALL_THE_JABY, TIM::create()),
CDFileBuilder::sony_tim(LBA::ALL_THE_JABY, TIM::create()), CDFileBuilder::sony_tim(LBA::ALL_THE_JABY, TIM::create()),
CDFileBuilder::sony_tim(LBA::ALL_THE_JABY, TIM::create()), CDFileBuilder::sony_tim(LBA::ALL_THE_JABY, TIM::create()),
CDFileBuilder::sony_tim(LBA::ALL_THE_JABY, TIM::create()), CDFileBuilder::sony_tim(LBA::ALL_THE_JABY, TIM::create()),
CDFileBuilder::sony_tim(LBA::ALL_THE_JABY, TIM::create()), CDFileBuilder::sony_tim(LBA::ALL_THE_JABY, TIM::create()),
CDFileBuilder::sony_tim(LBA::ALL_THE_JABY, TIM::create()), CDFileBuilder::sony_tim(LBA::ALL_THE_JABY, TIM::create()),
CDFileBuilder::sony_tim(LBA::ALL_THE_JABY, TIM::create()), CDFileBuilder::sony_tim(LBA::ALL_THE_JABY, TIM::create()),
CDFileBuilder::sony_tim(LBA::ALL_THE_JABY, TIM::create()), CDFileBuilder::sony_tim(LBA::ALL_THE_JABY, TIM::create()),
CDFileBuilder::sony_tim(LBA::ALL_THE_JABY, TIM::create()), CDFileBuilder::sony_tim(LBA::ALL_THE_JABY, TIM::create()),
CDFileBuilder::sony_tim(LBA::ALL_THE_JABY, TIM::create()), CDFileBuilder::sony_tim(LBA::ALL_THE_JABY, TIM::create()),
CDFileBuilder::sony_tim(LBA::ALL_THE_JABY, TIM::create()), CDFileBuilder::sony_tim(LBA::ALL_THE_JABY, TIM::create()),
CDFileBuilder::sony_tim(LBA::ALL_THE_JABY, TIM::create()), CDFileBuilder::sony_tim(LBA::ALL_THE_JABY, TIM::create()),
CDFileBuilder::sony_tim(LBA::ALL_THE_JABY, TIM::create()), CDFileBuilder::sony_tim(LBA::ALL_THE_JABY, TIM::create()),
CDFileBuilder::sony_tim(LBA::ALL_THE_JABY, TIM::create()), CDFileBuilder::sony_tim(LBA::ALL_THE_JABY, TIM::create()),
CDFileBuilder::sony_tim(LBA::ALL_THE_JABY, TIM::create()), CDFileBuilder::sony_tim(LBA::ALL_THE_JABY, TIM::create()),
CDFileBuilder::sony_tim(LBA::ALL_THE_JABY, TIM::create()), CDFileBuilder::sony_tim(LBA::ALL_THE_JABY, TIM::create()),
CDFileBuilder::sony_tim(LBA::ALL_THE_JABY, TIM::create()), CDFileBuilder::sony_tim(LBA::ALL_THE_JABY, TIM::create()),
}; };
} }

View File

@ -1,9 +1,9 @@
#pragma once #pragma once
#include <PSX/File/cd_file_types.hpp> #include <PSX/File/cd_file_types.hpp>
namespace GPUTest { namespace GPUTest {
using namespace JabyEngine; using namespace JabyEngine;
static constexpr auto TexPageTIM = SimpleTIM::create(384, 0, 384, 511); static constexpr auto TexPageTIM = SimpleTIM::create(384, 0, 384, 511);
static constexpr auto IconTIM = SimpleTIM::create(384, 256, 384, 510); static constexpr auto IconTIM = SimpleTIM::create(384, 256, 384, 510);
} }

View File

@ -1,166 +1,166 @@
#include "../../../include/asset_mgr.hpp" #include "../../../include/asset_mgr.hpp"
#include "../../../include/shared.hpp" #include "../../../include/shared.hpp"
#include "include/GTE_Sprite.hpp" #include "include/GTE_Sprite.hpp"
#include "include/gte_test_assets.hpp" #include "include/gte_test_assets.hpp"
#include <PSX/Periphery/periphery.hpp> #include <PSX/Periphery/periphery.hpp>
namespace GTETest { namespace GTETest {
using namespace JabyEngine; using namespace JabyEngine;
using namespace GTETest; using namespace GTETest;
namespace Jaby { namespace Jaby {
static constexpr auto AnimationTime = 250_ms; static constexpr auto AnimationTime = 250_ms;
static const struct { static const struct {
gte_float scale_left; gte_float scale_left;
gte_float scale_right; gte_float scale_right;
} animation[] = { } animation[] = {
{.scale_left = 1.0_gf, .scale_right = 1.0_gf}, {.scale_left = 1.0_gf, .scale_right = 1.0_gf},
{.scale_left = 1.0_gf, .scale_right = 1.0_gf}, {.scale_left = 1.0_gf, .scale_right = 1.0_gf},
{.scale_left = 1.2_gf, .scale_right = 1.5_gf}, {.scale_left = 1.2_gf, .scale_right = 1.5_gf},
{.scale_left = 1.5_gf, .scale_right = 1.2_gf}, {.scale_left = 1.5_gf, .scale_right = 1.2_gf},
{.scale_left = 1.2_gf, .scale_right = 1.5_gf}, {.scale_left = 1.2_gf, .scale_right = 1.5_gf},
{.scale_left = 1.5_gf, .scale_right = 1.2_gf}, {.scale_left = 1.5_gf, .scale_right = 1.2_gf},
{.scale_left = 1.8_gf, .scale_right = 2.3_gf}, {.scale_left = 1.8_gf, .scale_right = 2.3_gf},
{.scale_left = 2.3_gf, .scale_right = 1.8_gf}, {.scale_left = 2.3_gf, .scale_right = 1.8_gf},
{.scale_left = 1.8_gf, .scale_right = 2.3_gf}, {.scale_left = 1.8_gf, .scale_right = 2.3_gf},
{.scale_left = 2.3_gf, .scale_right = 1.8_gf}, {.scale_left = 2.3_gf, .scale_right = 1.8_gf},
{.scale_left = 3.2_gf, .scale_right = 4.5_gf}, {.scale_left = 3.2_gf, .scale_right = 4.5_gf},
{.scale_left = 4.5_gf, .scale_right = 3.2_gf}, {.scale_left = 4.5_gf, .scale_right = 3.2_gf},
{.scale_left = 3.2_gf, .scale_right = 4.5_gf}, {.scale_left = 3.2_gf, .scale_right = 4.5_gf},
{.scale_left = 4.5_gf, .scale_right = 3.2_gf}, {.scale_left = 4.5_gf, .scale_right = 3.2_gf},
{.scale_left = 1.8_gf, .scale_right = 2.3_gf}, {.scale_left = 1.8_gf, .scale_right = 2.3_gf},
{.scale_left = 2.3_gf, .scale_right = 1.8_gf}, {.scale_left = 2.3_gf, .scale_right = 1.8_gf},
{.scale_left = 1.8_gf, .scale_right = 2.3_gf}, {.scale_left = 1.8_gf, .scale_right = 2.3_gf},
{.scale_left = 2.3_gf, .scale_right = 1.8_gf}, {.scale_left = 2.3_gf, .scale_right = 1.8_gf},
{.scale_left = 1.2_gf, .scale_right = 1.5_gf}, {.scale_left = 1.2_gf, .scale_right = 1.5_gf},
{.scale_left = 1.5_gf, .scale_right = 1.2_gf}, {.scale_left = 1.5_gf, .scale_right = 1.2_gf},
{.scale_left = 1.2_gf, .scale_right = 1.5_gf}, {.scale_left = 1.2_gf, .scale_right = 1.5_gf},
{.scale_left = 1.5_gf, .scale_right = 1.2_gf}, {.scale_left = 1.5_gf, .scale_right = 1.2_gf},
}; };
static IntervalTimer<uint8_t> animation_timer; static IntervalTimer<uint8_t> animation_timer;
static auto animation_id = 0; static auto animation_id = 0;
static constexpr auto Position = Make::PositionI16(GPU::Display::Width - 64, GPU::Display::Height - 64); static constexpr auto Position = Make::PositionI16(GPU::Display::Width - 64, GPU::Display::Height - 64);
static constexpr GTE_Sprite make_star_eye(GPU::PositionI16 pos) { static constexpr GTE_Sprite make_star_eye(GPU::PositionI16 pos) {
return GTE_Sprite::create(Make::POLY_FT4( return GTE_Sprite::create(Make::POLY_FT4(
Make::AreaI16(pos, GPU::SizeI16(8, 8)), Make::AreaI16(pos, GPU::SizeI16(8, 8)),
JabySTARTim.get_page_offset_clut4().add(0, 64), JabySTARTim.get_page_offset_clut4().add(0, 64),
Make::TPage(JabySTARTim.get_texture_position(), GPU::SemiTransparency::B_add_F, GPU::TextureColorMode::clut4), Make::TPage(JabySTARTim.get_texture_position(), GPU::SemiTransparency::B_add_F, GPU::TextureColorMode::clut4),
Make::PageClut(JabySTARTim.get_clut_position()), Make::PageClut(JabySTARTim.get_clut_position()),
GPU::Color24::Grey() GPU::Color24::Grey()
).linked()); ).linked());
} }
static auto star_base = Make::SPRT( static auto star_base = Make::SPRT(
Make::AreaI16(Position, Make::SizeI16(64, 64)), Make::AreaI16(Position, Make::SizeI16(64, 64)),
Make::OffsetPageWithClut(JabySTARTim.get_page_offset_clut4(), Make::PageClut(JabySTARTim.get_clut_position())) Make::OffsetPageWithClut(JabySTARTim.get_page_offset_clut4(), Make::PageClut(JabySTARTim.get_clut_position()))
).linked(); ).linked();
static GTE_Sprite star_eyes[2] = { static GTE_Sprite star_eyes[2] = {
make_star_eye(Position.add(11, 30)), make_star_eye(Position.add(11, 30)),
make_star_eye(Position.add(33, 31)) make_star_eye(Position.add(33, 31))
}; };
} }
namespace Background { namespace Background {
static constexpr auto ColorBase = 0xC0; static constexpr auto ColorBase = 0xC0;
static constexpr GPU::AreaI16 Area[2] = { static constexpr GPU::AreaI16 Area[2] = {
Make::AreaI16(-30, -30, 350, 350), Make::AreaI16(-30, -30, 350, 350),
Make::AreaI16(0, 0, GPU::Display::Width, GPU::Display::Width), Make::AreaI16(0, 0, GPU::Display::Width, GPU::Display::Width),
}; };
static constexpr GPU::PositionI16 AreaPivot[2] = { static constexpr GPU::PositionI16 AreaPivot[2] = {
Make::PositionI16(Area[0].size.width/2, Area[0].size.height/2), Make::PositionI16(Area[0].size.width/2, Area[0].size.height/2),
Make::PositionI16(Area[1].size.width/2, Area[1].size.height/2), Make::PositionI16(Area[1].size.width/2, Area[1].size.height/2),
}; };
static GPU::POLY_G4 poly[2] = { static GPU::POLY_G4 poly[2] = {
Make::POLY_G4(Area[0], {GPU::Color24::Blue(ColorBase), GPU::Color24::Red(ColorBase), GPU::Color24::Green(ColorBase), GPU::Color24::Purple(ColorBase)}), Make::POLY_G4(Area[0], {GPU::Color24::Blue(ColorBase), GPU::Color24::Red(ColorBase), GPU::Color24::Green(ColorBase), GPU::Color24::Purple(ColorBase)}),
Make::POLY_G4(Area[1], {GPU::Color24::Blue(ColorBase), GPU::Color24::Red(ColorBase), GPU::Color24::Green(ColorBase), GPU::Color24::Purple(ColorBase)}), Make::POLY_G4(Area[1], {GPU::Color24::Blue(ColorBase), GPU::Color24::Red(ColorBase), GPU::Color24::Green(ColorBase), GPU::Color24::Purple(ColorBase)}),
}; };
} }
static auto doener_fish = GTE_Sprite::create(Make::POLY_FT4( static auto doener_fish = GTE_Sprite::create(Make::POLY_FT4(
Make::AreaI16(Make::PositionI16(0, 0), Assets::Main::DoenerFishInfo.size), Make::AreaI16(Make::PositionI16(0, 0), Assets::Main::DoenerFishInfo.size),
Assets::Main::DoenerFishInfo.tim.get_page_offset_clut4(), Assets::Main::DoenerFishInfo.tim.get_page_offset_clut4(),
Make::TPage(Assets::Main::DoenerFishInfo.tim.get_texture_position(), GPU::SemiTransparency::B_add_F, GPU::TextureColorMode::clut4), Make::TPage(Assets::Main::DoenerFishInfo.tim.get_texture_position(), GPU::SemiTransparency::B_add_F, GPU::TextureColorMode::clut4),
Make::PageClut(Assets::Main::DoenerFishInfo.tim.get_clut_position()), Make::PageClut(Assets::Main::DoenerFishInfo.tim.get_clut_position()),
GPU::Color24::Grey() GPU::Color24::Grey()
).linked()); ).linked());
static auto gbl_rotation = 0.0_deg; static auto gbl_rotation = 0.0_deg;
static void setup() { static void setup() {
Jaby::star_base.concat(Jaby::star_eyes[0].display.concat(Jaby::star_eyes[1].display)); Jaby::star_base.concat(Jaby::star_eyes[0].display.concat(Jaby::star_eyes[1].display));
Jaby::star_eyes[0].scale = Jaby::animation[0].scale_right; Jaby::star_eyes[0].scale = Jaby::animation[0].scale_right;
Jaby::star_eyes[1].scale = Jaby::animation[0].scale_left; Jaby::star_eyes[1].scale = Jaby::animation[0].scale_left;
Jaby::animation_id = 1; Jaby::animation_id = 1;
Jaby::animation_timer = IntervalTimer<uint8_t>::create(Jaby::AnimationTime); Jaby::animation_timer = IntervalTimer<uint8_t>::create(Jaby::AnimationTime);
doener_fish.area.position = GPU::PositionI16::create(100, 100); doener_fish.area.position = GPU::PositionI16::create(100, 100);
Shared::back_menu.reset(); Shared::back_menu.reset();
GTE::set_geom_offset(0, 0); GTE::set_geom_offset(0, 0);
GTE::set_geom_screen(256); GTE::set_geom_screen(256);
} }
static bool update_or_exit() { static bool update_or_exit() {
Periphery::query_controller(); Periphery::query_controller();
if(Shared::back_menu.update(Make::PositionI16(0, GPU::Display::Height - 32))) { if(Shared::back_menu.update(Make::PositionI16(0, GPU::Display::Height - 32))) {
return true; return true;
} }
if(Jaby::animation_timer.is_expired()) { if(Jaby::animation_timer.is_expired()) {
Jaby::star_eyes[0].scale = Jaby::animation[Jaby::animation_id].scale_right; Jaby::star_eyes[0].scale = Jaby::animation[Jaby::animation_id].scale_right;
Jaby::star_eyes[1].scale = Jaby::animation[Jaby::animation_id].scale_left; Jaby::star_eyes[1].scale = Jaby::animation[Jaby::animation_id].scale_left;
Jaby::animation_id = (Jaby::animation_id + 1)%(sizeof(Jaby::animation)/sizeof(Jaby::animation[0])); Jaby::animation_id = (Jaby::animation_id + 1)%(sizeof(Jaby::animation)/sizeof(Jaby::animation[0]));
Jaby::animation_timer.reset(); Jaby::animation_timer.reset();
} }
for(size_t n = 0; n < sizeof(Background::poly)/sizeof(Background::poly[0]); n++) { for(size_t n = 0; n < sizeof(Background::poly)/sizeof(Background::poly[0]); n++) {
auto matrix = [](size_t n) -> GTE::MATRIX { auto matrix = [](size_t n) -> GTE::MATRIX {
auto matrix = GTE::MATRIX::translated(-Background::AreaPivot[n].x, -Background::AreaPivot[n].y); auto matrix = GTE::MATRIX::translated(-Background::AreaPivot[n].x, -Background::AreaPivot[n].y);
matrix.rotate(0.0_deg, 0.0_deg, (n == 0) ? gbl_rotation : -gbl_rotation); matrix.rotate(0.0_deg, 0.0_deg, (n == 0) ? gbl_rotation : -gbl_rotation);
return matrix.translate(Background::Area[n].position.x + Background::AreaPivot[n].x, Background::Area[n].position.y + Background::AreaPivot[n].y); return matrix.translate(Background::Area[n].position.x + Background::AreaPivot[n].x, Background::Area[n].position.y + Background::AreaPivot[n].y);
}(n); }(n);
matrix.apply_to_area(Background::poly[n], Make::AreaI16(Make::PositionI16(), Background::Area[n].size)); matrix.apply_to_area(Background::poly[n], Make::AreaI16(Make::PositionI16(), Background::Area[n].size));
} }
const auto matrix = GTE::MATRIX::rotated(-gbl_rotation, gbl_rotation, -gbl_rotation); const auto matrix = GTE::MATRIX::rotated(-gbl_rotation, gbl_rotation, -gbl_rotation);
doener_fish.apply(matrix); doener_fish.apply(matrix);
Jaby::star_eyes[0].apply(); Jaby::star_eyes[0].apply();
Jaby::star_eyes[1].apply(); Jaby::star_eyes[1].apply();
doener_fish.angle += 25.0_deg; doener_fish.angle += 25.0_deg;
gbl_rotation += 2.5_deg; gbl_rotation += 2.5_deg;
return false; return false;
} }
static void render() { static void render() {
for(const auto& poly : Background::poly) { for(const auto& poly : Background::poly) {
GPU::render(poly); GPU::render(poly);
} }
doener_fish.render(); doener_fish.render();
GPU::render(Jaby::star_base); GPU::render(Jaby::star_base);
Shared::back_menu.render(); Shared::back_menu.render();
GPU::wait_for_render(); //< Because we are single buffer GPU::wait_for_render(); //< Because we are single buffer
} }
void main() { void main() {
setup(); setup();
while(true) { while(true) {
if(update_or_exit()) { if(update_or_exit()) {
break; break;
} }
GPU::swap_buffers_vsync(1, false); GPU::swap_buffers_vsync(1, false);
render(); render();
} }
} }
} }

View File

@ -1,15 +1,15 @@
#include "include/gte_test_assets.hpp" #include "include/gte_test_assets.hpp"
#include <PSX/AutoLBA/auto_lba_declaration.hpp> #include <PSX/AutoLBA/auto_lba_declaration.hpp>
namespace GTETest { namespace GTETest {
enum LBA { enum LBA {
__jabyengine_start_lba_request __jabyengine_start_lba_request
__jabyengine_request_lba_for(JABY_STAR, "ASSETS/GTE/JABY.IMG"), __jabyengine_request_lba_for(JABY_STAR, "ASSETS/GTE/JABY.IMG"),
__jabyengine_end_lba_request __jabyengine_end_lba_request
}; };
__declare_lba_header(LBA); __declare_lba_header(LBA);
CDFile Assets[1] = { CDFile Assets[1] = {
CDFileBuilder::simple_tim(LBA::JABY_STAR, JabySTARTim), CDFileBuilder::simple_tim(LBA::JABY_STAR, JabySTARTim),
}; };
} }

View File

@ -1,47 +1,47 @@
#pragma once #pragma once
#include <PSX/GPU/gpu_primitives.hpp> #include <PSX/GPU/gpu_primitives.hpp>
#include <PSX/GPU/gpu.hpp> #include <PSX/GPU/gpu.hpp>
#include <PSX/GTE/gte.hpp> #include <PSX/GTE/gte.hpp>
#include <stdio.hpp> #include <stdio.hpp>
namespace GTETest { namespace GTETest {
using namespace JabyEngine; using namespace JabyEngine;
struct GTE_Sprite { struct GTE_Sprite {
GPU::AreaI16 area; GPU::AreaI16 area;
GPU::PositionI16 pivot; GPU::PositionI16 pivot;
deg_t angle; deg_t angle;
gte_float scale; gte_float scale;
GPU::POLY_FT4::Linked display; GPU::POLY_FT4::Linked display;
static constexpr GTE_Sprite create(const GPU::POLY_FT4::Linked& base) { static constexpr GTE_Sprite create(const GPU::POLY_FT4::Linked& base) {
const auto rect_size = base->get_rect_size(); const auto rect_size = base->get_rect_size();
return GTE_Sprite{ return GTE_Sprite{
.area = GPU::AreaI16::create(base->get_rect_pos(), rect_size), .area = GPU::AreaI16::create(base->get_rect_pos(), rect_size),
.pivot = GPU::PositionI16::create(rect_size.width/2, rect_size.height/2), .pivot = GPU::PositionI16::create(rect_size.width/2, rect_size.height/2),
.angle = 0.0_deg, .angle = 0.0_deg,
.scale = 1.0_gf, .scale = 1.0_gf,
.display = base .display = base
}; };
} }
void apply(const GTE::MATRIX& gbl_matrix = GTE::MATRIX::identity()) { void apply(const GTE::MATRIX& gbl_matrix = GTE::MATRIX::identity()) {
const auto matrix = const auto matrix =
GTE::MATRIX::translated(-this->pivot.x, -this->pivot.y, 0) GTE::MATRIX::translated(-this->pivot.x, -this->pivot.y, 0)
.rotate(0.0_deg, 0.0_deg, this->angle) .rotate(0.0_deg, 0.0_deg, this->angle)
.scale(this->scale, this->scale) .scale(this->scale, this->scale)
.translate(this->area.position.x + this->pivot.x, this->area.position.y + this->pivot.y, 0) .translate(this->area.position.x + this->pivot.x, this->area.position.y + this->pivot.y, 0)
.comp(gbl_matrix); .comp(gbl_matrix);
this->display->vertex0 = matrix.apply_to(GPU::Vertex::create(0, 0)); this->display->vertex0 = matrix.apply_to(GPU::Vertex::create(0, 0));
this->display->vertex1 = matrix.apply_to(GPU::Vertex::create(this->area.size.width, 0)); this->display->vertex1 = matrix.apply_to(GPU::Vertex::create(this->area.size.width, 0));
this->display->vertex2 = matrix.apply_to(GPU::Vertex::create(0, this->area.size.height)); this->display->vertex2 = matrix.apply_to(GPU::Vertex::create(0, this->area.size.height));
this->display->vertex3 = matrix.apply_to(GPU::Vertex::create(this->area.size.width, this->area.size.height)); this->display->vertex3 = matrix.apply_to(GPU::Vertex::create(this->area.size.width, this->area.size.height));
} }
void render() { void render() {
GPU::render(this->display); GPU::render(this->display);
} }
}; };
} }

View File

@ -1,13 +1,13 @@
#pragma once #pragma once
#include "../../../../include/asset_mgr.hpp" #include "../../../../include/asset_mgr.hpp"
#include <PSX/File/cd_file_types.hpp> #include <PSX/File/cd_file_types.hpp>
namespace GTETest { namespace GTETest {
using namespace JabyEngine; using namespace JabyEngine;
static constexpr auto JabySTARTim = SimpleTIM::create( static constexpr auto JabySTARTim = SimpleTIM::create(
// v Doenerfisch rotates so we need some space // v Doenerfisch rotates so we need some space
Assets::Main::DoenerFishInfo.tim.get_texture_x(), Assets::Main::DoenerFishInfo.tim.get_texture_y() + Assets::Main::DoenerFishInfo.size.height + 2, Assets::Main::DoenerFishInfo.tim.get_texture_x(), Assets::Main::DoenerFishInfo.tim.get_texture_y() + Assets::Main::DoenerFishInfo.size.height + 2,
Assets::Main::DoenerFishInfo.tim.get_clut_x() + 16, Assets::Main::DoenerFishInfo.tim.get_clut_y() Assets::Main::DoenerFishInfo.tim.get_clut_x() + 16, Assets::Main::DoenerFishInfo.tim.get_clut_y()
); );
} }

View File

@ -1,38 +1,38 @@
#pragma once #pragma once
#include <PSX/File/cd_file_types.hpp> #include <PSX/File/cd_file_types.hpp>
namespace BIOSInfo { namespace BIOSInfo {
void main(); void main();
} }
namespace ControllerTest { namespace ControllerTest {
extern const volatile JabyEngine::AutoLBAEntry lba[]; extern const volatile JabyEngine::AutoLBAEntry lba[];
extern JabyEngine::CDFile Assets[1]; extern JabyEngine::CDFile Assets[1];
void main(); void main();
} }
namespace GPUTest { namespace GPUTest {
extern const volatile JabyEngine::AutoLBAEntry lba[]; extern const volatile JabyEngine::AutoLBAEntry lba[];
extern JabyEngine::CDFile Assets[2]; extern JabyEngine::CDFile Assets[2];
extern JabyEngine::CDFile LargeAssets[36]; extern JabyEngine::CDFile LargeAssets[36];
void main(); void main();
} }
namespace GTETest { namespace GTETest {
extern const volatile JabyEngine::AutoLBAEntry lba[]; extern const volatile JabyEngine::AutoLBAEntry lba[];
extern JabyEngine::CDFile Assets[1]; extern JabyEngine::CDFile Assets[1];
void main(); void main();
} }
namespace FontCycler { namespace FontCycler {
void main(); void main();
} }
namespace ScreenCenter { namespace ScreenCenter {
extern const volatile JabyEngine::AutoLBAEntry lba[]; extern const volatile JabyEngine::AutoLBAEntry lba[];
extern JabyEngine::CDFile Assets[1]; extern JabyEngine::CDFile Assets[1];
void main(); void main();
} }

View File

@ -1,5 +1,5 @@
#include "include/frame.hpp" #include "include/frame.hpp"
#include <PSX/GPU/gpu.hpp> #include <PSX/GPU/gpu.hpp>
namespace ScreenCenter { namespace ScreenCenter {
} }

View File

@ -1,107 +1,107 @@
#pragma once #pragma once
#include <PSX/GPU/gpu.hpp> #include <PSX/GPU/gpu.hpp>
#include <PSX/GPU/make_gpu_primitives.hpp> #include <PSX/GPU/make_gpu_primitives.hpp>
#include <PSX/System/IOPorts/dma_io.hpp> #include <PSX/System/IOPorts/dma_io.hpp>
namespace ScreenCenter { namespace ScreenCenter {
using namespace JabyEngine; using namespace JabyEngine;
class Frame { class Frame {
private: private:
struct TopBorder : public GPU::internal::LinkedElementCreator<TopBorder> { struct TopBorder : public GPU::internal::LinkedElementCreator<TopBorder> {
GPU::TILE top_left[2]; GPU::TILE top_left[2];
GPU::TILE top_right[2]; GPU::TILE top_right[2];
static constexpr TopBorder::Linked create(GPU::Color24 BaseColor, GPU::SizeI16 Size) { static constexpr TopBorder::Linked create(GPU::Color24 BaseColor, GPU::SizeI16 Size) {
TopBorder frame; TopBorder frame;
frame.top_left[0] = Make::TILE(Make::AreaI16(0, 0, Size.width, Size.height), BaseColor); frame.top_left[0] = Make::TILE(Make::AreaI16(0, 0, Size.width, Size.height), BaseColor);
frame.top_left[1] = Make::TILE(Make::AreaI16(0, 0, Size.height, Size.width), BaseColor); frame.top_left[1] = Make::TILE(Make::AreaI16(0, 0, Size.height, Size.width), BaseColor);
frame.top_right[0] = Make::TILE(Make::AreaI16(GPU::Display::Width - Size.width, 0, Size.width, Size.height), BaseColor); frame.top_right[0] = Make::TILE(Make::AreaI16(GPU::Display::Width - Size.width, 0, Size.width, Size.height), BaseColor);
frame.top_right[1] = Make::TILE(Make::AreaI16(GPU::Display::Width - Size.height, 0, Size.height, Size.width), BaseColor); frame.top_right[1] = Make::TILE(Make::AreaI16(GPU::Display::Width - Size.height, 0, Size.height, Size.width), BaseColor);
return frame.linked(); return frame.linked();
} }
}; };
struct BottomBorder : GPU::internal::LinkedElementCreator<BottomBorder> { struct BottomBorder : GPU::internal::LinkedElementCreator<BottomBorder> {
GPU::TILE bottom_left[2]; GPU::TILE bottom_left[2];
GPU::TILE bottom_right[2]; GPU::TILE bottom_right[2];
static constexpr BottomBorder::Linked create(GPU::Color24 BaseColor, GPU::SizeI16 Size) { static constexpr BottomBorder::Linked create(GPU::Color24 BaseColor, GPU::SizeI16 Size) {
BottomBorder frame; BottomBorder frame;
frame.bottom_left[0] = Make::TILE(Make::AreaI16(0, GPU::Display::Height - Size.width, Size.height, Size.width), BaseColor); frame.bottom_left[0] = Make::TILE(Make::AreaI16(0, GPU::Display::Height - Size.width, Size.height, Size.width), BaseColor);
frame.bottom_left[1] = Make::TILE(Make::AreaI16(0, GPU::Display::Height - Size.height, Size.width, Size.height), BaseColor); frame.bottom_left[1] = Make::TILE(Make::AreaI16(0, GPU::Display::Height - Size.height, Size.width, Size.height), BaseColor);
frame.bottom_right[0] = Make::TILE(Make::AreaI16(GPU::Display::Width - Size.height, GPU::Display::Height - Size.width, Size.height, Size.width), BaseColor); frame.bottom_right[0] = Make::TILE(Make::AreaI16(GPU::Display::Width - Size.height, GPU::Display::Height - Size.width, Size.height, Size.width), BaseColor);
frame.bottom_right[1] = Make::TILE(Make::AreaI16(GPU::Display::Width - Size.width, GPU::Display::Height - Size.height, Size.width, Size.height), BaseColor); frame.bottom_right[1] = Make::TILE(Make::AreaI16(GPU::Display::Width - Size.width, GPU::Display::Height - Size.height, Size.width, Size.height), BaseColor);
return frame.linked(); return frame.linked();
} }
}; };
struct LineBorder : GPU::internal::LinkedElementCreator<LineBorder> { struct LineBorder : GPU::internal::LinkedElementCreator<LineBorder> {
GPU::LINE_G_MULTI<5> border; GPU::LINE_G_MULTI<5> border;
static constexpr LineBorder::Linked create(int16_t offset = 0) { static constexpr LineBorder::Linked create(int16_t offset = 0) {
const auto get_color = [](size_t idx, int16_t offset) -> GPU::Color24 { const auto get_color = [](size_t idx, int16_t offset) -> GPU::Color24 {
const GPU::Color24 Colors[4] = {GPU::Color24::Red(), GPU::Color24::Green(), GPU::Color24::Blue(), GPU::Color24::Yellow()}; const GPU::Color24 Colors[4] = {GPU::Color24::Red(), GPU::Color24::Green(), GPU::Color24::Blue(), GPU::Color24::Yellow()};
return Colors[(idx + offset)%4]; return Colors[(idx + offset)%4];
}; };
const int16_t origin = 0 + offset; const int16_t origin = 0 + offset;
const int16_t width = GPU::Display::Width - 1 - offset; const int16_t width = GPU::Display::Width - 1 - offset;
const int16_t height = GPU::Display::Height - 1 - offset; const int16_t height = GPU::Display::Height - 1 - offset;
LineBorder frame; LineBorder frame;
frame.border = Make::LINE_G( frame.border = Make::LINE_G(
GPU::ColorVertex{get_color(0, offset), Make::Vertex(origin, origin)}, GPU::ColorVertex{get_color(0, offset), Make::Vertex(origin, origin)},
GPU::ColorVertex{get_color(1, offset), Make::Vertex(origin, height)}, GPU::ColorVertex{get_color(1, offset), Make::Vertex(origin, height)},
GPU::ColorVertex{get_color(2, offset), Make::Vertex(width, height)}, GPU::ColorVertex{get_color(2, offset), Make::Vertex(width, height)},
GPU::ColorVertex{get_color(3, offset), Make::Vertex(width, origin)}, GPU::ColorVertex{get_color(3, offset), Make::Vertex(width, origin)},
GPU::ColorVertex{get_color(4, offset), Make::Vertex(origin, origin)} GPU::ColorVertex{get_color(4, offset), Make::Vertex(origin, origin)}
); );
return frame.linked(); return frame.linked();
} }
}; };
struct LineCross : GPU::internal::LinkedElementCreator<LineCross> { struct LineCross : GPU::internal::LinkedElementCreator<LineCross> {
GPU::LINE_G_SINGLE cross[2]; GPU::LINE_G_SINGLE cross[2];
static constexpr LineCross::Linked create(const decltype(LineBorder::border)& border) { static constexpr LineCross::Linked create(const decltype(LineBorder::border)& border) {
LineCross frame; LineCross frame;
frame.cross[0] = Make::LINE_G(border[0], border[2]); frame.cross[0] = Make::LINE_G(border[0], border[2]);
frame.cross[1] = Make::LINE_G(border[3], border[1]); frame.cross[1] = Make::LINE_G(border[3], border[1]);
return frame.linked(); return frame.linked();
} }
}; };
TopBorder::Linked top_border; TopBorder::Linked top_border;
BottomBorder::Linked bottom_border; BottomBorder::Linked bottom_border;
LineBorder::Linked line_border[2]; LineBorder::Linked line_border[2];
LineCross::Linked line_cross; LineCross::Linked line_cross;
public: public:
static constexpr Frame create() { static constexpr Frame create() {
constexpr auto BaseColor = GPU::Color24::from_rgb(0x1D, 0xA0, 0xA3); constexpr auto BaseColor = GPU::Color24::from_rgb(0x1D, 0xA0, 0xA3);
constexpr auto Size = Make::SizeI16(64, 16); constexpr auto Size = Make::SizeI16(64, 16);
Frame frame; Frame frame;
frame.top_border = TopBorder::create(BaseColor, Size); frame.top_border = TopBorder::create(BaseColor, Size);
frame.bottom_border = BottomBorder::create(BaseColor, Size); frame.bottom_border = BottomBorder::create(BaseColor, Size);
frame.line_border[0] = LineBorder::create(); frame.line_border[0] = LineBorder::create();
frame.line_border[1] = LineBorder::create(1); frame.line_border[1] = LineBorder::create(1);
frame.line_cross = LineCross::create(frame.line_border[0]->border); frame.line_cross = LineCross::create(frame.line_border[0]->border);
return frame; return frame;
} }
void setup() { void setup() {
this->top_border.concat(this->bottom_border.concat(this->line_border[0].concat(this->line_border[1].concat(this->line_cross)))); this->top_border.concat(this->bottom_border.concat(this->line_border[0].concat(this->line_border[1].concat(this->line_cross))));
} }
void render() const { void render() const {
GPU::render(this->top_border); GPU::render(this->top_border);
} }
}; };
} }

View File

@ -1,209 +1,209 @@
#include "../../../include/shared.hpp" #include "../../../include/shared.hpp"
#include "include/frame.hpp" #include "include/frame.hpp"
#include <FontWriter/fonts.hpp> #include <FontWriter/fonts.hpp>
#include <PSX/GPU/gpu.hpp> #include <PSX/GPU/gpu.hpp>
#include <PSX/GPU/make_gpu_primitives.hpp> #include <PSX/GPU/make_gpu_primitives.hpp>
#include <PSX/Periphery/periphery.hpp> #include <PSX/Periphery/periphery.hpp>
#include <PSX/Timer/frame_timer.hpp> #include <PSX/Timer/frame_timer.hpp>
namespace ScreenCenter { namespace ScreenCenter {
using namespace JabyEngine; using namespace JabyEngine;
using GenericButton = Periphery::GenericController::Button; using GenericButton = Periphery::GenericController::Button;
struct ButtonPulser { struct ButtonPulser {
static constexpr auto StartTime = 2500_ms; static constexpr auto StartTime = 2500_ms;
static constexpr auto PulseTime = 100_ms; static constexpr auto PulseTime = 100_ms;
enum struct State { enum struct State {
WentDown, WentDown,
Pulse, Pulse,
Unkown Unkown
}; };
SimpleTimer<uint8_t> timer; SimpleTimer<uint8_t> timer;
uint8_t pulse_time; uint8_t pulse_time;
void setup() { void setup() {
this->timer.reset(); this->timer.reset();
this->pulse_time = StartTime; this->pulse_time = StartTime;
} }
void reset() { void reset() {
ButtonPulser::setup(); ButtonPulser::setup();
} }
State check(GenericButton button) { State check(GenericButton button) {
const auto controller = Periphery::get_primary_controller_as<Periphery::GenericController>(); const auto controller = Periphery::get_primary_controller_as<Periphery::GenericController>();
if(!controller.button.was_down(button)) { if(!controller.button.was_down(button)) {
ButtonPulser::reset(); ButtonPulser::reset();
if(controller.button.went_down(button)) { if(controller.button.went_down(button)) {
return State::WentDown; return State::WentDown;
} }
} }
if(this->timer.is_expired_for(this->pulse_time)) { if(this->timer.is_expired_for(this->pulse_time)) {
this->pulse_time = PulseTime; this->pulse_time = PulseTime;
this->timer.reset(); this->timer.reset();
return State::Pulse; return State::Pulse;
} }
return State::Unkown; return State::Unkown;
} }
}; };
#ifdef JABYENGINE_PAL #ifdef JABYENGINE_PAL
static const char TVModeStr[] = "PAL"; static const char TVModeStr[] = "PAL";
static constexpr uint16_t ScanlinesV = 288; static constexpr uint16_t ScanlinesV = 288;
#else #else
static const char TVModeStr[] = "NTSC"; static const char TVModeStr[] = "NTSC";
static constexpr uint16_t ScanlinesV = 240; static constexpr uint16_t ScanlinesV = 240;
#endif //JABYENGINE_PAL #endif //JABYENGINE_PAL
namespace PSYQ { namespace PSYQ {
static const char*const Name = "PSYQ"; static const char*const Name = "PSYQ";
static void set_offset(uint16_t x, uint16_t y) { static void set_offset(uint16_t x, uint16_t y) {
GPU::Display::set_offset(x, y); GPU::Display::set_offset(x, y);
} }
} }
struct Formular { struct Formular {
const char* name; const char* name;
void (*function)(uint16_t, uint16_t); void (*function)(uint16_t, uint16_t);
}; };
static const Formular ScreenFormulars[] = { static const Formular ScreenFormulars[] = {
Formular{.name = PSYQ::Name, .function = PSYQ::set_offset} Formular{.name = PSYQ::Name, .function = PSYQ::set_offset}
}; };
static constexpr const GPU::VRAM2VRAM background_img[] = { static constexpr const GPU::VRAM2VRAM background_img[] = {
// current_id of 0 will be rendering on (0, 256) // current_id of 0 will be rendering on (0, 256)
GPU::VRAM2VRAM::create(Make::AreaU16(384, 240, 256, 240), Make::PositionU16(32, GPU::Display::Height)), GPU::VRAM2VRAM::create(Make::AreaU16(384, 240, 256, 240), Make::PositionU16(32, GPU::Display::Height)),
GPU::VRAM2VRAM::create(Make::AreaU16(384, 240, 256, 240), Make::PositionU16(32, 0)), GPU::VRAM2VRAM::create(Make::AreaU16(384, 240, 256, 240), Make::PositionU16(32, 0)),
}; };
static auto frame = Frame::create(); static auto frame = Frame::create();
static ButtonPulser button_pulse[4]; static ButtonPulser button_pulse[4];
static void (*update)() = nullptr; static void (*update)() = nullptr;
static int16_t offset_x = 0; static int16_t offset_x = 0;
static int16_t offset_y = 0; static int16_t offset_y = 0;
static uint8_t formular_sel = 0; static uint8_t formular_sel = 0;
static void update_interactive(); static void update_interactive();
static void reset_screen(); static void reset_screen();
static void update_enter_state() { static void update_enter_state() {
static const char IntroductionTest[] = "Press START to begin with\n"; static const char IntroductionTest[] = "Press START to begin with\n";
static constexpr auto IntroductionTestLength = BIOSFont::Info.estimate_str_render_length(IntroductionTest); static constexpr auto IntroductionTestLength = BIOSFont::Info.estimate_str_render_length(IntroductionTest);
static constexpr auto CenterPoint = Make::PositionI16((GPU::Display::Width - IntroductionTestLength)/2, (GPU::Display::Height - (2*16))/2); static constexpr auto CenterPoint = Make::PositionI16((GPU::Display::Width - IntroductionTestLength)/2, (GPU::Display::Height - (2*16))/2);
const auto controller = Periphery::get_primary_controller_as<Periphery::GenericController>(); const auto controller = Periphery::get_primary_controller_as<Periphery::GenericController>();
if(controller.button.went_up(GenericButton::R1) || controller.button.went_up(GenericButton::L1)) { if(controller.button.went_up(GenericButton::R1) || controller.button.went_up(GenericButton::L1)) {
// Only one mode supported // Only one mode supported
//formular_sel ^= 1; //formular_sel ^= 1;
} }
if(controller.button.went_down(GenericButton::ST)) { if(controller.button.went_down(GenericButton::ST)) {
update = update_interactive; update = update_interactive;
} }
auto cursor = FontWriter::update(CenterPoint); auto cursor = FontWriter::update(CenterPoint);
FontWriter::bios_font_writer.write(cursor, IntroductionTest, GPU::Color24::White()); FontWriter::bios_font_writer.write(cursor, IntroductionTest, GPU::Color24::White());
FontWriter::bios_font_writer.write(cursor, ScreenFormulars[formular_sel].name, GPU::Color24::White()); FontWriter::bios_font_writer.write(cursor, ScreenFormulars[formular_sel].name, GPU::Color24::White());
} }
static void update_interactive() { static void update_interactive() {
static const auto handle_button = [](ButtonPulser& button_pulse, GenericButton button, int16_t &dst, const int16_t mlp) { static const auto handle_button = [](ButtonPulser& button_pulse, GenericButton button, int16_t &dst, const int16_t mlp) {
switch(button_pulse.check(button)) { switch(button_pulse.check(button)) {
case ButtonPulser::State::WentDown: case ButtonPulser::State::WentDown:
dst += (1*mlp); dst += (1*mlp);
break; break;
case ButtonPulser::State::Pulse: case ButtonPulser::State::Pulse:
dst += (2*mlp); dst += (2*mlp);
break; break;
} }
}; };
static const char*const ModeStr = "TV-Mode: %s\n"; static const char*const ModeStr = "TV-Mode: %s\n";
static const char*const FormularStr = "<<%s>>\n"; static const char*const FormularStr = "<<%s>>\n";
static const char OffsetStr[] = "Offset: %i, %i"; static const char OffsetStr[] = "Offset: %i, %i";
static constexpr auto CenterLength = FontWriter::BIOSFont::Info.estimate_str_render_length(OffsetStr); static constexpr auto CenterLength = FontWriter::BIOSFont::Info.estimate_str_render_length(OffsetStr);
static constexpr auto CenterPoint = Make::PositionI16((GPU::Display::Width - CenterLength)/2, (GPU::Display::Height - 3*16)/2); static constexpr auto CenterPoint = Make::PositionI16((GPU::Display::Width - CenterLength)/2, (GPU::Display::Height - 3*16)/2);
const auto& screen_formular = ScreenFormulars[formular_sel]; const auto& screen_formular = ScreenFormulars[formular_sel];
const auto controller = Periphery::get_primary_controller_as<Periphery::GenericController>(); const auto controller = Periphery::get_primary_controller_as<Periphery::GenericController>();
handle_button(button_pulse[0], GenericButton::Left, offset_x, -1); handle_button(button_pulse[0], GenericButton::Left, offset_x, -1);
handle_button(button_pulse[1], GenericButton::Right, offset_x, 1); handle_button(button_pulse[1], GenericButton::Right, offset_x, 1);
handle_button(button_pulse[2], GenericButton::Up, offset_y, -1); handle_button(button_pulse[2], GenericButton::Up, offset_y, -1);
handle_button(button_pulse[3], GenericButton::Down, offset_y, 1); handle_button(button_pulse[3], GenericButton::Down, offset_y, 1);
if(controller.button.is_down(GenericButton::R1) && controller.button.is_down(GenericButton::L1)) { if(controller.button.is_down(GenericButton::R1) && controller.button.is_down(GenericButton::L1)) {
for(auto& pulse : button_pulse) { for(auto& pulse : button_pulse) {
pulse.setup(); pulse.setup();
} }
reset_screen(); reset_screen();
} }
auto cursor = FontWriter::update(CenterPoint.move(-offset_x, -offset_y)); auto cursor = FontWriter::update(CenterPoint.move(-offset_x, -offset_y));
FontWriter::bios_font_writer.write(cursor, ModeStr, GPU::Color24::White(), TVModeStr); FontWriter::bios_font_writer.write(cursor, ModeStr, GPU::Color24::White(), TVModeStr);
FontWriter::bios_font_writer.write(cursor, FormularStr, GPU::Color24::White(), screen_formular.name); FontWriter::bios_font_writer.write(cursor, FormularStr, GPU::Color24::White(), screen_formular.name);
FontWriter::bios_font_writer.write(cursor, OffsetStr, GPU::Color24::White(), offset_x, offset_y); FontWriter::bios_font_writer.write(cursor, OffsetStr, GPU::Color24::White(), offset_x, offset_y);
screen_formular.function(offset_x, offset_y); screen_formular.function(offset_x, offset_y);
} }
static void reset_screen() { static void reset_screen() {
PSYQ::set_offset(0, 0); PSYQ::set_offset(0, 0);
offset_x = 0; offset_x = 0;
offset_y = 0; offset_y = 0;
} }
static void setup() { static void setup() {
Shared::back_menu.reset(); Shared::back_menu.reset();
frame.setup(); frame.setup();
for(auto& pulse : button_pulse) { for(auto& pulse : button_pulse) {
pulse.setup(); pulse.setup();
} }
update = update_enter_state; update = update_enter_state;
formular_sel = 0; formular_sel = 0;
offset_x = 0; offset_x = 0;
offset_y = 0; offset_y = 0;
} }
static bool update_or_exit() { static bool update_or_exit() {
Periphery::query_controller(); Periphery::query_controller();
if(Shared::back_menu.update(Make::PositionI16(0, GPU::Display::Height - 32))) { if(Shared::back_menu.update(Make::PositionI16(0, GPU::Display::Height - 32))) {
return true; return true;
} }
update(); update();
return false; return false;
} }
static void render() { static void render() {
GPU::render(background_img[GPU::Display::current_id]); GPU::render(background_img[GPU::Display::current_id]);
frame.render(); frame.render();
Shared::back_menu.render(); Shared::back_menu.render();
} }
void main() { void main() {
setup(); setup();
while(true) { while(true) {
if(update_or_exit()) { if(update_or_exit()) {
reset_screen(); reset_screen();
break; break;
} }
GPU::swap_buffers_vsync(1); GPU::swap_buffers_vsync(1);
render(); render();
} }
} }
} }

View File

@ -1,17 +1,17 @@
#include <PSX/File/Processor/cd_file_processor.hpp> #include <PSX/File/Processor/cd_file_processor.hpp>
#include <PSX/AutoLBA/auto_lba_declaration.hpp> #include <PSX/AutoLBA/auto_lba_declaration.hpp>
namespace ScreenCenter { namespace ScreenCenter {
using namespace JabyEngine; using namespace JabyEngine;
enum LBA { enum LBA {
__jabyengine_start_lba_request __jabyengine_start_lba_request
__jabyengine_request_lba_for(BG_IMAGE, "ASSETS/SAND.TIM"), __jabyengine_request_lba_for(BG_IMAGE, "ASSETS/SAND.TIM"),
__jabyengine_end_lba_request __jabyengine_end_lba_request
}; };
__declare_lba_header(LBA); __declare_lba_header(LBA);
CDFile Assets[1] = { CDFile Assets[1] = {
CDFileBuilder::sony_tim(LBA::BG_IMAGE, TIM::create()) CDFileBuilder::sony_tim(LBA::BG_IMAGE, TIM::create())
}; };
} }

View File

@ -1,299 +1,299 @@
#include "../include/asset_mgr.hpp" #include "../include/asset_mgr.hpp"
#include "include/font_writer.hpp" #include "include/font_writer.hpp"
#include "include/menu.hpp" #include "include/menu.hpp"
#include "include/paco.hpp" #include "include/paco.hpp"
#include "Overlay/Overlays.hpp" #include "Overlay/Overlays.hpp"
#include <FontWriter/fonts.hpp> #include <FontWriter/fonts.hpp>
#include <FontWriter/font_writer.hpp> #include <FontWriter/font_writer.hpp>
#include <PSX/Audio/CDDA.hpp> #include <PSX/Audio/CDDA.hpp>
#include <PSX/Audio/CDXA.hpp> #include <PSX/Audio/CDXA.hpp>
#include <PSX/Periphery/periphery.hpp> #include <PSX/Periphery/periphery.hpp>
#include <stdio.hpp> #include <stdio.hpp>
using namespace JabyEngine; using namespace JabyEngine;
using DigitalButton = Periphery::GenericController::Button; using DigitalButton = Periphery::GenericController::Button;
struct CDPlayer { struct CDPlayer {
static constexpr auto MaxChannels = 2; static constexpr auto MaxChannels = 2;
uint8_t channel; uint8_t channel;
bool is_xa; bool is_xa;
static constexpr CDPlayer create() { static constexpr CDPlayer create() {
return CDPlayer{.channel = 0, .is_xa = true}; return CDPlayer{.channel = 0, .is_xa = true};
} }
void play() { void play() {
if(this->is_xa) { if(this->is_xa) {
Assets::XAAudio::play_mix(); Assets::XAAudio::play_mix();
} }
else { else {
const auto [first_track, last_track] = CDDA::get_tracks(); const auto [first_track, last_track] = CDDA::get_tracks();
CDDA::play(first_track); CDDA::play(first_track);
} }
} }
void stop() { void stop() {
if(this->is_xa) { if(this->is_xa) {
CDXA::stop(); CDXA::stop();
} }
else { else {
CDDA::stop(); CDDA::stop();
} }
} }
void change_channel(int8_t step) { void change_channel(int8_t step) {
if(this->is_xa) { if(this->is_xa) {
this->channel = static_cast<uint8_t>((this->channel + step))%MaxChannels; this->channel = static_cast<uint8_t>((this->channel + step))%MaxChannels;
CDXA::set_channel(this->channel); CDXA::set_channel(this->channel);
} }
} }
void change_audio() { void change_audio() {
CDPlayer::stop(); CDPlayer::stop();
this->is_xa = !this->is_xa; this->is_xa = !this->is_xa;
CDPlayer::play(); CDPlayer::play();
} }
void push() { void push() {
if(this->is_xa) { if(this->is_xa) {
CDXA::push_play(); CDXA::push_play();
} }
else { else {
CDDA::push_play(); CDDA::push_play();
} }
} }
void pop() { void pop() {
if(this->is_xa) { if(this->is_xa) {
CDXA::pop_play(); CDXA::pop_play();
} }
else { else {
CDDA::pop_play(); CDDA::pop_play();
} }
} }
}; };
struct StateChange { struct StateChange {
void (*asset_load)(); void (*asset_load)();
void (*main)(); void (*main)();
static constexpr StateChange empty() { static constexpr StateChange empty() {
return StateChange{.asset_load = nullptr, .main = nullptr}; return StateChange{.asset_load = nullptr, .main = nullptr};
} }
void clear() { void clear() {
this->asset_load = nullptr; this->asset_load = nullptr;
this->main = nullptr; this->main = nullptr;
} }
bool contains_state() const { bool contains_state() const {
return this->main; return this->main;
} }
auto operator<=>(const StateChange&) const = default; auto operator<=>(const StateChange&) const = default;
}; };
static const Menu::SimpleMenu::Entry MenuEntries[] = { static const Menu::SimpleMenu::Entry MenuEntries[] = {
{"Controller Test"}, {"Controller Test"},
{"GPU Test"}, {"GPU Test"},
{"GTE Test"}, {"GTE Test"},
{"Font Cycler"}, {"Font Cycler"},
{"Screen Center"}, {"Screen Center"},
{"BIOS Information"} {"BIOS Information"}
}; };
static const auto doener_fish = Make::SPRT( static const auto doener_fish = Make::SPRT(
Make::AreaI16(Make::PositionI16(8, GPU::Display::Height - Assets::Main::DoenerFishInfo.size.height), Assets::Main::DoenerFishInfo.size), // v this needs to be nicer! Has to be Make::AreaI16(Make::PositionI16(8, GPU::Display::Height - Assets::Main::DoenerFishInfo.size.height), Assets::Main::DoenerFishInfo.size), // v this needs to be nicer! Has to be
Make::OffsetPageWithClut(Assets::Main::DoenerFishInfo.tim.get_page_offset_clut4(), Make::PageClut(Assets::Main::DoenerFishInfo.tim.get_clut_position())), Make::OffsetPageWithClut(Assets::Main::DoenerFishInfo.tim.get_page_offset_clut4(), Make::PageClut(Assets::Main::DoenerFishInfo.tim.get_clut_position())),
GPU::Color24::Grey() GPU::Color24::Grey()
); );
static CDPlayer cd_player = CDPlayer::create(); static CDPlayer cd_player = CDPlayer::create();
static object::Paco paco; static object::Paco paco;
static Menu::SimpleMenu menu; static Menu::SimpleMenu menu;
static StateChange state_changer; static StateChange state_changer;
static StateChange old_state_changer; static StateChange old_state_changer;
namespace Shared { namespace Shared {
Menu::BackMenu back_menu; Menu::BackMenu back_menu;
JabyEngine::GPU::POLY_G4 background = Make::POLY_G4( JabyEngine::GPU::POLY_G4 background = Make::POLY_G4(
Make::AreaI16(0, 0, GPU::Display::Width, GPU::Display::Height), Make::AreaI16(0, 0, GPU::Display::Width, GPU::Display::Height),
{GPU::Color24::Red(0xA0), GPU::Color24::Green(0xA0), GPU::Color24::Blue(0xA0), GPU::Color24::Black()} {GPU::Color24::Red(0xA0), GPU::Color24::Green(0xA0), GPU::Color24::Blue(0xA0), GPU::Color24::Black()}
); );
bool load_test = false; bool load_test = false;
} }
static void setup() { static void setup() {
Assets::Main::load(); Assets::Main::load();
FontWriter::setup(); FontWriter::setup();
paco.setup(); paco.setup();
Shared::back_menu.setup(&FontWriter::bios_font_writer); Shared::back_menu.setup(&FontWriter::bios_font_writer);
menu.setup([](uint32_t selection) { menu.setup([](uint32_t selection) {
switch(selection) { switch(selection) {
case 0: case 0:
state_changer.asset_load = Assets::Overlay::load_controller_test; state_changer.asset_load = Assets::Overlay::load_controller_test;
state_changer.main = ControllerTest::main; state_changer.main = ControllerTest::main;
break; break;
case 1: case 1:
state_changer.asset_load = Assets::Overlay::load_gpu_test; state_changer.asset_load = Assets::Overlay::load_gpu_test;
state_changer.main = GPUTest::main; state_changer.main = GPUTest::main;
break; break;
case 2: case 2:
state_changer.asset_load = Assets::Overlay::load_gte_test; state_changer.asset_load = Assets::Overlay::load_gte_test;
state_changer.main = GTETest::main; state_changer.main = GTETest::main;
break; break;
case 3: case 3:
state_changer.asset_load = Assets::Overlay::load_font_cycler; state_changer.asset_load = Assets::Overlay::load_font_cycler;
state_changer.main = FontCycler::main; state_changer.main = FontCycler::main;
break; break;
case 4: case 4:
state_changer.asset_load = Assets::Overlay::load_screen_center; state_changer.asset_load = Assets::Overlay::load_screen_center;
state_changer.main = ScreenCenter::main; state_changer.main = ScreenCenter::main;
break; break;
case 5: case 5:
state_changer.asset_load = Assets::Overlay::load_bios_info; state_changer.asset_load = Assets::Overlay::load_bios_info;
state_changer.main = BIOSInfo::main; state_changer.main = BIOSInfo::main;
break; break;
} }
},MenuEntries); },MenuEntries);
cd_player.play(); cd_player.play();
} }
namespace NormalScene { namespace NormalScene {
static void update() { static void update() {
static const char Title[] = ">> Pool Box <<"; static const char Title[] = ">> Pool Box <<";
static const char Version[] = "Ver. 0.9.0"; static const char Version[] = "Ver. 0.9.0";
static constexpr auto TitleLength = DefaultFont::Info.estimate_str_render_length(Title); static constexpr auto TitleLength = DefaultFont::Info.estimate_str_render_length(Title);
static constexpr auto VersionLength = DefaultFont::Info.estimate_str_render_length(Version); static constexpr auto VersionLength = DefaultFont::Info.estimate_str_render_length(Version);
Periphery::query_controller(); Periphery::query_controller();
const auto& controller = Periphery::get_primary_controller_as<JabyEngine::Periphery::GenericController>(); const auto& controller = Periphery::get_primary_controller_as<JabyEngine::Periphery::GenericController>();
if(controller.is_connected()) { if(controller.is_connected()) {
if(controller.button.went_down(DigitalButton::SEL)) { if(controller.button.went_down(DigitalButton::SEL)) {
cd_player.change_audio(); cd_player.change_audio();
} }
if(controller.button.went_down(DigitalButton::R1)) { if(controller.button.went_down(DigitalButton::R1)) {
cd_player.change_channel(1); cd_player.change_channel(1);
} }
if(controller.button.went_down(DigitalButton::L1)) { if(controller.button.went_down(DigitalButton::L1)) {
cd_player.change_channel(-1); cd_player.change_channel(-1);
} }
// Trigger load test // Trigger load test
if(controller.button.is_down(DigitalButton::R2) && controller.button.is_down(DigitalButton::L2) && controller.button.is_down(DigitalButton::ST)) { if(controller.button.is_down(DigitalButton::R2) && controller.button.is_down(DigitalButton::L2) && controller.button.is_down(DigitalButton::ST)) {
Shared::load_test = true; Shared::load_test = true;
} }
} }
auto cursor = FontWriter::update(Make::PositionI16((GPU::Display::Width-TitleLength)/2, 16)); auto cursor = FontWriter::update(Make::PositionI16((GPU::Display::Width-TitleLength)/2, 16));
paco.update(); paco.update();
FontWriter::new_font_writer.write(cursor, Title, GPU::Color24::Yellow(0xD0), &FontWriter::wiggle); FontWriter::new_font_writer.write(cursor, Title, GPU::Color24::Yellow(0xD0), &FontWriter::wiggle);
FontWriter::new_font_writer.write(cursor.change_position(Make::PositionI16((GPU::Display::Width-VersionLength)/2, 16 + DefaultFont::Info.get_kern_size().height)), Version, GPU::Color24::Green(0xD0), &FontWriter::wiggle); FontWriter::new_font_writer.write(cursor.change_position(Make::PositionI16((GPU::Display::Width-VersionLength)/2, 16 + DefaultFont::Info.get_kern_size().height)), Version, GPU::Color24::Green(0xD0), &FontWriter::wiggle);
menu.update(FontWriter::bios_font_writer, cursor, Make::PositionI16(8, 64)); menu.update(FontWriter::bios_font_writer, cursor, Make::PositionI16(8, 64));
cursor.change_position(Make::PositionI16(doener_fish.position.x + doener_fish.size.width, GPU::Display::Height - 48)); cursor.change_position(Make::PositionI16(doener_fish.position.x + doener_fish.size.width, GPU::Display::Height - 48));
FontWriter::bios_font_writer.write(cursor, "Audio:\n%s\n(SEL/R1/R2)", cd_player.is_xa ? "CD-XA" : "CD-DA"); FontWriter::bios_font_writer.write(cursor, "Audio:\n%s\n(SEL/R1/R2)", cd_player.is_xa ? "CD-XA" : "CD-DA");
if(Shared::load_test) { if(Shared::load_test) {
// Force state change if we are in the load_test state // Force state change if we are in the load_test state
state_changer.asset_load = Assets::Overlay::load_large_gpu_test; state_changer.asset_load = Assets::Overlay::load_large_gpu_test;
state_changer.main = GPUTest::main; state_changer.main = GPUTest::main;
} }
} }
static void render() { static void render() {
GPU::render(Shared::background); GPU::render(Shared::background);
FontWriter::new_font_writer.render(); FontWriter::new_font_writer.render();
FontWriter::bios_font_writer.render(); FontWriter::bios_font_writer.render();
paco.render(); paco.render();
GPU::render(doener_fish); GPU::render(doener_fish);
} }
static void run() { static void run() {
update(); update();
GPU::swap_buffers_vsync(1); GPU::swap_buffers_vsync(1);
render(); render();
} }
} }
namespace LoadingScene { namespace LoadingScene {
static SimpleTimer<uint8_t> jaby_timer; static SimpleTimer<uint8_t> jaby_timer;
static uint8_t jaby_frame_offset; static uint8_t jaby_frame_offset;
static void update() { static void update() {
jaby_timer.reset(); jaby_timer.reset();
jaby_frame_offset = 0; jaby_frame_offset = 0;
} }
static void vsync_render() { static void vsync_render() {
static constexpr auto StartPosition = Make::PositionI16(24, 64); static constexpr auto StartPosition = Make::PositionI16(24, 64);
const auto load_font = Make::SPRT( const auto load_font = Make::SPRT(
Make::AreaI16(StartPosition.move(Assets::Main::JabyLoader::JabyFrame.size.width + 8, 0), Assets::Main::JabyLoader::FontFrame.size), Make::AreaI16(StartPosition.move(Assets::Main::JabyLoader::JabyFrame.size.width + 8, 0), Assets::Main::JabyLoader::FontFrame.size),
Make::OffsetPageWithClut(Assets::Main::JabyLoader::TIMLoaction.get_page_offset_clut4().move(Assets::Main::JabyLoader::FontFrame.position.x, Assets::Main::JabyLoader::FontFrame.position.y), Make::PageClut(Assets::Main::JabyLoader::TIMLoaction.get_clut_position())), Make::OffsetPageWithClut(Assets::Main::JabyLoader::TIMLoaction.get_page_offset_clut4().move(Assets::Main::JabyLoader::FontFrame.position.x, Assets::Main::JabyLoader::FontFrame.position.y), Make::PageClut(Assets::Main::JabyLoader::TIMLoaction.get_clut_position())),
GPU::Color24::Grey() GPU::Color24::Grey()
); );
auto jaby_sprt = Make::SPRT( auto jaby_sprt = Make::SPRT(
Make::AreaI16(StartPosition, Assets::Main::JabyLoader::JabyFrame.size), Make::AreaI16(StartPosition, Assets::Main::JabyLoader::JabyFrame.size),
Make::OffsetPageWithClut(Assets::Main::JabyLoader::TIMLoaction.get_page_offset_clut4(), Make::PageClut(Assets::Main::JabyLoader::TIMLoaction.get_clut_position())), Make::OffsetPageWithClut(Assets::Main::JabyLoader::TIMLoaction.get_page_offset_clut4(), Make::PageClut(Assets::Main::JabyLoader::TIMLoaction.get_clut_position())),
GPU::Color24::Grey() GPU::Color24::Grey()
); );
if(jaby_timer.is_expired_for(500_ms)) { if(jaby_timer.is_expired_for(500_ms)) {
jaby_frame_offset = jaby_frame_offset ? 0 : 32; jaby_frame_offset = jaby_frame_offset ? 0 : 32;
jaby_timer.reset(); jaby_timer.reset();
} }
jaby_sprt.tex_offset.add(jaby_frame_offset, 0); jaby_sprt.tex_offset.add(jaby_frame_offset, 0);
GPU::swap_buffers(!Shared::load_test); GPU::swap_buffers(!Shared::load_test);
GPU::render(jaby_sprt); GPU::render(jaby_sprt);
GPU::render(load_font); GPU::render(load_font);
jaby_sprt.position.move(Assets::Main::JabyLoader::FontFrame.size.width + Assets::Main::JabyLoader::JabyFrame.size.width + 8, 0); jaby_sprt.position.move(Assets::Main::JabyLoader::FontFrame.size.width + Assets::Main::JabyLoader::JabyFrame.size.width + 8, 0);
GPU::render(jaby_sprt); GPU::render(jaby_sprt);
} }
static void run() { static void run() {
if(Shared::load_test || old_state_changer != state_changer) { if(Shared::load_test || old_state_changer != state_changer) {
GPU::set_vsync_callback(vsync_render); GPU::set_vsync_callback(vsync_render);
cd_player.push(); cd_player.push();
state_changer.asset_load(); state_changer.asset_load();
old_state_changer = state_changer; old_state_changer = state_changer;
cd_player.pop(); cd_player.pop();
GPU::set_vsync_callback(nullptr); GPU::set_vsync_callback(nullptr);
} }
state_changer.main(); state_changer.main();
state_changer.clear(); state_changer.clear();
} }
} }
void main() { void main() {
const auto& controller = Periphery::get_primary_controller_as<JabyEngine::Periphery::GenericController>(); const auto& controller = Periphery::get_primary_controller_as<JabyEngine::Periphery::GenericController>();
setup(); setup();
while(true) { while(true) {
if(state_changer.contains_state()) { if(state_changer.contains_state()) {
LoadingScene::run(); LoadingScene::run();
} }
else { else {
NormalScene::run(); NormalScene::run();
} }
} }
} }

View File

@ -1,135 +1,135 @@
#include "../include/asset_mgr.hpp" #include "../include/asset_mgr.hpp"
#include "Custom/custom_files.hpp" #include "Custom/custom_files.hpp"
#include "Overlay/Overlays.hpp" #include "Overlay/Overlays.hpp"
#include <PSX/Audio/CDXA.hpp> #include <PSX/Audio/CDXA.hpp>
#include <PSX/AutoLBA/auto_lba.hpp> #include <PSX/AutoLBA/auto_lba.hpp>
#include <PSX/AutoLBA/auto_lba_declaration.hpp> #include <PSX/AutoLBA/auto_lba_declaration.hpp>
#include <PSX/File/Processor/cd_file_processor.hpp> #include <PSX/File/Processor/cd_file_processor.hpp>
#include <stdio.hpp> #include <stdio.hpp>
extern "C" uint32_t __bios_info_start; extern "C" uint32_t __bios_info_start;
extern "C" uint32_t __controller_tests_start; extern "C" uint32_t __controller_tests_start;
extern "C" uint32_t __gpu_tests_start; extern "C" uint32_t __gpu_tests_start;
extern "C" uint32_t __gte_tests_start; extern "C" uint32_t __gte_tests_start;
extern "C" uint32_t __font_cycler_start; extern "C" uint32_t __font_cycler_start;
extern "C" uint32_t __screen_center_start; extern "C" uint32_t __screen_center_start;
namespace Assets { namespace Assets {
enum LBA { enum LBA {
__jabyengine_start_lba_request __jabyengine_start_lba_request
__jabyengine_request_lba_for(PACO, "ASSETS/MAIN/PACO.IMG"), __jabyengine_request_lba_for(PACO, "ASSETS/MAIN/PACO.IMG"),
__jabyengine_request_lba_for(DFISH, "ASSETS/MAIN/DFISH.IMG"), __jabyengine_request_lba_for(DFISH, "ASSETS/MAIN/DFISH.IMG"),
__jabyengine_request_lba_for(JABY_LOAD, "ASSETS/MAIN/LOAD.IMG"), __jabyengine_request_lba_for(JABY_LOAD, "ASSETS/MAIN/LOAD.IMG"),
__jabyengine_request_lba_for(APPLE_SFX, "SFX/APPLE.VAG"), __jabyengine_request_lba_for(APPLE_SFX, "SFX/APPLE.VAG"),
__jabyengine_request_lba_for(BLUBB_SFX, "SFX/BLUBB.VAG"), __jabyengine_request_lba_for(BLUBB_SFX, "SFX/BLUBB.VAG"),
__jabyengine_request_lba_for(FRIEND_SFX, "SFX/FRIEND.VAG"), __jabyengine_request_lba_for(FRIEND_SFX, "SFX/FRIEND.VAG"),
__jabyengine_request_lba_for(MIX_XA, "XAAUDIO/MIX.XA"), __jabyengine_request_lba_for(MIX_XA, "XAAUDIO/MIX.XA"),
__jabyengine_request_lba_for(BIOS_INFO_OVL, "BIO.BIN"), __jabyengine_request_lba_for(BIOS_INFO_OVL, "BIO.BIN"),
__jabyengine_request_lba_for(GPU_TEST_OVL, "GTO.BIN"), __jabyengine_request_lba_for(GPU_TEST_OVL, "GTO.BIN"),
__jabyengine_request_lba_for(GTE_TEST_OVL, "GTE.BIN"), __jabyengine_request_lba_for(GTE_TEST_OVL, "GTE.BIN"),
__jabyengine_request_lba_for(CONT_TEST_OVL, "CTO.BIN"), __jabyengine_request_lba_for(CONT_TEST_OVL, "CTO.BIN"),
__jabyengine_request_lba_for(FONT_CYC_OVL, "FCO.BIN"), __jabyengine_request_lba_for(FONT_CYC_OVL, "FCO.BIN"),
__jabyengine_request_lba_for(SCREEN_CENT_OVL, "SCO.BIN"), __jabyengine_request_lba_for(SCREEN_CENT_OVL, "SCO.BIN"),
__jabyengine_end_lba_request __jabyengine_end_lba_request
}; };
__declare_lba_header(LBA); __declare_lba_header(LBA);
static void load(const volatile AutoLBAEntry* lba, const CDFile* assets, size_t size) { static void load(const volatile AutoLBAEntry* lba, const CDFile* assets, size_t size) {
const auto buffer_cfg = CDFileProcessor::BufferConfiguration::new_default(); const auto buffer_cfg = CDFileProcessor::BufferConfiguration::new_default();
CDFileProcessor file_processor; CDFileProcessor file_processor;
file_processor.setup(lba, CDFileProcessor::JobArray{assets, size}, buffer_cfg); file_processor.setup(lba, CDFileProcessor::JobArray{assets, size}, buffer_cfg);
while(true) { while(true) {
switch(file_processor.process()) { switch(file_processor.process()) {
case Progress::InProgress: case Progress::InProgress:
break; break;
case Progress::Done: case Progress::Done:
if(!file_processor.next(lba, buffer_cfg)) { if(!file_processor.next(lba, buffer_cfg)) {
return; return;
} }
break; break;
case Progress::Error: case Progress::Error:
printf("Error detected! Aborting load\n"); printf("Error detected! Aborting load\n");
return; return;
} }
} }
file_processor.shutdown(); file_processor.shutdown();
} }
template<size_t N> template<size_t N>
static void load(const volatile AutoLBAEntry* lba, const CDFile (&files)[N]) { static void load(const volatile AutoLBAEntry* lba, const CDFile (&files)[N]) {
return load(lba, files, N); return load(lba, files, N);
} }
namespace Main { namespace Main {
using SPU::operator""_vol; using SPU::operator""_vol;
static const CDFile Files[] = { static const CDFile Files[] = {
CDFileBuilder::simple_tim(LBA::PACO, PacoTIM), CDFileBuilder::simple_tim(LBA::PACO, PacoTIM),
CDFileBuilder::simple_tim(LBA::DFISH, DoenerFishInfo.tim), CDFileBuilder::simple_tim(LBA::DFISH, DoenerFishInfo.tim),
CDFileBuilder::simple_tim(LBA::JABY_LOAD, JabyLoader::TIMLoaction), CDFileBuilder::simple_tim(LBA::JABY_LOAD, JabyLoader::TIMLoaction),
CDFileBuilder::sony_vag(LBA::APPLE_SFX, VAG::create(0, 1.0_vol)), CDFileBuilder::sony_vag(LBA::APPLE_SFX, VAG::create(0, 1.0_vol)),
CDFileBuilder::sony_vag(LBA::BLUBB_SFX, VAG::create(1, 1.0_vol)), CDFileBuilder::sony_vag(LBA::BLUBB_SFX, VAG::create(1, 1.0_vol)),
CDFileBuilder::sony_vag(LBA::FRIEND_SFX, VAG::create(2, 1.0_vol)), CDFileBuilder::sony_vag(LBA::FRIEND_SFX, VAG::create(2, 1.0_vol)),
CustomCDFileBuilder::jingle(2), CustomCDFileBuilder::jingle(2),
}; };
void load() { void load() {
::Assets::load(lba, Files); ::Assets::load(lba, Files);
} }
} }
namespace Overlay { namespace Overlay {
static void load(const CDFile& overlay_file, const volatile AutoLBAEntry* overlay_lba, const CDFile* overlay_assets, size_t size) { static void load(const CDFile& overlay_file, const volatile AutoLBAEntry* overlay_lba, const CDFile* overlay_assets, size_t size) {
::Assets::load(lba, &overlay_file, 1); ::Assets::load(lba, &overlay_file, 1);
if(overlay_lba) { if(overlay_lba) {
::Assets::load(overlay_lba, overlay_assets, size); ::Assets::load(overlay_lba, overlay_assets, size);
} }
} }
static void load(const CDFile& overlay_file) { static void load(const CDFile& overlay_file) {
load(overlay_file, nullptr, nullptr, 0ull); load(overlay_file, nullptr, nullptr, 0ull);
} }
template<size_t N> template<size_t N>
static void load(const CDFile& overlay_file, const volatile AutoLBAEntry* overlay_lba, const CDFile (&overlay_assets)[N]) { static void load(const CDFile& overlay_file, const volatile AutoLBAEntry* overlay_lba, const CDFile (&overlay_assets)[N]) {
load(overlay_file, overlay_lba, overlay_assets, N); load(overlay_file, overlay_lba, overlay_assets, N);
} }
void load_bios_info() { void load_bios_info() {
load(CDFileBuilder::overlay(LBA::BIOS_INFO_OVL, &__bios_info_start)); load(CDFileBuilder::overlay(LBA::BIOS_INFO_OVL, &__bios_info_start));
} }
void load_controller_test() { void load_controller_test() {
load(CDFileBuilder::overlay(LBA::CONT_TEST_OVL, &__controller_tests_start), ControllerTest::lba, ControllerTest::Assets); load(CDFileBuilder::overlay(LBA::CONT_TEST_OVL, &__controller_tests_start), ControllerTest::lba, ControllerTest::Assets);
} }
void load_gpu_test() { void load_gpu_test() {
load(CDFileBuilder::overlay(LBA::GPU_TEST_OVL, &__gpu_tests_start), GPUTest::lba, GPUTest::Assets); load(CDFileBuilder::overlay(LBA::GPU_TEST_OVL, &__gpu_tests_start), GPUTest::lba, GPUTest::Assets);
} }
void load_large_gpu_test() { void load_large_gpu_test() {
load(CDFileBuilder::overlay(LBA::GPU_TEST_OVL, &__gpu_tests_start), GPUTest::lba, GPUTest::LargeAssets); load(CDFileBuilder::overlay(LBA::GPU_TEST_OVL, &__gpu_tests_start), GPUTest::lba, GPUTest::LargeAssets);
} }
void load_gte_test() { void load_gte_test() {
load(CDFileBuilder::overlay(LBA::GTE_TEST_OVL, &__gte_tests_start), GTETest::lba, GTETest::Assets); load(CDFileBuilder::overlay(LBA::GTE_TEST_OVL, &__gte_tests_start), GTETest::lba, GTETest::Assets);
} }
void load_font_cycler() { void load_font_cycler() {
load(CDFileBuilder::overlay(LBA::FONT_CYC_OVL, &__font_cycler_start)); load(CDFileBuilder::overlay(LBA::FONT_CYC_OVL, &__font_cycler_start));
} }
void load_screen_center() { void load_screen_center() {
load(CDFileBuilder::overlay(LBA::SCREEN_CENT_OVL, &__screen_center_start), ScreenCenter::lba, ScreenCenter::Assets); load(CDFileBuilder::overlay(LBA::SCREEN_CENT_OVL, &__screen_center_start), ScreenCenter::lba, ScreenCenter::Assets);
} }
} }
namespace XAAudio { namespace XAAudio {
void play_mix() { void play_mix() {
CDXA::play(lba, MIX_XA, 0, false); CDXA::play(lba, MIX_XA, 0, false);
} }
} }
} }

View File

@ -1,35 +1,35 @@
#include "include/font_writer.hpp" #include "include/font_writer.hpp"
#include <FontWriter/fonts.hpp> #include <FontWriter/fonts.hpp>
#include <PSX/File/Processor/cd_file_processor.hpp> //< only for __heap_start D: #include <PSX/File/Processor/cd_file_processor.hpp> //< only for __heap_start D:
#include <PSX/Timer/frame_timer.hpp> #include <PSX/Timer/frame_timer.hpp>
namespace FontWriter { namespace FontWriter {
using namespace JabyEngine; using namespace JabyEngine;
static constexpr auto LibraryFontTIM = SimpleTIM::create(320, 0, 320, DefaultFont::Info.texture_size.height); static constexpr auto LibraryFontTIM = SimpleTIM::create(320, 0, 320, DefaultFont::Info.texture_size.height);
static FontPrimitive font_buffer[2*256]; static FontPrimitive font_buffer[2*256];
Wiggle wiggle = {Make::PositionI8(0, 0), Make::PositionI8(1, -2), Make::PositionI8(0, -4), Make::PositionI8(-1, -2), Make::PositionI8(0, 0), Make::PositionI8(1, 2), Make::PositionI8(0, 4), Make::PositionI8(-1, 2)}; Wiggle wiggle = {Make::PositionI8(0, 0), Make::PositionI8(1, -2), Make::PositionI8(0, -4), Make::PositionI8(-1, -2), Make::PositionI8(0, 0), Make::PositionI8(1, 2), Make::PositionI8(0, 4), Make::PositionI8(-1, 2)};
JabyEngine::FontWriter new_font_writer = JabyEngine::FontWriter::empty(); JabyEngine::FontWriter new_font_writer = JabyEngine::FontWriter::empty();
JabyEngine::FontWriter bios_font_writer = JabyEngine::FontWriter::empty(); JabyEngine::FontWriter bios_font_writer = JabyEngine::FontWriter::empty();
static SimpleTimer<uint8_t> timer; static SimpleTimer<uint8_t> timer;
uint8_t wiggle_count = 0; uint8_t wiggle_count = 0;
void setup() { void setup() {
JabyEngine::DefaultFont::load(&__heap_start, LibraryFontTIM); JabyEngine::DefaultFont::load(&__heap_start, LibraryFontTIM);
JabyEngine::GlobalFontPrimitivePool::setup(font_buffer); JabyEngine::GlobalFontPrimitivePool::setup(font_buffer);
new_font_writer.setup(LibraryFontTIM, JabyEngine::DefaultFont::Info); new_font_writer.setup(LibraryFontTIM, JabyEngine::DefaultFont::Info);
bios_font_writer.setup(JabyEngine::BIOSFont::TIM, JabyEngine::BIOSFont::Info); bios_font_writer.setup(JabyEngine::BIOSFont::TIM, JabyEngine::BIOSFont::Info);
timer.reset(); timer.reset();
} }
Cursor update(const GPU::PositionI16& start) { Cursor update(const GPU::PositionI16& start) {
if(timer.is_expired_for(50_ms)) { if(timer.is_expired_for(50_ms)) {
timer.reset(); timer.reset();
wiggle_count++; wiggle_count++;
} }
return Cursor::create(start, wiggle_count); return Cursor::create(start, wiggle_count);
} }
} }

View File

@ -1,14 +1,14 @@
#pragma once #pragma once
#include <FontWriter/Type/types.hpp> #include <FontWriter/Type/types.hpp>
#include <FontWriter/font_writer.hpp> #include <FontWriter/font_writer.hpp>
namespace FontWriter { namespace FontWriter {
using namespace JabyEngine; using namespace JabyEngine;
extern Wiggle wiggle; extern Wiggle wiggle;
extern JabyEngine::FontWriter new_font_writer; extern JabyEngine::FontWriter new_font_writer;
extern JabyEngine::FontWriter bios_font_writer; extern JabyEngine::FontWriter bios_font_writer;
void setup(); void setup();
Cursor update(const GPU::PositionI16& start); Cursor update(const GPU::PositionI16& start);
} }

View File

@ -1,50 +1,50 @@
#pragma once #pragma once
#include "font_writer.hpp" #include "font_writer.hpp"
#include <FontWriter/font_writer.hpp> #include <FontWriter/font_writer.hpp>
#include <PSX/Timer/frame_timer.hpp> #include <PSX/Timer/frame_timer.hpp>
namespace Menu { namespace Menu {
using namespace JabyEngine; using namespace JabyEngine;
class SimpleMenu { class SimpleMenu {
public: public:
struct Entry { struct Entry {
const char* name; const char* name;
}; };
typedef void (*Callback)(uint32_t selection); typedef void (*Callback)(uint32_t selection);
private: private:
Callback selection_callback; Callback selection_callback;
const Entry* entries; const Entry* entries;
size_t size; size_t size;
uint8_t cur_selection; uint8_t cur_selection;
public: public:
void setup(Callback callback, const Entry* entries, size_t size); void setup(Callback callback, const Entry* entries, size_t size);
template<size_t N> template<size_t N>
void setup(Callback callback, const Entry (&entries)[N]) { void setup(Callback callback, const Entry (&entries)[N]) {
SimpleMenu::setup(callback, entries, N); SimpleMenu::setup(callback, entries, N);
} }
void update(JabyEngine::FontWriter& font_writer, Cursor& cursor, const GPU::PositionI16& start); void update(JabyEngine::FontWriter& font_writer, Cursor& cursor, const GPU::PositionI16& start);
}; };
class BackMenu { class BackMenu {
private: private:
JabyEngine::FontWriter* font_writer; JabyEngine::FontWriter* font_writer;
SimpleTimer<uint32_t> timeout; SimpleTimer<uint32_t> timeout;
bool waiting; bool waiting;
public: public:
void setup(JabyEngine::FontWriter* font_writer); void setup(JabyEngine::FontWriter* font_writer);
void reset() { void reset() {
this->timeout.reset(); this->timeout.reset();
this->waiting = false; this->waiting = false;
} }
bool update(const GPU::PositionI16& position, bool auto_clear = true); bool update(const GPU::PositionI16& position, bool auto_clear = true);
void render(); void render();
}; };
} }

View File

@ -1,35 +1,35 @@
#pragma once #pragma once
#include "../../include/asset_mgr.hpp" #include "../../include/asset_mgr.hpp"
#include <PSX/GPU/make_gpu_primitives.hpp> #include <PSX/GPU/make_gpu_primitives.hpp>
#include <PSX/Timer/frame_timer.hpp> #include <PSX/Timer/frame_timer.hpp>
namespace object { namespace object {
using namespace JabyEngine; using namespace JabyEngine;
class Paco { class Paco {
private: private:
static constexpr auto Size = Make::SizeI16(120, 128); static constexpr auto Size = Make::SizeI16(120, 128);
static const GPU::Color24 Colors[]; static const GPU::Color24 Colors[];
GPU::TexPage::Linked tex_page; GPU::TexPage::Linked tex_page;
GPU::SPRT::Linked sprite; GPU::SPRT::Linked sprite;
SimpleTimer<uint8_t> timer; SimpleTimer<uint8_t> timer;
uint8_t color_idx; uint8_t color_idx;
public: public:
constexpr Paco() : constexpr Paco() :
tex_page(Make::TexPage(Make::PositionU16( tex_page(Make::TexPage(Make::PositionU16(
Assets::Main::PacoTIM.get_texture_x(), Assets::Main::PacoTIM.get_texture_y()), Assets::Main::PacoTIM.get_texture_x(), Assets::Main::PacoTIM.get_texture_y()),
GPU::TextureColorMode::clut4).linked()), GPU::TextureColorMode::clut4).linked()),
sprite(Make::SPRT( sprite(Make::SPRT(
Make::AreaI16(Make::PositionI16(GPU::Display::Width - Size.width, GPU::Display::Height - Size.height), Size), Make::AreaI16(Make::PositionI16(GPU::Display::Width - Size.width, GPU::Display::Height - Size.height), Size),
Make::OffsetPageWithClut(Make::PageOffset(0, 0), Make::PageClut(Assets::Main::PacoTIM.get_clut_x(), Assets::Main::PacoTIM.get_clut_y())), Make::OffsetPageWithClut(Make::PageOffset(0, 0), Make::PageClut(Assets::Main::PacoTIM.get_clut_x(), Assets::Main::PacoTIM.get_clut_y())),
GPU::Color24::Blue()).linked()), GPU::Color24::Blue()).linked()),
timer(), timer(),
color_idx(0) {} color_idx(0) {}
void setup(); void setup();
void update(); void update();
void render(); void render();
}; };
} }

View File

@ -1,81 +1,81 @@
#include "../include/shared.hpp" #include "../include/shared.hpp"
#include "include/menu.hpp" #include "include/menu.hpp"
#include <PSX/Periphery/periphery.hpp> #include <PSX/Periphery/periphery.hpp>
#include <PSX/SPU/spu.hpp> #include <PSX/SPU/spu.hpp>
namespace Menu { namespace Menu {
using DigitalButton = Periphery::GenericController::Button; using DigitalButton = Periphery::GenericController::Button;
void SimpleMenu :: setup(Callback callback, const Entry* entries, size_t size) { void SimpleMenu :: setup(Callback callback, const Entry* entries, size_t size) {
this->selection_callback = callback; this->selection_callback = callback;
this->entries = entries; this->entries = entries;
this->size = size; this->size = size;
this->cur_selection = 0; this->cur_selection = 0;
} }
void SimpleMenu :: update(JabyEngine::FontWriter& font_writer, Cursor& cursor, const GPU::PositionI16& start) { void SimpleMenu :: update(JabyEngine::FontWriter& font_writer, Cursor& cursor, const GPU::PositionI16& start) {
const auto& controller = Periphery::get_primary_controller_as<JabyEngine::Periphery::GenericController>(); const auto& controller = Periphery::get_primary_controller_as<JabyEngine::Periphery::GenericController>();
if(controller.button.went_down(DigitalButton::Up) && this->cur_selection > 0) { if(controller.button.went_down(DigitalButton::Up) && this->cur_selection > 0) {
this->cur_selection -= 1; this->cur_selection -= 1;
} }
if(controller.button.went_down(DigitalButton::Down) && this->cur_selection < (this->size - 1)) { if(controller.button.went_down(DigitalButton::Down) && this->cur_selection < (this->size - 1)) {
this->cur_selection += 1; this->cur_selection += 1;
} }
if(controller.button.went_down(DigitalButton::Cross)) { if(controller.button.went_down(DigitalButton::Cross)) {
SPU::voice[0].play(); SPU::voice[0].play();
this->selection_callback(this->cur_selection); this->selection_callback(this->cur_selection);
} }
cursor.pos = Make::PositionI16(8, 64); cursor.pos = Make::PositionI16(8, 64);
for(size_t n = 0; n < this->size; n++) { for(size_t n = 0; n < this->size; n++) {
const auto& cur_entry = this->entries[n]; const auto& cur_entry = this->entries[n];
if(this->cur_selection == n) { if(this->cur_selection == n) {
FontWriter::bios_font_writer.write(cursor, ">%s<\n", cur_entry.name); FontWriter::bios_font_writer.write(cursor, ">%s<\n", cur_entry.name);
} }
else { else {
FontWriter::bios_font_writer.write(cursor, "%s\n", cur_entry.name); FontWriter::bios_font_writer.write(cursor, "%s\n", cur_entry.name);
} }
} }
} }
void BackMenu :: setup(JabyEngine::FontWriter* font_writer) { void BackMenu :: setup(JabyEngine::FontWriter* font_writer) {
this->font_writer = font_writer; this->font_writer = font_writer;
this->timeout.reset(); this->timeout.reset();
this->waiting = false; this->waiting = false;
} }
bool BackMenu :: update(const GPU::PositionI16& position, bool auto_clear) { bool BackMenu :: update(const GPU::PositionI16& position, bool auto_clear) {
const auto& controller = Periphery::get_primary_controller_as<JabyEngine::Periphery::GenericController>(); const auto& controller = Periphery::get_primary_controller_as<JabyEngine::Periphery::GenericController>();
if(Shared::load_test || controller.button.is_down(DigitalButton::Circle)) { if(Shared::load_test || controller.button.is_down(DigitalButton::Circle)) {
this->waiting = true; this->waiting = true;
if(this->timeout.is_expired_for(2500_ms)) { if(this->timeout.is_expired_for(2500_ms)) {
return true; return true;
} }
} }
else { else {
this->waiting = false; this->waiting = false;
this->timeout.reset(); this->timeout.reset();
} }
if(this->waiting) { if(this->waiting) {
auto cursor = JabyEngine::Cursor::create(position); auto cursor = JabyEngine::Cursor::create(position);
this->font_writer->write(cursor, "Press and hold O\nto get back", GPU::Color24::Red(0xD0)); this->font_writer->write(cursor, "Press and hold O\nto get back", GPU::Color24::Red(0xD0));
} }
else if(auto_clear) { else if(auto_clear) {
this->font_writer->clear(); this->font_writer->clear();
} }
return false; return false;
} }
void BackMenu :: render() { void BackMenu :: render() {
this->font_writer->render(); this->font_writer->render();
} }
} }

View File

@ -1,66 +1,66 @@
include $(JABY_ENGINE_DIR)/mkfile/common/ExportPath.mk include $(JABY_ENGINE_DIR)/mkfile/common/ExportPath.mk
include $(JABY_ENGINE_DIR)/mkfile/common/RebuildTarget.mk include $(JABY_ENGINE_DIR)/mkfile/common/RebuildTarget.mk
OUTPUT_DIR = bin OUTPUT_DIR = bin
CLUT_4_COLOR_TRANS_FLAGS = simple-tim clut4 --color-trans CLUT_4_COLOR_TRANS_FLAGS = simple-tim clut4 --color-trans
# Ressources to convert # Ressources to convert
## Music tracks ## Music tracks
INPUT += $(OUTPUT_DIR)/Evacuation_cdda.xa INPUT += $(OUTPUT_DIR)/Evacuation_cdda.xa
INPUT += $(OUTPUT_DIR)/OnMyOwn_BailBonds.xa INPUT += $(OUTPUT_DIR)/OnMyOwn_BailBonds.xa
INPUT += $(OUTPUT_DIR)/apple.vag INPUT += $(OUTPUT_DIR)/apple.vag
INPUT += $(OUTPUT_DIR)/blubb-mono.vag INPUT += $(OUTPUT_DIR)/blubb-mono.vag
INPUT += $(OUTPUT_DIR)/Friendship_samp.vag INPUT += $(OUTPUT_DIR)/Friendship_samp.vag
## Images ## Images
INPUT += $(OUTPUT_DIR)/TexturePage.img INPUT += $(OUTPUT_DIR)/TexturePage.img
TexturePage_FLAGS = simple-tim clut4 TexturePage_FLAGS = simple-tim clut4
INPUT += $(OUTPUT_DIR)/IconTexture.img INPUT += $(OUTPUT_DIR)/IconTexture.img
IconTexture_FLAGS = simple-tim clut4 --semi-trans --color-trans IconTexture_FLAGS = simple-tim clut4 --semi-trans --color-trans
INPUT += $(OUTPUT_DIR)/Paco.img INPUT += $(OUTPUT_DIR)/Paco.img
Paco_FLAGS = $(CLUT_4_COLOR_TRANS_FLAGS) Paco_FLAGS = $(CLUT_4_COLOR_TRANS_FLAGS)
INPUT += $(OUTPUT_DIR)/Controller.img INPUT += $(OUTPUT_DIR)/Controller.img
Controller_FLAGS = $(CLUT_4_COLOR_TRANS_FLAGS) Controller_FLAGS = $(CLUT_4_COLOR_TRANS_FLAGS)
INPUT += $(OUTPUT_DIR)/doener_fish.img INPUT += $(OUTPUT_DIR)/doener_fish.img
doener_fish_FLAGS = $(CLUT_4_COLOR_TRANS_FLAGS) doener_fish_FLAGS = $(CLUT_4_COLOR_TRANS_FLAGS)
INPUT += $(OUTPUT_DIR)/JabyStar.img INPUT += $(OUTPUT_DIR)/JabyStar.img
JabyStar_FLAGS = $(CLUT_4_COLOR_TRANS_FLAGS) JabyStar_FLAGS = $(CLUT_4_COLOR_TRANS_FLAGS)
INPUT += $(OUTPUT_DIR)/JabyTails.img INPUT += $(OUTPUT_DIR)/JabyTails.img
JabyTails_FLAGS = $(CLUT_4_COLOR_TRANS_FLAGS) JabyTails_FLAGS = $(CLUT_4_COLOR_TRANS_FLAGS)
INPUT += $(OUTPUT_DIR)/IMG_6921.tim INPUT += $(OUTPUT_DIR)/IMG_6921.tim
IMG_6921_TIM_FLAGS = tim full16 --clut-pos {384,255} --tex-pos {384,256} IMG_6921_TIM_FLAGS = tim full16 --clut-pos {384,255} --tex-pos {384,256}
INPUT += $(OUTPUT_DIR)/AllTheJaby.tim INPUT += $(OUTPUT_DIR)/AllTheJaby.tim
AllTheJaby_TIM_FLAGS = tim full16 --tex-pos {0,0} AllTheJaby_TIM_FLAGS = tim full16 --tex-pos {0,0}
$(OUTPUT_DIR)/%.vag: audio/%.wav $(OUTPUT_DIR)/%.vag: audio/%.wav
@mkdir -p $(OUTPUT_DIR) @mkdir -p $(OUTPUT_DIR)
psxfileconv --lz4 $< -o $@ vag psxfileconv --lz4 $< -o $@ vag
$(OUTPUT_DIR)/OnMyOwn_BailBonds.xa: audio/OnMyOwn_BailBonds.mp3 $(OUTPUT_DIR)/OnMyOwn_BailBonds.xa: audio/OnMyOwn_BailBonds.mp3
@mkdir -p $(OUTPUT_DIR) @mkdir -p $(OUTPUT_DIR)
psxfileconv $< -o $@ xa psxfileconv $< -o $@ xa
$(OUTPUT_DIR)/%.xa: audio/%.wav $(OUTPUT_DIR)/%.xa: audio/%.wav
@mkdir -p $(OUTPUT_DIR) @mkdir -p $(OUTPUT_DIR)
psxfileconv $< -o $@ xa psxfileconv $< -o $@ xa
$(OUTPUT_DIR)/%.img: %.png $(OUTPUT_DIR)/%.img: %.png
@mkdir -p $(OUTPUT_DIR) @mkdir -p $(OUTPUT_DIR)
psxfileconv --lz4 $< -o $@ $($*_FLAGS) psxfileconv --lz4 $< -o $@ $($*_FLAGS)
$(OUTPUT_DIR)/%.tim: %.png $(OUTPUT_DIR)/%.tim: %.png
@mkdir -p $(OUTPUT_DIR) @mkdir -p $(OUTPUT_DIR)
psxfileconv --lz4 $< -o $@ $($*_TIM_FLAGS) psxfileconv --lz4 $< -o $@ $($*_TIM_FLAGS)
all: $(INPUT) all: $(INPUT)
clean: clean:
rm -fr $(OUTPUT_DIR) rm -fr $(OUTPUT_DIR)

View File

@ -1,2 +1,2 @@
include $(JABY_ENGINE_DIR)/mkfile/ISOMakefile.mk include $(JABY_ENGINE_DIR)/mkfile/ISOMakefile.mk
include $(JABY_ENGINE_DIR)/mkfile/common/RebuildTarget.mk include $(JABY_ENGINE_DIR)/mkfile/common/RebuildTarget.mk

View File

@ -1,23 +1,23 @@
#pragma once #pragma once
#include "../jabyengine_defines.hpp" #include "../jabyengine_defines.hpp"
namespace JabyEngine { namespace JabyEngine {
namespace CDDA { namespace CDDA {
struct TrackList { struct TrackList {
uint8_t first_track; uint8_t first_track;
uint8_t last_track; uint8_t last_track;
static constexpr TrackList empty() { static constexpr TrackList empty() {
return TrackList{.first_track = 0, .last_track = 0}; return TrackList{.first_track = 0, .last_track = 0};
} }
}; };
TrackList get_tracks(); TrackList get_tracks();
void play(uint8_t track); void play(uint8_t track);
void stop(); void stop();
void push_play(); void push_play();
void pop_play(); void pop_play();
} }
} }

View File

@ -1,14 +1,14 @@
#pragma once #pragma once
#include "../AutoLBA/auto_lba.hpp" #include "../AutoLBA/auto_lba.hpp"
namespace JabyEngine { namespace JabyEngine {
namespace CDXA { namespace CDXA {
void play(const volatile AutoLBAEntry* lba, uint8_t rel_lba_idx, uint8_t channel, bool double_speed); void play(const volatile AutoLBAEntry* lba, uint8_t rel_lba_idx, uint8_t channel, bool double_speed);
void stop(); void stop();
void set_channel(uint8_t channel); void set_channel(uint8_t channel);
void push_play(); void push_play();
void pop_play(); void pop_play();
} }
} }

View File

@ -1,19 +1,19 @@
#pragma once #pragma once
#include "../jabyengine_defines.hpp" #include "../jabyengine_defines.hpp"
namespace JabyEngine { namespace JabyEngine {
// Taken from boost endian // Taken from boost endian
static constexpr uint8_t read_be(uint8_t x) { static constexpr uint8_t read_be(uint8_t x) {
return x; return x;
} }
static constexpr uint16_t read_be(uint16_t x) { static constexpr uint16_t read_be(uint16_t x) {
return (x << 8) | (x >> 8); return (x << 8) | (x >> 8);
} }
static constexpr uint32_t read_be(uint32_t x) { static constexpr uint32_t read_be(uint32_t x) {
const uint32_t step16 = x << 16 | x >> 16; const uint32_t step16 = x << 16 | x >> 16;
return ((step16 << 8) & 0xff00ff00) | ((step16 >> 8) & 0x00ff00ff); return ((step16 << 8) & 0xff00ff00) | ((step16 >> 8) & 0x00ff00ff);
} }
} }

View File

@ -1,61 +1,61 @@
#pragma once #pragma once
#include "array_range.hpp" #include "array_range.hpp"
namespace JabyEngine { namespace JabyEngine {
template<typename T> template<typename T>
class CircularBuffer { class CircularBuffer {
private: private:
T* start_adr = nullptr; T* start_adr = nullptr;
T* end_adr = nullptr; T* end_adr = nullptr;
T* read_adr = nullptr; T* read_adr = nullptr;
T* write_adr = nullptr; T* write_adr = nullptr;
T* increment(T* cur_element) const { T* increment(T* cur_element) const {
cur_element += 1; cur_element += 1;
if(cur_element == this->end_adr) { if(cur_element == this->end_adr) {
return this->start_adr; return this->start_adr;
} }
return cur_element; return cur_element;
} }
public: public:
CircularBuffer() = default; CircularBuffer() = default;
T* setup(T* buffer_start_adr, size_t elements) { T* setup(T* buffer_start_adr, size_t elements) {
this->start_adr = buffer_start_adr; this->start_adr = buffer_start_adr;
this->end_adr = &buffer_start_adr[elements]; this->end_adr = &buffer_start_adr[elements];
this->read_adr = this->start_adr; this->read_adr = this->start_adr;
this->write_adr = this->start_adr; this->write_adr = this->start_adr;
return this->end_adr; return this->end_adr;
} }
T* allocate() { T* allocate() {
T* cur_adr = this->write_adr; T* cur_adr = this->write_adr;
T* next_adr = CircularBuffer::increment(cur_adr); T* next_adr = CircularBuffer::increment(cur_adr);
if(next_adr == this->read_adr) { if(next_adr == this->read_adr) {
return nullptr; return nullptr;
} }
else { else {
this->write_adr = next_adr; this->write_adr = next_adr;
return cur_adr; return cur_adr;
} }
} }
T* get_next() const { T* get_next() const {
return this->read_adr; return this->read_adr;
} }
void pop() { void pop() {
if(CircularBuffer::has_data()) { if(CircularBuffer::has_data()) {
this->read_adr = CircularBuffer::increment(this->read_adr); this->read_adr = CircularBuffer::increment(this->read_adr);
} }
} }
constexpr bool has_data() const { constexpr bool has_data() const {
return (this->read_adr != this->write_adr); return (this->read_adr != this->write_adr);
} }
}; };
} }

View File

@ -1,14 +1,14 @@
#pragma once #pragma once
#include <stdio.h> #include <stdio.h>
namespace JabyEngine { namespace JabyEngine {
template<typename T> template<typename T>
static inline void dump_to_stdoutln(const T& object) { static inline void dump_to_stdoutln(const T& object) {
const uint8_t* raw_ptr = reinterpret_cast<const uint8_t*>(&object); const uint8_t* raw_ptr = reinterpret_cast<const uint8_t*>(&object);
for(size_t raw_pos = 0; raw_pos < sizeof(T); raw_pos++) { for(size_t raw_pos = 0; raw_pos < sizeof(T); raw_pos++) {
printf("[%02X]", raw_ptr[raw_pos]); printf("[%02X]", raw_ptr[raw_pos]);
} }
printf("\n"); printf("\n");
} }
} }

View File

@ -1,8 +1,8 @@
#pragma once #pragma once
#include "../../stdint.hpp" #include "../../stdint.hpp"
namespace JabyEngine { namespace JabyEngine {
uint16_t unaligned_lhu(const uint8_t* adr) { uint16_t unaligned_lhu(const uint8_t* adr) {
return (static_cast<uint16_t>(adr[0]) | static_cast<uint16_t>(adr[1]) << 8); return (static_cast<uint16_t>(adr[0]) | static_cast<uint16_t>(adr[1]) << 8);
} }
} }

View File

@ -1,15 +1,15 @@
#pragma once #pragma once
#include <stddef.hpp> #include <stddef.hpp>
namespace JabyEngine { namespace JabyEngine {
using word_t = uint32_t; using word_t = uint32_t;
static constexpr size_t bytes_to_words(size_t bytes) { static constexpr size_t bytes_to_words(size_t bytes) {
return bytes/sizeof(word_t); return bytes/sizeof(word_t);
} }
static constexpr size_t words_to_bytes(size_t words) { static constexpr size_t words_to_bytes(size_t words) {
return words*sizeof(word_t); return words*sizeof(word_t);
} }
} }

View File

@ -1,73 +1,73 @@
#pragma once #pragma once
#include "../../Auxiliary/types.hpp" #include "../../Auxiliary/types.hpp"
#include "../cd_file_types.hpp" #include "../cd_file_types.hpp"
namespace JabyEngine { namespace JabyEngine {
namespace FileProcessor { namespace FileProcessor {
class State { class State {
public: public:
struct Reserved { struct Reserved {
uint32_t reserved[8]; uint32_t reserved[8];
}; };
struct CDDataProcessor; struct CDDataProcessor;
template<typename T> template<typename T>
using GenericProcessRoutine = Progress (*)(CDDataProcessor&, T&); using GenericProcessRoutine = Progress (*)(CDDataProcessor&, T&);
typedef GenericProcessRoutine<Reserved> ProcessRoutine; typedef GenericProcessRoutine<Reserved> ProcessRoutine;
struct CDDataProcessor { struct CDDataProcessor {
ProcessRoutine process_routine = nullptr; ProcessRoutine process_routine = nullptr;
const uint8_t* data_adr = nullptr; const uint8_t* data_adr = nullptr;
size_t data_bytes = 0ull; size_t data_bytes = 0ull;
template<typename T> template<typename T>
static __always_inline CDDataProcessor from(GenericProcessRoutine<T> process_routine, const uint8_t* data_adr) { static __always_inline CDDataProcessor from(GenericProcessRoutine<T> process_routine, const uint8_t* data_adr) {
return {reinterpret_cast<ProcessRoutine>(process_routine), data_adr}; return {reinterpret_cast<ProcessRoutine>(process_routine), data_adr};
} }
template<typename T> template<typename T>
T simple_read_r() { T simple_read_r() {
static constexpr size_t T_SIZE = sizeof(T); static constexpr size_t T_SIZE = sizeof(T);
T value = *reinterpret_cast<const T*>(this->data_adr); T value = *reinterpret_cast<const T*>(this->data_adr);
CDDataProcessor::processed(T_SIZE); CDDataProcessor::processed(T_SIZE);
return value; return value;
} }
constexpr void processed(size_t bytes) { constexpr void processed(size_t bytes) {
this->data_adr += bytes; this->data_adr += bytes;
this->data_bytes -= bytes; this->data_bytes -= bytes;
} }
constexpr void skip(size_t bytes) { constexpr void skip(size_t bytes) {
CDDataProcessor::processed(bytes); CDDataProcessor::processed(bytes);
} }
}; };
CDDataProcessor data_proc; CDDataProcessor data_proc;
Reserved reserved; Reserved reserved;
template<typename T> template<typename T>
static __always_inline State from(const T& state, const uint32_t* data_adr, GenericProcessRoutine<T> process_routine) { static __always_inline State from(const T& state, const uint32_t* data_adr, GenericProcessRoutine<T> process_routine) {
return {CDDataProcessor::from(process_routine, reinterpret_cast<const uint8_t*>(data_adr)), *reinterpret_cast<const Reserved*>(&state)}; return {CDDataProcessor::from(process_routine, reinterpret_cast<const uint8_t*>(data_adr)), *reinterpret_cast<const Reserved*>(&state)};
static_assert(sizeof(T) <= sizeof(Reserved)); static_assert(sizeof(T) <= sizeof(Reserved));
} }
public: public:
Progress process(size_t bytes_ready) { Progress process(size_t bytes_ready) {
this->data_proc.data_bytes += bytes_ready; this->data_proc.data_bytes += bytes_ready;
return (*this->data_proc.process_routine)(this->data_proc, this->reserved); return (*this->data_proc.process_routine)(this->data_proc, this->reserved);
} }
}; };
// The nothing state // The nothing state
State create(const uint32_t* data_adr, const Nothing& nothing); State create(const uint32_t* data_adr, const Nothing& nothing);
State create(const uint32_t* data_adr, const SimpleTIM& file); State create(const uint32_t* data_adr, const SimpleTIM& file);
State create(const uint32_t* data_adr, const TIM& file); State create(const uint32_t* data_adr, const TIM& file);
State create(const uint32_t* data_adr, const VAG& file); State create(const uint32_t* data_adr, const VAG& file);
State create_custom(const uint32_t* data_adr, const CDFileType_t& file_type, const CDFile::Payload& payload); State create_custom(const uint32_t* data_adr, const CDFileType_t& file_type, const CDFile::Payload& payload);
} }
} }

View File

@ -1,62 +1,62 @@
#pragma once #pragma once
#include "Processor/file_processor.hpp" #include "Processor/file_processor.hpp"
#include "cd_file_types.hpp" #include "cd_file_types.hpp"
#include <limits.hpp> #include <limits.hpp>
namespace JabyEngine { namespace JabyEngine {
namespace FileProcessor { namespace FileProcessor {
namespace Helper { namespace Helper {
template<typename T> template<typename T>
static Progress exchange_and_execute_process_function(State::GenericProcessRoutine<T> process_routine, State::CDDataProcessor& data_proc, T& state) { static Progress exchange_and_execute_process_function(State::GenericProcessRoutine<T> process_routine, State::CDDataProcessor& data_proc, T& state) {
data_proc.process_routine = reinterpret_cast<State::ProcessRoutine>(process_routine); data_proc.process_routine = reinterpret_cast<State::ProcessRoutine>(process_routine);
return process_routine(data_proc, state); return process_routine(data_proc, state);
} }
namespace DMA { namespace DMA {
struct WordsReady { struct WordsReady {
uint32_t words_to_use; uint32_t words_to_use;
bool is_last; bool is_last;
static constexpr WordsReady calculate(const State::CDDataProcessor& data_proc, size_t words_left) { static constexpr WordsReady calculate(const State::CDDataProcessor& data_proc, size_t words_left) {
const auto config_data_words = (data_proc.data_bytes/sizeof(uint32_t)); const auto config_data_words = (data_proc.data_bytes/sizeof(uint32_t));
const auto words_to_use = (config_data_words > words_left) ? words_left : config_data_words; const auto words_to_use = (config_data_words > words_left) ? words_left : config_data_words;
return { return {
.words_to_use = words_to_use, .words_to_use = words_to_use,
.is_last = words_to_use == words_left .is_last = words_to_use == words_left
}; };
} }
}; };
template<typename T> template<typename T>
static size_t send_words(size_t words_to_send, bool send_all) { static size_t send_words(size_t words_to_send, bool send_all) {
auto blocks_to_send = words_to_send/16; auto blocks_to_send = words_to_send/16;
while(blocks_to_send > 0) { while(blocks_to_send > 0) {
const auto block_send = (blocks_to_send > UI16_MAX) ? UI16_MAX : blocks_to_send; const auto block_send = (blocks_to_send > UI16_MAX) ? UI16_MAX : blocks_to_send;
// Send data! // Send data!
T::wait(); T::wait();
T::Receive::start(blocks_to_send); T::Receive::start(blocks_to_send);
blocks_to_send -= block_send; blocks_to_send -= block_send;
} }
if(send_all) { if(send_all) {
const auto last_words_to_send = (words_to_send & 0b1111); const auto last_words_to_send = (words_to_send & 0b1111);
if(last_words_to_send > 0) { if(last_words_to_send > 0) {
T::wait(); T::wait();
T::Receive::start(1, last_words_to_send); T::Receive::start(1, last_words_to_send);
} }
T::wait(); T::wait();
T::end(); T::end();
return words_to_send; return words_to_send;
} }
else { else {
return (words_to_send & ~0b1111); return (words_to_send & ~0b1111);
} }
} }
} }
} }
} }
} }

View File

@ -1,52 +1,52 @@
#pragma once #pragma once
#include "../../System/IOPorts/gpu_io.hpp" #include "../../System/IOPorts/gpu_io.hpp"
#include "linked_elements.hpp" #include "linked_elements.hpp"
#include "primitive_support_types.hpp" #include "primitive_support_types.hpp"
namespace JabyEngine { namespace JabyEngine {
namespace GPU { namespace GPU {
struct TexPage : public internal::LinkedElementCreator<TexPage> { struct TexPage : public internal::LinkedElementCreator<TexPage> {
static constexpr bool is_render_primitive = true; static constexpr bool is_render_primitive = true;
GPU_IO_Values::GP0 value; GPU_IO_Values::GP0 value;
static constexpr TexPage create(const PositionU16& tex_pos, TextureColorMode tex_color, SemiTransparency transparency = SemiTransparency::B_Half_add_F_Half, bool dither = false) { static constexpr TexPage create(const PositionU16& tex_pos, TextureColorMode tex_color, SemiTransparency transparency = SemiTransparency::B_Half_add_F_Half, bool dither = false) {
return TexPage{.value = GPU_IO_Values::GP0::TexPage(tex_pos, transparency, tex_color, dither, false)}; return TexPage{.value = GPU_IO_Values::GP0::TexPage(tex_pos, transparency, tex_color, dither, false)};
} }
}; };
struct CPU2VRAM { struct CPU2VRAM {
static constexpr bool is_render_primitive = true; static constexpr bool is_render_primitive = true;
GPU_IO_Values::GP0 cmd; GPU_IO_Values::GP0 cmd;
GPU_IO_Values::GP0 pos; GPU_IO_Values::GP0 pos;
GPU_IO_Values::GP0 size; GPU_IO_Values::GP0 size;
static constexpr CPU2VRAM create(const AreaU16& dst) { static constexpr CPU2VRAM create(const AreaU16& dst) {
return CPU2VRAM{ return CPU2VRAM{
.cmd = GPU_IO_Values::GP0::CPU2VRAMBlitting(), .cmd = GPU_IO_Values::GP0::CPU2VRAMBlitting(),
.pos = GPU_IO_Values::GP0::PostionTopLeft(dst.position), .pos = GPU_IO_Values::GP0::PostionTopLeft(dst.position),
.size = GPU_IO_Values::GP0::WidthHeight(dst.size) .size = GPU_IO_Values::GP0::WidthHeight(dst.size)
}; };
} }
}; };
struct VRAM2VRAM { struct VRAM2VRAM {
static constexpr bool is_render_primitive = true; static constexpr bool is_render_primitive = true;
GPU_IO_Values::GP0 cmd; GPU_IO_Values::GP0 cmd;
GPU_IO_Values::GP0 src_pos; GPU_IO_Values::GP0 src_pos;
GPU_IO_Values::GP0 dst_pos; GPU_IO_Values::GP0 dst_pos;
GPU_IO_Values::GP0 size; GPU_IO_Values::GP0 size;
static constexpr VRAM2VRAM create(const AreaU16& src, const PositionU16& dst) { static constexpr VRAM2VRAM create(const AreaU16& src, const PositionU16& dst) {
return VRAM2VRAM{ return VRAM2VRAM{
.cmd = GPU_IO_Values::GP0::VRAM2VRAMBlitting(), .cmd = GPU_IO_Values::GP0::VRAM2VRAMBlitting(),
.src_pos = GPU_IO_Values::GP0::PostionTopLeft(src.position), .src_pos = GPU_IO_Values::GP0::PostionTopLeft(src.position),
.dst_pos = GPU_IO_Values::GP0::PostionTopLeft(dst), .dst_pos = GPU_IO_Values::GP0::PostionTopLeft(dst),
.size = GPU_IO_Values::GP0::WidthHeight(src.size) .size = GPU_IO_Values::GP0::WidthHeight(src.size)
}; };
} }
}; };
} }
} }

View File

@ -1,35 +1,35 @@
#pragma once #pragma once
#include "../jabyengine_config.hpp" #include "../jabyengine_config.hpp"
#include "gpu_primitives.hpp" #include "gpu_primitives.hpp"
namespace JabyEngine { namespace JabyEngine {
namespace GPU { namespace GPU {
struct BIOS_Font { struct BIOS_Font {
// This size is by Hardware limitation // This size is by Hardware limitation
static constexpr auto Size = SizeU16::create(16, 16); static constexpr auto Size = SizeU16::create(16, 16);
static constexpr auto TextureLoadPos = Configuration::BIOSFont::texture_load_pos(); static constexpr auto TextureLoadPos = Configuration::BIOSFont::texture_load_pos();
static constexpr auto CLUTLoadPos = Configuration::BIOSFont::CLUT_load_pos(); static constexpr auto CLUTLoadPos = Configuration::BIOSFont::CLUT_load_pos();
static constexpr TexPage get_tex_page() { static constexpr TexPage get_tex_page() {
return TexPage::create(BIOS_Font::TextureLoadPos, GPU::TextureColorMode::clut4); return TexPage::create(BIOS_Font::TextureLoadPos, GPU::TextureColorMode::clut4);
} }
static constexpr TPage get_tpage() { static constexpr TPage get_tpage() {
return TPage::create(TextureLoadPos.x, TextureLoadPos.y, SemiTransparency::B_add_F, TextureColorMode::clut4); return TPage::create(TextureLoadPos.x, TextureLoadPos.y, SemiTransparency::B_add_F, TextureColorMode::clut4);
} }
static constexpr PageOffset get_offset_page() { static constexpr PageOffset get_offset_page() {
return PageOffset::create(BIOS_Font::CLUTLoadPos.x & 0x3F, BIOS_Font::CLUTLoadPos.y & 0xFF); return PageOffset::create(BIOS_Font::CLUTLoadPos.x & 0x3F, BIOS_Font::CLUTLoadPos.y & 0xFF);
} }
static constexpr PageClut get_page_clut() { static constexpr PageClut get_page_clut() {
return PageClut::create(BIOS_Font::CLUTLoadPos); return PageClut::create(BIOS_Font::CLUTLoadPos);
} }
static constexpr OffsetPageWithClut get_offset_page_with_clut() { static constexpr OffsetPageWithClut get_offset_page_with_clut() {
return OffsetPageWithClut::create(BIOS_Font::get_offset_page(), BIOS_Font::get_page_clut()); return OffsetPageWithClut::create(BIOS_Font::get_offset_page(), BIOS_Font::get_page_clut());
} }
}; };
} }
} }

View File

@ -1,349 +1,349 @@
#pragma once #pragma once
#include "gpu_primitives.hpp" #include "gpu_primitives.hpp"
namespace JabyEngine { namespace JabyEngine {
namespace Make { namespace Make {
template<typename T, typename...ARGS> template<typename T, typename...ARGS>
static constexpr T creator_template(const ARGS&...args) { static constexpr T creator_template(const ARGS&...args) {
return T::create(args...); return T::create(args...);
} }
// ################################################################### // ###################################################################
static constexpr GPU::SizeI8 SizeI8() { static constexpr GPU::SizeI8 SizeI8() {
return creator_template<GPU::SizeI8>(0_i8, 0_i8); return creator_template<GPU::SizeI8>(0_i8, 0_i8);
} }
static constexpr GPU::SizeI8 SizeI8(int8_t x, int8_t y) { static constexpr GPU::SizeI8 SizeI8(int8_t x, int8_t y) {
return creator_template<GPU::SizeI8>(x, y); return creator_template<GPU::SizeI8>(x, y);
} }
// ################################################################### // ###################################################################
static constexpr GPU::SizeU8 SizeU8() { static constexpr GPU::SizeU8 SizeU8() {
return creator_template<GPU::SizeU8>(0_u8, 0_u8); return creator_template<GPU::SizeU8>(0_u8, 0_u8);
} }
static constexpr GPU::SizeU8 SizeU8(uint8_t x, uint8_t y) { static constexpr GPU::SizeU8 SizeU8(uint8_t x, uint8_t y) {
return creator_template<GPU::SizeU8>(x, y); return creator_template<GPU::SizeU8>(x, y);
} }
// ################################################################### // ###################################################################
static constexpr GPU::SizeI16 SizeI16() { static constexpr GPU::SizeI16 SizeI16() {
return creator_template<GPU::SizeI16>(0_i16, 0_i16); return creator_template<GPU::SizeI16>(0_i16, 0_i16);
} }
static constexpr GPU::SizeI16 SizeI16(int16_t x, int16_t y) { static constexpr GPU::SizeI16 SizeI16(int16_t x, int16_t y) {
return creator_template<GPU::SizeI16>(x, y); return creator_template<GPU::SizeI16>(x, y);
} }
// ################################################################### // ###################################################################
static constexpr GPU::SizeU16 SizeU16() { static constexpr GPU::SizeU16 SizeU16() {
return creator_template<GPU::SizeU16>(0_u16, 0_u16); return creator_template<GPU::SizeU16>(0_u16, 0_u16);
} }
static constexpr GPU::SizeU16 SizeU16(uint16_t x, uint16_t y) { static constexpr GPU::SizeU16 SizeU16(uint16_t x, uint16_t y) {
return creator_template<GPU::SizeU16>(x, y); return creator_template<GPU::SizeU16>(x, y);
} }
// ################################################################### // ###################################################################
static constexpr GPU::PositionI8 PositionI8() { static constexpr GPU::PositionI8 PositionI8() {
return creator_template<GPU::PositionI8>(0_i8, 0_i8); return creator_template<GPU::PositionI8>(0_i8, 0_i8);
} }
static constexpr GPU::PositionI8 PositionI8(int8_t x, int8_t y) { static constexpr GPU::PositionI8 PositionI8(int8_t x, int8_t y) {
return creator_template<GPU::PositionI8>(x, y); return creator_template<GPU::PositionI8>(x, y);
} }
// ################################################################### // ###################################################################
static constexpr GPU::PositionU8 PositionU8() { static constexpr GPU::PositionU8 PositionU8() {
return creator_template<GPU::PositionU8>(0_u8, 0_u8); return creator_template<GPU::PositionU8>(0_u8, 0_u8);
} }
static constexpr GPU::PositionU8 PositionU8(int8_t x, int8_t y) { static constexpr GPU::PositionU8 PositionU8(int8_t x, int8_t y) {
return creator_template<GPU::PositionU8>(x, y); return creator_template<GPU::PositionU8>(x, y);
} }
// ################################################################### // ###################################################################
static constexpr GPU::PositionI16 PositionI16() { static constexpr GPU::PositionI16 PositionI16() {
return creator_template<GPU::PositionI16>(0_i16, 0_i16); return creator_template<GPU::PositionI16>(0_i16, 0_i16);
} }
static constexpr GPU::PositionI16 PositionI16(int16_t x, int16_t y) { static constexpr GPU::PositionI16 PositionI16(int16_t x, int16_t y) {
return creator_template<GPU::PositionI16>(x, y); return creator_template<GPU::PositionI16>(x, y);
} }
// ################################################################### // ###################################################################
static constexpr GPU::PositionU16 PositionU16() { static constexpr GPU::PositionU16 PositionU16() {
return creator_template<GPU::PositionU16>(0_u16, 0_u16); return creator_template<GPU::PositionU16>(0_u16, 0_u16);
} }
static constexpr GPU::PositionU16 PositionU16(uint16_t x, uint16_t y) { static constexpr GPU::PositionU16 PositionU16(uint16_t x, uint16_t y) {
return creator_template<GPU::PositionU16>(x, y); return creator_template<GPU::PositionU16>(x, y);
} }
// ################################################################### // ###################################################################
static constexpr GPU::Vertex Vertex() { static constexpr GPU::Vertex Vertex() {
return creator_template<GPU::Vertex>(0_i16, 0_i16); return creator_template<GPU::Vertex>(0_i16, 0_i16);
} }
static constexpr GPU::Vertex Vertex(int16_t x, int16_t y) { static constexpr GPU::Vertex Vertex(int16_t x, int16_t y) {
return creator_template<GPU::Vertex>(x, y); return creator_template<GPU::Vertex>(x, y);
} }
// ################################################################### // ###################################################################
static constexpr GPU::AreaI16 AreaI16() { static constexpr GPU::AreaI16 AreaI16() {
return creator_template<GPU::AreaI16>(0, 0, 0, 0); return creator_template<GPU::AreaI16>(0, 0, 0, 0);
} }
static constexpr GPU::AreaI16 AreaI16(int16_t x, int16_t y, int16_t w, int16_t h) { static constexpr GPU::AreaI16 AreaI16(int16_t x, int16_t y, int16_t w, int16_t h) {
return creator_template<GPU::AreaI16>(x, y, w, h); return creator_template<GPU::AreaI16>(x, y, w, h);
} }
static constexpr GPU::AreaI16 AreaI16(GPU::PositionI16 pos, GPU::SizeI16 size) { static constexpr GPU::AreaI16 AreaI16(GPU::PositionI16 pos, GPU::SizeI16 size) {
return creator_template<GPU::AreaI16>(pos, size); return creator_template<GPU::AreaI16>(pos, size);
} }
// ################################################################### // ###################################################################
static constexpr GPU::AreaU16 AreaU16() { static constexpr GPU::AreaU16 AreaU16() {
return creator_template<GPU::AreaU16>(0, 0, 0, 0); return creator_template<GPU::AreaU16>(0, 0, 0, 0);
} }
static constexpr GPU::AreaU16 AreaU16(uint16_t x, uint16_t y, uint16_t w, uint16_t h) { static constexpr GPU::AreaU16 AreaU16(uint16_t x, uint16_t y, uint16_t w, uint16_t h) {
return creator_template<GPU::AreaU16>(x, y, w, h); return creator_template<GPU::AreaU16>(x, y, w, h);
} }
static constexpr GPU::AreaU16 AreaU16(GPU::PositionU16 pos, GPU::SizeU16 size) { static constexpr GPU::AreaU16 AreaU16(GPU::PositionU16 pos, GPU::SizeU16 size) {
return creator_template<GPU::AreaU16>(pos, size); return creator_template<GPU::AreaU16>(pos, size);
} }
// ################################################################### // ###################################################################
static constexpr GPU::PageOffset PageOffset() { static constexpr GPU::PageOffset PageOffset() {
return creator_template<GPU::PageOffset>(0_u8, 0_u8); return creator_template<GPU::PageOffset>(0_u8, 0_u8);
} }
static constexpr GPU::PageOffset PageOffset(uint8_t u, uint8_t v) { static constexpr GPU::PageOffset PageOffset(uint8_t u, uint8_t v) {
return creator_template<GPU::PageOffset>(u, v); return creator_template<GPU::PageOffset>(u, v);
} }
// ################################################################### // ###################################################################
static constexpr GPU::PageClut PageClut() { static constexpr GPU::PageClut PageClut() {
return creator_template<GPU::PageClut>(0_u16, 0_u16); return creator_template<GPU::PageClut>(0_u16, 0_u16);
} }
static constexpr GPU::PageClut PageClut(uint16_t x, uint16_t y) { static constexpr GPU::PageClut PageClut(uint16_t x, uint16_t y) {
return creator_template<GPU::PageClut>(x, y); return creator_template<GPU::PageClut>(x, y);
} }
static constexpr GPU::PageClut PageClut(const GPU::PositionU16& clut_pos) { static constexpr GPU::PageClut PageClut(const GPU::PositionU16& clut_pos) {
return creator_template<GPU::PageClut>(clut_pos); return creator_template<GPU::PageClut>(clut_pos);
} }
// ################################################################### // ###################################################################
static constexpr GPU::TPage TPage() { static constexpr GPU::TPage TPage() {
return creator_template<GPU::TPage>(0_u16, 0_u16, GPU::SemiTransparency::B_add_F, GPU::TextureColorMode::clut4); return creator_template<GPU::TPage>(0_u16, 0_u16, GPU::SemiTransparency::B_add_F, GPU::TextureColorMode::clut4);
} }
static constexpr GPU::TPage TPage(uint16_t x, uint16_t y, GPU::SemiTransparency transparency, GPU::TextureColorMode clut_color) { static constexpr GPU::TPage TPage(uint16_t x, uint16_t y, GPU::SemiTransparency transparency, GPU::TextureColorMode clut_color) {
return creator_template<GPU::TPage>(x, y, transparency, clut_color); return creator_template<GPU::TPage>(x, y, transparency, clut_color);
} }
static constexpr GPU::TPage TPage(const GPU::PositionU16& tex_pos, GPU::SemiTransparency transparency, GPU::TextureColorMode clut_color) { static constexpr GPU::TPage TPage(const GPU::PositionU16& tex_pos, GPU::SemiTransparency transparency, GPU::TextureColorMode clut_color) {
return creator_template<GPU::TPage>(tex_pos, transparency, clut_color); return creator_template<GPU::TPage>(tex_pos, transparency, clut_color);
} }
// ################################################################### // ###################################################################
static constexpr GPU::TexPage TexPage() { static constexpr GPU::TexPage TexPage() {
return creator_template<GPU::TexPage>(PositionU16(), GPU::TextureColorMode::clut4, GPU::SemiTransparency::B_Half_add_F_Half, false); return creator_template<GPU::TexPage>(PositionU16(), GPU::TextureColorMode::clut4, GPU::SemiTransparency::B_Half_add_F_Half, false);
} }
static constexpr GPU::TexPage TexPage(const GPU::PositionU16& tex_pos, GPU::TextureColorMode tex_color, GPU::SemiTransparency transparency = GPU::SemiTransparency::B_Half_add_F_Half, bool dither = false) { static constexpr GPU::TexPage TexPage(const GPU::PositionU16& tex_pos, GPU::TextureColorMode tex_color, GPU::SemiTransparency transparency = GPU::SemiTransparency::B_Half_add_F_Half, bool dither = false) {
return creator_template<GPU::TexPage>(tex_pos, tex_color, transparency, dither); return creator_template<GPU::TexPage>(tex_pos, tex_color, transparency, dither);
} }
// ################################################################### // ###################################################################
static constexpr GPU::OffsetPageWithClut OffsetPageWithClut() { static constexpr GPU::OffsetPageWithClut OffsetPageWithClut() {
return creator_template<GPU::OffsetPageWithClut>(PageOffset(), PageClut()); return creator_template<GPU::OffsetPageWithClut>(PageOffset(), PageClut());
} }
static constexpr GPU::OffsetPageWithClut OffsetPageWithClut(GPU::PageOffset tex_offset, GPU::PageClut clut) { static constexpr GPU::OffsetPageWithClut OffsetPageWithClut(GPU::PageOffset tex_offset, GPU::PageClut clut) {
return creator_template<GPU::OffsetPageWithClut>(tex_offset, clut); return creator_template<GPU::OffsetPageWithClut>(tex_offset, clut);
} }
// ################################################################### // ###################################################################
static constexpr GPU::VertexColor VertexColor() { static constexpr GPU::VertexColor VertexColor() {
return creator_template<GPU::VertexColor>(Vertex(), GPU::Color24::Black()); return creator_template<GPU::VertexColor>(Vertex(), GPU::Color24::Black());
} }
static constexpr GPU::VertexColor VertexColor(GPU::Vertex pos, GPU::Color24 color) { static constexpr GPU::VertexColor VertexColor(GPU::Vertex pos, GPU::Color24 color) {
return creator_template<GPU::VertexColor>(pos, color); return creator_template<GPU::VertexColor>(pos, color);
} }
// ################################################################### // ###################################################################
static constexpr GPU::ColorVertex ColorVertex() { static constexpr GPU::ColorVertex ColorVertex() {
return creator_template<GPU::ColorVertex>(GPU::Color24::Black(), Vertex()); return creator_template<GPU::ColorVertex>(GPU::Color24::Black(), Vertex());
} }
static constexpr GPU::ColorVertex ColorVertex(GPU::Color24 color, GPU::Vertex pos) { static constexpr GPU::ColorVertex ColorVertex(GPU::Color24 color, GPU::Vertex pos) {
return creator_template<GPU::ColorVertex>(color, pos); return creator_template<GPU::ColorVertex>(color, pos);
} }
// ################################################################### // ###################################################################
static constexpr GPU::LINE_F_SINGLE LINE_F(const GPU::Color24& color, const GPU::Vertex& start_point, const GPU::Vertex& end_point) { static constexpr GPU::LINE_F_SINGLE LINE_F(const GPU::Color24& color, const GPU::Vertex& start_point, const GPU::Vertex& end_point) {
return GPU::LINE_F::create(color, start_point, end_point); return GPU::LINE_F::create(color, start_point, end_point);
} }
template<typename...ARGS> template<typename...ARGS>
static constexpr GPU::LINE_F_MULTI<sizeof...(ARGS) + 1> LINE_F(const GPU::Color24& color, const GPU::Vertex& start_point, const ARGS&...rest) { static constexpr GPU::LINE_F_MULTI<sizeof...(ARGS) + 1> LINE_F(const GPU::Color24& color, const GPU::Vertex& start_point, const ARGS&...rest) {
return GPU::LINE_F::create(color, start_point, rest...); return GPU::LINE_F::create(color, start_point, rest...);
} }
static constexpr GPU::LINE_G_SINGLE LINE_G(const GPU::ColorVertex& start_point, const GPU::ColorVertex& end_point) { static constexpr GPU::LINE_G_SINGLE LINE_G(const GPU::ColorVertex& start_point, const GPU::ColorVertex& end_point) {
return GPU::LINE_G::create(start_point, end_point); return GPU::LINE_G::create(start_point, end_point);
} }
template<typename...ARGS> template<typename...ARGS>
static constexpr GPU::LINE_G_MULTI<sizeof...(ARGS) + 1> LINE_G(const GPU::ColorVertex& start_point, const ARGS&...rest) { static constexpr GPU::LINE_G_MULTI<sizeof...(ARGS) + 1> LINE_G(const GPU::ColorVertex& start_point, const ARGS&...rest) {
return GPU::LINE_G::create(start_point, rest...); return GPU::LINE_G::create(start_point, rest...);
} }
// ################################################################### // ###################################################################
// ################################################################### // ###################################################################
// ################################################################### // ###################################################################
static constexpr GPU::POLY_F3 POLY_F3(const GPU::Vertex (&verticies)[3], GPU::Color24 color) { static constexpr GPU::POLY_F3 POLY_F3(const GPU::Vertex (&verticies)[3], GPU::Color24 color) {
return creator_template<GPU::POLY_F3>(verticies, color); return creator_template<GPU::POLY_F3>(verticies, color);
} }
static constexpr GPU::POLY_FT3 POLY_FT3(const GPU::Vertex (&verticies)[3], const GPU::PageOffset (&tex_offset)[3], GPU::TPage tpage, GPU::PageClut clut, GPU::Color24 color = GPU::Color24::Grey()) { static constexpr GPU::POLY_FT3 POLY_FT3(const GPU::Vertex (&verticies)[3], const GPU::PageOffset (&tex_offset)[3], GPU::TPage tpage, GPU::PageClut clut, GPU::Color24 color = GPU::Color24::Grey()) {
return creator_template<GPU::POLY_FT3>(verticies, tex_offset, tpage, clut, color); return creator_template<GPU::POLY_FT3>(verticies, tex_offset, tpage, clut, color);
} }
static constexpr GPU::POLY_FT3 POLY_FT3(const GPU::POLY_FT3::VertexEx (&vertices_ex)[3], GPU::TPage tpage, GPU::PageClut clut, GPU::Color24 color) { static constexpr GPU::POLY_FT3 POLY_FT3(const GPU::POLY_FT3::VertexEx (&vertices_ex)[3], GPU::TPage tpage, GPU::PageClut clut, GPU::Color24 color) {
return creator_template<GPU::POLY_FT3>(vertices_ex, tpage, clut, color); return creator_template<GPU::POLY_FT3>(vertices_ex, tpage, clut, color);
} }
static constexpr GPU::POLY_G3 POLY_G3(const GPU::Vertex (&verticies)[3], const GPU::Color24 (&color)[3]) { static constexpr GPU::POLY_G3 POLY_G3(const GPU::Vertex (&verticies)[3], const GPU::Color24 (&color)[3]) {
return creator_template<GPU::POLY_G3>(verticies, color); return creator_template<GPU::POLY_G3>(verticies, color);
} }
static constexpr GPU::POLY_G3 POLY_G3(const GPU::VertexColor (&verticies_ex)[3]) { static constexpr GPU::POLY_G3 POLY_G3(const GPU::VertexColor (&verticies_ex)[3]) {
return creator_template<GPU::POLY_G3>(verticies_ex); return creator_template<GPU::POLY_G3>(verticies_ex);
} }
static constexpr GPU::POLY_GT3 POLY_GT3(const GPU::Vertex (&verticies)[3], const GPU::PageOffset (&tex_offset)[3], const GPU::Color24 (&color)[3], GPU::TPage tpage, GPU::PageClut clut) { static constexpr GPU::POLY_GT3 POLY_GT3(const GPU::Vertex (&verticies)[3], const GPU::PageOffset (&tex_offset)[3], const GPU::Color24 (&color)[3], GPU::TPage tpage, GPU::PageClut clut) {
return creator_template<GPU::POLY_GT3>(verticies, tex_offset, color, tpage, clut); return creator_template<GPU::POLY_GT3>(verticies, tex_offset, color, tpage, clut);
} }
static constexpr GPU::POLY_GT3 POLY_GT3(const GPU::POLY_GT3::VertexEx (&verticies_ex)[3], GPU::TPage tpage, GPU::PageClut clut) { static constexpr GPU::POLY_GT3 POLY_GT3(const GPU::POLY_GT3::VertexEx (&verticies_ex)[3], GPU::TPage tpage, GPU::PageClut clut) {
return creator_template<GPU::POLY_GT3>(verticies_ex, tpage, clut); return creator_template<GPU::POLY_GT3>(verticies_ex, tpage, clut);
} }
static constexpr GPU::POLY_F4 POLY_F4(const GPU::Vertex (&verticies)[4], GPU::Color24 color) { static constexpr GPU::POLY_F4 POLY_F4(const GPU::Vertex (&verticies)[4], GPU::Color24 color) {
return creator_template<GPU::POLY_F4>(verticies, color); return creator_template<GPU::POLY_F4>(verticies, color);
} }
static constexpr GPU::POLY_F4 POLY_F4(const GPU::AreaI16& area, GPU::Color24 color) { static constexpr GPU::POLY_F4 POLY_F4(const GPU::AreaI16& area, GPU::Color24 color) {
return creator_template<GPU::POLY_F4>(area, color); return creator_template<GPU::POLY_F4>(area, color);
} }
static constexpr GPU::POLY_FT4 POLY_FT4(const GPU::Vertex (&verticies)[4], const GPU::PageOffset (&tex_offset)[4], GPU::TPage tpage, GPU::PageClut clut, GPU::Color24 color) { static constexpr GPU::POLY_FT4 POLY_FT4(const GPU::Vertex (&verticies)[4], const GPU::PageOffset (&tex_offset)[4], GPU::TPage tpage, GPU::PageClut clut, GPU::Color24 color) {
return creator_template<GPU::POLY_FT4>(verticies, tex_offset, tpage, clut, color); return creator_template<GPU::POLY_FT4>(verticies, tex_offset, tpage, clut, color);
} }
static constexpr GPU::POLY_FT4 POLY_FT4(const GPU::POLY_FT4::VertexEx (&vertices_ex)[4], GPU::TPage tpage, GPU::PageClut clut, GPU::Color24 color = GPU::Color24::Grey()) { static constexpr GPU::POLY_FT4 POLY_FT4(const GPU::POLY_FT4::VertexEx (&vertices_ex)[4], GPU::TPage tpage, GPU::PageClut clut, GPU::Color24 color = GPU::Color24::Grey()) {
return creator_template<GPU::POLY_FT4>(vertices_ex, tpage, clut, color); return creator_template<GPU::POLY_FT4>(vertices_ex, tpage, clut, color);
} }
static constexpr GPU::POLY_FT4 POLY_FT4(const GPU::AreaI16& area, const GPU::PageOffset& tex_offset, GPU::TPage tpage, GPU::PageClut clut, GPU::Color24 color = GPU::Color24::Grey()) { static constexpr GPU::POLY_FT4 POLY_FT4(const GPU::AreaI16& area, const GPU::PageOffset& tex_offset, GPU::TPage tpage, GPU::PageClut clut, GPU::Color24 color = GPU::Color24::Grey()) {
return creator_template<GPU::POLY_FT4>(area, tex_offset, tpage, clut, color); return creator_template<GPU::POLY_FT4>(area, tex_offset, tpage, clut, color);
} }
static constexpr GPU::POLY_G4 POLY_G4(const GPU::Vertex (&verticies)[4], const GPU::Color24 (&color)[4]) { static constexpr GPU::POLY_G4 POLY_G4(const GPU::Vertex (&verticies)[4], const GPU::Color24 (&color)[4]) {
return creator_template<GPU::POLY_G4>(verticies, color); return creator_template<GPU::POLY_G4>(verticies, color);
} }
static constexpr GPU::POLY_G4 POLY_G4(const GPU::VertexColor (&verticies_ex)[4]) { static constexpr GPU::POLY_G4 POLY_G4(const GPU::VertexColor (&verticies_ex)[4]) {
return creator_template<GPU::POLY_G4>(verticies_ex); return creator_template<GPU::POLY_G4>(verticies_ex);
} }
static constexpr GPU::POLY_G4 POLY_G4(const GPU::AreaI16& area, const GPU::Color24 (&color)[4]) { static constexpr GPU::POLY_G4 POLY_G4(const GPU::AreaI16& area, const GPU::Color24 (&color)[4]) {
return creator_template<GPU::POLY_G4>(area, color); return creator_template<GPU::POLY_G4>(area, color);
} }
static constexpr GPU::POLY_GT4 POLY_GT4(const GPU::Vertex (&verticies)[4], const GPU::PageOffset (&tex_offset)[4], const GPU::Color24 (&color)[4], GPU::TPage tpage, GPU::PageClut clut) { static constexpr GPU::POLY_GT4 POLY_GT4(const GPU::Vertex (&verticies)[4], const GPU::PageOffset (&tex_offset)[4], const GPU::Color24 (&color)[4], GPU::TPage tpage, GPU::PageClut clut) {
return creator_template<GPU::POLY_GT4>(verticies, tex_offset, color, tpage, clut); return creator_template<GPU::POLY_GT4>(verticies, tex_offset, color, tpage, clut);
} }
static constexpr GPU::POLY_GT4 POLY_GT4(const GPU::POLY_GT4::VertexEx (&verticies_ex)[4], GPU::TPage tpage, GPU::PageClut clut) { static constexpr GPU::POLY_GT4 POLY_GT4(const GPU::POLY_GT4::VertexEx (&verticies_ex)[4], GPU::TPage tpage, GPU::PageClut clut) {
return creator_template<GPU::POLY_GT4>(verticies_ex, tpage, clut); return creator_template<GPU::POLY_GT4>(verticies_ex, tpage, clut);
} }
static constexpr GPU::POLY_GT4 POLY_GT4(const GPU::AreaI16& area, const GPU::PageOffset& tex_offset, GPU::TPage tpage, GPU::PageClut clut, const GPU::Color24 (&color)[4]) { static constexpr GPU::POLY_GT4 POLY_GT4(const GPU::AreaI16& area, const GPU::PageOffset& tex_offset, GPU::TPage tpage, GPU::PageClut clut, const GPU::Color24 (&color)[4]) {
return creator_template<GPU::POLY_GT4>(area, tex_offset, tpage, clut, color); return creator_template<GPU::POLY_GT4>(area, tex_offset, tpage, clut, color);
} }
// ################################################################### // ###################################################################
static constexpr GPU::TILE_1 TILE_1() { static constexpr GPU::TILE_1 TILE_1() {
return creator_template<GPU::TILE_1>(Vertex(), GPU::Color24::Black()); return creator_template<GPU::TILE_1>(Vertex(), GPU::Color24::Black());
} }
static constexpr GPU::TILE_1 TILE_1(const GPU::Vertex& position, const GPU::Color24& color) { static constexpr GPU::TILE_1 TILE_1(const GPU::Vertex& position, const GPU::Color24& color) {
return creator_template<GPU::TILE_1>(position, color); return creator_template<GPU::TILE_1>(position, color);
} }
static constexpr GPU::TILE_8 TILE_8() { static constexpr GPU::TILE_8 TILE_8() {
return creator_template<GPU::TILE_8>(Vertex(), GPU::Color24::Black()); return creator_template<GPU::TILE_8>(Vertex(), GPU::Color24::Black());
} }
static constexpr GPU::TILE_8 TILE_8(const GPU::Vertex& position, const GPU::Color24& color) { static constexpr GPU::TILE_8 TILE_8(const GPU::Vertex& position, const GPU::Color24& color) {
return creator_template<GPU::TILE_8>(position, color); return creator_template<GPU::TILE_8>(position, color);
} }
static constexpr GPU::TILE_16 TILE_16() { static constexpr GPU::TILE_16 TILE_16() {
return creator_template<GPU::TILE_16>(Vertex(), GPU::Color24::Black()); return creator_template<GPU::TILE_16>(Vertex(), GPU::Color24::Black());
} }
static constexpr GPU::TILE_16 TILE_16(const GPU::Vertex& position, const GPU::Color24& color) { static constexpr GPU::TILE_16 TILE_16(const GPU::Vertex& position, const GPU::Color24& color) {
return creator_template<GPU::TILE_16>(position, color); return creator_template<GPU::TILE_16>(position, color);
} }
static constexpr GPU::TILE TILE() { static constexpr GPU::TILE TILE() {
return creator_template<GPU::TILE>(AreaI16(), GPU::Color24::Black()); return creator_template<GPU::TILE>(AreaI16(), GPU::Color24::Black());
} }
static constexpr GPU::TILE TILE(const GPU::AreaI16& area, const GPU::Color24& color) { static constexpr GPU::TILE TILE(const GPU::AreaI16& area, const GPU::Color24& color) {
return creator_template<GPU::TILE>(area, color); return creator_template<GPU::TILE>(area, color);
} }
// ################################################################### // ###################################################################
static constexpr GPU::SPRT_1 SPRT_1() { static constexpr GPU::SPRT_1 SPRT_1() {
return creator_template<GPU::SPRT_1>(Vertex(), OffsetPageWithClut(), GPU::Color24::Black()); return creator_template<GPU::SPRT_1>(Vertex(), OffsetPageWithClut(), GPU::Color24::Black());
} }
static constexpr GPU::SPRT_1 SPRT_1(const GPU::Vertex& position, const GPU::OffsetPageWithClut& tex_offset_w_clut, const GPU::Color24& color = GPU::Color24::Grey()) { static constexpr GPU::SPRT_1 SPRT_1(const GPU::Vertex& position, const GPU::OffsetPageWithClut& tex_offset_w_clut, const GPU::Color24& color = GPU::Color24::Grey()) {
return creator_template<GPU::SPRT_1>(position, tex_offset_w_clut, color); return creator_template<GPU::SPRT_1>(position, tex_offset_w_clut, color);
} }
static constexpr GPU::SPRT_8 SPRT_8() { static constexpr GPU::SPRT_8 SPRT_8() {
return creator_template<GPU::SPRT_8>(Vertex(), OffsetPageWithClut(), GPU::Color24::Black()); return creator_template<GPU::SPRT_8>(Vertex(), OffsetPageWithClut(), GPU::Color24::Black());
} }
static constexpr GPU::SPRT_8 SPRT_8(const GPU::Vertex& position, const GPU::OffsetPageWithClut& tex_offset_w_clut, const GPU::Color24& color = GPU::Color24::Grey()) { static constexpr GPU::SPRT_8 SPRT_8(const GPU::Vertex& position, const GPU::OffsetPageWithClut& tex_offset_w_clut, const GPU::Color24& color = GPU::Color24::Grey()) {
return creator_template<GPU::SPRT_8>(position, tex_offset_w_clut, color); return creator_template<GPU::SPRT_8>(position, tex_offset_w_clut, color);
} }
static constexpr GPU::SPRT_16 SPRT_16() { static constexpr GPU::SPRT_16 SPRT_16() {
return creator_template<GPU::SPRT_16>(Vertex(), OffsetPageWithClut(), GPU::Color24::Black()); return creator_template<GPU::SPRT_16>(Vertex(), OffsetPageWithClut(), GPU::Color24::Black());
} }
static constexpr GPU::SPRT_16 SPRT_16(const GPU::Vertex& position, const GPU::OffsetPageWithClut& tex_offset_w_clut, const GPU::Color24& color = GPU::Color24::Grey()) { static constexpr GPU::SPRT_16 SPRT_16(const GPU::Vertex& position, const GPU::OffsetPageWithClut& tex_offset_w_clut, const GPU::Color24& color = GPU::Color24::Grey()) {
return creator_template<GPU::SPRT_16>(position, tex_offset_w_clut, color); return creator_template<GPU::SPRT_16>(position, tex_offset_w_clut, color);
} }
static constexpr GPU::SPRT SPRT() { static constexpr GPU::SPRT SPRT() {
return creator_template<GPU::SPRT>(AreaI16(), OffsetPageWithClut(), GPU::Color24::Black()); return creator_template<GPU::SPRT>(AreaI16(), OffsetPageWithClut(), GPU::Color24::Black());
} }
static constexpr GPU::SPRT SPRT(const GPU::AreaI16& area, const GPU::OffsetPageWithClut& tex_offset_w_clut, const GPU::Color24& color = GPU::Color24::Grey()) { static constexpr GPU::SPRT SPRT(const GPU::AreaI16& area, const GPU::OffsetPageWithClut& tex_offset_w_clut, const GPU::Color24& color = GPU::Color24::Grey()) {
return creator_template<GPU::SPRT>(area, tex_offset_w_clut, color); return creator_template<GPU::SPRT>(area, tex_offset_w_clut, color);
} }
} }
} }

View File

@ -1,241 +1,241 @@
#pragma once #pragma once
#include "gte_instruction.hpp" #include "gte_instruction.hpp"
namespace JabyEngine { namespace JabyEngine {
namespace GTE { namespace GTE {
static constexpr auto StackSize = 16; static constexpr auto StackSize = 16;
/* /*
matrix: first input matrix: first input
Sets the 3x3 constant rotation matrix and the parallel transfer vector from input Sets the 3x3 constant rotation matrix and the parallel transfer vector from input
*/ */
void set_matrix(const MATRIX& matrix); void set_matrix(const MATRIX& matrix);
/* /*
returns: current matrix returns: current matrix
Gets the current 3x3 constant rotation matrix and the parallel transfer vector Gets the current 3x3 constant rotation matrix and the parallel transfer vector
*/ */
MATRIX get_matrix(); MATRIX get_matrix();
/* /*
RotTrans RotTrans
Perform coordinate transformation using a rotation matrix Perform coordinate transformation using a rotation matrix
input: Input vector input: Input vector
output: Output vector output: Output vector
flag: flag output flag: flag output
*/ */
static void rot_trans(const SVECTOR& input, VECTOR& output, int32_t& flag) { static void rot_trans(const SVECTOR& input, VECTOR& output, int32_t& flag) {
ldv0(input); ldv0(input);
rt(); rt();
stlvnl(output); stlvnl(output);
stflg(flag); stflg(flag);
} }
/* /*
ScaleMatrix ScaleMatrix
m: Pointer to matrix (input/output) m: Pointer to matrix (input/output)
v: Pointer to scale vector (input) v: Pointer to scale vector (input)
result: m result: m
Scales m by v. The components of v are fixed point decimals in which 1.0 represents 4096 Scales m by v. The components of v are fixed point decimals in which 1.0 represents 4096
*/ */
static ROTMATRIX& scale_matrix(ROTMATRIX& m, const VECTOR& v) { static ROTMATRIX& scale_matrix(ROTMATRIX& m, const VECTOR& v) {
static const auto multiply_matrix_row = [](int32_t value, ROTMATRIX& matrix, size_t row) { static const auto multiply_matrix_row = [](int32_t value, ROTMATRIX& matrix, size_t row) {
ldir0(value); // lwc2 r8, v.x ldir0(value); // lwc2 r8, v.x
ldclmv(matrix, row); // load matrix row to r9 - r11 (mtc2) ldclmv(matrix, row); // load matrix row to r9 - r11 (mtc2)
gpf12(); // gte_gpf12 gpf12(); // gte_gpf12
stclmv(matrix, row); // store matrix row stclmv(matrix, row); // store matrix row
}; };
multiply_matrix_row(v.x, m, 0); multiply_matrix_row(v.x, m, 0);
multiply_matrix_row(v.y, m, 1); multiply_matrix_row(v.y, m, 1);
multiply_matrix_row(v.z, m, 2); multiply_matrix_row(v.z, m, 2);
return m; return m;
} }
/* /*
SetRotMatrix SetRotMatrix
Sets a 3x3 matrix m as a constant rotation matrix. Sets a 3x3 matrix m as a constant rotation matrix.
matrix: The rotation matrix to set matrix: The rotation matrix to set
*/ */
static void set_rot_matrix(const ROTMATRIX& matrix) { static void set_rot_matrix(const ROTMATRIX& matrix) {
__asm__ volatile("lw $12, 0(%0)" :: "r"(&matrix) : "$12", "$13", "$14"); __asm__ volatile("lw $12, 0(%0)" :: "r"(&matrix) : "$12", "$13", "$14");
__asm__ volatile("lw $13, 4(%0)" :: "r"(&matrix) : "$12", "$13", "$14"); __asm__ volatile("lw $13, 4(%0)" :: "r"(&matrix) : "$12", "$13", "$14");
__asm__ volatile("ctc2 $12, $0" :: "r"(&matrix) : "$12", "$13", "$14"); __asm__ volatile("ctc2 $12, $0" :: "r"(&matrix) : "$12", "$13", "$14");
__asm__ volatile("ctc2 $13, $1" :: "r"(&matrix) : "$12", "$13", "$14"); __asm__ volatile("ctc2 $13, $1" :: "r"(&matrix) : "$12", "$13", "$14");
__asm__ volatile("lw $12, 8(%0)" :: "r"(&matrix) : "$12", "$13", "$14"); __asm__ volatile("lw $12, 8(%0)" :: "r"(&matrix) : "$12", "$13", "$14");
__asm__ volatile("lw $13, 12(%0)" :: "r"(&matrix) : "$12", "$13", "$14"); __asm__ volatile("lw $13, 12(%0)" :: "r"(&matrix) : "$12", "$13", "$14");
__asm__ volatile("lw $14, 16(%0)" :: "r"(&matrix) : "$12", "$13", "$14"); __asm__ volatile("lw $14, 16(%0)" :: "r"(&matrix) : "$12", "$13", "$14");
__asm__ volatile("ctc2 $12, $2" :: "r"(&matrix) : "$12", "$13", "$14"); __asm__ volatile("ctc2 $12, $2" :: "r"(&matrix) : "$12", "$13", "$14");
__asm__ volatile("ctc2 $13, $3" :: "r"(&matrix) : "$12", "$13", "$14"); __asm__ volatile("ctc2 $13, $3" :: "r"(&matrix) : "$12", "$13", "$14");
__asm__ volatile("ctc2 $14, $4" :: "r"(&matrix) : "$12", "$13", "$14"); __asm__ volatile("ctc2 $14, $4" :: "r"(&matrix) : "$12", "$13", "$14");
} }
/* /*
GetRotMatrix GetRotMatrix
Writes the current 3x3 constant rotation matrix to matrix Writes the current 3x3 constant rotation matrix to matrix
(This doesn't require us to use memory clobber) (This doesn't require us to use memory clobber)
*/ */
static void get_rot_matrix(ROTMATRIX &matrix) { static void get_rot_matrix(ROTMATRIX &matrix) {
__asm__ volatile("cfc2 $12, $0" :: "r"(&matrix) : "$12", "$13", "$14"); __asm__ volatile("cfc2 $12, $0" :: "r"(&matrix) : "$12", "$13", "$14");
__asm__ volatile("cfc2 $13, $1" :: "r"(&matrix) : "$12", "$13", "$14"); __asm__ volatile("cfc2 $13, $1" :: "r"(&matrix) : "$12", "$13", "$14");
__asm__ volatile("sw $12, 0(%0)" :: "r"(&matrix) : "$12", "$13", "$14"); __asm__ volatile("sw $12, 0(%0)" :: "r"(&matrix) : "$12", "$13", "$14");
__asm__ volatile("sw $13, 4(%0)" :: "r"(&matrix) : "$12", "$13", "$14"); __asm__ volatile("sw $13, 4(%0)" :: "r"(&matrix) : "$12", "$13", "$14");
__asm__ volatile("cfc2 $12, $2" :: "r"(&matrix) : "$12", "$13", "$14"); __asm__ volatile("cfc2 $12, $2" :: "r"(&matrix) : "$12", "$13", "$14");
__asm__ volatile("cfc2 $13, $3" :: "r"(&matrix) : "$12", "$13", "$14"); __asm__ volatile("cfc2 $13, $3" :: "r"(&matrix) : "$12", "$13", "$14");
__asm__ volatile("cfc2 $14, $4" :: "r"(&matrix) : "$12", "$13", "$14"); __asm__ volatile("cfc2 $14, $4" :: "r"(&matrix) : "$12", "$13", "$14");
__asm__ volatile("sw $12, 8(%0)" :: "r"(&matrix) : "$12", "$13", "$14"); __asm__ volatile("sw $12, 8(%0)" :: "r"(&matrix) : "$12", "$13", "$14");
__asm__ volatile("sw $13, 12(%0)" :: "r"(&matrix) : "$12", "$13", "$14"); __asm__ volatile("sw $13, 12(%0)" :: "r"(&matrix) : "$12", "$13", "$14");
__asm__ volatile("sw $14, 16(%0)" :: "r"(&matrix) : "$12", "$13", "$14"); __asm__ volatile("sw $14, 16(%0)" :: "r"(&matrix) : "$12", "$13", "$14");
} }
/* /*
SetTransMatrix SetTransMatrix
Sets a constant parallel transfer vector specified by m Sets a constant parallel transfer vector specified by m
*/ */
static void set_trans_vector(const TRANSFERVECTOR& vector) { static void set_trans_vector(const TRANSFERVECTOR& vector) {
__asm__ volatile("lw $12, 0(%0)" :: "r"(&vector) : "$12", "$13", "$14"); __asm__ volatile("lw $12, 0(%0)" :: "r"(&vector) : "$12", "$13", "$14");
__asm__ volatile("lw $13, 4(%0)" :: "r"(&vector) : "$12", "$13", "$14"); __asm__ volatile("lw $13, 4(%0)" :: "r"(&vector) : "$12", "$13", "$14");
__asm__ volatile("ctc2 $12, $5" :: "r"(&vector) : "$12", "$13", "$14"); __asm__ volatile("ctc2 $12, $5" :: "r"(&vector) : "$12", "$13", "$14");
__asm__ volatile("lw $14, 8(%0)" :: "r"(&vector) : "$12", "$13", "$14"); __asm__ volatile("lw $14, 8(%0)" :: "r"(&vector) : "$12", "$13", "$14");
__asm__ volatile("ctc2 $13, $6" :: "r"(&vector) : "$12", "$13", "$14"); __asm__ volatile("ctc2 $13, $6" :: "r"(&vector) : "$12", "$13", "$14");
__asm__ volatile("ctc2 $14, $7" :: "r"(&vector) : "$12", "$13", "$14"); __asm__ volatile("ctc2 $14, $7" :: "r"(&vector) : "$12", "$13", "$14");
} }
/* /*
GetTransMatrix GetTransMatrix
Writes the current constant parallel transfer vector to matrix Writes the current constant parallel transfer vector to matrix
(This doesn't require us to use memory clobber) (This doesn't require us to use memory clobber)
*/ */
static void get_trans_vector(TRANSFERVECTOR& vector) { static void get_trans_vector(TRANSFERVECTOR& vector) {
__asm__ volatile("cfc2 $14, $7" :: "r"(&vector) : "$12", "$13", "$14"); __asm__ volatile("cfc2 $14, $7" :: "r"(&vector) : "$12", "$13", "$14");
__asm__ volatile("cfc2 $13, $6" :: "r"(&vector) : "$12", "$13", "$14"); __asm__ volatile("cfc2 $13, $6" :: "r"(&vector) : "$12", "$13", "$14");
__asm__ volatile("sw $14, 8(%0)" :: "r"(&vector) : "$12", "$13", "$14"); __asm__ volatile("sw $14, 8(%0)" :: "r"(&vector) : "$12", "$13", "$14");
__asm__ volatile("cfc2 $12, $5" :: "r"(&vector) : "$12", "$13", "$14"); __asm__ volatile("cfc2 $12, $5" :: "r"(&vector) : "$12", "$13", "$14");
__asm__ volatile("sw $13, 4(%0)" :: "r"(&vector) : "$12", "$13", "$14"); __asm__ volatile("sw $13, 4(%0)" :: "r"(&vector) : "$12", "$13", "$14");
__asm__ volatile("sw $12, 0(%0)" :: "r"(&vector) : "$12", "$13", "$14"); __asm__ volatile("sw $12, 0(%0)" :: "r"(&vector) : "$12", "$13", "$14");
} }
/* /*
ApplyMatrix ApplyMatrix
m0: Matrix to apply m0: Matrix to apply
v0: Vector to apply to v0: Vector to apply to
v1: Result v1: Result
returns: result returns: result
Applies the matrix to the vector Applies the matrix to the vector
The function destroys the constant rotation matrix and transfer vector The function destroys the constant rotation matrix and transfer vector
*/ */
static SVECTOR& apply_matrix(const MATRIX& m0, const SVECTOR& v0, SVECTOR& v1) { static SVECTOR& apply_matrix(const MATRIX& m0, const SVECTOR& v0, SVECTOR& v1) {
set_matrix(m0); set_matrix(m0);
JabyEngine::GTE::ldv0(v0); JabyEngine::GTE::ldv0(v0);
JabyEngine::GTE::rt(); JabyEngine::GTE::rt();
JabyEngine::GTE::stsv(v1); JabyEngine::GTE::stsv(v1);
return v1; return v1;
} }
/* /*
Same as apply_matrix but works on Vertex Same as apply_matrix but works on Vertex
*/ */
static GPU::Vertex& apply_matrix(const MATRIX& m0, const GPU::Vertex& v0, GPU::Vertex& v1) { static GPU::Vertex& apply_matrix(const MATRIX& m0, const GPU::Vertex& v0, GPU::Vertex& v1) {
set_matrix(m0); set_matrix(m0);
JabyEngine::GTE::ldgv0(v0); JabyEngine::GTE::ldgv0(v0);
JabyEngine::GTE::rt(); JabyEngine::GTE::rt();
JabyEngine::GTE::stgv(v1); JabyEngine::GTE::stgv(v1);
return v1; return v1;
} }
/* /*
MulMatrix0 MulMatrix0
m0: first input m0: first input
m1: second input m1: second input
result: result of multiplication result: result of multiplication
returns: result returns: result
Multiplies two matrices m0 and m1. Multiplies two matrices m0 and m1.
The function destroys the constant rotation matrix The function destroys the constant rotation matrix
*/ */
ROTMATRIX& multiply_matrix(const ROTMATRIX& m0, const ROTMATRIX& m1, ROTMATRIX& result); ROTMATRIX& multiply_matrix(const ROTMATRIX& m0, const ROTMATRIX& m1, ROTMATRIX& result);
/* /*
CompMatrix CompMatrix
m0: first input m0: first input
m1: second input m1: second input
result: result of computing m0 and m1 result: result of computing m0 and m1
return: returns result return: returns result
*/ */
static MATRIX& comp_matrix(const MATRIX& m0, const MATRIX& m1, MATRIX& result) { static MATRIX& comp_matrix(const MATRIX& m0, const MATRIX& m1, MATRIX& result) {
multiply_matrix(m0.rotation, m1.rotation, result.rotation); multiply_matrix(m0.rotation, m1.rotation, result.rotation);
set_trans_vector(m0.transfer); set_trans_vector(m0.transfer);
GTE::ldlv0(reinterpret_cast<const VECTOR&>(m1.transfer)); GTE::ldlv0(reinterpret_cast<const VECTOR&>(m1.transfer));
GTE::rt(); GTE::rt();
GTE::stlvnl(reinterpret_cast<VECTOR&>(result.transfer)); GTE::stlvnl(reinterpret_cast<VECTOR&>(result.transfer));
return result; return result;
} }
/* /*
matrix: optional input matrix: optional input
Pushes the current matrix (rotation and parallel) to an internal stack Pushes the current matrix (rotation and parallel) to an internal stack
Optional: replaces current matrix (rotation and parallel) with input Optional: replaces current matrix (rotation and parallel) with input
*/ */
void push_matrix(); void push_matrix();
void push_matrix_and_set(const MATRIX& matrix); void push_matrix_and_set(const MATRIX& matrix);
/* /*
Restores the previous stored matrix (rotation and parallel) Restores the previous stored matrix (rotation and parallel)
*/ */
MATRIX get_and_pop_matrix(); MATRIX get_and_pop_matrix();
void pop_matrix(); void pop_matrix();
/* /*
SetGeomOffset(ofx,ofy) SetGeomOffset(ofx,ofy)
Load GTE-offset. Load GTE-offset.
*/ */
static void set_geom_offset(int32_t off_x, int32_t off_y) { static void set_geom_offset(int32_t off_x, int32_t off_y) {
__asm__ volatile("sll $12, %0, 16" :: "r"(off_x), "r"(off_y) : "$12", "$13"); __asm__ volatile("sll $12, %0, 16" :: "r"(off_x), "r"(off_y) : "$12", "$13");
__asm__ volatile("sll $13, %1, 16" :: "r"(off_x), "r"(off_y) : "$12", "$13"); __asm__ volatile("sll $13, %1, 16" :: "r"(off_x), "r"(off_y) : "$12", "$13");
__asm__ volatile("ctc2 $12, $24" :: "r"(off_x), "r"(off_y) : "$12", "$13"); __asm__ volatile("ctc2 $12, $24" :: "r"(off_x), "r"(off_y) : "$12", "$13");
__asm__ volatile("ctc2 $13, $25" :: "r"(off_x), "r"(off_y) : "$12", "$13"); __asm__ volatile("ctc2 $13, $25" :: "r"(off_x), "r"(off_y) : "$12", "$13");
} }
/* /*
SetGeomScreen(h) SetGeomScreen(h)
Load distance from viewpoint to screen. Load distance from viewpoint to screen.
*/ */
static void set_geom_screen(int32_t h) { static void set_geom_screen(int32_t h) {
__asm__ volatile("ctc2 %0, $26" :: "r"(h)); __asm__ volatile("ctc2 %0, $26" :: "r"(h));
} }
// Implementations for the MATRIX struct // Implementations for the MATRIX struct
inline MATRIX& MATRIX :: comp(const MATRIX& matrix) { inline MATRIX& MATRIX :: comp(const MATRIX& matrix) {
return comp_matrix(matrix, *this, *this); return comp_matrix(matrix, *this, *this);
} }
inline GPU::Vertex& MATRIX :: apply_to(GPU::Vertex& vertex) const { inline GPU::Vertex& MATRIX :: apply_to(GPU::Vertex& vertex) const {
return apply_matrix(*this, vertex, vertex); return apply_matrix(*this, vertex, vertex);
} }
inline GPU::Vertex MATRIX :: apply_to(const GPU::Vertex& vertex) const { inline GPU::Vertex MATRIX :: apply_to(const GPU::Vertex& vertex) const {
GPU::Vertex result; GPU::Vertex result;
apply_matrix(*this, vertex, result); apply_matrix(*this, vertex, result);
return result; return result;
} }
} }
} }

View File

@ -1,137 +1,137 @@
#pragma once #pragma once
#include "gte_types.hpp" #include "gte_types.hpp"
namespace JabyEngine { namespace JabyEngine {
namespace GTE { namespace GTE {
// Load vertex or normal to vertex register 0 // Load vertex or normal to vertex register 0
static __always_inline void ldv0(const SVECTOR& vector) { static __always_inline void ldv0(const SVECTOR& vector) {
__asm__ volatile("lwc2 $0, 0(%0)" :: "r"(&vector)); __asm__ volatile("lwc2 $0, 0(%0)" :: "r"(&vector));
__asm__ volatile("lwc2 $1, 4(%0)" :: "r"(&vector)); __asm__ volatile("lwc2 $1, 4(%0)" :: "r"(&vector));
} }
// Load vertex or normal to vertex register 1 // Load vertex or normal to vertex register 1
static __always_inline void ldv1(const SVECTOR& vector) { static __always_inline void ldv1(const SVECTOR& vector) {
__asm__ volatile("lwc2 $2, 0(%0)" :: "r"(&vector)); __asm__ volatile("lwc2 $2, 0(%0)" :: "r"(&vector));
__asm__ volatile("lwc2 $3, 4(%0)" :: "r"(&vector)); __asm__ volatile("lwc2 $3, 4(%0)" :: "r"(&vector));
} }
// Load vertex or normal to vertex register 2 // Load vertex or normal to vertex register 2
static __always_inline void ldv2(const SVECTOR& vector) { static __always_inline void ldv2(const SVECTOR& vector) {
__asm__ volatile("lwc2 $4, 0(%0)" :: "r"(&vector)); __asm__ volatile("lwc2 $4, 0(%0)" :: "r"(&vector));
__asm__ volatile("lwc2 $5, 4(%0)" :: "r"(&vector)); __asm__ volatile("lwc2 $5, 4(%0)" :: "r"(&vector));
} }
// Load int32_t to ir0 register (for multiplying usually) // Load int32_t to ir0 register (for multiplying usually)
static __always_inline void ldir0(const int32_t& value) { static __always_inline void ldir0(const int32_t& value) {
__asm__ volatile("lwc2 $8, 0(%0)" :: "r"(&value)); __asm__ volatile("lwc2 $8, 0(%0)" :: "r"(&value));
} }
// Load LS 16 bits of VECTOR to 16 bit universal vector. // Load LS 16 bits of VECTOR to 16 bit universal vector.
static __always_inline void ldlv0(const VECTOR& vector) { static __always_inline void ldlv0(const VECTOR& vector) {
__asm__ volatile("lhu $13, 4(%0)" :: "r"(&vector) : "$12", "$13"); __asm__ volatile("lhu $13, 4(%0)" :: "r"(&vector) : "$12", "$13");
__asm__ volatile("lhu $12, 0(%0)" :: "r"(&vector) : "$12", "$13"); __asm__ volatile("lhu $12, 0(%0)" :: "r"(&vector) : "$12", "$13");
__asm__ volatile("sll $13, $13, 16" :: "r"(&vector) : "$12", "$13"); __asm__ volatile("sll $13, $13, 16" :: "r"(&vector) : "$12", "$13");
__asm__ volatile("or $12, $12, $13" :: "r"(&vector) : "$12", "$13"); __asm__ volatile("or $12, $12, $13" :: "r"(&vector) : "$12", "$13");
__asm__ volatile("mtc2 $12, $0" :: "r"(&vector) : "$12", "$13"); __asm__ volatile("mtc2 $12, $0" :: "r"(&vector) : "$12", "$13");
__asm__ volatile("lwc2 $1, 8(%0)" :: "r"(&vector) : "$12", "$13"); __asm__ volatile("lwc2 $1, 8(%0)" :: "r"(&vector) : "$12", "$13");
} }
// Loads a GPU VERTEX type // Loads a GPU VERTEX type
static __always_inline void ldgv0(const GPU::Vertex& vertex) { static __always_inline void ldgv0(const GPU::Vertex& vertex) {
__asm__ volatile("lwc2 $0, 0(%0)" :: "r"(&vertex)); __asm__ volatile("lwc2 $0, 0(%0)" :: "r"(&vertex));
__asm__ volatile("lwc2 $1, 0" :: "r"(&vertex)); __asm__ volatile("lwc2 $1, 0" :: "r"(&vertex));
} }
// Load column vector of MATRIX to universal register // Load column vector of MATRIX to universal register
static __always_inline void ldclmv(const ROTMATRIX& matrix, size_t col) { static __always_inline void ldclmv(const ROTMATRIX& matrix, size_t col) {
__asm__ volatile("lhu $12, 0(%0)" :: "r"(reinterpret_cast<uintptr_t>(&matrix) + (col << 1)) : "$12", "$13", "$14"); __asm__ volatile("lhu $12, 0(%0)" :: "r"(reinterpret_cast<uintptr_t>(&matrix) + (col << 1)) : "$12", "$13", "$14");
__asm__ volatile("lhu $13, 6(%0)" :: "r"(reinterpret_cast<uintptr_t>(&matrix) + (col << 1)) : "$12", "$13", "$14"); __asm__ volatile("lhu $13, 6(%0)" :: "r"(reinterpret_cast<uintptr_t>(&matrix) + (col << 1)) : "$12", "$13", "$14");
__asm__ volatile("lhu $14, 12(%0)" :: "r"(reinterpret_cast<uintptr_t>(&matrix) + (col << 1)) : "$12", "$13", "$14"); __asm__ volatile("lhu $14, 12(%0)" :: "r"(reinterpret_cast<uintptr_t>(&matrix) + (col << 1)) : "$12", "$13", "$14");
__asm__ volatile("mtc2 $12, $9" :: "r"(reinterpret_cast<uintptr_t>(&matrix) + (col << 1)) : "$12", "$13", "$14"); __asm__ volatile("mtc2 $12, $9" :: "r"(reinterpret_cast<uintptr_t>(&matrix) + (col << 1)) : "$12", "$13", "$14");
__asm__ volatile("mtc2 $13, $10" :: "r"(reinterpret_cast<uintptr_t>(&matrix) + (col << 1)) : "$12", "$13", "$14"); __asm__ volatile("mtc2 $13, $10" :: "r"(reinterpret_cast<uintptr_t>(&matrix) + (col << 1)) : "$12", "$13", "$14");
__asm__ volatile("mtc2 $14, $11" :: "r"(reinterpret_cast<uintptr_t>(&matrix) + (col << 1)) : "$12", "$13", "$14"); __asm__ volatile("mtc2 $14, $11" :: "r"(reinterpret_cast<uintptr_t>(&matrix) + (col << 1)) : "$12", "$13", "$14");
} }
// Store flag // Store flag
static __always_inline void stflg(int32_t& flag) { static __always_inline void stflg(int32_t& flag) {
__asm__ volatile("cfc2 $12, $31" :: "r"(&flag) : "$12", "memory"); __asm__ volatile("cfc2 $12, $31" :: "r"(&flag) : "$12", "memory");
__asm__ volatile("nop" :: "r"(&flag) : "$12", "memory"); __asm__ volatile("nop" :: "r"(&flag) : "$12", "memory");
__asm__ volatile("sw $12, 0(%0)" :: "r"(&flag) : "$12", "memory"); __asm__ volatile("sw $12, 0(%0)" :: "r"(&flag) : "$12", "memory");
} }
// Store MATRIX column from 16 bit universal register // Store MATRIX column from 16 bit universal register
static __always_inline void stclmv(ROTMATRIX& matrix, size_t col) { static __always_inline void stclmv(ROTMATRIX& matrix, size_t col) {
__asm__ volatile("mfc2 $12, $9" :: "r"(reinterpret_cast<uintptr_t>(&matrix) + (col << 1)) : "$12", "$13", "$14", "memory"); __asm__ volatile("mfc2 $12, $9" :: "r"(reinterpret_cast<uintptr_t>(&matrix) + (col << 1)) : "$12", "$13", "$14", "memory");
__asm__ volatile("mfc2 $13, $10" :: "r"(reinterpret_cast<uintptr_t>(&matrix) + (col << 1)) : "$12", "$13", "$14", "memory"); __asm__ volatile("mfc2 $13, $10" :: "r"(reinterpret_cast<uintptr_t>(&matrix) + (col << 1)) : "$12", "$13", "$14", "memory");
__asm__ volatile("mfc2 $14, $11" :: "r"(reinterpret_cast<uintptr_t>(&matrix) + (col << 1)) : "$12", "$13", "$14", "memory"); __asm__ volatile("mfc2 $14, $11" :: "r"(reinterpret_cast<uintptr_t>(&matrix) + (col << 1)) : "$12", "$13", "$14", "memory");
__asm__ volatile("sh $12, 0(%0)" :: "r"(reinterpret_cast<uintptr_t>(&matrix) + (col << 1)) : "$12", "$13", "$14", "memory"); __asm__ volatile("sh $12, 0(%0)" :: "r"(reinterpret_cast<uintptr_t>(&matrix) + (col << 1)) : "$12", "$13", "$14", "memory");
__asm__ volatile("sh $13, 6(%0)" :: "r"(reinterpret_cast<uintptr_t>(&matrix) + (col << 1)) : "$12", "$13", "$14", "memory"); __asm__ volatile("sh $13, 6(%0)" :: "r"(reinterpret_cast<uintptr_t>(&matrix) + (col << 1)) : "$12", "$13", "$14", "memory");
__asm__ volatile("sh $14, 12(%0)" :: "r"(reinterpret_cast<uintptr_t>(&matrix) + (col << 1)) : "$12", "$13", "$14", "memory"); __asm__ volatile("sh $14, 12(%0)" :: "r"(reinterpret_cast<uintptr_t>(&matrix) + (col << 1)) : "$12", "$13", "$14", "memory");
} }
// Store VECTOR from 32 bit universal register // Store VECTOR from 32 bit universal register
static __always_inline void stlvnl(VECTOR& out_vector) { static __always_inline void stlvnl(VECTOR& out_vector) {
__asm__ volatile("swc2 $25, 0(%0)" :: "r"(&out_vector) : "memory"); __asm__ volatile("swc2 $25, 0(%0)" :: "r"(&out_vector) : "memory");
__asm__ volatile("swc2 $26, 4(%0)" :: "r"(&out_vector) : "memory"); __asm__ volatile("swc2 $26, 4(%0)" :: "r"(&out_vector) : "memory");
__asm__ volatile("swc2 $27, 8(%0)" :: "r"(&out_vector) : "memory"); __asm__ volatile("swc2 $27, 8(%0)" :: "r"(&out_vector) : "memory");
} }
// Modify to store in VERTEX? // Modify to store in VERTEX?
// Store SVECTOR from 16 bit universal register // Store SVECTOR from 16 bit universal register
static __always_inline void stsv(SVECTOR& out_vector) { static __always_inline void stsv(SVECTOR& out_vector) {
__asm__ volatile("mfc2 $12, $9" :: "r"(&out_vector) : "$12", "$13", "$14", "memory"); __asm__ volatile("mfc2 $12, $9" :: "r"(&out_vector) : "$12", "$13", "$14", "memory");
__asm__ volatile("mfc2 $13, $10" :: "r"(&out_vector) : "$12", "$13", "$14", "memory"); __asm__ volatile("mfc2 $13, $10" :: "r"(&out_vector) : "$12", "$13", "$14", "memory");
__asm__ volatile("mfc2 $14, $11" :: "r"(&out_vector) : "$12", "$13", "$14", "memory"); __asm__ volatile("mfc2 $14, $11" :: "r"(&out_vector) : "$12", "$13", "$14", "memory");
__asm__ volatile("sh $12, 0(%0)" :: "r"(&out_vector) : "$12", "$13", "$14", "memory"); __asm__ volatile("sh $12, 0(%0)" :: "r"(&out_vector) : "$12", "$13", "$14", "memory");
__asm__ volatile("sh $13, 2(%0)" :: "r"(&out_vector) : "$12", "$13", "$14", "memory"); __asm__ volatile("sh $13, 2(%0)" :: "r"(&out_vector) : "$12", "$13", "$14", "memory");
__asm__ volatile("sh $14, 4(%0)" :: "r"(&out_vector) : "$12", "$13", "$14", "memory"); __asm__ volatile("sh $14, 4(%0)" :: "r"(&out_vector) : "$12", "$13", "$14", "memory");
} }
// Stores result into a GPU Vertex type // Stores result into a GPU Vertex type
static __always_inline void stgv(GPU::Vertex& out_vertex) { static __always_inline void stgv(GPU::Vertex& out_vertex) {
__asm__ volatile("mfc2 $12, $9" :: "r"(&out_vertex) : "$12", "$13", "$14", "memory"); __asm__ volatile("mfc2 $12, $9" :: "r"(&out_vertex) : "$12", "$13", "$14", "memory");
__asm__ volatile("mfc2 $13, $10" :: "r"(&out_vertex) : "$12", "$13", "$14", "memory"); __asm__ volatile("mfc2 $13, $10" :: "r"(&out_vertex) : "$12", "$13", "$14", "memory");
__asm__ volatile("sh $12, 0(%0)" :: "r"(&out_vertex) : "$12", "$13", "$14", "memory"); __asm__ volatile("sh $12, 0(%0)" :: "r"(&out_vertex) : "$12", "$13", "$14", "memory");
__asm__ volatile("sh $13, 2(%0)" :: "r"(&out_vertex) : "$12", "$13", "$14", "memory"); __asm__ volatile("sh $13, 2(%0)" :: "r"(&out_vertex) : "$12", "$13", "$14", "memory");
} }
/* /*
Kernel of RotTrans Kernel of RotTrans
(Transfer vector)+(Rotation Matrix)*(vertex register 0) (Transfer vector)+(Rotation Matrix)*(vertex register 0)
*/ */
static __always_inline void rt() { static __always_inline void rt() {
__asm__ volatile("nop"); __asm__ volatile("nop");
__asm__ volatile("nop"); __asm__ volatile("nop");
__asm__ volatile("cop2 0x0480012"); __asm__ volatile("cop2 0x0480012");
} }
/* /*
Variation of gte_rt Variation of gte_rt
(Rotation Matrix)*(vertex register 0). (Rotation Matrix)*(vertex register 0).
*/ */
static __always_inline void rtv0() { static __always_inline void rtv0() {
__asm__ volatile("nop;"); __asm__ volatile("nop;");
__asm__ volatile("nop;"); __asm__ volatile("nop;");
__asm__ volatile("cop2 0x0486012;"); __asm__ volatile("cop2 0x0486012;");
} }
/* /*
Variation of gte_rt Variation of gte_rt
(Rotation Matrix)*(16 bit universal vector) (Rotation Matrix)*(16 bit universal vector)
*/ */
static __always_inline void rtir() { static __always_inline void rtir() {
__asm__ volatile("nop"); __asm__ volatile("nop");
__asm__ volatile("nop"); __asm__ volatile("nop");
__asm__ volatile("cop2 0x049E012"); __asm__ volatile("cop2 0x049E012");
} }
/* /*
Last half of LoadAverage12. Last half of LoadAverage12.
*/ */
static __always_inline void gpf12(){ static __always_inline void gpf12(){
__asm__ volatile("nop"); __asm__ volatile("nop");
__asm__ volatile("nop"); __asm__ volatile("nop");
__asm__ volatile("cop2 0x0198003D"); __asm__ volatile("cop2 0x0198003D");
} }
} }
} }

View File

@ -1,138 +1,138 @@
#pragma once #pragma once
#include "../GPU/Primitives/primitive_poly_types.hpp" #include "../GPU/Primitives/primitive_poly_types.hpp"
#include "../GPU/gpu_types.hpp" #include "../GPU/gpu_types.hpp"
#include "../../math.hpp" #include "../../math.hpp"
#include "../../stdio.hpp" #include "../../stdio.hpp"
namespace JabyEngine { namespace JabyEngine {
namespace GTE { namespace GTE {
namespace internal { namespace internal {
template<typename T> template<typename T>
struct VECTOR { struct VECTOR {
T x; T x;
T y; T y;
T z; T z;
T pad; T pad;
static constexpr VECTOR create() { static constexpr VECTOR create() {
return VECTOR::create(0, 0, 0); return VECTOR::create(0, 0, 0);
} }
static constexpr VECTOR create(T x, T y, T z) { static constexpr VECTOR create(T x, T y, T z) {
return VECTOR{.x = x, .y = y, .z = z, .pad = 0}; return VECTOR{.x = x, .y = y, .z = z, .pad = 0};
} }
static constexpr VECTOR create(gte_float x, gte_float y, gte_float z) { static constexpr VECTOR create(gte_float x, gte_float y, gte_float z) {
return VECTOR{.x = static_cast<T>(x), .y = static_cast<T>(y), .z = static_cast<T>(z)}; return VECTOR{.x = static_cast<T>(x), .y = static_cast<T>(y), .z = static_cast<T>(z)};
} }
template<typename S> template<typename S>
static constexpr VECTOR from(const GPU::Position<S>& pos) { static constexpr VECTOR from(const GPU::Position<S>& pos) {
return VECTOR::create(static_cast<T>(pos.x), static_cast<T>(pos.y), 0); return VECTOR::create(static_cast<T>(pos.x), static_cast<T>(pos.y), 0);
} }
template<typename S> template<typename S>
constexpr S to() const { constexpr S to() const {
return S::create(static_cast<S::PrimitiveType>(this->x), static_cast<S::PrimitiveType>(this->y)); return S::create(static_cast<S::PrimitiveType>(this->x), static_cast<S::PrimitiveType>(this->y));
} }
}; };
} }
using VECTOR = internal::VECTOR<int32_t>; using VECTOR = internal::VECTOR<int32_t>;
using SVECTOR = internal::VECTOR<int16_t>; using SVECTOR = internal::VECTOR<int16_t>;
struct ROTMATRIX { struct ROTMATRIX {
int16_t matrix[3][3]; int16_t matrix[3][3];
static constexpr ROTMATRIX identity() { static constexpr ROTMATRIX identity() {
return ROTMATRIX{.matrix = { return ROTMATRIX{.matrix = {
{static_cast<int16_t>(gte_float::one()), 0, 0}, {static_cast<int16_t>(gte_float::one()), 0, 0},
{0, static_cast<int16_t>(gte_float::one()), 0}, {0, static_cast<int16_t>(gte_float::one()), 0},
{0, 0, static_cast<int16_t>(gte_float::one())} {0, 0, static_cast<int16_t>(gte_float::one())}
} }
}; };
} }
static constexpr ROTMATRIX scaled(gte_float sx = 1.0_gf, gte_float sy = 1.0_gf, gte_float sz = 1.0_gf) { static constexpr ROTMATRIX scaled(gte_float sx = 1.0_gf, gte_float sy = 1.0_gf, gte_float sz = 1.0_gf) {
return ROTMATRIX{.matrix = { return ROTMATRIX{.matrix = {
{static_cast<int16_t>(sx), 0, 0}, {static_cast<int16_t>(sx), 0, 0},
{0, static_cast<int16_t>(sy), 0}, {0, static_cast<int16_t>(sy), 0},
{0, 0, static_cast<int16_t>(sz)} {0, 0, static_cast<int16_t>(sz)}
} }
}; };
} }
static ROTMATRIX rotated(deg_t x = 0.0_deg, deg_t y = 0.0_deg, deg_t z = 0.0_deg); static ROTMATRIX rotated(deg_t x = 0.0_deg, deg_t y = 0.0_deg, deg_t z = 0.0_deg);
}; };
struct TRANSFERVECTOR : public VECTOR { struct TRANSFERVECTOR : public VECTOR {
static constexpr TRANSFERVECTOR identity() { static constexpr TRANSFERVECTOR identity() {
return TRANSFERVECTOR::translated(); return TRANSFERVECTOR::translated();
} }
static constexpr TRANSFERVECTOR translated(int32_t x = 0, int32_t y = 0, int32_t z = 0) { static constexpr TRANSFERVECTOR translated(int32_t x = 0, int32_t y = 0, int32_t z = 0) {
return TRANSFERVECTOR{{.x = x, .y = y, .z = z}}; return TRANSFERVECTOR{{.x = x, .y = y, .z = z}};
} }
}; };
struct MATRIX { struct MATRIX {
ROTMATRIX rotation; ROTMATRIX rotation;
TRANSFERVECTOR transfer; TRANSFERVECTOR transfer;
static constexpr MATRIX identity() { static constexpr MATRIX identity() {
return MATRIX{.rotation = ROTMATRIX::identity(), .transfer = TRANSFERVECTOR::identity()}; return MATRIX{.rotation = ROTMATRIX::identity(), .transfer = TRANSFERVECTOR::identity()};
} }
static constexpr MATRIX translated(int32_t x = 0, int32_t y = 0, int32_t z = 0) { static constexpr MATRIX translated(int32_t x = 0, int32_t y = 0, int32_t z = 0) {
return MATRIX{.rotation = ROTMATRIX::identity(), .transfer = TRANSFERVECTOR::translated(x, y, z)}; return MATRIX{.rotation = ROTMATRIX::identity(), .transfer = TRANSFERVECTOR::translated(x, y, z)};
} }
static constexpr MATRIX scaled(gte_float sx = 1.0_gf, gte_float sy = 1.0_gf, gte_float sz = 1.0_gf) { static constexpr MATRIX scaled(gte_float sx = 1.0_gf, gte_float sy = 1.0_gf, gte_float sz = 1.0_gf) {
return MATRIX{.rotation = ROTMATRIX::scaled(sx, sy, sz), .transfer = TRANSFERVECTOR::identity()}; return MATRIX{.rotation = ROTMATRIX::scaled(sx, sy, sz), .transfer = TRANSFERVECTOR::identity()};
} }
static MATRIX rotated(deg_t x = 0.0_deg, deg_t y = 0.0_deg, deg_t z = 0.0_deg) { static MATRIX rotated(deg_t x = 0.0_deg, deg_t y = 0.0_deg, deg_t z = 0.0_deg) {
return MATRIX{.rotation = ROTMATRIX::rotated(x, y, z), .transfer = TRANSFERVECTOR::identity()}; return MATRIX{.rotation = ROTMATRIX::rotated(x, y, z), .transfer = TRANSFERVECTOR::identity()};
} }
static MATRIX comp(MATRIX new_matrix, const MATRIX& matrix) { static MATRIX comp(MATRIX new_matrix, const MATRIX& matrix) {
new_matrix.comp(matrix); new_matrix.comp(matrix);
return new_matrix; return new_matrix;
} }
void dump() const { void dump() const {
printf("---\n"); printf("---\n");
printf("|%i|%i|%i|\n", this->rotation.matrix[0][0], this->rotation.matrix[0][1], this->rotation.matrix[0][2]); printf("|%i|%i|%i|\n", this->rotation.matrix[0][0], this->rotation.matrix[0][1], this->rotation.matrix[0][2]);
printf("|%i|%i|%i|\n", this->rotation.matrix[1][0], this->rotation.matrix[1][1], this->rotation.matrix[1][2]); printf("|%i|%i|%i|\n", this->rotation.matrix[1][0], this->rotation.matrix[1][1], this->rotation.matrix[1][2]);
printf("|%i|%i|%i|\n", this->rotation.matrix[2][0], this->rotation.matrix[2][1], this->rotation.matrix[2][2]); printf("|%i|%i|%i|\n", this->rotation.matrix[2][0], this->rotation.matrix[2][1], this->rotation.matrix[2][2]);
printf("~~~\n"); printf("~~~\n");
printf("|%i|%i|%i|\n", this->transfer.x, this->transfer.y, this->transfer.z); printf("|%i|%i|%i|\n", this->transfer.x, this->transfer.y, this->transfer.z);
printf("---\n"); printf("---\n");
} }
MATRIX& comp(const MATRIX& matrix); MATRIX& comp(const MATRIX& matrix);
MATRIX& translate(int32_t x = 0, int32_t y = 0, int32_t z = 0) { MATRIX& translate(int32_t x = 0, int32_t y = 0, int32_t z = 0) {
return MATRIX::comp(MATRIX::translated(x, y, z)); return MATRIX::comp(MATRIX::translated(x, y, z));
} }
MATRIX& scale(gte_float sx = 1.0_gf, gte_float sy = 1.0_gf, gte_float sz = 1.0_gf) { MATRIX& scale(gte_float sx = 1.0_gf, gte_float sy = 1.0_gf, gte_float sz = 1.0_gf) {
return MATRIX::comp(MATRIX::scaled(sx, sy, sz)); return MATRIX::comp(MATRIX::scaled(sx, sy, sz));
} }
MATRIX& rotate(deg_t x = 0.0_deg, deg_t y = 0.0_deg, deg_t z = 0.0_deg) { MATRIX& rotate(deg_t x = 0.0_deg, deg_t y = 0.0_deg, deg_t z = 0.0_deg) {
return MATRIX::comp(MATRIX::rotated(x, y, z)); return MATRIX::comp(MATRIX::rotated(x, y, z));
} }
GPU::Vertex& apply_to(GPU::Vertex& vertex) const; GPU::Vertex& apply_to(GPU::Vertex& vertex) const;
GPU::Vertex apply_to(const GPU::Vertex& vertex) const; GPU::Vertex apply_to(const GPU::Vertex& vertex) const;
template<typename T> template<typename T>
T& apply_to_area(T& poly, const GPU::AreaI16& area) const { T& apply_to_area(T& poly, const GPU::AreaI16& area) const {
poly.vertex0 = MATRIX::apply_to(GPU::POLY_G4::vertex0_from(area)); poly.vertex0 = MATRIX::apply_to(GPU::POLY_G4::vertex0_from(area));
poly.vertex1 = MATRIX::apply_to(GPU::POLY_G4::vertex1_from(area)); poly.vertex1 = MATRIX::apply_to(GPU::POLY_G4::vertex1_from(area));
poly.vertex2 = MATRIX::apply_to(GPU::POLY_G4::vertex2_from(area)); poly.vertex2 = MATRIX::apply_to(GPU::POLY_G4::vertex2_from(area));
poly.vertex3 = MATRIX::apply_to(GPU::POLY_G4::vertex3_from(area)); poly.vertex3 = MATRIX::apply_to(GPU::POLY_G4::vertex3_from(area));
return poly; return poly;
} }
}; };
} }
} }

View File

@ -1,107 +1,107 @@
#pragma once #pragma once
#include "../GPU/gpu_types.hpp" #include "../GPU/gpu_types.hpp"
#include "raw_controller.hpp" #include "raw_controller.hpp"
namespace JabyEngine { namespace JabyEngine {
namespace Periphery { namespace Periphery {
class GenericController : public RawController { class GenericController : public RawController {
public: public:
struct Rumble { struct Rumble {
static constexpr uint8_t LargeMotorThreshold = 0x60; static constexpr uint8_t LargeMotorThreshold = 0x60;
}; };
enum struct Button : uint16_t { enum struct Button : uint16_t {
L2 = static_cast<uint16_t>(GenericButton::D0), L2 = static_cast<uint16_t>(GenericButton::D0),
R2 = static_cast<uint16_t>(GenericButton::D1), R2 = static_cast<uint16_t>(GenericButton::D1),
L1 = static_cast<uint16_t>(GenericButton::D2), L1 = static_cast<uint16_t>(GenericButton::D2),
R1 = static_cast<uint16_t>(GenericButton::D3), R1 = static_cast<uint16_t>(GenericButton::D3),
Triangle = static_cast<uint16_t>(GenericButton::D4), Triangle = static_cast<uint16_t>(GenericButton::D4),
Circle = static_cast<uint16_t>(GenericButton::D5), Circle = static_cast<uint16_t>(GenericButton::D5),
Cross = static_cast<uint16_t>(GenericButton::D6), Cross = static_cast<uint16_t>(GenericButton::D6),
Square = static_cast<uint16_t>(GenericButton::D7), Square = static_cast<uint16_t>(GenericButton::D7),
SEL = static_cast<uint16_t>(GenericButton::D8), SEL = static_cast<uint16_t>(GenericButton::D8),
ST = static_cast<uint16_t>(GenericButton::D11), ST = static_cast<uint16_t>(GenericButton::D11),
Up = static_cast<uint16_t>(GenericButton::D12), Up = static_cast<uint16_t>(GenericButton::D12),
Right = static_cast<uint16_t>(GenericButton::D13), Right = static_cast<uint16_t>(GenericButton::D13),
Down = static_cast<uint16_t>(GenericButton::D14), Down = static_cast<uint16_t>(GenericButton::D14),
Left = static_cast<uint16_t>(GenericButton::D15) Left = static_cast<uint16_t>(GenericButton::D15)
}; };
void set_digital_rumble() { void set_digital_rumble() {
RawController::header.rumble0 = 0x1; RawController::header.rumble0 = 0x1;
RawController::header.rumble1 = 0x7F; RawController::header.rumble1 = 0x7F;
} }
void set_analog_rumble(uint8_t largeMotor, bool smallMotor) { void set_analog_rumble(uint8_t largeMotor, bool smallMotor) {
RawController::header.rumble0 = smallMotor ? 0x1 : 0x0; RawController::header.rumble0 = smallMotor ? 0x1 : 0x0;
RawController::header.rumble1 = largeMotor; RawController::header.rumble1 = largeMotor;
} }
void stopRumble() { void stopRumble() {
RawController::header.rumble0 = 0x0; RawController::header.rumble0 = 0x0;
RawController::header.rumble1 = 0x0; RawController::header.rumble1 = 0x0;
} }
bool is_small_rumble() const { bool is_small_rumble() const {
return static_cast<bool>(RawController::header.rumble0); return static_cast<bool>(RawController::header.rumble0);
} }
uint8_t get_large_rumble() const { uint8_t get_large_rumble() const {
return RawController::header.rumble1; return RawController::header.rumble1;
} }
bool is_connected() const { bool is_connected() const {
return RawController::header.state != RawController::State::Disconnected; return RawController::header.state != RawController::State::Disconnected;
} }
bool is_useable() const { bool is_useable() const {
const auto type = RawController::get_type(); const auto type = RawController::get_type();
return ((RawController::header.state == RawController::State::Stable) && (type == ControllerType::Controller || type == ControllerType::DualShock)); return ((RawController::header.state == RawController::State::Stable) && (type == ControllerType::Controller || type == ControllerType::DualShock));
} }
}; };
class AnalogeController : public GenericController { class AnalogeController : public GenericController {
public: public:
enum struct Button : uint16_t { enum struct Button : uint16_t {
L2 = static_cast<uint16_t>(GenericButton::D0), L2 = static_cast<uint16_t>(GenericButton::D0),
R2 = static_cast<uint16_t>(GenericButton::D1), R2 = static_cast<uint16_t>(GenericButton::D1),
L1 = static_cast<uint16_t>(GenericButton::D2), L1 = static_cast<uint16_t>(GenericButton::D2),
R1 = static_cast<uint16_t>(GenericButton::D3), R1 = static_cast<uint16_t>(GenericButton::D3),
Triangle = static_cast<uint16_t>(GenericButton::D4), Triangle = static_cast<uint16_t>(GenericButton::D4),
Circle = static_cast<uint16_t>(GenericButton::D5), Circle = static_cast<uint16_t>(GenericButton::D5),
Cross = static_cast<uint16_t>(GenericButton::D6), Cross = static_cast<uint16_t>(GenericButton::D6),
Square = static_cast<uint16_t>(GenericButton::D7), Square = static_cast<uint16_t>(GenericButton::D7),
SEL = static_cast<uint16_t>(GenericButton::D8), SEL = static_cast<uint16_t>(GenericButton::D8),
L3 = static_cast<uint16_t>(GenericButton::D9), L3 = static_cast<uint16_t>(GenericButton::D9),
R3 = static_cast<uint16_t>(GenericButton::D10), R3 = static_cast<uint16_t>(GenericButton::D10),
ST = static_cast<uint16_t>(GenericButton::D11), ST = static_cast<uint16_t>(GenericButton::D11),
Up = static_cast<uint16_t>(GenericButton::D12), Up = static_cast<uint16_t>(GenericButton::D12),
Right = static_cast<uint16_t>(GenericButton::D13), Right = static_cast<uint16_t>(GenericButton::D13),
Down = static_cast<uint16_t>(GenericButton::D14), Down = static_cast<uint16_t>(GenericButton::D14),
Left = static_cast<uint16_t>(GenericButton::D15) Left = static_cast<uint16_t>(GenericButton::D15)
}; };
private: private:
uint8_t read_special_byte(size_t idx) const { uint8_t read_special_byte(size_t idx) const {
return reinterpret_cast<const uint8_t(&)[4]>(this->special)[idx]; return reinterpret_cast<const uint8_t(&)[4]>(this->special)[idx];
} }
public: public:
GPU::PositionI16 get_right_stick_pos() const { GPU::PositionI16 get_right_stick_pos() const {
const uint8_t joy_x = AnalogeController::read_special_byte(0); const uint8_t joy_x = AnalogeController::read_special_byte(0);
const uint8_t joy_y = AnalogeController::read_special_byte(1); const uint8_t joy_y = AnalogeController::read_special_byte(1);
return GPU::PositionI16::create(joy_x - 0x80, joy_y - 0x80); return GPU::PositionI16::create(joy_x - 0x80, joy_y - 0x80);
} }
GPU::PositionI16 get_left_stick_pos() const { GPU::PositionI16 get_left_stick_pos() const {
const uint8_t joy_x = AnalogeController::read_special_byte(2); const uint8_t joy_x = AnalogeController::read_special_byte(2);
const uint8_t joy_y = AnalogeController::read_special_byte(3); const uint8_t joy_y = AnalogeController::read_special_byte(3);
return GPU::PositionI16::create(joy_x - 0x80, joy_y - 0x80); return GPU::PositionI16::create(joy_x - 0x80, joy_y - 0x80);
} }
}; };
using GenericButtonState = GenericController::ButtonState; using GenericButtonState = GenericController::ButtonState;
} }
} }

View File

@ -1,24 +1,24 @@
#pragma once #pragma once
#include "../jabyengine_config.hpp" #include "../jabyengine_config.hpp"
#include "controller.hpp" #include "controller.hpp"
namespace JabyEngine { namespace JabyEngine {
namespace Periphery { namespace Periphery {
static constexpr uint32_t PortCount = Configuration::Periphery::include_portB() ? 2 : 1; static constexpr uint32_t PortCount = Configuration::Periphery::include_portB() ? 2 : 1;
static constexpr uint32_t DeviceCount = Configuration::Periphery::use_multi_tap() ? 4 : 1; static constexpr uint32_t DeviceCount = Configuration::Periphery::use_multi_tap() ? 4 : 1;
extern RawController controller[PortCount][DeviceCount]; extern RawController controller[PortCount][DeviceCount];
void query_controller(); void query_controller();
template<typename T> template<typename T>
inline T& get_controller_as(size_t port, size_t device) { inline T& get_controller_as(size_t port, size_t device) {
return *reinterpret_cast<T*>(&controller[port][device]); return *reinterpret_cast<T*>(&controller[port][device]);
} }
template<typename T> template<typename T>
inline T& get_primary_controller_as() { inline T& get_primary_controller_as() {
return get_controller_as<T>(0, 0); return get_controller_as<T>(0, 0);
} }
} }
} }

View File

@ -1,137 +1,137 @@
#pragma once #pragma once
#include "../jabyengine_defines.hpp" #include "../jabyengine_defines.hpp"
namespace JabyEngine { namespace JabyEngine {
namespace Periphery { namespace Periphery {
enum struct ControllerType : uint8_t { enum struct ControllerType : uint8_t {
Unkown = 0x0, Unkown = 0x0,
Mouse = 0x1, Mouse = 0x1,
NegCon = 0x2, NegCon = 0x2,
HyperBlaster = 0x3, // Konami Lightgun HyperBlaster = 0x3, // Konami Lightgun
Controller = 0x4, Controller = 0x4,
ArcadeFlightStick = 0x5, ArcadeFlightStick = 0x5,
GCon = 0x6, GCon = 0x6,
DualShock = 0x7, DualShock = 0x7,
MultiTap = 0x8 MultiTap = 0x8
}; };
enum struct GenericButton : uint16_t { enum struct GenericButton : uint16_t {
D8 = (1 << 0), D8 = (1 << 0),
D9 = (1 << 1), D9 = (1 << 1),
D10 = (1 << 2), D10 = (1 << 2),
D11 = (1 << 3), D11 = (1 << 3),
D12 = (1 << 4), D12 = (1 << 4),
D13 = (1 << 5), D13 = (1 << 5),
D14 = (1 << 6), D14 = (1 << 6),
D15 = (1 << 7), D15 = (1 << 7),
D0 = (1 << 8), D0 = (1 << 8),
D1 = (1 << 9), D1 = (1 << 9),
D2 = (1 << 10), D2 = (1 << 10),
D3 = (1 << 11), D3 = (1 << 11),
D4 = (1 << 12), D4 = (1 << 12),
D5 = (1 << 13), D5 = (1 << 13),
D6 = (1 << 14), D6 = (1 << 14),
D7 = (1 << 15) D7 = (1 << 15)
}; };
struct LED { struct LED {
enum struct State : uint8_t { enum struct State : uint8_t {
Off = 0x0, Off = 0x0,
On = 0x1 On = 0x1
}; };
enum struct Lock { enum struct Lock {
Off = 0x2, Off = 0x2,
On = 0x3 On = 0x3
}; };
}; };
class RawController { class RawController {
public: public:
enum struct State : uint8_t enum struct State : uint8_t
{ {
Disconnected = 0, Disconnected = 0,
EnterConfigMode = (1 << 0), EnterConfigMode = (1 << 0),
LockAnalog = (1 << 1), LockAnalog = (1 << 1),
UnlockRumble = (1 << 2), UnlockRumble = (1 << 2),
ExitConfigMode = (1 << 3), ExitConfigMode = (1 << 3),
Stable = (1 << 4) Stable = (1 << 4)
}; };
protected: protected:
struct Header { struct Header {
uint8_t type; uint8_t type;
State state; State state;
uint8_t rumble0; uint8_t rumble0;
uint8_t rumble1; uint8_t rumble1;
void clear() { void clear() {
this->type = 0; this->type = 0;
this->state = State::Disconnected; this->state = State::Disconnected;
} }
}; };
public: public:
class ButtonState { class ButtonState {
private: private:
uint16_t oldState; uint16_t oldState;
uint16_t currentState; uint16_t currentState;
static bool is_down(uint16_t data, uint16_t button) { static bool is_down(uint16_t data, uint16_t button) {
return ((data & button) == 0); return ((data & button) == 0);
} }
void exchange_state() { void exchange_state() {
this->oldState = this->currentState; this->oldState = this->currentState;
} }
public: public:
template<typename T> template<typename T>
bool is_down(T button) const { bool is_down(T button) const {
return ButtonState::is_down(this->currentState, static_cast<uint16_t>(button)); return ButtonState::is_down(this->currentState, static_cast<uint16_t>(button));
} }
template<typename T> template<typename T>
bool was_down(T button) const { bool was_down(T button) const {
return ButtonState::is_down(this->oldState, static_cast<uint16_t>(button)); return ButtonState::is_down(this->oldState, static_cast<uint16_t>(button));
} }
template<typename T> template<typename T>
bool went_down(T button) const { bool went_down(T button) const {
return (!ButtonState::was_down(button) && ButtonState::is_down(button)); return (!ButtonState::was_down(button) && ButtonState::is_down(button));
} }
template<typename T> template<typename T>
bool went_up(T button) const { bool went_up(T button) const {
return (ButtonState::was_down(button) && !ButtonState::is_down(button)); return (ButtonState::was_down(button) && !ButtonState::is_down(button));
} }
friend class RawController; friend class RawController;
friend struct ControllerHelper; friend struct ControllerHelper;
friend void query_controller(); friend void query_controller();
}; };
Header header; Header header;
ButtonState button; ButtonState button;
uint32_t special; uint32_t special;
public: public:
ControllerType get_type() const { ControllerType get_type() const {
return static_cast<ControllerType>((this->header.type >> 4)); return static_cast<ControllerType>((this->header.type >> 4));
} }
ButtonState get_button_state() const { ButtonState get_button_state() const {
return this->button; return this->button;
} }
//For debugging only //For debugging only
uint8_t get_raw_type() const { uint8_t get_raw_type() const {
return this->header.type; return this->header.type;
} }
uint16_t get_raw_button_state() const { uint16_t get_raw_button_state() const {
return this->button.currentState; return this->button.currentState;
} }
}; };
} }
} }

View File

@ -1,51 +1,51 @@
#pragma once #pragma once
#include "../System/IOPorts/spu_io.hpp" #include "../System/IOPorts/spu_io.hpp"
namespace JabyEngine { namespace JabyEngine {
namespace SPU { namespace SPU {
using SPU_IO_Values::operator""_vol; using SPU_IO_Values::operator""_vol;
using SRAMAdr = SPU_IO_Values::SRAMAdr; using SRAMAdr = SPU_IO_Values::SRAMAdr;
using SimpleVolume = SPU_IO_Values::SimpleVolume; using SimpleVolume = SPU_IO_Values::SimpleVolume;
using SweepVolume = SPU_IO_Values::SweepVolume; using SweepVolume = SPU_IO_Values::SweepVolume;
struct Voice { struct Voice {
size_t get_id() const { size_t get_id() const {
return reinterpret_cast<size_t>(this); return reinterpret_cast<size_t>(this);
} }
SRAMAdr allocate(size_t size); SRAMAdr allocate(size_t size);
SRAMAdr allocate(SPU_IO_Values::SampleRate frequency, size_t size); SRAMAdr allocate(SPU_IO_Values::SampleRate frequency, size_t size);
void deallocate(); void deallocate();
void set_sample_rate(SPU_IO_Values::SampleRate frequency) { void set_sample_rate(SPU_IO_Values::SampleRate frequency) {
SPU_IO::Voice[Voice::get_id()].sampleRate.write(frequency); SPU_IO::Voice[Voice::get_id()].sampleRate.write(frequency);
} }
void set_volume(SimpleVolume left, SimpleVolume right) { void set_volume(SimpleVolume left, SimpleVolume right) {
SPU_IO::Voice[Voice::get_id()].volumeLeft.write(SweepVolume::create(left)); SPU_IO::Voice[Voice::get_id()].volumeLeft.write(SweepVolume::create(left));
SPU_IO::Voice[Voice::get_id()].volumeRight.write(SweepVolume::create(right)); SPU_IO::Voice[Voice::get_id()].volumeRight.write(SweepVolume::create(right));
} }
void play() { void play() {
SPU_IO::Key::On.write(SPU_IO_Values::KeyOn::for_specific(Voice::get_id())); SPU_IO::Key::On.write(SPU_IO_Values::KeyOn::for_specific(Voice::get_id()));
} }
void play_if_end() { void play_if_end() {
if(Voice::is_end()) { if(Voice::is_end()) {
Voice::play(); Voice::play();
} }
} }
void stop() { void stop() {
SPU_IO::Key::Off.write(SPU_IO_Values::KeyOff::for_specific(Voice::get_id())); SPU_IO::Key::Off.write(SPU_IO_Values::KeyOff::for_specific(Voice::get_id()));
} }
bool is_end() const { bool is_end() const {
return SPU_IO::Voice[Voice::get_id()].adsr_volume.read() == SimpleVolume::mute(); return SPU_IO::Voice[Voice::get_id()].adsr_volume.read() == SimpleVolume::mute();
} }
}; };
static auto& voice = __declare_io_port_array(Voice, SPU_IO::VoiceCount, 0x0); static auto& voice = __declare_io_port_array(Voice, SPU_IO::VoiceCount, 0x0);
} }
} }

View File

@ -1,106 +1,106 @@
#pragma once #pragma once
#include "ioport.hpp" #include "ioport.hpp"
namespace JabyEngine { namespace JabyEngine {
namespace CD_IO_Values { namespace CD_IO_Values {
__declare_io_struct(AudioVolumeApply, uint8_t) { __declare_io_struct(AudioVolumeApply, uint8_t) {
static constexpr auto Mute = Bit(0); static constexpr auto Mute = Bit(0);
static constexpr auto ApplyChanges = Bit(5); static constexpr auto ApplyChanges = Bit(5);
}; };
struct CDDAVolume { struct CDDAVolume {
using Type = uint8_t; using Type = uint8_t;
static constexpr uint8_t Off = 0x0; static constexpr uint8_t Off = 0x0;
static constexpr uint8_t Default = 0x80; static constexpr uint8_t Default = 0x80;
static constexpr uint8_t Max = 0xFF; static constexpr uint8_t Max = 0xFF;
}; };
__declare_io_struct(CommandFifo, uint8_t) { __declare_io_struct(CommandFifo, uint8_t) {
}; };
__declare_io_struct(DataFifo, uint8_t) { __declare_io_struct(DataFifo, uint8_t) {
}; };
__declare_io_struct(DataFifo16, uint16_t) { __declare_io_struct(DataFifo16, uint16_t) {
}; };
__declare_io_struct(InterruptEnable, uint8_t) { __declare_io_struct(InterruptEnable, uint8_t) {
static constexpr auto InterruptTypValue = BitRange::from_to(0, 2); static constexpr auto InterruptTypValue = BitRange::from_to(0, 2);
static constexpr auto InterruptExtended = BitRange::from_to(0, 4); static constexpr auto InterruptExtended = BitRange::from_to(0, 4);
static constexpr auto UnknownIRQ = Bit(3); static constexpr auto UnknownIRQ = Bit(3);
static constexpr auto CommandStartIRQ = Bit(4); static constexpr auto CommandStartIRQ = Bit(4);
}; };
using InterruptFlag = InterruptEnable; using InterruptFlag = InterruptEnable;
__declare_io_struct(IndexStatus, uint8_t) { __declare_io_struct(IndexStatus, uint8_t) {
static constexpr auto PortIndex = BitRange::from_to(0, 1); static constexpr auto PortIndex = BitRange::from_to(0, 1);
static constexpr auto HasXAFifoData = Bit(2); static constexpr auto HasXAFifoData = Bit(2);
static constexpr auto IsParameterFifoEmpty = Bit(3); static constexpr auto IsParameterFifoEmpty = Bit(3);
static constexpr auto HasParameterFifoSpace = Bit(4); static constexpr auto HasParameterFifoSpace = Bit(4);
static constexpr auto HasResponseFifoData = Bit(5); static constexpr auto HasResponseFifoData = Bit(5);
static constexpr auto HasDataFifoData = Bit(6); static constexpr auto HasDataFifoData = Bit(6);
static constexpr auto IsTransmissionBusy = Bit(7); static constexpr auto IsTransmissionBusy = Bit(7);
}; };
__declare_io_struct(LeftCD2LeftSPU, CDDAVolume::Type) { __declare_io_struct(LeftCD2LeftSPU, CDDAVolume::Type) {
}; };
__declare_io_struct(LeftCD2RightSPU, CDDAVolume::Type) { __declare_io_struct(LeftCD2RightSPU, CDDAVolume::Type) {
}; };
__declare_io_struct(Mode, uint8_t) { __declare_io_struct(Mode, uint8_t) {
static constexpr auto DoubleSpeed = Bit(7); static constexpr auto DoubleSpeed = Bit(7);
static constexpr auto SingleSpeed = !DoubleSpeed; static constexpr auto SingleSpeed = !DoubleSpeed;
static constexpr auto XADPCM = Bit(6); static constexpr auto XADPCM = Bit(6);
static constexpr auto WholeSector = Bit(5); static constexpr auto WholeSector = Bit(5);
static constexpr auto DataSector = !WholeSector; static constexpr auto DataSector = !WholeSector;
static constexpr auto UseXAFilter = Bit(3); static constexpr auto UseXAFilter = Bit(3);
static constexpr auto AudioPlayIRQ = Bit(2); static constexpr auto AudioPlayIRQ = Bit(2);
static constexpr auto AutoPauseTrack = Bit(1); static constexpr auto AutoPauseTrack = Bit(1);
static constexpr auto CDDA = Bit(0); static constexpr auto CDDA = Bit(0);
operator uint8_t() const { operator uint8_t() const {
return this->raw; return this->raw;
} }
}; };
__declare_io_struct(ParameterFifo, uint8_t) { __declare_io_struct(ParameterFifo, uint8_t) {
}; };
__declare_io_struct(Request, uint8_t) { __declare_io_struct(Request, uint8_t) {
static constexpr auto WantCommandStartIRQ = Bit(5); static constexpr auto WantCommandStartIRQ = Bit(5);
static constexpr auto WantData = Bit(7); static constexpr auto WantData = Bit(7);
static Request want_data() { static Request want_data() {
return Request{static_cast<uint8_t>(Request::WantData)}; return Request{static_cast<uint8_t>(Request::WantData)};
} }
static Request reset() { static Request reset() {
return Request{0}; return Request{0};
} }
}; };
__declare_io_struct(ResponseFifo, uint8_t) { __declare_io_struct(ResponseFifo, uint8_t) {
}; };
__declare_io_struct(RightCD2LeftSPU, CDDAVolume::Type) { __declare_io_struct(RightCD2LeftSPU, CDDAVolume::Type) {
}; };
__declare_io_struct(RightCD2RightSPU, CDDAVolume::Type) { __declare_io_struct(RightCD2RightSPU, CDDAVolume::Type) {
}; };
__declare_io_struct(SoundMapCoding, uint8_t) { __declare_io_struct(SoundMapCoding, uint8_t) {
static constexpr auto Stereo = Bit(0); static constexpr auto Stereo = Bit(0);
static constexpr auto Mono = !Stereo; static constexpr auto Mono = !Stereo;
static constexpr auto SampleRate_18900hz = Bit(2); static constexpr auto SampleRate_18900hz = Bit(2);
static constexpr auto SampleRate_37800hz = !SampleRate_18900hz; static constexpr auto SampleRate_37800hz = !SampleRate_18900hz;
static constexpr auto BitsPerSample8 = Bit(4); static constexpr auto BitsPerSample8 = Bit(4);
static constexpr auto BitsPerSample4 = !BitsPerSample8; static constexpr auto BitsPerSample4 = !BitsPerSample8;
static constexpr auto Emphasis = Bit(6); static constexpr auto Emphasis = Bit(6);
}; };
__declare_io_struct(SoundMapDataOut, uint8_t) { __declare_io_struct(SoundMapDataOut, uint8_t) {
}; };
} }
} }

View File

@ -1,152 +1,152 @@
#pragma once #pragma once
#include "ioport.hpp" #include "ioport.hpp"
namespace JabyEngine { namespace JabyEngine {
namespace DMA_IO_Values { namespace DMA_IO_Values {
using Priority = uint32_t; using Priority = uint32_t;
static constexpr Priority HighestPriority = 0; static constexpr Priority HighestPriority = 0;
static constexpr Priority LowestPriority = 7; static constexpr Priority LowestPriority = 7;
__declare_io_struct(BCR, uint32_t) { __declare_io_struct(BCR, uint32_t) {
struct SyncMode0 { struct SyncMode0 {
static constexpr auto NumberOfWords = BitRange::from_to(0, 15); static constexpr auto NumberOfWords = BitRange::from_to(0, 15);
static constexpr auto CD_OneBlock = Bit(16); static constexpr auto CD_OneBlock = Bit(16);
static constexpr BCR for_cd(size_t words) { static constexpr BCR for_cd(size_t words) {
return BCR::from(SyncMode0::CD_OneBlock, SyncMode0::NumberOfWords.with(words)); return BCR::from(SyncMode0::CD_OneBlock, SyncMode0::NumberOfWords.with(words));
} }
}; };
struct SyncMode1 { struct SyncMode1 {
static constexpr auto BlockSize = BitRange::from_to(0, 15); static constexpr auto BlockSize = BitRange::from_to(0, 15);
static constexpr auto BlockAmount = BitRange::from_to(16, 31); static constexpr auto BlockAmount = BitRange::from_to(16, 31);
}; };
struct SyncMode2 { struct SyncMode2 {
static constexpr BCR for_gpu_cmd() { static constexpr BCR for_gpu_cmd() {
return {0}; return {0};
} }
}; };
}; };
__declare_io_struct(CHCHR, uint32_t) { __declare_io_struct(CHCHR, uint32_t) {
enum SyncMode_t { enum SyncMode_t {
Sync0 = 0, //Start immediately, Sync0 = 0, //Start immediately,
Sync1 = 1, //Sync blocks to DMA requests Sync1 = 1, //Sync blocks to DMA requests
Sync2 = 2, //Linked List Sync2 = 2, //Linked List
}; };
static constexpr auto ManualStart = Bit(28); static constexpr auto ManualStart = Bit(28);
static constexpr auto Start = Bit(24); static constexpr auto Start = Bit(24);
static constexpr auto Busy = Start; static constexpr auto Busy = Start;
static constexpr auto ChoppingCPUWindowSize = BitRange::from_to(20, 22); static constexpr auto ChoppingCPUWindowSize = BitRange::from_to(20, 22);
static constexpr auto ChoppingDMAWindowSize = BitRange::from_to(16, 18); static constexpr auto ChoppingDMAWindowSize = BitRange::from_to(16, 18);
static constexpr auto SyncMode = BitRange::from_to(9, 10); static constexpr auto SyncMode = BitRange::from_to(9, 10);
static constexpr auto UseSyncMode0 = SyncMode.with(Sync0); static constexpr auto UseSyncMode0 = SyncMode.with(Sync0);
static constexpr auto UseSyncMode1 = SyncMode.with(Sync1); static constexpr auto UseSyncMode1 = SyncMode.with(Sync1);
static constexpr auto UseSyncMode2 = SyncMode.with(Sync2); static constexpr auto UseSyncMode2 = SyncMode.with(Sync2);
static constexpr auto UseChopping = Bit(8); static constexpr auto UseChopping = Bit(8);
static constexpr auto MemoryAdrDecreaseBy4 = Bit(1); static constexpr auto MemoryAdrDecreaseBy4 = Bit(1);
static constexpr auto MemoryAdrIncreaseBy4 = !MemoryAdrDecreaseBy4; static constexpr auto MemoryAdrIncreaseBy4 = !MemoryAdrDecreaseBy4;
static constexpr auto FromMainRAM = Bit(0); static constexpr auto FromMainRAM = Bit(0);
static constexpr auto ToMainRAM = !FromMainRAM; static constexpr auto ToMainRAM = !FromMainRAM;
static constexpr CHCHR StartMDECin() { static constexpr CHCHR StartMDECin() {
return CHCHR{0x01000201}; return CHCHR{0x01000201};
} }
static constexpr CHCHR StartMDECout() { static constexpr CHCHR StartMDECout() {
return CHCHR{0x01000200}; return CHCHR{0x01000200};
} }
static constexpr CHCHR StartGPUReceive() { static constexpr CHCHR StartGPUReceive() {
return CHCHR{0x01000201}; return CHCHR{0x01000201};
} }
static constexpr CHCHR StartGPULinked() { static constexpr CHCHR StartGPULinked() {
return CHCHR{0x01000401}; return CHCHR{0x01000401};
} }
static constexpr CHCHR StartCDROM() { static constexpr CHCHR StartCDROM() {
return CHCHR{0x11000000}; return CHCHR{0x11000000};
} }
static constexpr CHCHR StartSPUReceive() { static constexpr CHCHR StartSPUReceive() {
return CHCHR{0x01000201}; return CHCHR{0x01000201};
} }
static constexpr CHCHR StartOTC() { static constexpr CHCHR StartOTC() {
return CHCHR{0x11000002}; return CHCHR{0x11000002};
} }
}; };
__declare_io_struct(DICR, uint32_t) { __declare_io_struct(DICR, uint32_t) {
static constexpr auto MasterEnable = Bit(31); static constexpr auto MasterEnable = Bit(31);
static constexpr auto Flags = BitRange::from_to(24, 30); static constexpr auto Flags = BitRange::from_to(24, 30);
static constexpr auto MasterEnableDPCR = Bit(23); static constexpr auto MasterEnableDPCR = Bit(23);
static constexpr auto EnableDPCR = BitRange::from_to(16, 22); static constexpr auto EnableDPCR = BitRange::from_to(16, 22);
static constexpr auto ForceIRQ = Bit(15); static constexpr auto ForceIRQ = Bit(15);
static constexpr DICR empty() { static constexpr DICR empty() {
return DICR{0}; return DICR{0};
} }
}; };
__declare_io_struct(DPCR, uint32_t) { __declare_io_struct(DPCR, uint32_t) {
struct DMASetting { struct DMASetting {
uint16_t master_bit; uint16_t master_bit;
static constexpr DMASetting create(uint16_t master_bit) { static constexpr DMASetting create(uint16_t master_bit) {
return DMASetting{master_bit}; return DMASetting{master_bit};
} }
constexpr BitRange::RangeValuePair<uint32_t> turn_on(uint8_t priority) const { constexpr BitRange::RangeValuePair<uint32_t> turn_on(uint8_t priority) const {
return BitRange::from_to(this->master_bit - 3, this->master_bit).with(static_cast<uint32_t>(0b1000 + (priority & 0b111))); return BitRange::from_to(this->master_bit - 3, this->master_bit).with(static_cast<uint32_t>(0b1000 + (priority & 0b111)));
} }
constexpr ClearBit turn_off() const { constexpr ClearBit turn_off() const {
return ClearBit(this->master_bit); return ClearBit(this->master_bit);
} }
}; };
static constexpr const auto OTC = DMASetting(27); static constexpr const auto OTC = DMASetting(27);
static constexpr const auto PIO = DMASetting(23); static constexpr const auto PIO = DMASetting(23);
static constexpr const auto SPU = DMASetting(19); static constexpr const auto SPU = DMASetting(19);
static constexpr const auto CDROM = DMASetting(15); static constexpr const auto CDROM = DMASetting(15);
static constexpr const auto GPU = DMASetting(11); static constexpr const auto GPU = DMASetting(11);
static constexpr const auto MDEC_Out = DMASetting(7); static constexpr const auto MDEC_Out = DMASetting(7);
static constexpr const auto MDEC_In = DMASetting(3); static constexpr const auto MDEC_In = DMASetting(3);
static constexpr auto OTCEnabled = Bit(27); static constexpr auto OTCEnabled = Bit(27);
static constexpr auto OTCPriority = BitRange::from_to(24, 26); static constexpr auto OTCPriority = BitRange::from_to(24, 26);
static constexpr auto PIOEnabled = Bit(23); static constexpr auto PIOEnabled = Bit(23);
static constexpr auto PIOPriority = BitRange::from_to(20, 22); static constexpr auto PIOPriority = BitRange::from_to(20, 22);
static constexpr auto SPUEnabled = Bit(19); static constexpr auto SPUEnabled = Bit(19);
static constexpr auto SPUPriority = BitRange::from_to(16, 18); static constexpr auto SPUPriority = BitRange::from_to(16, 18);
static constexpr auto CDROMEnabled = Bit(15); static constexpr auto CDROMEnabled = Bit(15);
static constexpr auto CDROMPriority = BitRange::from_to(12, 14); static constexpr auto CDROMPriority = BitRange::from_to(12, 14);
static constexpr auto GPUEnabled = Bit(11); static constexpr auto GPUEnabled = Bit(11);
static constexpr auto GPUPriority = BitRange::from_to(8, 10); static constexpr auto GPUPriority = BitRange::from_to(8, 10);
static constexpr auto MDECoutEnabled = Bit(7); static constexpr auto MDECoutEnabled = Bit(7);
static constexpr auto MDECoutPriority = BitRange::from_to(4, 6); static constexpr auto MDECoutPriority = BitRange::from_to(4, 6);
static constexpr auto MDECinEnabled = Bit(3); static constexpr auto MDECinEnabled = Bit(3);
static constexpr auto MDECinPriority = BitRange::from_to(0, 2); static constexpr auto MDECinPriority = BitRange::from_to(0, 2);
}; };
__declare_io_struct(MADR, uint32_t) { __declare_io_struct(MADR, uint32_t) {
static constexpr auto MemoryAdr = BitRange::from_to(0, 23); static constexpr auto MemoryAdr = BitRange::from_to(0, 23);
}; };
} }
} }

View File

@ -1,220 +1,220 @@
#pragma once #pragma once
#include "../../../GPU/gpu_types.hpp" #include "../../../GPU/gpu_types.hpp"
#include "ioport.hpp" #include "ioport.hpp"
namespace JabyEngine { namespace JabyEngine {
namespace GPU_IO_Values { namespace GPU_IO_Values {
namespace internal { namespace internal {
template<typename T> template<typename T>
static constexpr T construct_cmd(uint32_t cmd, uint32_t value) { static constexpr T construct_cmd(uint32_t cmd, uint32_t value) {
return T::from(T::ID.with(cmd), T::Value.with(value)); return T::from(T::ID.with(cmd), T::Value.with(value));
} }
} }
__declare_io_struct(DisplayMode, uint32_t) { __declare_io_struct(DisplayMode, uint32_t) {
enum AreaColorDepth { enum AreaColorDepth {
$15bit = 0, $15bit = 0,
$24bit = 1, $24bit = 1,
}; };
enum State { enum State {
On = 0, On = 0,
Off = 1 Off = 1
}; };
enum HorizontalResolution { enum HorizontalResolution {
$256 = 0, $256 = 0,
$320 = 1, $320 = 1,
$512 = 2, $512 = 2,
$640 = 3, $640 = 3,
}; };
enum struct TVEncoding { enum struct TVEncoding {
NTSC = 0, NTSC = 0,
PAL = 1, PAL = 1,
}; };
enum VerticalResolution { enum VerticalResolution {
$240 = 0, $240 = 0,
$480 = 1 $480 = 1
}; };
static constexpr auto HorizontalResolution368 = Bit(6); static constexpr auto HorizontalResolution368 = Bit(6);
static constexpr auto VerticalInterlace = Bit(5); static constexpr auto VerticalInterlace = Bit(5);
static constexpr auto DisplayAreaColorDepth = BitRange::from_to(4, 4); static constexpr auto DisplayAreaColorDepth = BitRange::from_to(4, 4);
static constexpr auto VideoMode = BitRange::from_to(3, 3); static constexpr auto VideoMode = BitRange::from_to(3, 3);
static constexpr auto VerticalResolution = BitRange::from_to(2, 2); static constexpr auto VerticalResolution = BitRange::from_to(2, 2);
static constexpr auto HorizontalResolution = BitRange::from_to(0, 1); static constexpr auto HorizontalResolution = BitRange::from_to(0, 1);
static constexpr DisplayMode PAL() { static constexpr DisplayMode PAL() {
return DisplayMode::from( return DisplayMode::from(
HorizontalResolution.with(HorizontalResolution::$320), HorizontalResolution.with(HorizontalResolution::$320),
VerticalResolution.with(VerticalResolution::$240), VerticalResolution.with(VerticalResolution::$240),
VideoMode.with(TVEncoding::PAL), VideoMode.with(TVEncoding::PAL),
DisplayAreaColorDepth.with(AreaColorDepth::$15bit) DisplayAreaColorDepth.with(AreaColorDepth::$15bit)
); );
} }
static constexpr DisplayMode NTSC() { static constexpr DisplayMode NTSC() {
return DisplayMode::from( return DisplayMode::from(
HorizontalResolution.with(HorizontalResolution::$320), HorizontalResolution.with(HorizontalResolution::$320),
VerticalResolution.with(VerticalResolution::$240), VerticalResolution.with(VerticalResolution::$240),
VideoMode.with(TVEncoding::NTSC), VideoMode.with(TVEncoding::NTSC),
DisplayAreaColorDepth.with(AreaColorDepth::$15bit) DisplayAreaColorDepth.with(AreaColorDepth::$15bit)
); );
} }
}; };
__declare_io_struct(GPUREAD, uint32_t) { __declare_io_struct(GPUREAD, uint32_t) {
}; };
__declare_io_struct(GPUSTAT, uint32_t) { __declare_io_struct(GPUSTAT, uint32_t) {
enum DMADirection { enum DMADirection {
Off = 0, Off = 0,
Fifo = 1, Fifo = 1,
CPU2GPU = 2, CPU2GPU = 2,
GPU2CPU = 3, GPU2CPU = 3,
}; };
static constexpr auto DrawingOddLinesInterlaced = Bit(31); static constexpr auto DrawingOddLinesInterlaced = Bit(31);
static constexpr auto DMADirectionValue = BitRange::from_to(29, 30); static constexpr auto DMADirectionValue = BitRange::from_to(29, 30);
static constexpr auto DMAReady = Bit(28); static constexpr auto DMAReady = Bit(28);
static constexpr auto VRAMtoCPUtransferReay = Bit(27); static constexpr auto VRAMtoCPUtransferReay = Bit(27);
static constexpr auto GP0ReadyForCMD = Bit(26); static constexpr auto GP0ReadyForCMD = Bit(26);
static constexpr auto FifoNotFull = Bit(25); // Only for Fifo static constexpr auto FifoNotFull = Bit(25); // Only for Fifo
static constexpr auto InterruptRequest = Bit(24); static constexpr auto InterruptRequest = Bit(24);
static constexpr auto DisplayDisabled = Bit(23); static constexpr auto DisplayDisabled = Bit(23);
static constexpr auto VerticalInterlaceOn = Bit(22); static constexpr auto VerticalInterlaceOn = Bit(22);
static constexpr auto DisplayAreaColorDepth = BitRange::from_to(21, 21); static constexpr auto DisplayAreaColorDepth = BitRange::from_to(21, 21);
static constexpr auto VideoModePal = Bit(20); static constexpr auto VideoModePal = Bit(20);
static constexpr auto VerticalResolutionValue = BitRange::from_to(19, 19); static constexpr auto VerticalResolutionValue = BitRange::from_to(19, 19);
static constexpr auto HorizontalResolutionValue = BitRange::from_to(17, 18); static constexpr auto HorizontalResolutionValue = BitRange::from_to(17, 18);
static constexpr auto HorizontalResolution368 = Bit(16); static constexpr auto HorizontalResolution368 = Bit(16);
static constexpr auto TexturesDisabled = Bit(15); static constexpr auto TexturesDisabled = Bit(15);
static constexpr auto NotDrawingMaskedPixels = Bit(12); static constexpr auto NotDrawingMaskedPixels = Bit(12);
static constexpr auto MaskBitSetDuringDrawEnabled = Bit(11); static constexpr auto MaskBitSetDuringDrawEnabled = Bit(11);
static constexpr auto DrawingToDisplayAreadAllowed = Bit(10); static constexpr auto DrawingToDisplayAreadAllowed = Bit(10);
static constexpr auto DitherEnabled = Bit(9); static constexpr auto DitherEnabled = Bit(9);
static constexpr auto TexturePageColorValue = BitRange::from_to(7, 8); static constexpr auto TexturePageColorValue = BitRange::from_to(7, 8);
static constexpr auto SemiTransparencyValue = BitRange::from_to(5, 6); static constexpr auto SemiTransparencyValue = BitRange::from_to(5, 6);
static constexpr auto TexturePageY = BitRange::from_to(4, 4); // N*256 static constexpr auto TexturePageY = BitRange::from_to(4, 4); // N*256
static constexpr auto TexturePageX = BitRange::from_to(0, 3); // N*64 static constexpr auto TexturePageX = BitRange::from_to(0, 3); // N*64
static constexpr auto VerticalResolution480 = Bit(19); static constexpr auto VerticalResolution480 = Bit(19);
static constexpr auto TexturePageY256 = Bit(4); static constexpr auto TexturePageY256 = Bit(4);
}; };
__declare_io_struct(GP0, uint32_t) { __declare_io_struct(GP0, uint32_t) {
static constexpr auto ID = BitRange::from_to(24, 31); static constexpr auto ID = BitRange::from_to(24, 31);
static constexpr auto Value = BitRange::from_to(0, 23); static constexpr auto Value = BitRange::from_to(0, 23);
static constexpr GP0 DrawAreaTemplate(uint8_t code, uint16_t x, uint16_t y) { static constexpr GP0 DrawAreaTemplate(uint8_t code, uint16_t x, uint16_t y) {
constexpr auto Command = BitRange::from_to(24, 31); constexpr auto Command = BitRange::from_to(24, 31);
constexpr auto Y = BitRange::from_to(10, 18); constexpr auto Y = BitRange::from_to(10, 18);
constexpr auto X = BitRange::from_to(0, 9); constexpr auto X = BitRange::from_to(0, 9);
return internal::construct_cmd<GP0>(code, Y.as_value(static_cast<uint32_t>(y)) | X.as_value(static_cast<uint32_t>(x))); return internal::construct_cmd<GP0>(code, Y.as_value(static_cast<uint32_t>(y)) | X.as_value(static_cast<uint32_t>(x)));
} }
static constexpr GP0 ClearCache() { static constexpr GP0 ClearCache() {
return internal::construct_cmd<GP0>(0x01, 0x0); return internal::construct_cmd<GP0>(0x01, 0x0);
} }
static constexpr GP0 QuickFill(GPU::Color24 color) { static constexpr GP0 QuickFill(GPU::Color24 color) {
return internal::construct_cmd<GP0>(0x02, color.raw()); return internal::construct_cmd<GP0>(0x02, color.raw());
} }
static constexpr GP0 VRAM2VRAMBlitting() { static constexpr GP0 VRAM2VRAMBlitting() {
return internal::construct_cmd<GP0>(0x80, 0); return internal::construct_cmd<GP0>(0x80, 0);
} }
static constexpr GP0 CPU2VRAMBlitting() { static constexpr GP0 CPU2VRAMBlitting() {
return internal::construct_cmd<GP0>(0xA0, 0); return internal::construct_cmd<GP0>(0xA0, 0);
} }
static constexpr GP0 TexPage(const GPU::PositionU16& page_pos, GPU::SemiTransparency transparency, GPU::TextureColorMode tex_color, bool dither, bool draw_on_display_area) { static constexpr GP0 TexPage(const GPU::PositionU16& page_pos, GPU::SemiTransparency transparency, GPU::TextureColorMode tex_color, bool dither, bool draw_on_display_area) {
constexpr auto TexXRange = BitRange::from_to(0, 3); constexpr auto TexXRange = BitRange::from_to(0, 3);
constexpr auto TexYRange = BitRange::from_to(4, 4); constexpr auto TexYRange = BitRange::from_to(4, 4);
constexpr auto TransparencyRange = BitRange::from_to(5, 6); constexpr auto TransparencyRange = BitRange::from_to(5, 6);
constexpr auto TextureColorRange = BitRange::from_to(7, 8); constexpr auto TextureColorRange = BitRange::from_to(7, 8);
constexpr auto DitherBit = BitRange::from_to(9, 9); constexpr auto DitherBit = BitRange::from_to(9, 9);
constexpr auto DrawOnDisplayAreaBit = BitRange::from_to(10, 10); constexpr auto DrawOnDisplayAreaBit = BitRange::from_to(10, 10);
return internal::construct_cmd<GP0>(0xE1, return internal::construct_cmd<GP0>(0xE1,
TexXRange.as_value(page_pos.x >> 6) | TexYRange.as_value(page_pos.y >> 8) | TexXRange.as_value(page_pos.x >> 6) | TexYRange.as_value(page_pos.y >> 8) |
TransparencyRange.as_value(static_cast<uint32_t>(transparency)) | TextureColorRange.as_value(static_cast<uint32_t>(tex_color)) | TransparencyRange.as_value(static_cast<uint32_t>(transparency)) | TextureColorRange.as_value(static_cast<uint32_t>(tex_color)) |
DitherBit.as_value(static_cast<uint32_t>(dither)) | DrawOnDisplayAreaBit.as_value(static_cast<uint32_t>(draw_on_display_area)) DitherBit.as_value(static_cast<uint32_t>(dither)) | DrawOnDisplayAreaBit.as_value(static_cast<uint32_t>(draw_on_display_area))
); );
} }
static constexpr GP0 DrawAreaTopLeft(const GPU::PositionU16& position) { static constexpr GP0 DrawAreaTopLeft(const GPU::PositionU16& position) {
return GP0::DrawAreaTemplate(0xE3, position.x, position.y); return GP0::DrawAreaTemplate(0xE3, position.x, position.y);
} }
static constexpr GP0 DrawAreaBottomRight(const GPU::PositionU16& position) { static constexpr GP0 DrawAreaBottomRight(const GPU::PositionU16& position) {
return GP0::DrawAreaTemplate(0xE4, position.x, position.y); return GP0::DrawAreaTemplate(0xE4, position.x, position.y);
} }
static constexpr GP0 DrawOffset(const GPU::PositionI16& offset) { static constexpr GP0 DrawOffset(const GPU::PositionI16& offset) {
constexpr auto X = BitRange::from_to(0, 10); constexpr auto X = BitRange::from_to(0, 10);
constexpr auto Y = BitRange::from_to(11, 21); constexpr auto Y = BitRange::from_to(11, 21);
return internal::construct_cmd<GPU_IO_Values::GP0>(0xE5, X.as_value(static_cast<int32_t>(offset.x)) | Y.as_value(static_cast<int32_t>(offset.y))); return internal::construct_cmd<GPU_IO_Values::GP0>(0xE5, X.as_value(static_cast<int32_t>(offset.x)) | Y.as_value(static_cast<int32_t>(offset.y)));
} }
static constexpr GP0 PostionTopLeft(const GPU::PositionU16& position) { static constexpr GP0 PostionTopLeft(const GPU::PositionU16& position) {
return GP0{(static_cast<uint32_t>(position.y) << 16u) | position.x}; return GP0{(static_cast<uint32_t>(position.y) << 16u) | position.x};
} }
static constexpr GP0 WidthHeight(const GPU::SizeU16& size) { static constexpr GP0 WidthHeight(const GPU::SizeU16& size) {
return GP0{(static_cast<uint32_t>(size.height) << 16u) | size.width}; return GP0{(static_cast<uint32_t>(size.height) << 16u) | size.width};
} }
}; };
__declare_io_struct(GP1, uint32_t) { __declare_io_struct(GP1, uint32_t) {
static constexpr auto ID = BitRange::from_to(24, 31); static constexpr auto ID = BitRange::from_to(24, 31);
static constexpr auto Value = BitRange::from_to(0, 23); static constexpr auto Value = BitRange::from_to(0, 23);
static constexpr GP1 Reset() { static constexpr GP1 Reset() {
return GP1{0}; return GP1{0};
} }
static constexpr GP1 ResetCMDBuffer() { static constexpr GP1 ResetCMDBuffer() {
return internal::construct_cmd<GP1>(0x01, 0); return internal::construct_cmd<GP1>(0x01, 0);
} }
static constexpr GP1 DisplayState(DisplayMode::State state) { static constexpr GP1 DisplayState(DisplayMode::State state) {
return internal::construct_cmd<GP1>(0x03, static_cast<uint32_t>(state)); return internal::construct_cmd<GP1>(0x03, static_cast<uint32_t>(state));
} }
static constexpr GP1 DMADirection(GPUSTAT::DMADirection dir) { static constexpr GP1 DMADirection(GPUSTAT::DMADirection dir) {
return internal::construct_cmd<GP1>(0x04, dir); return internal::construct_cmd<GP1>(0x04, dir);
} }
static constexpr GP1 DisplayArea(const GPU::PositionU16& position) { static constexpr GP1 DisplayArea(const GPU::PositionU16& position) {
constexpr auto X = BitRange::from_to(0, 9); constexpr auto X = BitRange::from_to(0, 9);
constexpr auto Y = BitRange::from_to(10, 18); constexpr auto Y = BitRange::from_to(10, 18);
return internal::construct_cmd<GP1>(0x05, X.as_value(static_cast<uint32_t>(position.x)) | Y.as_value(static_cast<uint32_t>(position.y))); return internal::construct_cmd<GP1>(0x05, X.as_value(static_cast<uint32_t>(position.x)) | Y.as_value(static_cast<uint32_t>(position.y)));
} }
static constexpr GP1 HorizontalDisplayRange(uint16_t x1, uint16_t x2) { static constexpr GP1 HorizontalDisplayRange(uint16_t x1, uint16_t x2) {
constexpr auto X1 = BitRange::from_to(0, 11); constexpr auto X1 = BitRange::from_to(0, 11);
constexpr auto X2 = BitRange::from_to(12, 23); constexpr auto X2 = BitRange::from_to(12, 23);
return internal::construct_cmd<GP1>(0x06, X1.as_value(static_cast<uint32_t>(x1)) | X2.as_value(static_cast<uint32_t>(x2))); return internal::construct_cmd<GP1>(0x06, X1.as_value(static_cast<uint32_t>(x1)) | X2.as_value(static_cast<uint32_t>(x2)));
} }
static constexpr GP1 VerticalDisplayRange(uint16_t y1, uint16_t y2) { static constexpr GP1 VerticalDisplayRange(uint16_t y1, uint16_t y2) {
constexpr auto Y1 = BitRange::from_to(0, 9); constexpr auto Y1 = BitRange::from_to(0, 9);
constexpr auto Y2 = BitRange::from_to(10, 19); constexpr auto Y2 = BitRange::from_to(10, 19);
return internal::construct_cmd<GP1>(0x07, Y1.as_value(static_cast<uint32_t>(y1)) | Y2.as_value(static_cast<uint32_t>(y2))); return internal::construct_cmd<GP1>(0x07, Y1.as_value(static_cast<uint32_t>(y1)) | Y2.as_value(static_cast<uint32_t>(y2)));
} }
static constexpr GP1 DisplayMode(GPU_IO_Values::DisplayMode mode) { static constexpr GP1 DisplayMode(GPU_IO_Values::DisplayMode mode) {
return internal::construct_cmd<GP1>(0x08, mode.raw); return internal::construct_cmd<GP1>(0x08, mode.raw);
} }
}; };
} }
} }

View File

@ -1,12 +1,12 @@
#pragma once #pragma once
#include "ioport.hpp" #include "ioport.hpp"
namespace JabyEngine { namespace JabyEngine {
namespace Interrupt_IO_Values { namespace Interrupt_IO_Values {
__declare_io_struct(Mask, uint32_t) { __declare_io_struct(Mask, uint32_t) {
}; };
__declare_io_struct(Status, uint32_t) { __declare_io_struct(Status, uint32_t) {
}; };
} }
} }

View File

@ -1,118 +1,118 @@
#pragma once #pragma once
#include "../../../Auxiliary/types.hpp" #include "../../../Auxiliary/types.hpp"
#include "../../../Auxiliary/bits.hpp" #include "../../../Auxiliary/bits.hpp"
namespace JabyEngine { namespace JabyEngine {
namespace IOAdress { namespace IOAdress {
constexpr uintptr_t patch_adr(uintptr_t adr) { constexpr uintptr_t patch_adr(uintptr_t adr) {
constexpr uintptr_t Mask = 0xF0000000; constexpr uintptr_t Mask = 0xF0000000;
constexpr uintptr_t Base = 0x10000000; // We might want to change this later to 0xB0000000 for caching and stuff (More research needed) constexpr uintptr_t Base = 0x10000000; // We might want to change this later to 0xB0000000 for caching and stuff (More research needed)
return (Base + (adr & ~Mask)); return (Base + (adr & ~Mask));
} }
} }
namespace internal { namespace internal {
template<typename T, typename S> template<typename T, typename S>
struct IOValue { struct IOValue {
typedef S UnderlyingType; typedef S UnderlyingType;
UnderlyingType raw; UnderlyingType raw;
template<typename...ARGS> template<typename...ARGS>
static constexpr T from(const ARGS&...args) { static constexpr T from(const ARGS&...args) {
return T{0}.set(args...); return T{0}.set(args...);
} }
constexpr T& set(Bit bit) { constexpr T& set(Bit bit) {
this->raw = bit::set(this->raw, bit); this->raw = bit::set(this->raw, bit);
return static_cast<T&>(*this); return static_cast<T&>(*this);
} }
constexpr T& set(ClearBit bit) { constexpr T& set(ClearBit bit) {
this->raw = bit::set(this->raw, bit); this->raw = bit::set(this->raw, bit);
return static_cast<T&>(*this); return static_cast<T&>(*this);
} }
constexpr T& set_range(const BitRange& bits, UnderlyingType value) { constexpr T& set_range(const BitRange& bits, UnderlyingType value) {
this->raw = bit::value::set_normalized(this->raw, bits, value); this->raw = bit::value::set_normalized(this->raw, bits, value);
return static_cast<T&>(*this); return static_cast<T&>(*this);
} }
template<typename U> template<typename U>
constexpr T& set(const BitRange::RangeValuePair<U>& value) { constexpr T& set(const BitRange::RangeValuePair<U>& value) {
this->raw = bit::value::set_normalized(this->raw, value); this->raw = bit::value::set_normalized(this->raw, value);
return static_cast<T&>(*this); return static_cast<T&>(*this);
} }
template<typename U, typename...ARGS> template<typename U, typename...ARGS>
constexpr T& set(const U& head, const ARGS&...tail) { constexpr T& set(const U& head, const ARGS&...tail) {
return this->set(head).set(tail...); return this->set(head).set(tail...);
} }
constexpr IOValue<T, S>::UnderlyingType get(BitRange bits) const { constexpr IOValue<T, S>::UnderlyingType get(BitRange bits) const {
return bit::value::get_normalized(this->raw, bits.pos, bits.length); return bit::value::get_normalized(this->raw, bits.pos, bits.length);
} }
constexpr T& clear(Bit bit) { constexpr T& clear(Bit bit) {
this->raw = bit::clear(this->raw, bit); this->raw = bit::clear(this->raw, bit);
return static_cast<T&>(*this); return static_cast<T&>(*this);
} }
constexpr bool is_set(Bit bit) const { constexpr bool is_set(Bit bit) const {
return bit::is_set(this->raw, bit); return bit::is_set(this->raw, bit);
} }
}; };
} }
template<typename T> template<typename T>
struct IOPort { struct IOPort {
using Value = T; using Value = T;
T value; T value;
T read() const { T read() const {
return {const_cast<const volatile IOPort<T>*>(this)->value.raw}; return {const_cast<const volatile IOPort<T>*>(this)->value.raw};
} }
void write(T value) { void write(T value) {
const_cast<volatile IOPort<T>*>(this)->value.raw = value.raw; const_cast<volatile IOPort<T>*>(this)->value.raw = value.raw;
} }
}; };
template<> template<>
struct IOPort<uint32_t>; struct IOPort<uint32_t>;
template<typename T> template<typename T>
struct IOPort32 { struct IOPort32 {
union ValueHelper { union ValueHelper {
struct { struct {
uint16_t low; uint16_t low;
uint16_t high; uint16_t high;
}; };
T value; T value;
}; };
using Value = T; using Value = T;
T value; T value;
T read() const { T read() const {
const auto* cast_this = reinterpret_cast<const IOPort32<ValueHelper>*>(this); const auto* cast_this = reinterpret_cast<const IOPort32<ValueHelper>*>(this);
const volatile auto* cv_this = const_cast<volatile decltype(cast_this)>(cast_this); const volatile auto* cv_this = const_cast<volatile decltype(cast_this)>(cast_this);
return ValueHelper{.low = cv_this->value.low, .high = cv_this->value.high}.value; return ValueHelper{.low = cv_this->value.low, .high = cv_this->value.high}.value;
} }
void write(T value) { void write(T value) {
const auto new_value = ValueHelper{.value = value}; const auto new_value = ValueHelper{.value = value};
auto* cast_this = reinterpret_cast<IOPort32<ValueHelper>*>(this); auto* cast_this = reinterpret_cast<IOPort32<ValueHelper>*>(this);
volatile auto* v_this = const_cast<volatile decltype(cast_this)>(cast_this); volatile auto* v_this = const_cast<volatile decltype(cast_this)>(cast_this);
v_this->value.low = new_value.low; v_this->value.low = new_value.low;
v_this->value.high = new_value.high; v_this->value.high = new_value.high;
} }
}; };
#define __declare_io_struct(name, type) struct name : public ::JabyEngine::internal::IOValue<struct name, type> #define __declare_io_struct(name, type) struct name : public ::JabyEngine::internal::IOValue<struct name, type>
#define __declare_io_port(type, adr) *reinterpret_cast<type*>(adr) #define __declare_io_port(type, adr) *reinterpret_cast<type*>(adr)
#define __declare_io_value(type, adr) __declare_io_port(type, adr) #define __declare_io_value(type, adr) __declare_io_port(type, adr)
#define __declare_io_port_array(type, size, adr) reinterpret_cast<type(&)[size]>(*reinterpret_cast<type*>(adr)) #define __declare_io_port_array(type, size, adr) reinterpret_cast<type(&)[size]>(*reinterpret_cast<type*>(adr))
} }

View File

@ -1,18 +1,18 @@
#pragma once #pragma once
#include "ioport.hpp" #include "ioport.hpp"
namespace JabyEngine { namespace JabyEngine {
namespace Memory_IO_Values { namespace Memory_IO_Values {
__declare_io_struct(CD_DELAY, uint32_t) { __declare_io_struct(CD_DELAY, uint32_t) {
static constexpr CD_DELAY create() { static constexpr CD_DELAY create() {
return CD_DELAY{0x20943}; return CD_DELAY{0x20943};
} }
}; };
__declare_io_struct(COM_DELAY, uint32_t) { __declare_io_struct(COM_DELAY, uint32_t) {
static constexpr COM_DELAY create() { static constexpr COM_DELAY create() {
return COM_DELAY{0x1325}; return COM_DELAY{0x1325};
} }
}; };
} }
} }

View File

@ -1,52 +1,52 @@
#pragma once #pragma once
#include "ioport.hpp" #include "ioport.hpp"
namespace JabyEngine { namespace JabyEngine {
namespace Periphery_IO_Values { namespace Periphery_IO_Values {
__declare_io_struct(JOY_BAUD, uint16_t) { __declare_io_struct(JOY_BAUD, uint16_t) {
static constexpr JOY_BAUD create() { static constexpr JOY_BAUD create() {
return JOY_BAUD{0x0088}; return JOY_BAUD{0x0088};
} }
}; };
__declare_io_struct(JOY_CTRL, uint16_t) { __declare_io_struct(JOY_CTRL, uint16_t) {
static constexpr auto TXEnable = Bit(0); static constexpr auto TXEnable = Bit(0);
static constexpr auto SelectJoy = Bit(1); static constexpr auto SelectJoy = Bit(1);
static constexpr auto ACK = Bit(4); static constexpr auto ACK = Bit(4);
static constexpr auto ACKIrqEnable = Bit(12); static constexpr auto ACKIrqEnable = Bit(12);
static constexpr auto PortBSelected = Bit(13); static constexpr auto PortBSelected = Bit(13);
static constexpr auto PortASelected = !PortBSelected; static constexpr auto PortASelected = !PortBSelected;
static constexpr JOY_CTRL create_for(uint16_t port) { static constexpr JOY_CTRL create_for(uint16_t port) {
return JOY_CTRL{static_cast<uint16_t>(port << PortBSelected)}.set(TXEnable, SelectJoy, ACKIrqEnable); return JOY_CTRL{static_cast<uint16_t>(port << PortBSelected)}.set(TXEnable, SelectJoy, ACKIrqEnable);
} }
static constexpr JOY_CTRL close() { static constexpr JOY_CTRL close() {
return JOY_CTRL{0}; return JOY_CTRL{0};
} }
}; };
__declare_io_struct(JOY_MODE, uint16_t) { __declare_io_struct(JOY_MODE, uint16_t) {
static constexpr JOY_MODE create() { static constexpr JOY_MODE create() {
return JOY_MODE{0x000D}; return JOY_MODE{0x000D};
} }
}; };
__declare_io_struct(JOY_RX_DATA, uint8_t) { __declare_io_struct(JOY_RX_DATA, uint8_t) {
}; };
__declare_io_struct(JOY_STAT, uint32_t) { __declare_io_struct(JOY_STAT, uint32_t) {
static constexpr auto TXReadyStart = Bit(0); static constexpr auto TXReadyStart = Bit(0);
static constexpr auto RXFifoNonEmpty = Bit(1); static constexpr auto RXFifoNonEmpty = Bit(1);
static constexpr auto TXReadyFinished = Bit(2); static constexpr auto TXReadyFinished = Bit(2);
static constexpr auto RXParityError = Bit(3); static constexpr auto RXParityError = Bit(3);
static constexpr auto ACKIrqLow = Bit(7); static constexpr auto ACKIrqLow = Bit(7);
}; };
__declare_io_struct(JOY_TX_DATA, uint32_t) { __declare_io_struct(JOY_TX_DATA, uint32_t) {
static constexpr JOY_TX_DATA create(uint8_t byte) { static constexpr JOY_TX_DATA create(uint8_t byte) {
return JOY_TX_DATA{byte}; return JOY_TX_DATA{byte};
} }
}; };
} }
} }

View File

@ -1,215 +1,215 @@
#pragma once #pragma once
#include "ioport.hpp" #include "ioport.hpp"
#include <limits.hpp> #include <limits.hpp>
namespace JabyEngine { namespace JabyEngine {
namespace SPU_IO_Values { namespace SPU_IO_Values {
namespace MemoryMap { namespace MemoryMap {
static constexpr uintptr_t ADPCM = 0x01000; static constexpr uintptr_t ADPCM = 0x01000;
static constexpr uintptr_t End = 0x7FFFF; static constexpr uintptr_t End = 0x7FFFF;
} }
__declare_io_struct(AD, uint16_t) { __declare_io_struct(AD, uint16_t) {
static constexpr auto AttackMode = Bit(15); static constexpr auto AttackMode = Bit(15);
static constexpr auto AttackShift = BitRange::from_to(10, 14); static constexpr auto AttackShift = BitRange::from_to(10, 14);
static constexpr auto AttackStep = BitRange::from_to(8, 9); static constexpr auto AttackStep = BitRange::from_to(8, 9);
static constexpr auto DecayShift = BitRange::from_to(4, 7); static constexpr auto DecayShift = BitRange::from_to(4, 7);
static constexpr auto SustainLevel = BitRange::from_to(0, 3); static constexpr auto SustainLevel = BitRange::from_to(0, 3);
static constexpr AD none() { static constexpr AD none() {
return AD{0}; return AD{0};
} }
}; };
__declare_io_struct(ControlRegister, uint16_t) { __declare_io_struct(ControlRegister, uint16_t) {
enum RAMTransferMode { enum RAMTransferMode {
Stop = 0, Stop = 0,
ManualWrite = 1, ManualWrite = 1,
DMAWrite = 2, DMAWrite = 2,
DMARead = 3 DMARead = 3
}; };
static constexpr auto Enable = Bit(15); static constexpr auto Enable = Bit(15);
static constexpr auto Unmute = Bit(14); static constexpr auto Unmute = Bit(14);
static constexpr auto NoiseFrequcenyShift = BitRange::from_to(10, 13); static constexpr auto NoiseFrequcenyShift = BitRange::from_to(10, 13);
static constexpr auto NoiseFrequcenyStep = BitRange::from_to(8, 9); static constexpr auto NoiseFrequcenyStep = BitRange::from_to(8, 9);
static constexpr auto ReverbMasterEnable = Bit(7); static constexpr auto ReverbMasterEnable = Bit(7);
static constexpr auto IRQ9Enable = Bit(6); static constexpr auto IRQ9Enable = Bit(6);
static constexpr auto TransferMode = BitRange::from_to(4, 5); static constexpr auto TransferMode = BitRange::from_to(4, 5);
static constexpr auto ExternalAudioReverb = Bit(3); static constexpr auto ExternalAudioReverb = Bit(3);
static constexpr auto CDAudioReverb = Bit(2); static constexpr auto CDAudioReverb = Bit(2);
static constexpr auto ExternalAudioEnable = Bit(1); static constexpr auto ExternalAudioEnable = Bit(1);
static constexpr auto CDAudioEnable = Bit(0); static constexpr auto CDAudioEnable = Bit(0);
}; };
__declare_io_struct(DataTransferControl, uint16_t) { __declare_io_struct(DataTransferControl, uint16_t) {
static constexpr DataTransferControl NormalTransferMode() { static constexpr DataTransferControl NormalTransferMode() {
return DataTransferControl{0x0004}; return DataTransferControl{0x0004};
} }
}; };
__declare_io_struct(Echo, uint32_t) { __declare_io_struct(Echo, uint32_t) {
static constexpr auto EchoBits = BitRange::from_to(0, 23); static constexpr auto EchoBits = BitRange::from_to(0, 23);
static constexpr Echo AllOff() { static constexpr Echo AllOff() {
return Echo{0}; return Echo{0};
} }
}; };
__declare_io_struct(KeyOff, uint32_t) { __declare_io_struct(KeyOff, uint32_t) {
static constexpr KeyOff for_specific(uint32_t id) { static constexpr KeyOff for_specific(uint32_t id) {
return KeyOff{1u << id}; return KeyOff{1u << id};
} }
static constexpr KeyOff all() { static constexpr KeyOff all() {
return KeyOff{UI32_MAX}; return KeyOff{UI32_MAX};
} }
}; };
__declare_io_struct(KeyOn, uint32_t) { __declare_io_struct(KeyOn, uint32_t) {
static constexpr KeyOn for_specific(uint32_t id) { static constexpr KeyOn for_specific(uint32_t id) {
return KeyOn{1u << id}; return KeyOn{1u << id};
} }
static constexpr KeyOn all() { static constexpr KeyOn all() {
return KeyOn{UI32_MAX}; return KeyOn{UI32_MAX};
} }
}; };
__declare_io_struct(KeyStatus, uint32_t) { __declare_io_struct(KeyStatus, uint32_t) {
}; };
__declare_io_struct(Noise, uint16_t) { __declare_io_struct(Noise, uint16_t) {
static constexpr auto NoiseBits = BitRange::from_to(0, 23); static constexpr auto NoiseBits = BitRange::from_to(0, 23);
static constexpr Noise AllOff() { static constexpr Noise AllOff() {
return Noise{0}; return Noise{0};
} }
}; };
__declare_io_struct(PitchModulation, uint32_t) { __declare_io_struct(PitchModulation, uint32_t) {
static constexpr auto EnableBits = BitRange::from_to(1, 23); static constexpr auto EnableBits = BitRange::from_to(1, 23);
static constexpr PitchModulation AllOff() { static constexpr PitchModulation AllOff() {
return PitchModulation{0}; return PitchModulation{0};
} }
}; };
__declare_io_struct(SampleRate, uint16_t) { __declare_io_struct(SampleRate, uint16_t) {
static constexpr SampleRate stop() { static constexpr SampleRate stop() {
return SampleRate{0}; return SampleRate{0};
} }
static constexpr SampleRate from_HZ(uint32_t freq) { static constexpr SampleRate from_HZ(uint32_t freq) {
constexpr uint32_t Base1024Hz = static_cast<uint32_t>((4096.0/44100.0)*1024.0); constexpr uint32_t Base1024Hz = static_cast<uint32_t>((4096.0/44100.0)*1024.0);
return SampleRate{static_cast<uint16_t>((freq >> 10)*Base1024Hz)}; return SampleRate{static_cast<uint16_t>((freq >> 10)*Base1024Hz)};
} }
static constexpr SampleRate from_HZ(double freq) { static constexpr SampleRate from_HZ(double freq) {
//4096 == 44100Hz //4096 == 44100Hz
constexpr double Base = (4096.0 / 44100.0); constexpr double Base = (4096.0 / 44100.0);
return SampleRate{static_cast<uint16_t>((freq*Base))}; return SampleRate{static_cast<uint16_t>((freq*Base))};
} }
}; };
__declare_io_struct(SimpleVolume, int16_t) { __declare_io_struct(SimpleVolume, int16_t) {
static constexpr auto MaxVolume = I16_MAX; static constexpr auto MaxVolume = I16_MAX;
static constexpr SimpleVolume mute() { static constexpr SimpleVolume mute() {
return SimpleVolume{0}; return SimpleVolume{0};
} }
constexpr operator int16_t() const { constexpr operator int16_t() const {
return this->raw; return this->raw;
} }
}; };
static constexpr SimpleVolume operator""_vol(long double fraction) { static constexpr SimpleVolume operator""_vol(long double fraction) {
return {static_cast<int16_t>(static_cast<long double>(SimpleVolume::MaxVolume)*fraction)}; return {static_cast<int16_t>(static_cast<long double>(SimpleVolume::MaxVolume)*fraction)};
} }
__declare_io_struct(SR, uint16_t) { __declare_io_struct(SR, uint16_t) {
static constexpr auto SustainMode = Bit(31 - 16); static constexpr auto SustainMode = Bit(31 - 16);
static constexpr auto SustainDirection = Bit(30 - 16); static constexpr auto SustainDirection = Bit(30 - 16);
static constexpr auto SustainShift = BitRange::from_to((24 - 16), (28 - 16)); static constexpr auto SustainShift = BitRange::from_to((24 - 16), (28 - 16));
static constexpr auto SustainStep = BitRange::from_to((22 - 16), (23 - 16)); static constexpr auto SustainStep = BitRange::from_to((22 - 16), (23 - 16));
static constexpr auto ReleaseMode = Bit(21 - 16); static constexpr auto ReleaseMode = Bit(21 - 16);
static constexpr auto ReleaseShift = BitRange::from_to((16 - 16), (20 - 16)); static constexpr auto ReleaseShift = BitRange::from_to((16 - 16), (20 - 16));
static constexpr SR none() { static constexpr SR none() {
return SR{0}; return SR{0};
} }
}; };
__declare_io_struct(SRAMAdr, uint16_t) { __declare_io_struct(SRAMAdr, uint16_t) {
static constexpr SRAMAdr null() { static constexpr SRAMAdr null() {
return SRAMAdr{0x0}; return SRAMAdr{0x0};
} }
static constexpr SRAMAdr adpcm_start() { static constexpr SRAMAdr adpcm_start() {
return SRAMAdr{MemoryMap::ADPCM}; return SRAMAdr{MemoryMap::ADPCM};
} }
}; };
__declare_io_struct(StatusRegister, uint16_t) { __declare_io_struct(StatusRegister, uint16_t) {
enum CapureBufferHalf { enum CapureBufferHalf {
First = 0, First = 0,
Second = 1 Second = 1
}; };
static constexpr auto Unused = BitRange::from_to(12, 15); static constexpr auto Unused = BitRange::from_to(12, 15);
static constexpr auto CaputreBufferHalf = Bit(11); static constexpr auto CaputreBufferHalf = Bit(11);
static constexpr auto TransferBusy = Bit(10); static constexpr auto TransferBusy = Bit(10);
static constexpr auto IsDMARead = Bit(9); static constexpr auto IsDMARead = Bit(9);
static constexpr auto isDMAWrite = Bit(8); static constexpr auto isDMAWrite = Bit(8);
static constexpr auto isDMA = Bit(7); static constexpr auto isDMA = Bit(7);
static constexpr auto isIRQ = Bit(6); static constexpr auto isIRQ = Bit(6);
// Copies of ControlRegister // Copies of ControlRegister
static constexpr auto TransferMode = BitRange::from_to(4, 5); static constexpr auto TransferMode = BitRange::from_to(4, 5);
static constexpr auto ExternalAudioReverb = Bit(3); static constexpr auto ExternalAudioReverb = Bit(3);
static constexpr auto CDAudioReverb = Bit(2); static constexpr auto CDAudioReverb = Bit(2);
static constexpr auto ExternalAudioEnable = Bit(1); static constexpr auto ExternalAudioEnable = Bit(1);
static constexpr auto CDAudioEnable = Bit(0); static constexpr auto CDAudioEnable = Bit(0);
}; };
__declare_io_struct(SweepVolume, int16_t) { __declare_io_struct(SweepVolume, int16_t) {
struct VolumeMode { struct VolumeMode {
static constexpr auto MaxVolume = (I16_MAX >> 1); static constexpr auto MaxVolume = (I16_MAX >> 1);
static constexpr auto EnableSweep = Bit(15); static constexpr auto EnableSweep = Bit(15);
static constexpr auto Enable = !EnableSweep; static constexpr auto Enable = !EnableSweep;
static constexpr auto Volume = BitRange::from_to(0, 14); static constexpr auto Volume = BitRange::from_to(0, 14);
}; };
struct SweepMode { struct SweepMode {
enum Mode { enum Mode {
Linear = 0, Linear = 0,
Exponential = 1, Exponential = 1,
}; };
enum Direction { enum Direction {
Increase = 0, Increase = 0,
Decrease = 1, Decrease = 1,
}; };
enum Phase { enum Phase {
Posititve = 0, Posititve = 0,
Negative = 1, Negative = 1,
}; };
static constexpr auto Mode = Bit(14); static constexpr auto Mode = Bit(14);
static constexpr auto Direction = Bit(13); static constexpr auto Direction = Bit(13);
static constexpr auto Phase = Bit(12); static constexpr auto Phase = Bit(12);
static constexpr auto Shift = BitRange::from_to(2, 6); static constexpr auto Shift = BitRange::from_to(2, 6);
static constexpr auto Step = BitRange::from_to(0, 1); static constexpr auto Step = BitRange::from_to(0, 1);
}; };
static constexpr SweepVolume create(SimpleVolume volume) { static constexpr SweepVolume create(SimpleVolume volume) {
return from(VolumeMode::Enable, VolumeMode::Volume.with(volume.raw >> 1)); return from(VolumeMode::Enable, VolumeMode::Volume.with(volume.raw >> 1));
} }
static constexpr SweepVolume mute() { static constexpr SweepVolume mute() {
return SweepVolume{0}; return SweepVolume{0};
} }
}; };
} }
} }

View File

@ -1,31 +1,31 @@
#pragma once #pragma once
#include "ioport.hpp" #include "ioport.hpp"
namespace JabyEngine { namespace JabyEngine {
namespace Timer_IO_Values { namespace Timer_IO_Values {
__declare_io_struct(CounterMode, uint32_t) { __declare_io_struct(CounterMode, uint32_t) {
static constexpr auto SyncEnable = Bit(0); static constexpr auto SyncEnable = Bit(0);
static constexpr auto FreeRun = !SyncEnable; static constexpr auto FreeRun = !SyncEnable;
static constexpr auto SyncMode = BitRange::from_to(1, 2); static constexpr auto SyncMode = BitRange::from_to(1, 2);
static constexpr auto ResetAfterTarget = Bit(3); static constexpr auto ResetAfterTarget = Bit(3);
static constexpr auto IRQAtTarget = Bit(4); static constexpr auto IRQAtTarget = Bit(4);
static constexpr auto IRQAtMax = Bit(5); static constexpr auto IRQAtMax = Bit(5);
static constexpr auto IRQEveryTime = Bit(6); static constexpr auto IRQEveryTime = Bit(6);
static constexpr auto IRQOneShot = !IRQEveryTime; static constexpr auto IRQOneShot = !IRQEveryTime;
static constexpr auto IRQToggle = Bit(7); static constexpr auto IRQToggle = Bit(7);
static constexpr auto IRQPulse = !IRQToggle; static constexpr auto IRQPulse = !IRQToggle;
static constexpr auto ClockSource = BitRange::from_to(8, 9); static constexpr auto ClockSource = BitRange::from_to(8, 9);
static constexpr auto HasIRQRequest = Bit(10); static constexpr auto HasIRQRequest = Bit(10);
static constexpr auto IsTargetReached = Bit(11); static constexpr auto IsTargetReached = Bit(11);
static constexpr auto IsMaxReached = Bit(12); static constexpr auto IsMaxReached = Bit(12);
}; };
__declare_io_struct(CounterTarget, uint32_t) { __declare_io_struct(CounterTarget, uint32_t) {
static constexpr auto CounterTargetValue = BitRange::from_to(0, 15); static constexpr auto CounterTargetValue = BitRange::from_to(0, 15);
}; };
__declare_io_struct(CounterValue, uint32_t) { __declare_io_struct(CounterValue, uint32_t) {
static constexpr auto Value = BitRange::from_to(0, 15); static constexpr auto Value = BitRange::from_to(0, 15);
}; };
} }
} }

View File

@ -1,41 +1,41 @@
#pragma once #pragma once
#include "IOValues/interrupt_io_values.hpp" #include "IOValues/interrupt_io_values.hpp"
namespace JabyEngine { namespace JabyEngine {
using Status_IO = IOPort<Interrupt_IO_Values::Status>; using Status_IO = IOPort<Interrupt_IO_Values::Status>;
using Mask_IO = IOPort<Interrupt_IO_Values::Mask>; using Mask_IO = IOPort<Interrupt_IO_Values::Mask>;
struct Interrupt { struct Interrupt {
static constexpr auto VBlank = Bit(0); static constexpr auto VBlank = Bit(0);
static constexpr auto GPU = Bit(1); static constexpr auto GPU = Bit(1);
static constexpr auto CDROM = Bit(2); static constexpr auto CDROM = Bit(2);
static constexpr auto DMA = Bit(3); static constexpr auto DMA = Bit(3);
static constexpr auto Timer0 = Bit(4); static constexpr auto Timer0 = Bit(4);
static constexpr auto Timer1 = Bit(5); static constexpr auto Timer1 = Bit(5);
static constexpr auto Timer2 = Bit(6); static constexpr auto Timer2 = Bit(6);
static constexpr auto Periphery = Bit(7); static constexpr auto Periphery = Bit(7);
static constexpr auto SIO = Bit(8); static constexpr auto SIO = Bit(8);
static constexpr auto SPU = Bit(9); static constexpr auto SPU = Bit(9);
static constexpr auto Controller = Bit(10); static constexpr auto Controller = Bit(10);
static constexpr auto LightPen = Controller; static constexpr auto LightPen = Controller;
static inline auto& Status = __declare_io_port(Status_IO, 0x1F801070); static inline auto& Status = __declare_io_port(Status_IO, 0x1F801070);
static inline auto& Mask = __declare_io_port(Mask_IO, 0x1F801074); static inline auto& Mask = __declare_io_port(Mask_IO, 0x1F801074);
static bool is_irq(Bit irq) { static bool is_irq(Bit irq) {
return Status.read().is_set(irq); return Status.read().is_set(irq);
} }
static void ack_irq(Bit irq) { static void ack_irq(Bit irq) {
Status.write({bit::clear<uint32_t>(0b11111111111, irq)}); Status.write({bit::clear<uint32_t>(0b11111111111, irq)});
} }
static void disable_irq(Bit irq) { static void disable_irq(Bit irq) {
Mask.write(Mask.read().clear(irq)); Mask.write(Mask.read().clear(irq));
} }
static void enable_irq(Bit irq) { static void enable_irq(Bit irq) {
Mask.write(Mask.read().set(irq)); Mask.write(Mask.read().set(irq));
} }
}; };
} }

View File

@ -1,29 +1,29 @@
#pragma once #pragma once
#include "IOValues/periphery_io_values.hpp" #include "IOValues/periphery_io_values.hpp"
namespace JabyEngine { namespace JabyEngine {
namespace Periphery_IO { namespace Periphery_IO {
struct JOY_STAT_IO : public IOPort<Periphery_IO_Values::JOY_STAT> { struct JOY_STAT_IO : public IOPort<Periphery_IO_Values::JOY_STAT> {
inline bool has_response() const { inline bool has_response() const {
return this->read().is_set(Periphery_IO_Values::JOY_STAT::RXFifoNonEmpty); return this->read().is_set(Periphery_IO_Values::JOY_STAT::RXFifoNonEmpty);
} }
inline bool is_ready_transfer() const { inline bool is_ready_transfer() const {
return this->read().is_set(Periphery_IO_Values::JOY_STAT::TXReadyFinished); return this->read().is_set(Periphery_IO_Values::JOY_STAT::TXReadyFinished);
} }
}; };
using JOY_BAUD_IO = IOPort<Periphery_IO_Values::JOY_BAUD>; using JOY_BAUD_IO = IOPort<Periphery_IO_Values::JOY_BAUD>;
using JOY_CTRL_IO = IOPort<Periphery_IO_Values::JOY_CTRL>; using JOY_CTRL_IO = IOPort<Periphery_IO_Values::JOY_CTRL>;
using JOY_MODE_IO = IOPort<Periphery_IO_Values::JOY_MODE>; using JOY_MODE_IO = IOPort<Periphery_IO_Values::JOY_MODE>;
using JOY_RX_DATA_IO = IOPort<Periphery_IO_Values::JOY_RX_DATA>; using JOY_RX_DATA_IO = IOPort<Periphery_IO_Values::JOY_RX_DATA>;
using JOY_TX_DATA_IO = IOPort<Periphery_IO_Values::JOY_TX_DATA>; using JOY_TX_DATA_IO = IOPort<Periphery_IO_Values::JOY_TX_DATA>;
static auto& JOY_TX_DATA = __declare_io_port(JOY_TX_DATA_IO, 0x1F801040); static auto& JOY_TX_DATA = __declare_io_port(JOY_TX_DATA_IO, 0x1F801040);
static const auto& JOY_RX_DATA = __declare_io_port(JOY_RX_DATA_IO, 0x1F801040); static const auto& JOY_RX_DATA = __declare_io_port(JOY_RX_DATA_IO, 0x1F801040);
static const auto& JOY_STAT = __declare_io_port(JOY_STAT_IO, 0x1F801044); static const auto& JOY_STAT = __declare_io_port(JOY_STAT_IO, 0x1F801044);
static auto& JOY_MODE = __declare_io_port(JOY_MODE_IO, 0x1F801048); static auto& JOY_MODE = __declare_io_port(JOY_MODE_IO, 0x1F801048);
static auto& JOY_CTRL = __declare_io_port(JOY_CTRL_IO, 0x1F80104A); static auto& JOY_CTRL = __declare_io_port(JOY_CTRL_IO, 0x1F80104A);
static auto& JOY_BAUD = __declare_io_port(JOY_BAUD_IO, 0x1F80104E); static auto& JOY_BAUD = __declare_io_port(JOY_BAUD_IO, 0x1F80104E);
} }
} }

View File

@ -1,89 +1,89 @@
#pragma once #pragma once
#include "IOValues/timer_io_values.hpp" #include "IOValues/timer_io_values.hpp"
namespace JabyEngine { namespace JabyEngine {
namespace Timer_IO { namespace Timer_IO {
using CounterMode_IO = IOPort<Timer_IO_Values::CounterMode>; using CounterMode_IO = IOPort<Timer_IO_Values::CounterMode>;
using CounterTarget_IO = IOPort<Timer_IO_Values::CounterTarget>; using CounterTarget_IO = IOPort<Timer_IO_Values::CounterTarget>;
using CounterValue_IO = IOPort<Timer_IO_Values::CounterValue>; using CounterValue_IO = IOPort<Timer_IO_Values::CounterValue>;
#pragma pack(push, 1) #pragma pack(push, 1)
struct Counter { struct Counter {
CounterValue_IO value; CounterValue_IO value;
CounterMode_IO mode; CounterMode_IO mode;
CounterTarget_IO target; CounterTarget_IO target;
uint32_t unused; uint32_t unused;
inline uint16_t get_current_value() const { inline uint16_t get_current_value() const {
return this->value.read().get(Timer_IO_Values::CounterValue::Value); return this->value.read().get(Timer_IO_Values::CounterValue::Value);
} }
inline void set_target_value(uint16_t value) { inline void set_target_value(uint16_t value) {
this->target.write(Timer_IO_Values::CounterTarget{0}.set_range(Timer_IO_Values::CounterTarget::CounterTargetValue, value)); this->target.write(Timer_IO_Values::CounterTarget{0}.set_range(Timer_IO_Values::CounterTarget::CounterTargetValue, value));
} }
inline void set_mode(Timer_IO_Values::CounterMode mode) { inline void set_mode(Timer_IO_Values::CounterMode mode) {
this->mode.write(mode); this->mode.write(mode);
} }
}; };
#pragma pack(pop) #pragma pack(pop)
#pragma pack(push, 1) #pragma pack(push, 1)
struct Counter0 : public Counter { struct Counter0 : public Counter {
struct SyncMode { struct SyncMode {
static constexpr auto Zero_At_Hblank = Timer_IO_Values::CounterMode::SyncMode.with(1u); static constexpr auto Zero_At_Hblank = Timer_IO_Values::CounterMode::SyncMode.with(1u);
static constexpr auto Pause_During_Hblank = Timer_IO_Values::CounterMode::SyncMode.with(0u); static constexpr auto Pause_During_Hblank = Timer_IO_Values::CounterMode::SyncMode.with(0u);
static constexpr auto Zero_At_Hblank_Pause_Outside_Hblank = Timer_IO_Values::CounterMode::SyncMode.with(2u); static constexpr auto Zero_At_Hblank_Pause_Outside_Hblank = Timer_IO_Values::CounterMode::SyncMode.with(2u);
static constexpr auto Pause_Until_Hblank_Then_Freerun = Timer_IO_Values::CounterMode::SyncMode.with(3u); static constexpr auto Pause_Until_Hblank_Then_Freerun = Timer_IO_Values::CounterMode::SyncMode.with(3u);
}; };
struct Source { struct Source {
static constexpr auto System_Clock = Timer_IO_Values::CounterMode::ClockSource.with(0u); static constexpr auto System_Clock = Timer_IO_Values::CounterMode::ClockSource.with(0u);
static constexpr auto Dot_Clock = Timer_IO_Values::CounterMode::ClockSource.with(1u); static constexpr auto Dot_Clock = Timer_IO_Values::CounterMode::ClockSource.with(1u);
static constexpr auto System_Clock_Too = Timer_IO_Values::CounterMode::ClockSource.with(2u); static constexpr auto System_Clock_Too = Timer_IO_Values::CounterMode::ClockSource.with(2u);
static constexpr auto Dot_Clock_Too = Timer_IO_Values::CounterMode::ClockSource.with(3u); static constexpr auto Dot_Clock_Too = Timer_IO_Values::CounterMode::ClockSource.with(3u);
}; };
}; };
struct Counter1 : public Counter { struct Counter1 : public Counter {
struct SyncMode { struct SyncMode {
static constexpr auto Pause_During_Vblank = Timer_IO_Values::CounterMode::SyncMode.with(0u); static constexpr auto Pause_During_Vblank = Timer_IO_Values::CounterMode::SyncMode.with(0u);
static constexpr auto Zero_At_Vblank = Timer_IO_Values::CounterMode::SyncMode.with(1u); static constexpr auto Zero_At_Vblank = Timer_IO_Values::CounterMode::SyncMode.with(1u);
static constexpr auto Zero_At_Vblank_Pause_Outside_Vblank = Timer_IO_Values::CounterMode::SyncMode.with(2u); static constexpr auto Zero_At_Vblank_Pause_Outside_Vblank = Timer_IO_Values::CounterMode::SyncMode.with(2u);
static constexpr auto Pause_Until_Vblank_Then_FreeRun = Timer_IO_Values::CounterMode::SyncMode.with(3u); static constexpr auto Pause_Until_Vblank_Then_FreeRun = Timer_IO_Values::CounterMode::SyncMode.with(3u);
}; };
struct Source { struct Source {
static constexpr auto System_Clock = Timer_IO_Values::CounterMode::ClockSource.with(0u); static constexpr auto System_Clock = Timer_IO_Values::CounterMode::ClockSource.with(0u);
static constexpr auto Hblank = Timer_IO_Values::CounterMode::ClockSource.with(1u); static constexpr auto Hblank = Timer_IO_Values::CounterMode::ClockSource.with(1u);
static constexpr auto System_Clock_Too = Timer_IO_Values::CounterMode::ClockSource.with(2u); static constexpr auto System_Clock_Too = Timer_IO_Values::CounterMode::ClockSource.with(2u);
static constexpr auto Hblank_Too = Timer_IO_Values::CounterMode::ClockSource.with(3u); static constexpr auto Hblank_Too = Timer_IO_Values::CounterMode::ClockSource.with(3u);
}; };
}; };
struct Counter2 : public Counter { struct Counter2 : public Counter {
struct SyncMode { struct SyncMode {
static constexpr auto Stop_Counter = Timer_IO_Values::CounterMode::SyncMode.with(0u); static constexpr auto Stop_Counter = Timer_IO_Values::CounterMode::SyncMode.with(0u);
static constexpr auto FreeRun = Timer_IO_Values::CounterMode::SyncMode.with(1u); static constexpr auto FreeRun = Timer_IO_Values::CounterMode::SyncMode.with(1u);
static constexpr auto FreeRun_Too = Timer_IO_Values::CounterMode::SyncMode.with(2u); static constexpr auto FreeRun_Too = Timer_IO_Values::CounterMode::SyncMode.with(2u);
static constexpr auto Stop_Counter_Too = Timer_IO_Values::CounterMode::SyncMode.with(3u); static constexpr auto Stop_Counter_Too = Timer_IO_Values::CounterMode::SyncMode.with(3u);
}; };
struct Source { struct Source {
static constexpr auto System_Clock = Timer_IO_Values::CounterMode::ClockSource.with(0u); static constexpr auto System_Clock = Timer_IO_Values::CounterMode::ClockSource.with(0u);
static constexpr auto System_Clock_Too = Timer_IO_Values::CounterMode::ClockSource.with(1u); static constexpr auto System_Clock_Too = Timer_IO_Values::CounterMode::ClockSource.with(1u);
static constexpr auto System_Clock_Div_8 = Timer_IO_Values::CounterMode::ClockSource.with(2u); static constexpr auto System_Clock_Div_8 = Timer_IO_Values::CounterMode::ClockSource.with(2u);
static constexpr auto System_Clock_Div_8_Too = Timer_IO_Values::CounterMode::ClockSource.with(3u); static constexpr auto System_Clock_Div_8_Too = Timer_IO_Values::CounterMode::ClockSource.with(3u);
}; };
}; };
#pragma pack(pop) #pragma pack(pop)
static constexpr uintptr_t counter_base_adr(size_t ID) { static constexpr uintptr_t counter_base_adr(size_t ID) {
return (0x1F801100 + (ID*0x10)); return (0x1F801100 + (ID*0x10));
} }
static auto& Counter0 = __declare_io_value(struct Counter0, counter_base_adr(0)); static auto& Counter0 = __declare_io_value(struct Counter0, counter_base_adr(0));
static auto& Counter1 = __declare_io_value(struct Counter1, counter_base_adr(1)); static auto& Counter1 = __declare_io_value(struct Counter1, counter_base_adr(1));
static auto& Counter2 = __declare_io_value(struct Counter2, counter_base_adr(2)); static auto& Counter2 = __declare_io_value(struct Counter2, counter_base_adr(2));
} }
} }

View File

@ -1,20 +1,20 @@
#pragma once #pragma once
#include "syscalls.hpp" #include "syscalls.hpp"
namespace JabyEngine { namespace JabyEngine {
namespace Callback { namespace Callback {
struct [[deprecated("Currently not supported")]] VSyncCallback { struct [[deprecated("Currently not supported")]] VSyncCallback {
using Function = void (*)(); using Function = void (*)();
static Function callback; static Function callback;
static void install(Function function) { static void install(Function function) {
VSyncCallback::callback = function; VSyncCallback::callback = function;
} }
static void uninstall() { static void uninstall() {
VSyncCallback::install(nullptr); VSyncCallback::install(nullptr);
} }
}; };
} }
} }

View File

@ -1,293 +1,293 @@
#pragma once #pragma once
#include "../jabyengine_defines.hpp" #include "../jabyengine_defines.hpp"
/* /*
R0 zr Constant Zero R0 zr Constant Zero
R1 at Reserved for the assembler R1 at Reserved for the assembler
R2-R3 v0-v1 Values for results and expression evaluation R2-R3 v0-v1 Values for results and expression evaluation
R4-R7 a0-a3 Arguments R4-R7 a0-a3 Arguments
R8-R15 t0-t7 Temporaries (not preserved across call) R8-R15 t0-t7 Temporaries (not preserved across call)
R16-R23 s0-s7 Saved (preserved across call) R16-R23 s0-s7 Saved (preserved across call)
R24-R25 t8-t9 More temporaries (not preserved across call) R24-R25 t8-t9 More temporaries (not preserved across call)
R26-R27 k0-k1 Reserved for OS Kernel R26-R27 k0-k1 Reserved for OS Kernel
R28 gp Global Pointer R28 gp Global Pointer
R29 sp Stack Pointer R29 sp Stack Pointer
R30 fp Frame Pointer R30 fp Frame Pointer
R31 ra Return address (set by function call) R31 ra Return address (set by function call)
*/ */
namespace JabyEngine { namespace JabyEngine {
namespace BIOS { namespace BIOS {
struct Version { struct Version {
enum Type { enum Type {
Unkown, Unkown,
Devboard, Devboard,
PS1, PS1,
PS2, PS2,
PS3, PS3,
PSCompatible, // internal usage only PSCompatible, // internal usage only
No$psx, No$psx,
XEBRA XEBRA
}; };
struct { struct {
uint8_t day; uint8_t day;
uint8_t month; uint8_t month;
uint16_t year; uint16_t year;
} date; } date;
Type type; Type type;
const char* kernel_maker; const char* kernel_maker;
const char* version_str; const char* version_str;
const char* gui_version; const char* gui_version;
const char* copyright; const char* copyright;
}; };
extern const Version version; extern const Version version;
} }
struct TCB { struct TCB {
uint32_t status; uint32_t status;
uint32_t unused; uint32_t unused;
uint32_t reg[32]; uint32_t reg[32];
uint32_t epc; uint32_t epc;
uint32_t hi; uint32_t hi;
uint32_t lo; uint32_t lo;
uint32_t sr; uint32_t sr;
uint32_t cause; uint32_t cause;
uint32_t unused2[9]; uint32_t unused2[9];
}; };
struct PCB { struct PCB {
TCB* current_tcb; TCB* current_tcb;
}; };
struct ToT { struct ToT {
using ExCB = void; using ExCB = void;
using EvCB = void; using EvCB = void;
using FCB = void; using FCB = void;
ExCB* exception_chain; ExCB* exception_chain;
uint32_t exception_chain_size; uint32_t exception_chain_size;
PCB* processes; PCB* processes;
uint32_t processes_size; uint32_t processes_size;
TCB* threads; TCB* threads;
uint32_t threads_size; uint32_t threads_size;
uint32_t reserved_0; uint32_t reserved_0;
uint32_t reserved_1; uint32_t reserved_1;
EvCB* events; EvCB* events;
uint32_t events_size; uint32_t events_size;
uint32_t reserved_2; uint32_t reserved_2;
uint32_t reserved_3; uint32_t reserved_3;
uint32_t reserved_4; uint32_t reserved_4;
uint32_t reserved_5; uint32_t reserved_5;
uint32_t reserved_6; uint32_t reserved_6;
uint32_t reserved_7; uint32_t reserved_7;
FCB* files; FCB* files;
uint32_t files_size; uint32_t files_size;
uint32_t reserved_8; uint32_t reserved_8;
uint32_t reserved_9; uint32_t reserved_9;
}; };
extern ToT table_of_tables; extern ToT table_of_tables;
namespace SysCall { namespace SysCall {
static constexpr const uint32_t Table_A = 0xA0; static constexpr const uint32_t Table_A = 0xA0;
static constexpr const uint32_t Table_B = 0xB0; static constexpr const uint32_t Table_B = 0xB0;
static constexpr const uint32_t Table_C = 0xC0; static constexpr const uint32_t Table_C = 0xC0;
enum struct Priority { enum struct Priority {
CdromDmaIrq = 0, CdromDmaIrq = 0,
CdromIoIrq = 0, CdromIoIrq = 0,
SyscallException = 0, SyscallException = 0,
CardSpecificIrq = 1, CardSpecificIrq = 1,
VblankIrq = 1, VblankIrq = 1,
Timer2Irq = 1, Timer2Irq = 1,
Timer1Irq = 1, Timer1Irq = 1,
Timer0Irq = 1, Timer0Irq = 1,
PadCardIrq = 2, PadCardIrq = 2,
DefInt = 3 DefInt = 3
}; };
enum InterruptVerifierResult { enum InterruptVerifierResult {
SkipHandler = 0, SkipHandler = 0,
ExecuteHandler = 1 ExecuteHandler = 1
}; };
typedef InterruptVerifierResult (*InterruptVerifier)(); typedef InterruptVerifierResult (*InterruptVerifier)();
typedef void (*InterruptHandler)(uint32_t); typedef void (*InterruptHandler)(uint32_t);
using ThreadHandle = uint32_t; using ThreadHandle = uint32_t;
#pragma pack(push, 1) #pragma pack(push, 1)
struct InterruptCallback { struct InterruptCallback {
struct InterruptCallback* next; struct InterruptCallback* next;
InterruptHandler handler_function; InterruptHandler handler_function;
InterruptVerifier verifier_function; InterruptVerifier verifier_function;
uint32_t notUsed; uint32_t notUsed;
static constexpr InterruptCallback from(InterruptVerifier verifier, InterruptHandler handler) { static constexpr InterruptCallback from(InterruptVerifier verifier, InterruptHandler handler) {
return InterruptCallback{nullptr, handler, verifier, 0}; return InterruptCallback{nullptr, handler, verifier, 0};
} }
}; };
#pragma pack(pop) #pragma pack(pop)
#define __syscall_function_cast(table, ...) reinterpret_cast<__VA_ARGS__>(table) #define __syscall_function_cast(table, ...) reinterpret_cast<__VA_ARGS__>(table)
static __always_inline uint32_t* get_gp() { static __always_inline uint32_t* get_gp() {
uint32_t* gp; uint32_t* gp;
__asm__("sw $gp, %0" : "=m"(gp)); __asm__("sw $gp, %0" : "=m"(gp));
return gp; return gp;
} }
static __always_inline void DequeueCdIntr() { static __always_inline void DequeueCdIntr() {
register uint32_t FuncID asm("t1") = 0xa3; register uint32_t FuncID asm("t1") = 0xa3;
__asm__ volatile("" : "=r"(FuncID) : "r"(FuncID)); __asm__ volatile("" : "=r"(FuncID) : "r"(FuncID));
__syscall_function_cast(Table_A, void(*)())(); __syscall_function_cast(Table_A, void(*)())();
} }
static __always_inline void FlushCache() { static __always_inline void FlushCache() {
register uint32_t FuncID asm("t1") = 0x44; register uint32_t FuncID asm("t1") = 0x44;
__asm__ volatile("" : "=r"(FuncID) : "r"(FuncID)); __asm__ volatile("" : "=r"(FuncID) : "r"(FuncID));
__syscall_function_cast(Table_A, void(*)())(); __syscall_function_cast(Table_A, void(*)())();
} }
static __always_inline void* memcpy(void *dst, const void *src, size_t len) { static __always_inline void* memcpy(void *dst, const void *src, size_t len) {
register uint32_t FuncID asm("t1") = 0x2A; register uint32_t FuncID asm("t1") = 0x2A;
__asm__ volatile("" : "=r"(FuncID) : "r"(FuncID)); __asm__ volatile("" : "=r"(FuncID) : "r"(FuncID));
return __syscall_function_cast(Table_A, void*(*)(void*, const void*, size_t))(dst, src, len); return __syscall_function_cast(Table_A, void*(*)(void*, const void*, size_t))(dst, src, len);
} }
static __always_inline ThreadHandle OpenThread(void (*thread_func)(), uint32_t* stack_ptr, uint32_t* gp) { static __always_inline ThreadHandle OpenThread(void (*thread_func)(), uint32_t* stack_ptr, uint32_t* gp) {
register uint32_t FuncID asm("t1") = 0x0E; register uint32_t FuncID asm("t1") = 0x0E;
__asm__ volatile("" : "=r"(FuncID) : "r"(FuncID)); __asm__ volatile("" : "=r"(FuncID) : "r"(FuncID));
return __syscall_function_cast(Table_B, ThreadHandle(*)(void(*)(), uint32_t*, uint32_t*))(thread_func, stack_ptr, gp); return __syscall_function_cast(Table_B, ThreadHandle(*)(void(*)(), uint32_t*, uint32_t*))(thread_func, stack_ptr, gp);
} }
static __always_inline void [[noreturn]] ChangeThread(ThreadHandle handle) { static __always_inline void [[noreturn]] ChangeThread(ThreadHandle handle) {
register uint32_t FuncID asm("t1") = 0x10; register uint32_t FuncID asm("t1") = 0x10;
__asm__ volatile("" : "=r"(FuncID) : "r"(FuncID)); __asm__ volatile("" : "=r"(FuncID) : "r"(FuncID));
__syscall_function_cast(Table_B, void(*)(ThreadHandle))(handle); __syscall_function_cast(Table_B, void(*)(ThreadHandle))(handle);
} }
static __always_inline void InitPad(uint8_t *portA, uint32_t portASize, uint8_t *portB, uint32_t portBSize) { static __always_inline void InitPad(uint8_t *portA, uint32_t portASize, uint8_t *portB, uint32_t portBSize) {
register uint32_t FuncID asm("t1") = 0x12; register uint32_t FuncID asm("t1") = 0x12;
__asm__ volatile("" : "=r"(FuncID) : "r"(FuncID)); __asm__ volatile("" : "=r"(FuncID) : "r"(FuncID));
__syscall_function_cast(Table_B, void(*)(uint8_t*, uint32_t, uint8_t*, uint32_t))(portA, portASize, portB, portBSize); __syscall_function_cast(Table_B, void(*)(uint8_t*, uint32_t, uint8_t*, uint32_t))(portA, portASize, portB, portBSize);
} }
static __always_inline void StartPad() { static __always_inline void StartPad() {
register uint32_t FuncID asm("t1") = 0x13; register uint32_t FuncID asm("t1") = 0x13;
__asm__ volatile("" : "=r"(FuncID) : "r"(FuncID)); __asm__ volatile("" : "=r"(FuncID) : "r"(FuncID));
__syscall_function_cast(Table_B, void(*)())(); __syscall_function_cast(Table_B, void(*)())();
} }
static __always_inline void StopPad() { static __always_inline void StopPad() {
register uint32_t FuncID asm("t1") = 0x14; register uint32_t FuncID asm("t1") = 0x14;
__asm__ volatile("" : "=r"(FuncID) : "r"(FuncID)); __asm__ volatile("" : "=r"(FuncID) : "r"(FuncID));
__syscall_function_cast(Table_B, void(*)())(); __syscall_function_cast(Table_B, void(*)())();
} }
static __always_inline void ChangeClearPad(int32_t _reserved) { static __always_inline void ChangeClearPad(int32_t _reserved) {
register uint32_t FuncID asm("t1") = 0x5B; register uint32_t FuncID asm("t1") = 0x5B;
__asm__ volatile("" : "=r"(FuncID) : "r"(FuncID)); __asm__ volatile("" : "=r"(FuncID) : "r"(FuncID));
__syscall_function_cast(Table_B, void(*)(int32_t))(_reserved); __syscall_function_cast(Table_B, void(*)(int32_t))(_reserved);
} }
static __always_inline void [[noreturn]] ReturnFromException() { static __always_inline void [[noreturn]] ReturnFromException() {
register uint32_t FuncID asm("t1") = 0x17; register uint32_t FuncID asm("t1") = 0x17;
__asm__ volatile("" : "=r"(FuncID) : "r"(FuncID)); __asm__ volatile("" : "=r"(FuncID) : "r"(FuncID));
__syscall_function_cast(Table_B, void(*)())(); __syscall_function_cast(Table_B, void(*)())();
} }
static __always_inline void SetDefaultExitFromException() { static __always_inline void SetDefaultExitFromException() {
register uint32_t FuncID asm("t1") = 0x18; register uint32_t FuncID asm("t1") = 0x18;
__asm__ volatile("" : "=r"(FuncID) : "r"(FuncID)); __asm__ volatile("" : "=r"(FuncID) : "r"(FuncID));
__syscall_function_cast(Table_B, void(*)())(); __syscall_function_cast(Table_B, void(*)())();
} }
static __always_inline int SysEnqIntRP(Priority prio, InterruptCallback* interElm) { static __always_inline int SysEnqIntRP(Priority prio, InterruptCallback* interElm) {
register uint32_t FuncID asm("t1") = 0x02; register uint32_t FuncID asm("t1") = 0x02;
__asm__ volatile("" : "=r"(FuncID) : "r"(FuncID)); __asm__ volatile("" : "=r"(FuncID) : "r"(FuncID));
return __syscall_function_cast(Table_C, int(*)(Priority prio, InterruptCallback *interElm))(prio, interElm); return __syscall_function_cast(Table_C, int(*)(Priority prio, InterruptCallback *interElm))(prio, interElm);
} }
static __always_inline int SysDeqIntRP(Priority prio, InterruptCallback *interElm) { static __always_inline int SysDeqIntRP(Priority prio, InterruptCallback *interElm) {
register uint32_t FuncID asm("t1") = 0x03; register uint32_t FuncID asm("t1") = 0x03;
__asm__ volatile("" : "=r"(FuncID) : "r"(FuncID)); __asm__ volatile("" : "=r"(FuncID) : "r"(FuncID));
return __syscall_function_cast(Table_C, int(*)(Priority prio, InterruptCallback *interElm))(prio, interElm); return __syscall_function_cast(Table_C, int(*)(Priority prio, InterruptCallback *interElm))(prio, interElm);
} }
static __always_inline uint32_t EnterCriticalSection() { static __always_inline uint32_t EnterCriticalSection() {
register uint32_t FuncID asm("a0") = 0x01; register uint32_t FuncID asm("a0") = 0x01;
register uint32_t returnValue asm("v0"); register uint32_t returnValue asm("v0");
__asm__ volatile("syscall" : "=r"(returnValue) : "r"(FuncID) : "memory"); __asm__ volatile("syscall" : "=r"(returnValue) : "r"(FuncID) : "memory");
return returnValue; return returnValue;
} }
static __always_inline void ExitCriticalSection() { static __always_inline void ExitCriticalSection() {
register uint32_t FuncID asm("a0") = 0x02; register uint32_t FuncID asm("a0") = 0x02;
__asm__ volatile("syscall" :: "r"(FuncID) : "memory"); __asm__ volatile("syscall" :: "r"(FuncID) : "memory");
} }
static __always_inline void DeliverEvent(uint32_t classId, uint32_t spec) { static __always_inline void DeliverEvent(uint32_t classId, uint32_t spec) {
register uint32_t FuncID asm("t1") = 0x07; register uint32_t FuncID asm("t1") = 0x07;
__asm__ volatile("" : "=r"(FuncID) : "r"(FuncID)); __asm__ volatile("" : "=r"(FuncID) : "r"(FuncID));
__syscall_function_cast(Table_B, void (*)(uint32_t, uint32_t))(classId, spec); __syscall_function_cast(Table_B, void (*)(uint32_t, uint32_t))(classId, spec);
} }
static __always_inline uint32_t OpenEvent(uint32_t classId, uint32_t spec, uint32_t mode, void (*handler)()) { static __always_inline uint32_t OpenEvent(uint32_t classId, uint32_t spec, uint32_t mode, void (*handler)()) {
register uint32_t FuncID asm("t1") = 0x08; register uint32_t FuncID asm("t1") = 0x08;
__asm__ volatile("" : "=r"(FuncID) : "r"(FuncID)); __asm__ volatile("" : "=r"(FuncID) : "r"(FuncID));
return __syscall_function_cast(Table_B, uint32_t(*)(uint32_t, uint32_t, uint32_t, void(*)()))(classId, spec, mode, handler); return __syscall_function_cast(Table_B, uint32_t(*)(uint32_t, uint32_t, uint32_t, void(*)()))(classId, spec, mode, handler);
} }
static __always_inline int CloseEvent(uint32_t event) { static __always_inline int CloseEvent(uint32_t event) {
register uint32_t FuncID asm("t1") = 0x09; register uint32_t FuncID asm("t1") = 0x09;
__asm__ volatile("" : "=r"(FuncID) : "r"(FuncID)); __asm__ volatile("" : "=r"(FuncID) : "r"(FuncID));
return __syscall_function_cast(Table_B, uint32_t(*)(uint32_t))(event); return __syscall_function_cast(Table_B, uint32_t(*)(uint32_t))(event);
} }
static __always_inline int32_t TestEvent(uint32_t event) { static __always_inline int32_t TestEvent(uint32_t event) {
register uint32_t FuncID asm("t1") = 0x0B; register uint32_t FuncID asm("t1") = 0x0B;
__asm__ volatile("" : "=r"(FuncID) : "r"(FuncID)); __asm__ volatile("" : "=r"(FuncID) : "r"(FuncID));
return __syscall_function_cast(Table_B, int32_t (*)(uint32_t))(event); return __syscall_function_cast(Table_B, int32_t (*)(uint32_t))(event);
} }
static __always_inline int32_t EnableEvent(uint32_t event) { static __always_inline int32_t EnableEvent(uint32_t event) {
register uint32_t FuncID asm("t1") = 0x0C; register uint32_t FuncID asm("t1") = 0x0C;
__asm__ volatile("" : "=r"(FuncID) : "r"(FuncID)); __asm__ volatile("" : "=r"(FuncID) : "r"(FuncID));
return __syscall_function_cast(Table_B, int32_t (*)(uint32_t))(event); return __syscall_function_cast(Table_B, int32_t (*)(uint32_t))(event);
} }
static __always_inline const uint16_t* Krom2RawAdd(uint16_t sjis_code) { static __always_inline const uint16_t* Krom2RawAdd(uint16_t sjis_code) {
register uint32_t FuncID asm("t1") = 0x51; register uint32_t FuncID asm("t1") = 0x51;
__asm__ volatile("" : "=r"(FuncID) : "r"(FuncID)); __asm__ volatile("" : "=r"(FuncID) : "r"(FuncID));
return __syscall_function_cast(Table_B, const uint16_t* (*)(uint16_t))(sjis_code); return __syscall_function_cast(Table_B, const uint16_t* (*)(uint16_t))(sjis_code);
} }
void printf(const char* txt, ...); void printf(const char* txt, ...);
} }
} }

View File

@ -1,74 +1,74 @@
#ifndef __JABYENGINE_FRAME_TIMER_HPP__ #ifndef __JABYENGINE_FRAME_TIMER_HPP__
#define __JABYENGINE_FRAME_TIMER_HPP__ #define __JABYENGINE_FRAME_TIMER_HPP__
#include "frame_time_helper.hpp" #include "frame_time_helper.hpp"
#include <stdint.hpp> #include <stdint.hpp>
namespace JabyEngine { namespace JabyEngine {
class MasterTime { class MasterTime {
__friends: __friends:
static uint32_t value; static uint32_t value;
public: public:
static uint32_t read() { static uint32_t read() {
return reinterpret_cast<volatile uint32_t&>(MasterTime::value); return reinterpret_cast<volatile uint32_t&>(MasterTime::value);
} }
template<typename T> template<typename T>
static T read_as() { static T read_as() {
return static_cast<T>(MasterTime::read()); return static_cast<T>(MasterTime::read());
} }
}; };
template<typename T> template<typename T>
class SimpleTimer { class SimpleTimer {
protected: protected:
T value = 0; T value = 0;
public: public:
constexpr SimpleTimer() = default; constexpr SimpleTimer() = default;
static SimpleTimer create() { static SimpleTimer create() {
SimpleTimer timer; SimpleTimer timer;
timer.reset(); timer.reset();
return timer; return timer;
} }
bool is_expired_for(T time) const { bool is_expired_for(T time) const {
return static_cast<T>((MasterTime::read_as<T>() - this->value)) >= time; return static_cast<T>((MasterTime::read_as<T>() - this->value)) >= time;
} }
void reset() { void reset() {
this->value = MasterTime::read_as<T>(); this->value = MasterTime::read_as<T>();
} }
}; };
template<typename T> template<typename T>
class IntervalTimer : public SimpleTimer<T> { class IntervalTimer : public SimpleTimer<T> {
private: private:
T interval = 0; T interval = 0;
public: public:
constexpr IntervalTimer() = default; constexpr IntervalTimer() = default;
constexpr IntervalTimer(T interval) : SimpleTimer<T>(), interval(interval) { constexpr IntervalTimer(T interval) : SimpleTimer<T>(), interval(interval) {
} }
static constexpr IntervalTimer create(T interval) { static constexpr IntervalTimer create(T interval) {
IntervalTimer timer; IntervalTimer timer;
static_cast<SimpleTimer<T>&>(timer) = SimpleTimer<T>::create(); static_cast<SimpleTimer<T>&>(timer) = SimpleTimer<T>::create();
timer.interval = interval; timer.interval = interval;
return timer; return timer;
} }
void set_interval(T interval) { void set_interval(T interval) {
this->interval = interval; this->interval = interval;
} }
bool is_expired() const { bool is_expired() const {
return SimpleTimer<T>::is_expired_for(this->interval); return SimpleTimer<T>::is_expired_for(this->interval);
} }
}; };
} }
#endif //!__JABYENGINE_FRAME_TIMER_HPP__ #endif //!__JABYENGINE_FRAME_TIMER_HPP__

View File

@ -1,81 +1,81 @@
#ifndef __JABYENGINE_HIGH_RES_TIMER_HPP__ #ifndef __JABYENGINE_HIGH_RES_TIMER_HPP__
#define __JABYENGINE_HIGH_RES_TIMER_HPP__ #define __JABYENGINE_HIGH_RES_TIMER_HPP__
#include "../jabyengine_defines.hpp" #include "../jabyengine_defines.hpp"
#include <PSX/System/IOPorts/interrupt_io.hpp> #include <PSX/System/IOPorts/interrupt_io.hpp>
#include <PSX/System/IOPorts/timer_io.hpp> #include <PSX/System/IOPorts/timer_io.hpp>
namespace JabyEngine { namespace JabyEngine {
struct CPUTicks { struct CPUTicks {
static constexpr double Frequency_Hz = 33868800.0; static constexpr double Frequency_Hz = 33868800.0;
static constexpr double Frequency_Hz_Div8 = (Frequency_Hz/8.0); static constexpr double Frequency_Hz_Div8 = (Frequency_Hz/8.0);
template<typename T> template<typename T>
static constexpr T ticks_per_ns(double CPU_Frequency_Hz, double time = 1.0) { static constexpr T ticks_per_ns(double CPU_Frequency_Hz, double time = 1.0) {
return static_cast<T>((time/CPU_Frequency_Hz)*1000.0*1000.0*1000.0); return static_cast<T>((time/CPU_Frequency_Hz)*1000.0*1000.0*1000.0);
} }
template<typename T> template<typename T>
static constexpr T ticks_per_us(double CPU_Frequency_Hz, double time = 1.0) { static constexpr T ticks_per_us(double CPU_Frequency_Hz, double time = 1.0) {
return static_cast<T>(((time*1000.0)/ticks_per_ns<double>(CPU_Frequency_Hz))); return static_cast<T>(((time*1000.0)/ticks_per_ns<double>(CPU_Frequency_Hz)));
} }
template<typename T> template<typename T>
static constexpr T ticks_per_ms(double CPU_Frequency_Hz, double time = 1.0) { static constexpr T ticks_per_ms(double CPU_Frequency_Hz, double time = 1.0) {
return static_cast<T>(((time*1000.0*1000.0)/ticks_per_ns<double>(CPU_Frequency_Hz))); return static_cast<T>(((time*1000.0*1000.0)/ticks_per_ns<double>(CPU_Frequency_Hz)));
} }
}; };
class HighResTime { class HighResTime {
public: public:
class TimeStamp { class TimeStamp {
private: private:
uint16_t counter_10ms_value; uint16_t counter_10ms_value;
uint16_t fraction; uint16_t fraction;
constexpr TimeStamp(uint16_t counter_10ms_value, uint16_t fraction) : counter_10ms_value(counter_10ms_value), fraction(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) { constexpr static size_t to_us(uint16_t counter_10ms_value, uint16_t fraction) {
return counter_10ms_value*(10*1000) + ((fraction/HighResTime::TicksFor100us)*100); return counter_10ms_value*(10*1000) + ((fraction/HighResTime::TicksFor100us)*100);
} }
constexpr static size_t to_ms(uint16_t counter_10ms_value, uint16_t fraction) { constexpr static size_t to_ms(uint16_t counter_10ms_value, uint16_t fraction) {
return counter_10ms_value*10 + (fraction/HighResTime::TicksFor1ms); return counter_10ms_value*10 + (fraction/HighResTime::TicksFor1ms);
} }
public: public:
constexpr size_t microseconds_to(const TimeStamp& end) const { 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)); 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 { 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)); return TimeStamp::to_ms((end.counter_10ms_value - this->counter_10ms_value), (end.fraction - this->fraction));
} }
friend class HighResTime; friend class HighResTime;
}; };
__friends: __friends:
static constexpr uint16_t TicksFor100us = CPUTicks::ticks_per_us<uint16_t>(CPUTicks::Frequency_Hz_Div8, 100.0); static constexpr uint16_t TicksFor100us = CPUTicks::ticks_per_us<uint16_t>(CPUTicks::Frequency_Hz_Div8, 100.0);
static constexpr uint16_t TicksFor1ms = CPUTicks::ticks_per_ms<uint16_t>(CPUTicks::Frequency_Hz_Div8, 1.0); static constexpr uint16_t TicksFor1ms = CPUTicks::ticks_per_ms<uint16_t>(CPUTicks::Frequency_Hz_Div8, 1.0);
static constexpr uint16_t TicksFor10ms = CPUTicks::ticks_per_ms<uint16_t>(CPUTicks::Frequency_Hz_Div8, 10.0); static constexpr uint16_t TicksFor10ms = CPUTicks::ticks_per_ms<uint16_t>(CPUTicks::Frequency_Hz_Div8, 10.0);
static volatile uint16_t global_counter_10ms; static volatile uint16_t global_counter_10ms;
public: public:
HighResTime() = delete; HighResTime() = delete;
~HighResTime() = delete; ~HighResTime() = delete;
static void enable() { static void enable() {
Interrupt::enable_irq(Interrupt::Timer2); Interrupt::enable_irq(Interrupt::Timer2);
} }
static void disable() { static void disable() {
Interrupt::disable_irq(Interrupt::Timer2); Interrupt::disable_irq(Interrupt::Timer2);
} }
static TimeStamp get_time_stamp() { static TimeStamp get_time_stamp() {
return TimeStamp(HighResTime::global_counter_10ms, Timer_IO::Counter2.get_current_value()); return TimeStamp(HighResTime::global_counter_10ms, Timer_IO::Counter2.get_current_value());
} }
}; };
} }
#endif //!__JABYENGINE_HIGH_RES_TIMER_HPP__ #endif //!__JABYENGINE_HIGH_RES_TIMER_HPP__

View File

@ -1,37 +1,37 @@
#pragma once #pragma once
#include <PSX/GPU/gpu_types.hpp> #include <PSX/GPU/gpu_types.hpp>
namespace JabyEngine { namespace JabyEngine {
struct DefaultConfiguration { struct DefaultConfiguration {
struct BIOSFont { struct BIOSFont {
static constexpr GPU::PositionU16 texture_load_pos() { static constexpr GPU::PositionU16 texture_load_pos() {
return GPU::PositionU16::create(320, 256); return GPU::PositionU16::create(320, 256);
} }
static constexpr GPU::PositionU16 CLUT_load_pos() { static constexpr GPU::PositionU16 CLUT_load_pos() {
return GPU::PositionU16::create(320, 511); return GPU::PositionU16::create(320, 511);
} }
}; };
static constexpr auto DisplayDefaultOffset = GPU::PositionI16::create(0, 0); static constexpr auto DisplayDefaultOffset = GPU::PositionI16::create(0, 0);
struct Periphery { struct Periphery {
static constexpr bool include_portB() { static constexpr bool include_portB() {
return false; return false;
} }
static constexpr bool use_multi_tap(){ static constexpr bool use_multi_tap(){
return false; return false;
} }
}; };
}; };
#if __has_include(<jabyengine_custom_config.hpp>) #if __has_include(<jabyengine_custom_config.hpp>)
#include <jabyengine_custom_config.hpp> #include <jabyengine_custom_config.hpp>
using Configuration = CustomConfiguration; using Configuration = CustomConfiguration;
#else #else
using Configuration = DefaultConfiguration; using Configuration = DefaultConfiguration;
#define __SUPPORT_PS3__ #define __SUPPORT_PS3__
#define __DEBUG_SPU_MMU__ #define __DEBUG_SPU_MMU__
#endif // has jabyengine_custom_config #endif // has jabyengine_custom_config
} }

View File

@ -1,16 +1,16 @@
#pragma once #pragma once
#include "Auxiliary/literals.hpp" #include "Auxiliary/literals.hpp"
#include <stddef.hpp> #include <stddef.hpp>
#define __used __attribute__((used)) #define __used __attribute__((used))
#define __no_align __attribute__((packed)) #define __no_align __attribute__((packed))
#define __no_inline __attribute__((noinline)) #define __no_inline __attribute__((noinline))
#define __no_return __attribute__((noreturn)) #define __no_return __attribute__((noreturn))
#define __always_inline __attribute__((always_inline)) #define __always_inline __attribute__((always_inline))
#define __weak __attribute__((weak)) #define __weak __attribute__((weak))
#define __section(name) __attribute__((section(name))) #define __section(name) __attribute__((section(name)))
#define __collect(...) __VA_ARGS__ #define __collect(...) __VA_ARGS__
#ifndef __friends #ifndef __friends
#define __friends private #define __friends private
#endif //!__friends #endif //!__friends

View File

@ -1,78 +1,78 @@
#pragma once #pragma once
#include "stdint.hpp" #include "stdint.hpp"
namespace math { namespace math {
template<typename T> template<typename T>
struct raw_math { struct raw_math {
constexpr T operator-() const { constexpr T operator-() const {
return T{.raw = static_cast<decltype(T::raw)>(-(static_cast<const T&>(*this).raw))}; return T{.raw = static_cast<decltype(T::raw)>(-(static_cast<const T&>(*this).raw))};
} }
constexpr T operator+(const T& obj) const { constexpr T operator+(const T& obj) const {
return T{.raw = static_cast<const T&>(*this).raw + obj.raw}; return T{.raw = static_cast<const T&>(*this).raw + obj.raw};
} }
constexpr T operator-(const T& b) const {} constexpr T operator-(const T& b) const {}
constexpr T& operator+=(const T& obj) { constexpr T& operator+=(const T& obj) {
static_cast<T&>(*this).raw += obj.raw; static_cast<T&>(*this).raw += obj.raw;
return static_cast<T&>(*this); return static_cast<T&>(*this);
} }
constexpr T& operator-=(const T& obj) { constexpr T& operator-=(const T& obj) {
static_cast<T&>(*this).raw -= obj.raw; static_cast<T&>(*this).raw -= obj.raw;
return static_cast<T&>(*this); return static_cast<T&>(*this);
} }
}; };
} }
struct deg_t : public math::raw_math<deg_t> { struct deg_t : public math::raw_math<deg_t> {
static constexpr auto full_circle = 32768; static constexpr auto full_circle = 32768;
static constexpr auto one_degree = full_circle/360; static constexpr auto one_degree = full_circle/360;
static constexpr auto one_tenth_degree = full_circle/3600; static constexpr auto one_tenth_degree = full_circle/3600;
int16_t raw; int16_t raw;
static constexpr deg_t zero() { static constexpr deg_t zero() {
return deg_t{.raw = 0}; return deg_t{.raw = 0};
} }
static constexpr deg_t from_degree(int32_t deg) { static constexpr deg_t from_degree(int32_t deg) {
return deg_t{.raw = static_cast<int16_t>(deg*one_degree)}; return deg_t{.raw = static_cast<int16_t>(deg*one_degree)};
} }
static constexpr deg_t from_tenth_degree(int32_t deg10) { static constexpr deg_t from_tenth_degree(int32_t deg10) {
return deg_t{.raw = static_cast<int16_t>(deg10*one_tenth_degree)}; return deg_t{.raw = static_cast<int16_t>(deg10*one_tenth_degree)};
} }
}; };
static constexpr deg_t operator""_deg(long double degree) { static constexpr deg_t operator""_deg(long double degree) {
return deg_t::from_tenth_degree((degree*10.0)); return deg_t::from_tenth_degree((degree*10.0));
} }
struct gte_float : public math::raw_math<gte_float> { struct gte_float : public math::raw_math<gte_float> {
int32_t raw; int32_t raw;
static constexpr gte_float from_double(double value) { static constexpr gte_float from_double(double value) {
return gte_float{.raw = static_cast<int32_t>(4096.0*value)}; return gte_float{.raw = static_cast<int32_t>(4096.0*value)};
} }
static constexpr gte_float one() { static constexpr gte_float one() {
return gte_float::from_double(1.0); return gte_float::from_double(1.0);
} }
constexpr explicit operator int32_t() const { constexpr explicit operator int32_t() const {
return this->raw; return this->raw;
} }
constexpr explicit operator int16_t() const { constexpr explicit operator int16_t() const {
return static_cast<int16_t>(this->raw); return static_cast<int16_t>(this->raw);
} }
}; };
static constexpr gte_float operator""_gf(long double value) { static constexpr gte_float operator""_gf(long double value) {
return gte_float::from_double(value); return gte_float::from_double(value);
} }
gte_float sin(deg_t value); gte_float sin(deg_t value);
gte_float cos(deg_t value); gte_float cos(deg_t value);

View File

@ -1,7 +1,7 @@
#pragma once #pragma once
using va_list = __builtin_va_list; using va_list = __builtin_va_list;
#define va_start __builtin_va_start #define va_start __builtin_va_start
#define va_end __builtin_va_end #define va_end __builtin_va_end
#define next_arg __builtin_next_arg #define next_arg __builtin_next_arg
#define va_arg __builtin_va_arg #define va_arg __builtin_va_arg

View File

@ -1,4 +1,4 @@
#pragma once #pragma once
#include "PSX/jabyengine_defines.hpp" #include "PSX/jabyengine_defines.hpp"
int printf(const char* txt, ...) asm("_ZN10JabyEngine7SysCall6printfEPKcz"); int printf(const char* txt, ...) asm("_ZN10JabyEngine7SysCall6printfEPKcz");

View File

@ -1,10 +1,10 @@
#pragma once #pragma once
#include "PSX/jabyengine_defines.hpp" #include "PSX/jabyengine_defines.hpp"
int strncmp(const char* s1, const char* s2, size_t n); int strncmp(const char* s1, const char* s2, size_t n);
size_t strlen(const char* str); size_t strlen(const char* str);
extern "C" { extern "C" {
// Needs to be provided for GCC optimizations // Needs to be provided for GCC optimizations
void* memset(void* dest, int val, size_t len); void* memset(void* dest, int val, size_t len);
} }

40
license
View File

@ -1,21 +1,21 @@
MIT License MIT License
Copyright (c) 2025 Jaby Copyright (c) 2025 Jaby
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions: furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. SOFTWARE.

View File

@ -1,23 +1,23 @@
CD_OUTPUT ?= $(REGION)/$(ARTIFACT).bin CD_OUTPUT ?= $(REGION)/$(ARTIFACT).bin
PKG_OUTPUT ?= $(REGION)/$(ARTIFACT).pkg PKG_OUTPUT ?= $(REGION)/$(ARTIFACT).pkg
$(CD_OUTPUT): always $(CD_OUTPUT): always
@mkdir -p $(REGION) @mkdir -p $(REGION)
psxcdgen_ex --list $(REGION)/$(ARTIFACT).lba -o $(REGION)/$(ARTIFACT) bin-cue Config.xml psxcdgen_ex --list $(REGION)/$(ARTIFACT).lba -o $(REGION)/$(ARTIFACT) bin-cue Config.xml
$(PKG_OUTPUT): always $(PKG_OUTPUT): always
@mkdir -p $(REGION) @mkdir -p $(REGION)
@echo "!!PKG generation is experimentel!!" @echo "!!PKG generation is experimentel!!"
run_pop_fe.sh $(ARTIFACT) $(shell pwd)/../assets/pkg $(shell pwd)/$(REGION)/$(ARTIFACT).cue run_pop_fe.sh $(ARTIFACT) $(shell pwd)/../assets/pkg $(shell pwd)/$(REGION)/$(ARTIFACT).cue
all: $(CD_OUTPUT) all: $(CD_OUTPUT)
clean: pkg_clean clean: pkg_clean
rm -fr $(REGION)/*.bin rm -fr $(REGION)/*.bin
rm -fr $(REGION)/*.cue rm -fr $(REGION)/*.cue
rm -fr $(REGION)/*.lba rm -fr $(REGION)/*.lba
pkg_all: $(PKG_OUTPUT) pkg_all: $(PKG_OUTPUT)
pkg_clean: pkg_clean:
rm -fr $(REGION)/*.pkg rm -fr $(REGION)/*.pkg
always: ; always: ;

View File

@ -1,98 +1,98 @@
SELF_DIR := $(dir $(lastword $(MAKEFILE_LIST))) SELF_DIR := $(dir $(lastword $(MAKEFILE_LIST)))
include $(SELF_DIR)common/ExportPath.mk include $(SELF_DIR)common/ExportPath.mk
substitute = $(subst $(JABY_ENGINE_DIR)/include/modules,!JABYENGINEMODULES,$(subst ..,!super,$1)) substitute = $(subst $(JABY_ENGINE_DIR)/include/modules,!JABYENGINEMODULES,$(subst ..,!super,$1))
desubstitute = $(subst !JABYENGINEMODULES,$(JABY_ENGINE_DIR)/include/modules,$(subst !super,..,$1)) desubstitute = $(subst !JABYENGINEMODULES,$(JABY_ENGINE_DIR)/include/modules,$(subst !super,..,$1))
#Build architecture/variant string, possible values: x86, armv7le, etc... #Build architecture/variant string, possible values: x86, armv7le, etc...
PLATFORM ?= PSX PLATFORM ?= PSX
#Build profile, possible values: release, debug, profile, coverage #Build profile, possible values: release, debug, profile, coverage
BUILD_DIR ?= bin/$(PSX_TV_FORMAT) BUILD_DIR ?= bin/$(PSX_TV_FORMAT)
BUILD_PROFILE ?= debug BUILD_PROFILE ?= debug
PSX_TV_FORMAT ?= PAL PSX_TV_FORMAT ?= PAL
CONFIG_NAME ?= $(PLATFORM)-$(BUILD_PROFILE) CONFIG_NAME ?= $(PLATFORM)-$(BUILD_PROFILE)
OUTPUT_DIR = $(BUILD_DIR)/$(CONFIG_NAME) OUTPUT_DIR = $(BUILD_DIR)/$(CONFIG_NAME)
TARGET = $(OUTPUT_DIR)/$(ARTIFACT) TARGET = $(OUTPUT_DIR)/$(ARTIFACT)
#Compiler definitions #Compiler definitions
HAS_LINUX_MIPS_GCC = $(shell which mipsel-linux-gnu-gcc > /dev/null 2> /dev/null && echo true || echo false) HAS_LINUX_MIPS_GCC = $(shell which mipsel-linux-gnu-gcc > /dev/null 2> /dev/null && echo true || echo false)
ifeq ($(HAS_LINUX_MIPS_GCC),true) ifeq ($(HAS_LINUX_MIPS_GCC),true)
PREFIX ?= mipsel-linux-gnu PREFIX ?= mipsel-linux-gnu
FORMAT ?= elf32-tradlittlemips FORMAT ?= elf32-tradlittlemips
else else
PREFIX ?= mipsel-none-elf PREFIX ?= mipsel-none-elf
FORMAT ?= elf32-littlemips FORMAT ?= elf32-littlemips
endif endif
#Take this to PSEXETarget.mk?? #Take this to PSEXETarget.mk??
#LDSCRIPT ?= $(PSCX_REDUX_DIR)/ps-exe.ld #LDSCRIPT ?= $(PSCX_REDUX_DIR)/ps-exe.ld
#ifneq ($(strip $(OVERLAYSCRIPT)),) #ifneq ($(strip $(OVERLAYSCRIPT)),)
#LDSCRIPT := $(addprefix $(OVERLAYSCRIPT) , -T$(LDSCRIPT)) #LDSCRIPT := $(addprefix $(OVERLAYSCRIPT) , -T$(LDSCRIPT))
#else #else
#LDSCRIPT := $(addprefix $(PSCX_REDUX_DIR)/default.ld , -T$(LDSCRIPT)) #LDSCRIPT := $(addprefix $(PSCX_REDUX_DIR)/default.ld , -T$(LDSCRIPT))
#endif #endif
CC = $(PREFIX)-gcc CC = $(PREFIX)-gcc
CXX = $(PREFIX)-g++ CXX = $(PREFIX)-g++
LD = $(CXX) LD = $(CXX)
AR = ar AR = ar
#architecture flags #architecture flags
ARCHFLAGS = -march=r2000 -mtune=r2000 -mabi=32 -EL -fno-pic -mno-shared -nostdinc -nostdinc++ -mno-abicalls -mfp32 -mno-llsc 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 ARCHFLAGS += -fno-stack-protector -nostdlib -ffreestanding
#Compiler flags for build profiles #Compiler flags for build profiles
CCFLAGS_release += -O3 CCFLAGS_release += -O3
CCFLAGS_debug += -O0 CCFLAGS_debug += -O0
CXXFLAGS += -fno-exceptions -fno-rtti -fno-threadsafe-statics CXXFLAGS += -fno-exceptions -fno-rtti -fno-threadsafe-statics
CCFLAGS += -mno-gpopt -fomit-frame-pointer -ffunction-sections -fdata-sections CCFLAGS += -mno-gpopt -fomit-frame-pointer -ffunction-sections -fdata-sections
CCFLAGS += -fno-builtin -fno-strict-aliasing -Wno-attributes CCFLAGS += -fno-builtin -fno-strict-aliasing -Wno-attributes
CCFLAGS += -std=c++20 -fmodules-ts CCFLAGS += -std=c++20 -fmodules-ts
CCFLAGS += $(CCFLAGS_$(BUILD_PROFILE)) CCFLAGS += $(CCFLAGS_$(BUILD_PROFILE))
CCFLAGS += $(ARCHFLAGS) CCFLAGS += $(ARCHFLAGS)
CCFLAGS += $(INCLUDES) CCFLAGS += $(INCLUDES)
CCFLAGS += -DJABYENGINE_$(PSX_TV_FORMAT) CCFLAGS += -DJABYENGINE_$(PSX_TV_FORMAT)
#Linker flags #Linker flags
LDFLAGS_release += -Os LDFLAGS_release += -Os
LDFLAGS_all += -Wl,-Map=$(TARGET).map -nostdlib -T$(JABY_ENGINE_DIR)/mkfile/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)/mkfile/psexe.ld -static -Wl,--gc-sections -Wl,--build-id=none -Wl,--no-check-sections
LDFLAGS_all += $(ARCHFLAGS) -Wl,--oformat=$(FORMAT) LDFLAGS_all += $(ARCHFLAGS) -Wl,--oformat=$(FORMAT)
LDFLAGS_all += $(LDFLAGS_$(BUILD_PROFILE)) LDFLAGS_all += $(LDFLAGS_$(BUILD_PROFILE))
LIBS_all += $(LIBS_$(BUILD_PROFILE)) LIBS_all += $(LIBS_$(BUILD_PROFILE))
DEPS = -Wp,-MMD,$(@:%.o=%.d),-MT,$@ DEPS = -Wp,-MMD,$(@:%.o=%.d),-MT,$@
#Object files list #Object files list
MODS += $(call rwildcard,$(JABY_ENGINE_DIR)/include/modules, cxx) MODS += $(call rwildcard,$(JABY_ENGINE_DIR)/include/modules, cxx)
SRCS := $(MODS) $(SRCS) SRCS := $(MODS) $(SRCS)
OBJS = $(addprefix $(OUTPUT_DIR)/,$(addsuffix .o, $(call substitute,$(basename $(SRCS))))) OBJS = $(addprefix $(OUTPUT_DIR)/,$(addsuffix .o, $(call substitute,$(basename $(SRCS)))))
#Compiling rule #Compiling rule
.SECONDEXPANSION: .SECONDEXPANSION:
$(OUTPUT_DIR)/%.o: $$(call desubstitute,%.s) $(OUTPUT_DIR)/%.o: $$(call desubstitute,%.s)
@mkdir -p $(dir $@) @mkdir -p $(dir $@)
$(CC) -c $(DEPS) -o $@ $(CCFLAGS) $< $(CC) -c $(DEPS) -o $@ $(CCFLAGS) $<
.SECONDEXPANSION: .SECONDEXPANSION:
$(OUTPUT_DIR)/%.o: $$(call desubstitute,%.c) $(OUTPUT_DIR)/%.o: $$(call desubstitute,%.c)
@mkdir -p $(dir $@) @mkdir -p $(dir $@)
$(CC) -c $(DEPS) -o $@ $(CCFLAGS) $< $(CC) -c $(DEPS) -o $@ $(CCFLAGS) $<
.SECONDEXPANSION: .SECONDEXPANSION:
$(OUTPUT_DIR)/%.o: $$(call desubstitute,%.cpp) $(OUTPUT_DIR)/%.o: $$(call desubstitute,%.cpp)
@mkdir -p $(dir $@) @mkdir -p $(dir $@)
$(CXX) -c $(DEPS) -o $@ $(CCFLAGS) $(CXXFLAGS) $< $(CXX) -c $(DEPS) -o $@ $(CCFLAGS) $(CXXFLAGS) $<
.SECONDEXPANSION: .SECONDEXPANSION:
$(OUTPUT_DIR)/%.o: $$(call desubstitute,%.cxx) $(OUTPUT_DIR)/%.o: $$(call desubstitute,%.cxx)
@mkdir -p $(dir $@) @mkdir -p $(dir $@)
$(CXX) -c $(DEPS) -o $@ $(CCFLAGS) $(CXXFLAGS) $< $(CXX) -c $(DEPS) -o $@ $(CCFLAGS) $(CXXFLAGS) $<
#Inclusion of dependencies (object files to source and includes) #Inclusion of dependencies (object files to source and includes)
-include $(OBJS:%.o=%.d) -include $(OBJS:%.o=%.d)

View File

@ -1,40 +1,40 @@
#Not intended to be overriden #Not intended to be overriden
AUTO_OVERLAY_DIR = $(OUTPUT_DIR)/auto_overlay AUTO_OVERLAY_DIR = $(OUTPUT_DIR)/auto_overlay
include $(AUTO_OVERLAY_DIR)/Overlays.mk include $(AUTO_OVERLAY_DIR)/Overlays.mk
include $(JABY_ENGINE_DIR)/mkfile/common/CustomConfigHelper.mk include $(JABY_ENGINE_DIR)/mkfile/common/CustomConfigHelper.mk
JABY_ENGINE_LIB_DIR = $(JABY_ENGINE_DIR)/lib/PSX-$(BUILD_PROFILE)/$(CUSTOM_CONFIG) JABY_ENGINE_LIB_DIR = $(JABY_ENGINE_DIR)/lib/PSX-$(BUILD_PROFILE)/$(CUSTOM_CONFIG)
JABY_ENGINE_SUPPORT_LIB_DIR = $(JABY_ENGINE_DIR)/support/lib/PSX-$(BUILD_PROFILE) JABY_ENGINE_SUPPORT_LIB_DIR = $(JABY_ENGINE_DIR)/support/lib/PSX-$(BUILD_PROFILE)
JABY_ENGINE_SUPPORT_LIBS = $(addprefix -l,$(SUPPORT_LIBS)) JABY_ENGINE_SUPPORT_LIBS = $(addprefix -l,$(SUPPORT_LIBS))
JABY_ENGINE_SUPPORT_DEPS = $(addsuffix .a,$(addprefix $(JABY_ENGINE_SUPPORT_LIB_DIR)/lib,$(SUPPORT_LIBS))) JABY_ENGINE_SUPPORT_DEPS = $(addsuffix .a,$(addprefix $(JABY_ENGINE_SUPPORT_LIB_DIR)/lib,$(SUPPORT_LIBS)))
JABY_ENGINE_LIB_NAME = JabyEngine_$(PSX_TV_FORMAT) JABY_ENGINE_LIB_NAME = JabyEngine_$(PSX_TV_FORMAT)
OVERLAY_TARGET = $(foreach ovl, $(OVERLAYSECTION), $(OUTPUT_DIR)/Overlay$(ovl)) OVERLAY_TARGET = $(foreach ovl, $(OVERLAYSECTION), $(OUTPUT_DIR)/Overlay$(ovl))
#Linking rule #Linking rule
$(TARGET).elf: $(OBJS) $(JABY_ENGINE_LIB_DIR)/lib$(JABY_ENGINE_LIB_NAME).a $(JABY_ENGINE_SUPPORT_DEPS) $(AUTO_OVERLAY_DIR)/Overlays.ld $(TARGET).elf: $(OBJS) $(JABY_ENGINE_LIB_DIR)/lib$(JABY_ENGINE_LIB_NAME).a $(JABY_ENGINE_SUPPORT_DEPS) $(AUTO_OVERLAY_DIR)/Overlays.ld
$(LD) -o $(TARGET).elf $(LDFLAGS_all) $(LDFLAGS) $(OBJS) -L$(JABY_ENGINE_LIB_DIR) -L$(JABY_ENGINE_SUPPORT_LIB_DIR) -L$(AUTO_OVERLAY_DIR) -l$(JABY_ENGINE_LIB_NAME) $(LIBS) $(JABY_ENGINE_SUPPORT_LIBS) $(LD) -o $(TARGET).elf $(LDFLAGS_all) $(LDFLAGS) $(OBJS) -L$(JABY_ENGINE_LIB_DIR) -L$(JABY_ENGINE_SUPPORT_LIB_DIR) -L$(AUTO_OVERLAY_DIR) -l$(JABY_ENGINE_LIB_NAME) $(LIBS) $(JABY_ENGINE_SUPPORT_LIBS)
#Strips the psexe #Strips the psexe
$(TARGET).psexe: $(TARGET).elf $(TARGET).psexe: $(TARGET).elf
$(PREFIX)-objcopy $(addprefix -R , $(OVERLAYSECTION)) -O binary $< $@ $(PREFIX)-objcopy $(addprefix -R , $(OVERLAYSECTION)) -O binary $< $@
#Create overlays #Create overlays
$(OVERLAY_TARGET): $(TARGET).elf $(OVERLAY_TARGET): $(TARGET).elf
$(PREFIX)-objcopy -j $(suffix $@) -O binary $< $@ $(PREFIX)-objcopy -j $(suffix $@) -O binary $< $@
#Create overlay makefile #Create overlay makefile
$(AUTO_OVERLAY_DIR)/Overlays.mk: $(OVERLAY_CONFIG) $(AUTO_OVERLAY_DIR)/Overlays.mk: $(OVERLAY_CONFIG)
@mkdir -p $(AUTO_OVERLAY_DIR) @mkdir -p $(AUTO_OVERLAY_DIR)
mkoverlay --mk-file $(AUTO_OVERLAY_DIR)/Overlays.mk --ld-script $(AUTO_OVERLAY_DIR)/Overlays.ld $< mkoverlay --mk-file $(AUTO_OVERLAY_DIR)/Overlays.mk --ld-script $(AUTO_OVERLAY_DIR)/Overlays.ld $<
#Rules section for default compilation and linking #Rules section for default compilation and linking
all: $(TARGET).psexe $(OVERLAY_TARGET) all: $(TARGET).psexe $(OVERLAY_TARGET)
clean: clean:
rm -fr $(OUTPUT_DIR) rm -fr $(OUTPUT_DIR)
# For mkoverlay to function correctly this is required (otherwise Overlays.mk is not re-generated) # For mkoverlay to function correctly this is required (otherwise Overlays.mk is not re-generated)
rebuild: clean rebuild: clean
$(MAKE) all $(MAKE) all

View File

@ -1,4 +1,4 @@
JABY_ENGINE_CONFIG_DIR = $(JABY_ENGINE_DIR)config JABY_ENGINE_CONFIG_DIR = $(JABY_ENGINE_DIR)config
ifdef CUSTOM_CONFIG ifdef CUSTOM_CONFIG
CCFLAGS += -I$(JABY_ENGINE_CONFIG_DIR)/$(CUSTOM_CONFIG) -imacros $(JABY_ENGINE_CONFIG_DIR)/$(CUSTOM_CONFIG)/jabyengine_custom_config.hpp CCFLAGS += -I$(JABY_ENGINE_CONFIG_DIR)/$(CUSTOM_CONFIG) -imacros $(JABY_ENGINE_CONFIG_DIR)/$(CUSTOM_CONFIG)/jabyengine_custom_config.hpp
endif endif

View File

@ -1,2 +1,2 @@
#Add the JabyEngine tools to path #Add the JabyEngine tools to path
export PATH := $(JABY_ENGINE_DIR)/bin/:$(PATH) export PATH := $(JABY_ENGINE_DIR)/bin/:$(PATH)

View File

@ -1,3 +1,3 @@
rebuild: rebuild:
$(MAKE) clean $(MAKE) clean
$(MAKE) all $(MAKE) all

View File

@ -1,2 +1,2 @@
#Macro to expand files recursively: parameters $1 - directory, $2 - extension, i.e. cpp #Macro to expand files recursively: parameters $1 - directory, $2 - extension, i.e. cpp
rwildcard = $(wildcard $(addprefix $1/*.,$2)) $(foreach d,$(wildcard $1/*),$(call rwildcard,$d,$2)) rwildcard = $(wildcard $(addprefix $1/*.,$2)) $(foreach d,$(wildcard $1/*),$(call rwildcard,$d,$2))

View File

@ -1,262 +1,262 @@
/* /*
MIT License MIT License
Copyright (c) 2019 PCSX-Redux authors Copyright (c) 2019 PCSX-Redux authors
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions: furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. SOFTWARE.
*/ */
OUTPUT_FORMAT("binary") OUTPUT_FORMAT("binary")
EXTERN(_ZN10JabyEngine5startEv) EXTERN(_ZN10JabyEngine5startEv)
ENTRY(_ZN10JabyEngine5startEv) ENTRY(_ZN10JabyEngine5startEv)
TLOAD_ADDR = DEFINED(TLOAD_ADDR) ? TLOAD_ADDR : 0x80010000; TLOAD_ADDR = DEFINED(TLOAD_ADDR) ? TLOAD_ADDR : 0x80010000;
MEMORY { MEMORY {
zero : ORIGIN = 0x0 LENGTH = 0x100 zero : ORIGIN = 0x0 LENGTH = 0x100
bios : ORIGIN = 0x100, LENGTH = 0x500 bios : ORIGIN = 0x100, LENGTH = 0x500
loader : ORIGIN = (TLOAD_ADDR - 0x800), LENGTH = 2048 loader : ORIGIN = (TLOAD_ADDR - 0x800), LENGTH = 2048
ram(rwx) : ORIGIN = 0x80010000, LENGTH = 2M - 0x10000 ram(rwx) : ORIGIN = 0x80010000, LENGTH = 2M - 0x10000
ram_alt(rwx) : ORIGIN = 0x80010000, LENGTH = 2M - 0x10000 ram_alt(rwx) : ORIGIN = 0x80010000, LENGTH = 2M - 0x10000
dcache : ORIGIN = 0x1f800000, LENGTH = 0x400 dcache : ORIGIN = 0x1f800000, LENGTH = 0x400
} }
__ram_top = ORIGIN(ram) + LENGTH(ram); __ram_top = ORIGIN(ram) + LENGTH(ram);
__sp = __ram_top - 0x100; __sp = __ram_top - 0x100;
__dcache = ORIGIN(dcache); __dcache = ORIGIN(dcache);
__dcache_top = ORIGIN(dcache) + LENGTH(dcache); __dcache_top = ORIGIN(dcache) + LENGTH(dcache);
__bss_len = (__bss_end - __bss_start); __bss_len = (__bss_end - __bss_start);
__ftext_len = (__ftext_end - __ftext_start); __ftext_len = (__ftext_end - __ftext_start);
__fdata_len = (__planschi_end - __fdata_start); __fdata_len = (__planschi_end - __fdata_start);
__persistent_lbas_len = (__persistent_lbas_end - __persistent_lbas_start); __persistent_lbas_len = (__persistent_lbas_end - __persistent_lbas_start);
__stack_start = ORIGIN(ram) + LENGTH(ram); __stack_start = ORIGIN(ram) + LENGTH(ram);
SECTIONS { SECTIONS {
.zero (NOLOAD) : { .zero (NOLOAD) : {
_ZN10JabyEngine3SPU5voiceE = .; _ZN10JabyEngine3SPU5voiceE = .;
} > zero } > zero
.bios (NOLOAD) : { .bios (NOLOAD) : {
_ZN10JabyEngine15table_of_tablesE = .; _ZN10JabyEngine15table_of_tablesE = .;
} > bios } > bios
/DISCARD/ : { *(.MIPS.abiflags) } /DISCARD/ : { *(.MIPS.abiflags) }
/* Everything is statically linked, so discard PLTs. */ /* Everything is statically linked, so discard PLTs. */
/DISCARD/ : { *(.rel.iplt) *(.rela.iplt) *(.rel.plt) *(.rela.plt) *(.plt) *(.iplt) } /DISCARD/ : { *(.rel.iplt) *(.rela.iplt) *(.rel.plt) *(.rela.plt) *(.plt) *(.iplt) }
/* Discard things that the standard link script drops, too. */ /* Discard things that the standard link script drops, too. */
/DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) *(.gnu.*) *(.comment) } /DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) *(.gnu.*) *(.comment) }
} }
/*Overlay sections created by mkoverlay*/ /*Overlay sections created by mkoverlay*/
INCLUDE Overlays.ld INCLUDE Overlays.ld
SECTIONS { SECTIONS {
.planschi __engine_bss_end : SUBALIGN(4) .planschi __engine_bss_end : SUBALIGN(4)
{ {
__planschi_start = .; __planschi_start = .;
__boot_loader_start = .; __boot_loader_start = .;
*libJabyEngine_*.a:*_boot.o(.text.startup._GLOBAL__*) *libJabyEngine_*.a:*_boot.o(.text.startup._GLOBAL__*)
*_boot.o(.text.startup._GLOBAL__*) *_boot.o(.text.startup._GLOBAL__*)
*libJabyEngine_*.a:*_boot.o(.ctors) *libJabyEngine_*.a:*_boot.o(.ctors)
*_boot.o(.ctors) *_boot.o(.ctors)
*libJabyEngine_*.a:*_boot.o(.text.*) *libJabyEngine_*.a:*_boot.o(.text.*)
*_boot.o(.text.*) *_boot.o(.text.*)
*libJabyEngine_*.a:*_boot.o(.rodata*) *libJabyEngine_*.a:*_boot.o(.rodata*)
*_boot.o(.rodata*) *_boot.o(.rodata*)
*libJabyEngine_*.a:*_boot.o(.sdata*) *libJabyEngine_*.a:*_boot.o(.sdata*)
*_boot.o(.sdata*) *_boot.o(.sdata*)
*libJabyEngine_*.a:*_boot.o(.data*) *libJabyEngine_*.a:*_boot.o(.data*)
*_boot.o(.data*) *_boot.o(.data*)
*libJabyEngine_*.a:*_boot.o(.sbss*) *libJabyEngine_*.a:*_boot.o(.sbss*)
*_boot.o(.sbss*) *_boot.o(.sbss*)
*libJabyEngine_*.a:*_boot.o(.bss*) *libJabyEngine_*.a:*_boot.o(.bss*)
*_boot.o(.bss*) *_boot.o(.bss*)
*libJabyEngine_*.a:*_boot.o(*) *libJabyEngine_*.a:*_boot.o(*)
*_boot.o(*) *_boot.o(*)
. = ALIGN(4); . = ALIGN(4);
__boot_loader_end = .; __boot_loader_end = .;
/*Only needed for the PSX BIOS to load the entire game*/ /*Only needed for the PSX BIOS to load the entire game*/
. = ALIGN(2048); . = ALIGN(2048);
__planschi_end = .; __planschi_end = .;
} > ram } > ram
} }
SECTIONS { SECTIONS {
.PSX_EXE_Header : { .PSX_EXE_Header : {
/* /*
0x0000 - 0x0007 : "PS-X EXE" 0x0000 - 0x0007 : "PS-X EXE"
*/ */
BYTE(80); BYTE(83); BYTE(45); BYTE(88); BYTE(32); BYTE(69); BYTE(88); BYTE(69); BYTE(80); BYTE(83); BYTE(45); BYTE(88); BYTE(32); BYTE(69); BYTE(88); BYTE(69);
/* 0x0008 - 0x000F : skip text_off and data_off since they're not supported by the PS1 BIOS */ /* 0x0008 - 0x000F : skip text_off and data_off since they're not supported by the PS1 BIOS */
LONG(0); LONG(0); LONG(0); LONG(0);
/* 0x0010 - 0x0013 : entry point */ /* 0x0010 - 0x0013 : entry point */
LONG(ABSOLUTE(_ZN10JabyEngine5startEv)); LONG(ABSOLUTE(_ZN10JabyEngine5startEv));
/* 0x0014 - 0x0017 : initial value of $gp */ /* 0x0014 - 0x0017 : initial value of $gp */
LONG(0); LONG(0);
/* 0x0018 - 0x001B : Memory address to load "text" section to. */ /* 0x0018 - 0x001B : Memory address to load "text" section to. */
/* /*
NOTE: The "text" section is actually all of the "load" NOTE: The "text" section is actually all of the "load"
sections of the file including .text, .rodata, .data. sections of the file including .text, .rodata, .data.
etc. etc.
*/ */
LONG(TLOAD_ADDR); LONG(TLOAD_ADDR);
/* 0x001C - 0x001F : size, in bytes, of the "text" section. */ /* 0x001C - 0x001F : size, in bytes, of the "text" section. */
LONG(__persistent_lbas_len + __ftext_len + __fdata_len); LONG(__persistent_lbas_len + __ftext_len + __fdata_len);
/* 0x0020 - 0x002F : /* 0x0020 - 0x002F :
Skip "data_addr", "data_size", "bss_addr" and "bss_size". Skip "data_addr", "data_size", "bss_addr" and "bss_size".
None of these are supported by retail PS1 BIOS. None of these are supported by retail PS1 BIOS.
*/ */
LONG(0); LONG(0); LONG(0); LONG(0);
LONG(0); LONG(0); LONG(0); LONG(0);
/* 0x0030 - 0x0033 : Initial stack address. */ /* 0x0030 - 0x0033 : Initial stack address. */
LONG(DEFINED(_sp) ? ABSOLUTE(_sp) : 0x801FFF00); LONG(DEFINED(_sp) ? ABSOLUTE(_sp) : 0x801FFF00);
/* 0x0034 - 0x0037 : Initial stack size, set it to 0. */ /* 0x0034 - 0x0037 : Initial stack size, set it to 0. */
LONG(0); LONG(0);
/* Skip the remaining fields as they're not supported by the BIOS */ /* Skip the remaining fields as they're not supported by the BIOS */
/* e.g. 2048 header bytes minus whatever we've actually used */ /* e.g. 2048 header bytes minus whatever we've actually used */
. = . + 1992; . = . + 1992;
} > loader } > loader
.persistent_lbas TLOAD_ADDR : { .persistent_lbas TLOAD_ADDR : {
__persistent_lbas_start = .; __persistent_lbas_start = .;
__persistent_lbas = .; __persistent_lbas = .;
KEEP(*(.header.lbas)) KEEP(*(.header.lbas))
. = ALIGN(4); . = ALIGN(4);
__persistent_lbas_end = .; __persistent_lbas_end = .;
} > ram } > ram
__ftext_start = ABSOLUTE(.); __ftext_start = ABSOLUTE(.);
.text : { .text : {
__text_start = .; __text_start = .;
*(.start) *(.start)
*(.init) *(.init)
KEEP (*(SORT_NONE(.fini))) KEEP (*(SORT_NONE(.fini)))
*(.text.unlikely .text.*_unlikely .text.unlikely.*) *(.text.unlikely .text.*_unlikely .text.unlikely.*)
*(.text.exit .text.exit.*) *(.text.exit .text.exit.*)
*(.text.startup .text.startup.*) *(.text.startup .text.startup.*)
*(.text.hot .text.hot.*) *(.text.hot .text.hot.*)
*(.text .stub .text.* .gnu.linkonce.t.*) *(.text .stub .text.* .gnu.linkonce.t.*)
. = ALIGN(16); . = ALIGN(16);
KEEP(*(.init)) KEEP(*(.init))
. = ALIGN(16); . = ALIGN(16);
KEEP(*(.fini)) KEEP(*(.fini))
. = ALIGN(16); . = ALIGN(16);
__text_end = .; __text_end = .;
} > ram } > ram
__ftext_end = ABSOLUTE(.); __ftext_end = ABSOLUTE(.);
__fdata_start = ABSOLUTE(.); __fdata_start = ABSOLUTE(.);
.rodata : { .rodata : {
*(.rodata .rodata.* .rdata .rdata.* .gnu.linkonce.r.*) *(.rodata .rodata.* .rdata .rdata.* .gnu.linkonce.r.*)
. = ALIGN(16); . = ALIGN(16);
__preinit_array_start = .; __preinit_array_start = .;
KEEP (*(.preinit_array)) KEEP (*(.preinit_array))
__preinit_array_end = .; __preinit_array_end = .;
. = ALIGN(16); . = ALIGN(16);
__init_array_start = .; __init_array_start = .;
KEEP (*(SORT(.init_array.*))) KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array)) KEEP (*(.init_array))
. = ALIGN(16); . = ALIGN(16);
KEEP (*crtbegin.o(.ctors)) KEEP (*crtbegin.o(.ctors))
KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
KEEP (*(SORT(.ctors.*))) KEEP (*(SORT(.ctors.*)))
KEEP (*crtend.o(.ctors)) KEEP (*crtend.o(.ctors))
__init_array_end = .; __init_array_end = .;
. = ALIGN(16); . = ALIGN(16);
__fini_array_start = .; __fini_array_start = .;
KEEP (*(.fini_array)) KEEP (*(.fini_array))
KEEP (*(SORT(.fini_array.*))) KEEP (*(SORT(.fini_array.*)))
KEEP (*crtbegin.o(.dtors)) KEEP (*crtbegin.o(.dtors))
KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
KEEP (*(SORT(.dtors.*))) KEEP (*(SORT(.dtors.*)))
KEEP (*crtend.o(.dtors)) KEEP (*crtend.o(.dtors))
__fini_array_end = .; __fini_array_end = .;
__build_id = .; __build_id = .;
*(.note.gnu.build-id) *(.note.gnu.build-id)
__build_id_end = .; __build_id_end = .;
} > ram } > ram
.rodata1 : { .rodata1 : {
*(.rodata1) *(.rodata1)
} > ram } > ram
.data : { .data : {
__data_start = .; __data_start = .;
*(.a0table) *(.a0table)
*(.data .data.* .gnu.linkonce.d.*) *(.data .data.* .gnu.linkonce.d.*)
*(.data1) *(.data1)
*(.sdata .sdata.* .gnu.linkonce.s.*) *(.sdata .sdata.* .gnu.linkonce.s.*)
*(.sdata2 .sdata2.* .gnu.linkonce.s2.*) *(.sdata2 .sdata2.* .gnu.linkonce.s2.*)
*(.got.plt) *(.got.plt)
*(.got) *(.got)
__data_end = .; __data_end = .;
} > ram } > ram
.engine_bss : { .engine_bss : {
__engine_bss_start = .; __engine_bss_start = .;
*libJabyEngine_*.a:*(.dynsbss) *libJabyEngine_*.a:*(.dynsbss)
*libJabyEngine_*.a:*(.sbss .sbss.* .gnu.linkonce.sb.*) *libJabyEngine_*.a:*(.sbss .sbss.* .gnu.linkonce.sb.*)
*libJabyEngine_*.a:*(.scommon) *libJabyEngine_*.a:*(.scommon)
*libJabyEngine_*.a:*(.dynbss) *libJabyEngine_*.a:*(.dynbss)
*libJabyEngine_*.a:*(.bss .bss.* .gnu.linkonce.b.*) *libJabyEngine_*.a:*(.bss .bss.* .gnu.linkonce.b.*)
*libJabyEngine_*.a:*(COMMON) *libJabyEngine_*.a:*(COMMON)
. = ALIGN(4); . = ALIGN(4);
__engine_bss_end = .; __engine_bss_end = .;
} > ram } > ram
__fdata_end = .; __fdata_end = .;
.bss __persistent_overlay_end (NOLOAD) : { .bss __persistent_overlay_end (NOLOAD) : {
__bss_start = .; __bss_start = .;
*(.dynsbss) *(.dynsbss)
*(.sbss .sbss.* .gnu.linkonce.sb.*) *(.sbss .sbss.* .gnu.linkonce.sb.*)
*(.scommon) *(.scommon)
*(.dynbss) *(.dynbss)
*(.bss .bss.* .gnu.linkonce.b.*) *(.bss .bss.* .gnu.linkonce.b.*)
*(COMMON) *(COMMON)
. = ALIGN(4); . = ALIGN(4);
__bss_end = .; __bss_end = .;
} > ram } > ram
__heap_start = __bss_end; __heap_start = __bss_end;
__end = .; __end = .;
} }

View File

@ -1,19 +1,19 @@
FROM "ubuntu:22.04" FROM "ubuntu:22.04"
WORKDIR /usr/scripts WORKDIR /usr/scripts
ADD ["scripts/make_gcc.sh", "/usr/scripts"] ADD ["scripts/make_gcc.sh", "/usr/scripts"]
WORKDIR /tmp WORKDIR /tmp
RUN apt update && /usr/scripts/make_gcc.sh RUN apt update && /usr/scripts/make_gcc.sh
WORKDIR /usr/scripts WORKDIR /usr/scripts
ADD ["scripts/install_rust.sh", "/usr/scripts"] ADD ["scripts/install_rust.sh", "/usr/scripts"]
RUN apt update && ./install_rust.sh RUN apt update && ./install_rust.sh
ADD ["scripts/install_pop-fe.sh", "scripts/run_pop_fe.sh", "/usr/scripts"] ADD ["scripts/install_pop-fe.sh", "scripts/run_pop_fe.sh", "/usr/scripts"]
WORKDIR /usr/jaby_engine/bin/extern WORKDIR /usr/jaby_engine/bin/extern
RUN apt update && /usr/scripts/install_pop-fe.sh RUN apt update && /usr/scripts/install_pop-fe.sh
WORKDIR /project WORKDIR /project
ENV PATH="/jaby_engine/bin:/root/.cargo/bin:${PATH}" ENV PATH="/jaby_engine/bin:/root/.cargo/bin:${PATH}"
ENV JABY_ENGINE_PATH=/jaby_engine ENV JABY_ENGINE_PATH=/jaby_engine
ENV JABY_ENGINE_DIR=/jaby_engine ENV JABY_ENGINE_DIR=/jaby_engine
ENV PSX_LICENSE_PATH=/psx_license ENV PSX_LICENSE_PATH=/psx_license

180
readme.md
View File

@ -1,90 +1,90 @@
- [JabyEngine](#jabyengine) - [JabyEngine](#jabyengine)
- [About](#about) - [About](#about)
- [How to build](#how-to-build) - [How to build](#how-to-build)
- [Building `Tools` (without VS Code)](#building-tools-without-vs-code) - [Building `Tools` (without VS Code)](#building-tools-without-vs-code)
- [Building `JabyEngine` (without VS Code)](#building-jabyengine-without-vs-code) - [Building `JabyEngine` (without VS Code)](#building-jabyengine-without-vs-code)
- [Building support library (without VS Code)](#building-support-library-without-vs-code) - [Building support library (without VS Code)](#building-support-library-without-vs-code)
- [`FontWriter` (without VSCode)](#fontwriter-without-vscode) - [`FontWriter` (without VSCode)](#fontwriter-without-vscode)
- [Building `PoolBox` (without VSCode)](#building-poolbox-without-vscode) - [Building `PoolBox` (without VSCode)](#building-poolbox-without-vscode)
- [Media creators](#media-creators) - [Media creators](#media-creators)
- [JabyEngine](#jabyengine-1) - [JabyEngine](#jabyengine-1)
- [PoolBox](#poolbox) - [PoolBox](#poolbox)
- [Special thanks](#special-thanks) - [Special thanks](#special-thanks)
# JabyEngine # JabyEngine
## About ## About
JabyEngine is my personal attempt to eventually make my own PS1 game from "ground up". Originally I didn't indented to release this code publicly but recently I decided to give it a try. If you read this, thank you! JabyEngine is my personal attempt to eventually make my own PS1 game from "ground up". Originally I didn't indented to release this code publicly but recently I decided to give it a try. If you read this, thank you!
## How to build ## How to build
JabyEngine can be build with a docker image using `podman`. Simply run the `install.sh` script from the `podman` folder and you should be good to go. JabyEngine can be build with a docker image using `podman`. Simply run the `install.sh` script from the `podman` folder and you should be good to go.
`podman_jaby_engine.sh` allows you to easily run the docker image for builds: `podman_jaby_engine.sh` allows you to easily run the docker image for builds:
`podman_jaby_engine.sh <project mounting folder>:<working directory relative to project mounting folder> <Command to run> <Arg1> <Args2> <...>` `podman_jaby_engine.sh <project mounting folder>:<working directory relative to project mounting folder> <Command to run> <Arg1> <Args2> <...>`
The following environment variables should be set: The following environment variables should be set:
* `JABY_ENGINE_PATH`: The path to the root folder of this repo. If you used the `install.sh` script and the environment variable was not set, the script will have set it to the folder. Restarting the shell or VS Code might be required. * `JABY_ENGINE_PATH`: The path to the root folder of this repo. If you used the `install.sh` script and the environment variable was not set, the script will have set it to the folder. Restarting the shell or VS Code might be required.
* `PSX_LICENSE_PATH`: The path to a folder containing the PS1 licenses for generating a CD. * `PSX_LICENSE_PATH`: The path to a folder containing the PS1 licenses for generating a CD.
Additionally you can also specify the following optional environment variables: Additionally you can also specify the following optional environment variables:
* `JABY_ENGINE_NO_DOCKER`: Turns off the usage of `podman` for builds. This is only recommended for specific development. * `JABY_ENGINE_NO_DOCKER`: Turns off the usage of `podman` for builds. This is only recommended for specific development.
VS Code has build targets set for all the projects which should be build in this order: VS Code has build targets set for all the projects which should be build in this order:
* `src/Tools/Tools.code-workspace`: Build all tools * `src/Tools/Tools.code-workspace`: Build all tools
* `src/Library/Library.code-workspace`: Build JabyEngine for the configurations you need * `src/Library/Library.code-workspace`: Build JabyEngine for the configurations you need
* `support/src/SupportLibrary.code-workspace` (optional): Build for using support code * `support/src/SupportLibrary.code-workspace` (optional): Build for using support code
* `examples/PoolBox/PoolBox.code-workspace`(optional): Build for an example "game" * `examples/PoolBox/PoolBox.code-workspace`(optional): Build for an example "game"
### Building `Tools` (without VS Code) ### Building `Tools` (without VS Code)
`make` requires the following values to be passed: `make` requires the following values to be passed:
* `CARGO_CMD`: `build` * `CARGO_CMD`: `build`
* `BUILD_PROFILE`: `debug`/`release` * `BUILD_PROFILE`: `debug`/`release`
### Building `JabyEngine` (without VS Code) ### Building `JabyEngine` (without VS Code)
`make` requires the following values to be passed: `make` requires the following values to be passed:
* `BUILD_PROFILE`: `debug`/`release` * `BUILD_PROFILE`: `debug`/`release`
* `PSX_TV_FORMAT`: `PAL`/`NTSC` * `PSX_TV_FORMAT`: `PAL`/`NTSC`
* `CUSTOM_CONFIG`: Empty or folder name under `./config` * `CUSTOM_CONFIG`: Empty or folder name under `./config`
### Building support library (without VS Code) ### Building support library (without VS Code)
These projects shall eventually turn into useful extensions for the engine. So far they are more tests then proper code. However `PoolBox` is depended on `FontWriter`. These projects shall eventually turn into useful extensions for the engine. So far they are more tests then proper code. However `PoolBox` is depended on `FontWriter`.
#### `FontWriter` (without VSCode) #### `FontWriter` (without VSCode)
`make` requires the following values to be passed: `make` requires the following values to be passed:
* `BUILD_PROFILE`: `debug`/`release` * `BUILD_PROFILE`: `debug`/`release`
### Building `PoolBox` (without VSCode) ### Building `PoolBox` (without VSCode)
`PoolBox` is the one and only example project so far. `PoolBox` is the one and only example project so far.
`make` requires the following values to be passed: `make` requires the following values to be passed:
* `BUILD_PROFILE`: `debug`/`release` * `BUILD_PROFILE`: `debug`/`release`
* `REGION`: `SCEE`/`SCEA`/`SCEI` * `REGION`: `SCEE`/`SCEA`/`SCEI`
* `CUSTOM_CONFIG`: Empty or folder name under `$(JABY_ENGINE_PATH)/config` * `CUSTOM_CONFIG`: Empty or folder name under `$(JABY_ENGINE_PATH)/config`
# Media creators # Media creators
## JabyEngine ## JabyEngine
| Art | Author | | Art | Author |
|-----------------------------------------------------------------|------------------------------------------------------------| |-----------------------------------------------------------------|------------------------------------------------------------|
| `ressources\Splash_ntsc.png` <br/> `ressources\Splash_ntsc.png` | Niuka | | `ressources\Splash_ntsc.png` <br/> `ressources\Splash_ntsc.png` | Niuka |
| `bin/extern/32BIT.TMD` | http://psx.arthus.net/homebrew/assets/boot_logos/32BIT.TMD | | `bin/extern/32BIT.TMD` | http://psx.arthus.net/homebrew/assets/boot_logos/32BIT.TMD |
## PoolBox ## PoolBox
| Art | Author | | Art | Author |
|-----------------------------------------------------------------|-------------| |-----------------------------------------------------------------|-------------|
| `examples\PoolBox\assets\AllTheJaby.png` | Niuka | | `examples\PoolBox\assets\AllTheJaby.png` | Niuka |
| `examples\PoolBox\assets\IconTexture.png` | Charlie Nax | | `examples\PoolBox\assets\IconTexture.png` | Charlie Nax |
| `examples\PoolBox\assets\Paco.png` | Paco | | `examples\PoolBox\assets\Paco.png` | Paco |
| Music | Author | | Music | Author |
|---------------------------------------------------------------------------|---------------------------------------| |---------------------------------------------------------------------------|---------------------------------------|
| `examples\PoolBox\assets\audio\apple.wav` | ??? | | `examples\PoolBox\assets\audio\apple.wav` | ??? |
| `examples\PoolBox\assets\audio\blubb-mono.wav` | ??? | | `examples\PoolBox\assets\audio\blubb-mono.wav` | ??? |
| `examples\PoolBox\assets\audio\Evacuation_cdda.wav` | Cody the white tiger | | `examples\PoolBox\assets\audio\Evacuation_cdda.wav` | Cody the white tiger |
| `examples\PoolBox\assets\audio\Friendship_samp.wav` | From Dragon Quest VII | | `examples\PoolBox\assets\audio\Friendship_samp.wav` | From Dragon Quest VII |
| `examples\PoolBox\assets\audio\jlbrock44_Three_Kings_Funk_cdda_ready.wav` | `Three Kings Funk` by spinningmerkaba | | `examples\PoolBox\assets\audio\jlbrock44_Three_Kings_Funk_cdda_ready.wav` | `Three Kings Funk` by spinningmerkaba |
| `examples\PoolBox\assets\audio\OnMyOwn_BailBonds.mp3` | `On My Own` by Bail Bonds | | `examples\PoolBox\assets\audio\OnMyOwn_BailBonds.mp3` | `On My Own` by Bail Bonds |
# Special thanks # Special thanks
* Cody the white tiger * Cody the white tiger
* Nicolas Noble * Nicolas Noble
* Pyravia * Pyravia
* Sickle * Sickle

View File

@ -1,103 +1,103 @@
{ {
"folders": [ "folders": [
{ {
"name": "JabyEngine", "name": "JabyEngine",
"path": ".", "path": ".",
}, },
{ {
"name": "Include", "name": "Include",
"path": "..\\..\\include" "path": "..\\..\\include"
}, },
{ {
"name": "Root", "name": "Root",
"path": "..\\.." "path": "..\\.."
} }
], ],
"tasks": { "tasks": {
"version": "2.0.0", "version": "2.0.0",
"tasks": [ "tasks": [
{ {
"label": "make", "label": "make",
"type": "shell", "type": "shell",
"command": "../../scripts/podman_jaby_engine.sh ../../:src/Library make ${input:target} BUILD_PROFILE=${input:build cfg} PSX_TV_FORMAT=${input:tv format} CUSTOM_CONFIG=${input:config options}", "command": "../../scripts/podman_jaby_engine.sh ../../:src/Library make ${input:target} BUILD_PROFILE=${input:build cfg} PSX_TV_FORMAT=${input:tv format} CUSTOM_CONFIG=${input:config options}",
"group": "build" "group": "build"
}, },
{ {
"label": "make_all", "label": "make_all",
"type": "shell", "type": "shell",
"command": "../../scripts/podman_jaby_engine.sh ../../:src/Library make -f MakeAll.mk ${input:target prefix}_${input:target} BUILD_PROFILE=${input:build cfg} CUSTOM_CONFIG=${input:config options}", "command": "../../scripts/podman_jaby_engine.sh ../../:src/Library make -f MakeAll.mk ${input:target prefix}_${input:target} BUILD_PROFILE=${input:build cfg} CUSTOM_CONFIG=${input:config options}",
"group": "build" "group": "build"
} }
], ],
"inputs": [ "inputs": [
{ {
"id": "build cfg", "id": "build cfg",
"type": "pickString", "type": "pickString",
"options": ["debug", "release"], "options": ["debug", "release"],
"default": "release", "default": "release",
"description": "build configuration" "description": "build configuration"
}, },
{ {
"id": "tv format", "id": "tv format",
"type": "pickString", "type": "pickString",
"options": ["PAL", "NTSC"], "options": ["PAL", "NTSC"],
"default": "PAL", "default": "PAL",
"description": "TV format to use" "description": "TV format to use"
}, },
{ {
"id": "config options", "id": "config options",
"type": "command", "type": "command",
"command": "shellCommand.execute", "command": "shellCommand.execute",
"args": { "args": {
"command": "echo \"|<Default>\" && ls -d */", "command": "echo \"|<Default>\" && ls -d */",
"cwd": "${workspaceFolder}/../../config", "cwd": "${workspaceFolder}/../../config",
"fieldSeparator": "|" "fieldSeparator": "|"
} }
}, },
{ {
"id": "target prefix", "id": "target prefix",
"type": "pickString", "type": "pickString",
"options": ["jabyengine", "all_jabyengine"], "options": ["jabyengine", "all_jabyengine"],
"default": "jabyengine", "default": "jabyengine",
"description": "To build JabyEngine or JabyEngine with all configs" "description": "To build JabyEngine or JabyEngine with all configs"
}, },
{ {
"id": "target", "id": "target",
"type": "pickString", "type": "pickString",
"options": ["all", "clean", "rebuild"], "options": ["all", "clean", "rebuild"],
"default": "all", "default": "all",
"description": "build target", "description": "build target",
} }
] ]
}, },
"extensions": { "extensions": {
"recommendations": ["augustocdias.tasks-shell-input", "cantonios.project-templates"] "recommendations": ["augustocdias.tasks-shell-input", "cantonios.project-templates"]
}, },
"settings": { "settings": {
"cmake.configureOnOpen": false, "cmake.configureOnOpen": false,
"C_Cpp.default.includePath": [ "C_Cpp.default.includePath": [
"include", "include",
"../../include" "../../include"
], ],
"C_Cpp.default.compilerPath": "", "C_Cpp.default.compilerPath": "",
"C_Cpp.default.cStandard": "c17", "C_Cpp.default.cStandard": "c17",
"C_Cpp.default.cppStandard": "c++20", "C_Cpp.default.cppStandard": "c++20",
"C_Cpp.default.intelliSenseMode": "linux-gcc-x86", "C_Cpp.default.intelliSenseMode": "linux-gcc-x86",
"C_Cpp.default.compilerArgs": [ "C_Cpp.default.compilerArgs": [
], ],
"C_Cpp.default.defines": [ "C_Cpp.default.defines": [
"JABYENGINE_PAL", "JABYENGINE_PAL",
"__DEBUG_SPU_MMU__", "__DEBUG_SPU_MMU__",
"__friends=public" "__friends=public"
], ],
"files.exclude": { "files.exclude": {
"**/*.o": true, "**/*.o": true,
"**/*.dep": true "**/*.dep": true
}, },
"files.associations": { "files.associations": {
"stdio.h": "c", "stdio.h": "c",
"TUTO0.C": "cpp", "TUTO0.C": "cpp",
"MAIN.C": "cpp" "MAIN.C": "cpp"
} }
} }
} }

View File

@ -1,26 +1,26 @@
define make_one define make_one
$(MAKE) $1 PSX_TV_FORMAT=PAL CUSTOM_CONFIG=$2 $(MAKE) $1 PSX_TV_FORMAT=PAL CUSTOM_CONFIG=$2
$(MAKE) $1 PSX_TV_FORMAT=NTSC CUSTOM_CONFIG=$2 $(MAKE) $1 PSX_TV_FORMAT=NTSC CUSTOM_CONFIG=$2
endef endef
define make_all define make_all
$(call make_one,$1,) $(call make_one,$1,)
$(foreach config,$2,$(call make_one,$1,$(config))) $(foreach config,$2,$(call make_one,$1,$(config)))
endef endef
config_files = $(shell cd ../../config && ls -d */) config_files = $(shell cd ../../config && ls -d */)
jabyengine_%: jabyengine_%:
$(call make_one,$*,$(CUSTOM_CONFIG)) $(call make_one,$*,$(CUSTOM_CONFIG))
all_jabyengine_%: all_jabyengine_%:
$(call make_all,$*,$(config_files)) $(call make_all,$*,$(config_files))
all: all:
$(call make_all,all,$(config_files)) $(call make_all,all,$(config_files))
clean: clean:
$(call make_all,clean,$(config_files)) $(call make_all,clean,$(config_files))
rebuild: rebuild:
$(call make_all,rebuild,$(config_files)) $(call make_all,rebuild,$(config_files))

View File

@ -1,51 +1,51 @@
include ../../mkfile/common/RebuildTarget.mk include ../../mkfile/common/RebuildTarget.mk
JABY_ENGINE_DIR = ../../ JABY_ENGINE_DIR = ../../
ARTIFACT = libJabyEngine_$(PSX_TV_FORMAT) ARTIFACT = libJabyEngine_$(PSX_TV_FORMAT)
SPLASH_IMAGE = src/BootLoader/splash_image_pal_boot.hpp SPLASH_IMAGE = src/BootLoader/splash_image_pal_boot.hpp
SPLASH_IMAGE_NTSC = src/BootLoader/splash_image_ntsc_boot.hpp SPLASH_IMAGE_NTSC = src/BootLoader/splash_image_ntsc_boot.hpp
CCFLAGS += -I../../include -D__friends=public CCFLAGS += -I../../include -D__friends=public
CCFLAGS += -save-temps=obj CCFLAGS += -save-temps=obj
include ../../mkfile/common/CustomConfigHelper.mk include ../../mkfile/common/CustomConfigHelper.mk
CONFIG_NAME = $(PLATFORM)-$(BUILD_PROFILE)/$(CUSTOM_CONFIG) CONFIG_NAME = $(PLATFORM)-$(BUILD_PROFILE)/$(CUSTOM_CONFIG)
include ../../mkfile/common/Wildcard.mk include ../../mkfile/common/Wildcard.mk
SRCS = $(call rwildcard, src, c cpp s) SRCS = $(call rwildcard, src, c cpp s)
include ../../mkfile/Makefile include ../../mkfile/Makefile
LIB_DIR = ../../lib/$(CONFIG_NAME) LIB_DIR = ../../lib/$(CONFIG_NAME)
MAIN_LIB_OBJS = $(filter-out $(MAIN_BOOT_OBJ) $(OVERLAY_BOOT_OBJ),$(OBJS)) MAIN_LIB_OBJS = $(filter-out $(MAIN_BOOT_OBJ) $(OVERLAY_BOOT_OBJ),$(OBJS))
#$(info $$var is [${MAIN_BOOT_OBJ}]) #$(info $$var is [${MAIN_BOOT_OBJ}])
#$(info $$var2 is [${MAIN_LIB_OBJS}]) #$(info $$var2 is [${MAIN_LIB_OBJS}])
#Linking rule #Linking rule
$(TARGET).a: $(MAIN_LIB_OBJS) $(SPLASH_IMAGE) $(TARGET).a: $(MAIN_LIB_OBJS) $(SPLASH_IMAGE)
@mkdir -p $(dir $@) @mkdir -p $(dir $@)
$(AR) rcs $(TARGET).a $(MAIN_LIB_OBJS) $(AR) rcs $(TARGET).a $(MAIN_LIB_OBJS)
#Copy rules #Copy rules
$(LIB_DIR)/$(ARTIFACT).a: $(TARGET).a $(LIB_DIR)/$(ARTIFACT).a: $(TARGET).a
@mkdir -p $(LIB_DIR) @mkdir -p $(LIB_DIR)
cp $(TARGET).a $(LIB_DIR)/$(ARTIFACT).a cp $(TARGET).a $(LIB_DIR)/$(ARTIFACT).a
# rule to make the boot image # rule to make the boot image
$(SPLASH_IMAGE): ressources/Splash.png $(SPLASH_IMAGE): ressources/Splash.png
psxfileconv --lz4 $< simple-tim full16 | cpp_out --name SplashScreen -o $@ psxfileconv --lz4 $< simple-tim full16 | cpp_out --name SplashScreen -o $@
$(SPLASH_IMAGE_NTSC): ressources/Splash_ntsc.png $(SPLASH_IMAGE_NTSC): ressources/Splash_ntsc.png
psxfileconv --lz4 $< simple-tim full16 | cpp_out --name SplashScreen -o $@ psxfileconv --lz4 $< simple-tim full16 | cpp_out --name SplashScreen -o $@
#Rules section for default compilation and linking #Rules section for default compilation and linking
all: $(SPLASH_IMAGE) $(SPLASH_IMAGE_NTSC) $(LIB_DIR)/$(ARTIFACT).a all: $(SPLASH_IMAGE) $(SPLASH_IMAGE_NTSC) $(LIB_DIR)/$(ARTIFACT).a
clean: clean:
rm -fr $(SPLASH_IMAGE) rm -fr $(SPLASH_IMAGE)
rm -fr $(SPLASH_IMAGE_NTSC) rm -fr $(SPLASH_IMAGE_NTSC)
rm -fr $(OUTPUT_DIR) rm -fr $(OUTPUT_DIR)
rm -fr gcm.cache rm -fr gcm.cache
rm -fr $(LIB_DIR)/$(ARTIFACT).a rm -fr $(LIB_DIR)/$(ARTIFACT).a

View File

@ -1,44 +1,44 @@
#pragma once #pragma once
#include <PSX/System/IOPorts/dma_io.hpp> #include <PSX/System/IOPorts/dma_io.hpp>
#include <PSX/SPU/spu.hpp> #include <PSX/SPU/spu.hpp>
namespace JabyEngine { namespace JabyEngine {
namespace SPU { namespace SPU {
namespace internal { namespace internal {
struct DMA { struct DMA {
static void wait() { static void wait() {
DMA_IO::SPU.wait(); DMA_IO::SPU.wait();
while(SPU_IO::StatusRegister.read().is_set(SPU_IO_Values::StatusRegister::TransferBusy)); while(SPU_IO::StatusRegister.read().is_set(SPU_IO_Values::StatusRegister::TransferBusy));
} }
static void end() { static void end() {
SPU_IO::ControlRegister.set_transfer_mode(SPU_IO_Values::ControlRegister::Stop); SPU_IO::ControlRegister.set_transfer_mode(SPU_IO_Values::ControlRegister::Stop);
} }
struct Receive { struct Receive {
static void prepare() { static void prepare() {
end(); end();
SPU_IO::DataTransferControl.write(SPU_IO_Values::DataTransferControl::NormalTransferMode()); SPU_IO::DataTransferControl.write(SPU_IO_Values::DataTransferControl::NormalTransferMode());
SPU_IO::ControlRegister.set_transfer_mode(SPU_IO_Values::ControlRegister::Stop); SPU_IO::ControlRegister.set_transfer_mode(SPU_IO_Values::ControlRegister::Stop);
} }
static void set_src(uintptr_t adr) { static void set_src(uintptr_t adr) {
DMA_IO::SPU.set_adr(adr); DMA_IO::SPU.set_adr(adr);
} }
static void set_dst(SPU::SRAMAdr adr) { static void set_dst(SPU::SRAMAdr adr) {
SPU_IO::SRAMTransferAdr.write(adr); SPU_IO::SRAMTransferAdr.write(adr);
SPU_IO::ControlRegister.set_transfer_mode(SPU_IO_Values::ControlRegister::DMAWrite); SPU_IO::ControlRegister.set_transfer_mode(SPU_IO_Values::ControlRegister::DMAWrite);
} }
static void start(uint16_t blockCount, uint16_t wordsPerBlock = 0x10) { static void start(uint16_t blockCount, uint16_t wordsPerBlock = 0x10) {
using SyncMode1 = DMA_IO_Values::BCR::SyncMode1; using SyncMode1 = DMA_IO_Values::BCR::SyncMode1;
DMA_IO::SPU.block_ctrl.write(DMA_IO_Values::BCR::from(SyncMode1::BlockSize.with(wordsPerBlock), SyncMode1::BlockAmount.with(blockCount))); DMA_IO::SPU.block_ctrl.write(DMA_IO_Values::BCR::from(SyncMode1::BlockSize.with(wordsPerBlock), SyncMode1::BlockAmount.with(blockCount)));
DMA_IO::SPU.channel_ctrl.write(DMA_IO_Values::CHCHR::StartSPUReceive()); DMA_IO::SPU.channel_ctrl.write(DMA_IO_Values::CHCHR::StartSPUReceive());
} }
}; };
}; };
} }
} }
} }

View File

@ -1,9 +1,9 @@
#pragma once #pragma once
#include <PSX/jabyengine.hpp> #include <PSX/jabyengine.hpp>
namespace JabyEngine { namespace JabyEngine {
namespace SPU_MMU { namespace SPU_MMU {
const uint8_t* allocate(uint8_t voice, size_t size); const uint8_t* allocate(uint8_t voice, size_t size);
void deallocate(uint8_t voice); void deallocate(uint8_t voice);
} }
} }

View File

@ -1,51 +1,51 @@
#pragma once #pragma once
#include "threads.hpp" #include "threads.hpp"
#include <stdio.hpp> #include <stdio.hpp>
namespace JabyEngine { namespace JabyEngine {
namespace Callback { namespace Callback {
namespace internal { namespace internal {
static void execute_callback(Thread::Handle thread_handle, uint32_t parm) { static void execute_callback(Thread::Handle thread_handle, uint32_t parm) {
if(CurrentThread::is_me(MainThread::Handle)) { if(CurrentThread::is_me(MainThread::Handle)) {
CurrentThread::replace_with(thread_handle); CurrentThread::replace_with(thread_handle);
CurrentThread::force_a0(parm); CurrentThread::force_a0(parm);
} }
SysCall::ReturnFromException(); SysCall::ReturnFromException();
} }
static uint32_t resume_callback(Thread::Handle handle) { static uint32_t resume_callback(Thread::Handle handle) {
SysCall::ChangeThread(handle); SysCall::ChangeThread(handle);
asm("sw $a0, %0" : "=m"(handle)); asm("sw $a0, %0" : "=m"(handle));
return handle; return handle;
} }
namespace VSync { namespace VSync {
static constexpr size_t StackSize = 64; static constexpr size_t StackSize = 64;
extern SysCall::ThreadHandle thread_handle; extern SysCall::ThreadHandle thread_handle;
extern uint32_t stack[StackSize]; extern uint32_t stack[StackSize];
void routine(); void routine();
static void [[deprecated("Currently not in use")]] execute() { static void [[deprecated("Currently not in use")]] execute() {
execute_callback(VSync::thread_handle, 0); execute_callback(VSync::thread_handle, 0);
} }
} }
namespace CD { namespace CD {
static constexpr size_t StackSize = 256; static constexpr size_t StackSize = 256;
extern Thread::Handle thread_handle; extern Thread::Handle thread_handle;
extern uint32_t stack[StackSize]; extern uint32_t stack[StackSize];
void routine(uint32_t irq); void routine(uint32_t irq);
static void execute(uint32_t irq) { static void execute(uint32_t irq) {
execute_callback(CD::thread_handle, irq); execute_callback(CD::thread_handle, irq);
} }
static uint32_t resume() { static uint32_t resume() {
return resume_callback(MainThread::Handle); return resume_callback(MainThread::Handle);
} }
} }
} }
} }
} }

Some files were not shown because too many files have changed in this diff Show More