Cygwin support, using SDL.
[btb/d2x.git] / unused / win95 / ddgfx.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: ddgfx.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
24 #include <windows.h>
25 #include <stdlib.h>
26 #include "win\ddraw.h"
27 #include "dd.h"
28
29
30 #include "fix.h"
31 #include "gr.h"
32 #include "rle.h"
33 #include "mono.h"
34 #include "error.h"
35 #include "args.h"
36 #include "winapp.h"
37
38
39 #define MAX_GFX_BITMAPS         512
40
41
42 // Data!
43
44 static BOOL dd_gfx_initialized = 0;
45 static unsigned short gfxBitmapHandleCur = 1;
46
47 static struct _gfxBitmap {
48         LPDIRECTDRAWSURFACE lpdds;
49         int w;
50         int h;
51 } gfxBitmap[MAX_GFX_BITMAPS];
52
53
54 //      Functions
55
56 int dd_gfx_init()
57 {
58         int i;
59         
60         if (dd_gfx_initialized) return 1;
61
62         for (i = 0; i < MAX_GFX_BITMAPS; i++)
63                 gfxBitmap[i].lpdds = NULL;
64
65         gfxBitmapHandleCur = 1;
66
67         atexit(dd_gfx_close);
68
69
70         if (FindArg("-disallowgfx")) dd_gfx_initialized = 0;
71         else if (FindArg("-forcegfx")) dd_gfx_initialized = 1;
72         else {
73                 if (ddDriverCaps.hwcolorkey) 
74                         logentry("Card supports HW colorkeying.\n");
75
76                 if (ddDriverCaps.hwbltstretch)
77                         logentry("Card supports HW bitmap stretching.\n");
78                 
79                 if (ddDriverCaps.hwcolorkey) dd_gfx_initialized = 1;
80                 else dd_gfx_initialized = 0;
81         }
82
83         return 0;
84 }
85
86
87 int dd_gfx_close()
88 {
89         int i;
90
91         if (!dd_gfx_initialized) return 1;
92
93         for (i = 0; i < MAX_GFX_BITMAPS; i++)
94         {
95                 if (gfxBitmap[i].lpdds)
96                         IDirectDrawSurface_Release(gfxBitmap[i].lpdds);
97         }
98         
99         dd_gfx_initialized =0;
100
101         return 0;
102 }
103
104
105 unsigned short dd_gfx_createbitmap2D(int w, int h)
106 {
107         int i, force;
108         unsigned short handle;
109
110         if (!dd_gfx_initialized) return 0;
111
112         for (i = 0; i < MAX_GFX_BITMAPS; i++)
113                 if (!gfxBitmap[i].lpdds) {
114                         handle = (unsigned short)(i);
115                         break;
116                 }
117
118         if (i == MAX_GFX_BITMAPS) return 0;
119
120 //      Only do this if we can benefit from it.
121 //      if (ddDriverCaps.hwcolorkey && ddDriverCaps.hwbltstretch) 
122
123         if (FindArg("-forcegfx"))       force = 1;
124         else force = 0;
125
126         if (ddDriverCaps.hwcolorkey || force) 
127         {
128                 LPDIRECTDRAWSURFACE lpdds;
129                 DDSURFACEDESC ddsd;
130                 HRESULT ddresult;
131                 DDCOLORKEY ddck;
132
133                 memset(&ddsd, 0, sizeof(ddsd));
134                 ddsd.dwSize = sizeof(ddsd);
135                 ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
136                 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY;
137                 ddsd.dwWidth = w;
138                 ddsd.dwHeight = h;
139
140                 ddresult = IDirectDraw_CreateSurface(_lpDD, &ddsd, &lpdds, NULL);
141
142                 if (ddresult != DD_OK) {
143                         mprintf((0, "DDGFX: Failed to create vidmem 2d bitmap (%x).\n", ddresult));
144                         return 0;
145                 }
146       ddck.dwColorSpaceLowValue = TRANSPARENCY_COLOR;
147       ddck.dwColorSpaceHighValue = TRANSPARENCY_COLOR;
148       IDirectDrawSurface_SetColorKey(lpdds, DDCKEY_SRCBLT, &ddck);
149
150                 gfxBitmap[handle].lpdds = lpdds;
151                 gfxBitmap[handle].w = w;
152                 gfxBitmap[handle].h = h; 
153                 handle++;                                                                       // Make it a valid handle       
154         }
155         else handle = 0;
156
157         return handle;
158 }       
159
160
161 int dd_gfx_loadbitmap2D(unsigned short handle, void *buf, int rleflag)
162 {
163         HRESULT ddresult;
164         DDSURFACEDESC ddsd;
165         char *ptr;
166         int pitch, i;
167         grs_bitmap tbmp;
168
169         Assert(handle != 0);
170
171         if (!dd_gfx_initialized) return 0;
172
173         handle--;                                                                       // Convert to valid handle
174
175 RedoLock:
176
177         memset(&ddsd, 0, sizeof(ddsd));
178         ddsd.dwSize = sizeof(ddsd);
179
180         ddresult = IDirectDrawSurface_Lock(gfxBitmap[handle].lpdds, NULL,       &ddsd, DDLOCK_WAIT, NULL);
181         if (ddresult != DD_OK) {
182                 if (ddresult == DDERR_SURFACELOST) {
183                         ddresult = IDirectDrawSurface_Restore(gfxBitmap[handle].lpdds);
184                         if (ddresult != DD_OK) {
185                                 if (ddresult != DDERR_WRONGMODE) {
186                                         logentry("DDGFX::Restore::Surface err: %x\n", ddresult);                
187                                         return 1;
188                                 }
189                                 else {
190                                         LPDIRECTDRAWSURFACE lpdds;
191                                         DDCOLORKEY ddck;
192
193                                         IDirectDrawSurface_Release(lpdds);
194                                         gfxBitmap[handle].lpdds = NULL;
195
196                                         memset(&ddsd, 0, sizeof(ddsd));
197                                         ddsd.dwSize = sizeof(ddsd);
198                                         ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
199                                         ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY;
200                                         ddsd.dwWidth = gfxBitmap[handle].w;
201                                         ddsd.dwHeight = gfxBitmap[handle].h;
202
203                                         ddresult = IDirectDraw_CreateSurface(_lpDD, &ddsd, &lpdds, NULL);
204
205                                         if (ddresult != DD_OK) {
206                                                 mprintf((0, "DDGFX: Failed to restore vidmem 2d bitmap.\n"));
207                                                 return 1;
208                                         }
209                                 ddck.dwColorSpaceLowValue = TRANSPARENCY_COLOR;
210                                 ddck.dwColorSpaceHighValue = TRANSPARENCY_COLOR;
211                                 IDirectDrawSurface_SetColorKey(lpdds, DDCKEY_SRCBLT, &ddck);
212                                         gfxBitmap[handle].lpdds = lpdds;
213                                 }
214                         }
215                         
216                         goto RedoLock;
217                 }
218                 else {
219                         mprintf((0, "DDGFX:Unable to lock surface!!\n"));
220                         return 1;
221                 }
222         }
223
224 //      Locked!
225         ptr = ddsd.lpSurface;
226         pitch = ddsd.lPitch;    
227
228         gr_init_bitmap(&tbmp, BM_LINEAR, 0,0,gfxBitmap[handle].w, gfxBitmap[handle].h, gfxBitmap[handle].w, buf);
229         if (rleflag) tbmp.bm_flags = BM_FLAG_RLE;
230
231         for(i = 0; i < gfxBitmap[handle].h; i++) 
232         {
233                 extern ubyte scale_rle_data[];
234                 if (rleflag) {
235                         decode_row(&tbmp,i);
236                         memcpy(ptr+(i*pitch), scale_rle_data, gfxBitmap[handle].w);
237                 } 
238                 else memcpy(ptr+(i*pitch), (ubyte*)(buf)+(i*gfxBitmap[handle].w), gfxBitmap[handle].w);
239         }
240         
241         IDirectDrawSurface_Unlock(gfxBitmap[handle].lpdds, ptr);
242
243 //      Unlocked...
244
245         return 0;
246 }
247
248         
249 int dd_gfx_destroybitmap2D(unsigned short handle)
250 {
251         if (!dd_gfx_initialized) return 0;
252
253         if (handle == 0) return 1;
254         handle--;                                                                       // Convert to valid handle
255
256         if (gfxBitmap[handle].lpdds) {
257                 IDirectDrawSurface_Release(gfxBitmap[handle].lpdds);
258                 gfxBitmap[handle].lpdds = NULL;
259                 return 0;
260         }
261         else return 1;
262 }               
263
264
265 int dd_gfx_resetbitmap2Dcache()
266 {
267         int i;
268
269         if (!dd_gfx_initialized) return 0;
270
271         for (i = 0; i < MAX_GFX_BITMAPS; i++)
272                 dd_gfx_destroybitmap2D(i+1);
273
274         return 0;
275 }
276                 
277                 
278 void dd_gfx_blt2D(unsigned short handle, int x, int y, int x2, int y2,
279                                                 fix u0, fix v0, fix u1, fix v1)
280 {
281         RECT drect, srect;
282
283         if (!dd_gfx_initialized) return;
284
285         Assert(handle != 0);
286         handle--;                                                                       // Convert to valid handle
287
288         SetRect(&drect, x,y,x2,y2);
289         SetRect(&srect, f2i(u0), f2i(v0), f2i(u1), f2i(v1));
290
291         IDirectDrawSurface_Blt(dd_grd_curcanv->lpdds, &drect,
292                                         gfxBitmap[handle].lpdds, 
293                                         &srect, DDBLT_WAIT| DDBLT_KEYSRC,
294                                         NULL);
295 }