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