Subversion Repositories AndroidProjects

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
244 chris 1
#include "DDImage.h"
2
#include <Math.h>
3
#include "DDInterface.h"
4
#include "D3DInterface.h"
5
#include "Rect.h"
6
#include "Graphics.h"
7
#include "SexyAppBase.h"
8
#include "Debug.h"
9
#include "PerfTimer.h"
10
 
11
#pragma warning(disable:4005) // macro redefinition
12
#pragma warning(disable:4244) // conversion possible loss of data
13
 
14
using namespace Sexy;
15
 
16
extern bool gOptimizeSoftwareDrawing;
17
 
18
DDImage::DDImage(DDInterface* theDDInterface) :
19
        MemoryImage(theDDInterface->mApp)
20
{
21
        mDDInterface = theDDInterface; 
22
        Init();
23
}
24
 
25
DDImage::DDImage() :
26
        MemoryImage(gSexyAppBase)
27
{
28
        mDDInterface = gSexyAppBase->mDDInterface;
29
        Init();
30
}
31
 
32
DDImage::~DDImage()
33
{
34
        if (mSurface != NULL)
35
                mSurface->Release();
36
        mDDInterface->RemoveDDImage(this);
37
 
38
        DBG_ASSERTE(mLockCount == 0);
39
}
40
 
41
void DDImage::Init()
42
{
43
        mSurface = NULL;
44
        mDDInterface->AddDDImage(this);
45
 
46
        mNoLock = false;
47
        mVideoMemory = false;
48
        mFirstPixelTrans = false;
49
        mWantDDSurface = false;                
50
        mDrawToBits = false;
51
        mSurfaceSet = false;
52
 
53
        mLockCount = 0;
54
}
55
 
56
bool DDImage::Check3D(Image *theImage)
57
{
58
        DDImage *anImage = dynamic_cast<DDImage*>(theImage);
59
        if (anImage!=NULL)
60
                return Check3D(anImage);
61
        else
62
                return false;
63
}
64
 
65
bool DDImage::Check3D(DDImage *theImage)
66
{
67
        return theImage->mDDInterface->mIs3D && theImage->mSurface==theImage->mDDInterface->mDrawSurface;
68
}
69
 
70
bool DDImage::LockSurface()
71
{
72
        if (Check3D(this))
73
                return false;
74
 
75
        if (mLockCount == 0)
76
        {
77
                memset(&mLockedSurfaceDesc, 0, sizeof(mLockedSurfaceDesc));
78
                mLockedSurfaceDesc.dwSize = sizeof(mLockedSurfaceDesc);
79
                int aResult = GetSurface()->Lock(NULL, &mLockedSurfaceDesc, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL);
80
 
81
                if (aResult != DD_OK)
82
                        return false;
83
        }
84
 
85
        mLockCount++;
86
 
87
        DBG_ASSERTE(mLockCount < 8);
88
 
89
        return true;
90
}
91
 
92
bool DDImage::UnlockSurface()
93
{
94
        if (Check3D(this))
95
                return false;
96
 
97
        --mLockCount;
98
 
99
        if (mLockCount == 0)
100
        {
101
                mSurface->Unlock(NULL);
102
        }
103
 
104
        DBG_ASSERTE(mLockCount >= 0);
105
 
106
        return true;
107
}
108
 
109
void DDImage::SetSurface(LPDIRECTDRAWSURFACE theSurface)
110
{
111
        mSurfaceSet = true;
112
        mSurface = theSurface;
113
        mSurface->AddRef();
114
 
115
//      TDDSurfaceDesc aDesc;
116
        DDSURFACEDESC aDesc;
117
        ZeroMemory(&aDesc, sizeof(aDesc));
118
        aDesc.dwSize = sizeof(aDesc);
119
    aDesc.dwFlags = DDSD_HEIGHT | DDSD_WIDTH;
120
    HRESULT aResult = mSurface->GetSurfaceDesc(&aDesc);
121
 
122
        mWidth = aDesc.dwWidth;
123
        mHeight = aDesc.dwHeight;
124
 
125
        mNoLock = false;
126
}
127
 
128
bool DDImage::GenerateDDSurface()
129
{
130
        if (mSurface != NULL)
131
                return true;   
132
 
133
        CommitBits();
134
 
135
        if (mHasAlpha)
136
                return false;
137
 
138
        mWantDDSurface = true;
139
 
140
        // Force into non-palletized mode for this
141
        if (mColorTable != NULL)
142
                GetBits();
143
 
144
        HRESULT aResult;
145
//      TDDSurfaceDesc aDesc;
146
        DDSURFACEDESC2 aDesc;
147
 
148
        ZeroMemory(&aDesc, sizeof(aDesc));
149
        aDesc.dwSize = sizeof(aDesc);
150
        aDesc.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
151
        aDesc.ddsCaps.dwCaps = mVideoMemory ? DDSCAPS_VIDEOMEMORY : DDSCAPS_SYSTEMMEMORY;
152
        aDesc.dwWidth = mWidth;
153
        aDesc.dwHeight = mHeight;
154
 
155
        AutoCrit aCrit(mDDInterface->mCritSect); // prevent mSurface from being released while we're in this code
156
 
157
        aResult = mDDInterface->CreateSurface(&aDesc, &mSurface, NULL);
158
        if (aResult != DD_OK)
159
                return false;
160
 
161
        if (!LockSurface())
162
                return false;
163
 
164
        const int rRightShift = 16 + (8-mDDInterface->mRedBits);
165
        const int gRightShift = 8 + (8-mDDInterface->mGreenBits);
166
        const int bRightShift = 0 + (8-mDDInterface->mBlueBits);
167
 
168
        const int rLeftShift = mDDInterface->mRedShift;
169
        const int gLeftShift = mDDInterface->mGreenShift;
170
        const int bLeftShift = mDDInterface->mBlueShift;
171
 
172
        const int rMask = mLockedSurfaceDesc.ddpfPixelFormat.dwRBitMask;
173
        const int gMask = mLockedSurfaceDesc.ddpfPixelFormat.dwGBitMask;
174
        const int bMask = mLockedSurfaceDesc.ddpfPixelFormat.dwBBitMask;
175
 
176
        int aNumBits = mLockedSurfaceDesc.ddpfPixelFormat.dwRGBBitCount;
177
 
178
        if (aNumBits == 16)
179
        {
180
                ushort* mSurfaceBits = (ushort*) mLockedSurfaceDesc.lpSurface;
181
 
182
                if (mSurfaceBits != NULL)
183
                {
184
                        int i;
185
                        bool firstTrans = true;                
186
 
187
                        ushort* a16Bits = NULL;
188
                        ushort aTransColor = 0;
189
 
190
                        if (mBits != NULL)
191
                        {
192
                                a16Bits = new ushort[mWidth*mHeight];
193
                                ulong* aSrcPtr = mBits;
194
                                ushort* a16SrcPtr = a16Bits;
195
 
196
                                for (i = 0; i < mWidth*mHeight; i++)
197
                                {                      
198
                                        ulong val = *(aSrcPtr++);
199
 
200
                                        *a16SrcPtr =    (((val>>rRightShift)<<rLeftShift)&rMask) |
201
                                                                        (((val>>gRightShift)<<gLeftShift)&gMask) |
202
                                                                        (((val>>bRightShift)<<bLeftShift)&bMask);
203
 
204
                                        int anAlpha = val >> 24;
205
                                        if ((firstTrans) && (anAlpha < 255))
206
                                        {
207
                                                firstTrans = false;
208
                                                aTransColor = *a16SrcPtr;
209
                                        }
210
 
211
                                        ++a16SrcPtr;
212
                                }
213
                        }
214
 
215
                        if ((mHasTrans) && (mBits != NULL))
216
                        {
217
                                if (mFirstPixelTrans)
218
                                {
219
                                        aTransColor = *a16Bits;
220
 
221
                                        if (a16Bits != NULL)
222
                                        {
223
                                                ushort* aDestPtr = mSurfaceBits;                                               
224
                                                ushort* a16SrcPtr = a16Bits;
225
                                                for (int aRow = 0; aRow < mHeight; aRow++)
226
                                                {
227
                                                        for (int aCol = 0; aCol < mWidth; aCol++)
228
                                                        {                                                                                                                              
229
                                                                *(aDestPtr++) = *a16SrcPtr;
230
                                                                ++a16SrcPtr;
231
                                                        }
232
 
233
                                                        aDestPtr += mLockedSurfaceDesc.lPitch/2 - mWidth;
234
                                                }
235
                                        }
236
                                }
237
                                else
238
                                {
239
                                        bool needNewColor = false;
240
                                        ulong* aSrcPtr = mBits;
241
                                        ushort* a16SrcPtr = a16Bits;
242
                                        for (i = 0; i < mWidth*mHeight; i++)
243
                                        {
244
                                                ulong val = *(aSrcPtr++);
245
                                                ushort a16Val = *(a16SrcPtr++);
246
 
247
                                                int anAlpha = val >> 24;
248
                                                if ((anAlpha == 255) && (aTransColor == a16Val))
249
                                                {
250
                                                        needNewColor = true;
251
                                                        break;
252
                                                }
253
                                        }
254
 
255
                                        if (needNewColor)
256
                                        {
257
                                                int* aUsedColorArray = new int[2048];
258
 
259
                                                ZeroMemory(aUsedColorArray, 2048*sizeof(int));                                 
260
 
261
                                                aSrcPtr = mBits;
262
                                                a16SrcPtr = a16Bits;
263
                                                for (i = 0; i < mWidth*mHeight; i++)
264
                                                {
265
                                                        ulong val = *(aSrcPtr++);
266
                                                        ushort a16Val = *(a16SrcPtr++);
267
 
268
                                                        int anAlpha = val >> 24;
269
                                                        if (anAlpha > 0)
270
                                                                aUsedColorArray[a16Val/32] |= (1<<(a16Val%32));                                        
271
                                                }
272
 
273
                                                bool done = false;
274
                                                for (int i = 0; i < 2048; i++)
275
                                                {
276
                                                        if (aUsedColorArray[i] != 0xFFFF)
277
                                                        {
278
                                                                for (int aBit = 0; aBit < 32; aBit++)                                                                                                          
279
                                                                {
280
                                                                        if ((aUsedColorArray[i] & (1<<aBit)) == 0)
281
                                                                        {
282
                                                                                aTransColor = i*32+aBit;
283
                                                                                break;
284
                                                                        }
285
                                                                }
286
                                                        }
287
 
288
                                                        if (done)
289
                                                                break;
290
                                                }
291
 
292
                                                delete aUsedColorArray;
293
                                        }
294
 
295
                                        if (mBits != NULL)
296
                                        {
297
                                                ushort* aDestPtr = mSurfaceBits;
298
                                                ulong* aSrcPtr = mBits;
299
                                                ushort* a16SrcPtr = a16Bits;
300
                                                for (int aRow = 0; aRow < mHeight; aRow++)
301
                                                {
302
                                                        for (int aCol = 0; aCol < mWidth; aCol++)
303
                                                        {
304
                                                                ulong val = *(aSrcPtr++);
305
 
306
                                                                //*(aDestPtr++) = 0xFF000000 |  ((val >> 24) & 0xFF);
307
 
308
                                                                int anAlpha = val >> 24;
309
                                                                if (anAlpha < 255)
310
                                                                        *(aDestPtr++) = aTransColor;
311
                                                                else
312
                                                                        *(aDestPtr++) = *a16SrcPtr;
313
 
314
                                                                ++a16SrcPtr;
315
                                                        }
316
 
317
                                                        aDestPtr += mLockedSurfaceDesc.lPitch/2 - mWidth;
318
                                                }
319
                                        }
320
                                }
321
                        }
322
                        else
323
                        {
324
                                if (a16Bits != NULL)
325
                                {
326
                                        ushort* aDestPtr = mSurfaceBits;                                               
327
                                        ushort* a16SrcPtr = a16Bits;
328
                                        for (int aRow = 0; aRow < mHeight; aRow++)
329
                                        {
330
                                                for (int aCol = 0; aCol < mWidth; aCol++)
331
                                                {                                                                                                                              
332
                                                        *(aDestPtr++) = *a16SrcPtr;
333
                                                        ++a16SrcPtr;
334
                                                }
335
 
336
                                                aDestPtr += mLockedSurfaceDesc.lPitch/2 - mWidth;
337
                                        }
338
                                }
339
                        }
340
 
341
                        delete a16Bits;
342
 
343
                        if (mHasTrans)
344
                        {
345
                                DDCOLORKEY aColorKey = {aTransColor, aTransColor};
346
                                mSurface->SetColorKey(DDCKEY_SRCBLT, &aColorKey);                              
347
                        }              
348
                }
349
        }
350
        else if (aNumBits == 32)
351
        {
352
                ulong* mSurfaceBits = (ulong*) mLockedSurfaceDesc.lpSurface;           
353
 
354
                if (mSurfaceBits != NULL)
355
                {
356
                        int i;
357
                        bool firstTrans = true;                                        
358
 
359
                        ulong aTransColor = 0;
360
 
361
                        if ((mHasTrans) && (mBits != NULL))
362
                        {
363
                                if (mFirstPixelTrans)
364
                                {
365
                                        ulong val = *mBits;
366
 
367
                                        aTransColor = (((val>>rRightShift)<<rLeftShift)&rMask) |
368
                                                                  (((val>>gRightShift)<<gLeftShift)&gMask) |
369
                                                                  (((val>>bRightShift)<<bLeftShift)&bMask);
370
 
371
                                        if (mBits != NULL)
372
                                        {
373
                                                ulong* aDestPtr = mSurfaceBits;
374
                                                ulong* aSrcPtr = mBits;
375
                                                for (int aRow = 0; aRow < mHeight; aRow++)
376
                                                {
377
                                                        for (int aCol = 0; aCol < mWidth; aCol++)
378
                                                        {                              
379
                                                                ulong val = *(aSrcPtr++);                                                              
380
 
381
                                                                *(aDestPtr++) =
382
                                                                                (((val>>rRightShift)<<rLeftShift)&rMask) |
383
                                                                                (((val>>gRightShift)<<gLeftShift)&gMask) |
384
                                                                                (((val>>bRightShift)<<bLeftShift)&bMask);
385
                                                        }
386
 
387
                                                        aDestPtr += mLockedSurfaceDesc.lPitch/4 - mWidth;
388
                                                }
389
                                        }
390
                                }
391
                                else
392
                                {
393
                                        ulong* aSrcPtr = mBits;
394
                                        for (i = 0; i < mWidth*mHeight; i++)
395
                                        {                      
396
                                                ulong val = *(aSrcPtr++);                              
397
 
398
                                                int anAlpha = val >> 24;
399
                                                if ((firstTrans) && (anAlpha < 255))
400
                                                {
401
                                                        firstTrans = false;
402
                                                        aTransColor = val;                                     
403
                                                }
404
                                        }
405
 
406
                                        bool needNewColor = false;
407
                                        aSrcPtr = mBits;
408
                                        for (i = 0; i < mWidth*mHeight; i++)
409
                                        {
410
                                                ulong val = *(aSrcPtr++);
411
 
412
                                                int anAlpha = val >> 24;
413
                                                if ((anAlpha == 255) && (aTransColor == (val & 0x00FFFFFF)))
414
                                                {
415
                                                        needNewColor = true;
416
                                                        break;
417
                                                }
418
                                        }
419
 
420
                                        if (needNewColor)
421
                                        {
422
                                                int* aUsedColorArray = new int[0x80000];
423
 
424
                                                ZeroMemory(aUsedColorArray, 0x80000*sizeof(int));                                      
425
 
426
                                                aSrcPtr = mBits;       
427
                                                for (i = 0; i < mWidth*mHeight; i++)
428
                                                {
429
                                                        ulong val = *(aSrcPtr++);                                              
430
 
431
                                                        int anAlpha = val >> 24;                                               
432
 
433
                                                        if (anAlpha > 0)
434
                                                                aUsedColorArray[(val & 0xFFFFFF)/32] |= (1<<(val%32));
435
                                                }
436
 
437
                                                bool done = false;
438
                                                for (int i = 0; i < 0x80000; i++)
439
                                                {
440
                                                        if (aUsedColorArray[i] != 0xFFFF)                                              
441
                                                        {
442
                                                                for (int aBit = 0; aBit < 32; aBit++)                                                                                                          
443
                                                                {
444
                                                                        if ((aUsedColorArray[i] & (1<<aBit)) == 0)                                                             
445
                                                                        {
446
                                                                                aTransColor = i*32+aBit;                                                       
447
                                                                                done = true;
448
                                                                                break;
449
                                                                        }
450
                                                                }
451
                                                        }
452
 
453
                                                        if (done)
454
                                                                break;
455
                                                }                                              
456
 
457
                                                delete aUsedColorArray;
458
                                        }
459
 
460
                                        if (mBits != NULL)
461
                                        {
462
                                                ulong* aDestPtr = mSurfaceBits;
463
                                                ulong* aSrcPtr = mBits;
464
                                                for (int aRow = 0; aRow < mHeight; aRow++)
465
                                                {
466
                                                        for (int aCol = 0; aCol < mWidth; aCol++)
467
                                                        {                              
468
                                                                ulong val = *(aSrcPtr++);
469
 
470
                                                                //*(aDestPtr++) = 0xFF000000 |  ((val >> 24) & 0xFF);
471
 
472
                                                                int anAlpha = val >> 24;
473
                                                                if (anAlpha < 255)
474
                                                                        *(aDestPtr++) = aTransColor;
475
                                                                else
476
                                                                {
477
                                                                        *(aDestPtr++) =
478
                                                                                                (((val>>rRightShift)<<rLeftShift)&rMask) |
479
                                                                                                (((val>>gRightShift)<<gLeftShift)&gMask) |
480
                                                                                                (((val>>bRightShift)<<bLeftShift)&bMask);
481
                                                                }
482
                                                        }
483
 
484
                                                        aDestPtr += mLockedSurfaceDesc.lPitch/4 - mWidth;
485
                                                }
486
                                        }
487
                                }
488
 
489
                                DDCOLORKEY aColorKey = {aTransColor, aTransColor};
490
                                mSurface->SetColorKey(DDCKEY_SRCBLT, &aColorKey);
491
                        }
492
                        else
493
                        {
494
                                if (mBits != NULL)
495
                                {
496
                                        ulong* aDestPtr = mSurfaceBits;
497
                                        ulong* aSrcPtr = mBits;
498
                                        for (int aRow = 0; aRow < mHeight; aRow++)
499
                                        {
500
                                                for (int aCol = 0; aCol < mWidth; aCol++)
501
                                                {                              
502
                                                        ulong val = *(aSrcPtr++);                                      
503
 
504
                                                        *(aDestPtr++) =
505
                                                                                (((val>>rRightShift)<<rLeftShift)&rMask) |
506
                                                                                (((val>>gRightShift)<<gLeftShift)&gMask) |
507
                                                                                (((val>>bRightShift)<<bLeftShift)&bMask);
508
                                                }
509
 
510
                                                aDestPtr += mLockedSurfaceDesc.lPitch/4 - mWidth;
511
                                        }
512
                                }
513
                        }
514
                }
515
        }
516
        else
517
        {
518
                return false;
519
        }
520
 
521
        UnlockSurface();
522
 
523
        return true;
524
}
525
 
