diff --git a/example/example.mk b/example/example.mk index 2434323..6881702 100644 --- a/example/example.mk +++ b/example/example.mk @@ -1,6 +1,20 @@ +MACAW_OBJ = \ + example/macaw.o \ + vga.o \ + holly/core.o \ + holly/region_array.o \ + holly/background.o \ + holly/ta_fifo_polygon_converter.o \ + macaw.data.o + +example/macaw.elf: LDSCRIPT = $(LIB)/alt.lds +example/macaw.elf: $(START_OBJ) $(MACAW_OBJ) + CUBE_OBJ = \ example/cube.o \ - vga.o + vga.o \ + holly/core.o \ + holly/ta_fifo_polygon_converter.o example/cube.elf: LDSCRIPT = $(LIB)/alt.lds example/cube.elf: $(START_OBJ) $(CUBE_OBJ) diff --git a/example/macaw.cpp b/example/macaw.cpp new file mode 100644 index 0000000..7dd4a08 --- /dev/null +++ b/example/macaw.cpp @@ -0,0 +1,119 @@ +#include + +#include "align.hpp" +#include "vga.hpp" + +#include "holly/texture_memory_alloc.hpp" +#include "holly.hpp" +#include "holly/core.hpp" +#include "holly/core_bits.hpp" +#include "holly/ta_fifo_polygon_converter.hpp" +#include "holly/ta_parameter.hpp" + +#include "macaw.hpp" + +struct vertex { + float x; + float y; + float z; + float u; + float v; + uint32_t color; +}; + +const struct vertex strip_vertices[4] = { + // [ position ] [ uv coordinates ] [color ] + { -0.5f, 0.5f, 0.f, 0.f , 127.f/128.f, 0x00000000}, // the first two base colors in a + { -0.5f, -0.5f, 0.f, 0.f , 0.f , 0x00000000}, // non-Gouraud triangle strip are ignored + { 0.5f, 0.5f, 0.f, 127.f/128.f, 127.f/128.f, 0xffff00ff}, + { 0.5f, -0.5f, 0.f, 127.f/128.f, 0.f , 0xffffff00}, +}; +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; + +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; + uint32_t texture_address = (offsetof (struct texture_memory_alloc, texture)); + ta_parameter[ix++].global_polygon_type_0 = global_polygon_type_0(texture_address); + + for (uint32_t i = 0; i < strip_length; i++) { + bool end_of_strip = i == strip_length - 1; + + float x = strip_vertices[i].x; + float y = strip_vertices[i].y; + float z = strip_vertices[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; + z = 1.f / (z + 10.f); + + ta_parameter[ix++].vertex_polygon_type_3 = + vertex_polygon_type_3(x, y, z, + strip_vertices[i].u, + strip_vertices[i].v, + strip_vertices[i].color, + end_of_strip); + } + + ta_parameter[ix++].global_end_of_list = global_end_of_list(); + + theta += half_degree; + + return ix * 32; +} + +void main() +{ + vga(); + + auto src = reinterpret_cast(&_binary_macaw_data_start); + auto size = reinterpret_cast(&_binary_macaw_data_size); + auto mem = reinterpret_cast(0xa400'0000); + for (uint32_t px = 0; px < size / 3; px++) { + uint8_t r = src[px * 3 + 0]; + uint8_t g = src[px * 3 + 1]; + uint8_t b = src[px * 3 + 2]; + + uint16_t rgb565 = ((r / 8) << 11) | ((g / 4) << 5) | ((b / 8) << 0); + mem->texture[px] = rgb565; + } + + holly.SOFTRESET = softreset::pipeline_soft_reset + | softreset::ta_soft_reset; + holly.SOFTRESET = 0; + + 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 + 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, strip_vertices, strip_length); + 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/float_uint32.hpp b/float_uint32.hpp index 56c7bbf..5ae6c7b 100644 --- a/float_uint32.hpp +++ b/float_uint32.hpp @@ -4,7 +4,7 @@ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wstrict-aliasing" -constexpr uint32_t _i(float f) { +inline uint32_t _i(float f) { return *(reinterpret_cast(&f)); } #pragma GCC diagnostic pop diff --git a/holly/core.cpp b/holly/core.cpp index 246cc41..435aa34 100644 --- a/holly/core.cpp +++ b/holly/core.cpp @@ -60,7 +60,7 @@ void core_init_texture_memory() ); } -void core_start_render(int fb) +void core_start_render(int frame_ix, int num_frames) { holly.REGION_BASE = (offsetof (struct texture_memory_alloc, region_array)); holly.PARAM_BASE = (offsetof (struct texture_memory_alloc, isp_tsp_parameters)); @@ -73,11 +73,10 @@ void core_start_render(int fb) holly.FB_W_CTRL = 1 << 3 | fb_w_ctrl::fb_packmode::_565_rgb_16bit; holly.FB_W_LINESTRIDE = (640 * 2) / 8; - int w_fb = (!(!fb)) * 0x00096000; - int r_fb = (!fb) * 0x00096000; + int w_fb = ((frame_ix + 0) & num_frames) * 0x00096000; + int r_fb = ((frame_ix + 1) & num_frames) * 0x00096000; holly.FB_W_SOF1 = (offsetof (struct texture_memory_alloc, framebuffer)) + w_fb; - //holly.FB_R_SOF1 = (offsetof (struct texture_memory_alloc, framebuffer)) + r_fb; - holly.FB_R_SOF1 = (offsetof (struct texture_memory_alloc, framebuffer)) + w_fb; + holly.FB_R_SOF1 = (offsetof (struct texture_memory_alloc, framebuffer)) + r_fb; holly.STARTRENDER = 1; } diff --git a/holly/core.hpp b/holly/core.hpp index 540c78d..b281daf 100644 --- a/holly/core.hpp +++ b/holly/core.hpp @@ -2,4 +2,4 @@ void core_init(); void core_init_texture_memory(); -void core_start_render(int fb); +void core_start_render(int frame_ix, int num_frames); diff --git a/holly/ta_parameter.hpp b/holly/ta_parameter.hpp index fdf679b..f8445ee 100644 --- a/holly/ta_parameter.hpp +++ b/holly/ta_parameter.hpp @@ -312,3 +312,13 @@ static_assert((offsetof (struct global_end_of_list, _res3)) == 0x10); 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); + +union ta_parameter { + struct global_polygon_type_0 global_polygon_type_0; + struct global_sprite global_sprite; + + struct vertex_polygon_type_0 vertex_polygon_type_0; + struct vertex_polygon_type_3 vertex_polygon_type_3; + + struct global_end_of_list global_end_of_list; +}; diff --git a/main.cpp b/main.cpp index 07f2e96..b42f14c 100644 --- a/main.cpp +++ b/main.cpp @@ -77,17 +77,6 @@ void main() maple_test(); //((void(*)(void))0xac010000)(); - /* - volatile uint16_t * framebuffer = reinterpret_cast(&texture_memory[0]); - for (int y = 0; y < 480; y++) { - for (int x = 0; x < 640; x++) { - struct hsv hsv = {(y * 255) / 480, 255, 255}; - struct rgb rgb = hsv_to_rgb(hsv); - framebuffer[y * 640 + x] = ((rgb.r >> 3) << 11) | ((rgb.g >> 2) << 5) | ((rgb.b >> 3) << 0); - } - } - */ - /* volatile texture_memory_alloc * mem = reinterpret_cast(0xa400'0000); diff --git a/scene.cpp b/scene.cpp index a9a5d6d..bd94a78 100644 --- a/scene.cpp +++ b/scene.cpp @@ -12,22 +12,6 @@ -0.5,0.5 | 0.5,0.5 */ -struct vertex0 { - float x; - float y; - float z; - float u; - float v; - uint32_t color; -}; - -const struct vertex0 scene_triangle[4] = { - { -0.5f, 0.5f, 0.f, 0.f , 128.f/128.f, 0x00000000}, // the first two base colors in a - { -0.5f, -0.5f, 0.f, 0.f , 0.f , 0x00000000}, // triangle strip are ignored - { 0.5f, 0.5f, 0.f, 128.f/128.f, 128.f/128.f, 0xffff00ff}, - { 0.5f, -0.5f, 0.f, 128.f/128.f, 0.f , 0xffffff00}, -}; - struct vertex1 { float x; float y; @@ -74,12 +58,6 @@ uint32_t scene_transform_quad(uint32_t * _scene, uint32_t base_color) static float theta = 0; constexpr float half_degree = 0.01745329f / 2.f; -union ta_parameter { - struct global_polygon_type_0 global_polygon_type_0; - struct vertex_polygon_type_3 vertex_polygon_type_3; - struct global_end_of_list global_end_of_list; -}; - uint32_t scene_transform(uint32_t * _scene) { ta_parameter * scene = reinterpret_cast(&_scene[0]);