example: add maple_analog
Also adds the incomplete modifier_volume example. This also adds vec2 for UV coordinates, and obj_to_cpp has been modified to parse vertex texture coordinates from obj files.
This commit is contained in:
parent
6a17031c6f
commit
4bb04a0362
28
Makefile
28
Makefile
@ -1,26 +1,8 @@
|
||||
all: main.elf
|
||||
all:
|
||||
|
||||
include common.mk
|
||||
|
||||
geometry/%.hpp: geometry/%.obj
|
||||
PYTHONPATH=regs/gen python tools/obj_to_cpp.py $< > $@
|
||||
|
||||
include example/example.mk
|
||||
|
||||
MAIN_OBJ = \
|
||||
main.o \
|
||||
vga.o \
|
||||
rgb.o \
|
||||
holly/background.o \
|
||||
holly/region_array.o \
|
||||
holly/ta_fifo_polygon_converter.o \
|
||||
holly/core.o \
|
||||
maple/maple.o \
|
||||
scene.o \
|
||||
macaw.data.o \
|
||||
wink.data.o
|
||||
|
||||
serial.elf: LDSCRIPT = $(LIB)/alt.lds
|
||||
serial.elf: $(START_OBJ) serial_main.o load.o
|
||||
|
||||
main.elf: LDSCRIPT = $(LIB)/main.lds
|
||||
main.elf: $(START_OBJ) $(MAIN_OBJ)
|
||||
|
||||
test.elf: LDSCRIPT = $(LIB)/alt.lds
|
||||
test.elf: $(START_OBJ) $(MAIN_OBJ)
|
||||
|
@ -130,6 +130,12 @@ audio.pcm:
|
||||
%.data.o: %.data
|
||||
$(BUILD_BINARY_O)
|
||||
|
||||
maple/maple_bus_commands.hpp: regs/maple_bus_commands.csv regs/gen/maple_bus_commands.py
|
||||
python regs/gen/maple_bus_commands.py $< > $@
|
||||
|
||||
maple/maple_bus_bits.hpp: regs/maple_bus_bits.csv regs/gen/core_bits.py
|
||||
python regs/gen/core_bits.py $< > $@
|
||||
|
||||
clean:
|
||||
find -P \
|
||||
-regextype posix-egrep \
|
||||
|
@ -193,6 +193,19 @@ MAPLE_VIBRATOR_OBJ = \
|
||||
example/maple_vibrator.elf: LDSCRIPT = $(LIB)/alt.lds
|
||||
example/maple_vibrator.elf: $(START_OBJ) $(MAPLE_VIBRATOR_OBJ)
|
||||
|
||||
MAPLE_ANALOG_OBJ = \
|
||||
example/maple_analog.o \
|
||||
vga.o \
|
||||
holly/core.o \
|
||||
holly/region_array.o \
|
||||
holly/background.o \
|
||||
holly/ta_fifo_polygon_converter.o \
|
||||
serial.o \
|
||||
maple/maple.o
|
||||
|
||||
example/maple_analog.elf: LDSCRIPT = $(LIB)/alt.lds
|
||||
example/maple_analog.elf: $(START_OBJ) $(MAPLE_ANALOG_OBJ)
|
||||
|
||||
SERIAL_TRANSFER_OBJ = \
|
||||
example/serial_transfer.o \
|
||||
serial_load.o
|
||||
|
235
example/maple_analog.cpp
Normal file
235
example/maple_analog.cpp
Normal file
@ -0,0 +1,235 @@
|
||||
#include <cstdint>
|
||||
#include <bit>
|
||||
|
||||
#include "align.hpp"
|
||||
|
||||
#include "vga.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 "holly/ta_bits.hpp"
|
||||
#include "holly/region_array.hpp"
|
||||
#include "holly/background.hpp"
|
||||
#include "holly/texture_memory_alloc.hpp"
|
||||
#include "memorymap.hpp"
|
||||
#include "serial.hpp"
|
||||
|
||||
#include "geometry/border.hpp"
|
||||
#include "geometry/circle.hpp"
|
||||
#include "math/vec4.hpp"
|
||||
|
||||
#include "maple/maple.hpp"
|
||||
#include "maple/maple_impl.hpp"
|
||||
#include "maple/maple_bus_bits.hpp"
|
||||
#include "maple/maple_bus_commands.hpp"
|
||||
#include "maple/maple_bus_ft0.hpp"
|
||||
|
||||
uint32_t _command_buf[1024 / 4 + 32];
|
||||
uint32_t _receive_buf[1024 / 4 + 32];
|
||||
|
||||
static ft0::data_transfer::data_format data[4];
|
||||
|
||||
void do_get_condition(uint32_t * command_buf,
|
||||
uint32_t * receive_buf)
|
||||
{
|
||||
using command_type = get_condition;
|
||||
using response_type = data_transfer<ft0::data_transfer::data_format>;
|
||||
|
||||
get_condition::data_fields data_fields = {
|
||||
.function_type = std::byteswap(function_type::controller)
|
||||
};
|
||||
|
||||
maple::init_host_command_all_ports<command_type, response_type>(command_buf, receive_buf,
|
||||
data_fields);
|
||||
maple::dma_start(command_buf);
|
||||
|
||||
using command_response_type = struct maple::command_response<response_type::data_fields>;
|
||||
for (uint8_t port = 0; port < 4; port++) {
|
||||
auto response = reinterpret_cast<command_response_type *>(receive_buf);
|
||||
auto& bus_data = response[port].bus_data;
|
||||
if (bus_data.command_code != response_type::command_code) {
|
||||
return;
|
||||
}
|
||||
auto& data_fields = bus_data.data_fields;
|
||||
if ((data_fields.function_type & std::byteswap(function_type::controller)) == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
bool a = ft0::data_transfer::digital_button::a(data_fields.data.digital_button);
|
||||
if (a == 0) {
|
||||
serial::string("port ");
|
||||
serial::integer<uint8_t>(port);
|
||||
serial::string(" `a` press ");
|
||||
serial::integer<uint8_t>(a);
|
||||
}
|
||||
*/
|
||||
data[port].analog_axis_3 = data_fields.data.analog_axis_3;
|
||||
data[port].analog_axis_4 = data_fields.data.analog_axis_4;
|
||||
}
|
||||
}
|
||||
|
||||
void transform(ta_parameter_writer& parameter,
|
||||
const vec3 * vertices,
|
||||
const face& face,
|
||||
const vec4& color,
|
||||
const vec3& position,
|
||||
const float scale
|
||||
)
|
||||
{
|
||||
const uint32_t parameter_control_word = para_control::para_type::polygon_or_modifier_volume
|
||||
| para_control::list_type::opaque
|
||||
| obj_control::col_type::floating_color
|
||||
| obj_control::gouraud;
|
||||
|
||||
const uint32_t isp_tsp_instruction_word = isp_tsp_instruction_word::depth_compare_mode::greater
|
||||
| isp_tsp_instruction_word::culling_mode::cull_if_positive;
|
||||
|
||||
const uint32_t tsp_instruction_word = tsp_instruction_word::src_alpha_instr::one
|
||||
| tsp_instruction_word::dst_alpha_instr::zero
|
||||
| tsp_instruction_word::fog_control::no_fog;
|
||||
|
||||
parameter.append<global_polygon_type_0>() = global_polygon_type_0(parameter_control_word,
|
||||
isp_tsp_instruction_word,
|
||||
tsp_instruction_word,
|
||||
0);
|
||||
|
||||
constexpr uint32_t strip_length = 3;
|
||||
for (uint32_t i = 0; i < strip_length; i++) {
|
||||
bool end_of_strip = i == strip_length - 1;
|
||||
|
||||
// world transform
|
||||
uint32_t vertex_ix = face[i].vertex;
|
||||
auto& vertex = vertices[vertex_ix];
|
||||
auto point = vertex;
|
||||
|
||||
// rotate 90° around the X axis
|
||||
float x = point.x;
|
||||
float y = point.z;
|
||||
float z = point.y;
|
||||
|
||||
// world transform
|
||||
x *= scale; // world space
|
||||
y *= scale; // world space
|
||||
z *= 10;
|
||||
|
||||
// object transform
|
||||
x += position.x; // object space
|
||||
y += position.y; // object space
|
||||
z += position.z; // object space
|
||||
|
||||
// camera transform
|
||||
z += 1;
|
||||
//y -= 10;
|
||||
|
||||
// screen space transform
|
||||
x *= 240.f;
|
||||
y *= 240.f;
|
||||
x += 320.f;
|
||||
y += 240.f;
|
||||
z = 1 / z;
|
||||
|
||||
parameter.append<vertex_polygon_type_1>() =
|
||||
vertex_polygon_type_1(x, y, z,
|
||||
color.w, // alpha
|
||||
color.x, // r
|
||||
color.y, // g
|
||||
color.z, // b
|
||||
end_of_strip);
|
||||
}
|
||||
}
|
||||
|
||||
void init_texture_memory(const struct opb_size& opb_size)
|
||||
{
|
||||
auto mem = reinterpret_cast<volatile texture_memory_alloc *>(texture_memory32);
|
||||
|
||||
background_parameter(mem->background, 0xff220000);
|
||||
|
||||
region_array2(mem->region_array,
|
||||
(offsetof (struct texture_memory_alloc, object_list)),
|
||||
640 / 32, // width
|
||||
480 / 32, // height
|
||||
opb_size
|
||||
);
|
||||
}
|
||||
|
||||
uint32_t _ta_parameter_buf[((32 * 8192) + 32) / 4];
|
||||
|
||||
void main()
|
||||
{
|
||||
uint32_t * command_buf = align_32byte(_command_buf);
|
||||
uint32_t * receive_buf = align_32byte(_receive_buf);
|
||||
|
||||
vga();
|
||||
|
||||
// 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);
|
||||
|
||||
constexpr uint32_t ta_alloc = ta_alloc_ctrl::pt_opb::no_list
|
||||
| ta_alloc_ctrl::tm_opb::no_list
|
||||
| ta_alloc_ctrl::t_opb::no_list
|
||||
| ta_alloc_ctrl::om_opb::no_list
|
||||
| ta_alloc_ctrl::o_opb::_16x4byte;
|
||||
|
||||
constexpr struct opb_size opb_size = { .opaque = 16 * 4
|
||||
, .opaque_modifier = 0
|
||||
, .translucent = 0
|
||||
, .translucent_modifier = 0
|
||||
, .punch_through = 0
|
||||
};
|
||||
|
||||
holly.SOFTRESET = softreset::pipeline_soft_reset
|
||||
| softreset::ta_soft_reset;
|
||||
holly.SOFTRESET = 0;
|
||||
|
||||
core_init();
|
||||
init_texture_memory(opb_size);
|
||||
|
||||
uint32_t frame_ix = 0;
|
||||
constexpr uint32_t num_frames = 1;
|
||||
|
||||
while (1) {
|
||||
do_get_condition(command_buf, receive_buf);
|
||||
|
||||
ta_polygon_converter_init(opb_size.total(),
|
||||
ta_alloc,
|
||||
640 / 32,
|
||||
480 / 32);
|
||||
|
||||
float x_pos = static_cast<float>(data[0].analog_axis_3 - 0x80) * (0.5 / 127);
|
||||
float y_pos = static_cast<float>(data[0].analog_axis_4 - 0x80) * (0.5 / 127);
|
||||
|
||||
auto parameter = ta_parameter_writer(ta_parameter_buf);
|
||||
for (uint32_t i = 0; i < border::num_faces; i++) {
|
||||
transform(parameter,
|
||||
border::vertices,
|
||||
border::faces[i],
|
||||
{1.0, 0.0, 0.0, 1.0}, // color
|
||||
{0.0, 0.0, 0.0}, // position
|
||||
0.5f * (1.f / 0.95f) // scale
|
||||
);
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < circle::num_faces; i++) {
|
||||
transform(parameter,
|
||||
circle::vertices,
|
||||
circle::faces[i],
|
||||
{0.0, 1.0, 1.0, 1.0}, // color
|
||||
{x_pos, y_pos, 0.0}, // position
|
||||
0.05f // scale
|
||||
);
|
||||
}
|
||||
|
||||
parameter.append<global_end_of_list>() = global_end_of_list();
|
||||
ta_polygon_converter_transfer(ta_parameter_buf, parameter.offset);
|
||||
ta_wait_opaque_list();
|
||||
core_start_render(frame_ix, num_frames);
|
||||
|
||||
v_sync_out();
|
||||
core_wait_end_of_render_video(frame_ix, num_frames);
|
||||
frame_ix += 1;
|
||||
}
|
||||
}
|
155
example/modifier_volume.cpp
Normal file
155
example/modifier_volume.cpp
Normal file
@ -0,0 +1,155 @@
|
||||
#include <cstdint>
|
||||
|
||||
#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 "holly/ta_bits.hpp"
|
||||
#include "holly/region_array.hpp"
|
||||
#include "holly/background.hpp"
|
||||
#include "memorymap.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, 0x00000000},
|
||||
{ 0.5f, -0.5f, 0.f, 127.f/128.f, 0.f , 0x00000000},
|
||||
};
|
||||
constexpr uint32_t strip_length = (sizeof (strip_vertices)) / (sizeof (struct vertex));
|
||||
|
||||
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 parameter = ta_parameter_writer(ta_parameter_buf);
|
||||
uint32_t texture_address = (offsetof (struct texture_memory_alloc, texture));
|
||||
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;
|
||||
|
||||
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);
|
||||
|
||||
parameter.append<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);
|
||||
}
|
||||
|
||||
parameter.append<global_end_of_list>() = global_end_of_list();
|
||||
|
||||
return parameter.offset;
|
||||
}
|
||||
|
||||
void init_texture_memory(const struct opb_size& opb_size)
|
||||
{
|
||||
auto mem = reinterpret_cast<volatile texture_memory_alloc *>(texture_memory32);
|
||||
|
||||
background_parameter(mem->background);
|
||||
|
||||
region_array2(mem->region_array,
|
||||
(offsetof (struct texture_memory_alloc, object_list)),
|
||||
640 / 32, // width
|
||||
480 / 32, // height
|
||||
opb_size
|
||||
);
|
||||
}
|
||||
|
||||
void copy_macaw_texture()
|
||||
{
|
||||
auto src = reinterpret_cast<const uint8_t *>(&_binary_macaw_data_start);
|
||||
auto size = reinterpret_cast<const uint32_t>(&_binary_macaw_data_size);
|
||||
auto mem = reinterpret_cast<volatile texture_memory_alloc *>(texture_memory64);
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t _ta_parameter_buf[((32 * (strip_length + 2)) + 32) / 4];
|
||||
|
||||
void main()
|
||||
{
|
||||
vga();
|
||||
copy_macaw_texture();
|
||||
|
||||
// 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);
|
||||
|
||||
constexpr uint32_t ta_alloc = ta_alloc_ctrl::pt_opb::no_list
|
||||
| ta_alloc_ctrl::tm_opb::no_list
|
||||
| ta_alloc_ctrl::t_opb::no_list
|
||||
| ta_alloc_ctrl::om_opb::no_list
|
||||
| ta_alloc_ctrl::o_opb::_16x4byte;
|
||||
|
||||
constexpr struct opb_size opb_size = { .opaque = 16 * 4
|
||||
, .opaque_modifier = 0
|
||||
, .translucent = 0
|
||||
, .translucent_modifier = 0
|
||||
, .punch_through = 0
|
||||
};
|
||||
|
||||
constexpr uint32_t tiles = (640 / 32) * (320 / 32);
|
||||
|
||||
holly.SOFTRESET = softreset::pipeline_soft_reset
|
||||
| softreset::ta_soft_reset;
|
||||
holly.SOFTRESET = 0;
|
||||
|
||||
core_init();
|
||||
init_texture_memory(opb_size);
|
||||
|
||||
uint32_t frame_ix = 0;
|
||||
constexpr uint32_t num_frames = 1;
|
||||
|
||||
while (true) {
|
||||
ta_polygon_converter_init(opb_size.total() * tiles, ta_alloc);
|
||||
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();
|
||||
|
||||
core_start_render(frame_ix, num_frames);
|
||||
|
||||
v_sync_in();
|
||||
core_wait_end_of_render_video(frame_ix, num_frames);
|
||||
|
||||
theta += half_degree;
|
||||
frame_ix += 1;
|
||||
}
|
||||
}
|
42
geometry/border.hpp
Normal file
42
geometry/border.hpp
Normal file
@ -0,0 +1,42 @@
|
||||
#pragma once
|
||||
|
||||
#include "geometry.hpp"
|
||||
|
||||
namespace border {
|
||||
constexpr vec3 vertices[] = {
|
||||
{ -1.000000f, 0.000000f, 1.000000f },
|
||||
{ 1.000000f, 0.000000f, 1.000000f },
|
||||
{ -1.000000f, 0.000000f, -1.000000f },
|
||||
{ 1.000000f, 0.000000f, -1.000000f },
|
||||
{ 0.950000f, 0.000000f, 1.000000f },
|
||||
{ 0.950000f, 0.000000f, -1.000000f },
|
||||
{ 0.950000f, 0.000000f, 0.950000f },
|
||||
{ 0.950000f, 0.000000f, -0.950000f },
|
||||
{ -0.950000f, 0.000000f, -1.000000f },
|
||||
{ -0.950000f, 0.000000f, 1.000000f },
|
||||
{ -0.950000f, 0.000000f, 0.950000f },
|
||||
{ -0.950000f, 0.000000f, -0.950000f },
|
||||
};
|
||||
|
||||
constexpr vec3 normals[] = {
|
||||
{ -0.000000f, 1.000000f, -0.000000f },
|
||||
};
|
||||
|
||||
constexpr face faces[] = {
|
||||
{{ 5, 0}, {11, 0}, { 7, 0}},
|
||||
{{ 4, 0}, {10, 0}, { 9, 0}},
|
||||
{{ 5, 0}, { 8, 0}, {11, 0}},
|
||||
{{ 4, 0}, { 6, 0}, {10, 0}},
|
||||
{{ 7, 0}, { 3, 0}, { 5, 0}},
|
||||
{{ 0, 0}, {10, 0}, {11, 0}},
|
||||
{{11, 0}, { 2, 0}, { 0, 0}},
|
||||
{{ 1, 0}, { 6, 0}, { 4, 0}},
|
||||
{{ 7, 0}, { 6, 0}, { 3, 0}},
|
||||
{{ 0, 0}, { 9, 0}, {10, 0}},
|
||||
{{11, 0}, { 8, 0}, { 2, 0}},
|
||||
{{ 1, 0}, { 3, 0}, { 6, 0}},
|
||||
};
|
||||
|
||||
constexpr uint32_t num_faces = (sizeof (faces)) / (sizeof (face));
|
||||
|
||||
}
|
29
geometry/border.obj
Normal file
29
geometry/border.obj
Normal file
@ -0,0 +1,29 @@
|
||||
# Blender 3.3.6
|
||||
# www.blender.org
|
||||
o Border
|
||||
v -1.000000 0.000000 1.000000
|
||||
v 1.000000 0.000000 1.000000
|
||||
v -1.000000 0.000000 -1.000000
|
||||
v 1.000000 0.000000 -1.000000
|
||||
v 0.950000 0.000000 1.000000
|
||||
v 0.950000 0.000000 -1.000000
|
||||
v 0.950000 0.000000 0.950000
|
||||
v 0.950000 0.000000 -0.950000
|
||||
v -0.950000 0.000000 -1.000000
|
||||
v -0.950000 0.000000 1.000000
|
||||
v -0.950000 0.000000 0.950000
|
||||
v -0.950000 0.000000 -0.950000
|
||||
vn -0.0000 1.0000 -0.0000
|
||||
s 0
|
||||
f 6//1 12//1 8//1
|
||||
f 5//1 11//1 10//1
|
||||
f 6//1 9//1 12//1
|
||||
f 5//1 7//1 11//1
|
||||
f 8//1 4//1 6//1
|
||||
f 1//1 11//1 12//1
|
||||
f 12//1 3//1 1//1
|
||||
f 2//1 7//1 5//1
|
||||
f 8//1 7//1 4//1
|
||||
f 1//1 10//1 11//1
|
||||
f 12//1 9//1 3//1
|
||||
f 2//1 4//1 7//1
|
80
geometry/circle.hpp
Normal file
80
geometry/circle.hpp
Normal file
@ -0,0 +1,80 @@
|
||||
#pragma once
|
||||
|
||||
#include "geometry.hpp"
|
||||
|
||||
namespace circle {
|
||||
constexpr vec3 vertices[] = {
|
||||
{ 0.000000f, 0.000000f, -1.000000f },
|
||||
{ -0.195090f, 0.000000f, -0.980785f },
|
||||
{ -0.382683f, 0.000000f, -0.923880f },
|
||||
{ -0.555570f, 0.000000f, -0.831470f },
|
||||
{ -0.707107f, 0.000000f, -0.707107f },
|
||||
{ -0.831470f, 0.000000f, -0.555570f },
|
||||
{ -0.923880f, 0.000000f, -0.382683f },
|
||||
{ -0.980785f, 0.000000f, -0.195090f },
|
||||
{ -1.000000f, 0.000000f, 0.000000f },
|
||||
{ -0.980785f, 0.000000f, 0.195090f },
|
||||
{ -0.923880f, 0.000000f, 0.382683f },
|
||||
{ -0.831470f, 0.000000f, 0.555570f },
|
||||
{ -0.707107f, 0.000000f, 0.707107f },
|
||||
{ -0.555570f, 0.000000f, 0.831470f },
|
||||
{ -0.382683f, 0.000000f, 0.923880f },
|
||||
{ -0.195090f, 0.000000f, 0.980785f },
|
||||
{ 0.000000f, 0.000000f, 1.000000f },
|
||||
{ 0.195090f, 0.000000f, 0.980785f },
|
||||
{ 0.382683f, 0.000000f, 0.923880f },
|
||||
{ 0.555570f, 0.000000f, 0.831470f },
|
||||
{ 0.707107f, 0.000000f, 0.707107f },
|
||||
{ 0.831470f, 0.000000f, 0.555570f },
|
||||
{ 0.923880f, 0.000000f, 0.382683f },
|
||||
{ 0.980785f, 0.000000f, 0.195090f },
|
||||
{ 1.000000f, 0.000000f, 0.000000f },
|
||||
{ 0.980785f, 0.000000f, -0.195090f },
|
||||
{ 0.923880f, 0.000000f, -0.382683f },
|
||||
{ 0.831470f, 0.000000f, -0.555570f },
|
||||
{ 0.707107f, 0.000000f, -0.707107f },
|
||||
{ 0.555570f, 0.000000f, -0.831470f },
|
||||
{ 0.382683f, 0.000000f, -0.923880f },
|
||||
{ 0.195090f, 0.000000f, -0.980785f },
|
||||
};
|
||||
|
||||
constexpr vec3 normals[] = {
|
||||
{ -0.000000f, 1.000000f, -0.000000f },
|
||||
};
|
||||
|
||||
constexpr face faces[] = {
|
||||
{{31, 0}, { 0, 0}, { 1, 0}},
|
||||
{{30, 0}, {31, 0}, { 1, 0}},
|
||||
{{20, 0}, {13, 0}, {18, 0}},
|
||||
{{ 1, 0}, { 2, 0}, { 3, 0}},
|
||||
{{29, 0}, { 1, 0}, { 3, 0}},
|
||||
{{28, 0}, {29, 0}, { 3, 0}},
|
||||
{{29, 0}, {30, 0}, { 1, 0}},
|
||||
{{ 3, 0}, { 4, 0}, { 5, 0}},
|
||||
{{27, 0}, { 3, 0}, { 5, 0}},
|
||||
{{26, 0}, {27, 0}, { 5, 0}},
|
||||
{{26, 0}, { 5, 0}, { 6, 0}},
|
||||
{{25, 0}, {26, 0}, { 6, 0}},
|
||||
{{25, 0}, { 6, 0}, { 7, 0}},
|
||||
{{24, 0}, {25, 0}, { 7, 0}},
|
||||
{{24, 0}, { 7, 0}, { 8, 0}},
|
||||
{{23, 0}, {24, 0}, { 8, 0}},
|
||||
{{23, 0}, { 8, 0}, { 9, 0}},
|
||||
{{22, 0}, {23, 0}, { 9, 0}},
|
||||
{{22, 0}, { 9, 0}, {10, 0}},
|
||||
{{21, 0}, {22, 0}, {10, 0}},
|
||||
{{21, 0}, {10, 0}, {11, 0}},
|
||||
{{20, 0}, {21, 0}, {11, 0}},
|
||||
{{12, 0}, {13, 0}, {11, 0}},
|
||||
{{27, 0}, {28, 0}, { 3, 0}},
|
||||
{{13, 0}, {20, 0}, {11, 0}},
|
||||
{{19, 0}, {20, 0}, {18, 0}},
|
||||
{{18, 0}, {13, 0}, {14, 0}},
|
||||
{{17, 0}, {18, 0}, {14, 0}},
|
||||
{{17, 0}, {14, 0}, {15, 0}},
|
||||
{{16, 0}, {17, 0}, {15, 0}},
|
||||
};
|
||||
|
||||
constexpr uint32_t num_faces = (sizeof (faces)) / (sizeof (face));
|
||||
|
||||
}
|
67
geometry/circle.obj
Normal file
67
geometry/circle.obj
Normal file
@ -0,0 +1,67 @@
|
||||
# Blender 3.3.6
|
||||
# www.blender.org
|
||||
o Circle
|
||||
v 0.000000 0.000000 -1.000000
|
||||
v -0.195090 0.000000 -0.980785
|
||||
v -0.382683 0.000000 -0.923880
|
||||
v -0.555570 0.000000 -0.831470
|
||||
v -0.707107 0.000000 -0.707107
|
||||
v -0.831470 0.000000 -0.555570
|
||||
v -0.923880 0.000000 -0.382683
|
||||
v -0.980785 0.000000 -0.195090
|
||||
v -1.000000 0.000000 0.000000
|
||||
v -0.980785 0.000000 0.195090
|
||||
v -0.923880 0.000000 0.382683
|
||||
v -0.831470 0.000000 0.555570
|
||||
v -0.707107 0.000000 0.707107
|
||||
v -0.555570 0.000000 0.831470
|
||||
v -0.382683 0.000000 0.923880
|
||||
v -0.195090 0.000000 0.980785
|
||||
v 0.000000 0.000000 1.000000
|
||||
v 0.195090 0.000000 0.980785
|
||||
v 0.382683 0.000000 0.923880
|
||||
v 0.555570 0.000000 0.831470
|
||||
v 0.707107 0.000000 0.707107
|
||||
v 0.831470 0.000000 0.555570
|
||||
v 0.923880 0.000000 0.382683
|
||||
v 0.980785 0.000000 0.195090
|
||||
v 1.000000 0.000000 0.000000
|
||||
v 0.980785 0.000000 -0.195090
|
||||
v 0.923880 0.000000 -0.382683
|
||||
v 0.831470 0.000000 -0.555570
|
||||
v 0.707107 0.000000 -0.707107
|
||||
v 0.555570 0.000000 -0.831470
|
||||
v 0.382683 0.000000 -0.923880
|
||||
v 0.195090 0.000000 -0.980785
|
||||
vn -0.0000 1.0000 -0.0000
|
||||
s 0
|
||||
f 32//1 1//1 2//1
|
||||
f 31//1 32//1 2//1
|
||||
f 21//1 14//1 19//1
|
||||
f 2//1 3//1 4//1
|
||||
f 30//1 2//1 4//1
|
||||
f 29//1 30//1 4//1
|
||||
f 30//1 31//1 2//1
|
||||
f 4//1 5//1 6//1
|
||||
f 28//1 4//1 6//1
|
||||
f 27//1 28//1 6//1
|
||||
f 27//1 6//1 7//1
|
||||
f 26//1 27//1 7//1
|
||||
f 26//1 7//1 8//1
|
||||
f 25//1 26//1 8//1
|
||||
f 25//1 8//1 9//1
|
||||
f 24//1 25//1 9//1
|
||||
f 24//1 9//1 10//1
|
||||
f 23//1 24//1 10//1
|
||||
f 23//1 10//1 11//1
|
||||
f 22//1 23//1 11//1
|
||||
f 22//1 11//1 12//1
|
||||
f 21//1 22//1 12//1
|
||||
f 13//1 14//1 12//1
|
||||
f 28//1 29//1 4//1
|
||||
f 14//1 21//1 12//1
|
||||
f 20//1 21//1 19//1
|
||||
f 19//1 14//1 15//1
|
||||
f 18//1 19//1 15//1
|
||||
f 18//1 15//1 16//1
|
||||
f 17//1 18//1 16//1
|
@ -1,43 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "geometry.hpp"
|
||||
|
||||
namespace cube {
|
||||
constexpr vec3 vertices[] = {
|
||||
{ 1.000000f, 1.000000f, -1.000000f },
|
||||
{ 1.000000f, -1.000000f, -1.000000f },
|
||||
{ 1.000000f, 1.000000f, 1.000000f },
|
||||
{ 1.000000f, -1.000000f, 1.000000f },
|
||||
{ -1.000000f, 1.000000f, -1.000000f },
|
||||
{ -1.000000f, -1.000000f, -1.000000f },
|
||||
{ -1.000000f, 1.000000f, 1.000000f },
|
||||
{ -1.000000f, -1.000000f, 1.000000f },
|
||||
};
|
||||
|
||||
constexpr vec3 normals[] = {
|
||||
{ -0.000000f, 1.000000f, -0.000000f },
|
||||
{ -0.000000f, -0.000000f, 1.000000f },
|
||||
{ -1.000000f, -0.000000f, -0.000000f },
|
||||
{ -0.000000f, -1.000000f, -0.000000f },
|
||||
{ 1.000000f, -0.000000f, -0.000000f },
|
||||
{ -0.000000f, -0.000000f, -1.000000f },
|
||||
};
|
||||
|
||||
constexpr face faces[] = {
|
||||
{{ 4, 0}, { 2, 0}, { 0, 0}},
|
||||
{{ 2, 1}, { 7, 1}, { 3, 1}},
|
||||
{{ 6, 2}, { 5, 2}, { 7, 2}},
|
||||
{{ 1, 3}, { 7, 3}, { 5, 3}},
|
||||
{{ 0, 4}, { 3, 4}, { 1, 4}},
|
||||
{{ 4, 5}, { 1, 5}, { 5, 5}},
|
||||
{{ 4, 0}, { 6, 0}, { 2, 0}},
|
||||
{{ 2, 1}, { 6, 1}, { 7, 1}},
|
||||
{{ 6, 2}, { 4, 2}, { 5, 2}},
|
||||
{{ 1, 3}, { 3, 3}, { 7, 3}},
|
||||
{{ 0, 4}, { 2, 4}, { 3, 4}},
|
||||
{{ 4, 5}, { 0, 5}, { 1, 5}},
|
||||
};
|
||||
|
||||
constexpr uint32_t num_faces = (sizeof (faces)) / (sizeof (face));
|
||||
|
||||
}
|
@ -1,30 +1,41 @@
|
||||
# Blender 3.3.6
|
||||
# www.blender.org
|
||||
o Cube
|
||||
v 1.000000 1.000000 -1.000000
|
||||
v 1.000000 -1.000000 -1.000000
|
||||
v 1.000000 1.000000 1.000000
|
||||
v 1.000000 -1.000000 1.000000
|
||||
v -1.000000 1.000000 -1.000000
|
||||
v -1.000000 -1.000000 -1.000000
|
||||
v -1.000000 1.000000 1.000000
|
||||
v -1.000000 -1.000000 1.000000
|
||||
vn -0.0000 1.0000 -0.0000
|
||||
vn -0.0000 -0.0000 1.0000
|
||||
v -1.000000 1.000000 1.000000
|
||||
v -1.000000 -1.000000 -1.000000
|
||||
v -1.000000 1.000000 -1.000000
|
||||
v 1.000000 -1.000000 1.000000
|
||||
v 1.000000 1.000000 1.000000
|
||||
v 1.000000 -1.000000 -1.000000
|
||||
v 1.000000 1.000000 -1.000000
|
||||
vn -1.0000 -0.0000 -0.0000
|
||||
vn -0.0000 -1.0000 -0.0000
|
||||
vn 1.0000 -0.0000 -0.0000
|
||||
vn -0.0000 -0.0000 -1.0000
|
||||
vn 1.0000 -0.0000 -0.0000
|
||||
vn -0.0000 -0.0000 1.0000
|
||||
vn -0.0000 -1.0000 -0.0000
|
||||
vn -0.0000 1.0000 -0.0000
|
||||
vt 1.000000 0.000000
|
||||
vt 1.000000 1.000000
|
||||
vt 0.000000 0.000000
|
||||
vt 1.000000 1.000000
|
||||
vt 1.000000 0.000000
|
||||
vt 0.000000 0.000000
|
||||
vt 0.000000 1.000000
|
||||
vt 1.000000 0.000000
|
||||
vt 0.000000 1.000000
|
||||
vt 0.000000 0.000000
|
||||
vt 1.000000 1.000000
|
||||
s 0
|
||||
f 5//1 3//1 1//1
|
||||
f 3//2 8//2 4//2
|
||||
f 7//3 6//3 8//3
|
||||
f 2//4 8//4 6//4
|
||||
f 1//5 4//5 2//5
|
||||
f 5//6 2//6 6//6
|
||||
f 5//1 7//1 3//1
|
||||
f 3//2 7//2 8//2
|
||||
f 7//3 5//3 6//3
|
||||
f 2//4 4//4 8//4
|
||||
f 1//5 3//5 4//5
|
||||
f 5//6 1//6 2//6
|
||||
f 2/2/1 3/4/1 1/1/1
|
||||
f 4/5/2 7/9/2 3/3/2
|
||||
f 8/11/3 5/6/3 7/8/3
|
||||
f 6/7/4 1/1/4 5/6/4
|
||||
f 7/9/5 1/1/5 3/4/5
|
||||
f 4/5/6 6/7/6 8/10/6
|
||||
f 2/2/1 4/5/1 3/4/1
|
||||
f 4/5/2 8/11/2 7/9/2
|
||||
f 8/11/3 6/7/3 5/6/3
|
||||
f 6/7/4 2/2/4 1/1/4
|
||||
f 7/9/5 5/6/5 1/1/5
|
||||
f 4/5/6 2/2/6 6/7/6
|
||||
|
@ -2,14 +2,17 @@
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#include "math/vec2.hpp"
|
||||
#include "math/vec3.hpp"
|
||||
#include "math/vec4.hpp"
|
||||
|
||||
using vec2 = vec<2, float>;
|
||||
using vec3 = vec<3, float>;
|
||||
using vec4 = vec<4, float>;
|
||||
|
||||
struct vertex__normal {
|
||||
uint16_t vertex;
|
||||
uint16_t texture;
|
||||
uint16_t normal;
|
||||
};
|
||||
|
||||
|
15
geometry/plane.obj
Normal file
15
geometry/plane.obj
Normal file
@ -0,0 +1,15 @@
|
||||
# Blender 3.3.6
|
||||
# www.blender.org
|
||||
o Plane
|
||||
v -1.000000 0.000000 1.000000
|
||||
v 1.000000 0.000000 1.000000
|
||||
v -1.000000 0.000000 -1.000000
|
||||
v 1.000000 0.000000 -1.000000
|
||||
vn -0.0000 1.0000 -0.0000
|
||||
vt 0.000000 0.000000
|
||||
vt 1.000000 0.000000
|
||||
vt 0.000000 1.000000
|
||||
vt 1.000000 1.000000
|
||||
s 0
|
||||
f 2/2/1 3/3/1 1/1/1
|
||||
f 2/2/1 4/4/1 3/3/1
|
@ -37,33 +37,6 @@ void init_host_command(uint32_t * command_buf, uint32_t * receive_buf,
|
||||
host_command->bus_data.data_size = data_size / 4;
|
||||
}
|
||||
|
||||
void init_host_command_all_ports(uint32_t * buf, uint32_t * receive_buf,
|
||||
uint8_t command_code, uint32_t command_data_size, uint32_t response_data_size)
|
||||
{
|
||||
const uint32_t command_size = ((sizeof (struct host_command<uint8_t[0]>)) + command_data_size);
|
||||
const uint32_t response_size = align_32byte(((sizeof (struct command_response<uint8_t[0]>)) + response_data_size));
|
||||
|
||||
init_host_command(&buf[(command_size / 4) * 0], &receive_buf[(response_size / 4) * 0],
|
||||
host_instruction::port_select::a, // destination_port
|
||||
ap::de::device | ap::port_select::a, command_code, command_data_size,
|
||||
false); // end_flag
|
||||
|
||||
init_host_command(&buf[(command_size / 4) * 1], &receive_buf[(response_size / 4) * 1],
|
||||
host_instruction::port_select::b, // destination_port
|
||||
ap::de::device | ap::port_select::b, command_code, command_data_size,
|
||||
false); // end_flag
|
||||
|
||||
init_host_command(&buf[(command_size / 4) * 2], &receive_buf[(response_size / 4) * 2],
|
||||
host_instruction::port_select::c, // destination_port
|
||||
ap::de::device | ap::port_select::c, command_code, command_data_size,
|
||||
false); // end_flag
|
||||
|
||||
init_host_command(&buf[(command_size / 4) * 3], &receive_buf[(response_size / 4) * 3],
|
||||
host_instruction::port_select::d, // destination_port
|
||||
ap::de::device | ap::port_select::d, command_code, command_data_size,
|
||||
true); // end_flag
|
||||
}
|
||||
|
||||
void init_device_request(uint32_t * buf, uint32_t * receive_buf,
|
||||
uint32_t destination_port,
|
||||
uint8_t destination_ap)
|
||||
|
@ -2,6 +2,8 @@
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#include "align.hpp"
|
||||
|
||||
namespace maple {
|
||||
|
||||
template <typename T>
|
||||
@ -26,16 +28,15 @@ struct command_response {
|
||||
uint8_t data_size;
|
||||
T data_fields;
|
||||
} bus_data;
|
||||
uint8_t _pad[align_32byte((sizeof (bus_data))) - (sizeof (bus_data))];
|
||||
};
|
||||
static_assert((sizeof (command_response<uint8_t[0]>)) == align_32byte((sizeof (command_response<uint8_t[0]>))));
|
||||
|
||||
void init_host_command(uint32_t * buf, uint32_t * receive_buf,
|
||||
uint32_t destination_port,
|
||||
uint8_t destination_ap, uint8_t command_code, uint8_t data_size,
|
||||
bool end_flag);
|
||||
|
||||
void init_host_command_all_ports(uint32_t * buf, uint32_t * receive_buf,
|
||||
uint8_t command_code, uint32_t command_data_size, uint32_t response_data_size);
|
||||
|
||||
void init_device_request(uint32_t * buf, uint32_t * receive_buf,
|
||||
uint32_t destination_port,
|
||||
uint8_t destination_ap);
|
||||
|
@ -1,3 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#include "../float_uint32.hpp"
|
||||
|
@ -1,3 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
struct device_id {
|
||||
@ -6,36 +8,40 @@ struct device_id {
|
||||
};
|
||||
|
||||
static_assert((sizeof (struct device_id)) == 16);
|
||||
namespace device_request {
|
||||
constexpr uint32_t command_code = 0x1;
|
||||
struct device_request {
|
||||
static constexpr uint32_t command_code = 0x1;
|
||||
|
||||
struct data_fields {
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
namespace all_status_request {
|
||||
constexpr uint32_t command_code = 0x2;
|
||||
|
||||
struct all_status_request {
|
||||
static constexpr uint32_t command_code = 0x2;
|
||||
|
||||
struct data_fields {
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
namespace device_reset {
|
||||
constexpr uint32_t command_code = 0x3;
|
||||
|
||||
struct device_reset {
|
||||
static constexpr uint32_t command_code = 0x3;
|
||||
|
||||
struct data_fields {
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
namespace device_kill {
|
||||
constexpr uint32_t command_code = 0x4;
|
||||
|
||||
struct device_kill {
|
||||
static constexpr uint32_t command_code = 0x4;
|
||||
|
||||
struct data_fields {
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
namespace device_status {
|
||||
constexpr uint32_t command_code = 0x5;
|
||||
|
||||
struct device_status {
|
||||
static constexpr uint32_t command_code = 0x5;
|
||||
|
||||
struct data_fields {
|
||||
struct device_id device_id;
|
||||
@ -48,10 +54,11 @@ namespace device_status {
|
||||
};
|
||||
|
||||
static_assert((sizeof (struct data_fields)) == 112);
|
||||
}
|
||||
};
|
||||
|
||||
namespace device_all_status {
|
||||
constexpr uint32_t command_code = 0x6;
|
||||
|
||||
struct device_all_status {
|
||||
static constexpr uint32_t command_code = 0x6;
|
||||
|
||||
template <typename T>
|
||||
struct data_fields {
|
||||
@ -66,39 +73,40 @@ namespace device_all_status {
|
||||
};
|
||||
|
||||
static_assert((sizeof (struct data_fields<char[0]>)) == 112);
|
||||
}
|
||||
};
|
||||
|
||||
namespace device_reply {
|
||||
constexpr uint32_t command_code = 0x7;
|
||||
|
||||
struct device_reply {
|
||||
static constexpr uint32_t command_code = 0x7;
|
||||
|
||||
struct data_fields {
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct data_transfer {
|
||||
static constexpr uint32_t command_code = 0x8;
|
||||
|
||||
namespace data_transfer {
|
||||
constexpr uint32_t command_code = 0x8;
|
||||
|
||||
template <typename T>
|
||||
struct data_fields {
|
||||
uint32_t function_type;
|
||||
T data;
|
||||
};
|
||||
|
||||
static_assert((sizeof (struct data_fields<char[0]>)) == 4);
|
||||
}
|
||||
};
|
||||
static_assert((sizeof (struct data_transfer<uint8_t[0]>::data_fields)) == 4);
|
||||
|
||||
namespace get_condition {
|
||||
constexpr uint32_t command_code = 0x9;
|
||||
struct get_condition {
|
||||
static constexpr uint32_t command_code = 0x9;
|
||||
|
||||
struct data_fields {
|
||||
uint32_t function_type;
|
||||
};
|
||||
|
||||
static_assert((sizeof (struct data_fields)) == 4);
|
||||
}
|
||||
};
|
||||
|
||||
namespace get_media_info {
|
||||
constexpr uint32_t command_code = 0xa;
|
||||
|
||||
struct get_media_info {
|
||||
static constexpr uint32_t command_code = 0xa;
|
||||
|
||||
struct data_fields {
|
||||
uint32_t function_type;
|
||||
@ -106,10 +114,11 @@ namespace get_media_info {
|
||||
};
|
||||
|
||||
static_assert((sizeof (struct data_fields)) == 8);
|
||||
}
|
||||
};
|
||||
|
||||
namespace block_read {
|
||||
constexpr uint32_t command_code = 0xb;
|
||||
|
||||
struct block_read {
|
||||
static constexpr uint32_t command_code = 0xb;
|
||||
|
||||
struct data_fields {
|
||||
uint32_t function_type;
|
||||
@ -119,10 +128,11 @@ namespace block_read {
|
||||
};
|
||||
|
||||
static_assert((sizeof (struct data_fields)) == 8);
|
||||
}
|
||||
};
|
||||
|
||||
namespace block_write {
|
||||
constexpr uint32_t command_code = 0xc;
|
||||
|
||||
struct block_write {
|
||||
static constexpr uint32_t command_code = 0xc;
|
||||
|
||||
template <typename T>
|
||||
struct data_fields {
|
||||
@ -134,10 +144,11 @@ namespace block_write {
|
||||
};
|
||||
|
||||
static_assert((sizeof (struct data_fields<char[0]>)) == 8);
|
||||
}
|
||||
};
|
||||
|
||||
namespace get_last_error {
|
||||
constexpr uint32_t command_code = 0xd;
|
||||
|
||||
struct get_last_error {
|
||||
static constexpr uint32_t command_code = 0xd;
|
||||
|
||||
struct data_fields {
|
||||
uint32_t function_type;
|
||||
@ -147,10 +158,11 @@ namespace get_last_error {
|
||||
};
|
||||
|
||||
static_assert((sizeof (struct data_fields)) == 8);
|
||||
}
|
||||
};
|
||||
|
||||
namespace set_condition {
|
||||
constexpr uint32_t command_code = 0xe;
|
||||
|
||||
struct set_condition {
|
||||
static constexpr uint32_t command_code = 0xe;
|
||||
|
||||
template <typename T>
|
||||
struct data_fields {
|
||||
@ -159,10 +171,11 @@ namespace set_condition {
|
||||
};
|
||||
|
||||
static_assert((sizeof (struct data_fields<char[0]>)) == 4);
|
||||
}
|
||||
};
|
||||
|
||||
namespace ft4_control {
|
||||
constexpr uint32_t command_code = 0xf;
|
||||
|
||||
struct ft4_control {
|
||||
static constexpr uint32_t command_code = 0xf;
|
||||
|
||||
template <typename T>
|
||||
struct data_fields {
|
||||
@ -171,10 +184,11 @@ namespace ft4_control {
|
||||
};
|
||||
|
||||
static_assert((sizeof (struct data_fields<char[0]>)) == 4);
|
||||
}
|
||||
};
|
||||
|
||||
namespace ar_control {
|
||||
constexpr uint32_t command_code = 0x10;
|
||||
|
||||
struct ar_control {
|
||||
static constexpr uint32_t command_code = 0x10;
|
||||
|
||||
template <typename T>
|
||||
struct data_fields {
|
||||
@ -183,56 +197,63 @@ namespace ar_control {
|
||||
};
|
||||
|
||||
static_assert((sizeof (struct data_fields<char[0]>)) == 4);
|
||||
}
|
||||
};
|
||||
|
||||
namespace function_type_unknown {
|
||||
constexpr uint32_t command_code = 0xfe;
|
||||
|
||||
struct function_type_unknown {
|
||||
static constexpr uint32_t command_code = 0xfe;
|
||||
|
||||
struct data_fields {
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
namespace command_unknown {
|
||||
constexpr uint32_t command_code = 0xfd;
|
||||
|
||||
struct command_unknown {
|
||||
static constexpr uint32_t command_code = 0xfd;
|
||||
|
||||
struct data_fields {
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
namespace transmit_again {
|
||||
constexpr uint32_t command_code = 0xfc;
|
||||
|
||||
struct transmit_again {
|
||||
static constexpr uint32_t command_code = 0xfc;
|
||||
|
||||
struct data_fields {
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
namespace file_error {
|
||||
constexpr uint32_t command_code = 0xfb;
|
||||
|
||||
struct file_error {
|
||||
static constexpr uint32_t command_code = 0xfb;
|
||||
|
||||
struct data_fields {
|
||||
uint32_t function_error_code;
|
||||
};
|
||||
|
||||
static_assert((sizeof (struct data_fields)) == 4);
|
||||
}
|
||||
};
|
||||
|
||||
namespace lcd_error {
|
||||
constexpr uint32_t command_code = 0xfa;
|
||||
|
||||
struct lcd_error {
|
||||
static constexpr uint32_t command_code = 0xfa;
|
||||
|
||||
struct data_fields {
|
||||
uint32_t function_error_code;
|
||||
};
|
||||
|
||||
static_assert((sizeof (struct data_fields)) == 4);
|
||||
}
|
||||
};
|
||||
|
||||
namespace ar_error {
|
||||
constexpr uint32_t command_code = 0xf9;
|
||||
|
||||
struct ar_error {
|
||||
static constexpr uint32_t command_code = 0xf9;
|
||||
|
||||
struct data_fields {
|
||||
uint32_t function_error_code;
|
||||
};
|
||||
|
||||
static_assert((sizeof (struct data_fields)) == 4);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
46
maple/maple_impl.hpp
Normal file
46
maple/maple_impl.hpp
Normal file
@ -0,0 +1,46 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#include "maple/maple.hpp"
|
||||
#include "maple/maple_bus_commands.hpp"
|
||||
#include "maple/maple_bus_bits.hpp"
|
||||
|
||||
namespace maple {
|
||||
|
||||
template <typename C, typename R>
|
||||
void init_host_command_all_ports(uint32_t * command_buf, uint32_t * receive_buf,
|
||||
const typename C::data_fields& data_fields)
|
||||
{
|
||||
using command_type = maple::host_command<typename C::data_fields>;
|
||||
using response_type = maple::command_response<typename R::data_fields>;
|
||||
|
||||
auto host_command = reinterpret_cast<command_type *>(command_buf);
|
||||
auto response_command = reinterpret_cast<response_type *>(receive_buf);
|
||||
|
||||
init_host_command((uint32_t*)&host_command[0], (uint32_t*)&response_command[0],
|
||||
host_instruction::port_select::a, // destination_port
|
||||
ap::de::device | ap::port_select::a, C::command_code, (sizeof (typename C::data_fields)),
|
||||
false); // end_flag
|
||||
host_command[0].bus_data.data_fields = data_fields;
|
||||
|
||||
init_host_command((uint32_t*)&host_command[1], (uint32_t*)&response_command[1],
|
||||
host_instruction::port_select::b, // destination_port
|
||||
ap::de::device | ap::port_select::b, C::command_code, (sizeof (typename C::data_fields)),
|
||||
false); // end_flag
|
||||
host_command[1].bus_data.data_fields = data_fields;
|
||||
|
||||
init_host_command((uint32_t*)&host_command[2], (uint32_t*)&response_command[2],
|
||||
host_instruction::port_select::c, // destination_port
|
||||
ap::de::device | ap::port_select::c, C::command_code, (sizeof (typename C::data_fields)),
|
||||
false); // end_flag
|
||||
host_command[2].bus_data.data_fields = data_fields;
|
||||
|
||||
init_host_command((uint32_t*)&host_command[3], (uint32_t*)&response_command[3],
|
||||
host_instruction::port_select::d, // destination_port
|
||||
ap::de::device | ap::port_select::d, C::command_code, (sizeof (typename C::data_fields)),
|
||||
true); // end_flag
|
||||
host_command[3].bus_data.data_fields = data_fields;
|
||||
}
|
||||
|
||||
}
|
147
math/vec2.hpp
Normal file
147
math/vec2.hpp
Normal file
@ -0,0 +1,147 @@
|
||||
#pragma once
|
||||
|
||||
#include "math.hpp"
|
||||
#include "vec.hpp"
|
||||
|
||||
//
|
||||
// vec3
|
||||
//
|
||||
|
||||
template <typename T>
|
||||
struct vec<2, T>
|
||||
{
|
||||
union {
|
||||
struct { T x, y; };
|
||||
struct { T u, v; };
|
||||
};
|
||||
|
||||
inline constexpr vec();
|
||||
inline constexpr vec(T scalar);
|
||||
inline constexpr vec(T _x, T _y);
|
||||
|
||||
constexpr inline vec<2, T> operator-() const;
|
||||
inline constexpr T const& operator[](int i) const;
|
||||
inline constexpr vec<2, T>& operator=(vec<2, T> const& v);
|
||||
inline constexpr vec<2, T>& operator+=(vec<2, T> const& v);
|
||||
inline constexpr vec<2, T>& operator-=(vec<2, T> const& v);
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
inline constexpr vec<2, T>::vec()
|
||||
: x(0), y(0), z(0)
|
||||
{}
|
||||
|
||||
template <typename T>
|
||||
inline constexpr vec<2, T>::vec(T scalar)
|
||||
: x(scalar), y(scalar), z(scalar)
|
||||
{}
|
||||
|
||||
template <typename T>
|
||||
inline constexpr vec<2, T>::vec(T _x, T _y)
|
||||
: x(_x), y(_y)
|
||||
{}
|
||||
|
||||
template <typename T>
|
||||
constexpr inline vec<2, T> vec<2, T>::operator-() const
|
||||
{
|
||||
return vec<2, T>(-x, -y);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline constexpr T const& vec<2, T>::operator[](int i) const
|
||||
{
|
||||
switch(i)
|
||||
{
|
||||
default: [[fallthrough]];
|
||||
case 0: return x;
|
||||
case 1: return y;
|
||||
case 2: return z;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline constexpr vec<2, T>& vec<2, T>::operator=(vec<2, T> const& v)
|
||||
{
|
||||
this->x = static_cast<T>(v.x);
|
||||
this->y = static_cast<T>(v.y);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline constexpr vec<2, T>& vec<2, T>::operator+=(vec<2, T> const& v)
|
||||
{
|
||||
*this = *this + vec<2, T>(v);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline constexpr vec<2, T>& vec<2, T>::operator-=(vec<2, T> const& v)
|
||||
{
|
||||
*this = *this - vec<2, T>(v);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline constexpr vec<2, T> operator+(vec<2, T> const& v1, vec<2, T> const& v2)
|
||||
{
|
||||
return vec<2, T>(v1.x + v2.x,
|
||||
v1.y + v2.y);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline constexpr vec<2, T> operator-(vec<2, T> const& v1, vec<2, T> const& v2)
|
||||
{
|
||||
return vec<2, T>(v1.x - v2.x,
|
||||
v1.y - v2.y);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline constexpr vec<2, T> operator*(vec<2, T> const& v1, vec<2, T> const& v2)
|
||||
{
|
||||
return vec<2, T>(v1.x * v2.x,
|
||||
v1.y * v2.y);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline constexpr vec<2, T> operator*(vec<2, T> const& v1, T const& scalar)
|
||||
{
|
||||
return v1 * vec<2, T>(scalar);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline constexpr vec<2, T> operator/(vec<2, T> const& v1, vec<2, T> const& v2)
|
||||
{
|
||||
return vec<2, T>(v1.x / v2.x,
|
||||
v1.y / v2.y);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline constexpr vec<2, T> operator/(vec<2, T> const& v1, T const& scalar)
|
||||
{
|
||||
return v1 / vec<2, T>(scalar);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline constexpr T dot(vec<2, T> const& v1, vec<2, T> const& v2)
|
||||
{
|
||||
vec<2, T> tmp(v1 * v2);
|
||||
return tmp.x + tmp.y;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline constexpr vec<2, T> functor1(T (&func) (T const& x), vec<2, T> const& v)
|
||||
{
|
||||
return vec<2, T>(func(v.x), func(v.y));
|
||||
}
|
||||
|
||||
template <typename T, typename U>
|
||||
inline constexpr vec<2, U> functor1(U (&func) (T const& x), vec<2, T> const& v)
|
||||
{
|
||||
return vec<2, U>(func(v.x), func(v.y));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline constexpr T length(vec<2, T> const& v)
|
||||
{
|
||||
return sqrt(dot(v, v));
|
||||
}
|
@ -10,7 +10,10 @@
|
||||
template <typename T>
|
||||
struct vec<3, T>
|
||||
{
|
||||
T x, y, z;
|
||||
union {
|
||||
struct { T x, y, z; };
|
||||
struct { T r, g, b; };
|
||||
};
|
||||
|
||||
inline constexpr vec();
|
||||
inline constexpr vec(T scalar);
|
||||
|
@ -10,7 +10,10 @@
|
||||
template <typename T>
|
||||
struct vec<4, T>
|
||||
{
|
||||
T x, y, z, w;
|
||||
union {
|
||||
struct { T x, y, z, w; };
|
||||
struct { T r, g, b, a; };
|
||||
}
|
||||
|
||||
inline constexpr vec();
|
||||
inline constexpr vec(T scalar);
|
||||
|
61
qemu.lds
Normal file
61
qemu.lds
Normal file
@ -0,0 +1,61 @@
|
||||
OUTPUT_FORMAT("elf32-shl", "elf32-shl", "elf32-shl")
|
||||
MEMORY
|
||||
{
|
||||
p1ram : ORIGIN = 0x00000000, LENGTH = 0x7fffffff
|
||||
}
|
||||
SECTIONS
|
||||
{
|
||||
. = ORIGIN(p1ram);
|
||||
|
||||
.text ALIGN(4) : SUBALIGN(4)
|
||||
{
|
||||
KEEP(*(.text.start))
|
||||
*(.text.startup.*)
|
||||
*(.text.*)
|
||||
*(.text)
|
||||
} > p1ram
|
||||
|
||||
.data ALIGN(4) : SUBALIGN(4)
|
||||
{
|
||||
*(.data)
|
||||
*(.data.*)
|
||||
} > p1ram
|
||||
|
||||
.rodata ALIGN(4) : SUBALIGN(4)
|
||||
{
|
||||
*(.rodata)
|
||||
*(.rodata.*)
|
||||
} > p1ram
|
||||
|
||||
.ctors ALIGN(4) : SUBALIGN(4)
|
||||
{
|
||||
KEEP(*(.ctors))
|
||||
KEEP(*(.ctors.*))
|
||||
} > p1ram
|
||||
|
||||
.text.p2ram ALIGN(4) : SUBALIGN(4)
|
||||
{
|
||||
*(.p2ram)
|
||||
*(.p2ram.*)
|
||||
} > p1ram
|
||||
|
||||
.bss ALIGN(4) (NOLOAD) : SUBALIGN(4)
|
||||
{
|
||||
*(.bss)
|
||||
*(.bss.*)
|
||||
*(COMMON)
|
||||
} > p1ram
|
||||
|
||||
INCLUDE "debug.lds"
|
||||
}
|
||||
|
||||
__p1ram_start = ORIGIN(p1ram);
|
||||
__p1ram_end = ORIGIN(p1ram) + LENGTH(p1ram);
|
||||
|
||||
__bss_link_start = ADDR(.bss);
|
||||
__bss_link_end = ADDR(.bss) + SIZEOF(.bss);
|
||||
|
||||
__ctors_link_start = ADDR(.ctors);
|
||||
__ctors_link_end = ADDR(.ctors) + SIZEOF(.ctors);
|
||||
|
||||
INCLUDE "addresses.lds"
|
@ -216,6 +216,8 @@ def render_registers(registers):
|
||||
yield from render_register(register)
|
||||
|
||||
def header():
|
||||
yield "#pragma once"
|
||||
yield ""
|
||||
yield "#include <cstdint>"
|
||||
yield ""
|
||||
yield '#include "../float_uint32.hpp"'
|
||||
|
@ -14,8 +14,8 @@ class CommandNamespace:
|
||||
|
||||
def command_namespace(namespace: CommandNamespace,
|
||||
data_fields: list[tuple[str, tuple[int, str]]]):
|
||||
yield f"namespace {namespace.name} {{"
|
||||
yield f"constexpr uint32_t command_code = {hex(namespace.command_code)};"
|
||||
yield f"struct {namespace.name} {{"
|
||||
yield f"static constexpr uint32_t command_code = {hex(namespace.command_code)};"
|
||||
yield ""
|
||||
|
||||
if namespace.data_size == (0, None):
|
||||
@ -57,7 +57,7 @@ def command_namespace(namespace: CommandNamespace,
|
||||
else:
|
||||
yield f"static_assert((sizeof (struct data_fields)) == {length});"
|
||||
|
||||
yield "}"
|
||||
yield "};"
|
||||
yield ""
|
||||
|
||||
def parse_data_size(data_size, base, multiple) -> tuple[int, str]:
|
||||
@ -155,6 +155,8 @@ def new_aggregator():
|
||||
return process
|
||||
|
||||
def headers():
|
||||
yield "#pragma once"
|
||||
yield ""
|
||||
yield "#include <cstdint>"
|
||||
yield ""
|
||||
yield "struct device_id {"
|
Binary file not shown.
@ -1,30 +0,0 @@
|
||||
"register_name","enum_name","bits","bit_name","value","mask","description"
|
||||
"host_instruction",,31,"end_flag",1,,
|
||||
,,,,,,
|
||||
"host_instruction","port_select","17-16","a",0,,
|
||||
"host_instruction","port_select","17-16","b",1,,
|
||||
"host_instruction","port_select","17-16","c",2,,
|
||||
"host_instruction","port_select","17-16","d",3,,
|
||||
,,,,,,
|
||||
"host_instruction","pattern","10-8","normal","0b000",,
|
||||
"host_instruction","pattern","10-8","light_gun_mode","0b010",,
|
||||
"host_instruction","pattern","10-8","reset","0b011",,
|
||||
"host_instruction","pattern","10-8","return_from_light_gun_mode","0b100",,
|
||||
"host_instruction","pattern","10-8","nop","0b111",,
|
||||
,,,,,,
|
||||
"host_instruction",,"7-0","transfer_length",,"0xff",
|
||||
,,,,,,
|
||||
"ap","port_select","7-6","a","0b00",,
|
||||
"ap","port_select","7-6","b","0b01",,
|
||||
"ap","port_select","7-6","c","0b10",,
|
||||
"ap","port_select","7-6","d","0b11",,
|
||||
,,,,,,
|
||||
"ap","de",5,"device",1,,
|
||||
"ap","de",5,"expansion_device",0,,
|
||||
"ap","de",5,"port",0,,
|
||||
,,,,,,
|
||||
"ap","lm_bus","4-0","_4","0b10000",,
|
||||
"ap","lm_bus","4-0","_3","0b01000",,
|
||||
"ap","lm_bus","4-0","_2","0b00100",,
|
||||
"ap","lm_bus","4-0","_1","0b00010",,
|
||||
"ap","lm_bus","4-0","_0","0b00001",,
|
|
Binary file not shown.
@ -6,23 +6,26 @@ from generate import renderer
|
||||
with open(sys.argv[1], 'r') as f:
|
||||
lines = f.read().split("\n")
|
||||
|
||||
@dataclass
|
||||
@dataclass(frozen=True)
|
||||
class Vertex:
|
||||
x: float
|
||||
y: float
|
||||
z: float
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class TextureCoordinate:
|
||||
u: float
|
||||
v: float
|
||||
|
||||
@dataclass
|
||||
class VertexNormal:
|
||||
class VertexTextureNormal:
|
||||
vertex: int
|
||||
texture: int
|
||||
normal: int
|
||||
|
||||
Face = tuple[VertexNormal, VertexNormal, VertexNormal]
|
||||
Face = tuple[VertexTextureNormal, VertexTextureNormal, VertexTextureNormal]
|
||||
|
||||
name = None
|
||||
vertices = []
|
||||
normals = []
|
||||
faces = []
|
||||
|
||||
def parse_object(line):
|
||||
h, name = line.split()
|
||||
@ -35,9 +38,15 @@ def parse_vertex(line):
|
||||
assert len(xyz) == 3
|
||||
return Vertex(*map(float, xyz))
|
||||
|
||||
def parse_texture_coordinate(line):
|
||||
h, *uv = line.split()
|
||||
assert h == 'vt'
|
||||
assert len(uv) == 2
|
||||
return TextureCoordinate(*map(float, uv))
|
||||
|
||||
def maybe_int(i, offset):
|
||||
if i.strip() == "":
|
||||
return None
|
||||
assert False
|
||||
else:
|
||||
return int(i) + offset
|
||||
|
||||
@ -52,7 +61,7 @@ def parse_face(line):
|
||||
maybe_int(iix, offset=-1)
|
||||
for iix in ix
|
||||
]
|
||||
return VertexNormal(vertex_ix, normal_ix)
|
||||
return VertexTextureNormal(vertex_ix, uv_ix, normal_ix)
|
||||
|
||||
return tuple(map(parse_ixs, tri))
|
||||
|
||||
@ -70,30 +79,25 @@ def generate_normals(normals):
|
||||
yield "};"
|
||||
yield ""
|
||||
|
||||
def generate_texture_coordinates(texture_coordinates):
|
||||
yield "constexpr vec2 texture[] = {"
|
||||
for t in texture_coordinates:
|
||||
yield f"{{ {t.u:9f}f, {t.v:9f}f }},"
|
||||
yield "};"
|
||||
yield ""
|
||||
|
||||
def generate_faces(faces):
|
||||
yield "constexpr face faces[] = {"
|
||||
for f in faces:
|
||||
inner = ", ".join(f"{{{vn.vertex:2}, {vn.normal:2}}}" for vn in f)
|
||||
inner = ", ".join(f"{{{vtn.vertex:3}, {vtn.texture:3}, {vtn.normal:3}}}" for vtn in f)
|
||||
yield f"{{{inner}}},"
|
||||
yield "};"
|
||||
yield ""
|
||||
yield "constexpr uint32_t num_faces = (sizeof (faces)) / (sizeof (face));"
|
||||
yield ""
|
||||
|
||||
for line in lines:
|
||||
if line.startswith('o '):
|
||||
assert name is None
|
||||
name = parse_object(line)
|
||||
elif line.startswith('v '):
|
||||
vertices.append(parse_vertex(line))
|
||||
elif line.startswith('vn '):
|
||||
normals.append(parse_vertex(line))
|
||||
elif line.startswith('f '):
|
||||
faces.append(parse_face(line))
|
||||
else:
|
||||
pass
|
||||
|
||||
def generate_namespace():
|
||||
def generate_namespace(vertices, texture_coordinates, normals, faces):
|
||||
global name
|
||||
assert name is not None
|
||||
yield "#pragma once"
|
||||
yield ""
|
||||
@ -102,11 +106,58 @@ def generate_namespace():
|
||||
yield f"namespace {name} {{"
|
||||
|
||||
yield from generate_vertices(vertices)
|
||||
yield from generate_texture_coordinates(texture_coordinates)
|
||||
yield from generate_normals(normals)
|
||||
yield from generate_faces(faces)
|
||||
|
||||
yield "}"
|
||||
|
||||
render, out = renderer()
|
||||
render(generate_namespace())
|
||||
sys.stdout.write(out.getvalue())
|
||||
def merge_texture_coordinates(texture_coordinates, faces):
|
||||
ix = 0
|
||||
_texture = dict()
|
||||
_faces = []
|
||||
for face in faces:
|
||||
for vtn in face:
|
||||
key = texture_coordinates[vtn.texture]
|
||||
if key not in _texture:
|
||||
_texture[key] = ix
|
||||
ix += 1
|
||||
_faces.append(tuple(
|
||||
VertexTextureNormal(vtn.vertex,
|
||||
_texture[texture_coordinates[vtn.texture]],
|
||||
vtn.normal)
|
||||
for vtn in face
|
||||
))
|
||||
return _texture, _faces
|
||||
|
||||
|
||||
def main():
|
||||
global name
|
||||
vertices = []
|
||||
texture_coordinates = []
|
||||
normals = []
|
||||
faces = []
|
||||
|
||||
for line in lines:
|
||||
if line.startswith('o '):
|
||||
assert name is None
|
||||
name = parse_object(line)
|
||||
elif line.startswith('v '):
|
||||
vertices.append(parse_vertex(line))
|
||||
elif line.startswith('vn '):
|
||||
normals.append(parse_vertex(line))
|
||||
elif line.startswith('vt '):
|
||||
texture_coordinates.append(parse_texture_coordinate(line))
|
||||
elif line.startswith('f '):
|
||||
faces.append(parse_face(line))
|
||||
else:
|
||||
pass
|
||||
|
||||
texture_coordinates, faces = merge_texture_coordinates(texture_coordinates, faces)
|
||||
|
||||
render, out = renderer()
|
||||
render(generate_namespace(vertices, texture_coordinates, normals, faces))
|
||||
sys.stdout.write(out.getvalue())
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
Loading…
x
Reference in New Issue
Block a user