526
void DDImage::DeleteDDSurface()
527
{
528
        if (mSurface != NULL)
529
        {
530
                if ((mColorTable == NULL) && (mBits == NULL) && (mD3DData == NULL))
531
                        GetBits();
532
 
533
                mSurface->Release();
534
                mSurface = NULL;
535
        }
536
}
537
 
538
void DDImage::ReInit()
539
{
540
        MemoryImage::ReInit();
541
 
542
        if (mWantDDSurface)
543
                GenerateDDSurface();
544
}
545
 
546
void DDImage::PurgeBits()
547
{
548
        if (mSurfaceSet)
549
                return;
550
 
551
        mPurgeBits = true;
552
 
553
        CommitBits();
554
 
555
        if (!mApp->Is3DAccelerated())
556
        {
557
                if ((mWantDDSurface) && (GenerateDDSurface()))
558
                {                        
559
                        delete [] mBits;
560
                        mBits = NULL;
561
 
562
                        delete [] mColorIndices;
563
                        mColorIndices = NULL;
564
 
565
                        delete [] mColorTable;
566
                        mColorTable = NULL;                        
567
 
568
                        return;
569
                }      
570
        }
571
        else // Accelerated
572
        {
573
                if (mSurface != NULL)
574
                {
575
                        GetBits();
576
                        DeleteDDSurface();
577
                }
578
        }
579
 
580
        MemoryImage::PurgeBits();
581
}
582
 
583
void DDImage::DeleteAllNonSurfaceData()
584
{
585
        delete [] mBits;
586
        mBits = NULL;
587
 
588
        delete [] mNativeAlphaData;
589
        mNativeAlphaData = NULL;
590
 
591
        delete [] mRLAdditiveData;
592
        mRLAdditiveData = NULL;
593
 
594
        delete [] mRLAlphaData;
595
        mRLAlphaData = NULL;
596
 
597
        delete [] mColorTable;
598
        mColorTable = NULL;
599
 
600
        delete [] mColorIndices;
601
        mColorIndices = NULL;
602
}
603
 
604
void DDImage::DeleteNativeData()
605
{
606
        if (mSurfaceSet)
607
                return;
608
 
609
        MemoryImage::DeleteNativeData();
610
        DeleteDDSurface();
611
}
612
 
613
void DDImage::DeleteExtraBuffers()
614
{
615
        if (mSurfaceSet)
616
                return;
617
 
618
        MemoryImage::DeleteExtraBuffers();
619
        DeleteDDSurface();
620
}
621
 
622
void DDImage::SetVideoMemory(bool wantVideoMemory)
623
{
624
        if (wantVideoMemory != mVideoMemory)
625
        {              
626
                mVideoMemory = wantVideoMemory;
627
 
628
                // Make sure that we have the bits
629
                GetBits();
630
 
631
                DeleteDDSurface();
632
        }
633
}
634
 
635
void DDImage::RehupFirstPixelTrans()
636
{
637
        if (!GenerateDDSurface())
638
                return;
639
 
640
        if ((mNoLock) || (!mHasTrans) || (!mFirstPixelTrans))
641
                return;
642
 
643
//      TDDSurfaceDesc aDesc;
644
        DDSURFACEDESC aDesc;
645
 
646
        ZeroMemory(&aDesc, sizeof(aDesc));
647
        aDesc.dwSize = sizeof(aDesc);
648
    aDesc.dwFlags = DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
649
    HRESULT aResult = mDDInterface->mPrimarySurface->GetSurfaceDesc(&aDesc);
650
        if (FAILED(aResult))
651
                return;
652
 
653
        int aNumBits = aDesc.ddpfPixelFormat.dwRGBBitCount;
654
 
655
        if (aNumBits == 16)
656
        {
657
                if (!LockSurface())
658
                        return;
659
 
660
                ushort* aSurfaceBits = (ushort*) mLockedSurfaceDesc.lpSurface; 
661
 
662
                ushort aTransColor = *aSurfaceBits;
663
 
664
                DDCOLORKEY aColorKey = {aTransColor, aTransColor};
665
                mSurface->SetColorKey(DDCKEY_SRCBLT, &aColorKey);      
666
 
667
                UnlockSurface();
668
        }
669
        else if ((aNumBits == 24) || (aNumBits == 32))
670
        {
671
                if (!LockSurface())
672
                        return;
673
 
674
                ulong* aSurfaceBits = (ulong*) mLockedSurfaceDesc.lpSurface;           
675
 
676
                ulong aTransColor = *aSurfaceBits;
677
 
678
                DDCOLORKEY aColorKey = {aTransColor, aTransColor};
679
                mSurface->SetColorKey(DDCKEY_SRCBLT, &aColorKey);              
680
 
681
                UnlockSurface();
682
        }
683
}
684
 
685
LPDIRECTDRAWSURFACE DDImage::GetSurface()
686
{
687
        //TODO: Log if generate surface fails
688
 
689
        if (mSurface == NULL)
690
                GenerateDDSurface();
691
 
692
        return mSurface;
693
}
694
 
695
bool DDImage::PolyFill3D(const Point theVertices[], int theNumVertices, const Rect *theClipRect, const Color &theColor, int theDrawMode, int tx, int ty, bool convex)
696
{
697
        if (Check3D(this))
698
        {
699
                mDDInterface->mD3DInterface->FillPoly(theVertices,theNumVertices,theClipRect,theColor,theDrawMode,tx,ty);
700
                return true;
701
        }
702
        else
703
                return false;
704
}
705
 
706
void DDImage::FillRect(const Rect& theRect, const Color& theColor, int theDrawMode)
707
{
708
        if (Check3D(this))
709
        {
710
                mDDInterface->mD3DInterface->FillRect(theRect,theColor,theDrawMode);
711
                return;
712
        }
713
 
714
        CommitBits();
715
        if ((mDrawToBits) || (mHasAlpha) || ((mHasTrans) && (!mFirstPixelTrans)) || (mDDInterface->mIs3D))
716
        {
717
                MemoryImage::FillRect(theRect, theColor, theDrawMode);
718
                return;
719
        }      
720
 
721
        switch (theDrawMode)
722
        {
723
        case Graphics::DRAWMODE_NORMAL:
724
                NormalFillRect(theRect, theColor);
725
                break;
726
        case Graphics::DRAWMODE_ADDITIVE:
727
                AdditiveFillRect(theRect, theColor);
728
                break;
729
        }
730
 
731
        DeleteAllNonSurfaceData();
732
}
733
 
