update
[btb/d2x.git] / arch / win32 / win32.c
1 #define WIN32_LEAN_AND_MEAN
2 #include <windows.h>
3 #include <stdio.h>
4 #include "gr.h"
5 #include "grdef.h"
6 #include "u_mem.h"
7 #include "timer.h"
8 #include "error.h"
9
10 #include "gr.h"
11 #include "grdef.h"
12 #include "palette.h"
13 #include "rle.h"
14 #include "d3dhelp.h"
15 #include "game.h"
16 #include "gauges.h"
17 #include "args.h"
18
19 #include "gamefont.h"
20
21 #ifndef NDEBUG
22 #ifdef _MSC_VER
23 #include <crtdbg.h>
24 #endif
25 #endif
26
27 void gr_linear_rep_movsdm(ubyte *src, ubyte *dest, int num_pixels);
28 void InitMain();
29 void show_dd_error(HRESULT hr, char *loc);
30 void GetDDErrorString(HRESULT hr, char *buf, int size);
31
32 void BlitToPrimary(HDC hSrcDC);
33 void BlitToPrimaryRect(HDC hSrcDC, int x, int y, int w, int h, 
34         unsigned char *dst);
35 extern HWND g_hWnd;
36
37 void key_init(void);
38 void mouse_init(void);
39
40
41 unsigned char *createdib(void);
42
43 static unsigned char *backbuffer, *screenbuffer;
44 static int screensize;
45 static HBITMAP screen_bitmap;
46
47 void arch_init_start()
48 {
49         #ifndef NDEBUG
50         #ifdef _MSC_VER
51         if (FindArg("-memdbg"))
52                 _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_CHECK_ALWAYS_DF | 
53                         /* _CRTDBG_CHECK_CRT_DF | */
54                         _CRTDBG_DELAY_FREE_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
55         #endif
56         #endif
57
58         InitMain ();
59 }
60
61 void arch_init()
62 {
63         //SetPriorityClass (GetCurrentProcess(),HIGH_PRIORITY_CLASS);
64
65         timer_init ();
66         key_init();
67         mouse_init();
68
69         printf("arch_init successfully completed\n");
70 }
71
72
73
74
75 int gr_installed = 0;
76
77 int gr_check_mode(int mode)
78 {
79         if (mode == SM_320x200C)
80                 return 0;
81
82         return 11;
83 }
84
85 int gr_set_mode(int mode)
86 {
87         unsigned int w,h,t,r;
88
89         if (mode == SM_ORIGINAL)
90                 return 0;
91
92         switch (mode)
93         {
94         case SM(320,200):
95                 w = 320; r = 320; h = 200; t=BM_LINEAR;//BM_DIRECTX;;
96                 break;
97         default:
98                 return 1;
99         }
100
101         gr_palette_clear();
102
103         memset( grd_curscreen, 0, sizeof(grs_screen));
104         grd_curscreen->sc_mode = mode;
105         grd_curscreen->sc_w = w;
106         grd_curscreen->sc_h = h;
107         grd_curscreen->sc_aspect = fixdiv(grd_curscreen->sc_w*3,grd_curscreen->sc_h*4);
108         gr_init_canvas(&grd_curscreen->sc_canvas, (unsigned char *)BM_D3D_DISPLAY, t, w, h);
109         gr_set_current_canvas(NULL);
110
111
112         if (!(backbuffer = createdib()))
113                 return 1;
114
115         grd_curscreen->sc_canvas.cv_bitmap.bm_data = backbuffer;
116         grd_curscreen->sc_canvas.cv_bitmap.bm_type = BM_LINEAR;
117         grd_curscreen->sc_canvas.cv_bitmap.bm_x = 0;
118         grd_curscreen->sc_canvas.cv_bitmap.bm_y = 0;
119         grd_curscreen->sc_canvas.cv_bitmap.bm_w = w;
120         grd_curscreen->sc_canvas.cv_bitmap.bm_h = h;
121         grd_curscreen->sc_canvas.cv_bitmap.bm_rowsize = w;
122         
123         gamefont_choose_game_font(w,h);
124         
125         return 0;
126 }
127
128 int gr_init(int mode)
129 {
130         //int org_gamma;
131         int retcode;
132         //HRESULT hr;
133
134         // Only do this function once!
135         if (gr_installed==1)
136                 return -1;
137
138         MALLOC( grd_curscreen,grs_screen,1 );
139         memset( grd_curscreen, 0, sizeof(grs_screen));
140
141         // Set the mode.
142         if ((retcode=gr_set_mode(mode)))
143         {
144                 return retcode;
145         }
146
147         // Set all the screen, canvas, and bitmap variables that
148         // aren't set by the gr_set_mode call:
149         grd_curscreen->sc_canvas.cv_color = 0;
150         grd_curscreen->sc_canvas.cv_drawmode = 0;
151         grd_curscreen->sc_canvas.cv_font = NULL;
152         grd_curscreen->sc_canvas.cv_font_fg_color = 0;
153         grd_curscreen->sc_canvas.cv_font_bg_color = 0;
154         gr_set_current_canvas( &grd_curscreen->sc_canvas );
155
156         // Set flags indicating that this is installed.
157         gr_installed = 1;
158
159         return 0;
160 }
161
162 void gr_upixel( int x, int y )
163 {
164         gr_bm_upixel(&grd_curcanv->cv_bitmap, x, y, (unsigned char)COLOR);
165 #if 0
166         grs_bitmap * bm = &grd_curcanv->cv_bitmap;
167         Win32_Rect (
168                 //x + bm->bm_x, y + bm->bm_y,
169                 //x + bm->bm_x, y + bm->bm_y,
170                 x, y, x, y,
171                 bm->bm_data, COLOR);
172 #endif
173 }
174
175 void gr_bm_upixel( grs_bitmap * bm, int x, int y, unsigned char color )
176 {
177         switch (bm->bm_type)
178         {
179         case BM_LINEAR:
180                 bm->bm_data[ bm->bm_rowsize*y+x ] = color;
181                 break;
182
183         case BM_DIRECTX:
184                 {
185                         unsigned char *p = gr_current_pal + color * 3;
186                 Win32_Rect (
187                         x, y, x, y,
188                         //x + bm->bm_x, y + bm->bm_y,
189                         //x + bm->bm_x, y + bm->bm_y,
190                                 (int)bm->bm_data, color);
191                 }
192                 break;
193
194         default:
195                 Assert (FALSE);
196                 break;
197         }
198 }
199
200 RGBQUAD w32lastrgb[256];
201
202 void gr_update ()
203 {
204         HDC hdc;
205         unsigned char *p;
206         int i;
207
208         p = gr_current_pal;
209         for (i = 0; i < 256; i++) {
210                 w32lastrgb[i].rgbRed = *p++ * 4;
211                 w32lastrgb[i].rgbGreen = *p++ * 4;
212                 w32lastrgb[i].rgbBlue = *p++ * 4;
213         }
214         hdc = CreateCompatibleDC(NULL);
215         SelectObject(hdc, screen_bitmap);
216         SetDIBColorTable(hdc, 0, 256, w32lastrgb);
217
218         BlitToPrimary(hdc);
219         DeleteDC(hdc);
220 }
221
222 void show_dd_error(HRESULT hr, char *loc)
223 {
224         char buf[512], len;
225
226         strcpy(buf, loc);
227         len = strlen(buf);
228         #ifdef NDEBUG
229         sprintf(buf + len, "%x", hr);
230         #else
231         GetDDErrorString(hr, buf + len, sizeof(buf) - len);
232         #endif
233         Error(buf);
234 }
235
236 unsigned char *createdib(void)
237 {
238         BITMAPINFO *bmHdr;
239         HDC hdc;
240         int i;
241         unsigned char *p;
242         unsigned char *buffer;
243         
244         if (!(bmHdr = malloc(sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD))))
245                 return NULL;
246
247         memset(bmHdr, 0, sizeof(*bmHdr));
248         bmHdr->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
249         bmHdr->bmiHeader.biWidth = grd_curscreen->sc_canvas.cv_bitmap.bm_w;
250         bmHdr->bmiHeader.biHeight = -grd_curscreen->sc_canvas.cv_bitmap.bm_h;
251         bmHdr->bmiHeader.biPlanes = 1;
252         bmHdr->bmiHeader.biBitCount = 8;
253         bmHdr->bmiHeader.biCompression = BI_RGB;
254
255         p = gr_current_pal;
256         for (i = 0; i < 256; i++) {
257                 #if 0
258                 ((short *)bmHdr->bmiColors)[i] = i;
259                 #else
260                 bmHdr->bmiColors[i].rgbRed = (*p++) << 2;
261                 bmHdr->bmiColors[i].rgbGreen = (*p++) << 2;
262                 bmHdr->bmiColors[i].rgbBlue = (*p++) << 2;
263                 bmHdr->bmiColors[i].rgbReserved = 0;
264                 #endif
265         }
266         hdc = CreateCompatibleDC(NULL);
267         if (!(screen_bitmap = CreateDIBSection(hdc, bmHdr, DIB_RGB_COLORS,
268                 &buffer, NULL, 0))) {
269                         int err = GetLastError();
270                         char buf[256];
271                         sprintf(buf, "CreateDISection():%d", err);
272                         MessageBox(g_hWnd, buf, NULL, MB_OK);
273         }
274         DeleteDC(hdc);
275         free(bmHdr);
276         return buffer;
277 }
278
279 void Win32_BlitLinearToDirectX_bm(grs_bitmap *bm, int sx, int sy, 
280         int w, int h, int dx, int dy, int masked) {
281         HDC hdc;
282         unsigned char *src, *dest, *rle_w;
283         int i;
284
285         dest = backbuffer + dy * 320 + dx;
286         
287         if (bm->bm_flags & BM_FLAG_RLE) {
288                 src = bm->bm_data + 4 + bm->bm_h;
289                 rle_w = bm->bm_data + 4;
290                 while (sy--)
291                         src += (int)*rle_w++;
292                 if (masked) {
293                         for (i = h; i--; ) {
294                                 gr_rle_expand_scanline_masked(dest, src, sx, sx + w - 1);
295                                 src += (int)*rle_w++;
296                                 dest += 320;
297                         }
298                 } else {
299                         for (i = h; i--; ) {
300                                 gr_rle_expand_scanline(dest, src, sx, sx + w - 1);
301                                 src += (int)*rle_w++;
302                                 dest += 320;
303                         }
304                 }
305         } else {
306                 src = bm->bm_data + sy * bm->bm_rowsize + sx;
307                 if (masked) {
308                         for (i = h; i--; ) {
309                                 gr_linear_rep_movsdm(src, dest, w);
310                                 src += bm->bm_rowsize;
311                                 dest += 320;
312                         }
313                 } else {
314                         for (i = h; i--; ) {
315                                 gr_linear_movsd(src, dest, w);
316                                 src += bm->bm_rowsize;
317                                 dest += 320;
318                         }
319                 }
320         }
321         hdc = CreateCompatibleDC(NULL);
322         SelectObject(hdc, screen_bitmap);
323         SetDIBColorTable(hdc, 0, 256, w32lastrgb);
324         BlitToPrimaryRect(hdc, dx, dy, w, h, grd_curcanv->cv_bitmap.bm_data);
325         DeleteDC(hdc);
326 }
327
328 void Win32_MakePalVisible(void) {
329         gr_update();    
330 }
331
332 void Win32_InvalidatePages(void) {
333         reset_cockpit();
334         init_gauges();
335 }