added worldarea -> will be responsible for world map rendering
[dboe.git] / blades.c
blob5f78157d3b78a645b4f0dcdc8e535f08faa7521d
1 /*
2 Blades of Exile Game/Scenario Editor/Character Editor
3 Copyright (C) 1998-2007, Jeff Vogel
4 http://www.spiderwebsoftware.com, spidweb@spiderwebsoftware.com
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License along
17 with this program; if not, write to the Free Software Foundation, Inc.,
18 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 // Blades of Exile for Windows
22 // Will this horror never end?
24 //#include <windows.h>
25 #include <gtk/gtk.h>
27 #include "stdlib.h"
28 #include "math.h"
30 #include "global.h"
31 #include "graphics.h"
32 #include "newgraph.h"
33 #include "fileio.h"
34 #include "actions.h"
35 #include "text.h"
36 #include "party.h"
37 #include "exlsound.h"
38 #include "items.h"
39 #include "fields.h"
40 #include "town.h"
41 #include "dlogtool.h"
42 #include "startup.h"
43 #include "dlgutils.h"
44 #include "exlsound.h"
45 #include "infodlgs.h"
46 #include "graphutl.h"
48 void check_game_done();
49 Boolean handle_menu (short item, HMENU menu);
50 void load_cursors();
51 void set_cursor(HCURSOR which_curs);
52 void change_cursor(POINT where_curs);
53 void check_colors();
54 void cursor_go();
55 void cursor_stay();
57 /* Mac stuff globals */
58 Boolean All_Done = FALSE,dialog_not_toast = FALSE;
59 short had_text_freeze = 0,num_fonts;
60 Boolean in_startup_mode = TRUE,app_started_normally = FALSE;
61 Boolean play_sounds = TRUE,first_startup_update = TRUE;
62 Boolean diff_depth_ok = FALSE,first_sound_played = FALSE,spell_forced = FALSE,startup_loaded = FALSE;
63 Boolean save_maps = TRUE,party_in_memory = FALSE,in_scen_debug = FALSE;
64 HWND text_sbar = NULL,item_sbar = NULL,shop_sbar = NULL;
65 RECT sbar_rect = {545,284,562,421};
66 RECT shop_sbar_rect = {258,67,274,357};
67 RECT item_sbar_rect = {545,146,562,254}; /**/
68 short dialog_answer;
69 POINT store_anim_ul;
71 Boolean gInBackground = FALSE;
72 long start_time;
73 Boolean allowed_one_erase = FALSE;
75 Boolean palette_suspect = FALSE,window_in_front = FALSE;
77 short on_spell_menu[2][62];
78 short on_monst_menu[256];
79 Boolean belt_present = FALSE;
81 // Cursors
82 short current_cursor = 120;
83 HCURSOR arrow_curs[3][3], sword_curs, key_curs, target_curs,talk_curs,look_curs;
86 // Shareware globals
87 Boolean registered = TRUE,ed_reg = FALSE;
88 long register_flag = 0;
89 long ed_flag = 0,ed_key;
90 Boolean game_run_before = TRUE;
92 Boolean debug_on = FALSE,give_intro_hint = TRUE;
94 /* Adventure globals */
95 party_record_type party;
96 pc_record_type adven[6];
97 outdoor_record_type outdoors[2][2];
98 current_town_type c_town;
99 big_tr_type t_d;
100 town_item_list t_i;
101 unsigned char out[96][96];
102 unsigned char out_e[96][96];
103 setup_save_type setup_save;
104 unsigned char misc_i[64][64],sfx[64][64];
105 location monster_targs[T_M];
107 /* Display globals */
108 extern short combat_posing_monster = -1, current_working_monster = -1; // 0-5 PC 100 + x - monster x
109 Boolean fast_bang = FALSE;
110 short spec_item_array[60];
111 short overall_mode = 45,current_spell_range;
112 Boolean first_update = TRUE,anim_onscreen = FALSE,frills_on = TRUE,sys_7_avail,suppress_stat_screen = FALSE;
113 short stat_window = 0,store_modifier;
114 Boolean monsters_going = FALSE,boom_anim_active = FALSE,cartoon_happening = FALSE;
115 short give_delays = 0;
116 Boolean modeless_exists[18] = {FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,
117 FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,
118 FALSE,FALSE,FALSE,FALSE,FALSE,FALSE};
119 short modeless_key[18] = {1079,1080,1081,1082,1084, 1046,1088,1089,1090,1092, 1095,1072,0,0,0,0,0,0};
120 HWND modeless_dialogs[18] = {NULL, NULL, NULL, NULL, NULL, NULL,
121 NULL, NULL, NULL, NULL, NULL, NULL,
122 NULL, NULL, NULL, NULL, NULL, NULL};
124 short town_size[3] = {64,48,32};
125 short which_item_page[6] = {0,0,0,0,0,0}; // Remembers which of the 2 item pages pc looked at
126 short ulx = 0, uly = 0;
127 short display_mode = 0; // 0 - center 1- ul 2 - ur 3 - dl 4 - dr 5 - small win
128 long stored_key;
129 short pixel_depth,old_depth = 8;
130 short current_ground = 0,stat_screen_mode = 0;
131 short anim_step = -1;
132 long anim_ticks = 0;
134 // Spell casting globals
135 short store_mage = 0, store_priest = 0;
136 short store_mage_lev = 0, store_priest_lev = 0;
137 short store_spell_target = 6,pc_casting;
138 short pc_last_cast[2][6] = {{1,1,1,1,1,1},{1,1,1,1,1,1}};
139 short num_targets_left = 0;
140 location spell_targets[8];
142 long store_mouse;
144 /* Combat globals */
145 short which_combat_type,town_type;
146 location center;
147 unsigned char far combat_terrain[64][64];
148 location pc_pos[6];
149 short current_pc;
150 short combat_active_pc;
151 effect_pat_type current_pat;
152 short monst_target[T_M]; // 0-5 target that pc 6 - no target 100 + x - target monster x
153 short spell_caster, missile_firer,current_monst_tactic;
154 short store_current_pc = 0;
157 stored_items_list_type stored_items[3];
158 stored_outdoor_maps_type o_maps;
160 // Special stuff booleans
161 Boolean web,crate,barrel,fire_barrier,force_barrier,quickfire,force_wall,fire_wall,antimagic,scloud,ice_wall,blade_wall;
162 Boolean sleep_field;
164 long last_anim_time = 0,last_redraw_time;
166 /* Windoze stuff globals */
167 Boolean cursor_shown = TRUE;
168 short store_pc_being_created;
170 GtkWidget *main_win; //HWND mainPtr;
171 HWND force_dlog = NULL;
172 HFONT font,fantasy_font,small_bold_font,italic_font,underline_font,bold_font,tiny_font;
173 FARPROC modeless_dlogprocs[18] = {NULL, NULL, NULL, NULL, NULL, NULL,
174 NULL, NULL, NULL, NULL, NULL, NULL,
175 NULL, NULL, NULL, NULL, NULL, NULL};
176 HBITMAP bmap = NULL;
177 HPALETTE hpal;
178 PALETTEENTRY far ape[256];
179 HDC main_dc,main_dc2,main_dc3;
180 HANDLE store_hInstance,accel;
181 BOOL event_handled;
182 scenario_data_type far scenario;
183 piles_of_stuff_dumping_type *data_store;
184 piles_of_stuff_dumping_type2 *data_store2;
185 piles_of_stuff_dumping_type3 *data_store3;
186 piles_of_stuff_dumping_type4 *data_store4;
187 piles_of_stuff_dumping_type5 *data_store5;
188 talking_record_type far talking;
189 char far scen_strs2[110][256];
190 stored_town_maps_type far town_maps,town_maps2;
192 char szWinName[] = "Blades of Exile Dialogs";
193 char szAppName[] = "Blades of Exile";
194 char file_path_name[256];
196 Boolean block_erase = FALSE;
198 long FAR PASCAL _export WndProc (HWND, UINT, UINT, LONG);
199 Boolean handle_menu (short, HMENU);
201 int main(int argc, char **argv) {
202 // short i,seed;
203 // RECT windRECT;
204 // HGLOBAL temp_buffer,temp_buffer2;
205 // HGLOBAL temp_buffer3,temp_buffer4;
206 // HGLOBAL temp_buffer5,temp_buffer6;
208 //wndclass.hIcon = LoadIcon(hInstance,MAKEINTRESOURCE(10));
209 //gtk_window_set_icon(main_win, icon);
210 //gtk_window_set_default_icon_list();
211 //set background white
212 //add menu MAKEINTRESOURCE(1);
214 gtk_init(&argc, &argv);
215 main_win = gtk_window_new(GTK_WINDOW_TOPLEVEL);
216 gtk_window_set_title(main_win, "Deadly Blades of Exile");
217 gtk_window_resize_to_geometry(main_win, 588, 478);
220 // temp_buffer = malloc(sizeof(piles_of_stuff_dumping_type));
221 // if (temp_buffer == NULL)
222 // gtk_main_quit();
224 data_store = malloc(sizeof(piles_of_stuff_dumping_type));
225 if (data_store == NULL)
226 gtk_main_quit();
227 data_store2 = malloc(sizeof(piles_of_stuff_dumping_type2));
228 if (data_store2 == NULL)
229 gtk_main_quit();
230 data_store3 = malloc(sizeof(piles_of_stuff_dumping_type3));
231 if (data_store3 == NULL)
232 gtk_main_quit();
233 data_store4 = malloc(sizeof(piles_of_stuff_dumping_type4));
234 if (data_store4 == NULL)
235 gtk_main_quit();
236 data_store5 = malloc(sizeof(piles_of_stuff_dumping_type5));
237 if (data_store5 == NULL)
238 gtk_main_quit();
240 // last_redraw_time = seed = (short) GetCurrentTime();
241 // srand(seed);
243 get_reg_data();
245 // if (display_mode != 5)
246 // max_window(mainPtr);
247 // else {
248 // GetWindowRect(GetDesktopWindow(),&windRECT);
249 // MoveWindow(mainPtr,(windRECT.right - (588 + 10)) / 2, (windRECT.bottom - (425 + 52)) / 2 , 588 + 10,425 + 52,TRUE);
250 // }
252 load_sounds();
254 //font = CreateFont(12,0,0,0,0, 0,0,0, 0,0, 0,0,0,"MS Sans Serif");
255 //small_bold_font = CreateFont(12,0,0,0,700, 0,0,0, 0,0, 0,0,0,"MS Sans Serif");
256 //italic_font = CreateFont(12,0,0,0,700, 1,0,0, 0,0, 0,0,0,"MS Sans Serif");
257 //underline_font = CreateFont(12,0,0,0,0, 0,1,0, 0,0, 0,0,0,"MS Sans Serif");
258 //bold_font = CreateFont(14,0,0,0,700, 0,0,0, 0,0, 0,0,0,"MS Sans Serif");
259 //tiny_font = font;
260 //fantasy_font = CreateFont(22,0,0,0,0, 0,0,0, 0,0, 0,0,0,"MaidenWord");
261 //if (fantasy_font == NULL)
262 // fantasy_font = CreateFont(22,0,0,0,0, 0,0,0, 0,0, 0,0,0,"MS Sans Serif");
264 //shop_sbar = CreateWindow("scrollbar",NULL, WS_CHILD | WS_TABSTOP | SBS_VERT, shop_sbar_rect.left,shop_sbar_rect.top,shop_sbar_rect.right,shop_sbar_rect.bottom, mainPtr,3,store_hInstance,NULL);
265 //SetScrollRange(shop_sbar,SB_CTL,0,16,FALSE);
267 //ShowWindow(mainPtr,nCmdShow);
269 // plop_fancy_startup(); TODO: splash screen
271 init_screen_locs();
273 //fancy_startup_delay();
275 //SetTimer(mainPtr,1,620,NULL);
276 //SetTimer(mainPtr,2,200,NULL);
277 //SetTimer(mainPtr,3,10,NULL);
278 file_initialize();
279 //check_colors();
280 //menu_activate(0);
281 //cursor_stay();
282 //showcursor(TRUE);
283 //reset_text_bar();
285 //adjust_window_mode();
287 cd_init_dialogs();
289 if (load_blades_data() == FALSE)
290 registered = FALSE;
292 if (game_run_before == FALSE)
293 FCD(986,0);
294 else if (give_intro_hint == TRUE)
295 tip_of_day();
297 //event_handled = FALSE;
298 //while(GetMessage(&msg,NULL,0,0)) {
299 // if (event_handled == FALSE) {
300 // if (!TranslateAccelerator(mainPtr, accel, &msg)) {
301 // TranslateMessage(&msg);
302 // DispatchMessage(&msg);
303 // }
304 // }
306 //return msg.wParam;
308 gtk_widget_show(main_win);
310 g_signal_connect();
312 gtk_main();
314 return 0;
317 int PASCAL WinMain (hInstance,hPrevInstance, lpszCmdParam, nCmdShow)
318 HANDLE hInstance;
319 HANDLE hPrevInstance;
320 LPSTR lpszCmdParam;
321 int nCmdShow;
324 MSG msg;
325 WNDCLASS wndclass,wndclass2;
326 short i,seed;
327 RECT windRECT;
328 HGLOBAL temp_buffer,temp_buffer2;
329 HGLOBAL temp_buffer3,temp_buffer4;
330 HGLOBAL temp_buffer5,temp_buffer6;
332 if (!hPrevInstance) {
333 wndclass.style = CS_HREDRAW | CS_VREDRAW | CS_BYTEALIGNWINDOW;
334 wndclass.lpfnWndProc = WndProc;
335 wndclass.cbClsExtra = 0;
336 wndclass.cbWndExtra = 0;
337 wndclass.hInstance = hInstance;
338 wndclass.hIcon = LoadIcon(hInstance,MAKEINTRESOURCE(10));
339 wndclass.hCursor = NULL;
340 wndclass.hbrBackground = GetStockObject(WHITE_BRUSH);
341 wndclass.lpszMenuName = MAKEINTRESOURCE(1);
342 wndclass.lpszClassName = szAppName;
344 RegisterClass(&wndclass);
346 wndclass2.style = CS_HREDRAW | CS_VREDRAW | CS_BYTEALIGNWINDOW;
347 wndclass2.lpfnWndProc = WndProc;
348 wndclass2.cbClsExtra = 0;
349 wndclass2.cbWndExtra = 0;
350 wndclass2.hInstance = hInstance;
351 wndclass2.hIcon = LoadIcon(hInstance,MAKEINTRESOURCE(10));
352 wndclass2.hCursor = NULL;
353 wndclass2.hbrBackground = GetStockObject(WHITE_BRUSH);
354 wndclass2.lpszMenuName = NULL;
355 wndclass2.lpszClassName = szWinName;
357 RegisterClass(&wndclass2);
360 mainPtr = CreateWindow (szAppName,
361 "Blades of Exile",
362 WS_OVERLAPPEDWINDOW,
365 588,
366 478,
367 NULL,
368 NULL,
369 hInstance,
370 NULL);
372 if (!hPrevInstance) { // initialize
373 //center_window(mainPtr);
374 GetModuleFileName(hInstance,file_path_name,256);
375 //ASB(file_path_name);
377 store_hInstance = hInstance;
378 accel = LoadAccelerators(hInstance, MAKEINTRESOURCE(1));
379 init_buf();
380 load_cursors();
382 temp_buffer = GlobalAlloc(GMEM_FIXED,sizeof(piles_of_stuff_dumping_type));
383 if (temp_buffer == NULL) {
384 PostQuitMessage(0);
386 data_store = (piles_of_stuff_dumping_type *) (GlobalLock(temp_buffer));
387 if (data_store == NULL) {
388 PostQuitMessage(0);
390 temp_buffer2 = GlobalAlloc(GMEM_FIXED,sizeof(piles_of_stuff_dumping_type2));
391 if (temp_buffer2 == NULL) {
392 PostQuitMessage(0);
394 data_store2 = (piles_of_stuff_dumping_type2 *) (GlobalLock(temp_buffer2));
395 if (data_store2 == NULL) {
396 PostQuitMessage(0);
398 temp_buffer3 = GlobalAlloc(GMEM_FIXED,sizeof(piles_of_stuff_dumping_type3));
399 if (temp_buffer3 == NULL) {
400 PostQuitMessage(0);
402 data_store3 = (piles_of_stuff_dumping_type3 *) (GlobalLock(temp_buffer3));
403 if (data_store3 == NULL) {
404 PostQuitMessage(0);
406 temp_buffer4 = GlobalAlloc(GMEM_FIXED,sizeof(piles_of_stuff_dumping_type4));
407 if (temp_buffer4 == NULL) {
408 PostQuitMessage(0);
410 data_store4 = (piles_of_stuff_dumping_type4 *) (GlobalLock(temp_buffer4));
411 if (data_store4 == NULL) {
412 PostQuitMessage(0);
414 temp_buffer5 = GlobalAlloc(GMEM_FIXED,sizeof(piles_of_stuff_dumping_type5));
415 if (temp_buffer5 == NULL) {
416 PostQuitMessage(0);
418 data_store5 = (piles_of_stuff_dumping_type5 *) (GlobalLock(temp_buffer5));
419 if (data_store5 == NULL) {
420 PostQuitMessage(0);
423 last_redraw_time = seed = (short) GetCurrentTime();
424 srand(seed);
426 get_reg_data();
428 if (display_mode != 5)
429 max_window(mainPtr);
430 else {
431 GetWindowRect(GetDesktopWindow(),&windRECT);
432 MoveWindow(mainPtr,(windRECT.right - (588 + 10)) / 2,
433 (windRECT.bottom - (425 + 52)) / 2 ,
434 588 + 10,425 + 52,TRUE);
438 load_sounds();
440 font = CreateFont(12,0,0,0,0, 0,0,0, 0,0,
441 0,0,0,"MS Sans Serif");
442 small_bold_font = CreateFont(12,0,0,0,700, 0,0,0, 0,0,
443 0,0,0,"MS Sans Serif");
444 italic_font = CreateFont(12,0,0,0,700, 1,0,0, 0,0,
445 0,0,0,"MS Sans Serif");
446 underline_font = CreateFont(12,0,0,0,0, 0,1,0, 0,0,
447 0,0,0,"MS Sans Serif");
448 bold_font = CreateFont(14,0,0,0,700, 0,0,0, 0,0,
449 0,0,0,"MS Sans Serif");
450 tiny_font = font;
451 fantasy_font = CreateFont(22,0,0,0,0, 0,0,0, 0,0,
452 0,0,0,"MaidenWord");
453 if (fantasy_font == NULL) {
454 fantasy_font = CreateFont(22,0,0,0,0, 0,0,0, 0,0,
455 0,0,0,"MS Sans Serif");
458 //Rect sbar_rect = {546,283,562,421};
459 //Rect shop_sbar_rect = {258,67,274,357};
460 //Rect item_sbar_rect = {546,146,562,254}; /**/
462 text_sbar = CreateWindow("scrollbar",NULL,
463 WS_CHILD | WS_TABSTOP | SBS_VERT, sbar_rect.left,sbar_rect.top,sbar_rect.right,sbar_rect.bottom,
464 mainPtr,1,store_hInstance,NULL);
465 SetScrollRange(text_sbar,SB_CTL,0,58,FALSE);
466 item_sbar = CreateWindow("scrollbar",NULL,
467 WS_CHILD | WS_TABSTOP | SBS_VERT, item_sbar_rect.left,item_sbar_rect.top,item_sbar_rect.right,item_sbar_rect.bottom,
468 mainPtr,2,store_hInstance,NULL);
469 SetScrollRange(item_sbar,SB_CTL,0,16,FALSE);
471 //shop_sbar = CreateWindow("scrollbar",NULL,
472 // WS_CHILD | WS_TABSTOP | SBS_VERT, shop_sbar_rect.left,shop_sbar_rect.top,shop_sbar_rect.right,shop_sbar_rect.bottom,
473 // mainPtr,3,store_hInstance,NULL);
474 //SetScrollRange(shop_sbar,SB_CTL,0,16,FALSE);
476 //ShowWindow(mainPtr,nCmdShow);
478 //plop_fancy_startup();
480 init_screen_locs();
482 //fancy_startup_delay();
484 //SetTimer(mainPtr,1,620,NULL);
485 //SetTimer(mainPtr,2,200,NULL);
486 //SetTimer(mainPtr,3,10,NULL);
487 file_initialize();
488 //check_colors();
489 //menu_activate(0);
490 //cursor_stay();
491 //showcursor(TRUE);
492 //reset_text_bar();
494 //adjust_window_mode();
496 cd_init_dialogs();
498 if (load_blades_data() == FALSE)
499 registered = FALSE;
501 if (game_run_before == FALSE)
502 FCD(986,0);
503 else if (give_intro_hint == TRUE)
504 tip_of_day();
507 event_handled = FALSE;
508 while(GetMessage(&msg,NULL,0,0)) {
509 if (event_handled == FALSE) {
510 if (!TranslateAccelerator(mainPtr, accel, &msg)) {
511 TranslateMessage(&msg);
512 DispatchMessage(&msg);
516 return msg.wParam;
519 long FAR PASCAL _export WndProc (hwnd,message,wParam,lParam)
520 HWND hwnd;
521 UINT message;
522 UINT wParam;
523 LONG lParam;
525 HDC hdc;
526 PAINTSTRUCT ps;
527 RECT rect;
528 short cxDib, cyDib;
529 BYTE huge * lpDibBits;
530 RECT s_rect = {0,0,30,30},d_rect = {0,0,30,30},d2 = {0,0,420,216},s2 = {0,0,420,216};
531 POINT press;
532 short handled = 0;
533 HMENU menu;
534 RECT dlg_rect,wind_rect,draw_rect;
535 short store_ulx,store_uly,sbar_pos;
536 short which_sbar;
538 short old_setting,new_setting;
539 short smin,smax;
541 // First, handle window size
542 GetWindowRect(mainPtr,&wind_rect);
543 switch (display_mode) {
544 case 1:
545 store_ulx = 0; store_uly = 0; break;
546 case 2: store_ulx = wind_rect.right - 550 - 21; store_uly = 0; break;
547 case 3: store_ulx = 0; store_uly = wind_rect.bottom - 422 - 24 - 21; break;
548 case 4: store_ulx = wind_rect.right - 550 - 21; store_uly = wind_rect.bottom - 422 - 24 - 21; break;
549 case 5: store_ulx = 0; store_uly = 0;
550 default:
551 store_ulx = ((wind_rect.right - wind_rect.left) - 536) / 2 - 30;
552 store_uly = ((wind_rect.bottom - wind_rect.top) - 478) / 2 + 8;
553 break;
555 store_ulx = store_ulx - (store_ulx % 8);
556 store_uly = store_uly - (store_uly % 8);
557 if ((store_ulx != ulx) || (store_uly != uly)) {
558 ulx = store_ulx;
559 uly = store_uly;
560 adjust_window_mode();
563 switch (message) {
564 /*case WM_SIZE: case WM_MOVE:
565 if (hwnd == mainPtr) {
566 print_nums((message == WM_SIZE) ? 500 : 0,0,0);
567 GetClientRect(mainPtr,&draw_rect);
568 InvalidateRect(mainPtr,&draw_rect,TRUE);
570 break;*/
571 case WM_KEYDOWN:
572 if (hwnd != mainPtr)
573 check_cd_event(hwnd,message,wParam,lParam);
574 else {
575 cursor_go();
576 All_Done = handle_syskeystroke(wParam,lParam,&handled);
577 check_game_done();
579 if (handled == 1)
580 FlushEvents(0);
581 return 0;
582 break;
584 case WM_CHAR:
585 if (hwnd != mainPtr)
586 check_cd_event(hwnd,message,wParam,lParam);
587 else {
588 cursor_go();
589 All_Done = handle_keystroke(wParam,lParam);
590 check_game_done();
592 return 0;
593 break;
595 case WM_LBUTTONDOWN:
596 cursor_stay();
597 if (hwnd != mainPtr)
598 check_cd_event(hwnd,message,wParam,lParam);
599 else {
600 SetFocus(hwnd);
601 press = MAKEPOINT(lParam);
602 if (in_startup_mode == FALSE)
603 All_Done = handle_action(press, wParam,lParam);
604 else All_Done = handle_startup_press(press);
605 change_cursor(press);
606 check_game_done();
608 return 0;
609 break;
611 case WM_RBUTTONDOWN:
612 cursor_stay();
613 if (hwnd != mainPtr)
614 check_cd_event(hwnd,message,wParam,lParam);
615 else {
616 SetFocus(hwnd);
617 press = MAKEPOINT(lParam);
618 if (in_startup_mode == FALSE)
619 All_Done = handle_action(press, wParam,-2);
620 else All_Done = handle_startup_press(press);
621 change_cursor(press);
622 check_game_done();
624 return 0;
625 break;
627 case WM_PALETTECHANGED:
628 palette_suspect = TRUE;
629 return 0;
631 case WM_ACTIVATEAPP:
632 if ((hwnd == mainPtr) && (wParam == 0)) {
633 reset_palette();
635 if ((hwnd == mainPtr) && (wParam != 0)) {
636 inflict_palette();
638 break;
639 case WM_ACTIVATE:
640 if (hwnd == mainPtr) {
641 if ((wParam == WA_ACTIVE) ||(wParam == WA_CLICKACTIVE)) {
642 if (palette_suspect == TRUE) {
643 inflict_palette();
644 palette_suspect = FALSE;
645 GetClientRect(hwnd,&dlg_rect);
646 InvalidateRect(hwnd,&dlg_rect,FALSE);
649 if ((wParam == WA_ACTIVE) ||(wParam == WA_CLICKACTIVE)) {
650 window_in_front = TRUE;
651 GetClientRect(hwnd,&dlg_rect);
652 InvalidateRect(hwnd,&dlg_rect,FALSE);
654 if (wParam == WA_INACTIVE) {
655 cursor_stay();
656 anim_onscreen = FALSE;
657 window_in_front = FALSE;
660 return 0;
662 case WM_ERASEBKGND:
663 if (hwnd != mainPtr)
664 break;
665 if (block_erase == TRUE) {
666 block_erase = FALSE;
667 return 1;
669 //if (allowed_one_erase == TRUE)
670 return 1;
671 allowed_one_erase = TRUE;
672 break;
673 case WM_MOUSEMOVE:
674 if (store_mouse != lParam)
675 cursor_stay();
676 store_mouse = lParam;
677 press = MAKEPOINT(lParam);
678 if (hwnd == mainPtr) {
679 change_cursor(press);
680 if ((overall_mode > 10) && (overall_mode < 20) && (party.stuff_done[181][6] == 0))
681 draw_targeting_line(press);
683 return 0;
685 case WM_PAINT:
686 if ((block_erase == TRUE) && (hwnd == mainPtr)) {
687 block_erase = FALSE;
689 //if (hwnd == mainPtr) {
690 // GetClientRect(mainPtr,&draw_rect);
691 // ValidateRect(mainPtr,&draw_rect);
692 // }
693 hdc = BeginPaint(hwnd,&ps);
694 EndPaint(hwnd,&ps);
696 if (hwnd != mainPtr)
697 check_cd_event(hwnd,message,wParam,lParam);
698 else {
699 force_reprint();
700 reset_text_bar();
701 if (in_startup_mode == TRUE) {
702 draw_startup(0);
704 else if (first_update == TRUE) {
705 first_update = FALSE;
706 if (overall_mode == 0)
707 redraw_screen(0);
708 if ((overall_mode > 0) & (overall_mode < 10))
709 redraw_screen(1);
710 // 1st update never combat
712 else refresh_screen(overall_mode);
716 return 0;
718 case WM_TIMER:
719 switch(wParam) {
720 case 1:
721 if ((in_startup_mode == FALSE) && (anim_onscreen == TRUE)
722 && (window_in_front == TRUE) && (give_delays == FALSE)) {
723 //if (GetCurrentTime() - last_redraw_time > 600) {
724 anim_ticks++;
725 initiate_redraw();
726 // }
728 break;
729 case 2:
730 if ((overall_mode > 10) && (overall_mode < 20) && (party.stuff_done[181][6] == 0)) {
731 GetCursorPos(&press);
732 press.x -= wind_rect.left + 3;
733 press.y -= wind_rect.top + 41;
734 draw_targeting_line(press);
736 if ((in_startup_mode == TRUE) && (window_in_front == TRUE)) {
737 draw_startup_anim();
739 break;
741 return 0;
743 case WM_COMMAND: // 1006 is dummy event
744 // creation events 2000 spend xp 2001 pick graphic 2002 finish up
745 if (hwnd == mainPtr) {
746 menu = GetMenu(mainPtr);
747 All_Done = handle_menu((short) wParam, menu);
748 check_game_done();
750 else {
751 check_cd_event(hwnd,message,wParam,lParam);
753 return 0;
755 case WM_VSCROLL:
756 which_sbar = GetWindowWord(HIWORD (lParam), GWW_ID);
757 switch (which_sbar) {// 1 text 2 items 3 shop
758 case 1:
759 sbar_pos = GetScrollPos(text_sbar,SB_CTL);
760 switch (wParam ) {
761 case SB_PAGEDOWN: sbar_pos += 11; break;
762 case SB_LINEDOWN: sbar_pos++; break;
763 case SB_PAGEUP: sbar_pos -= 11; break;
764 case SB_LINEUP: sbar_pos--; break;
765 case SB_TOP: sbar_pos = 0; break;
766 case SB_BOTTOM: sbar_pos = 57; break;
767 case SB_THUMBPOSITION:
768 case SB_THUMBTRACK:
769 sbar_pos = LOWORD(lParam);
770 break;
772 if (sbar_pos < 0)
773 sbar_pos = 0;
774 if (sbar_pos > 58)
775 sbar_pos = 58;
776 SetScrollPos(text_sbar,SB_CTL,sbar_pos,TRUE);
777 force_reprint();
778 print_buf();
779 break;
780 case 2:
781 old_setting = sbar_pos = GetScrollPos(item_sbar,SB_CTL);
782 GetScrollRange(item_sbar,SB_CTL,(int *) &smin,(int *) &smax);
783 switch (wParam ) {
784 case SB_PAGEDOWN: sbar_pos += (stat_window == 7) ? 2 : 8; break;
785 case SB_LINEDOWN: sbar_pos++; break;
786 case SB_PAGEUP: sbar_pos -= (stat_window == 7) ? 2 : 8; break;
787 case SB_LINEUP: sbar_pos--; break;
788 case SB_TOP: sbar_pos = 0; break;
789 case SB_BOTTOM: sbar_pos = smax; break;
790 case SB_THUMBPOSITION:
791 case SB_THUMBTRACK:
792 sbar_pos = LOWORD(lParam);
793 break;
795 if (sbar_pos < 0)
796 sbar_pos = 0;
797 if (sbar_pos > smax)
798 sbar_pos = smax;
799 SetScrollPos(item_sbar,SB_CTL,sbar_pos,TRUE);
800 if (sbar_pos != old_setting)
801 put_item_screen(stat_window,1);
802 break;
803 case 3:
804 old_setting = sbar_pos = GetScrollPos(shop_sbar,SB_CTL);
805 GetScrollRange(shop_sbar,SB_CTL,(int *) &smin,(int *) &smax);
806 switch (wParam ) {
807 case SB_PAGEDOWN: sbar_pos += 8; break;
808 case SB_LINEDOWN: sbar_pos++; break;
809 case SB_PAGEUP: sbar_pos -= 8; break;
810 case SB_LINEUP: sbar_pos--; break;
811 case SB_TOP: sbar_pos = 0; break;
812 case SB_BOTTOM: sbar_pos = smax; break;
813 case SB_THUMBPOSITION:
814 case SB_THUMBTRACK:
815 sbar_pos = LOWORD(lParam);
816 break;
818 if (sbar_pos < 0)
819 sbar_pos = 0;
820 if (sbar_pos > smax)
821 sbar_pos = smax;
822 SetScrollPos(shop_sbar,SB_CTL,sbar_pos,TRUE);
823 if (sbar_pos != old_setting)
824 draw_shop_graphics(0,shop_sbar_rect);
825 break;
827 SetFocus(mainPtr);
828 return 0;
830 case WM_DESTROY:
831 if (hwnd == mainPtr) {
832 lose_graphics();
833 PostQuitMessage(0);
835 return 0;
836 case WM_CLOSE:
837 if (hwnd == mainPtr) {
838 lose_graphics();
839 PostQuitMessage(0);
841 return 0;
842 case WM_QUIT:
843 if (hwnd == mainPtr)
844 lose_graphics();
845 break;
850 return DefWindowProc(hwnd,message,wParam,lParam);
853 void check_game_done()
855 through_sending();
856 if (All_Done == TRUE) {
857 lose_graphics();
858 showcursor(TRUE);
859 PostQuitMessage(0);
863 Boolean handle_menu (short item, HMENU menu)
865 short choice,i;
866 POINT x = {1001,0},pass_point;
867 Boolean to_return = FALSE;
869 switch (item) {
870 case 1:
871 if (in_startup_mode == TRUE)
872 startup_load();
873 else do_load();
874 break;
875 case 2:
876 do_save(0);
877 break;
878 case 3:
879 if (in_startup_mode == TRUE)
880 save_file(1);
881 else do_save(1);
882 break;
883 case 4:
884 if (in_startup_mode == FALSE) {
885 choice = FCD(1091,0);
886 if (choice == 1)
887 return FALSE;
888 for (i = 0; i < 6; i++)
889 adven[i].main_status = 0;
890 party_in_memory = FALSE;
891 reload_startup();
892 in_startup_mode = TRUE;
893 draw_startup(0);
895 start_new_game();
896 update_pc_graphics();
897 draw_startup(0);
898 break;
899 case 6:
900 pick_preferences();
901 break;
902 case 8:
904 if (in_startup_mode == TRUE) {
905 to_return = All_Done = TRUE;
906 break;
908 if (overall_mode > 1) {
909 choice = FCD(1067,0);
910 if (choice == 1)
911 return All_Done;
913 else {
914 choice = FCD(1066,0);
915 if (choice == 3)
916 break;
917 if (choice == 1)
918 save_file(0);
920 to_return = All_Done = TRUE;
921 break;
923 // options menu
924 case 21:
925 choice = char_select_pc(0,0,"New graphic for who?");
926 if (choice < 6)
927 pick_pc_graphic(choice,1,0);
928 update_pc_graphics();
929 initiate_redraw();
930 break;
932 case 24:
933 if (prime_time() == FALSE) {
934 ASB("Finish what you're doing first.");
935 print_buf();
937 else {
938 choice = char_select_pc(0,0,"Delete who?");
939 if (choice < 6) {
940 if ((i = FCD(1053,0)) == 2)
941 kill_pc(choice,0);
943 update_pc_graphics();
944 initiate_redraw();
946 break;
949 case 22:
950 choice = select_pc(0,0);
951 if (choice < 6)
952 pick_pc_name(choice,0);
953 put_pc_screen();
954 put_item_screen(stat_window,0);
955 break;
958 case 23:
959 if (!(is_town())) {
960 add_string_to_buf("Add PC: Town mode only.");
961 print_buf();
962 break;
964 for (i = 0; i < 6; i++)
965 if (adven[i].main_status == 0)
966 i = 20;
967 if (i == 6) {
968 ASB("Add PC: You already have 6 PCs.");
969 print_buf();
971 if (c_town.town_num == scenario.which_town_start) {
972 give_help(56,0,0);
973 create_pc(6,0);
975 else {
976 add_string_to_buf("Add PC: You can only make new");
977 add_string_to_buf(" characters in the town you ");
978 add_string_to_buf(" started in.");
980 print_buf();
981 put_pc_screen();
982 put_item_screen(stat_window,0);
983 break;
984 case 27:
985 if (overall_mode == 20) {
986 ASB("Talking notes: Can't read while talking.");
987 print_buf();
988 return to_return;
990 talk_notes();
991 break;
992 case 28:
993 adventure_notes();
994 break;
995 case 29:
996 if (in_startup_mode == FALSE)
997 print_party_stats();
998 break;
1000 // help menu
1001 case 41: FCD(1079,0);
1002 break;
1003 case 42: FCD(1080,0); break;
1004 case 43: FCD(1081,0); break;
1005 case 44: FCD(1072,0); break; // magic barriers
1006 case 46: FCD(1084,0); break;
1007 case 47: FCD(1088,0); break;
1009 // library
1010 case 61: display_spells(0,100,0);
1011 break;
1012 case 62: display_spells(1,100,0);
1013 break;
1014 case 63: display_skills(100,0);
1015 break;
1016 case 64:
1017 display_help(0,0);
1018 break;
1019 case 65: tip_of_day(); break;
1020 case 67: FCD(986,0); break;
1022 // actions
1023 case 81:
1024 if (overall_mode != 1) {
1025 ASB("Alchemy: In town mode only.");
1026 print_buf();
1027 break;
1029 pass_point.x = 1000;
1030 pass_point.y = 405;
1031 to_return = handle_action(pass_point,(UINT) 0,(LONG)-1);
1032 break;
1033 case 82:
1034 //handle_keystroke('w',0,event);
1035 to_return = handle_action(x,(UINT) 0,(LONG)-1);
1036 break;
1037 case 84:
1038 if (prime_time() == FALSE) {
1039 ASB("Finish what you're doing first.");
1040 print_buf();
1042 else {
1043 give_help(62,0,0);
1044 display_map();
1046 make_cursor_sword();
1047 break;
1049 // mage is 399
1050 case 399: give_help(209,0,0);
1051 party.help_received[9] = FALSE; break;
1053 // priest is 499
1054 case 499: give_help(209,0,0);
1055 party.help_received[9] = FALSE; break;
1057 // monsters is 599
1058 case 599: give_help(212,0,0); break;
1060 case 100: // index
1061 WinHelp(mainPtr,"bladhelp.hlp",HELP_CONTENTS,0L);
1062 break;
1063 case 200: // about
1064 FCD(1062,0);
1065 break;
1067 default:
1068 if ((item >= 400) && (item < 500)) { // mage spell
1069 if (prime_time() == FALSE) {
1070 ASB("Finish what you're doing first.");
1071 print_buf();
1073 else handle_menu_spell(item - 400,0);
1074 break;
1076 if ((item >= 500) && (item < 600)) { // priest spell
1077 if (prime_time() == FALSE) {
1078 ASB("Finish what you're doing first.");
1079 print_buf();
1081 else handle_menu_spell(item - 500,1);
1082 break;
1084 if ((item >= 600) && (item < 700)) { // monster spell
1085 display_monst(item - 600,(creature_data_type *) NULL,1);
1086 break;
1088 break;
1090 if (in_startup_mode == TRUE)
1091 menu_activate(0);
1092 else menu_activate(1);
1093 return to_return;
1096 void load_cursors()
1098 short i,j;
1100 for (i = 0; i < 3; i++)
1101 for (j = 0; j < 3; j++)
1102 arrow_curs[i][j] = LoadCursor(store_hInstance,MAKEINTRESOURCE(100 + (i - 1) + 10 * (j - 1)));
1103 sword_curs = LoadCursor(store_hInstance,MAKEINTRESOURCE(120));
1105 key_curs = LoadCursor(store_hInstance,MAKEINTRESOURCE(122));
1106 talk_curs = LoadCursor(store_hInstance,MAKEINTRESOURCE(126));
1107 target_curs = LoadCursor(store_hInstance,MAKEINTRESOURCE(124));
1108 look_curs = LoadCursor(store_hInstance,MAKEINTRESOURCE(129));
1110 set_cursor(sword_curs);
1111 current_cursor = 124;
1115 void set_cursor(HCURSOR which_curs)
1117 SetCursor (which_curs);
1120 void change_cursor(POINT where_curs)
1122 short curs_types[50] = {0,0,126,124,122,122,0,0,0,0,
1123 0,124,124,124,124,122,0,0,0,0,
1124 120,120,0,0,0,0,0,0,0,0,
1125 0,0,0,0,0,129,129,129,0,0,
1126 0,0,0,0,0,120,0,0,0,0},cursor_needed;
1127 location cursor_direction;
1128 RECT world_screen = {23, 23, 274, 346};
1130 where_curs.x -= ulx;
1131 where_curs.y -= uly;
1133 if (PtInRect(&world_screen,where_curs) == FALSE)
1134 cursor_needed = 120;
1135 else cursor_needed = curs_types[overall_mode];
1137 if (in_startup_mode == TRUE)
1138 cursor_needed = 120;
1139 else if (cursor_needed == 0) {
1140 if ((PtInRect(&world_screen,where_curs) == FALSE) || (in_startup_mode == TRUE))
1141 cursor_needed = 120;
1142 else {
1143 cursor_direction = get_cur_direction(where_curs);
1144 cursor_needed = 100 + (cursor_direction.x) + 10 * ( cursor_direction.y);
1145 if (cursor_needed == 100)
1146 cursor_needed = 120;
1149 current_cursor = cursor_needed;
1151 //cursor_needed = 120;
1152 //play_sound(0);
1154 switch (cursor_needed) {
1155 case 120:
1156 set_cursor(sword_curs);
1157 break;
1158 case 121:
1160 case 122:
1161 set_cursor(key_curs);
1162 break;
1163 case 124:
1164 set_cursor(target_curs);
1165 break;
1166 case 126:
1167 set_cursor(talk_curs);
1168 break;
1169 case 129:
1170 set_cursor(look_curs);
1171 break;
1173 default: // an arrow
1174 set_cursor(arrow_curs[cursor_direction.x + 1][cursor_direction.y + 1]);
1175 break;
1180 void check_colors()
1182 short a,b;
1184 a = GetDeviceCaps(main_dc,BITSPIXEL);
1185 b = GetDeviceCaps(main_dc,PLANES);
1186 if (a * b < 8) {
1187 MessageBox(mainPtr,"Exile III is designed for 256 colors. The current graphics device is set for less. Exile 3 is playable with less colors, but will look somewhat odd." ,
1188 "Not 256 colors!",MB_OK | MB_ICONEXCLAMATION);
1189 MessageBox(mainPtr,"For tips on how to get 256 colors, hit F1 for help, and then select 'Getting 256 Colors' from the table of contents." ,
1190 "Not 256 colors!",MB_OK | MB_ICONEXCLAMATION);
1194 void cursor_go()
1196 if (in_startup_mode == TRUE)
1197 return;
1198 if (cursor_shown == TRUE) {
1199 cursor_shown = FALSE;
1200 showcursor(FALSE);
1204 void cursor_stay()
1206 if ((cursor_shown == FALSE) || (in_startup_mode == TRUE)) {
1207 cursor_shown = TRUE;
1208 showcursor(TRUE);