diff --git a/libctru/include/3ds/GPU.h b/libctru/include/3ds/GPU.h index f2e3fce..2d521e9 100644 --- a/libctru/include/3ds/GPU.h +++ b/libctru/include/3ds/GPU.h @@ -77,6 +77,13 @@ typedef enum{ #define GPU_TEVSOURCES(a,b,c) (((a))|((b)<<4)|((c)<<8)) #define GPU_TEVOPERANDS(a,b,c) (((a))|((b)<<4)|((c)<<8)) +typedef enum{ + GPU_TRIANGLES = 0x0000, + GPU_TRIANGLE_STRIP = 0x0100, + GPU_TRIANGLE_FAN = 0x0200, + GPU_UNKPRIM = 0x0300 // ? +}GPU_Primitive_t; + void GPU_SetUniform(u32 startreg, u32* data, u32 numreg); void GPU_SetViewport(u32* depthBuffer, u32* colorBuffer, u32 x, u32 y, u32 w, u32 h); void GPU_DepthRange(float nearVal, float farVal); @@ -87,4 +94,7 @@ void GPU_SetAttributeBuffers(u8 totalAttributes, u32* baseAddress, u64 attribute void GPU_SetTexture(u32* data, u16 width, u16 height, u32 param, GPU_TEXCOLOR colorType); void GPU_SetTexEnv(u8 id, u16 rgbSources, u16 alphaSources, u16 rgbOperands, u16 alphaOperands, GPU_COMBINEFUNC rgbCombine, GPU_COMBINEFUNC alphaCombine, u32 constantColor); +void GPU_DrawArray(GPU_Primitive_t primitive, u32 n); +void GPU_DrawElements(GPU_Primitive_t primitive, u32* indexArray, u32 n); + #endif diff --git a/libctru/include/3ds/gfx.h b/libctru/include/3ds/gfx.h index 27f941b..feeb493 100644 --- a/libctru/include/3ds/gfx.h +++ b/libctru/include/3ds/gfx.h @@ -24,6 +24,7 @@ void gfxExit(); void gfxSet3D(bool enable); void gfxFlushBuffers(); void gfxSwapBuffers(); +void gfxSwapBuffersGpu(); //helper stuff u8* gfxGetFramebuffer(gfxScreen_t screen, gfx3dSide_t side, u16* width, u16* height); diff --git a/libctru/source/gfx.c b/libctru/source/gfx.c index 0b5422d..6492033 100644 --- a/libctru/source/gfx.c +++ b/libctru/source/gfx.c @@ -10,6 +10,9 @@ GSP_FramebufferInfo topFramebufferInfo, bottomFramebufferInfo; +u8 gfxThreadID; +u8* gfxSharedMemory; + u8* gfxTopLeftFramebuffers[2]; u8* gfxTopRightFramebuffers[2]; u8* gfxBottomFramebuffers[2]; @@ -51,20 +54,31 @@ void gfxSetFramebufferInfo(gfxScreen_t screen, u8 id) } } +void gfxWriteFramebufferInfo(gfxScreen_t screen) +{ + u8* framebufferInfoHeader=gfxSharedMemory+0x200+gfxThreadID*0x80; + if(screen==GFX_BOTTOM)framebufferInfoHeader+=0x40; + GSP_FramebufferInfo* framebufferInfo=(GSP_FramebufferInfo*)&framebufferInfoHeader[0x4]; + framebufferInfoHeader[0x0]^=1; + framebufferInfo[framebufferInfoHeader[0x0]]=(screen==GFX_TOP)?(topFramebufferInfo):(bottomFramebufferInfo); + framebufferInfoHeader[0x1]=1; +} + extern u32 __gsp_heap_size; void gfxInit() { gspInit(); + gfxSharedMemory=(u8*)0x10002000; + GSPGPU_AcquireRight(NULL, 0x0); GSPGPU_SetLcdForceBlack(NULL, 0x0); //setup our gsp shared mem section - u8 threadID; svcCreateEvent(&gspEvent, 0x0); - GSPGPU_RegisterInterruptRelayQueue(NULL, gspEvent, 0x1, &gspSharedMemHandle, &threadID); - svcMapMemoryBlock(gspSharedMemHandle, 0x10002000, 0x3, 0x10000000); + GSPGPU_RegisterInterruptRelayQueue(NULL, gspEvent, 0x1, &gspSharedMemHandle, &gfxThreadID); + svcMapMemoryBlock(gspSharedMemHandle, (u32)gfxSharedMemory, 0x3, 0x10000000); //map GSP heap svcControlMemory((u32*)&gspHeap, 0x0, 0x0, __gsp_heap_size, 0x10003, 0x3); @@ -91,12 +105,12 @@ void gfxInit() gfxSetFramebufferInfo(GFX_BOTTOM, 0); //GSP shared mem : 0x2779F000 - gxCmdBuf=(u32*)(0x10002000+0x800+threadID*0x200); + gxCmdBuf=(u32*)(gfxSharedMemory+0x800+gfxThreadID*0x200); currentBuffer=0; // Initialize event handler and wait for VBlank - gspInitEventHandler(gspEvent, (vu8*)0x10002000, threadID); + gspInitEventHandler(gspEvent, (vu8*)gfxSharedMemory, gfxThreadID); gspWaitForVBlank(); } @@ -150,3 +164,12 @@ void gfxSwapBuffers() GSPGPU_SetBufferSwap(NULL, GFX_TOP, &topFramebufferInfo); GSPGPU_SetBufferSwap(NULL, GFX_BOTTOM, &bottomFramebufferInfo); } + +void gfxSwapBuffersGpu() +{ + currentBuffer^=1; + gfxSetFramebufferInfo(GFX_TOP, currentBuffer); + gfxSetFramebufferInfo(GFX_BOTTOM, currentBuffer); + gfxWriteFramebufferInfo(GFX_TOP); + gfxWriteFramebufferInfo(GFX_BOTTOM); +}