Compare commits
No commits in common. "9bf58636f1d3d7d20c5a1473b3df3861c0329136" and "a9bde33a07d3fd122df7ee6554ab49e116fea8d3" have entirely different histories.
9bf58636f1
...
a9bde33a07
@ -1,15 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern uint32_t _binary_cover_clocks_data_start __asm("_binary_cover_clocks_data_start");
|
|
||||||
extern uint32_t _binary_cover_clocks_data_end __asm("_binary_cover_clocks_data_end");
|
|
||||||
extern uint32_t _binary_cover_clocks_data_size __asm("_binary_cover_clocks_data_size");
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
BIN
cover/clocks.png
Before Width: | Height: | Size: 8.8 KiB |
@ -1,15 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern uint32_t _binary_cover_moonmountains_data_start __asm("_binary_cover_moonmountains_data_start");
|
|
||||||
extern uint32_t _binary_cover_moonmountains_data_end __asm("_binary_cover_moonmountains_data_end");
|
|
||||||
extern uint32_t _binary_cover_moonmountains_data_size __asm("_binary_cover_moonmountains_data_size");
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
Before Width: | Height: | Size: 5.9 KiB |
@ -1,15 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern uint32_t _binary_cover_mossycottage_data_start __asm("_binary_cover_mossycottage_data_start");
|
|
||||||
extern uint32_t _binary_cover_mossycottage_data_end __asm("_binary_cover_mossycottage_data_end");
|
|
||||||
extern uint32_t _binary_cover_mossycottage_data_size __asm("_binary_cover_mossycottage_data_size");
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
Before Width: | Height: | Size: 14 KiB |
@ -1,15 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern uint32_t _binary_cover_mountain_data_start __asm("_binary_cover_mountain_data_start");
|
|
||||||
extern uint32_t _binary_cover_mountain_data_end __asm("_binary_cover_mountain_data_end");
|
|
||||||
extern uint32_t _binary_cover_mountain_data_size __asm("_binary_cover_mountain_data_size");
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
Before Width: | Height: | Size: 11 KiB |
@ -1,15 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern uint32_t _binary_cover_mountainfull_data_start __asm("_binary_cover_mountainfull_data_start");
|
|
||||||
extern uint32_t _binary_cover_mountainfull_data_end __asm("_binary_cover_mountainfull_data_end");
|
|
||||||
extern uint32_t _binary_cover_mountainfull_data_size __asm("_binary_cover_mountainfull_data_size");
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
Before Width: | Height: | Size: 8.8 KiB |
@ -1,15 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern uint32_t _binary_cover_redtree_data_start __asm("_binary_cover_redtree_data_start");
|
|
||||||
extern uint32_t _binary_cover_redtree_data_end __asm("_binary_cover_redtree_data_end");
|
|
||||||
extern uint32_t _binary_cover_redtree_data_size __asm("_binary_cover_redtree_data_size");
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
Before Width: | Height: | Size: 19 KiB |
@ -1,15 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern uint32_t _binary_cover_redtreefull_data_start __asm("_binary_cover_redtreefull_data_start");
|
|
||||||
extern uint32_t _binary_cover_redtreefull_data_end __asm("_binary_cover_redtreefull_data_end");
|
|
||||||
extern uint32_t _binary_cover_redtreefull_data_size __asm("_binary_cover_redtreefull_data_size");
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
Before Width: | Height: | Size: 513 KiB |
@ -1,15 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern uint32_t _binary_cover_silvertrees_data_start __asm("_binary_cover_silvertrees_data_start");
|
|
||||||
extern uint32_t _binary_cover_silvertrees_data_end __asm("_binary_cover_silvertrees_data_end");
|
|
||||||
extern uint32_t _binary_cover_silvertrees_data_size __asm("_binary_cover_silvertrees_data_size");
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
Before Width: | Height: | Size: 17 KiB |
@ -1,15 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern uint32_t _binary_cover_silvertreesfull_data_start __asm("_binary_cover_silvertreesfull_data_start");
|
|
||||||
extern uint32_t _binary_cover_silvertreesfull_data_end __asm("_binary_cover_silvertreesfull_data_end");
|
|
||||||
extern uint32_t _binary_cover_silvertreesfull_data_size __asm("_binary_cover_silvertreesfull_data_size");
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
Before Width: | Height: | Size: 433 KiB |
@ -1,15 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern uint32_t _binary_cover_thebeach_data_start __asm("_binary_cover_thebeach_data_start");
|
|
||||||
extern uint32_t _binary_cover_thebeach_data_end __asm("_binary_cover_thebeach_data_end");
|
|
||||||
extern uint32_t _binary_cover_thebeach_data_size __asm("_binary_cover_thebeach_data_size");
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
Before Width: | Height: | Size: 10 KiB |
@ -1,15 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern uint32_t _binary_cover_tree_data_start __asm("_binary_cover_tree_data_start");
|
|
||||||
extern uint32_t _binary_cover_tree_data_end __asm("_binary_cover_tree_data_end");
|
|
||||||
extern uint32_t _binary_cover_tree_data_size __asm("_binary_cover_tree_data_size");
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
BIN
cover/tree.png
Before Width: | Height: | Size: 10 KiB |
32
demo.mk
@ -1,6 +1,5 @@
|
|||||||
FONT_OBJ = \
|
FONT_OBJ = \
|
||||||
font/ter_u12n.data.o \
|
font/ter_u12n.data.o
|
||||||
font/ter_u32n.data.o
|
|
||||||
|
|
||||||
TEXTURE_OBJ = \
|
TEXTURE_OBJ = \
|
||||||
texture/igh25_box_top_32.data.o \
|
texture/igh25_box_top_32.data.o \
|
||||||
@ -22,7 +21,6 @@ TEXTURE_OBJ = \
|
|||||||
texture/turning/frame0006_128.data.o
|
texture/turning/frame0006_128.data.o
|
||||||
DEMO_OBJ = \
|
DEMO_OBJ = \
|
||||||
$(LIB)/holly/core.o \
|
$(LIB)/holly/core.o \
|
||||||
$(LIB)/holly/video_output.o \
|
|
||||||
$(LIB)/holly/region_array.o \
|
$(LIB)/holly/region_array.o \
|
||||||
$(LIB)/holly/background.o \
|
$(LIB)/holly/background.o \
|
||||||
$(LIB)/holly/ta_fifo_polygon_converter.o \
|
$(LIB)/holly/ta_fifo_polygon_converter.o \
|
||||||
@ -39,8 +37,6 @@ DEMO_OBJ = \
|
|||||||
src/platform/input.o \
|
src/platform/input.o \
|
||||||
src/platform/texture.o \
|
src/platform/texture.o \
|
||||||
src/platform/font.o \
|
src/platform/font.o \
|
||||||
src/platform/detect_emulator.o \
|
|
||||||
reference/reference_render.data.o \
|
|
||||||
src/demo/ballistics.o \
|
src/demo/ballistics.o \
|
||||||
src/demo/bridge.o \
|
src/demo/bridge.o \
|
||||||
src/demo/sailboat.o \
|
src/demo/sailboat.o \
|
||||||
@ -52,28 +48,7 @@ DEMO_OBJ = \
|
|||||||
src/physics/particle_contact.o \
|
src/physics/particle_contact.o \
|
||||||
src/physics/body.o \
|
src/physics/body.o \
|
||||||
src/physics/force_generator.o \
|
src/physics/force_generator.o \
|
||||||
src/physics/collide.o \
|
src/physics/collide.o
|
||||||
src/xm_player/sound.o \
|
|
||||||
src/xm_player/interpreter.o \
|
|
||||||
src/xm_player/playlist.o \
|
|
||||||
src/xm_player/cover.o \
|
|
||||||
src/xm_player/xm.o \
|
|
||||||
src/xm_player/malloc.o \
|
|
||||||
xm/CloudsAhead.xm.o \
|
|
||||||
xm/CottageFantasy.xm.o \
|
|
||||||
xm/ForestAtTwilight.xm.o \
|
|
||||||
xm/RedBlossom.xm.o \
|
|
||||||
xm/SpringWaltz.xm.o \
|
|
||||||
xm/SummerDreamsDemoTrackv4.xm.o \
|
|
||||||
xm/TheClockOfElery.xm.o \
|
|
||||||
xm/TheMountainsOfElmindeer.xm.o \
|
|
||||||
cover/clocks.data.o \
|
|
||||||
cover/mossycottage.data.o \
|
|
||||||
cover/mountain.data.o \
|
|
||||||
cover/thebeach.data.o \
|
|
||||||
cover/tree.data.o \
|
|
||||||
cover/redtree.data.o \
|
|
||||||
cover/silvertrees.data.o
|
|
||||||
|
|
||||||
demo.elf: LDSCRIPT = $(LIB)/main.lds
|
demo.elf: LDSCRIPT = $(LIB)/main.lds
|
||||||
demo.elf: $(START_OBJ) $(DEMO_OBJ) $(FONT_OBJ) $(TEXTURE_OBJ) $(LIBGCC)
|
demo.elf: $(START_OBJ) $(DEMO_OBJ) $(FONT_OBJ) $(TEXTURE_OBJ) $(LIBGCC)
|
||||||
@ -92,6 +67,3 @@ texture/turning/%.data: texture/turning/%.png
|
|||||||
|
|
||||||
font/ter_u12n.data:
|
font/ter_u12n.data:
|
||||||
$(LIB)/tools/ttf_bitmap2 20 7f 128 64 /usr/share/fonts/terminus/ter-u12n.otb $@ > /dev/null
|
$(LIB)/tools/ttf_bitmap2 20 7f 128 64 /usr/share/fonts/terminus/ter-u12n.otb $@ > /dev/null
|
||||||
|
|
||||||
font/ter_u32n.data:
|
|
||||||
$(LIB)/tools/ttf_bitmap2 20 7f 256 256 /usr/share/fonts/terminus/ter-u32n.otb $@ > /dev/null
|
|
||||||
|
@ -1,15 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern uint32_t _binary_font_ter_u32n_data_start __asm("_binary_font_ter_u32n_data_start");
|
|
||||||
extern uint32_t _binary_font_ter_u32n_data_end __asm("_binary_font_ter_u32n_data_end");
|
|
||||||
extern uint32_t _binary_font_ter_u32n_data_size __asm("_binary_font_ter_u32n_data_size");
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
@ -1,15 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern uint32_t _binary_reference_reference_render_data_start __asm("_binary_reference_reference_render_data_start");
|
|
||||||
extern uint32_t _binary_reference_reference_render_data_end __asm("_binary_reference_reference_render_data_end");
|
|
||||||
extern uint32_t _binary_reference_reference_render_data_size __asm("_binary_reference_reference_render_data_size");
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
@ -25,10 +25,10 @@ namespace demo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
mat4x4 view_trans
|
mat4x4 view_trans
|
||||||
= translate(vec3(0.5, -0.5, 0.75))
|
= translate(vec3(-0.5, 0.5, 0.75))
|
||||||
* rotate_x(-pi / 4)
|
* rotate_x(pi / 4)
|
||||||
* rotate_y(-pi / 4)
|
* rotate_y(pi / 4)
|
||||||
* scale(vec3(1, 1, 1));
|
* scale(vec3(-1, -1, 1));
|
||||||
|
|
||||||
return view_trans;
|
return view_trans;
|
||||||
}
|
}
|
||||||
|
@ -86,9 +86,9 @@ namespace demo {
|
|||||||
|
|
||||||
mat4x4 view_trans
|
mat4x4 view_trans
|
||||||
= translate(vec3(0.0, 0.0, 0.5))
|
= translate(vec3(0.0, 0.0, 0.5))
|
||||||
* rotate_x(-pi / 4)
|
* rotate_x(pi / 4)
|
||||||
* rotate_y(-pi / 12)
|
* rotate_y(pi / 12)
|
||||||
* scale(vec3(1, 1, 1));
|
* scale(vec3(-1, -1, 1));
|
||||||
|
|
||||||
return view_trans;
|
return view_trans;
|
||||||
}
|
}
|
||||||
|
@ -3,15 +3,12 @@
|
|||||||
|
|
||||||
#include "platform/graphics_primitive.hpp"
|
#include "platform/graphics_primitive.hpp"
|
||||||
#include "platform/font.hpp"
|
#include "platform/font.hpp"
|
||||||
#include "platform/emulator_detected.hpp"
|
|
||||||
|
|
||||||
#include "demo/lizard/main.hpp"
|
#include "demo/lizard/main.hpp"
|
||||||
#include "demo/lizard/levels.hpp"
|
#include "demo/lizard/levels.hpp"
|
||||||
|
|
||||||
#include "texture/igh25_box_top_32.data.h"
|
#include "texture/igh25_box_top_32.data.h"
|
||||||
|
|
||||||
#include "xm_player/playlist.hpp"
|
|
||||||
|
|
||||||
#include "assert.h"
|
#include "assert.h"
|
||||||
|
|
||||||
extern float alpha_mul;
|
extern float alpha_mul;
|
||||||
@ -48,43 +45,18 @@ namespace demo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
world::platform * find_end_platform(world::level& level)
|
|
||||||
{
|
|
||||||
float end_x = 81;
|
|
||||||
float end_z = 212;
|
|
||||||
for (int i = 0; i < level.platforms_length; i++) {
|
|
||||||
world::platform * p = &level.platforms[i];
|
|
||||||
if (p->position.x == end_x && p->position.z == end_z) {
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
mat4x4 lizard::init()
|
mat4x4 lizard::init()
|
||||||
{
|
{
|
||||||
platform_touch_count = 0;
|
vx = 0;
|
||||||
|
vy = 0;
|
||||||
|
|
||||||
vx = -pi / 3.5;
|
current_level = &demo::level1_level;
|
||||||
vy = -pi / 8;
|
|
||||||
|
|
||||||
current_level = &demo::igh25_map1_level;
|
|
||||||
|
|
||||||
world::table_build(*current_level);
|
world::table_build(*current_level);
|
||||||
end_platform = find_end_platform(*current_level);
|
|
||||||
|
|
||||||
lizard_position = {2.5, 1, 2.5};
|
lizard_position = {7.5, 1, 7.5};
|
||||||
//lizard_position = {218.5, 0, 65.5};
|
|
||||||
//lizard_position = {81, 100, 212};
|
|
||||||
lizard_velocity = {0, 0, 0};
|
lizard_velocity = {0, 0, 0};
|
||||||
|
|
||||||
if (!emulator_detected) {
|
|
||||||
emulator_detected_hud_frames = 60 * 30;
|
|
||||||
playlist::next();
|
|
||||||
} else {
|
|
||||||
emulator_detected_hud_frames = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return view_trans;
|
return view_trans;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -98,48 +70,40 @@ namespace demo {
|
|||||||
|
|
||||||
void lizard::update()
|
void lizard::update()
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
if (!collided)
|
||||||
|
lizard_velocity.y -= 0.01;
|
||||||
|
*/
|
||||||
lizard_rotation *= 0.8;
|
lizard_rotation *= 0.8;
|
||||||
|
|
||||||
lizard_turning_frame += lizard_rotation * 5;
|
lizard_turning_frame += lizard_rotation * 10;
|
||||||
|
|
||||||
lizard_heading += lizard_rotation;
|
lizard_heading += lizard_rotation;
|
||||||
|
|
||||||
if (abs(lizard_velocity.x) > 0.10)
|
if (abs(lizard_velocity.x) > 0.05)
|
||||||
lizard_velocity.x = 0.10 * sign(lizard_velocity.x);
|
lizard_velocity.x = 0.05 * sign(lizard_velocity.x);
|
||||||
if (abs(lizard_velocity.y) > 0.20)
|
if (abs(lizard_velocity.y) > 0.05)
|
||||||
lizard_velocity.y = 0.20 * sign(lizard_velocity.y);
|
lizard_velocity.y = 0.05 * sign(lizard_velocity.y);
|
||||||
if (abs(lizard_velocity.z) > 0.10)
|
if (abs(lizard_velocity.z) > 0.05)
|
||||||
lizard_velocity.z = 0.10 * sign(lizard_velocity.z);
|
lizard_velocity.z = 0.05 * sign(lizard_velocity.z);
|
||||||
|
|
||||||
lizard_velocity.x *= 0.8;
|
lizard_velocity.x *= 0.8;
|
||||||
lizard_velocity.y *= 0.99;
|
lizard_velocity.y *= 0.8;
|
||||||
lizard_velocity.z *= 0.8;
|
lizard_velocity.z *= 0.8;
|
||||||
|
|
||||||
vec2 frame_velocity = vec2(lizard_velocity.x, lizard_velocity.z);
|
lizard_walking_frame += magnitude(lizard_velocity) * 15;
|
||||||
lizard_walking_frame += magnitude(frame_velocity) * 5;
|
|
||||||
|
|
||||||
world::platform * p = lizard_collide();
|
|
||||||
collided = (p != nullptr);
|
|
||||||
if (!collided) {
|
|
||||||
lizard_velocity.y -= 0.01;
|
|
||||||
} else {
|
|
||||||
if (p->touched == false) {
|
|
||||||
platform_touch_count += 1;
|
|
||||||
last_platform1 = last_platform;
|
|
||||||
last_platform = p;
|
|
||||||
}
|
|
||||||
|
|
||||||
p->touched = true;
|
|
||||||
//lizard_position.y -= -lizard_velocity.y;
|
|
||||||
float pp = p->position.y + p->scale.y * 0.5;
|
|
||||||
//lizard_velocity.y *= 0.1;
|
|
||||||
lizard_position.y = pp + 0.5;
|
|
||||||
}
|
|
||||||
|
|
||||||
lizard_position.x += lizard_velocity.x;
|
lizard_position.x += lizard_velocity.x;
|
||||||
lizard_position.y += lizard_velocity.y;
|
lizard_position.y += lizard_velocity.y;
|
||||||
lizard_position.z += lizard_velocity.z;
|
lizard_position.z += lizard_velocity.z;
|
||||||
|
|
||||||
|
world::platform * p = lizard_collide();
|
||||||
|
collided = p != nullptr;
|
||||||
|
|
||||||
|
if (collided) {
|
||||||
|
lizard_position.y -= -lizard_velocity.y;
|
||||||
|
}
|
||||||
|
|
||||||
view_trans
|
view_trans
|
||||||
= translate(vec3(0, 0, 3))
|
= translate(vec3(0, 0, 3))
|
||||||
* rotate_x(vy)
|
* rotate_x(vy)
|
||||||
@ -149,75 +113,35 @@ namespace demo {
|
|||||||
|
|
||||||
void lizard::y()
|
void lizard::y()
|
||||||
{
|
{
|
||||||
lizard_velocity = {0, 0, 0};
|
lizard_velocity.y += 0.01;
|
||||||
if (last_platform1 == nullptr) {
|
|
||||||
lizard_position = {2.5, 1, 2.5};
|
|
||||||
} else {
|
|
||||||
lizard_position = last_platform1->position;
|
|
||||||
lizard_position.y += 0.5;
|
|
||||||
if (last_platform->touched == true)
|
|
||||||
platform_touch_count -= 1;
|
|
||||||
last_platform->touched = false;
|
|
||||||
last_platform = last_platform1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void lizard::a()
|
void lizard::a()
|
||||||
{
|
{
|
||||||
//lizard_velocity.y -= 0.01;
|
lizard_velocity.y -= 0.01;
|
||||||
if (collided) {
|
|
||||||
lizard_velocity.y = 30;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void lizard::start()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void lizard::ra()
|
|
||||||
{
|
|
||||||
vx += 0.01f;
|
|
||||||
}
|
|
||||||
|
|
||||||
void lizard::la()
|
|
||||||
{
|
|
||||||
vx -= 0.01f;
|
|
||||||
}
|
|
||||||
|
|
||||||
void lizard::ua()
|
|
||||||
{
|
|
||||||
vy += 0.01f;
|
|
||||||
}
|
|
||||||
|
|
||||||
void lizard::da()
|
|
||||||
{
|
|
||||||
vy -= 0.01f;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void lizard::x()
|
void lizard::x()
|
||||||
{
|
{
|
||||||
//lizard_rotation += pi * (1.0f / 160);
|
lizard_rotation += pi * (1.0f / 160);
|
||||||
}
|
}
|
||||||
|
|
||||||
void lizard::b()
|
void lizard::b()
|
||||||
{
|
{
|
||||||
//lizard_rotation -= pi * (1.0f / 160);
|
lizard_rotation -= pi * (1.0f / 160);
|
||||||
}
|
}
|
||||||
|
|
||||||
void lizard::analog(float dl, float dr, float dx, float dy)
|
void lizard::analog(float dl, float dr, float dx, float dy)
|
||||||
{
|
{
|
||||||
//float forward = (dr - dl) * -0.001f;
|
//float forward = (dr - dl) * -0.001f;
|
||||||
//alpha_mul += forward;
|
//alpha_mul += forward;
|
||||||
float forward = (dr - dl) * -0.1f;
|
float forward = (dr - dl) * -0.04f;
|
||||||
//vx += forward * 0.5f;
|
|
||||||
|
|
||||||
lizard_velocity.x += -cos(lizard_heading) * forward;
|
lizard_velocity.x += -cos(lizard_heading) * forward;
|
||||||
lizard_velocity.z += sin(lizard_heading) * forward;
|
lizard_velocity.z += sin(lizard_heading) * forward;
|
||||||
|
|
||||||
lizard_rotation += -dx * 0.03f;
|
vy += dy * 0.03f;
|
||||||
|
vx += dx * 0.03f;
|
||||||
//vy += dy * 0.03f;
|
|
||||||
//vx += dx * 0.03f;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
world::platform * lizard::lizard_collide()
|
world::platform * lizard::lizard_collide()
|
||||||
@ -238,113 +162,39 @@ namespace demo {
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char * emulator_speech[] = {
|
|
||||||
"This counterfeit Dreamcast failed a",
|
|
||||||
"CORE rasterization test.",
|
|
||||||
"",
|
|
||||||
"Dreamcast emulator behavior is highly",
|
|
||||||
"divergent from genuine Sega Dreamcast",
|
|
||||||
"hardware.",
|
|
||||||
"",
|
|
||||||
"Some emulator authors deliberately",
|
|
||||||
"choose to forgo accuracy, and instead ",
|
|
||||||
"develop a distinct and unrelated",
|
|
||||||
"fantasy-platform."
|
|
||||||
};
|
|
||||||
const int emulator_speech_lines = (sizeof (emulator_speech)) / (sizeof (emulator_speech[0]));
|
|
||||||
|
|
||||||
void lizard::draw_hud(ta_parameter_writer& writer)
|
void lizard::draw_hud(ta_parameter_writer& writer)
|
||||||
{
|
{
|
||||||
|
const int title_length = 8;
|
||||||
|
const int title_width_2 = (font::ter_u12n.hori_advance * title_length) >> 1;
|
||||||
const int framebuffer_width_2 = framebuffer::framebuffer.px_width >> 1;
|
const int framebuffer_width_2 = framebuffer::framebuffer.px_width >> 1;
|
||||||
const int framebuffer_height_2 = framebuffer::framebuffer.px_height >> 1;
|
const int x = framebuffer_width_2 - title_width_2;
|
||||||
vec3 center_p = vec3(0, 5, 10);
|
vec3 center_p = vec3(x, 5, 10);
|
||||||
|
|
||||||
font::ter_u12n.global(writer);
|
font::ter_u12n.global(writer);
|
||||||
{
|
font::ter_u12n.draw_string(writer, center_p, "platform", 0xffffffff);
|
||||||
const int title_length = 12;
|
|
||||||
const int title_width_2 = (font::ter_u12n.hori_advance * title_length) >> 1;
|
vec3 status_p = vec3(10, 10, 10);
|
||||||
const int x = framebuffer_width_2 - title_width_2;
|
/*
|
||||||
center_p.x = x;
|
if (collided)
|
||||||
//font::ter_u12n.draw_string(writer, center_p, "demo: lizard", 0xffffffff);
|
font::ter_u12n.draw_string(writer, status_p, "collide", 0xffffffff);
|
||||||
}
|
else
|
||||||
//center_p.y += font::ter_u12n.height;
|
font::ter_u12n.draw_string(writer, status_p, "air", 0xffffffff);
|
||||||
{
|
*/
|
||||||
const int title_length = 46;
|
|
||||||
const int title_width_2 = (font::ter_u12n.hori_advance * title_length) >> 1;
|
font::ter_u12n.draw_float(writer, status_p, (float)last_drawn_frame, 0xffffffff, 10);
|
||||||
const int x = framebuffer_width_2 - title_width_2;
|
|
||||||
center_p.x = x;
|
|
||||||
font::ter_u12n.draw_string(writer, center_p, "objective: find and touch the glowing platform", 0xffffffff);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
vec3 status_p = vec3(10, framebuffer::framebuffer.px_height - 24, 10);
|
void lizard::draw_platform(ta_parameter_writer& writer, const mat4x4& trans, const world::platform& p)
|
||||||
font::ter_u12n.draw_string(writer, status_p, "score:", 0xffffffff);
|
|
||||||
//font::ter_u12n.draw_float(writer, status_p, (float)last_drawn_frame, 0xffffffff, 10);
|
|
||||||
status_p.x += font::ter_u12n.hori_advance * 7;
|
|
||||||
font::ter_u12n.draw_int(writer, status_p, (float)platform_touch_count, 0xffffffff, 4);
|
|
||||||
|
|
||||||
const int height_2 = (font::ter_u32n.height * (emulator_speech_lines + 2)) >> 1;
|
|
||||||
const int y = framebuffer_height_2 - height_2;
|
|
||||||
vec3 center_e = vec3(8, y, 10);
|
|
||||||
if (emulator_detected_hud_frames < 60 * 30) {
|
|
||||||
font::ter_u32n.global(writer);;
|
|
||||||
for (int i = 0; i < emulator_speech_lines; i++) {
|
|
||||||
font::ter_u32n.draw_string(writer, center_e, emulator_speech[i], 0xffffffff);
|
|
||||||
font::ter_u32n.draw_string(writer, {center_e.x + 2, center_e.y + 0, center_e.z - 1}, emulator_speech[i], 0x00000000);
|
|
||||||
font::ter_u32n.draw_string(writer, {center_e.x - 2, center_e.y + 0, center_e.z - 1}, emulator_speech[i], 0x00000000);
|
|
||||||
font::ter_u32n.draw_string(writer, {center_e.x + 0, center_e.y + 2, center_e.z - 1}, emulator_speech[i], 0x00000000);
|
|
||||||
font::ter_u32n.draw_string(writer, {center_e.x + 0, center_e.y - 2, center_e.z - 1}, emulator_speech[i], 0x00000000);
|
|
||||||
center_e.y += font::ter_u32n.height;
|
|
||||||
}
|
|
||||||
center_e.y += font::ter_u32n.height;
|
|
||||||
int timeout = 30 - (emulator_detected_hud_frames / 60);
|
|
||||||
font::ter_u32n.draw_int(writer, center_e, timeout, 0xffffffff, 0);
|
|
||||||
emulator_detected_hud_frames += 1;
|
|
||||||
if (emulator_detected_hud_frames >= 60 * 30) {
|
|
||||||
playlist::next();
|
|
||||||
}
|
|
||||||
} else if (end_platform != nullptr && end_platform->touched) {
|
|
||||||
font::ter_u32n.global(writer);
|
|
||||||
const int title_length = 18;
|
|
||||||
const int title_width_2 = (font::ter_u12n.hori_advance * title_length) >> 1;
|
|
||||||
const int x = framebuffer_width_2 - title_width_2;
|
|
||||||
center_e.x = x;
|
|
||||||
|
|
||||||
const char * s = "objective complete";
|
|
||||||
font::ter_u32n.draw_string(writer, center_e, s, 0xffffffff);
|
|
||||||
font::ter_u32n.draw_string(writer, {center_e.x + 2, center_e.y + 0, center_e.z - 1}, s, 0x00000000);
|
|
||||||
font::ter_u32n.draw_string(writer, {center_e.x - 2, center_e.y + 0, center_e.z - 1}, s, 0x00000000);
|
|
||||||
font::ter_u32n.draw_string(writer, {center_e.x + 0, center_e.y + 2, center_e.z - 1}, s, 0x00000000);
|
|
||||||
font::ter_u32n.draw_string(writer, {center_e.x + 0, center_e.y - 2, center_e.z - 1}, s, 0x00000000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void lizard::draw_platform(ta_parameter_writer& writer, const mat4x4& trans, const world::platform * p)
|
|
||||||
{
|
{
|
||||||
mat4x4 t
|
mat4x4 t
|
||||||
= trans
|
= trans
|
||||||
* translate(p->position)
|
* translate(p.position)
|
||||||
* scale(p->scale);
|
* scale(p.scale);
|
||||||
|
|
||||||
float intensity_offset;
|
|
||||||
vec3 base_color;
|
|
||||||
if (p == end_platform) {
|
|
||||||
base_color = vec3(0.5, 1, 0.5);
|
|
||||||
intensity_offset = sin(end_platform_tick * 0.1f) * 0.4f + 0.5f;
|
|
||||||
end_platform_tick += 1;
|
|
||||||
} else if (p->touched) {
|
|
||||||
intensity_offset = 0.5;
|
|
||||||
base_color = vec3(1, 1, 1);
|
|
||||||
} else {
|
|
||||||
intensity_offset = 0;
|
|
||||||
base_color = vec3(1, 0.5, 0.5);
|
|
||||||
}
|
|
||||||
|
|
||||||
draw_textured_cube(writer,
|
draw_textured_cube(writer,
|
||||||
t,
|
t,
|
||||||
p->scale,
|
p.scale,
|
||||||
texture::cube_type_1,
|
texture::cube_type_1);
|
||||||
base_color,
|
|
||||||
intensity_offset);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void lizard::draw_lizard(ta_parameter_writer& writer, const mat4x4& trans)
|
void lizard::draw_lizard(ta_parameter_writer& writer, const mat4x4& trans)
|
||||||
@ -359,7 +209,7 @@ namespace demo {
|
|||||||
t,
|
t,
|
||||||
vec3(1, 0.5, 0));
|
vec3(1, 0.5, 0));
|
||||||
*/
|
*/
|
||||||
if (abs(lizard_rotation) > 0.01) {
|
if (abs(lizard_rotation) > 0) {
|
||||||
int frame = ((int)lizard_turning_frame) % lizard_turning_frames_count;
|
int frame = ((int)lizard_turning_frame) % lizard_turning_frames_count;
|
||||||
if (frame < 0)
|
if (frame < 0)
|
||||||
frame = lizard_turning_frames_count + frame;
|
frame = lizard_turning_frames_count + frame;
|
||||||
@ -380,56 +230,15 @@ namespace demo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void lizard::draw_cover(ta_parameter_writer& writer, const mat4x4& trans)
|
|
||||||
{
|
|
||||||
mat4x4 t
|
|
||||||
= trans
|
|
||||||
* translate(lizard_position)
|
|
||||||
* scale(1000.f);
|
|
||||||
|
|
||||||
int texture_offset = playlist::playlist[playlist::state.playlist_ix].cover_ix;
|
|
||||||
if (cover_ix_transition >= 1.0) {
|
|
||||||
if (texture_offset != last_cover_texture_offset) {
|
|
||||||
cover_ix_transition = 0.0;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
cover_ix_transition += 0.001f;
|
|
||||||
if (cover_ix_transition >= 1.0) {
|
|
||||||
last_cover_texture_offset = texture_offset;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
draw_textured_cube2(writer, t, last_cover_texture_offset, texture_offset, cover_ix_transition);
|
|
||||||
}
|
|
||||||
|
|
||||||
void lizard::draw(ta_parameter_writer& writer, const mat4x4& _)
|
void lizard::draw(ta_parameter_writer& writer, const mat4x4& _)
|
||||||
{
|
{
|
||||||
// punch through
|
// punch through
|
||||||
const mat4x4& trans = view_trans;
|
const mat4x4& trans = view_trans;
|
||||||
|
|
||||||
draw_hud(writer);
|
draw_hud(writer);
|
||||||
|
|
||||||
draw_lizard(writer, trans);
|
draw_lizard(writer, trans);
|
||||||
|
|
||||||
writer.append<ta_global_parameter::end_of_list>() =
|
|
||||||
ta_global_parameter::end_of_list(para_control::para_type::end_of_list);
|
|
||||||
|
|
||||||
// opaque modifier
|
|
||||||
|
|
||||||
mat4x4 t
|
|
||||||
= trans
|
|
||||||
* translate(lizard_position)
|
|
||||||
* rotate_y(lizard_heading)
|
|
||||||
* scale(vec3(1.0, 1.0, 1.0));
|
|
||||||
|
|
||||||
draw_lizard_mv(writer,
|
|
||||||
t);
|
|
||||||
|
|
||||||
writer.append<ta_global_parameter::end_of_list>() =
|
|
||||||
ta_global_parameter::end_of_list(para_control::para_type::end_of_list);
|
|
||||||
|
|
||||||
// translucent
|
|
||||||
|
|
||||||
draw_cover(writer, trans);
|
|
||||||
|
|
||||||
writer.append<ta_global_parameter::end_of_list>() =
|
writer.append<ta_global_parameter::end_of_list>() =
|
||||||
ta_global_parameter::end_of_list(para_control::para_type::end_of_list);
|
ta_global_parameter::end_of_list(para_control::para_type::end_of_list);
|
||||||
|
|
||||||
@ -438,7 +247,7 @@ namespace demo {
|
|||||||
//draw_axis(writer, trans * translate(lizard_position));
|
//draw_axis(writer, trans * translate(lizard_position));
|
||||||
|
|
||||||
for (int i = 0; i < current_level->platforms_length; i++) {
|
for (int i = 0; i < current_level->platforms_length; i++) {
|
||||||
draw_platform(writer, trans, ¤t_level->platforms[i]);
|
draw_platform(writer, trans, current_level->platforms[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
writer.append<ta_global_parameter::end_of_list>() =
|
writer.append<ta_global_parameter::end_of_list>() =
|
||||||
|
@ -7,22 +7,13 @@ namespace demo {
|
|||||||
|
|
||||||
struct lizard : scene {
|
struct lizard : scene {
|
||||||
world::level * current_level;
|
world::level * current_level;
|
||||||
world::platform * last_platform1;
|
|
||||||
world::platform * last_platform;
|
|
||||||
world::platform * end_platform;
|
|
||||||
vec3 lizard_position;
|
vec3 lizard_position;
|
||||||
vec3 lizard_velocity;
|
vec3 lizard_velocity;
|
||||||
float lizard_heading;
|
float lizard_heading;
|
||||||
float lizard_rotation;
|
float lizard_rotation;
|
||||||
float lizard_walking_frame;
|
float lizard_walking_frame;
|
||||||
float lizard_turning_frame;
|
float lizard_turning_frame;
|
||||||
int platform_touch_count;
|
|
||||||
int end_platform_tick;
|
|
||||||
|
|
||||||
int last_cover_texture_offset;
|
|
||||||
float cover_ix_transition;
|
|
||||||
|
|
||||||
int emulator_detected_hud_frames;
|
|
||||||
bool collided;
|
bool collided;
|
||||||
|
|
||||||
mat4x4 view_trans;
|
mat4x4 view_trans;
|
||||||
@ -39,21 +30,13 @@ namespace demo {
|
|||||||
void b() override;
|
void b() override;
|
||||||
void a() override;
|
void a() override;
|
||||||
|
|
||||||
void ra() override;
|
|
||||||
void la() override;
|
|
||||||
void ua() override;
|
|
||||||
void da() override;
|
|
||||||
|
|
||||||
void start() override;
|
|
||||||
|
|
||||||
void analog(float dl, float dr, float dx, float dy) override;
|
void analog(float dl, float dr, float dx, float dy) override;
|
||||||
|
|
||||||
world::platform * lizard_collide();
|
world::platform * lizard_collide();
|
||||||
|
|
||||||
void draw_hud(ta_parameter_writer& writer);
|
void draw_hud(ta_parameter_writer& writer);
|
||||||
void draw_platform(ta_parameter_writer& writer, const mat4x4& trans, const world::platform * p);
|
void draw_platform(ta_parameter_writer& writer, const mat4x4& trans, const world::platform& p);
|
||||||
void draw_lizard(ta_parameter_writer& writer, const mat4x4& trans);
|
void draw_lizard(ta_parameter_writer& writer, const mat4x4& trans);
|
||||||
void draw_cover(ta_parameter_writer& writer, const mat4x4& trans);
|
|
||||||
void draw(ta_parameter_writer& writer, const mat4x4& trans) override;
|
void draw(ta_parameter_writer& writer, const mat4x4& trans) override;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
Before Width: | Height: | Size: 15 KiB |
@ -79,7 +79,6 @@ namespace demo::world {
|
|||||||
int scale_z = (int)level.platforms[i].scale.z;
|
int scale_z = (int)level.platforms[i].scale.z;
|
||||||
float scale_x_2 = level.platforms[i].scale.x * 0.5;
|
float scale_x_2 = level.platforms[i].scale.x * 0.5;
|
||||||
float scale_z_2 = level.platforms[i].scale.z * 0.5;
|
float scale_z_2 = level.platforms[i].scale.z * 0.5;
|
||||||
level.platforms[i].touched = false;
|
|
||||||
|
|
||||||
for (int xo = 0; xo < scale_x; xo++) {
|
for (int xo = 0; xo < scale_x; xo++) {
|
||||||
for (int zo = 0; zo < scale_z; zo++) {
|
for (int zo = 0; zo < scale_z; zo++) {
|
||||||
|
@ -9,7 +9,6 @@ namespace demo::world {
|
|||||||
struct platform {
|
struct platform {
|
||||||
vec3 position;
|
vec3 position;
|
||||||
vec3 scale;
|
vec3 scale;
|
||||||
bool touched;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct level {
|
struct level {
|
||||||
@ -17,7 +16,7 @@ namespace demo::world {
|
|||||||
int platforms_length;
|
int platforms_length;
|
||||||
};
|
};
|
||||||
|
|
||||||
constexpr int lookup_table_dim = 256;
|
constexpr int lookup_table_dim = 128;
|
||||||
|
|
||||||
struct platform_lookup {
|
struct platform_lookup {
|
||||||
vec2i xz_offset;
|
vec2i xz_offset;
|
||||||
|
@ -16,7 +16,6 @@ namespace demo {
|
|||||||
virtual void la() {}
|
virtual void la() {}
|
||||||
virtual void da() {}
|
virtual void da() {}
|
||||||
virtual void ua() {}
|
virtual void ua() {}
|
||||||
virtual void start() {}
|
|
||||||
virtual void update() = 0;
|
virtual void update() = 0;
|
||||||
virtual void draw(ta_parameter_writer& writer, const mat4x4& trans) = 0;
|
virtual void draw(ta_parameter_writer& writer, const mat4x4& trans) = 0;
|
||||||
};
|
};
|
||||||
|
@ -1,254 +0,0 @@
|
|||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#include "memorymap.hpp"
|
|
||||||
|
|
||||||
#include "holly/background.hpp"
|
|
||||||
#include "holly/core.hpp"
|
|
||||||
#include "holly/isp_tsp.hpp"
|
|
||||||
#include "holly/object_list_data.hpp"
|
|
||||||
#include "holly/region_array.hpp"
|
|
||||||
#include "holly/texture_memory_alloc9.hpp"
|
|
||||||
|
|
||||||
#include "math/float_types.hpp"
|
|
||||||
|
|
||||||
#include "reference/reference_render.data.h"
|
|
||||||
|
|
||||||
const struct opb_size opb_size = { .opaque = 0
|
|
||||||
, .opaque_modifier = 8 * 4
|
|
||||||
, .translucent = 0
|
|
||||||
, .translucent_modifier = 0
|
|
||||||
, .punch_through = 8 * 4
|
|
||||||
};
|
|
||||||
|
|
||||||
static const int framebuffer_width = 32;
|
|
||||||
static const int framebuffer_height = 32;
|
|
||||||
static const int tile_width = framebuffer_width / 32;
|
|
||||||
static const int tile_height = framebuffer_height / 32;
|
|
||||||
|
|
||||||
struct triangle_parameter_vertex {
|
|
||||||
float x;
|
|
||||||
float y;
|
|
||||||
float z;
|
|
||||||
uint32_t color1;
|
|
||||||
uint32_t color2;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct triangle_parameter {
|
|
||||||
uint32_t isp_tsp_instruction_word;
|
|
||||||
uint32_t tsp_instruction_word_0;
|
|
||||||
uint32_t texture_control_word_0;
|
|
||||||
uint32_t tsp_instruction_word_1;
|
|
||||||
uint32_t texture_control_word_1;
|
|
||||||
triangle_parameter_vertex a;
|
|
||||||
triangle_parameter_vertex b;
|
|
||||||
triangle_parameter_vertex c;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct modifier_volume_parameter_vertex {
|
|
||||||
float x;
|
|
||||||
float y;
|
|
||||||
float z;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct modifier_volume_parameter {
|
|
||||||
uint32_t isp_tsp_instruction_word;
|
|
||||||
uint32_t pad1;
|
|
||||||
uint32_t pad2;
|
|
||||||
modifier_volume_parameter_vertex a;
|
|
||||||
modifier_volume_parameter_vertex b;
|
|
||||||
modifier_volume_parameter_vertex c;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <int N>
|
|
||||||
struct object_pointer_block {
|
|
||||||
uint32_t pointer[N];
|
|
||||||
};
|
|
||||||
static_assert((sizeof (object_pointer_block<8>)) == 32);
|
|
||||||
|
|
||||||
using vec2i = vec<2, int>;
|
|
||||||
|
|
||||||
static const int opaque_modifier_start = 0;
|
|
||||||
static const int punch_through_start = (sizeof (triangle_parameter));
|
|
||||||
|
|
||||||
static volatile uint8_t * const object_list = (volatile uint8_t *)(&texture_memory32[texture_memory_alloc.object_list.start / 4]);
|
|
||||||
static volatile uint8_t * const isp_tsp_parameters = (volatile uint8_t *)(&texture_memory32[texture_memory_alloc.isp_tsp_parameters.start / 4]);
|
|
||||||
|
|
||||||
static inline void transfer_object_list(volatile uint8_t * mem)
|
|
||||||
{
|
|
||||||
auto blocks = reinterpret_cast<volatile object_pointer_block<8> *>(mem);
|
|
||||||
|
|
||||||
{ // opaque modifier
|
|
||||||
auto& block = blocks[0];
|
|
||||||
block.pointer[0] = object_list_data::pointer_type::triangle_array
|
|
||||||
| object_list_data::triangle_array::number_of_triangles(0)
|
|
||||||
| object_list_data::triangle_array::skip(0)
|
|
||||||
| object_list_data::triangle_array::start(opaque_modifier_start / 4);
|
|
||||||
|
|
||||||
block.pointer[1] = object_list_data::pointer_type::object_pointer_block_link
|
|
||||||
| object_list_data::object_pointer_block_link::end_of_list;
|
|
||||||
}
|
|
||||||
|
|
||||||
{ // punch through
|
|
||||||
auto& block = blocks[1];
|
|
||||||
block.pointer[0] = object_list_data::pointer_type::triangle_array
|
|
||||||
| object_list_data::triangle_array::number_of_triangles(0)
|
|
||||||
| object_list_data::triangle_array::shadow
|
|
||||||
| object_list_data::triangle_array::skip(1)
|
|
||||||
| object_list_data::triangle_array::start(punch_through_start / 4);
|
|
||||||
|
|
||||||
block.pointer[1] = object_list_data::pointer_type::object_pointer_block_link
|
|
||||||
| object_list_data::object_pointer_block_link::end_of_list;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void transfer_isp_tsp_parameters(volatile uint8_t * mem,
|
|
||||||
const vec3& ap, const vec2i& ac,
|
|
||||||
const vec3& bp, const vec2i& bc,
|
|
||||||
const vec3& cp, const vec2i& cc)
|
|
||||||
{
|
|
||||||
auto params = reinterpret_cast<volatile triangle_parameter *>(mem);
|
|
||||||
params->isp_tsp_instruction_word = isp_tsp_instruction_word::depth_compare_mode::greater
|
|
||||||
| isp_tsp_instruction_word::culling_mode::no_culling
|
|
||||||
| isp_tsp_instruction_word::gouraud_shading;
|
|
||||||
|
|
||||||
params->tsp_instruction_word_0 = tsp_instruction_word::src_alpha_instr::one
|
|
||||||
| tsp_instruction_word::dst_alpha_instr::zero
|
|
||||||
| tsp_instruction_word::fog_control::no_fog;
|
|
||||||
|
|
||||||
params->texture_control_word_0 = 0;
|
|
||||||
|
|
||||||
params->tsp_instruction_word_1 = tsp_instruction_word::src_alpha_instr::one
|
|
||||||
| tsp_instruction_word::dst_alpha_instr::one
|
|
||||||
| tsp_instruction_word::fog_control::no_fog;
|
|
||||||
|
|
||||||
params->texture_control_word_1 = 0;
|
|
||||||
|
|
||||||
params->a.x = ap.x;
|
|
||||||
params->a.y = ap.y;
|
|
||||||
params->a.z = ap.z;
|
|
||||||
params->a.color1 = ac.x;
|
|
||||||
params->a.color2 = ac.y;
|
|
||||||
|
|
||||||
params->b.x = bp.x;
|
|
||||||
params->b.y = bp.y;
|
|
||||||
params->b.z = bp.z;
|
|
||||||
params->b.color1 = bc.x;
|
|
||||||
params->b.color2 = bc.y;
|
|
||||||
|
|
||||||
params->c.x = cp.x;
|
|
||||||
params->c.y = cp.y;
|
|
||||||
params->c.z = cp.z;
|
|
||||||
params->c.color1 = cc.x;
|
|
||||||
params->c.color2 = cc.y;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void transfer_modifier_volume_isp_tsp_parameters(volatile uint8_t * mem,
|
|
||||||
const vec3& ap,
|
|
||||||
const vec3& bp,
|
|
||||||
const vec3& cp)
|
|
||||||
{
|
|
||||||
auto params = reinterpret_cast<volatile modifier_volume_parameter *>(mem);
|
|
||||||
params->isp_tsp_instruction_word = isp_tsp_instruction_word::volume_instruction::inside_last_polygon
|
|
||||||
| isp_tsp_instruction_word::culling_mode::no_culling;
|
|
||||||
|
|
||||||
params->pad1 = 0;
|
|
||||||
params->pad2 = 0;
|
|
||||||
|
|
||||||
params->a.x = ap.x;
|
|
||||||
params->a.y = ap.y;
|
|
||||||
params->a.z = ap.z;
|
|
||||||
|
|
||||||
params->b.x = bp.x;
|
|
||||||
params->b.y = bp.y;
|
|
||||||
params->b.z = bp.z;
|
|
||||||
|
|
||||||
params->c.x = cp.x;
|
|
||||||
params->c.y = cp.y;
|
|
||||||
params->c.z = cp.z;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void transfer_punch_through()
|
|
||||||
{
|
|
||||||
vec3 ap = {18.2192f, 1.0f, 0.01f};
|
|
||||||
vec3 bp = {27.8808f, 25.4219f, 0.01f};
|
|
||||||
vec3 cp = { 1.9f, 21.5781f, 0.01f};
|
|
||||||
|
|
||||||
vec2i ac = {0x0000ff, 0xff0000};
|
|
||||||
vec2i bc = {0x00ff00, 0x0000ff};
|
|
||||||
vec2i cc = {0xff0000, 0x00ff00};
|
|
||||||
|
|
||||||
transfer_isp_tsp_parameters(&isp_tsp_parameters[punch_through_start],
|
|
||||||
ap, ac,
|
|
||||||
bp, bc,
|
|
||||||
cp, cc);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void transfer_opaque_modifier()
|
|
||||||
{
|
|
||||||
vec3 ap = { 0.0f, -50.0f, 0.1f};
|
|
||||||
vec3 bp = {100.0f, 0.0f, 0.1f};
|
|
||||||
vec3 cp = { 0.0f, 50.0f, 0.1f};
|
|
||||||
|
|
||||||
transfer_modifier_volume_isp_tsp_parameters(&isp_tsp_parameters[opaque_modifier_start],
|
|
||||||
ap,
|
|
||||||
bp,
|
|
||||||
cp);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void init_texture_memory()
|
|
||||||
{
|
|
||||||
region_array_multipass(tile_width,
|
|
||||||
tile_height,
|
|
||||||
&opb_size,
|
|
||||||
1,
|
|
||||||
texture_memory_alloc.region_array.start,
|
|
||||||
texture_memory_alloc.object_list.start);
|
|
||||||
|
|
||||||
background_parameter2(texture_memory_alloc.background[0].start,
|
|
||||||
0xff000000);
|
|
||||||
|
|
||||||
transfer_object_list(object_list);
|
|
||||||
|
|
||||||
transfer_punch_through();
|
|
||||||
|
|
||||||
transfer_opaque_modifier();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
static inline bool compare_equal(T a, T b, int length)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < length; i++) {
|
|
||||||
if (a[i] != b[i])
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool detect_emulator()
|
|
||||||
{
|
|
||||||
init_texture_memory();
|
|
||||||
|
|
||||||
bool dither = true;
|
|
||||||
core_start_render2(texture_memory_alloc.region_array.start,
|
|
||||||
texture_memory_alloc.isp_tsp_parameters.start,
|
|
||||||
texture_memory_alloc.background[0].start,
|
|
||||||
texture_memory_alloc.framebuffer[0].start,
|
|
||||||
framebuffer_width,
|
|
||||||
dither);
|
|
||||||
core_wait_end_of_render_video();
|
|
||||||
|
|
||||||
uint32_t * a = (uint32_t *)&_binary_reference_reference_render_data_start;
|
|
||||||
uint32_t * b = (uint32_t *)&texture_memory32[texture_memory_alloc.framebuffer[0].start / 4];
|
|
||||||
int length = 32 * 32 * 2 / 4;
|
|
||||||
|
|
||||||
int equal = compare_equal(a, b, length);
|
|
||||||
|
|
||||||
for (uint32_t i = 0; i < (8 * 1024 * 1024 / 32); i++) {
|
|
||||||
asm volatile ("ocbp @%0"
|
|
||||||
: // output
|
|
||||||
: "r" (((uint32_t)texture_memory32) + (32 * i)) // input
|
|
||||||
: "memory");
|
|
||||||
}
|
|
||||||
|
|
||||||
return !equal;
|
|
||||||
}
|
|
@ -1,3 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
bool detect_emulator();
|
|
@ -1,3 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
extern bool emulator_detected;
|
|
@ -107,36 +107,6 @@ namespace font {
|
|||||||
return length >= offset ? length : offset;
|
return length >= offset ? length : offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int format_int(char * s, int num)
|
|
||||||
{
|
|
||||||
int offset = 0;
|
|
||||||
bool negative = num < 0;
|
|
||||||
if (negative) {
|
|
||||||
s[offset++] = '-';
|
|
||||||
num = -num;
|
|
||||||
}
|
|
||||||
int whole = num;
|
|
||||||
offset += unparse_base10_unsigned(&s[offset], whole, 0, 0);
|
|
||||||
return offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
int face::draw_int(ta_parameter_writer& writer,
|
|
||||||
const vec3& p,
|
|
||||||
int num,
|
|
||||||
uint32_t base_color,
|
|
||||||
int length) const
|
|
||||||
{
|
|
||||||
char s[20];
|
|
||||||
int offset = format_int(s, num);
|
|
||||||
s[offset] = 0;
|
|
||||||
float x = p.x;
|
|
||||||
if (offset < length) {
|
|
||||||
x += hori_advance * (length - offset);
|
|
||||||
}
|
|
||||||
draw_string(writer, {x, p.y, p.z}, s, base_color);
|
|
||||||
return length >= offset ? length : offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
void face::draw_mat4(ta_parameter_writer& writer,
|
void face::draw_mat4(ta_parameter_writer& writer,
|
||||||
const vec3& p,
|
const vec3& p,
|
||||||
const mat4x4& mat,
|
const mat4x4& mat,
|
||||||
@ -169,16 +139,4 @@ namespace font {
|
|||||||
.height = 12,
|
.height = 12,
|
||||||
.row_stride = 21,
|
.row_stride = 21,
|
||||||
};
|
};
|
||||||
|
|
||||||
const face ter_u32n = {
|
|
||||||
.texture_size = tsp_instruction_word::texture_u_size::from_int(256)
|
|
||||||
| tsp_instruction_word::texture_v_size::from_int(256),
|
|
||||||
.texture_offset = texture::offset::ter_u32n,
|
|
||||||
.texture_width = 256,
|
|
||||||
.texture_height = 256,
|
|
||||||
.hori_advance = 16,
|
|
||||||
.width = 16,
|
|
||||||
.height = 32,
|
|
||||||
.row_stride = 16,
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
@ -37,12 +37,6 @@ namespace font {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int draw_int(ta_parameter_writer& writer,
|
|
||||||
const vec3& p,
|
|
||||||
int num,
|
|
||||||
uint32_t base_color,
|
|
||||||
int length) const;
|
|
||||||
|
|
||||||
int draw_float(ta_parameter_writer& writer,
|
int draw_float(ta_parameter_writer& writer,
|
||||||
const vec3& p,
|
const vec3& p,
|
||||||
float num,
|
float num,
|
||||||
@ -57,5 +51,4 @@ namespace font {
|
|||||||
};
|
};
|
||||||
|
|
||||||
extern const face ter_u12n;
|
extern const face ter_u12n;
|
||||||
extern const face ter_u32n;
|
|
||||||
}
|
}
|
||||||
|
@ -13,8 +13,6 @@
|
|||||||
#include "holly/texture_memory_alloc9.hpp"
|
#include "holly/texture_memory_alloc9.hpp"
|
||||||
#include "holly/ta_fifo_texture_memory_transfer.hpp"
|
#include "holly/ta_fifo_texture_memory_transfer.hpp"
|
||||||
#include "holly/ta_fifo_polygon_converter.hpp"
|
#include "holly/ta_fifo_polygon_converter.hpp"
|
||||||
#include "holly/video_output.hpp"
|
|
||||||
#include "dve.hpp"
|
|
||||||
|
|
||||||
#include "math/float_types.hpp"
|
#include "math/float_types.hpp"
|
||||||
#include "math/transform.hpp"
|
#include "math/transform.hpp"
|
||||||
@ -24,7 +22,6 @@
|
|||||||
#include "platform/graphics.hpp"
|
#include "platform/graphics.hpp"
|
||||||
#include "platform/input.hpp"
|
#include "platform/input.hpp"
|
||||||
#include "platform/font.hpp"
|
#include "platform/font.hpp"
|
||||||
#include "platform/emulator_detected.hpp"
|
|
||||||
|
|
||||||
#include "demo/ballistics.hpp"
|
#include "demo/ballistics.hpp"
|
||||||
#include "demo/bridge.hpp"
|
#include "demo/bridge.hpp"
|
||||||
@ -48,14 +45,14 @@ namespace graphics {
|
|||||||
constexpr uint32_t ta_alloc
|
constexpr uint32_t ta_alloc
|
||||||
= ta_alloc_ctrl::pt_opb::_32x4byte
|
= ta_alloc_ctrl::pt_opb::_32x4byte
|
||||||
| ta_alloc_ctrl::tm_opb::no_list
|
| ta_alloc_ctrl::tm_opb::no_list
|
||||||
| ta_alloc_ctrl::t_opb::_32x4byte
|
| ta_alloc_ctrl::t_opb::no_list
|
||||||
| ta_alloc_ctrl::om_opb::_32x4byte
|
| ta_alloc_ctrl::om_opb::no_list
|
||||||
| ta_alloc_ctrl::o_opb::_32x4byte;
|
| ta_alloc_ctrl::o_opb::_32x4byte;
|
||||||
|
|
||||||
const opb_size opb_size = {
|
const opb_size opb_size = {
|
||||||
.opaque = 32 * 4,
|
.opaque = 32 * 4,
|
||||||
.opaque_modifier = 32 * 4,
|
.opaque_modifier = 0,
|
||||||
.translucent = 32 * 4,
|
.translucent = 0,
|
||||||
.translucent_modifier = 0,
|
.translucent_modifier = 0,
|
||||||
.punch_through = 32 * 4
|
.punch_through = 32 * 4
|
||||||
};
|
};
|
||||||
@ -98,21 +95,14 @@ namespace graphics {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//demo::ballistics _ballistics;
|
/*
|
||||||
//demo::bridge _bridge;
|
demo::ballistics _ballistics;
|
||||||
//demo::sailboat _sailboat;
|
demo::bridge _bridge;
|
||||||
//demo::collision _collision;
|
demo::sailboat _sailboat;
|
||||||
|
demo::collision _collision;
|
||||||
|
*/
|
||||||
demo::lizard _lizard;
|
demo::lizard _lizard;
|
||||||
|
demo::scene * current_scene = &_lizard;
|
||||||
demo::scene * scenes[] = {
|
|
||||||
&_lizard,
|
|
||||||
//&_bridge,
|
|
||||||
//&_ballistics
|
|
||||||
};
|
|
||||||
|
|
||||||
int current_scene_ix = 0;
|
|
||||||
|
|
||||||
demo::scene * current_scene = scenes[current_scene_ix];
|
|
||||||
|
|
||||||
void draw()
|
void draw()
|
||||||
{
|
{
|
||||||
@ -125,10 +115,12 @@ namespace graphics {
|
|||||||
{
|
{
|
||||||
core_init();
|
core_init();
|
||||||
framebuffer::scaler_init();
|
framebuffer::scaler_init();
|
||||||
|
|
||||||
view_trans = current_scene->init();
|
view_trans = current_scene->init();
|
||||||
|
|
||||||
// read
|
// read
|
||||||
//while (spg_status::vsync(holly.SPG_STATUS));
|
while (spg_status::vsync(holly.SPG_STATUS));
|
||||||
//while (!spg_status::vsync(holly.SPG_STATUS));
|
while (!spg_status::vsync(holly.SPG_STATUS));
|
||||||
|
|
||||||
system.LMMODE0 = 1; // 32-bit address space
|
system.LMMODE0 = 1; // 32-bit address space
|
||||||
system.LMMODE1 = 1; // 32-bit address space
|
system.LMMODE1 = 1; // 32-bit address space
|
||||||
@ -141,28 +133,11 @@ namespace graphics {
|
|||||||
720 * 480 * 2,
|
720 * 480 * 2,
|
||||||
0xc5f7c5f7);
|
0xc5f7c5f7);
|
||||||
|
|
||||||
//framebuffer::spg_set_mode_640x480_vga();
|
framebuffer::spg_set_mode_640x480_vga();
|
||||||
//framebuffer::spg_set_mode_720x480_vga();
|
//framebuffer::spg_set_mode_720x480_vga();
|
||||||
//framebuffer::init(720, 480,
|
//framebuffer::init(720, 480,
|
||||||
uint32_t cable_type = video_output::get_cable_type();
|
|
||||||
if (emulator_detected) {
|
|
||||||
framebuffer::spg_set_mode_640x480_vga();
|
|
||||||
framebuffer::init(640, 480,
|
framebuffer::init(640, 480,
|
||||||
texture_memory_alloc.framebuffer[0].start);
|
texture_memory_alloc.framebuffer[0].start);
|
||||||
} else {
|
|
||||||
switch (cable_type) {
|
|
||||||
case pdtra::cable_type::vga:
|
|
||||||
framebuffer::spg_set_mode_640x480_vga();
|
|
||||||
framebuffer::init(640, 480,
|
|
||||||
texture_memory_alloc.framebuffer[0].start);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
framebuffer::spg_set_mode_320x240_ntsc_ni();
|
|
||||||
framebuffer::init(320, 240,
|
|
||||||
texture_memory_alloc.framebuffer[0].start);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
core_param_init(texture_memory_alloc.region_array.start,
|
core_param_init(texture_memory_alloc.region_array.start,
|
||||||
texture_memory_alloc.isp_tsp_parameters.start,
|
texture_memory_alloc.isp_tsp_parameters.start,
|
||||||
texture_memory_alloc.background[0].start,
|
texture_memory_alloc.background[0].start,
|
||||||
@ -173,7 +148,7 @@ namespace graphics {
|
|||||||
holly.SOFTRESET = 0;
|
holly.SOFTRESET = 0;
|
||||||
|
|
||||||
background_parameter2(texture_memory_alloc.background[0].start,
|
background_parameter2(texture_memory_alloc.background[0].start,
|
||||||
0xffffff);
|
0x110012);
|
||||||
|
|
||||||
region_array_multipass(framebuffer::framebuffer.tile_width(),
|
region_array_multipass(framebuffer::framebuffer.tile_width(),
|
||||||
framebuffer::framebuffer.tile_height(),
|
framebuffer::framebuffer.tile_height(),
|
||||||
@ -190,7 +165,6 @@ namespace graphics {
|
|||||||
uint8_t b;
|
uint8_t b;
|
||||||
uint8_t x;
|
uint8_t x;
|
||||||
uint8_t y;
|
uint8_t y;
|
||||||
uint8_t start;
|
|
||||||
};
|
};
|
||||||
static button_state last[4] = {};
|
static button_state last[4] = {};
|
||||||
|
|
||||||
@ -219,11 +193,9 @@ namespace graphics {
|
|||||||
bool da = ft0::data_transfer::digital_button::da(data.digital_button) == 0;
|
bool da = ft0::data_transfer::digital_button::da(data.digital_button) == 0;
|
||||||
bool ua = ft0::data_transfer::digital_button::ua(data.digital_button) == 0;
|
bool ua = ft0::data_transfer::digital_button::ua(data.digital_button) == 0;
|
||||||
|
|
||||||
bool start = ft0::data_transfer::digital_button::start(data.digital_button) == 0;
|
if (a) current_scene->a();
|
||||||
|
|
||||||
if (last[port_ix].a != a && a) current_scene->a();
|
|
||||||
if (b) current_scene->b();
|
if (b) current_scene->b();
|
||||||
if (last[port_ix].x != x && x) current_scene->x();
|
if (x) current_scene->x();
|
||||||
if (y) current_scene->y();
|
if (y) current_scene->y();
|
||||||
|
|
||||||
if (ra) current_scene->ra();
|
if (ra) current_scene->ra();
|
||||||
@ -231,23 +203,14 @@ namespace graphics {
|
|||||||
if (da) current_scene->da();
|
if (da) current_scene->da();
|
||||||
if (ua) current_scene->ua();
|
if (ua) current_scene->ua();
|
||||||
|
|
||||||
//if (start) current_scene->start();
|
|
||||||
|
|
||||||
current_scene->analog(dl, dr, dx, dy);
|
|
||||||
|
|
||||||
//view_trans = rotate_y(dy) * view_trans;// * rotate_x(dx);
|
|
||||||
|
|
||||||
if (last[port_ix].start != start && start && x) {
|
|
||||||
//current_scene_ix += 1;
|
|
||||||
//current_scene = scenes[current_scene_ix % 3];
|
|
||||||
//view_trans = current_scene->init(emulator);
|
|
||||||
}
|
|
||||||
|
|
||||||
last[port_ix].a = a;
|
last[port_ix].a = a;
|
||||||
last[port_ix].b = b;
|
last[port_ix].b = b;
|
||||||
last[port_ix].x = x;
|
last[port_ix].x = x;
|
||||||
last[port_ix].y = y;
|
last[port_ix].y = y;
|
||||||
last[port_ix].start = start;
|
|
||||||
|
current_scene->analog(dl, dr, dx, dy);
|
||||||
|
|
||||||
|
//view_trans = rotate_y(dy) * view_trans;// * rotate_x(dx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,7 @@ static inline float _intensity(const mat4x4& trans, const vec3& normal)
|
|||||||
|
|
||||||
vec3 n = normal_multiply(trans, normal);
|
vec3 n = normal_multiply(trans, normal);
|
||||||
float n_dot_l = dot(n, light_vec);
|
float n_dot_l = dot(n, light_vec);
|
||||||
float intensity = 0.2f;
|
float intensity = 0.5f;
|
||||||
if (n_dot_l > 0)
|
if (n_dot_l > 0)
|
||||||
intensity += 0.5f * n_dot_l * (inverse_length(n) * inverse_length(light_vec));
|
intensity += 0.5f * n_dot_l * (inverse_length(n) * inverse_length(light_vec));
|
||||||
return intensity;
|
return intensity;
|
||||||
@ -265,9 +265,7 @@ void draw_halfspace(ta_parameter_writer& writer,
|
|||||||
void draw_textured_cube(ta_parameter_writer& writer,
|
void draw_textured_cube(ta_parameter_writer& writer,
|
||||||
const mat4x4& trans,
|
const mat4x4& trans,
|
||||||
const vec3& scale,
|
const vec3& scale,
|
||||||
const texture::cube_texture_offsets& offsets,
|
const texture::cube_texture_offsets& offsets)
|
||||||
const vec3& base_color,
|
|
||||||
float intensity_offset)
|
|
||||||
{
|
{
|
||||||
static const vec3 position[] = {
|
static const vec3 position[] = {
|
||||||
{-0.5, -0.5, 0.5},
|
{-0.5, -0.5, 0.5},
|
||||||
@ -325,7 +323,7 @@ void draw_textured_cube(ta_parameter_writer& writer,
|
|||||||
}
|
}
|
||||||
|
|
||||||
int texture_uv_size
|
int texture_uv_size
|
||||||
= tsp_instruction_word::texture_shading_instruction::modulate
|
= tsp_instruction_word::texture_shading_instruction::decal
|
||||||
| tsp_instruction_word::src_alpha_instr::one
|
| tsp_instruction_word::src_alpha_instr::one
|
||||||
| tsp_instruction_word::dst_alpha_instr::zero
|
| tsp_instruction_word::dst_alpha_instr::zero
|
||||||
| tsp_instruction_word::texture_u_size::from_int(32)
|
| tsp_instruction_word::texture_u_size::from_int(32)
|
||||||
@ -334,11 +332,11 @@ void draw_textured_cube(ta_parameter_writer& writer,
|
|||||||
int pixel_format
|
int pixel_format
|
||||||
= texture_control_word::pixel_format::_565;
|
= texture_control_word::pixel_format::_565;
|
||||||
|
|
||||||
vec4 color = {base_color.x, base_color.y, base_color.z, 1};
|
const vec4 color = {0, 0, 0, 0};
|
||||||
|
|
||||||
global_polygon_textured_intensity(writer,
|
global_polygon_textured_intensity(writer,
|
||||||
color,
|
color,
|
||||||
para_control::list_type::opaque,// | obj_control::shadow,
|
para_control::list_type::opaque,
|
||||||
offsets.side,
|
offsets.side,
|
||||||
texture_uv_size,
|
texture_uv_size,
|
||||||
pixel_format);
|
pixel_format);
|
||||||
@ -347,14 +345,14 @@ void draw_textured_cube(ta_parameter_writer& writer,
|
|||||||
if (i == 4)
|
if (i == 4)
|
||||||
global_polygon_textured_intensity(writer,
|
global_polygon_textured_intensity(writer,
|
||||||
color,
|
color,
|
||||||
para_control::list_type::opaque,// | obj_control::shadow,
|
para_control::list_type::opaque,
|
||||||
offsets.bottom,
|
offsets.bottom,
|
||||||
texture_uv_size,
|
texture_uv_size,
|
||||||
pixel_format);
|
pixel_format);
|
||||||
if (i == 5)
|
if (i == 5)
|
||||||
global_polygon_textured_intensity(writer,
|
global_polygon_textured_intensity(writer,
|
||||||
color,
|
color,
|
||||||
para_control::list_type::opaque | obj_control::shadow,
|
para_control::list_type::opaque,
|
||||||
offsets.top,
|
offsets.top,
|
||||||
texture_uv_size,
|
texture_uv_size,
|
||||||
pixel_format);
|
pixel_format);
|
||||||
@ -369,125 +367,7 @@ void draw_textured_cube(ta_parameter_writer& writer,
|
|||||||
const vec2& ct = texture[1] * uv_scale[i];
|
const vec2& ct = texture[1] * uv_scale[i];
|
||||||
const vec2& dt = texture[2] * uv_scale[i];
|
const vec2& dt = texture[2] * uv_scale[i];
|
||||||
|
|
||||||
const float base_intensity = _intensity(trans, normal[i]) + intensity_offset;
|
const float base_intensity = _intensity(trans, normal[i]);
|
||||||
|
|
||||||
quad_type_7_maybe_clip(writer,
|
|
||||||
ap, at,
|
|
||||||
bp, bt,
|
|
||||||
cp, ct,
|
|
||||||
dp, dt,
|
|
||||||
base_intensity);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void draw_textured_cube2(ta_parameter_writer& writer,
|
|
||||||
const mat4x4& trans,
|
|
||||||
int texture_offset1,
|
|
||||||
int texture_offset2,
|
|
||||||
float transition)
|
|
||||||
{
|
|
||||||
static const vec3 position[] = {
|
|
||||||
{-0.5, -0.5, 0.5},
|
|
||||||
{-0.5, 0.5, 0.5},
|
|
||||||
{-0.5, -0.5, -0.5},
|
|
||||||
{-0.5, 0.5, -0.5},
|
|
||||||
{ 0.5, -0.5, 0.5},
|
|
||||||
{ 0.5, 0.5, 0.5},
|
|
||||||
{ 0.5, -0.5, -0.5},
|
|
||||||
{ 0.5, 0.5, -0.5},
|
|
||||||
};
|
|
||||||
static const vec2 texture[] = {
|
|
||||||
{0.0, 0.0},
|
|
||||||
{1.0, 0.0},
|
|
||||||
{1.0, 1.0},
|
|
||||||
{0.0, 1.0},
|
|
||||||
};
|
|
||||||
const int position_length = (sizeof (position)) / (sizeof (position[0]));
|
|
||||||
|
|
||||||
struct quad {
|
|
||||||
int a, b, c, d;
|
|
||||||
};
|
|
||||||
|
|
||||||
static const quad quads[] = {
|
|
||||||
{0, 1, 3, 2}, // front (z, y)
|
|
||||||
{2, 3, 7, 6}, // left (x, y)
|
|
||||||
{6, 7, 5, 4}, // rear (z, y)
|
|
||||||
{4, 5, 1, 0}, // right (x, y)
|
|
||||||
//{2, 6, 4, 0}, // bottom (x, z)
|
|
||||||
//{7, 3, 1, 5} // top (x, z)
|
|
||||||
};
|
|
||||||
|
|
||||||
const int quads_length = (sizeof (quads)) / (sizeof (quads[0]));
|
|
||||||
|
|
||||||
vec3 position_cache[position_length];
|
|
||||||
for (int i = 0; i < position_length; i++) {
|
|
||||||
position_cache[i] = trans * position[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
int texture_uv_size
|
|
||||||
= tsp_instruction_word::texture_shading_instruction::modulate_alpha
|
|
||||||
| tsp_instruction_word::src_alpha_instr::src_alpha
|
|
||||||
| tsp_instruction_word::dst_alpha_instr::inverse_src_alpha
|
|
||||||
| tsp_instruction_word::use_alpha
|
|
||||||
| tsp_instruction_word::texture_u_size::from_int(128)
|
|
||||||
| tsp_instruction_word::texture_v_size::from_int(128);
|
|
||||||
|
|
||||||
int pixel_format
|
|
||||||
= texture_control_word::pixel_format::_565;
|
|
||||||
|
|
||||||
const vec2 uv_scale = {72.0f / 128.0f, 72.0f / 128.0f};
|
|
||||||
|
|
||||||
for (int i = 0; i < quads_length; i++) {
|
|
||||||
const vec3& ap = position_cache[quads[i].a];
|
|
||||||
const vec3& bp = position_cache[quads[i].b];
|
|
||||||
const vec3& cp = position_cache[quads[i].c];
|
|
||||||
const vec3& dp = position_cache[quads[i].d];
|
|
||||||
|
|
||||||
bool flip = (i < 4) && (i % 2 == 0);
|
|
||||||
|
|
||||||
vec2 at;
|
|
||||||
vec2 bt;
|
|
||||||
vec2 ct;
|
|
||||||
vec2 dt;
|
|
||||||
|
|
||||||
if (flip) {
|
|
||||||
at = vec2(1.0 - texture[3].x, texture[3].y) * uv_scale;
|
|
||||||
bt = vec2(1.0 - texture[0].x, texture[0].y) * uv_scale;
|
|
||||||
ct = vec2(1.0 - texture[1].x, texture[1].y) * uv_scale;
|
|
||||||
dt = vec2(1.0 - texture[2].x, texture[2].y) * uv_scale;
|
|
||||||
} else {
|
|
||||||
at = texture[3] * uv_scale;
|
|
||||||
bt = texture[0] * uv_scale;
|
|
||||||
ct = texture[1] * uv_scale;
|
|
||||||
dt = texture[2] * uv_scale;
|
|
||||||
}
|
|
||||||
|
|
||||||
const float base_intensity = 0.4f;
|
|
||||||
|
|
||||||
vec4 color1 = {1, 1, 1, 1.0f - transition};
|
|
||||||
|
|
||||||
global_polygon_textured_intensity(writer,
|
|
||||||
color1,
|
|
||||||
para_control::list_type::translucent,
|
|
||||||
texture_offset1,
|
|
||||||
texture_uv_size,
|
|
||||||
pixel_format);
|
|
||||||
|
|
||||||
quad_type_7_maybe_clip(writer,
|
|
||||||
ap, at,
|
|
||||||
bp, bt,
|
|
||||||
cp, ct,
|
|
||||||
dp, dt,
|
|
||||||
base_intensity);
|
|
||||||
|
|
||||||
vec4 color2 = {1, 1, 1, transition};
|
|
||||||
|
|
||||||
global_polygon_textured_intensity(writer,
|
|
||||||
color2,
|
|
||||||
para_control::list_type::translucent,
|
|
||||||
texture_offset2,
|
|
||||||
texture_uv_size,
|
|
||||||
pixel_format);
|
|
||||||
|
|
||||||
quad_type_7_maybe_clip(writer,
|
quad_type_7_maybe_clip(writer,
|
||||||
ap, at,
|
ap, at,
|
||||||
@ -667,235 +547,3 @@ void draw_textured_voxel(ta_parameter_writer& writer,
|
|||||||
base_intensity);
|
base_intensity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void draw_lizard_mv(ta_parameter_writer& writer,
|
|
||||||
const mat4x4& trans)
|
|
||||||
{
|
|
||||||
const vec3 position[] = {
|
|
||||||
{0.024607, -19.000000, -0.547183},
|
|
||||||
{0.024607, 1.000000, -0.547183},
|
|
||||||
{0.581259, -19.000000, -0.638034},
|
|
||||||
{0.581259, 1.000000, -0.638034},
|
|
||||||
{1.140180, -19.000000, -0.601015},
|
|
||||||
{1.140180, 1.000000, -0.601015},
|
|
||||||
{1.655285, -19.000000, -0.540899},
|
|
||||||
{1.655285, 1.000000, -0.540899},
|
|
||||||
{2.106778, -19.000000, -0.218025},
|
|
||||||
{2.106778, 1.000000, -0.218025},
|
|
||||||
{2.469107, -19.000000, -0.230178},
|
|
||||||
{2.469107, 1.000000, -0.230178},
|
|
||||||
{2.748537, -19.000000, -0.269455},
|
|
||||||
{2.748537, 1.000000, -0.269455},
|
|
||||||
{2.918084, -19.000000, -0.147419},
|
|
||||||
{2.918084, 1.000000, -0.147419},
|
|
||||||
{2.979434, -19.000000, 0.000000},
|
|
||||||
{2.979434, 1.000000, 0.000000},
|
|
||||||
{2.950894, -19.000000, 0.249949},
|
|
||||||
{2.950894, 1.000000, 0.249949},
|
|
||||||
{2.871574, -19.000000, 0.371985},
|
|
||||||
{2.871574, 1.000000, 0.371985},
|
|
||||||
{2.280451, -19.000000, 0.295798},
|
|
||||||
{2.280451, 1.000000, 0.295798},
|
|
||||||
{2.123183, -19.000000, 0.349264},
|
|
||||||
{2.123183, 1.000000, 0.349264},
|
|
||||||
{1.757816, -19.000000, 0.590114},
|
|
||||||
{1.757816, 1.000000, 0.590114},
|
|
||||||
{1.242711, -19.000000, 0.650229},
|
|
||||||
{1.242711, 1.000000, 0.650229},
|
|
||||||
{0.571416, -19.000000, 0.652798},
|
|
||||||
{0.571416, 1.000000, 0.652798},
|
|
||||||
{0.009843, -19.000000, 0.596398},
|
|
||||||
{0.009843, 1.000000, 0.596398},
|
|
||||||
{-0.650159, -19.000000, 0.623270},
|
|
||||||
{-0.650159, 1.000000, 0.623270},
|
|
||||||
{-1.661035, -19.000000, 0.654331},
|
|
||||||
{-1.661035, 1.000000, 0.654331},
|
|
||||||
{-2.176140, -19.000000, 0.594215},
|
|
||||||
{-2.176140, 1.000000, 0.594215},
|
|
||||||
{-2.455382, -19.000000, 0.455896},
|
|
||||||
{-2.455382, 1.000000, 0.455896},
|
|
||||||
{-2.612649, -19.000000, 0.623895},
|
|
||||||
{-2.612649, 1.000000, 0.623895},
|
|
||||||
{-2.887979, -19.000000, 0.511426},
|
|
||||||
{-2.887979, 1.000000, 0.511426},
|
|
||||||
{-2.922185, -19.000000, 0.126913},
|
|
||||||
{-2.922185, 1.000000, 0.126913},
|
|
||||||
{-2.979434, -19.000000, 0.000000},
|
|
||||||
{-2.979434, 1.000000, 0.000000},
|
|
||||||
{-2.922185, -19.000000, -0.126913},
|
|
||||||
{-2.922185, 1.000000, -0.126913},
|
|
||||||
{-2.879776, -19.000000, -0.482718},
|
|
||||||
{-2.879776, 1.000000, -0.482718},
|
|
||||||
{-2.604447, -19.000000, -0.595187},
|
|
||||||
{-2.604447, 1.000000, -0.595187},
|
|
||||||
{-2.397965, -19.000000, -0.443592},
|
|
||||||
{-2.397965, 1.000000, -0.443592},
|
|
||||||
{-2.061306, -19.000000, -0.586012},
|
|
||||||
{-2.061306, 1.000000, -0.586012},
|
|
||||||
{-1.359185, -19.000000, -0.621521},
|
|
||||||
{-1.359185, 1.000000, -0.621521},
|
|
||||||
{-0.576337, -19.000000, -0.574055},
|
|
||||||
{-0.576337, 1.000000, -0.574055},
|
|
||||||
};
|
|
||||||
const int position_length = (sizeof (position)) / (sizeof (position[0]));
|
|
||||||
|
|
||||||
struct tri {
|
|
||||||
int a;
|
|
||||||
int b;
|
|
||||||
int c;
|
|
||||||
};
|
|
||||||
|
|
||||||
const tri tris[] = {
|
|
||||||
{1, 2, 0},
|
|
||||||
{3, 4, 2},
|
|
||||||
{5, 6, 4},
|
|
||||||
{7, 8, 6},
|
|
||||||
{9, 10, 8},
|
|
||||||
{11, 12, 10},
|
|
||||||
{13, 14, 12},
|
|
||||||
{15, 16, 14},
|
|
||||||
{17, 18, 16},
|
|
||||||
{19, 20, 18},
|
|
||||||
{21, 22, 20},
|
|
||||||
{23, 24, 22},
|
|
||||||
{25, 26, 24},
|
|
||||||
{27, 28, 26},
|
|
||||||
{29, 30, 28},
|
|
||||||
{31, 32, 30},
|
|
||||||
{33, 34, 32},
|
|
||||||
{35, 36, 34},
|
|
||||||
{37, 38, 36},
|
|
||||||
{39, 40, 38},
|
|
||||||
{41, 42, 40},
|
|
||||||
{43, 44, 42},
|
|
||||||
{45, 46, 44},
|
|
||||||
{47, 48, 46},
|
|
||||||
{49, 50, 48},
|
|
||||||
{51, 52, 50},
|
|
||||||
{53, 54, 52},
|
|
||||||
{55, 56, 54},
|
|
||||||
{57, 58, 56},
|
|
||||||
{59, 60, 58},
|
|
||||||
{47, 37, 25},
|
|
||||||
{61, 62, 60},
|
|
||||||
{63, 0, 62},
|
|
||||||
{32, 46, 56},
|
|
||||||
{1, 3, 2},
|
|
||||||
{3, 5, 4},
|
|
||||||
{5, 7, 6},
|
|
||||||
{7, 9, 8},
|
|
||||||
{9, 11, 10},
|
|
||||||
{11, 13, 12},
|
|
||||||
{13, 15, 14},
|
|
||||||
{15, 17, 16},
|
|
||||||
{17, 19, 18},
|
|
||||||
{19, 21, 20},
|
|
||||||
{21, 23, 22},
|
|
||||||
{23, 25, 24},
|
|
||||||
{25, 27, 26},
|
|
||||||
{27, 29, 28},
|
|
||||||
{29, 31, 30},
|
|
||||||
{31, 33, 32},
|
|
||||||
{33, 35, 34},
|
|
||||||
{35, 37, 36},
|
|
||||||
{37, 39, 38},
|
|
||||||
{39, 41, 40},
|
|
||||||
{41, 43, 42},
|
|
||||||
{43, 45, 44},
|
|
||||||
{45, 47, 46},
|
|
||||||
{47, 49, 48},
|
|
||||||
{49, 51, 50},
|
|
||||||
{51, 53, 52},
|
|
||||||
{53, 55, 54},
|
|
||||||
{55, 57, 56},
|
|
||||||
{57, 59, 58},
|
|
||||||
{59, 61, 60},
|
|
||||||
{5, 3, 1},
|
|
||||||
{63, 61, 59},
|
|
||||||
{7, 5, 1},
|
|
||||||
{1, 63, 59},
|
|
||||||
{57, 55, 53},
|
|
||||||
{1, 59, 57},
|
|
||||||
{9, 7, 1},
|
|
||||||
{15, 13, 11},
|
|
||||||
{9, 1, 57},
|
|
||||||
{15, 11, 9},
|
|
||||||
{19, 17, 15},
|
|
||||||
{23, 21, 19},
|
|
||||||
{29, 27, 25},
|
|
||||||
{23, 19, 15},
|
|
||||||
{31, 29, 25},
|
|
||||||
{25, 23, 15},
|
|
||||||
{15, 9, 57},
|
|
||||||
{57, 53, 51},
|
|
||||||
{51, 49, 47},
|
|
||||||
{47, 45, 43},
|
|
||||||
{41, 39, 37},
|
|
||||||
{47, 43, 41},
|
|
||||||
{57, 51, 47},
|
|
||||||
{25, 15, 57},
|
|
||||||
{33, 31, 25},
|
|
||||||
{37, 35, 33},
|
|
||||||
{47, 41, 37},
|
|
||||||
{25, 57, 47},
|
|
||||||
{37, 33, 25},
|
|
||||||
{61, 63, 62},
|
|
||||||
{63, 1, 0},
|
|
||||||
{0, 2, 4},
|
|
||||||
{4, 6, 8},
|
|
||||||
{10, 12, 14},
|
|
||||||
{0, 4, 8},
|
|
||||||
{8, 10, 14},
|
|
||||||
{14, 16, 18},
|
|
||||||
{18, 20, 22},
|
|
||||||
{24, 26, 28},
|
|
||||||
{14, 18, 22},
|
|
||||||
{24, 28, 30},
|
|
||||||
{14, 22, 24},
|
|
||||||
{62, 0, 8},
|
|
||||||
{8, 14, 24},
|
|
||||||
{24, 30, 32},
|
|
||||||
{32, 34, 36},
|
|
||||||
{36, 38, 40},
|
|
||||||
{40, 42, 44},
|
|
||||||
{46, 48, 50},
|
|
||||||
{40, 44, 46},
|
|
||||||
{32, 36, 40},
|
|
||||||
{8, 24, 32},
|
|
||||||
{60, 62, 8},
|
|
||||||
{56, 58, 60},
|
|
||||||
{52, 54, 56},
|
|
||||||
{46, 50, 52},
|
|
||||||
{32, 40, 46},
|
|
||||||
{60, 8, 32},
|
|
||||||
{46, 52, 56},
|
|
||||||
{56, 60, 32}
|
|
||||||
};
|
|
||||||
|
|
||||||
const int tris_length = (sizeof (tris)) / (sizeof (tris[0]));
|
|
||||||
|
|
||||||
static vec3 position_cache[position_length];
|
|
||||||
for (int i = 0; i < position_length; i++) {
|
|
||||||
position_cache[i] = screen_transform(trans * (position[i] * vec3(-0.5, 1, 0.7)));
|
|
||||||
}
|
|
||||||
|
|
||||||
global_polygon_modifier_volume(writer);
|
|
||||||
|
|
||||||
for (int i = 0; i < tris_length; i++) {
|
|
||||||
|
|
||||||
const vec3& ap = position_cache[tris[i].a];
|
|
||||||
const vec3& bp = position_cache[tris[i].b];
|
|
||||||
const vec3& cp = position_cache[tris[i].c];
|
|
||||||
|
|
||||||
bool last_in_volume = i == (tris_length - 1);
|
|
||||||
if (last_in_volume) {
|
|
||||||
global_polygon_modifier_volume_last_in_volume(writer);
|
|
||||||
}
|
|
||||||
|
|
||||||
writer.append<ta_vertex_parameter::modifier_volume>() =
|
|
||||||
ta_vertex_parameter::modifier_volume(modifier_volume_vertex_parameter_control_word(),
|
|
||||||
ap.x, ap.y, ap.z,
|
|
||||||
bp.x, bp.y, bp.z,
|
|
||||||
cp.x, cp.y, cp.z);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -83,15 +83,7 @@ void draw_cube(ta_parameter_writer& writer,
|
|||||||
void draw_textured_cube(ta_parameter_writer& writer,
|
void draw_textured_cube(ta_parameter_writer& writer,
|
||||||
const mat4x4& trans,
|
const mat4x4& trans,
|
||||||
const vec3& scale,
|
const vec3& scale,
|
||||||
const texture::cube_texture_offsets& offsets,
|
const texture::cube_texture_offsets& offsets);
|
||||||
const vec3& base_color,
|
|
||||||
float intensity_offset);
|
|
||||||
|
|
||||||
void draw_textured_cube2(ta_parameter_writer& writer,
|
|
||||||
const mat4x4& trans,
|
|
||||||
int texture_offset1,
|
|
||||||
int texture_offset2,
|
|
||||||
float transition);
|
|
||||||
|
|
||||||
void draw_icosphere(ta_parameter_writer& writer,
|
void draw_icosphere(ta_parameter_writer& writer,
|
||||||
const mat4x4& trans,
|
const mat4x4& trans,
|
||||||
@ -112,6 +104,3 @@ void draw_halfspace(ta_parameter_writer& writer,
|
|||||||
void draw_textured_voxel(ta_parameter_writer& writer,
|
void draw_textured_voxel(ta_parameter_writer& writer,
|
||||||
const mat4x4& trans,
|
const mat4x4& trans,
|
||||||
int texture_offset);
|
int texture_offset);
|
||||||
|
|
||||||
void draw_lizard_mv(ta_parameter_writer& writer,
|
|
||||||
const mat4x4& trans);
|
|
||||||
|
@ -1,25 +1,14 @@
|
|||||||
#include "assert.h"
|
#include "assert.h"
|
||||||
#include "interrupt.hpp"
|
#include "interrupt.hpp"
|
||||||
#include "aica/aica.hpp"
|
//#include "aica/aica.hpp"
|
||||||
|
|
||||||
#include "platform/graphics.hpp"
|
#include "platform/graphics.hpp"
|
||||||
#include "platform/input.hpp"
|
#include "platform/input.hpp"
|
||||||
#include "platform/texture.hpp"
|
#include "platform/texture.hpp"
|
||||||
#include "platform/detect_emulator.hpp"
|
|
||||||
#include "xm_player/sound.hpp"
|
|
||||||
#include "xm_player/interpreter.hpp"
|
|
||||||
#include "printf/printf.h"
|
#include "printf/printf.h"
|
||||||
|
|
||||||
#include "platform/emulator_detected.hpp"
|
|
||||||
|
|
||||||
bool emulator_detected;
|
|
||||||
|
|
||||||
void vbr100()
|
void vbr100()
|
||||||
{
|
{
|
||||||
if (sh7091.CCN.EXPEVT == 0xe0) {
|
|
||||||
serial::string("vbr100 expevt == 0xe0\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
serial::string("vbr100\n");
|
serial::string("vbr100\n");
|
||||||
interrupt_exception();
|
interrupt_exception();
|
||||||
}
|
}
|
||||||
@ -52,14 +41,9 @@ void vbr600()
|
|||||||
|
|
||||||
graphics::interrupt(istnrm);
|
graphics::interrupt(istnrm);
|
||||||
} else if (sh7091.CCN.EXPEVT == 0 && sh7091.CCN.INTEVT == 0x360) { // AICA
|
} else if (sh7091.CCN.EXPEVT == 0 && sh7091.CCN.INTEVT == 0x360) { // AICA
|
||||||
wait(); aica_sound.common.mcire = (1 << 6); // interrupt timer A
|
//wait(); aica_sound.common.mcire = (1 << 6); // interrupt timer A
|
||||||
|
|
||||||
wait(); aica_sound.common.tactl_tima
|
//scene::current_scene->interrupt();
|
||||||
= aica::tactl_tima::TACTL(0) // increment once every sample
|
|
||||||
| aica::tactl_tima::TIMA(0xfffd) // interrupt after 3 counts
|
|
||||||
;
|
|
||||||
|
|
||||||
interpreter::interrupt();
|
|
||||||
} else {
|
} else {
|
||||||
serial::string("vbr600\n");
|
serial::string("vbr600\n");
|
||||||
interrupt_exception();
|
interrupt_exception();
|
||||||
@ -74,20 +58,15 @@ void main()
|
|||||||
{
|
{
|
||||||
serial::init(0);
|
serial::init(0);
|
||||||
|
|
||||||
emulator_detected = detect_emulator();
|
|
||||||
|
|
||||||
input::init();
|
input::init();
|
||||||
graphics::init();
|
graphics::init();
|
||||||
texture::init();
|
texture::init();
|
||||||
sound::init();
|
|
||||||
|
|
||||||
interrupt_init();
|
interrupt_init();
|
||||||
system.IML6NRM = istnrm::end_of_render_tsp
|
system.IML6NRM = istnrm::end_of_render_tsp
|
||||||
| istnrm::v_blank_in
|
| istnrm::v_blank_in
|
||||||
| istnrm::end_of_transferring_opaque_list;
|
| istnrm::end_of_transferring_opaque_list;
|
||||||
|
|
||||||
system.IML4EXT = istext::aica;
|
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
input::update();
|
input::update();
|
||||||
graphics::step();
|
graphics::step();
|
||||||
|
@ -10,34 +10,6 @@
|
|||||||
#include "math/geometry.hpp"
|
#include "math/geometry.hpp"
|
||||||
#include "math/float_types.hpp"
|
#include "math/float_types.hpp"
|
||||||
|
|
||||||
static inline void global_polygon_modifier_volume(ta_parameter_writer& writer)
|
|
||||||
{
|
|
||||||
uint32_t parameter_control_word = para_control::para_type::polygon_or_modifier_volume
|
|
||||||
| para_control::list_type::opaque_modifier_volume
|
|
||||||
;
|
|
||||||
|
|
||||||
uint32_t isp_tsp_instruction_word = isp_tsp_instruction_word::volume_instruction::normal_polygon
|
|
||||||
| isp_tsp_instruction_word::culling_mode::no_culling;
|
|
||||||
|
|
||||||
writer.append<ta_global_parameter::modifier_volume>() =
|
|
||||||
ta_global_parameter::modifier_volume(parameter_control_word,
|
|
||||||
isp_tsp_instruction_word);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void global_polygon_modifier_volume_last_in_volume(ta_parameter_writer& writer)
|
|
||||||
{
|
|
||||||
const uint32_t last_parameter_control_word = para_control::para_type::polygon_or_modifier_volume
|
|
||||||
| para_control::list_type::opaque_modifier_volume
|
|
||||||
| obj_control::volume::modifier_volume::last_in_volume;
|
|
||||||
|
|
||||||
const uint32_t last_isp_tsp_instruction_word = isp_tsp_instruction_word::volume_instruction::inside_last_polygon
|
|
||||||
| isp_tsp_instruction_word::culling_mode::no_culling;
|
|
||||||
|
|
||||||
writer.append<ta_global_parameter::modifier_volume>() =
|
|
||||||
ta_global_parameter::modifier_volume(last_parameter_control_word,
|
|
||||||
last_isp_tsp_instruction_word);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void global_polygon_intensity(ta_parameter_writer& writer,
|
static inline void global_polygon_intensity(ta_parameter_writer& writer,
|
||||||
const vec3& color,
|
const vec3& color,
|
||||||
uint32_t culling_mode = isp_tsp_instruction_word::culling_mode::no_culling)
|
uint32_t culling_mode = isp_tsp_instruction_word::culling_mode::no_culling)
|
||||||
|
@ -8,7 +8,6 @@
|
|||||||
#include "holly/ta_fifo_texture_memory_transfer.hpp"
|
#include "holly/ta_fifo_texture_memory_transfer.hpp"
|
||||||
|
|
||||||
#include "font/ter_u12n.data.h"
|
#include "font/ter_u12n.data.h"
|
||||||
#include "font/ter_u32n.data.h"
|
|
||||||
#include "texture/igh25_box_top_32.data.h"
|
#include "texture/igh25_box_top_32.data.h"
|
||||||
#include "texture/igh25_box_bottom_32.data.h"
|
#include "texture/igh25_box_bottom_32.data.h"
|
||||||
#include "texture/igh25_box_side_32.data.h"
|
#include "texture/igh25_box_side_32.data.h"
|
||||||
@ -26,15 +25,6 @@
|
|||||||
#include "texture/turning/frame0004_128.data.h"
|
#include "texture/turning/frame0004_128.data.h"
|
||||||
#include "texture/turning/frame0005_128.data.h"
|
#include "texture/turning/frame0005_128.data.h"
|
||||||
#include "texture/turning/frame0006_128.data.h"
|
#include "texture/turning/frame0006_128.data.h"
|
||||||
#include "cover/clocks.data.h"
|
|
||||||
#include "cover/mossycottage.data.h"
|
|
||||||
#include "cover/mountain.data.h"
|
|
||||||
#include "cover/thebeach.data.h"
|
|
||||||
#include "cover/tree.data.h"
|
|
||||||
#include "cover/redtree.data.h"
|
|
||||||
#include "cover/silvertrees.data.h"
|
|
||||||
|
|
||||||
#include "assert.h"
|
|
||||||
|
|
||||||
namespace texture {
|
namespace texture {
|
||||||
struct entry {
|
struct entry {
|
||||||
@ -49,11 +39,6 @@ namespace texture {
|
|||||||
.size = reinterpret_cast<int>(&_binary_font_ter_u12n_data_size),
|
.size = reinterpret_cast<int>(&_binary_font_ter_u12n_data_size),
|
||||||
.offset = offset::ter_u12n,
|
.offset = offset::ter_u12n,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
.start = reinterpret_cast<void *>(&_binary_font_ter_u32n_data_start),
|
|
||||||
.size = reinterpret_cast<int>(&_binary_font_ter_u32n_data_size),
|
|
||||||
.offset = offset::ter_u32n,
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
.start = reinterpret_cast<void *>(&_binary_texture_igh25_box_top_32_data_start),
|
.start = reinterpret_cast<void *>(&_binary_texture_igh25_box_top_32_data_start),
|
||||||
.size = reinterpret_cast<int>(&_binary_texture_igh25_box_top_32_data_size),
|
.size = reinterpret_cast<int>(&_binary_texture_igh25_box_top_32_data_size),
|
||||||
@ -139,41 +124,6 @@ namespace texture {
|
|||||||
.size = reinterpret_cast<int>(&_binary_texture_turning_frame0006_128_data_size),
|
.size = reinterpret_cast<int>(&_binary_texture_turning_frame0006_128_data_size),
|
||||||
.offset = offset::turning_frame0006,
|
.offset = offset::turning_frame0006,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
.start = reinterpret_cast<void *>(&_binary_cover_clocks_data_start),
|
|
||||||
.size = reinterpret_cast<int>(&_binary_cover_clocks_data_size),
|
|
||||||
.offset = offset::clocks,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.start = reinterpret_cast<void *>(&_binary_cover_mossycottage_data_start),
|
|
||||||
.size = reinterpret_cast<int>(&_binary_cover_mossycottage_data_size),
|
|
||||||
.offset = offset::mossycottage,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.start = reinterpret_cast<void *>(&_binary_cover_mountain_data_start),
|
|
||||||
.size = reinterpret_cast<int>(&_binary_cover_mountain_data_size),
|
|
||||||
.offset = offset::mountain,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.start = reinterpret_cast<void *>(&_binary_cover_thebeach_data_start),
|
|
||||||
.size = reinterpret_cast<int>(&_binary_cover_thebeach_data_size),
|
|
||||||
.offset = offset::thebeach,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.start = reinterpret_cast<void *>(&_binary_cover_tree_data_start),
|
|
||||||
.size = reinterpret_cast<int>(&_binary_cover_tree_data_size),
|
|
||||||
.offset = offset::tree,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.start = reinterpret_cast<void *>(&_binary_cover_redtree_data_start),
|
|
||||||
.size = reinterpret_cast<int>(&_binary_cover_redtree_data_size),
|
|
||||||
.offset = offset::redtree,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.start = reinterpret_cast<void *>(&_binary_cover_silvertrees_data_start),
|
|
||||||
.size = reinterpret_cast<int>(&_binary_cover_silvertrees_data_size),
|
|
||||||
.offset = offset::silvertrees,
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const int textures_length = (sizeof (textures)) / (sizeof (textures[0]));
|
const int textures_length = (sizeof (textures)) / (sizeof (textures[0]));
|
||||||
@ -200,7 +150,6 @@ namespace texture {
|
|||||||
int size = textures[i].size;
|
int size = textures[i].size;
|
||||||
|
|
||||||
ta_fifo_texture_memory_transfer::copy(dst, src, size);
|
ta_fifo_texture_memory_transfer::copy(dst, src, size);
|
||||||
assert((int)offset + size < 8 * 1024 * 1024);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
transfer_palettes();
|
transfer_palettes();
|
||||||
|
@ -3,8 +3,7 @@
|
|||||||
namespace texture {
|
namespace texture {
|
||||||
namespace offset {
|
namespace offset {
|
||||||
constexpr int ter_u12n = 0;
|
constexpr int ter_u12n = 0;
|
||||||
constexpr int ter_u32n = ter_u12n + 4096;
|
constexpr int igh25_box_top_32 = ter_u12n + 4096;
|
||||||
constexpr int igh25_box_top_32 = ter_u32n + 32768;
|
|
||||||
constexpr int igh25_box_bottom_32 = igh25_box_top_32 + 2048;
|
constexpr int igh25_box_bottom_32 = igh25_box_top_32 + 2048;
|
||||||
constexpr int igh25_box_side_32 = igh25_box_bottom_32 + 2048;
|
constexpr int igh25_box_side_32 = igh25_box_bottom_32 + 2048;
|
||||||
|
|
||||||
@ -23,14 +22,6 @@ namespace texture {
|
|||||||
constexpr int turning_frame0004 = turning_frame0003 + 8192;
|
constexpr int turning_frame0004 = turning_frame0003 + 8192;
|
||||||
constexpr int turning_frame0005 = turning_frame0004 + 8192;
|
constexpr int turning_frame0005 = turning_frame0004 + 8192;
|
||||||
constexpr int turning_frame0006 = turning_frame0005 + 8192;
|
constexpr int turning_frame0006 = turning_frame0005 + 8192;
|
||||||
|
|
||||||
constexpr int clocks = turning_frame0006 + 8192;
|
|
||||||
constexpr int mossycottage = clocks + 32768;
|
|
||||||
constexpr int mountain = mossycottage + 32768;
|
|
||||||
constexpr int thebeach = mountain + 32768;
|
|
||||||
constexpr int tree = thebeach + 32768;
|
|
||||||
constexpr int redtree = tree + 32768;
|
|
||||||
constexpr int silvertrees = redtree + 32768;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct cube_texture_offsets {
|
struct cube_texture_offsets {
|
||||||
|
@ -1,5 +0,0 @@
|
|||||||
#include "xm_player/cover.hpp"
|
|
||||||
|
|
||||||
namespace cover {
|
|
||||||
int cover_ix;
|
|
||||||
}
|
|
@ -1,16 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
namespace cover {
|
|
||||||
extern int cover_ix;
|
|
||||||
|
|
||||||
enum cover_type {
|
|
||||||
thebeach,
|
|
||||||
silvertrees,
|
|
||||||
redtree,
|
|
||||||
mountain,
|
|
||||||
mossycottage,
|
|
||||||
clocks,
|
|
||||||
tree,
|
|
||||||
moonmountains,
|
|
||||||
};
|
|
||||||
}
|
|
@ -1,413 +0,0 @@
|
|||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#include "printf/printf.h"
|
|
||||||
#include "aica/aica.hpp"
|
|
||||||
|
|
||||||
#include "xm_player/interpreter.hpp"
|
|
||||||
#include "xm_player/sound.hpp"
|
|
||||||
#include "xm_player/playlist.hpp"
|
|
||||||
#include "xm_player/cover.hpp"
|
|
||||||
|
|
||||||
namespace interpreter {
|
|
||||||
|
|
||||||
struct interpreter_state state = {};
|
|
||||||
|
|
||||||
// quater-semitones
|
|
||||||
//
|
|
||||||
// for i in range(48):
|
|
||||||
// round(1024 * (2 ** (i / 48) - 1))
|
|
||||||
//
|
|
||||||
const static int16_t cent_to_fns[] = {
|
|
||||||
0, 15, 30, 45, 61, 77, 93, 109, 125, 142, 159, 176,
|
|
||||||
194, 211, 229, 248, 266, 285, 304, 323, 343, 363, 383, 403,
|
|
||||||
424, 445, 467, 488, 510, 533, 555, 578, 601, 625, 649, 673,
|
|
||||||
698, 723, 749, 774, 801, 827, 854, 881, 909, 937, 966, 995
|
|
||||||
};
|
|
||||||
const int cent_to_fns_length = (sizeof (cent_to_fns)) / (sizeof (cent_to_fns[0]));
|
|
||||||
|
|
||||||
uint16_t
|
|
||||||
note_to_oct_fns(const int8_t note)
|
|
||||||
{
|
|
||||||
// log(8363 / 44100) / log(2)
|
|
||||||
const float base_ratio = -2.3986861877015477;
|
|
||||||
|
|
||||||
float c4_note = (float)note - 49.0;
|
|
||||||
float ratio = base_ratio + (c4_note / 12.0);
|
|
||||||
|
|
||||||
float whole = (int)ratio;
|
|
||||||
float fraction;
|
|
||||||
if (ratio < 0) {
|
|
||||||
if (whole > ratio)
|
|
||||||
whole -= 1;
|
|
||||||
fraction = -(whole - ratio);
|
|
||||||
} else {
|
|
||||||
fraction = ratio - whole;
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(fraction >= 0.0);
|
|
||||||
assert(fraction < 1.0);
|
|
||||||
|
|
||||||
int fns = cent_to_fns[(int)(fraction * cent_to_fns_length)];
|
|
||||||
|
|
||||||
return aica::oct_fns::OCT((int)whole) | aica::oct_fns::FNS((int)fns);
|
|
||||||
}
|
|
||||||
|
|
||||||
const static int8_t volume_table[] = {
|
|
||||||
0, 3, 5, 6, 7, 8, 8, 9, 9, 9, 10, 10, 10, 10, 11, 11,
|
|
||||||
11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13,
|
|
||||||
13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14,
|
|
||||||
14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
|
|
||||||
15
|
|
||||||
};
|
|
||||||
|
|
||||||
void _play_note(int ch, const xm_pattern_format_t * pf)
|
|
||||||
{
|
|
||||||
int instrument = (pf->instrument != 0) ? pf->instrument : state.channel[ch].instrument;
|
|
||||||
if (instrument == 0)
|
|
||||||
instrument = 1;
|
|
||||||
state.channel[ch].instrument = instrument;
|
|
||||||
|
|
||||||
xm_sample_header_t * sample_header = state.xm.sample_header[instrument - 1];
|
|
||||||
int start = state.xm.sample_data_offset[instrument - 1];
|
|
||||||
|
|
||||||
int sample_type = ((sample_header->type & (1 << 4)) != 0);
|
|
||||||
int bytes_per_sample = 1 + sample_type;
|
|
||||||
|
|
||||||
int loop_type = sample_header->type & 0b11;
|
|
||||||
int lpctl = (loop_type == 0) ? 0 : 1;
|
|
||||||
int lsa = s32(&sample_header->sample_loop_start) / bytes_per_sample;
|
|
||||||
int len = s32(&sample_header->sample_loop_length) / bytes_per_sample;
|
|
||||||
if (len == 0) {
|
|
||||||
len = s32(&sample_header->sample_length) / bytes_per_sample;
|
|
||||||
}
|
|
||||||
if (len >= 65535) {
|
|
||||||
len = 65532;
|
|
||||||
}
|
|
||||||
assert(start >= 0);
|
|
||||||
assert(lsa >= 0);
|
|
||||||
assert(len >= 0);
|
|
||||||
|
|
||||||
if (loop_type == 2) // bidirectional
|
|
||||||
len += len - 2;
|
|
||||||
|
|
||||||
int volume_column = state.channel[ch].volume;
|
|
||||||
if (pf->volume_column_byte >= 0x10 && pf->volume_column_byte <= 0x50) {
|
|
||||||
volume_column = pf->volume_column_byte - 0x10;
|
|
||||||
state.channel[ch].volume = volume_column;
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(sample_header->volume >= 0 && sample_header->volume <= 64);
|
|
||||||
int volume = (sample_header->volume * volume_column) / 64;
|
|
||||||
assert(volume >= 0 && volume <= 64);
|
|
||||||
int disdl = volume_table[volume];
|
|
||||||
bool pcms = !sample_type;
|
|
||||||
wait(); aica_sound.channel[ch].PCMS(pcms);
|
|
||||||
wait(); aica_sound.channel[ch].SA(start);
|
|
||||||
wait(); aica_sound.channel[ch].LPCTL(lpctl);
|
|
||||||
wait(); aica_sound.channel[ch].LSA((lsa) & ~(0b11));
|
|
||||||
wait(); aica_sound.channel[ch].LEA((lsa + len) & ~(0b11));
|
|
||||||
wait(); aica_sound.channel[ch].DISDL(disdl);
|
|
||||||
wait(); aica_sound.channel[ch].oct_fns = note_to_oct_fns(pf->note + sample_header->relative_note_number);
|
|
||||||
|
|
||||||
if (pf->effect_type == 0x04) { // vibrato
|
|
||||||
wait(); aica_sound.channel[ch].LFOF(0x12);
|
|
||||||
wait(); aica_sound.channel[ch].ALFOWS(2);
|
|
||||||
wait(); aica_sound.channel[ch].PLFOWS(2);
|
|
||||||
wait(); aica_sound.channel[ch].ALFOS(0);
|
|
||||||
wait(); aica_sound.channel[ch].PLFOS(4);
|
|
||||||
} else {
|
|
||||||
//wait(); aica_sound.channel[ch].LFOF(0x11);
|
|
||||||
//wait(); aica_sound.channel[ch].ALFOWS(2);
|
|
||||||
//wait(); aica_sound.channel[ch].PLFOWS(2);
|
|
||||||
wait(); aica_sound.channel[ch].ALFOS(0);
|
|
||||||
wait(); aica_sound.channel[ch].PLFOS(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
state.channel[ch].keyon = 255;
|
|
||||||
wait(); aica_sound.channel[ch].KYONB(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void play_note_effect(int ch, const xm_pattern_format_t * pf)
|
|
||||||
{
|
|
||||||
int effect_tick = state.tick % state.ticks_per_line;
|
|
||||||
|
|
||||||
switch (pf->effect_type) {
|
|
||||||
case 0x04: // 4 vibrato
|
|
||||||
wait(); aica_sound.channel[ch].LFOF(0x12);
|
|
||||||
wait(); aica_sound.channel[ch].ALFOWS(2);
|
|
||||||
wait(); aica_sound.channel[ch].PLFOWS(2);
|
|
||||||
wait(); aica_sound.channel[ch].ALFOS(0);
|
|
||||||
wait(); aica_sound.channel[ch].PLFOS(4);
|
|
||||||
break;
|
|
||||||
case 0x0d: // D pattern break
|
|
||||||
state.pattern_break = pf->effect_parameter;
|
|
||||||
break;
|
|
||||||
case 0x0e: // E
|
|
||||||
switch (pf->effect_parameter & 0xf0) {
|
|
||||||
case 0xd0: // ED note delay
|
|
||||||
if (effect_tick == (pf->effect_parameter & 0x0f)) {
|
|
||||||
_play_note(ch, pf);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 0x14: // K delayed tick
|
|
||||||
if (effect_tick == pf->effect_parameter) {
|
|
||||||
wait(); aica_sound.channel[ch].KYONB(0);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void play_note(int ch, const xm_pattern_format_t * pf)
|
|
||||||
{
|
|
||||||
if (pf->note == 97) {
|
|
||||||
wait(); aica_sound.channel[ch].KYONB(0);
|
|
||||||
} else if (pf->note != 0) {
|
|
||||||
bool note_delay = (pf->effect_type == 0xe) && ((pf->effect_parameter & 0xf0) == 0xd0); // ED note delay
|
|
||||||
if (!note_delay)
|
|
||||||
_play_note(ch, pf);
|
|
||||||
}
|
|
||||||
|
|
||||||
play_note_effect(ch, pf);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
void play_debug_note(int ch, xm_pattern_format_t * pf)
|
|
||||||
{
|
|
||||||
debug_note(ch, pf);
|
|
||||||
play_note(ch, pf);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
void rekey_note(int ch, const xm_pattern_format_t * pf)
|
|
||||||
{
|
|
||||||
if (pf->note == 97) {
|
|
||||||
} else if (pf->note != 0) {
|
|
||||||
wait(); aica_sound.channel[ch].KYONB(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void next_pattern()
|
|
||||||
{
|
|
||||||
if (state.reverse)
|
|
||||||
state.pattern_order_table_index -= 1;
|
|
||||||
else
|
|
||||||
state.pattern_order_table_index += 1;
|
|
||||||
|
|
||||||
if (state.pattern_order_table_index < 0)
|
|
||||||
state.pattern_order_table_index = state.xm.song_length - 1;
|
|
||||||
if (state.pattern_order_table_index >= state.xm.song_length) {
|
|
||||||
if (state.repeat) {
|
|
||||||
state.pattern_order_table_index = 0;
|
|
||||||
} else if (state.reverse) {
|
|
||||||
if (playlist::prev(false))
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
if (playlist::next(false))
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
printf("pattern_order_table_index: %d\n", state.pattern_order_table_index);
|
|
||||||
|
|
||||||
state.pattern_index = state.xm.header->pattern_order_table[state.pattern_order_table_index];
|
|
||||||
|
|
||||||
if (state.pattern_break >= 0) {
|
|
||||||
state.next_line_index = state.pattern_break;
|
|
||||||
} else {
|
|
||||||
int line_count = state.xm.pattern_note_count[state.pattern_index] / state.xm.number_of_channels;
|
|
||||||
if (state.reverse)
|
|
||||||
state.next_line_index = line_count - 1;
|
|
||||||
else
|
|
||||||
state.next_line_index = 0;
|
|
||||||
}
|
|
||||||
state.pattern_break = -1;
|
|
||||||
|
|
||||||
printf("note_count: %d\n", state.xm.pattern_note_count[state.pattern_index]);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <void (*F)(int, const xm_pattern_format_t *)>
|
|
||||||
void execute_line(int line_index)
|
|
||||||
{
|
|
||||||
int line_pattern_index = line_index * state.xm.number_of_channels;
|
|
||||||
for (int ch = 0; ch < state.xm.number_of_channels; ch++) {
|
|
||||||
xm_pattern_format_t * pattern = state.xm.pattern[state.pattern_index];
|
|
||||||
F(ch, &pattern[line_pattern_index + ch]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void interrupt()
|
|
||||||
{
|
|
||||||
if (state.deferred_load_tick == 1) {
|
|
||||||
deferred_load_finish();
|
|
||||||
}
|
|
||||||
if (state.deferred_load_tick > 0) {
|
|
||||||
state.deferred_load_tick -= 1;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (state.paused)
|
|
||||||
return;
|
|
||||||
|
|
||||||
state.interrupt_clock += 1;
|
|
||||||
// execute keyons
|
|
||||||
for (int ch = 0; ch < 64; ch++) {
|
|
||||||
/*
|
|
||||||
if (state.channel[ch].keyon == 2) {
|
|
||||||
int sgc = aica_sound.common.SGC();
|
|
||||||
if (sgc == 3) {
|
|
||||||
wait(); aica_sound.channel[ch].KYONB(1);
|
|
||||||
state.channel[ch].keyon = 0;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
} else if (state.channel[ch].keyon == 1) {
|
|
||||||
wait(); aica_sound.common.afsel_mslc_mobuf
|
|
||||||
= aica::afsel_mslc_mobuf::AFSEL(0)
|
|
||||||
| aica::afsel_mslc_mobuf::MSLC(ch);
|
|
||||||
state.channel[ch].keyon = 2;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
const int keyon_tick = 254;
|
|
||||||
if (state.channel[ch].keyon > keyon_tick) {
|
|
||||||
state.channel[ch].keyon -= 1;
|
|
||||||
}
|
|
||||||
else if (state.channel[ch].keyon == keyon_tick) {
|
|
||||||
wait(); aica_sound.channel[ch].KYONB(1);
|
|
||||||
state.channel[ch].keyon -= 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
wait(); aica_sound.channel[0].KYONEX(1);
|
|
||||||
|
|
||||||
if ((state.interrupt_clock % state.current_tick_rate) != 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
for (int ch = 0; ch < 64; ch++) {
|
|
||||||
int keyon = state.channel[ch].keyon;
|
|
||||||
if (keyon != 0) {
|
|
||||||
state.channel[ch].keyon -= 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int tick = state.tick % state.ticks_per_line;
|
|
||||||
bool note_tick = tick == 0;
|
|
||||||
if (note_tick) {
|
|
||||||
// execute notes
|
|
||||||
state.line_index = state.next_line_index;
|
|
||||||
if (state.reverse)
|
|
||||||
state.next_line_index -= 1;
|
|
||||||
else
|
|
||||||
state.next_line_index += 1;
|
|
||||||
|
|
||||||
execute_line<play_note>(state.line_index);
|
|
||||||
} else {
|
|
||||||
// execute effects
|
|
||||||
execute_line<play_note_effect>(state.line_index);
|
|
||||||
}
|
|
||||||
wait(); aica_sound.channel[0].KYONEX(1);
|
|
||||||
|
|
||||||
bool pattern_break_tick = tick == (state.ticks_per_line - 1);
|
|
||||||
if (pattern_break_tick) {
|
|
||||||
if (state.pattern_break >= 0) {
|
|
||||||
printf("pattern_break\n");
|
|
||||||
next_pattern();
|
|
||||||
}
|
|
||||||
int note_index = state.next_line_index * state.xm.number_of_channels;
|
|
||||||
bool end_of_pattern
|
|
||||||
= note_index < 0
|
|
||||||
|| note_index >= state.xm.pattern_note_count[state.pattern_index];
|
|
||||||
|
|
||||||
if (end_of_pattern) {
|
|
||||||
printf("end_of_pattern\n");
|
|
||||||
next_pattern();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
state.tick += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void init(float clock_multiplier)
|
|
||||||
{
|
|
||||||
// 195 = 1ms
|
|
||||||
// 2500 / bpm milliseconds
|
|
||||||
|
|
||||||
int default_bpm = s16(&state.xm.header->default_bpm);
|
|
||||||
int default_tempo = s16(&state.xm.header->default_tempo);
|
|
||||||
int tick_rate = clock_multiplier * 2500 / default_bpm;
|
|
||||||
|
|
||||||
printf("default_bpm %d\n", default_bpm);
|
|
||||||
printf("default_tempo %d\n", default_tempo);
|
|
||||||
printf("tick_rate %d\n", tick_rate);
|
|
||||||
|
|
||||||
state.current_tick_rate = tick_rate;
|
|
||||||
state.default_tick_rate = tick_rate;
|
|
||||||
state.ticks_per_line = default_tempo;
|
|
||||||
state.tick = 0;
|
|
||||||
state.line_index = 0;
|
|
||||||
state.pattern_order_table_index = -1;
|
|
||||||
next_pattern();
|
|
||||||
for (int ch = 0; ch < 64; ch++) {
|
|
||||||
state.channel[ch].keyon = 0;
|
|
||||||
state.channel[ch].volume = 64;
|
|
||||||
}
|
|
||||||
state.paused = false;
|
|
||||||
|
|
||||||
printf("tick_rate %d\n", state.current_tick_rate);
|
|
||||||
}
|
|
||||||
|
|
||||||
void stop_sound()
|
|
||||||
{
|
|
||||||
for (int ch = 0; ch < 64; ch++) {
|
|
||||||
wait();
|
|
||||||
//bool kyonb = aica_sound.channel[ch].KYONB() != 0;
|
|
||||||
wait(); aica_sound.channel[ch].KYONB(0);
|
|
||||||
//state.channel[ch].keyon = kyonb ? 255 : 0;
|
|
||||||
}
|
|
||||||
wait(); aica_sound.channel[0].KYONEX(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
void resume_sound()
|
|
||||||
{
|
|
||||||
for (int ch = 0; ch < 64; ch++) {
|
|
||||||
wait(); aica_sound.channel[ch].RR(0xa);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void pause()
|
|
||||||
{
|
|
||||||
stop_sound();
|
|
||||||
state.paused = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void unpause()
|
|
||||||
{
|
|
||||||
state.paused = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint8_t __attribute__((aligned(32))) sample_data[1024 * 1024 * 2];
|
|
||||||
const int sample_data_length = (sizeof (sample_data));
|
|
||||||
|
|
||||||
void deferred_load(int buf, int cover_ix)
|
|
||||||
{
|
|
||||||
const float aica_clock_multiplier = 44.1 / 3;
|
|
||||||
state.deferred_cover_ix = cover_ix;
|
|
||||||
|
|
||||||
state.deferred_load_tick = aica_clock_multiplier * 1000 / 2;
|
|
||||||
|
|
||||||
state.sample_data_ix = xm_init(&interpreter::state.xm,
|
|
||||||
buf,
|
|
||||||
sample_data,
|
|
||||||
sample_data_length);
|
|
||||||
interpreter::init(aica_clock_multiplier);
|
|
||||||
}
|
|
||||||
|
|
||||||
void deferred_load_finish()
|
|
||||||
{
|
|
||||||
sound::transfer(sample_data, state.sample_data_ix);
|
|
||||||
|
|
||||||
cover::cover_ix = state.deferred_cover_ix;
|
|
||||||
|
|
||||||
resume_sound();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,50 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "xm_player/xm.h"
|
|
||||||
|
|
||||||
namespace interpreter {
|
|
||||||
|
|
||||||
constexpr int max_channels = 64;
|
|
||||||
|
|
||||||
struct channel_state {
|
|
||||||
uint8_t instrument;
|
|
||||||
uint8_t keyon;
|
|
||||||
uint8_t volume;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct interpreter_state {
|
|
||||||
int interrupt_clock;
|
|
||||||
int current_tick_rate;
|
|
||||||
int default_tick_rate;
|
|
||||||
int ticks_per_line;
|
|
||||||
int tick;
|
|
||||||
int pattern_order_table_index;
|
|
||||||
int pattern_break;
|
|
||||||
int pattern_index;
|
|
||||||
int line_index;
|
|
||||||
int next_line_index; // within the current pattern
|
|
||||||
bool paused;
|
|
||||||
bool reverse;
|
|
||||||
bool repeat;
|
|
||||||
|
|
||||||
int deferred_load_tick;
|
|
||||||
int sample_data_ix;
|
|
||||||
int deferred_cover_ix;
|
|
||||||
|
|
||||||
struct xm_state xm;
|
|
||||||
|
|
||||||
struct channel_state channel[max_channels];
|
|
||||||
};
|
|
||||||
|
|
||||||
extern struct interpreter_state state;
|
|
||||||
void interrupt();
|
|
||||||
void init(float clock_multiplier);
|
|
||||||
void pause();
|
|
||||||
void unpause();
|
|
||||||
|
|
||||||
void resume_sound();
|
|
||||||
void stop_sound();
|
|
||||||
|
|
||||||
void deferred_load(int buf, int cover_ix);
|
|
||||||
void deferred_load_finish();
|
|
||||||
}
|
|
@ -1,33 +0,0 @@
|
|||||||
#include "assert.h"
|
|
||||||
#include "malloc.h"
|
|
||||||
|
|
||||||
struct arena {
|
|
||||||
uint8_t * mem;
|
|
||||||
uint32_t size;
|
|
||||||
uint32_t ix;
|
|
||||||
};
|
|
||||||
|
|
||||||
static uint8_t arena_mem[0x100000];
|
|
||||||
|
|
||||||
static struct arena arena = {
|
|
||||||
.mem = arena_mem,
|
|
||||||
.size = (sizeof (arena_mem)),
|
|
||||||
.ix = 0,
|
|
||||||
};
|
|
||||||
|
|
||||||
void malloc_arena_reset()
|
|
||||||
{
|
|
||||||
arena.ix = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void * malloc_arena(uint32_t size)
|
|
||||||
{
|
|
||||||
if (size == 0)
|
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
assert((arena.ix & (~3)) == arena.ix);
|
|
||||||
void * ptr = &arena.mem[arena.ix];
|
|
||||||
size = (size + 3) & (~3);
|
|
||||||
arena.ix += size;
|
|
||||||
return ptr;
|
|
||||||
}
|
|
@ -1,14 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void malloc_arena_reset();
|
|
||||||
void * malloc_arena(uint32_t size);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
@ -1,107 +0,0 @@
|
|||||||
#include "interpreter.hpp"
|
|
||||||
#include "sound.hpp"
|
|
||||||
#include "playlist.hpp"
|
|
||||||
|
|
||||||
#include "xm_player/xm.h"
|
|
||||||
#include "xm_player/cover.hpp"
|
|
||||||
|
|
||||||
#include "xm/CloudsAhead.xm.h"
|
|
||||||
#include "xm/CottageFantasy.xm.h"
|
|
||||||
#include "xm/RedBlossom.xm.h"
|
|
||||||
#include "xm/TheClockOfElery.xm.h"
|
|
||||||
#include "xm/ForestAtTwilight.xm.h"
|
|
||||||
#include "xm/SpringWaltz.xm.h"
|
|
||||||
#include "xm/TheMountainsOfElmindeer.xm.h"
|
|
||||||
|
|
||||||
#include "platform/texture.hpp"
|
|
||||||
|
|
||||||
namespace playlist {
|
|
||||||
|
|
||||||
struct state state = {
|
|
||||||
.playlist_ix = -1,
|
|
||||||
.loops = -1,
|
|
||||||
};
|
|
||||||
|
|
||||||
const playlist_item playlist[] = {
|
|
||||||
{
|
|
||||||
.artist = "Shiroiii",
|
|
||||||
.title = "Clouds Ahead",
|
|
||||||
.start = (int)&_binary_xm_CloudsAhead_xm_start,
|
|
||||||
.cover_ix = texture::offset::thebeach,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.artist = "Shiroiii",
|
|
||||||
.title = "Cottage Fantasy",
|
|
||||||
.start = (int)&_binary_xm_CottageFantasy_xm_start,
|
|
||||||
.cover_ix = texture::offset::mossycottage,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.artist = "Shiroiii",
|
|
||||||
.title = "Red Blossom",
|
|
||||||
.start = (int)&_binary_xm_RedBlossom_xm_start,
|
|
||||||
.cover_ix = texture::offset::redtree,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.artist = "Shiroiii",
|
|
||||||
.title = "The Clock Of Elery",
|
|
||||||
.start = (int)&_binary_xm_TheClockOfElery_xm_start,
|
|
||||||
.cover_ix = texture::offset::clocks,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.artist = "Shiroiii",
|
|
||||||
.title = "Forest At Twilight",
|
|
||||||
.start = (int)&_binary_xm_ForestAtTwilight_xm_start,
|
|
||||||
.cover_ix = texture::offset::silvertrees,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.artist = "Shiroiii",
|
|
||||||
.title = "Spring Waltz",
|
|
||||||
.start = (int)&_binary_xm_SpringWaltz_xm_start,
|
|
||||||
.cover_ix = texture::offset::tree,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.artist = "Shiroiii",
|
|
||||||
.title = "Mountains of Elmindeer",
|
|
||||||
.start = (int)&_binary_xm_TheMountainsOfElmindeer_xm_start,
|
|
||||||
.cover_ix = texture::offset::mountain,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const int playlist_length = (sizeof (playlist)) / (sizeof (playlist[0]));
|
|
||||||
|
|
||||||
bool next(bool stop_sound)
|
|
||||||
{
|
|
||||||
if (state.loops < 0 || state.loops >= 1) {
|
|
||||||
state.playlist_ix += 1;
|
|
||||||
state.loops = 0;
|
|
||||||
|
|
||||||
if (state.playlist_ix >= playlist_length)
|
|
||||||
state.playlist_ix = 0;
|
|
||||||
|
|
||||||
printf("next deferred_load playlist_ix %d\n", state.playlist_ix);
|
|
||||||
interpreter::stop_sound();
|
|
||||||
|
|
||||||
const playlist_item& item = playlist[state.playlist_ix];
|
|
||||||
interpreter::deferred_load(item.start, item.cover_ix);
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
state.loops += 1;
|
|
||||||
interpreter::state.pattern_order_table_index = 0;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool prev(bool stop_sound)
|
|
||||||
{
|
|
||||||
state.playlist_ix -= 1;
|
|
||||||
if (state.playlist_ix < 0)
|
|
||||||
state.playlist_ix = playlist_length - 1;
|
|
||||||
|
|
||||||
printf("prev deferred_load playlist_ix %d\n", state.playlist_ix);
|
|
||||||
interpreter::stop_sound();
|
|
||||||
const playlist_item& item = playlist[state.playlist_ix];
|
|
||||||
interpreter::deferred_load(item.start, item.cover_ix);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,22 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
namespace playlist {
|
|
||||||
struct playlist_item {
|
|
||||||
const char * const artist;
|
|
||||||
const char * const title;
|
|
||||||
const int start;
|
|
||||||
const int cover_ix;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct state {
|
|
||||||
int playlist_ix;
|
|
||||||
int loops;
|
|
||||||
};
|
|
||||||
|
|
||||||
bool next(bool stop_sound=true);
|
|
||||||
bool prev(bool stop_sound=true);
|
|
||||||
|
|
||||||
extern struct state state;
|
|
||||||
extern const playlist_item playlist[];
|
|
||||||
extern const int playlist_length;
|
|
||||||
}
|
|
@ -1,152 +0,0 @@
|
|||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#include "memorymap.hpp"
|
|
||||||
|
|
||||||
#include "systembus.hpp"
|
|
||||||
#include "systembus_bits.hpp"
|
|
||||||
|
|
||||||
#include "sh7091/sh7091.hpp"
|
|
||||||
#include "sh7091/sh7091_bits.hpp"
|
|
||||||
#include "sh7091/serial.hpp"
|
|
||||||
|
|
||||||
#include "printf/printf.h"
|
|
||||||
|
|
||||||
#include "aica/aica.hpp"
|
|
||||||
|
|
||||||
#include "sound.hpp"
|
|
||||||
|
|
||||||
#include "assert.h"
|
|
||||||
|
|
||||||
static void g2_aica_dma(uint32_t g2_address, uint32_t system_address, int length)
|
|
||||||
{
|
|
||||||
using namespace dmac;
|
|
||||||
|
|
||||||
constexpr uint32_t dma_address_mask = 0x1fffffe0;
|
|
||||||
|
|
||||||
length = (length + 31) & (~31);
|
|
||||||
|
|
||||||
// is DMAOR needed?
|
|
||||||
sh7091.DMAC.DMAOR = dmaor::ddt::on_demand_data_transfer_mode /* on-demand data transfer mode */
|
|
||||||
| dmaor::pr::ch2_ch0_ch1_ch3 /* priority mode; CH2 > CH0 > CH1 > CH3 */
|
|
||||||
| dmaor::dme::operation_enabled_on_all_channels; /* DMAC master enable */
|
|
||||||
|
|
||||||
|
|
||||||
g2_if.ADEN = 0; // disable G2-AICA-DMA
|
|
||||||
|
|
||||||
g2_if.G2APRO = 0x4659007f; // disable protection
|
|
||||||
|
|
||||||
g2_if.ADSTAG = dma_address_mask & g2_address; // G2 address
|
|
||||||
g2_if.ADSTAR = dma_address_mask & system_address; // system memory address
|
|
||||||
g2_if.ADLEN = length;
|
|
||||||
g2_if.ADDIR = 0; // from root bus to G2 device
|
|
||||||
g2_if.ADTSEL = 0; // CPU controlled trigger
|
|
||||||
g2_if.ADEN = 1; // enable G2-AICA-DMA
|
|
||||||
g2_if.ADST = 1; // start G2-AICA-DMA
|
|
||||||
}
|
|
||||||
|
|
||||||
static void g2_aica_dma_wait_complete()
|
|
||||||
{
|
|
||||||
// wait for maple DMA completion
|
|
||||||
while ((system.ISTNRM & istnrm::end_of_dma_aica_dma) == 0);
|
|
||||||
system.ISTNRM = istnrm::end_of_dma_aica_dma;
|
|
||||||
assert(g2_if.ADST == 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void writeback(void const * const buf, uint32_t size)
|
|
||||||
{
|
|
||||||
uint8_t const * const buf8 = reinterpret_cast<uint8_t const * const>(buf);
|
|
||||||
|
|
||||||
for (uint32_t i = 0; i < size / (32); i++) {
|
|
||||||
asm volatile ("ocbwb @%0"
|
|
||||||
: // output
|
|
||||||
: "r" (&buf8[i * 32]) // input
|
|
||||||
: "memory"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint8_t __attribute__((aligned(32))) zero[0x28c0] = {};
|
|
||||||
|
|
||||||
namespace sound {
|
|
||||||
|
|
||||||
void init()
|
|
||||||
{
|
|
||||||
printf("sound::init\n");
|
|
||||||
|
|
||||||
wait(); aica_sound.common.vreg_armrst = aica::vreg_armrst::ARMRST(1);
|
|
||||||
wait(); aica_sound.common.dmea0_mrwinh = aica::dmea0_mrwinh::MRWINH(0b0111);
|
|
||||||
system.ISTNRM = istnrm::end_of_dma_aica_dma;
|
|
||||||
|
|
||||||
writeback(zero, (sizeof (zero)));
|
|
||||||
|
|
||||||
// slot/common: 00700000 - 007028c0 (excludes vreg_armrst)
|
|
||||||
g2_aica_dma((uint32_t)0x00700000, (int)zero, 0x28c0);
|
|
||||||
g2_aica_dma_wait_complete();
|
|
||||||
|
|
||||||
// dsp : 00703000 - 007045c8
|
|
||||||
g2_aica_dma((uint32_t)0x00703000, (int)zero, 0x15e0);
|
|
||||||
g2_aica_dma_wait_complete();
|
|
||||||
|
|
||||||
wait(); aica_sound.common.dmea0_mrwinh = aica::dmea0_mrwinh::MRWINH(0b0001);
|
|
||||||
|
|
||||||
for (int i = 0; i < 64; i++) {
|
|
||||||
wait(); aica_sound.channel[i].KYONB(0);
|
|
||||||
wait(); aica_sound.channel[i].LPCTL(0);
|
|
||||||
wait(); aica_sound.channel[i].PCMS(0);
|
|
||||||
wait(); aica_sound.channel[i].LSA(0);
|
|
||||||
wait(); aica_sound.channel[i].LEA(0);
|
|
||||||
|
|
||||||
wait(); aica_sound.channel[i].D2R(0xa);
|
|
||||||
wait(); aica_sound.channel[i].D1R(0xa);
|
|
||||||
wait(); aica_sound.channel[i].RR(0xa);
|
|
||||||
wait(); aica_sound.channel[i].AR(0x1f);
|
|
||||||
/*
|
|
||||||
wait(); aica_sound.channel[i].D2R(0);
|
|
||||||
wait(); aica_sound.channel[i].D1R(0);
|
|
||||||
wait(); aica_sound.channel[i].RR(0x1f);
|
|
||||||
wait(); aica_sound.channel[i].AR(0x1f);
|
|
||||||
*/
|
|
||||||
|
|
||||||
wait(); aica_sound.channel[i].ALFOS(0);
|
|
||||||
wait(); aica_sound.channel[i].PLFOS(0);
|
|
||||||
|
|
||||||
wait(); aica_sound.channel[i].OCT(0);
|
|
||||||
wait(); aica_sound.channel[i].FNS(0);
|
|
||||||
wait(); aica_sound.channel[i].DISDL(0);
|
|
||||||
wait(); aica_sound.channel[i].DIPAN(0);
|
|
||||||
|
|
||||||
wait(); aica_sound.channel[i].Q(0b00100);
|
|
||||||
wait(); aica_sound.channel[i].TL(0);
|
|
||||||
wait(); aica_sound.channel[i].LPOFF(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
wait(); aica_sound.channel[0].KYONEX(1);
|
|
||||||
|
|
||||||
wait(); aica_sound.common.mono_mem8mb_dac18b_ver_mvol =
|
|
||||||
aica::mono_mem8mb_dac18b_ver_mvol::MONO(0) // enable panpots
|
|
||||||
| aica::mono_mem8mb_dac18b_ver_mvol::MEM8MB(0) // 16Mbit SDRAM
|
|
||||||
| aica::mono_mem8mb_dac18b_ver_mvol::DAC18B(0) // 16-bit DAC
|
|
||||||
| aica::mono_mem8mb_dac18b_ver_mvol::MVOL(0xc) // volume
|
|
||||||
;
|
|
||||||
|
|
||||||
wait(); aica_sound.common.tactl_tima =
|
|
||||||
aica::tactl_tima::TACTL(0) // increment once every sample
|
|
||||||
| aica::tactl_tima::TIMA(0xfffd) // interrupt after 3 counts
|
|
||||||
;
|
|
||||||
|
|
||||||
wait(); aica_sound.common.mcieb = (1 << 6); // interrupt timer A
|
|
||||||
wait(); aica_sound.common.mcire = (1 << 6); // interrupt timer A
|
|
||||||
}
|
|
||||||
|
|
||||||
void transfer(const void * sample_data, int sample_data_ix)
|
|
||||||
{
|
|
||||||
printf("aica transfer 0x%08x 0x%08x 0x%x\n", (int)aica_wave_memory, (int)sample_data, sample_data_ix);
|
|
||||||
|
|
||||||
int size = (sample_data_ix + 31) & (~31);
|
|
||||||
writeback(sample_data, size);
|
|
||||||
|
|
||||||
g2_aica_dma((int)aica_wave_memory, (int)sample_data, size);
|
|
||||||
g2_aica_dma_wait_complete();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,22 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "systembus.hpp"
|
|
||||||
#include "systembus_bits.hpp"
|
|
||||||
|
|
||||||
static inline void wait()
|
|
||||||
{
|
|
||||||
uint32_t ffst = system.FFST;
|
|
||||||
while ( ffst::holly_cpu_if_block_internal_write_buffer(ffst)
|
|
||||||
| ffst::holly_g2_if_block_internal_write_buffer(ffst)
|
|
||||||
| ffst::aica_internal_write_buffer(ffst)) {
|
|
||||||
ffst = system.FFST;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace sound {
|
|
||||||
|
|
||||||
void init();
|
|
||||||
|
|
||||||
void transfer(const void * sample_data, int sample_data_ix);
|
|
||||||
|
|
||||||
}
|
|
@ -1,223 +0,0 @@
|
|||||||
#include "xm/xm.h"
|
|
||||||
#include "printf/printf.h"
|
|
||||||
#include "xm.h"
|
|
||||||
#include "malloc.h"
|
|
||||||
|
|
||||||
static int xm_unpack_sample(int buf,
|
|
||||||
int offset,
|
|
||||||
xm_sample_header_t * sample_header,
|
|
||||||
uint8_t * sample_data,
|
|
||||||
int sample_data_ix)
|
|
||||||
{
|
|
||||||
int size = s32(&sample_header->sample_length);
|
|
||||||
int loop_start = s32(&sample_header->sample_loop_start);
|
|
||||||
int loop_length = s32(&sample_header->sample_loop_length);
|
|
||||||
|
|
||||||
int loop_type = sample_header->type & 0b11;
|
|
||||||
|
|
||||||
if (sample_header->type & (1 << 4)) { // 16-bit samples
|
|
||||||
int num_samples = size / 2;
|
|
||||||
int lsa = loop_start / 2;
|
|
||||||
int len = loop_length / 2;
|
|
||||||
|
|
||||||
int old = 0;
|
|
||||||
volatile int16_t * out = (volatile int16_t *)(&sample_data[sample_data_ix]);
|
|
||||||
int16_t * in = (int16_t *)(buf + offset);
|
|
||||||
for (int i = 0; i < num_samples; i++) {
|
|
||||||
old += s16(&in[i]);
|
|
||||||
out[i] = old;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (loop_type == 2) { // bidirectional
|
|
||||||
for (int i = 0; i < len - 2; i++) {
|
|
||||||
out[num_samples + i] = out[lsa + (len - i - 2)];
|
|
||||||
}
|
|
||||||
|
|
||||||
size += (len - 2) * 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
} else { // 8-bit
|
|
||||||
int num_samples = size;
|
|
||||||
int lsa = loop_start;
|
|
||||||
int len = loop_length;
|
|
||||||
|
|
||||||
int old = 0;
|
|
||||||
volatile int8_t * out = (volatile int8_t *)(&sample_data[sample_data_ix]);
|
|
||||||
int8_t * in = (int8_t *)(buf + offset);
|
|
||||||
for (int i = 0; i < num_samples; i++) {
|
|
||||||
old += in[i];
|
|
||||||
out[i] = old;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (loop_type == 2) { // bidirectional
|
|
||||||
for (int i = 0; i < len - 2; i++) {
|
|
||||||
out[num_samples + i] = out[lsa + (len - i - 2)];
|
|
||||||
}
|
|
||||||
|
|
||||||
size += (len - 2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (size & 1) {
|
|
||||||
size += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int xm_samples_init(xm_state_t * xm,
|
|
||||||
int buf,
|
|
||||||
int offset,
|
|
||||||
int instrument_ix,
|
|
||||||
int number_of_samples,
|
|
||||||
uint8_t * sample_data,
|
|
||||||
int sample_data_length,
|
|
||||||
int * sample_data_ix)
|
|
||||||
{
|
|
||||||
xm_sample_header_t * sample_header[number_of_samples];
|
|
||||||
xm->sample_header[instrument_ix] = (xm_sample_header_t *)(buf + offset);
|
|
||||||
//if (instrument_ix <= 12)
|
|
||||||
//debug_xm_sample_header(instrument_ix, xm->sample_header[instrument_ix]);
|
|
||||||
|
|
||||||
for (int i = 0; i < number_of_samples; i++) {
|
|
||||||
sample_header[i] = (xm_sample_header_t *)(buf + offset);
|
|
||||||
offset += (sizeof (xm_sample_header_t));
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < number_of_samples; i++) {
|
|
||||||
int sample_length = s32(&sample_header[i]->sample_length);
|
|
||||||
if (sample_length > 0) {
|
|
||||||
//printf(" sample_length % 6d\n", sample_length);
|
|
||||||
xm->sample_data_offset[instrument_ix] = *sample_data_ix;
|
|
||||||
*sample_data_ix += xm_unpack_sample(buf,
|
|
||||||
offset,
|
|
||||||
sample_header[i],
|
|
||||||
sample_data,
|
|
||||||
*sample_data_ix);
|
|
||||||
assert(*sample_data_ix <= sample_data_length);
|
|
||||||
}
|
|
||||||
offset += sample_length;
|
|
||||||
}
|
|
||||||
return offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline xm_pattern_format_t parse_pattern_line(uint8_t * pattern, int * note_offset)
|
|
||||||
{
|
|
||||||
int offset = *note_offset;
|
|
||||||
|
|
||||||
int p = pattern[offset];
|
|
||||||
if (p & 0x80) {
|
|
||||||
offset += 1;
|
|
||||||
xm_pattern_format_t pf = {};
|
|
||||||
if (p & (1 << 0))
|
|
||||||
pf.note = pattern[offset++];
|
|
||||||
if (p & (1 << 1))
|
|
||||||
pf.instrument = pattern[offset++];
|
|
||||||
if (p & (1 << 2))
|
|
||||||
pf.volume_column_byte = pattern[offset++];
|
|
||||||
if (p & (1 << 3))
|
|
||||||
pf.effect_type = pattern[offset++];
|
|
||||||
if (p & (1 << 4))
|
|
||||||
pf.effect_parameter = pattern[offset++];
|
|
||||||
*note_offset = offset;
|
|
||||||
return pf;
|
|
||||||
} else {
|
|
||||||
xm_pattern_format_t * pf = (xm_pattern_format_t *)&pattern[offset];
|
|
||||||
offset += 5;
|
|
||||||
*note_offset = offset;
|
|
||||||
return *pf;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int count_pattern_notes(uint8_t * pattern, int pattern_data_size)
|
|
||||||
{
|
|
||||||
int note_offset = 0;
|
|
||||||
int note_count = 0;
|
|
||||||
|
|
||||||
while (note_offset < pattern_data_size) {
|
|
||||||
parse_pattern_line(pattern, ¬e_offset);
|
|
||||||
note_count += 1;
|
|
||||||
}
|
|
||||||
assert(note_offset == pattern_data_size);
|
|
||||||
|
|
||||||
return note_count;
|
|
||||||
}
|
|
||||||
|
|
||||||
void xm_unpack_pattern(xm_state_t * xm,
|
|
||||||
int pattern_index)
|
|
||||||
{
|
|
||||||
xm_pattern_header_t * pattern_header = xm->pattern_header[pattern_index];
|
|
||||||
uint8_t * pattern = (uint8_t *)(((int)pattern_header) + s32(&pattern_header->pattern_header_length));
|
|
||||||
|
|
||||||
int pattern_data_size = s16(&pattern_header->packed_pattern_data_size);
|
|
||||||
|
|
||||||
int note_count = count_pattern_notes(pattern, pattern_data_size);
|
|
||||||
|
|
||||||
xm_pattern_format_t * pf = (xm_pattern_format_t *)malloc_arena((sizeof (xm_pattern_format_t)) * note_count);
|
|
||||||
|
|
||||||
xm->pattern[pattern_index] = pf;
|
|
||||||
xm->pattern_note_count[pattern_index] = note_count;
|
|
||||||
|
|
||||||
int note_offset = 0;
|
|
||||||
for (int i = 0; i < note_count; i++) {
|
|
||||||
pf[i] = parse_pattern_line(pattern, ¬e_offset);
|
|
||||||
}
|
|
||||||
assert(note_offset == pattern_data_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
int xm_init(xm_state_t * xm,
|
|
||||||
int buf,
|
|
||||||
uint8_t * sample_data,
|
|
||||||
int sample_data_length)
|
|
||||||
{
|
|
||||||
int sample_data_ix = 0;
|
|
||||||
|
|
||||||
xm->header = (xm_header_t *)(buf);
|
|
||||||
|
|
||||||
int offset = s32(&xm->header->header_size) + (offsetof (struct xm_header, header_size));
|
|
||||||
int number_of_patterns = s16(&xm->header->number_of_patterns);
|
|
||||||
printf("number_of_patterns: %d\n", number_of_patterns);
|
|
||||||
|
|
||||||
for (int i = 0; i < number_of_patterns; i++) {
|
|
||||||
xm_pattern_header_t * pattern_header = (xm_pattern_header_t *)(buf + offset);
|
|
||||||
xm->pattern_header[i] = pattern_header;
|
|
||||||
offset += s32(&pattern_header->pattern_header_length) + s16(&pattern_header->packed_pattern_data_size);
|
|
||||||
}
|
|
||||||
printf("end_of_patterns: %d\n", offset);
|
|
||||||
|
|
||||||
int number_of_instruments = s16(&xm->header->number_of_instruments);
|
|
||||||
for (int instrument_ix = 0; instrument_ix < number_of_instruments; instrument_ix++) {
|
|
||||||
xm_instrument_header_t * instrument_header = (xm_instrument_header_t *)(buf + offset);
|
|
||||||
|
|
||||||
xm->instrument_header[instrument_ix] = instrument_header;
|
|
||||||
offset += s32(&instrument_header->instrument_size);
|
|
||||||
|
|
||||||
int number_of_samples = s16(&instrument_header->number_of_samples);
|
|
||||||
offset = xm_samples_init(xm,
|
|
||||||
buf,
|
|
||||||
offset,
|
|
||||||
instrument_ix,
|
|
||||||
number_of_samples,
|
|
||||||
sample_data,
|
|
||||||
sample_data_length,
|
|
||||||
&sample_data_ix);
|
|
||||||
}
|
|
||||||
printf("end_of_instruments: %d\n", offset);
|
|
||||||
|
|
||||||
int number_of_channels = s16(&xm->header->number_of_channels);
|
|
||||||
xm->number_of_channels = number_of_channels;
|
|
||||||
printf("number_of_channels: %d\n", number_of_channels);
|
|
||||||
|
|
||||||
int song_length = s16(&xm->header->song_length);
|
|
||||||
xm->song_length = song_length;
|
|
||||||
printf("song_length: %d\n", song_length);
|
|
||||||
|
|
||||||
// reset arena
|
|
||||||
malloc_arena_reset();
|
|
||||||
|
|
||||||
for (int pattern_index = 0; pattern_index < number_of_patterns; pattern_index++) {
|
|
||||||
xm_unpack_pattern(xm, pattern_index);
|
|
||||||
}
|
|
||||||
|
|
||||||
return sample_data_ix;
|
|
||||||
}
|
|
@ -1,46 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "xm/xm.h"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define xm_max_patterns 64
|
|
||||||
#define xm_max_instruments 128
|
|
||||||
|
|
||||||
typedef struct xm_state {
|
|
||||||
xm_header_t * header;
|
|
||||||
xm_pattern_header_t * pattern_header[xm_max_patterns];
|
|
||||||
xm_instrument_header_t * instrument_header[xm_max_instruments];
|
|
||||||
xm_sample_header_t * sample_header[xm_max_instruments]; // array
|
|
||||||
int sample_data_offset[xm_max_instruments];
|
|
||||||
|
|
||||||
int number_of_channels;
|
|
||||||
int song_length;
|
|
||||||
xm_pattern_format_t * pattern[xm_max_patterns];
|
|
||||||
int pattern_note_count[xm_max_patterns];
|
|
||||||
} xm_state_t;
|
|
||||||
|
|
||||||
int xm_init(xm_state_t * xm,
|
|
||||||
int buf,
|
|
||||||
uint8_t * sample_data,
|
|
||||||
int sample_data_length);
|
|
||||||
|
|
||||||
static inline int s16(void * buf)
|
|
||||||
{
|
|
||||||
uint8_t * b = (uint8_t *)buf;
|
|
||||||
int16_t v = (b[0] << 0) | (b[1] << 8);
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int s32(void * buf)
|
|
||||||
{
|
|
||||||
uint8_t * b = (uint8_t *)buf;
|
|
||||||
int32_t v = (b[0] << 0) | (b[1] << 8) | (b[2] << 16) | (b[3] << 24);
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
@ -51,8 +51,6 @@ def visit_pixels(x, y, width, height):
|
|||||||
xx = x + xi
|
xx = x + xi
|
||||||
yy = y + yi
|
yy = y + yi
|
||||||
location = (xx, yy)
|
location = (xx, yy)
|
||||||
if location in visited:
|
|
||||||
print(location)
|
|
||||||
assert location not in visited
|
assert location not in visited
|
||||||
visited.add(location)
|
visited.add(location)
|
||||||
|
|
||||||
|
@ -1,15 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern uint32_t _binary_xm_CloudsAhead_xm_start __asm("_binary_xm_CloudsAhead_xm_start");
|
|
||||||
extern uint32_t _binary_xm_CloudsAhead_xm_end __asm("_binary_xm_CloudsAhead_xm_end");
|
|
||||||
extern uint32_t _binary_xm_CloudsAhead_xm_size __asm("_binary_xm_CloudsAhead_xm_size");
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
@ -1,15 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern uint32_t _binary_xm_CottageFantasy_xm_start __asm("_binary_xm_CottageFantasy_xm_start");
|
|
||||||
extern uint32_t _binary_xm_CottageFantasy_xm_end __asm("_binary_xm_CottageFantasy_xm_end");
|
|
||||||
extern uint32_t _binary_xm_CottageFantasy_xm_size __asm("_binary_xm_CottageFantasy_xm_size");
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
@ -1,15 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern uint32_t _binary_xm_ForestAtTwilight_xm_start __asm("_binary_xm_ForestAtTwilight_xm_start");
|
|
||||||
extern uint32_t _binary_xm_ForestAtTwilight_xm_end __asm("_binary_xm_ForestAtTwilight_xm_end");
|
|
||||||
extern uint32_t _binary_xm_ForestAtTwilight_xm_size __asm("_binary_xm_ForestAtTwilight_xm_size");
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
BIN
xm/RedBlossom.xm
@ -1,15 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern uint32_t _binary_xm_RedBlossom_xm_start __asm("_binary_xm_RedBlossom_xm_start");
|
|
||||||
extern uint32_t _binary_xm_RedBlossom_xm_end __asm("_binary_xm_RedBlossom_xm_end");
|
|
||||||
extern uint32_t _binary_xm_RedBlossom_xm_size __asm("_binary_xm_RedBlossom_xm_size");
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
@ -1,15 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern uint32_t _binary_xm_SpringWaltz_xm_start __asm("_binary_xm_SpringWaltz_xm_start");
|
|
||||||
extern uint32_t _binary_xm_SpringWaltz_xm_end __asm("_binary_xm_SpringWaltz_xm_end");
|
|
||||||
extern uint32_t _binary_xm_SpringWaltz_xm_size __asm("_binary_xm_SpringWaltz_xm_size");
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
@ -1,15 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern uint32_t _binary_xm_SummerDreamsDemoTrackv4_xm_start __asm("_binary_xm_SummerDreamsDemoTrackv4_xm_start");
|
|
||||||
extern uint32_t _binary_xm_SummerDreamsDemoTrackv4_xm_end __asm("_binary_xm_SummerDreamsDemoTrackv4_xm_end");
|
|
||||||
extern uint32_t _binary_xm_SummerDreamsDemoTrackv4_xm_size __asm("_binary_xm_SummerDreamsDemoTrackv4_xm_size");
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
@ -1,15 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern uint32_t _binary_xm_TheClockOfElery_xm_start __asm("_binary_xm_TheClockOfElery_xm_start");
|
|
||||||
extern uint32_t _binary_xm_TheClockOfElery_xm_end __asm("_binary_xm_TheClockOfElery_xm_end");
|
|
||||||
extern uint32_t _binary_xm_TheClockOfElery_xm_size __asm("_binary_xm_TheClockOfElery_xm_size");
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
@ -1,15 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern uint32_t _binary_xm_TheMountainsOfElmindeer_xm_start __asm("_binary_xm_TheMountainsOfElmindeer_xm_start");
|
|
||||||
extern uint32_t _binary_xm_TheMountainsOfElmindeer_xm_end __asm("_binary_xm_TheMountainsOfElmindeer_xm_end");
|
|
||||||
extern uint32_t _binary_xm_TheMountainsOfElmindeer_xm_size __asm("_binary_xm_TheMountainsOfElmindeer_xm_size");
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|