Ticket #8270: sword2-graphics.diff

File sword2-graphics.diff, 14.3 KB (added by eriktorbjorn, 21 years ago)

Patch against an August 16 CVS snapshot

  • scummvm/bs2/driver/d_draw.cpp

    diff -ur ScummVM-cvs20030816/scummvm/bs2/driver/d_draw.cpp ScummVM-cvs20030816+hack/scummvm/bs2/driver/d_draw.cpp
    old new  
    4545#define MILLISECSPERCYCLE 83
    4646
    4747
     48// Surface *lpPrimarySurface;
     49Surface *lpBackBuffer;
    4850
    4951/*
    5052LPDIRECTDRAW7        m_pDD;
     
    234236
    235237int32 InitialiseDisplay(int16 width, int16 height, int16 colourDepth, int32 windowType)
    236238{
     239        screenWide = width;
     240        screenDeep = height;
     241
     242//      lpPrimarySurface = new Surface(width, height);
     243        lpBackBuffer = new Surface(width, height);
     244
    237245/*
    238246        DDSURFACEDESC       ddsd;
    239247    DDSCAPS             ddscaps;
     
    715723int32 FlipScreens(void)
    716724
    717725{
    718         warning("stub FlipScreens");
     726        // I think this function can be removed. We render to lpBackBuffer,
     727        // and the backend acts as the primary buffer.
     728
     729        debug(0, "FlipScreens");
     730
    719731/*
    720732    HRESULT             hr;
    721733        BOOL            vbl;
     
    825837
    826838int32 EraseBackBuffer( void )
    827839{
    828         warning("stub EraseBackBuffer");
     840        debug(0, "EraseBackBuffer");
     841        lpBackBuffer->clear();
     842
    829843/*
    830844    DDBLTFX     ddbltfx;
    831845    HRESULT     hr;
     
    12241238//      s->lpDraw                       = lpDraw;
    12251239//      s->lpDD2                        = lpDD2;
    12261240//      s->lpPrimarySurface = lpPrimarySurface;
    1227 //      s->lpBackBuffer         = lpBackBuffer;
     1241        s->lpBackBuffer         = lpBackBuffer;
    12281242//      s->lpPalette            = lpPalette;
    12291243        s->screenDeep           = screenDeep;
    12301244        s->screenWide           = screenWide;
  • scummvm/bs2/driver/d_draw.h

    diff -ur ScummVM-cvs20030816/scummvm/bs2/driver/d_draw.h ScummVM-cvs20030816+hack/scummvm/bs2/driver/d_draw.h
    old new  
    7878
    7979
    8080extern uint8 *lpPalette;                        // palette
    81 extern uint8 *lpBackBuffer;             // back surface
    82 extern uint8 *lpPrimarySurface; // DirectDraw front buffer.
     81extern Surface *lpBackBuffer;           // back surface
     82// extern Surface *lpPrimarySurface;    // DirectDraw front buffer.
    8383extern uint8 *lpDD2;                            // DirectDraw2 object
    8484extern BOOL bFullScreen;                // Defines whether the app is running in full screen mode or not.
    8585//extern DDCOLORKEY                             blackColorKey;          // transparent pixel for color key blitting.
  • scummvm/bs2/driver/driver96.h

    diff -ur ScummVM-cvs20030816/scummvm/bs2/driver/driver96.h ScummVM-cvs20030816+hack/scummvm/bs2/driver/driver96.h
    old new  
    10531053#include "common/scummsys.h"
    10541054#include "common/engine.h" // for warning()
    10551055#include "common/system.h"
     1056#include "common/rect.h"
    10561057//#include "ddraw.h"
    10571058//#include "dsound.h"
    10581059
     
    12541255#define TRUE 1
    12551256#define FALSE 0
    12561257
     1258// FIXME: Temporary (?) surface class to replace LPDIRECTDRAWSURFACE for now.
     1259
     1260class Surface {
     1261public:
     1262        uint16 _width, _height;
     1263        uint16 _pitch;
     1264        byte *_pixels;
     1265
     1266        Surface(uint width, uint height) {
     1267                _width = width;
     1268                _height = height;
     1269                _pixels = (byte *) calloc(_width, _height);
     1270        };
     1271
     1272        ~Surface() {
     1273                free(_pixels);
     1274        };
     1275
     1276        void clear();
     1277        void blit(Surface *s, ScummVM::Rect *r);
     1278        void blit(Surface *s, ScummVM::Rect *r, ScummVM::Rect *clip_rect);
     1279};
     1280
    12571281//
    12581282//      Structure definitions
    12591283//      ---------------------
     
    13511375//      HWND                            hwnd;
    13521376//      LPDIRECTDRAW            lpDraw;
    13531377//      LPDIRECTDRAW2           lpDD2;
    1354 //      LPDIRECTDRAWSURFACE     lpPrimarySurface;
    1355 //      LPDIRECTDRAWSURFACE     lpBackBuffer;
     1378//      Surface                         *lpPrimarySurface;
     1379        Surface                         *lpBackBuffer;
    13561380//      LPDIRECTDRAWPALETTE     lpPalette;
    13571381        int16                           screenDeep;
    13581382        int16                           screenWide;
  • scummvm/bs2/driver/palette.cpp

    diff -ur ScummVM-cvs20030816/scummvm/bs2/driver/palette.cpp ScummVM-cvs20030816+hack/scummvm/bs2/driver/palette.cpp
    old new  
    318318int32 SetPalette(int16 startEntry, int16 noEntries, uint8 *colourTable, uint8 fadeNow)
    319319
    320320{
    321         warning("stub SetPalette( %d, %d, %d )", startEntry, noEntries, fadeNow);
     321        debug(0, "SetPalette(%d, %d, %d)", startEntry, noEntries, fadeNow);
     322
     323        StackLock lock(g_sword2->_paletteMutex);
     324
     325        if (noEntries == 0) {
     326                RestorePalette();
     327                return RD_OK;
     328        }
     329
     330        // FIXME: Handle the fadeNow parameter
     331
     332        memcpy(&palCopy[startEntry][0], colourTable, noEntries * 4);
     333        g_sword2->_system->set_palette((byte *) palCopy, startEntry, noEntries);
     334
    322335/*
    323336
    324337        int32 hr;
  • scummvm/bs2/driver/render.cpp

    diff -ur ScummVM-cvs20030816/scummvm/bs2/driver/render.cpp ScummVM-cvs20030816+hack/scummvm/bs2/driver/render.cpp
    old new  
    208208#include "_mouse.h"
    209209#include "render.h"
    210210#include "menu.h"
     211#include "../sword2.h"
    211212
    212213
    213214
     
    248249static  int16   scrollyTarget;
    249250static  int16   scrollxOld;
    250251static  int16   scrollyOld;
    251 //static        uint16  layer = 0;
     252static  uint16  layer = 0;
    252253
    253254
    254255
     
    275276uint8 xblocks[MAXLAYERS];
    276277uint8 yblocks[MAXLAYERS];
    277278uint8 restoreLayer[MAXLAYERS];
    278 //LPDIRECTDRAWSURFACE *blockSurfaces[MAXLAYERS] = {0,0,0,0,0};
    279279
     280// Each layer is composed by several sub-blocks
     281
     282Surface **blockSurfaces[MAXLAYERS] = { 0, 0, 0, 0, 0 };
     283
     284
     285
     286void Surface::clear() {
     287        memset(_pixels, 0, _width * _height);
     288        g_sword2->_system->copy_rect(_pixels, _width, 0, 0, _width, _height);
     289}
     290
     291void Surface::blit(Surface *s, ScummVM::Rect *r) {
     292        ScummVM::Rect clip_rect;
     293
     294        clip_rect.left = 0;
     295        clip_rect.top = 0;
     296        clip_rect.right = 640;
     297        clip_rect.bottom = 480;
     298
     299        blit(s, r, &clip_rect);
     300}
     301
     302void Surface::blit(Surface *s, ScummVM::Rect *r, ScummVM::Rect *clip_rect) {
     303        if (r->top > clip_rect->bottom || r->left > clip_rect->right || r->bottom <= clip_rect->top || r->right <= clip_rect->left)
     304                return;
     305
     306        byte *src = s->_pixels;
     307
     308        if (r->top < clip_rect->top) {
     309                src -= s->_width * (r->top - clip_rect->top);
     310                r->top = clip_rect->top;
     311        }
     312        if (r->left < clip_rect->left) {
     313                src -= (r->left - clip_rect->left);
     314                r->left = clip_rect->left;
     315        }
     316        if (r->bottom > clip_rect->bottom)
     317                r->bottom = clip_rect->bottom;
     318        if (r->right > clip_rect->right)
     319                r->right = clip_rect->right;
     320
     321        byte *dst = _pixels + r->top * _width + r->left;
     322        int i, j;
     323
     324        // FIXME: We first render the data to the back buffer, and then copy
     325        // it to the backend. Since the same area will probably be copied
     326        // several times, as each new parallax layer is rendered, this may be
     327        // a bit inefficient.
     328
     329        for (i = 0; i < r->bottom - r->top; i++) {
     330                for (j = 0; j < r->right - r->left; j++) {
     331                        if (src[j])
     332                                dst[j] = src[j];
     333                }
     334                src += s->_width;
     335                dst += _width;
     336        }
     337
     338        g_sword2->_system->copy_rect(_pixels + r->top * _width + r->left, _width, r->left, r->top, r->right - r->left, r->bottom - r->top);
     339}
    280340
    281341
    282342
    283343int32 RestoreBackgroundLayer(_parallax *p, int16 l)
    284344{
    285         warning("stub RestoreBackgroundLayer %d", l);
     345        int16 oldLayer = layer;
     346        int16 i;
     347
     348        debug(0, "RestoreBackgroundLayer %d", l);
     349
     350        layer = l;
     351        if (blockSurfaces[l]) {
     352                for (i = 0; i < xblocks[l] * yblocks[l]; i++)
     353                        if (blockSurfaces[l][i])
     354                                delete blockSurfaces[l][i];
     355
     356                free(blockSurfaces[l]);
     357                blockSurfaces[l] = NULL;
     358        }
     359        RestoreSurfaces();
     360        InitialiseBackgroundLayer(p);
     361        layer = oldLayer;
     362
    286363/*
    287364        int16 oldLayer = layer;
    288365        int16 i;
     
    605682
    606683
    607684
    608 int32 RenderParallax(_parallax *p, int16 layer)
     685int32 RenderParallax(_parallax *p, int16 l) {
     686        int16 x, y;
     687        int16 i, j;
     688        ScummVM::Rect r;
     689
     690        debug(0, "RenderParallax %d", l);
     691
     692        if (locationWide == screenWide)
     693                x = 0;
     694        else
     695                x = ((int32) ((p->w - screenWide) * scrollx) / (int32) (locationWide - screenWide));
     696
     697        if (locationDeep == (screenDeep - MENUDEEP * 2))
     698                y = 0;
     699        else
     700                y = ((int32) ((p->h - (screenDeep - MENUDEEP * 2)) * scrolly) / (int32) (locationDeep - (screenDeep - MENUDEEP * 2)));
     701
     702        ScummVM::Rect clip_rect;
     703
     704        // Leave enough space for the top and bottom menues
     705
     706        clip_rect.left = 0;
     707        clip_rect.right = 640;
     708        clip_rect.top = 40;
     709        clip_rect.bottom = 440;
     710
     711        for (j = 0; j < yblocks[l]; j++) {
     712                for (i = 0; i < xblocks[l]; i++) {
     713                        if (blockSurfaces[l][i + j * xblocks[l]]) {
     714                                r.left = i * BLOCKWIDTH - x;
     715                                r.right = r.left + BLOCKWIDTH;
     716                                r.top = j * BLOCKHEIGHT - y + 40;
     717                                r.bottom = r.top + BLOCKHEIGHT;
     718                                lpBackBuffer->blit(blockSurfaces[l][i + j * xblocks[l]], &r, &clip_rect);
     719                        }
     720                }
     721        }
     722
     723        parallaxScrollx = scrollx - x;
     724        parallaxScrolly = scrolly - y;
    609725
    610 {
    611         warning("stub RenderParallax %d", layer);
    612726/*
    613727
    614728#if PROFILING == 1
     
    619733
    620734#endif
    621735
    622         if ((renderCaps & RDBLTFX_ALLHARDWARE) || ((renderCaps & RDBLTFX_FGPARALLAX) && (layer > 2)))
     736        if ((renderCaps & RDBLTFX_ALLHARDWARE) || ((renderCaps & RDBLTFX_FGPARALLAX) && (l > 2)))
    623737        {
    624738
    625739                int16 x, y;
     
    628742                HRESULT hr = 0;
    629743                RECT r, rd;
    630744
    631                 if (restoreLayer[layer])
     745                if (restoreLayer[l])
    632746                {
    633                         RestoreBackgroundLayer(p, layer);
    634                         restoreLayer[layer] = 0;
     747                        RestoreBackgroundLayer(p, l);
     748                        restoreLayer[l] = 0;
    635749                }
    636750
    637751                if (locationWide == screenWide)
     
    648762                while (TRUE)
    649763                {
    650764                        j = 0;
    651                         while (j < yblocks[layer])
     765                        while (j < yblocks[l])
    652766                        {
    653767                                i = 0;
    654                                 while (i < xblocks[layer])
     768                                while (i < xblocks[l])
    655769                                {
    656                                         if (*(blockSurfaces[layer] + i + j * xblocks[layer]))
     770                                        if (*(blockSurfaces[l] + i + j * xblocks[l]))
    657771                                        {
    658772                                                r.left = i * BLOCKWIDTH - x;
    659773                                                r.right = r.left + BLOCKWIDTH;
     
    684798                                                        rd.bottom = BLOCKHEIGHT - (r.bottom - 440);
    685799                                                        r.bottom = 440;
    686800                                                }
    687                                                 hr = IDirectDrawSurface2_Blt(lpBackBuffer, &r, *(blockSurfaces[layer] + i + j * xblocks[layer]), &rd, DDBLT_WAIT | DDBLT_KEYSRC, NULL);
     801                                                hr = IDirectDrawSurface2_Blt(lpBackBuffer, &r, *(blockSurfaces[l] + i + j * xblocks[l]), &rd, DDBLT_WAIT | DDBLT_KEYSRC, NULL);
    688802                                                if (hr == DDERR_INVALIDRECT)
    689803                                                        hr = 0;
    690804                                                if (hr)
     
    707821                                                if (++restoreSurfaces == 4)
    708822                                                        return(RDERR_RESTORELAYERS);
    709823                                                else
    710                                                         RestoreBackgroundLayer(p, layer);
     824                                                        RestoreBackgroundLayer(p, l);
    711825                                        }
    712826                                        else
    713827                                                return(RD_OK);
     
    9961110int32 CopyScreenBuffer(void)
    9971111
    9981112{
    999         warning("stub CopyScreenBuffer");
     1113        debug(0, "CopyScreenBuffer");
     1114
     1115        // FIXME: The backend should keep track of dirty rects, but I have a
     1116        // feeling each one may be drawn several times, so we may have do add
     1117        // our own handling of them instead.
     1118
     1119        g_sword2->_system->update_screen();
     1120
    10001121/*
    10011122
    10021123        uint8                   *dst, *src;
     
    10651186
    10661187
    10671188
    1068 int32 InitialiseBackgroundLayer(_parallax *p)
     1189int32 InitialiseBackgroundLayer(_parallax *p) {
     1190        uint8 *memchunk;
     1191        uint32 *quaddata;
     1192        uint8 zeros;
     1193        uint16 count;
     1194        uint16 i, j, k;
     1195        uint16 x;
     1196        uint8 *data;
     1197        uint8 *dst;
     1198        _parallaxLine *line;
     1199
     1200        debug(0, "InitialiseBackgroundLayer");
     1201
     1202        // This function is called to re-initialise the layers if they have
     1203        // been lost. We know this if the layers have already been assigned.
     1204
     1205        // TODO: Can layers still be lost, or is that a DirectDraw-ism?
     1206
     1207        if (layer == MAXLAYERS)
     1208                CloseBackgroundLayer();
     1209
     1210        if (!p) {
     1211                layer++;
     1212                return RD_OK;
     1213        }
     1214
     1215        xblocks[layer] = (p->w + BLOCKWIDTH - 1) >> BLOCKWBITS;
     1216        yblocks[layer] = (p->h + BLOCKHEIGHT - 1) >> BLOCKHBITS;
     1217
     1218        blockSurfaces[layer] = (Surface **) calloc(xblocks[layer] * yblocks[layer], sizeof(Surface *));
     1219        if (!blockSurfaces[layer])
     1220                return RDERR_OUTOFMEMORY;
     1221
     1222        // Decode the parallax layer into a large chunk of memory
     1223
     1224        memchunk = (uint8 *) malloc(xblocks[layer] * BLOCKWIDTH * yblocks[layer] * BLOCKHEIGHT);
     1225        if (!memchunk)
     1226                return RDERR_OUTOFMEMORY;
     1227
     1228        // We clear not the entire memory chunk, but enough of it to store
     1229        // the entire parallax layer.
     1230
     1231        memset(memchunk, 0, p->w * p->h);
     1232
     1233        for (i = 0; i < p->h; i++) {
     1234                if (p->offset[i] == 0)
     1235                        continue;
     1236
     1237                line = (_parallaxLine *) ((uint8 *) p + p->offset[i]);
     1238                data = (uint8 *) line + sizeof(_parallaxLine);
     1239                x = line->offset;
     1240
     1241                dst = memchunk + i * p->w + x;
     1242
     1243                zeros = 0;
     1244                if (line->packets == 0) {
     1245                        memcpy(dst, data, p->w);
     1246                        continue;
     1247                }
     1248
     1249                for (j = 0; j < line->packets; j++) {
     1250                        if (zeros) {
     1251                                dst += *data;
     1252                                x += *data;
     1253                                data++;
     1254                                zeros = 0;
     1255                        } else if (*data == 0) {
     1256                                data++;
     1257                                zeros = 1;
     1258                        } else {
     1259                                count = *data++;
     1260                                memcpy(dst, data, count);
     1261                                data += count;
     1262                                dst += count;
     1263                                x += count;
     1264                                zeros = 1;
     1265                        }
     1266                }
     1267        }
     1268
     1269        // Now create the surfaces!
     1270
     1271        for (i = 0; i < xblocks[layer] * yblocks[layer]; i++) {
     1272                bool block_has_data = false;
     1273
     1274                data = memchunk + (p->w * BLOCKHEIGHT * (i / xblocks[layer])) + BLOCKWIDTH * (i % xblocks[layer]);
     1275
     1276                quaddata = (uint32 *) data;
     1277
     1278                for (j = 0; j < BLOCKHEIGHT; j++) {
     1279                        for (k = 0; k < BLOCKWIDTH / 4; k++) {
     1280                                if (*quaddata) {
     1281                                        block_has_data = true;
     1282                                        goto bailout;
     1283                                }
     1284                                quaddata++;
     1285                        }
     1286                        quaddata += ((p->w - BLOCKWIDTH) / 4);
     1287                }
     1288
     1289bailout:
     1290
     1291                //  Only assign a surface to the block if it contains data.
     1292
     1293                if (block_has_data) {
     1294                        blockSurfaces[layer][i] = new Surface(BLOCKWIDTH, BLOCKHEIGHT);
     1295
     1296                        //  Copy the data into the surfaces.
     1297                        dst = blockSurfaces[layer][i]->_pixels;
     1298                        for (j = 0; j < BLOCKHEIGHT; j++) {
     1299                                memcpy(dst, data, BLOCKWIDTH);
     1300                                data += p->w;
     1301                                dst += BLOCKWIDTH;
     1302                        }
     1303                } else
     1304                        blockSurfaces[layer][i] = NULL;
     1305        }
     1306        free(memchunk);
     1307        layer++;
    10691308
    1070 {
    1071         warning("stub InitialiseBackgroundLayer");
    10721309/*
    10731310        uint8                   *memchunk;
    10741311        uint32                  *quaddata;
     
    12521489int32 CloseBackgroundLayer(void)
    12531490
    12541491{
    1255         warning("stub CloseBackgroundLayer");
     1492        debug(0, "CloseBackgroundLayer");
     1493
     1494        int16 i, j;
     1495
     1496        for (j = 0; j < MAXLAYERS; j++) {
     1497                if (blockSurfaces[j]) {
     1498                        for (i = 0; i < xblocks[j] * yblocks[j]; i++)
     1499                                if (blockSurfaces[j][i])
     1500                                        delete blockSurfaces[j][i];
     1501                        free(blockSurfaces[j]);
     1502                }
     1503        }
     1504
     1505        layer = 0;
    12561506/*
    12571507        int16                   i, j;
    12581508
  • scummvm/bs2/sword2.cpp

    diff -ur ScummVM-cvs20030816/scummvm/bs2/sword2.cpp ScummVM-cvs20030816+hack/scummvm/bs2/sword2.cpp
    old new  
    281281
    282282       
    283283        Zdebug("CALLING: InitialiseDisplay");
    284         // rv = InitialiseDisplay(640, 480, 8, RD_FULLSCREEN);
    285284        _system->init_size(640, 480);
    286         rv = RD_OK;
     285        rv = InitialiseDisplay(640, 480, 8, RD_FULLSCREEN);
    287286               
    288287        Zdebug("RETURNED with rv = %.8x", rv);
    289288        if (rv != RD_OK)