]> Chaos Git - corbenik/ctrulib.git/commitdiff
SHDR : untested
authorsmea <smealum@gmail.com>
Sat, 8 Mar 2014 11:43:16 +0000 (12:43 +0100)
committersmea <smealum@gmail.com>
Sat, 8 Mar 2014 11:43:16 +0000 (12:43 +0100)
libctru/include/ctr/SHDR.h [new file with mode: 0644]
libctru/source/SHDR.c [new file with mode: 0644]

diff --git a/libctru/include/ctr/SHDR.h b/libctru/include/ctr/SHDR.h
new file mode 100644 (file)
index 0000000..e0712e0
--- /dev/null
@@ -0,0 +1,50 @@
+#ifndef SHDR_H
+#define SHDR_H
+
+typedef enum{
+       VERTEX_SHDR=0x0,
+       GEOMETRY_SHDR=0x1
+}SHDR_type;
+
+typedef enum{
+       RESULT_POSITION = 0x0,
+       RESULT_COLOR = 0x2,
+       RESULT_TEXCOORD0 = 0x3,
+       RESULT_TEXCOORD1 = 0x5,
+       RESULT_TEXCOORD2 = 0x6
+}SHDR_outType;
+
+typedef struct{
+       u32 codeSize;
+       u32* codeData;
+       u32 opdescSize;
+       u32* opcdescData;
+}DVLP_s;
+
+typedef struct{
+       u32 header;
+       u32 data[4];
+}DVLE_constEntry_s;
+
+typedef struct{
+       u32 header;
+       u16 type;
+       u16 regID;
+}DVLE_outEntry_s;
+
+typedef struct{
+       SHDR_type type;
+       u32 mainOffset, endmainOffset;
+       u32 constTableSize;
+       DVLE_constEntry_s* constTableData;
+       u32 outTableSize;
+       DVLE_outEntry_s* outTableData;
+}DVLE_s;
+
+typedef struct{
+       u32 numDVLE;
+       DVLP_s DVLP;
+       DVLE_s* DVLE;
+}DVLB_s;
+
+#endif
diff --git a/libctru/source/SHDR.c b/libctru/source/SHDR.c
new file mode 100644 (file)
index 0000000..9955380
--- /dev/null
@@ -0,0 +1,104 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <ctr/types.h>
+#include <ctr/GSP.h>
+#include <ctr/GX.h>
+#include <ctr/GPU.h>
+#include <ctr/SHDR.h>
+#include <ctr/svc.h>
+
+//please don't feed this an invalid SHBIN
+DVLB_s* SHDR_ParseSHBIN(u32* shbinData, u32 shbinSize)
+{
+       if(!shbinData)return NULL;
+       DVLB_s* ret=malloc(sizeof(DVLB_s));
+       if(!ret)goto exit;
+
+       //parse DVLB
+       ret->numDVLE=shbinData[1];
+       ret->DVLE=malloc(sizeof(DVLE_s)*ret->numDVLE);
+       if(!ret->DVLE)goto clean1;
+
+       //parse DVLP
+       u32* dvlpData=&shbinData[2+ret->numDVLE];
+       ret->DVLP.codeSize=dvlpData[3];
+       ret->DVLP.codeData=&dvlpData[dvlpData[2]/4];
+       ret->DVLP.opdescSize=dvlpData[5];
+       ret->DVLP.opcdescData=&dvlpData[dvlpData[4]/4];
+
+       //parse DVLE
+       int i;
+       for(i=0;i<ret->numDVLE;i++)
+       {
+               DVLE_s* dvle=&ret->DVLE[i];
+               u32* dvleData=&shbinData[shbinData[2+i]/4];
+
+               dvle->type=(dvleData[1]>>16)&0xFF;
+               dvle->mainOffset=dvleData[2];
+               dvle->endmainOffset=dvleData[3];
+
+               dvle->constTableSize=dvleData[7];
+               dvle->constTableData=(DVLE_constEntry_s*)&dvleData[dvleData[6]/4];
+
+               dvle->outTableSize=dvleData[11];
+               dvle->outTableData=(DVLE_outEntry_s*)&dvleData[dvleData[10]/4];
+       }
+
+       clean1:
+               free(ret);
+       exit:
+               return ret;
+}
+
+void DVLP_SendCode(DVLP_s* dvlp)
+{
+       if(!dvlp)return;
+
+       GPUCMD_AddSingleParam(0x000F02CB, 0x00000000);
+
+       int i;
+       for(i=0;i<dvlp->codeSize;i+=0x80)GPUCMD_Add(0x000F02CC, &dvlp->codeData[i], ((dvlp->codeSize-i)<0x80)?(dvlp->codeSize-i):0x80);
+
+       GPUCMD_AddSingleParam(0x000F02BF, 0x00000001);
+}
+
+void DVLP_SendOpDesc(DVLP_s* dvlp)
+{
+       if(!dvlp)return;
+
+       GPUCMD_AddSingleParam(0x000F02D5, 0x00000000);
+
+       GPUCMD_Add(0x000F02D6, dvlp->opcdescData, dvlp->opdescSize);
+}
+
+void DVLE_SendOutmap(DVLE_s* dvle)
+{
+       if(!dvle)return;
+
+       u32 param[0x8]={0x1F1F1F1F,0x1F1F1F1F,0x1F1F1F1F,0x1F1F1F1F,
+                                       0x1F1F1F1F,0x1F1F1F1F,0x1F1F1F1F,0x1F1F1F1F};
+
+       int i;
+       for(i=0;i<dvle->outTableSize;i++)
+       {
+               u32* out=&param[dvle->outTableData[i].regID];
+
+               //desc could include masking/swizzling info not currently taken into account
+               //also TODO : map out other output register values
+               switch(dvle->outTableData[i].type)
+               {
+                       case RESULT_POSITION: *out=0x03020100; break;
+                       case RESULT_COLOR: *out=0x0B0A0908; break;
+               }
+       }
+
+       GPUCMD_Add(0x800F0050, param, 0x00000007);
+}
+
+//TODO
+void SHDR_FreeDVLB(DVLB_s* dvlb)
+{
+       if(!dvlb)return;
+
+}