graphics: draw multi-line pattern
This commit is contained in:
parent
43fd3e9ec4
commit
01eaa32e37
@ -159,8 +159,7 @@ void core_param_init()
|
||||
holly.ISP_BACKGND_D = _i(1.f/100000.f);
|
||||
|
||||
holly.FB_W_CTRL
|
||||
= fb_w_ctrl::fb_dither
|
||||
| fb_w_ctrl::fb_packmode::_565_rgb_16bit;
|
||||
= fb_w_ctrl::fb_packmode::_565_rgb_16bit;
|
||||
|
||||
holly.FB_W_LINESTRIDE = (framebuffer.px_width * bytes_per_pixel) / 8;
|
||||
}
|
||||
|
219
src/graphics.cpp
219
src/graphics.cpp
@ -19,7 +19,7 @@
|
||||
#include "holly/ta_global_parameter.hpp"
|
||||
#include "holly/ta_parameter.hpp"
|
||||
#include "holly/ta_vertex_parameter.hpp"
|
||||
#include "holly/texture_memory_alloc7.hpp"
|
||||
#include "holly/texture_memory_alloc9.hpp"
|
||||
#include "holly/video_output.hpp"
|
||||
|
||||
#include "font/tandy1k.data.h"
|
||||
@ -34,9 +34,9 @@
|
||||
#include "interpreter.hpp"
|
||||
|
||||
constexpr uint32_t ta_alloc = 0
|
||||
| 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::t_opb::_8x4byte
|
||||
| ta_alloc_ctrl::om_opb::no_list
|
||||
| ta_alloc_ctrl::o_opb::_32x4byte;
|
||||
|
||||
@ -45,9 +45,9 @@ constexpr struct opb_size opb_size[ta_cont_count] = {
|
||||
{
|
||||
.opaque = 32 * 4,
|
||||
.opaque_modifier = 0,
|
||||
.translucent = 0,
|
||||
.translucent = 8 * 4,
|
||||
.translucent_modifier = 0,
|
||||
.punch_through = 0
|
||||
.punch_through = 32 * 4
|
||||
}
|
||||
};
|
||||
|
||||
@ -138,7 +138,9 @@ void transfer_palettes()
|
||||
holly.PAL_RAM_CTRL = pal_ram_ctrl::pixel_format::argb1555;
|
||||
|
||||
holly.PALETTE_RAM[0] = 0;
|
||||
holly.PALETTE_RAM[1] = 0x7fff;
|
||||
holly.PALETTE_RAM[1] = 0xffff;
|
||||
|
||||
holly.PT_ALPHA_REF = 0x80;
|
||||
}
|
||||
|
||||
void graphics_init()
|
||||
@ -153,7 +155,7 @@ void graphics_init()
|
||||
spg_set_mode_640x480();
|
||||
framebuffer_init();
|
||||
|
||||
background_parameter2(texture_memory_alloc.framebuffer[0].start,
|
||||
background_parameter2(texture_memory_alloc.background[0].start,
|
||||
0xff800080);
|
||||
|
||||
region_array_multipass(framebuffer.tile_width(),
|
||||
@ -173,10 +175,10 @@ struct vertex {
|
||||
};
|
||||
|
||||
const vertex quad_vertices[] = {
|
||||
{ { 0, 0, 0.1f }, {0, 0} },
|
||||
{ { 1, 0, 0.1f }, {1, 0} },
|
||||
{ { 1, 1, 0.1f }, {1, 1} },
|
||||
{ { 0, 1, 0.1f }, {0, 1} },
|
||||
{ { 0, 0, 0.001f }, {0, 0} },
|
||||
{ { 1, 0, 0.001f }, {1, 0} },
|
||||
{ { 1, 1, 0.001f }, {1, 1} },
|
||||
{ { 0, 1, 0.001f }, {0, 1} },
|
||||
};
|
||||
|
||||
const int texture_width = 128;
|
||||
@ -240,25 +242,18 @@ int transfer_string(ta_parameter_writer& writer, const char * s, int x, int y,
|
||||
return len;
|
||||
}
|
||||
|
||||
int transfer_integer(ta_parameter_writer& writer, int n, int x, int y, int offset,
|
||||
int transfer_integer(ta_parameter_writer& writer, int n, int x, int y,
|
||||
int length, int fill,
|
||||
int base_color)
|
||||
{
|
||||
char buf[16];
|
||||
|
||||
int len = unparse_base10(buf, n, 3, ' ');
|
||||
int len = unparse_base10(buf, n, length, fill);
|
||||
buf[len] = 0;
|
||||
|
||||
int shift = 0;
|
||||
if (offset >= 0) {
|
||||
shift = 10 - offset;
|
||||
if (shift < 0)
|
||||
shift = 0;
|
||||
}
|
||||
x += glyph_hori_advance * shift;
|
||||
|
||||
transfer_string(writer, buf, x, y, base_color);
|
||||
|
||||
return len + shift;
|
||||
return len;
|
||||
}
|
||||
|
||||
int transfer_hex_integer(ta_parameter_writer& writer, int n, int x, int y,
|
||||
@ -394,10 +389,28 @@ static inline int transfer_effect_parameter(ta_parameter_writer& writer, int eff
|
||||
return x;
|
||||
}
|
||||
|
||||
static inline int transfer_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, 2, ' ', base_color);
|
||||
x += glyph_hori_advance * len;
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
void transfer_line(ta_parameter_writer& writer, int line_index, int x, int y)
|
||||
{
|
||||
using namespace interpreter;
|
||||
|
||||
x += 3;
|
||||
x += 1;
|
||||
x = transfer_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];
|
||||
@ -420,21 +433,171 @@ void transfer_line(ta_parameter_writer& writer, int line_index, int x, int y)
|
||||
}
|
||||
}
|
||||
|
||||
void transfer_scene(ta_parameter_writer& writer)
|
||||
void transfer_vertical_border(ta_parameter_writer& writer, float x, float y, int length)
|
||||
{
|
||||
global_polygon_type_0(writer);
|
||||
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);
|
||||
|
||||
int y = 48;
|
||||
int x = 3;
|
||||
for (int i = 0; i < 20; i++) {
|
||||
transfer_line(writer, i, x, y);
|
||||
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);
|
||||
}
|
||||
|
||||
const int line_column_total_advance = (3 + 2 + 2 + 1 + 2) * glyph_hori_advance;
|
||||
const int line_column_width = line_column_total_advance + 6 + 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;
|
||||
|
||||
void transfer_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, x0, y,
|
||||
x - x0);
|
||||
|
||||
transfer_horizontal_border(writer, x0, y + line_column_height,
|
||||
x - x0);
|
||||
}
|
||||
|
||||
void transfer_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)
|
||||
transfer_line(writer, line_ix, x, y);
|
||||
y += glyph_vert_advance;
|
||||
}
|
||||
}
|
||||
|
||||
void transfer_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, 1.0/15.0},
|
||||
{x + 0, y + 1, 1.0/15.0},
|
||||
{x + middle_width, y + 1, 1.0/15.0},
|
||||
{x + middle_width, y + 0, 1.0/15.0},
|
||||
0x555555);
|
||||
|
||||
y += 1;
|
||||
|
||||
quad_type_0(writer,
|
||||
{x + 0, y + 0, 1.0/15.0},
|
||||
{x + 0, y + middle_height, 1.0/15.0},
|
||||
{x + middle_width, y + middle_height, 1.0/15.0},
|
||||
{x + middle_width, y + 0, 1.0/15.0},
|
||||
0x404040);
|
||||
|
||||
y += middle_width;
|
||||
|
||||
quad_type_0(writer,
|
||||
{x + 0, y + 0, 1.0/15.0},
|
||||
{x + 0, y + 1, 1.0/15.0},
|
||||
{x + middle_width, y + 1, 1.0/15.0},
|
||||
{x + middle_width, y + 0, 1.0/15.0},
|
||||
0x202020);
|
||||
}
|
||||
|
||||
void transfer_scene(ta_parameter_writer& writer)
|
||||
{
|
||||
const int x = 3;
|
||||
const int y = 48;
|
||||
|
||||
{ // punch-through
|
||||
global_polygon_textured(writer);
|
||||
|
||||
transfer_lines(writer, x, y);
|
||||
|
||||
writer.append<ta_global_parameter::end_of_list>() =
|
||||
ta_global_parameter::end_of_list(para_control::para_type::end_of_list);
|
||||
}
|
||||
|
||||
{ // translucent
|
||||
global_polygon_untextured(writer,
|
||||
para_control::list_type::translucent,
|
||||
tsp_instruction_word::dst_alpha_instr::one);
|
||||
|
||||
transfer_middle_line(writer, x, y);
|
||||
|
||||
writer.append<ta_global_parameter::end_of_list>() =
|
||||
ta_global_parameter::end_of_list(para_control::para_type::end_of_list);
|
||||
}
|
||||
|
||||
{ // opaque
|
||||
global_polygon_untextured(writer,
|
||||
para_control::list_type::opaque,
|
||||
tsp_instruction_word::dst_alpha_instr::zero);
|
||||
|
||||
transfer_borders(writer, x, y);
|
||||
|
||||
writer.append<ta_global_parameter::end_of_list>() =
|
||||
ta_global_parameter::end_of_list(para_control::para_type::end_of_list);
|
||||
}
|
||||
}
|
||||
|
||||
void graphics_event(ta_parameter_writer& writer)
|
||||
{
|
||||
writer.offset = 0;
|
||||
|
33
src/main.cpp
33
src/main.cpp
@ -191,12 +191,45 @@ void load_xm()
|
||||
sound_init(sample_data, sample_data_ix, state.tick_rate);
|
||||
}
|
||||
|
||||
#include "memorymap.hpp"
|
||||
#include "holly/texture_memory_alloc9.hpp"
|
||||
#include "holly/holly.hpp"
|
||||
|
||||
static inline uint16_t rgb565(uint8_t r, uint8_t g, uint8_t b)
|
||||
{
|
||||
int r5 = r & 31;
|
||||
int g6 = g & 63;
|
||||
int b5 = b & 31;
|
||||
return (r5 << 11) | (g6 << 5) | (b5 << 0);
|
||||
}
|
||||
|
||||
void test_pattern()
|
||||
{
|
||||
uint16_t * framebuffer = (uint16_t *)&texture_memory32[texture_memory_alloc.framebuffer[0].start / 4];
|
||||
|
||||
for (int y = 0; y < 480; y++) {
|
||||
for (int x = 0; x < 720; x++) {
|
||||
if (x == 0 || y == 0 || y == 479)
|
||||
framebuffer[y * 720 + x] = rgb565(31, 0, 0);
|
||||
else if (x == 719)
|
||||
framebuffer[y * 720 + x] = rgb565(0, 0, 31);
|
||||
else
|
||||
framebuffer[y * 720 + x] = rgb565(0, 31 * (x & 1), 0);
|
||||
}
|
||||
}
|
||||
|
||||
holly.FB_R_SOF1 = texture_memory_alloc.framebuffer[0].start;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
serial::init(0);
|
||||
|
||||
load_xm();
|
||||
graphics_init();
|
||||
|
||||
test_pattern();
|
||||
|
||||
interrupt_init();
|
||||
//channel_sandbox_defaults();
|
||||
|
||||
|
@ -1,12 +1,12 @@
|
||||
void global_polygon_type_0(ta_parameter_writer& writer)
|
||||
void global_polygon_textured(ta_parameter_writer& writer)
|
||||
{
|
||||
const uint32_t parameter_control_word = para_control::para_type::polygon_or_modifier_volume
|
||||
| para_control::list_type::opaque
|
||||
| para_control::list_type::punch_through
|
||||
| obj_control::col_type::packed_color
|
||||
| obj_control::texture
|
||||
;
|
||||
|
||||
const uint32_t isp_tsp_instruction_word = isp_tsp_instruction_word::depth_compare_mode::always
|
||||
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::texture_shading_instruction::modulate
|
||||
@ -31,6 +31,39 @@ void global_polygon_type_0(ta_parameter_writer& writer)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
void global_polygon_untextured(ta_parameter_writer& writer, uint32_t list_type, uint32_t dst_alpha)
|
||||
{
|
||||
const uint32_t parameter_control_word = para_control::para_type::polygon_or_modifier_volume
|
||||
| list_type
|
||||
| obj_control::col_type::packed_color
|
||||
;
|
||||
|
||||
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::texture_shading_instruction::modulate
|
||||
| tsp_instruction_word::src_alpha_instr::one
|
||||
| dst_alpha
|
||||
| tsp_instruction_word::fog_control::no_fog
|
||||
| tsp_instruction_word::texture_u_size::from_int(128)
|
||||
| tsp_instruction_word::texture_v_size::from_int(256);
|
||||
|
||||
const uint32_t texture_address = texture_memory_alloc.texture.start;
|
||||
const uint32_t texture_control_word = texture_control_word::pixel_format::_4bpp_palette
|
||||
| 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_3(ta_parameter_writer& writer,
|
||||
const vec3& ap, const vec2& at,
|
||||
const vec3& bp, const vec2& bt,
|
||||
@ -62,3 +95,31 @@ static inline void quad_type_3(ta_parameter_writer& writer,
|
||||
ct.x, ct.y,
|
||||
base_color, 0);
|
||||
}
|
||||
|
||||
static inline void quad_type_0(ta_parameter_writer& writer,
|
||||
const vec3& ap,
|
||||
const vec3& bp,
|
||||
const vec3& cp,
|
||||
const vec3& dp,
|
||||
int base_color)
|
||||
{
|
||||
writer.append<ta_vertex_parameter::polygon_type_0>() =
|
||||
ta_vertex_parameter::polygon_type_0(polygon_vertex_parameter_control_word(false),
|
||||
ap.x, ap.y, ap.z,
|
||||
base_color);
|
||||
|
||||
writer.append<ta_vertex_parameter::polygon_type_0>() =
|
||||
ta_vertex_parameter::polygon_type_0(polygon_vertex_parameter_control_word(false),
|
||||
bp.x, bp.y, bp.z,
|
||||
base_color);
|
||||
|
||||
writer.append<ta_vertex_parameter::polygon_type_0>() =
|
||||
ta_vertex_parameter::polygon_type_0(polygon_vertex_parameter_control_word(false),
|
||||
dp.x, dp.y, dp.z,
|
||||
base_color);
|
||||
|
||||
writer.append<ta_vertex_parameter::polygon_type_0>() =
|
||||
ta_vertex_parameter::polygon_type_0(polygon_vertex_parameter_control_word(true),
|
||||
cp.x, cp.y, cp.z,
|
||||
base_color);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user