734
void DDImage::NormalDrawLine(double theStartX, double theStartY, double theEndX, double theEndY, const Color& theColor)
735
{
736
        if (mNoLock)
737
                return;
738
 
739
        double aMinX = min(theStartX, theEndX);
740
        double aMinY = min(theStartY, theEndY);
741
        double aMaxX = max(theStartX, theEndX);
742
        double aMaxY = max(theStartY, theEndY);
743
 
744
        LPDIRECTDRAWSURFACE aSurface = GetSurface();
745
 
746
        if (!LockSurface())
747
                return;
748
 
749
        ulong aRMask = mLockedSurfaceDesc.ddpfPixelFormat.dwRBitMask;
750
        ulong aGMask = mLockedSurfaceDesc.ddpfPixelFormat.dwGBitMask;
751
        ulong aBMask = mLockedSurfaceDesc.ddpfPixelFormat.dwBBitMask;
752
 
753
        ulong aRRoundAdd = aRMask >> 1;
754
        ulong aGRoundAdd = aGMask >> 1;
755
        ulong aBRoundAdd = aBMask >> 1;
756
 
757
        if (mLockedSurfaceDesc.ddpfPixelFormat.dwRGBBitCount == 16)
758
        {
759
                if (theColor.mAlpha == 255)
760
                {
761
                        ushort aColor = (ushort)
762
                                (((((theColor.mRed * aRMask) + aRRoundAdd) >> 8) & aRMask) |
763
                                ((((theColor.mGreen * aGMask) + aGRoundAdd) >> 8) & aGMask) |
764
                                ((((theColor.mBlue * aBMask) + aBRoundAdd) >> 8) & aBMask));
765
 
766
                        double dv = theEndY - theStartY;
767
                        double dh = theEndX - theStartX;
768
                        int minG, maxG, G, DeltaG1, DeltaG2;
769
                        double swap;
770
                        int inc = 1;
771
                        int aCurX;
772
                        int aCurY;
773
                        int aRowWidth = mLockedSurfaceDesc.lPitch/2;
774
                        int aRowAdd = aRowWidth;
775
 
776
                        if (fabs(dv) < fabs(dh))
777
                        {
778
                                // Mostly horizontal
779
                                if (dh < 0)
780
                                {
781
                                        dh = -dh;
782
                                        dv = -dv;
783
                                        swap = theEndY;
784
                                        theEndY = theStartY;
785
                                        theStartY = swap;
786
                                        swap = theEndX;
787
                                        theEndX = theStartX;
788
                                        theStartX = swap;
789
                                }
790
                                if (dv < 0)
791
                                {
792
                                        dv = -dv;
793
                                        inc = -1;
794
                                        aRowAdd = -aRowAdd;
795
                                }
796
 
797
                                ushort* aDestPixels = ((ushort*) mLockedSurfaceDesc.lpSurface) + ((int) theStartY * aRowWidth) + (int) theStartX;
798
                                *aDestPixels = aColor;
799
                                aDestPixels++;
800
 
801
                                aCurY = (int) theStartY;
802
                                aCurX = (int) theStartX + 1;
803
 
804
                                G = 2 * dv - dh;
805
                                DeltaG1 = 2 * (dv - dh);
806
                                DeltaG2 = 2 * dv;
807
 
808
                                G += DeltaG2 * (theStartY - (int) theStartY);
809
 
810
                                while (aCurX <= theEndX)
811
                                {
812
                                        if (G > 0)
813
                                        {
814
                                                G += DeltaG1;
815
                                                aCurY += inc;
816
                                                aDestPixels += aRowAdd;
817
 
818
                                                if (aCurX<aMinX || aCurY<aMinY || aCurX>aMaxX || aCurY>aMaxY)
819
                                                        break;
820
                                        }
821
                                        else
822
                                                G += DeltaG2;
823
 
824
                                        *aDestPixels = aColor;
825
 
826
                                        aCurX++;
827
                                        aDestPixels++;
828
                                }
829
                        }
830
                        else
831
                        {
832
                                // Mostly vertical
833
                                if ( dv < 0 )
834
                                {
835
                                        dh = -dh;
836
                                        dv = -dv;
837
                                        swap = theEndY;
838
                                        theEndY = theStartY;
839
                                        theStartY = swap;
840
                                        swap = theEndX;
841
                                        theEndX = theStartX;
842
                                        theStartX = swap;
843
                                }
844
 
845
                                if (dh < 0)
846
                                {
847
                                        dh = -dh;
848
                                        inc = -1;
849
                                }
850
 
851
                                ushort* aDestPixels = ((ushort*) mLockedSurfaceDesc.lpSurface) + ((int) theStartY * mLockedSurfaceDesc.lPitch/2) + (int) theStartX;
852
                                *aDestPixels = aColor;
853
                                aDestPixels += aRowAdd;
854
 
855
                                aCurX = theStartX;
856
                                aCurY = theStartY + 1;
857
 
858
                                G = 2 * dh - dv;
859
                                minG = maxG = G;
860
                                DeltaG1 = 2 * ( dh - dv );
861
                                DeltaG2 = 2 * dh;
862
 
863
                                G += DeltaG2 * (theStartX - (int) theStartX);
864
 
865
                                while (aCurY <= theEndY)
866
                                {
867
                                        if ( G > 0 )
868
                                        {                                              
869
                                                G += DeltaG1;
870
                                                aCurX += inc;
871
                                                aDestPixels += inc;
872
 
873
                                                if (aCurX<aMinX || aCurY<aMinY || aCurX>aMaxX || aCurY>aMaxY)
874
                                                        break;
875
                                        }
876
                                        else
877
                                                G += DeltaG2;
878
 
879
                                        *aDestPixels = aColor;
880
 
881
                                        aCurY++;
882
                                        aDestPixels += aRowAdd;
883
                                }
884
                        }
885
                }
886
                else
887
                {
888
                        ushort src =
889
                                ((((((theColor.mRed * theColor.mAlpha + 0x80) >> 8) * aRMask) + aRRoundAdd) >> 8) & aRMask) +
890
                                ((((((theColor.mGreen * theColor.mAlpha + 0x80) >> 8) * aGMask) + aGRoundAdd) >> 8) & aGMask) +
891
                                ((((((theColor.mBlue * theColor.mAlpha + 0x80) >> 8) * aBMask) + aBRoundAdd) >> 8) & aBMask);
892
                        int oma = 256 - theColor.mAlpha;
893
 
894
                        double dv = theEndY - theStartY;
895
                        double dh = theEndX - theStartX;
896
                        int minG, maxG, G, DeltaG1, DeltaG2;
897
                        double swap;
898
                        int inc = 1;
899
                        int aCurX;
900
                        int aCurY;
901
                        int aRowWidth = mLockedSurfaceDesc.lPitch/2;
902
                        int aRowAdd = aRowWidth;
903
 
904
                        if (abs(dv) < abs(dh))
905
                        {
906
                                // Mostly horizontal
907
                                if (dh < 0)
908
                                {
909
                                        dh = -dh;
910
                                        dv = -dv;
911
                                        swap = theEndY;
912
                                        theEndY = theStartY;
913
                                        theStartY = swap;
914
                                        swap = theEndX;
915
                                        theEndX = theStartX;
916
                                        theStartX = swap;
917
                                }
918
                                if (dv < 0)
919
                                {
920
                                        dv = -dv;
921
                                        inc = -1;
922
                                        aRowAdd = -aRowAdd;
923
                                }
924
 
925
                                ushort* aDestPixels = ((ushort*) mLockedSurfaceDesc.lpSurface) + ((int) theStartY * aRowWidth) + (int) theStartX;
926
                                ushort dest = *aDestPixels;
927
                                *(aDestPixels++) = src +
928
                                        (((((dest & aRMask) * oma) + aRRoundAdd) >> 8) & aRMask) +
929
                                        (((((dest & aGMask) * oma) + aGRoundAdd) >> 8) & aGMask) +
930
                                        (((((dest & aBMask) * oma) + aBRoundAdd) >> 8) & aBMask);                              
931
 
932
                                aCurY = theStartY;
933
                                aCurX = theStartX + 1;
934
 
935
                                G = 2 * dv - dh;
936
                                DeltaG1 = 2 * (dv - dh);
937
                                DeltaG2 = 2 * dv;
938
 
939
                                G += DeltaG2 * (theStartY - (int) theStartY);
940
 
941
                                while (aCurX <= theEndX)
942
                                {
943
                                        if (G > 0)
944
                                        {
945
                                                G += DeltaG1;
946
                                                aCurY += inc;
947
                                                aDestPixels += aRowAdd;
948
 
949
                                                if (aCurX<aMinX || aCurY<aMinY || aCurX>aMaxX || aCurY>aMaxY)
950
                                                        break;
951
                                        }
952
                                        else
953
                                                G += DeltaG2;
954
 
955
                                        dest = *aDestPixels;
956
                                        *(aDestPixels++) = src +
957
                                                (((((dest & aRMask) * oma) + aRRoundAdd) >> 8) & aRMask) +
958
                                                (((((dest & aGMask) * oma) + aGRoundAdd) >> 8) & aGMask) +
959
                                                (((((dest & aBMask) * oma) + aBRoundAdd) >> 8) & aBMask);                                      
960
 
961
                                        aCurX++;                                       
962
                                }
963
                        }
964
                        else
965
                        {
966
                                // Mostly vertical
967
                                if ( dv < 0 )
968
                                {
969
                                        dh = -dh;
970
                                        dv = -dv;
971
                                        swap = theEndY;
972
                                        theEndY = theStartY;
973
                                        theStartY = swap;
974
                                        swap = theEndX;
975
                                        theEndX = theStartX;
976
                                        theStartX = swap;
977
                                }
978
 
979
                                if (dh < 0)
980
                                {
981
                                        dh = -dh;
982
                                        inc = -1;
983
                                }
984
 
985
                                ushort* aDestPixels = ((ushort*) mLockedSurfaceDesc.lpSurface) + ((int) theStartY * mLockedSurfaceDesc.lPitch/2) + (int) theStartX;
986
                                ushort dest = *aDestPixels;
987
                                *aDestPixels = src +
988
                                        (((((dest & aRMask) * oma) + aRRoundAdd) >> 8) & aRMask) +
989
                                        (((((dest & aGMask) * oma) + aGRoundAdd) >> 8) & aGMask) +
990
                                        (((((dest & aBMask) * oma) + aBRoundAdd) >> 8) & aBMask);
991
                                aDestPixels += aRowAdd;
992
 
993
                                aCurX = theStartX;
994
                                aCurY = theStartY + 1;
995
 
996
                                G = 2 * dh - dv;
997
                                minG = maxG = G;
998
                                DeltaG1 = 2 * ( dh - dv );
999
                                DeltaG2 = 2 * dh;
1000
 
1001
                                G += DeltaG2 * (theStartX - (int) theStartX);
1002
 
1003
                                while (aCurY <= theEndY)
1004
                                {
1005
                                        if ( G > 0 )
1006
                                        {
1007
                                                G += DeltaG1;
1008
                                                aCurX += inc;
1009
                                                aDestPixels += inc;
1010
 
1011
                                                if (aCurX<aMinX || aCurY<aMinY || aCurX>aMaxX || aCurY>aMaxY)
1012
                                                        break;
1013
                                        }
1014
                                        else
1015
                                                G += DeltaG2;
1016
 
1017
                                        dest = *aDestPixels;
1018
                                        *aDestPixels = src +
1019
                                                (((((dest & aRMask) * oma) + aRRoundAdd) >> 8) & aRMask) +
1020
                                                (((((dest & aGMask) * oma) + aGRoundAdd) >> 8) & aGMask) +
1021
                                                (((((dest & aBMask) * oma) + aBRoundAdd) >> 8) & aBMask);
1022
 
1023
                                        aCurY++;
1024
                                        aDestPixels += aRowAdd;
1025
                                }
1026
                        }
1027
                }
1028
        }
1029
        else if (mLockedSurfaceDesc.ddpfPixelFormat.dwRGBBitCount == 32)
1030
        {
1031
                if (theColor.mAlpha == 255)
1032
                {
1033
                        ulong aColor =
1034
                                ((((theColor.mRed * aRMask) + aRRoundAdd) >> 8) & aRMask) |
1035
                                ((((theColor.mGreen * aGMask) + aGRoundAdd) >> 8) & aGMask) |
1036
                                ((((theColor.mBlue * aBMask) + aBRoundAdd) >> 8) & aBMask);
1037
 
1038
                        double dv = theEndY - theStartY;
1039
                        double dh = theEndX - theStartX;
1040
                        int minG, maxG, G, DeltaG1, DeltaG2;
1041
                        double swap;
1042
                        int inc = 1;
1043
                        int aCurX;
1044
                        int aCurY;
1045
                        int aRowWidth = mLockedSurfaceDesc.lPitch/4;
1046
                        int aRowAdd = aRowWidth;;
1047
 
1048
                        if (abs(dv) < abs(dh))
1049
                        {
1050
                                // Mostly horizontal
1051
                                if (dh < 0)
1052
                                {
1053
                                        dh = -dh;
1054
                                        dv = -dv;
1055
                                        swap = theEndY;
1056
                                        theEndY = theStartY;
1057
                                        theStartY = swap;
1058
                                        swap = theEndX;
1059
                                        theEndX = theStartX;
1060
                                        theStartX = swap;
1061
                                }
1062
                                if (dv < 0)
1063
                                {
1064
                                        dv = -dv;
1065
                                        inc = -1;
1066
                                        aRowAdd = -aRowAdd;
1067
                                }
1068
 
1069
                                ulong* aDestPixels = ((ulong*) mLockedSurfaceDesc.lpSurface) + ((int) theStartY * aRowWidth) + (int) theStartX;
1070
                                *aDestPixels = aColor;
1071
                                aDestPixels++;
1072
 
1073
                                aCurY = theStartY;
1074
                                aCurX = theStartX + 1;
1075
 
1076
                                G = 2 * dv - dh;
1077
                                DeltaG1 = 2 * (dv - dh);
1078
                                DeltaG2 = 2 * dv;
1079
 
1080
                                G += DeltaG2 * (theStartY - (int) theStartY);
1081
 
1082
                                while (aCurX <= theEndX)
1083
                                {
1084
                                        if (G > 0)
1085
                                        {
1086
                                                G += DeltaG1;
1087
                                                aCurY += inc;
1088
                                                aDestPixels += aRowAdd;
1089
 
1090
                                                if (aCurX<aMinX || aCurY<aMinY || aCurX>aMaxX || aCurY>aMaxY)
1091
                                                        break;
1092
                                        }
1093
                                        else
1094
                                                G += DeltaG2;
1095
 
1096
                                        *aDestPixels = aColor;
1097
 
1098
                                        aCurX++;
1099
                                        aDestPixels++;
1100
                                }
1101
                        }
1102
                        else
1103
                        {
1104
                                // Mostly vertical
1105
                                if ( dv < 0 )
1106
                                {
1107
                                        dh = -dh;
1108
                                        dv = -dv;
1109
                                        swap = theEndY;
1110
                                        theEndY = theStartY;
1111
                                        theStartY = swap;
1112
                                        swap = theEndX;
1113
                                        theEndX = theStartX;
1114
                                        theStartX = swap;
1115
                                }
1116
 
1117
                                if (dh < 0)
1118
                                {
1119
                                        dh = -dh;
1120
                                        inc = -1;
1121
                                }
1122
 
1123
                                ulong* aDestPixels = ((ulong*) mLockedSurfaceDesc.lpSurface) + ((int) theStartY * aRowWidth) + (int) theStartX;
1124
                                *aDestPixels = aColor;
1125
                                aDestPixels += aRowAdd;
1126
 
1127
                                aCurX = theStartX;
1128
                                aCurY = theStartY + 1;
1129
 
1130
                                G = 2 * dh - dv;
1131
                                minG = maxG = G;
1132
                                DeltaG1 = 2 * ( dh - dv );
1133
                                DeltaG2 = 2 * dh;
1134
 
1135
                                G += DeltaG2 * (theStartX - (int) theStartX);
1136
 
1137
                                while (aCurY <= theEndY)
1138
                                {
1139
                                        if ( G > 0 )
1140
                                        {
1141
                                                G += DeltaG1;
1142
                                                aCurX += inc;
1143
                                                aDestPixels += inc;
1144
 
1145
                                                if (aCurX<aMinX || aCurY<aMinY || aCurX>aMaxX || aCurY>aMaxY)
1146
                                                        break;
1147
                                        }
1148
                                        else
1149
                                                G += DeltaG2;
1150
 
1151
                                        *aDestPixels = aColor;
1152
 
1153
                                        aCurY++;
1154
                                        aDestPixels += aRowAdd;
1155
                                }
1156
                        }
1157
                }
1158
                else
1159
                {
1160
                        ulong src =
1161
                                ((((((theColor.mRed * theColor.mAlpha + 0x80) >> 8) * aRMask) + aRRoundAdd) >> 8) & aRMask) +
1162
                                ((((((theColor.mGreen * theColor.mAlpha + 0x80) >> 8) * aGMask) + aGRoundAdd) >> 8) & aGMask) +
1163
                                ((((((theColor.mBlue * theColor.mAlpha + 0x80) >> 8) * aBMask) + aBRoundAdd) >> 8) & aBMask);
1164
                        int oma = 256 - theColor.mAlpha;
1165
 
1166
                        double dv = theEndY - theStartY;
1167
                        double dh = theEndX - theStartX;
1168
                        int minG, maxG, G, DeltaG1, DeltaG2;
1169
                        double swap;
1170
                        int inc = 1;
1171
                        int aCurX;
1172
                        int aCurY;
1173
                        int aRowWidth = mLockedSurfaceDesc.lPitch/4;
1174
                        int aRowAdd = aRowWidth;
1175
 
1176
                        if (abs(dv) < abs(dh))
1177
                        {
1178
                                // Mostly horizontal
1179
                                if (dh < 0)
1180
                                {
1181
                                        dh = -dh;
1182
                                        dv = -dv;
1183
                                        swap = theEndY;
1184
                                        theEndY = theStartY;
1185
                                        theStartY = swap;
1186
                                        swap = theEndX;
1187
                                        theEndX = theStartX;
1188
                                        theStartX = swap;
1189
                                }
1190
                                if (dv < 0)
1191
                                {
1192
                                        dv = -dv;
1193
                                        inc = -1;
1194
                                        aRowAdd = -aRowAdd;
1195
                                }
1196
 
1197
                                ulong* aDestPixels = ((ulong*) mLockedSurfaceDesc.lpSurface) + ((int) theStartY * aRowWidth) + (int) theStartX;
1198
                                ulong dest = *aDestPixels;
1199
                                *(aDestPixels++) = src +
1200
                                        (((((dest & aRMask) * oma) + aRRoundAdd) >> 8) & aRMask) +
1201
                                        (((((dest & aGMask) * oma) + aGRoundAdd) >> 8) & aGMask) +
1202
                                        (((((dest & aBMask) * oma) + aBRoundAdd) >> 8) & aBMask);                              
1203
 
1204
                                aCurY = theStartY;
1205
                                aCurX = theStartX + 1;
1206
 
1207
                                G = 2 * dv - dh;
1208
                                DeltaG1 = 2 * (dv - dh);
1209
                                DeltaG2 = 2 * dv;
1210
 
1211
                                G += DeltaG2 * (theStartX - (int) theStartX);
1212
 
1213
                                while (aCurX <= theEndX)
1214
                                {
1215
                                        if (G > 0)
1216
                                        {
1217
                                                G += DeltaG1;
1218
                                                aCurY += inc;
1219
                                                aDestPixels += aRowAdd;
1220
 
1221
                                                if (aCurX<aMinX || aCurY<aMinY || aCurX>aMaxX || aCurY>aMaxY)
1222
                                                        break;
1223
                                        }
1224
                                        else
1225
                                                G += DeltaG2;
1226
 
1227
                                        dest = *aDestPixels;
1228
                                        *(aDestPixels++) = src +
1229
                                                (((((dest & aRMask) * oma) + aRRoundAdd) >> 8) & aRMask) +
1230
                                                (((((dest & aGMask) * oma) + aGRoundAdd) >> 8) & aGMask) +
1231
                                                (((((dest & aBMask) * oma) + aBRoundAdd) >> 8) & aBMask);                                      
1232
 
1233
                                        aCurX++;                                       
1234
                                }
1235
                        }
1236
                        else
1237
                        {
1238
                                // Mostly vertical
1239
                                if ( dv < 0 )
1240
                                {
1241
                                        dh = -dh;
1242
                                        dv = -dv;
1243
                                        swap = theEndY;
1244
                                        theEndY = theStartY;
1245
                                        theStartY = swap;
1246
                                        swap = theEndX;
1247
                                        theEndX = theStartX;
1248
                                        theStartX = swap;
1249
                                }
1250
 
1251
                                if (dh < 0)
1252
                                {
1253
                                        dh = -dh;
1254
                                        inc = -1;
1255
                                }
1256
 
1257
                                ulong* aDestPixels = ((ulong*) mLockedSurfaceDesc.lpSurface) + ((int) theStartY * aRowWidth) + (int) theStartX;
1258
                                ulong dest = *aDestPixels;
1259
                                *aDestPixels = src +
1260
                                        (((((dest & aRMask) * oma) + aRRoundAdd) >> 8) & aRMask) +
1261
                                        (((((dest & aGMask) * oma) + aGRoundAdd) >> 8) & aGMask) +
1262
                                        (((((dest & aBMask) * oma) + aBRoundAdd) >> 8) & aBMask);
1263
                                aDestPixels += aRowAdd;
1264
 
1265
                                aCurX = theStartX;
1266
                                aCurY = theStartY + 1;
1267
 
1268
                                G = 2 * dh - dv;
1269
                                minG = maxG = G;
1270
                                DeltaG1 = 2 * ( dh - dv );
1271
                                DeltaG2 = 2 * dh;
1272
 
1273
                                G += DeltaG2 * (theStartX - (int) theStartX);
1274
 
1275
                                while (aCurY <= theEndY)
1276
                                {
1277
                                        if ( G > 0 )
1278
                                        {
1279
                                                G += DeltaG1;
1280
                                                aCurX += inc;
1281
                                                aDestPixels += inc;
1282
 
1283
                                                if (aCurX<aMinX || aCurY<aMinY || aCurX>aMaxX || aCurY>aMaxY)
1284
                                                        break;
1285
                                        }
1286
                                        else
1287
                                                G += DeltaG2;
1288
 
1289
                                        dest = *aDestPixels;
1290
                                        *aDestPixels = src +
1291
                                                (((((dest & aRMask) * oma) + aRRoundAdd) >> 8) & aRMask) +
1292
                                                (((((dest & aGMask) * oma) + aGRoundAdd) >> 8) & aGMask) +
1293
                                                (((((dest & aBMask) * oma) + aBRoundAdd) >> 8) & aBMask);
1294
 
1295
                                        aCurY++;
1296
                                        aDestPixels += aRowAdd;
1297
                                }
1298
                        }
1299
                }
1300
        }
1301
 
1302
        UnlockSurface();
1303
}
1304
 
