diff options
-rw-r--r-- | sword2/build_display.cpp | 17 | ||||
-rw-r--r-- | sword2/driver/d_draw.cpp | 10 | ||||
-rw-r--r-- | sword2/driver/rdwin.cpp | 12 | ||||
-rw-r--r-- | sword2/driver/rdwin.h | 1 | ||||
-rw-r--r-- | sword2/driver/render.cpp | 52 | ||||
-rw-r--r-- | sword2/driver/sprite.cpp | 4 |
6 files changed, 67 insertions, 29 deletions
diff --git a/sword2/build_display.cpp b/sword2/build_display.cpp index d4f9bc54c2..08783c5874 100644 --- a/sword2/build_display.cpp +++ b/sword2/build_display.cpp @@ -157,8 +157,10 @@ void Build_display(void) //Tony21Sept96 //---------------------------------------------------- // clear the back buffer, before building up the new screen // from the back forwards - - EraseBackBuffer(); + + // FIXME: I'm not convinced that this is needed. Isn't + // the whole screen redrawn each time? + // EraseBackBuffer(); //---------------------------------------------------- // first background parallax + related anims @@ -253,7 +255,8 @@ void Build_display(void) //Tony21Sept96 //---------------------------------------------------- // ready - blit to screen - CopyScreenBuffer(); + if (ServiceWindows() == RDERR_APPCLOSED) // if the game is being shut down, drop out + break; //---------------------------------------------------- // update our fps reading @@ -262,7 +265,7 @@ void Build_display(void) //Tony21Sept96 if (SVM_timeGetTime() > cycleTime) { fps = frameCount; - debug(2, "FPS: %d", fps); + debug(0, "FPS: %d", fps); frameCount = 0; cycleTime = SVM_timeGetTime()+1000; } @@ -270,17 +273,11 @@ void Build_display(void) //Tony21Sept96 // check if we've got time to render the screen again this cycle // (so drivers can smooth out the scrolling in between normal game cycles) - // FIXME: If we have already reached the scroll target, - // we should sleep for the rest of the render cycle. - EndRenderCycle(&end); if (end) // if we haven't got time to render again this cycle, drop out of 'render cycle' while-loop break; - if (ServiceWindows() == RDERR_APPCLOSED) // if the game is being shut down, drop out - break; - //---------------------------------------------------- } // END OF RENDER CYCLE diff --git a/sword2/driver/d_draw.cpp b/sword2/driver/d_draw.cpp index 573278ae27..d91eacb503 100644 --- a/sword2/driver/d_draw.cpp +++ b/sword2/driver/d_draw.cpp @@ -24,6 +24,7 @@ #include "_mouse.h" #include "d_draw.h" #include "palette.h" +#include "render.h" #define SCREENYOFFSET 40 #define MILLISECSPERCYCLE 83 @@ -205,14 +206,7 @@ int32 WaitForVbl(void) } int32 EraseBackBuffer( void ) { - // Since the entire screen is redrawn each time, there probably isn't - // any need to actually clear the back buffer. - // - // At the very least, since the menu code now is solely responsible - // for its own parts of the screen, we'd only need to clear the - // picture area. - - // memset(lpBackBuffer + MENUDEEP * screnWide, 0, screenWide * (screenDeep - 2 * MENUDEEP)); + memset(lpBackBuffer + MENUDEEP * screenWide, 0, screenWide * RENDERDEEP); return RD_OK; } diff --git a/sword2/driver/rdwin.cpp b/sword2/driver/rdwin.cpp index 83ff62f970..299721c9ce 100644 --- a/sword2/driver/rdwin.cpp +++ b/sword2/driver/rdwin.cpp @@ -537,7 +537,11 @@ int32 CloseAppWindow(void) } +static bool _needRedraw = false; +void SetNeedRedraw() { + _needRedraw = true; +} int32 ServiceWindows(void) @@ -548,8 +552,14 @@ int32 ServiceWindows(void) // FIXME: We re-render the entire picture area of the screen for each // frame, which is pretty horrible. - g_system->copy_rect(lpBackBuffer + MENUDEEP * screenWide, screenWide, 0, MENUDEEP, screenWide, screenDeep - 2 * MENUDEEP); + if (_needRedraw) { + g_system->copy_rect(lpBackBuffer + MENUDEEP * screenWide, screenWide, 0, MENUDEEP, screenWide, screenDeep - 2 * MENUDEEP); + _needRedraw = false; + } + + // We still need to update because of fades, menu animations, etc. g_system->update_screen(); + // warning("stub ServiceWindows"); // too noisy /* MSG msg; diff --git a/sword2/driver/rdwin.h b/sword2/driver/rdwin.h index e176f9a40b..271b313ad7 100644 --- a/sword2/driver/rdwin.h +++ b/sword2/driver/rdwin.h @@ -52,5 +52,6 @@ extern RECT rcWindow; // size of the current window. extern void Message(LPSTR fmt, ...); */ +extern void SetNeedRedraw(void); #endif diff --git a/sword2/driver/render.cpp b/sword2/driver/render.cpp index 5b05d4958f..7997d8e3dd 100644 --- a/sword2/driver/render.cpp +++ b/sword2/driver/render.cpp @@ -258,7 +258,6 @@ int32 renderCountIndex = 0; int32 renderTimeLog[RENDERAVERAGETOTAL] = {60, 60, 60, 60}; int32 initialTime; int32 startTime; -int32 originTime; int32 totalTime; int32 renderAverageTime = 60; int32 framesPerGameCycle; @@ -331,6 +330,7 @@ void BlitBlockSurface(BlockSurface *s, ScummVM::Rect *r, ScummVM::Rect *clip_rec } // UploadRect(r); + SetNeedRedraw(); } #define SCALE_MAXWIDTH 512 @@ -987,10 +987,11 @@ void LogMe(int32 in) } */ +// Uncomment this when benchmarking the drawing routines. +#define LIMIT_FRAME_RATE int32 InitialiseRenderCycle(void) { initialTime = SVM_timeGetTime(); - originTime = initialTime; totalTime = initialTime + MILLISECSPERCYCLE; return RD_OK; } @@ -1018,13 +1019,27 @@ int32 StartRenderCycle(void) { } +// FIXME: Move this to some better place? + +void sleepUntil(int32 time) { + while ((int32) SVM_timeGetTime() < time) { + g_sword2->parseEvents(); + + // Make sure menu animations and fades don't suffer + ProcessMenu(); + if (ServiceWindows() == RDERR_APPCLOSED) + break; + + g_system->delay_msecs(10); + } +} int32 EndRenderCycle(BOOL *end) { int32 time; time = SVM_timeGetTime(); renderTimeLog[renderCountIndex] = time - startTime; - startTime += renderTimeLog[renderCountIndex]; + startTime = time; renderAverageTime = (renderTimeLog[0] + renderTimeLog[1] + renderTimeLog[2] + renderTimeLog[3]) >> 2; framesPerGameCycle += 1; @@ -1037,13 +1052,31 @@ int32 EndRenderCycle(BOOL *end) { InitialiseRenderCycle(); } else if (startTime + renderAverageTime >= totalTime) { *end = TRUE; - originTime = totalTime; totalTime += MILLISECSPERCYCLE; initialTime = time; +#ifdef LIMIT_FRAME_RATE + } else if (scrollxTarget == scrollx && scrollyTarget == scrolly) { + // If we have already reached the scroll target sleep for the + // rest of the render cycle. + *end = TRUE; + sleepUntil(totalTime); + initialTime = SVM_timeGetTime(); + totalTime += MILLISECSPERCYCLE; +#endif } else { *end = FALSE; - scrollx = (int16) (scrollxOld + ((scrollxTarget - scrollxOld) * (startTime - initialTime + renderAverageTime)) / (totalTime - initialTime)); - scrolly = (int16) (scrollyOld + ((scrollyTarget - scrollyOld) * (startTime - initialTime + renderAverageTime)) / (totalTime - initialTime)); + + // This is an attempt to ensure that we always reach the scroll + // target. Otherwise the game frequently tries to pump out new + // interpolation frames without ever getting anywhere. + + if (ABS(scrollx - scrollxTarget) <= 1 && ABS(scrolly - scrollyTarget) <= 1) { + scrollx = scrollxTarget; + scrolly = scrollyTarget; + } else { + scrollx = (int16) (scrollxOld + ((scrollxTarget - scrollxOld) * (startTime - initialTime + renderAverageTime)) / (totalTime - initialTime)); + scrolly = (int16) (scrollyOld + ((scrollyTarget - scrollyOld) * (startTime - initialTime + renderAverageTime)) / (totalTime - initialTime)); + } } return RD_OK; @@ -1057,9 +1090,8 @@ int32 SetScrollTarget(int16 sx, int16 sy) { } int32 CopyScreenBuffer(void) { - // FIXME: This function no longer seems needed. Calling copy_rect() - // for the whole screen is slower than the current approach. Not by - // much, but still... + // FIXME: This function no longer seems to be needed. We copy the + // back buffer to the screen in ServiceWindows() instead. return RD_OK; } @@ -1207,6 +1239,6 @@ int32 CloseBackgroundLayer(void) { int32 EraseSoftwareScreenBuffer(void) { - memset(myScreenBuffer, 0, RENDERWIDE * RENDERDEEP); + // memset(myScreenBuffer, 0, RENDERWIDE * RENDERDEEP); return(RD_OK); } diff --git a/sword2/driver/sprite.cpp b/sword2/driver/sprite.cpp index 5054a6c782..9542956f92 100644 --- a/sword2/driver/sprite.cpp +++ b/sword2/driver/sprite.cpp @@ -265,6 +265,7 @@ #include "render.h" #include "menu.h" #include "palette.h" +#include "rdwin.h" #if PROFILING == 1 @@ -1330,6 +1331,8 @@ int32 DrawSurface(_spriteInfo *s, uint8 *surface) { free(sprite); // UploadRect(&rd); + SetNeedRedraw(); + return 0; } @@ -1621,6 +1624,7 @@ int32 DrawSprite(_spriteInfo *s) { free(sprite); // UploadRect(&rd); + SetNeedRedraw(); /* |