From 0cdf8ff1027b63e5ec9ce0ccc72cf4d8a8721a21 Mon Sep 17 00:00:00 2001
From: Jannik Vogel <email@jannikvogel.de>
Date: Tue, 15 Mar 2016 20:00:42 +0100
Subject: [PATCH 1/2] Update nihstro to latest master

---
 externals/nihstro | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/externals/nihstro b/externals/nihstro
index 445cba0b2f..26a0a04a45 160000
--- a/externals/nihstro
+++ b/externals/nihstro
@@ -1 +1 @@
-Subproject commit 445cba0b2ff8d348368e32698e4760a670260bfc
+Subproject commit 26a0a04a458df2b9ba6e39608bee183d8a0a00ec

From 9aad2f29bb5106c840badcce8027f3e0271dfe1f Mon Sep 17 00:00:00 2001
From: Jannik Vogel <email@jannikvogel.de>
Date: Wed, 9 Mar 2016 14:48:45 +0100
Subject: [PATCH 2/2] PICA: Fix MAD/MADI encoding

---
 .../debugger/graphics_vertex_shader.cpp       | 12 +++-
 src/video_core/shader/shader_interpreter.cpp  |  7 ++-
 src/video_core/shader/shader_jit_x64.cpp      | 55 ++++++++++---------
 3 files changed, 43 insertions(+), 31 deletions(-)

diff --git a/src/citra_qt/debugger/graphics_vertex_shader.cpp b/src/citra_qt/debugger/graphics_vertex_shader.cpp
index 4b676f1b16..d648d46403 100644
--- a/src/citra_qt/debugger/graphics_vertex_shader.cpp
+++ b/src/citra_qt/debugger/graphics_vertex_shader.cpp
@@ -179,9 +179,17 @@ QVariant GraphicsVertexShaderModel::data(const QModelIndex& index, int role) con
                     AlignToColumn(kOutputColumnWidth);
                     print_input(output, src1, swizzle.negate_src1, SelectorToString(swizzle.src1_selector));
                     AlignToColumn(kInputOperandColumnWidth);
-                    print_input(output, src2, swizzle.negate_src2, SelectorToString(swizzle.src2_selector));
+                    if (src_is_inverted) {
+                      print_input(output, src2, swizzle.negate_src2, SelectorToString(swizzle.src2_selector));
+                    } else {
+                      print_input(output, src2, swizzle.negate_src2, SelectorToString(swizzle.src2_selector), true, instr.mad.AddressRegisterName());
+                    }
                     AlignToColumn(kInputOperandColumnWidth);
-                    print_input(output, src3, swizzle.negate_src3, SelectorToString(swizzle.src3_selector));
+                    if (src_is_inverted) {
+                      print_input(output, src3, swizzle.negate_src3, SelectorToString(swizzle.src3_selector), true, instr.mad.AddressRegisterName());
+                    } else {
+                      print_input(output, src3, swizzle.negate_src3, SelectorToString(swizzle.src3_selector));
+                    }
                     AlignToColumn(kInputOperandColumnWidth);
                     break;
                 }