1305
void DDImage::AdditiveDrawLine(double theStartX, double theStartY, double theEndX, double theEndY, const Color& theColor)
1306
{
1307
        if (mNoLock)
1308
                return;
1309
 
1310
        double aMinX = min(theStartX, theEndX);
1311
        double aMinY = min(theStartY, theEndY);
1312
        double aMaxX = max(theStartX, theEndX);
1313
        double aMaxY = max(theStartY, theEndY);
1314
 
1315
        LPDIRECTDRAWSURFACE aSurface = GetSurface();
1316
 
1317
        if (!LockSurface())
1318
                return;
1319
 
1320
        ulong aRMask = mLockedSurfaceDesc.ddpfPixelFormat.dwRBitMask;
1321
        ulong aGMask = mLockedSurfaceDesc.ddpfPixelFormat.dwGBitMask;
1322
        ulong aBMask = mLockedSurfaceDesc.ddpfPixelFormat.dwBBitMask;
1323
 
1324
        ulong aRRoundAdd = aRMask >> 1;
1325
        ulong aGRoundAdd = aGMask >> 1;
1326
        ulong aBRoundAdd = aBMask >> 1;
1327
 
1328
        int aRedShift = mDDInterface->mRedShift;
1329
        int aGreenShift = mDDInterface->mGreenShift;
1330
        int aBlueShift = mDDInterface->mBlueShift;
1331
 
1332
        int* aMaxRedTable = mDDInterface->mRedAddTable;
1333
        int* aMaxGreenTable = mDDInterface->mGreenAddTable;
1334
        int* aMaxBlueTable = mDDInterface->mBlueAddTable;
1335
 
1336
        if (mLockedSurfaceDesc.ddpfPixelFormat.dwRGBBitCount == 16)
1337
        {
1338
                ushort rc = ((theColor.mRed * theColor.mAlpha) / 255) >> (8-mDDInterface->mRedBits);
1339
                ushort gc = ((theColor.mGreen * theColor.mAlpha) / 255) >> (8-mDDInterface->mGreenBits);
1340
                ushort bc = ((theColor.mBlue * theColor.mAlpha) / 255) >> (8-mDDInterface->mBlueBits);
1341
 
1342
                double dv = theEndY - theStartY;
1343
                double dh = theEndX - theStartX;
1344
                int minG, maxG, G, DeltaG1, DeltaG2;
1345
                double swap;
1346
                int inc = 1;
1347
                int aCurX;
1348
                int aCurY;
1349
                int aRowWidth = mLockedSurfaceDesc.lPitch/2;
1350
                int aRowAdd = aRowWidth;
1351
 
1352
                if (abs(dv) < abs(dh))
1353
                {
1354
                        // Mostly horizontal
1355
                        if (dh < 0)
1356
                        {
1357
                                dh = -dh;
1358
                                dv = -dv;
1359
                                swap = theEndY;
1360
                                theEndY = theStartY;
1361
                                theStartY = swap;
1362
                                swap = theEndX;
1363
                                theEndX = theStartX;
1364
                                theStartX = swap;
1365
                        }
1366
                        if (dv < 0)
1367
                        {
1368
                                dv = -dv;
1369
                                inc = -1;
1370
                                aRowAdd = -aRowAdd;
1371
                        }
1372
 
1373
                        ushort* aDestPixels = ((ushort*) mLockedSurfaceDesc.lpSurface) + ((int) theStartY * aRowWidth) + (int) theStartX;
1374
                        ushort dest = *aDestPixels;
1375
 
1376
                        int r = aMaxRedTable[((dest & aRMask) >> aRedShift) + rc];
1377
                        int g = aMaxGreenTable[((dest & aGMask) >> aGreenShift) + gc];
1378
                        int b = aMaxBlueTable[((dest & aBMask) >> aBlueShift) + bc];
1379
 
1380
                        *(aDestPixels++) =
1381
                                (r << aRedShift) |
1382
                                (g << aGreenShift) |
1383
                                (b << aBlueShift);
1384
 
1385
                        aCurY = theStartY;
1386
                        aCurX = theStartX + 1;
1387
 
1388
                        G = 2 * dv - dh;
1389
                        DeltaG1 = 2 * (dv - dh);
1390
                        DeltaG2 = 2 * dv;
1391
 
1392
                        G += DeltaG2 * (theStartY - (int) theStartY);
1393
 
1394
                        while (aCurX <= theEndX)
1395
                        {
1396
                                if (G > 0)
1397
                                {                                      
1398
                                        G += DeltaG1;
1399
                                        aCurY += inc;
1400
                                        aDestPixels += aRowAdd;
1401
 
1402
                                        if (aCurX<aMinX || aCurY<aMinY || aCurX>aMaxX || aCurY>aMaxY)
1403
                                                break;
1404
                                }
1405
                                else
1406
                                        G += DeltaG2;
1407
 
1408
                                dest = *aDestPixels;
1409
 
1410
                                r = aMaxRedTable[((dest & aRMask) >> aRedShift) + rc];
1411
                                g = aMaxGreenTable[((dest & aGMask) >> aGreenShift) + gc];
1412
                                b = aMaxBlueTable[((dest & aBMask) >> aBlueShift) + bc];
1413
 
1414
                                *(aDestPixels++) =
1415
                                        (r << aRedShift) |
1416
                                        (g << aGreenShift) |
1417
                                        (b << aBlueShift);
1418
 
1419
                                aCurX++;                               
1420
                        }
1421
                }
1422
                else
1423
                {
1424
                        // Mostly vertical
1425
                        if ( dv < 0 )
1426
                        {
1427
                                dh = -dh;
1428
                                dv = -dv;
1429
                                swap = theEndY;
1430
                                theEndY = theStartY;
1431
                                theStartY = swap;
1432
                                swap = theEndX;
1433
                                theEndX = theStartX;
1434
                                theStartX = swap;
1435
                        }
1436
 
1437
                        if (dh < 0)
1438
                        {
1439
                                dh = -dh;
1440
                                inc = -1;
1441
                        }
1442
 
1443
                        ushort* aDestPixels = ((ushort*) mLockedSurfaceDesc.lpSurface) + ((int) theStartY * mLockedSurfaceDesc.lPitch/2) + (int) theStartX;
1444
 
1445
                        ushort dest = *aDestPixels;
1446
 
1447
                        int r = aMaxRedTable[((dest & aRMask) >> aRedShift) + rc];
1448
                        int g = aMaxGreenTable[((dest & aGMask) >> aGreenShift) + gc];
1449
                        int b = aMaxBlueTable[((dest & aBMask) >> aBlueShift) + bc];
1450
 
1451
                        *aDestPixels =
1452
                                (r << aRedShift) |
1453
                                (g << aGreenShift) |
1454
                                (b << aBlueShift);
1455
 
1456
                        aDestPixels += aRowAdd;
1457
 
1458
                        aCurX = theStartX;
1459
                        aCurY = theStartY + 1;
1460
 
1461
                        G = 2 * dh - dv;
1462
                        minG = maxG = G;
1463
                        DeltaG1 = 2 * ( dh - dv );
1464
                        DeltaG2 = 2 * dh;      
1465
 
1466
                        G += DeltaG2 * (theStartX - (int) theStartX);
1467
 
1468
                        while (aCurY <= theEndY)
1469
                        {
1470
                                if ( G > 0 )
1471
                                {
1472
                                        G += DeltaG1;
1473
                                        aCurX += inc;
1474
                                        aDestPixels += inc;
1475
 
1476
                                        if (aCurX<aMinX || aCurY<aMinY || aCurX>aMaxX || aCurY>aMaxY)
1477
                                                break;
1478
                                }
1479
                                else
1480
                                        G += DeltaG2;
1481
 
1482
                                dest = *aDestPixels;
1483
 
1484
                                r = aMaxRedTable[((dest & aRMask) >> aRedShift) + rc];
1485
                                g = aMaxGreenTable[((dest & aGMask) >> aGreenShift) + gc];
1486
                                b = aMaxBlueTable[((dest & aBMask) >> aBlueShift) + bc];
1487
 
1488
                                *aDestPixels =
1489
                                        (r << aRedShift) |
1490
                                        (g << aGreenShift) |
1491
                                        (b << aBlueShift);
1492
 
1493
                                aCurY++;
1494
                                aDestPixels += aRowAdd;
1495
                        }
1496
                }
1497
        }
1498
        else if (mLockedSurfaceDesc.ddpfPixelFormat.dwRGBBitCount == 32)
1499
        {
1500
                ulong rc = ((theColor.mRed * theColor.mAlpha) / 255) >> (8-mDDInterface->mRedBits);
1501
                ulong gc = ((theColor.mGreen * theColor.mAlpha) / 255) >> (8-mDDInterface->mGreenBits);
1502
                ulong bc = ((theColor.mBlue * theColor.mAlpha) / 255) >> (8-mDDInterface->mBlueBits);
1503
 
1504
                double dv = theEndY - theStartY;
1505
                double dh = theEndX - theStartX;
1506
                int minG, maxG, G, DeltaG1, DeltaG2;
1507
                double swap;
1508
                int inc = 1;
1509
                int aCurX;
1510
                int aCurY;
1511
                int aRowWidth = mLockedSurfaceDesc.lPitch/4;
1512
                int aRowAdd = aRowWidth;
1513
 
1514
                if (abs(dv) < abs(dh))
1515
                {
1516
                        // Mostly horizontal
1517
                        if (dh < 0)
1518
                        {
1519
                                dh = -dh;
1520
                                dv = -dv;
1521
                                swap = theEndY;
1522
                                theEndY = theStartY;
1523
                                theStartY = swap;
1524
                                swap = theEndX;
1525
                                theEndX = theStartX;
1526
                                theStartX = swap;
1527
                        }
1528
 
1529
                        if (dv < 0)
1530
                        {
1531
                                dv = -dv;
1532
                                inc = -1;
1533
                                aRowAdd = -aRowAdd;
1534
                        }
1535
 
1536
                        ulong* aDestPixels = ((ulong*) mLockedSurfaceDesc.lpSurface) + ((int) theStartY * aRowWidth) + (int) theStartX;
1537
                        ulong dest = *aDestPixels;
1538
 
1539
                        int r = aMaxRedTable[((dest & aRMask) >> aRedShift) + rc];
1540
                        int g = aMaxGreenTable[((dest & aGMask) >> aGreenShift) + gc];
1541
                        int b = aMaxBlueTable[((dest & aBMask) >> aBlueShift) + bc];
1542
 
1543
                        *(aDestPixels++) =
1544
                                (r << aRedShift) |
1545
                                (g << aGreenShift) |
1546
                                (b << aBlueShift);
1547
 
1548
                        aCurY = theStartY;
1549
                        aCurX = theStartX + 1;
1550
 
1551
                        G = 2 * dv - dh;
1552
                        DeltaG1 = 2 * (dv - dh);
1553
                        DeltaG2 = 2 * dv;                      
1554
 
1555
                        while (aCurX <= theEndX)
1556
                        {
1557
                                if (G > 0)
1558
                                {
1559
                                        G += DeltaG1;
1560
                                        aCurY += inc;
1561
                                        aDestPixels += aRowAdd;
1562
 
1563
                                        if (aCurX<aMinX || aCurY<aMinY || aCurX>aMaxX || aCurY>aMaxY)
1564
                                                break;
1565
                                }
1566
                                else
1567
                                        G += DeltaG2;
1568
 
1569
                                dest = *aDestPixels;
1570
 
1571
                                r = aMaxRedTable[((dest & aRMask) >> aRedShift) + rc];
1572
                                g = aMaxGreenTable[((dest & aGMask) >> aGreenShift) + gc];
1573
                                b = aMaxBlueTable[((dest & aBMask) >> aBlueShift) + bc];
1574
 
1575
                                *(aDestPixels++) =
1576
                                        (r << aRedShift) |
1577
                                        (g << aGreenShift) |
1578
                                        (b << aBlueShift);
1579
 
1580
                                aCurX++;                               
1581
                        }
1582
                }
1583
                else
1584
                {
1585
                        // Mostly vertical
1586
                        if ( dv < 0 )
1587
                        {
1588
                                dh = -dh;
1589
                                dv = -dv;
1590
                                swap = theEndY;
1591
                                theEndY = theStartY;
1592
                                theStartY = swap;
1593
                                swap = theEndX;
1594
                                theEndX = theStartX;
1595
                                theStartX = swap;
1596
                        }
1597
 
1598
                        if (dh < 0)
1599
                        {
1600
                                dh = -dh;
1601
                                inc = -1;
1602
                        }
1603
 
1604
                        ulong* aDestPixels = ((ulong*) mLockedSurfaceDesc.lpSurface) + ((int) theStartY * mLockedSurfaceDesc.lPitch/4) + (int) theStartX;
1605
 
1606
                        ulong dest = *aDestPixels;
1607
 
1608
                        int r = aMaxRedTable[((dest & aRMask) >> aRedShift) + rc];
1609
                        int g = aMaxGreenTable[((dest & aGMask) >> aGreenShift) + gc];
1610
                        int b = aMaxBlueTable[((dest & aBMask) >> aBlueShift) + bc];
1611
 
1612
                        *aDestPixels =
1613
                                (r << aRedShift) |
1614
                                (g << aGreenShift) |
1615
                                (b << aBlueShift);
1616
 
1617
                        aDestPixels += aRowAdd;
1618
 
1619
                        aCurX = theStartX;
1620
                        aCurY = theStartY + 1;
1621
 
1622
                        G = 2 * dh - dv;
1623
                        minG = maxG = G;
1624
                        DeltaG1 = 2 * ( dh - dv );
1625
                        DeltaG2 = 2 * dh;
1626
                        while (aCurY <= theEndY)
1627
                        {
1628
                                if ( G > 0 )
1629
                                {
1630
                                        G += DeltaG1;
1631
                                        aCurX += inc;
1632
                                        aDestPixels += inc;
1633
 
1634
                                        if (aCurX<aMinX || aCurY<aMinY || aCurX>aMaxX || aCurY>aMaxY)
1635
                                                break;
1636
                                }
1637
                                else
1638
                                        G += DeltaG2;
1639
 
1640
                                dest = *aDestPixels;
1641
 
1642
                                r = aMaxRedTable[((dest & aRMask) >> aRedShift) + rc];
1643
                                g = aMaxGreenTable[((dest & aGMask) >> aGreenShift) + gc];
1644
                                b = aMaxBlueTable[((dest & aBMask) >> aBlueShift) + bc];
1645
 
1646
                                *aDestPixels =
1647
                                        (r << aRedShift) |
1648
                                        (g << aGreenShift) |
1649
                                        (b << aBlueShift);
1650
 
1651
                                aCurY++;
1652
                                aDestPixels += aRowAdd;
1653
                        }
1654
                }
1655
        }
1656
 
1657
        UnlockSurface();
1658
}
1659
 
1660
void DDImage::DrawLine(double theStartX, double theStartY, double theEndX, double theEndY, const Color& theColor, int theDrawMode)
1661
{      
1662
        if (Check3D(this))
1663
        {
1664
                mDDInterface->mD3DInterface->DrawLine(theStartX,theStartY,theEndX,theEndY,theColor,theDrawMode);
1665
                return;
1666
        }
1667
 
1668
        if ((mDrawToBits) || (mHasAlpha) || (mHasTrans) || (mDDInterface->mIs3D))
1669
        {
1670
                MemoryImage::DrawLine(theStartX, theStartY, theEndX, theEndY, theColor, theDrawMode);
1671
                return;
1672
        }
1673
 
1674
        if (theStartY == theEndY)
1675
        {
1676
                int aStartX = min(theStartX, theEndX);
1677
                int aEndX = max(theStartX, theEndX);
1678
 
1679
                FillRect(Rect(aStartX, theStartY, aEndX-aStartX+1, theEndY-theStartY+1), theColor, theDrawMode);
1680
                return;
1681
        }
1682
        else if (theStartX == theEndX)
1683
        {
1684
                int aStartY = min(theStartY, theEndY);
1685
                int aEndY = max(theStartY, theEndY);
1686
 
1687
                FillRect(Rect(theStartX, aStartY, theEndX-theStartX+1, aEndY-aStartY+1), theColor, theDrawMode);
1688
                return;
1689
        }
1690
 
1691
        CommitBits();  
1692
 
1693
        switch (theDrawMode)
1694
        {
1695
        case Graphics::DRAWMODE_NORMAL:
1696
                NormalDrawLine(theStartX, theStartY, theEndX, theEndY, theColor);
1697
                break;
1698
        case Graphics::DRAWMODE_ADDITIVE:
1699
                AdditiveDrawLine(theStartX, theStartY, theEndX, theEndY, theColor);
1700
                break;
1701
        }
1702
 
1703
        DeleteAllNonSurfaceData();
1704
}
1705
 
1706
void DDImage::NormalDrawLineAA(double theStartX, double theStartY, double theEndX, double theEndY, const Color& theColor)
1707
{
1708
        LPDIRECTDRAWSURFACE aSurface = GetSurface();
1709
 
1710
        if (!LockSurface())
1711
                return;
1712
 
1713
        ulong aRMask = mLockedSurfaceDesc.ddpfPixelFormat.dwRBitMask;
1714
        ulong aGMask = mLockedSurfaceDesc.ddpfPixelFormat.dwGBitMask;
1715
        ulong aBMask = mLockedSurfaceDesc.ddpfPixelFormat.dwBBitMask;
1716
        ulong color = (((theColor.mRed * aRMask) >> 8) & aRMask) |
1717
                                        (((theColor.mGreen * aGMask) >> 8) & aGMask) |
1718
                                        (((theColor.mBlue * aBMask) >> 8) & aBMask);
1719
 
1720
        int aX0 = (int)theStartX, aX1 = (int)theEndX;
1721
        int aY0 = (int)theStartY, aY1 = (int)theEndY;
1722
        int aXinc = 1;
1723
        if (aY0 > aY1)
1724
        {
1725
                int aTempX = aX0, aTempY = aY0;
1726
                aX0 = aX1; aY0 = aY1;
1727
                aX1 = aTempX; aY1 = aTempY;
1728
                double aTempXd = theStartX, aTempYd = theStartY;
1729
                theStartX = theEndX; theStartY = theEndY;
1730
                theEndX = aTempXd; theEndY = aTempYd;
1731
        }
1732
 
1733
        int dx = aX1 - aX0;
1734
        int dy = aY1 - aY0;
1735
        double dxd = theEndX - theStartX;
1736
        double dyd = theEndY - theStartY;
1737
        if (dx < 0)
1738
        {
1739
                dx = -dx;
1740
                aXinc = -1;
1741
                dxd = -dxd;
1742
        }
1743
 
1744
        if (mLockedSurfaceDesc.ddpfPixelFormat.dwRGBBitCount == 32)
1745
        {
1746
                ulong* aBits = (ulong*)mLockedSurfaceDesc.lpSurface;
1747
#ifdef OPTIMIZE_SOFTWARE_DRAWING
1748
                if (theColor.mAlpha != 255)
1749
                {
1750
                        #define PIXEL_TYPE                      ulong
1751
                        #define CALC_WEIGHT_A(w)        (((w) * (theColor.mAlpha+1)) >> 8)
1752
                        #define BLEND_PIXEL(p)          \
1753
                                                *(p) =                  \
1754
                                                                ((((color & 0xFF00FF) * a + (dest & 0xFF00FF) * oma) >> 8) & 0xFF00FF) |\
1755
                                                                ((((color & 0x00FF00) * a + (dest & 0x00FF00) * oma) >> 8) & 0x00FF00);
1756
                        const int STRIDE = mLockedSurfaceDesc.lPitch / sizeof(PIXEL_TYPE);
1757
 
1758
                        #include "GENERIC_DrawLineAA.inc"
1759
 
1760
                        #undef PIXEL_TYPE
1761
                        #undef CALC_WEIGHT_A
1762
                        #undef BLEND_PIXEL
1763
                }
1764
                else
1765
                {
1766
                        #define PIXEL_TYPE                      ulong
1767
                        #define CALC_WEIGHT_A(w)        (w)
1768
                        #define BLEND_PIXEL(p)          \
1769
                                                *(p) =                  \
1770
                                                                ((((color & 0xFF00FF) * a + (dest & 0xFF00FF) * oma) >> 8) & 0xFF00FF) |\
1771
                                                                ((((color & 0x00FF00) * a + (dest & 0x00FF00) * oma) >> 8) & 0x00FF00);
1772
                        const int STRIDE = mLockedSurfaceDesc.lPitch / sizeof(PIXEL_TYPE);
1773
 
1774
                        #include "GENERIC_DrawLineAA.inc"
1775
 
1776
                        #undef PIXEL_TYPE
1777
                        #undef CALC_WEIGHT_A
1778
                        #undef BLEND_PIXEL
1779
                }
1780
#else
1781
                if (theColor.mAlpha != 255)
1782
                {
1783
                        #define PIXEL_TYPE                      ulong
1784
                        #define CALC_WEIGHT_A(w)        (((w) * (theColor.mAlpha+1)) >> 8)
1785
                        #define BLEND_PIXEL(p)          \
1786
                                                *(p) =                  \
1787
                                                                ((((color & aRMask) * a + (dest & aRMask) * oma) >> 8) & aRMask) |\
1788
                                                                ((((color & aGMask) * a + (dest & aGMask) * oma) >> 8) & aGMask) |\
1789
                                                                ((((color & aBMask) * a + (dest & aBMask) * oma) >> 8) & aBMask);
1790
                        const int STRIDE = mLockedSurfaceDesc.lPitch / sizeof(PIXEL_TYPE);
1791
 
1792
                        #include "GENERIC_DrawLineAA.inc"
1793
 
1794
                        #undef PIXEL_TYPE
1795
                        #undef CALC_WEIGHT_A
1796
                        #undef BLEND_PIXEL
1797
                }
1798
                else
1799
                {
1800
                        #define PIXEL_TYPE                      ulong
1801
                        #define CALC_WEIGHT_A(w)        (w)
1802
                        #define BLEND_PIXEL(p)          \
1803
                                                *(p) =                  \
1804
                                                                ((((color & aRMask) * a + (dest & aRMask) * oma) >> 8) & aRMask) |\
1805
                                                                ((((color & aGMask) * a + (dest & aGMask) * oma) >> 8) & aGMask) |\
1806
                                                                ((((color & aBMask) * a + (dest & aBMask) * oma) >> 8) & aBMask);
1807
                        const int STRIDE = mLockedSurfaceDesc.lPitch / sizeof(PIXEL_TYPE);
1808
 
1809
                        #include "GENERIC_DrawLineAA.inc"
1810
 
1811
                        #undef PIXEL_TYPE
1812
                        #undef CALC_WEIGHT_A
1813
                        #undef BLEND_PIXEL
1814
                }
1815
#endif
1816
        }
1817
        else if (mLockedSurfaceDesc.ddpfPixelFormat.dwRGBBitCount == 16)
1818
        {
1819
                ushort* aBits = (ushort*)mLockedSurfaceDesc.lpSurface;
1820
#ifdef OPTIMIZE_SOFTWARE_DRAWING
1821
                if (aGMask == 0x3E0) // 5-5-5
1822
                {
1823
                        #define PIXEL_TYPE                      ushort
1824
                        #define BLEND_PIXEL(p)          \
1825
                        {\
1826
                                a >>= 3;\
1827
                                oma >>= 3;\
1828
                                ulong _src = (((color | (color << 16)) & 0x3E07C1F) * a >> 5) & 0x3E07C1F;\
1829
                                ulong _dest = (((dest | (dest << 16)) & 0x3E07C1F) * oma >> 5) & 0x3E07C1F;\
1830
                                *(p) = (_src | (_src>>16)) + (_dest | (_dest>>16));\
1831
                        }
1832
                        const int STRIDE = mLockedSurfaceDesc.lPitch / sizeof(PIXEL_TYPE);
1833
                        if (theColor.mAlpha != 255)
1834
                        {
1835
                                #define CALC_WEIGHT_A(w)        (((w) * (theColor.mAlpha+1)) >> 8)
1836
                                #include "GENERIC_DrawLineAA.inc"
1837
                                #undef CALC_WEIGHT_A
1838
                        }
1839
                        else
1840
                        {
1841
                                #define CALC_WEIGHT_A(w)        (w)
1842
                                #include "GENERIC_DrawLineAA.inc"
1843
                                #undef CALC_WEIGHT_A
1844
                        }
1845
                        #undef PIXEL_TYPE
1846
                        #undef BLEND_PIXEL
1847
                }
1848
                else if (aGMask == 0x7E0) // 5-6-5
1849
                {
1850
                        #define PIXEL_TYPE                      ushort
1851
                        #define BLEND_PIXEL(p)          \
1852
                        {\
1853
                                a >>= 3;\
1854
                                oma >>= 3;\
1855
                                ulong _src = (((color | (color << 16)) & 0x7E0F81F) * a >> 5) & 0x7E0F81F;\
1856
                                ulong _dest = (((dest | (dest << 16)) & 0x7E0F81F) * oma >> 5) & 0x7E0F81F;\
1857
                                *(p) = (_src | (_src>>16)) + (_dest | (_dest>>16));\
1858
                        }
1859
                        const int STRIDE = mLockedSurfaceDesc.lPitch / sizeof(PIXEL_TYPE);
1860
                        if (theColor.mAlpha != 255)
1861
                        {
1862
                                #define CALC_WEIGHT_A(w)        (((w) * (theColor.mAlpha+1)) >> 8)
1863
                                #include "GENERIC_DrawLineAA.inc"
1864
                                #undef CALC_WEIGHT_A
1865
                        }
1866
                        else
1867
                        {
1868
                                #define CALC_WEIGHT_A(w)        (w)
1869
                                #include "GENERIC_DrawLineAA.inc"
1870
                                #undef CALC_WEIGHT_A
1871
                        }
1872
                        #undef PIXEL_TYPE
1873
                        #undef BLEND_PIXEL
1874
                }
1875
                else
1876
                {
1877
#endif
1878
                        if (theColor.mAlpha != 255)
1879
                        {
1880
                                #define PIXEL_TYPE                      ushort
1881
                                #define CALC_WEIGHT_A(w)        (((w) * (theColor.mAlpha+1)) >> 8)
1882
                                #define BLEND_PIXEL(p)          \
1883
                                                        *(p) =                  \
1884
                                                                        ((((color & aRMask) * a + (dest & aRMask) * oma) >> 8) & aRMask) |\
1885
                                                                        ((((color & aGMask) * a + (dest & aGMask) * oma) >> 8) & aGMask) |\
1886
                                                                        ((((color & aBMask) * a + (dest & aBMask) * oma) >> 8) & aBMask);
1887
                                const int STRIDE = mLockedSurfaceDesc.lPitch / sizeof(PIXEL_TYPE);
1888
 
1889
                                #include "GENERIC_DrawLineAA.inc"
1890
 
1891
                                #undef PIXEL_TYPE
1892
                                #undef CALC_WEIGHT_A
1893
                                #undef BLEND_PIXEL
1894
                        }
1895
                        else
1896
                        {
1897
                                #define PIXEL_TYPE                      ushort
1898
                                #define CALC_WEIGHT_A(w)        (w)
1899
                                #define BLEND_PIXEL(p)          \
1900
                                                        *(p) =                  \
1901
                                                                        ((((color & aRMask) * a + (dest & aRMask) * oma) >> 8) & aRMask) |\
1902
                                                                        ((((color & aGMask) * a + (dest & aGMask) * oma) >> 8) & aGMask) |\
1903
                                                                        ((((color & aBMask) * a + (dest & aBMask) * oma) >> 8) & aBMask);
1904
                                const int STRIDE = mLockedSurfaceDesc.lPitch / sizeof(PIXEL_TYPE);
1905
 
1906
                                #include "GENERIC_DrawLineAA.inc"
1907
 
1908
                                #undef PIXEL_TYPE
1909
                                #undef CALC_WEIGHT_A
1910
                                #undef BLEND_PIXEL
1911
                        }
1912
#ifdef OPTIMIZE_SOFTWARE_DRAWING
1913
                }
1914
#endif
1915
        }
1916
 
1917
        UnlockSurface();
1918
}
1919
 
