demo: add font

This commit is contained in:
Zack Buhman 2025-07-16 21:12:04 -05:00
parent eaba4457c0
commit fc8ac2170e
13 changed files with 346 additions and 76 deletions

View File

@ -1,3 +1,6 @@
FONT_OBJ = \
font/ter_u12n.data.o
DEMO_OBJ = \
$(LIB)/holly/core.o \
$(LIB)/holly/region_array.o \
@ -14,7 +17,9 @@ DEMO_OBJ = \
src/demo/graphics.o \
src/demo/input.o \
src/demo/ballistics.o \
src/demo/texture.o \
src/demo/font.o \
src/physics/particle.o \
demo.elf: LDSCRIPT = $(LIB)/main.lds
demo.elf: $(START_OBJ) $(DEMO_OBJ) $(LIBGCC)
demo.elf: $(START_OBJ) $(DEMO_OBJ) $(FONT_OBJ) $(LIBGCC)

BIN
font/ter_u12n.data Normal file

Binary file not shown.

15
font/ter_u12n.data.h Normal file
View File

@ -0,0 +1,15 @@
#pragma once
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
extern uint32_t _binary_font_ter_u12n_data_start __asm("_binary_font_ter_u12n_data_start");
extern uint32_t _binary_font_ter_u12n_data_end __asm("_binary_font_ter_u12n_data_end");
extern uint32_t _binary_font_ter_u12n_data_size __asm("_binary_font_ter_u12n_data_size");
#ifdef __cplusplus
}
#endif

View File

