diff options
-rw-r--r-- | sword2/driver/menu.cpp | 299 | ||||
-rw-r--r-- | sword2/driver/render.cpp | 479 | ||||
-rw-r--r-- | sword2/driver/render.h | 5 | ||||
-rw-r--r-- | sword2/driver/sprite.cpp | 125 |
4 files changed, 286 insertions, 622 deletions
diff --git a/sword2/driver/menu.cpp b/sword2/driver/menu.cpp index 696ed4ae91..8f80bdc29f 100644 --- a/sword2/driver/menu.cpp +++ b/sword2/driver/menu.cpp @@ -108,144 +108,147 @@ #define WIN32_LEAN_AND_MEAN -//#include <windows.h> -//#include <windowsx.h> -//#include <mmsystem.h> - -//#include "ddraw.h" - #include "stdafx.h" #include "driver96.h" #include "menu.h" #include "d_draw.h" #include "render.h" - +#include "common/rect.h" #define MENUDEEP 40 #define MAXMENUANIMS 8 - - -static uint8 menuStatus[2] = -{ +static uint8 menuStatus[2] = { RDMENU_HIDDEN, RDMENU_HIDDEN }; -static uint8 *icons[2][RDMENU_MAXPOCKETS] = -{ - { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }, - { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL } -}; - -// static LPDIRECTDRAWSURFACE lpIconSurface[2][RDMENU_MAXPOCKETS] = -static Surface *lpIconSurface[2][RDMENU_MAXPOCKETS] = -{ +static uint8 *icons[2][RDMENU_MAXPOCKETS] = { { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }, { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL } }; -static uint8 pocketStatus[2][RDMENU_MAXPOCKETS] = -{ +static uint8 pocketStatus[2][RDMENU_MAXPOCKETS] = { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }; -//static uint8 menuCounter[2]; -//static uint8 lastIcon[2]; static uint8 iconCount = 0; +int32 ProcessMenu(void) { + uint8 menu; + uint8 i; + uint8 complete; + uint8 frameCount; + int32 curx, xoff; + int32 cury, yoff; + ScummVM::Rect r; + int32 delta; + static int32 lastTime = 0; + if (lastTime == 0) { + lastTime = SVM_timeGetTime(); + frameCount = 1; + } else { + delta = SVM_timeGetTime() - lastTime; + if (delta > 250) { + lastTime += delta; + delta = 250; + frameCount = 1; + } else { + frameCount = (uint8) ((iconCount + 8) * delta / 750); + lastTime += frameCount * 750 / (iconCount + 8); + } + } + while (frameCount-- > 0) { + for (menu = RDMENU_TOP; menu <= RDMENU_BOTTOM; menu++) { + if (menuStatus[menu] == RDMENU_OPENING) { + // The menu is opening, so process it here + complete = 1; -int32 CreateIconSurface(uint8 menu, uint8 pocket) + // Propagate the animation from the first icon. + for (i = RDMENU_MAXPOCKETS - 1; i > 0; i--) { + pocketStatus[menu][i] = pocketStatus[menu][i - 1]; + if (pocketStatus[menu][i] != MAXMENUANIMS) + complete = 0; + } + if (pocketStatus[menu][i] != MAXMENUANIMS) + complete = 0; -{ - warning("stub CreatIconSurface( %d, %d )", menu, pocket); -/* + // ... and animate the first icon + if (pocketStatus[menu][0] != MAXMENUANIMS) + pocketStatus[menu][0]++; - HRESULT hr; - DDSURFACEDESC ddsd; + // Check to see if the menu is fully open + if (complete) + menuStatus[menu] = RDMENU_SHOWN; + } else if (menuStatus[menu] == RDMENU_CLOSING) { + // The menu is closing, so process it here + complete = 1; + // Propagate the animation from the first icon. + for (i = RDMENU_MAXPOCKETS - 1; i > 0; i--) { + pocketStatus[menu][i] = pocketStatus[menu][i - 1]; + if (pocketStatus[menu][i] != 0) + complete = 0; + } + if (pocketStatus[menu][i] != 0) + complete = 0; - // Set up the direct draw surface for the icon. - 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_BLTSTRETCH) - ddsd.ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY; - else - ddsd.ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY; + // ... and animate the first icon + if (pocketStatus[menu][0] != 0) + pocketStatus[menu][0]--; - ddsd.dwWidth = RDMENU_ICONWIDE; - ddsd.dwHeight = RDMENU_ICONDEEP; - hr = IDirectDraw2_CreateSurface(lpDD2, &ddsd, &lpIconSurface[menu][pocket], NULL); - if ((dxHalCaps & RDCAPS_BLTSTRETCH) && (hr == DDERR_OUTOFVIDEOMEMORY)) - { - ddsd.ddsCaps.dwCaps &= (0xffffffff - DDSCAPS_VIDEOMEMORY); - ddsd.ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY; - hr = IDirectDraw2_CreateSurface(lpDD2, &ddsd, &lpIconSurface[menu][pocket], NULL); - } - if (hr != DD_OK) - { - DirectDrawError("Unable to create icon surface", hr); - return(hr); + // Check to see if the menu is fully open + if (complete) + menuStatus[menu] = RDMENU_HIDDEN; + } + } } -*/ - return(RD_OK); -} - - - -int32 LoadIconSurface(int32 menu, int32 pocket) - -{ - warning("stub LoadIconSurface( %d, %d )"); -/* - - uint8 *src, *dst; - int32 i; - HRESULT hr; - DDSURFACEDESC ddsd; - + + // Does the menu need to be drawn? + for (menu = RDMENU_TOP; menu <= RDMENU_BOTTOM; menu++) { + if (menuStatus[menu] != RDMENU_HIDDEN) { + // Draw the menu here. + curx = RDMENU_ICONSTART + RDMENU_ICONWIDE / 2; + cury = (MENUDEEP / 2) + (RENDERDEEP + MENUDEEP) * menu; - memset(&ddsd, 0, sizeof(DDSURFACEDESC)); - ddsd.dwSize = sizeof(DDSURFACEDESC); + for (i = 0; i < RDMENU_MAXPOCKETS; i++) { + if (icons[menu][i]) { + if (pocketStatus[menu][i] == MAXMENUANIMS) { + xoff = (RDMENU_ICONWIDE / 2); + r.left = curx - xoff; + r.right = r.left + RDMENU_ICONWIDE; + yoff = (RDMENU_ICONDEEP / 2); + r.top = cury - yoff; + r.bottom = r.top + RDMENU_ICONDEEP; + } else { + xoff = (RDMENU_ICONWIDE / 2) * pocketStatus[menu][i] / MAXMENUANIMS; + r.left = curx - xoff; + r.right = curx + xoff; + yoff = (RDMENU_ICONDEEP / 2) * pocketStatus[menu][i] / MAXMENUANIMS; + r.top = cury - yoff; + r.bottom = cury + yoff; + } - hr = IDirectDrawSurface2_Lock(lpIconSurface[menu][pocket], NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL); - if (hr != DD_OK) - { - IDirectDrawSurface2_Restore(lpIconSurface[menu][pocket]); - hr = IDirectDrawSurface2_Lock(lpIconSurface[menu][pocket], NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL); - if (hr != DD_OK) - { - DirectDrawError("Unable to lock icon surface", hr); - return(hr); + if ((xoff != 0) && (yoff != 0)) { + SquashImage( + lpBackBuffer->_pixels + r.top * lpBackBuffer->_width + r.left, + lpBackBuffer->_width, + r.right - r.left, + r.bottom - r.top, + icons[menu][i], + RDMENU_ICONWIDE, + RDMENU_ICONWIDE, + RDMENU_ICONDEEP); + lpBackBuffer->upload(&r); + } + } + curx += (RDMENU_ICONSPACING + RDMENU_ICONWIDE); + } } } - - src = icons[menu][pocket]; - dst = ddsd.lpSurface; - for (i=0; i<RDMENU_ICONDEEP; i++) - { - memcpy(dst, src, RDMENU_ICONWIDE); - src += RDMENU_ICONWIDE; - dst += ddsd.lPitch; - } - - IDirectDrawSurface2_Unlock(lpIconSurface[menu][pocket], ddsd.lpSurface); -*/ - return(RD_OK); - -} - - - - -int32 ProcessMenu(void) - -{ - warning("stub ProcessMenu"); + /* uint8 menu; @@ -465,45 +468,34 @@ int32 ProcessMenu(void) return RD_OK; } - -int32 ShowMenu(uint8 menu) - -{ - - // Check for invalid menu parameter +int32 ShowMenu(uint8 menu) { + // Check for invalid menu parameter if (menu > RDMENU_BOTTOM) - return(RDERR_INVALIDMENU); + return RDERR_INVALIDMENU; - // Check that the menu is not currently shown, or in the process of being shown. - if ((menuStatus[menu] == RDMENU_SHOWN) || (menuStatus[menu] == RDMENU_OPENING)) - return(RDERR_INVALIDCOMMAND); + // Check that the menu is not currently shown, or in the process of + // being shown. + if (menuStatus[menu] == RDMENU_SHOWN || menuStatus[menu] == RDMENU_OPENING) + return RDERR_INVALIDCOMMAND; menuStatus[menu] = RDMENU_OPENING; - return RD_OK; - } - -int32 HideMenu(uint8 menu) - -{ - - // Check for invalid menu parameter +int32 HideMenu(uint8 menu) { + // Check for invalid menu parameter if (menu > RDMENU_BOTTOM) return(RDERR_INVALIDMENU); - // Check that the menu is not currently hidden, or in the process of being hidden. - if ((menuStatus[menu] == RDMENU_HIDDEN) || (menuStatus[menu] == RDMENU_CLOSING)) - return(RDERR_INVALIDCOMMAND); + // Check that the menu is not currently hidden, or in the process of + // being hidden. + if (menuStatus[menu] == RDMENU_HIDDEN || menuStatus[menu] == RDMENU_CLOSING) + return RDERR_INVALIDCOMMAND; menuStatus[menu] = RDMENU_CLOSING; - return RD_OK; - } - int32 CloseMenuImmediately(void) { menuStatus[0] = RDMENU_HIDDEN; @@ -512,66 +504,39 @@ int32 CloseMenuImmediately(void) return (RD_OK); } -int32 SetMenuIcon(uint8 menu, uint8 pocket, uint8 *icon) - -{ +int32 SetMenuIcon(uint8 menu, uint8 pocket, uint8 *icon) { debug(5, "stub SetMenuIcon( %d, %d )", menu, pocket); - -// HRESULT hr; - int32 hr; - - - // Check for invalid menu parameter. + // Check for invalid menu parameter. if (menu > RDMENU_BOTTOM) - return(RDERR_INVALIDMENU); + return RDERR_INVALIDMENU; - // Check for invalid pocket parameter + // Check for invalid pocket parameter if (pocket >= RDMENU_MAXPOCKETS) - return(RDERR_INVALIDPOCKET); + return RDERR_INVALIDPOCKET; - // If there is an icon in the requested menu/pocket, clear it out. - if (icons[menu][pocket]) - { + // If there is an icon in the requested menu/pocket, clear it out. + if (icons[menu][pocket]) { iconCount--; free(icons[menu][pocket]); icons[menu][pocket] = NULL; -// IDirectDrawSurface2_Release(lpIconSurface[menu][pocket]); - delete lpIconSurface[menu][pocket]; - lpIconSurface[menu][pocket] = NULL; } - // Only put the icon in the pocket if it is not NULL - if (icon != NULL) - { + // Only put the icon in the pocket if it is not NULL + if (icon != NULL) { iconCount++; icons[menu][pocket] = (uint8 *) malloc(RDMENU_ICONWIDE * RDMENU_ICONDEEP); if (icons[menu][pocket] == NULL) - return(RDERR_OUTOFMEMORY); + return RDERR_OUTOFMEMORY; memcpy(icons[menu][pocket], icon, RDMENU_ICONWIDE * RDMENU_ICONDEEP); - - hr = CreateIconSurface(menu, pocket); - //if (hr != DD_OK) - if (hr != RD_OK) - return(hr); - - hr = LoadIconSurface(menu, pocket); - if (hr != RD_OK) - return(hr); } return RD_OK; } - -uint8 GetMenuStatus(uint8 menu) - -{ - +uint8 GetMenuStatus(uint8 menu) { if (menu > RDMENU_BOTTOM) - return(RDMENU_HIDDEN); - - return(menuStatus[menu]); - + return RDMENU_HIDDEN; + return menuStatus[menu]; } 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; } diff --git a/sword2/driver/render.h b/sword2/driver/render.h index 287e243bc8..259b6ffbc0 100644 --- a/sword2/driver/render.h +++ b/sword2/driver/render.h @@ -86,7 +86,10 @@ extern int16 parallaxScrolly; // current y offset to link a sprite to the pa extern int16 locationWide; extern int16 locationDeep; -extern uint8 myScreenBuffer[RENDERWIDE * RENDERDEEP]; +// extern uint8 myScreenBuffer[RENDERWIDE * RENDERDEEP]; + +void SquashImage(byte *dst, uint16 dstPitch, uint16 dstWidth, uint16 dstHeight, byte *src, uint16 srcPitch, uint16 srcWidth, uint16 srcHeight); +void StretchImage(byte *dst, uint16 dstPitch, uint16 dstWidth, uint16 dstHeight, byte *src, uint16 srcPitch, uint16 srcWidth, uint16 srcHeight); #endif diff --git a/sword2/driver/sprite.cpp b/sword2/driver/sprite.cpp index f7e15eea03..778e1154b5 100644 --- a/sword2/driver/sprite.cpp +++ b/sword2/driver/sprite.cpp @@ -1584,9 +1584,6 @@ int32 DrawSprite(_spriteInfo *s) { // ----------------------------------------------------------------- if (scale != 256) { - int32 dx, dy, ince, incne, d; - int16 x, y; - if (s->scaledWidth > SCALE_MAXWIDTH || s->scaledHeight > SCALE_MAXHEIGHT) { if (freeSprite) free(sprite); @@ -1600,133 +1597,15 @@ int32 DrawSprite(_spriteInfo *s) { return RDERR_OUTOFMEMORY; } - // This is based on the "line doubling" scaler in the original - // code. - if (scale < 256) { - // Work out the x-scale - - dx = s->w; - dy = s->scaledWidth; - ince = 2 * dy; - incne = 2 * (dy - dx); - d = 2 * dy - dx; - - x = 0; - y = 0; - xScale[y] = x; - - while (x < s->w) { - if (d <= 0) { - d += ince; - x++; - } else { - d += incne; - x++; - y++; - } - xScale[y] = x; - } - - // Work out the y-scale - - dx = s->h; - dy = s->scaledHeight; - ince = 2 * dy; - incne = 2 * (dy - dx); - d = 2 * dy - dx; - - x = 0; - y = 0; - yScale[y] = x; - - while (x < s->h) { - if (d <= 0) { - d += ince; - x++; - } else { - d += incne; - x++; - y++; - } - yScale[y] = x; - } - - // Copy the sprite - - dst = newSprite; - - for (y = 0; y < s->scaledHeight; y++) { - for (x = 0; x < s->scaledWidth; x++) { - *dst++ = *(sprite + yScale[y] * s->w + xScale[x]); - } - } + SquashImage(newSprite, s->scaledWidth, s->scaledWidth, s->scaledHeight, sprite, s->w, s->w, s->h); } else { if (s->scale > 512) { if (freeSprite) free(sprite); return RDERR_INVALIDSCALING; } - - // Work out the x-scale - - dy = s->w; - dx = s->scaledWidth; - ince = 2 * dy; - incne = 2 * (dy - dx); - d = 2 * dy - dx; - - x = 0; - y = 0; - xScale[y] = x; - while (x < s->scaledWidth) { - if (d <= 0) { - d += ince; - x++; - } else { - d += incne; - x++; - y++; - xScale[y] = x; - } - } - - // Work out the y-scale - - dy = s->h; - dx = s->scaledHeight; - ince = 2 * dy; - incne = 2 * (dy - dx); - d = 2 * dy - dx; - - x = 0; - y = 0; - yScale[y] = x; - while (x < s->scaledHeight) { - if (d <= 0) { - d += ince; - x++; - } else { - d += incne; - x++; - y++; - yScale[y] = x; - } - } - - // Copy the sprite - - dst = newSprite; - - for (y = 0; y <s->h; y++) { - for (j = yScale[y]; j < yScale[y + 1]; j++) { - for (x = 0; x < s->w; x++) { - for (i = xScale[x]; i < xScale[x + 1]; i++) { - *dst++ = *(sprite + y * s->w + x); - } - } - } - } + StretchImage(newSprite, s->scaledWidth, s->scaledWidth, s->scaledHeight, sprite, s->w, s->w, s->h); } if (freeSprite) |