diff --git a/include/PICA/shader.hpp b/include/PICA/shader.hpp index f249cd0a..b1833607 100644 --- a/include/PICA/shader.hpp +++ b/include/PICA/shader.hpp @@ -23,6 +23,7 @@ namespace ShaderOpcodes { RSQ = 0x0F, MOVA = 0x12, MOV = 0x13, + SLTI = 0x1B, NOP = 0x21, END = 0x22, CALL = 0x24, @@ -111,6 +112,7 @@ class PICAShader { void mul(u32 instruction); void rcp(u32 instruction); void rsq(u32 instruction); + void slti(u32 instruction); // src1, src2 and src3 have different negation & component swizzle bits in the operand descriptor // https://problemkaputt.github.io/gbatek.htm#3dsgpushaderinstructionsetopcodesummary in the diff --git a/src/core/PICA/shader_interpreter.cpp b/src/core/PICA/shader_interpreter.cpp index de23d05c..4a7e0e70 100644 --- a/src/core/PICA/shader_interpreter.cpp +++ b/src/core/PICA/shader_interpreter.cpp @@ -36,6 +36,7 @@ void PICAShader::run() { case ShaderOpcodes::NOP: break; // Do nothing case ShaderOpcodes::RCP: rcp(instruction); break; case ShaderOpcodes::RSQ: rsq(instruction); break; + case ShaderOpcodes::SLTI: slti(instruction); break; case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37: madi(instruction); @@ -406,6 +407,27 @@ void PICAShader::madi(u32 instruction) { } } +void PICAShader::slti(u32 instruction) { + const u32 operandDescriptor = operandDescriptors[instruction & 0x1f]; + const u32 src1 = (instruction >> 14) & 0x1f; + u32 src2 = (instruction >> 7) & 0x7f; + const u32 idx = (instruction >> 19) & 3; + const u32 dest = (instruction >> 21) & 0x1f; + + src2 = getIndexedSource(src2, idx); + + auto srcVec1 = getSourceSwizzled<1>(src1, operandDescriptor); + auto srcVec2 = getSourceSwizzled<2>(src2, operandDescriptor); + auto& destVector = getDest(dest); + + u32 componentMask = operandDescriptor & 0xf; + for (int i = 0; i < 4; i++) { + if (componentMask & (1 << i)) { + destVector[3 - i] = srcVec1[3 - i] < srcVec2[3 - i] ? f24::fromFloat32(1.0) : f24::zero(); + } + } +} + void PICAShader::cmp(u32 instruction) { const u32 operandDescriptor = operandDescriptors[instruction & 0x7f]; const u32 src1 = (instruction >> 12) & 0x7f;