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 // ----------------------------------------------------------------------------
dd_gr_create_canvas(int w,int h)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
dd_gr_init_canvas(dd_grs_canvas * canv,int pixtype,int w,int h)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
dd_gr_reinit_canvas(dd_grs_canvas * canv)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 // ----------------------------------------------------------------------------
dd_gr_free_canvas(dd_grs_canvas * canvas)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 // ----------------------------------------------------------------------------
dd_gr_create_sub_canvas(dd_grs_canvas * cvs,int x,int y,int w,int h)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 // ----------------------------------------------------------------------------
dd_gr_free_sub_canvas(dd_grs_canvas * cvs)231 void dd_gr_free_sub_canvas(dd_grs_canvas *cvs)
232 {
233 free(cvs);
234 }
235
236
237 // dd_gr_hacks
238 // ----------------------------------------------------------------------------
dd_gr_dup_hack(dd_grs_canvas * hacked,dd_grs_canvas * src)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
dd_gr_dup_unhack(dd_grs_canvas * hacked)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 // ----------------------------------------------------------------------------
dd_gr_init()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 // ----------------------------------------------------------------------------
dd_gr_close()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 // ----------------------------------------------------------------------------
dd_gr_init_screen()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
dd_gr_restore_canvas(dd_grs_canvas * canvas)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 // ----------------------------------------------------------------------------
dd_gr_screen_lock()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 // ----------------------------------------------------------------------------
dd_gr_screen_unlock()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
dd_gr_lock(dd_grs_canvas * canv)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
dd_gr_lock_d(dd_grs_canvas * canv,char * filename,int line)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
dd_gr_unlock(dd_grs_canvas * canv)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
dd_gr_set_current_canvas(dd_grs_canvas * canvas)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.
dd_gr_init_sub_canvas(dd_grs_canvas * new,dd_grs_canvas * src,int x,int y,int w,int h)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.
dd_gr_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)
dd_gr_restore_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
dd_gr_blt_notrans(dd_grs_canvas * srccanv,int sx,int sy,int swidth,int sheight,dd_grs_canvas * destcanv,int dx,int dy,int dwidth,int dheight)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.
dd_gr_blt_display(dd_grs_canvas * srccanv,int sx,int sy,int swidth,int sheight,int dx,int dy,int dwidth,int dheight)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
dd_gr_blt_screen(dd_grs_canvas * srccanv,int sx,int sy,int swidth,int sheight,int dx,int dy,int dwidth,int dheight)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.
dd_gr_clear_canvas(int color)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
762