diff --git a/Makefile b/Makefile index c736c7a..25f67c2 100644 --- a/Makefile +++ b/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) diff --git a/common.mk b/common.mk index 8bbee2b..afa9463 100644 --- a/common.mk +++ b/common.mk @@ -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 \ diff --git a/example/example.mk b/example/example.mk index d6108c0..d0583af 100644 --- a/example/example.mk +++ b/example/example.mk @@ -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 diff --git a/example/maple_analog.cpp b/example/maple_analog.cpp new file mode 100644 index 0000000..7f78a31 --- /dev/null +++ b/example/maple_analog.cpp @@ -0,0 +1,235 @@ +#include +#include + +#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; + + get_condition::data_fields data_fields = { + .function_type = std::byteswap(function_type::controller) + }; + + maple::init_host_command_all_ports(command_buf, receive_buf, + data_fields); + maple::dma_start(command_buf); + + using command_response_type = struct maple::command_response; + for (uint8_t port = 0; port < 4; port++) { + auto response = reinterpret_cast(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(port); + serial::string(" `a` press "); + serial::integer(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(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(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(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(data[0].analog_axis_3 - 0x80) * (0.5 / 127); + float y_pos = static_cast(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(); + 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; + } +} diff --git a/example/modifier_volume.cpp b/example/modifier_volume.cpp new file mode 100644 index 0000000..f541b2d --- /dev/null +++ b/example/modifier_volume.cpp @@ -0,0 +1,155 @@ +#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 "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(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(x, y, z, + strip_vertices[i].u, + strip_vertices[i].v, + strip_vertices[i].color, + end_of_strip); + } + + parameter.append() = global_end_of_list(); + + return parameter.offset; +} + +void init_texture_memory(const struct opb_size& opb_size) +{ + auto mem = reinterpret_cast(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(&_binary_macaw_data_start); + auto size = reinterpret_cast(&_binary_macaw_data_size); + auto mem = reinterpret_cast(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; + } +} diff --git a/geometry/border.hpp b/geometry/border.hpp new file mode 100644 index 0000000..5b4ce2c --- /dev/null +++ b/geometry/border.hpp @@ -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)); + +} diff --git a/geometry/border.obj b/geometry/border.obj new file mode 100644 index 0000000..213a27d --- /dev/null +++ b/geometry/border.obj @@ -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 diff --git a/geometry/circle.hpp b/geometry/circle.hpp new file mode 100644 index 0000000..dbe2dea --- /dev/null +++ b/geometry/circle.hpp @@ -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)); + +} diff --git a/geometry/circle.obj b/geometry/circle.obj new file mode 100644 index 0000000..a932d98 --- /dev/null +++ b/geometry/circle.obj @@ -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 diff --git a/geometry/cube.hpp b/geometry/cube.hpp index b480325..e69de29 100644 --- a/geometry/cube.hpp +++ b/geometry/cube.hpp @@ -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)); - -} diff --git a/geometry/cube.obj b/geometry/cube.obj index f8e3454..a827254 100644 --- a/geometry/cube.obj +++ b/geometry/cube.obj @@ -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 diff --git a/geometry/geometry.hpp b/geometry/geometry.hpp index a720c02..cf47830 100644 --- a/geometry/geometry.hpp +++ b/geometry/geometry.hpp @@ -2,14 +2,17 @@ #include +#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; }; diff --git a/geometry/plane.obj b/geometry/plane.obj new file mode 100644 index 0000000..6c70187 --- /dev/null +++ b/geometry/plane.obj @@ -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 diff --git a/maple/maple.cpp b/maple/maple.cpp index 69536f1..0fbb854 100644 --- a/maple/maple.cpp +++ b/maple/maple.cpp @@ -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)) + command_data_size); - const uint32_t response_size = align_32byte(((sizeof (struct command_response)) + 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) diff --git a/maple/maple.hpp b/maple/maple.hpp index c9e9850..dc2b8ea 100644 --- a/maple/maple.hpp +++ b/maple/maple.hpp @@ -2,6 +2,8 @@ #include +#include "align.hpp" + namespace maple { template @@ -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)) == align_32byte((sizeof (command_response)))); 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); diff --git a/maple/maple_bus_bits.hpp b/maple/maple_bus_bits.hpp index ce4e37d..20df07d 100644 --- a/maple/maple_bus_bits.hpp +++ b/maple/maple_bus_bits.hpp @@ -1,3 +1,5 @@ +#pragma once + #include #include "../float_uint32.hpp" diff --git a/maple/maple_bus_commands.hpp b/maple/maple_bus_commands.hpp index a229f80..856663a 100644 --- a/maple/maple_bus_commands.hpp +++ b/maple/maple_bus_commands.hpp @@ -1,3 +1,5 @@ +#pragma once + #include 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 struct data_fields { @@ -66,39 +73,40 @@ namespace device_all_status { }; static_assert((sizeof (struct data_fields)) == 112); -} +}; -namespace device_reply { - constexpr uint32_t command_code = 0x7; + +struct device_reply { + static constexpr uint32_t command_code = 0x7; struct data_fields { }; -} +}; + +template +struct data_transfer { + static constexpr uint32_t command_code = 0x8; -namespace data_transfer { - constexpr uint32_t command_code = 0x8; - - template struct data_fields { uint32_t function_type; T data; }; - - static_assert((sizeof (struct data_fields)) == 4); -} +}; +static_assert((sizeof (struct data_transfer::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 struct data_fields { @@ -134,10 +144,11 @@ namespace block_write { }; static_assert((sizeof (struct data_fields)) == 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 struct data_fields { @@ -159,10 +171,11 @@ namespace set_condition { }; static_assert((sizeof (struct data_fields)) == 4); -} +}; -namespace ft4_control { - constexpr uint32_t command_code = 0xf; + +struct ft4_control { + static constexpr uint32_t command_code = 0xf; template struct data_fields { @@ -171,10 +184,11 @@ namespace ft4_control { }; static_assert((sizeof (struct data_fields)) == 4); -} +}; -namespace ar_control { - constexpr uint32_t command_code = 0x10; + +struct ar_control { + static constexpr uint32_t command_code = 0x10; template struct data_fields { @@ -183,56 +197,63 @@ namespace ar_control { }; static_assert((sizeof (struct data_fields)) == 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); -} +}; + diff --git a/maple/maple_impl.hpp b/maple/maple_impl.hpp new file mode 100644 index 0000000..d777bce --- /dev/null +++ b/maple/maple_impl.hpp @@ -0,0 +1,46 @@ +#pragma once + +#include + +#include "maple/maple.hpp" +#include "maple/maple_bus_commands.hpp" +#include "maple/maple_bus_bits.hpp" + +namespace maple { + +template +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; + using response_type = maple::command_response; + + auto host_command = reinterpret_cast(command_buf); + auto response_command = reinterpret_cast(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; +} + +} diff --git a/math/vec2.hpp b/math/vec2.hpp new file mode 100644 index 0000000..1197ce2 --- /dev/null +++ b/math/vec2.hpp @@ -0,0 +1,147 @@ +#pragma once + +#include "math.hpp" +#include "vec.hpp" + +// +// vec3 +// + +template +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 +inline constexpr vec<2, T>::vec() + : x(0), y(0), z(0) +{} + +template +inline constexpr vec<2, T>::vec(T scalar) + : x(scalar), y(scalar), z(scalar) +{} + +template +inline constexpr vec<2, T>::vec(T _x, T _y) + : x(_x), y(_y) +{} + +template +constexpr inline vec<2, T> vec<2, T>::operator-() const +{ + return vec<2, T>(-x, -y); +} + +template +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 +inline constexpr vec<2, T>& vec<2, T>::operator=(vec<2, T> const& v) +{ + this->x = static_cast(v.x); + this->y = static_cast(v.y); + return *this; +} + +template +inline constexpr vec<2, T>& vec<2, T>::operator+=(vec<2, T> const& v) +{ + *this = *this + vec<2, T>(v); + return *this; +} + +template +inline constexpr vec<2, T>& vec<2, T>::operator-=(vec<2, T> const& v) +{ + *this = *this - vec<2, T>(v); + return *this; +} + +template +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 +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 +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 +inline constexpr vec<2, T> operator*(vec<2, T> const& v1, T const& scalar) +{ + return v1 * vec<2, T>(scalar); +} + +template +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 +inline constexpr vec<2, T> operator/(vec<2, T> const& v1, T const& scalar) +{ + return v1 / vec<2, T>(scalar); +} + +template +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 +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 +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 +inline constexpr T length(vec<2, T> const& v) +{ + return sqrt(dot(v, v)); +} diff --git a/math/vec3.hpp b/math/vec3.hpp index 7383cee..434d1c2 100644 --- a/math/vec3.hpp +++ b/math/vec3.hpp @@ -10,7 +10,10 @@ template 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); diff --git a/math/vec4.hpp b/math/vec4.hpp index 2ec8b45..4db56d7 100644 --- a/math/vec4.hpp +++ b/math/vec4.hpp @@ -10,7 +10,10 @@ template 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); diff --git a/qemu.lds b/qemu.lds new file mode 100644 index 0000000..1889748 --- /dev/null +++ b/qemu.lds @@ -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" diff --git a/regs/gen/core_bits.py b/regs/gen/core_bits.py index 5c2949b..f47db48 100644 --- a/regs/gen/core_bits.py +++ b/regs/gen/core_bits.py @@ -216,6 +216,8 @@ def render_registers(registers): yield from render_register(register) def header(): + yield "#pragma once" + yield "" yield "#include " yield "" yield '#include "../float_uint32.hpp"' diff --git a/regs/gen/maple_commands.py b/regs/gen/maple_bus_commands.py similarity index 96% rename from regs/gen/maple_commands.py rename to regs/gen/maple_bus_commands.py index 7b5330e..86ab98a 100644 --- a/regs/gen/maple_commands.py +++ b/regs/gen/maple_bus_commands.py @@ -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 " yield "" yield "struct device_id {" diff --git a/regs/maple_bus_bits.ods b/regs/maple_bus_bits.ods index 7c93f53..c856a5e 100644 Binary files a/regs/maple_bus_bits.ods and b/regs/maple_bus_bits.ods differ diff --git a/regs/maple_host_bits.csv b/regs/maple_host_bits.csv deleted file mode 100644 index febbbe6..0000000 --- a/regs/maple_host_bits.csv +++ /dev/null @@ -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",, diff --git a/regs/maple_host_bits.ods b/regs/maple_host_bits.ods deleted file mode 100644 index f06e279..0000000 Binary files a/regs/maple_host_bits.ods and /dev/null differ diff --git a/tools/obj_to_cpp.py b/tools/obj_to_cpp.py index 490122d..2cb67ab 100644 --- a/tools/obj_to_cpp.py +++ b/tools/obj_to_cpp.py @@ -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()