diff --git a/include/PICA/shader.hpp b/include/PICA/shader.hpp index e4101141..78de1adc 100644 --- a/include/PICA/shader.hpp +++ b/include/PICA/shader.hpp @@ -15,6 +15,7 @@ namespace ShaderOpcodes { ADD = 0x00, DP4 = 0x02, MUL = 0x08, + MOVA = 0x12, MOV = 0x13, END = 0x22 }; @@ -32,7 +33,8 @@ class PICAShader { std::array floatUniformBuffer; // Buffer for temporarily caching float uniform data std::array operandDescriptors; - std::array tempRegisters; + std::array tempRegisters; // General purpose registers the shader can use for temp values + OpenGL::Vector addrRegister; // Address register ShaderType type; vec4f getSource(u32 source); @@ -42,6 +44,7 @@ class PICAShader { void add(u32 instruction); void dp4(u32 instruction); void mov(u32 instruction); + void mova(u32 instruction); void mul(u32 instruction); // src1, src2 and src3 have different negation & component swizzle bits in the operand descriptor diff --git a/src/core/PICA/shader_interpreter.cpp b/src/core/PICA/shader_interpreter.cpp index c55cd6a1..afdf9a07 100644 --- a/src/core/PICA/shader_interpreter.cpp +++ b/src/core/PICA/shader_interpreter.cpp @@ -12,6 +12,7 @@ void PICAShader::run() { case ShaderOpcodes::DP4: dp4(instruction); break; case ShaderOpcodes::END: return; // Stop running shader case ShaderOpcodes::MOV: mov(instruction); break; + case ShaderOpcodes::MOVA: mova(instruction); break; case ShaderOpcodes::MUL: mul(instruction); break; default:Helpers::panic("Unimplemented PICA instruction %08X (Opcode = %02X)", instruction, opcode); } @@ -98,6 +99,22 @@ void PICAShader::mov(u32 instruction) { } } +void PICAShader::mova(u32 instruction) { + const u32 operandDescriptor = operandDescriptors[instruction & 0x7f]; + const u32 src = (instruction >> 12) & 0x7f; + const u32 idx = (instruction >> 19) & 3; + const u32 dest = (instruction >> 21) & 0x1f; + + if (idx) Helpers::panic("[PICA] MOVA: idx != 0"); + vec4f srcVector = getSourceSwizzled<1>(src, operandDescriptor); + + u32 componentMask = operandDescriptor & 0xf; + if (componentMask & 0b1000) // x component + addrRegister.x() = static_cast(srcVector.x().toFloat32()); + if (componentMask & 0b0100) // y component + addrRegister.y() = static_cast(srcVector.y().toFloat32()); +} + void PICAShader::dp4(u32 instruction) { const u32 operandDescriptor = operandDescriptors[instruction & 0x7f]; const u32 src1 = (instruction >> 12) & 0x7f;