From 43fd3e9ec49128c5bf232ca0f0494494c6b6d1fb Mon Sep 17 00:00:00 2001 From: Zack Buhman Date: Tue, 24 Jun 2025 19:40:38 -0500 Subject: [PATCH] graphics: draw pattern --- src/graphics.cpp | 185 +++++++++++++++++++++++++++++++++++++++++-- src/interpreter.cpp | 10 +-- src/main.cpp | 2 +- src/ta_parameter.hpp | 18 +++-- 4 files changed, 193 insertions(+), 22 deletions(-) diff --git a/src/graphics.cpp b/src/graphics.cpp index bc4a4c7..4ddd853 100644 --- a/src/graphics.cpp +++ b/src/graphics.cpp @@ -31,6 +31,7 @@ #include "ta_parameter.hpp" #include "framebuffer.hpp" +#include "interpreter.hpp" constexpr uint32_t ta_alloc = 0 | ta_alloc_ctrl::pt_opb::no_list @@ -206,7 +207,7 @@ static inline vec3 transform_glyph_position(const vec3& p, float x, float y) }; } -void transfer_glyph(ta_parameter_writer& writer, char c, int x, int y) +void transfer_glyph(ta_parameter_writer& writer, int c, int x, int y, 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); @@ -222,21 +223,25 @@ void transfer_glyph(ta_parameter_writer& writer, char c, int x, int y) ap, at, bp, bt, cp, ct, - dp, dt); + dp, dt, + 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, int x, int y, + int base_color) { + const uint8_t * u8 = (const uint8_t *)s; int len = 0; - while (*s) { + while (*u8) { len += 1; - transfer_glyph(writer, *s++, x, y); + transfer_glyph(writer, *u8++, x, y, base_color); x += glyph_hori_advance; } return len; } -int transfer_integer(ta_parameter_writer& writer, int n, int x, int y, int offset) +int transfer_integer(ta_parameter_writer& writer, int n, int x, int y, int offset, + int base_color) { char buf[16]; @@ -251,16 +256,180 @@ int transfer_integer(ta_parameter_writer& writer, int n, int x, int y, int offse } x += glyph_hori_advance * shift; - transfer_string(writer, buf, x, y); + transfer_string(writer, buf, x, y, base_color); return len + shift; } +int transfer_hex_integer(ta_parameter_writer& writer, int n, int x, int y, + int length, int fill, + int base_color) +{ + char buf[16]; + + int len = unparse_base16(buf, n, length, fill); + buf[len] = 0; + + transfer_string(writer, buf, x, y, base_color); + + return len; +} + +const char note_names[12][2] = { + {'C', '-'}, + {'C', '#'}, + {'D', '-'}, + {'D', '#'}, + + {'E', '-'}, + {'F', '-'}, + {'F', '#'}, + {'G', '-'}, + + {'G', '#'}, + {'A', '-'}, + {'A', '#'}, + {'B', '-'}, +}; + +const int horizontal_bar = 0x16; +const int interpunct = 0xb7; + +int transfer_fill(ta_parameter_writer& writer, int count, int x, int y, + int base_color) +{ + for (int i = 0; i < count; i++) { + transfer_glyph(writer, interpunct, x, y, base_color); + x += glyph_hori_advance; + } + return x; +} + +static inline int effect_type_char(int effect_type) +{ + if (effect_type >= 0 && effect_type <= 9) + return effect_type + '0'; + if (effect_type >= 10 && effect_type <= 36) + return (effect_type - 10) + 'a'; + return 128; +} + +static inline int transfer_note(ta_parameter_writer& writer, int note, int x, int y) +{ + int base_color = 0xffffff; + + if (note == 97) { + transfer_glyph(writer, horizontal_bar, x, y, base_color); + x += glyph_hori_advance; + transfer_glyph(writer, horizontal_bar, x, y, base_color); + x += glyph_hori_advance; + transfer_glyph(writer, horizontal_bar, x, y, 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); + x += glyph_hori_advance; + transfer_glyph(writer, note_name[1], x, y, base_color); + x += glyph_hori_advance; + transfer_glyph(writer, '0' + octave, x, y, base_color); + x += glyph_hori_advance; + } else { + x = transfer_fill(writer, 3, x, y, base_color); + } + return x; +} + +static inline int transfer_instrument(ta_parameter_writer& writer, int instrument, int x, int y) +{ + int base_color = 0x9393ff; + + if (instrument != 0) { + int len = transfer_hex_integer(writer, instrument, x, y, 2, interpunct, base_color); + x += glyph_hori_advance * len; + } else { + x = transfer_fill(writer, 2, x, y, base_color); + } + return x; +} + +static inline int transfer_volume_column_byte(ta_parameter_writer& writer, int volume_column_byte, int x, int y) +{ + int base_color = 0xa7c9f1; + + if (volume_column_byte != 0) { + int len = transfer_hex_integer(writer, volume_column_byte, x, y, 2, interpunct, base_color); + x += glyph_hori_advance * len; + } else { + x = transfer_fill(writer, 2, x, y, base_color); + } + return x; +} + +static inline int transfer_effect_type(ta_parameter_writer& writer, int effect_type, int x, int y) +{ + int base_color = 0xffffff; + + if (effect_type != 0) { + int c = effect_type_char(effect_type); + transfer_glyph(writer, c, x, y, base_color); + x += glyph_hori_advance; + } else { + x = transfer_fill(writer, 1, x, y, base_color); + } + return x; +} + +static inline int transfer_effect_parameter(ta_parameter_writer& writer, int effect_parameter, int x, int y) +{ + int base_color = 0x7f7f80; + + if (effect_parameter != 0) { + int len = transfer_hex_integer(writer, effect_parameter, x, y, 2, interpunct, base_color); + x += glyph_hori_advance * len; + } else { + x = transfer_fill(writer, 2, x, y, base_color); + } + return x; +} + +void transfer_line(ta_parameter_writer& writer, int line_index, int x, int y) +{ + using namespace interpreter; + + + int line_pattern_index = line_index * state.xm.number_of_channels; + const xm_pattern_format_t * pattern = state.xm.pattern[state.pattern_index]; + for (int ch = 0; ch < state.xm.number_of_channels; ch++) { + const xm_pattern_format_t& pf = pattern[line_pattern_index + ch]; + + x += 1; + x = transfer_note(writer, pf.note, x, y); + x += 1; + x = transfer_instrument(writer, pf.instrument, x, y); + x += 1; + x = transfer_volume_column_byte(writer, pf.volume_column_byte, x, y); + x += 1; + x = transfer_effect_type(writer, pf.effect_type, x, y); + x += 1; + x = transfer_effect_parameter(writer, pf.effect_parameter, x, y); + x += 1; + + x += 3; + } +} + void transfer_scene(ta_parameter_writer& writer) { global_polygon_type_0(writer); - transfer_string(writer, "hello", 32, 32); + int y = 48; + int x = 3; + for (int i = 0; i < 20; i++) { + transfer_line(writer, i, x, y); + y += glyph_vert_advance; + } writer.append() = ta_global_parameter::end_of_list(para_control::para_type::end_of_list); diff --git a/src/interpreter.cpp b/src/interpreter.cpp index 9057c25..08d3ffe 100644 --- a/src/interpreter.cpp +++ b/src/interpreter.cpp @@ -58,7 +58,7 @@ const static int8_t volume_table[] = { 15 }; -void _play_note(int ch, xm_pattern_format_t * pf) +void _play_note(int ch, const xm_pattern_format_t * pf) { int instrument = (pf->instrument != 0) ? pf->instrument : state.channel[ch].instrument; if (instrument == 0) @@ -116,7 +116,7 @@ void _play_note(int ch, xm_pattern_format_t * pf) wait(); aica_sound.channel[ch].KYONB(1); } -void play_note_effect(int ch, xm_pattern_format_t * pf) +void play_note_effect(int ch, const xm_pattern_format_t * pf) { int effect_tick = (state.tick / 2) % state.ticks_per_line; @@ -148,7 +148,7 @@ void play_note_effect(int ch, xm_pattern_format_t * pf) } } -void play_note(int ch, xm_pattern_format_t * pf) +void play_note(int ch, const xm_pattern_format_t * pf) { if (pf->note == 97) { wait(); aica_sound.channel[ch].KYONB(0); @@ -169,7 +169,7 @@ void play_debug_note(int ch, xm_pattern_format_t * pf) } */ -void rekey_note(int ch, xm_pattern_format_t * pf) +void rekey_note(int ch, const xm_pattern_format_t * pf) { if (pf->note == 97) { } else if (pf->note != 0) { @@ -195,7 +195,7 @@ static inline void next_pattern() printf("note_count: %d\n", state.xm.pattern_note_count[state.pattern_index]); } -template +template void execute_line(int line_index) { int line_pattern_index = line_index * state.xm.number_of_channels; diff --git a/src/main.cpp b/src/main.cpp index 6915546..9cc27b1 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -48,7 +48,7 @@ void vbr600() = tmu::tcr0::UNIE | tmu::tcr0::tpsc::p_phi_256; // clear underflow - interpreter::interrupt(); + //interpreter::interrupt(); } else { serial::string("vbr600\n"); interrupt_exception(); diff --git a/src/ta_parameter.hpp b/src/ta_parameter.hpp index 926f48d..9bf4a37 100644 --- a/src/ta_parameter.hpp +++ b/src/ta_parameter.hpp @@ -3,13 +3,14 @@ void global_polygon_type_0(ta_parameter_writer& writer) const uint32_t parameter_control_word = para_control::para_type::polygon_or_modifier_volume | para_control::list_type::opaque | obj_control::col_type::packed_color - | obj_control::texture - ; + | obj_control::texture + ; const uint32_t isp_tsp_instruction_word = isp_tsp_instruction_word::depth_compare_mode::always | isp_tsp_instruction_word::culling_mode::no_culling; - const uint32_t tsp_instruction_word = tsp_instruction_word::src_alpha_instr::one + 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 | tsp_instruction_word::texture_u_size::from_int(128) @@ -34,29 +35,30 @@ static inline void quad_type_3(ta_parameter_writer& writer, const vec3& ap, const vec2& at, const vec3& bp, const vec2& bt, const vec3& cp, const vec2& ct, - const vec3& dp, const vec2& dt) + const vec3& dp, const vec2& dt, + int base_color) { writer.append() = ta_vertex_parameter::polygon_type_3(polygon_vertex_parameter_control_word(false), ap.x, ap.y, ap.z, at.x, at.y, - 0, 0); + base_color, 0); writer.append() = ta_vertex_parameter::polygon_type_3(polygon_vertex_parameter_control_word(false), bp.x, bp.y, bp.z, bt.x, bt.y, - 0, 0); + base_color, 0); writer.append() = ta_vertex_parameter::polygon_type_3(polygon_vertex_parameter_control_word(false), dp.x, dp.y, dp.z, dt.x, dt.y, - 0, 0); + base_color, 0); writer.append() = ta_vertex_parameter::polygon_type_3(polygon_vertex_parameter_control_word(true), cp.x, cp.y, cp.z, ct.x, ct.y, - 0, 0); + base_color, 0); }