diff --git a/doc/plugin-dev.md b/doc/plugin-dev.md index 5de0d08f8..6d6d1f4d8 100644 --- a/doc/plugin-dev.md +++ b/doc/plugin-dev.md @@ -8,7 +8,7 @@ To find the functions and variables available for use in plugins, look for `CC_A You need to download and install either Visual Studio, MinGW, or GCC/Clang. -*Note: MinGW/GCC/Clang are relatively small, while Visual Studio is gigabytes in size. +*Note: MinGW/GCC/Clang are relatively small, while Visual Studio is gigabytes in size. If you're just trying to compile a plugin on Windows you might want to use MinGW. See main readme.* I assume your directory is structured like this: diff --git a/src/3ds/Graphics_3DS.c b/src/3ds/Graphics_3DS.c index 78c8df995..7854f8098 100644 --- a/src/3ds/Graphics_3DS.c +++ b/src/3ds/Graphics_3DS.c @@ -127,6 +127,22 @@ static void AptEventHook(APT_HookType hookType, void* param) { } } +static void SetInitialStates(void) { + extern void C3Di_UpdateContext(void); + C3Di_UpdateContext(); + + static C3D_FVec _1_div_255 = { .x = 1/255.0f, .y = 1/255.0f, .z = 1/255.0f, .w = 1/255.0f }; + pica_upload_vec4_constant(CONST_255, &_1_div_255); + + // NOTE: GPUREG_VERTEX_OFFSET only works when drawing non-indexed arrays + GPUCMD_AddWrite(GPUREG_VERTEX_OFFSET, 0); + + // https://github.com/devkitPro/citro3d/issues/47 + // "Fyi the permutation specifies the order in which the attributes are stored in the buffer, LSB first. So 0x210 indicates attributes 0, 1 & 2." + // This just maps array attrib 0 = vertex attrib 0, array attrib 1 = vertex attrib 1, etc + pica_set_attrib_array0_mapping(0x210); +} + static void InitCitro3D(void) { C3D_Init(C3D_DEFAULT_CMDBUF_SIZE * 4); aptHook(&hookCookie, AptEventHook, NULL); @@ -154,6 +170,7 @@ static void InitCitro3D(void) { AllocShaders(); GSP_setup(); + SetInitialStates(); } static GfxResourceID white_square; @@ -551,20 +568,6 @@ void Gfx_BeginFrame(void) { C3D_FrameBegin(0); topTarget = &topTargetLeft; C3D_FrameDrawOn(topTarget); - - extern void C3Di_UpdateContext(void); - C3Di_UpdateContext(); - - static C3D_FVec _1_div_255 = { .x = 1/255.0f, .y = 1/255.0f, .z = 1/255.0f, .w = 1/255.0f }; - pica_upload_vec4_constant(CONST_255, &_1_div_255); - - // NOTE: GPUREG_VERTEX_OFFSET only works when drawing non-indexed arrays - GPUCMD_AddWrite(GPUREG_VERTEX_OFFSET, 0); - - // https://github.com/devkitPro/citro3d/issues/47 - // "Fyi the permutation specifies the order in which the attributes are stored in the buffer, LSB first. So 0x210 indicates attributes 0, 1 & 2." - // This just maps array attrib 0 = vertex attrib 0, array attrib 1 = vertex attrib 1, etc - pica_set_attrib_array0_mapping(0x210); } void Gfx_ClearBuffers(GfxBuffers buffers) { @@ -577,7 +580,7 @@ void Gfx_ClearBuffers(GfxBuffers buffers) { void Gfx_EndFrame(void) { gfxSet3D(rendering3D); - C3D_FrameEnd(0); + C3D_FrameFinish(0); //gfxFlushBuffers(); //gfxSwapBuffers(); @@ -587,6 +590,8 @@ void Gfx_EndFrame(void) { // wait for vblank for both screens if (gfx_vsync) GSP_wait_for_full_vblank(); + + C3D_FrameEnd(0); } void Gfx_OnWindowResize(void) { } diff --git a/third_party/citro3d.c b/third_party/citro3d.c index 64513fe52..90bf93b31 100644 --- a/third_party/citro3d.c +++ b/third_party/citro3d.c @@ -216,7 +216,6 @@ enum static bool C3D_FrameBegin(u8 flags); static bool C3D_FrameDrawOn(C3D_RenderTarget* target); -static void C3D_FrameEnd(u8 flags); static void C3D_RenderTargetSetOutput(C3D_RenderTarget* target, gfxScreen_t screen, gfx3dSide_t side, u32 transferFlags); @@ -788,21 +787,12 @@ static void C3D_ImmDrawEnd(void) static C3D_RenderTarget *linkedTarget[3]; -static bool inFrame, inSafeTransfer; +static bool inFrame; static bool swapPending, isTopStereo; static void onQueueFinish(gxCmdQueue_s* queue) { - if (inSafeTransfer) - { - inSafeTransfer = false; - if (inFrame) - { - gxCmdQueueStop(queue); - gxCmdQueueClear(queue); - } - } - else if (swapPending) + if (swapPending) { gfxScreenSwapBuffers(GFX_TOP, isTopStereo); gfxScreenSwapBuffers(GFX_BOTTOM, false); @@ -843,14 +833,7 @@ static void C3Di_RenderQueueWaitDone(void) static bool C3D_FrameBegin(u8 flags) { - C3D_Context* ctx = C3Di_GetContext(); - if (inFrame) return false; - - if (!C3Di_WaitAndClearQueue((flags & C3D_FRAME_NONBLOCK) ? 0 : -1)) - return false; - inFrame = true; - GPUCMD_SetBuffer(ctx->cmdBuf, ctx->cmdBufSize, 0); return true; } @@ -864,7 +847,7 @@ static bool C3D_FrameDrawOn(C3D_RenderTarget* target) return true; } -static void C3D_FrameEnd(u8 flags) +static void C3D_FrameFinish(u8 flags) { C3D_Context* ctx = C3Di_GetContext(); if (!inFrame) return; @@ -903,6 +886,14 @@ static void C3D_FrameEnd(u8 flags) gxCmdQueueRun(&ctx->gxQueue); } +static void C3D_FrameEnd(u8 flags) +{ + C3D_Context* ctx = C3Di_GetContext(); + + C3Di_WaitAndClearQueue((flags & C3D_FRAME_NONBLOCK) ? 0 : -1); + GPUCMD_SetBuffer(ctx->cmdBuf, ctx->cmdBufSize, 0); +} + static void C3D_RenderTargetInit(C3D_RenderTarget* target, int width, int height) { memset(target, 0, sizeof(C3D_RenderTarget)); @@ -952,6 +943,11 @@ static void C3D_RenderTargetSetOutput(C3D_RenderTarget* target, gfxScreen_t scre C3Di_WaitAndClearQueue(-1); } linkedTarget[id] = target; + + target->linked = true; + target->transferFlags = transferFlags; + target->screen = screen; + target->side = side; } @@ -1019,9 +1015,6 @@ static bool C3D_Init(size_t cmdBufSize) int i; C3D_Context* ctx = C3Di_GetContext(); - if (ctx->flags & C3DiF_Active) - return false; - cmdBufSize = (cmdBufSize + 0xF) &~ 0xF; // 0x10-byte align ctx->cmdBufSize = cmdBufSize/4; ctx->cmdBuf = (u32*)linearAlloc(cmdBufSize); @@ -1056,6 +1049,7 @@ static bool C3D_Init(size_t cmdBufSize) C3Di_RenderQueueInit(); + GPUCMD_SetBuffer(ctx->cmdBuf, ctx->cmdBufSize, 0); return true; }