#include #include "systembus.hpp" #include "systembus_bits.hpp" #include "holly/holly.hpp" #include "holly/ta_bits.hpp" #include "holly/region_array.hpp" #include "holly/background.hpp" #include "holly/core_bits.hpp" #include "holly/core.hpp" #include "holly/framebuffer.hpp" #include "holly/texture_memory_alloc9.hpp" #include "holly/ta_fifo_texture_memory_transfer.hpp" #include "holly/ta_fifo_polygon_converter.hpp" #include "math/float_types.hpp" #include "math/transform.hpp" #include "platform/ta_parameter_presets.hpp" #include "platform/graphics_primitive.hpp" #include "platform/graphics.hpp" #include "platform/input.hpp" #include "platform/font.hpp" #include "demo/ballistics.hpp" #include "demo/bridge.hpp" #include "demo/sailboat.hpp" #include "maple/maple_bus_bits.hpp" namespace graphics { 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; static volatile int next_frame = 0; static volatile int framebuffer_ix = 0; static volatile int next_frame_ix = 0; constexpr uint32_t ta_alloc = 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 | ta_alloc_ctrl::o_opb::_32x4byte; const opb_size opb_size = { .opaque = 32 * 4, .opaque_modifier = 0, .translucent = 0, .translucent_modifier = 0, .punch_through = 32 * 4 }; mat4x4 view_trans; void interrupt(uint32_t istnrm) { if (istnrm & istnrm::v_blank_in) { system.ISTNRM = istnrm::v_blank_in; next_frame = 1; holly.FB_R_SOF1 = texture_memory_alloc.framebuffer[next_frame_ix].start; holly.FB_R_SOF2 = texture_memory_alloc.framebuffer[next_frame_ix].start; } if (istnrm & istnrm::end_of_render_tsp) { system.ISTNRM = istnrm::end_of_render_tsp | istnrm::end_of_render_isp | istnrm::end_of_render_video; next_frame_ix = framebuffer_ix; framebuffer_ix += 1; if (framebuffer_ix >= 3) framebuffer_ix = 0; core_in_use = 0; } if (istnrm & istnrm::end_of_transferring_opaque_list) { system.ISTNRM = istnrm::end_of_transferring_opaque_list; core_in_use = 1; core_start_render2(texture_memory_alloc.region_array.start, texture_memory_alloc.isp_tsp_parameters.start, texture_memory_alloc.background[0].start, texture_memory_alloc.framebuffer[framebuffer_ix].start, framebuffer::framebuffer.px_width); ta_in_use = 0; } } demo::ballistics _ballistics; demo::bridge _bridge; demo::sailboat _sailboat; demo::scene * current_scene = &_sailboat; void draw() { current_scene->draw(writer, view_trans * scale(0.05f)); } void init() { core_init(); framebuffer::scaler_init(); view_trans = current_scene->init(); // read while (spg_status::vsync(holly.SPG_STATUS)); while (!spg_status::vsync(holly.SPG_STATUS)); system.LMMODE0 = 1; // 32-bit address space system.LMMODE1 = 1; // 32-bit address space int length = texture_memory_alloc.framebuffer[2].start; ta_fifo_texture_memory_transfer::zeroize(&ta_fifo_texture_memory[0 / 4], length, 0x00c0bebc); ta_fifo_texture_memory_transfer::zeroize(&ta_fifo_texture_memory[length / 4], 720 * 480 * 2, 0xc5f7c5f7); framebuffer::spg_set_mode_640x480_vga(); //framebuffer::spg_set_mode_720x480_vga(); //framebuffer::init(720, 480, framebuffer::init(640, 480, texture_memory_alloc.framebuffer[0].start); core_param_init(texture_memory_alloc.region_array.start, texture_memory_alloc.isp_tsp_parameters.start, texture_memory_alloc.background[0].start, framebuffer::framebuffer.px_width); holly.SOFTRESET = softreset::pipeline_soft_reset | softreset::ta_soft_reset; holly.SOFTRESET = 0; background_parameter2(texture_memory_alloc.background[0].start, 0x110012); region_array_multipass(framebuffer::framebuffer.tile_width(), framebuffer::framebuffer.tile_height(), &opb_size, 1, texture_memory_alloc.region_array.start, texture_memory_alloc.object_list.start); } void input_events() { struct button_state { uint8_t a; uint8_t b; uint8_t x; uint8_t y; }; static button_state last[4] = {}; for (int port_ix = 0; port_ix < 4; port_ix++) { auto& port = input::state.port[port_ix]; if ((port.function_type & function_type::controller) != 0 && port.host_response_data_transfer_ft0 != nullptr) { auto& bus_data = port.host_response_data_transfer_ft0->bus_data; auto& data_fields = bus_data.data_fields; if ((std::byteswap(data_fields.function_type) & function_type::controller) == 0) continue; auto& data = data_fields.data; float dx = static_cast(data.analog_coordinate_axis[2] - 0x80) * 0.001; float dy = static_cast(data.analog_coordinate_axis[3] - 0x80) * 0.001; bool a = ft0::data_transfer::digital_button::a(data.digital_button) == 0; bool b = ft0::data_transfer::digital_button::b(data.digital_button) == 0; bool x = ft0::data_transfer::digital_button::x(data.digital_button) == 0; bool y = ft0::data_transfer::digital_button::y(data.digital_button) == 0; if (last[port_ix].a == 0 && a) current_scene->a(); if (last[port_ix].b == 0 && b) current_scene->b(); if (last[port_ix].x == 0 && x) current_scene->x(); if (last[port_ix].y == 0 && y) current_scene->y(); last[port_ix].a = a; last[port_ix].b = b; last[port_ix].x = x; last[port_ix].y = y; current_scene->analog(dx); view_trans = view_trans * rotate_y(dy); } } } void step() { input_events(); current_scene->update(); writer.offset = 0; draw(); while (ta_in_use); while (core_in_use); ta_in_use = 1; ta_polygon_converter_init2(texture_memory_alloc.isp_tsp_parameters.start, texture_memory_alloc.isp_tsp_parameters.end, texture_memory_alloc.object_list.start, texture_memory_alloc.object_list.end, opb_size.total(), ta_alloc, framebuffer::framebuffer.tile_width(), framebuffer::framebuffer.tile_height()); ta_polygon_converter_writeback(writer.buf, writer.offset); ta_polygon_converter_transfer(writer.buf, writer.offset); while (next_frame == 0); next_frame = 0; } }