diff --git a/chess/chess.cpp b/chess/chess.cpp index 2386b7f..18e0ff3 100644 --- a/chess/chess.cpp +++ b/chess/chess.cpp @@ -286,6 +286,8 @@ void game_init(game_state& game_state) game_state.halfmove_number = 0; game_state.fullmove_number = 0; game_state.interaction.selected_position = -1; + game_state.interaction.last_move.from_position = -1; + game_state.interaction.last_move.to_position = -1; board_init(game_state); } @@ -411,6 +413,8 @@ void do_move(game_state& game_state, int8_t from_position, move_t& move) destination.piece_list_offset = origin.piece_list_offset; origin.type = piece_type::empty; game_state.piece_list.piece[origin.piece_list_offset] = &destination; + game_state.interaction.last_move.from_position = from_position; + game_state.interaction.last_move.to_position = move.to_position; game_state.turn = -game_state.turn; } @@ -443,4 +447,23 @@ void select_position(game_state& game_state, int8_t x, int8_t y) game_state.interaction.moves.length = 0; } +void clear_annotations(game_state& game_state) +{ + game_state.interaction.annotation_list.length = 0; +} + +void annotate_position(game_state& game_state, int8_t x, int8_t y) +{ + int8_t position = xy_to_position(x, y); + auto& annotation_list = game_state.interaction.annotation_list; + + for (int i = 0; i < annotation_list.length; i++) { + if (annotation_list.annotation[i].from_position == position) { + return; + } + } + + annotation_list.annotation[annotation_list.length++].from_position = position; +} + } diff --git a/chess/chess.hpp b/chess/chess.hpp index eecc96e..f4ba3fa 100644 --- a/chess/chess.hpp +++ b/chess/chess.hpp @@ -57,9 +57,30 @@ struct moves_list { int8_t length; }; +enum struct annotation_type : int8_t { + highlight, + arrow, +}; + +struct annotation { + annotation_type type; + int8_t from_position; + int8_t to_position; +}; + +struct annotation_list { + struct annotation annotation[127]; + int8_t length; +}; + struct interaction_state { + struct { + int8_t from_position; + int8_t to_position; + } last_move; int8_t selected_position; struct moves_list moves; + struct annotation_list annotation_list; }; struct game_state { @@ -74,9 +95,11 @@ struct game_state { xy position_to_xy(int8_t position); int8_t xy_to_position(int8_t x, int8_t y); -void game_init(game_state& game_state); -void select_position(game_state& game_state, int8_t x, int8_t y); int8_t piece_list_to_position(const chess::board_state& board_state, chess::piece * piece); +void game_init(game_state& game_state); +void select_position(game_state& game_state, int8_t x, int8_t y); +void annotate_position(game_state& game_state, int8_t x, int8_t y); +void clear_annotations(game_state& game_state); } diff --git a/chess/chess.mk b/chess/chess.mk index 052f496..7d95d79 100644 --- a/chess/chess.mk +++ b/chess/chess.mk @@ -21,7 +21,7 @@ CHESS_GEOMETRY = \ chess/rook.hpp \ chess/square.hpp \ chess/circle.hpp \ - chess/cursor.hpp + chess/pointer.hpp chess/render.o: chess/render.cpp $(CHESS_GEOMETRY) diff --git a/chess/cursor.hpp b/chess/cursor.hpp deleted file mode 100644 index 78311ac..0000000 --- a/chess/cursor.hpp +++ /dev/null @@ -1,26 +0,0 @@ -#pragma once - -#include "geometry/geometry.hpp" - -namespace cursor { - constexpr vec3 vertices[] = { - { 0.407995f, -0.805648f, 2.000000f }, - { 0.000000f, 0.000000f, 2.000000f }, - { 0.550770f, -0.527772f, 2.000000f }, - { 0.302290f, -0.556623f, 2.000000f }, - { 0.297535f, -0.852536f, 2.000000f }, - { 0.000000f, -0.762211f, 2.000000f }, - { 0.191836f, -0.603526f, 2.000000f }, - }; - - constexpr face_v faces[] = { - {{1}, {6}, {0}}, - {{3}, {2}, {1}}, - {{1}, {5}, {6}}, - {{6}, {4}, {0}}, - {{0}, {3}, {1}}, - }; - - constexpr uint32_t num_faces = (sizeof (faces)) / (sizeof (face_v)); - -} diff --git a/chess/cursor.obj b/chess/cursor.obj deleted file mode 100644 index 870e10a..0000000 --- a/chess/cursor.obj +++ /dev/null @@ -1,16 +0,0 @@ -# Blender 3.3.6 -# www.blender.org -o Cursor -v 0.407995 -0.805648 2.000000 -v 0.000000 0.000000 2.000000 -v 0.550770 -0.527772 2.000000 -v 0.302290 -0.556623 2.000000 -v 0.297535 -0.852536 2.000000 -v 0.000000 -0.762211 2.000000 -v 0.191836 -0.603526 2.000000 -s 0 -f 2 7 1 -f 4 3 2 -f 2 6 7 -f 7 5 1 -f 1 4 2 diff --git a/chess/main.cpp b/chess/main.cpp index 57a1f68..9046576 100644 --- a/chess/main.cpp +++ b/chess/main.cpp @@ -22,26 +22,29 @@ #include "sh7091/store_queue.hpp" #include "sh7091/serial.hpp" -#include "render.hpp" -#include "input.hpp" +#include "chess/chess.hpp" +#include "chess/render.hpp" +#include "chess/input.hpp" -struct button { - bool a; - bool b; -}; - -struct cursor { - float x; - float y; - struct button button[2]; -}; - -void cursor_update(chess::game_state& game_state, struct cursor& cursor, uint32_t frame_ix) +void cursor_update(struct render::cursor_state& cursor_state, uint32_t frame_ix) { for (int port_ix = 0; port_ix < 4; port_ix++) { + int cursor_ix = cursor_state.port_map[port_ix]; + if (cursor_ix == -1) + continue; + auto& cursor = cursor_state.cur[cursor_ix]; + auto& port = input::state.port[port_ix]; if (port.function_type & function_type::controller) { - + 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) { + auto& data = data_fields.data; + cursor.x += static_cast(data.analog_coordinate_axis[2] - 0x80) * 0.0035; + cursor.y += static_cast(data.analog_coordinate_axis[3] - 0x80) * -0.0035; + cursor.button[frame_ix].a = ft0::data_transfer::digital_button::a(data.digital_button) == 0; + cursor.button[frame_ix].b = ft0::data_transfer::digital_button::b(data.digital_button) == 0; + } } if (port.function_type & function_type::pointing) { auto& bus_data = port.host_response_data_transfer_ft9->bus_data; @@ -50,20 +53,27 @@ void cursor_update(chess::game_state& game_state, struct cursor& cursor, uint32_ auto& data = data_fields.data; cursor.x += static_cast(data.analog_coordinate_axis[0] - 0x200) * 0.0035; cursor.y += static_cast(data.analog_coordinate_axis[1] - 0x200) * -0.0035; - cursor.button[frame_ix].a = ft9::data_transfer::button::a(data.button) == 0; - cursor.button[frame_ix].b = ft9::data_transfer::button::b(data.button) == 0; + cursor.button[frame_ix].a = ft9::data_transfer::digital_button::a(data.digital_button) == 0; + cursor.button[frame_ix].b = ft9::data_transfer::digital_button::b(data.digital_button) == 0; } } } +} - uint32_t last_frame = (frame_ix + 1) & 1; - if (cursor.button[last_frame].a != cursor.button[frame_ix].a && cursor.button[frame_ix].a) { - int8_t x = cursor.x + 0.5f; - int8_t y = cursor.y + 0.5f; - chess::select_position(game_state, x, y); - } - if (cursor.button[last_frame].b != cursor.button[frame_ix].b && cursor.button[frame_ix].b) { - serial::string("b\n"); +void cursor_events(chess::game_state& game_state, struct render::cursor_state& cursor_state, uint32_t frame_ix) +{ + for (int cursor_ix = 0; cursor_ix < render::cursor_state::num_cursors; cursor_ix++) { + auto& cursor = cursor_state.cur[cursor_ix]; + const uint32_t last_frame = (frame_ix + 1) & 1; + const int8_t x = cursor.x + 0.5f; + const int8_t y = cursor.y + 0.5f; + if (cursor.button[last_frame].a != cursor.button[frame_ix].a && cursor.button[frame_ix].a) { + chess::clear_annotations(game_state); + chess::select_position(game_state, x, y); + } + if (cursor.button[last_frame].b != cursor.button[frame_ix].b && cursor.button[frame_ix].b) { + chess::annotate_position(game_state, x, y); + } } } @@ -73,13 +83,13 @@ void main() 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::t_opb::_16x4byte | ta_alloc_ctrl::om_opb::no_list - | ta_alloc_ctrl::o_opb::_16x4byte; + | ta_alloc_ctrl::o_opb::no_list; - constexpr struct opb_size opb_size = { .opaque = 16 * 4 + constexpr struct opb_size opb_size = { .opaque = 0 , .opaque_modifier = 0 - , .translucent = 0 + , .translucent = 16 * 4 , .translucent_modifier = 0 , .punch_through = 0 }; @@ -102,31 +112,29 @@ void main() uint32_t frame_ix = 0; - struct cursor cursor; - cursor.x = 4.f; - cursor.y = 4.f; + struct render::view_transform vt; + vt.piece_rotation = 0.f; + vt.board_rotation = 0.f; + + struct render::cursor_state cursor_state = render::cursor_state(); while (true) { input::state_update(send_buf, recv_buf); - cursor_update(game_state, cursor, frame_ix); + cursor_update(cursor_state, frame_ix); + cursor_events(game_state, cursor_state, frame_ix); ta_polygon_converter_init(opb_size.total(), ta_alloc, 640 / 32, 480 / 32); - render::draw_board(); - if (game_state.interaction.selected_position != -1) - render::draw_illumination(game_state.interaction.selected_position); - render::draw_pieces(game_state); - render::draw_moves(game_state.interaction.moves); - render::draw_cursor(cursor.x, cursor.y); + render::render(game_state, vt, cursor_state); *reinterpret_cast(store_queue) = ta_global_parameter::end_of_list(para_control::para_type::end_of_list); sq_transfer_32byte(ta_fifo_polygon_converter); - ta_wait_opaque_list(); + ta_wait_translucent_list(); core_start_render(frame_ix); core_wait_end_of_render_video(); diff --git a/chess/cursor.blend b/chess/pointer.blend similarity index 73% rename from chess/cursor.blend rename to chess/pointer.blend index ceeace3..ab34813 100644 Binary files a/chess/cursor.blend and b/chess/pointer.blend differ diff --git a/chess/pointer.hpp b/chess/pointer.hpp new file mode 100644 index 0000000..cef95fd --- /dev/null +++ b/chess/pointer.hpp @@ -0,0 +1,26 @@ +#pragma once + +#include "geometry/geometry.hpp" + +namespace pointer { + constexpr vec3 vertices[] = { + { 0.407995f, -0.805648f, -0.000000f }, + { 0.000000f, 0.000000f, 0.000000f }, + { 0.550770f, -0.527772f, -0.000000f }, + { 0.302290f, -0.556623f, -0.000000f }, + { 0.297535f, -0.852536f, -0.000000f }, + { 0.000000f, -0.762211f, 0.000000f }, + { 0.191836f, -0.603526f, 0.000000f }, + }; + + constexpr face_v faces[] = { + {{1}, {6}, {0}}, + {{3}, {2}, {1}}, + {{1}, {5}, {6}}, + {{6}, {4}, {0}}, + {{0}, {3}, {1}}, + }; + + constexpr uint32_t num_faces = (sizeof (faces)) / (sizeof (face_v)); + +} diff --git a/chess/pointer.obj b/chess/pointer.obj new file mode 100644 index 0000000..f91ef1f --- /dev/null +++ b/chess/pointer.obj @@ -0,0 +1,16 @@ +# Blender 3.3.6 +# www.blender.org +o Pointer +v 0.407995 -0.805648 -0.000000 +v 0.000000 0.000000 0.000000 +v 0.550770 -0.527772 -0.000000 +v 0.302290 -0.556623 -0.000000 +v 0.297535 -0.852536 -0.000000 +v 0.000000 -0.762211 0.000000 +v 0.191836 -0.603526 0.000000 +s 0 +f 2 7 1 +f 4 3 2 +f 2 6 7 +f 7 5 1 +f 1 4 2 diff --git a/chess/render.cpp b/chess/render.cpp index fd123b4..d063304 100644 --- a/chess/render.cpp +++ b/chess/render.cpp @@ -6,7 +6,7 @@ #include "chess/rook.hpp" #include "chess/square.hpp" #include "chess/circle.hpp" -#include "chess/cursor.hpp" +#include "chess/pointer.hpp" #include "sh7091/store_queue.hpp" #include "sh7091/serial.hpp" @@ -16,41 +16,77 @@ #include "holly/ta_global_parameter.hpp" #include "holly/ta_vertex_parameter.hpp" -#include "render.hpp" +#include "chess/chess.hpp" +#include "chess/render.hpp" namespace render { -static inline vec3 transform(const vec3 v, float cell_x, float cell_y, float scale) -{ - float x = v.x * 28.f * scale; - float y = -v.y * 28.f * scale; - x += 124.f + cell_x * 56.f; - y += 44.f + (7 - cell_y) * 56.f; +constexpr float board_z = 100.f; +constexpr float illumination_z = 99.f; +constexpr float piece_z = 70.f; +constexpr float move_z = 50.f; +constexpr float cursor_z = 0.f; - return {x, y, 1.f/(v.z + 10.0f)}; +vec3 __attribute__ ((noinline)) +transform(view_transform vt, + const vec3 v, + float cell_x, + float cell_y, + float z_offset, + float scale, + float rotation) +{ + float x0 = v.x; + float y0 = -v.y; + + // piece rotation + float x1 = x0 * __builtin_cosf(rotation) - y0 * __builtin_sinf(rotation); + float y1 = x0 * __builtin_sinf(rotation) + y0 * __builtin_cosf(rotation); + + float x2 = x1 * 28.f * scale; + float y2 = y1 * 28.f * scale; + + float x3 = x2 + (cell_x ) * 56.f - (196.f); + float y3 = y2 + (7 - cell_y) * 56.f - (196.f); + + float x4 = x3 * __builtin_cosf(vt.board_rotation) - y3 * __builtin_sinf(vt.board_rotation); + float y4 = x3 * __builtin_sinf(vt.board_rotation) + y3 * __builtin_cosf(vt.board_rotation); + + float x5 = x4 + 124.f + (196.f); + float y5 = y4 + 44.f + (196.f); + + float z = v.z + z_offset; + + return {x5, y5, 1.f/(z + 10.0f)}; } -static void draw_model(vec3 const * const vertices, +static void draw_model(const view_transform vt, + vec3 const * const vertices, face_v const * const faces, uint32_t num_faces, uint32_t base_color, float cell_x, float cell_y, + float z_offset, float scale, - bool always) + float rotation, + bool always, + bool alpha = false) { const uint32_t parameter_control_word = para_control::para_type::polygon_or_modifier_volume - | para_control::list_type::opaque + | para_control::list_type::translucent | obj_control::col_type::packed_color; - const uint32_t isp_tsp_instruction_word = (always ? isp_tsp_instruction_word::depth_compare_mode::always + const uint32_t isp_tsp_instruction_word = (always ? isp_tsp_instruction_word::depth_compare_mode::greater : isp_tsp_instruction_word::depth_compare_mode::greater) | isp_tsp_instruction_word::culling_mode::no_culling; - 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; - + const uint32_t tsp_instruction_word = (alpha ? tsp_instruction_word::src_alpha_instr::src_alpha + : tsp_instruction_word::src_alpha_instr::one) + | (alpha ? tsp_instruction_word::dst_alpha_instr::inverse_src_alpha + : tsp_instruction_word::dst_alpha_instr::zero) + | tsp_instruction_word::fog_control::no_fog + | tsp_instruction_word::use_alpha; for (uint32_t face_ix = 0; face_ix < num_faces; face_ix++) { @@ -69,7 +105,13 @@ static void draw_model(vec3 const * const vertices, constexpr uint32_t strip_length = 3; for (uint32_t i = 0; i < strip_length; i++) { uint32_t vertex_ix = face[i].vertex; - const auto vertex = transform(vertices[vertex_ix], cell_x, cell_y, scale); + const auto vertex = transform(vt, + vertices[vertex_ix], + cell_x, + cell_y, + z_offset, + scale, + rotation); bool end_of_strip = i == strip_length - 1; float z = __builtin_fabsf(vertices[vertex_ix].z); @@ -83,7 +125,7 @@ static void draw_model(vec3 const * const vertices, } } -void draw_board() +void draw_board(const view_transform vt) { for (int i = 0; i < 8 * 8; i++) { int x = i % 8; @@ -94,98 +136,129 @@ void draw_board() constexpr uint32_t green = 0xff739552; uint32_t color = white ? cream : green; - draw_model(square::vertices, + draw_model(vt, + square::vertices, square::faces, square::num_faces, color, x, y, + board_z, 1.0f, // scale + 0.0f, // rotation true); // always } } -void draw_illumination(int8_t position) +void draw_illumination(const view_transform vt, + int8_t position, uint32_t highlight_color) { auto [x, y] = chess::position_to_xy(position); - constexpr uint32_t cream = 0xfff5f681; - draw_model(square::vertices, + draw_model(vt, + square::vertices, square::faces, square::num_faces, - cream, + highlight_color, x, y, + illumination_z, 1.0f, // scale - true); // always + 0.0f, // rotation + true, // always + true); // alpha } -void draw_moves(chess::moves_list& moves) +void draw_moves(const view_transform vt, + const chess::moves_list& moves) { for (int i = 0; i < moves.length; i++) { chess::xy move_xy = chess::position_to_xy(moves.moves[i].to_position); - uint32_t color = 0xff777777; - draw_model(circle::vertices, + uint32_t color = 0x37000000; + draw_model(vt, + circle::vertices, circle::faces, circle::num_faces, color, move_xy.x, move_xy.y, - 0.5f, // scale - true); // always + move_z, + 0.4f, // scale + 0.0f, // rotation + true, // always + true); // alpha } } -void draw_piece(int8_t type, int8_t x, int8_t y) +void draw_piece(const view_transform vt, + int8_t type, int8_t x, int8_t y) { bool white = type > 0; uint32_t color = white ? 0xffdddddd : 0xff444444; switch (__builtin_abs(type)) { case chess::piece_type::pawn: - draw_model(pawn::vertices, + draw_model(vt, + pawn::vertices, pawn::faces, pawn::num_faces, color, x, y, + piece_z, 1.0f, // scale + vt.piece_rotation, // rotation false); // always break; case chess::piece_type::knight: - draw_model(knight::vertices, + draw_model(vt, + knight::vertices, knight::faces, knight::num_faces, color, x, y, + piece_z, 1.0f, // scale + vt.piece_rotation, // rotation false); // always break; case chess::piece_type::bishop: - draw_model(bishop::vertices, + draw_model(vt, + bishop::vertices, bishop::faces, bishop::num_faces, color, x, y, + piece_z, 1.0f, // scale + vt.piece_rotation, // rotation false); // always break; case chess::piece_type::rook: - draw_model(rook::vertices, + draw_model(vt, + rook::vertices, rook::faces, rook::num_faces, color, x, y, + piece_z, 1.0f, // scale + vt.piece_rotation, // rotation false); // always break; case chess::piece_type::queen: - draw_model(queen::vertices, + draw_model(vt, + queen::vertices, queen::faces, queen::num_faces, color, x, y, + piece_z, 1.0f, // scale + vt.piece_rotation, // rotation false); // always break; case chess::piece_type::king: - draw_model(king::vertices, + draw_model(vt, + king::vertices, king::faces, king::num_faces, color, x, y, + piece_z, 1.0f, // scale + vt.piece_rotation, // rotation false); // always break; default: @@ -193,27 +266,92 @@ void draw_piece(int8_t type, int8_t x, int8_t y) } } -void draw_pieces(const chess::game_state& game_state) +void draw_pieces(const view_transform vt, + const chess::game_state& game_state) { const auto& piece_list = game_state.piece_list; for (int i = 0; i < piece_list.length; i++) { chess::piece * piece = piece_list.piece[i]; int8_t position = piece_list_to_position(game_state.board, piece); auto [x, y] = chess::position_to_xy(position); - draw_piece(piece->type, x, y); + draw_piece(vt, + piece->type, + x, y); } } -void draw_cursor(float x, float y) +uint32_t cursor_colors[4] = { + 0xffff00ff, + 0xff00ff00, + 0xffffff00, + 0xffff0000, +}; + +void draw_cursor(const view_transform vt, + float x, float y, + int cursor_index) { - uint32_t color = 0xffff00ff; - draw_model(cursor::vertices, - cursor::faces, - cursor::num_faces, - color, + constexpr float pi = 3.141592653589793f; + + draw_model(vt, + pointer::vertices, + pointer::faces, + pointer::num_faces, + cursor_colors[cursor_index % 4], x, y, + cursor_z, 1.0f, // scale + pi * cursor_index, // rotation true); // always } + +void draw_annotation(const view_transform vt, + const chess::annotation_list& annotation_list) +{ + constexpr uint32_t red_highlight = 0xcceb6150; + + for (int i = 0; i < annotation_list.length; i++) { + auto& annotation = annotation_list.annotation[i]; + switch (annotation.type) { + case chess::annotation_type::highlight: + render::draw_illumination(vt, + annotation.from_position, + red_highlight); + break; + default: break; + } + } +} + +void draw_interaction(const view_transform vt, + const chess::interaction_state& interaction) +{ + constexpr uint32_t yellow_highlight = 0x7fffff33; + + if (interaction.selected_position != -1) + render::draw_illumination(vt, interaction.selected_position, yellow_highlight); + if (interaction.last_move.from_position != -1) + render::draw_illumination(vt, interaction.last_move.from_position, yellow_highlight); + if (interaction.last_move.to_position != -1) + render::draw_illumination(vt, interaction.last_move.to_position, yellow_highlight); +} + +void render(const chess::game_state& game_state, + const view_transform vt, + const cursor_state cursor_state) +{ + render::draw_board(vt); + + render::draw_interaction(vt, game_state.interaction); + render::draw_annotation(vt, game_state.interaction.annotation_list); + + render::draw_pieces(vt, game_state); + render::draw_moves(vt, game_state.interaction.moves); + for (int i = 0; i < cursor_state::num_cursors; i++) { + auto& cursor = cursor_state.cur[i]; + render::draw_cursor(vt, cursor.x, cursor.y, i); + } +} + } // namespace render diff --git a/chess/render.hpp b/chess/render.hpp index 01c663c..184fc26 100644 --- a/chess/render.hpp +++ b/chess/render.hpp @@ -2,14 +2,52 @@ #include -#include "chess.hpp" +#include "chess/chess.hpp" namespace render { -void draw_board(); -void draw_illumination(int8_t position); -void draw_moves(chess::moves_list& moves); -void draw_pieces(const chess::game_state& game_state); -void draw_cursor(float x, float y); +struct view_transform { + float piece_rotation; + float board_rotation; +}; + +struct button { + bool a; + bool b; +}; + +struct cursor { + float x; + float y; + struct button button[2]; + + constexpr cursor() + : x(4.f), y(4.f) + { + button[0] = {false, false}; + button[1] = {false, false}; + } +}; + +struct cursor_state { + constexpr static int num_cursors = 2; + + struct cursor cur[num_cursors]; + int port_map[4]; + + constexpr cursor_state() + { + port_map[0] = 0; + port_map[1] = 1; + port_map[2] = -1; + port_map[3] = -1; + cur[0] = cursor(); + cur[1] = cursor(); + } +}; + +void render(const chess::game_state& game_state, + const view_transform vt, + const cursor_state cursor_state); } diff --git a/maple/maple_bus_ft0.hpp b/maple/maple_bus_ft0.hpp index 753a748..f6a7d26 100644 --- a/maple/maple_bus_ft0.hpp +++ b/maple/maple_bus_ft0.hpp @@ -55,12 +55,7 @@ namespace ft0 { struct data_format { uint16_t digital_button; - uint8_t analog_axis_1; - uint8_t analog_axis_2; - uint8_t analog_axis_3; - uint8_t analog_axis_4; - uint8_t analog_axis_5; - uint8_t analog_axis_6; + uint8_t analog_coordinate_axis[6]; }; static_assert((sizeof (struct data_format)) % 4 == 0); static_assert((sizeof (struct data_format)) == 8); diff --git a/maple/maple_bus_ft9.hpp b/maple/maple_bus_ft9.hpp index d2abd1f..d586610 100644 --- a/maple/maple_bus_ft9.hpp +++ b/maple/maple_bus_ft9.hpp @@ -2,7 +2,7 @@ namespace ft9 { namespace data_transfer { - namespace button { + namespace digital_button { constexpr uint32_t r() { return 0b1 << 7; } constexpr uint32_t r(uint32_t reg) { return (reg >> 7) & 0b1; } @@ -39,7 +39,7 @@ namespace ft9 { } struct data_format { - uint8_t button; + uint8_t digital_button; uint8_t option; uint8_t analog_coordinate_overflow; uint8_t reserved; diff --git a/regs/maple_bus_ft0.csv b/regs/maple_bus_ft0.csv index a081908..36b6f41 100644 --- a/regs/maple_bus_ft0.csv +++ b/regs/maple_bus_ft0.csv @@ -1,9 +1,9 @@ "data_transfer",7,6,5,4,3,2,1,0 "digital_button","Ra","La","Da","Ua","Start","A","B","C" "digital_button","Rb","Lb","Db","Ub","D","X","Y","Z" -"analog_axis_1",,,,,,,, -"analog_axis_2",,,,,,,, -"analog_axis_3",,,,,,,, -"analog_axis_4",,,,,,,, -"analog_axis_5",,,,,,,, -"analog_axis_6",,,,,,,, +"analog_coordinate_axis",,,,,,,, +"analog_coordinate_axis",,,,,,,, +"analog_coordinate_axis",,,,,,,, +"analog_coordinate_axis",,,,,,,, +"analog_coordinate_axis",,,,,,,, +"analog_coordinate_axis",,,,,,,, diff --git a/regs/maple_bus_ft0.ods b/regs/maple_bus_ft0.ods index 2cbaf1a..36a8ebf 100644 Binary files a/regs/maple_bus_ft0.ods and b/regs/maple_bus_ft0.ods differ diff --git a/regs/maple_bus_ft9.csv b/regs/maple_bus_ft9.csv index a24c916..78ad170 100644 --- a/regs/maple_bus_ft9.csv +++ b/regs/maple_bus_ft9.csv @@ -1,5 +1,5 @@ "data_transfer",7,6,5,4,3,2,1,0 -"button","r","l","d","u","s","a","b","c" +"digital_button","r","l","d","u","s","a","b","c" "option",,,,,,,"batt","wire" "analog_coordinate_overflow",,,,,,,, "reserved",,,,,,,, diff --git a/regs/maple_bus_ft9.ods b/regs/maple_bus_ft9.ods index 1184608..78d4038 100644 Binary files a/regs/maple_bus_ft9.ods and b/regs/maple_bus_ft9.ods differ diff --git a/text_editor/keyboard.cpp b/text_editor/keyboard.cpp index 3d846c2..38fb6d6 100644 --- a/text_editor/keyboard.cpp +++ b/text_editor/keyboard.cpp @@ -9,30 +9,75 @@ #include "keyboard.hpp" -void keyboard_do_get_condition(ft6::data_transfer::data_format& data) +void do_device_request() { uint32_t send_buf[1024] __attribute__((aligned(32))); uint32_t recv_buf[1024] __attribute__((aligned(32))); auto writer = maple::host_command_writer(send_buf, recv_buf); - using command_type = get_condition; - using response_type = data_transfer; + using command_type = maple::device_request; + using response_type = maple::device_status; auto [host_command, host_response] = writer.append_command_all_ports(); + + maple::dma_start(send_buf, writer.send_offset, + recv_buf, writer.recv_offset); + + for (uint8_t port = 0; port < 1; port++) { + auto& bus_data = host_response[port].bus_data; + auto& data_fields = bus_data.data_fields; + if (bus_data.command_code != response_type::command_code) { + serial::string("port: "); + serial::integer(port); + serial::string(" disconnected\n"); + } else { + serial::string("port: "); + serial::integer(port); + serial::string(" ft: "); + serial::integer(std::byteswap(data_fields.device_id.ft)); + serial::string(" fd[0]: "); + serial::integer(std::byteswap(data_fields.device_id.fd[0])); + serial::string(" fd[1]: "); + serial::integer(std::byteswap(data_fields.device_id.fd[1])); + serial::string(" fd[2]: "); + serial::integer(std::byteswap(data_fields.device_id.fd[2])); + serial::string(" source_ap.lm_bus: "); + serial::integer(bus_data.source_ap & ap::lm_bus::bit_mask); + } + } +} + +void keyboard_do_get_condition(ft6::data_transfer::data_format& data) +{ + uint32_t send_buf[1024] __attribute__((aligned(32))); + uint32_t recv_buf[1024] __attribute__((aligned(32))); + + using command_type = maple::get_condition; + using response_type = maple::data_transfer; + + auto writer = maple::host_command_writer(send_buf, recv_buf); + + auto [host_command, host_response] + = writer.append_command_all_ports(); + host_command->bus_data.data_fields.function_type = std::byteswap(function_type::keyboard); maple::dma_start(send_buf, writer.send_offset, recv_buf, writer.recv_offset); - for (uint8_t port = 0; port < 4; port++) { + for (uint8_t port = 0; port < 1; port++) { auto& bus_data = host_response[port].bus_data; auto& data_fields = bus_data.data_fields; + //serial::integer(port, ' '); + //serial::integer(bus_data.command_code); if (bus_data.command_code != response_type::command_code) { + do_device_request(); continue; } if ((std::byteswap(data_fields.function_type) & function_type::keyboard) == 0) { + serial::integer(std::byteswap(data_fields.function_type)); continue; } @@ -61,9 +106,9 @@ void keyboard_debug(ft6::data_transfer::data_format * keyboards, uint32_t frame_ } if (difference) { for (int i = 0; i < 6; i++) { - serial::integer(keyboards[this_frame].scan_code_array[i], ' '); + //serial::integer(keyboards[this_frame].scan_code_array[i], ' '); } - serial::string("\n"); + //serial::string("\n"); } } @@ -97,10 +142,14 @@ void keyboard_update(ft6::data_transfer::data_format * keyboards, uint32_t frame bool shifted = is_shifted(keyboards[this_frame].modifier_key); char_type code_point = ft6::scan_code::code_point[scan_code][shifted]; if (code_point != 0) { - gap_append(gb, code_point); + serial::character(code_point); + serial::character('\n'); + //gap_append(gb, code_point); continue; } } + serial::integer(scan_code); + continue; switch (scan_code) { case ft6::scan_code::_return: gap_append(gb, '\n'); break; case ft6::scan_code::backspace: gap_pop(gb); break; diff --git a/text_editor/render.cpp b/text_editor/render.cpp index 937c0cd..3ad6d4d 100644 --- a/text_editor/render.cpp +++ b/text_editor/render.cpp @@ -3,6 +3,8 @@ #include "transform.hpp" #include "holly/ta_global_parameter.hpp" +#include "holly/ta_fifo_polygon_converter.hpp" +#include "sh7091/serial.hpp" static inline uint32_t get_font_ix(const struct font * font, char_type c) @@ -115,7 +117,19 @@ void render(ta_parameter_writer& parameter, parameter.append() = ta_global_parameter::end_of_list(para_control::para_type::end_of_list); + ta_polygon_converter_transfer(parameter.buf, parameter.offset); + ta_wait_opaque_list(); + + parameter.offset = 0; + + /* render_cursor(parameter, cursor, window); parameter.append() = ta_global_parameter::end_of_list(para_control::para_type::end_of_list); + + ta_polygon_converter_transfer(parameter.buf, parameter.offset); + serial::string("wait tl\n"); + ta_wait_translucent_list(); + serial::string("done tl\n"); + */ } diff --git a/text_editor/text_editor.cpp b/text_editor/text_editor.cpp index 6fbe1dc..45f52b5 100644 --- a/text_editor/text_editor.cpp +++ b/text_editor/text_editor.cpp @@ -15,6 +15,8 @@ #include "holly/ta_global_parameter.hpp" #include "holly/ta_bits.hpp" +#include "sh7091/serial.hpp" + #include "font/font.hpp" #include "ter_u20n.hpp" @@ -78,13 +80,13 @@ void main() constexpr uint32_t ta_alloc = ta_alloc_ctrl::pt_opb::no_list | ta_alloc_ctrl::tm_opb::no_list - | ta_alloc_ctrl::t_opb::_16x4byte + //| ta_alloc_ctrl::t_opb::_16x4byte | 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 = 16 * 4 + //, .translucent = 16 * 4 , .translucent_modifier = 0 , .punch_through = 0 }; @@ -118,9 +120,6 @@ void main() auto parameter = ta_parameter_writer(ta_parameter_buf); render(parameter, font, glyphs, state.gb, state.window); - ta_polygon_converter_transfer(parameter.buf, parameter.offset); - ta_wait_opaque_list(); - core_start_render(frame_ix); core_wait_end_of_render_video(); diff --git a/text_editor/text_editor.mk b/text_editor/text_editor.mk index a3e5a4b..ff9bced 100644 --- a/text_editor/text_editor.mk +++ b/text_editor/text_editor.mk @@ -11,7 +11,8 @@ TEXT_EDITOR_OBJ = \ holly/ta_fifo_polygon_converter.o \ maple/maple.o \ sh7091/serial.o \ - ter_u20n.data.o + ter_u20n.data.o \ + $(LIBGCC) text_editor/text_editor.elf: LDSCRIPT = $(LIB)/main.lds text_editor/text_editor.elf: $(START_OBJ) $(TEXT_EDITOR_OBJ) diff --git a/text_editor/transform.cpp b/text_editor/transform.cpp index e472aa9..d3ba0ec 100644 --- a/text_editor/transform.cpp +++ b/text_editor/transform.cpp @@ -100,7 +100,7 @@ void transform_glyph(ta_parameter_writer& parameter, const uint32_t texture_address = texture_memory_alloc::texture.start; const uint32_t texture_control_word = texture_control_word::pixel_format::_4bpp_palette | texture_control_word::scan_order::twiddled - | texture_control_word::palette_selector(0) + | texture_control_word::palette_selector4(0) | texture_control_word::texture_address(texture_address / 8); parameter.append() =