diff --git a/misc/ps1/ps1defs.h b/misc/ps1/ps1defs.h index 9b6ad947d..06726aadf 100644 --- a/misc/ps1/ps1defs.h +++ b/misc/ps1/ps1defs.h @@ -3,9 +3,11 @@ enum dma_chrc_flags { }; enum dma_chrc_CMD { - CHRC_FROM_RAM = (1 << 0), - CHRC_BEGIN = (1 << 24), - CHRC_MODE_SLICE = (1 << 9) + CHRC_FROM_RAM = (1 << 0), + CHRC_DIR_DECREMENT = (1 << 1), + CHRC_MODE_SLICE = (1 << 9), + CHRC_BEGIN_XFER = (1 << 24), + CHRC_NO_DREQ_WAIT = (1 << 28), }; enum gpu_status_flags { diff --git a/src/EnvRenderer.c b/src/EnvRenderer.c index e4b3a315c..17712821b 100644 --- a/src/EnvRenderer.c +++ b/src/EnvRenderer.c @@ -22,13 +22,6 @@ cc_bool EnvRenderer_Legacy, EnvRenderer_Minimal; -static float CalcBlendFactor(float x) { - float blend = -0.13f + 0.28f * ((float)Math_Log2(x) * 0.17329f); - if (blend < 0.0f) blend = 0.0f; - if (blend > 1.0f) blend = 1.0f; - return blend; -} - #define EnvRenderer_AxisSize() (EnvRenderer_Legacy ? 128 : 2048) /* Returns the number of vertices needed to subdivide a quad */ static int CalcNumVertices(int axis1Len, int axis2Len) { @@ -40,6 +33,21 @@ static int CalcNumVertices(int axis1Len, int axis2Len) { /*########################################################################################################################* *------------------------------------------------------------Fog----------------------------------------------------------* *#########################################################################################################################*/ +static PackedCol fog_color; + +static float CalcBlendFactor(float x) { + float blend = -0.13f + 0.28f * ((float)Math_Log2(x) * 0.17329f); + if (blend < 0.0f) blend = 0.0f; + if (blend > 1.0f) blend = 1.0f; + return blend; +} + +static CC_INLINE void UpdateFogBlend(void) { + float blend = CalcBlendFactor((float)Game_ViewDistance); + /* Blend fog and sky together */ + fog_color = PackedCol_Lerp(Env.FogCol, Env.SkyCol, blend); +} + static cc_bool CameraInsideBlock(BlockID block, IVec3* coords) { struct AABB blockBB; Vec3 pos; @@ -50,7 +58,7 @@ static cc_bool CameraInsideBlock(BlockID block, IVec3* coords) { return AABB_ContainsPoint(&blockBB, &Camera.CurrentPos); } -static void CalcFog(float* density, PackedCol* color) { +static PackedCol CalcFog(float* density) { IVec3 coords; BlockID block; float blend; @@ -60,12 +68,10 @@ static void CalcFog(float* density, PackedCol* color) { if (Blocks.FogDensity[block] && CameraInsideBlock(block, &coords)) { *density = Blocks.FogDensity[block]; - *color = Blocks.FogCol[block]; + return Blocks.FogCol[block]; } else { *density = 0.0f; - /* Blend fog and sky together */ - blend = CalcBlendFactor((float)Game_ViewDistance); - *color = PackedCol_Lerp(Env.FogCol, Env.SkyCol, blend); + return fog_color; } } @@ -117,7 +123,7 @@ void EnvRenderer_UpdateFog(void) { PackedCol fogColor; if (!World.Loaded) return; - CalcFog(&fogDensity, &fogColor); + fogColor = CalcFog(&fogDensity); Gfx_ClearColor(fogColor); if (EnvRenderer_Minimal) { @@ -864,6 +870,7 @@ static void OnContextLost(void* obj) { static void UpdateAll(void) { DeleteStaticVbs(); + UpdateFogBlend(); EnvRenderer_UpdateFog(); DeleteWeatherVB(); @@ -918,8 +925,10 @@ static void OnEnvVariableChanged(void* obj, int envVar) { } else if (envVar == ENV_VAR_SHADOW_COLOR) { DeleteSidesVB(); } else if (envVar == ENV_VAR_SKY_COLOR) { + UpdateFogBlend(); DeleteSkyVB(); } else if (envVar == ENV_VAR_FOG_COLOR) { + UpdateFogBlend(); EnvRenderer_UpdateFog(); } else if (envVar == ENV_VAR_CLOUDS_COLOR) { DeleteCloudsVB(); diff --git a/src/Graphics_PS1.c b/src/Graphics_PS1.c index 829463afb..e1aee2cd5 100644 --- a/src/Graphics_PS1.c +++ b/src/Graphics_PS1.c @@ -26,9 +26,11 @@ // crashes due to too many primitives being drawn, increase this value. #define BUFFER_LENGTH 32768 +#define wait_while(cond) while (cond) { __asm__ volatile(""); } + typedef struct { - DISPENV disp_env; DRAWENV draw_env; + uint32_t fb_pos; uint32_t ot[OT_LENGTH]; //uint32_t oct[OCT_LENGTH]; @@ -43,24 +45,37 @@ static RenderBuffer* buffer; static void* lastPoly; static cc_bool cullingEnabled, noMemWarned; +// Resets ordering table to reverse default order +// TODO move wait until later +static void ResetOTableR(uint32_t* ot) { + DMA_MADR(DMA_OTC) = (uint32_t)&ot[OT_LENGTH - 1]; + DMA_BCR(DMA_OTC) = OT_LENGTH; + DMA_CHCR(DMA_OTC) = CHRC_NO_DREQ_WAIT | CHRC_BEGIN_XFER | CHRC_DIR_DECREMENT; + + wait_while(DMA_CHCR(DMA_OTC) & CHRC_STATUS_BUSY); +} + static void OnBufferUpdated(void) { buffer = &buffers[active_buffer]; next_packet = buffer->buffer; next_packet_end = next_packet + BUFFER_LENGTH; - ClearOTagR(buffer->ot, OT_LENGTH); - //ClearOTagR(buffer->oct, OCT_LENGTH); + + ResetOTableR(buffer->ot); +} + +static void InitContext(RenderBuffer* buffer, int x, int y, int w, int h) { + SetDefDrawEnv(&buffer->draw_env, x, y, w, h); + buffer->draw_env.isbg = 1; + + buffer->fb_pos = (x & 0x3ff) | ((y & 0x1ff) << 10); } static void SetupContexts(int w, int h, int r, int g, int b) { - SetDefDrawEnv(&buffers[0].draw_env, 0, 0, w, h); - SetDefDispEnv(&buffers[0].disp_env, 0, 0, w, h); - SetDefDrawEnv(&buffers[1].draw_env, 0, h, w, h); - SetDefDispEnv(&buffers[1].disp_env, 0, h, w, h); + InitContext(&buffers[0], 0, 0, w, h); + InitContext(&buffers[1], 0, h, w, h); setRGB0(&buffers[0].draw_env, r, g, b); setRGB0(&buffers[1].draw_env, r, g, b); - buffers[0].draw_env.isbg = 1; - buffers[1].draw_env.isbg = 1; /* buffers[0].draw_env.tw.w = 16; buffers[0].draw_env.tw.h = 16; @@ -110,8 +125,6 @@ void Gfx_Free(void) { /*########################################################################################################################* *------------------------------------------------------VRAM transfers-----------------------------------------------------* *#########################################################################################################################*/ -#define wait_while(cond) while (cond) { __asm__ volatile(""); } - static void WaitUntilFinished(void) { // Wait until DMA to GPU has finished wait_while((DMA_CHCR(DMA_GPU) & CHRC_STATUS_BUSY)); @@ -147,13 +160,14 @@ void Gfx_TransferToVRAM(int x, int y, int w, int h, void* pixels) { GPU_GP1 = GP1_CMD_DMA_MODE | GP1_DMA_CPU_TO_GP0; // Wait until any prior DMA to GPU has finished - wait_while((DMA_CHCR(DMA_GPU) & CHRC_STATUS_BUSY)); + wait_while((DMA_CHCR(DMA_GPU) & CHRC_STATUS_BUSY)) + // Wait until GPU is ready to receive DMA data wait_while(!(GPU_GP1 & GPU_STATUS_DMA_RECV_READY)); DMA_MADR(DMA_GPU) = (uint32_t)pixels; DMA_BCR(DMA_GPU) = block_size | (num_blocks << 16); - DMA_CHCR(DMA_GPU) = CHRC_BEGIN | CHRC_MODE_SLICE | CHRC_FROM_RAM; + DMA_CHCR(DMA_GPU) = CHRC_BEGIN_XFER | CHRC_MODE_SLICE | CHRC_FROM_RAM; WaitUntilFinished(); } @@ -911,9 +925,11 @@ void Gfx_EndFrame(void) { RenderBuffer* draw_buffer = &buffers[active_buffer]; RenderBuffer* disp_buffer = &buffers[active_buffer ^ 1]; - PutDispEnv(&disp_buffer->disp_env); + // Use previous finished frame as display framebuffer + GPU_GP1 = GP1_CMD_DISPLAY_ADDRESS | disp_buffer->fb_pos; + + // Start sending commands to GPU to draw this frame DrawOTagEnv(&draw_buffer->ot[OT_LENGTH - 1], &draw_buffer->draw_env); - //DrawOTagEnv(&draw_buffer->oct[OCT_LENGTH - 1], &draw_buffer->draw_env); active_buffer ^= 1; OnBufferUpdated(); @@ -942,20 +958,8 @@ void Gfx_SetViewport(int x, int y, int w, int h) buffers[1].draw_env.clip.y = y; buffers[1].draw_env.clip.w = w; buffers[1].draw_env.clip.h = h; - - buffers[0].disp_env.disp.x = x; - buffers[0].disp_env.disp.y = y; - buffers[0].disp_env.disp.w = w; - buffers[0].disp_env.disp.h = h; - - buffers[1].disp_env.disp.x = x; - buffers[1].disp_env.disp.y = y; - buffers[1].disp_env.disp.w = w; - buffers[1].disp_env.disp.h = h; //SetDefDrawEnv(&buffers[0].draw_env, x, y, w, h); - //SetDefDispEnv(&buffers[0].disp_env, x, y, w, h); //SetDefDrawEnv(&buffers[1].draw_env, x, y+h, w, h); - //SetDefDispEnv(&buffers[1].disp_env, x, y+h, w, h); } void Gfx_SetScissor (int x, int y, int w, int h) { } diff --git a/src/Window_PS1.c b/src/Window_PS1.c index c71ed823b..e97fee398 100644 --- a/src/Window_PS1.c +++ b/src/Window_PS1.c @@ -66,6 +66,8 @@ static void InitScreen(void) { GPU_GP1 = GP1_CMD_VERTICAL_RANGE | ver_range; GPU_GP1 = GP1_CMD_VIDEO_MODE | mode; GPU_GP1 = GP1_CMD_DISPLAY_ACTIVE | GP1_DISPLAY_ENABLED; + + GPU_GP1 = GP1_CMD_DMA_MODE | GP1_DMA_CPU_TO_GP0; } // Resets screen to an initial grey colour @@ -91,7 +93,9 @@ void Window_Create2D(int width, int height) { void Window_Create3D(int width, int height) { ResetGraph(0); - launcherMode = false; + launcherMode = false; + + InitScreen(); } void Window_Destroy(void) { }