diff options
author | Torbjörn Andersson | 2003-08-23 13:02:21 +0000 |
---|---|---|
committer | Torbjörn Andersson | 2003-08-23 13:02:21 +0000 |
commit | df247cff6259ba24cd5d6704347532b3382f7c53 (patch) | |
tree | 4c93d5e0ff053a788ac8ac9a05ebf25584b07a1d /sword2 | |
parent | b113720a6d9ece3306e7d2a0642ada11f87a6728 (diff) | |
download | scummvm-rg350-df247cff6259ba24cd5d6704347532b3382f7c53.tar.gz scummvm-rg350-df247cff6259ba24cd5d6704347532b3382f7c53.tar.bz2 scummvm-rg350-df247cff6259ba24cd5d6704347532b3382f7c53.zip |
Unstubbed the Create/Draw/DeleteSurface() functions, and removed some
unnecessary stuff from our own Surface class. The former allows the in-game
dialogs to at least sort of work, and the latter gained me a few frames per
second, according to the built-in FPS counter.
svn-id: r9825
Diffstat (limited to 'sword2')
-rw-r--r-- | sword2/build_display.cpp | 1 | ||||
-rw-r--r-- | sword2/controls.cpp | 32 | ||||
-rw-r--r-- | sword2/driver/d_draw.cpp | 2 | ||||
-rw-r--r-- | sword2/driver/driver96.h | 18 | ||||
-rw-r--r-- | sword2/driver/menu.cpp | 2 | ||||
-rw-r--r-- | sword2/driver/rdwin.cpp | 1 | ||||
-rw-r--r-- | sword2/driver/render.cpp | 38 | ||||
-rw-r--r-- | sword2/driver/render.h | 1 | ||||
-rw-r--r-- | sword2/driver/sprite.cpp | 328 |
9 files changed, 148 insertions, 275 deletions
diff --git a/sword2/build_display.cpp b/sword2/build_display.cpp index 5795ec408d..41c5e4fc75 100644 --- a/sword2/build_display.cpp +++ b/sword2/build_display.cpp @@ -262,6 +262,7 @@ void Build_display(void) //Tony21Sept96 if (SVM_timeGetTime() > cycleTime) { fps = frameCount; + debug(2, "FPS: %d", fps); frameCount = 0; cycleTime = SVM_timeGetTime()+1000; } diff --git a/sword2/controls.cpp b/sword2/controls.cpp index 96f99044fe..38e489c42b 100644 --- a/sword2/controls.cpp +++ b/sword2/controls.cpp @@ -54,16 +54,16 @@ #define CHARACTER_OVERLAP 2 // overlap characters by 3 pixels //----------------------------------------------------------------------------------------------------------------------- -void Create_surface_image(_spriteInfo *sprite, uint32 *surface, uint32 res, uint32 x, uint32 y, uint32 pc); +void Create_surface_image(_spriteInfo *sprite, uint8 **surface, uint32 res, uint32 x, uint32 y, uint32 pc); void Build_surfaces(void); void Build_chr_surfaces(void); void Kill_chr_surfaces(void); void Kill_surfaces(void); void Renew_surfaces(void); -void Engine_string(uint32 x, uint32 y, uint32 res, uint32 *surface_list, uint8 *buf); +void Engine_string(uint32 x, uint32 y, uint32 res, uint8 **surface_list, uint8 *buf); void Kill_mini_surfaces(void); void Build_mini_surfaces(void); -uint32 Generic_mini_control(uint32 text_id); +uint32 Generic_mini_control(uint32 text_id); uint32 Pixel_text_length(uint8 *buf, uint32 res); void Control_error(char* text); @@ -139,50 +139,50 @@ void Control_error(char* text); //-------------------------------------------- -uint32 panel_surface; +uint8 *panel_surface; _spriteInfo panel_sprite; _spriteInfo slab_sprite[8]; -uint32 slab_surface[8]; +uint8 *slab_surface[8]; _spriteInfo chr_sprite; #define SIZE_OF_CHAR_SET (256-32) // our fonts start on SPACE character (32) -uint32 chr_surface[SIZE_OF_CHAR_SET]; -uint32 red_chr_surface[SIZE_OF_CHAR_SET]; +uint8 *chr_surface[SIZE_OF_CHAR_SET]; +uint8 *red_chr_surface[SIZE_OF_CHAR_SET]; _spriteInfo can_button_sprite[2]; -uint32 can_button_surface[2]; +uint8 *can_button_surface[2]; uint32 can_button_state=0; uint32 touching_can_button=0; _spriteInfo button_sprite[2]; -uint32 button_surface[2]; +uint8 *button_surface[2]; uint32 restore_button_state=0; uint32 touching_restore_button=0; _spriteInfo up_button_sprite[2]; -uint32 up_button_surface[2]; +uint8 *up_button_surface[2]; uint32 up_button_state=0; uint32 touching_up_button=0; _spriteInfo down_button_sprite[2]; -uint32 down_button_surface[2]; +uint8 *down_button_surface[2]; uint32 down_button_state=0; uint32 touching_down_button=0; _spriteInfo zup_button_sprite[2]; -uint32 zup_button_surface[2]; +uint8 *zup_button_surface[2]; uint32 zup_button_state=0; uint32 touching_zup_button=0; _spriteInfo zdown_button_sprite[2]; -uint32 zdown_button_surface[2]; +uint8 *zdown_button_surface[2]; uint32 zdown_button_state=0; uint32 touching_zdown_button=0; _spriteInfo grfx_icon_sprite[4]; -uint32 grfx_icon_surface[4]; +uint8 *grfx_icon_surface[4]; uint8 *charSet; uint8 *red_charSet; @@ -670,7 +670,7 @@ uint32 Restore_control(void) //Tony20Mar97 return(0); } //----------------------------------------------------------------------------------------------------------------------- -void Create_surface_image(_spriteInfo *sprite, uint32 *surface, uint32 res, uint32 x, uint32 y, uint32 pc) //TonyMarch97 +void Create_surface_image(_spriteInfo *sprite, uint8 **surface, uint32 res, uint32 x, uint32 y, uint32 pc) //TonyMarch97 { uint8 *file, *colTablePtr=NULL; _animHeader *anim_head; @@ -1765,7 +1765,7 @@ void Kill_mini_surfaces(void) //tony3Apr97 } //----------------------------------------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------------------------------------- -void Engine_string(uint32 x, uint32 y, uint32 res, uint32 *surface_list, uint8 *buf) //tony2Apr97 +void Engine_string(uint32 x, uint32 y, uint32 res, uint8 **surface_list, uint8 *buf) //tony2Apr97 { //takes fonts as sprites and prints transparently to screen //requires the chr$ surfaces have been setup diff --git a/sword2/driver/d_draw.cpp b/sword2/driver/d_draw.cpp index d62697ce62..68dc133c0c 100644 --- a/sword2/driver/d_draw.cpp +++ b/sword2/driver/d_draw.cpp @@ -389,7 +389,7 @@ int32 NextSmackerFrame(void) { } -uint32 textSurface = 0; +uint8 *textSurface = NULL; void OpenTextObject(_movieTextObject *obj) { CreateSurface(obj->textSprite, &textSurface); diff --git a/sword2/driver/driver96.h b/sword2/driver/driver96.h index f57ddd660e..1f3163dc28 100644 --- a/sword2/driver/driver96.h +++ b/sword2/driver/driver96.h @@ -1248,19 +1248,23 @@ typedef int BOOL; #define FALSE 0 // FIXME: Temporary (?) surface class to replace LPDIRECTDRAWSURFACE for now. +// Actually, this class should be used as little as possible since it +// introduces an extra layer of data copying. It should only be used where we +// decode something once and draw it many times, such as the parallax layers. +// +// Even then it's only necessary if we also need to keep track of the +// surface's coordinates. class Surface { public: uint16 _width, _height; uint16 _pitch; byte *_pixels; - int _colorKey; Surface(uint width, uint height) { _width = width; _height = height; _pixels = (byte *) calloc(_width, _height); - _colorKey = -1; }; ~Surface() { @@ -1270,10 +1274,6 @@ public: void clear(); void blit(Surface *s, ScummVM::Rect *r); void blit(Surface *s, ScummVM::Rect *r, ScummVM::Rect *clip_rect); - void upload(ScummVM::Rect *r); - void setColorKey(int colorKey) { - _colorKey = colorKey; - }; }; // @@ -1538,9 +1538,9 @@ extern void GetKeyStatus(_drvKeyStatus *s); // Sprite functions - from sprite.c //----------------------------------------------------------------------------- extern int32 DrawSprite(_spriteInfo *s); -extern int32 CreateSurface(_spriteInfo *s, uint32 *surface); -extern int32 DrawSurface(_spriteInfo *s, uint32 surface); -extern int32 DeleteSurface(uint32 surface); +extern int32 CreateSurface(_spriteInfo *s, uint8 **surface); +extern int32 DrawSurface(_spriteInfo *s, uint8 *surface); +extern int32 DeleteSurface(uint8 *surface); extern int32 OpenLightMask(_spriteInfo *s); extern int32 CloseLightMask(void); //----------------------------------------------------------------------------- diff --git a/sword2/driver/menu.cpp b/sword2/driver/menu.cpp index 9fe3d2ddb6..241866e8f8 100644 --- a/sword2/driver/menu.cpp +++ b/sword2/driver/menu.cpp @@ -246,7 +246,7 @@ int32 ProcessMenu(void) { dst += lpBackBuffer->_width; } } - lpBackBuffer->upload(&r); + UploadRect(&r); } } curx += (RDMENU_ICONSPACING + RDMENU_ICONWIDE); diff --git a/sword2/driver/rdwin.cpp b/sword2/driver/rdwin.cpp index f00f201c6c..bfa990e7fb 100644 --- a/sword2/driver/rdwin.cpp +++ b/sword2/driver/rdwin.cpp @@ -546,6 +546,7 @@ int32 ServiceWindows(void) { g_sword2->parseEvents(); + g_sword2->_system->update_screen(); // warning("stub ServiceWindows"); // too noisy /* MSG msg; diff --git a/sword2/driver/render.cpp b/sword2/driver/render.cpp index b214998c9f..1d9749e3f8 100644 --- a/sword2/driver/render.cpp +++ b/sword2/driver/render.cpp @@ -326,28 +326,21 @@ void Surface::blit(Surface *s, ScummVM::Rect *r, ScummVM::Rect *clip_rect) { // several times, as each new parallax layer is rendered, this may be // a bit inefficient. - if (s->_colorKey >= 0) { - for (i = 0; i < r->bottom - r->top; i++) { - for (j = 0; j < r->right - r->left; j++) { - if (src[j] != s->_colorKey) - dst[j] = src[j]; - } - src += s->_width; - dst += _width; - } - } else { - for (i = 0; i < r->bottom - r->top; i++) { - memcpy(dst, src, r->right - r->left); - src += s->_width; - dst += _width; + for (i = 0; i < r->bottom - r->top; i++) { + for (j = 0; j < r->right - r->left; j++) { + if (src[j]) + dst[j] = src[j]; } + src += s->_width; + dst += _width; } - upload(r); + UploadRect(r); } -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); +void UploadRect(ScummVM::Rect *r) { + g_system->copy_rect(lpBackBuffer->_pixels + r->top * lpBackBuffer->_width + r->left, + lpBackBuffer->_width, r->left, r->top, r->right - r->left, r->bottom - r->top); } #define SCALE_MAXWIDTH 512 @@ -950,13 +943,9 @@ int32 SetScrollTarget(int16 sx, int16 sy) { } int32 CopyScreenBuffer(void) { - debug(9, "CopyScreenBuffer"); - - // FIXME: The backend should keep track of dirty rects, but I have a - // feeling each one may be drawn several times, so we may have do add - // our own handling of them instead. - - g_sword2->_system->update_screen(); + // 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... return RD_OK; } @@ -1067,7 +1056,6 @@ bailout: if (block_has_data) { blockSurfaces[layer][i] = new Surface(BLOCKWIDTH, BLOCKHEIGHT); - blockSurfaces[layer][i]->setColorKey(0); // Copy the data into the surfaces. dst = blockSurfaces[layer][i]->_pixels; diff --git a/sword2/driver/render.h b/sword2/driver/render.h index 259b6ffbc0..d49d64ee11 100644 --- a/sword2/driver/render.h +++ b/sword2/driver/render.h @@ -91,6 +91,7 @@ extern int16 locationDeep; 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); +void UploadRect(ScummVM::Rect *r); #endif diff --git a/sword2/driver/sprite.cpp b/sword2/driver/sprite.cpp index b5d0336bfa..324f7981bf 100644 --- a/sword2/driver/sprite.cpp +++ b/sword2/driver/sprite.cpp @@ -1197,264 +1197,146 @@ int32 SoftwareRenderCompressed256(_spriteInfo *s) } -int32 CreateSurface(_spriteInfo *s, uint32 *surface) +// The purpose of this function seems to be to decode a sprite to its +// simplest form in advance. -{ - warning("stub CreateSurface"); -/* - - uint8 *sprite, *newSprite; - uint8 *src, *dst; - int32 freeSprite = 0; - int32 i; - HRESULT hr; - DDSURFACEDESC ddsd; - LPDIRECTDRAWSURFACE dds; - - - // Create a surface for the sprite and then draw it. - memset(&ddsd, 0, sizeof(DDSURFACEDESC)); - ddsd.dwSize = sizeof(DDSURFACEDESC); - ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT; - ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN; - if (s->scale & 0xff) - { - if (dxHalCaps & RDCAPS_BLTSTRETCH) - ddsd.ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY; - else - ddsd.ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY; - } - else - { - if (dxHalCaps & RDCAPS_SRCBLTCKEY) - ddsd.ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY; - else - ddsd.ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY; - } +int32 CreateSurface(_spriteInfo *s, uint8 **sprite) { + uint8 *newSprite; - ddsd.dwWidth = s->w; - ddsd.dwHeight = s->h; - hr = IDirectDraw2_CreateSurface(lpDD2, &ddsd, &dds, NULL); - if (hr == DDERR_OUTOFVIDEOMEMORY) - { - ddsd.ddsCaps.dwCaps &= (0xffffffff - DDSCAPS_VIDEOMEMORY); - ddsd.ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY; - hr = IDirectDraw2_CreateSurface(lpDD2, &ddsd, &dds, NULL); - } - if (hr != DD_OK) - { - DirectDrawError("Cannot create sprite surface", hr); - return(hr); - } - - if (s->type & RDSPR_TRANS) - hr = IDirectDrawSurface2_SetColorKey(dds, DDCKEY_SRCBLT, &blackColorKey); + *sprite = (uint8 *) malloc(s->w * s->h); + if (!*sprite) + return RDERR_OUTOFMEMORY; - if (s->type &RDSPR_NOCOMPRESSION) - { - sprite = s->data; - } - else - { - sprite = (uint8 *) malloc(s->w * s->h); - freeSprite = 1; - if (sprite == NULL) - { - IDirectDrawSurface2_Release(dds); - return(RDERR_OUTOFMEMORY); - } - - if (s->type >> 8 == RDSPR_RLE16 >> 8) - { - if (DecompressRLE16(sprite, s->data, s->w * s->h, s->colourTable)) - return(RDERR_DECOMPRESSION); - } - else - { - if (DecompressRLE256(sprite, s->data, s->w * s->h)) - return(RDERR_DECOMPRESSION); + if (s->type & RDSPR_NOCOMPRESSION) { + memcpy(*sprite, s->data, s->w * s->h); + } else { + if (s->type >> 8 == RDSPR_RLE16 >> 8) { + if (DecompressRLE16(*sprite, s->data, s->w * s->h, s->colourTable)) { + free(*sprite); + return RDERR_DECOMPRESSION; + } + } else { + if (DecompressRLE256(*sprite, s->data, s->w * s->h)) { + free(*sprite); + return RDERR_DECOMPRESSION; + } } - if (s->type & RDSPR_FLIP) - { + if (s->type & RDSPR_FLIP) { newSprite = (uint8 *) malloc(s->w * s->h); - if (newSprite == NULL) - { - free(sprite); - return(RDERR_OUTOFMEMORY); + if (!newSprite) { + free(*sprite); + return RDERR_OUTOFMEMORY; } - MirrorSprite(newSprite, sprite, s->w, s->h); - free(sprite); - sprite = newSprite; - } - } - - hr = IDirectDrawSurface2_Lock(dds, NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL); - if (hr != DD_OK) - { - IDirectDrawSurface2_Restore(dds); - hr = IDirectDrawSurface2_Lock(dds, NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL); - if (hr != DD_OK) - { - DirectDrawError("Cannot lock sprite surface", hr); - return(hr); + MirrorSprite(newSprite, *sprite, s->w, s->h); + free(*sprite); + *sprite = newSprite; } } - - src = sprite; - dst = ddsd.lpSurface; - for (i=0; i<s->h; i++) - { - memcpy(dst, src, s->w); - src += s->w; - dst += ddsd.lPitch; - } - - IDirectDrawSurface2_Unlock(dds, ddsd.lpSurface); - - *surface = (uint32) dds; - - if (freeSprite) - free(sprite); -*/ - return(RD_OK); - + return RD_OK; } -int32 DrawSurface(_spriteInfo *s, uint32 surface) - -{ - warning("stub DrawSurface"); -/* - - HRESULT hr; - RECT rd, rs; - LPDIRECTDRAWSURFACE dds; - char myString[256]; - +int32 DrawSurface(_spriteInfo *s, uint8 *surface) { + ScummVM::Rect rd, rs; + uint16 x, y, srcPitch, scale; + uint8 *sprite, *src, *dst; + bool freeSprite = false; - dds = (LPDIRECTDRAWSURFACE) surface; + // FIXME: It should be possible to implement this in terms of the + // DrawSprite() function. - // Set startx and starty for the screen buffer ADDED THIS! - if (s->type & RDSPR_DISPLAYALIGN) + if (s->type & RDSPR_DISPLAYALIGN) { rd.top = s->y; - else - rd.top = s->y - scrolly; - - if (s->type & RDSPR_DISPLAYALIGN) rd.left = s->x; - else + } else { + rd.top = s->y - scrolly; rd.left = s->x - scrollx; + } rs.left = 0; rs.right = s->w; rs.top = 0; rs.bottom = s->h; - if (s->scale & 0xff) - { - rd.right = rd.left + s->scaledWidth; - rd.bottom = rd.top + s->scaledHeight; - // Do clipping - if (rd.top < 40) - { - rs.top = (40 - rd.top) * 256 / s->scale; - rd.top = 40; - } - if (rd.bottom > 440) - { - rs.bottom -= ((rd.bottom - 440) * 256 / s->scale); - rd.bottom = 440; - } - if (rd.left < 0) - { - rs.left = (0 - rd.left) * 256 / s->scale; - rd.left = 0; - } - if (rd.right > 640) - { - rs.right -= ((rd.right - 640) * 256 / s->scale); - rd.right = 640; - } + + scale = (s->scale == 0) ? 256 : s->scale; + + if (scale != 256) { + rs.right = s->scaledWidth; + rs.bottom = s->scaledHeight; + srcPitch = s->scaledWidth; + } else { + rs.right = s->w; + rs.bottom = s->h; + srcPitch = s->w; } - else - { - rd.right = rd.left + s->w; - rd.bottom = rd.top + s->h; - // Do clipping - if (rd.top < 40) - { - rs.top = 40 - rd.top; - rd.top = 40; - } - if (rd.bottom > 440) - { - rs.bottom -= (rd.bottom - 440); - rd.bottom = 440; - } - if (rd.left < 0) - { - rs.left = 0 - rd.left; - rd.left = 0; - } - if (rd.right > 640) - { - rs.right -= (rd.right - 640); - rd.right = 640; - } + rd.right = rd.left + rs.right; + rd.bottom = rd.top + rs.bottom; + + // Do clipping + if (rd.top < 40) { + rs.top = (40 - rd.top) * 256 / s->scale; + rd.top = 40; + } + if (rd.bottom > 440) { + rs.bottom -= ((rd.bottom - 440) * 256 / s->scale); + rd.bottom = 440; + } + if (rd.left < 0) { + rs.left = (0 - rd.left) * 256 / s->scale; + rd.left = 0; + } + if (rd.right > 640) { + rs.right -= ((rd.right - 640) * 256 / s->scale); + rd.right = 640; } - if (s->type & RDSPR_TRANS) - { - hr = IDirectDrawSurface2_Blt(lpBackBuffer, &rd, dds, &rs, DDBLT_WAIT | DDBLT_KEYSRC, NULL); - if (hr) - { - if (hr == DDERR_SURFACELOST) - hr = RDERR_SURFACELOST; - else if (dxHalCaps & RDCAPS_BLTSTRETCH) - dxHalCaps -= RDCAPS_BLTSTRETCH; - else - { - sprintf(myString, "DrawSurface failed, sprite: x%d y%d w%d h%d s%d t%d sx%d sy%d", s->x, s->y, s->w, s->h, s->scale, s->type, scrollx, scrolly); - DirectDrawError(myString, hr); - } + if (scale != 256) { + sprite = (uint8 *) malloc(s->scaledWidth * s->scaledHeight); + if (!sprite) + return RDERR_OUTOFMEMORY; + + if (scale < 256) { + SquashImage(sprite, s->scaledWidth, s->scaledWidth, s->scaledHeight, surface, s->w, s->w, s->h); + } else { + StretchImage(sprite, s->scaledWidth, s->scaledWidth, s->scaledHeight, surface, s->w, s->w, s->h); } - } - else - { - hr = IDirectDrawSurface2_Blt(lpBackBuffer, &rd, dds, &rs, DDBLT_WAIT, NULL); - if (hr) - { - if (hr == DDERR_SURFACELOST) - hr = RDERR_SURFACELOST; - else - { - sprintf(myString, "DrawSurface failed, sprite: x%d y%d w%d h%d s%d t%d sx%d sy%d", s->x, s->y, s->w, s->h, s->scale, s->type, scrollx, scrolly); - DirectDrawError(myString, hr); + + freeSprite = true; + } else + sprite = surface; + + src = sprite + rs.top * srcPitch + rs.left; + dst = lpBackBuffer->_pixels + lpBackBuffer->_width * rd.top + rd.left; + + if (s->type & RDSPR_TRANS) { + for (y = 0; y < rd.bottom - rd.top; y++) { + for (x = 0; x < rd.right - rd.left; x++) { + if (src[x]) + dst[x] = src[x]; } + src += srcPitch; + dst += lpBackBuffer->_width; } + } else { + for (y = 0; y < rd.bottom - rd.top; y++) + memcpy(dst, src, lpBackBuffer->_width); + src += srcPitch; + dst += lpBackBuffer->_width; } - return(hr); -*/ + if (freeSprite) + free(sprite); + + UploadRect(&rd); return 0; } -int32 DeleteSurface(uint32 surface) - -{ - warning("stub DeleteSurface( %d )", surface); -/* - - LPDIRECTDRAWSURFACE dds; - - dds = (LPDIRECTDRAWSURFACE) surface; - return(IDirectDrawSurface2_Release(dds)); -*/ +int32 DeleteSurface(uint8 *surface) { + free(surface); return 0; - } #define SCALE_MAXWIDTH 512 @@ -1722,7 +1604,7 @@ int32 DrawSprite(_spriteInfo *s) { if (freeSprite) free(sprite); - lpBackBuffer->upload(&rd); + UploadRect(&rd); /* |