diff --git a/src/video_core/shader/shader_interpreter.cpp b/src/video_core/shader/shader_interpreter.cpp
index 79fcc56b9b..295a2466b1 100644
--- a/src/video_core/shader/shader_interpreter.cpp
+++ b/src/video_core/shader/shader_interpreter.cpp
@@ -413,9 +413,12 @@ void RunInterpreter(UnitState<Debug>& state) {
 
                 bool is_inverted = (instr.opcode.Value().EffectiveOpCode() == OpCode::Id::MADI);
 
+                const int address_offset = (instr.mad.address_register_index == 0)
+                                           ? 0 : state.address_registers[instr.mad.address_register_index - 1];
+
                 const float24* src1_ = LookupSourceRegister(instr.mad.GetSrc1(is_inverted));
-                const float24* src2_ = LookupSourceRegister(instr.mad.GetSrc2(is_inverted));
-                const float24* src3_ = LookupSourceRegister(instr.mad.GetSrc3(is_inverted));
+                const float24* src2_ = LookupSourceRegister(instr.mad.GetSrc2(is_inverted) + (!is_inverted * address_offset));
+                const float24* src3_ = LookupSourceRegister(instr.mad.GetSrc3(is_inverted) + ( is_inverted * address_offset));
 
                 const bool negate_src1 = ((bool)swizzle.negate_src1 != false);
                 const bool negate_src2 = ((bool)swizzle.negate_src2 != false);
diff --git a/src/video_core/shader/shader_jit_x64.cpp b/src/video_core/shader/shader_jit_x64.cpp
index 5083d7e54b..443bcbbefc 100644
--- a/src/video_core/shader/shader_jit_x64.cpp
+++ b/src/video_core/shader/shader_jit_x64.cpp
@@ -160,40 +160,41 @@ void JitCompiler::Compile_SwizzleSrc(Instruction instr, unsigned src_num, Source
     ASSERT_MSG(src_offset == src_offset_disp, "Source register offset too large for int type");
 
     unsigned operand_desc_id;
+
+    const bool is_inverted = (0 != (instr.opcode.Value().GetInfo().subtype & OpCode::Info::SrcInversed));
+
+    unsigned address_register_index;
+    unsigned offset_src;
+
     if (instr.opcode.Value().EffectiveOpCode() == OpCode::Id::MAD ||
         instr.opcode.Value().EffectiveOpCode() == OpCode::Id::MADI) {
-        // The MAD and MADI instructions do not use the address offset registers, so loading the
-        // source is a bit simpler here
-
         operand_desc_id = instr.mad.operand_desc_id;
-
-        // Load the source
-        MOVAPS(dest, MDisp(src_ptr, src_offset_disp));
+        offset_src = is_inverted ? 3 : 2;
+        address_register_index = instr.mad.address_register_index;
     } else {
         operand_desc_id = instr.common.operand_desc_id;
+        offset_src = is_inverted ? 2 : 1;
+        address_register_index = instr.common.address_register_index;
+    }
 
-        const bool is_inverted = (0 != (instr.opcode.Value().GetInfo().subtype & OpCode::Info::SrcInversed));
-        unsigned offset_src = is_inverted ? 2 : 1;
-
-        if (src_num == offset_src && instr.common.address_register_index != 0) {
-            switch (instr.common.address_register_index) {
-            case 1: // address offset 1
-                MOVAPS(dest, MComplex(src_ptr, ADDROFFS_REG_0, SCALE_1, src_offset_disp));
-                break;
-            case 2: // address offset 2
-                MOVAPS(dest, MComplex(src_ptr, ADDROFFS_REG_1, SCALE_1, src_offset_disp));
-                break;
-            case 3: // address offset 3
-                MOVAPS(dest, MComplex(src_ptr, LOOPCOUNT_REG, SCALE_1, src_offset_disp));
-                break;
-            default:
-                UNREACHABLE();
-                break;
-            }
-        } else {
-            // Load the source
-            MOVAPS(dest, MDisp(src_ptr, src_offset_disp));
+    if (src_num == offset_src && address_register_index != 0) {
+        switch (address_register_index) {
+        case 1: // address offset 1
+            MOVAPS(dest, MComplex(src_ptr, ADDROFFS_REG_0, SCALE_1, src_offset_disp));
+            break;
+        case 2: // address offset 2
+            MOVAPS(dest, MComplex(src_ptr, ADDROFFS_REG_1, SCALE_1, src_offset_disp));
+            break;
+        case 3: // address offset 3
+            MOVAPS(dest, MComplex(src_ptr, LOOPCOUNT_REG, SCALE_1, src_offset_disp));
+            break;
+        default:
+            UNREACHABLE();
+            break;
         }
+    } else {
+        // Load the source
+        MOVAPS(dest, MDisp(src_ptr, src_offset_disp));
     }
 
     SwizzlePattern swiz = { g_state.vs.swizzle_data[operand_desc_id] };