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).
This commit is contained in:
parent
3e9572673c
commit
9fc40136af
@ -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 \
|
||||
|
@ -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<union ta_parameter *>(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>() = 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>() =
|
||||
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>() = 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) {
|
||||
|
81
example/sprite.cpp
Normal file
81
example/sprite.cpp
Normal file
@ -0,0 +1,81 @@
|
||||
#include <cstdint>
|
||||
|
||||
#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>() = global_sprite(base_color);
|
||||
parameter.append<vertex_sprite_type_0>() =
|
||||
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>() = 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);
|
||||
}
|
||||
}
|
@ -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 <typename T>
|
||||
inline T& append()
|
||||
{
|
||||
T& t = *reinterpret_cast<T *>(&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);
|
||||
*/
|
||||
|
98
scene.cpp
98
scene.cpp
@ -1,98 +0,0 @@
|
||||
#include <cstdint>
|
||||
#include <cstddef>
|
||||
|
||||
#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_quad_ta_parameters *>(&_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<ta_parameter *>(&_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;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user