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 39bce44554
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
*.png 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
**/build
**/bin
**/gcm.cache
**/iso/Info
/iso
# Custom configs should not be part of JabyEngine
**/config
.lfsconfig
*.d
*.a
*.o
*.ii
*.xa
# TODO: Remove later
# For now we ignore what is in root
**/build
**/bin
**/gcm.cache
**/iso/Info
/iso
# Custom configs should not be part of JabyEngine
**/config
.lfsconfig
*.d
*.a
*.o
*.ii
*.xa
# TODO: Remove later
examples/PoolBox/assets/tmp.VAG

View File

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

View File

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

View File

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

View File

@ -1,6 +1,6 @@
# Observed bugs
- [Observed bugs](#observed-bugs)
- [Deadlock](#deadlock)
## Deadlock
# Observed bugs
- [Observed bugs](#observed-bugs)
- [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.

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,110 +1,110 @@
#include "include/controller_state.hpp"
#include <PSX/GPU/gpu.hpp>
#include <PSX/SPU/spu.hpp>
namespace ControllerTest {
using DigitalButton = Periphery::AnalogeController::Button;
using namespace JabyEngine;
static void set_active(GPU::SPRT_16::Linked& sprt, bool is_active) {
sprt->tex_offset.y = is_active ? 16 : 0;
if(is_active) {
SPU::voice[1].play_if_end();
}
}
static void set_active(GPU::POLY_FT4::Linked& poly, bool is_active) {
poly->tex_offset0.y = is_active ? 16 : 0;
poly->tex_offset1.y = is_active ? 16 : 0;
poly->tex_offset2.y = is_active ? 32 : 16;
poly->tex_offset3.y = is_active ? 32 : 16;
if(is_active) {
SPU::voice[1].play_if_end();
}
}
static const char* get_type_name(Periphery::ControllerType type) {
switch(type) {
case Periphery::ControllerType::Unkown:
return "Unkown";
case Periphery::ControllerType::Mouse:
return "Mouse";
case Periphery::ControllerType::NegCon:
return "NegCon";
case Periphery::ControllerType::HyperBlaster:
return "HyperBlaster";
case Periphery::ControllerType::Controller:
return "Digital Controller";
case Periphery::ControllerType::ArcadeFlightStick:
return "Flight Stick";
case Periphery::ControllerType::GCon:
return "GCon";
case Periphery::ControllerType::DualShock:
return "DualShock";
case Periphery::ControllerType::MultiTap:
return "MultiTap";
default:
return "???";
}
}
void ControllerState :: setup() {
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]);
}
}
void ControllerState :: update(const Periphery::AnalogeController* controller, JabyEngine::FontWriter& font_writer) {
static const DigitalButton ButtonSprtMap[] = {
DigitalButton::Triangle, DigitalButton::Circle, DigitalButton::Cross, DigitalButton::Square,
DigitalButton::ST, DigitalButton::SEL, DigitalButton::L1, DigitalButton::L2, DigitalButton::R1, DigitalButton::R2,
DigitalButton::L3, DigitalButton::R3
};
static const DigitalButton ArrowPolyMap[] = {
DigitalButton::Up, DigitalButton::Right, DigitalButton::Down, DigitalButton::Left
};
auto& cur_button_sprts = this->buttons[GPU::update_id()];
auto& cur_arrow_poly = this->arrows[GPU::update_id()];
if(controller) {
for(size_t n = 0; n < sizeof(ButtonSprtMap)/sizeof(ButtonSprtMap[0]); 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++) {
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);
// Text stuff down here
const auto offset_point = cur_button_sprts[1]->position;
const auto left_stick = controller->get_left_stick_pos();
const auto right_stick = controller->get_right_stick_pos();
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, "[%s]", get_type_name(static_cast<Periphery::ControllerType>(controller->get_type())));
}
else {
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());
this->tex_page[GPU::update_id()].terminate();
}
}
void ControllerState :: render() {
GPU::render(this->tex_page[GPU::render_id()]);
}
#include "include/controller_state.hpp"
#include <PSX/GPU/gpu.hpp>
#include <PSX/SPU/spu.hpp>
namespace ControllerTest {
using DigitalButton = Periphery::AnalogeController::Button;
using namespace JabyEngine;
static void set_active(GPU::SPRT_16::Linked& sprt, bool is_active) {
sprt->tex_offset.y = is_active ? 16 : 0;
if(is_active) {
SPU::voice[1].play_if_end();
}
}
static void set_active(GPU::POLY_FT4::Linked& poly, bool is_active) {
poly->tex_offset0.y = is_active ? 16 : 0;
poly->tex_offset1.y = is_active ? 16 : 0;
poly->tex_offset2.y = is_active ? 32 : 16;
poly->tex_offset3.y = is_active ? 32 : 16;
if(is_active) {
SPU::voice[1].play_if_end();
}
}
static const char* get_type_name(Periphery::ControllerType type) {
switch(type) {
case Periphery::ControllerType::Unkown:
return "Unkown";
case Periphery::ControllerType::Mouse:
return "Mouse";
case Periphery::ControllerType::NegCon:
return "NegCon";
case Periphery::ControllerType::HyperBlaster:
return "HyperBlaster";
case Periphery::ControllerType::Controller:
return "Digital Controller";
case Periphery::ControllerType::ArcadeFlightStick:
return "Flight Stick";
case Periphery::ControllerType::GCon:
return "GCon";
case Periphery::ControllerType::DualShock:
return "DualShock";
case Periphery::ControllerType::MultiTap:
return "MultiTap";
default:
return "???";
}
}
void ControllerState :: setup() {
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]);
}
}
void ControllerState :: update(const Periphery::AnalogeController* controller, JabyEngine::FontWriter& font_writer) {
static const DigitalButton ButtonSprtMap[] = {
DigitalButton::Triangle, DigitalButton::Circle, DigitalButton::Cross, DigitalButton::Square,
DigitalButton::ST, DigitalButton::SEL, DigitalButton::L1, DigitalButton::L2, DigitalButton::R1, DigitalButton::R2,
DigitalButton::L3, DigitalButton::R3
};
static const DigitalButton ArrowPolyMap[] = {
DigitalButton::Up, DigitalButton::Right, DigitalButton::Down, DigitalButton::Left
};
auto& cur_button_sprts = this->buttons[GPU::update_id()];
auto& cur_arrow_poly = this->arrows[GPU::update_id()];
if(controller) {
for(size_t n = 0; n < sizeof(ButtonSprtMap)/sizeof(ButtonSprtMap[0]); 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++) {
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);
// Text stuff down here
const auto offset_point = cur_button_sprts[1]->position;
const auto left_stick = controller->get_left_stick_pos();
const auto right_stick = controller->get_right_stick_pos();
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, "[%s]", get_type_name(static_cast<Periphery::ControllerType>(controller->get_type())));
}
else {
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());
this->tex_page[GPU::update_id()].terminate();
}
}
void ControllerState :: render() {
GPU::render(this->tex_page[GPU::render_id()]);
}
}

