2024-12-14 05:34:10 -06:00

200 lines
6.6 KiB
C++

#include "holly/isp_tsp.hpp"
#include "holly/ta_parameter.hpp"
#include "holly/ta_global_parameter.hpp"
#include "holly/ta_vertex_parameter.hpp"
#include "sh7091/store_queue.hpp"
#include "sh7091/serial.hpp"
#include "math/vec2.hpp"
#include "font/font.h"
#include "maple/maple_bus_ft0.hpp"
#include "unparse.h"
#include "solution.h"
extern void glyph_start(const uint32_t texture_width, uint32_t texture_height);
extern int32_t transform_char(const uint32_t texture_width,
const uint32_t texture_height,
const uint32_t first_char_code,
const glyph * glyphs,
const char c,
int32_t horizontal_advance,
int32_t vertical_advance,
uint32_t base_color = 0xffffffff);
using vec2 = vec<2, float>;
constexpr vec2 square_vertices[] = {
{0.0, 4.0},
{0.0, 0.0},
{4.0, 4.0},
{4.0, 0.0},
};
static void polygon_start()
{
const uint32_t parameter_control_word = para_control::para_type::polygon_or_modifier_volume
| para_control::list_type::translucent
| obj_control::col_type::packed_color;
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;
*reinterpret_cast<ta_global_parameter::polygon_type_0 *>(store_queue) =
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
);
sq_transfer_32byte(ta_fifo_polygon_converter);
}
static void draw_robot(int cx, int cy, uint32_t base_color)
{
float z = 1.0 / 10.0;
for (int i = 0; i < 4; i++) {
bool end_of_strip = i == 3;
vec2 v = square_vertices[i];
v.x += 118 + 4 * cx;
v.y += 34 + 4 * cy;
*reinterpret_cast<ta_vertex_parameter::polygon_type_0 *>(store_queue) =
ta_vertex_parameter::polygon_type_0(polygon_vertex_parameter_control_word(end_of_strip),
v.x, v.y, z,
base_color);
sq_transfer_32byte(ta_fifo_polygon_converter);
}
}
static void draw_time(const struct font * font,
const struct glyph * glyphs)
{
int32_t horizontal_advance = 250 << 6;
int32_t vertical_advance = font->face_metrics.height;
{
char time[64] = "time: ";
int ix = 6;
ix += unparse_base10(&time[ix], _2024_day14_state.time, 0, 0);
for (int i = 0; i < ix; i++) {
char c = time[i];
horizontal_advance += transform_char(font->texture_width,
font->texture_height,
font->first_char_code,
glyphs,
c,
horizontal_advance,
vertical_advance);
}
}
{
horizontal_advance = (450 << 6);
char max_size[64] = "max_size: ";
int ix = 10;
ix += unparse_base10(&max_size[ix], _2024_day14_state.max_size, 0, 0);
for (int i = 0; i < ix; i++) {
char c = max_size[i];
horizontal_advance += transform_char(font->texture_width,
font->texture_height,
font->first_char_code,
glyphs,
c,
horizontal_advance,
vertical_advance);
}
}
}
static void draw_christmas(const struct font * font,
const struct glyph * glyphs,
uint32_t base_color,
int x)
{
int32_t horizontal_advance = (x << 6) + font->face_metrics.max_advance / 2;
int32_t vertical_advance = (480 << 6) - (font->face_metrics.height / 2);
char max_size[64] = "christmas detected";
for (int i = 0; i < 18; i++) {
char c = max_size[i];
horizontal_advance += transform_char(font->texture_width,
font->texture_height,
font->first_char_code,
glyphs,
c,
horizontal_advance,
vertical_advance,
base_color);
}
}
extern "C"
void _2024_day14_render(const struct font * font,
const struct glyph * glyphs,
ft0::data_transfer::data_format * maple_ft0_data)
{
static int frame = 0;
frame += 1;
static bool last_a = true;
static bool last_b = true;
if (maple_ft0_data[0].digital_button != 0) {
bool a = ft0::data_transfer::digital_button::a(maple_ft0_data[0].digital_button) == 0;
bool b = ft0::data_transfer::digital_button::b(maple_ft0_data[0].digital_button) == 0;
if (a && !last_a) {
_2024_day14_state.step = 1;
}
if (b && !last_b) {
_2024_day14_state.step = -1;
}
last_a = a;
last_b = b;
}
polygon_start();
uint32_t red_and_green[2] = {
0xffff0000,
0xff00ff00,
};
uint32_t base_color = 0xff00ffff;
uint32_t font_color = 0xffffffff;
if (_2024_day14_state.step == 0 && _2024_day14_state.max_size > 200) {
int robot_ix = (frame / 60) % 2;
base_color = red_and_green[robot_ix];
font_color = red_and_green[(robot_ix + 1) % 2];
}
for (int i = 0; i < _2024_day14_state.robot_length; i++) {
struct robot * robot = &_2024_day14_state.robot[i];
draw_robot(robot->x, robot->y, base_color);
}
glyph_start(font->texture_width, font->texture_height);
draw_time(font,
glyphs);
if (font_color != 0xffffffff) {
draw_christmas(font, glyphs,
font_color, 50);
draw_christmas(font, glyphs,
font_color, 350);
}
}