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 = \
|
MACAW_OBJ = \
|
||||||
example/macaw.o \
|
example/macaw.o \
|
||||||
vga.o \
|
vga.o \
|
||||||
|
@ -30,8 +30,6 @@ const struct vertex strip_vertices[4] = {
|
|||||||
};
|
};
|
||||||
constexpr uint32_t strip_length = (sizeof (strip_vertices)) / (sizeof (struct vertex));
|
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;
|
static float theta = 0;
|
||||||
constexpr float half_degree = 0.01745329f / 2.f;
|
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 vertex * strip_vertices,
|
||||||
const uint32_t strip_length)
|
const uint32_t strip_length)
|
||||||
{
|
{
|
||||||
auto ta_parameter = reinterpret_cast<union ta_parameter *>(ta_parameter_buf);
|
auto parameter = ta_parameter_writer(ta_parameter_buf);
|
||||||
int ix = 0;
|
|
||||||
uint32_t texture_address = (offsetof (struct texture_memory_alloc, texture));
|
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++) {
|
for (uint32_t i = 0; i < strip_length; i++) {
|
||||||
bool end_of_strip = i == strip_length - 1;
|
bool end_of_strip = i == strip_length - 1;
|
||||||
@ -61,7 +58,7 @@ uint32_t transform(uint32_t * ta_parameter_buf,
|
|||||||
y += 240.f;
|
y += 240.f;
|
||||||
z = 1.f / (z + 10.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,
|
vertex_polygon_type_3(x, y, z,
|
||||||
strip_vertices[i].u,
|
strip_vertices[i].u,
|
||||||
strip_vertices[i].v,
|
strip_vertices[i].v,
|
||||||
@ -69,13 +66,15 @@ uint32_t transform(uint32_t * ta_parameter_buf,
|
|||||||
end_of_strip);
|
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;
|
theta += half_degree;
|
||||||
|
|
||||||
return ix * 32;
|
return parameter.offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t _ta_parameter_buf[((32 * (strip_length + 2)) + 32) / 4];
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
vga();
|
vga();
|
||||||
@ -99,8 +98,8 @@ void main()
|
|||||||
core_init();
|
core_init();
|
||||||
core_init_texture_memory();
|
core_init_texture_memory();
|
||||||
|
|
||||||
// the address of `scene` must be a multiple of 32 bytes
|
// 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
|
// This is mandatory for ch2-dma to the ta fifo polygon converter.
|
||||||
uint32_t * ta_parameter_buf = align_32byte(_ta_parameter_buf);
|
uint32_t * ta_parameter_buf = align_32byte(_ta_parameter_buf);
|
||||||
|
|
||||||
while (true) {
|
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, _res5)) == 0x18);
|
||||||
static_assert((offsetof (struct global_end_of_list, _res6)) == 0x1c);
|
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 {
|
union ta_parameter {
|
||||||
struct global_polygon_type_0 global_polygon_type_0;
|
struct global_polygon_type_0 global_polygon_type_0;
|
||||||
struct global_sprite global_sprite;
|
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_0 vertex_polygon_type_0;
|
||||||
struct vertex_polygon_type_3 vertex_polygon_type_3;
|
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;
|
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