1920
void DDImage::AdditiveDrawLineAA(double theStartX, double theStartY, double theEndX, double theEndY, const Color& theColor)
1921
{
1922
}
1923
 
1924
void DDImage::DrawLineAA(double theStartX, double theStartY, double theEndX, double theEndY, const Color& theColor, int theDrawMode)
1925
{
1926
        if (Check3D(this))
1927
        {
1928
                mDDInterface->mD3DInterface->DrawLine(theStartX,theStartY,theEndX,theEndY,theColor,theDrawMode);
1929
                return;
1930
        }
1931
 
1932
        if ((mDrawToBits) || (mHasAlpha) || (mHasTrans) || (mDDInterface->mIs3D))
1933
        {
1934
                MemoryImage::DrawLine(theStartX, theStartY, theEndX, theEndY, theColor, theDrawMode);
1935
                return;
1936
        }
1937
 
1938
        if (theStartY == theEndY)
1939
        {
1940
                int aStartX = min(theStartX, theEndX);
1941
                int aEndX = max(theStartX, theEndX);
1942
 
1943
                FillRect(Rect(aStartX, theStartY, aEndX-aStartX+1, theEndY-theStartY+1), theColor, theDrawMode);
1944
                return;
1945
        }
1946
        else if (theStartX == theEndX)
1947
        {
1948
                int aStartY = min(theStartY, theEndY);
1949
                int aEndY = max(theStartY, theEndY);
1950
 
1951
                FillRect(Rect(theStartX, aStartY, theEndX-theStartX+1, aEndY-aStartY+1), theColor, theDrawMode);
1952
                return;
1953
        }
1954
 
1955
        CommitBits();  
1956
 
1957
        switch (theDrawMode)
1958
        {
1959
        case Graphics::DRAWMODE_NORMAL:
1960
                NormalDrawLineAA(theStartX, theStartY, theEndX, theEndY, theColor);
1961
                break;
1962
        case Graphics::DRAWMODE_ADDITIVE:
1963
                AdditiveDrawLineAA(theStartX, theStartY, theEndX, theEndY, theColor);
1964
                break;
1965
        }
1966
 
1967
        DeleteAllNonSurfaceData();
1968
}
1969
 
1970
void DDImage::CommitBits()
1971
{
1972
        if (mSurface == NULL)
1973
        {
1974
                MemoryImage::CommitBits();
1975
                return;
1976
        }
1977
}
1978
 
1979
void DDImage::Create(int theWidth, int theHeight)
1980
{
1981
        delete [] mBits;
1982
 
1983
        mWidth = theWidth;
1984
        mHeight = theHeight;
1985
 
1986
        mBits = NULL;
1987
 
1988
        BitsChanged(); 
1989
}
1990
 
1991
void DDImage::BitsChanged()
1992
{
1993
        MemoryImage::BitsChanged();
1994
 
1995
        if (mSurface != NULL)
1996
                mSurface->Release();
1997
        mSurface = NULL;
1998
}
1999
 
2000
ulong* DDImage::GetBits()
2001
{
2002
        if (mBits == NULL)
2003
        {
2004
                if (mSurface == NULL)
2005
                        return MemoryImage::GetBits();
2006
 
2007
                if (mNoLock)
2008
                        return NULL;
2009
 
2010
                LPDIRECTDRAWSURFACE aSurface = mSurface;               
2011
 
2012
                if (!LockSurface())
2013
                        return NULL;
2014
 
2015
                mBits = new ulong[mWidth*mHeight + 1];
2016
                mBits[mWidth*mHeight] = MEMORYCHECK_ID;
2017
 
2018
                int aRRound = (1 << (7 - mDDInterface->mRedBits));
2019
                int aGRound = (1 << (7 - mDDInterface->mGreenBits));
2020
                int aBRound = (1 << (7 - mDDInterface->mBlueBits));
2021
 
2022
                if (mLockedSurfaceDesc.ddpfPixelFormat.dwRGBBitCount == 16)
2023
                {
2024
                        ushort* aSrcPixelsRow = (ushort*) mLockedSurfaceDesc.lpSurface;
2025
                        ulong* aDest = mBits;
2026
 
2027
                        for (int y = 0; y < mHeight; y++)
2028
                        {                              
2029
                                ushort* aSrcPixels = aSrcPixelsRow;
2030
 
2031
                                for (int x = 0; x < mWidth; x++)
2032
                                {
2033
                                        ulong src = *(aSrcPixels++);
2034
 
2035
                                        int r = ((src >> mDDInterface->mRedShift << (8 - mDDInterface->mRedBits)) & 0xFF);
2036
                                        int g = ((src >> mDDInterface->mGreenShift << (8 - mDDInterface->mGreenBits)) & 0xFF);
2037
                                        int b = ((src >> mDDInterface->mBlueShift << (8 - mDDInterface->mBlueBits)) & 0xFF);
2038
 
2039
                                        *aDest++ = 0xFF000000 | (r << 16) | (g << 8) | (b);
2040
                                }
2041
 
2042
                                aSrcPixelsRow += mLockedSurfaceDesc.lPitch/2;
2043
                        }
2044
                }
2045
                else if (mLockedSurfaceDesc.ddpfPixelFormat.dwRGBBitCount == 32)
2046
                {
2047
                        ulong* aSrcPixelsRow = (ulong*) mLockedSurfaceDesc.lpSurface;
2048
                        ulong* aDest = mBits;
2049
 
2050
                        for (int y = 0; y < mHeight; y++)
2051
                        {                              
2052
                                ulong* aSrcPixels = aSrcPixelsRow;
2053
 
2054
                                for (int x = 0; x < mWidth; x++)
2055
                                {
2056
                                        ulong src = *(aSrcPixels++);
2057
 
2058
                                        int r = (src >> mDDInterface->mRedShift << (8 - mDDInterface->mRedBits)) & 0xFF;
2059
                                        int g = (src >> mDDInterface->mGreenShift << (8 - mDDInterface->mGreenBits)) & 0xFF;
2060
                                        int b = (src >> mDDInterface->mBlueShift << (8 - mDDInterface->mBlueBits)) & 0xFF;
2061
 
2062
                                        *aDest++ = 0xFF000000 | (r << 16) | (g << 8) | (b);
2063
                                }
2064
 
2065
                                aSrcPixelsRow += mLockedSurfaceDesc.lPitch/4;
2066
                        }
2067
                }              
2068
 
2069
                UnlockSurface();
2070
        }
2071
 
2072
        return mBits;
2073
}
2074
 
2075
void DDImage::NormalFillRect(const Rect& theRect, const Color& theColor)
2076
{
2077
        if (mNoLock)
2078
                return;
2079
 
2080
        LPDIRECTDRAWSURFACE aSurface = GetSurface();
2081
 
2082
        if (!LockSurface())
2083
                return;
2084
 
2085
        ulong aRMask = mLockedSurfaceDesc.ddpfPixelFormat.dwRBitMask;
2086
        ulong aGMask = mLockedSurfaceDesc.ddpfPixelFormat.dwGBitMask;
2087
        ulong aBMask = mLockedSurfaceDesc.ddpfPixelFormat.dwBBitMask;
2088
 
2089
        ulong aRRoundAdd = aRMask;
2090
        ulong aGRoundAdd = aGMask;
2091
        ulong aBRoundAdd = aBMask;
2092
 
2093
        if (mLockedSurfaceDesc.ddpfPixelFormat.dwRGBBitCount == 16)
2094
        {
2095
                if (theColor.mAlpha == 255)
2096
                {
2097
                        ushort aColor =
2098
                                ((((theColor.mRed * aRMask) + aRRoundAdd) >> 8) & aRMask) |
2099
                                ((((theColor.mGreen * aGMask) + aGRoundAdd) >> 8) & aGMask) |
2100
                                ((((theColor.mBlue * aBMask) + aBRoundAdd) >> 8) & aBMask);
2101
 
2102
                        ushort* aDestPixelsRow = ((ushort*) mLockedSurfaceDesc.lpSurface) + (theRect.mY * mLockedSurfaceDesc.lPitch/2) + theRect.mX;
2103
 
2104
                        for (int y = 0; y < theRect.mHeight; y++)
2105
                        {
2106
                                ushort* aDestPixels = aDestPixelsRow;                  
2107
 
2108
                                for (int x = 0; x < theRect.mWidth; x++)                       
2109
                                        *(aDestPixels++) = aColor;
2110
 
2111
                                aDestPixelsRow += mLockedSurfaceDesc.lPitch/2;                 
2112
                        }
2113
                }
2114
                else
2115
                {
2116
                        ushort src =
2117
                                ((((((theColor.mRed * theColor.mAlpha + 0x80) >> 8) * aRMask) + aRRoundAdd) >> 8) & aRMask) +
2118
                                ((((((theColor.mGreen * theColor.mAlpha + 0x80) >> 8) * aGMask) + aGRoundAdd) >> 8) & aGMask) +
2119
                                ((((((theColor.mBlue * theColor.mAlpha + 0x80) >> 8) * aBMask) + aBRoundAdd) >> 8) & aBMask);
2120
                        int oma = 256 - theColor.mAlpha;
2121
 
2122
                        ushort* aDestPixelsRow = ((ushort*) mLockedSurfaceDesc.lpSurface) + (theRect.mY * mLockedSurfaceDesc.lPitch/2) + theRect.mX;
2123
 
2124
                        for (int y = 0; y < theRect.mHeight; y++)
2125
                        {
2126
                                ushort* aDestPixels = aDestPixelsRow;                  
2127
 
2128
                                for (int x = 0; x < theRect.mWidth; x++)                       
2129
                                {
2130
                                        ushort dest = *aDestPixels;
2131
 
2132
                                        *(aDestPixels++) = src +
2133
                                                (((((dest & aRMask) * oma) + aRRoundAdd) >> 8) & aRMask) +
2134
                                                (((((dest & aGMask) * oma) + aGRoundAdd) >> 8) & aGMask) +
2135
                                                (((((dest & aBMask) * oma) + aBRoundAdd) >> 8) & aBMask);
2136
                                }
2137
 
2138
                                aDestPixelsRow += mLockedSurfaceDesc.lPitch/2;                 
2139
                        }
2140
                }
2141
        }
2142
        else if (mLockedSurfaceDesc.ddpfPixelFormat.dwRGBBitCount == 32)
2143
        {
2144
                if (theColor.mAlpha == 255)
2145
                {
2146
                        ulong aColor =
2147
                                ((((theColor.mRed * aRMask)) >> 8) & aRMask) |
2148
                                ((((theColor.mGreen * aGMask)) >> 8) & aGMask) |
2149
                                ((((theColor.mBlue * aBMask)) >> 8) & aBMask);
2150
 
2151
                        ulong* aDestPixelsRow = ((ulong*) mLockedSurfaceDesc.lpSurface) + (theRect.mY * mLockedSurfaceDesc.lPitch/4) + theRect.mX;
2152
 
2153
                        for (int y = 0; y < theRect.mHeight; y++)
2154
                        {
2155
                                ulong* aDestPixels = aDestPixelsRow;                   
2156
 
2157
                                for (int x = 0; x < theRect.mWidth; x++)                       
2158
                                        *(aDestPixels++) = aColor;
2159
 
2160
                                aDestPixelsRow += mLockedSurfaceDesc.lPitch/4;
2161
                        }
2162
                }
2163
                else
2164
                {
2165
                        ulong src =
2166
                                ((((((theColor.mRed * theColor.mAlpha + 0x7F) >> 8) * aRMask) + aRRoundAdd) >> 8) & aRMask) +
2167
                                ((((((theColor.mGreen * theColor.mAlpha + 0x7F) >> 8) * aGMask) + aGRoundAdd) >> 8) & aGMask) +
2168
                                ((((((theColor.mBlue * theColor.mAlpha + 0x7F) >> 8) * aBMask) + aBRoundAdd) >> 8) & aBMask);
2169
                        int oma = 256 - theColor.mAlpha;
2170
 
2171
                        ulong* aDestPixelsRow = ((ulong*) mLockedSurfaceDesc.lpSurface) + (theRect.mY * mLockedSurfaceDesc.lPitch/4) + theRect.mX;
2172
 
2173
                        for (int y = 0; y < theRect.mHeight; y++)
2174
                        {
2175
                                ulong* aDestPixels = aDestPixelsRow;                   
2176
 
2177
                                for (int x = 0; x < theRect.mWidth; x++)                       
2178
                                {
2179
                                        ulong dest = *aDestPixels;
2180
 
2181
                                        *(aDestPixels++) = src +
2182
                                                (((((dest & aRMask) * oma)) >> 8) & aRMask) +
2183
                                                (((((dest & aGMask) * oma)) >> 8) & aGMask) +
2184
                                                (((((dest & aBMask) * oma)) >> 8) & aBMask);
2185
                                }
2186
 
2187
                                aDestPixelsRow += mLockedSurfaceDesc.lPitch/4;
2188
                        }
2189
                }
2190
        }
2191
 
2192
        UnlockSurface();
2193
}
2194
 
