Fix inconsistent EOL
This commit is contained in:
3
.gitattributes
vendored
3
.gitattributes
vendored
@@ -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
38
.gitignore
vendored
@@ -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
|
||||
@@ -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__
|
||||
@@ -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__
|
||||
```
|
||||
@@ -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__
|
||||
@@ -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.
|
||||
@@ -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: ;
|
||||
@@ -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"
|
||||
],
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
};
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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()]);
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
};
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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()),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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),
|
||||
};
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -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()
|
||||
);
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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 {
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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())
|
||||
};
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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();
|
||||
};
|
||||
}
|
||||
@@ -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();
|
||||
};
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
@@ -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
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -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());
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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) {
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -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) {
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -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))
|
||||
}
|
||||
@@ -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};
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -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};
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -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};
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -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, ...);
|
||||
}
|
||||
}
|
||||
@@ -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__
|
||||
@@ -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__
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
154
include/math.hpp
154
include/math.hpp
@@ -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);
|
||||
@@ -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
|
||||
@@ -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");
|
||||
@@ -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
40
license
@@ -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.
|
||||
@@ -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: ;
|
||||
194
mkfile/Makefile
194
mkfile/Makefile
@@ -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)
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -1,2 +1,2 @@
|
||||
#Add the JabyEngine tools to path
|
||||
#Add the JabyEngine tools to path
|
||||
export PATH := $(JABY_ENGINE_DIR)/bin/:$(PATH)
|
||||
@@ -1,3 +1,3 @@
|
||||
rebuild:
|
||||
$(MAKE) clean
|
||||
rebuild:
|
||||
$(MAKE) clean
|
||||
$(MAKE) all
|
||||
@@ -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))
|
||||
522
mkfile/psexe.ld
522
mkfile/psexe.ld
@@ -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 = .;
|
||||
}
|
||||
@@ -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
180
readme.md
@@ -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
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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))
|
||||
@@ -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
|
||||
@@ -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());
|
||||
}
|
||||
};
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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
Reference in New Issue
Block a user