diff --git a/input.hpp b/input.hpp new file mode 100755 index 0000000..175ab10 --- /dev/null +++ b/input.hpp @@ -0,0 +1,26 @@ +#pragma once + +#include "maple/maple.hpp" +#include "maple/maple_bus_commands.hpp" +#include "maple/maple_bus_ft0.hpp" +#include "maple/maple_bus_ft9.hpp" + +namespace input { + +struct port_state { + uint32_t function_type; + uint32_t next_function_type; + maple::host_response::data_fields> * host_response_data_transfer_ft0; + maple::host_response::data_fields> * host_response_data_transfer_ft9; +}; + +struct input_state { + port_state port[4]; +}; + +extern input_state state; + +void state_update(uint8_t * send_buf, uint8_t * recv_buf); +void state_init(); + +} diff --git a/src/cursor.cpp b/src/cursor.cpp new file mode 100644 index 0000000..cfb0cf9 --- /dev/null +++ b/src/cursor.cpp @@ -0,0 +1,64 @@ +#include + +#include "maple/maple.hpp" +#include "maple/maple_host_command_writer.hpp" +#include "maple/maple_bus_bits.hpp" +#include "maple/maple_bus_commands.hpp" +#include "maple/maple_bus_ft0.hpp" +#include "maple/maple_bus_ft9.hpp" + +#include "sh7091/serial.hpp" + +#include "input.hpp" +#include "cursor.hpp" +#include "framebuffer.hpp" + +namespace cursor { + + struct cursor state[4]; + + void init() + { + for (int port_ix = 0; port_ix < 4; port_ix++) { + state[port_ix].x = framebuffer.px_width / 2; + state[port_ix].y = framebuffer.px_height / 2; + } + } + + void update() + { + for (int port_ix = 0; port_ix < 4; port_ix++) { + state[port_ix].active = false; + + auto& port = input::state.port[port_ix]; + if ((port.function_type & function_type::controller) != 0 && port.host_response_data_transfer_ft0 != nullptr) { + auto& bus_data = port.host_response_data_transfer_ft0->bus_data; + auto& data_fields = bus_data.data_fields; + if ((std::byteswap(data_fields.function_type) & function_type::controller) == 0) + continue; + + auto& data = data_fields.data; + + float dx = static_cast(data.analog_coordinate_axis[2] - 0x80) * 0.015; + float dy = static_cast(data.analog_coordinate_axis[3] - 0x80) * -0.015; + state[port_ix].x += dx; + state[port_ix].y += dy; + + state[port_ix].active = true; + } else if ((port.function_type & function_type::pointing) != 0 && port.host_response_data_transfer_ft9 != nullptr) { + auto& bus_data = port.host_response_data_transfer_ft9->bus_data; + auto& data_fields = bus_data.data_fields; + if ((std::byteswap(data_fields.function_type) & function_type::pointing) == 0) + continue; + auto& data = data_fields.data; + float dx = static_cast(data.analog_coordinate_axis[0] - 0x200) * 0.065; + float dy = static_cast(data.analog_coordinate_axis[1] - 0x200) * -0.065; + state[port_ix].x += dx; + state[port_ix].y += dy; + + state[port_ix].active = true; + } + } + } + +} diff --git a/src/cursor.hpp b/src/cursor.hpp new file mode 100644 index 0000000..cabe86a --- /dev/null +++ b/src/cursor.hpp @@ -0,0 +1,15 @@ +#pragma once + +namespace cursor { + + struct cursor { + bool active; + float x; + float y; + }; + + extern struct cursor state[4]; + + void init(); + void update(); +} diff --git a/src/framebuffer.cpp b/src/framebuffer.cpp index 6b9948a..68467ab 100644 --- a/src/framebuffer.cpp +++ b/src/framebuffer.cpp @@ -129,7 +129,7 @@ void core_param_init() { uint32_t region_array_start = texture_memory_alloc.region_array.start; uint32_t isp_tsp_parameters_start = texture_memory_alloc.isp_tsp_parameters.start; - uint32_t background_start = texture_memory_alloc.background[0].start; + uint32_t background_start = texture_memory_alloc.background[1].start; holly.REGION_BASE = region_array_start; holly.PARAM_BASE = isp_tsp_parameters_start; diff --git a/src/graphics.cpp b/src/graphics.cpp index d3e61cb..bfc35fb 100644 --- a/src/graphics.cpp +++ b/src/graphics.cpp @@ -23,6 +23,9 @@ #include "graphics.hpp" #include "texture.hpp" #include "scene/scene.hpp" +#include "ta_multiwriter.hpp" +#include "cursor.hpp" +#include "ta_parameter.hpp" static volatile int ta_in_use = 0; static volatile int core_in_use = 0; @@ -30,6 +33,9 @@ static volatile int next_frame = 0; static volatile int framebuffer_ix = 0; static volatile int next_frame_ix = 0; +static void * op_buf = nullptr; +static int op_offset = 0; + void graphics_interrupt(uint32_t istnrm) { if (istnrm & istnrm::v_blank_in) { @@ -51,13 +57,23 @@ void graphics_interrupt(uint32_t istnrm) core_in_use = 0; } + if (istnrm & istnrm::end_of_transferring_punch_through_list) { + system.ISTNRM = istnrm::end_of_transferring_punch_through_list; + + assert(op_buf != nullptr); + assert(op_offset > 0); + + ta_polygon_converter_writeback(op_buf, op_offset); + ta_polygon_converter_transfer(op_buf, op_offset); + } + if (istnrm & istnrm::end_of_transferring_opaque_list) { system.ISTNRM = istnrm::end_of_transferring_opaque_list; core_in_use = 1; core_start_render2(texture_memory_alloc.region_array.start, texture_memory_alloc.isp_tsp_parameters.start, - texture_memory_alloc.background[0].start, + texture_memory_alloc.background[1].start, texture_memory_alloc.framebuffer[framebuffer_ix].start, framebuffer.px_width); @@ -87,7 +103,7 @@ void graphics_init() spg_set_mode_640x480(); framebuffer_init(); - background_parameter2(texture_memory_alloc.background[0].start, + background_parameter2(texture_memory_alloc.background[1].start, 0xff800080); texture::transfer_texture_memory(); @@ -104,11 +120,29 @@ void graphics_scene_init(const opb_size * opb_size) texture_memory_alloc.object_list.start); } -void graphics_event(ta_parameter_writer& writer) +void graphics_cursor(ta_multiwriter& multi) { - writer.offset = 0; + global_polygon_untextured(multi.op, + para_control::list_type::opaque, + tsp_instruction_word::dst_alpha_instr::zero); - scene::current_scene->transfer(writer); + const cursor::cursor& c = cursor::state[0]; + + quad_type_0(multi.op, + {c.x - 1, c.y - 1, 10}, + {c.x + 1, c.y - 1, 10}, + {c.x + 1, c.y + 1, 10}, + {c.x - 1, c.y + 1, 10}, + 0xffffff); +} + +void graphics_event(ta_multiwriter& multi) +{ + multi.op.offset = 0; + multi.pt.offset = 0; + + graphics_cursor(multi); + scene::current_scene->transfer(multi); while (ta_in_use); while (core_in_use); @@ -121,8 +155,30 @@ void graphics_event(ta_parameter_writer& writer) scene::current_scene->ta_alloc, framebuffer.tile_width(), framebuffer.tile_height()); - ta_polygon_converter_writeback(writer.buf, writer.offset); - ta_polygon_converter_transfer(writer.buf, writer.offset); + + if (multi.op.offset != 0) { + multi.op.append() = + ta_global_parameter::end_of_list(para_control::para_type::end_of_list); + } + + if (multi.pt.offset != 0) { + multi.pt.append() = + ta_global_parameter::end_of_list(para_control::para_type::end_of_list); + } + + if (multi.pt.offset != 0) { + op_buf = multi.op.buf; + op_offset = multi.op.offset; + + ta_polygon_converter_writeback(multi.pt.buf, multi.pt.offset); + ta_polygon_converter_transfer(multi.pt.buf, multi.pt.offset); + } else { + op_buf = nullptr; + op_offset = 0; + + ta_polygon_converter_writeback(multi.op.buf, multi.op.offset); + ta_polygon_converter_transfer(multi.op.buf, multi.op.offset); + } while (next_frame == 0); next_frame = 0; diff --git a/src/graphics.hpp b/src/graphics.hpp index f010265..12cec05 100644 --- a/src/graphics.hpp +++ b/src/graphics.hpp @@ -2,12 +2,12 @@ #include -#include "holly/ta_parameter.hpp" #include "holly/region_array.hpp" +#include "ta_multiwriter.hpp" constexpr int ta_cont_count = 1; void graphics_interrupt(uint32_t istnrm); void graphics_init(); -void graphics_event(ta_parameter_writer& writer); +void graphics_event(ta_multiwriter& multi); void graphics_scene_init(const opb_size * opb_size); diff --git a/src/graphics_primitive.cpp b/src/graphics_primitive.cpp index 61a64d6..dce5b64 100644 --- a/src/graphics_primitive.cpp +++ b/src/graphics_primitive.cpp @@ -2,17 +2,18 @@ #include "ta_parameter.hpp" #include "graphics_primitive.hpp" +#include "texture.hpp" struct vertex { - vec3 p; + vec2 p; vec2 t; }; const vertex quad_vertices[] = { - { { 0, 0, 0.001f }, {0, 0} }, - { { 1, 0, 0.001f }, {1, 0} }, - { { 1, 1, 0.001f }, {1, 1} }, - { { 0, 1, 0.001f }, {0, 1} }, + { { 0, 0 }, {0, 0} }, + { { 1, 0 }, {1, 0} }, + { { 1, 1 }, {1, 1} }, + { { 0, 1 }, {0, 1} }, }; static inline vec2 transform_glyph_texture(const vec2& t, int char_code) @@ -26,22 +27,35 @@ static inline vec2 transform_glyph_texture(const vec2& t, int char_code) }; } -static inline vec3 transform_glyph_position(const vec3& p, float x, float y) +static inline vec3 transform_glyph_position(const vec2& p, float x, float y, float z) { return { p.x * glyph::width + x, p.y * glyph::height + y, - p.z + z }; } -void transfer_glyph(ta_parameter_writer& writer, int c, int x, int y, +void transfer_global_polygon_glyph(ta_parameter_writer& writer) +{ + uint32_t texture_size = tsp_instruction_word::texture_u_size::from_int(128) + | tsp_instruction_word::texture_v_size::from_int(256) + | tsp_instruction_word::dst_alpha_instr::one; + + global_polygon_textured(writer, + para_control::list_type::punch_through, + texture::offset::tandy1k, + texture_size, + texture_control_word::pixel_format::_4bpp_palette); +} + +void transfer_glyph(ta_parameter_writer& writer, int c, float x, float y, float z, int base_color) { - vec3 ap = transform_glyph_position(quad_vertices[0].p, x, y); - vec3 bp = transform_glyph_position(quad_vertices[1].p, x, y); - vec3 cp = transform_glyph_position(quad_vertices[2].p, x, y); - vec3 dp = transform_glyph_position(quad_vertices[3].p, x, y); + vec3 ap = transform_glyph_position(quad_vertices[0].p, x, y, z); + vec3 bp = transform_glyph_position(quad_vertices[1].p, x, y, z); + vec3 cp = transform_glyph_position(quad_vertices[2].p, x, y, z); + vec3 dp = transform_glyph_position(quad_vertices[3].p, x, y, z); vec2 at = transform_glyph_texture(quad_vertices[0].t, c); vec2 bt = transform_glyph_texture(quad_vertices[1].t, c); @@ -56,20 +70,22 @@ void transfer_glyph(ta_parameter_writer& writer, int c, int x, int y, base_color); } -int transfer_string(ta_parameter_writer& writer, const char * s, int x, int y, +int transfer_string(ta_parameter_writer& writer, const char * s, + float x, float y, float z, int base_color) { const uint8_t * u8 = (const uint8_t *)s; int len = 0; while (*u8) { len += 1; - transfer_glyph(writer, *u8++, x, y, base_color); + transfer_glyph(writer, *u8++, x, y, z, base_color); x += glyph::hori_advance; } return len; } -int transfer_integer(ta_parameter_writer& writer, int n, int x, int y, +int transfer_integer(ta_parameter_writer& writer, int n, + float x, float y, float z, int length, int fill, int base_color) { @@ -78,12 +94,13 @@ int transfer_integer(ta_parameter_writer& writer, int n, int x, int y, int len = unparse_base10(buf, n, length, fill); buf[len] = 0; - transfer_string(writer, buf, x, y, base_color); + transfer_string(writer, buf, x, y, z, base_color); return len; } -int transfer_hex_integer(ta_parameter_writer& writer, int n, int x, int y, +int transfer_hex_integer(ta_parameter_writer& writer, int n, + float x, float y, float z, int length, int fill, int base_color) { @@ -92,7 +109,7 @@ int transfer_hex_integer(ta_parameter_writer& writer, int n, int x, int y, int len = unparse_base16(buf, n, length, fill); buf[len] = 0; - transfer_string(writer, buf, x, y, base_color); + transfer_string(writer, buf, x, y, z, base_color); return len; } diff --git a/src/graphics_primitive.hpp b/src/graphics_primitive.hpp index 27f90fa..498ab5a 100644 --- a/src/graphics_primitive.hpp +++ b/src/graphics_primitive.hpp @@ -15,16 +15,26 @@ namespace glyph { const int interpunct = 0xb7; }; -void transfer_glyph(ta_parameter_writer& writer, int c, int x, int y, +void transfer_global_polygon_glyph(ta_parameter_writer& writer); + +void transfer_glyph(ta_parameter_writer& writer, int c, + float x, float y, float z, int base_color); -int transfer_string(ta_parameter_writer& writer, const char * s, int x, int y, +int transfer_string(ta_parameter_writer& writer, const char * s, + float x, float y, float z, int base_color); -int transfer_integer(ta_parameter_writer& writer, int n, int x, int y, +int transfer_integer(ta_parameter_writer& writer, int n, + float x, float y, float z, int length, int fill, int base_color); +int transfer_hex_integer(ta_parameter_writer& writer, int n, + float x, float y, float z, + int length, int fill, + int base_color); + int transfer_hex_integer(ta_parameter_writer& writer, int n, int x, int y, int length, int fill, int base_color); diff --git a/src/input.cpp b/src/input.cpp new file mode 100644 index 0000000..270d9e7 --- /dev/null +++ b/src/input.cpp @@ -0,0 +1,113 @@ +#include + +#include "maple/maple.hpp" +#include "maple/maple_port.hpp" +#include "maple/maple_bus_bits.hpp" +#include "maple/maple_bus_commands.hpp" +#include "maple/maple_bus_ft0.hpp" +#include "maple/maple_bus_ft9.hpp" +#include "maple/maple_host_command_writer.hpp" + +#include "sh7091/serial.hpp" + +#include "input.hpp" + +namespace input { + +struct input_state state; + +template +static inline void do_get_condition_controller(maple::host_command_writer& writer, + const uint32_t port) +{ + using command_type = maple::get_condition; + using response_type = maple::data_transfer; + + uint32_t host_port_select = host_instruction_port_select(port); + uint32_t destination_ap = ap_port_select(port) | ap::de::device; + + auto [host_command, host_response] + = writer.template append_command(host_port_select, + destination_ap, + false); // end_flag + + host_command->bus_data.data_fields.function_type = std::byteswap(function_type::controller); + + state.port[port].host_response_data_transfer_ft0 = host_response; +} + +template +static inline void do_get_condition_pointing(maple::host_command_writer& writer, + const uint32_t port) +{ + using command_type = maple::get_condition; + using response_type = maple::data_transfer; + + uint32_t host_port_select = host_instruction_port_select(port); + uint32_t destination_ap = ap_port_select(port) | ap::de::device; + + auto [host_command, host_response] + = writer.template append_command(host_port_select, + destination_ap, + false); // end_flag + + host_command->bus_data.data_fields.function_type = std::byteswap(function_type::pointing); + + state.port[port].host_response_data_transfer_ft9 = host_response; +} + +template +static inline maple::host_response * do_device_request(maple::host_command_writer& writer) +{ + using command_type = maple::device_request; + using response_type = maple::device_status; + + auto [host_command, host_response] + = writer.template append_command_all_ports(); + + return host_response; +} + +void state_update(uint8_t * send_buf, uint8_t * recv_buf) +{ + maple::host_command_writer writer(send_buf, recv_buf); + + for (uint8_t port_ix = 0; port_ix < 4; port_ix++) { + state.port[port_ix].function_type = state.port[port_ix].next_function_type; + + if (state.port[port_ix].function_type & function_type::controller) { + do_get_condition_controller(writer, port_ix); + } + + if (state.port[port_ix].function_type & function_type::pointing) { + do_get_condition_pointing(writer, port_ix); + } + } + + auto host_response_device_status = do_device_request(writer); + + // what?? + maple::dma_start(writer.send_buf, writer.send_offset, + writer.recv_buf, writer.recv_offset); + maple::dma_wait_complete(); + + for (uint8_t port_ix = 0; port_ix < 4; port_ix++) { + auto& bus_data = host_response_device_status[port_ix].bus_data; + auto& data_fields = bus_data.data_fields; + if (bus_data.command_code != maple::device_status::command_code) { + state.port[port_ix].function_type = 0; + state.port[port_ix].next_function_type = 0; + } else { + state.port[port_ix].next_function_type = std::byteswap(data_fields.device_id.ft); + } + } +} + +void state_init() +{ + for (uint8_t port = 0; port < 4; port++) { + state.port[port].function_type = 0; + } +} + +} diff --git a/src/main.cpp b/src/main.cpp index bd9235c..1f1cc39 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,11 +1,3 @@ -#include - -#include "maple/maple.hpp" -#include "maple/maple_host_command_writer.hpp" -#include "maple/maple_bus_bits.hpp" -#include "maple/maple_bus_commands.hpp" -#include "maple/maple_bus_ft0.hpp" - #include "aica/aica.hpp" #include "interrupt.hpp" @@ -14,6 +6,8 @@ #include "sound.hpp" #include "scene/scene.hpp" #include "scene/logo/sound.hpp" +#include "cursor.hpp" +#include "input.hpp" #include "xm/milkypack01.xm.h" #include "xm.h" @@ -54,7 +48,7 @@ void vbr600() | aica::tactl_tima::TIMA(0xffff) // interrupt after 1 counts ; - scene::logo::sound::interrupt(); + //scene::logo::sound::interrupt(); //interpreter::interrupt(); } else { serial::string("vbr600\n"); @@ -65,53 +59,7 @@ void vbr600() asm volatile ("ldc %0,sr" : : "r" (sr)); } -static ft0::data_transfer::data_format data[4]; - -uint8_t send_buf[1024] __attribute__((aligned(32))); -uint8_t recv_buf[1024] __attribute__((aligned(32))); - -void do_get_condition() -{ - auto writer = maple::host_command_writer(send_buf, recv_buf); - - using command_type = maple::get_condition; - using response_type = maple::data_transfer; - - auto [host_command, host_response] - = writer.append_command_all_ports(); - - { - using command_type = maple::device_request; - using response_type = maple::device_status; - - writer.append_command_all_ports(); - } - - for (int port = 0; port < 4; port++) { - auto& data_fields = host_command[port].bus_data.data_fields; - data_fields.function_type = std::byteswap(function_type::controller); - } - maple::dma_start(send_buf, writer.send_offset, - recv_buf, writer.recv_offset); - - for (uint8_t port = 0; port < 4; port++) { - auto& bus_data = host_response[port].bus_data; - if (bus_data.command_code != response_type::command_code) { - return; - } - auto& data_fields = bus_data.data_fields; - if ((std::byteswap(data_fields.function_type) & function_type::controller) == 0) { - return; - } - - data[port].digital_button = data_fields.data.digital_button; - for (int i = 0; i < 6; i++) { - data[port].analog_coordinate_axis[i] - = data_fields.data.analog_coordinate_axis[i]; - } - } -} - +/* void input_update() { int ra = ft0::data_transfer::digital_button::ra(data[0].digital_button) == 0; @@ -134,7 +82,6 @@ void input_update() static int last_a = 0; static int last_b = 0; - /* if (ra && ra != last_ra) { sandbox_state.channel_ix += 1; if (sandbox_state.channel_ix > 63) @@ -168,7 +115,6 @@ void input_update() if (b && b != last_b) { label_update(1); } - */ last_ra = ra; last_la = la; @@ -180,6 +126,7 @@ void input_update() last_a = a; last_b = b; } +*/ void load_xm(float clock_multiplier) { @@ -231,13 +178,18 @@ void test_pattern() void main() { + printf("main\n"); serial::init(0); + printf("main\n"); sound::init(); graphics_init(); scene::scene_init(); - //const float aica_clock_multiplier = 44.1; - //load_xm(aica_clock_multiplier); + input::state_init(); + cursor::init(); + + const float aica_clock_multiplier = 44.1; + load_xm(aica_clock_multiplier); //test_pattern(); @@ -250,15 +202,19 @@ void main() system.IML4EXT = istext::aica; - static uint8_t __attribute__((aligned(32))) ta_parameter_buf[1024 * 1024 * 1]; - ta_parameter_writer writer = ta_parameter_writer(ta_parameter_buf, (sizeof (ta_parameter_buf))); + static uint8_t op_buf[1024 * 1024 / 2] __attribute__((aligned(32))); + static uint8_t pt_buf[1024 * 1024 / 2] __attribute__((aligned(32))); + ta_multiwriter multi(ta_parameter_writer(op_buf, (sizeof (op_buf))), + ta_parameter_writer(pt_buf, (sizeof (pt_buf)))); - do_get_condition(); + static uint8_t send_buf[1024] __attribute__((aligned(32))); + static uint8_t recv_buf[1024] __attribute__((aligned(32))); + + input::state_update(send_buf, recv_buf); while (1) { - maple::dma_wait_complete(); - do_get_condition(); - input_update(); + cursor::update(); + input::state_update(send_buf, recv_buf); - graphics_event(writer); + graphics_event(multi); } } diff --git a/src/scene/logo/scene.cpp b/src/scene/logo/scene.cpp index fe69b99..c5a9bc8 100644 --- a/src/scene/logo/scene.cpp +++ b/src/scene/logo/scene.cpp @@ -187,7 +187,7 @@ namespace scene::logo { }; } - void transfer(ta_parameter_writer& writer) + void transfer(ta_multiwriter& multi) { vec3 t = {framebuffer.px_width / 2.f, framebuffer.px_height / 2.f, 0}; float s = framebuffer.px_height / 3.f; @@ -215,15 +215,12 @@ namespace scene::logo { * rotate_y(k.ry) * scale((vec3){-1, -1, 1}); - render_mesh(writer, mesh_thirty_two, trans, k.i, tick < (9.85 * 60)); + render_mesh(multi.op, mesh_thirty_two, trans, k.i, tick < (9.85 * 60)); if (keyframe_ix > 0) { - render_mesh(writer, mesh_bit, trans, k.i, tick < (10.85 * 60)); - render_mesh(writer, mesh_jam, trans, k.i, tick < (11.85 * 60)); + render_mesh(multi.op, mesh_bit, trans, k.i, tick < (10.85 * 60)); + render_mesh(multi.op, mesh_jam, trans, k.i, tick < (11.85 * 60)); } - writer.append() = - ta_global_parameter::end_of_list(para_control::para_type::end_of_list); - tick += 1; } diff --git a/src/scene/logo/scene.hpp b/src/scene/logo/scene.hpp index 30cc52e..6b2d2d9 100644 --- a/src/scene/logo/scene.hpp +++ b/src/scene/logo/scene.hpp @@ -2,10 +2,11 @@ #include "holly/ta_bits.hpp" #include "scene/scene.hpp" +#include "ta_multiwriter.hpp" namespace scene::logo { - void transfer(ta_parameter_writer& writer); + void transfer(ta_multiwriter& multi); void init(); diff --git a/src/scene/scene.cpp b/src/scene/scene.cpp index 09f40c3..12f3b06 100644 --- a/src/scene/scene.cpp +++ b/src/scene/scene.cpp @@ -10,13 +10,16 @@ static const scene::scene scenes[] = { }; namespace scene { - const scene * current_scene = &scenes[1]; + const scene * current_scene = &scenes[0]; void scene_init() { graphics_scene_init(¤t_scene->opb_size); + printf("scene init\n"); - if (current_scene->init != nullptr) + if (current_scene->init != nullptr) { + printf("current_scene init\n"); current_scene->init(); + } } } diff --git a/src/scene/scene.hpp b/src/scene/scene.hpp index a1aa3ac..c265b71 100644 --- a/src/scene/scene.hpp +++ b/src/scene/scene.hpp @@ -1,14 +1,14 @@ #pragma once -#include "holly/ta_parameter.hpp" #include "holly/region_array.hpp" +#include "ta_multiwriter.hpp" namespace scene { struct scene { const uint32_t ta_alloc; const struct opb_size opb_size; - void (* const transfer)(ta_parameter_writer& writer); + void (* const transfer)(ta_multiwriter& multi); void (* const init)(); }; diff --git a/src/scene/tracker/channel_status.cpp b/src/scene/tracker/channel_status.cpp index 22cb35f..b81fa87 100644 --- a/src/scene/tracker/channel_status.cpp +++ b/src/scene/tracker/channel_status.cpp @@ -81,7 +81,8 @@ void transfer(ta_parameter_writer& writer, int x, int y) texture_control_word::pixel_format::_4bpp_palette); int hori_center = inner_width / 2 - (glyph::hori_advance * (ch >= 10)) / 2; - transfer_integer(writer, ch, xi + hori_center, y + vert_center, + transfer_integer(writer, ch, + xi + hori_center, y + vert_center, 0.0001f, 0, 0, 0xa7a7a7); } diff --git a/src/scene/tracker/notes.cpp b/src/scene/tracker/notes.cpp index ca446cb..b5f6126 100644 --- a/src/scene/tracker/notes.cpp +++ b/src/scene/tracker/notes.cpp @@ -11,6 +11,8 @@ const int line_rows_half = 15; const int line_rows = line_rows_half * 2 + 1; const int line_column_height = line_rows * glyph::vert_advance + 3 + 1; +const int depth = 0.0001f; + static inline int transfer_line_index(ta_parameter_writer& writer, int line_index, int x, int y) { const int dark = 0x5d646b; @@ -18,7 +20,7 @@ static inline int transfer_line_index(ta_parameter_writer& writer, int line_inde int base_color = ((line_index % 4) == 0) ? dark : light; - int len = transfer_integer(writer, line_index, x, y, 2, ' ', base_color); + int len = transfer_integer(writer, line_index, x, y, depth, 2, ' ', base_color); x += glyph::hori_advance * len; return x; @@ -28,7 +30,7 @@ static inline int transfer_fill(ta_parameter_writer& writer, int count, int x, i int base_color) { for (int i = 0; i < count; i++) { - transfer_glyph(writer, glyph::interpunct, x, y, base_color); + transfer_glyph(writer, glyph::interpunct, x, y, depth, base_color); x += glyph::hori_advance; } return x; @@ -56,21 +58,21 @@ static inline int transfer_note(ta_parameter_writer& writer, int note, int x, in int base_color = 0xffffff; if (note == 97) { - transfer_glyph(writer, glyph::horizontal_bar, x, y, base_color); + transfer_glyph(writer, glyph::horizontal_bar, x, y, depth, base_color); x += glyph::hori_advance; - transfer_glyph(writer, glyph::horizontal_bar, x, y, base_color); + transfer_glyph(writer, glyph::horizontal_bar, x, y, depth, base_color); x += glyph::hori_advance; - transfer_glyph(writer, glyph::horizontal_bar, x, y, base_color); + transfer_glyph(writer, glyph::horizontal_bar, x, y, depth, base_color); x += glyph::hori_advance; } else if (note != 0) { int c0_note = note - 1; const char * note_name = note_names[c0_note % 12]; int octave = c0_note / 12; - transfer_glyph(writer, note_name[0], x, y, base_color); + transfer_glyph(writer, note_name[0], x, y, depth, base_color); x += glyph::hori_advance; - transfer_glyph(writer, note_name[1], x, y, base_color); + transfer_glyph(writer, note_name[1], x, y, depth, base_color); x += glyph::hori_advance; - transfer_glyph(writer, '0' + octave, x, y, base_color); + transfer_glyph(writer, '0' + octave, x, y, depth, base_color); x += glyph::hori_advance; } else { x = transfer_fill(writer, 3, x, y, base_color); @@ -119,7 +121,7 @@ static inline int transfer_effect_type(ta_parameter_writer& writer, int effect_t if (effect_type != 0) { int c = effect_type_char(effect_type); - transfer_glyph(writer, c, x, y, base_color); + transfer_glyph(writer, c, x, y, depth, base_color); x += glyph::hori_advance; } else { x = transfer_fill(writer, 1, x, y, base_color); diff --git a/src/scene/tracker/scene.cpp b/src/scene/tracker/scene.cpp index fca7b3e..0de4b23 100644 --- a/src/scene/tracker/scene.cpp +++ b/src/scene/tracker/scene.cpp @@ -7,6 +7,7 @@ #include "notes.hpp" #include "channel_status.hpp" #include "texture.hpp" +#include "widget/button.hpp" namespace scene::tracker { @@ -26,7 +27,7 @@ namespace scene::tracker { .transfer = transfer, }; - void transfer(ta_parameter_writer& writer) + void transfer(ta_multiwriter& multi) { const int x = 3; const int y = 100; @@ -35,18 +36,18 @@ namespace scene::tracker { uint32_t texture_size = tsp_instruction_word::texture_u_size::from_int(128) | tsp_instruction_word::texture_v_size::from_int(256); - global_polygon_textured(writer, + /* + global_polygon_textured(multi.pt, para_control::list_type::punch_through, texture::offset::tandy1k, texture_size, texture_control_word::pixel_format::_4bpp_palette); + */ - tracker::notes::transfer_lines(writer, x, y); - - writer.append() = - ta_global_parameter::end_of_list(para_control::para_type::end_of_list); + //tracker::notes::transfer_lines(multi.pt, x, y); } + /* { // translucent global_polygon_untextured(writer, para_control::list_type::translucent, @@ -57,18 +58,18 @@ namespace scene::tracker { writer.append() = ta_global_parameter::end_of_list(para_control::para_type::end_of_list); } + */ { // opaque - global_polygon_untextured(writer, + global_polygon_untextured(multi.op, para_control::list_type::opaque, tsp_instruction_word::dst_alpha_instr::zero); - tracker::notes::borders(writer, x, y); + //tracker::notes::borders(multi.op, x, y); - tracker::channel_status::transfer(writer, 0, 0); + //tracker::channel_status::transfer(multi.op, 0, 0); - writer.append() = - ta_global_parameter::end_of_list(para_control::para_type::end_of_list); + widget::button(60, 60, 50, 50, "test").draw(multi); } } } diff --git a/src/scene/tracker/scene.hpp b/src/scene/tracker/scene.hpp index ace7aac..8d80b3f 100644 --- a/src/scene/tracker/scene.hpp +++ b/src/scene/tracker/scene.hpp @@ -2,10 +2,11 @@ #include "holly/ta_bits.hpp" #include "scene/scene.hpp" +#include "ta_multiwriter.hpp" namespace scene::tracker { - void transfer(ta_parameter_writer& writer); + void transfer(ta_multiwriter& multi); extern const struct scene::scene scene; } diff --git a/src/ta_multiwriter.hpp b/src/ta_multiwriter.hpp new file mode 100644 index 0000000..ed71542 --- /dev/null +++ b/src/ta_multiwriter.hpp @@ -0,0 +1,8 @@ +#pragma once + +#include "holly/ta_parameter.hpp" + +struct ta_multiwriter { + ta_parameter_writer op; + ta_parameter_writer pt; +}; diff --git a/src/ta_parameter.hpp b/src/ta_parameter.hpp index 4dcac94..1de580a 100644 --- a/src/ta_parameter.hpp +++ b/src/ta_parameter.hpp @@ -27,7 +27,6 @@ static inline void global_polygon_textured(ta_parameter_writer& writer, const uint32_t tsp_instruction_word = tsp_instruction_word::texture_shading_instruction::modulate | tsp_instruction_word::src_alpha_instr::one - | tsp_instruction_word::dst_alpha_instr::zero | tsp_instruction_word::fog_control::no_fog | texture_size; diff --git a/src/widget/bounding_box.hpp b/src/widget/bounding_box.hpp new file mode 100644 index 0000000..4c1b901 --- /dev/null +++ b/src/widget/bounding_box.hpp @@ -0,0 +1,12 @@ +#pragma once + +namespace widget { + + struct bounding_box { + const float x; + const float y; + const float width; + const float height; + }; + +} diff --git a/src/widget/button.cpp b/src/widget/button.cpp new file mode 100644 index 0000000..d7a07b8 --- /dev/null +++ b/src/widget/button.cpp @@ -0,0 +1,119 @@ +#include "widget/button.hpp" + +#include "ta_parameter.hpp" +#include "graphics_primitive.hpp" + +namespace widget { + + const static float shadow_depth = 1.0 / 10.0; + const static int shadow_color = 0x0000000; + + const static float lowlight_depth = 1.0 / 9.0; + const static int lowlight_color = 0x0c0d0d; + + const static float highlight_depth = 1.0 / 8.0; + const static int highlight_color = 0x353a3a; + + const static float background_depth = 1.0 / 7.0; + const static int background_color = 0x282c2c; + + const static float label_depth = 1.0 / 6.0; + const static int label_color = 0xffffff; + + void button::draw_shadow(ta_parameter_writer& writer) + { + { + float x0 = x + 1; + float x1 = x + width - 1; + float y0 = y; + float y1 = y + height; + quad_type_0(writer, + {x0, y0, shadow_depth}, + {x1, y0, shadow_depth}, + {x1, y1, shadow_depth}, + {x0, y1, shadow_depth}, + shadow_color); + } + { + float x0 = x; + float x1 = x + width; + float y0 = y + 1; + float y1 = y + height - 1; + quad_type_0(writer, + {x0, y0, shadow_depth}, + {x1, y0, shadow_depth}, + {x1, y1, shadow_depth}, + {x0, y1, shadow_depth}, + shadow_color); + } + } + + void button::draw_lowlight(ta_parameter_writer& writer) + { + float x0 = x + 1; + float x1 = x + width - 1; + float y0 = y + 1; + float y1 = y + height - 1; + quad_type_0(writer, + {x0, y0, lowlight_depth}, + {x1, y0, lowlight_depth}, + {x1, y1, lowlight_depth}, + {x0, y1, lowlight_depth}, + lowlight_color); + } + + void button::draw_highlight(ta_parameter_writer& writer) + { + float x0 = x + 1; + float x1 = x + width - 2; + float y0 = y + 1; + float y1 = y + height - 2; + quad_type_0(writer, + {x0, y0, highlight_depth}, + {x1, y0, highlight_depth}, + {x1, y1, highlight_depth}, + {x0, y1, highlight_depth}, + highlight_color); + } + + void button::draw_background(ta_parameter_writer& writer) + { + float x0 = x + 2; + float x1 = x + width - 2; + float y0 = y + 2; + float y1 = y + height - 2; + quad_type_0(writer, + {x0, y0, background_depth}, + {x1, y0, background_depth}, + {x1, y1, background_depth}, + {x0, y1, background_depth}, + background_color); + } + + void button::draw_label(ta_parameter_writer& writer) + { + float cx = x + width / 2 - (glyph::hori_advance * label_length) / 2; + float cy = y + height / 2 - glyph::vert_advance / 2; + + transfer_string(writer, label, cx, cy, label_depth, label_color); + } + + void button::draw(ta_multiwriter& multi) + { + global_polygon_untextured(multi.op, + para_control::list_type::opaque, + tsp_instruction_word::dst_alpha_instr::zero); + + draw_shadow(multi.op); + + draw_lowlight(multi.op); + + draw_highlight(multi.op); + + draw_background(multi.op); + + transfer_global_polygon_glyph(multi.pt); + + draw_label(multi.pt); + } +} diff --git a/src/widget/button.hpp b/src/widget/button.hpp new file mode 100644 index 0000000..7c1e39d --- /dev/null +++ b/src/widget/button.hpp @@ -0,0 +1,34 @@ +#pragma once + +#include "holly/ta_parameter.hpp" +#include "ta_multiwriter.hpp" +#include "widget/bounding_box.hpp" + +namespace widget { + + constexpr inline int str_length(const char * s) + { + int l = 0; + while (*s++) { + l += 1; + } + return l; + } + + struct button : bounding_box { + const char * const label; + const int label_length; + + button(float _x, float _y, float _width, float _height, const char * _label) + : bounding_box(_x, _y, _width, _height), label(_label), label_length(str_length(_label)) + { + } + + void draw_shadow(ta_parameter_writer& writer); + void draw_lowlight(ta_parameter_writer& writer); + void draw_highlight(ta_parameter_writer& writer); + void draw_background(ta_parameter_writer& writer); + void draw_label(ta_parameter_writer& writer); + void draw(ta_multiwriter& multi); + }; +} diff --git a/xm_player.mk b/xm_player.mk index 7b72a34..5a2dabd 100644 --- a/xm_player.mk +++ b/xm_player.mk @@ -20,21 +20,24 @@ XM_PLAYER_OBJ = \ $(LIB)/printf/printf.o \ $(LIB)/printf/unparse.o \ $(LIB)/printf/parse.o \ + src/cursor.o \ + src/framebuffer.o \ src/graphics.o \ + src/graphics_primitive.o \ + src/input.o \ src/interpreter.o \ src/main.o \ - src/sound.o \ - src/xm.o \ src/malloc.o \ - src/framebuffer.o \ - src/texture.o \ - src/graphics_primitive.o \ + src/scene/logo/scene.o \ + src/scene/logo/sound.o \ src/scene/scene.o \ - src/scene/tracker/scene.o \ src/scene/tracker/channel_status.o \ src/scene/tracker/notes.o \ - src/scene/logo/scene.o \ - src/scene/logo/sound.o + src/scene/tracker/scene.o \ + src/sound.o \ + src/texture.o \ + src/widget/button.o \ + src/xm.o xm_player.elf: LDSCRIPT = $(LIB)/main.lds xm_player.elf: $(START_OBJ) $(XM_PLAYER_OBJ) $(TEXTURE_OBJ) $(XM_OBJ) $(PCM_OBJ) $(LIBGCC)