mirror of
https://github.com/liuk7071/ChonkyStation.git
synced 2025-04-02 10:52:38 -04:00
2412 lines
No EOL
85 KiB
C++
2412 lines
No EOL
85 KiB
C++
#include "gpu.h"
|
|
#include "Bus.h"
|
|
#include <cmath>
|
|
Bus* bus;
|
|
|
|
gpu::gpu() {
|
|
debug = false;
|
|
}
|
|
|
|
void connectBus(Bus* _bus) {
|
|
bus = _bus;
|
|
}
|
|
|
|
#define LOG
|
|
#undef LOG
|
|
|
|
inline void gpu::debug_printf(const char* fmt, ...) {
|
|
#ifdef LOG
|
|
if (debug) {
|
|
std::va_list args;
|
|
va_start(args, fmt);
|
|
std::vprintf(fmt, args);
|
|
va_end(args);
|
|
}
|
|
#endif
|
|
}
|
|
|
|
uint32_t gpu::get_status() {
|
|
uint32_t status = 0b01011110100000000000000000000000;
|
|
status |= page_base_x << 0;
|
|
status |= page_base_y << 3;
|
|
status |= texture_disable << 15;
|
|
status |= interlace << 31;
|
|
|
|
return status;
|
|
}
|
|
|
|
void gpu::InitGL() {
|
|
//WriteBuffer.reserve(1024 * 512);
|
|
//WriteBuffer.clear();
|
|
glGetIntegerv(GL_FRAMEBUFFER_BINDING, &oldFBO);
|
|
glGenFramebuffers(1, &FBO);
|
|
glBindFramebuffer(GL_FRAMEBUFFER, FBO);
|
|
|
|
glGenTextures(1, &id);
|
|
glBindTexture(GL_TEXTURE_2D, id);
|
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 640, 480, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
|
glBindTexture(GL_TEXTURE_2D, 0);
|
|
//glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, id, 0);
|
|
//glBindFramebuffer(GL_FRAMEBUFFER, oldFBO);
|
|
|
|
GLenum DrawBuffers[1] = { GL_COLOR_ATTACHMENT0 };
|
|
glDrawBuffers(1, DrawBuffers);
|
|
|
|
VertexShader = glCreateShader(GL_VERTEX_SHADER);
|
|
glShaderSource(VertexShader, 1, &VertexShaderSource, NULL);
|
|
glCompileShader(VertexShader);
|
|
int success;
|
|
char InfoLog[512];
|
|
glGetShaderiv(VertexShader, GL_COMPILE_STATUS, &success);
|
|
if (!success) {
|
|
glGetShaderInfoLog(VertexShader, 512, NULL, InfoLog);
|
|
std::cout << "Vertex shader compilation failed\n" << InfoLog << std::endl;
|
|
}
|
|
FragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
|
|
glShaderSource(FragmentShader, 1, &FragmentShaderSource, NULL);
|
|
glCompileShader(FragmentShader);
|
|
glGetShaderiv(FragmentShader, GL_COMPILE_STATUS, &success);
|
|
if (!success) {
|
|
glGetShaderInfoLog(FragmentShader, 512, NULL, InfoLog);
|
|
std::cout << "Fragment shader compilation failed\n" << InfoLog << std::endl;
|
|
}
|
|
ShaderProgram = glCreateProgram();
|
|
glAttachShader(ShaderProgram, VertexShader);
|
|
glAttachShader(ShaderProgram, FragmentShader);
|
|
glLinkProgram(ShaderProgram);
|
|
glGetProgramiv(ShaderProgram, GL_LINK_STATUS, &success);
|
|
if (!success) {
|
|
glGetProgramInfoLog(ShaderProgram, 512, NULL, InfoLog);
|
|
std::cout << "Linking shader program failed\n" << InfoLog << std::endl;
|
|
}
|
|
|
|
VertexShader = glCreateShader(GL_VERTEX_SHADER);
|
|
glShaderSource(VertexShader, 1, &TextureVertexShaderSource, NULL);
|
|
glCompileShader(VertexShader);
|
|
glGetShaderiv(VertexShader, GL_COMPILE_STATUS, &success);
|
|
if (!success) {
|
|
glGetShaderInfoLog(VertexShader, 512, NULL, InfoLog);
|
|
std::cout << "Vertex shader compilation failed\n" << InfoLog << std::endl;
|
|
}
|
|
FragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
|
|
glShaderSource(FragmentShader, 1, &TextureFragmentShaderSource, NULL);
|
|
glCompileShader(FragmentShader);
|
|
glGetShaderiv(FragmentShader, GL_COMPILE_STATUS, &success);
|
|
if (!success) {
|
|
glGetShaderInfoLog(FragmentShader, 512, NULL, InfoLog);
|
|
std::cout << "Fragment shader compilation failed\n" << InfoLog << std::endl;
|
|
}
|
|
TextureShaderProgram = glCreateProgram();
|
|
glAttachShader(TextureShaderProgram, VertexShader);
|
|
glAttachShader(TextureShaderProgram, FragmentShader);
|
|
glLinkProgram(TextureShaderProgram);
|
|
glGetProgramiv(TextureShaderProgram, GL_LINK_STATUS, &success);
|
|
if (!success) {
|
|
glGetProgramInfoLog(TextureShaderProgram, 512, NULL, InfoLog);
|
|
std::cout << "Linking shader program failed\n" << InfoLog << std::endl;
|
|
}
|
|
|
|
glGenVertexArrays(1, &VAO);
|
|
glGenVertexArrays(1, &TextureVAO);
|
|
glGenBuffers(1, &VBO);
|
|
glGenBuffers(1, &TextureVBO);
|
|
|
|
glGenTextures(1, &VramTexture);
|
|
glBindTexture(GL_TEXTURE_2D, VramTexture);
|
|
//glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
|
//glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
|
glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 1024 * scaling_factor, 512 * scaling_factor);
|
|
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, VramTexture, 0);
|
|
glPixelStorei(GL_UNPACK_ALIGNMENT, 2);
|
|
glPixelStorei(GL_PACK_ALIGNMENT, 2);
|
|
glClearColor(0.f, 0.f, 0.f, 1.f);
|
|
glClear(GL_COLOR_BUFFER_BIT);
|
|
|
|
glGenTextures(1, &SampleVramTexture);
|
|
glBindTexture(GL_TEXTURE_2D, SampleVramTexture);
|
|
//glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
|
//glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
|
glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 1024 * scaling_factor, 512 * scaling_factor);
|
|
|
|
glGenFramebuffers(1, &tempFBO);
|
|
glBindFramebuffer(GL_FRAMEBUFFER, tempFBO);
|
|
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, SampleVramTexture, 0);
|
|
|
|
|
|
glBindFramebuffer(GL_FRAMEBUFFER, oldFBO);
|
|
|
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1024, 512, 0, GL_RGBA, GL_UNSIGNED_BYTE, vram8);
|
|
|
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1024, 512, 0, GL_RGBA, GL_UNSIGNED_BYTE, vram4);
|
|
|
|
// Initialize VAO for untextured polygons
|
|
glBindBuffer(GL_ARRAY_BUFFER, VBO);
|
|
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);
|
|
|
|
// Initialize VAO for textured polygons
|
|
glBindBuffer(GL_ARRAY_BUFFER, TextureVBO);
|
|
glBindVertexArray(TextureVAO);
|
|
// Position attribute
|
|
glVertexAttribPointer(0, 3, GL_INT, GL_FALSE, 13 * sizeof(int32_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);
|
|
}
|
|
|
|
void gpu::SyncVRAM() {
|
|
glBindTexture(GL_TEXTURE_2D, SampleVramTexture);
|
|
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 1024 * scaling_factor, 512 * scaling_factor);
|
|
}
|
|
|
|
void gpu::SetOpenGLState() {
|
|
glViewport(0, 0, 1024 * scaling_factor, 512 * scaling_factor);
|
|
glBindFramebuffer(GL_FRAMEBUFFER, FBO);
|
|
glScissor(drawing_topleft_x * scaling_factor, drawing_topleft_y * scaling_factor, (drawing_bottomright_x - drawing_topleft_x) * scaling_factor, (drawing_bottomright_y - drawing_topleft_y) * scaling_factor);
|
|
glEnable(GL_SCISSOR_TEST);
|
|
|
|
if (DrawingTextured) {
|
|
glBindBuffer(GL_ARRAY_BUFFER, TextureVBO);
|
|
glBindVertexArray(TextureVAO);
|
|
glUseProgram(TextureShaderProgram);
|
|
}
|
|
else {
|
|
glBindBuffer(GL_ARRAY_BUFFER, VBO);
|
|
glBindVertexArray(VAO);
|
|
glUseProgram(ShaderProgram);
|
|
}
|
|
}
|
|
|
|
void gpu::SwitchToTextured() {
|
|
if (!DrawingTextured) {
|
|
DrawingTextured = true;
|
|
glBindBuffer(GL_ARRAY_BUFFER, TextureVBO);
|
|
glBindVertexArray(TextureVAO);
|
|
glUseProgram(TextureShaderProgram);
|
|
}
|
|
}
|
|
|
|
void gpu::SwitchToUntextured() {
|
|
if (DrawingTextured) {
|
|
DrawingTextured = false;
|
|
glBindBuffer(GL_ARRAY_BUFFER, VBO);
|
|
glBindVertexArray(VAO);
|
|
glUseProgram(ShaderProgram);
|
|
}
|
|
}
|
|
|
|
void gpu::putpixel(point v1, uint32_t colour) {
|
|
// TODO: OpenGL implementation
|
|
uint32_t a = (colour >> 15) & 1;
|
|
uint32_t b = (colour >> 10) & 0b11111;
|
|
uint32_t g = (colour >> 5) & 0b11111;
|
|
uint32_t r = colour & 0b11111;
|
|
uint32_t rgba = ((r << 3) << 24) | ((g << 3) << 16) | ((b << 3) << 8) | 0xff;
|
|
vram_rgb[(v1.y + ypos) * 1024 + (v1.x + xpos)] = rgba;
|
|
}
|
|
|
|
void gpu::ClearScreen() {
|
|
glClearColor(0, 0, 0, 1);
|
|
glClear(GL_COLOR_BUFFER_BIT);
|
|
}
|
|
|
|
void gpu::execute_gp0(uint32_t command) {
|
|
uint8_t instr = (command >> 24) & 0xff;
|
|
if (cmd_left == 0) {
|
|
cmd_length = 0;
|
|
switch (instr) {
|
|
case 0x04:
|
|
case 0x08:
|
|
case 0x0c:
|
|
case 0x10:
|
|
case 0x14:
|
|
case 0x18:
|
|
case 0x1c:
|
|
case 0x1d:
|
|
case 0x00: // nop
|
|
debug_printf("[GP0] NOP (0x%x)\n", command);
|
|
break;
|
|
case 0x01: { // Clear Cache
|
|
SyncVRAM();
|
|
debug_printf("[GP0] Clear Cache\n");
|
|
break;
|
|
}
|
|
case 0x02: { // Fill rectangle in VRAM
|
|
fifo[0] = command;
|
|
cmd_length++;
|
|
cmd_left = 2;
|
|
break;
|
|
}
|
|
case 0x21:
|
|
case 0x20: { // Monochrome three-point polygon, opaque
|
|
fifo[0] = command;
|
|
cmd_length++;
|
|
cmd_left = 3;
|
|
break;
|
|
}
|
|
case 0x23:
|
|
case 0x22: { // Monochrome three-point polygon, semi-transparent
|
|
fifo[0] = command;
|
|
cmd_length++;
|
|
cmd_left = 3;
|
|
break;
|
|
}
|
|
case 0x29:
|
|
case 0x28: { // Monochrome four-point polygon, opaque
|
|
fifo[0] = command;
|
|
cmd_length++;
|
|
cmd_left = 4;
|
|
break;
|
|
}
|
|
case 0x26:
|
|
case 0x24: { // Textured three-point polygon, opaque, texture-blending
|
|
fifo[0] = command;
|
|
cmd_length++;
|
|
cmd_left = 6;
|
|
break;
|
|
}
|
|
case 0x25: { // Textured three-point polygon, opaque, raw-texture
|
|
fifo[0] = command;
|
|
cmd_length++;
|
|
cmd_left = 6;
|
|
break;
|
|
}
|
|
case 0x2B:
|
|
case 0x2A: { // Monochrome four-point polygon, semi-transparent
|
|
fifo[0] = command;
|
|
cmd_length++;
|
|
cmd_left = 4;
|
|
break;
|
|
}
|
|
case 0x2C: { // Textured four-point polygon, opaque, texture-blending
|
|
fifo[0] = command;
|
|
cmd_length++;
|
|
cmd_left = 8;
|
|
break;
|
|
}
|
|
case 0x2D: { // Textured four-point polygon, opaque, raw-texture
|
|
fifo[0] = command;
|
|
cmd_length++;
|
|
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++;
|
|
cmd_left = 8;
|
|
break;
|
|
}
|
|
case 0x30: { // Shaded three-point polygon, opaque
|
|
fifo[0] = command;
|
|
cmd_length++;
|
|
cmd_left = 5;
|
|
break;
|
|
}
|
|
case 0x33:
|
|
case 0x32: { // Shaded three-point polygon, semi-transparent
|
|
fifo[0] = command;
|
|
cmd_length++;
|
|
cmd_left = 5;
|
|
break;
|
|
}
|
|
case 0x36: // Shaded Textured three-point polygon, semi-transparent, tex-blend
|
|
case 0x34: { // Shaded Textured three-point polygon, opaque, texture-blending
|
|
fifo[0] = command;
|
|
cmd_length++;
|
|
cmd_left = 8;
|
|
break;
|
|
}
|
|
case 0x38: { // Shaded four-point polygon, opaque
|
|
fifo[0] = command;
|
|
cmd_length++;
|
|
cmd_left = 7;
|
|
break;
|
|
}
|
|
case 0x3c: { // Shaded Textured four-point polygon, opaque, texture-blending
|
|
fifo[0] = command;
|
|
cmd_length++;
|
|
cmd_left = 11;
|
|
break;
|
|
}
|
|
case 0x3e: { // Shaded Textured four-point polygon, semi-transparent, texture-blending
|
|
fifo[0] = command;
|
|
cmd_length++;
|
|
cmd_left = 11;
|
|
break;
|
|
}
|
|
//case 0x41:
|
|
case 0x40: { // Monochrome line, opaque
|
|
fifo[0] = command;
|
|
cmd_length++;
|
|
cmd_left = 2;
|
|
break;
|
|
}
|
|
case 0x3B:
|
|
case 0x3A: { // Shaded four-point polygon, semi-transparent
|
|
fifo[0] = command;
|
|
cmd_length++;
|
|
cmd_left = 7;
|
|
break;
|
|
}
|
|
case 0x4c:
|
|
case 0x58:
|
|
case 0x42:
|
|
case 0x48: { // Monochrome Poly-line, opaque
|
|
//abort();
|
|
fifo[0] = command;
|
|
cmd_length++;
|
|
cmd_left = 1;
|
|
gp0_mode = 2;
|
|
break;
|
|
}
|
|
case 0x52: { // Shaded line, semi-transparent
|
|
fifo[0] = command;
|
|
cmd_length++;
|
|
cmd_left = 3;
|
|
break;
|
|
}
|
|
case 0x60: { // Monochrome Rectangle (variable size) (opaque)
|
|
fifo[0] = command;
|
|
cmd_length++;
|
|
cmd_left = 2;
|
|
break;
|
|
}
|
|
case 0x63:
|
|
case 0x62: { // Monochrome Rectangle (variable size) (semi-transparent)
|
|
fifo[0] = command;
|
|
cmd_length++;
|
|
cmd_left = 2;
|
|
break;
|
|
}
|
|
case 0x64: { // Textured Rectangle, variable size, opaque, texture-blending
|
|
fifo[0] = command;
|
|
cmd_length++;
|
|
cmd_left = 3;
|
|
break;
|
|
}
|
|
case 0x65: { // Textured Rectangle, variable size, opaque, raw-texture
|
|
fifo[0] = command;
|
|
cmd_length++;
|
|
cmd_left = 3;
|
|
break;
|
|
}
|
|
case 0x66: { // Textured Rectangle, variable size, semi-transp, texture-blending
|
|
fifo[0] = command;
|
|
cmd_length++;
|
|
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 0x76:
|
|
case 0x74: { // Textured Rectangle, 8x8, opaque, texture-blending
|
|
fifo[0] = command;
|
|
cmd_length++;
|
|
cmd_left = 2;
|
|
break;
|
|
}
|
|
case 0x75: { // Textured Rectangle, 8x8, opaque, raw-texture
|
|
fifo[0] = command;
|
|
cmd_length++;
|
|
cmd_left = 2;
|
|
break;
|
|
}
|
|
case 0x78: { // Monochrome Rectangle (16x16) (opaque)
|
|
fifo[0] = command;
|
|
cmd_length++;
|
|
cmd_left = 1;
|
|
break;
|
|
}
|
|
case 0x7C: { // Textured Rectangle, 16x16, opaque, texture-blending
|
|
fifo[0] = command;
|
|
cmd_length++;
|
|
cmd_left = 2;
|
|
break;
|
|
}
|
|
case 0x7D: { // Textured Rectangle, 16x16, opaque, raw-texture
|
|
fifo[0] = command;
|
|
cmd_length++;
|
|
cmd_left = 2;
|
|
break;
|
|
}
|
|
case 0x7E: // Textured Rectangle, 16x16, semi-transparent, texture-blending
|
|
case 0x7F: { // Textured Rectangle, 16x16, semi-transparent, raw-texture
|
|
fifo[0] = command;
|
|
cmd_length++;
|
|
cmd_left = 2;
|
|
break;
|
|
}
|
|
case 0x80: { // Copy Rectangle (VRAM to VRAM)
|
|
fifo[0] = command;
|
|
cmd_length++;
|
|
cmd_left = 3;
|
|
break;
|
|
}
|
|
case 0xA0: { // Copy rectangle CPU to VRAM
|
|
fifo[0] = command;
|
|
cmd_length++;
|
|
cmd_left = 2;
|
|
break;
|
|
}
|
|
case 0xC0: { // Copy rectangle VRAM to CPU
|
|
debug_printf("[GP0] Copy Rectangle (VRAM to CPU)\n");
|
|
fifo[0] = command;
|
|
cmd_length++;
|
|
cmd_left = 2;
|
|
break;
|
|
}
|
|
case 0xE1: { // Draw Mode Setting
|
|
debug_printf("[GP0] Draw Mode Setting\n");
|
|
page_base_x = command & 0xf;
|
|
page_base_y = (command >> 4) & 1;
|
|
semi_transparency = (command >> 5) & 3;
|
|
texture_depth = (command >> 7) & 3;
|
|
dithering = ((command >> 9) & 1) != 0;
|
|
allow_display_drawing = ((command >> 10) & 1) != 0;
|
|
texpage_raw = command & 0xffff;
|
|
texture_disable = (command & (1 << 11));
|
|
|
|
// rectangle x flip
|
|
// rectangle y flip
|
|
break;
|
|
}
|
|
case 0xE2: { // Set Texture Window
|
|
int texWindow = command & 0xfffff;
|
|
glUseProgram(TextureShaderProgram);
|
|
int maskUniformLocation = glGetUniformLocation(TextureShaderProgram, "texWindow");
|
|
|
|
int texWindowX = texWindow & 0x1f;
|
|
int texWindowY = (texWindow >> 5) & 0x1f;
|
|
int texWindowOffsX = (texWindow >> 10) & 0x1f;
|
|
int texWindowOffsY = (texWindow >> 15) & 0x1f;
|
|
glUniform4i(maskUniformLocation, ~(texWindowX * 8), ~(texWindowY * 8), ((texWindowOffsX & texWindowX) * 8), ((texWindowOffsY & texWindowY) * 8));
|
|
if (!DrawingTextured) glUseProgram(ShaderProgram);
|
|
debug_printf("[GP0] Set Texture Window\n");
|
|
break;
|
|
}
|
|
case 0xE3: { // Set Drawing Area top left
|
|
drawing_topleft_x = command & 1023;
|
|
drawing_topleft_y = (command >> 10) & 511;
|
|
debug_printf("[GP0] Set Drawing Area top left\n");
|
|
glScissor(drawing_topleft_x * scaling_factor, drawing_topleft_y * scaling_factor, (drawing_bottomright_x - drawing_topleft_x) * scaling_factor, (drawing_bottomright_y - drawing_topleft_y) * scaling_factor);
|
|
break;
|
|
}
|
|
case 0xE4: { // Set Drawing Area bottom right
|
|
drawing_bottomright_x = command & 1023;
|
|
drawing_bottomright_y = (command >> 10) & 511;
|
|
debug_printf("[GP0] Set Drawing Area bottom right\n");
|
|
glScissor(drawing_topleft_x * scaling_factor, drawing_topleft_y * scaling_factor, (drawing_bottomright_x - drawing_topleft_x) * scaling_factor, (drawing_bottomright_y - drawing_topleft_y) * scaling_factor);
|
|
break;
|
|
}
|
|
case 0xE5: { // Set Drawing Area Offset
|
|
xoffset = (command & 0b1111111111);
|
|
yoffset = ((command >> 11) & 0b1111111111);
|
|
int offsetUniformLocation = glGetUniformLocation(ShaderProgram, "offset");
|
|
glUseProgram(ShaderProgram);
|
|
glUniform3f(offsetUniformLocation, xoffset, yoffset, 0);
|
|
offsetUniformLocation = glGetUniformLocation(TextureShaderProgram, "offset");
|
|
glUseProgram(TextureShaderProgram);
|
|
glUniform3f(offsetUniformLocation, xoffset, yoffset, 0);
|
|
if (!DrawingTextured) glUseProgram(ShaderProgram);
|
|
debug_printf("[GP0] Set Drawing Area Offset\n");
|
|
break;
|
|
}
|
|
case 0xE6: { // Set Mask Bit Setting
|
|
debug_printf("[GP0] Set Mask Bit Setting\n");
|
|
mask_bit = (command & 1) != 0;
|
|
disallow_masked_pixels_drawing = (command & 2) != 0;
|
|
break;
|
|
}
|
|
default:
|
|
printf("\n[GP0] Unknown GP0 command: 0x%x (0x%x)\n", instr, command);
|
|
//abort();
|
|
}
|
|
}
|
|
else {
|
|
cmd_left--;
|
|
switch (gp0_mode) {
|
|
case 0: { // command mode
|
|
fifo[cmd_length++] = command;
|
|
|
|
if (cmd_left == 0) { // all the parameters are in, run command
|
|
switch ((fifo[0] >> 24) & 0xff) {
|
|
|
|
case 0x02: gpu::fill_rectangle(); break;
|
|
case 0x21:
|
|
case 0x20: SwitchToUntextured(); gpu::draw_untextured_tri(MONOCHROME, SOLID); break;
|
|
case 0x23:
|
|
case 0x22: SwitchToUntextured(); gpu::draw_untextured_tri(MONOCHROME, SEMI_TRANSPARENT); break;
|
|
case 0x26:
|
|
case 0x24: SwitchToTextured(); gpu::texture_blending_three_point_opaque_polygon(); break;
|
|
case 0x25: SwitchToTextured(); gpu::texture_three_point_opaque_polygon(); break;
|
|
case 0x29:
|
|
case 0x28: SwitchToUntextured(); gpu::draw_untextured_quad(MONOCHROME, SOLID); break;
|
|
case 0x2B:
|
|
case 0x2A: SwitchToUntextured(); gpu::draw_untextured_quad(MONOCHROME, SEMI_TRANSPARENT); break;
|
|
case 0x2C: SwitchToTextured(); gpu::texture_blending_four_point_opaque_polygon(); break;
|
|
case 0x2D: SwitchToTextured(); gpu::texture_four_point_opaque_polygon(); break;
|
|
case 0x2E: SwitchToTextured(); gpu::texture_blending_four_point_polygon_semi_transparent(); break;
|
|
case 0x2F: SwitchToTextured(); gpu::texture_four_point_semi_transparent_polygon(); break;
|
|
case 0x30: SwitchToUntextured(); gpu::draw_untextured_tri(GOURAUD, SOLID); break;
|
|
case 0x33:
|
|
case 0x32: SwitchToUntextured(); gpu::draw_untextured_tri(GOURAUD, SEMI_TRANSPARENT); break;
|
|
case 0x36:
|
|
case 0x34: SwitchToTextured(); gpu::shaded_texture_blending_three_point_opaque_polygon(); break;
|
|
case 0x38: SwitchToUntextured(); gpu::draw_untextured_quad(GOURAUD, SOLID); break;
|
|
case 0x3B:
|
|
case 0x3A: SwitchToUntextured(); gpu::draw_untextured_quad(GOURAUD, SEMI_TRANSPARENT); break;
|
|
case 0x3C: SwitchToTextured(); gpu::shaded_texture_blending_textured_four_point_opaque_polygon(); break;
|
|
case 0x3E: SwitchToTextured(); gpu::shaded_texture_blending_textured_four_point_semi_transparent_polygon(); break;
|
|
case 0x41:
|
|
case 0x40: gpu::monochrome_line_opaque(); break;
|
|
case 0x52: SwitchToUntextured(); gpu::shaded_line_semi_transparent(); break;
|
|
case 0x60: SwitchToUntextured(); gpu::monochrome_rectangle_variable_size_opaque(); break;
|
|
case 0x63:
|
|
case 0x62: SwitchToUntextured(); gpu::monochrome_rectangle_variable_size_semi_transparent(); break;
|
|
case 0x64: SwitchToTextured(); gpu::texture_blending_rectangle_variable_size_opaque(); break;
|
|
case 0x65: SwitchToTextured(); gpu::texture_rectangle_variable_size_opaque(); break;
|
|
case 0x66: SwitchToTextured(); gpu::texture_blending_rectangle_variable_size_semi_transparent(); break;
|
|
case 0x67: SwitchToTextured(); gpu::textured_rectangle_variable_size_semi_transparent(); break;
|
|
case 0x68: SwitchToUntextured(); gpu::monochrome_rectangle_dot_opaque(); break;
|
|
case 0x70: SwitchToUntextured(); gpu::monochrome_rectangle_8x8_opaque(); break;
|
|
case 0x76:
|
|
case 0x74: SwitchToTextured(); gpu::texture_blending_rectangle_8x8_opaque(); break;
|
|
case 0x75: SwitchToTextured(); gpu::texture_rectangle_8x8_opaque(); break;
|
|
case 0x78: SwitchToUntextured(); gpu::monochrome_rectangle_16x16_opaque(); break;
|
|
case 0x7C: SwitchToTextured(); gpu::texture_blending_rectangle_16x16_opaque(); break;
|
|
case 0x7D: SwitchToTextured(); gpu::texture_rectangle_16x16_opaque(); break;
|
|
case 0x7E:
|
|
case 0x7F: SwitchToTextured(); gpu::texture_rectangle_16x16_semi_transparent(); break;
|
|
case 0x80: gpu::vram_to_vram(); break;
|
|
case 0xA0: gpu::cpu_to_vram(); break;
|
|
case 0xC0: gpu::vram_to_cpu(); break;
|
|
//default: printf("\n%d", fifo[0] >> 24); abort();
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 1: { // load mode
|
|
debug_printf("[CPU to VRAM transfer] Data: 0x%x\n", command);
|
|
uint32_t resolution = fifo[2];
|
|
uint32_t coords = fifo[1];
|
|
auto width = resolution & 0xffff;
|
|
auto height = resolution >> 16;
|
|
if (width == 0) width = 1024;
|
|
if (height == 0) height = 512;
|
|
width &= 0x3ff;
|
|
height &= 0x1ff;
|
|
auto x = coords & 0xffff;
|
|
auto y = coords >> 16;
|
|
const auto scaled_x = x * scaling_factor;
|
|
const auto scaled_y = y * scaling_factor;
|
|
const auto scaled_width = width * scaling_factor;
|
|
const auto scaled_height = height * scaling_factor;
|
|
|
|
if (cmd_left == 0) {
|
|
gp0_mode = 0;
|
|
if (scaling_factor == 1) {
|
|
glBindTexture(GL_TEXTURE_2D, VramTexture);
|
|
}
|
|
else {
|
|
glBindTexture(GL_TEXTURE_2D, SampleVramTexture);
|
|
}
|
|
glTexSubImage2D(GL_TEXTURE_2D, 0, scaled_x, scaled_y, width, height, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, &WriteBuffer[0]);
|
|
for (int i = 0; i < (1024 * 512); i++) WriteBuffer[i] = 0;
|
|
//WriteBuffer.clear();
|
|
WriteBufferCnt = 0;
|
|
if (scaling_factor == 1) {
|
|
SyncVRAM();
|
|
}
|
|
else {
|
|
glDisable(GL_SCISSOR_TEST);
|
|
glBindFramebuffer(GL_READ_FRAMEBUFFER, tempFBO);
|
|
glBlitFramebuffer(scaled_x, scaled_y, scaled_x + width, scaled_y + height, scaled_x, scaled_y, scaled_x + scaled_width, scaled_y + scaled_height, GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
|
glEnable(GL_SCISSOR_TEST);
|
|
glBindFramebuffer(GL_READ_FRAMEBUFFER, FBO);
|
|
SyncVRAM();
|
|
}
|
|
break;
|
|
}
|
|
//WriteBuffer.push_back(command);
|
|
WriteBuffer[WriteBufferCnt++] = command;
|
|
break;
|
|
}
|
|
case 2: { // polyline mode
|
|
if (command == 0x50005000 || command == 0x55555555) {
|
|
//monochrome_polyline_opaque();
|
|
cmd_length = 0;
|
|
gp0_mode = 0;
|
|
cmd_left = 0;
|
|
for (int i = 0; i < 12; i++) fifo[i] = 0;
|
|
return;
|
|
}
|
|
cmd_left += 2;
|
|
//fifo[cmd_length++] = command;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void gpu::update_hres() {
|
|
display_area.width = (((x2 - x1) / width_divisor) + 2) & ~3;
|
|
}
|
|
void gpu::update_vres() {
|
|
display_area.height = y2 - y1;
|
|
if (interlacing) display_area.height *= 2;
|
|
}
|
|
|
|
void gpu::execute_gp1(uint32_t command) {
|
|
uint8_t instr = (command >> 24) & 0xff;
|
|
|
|
switch (instr) {
|
|
case 0x0: { // reset gpu
|
|
hres1 = 1;
|
|
int res_divisors[] = { 10, 8, 5, 4 };
|
|
width_divisor = res_divisors[hres1]; // NTSC: 3413 video cycles per scanline
|
|
|
|
x1 = 0x200;
|
|
x2 = 0x200 + 256 * 10;
|
|
y1 = 0x10;
|
|
y2 = 0x10 + 240;
|
|
update_hres();
|
|
update_vres();
|
|
debug_printf("[GP1] Reset Gpu\n");
|
|
break;
|
|
}
|
|
case 0x1: // reset command buffer
|
|
debug_printf("[GP1] Reset Command Buffer\n");
|
|
break;
|
|
case 0x4: { // set dma direction
|
|
debug_printf("[GP1] Set DMA Direction to %d\n", command & 0b11);
|
|
dma_direction = command & 0b11;
|
|
break;
|
|
}
|
|
case 0x5: { // Start of Display area
|
|
frame_counter++;
|
|
display_area.origin.x = command & 0x3ff;
|
|
display_area.origin.y = (command >> 10) & 0x1ff;
|
|
update_hres();
|
|
update_vres();
|
|
break;
|
|
}
|
|
case 0x6: { // Horizontal Display range
|
|
x1 = command & 0xfff;
|
|
x2 = (command >> 12) & 0xfff;
|
|
update_hres();
|
|
break;
|
|
}
|
|
case 0x7: { // Vertical Display range
|
|
y1 = command & 0x3ff;
|
|
y2 = (command >> 10) & 0x3ff;
|
|
update_vres();
|
|
break;
|
|
}
|
|
case 0x8: { // Display mode
|
|
hres1 = command & 3;
|
|
vres = (command >> 2) & 1;
|
|
video_mode = (command >> 3) & 1;
|
|
interlacing = (command >> 5) & 1;
|
|
hres2 = (command >> 6) & 1;
|
|
int res_divisors[] = { 10, 8, 5, 4 };
|
|
width_divisor = res_divisors[hres1]; // NTSC: 3413 video cycles per scanline
|
|
if (hres2) width_divisor = 7;
|
|
update_hres();
|
|
update_vres();
|
|
break;
|
|
}
|
|
default:
|
|
debug_printf("[GP1] Unknown GP1 command: 0x%x\n", instr);
|
|
//exit(0);
|
|
}
|
|
}
|
|
|
|
// commands
|
|
|
|
void gpu::draw_untextured_tri(int shading, int transparency) {
|
|
if (shading == MONOCHROME) {
|
|
point v1, v2, v3;
|
|
uint32_t colour = fifo[0] & 0xffffff;
|
|
v1.x = fifo[1] & 0xffff;
|
|
v1.y = fifo[1] >> 16;
|
|
v2.x = fifo[2] & 0xffff;
|
|
v2.y = fifo[2] >> 16;
|
|
v3.x = fifo[3] & 0xffff;
|
|
v3.y = fifo[3] >> 16;
|
|
|
|
|
|
|
|
uint32_t Vertices1[]{
|
|
v1.x, v1.y, 0.0,
|
|
v2.x, v2.y, 0.0,
|
|
v3.x, v3.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)
|
|
};
|
|
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices1), Vertices1, GL_STATIC_DRAW);
|
|
glDrawArrays(GL_TRIANGLES, 0, 3);
|
|
|
|
}
|
|
else if (shading == GOURAUD) {
|
|
point v1, v2, v3;
|
|
v1.c = fifo[0] & 0xffffff;
|
|
v2.c = fifo[2] & 0xffffff;
|
|
v3.c = fifo[4] & 0xffffff;
|
|
v1.x = fifo[1] & 0xffff;
|
|
v1.y = fifo[1] >> 16;
|
|
v2.x = fifo[3] & 0xffff;
|
|
v2.y = fifo[3] >> 16;
|
|
v3.x = fifo[5] & 0xffff;
|
|
v3.y = fifo[5] >> 16;
|
|
|
|
|
|
|
|
uint32_t Vertices[]{
|
|
v1.x, v1.y, 0.0,
|
|
v2.x, v2.y, 0.0,
|
|
v3.x, v3.y, 0.0,
|
|
|
|
(((v1.c) >> 0) & 0xff), (((v1.c) >> 8) & 0xff), (((v1.c) >> 16) & 0xff),
|
|
(((v2.c) >> 0) & 0xff), (((v2.c) >> 8) & 0xff), (((v2.c) >> 16) & 0xff),
|
|
(((v3.c) >> 0) & 0xff), (((v3.c) >> 8) & 0xff), (((v3.c) >> 16) & 0xff)
|
|
};
|
|
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices), Vertices, GL_STATIC_DRAW);
|
|
glDrawArrays(GL_TRIANGLES, 0, 3);
|
|
|
|
}
|
|
}
|
|
|
|
void gpu::draw_untextured_quad(int shading, int transparency) {
|
|
if (shading == MONOCHROME) {
|
|
uint32_t colour = fifo[0] & 0xffffff;
|
|
point v1, v2, v3, v4;
|
|
v1.x = fifo[1] & 0xffff;
|
|
v1.y = fifo[1] >> 16;
|
|
v2.x = fifo[2] & 0xffff;
|
|
v2.y = fifo[2] >> 16;
|
|
v3.x = fifo[3] & 0xffff;
|
|
v3.y = fifo[3] >> 16;
|
|
v4.x = fifo[4] & 0xffff;
|
|
v4.y = fifo[4] >> 16;
|
|
|
|
|
|
|
|
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)
|
|
};
|
|
|
|
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices1), Vertices1, GL_STATIC_DRAW);
|
|
glDrawArrays(GL_TRIANGLES, 0, 3);
|
|
|
|
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)
|
|
};
|
|
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices2), Vertices2, GL_STATIC_DRAW);
|
|
glDrawArrays(GL_TRIANGLES, 0, 3);
|
|
|
|
}
|
|
else if (shading == GOURAUD) {
|
|
point v1, v2, v3, v4;
|
|
v1.c = fifo[0] & 0xffffff;
|
|
v2.c = fifo[2] & 0xffffff;
|
|
v3.c = fifo[4] & 0xffffff;
|
|
v4.c = fifo[6] & 0xffffff;
|
|
v1.x = fifo[1] & 0xffff;
|
|
v1.y = fifo[1] >> 16;
|
|
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;
|
|
|
|
|
|
|
|
uint32_t Vertices1[]{
|
|
v1.x, v1.y, 0.0,
|
|
v2.x, v2.y, 0.0,
|
|
v3.x, v3.y, 0.0,
|
|
|
|
(((v1.c) >> 0) & 0xff), (((v1.c) >> 8) & 0xff), (((v1.c) >> 16) & 0xff),
|
|
(((v2.c) >> 0) & 0xff), (((v2.c) >> 8) & 0xff), (((v2.c) >> 16) & 0xff),
|
|
(((v3.c) >> 0) & 0xff), (((v3.c) >> 8) & 0xff), (((v3.c) >> 16) & 0xff)
|
|
};
|
|
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices1), Vertices1, GL_STATIC_DRAW);
|
|
glDrawArrays(GL_TRIANGLES, 0, 3);
|
|
|
|
uint32_t Vertices2[]{
|
|
v2.x, v2.y, 0.0,
|
|
v3.x, v3.y, 0.0,
|
|
v4.x, v4.y, 0.0,
|
|
|
|
(((v2.c) >> 0) & 0xff), (((v2.c) >> 8) & 0xff), (((v2.c) >> 16) & 0xff),
|
|
(((v3.c) >> 0) & 0xff), (((v3.c) >> 8) & 0xff), (((v3.c) >> 16) & 0xff),
|
|
(((v4.c) >> 0) & 0xff), (((v4.c) >> 8) & 0xff), (((v4.c) >> 16) & 0xff)
|
|
};
|
|
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices2), Vertices2, GL_STATIC_DRAW);
|
|
glDrawArrays(GL_TRIANGLES, 0, 3);
|
|
|
|
}
|
|
}
|
|
|
|
void gpu::texture_blending_three_point_opaque_polygon() {
|
|
uint32_t colour = fifo[0] & 0xffffff;
|
|
debug_printf("[GP0] Textured three-point polygon, opaque, 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;
|
|
//printf("\nclut: 0x%x\n", clut);
|
|
uint32_t clutX = (clut & 0x3f);
|
|
clutX *= 16;
|
|
uint32_t clutY = (clut >> 6);
|
|
|
|
texpage = fifo[4] >> 16;
|
|
//printf("texpage: 0x%x\n", texpage);
|
|
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;
|
|
|
|
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
|
|
};
|
|
|
|
glBindTexture(GL_TEXTURE_2D, SampleVramTexture);
|
|
|
|
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices1), Vertices1, GL_STATIC_DRAW);
|
|
|
|
glUniform1i(colourDepthUniform, colourDepth);
|
|
glDrawArrays(GL_TRIANGLES, 0, 3);
|
|
}
|
|
|
|
void gpu::texture_three_point_opaque_polygon() {
|
|
uint32_t colour = fifo[0] & 0xffffff;
|
|
debug_printf("[GP0] Textured three-point polygon, opaque, raw-texture (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;
|
|
//printf("\nclut: 0x%x\n", clut);
|
|
uint32_t clutX = (clut & 0x3f);
|
|
clutX *= 16;
|
|
uint32_t clutY = (clut >> 6);
|
|
|
|
texpage = fifo[4] >> 16;
|
|
//printf("texpage: 0x%x\n", texpage);
|
|
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;
|
|
|
|
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, 128, 128, 128, t1.x, t1.y, texpageX, texpageY, clutX, clutY, colourDepth,
|
|
v2.x, v2.y, 0.0f, 128, 128, 128, t2.x, t2.y, texpageX, texpageY, clutX, clutY, colourDepth,
|
|
v3.x, v3.y, 0.0f, 128, 128, 128, 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
|
|
};
|
|
|
|
glBindTexture(GL_TEXTURE_2D, SampleVramTexture);
|
|
|
|
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices1), Vertices1, GL_STATIC_DRAW);
|
|
|
|
glUniform1i(colourDepthUniform, colourDepth);
|
|
glDrawArrays(GL_TRIANGLES, 0, 3);
|
|
}
|
|
|
|
void gpu::texture_blending_four_point_opaque_polygon() {
|
|
uint32_t colour = fifo[0] & 0xffffff;
|
|
debug_printf("[GP0] Textured four-point polygon, opaque, 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;
|
|
//printf("\nclut: 0x%x\n", clut);
|
|
uint32_t clutX = (clut & 0x3f);
|
|
clutX *= 16;
|
|
uint32_t clutY = (clut >> 6);
|
|
|
|
texpage = fifo[4] >> 16;
|
|
//printf("texpage: 0x%x\n", texpage);
|
|
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;
|
|
|
|
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
|
|
};
|
|
|
|
glBindTexture(GL_TEXTURE_2D, SampleVramTexture);
|
|
|
|
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices1), Vertices1, GL_STATIC_DRAW);
|
|
|
|
glUniform1i(colourDepthUniform, colourDepth);
|
|
glDrawArrays(GL_TRIANGLES, 0, 3);
|
|
|
|
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
|
|
};
|
|
|
|
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices2), Vertices2, GL_STATIC_DRAW);
|
|
glDrawArrays(GL_TRIANGLES, 0, 3);
|
|
|
|
}
|
|
|
|
void gpu::texture_four_point_opaque_polygon() {
|
|
uint32_t colour = fifo[0] & 0xffffff;
|
|
debug_printf("[GP0] Textured four-point polygon, opaque, raw textures (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);
|
|
|
|
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;
|
|
|
|
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, 128, 128, 128, t1.x, t1.y, texpageX, texpageY, clutX, clutY, colourDepth,
|
|
v2.x, v2.y, 0.0f, 128, 128, 128, t2.x, t2.y, texpageX, texpageY, clutX, clutY, colourDepth,
|
|
v3.x, v3.y, 0.0f, 128, 128, 128, 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
|
|
};
|
|
|
|
|
|
glBindTexture(GL_TEXTURE_2D, SampleVramTexture);
|
|
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices1), Vertices1, GL_STATIC_DRAW);
|
|
glUniform1i(colourDepthUniform, colourDepth);
|
|
glDrawArrays(GL_TRIANGLES, 0, 3);
|
|
|
|
uint32_t Vertices2[] = {
|
|
// positions // colors // texture coords // texpage
|
|
v2.x, v2.y, 0, 128, 128, 128, t2.x, t2.y, texpageX, texpageY, clutX, clutY, colourDepth,
|
|
v3.x, v3.y, 0.0f, 128, 128, 128, t3.x, t3.y, texpageX, texpageY, clutX, clutY, colourDepth,
|
|
v4.x, v4.y, 0.0f, 128, 128, 128, 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
|
|
};
|
|
|
|
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices2), Vertices2, GL_STATIC_DRAW);
|
|
glDrawArrays(GL_TRIANGLES, 0, 3);
|
|
|
|
}
|
|
|
|
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);
|
|
|
|
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;
|
|
|
|
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
|
|
};
|
|
|
|
|
|
glBindTexture(GL_TEXTURE_2D, SampleVramTexture);
|
|
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices1), Vertices1, GL_STATIC_DRAW);
|
|
glUniform1i(colourDepthUniform, colourDepth);
|
|
glDrawArrays(GL_TRIANGLES, 0, 3);
|
|
|
|
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
|
|
};
|
|
|
|
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices2), Vertices2, GL_STATIC_DRAW);
|
|
glDrawArrays(GL_TRIANGLES, 0, 3);
|
|
|
|
}
|
|
|
|
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);
|
|
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);
|
|
|
|
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;
|
|
|
|
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, 128, 128, 128, t1.x, t1.y, texpageX, texpageY, clutX, clutY, colourDepth,
|
|
v2.x, v2.y, 0.0f, 128, 128, 128, t2.x, t2.y, texpageX, texpageY, clutX, clutY, colourDepth,
|
|
v3.x, v3.y, 0.0f, 128, 128, 128, 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
|
|
};
|
|
|
|
|
|
glBindTexture(GL_TEXTURE_2D, SampleVramTexture);
|
|
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices1), Vertices1, GL_STATIC_DRAW);
|
|
glUniform1i(colourDepthUniform, colourDepth);
|
|
glDrawArrays(GL_TRIANGLES, 0, 3);
|
|
|
|
uint32_t Vertices2[] = {
|
|
// positions // colors // texture coords // texpage
|
|
v2.x, v2.y, 0, 128, 128, 128, t2.x, t2.y, texpageX, texpageY, clutX, clutY, colourDepth,
|
|
v3.x, v3.y, 0.0f, 128, 128, 128, t3.x, t3.y, texpageX, texpageY, clutX, clutY, colourDepth,
|
|
v4.x, v4.y, 0.0f, 128, 128, 128, 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
|
|
};
|
|
|
|
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices2), Vertices2, GL_STATIC_DRAW);
|
|
glDrawArrays(GL_TRIANGLES, 0, 3);
|
|
|
|
}
|
|
|
|
void gpu::shaded_texture_blending_three_point_opaque_polygon() {
|
|
uint32_t colour = fifo[0] & 0xffffff;
|
|
debug_printf("[GP0] Textured four-point polygon, opaque, raw textures (colour: 0x%x)\n", colour);
|
|
point v1, v2, v3;
|
|
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);
|
|
|
|
texpage = fifo[5] >> 16;
|
|
uint32_t texpageX = ((texpage & 0b1111) * 64);
|
|
uint32_t texpageY = (((texpage & 0b10000) >> 4) * 256);
|
|
v2.x = fifo[4] & 0xffff;
|
|
v2.y = fifo[4] >> 16;
|
|
v3.x = fifo[7] & 0xffff;
|
|
v3.y = fifo[7] >> 16;
|
|
|
|
v1.c = fifo[0] & 0xffffff;
|
|
v2.c = fifo[3] & 0xffffff;
|
|
v3.c = fifo[6] & 0xffffff;
|
|
|
|
point t1, t2, t3, t4;
|
|
t1.x = (fifo[2] & 0xffff) & 0xff;
|
|
t1.y = ((fifo[2] & 0xffff) >> 8) & 0xff;
|
|
t2.x = (fifo[5] & 0xffff) & 0xff;
|
|
t2.y = ((fifo[5] & 0xffff) >> 8) & 0xff;
|
|
t3.x = (fifo[8] & 0xffff) & 0xff;
|
|
t3.y = ((fifo[8] & 0xffff) >> 8) & 0xff;
|
|
t4.x = (fifo[11] & 0xffff) & 0xff;
|
|
t4.y = ((fifo[11] & 0xffff) >> 8) & 0xff;
|
|
int colourDepth = (texpage >> 7) & 3;
|
|
|
|
uint32_t Vertices1[] = {
|
|
// positions // colors // texture coords
|
|
v1.x, v1.y, 0, (((v1.c) >> 0) & 0xff), (((v1.c) >> 8) & 0xff), (((v1.c) >> 16) & 0xff), t1.x, t1.y, texpageX, texpageY, clutX, clutY, colourDepth,
|
|
v2.x, v2.y, 0.0f, (((v2.c) >> 0) & 0xff), (((v2.c) >> 8) & 0xff), (((v2.c) >> 16) & 0xff), t2.x, t2.y, texpageX, texpageY, clutX, clutY, colourDepth,
|
|
v3.x, v3.y, 0.0f, (((v3.c) >> 0) & 0xff), (((v3.c) >> 8) & 0xff), (((v3.c) >> 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
|
|
};
|
|
|
|
|
|
glBindTexture(GL_TEXTURE_2D, SampleVramTexture);
|
|
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices1), Vertices1, GL_STATIC_DRAW);
|
|
glUniform1i(colourDepthUniform, colourDepth);
|
|
glDrawArrays(GL_TRIANGLES, 0, 3);
|
|
|
|
}
|
|
|
|
void gpu::shaded_texture_blending_textured_four_point_opaque_polygon() {
|
|
uint32_t colour = fifo[0] & 0xffffff;
|
|
debug_printf("[GP0] Textured four-point polygon, opaque, raw textures (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);
|
|
|
|
texpage = fifo[5] >> 16;
|
|
uint32_t texpageX = ((texpage & 0b1111) * 64);
|
|
uint32_t texpageY = (((texpage & 0b10000) >> 4) * 256);
|
|
v2.x = fifo[4] & 0xffff;
|
|
v2.y = fifo[4] >> 16;
|
|
v3.x = fifo[7] & 0xffff;
|
|
v3.y = fifo[7] >> 16;
|
|
v4.x = fifo[10] & 0xffff;
|
|
v4.y = fifo[10] >> 16;
|
|
|
|
v1.c = fifo[0] & 0xffffff;
|
|
v2.c = fifo[3] & 0xffffff;
|
|
v3.c = fifo[6] & 0xffffff;
|
|
v4.c = fifo[9] & 0xffffff;
|
|
|
|
point t1, t2, t3, t4;
|
|
t1.x = (fifo[2] & 0xffff) & 0xff;
|
|
t1.y = ((fifo[2] & 0xffff) >> 8) & 0xff;
|
|
t2.x = (fifo[5] & 0xffff) & 0xff;
|
|
t2.y = ((fifo[5] & 0xffff) >> 8) & 0xff;
|
|
t3.x = (fifo[8] & 0xffff) & 0xff;
|
|
t3.y = ((fifo[8] & 0xffff) >> 8) & 0xff;
|
|
t4.x = (fifo[11] & 0xffff) & 0xff;
|
|
t4.y = ((fifo[11] & 0xffff) >> 8) & 0xff;
|
|
int colourDepth = (texpage >> 7) & 3;
|
|
|
|
uint32_t Vertices1[] = {
|
|
// positions // colors // texture coords
|
|
v1.x, v1.y, 0, (((v1.c) >> 0) & 0xff), (((v1.c) >> 8) & 0xff), (((v1.c) >> 16) & 0xff), t1.x, t1.y, texpageX, texpageY, clutX, clutY, colourDepth,
|
|
v2.x, v2.y, 0.0f, (((v2.c) >> 0) & 0xff), (((v2.c) >> 8) & 0xff), (((v2.c) >> 16) & 0xff), t2.x, t2.y, texpageX, texpageY, clutX, clutY, colourDepth,
|
|
v3.x, v3.y, 0.0f, (((v3.c) >> 0) & 0xff), (((v3.c) >> 8) & 0xff), (((v3.c) >> 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
|
|
};
|
|
|
|
|
|
glBindTexture(GL_TEXTURE_2D, SampleVramTexture);
|
|
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices1), Vertices1, GL_STATIC_DRAW);
|
|
glUniform1i(colourDepthUniform, colourDepth);
|
|
glDrawArrays(GL_TRIANGLES, 0, 3);
|
|
|
|
uint32_t Vertices2[] = {
|
|
// positions // colors // texture coords // texpage
|
|
v2.x, v2.y, 0, (((v2.c) >> 0) & 0xff), (((v2.c) >> 8) & 0xff), (((v2.c) >> 16) & 0xff), t2.x, t2.y, texpageX, texpageY, clutX, clutY, colourDepth,
|
|
v3.x, v3.y, 0.0f, (((v3.c) >> 0) & 0xff), (((v3.c) >> 8) & 0xff), (((v3.c) >> 16) & 0xff), t3.x, t3.y, texpageX, texpageY, clutX, clutY, colourDepth,
|
|
v4.x, v4.y, 0.0f, (((v4.c) >> 0) & 0xff), (((v4.c) >> 8) & 0xff), (((v4.c) >> 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
|
|
};
|
|
|
|
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices2), Vertices2, GL_STATIC_DRAW);
|
|
glDrawArrays(GL_TRIANGLES, 0, 3);
|
|
|
|
}
|
|
|
|
void gpu::shaded_texture_blending_textured_four_point_semi_transparent_polygon() {
|
|
uint32_t colour = fifo[0] & 0xffffff;
|
|
debug_printf("[GP0] Textured four-point polygon, opaque, raw textures (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);
|
|
|
|
texpage = fifo[5] >> 16;
|
|
uint32_t texpageX = ((texpage & 0b1111) * 64);
|
|
uint32_t texpageY = (((texpage & 0b10000) >> 4) * 256);
|
|
v2.x = fifo[4] & 0xffff;
|
|
v2.y = fifo[4] >> 16;
|
|
v3.x = fifo[7] & 0xffff;
|
|
v3.y = fifo[7] >> 16;
|
|
v4.x = fifo[10] & 0xffff;
|
|
v4.y = fifo[10] >> 16;
|
|
|
|
v1.c = fifo[0] & 0xffffff;
|
|
v2.c = fifo[3] & 0xffffff;
|
|
v3.c = fifo[6] & 0xffffff;
|
|
v4.c = fifo[9] & 0xffffff;
|
|
|
|
point t1, t2, t3, t4;
|
|
t1.x = (fifo[2] & 0xffff) & 0xff;
|
|
t1.y = ((fifo[2] & 0xffff) >> 8) & 0xff;
|
|
t2.x = (fifo[5] & 0xffff) & 0xff;
|
|
t2.y = ((fifo[5] & 0xffff) >> 8) & 0xff;
|
|
t3.x = (fifo[8] & 0xffff) & 0xff;
|
|
t3.y = ((fifo[8] & 0xffff) >> 8) & 0xff;
|
|
t4.x = (fifo[11] & 0xffff) & 0xff;
|
|
t4.y = ((fifo[11] & 0xffff) >> 8) & 0xff;
|
|
int colourDepth = (texpage >> 7) & 3;
|
|
|
|
uint32_t Vertices1[] = {
|
|
// positions // colors // texture coords
|
|
v1.x, v1.y, 0, (((v1.c) >> 0) & 0xff), (((v1.c) >> 8) & 0xff), (((v1.c) >> 16) & 0xff), t1.x, t1.y, texpageX, texpageY, clutX, clutY, colourDepth,
|
|
v2.x, v2.y, 0.0f, (((v2.c) >> 0) & 0xff), (((v2.c) >> 8) & 0xff), (((v2.c) >> 16) & 0xff), t2.x, t2.y, texpageX, texpageY, clutX, clutY, colourDepth,
|
|
v3.x, v3.y, 0.0f, (((v3.c) >> 0) & 0xff), (((v3.c) >> 8) & 0xff), (((v3.c) >> 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
|
|
};
|
|
|
|
|
|
glBindTexture(GL_TEXTURE_2D, SampleVramTexture);
|
|
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices1), Vertices1, GL_STATIC_DRAW);
|
|
glUniform1i(colourDepthUniform, colourDepth);
|
|
glDrawArrays(GL_TRIANGLES, 0, 3);
|
|
|
|
uint32_t Vertices2[] = {
|
|
// positions // colors // texture coords // texpage
|
|
v2.x, v2.y, 0, (((v2.c) >> 0) & 0xff), (((v2.c) >> 8) & 0xff), (((v2.c) >> 16) & 0xff), t2.x, t2.y, texpageX, texpageY, clutX, clutY, colourDepth,
|
|
v3.x, v3.y, 0.0f, (((v3.c) >> 0) & 0xff), (((v3.c) >> 8) & 0xff), (((v3.c) >> 16) & 0xff), t3.x, t3.y, texpageX, texpageY, clutX, clutY, colourDepth,
|
|
v4.x, v4.y, 0.0f, (((v4.c) >> 0) & 0xff), (((v4.c) >> 8) & 0xff), (((v4.c) >> 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
|
|
};
|
|
|
|
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices2), Vertices2, GL_STATIC_DRAW);
|
|
glDrawArrays(GL_TRIANGLES, 0, 3);
|
|
|
|
}
|
|
|
|
void gpu::monochrome_line_opaque() {
|
|
point v1, v2;
|
|
uint32_t colour = fifo[0] & 0xffffff;
|
|
v1.x = fifo[1] & 0xffff;
|
|
v1.y = fifo[1] >> 16;
|
|
v2.x = fifo[2] & 0xffff;
|
|
v2.y = fifo[2] >> 16;
|
|
|
|
uint32_t Vertices1[]{
|
|
v1.x, v1.y, 0.0,
|
|
v2.x, v2.y, 0.0,
|
|
|
|
(((colour) >> 0) & 0xff), (((colour) >> 8) & 0xff), (((colour) >> 16) & 0xff),
|
|
(((colour) >> 0) & 0xff), (((colour) >> 8) & 0xff), (((colour) >> 16) & 0xff),
|
|
};
|
|
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices1), Vertices1, GL_STATIC_DRAW);
|
|
glDrawArrays(GL_LINES, 0, 2);
|
|
}
|
|
|
|
void gpu::shaded_line_semi_transparent() {
|
|
point v1, v2;
|
|
v1.c = fifo[0] & 0xffffff;
|
|
v2.c = fifo[2] & 0xffffff;
|
|
v1.x = fifo[1] & 0xffff;
|
|
v1.y = fifo[1] >> 16;
|
|
v2.x = fifo[3] & 0xffff;
|
|
v2.y = fifo[3] >> 16;
|
|
|
|
|
|
|
|
uint32_t Vertices[]{
|
|
v1.x, v1.y, 0.0,
|
|
v2.x, v2.y, 0.0,
|
|
|
|
(((v1.c) >> 0) & 0xff), (((v1.c) >> 8) & 0xff), (((v1.c) >> 16) & 0xff),
|
|
(((v2.c) >> 0) & 0xff), (((v2.c) >> 8) & 0xff), (((v2.c) >> 16) & 0xff),
|
|
};
|
|
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices), Vertices, GL_STATIC_DRAW);
|
|
glDrawArrays(GL_LINES, 0, 2);
|
|
}
|
|
|
|
void gpu::monochrome_polyline_opaque() {
|
|
uint32_t colour = fifo[0] & 0xffffff;
|
|
debug_printf("[GP0] Monochrome four-point polygon, opaque (colour: 0x%x)\n", colour);
|
|
point v1, v2, v3, v4, v5, v6;
|
|
/*for (int i = 1; i < cmd_length; i++) {
|
|
v1.x = fifo[i] & 0xffff;
|
|
v1.y = fifo[i] >> 16;
|
|
v2.x = fifo[i+1] & 0xffff;
|
|
v2.y = fifo[i+1] >> 16;
|
|
uint32_t Vertices1[]{
|
|
v1.x, v1.y, 0,
|
|
v2.x, v2.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)
|
|
};
|
|
glBindBuffer(GL_ARRAY_BUFFER, VBO);
|
|
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices1), Vertices1, GL_STATIC_DRAW);
|
|
glBindVertexArray(VAO);
|
|
glVertexAttribPointer(0, 2, GL_UNSIGNED_INT, GL_FALSE, 3 * sizeof(uint32_t), (void*)0);
|
|
glEnableVertexAttribArray(0);
|
|
glVertexAttribPointer(1, 3, GL_UNSIGNED_INT, GL_FALSE, 3 * sizeof(uint32_t), (void*)(6 * sizeof(uint32_t)));
|
|
glEnableVertexAttribArray(1);
|
|
glUseProgram(ShaderProgram);
|
|
glBindVertexArray(VAO);
|
|
glDrawArrays(GL_LINE, 0, 3);
|
|
glBindVertexArray(0);
|
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
|
|
|
}*/
|
|
v1.x = fifo[1] & 0xffff;
|
|
v1.y = fifo[1] >> 16;
|
|
v2.x = fifo[2] & 0xffff;
|
|
v2.y = fifo[2] >> 16;
|
|
v3.x = fifo[3] & 0xffff;
|
|
v3.y = fifo[3] >> 16;
|
|
v4.x = fifo[4] & 0xffff;
|
|
v4.y = fifo[4] >> 16;
|
|
v5.x = fifo[5] & 0xffff;
|
|
v5.y = fifo[5] >> 16;
|
|
|
|
//printf("%d\n", cmd_length);
|
|
uint32_t Vertices1[]{
|
|
v1.x, v1.y, 0,
|
|
v2.x, v2.y, 0,
|
|
v3.x, v3.y, 0,
|
|
v4.x, v4.y, 0,
|
|
v5.x, v5.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),
|
|
(((colour) >> 0) & 0xff), (((colour) >> 8) & 0xff), (((colour) >> 16) & 0xff),
|
|
(((colour) >> 0) & 0xff), (((colour) >> 8) & 0xff), (((colour) >> 16) & 0xff),
|
|
};
|
|
|
|
|
|
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*)(15 * sizeof(uint32_t)));
|
|
glEnableVertexAttribArray(1);
|
|
glUseProgram(ShaderProgram);
|
|
glBindVertexArray(VAO);
|
|
glDrawArrays(GL_LINE_STRIP, 0, 5);
|
|
glBindVertexArray(0);
|
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
|
|
|
|
|
/*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)
|
|
};
|
|
|
|
glBindBuffer(GL_ARRAY_BUFFER, VBO);
|
|
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices2), Vertices2, GL_STATIC_DRAW);
|
|
glBindVertexArray(VAO);
|
|
glVertexAttribPointer(0, 3, GL_UNSIGNED_INT, GL_FALSE, 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_LINE_STRIP, 0, 3);
|
|
glBindVertexArray(0);
|
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
|
*/
|
|
}
|
|
|
|
void gpu::monochrome_rectangle_variable_size_opaque() {
|
|
uint32_t colour = fifo[0] & 0xffffff;
|
|
debug_printf("[GP0] Monochrome Rectangle (variable size) (opaque) (colour: 0x%x)\n", colour);
|
|
point v1, res, v2, v3, v4;
|
|
v1.x = fifo[1] & 0xffff;
|
|
v1.y = fifo[1] >> 16;
|
|
res.x = fifo[2] & 0xffff;
|
|
res.y = fifo[2] >> 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;
|
|
|
|
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)
|
|
};
|
|
|
|
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices1), Vertices1, GL_STATIC_DRAW);
|
|
glDrawArrays(GL_TRIANGLES, 0, 3);
|
|
|
|
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)
|
|
};
|
|
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices2), Vertices2, GL_STATIC_DRAW);
|
|
glDrawArrays(GL_TRIANGLES, 0, 3);
|
|
|
|
}
|
|
|
|
void gpu::monochrome_rectangle_variable_size_semi_transparent() {
|
|
uint32_t colour = fifo[0] & 0xffffff;
|
|
debug_printf("[GP0] Monochrome Rectangle (variable size) (semi-transparent) (colour: 0x%x)\n", colour);
|
|
point v1, res, v2, v3, v4;
|
|
v1.x = fifo[1] & 0xffff;
|
|
v1.y = fifo[1] >> 16;
|
|
res.x = fifo[2] & 0xffff;
|
|
res.y = fifo[2] >> 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;
|
|
|
|
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)
|
|
};
|
|
|
|
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices1), Vertices1, GL_STATIC_DRAW);
|
|
glDrawArrays(GL_TRIANGLES, 0, 3);
|
|
|
|
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)
|
|
};
|
|
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices2), Vertices2, GL_STATIC_DRAW);
|
|
glDrawArrays(GL_TRIANGLES, 0, 3);
|
|
|
|
}
|
|
|
|
void gpu::texture_blending_rectangle_variable_size_opaque() {
|
|
uint32_t colour = fifo[0] & 0xffffff;
|
|
debug_printf("[GP0] Textured Rectangle, variable size, 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);
|
|
|
|
//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;
|
|
|
|
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
|
|
};
|
|
|
|
|
|
glBindTexture(GL_TEXTURE_2D, SampleVramTexture);
|
|
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices1), Vertices1, GL_STATIC_DRAW);
|
|
glUniform1i(colourDepthUniform, colourDepth);
|
|
glDrawArrays(GL_TRIANGLES, 0, 3);
|
|
|
|
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
|
|
};
|
|
|
|
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices2), Vertices2, GL_STATIC_DRAW);
|
|
glDrawArrays(GL_TRIANGLES, 0, 3);
|
|
|
|
}
|
|
|
|
void gpu::texture_blending_rectangle_8x8_opaque() {
|
|
uint32_t colour = fifo[0] & 0xffffff;
|
|
debug_printf("[GP0] Textured Rectangle, 8x8, 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);
|
|
|
|
//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;
|
|
|
|
point t1, t2, t3, t4;
|
|
t1.x = (fifo[2] & 0xffff) & 0xff;
|
|
t1.y = ((fifo[2] & 0xffff) >> 8) & 0xff;
|
|
t2.x = t1.x + 8;
|
|
t2.y = t1.y;
|
|
t3.x = t1.x;
|
|
t3.y = t1.y + 8;
|
|
t4.x = t1.x + 8;
|
|
t4.y = t1.y + 8;
|
|
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
|
|
};
|
|
|
|
|
|
glBindTexture(GL_TEXTURE_2D, SampleVramTexture);
|
|
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices1), Vertices1, GL_STATIC_DRAW);
|
|
glUniform1i(colourDepthUniform, colourDepth);
|
|
glDrawArrays(GL_TRIANGLES, 0, 3);
|
|
|
|
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
|
|
};
|
|
|
|
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices2), Vertices2, GL_STATIC_DRAW);
|
|
glDrawArrays(GL_TRIANGLES, 0, 3);
|
|
|
|
}
|
|
|
|
void gpu::texture_rectangle_8x8_opaque() {
|
|
uint32_t colour = fifo[0] & 0xffffff;
|
|
debug_printf("[GP0] Textured Rectangle, 8x8, opaque, 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);
|
|
|
|
//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;
|
|
|
|
point t1, t2, t3, t4;
|
|
t1.x = (fifo[2] & 0xffff) & 0xff;
|
|
t1.y = ((fifo[2] & 0xffff) >> 8) & 0xff;
|
|
t2.x = t1.x + 8;
|
|
t2.y = t1.y;
|
|
t3.x = t1.x;
|
|
t3.y = t1.y + 8;
|
|
t4.x = t1.x + 8;
|
|
t4.y = t1.y + 8;
|
|
int colourDepth = (texpage >> 7) & 3;
|
|
|
|
uint32_t Vertices1[] = {
|
|
// positions // colors // texture coords
|
|
v1.x, v1.y, 0, 128, 128, 128, t1.x, t1.y, texpageX, texpageY, clutX, clutY, colourDepth,
|
|
v2.x, v2.y, 0.0f, 128, 128, 128, t2.x, t2.y, texpageX, texpageY, clutX, clutY, colourDepth,
|
|
v3.x, v3.y, 0.0f, 128, 128, 128, 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
|
|
};
|
|
|
|
|
|
glBindTexture(GL_TEXTURE_2D, SampleVramTexture);
|
|
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices1), Vertices1, GL_STATIC_DRAW);
|
|
glUniform1i(colourDepthUniform, colourDepth);
|
|
glDrawArrays(GL_TRIANGLES, 0, 3);
|
|
|
|
uint32_t Vertices2[] = {
|
|
// positions // colors // texture coords // texpage
|
|
v2.x, v2.y, 0, 128, 128, 128, t2.x, t2.y, texpageX, texpageY, clutX, clutY, colourDepth,
|
|
v3.x, v3.y, 0.0f, 128, 128, 128, t3.x, t3.y, texpageX, texpageY, clutX, clutY, colourDepth,
|
|
v4.x, v4.y, 0.0f, 128, 128, 128, 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
|
|
};
|
|
|
|
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices2), Vertices2, GL_STATIC_DRAW);
|
|
glDrawArrays(GL_TRIANGLES, 0, 3);
|
|
|
|
}
|
|
|
|
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);
|
|
|
|
//texpage = fifo[4] >> 16;
|
|
uint32_t texpageX = ((texpage & 0b1111) * 64);
|
|
uint32_t texpageY = (((texpage & 0b10000) >> 4) * 256);
|
|
v2.x = v1.x + 16;
|
|
v2.y = v1.y;
|
|
v3.x = v1.x;
|
|
v3.y = v1.y + 16;
|
|
v4.x = v1.x + 16;
|
|
v4.y = v1.y + 16;
|
|
|
|
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
|
|
};
|
|
|
|
|
|
glBindTexture(GL_TEXTURE_2D, SampleVramTexture);
|
|
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices1), Vertices1, GL_STATIC_DRAW);
|
|
glUniform1i(colourDepthUniform, colourDepth);
|
|
glDrawArrays(GL_TRIANGLES, 0, 3);
|
|
|
|
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
|
|
};
|
|
|
|
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices2), Vertices2, GL_STATIC_DRAW);
|
|
glDrawArrays(GL_TRIANGLES, 0, 3);
|
|
|
|
}
|
|
|
|
void gpu::texture_rectangle_16x16_opaque() {
|
|
uint32_t colour = fifo[0] & 0xffffff;
|
|
debug_printf("[GP0] Textured Rectangle, 16x16, opaque, 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);
|
|
|
|
//texpage = fifo[4] >> 16;
|
|
uint32_t texpageX = ((texpage & 0b1111) * 64);
|
|
uint32_t texpageY = (((texpage & 0b10000) >> 4) * 256);
|
|
v2.x = v1.x + 16;
|
|
v2.y = v1.y;
|
|
v3.x = v1.x;
|
|
v3.y = v1.y + 16;
|
|
v4.x = v1.x + 16;
|
|
v4.y = v1.y + 16;
|
|
|
|
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, 128, 128, 128, t1.x, t1.y, texpageX, texpageY, clutX, clutY, colourDepth,
|
|
v2.x, v2.y, 0.0f, 128, 128, 128, t2.x, t2.y, texpageX, texpageY, clutX, clutY, colourDepth,
|
|
v3.x, v3.y, 0.0f, 128, 128, 128, 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
|
|
};
|
|
|
|
|
|
glBindTexture(GL_TEXTURE_2D, SampleVramTexture);
|
|
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices1), Vertices1, GL_STATIC_DRAW);
|
|
glUniform1i(colourDepthUniform, colourDepth);
|
|
glDrawArrays(GL_TRIANGLES, 0, 3);
|
|
|
|
uint32_t Vertices2[] = {
|
|
// positions // colors // texture coords // texpage
|
|
v2.x, v2.y, 0, 128, 128, 128, t2.x, t2.y, texpageX, texpageY, clutX, clutY, colourDepth,
|
|
v3.x, v3.y, 0.0f, 128, 128, 128, t3.x, t3.y, texpageX, texpageY, clutX, clutY, colourDepth,
|
|
v4.x, v4.y, 0.0f, 128, 128, 128, 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
|
|
};
|
|
|
|
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices2), Vertices2, GL_STATIC_DRAW);
|
|
glDrawArrays(GL_TRIANGLES, 0, 3);
|
|
|
|
}
|
|
|
|
void gpu::texture_rectangle_16x16_semi_transparent() {
|
|
uint32_t colour = fifo[0] & 0xffffff;
|
|
debug_printf("[GP0] Textured Rectangle, 16x16, semi-transparent, 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);
|
|
|
|
//texpage = fifo[4] >> 16;
|
|
uint32_t texpageX = ((texpage & 0b1111) * 64);
|
|
uint32_t texpageY = (((texpage & 0b10000) >> 4) * 256);
|
|
v2.x = v1.x + 16;
|
|
v2.y = v1.y;
|
|
v3.x = v1.x;
|
|
v3.y = v1.y + 16;
|
|
v4.x = v1.x + 16;
|
|
v4.y = v1.y + 16;
|
|
|
|
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, 128, 128, 128, t1.x, t1.y, texpageX, texpageY, clutX, clutY, colourDepth,
|
|
v2.x, v2.y, 0.0f, 128, 128, 128, t2.x, t2.y, texpageX, texpageY, clutX, clutY, colourDepth,
|
|
v3.x, v3.y, 0.0f, 128, 128, 128, 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
|
|
};
|
|
|
|
|
|
glBindTexture(GL_TEXTURE_2D, SampleVramTexture);
|
|
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices1), Vertices1, GL_STATIC_DRAW);
|
|
glUniform1i(colourDepthUniform, colourDepth);
|
|
glDrawArrays(GL_TRIANGLES, 0, 3);
|
|
|
|
uint32_t Vertices2[] = {
|
|
// positions // colors // texture coords // texpage
|
|
v2.x, v2.y, 0, 128, 128, 128, t2.x, t2.y, texpageX, texpageY, clutX, clutY, colourDepth,
|
|
v3.x, v3.y, 0.0f, 128, 128, 128, t3.x, t3.y, texpageX, texpageY, clutX, clutY, colourDepth,
|
|
v4.x, v4.y, 0.0f, 128, 128, 128, 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
|
|
};
|
|
|
|
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices2), Vertices2, GL_STATIC_DRAW);
|
|
glDrawArrays(GL_TRIANGLES, 0, 3);
|
|
|
|
}
|
|
|
|
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);
|
|
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);
|
|
|
|
//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;
|
|
|
|
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, 128, 128, 128, t1.x, t1.y, texpageX, texpageY, clutX, clutY, colourDepth,
|
|
v2.x, v2.y, 0.0f, 128, 128, 128, t2.x, t2.y, texpageX, texpageY, clutX, clutY, colourDepth,
|
|
v3.x, v3.y, 0.0f, 128, 128, 128, 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
|
|
};
|
|
|
|
|
|
glBindTexture(GL_TEXTURE_2D, SampleVramTexture);
|
|
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices1), Vertices1, GL_STATIC_DRAW);
|
|
glUniform1i(colourDepthUniform, colourDepth);
|
|
glDrawArrays(GL_TRIANGLES, 0, 3);
|
|
|
|
uint32_t Vertices2[] = {
|
|
// positions // colors // texture coords // texpage
|
|
v2.x, v2.y, 0, 128, 128, 128, t2.x, t2.y, texpageX, texpageY, clutX, clutY, colourDepth,
|
|
v3.x, v3.y, 0.0f, 128, 128, 128, t3.x, t3.y, texpageX, texpageY, clutX, clutY, colourDepth,
|
|
v4.x, v4.y, 0.0f, 128, 128, 128, 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
|
|
};
|
|
|
|
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices2), Vertices2, GL_STATIC_DRAW);
|
|
glDrawArrays(GL_TRIANGLES, 0, 3);
|
|
|
|
}
|
|
|
|
void gpu::texture_blending_rectangle_variable_size_semi_transparent() {
|
|
uint32_t colour = fifo[0] & 0xffffff;
|
|
debug_printf("[GP0] Textured Rectangle, variable size, semi-transp, 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);
|
|
|
|
//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;
|
|
|
|
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
|
|
};
|
|
|
|
|
|
glBindTexture(GL_TEXTURE_2D, SampleVramTexture);
|
|
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices1), Vertices1, GL_STATIC_DRAW);
|
|
glUniform1i(colourDepthUniform, colourDepth);
|
|
glDrawArrays(GL_TRIANGLES, 0, 3);
|
|
|
|
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
|
|
};
|
|
|
|
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices2), Vertices2, GL_STATIC_DRAW);
|
|
glDrawArrays(GL_TRIANGLES, 0, 3);
|
|
|
|
}
|
|
|
|
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);
|
|
|
|
//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;
|
|
|
|
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, 128, 128, 128, t1.x, t1.y, texpageX, texpageY, clutX, clutY, colourDepth,
|
|
v2.x, v2.y, 0.0f, 128, 128, 128, t2.x, t2.y, texpageX, texpageY, clutX, clutY, colourDepth,
|
|
v3.x, v3.y, 0.0f, 128, 128, 128, 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
|
|
};
|
|
|
|
|
|
glBindTexture(GL_TEXTURE_2D, SampleVramTexture);
|
|
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices1), Vertices1, GL_STATIC_DRAW);
|
|
glUniform1i(colourDepthUniform, colourDepth);
|
|
glDrawArrays(GL_TRIANGLES, 0, 3);
|
|
|
|
uint32_t Vertices2[] = {
|
|
// positions // colors // texture coords // texpage
|
|
v2.x, v2.y, 0, 128, 128, 128, t2.x, t2.y, texpageX, texpageY, clutX, clutY, colourDepth,
|
|
v3.x, v3.y, 0.0f, 128, 128, 128, t3.x, t3.y, texpageX, texpageY, clutX, clutY, colourDepth,
|
|
v4.x, v4.y, 0.0f, 128, 128, 128, 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
|
|
};
|
|
|
|
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices2), Vertices2, GL_STATIC_DRAW);
|
|
glDrawArrays(GL_TRIANGLES, 0, 3);
|
|
|
|
}
|
|
|
|
void gpu::monochrome_rectangle_dot_opaque() {
|
|
uint32_t colour = fifo[0] & 0xffffff;
|
|
debug_printf("[GP0] Monochrome Rectangle (1x1) (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 + 1;
|
|
v2.y = v1.y;
|
|
v3.x = v1.x;
|
|
v3.y = v1.y + 1;
|
|
v4.x = v1.x + 1;
|
|
v4.y = v1.y + 1;
|
|
|
|
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)
|
|
};
|
|
|
|
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices1), Vertices1, GL_STATIC_DRAW);
|
|
glDrawArrays(GL_TRIANGLES, 0, 3);
|
|
|
|
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)
|
|
};
|
|
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices2), Vertices2, GL_STATIC_DRAW);
|
|
glDrawArrays(GL_TRIANGLES, 0, 3);
|
|
|
|
}
|
|
|
|
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;
|
|
|
|
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)
|
|
};
|
|
|
|
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices1), Vertices1, GL_STATIC_DRAW);
|
|
glDrawArrays(GL_TRIANGLES, 0, 3);
|
|
|
|
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)
|
|
};
|
|
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices2), Vertices2, GL_STATIC_DRAW);
|
|
glDrawArrays(GL_TRIANGLES, 0, 3);
|
|
}
|
|
|
|
void gpu::monochrome_rectangle_16x16_opaque() {
|
|
uint32_t colour = fifo[0] & 0xffffff;
|
|
debug_printf("[GP0] Monochrome Rectangle (16x16) (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 + 16;
|
|
v2.y = v1.y;
|
|
v3.x = v1.x;
|
|
v3.y = v1.y + 16;
|
|
v4.x = v1.x + 16;
|
|
v4.y = v1.y + 16;
|
|
|
|
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)
|
|
};
|
|
|
|
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices1), Vertices1, GL_STATIC_DRAW);
|
|
glDrawArrays(GL_TRIANGLES, 0, 3);
|
|
|
|
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)
|
|
};
|
|
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices2), Vertices2, GL_STATIC_DRAW);
|
|
glDrawArrays(GL_TRIANGLES, 0, 3);
|
|
}
|
|
|
|
void gpu::fill_rectangle() {
|
|
debug_printf("[GP0] Fill Rectangle\n");
|
|
glViewport(0, 0, 1024 * scaling_factor, 512 * scaling_factor);
|
|
uint8_t r = (fifo[0] & 0xff);
|
|
uint8_t g = ((fifo[0] >> 8) & 0xff);
|
|
uint8_t b = ((fifo[0] >> 16) & 0xff);
|
|
uint32_t x = fifo[1] & 0xffff;
|
|
uint32_t y = fifo[1] >> 16;
|
|
uint32_t width = fifo[2] & 0xffff;
|
|
uint32_t height = fifo[2] >> 16;
|
|
|
|
glClearColor(r / 255.f, g / 255.f, b / 255.f, 1.f);
|
|
glScissor(x * scaling_factor, y * scaling_factor, width * scaling_factor, height * scaling_factor);
|
|
glClear(GL_COLOR_BUFFER_BIT);
|
|
glScissor(drawing_topleft_x * scaling_factor, drawing_topleft_y * scaling_factor, (drawing_bottomright_x - drawing_topleft_x) * scaling_factor, (drawing_bottomright_y - drawing_topleft_y) * scaling_factor);
|
|
}
|
|
|
|
void gpu::vram_to_vram() {
|
|
uint32_t colour = fifo[0] & 0xffffff;
|
|
debug_printf("[GP0] Copy Rectangle (VRAM to VRAM)\n", colour);
|
|
uint32_t resolution = fifo[3];
|
|
uint32_t coords = fifo[1];
|
|
uint32_t dest_coords = fifo[2];
|
|
auto width = resolution & 0xffff;
|
|
auto height = resolution >> 16;
|
|
if (width == 0) width = 1024;
|
|
if (height == 0) height = 512;
|
|
|
|
auto x = coords & 0x3ff;
|
|
auto y = (coords >> 16) & 0x1ff;
|
|
auto dest_x = dest_coords & 0x3ff;
|
|
auto dest_y = (dest_coords >> 16) & 0x1ff;
|
|
|
|
//glReadPixels(x, y, width, height, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, ReadBuffer);
|
|
|
|
glBindTexture(GL_TEXTURE_2D, VramTexture);
|
|
//glTexSubImage2D(GL_TEXTURE_2D, 0, dest_x, dest_y, width, height, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, ReadBuffer);
|
|
}
|
|
|
|
void gpu::cpu_to_vram() {
|
|
debug_printf("[GP0] Copy Rectangle (CPU to VRAM)\n");
|
|
uint32_t resolution = fifo[2];
|
|
uint32_t coords = fifo[1];
|
|
auto width = resolution & 0xffff;
|
|
auto height = resolution >> 16;
|
|
xpos = 0;
|
|
ypos = 0;
|
|
uint32_t size = width * height;
|
|
size += 1;
|
|
size &= ~1;
|
|
cmd_left = size / 2;
|
|
cmd_left++;
|
|
gp0_mode = 1;
|
|
}
|
|
|
|
void gpu::vram_to_cpu() {
|
|
uint32_t resolution = fifo[2];
|
|
uint32_t coords = fifo[1];
|
|
auto width = resolution & 0xffff;
|
|
auto height = resolution >> 16;
|
|
if (width == 0) width = 1024;
|
|
if (height == 0) height = 512;
|
|
|
|
auto x = coords & 0x3ff;
|
|
auto y = (coords >> 16) & 0x1ff;
|
|
|
|
width &= 0x3ff;
|
|
height &= 0x1ff;
|
|
uint32_t size = width * height;
|
|
size += 1;
|
|
size &= ~1;
|
|
|
|
size /= 2;
|
|
|
|
glReadPixels(x, y, width, height, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, ReadBuffer);
|
|
|
|
ReadBufferCnt = 0;
|
|
} |