diff --git a/cover/clocks.data.h b/cover/clocks.data.h new file mode 100644 index 0000000..1adebb5 --- /dev/null +++ b/cover/clocks.data.h @@ -0,0 +1,15 @@ +#pragma once + +#include + +#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 diff --git a/cover/clocks.png b/cover/clocks.png new file mode 100644 index 0000000..3780f41 Binary files /dev/null and b/cover/clocks.png differ diff --git a/cover/moonmountains.data.h b/cover/moonmountains.data.h new file mode 100644 index 0000000..3f930df --- /dev/null +++ b/cover/moonmountains.data.h @@ -0,0 +1,15 @@ +#pragma once + +#include + +#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 diff --git a/cover/moonmountains.png b/cover/moonmountains.png new file mode 100644 index 0000000..151378e Binary files /dev/null and b/cover/moonmountains.png differ diff --git a/cover/mossycottage.data.h b/cover/mossycottage.data.h new file mode 100644 index 0000000..9cf35a2 --- /dev/null +++ b/cover/mossycottage.data.h @@ -0,0 +1,15 @@ +#pragma once + +#include + +#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 diff --git a/cover/mossycottage.png b/cover/mossycottage.png new file mode 100644 index 0000000..83863bb Binary files /dev/null and b/cover/mossycottage.png differ diff --git a/cover/mountain.data.h b/cover/mountain.data.h new file mode 100644 index 0000000..36956bf --- /dev/null +++ b/cover/mountain.data.h @@ -0,0 +1,15 @@ +#pragma once + +#include + +#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 diff --git a/cover/mountain.png b/cover/mountain.png new file mode 100644 index 0000000..85758f8 Binary files /dev/null and b/cover/mountain.png differ diff --git a/cover/mountainfull.data.h b/cover/mountainfull.data.h new file mode 100644 index 0000000..2d692bf --- /dev/null +++ b/cover/mountainfull.data.h @@ -0,0 +1,15 @@ +#pragma once + +#include + +#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 diff --git a/cover/mountainfull.png b/cover/mountainfull.png new file mode 100644 index 0000000..11122e6 Binary files /dev/null and b/cover/mountainfull.png differ diff --git a/cover/redtree.data.h b/cover/redtree.data.h new file mode 100644 index 0000000..bf56d18 --- /dev/null +++ b/cover/redtree.data.h @@ -0,0 +1,15 @@ +#pragma once + +#include + +#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 diff --git a/cover/redtree.png b/cover/redtree.png new file mode 100644 index 0000000..26304d4 Binary files /dev/null and b/cover/redtree.png differ diff --git a/cover/redtreefull.data.h b/cover/redtreefull.data.h new file mode 100644 index 0000000..1340794 --- /dev/null +++ b/cover/redtreefull.data.h @@ -0,0 +1,15 @@ +#pragma once + +#include + +#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 diff --git a/cover/redtreefull.png b/cover/redtreefull.png new file mode 100644 index 0000000..34a7ec6 Binary files /dev/null and b/cover/redtreefull.png differ diff --git a/cover/silvertrees.data.h b/cover/silvertrees.data.h new file mode 100644 index 0000000..469f5a4 --- /dev/null +++ b/cover/silvertrees.data.h @@ -0,0 +1,15 @@ +#pragma once + +#include + +#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 diff --git a/cover/silvertrees.png b/cover/silvertrees.png new file mode 100644 index 0000000..9cb6cfb Binary files /dev/null and b/cover/silvertrees.png differ diff --git a/cover/silvertreesfull.data.h b/cover/silvertreesfull.data.h new file mode 100644 index 0000000..1c84cbb --- /dev/null +++ b/cover/silvertreesfull.data.h @@ -0,0 +1,15 @@ +#pragma once + +#include + +#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 diff --git a/cover/silvertreesfull.png b/cover/silvertreesfull.png new file mode 100644 index 0000000..e09164e Binary files /dev/null and b/cover/silvertreesfull.png differ diff --git a/cover/thebeach.data.h b/cover/thebeach.data.h new file mode 100644 index 0000000..3c5c511 --- /dev/null +++ b/cover/thebeach.data.h @@ -0,0 +1,15 @@ +#pragma once + +#include + +#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 diff --git a/cover/thebeach.png b/cover/thebeach.png new file mode 100644 index 0000000..99ffaf3 Binary files /dev/null and b/cover/thebeach.png differ diff --git a/cover/tree.data.h b/cover/tree.data.h new file mode 100644 index 0000000..021b898 --- /dev/null +++ b/cover/tree.data.h @@ -0,0 +1,15 @@ +#pragma once + +#include + +#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 diff --git a/cover/tree.png b/cover/tree.png new file mode 100644 index 0000000..5982d37 Binary files /dev/null and b/cover/tree.png differ diff --git a/demo.mk b/demo.mk index e3bf721..f852bae 100644 --- a/demo.mk +++ b/demo.mk @@ -66,7 +66,14 @@ DEMO_OBJ = \ xm/SpringWaltz.xm.o \ xm/SummerDreamsDemoTrackv4.xm.o \ xm/TheClockOfElery.xm.o \ - xm/TheMountainsOfElmindeer.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: $(START_OBJ) $(DEMO_OBJ) $(FONT_OBJ) $(TEXTURE_OBJ) $(LIBGCC) diff --git a/src/demo/lizard/main.cpp b/src/demo/lizard/main.cpp index 2e6c507..199746e 100644 --- a/src/demo/lizard/main.cpp +++ b/src/demo/lizard/main.cpp @@ -78,7 +78,7 @@ namespace demo { //lizard_position = {81, 100, 212}; lizard_velocity = {0, 0, 0}; - if (!emulator_detected) { + if (1 || !emulator_detected) { emulator_detected_hud_frames = 60 * 30; playlist::next(); } else { @@ -149,10 +149,10 @@ namespace demo { void lizard::y() { - if (last_platform1 == nullptr) - init(); - else { - lizard_velocity = {0, 0, 0}; + lizard_velocity = {0, 0, 0}; + 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) @@ -265,9 +265,9 @@ namespace demo { const int title_width_2 = (font::ter_u12n.hori_advance * title_length) >> 1; const int x = framebuffer_width_2 - title_width_2; center_p.x = x; - font::ter_u12n.draw_string(writer, center_p, "demo: lizard", 0xffffffff); + //font::ter_u12n.draw_string(writer, center_p, "demo: lizard", 0xffffffff); } - center_p.y += font::ter_u12n.height; + //center_p.y += font::ter_u12n.height; { const int title_length = 46; const int title_width_2 = (font::ter_u12n.hori_advance * title_length) >> 1; @@ -380,6 +380,27 @@ 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& _) { // punch through @@ -388,6 +409,13 @@ namespace demo { draw_hud(writer); draw_lizard(writer, trans); + writer.append() = + 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(para_control::para_type::end_of_list); diff --git a/src/demo/lizard/main.hpp b/src/demo/lizard/main.hpp index a3f8911..343e6c3 100644 --- a/src/demo/lizard/main.hpp +++ b/src/demo/lizard/main.hpp @@ -19,6 +19,9 @@ namespace demo { int platform_touch_count; int end_platform_tick; + int last_cover_texture_offset; + float cover_ix_transition; + int emulator_detected_hud_frames; bool collided; @@ -50,6 +53,7 @@ namespace demo { void draw_hud(ta_parameter_writer& writer); 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_cover(ta_parameter_writer& writer, const mat4x4& trans); void draw(ta_parameter_writer& writer, const mat4x4& trans) override; }; } diff --git a/src/platform/graphics.cpp b/src/platform/graphics.cpp index ca0fe6d..94921ff 100644 --- a/src/platform/graphics.cpp +++ b/src/platform/graphics.cpp @@ -48,14 +48,14 @@ namespace graphics { constexpr uint32_t ta_alloc = ta_alloc_ctrl::pt_opb::_32x4byte | ta_alloc_ctrl::tm_opb::no_list - | ta_alloc_ctrl::t_opb::no_list + | ta_alloc_ctrl::t_opb::_32x4byte | ta_alloc_ctrl::om_opb::no_list | ta_alloc_ctrl::o_opb::_32x4byte; const opb_size opb_size = { .opaque = 32 * 4, .opaque_modifier = 0, - .translucent = 0, + .translucent = 32 * 4, .translucent_modifier = 0, .punch_through = 32 * 4 }; @@ -173,7 +173,7 @@ namespace graphics { holly.SOFTRESET = 0; background_parameter2(texture_memory_alloc.background[0].start, - 0x110012); + 0xffffff); region_array_multipass(framebuffer::framebuffer.tile_width(), framebuffer::framebuffer.tile_height(), diff --git a/src/platform/graphics_primitive.cpp b/src/platform/graphics_primitive.cpp index 63682b2..7ac71d4 100644 --- a/src/platform/graphics_primitive.cpp +++ b/src/platform/graphics_primitive.cpp @@ -380,6 +380,124 @@ void draw_textured_cube(ta_parameter_writer& writer, } } +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, + ap, at, + bp, bt, + cp, ct, + dp, dt, + base_intensity); + } +} + constexpr inline float pow(float x, int n) { for (int i = 0; i < n; i++) diff --git a/src/platform/graphics_primitive.hpp b/src/platform/graphics_primitive.hpp index 5e81603..d0efb71 100644 --- a/src/platform/graphics_primitive.hpp +++ b/src/platform/graphics_primitive.hpp @@ -87,6 +87,12 @@ void draw_textured_cube(ta_parameter_writer& writer, 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, const mat4x4& trans, const vec3& color); diff --git a/src/platform/texture.cpp b/src/platform/texture.cpp index 8933ee2..678f399 100644 --- a/src/platform/texture.cpp +++ b/src/platform/texture.cpp @@ -26,6 +26,15 @@ #include "texture/turning/frame0004_128.data.h" #include "texture/turning/frame0005_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 { struct entry { @@ -130,6 +139,41 @@ namespace texture { .size = reinterpret_cast(&_binary_texture_turning_frame0006_128_data_size), .offset = offset::turning_frame0006, }, + { + .start = reinterpret_cast(&_binary_cover_clocks_data_start), + .size = reinterpret_cast(&_binary_cover_clocks_data_size), + .offset = offset::clocks, + }, + { + .start = reinterpret_cast(&_binary_cover_mossycottage_data_start), + .size = reinterpret_cast(&_binary_cover_mossycottage_data_size), + .offset = offset::mossycottage, + }, + { + .start = reinterpret_cast(&_binary_cover_mountain_data_start), + .size = reinterpret_cast(&_binary_cover_mountain_data_size), + .offset = offset::mountain, + }, + { + .start = reinterpret_cast(&_binary_cover_thebeach_data_start), + .size = reinterpret_cast(&_binary_cover_thebeach_data_size), + .offset = offset::thebeach, + }, + { + .start = reinterpret_cast(&_binary_cover_tree_data_start), + .size = reinterpret_cast(&_binary_cover_tree_data_size), + .offset = offset::tree, + }, + { + .start = reinterpret_cast(&_binary_cover_redtree_data_start), + .size = reinterpret_cast(&_binary_cover_redtree_data_size), + .offset = offset::redtree, + }, + { + .start = reinterpret_cast(&_binary_cover_silvertrees_data_start), + .size = reinterpret_cast(&_binary_cover_silvertrees_data_size), + .offset = offset::silvertrees, + }, }; const int textures_length = (sizeof (textures)) / (sizeof (textures[0])); @@ -156,6 +200,7 @@ namespace texture { int size = textures[i].size; ta_fifo_texture_memory_transfer::copy(dst, src, size); + assert((int)offset + size < 8 * 1024 * 1024); } transfer_palettes(); diff --git a/src/platform/texture.hpp b/src/platform/texture.hpp index 2a08d28..2bd4f48 100644 --- a/src/platform/texture.hpp +++ b/src/platform/texture.hpp @@ -23,6 +23,14 @@ namespace texture { constexpr int turning_frame0004 = turning_frame0003 + 8192; constexpr int turning_frame0005 = turning_frame0004 + 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 { diff --git a/src/xm_player/playlist.cpp b/src/xm_player/playlist.cpp index b9a13a6..2eaa3e9 100644 --- a/src/xm_player/playlist.cpp +++ b/src/xm_player/playlist.cpp @@ -13,6 +13,8 @@ #include "xm/SpringWaltz.xm.h" #include "xm/TheMountainsOfElmindeer.xm.h" +#include "platform/texture.hpp" + namespace playlist { struct state state = { @@ -25,43 +27,43 @@ namespace playlist { .artist = "Shiroiii", .title = "Clouds Ahead", .start = (int)&_binary_xm_CloudsAhead_xm_start, - .cover_ix = cover::thebeach, + .cover_ix = texture::offset::thebeach, }, { .artist = "Shiroiii", .title = "Cottage Fantasy", .start = (int)&_binary_xm_CottageFantasy_xm_start, - .cover_ix = cover::mossycottage, + .cover_ix = texture::offset::mossycottage, }, { .artist = "Shiroiii", .title = "Red Blossom", .start = (int)&_binary_xm_RedBlossom_xm_start, - .cover_ix = cover::redtree, + .cover_ix = texture::offset::redtree, }, { .artist = "Shiroiii", .title = "The Clock Of Elery", .start = (int)&_binary_xm_TheClockOfElery_xm_start, - .cover_ix = cover::clocks, + .cover_ix = texture::offset::clocks, }, { .artist = "Shiroiii", .title = "Forest At Twilight", .start = (int)&_binary_xm_ForestAtTwilight_xm_start, - .cover_ix = cover::silvertrees, + .cover_ix = texture::offset::silvertrees, }, { .artist = "Shiroiii", .title = "Spring Waltz", .start = (int)&_binary_xm_SpringWaltz_xm_start, - .cover_ix = cover::tree, + .cover_ix = texture::offset::tree, }, { .artist = "Shiroiii", .title = "Mountains of Elmindeer", .start = (int)&_binary_xm_TheMountainsOfElmindeer_xm_start, - .cover_ix = cover::mountain, + .cover_ix = texture::offset::mountain, }, }; @@ -69,7 +71,7 @@ namespace playlist { bool next(bool stop_sound) { - if (state.loops < 0 || state.loops >= 2) { + if (state.loops < 0 || state.loops >= 3) { state.playlist_ix += 1; state.loops = 0;