]> icculus.org git repositories - btb/d2x.git/blob - unused/win95/ddgr.c
use the orientation parameter of g3_draw_bitmap
[btb/d2x.git] / unused / win95 / ddgr.c
1 /*
2 THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
3 SOFTWARE CORPORATION ("PARALLAX").  PARALLAX, IN DISTRIBUTING THE CODE TO
4 END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
5 ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
6 IN USING, DISPLAYING,  AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
7 SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
8 FREE PURPOSES.  IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
9 CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES.  THE END-USER UNDERSTANDS
10 AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.  
11 COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION.  ALL RIGHTS RESERVED.
12 */
13
14
15
16 #define WIN95
17 #define _WIN32
18 #define WIN32_LEAN_AND_MEAN
19 #include <windows.h>
20 #include "ddraw.h"
21
22 #include <stdlib.h>
23 #include <mem.h>
24
25 #include "winapp.h"
26 #include "mem.h"
27 #include "dxxerror.h"
28 #include "gr.h"
29 #include "dd.h"
30 #include "mono.h"
31
32
33 //      Canvas Globals
34 //      ----------------------------------------------------------------------------
35 int dd_gr_initialized = 0;
36
37 dd_grs_canvas *dd_grd_screencanv = NULL;
38 dd_grs_canvas *dd_grd_backcanv = NULL;
39 dd_grs_canvas *dd_grd_curcanv = NULL;
40
41 static int ddgr_atexit_called = 0;
42
43 extern int _DDLockCounter;
44 extern BOOL _DDSysMemSurfacing;
45 extern int W95OldDisplayMode;
46
47 extern RECT ViewportRect;               // Superhack! (from descentw.c.  Too much trouble
48                                                                                         // to move!)
49
50
51 //      dd_gr_create_canvas
52 //      ----------------------------------------------------------------------------
53 dd_grs_canvas *dd_gr_create_canvas(int w, int h)
54 {
55         dd_grs_canvas *ddnew;
56         grs_canvas *new;
57         DDSCAPS ddsc;
58
59         ddnew = (dd_grs_canvas *)malloc( sizeof(dd_grs_canvas) );
60         ddnew->xoff = ddnew->yoff = 0;
61
62         new = &ddnew->canvas;
63
64         new->cv_bitmap.bm_x = 0;
65         new->cv_bitmap.bm_y = 0;
66         new->cv_bitmap.bm_w = w;
67         new->cv_bitmap.bm_h = h;
68         new->cv_bitmap.bm_flags = 0;
69         new->cv_bitmap.bm_type = BM_LINEAR;
70         new->cv_bitmap.bm_rowsize = 0;
71         new->cv_bitmap.bm_data = NULL;
72
73         new->cv_color = 0;
74         new->cv_drawmode = 0;
75         new->cv_font = NULL;
76         new->cv_font_fg_color = 0;
77         new->cv_font_bg_color = 0;
78
79         ddnew->lpdds = DDCreateSurface(w, h, 0);
80         if (!ddnew->lpdds) 
81                 Error("dd_gr_create_canvas: Unable to create DD Surface");
82         ddnew->lock_count = 0;
83
84         IDirectDrawSurface_GetCaps(ddnew->lpdds, &ddsc); 
85
86         if (ddDriverCaps.offscreen.sysmem) ddnew->sram = 1;
87         else ddnew->sram = 0;           
88
89         return ddnew;
90 }
91
92
93 void dd_gr_init_canvas(dd_grs_canvas *canv, int pixtype, int w, int h)
94 {
95         grs_canvas *new;
96         DDSCAPS ddsc;
97
98         canv->xoff = canv->yoff = 0;
99
100         new = &canv->canvas;
101
102         new->cv_bitmap.bm_x = 0;
103         new->cv_bitmap.bm_y = 0;
104         new->cv_bitmap.bm_w = w;
105         new->cv_bitmap.bm_h = h;
106         new->cv_bitmap.bm_flags = 0;
107         new->cv_bitmap.bm_type = BM_LINEAR;
108         new->cv_bitmap.bm_rowsize = 0;
109         new->cv_bitmap.bm_data = NULL;
110
111         new->cv_color = 0;
112         new->cv_drawmode = 0;
113         new->cv_font = NULL;
114         new->cv_font_fg_color = 0;
115         new->cv_font_bg_color = 0;
116
117         canv->lpdds = DDCreateSurface(w,h,0);
118         if (!canv->lpdds) 
119                 Error("dd_gr_create_canvas: Unable to create DD Surface");
120                 
121         canv->lock_count = 0;
122         IDirectDrawSurface_GetCaps(canv->lpdds, &ddsc);         
123
124         if (ddsc.dwCaps & DDSCAPS_VIDEOMEMORY) canv->sram = 0;
125         else if (ddDriverCaps.offscreen.sysmem) canv->sram = 1;
126         else canv->sram = 0;            
127
128 }
129
130
131 void dd_gr_reinit_canvas(dd_grs_canvas *canv)
132 {
133         grs_canvas *new;
134         DDSURFACEDESC ddsd;
135         LPDIRECTDRAWSURFACE lpdds;      
136
137         ddsd.dwSize = sizeof(ddsd);
138         ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT;
139         IDirectDrawSurface_GetSurfaceDesc(canv->lpdds, &ddsd);
140
141         lpdds = canv->lpdds;
142
143         memset(canv, 0, sizeof(dd_grs_canvas));
144         canv->lpdds = lpdds;
145
146         canv->lock_count = 0;
147         canv->xoff = canv->yoff = 0;
148
149         new = &canv->canvas;
150
151         new->cv_bitmap.bm_x = 0;
152         new->cv_bitmap.bm_y = 0;
153         new->cv_bitmap.bm_w = ddsd.dwWidth;
154         new->cv_bitmap.bm_h = ddsd.dwHeight;
155         new->cv_bitmap.bm_flags = 0;
156         new->cv_bitmap.bm_type = BM_LINEAR;
157         new->cv_bitmap.bm_rowsize = 0;
158         new->cv_bitmap.bm_data = NULL;
159
160         new->cv_color = 0;
161         new->cv_drawmode = 0;
162         new->cv_font = NULL;
163         new->cv_font_fg_color = 0;
164         new->cv_font_bg_color = 0;
165 }
166
167
168 //      dd_gr_free_canvas
169 //      ----------------------------------------------------------------------------
170 void dd_gr_free_canvas(dd_grs_canvas *canvas)
171 {
172         if (canvas == dd_grd_curcanv) { //bad!! freeing current canvas!
173                 DebugBreak();
174                 gr_set_current_canvas(NULL);
175         }
176
177         DDFreeSurface(canvas->lpdds);
178         free(canvas);
179 }
180
181
182 //      dd_gr_create_sub_canvas
183 //      ----------------------------------------------------------------------------
184 dd_grs_canvas *dd_gr_create_sub_canvas(dd_grs_canvas *cvs, 
185                                                                         int x, int y, int w, int h)
186 {
187    dd_grs_canvas *ddnew;
188         grs_canvas *canv;
189         grs_canvas *new;
190
191         canv = &cvs->canvas;
192
193         if (x+w > canv->cv_bitmap.bm_w) {Int3(); w=canv->cv_bitmap.bm_w-x;}
194         if (y+h > canv->cv_bitmap.bm_h) {Int3(); h=canv->cv_bitmap.bm_h-y;}
195
196    ddnew = (dd_grs_canvas *)malloc( sizeof(dd_grs_canvas) );
197         ddnew->xoff = cvs->xoff;
198         ddnew->yoff = cvs->yoff;
199         ddnew->lock_count = 0;
200         ddnew->lpdds = cvs->lpdds;
201         new = &ddnew->canvas;
202
203         new->cv_bitmap.bm_x = x+canv->cv_bitmap.bm_x;
204         new->cv_bitmap.bm_y = y+canv->cv_bitmap.bm_y;
205         new->cv_bitmap.bm_w = w;
206         new->cv_bitmap.bm_h = h;
207         new->cv_bitmap.bm_flags = 0;
208         new->cv_bitmap.bm_type = canv->cv_bitmap.bm_type;
209         new->cv_bitmap.bm_rowsize = 0;
210
211         new->cv_bitmap.bm_data = 0;
212
213         new->cv_color = canv->cv_color;
214    new->cv_drawmode = canv->cv_drawmode;
215    new->cv_font = canv->cv_font;
216         new->cv_font_fg_color = canv->cv_font_fg_color;
217         new->cv_font_bg_color = canv->cv_font_bg_color;
218
219         ddnew->sram = cvs->sram;
220
221    return ddnew;
222 }
223
224
225 //      dd_gr_free_sub_canvas
226 //      ----------------------------------------------------------------------------
227 void dd_gr_free_sub_canvas(dd_grs_canvas *cvs)
228 {
229         free(cvs);
230 }
231
232
233 //      dd_gr_hacks
234 //      ----------------------------------------------------------------------------
235 void dd_gr_dup_hack(dd_grs_canvas *hacked, dd_grs_canvas *src)
236 {
237         hacked->canvas.cv_bitmap.bm_data = src->canvas.cv_bitmap.bm_data;
238         hacked->canvas.cv_bitmap.bm_rowsize = src->canvas.cv_bitmap.bm_rowsize;
239 }
240
241 void dd_gr_dup_unhack(dd_grs_canvas *hacked)
242 {
243         hacked->canvas.cv_bitmap.bm_data = 0;
244         hacked->canvas.cv_bitmap.bm_rowsize = 0;
245 }
246
247
248 //      dd_gr_init
249 //      ----------------------------------------------------------------------------
250 void dd_gr_init()
251 {
252         Assert(!dd_gr_initialized);
253
254         if (!dd_grd_screencanv) 
255                 dd_grd_screencanv = (dd_grs_canvas *)malloc(sizeof(dd_grs_canvas));
256         if (!dd_grd_backcanv) 
257                 dd_grd_backcanv = (dd_grs_canvas *)malloc(sizeof(dd_grs_canvas));
258         
259
260         dd_grd_screencanv->lpdds = NULL;
261         dd_grd_backcanv->lpdds = NULL;  
262
263         if (!ddgr_atexit_called) {
264                 atexit(dd_gr_close);
265                 ddgr_atexit_called = 1;
266         }
267         dd_gr_initialized = 1;
268 }
269
270
271 //      dd_gr_close
272 //      ----------------------------------------------------------------------------
273 void dd_gr_close()
274 {
275         Assert(dd_gr_initialized);
276
277         if (dd_grd_screencanv) free(dd_grd_screencanv);
278         if (dd_grd_backcanv) free(dd_grd_backcanv);
279
280         dd_grd_screencanv = dd_grd_backcanv = NULL;
281         dd_gr_initialized = 0;
282 }       
283
284
285 //      dd_gr_init_screen
286 //      ----------------------------------------------------------------------------
287 void dd_gr_init_screen()
288 {
289         grs_canvas *new;
290
291 // Define screen canvas
292         if (dd_grd_screencanv->lpdds != NULL && !IDirectDrawSurface_IsLost(dd_grd_screencanv->lpdds)) {
293                 gr_palette_clear();
294                 dd_gr_set_current_canvas(NULL);
295                 dd_gr_clear_canvas(BM_XRGB(0,0,0));
296                 if (_DDModeList[W95OldDisplayMode].modex) {
297                         dd_gr_flip();
298                         dd_gr_clear_canvas(BM_XRGB(0,0,0));
299                         dd_gr_flip();
300                 }
301         }
302
303 //      Capture the surface's palette.
304         DDSetDisplayMode(W95DisplayMode, 0);
305         grwin_set_winpalette(_lpDD, _lpDDPalette);
306         gr_palette_clear();
307
308         gr_init_screen(BM_LINEAR, 
309                                         GRMODEINFO(rw), GRMODEINFO(rh), 
310                                         0, 0, 0, NULL);
311         
312         dd_grd_screencanv->lock_count = 0;
313         memcpy(&dd_grd_screencanv->canvas, &grd_curscreen->sc_canvas, sizeof(grs_canvas));
314
315 //      NEW!!!  
316 //      Scheme 1:
317 //              The 'Emulated' Method.
318 //              We will define the screen canvas as the Windows equiv to 
319 //              DOS display memory.   This will be our Direct Draw Back canvas.
320
321         if (GRMODEINFO(emul) || GRMODEINFO(modex)) {
322                 dd_grd_screencanv->lpdds = _lpDDSBack;
323                 dd_grd_backcanv->lpdds = NULL;
324                 dd_grd_curcanv = NULL;
325         }
326         
327 //      Scheme 2:
328 //              The Page Flipping Full Screen Method
329 //              The screen canvas is the actual display
330 //              The back canvas is our scratch page
331 //              This does not apply to Mode X modes
332         
333         else if (GRMODEINFO(paged) && !GRMODEINFO(modex)) {
334                 dd_grd_screencanv->lpdds = _lpDDSPrimary;
335
336                 new = &dd_grd_backcanv->canvas;
337
338                 new->cv_bitmap.bm_x = 0;
339                 new->cv_bitmap.bm_y = 0;
340                 new->cv_bitmap.bm_w = _DDModeList[W95DisplayMode].rw;
341                 new->cv_bitmap.bm_h = _DDModeList[W95DisplayMode].rh;
342                 new->cv_bitmap.bm_flags = 0;
343                 new->cv_bitmap.bm_type = BM_LINEAR;
344                 new->cv_bitmap.bm_rowsize = 0;
345                 new->cv_bitmap.bm_data = NULL;
346
347                 new->cv_color = 0;
348                 new->cv_drawmode = 0;
349                 new->cv_font = NULL;
350                 new->cv_font_fg_color = 0;
351                 new->cv_font_bg_color = 0;
352         
353                 dd_grd_backcanv->lpdds = _lpDDSBack;    
354                 dd_grd_backcanv->lock_count = 0;
355                 dd_grd_curcanv = NULL;
356         }
357
358 //      Scheme 3:
359 //              No page flipping (just 1 page), and no use for back surface.
360
361         else if (GRMODEINFO(dbuf) && !GRMODEINFO(paged)) {
362                 dd_grd_screencanv->lpdds = _lpDDSPrimary;
363                 dd_grd_backcanv->lpdds = NULL;
364                 dd_grd_curcanv = NULL;
365         }
366
367 //      Bad Scheme
368
369         else {
370                 Int3();                                                                 // An illegal hacked graphic mode
371         }
372
373         dd_gr_set_current_canvas(NULL);
374         dd_gr_clear_canvas(BM_XRGB(0,0,0));
375 //      if (GRMODEINFO(modex)) {
376 //              dd_gr_flip();
377 //              dd_gr_clear_canvas(BM_XRGB(0,0,0));
378 //              dd_gr_flip();
379 //      }
380 }
381
382
383 int dd_gr_restore_canvas(dd_grs_canvas *canvas)
384 {
385         if (!DDRestoreSurface(canvas->lpdds)) {
386         //      Recreate surface
387                 DDFreeSurface(canvas->lpdds);
388                 if (canvas->sram) {
389                         canvas->lpdds = DDCreateSysMemSurface(canvas->canvas.cv_bitmap.bm_w,
390                                                                                         canvas->canvas.cv_bitmap.bm_h);
391                 }
392                 else {
393                         canvas->lpdds = DDCreateSurface(canvas->canvas.cv_bitmap.bm_w,
394                                                                                         canvas->canvas.cv_bitmap.bm_h, TRUE);
395                 }
396                 if (!canvas->lpdds) return 0;
397         }
398         return 1;
399 }
400         
401         
402
403 //      dd_gr_screen_lock
404 //              copies dd_gr_screencanv to grd_curscreen->sc_canvas
405 //      ----------------------------------------------------------------------------
406 void dd_gr_screen_lock()
407 {
408         if (dd_grd_screencanv->lpdds == _lpDDSPrimary && GRMODEINFO(modex)) 
409                 Int3();                                                                 // Can't do this in ModeX!!
410         dd_gr_lock(dd_grd_screencanv);
411         memcpy(&grd_curscreen->sc_canvas, &dd_grd_screencanv->canvas, sizeof(grs_canvas)); 
412 }
413
414
415 //      dd_gr_screen_unlock
416 //              copies grd_curscreen->sc_canvas to dd_gr_screencanv
417 //      ----------------------------------------------------------------------------
418 void dd_gr_screen_unlock()
419 {
420         memcpy(&dd_grd_screencanv->canvas, &grd_curscreen->sc_canvas, sizeof(grs_canvas)); 
421         dd_gr_unlock(dd_grd_screencanv);
422 }
423
424
425 void dd_gr_lock(dd_grs_canvas *canv)
426 {
427         RECT rect;
428         ubyte *data;
429         grs_bitmap *bmp;
430         int rowsize;
431
432         if (canv->lock_count == 0) 
433         {
434                 bmp = &canv->canvas.cv_bitmap;
435                 SetRect(&rect,bmp->bm_x,bmp->bm_y,bmp->bm_x+bmp->bm_w, bmp->bm_y+bmp->bm_h);
436
437                 if (!dd_gr_restore_canvas(canv)) 
438                         Error("Failed to lock canvas (restore err)!\n");
439
440                 data = DDLockSurface(canv->lpdds, &rect, &rowsize);
441                 canv->canvas.cv_bitmap.bm_rowsize = (short)rowsize;
442                 
443                 if (!data) 
444                         Error("Failed to lock canvas! You may need to use the -emul option.\n");
445
446                 canv->canvas.cv_bitmap.bm_data = data;
447
448                 if (canv == dd_grd_curcanv) {
449                         gr_set_current_canvas(&canv->canvas);
450                 }
451         }       
452         canv->lock_count++;
453 }
454
455
456 void dd_gr_lock_d(dd_grs_canvas *canv, char *filename, int line)
457 {
458         RECT rect;
459         ubyte *data;
460         grs_bitmap *bmp;
461         int rowsize;
462
463         if (canv->lock_count == 0) 
464         {
465                 bmp = &canv->canvas.cv_bitmap;
466                 SetRect(&rect,bmp->bm_x,bmp->bm_y,bmp->bm_x+bmp->bm_w, bmp->bm_y+bmp->bm_h);
467
468                 if (!dd_gr_restore_canvas(canv)) 
469                 #ifndef NDEBUG
470                         Error("Failed to lock canvas (restore err) (%s line %d)\n", filename, line);
471                 #else
472                         Error("Failed to lock canvas (restore err)!\n");
473                 #endif  
474                 
475                 data = DDLockSurface(canv->lpdds, &rect, &rowsize);
476                 canv->canvas.cv_bitmap.bm_rowsize = (short)rowsize;
477                 
478                 if (!data) 
479                 #ifndef NDEBUG
480                         Error("Failed to lock canvas (%s line %d)\n", filename, line);
481                 #else
482                         Error("Failed to lock canvas! You may ned to use the -emul option.\n");
483                 #endif  
484
485                 canv->canvas.cv_bitmap.bm_data = data;
486
487                 if (canv == dd_grd_curcanv) {
488                         gr_set_current_canvas(&canv->canvas);
489                 }
490         }
491
492         canv->lock_count++;
493 }
494
495
496 void dd_gr_unlock(dd_grs_canvas *canv)
497 {
498         if (canv->lock_count == 1) 
499         {
500                 DDUnlockSurface(canv->lpdds, canv->canvas.cv_bitmap.bm_data);
501         }
502         canv->lock_count--;
503 }
504
505
506 //      dd_gr_set_current_canvas
507 //              This function should do this:
508 //                      set desired canvas to dd_grd_curcanv
509 //                      call gr_set_current_canvas
510 //              
511 //              If desired canvas is NULL, then set current canvas to screen
512 //                      set grd_curscreen->sc_canvas.cv_bitmap, etc to dd_grd_screencanv info
513 //                      call gr_set_current_canvas(NULL)
514 //                              this will use what is in grd_curscreen->etc to do the proper thing
515 //
516 //              Note: Must lock desired canvas before calling this.
517 //                              This causes an address to be delivered to the canvas.
518 //                              Else address is invalid and will crash.
519
520 void dd_gr_set_current_canvas(dd_grs_canvas *canvas)
521 {
522         if (canvas == NULL) {
523                 dd_grd_curcanv = dd_grd_screencanv;
524                 gr_set_current_canvas(&dd_grd_screencanv->canvas);
525         }
526         else {
527                 dd_grd_curcanv = canvas;
528                 gr_set_current_canvas(&dd_grd_curcanv->canvas);
529         }
530 }
531
532
533 //      dd_gr_init_sub_canvas
534 //              perform gr_init_sub_canvas.
535 //              same surface but reset lock count.
536 void dd_gr_init_sub_canvas(dd_grs_canvas *new, dd_grs_canvas *src, 
537                                                                         int x, int y, int w, int h)
538 {
539         gr_init_sub_canvas(&new->canvas, &src->canvas, x, y, w, h);
540         new->xoff = src->xoff;
541         new->yoff = src->yoff;
542         new->lpdds = src->lpdds;
543         new->lock_count = 0;
544         new->sram = src->sram;
545 }
546
547
548 //      dd_gr_flip()
549 //              performs a general 'flip' of canvases.
550 //              If we are in a slow display mode, we will copy the screen canvas
551 //              to the display
552 //              If we are in a FullScreen mode, then we will just perform a
553 //              Direct Draw Flip.
554 void dd_gr_flip()
555 {
556         if (GRMODEINFO(emul)) {
557                 dd_gr_blt_display(dd_grd_screencanv, 
558                                                 0,0,0,0,        
559                                                 ViewportRect.left, ViewportRect.top, 
560                                                 ViewportRect.right-ViewportRect.left, 
561                                                 ViewportRect.bottom-ViewportRect.top);
562         }
563         else if (_DDFullScreen) {
564                 DDFlip();
565         }
566         else {                   
567                 Int3();                                                                 // Illegal display mode!
568         }
569 }
570
571
572 //      dd_gr_restore_display
573 //              blts the screen canvas to the display 
574 //              (for Slow modes which emulate a DOS display)
575 void dd_gr_restore_display()
576 {
577         if (GRMODEINFO(emul)) {
578         //      We use a offscreen buffer as grd_screencanv, so just
579         // blt this to the display
580
581                 IDirectDrawSurface_Blt(_lpDDSPrimary,
582                                         NULL,
583                                         dd_grd_screencanv->lpdds,
584                                         NULL,
585                                         DDBLT_WAIT,
586                                         NULL);
587         }
588         else if (GRMODEINFO(modex)) {
589 //              dd_gr_flip();
590         }
591 }
592
593
594 //      DD Blt Functions
595 //
596 //      dd_gr_blt_notrans
597 //              blts one canvas region to another canvas with scaling and
598 //              no color keying
599 void dd_gr_blt_notrans(dd_grs_canvas *srccanv,
600                                         int sx, int sy, int swidth, int sheight,
601                                         dd_grs_canvas *destcanv, 
602                                         int dx, int dy, int dwidth, int dheight)
603 {
604         RECT srect, drect;
605         RECT *psrect, *pdrect;
606         grs_bitmap *sbmp, *dbmp;
607
608         psrect = &srect;
609         pdrect = &drect;
610         sbmp = &srccanv->canvas.cv_bitmap;
611         dbmp = &destcanv->canvas.cv_bitmap;
612
613         if (swidth || sheight) {
614                 SetRect(psrect, sx+sbmp->bm_x, sy+sbmp->bm_y, sx+sbmp->bm_x+swidth, 
615                                         sy+sbmp->bm_y+sheight);
616         }
617         else {
618                 SetRect(psrect, sbmp->bm_x, sbmp->bm_y, sbmp->bm_w+sbmp->bm_x,
619                                                         sbmp->bm_h+sbmp->bm_y);
620         }
621
622         if (dwidth || dheight) {
623                 SetRect(pdrect, dx+dbmp->bm_x, dy+dbmp->bm_y, dx+dbmp->bm_x+dwidth, 
624                                         dy+dbmp->bm_y+dheight);
625         }
626         else {
627                 SetRect(pdrect, dbmp->bm_x, dbmp->bm_y, dbmp->bm_x+dbmp->bm_w, 
628                                         dbmp->bm_y+dbmp->bm_h);
629         }
630
631         if (_DDFullScreen && !GRMODEINFO(emul)) {
632                 IDirectDrawSurface_BltFast(destcanv->lpdds, dx+dbmp->bm_x, dy+dbmp->bm_y,               
633                                                         srccanv->lpdds, psrect, 
634                                                         DDBLTFAST_NOCOLORKEY | DDBLTFAST_WAIT);
635         }               
636         else {
637                 IDirectDrawSurface_Blt(destcanv->lpdds,
638                                         pdrect,
639                                         srccanv->lpdds,
640                                         psrect,
641                                         DDBLT_WAIT,
642                                         NULL);
643         }
644 }
645
646
647 //      dd_gr_blt_display        (no keying)
648 //              blts a canvas region to the display.
649 //              for windowed modes, this is the only way to blt
650 //              a canvas to the display.
651 void dd_gr_blt_display(dd_grs_canvas *srccanv,
652                                         int sx, int sy, int swidth, int sheight,
653                                         int dx, int dy, int dwidth, int dheight)
654 {
655         RECT srect, drect;
656         RECT *psrect, *pdrect;
657         HRESULT result;
658         grs_bitmap *sbmp;
659
660         if (srccanv->lpdds == _lpDDSPrimary) {
661                 Int3();                                                                 // This will crash the system
662         }
663
664
665         psrect = &srect;
666         pdrect = &drect;
667         sbmp = &srccanv->canvas.cv_bitmap;
668
669         if (swidth || sheight) {
670                 SetRect(psrect, sx+sbmp->bm_x, sy+sbmp->bm_y, sx+sbmp->bm_x+swidth-1, 
671                                         sy+sbmp->bm_y+sheight-1);
672         }
673         else {
674                 SetRect(psrect, sbmp->bm_x, sbmp->bm_y, sbmp->bm_w+sbmp->bm_x-1,
675                                                         sbmp->bm_h+sbmp->bm_y-1);
676         }
677
678         if (dwidth || dheight) {
679                 SetRect(pdrect, dx, dy, dx+dwidth-1, dy+dheight-1);
680         }
681         else pdrect = NULL;
682
683 //      We are blting to the display which is _lpDDSPrimary.
684         result = IDirectDrawSurface_Blt(_lpDDSPrimary,
685                                         pdrect,
686                                         srccanv->lpdds,
687                                         psrect,
688                                         DDBLT_WAIT,
689                                         NULL);
690         if (result != DD_OK) 
691                 Error("DDERR: Blt: (%d)\n", (result & 0x0000ffff));
692 }
693
694
695 //      dd_gr_blt_screen         (no keying)
696 //              blts canvas to screen canvas
697 void dd_gr_blt_screen(dd_grs_canvas *srccanv,
698                                         int sx, int sy, int swidth, int sheight,
699                                         int dx, int dy, int dwidth, int dheight)
700 {
701         dd_gr_blt_notrans(srccanv, sx, sy, swidth, sheight,
702                                                         dd_grd_screencanv, dx, dy, dwidth, dheight);
703 }
704
705
706 //      dd_gr_clear_canvas
707 //              clears a canvas the 'fast' way.
708 void dd_gr_clear_canvas(int color)
709 {
710     DDBLTFX     ddbltfx;
711     HRESULT     ddresult;
712          RECT            drect;
713          grs_bitmap      *bmp;
714
715          bmp = &dd_grd_curcanv->canvas.cv_bitmap;
716
717          UpdateWindow(GetLibraryWindow());
718
719     ddbltfx.dwSize = sizeof( ddbltfx );
720     ddbltfx.dwFillColor = (DWORD)color;
721
722     Assert(_DDLockCounter == 0);
723
724          SetRect(&drect, bmp->bm_x, bmp->bm_y, bmp->bm_x+bmp->bm_w, 
725                                         bmp->bm_y+bmp->bm_h);
726
727     ddresult = IDirectDrawSurface_Blt(
728                             dd_grd_curcanv->lpdds,  // dest surface
729                             &drect,                 // dest rect
730                             NULL,                   // src surface
731                             NULL,                   // src rect
732                             DDBLT_COLORFILL | DDBLT_WAIT,
733                             &ddbltfx);
734          if (ddresult != DD_OK) {
735                 if (ddresult == DDERR_SURFACELOST) {
736                         if (!dd_gr_restore_canvas(dd_grd_curcanv))
737                                 Error("Direct Draw GR library Blt Clear Restore error.");
738                 }               
739                 else Error("Direct Draw GR library Blt Clear error: %x", ddresult);
740          }
741
742         if (!_DDFullScreen) {
743                 Assert(_DDLockCounter == 0);            
744                 DDGRRESTORE;
745         }
746 }
747
748
749
750
751
752
753
754
755
756
757