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