diff --git a/dejavusansmono.data b/dejavusansmono.data index e61fec3..d25d936 100644 Binary files a/dejavusansmono.data and b/dejavusansmono.data differ diff --git a/dejavusansmono_mono.data b/dejavusansmono_mono.data index 7e234c5..9dea48d 100644 Binary files a/dejavusansmono_mono.data and b/dejavusansmono_mono.data differ diff --git a/example/font_outline.cpp b/example/font_outline.cpp index 14269fd..ed35b49 100644 --- a/example/font_outline.cpp +++ b/example/font_outline.cpp @@ -15,6 +15,7 @@ #include "holly/ta_bits.hpp" #include "twiddle.hpp" #include "serial.hpp" +#include "palette.hpp" #include "font/font.hpp" #include "dejavusansmono.hpp" @@ -59,17 +60,18 @@ uint32_t transform(ta_parameter_writer& parameter, auto polygon = global_polygon_type_0(texture_address); polygon.parameter_control_word = para_control::para_type::polygon_or_modifier_volume - | para_control::list_type::opaque + | para_control::list_type::translucent | obj_control::col_type::packed_color | obj_control::texture; - polygon.tsp_instruction_word = tsp_instruction_word::src_alpha_instr::one - | tsp_instruction_word::dst_alpha_instr::zero + polygon.tsp_instruction_word = tsp_instruction_word::src_alpha_instr::src_alpha + | tsp_instruction_word::dst_alpha_instr::one | tsp_instruction_word::fog_control::no_fog + | tsp_instruction_word::use_alpha | tsp_instruction_word::texture_u_size::from_int(texture_width) | tsp_instruction_word::texture_v_size::from_int(texture_height); - polygon.texture_control_word = texture_control_word::pixel_format::_8bpp_palette + polygon.texture_control_word = texture_control_word::pixel_format::_4bpp_palette | texture_control_word::scan_order::twiddled | texture_control_word::texture_address(texture_address / 8); parameter.append() = polygon; @@ -117,17 +119,17 @@ uint32_t transform2(ta_parameter_writer& parameter, auto polygon = global_polygon_type_0(texture_address); polygon.parameter_control_word = para_control::para_type::polygon_or_modifier_volume - | para_control::list_type::opaque + | para_control::list_type::translucent | obj_control::col_type::packed_color | obj_control::texture; - polygon.tsp_instruction_word = tsp_instruction_word::src_alpha_instr::one + polygon.tsp_instruction_word = tsp_instruction_word::src_alpha_instr::src_alpha | 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); - polygon.texture_control_word = texture_control_word::pixel_format::_8bpp_palette + polygon.texture_control_word = texture_control_word::pixel_format::_4bpp_palette | texture_control_word::scan_order::twiddled | texture_control_word::texture_address(texture_address / 8); parameter.append() = polygon; @@ -139,8 +141,8 @@ uint32_t transform2(ta_parameter_writer& parameter, float y = strip_vertices[i].y; float z = strip_vertices[i].z; - x *= 128.f; - y *= 256.f; + x *= static_cast(texture_width); + y *= static_cast(texture_height); x += 50.f; y += 50.f; z = 1.f / (z + 9.f); @@ -179,28 +181,11 @@ void inflate_font(const uint32_t * src, auto mem = reinterpret_cast(texture_memory64); auto texture = reinterpret_cast(mem->texture); - twiddle::texture3<8, 8>(texture, reinterpret_cast(src), + twiddle::texture3<4, 8>(texture, reinterpret_cast(src), stride, curve_end_ix); } -template -void palette_data() -{ - static_assert(C >= 2); - constexpr int increment = 256 / C; - - holly.PAL_RAM_CTRL = pal_ram_ctrl::pixel_format::rgb565; - - // generate a palette with `C` shades of grey, - // ranging in intensity from rgb565(0, 0, 0) to rgb565(31, 63, 31) - for (int i = 0; i < 256; i += increment) { - holly.PALETTE_RAM[i / increment] = ((i >> 3) << 11) - | ((i >> 2) << 5) - | ((i >> 3) << 0); - } -} - uint32_t _ta_parameter_buf[((32 * 10 * 17) + 32) / 4]; void main() @@ -226,7 +211,7 @@ void main() inflate_font(texture, font->texture_stride, font->max_z_curve_ix); - palette_data<256>(); + palette_data<16>(); // 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. @@ -234,13 +219,13 @@ void main() 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::t_opb::_16x4byte | ta_alloc_ctrl::om_opb::no_list - | ta_alloc_ctrl::o_opb::_16x4byte; + | ta_alloc_ctrl::o_opb::no_list; - constexpr struct opb_size opb_size = { .opaque = 16 * 4 + constexpr struct opb_size opb_size = { .opaque = 0 , .opaque_modifier = 0 - , .translucent = 0 + , .translucent = 16 * 4 , .translucent_modifier = 0 , .punch_through = 0 }; @@ -266,10 +251,8 @@ void main() auto parameter = ta_parameter_writer(ta_parameter_buf); - /* transform2(parameter, font->texture_width, font->texture_height); - */ transform(parameter, font->texture_width, font->texture_height, @@ -288,7 +271,7 @@ void main() parameter.append() = global_end_of_list(); ta_polygon_converter_transfer(ta_parameter_buf, parameter.offset); - ta_wait_opaque_list(); + ta_wait_translucent_list(); core_start_render(frame_ix, num_frames); diff --git a/example/font_outline_punch_through.cpp b/example/font_outline_punch_through.cpp index 30f1a05..4544b0a 100644 --- a/example/font_outline_punch_through.cpp +++ b/example/font_outline_punch_through.cpp @@ -15,6 +15,7 @@ #include "holly/ta_bits.hpp" #include "twiddle.hpp" #include "serial.hpp" +#include "palette.hpp" #include "font/font.hpp" #include "dejavusansmono_mono.hpp" @@ -39,11 +40,11 @@ const struct vertex strip_vertices[4] = { constexpr uint32_t strip_length = (sizeof (strip_vertices)) / (sizeof (struct vertex)); uint32_t transform(ta_parameter_writer& parameter, - const uint32_t texture_width, uint32_t texture_height, - const uint32_t first_char_code, - const glyph * glyphs, - const char * s, const uint32_t len, - const uint32_t y_offset) + const uint32_t texture_width, uint32_t texture_height, + const uint32_t first_char_code, + const glyph * glyphs, + const char * s, const uint32_t len, + const uint32_t y_offset) { uint32_t texture_address = (offsetof (struct texture_memory_alloc, texture)); @@ -59,19 +60,20 @@ uint32_t transform(ta_parameter_writer& parameter, auto polygon = global_polygon_type_0(texture_address); polygon.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; + | para_control::list_type::punch_through + | obj_control::col_type::packed_color + | obj_control::texture; - polygon.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); + polygon.tsp_instruction_word = tsp_instruction_word::src_alpha_instr::src_alpha + | tsp_instruction_word::dst_alpha_instr::one + | tsp_instruction_word::fog_control::no_fog + //| tsp_instruction_word::use_alpha + | tsp_instruction_word::texture_u_size::from_int(texture_width) + | tsp_instruction_word::texture_v_size::from_int(texture_height); polygon.texture_control_word = texture_control_word::pixel_format::_4bpp_palette - | texture_control_word::scan_order::twiddled - | texture_control_word::texture_address(texture_address / 8); + | texture_control_word::scan_order::twiddled + | texture_control_word::texture_address(texture_address / 8); parameter.append() = polygon; for (uint32_t i = 0; i < strip_length; i++) { @@ -98,10 +100,10 @@ uint32_t transform(ta_parameter_writer& parameter, v = v / static_cast(texture_height); parameter.append() = - vertex_polygon_type_3(x, y, z, - u, v, - 0x00000000, // base_color - end_of_strip); + vertex_polygon_type_3(x, y, z, + u, v, + 0x00000000, // base_color + end_of_strip); } advance += glyph.metrics.horiAdvance; @@ -110,6 +112,53 @@ uint32_t transform(ta_parameter_writer& parameter, return parameter.offset; } +uint32_t transform2(ta_parameter_writer& parameter, + const uint32_t texture_width, uint32_t texture_height) +{ + uint32_t texture_address = (offsetof (struct texture_memory_alloc, texture)); + + auto polygon = global_polygon_type_0(texture_address); + polygon.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; + + polygon.tsp_instruction_word = tsp_instruction_word::src_alpha_instr::src_alpha + | 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); + + polygon.texture_control_word = texture_control_word::pixel_format::_4bpp_palette + | texture_control_word::scan_order::twiddled + | texture_control_word::texture_address(texture_address / 8); + parameter.append() = polygon; + + for (uint32_t i = 0; i < strip_length; i++) { + bool end_of_strip = i == strip_length - 1; + + float x = strip_vertices[i].x; + float y = strip_vertices[i].y; + float z = strip_vertices[i].z; + + x *= static_cast(texture_width); + y *= static_cast(texture_height); + x += 50.f; + y += 50.f; + z = 1.f / (z + 9.f); + + float u = strip_vertices[i].u; + float v = strip_vertices[i].v; + + parameter.append() = + vertex_polygon_type_3(x, y, z, + u, v, + 0x00000000, // base_color + end_of_strip); + } + + return parameter.offset; +} void init_texture_memory(const struct opb_size& opb_size) { @@ -118,11 +167,11 @@ void init_texture_memory(const struct opb_size& opb_size) background_parameter(mem->background, 0xff0000ff); region_array2(mem->region_array, - (offsetof (struct texture_memory_alloc, object_list)), - 640 / 32, // width - 480 / 32, // height - opb_size - ); + (offsetof (struct texture_memory_alloc, object_list)), + 640 / 32, // width + 480 / 32, // height + opb_size + ); } constexpr inline uint32_t b(uint32_t v, uint32_t n) @@ -131,38 +180,15 @@ constexpr inline uint32_t b(uint32_t v, uint32_t n) } void inflate_font(const uint32_t * src, - const uint32_t stride, - const uint32_t curve_end_ix) + const uint32_t stride, + const uint32_t curve_end_ix) { auto mem = reinterpret_cast(texture_memory64); auto texture = reinterpret_cast(mem->texture); twiddle::texture3<4, 1>(texture, reinterpret_cast(src), - stride, - curve_end_ix); -} - -template -void palette_data() -{ - static_assert(C >= 2); - constexpr int increment = 256 / C; - - holly.PAL_RAM_CTRL = pal_ram_ctrl::pixel_format::rgb565; - - // generate a palette with `C` shades of grey, - // ranging in intensity from rgb565(0, 0, 0) to rgb565(31, 63, 31) - for (int i = 0; i < 256; i += increment) { - holly.PALETTE_RAM[i / increment] = ((i >> 3) << 11) - | ((i >> 2) << 5) - | ((i >> 3) << 0); - } -} - -void palette_data_mono() -{ - holly.PALETTE_RAM[0] = 0; - holly.PALETTE_RAM[1] = 0xffff; + stride, + curve_end_ix); } uint32_t _ta_parameter_buf[((32 * 10 * 17) + 32) / 4]; @@ -187,33 +213,34 @@ void main() */ inflate_font(texture, - font->texture_stride, - font->max_z_curve_ix); - palette_data_mono(); + font->texture_stride, + font->max_z_curve_ix); + palette_data<2>(); // 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 + constexpr uint32_t ta_alloc = ta_alloc_ctrl::pt_opb::_16x4byte + | 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 - }; + , .opaque_modifier = 0 + , .translucent = 0 + , .translucent_modifier = 0 + , .punch_through = 16 * 4 + }; constexpr uint32_t tiles = (640 / 32) * (320 / 32); holly.SOFTRESET = softreset::pipeline_soft_reset - | softreset::ta_soft_reset; + | softreset::ta_soft_reset; holly.SOFTRESET = 0; + holly.PT_ALPHA_REF = 0x1; core_init(); init_texture_memory(opb_size); @@ -225,28 +252,33 @@ void main() while (true) { ta_polygon_converter_init(opb_size.total() * tiles, ta_alloc, - 640, 480); + 640, 480); auto parameter = ta_parameter_writer(ta_parameter_buf); - transform(parameter, - font->texture_width, font->texture_height, - font->first_char_code, - glyphs, - ana, 17, - font->glyph_height * 0); + transform2(parameter, + font->texture_width, font->texture_height); + + parameter.append() = global_end_of_list(); transform(parameter, - font->texture_width, font->texture_height, - font->first_char_code, - glyphs, - cabal, 26, - font->glyph_height * 1); + font->texture_width, font->texture_height, + font->first_char_code, + glyphs, + ana, 17, + font->glyph_height * 0); + + transform(parameter, + font->texture_width, font->texture_height, + font->first_char_code, + glyphs, + cabal, 26, + font->glyph_height * 1); parameter.append() = global_end_of_list(); ta_polygon_converter_transfer(ta_parameter_buf, parameter.offset); - ta_wait_opaque_list(); + ta_wait_punch_through_list(); core_start_render(frame_ix, num_frames); diff --git a/holly/core.cpp b/holly/core.cpp index 9c06e1c..f7584fe 100644 --- a/holly/core.cpp +++ b/holly/core.cpp @@ -13,7 +13,8 @@ void core_init() { - holly.ISP_FEED_CFG = isp_feed_cfg::cache_size_for_translucency(0x200); + holly.ISP_FEED_CFG = isp_feed_cfg::cache_size_for_translucency(0x200) + | isp_feed_cfg::punch_through_chunk_size(0x200); holly.FPU_SHAD_SCALE = fpu_shad_scale::scale_factor_for_shadows(1); holly.FPU_CULL_VAL = _i(1.f); diff --git a/holly/ta_fifo_polygon_converter.cpp b/holly/ta_fifo_polygon_converter.cpp index eab3737..61c5ef7 100644 --- a/holly/ta_fifo_polygon_converter.cpp +++ b/holly/ta_fifo_polygon_converter.cpp @@ -114,3 +114,10 @@ void ta_wait_translucent_list() system.ISTNRM = ISTNRM__END_OF_TRANSFERRING_TRANSLUCENT_LIST; } + +void ta_wait_punch_through_list() +{ + while ((system.ISTNRM & ISTNRM__END_OF_TRANSFERRING_PUNCH_THROUGH_LIST) == 0); + + system.ISTNRM = ISTNRM__END_OF_TRANSFERRING_PUNCH_THROUGH_LIST; +} diff --git a/holly/ta_fifo_polygon_converter.hpp b/holly/ta_fifo_polygon_converter.hpp index 52bbd01..58a26e5 100644 --- a/holly/ta_fifo_polygon_converter.hpp +++ b/holly/ta_fifo_polygon_converter.hpp @@ -11,3 +11,4 @@ void ta_polygon_converter_cont(uint32_t ol_base_offset, void ta_polygon_converter_transfer(volatile uint32_t * buf, uint32_t size); void ta_wait_opaque_list(); void ta_wait_translucent_list(); +void ta_wait_punch_through_list(); diff --git a/palette.hpp b/palette.hpp new file mode 100644 index 0000000..5086296 --- /dev/null +++ b/palette.hpp @@ -0,0 +1,50 @@ +#pragma once + +constexpr inline uint16_t rgb565(uint8_t r, uint8_t g, uint8_t b) +{ + return ((r >> 3) << 11) | ((g >> 2) << 5) | ((b >> 3) << 0); +} + +constexpr inline uint16_t grey565(uint8_t i) +{ + return ((i >> 3) << 11) | ((i >> 2) << 5) | ((i >> 3) << 0); +} + +constexpr inline uint16_t argb4444(uint8_t i) +{ + return (i << 12) | (15 << 8) | (15 << 4) | (15 << 0); +} + +template +void palette_data(); + +template <> +void palette_data<255>() +{ + holly.PAL_RAM_CTRL = pal_ram_ctrl::pixel_format::rgb565; + + // ranging in intensity from rgb565(0, 0, 0) to rgb565(31, 63, 31) + for (int i = 0; i < 256; i += 1) { + holly.PALETTE_RAM[i] = grey565(i); + } +} + +template <> +void palette_data<16>() +{ + holly.PAL_RAM_CTRL = pal_ram_ctrl::pixel_format::argb4444; + + // ranging in intensity from rgb565(0, 0, 0) to rgb565(31, 63, 31) + for (uint32_t i = 0; i < 16; i++) { + holly.PALETTE_RAM[i] = argb4444(i); + } +} + +template <> +void palette_data<2>() +{ + holly.PAL_RAM_CTRL = pal_ram_ctrl::pixel_format::argb1555; + + holly.PALETTE_RAM[0] = 0x0000; + holly.PALETTE_RAM[1] = 0xffff; +}