@ -91,6 +91,8 @@ namespace demo {
void ballistics::draw(ta_parameter_writer& writer, const mat4x4& trans)
{
draw_grid(writer, trans * translate(vec3(0, 0, 50)) * scale(vec3(20, 10, 100)));
for (int i = 0; i < max_projectiles; i++) {
projectile * projectile = &projectiles[i];
if (projectile->type == projectile_type::NONE)

View File

@ -4,6 +4,7 @@
#include "demo/graphics.hpp"
#include "demo/input.hpp"
#include "demo/texture.hpp"
#include "printf/printf.h"
void vbr100()
@ -59,6 +60,8 @@ void main()
input::init();
graphics::init();
texture::init();
printf("texture init\n");
interrupt_init();
system.IML6NRM = istnrm::end_of_render_tsp

84
src/demo/font.cpp Normal file
View File

@ -0,0 +1,84 @@
#include "holly/isp_tsp.hpp"
#include "demo/font.hpp"
#include "demo/ta_parameter_presets.hpp"
#include "demo/texture.hpp"
namespace font {
static inline vec2 transform_glyph_texture(const face& face, const vec2& t, int char_code)
{
int row = char_code / face.row_stride;
int col = char_code % face.row_stride;
return {
(float)(col * face.width + t.x * face.width) / (float)(face.texture_width),
(float)(row * face.height + t.y * face.height) / (float)(face.texture_height),
};
}
static inline vec3 transform_glyph_position(const face& face, const vec2& p, float x, float y, float z)
{
return {
p.x * face.width + x,
p.y * face.height + y,
z
};
}
void face::global(ta_parameter_writer& writer) const
{
global_polygon_textured(writer,
para_control::list_type::punch_through,
texture_offset,
texture_size | tsp_instruction_word::dst_alpha_instr::inverse_src_alpha,
texture_control_word::pixel_format::_4bpp_palette);
}
void face::draw_glyph(ta_parameter_writer& writer,
const vec3& p,
int c,
uint32_t base_color) const
{
static const vec2 vtx[] = {
{ 0, 0 },
{ 1, 0 },
{ 1, 1 },
{ 0, 1 },
};
if (c <= 0x20 || c >= 0x7f) {
return;
}
c -= 0x20;
vec3 ap = transform_glyph_position(*this, vtx[0], p.x, p.y, p.z);
vec3 bp = transform_glyph_position(*this, vtx[1], p.x, p.y, p.z);
vec3 cp = transform_glyph_position(*this, vtx[2], p.x, p.y, p.z);
vec3 dp = transform_glyph_position(*this, vtx[3], p.x, p.y, p.z);
vec2 at = transform_glyph_texture(*this, vtx[0], c);
vec2 bt = transform_glyph_texture(*this, vtx[1], c);
vec2 ct = transform_glyph_texture(*this, vtx[2], c);
vec2 dt = transform_glyph_texture(*this, vtx[3], c);
quad_type_3(writer,
ap, at,
bp, bt,
cp, ct,
dp, dt,
base_color);
}
const face ter_u12n = {
.texture_size = tsp_instruction_word::texture_u_size::from_int(128)
| tsp_instruction_word::texture_v_size::from_int(64),
.texture_offset = texture::offset::ter_u12n,
.texture_width = 128,
.texture_height = 64,
.hori_advance = 6,
.width = 6,
.height = 12,
.row_stride = 21,
};
};

28
src/demo/font.hpp Normal file
View File

@ -0,0 +1,28 @@
#include <stdint.h>
#include "math/float_types.hpp"
#include "holly/ta_parameter.hpp"
namespace font {
struct face {
uint32_t texture_size;
uint32_t texture_offset;
int16_t texture_width;
int16_t texture_height;
int8_t hori_advance;
int8_t width;
int8_t height;
int8_t row_stride;
void global(ta_parameter_writer& writer) const;
void draw_glyph(ta_parameter_writer& writer,
const vec3& p,
int c,
uint32_t base_color) const;
};
extern const face ter_u12n;
}

View File

@ -14,21 +14,22 @@
#include "holly/ta_fifo_texture_memory_transfer.hpp"
#include "holly/ta_fifo_polygon_converter.hpp"
#include "ta_parameter_presets.hpp"
#include "math/float_types.hpp"
#include "math/transform.hpp"
#include "demo/ta_parameter_presets.hpp"
#include "demo/graphics_primitive.hpp"
#include "demo/graphics.hpp"
#include "demo/ballistics.hpp"
#include "demo/input.hpp"
#include "demo/font.hpp"
#include "maple/maple_bus_bits.hpp"
namespace graphics {
static uint8_t op_buf[1024 * 1024] __attribute__((aligned(32)));
static ta_parameter_writer writer(op_buf, (sizeof (op_buf)));
static uint8_t ta_buf[1024 * 1024] __attribute__((aligned(32)));
static ta_parameter_writer writer(ta_buf, (sizeof (ta_buf)));
static volatile int ta_in_use = 0;
static volatile int core_in_use = 0;
@ -37,7 +38,7 @@ namespace graphics {
static volatile int next_frame_ix = 0;
constexpr uint32_t ta_alloc
= ta_alloc_ctrl::pt_opb::no_list
= ta_alloc_ctrl::pt_opb::_32x4byte
| ta_alloc_ctrl::tm_opb::no_list
| ta_alloc_ctrl::t_opb::no_list
| ta_alloc_ctrl::om_opb::no_list
@ -48,7 +49,7 @@ namespace graphics {
.opaque_modifier = 0,
.translucent = 0,
.translucent_modifier = 0,
.punch_through = 0
.punch_through = 32 * 4
};
mat4x4 view_trans;
@ -93,10 +94,13 @@ namespace graphics {
void draw()
{
draw_grid(writer, view_trans);
draw_axis(writer, view_trans);
font::ter_u12n.global(writer);
font::ter_u12n.draw_glyph(writer, vec3(10, 10, 10), 'a', 0xffffffff);
//draw_cube(writer, view_trans * scale(0.1f), {1, 1, 0});
writer.append<ta_global_parameter::end_of_list>() =
ta_global_parameter::end_of_list(para_control::para_type::end_of_list);
draw_axis(writer, view_trans);
b.draw(writer, view_trans * scale(0.05f));
@ -185,8 +189,6 @@ namespace graphics {
}
}
static int tick = 0;
void step()
{
view_transform();

View File

@ -1,7 +1,8 @@
#include "ta_parameter_presets.hpp"
#include "math/math.hpp"
#include "holly/framebuffer.hpp"
#include "demo/ta_parameter_presets.hpp"
#define _fsrra(n) (1.0f / (sqrt<float>(n)))
static inline void draw_line(ta_parameter_writer& writer,
@ -47,7 +48,7 @@ static inline void draw_grid(ta_parameter_writer& writer,
for (int i = 1; i < 10; i++) {
float x = (float)i * 0.1f - 0.5f;
{
if (0) {
vec3 p1 = screen_transform(trans * vec3(x, 0, 0.5));
vec3 p2 = screen_transform(trans * vec3(x, 0, -0.5));
draw_line(writer, p1, p2);

View File

@ -0,0 +1,130 @@
#pragma once
#include "holly/ta_parameter.hpp"
#include "holly/ta_vertex_parameter.hpp"
#include "holly/ta_global_parameter.hpp"
#include "holly/isp_tsp.hpp"
#include "holly/texture_memory_alloc9.hpp"
#include "math/float_types.hpp"
static inline void global_polygon_intensity(ta_parameter_writer& writer,
const vec3& color)
{
const uint32_t parameter_control_word = para_control::para_type::polygon_or_modifier_volume
| para_control::list_type::opaque
| obj_control::col_type::intensity_mode_1
;
const uint32_t isp_tsp_instruction_word = isp_tsp_instruction_word::depth_compare_mode::greater_or_equal
| isp_tsp_instruction_word::culling_mode::no_culling;
const uint32_t tsp_instruction_word = tsp_instruction_word::texture_shading_instruction::decal
| tsp_instruction_word::src_alpha_instr::one
| tsp_instruction_word::dst_alpha_instr::zero
| tsp_instruction_word::fog_control::no_fog;
const uint32_t texture_control_word = 0;
writer.append<ta_global_parameter::polygon_type_1>() =
ta_global_parameter::polygon_type_1(parameter_control_word,
isp_tsp_instruction_word,
tsp_instruction_word,
texture_control_word,
1.0f, color.x, color.y, color.z);
}
static inline void global_polygon_textured(ta_parameter_writer& writer,
uint32_t list_type,
uint32_t texture_offset,
uint32_t texture_size,
uint32_t pixel_format)
{
const uint32_t parameter_control_word = para_control::para_type::polygon_or_modifier_volume
| list_type
| obj_control::col_type::packed_color
| obj_control::texture
;
const uint32_t isp_tsp_instruction_word = isp_tsp_instruction_word::depth_compare_mode::greater_or_equal
| isp_tsp_instruction_word::culling_mode::no_culling;
const uint32_t tsp_instruction_word = tsp_instruction_word::texture_shading_instruction::modulate
| tsp_instruction_word::src_alpha_instr::one
| tsp_instruction_word::fog_control::no_fog
| texture_size;
const uint32_t texture_address = texture_memory_alloc.texture.start + texture_offset;
const uint32_t texture_control_word = pixel_format
| texture_control_word::scan_order::twiddled
| texture_control_word::texture_address(texture_address / 8);
writer.append<ta_global_parameter::polygon_type_0>() =
ta_global_parameter::polygon_type_0(parameter_control_word,
isp_tsp_instruction_word,
tsp_instruction_word,
texture_control_word,
0, // data_size_for_sort_dma
0 // next_address_for_sort_dma
);
}
static inline void quad_type_2(ta_parameter_writer& writer,
const vec3& ap,
const vec3& bp,
const vec3& cp,
const vec3& dp,
float base_intensity)
{
writer.append<ta_vertex_parameter::polygon_type_2>() =
ta_vertex_parameter::polygon_type_2(polygon_vertex_parameter_control_word(false),
ap.x, ap.y, ap.z,
base_intensity);
writer.append<ta_vertex_parameter::polygon_type_2>() =
ta_vertex_parameter::polygon_type_2(polygon_vertex_parameter_control_word(false),
bp.x, bp.y, bp.z,
base_intensity);
writer.append<ta_vertex_parameter::polygon_type_2>() =
ta_vertex_parameter::polygon_type_2(polygon_vertex_parameter_control_word(false),
dp.x, dp.y, dp.z,
base_intensity);
writer.append<ta_vertex_parameter::polygon_type_2>() =
ta_vertex_parameter::polygon_type_2(polygon_vertex_parameter_control_word(true),
cp.x, cp.y, cp.z,
base_intensity);
}
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,
uint32_t base_color)
{
writer.append<ta_vertex_parameter::polygon_type_3>() =
ta_vertex_parameter::polygon_type_3(polygon_vertex_parameter_control_word(false),
ap.x, ap.y, ap.z,
at.x, at.y,
base_color, 0);
writer.append<ta_vertex_parameter::polygon_type_3>() =
ta_vertex_parameter::polygon_type_3(polygon_vertex_parameter_control_word(false),
bp.x, bp.y, bp.z,
bt.x, bt.y,
base_color, 0);
writer.append<ta_vertex_parameter::polygon_type_3>() =
ta_vertex_parameter::polygon_type_3(polygon_vertex_parameter_control_word(false),
dp.x, dp.y, dp.z,
dt.x, dt.y,
base_color, 0);
writer.append<ta_vertex_parameter::polygon_type_3>() =
ta_vertex_parameter::polygon_type_3(polygon_vertex_parameter_control_word(true),
cp.x, cp.y, cp.z,
ct.x, ct.y,
base_color, 0);
}

55
src/demo/texture.cpp Normal file
View File

@ -0,0 +1,55 @@
#include "texture.hpp"
#include "systembus.hpp"
#include "holly/holly.hpp"
#include "holly/core_bits.hpp"
#include "holly/texture_memory_alloc9.hpp"
#include "holly/ta_fifo_texture_memory_transfer.hpp"
#include "font/ter_u12n.data.h"
namespace texture {
struct entry {
void * start;
int size;
int offset;
};
const entry textures[] = {
{
.start = reinterpret_cast<void *>(&_binary_font_ter_u12n_data_start),
.size = reinterpret_cast<int>(&_binary_font_ter_u12n_data_size),
.offset = offset::ter_u12n,
},
};
const int textures_length = (sizeof (textures)) / (sizeof (textures[0]));
static inline void transfer_palettes()
{
holly.PAL_RAM_CTRL = pal_ram_ctrl::pixel_format::argb4444;
holly.PALETTE_RAM[0] = 0;
holly.PALETTE_RAM[1] = 0xffff;
holly.PT_ALPHA_REF = 0xf0;
}
void init()
{
system.LMMODE0 = 0; // 64-bit address space
system.LMMODE1 = 0; // 64-bit address space
for (int i = 0; i < textures_length; i++) {
uint32_t offset = texture_memory_alloc.texture.start + textures[i].offset;
void * dst = reinterpret_cast<void *>(&ta_fifo_texture_memory[offset / 4]);
void * src = textures[i].start;
int size = textures[i].size;
ta_fifo_texture_memory_transfer::copy(dst, src, size);
}
transfer_palettes();
}
}

7
src/demo/texture.hpp Normal file
View File

@ -0,0 +1,7 @@
namespace texture {
namespace offset {
constexpr int ter_u12n = 0;
}
void init();
}

View File

@ -1,62 +0,0 @@
#pragma once
#include "holly/ta_parameter.hpp"
#include "holly/ta_vertex_parameter.hpp"
#include "holly/ta_global_parameter.hpp"
#include "holly/isp_tsp.hpp"
#include "math/float_types.hpp"
static inline void global_polygon_intensity(ta_parameter_writer& writer,
const vec3& color)
{
const uint32_t parameter_control_word = para_control::para_type::polygon_or_modifier_volume
| para_control::list_type::opaque
| obj_control::col_type::intensity_mode_1
;
const uint32_t isp_tsp_instruction_word = isp_tsp_instruction_word::depth_compare_mode::greater_or_equal
| isp_tsp_instruction_word::culling_mode::no_culling;
const uint32_t tsp_instruction_word = tsp_instruction_word::texture_shading_instruction::decal
| tsp_instruction_word::src_alpha_instr::one
| tsp_instruction_word::dst_alpha_instr::zero
| tsp_instruction_word::fog_control::no_fog;
const uint32_t texture_control_word = 0;
writer.append<ta_global_parameter::polygon_type_1>() =
ta_global_parameter::polygon_type_1(parameter_control_word,
isp_tsp_instruction_word,
tsp_instruction_word,
texture_control_word,
1.0f, color.x, color.y, color.z);
}
static inline void quad_type_2(ta_parameter_writer& writer,
const vec3& ap,
const vec3& bp,
const vec3& cp,
const vec3& dp,
float base_intensity)
{
writer.append<ta_vertex_parameter::polygon_type_2>() =
ta_vertex_parameter::polygon_type_2(polygon_vertex_parameter_control_word(false),
ap.x, ap.y, ap.z,
base_intensity);
writer.append<ta_vertex_parameter::polygon_type_2>() =
ta_vertex_parameter::polygon_type_2(polygon_vertex_parameter_control_word(false),
bp.x, bp.y, bp.z,
base_intensity);
writer.append<ta_vertex_parameter::polygon_type_2>() =
ta_vertex_parameter::polygon_type_2(polygon_vertex_parameter_control_word(false),
dp.x, dp.y, dp.z,
base_intensity);
writer.append<ta_vertex_parameter::polygon_type_2>() =
ta_vertex_parameter::polygon_type_2(polygon_vertex_parameter_control_word(true),
cp.x, cp.y, cp.z,
base_intensity);
}