View File

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

View File

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

View File

@ -1,67 +1,67 @@
#pragma once
#include "controller_test_assets.hpp"
#include <FontWriter/font_writer.hpp>
#include <PSX/GPU/make_gpu_primitives.hpp>
#include <PSX/Periphery/controller.hpp>
namespace ControllerTest {
using namespace JabyEngine;
class ControllerState {
private:
GPU::TexPage::Linked tex_page[2];
GPU::SPRT_16::Linked buttons[2][13];
GPU::POLY_FT4::Linked arrows[2][4];
public:
static constexpr ControllerState create(GPU::PositionI16 offset = Make::PositionI16(0, 0)) {
ControllerState state;
for(auto& tex_page : state.tex_page) {
tex_page = Make::TexPage(ControllerButtonTIM.get_texture_position(), GPU::TextureColorMode::clut4).linked();
}
for(auto& buttons : state.buttons) {
// 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();
// 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();
// 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();
// 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();
// 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();
// 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();
// 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();
// 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();
// 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();
// 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();
// 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();
// 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();
// 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();
}
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[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[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;
}
void setup();
void update(const Periphery::AnalogeController* controller, JabyEngine::FontWriter& font_writer);
void render();
};
#pragma once
#include "controller_test_assets.hpp"
#include <FontWriter/font_writer.hpp>
#include <PSX/GPU/make_gpu_primitives.hpp>
#include <PSX/Periphery/controller.hpp>
namespace ControllerTest {
using namespace JabyEngine;
class ControllerState {
private:
GPU::TexPage::Linked tex_page[2];
GPU::SPRT_16::Linked buttons[2][13];
GPU::POLY_FT4::Linked arrows[2][4];
public:
static constexpr ControllerState create(GPU::PositionI16 offset = Make::PositionI16(0, 0)) {
ControllerState state;
for(auto& tex_page : state.tex_page) {
tex_page = Make::TexPage(ControllerButtonTIM.get_texture_position(), GPU::TextureColorMode::clut4).linked();
}
for(auto& buttons : state.buttons) {
// 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();
// 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();
// 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();
// 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();
// 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();
// 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();
// 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();
// 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();
// 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();
// 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();
// 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();
// 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();
// 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();
}
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[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[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;
}
void setup();
void update(const Periphery::AnalogeController* controller, JabyEngine::FontWriter& font_writer);
void render();
};
}

View File

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

View File

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

View File

@ -1,174 +1,174 @@
#include "../../../include/shared.hpp"
#include "include/gpu_test_assets.hpp"
#include <PSX/GPU/gpu.hpp>
#include <PSX/GPU/make_gpu_primitives.hpp>
#include <PSX/Periphery/periphery.hpp>
#include <PSX/Timer/high_res_timer.hpp>
namespace GPUTest {
using namespace JabyEngine;
// Some default values for the objects
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 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 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 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 LineColor = GPU::Color24::from_rgb(0xFF, 0x0, 0x0);
static constexpr const auto triangle1 = Make::POLY_F3({
Make::Vertex(TriangleArea.position.x, TriangleArea.position.y),
Make::Vertex(TriangleArea.size.width, TriangleArea.size.height),
Make::Vertex(TriangleArea.position.x, TriangleArea.size.height)
}, TriangleColor
);
static constexpr const auto triangle2 = Make::POLY_FT3({
Make::Vertex(TriangleArea.position.x, TriangleArea.position.y),
Make::Vertex(TriangleArea.size.width, TriangleArea.position.y),
Make::Vertex(TriangleArea.size.width, TriangleArea.size.height)
},{
// Texture
Make::PageOffset(TriangleArea.position.x, TriangleArea.position.y),
Make::PageOffset(TriangleArea.size.width, TriangleArea.position.y),
Make::PageOffset(TriangleArea.size.width, TriangleArea.size.height)
}, TriangleTPage, TriangleClut, GPU::Color24::Grey()
);
static constexpr const auto triangle3 = Make::POLY_G3({
{triangle1.vertex0.move(TriangleArea.size.width, 0), GPU::Color24::Red()},
{triangle1.vertex1.move(TriangleArea.size.width, 0), GPU::Color24::Green()},
{triangle1.vertex2.move(TriangleArea.size.width, 0), GPU::Color24::Blue()}}
);
static constexpr const auto triangle4 = Make::POLY_GT3({
{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.vertex2.move(TriangleArea.size.width, 0), triangle2.tex_offset2, GPU::Color24::Green()}},
TriangleTPage,
TriangleClut
);
static constexpr const auto rectangle1 = Make::POLY_F4(RectangleArea, RectangleColor);
static constexpr const auto rectangle2 = Make::POLY_FT4(Make::AreaI16(
RectangleArea.position.move(RectangleArea.size.width, 0), RectangleArea.size), Make::PageOffset(0, 0),
RectangleTPage,
RectangleClut,
GPU::Color24::Grey()
);
static constexpr const auto rectangle3 = Make::POLY_G4(
{RectangleArea.position.move(RectangleArea.size.width*2, 0), RectangleArea.size}, {
GPU::Color24::Red(),
GPU::Color24::Blue(),
GPU::Color24::Green(),
GPU::Color24::White()});
static constexpr const auto rectangle4 = Make::POLY_GT4(Make::AreaI16(
RectangleArea.position.move(RectangleArea.size.width*3, 0), RectangleArea.size), Make::PageOffset(0, 0),
RectangleTPage,
RectangleClut, {
GPU::Color24::Red(),
GPU::Color24::Blue(),
GPU::Color24::Green(),
GPU::Color24::White()}
);
static constexpr const auto rectangle5 = Make::POLY_GT4(Make::AreaI16(
RectangleArea.position.move(0, RectangleArea.size.height), RectangleArea.size), Make::PageOffset(0, 0),
RectangleTPage,
RectangleClut, {
GPU::Color24::Red(),
GPU::Color24::Blue(),
GPU::Color24::Green(),
GPU::Color24::White()}
).set_semi_transparent(true);
static constexpr const auto line1 = Make::LINE_F(LineColor,
Make::Vertex(0, 0),
Make::Vertex(GPU::Display::Width, GPU::Display::Height)
);
static constexpr const auto line2 = Make::LINE_F(LineColor.invert(),
Make::Vertex(0, 0),
Make::Vertex(16, 0),
Make::Vertex(16, 16),
Make::Vertex(0, 0)
);
static constexpr const auto line3 = Make::LINE_G(
GPU::ColorVertex{LineColor, Make::Vertex(GPU::Display::Width, 0)},
GPU::ColorVertex{LineColor.invert(), Make::Vertex(0, GPU::Display::Height)}
);
static constexpr const auto line4 = Make::LINE_G(
GPU::ColorVertex{GPU::Color24::Red(), Make::Vertex(0, 0)},
GPU::ColorVertex{GPU::Color24::Green(), Make::Vertex(0, 16)},
GPU::ColorVertex{GPU::Color24::Blue(), Make::Vertex(16, 16)},
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 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 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 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 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 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();
void main() {
rect9.concat(rect10);
Shared::back_menu.reset();
HighResTime::enable();
auto start_time = HighResTime::get_time_stamp();
auto time_passed = 0;
while(true) {
// Update Phase
Periphery::query_controller();
if(Shared::back_menu.update(Make::PositionI16(0, GPU::Display::Height - 32))) {
break;
}
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);
GPU::swap_buffers_vsync(1);
const auto end_time = HighResTime::get_time_stamp();
time_passed = start_time.milliseconds_to(end_time);
start_time = end_time;
GPU::render(triangle1);
GPU::render(triangle2);
GPU::render(triangle3);
GPU::render(triangle4);
GPU::render(rectangle1);
GPU::render(rectangle2);
GPU::render(rectangle3);
GPU::render(rectangle4);
GPU::render(rectangle5);
GPU::render(rect1);
GPU::render(rect2);
GPU::render(rect3);
GPU::render(rect4);
GPU::render(texpage);
GPU::render(rect5);
GPU::render(rect6);
GPU::render(rect7);
GPU::render(rect8);
GPU::render(line1);
GPU::render(line2);
GPU::render(line3);
GPU::render(line4);
GPU::render(rect9);
Shared::back_menu.render();
}
HighResTime::disable();
}
}
#include "../../../include/shared.hpp"
#include "include/gpu_test_assets.hpp"
#include <PSX/GPU/gpu.hpp>
#include <PSX/GPU/make_gpu_primitives.hpp>
#include <PSX/Periphery/periphery.hpp>
#include <PSX/Timer/high_res_timer.hpp>
namespace GPUTest {
using namespace JabyEngine;
// Some default values for the objects
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 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 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 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 LineColor = GPU::Color24::from_rgb(0xFF, 0x0, 0x0);
static constexpr const auto triangle1 = Make::POLY_F3({
Make::Vertex(TriangleArea.position.x, TriangleArea.position.y),
Make::Vertex(TriangleArea.size.width, TriangleArea.size.height),
Make::Vertex(TriangleArea.position.x, TriangleArea.size.height)
}, TriangleColor
);
static constexpr const auto triangle2 = Make::POLY_FT3({
Make::Vertex(TriangleArea.position.x, TriangleArea.position.y),
Make::Vertex(TriangleArea.size.width, TriangleArea.position.y),
Make::Vertex(TriangleArea.size.width, TriangleArea.size.height)
},{
// Texture
Make::PageOffset(TriangleArea.position.x, TriangleArea.position.y),
Make::PageOffset(TriangleArea.size.width, TriangleArea.position.y),
Make::PageOffset(TriangleArea.size.width, TriangleArea.size.height)
}, TriangleTPage, TriangleClut, GPU::Color24::Grey()
);
static constexpr const auto triangle3 = Make::POLY_G3({
{triangle1.vertex0.move(TriangleArea.size.width, 0), GPU::Color24::Red()},
{triangle1.vertex1.move(TriangleArea.size.width, 0), GPU::Color24::Green()},
{triangle1.vertex2.move(TriangleArea.size.width, 0), GPU::Color24::Blue()}}
);
static constexpr const auto triangle4 = Make::POLY_GT3({
{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.vertex2.move(TriangleArea.size.width, 0), triangle2.tex_offset2, GPU::Color24::Green()}},
TriangleTPage,
TriangleClut
);
static constexpr const auto rectangle1 = Make::POLY_F4(RectangleArea, RectangleColor);
static constexpr const auto rectangle2 = Make::POLY_FT4(Make::AreaI16(
RectangleArea.position.move(RectangleArea.size.width, 0), RectangleArea.size), Make::PageOffset(0, 0),
RectangleTPage,
RectangleClut,
GPU::Color24::Grey()
);
static constexpr const auto rectangle3 = Make::POLY_G4(
{RectangleArea.position.move(RectangleArea.size.width*2, 0), RectangleArea.size}, {
GPU::Color24::Red(),
GPU::Color24::Blue(),
GPU::Color24::Green(),
GPU::Color24::White()});
static constexpr const auto rectangle4 = Make::POLY_GT4(Make::AreaI16(
RectangleArea.position.move(RectangleArea.size.width*3, 0), RectangleArea.size), Make::PageOffset(0, 0),
RectangleTPage,
RectangleClut, {
GPU::Color24::Red(),
GPU::Color24::Blue(),
GPU::Color24::Green(),
GPU::Color24::White()}
);
static constexpr const auto rectangle5 = Make::POLY_GT4(Make::AreaI16(
RectangleArea.position.move(0, RectangleArea.size.height), RectangleArea.size), Make::PageOffset(0, 0),
RectangleTPage,
RectangleClut, {
GPU::Color24::Red(),
GPU::Color24::Blue(),
GPU::Color24::Green(),
GPU::Color24::White()}
).set_semi_transparent(true);
static constexpr const auto line1 = Make::LINE_F(LineColor,
Make::Vertex(0, 0),
Make::Vertex(GPU::Display::Width, GPU::Display::Height)
);
static constexpr const auto line2 = Make::LINE_F(LineColor.invert(),
Make::Vertex(0, 0),
Make::Vertex(16, 0),
Make::Vertex(16, 16),
Make::Vertex(0, 0)
);
static constexpr const auto line3 = Make::LINE_G(
GPU::ColorVertex{LineColor, Make::Vertex(GPU::Display::Width, 0)},
GPU::ColorVertex{LineColor.invert(), Make::Vertex(0, GPU::Display::Height)}
);
static constexpr const auto line4 = Make::LINE_G(
GPU::ColorVertex{GPU::Color24::Red(), Make::Vertex(0, 0)},
GPU::ColorVertex{GPU::Color24::Green(), Make::Vertex(0, 16)},
GPU::ColorVertex{GPU::Color24::Blue(), Make::Vertex(16, 16)},
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 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 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 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 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 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();
void main() {
rect9.concat(rect10);
Shared::back_menu.reset();
HighResTime::enable();
auto start_time = HighResTime::get_time_stamp();
auto time_passed = 0;
while(true) {
// Update Phase
Periphery::query_controller();
if(Shared::back_menu.update(Make::PositionI16(0, GPU::Display::Height - 32))) {
break;
}
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);
GPU::swap_buffers_vsync(1);
const auto end_time = HighResTime::get_time_stamp();
time_passed = start_time.milliseconds_to(end_time);
start_time = end_time;
GPU::render(triangle1);
GPU::render(triangle2);
GPU::render(triangle3);
GPU::render(triangle4);
GPU::render(rectangle1);
GPU::render(rectangle2);
GPU::render(rectangle3);
GPU::render(rectangle4);
GPU::render(rectangle5);
GPU::render(rect1);
GPU::render(rect2);
GPU::render(rect3);
GPU::render(rect4);
GPU::render(texpage);
GPU::render(rect5);
GPU::render(rect6);
GPU::render(rect7);
GPU::render(rect8);
GPU::render(line1);
GPU::render(line2);
GPU::render(line3);
GPU::render(line4);
GPU::render(rect9);
Shared::back_menu.render();
}
HighResTime::disable();
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,13 +1,13 @@
#pragma once
#include "../../../../include/asset_mgr.hpp"
#include <PSX/File/cd_file_types.hpp>
namespace GTETest {
using namespace JabyEngine;
static constexpr auto JabySTARTim = SimpleTIM::create(
// 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_clut_x() + 16, Assets::Main::DoenerFishInfo.tim.get_clut_y()
);
#pragma once
#include "../../../../include/asset_mgr.hpp"
#include <PSX/File/cd_file_types.hpp>
namespace GTETest {
using namespace JabyEngine;
static constexpr auto JabySTARTim = SimpleTIM::create(
// 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_clut_x() + 16, Assets::Main::DoenerFishInfo.tim.get_clut_y()
);
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,81 +1,81 @@
#include "../include/shared.hpp"
#include "include/menu.hpp"
#include <PSX/Periphery/periphery.hpp>
#include <PSX/SPU/spu.hpp>
namespace Menu {
using DigitalButton = Periphery::GenericController::Button;
void SimpleMenu :: setup(Callback callback, const Entry* entries, size_t size) {
this->selection_callback = callback;
this->entries = entries;
this->size = size;
this->cur_selection = 0;
}
void SimpleMenu :: update(JabyEngine::FontWriter& font_writer, Cursor& cursor, const GPU::PositionI16& start) {
const auto& controller = Periphery::get_primary_controller_as<JabyEngine::Periphery::GenericController>();
if(controller.button.went_down(DigitalButton::Up) && this->cur_selection > 0) {
this->cur_selection -= 1;
}
if(controller.button.went_down(DigitalButton::Down) && this->cur_selection < (this->size - 1)) {
this->cur_selection += 1;
}
if(controller.button.went_down(DigitalButton::Cross)) {
SPU::voice[0].play();
this->selection_callback(this->cur_selection);
}
cursor.pos = Make::PositionI16(8, 64);
for(size_t n = 0; n < this->size; n++) {
const auto& cur_entry = this->entries[n];
if(this->cur_selection == n) {
FontWriter::bios_font_writer.write(cursor, ">%s<\n", cur_entry.name);
}
else {
FontWriter::bios_font_writer.write(cursor, "%s\n", cur_entry.name);
}
}
}
void BackMenu :: setup(JabyEngine::FontWriter* font_writer) {
this->font_writer = font_writer;
this->timeout.reset();
this->waiting = false;
}
bool BackMenu :: update(const GPU::PositionI16& position, bool auto_clear) {
const auto& controller = Periphery::get_primary_controller_as<JabyEngine::Periphery::GenericController>();
if(Shared::load_test || controller.button.is_down(DigitalButton::Circle)) {
this->waiting = true;
if(this->timeout.is_expired_for(2500_ms)) {
return true;
}
}
else {
this->waiting = false;
this->timeout.reset();
}
if(this->waiting) {
auto cursor = JabyEngine::Cursor::create(position);
this->font_writer->write(cursor, "Press and hold O\nto get back", GPU::Color24::Red(0xD0));
}
else if(auto_clear) {
this->font_writer->clear();
}
return false;
}
void BackMenu :: render() {
this->font_writer->render();
}
#include "../include/shared.hpp"
#include "include/menu.hpp"
#include <PSX/Periphery/periphery.hpp>
#include <PSX/SPU/spu.hpp>
namespace Menu {
using DigitalButton = Periphery::GenericController::Button;
void SimpleMenu :: setup(Callback callback, const Entry* entries, size_t size) {
this->selection_callback = callback;
this->entries = entries;
this->size = size;
this->cur_selection = 0;
}
void SimpleMenu :: update(JabyEngine::FontWriter& font_writer, Cursor& cursor, const GPU::PositionI16& start) {
const auto& controller = Periphery::get_primary_controller_as<JabyEngine::Periphery::GenericController>();
if(controller.button.went_down(DigitalButton::Up) && this->cur_selection > 0) {
this->cur_selection -= 1;
}
if(controller.button.went_down(DigitalButton::Down) && this->cur_selection < (this->size - 1)) {
this->cur_selection += 1;
}
if(controller.button.went_down(DigitalButton::Cross)) {
SPU::voice[0].play();
this->selection_callback(this->cur_selection);
}
cursor.pos = Make::PositionI16(8, 64);
for(size_t n = 0; n < this->size; n++) {
const auto& cur_entry = this->entries[n];
if(this->cur_selection == n) {
FontWriter::bios_font_writer.write(cursor, ">%s<\n", cur_entry.name);
}
else {
FontWriter::bios_font_writer.write(cursor, "%s\n", cur_entry.name);
}
}
}
void BackMenu :: setup(JabyEngine::FontWriter* font_writer) {
this->font_writer = font_writer;
this->timeout.reset();
this->waiting = false;
}
bool BackMenu :: update(const GPU::PositionI16& position, bool auto_clear) {
const auto& controller = Periphery::get_primary_controller_as<JabyEngine::Periphery::GenericController>();
if(Shared::load_test || controller.button.is_down(DigitalButton::Circle)) {
this->waiting = true;
if(this->timeout.is_expired_for(2500_ms)) {
return true;
}
}
else {
this->waiting = false;
this->timeout.reset();
}
if(this->waiting) {
auto cursor = JabyEngine::Cursor::create(position);
this->font_writer->write(cursor, "Press and hold O\nto get back", GPU::Color24::Red(0xD0));
}
else if(auto_clear) {
this->font_writer->clear();
}
return false;
}
void BackMenu :: 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/RebuildTarget.mk
OUTPUT_DIR = bin
CLUT_4_COLOR_TRANS_FLAGS = simple-tim clut4 --color-trans
# Ressources to convert
## Music tracks
INPUT += $(OUTPUT_DIR)/Evacuation_cdda.xa
INPUT += $(OUTPUT_DIR)/OnMyOwn_BailBonds.xa
INPUT += $(OUTPUT_DIR)/apple.vag
INPUT += $(OUTPUT_DIR)/blubb-mono.vag
INPUT += $(OUTPUT_DIR)/Friendship_samp.vag
## Images
INPUT += $(OUTPUT_DIR)/TexturePage.img
TexturePage_FLAGS = simple-tim clut4
INPUT += $(OUTPUT_DIR)/IconTexture.img
IconTexture_FLAGS = simple-tim clut4 --semi-trans --color-trans
INPUT += $(OUTPUT_DIR)/Paco.img
Paco_FLAGS = $(CLUT_4_COLOR_TRANS_FLAGS)
INPUT += $(OUTPUT_DIR)/Controller.img
Controller_FLAGS = $(CLUT_4_COLOR_TRANS_FLAGS)
INPUT += $(OUTPUT_DIR)/doener_fish.img
doener_fish_FLAGS = $(CLUT_4_COLOR_TRANS_FLAGS)
INPUT += $(OUTPUT_DIR)/JabyStar.img
JabyStar_FLAGS = $(CLUT_4_COLOR_TRANS_FLAGS)
INPUT += $(OUTPUT_DIR)/JabyTails.img
JabyTails_FLAGS = $(CLUT_4_COLOR_TRANS_FLAGS)
INPUT += $(OUTPUT_DIR)/IMG_6921.tim
IMG_6921_TIM_FLAGS = tim full16 --clut-pos {384,255} --tex-pos {384,256}
INPUT += $(OUTPUT_DIR)/AllTheJaby.tim
AllTheJaby_TIM_FLAGS = tim full16 --tex-pos {0,0}
$(OUTPUT_DIR)/%.vag: audio/%.wav
@mkdir -p $(OUTPUT_DIR)
psxfileconv --lz4 $< -o $@ vag
$(OUTPUT_DIR)/OnMyOwn_BailBonds.xa: audio/OnMyOwn_BailBonds.mp3
@mkdir -p $(OUTPUT_DIR)
psxfileconv $< -o $@ xa
$(OUTPUT_DIR)/%.xa: audio/%.wav
@mkdir -p $(OUTPUT_DIR)
psxfileconv $< -o $@ xa
$(OUTPUT_DIR)/%.img: %.png
@mkdir -p $(OUTPUT_DIR)
psxfileconv --lz4 $< -o $@ $($*_FLAGS)
$(OUTPUT_DIR)/%.tim: %.png
@mkdir -p $(OUTPUT_DIR)
psxfileconv --lz4 $< -o $@ $($*_TIM_FLAGS)
all: $(INPUT)
clean:
include $(JABY_ENGINE_DIR)/mkfile/common/ExportPath.mk
include $(JABY_ENGINE_DIR)/mkfile/common/RebuildTarget.mk
OUTPUT_DIR = bin
CLUT_4_COLOR_TRANS_FLAGS = simple-tim clut4 --color-trans
# Ressources to convert
## Music tracks
INPUT += $(OUTPUT_DIR)/Evacuation_cdda.xa
INPUT += $(OUTPUT_DIR)/OnMyOwn_BailBonds.xa
INPUT += $(OUTPUT_DIR)/apple.vag
INPUT += $(OUTPUT_DIR)/blubb-mono.vag
INPUT += $(OUTPUT_DIR)/Friendship_samp.vag
## Images
INPUT += $(OUTPUT_DIR)/TexturePage.img
TexturePage_FLAGS = simple-tim clut4
INPUT += $(OUTPUT_DIR)/IconTexture.img
IconTexture_FLAGS = simple-tim clut4 --semi-trans --color-trans
INPUT += $(OUTPUT_DIR)/Paco.img
Paco_FLAGS = $(CLUT_4_COLOR_TRANS_FLAGS)
INPUT += $(OUTPUT_DIR)/Controller.img
Controller_FLAGS = $(CLUT_4_COLOR_TRANS_FLAGS)
INPUT += $(OUTPUT_DIR)/doener_fish.img
doener_fish_FLAGS = $(CLUT_4_COLOR_TRANS_FLAGS)
INPUT += $(OUTPUT_DIR)/JabyStar.img
JabyStar_FLAGS = $(CLUT_4_COLOR_TRANS_FLAGS)
INPUT += $(OUTPUT_DIR)/JabyTails.img
JabyTails_FLAGS = $(CLUT_4_COLOR_TRANS_FLAGS)
INPUT += $(OUTPUT_DIR)/IMG_6921.tim
IMG_6921_TIM_FLAGS = tim full16 --clut-pos {384,255} --tex-pos {384,256}
INPUT += $(OUTPUT_DIR)/AllTheJaby.tim
AllTheJaby_TIM_FLAGS = tim full16 --tex-pos {0,0}
$(OUTPUT_DIR)/%.vag: audio/%.wav
@mkdir -p $(OUTPUT_DIR)
psxfileconv --lz4 $< -o $@ vag
$(OUTPUT_DIR)/OnMyOwn_BailBonds.xa: audio/OnMyOwn_BailBonds.mp3
@mkdir -p $(OUTPUT_DIR)
psxfileconv $< -o $@ xa
$(OUTPUT_DIR)/%.xa: audio/%.wav
@mkdir -p $(OUTPUT_DIR)
psxfileconv $< -o $@ xa
$(OUTPUT_DIR)/%.img: %.png
@mkdir -p $(OUTPUT_DIR)
psxfileconv --lz4 $< -o $@ $($*_FLAGS)
$(OUTPUT_DIR)/%.tim: %.png
@mkdir -p $(OUTPUT_DIR)
psxfileconv --lz4 $< -o $@ $($*_TIM_FLAGS)
all: $(INPUT)
clean:
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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,14 +1,14 @@
#pragma once
#include <stdio.h>
namespace JabyEngine {
template<typename T>
static inline void dump_to_stdoutln(const 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++) {
printf("[%02X]", raw_ptr[raw_pos]);
}
printf("\n");
}
}
#pragma once
#include <stdio.h>
namespace JabyEngine {
template<typename T>
static inline void dump_to_stdoutln(const 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++) {
printf("[%02X]", raw_ptr[raw_pos]);
}
printf("\n");
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,118 +1,118 @@
#pragma once
#include "../../../Auxiliary/types.hpp"
#include "../../../Auxiliary/bits.hpp"
namespace JabyEngine {
namespace IOAdress {
constexpr uintptr_t patch_adr(uintptr_t adr) {
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)
return (Base + (adr & ~Mask));
}
}
namespace internal {
template<typename T, typename S>
struct IOValue {
typedef S UnderlyingType;
UnderlyingType raw;
template<typename...ARGS>
static constexpr T from(const ARGS&...args) {
return T{0}.set(args...);
}
constexpr T& set(Bit bit) {
this->raw = bit::set(this->raw, bit);
return static_cast<T&>(*this);
}
constexpr T& set(ClearBit bit) {
this->raw = bit::set(this->raw, bit);
return static_cast<T&>(*this);
}
constexpr T& set_range(const BitRange& bits, UnderlyingType value) {
this->raw = bit::value::set_normalized(this->raw, bits, value);
return static_cast<T&>(*this);
}
template<typename U>
constexpr T& set(const BitRange::RangeValuePair<U>& value) {
this->raw = bit::value::set_normalized(this->raw, value);
return static_cast<T&>(*this);
}
template<typename U, typename...ARGS>
constexpr T& set(const U& head, const ARGS&...tail) {
return this->set(head).set(tail...);
}
constexpr IOValue<T, S>::UnderlyingType get(BitRange bits) const {
return bit::value::get_normalized(this->raw, bits.pos, bits.length);
}
constexpr T& clear(Bit bit) {
this->raw = bit::clear(this->raw, bit);
return static_cast<T&>(*this);
}
constexpr bool is_set(Bit bit) const {
return bit::is_set(this->raw, bit);
}
};
}
template<typename T>
struct IOPort {
using Value = T;
T value;
T read() const {
return {const_cast<const volatile IOPort<T>*>(this)->value.raw};
}
void write(T value) {
const_cast<volatile IOPort<T>*>(this)->value.raw = value.raw;
}
};
template<>
struct IOPort<uint32_t>;
template<typename T>
struct IOPort32 {
union ValueHelper {
struct {
uint16_t low;
uint16_t high;
};
T value;
};
using Value = T;
T value;
T read() const {
const auto* cast_this = reinterpret_cast<const IOPort32<ValueHelper>*>(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;
}
void write(T value) {
const auto new_value = ValueHelper{.value = value};
auto* cast_this = reinterpret_cast<IOPort32<ValueHelper>*>(this);
volatile auto* v_this = const_cast<volatile decltype(cast_this)>(cast_this);
v_this->value.low = new_value.low;
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_port(type, adr) *reinterpret_cast<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))
#pragma once
#include "../../../Auxiliary/types.hpp"
#include "../../../Auxiliary/bits.hpp"
namespace JabyEngine {
namespace IOAdress {
constexpr uintptr_t patch_adr(uintptr_t adr) {
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)
return (Base + (adr & ~Mask));
}
}
namespace internal {
template<typename T, typename S>
struct IOValue {
typedef S UnderlyingType;
UnderlyingType raw;
template<typename...ARGS>
static constexpr T from(const ARGS&...args) {
return T{0}.set(args...);
}
constexpr T& set(Bit bit) {
this->raw = bit::set(this->raw, bit);
return static_cast<T&>(*this);
}
constexpr T& set(ClearBit bit) {
this->raw = bit::set(this->raw, bit);
return static_cast<T&>(*this);
}
constexpr T& set_range(const BitRange& bits, UnderlyingType value) {
this->raw = bit::value::set_normalized(this->raw, bits, value);
return static_cast<T&>(*this);
}
template<typename U>
constexpr T& set(const BitRange::RangeValuePair<U>& value) {
this->raw = bit::value::set_normalized(this->raw, value);
return static_cast<T&>(*this);
}
template<typename U, typename...ARGS>
constexpr T& set(const U& head, const ARGS&...tail) {
return this->set(head).set(tail...);
}
constexpr IOValue<T, S>::UnderlyingType get(BitRange bits) const {
return bit::value::get_normalized(this->raw, bits.pos, bits.length);
}
constexpr T& clear(Bit bit) {
this->raw = bit::clear(this->raw, bit);
return static_cast<T&>(*this);
}
constexpr bool is_set(Bit bit) const {
return bit::is_set(this->raw, bit);
}
};
}
template<typename T>
struct IOPort {
using Value = T;
T value;
T read() const {
return {const_cast<const volatile IOPort<T>*>(this)->value.raw};
}
void write(T value) {
const_cast<volatile IOPort<T>*>(this)->value.raw = value.raw;
}
};
template<>
struct IOPort<uint32_t>;
template<typename T>
struct IOPort32 {
union ValueHelper {
struct {
uint16_t low;
uint16_t high;
};
T value;
};
using Value = T;
T value;
T read() const {
const auto* cast_this = reinterpret_cast<const IOPort32<ValueHelper>*>(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;
}
void write(T value) {
const auto new_value = ValueHelper{.value = value};
auto* cast_this = reinterpret_cast<IOPort32<ValueHelper>*>(this);
volatile auto* v_this = const_cast<volatile decltype(cast_this)>(cast_this);
v_this->value.low = new_value.low;
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_port(type, adr) *reinterpret_cast<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))
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,89 +1,89 @@
#pragma once
#include "IOValues/timer_io_values.hpp"
namespace JabyEngine {
namespace Timer_IO {
using CounterMode_IO = IOPort<Timer_IO_Values::CounterMode>;
using CounterTarget_IO = IOPort<Timer_IO_Values::CounterTarget>;
using CounterValue_IO = IOPort<Timer_IO_Values::CounterValue>;
#pragma pack(push, 1)
struct Counter {
CounterValue_IO value;
CounterMode_IO mode;
CounterTarget_IO target;
uint32_t unused;
inline uint16_t get_current_value() const {
return this->value.read().get(Timer_IO_Values::CounterValue::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));
}
inline void set_mode(Timer_IO_Values::CounterMode mode) {
this->mode.write(mode);
}
};
#pragma pack(pop)
#pragma pack(push, 1)
struct Counter0 : public Counter {
struct SyncMode {
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 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);
};
struct Source {
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 System_Clock_Too = Timer_IO_Values::CounterMode::ClockSource.with(2u);
static constexpr auto Dot_Clock_Too = Timer_IO_Values::CounterMode::ClockSource.with(3u);
};
};
struct Counter1 : public Counter {
struct SyncMode {
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_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);
};
struct Source {
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 System_Clock_Too = Timer_IO_Values::CounterMode::ClockSource.with(2u);
static constexpr auto Hblank_Too = Timer_IO_Values::CounterMode::ClockSource.with(3u);
};
};
struct Counter2 : public Counter {
struct SyncMode {
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_Too = Timer_IO_Values::CounterMode::SyncMode.with(2u);
static constexpr auto Stop_Counter_Too = Timer_IO_Values::CounterMode::SyncMode.with(3u);
};
struct Source {
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_Div_8 = Timer_IO_Values::CounterMode::ClockSource.with(2u);
static constexpr auto System_Clock_Div_8_Too = Timer_IO_Values::CounterMode::ClockSource.with(3u);
};
};
#pragma pack(pop)
static constexpr uintptr_t counter_base_adr(size_t ID) {
return (0x1F801100 + (ID*0x10));
}
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& Counter2 = __declare_io_value(struct Counter2, counter_base_adr(2));
}
#pragma once
#include "IOValues/timer_io_values.hpp"
namespace JabyEngine {
namespace Timer_IO {
using CounterMode_IO = IOPort<Timer_IO_Values::CounterMode>;
using CounterTarget_IO = IOPort<Timer_IO_Values::CounterTarget>;
using CounterValue_IO = IOPort<Timer_IO_Values::CounterValue>;
#pragma pack(push, 1)
struct Counter {
CounterValue_IO value;
CounterMode_IO mode;
CounterTarget_IO target;
uint32_t unused;
inline uint16_t get_current_value() const {
return this->value.read().get(Timer_IO_Values::CounterValue::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));
}
inline void set_mode(Timer_IO_Values::CounterMode mode) {
this->mode.write(mode);
}
};
#pragma pack(pop)
#pragma pack(push, 1)
struct Counter0 : public Counter {
struct SyncMode {
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 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);
};
struct Source {
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 System_Clock_Too = Timer_IO_Values::CounterMode::ClockSource.with(2u);
static constexpr auto Dot_Clock_Too = Timer_IO_Values::CounterMode::ClockSource.with(3u);
};
};
struct Counter1 : public Counter {
struct SyncMode {
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_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);
};
struct Source {
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 System_Clock_Too = Timer_IO_Values::CounterMode::ClockSource.with(2u);
static constexpr auto Hblank_Too = Timer_IO_Values::CounterMode::ClockSource.with(3u);
};
};
struct Counter2 : public Counter {
struct SyncMode {
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_Too = Timer_IO_Values::CounterMode::SyncMode.with(2u);
static constexpr auto Stop_Counter_Too = Timer_IO_Values::CounterMode::SyncMode.with(3u);
};
struct Source {
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_Div_8 = Timer_IO_Values::CounterMode::ClockSource.with(2u);
static constexpr auto System_Clock_Div_8_Too = Timer_IO_Values::CounterMode::ClockSource.with(3u);
};
};
#pragma pack(pop)
static constexpr uintptr_t counter_base_adr(size_t ID) {
return (0x1F801100 + (ID*0x10));
}
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& Counter2 = __declare_io_value(struct Counter2, counter_base_adr(2));
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

40
license
View File

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

View File

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

View File

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

View File

@ -1,40 +1,40 @@
#Not intended to be overriden
AUTO_OVERLAY_DIR = $(OUTPUT_DIR)/auto_overlay
include $(AUTO_OVERLAY_DIR)/Overlays.mk
include $(JABY_ENGINE_DIR)/mkfile/common/CustomConfigHelper.mk
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_LIBS = $(addprefix -l,$(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)
OVERLAY_TARGET = $(foreach ovl, $(OVERLAYSECTION), $(OUTPUT_DIR)/Overlay$(ovl))
#Linking rule
$(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)
#Strips the psexe
$(TARGET).psexe: $(TARGET).elf
$(PREFIX)-objcopy $(addprefix -R , $(OVERLAYSECTION)) -O binary $< $@
#Create overlays
$(OVERLAY_TARGET): $(TARGET).elf
$(PREFIX)-objcopy -j $(suffix $@) -O binary $< $@
#Create overlay makefile
$(AUTO_OVERLAY_DIR)/Overlays.mk: $(OVERLAY_CONFIG)
@mkdir -p $(AUTO_OVERLAY_DIR)
mkoverlay --mk-file $(AUTO_OVERLAY_DIR)/Overlays.mk --ld-script $(AUTO_OVERLAY_DIR)/Overlays.ld $<
#Rules section for default compilation and linking
all: $(TARGET).psexe $(OVERLAY_TARGET)
clean:
rm -fr $(OUTPUT_DIR)
# For mkoverlay to function correctly this is required (otherwise Overlays.mk is not re-generated)
rebuild: clean
$(MAKE) all
#Not intended to be overriden
AUTO_OVERLAY_DIR = $(OUTPUT_DIR)/auto_overlay
include $(AUTO_OVERLAY_DIR)/Overlays.mk
include $(JABY_ENGINE_DIR)/mkfile/common/CustomConfigHelper.mk
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_LIBS = $(addprefix -l,$(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)
OVERLAY_TARGET = $(foreach ovl, $(OVERLAYSECTION), $(OUTPUT_DIR)/Overlay$(ovl))
#Linking rule
$(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)
#Strips the psexe
$(TARGET).psexe: $(TARGET).elf
$(PREFIX)-objcopy $(addprefix -R , $(OVERLAYSECTION)) -O binary $< $@
#Create overlays
$(OVERLAY_TARGET): $(TARGET).elf
$(PREFIX)-objcopy -j $(suffix $@) -O binary $< $@
#Create overlay makefile
$(AUTO_OVERLAY_DIR)/Overlays.mk: $(OVERLAY_CONFIG)
@mkdir -p $(AUTO_OVERLAY_DIR)
mkoverlay --mk-file $(AUTO_OVERLAY_DIR)/Overlays.mk --ld-script $(AUTO_OVERLAY_DIR)/Overlays.ld $<
#Rules section for default compilation and linking
all: $(TARGET).psexe $(OVERLAY_TARGET)
clean:
rm -fr $(OUTPUT_DIR)
# For mkoverlay to function correctly this is required (otherwise Overlays.mk is not re-generated)
rebuild: clean
$(MAKE) all

View File

@ -1,4 +1,4 @@
JABY_ENGINE_CONFIG_DIR = $(JABY_ENGINE_DIR)config
ifdef CUSTOM_CONFIG
CCFLAGS += -I$(JABY_ENGINE_CONFIG_DIR)/$(CUSTOM_CONFIG) -imacros $(JABY_ENGINE_CONFIG_DIR)/$(CUSTOM_CONFIG)/jabyengine_custom_config.hpp
JABY_ENGINE_CONFIG_DIR = $(JABY_ENGINE_DIR)config
ifdef CUSTOM_CONFIG
CCFLAGS += -I$(JABY_ENGINE_CONFIG_DIR)/$(CUSTOM_CONFIG) -imacros $(JABY_ENGINE_CONFIG_DIR)/$(CUSTOM_CONFIG)/jabyengine_custom_config.hpp
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)

View File

@ -1,3 +1,3 @@
rebuild:
$(MAKE) clean
rebuild:
$(MAKE) clean
$(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))

View File

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

View File

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

180
readme.md
View File

@ -1,90 +1,90 @@
- [JabyEngine](#jabyengine)
- [About](#about)
- [How to build](#how-to-build)
- [Building `Tools` (without VS Code)](#building-tools-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)
- [`FontWriter` (without VSCode)](#fontwriter-without-vscode)
- [Building `PoolBox` (without VSCode)](#building-poolbox-without-vscode)
- [Media creators](#media-creators)
- [JabyEngine](#jabyengine-1)
- [PoolBox](#poolbox)
- [Special thanks](#special-thanks)
# JabyEngine
## 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!
## 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.
`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> <...>`
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.
* `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:
* `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:
* `src/Tools/Tools.code-workspace`: Build all tools
* `src/Library/Library.code-workspace`: Build JabyEngine for the configurations you need
* `support/src/SupportLibrary.code-workspace` (optional): Build for using support code
* `examples/PoolBox/PoolBox.code-workspace`(optional): Build for an example "game"
### Building `Tools` (without VS Code)
`make` requires the following values to be passed:
* `CARGO_CMD`: `build`
* `BUILD_PROFILE`: `debug`/`release`
### Building `JabyEngine` (without VS Code)
`make` requires the following values to be passed:
* `BUILD_PROFILE`: `debug`/`release`
* `PSX_TV_FORMAT`: `PAL`/`NTSC`
* `CUSTOM_CONFIG`: Empty or folder name under `./config`
### 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`.
#### `FontWriter` (without VSCode)
`make` requires the following values to be passed:
* `BUILD_PROFILE`: `debug`/`release`
### Building `PoolBox` (without VSCode)
`PoolBox` is the one and only example project so far.
`make` requires the following values to be passed:
* `BUILD_PROFILE`: `debug`/`release`
* `REGION`: `SCEE`/`SCEA`/`SCEI`
* `CUSTOM_CONFIG`: Empty or folder name under `$(JABY_ENGINE_PATH)/config`
# Media creators
## JabyEngine
| Art | Author |
|-----------------------------------------------------------------|------------------------------------------------------------|
| `ressources\Splash_ntsc.png` <br/> `ressources\Splash_ntsc.png` | Niuka |
| `bin/extern/32BIT.TMD` | http://psx.arthus.net/homebrew/assets/boot_logos/32BIT.TMD |
## PoolBox
| Art | Author |
|-----------------------------------------------------------------|-------------|
| `examples\PoolBox\assets\AllTheJaby.png` | Niuka |
| `examples\PoolBox\assets\IconTexture.png` | Charlie Nax |
| `examples\PoolBox\assets\Paco.png` | Paco |
| Music | Author |
|---------------------------------------------------------------------------|---------------------------------------|
| `examples\PoolBox\assets\audio\apple.wav` | ??? |
| `examples\PoolBox\assets\audio\blubb-mono.wav` | ??? |
| `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\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 |
# Special thanks
* Cody the white tiger
* Nicolas Noble
* Pyravia
* Sickle
- [JabyEngine](#jabyengine)
- [About](#about)
- [How to build](#how-to-build)
- [Building `Tools` (without VS Code)](#building-tools-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)
- [`FontWriter` (without VSCode)](#fontwriter-without-vscode)
- [Building `PoolBox` (without VSCode)](#building-poolbox-without-vscode)
- [Media creators](#media-creators)
- [JabyEngine](#jabyengine-1)
- [PoolBox](#poolbox)
- [Special thanks](#special-thanks)
# JabyEngine
## 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!
## 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.
`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> <...>`
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.
* `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:
* `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:
* `src/Tools/Tools.code-workspace`: Build all tools
* `src/Library/Library.code-workspace`: Build JabyEngine for the configurations you need
* `support/src/SupportLibrary.code-workspace` (optional): Build for using support code
* `examples/PoolBox/PoolBox.code-workspace`(optional): Build for an example "game"
### Building `Tools` (without VS Code)
`make` requires the following values to be passed:
* `CARGO_CMD`: `build`
* `BUILD_PROFILE`: `debug`/`release`
### Building `JabyEngine` (without VS Code)
`make` requires the following values to be passed:
* `BUILD_PROFILE`: `debug`/`release`
* `PSX_TV_FORMAT`: `PAL`/`NTSC`
* `CUSTOM_CONFIG`: Empty or folder name under `./config`
### 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`.
#### `FontWriter` (without VSCode)
`make` requires the following values to be passed:
* `BUILD_PROFILE`: `debug`/`release`
### Building `PoolBox` (without VSCode)
`PoolBox` is the one and only example project so far.
`make` requires the following values to be passed:
* `BUILD_PROFILE`: `debug`/`release`
* `REGION`: `SCEE`/`SCEA`/`SCEI`
* `CUSTOM_CONFIG`: Empty or folder name under `$(JABY_ENGINE_PATH)/config`
# Media creators
## JabyEngine
| Art | Author |
|-----------------------------------------------------------------|------------------------------------------------------------|
| `ressources\Splash_ntsc.png` <br/> `ressources\Splash_ntsc.png` | Niuka |
| `bin/extern/32BIT.TMD` | http://psx.arthus.net/homebrew/assets/boot_logos/32BIT.TMD |
## PoolBox
| Art | Author |
|-----------------------------------------------------------------|-------------|
| `examples\PoolBox\assets\AllTheJaby.png` | Niuka |
| `examples\PoolBox\assets\IconTexture.png` | Charlie Nax |
| `examples\PoolBox\assets\Paco.png` | Paco |
| Music | Author |
|---------------------------------------------------------------------------|---------------------------------------|
| `examples\PoolBox\assets\audio\apple.wav` | ??? |
| `examples\PoolBox\assets\audio\blubb-mono.wav` | ??? |
| `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\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 |
# Special thanks
* Cody the white tiger
* Nicolas Noble
* Pyravia
* Sickle

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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