aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sword2/build_display.cpp17
-rw-r--r--sword2/driver/d_draw.cpp10
-rw-r--r--sword2/driver/rdwin.cpp12
-rw-r--r--sword2/driver/rdwin.h1
-rw-r--r--sword2/driver/render.cpp52
-rw-r--r--sword2/driver/sprite.cpp4
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();
/*