2195
void DDImage::AdditiveFillRect(const Rect& theRect, const Color& theColor)
2196
{
2197
        if (mNoLock)
2198
                return;
2199
 
2200
        LPDIRECTDRAWSURFACE aSurface = GetSurface();
2201
 
2202
        if (!LockSurface())
2203
                return;
2204
 
2205
        ulong aRMask = mLockedSurfaceDesc.ddpfPixelFormat.dwRBitMask;
2206
        ulong aGMask = mLockedSurfaceDesc.ddpfPixelFormat.dwGBitMask;
2207
        ulong aBMask = mLockedSurfaceDesc.ddpfPixelFormat.dwBBitMask;
2208
 
2209
        ulong aRRoundAdd = aRMask >> 1;
2210
        ulong aGRoundAdd = aGMask >> 1;
2211
        ulong aBRoundAdd = aBMask >> 1;
2212
 
2213
        int aRedShift = mDDInterface->mRedShift;
2214
        int aGreenShift = mDDInterface->mGreenShift;
2215
        int aBlueShift = mDDInterface->mBlueShift;
2216
 
2217
        int* aMaxRedTable = mDDInterface->mRedAddTable;
2218
        int* aMaxGreenTable = mDDInterface->mGreenAddTable;
2219
        int* aMaxBlueTable = mDDInterface->mBlueAddTable;      
2220
 
2221
        if (mLockedSurfaceDesc.ddpfPixelFormat.dwRGBBitCount == 16)
2222
        {
2223
                ushort rc = ((theColor.mRed * theColor.mAlpha) / 255) >> (8-mDDInterface->mRedBits);
2224
                ushort gc = ((theColor.mGreen * theColor.mAlpha) / 255) >> (8-mDDInterface->mGreenBits);
2225
                ushort bc = ((theColor.mBlue * theColor.mAlpha) / 255) >> (8-mDDInterface->mBlueBits);
2226
 
2227
                ushort* aDestPixelsRow = ((ushort*) mLockedSurfaceDesc.lpSurface) + (theRect.mY * mLockedSurfaceDesc.lPitch/2) + theRect.mX;
2228
 
2229
                for (int y = 0; y < theRect.mHeight; y++)
2230
                {
2231
                        ushort* aDestPixels = aDestPixelsRow;                  
2232
 
2233
                        for (int x = 0; x < theRect.mWidth; x++)                       
2234
                        {
2235
                                ushort dest = *aDestPixels;
2236
 
2237
                                int r = aMaxRedTable[((dest & aRMask) >> aRedShift) + rc];
2238
                                int g = aMaxGreenTable[((dest & aGMask) >> aGreenShift) + gc];
2239
                                int b = aMaxBlueTable[((dest & aBMask) >> aBlueShift) + bc];                           
2240
 
2241
                                *(aDestPixels++) =
2242
                                        (r << aRedShift) |
2243
                                        (g << aGreenShift) |
2244
                                        (b << aBlueShift);
2245
                        }                              
2246
 
2247
                        aDestPixelsRow += mLockedSurfaceDesc.lPitch/2;                 
2248
                }
2249
        }
2250
        else if (mLockedSurfaceDesc.ddpfPixelFormat.dwRGBBitCount == 32)
2251
        {
2252
                ulong rc = ((theColor.mRed * theColor.mAlpha) / 255) >> (8-mDDInterface->mRedBits);
2253
                ulong gc = ((theColor.mGreen * theColor.mAlpha) / 255) >> (8-mDDInterface->mGreenBits);
2254
                ulong bc = ((theColor.mBlue * theColor.mAlpha) / 255) >> (8-mDDInterface->mBlueBits);
2255
 
2256
                ulong* aDestPixelsRow = ((ulong*) mLockedSurfaceDesc.lpSurface) + (theRect.mY * mLockedSurfaceDesc.lPitch/4) + theRect.mX;
2257
 
2258
                for (int y = 0; y < theRect.mHeight; y++)
2259
                {
2260
                        ulong* aDestPixels = aDestPixelsRow;                   
2261
 
2262
                        for (int x = 0; x < theRect.mWidth; x++)                       
2263
                        {
2264
                                ulong dest = *aDestPixels;
2265
 
2266
                                int r = aMaxRedTable[((dest & aRMask) >> aRedShift) + rc];
2267
                                int g = aMaxGreenTable[((dest & aGMask) >> aGreenShift) + gc];
2268
                                int b = aMaxBlueTable[((dest & aBMask) >> aBlueShift) + bc];                           
2269
 
2270
                                *(aDestPixels++) =
2271
                                        (r << aRedShift) |
2272
                                        (g << aGreenShift) |
2273
                                        (b << aBlueShift);
2274
                        }                              
2275
 
2276
                        aDestPixelsRow += mLockedSurfaceDesc.lPitch/4;
2277
                }
2278
        }
2279
 
2280
        UnlockSurface();
2281
}
2282
 
2283
void DDImage::NormalBlt(Image* theImage, int theX, int theY, const Rect& theSrcRect, const Color& theColor)
2284
{
2285
        theImage->mDrawn = true;
2286
 
2287
        MemoryImage* aMemoryImage = dynamic_cast<MemoryImage*>(theImage);
2288
        DDImage* aDDImage = dynamic_cast<DDImage*>(theImage);  
2289
 
2290
        if (aMemoryImage != NULL)
2291
        {
2292
                aMemoryImage->CommitBits();            
2293
 
2294
                RECT aDestRect = {theX, theY, theX + theSrcRect.mWidth, theY + theSrcRect.mHeight};
2295
                RECT aSrcRect = {theSrcRect.mX, theSrcRect.mY, theSrcRect.mX + theSrcRect.mWidth, theSrcRect.mY + theSrcRect.mHeight}; 
2296
 
2297
                //TODO:
2298
                if ((aMemoryImage->mIsVolatile) && ((aDDImage == NULL) || (aDDImage->mSurface == NULL)) &&
2299
                        (!mNoLock) && (theColor == Color::White))
2300
                {
2301
                        if (aMemoryImage->mColorTable == NULL)
2302
                        {
2303
                                ulong* aSrcBits = aMemoryImage->GetBits();                     
2304
 
2305
                                #define SRC_TYPE ulong
2306
                                #define NEXT_SRC_COLOR (*(aSrcPixels++))
2307
                                #include "DDI_NormalBlt_Volatile.inc"
2308
                                #undef  SRC_TYPE
2309
                                #undef NEXT_SRC_COLOR
2310
                        }
2311
                        else
2312
                        {                      
2313
                                ulong* aColorTable = aMemoryImage->mColorTable;
2314
                                uchar* aSrcBits = aMemoryImage->mColorIndices;
2315
 
2316
                                #define SRC_TYPE uchar
2317
                                #define NEXT_SRC_COLOR (aColorTable[*(aSrcPixels++)])
2318
 
2319
                                #include "DDI_NormalBlt_Volatile.inc"
2320
 
2321
                                #undef SRC_TYPE
2322
                                #undef NEXT_SRC_COLOR
2323
                        }
2324
                }
2325
                else if ((aMemoryImage->mHasAlpha) || (theColor != Color::White))
2326
                {
2327
                        if (mNoLock)
2328
                                return;                
2329
 
2330
                        LPDIRECTDRAWSURFACE aSurface = GetSurface();
2331
 
2332
                        if (!LockSurface())
2333
                                return;
2334
 
2335
                        // Ensure NativeAlphaData is calculated
2336
                        void *aNativeData = aMemoryImage->GetNativeAlphaData(mDDInterface);
2337
 
2338
                        // Ensure RunLength data is calculated
2339
                        uchar* aSrcRLAlphaData = aMemoryImage->GetRLAlphaData();
2340
 
2341
                        #define _PLUSPLUS ++
2342
                        #define _PLUSEQUALS +=
2343
                        if (aMemoryImage->mColorTable == NULL)
2344
                        {
2345
                                ulong* aSrcPixelsRow = ((ulong*) aNativeData) + (theSrcRect.mY * theImage->mWidth) + theSrcRect.mX;
2346
                                ulong* aSrcPixels;
2347
 
2348
                                #define NEXT_SRC_COLOR (*(aSrcPixels++))
2349
                                #define PEEK_SRC_COLOR (*aSrcPixels)
2350
 
2351
                                #include "DDI_AlphaBlt.inc"
2352
 
2353
                                #undef NEXT_SRC_COLOR
2354
                                #undef PEEK_SRC_COLOR
2355
                        }
2356
                        else
2357
                        {
2358
                                ulong* aNativeColorTable = (ulong*) aNativeData;
2359
 
2360
                                uchar* aSrcPixelsRow = aMemoryImage->mColorIndices + (theSrcRect.mY * theImage->mWidth) + theSrcRect.mX;
2361
                                uchar* aSrcPixels;
2362
 
2363
                                #define NEXT_SRC_COLOR (aNativeColorTable[*(aSrcPixels++)])
2364
                                #define PEEK_SRC_COLOR (aNativeColorTable[*aSrcPixels])
2365
 
2366
                                #include "DDI_AlphaBlt.inc"
2367
 
2368
                                #undef NEXT_SRC_COLOR
2369
                                #undef PEEK_SRC_COLOR
2370
                        }              
2371
 
2372
                        #undef _PLUSPLUS
2373
                        #undef _PLUSEQUALS 
2374
                        UnlockSurface();
2375
                }              
2376
                else if ((aDDImage == NULL) || (aDDImage->mSurface == NULL) || ((!mVideoMemory) && (aDDImage->mVideoMemory)))
2377
                {
2378
                        if (mNoLock)
2379
                                return;
2380
 
2381
                        //TODO: Have some sort of cool thing here
2382
                        LPDIRECTDRAWSURFACE aSurface = GetSurface();
2383
 
2384
                        if (!LockSurface())
2385
                                return;
2386
 
2387
                        void* aNativeAlphaData = aMemoryImage->GetNativeAlphaData(mDDInterface);
2388
 
2389
                        if (aMemoryImage->mColorTable == NULL)
2390
                        {
2391
                                ulong* aSrcPixelsRow = ((ulong*) aNativeAlphaData) + (theSrcRect.mY * theImage->mWidth) + theSrcRect.mX;
2392
                                ulong* aSrcPixels;
2393
 
2394
                                #define NEXT_SRC_COLOR (*(aSrcPixels++))
2395
                                #define PEEK_SRC_COLOR (*aSrcPixels)
2396
 
2397
                                #include "DDI_FastBlt_NoAlpha.inc"
2398
 
2399
                                #undef NEXT_SRC_COLOR
2400
                                #undef PEEK_SRC_COLOR
2401
                        }
2402
                        else
2403
                        {
2404
                                ulong* aNativeAlphaColorTable = (ulong*) aNativeAlphaData;
2405
 
2406
                                uchar* aSrcPixelsRow = aMemoryImage->mColorIndices + (theSrcRect.mY * theImage->mWidth) + theSrcRect.mX;
2407
                                uchar* aSrcPixels;
2408
 
2409
                                #define NEXT_SRC_COLOR (aNativeAlphaColorTable[*(aSrcPixels++)])
2410
                                #define PEEK_SRC_COLOR (aNativeAlphaColorTable[*aSrcPixels])
2411
 
2412
                                #include "DDI_FastBlt_NoAlpha.inc"
2413
 
2414
                                #undef NEXT_SRC_COLOR
2415
                                #undef PEEK_SRC_COLOR
2416
                        }              
2417
                }
2418
                else
2419
                {
2420
                        if (mLockCount > 0)
2421
                                mSurface->Unlock(NULL);
2422
 
2423
                        DDBLTFX aBltFX;
2424
                        ZeroMemory(&aBltFX, sizeof(aBltFX));
2425
                        aBltFX.dwSize = sizeof(aBltFX);
2426
 
2427
                        DWORD aFlags = DDBLT_WAIT;
2428
 
2429
                        if (aDDImage->mHasTrans)
2430
                                aFlags |= DDBLT_KEYSRC;
2431
 
2432
                        HRESULT aResult = GetSurface()->Blt(&aDestRect, aDDImage->GetSurface(), &aSrcRect, aFlags, &aBltFX);
2433
 
2434
                        if (mLockCount > 0)
2435
                        {
2436
                                if (mSurface->Lock(NULL, &mLockedSurfaceDesc, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL) != DD_OK)
2437
                                        return;
2438
                        }
2439
                }
2440
        }
2441
}
2442
 
2443
void DDImage::NormalBltMirror(Image* theImage, int theX, int theY, const Rect& theSrcRectOrig, const Color& theColor)
2444
{
2445
        theImage->mDrawn = true;
2446
 
2447
        Rect theSrcRect = theSrcRectOrig;
2448
//      theSrcRect.mX = (theSrcRect.mX+theSrcRect.mWidth)*-1 + theImage->mWidth;
2449
        theX += theSrcRect.mWidth-1;
2450
 
2451
        MemoryImage* aMemoryImage = dynamic_cast<MemoryImage*>(theImage);
2452
        DDImage* aDDImage = dynamic_cast<DDImage*>(theImage);  
2453
 
2454
        if (aMemoryImage != NULL)
2455
        {
2456
                aMemoryImage->CommitBits();            
2457
 
2458
                if (mNoLock)
2459
                        return;
2460
 
2461
                LPDIRECTDRAWSURFACE aSurface = GetSurface();
2462
 
2463
                if (!LockSurface())
2464
                        return;
2465
 
2466
                // Ensure NativeAlphaData is calculated
2467
                void *aNativeData = aMemoryImage->GetNativeAlphaData(mDDInterface);
2468
 
2469
                // Ensure RunLength data is calculated
2470
                uchar* aSrcRLAlphaData = aMemoryImage->GetRLAlphaData();
2471
 
2472
                #define _PLUSPLUS --
2473
                #define _PLUSEQUALS -=
2474
                if (aMemoryImage->mColorTable == NULL)
2475
                {
2476
                        ulong* aSrcPixelsRow = ((ulong*) aNativeData) + (theSrcRect.mY * theImage->mWidth) + theSrcRect.mX;
2477
                        ulong* aSrcPixels;
2478
 
2479
                        #define NEXT_SRC_COLOR (*(aSrcPixels++))
2480
                        #define PEEK_SRC_COLOR (*aSrcPixels)
2481
 
2482
                        #include "DDI_AlphaBlt.inc"
2483
 
2484
                        #undef NEXT_SRC_COLOR
2485
                        #undef PEEK_SRC_COLOR
2486
                }
2487
                else
2488
                {
2489
                        ulong* aNativeColorTable = (ulong*) aNativeData;
2490
 
2491
                        uchar* aSrcPixelsRow = aMemoryImage->mColorIndices + (theSrcRect.mY * theImage->mWidth) + theSrcRect.mX;
2492
                        uchar* aSrcPixels;
2493
 
2494
                        #define NEXT_SRC_COLOR (aNativeColorTable[*(aSrcPixels++)])
2495
                        #define PEEK_SRC_COLOR (aNativeColorTable[*aSrcPixels])
2496
 
2497
                        #include "DDI_AlphaBlt.inc"
2498
 
2499
                        #undef NEXT_SRC_COLOR
2500
                        #undef PEEK_SRC_COLOR
2501
                }              
2502
 
2503
                #undef _PLUSPLUS
2504
                #undef _PLUSEQUALS 
2505
                UnlockSurface();
2506
        }
2507
}
2508
 
2509
 
2510
void DDImage::AdditiveBlt(Image* theImage, int theX, int theY, const Rect& theSrcRect, const Color& theColor)
2511
{
2512
        theImage->mDrawn = true;
2513
 
2514
        if (mNoLock)
2515
                return;
2516
 
2517
        MemoryImage* aMemoryImage = dynamic_cast<MemoryImage*>(theImage);
2518
        DDImage* aDDImage = dynamic_cast<DDImage*>(theImage);
2519
 
2520
        if (aMemoryImage != NULL)
2521
        {
2522
                if (!LockSurface())
2523
                        return;
2524
 
2525
                // Ensure NativeAlphaData is calculated
2526
                void* aNativeAlphaData = aMemoryImage->GetNativeAlphaData(mDDInterface);
2527
 
2528
                #define _PLUSPLUS ++
2529
                #define _PLUSEQUALS +=
2530
                if (aMemoryImage->mColorTable == NULL)
2531
                {
2532
                        ulong* aSrcPixelsRow = ((ulong*) aNativeAlphaData) + (theSrcRect.mY * theImage->mWidth) + theSrcRect.mX;
2533
                        ulong* aSrcPixels;
2534
 
2535
                        #define NEXT_SRC_COLOR (*(aSrcPixels++))
2536
                        #define PEEK_SRC_COLOR (*aSrcPixels)
2537
 
2538
                        #include "DDI_Additive.inc"
2539
 
2540
                        #undef NEXT_SRC_COLOR
2541
                        #undef PEEK_SRC_COLOR
2542
                }
2543
                else
2544
                {
2545
                        ulong* aNativeAlphaColorTable = (ulong*) aNativeAlphaData;
2546
 
2547
                        uchar* aSrcPixelsRow = aMemoryImage->mColorIndices + (theSrcRect.mY * theImage->mWidth) + theSrcRect.mX;
2548
                        uchar* aSrcPixels;
2549
 
2550
                        #define NEXT_SRC_COLOR (aNativeAlphaColorTable[*(aSrcPixels++)])
2551
                        #define PEEK_SRC_COLOR (aNativeAlphaColorTable[*aSrcPixels])
2552
 
2553
                        #include "DDI_Additive.inc"
2554
 
2555
                        #undef NEXT_SRC_COLOR
2556
                        #undef PEEK_SRC_COLOR
2557
                }
2558
                #undef _PLUSPLUS
2559
                #undef _PLUSEQUALS
2560
 
2561
                UnlockSurface();
2562
        }
2563
}
2564
 
