example: suzanne_profile: incomplete
This has turned in to an experiment related to texture sampling behavior on the Dreamcast.
This commit is contained in:
parent
0381d356bb
commit
f400fe6412
BIN
europc_mono.data
Normal file
BIN
europc_mono.data
Normal file
Binary file not shown.
7
europc_mono.hpp
Normal file
7
europc_mono.hpp
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
extern uint32_t _binary_europc_mono_data_start __asm("_binary_europc_mono_data_start");
|
||||||
|
extern uint32_t _binary_europc_mono_data_end __asm("_binary_europc_mono_data_end");
|
||||||
|
extern uint32_t _binary_europc_mono_data_size __asm("_binary_europc_mono_data_size");
|
@ -115,6 +115,20 @@ ICOSPHERE_OBJ = \
|
|||||||
example/icosphere.elf: LDSCRIPT = $(LIB)/alt.lds
|
example/icosphere.elf: LDSCRIPT = $(LIB)/alt.lds
|
||||||
example/icosphere.elf: $(START_OBJ) $(ICOSPHERE_OBJ)
|
example/icosphere.elf: $(START_OBJ) $(ICOSPHERE_OBJ)
|
||||||
|
|
||||||
|
SUZANNE_PROFILE_OBJ = \
|
||||||
|
example/suzanne_profile.o \
|
||||||
|
vga.o \
|
||||||
|
holly/core.o \
|
||||||
|
holly/region_array.o \
|
||||||
|
holly/background.o \
|
||||||
|
holly/ta_fifo_polygon_converter.o \
|
||||||
|
font/font_bitmap.o \
|
||||||
|
sh7091/serial.o \
|
||||||
|
europc_mono.data.o
|
||||||
|
|
||||||
|
example/suzanne_profile.elf: LDSCRIPT = $(LIB)/alt.lds
|
||||||
|
example/suzanne_profile.elf: $(START_OBJ) $(SUZANNE_PROFILE_OBJ)
|
||||||
|
|
||||||
WIFFLE_ATTENUATION_OBJ = \
|
WIFFLE_ATTENUATION_OBJ = \
|
||||||
example/wiffle_attenuation.o \
|
example/wiffle_attenuation.o \
|
||||||
vga.o \
|
vga.o \
|
||||||
|
326
example/suzanne_profile.cpp
Normal file
326
example/suzanne_profile.cpp
Normal file
@ -0,0 +1,326 @@
|
|||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
#include "align.hpp"
|
||||||
|
#include "vga.hpp"
|
||||||
|
|
||||||
|
#include "holly/holly.hpp"
|
||||||
|
#include "holly/core.hpp"
|
||||||
|
#include "holly/core_bits.hpp"
|
||||||
|
#include "holly/ta_fifo_polygon_converter.hpp"
|
||||||
|
#include "holly/ta_parameter.hpp"
|
||||||
|
#include "holly/ta_global_parameter.hpp"
|
||||||
|
#include "holly/ta_vertex_parameter.hpp"
|
||||||
|
#include "holly/isp_tsp.hpp"
|
||||||
|
#include "holly/ta_bits.hpp"
|
||||||
|
#include "holly/region_array.hpp"
|
||||||
|
#include "holly/background.hpp"
|
||||||
|
#include "holly/texture_memory_alloc.hpp"
|
||||||
|
#include "memorymap.hpp"
|
||||||
|
|
||||||
|
#include "geometry/suzanne.hpp"
|
||||||
|
#include "math/vec4.hpp"
|
||||||
|
|
||||||
|
#include "font/font_bitmap.hpp"
|
||||||
|
#include "europc_mono.hpp"
|
||||||
|
|
||||||
|
constexpr float half_degree = 0.01745329f / 2;
|
||||||
|
|
||||||
|
#define MODEL suzanne
|
||||||
|
|
||||||
|
vec3 rotate(const vec3& vertex,
|
||||||
|
const float theta)
|
||||||
|
{
|
||||||
|
float x = vertex.x;
|
||||||
|
float y = vertex.y;
|
||||||
|
float z = vertex.z;
|
||||||
|
float t;
|
||||||
|
|
||||||
|
t = y * cos(theta) - z * sin(theta);
|
||||||
|
z = y * sin(theta) + z * cos(theta);
|
||||||
|
y = t;
|
||||||
|
|
||||||
|
float theta2 = 3.14 * sin(theta / 2);
|
||||||
|
|
||||||
|
t = x * cos(theta2) - z * sin(theta2);
|
||||||
|
z = x * sin(theta2) + z * cos(theta2);
|
||||||
|
x = t;
|
||||||
|
|
||||||
|
return vec3(x, y, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
void transform(ta_parameter_writer& parameter,
|
||||||
|
const uint32_t face_ix,
|
||||||
|
const float theta,
|
||||||
|
const vec3 lights[3])
|
||||||
|
{
|
||||||
|
const uint32_t parameter_control_word = para_control::para_type::polygon_or_modifier_volume
|
||||||
|
| para_control::list_type::opaque
|
||||||
|
| obj_control::col_type::floating_color
|
||||||
|
| obj_control::gouraud;
|
||||||
|
|
||||||
|
const uint32_t isp_tsp_instruction_word = isp_tsp_instruction_word::depth_compare_mode::greater
|
||||||
|
| isp_tsp_instruction_word::culling_mode::cull_if_positive;
|
||||||
|
|
||||||
|
const uint32_t tsp_instruction_word = tsp_instruction_word::src_alpha_instr::one
|
||||||
|
| tsp_instruction_word::dst_alpha_instr::zero
|
||||||
|
| tsp_instruction_word::fog_control::no_fog;
|
||||||
|
|
||||||
|
parameter.append<ta_global_parameter::polygon_type_0>() =
|
||||||
|
ta_global_parameter::polygon_type_0(parameter_control_word,
|
||||||
|
isp_tsp_instruction_word,
|
||||||
|
tsp_instruction_word,
|
||||||
|
0, // texture_control_word
|
||||||
|
0, // data_size_for_sort_dma
|
||||||
|
0 // next_address_for_sort_dma
|
||||||
|
);
|
||||||
|
auto& face = MODEL::faces[face_ix];
|
||||||
|
|
||||||
|
constexpr uint32_t strip_length = 3;
|
||||||
|
for (uint32_t i = 0; i < strip_length; i++) {
|
||||||
|
// world transform
|
||||||
|
uint32_t vertex_ix = face[i].vertex;
|
||||||
|
auto& vertex = MODEL::vertices[vertex_ix];
|
||||||
|
auto point = rotate(vertex, theta);
|
||||||
|
|
||||||
|
// lighting transform
|
||||||
|
uint32_t normal_ix = face[i].normal;
|
||||||
|
auto& normal = MODEL::normals[normal_ix];
|
||||||
|
auto n = rotate(normal, theta);
|
||||||
|
|
||||||
|
vec4 color = {0.2, 0.2, 0.2, 1.0};
|
||||||
|
|
||||||
|
// intensity calculation
|
||||||
|
{
|
||||||
|
auto l = lights[0] - point;
|
||||||
|
auto n_dot_l = dot(n, l);
|
||||||
|
if (n_dot_l > 0) {
|
||||||
|
color.x += 0.6 * n_dot_l / (length(n) * length(l));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto l = lights[1] - point;
|
||||||
|
auto n_dot_l = dot(n, l);
|
||||||
|
if (n_dot_l > 0) {
|
||||||
|
color.y += 0.6 * n_dot_l / (length(n) * length(l));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto l = lights[2] - point;
|
||||||
|
auto n_dot_l = dot(n, l);
|
||||||
|
if (n_dot_l > 0) {
|
||||||
|
color.z += 0.6 * n_dot_l / (length(n) * length(l));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
float x = point.x;
|
||||||
|
float y = point.y;
|
||||||
|
float z = point.z;
|
||||||
|
|
||||||
|
x *= 10;
|
||||||
|
y *= 10;
|
||||||
|
z *= 10;
|
||||||
|
|
||||||
|
// camera transform
|
||||||
|
z += 20;
|
||||||
|
|
||||||
|
// perspective
|
||||||
|
x = x / z;
|
||||||
|
y = y / z;
|
||||||
|
|
||||||
|
// screen space transform
|
||||||
|
x *= 240.f;
|
||||||
|
y *= 240.f;
|
||||||
|
x += 320.f;
|
||||||
|
y += 240.f;
|
||||||
|
z = 1 / z;
|
||||||
|
|
||||||
|
bool end_of_strip = i == strip_length - 1;
|
||||||
|
parameter.append<ta_vertex_parameter::polygon_type_1>() =
|
||||||
|
ta_vertex_parameter::polygon_type_1(polygon_vertex_parameter_control_word(end_of_strip),
|
||||||
|
x, y, z,
|
||||||
|
color.w, // alpha
|
||||||
|
color.x, // r
|
||||||
|
color.y, // g
|
||||||
|
color.z // b
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void transform2(ta_parameter_writer& parameter,
|
||||||
|
const vec3& pos,
|
||||||
|
const vec4& color)
|
||||||
|
{
|
||||||
|
const uint32_t parameter_control_word = para_control::para_type::polygon_or_modifier_volume
|
||||||
|
| para_control::list_type::opaque
|
||||||
|
| obj_control::col_type::floating_color
|
||||||
|
| obj_control::gouraud;
|
||||||
|
|
||||||
|
const uint32_t isp_tsp_instruction_word = isp_tsp_instruction_word::depth_compare_mode::greater
|
||||||
|
| isp_tsp_instruction_word::culling_mode::no_culling;
|
||||||
|
|
||||||
|
const uint32_t tsp_instruction_word = tsp_instruction_word::src_alpha_instr::one
|
||||||
|
| tsp_instruction_word::dst_alpha_instr::zero
|
||||||
|
| tsp_instruction_word::fog_control::no_fog;
|
||||||
|
|
||||||
|
parameter.append<ta_global_parameter::polygon_type_0>() =
|
||||||
|
ta_global_parameter::polygon_type_0(parameter_control_word,
|
||||||
|
isp_tsp_instruction_word,
|
||||||
|
tsp_instruction_word,
|
||||||
|
0, // texture_control_word
|
||||||
|
0, // data_size_for_sort_dma
|
||||||
|
0 // next_address_for_sort_dma
|
||||||
|
);
|
||||||
|
|
||||||
|
constexpr vec3 triangle[] = {
|
||||||
|
{ 0.f, -1.f, 0.f},
|
||||||
|
{-1.f, 1.f, 0.f},
|
||||||
|
{ 1.f, 1.f, 0.f},
|
||||||
|
};
|
||||||
|
|
||||||
|
constexpr uint32_t strip_length = 3;
|
||||||
|
for (uint32_t i = 0; i < strip_length; i++) {
|
||||||
|
float x = triangle[i].x;
|
||||||
|
float y = triangle[i].y;
|
||||||
|
float z = triangle[i].z;
|
||||||
|
|
||||||
|
x *= 0.2;
|
||||||
|
y *= 0.2;
|
||||||
|
z *= 0.2;
|
||||||
|
|
||||||
|
x += pos.x;
|
||||||
|
y += pos.y;
|
||||||
|
z += pos.z;
|
||||||
|
|
||||||
|
// camera transform
|
||||||
|
z += 20;
|
||||||
|
|
||||||
|
// perspective
|
||||||
|
x = x / z;
|
||||||
|
y = y / z;
|
||||||
|
|
||||||
|
// screen space transform
|
||||||
|
x *= 240.f;
|
||||||
|
y *= 240.f;
|
||||||
|
x += 320.f;
|
||||||
|
y += 240.f;
|
||||||
|
z = 1 / z;
|
||||||
|
|
||||||
|
bool end_of_strip = i == strip_length - 1;
|
||||||
|
parameter.append<ta_vertex_parameter::polygon_type_1>() =
|
||||||
|
ta_vertex_parameter::polygon_type_1(polygon_vertex_parameter_control_word(end_of_strip),
|
||||||
|
x, y, z,
|
||||||
|
color.w, // alpha
|
||||||
|
color.x, // r
|
||||||
|
color.y, // g
|
||||||
|
color.z // b
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void init_texture_memory(const struct opb_size& opb_size)
|
||||||
|
{
|
||||||
|
auto mem = reinterpret_cast<volatile texture_memory_alloc *>(texture_memory32);
|
||||||
|
|
||||||
|
background_parameter(mem->background, 0xff220000);
|
||||||
|
|
||||||
|
region_array2(mem->region_array,
|
||||||
|
(offsetof (struct texture_memory_alloc, object_list)),
|
||||||
|
640 / 32, // width
|
||||||
|
480 / 32, // height
|
||||||
|
opb_size
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t _ta_parameter_buf[((32 * 8192) + 32) / 4];
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
vga();
|
||||||
|
|
||||||
|
auto src = reinterpret_cast<const uint8_t *>(&_binary_europc_mono_data_start);
|
||||||
|
font_bitmap::inflate(2, // pitch
|
||||||
|
9, // width
|
||||||
|
14, // height
|
||||||
|
16, // texture_width
|
||||||
|
16, // texture_height
|
||||||
|
src);
|
||||||
|
font_bitmap::palette_data();
|
||||||
|
|
||||||
|
// The address of `ta_parameter_buf` must be a multiple of 32 bytes.
|
||||||
|
// This is mandatory for ch2-dma to the ta fifo polygon converter.
|
||||||
|
uint32_t * ta_parameter_buf = align_32byte(_ta_parameter_buf);
|
||||||
|
|
||||||
|
constexpr uint32_t ta_alloc = ta_alloc_ctrl::pt_opb::no_list
|
||||||
|
| ta_alloc_ctrl::tm_opb::no_list
|
||||||
|
| ta_alloc_ctrl::t_opb::no_list
|
||||||
|
| ta_alloc_ctrl::om_opb::no_list
|
||||||
|
| ta_alloc_ctrl::o_opb::_16x4byte;
|
||||||
|
|
||||||
|
constexpr struct opb_size opb_size = { .opaque = 16 * 4
|
||||||
|
, .opaque_modifier = 0
|
||||||
|
, .translucent = 0
|
||||||
|
, .translucent_modifier = 0
|
||||||
|
, .punch_through = 0
|
||||||
|
};
|
||||||
|
|
||||||
|
holly.SOFTRESET = softreset::pipeline_soft_reset
|
||||||
|
| softreset::ta_soft_reset;
|
||||||
|
holly.SOFTRESET = 0;
|
||||||
|
|
||||||
|
core_init();
|
||||||
|
init_texture_memory(opb_size);
|
||||||
|
|
||||||
|
uint32_t frame_ix = 0;
|
||||||
|
constexpr uint32_t num_frames = 1;
|
||||||
|
|
||||||
|
float theta = 0;
|
||||||
|
vec3 lights[3] = {
|
||||||
|
{0.f, 0.f, 0.f},
|
||||||
|
{0.f, 0.f, 0.f},
|
||||||
|
{0.f, 0.f, 0.f},
|
||||||
|
};
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
ta_polygon_converter_init(opb_size.total(),
|
||||||
|
ta_alloc,
|
||||||
|
640 / 32,
|
||||||
|
480 / 32);
|
||||||
|
|
||||||
|
float theta2 = 3.14 * 2 * sin(theta / 7);
|
||||||
|
|
||||||
|
lights[0].x = cos(theta) * 15;
|
||||||
|
lights[0].z = sin(theta) * 15;
|
||||||
|
|
||||||
|
lights[1].x = cos(theta2 + half_degree * 180.f) * 15;
|
||||||
|
lights[1].z = sin(theta2 + half_degree * 180.f) * 15;
|
||||||
|
|
||||||
|
lights[2].x = cos(theta + half_degree * 360.f) * 15;
|
||||||
|
lights[2].z = sin(theta + half_degree * 360.f) * 15;
|
||||||
|
|
||||||
|
auto parameter = ta_parameter_writer(ta_parameter_buf);
|
||||||
|
for (uint32_t i = 0; i < MODEL::num_faces; i++) {
|
||||||
|
transform(parameter, i, theta, lights);
|
||||||
|
}
|
||||||
|
transform2(parameter, lights[0], {1.f, 0.f, 0.f, 1.f});
|
||||||
|
transform2(parameter, lights[1], {0.f, 1.f, 0.f, 1.f});
|
||||||
|
transform2(parameter, lights[2], {0.f, 0.f, 1.f, 1.f});
|
||||||
|
|
||||||
|
font_bitmap::transform_string(parameter,
|
||||||
|
16, 16, // texture
|
||||||
|
9, 14, // glyph
|
||||||
|
40, 40, // position
|
||||||
|
"test", 4);
|
||||||
|
|
||||||
|
parameter.append<ta_global_parameter::end_of_list>() = ta_global_parameter::end_of_list(para_control::para_type::end_of_list);
|
||||||
|
ta_polygon_converter_transfer(ta_parameter_buf, parameter.offset);
|
||||||
|
ta_wait_opaque_list();
|
||||||
|
core_start_render(frame_ix, num_frames);
|
||||||
|
|
||||||
|
v_sync_out();
|
||||||
|
core_wait_end_of_render_video(frame_ix, num_frames);
|
||||||
|
theta += half_degree;
|
||||||
|
frame_ix += 1;
|
||||||
|
}
|
||||||
|
}
|
173
font/font_bitmap.cpp
Normal file
173
font/font_bitmap.cpp
Normal file
@ -0,0 +1,173 @@
|
|||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
#include "../holly/holly.hpp"
|
||||||
|
#include "../holly/core_bits.hpp"
|
||||||
|
#include "../holly/texture_memory_alloc.hpp"
|
||||||
|
#include "../holly/isp_tsp.hpp"
|
||||||
|
#include "../holly/ta_parameter.hpp"
|
||||||
|
#include "../holly/ta_global_parameter.hpp"
|
||||||
|
#include "../holly/ta_vertex_parameter.hpp"
|
||||||
|
#include "../memorymap.hpp"
|
||||||
|
#include "../twiddle.hpp"
|
||||||
|
|
||||||
|
#include "../sh7091/serial.hpp"
|
||||||
|
|
||||||
|
#include "font_bitmap.hpp"
|
||||||
|
|
||||||
|
namespace font_bitmap {
|
||||||
|
|
||||||
|
static inline void inflate_character(const uint32_t pitch,
|
||||||
|
const uint32_t width,
|
||||||
|
const uint32_t height,
|
||||||
|
const uint32_t texture_width,
|
||||||
|
const uint32_t texture_height,
|
||||||
|
const uint8_t * src,
|
||||||
|
const uint8_t c)
|
||||||
|
{
|
||||||
|
const uint32_t character_index = c - ' ';
|
||||||
|
const uint32_t offset = pitch * height * character_index;
|
||||||
|
uint8_t temp[texture_width * texture_height];
|
||||||
|
|
||||||
|
for (uint32_t y = 0; y < height; y++) {
|
||||||
|
for (uint32_t x = 0; x < width; x++) {
|
||||||
|
uint8_t row = src[offset + (y * pitch) + (x / 8)];
|
||||||
|
uint8_t px = (row >> (7 - (x % 8))) & 1;
|
||||||
|
//serial::character((px == 1) ? 'X' : '_');
|
||||||
|
uint16_t palette_index = px ? 2 : 1;
|
||||||
|
temp[y * texture_width + x] = palette_index;
|
||||||
|
}
|
||||||
|
for (uint32_t x = width; x < texture_width; x++) {
|
||||||
|
temp[y * texture_width + x] = 1;
|
||||||
|
}
|
||||||
|
//serial::character('\n');
|
||||||
|
}
|
||||||
|
for (uint32_t y = height; y < texture_height; y++) {
|
||||||
|
for (uint32_t x = 0; x < texture_width; x++) {
|
||||||
|
temp[y * texture_width + x] = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto mem = reinterpret_cast<volatile texture_memory_alloc *>(texture_memory64);
|
||||||
|
auto texture = reinterpret_cast<volatile uint32_t *>(mem->texture);
|
||||||
|
|
||||||
|
const uint32_t texture_offset = texture_width * texture_height * character_index / 2;
|
||||||
|
twiddle::texture2<4>(&texture[texture_offset / 4], // uint32_t *
|
||||||
|
temp,
|
||||||
|
texture_width,
|
||||||
|
texture_width * texture_height);
|
||||||
|
}
|
||||||
|
|
||||||
|
void inflate(const uint32_t pitch,
|
||||||
|
const uint32_t width,
|
||||||
|
const uint32_t height,
|
||||||
|
const uint32_t texture_width,
|
||||||
|
const uint32_t texture_height,
|
||||||
|
const uint8_t * src)
|
||||||
|
{
|
||||||
|
for (uint8_t ix = 0x20; ix < 0x7f; ix++) {
|
||||||
|
inflate_character(pitch,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
texture_width,
|
||||||
|
texture_height,
|
||||||
|
src,
|
||||||
|
ix);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void palette_data()
|
||||||
|
{
|
||||||
|
holly.PAL_RAM_CTRL = pal_ram_ctrl::pixel_format::rgb565;
|
||||||
|
|
||||||
|
holly.PALETTE_RAM[1] = 0x0000;
|
||||||
|
holly.PALETTE_RAM[2] = 0xffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct quad_vertex {
|
||||||
|
float x;
|
||||||
|
float y;
|
||||||
|
float z;
|
||||||
|
float u;
|
||||||
|
float v;
|
||||||
|
};
|
||||||
|
|
||||||
|
const struct quad_vertex quad_vertices[4] = {
|
||||||
|
// [ position ] [ uv coordinates ]
|
||||||
|
{ -0.5f, 0.5f, 0.f, 0.f, 1.f, },
|
||||||
|
{ -0.5f, -0.5f, 0.f, 0.f, 0.f, },
|
||||||
|
{ 0.5f, 0.5f, 0.f, 1.f, 1.f, },
|
||||||
|
{ 0.5f, -0.5f, 0.f, 1.f, 0.f, },
|
||||||
|
};
|
||||||
|
constexpr uint32_t quad_length = (sizeof (quad_vertices)) / (sizeof (struct quad_vertex));
|
||||||
|
|
||||||
|
void transform_string(ta_parameter_writer& parameter,
|
||||||
|
const uint32_t texture_width,
|
||||||
|
const uint32_t texture_height,
|
||||||
|
const uint32_t glyph_width,
|
||||||
|
const uint32_t glyph_height,
|
||||||
|
const int32_t position_x,
|
||||||
|
const int32_t position_y,
|
||||||
|
const char * s,
|
||||||
|
const uint32_t len
|
||||||
|
)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
|
||||||
|
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
|
||||||
|
| tsp_instruction_word::dst_alpha_instr::zero
|
||||||
|
| tsp_instruction_word::fog_control::no_fog
|
||||||
|
| tsp_instruction_word::texture_u_size::from_int(texture_width)
|
||||||
|
| tsp_instruction_word::texture_v_size::from_int(texture_height);
|
||||||
|
|
||||||
|
for (uint32_t string_ix = 0; string_ix < len; string_ix++) {
|
||||||
|
const uint32_t texture_address = (offsetof (struct texture_memory_alloc, texture));
|
||||||
|
const uint32_t glyph_address = texture_address + texture_width * texture_height * (s[string_ix] - ' ') / 2;
|
||||||
|
const uint32_t texture_control_word = texture_control_word::pixel_format::_4bpp_palette
|
||||||
|
| texture_control_word::scan_order::twiddled
|
||||||
|
| texture_control_word::texture_address(glyph_address / 8);
|
||||||
|
|
||||||
|
parameter.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
|
||||||
|
);
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < quad_length; i++) {
|
||||||
|
bool end_of_strip = i == quad_length - 1;
|
||||||
|
|
||||||
|
float x = quad_vertices[i].x;
|
||||||
|
float y = quad_vertices[i].y;
|
||||||
|
float z = quad_vertices[i].z;
|
||||||
|
float u = quad_vertices[i].u;
|
||||||
|
float v = quad_vertices[i].v;
|
||||||
|
|
||||||
|
x *= static_cast<float>(glyph_width * 1);
|
||||||
|
y *= static_cast<float>(glyph_height * 1);
|
||||||
|
x += static_cast<float>(position_x + glyph_width * 4 * string_ix);
|
||||||
|
y += static_cast<float>(position_y);
|
||||||
|
z = 1.f / (z + 10.f);
|
||||||
|
|
||||||
|
u *= static_cast<float>(glyph_width - 1) / static_cast<float>(texture_width);
|
||||||
|
v *= static_cast<float>(glyph_height - 1) / static_cast<float>(texture_height);
|
||||||
|
|
||||||
|
parameter.append<ta_vertex_parameter::polygon_type_3>() =
|
||||||
|
ta_vertex_parameter::polygon_type_3(polygon_vertex_parameter_control_word(end_of_strip),
|
||||||
|
x, y, z,
|
||||||
|
u, v,
|
||||||
|
0, // base_color
|
||||||
|
0 // offset_color
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
29
font/font_bitmap.hpp
Normal file
29
font/font_bitmap.hpp
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
#include "../holly/ta_parameter.hpp"
|
||||||
|
|
||||||
|
namespace font_bitmap {
|
||||||
|
|
||||||
|
void inflate(const uint32_t pitch,
|
||||||
|
const uint32_t width,
|
||||||
|
const uint32_t height,
|
||||||
|
const uint32_t texture_width,
|
||||||
|
const uint32_t texture_height,
|
||||||
|
const uint8_t * src);
|
||||||
|
|
||||||
|
void palette_data();
|
||||||
|
|
||||||
|
void transform_string(ta_parameter_writer& parameter,
|
||||||
|
const uint32_t texture_width,
|
||||||
|
const uint32_t texture_height,
|
||||||
|
const uint32_t glyph_width,
|
||||||
|
const uint32_t glyph_height,
|
||||||
|
const int32_t position_x,
|
||||||
|
const int32_t position_y,
|
||||||
|
const char * s,
|
||||||
|
const uint32_t len
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
@ -1,31 +0,0 @@
|
|||||||
|
|
||||||
|
|
||||||
uint32_t pixel_data(const uint32_t * dest, const uint8_t * glyph_bitmaps, const uint32_t size)
|
|
||||||
{
|
|
||||||
const uint8_t temp[size];
|
|
||||||
|
|
||||||
const uint32_t * buf = reinterpret_cast<const uint32_t *>(&glyph_bitmaps[0]);
|
|
||||||
|
|
||||||
copy<uint32_t>(table, buf, size);
|
|
||||||
|
|
||||||
return table_address;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t font_data(const uint32_t * buf, state& state)
|
|
||||||
{
|
|
||||||
constexpr uint32_t font_offset = 0;
|
|
||||||
constexpr uint32_t glyphs_offset = (sizeof (struct font));
|
|
||||||
const uint32_t glyph_bitmaps_offset = (sizeof (struct font)) + (sizeof (struct glyph)) * font->glyph_index;
|
|
||||||
|
|
||||||
auto font = reinterpret_cast<const font *>(&buf[font_offset / 4]);
|
|
||||||
auto glyphs = reinterpret_cast<const glyph *>(&buf[glyphs_offset / 4]);
|
|
||||||
auto glyph_bitmaps = &(reinterpret_cast<const uint8_t *>(buf))[glyph_bitmaps_offset];
|
|
||||||
|
|
||||||
for (uint32_t glyph_ix = 0; glyph_ix < font->glyph_index; glyph_ix++) {
|
|
||||||
auto& glyph_bitmap = glyphs[glyph_ix].bitmap;
|
|
||||||
|
|
||||||
auto bitmap = &glyph_bitmaps[glyph_bitmap.offset];
|
|
||||||
// bitmap.pitch may be zero; bitmap.pitch is a multiple of 8 pixels
|
|
||||||
SIZE__X(bitmap.pitch) | SIZE__Y(bitmap.rows);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,3 +1,5 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
|
|
||||||
@ -96,7 +98,7 @@ struct ta_parameter_writer {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
uint32_t uv_16bit(float u, float v)
|
constexpr inline uint32_t uv_16bit(float u, float v)
|
||||||
{
|
{
|
||||||
uint32_t * ui = (reinterpret_cast<uint32_t *>(&u));
|
uint32_t * ui = (reinterpret_cast<uint32_t *>(&u));
|
||||||
uint32_t * vi = (reinterpret_cast<uint32_t *>(&v));
|
uint32_t * vi = (reinterpret_cast<uint32_t *>(&v));
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
extern uint32_t _binary_sperrypc_data_start __asm("_binary_sperrypc_data_start");
|
extern uint32_t _binary_sperrypc_data_start __asm("_binary_sperrypc_data_start");
|
||||||
|
Loading…
x
Reference in New Issue
Block a user