324 lines
8.5 KiB
C++
324 lines
8.5 KiB
C++
#include "../../ta_parameter.hpp"
|
|
|
|
#include "../../graphics_primitive.hpp"
|
|
#include "../../interpreter.hpp"
|
|
|
|
#include "notes.hpp"
|
|
#include "framebuffer.hpp"
|
|
|
|
union columns {
|
|
struct {
|
|
int note;
|
|
int instrument;
|
|
int volume_column_byte;
|
|
int effect_type;
|
|
int effect_parameter;
|
|
};
|
|
int col[5];
|
|
|
|
int count() const
|
|
{
|
|
int acc = 0;
|
|
for (int i = 0; i < 5; i++) {
|
|
acc += col[i] != 0;
|
|
}
|
|
return acc;
|
|
}
|
|
|
|
int sum() const
|
|
{
|
|
int acc = 0;
|
|
for (int i = 0; i < 5; i++) {
|
|
acc += col[i];
|
|
}
|
|
return acc;
|
|
}
|
|
};
|
|
|
|
const columns line_columns = {
|
|
.note = 3,
|
|
.instrument = 2,
|
|
.volume_column_byte = 0, // 2
|
|
.effect_type = 0, // 1
|
|
.effect_parameter = 0, // 1
|
|
};
|
|
|
|
const int line_column_total_advance = line_columns.sum() * glyph::hori_advance;
|
|
const int line_column_width = line_column_total_advance + (line_columns.count() + 1) + 3;
|
|
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 float depth = 0.0001f;
|
|
|
|
static inline int draw_line_index(ta_parameter_writer& writer, int line_index, int x, int y)
|
|
{
|
|
const int dark = 0x5d646b;
|
|
const int light = 0xa7a7a7;
|
|
|
|
int base_color = ((line_index % 4) == 0) ? dark : light;
|
|
|
|
int len = transfer_integer(writer, line_index, x, y, depth, 2, ' ', base_color);
|
|
x += glyph::hori_advance * len;
|
|
|
|
return x;
|
|
}
|
|
|
|
static inline int draw_fill(ta_parameter_writer& writer, int count, int x, int y,
|
|
int base_color)
|
|
{
|
|
for (int i = 0; i < count; i++) {
|
|
transfer_glyph(writer, glyph::interpunct, x, y, depth, base_color);
|
|
x += glyph::hori_advance;
|
|
}
|
|
return x;
|
|
}
|
|
|
|
static inline int draw_note(ta_parameter_writer& writer, int note, int x, int y)
|
|
{
|
|
static const char note_names[12][2] = {
|
|
{'C', '-'},
|
|
{'C', '#'},
|
|
{'D', '-'},
|
|
{'D', '#'},
|
|
|
|
{'E', '-'},
|
|
{'F', '-'},
|
|
{'F', '#'},
|
|
{'G', '-'},
|
|
|
|
{'G', '#'},
|
|
{'A', '-'},
|
|
{'A', '#'},
|
|
{'B', '-'},
|
|
};
|
|
|
|
int base_color = 0xffffff;
|
|
|
|
if (note == 97) {
|
|
transfer_glyph(writer, glyph::horizontal_bar, x, y, depth, base_color);
|
|
x += glyph::hori_advance;
|
|
transfer_glyph(writer, glyph::horizontal_bar, x, y, depth, base_color);
|
|
x += glyph::hori_advance;
|
|
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, depth, base_color);
|
|
x += glyph::hori_advance;
|
|
transfer_glyph(writer, note_name[1], x, y, depth, base_color);
|
|
x += glyph::hori_advance;
|
|
transfer_glyph(writer, '0' + octave, x, y, depth, base_color);
|
|
x += glyph::hori_advance;
|
|
} else {
|
|
x = draw_fill(writer, 3, x, y, base_color);
|
|
}
|
|
return x;
|
|
}
|
|
|
|
static inline int draw_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, depth,
|
|
2, glyph::interpunct,
|
|
base_color);
|
|
x += glyph::hori_advance * len;
|
|
} else {
|
|
x = draw_fill(writer, 2, x, y, base_color);
|
|
}
|
|
return x;
|
|
}
|
|
|
|
static inline int draw_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, depth,
|
|
2, glyph::interpunct,
|
|
base_color);
|
|
x += glyph::hori_advance * len;
|
|
} else {
|
|
x = draw_fill(writer, 2, x, y, base_color);
|
|
}
|
|
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 draw_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, depth, base_color);
|
|
x += glyph::hori_advance;
|
|
} else {
|
|
x = draw_fill(writer, 1, x, y, base_color);
|
|
}
|
|
return x;
|
|
}
|
|
|
|
static inline int draw_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, depth,
|
|
2, glyph::interpunct,
|
|
base_color);
|
|
x += glyph::hori_advance * len;
|
|
} else {
|
|
x = draw_fill(writer, 2, x, y, base_color);
|
|
}
|
|
return x;
|
|
}
|
|
|
|
static void draw_line(ta_parameter_writer& writer, int line_index, int x, int y)
|
|
{
|
|
using namespace interpreter;
|
|
|
|
x += 3;
|
|
x += 1;
|
|
x = draw_line_index(writer, line_index, x, y);
|
|
x += 1;
|
|
x += 3;
|
|
|
|
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;
|
|
if (line_columns.note != 0) {
|
|
x = draw_note(writer, pf.note, x, y);
|
|
x += 1;
|
|
}
|
|
if (line_columns.instrument != 0) {
|
|
x = draw_instrument(writer, pf.instrument, x, y);
|
|
x += 1;
|
|
}
|
|
if (line_columns.volume_column_byte != 0) {
|
|
x = draw_volume_column_byte(writer, pf.volume_column_byte, x, y);
|
|
x += 1;
|
|
}
|
|
if (line_columns.effect_type != 0) {
|
|
x = draw_effect_type(writer, pf.effect_type, x, y);
|
|
x += 1;
|
|
}
|
|
if (line_columns.effect_parameter != 0) {
|
|
x = draw_effect_parameter(writer, pf.effect_parameter, x, y);
|
|
x += 1;
|
|
}
|
|
|
|
x += 3;
|
|
}
|
|
}
|
|
|
|
namespace scene::tracker::notes {
|
|
|
|
void draw_borders(ta_parameter_writer& writer, int x, int y)
|
|
{
|
|
using namespace interpreter;
|
|
|
|
int x0 = x;
|
|
|
|
//transfer_vertical_border(writer, x, y, line_column_height);
|
|
x += 3 + glyph::hori_advance * 2 + 2;
|
|
|
|
for (int ch = 0; ch < (state.xm.number_of_channels); ch++) {
|
|
transfer_vertical_border(writer, x, y, line_column_height);
|
|
x += line_column_width;
|
|
}
|
|
transfer_vertical_border(writer, x, y, line_column_height);
|
|
|
|
transfer_horizontal_border(writer, 0, y,
|
|
framebuffer.px_width);
|
|
|
|
transfer_horizontal_border(writer, 0, y + line_column_height,
|
|
framebuffer.px_width);
|
|
}
|
|
|
|
void draw_lines(ta_parameter_writer& writer, int x, int y)
|
|
{
|
|
using namespace interpreter;
|
|
|
|
y += 3 + 1;
|
|
|
|
int pattern_line_count = state.xm.pattern_note_count[state.pattern_index] / state.xm.number_of_channels;
|
|
for (int i = 0; i < line_rows; i++) {
|
|
int line_ix = state.line_index - line_rows_half + i;
|
|
if (line_ix >= 0 && line_ix < pattern_line_count)
|
|
draw_line(writer, line_ix, x, y);
|
|
y += glyph::vert_advance;
|
|
}
|
|
}
|
|
|
|
void draw_middle_line(ta_parameter_writer& writer, float x, float y)
|
|
{
|
|
using namespace interpreter;
|
|
|
|
int middle_width = line_column_width * (state.xm.number_of_channels) + (2 * glyph::hori_advance) + 2 + 3;
|
|
int middle_height = glyph::vert_advance - 1;
|
|
|
|
y += 3;
|
|
|
|
y += glyph::vert_advance * line_rows_half;
|
|
|
|
quad_type_0(writer,
|
|
{x + 0, y + 0, depth / 2.0},
|
|
{x + 0, y + 1, depth / 2.0},
|
|
{x + middle_width, y + 1, depth / 2.0},
|
|
{x + middle_width, y + 0, depth / 2.0},
|
|
0x555555);
|
|
|
|
y += 1;
|
|
|
|
quad_type_0(writer,
|
|
{x + 0, y + 0, depth / 2.0},
|
|
{x + 0, y + middle_height, depth / 2.0},
|
|
{x + middle_width, y + middle_height, depth / 2.0},
|
|
{x + middle_width, y + 0, depth / 2.0},
|
|
0x404040);
|
|
|
|
y += middle_width;
|
|
|
|
quad_type_0(writer,
|
|
{x + 0, y + 0, depth / 2.0},
|
|
{x + 0, y + 1, depth / 2.0},
|
|
{x + middle_width, y + 1, depth / 2.0},
|
|
{x + middle_width, y + 0, depth / 2.0},
|
|
0x202020);
|
|
}
|
|
|
|
void draw(ta_multiwriter& multi, float x, float y)
|
|
{
|
|
transfer_global_polygon_glyph(multi.pt);
|
|
|
|
draw_lines(multi.pt, x, y);
|
|
|
|
global_polygon_untextured(multi.op,
|
|
para_control::list_type::opaque,
|
|
tsp_instruction_word::dst_alpha_instr::zero);
|
|
draw_borders(multi.op, x, y);
|
|
|
|
draw_middle_line(multi.op, x, y);
|
|
}
|
|
|
|
}
|