aboutsummaryrefslogtreecommitdiff
path: root/sword2/driver/render.cpp
diff options
context:
space:
mode:
authorTorbjörn Andersson2003-08-20 21:17:23 +0000
committerTorbjörn Andersson2003-08-20 21:17:23 +0000
commit8b9158817d7b3f08f752402d0d3ff1c943c42732 (patch)
tree807ba0b4e29751c7363e5b2a170768818821d28f /sword2/driver/render.cpp
parent470fd270099409ffbb075f9b82a9c8a4edda5f48 (diff)
downloadscummvm-rg350-8b9158817d7b3f08f752402d0d3ff1c943c42732.tar.gz
scummvm-rg350-8b9158817d7b3f08f752402d0d3ff1c943c42732.tar.bz2
scummvm-rg350-8b9158817d7b3f08f752402d0d3ff1c943c42732.zip
Lots of cleanup.
Oh, and the menus should work now. :-) svn-id: r9804
Diffstat (limited to 'sword2/driver/render.cpp')
-rw-r--r--sword2/driver/render.cpp479
1 files changed, 148 insertions, 331 deletions
diff --git a/sword2/driver/render.cpp b/sword2/driver/render.cpp
index ee0cd1c7fd..b214998c9f 100644
--- a/sword2/driver/render.cpp
+++ b/sword2/driver/render.cpp
@@ -350,12 +350,138 @@ void Surface::upload(ScummVM::Rect *r) {
g_sword2->_system->copy_rect(_pixels + r->top * _width + r->left, _width, r->left, r->top, r->right - r->left, r->bottom - r->top);
}
+#define SCALE_MAXWIDTH 512
+#define SCALE_MAXHEIGHT 512
+
+static uint16 xScale[SCALE_MAXWIDTH];
+static uint16 yScale[SCALE_MAXHEIGHT];
+
+// This is based on the "line doubling" scaler in the original sprite renderer.
+// I've made it into two separate functions because there were cases from
+// DrawSprite() where it wasn't obvious if the sprite should grow or shrink,
+// which caused crashes.
+//
+// The functions can probably be merged later, if/when we implement a better
+// scale function for it.
+
+void SquashImage(byte *dst, uint16 dstPitch, uint16 dstWidth, uint16 dstHeight,byte *src, uint16 srcPitch, uint16 srcWidth, uint16 srcHeight) {
+ int32 ince, incne, d;
+ int16 x, y;
+
+ // Work out the x-scale
+
+ ince = 2 * dstWidth;
+ incne = 2 * (dstWidth - srcWidth);
+ d = 2 * dstWidth - srcWidth;
+ x = y = 0;
+ xScale[y] = x;
+
+ while (x < srcWidth) {
+ if (d <= 0) {
+ d += ince;
+ x++;
+ } else {
+ d += incne;
+ x++;
+ y++;
+ }
+ xScale[y] = x;
+ }
+
+ // Work out the y-scale
+
+ ince = 2 * dstHeight;
+ incne = 2 * (dstHeight - srcHeight);
+ d = 2 * dstHeight - srcHeight;
+ x = y = 0;
+ yScale[y] = x;
+
+ while (x < srcHeight) {
+ if (d <= 0) {
+ d += ince;
+ x++;
+ } else {
+ d += incne;
+ x++;
+ y++;
+ }
+ yScale[y] = x;
+ }
+
+ // Copy the image
+
+ for (y = 0; y < dstHeight; y++) {
+ for (x = 0; x < dstWidth; x++) {
+ dst[x] = src[yScale[y] * srcPitch + xScale[x]];
+ }
+ dst += dstPitch;
+ }
+}
+
+void StretchImage(byte *dst, uint16 dstPitch, uint16 dstWidth, uint16 dstHeight,byte *src, uint16 srcPitch, uint16 srcWidth, uint16 srcHeight) {
+ int32 ince, incne, d;
+ int16 x, y, i, j, k;
+
+ // Work out the x-scale
+
+ ince = 2 * srcWidth;
+ incne = 2 * (srcWidth - dstWidth);
+ d = 2 * srcWidth - dstWidth;
+ x = y = 0;
+ xScale[y] = x;
+
+ while (x < dstWidth) {
+ if (d <= 0) {
+ d += ince;
+ x++;
+ } else {
+ d += incne;
+ x++;
+ y++;
+ xScale[y] = x;
+ }
+ }
+
+ // Work out the y-scale
+
+ ince = 2 * srcHeight;
+ incne = 2 * (srcHeight - dstHeight);
+ d = 2 * srcHeight - dstHeight;
+ x = y = 0;
+ yScale[y] = x;
+ while (x < dstHeight) {
+ if (d <= 0) {
+ d += ince;
+ x++;
+ } else {
+ d += incne;
+ x++;
+ y++;
+ yScale[y] = x;
+ }
+ }
+
+ // Copy the image
+
+ for (y = 0; y < srcHeight; y++) {
+ for (j = yScale[y]; j < yScale[y + 1]; j++) {
+ k = 0;
+ for (x = 0; x < srcWidth; x++) {
+ for (i = xScale[x]; i < xScale[x + 1]; i++) {
+ dst[k++] = src[y * srcPitch + x];
+ }
+ }
+ dst += dstPitch;
+ }
+ }
+}
+
int32 RestoreBackgroundLayer(_parallax *p, int16 l)
{
int16 oldLayer = layer;
int16 i;
- debug(0, "RestoreBackgroundLayer %d", l);
+ debug(2, "RestoreBackgroundLayer %d", l);
layer = l;
if (blockSurfaces[l]) {
@@ -368,25 +494,7 @@ int32 RestoreBackgroundLayer(_parallax *p, int16 l)
}
InitialiseBackgroundLayer(p);
layer = oldLayer;
-
-/*
- int16 oldLayer = layer;
- int16 i;
-
- layer = l;
- if (blockSurfaces[l])
- {
- for (i=0; i<xblocks[l] * yblocks[l]; i++)
- if (*(blockSurfaces[l]+i))
- IDirectDrawSurface2_Release(*(blockSurfaces[l] + i));
- free(blockSurfaces[l]);
- blockSurfaces[l] = NULL;
- }
- InitialiseBackgroundLayer(p);
- layer = oldLayer;
-*/
- return(RD_OK);
-
+ return RD_OK;
}
@@ -773,55 +881,38 @@ void LogMe(int32 in)
*/
-int32 InitialiseRenderCycle(void)
-
-{
-
+int32 InitialiseRenderCycle(void) {
initialTime = SVM_timeGetTime();
originTime = initialTime;
totalTime = initialTime + MILLISECSPERCYCLE;
-
- return(RD_OK);
-
+ return RD_OK;
}
-int32 StartRenderCycle(void)
-
-{
-
-
+int32 StartRenderCycle(void) {
scrollxOld = scrollx;
scrollyOld = scrolly;
startTime = SVM_timeGetTime();
- if (startTime + renderAverageTime >= totalTime)
- {
+ if (startTime + renderAverageTime >= totalTime) {
scrollx = scrollxTarget;
scrolly = scrollyTarget;
renderTooSlow = 1;
- }
- else
- {
+ } else {
scrollx = (int16) (scrollxOld + ((scrollxTarget - scrollxOld) * (startTime - initialTime + renderAverageTime)) / (totalTime - initialTime));
scrolly = (int16) (scrollyOld + ((scrollyTarget - scrollyOld) * (startTime - initialTime + renderAverageTime)) / (totalTime - initialTime));
renderTooSlow = 0;
}
framesPerGameCycle = 0;
-
- return(RD_OK);
-
+ return RD_OK;
}
-int32 EndRenderCycle(BOOL *end)
-
-{
-
+int32 EndRenderCycle(BOOL *end) {
int32 time;
time = SVM_timeGetTime();
@@ -834,44 +925,31 @@ int32 EndRenderCycle(BOOL *end)
if (++renderCountIndex == RENDERAVERAGETOTAL)
renderCountIndex = 0;
- if (renderTooSlow)
- {
+ if (renderTooSlow) {
*end = TRUE;
InitialiseRenderCycle();
- }
- else if (startTime + renderAverageTime >= totalTime)
- {
+ } else if (startTime + renderAverageTime >= totalTime) {
*end = TRUE;
originTime = totalTime;
totalTime += MILLISECSPERCYCLE;
initialTime = time;
- }
- else
- {
+ } else {
*end = FALSE;
scrollx = (int16) (scrollxOld + ((scrollxTarget - scrollxOld) * (startTime - initialTime + renderAverageTime)) / (totalTime - initialTime));
scrolly = (int16) (scrollyOld + ((scrollyTarget - scrollyOld) * (startTime - initialTime + renderAverageTime)) / (totalTime - initialTime));
}
- return(RD_OK);
-
+ return RD_OK;
}
-int32 SetScrollTarget(int16 sx, int16 sy)
-
-{
-
+int32 SetScrollTarget(int16 sx, int16 sy) {
scrollxTarget = sx;
scrollyTarget = sy;
-
- return(RD_OK);
-
+ return RD_OK;
}
-int32 CopyScreenBuffer(void)
-
-{
+int32 CopyScreenBuffer(void) {
debug(9, "CopyScreenBuffer");
// FIXME: The backend should keep track of dirty rects, but I have a
@@ -879,74 +957,10 @@ int32 CopyScreenBuffer(void)
// our own handling of them instead.
g_sword2->_system->update_screen();
-
-/*
-
- uint8 *dst, *src;
- int16 i;
- DDSURFACEDESC ddDescription;
- HRESULT hr;
-
-#if PROFILING == 1
- static long int endTime;
- long int startTime;
- int32 lastEndTime, profileTotalTime;
-#endif
-
-
-#if PROFILING == 1
- QueryPerformanceCounter(&startTime);
-// time = timeGetTime();
-#endif
-
-
- if (!(renderCaps & RDBLTFX_ALLHARDWARE))
- {
- ddDescription.dwSize = sizeof(ddDescription);
- hr = IDirectDrawSurface2_Lock(lpBackBuffer, NULL, &ddDescription, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL);
- if (hr != DD_OK)
- {
- hr = IDirectDrawSurface2_Lock(lpBackBuffer, NULL, &ddDescription, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL);
- }
- if (hr == DD_OK)
- {
- dst = (uint8 *) ddDescription.lpSurface + MENUDEEP * ddDescription.lPitch;
- src = myScreenBuffer;
- for (i=0; i<RENDERDEEP; i++)
- {
- memcpy(dst, src, screenWide);
- src += RENDERWIDE;
- dst += ddDescription.lPitch;
- }
- IDirectDrawSurface2_Unlock(lpBackBuffer, ddDescription.lpSurface);
- }
- else
- {
- return(RDERR_LOCKFAILED);
- }
- }
-
-#if PROFILING == 1
- lastEndTime = endTime.LowPart;
- QueryPerformanceCounter(&endTime);
- profileCopyScreenBuffer = (int32) (endTime.LowPart - startTime.LowPart) / 1000;
- profileTotalTime = (endTime.LowPart - lastEndTime) / 1000;
- if ((profileTotalTime > 0) && (profileTotalTime < 5000))
- PlotDots(0, 5, (int16) profileTotalTime);
- PlotDots(0, 10, (int16) profileCopyScreenBuffer);
- PlotDots(0, 15, (int16) (profileRenderLayers / 1000));
- PlotDots(0, 20, (int16) (profileSpriteRender / 1000));
- PlotDots(0, 25, (int16) (profileDecompression / 1000));
- profileRenderLayers = 0;
- profileSpriteRender = 0;
- profileDecompression = 0;
-#endif
-*/
- return(RD_OK);
+ return RD_OK;
}
-
int32 InitialiseBackgroundLayer(_parallax *p) {
uint8 *memchunk;
uint32 *quaddata;
@@ -958,7 +972,7 @@ int32 InitialiseBackgroundLayer(_parallax *p) {
uint8 *dst;
_parallaxLine *line;
- debug(0, "InitialiseBackgroundLayer");
+ debug(2, "InitialiseBackgroundLayer");
// This function is called to re-initialise the layers if they have
// been lost. We know this if the layers have already been assigned.
@@ -1067,190 +1081,13 @@ bailout:
}
free(memchunk);
layer++;
-
-/*
- uint8 *memchunk;
- uint32 *quaddata;
- uint8 zeros;
- uint16 count;
-// uint16 skip;
- uint16 i, j, k;
- uint16 x;
- uint8 *data;
- uint8 *dst;
- _parallaxLine *line;
- HRESULT hr;
- DDSURFACEDESC ddsd;
-
-
- if ((renderCaps & RDBLTFX_ALLHARDWARE) || ((renderCaps & RDBLTFX_FGPARALLAX) && (layer > 2)))
- {
-
- // This function is called to re-initialise the layers if they have been lost.
- // We know this if the layers have already been assigned.
- if (layer == MAXLAYERS)
- {
- CloseBackgroundLayer();
- }
-
-
- if (p == NULL)
- {
- layer += 1;
- return(RD_OK);
- }
-
- xblocks[layer] = (p->w + BLOCKWIDTH - 1) >> BLOCKWBITS;
- yblocks[layer] = (p->h + BLOCKHEIGHT - 1) >> BLOCKHBITS;
- blockSurfaces[layer] = (LPDIRECTDRAWSURFACE *) malloc(xblocks[layer] * yblocks[layer] * sizeof(LPDIRECTDRAWSURFACE));
- if (blockSurfaces[layer] == NULL)
- return(RDERR_OUTOFMEMORY);
-
- // Decode the parallax layer into a large chunk of memory
- memchunk = (uint8 *) malloc(xblocks[layer] * BLOCKWIDTH * yblocks[layer] * BLOCKHEIGHT);
- if (memchunk == NULL)
- return(RDERR_OUTOFMEMORY);
-
- memset(memchunk, 0, p->w * p->h);
-
- for (i = 0; i < p->h; i++)
- {
- if (p->offset[i] == 0)
- continue;
-
- line = (_parallaxLine *) ((uint8 *) p + p->offset[i]);
- data = (uint8 *) line + sizeof(_parallaxLine);
- x = line->offset;
-
- dst = memchunk + i * p->w + x;
-
- zeros = 0;
- if (line->packets == 0)
- {
- memcpy(dst, data, p->w);
- continue;
- }
-
- for (j=0; j<line->packets; j++)
- {
- if (zeros)
- {
- dst += *data;
- x += *data;
- data += 1;
- zeros = 0;
- }
- else
- {
- if (*data == 0)
- {
- data ++;
- zeros = 1;
- }
- else
- {
- count = *data++;
- memcpy(dst, data, count);
- data += count;
- dst += count;
- x += count;
- zeros = 1;
- }
- }
- }
- }
-
- // Now create the surfaces!
- memset(&ddsd, 0, sizeof(DDSURFACEDESC));
- ddsd.dwSize = sizeof(DDSURFACEDESC);
- ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
- ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
- if (dxHalCaps & RDCAPS_SRCBLTCKEY)
- ddsd.ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY;
- else
- ddsd.ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY;
-
- ddsd.dwWidth = BLOCKWIDTH;
- ddsd.dwHeight = BLOCKHEIGHT;
- for (i=0; i<xblocks[layer] * yblocks[layer]; i++)
- {
- // Only assign a surface to the block if it contains data.
- quaddata = (int32 *) (memchunk + (p->w * BLOCKHEIGHT * (i / xblocks[layer])) + BLOCKWIDTH * (i % xblocks[layer]));
- for (j=0; j<BLOCKHEIGHT; j++)
- {
- for (k=0; k<BLOCKWIDTH / 4; k++)
- {
- if (*quaddata)
- break;
- quaddata++;
- }
- quaddata += ((p->w - BLOCKWIDTH) / 4);
- if (k < BLOCKWIDTH / 4)
- break;
- }
-
- if (k < BLOCKWIDTH / 4)
- {
- hr = IDirectDraw2_CreateSurface(lpDD2, &ddsd, blockSurfaces[layer] + i, NULL);
- if (hr != DD_OK)
- {
- if (hr == DDERR_OUTOFVIDEOMEMORY)
- {
- ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;
- hr = IDirectDraw2_CreateSurface(lpDD2, &ddsd, blockSurfaces[layer] + i, NULL);
- }
- if (hr != DD_OK)
- {
- DirectDrawError("Cannot create parallax surface", hr);
- return(hr);
- }
- }
- // Set the surface blt source colour key
- hr = IDirectDrawSurface2_SetColorKey(*(blockSurfaces[layer] + i), DDCKEY_SRCBLT, &blackColorKey);
-
- // Copy the data into the surfaces.
- memset(&ddsd, 0, sizeof(DDSURFACEDESC));
- ddsd.dwSize = sizeof(DDSURFACEDESC);
- hr = IDirectDrawSurface2_Lock(*(blockSurfaces[layer] + i), NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL);
- if (hr != DD_OK)
- {
- IDirectDrawSurface2_Restore(*(blockSurfaces[layer] + i));
- hr = IDirectDrawSurface2_Lock(*(blockSurfaces[layer] + i), NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL);
- if (hr != DD_OK)
- {
- DirectDrawError("Cannot lock parallax surface", hr);
- return(hr);
- }
- }
-
- data = memchunk + (p->w * BLOCKHEIGHT * (i / xblocks[layer])) + BLOCKWIDTH * (i % xblocks[layer]);
- dst = ddsd.lpSurface;
- for (j=0; j<BLOCKHEIGHT; j++)
- {
- memcpy(dst, data, BLOCKWIDTH);
- data += p->w;
- dst += ddsd.lPitch;
- }
- IDirectDrawSurface2_Unlock(*(blockSurfaces[layer] + i), ddsd.lpSurface);
- }
- else
- {
- *(blockSurfaces[layer] + i) = NULL;
- }
- }
- free(memchunk);
- }
- layer += 1;
-*/
- return(RD_OK);
+ return RD_OK;
}
-int32 CloseBackgroundLayer(void)
-
-{
- debug(0, "CloseBackgroundLayer");
+int32 CloseBackgroundLayer(void) {
+ debug(2, "CloseBackgroundLayer");
int16 i, j;
@@ -1265,27 +1102,7 @@ int32 CloseBackgroundLayer(void)
}
layer = 0;
-/*
- int16 i, j;
-
-// if (renderCaps & RDBLTFX_ALLHARDWARE)
-// {
- for (j=0; j<MAXLAYERS; j++)
- {
- if (blockSurfaces[j])
- {
- for (i=0; i<xblocks[j] * yblocks[j]; i++)
- if (*(blockSurfaces[j]+i))
- IDirectDrawSurface2_Release(*(blockSurfaces[j] + i));
- free(blockSurfaces[j]);
- blockSurfaces[j] = NULL;
- }
- }
- layer = 0;
-// }
-*/
- return(RD_OK);
-
+ return RD_OK;
}