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