From 9fc40136af55fdc61a05f7f586b61158d58c9666 Mon Sep 17 00:00:00 2001 From: Zack Buhman Date: Wed, 13 Dec 2023 22:17:02 +0800 Subject: [PATCH] example: add sprite example This also adds ta_parameter_writer; I am not certain if I like this, but it felt necessary to deal with ta_parameters being either 32 or 64 bytes long--for this reason, a reinterpret_cast to a union is less attractive (the union members are not a fixed size). --- example/example.mk | 11 +++++ example/macaw.cpp | 19 ++++---- example/sprite.cpp | 81 ++++++++++++++++++++++++++++++++++ holly/ta_parameter.hpp | 22 ++++++++++ scene.cpp | 98 ------------------------------------------ scene.hpp | 7 --- 6 files changed, 123 insertions(+), 115 deletions(-) create mode 100644 example/sprite.cpp delete mode 100644 scene.cpp delete mode 100644 scene.hpp diff --git a/example/example.mk b/example/example.mk index 6881702..879914d 100644 --- a/example/example.mk +++ b/example/example.mk @@ -1,3 +1,14 @@ +SPRITE_OBJ = \ + example/sprite.o \ + vga.o \ + holly/core.o \ + holly/region_array.o \ + holly/background.o \ + holly/ta_fifo_polygon_converter.o + +example/sprite.elf: LDSCRIPT = $(LIB)/alt.lds +example/sprite.elf: $(START_OBJ) $(SPRITE_OBJ) + MACAW_OBJ = \ example/macaw.o \ vga.o \ diff --git a/example/macaw.cpp b/example/macaw.cpp index 7dd4a08..1143794 100644 --- a/example/macaw.cpp +++ b/example/macaw.cpp @@ -30,8 +30,6 @@ const struct vertex strip_vertices[4] = { }; constexpr uint32_t strip_length = (sizeof (strip_vertices)) / (sizeof (struct vertex)); -uint32_t _ta_parameter_buf[((32 * (strip_length + 2)) + 32) / 4]; - static float theta = 0; constexpr float half_degree = 0.01745329f / 2.f; @@ -39,10 +37,9 @@ uint32_t transform(uint32_t * ta_parameter_buf, const vertex * strip_vertices, const uint32_t strip_length) { - auto ta_parameter = reinterpret_cast(ta_parameter_buf); - int ix = 0; + auto parameter = ta_parameter_writer(ta_parameter_buf); uint32_t texture_address = (offsetof (struct texture_memory_alloc, texture)); - ta_parameter[ix++].global_polygon_type_0 = global_polygon_type_0(texture_address); + parameter.append() = global_polygon_type_0(texture_address); for (uint32_t i = 0; i < strip_length; i++) { bool end_of_strip = i == strip_length - 1; @@ -61,7 +58,7 @@ uint32_t transform(uint32_t * ta_parameter_buf, y += 240.f; z = 1.f / (z + 10.f); - ta_parameter[ix++].vertex_polygon_type_3 = + parameter.append() = vertex_polygon_type_3(x, y, z, strip_vertices[i].u, strip_vertices[i].v, @@ -69,13 +66,15 @@ uint32_t transform(uint32_t * ta_parameter_buf, end_of_strip); } - ta_parameter[ix++].global_end_of_list = global_end_of_list(); + parameter.append() = global_end_of_list(); theta += half_degree; - return ix * 32; + return parameter.offset; } +uint32_t _ta_parameter_buf[((32 * (strip_length + 2)) + 32) / 4]; + void main() { vga(); @@ -99,8 +98,8 @@ void main() core_init(); core_init_texture_memory(); - // the address of `scene` must be a multiple of 32 bytes - // this is mandatory for ch2-dma to the ta fifo polygon converter + // The address of `ta_parameter_buf` must be a multiple of 32 bytes. + // This is mandatory for ch2-dma to the ta fifo polygon converter. uint32_t * ta_parameter_buf = align_32byte(_ta_parameter_buf); while (true) { diff --git a/example/sprite.cpp b/example/sprite.cpp new file mode 100644 index 0000000..0d92742 --- /dev/null +++ b/example/sprite.cpp @@ -0,0 +1,81 @@ +#include + +#include "align.hpp" + +#include "vga.hpp" +#include "holly.hpp" +#include "holly/core.hpp" +#include "holly/core_bits.hpp" +#include "holly/ta_parameter.hpp" +#include "holly/ta_fifo_polygon_converter.hpp" + +struct vertex { + float x; + float y; + float z; +}; + +// screen space coordinates +const struct vertex quad_verticies[4] = { + { 200.f, 360.f, 0.1f }, + { 200.f, 120.f, 0.1f }, + { 440.f, 120.f, 0.1f }, + { 440.f, 360.f, 0.1f }, +}; + +uint32_t transform(uint32_t * ta_parameter_buf) +{ + auto parameter = ta_parameter_writer(ta_parameter_buf); + + constexpr uint32_t base_color = 0xffff0000; + parameter.append() = global_sprite(base_color); + parameter.append() = + vertex_sprite_type_0(quad_verticies[0].x, + quad_verticies[0].y, + quad_verticies[0].z, + quad_verticies[1].x, + quad_verticies[1].y, + quad_verticies[1].z, + quad_verticies[2].x, + quad_verticies[2].y, + quad_verticies[2].z, + quad_verticies[3].x, + quad_verticies[3].y); + // curiously, there is no quad_veritices[3].z in vertex_sprite_type_0 + + parameter.append() = global_end_of_list(); + + return parameter.offset; +} + +uint32_t _ta_parameter_buf[((32 + 64 + 32) + 32) / 4]; + +void main() +{ + vga(); + + holly.SOFTRESET = softreset::pipeline_soft_reset + | softreset::ta_soft_reset; + holly.SOFTRESET = 0; + + core_init(); + core_init_texture_memory(); + + // The address of `ta_parameter_buf` must be a multiple of 32 bytes. + // This is mandatory for ch2-dma to the ta fifo polygon converter. + uint32_t * ta_parameter_buf = align_32byte(_ta_parameter_buf); + + while (true) { + v_sync_out(); + v_sync_in(); + + ta_polygon_converter_init(); + uint32_t ta_parameter_size = transform(ta_parameter_buf); + ta_polygon_converter_transfer(ta_parameter_buf, ta_parameter_size); + ta_wait_opaque_list(); + + constexpr int frame_ix = 0; + constexpr int num_frames = 0; + core_start_render(frame_ix, num_frames); + } +} diff --git a/holly/ta_parameter.hpp b/holly/ta_parameter.hpp index f8445ee..42ce4e6 100644 --- a/holly/ta_parameter.hpp +++ b/holly/ta_parameter.hpp @@ -313,6 +313,24 @@ static_assert((offsetof (struct global_end_of_list, _res4)) == 0x14); static_assert((offsetof (struct global_end_of_list, _res5)) == 0x18); static_assert((offsetof (struct global_end_of_list, _res6)) == 0x1c); + +struct ta_parameter_writer { + uint32_t * buf; + uint32_t offset; // in bytes + + ta_parameter_writer(uint32_t * buf) + : buf(buf), offset(0) + { } + + template + inline T& append() + { + T& t = *reinterpret_cast(&buf[offset / 4]); + offset += (sizeof (T)); + return t; + } +}; +/* union ta_parameter { struct global_polygon_type_0 global_polygon_type_0; struct global_sprite global_sprite; @@ -320,5 +338,9 @@ union ta_parameter { struct vertex_polygon_type_0 vertex_polygon_type_0; struct vertex_polygon_type_3 vertex_polygon_type_3; + struct vertex_sprite_type_0 vertex_sprite_type_0; + struct global_end_of_list global_end_of_list; }; +static_assert((sizeof (ta_parameter)) == 32); +*/ diff --git a/scene.cpp b/scene.cpp deleted file mode 100644 index bd94a78..0000000 --- a/scene.cpp +++ /dev/null @@ -1,98 +0,0 @@ -#include -#include - -#include "holly/ta_parameter.hpp" - -#include "holly/texture_memory_alloc.hpp" - -/* - -0.5,-0.5 0.5,-0.5 - | - --- - -0.5,0.5 | 0.5,0.5 - */ - -struct vertex1 { - float x; - float y; - float z; -}; - -const struct vertex1 scene_quad[4] = { - { -0.5f, 0.5f, 0.f }, - { -0.5f, -0.5f, 0.f }, - { 0.5f, -0.5f, 0.f }, - { 0.5f, 0.5f, 0.f }, -}; - -struct scene_quad_ta_parameters { - global_sprite sprite; - vertex_sprite_type_0 vertex; - global_end_of_list end_of_list; -}; - -static_assert((sizeof (scene_quad_ta_parameters)) == 32 * 4); - -uint32_t scene_transform_quad(uint32_t * _scene, uint32_t base_color) -{ - auto scene = reinterpret_cast(&_scene[0]); - - //uint32_t base_color = 0xffffff00; - scene->sprite = global_sprite(base_color); - scene->vertex = vertex_sprite_type_0(scene_quad[0].x * 240 + 320, - scene_quad[0].y * 240 + 240, - 1 / (scene_quad[0].z + 10), - scene_quad[1].x * 240 + 320, - scene_quad[1].y * 240 + 240, - 1 / (scene_quad[1].z + 10), - scene_quad[2].x * 240 + 320, - scene_quad[2].y * 240 + 240, - 1 / (scene_quad[2].z + 10), - scene_quad[3].x * 240 + 320, - scene_quad[3].y * 240 + 240); - scene->end_of_list = global_end_of_list(); - - return (sizeof (scene_quad_ta_parameters)); -} - -static float theta = 0; -constexpr float half_degree = 0.01745329f / 2.f; - -uint32_t scene_transform(uint32_t * _scene) -{ - ta_parameter * scene = reinterpret_cast(&_scene[0]); - int ix = 0; - uint32_t texture_address = (offsetof (struct texture_memory_alloc, texture)); - scene[ix++].global_polygon_type_0 = global_polygon_type_0(texture_address); - - for (uint32_t i = 0; i < 4; i++) { - bool end_of_strip = i == 3; - - float x = scene_triangle[i].x; - float y = scene_triangle[i].y; - float z = scene_triangle[i].z; - float x1; - - x1 = x * __builtin_cosf(theta) - z * __builtin_sinf(theta); - z = x * __builtin_sinf(theta) + z * __builtin_cosf(theta); - x = x1; - x *= 240.f; - y *= 240.f; - x += 320.f; - y += 240.f; - - scene[ix++].vertex_polygon_type_3 = vertex_polygon_type_3(x, // x - y, // y - 1.f / (z + 10.f), // z - scene_triangle[i].u, // u - scene_triangle[i].v, // v - scene_triangle[i].color, // base_color - end_of_strip); - } - - scene[ix++].global_end_of_list = global_end_of_list(); - - theta += half_degree; - - return ix * 32; -} diff --git a/scene.hpp b/scene.hpp deleted file mode 100644 index 9a6eade..0000000 --- a/scene.hpp +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once - -#include - -uint32_t scene_transform_quad(uint32_t * scene, uint32_t color); - -uint32_t scene_transform(uint32_t * scene);