mirror of
https://gitee.com/anod/open_agb_firm.git
synced 2025-05-06 05:44:11 +08:00
分析代码
This commit is contained in:
parent
4dea86fb47
commit
4471e9ee53
199
tools/cmdlist/from/main.c
Normal file
199
tools/cmdlist/from/main.c
Normal file
@ -0,0 +1,199 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <3ds.h>
|
||||
#include <citro3d.h>
|
||||
#include <string.h>
|
||||
#include "vshader_shbin.h"
|
||||
|
||||
|
||||
#define CLEAR_COLOR (0x68B0D8FF)
|
||||
|
||||
#define DISPLAY_TRANSFER_FLAGS \
|
||||
(GX_TRANSFER_FLIP_VERT(0) | GX_TRANSFER_OUT_TILED(0) | GX_TRANSFER_RAW_COPY(0) | \
|
||||
GX_TRANSFER_IN_FORMAT(GX_TRANSFER_FMT_RGB8) | GX_TRANSFER_OUT_FORMAT(GX_TRANSFER_FMT_RGB8) | \
|
||||
GX_TRANSFER_SCALING(GX_TRANSFER_SCALE_NO))
|
||||
|
||||
|
||||
static DVLB_s* vshader_dvlb;
|
||||
static shaderProgram_s program;
|
||||
static int uLoc_projection;
|
||||
static C3D_Mtx projection;
|
||||
static C3D_Tex maintex;
|
||||
|
||||
|
||||
|
||||
static void sceneInit(void)
|
||||
{
|
||||
// Load the vertex shader, create a shader program and bind it
|
||||
vshader_dvlb = DVLB_ParseFile((u32*)vshader_shbin, vshader_shbin_size);
|
||||
shaderProgramInit(&program);
|
||||
shaderProgramSetVsh(&program, &vshader_dvlb->DVLE[0]);
|
||||
C3D_BindProgram(&program);
|
||||
|
||||
// Get the location of the uniforms
|
||||
uLoc_projection = shaderInstanceGetUniformLocation(program.vertexShader, "projection");
|
||||
|
||||
// Configure attributes for use with the vertex shader
|
||||
// Attribute format and element count are ignored in immediate mode
|
||||
C3D_AttrInfo* attrInfo = C3D_GetAttrInfo();
|
||||
AttrInfo_Init(attrInfo);
|
||||
AttrInfo_AddLoader(attrInfo, 0, GPU_FLOAT, 3); // v0=position xyz
|
||||
AttrInfo_AddLoader(attrInfo, 1, GPU_FLOAT, 2); // v1=texcoord xy
|
||||
|
||||
// Compute the projection matrix
|
||||
Mtx_OrthoTilt(&projection, 0.0, 400.0, 0.0, 240.0, 0.0, 1.0, true);
|
||||
|
||||
FILE *f = fopen("sdmc:/rgb_gba_test.bin", "rb");
|
||||
u8 *const data = linearAlloc(256 * 256 * 3);
|
||||
u8 *dst = data;
|
||||
for(u32 i = 0; i < 160; i++)
|
||||
{
|
||||
fread(dst, 240 * 3, 1, f);
|
||||
dst += 256 * 3;
|
||||
}
|
||||
fclose(f);
|
||||
GSPGPU_FlushDataCache(data, 256 * 256 * 3);
|
||||
|
||||
C3D_TexInit(&maintex, 256, 256, GPU_RGB8);
|
||||
const u32 flags = (GX_TRANSFER_FLIP_VERT(0) | GX_TRANSFER_OUT_TILED(1) | GX_TRANSFER_RAW_COPY(0) |
|
||||
GX_TRANSFER_IN_FORMAT(GX_TRANSFER_FMT_RGB8) | GX_TRANSFER_OUT_FORMAT(GX_TRANSFER_FMT_RGB8) |
|
||||
GX_TRANSFER_SCALING(GX_TRANSFER_SCALE_NO));
|
||||
C3D_SyncDisplayTransfer((u32*)data, GX_BUFFER_DIM(256, 256), (u32*)maintex.data, GX_BUFFER_DIM(256, 256), flags);
|
||||
linearFree(data);
|
||||
|
||||
C3D_TexSetFilter(&maintex, GPU_LINEAR, GPU_NEAREST);
|
||||
//C3D_TexSetWrap(&maintex, GPU_CLAMP_TO_EDGE, GPU_CLAMP_TO_EDGE);
|
||||
C3D_TexBind(0, &maintex);
|
||||
|
||||
// Configure the first fragment shading substage to just pass through the vertex color
|
||||
// See https://www.opengl.org/sdk/docs/man2/xhtml/glTexEnv.xml for more insight
|
||||
C3D_TexEnv* env = C3D_GetTexEnv(0);
|
||||
C3D_TexEnvInit(env);
|
||||
C3D_TexEnvSrc(env, C3D_Both, GPU_TEXTURE0, 0, 0);
|
||||
C3D_TexEnvFunc(env, C3D_Both, GPU_REPLACE);
|
||||
//C3D_TexEnvScale(env, C3D_Both, GPU_TEVSCALE_2);
|
||||
|
||||
C3D_TexEnv* env1 = C3D_GetTexEnv(1);
|
||||
C3D_TexEnvInit(env1);
|
||||
C3D_TexEnvSrc(env1, C3D_Both, GPU_PREVIOUS, GPU_PREVIOUS, 0);
|
||||
C3D_TexEnvFunc(env1, C3D_Both, GPU_MODULATE);
|
||||
}
|
||||
|
||||
static void sceneRender(void)
|
||||
{
|
||||
// Update the uniforms
|
||||
C3D_FVUnifMtx4x4(GPU_VERTEX_SHADER, uLoc_projection, &projection);
|
||||
// with scake=1.5, then xShift=20
|
||||
//
|
||||
// with scake=1.0, then xShift=80, the reason is 256 is change to 512
|
||||
// 80 0 0.5 1
|
||||
// 0 0.6875 0 0 --> 0.6875 = 1-80/256
|
||||
// 320 0 0.5 1
|
||||
// 0.46875 0.6875 0 0 --> 120/256 1-80/256
|
||||
// 80 160 0.5 1
|
||||
// 0 1 0 0
|
||||
// 320 160 0.5 1
|
||||
// 0.46875 1 0 0
|
||||
// Draw a textured quad directly
|
||||
C3D_ImmDrawBegin(GPU_TRIANGLE_STRIP);
|
||||
const float scale = 1.5f;
|
||||
const float xShift = (400.0f - (240.0f * scale)) / 2.0f;
|
||||
|
||||
// Bottom left corner.
|
||||
C3D_ImmSendAttrib(xShift, 0.0f, 0.5f, 1.0f); // v0=position xyz
|
||||
C3D_ImmSendAttrib(0.0f, 1.0f - (160.0f / 256.0f), 0.0f, 0.0f); // v1=texcoord xy
|
||||
|
||||
// Bottom right corner.
|
||||
C3D_ImmSendAttrib(240.0f * scale + xShift, 0.0f, 0.5f, 1.0f);
|
||||
C3D_ImmSendAttrib(1.0f * 240.0f / 256.0f, 1.0f - (160.0f / 256.0f), 0.0f, 0.0f);
|
||||
|
||||
// Top left corner.
|
||||
C3D_ImmSendAttrib(xShift, 160.0f * scale, 0.5f, 1.0f);
|
||||
C3D_ImmSendAttrib(0.0f, 1.0f, 0.0f, 0.0f);
|
||||
|
||||
// Top right corner.
|
||||
C3D_ImmSendAttrib(240.0f * scale + xShift, 160.0f * scale, 0.5f, 1.0f);
|
||||
C3D_ImmSendAttrib(1.0f * 240.0f / 256.0f, 1.0f, 0.0f, 0.0f);
|
||||
C3D_ImmDrawEnd();
|
||||
}
|
||||
|
||||
static void sceneExit(void)
|
||||
{
|
||||
// Free the shader program
|
||||
shaderProgramFree(&program);
|
||||
DVLB_Free(vshader_dvlb);
|
||||
C3D_TexDelete(&maintex);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
// Initialize graphics
|
||||
gfxInit(GSP_BGR8_OES, GSP_RGB565_OES, false);
|
||||
C3D_Init(C3D_DEFAULT_CMDBUF_SIZE);
|
||||
|
||||
// Initialize the render target
|
||||
C3D_RenderTarget* target = C3D_RenderTargetCreate(240, 400, GPU_RB_RGB8, GPU_RB_DEPTH24_STENCIL8);
|
||||
C3D_StencilTest(false, GPU_ALWAYS, 0, 0, 0);
|
||||
C3D_EarlyDepthTest(false, GPU_EARLYDEPTH_GEQUAL, 0);
|
||||
C3D_DepthTest(false, GPU_ALWAYS, GPU_WRITE_COLOR);
|
||||
C3D_AlphaTest(false, GPU_ALWAYS, 0);
|
||||
C3D_RenderTargetSetOutput(target, GFX_TOP, GFX_LEFT, DISPLAY_TRANSFER_FLAGS);
|
||||
|
||||
// Initialize the scene
|
||||
sceneInit();
|
||||
|
||||
// Main loop
|
||||
while (aptMainLoop())
|
||||
{
|
||||
hidScanInput();
|
||||
|
||||
// Respond to user input
|
||||
u32 kDown = hidKeysDown();
|
||||
if (kDown & KEY_START)
|
||||
break; // break in order to return to hbmenu
|
||||
|
||||
// Render the scene
|
||||
C3D_FrameBegin(C3D_FRAME_SYNCDRAW);
|
||||
C3D_RenderTargetClear(target, C3D_CLEAR_ALL, CLEAR_COLOR, 0);
|
||||
C3D_FrameDrawOn(target);
|
||||
sceneRender();
|
||||
C3D_FrameEnd(0);
|
||||
}
|
||||
|
||||
// Deinitialize the scene
|
||||
sceneExit();
|
||||
|
||||
C3D_RenderTargetDelete(target);
|
||||
|
||||
// Deinitialize graphics
|
||||
C3D_Fini();
|
||||
gfxExit();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// -Wl,-wrap=GX_ProcessCommandList
|
||||
Result __wrap_GX_ProcessCommandList(u32* buf0a, u32 buf0s, u8 flags)
|
||||
{
|
||||
static u32 dumped = 0;
|
||||
|
||||
if(dumped == 0)
|
||||
{
|
||||
dumped++;
|
||||
|
||||
FILE *f = fopen("sdmc:/first_cmdlist.bin", "wb");
|
||||
fwrite(buf0a, buf0s, 1, f);
|
||||
fclose(f);
|
||||
}
|
||||
else if(dumped == 1)
|
||||
{
|
||||
dumped++;
|
||||
|
||||
FILE *f = fopen("sdmc:/second_cmdlist.bin", "wb");
|
||||
fwrite(buf0a, buf0s, 1, f);
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
return __real_GX_ProcessCommandList(buf0a, buf0s, flags);
|
||||
}
|
35
tools/cmdlist/from/vshader.v.pica
Normal file
35
tools/cmdlist/from/vshader.v.pica
Normal file
@ -0,0 +1,35 @@
|
||||
; Example PICA200 vertex shader
|
||||
|
||||
; Uniforms
|
||||
.fvec projection[4]
|
||||
|
||||
; Constants
|
||||
.constf myconst(0.0, 1.0, -1.0, 0.5)
|
||||
.alias zeros myconst.xxxx ; Vector full of zeros
|
||||
.alias ones myconst.yyyy ; Vector full of ones
|
||||
|
||||
; Outputs
|
||||
.out outpos position
|
||||
.out outtc0 texcoord0
|
||||
|
||||
; Inputs (defined as aliases for convenience)
|
||||
.alias inpos v0
|
||||
.alias intex v1
|
||||
|
||||
.proc main
|
||||
; Force the w component of inpos to be 1.0
|
||||
mov r0.xyz, inpos
|
||||
mov r0.w, ones
|
||||
|
||||
; outpos = projectionMatrix * inpos
|
||||
dp4 outpos.x, projection[0], r0
|
||||
dp4 outpos.y, projection[1], r0
|
||||
dp4 outpos.z, projection[2], r0
|
||||
dp4 outpos.w, projection[3], r0
|
||||
|
||||
; outtc0 = intex
|
||||
mov outtc0, intex
|
||||
|
||||
; We're finished
|
||||
end
|
||||
.end
|
28
tools/cmdlist/parse.js
Normal file
28
tools/cmdlist/parse.js
Normal file
@ -0,0 +1,28 @@
|
||||
function *read_one_command( words )
|
||||
{
|
||||
let pos = 0;
|
||||
while( pos < words.length )
|
||||
{
|
||||
let header = words[pos+1];
|
||||
let [reg, size] = read_header(header);
|
||||
let param = [words[0]]
|
||||
|
||||
let idx = pos+2;
|
||||
while( size-- > 0 ) param.push( words[idx++] );
|
||||
pos += 2 + ( (size%2) ? size+1 : size );
|
||||
yield {reg, param}
|
||||
}
|
||||
}
|
||||
|
||||
function *parse( bytes )
|
||||
{
|
||||
const words = new Uint32Array( bytes );
|
||||
let output = [];
|
||||
while( 1 ){
|
||||
let command = yield read_one_command( words );
|
||||
if( command == null ) break;
|
||||
else output.push( command );
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user