2565
void DDImage::AdditiveBltMirror(Image* theImage, int theX, int theY, const Rect& theSrcRectOrig, const Color& theColor)
2566
{
2567
        theImage->mDrawn = true;
2568
 
2569
        if (mNoLock)
2570
                return;
2571
 
2572
        Rect theSrcRect = theSrcRectOrig;
2573
//      theSrcRect.mX = (theSrcRect.mX+theSrcRect.mWidth)*-1 + theImage->mWidth;
2574
        theX += theSrcRect.mWidth-1;
2575
 
2576
        MemoryImage* aMemoryImage = dynamic_cast<MemoryImage*>(theImage);
2577
        DDImage* aDDImage = dynamic_cast<DDImage*>(theImage);
2578
 
2579
        if (aMemoryImage != NULL)
2580
        {
2581
                if (!LockSurface())
2582
                        return;
2583
 
2584
                // Ensure NativeAlphaData is calculated
2585
                void* aNativeAlphaData = aMemoryImage->GetNativeAlphaData(mDDInterface);
2586
 
2587
                #define _PLUSPLUS --
2588
                #define _PLUSEQUALS -=
2589
                if (aMemoryImage->mColorTable == NULL)
2590
                {
2591
                        ulong* aSrcPixelsRow = ((ulong*) aNativeAlphaData) + (theSrcRect.mY * theImage->mWidth) + theSrcRect.mX;
2592
                        ulong* aSrcPixels;
2593
 
2594
                        #define NEXT_SRC_COLOR (*(aSrcPixels++))
2595
                        #define PEEK_SRC_COLOR (*aSrcPixels)
2596
 
2597
                        #include "DDI_Additive.inc"
2598
 
2599
                        #undef NEXT_SRC_COLOR
2600
                        #undef PEEK_SRC_COLOR
2601
                }
2602
                else
2603
                {
2604
                        ulong* aNativeAlphaColorTable = (ulong*) aNativeAlphaData;
2605
 
2606
                        uchar* aSrcPixelsRow = aMemoryImage->mColorIndices + (theSrcRect.mY * theImage->mWidth) + theSrcRect.mX;
2607
                        uchar* aSrcPixels;
2608
 
2609
                        #define NEXT_SRC_COLOR (aNativeAlphaColorTable[*(aSrcPixels++)])
2610
                        #define PEEK_SRC_COLOR (aNativeAlphaColorTable[*aSrcPixels])
2611
 
2612
                        #include "DDI_Additive.inc"
2613
 
2614
                        #undef NEXT_SRC_COLOR
2615
                        #undef PEEK_SRC_COLOR
2616
                }
2617
                #undef _PLUSPLUS
2618
                #undef _PLUSEQUALS
2619
 
2620
                UnlockSurface();
2621
        }
2622
}
2623
 
2624
void DDImage::Blt(Image* theImage, int theX, int theY, const Rect& theSrcRect, const Color& theColor, int theDrawMode)
2625
{
2626
        theImage->mDrawn = true;
2627
 
2628
        //if (gDebug)
2629
        //      mApp->CopyToClipboard("+DDImage::Blt"); 
2630
 
2631
        DBG_ASSERTE((theColor.mRed >= 0) && (theColor.mRed <= 255));
2632
        DBG_ASSERTE((theColor.mGreen >= 0) && (theColor.mGreen <= 255));
2633
        DBG_ASSERTE((theColor.mBlue >= 0) && (theColor.mBlue <= 255));
2634
        DBG_ASSERTE((theColor.mAlpha >= 0) && (theColor.mAlpha <= 255));
2635
 
2636
        CommitBits();  
2637
 
2638
        if (Check3D(this))
2639
        {
2640
                DDImage* aDDImage = dynamic_cast<DDImage*>(theImage);  
2641
 
2642
                // Special short-circuit 
2643
                if ((aDDImage != NULL) && (aDDImage->mSurface != NULL) &&
2644
                        (mDDInterface->mD3DInterface->mTransformStack.empty()) &&
2645
                        (theDrawMode == Graphics::DRAWMODE_NORMAL) &&
2646
                        (theColor == Color::White) && (!aDDImage->mHasAlpha))
2647
                {
2648
                        if (mLockCount > 0)
2649
                                mSurface->Unlock(NULL);
2650
 
2651
                        DDBLTFX aBltFX;
2652
                        ZeroMemory(&aBltFX, sizeof(aBltFX));
2653
                        aBltFX.dwSize = sizeof(aBltFX);
2654
 
2655
                        DWORD aFlags = DDBLT_WAIT;
2656
 
2657
                        if (aDDImage->mHasTrans)
2658
                                aFlags |= DDBLT_KEYSRC;
2659
 
2660
                        RECT aDestRect = {theX, theY, theX + theSrcRect.mWidth, theY + theSrcRect.mHeight};
2661
                        RECT aSrcRect = {theSrcRect.mX, theSrcRect.mY, theSrcRect.mX + theSrcRect.mWidth, theSrcRect.mY + theSrcRect.mHeight}; 
2662
 
2663
                        HRESULT aResult = GetSurface()->Blt(&aDestRect, aDDImage->GetSurface(), &aSrcRect, aFlags, &aBltFX);
2664
 
2665
                        if (mLockCount > 0)
2666
                        {
2667
                                if (mSurface->Lock(NULL, &mLockedSurfaceDesc, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL) != DD_OK)
2668
                                        return;
2669
                        }
2670
 
2671
                        return;
2672
                }
2673
 
2674
                mDDInterface->mD3DInterface->Blt(theImage,theX,theY,theSrcRect,theColor,theDrawMode);
2675
                return;
2676
        }
2677
 
2678
        if ((mDrawToBits) || (mHasAlpha) || ((mHasTrans) && (!mFirstPixelTrans)) || (mDDInterface->mIs3D && this!=mDDInterface->mNewCursorAreaImage && this!=mDDInterface->mOldCursorAreaImage))
2679
        {
2680
                MemoryImage::Blt(theImage, theX, theY, theSrcRect, theColor, theDrawMode);
2681
                return;
2682
        }      
2683
 
2684
        switch (theDrawMode)
2685
        {
2686
        case Graphics::DRAWMODE_NORMAL:        
2687
                NormalBlt(theImage, theX, theY, theSrcRect, theColor);
2688
                break;
2689
        case Graphics::DRAWMODE_ADDITIVE:
2690
                AdditiveBlt(theImage, theX, theY, theSrcRect, theColor);
2691
                break;
2692
        }
2693
 
2694
        DeleteAllNonSurfaceData();
2695
}
2696
 
2697
void DDImage::BltMirror(Image* theImage, int theX, int theY, const Rect& theSrcRect, const Color& theColor, int theDrawMode)
2698
{
2699
        DBG_ASSERTE((theColor.mRed >= 0) && (theColor.mRed <= 255));
2700
        DBG_ASSERTE((theColor.mGreen >= 0) && (theColor.mGreen <= 255));
2701
        DBG_ASSERTE((theColor.mBlue >= 0) && (theColor.mBlue <= 255));
2702
        DBG_ASSERTE((theColor.mAlpha >= 0) && (theColor.mAlpha <= 255));
2703
 
2704
        CommitBits();  
2705
 
2706
        if (Check3D(this))
2707
        {
2708
                mDDInterface->mD3DInterface->BltMirror(theImage,theX,theY,theSrcRect,theColor,theDrawMode);
2709
                return;
2710
        }
2711
 
2712
        switch (theDrawMode)
2713
        {
2714
        case Graphics::DRAWMODE_NORMAL:        
2715
                NormalBltMirror(theImage, theX, theY, theSrcRect, theColor);
2716
                break;
2717
        case Graphics::DRAWMODE_ADDITIVE:
2718
                AdditiveBltMirror(theImage, theX, theY, theSrcRect, theColor);
2719
                break;
2720
        }
2721
 
2722
        DeleteAllNonSurfaceData();
2723
}
2724
 
2725
void DDImage::BltF(Image* theImage, float theX, float theY, const Rect& theSrcRect, const Rect &theClipRect, const Color& theColor, int theDrawMode)
2726
{
2727
        theImage->mDrawn = true;
2728
 
2729
        if (Check3D(this))
2730
        {
2731
                FRect aClipRect(theClipRect.mX,theClipRect.mY,theClipRect.mWidth,theClipRect.mHeight);
2732
                FRect aDestRect(theX,theY,theSrcRect.mWidth,theSrcRect.mHeight);
2733
 
2734
                FRect anIntersect = aDestRect.Intersection(aClipRect);
2735
                if (anIntersect.mWidth!=aDestRect.mWidth || anIntersect.mHeight!=aDestRect.mHeight)
2736
                {
2737
                        if (anIntersect.mWidth!=0 && anIntersect.mHeight!=0)
2738
                                mDDInterface->mD3DInterface->BltClipF(theImage,theX,theY,theSrcRect,&theClipRect,theColor,theDrawMode);
2739
                }
2740
                else
2741
                        mDDInterface->mD3DInterface->Blt(theImage,theX,theY,theSrcRect,theColor,theDrawMode,true);
2742
 
2743
                return;
2744
        }
2745
        else
2746
                BltRotated(theImage,theX,theY,theSrcRect,theClipRect,theColor,theDrawMode,0,0,0);
2747
}
2748
 
2749
void DDImage::BltRotated(Image* theImage, float theX, float theY, const Rect &theSrcRect, const Rect& theClipRect, const Color& theColor, int theDrawMode, double theRot, float theRotCenterX, float theRotCenterY)
2750
{
2751
        theImage->mDrawn = true;
2752
 
2753
        if (mNoLock)
2754
                return;
2755
 
2756
        CommitBits();
2757
 
2758
        if (Check3D(this))
2759
        {
2760
                mDDInterface->mD3DInterface->BltRotated(theImage,theX,theY,&theClipRect,theColor,theDrawMode,theRot,theRotCenterX,theRotCenterY,theSrcRect);
2761
                return;
2762
        }
2763
 
2764
        if ((mDrawToBits) || (mHasAlpha) || ((mHasTrans) && (!mFirstPixelTrans)) || (mDDInterface->mIs3D))
2765
        {
2766
                MemoryImage::BltRotated(theImage, theX, theY, theSrcRect, theClipRect, theColor, theDrawMode, theRot, theRotCenterX, theRotCenterY);
2767
                return;
2768
        }      
2769
 
2770
        // This BltRotatedClipHelper clipping used to happen in Graphics::DrawImageRotated
2771
        FRect aDestRect;
2772
        if (!BltRotatedClipHelper(theX, theY, theSrcRect, theClipRect, theRot, aDestRect,theRotCenterX,theRotCenterY))
2773
                return;
2774
 
2775
        MemoryImage* aMemoryImage = dynamic_cast<MemoryImage*>(theImage);
2776
        DDImage* aDDImage = dynamic_cast<DDImage*>(theImage);
2777
 
2778
        if (aMemoryImage != NULL)
2779
        {
2780
                aMemoryImage->CommitBits();
2781
 
2782
                if (theDrawMode == Graphics::DRAWMODE_NORMAL)
2783
                {
2784
                        if (aMemoryImage->mColorTable == NULL)
2785
                        {
2786
                                ulong* aSrcBits = aMemoryImage->GetBits() + theSrcRect.mX + theSrcRect.mY*aMemoryImage->GetWidth();                    
2787
 
2788
                                #define SRC_TYPE ulong
2789
                                #define READ_COLOR(ptr) (*(ptr))
2790
 
2791
                                #include "DDI_BltRotated.inc"
2792
 
2793
                                #undef SRC_TYPE
2794
                                #undef READ_COLOR
2795
 
2796
                        }
2797
                        else
2798
                        {                      
2799
                                ulong* aColorTable = aMemoryImage->mColorTable;
2800
                                uchar* aSrcBits = aMemoryImage->mColorIndices + theSrcRect.mX + theSrcRect.mY*aMemoryImage->GetWidth();
2801
 
2802
                                #define SRC_TYPE uchar
2803
                                #define READ_COLOR(ptr) (aColorTable[*(ptr)])
2804
 
2805
                                #include "DDI_BltRotated.inc"
2806
 
2807
                                #undef SRC_TYPE
2808
                                #undef READ_COLOR
2809
                        }
2810
                }
2811
                else
2812
                {
2813
                        if (aMemoryImage->mColorTable == NULL)
2814
                        {
2815
                                ulong* aSrcBits = aMemoryImage->GetBits() + theSrcRect.mX + theSrcRect.mY*aMemoryImage->GetWidth();                    
2816
 
2817
                                #define SRC_TYPE ulong
2818
                                #define READ_COLOR(ptr) (*(ptr))
2819
 
2820
                                #include "DDI_BltRotated_Additive.inc"
2821
 
2822
                                #undef SRC_TYPE
2823
                                #undef READ_COLOR
2824
 
2825
                        }
2826
                        else
2827
                        {                      
2828
                                ulong* aColorTable = aMemoryImage->mColorTable;
2829
                                uchar* aSrcBits = aMemoryImage->mColorIndices + theSrcRect.mX + theSrcRect.mY*aMemoryImage->GetWidth();
2830
 
2831
                                #define SRC_TYPE uchar
2832
                                #define READ_COLOR(ptr) (aColorTable[*(ptr)])
2833
 
2834
                                #include "DDI_BltRotated_Additive.inc"
2835
 
2836
                                #undef SRC_TYPE
2837
                                #undef READ_COLOR
2838
                        }
2839
                }
2840
        }
2841
 
2842
        DeleteAllNonSurfaceData();
2843
}
2844
 
2845
void DDImage::StretchBlt(Image* theImage, const Rect& theDestRectOrig, const Rect& theSrcRectOrig, const Rect& theClipRect, const Color& theColor, int theDrawMode, bool fastStretch)
2846
{
2847
        theImage->mDrawn = true;
2848
 
2849
        DDImage* aSrcDDImage = dynamic_cast<DDImage*>(theImage);
2850
        MemoryImage* aSrcMemoryImage = dynamic_cast<MemoryImage*>(theImage);
2851
 
2852
        CommitBits();
2853
 
2854
        if (Check3D(this))
2855
        {
2856
                mDDInterface->mD3DInterface->StretchBlt(theImage,theDestRectOrig,theSrcRectOrig,&theClipRect,theColor,theDrawMode,fastStretch);
2857
                return;
2858
        }
2859
 
2860
        Rect theDestRect;
2861
        FRect theSrcRect;
2862
        if (!StretchBltClipHelper(theSrcRectOrig,theClipRect,theDestRectOrig,theSrcRect,theDestRect))
2863
                return;
2864
 
2865
        if (fastStretch)
2866
        {
2867
                if ((aSrcDDImage != NULL) && (theColor == Color::White) && (theDrawMode == Graphics::DRAWMODE_NORMAL) &&
2868
                        (!aSrcDDImage->mHasAlpha) && (aSrcDDImage->GetSurface() != NULL))
2869
                {
2870
                        LPDIRECTDRAWSURFACE aSrcSurface = aSrcDDImage->GetSurface();
2871
                        LPDIRECTDRAWSURFACE aDestSurface = GetSurface();
2872
 
2873
                        DDBLTFX aBltFX;
2874
                        ZeroMemory(&aBltFX, sizeof(aBltFX));
2875
                        aBltFX.dwSize = sizeof(aBltFX);
2876
 
2877
                        DWORD aFlags = DDBLT_WAIT;
2878
 
2879
                        if (aSrcDDImage->mHasTrans)
2880
                                aFlags |= DDBLT_KEYSRC;
2881
 
2882
                        RECT aDestRect = {theDestRect.mX, theDestRect.mY, theDestRect.mX + theDestRect.mWidth, theDestRect.mY + theDestRect.mHeight};
2883
                        RECT aSrcRect = {theSrcRect.mX, theSrcRect.mY, theSrcRect.mX + theSrcRect.mWidth, theSrcRect.mY + theSrcRect.mHeight}; 
2884
 
2885
                        if (mLockCount > 0)
2886
                        {
2887
                                mSurface->Unlock(NULL);
2888
                        }
2889
 
2890
                        HRESULT aResult = GetSurface()->Blt(&aDestRect, aSrcDDImage->GetSurface(), &aSrcRect, aFlags, &aBltFX);
2891
 
2892
                        if (mLockCount > 0)
2893
                        {
2894
                                if (mSurface->Lock(NULL, &mLockedSurfaceDesc, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL) != DD_OK)
2895
                                        return;
2896
                        }                      
2897
                }
2898
                else
2899
                {
2900
                        if (aSrcMemoryImage != NULL)
2901
                        {
2902
                                aSrcMemoryImage->CommitBits();
2903
 
2904
                        // Ensure NativeAlphaData is calculated
2905
                                void *aNativeAlphaData = aSrcMemoryImage->GetNativeAlphaData(mDDInterface);
2906
 
2907
                                #define _PLUSPLUS ++
2908
                                if (theDrawMode == Graphics::DRAWMODE_NORMAL)
2909
                                {
2910
                                        if (aSrcMemoryImage->mColorTable == NULL)
2911
                                        {
2912
                                                //ulong* aSrcBits = aSrcMemoryImage->GetBits();         
2913
                                                ulong* aSrcBits = ((ulong*) aNativeAlphaData); 
2914
 
2915
                                                #define SRC_TYPE ulong
2916
                                                #define READ_COLOR(ptr) (*(ptr))
2917
 
2918
                                                #include "DDI_FastStretch.inc"
2919
 
2920
                                                #undef SRC_TYPE
2921
                                                #undef READ_COLOR
2922
                                        }
2923
                                        else
2924
                                        {
2925
                                                ulong* aColorTable = (ulong*) aNativeAlphaData;
2926
                                                uchar* aSrcBits = aSrcMemoryImage->mColorIndices;
2927
 
2928
                                                #define SRC_TYPE uchar
2929
                                                #define READ_COLOR(ptr) (aColorTable[*(ptr)])
2930
 
2931
                                                #include "DDI_FastStretch.inc"
2932
 
2933
                                                #undef SRC_TYPE
2934
                                                #undef READ_COLOR
2935
                                        }
2936
                                }
2937
                                else
2938
                                {
2939
                                        if (aSrcMemoryImage->mColorTable == NULL)
2940
                                        {
2941
                                                //ulong* aSrcBits = aSrcMemoryImage->GetBits();         
2942
                                                ulong* aSrcBits = ((ulong*) aNativeAlphaData); 
2943
 
2944
                                                #define SRC_TYPE ulong
2945
                                                #define READ_COLOR(ptr) (*(ptr))
2946
 
2947
                                                #include "DDI_FastStretch_Additive.inc"
2948
 
2949
                                                #undef SRC_TYPE
2950
                                                #undef READ_COLOR
2951
                                        }
2952
                                        else
2953
                                        {
2954
                                                ulong* aColorTable = (ulong*) aNativeAlphaData;
2955
                                                uchar* aSrcBits = aSrcMemoryImage->mColorIndices;
2956
 
2957
                                                #define SRC_TYPE uchar
2958
                                                #define READ_COLOR(ptr) (aColorTable[*(ptr)])
2959
 
2960
                                                #include "DDI_FastStretch_Additive.inc"
2961
 
2962
                                                #undef SRC_TYPE
2963
                                                #undef READ_COLOR
2964
                                        }
2965
                                }
2966
                                #undef _PLUSPLUS
2967
                        }
2968
                }
2969
        }
2970
        else
2971
        {
2972
                if ((mDrawToBits) || (mHasAlpha) || (mHasTrans) || (mDDInterface->mIs3D))
2973
                {
2974
                        MemoryImage::StretchBlt(theImage, theDestRectOrig, theSrcRectOrig, theClipRect, theColor, theDrawMode, fastStretch);
2975
                        return;
2976
                }
2977
 
2978
                // Stretch it to a temporary image
2979
                MemoryImage aTempImage(mApp);
2980
                Rect aTempRect(0, 0, theDestRect.mWidth, theDestRect.mHeight);
2981
 
2982
                aTempImage.Create(theDestRect.mWidth, theDestRect.mHeight);                    
2983
                if (fastStretch)
2984
                        aTempImage.FastStretchBlt(theImage, aTempRect, theSrcRect, theColor, 0);
2985
                else
2986
                        aTempImage.SlowStretchBlt(theImage, aTempRect, theSrcRect, theColor, 0);
2987
 
2988
                Blt(&aTempImage, theDestRect.mX, theDestRect.mY, aTempRect, theColor, theDrawMode);
2989
        }
2990
 
2991
        DeleteAllNonSurfaceData();
2992
}
2993
 
