physics_engine/src/platform/graphics.cpp

245 lines
7.8 KiB
C++

#include <bit>
#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 "demo/collision.hpp"
#include "demo/lizard/main.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::collision _collision;
*/
demo::lizard _lizard;
demo::scene * current_scene = &_lizard;
void draw()
{
holly.PT_ALPHA_REF = 15;
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 dl = static_cast<float>(data.analog_coordinate_axis[0]) * (1.f / 255.f);
float dr = static_cast<float>(data.analog_coordinate_axis[1]) * (1.f / 255.f);
float dx = static_cast<float>(data.analog_coordinate_axis[2] - 0x80) * (1.f / 128.f);
float dy = static_cast<float>(data.analog_coordinate_axis[3] - 0x80) * (1.f / 128.f);
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;
bool ra = ft0::data_transfer::digital_button::ra(data.digital_button) == 0;
bool la = ft0::data_transfer::digital_button::la(data.digital_button) == 0;
bool da = ft0::data_transfer::digital_button::da(data.digital_button) == 0;
bool ua = ft0::data_transfer::digital_button::ua(data.digital_button) == 0;
if (a) current_scene->a();
if (b) current_scene->b();
if (x) current_scene->x();
if (y) current_scene->y();
if (ra) current_scene->ra();
if (la) current_scene->la();
if (da) current_scene->da();
if (ua) current_scene->ua();
last[port_ix].a = a;
last[port_ix].b = b;
last[port_ix].x = x;
last[port_ix].y = y;
current_scene->analog(dl, dr, dx, dy);
//view_trans = rotate_y(dy) * view_trans;// * rotate_x(dx);
}
}
}
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;
}
}