graphics: draw pattern

This commit is contained in:
Zack Buhman 2025-06-24 19:40:38 -05:00
parent cdeb839355
commit 43fd3e9ec4
4 changed files with 193 additions and 22 deletions

View File

@ -31,6 +31,7 @@
#include "ta_parameter.hpp" #include "ta_parameter.hpp"
#include "framebuffer.hpp" #include "framebuffer.hpp"
#include "interpreter.hpp"
constexpr uint32_t ta_alloc = 0 constexpr uint32_t ta_alloc = 0
| ta_alloc_ctrl::pt_opb::no_list | 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 ap = transform_glyph_position(quad_vertices[0].p, x, y);
vec3 bp = transform_glyph_position(quad_vertices[1].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, ap, at,
bp, bt, bp, bt,
cp, ct, 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; int len = 0;
while (*s) { while (*u8) {
len += 1; len += 1;
transfer_glyph(writer, *s++, x, y); transfer_glyph(writer, *u8++, x, y, base_color);
x += glyph_hori_advance; x += glyph_hori_advance;
} }
return len; 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]; 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; x += glyph_hori_advance * shift;
transfer_string(writer, buf, x, y); transfer_string(writer, buf, x, y, base_color);
return len + shift; 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) void transfer_scene(ta_parameter_writer& writer)
{ {
global_polygon_type_0(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>() = writer.append<ta_global_parameter::end_of_list>() =
ta_global_parameter::end_of_list(para_control::para_type::end_of_list); ta_global_parameter::end_of_list(para_control::para_type::end_of_list);

View File

@ -58,7 +58,7 @@ const static int8_t volume_table[] = {
15 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; int instrument = (pf->instrument != 0) ? pf->instrument : state.channel[ch].instrument;
if (instrument == 0) if (instrument == 0)
@ -116,7 +116,7 @@ void _play_note(int ch, xm_pattern_format_t * pf)
wait(); aica_sound.channel[ch].KYONB(1); 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; 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) { if (pf->note == 97) {
wait(); aica_sound.channel[ch].KYONB(0); 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) { if (pf->note == 97) {
} else if (pf->note != 0) { } 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]); printf("note_count: %d\n", state.xm.pattern_note_count[state.pattern_index]);
} }
template <void (*F)(int, xm_pattern_format_t *)> template <void (*F)(int, const xm_pattern_format_t *)>
void execute_line(int line_index) void execute_line(int line_index)
{ {
int line_pattern_index = line_index * state.xm.number_of_channels; int line_pattern_index = line_index * state.xm.number_of_channels;

View File

@ -48,7 +48,7 @@ void vbr600()
= tmu::tcr0::UNIE = tmu::tcr0::UNIE
| tmu::tcr0::tpsc::p_phi_256; // clear underflow | tmu::tcr0::tpsc::p_phi_256; // clear underflow
interpreter::interrupt(); //interpreter::interrupt();
} else { } else {
serial::string("vbr600\n"); serial::string("vbr600\n");
interrupt_exception(); interrupt_exception();

View File

@ -9,7 +9,8 @@ void global_polygon_type_0(ta_parameter_writer& writer)
const uint32_t isp_tsp_instruction_word = isp_tsp_instruction_word::depth_compare_mode::always const uint32_t isp_tsp_instruction_word = isp_tsp_instruction_word::depth_compare_mode::always
| isp_tsp_instruction_word::culling_mode::no_culling; | 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::dst_alpha_instr::zero
| tsp_instruction_word::fog_control::no_fog | tsp_instruction_word::fog_control::no_fog
| tsp_instruction_word::texture_u_size::from_int(128) | 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& ap, const vec2& at,
const vec3& bp, const vec2& bt, const vec3& bp, const vec2& bt,
const vec3& cp, const vec2& ct, 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>() = writer.append<ta_vertex_parameter::polygon_type_3>() =
ta_vertex_parameter::polygon_type_3(polygon_vertex_parameter_control_word(false), ta_vertex_parameter::polygon_type_3(polygon_vertex_parameter_control_word(false),
ap.x, ap.y, ap.z, ap.x, ap.y, ap.z,
at.x, at.y, at.x, at.y,
0, 0); base_color, 0);
writer.append<ta_vertex_parameter::polygon_type_3>() = writer.append<ta_vertex_parameter::polygon_type_3>() =
ta_vertex_parameter::polygon_type_3(polygon_vertex_parameter_control_word(false), ta_vertex_parameter::polygon_type_3(polygon_vertex_parameter_control_word(false),
bp.x, bp.y, bp.z, bp.x, bp.y, bp.z,
bt.x, bt.y, bt.x, bt.y,
0, 0); base_color, 0);
writer.append<ta_vertex_parameter::polygon_type_3>() = writer.append<ta_vertex_parameter::polygon_type_3>() =
ta_vertex_parameter::polygon_type_3(polygon_vertex_parameter_control_word(false), ta_vertex_parameter::polygon_type_3(polygon_vertex_parameter_control_word(false),
dp.x, dp.y, dp.z, dp.x, dp.y, dp.z,
dt.x, dt.y, dt.x, dt.y,
0, 0); base_color, 0);
writer.append<ta_vertex_parameter::polygon_type_3>() = writer.append<ta_vertex_parameter::polygon_type_3>() =
ta_vertex_parameter::polygon_type_3(polygon_vertex_parameter_control_word(true), ta_vertex_parameter::polygon_type_3(polygon_vertex_parameter_control_word(true),
cp.x, cp.y, cp.z, cp.x, cp.y, cp.z,
ct.x, ct.y, ct.x, ct.y,
0, 0); base_color, 0);
} }