2994
void DDImage::StretchBltMirror(Image* theImage, const Rect& theDestRectOrig, const Rect& theSrcRectOrig, const Rect& theClipRect, const Color& theColor, int theDrawMode, bool fastStretch)
2995
{
2996
        theImage->mDrawn = true;
2997
 
2998
        DDImage* aSrcDDImage = dynamic_cast<DDImage*>(theImage);
2999
        MemoryImage* aSrcMemoryImage = dynamic_cast<MemoryImage*>(theImage);
3000
 
3001
        CommitBits();
3002
 
3003
        if (Check3D(this))
3004
        {
3005
                mDDInterface->mD3DInterface->StretchBlt(theImage,theDestRectOrig,theSrcRectOrig,&theClipRect,theColor,theDrawMode,fastStretch,true);
3006
                return;
3007
        }
3008
 
3009
        FRect theSrcRect;
3010
        Rect theDestRect;
3011
 
3012
        if (!StretchBltMirrorClipHelper(theSrcRectOrig,theClipRect,theDestRectOrig,theSrcRect,theDestRect))
3013
                return;
3014
 
3015
        theDestRect.mX += theDestRect.mWidth-1;
3016
 
3017
 
3018
        if (aSrcMemoryImage != NULL)
3019
        {
3020
                aSrcMemoryImage->CommitBits();
3021
 
3022
        // Ensure NativeAlphaData is calculated
3023
                void *aNativeAlphaData = aSrcMemoryImage->GetNativeAlphaData(mDDInterface);
3024
 
3025
                #define _PLUSPLUS --
3026
                if (theDrawMode == Graphics::DRAWMODE_NORMAL)
3027
                {
3028
                        if (aSrcMemoryImage->mColorTable == NULL)
3029
                        {
3030
                                //ulong* aSrcBits = aSrcMemoryImage->GetBits();         
3031
                                ulong* aSrcBits = ((ulong*) aNativeAlphaData); 
3032
 
3033
                                #define SRC_TYPE ulong
3034
                                #define READ_COLOR(ptr) (*(ptr))
3035
 
3036
                                #include "DDI_FastStretch.inc"
3037
 
3038
                                #undef SRC_TYPE
3039
                                #undef READ_COLOR
3040
                        }
3041
                        else
3042
                        {
3043
                                ulong* aColorTable = (ulong*) aNativeAlphaData;
3044
                                uchar* aSrcBits = aSrcMemoryImage->mColorIndices;
3045
 
3046
                                #define SRC_TYPE uchar
3047
                                #define READ_COLOR(ptr) (aColorTable[*(ptr)])
3048
 
3049
                                #include "DDI_FastStretch.inc"
3050
 
3051
                                #undef SRC_TYPE
3052
                                #undef READ_COLOR
3053
                        }
3054
                }
3055
                else
3056
                {
3057
                        if (aSrcMemoryImage->mColorTable == NULL)
3058
                        {
3059
                                //ulong* aSrcBits = aSrcMemoryImage->GetBits();         
3060
                                ulong* aSrcBits = ((ulong*) aNativeAlphaData); 
3061
 
3062
                                #define SRC_TYPE ulong
3063
                                #define READ_COLOR(ptr) (*(ptr))
3064
 
3065
                                #include "DDI_FastStretch_Additive.inc"
3066
 
3067
                                #undef SRC_TYPE
3068
                                #undef READ_COLOR
3069
                        }
3070
                        else
3071
                        {
3072
                                ulong* aColorTable = (ulong*) aNativeAlphaData;
3073
                                uchar* aSrcBits = aSrcMemoryImage->mColorIndices;
3074
 
3075
                                #define SRC_TYPE uchar
3076
                                #define READ_COLOR(ptr) (aColorTable[*(ptr)])
3077
 
3078
                                #include "DDI_FastStretch_Additive.inc"
3079
 
3080
                                #undef SRC_TYPE
3081
                                #undef READ_COLOR
3082
                        }
3083
                }
3084
                #undef _PLUSPLUS
3085
        }
3086
 
3087
        DeleteAllNonSurfaceData();
3088
}
3089
 
3090
void DDImage::BltMatrix(Image* theImage, float x, float y, const SexyMatrix3 &theMatrix, const Rect& theClipRect, const Color& theColor, int theDrawMode, const Rect &theSrcRect, bool blend)
3091
{
3092
        theImage->mDrawn = true;
3093
 
3094
        if (Check3D(this))
3095
        {
3096
                mDDInterface->mD3DInterface->BltTransformed(theImage,&theClipRect,theColor,theDrawMode,theSrcRect,theMatrix,blend,x,y,true);
3097
                return;
3098
        }
3099
 
3100
        LPDIRECTDRAWSURFACE aSurface = GetSurface();
3101
        if (!LockSurface())
3102
                return;
3103
 
3104
        int aPixelFormat;
3105
        if (mLockedSurfaceDesc.ddpfPixelFormat.dwRGBBitCount == 32)
3106
                aPixelFormat = 0x888;
3107
        else if (mLockedSurfaceDesc.ddpfPixelFormat.dwRBitMask == 0xf800 && mLockedSurfaceDesc.ddpfPixelFormat.dwGBitMask == 0x07e0 && mLockedSurfaceDesc.ddpfPixelFormat.dwBBitMask == 0x001f)
3108
                aPixelFormat = 0x565;
3109
        else if (mLockedSurfaceDesc.ddpfPixelFormat.dwRBitMask == 0x7c00 && mLockedSurfaceDesc.ddpfPixelFormat.dwGBitMask == 0x03e0 && mLockedSurfaceDesc.ddpfPixelFormat.dwBBitMask == 0x001f)
3110
                aPixelFormat = 0x555;
3111
        else
3112
                DBG_ASSERTE(FALSE);
3113
 
3114
        BltMatrixHelper(theImage,x,y,theMatrix,theClipRect,theColor,theDrawMode,theSrcRect,mLockedSurfaceDesc.lpSurface,mLockedSurfaceDesc.lPitch,aPixelFormat,blend);
3115
 
3116
        UnlockSurface();
3117
 
3118
        DeleteAllNonSurfaceData();
3119
 
3120
}
3121
 
3122
void DDImage::BltTrianglesTex(Image *theTexture, const TriVertex theVertices[][3], int theNumTriangles, const Rect& theClipRect, const Color &theColor, int theDrawMode, float tx, float ty, bool blend)
3123
{
3124
        theTexture->mDrawn = true;
3125
 
3126
        if (Check3D(this))
3127
        {
3128
                mDDInterface->mD3DInterface->DrawTrianglesTex(theVertices,theNumTriangles,theColor,theDrawMode,theTexture,tx,ty,blend);
3129
                return;
3130
        }
3131
 
3132
        LPDIRECTDRAWSURFACE aSurface = GetSurface();
3133
        if (!LockSurface())
3134
                return;
3135
 
3136
        int aPixelFormat;
3137
        if (mLockedSurfaceDesc.ddpfPixelFormat.dwRGBBitCount == 32)
3138
                aPixelFormat = 0x888;
3139
        else if (mLockedSurfaceDesc.ddpfPixelFormat.dwRBitMask == 0xf800 && mLockedSurfaceDesc.ddpfPixelFormat.dwGBitMask == 0x07e0 && mLockedSurfaceDesc.ddpfPixelFormat.dwBBitMask == 0x001f)
3140
                aPixelFormat = 0x565;
3141
        else if (mLockedSurfaceDesc.ddpfPixelFormat.dwRBitMask == 0x7c00 && mLockedSurfaceDesc.ddpfPixelFormat.dwGBitMask == 0x03e0 && mLockedSurfaceDesc.ddpfPixelFormat.dwBBitMask == 0x001f)
3142
                aPixelFormat = 0x555;
3143
        else
3144
                DBG_ASSERTE(FALSE);
3145
 
3146
        BltTrianglesTexHelper(theTexture,theVertices,theNumTriangles,theClipRect,theColor,theDrawMode,mLockedSurfaceDesc.lpSurface,mLockedSurfaceDesc.lPitch,aPixelFormat,tx,ty,blend);
3147
        UnlockSurface();
3148
 
3149
        DeleteAllNonSurfaceData();
3150
}
3151
 
3152
bool DDImage::Palletize()
3153
{
3154
        if (MemoryImage::Palletize())
3155
        {
3156
                // Don't keep around the DDSurface if we palletize the image, that
3157
                // would be a waste of memory           
3158
                DeleteDDSurface();
3159
                return true;
3160
        }
3161
        else
3162
        {              
3163
                return false;
3164
        }
3165
}
3166
 
3167
void DDImage::FillScanLinesWithCoverage(Span* theSpans, int theSpanCount, const Color& theColor, int theDrawMode, const BYTE* theCoverage, int theCoverX, int theCoverY, int theCoverWidth, int theCoverHeight)
3168
{
3169
        if (theSpanCount == 0) return;
3170
 
3171
        if (Check3D(this))
3172
        { // ugh!#@$
3173
                int l = theSpans[0].mX, t = theSpans[0].mY;
3174
                int r = l + theSpans[0].mWidth, b = t;
3175
                for (int i = 1; i < theSpanCount; ++i)
3176
                {
3177
                        l = min(theSpans[i].mX, l);
3178
                        r = max(theSpans[i].mX + theSpans[i].mWidth - 1, r);
3179
                        t = min(theSpans[i].mY, t);
3180
                        b = max(theSpans[i].mY, b);
3181
                }
3182
                for (int i = 0; i < theSpanCount; ++i)
3183
                {
3184
                        theSpans[i].mX -= l;
3185
                        theSpans[i].mY -= t;
3186
                }
3187
 
3188
                MemoryImage aTempImage;
3189
                aTempImage.Create(r-l+1, b-t+1);
3190
                aTempImage.FillScanLinesWithCoverage(theSpans, theSpanCount, theColor, theDrawMode, theCoverage, theCoverX - l, theCoverY - t, theCoverWidth, theCoverHeight);
3191
                Blt(&aTempImage, l, t, Rect(0, 0, r-l+1, b-t+1), Color::White, theDrawMode);
3192
                return;
3193
        }
3194
 
3195
        LPDIRECTDRAWSURFACE aSurface = GetSurface();
3196
 
3197
        if (!LockSurface())
3198
                return;
3199
 
3200
        ulong aRMask = mLockedSurfaceDesc.ddpfPixelFormat.dwRBitMask;
3201
        ulong aGMask = mLockedSurfaceDesc.ddpfPixelFormat.dwGBitMask;
3202
        ulong aBMask = mLockedSurfaceDesc.ddpfPixelFormat.dwBBitMask;
3203
 
3204
        ulong aRRoundAdd = aRMask >> 1;
3205
        ulong aGRoundAdd = aGMask >> 1;
3206
        ulong aBRoundAdd = aBMask >> 1;
3207
 
3208
        if (mLockedSurfaceDesc.ddpfPixelFormat.dwRGBBitCount == 16)
3209
        {
3210
                //ushort src_red                = (((theColor.mRed * (theColor.mAlpha+1)) >> 8) * aRMask) & aRMask;
3211
                //ushort src_green      = (((theColor.mGreen * (theColor.mAlpha+1)) >> 8) * aGMask) & aGMask;
3212
                //ushort src_blue               = (((theColor.mBlue * (theColor.mAlpha+1)) >> 8) * aBMask) & aBMask;
3213
                ushort src =
3214
                        (((theColor.mRed * aRMask) >> 8) & aRMask) |
3215
                        (((theColor.mGreen * aGMask) >> 8) & aGMask) |
3216
                        (((theColor.mBlue * aBMask) >> 8) & aBMask);
3217
                ushort* theBits = (ushort*)mLockedSurfaceDesc.lpSurface;
3218
 
3219
                for (int i = 0; i < theSpanCount; ++i)
3220
                {
3221
                        Span* aSpan = &theSpans[i];
3222
                        int x = aSpan->mX - theCoverX;
3223
                        int y = aSpan->mY - theCoverY;
3224
 
3225
                        ushort* aDestPixels = &theBits[aSpan->mY*mWidth + aSpan->mX];
3226
                        const BYTE* aCoverBits = &theCoverage[y*theCoverWidth+x];
3227
                        for (int w = 0; w < aSpan->mWidth; ++w)
3228
                        {
3229
                                int cover = *aCoverBits++;
3230
                                int a = ((cover+1) * theColor.mAlpha) >> 8;
3231
                                int oma = 256 - a;
3232
                                ushort dest = *aDestPixels;
3233
 
3234
                                *(aDestPixels++) =
3235
                                        ((((dest & aRMask) * oma + (src & aRMask) * a) >> 8) & aRMask) |
3236
                                        ((((dest & aGMask) * oma + (src & aGMask) * a) >> 8) & aGMask) |
3237
                                        ((((dest & aBMask) * oma + (src & aBMask) * a) >> 8) & aBMask);
3238
                        }
3239
                }
3240
        }
3241
        else if (mLockedSurfaceDesc.ddpfPixelFormat.dwRGBBitCount == 32)
3242
        {
3243
                //ulong src_red         = (((theColor.mRed * (theColor.mAlpha+1)) >> 8) * aRMask) & aRMask;
3244
                //ulong src_green               = (((theColor.mGreen * (theColor.mAlpha+1)) >> 8) * aGMask) & aGMask;
3245
                //ulong src_blue                = (((theColor.mBlue * (theColor.mAlpha+1)) >> 8) * aBMask) & aBMask;
3246
                ulong src =
3247
                        (((theColor.mRed * aRMask) >> 8) & aRMask) |
3248
                        (((theColor.mGreen * aGMask) >> 8) & aGMask) |
3249
                        (((theColor.mBlue * aBMask) >> 8) & aBMask);
3250
                ulong* theBits = (ulong*)mLockedSurfaceDesc.lpSurface;
3251
 
3252
                for (int i = 0; i < theSpanCount; ++i)
3253
                {
3254
                        Span* aSpan = &theSpans[i];
3255
                        int x = aSpan->mX - theCoverX;
3256
                        int y = aSpan->mY - theCoverY;
3257
 
3258
                        ulong* aDestPixels = &theBits[aSpan->mY*mWidth + aSpan->mX];
3259
                        const BYTE* aCoverBits = &theCoverage[y*theCoverWidth+x];
3260
                        for (int w = 0; w < aSpan->mWidth; ++w)
3261
                        {
3262
                                int cover = *aCoverBits++;
3263
                                int a = ((cover+1) * theColor.mAlpha) >> 8;
3264
                                int oma = 256 - a;
3265
                                ulong dest = *aDestPixels;
3266
 
3267
                                *(aDestPixels++) =
3268
                                        ((((dest & aRMask) * oma + (src & aRMask) * a) >> 8) & aRMask) |
3269
                                        ((((dest & aGMask) * oma + (src & aGMask) * a) >> 8) & aGMask) |
3270
                                        ((((dest & aBMask) * oma + (src & aBMask) * a) >> 8) & aBMask);
3271
                        }
3272
                }
3273
        }
3274
 
3275
        UnlockSurface();
3276
        DeleteAllNonSurfaceData();
3277
}