mirror of
https://github.com/liuk7071/ChonkyStation.git
synced 2024-05-20 12:57:52 -04:00
Lots of games now go further thanks to SPU DMA interrupts
This commit is contained in:
parent
8562be5e2c
commit
4c3c6d6e96
|
@ -700,16 +700,18 @@ int main(int argc, char** argv) {
|
|||
while (!glfwWindowShouldClose(window)) {
|
||||
if (Cpu.frame_cycles >= (33868800 / 60) || !run) {
|
||||
if (tmr1irq) {
|
||||
printf("[TIMERS] TMR1 IRQ\n");
|
||||
tmr1irq = false;
|
||||
Cpu.bus.mem.I_STAT |= 0b100000;
|
||||
printf("[TIMERS] TMR2 IRQ\n");
|
||||
//tmr1irq = false;
|
||||
//Cpu.bus.mem.I_STAT |= 0b100000;
|
||||
Cpu.bus.mem.I_STAT |= 0b1000000;
|
||||
Cpu.bus.mem.tmr1_stub = 0;
|
||||
}
|
||||
Cpu.bus.mem.I_STAT |= 0b100000;
|
||||
//Cpu.bus.mem.I_STAT |= 0b1000000;
|
||||
if (Cpu.should_service_dma_irq) {
|
||||
printf("[DMA] IRQ\n");
|
||||
Cpu.bus.mem.I_STAT |= 0b1000;
|
||||
Cpu.should_service_dma_irq = false;
|
||||
//printf("[DMA] IRQ\n");
|
||||
//Cpu.bus.mem.I_STAT |= 0b1000;
|
||||
//Cpu.should_service_dma_irq = false;
|
||||
}
|
||||
//glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||
if (pad1_source == "Gamepad") {
|
||||
|
|
74
cdrom.cpp
74
cdrom.cpp
|
@ -39,7 +39,9 @@ void cdrom::execute(uint8_t command) {
|
|||
case 0x09: Pause(); break;
|
||||
case 0x0A: init(); break;
|
||||
case 0x0C: Demute(); break;
|
||||
case 0x0D: SetFilter(); break;
|
||||
case 0x0E: Setmode(); break;
|
||||
case 0x10: GetLocL(); break;
|
||||
case 0x13: GetTN(); break;
|
||||
case 0x14: GetTD(); break;
|
||||
case 0x15: SeekL(); break;
|
||||
|
@ -82,29 +84,31 @@ uint8_t cdrom::read_fifo() {
|
|||
void cdrom::queuedRead(void* dataptr) {
|
||||
cdrom* cdromptr = (cdrom*)(dataptr);
|
||||
if (cdromptr->reading) {
|
||||
cdromptr->seekloc++;
|
||||
cdromptr->cd.read(cdromptr->seekloc);
|
||||
//cdromptr->seekloc++;
|
||||
cdromptr->status |= 0b10000000; // DRQSTS
|
||||
cdromptr->queued_fifo[0] = cdromptr->get_stat();
|
||||
cdromptr->queued_response_length = 1;
|
||||
|
||||
cdromptr->Scheduler.push(&INT1, cdromptr->Scheduler.time + ((33868800 / 100) / (cdromptr->DoubleSpeed ? 2 : 1)), cdromptr);
|
||||
cdromptr->Scheduler.push(&INT1, cdromptr->Scheduler.time + 5000, cdromptr);
|
||||
}
|
||||
}
|
||||
void cdrom::INT1(void* dataptr) {
|
||||
cdrom* cdromptr = (cdrom*)(dataptr);
|
||||
if (cdromptr->reading) {
|
||||
printf("[IRQ] INT1 dispatched\n");
|
||||
cdromptr->interrupt_flag &= ~0b111;
|
||||
cdromptr->interrupt_flag |= 0b001;
|
||||
cdromptr->cd.read(cdromptr->seekloc++);
|
||||
if (!cdromptr->xa_adpcm) {
|
||||
printf("[IRQ] INT1 dispatched\n");
|
||||
cdromptr->interrupt_flag &= ~0b111;
|
||||
cdromptr->interrupt_flag |= 0b001;
|
||||
|
||||
for (int i = 0; i < 16; i++) {
|
||||
cdromptr->response_fifo[i] = cdromptr->queued_fifo[i];
|
||||
for (int i = 0; i < 16; i++) {
|
||||
cdromptr->response_fifo[i] = cdromptr->queued_fifo[i];
|
||||
}
|
||||
cdromptr->response_length = cdromptr->queued_response_length;
|
||||
cdromptr->status |= 0b00100000;
|
||||
cdromptr->cd.bytes_read = 0;
|
||||
}
|
||||
cdromptr->response_length = cdromptr->queued_response_length;
|
||||
cdromptr->status |= 0b00100000;
|
||||
cdromptr->cd.bytes_read = 0;
|
||||
cdromptr->Scheduler.push(&queuedRead, cdromptr->Scheduler.time + 5000, cdromptr);
|
||||
cdromptr->Scheduler.push(&queuedRead, cdromptr->Scheduler.time + ((33868800 / 75) / (cdromptr->DoubleSpeed ? 1 : 1)), cdromptr);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -177,7 +181,9 @@ void cdrom::test() {
|
|||
}
|
||||
void cdrom::GetStat() { // Return status byte
|
||||
debug_log("[CDROM] GetStat\n");
|
||||
response_fifo[0] = get_stat();
|
||||
//response_fifo[0] = get_stat();
|
||||
response_fifo[0] = rand() % 0xff;
|
||||
response_fifo[0] &= ~0b11101;
|
||||
response_length = 1;
|
||||
status |= 0b00100000;
|
||||
Scheduler.push(&INT3, Scheduler.time + 25000, this);
|
||||
|
@ -185,17 +191,18 @@ void cdrom::GetStat() { // Return status byte
|
|||
void cdrom::GetTN() { // Get first track number, and last track number in the TOC of the current Session.
|
||||
debug_log("[CDROM] GetTN (stubbed)\n");
|
||||
response_fifo[0] = get_stat();
|
||||
response_fifo[1] = 0x01;
|
||||
response_fifo[2] = 0x01;
|
||||
response_fifo[1] = 0x00;
|
||||
response_fifo[2] = 0x00;
|
||||
response_length = 3;
|
||||
status |= 0b00100000;
|
||||
Scheduler.push(&INT3, Scheduler.time + 15000, this);
|
||||
}
|
||||
void cdrom::GetTD() {
|
||||
debug_log("[CDROM] GetTD (stubbed)\n");
|
||||
response_fifo[0] = get_stat();
|
||||
response_fifo[1] = 0x01;
|
||||
response_fifo[2] = 0x01;
|
||||
//response_fifo[0] = get_stat();
|
||||
response_fifo[0] = 0x00;
|
||||
response_fifo[1] = 0x00;
|
||||
response_fifo[2] = 0x00;
|
||||
response_length = 3;
|
||||
status |= 0b00100000;
|
||||
Scheduler.push(&INT3, Scheduler.time + 15000, this);
|
||||
|
@ -222,6 +229,20 @@ void cdrom::Setmode() { // Set mode
|
|||
Scheduler.push(&INT3, Scheduler.time + 4000, this);
|
||||
//delay = 2;
|
||||
}
|
||||
void cdrom::GetLocL() {
|
||||
debug_log("[CDROM] GetLocL\n");
|
||||
response_fifo[0] = cd.SectorBuffer[0xc + 0];
|
||||
response_fifo[1] = cd.SectorBuffer[0xc + 1];
|
||||
response_fifo[2] = cd.SectorBuffer[0xc + 2];
|
||||
response_fifo[3] = cd.SectorBuffer[0xc + 3];
|
||||
response_fifo[4] = cd.SectorBuffer[0x10 + 0];
|
||||
response_fifo[5] = cd.SectorBuffer[0x10 + 1];
|
||||
response_fifo[6] = cd.SectorBuffer[0x10 + 2];
|
||||
response_fifo[7] = cd.SectorBuffer[0x10 + 3];
|
||||
response_length = 8;
|
||||
status |= 0b00100000;
|
||||
Scheduler.push(&INT3, Scheduler.time + 15000, this);
|
||||
}
|
||||
void cdrom::GetID() { // Disk info
|
||||
debug_log("[CDROM] GetID\n");
|
||||
if (cd.IsCDInserted) {
|
||||
|
@ -298,7 +319,7 @@ void cdrom::ReadN() { // Read with retry
|
|||
status |= 0b00001000; // Set parameter fifo empty bit
|
||||
debug_log("[CDROM] ReadN\n");
|
||||
cd.bytes_read = 0;
|
||||
cd.read(seekloc);
|
||||
//cd.read(seekloc);
|
||||
response_fifo[0] = get_stat();
|
||||
response_length = 1;
|
||||
//INT3();
|
||||
|
@ -309,23 +330,23 @@ void cdrom::ReadN() { // Read with retry
|
|||
//queued_INT1 = true;
|
||||
|
||||
Scheduler.push(&INT3, Scheduler.time + 4, this);
|
||||
Scheduler.push(&INT1, Scheduler.time + ((33868800 / 100) / (DoubleSpeed ? 2 : 1)), this);
|
||||
Scheduler.push(&INT1, Scheduler.time + ((33868800 / 75) / (DoubleSpeed ? 1 : 1)), this);
|
||||
//queued_delay = 33868800 / 75;
|
||||
status |= 0b00100000; // Set response fifo empty bit (means it's full)
|
||||
}
|
||||
void cdrom::ReadS() { // Read without retry
|
||||
status |= 0b00001000; // Set parameter fifo empty bit
|
||||
debug_log("[CDROM] ReadS\n");
|
||||
cd.read(seekloc);
|
||||
cd.bytes_read = 0;
|
||||
response_fifo[0] = get_stat();
|
||||
reading = false; // To not make it retry
|
||||
reading = true;
|
||||
response_length = 1;
|
||||
|
||||
queued_fifo[0] = 0x22;
|
||||
queued_response_length = 1;
|
||||
|
||||
Scheduler.push(&INT3, Scheduler.time + 4, this);
|
||||
Scheduler.push(&INT1, Scheduler.time + ((33868800 / 100) / (DoubleSpeed ? 2 : 1)), this);
|
||||
Scheduler.push(&INT1, Scheduler.time + ((33868800 / 75) / (DoubleSpeed ? 2 : 1)), this);
|
||||
status |= 0b00100000; // Set response fifo empty bit (means it's full)
|
||||
}
|
||||
void cdrom::Pause() {
|
||||
|
@ -367,4 +388,11 @@ void cdrom::Demute() {
|
|||
response_length = 1;
|
||||
status |= 0b00100000;
|
||||
Scheduler.push(&INT3, Scheduler.time + 25000, this);
|
||||
}
|
||||
void cdrom::SetFilter() {
|
||||
debug_log("[CDROM] SetFilter\n");
|
||||
response_fifo[0] = get_stat();
|
||||
response_length = 1;
|
||||
status |= 0b00100000;
|
||||
Scheduler.push(&INT3, Scheduler.time + 25000, this);
|
||||
}
|
2
cdrom.h
2
cdrom.h
|
@ -65,7 +65,9 @@ public:
|
|||
void Pause();
|
||||
void init();
|
||||
void Demute();
|
||||
void SetFilter();
|
||||
void Setmode();
|
||||
void GetLocL();
|
||||
|
||||
// setmode
|
||||
bool DoubleSpeed = false;
|
||||
|
|
17
cpu.cpp
17
cpu.cpp
|
@ -123,11 +123,6 @@ void cpu::exception(exceptions exc) {
|
|||
delay = false;
|
||||
}
|
||||
|
||||
void DMAIRQ(void* dataptr) {
|
||||
memory* memoryptr = (memory*)dataptr;
|
||||
memoryptr->I_STAT |= 0b1000;
|
||||
}
|
||||
|
||||
template<int channel>
|
||||
void cpu::do_dma() {
|
||||
//debug = true;
|
||||
|
@ -160,7 +155,8 @@ void cpu::do_dma() {
|
|||
//debug = false;
|
||||
if (((bus.mem.DICR >> 18) & 1) && ((bus.mem.DICR >> 23) & 1)) {
|
||||
bus.mem.DICR |= (1 << 26);
|
||||
should_service_dma_irq = true;
|
||||
bus.mem.I_STAT |= 0b1000;
|
||||
//should_service_dma_irq = true;
|
||||
}
|
||||
return;
|
||||
case 0:
|
||||
|
@ -195,7 +191,8 @@ void cpu::do_dma() {
|
|||
}
|
||||
if (((bus.mem.DICR >> 18) & 1) && ((bus.mem.DICR >> 23) & 1)) {
|
||||
bus.mem.DICR |= (1 << 26);
|
||||
should_service_dma_irq = true;
|
||||
bus.mem.I_STAT |= 0b1000;
|
||||
//should_service_dma_irq = true;
|
||||
}
|
||||
bus.mem.Ch2.CHCR &= ~(1 << 24);
|
||||
debug_log("[DMA] GPU Linked List transfer complete\n");
|
||||
|
@ -243,7 +240,8 @@ void cpu::do_dma() {
|
|||
//debug = false;
|
||||
if (((bus.mem.DICR >> 19) & 1) && ((bus.mem.DICR >> 23) & 1)) {
|
||||
bus.mem.DICR |= (1 << 27);
|
||||
should_service_dma_irq = true;
|
||||
bus.mem.I_STAT |= 0b1000;
|
||||
//should_service_dma_irq = true;
|
||||
}
|
||||
//bus.mem.CDROM.queued_read = true;
|
||||
//bus.mem.CDROM.delay = 2;
|
||||
|
@ -300,7 +298,8 @@ void cpu::do_dma() {
|
|||
//debug = false;
|
||||
if (((bus.mem.DICR >> 22) & 1) && ((bus.mem.DICR >> 23) & 1)) {
|
||||
bus.mem.DICR |= (1 << 30);
|
||||
should_service_dma_irq = true;
|
||||
bus.mem.I_STAT |= 0b1000;
|
||||
//should_service_dma_irq = true;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
|
553
gpu.cpp
553
gpu.cpp
|
@ -233,6 +233,11 @@ void gpu::execute_gp0(uint32_t command) {
|
|||
cmd_left = 8;
|
||||
break;
|
||||
}
|
||||
case 0x2E: { // Textured four-point polygon, semi-transparent, texture-blending
|
||||
cmd_length++;
|
||||
cmd_left = 8;
|
||||
break;
|
||||
}
|
||||
case 0x2F: { // Textured four-point polygon, semi-transparent, raw-texture
|
||||
fifo[0] = command;
|
||||
cmd_length++;
|
||||
|
@ -313,12 +318,24 @@ void gpu::execute_gp0(uint32_t command) {
|
|||
cmd_left = 3;
|
||||
break;
|
||||
}
|
||||
case 0x67: { // Textured Rectangle, variable size, semi-transp, raw-texture
|
||||
fifo[0] = command;
|
||||
cmd_length++;
|
||||
cmd_left = 3;
|
||||
break;
|
||||
}
|
||||
case 0x68: { // 1x1 Opaque Monochrome Rectangle
|
||||
fifo[0] = command;
|
||||
cmd_length++;
|
||||
cmd_left = 1;
|
||||
break;
|
||||
}
|
||||
case 0x70: { // Monochrome Rectangle (8x8) (opaque)
|
||||
fifo[0] = command;
|
||||
cmd_length++;
|
||||
cmd_left = 1;
|
||||
break;
|
||||
}
|
||||
case 0x74: { // Textured Rectangle, 8x8, opaque, texture-blending
|
||||
fifo[0] = command;
|
||||
cmd_length++;
|
||||
|
@ -331,6 +348,12 @@ void gpu::execute_gp0(uint32_t command) {
|
|||
cmd_left = 2;
|
||||
break;
|
||||
}
|
||||
case 0x7C: { // Textured Rectangle, 16x16, opaque, texture-blending
|
||||
fifo[0] = command;
|
||||
cmd_length++;
|
||||
cmd_left = 2;
|
||||
break;
|
||||
}
|
||||
case 0x80: { // Copy Rectangle (VRAM to VRAM)
|
||||
fifo[0] = command;
|
||||
cmd_length++;
|
||||
|
@ -344,8 +367,10 @@ void gpu::execute_gp0(uint32_t command) {
|
|||
break;
|
||||
}
|
||||
case 0xC0: { // Copy rectangle VRAM to CPU
|
||||
// unimplemented
|
||||
debug_printf("[GP0] Copy Rectangle (VRAM to CPU)\n");
|
||||
fifo[0] = command;
|
||||
cmd_length++;
|
||||
cmd_left = 2;
|
||||
break;
|
||||
}
|
||||
case 0xE1: { // Draw Mode Setting
|
||||
|
@ -394,7 +419,7 @@ void gpu::execute_gp0(uint32_t command) {
|
|||
}
|
||||
default:
|
||||
printf("\n[GP0] Unknown GP0 command: 0x%x (0x%x)\n", instr, command);
|
||||
//abort();
|
||||
abort();
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
@ -407,6 +432,8 @@ void gpu::execute_gp0(uint32_t command) {
|
|||
glScissor(drawing_topleft_x, drawing_topleft_y, (drawing_bottomright_x - drawing_topleft_x), (drawing_bottomright_y - drawing_topleft_y));
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
|
||||
//SyncVRAM();
|
||||
|
||||
switch ((fifo[0] >> 24) & 0xff) {
|
||||
|
||||
case 0x02: gpu::fill_rectangle(); break;
|
||||
|
@ -418,6 +445,7 @@ void gpu::execute_gp0(uint32_t command) {
|
|||
case 0x2A: gpu::monochrome_four_point_semi_transparent_polygon(); break;
|
||||
case 0x2C: gpu::texture_blending_four_point_opaque_polygon(); break;
|
||||
case 0x2D: gpu::texture_four_point_opaque_polygon(); break;
|
||||
case 0x2E: gpu::texture_blending_four_point_polygon_semi_transparent(); break;
|
||||
case 0x2F: gpu::texture_four_point_semi_transparent_polygon(); break;
|
||||
case 0x30: gpu::shaded_three_point_opaque_polygon(); break;
|
||||
case 0x32: gpu::shaded_three_point_semi_transparent_polygon(); break;
|
||||
|
@ -431,11 +459,15 @@ void gpu::execute_gp0(uint32_t command) {
|
|||
case 0x64: gpu::texture_blending_rectangle_variable_size_opaque(); break;
|
||||
case 0x65: gpu::texture_rectangle_variable_size_opaque(); break;
|
||||
case 0x66: gpu::texture_blending_rectangle_variable_size_semi_transparent(); break;
|
||||
case 0x67: gpu::textured_rectangle_variable_size_semi_transparent(); break;
|
||||
case 0x68: gpu::monochrome_rectangle_dot_opaque(); break;
|
||||
case 0x70: gpu::monochrome_rectangle_8x8_opaque(); break;
|
||||
case 0x74: gpu::texture_blending_rectangle_8x8_opaque(); break;
|
||||
case 0x75: gpu::texture_rectangle_8x8_opaque(); break;
|
||||
case 0x7C: gpu::texture_blending_rectangle_16x16_opaque(); break;
|
||||
case 0x80: break;
|
||||
case 0xA0: gpu::cpu_to_vram(); break;
|
||||
case 0xC0: gpu::vram_to_cpu(); break;
|
||||
default: printf("\n%d", fifo[0] >> 24); abort();
|
||||
}
|
||||
}
|
||||
|
@ -870,6 +902,149 @@ void gpu::texture_four_point_opaque_polygon() {
|
|||
glBindFramebuffer(GL_FRAMEBUFFER, oldFBO);
|
||||
}
|
||||
|
||||
void gpu::texture_blending_four_point_polygon_semi_transparent() {
|
||||
uint32_t colour = fifo[0] & 0xffffff;
|
||||
debug_printf("[GP0] Textured four-point polygon, semi-transparent, texture-blending (colour: 0x%x)\n", colour);
|
||||
point v1, v2, v3, v4;
|
||||
uint16_t texpage = 0;
|
||||
uint16_t clut = 0;
|
||||
v1.x = fifo[1] & 0xffff;
|
||||
v1.y = fifo[1] >> 16;
|
||||
clut = fifo[2] >> 16;
|
||||
uint32_t clutX = (clut & 0x3f);
|
||||
clutX *= 16;
|
||||
uint32_t clutY = (clut >> 6);
|
||||
int Clut[256];
|
||||
for (int i = 0; i < 256; i++) {
|
||||
Clut[i] = vram_rgb[clutY * 1024 + clutX + i];
|
||||
}
|
||||
GLuint ssbo;
|
||||
GLuint binding = 10;
|
||||
glGenBuffers(1, &ssbo);
|
||||
glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssbo);
|
||||
glBufferData(GL_SHADER_STORAGE_BUFFER, 256 * sizeof(int), Clut, GL_STATIC_READ);
|
||||
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, binding, ssbo);
|
||||
texpage = fifo[4] >> 16;
|
||||
uint32_t texpageX = ((texpage & 0b1111) * 64);
|
||||
uint32_t texpageY = (((texpage & 0b10000) >> 4) * 256);
|
||||
v2.x = fifo[3] & 0xffff;
|
||||
v2.y = fifo[3] >> 16;
|
||||
v3.x = fifo[5] & 0xffff;
|
||||
v3.y = fifo[5] >> 16;
|
||||
v4.x = fifo[7] & 0xffff;
|
||||
v4.y = fifo[7] >> 16;
|
||||
|
||||
v1.x += xoffset;
|
||||
v1.y += yoffset;
|
||||
v2.x += xoffset;
|
||||
v2.y += yoffset;
|
||||
v3.x += xoffset;
|
||||
v3.y += yoffset;
|
||||
v4.x += xoffset;
|
||||
v4.y += yoffset;
|
||||
|
||||
point t1, t2, t3, t4;
|
||||
t1.x = (fifo[2] & 0xffff) & 0xff;
|
||||
t1.y = ((fifo[2] & 0xffff) >> 8) & 0xff;
|
||||
t2.x = (fifo[4] & 0xffff) & 0xff;
|
||||
t2.y = ((fifo[4] & 0xffff) >> 8) & 0xff;
|
||||
t3.x = (fifo[6] & 0xffff) & 0xff;
|
||||
t3.y = ((fifo[6] & 0xffff) >> 8) & 0xff;
|
||||
t4.x = (fifo[8] & 0xffff) & 0xff;
|
||||
t4.y = ((fifo[8] & 0xffff) >> 8) & 0xff;
|
||||
int colourDepth = (texpage >> 7) & 3;
|
||||
|
||||
uint32_t Vertices1[] = {
|
||||
// positions // colors // texture coords
|
||||
v1.x, v1.y, 0, (((colour) >> 0) & 0xff), (((colour) >> 8) & 0xff), (((colour) >> 16) & 0xff), t1.x, t1.y, texpageX, texpageY, clutX, clutY, colourDepth,
|
||||
v2.x, v2.y, 0.0f, (((colour) >> 0) & 0xff), (((colour) >> 8) & 0xff), (((colour) >> 16) & 0xff), t2.x, t2.y, texpageX, texpageY, clutX, clutY, colourDepth,
|
||||
v3.x, v3.y, 0.0f, (((colour) >> 0) & 0xff), (((colour) >> 8) & 0xff), (((colour) >> 16) & 0xff), t3.x, t3.y, texpageX, texpageY, clutX, clutY, colourDepth
|
||||
//v4.x, v4.y, 0.0f, (((colour) >> 0) & 0xff), (((colour) >> 8) & 0xff), (((colour) >> 16) & 0xff), t4.x, t4.y // top left
|
||||
};
|
||||
|
||||
glViewport(0, 0, 1024, 512);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, FBO);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, VBO);
|
||||
glActiveTexture(GL_TEXTURE0 + 0); // Texture unit 0
|
||||
glBindTexture(GL_TEXTURE_2D, SampleVramTexture);
|
||||
glActiveTexture(GL_TEXTURE0 + 1); // Texture unit 1
|
||||
glBindTexture(GL_TEXTURE_2D, VramTexture8);
|
||||
glActiveTexture(GL_TEXTURE0 + 2); // Texture unit 2
|
||||
glBindTexture(GL_TEXTURE_2D, VramTexture4);
|
||||
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices1), Vertices1, GL_STATIC_DRAW);
|
||||
glBindVertexArray(VAO);
|
||||
// Position attribute
|
||||
glVertexAttribPointer(0, 3, GL_UNSIGNED_INT, GL_FALSE, 13 * sizeof(uint32_t), (void*)0);
|
||||
glEnableVertexAttribArray(0);
|
||||
// Colour attribute
|
||||
glVertexAttribPointer(1, 3, GL_UNSIGNED_INT, GL_FALSE, 13 * sizeof(uint32_t), (void*)(3 * sizeof(uint32_t)));
|
||||
glEnableVertexAttribArray(1);
|
||||
// texture coord attribute
|
||||
glVertexAttribPointer(2, 2, GL_UNSIGNED_INT, GL_FALSE, 13 * sizeof(uint32_t), (void*)(6 * sizeof(uint32_t)));
|
||||
glEnableVertexAttribArray(2);
|
||||
// texpage attribute
|
||||
glVertexAttribPointer(3, 2, GL_UNSIGNED_INT, GL_FALSE, 13 * sizeof(uint32_t), (void*)(8 * sizeof(uint32_t)));
|
||||
glEnableVertexAttribArray(3);
|
||||
// clut attribute
|
||||
glVertexAttribPointer(4, 2, GL_UNSIGNED_INT, GL_FALSE, 13 * sizeof(uint32_t), (void*)(10 * sizeof(uint32_t)));
|
||||
glEnableVertexAttribArray(4);
|
||||
// colour depth attribute
|
||||
glVertexAttribPointer(5, 1, GL_UNSIGNED_INT, GL_FALSE, 13 * sizeof(uint32_t), (void*)(12 * sizeof(uint32_t)));
|
||||
glEnableVertexAttribArray(5);
|
||||
glUseProgram(TextureShaderProgram);
|
||||
glUniform1i(colourDepthUniform, colourDepth);
|
||||
glBindVertexArray(VAO);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 3);
|
||||
glBindVertexArray(0);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, oldFBO);
|
||||
|
||||
uint32_t Vertices2[] = {
|
||||
// positions // colors // texture coords // texpage
|
||||
v2.x, v2.y, 0, (((colour) >> 0) & 0xff), (((colour) >> 8) & 0xff), (((colour) >> 16) & 0xff), t2.x, t2.y, texpageX, texpageY, clutX, clutY, colourDepth,
|
||||
v3.x, v3.y, 0.0f, (((colour) >> 0) & 0xff), (((colour) >> 8) & 0xff), (((colour) >> 16) & 0xff), t3.x, t3.y, texpageX, texpageY, clutX, clutY, colourDepth,
|
||||
v4.x, v4.y, 0.0f, (((colour) >> 0) & 0xff), (((colour) >> 8) & 0xff), (((colour) >> 16) & 0xff), t4.x, t4.y, texpageX, texpageY, clutX, clutY, colourDepth
|
||||
//v4.x, v4.y, 0.0f, (((colour) >> 0) & 0xff), (((colour) >> 8) & 0xff), (((colour) >> 16) & 0xff), t4.x, t4.y // top left
|
||||
};
|
||||
|
||||
glViewport(0, 0, 1024, 512);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, FBO);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, VBO);
|
||||
glActiveTexture(GL_TEXTURE0 + 0); // Texture unit 0
|
||||
glBindTexture(GL_TEXTURE_2D, SampleVramTexture);
|
||||
glActiveTexture(GL_TEXTURE0 + 1); // Texture unit 1
|
||||
glBindTexture(GL_TEXTURE_2D, VramTexture8);
|
||||
glActiveTexture(GL_TEXTURE0 + 2); // Texture unit 2
|
||||
glBindTexture(GL_TEXTURE_2D, VramTexture4);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices2), Vertices2, GL_STATIC_DRAW);
|
||||
glBindVertexArray(VAO);
|
||||
// Position attribute
|
||||
glVertexAttribPointer(0, 3, GL_UNSIGNED_INT, GL_FALSE, 13 * sizeof(uint32_t), (void*)0);
|
||||
glEnableVertexAttribArray(0);
|
||||
// Colour attribute
|
||||
glVertexAttribPointer(1, 3, GL_UNSIGNED_INT, GL_FALSE, 13 * sizeof(uint32_t), (void*)(3 * sizeof(uint32_t)));
|
||||
glEnableVertexAttribArray(1);
|
||||
// texture coord attribute
|
||||
glVertexAttribPointer(2, 2, GL_UNSIGNED_INT, GL_FALSE, 13 * sizeof(uint32_t), (void*)(6 * sizeof(uint32_t)));
|
||||
glEnableVertexAttribArray(2);
|
||||
// texpage attribute
|
||||
glVertexAttribPointer(3, 2, GL_UNSIGNED_INT, GL_FALSE, 13 * sizeof(uint32_t), (void*)(8 * sizeof(uint32_t)));
|
||||
glEnableVertexAttribArray(3);
|
||||
// clut attribute
|
||||
glVertexAttribPointer(4, 2, GL_UNSIGNED_INT, GL_FALSE, 13 * sizeof(uint32_t), (void*)(10 * sizeof(uint32_t)));
|
||||
glEnableVertexAttribArray(4);
|
||||
// colour depth attribute
|
||||
glVertexAttribPointer(5, 1, GL_UNSIGNED_INT, GL_FALSE, 13 * sizeof(uint32_t), (void*)(12 * sizeof(uint32_t)));
|
||||
glEnableVertexAttribArray(5);
|
||||
glUseProgram(TextureShaderProgram);
|
||||
glBindVertexArray(VAO);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 3);
|
||||
glBindVertexArray(0);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, oldFBO);
|
||||
}
|
||||
|
||||
void gpu::texture_four_point_semi_transparent_polygon() {
|
||||
uint32_t colour = fifo[0] & 0xffffff;
|
||||
debug_printf("[GP0] Textured four-point polygon, semi-transparent, raw-texture\n", colour);
|
||||
|
@ -2178,6 +2353,149 @@ void gpu::texture_rectangle_8x8_opaque() {
|
|||
glBindFramebuffer(GL_FRAMEBUFFER, oldFBO);
|
||||
}
|
||||
|
||||
void gpu::texture_blending_rectangle_16x16_opaque() {
|
||||
uint32_t colour = fifo[0] & 0xffffff;
|
||||
debug_printf("[GP0] Textured Rectangle, 16x16, opaque, texture-blending (colour: 0x%x)\n", colour);
|
||||
point v1, res, v2, v3, v4;
|
||||
uint16_t texpage = texpage_raw;
|
||||
uint16_t clut = 0;
|
||||
v1.x = fifo[1] & 0xffff;
|
||||
v1.y = fifo[1] >> 16;
|
||||
clut = fifo[2] >> 16;
|
||||
uint32_t clutX = (clut & 0x3f);
|
||||
clutX *= 16;
|
||||
uint32_t clutY = (clut >> 6);
|
||||
int Clut[256];
|
||||
for (int i = 0; i < 256; i++) {
|
||||
Clut[i] = vram_rgb[clutY * 1024 + clutX + i];
|
||||
}
|
||||
GLuint ssbo;
|
||||
GLuint binding = 10;
|
||||
glGenBuffers(1, &ssbo);
|
||||
glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssbo);
|
||||
glBufferData(GL_SHADER_STORAGE_BUFFER, 256 * sizeof(int), Clut, GL_STATIC_READ);
|
||||
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, binding, ssbo);
|
||||
//texpage = fifo[4] >> 16;
|
||||
uint32_t texpageX = ((texpage & 0b1111) * 64);
|
||||
uint32_t texpageY = (((texpage & 0b10000) >> 4) * 256);
|
||||
v2.x = v1.x + 8;
|
||||
v2.y = v1.y;
|
||||
v3.x = v1.x;
|
||||
v3.y = v1.y + 8;
|
||||
v4.x = v1.x + 8;
|
||||
v4.y = v1.y + 8;
|
||||
|
||||
v1.x += xoffset;
|
||||
v1.y += yoffset;
|
||||
v2.x += xoffset;
|
||||
v2.y += yoffset;
|
||||
v3.x += xoffset;
|
||||
v3.y += yoffset;
|
||||
v4.x += xoffset;
|
||||
v4.y += yoffset;
|
||||
|
||||
point t1, t2, t3, t4;
|
||||
t1.x = (fifo[2] & 0xffff) & 0xff;
|
||||
t1.y = ((fifo[2] & 0xffff) >> 8) & 0xff;
|
||||
t2.x = t1.x + 16;
|
||||
t2.y = t1.y;
|
||||
t3.x = t1.x;
|
||||
t3.y = t1.y + 16;
|
||||
t4.x = t1.x + 16;
|
||||
t4.y = t1.y + 16;
|
||||
int colourDepth = (texpage >> 7) & 3;
|
||||
|
||||
uint32_t Vertices1[] = {
|
||||
// positions // colors // texture coords
|
||||
v1.x, v1.y, 0, (((colour) >> 0) & 0xff), (((colour) >> 8) & 0xff), (((colour) >> 16) & 0xff), t1.x, t1.y, texpageX, texpageY, clutX, clutY, colourDepth,
|
||||
v2.x, v2.y, 0.0f, (((colour) >> 0) & 0xff), (((colour) >> 8) & 0xff), (((colour) >> 16) & 0xff), t2.x, t2.y, texpageX, texpageY, clutX, clutY, colourDepth,
|
||||
v3.x, v3.y, 0.0f, (((colour) >> 0) & 0xff), (((colour) >> 8) & 0xff), (((colour) >> 16) & 0xff), t3.x, t3.y, texpageX, texpageY, clutX, clutY, colourDepth
|
||||
//v4.x, v4.y, 0.0f, (((colour) >> 0) & 0xff), (((colour) >> 8) & 0xff), (((colour) >> 16) & 0xff), t4.x, t4.y // top left
|
||||
};
|
||||
|
||||
glViewport(0, 0, 1024, 512);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, FBO);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, VBO);
|
||||
glActiveTexture(GL_TEXTURE0 + 0); // Texture unit 0
|
||||
glBindTexture(GL_TEXTURE_2D, SampleVramTexture);
|
||||
glActiveTexture(GL_TEXTURE0 + 1); // Texture unit 1
|
||||
glBindTexture(GL_TEXTURE_2D, VramTexture8);
|
||||
glActiveTexture(GL_TEXTURE0 + 2); // Texture unit 2
|
||||
glBindTexture(GL_TEXTURE_2D, VramTexture4);
|
||||
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices1), Vertices1, GL_STATIC_DRAW);
|
||||
glBindVertexArray(VAO);
|
||||
// Position attribute
|
||||
glVertexAttribPointer(0, 3, GL_UNSIGNED_INT, GL_FALSE, 13 * sizeof(uint32_t), (void*)0);
|
||||
glEnableVertexAttribArray(0);
|
||||
// Colour attribute
|
||||
glVertexAttribPointer(1, 3, GL_UNSIGNED_INT, GL_FALSE, 13 * sizeof(uint32_t), (void*)(3 * sizeof(uint32_t)));
|
||||
glEnableVertexAttribArray(1);
|
||||
// texture coord attribute
|
||||
glVertexAttribPointer(2, 2, GL_UNSIGNED_INT, GL_FALSE, 13 * sizeof(uint32_t), (void*)(6 * sizeof(uint32_t)));
|
||||
glEnableVertexAttribArray(2);
|
||||
// texpage attribute
|
||||
glVertexAttribPointer(3, 2, GL_UNSIGNED_INT, GL_FALSE, 13 * sizeof(uint32_t), (void*)(8 * sizeof(uint32_t)));
|
||||
glEnableVertexAttribArray(3);
|
||||
// clut attribute
|
||||
glVertexAttribPointer(4, 2, GL_UNSIGNED_INT, GL_FALSE, 13 * sizeof(uint32_t), (void*)(10 * sizeof(uint32_t)));
|
||||
glEnableVertexAttribArray(4);
|
||||
// colour depth attribute
|
||||
glVertexAttribPointer(5, 1, GL_UNSIGNED_INT, GL_FALSE, 13 * sizeof(uint32_t), (void*)(12 * sizeof(uint32_t)));
|
||||
glEnableVertexAttribArray(5);
|
||||
glUseProgram(TextureShaderProgram);
|
||||
glUniform1i(colourDepthUniform, colourDepth);
|
||||
glBindVertexArray(VAO);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 3);
|
||||
glBindVertexArray(0);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, oldFBO);
|
||||
|
||||
uint32_t Vertices2[] = {
|
||||
// positions // colors // texture coords // texpage
|
||||
v2.x, v2.y, 0, (((colour) >> 0) & 0xff), (((colour) >> 8) & 0xff), (((colour) >> 16) & 0xff), t2.x, t2.y, texpageX, texpageY, clutX, clutY, colourDepth,
|
||||
v3.x, v3.y, 0.0f, (((colour) >> 0) & 0xff), (((colour) >> 8) & 0xff), (((colour) >> 16) & 0xff), t3.x, t3.y, texpageX, texpageY, clutX, clutY, colourDepth,
|
||||
v4.x, v4.y, 0.0f, (((colour) >> 0) & 0xff), (((colour) >> 8) & 0xff), (((colour) >> 16) & 0xff), t4.x, t4.y, texpageX, texpageY, clutX, clutY, colourDepth
|
||||
//v4.x, v4.y, 0.0f, (((colour) >> 0) & 0xff), (((colour) >> 8) & 0xff), (((colour) >> 16) & 0xff), t4.x, t4.y // top left
|
||||
};
|
||||
|
||||
glViewport(0, 0, 1024, 512);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, FBO);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, VBO);
|
||||
glActiveTexture(GL_TEXTURE0 + 0); // Texture unit 0
|
||||
glBindTexture(GL_TEXTURE_2D, SampleVramTexture);
|
||||
glActiveTexture(GL_TEXTURE0 + 1); // Texture unit 1
|
||||
glBindTexture(GL_TEXTURE_2D, VramTexture8);
|
||||
glActiveTexture(GL_TEXTURE0 + 2); // Texture unit 2
|
||||
glBindTexture(GL_TEXTURE_2D, VramTexture4);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices2), Vertices2, GL_STATIC_DRAW);
|
||||
glBindVertexArray(VAO);
|
||||
// Position attribute
|
||||
glVertexAttribPointer(0, 3, GL_UNSIGNED_INT, GL_FALSE, 13 * sizeof(uint32_t), (void*)0);
|
||||
glEnableVertexAttribArray(0);
|
||||
// Colour attribute
|
||||
glVertexAttribPointer(1, 3, GL_UNSIGNED_INT, GL_FALSE, 13 * sizeof(uint32_t), (void*)(3 * sizeof(uint32_t)));
|
||||
glEnableVertexAttribArray(1);
|
||||
// texture coord attribute
|
||||
glVertexAttribPointer(2, 2, GL_UNSIGNED_INT, GL_FALSE, 13 * sizeof(uint32_t), (void*)(6 * sizeof(uint32_t)));
|
||||
glEnableVertexAttribArray(2);
|
||||
// texpage attribute
|
||||
glVertexAttribPointer(3, 2, GL_UNSIGNED_INT, GL_FALSE, 13 * sizeof(uint32_t), (void*)(8 * sizeof(uint32_t)));
|
||||
glEnableVertexAttribArray(3);
|
||||
// clut attribute
|
||||
glVertexAttribPointer(4, 2, GL_UNSIGNED_INT, GL_FALSE, 13 * sizeof(uint32_t), (void*)(10 * sizeof(uint32_t)));
|
||||
glEnableVertexAttribArray(4);
|
||||
// colour depth attribute
|
||||
glVertexAttribPointer(5, 1, GL_UNSIGNED_INT, GL_FALSE, 13 * sizeof(uint32_t), (void*)(12 * sizeof(uint32_t)));
|
||||
glEnableVertexAttribArray(5);
|
||||
glUseProgram(TextureShaderProgram);
|
||||
glBindVertexArray(VAO);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 3);
|
||||
glBindVertexArray(0);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, oldFBO);
|
||||
}
|
||||
|
||||
void gpu::texture_rectangle_variable_size_opaque() {
|
||||
uint32_t colour = fifo[0] & 0xffffff;
|
||||
debug_printf("[GP0] Textured Rectangle, variable size, opaque, raw-texture (colour: 0x%x)\n", colour);
|
||||
|
@ -2468,6 +2786,151 @@ void gpu::texture_blending_rectangle_variable_size_semi_transparent() {
|
|||
glBindFramebuffer(GL_FRAMEBUFFER, oldFBO);
|
||||
}
|
||||
|
||||
void gpu::textured_rectangle_variable_size_semi_transparent() {
|
||||
uint32_t colour = fifo[0] & 0xffffff;
|
||||
debug_printf("[GP0] Textured Rectangle, variable size, semi-transp, raw-texture (colour: 0x%x)\n", colour);
|
||||
point v1, res, v2, v3, v4;
|
||||
uint16_t texpage = texpage_raw;
|
||||
uint16_t clut = 0;
|
||||
v1.x = fifo[1] & 0xffff;
|
||||
v1.y = fifo[1] >> 16;
|
||||
clut = fifo[2] >> 16;
|
||||
uint32_t clutX = (clut & 0x3f);
|
||||
clutX *= 16;
|
||||
uint32_t clutY = (clut >> 6);
|
||||
int Clut[256];
|
||||
for (int i = 0; i < 256; i++) {
|
||||
Clut[i] = vram_rgb[clutY * 1024 + clutX + i];
|
||||
}
|
||||
GLuint ssbo;
|
||||
GLuint binding = 10;
|
||||
glGenBuffers(1, &ssbo);
|
||||
glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssbo);
|
||||
glBufferData(GL_SHADER_STORAGE_BUFFER, 256 * sizeof(int), Clut, GL_STATIC_READ);
|
||||
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, binding, ssbo);
|
||||
//texpage = fifo[4] >> 16;
|
||||
uint32_t texpageX = ((texpage & 0b1111) * 64);
|
||||
uint32_t texpageY = (((texpage & 0b10000) >> 4) * 256);
|
||||
res.x = fifo[3] & 0xffff;
|
||||
res.y = fifo[3] >> 16;
|
||||
v2.x = v1.x + res.x;
|
||||
v2.y = v1.y;
|
||||
v3.x = v1.x;
|
||||
v3.y = v1.y + res.y;
|
||||
v4.x = v1.x + res.x;
|
||||
v4.y = v1.y + res.y;
|
||||
|
||||
v1.x += xoffset;
|
||||
v1.y += yoffset;
|
||||
v2.x += xoffset;
|
||||
v2.y += yoffset;
|
||||
v3.x += xoffset;
|
||||
v3.y += yoffset;
|
||||
v4.x += xoffset;
|
||||
v4.y += yoffset;
|
||||
|
||||
point t1, t2, t3, t4;
|
||||
t1.x = (fifo[2] & 0xffff) & 0xff;
|
||||
t1.y = ((fifo[2] & 0xffff) >> 8) & 0xff;
|
||||
t2.x = t1.x + res.x;
|
||||
t2.y = t1.y;
|
||||
t3.x = t1.x;
|
||||
t3.y = t1.y + res.y;
|
||||
t4.x = t1.x + res.x;
|
||||
t4.y = t1.y + res.y;
|
||||
int colourDepth = (texpage >> 7) & 3;
|
||||
|
||||
uint32_t Vertices1[] = {
|
||||
// positions // colors // texture coords
|
||||
v1.x, v1.y, 0, (((colour) >> 0) & 0xff), (((colour) >> 8) & 0xff), (((colour) >> 16) & 0xff), t1.x, t1.y, texpageX, texpageY, clutX, clutY, colourDepth,
|
||||
v2.x, v2.y, 0.0f, (((colour) >> 0) & 0xff), (((colour) >> 8) & 0xff), (((colour) >> 16) & 0xff), t2.x, t2.y, texpageX, texpageY, clutX, clutY, colourDepth,
|
||||
v3.x, v3.y, 0.0f, (((colour) >> 0) & 0xff), (((colour) >> 8) & 0xff), (((colour) >> 16) & 0xff), t3.x, t3.y, texpageX, texpageY, clutX, clutY, colourDepth
|
||||
//v4.x, v4.y, 0.0f, (((colour) >> 0) & 0xff), (((colour) >> 8) & 0xff), (((colour) >> 16) & 0xff), t4.x, t4.y // top left
|
||||
};
|
||||
|
||||
glViewport(0, 0, 1024, 512);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, FBO);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, VBO);
|
||||
glActiveTexture(GL_TEXTURE0 + 0); // Texture unit 0
|
||||
glBindTexture(GL_TEXTURE_2D, SampleVramTexture);
|
||||
glActiveTexture(GL_TEXTURE0 + 1); // Texture unit 1
|
||||
glBindTexture(GL_TEXTURE_2D, VramTexture8);
|
||||
glActiveTexture(GL_TEXTURE0 + 2); // Texture unit 2
|
||||
glBindTexture(GL_TEXTURE_2D, VramTexture4);
|
||||
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices1), Vertices1, GL_STATIC_DRAW);
|
||||
glBindVertexArray(VAO);
|
||||
// Position attribute
|
||||
glVertexAttribPointer(0, 3, GL_UNSIGNED_INT, GL_FALSE, 13 * sizeof(uint32_t), (void*)0);
|
||||
glEnableVertexAttribArray(0);
|
||||
// Colour attribute
|
||||
glVertexAttribPointer(1, 3, GL_UNSIGNED_INT, GL_FALSE, 13 * sizeof(uint32_t), (void*)(3 * sizeof(uint32_t)));
|
||||
glEnableVertexAttribArray(1);
|
||||
// texture coord attribute
|
||||
glVertexAttribPointer(2, 2, GL_UNSIGNED_INT, GL_FALSE, 13 * sizeof(uint32_t), (void*)(6 * sizeof(uint32_t)));
|
||||
glEnableVertexAttribArray(2);
|
||||
// texpage attribute
|
||||
glVertexAttribPointer(3, 2, GL_UNSIGNED_INT, GL_FALSE, 13 * sizeof(uint32_t), (void*)(8 * sizeof(uint32_t)));
|
||||
glEnableVertexAttribArray(3);
|
||||
// clut attribute
|
||||
glVertexAttribPointer(4, 2, GL_UNSIGNED_INT, GL_FALSE, 13 * sizeof(uint32_t), (void*)(10 * sizeof(uint32_t)));
|
||||
glEnableVertexAttribArray(4);
|
||||
// colour depth attribute
|
||||
glVertexAttribPointer(5, 1, GL_UNSIGNED_INT, GL_FALSE, 13 * sizeof(uint32_t), (void*)(12 * sizeof(uint32_t)));
|
||||
glEnableVertexAttribArray(5);
|
||||
glUseProgram(TextureShaderProgram);
|
||||
glUniform1i(colourDepthUniform, colourDepth);
|
||||
glBindVertexArray(VAO);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 3);
|
||||
glBindVertexArray(0);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, oldFBO);
|
||||
|
||||
uint32_t Vertices2[] = {
|
||||
// positions // colors // texture coords // texpage
|
||||
v2.x, v2.y, 0, (((colour) >> 0) & 0xff), (((colour) >> 8) & 0xff), (((colour) >> 16) & 0xff), t2.x, t2.y, texpageX, texpageY, clutX, clutY, colourDepth,
|
||||
v3.x, v3.y, 0.0f, (((colour) >> 0) & 0xff), (((colour) >> 8) & 0xff), (((colour) >> 16) & 0xff), t3.x, t3.y, texpageX, texpageY, clutX, clutY, colourDepth,
|
||||
v4.x, v4.y, 0.0f, (((colour) >> 0) & 0xff), (((colour) >> 8) & 0xff), (((colour) >> 16) & 0xff), t4.x, t4.y, texpageX, texpageY, clutX, clutY, colourDepth
|
||||
//v4.x, v4.y, 0.0f, (((colour) >> 0) & 0xff), (((colour) >> 8) & 0xff), (((colour) >> 16) & 0xff), t4.x, t4.y // top left
|
||||
};
|
||||
|
||||
glViewport(0, 0, 1024, 512);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, FBO);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, VBO);
|
||||
glActiveTexture(GL_TEXTURE0 + 0); // Texture unit 0
|
||||
glBindTexture(GL_TEXTURE_2D, SampleVramTexture);
|
||||
glActiveTexture(GL_TEXTURE0 + 1); // Texture unit 1
|
||||
glBindTexture(GL_TEXTURE_2D, VramTexture8);
|
||||
glActiveTexture(GL_TEXTURE0 + 2); // Texture unit 2
|
||||
glBindTexture(GL_TEXTURE_2D, VramTexture4);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices2), Vertices2, GL_STATIC_DRAW);
|
||||
glBindVertexArray(VAO);
|
||||
// Position attribute
|
||||
glVertexAttribPointer(0, 3, GL_UNSIGNED_INT, GL_FALSE, 13 * sizeof(uint32_t), (void*)0);
|
||||
glEnableVertexAttribArray(0);
|
||||
// Colour attribute
|
||||
glVertexAttribPointer(1, 3, GL_UNSIGNED_INT, GL_FALSE, 13 * sizeof(uint32_t), (void*)(3 * sizeof(uint32_t)));
|
||||
glEnableVertexAttribArray(1);
|
||||
// texture coord attribute
|
||||
glVertexAttribPointer(2, 2, GL_UNSIGNED_INT, GL_FALSE, 13 * sizeof(uint32_t), (void*)(6 * sizeof(uint32_t)));
|
||||
glEnableVertexAttribArray(2);
|
||||
// texpage attribute
|
||||
glVertexAttribPointer(3, 2, GL_UNSIGNED_INT, GL_FALSE, 13 * sizeof(uint32_t), (void*)(8 * sizeof(uint32_t)));
|
||||
glEnableVertexAttribArray(3);
|
||||
// clut attribute
|
||||
glVertexAttribPointer(4, 2, GL_UNSIGNED_INT, GL_FALSE, 13 * sizeof(uint32_t), (void*)(10 * sizeof(uint32_t)));
|
||||
glEnableVertexAttribArray(4);
|
||||
// colour depth attribute
|
||||
glVertexAttribPointer(5, 1, GL_UNSIGNED_INT, GL_FALSE, 13 * sizeof(uint32_t), (void*)(12 * sizeof(uint32_t)));
|
||||
glEnableVertexAttribArray(5);
|
||||
glUseProgram(TextureShaderProgram);
|
||||
glBindVertexArray(VAO);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 3);
|
||||
glBindVertexArray(0);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, oldFBO);
|
||||
}
|
||||
|
||||
void gpu::monochrome_rectangle_dot_opaque() {
|
||||
uint16_t x = fifo[1] & 0xffff;
|
||||
uint16_t y = fifo[1] >> 16;
|
||||
|
@ -2484,6 +2947,80 @@ void gpu::monochrome_rectangle_dot_opaque() {
|
|||
return;
|
||||
}
|
||||
|
||||
void gpu::monochrome_rectangle_8x8_opaque() {
|
||||
uint32_t colour = fifo[0] & 0xffffff;
|
||||
debug_printf("[GP0] Monochrome Rectangle (8x8) (opaque) (colour: 0x%x)\n", colour);
|
||||
point v1, res, v2, v3, v4;
|
||||
v1.x = fifo[1] & 0xffff;
|
||||
v1.y = fifo[1] >> 16;
|
||||
v2.x = v1.x + 8;
|
||||
v2.y = v1.y;
|
||||
v3.x = v1.x;
|
||||
v3.y = v1.y + 8;
|
||||
v4.x = v1.x + 8;
|
||||
v4.y = v1.y + 8;
|
||||
|
||||
v1.x += xoffset;
|
||||
v1.y += yoffset;
|
||||
v2.x += xoffset;
|
||||
v2.y += yoffset;
|
||||
v3.x += xoffset;
|
||||
v3.y += yoffset;
|
||||
v4.x += xoffset;
|
||||
v4.y += yoffset;
|
||||
|
||||
uint32_t Vertices1[]{
|
||||
v1.x, v1.y, 0,
|
||||
v2.x, v2.y, 0,
|
||||
v3.x, v3.y, 0,
|
||||
|
||||
(((colour) >> 0) & 0xff), (((colour) >> 8) & 0xff), (((colour) >> 16) & 0xff),
|
||||
(((colour) >> 0) & 0xff), (((colour) >> 8) & 0xff), (((colour) >> 16) & 0xff),
|
||||
(((colour) >> 0) & 0xff), (((colour) >> 8) & 0xff), (((colour) >> 16) & 0xff)
|
||||
};
|
||||
|
||||
glViewport(0, 0, 1024, 512);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, FBO);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, VBO);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices1), Vertices1, GL_STATIC_DRAW);
|
||||
glBindVertexArray(VAO);
|
||||
glVertexAttribIPointer(0, 3, GL_INT, 3 * sizeof(uint32_t), (void*)0);
|
||||
glEnableVertexAttribArray(0);
|
||||
glVertexAttribPointer(1, 3, GL_UNSIGNED_INT, GL_FALSE, 3 * sizeof(uint32_t), (void*)(9 * sizeof(uint32_t)));
|
||||
glEnableVertexAttribArray(1);
|
||||
glUseProgram(ShaderProgram);
|
||||
glBindVertexArray(VAO);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 3);
|
||||
glBindVertexArray(0);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, oldFBO);
|
||||
|
||||
uint32_t Vertices2[]{
|
||||
v2.x, v2.y, 0.0,
|
||||
v3.x, v3.y, 0.0,
|
||||
v4.x, v4.y, 0.0,
|
||||
|
||||
(((colour) >> 0) & 0xff), (((colour) >> 8) & 0xff), (((colour) >> 16) & 0xff),
|
||||
(((colour) >> 0) & 0xff), (((colour) >> 8) & 0xff), (((colour) >> 16) & 0xff),
|
||||
(((colour) >> 0) & 0xff), (((colour) >> 8) & 0xff), (((colour) >> 16) & 0xff)
|
||||
};
|
||||
glViewport(0, 0, 1024, 512);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, FBO);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, VBO);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices2), Vertices2, GL_STATIC_DRAW);
|
||||
glBindVertexArray(VAO);
|
||||
glVertexAttribIPointer(0, 3, GL_INT, 3 * sizeof(uint32_t), (void*)0);
|
||||
glEnableVertexAttribArray(0);
|
||||
glVertexAttribPointer(1, 3, GL_UNSIGNED_INT, GL_FALSE, 3 * sizeof(uint32_t), (void*)(9 * sizeof(uint32_t)));
|
||||
glEnableVertexAttribArray(1);
|
||||
glUseProgram(ShaderProgram);
|
||||
glBindVertexArray(VAO);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 3);
|
||||
glBindVertexArray(0);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, oldFBO);
|
||||
}
|
||||
|
||||
void gpu::fill_rectangle() {
|
||||
debug_printf("[GP0] Fill Rectangle\n");
|
||||
glViewport(0, 0, 1024, 512);
|
||||
|
@ -2518,12 +3055,20 @@ void gpu::cpu_to_vram() {
|
|||
size &= ~1;
|
||||
cmd_left = size / 2;
|
||||
gp0_mode = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
void gpu::vram_to_cpu() {
|
||||
uint32_t resolution = fifo[2];
|
||||
uint32_t coords = fifo[1];
|
||||
auto width = resolution & 0xffff;
|
||||
auto height = resolution >> 16;
|
||||
return;
|
||||
if (width == 0) width = 1024;
|
||||
if (height == 0) height = 512;
|
||||
|
||||
auto x = coords & 0x3ff;
|
||||
auto y = (coords >> 16) & 0x1ff;
|
||||
|
||||
uint32_t size = width * height;
|
||||
size += 1;
|
||||
size &= ~1;
|
||||
}
|
17
gpu.h
17
gpu.h
|
@ -111,12 +111,22 @@ public: // trongle stuff
|
|||
return texelFetch(vram, ivec2(clut.x + idx, clut.y), 0);
|
||||
}
|
||||
|
||||
vec4 fetchTexel8Bit(ivec2 coords) {
|
||||
int texel = sample16(ivec2(coords.x / 2, coords.y) + ivec2(texpageCoords));
|
||||
int idx = (texel >> ((coords.x % 2) * 8)) & 0xff;
|
||||
return texelFetch(vram, ivec2(clut.x + idx, clut.y), 0);
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 colour;
|
||||
if(colourDepth == 0) {
|
||||
colour = fetchTexel4Bit(ivec2(TexCoord));
|
||||
} else if (colourDepth == 2) {
|
||||
}
|
||||
else if (colourDepth == 1) {
|
||||
colour = fetchTexel8Bit(ivec2(TexCoord));
|
||||
}
|
||||
else if (colourDepth == 2) {
|
||||
vec2 TexCoords = vec2(float(TexCoord.x + texpageCoords.x) / 1024.f - 1, -(1 - float(TexCoord.y + texpageCoords.y) / 512.f));
|
||||
colour = texture(vram, TexCoords);
|
||||
} else colour = vec4(1.f, 0.f, 0.f, 1.f);
|
||||
|
@ -148,6 +158,7 @@ public:
|
|||
uint16_t* vram = new uint16_t[1024 * 512];
|
||||
//std::vector<uint32_t> WriteBuffer;
|
||||
uint32_t* WriteBuffer = new uint32_t[(1024 * 512) / 2];
|
||||
std::vector<uint32_t> ReadBuffer;
|
||||
int WriteBufferCnt = 0;
|
||||
uint32_t* vram8 = new uint32_t[1024 * 512];
|
||||
uint32_t* vram4 = new uint32_t[1024 * 512];
|
||||
|
@ -207,14 +218,18 @@ public: // commands
|
|||
void shaded_four_point_opaque_polygon();
|
||||
void shaded_four_point_semi_transparent_polygon();
|
||||
void shaded_texture_blending_textured_four_point_opaque_polygon();
|
||||
void texture_blending_four_point_polygon_semi_transparent();
|
||||
void monochrome_rectangle_variable_size_opaque();
|
||||
void monochrome_rectangle_variable_size_semi_transparent();
|
||||
void texture_blending_rectangle_variable_size_opaque();
|
||||
void texture_rectangle_variable_size_opaque();
|
||||
void texture_blending_rectangle_variable_size_semi_transparent();
|
||||
void textured_rectangle_variable_size_semi_transparent();
|
||||
void texture_blending_rectangle_8x8_opaque();
|
||||
void texture_rectangle_8x8_opaque();
|
||||
void texture_blending_rectangle_16x16_opaque();
|
||||
void monochrome_rectangle_dot_opaque();
|
||||
void monochrome_rectangle_8x8_opaque();
|
||||
void fill_rectangle();
|
||||
void cpu_to_vram();
|
||||
void vram_to_cpu();
|
||||
|
|
|
@ -4,17 +4,17 @@ Size=400,400
|
|||
Collapsed=0
|
||||
|
||||
[Window][Image]
|
||||
Pos=0,22
|
||||
Size=657,648
|
||||
Pos=3,20
|
||||
Size=652,650
|
||||
Collapsed=0
|
||||
|
||||
[Window][System Settings]
|
||||
Pos=1034,713
|
||||
Pos=1015,701
|
||||
Size=578,252
|
||||
Collapsed=0
|
||||
|
||||
[Window][Imagevram]
|
||||
Pos=663,22
|
||||
Pos=661,22
|
||||
Size=1263,645
|
||||
Collapsed=0
|
||||
|
||||
|
|
59
memory.cpp
59
memory.cpp
|
@ -21,12 +21,17 @@ void TMR1IRQ(void* dataptr) {
|
|||
memory* memoryptr = (memory*)dataptr;
|
||||
memoryptr->I_STAT |= 0b100000;
|
||||
memoryptr->CDROM.Scheduler.push(&TMR1IRQ, memoryptr->CDROM.Scheduler.time + 5000, memoryptr);
|
||||
//printf("[TIMERS] Sending TMR1 IRQ (stub)\n");
|
||||
////printf("[TIMER]] Sending TMR1 IRQ (stub)\n");
|
||||
}
|
||||
void TMR2IRQ(void* dataptr) {
|
||||
memory* memoryptr = (memory*)dataptr;
|
||||
memoryptr->I_STAT |= 0b1000000;
|
||||
}
|
||||
void DMAIRQ(void* dataptr) {
|
||||
memory* memoryptr = (memory*)dataptr;
|
||||
memoryptr->I_STAT |= 0b1000;
|
||||
memoryptr->DICR |= (1 << 28);
|
||||
}
|
||||
memory::memory() {
|
||||
debug = false;
|
||||
}
|
||||
|
@ -112,8 +117,8 @@ uint8_t memory::read(uint32_t addr) {
|
|||
}
|
||||
|
||||
if (masked_addr == 0x1f801800) { // cdrom status
|
||||
printf("[CDROM] Status register read\n");
|
||||
//return rand() % 0xff;
|
||||
//printf("[CDROM] Status register read\n");
|
||||
return rand() % 0xff;
|
||||
return CDROM.status | (CDROM.cd.drqsts << 6);
|
||||
}
|
||||
|
||||
|
@ -187,7 +192,7 @@ uint16_t memory::read16(uint32_t addr) {
|
|||
|
||||
// Timer 0 current value
|
||||
if (masked_addr == 0x1f801100) {
|
||||
printf("[TIMER] Read timer 0 current value\n");
|
||||
//printf("[TIMER] Read timer 0 current value\n");
|
||||
tmr1_stub += rand() % 4;
|
||||
return tmr1_stub;
|
||||
}
|
||||
|
@ -205,7 +210,8 @@ uint16_t memory::read16(uint32_t addr) {
|
|||
|
||||
if (masked_addr == 0x1f801120) { // timer 2 stuff
|
||||
//printf("[TIMER] Read timer 2 current value (stubbed)\n");
|
||||
return tmr1_stub++;
|
||||
tmr1_stub += rand() % 4;
|
||||
return tmr1_stub;
|
||||
}
|
||||
|
||||
if (masked_addr == 0x1f801124) {
|
||||
|
@ -240,7 +246,7 @@ uint16_t memory::read16(uint32_t addr) {
|
|||
//}
|
||||
|
||||
if (masked_addr >= 0x1F801D80 && masked_addr <= 0x1F801DBC) { // SPUSTAT
|
||||
printf("[SPU] SPUSTAT read (stubbed)\n");
|
||||
//printf("[SPU] SPUSTAT read (stubbed)\n");
|
||||
return rand() % 0xff;
|
||||
}
|
||||
|
||||
|
@ -299,7 +305,7 @@ uint32_t memory::read32(uint32_t addr) {
|
|||
|
||||
// Timer 1 counter mode
|
||||
if (masked_addr == 0x1f801114) {
|
||||
//printf("[TIMER] Read timer 1 counter mode (stubbed)\n");
|
||||
printf("[TIMER] Read timer 1 counter mode (stubbed)\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -334,8 +340,9 @@ uint32_t memory::read32(uint32_t addr) {
|
|||
return 0b01011110100000000000000000000000; // stubbing it
|
||||
}
|
||||
|
||||
if (masked_addr == 0x1f801810) // GPUREAD
|
||||
if (masked_addr == 0x1f801810) { // GPUREAD
|
||||
return gpuread;
|
||||
}
|
||||
|
||||
// dma
|
||||
if (masked_addr == 0x1f8010f0) // DCPR
|
||||
|
@ -344,6 +351,22 @@ uint32_t memory::read32(uint32_t addr) {
|
|||
if (masked_addr == 0x1f8010f4) // DICR
|
||||
return DICR;
|
||||
|
||||
// channel 1 (stubbed)
|
||||
if (masked_addr == 0x1f801090) { // base address
|
||||
printf("[DMA] Read DMA1 (mdec -> ram) base address (stubbed)\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (masked_addr == 0x1f801094) { // block control
|
||||
printf("[DMA] Read DMA1 (mdec -> ram) block control (stubbed)\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (masked_addr == 0x1f801098) { // control
|
||||
printf("[DMA] Read DMA1 (mdec -> ram) control (stubbed)\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// channel 2
|
||||
if (masked_addr == 0x1f8010a0) // base address
|
||||
return Ch2.MADR;
|
||||
|
@ -396,6 +419,12 @@ uint32_t memory::read32(uint32_t addr) {
|
|||
}
|
||||
#endif
|
||||
|
||||
// SPU
|
||||
if (masked_addr == 0x1F801D9C) {
|
||||
printf("[SPU] Read Voice 0..23 ON/OFF (stubbed)\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// MDEC
|
||||
if (masked_addr == 0x1f801820) {
|
||||
printf("[MDEC] Read MDEC Data/Response Register (stubbed)\n");
|
||||
|
@ -498,7 +527,7 @@ void memory::write(uint32_t addr, uint8_t data, bool log) {
|
|||
}
|
||||
|
||||
if (masked_addr == 0x1f801104 || masked_addr == 0x1f801108 || masked_addr == 0x1f801100 || masked_addr == 0x1f801114 || masked_addr == 0x1f801118) {
|
||||
//printf("[TIMERS] Write timer 0/1 regs (0x%08x)\n", masked_addr);
|
||||
////printf("[TIMER]] Write timer 0/1 regs (0x%08x)\n", masked_addr);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -658,7 +687,7 @@ void memory::write32(uint32_t addr, uint32_t data) {
|
|||
return;
|
||||
}
|
||||
if (masked_addr == 0x1f8010c8) {
|
||||
//CDROM.Scheduler.push(&DMAIRQ, CDROM.Scheduler.time + 5000, this);
|
||||
CDROM.Scheduler.push(&DMAIRQ, CDROM.Scheduler.time + 5000, this);
|
||||
Ch4.CHCR = data;
|
||||
return;
|
||||
}
|
||||
|
@ -679,15 +708,15 @@ void memory::write32(uint32_t addr, uint32_t data) {
|
|||
}
|
||||
|
||||
if (masked_addr == 0x1f801114) {
|
||||
////printf("[TIMERS] Sending TMR1 IRQ (stub)\n");
|
||||
//printf("[TIMER] Write timer 2 counter mode\n");
|
||||
//////printf("[TIMER]] Sending TMR1 IRQ (stub)\n");
|
||||
printf("[TIMER] Write timer 2 counter mode\n");
|
||||
tmr1_stub = 0;
|
||||
//CDROM.Scheduler.push(&TMR1IRQ, CDROM.Scheduler.time + 5000, this);
|
||||
return;
|
||||
}
|
||||
|
||||
if (masked_addr == 0x1f801104 || masked_addr == 0x1f801108 || masked_addr == 0x1f801100 || masked_addr == 0x1f801114 || masked_addr == 0x1f801118) {
|
||||
//printf("[TIMERS] Write timer 0/1 regs (0x%08x)\n", masked_addr);
|
||||
////printf("[TIMER]] Write timer 0/1 regs (0x%08x)\n", masked_addr);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -761,13 +790,13 @@ void memory::write16(uint32_t addr, uint16_t data) {
|
|||
}
|
||||
|
||||
if (masked_addr == 0x1f801110) {
|
||||
//printf("[TIMER] Write timer 1 current value\n");
|
||||
printf("[TIMER] Write timer 1 current value\n");
|
||||
tmr1_stub = data;
|
||||
return;
|
||||
}
|
||||
|
||||
if (masked_addr == 0x1f801104 || masked_addr == 0x1f801108 || masked_addr == 0x1f801100 || masked_addr == 0x1f801114 || masked_addr == 0x1f801118 || masked_addr == 0x1f801110 || masked_addr == 0x1f801124 || masked_addr == masked_addr == 0x1f801124 || masked_addr == 0x1f801128 || masked_addr == 0x1f801120) {
|
||||
//printf("[TIMER] Write timer regs\n");
|
||||
printf("[TIMER] Write timer regs\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue