xm_player/src/graphics_primitive.cpp
2025-06-30 15:04:24 -05:00

177 lines
5.0 KiB
C++

#include "printf/unparse.h"
#include "ta_parameter.hpp"
#include "graphics_primitive.hpp"
#include "texture.hpp"
struct vertex {
vec2 p;
vec2 t;
};
const vertex quad_vertices[] = {
{ { 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)
{
int row = char_code / glyph::row_stride;
int col = char_code % glyph::row_stride;
return {
(float)(col * glyph::width + t.x * glyph::width) / (float)(glyph::texture_width),
(float)(row * glyph::height + t.y * glyph::height) / (float)(glyph::texture_height),
};
}
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,
z
};
}
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::inverse_src_alpha;
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, 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);
vec2 ct = transform_glyph_texture(quad_vertices[2].t, c);
vec2 dt = transform_glyph_texture(quad_vertices[3].t, c);
quad_type_3(writer,
ap, at,
bp, bt,
cp, ct,
dp, dt,
base_color);
}
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, z, base_color);
x += glyph::hori_advance;
}
return len;
}
int transfer_integer(ta_parameter_writer& writer, int n,
float x, float y, float z,
int length, int fill,
int base_color)
{
char buf[16];
int len = unparse_base10(buf, n, length, fill);
buf[len] = 0;
transfer_string(writer, buf, x, y, z, base_color);
return len;
}
int transfer_hex_integer(ta_parameter_writer& writer, int n,
float x, float y, float z,
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, z, base_color);
return len;
}
void transfer_rectangle(ta_parameter_writer& writer,
float x, float y, float z,
float width, float height,
int base_color)
{
quad_type_0(writer,
{x + 0, y + 0, z},
{x + width, y + 0, z},
{x + width, y + height, z},
{x + 0, y + height, z},
base_color);
}
void transfer_vertical_border(ta_parameter_writer& writer, float x, float y, int length)
{
quad_type_0(writer,
{x + 0, y + 0, 1.0/7.0},
{x + 1, y + 0, 1.0/7.0},
{x + 1, y + length, 1.0/7.0},
{x + 0, y + length, 1.0/7.0},
0x2a3536);
quad_type_0(writer,
{x + 1, y + 0, 1.0/5.0},
{x + 2, y + 0, 1.0/5.0},
{x + 2, y + length, 1.0/5.0},
{x + 1, y + length, 1.0/5.0},
0x202829);
quad_type_0(writer,
{x + 2, y + 0, 1.0/10.0},
{x + 3, y + 0, 1.0/10.0},
{x + 3, y + length, 1.0/10.0},
{x + 2, y + length, 1.0/10.0},
0x101414);
}
void transfer_horizontal_border(ta_parameter_writer& writer, float x, float y, int length)
{
quad_type_0(writer,
{x + 0, y + 0, 1.0/7.0},
{x + 0, y + 1, 1.0/7.0},
{x + length, y + 1, 1.0/7.0},
{x + length, y + 0, 1.0/7.0},
0x2a3536);
quad_type_0(writer,
{x + 0, y + 1, 1.0/5.0},
{x + 0, y + 2, 1.0/5.0},
{x + length, y + 2, 1.0/5.0},
{x + length, y + 1, 1.0/5.0},
0x202829);
quad_type_0(writer,
{x + 0, y + 2, 1.0/10.0},
{x + 0, y + 3, 1.0/10.0},
{x + length, y + 3, 1.0/10.0},
{x + length, y + 2, 1.0/10.0},
0x101414);
}