diff --git a/Win32/Blades of Exile Char Editor/Blades of Exile Char Editor.cbp b/Win32/Blades of Exile Char Editor/Blades of Exile Char Editor.cbp
index 45687eaa..8c1ace8c 100644
--- a/Win32/Blades of Exile Char Editor/Blades of Exile Char Editor.cbp
+++ b/Win32/Blades of Exile Char Editor/Blades of Exile Char Editor.cbp
@@ -35,26 +35,26 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Win32/Blades of Exile Char Editor/Blades of Exile Character Editor.dev b/Win32/Blades of Exile Char Editor/Blades of Exile Character Editor.dev
index ad5f607e..6ecd47d2 100644
--- a/Win32/Blades of Exile Char Editor/Blades of Exile Character Editor.dev
+++ b/Win32/Blades of Exile Char Editor/Blades of Exile Character Editor.dev
@@ -29,27 +29,18 @@ SupportXPThemes=0
CompilerSet=0
CompilerSettings=0000000000000000000000
-[Unit1]
-FileName=BLADPCED.CPP
-CompileCpp=1
+[Unit2]
+FileName=bladpced.cpp
Folder=Blades of Exile Character Editor
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=
-
-[Unit2]
-FileName=BLADPCED.RC
-Folder=Blades of Exile Character Editor
-Compile=1
-Link=0
-Priority=1000
-OverrideBuildCmd=0
-BuildCmd=
+CompileCpp=1
[Unit3]
-FileName=DLOGTOOL.CPP
+FileName=dlogtool.cpp
CompileCpp=1
Folder=Blades of Exile Character Editor
Compile=1
@@ -59,7 +50,7 @@ OverrideBuildCmd=0
BuildCmd=
[Unit4]
-FileName=DLOGTOOL.H
+FileName=edaction.cpp
CompileCpp=1
Folder=Blades of Exile Character Editor
Compile=1
@@ -69,7 +60,7 @@ OverrideBuildCmd=0
BuildCmd=
[Unit5]
-FileName=EDACTION.CPP
+FileName=edfileio.cpp
CompileCpp=1
Folder=Blades of Exile Character Editor
Compile=1
@@ -79,7 +70,7 @@ OverrideBuildCmd=0
BuildCmd=
[Unit6]
-FileName=EDACTION.H
+FileName=editors.cpp
CompileCpp=1
Folder=Blades of Exile Character Editor
Compile=1
@@ -89,7 +80,7 @@ OverrideBuildCmd=0
BuildCmd=
[Unit7]
-FileName=EDFILEIO.CPP
+FileName=edsound.cpp
CompileCpp=1
Folder=Blades of Exile Character Editor
Compile=1
@@ -99,7 +90,7 @@ OverrideBuildCmd=0
BuildCmd=
[Unit8]
-FileName=EDFILEIO.H
+FileName=global.cpp
CompileCpp=1
Folder=Blades of Exile Character Editor
Compile=1
@@ -109,7 +100,7 @@ OverrideBuildCmd=0
BuildCmd=
[Unit9]
-FileName=EDITORS.CPP
+FileName=graphics.cpp
CompileCpp=1
Folder=Blades of Exile Character Editor
Compile=1
@@ -119,7 +110,7 @@ OverrideBuildCmd=0
BuildCmd=
[Unit10]
-FileName=EDITORS.H
+FileName=graphutl.h
CompileCpp=1
Folder=Blades of Exile Character Editor
Compile=1
@@ -129,7 +120,7 @@ OverrideBuildCmd=0
BuildCmd=
[Unit11]
-FileName=EDSOUND.CPP
+FileName=dlogtool.h
CompileCpp=1
Folder=Blades of Exile Character Editor
Compile=1
@@ -139,7 +130,7 @@ OverrideBuildCmd=0
BuildCmd=
[Unit12]
-FileName=EDSOUND.H
+FileName=edaction.h
CompileCpp=1
Folder=Blades of Exile Character Editor
Compile=1
@@ -149,7 +140,7 @@ OverrideBuildCmd=0
BuildCmd=
[Unit13]
-FileName=GLOBAL.CPP
+FileName=edfileio.h
CompileCpp=1
Folder=Blades of Exile Character Editor
Compile=1
@@ -159,7 +150,7 @@ OverrideBuildCmd=0
BuildCmd=
[Unit14]
-FileName=GLOBAL.H
+FileName=editors.h
CompileCpp=1
Folder=Blades of Exile Character Editor
Compile=1
@@ -169,7 +160,7 @@ OverrideBuildCmd=0
BuildCmd=
[Unit15]
-FileName=GRAPHICS.CPP
+FileName=edsound.h
CompileCpp=1
Folder=Blades of Exile Character Editor
Compile=1
@@ -179,7 +170,7 @@ OverrideBuildCmd=0
BuildCmd=
[Unit16]
-FileName=GRAPHICS.H
+FileName=global.h
CompileCpp=1
Folder=Blades of Exile Character Editor
Compile=1
@@ -189,7 +180,7 @@ OverrideBuildCmd=0
BuildCmd=
[Unit17]
-FileName=GRAPHUTL.CPP
+FileName=graphics.h
CompileCpp=1
Folder=Blades of Exile Character Editor
Compile=1
@@ -199,11 +190,11 @@ OverrideBuildCmd=0
BuildCmd=
[Unit18]
-FileName=GRAPHUTL.H
+FileName=BLADPCED.RC
CompileCpp=1
Folder=Blades of Exile Character Editor
Compile=1
-Link=1
+Link=0
Priority=1000
OverrideBuildCmd=0
BuildCmd=
@@ -226,3 +217,13 @@ ProductName=
ProductVersion=
AutoIncBuildNr=0
+[Unit1]
+FileName=graphutl.cpp
+CompileCpp=1
+Folder=Blades of Exile Character Editor
+Compile=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
diff --git a/Win32/Blades of Exile Char Editor/Resources/boot.cur b/Win32/Blades of Exile Char Editor/Resources/boot.cur
new file mode 100644
index 00000000..0bb41768
Binary files /dev/null and b/Win32/Blades of Exile Char Editor/Resources/boot.cur differ
diff --git a/Win32/Blades of Exile Char Editor/Resources/c.cur b/Win32/Blades of Exile Char Editor/Resources/c.cur
new file mode 100644
index 00000000..bcc4fefc
Binary files /dev/null and b/Win32/Blades of Exile Char Editor/Resources/c.cur differ
diff --git a/Win32/Blades of Exile Char Editor/Resources/d.cur b/Win32/Blades of Exile Char Editor/Resources/d.cur
new file mode 100644
index 00000000..68617d3e
Binary files /dev/null and b/Win32/Blades of Exile Char Editor/Resources/d.cur differ
diff --git a/Win32/Blades of Exile Char Editor/Resources/dl.cur b/Win32/Blades of Exile Char Editor/Resources/dl.cur
new file mode 100644
index 00000000..c4861293
Binary files /dev/null and b/Win32/Blades of Exile Char Editor/Resources/dl.cur differ
diff --git a/Win32/Blades of Exile Char Editor/Resources/dr.cur b/Win32/Blades of Exile Char Editor/Resources/dr.cur
new file mode 100644
index 00000000..7c1ae737
Binary files /dev/null and b/Win32/Blades of Exile Char Editor/Resources/dr.cur differ
diff --git a/Win32/Blades of Exile Char Editor/Resources/key.cur b/Win32/Blades of Exile Char Editor/Resources/key.cur
new file mode 100644
index 00000000..3cdf2d4a
Binary files /dev/null and b/Win32/Blades of Exile Char Editor/Resources/key.cur differ
diff --git a/Win32/Blades of Exile Char Editor/Resources/l.cur b/Win32/Blades of Exile Char Editor/Resources/l.cur
new file mode 100644
index 00000000..be7af994
Binary files /dev/null and b/Win32/Blades of Exile Char Editor/Resources/l.cur differ
diff --git a/Win32/Blades of Exile Char Editor/Resources/look.cur b/Win32/Blades of Exile Char Editor/Resources/look.cur
new file mode 100644
index 00000000..ca1ad8e5
Binary files /dev/null and b/Win32/Blades of Exile Char Editor/Resources/look.cur differ
diff --git a/Win32/Blades of Exile Char Editor/Resources/r.cur b/Win32/Blades of Exile Char Editor/Resources/r.cur
new file mode 100644
index 00000000..39f194ec
Binary files /dev/null and b/Win32/Blades of Exile Char Editor/Resources/r.cur differ
diff --git a/Win32/Blades of Exile Char Editor/Resources/snd0.wav b/Win32/Blades of Exile Char Editor/Resources/snd0.wav
new file mode 100644
index 00000000..793c0297
Binary files /dev/null and b/Win32/Blades of Exile Char Editor/Resources/snd0.wav differ
diff --git a/Win32/Blades of Exile Char Editor/Resources/snd1.wav b/Win32/Blades of Exile Char Editor/Resources/snd1.wav
new file mode 100644
index 00000000..d057572a
Binary files /dev/null and b/Win32/Blades of Exile Char Editor/Resources/snd1.wav differ
diff --git a/Win32/Blades of Exile Char Editor/Resources/snd3.wav b/Win32/Blades of Exile Char Editor/Resources/snd3.wav
new file mode 100644
index 00000000..ce6b09d0
Binary files /dev/null and b/Win32/Blades of Exile Char Editor/Resources/snd3.wav differ
diff --git a/Win32/Blades of Exile Char Editor/Resources/snd34.wav b/Win32/Blades of Exile Char Editor/Resources/snd34.wav
new file mode 100644
index 00000000..0a40f8d7
Binary files /dev/null and b/Win32/Blades of Exile Char Editor/Resources/snd34.wav differ
diff --git a/Win32/Blades of Exile Char Editor/Resources/snd37.wav b/Win32/Blades of Exile Char Editor/Resources/snd37.wav
new file mode 100644
index 00000000..6781ba20
Binary files /dev/null and b/Win32/Blades of Exile Char Editor/Resources/snd37.wav differ
diff --git a/Win32/Blades of Exile Char Editor/Resources/sword.cur b/Win32/Blades of Exile Char Editor/Resources/sword.cur
new file mode 100644
index 00000000..938203a3
Binary files /dev/null and b/Win32/Blades of Exile Char Editor/Resources/sword.cur differ
diff --git a/Win32/Blades of Exile Char Editor/Resources/talk.cur b/Win32/Blades of Exile Char Editor/Resources/talk.cur
new file mode 100644
index 00000000..2d0fe3e6
Binary files /dev/null and b/Win32/Blades of Exile Char Editor/Resources/talk.cur differ
diff --git a/Win32/Blades of Exile Char Editor/Resources/target.cur b/Win32/Blades of Exile Char Editor/Resources/target.cur
new file mode 100644
index 00000000..a077508f
Binary files /dev/null and b/Win32/Blades of Exile Char Editor/Resources/target.cur differ
diff --git a/Win32/Blades of Exile Char Editor/Resources/u.cur b/Win32/Blades of Exile Char Editor/Resources/u.cur
new file mode 100644
index 00000000..56ef1d9c
Binary files /dev/null and b/Win32/Blades of Exile Char Editor/Resources/u.cur differ
diff --git a/Win32/Blades of Exile Char Editor/Resources/ul.cur b/Win32/Blades of Exile Char Editor/Resources/ul.cur
new file mode 100644
index 00000000..9ffadb99
Binary files /dev/null and b/Win32/Blades of Exile Char Editor/Resources/ul.cur differ
diff --git a/Win32/Blades of Exile Char Editor/Resources/ur.cur b/Win32/Blades of Exile Char Editor/Resources/ur.cur
new file mode 100644
index 00000000..113bd7a3
Binary files /dev/null and b/Win32/Blades of Exile Char Editor/Resources/ur.cur differ
diff --git a/Win32/Blades of Exile Char Editor/bladpced.cpp b/Win32/Blades of Exile Char Editor/bladpced.cpp
new file mode 100644
index 00000000..f390f061
--- /dev/null
+++ b/Win32/Blades of Exile Char Editor/bladpced.cpp
@@ -0,0 +1,699 @@
+// Blades of Exile Editor
+// May God have mercy on all our souls.
+
+#include
+
+#include "stdlib.h"
+#include "string.h"
+#include "stdio.h"
+#include "math.h"
+
+#include "global.h"
+#include "graphics.h"
+#include "editors.h"
+#include "edfileio.h"
+#include "edsound.h"
+#include "dlogtool.h"
+#include "edaction.h"
+#include "graphutl.h"
+
+void check_game_done();
+void load_cursors();
+void set_cursor(HCURSOR which_curs);
+void change_cursor(POINT where_curs);
+void check_colors();
+void cursor_go();
+void cursor_stay();
+Boolean verify_restore_quit(short mode);
+void max_window(HWND window);
+void update_item_menu(short mode);
+void check_cd_event(HWND hwnd,UINT message,UINT wparam,LONG lparam);
+
+scen_item_data_type scen_item_list;
+short item_menus_lock=1;
+
+/* Mac stuff globals */
+RECT windRECT, Drag_RECT;
+Boolean All_Done = FALSE;
+short had_text_freeze = 0,num_fonts;
+Boolean in_startup_mode = TRUE,app_started_normally = FALSE,file_in_mem = FALSE;
+Boolean play_sounds = TRUE,first_startup_update = TRUE,party_in_scen = FALSE;
+Boolean diff_depth_ok = FALSE,first_sound_played = FALSE,spell_forced = FALSE,startup_loaded = FALSE;
+Boolean save_maps = FALSE,first_time = FALSE,palette_suspect = FALSE,window_in_front = TRUE;
+
+HWND sbar;
+
+Boolean bgm_on = FALSE,bgm_init = FALSE;
+
+Boolean gInBackground = FALSE;
+long start_time;
+
+// Cursors
+short current_cursor = 120;
+HCURSOR arrow_curs[3][3], sword_curs, boot_curs, key_curs, target_curs,talk_curs,look_curs;
+
+RECT pc_area_buttons[6][4] ; // 0 - whole 1 - pic 2 - name 3 - stat strs 4,5 - later
+RECT item_string_rects[24][4]; // 0 - name 1 - drop 2 - id 3 -
+RECT pc_info_rect; // Frame that holds a pc's basic info and items
+RECT name_rect; //Holds pc name inside pc_info_rect
+RECT info_area_rect;
+RECT hp_sp_rect; // Holds hit points and spells points for pc
+RECT skill_rect; // Holds "Skills:" string
+RECT pc_skills_rect[19]; //Holds current pc's skill levels
+RECT status_rect; //Holds the string "Status:"
+RECT pc_status_rect[10]; //Holds first 8 effects on pc
+RECT traits_rect; //Holds the string "Traits:"
+RECT pc_traits_rect[16]; //Holds pc traits
+RECT pc_race_rect; //Holds current pc's race
+RECT edit_rect[5][2]; //Buttons that bring up pc edit dialog boxs
+
+short store_flags[3];
+char town_strs[180][256];
+
+/* Adventure globals */
+party_record_type party;
+pc_record_type adven[6];
+outdoor_record_type outdoors[2][2];
+current_town_type c_town;
+big_tr_type t_d;
+stored_items_list_type t_i;
+unsigned char out[96][96];
+ unsigned char out_e[96][96];
+setup_save_type setup_save;
+unsigned char misc_i[64][64],sfx[64][64];
+
+short current_active_pc = 0;
+
+stored_items_list_type stored_items[3];
+stored_town_maps_type town_maps;
+stored_outdoor_maps_type o_maps;
+
+
+/* Display globals */
+short overall_mode = 45,current_spell_range;
+Boolean first_update = TRUE,anim_onscreen = FALSE,frills_on = TRUE,sys_7_avail,suppress_stat_screen = FALSE;
+short stat_window = 0,store_modifier;
+Boolean monsters_going = FALSE;
+short give_delays = 0;
+Boolean dialog_not_toast = TRUE;
+
+// storage for dialogs
+short store_chosen_pc;
+short store_choice_mode;
+location store_choice_loc;
+
+short town_size[3] = {64,48,24};
+short which_item_page[6] = {0,0,0,0,0,0}; // Remembers which of the 2 item pages pc looked at
+short pixel_depth,dialog_answer;
+
+
+// Spell casting globals
+short store_mage = 0, store_priest = 0;
+short store_mage_lev = 0, store_priest_lev = 0;
+short store_spell_target = 6,pc_casting;
+short num_targets_left = 0;
+location spell_targets[8];
+
+
+/* Windoze stuff globals */
+Boolean cursor_shown = TRUE;
+short store_pc_being_created;
+
+short ulx = 0, uly = 0;
+
+HWND mainPtr;
+HWND force_dlog = NULL;
+HFONT font,small_bold_font,italic_font,underline_font,bold_font,tiny_font;
+HBITMAP bmap = NULL;
+//HPALETTE hpal;
+HDC main_dc,main_dc2,main_dc3;
+HINSTANCE store_hInstance;
+HACCEL accel;
+BOOL event_handled;
+
+char szWinName[] = "Blades of Exile dialogs";
+char szAppName[] = "Blades of Exile Editor";
+char file_path_name[256];
+
+Boolean block_erase = FALSE;
+
+long CALLBACK _export WndProc (HWND, UINT, WPARAM, LPARAM);
+Boolean handle_menu (short, HMENU);
+
+int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR, int nCmdShow)
+{
+ MSG msg;
+ WNDCLASS wndclass,wndclass2;
+ short seed;
+
+ if (!hPrevInstance) {
+ wndclass.style = CS_HREDRAW | CS_VREDRAW | CS_BYTEALIGNWINDOW;
+ wndclass.lpfnWndProc = WndProc;
+ wndclass.cbClsExtra = 0;
+ wndclass.cbWndExtra = 0;
+ wndclass.hInstance = hInstance;
+ wndclass.hIcon = LoadIcon(hInstance,MAKEINTRESOURCE(10));
+ wndclass.hCursor = NULL;
+ wndclass.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
+ wndclass.lpszMenuName = MAKEINTRESOURCE(1);
+ wndclass.lpszClassName = szAppName;
+
+ RegisterClass(&wndclass);
+
+ wndclass2.style = CS_HREDRAW | CS_VREDRAW | CS_BYTEALIGNWINDOW;
+ wndclass2.lpfnWndProc = WndProc;
+ wndclass2.cbClsExtra = 0;
+ wndclass2.cbWndExtra = 0;
+ wndclass2.hInstance = hInstance;
+ wndclass2.hIcon = LoadIcon(hInstance,MAKEINTRESOURCE(10));
+ wndclass2.hCursor = NULL;
+ wndclass2.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
+ wndclass2.lpszMenuName = NULL;
+ wndclass2.lpszClassName = szWinName;
+
+ RegisterClass(&wndclass2);
+ }
+
+ mainPtr = CreateWindow (szAppName,
+ "Classic Blades of Exile Character Editor 1.1",
+ WS_OVERLAPPEDWINDOW,
+ 0,
+ 0,
+ 536,
+ 478,
+ NULL,
+ NULL,
+ hInstance,
+ NULL);
+
+ if (!hPrevInstance) { // initialize
+ Get_Path(file_path_name); //store the path to the executable
+ store_hInstance = hInstance;
+ accel = LoadAccelerators(hInstance, MAKEINTRESOURCE(1));
+
+ get_reg_data();
+
+ load_cursors();
+ seed = (short) GetCurrentTime();
+ srand(seed);
+
+ max_window(mainPtr);
+ Set_up_win ();
+
+ font = CreateFont(-9,0,0,0,0, 0,0,0, 0,0,
+ 0,0,0,"MS Sans Serif");
+ small_bold_font = CreateFont(12,0,0,0,700, 0,0,0, 0,0,
+ 0,0,0,"MS Sans Serif");
+ italic_font = CreateFont(12,0,0,0,0, 1,0,0, 0,0,
+ 0,0,0,"MS Sans Serif");
+ underline_font = CreateFont(12,0,0,0,0, 0,1,0, 0,0,
+ 0,0,0,"MS Sans Serif");
+ bold_font = CreateFont(14,0,0,0,700, 0,0,0, 0,0,
+ 0,0,0,"MS Sans Serif");
+ tiny_font = font;
+ load_sounds();
+
+ ShowWindow(mainPtr,nCmdShow);
+
+ init_main_buttons();
+
+ file_initialize();
+ check_colors();
+ cursor_stay();
+ update_item_menu(1);
+
+ cd_init_dialogs();
+
+ FCD(900,0);
+ }
+
+ event_handled = FALSE;
+ while(GetMessage(&msg,NULL,0,0)) {
+ if (event_handled == FALSE) {
+ if (!TranslateAccelerator(mainPtr, accel, &msg)) {
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ }
+ }
+ }
+ return msg.wParam;
+}
+
+long CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+HDC hdc;
+PAINTSTRUCT ps;
+POINT press;
+HMENU menu;
+
+ switch (message) {
+ case WM_KEYDOWN:
+ if (hwnd != mainPtr)
+ check_cd_event(hwnd,message,wParam,lParam);
+ return 0;
+ break;
+
+ case WM_CHAR:
+ if (hwnd != mainPtr)
+ check_cd_event(hwnd,message,wParam,lParam);
+ return 0;
+ break;
+
+ case WM_LBUTTONDOWN:
+ cursor_stay();
+ if (hwnd != mainPtr)
+ check_cd_event(hwnd,message,wParam,lParam);
+ else {
+ SetFocus(hwnd);
+ press = MAKEPOINT(lParam);
+
+ All_Done = handle_action(press, wParam,lParam);
+ check_game_done();
+ }
+ return 0;
+ break;
+
+
+ case WM_RBUTTONDOWN:
+ cursor_stay();
+ if (hwnd != mainPtr)
+ check_cd_event(hwnd,message,wParam,lParam);
+ return 0;
+ break;
+
+ case WM_ACTIVATE:
+ if (hwnd == mainPtr) {
+ if ((LOWORD(wParam) == WA_ACTIVE) ||(LOWORD(wParam) == WA_CLICKACTIVE)) {
+ window_in_front = TRUE;
+ }
+ if (LOWORD(wParam) == WA_INACTIVE) {
+ window_in_front = FALSE;
+ }
+ }
+ return 0;
+
+
+ case WM_MOUSEMOVE:
+ set_cursor(sword_curs);
+ return 0;
+
+ case WM_PAINT:
+ hdc = BeginPaint(hwnd,&ps);
+ EndPaint(hwnd,&ps);
+ if (hwnd != mainPtr)
+ check_cd_event(hwnd,message,wParam,lParam);
+ else redraw_screen();
+ return 0;
+
+
+ case WM_COMMAND:
+ if (hwnd == mainPtr) {
+
+ menu = GetMenu(mainPtr);
+ handle_menu((short) LOWORD(wParam), menu);
+ check_game_done();
+ }
+ else {
+ check_cd_event(hwnd,message,wParam,lParam);
+ }
+ return 0;
+
+
+ case WM_DESTROY:
+ case WM_CLOSE:
+ if (hwnd == mainPtr) {
+ lose_graphics();
+ PostQuitMessage(0);
+ }
+ return 0;
+ case WM_QUIT:
+ if (hwnd == mainPtr){
+ lose_graphics();
+ PostQuitMessage(0);
+ }
+ break;
+ }
+
+return DefWindowProc(hwnd,message,wParam,lParam);
+}
+
+void check_game_done()
+{
+ // through_sending();
+ if (All_Done == TRUE) {
+ lose_graphics();
+ PostQuitMessage(0);
+ }
+}
+
+Boolean handle_menu (short item, HMENU)
+{
+ short i,j,k;
+ Boolean to_return = FALSE;
+ item_record_type store_i;
+
+
+ if ((file_in_mem == FALSE) && ((item == 1) || (item == 3) ||
+ (item >= 40)) && (item != 200) && (item != 100)) {
+ display_strings(20,5,0,0,"Editing party",57,707,0);
+ item = -1;
+ }
+
+ switch (item) {
+ case -1: break;
+ case 1:
+ save_file(0);
+ break;
+ case 2:
+ if (verify_restore_quit(1) == TRUE)
+ load_file();
+ update_item_menu(item_menus_lock);
+ break;
+ case 3:
+ save_file(1);
+ break;
+ case 4:
+ All_Done = verify_restore_quit(0);
+ break;
+
+ case 41:
+ edit_gold_or_food(0);
+ redraw_screen();
+
+ break;
+ case 42:
+ edit_gold_or_food(1);
+ redraw_screen();
+ break;
+
+ case 44:
+ if (party.stuff_done[304][0] > 0) {
+ FCD(909,0);
+ break;
+ }
+ FCD(901,0);
+ leave_town();
+ break;
+
+ case 45:
+ if (party.stuff_done[304][0] == 0) {
+ FCD(911,0);
+ break;
+ }
+ FCD(910,0);
+ c_town.p_loc.x = party.stuff_done[304][1];
+ c_town.p_loc.y = party.stuff_done[304][2];
+ party.stuff_done[304][0] = 0;
+ for (i = 0; i < 6; i++)
+ if (adven[i].main_status >= 10)
+ adven[i].main_status -= 10;
+ redraw_screen();
+ break;
+
+
+ case 48:
+ display_strings(20,20,0,0,"Editing party",57,707,0);
+ for (i = 0; i < 4; i++)
+ party.creature_save[i].which_town = 200;
+ break;
+ case 51: // damage
+ display_strings(20,1,0,0,"Editing party",57,715,0);
+ for (i = 0; i < 6; i++)
+ adven[i].cur_health = adven[i].max_health;
+ redraw_screen();
+ break;
+ case 52: // spell pts
+ display_strings(20,2,0,0,"Editing party",57,715,0);
+ for (i = 0; i < 6; i++)
+ adven[i].cur_sp = adven[i].max_sp;
+ redraw_screen();
+ break;
+ case 53: // raise dead
+ display_strings(20,3,0,0,"Editing party",57,715,0);
+ for (i = 0; i < 6; i++)
+ if ((adven[i].main_status == 2) || (adven[i].main_status == 3) ||
+ (adven[i].main_status == 4))
+ adven[i].main_status = 1;
+ redraw_screen();
+ break;
+ case 54: // conditions
+ display_strings(20,4,0,0,"Editing party",57,715,0);
+ for (i = 0; i < 6; i++) {
+ adven[i].status[2] = 0;
+ if (adven[i].status[3] < 0)
+ adven[i].status[3] = 0;
+ adven[i].status[6] = 0;
+ adven[i].status[7] = 0;
+ adven[i].status[9] = 0;
+ adven[i].status[11] = 0;
+ adven[i].status[12] = 0;
+ adven[i].status[13] = 0;
+ }
+ redraw_screen();
+ break;
+
+ case 55:
+ if (party_in_scen == FALSE) {
+ display_strings(20,25,0,0,"Editing party",57,715,0);
+ break;
+ }
+ if (FCD(912,0) != 1)
+ break;
+ remove_party_from_scen();
+ party.stuff_done[304][0] = 0;
+ redraw_screen();
+ break;
+ case 62:
+ display_alchemy();
+ break;
+ case 63: // all property
+ display_strings(20,6,0,0,"Editing party",57,707,0);
+ for (i = 0; i < 30; i++) {
+ party.boats[i].property = FALSE;
+ party.horses[i].property = FALSE;
+ }
+ break;
+ case 70: // edit day
+ edit_day();
+ break;
+ case 71: // out maps
+ if (party_in_scen == FALSE) {
+ display_strings(20,25,0,0,"Editing party",57,715,0);
+ break;
+ }
+ display_strings(20,13,0,0,"Editing party",57,715,0);
+ for (i = 0; i < 96; i++)
+ for (j = 0; j < 96; j++)
+ out_e[i][j] = 1;
+ for (i = 0; i < 100; i++)
+ for (j = 0; j < 6; j++)
+ for (k = 0; k < 48; k++)
+ o_maps.outdoor_maps[i][j][k] = 255;
+
+ break;
+ case 72: // town maps
+ if (party_in_scen == FALSE) {
+ display_strings(20,25,0,0,"Editing party",57,715,0);
+ break;
+ }
+ display_strings(20,14,0,0,"Editing party",57,715,0);
+ for (i = 0; i < 64; i++)
+ for (j = 0; j < 64; j++)
+ c_town.explored[i][j] = 1;
+ for (i = 0; i < 200; i++)
+ for (j = 0; j < 8; j++)
+ for (k = 0; k < 64; k++)
+ town_maps.town_maps[i][j][k] = 255;
+ break;
+ case 100: // index
+ WinHelp(mainPtr,"Blades of Exile.hlp",HELP_CONTENTS,0L);
+ break;
+ case 200: // about
+ FCD(1062,0);
+ break;
+ default:
+ item -= 600;
+ store_i = scen_item_list.scen_items[item];
+ if(store_i.variety == 3){
+ party.gold += get_ran(1,1,20);
+ redraw_screen();
+ break;
+ }
+ if(store_i.variety == 11){
+ party.food += get_ran(1,1,20);
+ redraw_screen();
+ break;
+ }
+ give_to_pc(current_active_pc,store_i,FALSE);
+ draw_items(1);
+ break;
+
+ }
+
+ return to_return;
+}
+
+void load_cursors()
+{
+ sword_curs = LoadCursor(store_hInstance,MAKEINTRESOURCE(120));
+
+ set_cursor(sword_curs);
+ current_cursor = 124;
+}
+
+void set_cursor(HCURSOR which_curs)
+{
+ SetCursor (which_curs);
+}
+
+
+void check_colors()
+{
+ short a,b;
+
+ a = GetDeviceCaps(main_dc,BITSPIXEL);
+ b = GetDeviceCaps(main_dc,PLANES);
+ if (a * b < 8) {
+ MessageBox(mainPtr,"The Blades of Exile Editor is designed for 256 colors. The current graphics device is set for less. Exile is playable with less colors, but will look somewhat odd." ,
+ "Not 256 colors!",MB_OK | MB_ICONEXCLAMATION);
+ 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." ,
+ "Not 256 colors!",MB_OK | MB_ICONEXCLAMATION);
+ }
+}
+
+void cursor_go()
+{
+ if (in_startup_mode == TRUE)
+ return;
+ if (cursor_shown == TRUE) {
+ cursor_shown = FALSE;
+ showcursor(FALSE);
+ }
+}
+
+void cursor_stay()
+{
+ if ((cursor_shown == FALSE) || (in_startup_mode == TRUE)) {
+ cursor_shown = TRUE;
+ showcursor(TRUE);
+ }
+}
+
+Boolean verify_restore_quit(short mode)
+//short mode; // 0 - quit 1- restore
+{
+ short choice;
+
+ if (file_in_mem == FALSE)
+ return TRUE;
+ choice = FCD(1066 + mode,0);
+ if (choice == 3)
+ return FALSE;
+ if (choice == 2)
+ return TRUE;
+ save_file(0);
+ return TRUE;
+}
+
+void update_item_menu(short mode)
+//mode 0 - display item menus 1 - lock menus
+{
+ short i,j;
+
+ HMENU menu[10],big_menu;
+ char item_name[256];
+
+ big_menu = GetMenu(mainPtr);
+
+ for (i = 0; i < 10; i++)
+ menu[i] = GetSubMenu(big_menu,3 + i);
+ for(j=0;j<10;j++){ //first let's clean the menu
+ DeleteMenu(menu[j],1000 + j,MF_BYCOMMAND); //If there is any dummy, flush it
+ for (i=0;i<40;i++)
+ DeleteMenu(menu[j],600+(40*j)+i,MF_BYCOMMAND);
+ }
+ switch(mode){
+ case 0:
+ for (j = 0; j < 10; j++) { //then populate it
+ for (i = 0; i < 40; i++) {
+ sprintf(item_name, "%s",scen_item_list.scen_items[i + j * 40].full_name);
+ if ((i % 20 == 0) && (i > 0))
+ AppendMenu(menu[j],MF_MENUBREAK | MF_BYCOMMAND | MF_ENABLED | MF_STRING, 600 + (40 * j) + i, item_name);
+ else AppendMenu(menu[j],MF_BYCOMMAND | MF_ENABLED | MF_STRING, 600 + (40 * j) + i, item_name);
+ }
+ }
+ break;
+
+ case 1:
+ for (j = 0; j < 10; j++) //then lock menus
+ AppendMenu(menu[j],MF_MENUBREAK | MF_BYCOMMAND | MF_GRAYED | MF_STRING, 600 + (40 * j), "None");
+ break;
+ }
+}
+
+void max_window(HWND window)
+{
+ RECT main_rect,wind_rect;
+ short width,height;
+
+ cursor_shown = TRUE;
+ showcursor(TRUE);
+
+ GetWindowRect(GetDesktopWindow(),&main_rect);
+ GetWindowRect(window,&wind_rect);
+ width = main_rect.right - main_rect.left;
+ height = main_rect.bottom - main_rect.top;
+ MoveWindow(window,0,0,width,height,TRUE);
+
+}
+
+void check_cd_event(HWND hwnd,UINT message,WPARAM wparam,LPARAM lparam)
+{
+ POINT press;
+ short wind_hit = -1,item_hit = -1;
+
+ switch (message) {
+ case WM_COMMAND:
+ if (LOWORD(wparam) == 150)
+ break;
+ cd_find_dlog(hwnd,&wind_hit,&item_hit); // item_hit is dummy
+ item_hit = (short) LOWORD(wparam);
+ break;
+ case WM_KEYDOWN:
+ wind_hit = cd_process_syskeystroke(hwnd, wparam, lparam,&item_hit);
+ break;
+
+ case WM_CHAR:
+ wind_hit = cd_process_keystroke(hwnd, wparam, lparam,&item_hit);
+ break;
+
+ case WM_LBUTTONDOWN:
+ press = MAKEPOINT(lparam);
+ wind_hit = cd_process_click(hwnd,press, wparam, lparam,&item_hit);
+ break;
+ case WM_RBUTTONDOWN:
+ press = MAKEPOINT(lparam);
+ wparam = wparam | MK_CONTROL;
+ wind_hit = cd_process_click(hwnd,press, wparam, lparam,&item_hit);
+ break;
+
+ case WM_PAINT:
+ cd_redraw(hwnd);
+ break;
+ }
+ if (wind_hit < 0)
+ return;
+ switch (wind_hit) {
+ case -1: break;
+ case 917: edit_day_event_filter(item_hit); break;
+ case 970: case 971: case 972: case 973: display_strings_event_filter(item_hit); break;
+ case 991: display_pc_event_filter(item_hit); break;
+ case 996: display_alchemy_event_filter(item_hit); break;
+ case 1010: spend_xp_event_filter (item_hit); break;
+ case 1012: case 947: edit_gold_or_food_event_filter (item_hit); break;
+ case 1013: pick_race_abil_event_filter (item_hit); break;
+ case 1018: select_pc_event_filter (item_hit); break;
+ case 1024: edit_xp_event_filter (item_hit); break;
+ default: fancy_choice_dialog_event_filter (item_hit); break;
+ }
+}
diff --git a/Win32/Blades of Exile Char Editor/dlogtool.cpp b/Win32/Blades of Exile Char Editor/dlogtool.cpp
new file mode 100644
index 00000000..8a821bc2
--- /dev/null
+++ b/Win32/Blades of Exile Char Editor/dlogtool.cpp
@@ -0,0 +1,1575 @@
+#include
+
+#define ND 15
+#define NI 500
+#define NL 100
+#define NUM_DLOG_B 53
+
+#include "string.h"
+
+#include "global.h"
+#include "graphutl.h"
+#include "stdio.h"
+#include "edsound.h"
+#include "dlogtool.h"
+#include "graphics.h"
+
+extern Boolean play_sounds,cursor_shown,dialog_not_toast,block_erase;
+extern HBITMAP mixed_gworld, pc_stats_gworld, item_stats_gworld, text_area_gworld;
+extern HBITMAP storage_gworld,terrain_screen_gworld,text_bar_gworld,orig_text_bar_gworld,buttons_gworld;
+extern HBITMAP party_template_gworld,items_gworld,tiny_obj_gworld,fields_gworld;
+extern HBITMAP dlg_buttons_gworld,spec_scen_g;
+extern HBITMAP pcs_gworld,dlogpics_gworld;
+extern HFONT fantasy_font,font,italic_font,underline_font,bold_font,tiny_font,small_bold_font;
+extern HWND mainPtr;
+//extern HPALETTE hpal;
+extern HDC main_dc;
+extern HINSTANCE store_hInstance;
+long CALLBACK WndProc (HWND, UINT, UINT, LONG);
+extern HBRUSH bg[14];
+
+// Necessary evil
+extern HBITMAP anim_gworld,pcs_gworld;
+extern HBITMAP map_gworld,mixed_gworld;
+extern HBITMAP button_num_gworld;
+extern HBITMAP terrain_screen_gworld, buttons_gworld, text_screen_gworld,text_bar_gworld,orig_text_bar_gworld;
+extern HBITMAP pc_info_screen_gworld,orig_pc_info_screen_gworld,terrain_gworld, party_template_gworld;
+extern HBITMAP monster_template_gworld;
+extern HBITMAP startmsc_gworld;
+extern short terrain_pic[256];
+extern short ulx,uly;
+
+extern HACCEL accel;
+extern unsigned char m_pic_index_x[200];
+extern unsigned char m_pic_index_y[200];
+extern unsigned char m_pic_index[200];
+
+short current_key = 0;
+short dlg_keys[ND];
+short dlg_types[ND];
+HWND dlgs[ND];
+HWND dlg_parent[ND];
+short dlg_highest_item[ND];
+Boolean dlg_draw_ready[ND];
+
+short item_dlg[NI];
+short item_number[NI];
+char item_type[NI];
+RECT item_rect[NI];
+short item_flag[NI];
+char item_active[NI];
+char item_key[NI];
+short item_label[NI];
+short item_label_loc[NI];
+
+char text_long_str[10][256];
+char text_short_str[140][35];
+char labels[NL][25];
+Boolean label_taken[NL];
+
+HWND edit_box = NULL;
+HWND store_edit_parent; // kludgy
+WNDPROC edit_proc,old_edit_proc;
+
+HDC dlg_force_dc = NULL; // save HDCs when dealing with dlogs
+
+short store_free_slot,store_dlog_num;
+HWND store_parent;
+
+short available_dlog_buttons[NUM_DLOG_B] = {0,63,64,65,1,4,5,8,
+ 128,
+ 9,
+ 10, // 10
+ 11,12,13,
+ 14,15,16,17,29, 51,
+ 60,61,62, // 20
+ 66,69,70, 71,72,73,74,79,
+ 80,83,86,87,88, 91,92,93,99,100,
+ 101,102,104, 129,130,131,132,133,134,135,136,137};
+short button_type[150] = {1,1,4,5,1,1,0,0,1,1,
+ 1,1,1,1,1,1,1,1,8,8,
+ 9,9,9,1,1,2,1,6,7,1,
+ 1,12,1,1,2,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,
+ 0,1,1,1,2,1,1,1,2,2, // 50
+ 1,1,1,1,1,1,2,3,1,1,
+ 1,1,1,1,2,2,2,2,2,1,
+ 1,1,1,1,2,2,1,1,1,2,
+ 0,1,1,1,14,13,12,12,12,1,
+ 1,1,1,2,1,2,2,2,2,1, // 100
+ 2,2,2,2,2,2,2,2,2,2,
+ 2,2,2,2,2,2,2,2,1,1,
+ 1,1,1,1,1,1,1,1,0,0,
+ 0,0,0,0,0,0,0,0,0,0};
+char *button_strs[150] = {"Done ","Ask"," "," ","Keep", "Cancel","+","-","Buy","Leave",
+ "Get","1","2","3","4","5","6","Cast"," "," ",
+ " "," "," ","Buy","Sell","Other Spells","Buy x10"," "," ","Save",
+ "Race","Train","Items","Spells","Heal Party","1","2","3","4","5",
+ "6","7","8","9","10","11","12","13","14","15",
+ /*50*/ "16","Take","Create","Delete","Race/Special","Skill","Name","Graphic","Bash Door","Pick Lock",
+ "Leave","Steal","Attack","OK","Yes","No","Step In"," ","Record","Climb",
+ "Flee","Onward","Answer","Drink","Approach","Mage Spells","Priest Spells","Advantages","New Game","Land",
+ "Under","Restore","Restart","Quit","Save First","Just Quit","Rest","Read","Pull","Alchemy",
+ "17","Push","Pray","Wait","","","Delete","Graphic","Create","Give",
+ /*100*/ "Destroy","Pay","Free","Next Tip","Touch", "Open File","Create/Edit","Clear Special","Edit Abilities","Choose",
+ "Go Back","Create New","General","One Shots","Affect PCs","If-Thens","Town Specs","Out Specs","Advanced","Weapon Abil",
+ "General Abil.","NonSpell Use","Spell Usable","Reagents","Missiles","Abilities","Pick Picture","Animated","Enter","Burn",
+ "Insert","Remove","Accept","Refuse","Open","Close","Sit","Stand","","",
+ "18","19","20","Invisible!","","","","","",""};
+
+short button_left_adj[150] = {0,0,0,0,0, 0,0,0,0,0,
+0,0,0,0,0, 0,0,0,0,0,
+0,0,0,0,0, 0,0,0,0,0,
+0,0,0,0,0, 0,0,0,0,0,
+0,0,0,0,0, 0,0,0,0,0,
+0,0,0,0,0, 0,0,0,0,0, // 50
+0,0,0,0,0, 0,0,0,0,0,
+0,0,0,0,0, 0,0,0,0,0,
+0,0,0,0,0, 0,0,0,0,0,
+0,0,0,0,0, 0,0,0,0,0,
+0,0,0,0,0, 0,0,0,0,0,
+0,0,0,0,0, 0,0,0,0,0,
+0,0,0,0,0, 0,0,0,0,0,
+0,0,0,0,0, 0,0,0,0,0,
+0,0,0,0,0, 0,0,0,0,0};
+char button_def_key[150] = {0,0,20,21,'k', 24,0,0,0,0,
+ 'g','1','2','3','4', '5','6',0,0,0,
+ 0,0,0,0,0,' ',0,22,23,0,
+ 0,0,0,0,0,'1','2','3','4','5',
+ '6','7','8','9','a', 'b','c','d','e','f',
+ 'g',0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,'y','n',0,'?','r',0,
+ 0,0,0,0,0,0,0,0,0, 0,
+ 0,0,0,0,0,0,0,0,0,0,
+ 'g',0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0
+ };
+ // specials ... 20 - <- 21 - -> 22 up 23 down 24 esc
+ // 25-30 ctrl 1-6 31 - return
+
+short button_ul_x[15] = {0,46,0,126,0, 0,126,126,126,138, 166,0,0,126,172};
+short button_ul_y[15] = {0,0,132,23,46, 69,46,69,36,36, 36,23,92,92,0};
+short button_width[15] = {23,63,102,16,63, 63,63,63,6,14, 14,63,63,63,30};
+short button_height[15] = {23,23,23,13,23, 23,23,23,6,10,10,23,40,40,30};
+
+BOOL CALLBACK dummy_dialog_proc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
+LRESULT CALLBACK fresh_edit_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
+
+DLGPROC d_proc;
+
+extern char szAppName[];
+extern char szWinName[];
+
+void cd_init_dialogs()
+{
+ short i;
+
+ for (i = 0; i < ND; i++) {
+ dlg_keys[i] = -1;
+ dlg_types[i] = 0;
+ dlgs[i] = NULL;
+ dlg_highest_item[i] = 0;
+ }
+ for (i = 0; i < NI; i++) {
+ item_dlg[i] = -1;
+ }
+ for (i = 0; i < NL; i++) {
+ label_taken[i] = FALSE;
+ }
+ d_proc = dummy_dialog_proc;
+ edit_proc = fresh_edit_proc;
+}
+
+long CALLBACK fresh_edit_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+
+ switch (message) {
+ case WM_KEYDOWN:
+ if (wParam == VK_RETURN)
+ SendMessage(store_edit_parent,WM_COMMAND,9,0);
+ if (wParam == VK_ESCAPE)
+ SendMessage(store_edit_parent,WM_COMMAND,8,0);
+/* if (wParam == VK_RETURN)
+ SendMessage(store_edit_parent,WM_KEYDOWN,wParam,lParam);
+ if (wParam == VK_ESCAPE)
+ SendMessage(store_edit_parent,WM_KEYDOWN,wParam,lParam);*/
+ break;
+ }
+ return CallWindowProc((WNDPROC) old_edit_proc,hwnd,message,wParam,lParam);
+}
+
+short cd_create_dialog_parent_num(short dlog_num,short parent)
+{
+ short i;
+
+ if ((parent == 0) || (parent == 1))
+ return cd_create_dialog(dlog_num,mainPtr);
+ i = cd_get_dlg_index(parent);
+ if (i < 0)
+ return -1;
+ return cd_create_dialog(dlog_num,dlgs[i]);
+
+}
+
+short cd_create_dialog(short dlog_num,HWND parent)
+{
+ short i,free_slot = -1;
+ HWND dlg;
+
+ if (parent != NULL) {
+ if (IsWindowEnabled(parent) == 0)
+ return -1;
+ }
+
+ store_dlog_num = dlog_num;
+ store_parent = parent;
+
+ for (i = 0; i < ND; i++) {
+ if ((dlg_keys[i] >= 0) && (dlg_types[i] == dlog_num))
+ return -1;
+ }
+ for (i = 0; i < ND; i++) {
+ if (dlg_keys[i] < 0) {
+ free_slot = i;
+ i = 500;
+ }
+ }
+ if (free_slot < 0)
+ return -2;
+ current_key++;
+ dlg_keys[free_slot] = current_key;
+ dlg_types[free_slot] = dlog_num;
+ dlg_highest_item[free_slot] = 1;
+ dlg_draw_ready[free_slot] = FALSE;
+ dlgs[free_slot] = NULL;
+
+ // first, create dummy dlog
+ store_free_slot = free_slot;
+ dlg = CreateDialog(store_hInstance,MAKEINTRESOURCE(dlog_num),0,(DLGPROC) d_proc);
+
+ if (dlgs[free_slot] == NULL) {
+ play_sound(3);
+ return -3;
+ }
+ center_window(dlgs[free_slot]);
+
+
+
+ dlg_parent[free_slot] = parent;
+
+ switch (dlog_num) {
+ case 970: case 971: case 972: case 973: SetWindowText(dlgs[free_slot],"Blades of Exile"); break;
+ case 991: SetWindowText(dlgs[free_slot],"Character Statistics"); break;
+ case 996: SetWindowText(dlgs[free_slot],"Known Alchemy"); break;
+ case 998: SetWindowText(dlgs[free_slot],"Item Information"); break;
+ case 1012: SetWindowText(dlgs[free_slot],"How many?"); break;
+ case 1013: SetWindowText(dlgs[free_slot],"Race/Advantages/Disadvantages"); break;
+
+ case 1010: SetWindowText(dlgs[free_slot],"Training a PC"); break;
+ case 1018: SetWindowText(dlgs[free_slot],"Select a PC"); break;
+ default: SetWindowText(dlgs[free_slot],"Blades of Exile"); break;
+ }
+ ShowWindow(dlgs[free_slot],SW_SHOW);
+ DestroyWindow(dlg); //Necesary? Dunno.
+
+ if (dlg_parent[free_slot] != NULL) {
+ EnableWindow(dlg_parent[free_slot],FALSE);
+ }
+ dialog_not_toast = TRUE;
+ return 0;
+}
+
+BOOL CALLBACK dummy_dialog_proc(HWND hDlg, UINT message, WPARAM, LPARAM)
+{
+ short i,j,k,free_slot = -1,free_item = -1;
+ int type,flag;
+ char item_str[256];
+ Boolean str_stored = FALSE;
+ RECT dlg_rect;
+ short win_height = 0, win_width = 0;
+ short str_offset = 1;
+
+ free_slot = store_free_slot;
+
+ switch (message) {
+ case WM_INITDIALOG:
+
+ // now, make a window, matching dialog
+ GetWindowRect(hDlg,&dlg_rect);
+ dlgs[store_free_slot] = CreateWindow (szWinName,
+ "Blades of Exile Dialog",
+ 0,// was visible
+ 0,
+ 0,
+ dlg_rect.right - dlg_rect.left,
+ dlg_rect.bottom - dlg_rect.top,
+ NULL,
+ NULL,
+ store_hInstance,
+ NULL);
+ // Now, give the window its items
+ for (i = 0; i < 200; i++)
+ if (GetDlgItem(hDlg,i) != NULL) {
+ GetDlgItemText(hDlg,i,item_str,256);
+ str_offset = 1;
+ dlg_highest_item[free_slot] = i;
+ str_stored = FALSE;
+ if (strlen((char *)item_str) == 0) {
+ sprintf((char *) item_str, "+");
+ type = 3;
+ flag = 0;
+ str_stored = TRUE;
+ }
+ else if (item_str[0] == '+') { // default is framed text
+ type = 3;
+ flag = 1;
+ str_stored = TRUE;
+ }
+ else if (item_str[0] == '*') {
+ type = 3;
+ flag = 0;
+ str_stored = TRUE;
+ }
+ else if (item_str[0] == '~') {
+ type = 7;
+ flag = 0;
+ str_stored = TRUE;
+ }
+ else if (item_str[0] == '!') {
+ type = 4;
+ flag = 0;
+ str_stored = TRUE;
+ }
+ else if (item_str[0] == '=') {
+ type = 9;
+ flag = 1;
+ str_stored = TRUE;
+ }
+ else if (((item_str[0] >= 65) && (item_str[0] <= 122)) || (item_str[0] == '"')) {
+ type = 9;
+ flag = 0;
+ str_offset = 0;
+ str_stored = TRUE;
+ }
+ else if ((item_str[0] == '^') || (item_str[0] == '&')) {
+ type = (item_str[0] == '^') ? 10 : 11;
+ flag = 1;
+ //if (string_length((char *) item_str) > 55)
+ // flag = 2;
+ str_stored = TRUE;
+ }
+ else
+ {
+ //sscanf(item_str,"%d_%d",&type,&flag);
+ type = atoi(item_str);
+ flag = atoi(item_str+2);
+ }
+
+ free_item = -1;
+ // find free item
+ switch (type) {
+ case 0: case 1: case 2: case 5: case 6:
+ for (j = 150; j < NI; j++)
+ if (item_dlg[j] < 0) {
+ free_item = j;
+ j = NI + 1;
+ }
+ break;
+ default:
+ if ((type == 9) ||
+ ((str_stored == TRUE) && (strlen((char *) item_str) > 35))) {
+ for (j = 0; j < 10; j++)
+ if (item_dlg[j] < 0) {
+ free_item = j;
+ j = NI + 1;
+ }
+ }
+ else {
+ for (j = 10; j < 140; j++)
+ if (item_dlg[j] < 0) {
+ free_item = j;
+ j = NI + 1;
+ }
+ }
+ break;
+ }
+
+ if (free_item >= 0) {
+ item_dlg[free_item] = store_dlog_num;
+ item_type[free_item] = type;
+ item_number[free_item] = i;
+
+ item_rect[free_item] = get_item_rect(hDlg,i);
+ item_rect[free_item].top = item_rect[free_item].top / 2;
+ item_rect[free_item].left = item_rect[free_item].left / 2;
+ item_rect[free_item].bottom = item_rect[free_item].bottom / 2;
+ item_rect[free_item].right = item_rect[free_item].right / 2;
+
+ /*if ((type != 5) && ((store_dlog_num >= 2000) || (store_dlog_num == 986))) {
+ item_rect[free_item].top =
+ (item_rect[free_item].top * 11) / 10;
+ item_rect[free_item].bottom =
+ (item_rect[free_item].bottom * 11) / 10;
+ }*/
+
+ item_flag[free_item] = flag;
+ item_active[free_item] = 1;
+ item_label[free_item] = 0;
+ item_label_loc[free_item] = -1;
+ item_key[free_item] = 0;
+
+ switch (type) {
+ case 0: case 1:
+ if (item_flag[free_item] != 143) {
+ item_rect[free_item].right = item_rect[free_item].left + button_width[button_type[flag]];
+ item_rect[free_item].bottom = item_rect[free_item].top + button_height[button_type[flag]];
+
+ item_key[free_item] = button_def_key[flag];
+ if (type == 1)
+ item_key[free_item] = 31;
+ }
+ break;
+ case 2:
+ item_rect[free_item].right = item_rect[free_item].left + 14;
+ item_rect[free_item].bottom = item_rect[free_item].top + 10;
+ item_key[free_item] = 255;
+ break;
+ case 3: case 4: case 7: case 8: case 9: case 10: case 11:
+ sprintf(((free_item < 10) ? text_long_str[free_item] : text_short_str[free_item - 10]),"");
+ if (str_stored == TRUE) {
+ if (free_item < 10) {
+ sprintf(text_long_str[free_item],"%s",
+ (char *) (item_str + str_offset));
+ for (k = 0; k < 256; k++) {
+ if (text_long_str[free_item][k] == '|')
+ text_long_str[free_item][k] = 13;
+ if (text_long_str[free_item][k] == '_')
+ text_long_str[free_item][k] = '"';
+ }
+ // give text a little extra room
+ //if ((store_dlog_num >= 2000) || (store_dlog_num == 986))
+ // item_rect[free_item].right += 20;
+ }
+ else {
+ sprintf(text_short_str[free_item - 10],"%-34s",
+ (char *) (item_str + str_offset));
+ for (k = 0; k < 35; k++) {
+ if (text_short_str[free_item][k] == '|')
+ text_short_str[free_item][k] = 13;
+ if (text_short_str[free_item][k] == '_')
+ text_short_str[free_item][k] = '"';
+ }
+ }
+ }
+ item_key[free_item] = 255;
+ break;
+ case 6:
+ edit_box = CreateWindow("edit",NULL,WS_CHILD | WS_BORDER | WS_VISIBLE,
+ item_rect[free_item].left,item_rect[free_item].top,
+ item_rect[free_item].right - item_rect[free_item].left,
+ max(22,item_rect[free_item].bottom - item_rect[free_item].top),
+ dlgs[free_slot],(HMENU) 150,store_hInstance,NULL);
+ store_edit_parent = dlgs[free_slot];
+ old_edit_proc = (WNDPROC) GetWindowLong(edit_box,GWL_WNDPROC);
+ SetWindowLong(edit_box,GWL_WNDPROC,(LONG) edit_proc);
+ break;
+ }
+ win_height = max(win_height, item_rect[free_item].bottom + 28);
+ win_width = max(win_width, item_rect[free_item].right + 11);
+
+ }
+
+ }
+ MoveWindow(dlgs[free_slot],0,0,win_width,win_height,FALSE);
+ EndDialog(hDlg, 0);
+ return TRUE;
+ }
+ return TRUE;
+ }
+
+void cd_set_edit_focus()
+{ if (edit_box != NULL)
+ SetFocus(edit_box);
+}
+
+short cd_kill_dialog(short dlog_num,short parent_message)
+{
+ short i,which_dlg = -1;
+
+ for (i = 0; i < ND; i++)
+ if ((dlg_keys[i] >= 0) && (dlg_types[i] == dlog_num))
+ which_dlg = i;
+ if (which_dlg < 0)
+ return -1;
+
+ for (i = 0; i < NI; i++)
+ if (item_dlg[i] == dlog_num) {
+ if (item_type[i] == 6) {
+ DestroyWindow(edit_box);
+ edit_box = NULL;
+ }
+ if (item_label[i] > 0)
+ label_taken[item_label_loc[i]] = FALSE;
+ item_dlg[i] = -1;
+ }
+
+ if (dlg_parent[which_dlg] != NULL) {
+ EnableWindow(dlg_parent[which_dlg],TRUE);
+
+ SetFocus(dlg_parent[which_dlg]);
+ SetWindowPos(dlg_parent[which_dlg],HWND_TOP,0,0,100,100,
+ SWP_NOMOVE | SWP_NOSIZE | SWP_NOREDRAW);
+ cd_set_edit_focus();
+ }
+
+ if (parent_message > 0)
+ SendMessage(dlg_parent[which_dlg],WM_COMMAND,parent_message,0);
+
+DestroyWindow(dlgs[which_dlg]);
+ dlg_keys[which_dlg] = -1;
+ dialog_not_toast = TRUE;
+ block_erase = TRUE;
+ return 0;
+}
+
+short cd_process_click(HWND window,POINT the_point, WPARAM wparam, LPARAM,short *item)
+{
+ short i,which_dlg,dlg_num,item_id;
+ short dlog_key;
+
+ if ((which_dlg = cd_find_dlog(window,&dlg_num,&dlog_key)) < 0)
+ return -1;
+
+
+ for (i = 0; i < dlg_highest_item[which_dlg] + 1; i++)
+ if ((item_id = cd_get_item_id(dlg_num,i)) >= 0) {
+ if ((PtInRect(&item_rect[item_id],the_point)) && (item_active[item_id] > 0)
+ && ((item_type[item_id] < 3) || (item_type[item_id] == 8)
+ || (item_type[item_id] == 10)|| (item_type[item_id] == 11))) {
+ *item = i;
+ if (MK_CONTROL & wparam)
+ *item += 100;
+ if (item_type[item_id] != 8)
+ cd_press_button(dlg_num,i);
+ return dlg_num;
+ }
+ }
+ return -1;
+}
+
+short cd_process_syskeystroke(HWND window, WPARAM wparam, LPARAM, short *item)
+{
+ short i,which_dlg,dlg_num,dlg_key,item_id;
+ char char_hit;
+
+
+ if ((which_dlg = cd_find_dlog(window,&dlg_num,&dlg_key)) < 0)
+ return -1;
+ // specials ... 20 - <- 21 - -> 22 up 23 down 24 esc
+ // 25-30 ctrl 1-6
+
+ switch (wparam) {
+ case VK_ESCAPE:
+ char_hit = 24;
+ break;
+ case VK_LEFT:
+ char_hit = 20;
+ break;
+ case VK_UP:
+ char_hit = 22;
+ break;
+ case VK_RIGHT:
+ char_hit = 21;
+ break;
+ case VK_DOWN:
+ char_hit = 23;
+ break;
+ case VK_RETURN:
+ char_hit = 31;
+ break;
+ default:
+ return -1;
+ }
+
+ for (i = 0; i < dlg_highest_item[which_dlg] + 1; i++)
+ if ((item_id = cd_get_item_id(dlg_num,i)) >= 0) {
+ if ((item_key[item_id] == char_hit) && (item_active[item_id] > 0)
+ && ((item_type[item_id] < 3) || (item_type[item_id] == 8))) {
+ *item = i;
+ if (item_type[item_id] != 8)
+ cd_press_button(dlg_num,i);
+ return dlg_num;
+ }
+ }
+ // kludgy. If you get an escape and is isn't processed, make it an enter
+ if (wparam == VK_ESCAPE) {
+ char_hit = 31;
+ for (i = 0; i < dlg_highest_item[which_dlg] + 1; i++)
+ if ((item_id = cd_get_item_id(dlg_num,i)) >= 0) {
+ if ((item_key[item_id] == char_hit) && (item_active[item_id] > 0)
+ && ((item_type[item_id] < 3) || (item_type[item_id] == 8))) {
+ *item = i;
+ if (item_type[item_id] != 8)
+ cd_press_button(dlg_num,i);
+ return dlg_num;
+ }
+ }
+ }
+
+ return -1;
+}
+
+short cd_process_keystroke(HWND window, WPARAM wparam, LPARAM, short *item)
+{
+ short i,which_dlg,dlg_num,dlg_key,item_id;
+ char char_hit;
+
+ if ((which_dlg = cd_find_dlog(window,&dlg_num,&dlg_key)) < 0)
+ return -1;
+ // specials ... 20 - <- 21 - -> 22 up 23 down 24 esc
+ // 25-30 ctrl 1-6
+
+ char_hit = (char) wparam;
+
+ for (i = 0; i < dlg_highest_item[which_dlg] + 1; i++)
+ if ((item_id = cd_get_item_id(dlg_num,i)) >= 0) {
+ if ((item_key[item_id] == char_hit) && (item_active[item_id] > 0)
+ && ((item_type[item_id] < 3) || (item_type[item_id] == 8))) {
+ *item = i;
+ if (item_type[item_id] != 8)
+ cd_press_button(dlg_num,i);
+ return dlg_num;
+ }
+ }
+ return -1;
+}
+
+void cd_init_button(short dlog_num,short item_num, short button_num, short status)
+{
+ short dlg_index,item_index;
+
+ if (cd_get_indices(dlog_num,item_num,&dlg_index,&item_index) < 0)
+ return;
+ if (item_type[item_index] > 1) {
+ play_sound(0);
+ return;
+ }
+ item_flag[item_index] = button_num;
+ item_active[item_index] = status;
+ item_rect[item_index].right = item_rect[item_index].left + button_width[button_num];
+ item_rect[item_index].bottom = item_rect[item_index].top + button_width[button_num];
+ item_key[item_index] = button_def_key[button_num];
+ cd_draw_item(dlog_num,item_num);
+}
+
+void cd_attach_key(short dlog_num,short item_num,char key)
+{
+ short dlg_index,item_index;
+
+ if (cd_get_indices(dlog_num,item_num,&dlg_index,&item_index) < 0)
+ return;
+
+ if ((item_type[item_index] > 2) && (item_type[item_index] != 8)) {
+ play_sound(0);
+ return;
+ }
+ item_key[item_index] = key;
+}
+
+void cd_set_pict(short dlog_num, short item_num, short pict_num)
+{
+ short dlg_index,item_index;
+ if (cd_get_indices(dlog_num,item_num,&dlg_index,&item_index) < 0)
+ return;
+ if (item_type[item_index] != 5) {
+ play_sound(0);
+ return;
+ }
+ item_flag[item_index] = pict_num;
+ if (pict_num == -1)
+ cd_erase_item(dlog_num,item_num);
+ else cd_draw_item(dlog_num,item_num);
+}
+
+void cd_activate_item(short dlog_num, short item_num, short status)
+{
+ short dlg_index,item_index;
+ if (cd_get_indices(dlog_num,item_num,&dlg_index,&item_index) < 0)
+ return;
+
+ item_active[item_index] = status;
+ cd_draw_item(dlog_num,item_num);
+}
+
+short cd_get_active(short dlog_num, short item_num)
+{
+ short dlg_index,item_index;
+ if (cd_get_indices(dlog_num,item_num,&dlg_index,&item_index) < 0)
+ return -1;
+
+ return item_active[item_index];
+}
+
+
+void cd_get_item_text(short dlog_num, short item_num, char *str)
+{
+ short dlg_index,item_index;
+ if (cd_get_indices(dlog_num,item_num,&dlg_index,&item_index) < 0)
+ return ;
+ if (item_type[item_index] == 6) {
+ //print_nums(0,0,GetWindowText(edit_box,str,255));
+ if (edit_box != NULL)
+ GetWindowText(edit_box,str,255);
+ else sprintf(str,"");
+ //add_string_to_buf(str);
+ return;
+ }
+ if (item_index >= 150) {
+ play_sound(0);
+ return;
+ }
+ if (item_index < 10)
+ sprintf(str,"%s",text_long_str[item_index]);
+ else sprintf(str,"%s",text_short_str[item_index - 10]);
+}
+
+void cd_get_text_edit_str(short, char *str)
+{
+ if (edit_box != NULL)
+ GetWindowText(edit_box,str,255);
+ else str[0] = 0;
+}
+// NOTE!!! Expects a c string
+void cd_set_text_edit_str(short, char *str)
+{
+ if (edit_box != NULL)
+ SetWindowText(edit_box,str);
+}
+void cdsin(short dlog_num, short item_num, short num)
+{
+ cd_set_item_num( dlog_num, item_num, num);
+}
+void csit(short dlog_num, short item_num, char *str)
+{
+cd_set_item_text( dlog_num, item_num, str);
+}
+void csp(short dlog_num, short item_num, short pict_num)
+{
+ cd_set_pict( dlog_num, item_num, pict_num);
+}
+
+
+void cd_set_item_text(short dlog_num, short item_num, char *str)
+{
+ short k,dlg_index,item_index;
+ if (cd_get_indices(dlog_num,item_num,&dlg_index,&item_index) < 0)
+ return ;
+ if (item_type[item_index] == 6) {
+ if (edit_box != NULL)
+ SetWindowText(edit_box,str);
+ return;
+ }
+ if (item_index >= 150) {
+ play_sound(0);
+ return;
+ }
+ if (item_index < 10) {
+ sprintf(text_long_str[item_index],"%s",str);
+ for (k = 0; k < 256; k++) {
+ if (text_long_str[item_index][k] == '|')
+ text_long_str[item_index][k] = 13;
+ if (text_long_str[item_index][k] == '_')
+ text_long_str[item_index][k] = '"';
+ }
+
+ }
+ else sprintf(text_short_str[item_index - 10],"%-34s",str);
+ cd_draw_item( dlog_num,item_num);
+}
+
+void cd_set_item_num(short dlog_num, short item_num, short num)
+{
+ short dlg_index,item_index;
+ if (cd_get_indices(dlog_num,item_num,&dlg_index,&item_index) < 0)
+ return ;
+ if (item_index >= 150) {
+ play_sound(0);
+ return;
+ }
+ if (item_index < 10)
+ sprintf(text_long_str[item_index],"%d",num);
+ else sprintf(text_short_str[item_index - 10],"%d",num);
+ cd_draw_item( dlog_num,item_num);
+}
+
+void cd_set_flag(short dlog_num,short item_num,short flag)
+{
+ short dlg_index,item_index;
+
+ if (cd_get_indices(dlog_num,item_num,&dlg_index,&item_index) < 0)
+ return;
+
+ item_flag[item_index] = flag;
+ cd_draw_item(dlog_num,item_num);
+}
+
+void cd_set_led(short dlog_num,short item_num,short state)
+{
+ short dlg_index,item_index;
+
+ if (cd_get_indices(dlog_num,item_num,&dlg_index,&item_index) < 0)
+ return;
+
+ if (item_type[item_index] != 2) {
+ play_sound(0);
+ return;
+ }
+ item_flag[item_index] = state;
+ cd_draw_item(dlog_num,item_num);
+}
+
+short cd_get_led(short dlog_num,short item_num)
+{
+ short dlg_index,item_index;
+
+ if (cd_get_indices(dlog_num,item_num,&dlg_index,&item_index) < 0)
+ return 0;
+
+ if (item_type[item_index] != 2) {
+ play_sound(0);
+ return 0;
+ }
+ return item_flag[item_index];
+}
+
+
+void cd_text_frame(short dlog_num,short item_num,short frame)
+{
+ short dlg_index,item_index;
+
+ if (cd_get_indices(dlog_num,item_num,&dlg_index,&item_index) < 0)
+ return;
+
+ if (item_index >= 150) {
+ play_sound(0);
+ return;
+ }
+ item_flag[item_index] = frame;
+ cd_draw_item(dlog_num,item_num);
+}
+
+void cd_add_label(short dlog_num, short item_num, char *label, short label_flag)
+{
+ short dlg_index,item_index,label_loc = -1;
+ short i;
+
+ if (cd_get_indices(dlog_num,item_num,&dlg_index,&item_index) < 0)
+ return;
+
+ if (item_label_loc[item_index] < 0) {
+ item_label[item_index] = label_flag;
+ for (i = 0; i < 100; i++)
+ if (label_taken[i] == FALSE) {
+ label_loc = i;
+ label_taken[i] = TRUE;
+ i = 100;
+ }
+ if (label_loc < 0) {
+ play_sound(0);
+ return;
+ }
+ item_label_loc[item_index] = label_loc;
+ }
+ else cd_erase_item(dlog_num,item_num + 100);
+ label_loc = item_label_loc[item_index];
+ sprintf((char *) labels[label_loc],"%-24s",label);
+ if (item_active[item_index] > 0)
+ cd_draw_item(dlog_num,item_num);
+}
+
+void cd_take_label(short dlog_num, short item_num)
+{
+ short dlg_index,item_index;
+
+ if (cd_get_indices(dlog_num,item_num,&dlg_index,&item_index) < 0)
+ return;
+ item_label[item_index] = 0;
+ label_taken[item_label_loc[item_index]] = FALSE;
+}
+
+void cd_key_label(short dlog_num, short item_num,short loc)
+{
+ short dlg_index,item_index;
+ char str[10];
+ if (cd_get_indices(dlog_num,item_num,&dlg_index,&item_index) < 0)
+ return;
+ sprintf((char *) str," ");
+ str[0] = item_key[item_index];
+ cd_add_label(dlog_num,item_num, str, 7 + loc * 100);
+}
+
+void cd_draw_item(short dlog_num,short item_num)
+{
+ short dlg_index,item_index,store_label;
+ HDC win_dc;
+ COLORREF colors[4] = {RGB(0,0,0),RGB(255,0,0),RGB(0,0,102),RGB(255,255,255)};
+ //UINT c[4];
+ RECT from_rect,to_rect;
+ HFONT old_font;
+
+ if (cd_get_indices(dlog_num,item_num,&dlg_index,&item_index) < 0)
+ return;
+ if (dlg_draw_ready[dlg_index] == FALSE)
+ return;
+
+ /*c[0] = GetNearestPaletteIndex(hpal,colors[0]);
+ c[1] = GetNearestPaletteIndex(hpal,colors[1]);
+ c[2] = GetNearestPaletteIndex(hpal,colors[2]);
+ c[3] = GetNearestPaletteIndex(hpal,colors[3]);*/
+ win_dc = cd_get_dlog_dc(dlg_index);
+ old_font = (HFONT) SelectObject(win_dc,small_bold_font);
+ dlg_force_dc = win_dc;
+
+ if (item_active[item_index] == 0) {
+ cd_erase_item(dlog_num,item_num);
+ cd_erase_item(dlog_num,item_num + 100);
+ }
+ else {
+ switch (item_type[item_index]) {
+ case 0: case 1: case 10: case 11:
+ if (item_flag[item_index] == 143)
+ break;
+ from_rect.top = button_ul_y[button_type[item_flag[item_index]]];
+ from_rect.left = button_ul_x[button_type[item_flag[item_index]]];
+ from_rect.bottom = from_rect.top + button_height[button_type[item_flag[item_index]]];
+ from_rect.right = from_rect.left + button_width[button_type[item_flag[item_index]]];
+ rect_draw_some_item(dlg_buttons_gworld,from_rect,(HBITMAP)win_dc,item_rect[item_index],0,2);
+
+ SelectObject(win_dc,bold_font);
+ SetTextColor(win_dc,colors[2]);
+ if (item_type[item_index] < 2)
+ OffsetRect(&item_rect[item_index],-1 * button_left_adj[item_flag[item_index]],0);
+ if (item_type[item_index] < 2) {
+ char_win_draw_string(win_dc,item_rect[item_index],
+ (char *) (button_strs[item_flag[item_index]]),1,8);
+ }
+ else {
+ char_win_draw_string(win_dc,item_rect[item_index],
+ (char *) ((item_index < 10) ? text_long_str[item_index] :
+ text_short_str[item_index - 10]),1,8);
+ }
+ if (item_type[item_index] < 2)
+ OffsetRect(&item_rect[item_index],button_left_adj[item_flag[item_index]],0);
+ SetTextColor(win_dc,colors[0]);
+
+ break;
+
+ case 2:
+ switch (item_flag[item_index]) {
+ case 0: from_rect.left = 166; from_rect.top = 36; break;
+ case 1: from_rect.left = 152; from_rect.top = 36; break;
+ case 2: from_rect.left = 138; from_rect.top = 36; break;
+ }
+ from_rect.right = from_rect.left + 14;
+ from_rect.bottom = from_rect.top + 10;
+ rect_draw_some_item( dlg_buttons_gworld,from_rect,(HBITMAP) win_dc,item_rect[item_index],0,2); break;
+ break;
+
+ case 3: case 4: case 7: case 8: case 9:
+ cd_erase_item(dlog_num,item_num);
+ SetTextColor(win_dc,colors[3]);
+ if ((item_type[item_index] == 3) || (item_type[item_index] == 9))
+ SelectObject(win_dc,small_bold_font);
+ if (item_type[item_index] == 4)
+ SelectObject(win_dc,tiny_font);
+ if (item_type[item_index] == 7)
+ SelectObject(win_dc,bold_font);
+ if (item_flag[item_index] % 10 == 1)
+ cd_frame_item(dlog_num,item_num,2);
+ if (item_flag[item_index] >= 10) {
+ SetTextColor(win_dc,colors[1]);
+ }
+
+ if (item_rect[item_index].bottom - item_rect[item_index].top < 20) {
+ item_rect[item_index].left += 3;
+ DrawText(win_dc,(char *) ((item_index < 10) ? text_long_str[item_index] :
+ text_short_str[item_index - 10]), -1, &item_rect[item_index],
+ DT_LEFT | DT_SINGLELINE | DT_VCENTER | DT_NOCLIP);
+ item_rect[item_index].left -= 3;
+ }
+ else {
+ InflateRect(&item_rect[item_index],-4,-4);
+ DrawText(win_dc,(char *) ((item_index < 10) ? text_long_str[item_index] :
+ text_short_str[item_index - 10]), -1, &item_rect[item_index],
+ DT_LEFT | DT_WORDBREAK | DT_NOCLIP);
+ InflateRect(&item_rect[item_index],4,4);
+ }
+ SetTextColor(win_dc,colors[0]);
+ break;
+ case 5:
+ if (item_flag[item_index] == -1)
+ cd_erase_item(dlog_num,item_num);
+ else draw_dialog_graphic(dlgs[dlg_index], item_rect[item_index],
+ item_flag[item_index],(item_flag[item_index] >= 2000) ? FALSE : TRUE,0);
+ break;
+ }
+ }
+
+ if (item_label[item_index] != 0) {
+ store_label = item_label[item_index];
+ if (store_label >= 1000) {
+ store_label -= 1000;
+ SelectObject(win_dc,bold_font);
+ }
+ else SelectObject(win_dc,tiny_font);
+ to_rect = item_rect[item_index];
+ switch (store_label / 100) {
+ case 0:
+ to_rect.right = to_rect.left;
+ to_rect.left -= 2 * (store_label % 100);
+ break;
+ case 1:
+ to_rect.bottom = to_rect.top;
+ to_rect.top -= 2 * (store_label % 100);
+ break;
+ case 2:
+ to_rect.left = to_rect.right;
+ to_rect.right += 2 * (store_label % 100);
+ break;
+ case 3:
+ to_rect.top = to_rect.bottom;
+ to_rect.bottom += 2 * (store_label % 100);
+ break;
+ }
+
+ if (to_rect.bottom - to_rect.top < 14) {
+ to_rect.bottom += (14 - (to_rect.bottom - to_rect.top)) / 2 + 1;
+ to_rect.top -= (14 - (to_rect.bottom - to_rect.top)) / 2 + 1;
+ }
+ //cd_erase_rect(dlog_num,to_rect);
+ if (item_active[item_index] != 0) {
+ SetTextColor(win_dc,colors[3]);
+
+ DrawText(win_dc, (char *) labels[item_label_loc[item_index]],
+ -1, &to_rect, DT_LEFT | DT_SINGLELINE | DT_VCENTER);
+ SetTextColor(win_dc,colors[0]);
+
+ }
+ }
+
+
+ SelectObject(win_dc,old_font);
+ cd_kill_dc(dlg_index,win_dc);
+ dlg_force_dc = NULL;
+ }
+
+void cd_initial_draw(short dlog_num)
+{
+ short i,which_dlg = -1;
+
+ for (i = 0; i < ND; i++)
+ if ((dlg_keys[i] >= 0) && (dlg_types[i] == dlog_num))
+ which_dlg = i;
+ if (which_dlg < 0)
+ return;
+ dlg_draw_ready[which_dlg] = TRUE;
+
+ cd_erase_item(dlog_num, 0);
+ cd_draw(dlog_num);
+}
+
+void cd_draw(short dlog_num)
+{
+ short i,which_dlg = -1;
+
+ for (i = 0; i < ND; i++)
+ if ((dlg_keys[i] >= 0) && (dlg_types[i] == dlog_num))
+ which_dlg = i;
+ if (which_dlg < 0)
+ return;
+
+ for (i = 0; i < dlg_highest_item[which_dlg] + 1; i++) {
+ cd_draw_item(dlog_num,i);
+ }
+}
+
+void cd_redraw(HWND window)
+{
+ short which_dlg,dlg_num,dlg_key;
+
+ if ((which_dlg = cd_find_dlog(window,&dlg_num,&dlg_key)) < 0)
+ return;
+ dlg_draw_ready[which_dlg] = TRUE;
+ cd_initial_draw(dlg_num);
+}
+
+void cd_frame_item(short dlog_num, short item_num, short width)
+{
+ short dlg_index,item_index;
+
+ if (cd_get_indices(dlog_num,item_num,&dlg_index,&item_index) < 0)
+ return;
+ frame_dlog_rect(dlgs[dlg_index], item_rect[item_index], width);
+}
+
+void cd_erase_item(short dlog_num, short item_num)
+// if item_num is 0, nail whole window
+// item_num + 100 just erase label
+{
+ short i,dlg_index,item_index,store_label;
+ RECT to_fry;
+ HDC win_dc;
+ Boolean just_label = FALSE;
+
+ if (item_num >= 100) {
+ item_num -= 100;
+ just_label = TRUE;
+ }
+
+ if (item_num == 0) {
+ for (i = 0; i < ND; i++)
+ if ((dlg_keys[i] >= 0) && (dlg_types[i] == dlog_num))
+ dlg_index = i;
+ GetWindowRect(dlgs[dlg_index],&to_fry);
+ OffsetRect(&to_fry,-1 * to_fry.left,-1 * to_fry.top);
+ }
+ else {
+ if (cd_get_indices(dlog_num,item_num,&dlg_index,&item_index) < 0)
+ return;
+ to_fry = item_rect[item_index];
+ if (just_label == TRUE) {
+ if (item_label[item_index] != 0) {
+ store_label = item_label[item_index];
+ if (store_label >= 1000)
+ store_label -= 1000;
+
+ switch (store_label / 100) {
+ case 0:
+ to_fry.right = to_fry.left;
+ to_fry.left -= 2 * (store_label % 100);
+ break;
+ case 1:
+ to_fry.bottom = to_fry.top;
+ to_fry.top -= 2 * (store_label % 100);
+ break;
+ case 2:
+ to_fry.left = to_fry.right;
+ to_fry.right += 2 * (store_label % 100);
+ break;
+ case 3:
+ to_fry.top = to_fry.bottom;
+ to_fry.bottom += 2 * (store_label % 100);
+ break;
+ }
+ if ((i = 12 - (to_fry.bottom - to_fry.top)) > 0) {
+ // adjust rect ... but doesn't work for bold letters
+ to_fry.bottom += i / 2;
+ to_fry.bottom++; // extra pixel to get dangly letters
+ to_fry.top -= i / 2;
+ }
+ }
+ }
+ InflateRect(&to_fry,1,1);
+
+ }
+ if (dlg_draw_ready[dlg_index] == FALSE)
+ return;
+ win_dc = cd_get_dlog_dc(dlg_index);
+ paint_pattern((HBITMAP)win_dc,2,to_fry,0);
+ cd_kill_dc(dlg_index,win_dc);
+}
+
+void cd_erase_rect(short dlog_num,RECT to_fry)
+{
+ short dlg_index;
+ HDC win_dc;
+
+ if ((dlg_index = cd_get_dlg_index(dlog_num)) < 0)
+ return;
+ if (dlg_draw_ready[dlg_index] == FALSE)
+ return;
+
+ win_dc = cd_get_dlog_dc(dlg_index);
+ paint_pattern((HBITMAP)win_dc,2,to_fry,0);
+ cd_kill_dc(dlg_index,win_dc);
+}
+
+void cd_press_button(short dlog_num, short item_num)
+{
+ short dlg_index,item_index;
+ long dummy;
+ HDC win_dc;
+ RECT from_rect;
+ COLORREF colors[3] = {RGB(0,0,0),RGB(0,0,112),RGB(0,255,255)};
+ //UINT c[3];
+
+ if (cd_get_indices(dlog_num,item_num,&dlg_index,&item_index) < 0)
+ return;
+ // no press action for redio buttons
+ if ((item_type[item_index] == 2) || (item_flag[item_index] == 143)) {
+ play_sound(34);
+ return;
+ }
+
+ /*c[0] = GetNearestPaletteIndex(hpal,colors[0]);
+ c[1] = GetNearestPaletteIndex(hpal,colors[1]);
+ c[2] = GetNearestPaletteIndex(hpal,colors[2]);*/
+ win_dc = cd_get_dlog_dc(dlg_index);
+
+ from_rect.top = button_ul_y[button_type[item_flag[item_index]]];
+ from_rect.left = button_ul_x[button_type[item_flag[item_index]]];
+ from_rect.bottom = from_rect.top + button_height[button_type[item_flag[item_index]]];
+ from_rect.right = from_rect.left + button_width[button_type[item_flag[item_index]]];
+ OffsetRect(&from_rect,button_width[button_type[item_flag[item_index]]],0);
+
+ rect_draw_some_item(dlg_buttons_gworld,from_rect,(HBITMAP) win_dc,item_rect[item_index],0,2);
+
+ SelectObject(win_dc,bold_font);
+ SetTextColor(win_dc,colors[2]);
+ if (item_type[item_index] < 2)
+ OffsetRect(&item_rect[item_index],-1 * button_left_adj[item_flag[item_index]],0);
+ if (item_type[item_index] < 2) {
+ char_win_draw_string(win_dc,item_rect[item_index],
+ (char *) (button_strs[item_flag[item_index]]),1,8);
+ }
+ else {
+ char_win_draw_string(win_dc,item_rect[item_index],
+ (char *) ((item_index < 10) ? text_long_str[item_index] :
+ text_short_str[item_index - 10]),1,8);
+ }
+ if (item_type[item_index] < 2)
+ OffsetRect(&item_rect[item_index],button_left_adj[item_flag[item_index]],0);
+
+ if (play_sounds == TRUE) {
+ play_sound(37);
+ Delay(6,&dummy);
+ }
+ else Delay(10,&dummy);
+
+ OffsetRect(&from_rect,-1 * button_width[button_type[item_flag[item_index]]],0);
+ rect_draw_some_item(dlg_buttons_gworld,from_rect,(HBITMAP)win_dc,item_rect[item_index],0,2);
+
+ SelectObject(win_dc,bold_font);
+ SetTextColor(win_dc,colors[1]);
+ if (item_type[item_index] < 2)
+ OffsetRect(&item_rect[item_index],-1 * button_left_adj[item_flag[item_index]],0);
+ if (item_type[item_index] < 2) {
+ char_win_draw_string(win_dc,item_rect[item_index],
+ (char *) (button_strs[item_flag[item_index]]),1,8);
+ }
+ else {
+ char_win_draw_string(win_dc,item_rect[item_index],
+ (char *) ((item_index < 10) ? text_long_str[item_index] :
+ text_short_str[item_index - 10]),1,8);
+ }
+ if (item_type[item_index] < 2)
+ OffsetRect(&item_rect[item_index],button_left_adj[item_flag[item_index]],0);
+
+ SelectObject(win_dc,font);
+ SetTextColor(win_dc,colors[0]);
+
+ cd_kill_dc(dlg_index,win_dc);
+ }
+
+// LOW LEVEL
+
+short cd_get_indices(short dlg_num, short item_num, short *dlg_index, short *item_index)
+{
+ if ((*dlg_index = cd_get_dlg_index(dlg_num)) < 0) {
+ return -1;
+ }
+ if ((*item_index = cd_get_item_id(dlg_num,item_num)) < 0) {
+ return -1;
+ }
+ return 0;
+ }
+
+short cd_get_dlg_index(short dlog_num)
+{
+ short i;
+
+ for (i = 0; i < ND; i++)
+ if ((dlg_keys[i] >= 0) && (dlg_types[i] == dlog_num))
+ return i;
+ return -1;
+}
+
+short cd_find_dlog(HWND window, short *dlg_num, short *dlg_key)
+{
+ short i;
+ for (i = 0; i < ND; i++)
+ if ((dlg_keys[i] >= 0) && (dlgs[i] == window)) {
+ *dlg_num = dlg_types[i];
+ *dlg_key = dlg_keys[i];
+ return i;
+ }
+ return -1;
+}
+
+short cd_get_item_id(short dlg_num, short item_num)
+{
+ short i;
+
+ for (i = 0; i < NI; i++)
+ if ((item_dlg[i] == dlg_num) && (item_number[i] == item_num))
+ return i;
+ return -1;
+}
+
+HDC cd_get_dlog_dc(short which_slot)
+{
+ HDC win_dc;
+
+ win_dc = GetDC(dlgs[which_slot]);
+
+ //SelectPalette(win_dc,hpal,0);
+ SetBkMode(win_dc,TRANSPARENT);
+ return win_dc;
+ }
+
+void cd_kill_dc(short which_slot,HDC hdc)
+{
+ fry_dc(dlgs[which_slot],hdc);
+}
+
+// External graphics tools (huh huh huh ... tool ... huh huh huh)
+
+void center_window(HWND window)
+{
+ RECT main_rect,wind_rect;
+ short width,height;
+
+ cursor_shown = TRUE;
+ showcursor(TRUE);
+
+ GetWindowRect(GetDesktopWindow(),&main_rect);
+ GetWindowRect(window,&wind_rect);
+ width = wind_rect.right - wind_rect.left;
+ height = wind_rect.bottom - wind_rect.top;
+ MoveWindow(window,((main_rect.right - main_rect.left) - width) / 2,
+ ((main_rect.bottom - main_rect.top) - height) / 2,width,height,TRUE);
+
+}
+
+RECT get_item_rect(HWND hDlg, short item_num)
+{
+ HWND item;
+ RECT big_rect,small_rect;
+
+ item = GetDlgItem(hDlg, item_num);
+ GetWindowRect(hDlg,&big_rect);
+ GetWindowRect(item,&small_rect);
+ OffsetRect(&small_rect, -1 * big_rect.left - 7, -1 * big_rect.top - 7);
+ small_rect.right += 2;
+ small_rect.bottom += 2;
+ return small_rect;
+}
+
+
+void frame_dlog_rect(HWND hDlg, RECT rect, short val)
+{
+ HDC hdc;
+ HPEN dpen,lpen,old_pen;
+ COLORREF x = RGB(0,204,255),y = RGB(0,204,255);//y = RGB(119,119,119);
+ //UINT c;
+ Boolean keep_dc = FALSE;
+
+ InflateRect(&rect,val,val);
+
+ if (hDlg == mainPtr) {
+ keep_dc = TRUE;
+ hdc = main_dc;
+ OffsetRect(&rect,ulx,uly);
+ }
+ else if (dlg_force_dc != NULL) {
+ hdc = dlg_force_dc;
+ keep_dc = TRUE;
+ }
+ else hdc = GetDC(hDlg);
+ if (hdc == NULL) {
+ play_sound(0);
+ return;
+ }
+ //SelectPalette(hdc,hpal,0);
+ //c = GetNearestPaletteIndex(hpal,x);
+ lpen = CreatePen(PS_SOLID,1,x);
+ //c = GetNearestPaletteIndex(hpal,y);
+ dpen = CreatePen(PS_SOLID,1,y);
+ old_pen = (HPEN) SelectObject(hdc,dpen);
+ MoveToEx(hdc,rect.left,rect.top, NULL);
+ LineTo(hdc,rect.right,rect.top);
+ SelectObject(hdc,lpen);
+ LineTo(hdc,rect.right,rect.bottom);
+ LineTo(hdc,rect.left,rect.bottom);
+ SelectObject(hdc,dpen);
+ LineTo(hdc,rect.left,rect.top);
+ SelectObject(hdc,old_pen);
+ if (keep_dc == FALSE)
+ fry_dc(hDlg,hdc);
+ DeleteObject(dpen);
+ DeleteObject(lpen);
+}
+
+void draw_dialog_graphic(HWND hDlg, RECT rect, short which_g, Boolean do_frame,short win_or_gworld)
+// win_or_gworld: 0 - window 1 - an HBITMAP
+// 1 means hDlg is actually an HBITMAP variable!
+// 0 - 300 number of terrain graphic
+// 400 + x - monster graphic num
+// 600 + x item graphic
+// 700 + x dlog graphic
+// 800 + x pc graphic
+// 900 + x B&W graphic
+// 950 null item
+// 1000 + x Talking face
+// 1100 - item info help
+// 1200 - pc screen help
+// 1300 - combat ap
+// 1400-1402 - button help
+// 1500 - stat symbols help
+// 1600 + x - B&W maps
+// 1700 + x - anim graphic
+{
+ RECT from2 = {0,0,36,36};
+ RECT from_rect = {0,0,28, 36};
+ RECT pc_info_from = {0,127,106,157};
+ RECT item_info_from = {174,0,312,112};
+ RECT button_help_from = {0,0,320,100};
+ RECT large_scen_from = {0,0,64,64};
+
+ HBITMAP from_gworld;
+ short draw_dest = 2;
+ HDC hdc;
+
+
+
+ if (win_or_gworld == 1)
+ draw_dest = 0;
+
+ if (which_g < 0)
+ return;
+
+ if (which_g >= 3000)
+ do_frame = FALSE;
+ which_g = which_g % 3000;
+
+ if (win_or_gworld == 0) {
+ if (dlg_force_dc != NULL)
+ hdc = dlg_force_dc;
+ else hdc = GetDC(hDlg);
+ //SelectPalette(hdc,hpal,0);
+ }
+ if (which_g == 950) { // Empty. Maybe clear space.
+ if (win_or_gworld == 0) {
+ paint_pattern((HBITMAP)hdc,2,rect,0);
+ }
+ if (dlg_force_dc == NULL)
+ fry_dc(hDlg, hdc);
+ return;
+ }
+
+ switch (which_g / 100) {
+
+ case 7: // dialog
+ which_g -= 700;
+ from_gworld = dlogpics_gworld;
+ OffsetRect(&from2,36 * (which_g % 4),36 * (which_g / 4));
+ rect_draw_some_item(from_gworld,from2,(HBITMAP) ((win_or_gworld == 1) ? (HBITMAP)hDlg: (HBITMAP)hdc)
+ ,rect,0,draw_dest);
+ break;
+ case 11: // item info help
+ from_rect = item_info_from;
+ rect.right = rect.left + from_rect.right - from_rect.left;
+ rect.bottom = rect.top + from_rect.bottom - from_rect.top;
+ rect_draw_some_item(mixed_gworld,from_rect,(HBITMAP) ((win_or_gworld == 1) ? (HBITMAP)hDlg: (HBITMAP)hdc)
+ ,rect,0,draw_dest);
+ break;
+ case 12: // item info help
+ from_rect = pc_info_from;
+ rect.right = rect.left + pc_info_from.right - pc_info_from.left;
+ rect.bottom = rect.top + pc_info_from.bottom - pc_info_from.top;
+ rect_draw_some_item(mixed_gworld,from_rect,(HBITMAP) ((win_or_gworld == 1) ? (HBITMAP)hDlg: (HBITMAP)hdc)
+ ,rect,0,draw_dest);
+ break;
+ case 14: // button help
+ which_g -= 1400;
+ if (which_g >= 10) {
+ from_gworld = load_pict(900 + which_g,hdc);
+ from_rect = large_scen_from;
+ OffsetRect(&from_rect,64 * (which_g % 10),0);
+ rect_draw_some_item(from_gworld,from_rect,(HBITMAP) ((win_or_gworld == 1) ? (HBITMAP)hDlg: (HBITMAP)hdc)
+ ,rect,0,draw_dest);
+ DeleteObject(from_gworld);
+ break;
+ }
+ from_gworld = load_pict(1401,hdc);
+ from_rect = button_help_from;
+ rect.top += 10;
+ rect.right = rect.left + from_rect.right;
+ rect.bottom = rect.top + from_rect.bottom;
+ OffsetRect(&from_rect,0,100 * which_g);
+ rect_draw_some_item(from_gworld,from_rect,(HBITMAP) ((win_or_gworld == 1) ? (HBITMAP)hDlg: (HBITMAP)hdc)
+ ,rect,0,draw_dest);
+ DeleteObject(from_gworld);
+ break;
+
+
+ case 16:
+ which_g -= 1600;
+ from_gworld = load_pict(851,hdc);
+ from_rect.right = 32;
+ from_rect.bottom = 32;
+ OffsetRect(&from_rect,32 * (which_g % 5),32 * (which_g / 5));
+ rect.right = rect.left + 32;
+ rect.bottom = rect.top + 32;
+ rect_draw_some_item(from_gworld,from_rect,(HBITMAP) ((win_or_gworld == 1) ? (HBITMAP) (hDlg): (HBITMAP) hdc)
+ ,rect,0,draw_dest);
+ DeleteObject(from_gworld);
+ break;
+
+
+
+ }
+
+ if ((win_or_gworld == 0) && (dlg_force_dc == NULL))
+ fry_dc(hDlg, hdc);
+ if ((win_or_gworld == 0) && (do_frame == TRUE)){
+ rect.bottom--; rect.right--;
+ frame_dlog_rect(hDlg,rect,3);
+ }
+}
+
+void showcursor(Boolean a)
+{
+ short i;
+ i = ShowCursor(a);
+ if (a == FALSE)
+ while (i >= 0)
+ i = ShowCursor(FALSE);
+ if (a == TRUE)
+ while (i < 0)
+ i = ShowCursor(TRUE);
+ }
+
+void ModalDialog()
+{
+ MSG msg;
+
+ while ((dialog_not_toast == TRUE) && (GetMessage(&msg,NULL,0,0))) {
+ if (!TranslateAccelerator(mainPtr, accel, &msg)) {
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ }
+ }
+}
+
+RECT calc_rect(short i, short j)
+{
+ RECT base_rect = {0,0,28,36};
+
+ OffsetRect(&base_rect,i * 28, j * 36);
+ return base_rect;
+}
diff --git a/Win32/Blades of Exile Char Editor/dlogtool.h b/Win32/Blades of Exile Char Editor/dlogtool.h
new file mode 100644
index 00000000..1e73e689
--- /dev/null
+++ b/Win32/Blades of Exile Char Editor/dlogtool.h
@@ -0,0 +1,52 @@
+void cd_set_flag(short dlog_num,short item_num,short flag);
+void cd_erase_rect(short dlog_num,RECT to_fry);
+short cd_get_led(short dlog_num,short item_num);
+void frame_di(HWND hDlg, short item_num, short val);
+void cd_kill_dc(short which_slot,HDC hdc);
+HDC cd_get_dlog_dc(short which_slot);
+short cd_get_active(short dlog_num, short item_num);
+short cd_create_dialog_parent_num(short dlog_num,short parent);
+void cd_set_edit_focus();
+void cd_init_dialogs();
+short cd_create_dialog(short dlog_num,HWND parent) ;
+short cd_kill_dialog(short dlog_num,short parent_message);
+short cd_process_click(HWND window,POINT the_point, UINT wparam, LONG lparam,short *item);
+short cd_process_syskeystroke(HWND window,UINT wparam, LONG lparam,short *item);
+short cd_process_keystroke(HWND window,UINT wparam, LONG lparam,short *item);
+void cd_init_button(short dlog_num,short item_num, short button_num, short status);
+void cd_attach_key(short dlog_num,short item_num,char key);
+void cd_set_pict(short dlog_num, short item_num, short pict_num);
+void cd_activate_item(short dlog_num, short item_num, short status);
+void cd_get_item_text(short dlog_num, short item_num, char *str);
+void cd_set_item_text(short dlog_num, short item_num, char *str);
+void cd_set_item_num(short dlog_num, short item_num, short num);
+void cd_set_led(short dlog_num,short item_num,short state);
+void cd_text_frame(short dlog_num,short item_num,short frame);
+void cd_add_label(short dlog_num, short item_num, char *label, short label_flag);
+void cd_take_label(short dlog_num, short item_num);
+void cd_key_label(short dlog_num, short item_num,short loc);
+void cd_draw_item(short dlog_num,short item_num);
+void cd_initial_draw(short dlog_num);
+void cd_draw(short dlog_num);
+void cd_redraw(HWND window);
+void cd_frame_item(short dlog_num, short item_num, short width);
+void cd_erase_item(short dlog_num, short item_num);
+void cd_press_button(short dlog_num, short item_num);
+short cd_get_indices(short dlg_num, short item_num, short *dlg_index, short *item_index);
+short cd_get_dlg_index(short dlog_num);
+short cd_find_dlog(HWND window, short *dlg_num, short *dlg_key);
+short cd_get_item_id(short dlg_num, short item_num);
+void center_window(HWND window);
+RECT get_item_rect(HWND hDlg, short item_num);
+void frame_dlog_rect(HWND hDlg, RECT rect, short val);
+void draw_dialog_graphic(HWND hDlg, RECT rect, short which_g, Boolean do_frame,short win_or_gworld) ;
+void showcursor(Boolean a);
+
+void cd_get_text_edit_str(short dlog_num, char *str);
+void cd_set_text_edit_str(short dlog_num, char *str);
+void cdsin(short dlog_num, short item_num, short num);
+void csit(short dlog_num, short item_num, char *str);
+void csp(short dlog_num, short item_num, short pict_num);
+void ModalDialog();
+
+RECT calc_rect(short i, short j);
diff --git a/Win32/Blades of Exile Char Editor/edaction.cpp b/Win32/Blades of Exile Char Editor/edaction.cpp
new file mode 100644
index 00000000..0ee4a708
--- /dev/null
+++ b/Win32/Blades of Exile Char Editor/edaction.cpp
@@ -0,0 +1,653 @@
+#include
+
+#include "stdio.h"
+
+#include "graphics.h"
+#include "global.h"
+#include "editors.h"
+#include "edfileio.h"
+#include "edaction.h"
+#include "edsound.h"
+#include "dlogtool.h"
+#include "graphutl.h"
+
+/* Adventure globals */
+extern party_record_type party;
+extern pc_record_type adven[6];
+extern outdoor_record_type outdoors[2][2];
+extern current_town_type c_town;
+extern big_tr_type t_d;
+extern stored_items_list_type t_i;
+extern unsigned char out[96][96] ;
+extern unsigned char out_e[96][96];
+extern setup_save_type setup_save;
+extern stored_items_list_type stored_items[3];
+extern stored_town_maps_type maps;
+extern stored_outdoor_maps_type o_maps;
+extern pascal Boolean cd_event_filter();
+
+extern Boolean dialog_not_toast;
+
+extern HWND mainPtr;
+extern Boolean file_in_mem;
+extern short current_cursor,dialog_answer;
+
+extern HBITMAP pc_gworld;
+extern HCURSOR sword_curs;
+extern Boolean diff_depth_ok;
+extern RECT edit_rect[5][2];
+
+
+short which_pc_displayed,store_pc_trait_mode,store_which_to_edit;
+extern short current_active_pc;
+char empty_string[256] = " ";
+extern RECT pc_area_buttons[6][4],name_rect; // 0 - whole 1 - pic 2 - name 3 - stat strs 4,5 - later
+extern RECT item_string_rects[24][4]; // 0 - name 1 - drop 2 - id 3 -
+
+short store_trait_mode,store_train_pc;
+
+extern short ulx,uly;
+// Variables for spending xp
+ Boolean talk_done = FALSE;
+ long val_for_text;
+ Boolean keep_change = FALSE;
+ short store_skills[20],store_h,store_sp,i,which_skill,store_skp = 10000,store_g = 10000;
+
+
+short skill_cost[20] = {3,3,3,2,2,2, 1,2,2,6,
+ 5, 1,2,4,2,1, 4,2,5,0};
+short skill_max[20] = {20,20,20,20,20,20,20,20,20,7,
+ 7,20,20,10,20,20,20,20,20};
+short skill_g_cost[20] = {50,50,50,40,40,40,30,50,40,250,
+ 250,25,100,200,30,20,100,80,0,0};
+short skill_bonus[21] = {-3,-3,-2,-1,0,0,1,1,1,2,
+ 2,2,3,3,3,3,4,4,4,5,5};
+pc_record_type *store_xp_pc;
+
+//extern Rect pc_area_buttons[6][6] ; // 0 - whole 1 - pic 2 - name 3 - stat strs 4,5 - later
+//extern Rect item_string_rects[24][4]; // 0 - name 1 - drop 2 - id 3 -
+Boolean handle_action(POINT the_point, UINT wparam, LONG lparam )
+//short mode; // ignore,
+{
+ short i;
+
+ Boolean to_return = FALSE;
+ Boolean ctrl_key = FALSE;
+ Boolean right_button = FALSE;
+
+ if (lparam != -1) {
+ the_point.x -= ulx;
+ the_point.y -= uly;
+ }
+ if (lparam == -2)
+ right_button = TRUE;
+ if (MK_CONTROL & wparam)
+ ctrl_key = TRUE;
+
+ if (file_in_mem == FALSE)
+ return FALSE;
+
+
+ for (i = 0; i < 6; i++)
+ if ((PtInRect(&pc_area_buttons[i][0],the_point) == TRUE) &&
+ (adven[i].main_status > 0)) {
+ do_button_action(0,i);
+ current_active_pc = i;
+ display_party(6,1);
+ draw_items(1);
+ }
+ for (i = 0; i < 5; i++)
+ if ((PtInRect(&edit_rect[i][0],the_point) == TRUE) &&
+ (adven[current_active_pc].main_status > 0)) {
+ do_button_action(0,i + 10);
+ switch(i) {
+ case 0:
+ display_pc(current_active_pc,0,0);
+ break;
+ case 1:
+ display_pc(current_active_pc,1,0);
+ break;
+ case 2:
+ pick_race_abil(&adven[current_active_pc],0,0);
+ break;
+ case 3:
+ spend_xp(current_active_pc,1,0);
+ break;
+ case 4:
+ edit_xp(&adven[current_active_pc]);
+
+ break;
+ }
+ }
+ for (i = 0; i < 24; i++)
+ if ((PtInRect(&item_string_rects[i][1],the_point) == TRUE) && // drop item
+ (adven[current_active_pc].items[i].variety > 0)) { // variety = 0 no item in slot/ non 0 item exists
+ flash_rect(item_string_rects[i][1]);
+ take_item(current_active_pc,i);
+ draw_items(1);
+ }
+ for (i = 0; i < 24; i++)
+ if ((PtInRect(&item_string_rects[i][2],the_point) == TRUE) && // identify item
+ (adven[current_active_pc].items[i].variety > 0)) {
+ flash_rect(item_string_rects[i][2]);
+ adven[current_active_pc].items[i].item_properties = adven[current_active_pc].items[i].item_properties | 1;
+ draw_items(1);
+ }
+
+ return to_return;
+}
+
+void flash_rect(RECT to_flash)
+{
+
+ long dummy;
+ HDC hdc;
+
+ hdc = GetDC(mainPtr);
+ SetViewportOrgEx( hdc,ulx,uly, NULL);
+ InvertRect (hdc,&to_flash);
+ play_sound(37);
+ Delay(5,&dummy);
+ InvertRect (hdc,&to_flash);
+ fry_dc(mainPtr,hdc);
+}
+
+void edit_gold_or_food_event_filter (short)
+{
+ char get_text[256];
+
+ int tmp;
+
+ cd_get_text_edit_str((store_which_to_edit == 0) ? 1012 : 947,(char *) get_text);
+ dialog_answer = 0;
+ sscanf((char *) get_text,"%d",&tmp);
+ dialog_answer = tmp;
+ dialog_not_toast = FALSE;
+}
+
+void edit_gold_or_food(short which_to_edit)
+//0 - gold 1 - food
+{
+ char sign_text[256];
+
+ store_which_to_edit = which_to_edit;
+
+ make_cursor_sword();
+
+ cd_create_dialog((which_to_edit == 0) ? 1012 : 947,mainPtr);
+
+ sprintf((char *) sign_text,"%d",(short) ((which_to_edit == 0) ? party.gold : party.food));
+ cd_set_text_edit_str((which_to_edit == 0) ? 1012 : 947,(char *) sign_text);
+
+ cd_set_edit_focus();
+ while (dialog_not_toast)
+ ModalDialog();
+
+ cd_kill_dialog((which_to_edit == 0) ? 1012 : 947,0);
+
+ if (dialog_answer < 0)
+ dialog_answer = -1;
+ else dialog_answer = minmax(0,25000,dialog_answer);
+
+ if (dialog_answer >= 0) {
+ if (which_to_edit == 0)
+ party.gold = dialog_answer;
+ else party.food = dialog_answer;
+ }
+}
+
+void edit_day_event_filter (short)
+{
+ char get_text[256];
+ int tmp;
+
+ cd_get_text_edit_str(917,(char *) get_text);
+ sscanf((char *) get_text,"%d",&tmp);
+ dialog_answer = tmp;
+ dialog_not_toast = FALSE;
+}
+
+void edit_day()
+{
+
+
+ char sign_text[256];
+
+
+
+ make_cursor_sword();
+
+ cd_create_dialog(917,mainPtr);
+
+ sprintf((char *) sign_text,"%d",(short) ( ((party.age) / 3700) + 1));
+ cd_set_text_edit_str(917,(char *) sign_text);
+
+ cd_set_edit_focus();
+ while (dialog_not_toast)
+ ModalDialog();
+
+
+ cd_kill_dialog(917,0);
+
+ dialog_answer = minmax(1,500,dialog_answer)-1;
+
+ party.age = (long) (3700) * (long) (dialog_answer);
+}
+
+
+void put_pc_graphics()
+{
+ short i;
+
+ for (i = 3; i < 65; i++) {
+ if (((store_trait_mode == 0) && (adven[which_pc_displayed].mage_spells[i - 3] == TRUE)) ||
+ ((store_trait_mode == 1) && (adven[which_pc_displayed].priest_spells[i - 3] == TRUE)))
+ cd_set_led(991,i,1);
+ else cd_set_led(991,i,0);
+ }
+
+ cd_set_item_text(991,69,adven[which_pc_displayed].name);
+}
+Boolean display_pc_event_filter (short item_hit)
+{
+ short pc_num;
+
+ pc_num = which_pc_displayed;
+ switch (item_hit) {
+ case 1: case 65:
+ dialog_not_toast = FALSE;
+ break;
+
+ case 66:
+ do {
+ pc_num = (pc_num == 0) ? 5 : pc_num - 1;
+ } while (adven[pc_num].main_status == 0);
+ which_pc_displayed = pc_num;
+ put_pc_graphics();
+ break;
+ case 67:
+ do {
+ pc_num = (pc_num == 5) ? 0 : pc_num + 1;
+ } while (adven[pc_num].main_status == 0);
+ which_pc_displayed = pc_num;
+ put_pc_graphics();
+ break;
+
+ default:
+ if (store_trait_mode == 0)
+ adven[which_pc_displayed].mage_spells[item_hit - 3] =
+ 1 - adven[which_pc_displayed].mage_spells[item_hit - 3];
+ else
+ adven[which_pc_displayed].priest_spells[item_hit - 3] =
+ 1 - adven[which_pc_displayed].priest_spells[item_hit - 3];
+ put_pc_graphics();
+ break;
+ }
+ return FALSE;
+}
+
+void display_pc(short pc_num,short mode,short)
+{
+ short i;
+ char label_str[256];
+
+ if (adven[pc_num].main_status == 0) {
+ for (pc_num = 0; pc_num < 6; pc_num++)
+ if (adven[pc_num].main_status == 1)
+ break;
+ }
+ which_pc_displayed = pc_num;
+ store_trait_mode = mode;
+
+ make_cursor_sword();
+
+ cd_create_dialog_parent_num(991,0);
+
+ for (i = 3; i < 65; i++) {
+ get_str(label_str,(mode == 0) ? 7 : 8,(i - 3) * 2 + 1);
+ cd_add_label(991,i,(char *)label_str,46);
+ }
+ put_pc_graphics();
+
+ cd_set_pict(991,2,714 + mode);
+ while (dialog_not_toast)
+ ModalDialog();
+
+ cd_kill_dialog(991,0);
+}
+
+
+Boolean display_alchemy_event_filter (short item_hit)
+{
+ short i;
+
+ switch (item_hit) {
+ case 1: case 3:
+ dialog_not_toast = FALSE;
+ break;
+ default:
+ party.alchemy[item_hit - 4] = 1 - party.alchemy[item_hit - 4];
+ break;
+
+ }
+ for (i = 0; i < 20; i++) {
+ if (party.alchemy[i] > 0)
+ cd_set_led(996,i + 4,1);
+ else cd_set_led(996,i + 4,0);
+ }
+ return FALSE;
+}
+
+void display_alchemy()
+{
+ short i;
+ char *alch_names[] = {"Weak Curing Potion (1)","Weak Healing Potion (1)","Weak Poison (1)",
+ "Weak Speed Potion (3)","Medium Poison (3)",
+ "Medium Heal Potion (4)","Strong Curing (5)","Medium Speed Potion (5)",
+ "Graymold Salve (7)","Weak Power Potion (9)",
+ "Potion of Clarity (9)","Strong Poison (10)","Strong Heal Potion (12)","Killer Poison (12)",
+ "Resurrection Balm (9)","Medium Power Potion (14)","Knowledge Brew (19)",
+ "Strong Strength (10)","Bliss (18)","Strong Power (20)"
+ };
+
+ make_cursor_sword();
+
+ cd_create_dialog_parent_num(996,0);
+
+
+ for (i = 0; i < 20; i++) {
+ cd_add_label(996,i + 4,alch_names[i],1083);
+ if (party.alchemy[i] > 0)
+ cd_set_led(996,i + 4,1);
+ else cd_set_led(996,i + 4,0);
+ }
+
+ while (dialog_not_toast)
+ ModalDialog();
+
+ cd_kill_dialog(996,0);
+ dialog_not_toast = TRUE;
+
+}
+
+void do_xp_keep(short pc_num,short)
+{
+ for (i = 0; i < 20; i++)
+ adven[pc_num].skills[i] = store_skills[i];
+ adven[pc_num].cur_health += store_h - adven[pc_num].max_health;
+ adven[pc_num].max_health = store_h;
+ adven[pc_num].cur_sp += store_sp - adven[pc_num].max_sp;
+ adven[pc_num].max_sp = store_sp;
+
+}
+
+void draw_xp_skills()
+{
+ short i;
+ for (i = 0; i < 19; i++) {
+ if ((store_skp >= skill_cost[i]) && (store_g >= skill_g_cost[i]))
+ cd_text_frame(1010,54 + i,11);
+ else cd_text_frame(1010,54 + i,1);
+ cd_set_item_num(1010,54 + i,store_skills[i]);
+ }
+
+ if ((store_skp >= 1) && (store_g >= 10))
+ cd_text_frame(1010,52,11);
+ else cd_text_frame(1010,52,1);
+ cd_set_item_num(1010,52,store_h);
+ if ((store_skp >= 1) && (store_g >= 15))
+ cd_text_frame(1010,53,11);
+ else cd_text_frame(1010,53,1);
+ cd_set_item_num(1010,53,store_sp);
+}
+
+
+void do_xp_draw()
+
+{
+
+
+ char get_text[256];
+ short pc_num;
+
+ pc_num = store_train_pc;
+
+ sprintf((char *) get_text, "%s",(char *) adven[pc_num].name);
+
+
+ cd_set_item_text (1010, 51,get_text);
+
+ for (i = 0; i < 20; i++)
+ store_skills[i] = adven[pc_num].skills[i];
+ store_h = adven[pc_num].max_health;
+ store_sp = adven[pc_num].max_sp;
+ store_g = 12000;
+ store_skp = 10000;
+
+ draw_xp_skills();
+
+ update_gold_skills();
+}
+
+Boolean spend_xp_event_filter (short item_hit)
+{
+ short pc_num;
+
+ Boolean talk_done = FALSE;
+
+ pc_num = store_train_pc;
+
+ switch (item_hit) {
+ case 73:
+ dialog_answer = 0;
+ talk_done = TRUE;
+ break;
+
+
+
+ case 3: case 4:
+ if (((store_h >= 250) && (item_hit == 4)) ||((store_h <= 2) && (item_hit == 3)))
+ play_sound(0);
+ else {
+ if (item_hit == 3) {
+ store_g += 10;
+ store_h -= 2;
+ store_skp += 1;
+ }
+ else {
+ if ((store_g < 10) || (store_skp < 1)) {
+
+ play_sound(0);
+ }
+ else {
+ store_g -= 10;
+ store_h += 2;
+ store_skp -= 1;
+ }
+ }
+
+ update_gold_skills();
+ cd_set_item_num(1010,52,store_h);
+ draw_xp_skills();
+
+ }
+ break;
+
+ case 5: case 6:
+ if (((store_sp >= 150) && (item_hit == 6)) || ((store_sp <= 0) && (item_hit == 5)))
+ play_sound(0);
+ else {
+ if (item_hit == 5) {
+ store_g += 15;
+ store_sp -= 1;
+ store_skp += 1;
+ }
+ else {
+ if ((store_g < 15) || (store_skp < 1)) {
+
+ play_sound(0);
+ }
+ else {
+ store_sp += 1;
+ store_g -= 15;
+ store_skp -= 1;
+ }
+ }
+
+ update_gold_skills();
+ cd_set_item_num(1010,53,store_sp);
+ draw_xp_skills();
+ }
+ break;
+
+ case 48:
+ do_xp_keep(pc_num,0);
+ dialog_answer = 1;
+ talk_done = TRUE;
+ break;
+
+ case 49:
+
+ do_xp_keep(pc_num,0);
+ do {
+ pc_num = (pc_num == 0) ? 5 : pc_num - 1;
+ } while (adven[pc_num].main_status != 1);
+ store_train_pc = pc_num;
+ do_xp_draw();
+ break;
+
+ case 50:
+
+ do_xp_keep(pc_num,0);
+ do {
+ pc_num = (pc_num == 5) ? 0 : pc_num + 1;
+ } while (adven[pc_num].main_status != 1);
+ store_train_pc = pc_num;
+ do_xp_draw();
+ break;
+
+ case 100:
+ break;
+
+ default:
+ if (item_hit >= 100) {
+ }
+ else {
+ which_skill = (item_hit - 7) / 2;
+
+ if (((store_skills[which_skill] >= skill_max[which_skill]) && ((item_hit - 7) % 2 == 1)) ||
+ ((store_skills[which_skill] == 0) && ((item_hit - 7) % 2 == 0) && (which_skill > 2)) ||
+ ((store_skills[which_skill] == 1) && ((item_hit - 7) % 2 == 0) && (which_skill <= 2)))
+ play_sound(0);
+ else {
+ if ((item_hit - 7) % 2 == 0) {
+ store_g += skill_g_cost[which_skill];
+ store_skills[which_skill] -= 1;
+ store_skp += skill_cost[which_skill];
+ }
+ else {
+ if ((store_g < skill_g_cost[which_skill]) || (store_skp < skill_cost[which_skill])) {
+
+ play_sound(0);
+ }
+ else {
+ store_skills[which_skill] += 1;
+ store_g -= skill_g_cost[which_skill];
+ store_skp -= skill_cost[which_skill];
+ }
+ }
+
+ update_gold_skills();
+ cd_set_item_num(1010,54 + which_skill,store_skills[which_skill]);
+ draw_xp_skills();
+ }
+ }
+ break;
+ }
+
+ store_train_pc = pc_num;
+ if (talk_done == TRUE) {
+ dialog_not_toast = FALSE;
+ }
+ return FALSE;
+}
+void update_gold_skills()
+{
+ csit(1010,47,"Lots!");
+ csit(1010,46,"Lots!");
+}
+Boolean spend_xp(short pc_num, short, short parent)
+//short mode; // 0 - create 1 - train
+// returns 1 if cancelled
+{
+ char get_text[256],text2[256];
+
+
+ store_train_pc = pc_num;
+
+ make_cursor_sword();
+
+ cd_create_dialog_parent_num(1010,parent);
+ sprintf((char *) get_text,"Health (%d/%d)",1,10);
+ cd_add_label(1010,52,(char *) get_text,1075);
+ sprintf((char *) get_text,"Spell Pts. (%d/%d)",1,15);
+ //cd_add_label(1010,5,get_text,1040);
+ cd_add_label(1010,53,(char *) get_text,1075);
+ for (i = 54; i < 73; i++) {
+ get_str(text2,9,1 + 2 * (i - 54));
+ sprintf((char *) get_text,"%s (%d/%d)",text2,skill_cost[i - 54],skill_g_cost[i - 54]);
+ cd_add_label(1010,i,(char *) get_text,(i < 63) ? 1075 : 1069);
+ }
+ do_xp_draw();
+
+ dialog_answer = 0;
+
+ while (dialog_not_toast)
+ ModalDialog();
+
+
+ cd_kill_dialog(1010,0);
+
+ return dialog_answer;
+}
+
+void edit_xp_event_filter (short)
+{
+ char get_text[256];
+ int tmp;
+
+ cd_get_text_edit_str(1024,(char *) get_text);
+ sscanf((char *) get_text,"%d",&tmp);
+ dialog_answer = tmp;
+ dialog_not_toast = FALSE;
+}
+
+void edit_xp(pc_record_type *pc)
+{
+
+ short item_hit;
+ char sign_text[256];
+
+
+ store_xp_pc = pc;
+
+ make_cursor_sword();
+
+ cd_create_dialog(1024,mainPtr);
+
+ sprintf((char *) sign_text,"%d",(short)pc->experience);
+ cd_set_text_edit_str(1024,(char *) sign_text);
+ item_hit = get_tnl(store_xp_pc);
+ cdsin(1024,8,item_hit);
+
+ while (dialog_not_toast)
+ ModalDialog();
+
+ cd_kill_dialog(1024,0);
+
+ if (dialog_answer < 0)
+ dialog_answer = dialog_answer * -1;
+ dialog_answer = minmax(0,10000,dialog_answer);
+
+ pc->experience = dialog_answer;
+}
diff --git a/Win32/Blades of Exile Char Editor/edaction.h b/Win32/Blades of Exile Char Editor/edaction.h
new file mode 100644
index 00000000..88b67f50
--- /dev/null
+++ b/Win32/Blades of Exile Char Editor/edaction.h
@@ -0,0 +1,20 @@
+Boolean handle_action(POINT the_point, UINT wparam, LONG lparam );
+void flash_rect(RECT to_flash);
+void edit_gold_or_food_event_filter (short item_hit);
+void edit_gold_or_food(short which_to_edit);
+void put_pc_graphics();
+Boolean display_pc_event_filter (short item_hit);
+void display_pc(short pc_num,short mode,short parent);
+Boolean display_alchemy_event_filter (short item_hit);
+void display_alchemy();
+void do_xp_keep(short pc_num,short mode);
+void draw_xp_skills();
+void do_xp_draw();
+Boolean spend_xp_event_filter (short item_hit);
+void update_gold_skills();
+Boolean spend_xp(short pc_num, short mode, short parent);
+void edit_day();
+void edit_day_event_filter (short item_hit);
+void edit_xp_event_filter (short item_hit);
+void edit_xp(pc_record_type *pc);
+
diff --git a/Win32/Blades of Exile Char Editor/edfileio.cpp b/Win32/Blades of Exile Char Editor/edfileio.cpp
new file mode 100644
index 00000000..2543e9cb
--- /dev/null
+++ b/Win32/Blades of Exile Char Editor/edfileio.cpp
@@ -0,0 +1,1334 @@
+#include
+#include
+
+#include
+#include "stdio.h"
+
+#include "global.h"
+#include "edfileio.h"
+#include "graphics.h"
+#include "edsound.h"
+#include "editors.h"
+
+
+/* Adventure globals */
+extern party_record_type party;
+extern pc_record_type adven[6];
+extern outdoor_record_type outdoors[2][2];
+extern current_town_type c_town;
+extern big_tr_type t_d;
+extern stored_items_list_type t_i;
+extern unsigned char misc_i[64][64],sfx[64][64];
+extern unsigned char out[96][96];
+extern unsigned char out_e[96][96];
+extern setup_save_type setup_save;
+extern stored_items_list_type stored_items[3];
+extern stored_town_maps_type maps;
+extern stored_outdoor_maps_type o_maps;
+
+extern scen_item_data_type scen_item_list;
+extern char file_path_name[256];
+extern short item_menus_lock;
+
+extern Boolean play_sounds,sys_7_avail,party_in_scen;
+extern short current_active_pc;
+extern HWND mainPtr;
+
+extern Boolean file_in_mem;
+
+
+typedef struct {
+ char expl[96][96];
+ } out_info_type;
+
+extern short store_flags[3];
+
+// Big waste!
+out_info_type store_map;
+char last_load_file[63] = "blades.sav";
+char szFileName [128] = "blades.sav";
+char szTitleName [128] = "blades.sav";
+OPENFILENAME ofn;
+extern stored_town_maps_type town_maps;
+extern char town_strs[180][256];
+
+short store_size;
+
+
+void Get_Path(char* path){
+
+char file_path[256]=""; // initialization
+GetModuleFileName(NULL,file_path,256); // get path to the executable
+
+int i=255; // initialize the first while loop
+while(file_path[i] != '\\')
+ {
+ i--; // find the last '\' in the path to the executable
+ } // in order to get rid of 'blades of exile.exe'
+
+
+int j=0; // initialize the second loop
+
+for(j=0;j 0) {
+ current_active_pc = i;
+ i = 6;
+ }
+
+ file_in_mem = TRUE;
+ party_in_scen = in_scen;
+
+ item_menus_lock = load_items_list();
+
+ redraw_screen();
+}
+
+short load_items_list(){ //LOAD SCENARIO ITEMS LIST
+
+ HANDLE scen_file_id;
+ DWORD dwScenByteRead;
+
+ scenario_data_type scenario;
+ char scen_name[256]="";
+
+ if(party_in_scen)
+ sprintf(scen_name,"scenarios/%s",party.scen_name);
+ else
+ sprintf(scen_name,"bladbase.exs");
+
+ scen_file_id = CreateFile(scen_name, GENERIC_READ, FILE_SHARE_READ, NULL,
+ OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+ if (scen_file_id == INVALID_HANDLE_VALUE)
+ {
+ CloseHandle(scen_file_id);
+ MessageBox(mainPtr,"Couldn't open the scenario file, trying to use bladbase.exs instead.",
+ "File Error",MB_OK | MB_ICONEXCLAMATION);
+ scen_file_id = CreateFile("bladbase.exs", GENERIC_READ, FILE_SHARE_READ, NULL,
+ OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+ if(scen_file_id == INVALID_HANDLE_VALUE){
+ CloseHandle(scen_file_id);
+ MessageBox(mainPtr,"Couldn't open bladbase.exs, can't give items.",
+ "File Error",MB_OK | MB_ICONEXCLAMATION);
+ return 1;
+ }
+ }
+
+ if (ReadFile(scen_file_id, &scenario, sizeof(scenario_data_type), &dwScenByteRead, NULL) == FALSE) //get scenario data
+ {
+ CloseHandle(scen_file_id);
+ MessageBox(mainPtr,"Invalid scenario file !",
+ "File Error",MB_OK | MB_ICONEXCLAMATION);
+ return 1;
+ }
+
+// item data
+
+ if (ReadFile(scen_file_id, &scen_item_list, sizeof(scen_item_data_type), &dwScenByteRead, NULL) == FALSE)
+ {
+ CloseHandle(scen_file_id);
+MessageBox(mainPtr,"Couldn't read the scenario item list !",
+ "File Error",MB_OK | MB_ICONEXCLAMATION);
+ return 1;
+ }
+
+ if ((scenario.flag1 == 10) && (scenario.flag2 == 20)
+ && (scenario.flag3 == 30)
+ && (scenario.flag4 == 40)) {
+ port_item_list(); //Mac scenario, so let's make sure to adjust items properties
+ }
+
+ CloseHandle(scen_file_id);
+
+ return 0;
+}//END SCENARIO ITEMS LIST LOADING
+
+void load_town_strings(short which_town){ //LOAD TOWNS STRINGS LIST
+
+ HANDLE scen_file_id;
+ long len, len_to_jump=0;
+ DWORD dwScenByteRead;
+
+ scenario_data_type scenario;
+
+ char scen_name[256]="";
+ int i,j;
+
+ sprintf(scen_name,"scenarios/%s",party.scen_name);
+
+ scen_file_id = CreateFile(scen_name, GENERIC_READ, FILE_SHARE_READ, NULL,
+ OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+ if (scen_file_id == INVALID_HANDLE_VALUE)
+ {
+ MessageBox(mainPtr,"Couldn't open the scenario file !",
+ "File Error",MB_OK | MB_ICONEXCLAMATION);
+ return;
+ }
+
+if (ReadFile(scen_file_id, &scenario, sizeof(scenario_data_type), &dwScenByteRead, NULL) == FALSE)
+ {
+ CloseHandle(scen_file_id);
+ MessageBox(mainPtr,"Invalid scenario file !",
+ "File Error",MB_OK | MB_ICONEXCLAMATION);
+ return;
+ }
+
+ if ((scenario.flag1 == 10) && (scenario.flag2 == 20)
+ && (scenario.flag3 == 30)
+ && (scenario.flag4 == 40)) {
+ port_scenario(&scenario); //Mac scenario, so let's make sure we can read it properly
+ }
+
+ len_to_jump += sizeof(scen_item_data_type);//now let's jump to the town_strings position
+ for (i = 0; i < 300; i++)
+ len_to_jump += (long) scenario.scen_str_len[i];
+ long store = 0;
+ for (i = 0; i < 100; i++)
+ for (j = 0; j < 2; j++)
+ store += (long) (scenario.out_data_size[i][j]);
+ for (i = 0; i < which_town; i++)
+ for (j = 0; j < 5; j++)
+ store += (long) (scenario.town_data_size[i][j]);
+ len_to_jump += store;
+ len_to_jump += sizeof(town_record_type);
+
+ SetFilePointer(scen_file_id, len_to_jump, NULL, FILE_CURRENT);
+
+ switch (scenario.town_size[which_town]) {
+ case 0:
+ SetFilePointer(scen_file_id, sizeof(big_tr_type), NULL, FILE_CURRENT);
+ break;
+
+ case 1:
+ SetFilePointer(scen_file_id, sizeof(ave_tr_type), NULL, FILE_CURRENT);
+ break;
+
+ case 2:
+ SetFilePointer(scen_file_id, sizeof(tiny_tr_type), NULL, FILE_CURRENT);
+ break;
+ }
+
+ // town strings
+
+ for (i = 0; i < 140; i++) {
+ len = (long) (c_town.town.strlens[i]);
+ ReadFile(scen_file_id, &town_strs[i], len, &dwScenByteRead, NULL);
+ town_strs[i][len] = 0;
+ }
+
+ CloseHandle(scen_file_id);
+
+}//END TOWNS STRINGS LOADING
+
+void save_file(short mode)
+//short mode; // 0 - normal 1 - save as
+{
+ HANDLE file_id;
+
+ short i,j;
+
+ DWORD count, bytes, dwByteRead;
+ short flag;
+ short *store;
+ party_record_type *party_ptr;
+ setup_save_type *setup_ptr;
+ pc_record_type *pc_ptr;
+
+ char *party_encryptor;
+
+ Boolean town_save = FALSE,in_scen = FALSE,save_maps = FALSE;
+
+ if (file_in_mem == FALSE)
+ return;
+
+ if (store_flags[0] == 1342)
+ town_save = TRUE;
+ if (store_flags[1] == 100)
+ in_scen = TRUE;
+ if (store_flags[2] == 5567) {
+ save_maps = TRUE;
+ }
+
+ ofn.hwndOwner = mainPtr;
+ ofn.lpstrFile = szFileName;
+ ofn.lpstrFileTitle = szTitleName;
+ ofn.Flags = OFN_OVERWRITEPROMPT;
+
+ if (mode == 1) {
+ if (GetSaveFileName(&ofn) == 0)
+ return;
+ }
+
+ file_id = CreateFile(szFileName, GENERIC_WRITE, 0, NULL,
+ CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
+
+ SetCurrentDirectory(file_path_name);
+
+ if (file_id == INVALID_HANDLE_VALUE) return;
+
+ store = &flag;
+
+ flag = (town_save == TRUE) ? 1342 : 5790;
+ if (WriteFile(file_id, store, sizeof(short), &bytes, NULL) == FALSE)
+ {
+ CloseHandle(file_id);
+ FCD(1069,0);
+ return;
+ }
+ flag = (in_scen == TRUE) ? 100 : 200;
+ if (WriteFile(file_id, store, sizeof(short), &bytes, NULL) == FALSE)
+ {
+ CloseHandle(file_id);
+ FCD(1069,0);
+ return;
+ }
+ flag = (save_maps == TRUE) ? 5567 : 3422;
+ if (WriteFile(file_id, store, sizeof(short), &bytes, NULL) == FALSE)
+ {
+ CloseHandle(file_id);
+ FCD(1069,0);
+ return;
+ }
+
+ // SAVE PARTY
+ party_ptr = &party;
+
+ party_encryptor = (char *) party_ptr;
+ for (count = 0; count < sizeof(party_record_type); count++)
+ party_encryptor[count] ^= 0x5C;
+
+ WriteFile(file_id, &party.age, 4, &dwByteRead, NULL);
+ WriteFile(file_id, &party.gold, 2, &dwByteRead, NULL);
+ WriteFile(file_id, &party.food, 2, &dwByteRead, NULL);
+ WriteFile(file_id, party.stuff_done, 310*10, &dwByteRead, NULL);
+ WriteFile(file_id, party.item_taken, 200*8, &dwByteRead, NULL);
+ WriteFile(file_id, &party.light_level, 2, &dwByteRead, NULL);
+ WriteFile(file_id, &party.outdoor_corner.x, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &party.outdoor_corner.y, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &party.i_w_c.x, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &party.i_w_c.y, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &party.p_loc.x, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &party.p_loc.y, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &party.loc_in_sec.x, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &party.loc_in_sec.y, 1, &dwByteRead, NULL);
+
+ for (i = 0; i < 30; i++)
+ {
+ WriteFile(file_id, &party.boats[i].boat_loc.x, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &party.boats[i].boat_loc.y, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &party.boats[i].boat_loc_in_sec.x, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &party.boats[i].boat_loc_in_sec.y, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &party.boats[i].boat_sector.x, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &party.boats[i].boat_sector.y, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &party.boats[i].which_town, 2, &dwByteRead, NULL);
+ WriteFile(file_id, &party.boats[i].exists, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &party.boats[i].property, 1, &dwByteRead, NULL);
+ }
+ for (i = 0; i < 30; i++)
+ {
+ WriteFile(file_id, &party.horses[i].horse_loc.x, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &party.horses[i].horse_loc.y, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &party.horses[i].horse_loc_in_sec.x, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &party.horses[i].horse_loc_in_sec.y, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &party.horses[i].horse_sector.x, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &party.horses[i].horse_sector.y, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &party.horses[i].which_town, 2, &dwByteRead, NULL);
+ WriteFile(file_id, &party.horses[i].exists, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &party.horses[i].property, 1, &dwByteRead, NULL);
+ }
+ for (i = 0; i < 4; i++)
+ {
+ for (j = 0; j < 60; j++)
+ {
+ WriteFile(file_id, &party.creature_save[i].dudes[j].active, 2, &dwByteRead, NULL);
+ WriteFile(file_id, &party.creature_save[i].dudes[j].attitude, 2, &dwByteRead, NULL);
+ WriteFile(file_id, &party.creature_save[i].dudes[j].number, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &party.creature_save[i].dudes[j].m_loc.x, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &party.creature_save[i].dudes[j].m_loc.y, 1, &dwByteRead, NULL);
+ {
+ WriteFile(file_id, &party.creature_save[i].dudes[j].m_d.m_num, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &party.creature_save[i].dudes[j].m_d.level, 1, &dwByteRead, NULL);
+ WriteFile(file_id, party.creature_save[i].dudes[j].m_d.m_name, 26, &dwByteRead, NULL);
+ WriteFile(file_id, &party.creature_save[i].dudes[j].m_d.health, 2, &dwByteRead, NULL);
+ WriteFile(file_id, &party.creature_save[i].dudes[j].m_d.m_health, 2, &dwByteRead, NULL);
+ WriteFile(file_id, &party.creature_save[i].dudes[j].m_d.mp, 2, &dwByteRead, NULL);
+ WriteFile(file_id, &party.creature_save[i].dudes[j].m_d.max_mp, 2, &dwByteRead, NULL);
+ WriteFile(file_id, &party.creature_save[i].dudes[j].m_d.armor, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &party.creature_save[i].dudes[j].m_d.skill, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &party.creature_save[i].dudes[j].m_d.a, 2*3, &dwByteRead, NULL);
+ WriteFile(file_id, &party.creature_save[i].dudes[j].m_d.a1_type, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &party.creature_save[i].dudes[j].m_d.a23_type, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &party.creature_save[i].dudes[j].m_d.m_type, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &party.creature_save[i].dudes[j].m_d.speed, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &party.creature_save[i].dudes[j].m_d.ap, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &party.creature_save[i].dudes[j].m_d.mu, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &party.creature_save[i].dudes[j].m_d.cl, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &party.creature_save[i].dudes[j].m_d.breath, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &party.creature_save[i].dudes[j].m_d.breath_type, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &party.creature_save[i].dudes[j].m_d.treasure, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &party.creature_save[i].dudes[j].m_d.spec_skill, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &party.creature_save[i].dudes[j].m_d.poison, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &party.creature_save[i].dudes[j].m_d.morale, 2, &dwByteRead, NULL);
+ WriteFile(file_id, &party.creature_save[i].dudes[j].m_d.m_morale, 2, &dwByteRead, NULL);
+ WriteFile(file_id, &party.creature_save[i].dudes[j].m_d.corpse_item, 2, &dwByteRead, NULL);
+ WriteFile(file_id, &party.creature_save[i].dudes[j].m_d.corpse_item_chance, 2, &dwByteRead, NULL);
+ WriteFile(file_id, party.creature_save[i].dudes[j].m_d.status, 2*15, &dwByteRead, NULL);
+ WriteFile(file_id, &party.creature_save[i].dudes[j].m_d.direction, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &party.creature_save[i].dudes[j].m_d.immunities, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &party.creature_save[i].dudes[j].m_d.x_width, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &party.creature_save[i].dudes[j].m_d.y_width, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &party.creature_save[i].dudes[j].m_d.radiate_1, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &party.creature_save[i].dudes[j].m_d.radiate_2, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &party.creature_save[i].dudes[j].m_d.default_attitude, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &party.creature_save[i].dudes[j].m_d.summon_type, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &party.creature_save[i].dudes[j].m_d.default_facial_pic, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &party.creature_save[i].dudes[j].m_d.res1, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &party.creature_save[i].dudes[j].m_d.res2, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &party.creature_save[i].dudes[j].m_d.res3, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &party.creature_save[i].dudes[j].m_d.picture_num, 2, &dwByteRead, NULL);
+ }
+ WriteFile(file_id, &party.creature_save[i].dudes[j].mobile, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &party.creature_save[i].dudes[j].summoned, 2, &dwByteRead, NULL);
+ {
+ WriteFile(file_id, &party.creature_save[i].dudes[j].monst_start.number, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &party.creature_save[i].dudes[j].monst_start.start_attitude, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &party.creature_save[i].dudes[j].monst_start.start_loc.x, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &party.creature_save[i].dudes[j].monst_start.start_loc.y, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &party.creature_save[i].dudes[j].monst_start.mobile, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &party.creature_save[i].dudes[j].monst_start.time_flag, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &party.creature_save[i].dudes[j].monst_start.extra1, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &party.creature_save[i].dudes[j].monst_start.extra2, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &party.creature_save[i].dudes[j].monst_start.spec1, 2, &dwByteRead, NULL);
+ WriteFile(file_id, &party.creature_save[i].dudes[j].monst_start.spec2, 2, &dwByteRead, NULL);
+ WriteFile(file_id, &party.creature_save[i].dudes[j].monst_start.spec_enc_code, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &party.creature_save[i].dudes[j].monst_start.time_code, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &party.creature_save[i].dudes[j].monst_start.monster_time, 2, &dwByteRead, NULL);
+ WriteFile(file_id, &party.creature_save[i].dudes[j].monst_start.personality, 2, &dwByteRead, NULL);
+ WriteFile(file_id, &party.creature_save[i].dudes[j].monst_start.special_on_kill, 2, &dwByteRead, NULL);
+ WriteFile(file_id, &party.creature_save[i].dudes[j].monst_start.facial_pic, 2, &dwByteRead, NULL);
+ }
+ }
+
+ WriteFile(file_id, &party.creature_save[i].which_town, 2, &dwByteRead, NULL);
+ WriteFile(file_id, &party.creature_save[i].friendly, 2, &dwByteRead, NULL);
+ }
+
+ WriteFile(file_id, &party.in_boat, 2, &dwByteRead, NULL);
+ WriteFile(file_id, &party.in_horse, 2, &dwByteRead, NULL);
+ for (i = 0; i < 10; i++)
+ {
+ WriteFile(file_id, &party.out_c[i].exists, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &party.out_c[i].direction, 2, &dwByteRead, NULL);
+ {
+ WriteFile(file_id, party.out_c[i].what_monst.monst, 7, &dwByteRead, NULL);
+ WriteFile(file_id, party.out_c[i].what_monst.friendly, 3, &dwByteRead, NULL);
+ WriteFile(file_id, &party.out_c[i].what_monst.spec_on_meet, 2, &dwByteRead, NULL);
+ WriteFile(file_id, &party.out_c[i].what_monst.spec_on_win, 2, &dwByteRead, NULL);
+ WriteFile(file_id, &party.out_c[i].what_monst.spec_on_flee, 2, &dwByteRead, NULL);
+ WriteFile(file_id, &party.out_c[i].what_monst.cant_flee, 2, &dwByteRead, NULL);
+ WriteFile(file_id, &party.out_c[i].what_monst.end_spec1, 2, &dwByteRead, NULL);
+ WriteFile(file_id, &party.out_c[i].what_monst.end_spec1, 2, &dwByteRead, NULL);
+ }
+ WriteFile(file_id, &party.out_c[i].which_sector.x, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &party.out_c[i].which_sector.y, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &party.out_c[i].m_loc.x, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &party.out_c[i].m_loc.y, 1, &dwByteRead, NULL);
+ }
+ for (i = 0; i < 5; i++)
+ for (j = 0; j < 10; j++)
+ {
+ WriteFile(file_id, &party.magic_store_items[i][j].variety, 2, &dwByteRead, NULL);
+ WriteFile(file_id, &party.magic_store_items[i][j].item_level, 2, &dwByteRead, NULL);
+ WriteFile(file_id, &party.magic_store_items[i][j].awkward, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &party.magic_store_items[i][j].bonus, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &party.magic_store_items[i][j].protection, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &party.magic_store_items[i][j].charges, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &party.magic_store_items[i][j].type, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &party.magic_store_items[i][j].magic_use_type, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &party.magic_store_items[i][j].graphic_num, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &party.magic_store_items[i][j].ability, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &party.magic_store_items[i][j].ability_strength, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &party.magic_store_items[i][j].type_flag, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &party.magic_store_items[i][j].is_special, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &party.magic_store_items[i][j].a, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &party.magic_store_items[i][j].value, 2, &dwByteRead, NULL);
+ WriteFile(file_id, &party.magic_store_items[i][j].weight, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &party.magic_store_items[i][j].special_class, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &party.magic_store_items[i][j].item_loc.x, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &party.magic_store_items[i][j].item_loc.y, 1, &dwByteRead, NULL);
+ WriteFile(file_id, party.magic_store_items[i][j].full_name, 25, &dwByteRead, NULL);
+ WriteFile(file_id, party.magic_store_items[i][j].name, 15, &dwByteRead, NULL);
+ WriteFile(file_id, &party.magic_store_items[i][j].treas_class, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &party.magic_store_items[i][j].item_properties, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &party.magic_store_items[i][j].reserved1, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &party.magic_store_items[i][j].reserved2, 1, &dwByteRead, NULL);
+ }
+ WriteFile(file_id, &party.imprisoned_monst, 2*4, &dwByteRead, NULL);
+ WriteFile(file_id, party.m_seen, 256, &dwByteRead, NULL);
+ WriteFile(file_id, party.journal_str, 50, &dwByteRead, NULL);
+ WriteFile(file_id, party.journal_day, 2*50, &dwByteRead, NULL);
+ WriteFile(file_id, party.special_notes_str, 2*140*2, &dwByteRead, NULL);
+ for (i = 0; i < 120; i++)
+ {
+ WriteFile(file_id, &party.talk_save[i].personality, 2, &dwByteRead, NULL);
+ WriteFile(file_id, &party.talk_save[i].town_num, 2, &dwByteRead, NULL);
+ WriteFile(file_id, &party.talk_save[i].str1, 2, &dwByteRead, NULL);
+ WriteFile(file_id, &party.talk_save[i].str2, 2, &dwByteRead, NULL);
+ }
+ WriteFile(file_id, &party.direction, 2, &dwByteRead, NULL);
+ WriteFile(file_id, &party.at_which_save_slot, 2, &dwByteRead, NULL);
+ WriteFile(file_id, party.alchemy, 20, &dwByteRead, NULL);
+ WriteFile(file_id, party.can_find_town, 200, &dwByteRead, NULL);
+ WriteFile(file_id, party.key_times, 2*100, &dwByteRead, NULL);
+ WriteFile(file_id, party.party_event_timers, 2*30, &dwByteRead, NULL);
+ WriteFile(file_id, party.global_or_town, 2*30, &dwByteRead, NULL);
+ WriteFile(file_id, party.node_to_call, 2*30, &dwByteRead, NULL);
+ WriteFile(file_id, party.spec_items, 50, &dwByteRead, NULL);
+ WriteFile(file_id, party.help_received, 120, &dwByteRead, NULL);
+ WriteFile(file_id, party.m_killed, 2*200, &dwByteRead, NULL);
+ WriteFile(file_id, &party.total_m_killed, 4, &dwByteRead, NULL);
+ WriteFile(file_id, &party.total_dam_done, 4, &dwByteRead, NULL);
+ WriteFile(file_id, &party.total_xp_gained, 4, &dwByteRead, NULL);
+ WriteFile(file_id, &party.total_dam_taken, 4, &dwByteRead, NULL);
+ WriteFile(file_id, party.scen_name, 256, &dwByteRead, NULL);
+
+ for (count = 0; count < sizeof(party_record_type); count++)
+ party_encryptor[count] ^= 0x5C;
+
+ // SAVE SETUP
+ setup_ptr = &setup_save;
+ if (WriteFile(file_id, &setup_save, sizeof(setup_save_type), &bytes, NULL) == FALSE)
+ {
+ CloseHandle(file_id);
+ FCD(1069,0);
+ return;
+ }
+
+ // SAVE PCS
+ for (i = 0; i < 6; i++) {
+ pc_ptr = &adven[i];
+
+ party_encryptor = (char *) pc_ptr;
+ for (count = 0; count < sizeof(pc_record_type); count++)
+ party_encryptor[count] ^= 0x6B;
+ if (WriteFile(file_id, pc_ptr, sizeof(pc_record_type), &bytes, NULL) == FALSE)
+ {
+ CloseHandle(file_id);
+ for (count = 0; count < sizeof(pc_record_type); count++)
+ party_encryptor[count] ^= 0x6B;
+ FCD(1069,0);
+ MessageBeep(MB_OK);
+ return;
+ }
+ for (count = 0; count < sizeof(pc_record_type); count++)
+ party_encryptor[count] ^= 0x6B;
+ }
+
+ if (party_in_scen == TRUE) {
+
+ // SAVE OUT DATA
+ if (WriteFile(file_id, out_e, sizeof(out_info_type), &bytes, NULL) == FALSE)
+ {
+ CloseHandle(file_id);
+ FCD(1069,0);
+ return;
+ }
+
+ if (town_save == TRUE) {
+ {
+ WriteFile(file_id, &c_town.town_num, 2, &dwByteRead, NULL);
+ WriteFile(file_id, &c_town.difficulty, 2, &dwByteRead, NULL);
+ WriteFile(file_id, &c_town.town, sizeof(town_record_type), &dwByteRead, NULL);
+ WriteFile(file_id, c_town.explored, 64 * 64, &dwByteRead, NULL);
+ WriteFile(file_id, &c_town.hostile, 1, &dwByteRead, NULL);
+ {
+ for (j = 0; j < 60; j++)
+ {
+ WriteFile(file_id, &c_town.monst.dudes[j].active, 2, &dwByteRead, NULL);
+ WriteFile(file_id, &c_town.monst.dudes[j].attitude, 2, &dwByteRead, NULL);
+ WriteFile(file_id, &c_town.monst.dudes[j].number, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &c_town.monst.dudes[j].m_loc.x, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &c_town.monst.dudes[j].m_loc.y, 1, &dwByteRead, NULL);
+ {
+ WriteFile(file_id, &c_town.monst.dudes[j].m_d.m_num, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &c_town.monst.dudes[j].m_d.level, 1, &dwByteRead, NULL);
+ WriteFile(file_id, c_town.monst.dudes[j].m_d.m_name, 26, &dwByteRead, NULL);
+ WriteFile(file_id, &c_town.monst.dudes[j].m_d.health, 2, &dwByteRead, NULL);
+ WriteFile(file_id, &c_town.monst.dudes[j].m_d.m_health, 2, &dwByteRead, NULL);
+ WriteFile(file_id, &c_town.monst.dudes[j].m_d.mp, 2, &dwByteRead, NULL);
+ WriteFile(file_id, &c_town.monst.dudes[j].m_d.max_mp, 2, &dwByteRead, NULL);
+ WriteFile(file_id, &c_town.monst.dudes[j].m_d.armor, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &c_town.monst.dudes[j].m_d.skill, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &c_town.monst.dudes[j].m_d.a, 2*3, &dwByteRead, NULL);
+ WriteFile(file_id, &c_town.monst.dudes[j].m_d.a1_type, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &c_town.monst.dudes[j].m_d.a23_type, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &c_town.monst.dudes[j].m_d.m_type, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &c_town.monst.dudes[j].m_d.speed, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &c_town.monst.dudes[j].m_d.ap, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &c_town.monst.dudes[j].m_d.mu, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &c_town.monst.dudes[j].m_d.cl, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &c_town.monst.dudes[j].m_d.breath, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &c_town.monst.dudes[j].m_d.breath_type, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &c_town.monst.dudes[j].m_d.treasure, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &c_town.monst.dudes[j].m_d.spec_skill, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &c_town.monst.dudes[j].m_d.poison, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &c_town.monst.dudes[j].m_d.morale, 2, &dwByteRead, NULL);
+ WriteFile(file_id, &c_town.monst.dudes[j].m_d.m_morale, 2, &dwByteRead, NULL);
+ WriteFile(file_id, &c_town.monst.dudes[j].m_d.corpse_item, 2, &dwByteRead, NULL);
+ WriteFile(file_id, &c_town.monst.dudes[j].m_d.corpse_item_chance, 2, &dwByteRead, NULL);
+ WriteFile(file_id, c_town.monst.dudes[j].m_d.status, 2*15, &dwByteRead, NULL);
+ WriteFile(file_id, &c_town.monst.dudes[j].m_d.direction, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &c_town.monst.dudes[j].m_d.immunities, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &c_town.monst.dudes[j].m_d.x_width, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &c_town.monst.dudes[j].m_d.y_width, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &c_town.monst.dudes[j].m_d.radiate_1, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &c_town.monst.dudes[j].m_d.radiate_2, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &c_town.monst.dudes[j].m_d.default_attitude, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &c_town.monst.dudes[j].m_d.summon_type, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &c_town.monst.dudes[j].m_d.default_facial_pic, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &c_town.monst.dudes[j].m_d.res1, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &c_town.monst.dudes[j].m_d.res2, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &c_town.monst.dudes[j].m_d.res3, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &c_town.monst.dudes[j].m_d.picture_num, 2, &dwByteRead, NULL);
+ }
+ WriteFile(file_id, &c_town.monst.dudes[j].mobile, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &c_town.monst.dudes[j].summoned, 2, &dwByteRead, NULL);
+ {
+ WriteFile(file_id, &c_town.monst.dudes[j].monst_start.number, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &c_town.monst.dudes[j].monst_start.start_attitude, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &c_town.monst.dudes[j].monst_start.start_loc.x, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &c_town.monst.dudes[j].monst_start.start_loc.y, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &c_town.monst.dudes[j].monst_start.mobile, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &c_town.monst.dudes[j].monst_start.time_flag, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &c_town.monst.dudes[j].monst_start.extra1, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &c_town.monst.dudes[j].monst_start.extra2, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &c_town.monst.dudes[j].monst_start.spec1, 2, &dwByteRead, NULL);
+ WriteFile(file_id, &c_town.monst.dudes[j].monst_start.spec2, 2, &dwByteRead, NULL);
+ WriteFile(file_id, &c_town.monst.dudes[j].monst_start.spec_enc_code, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &c_town.monst.dudes[j].monst_start.time_code, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &c_town.monst.dudes[j].monst_start.monster_time, 2, &dwByteRead, NULL);
+ WriteFile(file_id, &c_town.monst.dudes[j].monst_start.personality, 2, &dwByteRead, NULL);
+ WriteFile(file_id, &c_town.monst.dudes[j].monst_start.special_on_kill, 2, &dwByteRead, NULL);
+ WriteFile(file_id, &c_town.monst.dudes[j].monst_start.facial_pic, 2, &dwByteRead, NULL);
+ }
+ }
+ WriteFile(file_id, &c_town.monst.which_town, 2, &dwByteRead, NULL);
+ WriteFile(file_id, &c_town.monst.friendly, 2, &dwByteRead, NULL);
+ }
+
+ WriteFile(file_id, &c_town.in_boat, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &c_town.p_loc.x, 1, &dwByteRead, NULL);
+ WriteFile(file_id, &c_town.p_loc.y, 1, &dwByteRead, NULL);
+ }
+
+ if (WriteFile(file_id, &t_d, sizeof(big_tr_type), &bytes, NULL) == FALSE)
+ {
+ CloseHandle(file_id);
+ FCD(1069,0);
+ return;
+ }
+ if (WriteFile(file_id, &t_i, sizeof(stored_items_list_type), &bytes, NULL) == FALSE)
+ {
+ CloseHandle(file_id);
+ FCD(1069,0);
+ return;
+ }
+ }
+
+ // Save stored items
+ for (i = 0; i < 3; i++) {
+ if (WriteFile(file_id, &stored_items[i], sizeof(stored_items_list_type), &bytes, NULL) == FALSE)
+ {
+ CloseHandle(file_id);
+ FCD(1069,0);
+ return;
+ }
+ }
+
+ // If saving maps, save maps
+ if (save_maps == TRUE) {
+ if (WriteFile(file_id, &(town_maps), sizeof(stored_town_maps_type), &bytes, NULL) == FALSE)
+ {
+ CloseHandle(file_id);
+ FCD(1069,0);
+ return;
+ }
+
+ if (WriteFile(file_id, &o_maps, sizeof(stored_outdoor_maps_type), &bytes, NULL) == FALSE)
+ {
+ CloseHandle(file_id);
+ FCD(1069,0);
+ return;
+ }
+ }
+
+ // SAVE SFX and MISC_I
+ if (WriteFile(file_id, sfx, (64 * 64), &bytes, NULL) == FALSE)
+ {
+ CloseHandle(file_id);
+ return;
+ }
+ if (WriteFile(file_id, misc_i, (64 * 64), &bytes, NULL) == FALSE)
+ {
+ CloseHandle(file_id);
+ FCD(1069,0);
+ return;
+ }
+ }
+
+ CloseHandle(file_id);
+}
+
+
+void leave_town()
+{
+ store_flags[0] = 5790;
+}
+
+
+void remove_party_from_scen()
+{
+ store_flags[1] = 200;
+ party_in_scen = FALSE;
+}
+
+void get_reg_data()
+{
+ const int BUFFER_LEN = 64;
+ char buffer[BUFFER_LEN];
+ const char * iniFile = "./blades.ini";
+ const char * section = "Blades of Exile";
+
+ GetPrivateProfileString(section, "play_sounds", "1", buffer, BUFFER_LEN, iniFile);
+ play_sounds = (atoi(buffer))? TRUE : FALSE;
+}
+
+//Mac porting stuff
+
+void port_scenario(scenario_data_type *scenario)
+{
+ short i,j;
+
+ flip_short(&scenario->flag_a);
+ flip_short(&scenario->flag_b);
+ flip_short(&scenario->flag_c);
+ flip_short(&scenario->flag_d);
+ flip_short(&scenario->flag_e);
+ flip_short(&scenario->flag_f);
+ flip_short(&scenario->flag_g);
+ flip_short(&scenario->flag_h);
+ flip_short(&scenario->flag_i);
+ flip_short(&scenario->intro_mess_pic);
+ flip_short(&scenario->intro_mess_len);
+ flip_short(&scenario->which_town_start);
+ for (i = 0; i < 200; i++)
+ for (j = 0; j < 5; j++)
+ flip_short(&scenario->town_data_size[i][j]);
+ for (i = 0; i < 10; i++)
+ flip_short(&scenario->town_to_add_to[i]);
+ for (i = 0; i < 10; i++)
+ for (j = 0; j < 2; j++)
+ flip_short(&scenario->flag_to_add_to_town[i][j]);
+ for (i = 0; i < 100; i++)
+ for (j = 0; j < 2; j++)
+ flip_short(&scenario->out_data_size[i][j]);
+ for (i = 0; i < 3; i++)
+ flip_rect(&scenario->store_item_rects[i]);
+ for (i = 0; i < 3; i++)
+ flip_short(&scenario->store_item_towns[i]);
+ for (i = 0; i < 50; i++)
+ flip_short(&scenario->special_items[i]);
+ for (i = 0; i < 50; i++)
+ flip_short(&scenario->special_item_special[i]);
+ flip_short(&scenario->rating);
+ flip_short(&scenario->uses_custom_graphics);
+ for (i = 0; i < 256; i++) {
+ flip_short(&scenario->scen_monsters[i].health);
+ flip_short(&scenario->scen_monsters[i].m_health);
+ flip_short(&scenario->scen_monsters[i].max_mp);
+ flip_short(&scenario->scen_monsters[i].mp);
+ flip_short(&scenario->scen_monsters[i].a[1]);
+ flip_short(&scenario->scen_monsters[i].a[0]);
+ flip_short(&scenario->scen_monsters[i].a[2]);
+ flip_short(&scenario->scen_monsters[i].morale);
+ flip_short(&scenario->scen_monsters[i].m_morale);
+ flip_short(&scenario->scen_monsters[i].corpse_item);
+ flip_short(&scenario->scen_monsters[i].corpse_item_chance);
+ flip_short(&scenario->scen_monsters[i].picture_num);
+ }
+
+ for (i = 0; i < 256; i++) {
+ flip_short(&scenario->ter_types[i].picture);
+ }
+ for (i = 0; i < 30; i++) {
+ flip_short(&scenario->scen_boats[i].which_town);
+ }
+ for (i = 0; i < 30; i++) {
+ flip_short(&scenario->scen_horses[i].which_town);
+ }
+ for (i = 0; i < 20; i++)
+ flip_short(&scenario->scenario_timer_times[i]);
+ for (i = 0; i < 20; i++)
+ flip_short(&scenario->scenario_timer_specs[i]);
+ for (i = 0; i < 256; i++) {
+ flip_spec_node(&scenario->scen_specials[i]);
+ }
+ for (i = 0; i < 10; i++) {
+ flip_short(&scenario->storage_shortcuts[i].ter_type);
+ flip_short(&scenario->storage_shortcuts[i].property);
+ for (j = 0; j < 10; j++) {
+ flip_short(&scenario->storage_shortcuts[i].item_num[j]);
+ flip_short(&scenario->storage_shortcuts[i].item_odds[j]);
+ }
+ }
+ flip_short(&scenario->last_town_edited);
+}
+
+void flip_short(short *s)
+{
+ char store,*s1, *s2;
+
+ s1 = (char *) s;
+ s2 = s1 + 1;
+ store = *s1;
+ *s1 = *s2;
+ *s2 = store;
+}
+
+void flip_rect(RECT16 *s)
+{
+ short a;
+ flip_short((short *) &(s->top));
+ flip_short((short *) &(s->bottom));
+ flip_short((short *) &(s->left));
+ flip_short((short *) &(s->right));
+ a = s->top;
+ s->top = s->left;
+ s->left = a;
+ a = s->bottom;
+ s->bottom = s->right;
+ s->right = a;
+}
+
+void flip_spec_node(special_node_type *spec)
+{
+ flip_short(&(spec->type));
+ flip_short(&(spec->sd1));
+ flip_short(&(spec->sd2));
+ flip_short(&(spec->pic));
+ flip_short(&(spec->m1));
+ flip_short(&(spec->m2));
+ flip_short(&(spec->ex1a));
+ flip_short(&(spec->ex1b));
+ flip_short(&(spec->ex2a));
+ flip_short(&(spec->ex2b));
+ flip_short(&(spec->jumpto));
+}
+
+void port_item_list()
+{
+ short i;
+
+ for (i = 0; i < 400; i++) {
+ flip_short(&(scen_item_list.scen_items[i].variety));
+ flip_short(&(scen_item_list.scen_items[i].item_level));
+ flip_short(&(scen_item_list.scen_items[i].value));
+ }
+}
diff --git a/Win32/Blades of Exile Char Editor/edfileio.h b/Win32/Blades of Exile Char Editor/edfileio.h
new file mode 100644
index 00000000..e32f4534
--- /dev/null
+++ b/Win32/Blades of Exile Char Editor/edfileio.h
@@ -0,0 +1,14 @@
+void file_initialize();
+void save_file(short mode);
+void load_file();
+void leave_town();
+void get_reg_data();
+void remove_party_from_scen();
+void Get_Path(char* path);
+short load_items_list();
+void load_town_strings(short which_town);
+void port_scenario(scenario_data_type *scenario);
+void port_item_list();
+void flip_short(short *s);
+void flip_rect(RECT16 *s);
+void flip_spec_node(special_node_type *spec);
diff --git a/Win32/Blades of Exile Char Editor/editors.cpp b/Win32/Blades of Exile Char Editor/editors.cpp
new file mode 100644
index 00000000..6937e0cb
--- /dev/null
+++ b/Win32/Blades of Exile Char Editor/editors.cpp
@@ -0,0 +1,406 @@
+#include
+
+
+#include "graphics.h"
+#include "global.h"
+#include "editors.h"
+#include "dlogtool.h"
+
+/* Adventure globals */
+extern party_record_type party;
+extern pc_record_type adven[6];
+extern outdoor_record_type outdoors[2][2];
+extern current_town_type c_town;
+extern big_tr_type t_d;
+extern stored_items_list_type t_i;
+extern unsigned char out[96][96];
+extern unsigned char out_e[96][96];
+extern setup_save_type setup_save;
+extern stored_items_list_type stored_items[3];
+extern stored_town_maps_type maps;
+extern stored_outdoor_maps_type o_maps;
+extern short dialog_answer;
+
+extern short store_flags[3];
+extern Boolean dialog_not_toast;
+
+extern short current_active_pc;
+
+extern HWND mainPtr;
+extern short current_cursor;
+
+extern HCURSOR sword_curs;
+extern Boolean diff_depth_ok,current_file_has_maps;
+
+Boolean equippable[18] = {FALSE,TRUE,TRUE,FALSE,TRUE,TRUE,TRUE,FALSE,FALSE,TRUE,TRUE,TRUE,
+ TRUE,TRUE,TRUE,FALSE,FALSE,TRUE};
+short num_hands_to_use[18] = {0,1,2,0,1,1,1,0,0,1,1,0,0,0,0,0,0,0};
+short num_that_can_equip[18] = {0,2,1,0,1,1,1,0,0,2,1,1,1,2,1,0,0,1};
+short selected,item_max = 0;
+Boolean choice_active[6];
+
+
+
+extern short store_trait_mode;
+pc_record_type *store_pc;
+HBITMAP button_num_gworld;
+
+FARPROC dlog_proc1;
+HWND test_dlog3;
+short answer_given;
+HWND store_focus;
+extern HANDLE store_hInstance;
+
+void combine_things(short pc_num)
+{
+
+ short i,j,test;
+
+ for (i = 0; i < 24; i++) {
+ if ((adven[pc_num].items[i].variety > 0) &&
+ (adven[pc_num].items[i].type_flag > 0) && (adven[pc_num].items[i].item_properties & 254 != 0)) {
+ for (j = i + 1; j < 24; j++)
+ if ((adven[pc_num].items[j].variety > 0) &&
+ (adven[pc_num].items[j].type_flag == adven[pc_num].items[i].type_flag)
+ && (adven[pc_num].items[j].item_properties & 254 != 0)) {
+ test = (short) (adven[pc_num].items[i].charges) + (short) (adven[pc_num].items[j].charges);
+ if (test > 125) {
+ adven[pc_num].items[i].charges = 125;
+ }
+ else adven[pc_num].items[i].charges += adven[pc_num].items[j].charges;
+ if (adven[pc_num].equip[j] == TRUE) {
+ adven[pc_num].equip[i] = TRUE;
+ adven[pc_num].equip[j] = FALSE;
+ }
+ take_item(pc_num,j);
+ }
+ }
+ if ((adven[pc_num].items[i].variety > 0) && (adven[pc_num].items[i].charges < 0))
+ adven[pc_num].items[i].charges = 1;
+ }
+}
+
+Boolean give_to_pc(short pc_num,item_record_type item, short)
+{
+ short free_space;
+
+
+ if (item.variety == 0)
+ return TRUE;
+ if (((free_space = pc_has_space(pc_num)) == 24 ) || (adven[pc_num].main_status != 1))
+ return FALSE;
+ else {
+ adven[pc_num].items[free_space] = item;
+ combine_things(pc_num);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+Boolean give_to_party(item_record_type item,short print_result)
+{
+ short i = 0;
+
+ while (i < 6) {
+ if (give_to_pc(i,item,print_result) == TRUE)
+ return TRUE;
+ i++;
+ }
+ return FALSE;
+}
+
+void give_gold(short amount, Boolean)
+{
+ party.gold += amount;
+}
+
+Boolean take_gold(short amount,Boolean)
+{
+ if (party.gold < amount)
+ return FALSE;
+ party.gold -= amount;
+ return TRUE;
+}
+
+
+short pc_has_space(short pc_num)
+{
+ short i = 0;
+
+ while (i < 24) {
+ if (adven[pc_num].items[i].variety == 0)
+ return i;
+ i++;
+ }
+ return 24;
+}
+
+
+void take_item(short pc_num,short which_item)
+//short pc_num,which_item; // if which_item > 20, don't update stat win, item is which_item - 20
+{
+ short i;
+
+
+ if ((adven[pc_num].weap_poisoned == which_item) && (adven[pc_num].status[0] > 0)) {
+// add_string_to_buf(" Poison lost. ");
+ adven[pc_num].status[0] = 0;
+ }
+ if ((adven[pc_num].weap_poisoned > which_item) && (adven[pc_num].status[0] > 0))
+ adven[pc_num].weap_poisoned--;
+
+ for (i = which_item; i < 23; i++) {
+ adven[pc_num].items[i] = adven[pc_num].items[i + 1];
+ adven[pc_num].equip[i] = adven[pc_num].equip[i + 1];
+ }
+ adven[pc_num].items[23].variety = 0;
+ adven[pc_num].equip[23] = FALSE;
+
+}
+
+
+void fancy_choice_dialog_event_filter (short item_hit)
+{
+ dialog_not_toast = FALSE;
+ dialog_answer = item_hit;
+}
+
+short fancy_choice_dialog(short which_dlog,short parent)
+// ignore parent in Mac version
+{
+ short i,store_dialog_answer;
+
+
+ store_dialog_answer = dialog_answer;
+ make_cursor_sword();
+
+ cd_create_dialog_parent_num(which_dlog,parent);
+
+
+ while (dialog_not_toast)
+ ModalDialog();
+
+ cd_kill_dialog(which_dlog,0);
+
+ i = dialog_answer;
+ dialog_answer = store_dialog_answer;
+
+ return i;
+}
+
+void select_pc_event_filter (short item_hit)
+{
+ dialog_not_toast = FALSE;
+ if (item_hit == 16)
+ dialog_answer = 6;
+ else dialog_answer = item_hit - 3;
+}
+
+short char_select_pc(short active_only,short free_inv_only,char *title)
+//active_only; // 0 - no 1 - yes 2 - disarm trap
+{
+ short i;
+
+ make_cursor_sword();
+
+ cd_create_dialog(1018,mainPtr);
+
+ if (active_only == 2)
+ csit(1018,15,"Select PC to disarm trap:");
+ else csit( 1018,15,title);
+
+ for (i = 0; i < 6; i++) {
+ if ((adven[i].main_status == 0) ||
+ ((active_only == TRUE) && (adven[i].main_status > 1)) ||
+ ((free_inv_only == 1) && (pc_has_space(i) == 24)) || (adven[i].main_status == 5)) {
+ cd_activate_item(1018, 3 + i, 0);
+ }
+ if (adven[i].main_status != 0) {
+ csit(1018,9 + i,adven[i].name);
+ }
+ else cd_activate_item(1018, 9 + i, 0);
+ }
+
+ while (dialog_not_toast)
+ ModalDialog();
+
+ cd_kill_dialog(1018,0);
+
+ return dialog_answer;
+}
+
+short select_pc(short active_only,short free_inv_only)
+//active_only; // 0 - no 1 - yes 2 - disarm trap
+{
+ if (active_only == 2)
+ return char_select_pc(active_only,free_inv_only,"Trap! Who will disarm?");
+ else return char_select_pc(active_only,free_inv_only,"Select a character:");
+}
+
+
+BOOL CALLBACK choice_dialog_proc
+ (HWND hDlg, UINT message, WPARAM wParam, LPARAM) {
+
+
+
+
+
+
+ test_dlog3 = hDlg;
+
+ switch (message) {
+ case WM_INITDIALOG:
+ center_window(hDlg);
+
+ return TRUE;
+ case WM_PAINT:
+
+ return FALSE;
+
+ case WM_COMMAND:
+ answer_given = (short) LOWORD(wParam);
+ if (answer_given == 100)
+ answer_given = 2;
+ EndDialog(hDlg, 0);
+ return TRUE;
+ }
+ return FALSE;
+ }
+
+short choice_dialog(short,short num)
+{
+
+
+ store_focus = GetFocus();
+ dlog_proc1 = (FARPROC) choice_dialog_proc;
+ if (dlog_proc1 == NULL) {
+ return 1;
+ }
+ DialogBox((HINSTANCE) store_hInstance, MAKEINTRESOURCE(num), store_focus, (DLGPROC) dlog_proc1);
+
+ DestroyWindow(test_dlog3);
+ SetFocus(store_focus);
+ return answer_given;
+}
+
+
+
+short party_total_level()
+{
+ short i,j = 0;
+
+ for (i = 0; i < 6; i++)
+ if (adven[i].main_status == 1)
+ j += adven[i].level;
+ return j;
+}
+
+
+
+short luck_total()
+{
+ short i = 0;
+
+ for (i = 0; i < 6; i++)
+ if (adven[i].main_status == 1)
+ i += adven[i].skills[18];
+ return i;
+}
+
+void display_traits_graphics()
+{
+ short i,store;
+
+ for (i = 0; i < 3; i++) {
+ cd_set_led(1013,4 + i,(store_pc->race == i) ? 1 : 0);
+ }
+ for (i = 0; i < 10; i++) {
+ cd_set_led(1013,7 + i,(store_pc->traits[i] > 0) ? 1 : 0);
+ }
+ for (i = 0; i < 5; i++) {
+ cd_set_led(1013,36 + i,(store_pc->traits[10 + i] > 0) ? 1 : 0);
+ }
+
+ store = get_tnl(store_pc);
+ cdsin(1013,18,store);
+}
+
+void pick_race_abil_event_filter(short item_hit)
+{
+ char abil_str[256];
+ pc_record_type *pc;
+
+ pc = store_pc;
+ switch (item_hit) {
+ case 3:
+ dialog_not_toast = FALSE;
+ break;
+ case 4: case 5: case 6:
+ if (store_trait_mode == 0)
+ pc->race = item_hit - 4;
+ display_traits_graphics();
+ get_str(abil_str,5,12 + item_hit);
+ csit(1013,19,(char *) abil_str);
+ break;
+ case 36: case 37: case 38: case 39: case 40:
+ if (store_trait_mode != 1)
+ pc->traits[item_hit - 36 + 10] = (pc->traits[item_hit - 36 + 10] == TRUE) ? FALSE : TRUE;
+ display_traits_graphics();
+ get_str(abil_str,5,item_hit - 36 + 11);
+ csit(1013,19,(char *) abil_str);
+ break;
+ default:
+ if (item_hit >= 100)
+ return;
+ if (store_trait_mode != 1)
+ pc->traits[item_hit - 7] = (pc->traits[item_hit - 7] == TRUE) ? FALSE : TRUE;
+ display_traits_graphics();
+ get_str(abil_str,5,item_hit - 6);
+ csit(1013,19,(char *) abil_str);
+ break;
+ }
+
+}
+
+void pick_race_abil(pc_record_type *pc,short mode,short parent_num)
+//mode; // 0 - edit 1 - just display 2 - can't change race
+{
+ char *start_str1 = "Click on advantage button for description.";
+ char *start_str2 = "Click on advantage button to add/lose.";
+
+
+ mode = 0;
+ store_trait_mode = mode;
+ store_pc = pc;
+ make_cursor_sword();
+
+ cd_create_dialog_parent_num(1013,parent_num);
+
+ display_traits_graphics();
+ if (mode == 1)
+ csit(1013,19,start_str1);
+ else csit(1013,19,start_str2);
+
+ while (dialog_not_toast)
+ ModalDialog();
+
+ cd_kill_dialog(1013,0);
+ dialog_not_toast = TRUE;
+}
+
+
+short get_tnl(pc_record_type *pc)
+{
+ short tnl = 100,i,store_per = 100;
+ short rp[3] = {0,12,20};
+ short ap[15] = {10,20,8,10,4, 6,10,7,12,15, -10,-8,-8,-20,-8};
+
+ tnl = (tnl * (100 + rp[pc->race])) / 100;
+ for (i = 0; i < 15; i++)
+ if (pc->traits[i] == TRUE)
+ store_per = store_per + ap[i];
+
+ tnl = (tnl * store_per) / 100;
+
+ return tnl;
+}
diff --git a/Win32/Blades of Exile Char Editor/editors.h b/Win32/Blades of Exile Char Editor/editors.h
new file mode 100644
index 00000000..8561e4d7
--- /dev/null
+++ b/Win32/Blades of Exile Char Editor/editors.h
@@ -0,0 +1,22 @@
+Boolean give_to_pc(short pc_num,item_record_type item, short print_result);
+Boolean give_to_party(item_record_type item,short print_result);
+void give_gold(short amount,Boolean print_result);
+Boolean take_gold(short amount,Boolean print_result);
+short pc_has_space(short pc_num);
+void take_item(short pc_num,short which_item);
+void fancy_choice_dialog_event_filter (short item_hit);
+short fancy_choice_dialog(short which_dlog,short parent);
+void select_pc_event_filter (short item_hit);
+short char_select_pc(short active_only,short free_inv_only,char *title);
+short select_pc(short active_only,short free_inv_only);
+short choice_dialog(short pic,short num);
+Boolean give_spec_items_event_filter (short item_hit);
+void give_spec_items();
+short party_total_level();
+short luck_total();
+void display_traits_graphics();
+void pick_race_abil_event_filter(short item_hit);
+void pick_race_abil(pc_record_type *pc,short mode,short parent_num);
+short get_tnl(pc_record_type *pc);
+void reset_boats();
+void combine_things(short pc_num);
diff --git a/Win32/Blades of Exile Char Editor/edsound.cpp b/Win32/Blades of Exile Char Editor/edsound.cpp
new file mode 100644
index 00000000..38805622
--- /dev/null
+++ b/Win32/Blades of Exile Char Editor/edsound.cpp
@@ -0,0 +1,313 @@
+#include "math.h"
+#include
+#include
+
+#include "stdio.h"
+
+#include "global.h"
+#include "edsound.h"
+
+#define NUM_SOUNDS 100
+
+HGLOBAL sound_handles[NUM_SOUNDS];
+char * snds[NUM_SOUNDS];
+
+extern HINSTANCE store_hInstance;
+
+extern Boolean play_sounds,in_startup_mode;
+extern HWND mainPtr;
+extern Boolean gInBackground;
+extern party_record_type party;
+extern Boolean cat,cow,chicken,dog,sheep,monsters_going;
+extern short num_chirps_played,overall_mode;
+
+short last_played = 10000;
+short error_beeps = 0;
+short store_last_sound_played = 0;
+
+Boolean always_asynch[100] = {FALSE,FALSE,FALSE,FALSE,FALSE,
+ TRUE,TRUE,FALSE,FALSE,FALSE,
+ TRUE,FALSE,FALSE,FALSE,FALSE, // 10
+ FALSE,FALSE,FALSE,FALSE,FALSE,
+ FALSE,FALSE,TRUE,FALSE,TRUE, // 20
+ TRUE,FALSE,FALSE,FALSE,FALSE,
+ FALSE,FALSE,FALSE,FALSE,TRUE, // 30
+ FALSE,FALSE,TRUE,FALSE,TRUE,
+ FALSE,TRUE,TRUE,TRUE,TRUE, // 40
+ TRUE,TRUE,TRUE,TRUE,TRUE,
+ TRUE,FALSE,FALSE,TRUE,FALSE, // 50
+ TRUE,FALSE,FALSE,FALSE,FALSE,
+ FALSE,TRUE,FALSE,FALSE,FALSE, // 60
+ FALSE,FALSE,FALSE,FALSE,FALSE,
+ FALSE,FALSE,FALSE,FALSE,FALSE, // 70
+ FALSE,TRUE,TRUE,TRUE,TRUE,
+ TRUE,TRUE,TRUE,TRUE,FALSE, // 80
+ TRUE,FALSE,FALSE,FALSE,FALSE,
+ FALSE,TRUE,FALSE,FALSE,FALSE, // 90
+ FALSE,FALSE,FALSE,FALSE,FALSE};
+Boolean load_when_play[100] = {
+0,0,1,1,1,0,0,1,1,1,
+0,0,0,1,0,1,1,1,1,1,
+1,1,0,1,1,1,1,0,1,1,
+1,1,1,1,0,1,1,0,1,1,
+1,1,1,1,1,1,1,0,0,0,
+0,1,1,0,1,0,1,1,1,1, // 50
+1,0,1,1,1,1,1,1,1,0,
+0,0,0,0,0,0,0,0,0,0, // 70
+1,1,1,1,1,0,0,0,0,0,
+1,0,1,1,1,1,1,1,1,0
+};
+
+short can_ignore[100] = {
+0,0,0,0,0,5,3,0,0,0,
+5,5,5,0,5,0,0,0,0,0,
+0,0,5,0,0,0,0,0,0,2,
+2,2,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,1,1,1,
+1,0,0,5,0,1,0,0,0,0, // 50
+0,0,0,0,5,0,0,0,0,0,
+0,0,0,0,0, 0,5,5,5,5, // 70
+4,4,4,4,0,0,0,0,0,0,
+0,5,5,0,0,0,0,0,0,0};
+// 1 - polite asych, 1 or 2 or 3- lose easily when pref is set for fewer snds
+// 3 can be async
+// 4 - nostop asynch ... when 4, this sound is NOSTOP, i.e. when played, is played
+// asynch, and refuses all other sounds. Sounds that come in are ignored, and
+// disappear into the ether
+// 5 - finally, bold asynch ... when 5, this sound is NOSTOP, i.e. when played, is played
+// asynch, and refuses all other sounds. When a sound is played on top of this, game
+// hangs on until sound is done, and then and only then plays later sound.
+
+
+short num_devs;
+Boolean sounds_fucked = FALSE;
+long intro_music_start_time = -1;
+
+void load_sounds ()
+{
+ short i,t,err;
+ HRSRC h;
+ char snd_name[20];
+ WAVEOUTCAPS wavecaps;
+
+ t = waveOutGetNumDevs();
+ if (t == 0) {
+ sounds_fucked = TRUE;
+ return;
+ }
+ err = waveOutGetDevCaps(0,&wavecaps,sizeof(WAVEOUTCAPS));
+if (err != 0) {
+ sounds_fucked = TRUE;
+ switch (err) {
+ case MMSYSERR_BADDEVICEID:
+ MessageBox(mainPtr,"Cannot initialize sounds - No sound device detected. Game can still be played, but quietly.",
+ "Sound Error",MB_OK | MB_ICONEXCLAMATION);
+ return;
+ case MMSYSERR_NODRIVER:
+ MessageBox(mainPtr,"Cannot initialize sounds - No driver installed. Game can still be played, but quietly.",
+ "Sound Error",MB_OK | MB_ICONEXCLAMATION);
+ return;
+ case MMSYSERR_NOMEM :
+ MessageBox(mainPtr,"Cannot initialize sounds - can't find enough memory. Game can still be played, but quietly.",
+ "Sound Error",MB_OK | MB_ICONEXCLAMATION);
+ return;
+ case MMSYSERR_ALLOCATED:
+ MessageBox(mainPtr,"Cannot initialize sounds - sound card already allocated. Game can still be played, but quietly.",
+ "Sound Error",MB_OK | MB_ICONEXCLAMATION);
+ return;
+ case MMSYSERR_ERROR:
+ MessageBox(mainPtr,"Cannot initialize sounds - internal error. Game can still be played, but quietly.",
+ "Sound Error",MB_OK | MB_ICONEXCLAMATION);
+ return;
+ default:
+ MessageBox(mainPtr,"Cannot initialize sounds - unidentified error. Game can still be played, but quietly.",
+ "Sound Error",MB_OK | MB_ICONEXCLAMATION);
+ return;
+
+ }
+
+ }
+
+ for (i = 0; i < NUM_SOUNDS; i++) {
+ sound_handles[i] = NULL;
+ load_when_play[i] = TRUE;
+ if (load_when_play[i] == FALSE) {
+ sprintf((char *)snd_name,"#%d",i + 1);
+ h = FindResource(store_hInstance,snd_name,"#100");
+
+ sound_handles[i] = LoadResource(store_hInstance,h);
+ snds[i] = (char*) LockResource(sound_handles[i]);
+ }
+ }
+
+}
+
+void play_sound(short which) // if < 0, play asynch
+{
+ if (PSD[304][9] > 0)
+ return;
+ if (in_startup_mode == TRUE) {
+ // put some in foreground check here
+ }
+ if (play_sounds == TRUE)
+ force_play_sound(which);
+}
+
+
+void force_play_sound(short which)
+{
+ short i,num_fails = 0;
+ char snd_name[30];
+ Boolean asyn = FALSE,a_sound_did_get_played = FALSE;
+ Boolean check_sound;
+ HRSRC h;
+
+ if ((sounds_fucked == TRUE) || (play_sounds == FALSE))
+ return;
+ if (which < 0) {
+ asyn = TRUE;
+ which = which * -1;
+ }
+
+ if (which >= 100)
+ return;
+
+ if ((always_asynch[which] == TRUE) &&
+ ((can_ignore[which] == 1) || (can_ignore[which] >= 3)))
+ asyn = TRUE;
+ if ((can_ignore[which] > 0) && (can_ignore[which] < 5) && (party.stuff_done[305][5] == 1))
+ return;
+ if ((can_ignore[which] != 1) && (can_ignore[which] < 3))
+ asyn = FALSE;
+ if ((party.stuff_done[305][5] == 1) && (can_ignore[which] < 5))
+ asyn = FALSE;
+
+ if ((load_when_play[which] == TRUE) && (sound_handles[which] == NULL)) {
+ asyn = FALSE;
+ sprintf((char *)snd_name,"#%d",which + 1);
+ h = FindResource(store_hInstance,snd_name,"#100");
+
+ sound_handles[which] = LoadResource(store_hInstance,h);
+ snds[which] = (char*) LockResource(sound_handles[which]);
+
+ }
+
+ if (store_last_sound_played == 6) {
+ sndPlaySound(NULL,0);
+ }
+
+ if (asyn == TRUE) {
+ if (can_ignore[which] >= 4)
+ check_sound = sndPlaySound(snds[which],SND_ASYNC | SND_MEMORY | SND_NOSTOP);
+ else check_sound = sndPlaySound(snds[which],SND_ASYNC | SND_MEMORY);
+
+ while (check_sound == FALSE) {
+
+ if (can_ignore[store_last_sound_played] == 4) {// then sound goes away
+ return;
+ }
+
+
+ num_fails++;
+ if (num_fails < 40)
+ sound_pause(25);
+ else {
+ MessageBox(mainPtr,"Cannot play sounds - Sounds stuck error a. Game can still be played, but quietly.",
+ "Sound Error",MB_OK | MB_ICONEXCLAMATION);
+ //print_nums(111,which,num_fails);
+ //sounds_fucked = TRUE;
+ return;
+ }
+ //ASB ("Asynch clearing buffer!!!");
+ //check_sound = sndPlaySound(snds[99],SND_SYNC | SND_MEMORY);
+ sndPlaySound(NULL,0);
+
+ if (can_ignore[which] >= 4)
+ check_sound = sndPlaySound(snds[which],SND_ASYNC | SND_MEMORY | SND_NOSTOP);
+ else check_sound = sndPlaySound(snds[which],SND_ASYNC | SND_MEMORY);
+ }
+ a_sound_did_get_played = TRUE;
+ }
+ else {
+ if (can_ignore[which] >= 4)
+ check_sound = sndPlaySound(snds[which],SND_SYNC | SND_MEMORY | SND_NOSTOP);
+ else check_sound = sndPlaySound(snds[which],SND_SYNC | SND_MEMORY);
+ while (check_sound == FALSE) {
+ if (can_ignore[store_last_sound_played] == 4) {// then sound goes away
+ //ASB("Sound overruled by asynch sound.");
+ return;
+ }
+
+
+ num_fails++;
+ if (num_fails < 40)
+ sound_pause(25);
+ else {
+ MessageBox(mainPtr,"Cannot play sounds - Sounds stuck error b. Game can still be played, but quietly.",
+ "Sound Error",MB_OK | MB_ICONEXCLAMATION);
+ //print_nums(222,which,num_fails);
+ //sounds_fucked = TRUE;
+ return;
+ }
+ //ASB ("Asynch clearing buffer!!!");
+ //check_sound = sndPlaySound(snds[99],SND_SYNC | SND_MEMORY);
+ sndPlaySound(NULL,0);
+
+ if (can_ignore[which] >= 4)
+ check_sound = sndPlaySound(snds[which],SND_SYNC | SND_MEMORY | SND_NOSTOP);
+ else check_sound = sndPlaySound(snds[which],SND_SYNC | SND_MEMORY);
+ }
+ a_sound_did_get_played = TRUE;
+ }
+
+ store_last_sound_played = which;
+
+ if ((load_when_play[which] == TRUE) && (asyn == FALSE)) {
+ // deleted a seemingly extraneous LoadResource here
+
+
+ sound_handles[which] = NULL;
+ }
+ for (i = 0; i < NUM_SOUNDS; i++)
+ if ((load_when_play[which] == TRUE) && (sound_handles[which] != NULL)
+ && (a_sound_did_get_played == TRUE) && (i != which)){
+ // deleted a seemingly extraneous LoadResource here
+
+
+ sound_handles[i] = NULL;
+ }
+
+}
+
+void kill_sound()
+{
+ sndPlaySound(NULL,0);
+}
+void one_sound(short which)
+{
+ if (which == last_played)
+ return;
+ play_sound(which);
+ last_played = which;
+}
+
+void clear_sound_memory()
+{
+ last_played = 100;
+}
+
+void flip_sound()
+{
+ play_sounds = (play_sounds == TRUE) ? FALSE : TRUE;
+}
+
+
+void sound_pause(long len) {
+ long t1,t2;
+
+ t1 = (long) GetCurrentTime();
+ t2 = t1;
+ while (t2 - t1 < len) {
+ t2 = (long)GetCurrentTime();
+ }
+}
diff --git a/Win32/Blades of Exile Char Editor/edsound.h b/Win32/Blades of Exile Char Editor/edsound.h
new file mode 100644
index 00000000..3629f07e
--- /dev/null
+++ b/Win32/Blades of Exile Char Editor/edsound.h
@@ -0,0 +1,7 @@
+void load_sounds ();
+void play_sound(short which) ; // if < 0, play asynch
+void force_play_sound(short which);
+void one_sound(short which);
+void clear_sound_memory();
+void sound_pause(long len);
+void flip_sound();
diff --git a/Win32/Blades of Exile Char Editor/global.cpp b/Win32/Blades of Exile Char Editor/global.cpp
new file mode 100644
index 00000000..c4aeb49d
--- /dev/null
+++ b/Win32/Blades of Exile Char Editor/global.cpp
@@ -0,0 +1,151 @@
+#include
+#include "global.h"
+#include "math.h"
+#include
+
+extern short give_delays;
+
+RECT RECT16::rect32()
+{
+ RECT tmp;
+ tmp.left = left;
+ tmp.top = top;
+ tmp.right = right;
+ tmp.bottom = bottom;
+ return tmp;
+}
+
+RECT16::RECT16 (const RECT & tmp)
+{
+ left = tmp.left;
+ top = tmp.top;
+ right = tmp.right;
+ bottom = tmp.bottom;
+}
+
+RECT16 & RECT16::operator=(const RECT & tmp)
+{
+ left = tmp.left;
+ top = tmp.top;
+ right = tmp.right;
+ bottom = tmp.bottom;
+ return (*this);
+}
+
+POINT MAKEPOINT(LONG lParam)
+{
+ POINT point;
+
+ point.x = LOWORD(lParam);
+ point.y = HIWORD(lParam);
+
+ return point;
+}
+
+short get_ran (short times,short min,short max)
+{
+ short store;
+ short i, to_ret = 0;
+
+ if ((max - min + 1) == 0)
+ return 0;
+ for (i = 1; i < times + 1; i++) {
+ store = rand() % (max - min + 1);
+ to_ret = to_ret + min + store;
+ }
+ return to_ret;
+}
+
+Boolean same_point(location p1,location p2)
+{
+ if ((p1.x == p2.x) & (p1.y == p2.y))
+ return TRUE;
+ else return FALSE;
+}
+
+short move_to_zero(short val)
+{
+ if (val < 0)
+ return val + 1;
+ if (val > 0)
+ return val - 1;
+ return val;
+}
+
+/*
+short max(short a,short b)
+{
+ if (a > b)
+ return a;
+ else return b;
+}
+
+short min(short a,short b)
+{
+ if (a < b)
+ return a;
+ else return b;
+}*/
+
+short minmax(short min,short max,short k)
+{
+ if (k < min)
+ return min;
+ if (k > max)
+ return max;
+ return k;
+}
+
+short s_pow(short x,short y)
+{
+ return (short) pow((double) x, (double) y);
+}
+
+short a_v(short x)
+{
+ if (x < 0)
+ return (-1 * x);
+ else return x;
+}
+short ex_abs(short x)
+{
+ if (x < 0)
+ return (-1 * x);
+ else return x;
+}
+
+void Delay(short val,long *)
+{
+ long then,now,wait_val;
+
+ wait_val = (long) val;
+ wait_val = wait_val * 16;
+ then = (long)GetCurrentTime();
+ now = then;
+ while (now - then < wait_val) {
+ now = (long) GetCurrentTime();
+ }
+}
+
+void pause(short length)
+{
+ long dummy,len;
+
+ len = (long) length;
+
+ if (give_delays == 0)
+ Delay(len, &dummy);
+}
+
+void beep()
+{
+ long dummy;
+
+ MessageBeep(MB_OK);
+ Delay(30,&dummy);
+ }
+
+void SysBeep(short)
+{
+ MessageBeep(MB_OK);
+}
diff --git a/Win32/Blades of Exile Char Editor/global.h b/Win32/Blades of Exile Char Editor/global.h
new file mode 100644
index 00000000..6ddaf17a
--- /dev/null
+++ b/Win32/Blades of Exile Char Editor/global.h
@@ -0,0 +1,441 @@
+
+#define T_M 60
+
+#define NUM_TOWN_ITEMS 115
+
+#define SLEEP_TICKS 0L
+#define MOUSE_REGION 0L
+#define DRAG_EDGE 15
+
+#define DISPLAY_LEFT 23
+#define DISPLAY_TOP 23
+#define BITMAP_WIDTH 28
+#define BITMAP_HEIGHT 36
+
+#define STORED_GRAPHICS 240
+
+#define PC_WIN_UL_X 291
+#define PC_WIN_UL_Y 5
+#define ITEM_WIN_UL_X 291
+#define ITEM_WIN_UL_Y 130
+#define TEXT_WIN_UL_X 291
+#define TEXT_WIN_UL_Y 283
+#define NUM_BUTTONS 15
+#define PSD party.stuff_done
+#define DES display_enc_string
+#define FCD fancy_choice_dialog
+#define D2ES display_2_enc_string
+#define NUM_MONST_G 173
+
+#define DOOR_LIGHT can_enter = run_trap(7,&PSD[c_town.town_num][which],4220,0); break;
+#define DOOR_HEAVY can_enter = run_trap(7,&PSD[c_town.town_num][which],4220,20); break;
+#define DOOR_ALARM can_enter = run_trap(7,&PSD[c_town.town_num][which],4220,11); break;
+#define DRESSER_LIGHT can_enter = run_trap(7,&PSD[c_town.town_num][which],4221,0); break;
+#define DRESSER_HEAVY can_enter = run_trap(7,&PSD[c_town.town_num][which],4221,20); break;
+#define DRESSER_ALARM can_enter = run_trap(7,&PSD[c_town.town_num][which],4221,11); break;
+#define FLOOR_LIGHT can_enter = run_trap(7,&PSD[c_town.town_num][which],4222,0); break;
+#define FLOOR_HEAVY can_enter = run_trap(7,&PSD[c_town.town_num][which],4222,20); break;
+#define FLOOR_ALARM can_enter = run_trap(7,&PSD[c_town.town_num][which],4222,11); break;
+#define CHEST_LIGHT can_enter = run_trap(7,&PSD[c_town.town_num][which],3450,0); break;
+#define CHEST_HEAVY can_enter = run_trap(7,&PSD[c_town.town_num][which],3450,20); break;
+#define CHEST_ALARM can_enter = run_trap(7,&PSD[c_town.town_num][which],3450,11); break;
+
+#define CDGT cd_retrieve_text_edit_str
+#define CDGN cd_retrieve_text_edit_num
+#define CDST cd_set_text_edit_str
+#define CDSN cd_set_text_edit_num
+
+#define huge
+
+struct RECT16
+{
+ short left;
+ short top;
+ short right;
+ short bottom;
+
+ RECT rect32();
+ RECT16 () {}
+ RECT16 (const RECT & );
+ RECT16 & operator=(const RECT &);
+};
+
+extern POINT MAKEPOINT(LONG lparam);
+
+typedef unsigned char BYTE;
+typedef char Boolean;
+
+typedef struct {
+ char x,y;
+ } location;
+typedef struct {
+ short x,y;} shortloc;
+
+typedef struct {
+ short type,sd1,sd2,pic,m1,m2,ex1a,ex1b,ex2a,ex2b,jumpto;
+ } special_node_type;
+
+typedef struct {
+ short personality,type;
+ char link1[4],link2[4];
+ short extras[4];
+ } talking_node_type;
+
+typedef struct {
+ unsigned char strlens[200];
+ talking_node_type talk_nodes[60];
+ } talking_record_type;
+
+typedef struct {
+ short picture;
+ unsigned char blockage,flag1,flag2,special,trans_to_what,fly_over,boat_over;
+ unsigned char block_horse,light_radius,step_sound,shortcut_key,res1,res2,res3;
+ } terrain_type_type;
+
+typedef struct {
+ unsigned char monst[4];
+ } wandering_type;
+
+typedef struct {
+ unsigned char monst[7];
+ unsigned char friendly[3];
+ short spec_on_meet,spec_on_win,spec_on_flee,cant_flee;
+ short end_spec1,end_spec2;
+} out_wandering_type;
+
+typedef struct {
+ unsigned char terrain[48][48];
+ location special_locs[18];
+ unsigned char special_id[18];
+ location exit_locs[8];
+ char exit_dests[8];
+ location sign_locs[8];
+ out_wandering_type wandering[4],special_enc[4];
+ location wandering_locs[4];
+ RECT16 info_rect[8];
+ unsigned char strlens[180];
+ special_node_type specials[60];
+ } outdoor_record_type;
+
+typedef struct {
+ unsigned char number;
+ unsigned char start_attitude;
+ location start_loc;
+ unsigned char mobile;
+ unsigned char time_flag;
+ unsigned char extra1,extra2;
+ short spec1, spec2;
+ char spec_enc_code,time_code;
+ short monster_time,personality;
+ short special_on_kill,facial_pic;
+
+ } creature_start_type;
+
+
+typedef struct {
+ short variety, item_level;
+ char awkward, bonus, protection, charges, type, magic_use_type;
+ unsigned char graphic_num,ability, ability_strength,type_flag, is_special,a;
+ short value;
+ unsigned char weight, special_class;
+ location item_loc;
+ char full_name[25], name[15];
+ unsigned char treas_class,item_properties,reserved1,reserved2;
+} item_record_type;
+
+typedef struct {
+ location item_loc;
+ short item_code,ability;
+ unsigned char charges,always_there,property,contained;
+ } preset_item_type;
+
+typedef struct {
+ location field_loc;
+ short field_type;
+ } preset_field_type;
+
+typedef struct {
+ short town_chop_time,town_chop_key;
+ wandering_type wandering[4];
+ location wandering_locs[4];
+ location special_locs[50];
+ unsigned char spec_id[50];
+ location sign_locs[15];
+ short lighting;
+ location start_locs[4];
+ location exit_locs[4];
+ short exit_specs[4];
+ RECT16 in_town_rect;
+ preset_item_type preset_items[64];
+ short max_num_monst;
+ preset_field_type preset_fields[50];
+ short spec_on_entry,spec_on_entry_if_dead;
+ short timer_spec_times[8];
+ short timer_specs[8];
+ unsigned char strlens[180];
+ special_node_type specials[100];
+ unsigned char specials1,specials2,res1,res2;
+ short difficulty;
+ } town_record_type;
+
+
+
+typedef struct {
+ unsigned char terrain[64][64];
+ RECT16 room_rect[16];
+ creature_start_type creatures[60];
+ unsigned char lighting[8][64];
+ } big_tr_type;
+
+typedef struct {
+ unsigned char terrain[48][48];
+ RECT16 room_rect[16];
+ creature_start_type creatures[40];
+ unsigned char lighting[6][48];
+ } ave_tr_type;
+
+typedef struct {
+ unsigned char terrain[32][32];
+ RECT16 room_rect[16];
+ creature_start_type creatures[30];
+ unsigned char lighting[4][32];
+ } tiny_tr_type;
+
+typedef struct {
+ short block_type;
+ short block_destroy_time;
+ char block_alignment;
+ char block_key_time;
+ location block_loc;
+ } city_block_type;
+
+typedef struct {
+ RECT16 what_rect;
+ unsigned char ter_type;
+ unsigned char hollow;
+ } city_ter_rect_type;
+
+typedef struct {
+ creature_start_type creatures[30];
+ city_block_type city_block[15];
+ city_ter_rect_type city_ter_rect[10];
+ } template_town_type;
+
+typedef struct {
+ item_record_type scen_items[400];
+ char monst_names[256][20];
+ char ter_names[256][30];
+ } scen_item_data_type;
+
+typedef struct {
+ short ter_type,item_num[10],item_odds[10],property;
+ } item_storage_shortcut_type;
+
+typedef struct {
+ unsigned char m_num,level,m_name[26];
+ short health,m_health,mp,max_mp;
+ unsigned char armor,skill;
+ short a[3];
+ unsigned char a1_type,a23_type,m_type,speed,ap,mu,cl,breath,breath_type,treasure,spec_skill,poison;
+ short morale,m_morale;
+ short corpse_item,corpse_item_chance;
+ short status[15];
+ unsigned char direction,immunities,x_width,y_width,radiate_1,radiate_2;
+ unsigned char default_attitude,summon_type,default_facial_pic,res1,res2,res3;
+ short picture_num;
+
+ } monster_record_type;
+
+typedef struct {
+ short active,attitude;
+ unsigned char number;
+ location m_loc;
+ monster_record_type m_d;
+ Boolean mobile;
+ short summoned;
+ creature_start_type monst_start;
+ } creature_data_type;
+
+
+typedef struct {
+ location horse_loc,horse_loc_in_sec,horse_sector;
+ short which_town;
+ Boolean exists,property;
+ } horse_record_type;
+typedef struct {
+ location boat_loc,boat_loc_in_sec,boat_sector;
+ short which_town;
+ Boolean exists,property;
+} boat_record_type;
+
+typedef struct {
+ unsigned char flag1, flag2, flag3, flag4;
+ unsigned char ver[3],min_run_ver,prog_make_ver[3],num_towns;
+ unsigned char out_width,out_height,difficulty,intro_pic,default_ground;
+ } scen_header_type;
+
+ typedef struct {
+ unsigned char flag1, flag2, flag3, flag4;
+ unsigned char ver[3],min_run_ver,prog_make_ver[3],num_towns;
+ unsigned char out_width,out_height,difficulty,intro_pic,default_ground;
+ unsigned char town_size[200];
+ unsigned char town_hidden[200],a;
+ short flag_a;
+ short intro_mess_pic,intro_mess_len;
+ location where_start,out_sec_start,out_start;
+ short which_town_start;
+ short flag_b;
+ short town_data_size[200][5];
+ short town_to_add_to[10];
+ short flag_to_add_to_town[10][2];
+ short flag_c;
+ short out_data_size[100][2];
+ RECT16 store_item_rects[3];
+ short store_item_towns[3];
+ short flag_e;
+ short special_items[50];
+ short special_item_special[50];
+ short rating,uses_custom_graphics;
+ short flag_f;
+ monster_record_type scen_monsters[256];
+ boat_record_type scen_boats[30];
+ horse_record_type scen_horses[30];
+ short flag_g;
+ terrain_type_type ter_types[256];
+ short scenario_timer_times[20];
+ short scenario_timer_specs[20];
+ short flag_h;
+ special_node_type scen_specials[256];
+ item_storage_shortcut_type storage_shortcuts[10];
+ short flag_d;
+ unsigned char scen_str_len[300];
+ short flag_i;
+ location last_out_edited;
+ short last_town_edited;
+
+ } scenario_data_type;
+
+// for game
+typedef struct {
+ short personality;
+ short town_num;
+ short str1,str2;
+ } talk_save_type;
+
+typedef struct {
+ creature_data_type dudes[60];
+ short which_town;
+ short friendly;
+ } creature_list_type;
+
+typedef struct {
+ short town_num, difficulty;
+ town_record_type town;
+ char explored[64][64];
+ Boolean hostile;
+ creature_list_type monst;
+ Boolean in_boat;
+ location p_loc;
+ } current_town_type;
+
+typedef struct {
+ Boolean exists;
+ short direction;
+ out_wandering_type what_monst;
+ location which_sector,m_loc;
+ } outdoor_creature_type;
+
+typedef struct {
+ long age;
+ short gold,food;
+ unsigned char stuff_done[310][10],item_taken[200][8];
+ short light_level;
+ location outdoor_corner,i_w_c,p_loc,loc_in_sec;
+ boat_record_type boats[30];
+ horse_record_type horses[30];
+ creature_list_type creature_save[4];
+ short in_boat,in_horse;
+ outdoor_creature_type out_c[10];
+ item_record_type magic_store_items[5][10];
+ short imprisoned_monst[4];
+ char m_seen[256];
+ char journal_str[50];
+ short journal_day[50];
+ short special_notes_str[140][2];
+ talk_save_type talk_save[120];
+ short direction,at_which_save_slot;
+ char alchemy[20];
+ Boolean can_find_town[200];
+ short key_times[100];
+ short party_event_timers[30];
+ short global_or_town[30];
+ short node_to_call[30];
+ char spec_items[50],help_received[120];
+ short m_killed[200];
+ long total_m_killed,total_dam_done,total_xp_gained,total_dam_taken;
+ char scen_name[256];
+ } party_record_type;
+
+typedef struct { char town_maps[200][8][64];} stored_town_maps_type;
+typedef struct {
+ char town_strs[180][256];
+ } piles_of_stuff_dumping_type;
+typedef struct {
+ char scen_header_strs[25][3][80];
+ char scen_names[25][256];
+ scen_item_data_type scen_item_list;
+ } piles_of_stuff_dumping_type2;
+typedef struct {
+ char talk_strs[170][256];
+ } piles_of_stuff_dumping_type3;
+typedef struct {
+ char out_strs[9][256];
+ } outdoor_strs_type;
+typedef struct {
+ outdoor_strs_type outdoor_text[2][2];
+ } piles_of_stuff_dumping_type4;
+typedef struct {
+char scen_strs[160][256];
+ } piles_of_stuff_dumping_type5;
+
+typedef struct {
+ short main_status;
+ char name[20];
+ short skills[30];
+ short max_health,cur_health,max_sp,cur_sp,experience,skill_pts,level;
+ short status[15];
+ item_record_type items[24];
+ Boolean equip[24];
+ Boolean priest_spells[62],mage_spells[62];
+ short which_graphic,weap_poisoned;
+ Boolean advan[15],traits[15];
+ short race,exp_adj,direction;
+ } pc_record_type;
+
+typedef struct {
+ unsigned char setup[4][64][64];
+ } setup_save_type;
+
+typedef struct {unsigned char pattern[9][9];} effect_pat_type;
+
+typedef struct {
+ item_record_type items[NUM_TOWN_ITEMS];
+ } stored_items_list_type;
+
+typedef struct {
+ char outdoor_maps[100][6][48];
+ } stored_outdoor_maps_type;
+
+short s_pow(short x,short y);
+short a_v(short x);
+short ex_abs(short x);
+short get_ran (short times,short min,short max);
+Boolean same_point(location p1,location p2);
+void pause(short length);
+short minmax(short min,short max,short k);
+/*short min(short a,short b);
+short max(short a,short b);*/
+short move_to_zero(short val);
+void Delay(short val,long *dummy);
+void alter_rect(RECT *r) ;
+Boolean sd_legit(short a, short b);
diff --git a/Win32/Blades of Exile Char Editor/graphics.cpp b/Win32/Blades of Exile Char Editor/graphics.cpp
new file mode 100644
index 00000000..9fe2d885
--- /dev/null
+++ b/Win32/Blades of Exile Char Editor/graphics.cpp
@@ -0,0 +1,1034 @@
+#include
+
+#include "stdio.h"
+#include "string.h"
+#include "global.h"
+#include "graphics.h"
+#include "edsound.h"
+#include "dlogtool.h"
+#include "graphutl.h"
+
+
+extern short store_size;
+
+/* Adventure globals */
+extern party_record_type party;
+extern pc_record_type adven[6];
+extern outdoor_record_type outdoors[2][2];
+extern current_town_type c_town;
+extern big_tr_type t_d;
+extern stored_items_list_type t_i;
+extern unsigned char out[96][96];
+extern unsigned char out_e[96][96];
+extern setup_save_type setup_save;
+extern stored_items_list_type stored_items[3];
+extern stored_town_maps_type maps;
+extern stored_outdoor_maps_type o_maps;
+
+extern HWND mainPtr;
+extern Boolean play_sounds,file_in_mem;
+
+extern short store_flags[3];
+extern HBITMAP button_num_gworld;
+extern short current_active_pc,ulx,uly;
+extern Boolean dialog_not_toast,party_in_scen;
+extern char town_strs[180][256];
+
+extern HFONT font,italic_font,underline_font,bold_font,tiny_font,small_bold_font;
+extern HCURSOR arrow_curs[3][3], sword_curs, boot_curs, key_curs, target_curs,talk_curs,look_curs;
+//extern HPALETTE hpal;
+extern HDC main_dc,main_dc2,main_dc3;
+HBITMAP title_gworld,pc_gworld,dlogpics_gworld,buttons_gworld;
+HBITMAP dlg_buttons_gworld,mixed_gworld,dialog_pattern_gworld,pattern_gworld;
+RECT whole_win_rect;
+ RECT title_from = {41,0,380,70};
+extern RECT pc_area_buttons[6][4] ; // 0 - whole 1 - pic 2 - name 3 - stat strs 4,5 - later
+extern RECT item_string_rects[24][4]; // 0 - name 1 - drop 2 - id 3 -
+extern RECT pc_info_rect; // Frame that holds a pc's basic info and items
+extern RECT name_rect;
+extern RECT pc_race_rect;
+extern RECT info_area_rect;
+extern RECT hp_sp_rect;
+extern RECT skill_rect;
+extern RECT pc_skills_rect[19];
+extern RECT status_rect;
+extern RECT pc_status_rect[10];
+extern RECT traits_rect;
+extern RECT pc_traits_rect[16];
+extern RECT edit_rect[5][2];
+extern HINSTANCE store_hInstance;
+
+short store_str1a;
+short store_str1b;
+short store_str2a;
+short store_str2b;
+short store_which_string_dlog;
+short store_page_on,store_num_i;
+ RECT frame_rect = {0,0,605,440};
+RECT ed_buttons_from[2] = {{0,0,57,57},{57,0,114,57}};
+short current_pressed_button = -1;
+
+void init_main_buttons()
+{
+
+ short i;
+
+ short indent = 0, indent2 = 0;
+ RECT base_rect;
+ RECT active_area_rect = {0,0,590,440};
+
+
+ GetClientRect(mainPtr,&whole_win_rect);
+ ulx = (whole_win_rect.right - 600) / 2;
+ uly = (whole_win_rect.bottom - 440) / 2;
+
+ pc_info_rect= active_area_rect;
+ InflateRect(&pc_info_rect,-100,-100);
+ pc_info_rect.bottom+=52;
+ pc_info_rect.top-=25;
+ pc_info_rect.right+=5;
+ name_rect.left = pc_info_rect.left;
+ name_rect.right = pc_info_rect.left + 100;
+ name_rect.bottom = pc_info_rect.top + 15;
+ name_rect.top = pc_info_rect.top;
+
+ //Initialize pc_area_buttons
+ pc_area_buttons[0][0].top=pc_info_rect.top;
+ pc_area_buttons[0][0].bottom=pc_area_buttons[0][0].top + 57 ;
+
+ for(i = 0; i < 6; i++)
+ {
+ pc_area_buttons[i][0].left = 20;
+ pc_area_buttons[i][0].right = pc_area_buttons[0][0].left + 57;
+ pc_area_buttons[i][2].left = 20;
+ pc_area_buttons[i][2].right = pc_area_buttons[i][2].left + 56;
+ pc_area_buttons[i][3].left = 20;
+ pc_area_buttons[i][3].right = pc_area_buttons[i][3].left + 56;
+ pc_area_buttons[i][1].left = 34;
+ pc_area_buttons[i][1].right = pc_area_buttons[i][1].left + 28;
+
+ pc_area_buttons[i][0].top = pc_area_buttons[0][0].top + 60*i;
+ pc_area_buttons[i][0].bottom = pc_area_buttons[0][0].bottom + 60*i;
+
+ pc_area_buttons[i][1].top = pc_area_buttons[i][0].top+3;
+ pc_area_buttons[i][1].bottom = pc_area_buttons[i][2].top = pc_area_buttons[i][0].bottom - 18;
+ pc_area_buttons[i][2].bottom = pc_area_buttons[i][3].top = pc_area_buttons[i][0].bottom - 9;
+ pc_area_buttons[i][3].bottom = pc_area_buttons[i][0].bottom;
+ OffsetRect(&pc_area_buttons[i][2],0,4);
+ OffsetRect(&pc_area_buttons[i][3],0,-2);
+ }
+
+ //Initialize the edit_rect buttons
+ edit_rect[0][0].top = pc_info_rect.top;
+ for(i = 0; i < 5; i++) {
+ if(i >= 2)
+ indent = 7;
+ else
+ indent = 0;
+ if( i == 4)
+ indent2 = 1;
+ edit_rect[i][0].top = edit_rect[0][0].top + 66*i;
+ edit_rect[i][0].bottom = edit_rect[i][0].top + 53;
+ edit_rect[i][0].left = 510;
+ edit_rect[i][0].right = edit_rect[i][0].left + 53;
+ edit_rect[i][1].top = edit_rect[i][0].top + 7 + indent;
+ edit_rect[i][1].bottom = edit_rect[i][0].bottom - 11 - indent;
+ edit_rect[i][1].right = edit_rect[i][0].right - 8 +indent2;
+ edit_rect[i][1].left = edit_rect[i][0].left + 10 + indent2;
+ }
+
+ //Initialize pc_race_rect
+ pc_race_rect.top = pc_info_rect.top;
+ pc_race_rect.bottom = name_rect.bottom;
+ pc_race_rect.left = name_rect.right;
+ pc_race_rect.right = pc_info_rect.left + (pc_info_rect.right - pc_info_rect.left)/2;
+
+ //initialize info_area_rect
+ info_area_rect.top = pc_info_rect.top;
+ info_area_rect.left = pc_info_rect.left;
+ info_area_rect.right = pc_race_rect.right;
+ info_area_rect.bottom = pc_info_rect.bottom;
+
+ // Initialize hp_sp_rect
+ hp_sp_rect.top = name_rect.bottom + 1;
+ hp_sp_rect.left = pc_info_rect.left + 1;
+ hp_sp_rect.right = pc_race_rect.right - 30;
+ hp_sp_rect.bottom = hp_sp_rect.top + 12;
+ for (i = 0; i < 6; i++) {
+ pc_area_buttons[i][3].left = hp_sp_rect.right - 32;
+ pc_area_buttons[i][3].right = pc_area_buttons[i][3].left + 77;
+ pc_area_buttons[i][3].top = hp_sp_rect.top + 1;
+ pc_area_buttons[i][3].bottom = hp_sp_rect.bottom + 1;
+ }
+
+ // Initialize skill_rect
+ skill_rect.top = hp_sp_rect.bottom + 2;
+ skill_rect.left = pc_info_rect.left + 1;
+ skill_rect.right = pc_race_rect.right;
+ skill_rect.bottom = skill_rect.top + 12;
+
+ //Initialize skills_rect
+ base_rect.top = skill_rect.bottom + 1;
+ base_rect.left = skill_rect.left + 1;
+ base_rect.right = name_rect.right - 1;
+ base_rect.bottom = base_rect.top + (pc_info_rect.bottom - skill_rect.bottom)/30;
+
+ for (i = 0; i < 19; i++) {
+ pc_skills_rect[i] = base_rect;
+ OffsetRect(&pc_skills_rect[i], (i / 10) * ((name_rect.right)-(name_rect.left)), (i % 10) * (pc_info_rect.bottom - name_rect.bottom)/30);
+ }
+
+ //Initialize status_rect
+ status_rect.top = pc_skills_rect[9].bottom + 5;
+ status_rect.left = pc_info_rect.left + 1;
+ status_rect.right = pc_race_rect.right;
+ status_rect.bottom = status_rect.top + 12;
+ //Initialize pc_status_rect
+ base_rect.top = status_rect.bottom + 1;
+ base_rect.left = status_rect.left + 1;
+ base_rect.right = name_rect.right - 1;
+ base_rect.bottom = base_rect.top + (pc_info_rect.bottom - status_rect.bottom)/15;
+ for (i = 0; i < 10; i++) {
+ pc_status_rect[i] = base_rect;
+ OffsetRect(&pc_status_rect[i], (i / 5) * ((name_rect.right)-(name_rect.left)), (i % 5) * (pc_info_rect.bottom - status_rect.bottom)/15);
+ }
+ //Initialize traits_rect
+ traits_rect.top = pc_status_rect[4].bottom + 5;
+ traits_rect.left = pc_info_rect.left + 1;
+ traits_rect.right = pc_race_rect.right;
+ traits_rect.bottom = traits_rect.top + 12;
+ //Initialize pc_traits_rect
+ base_rect.top = traits_rect.bottom - 1;
+ base_rect.left = traits_rect.left + 1;
+ base_rect.right = name_rect.right - 1;
+ base_rect.bottom = base_rect.top + 10;
+ for (i = 0; i < 16; i++) {
+ pc_traits_rect[i] = base_rect;
+ OffsetRect(&pc_traits_rect[i], (i / 7) * ((name_rect.right)-(name_rect.left)), (i % 7) * 10);
+ }
+
+
+ item_string_rects[0][0].top = pc_info_rect.top + 3;
+ item_string_rects[0][0].left = pc_info_rect.left + (pc_info_rect.right - pc_info_rect.left)/2;
+ item_string_rects[0][0].right = pc_info_rect.right;
+ item_string_rects[0][0].bottom = item_string_rects[0][0].top + 12;
+ for (i = 1; i < 24; i++) {
+ item_string_rects[i][0] = item_string_rects[0][0];
+ OffsetRect(&item_string_rects[i][0],0,13 * i);
+ }
+ for (i = 0; i < 24; i++) {
+ item_string_rects[i][1] = item_string_rects[i][0];
+ item_string_rects[i][1].right -= 14;
+ item_string_rects[i][1].left = item_string_rects[i][1].right - 14;
+ item_string_rects[i][2] = item_string_rects[i][0];
+ item_string_rects[i][2].left = item_string_rects[i][2].right - 14;
+ }
+ for (i = 0; i < 24; i++) {
+ item_string_rects[i][0].left += 2;
+ item_string_rects[i][0].bottom++;
+ }
+
+ name_rect.left -= 2;
+ pc_info_rect.left -= 2;
+ info_area_rect.left -= 2;
+
+}
+
+void Set_up_win ()
+{
+
+
+ main_dc = GetDC(mainPtr);
+
+ dlg_buttons_gworld = load_pict(2000,main_dc);
+ title_gworld = load_pict(5000,main_dc);
+ //SelectPalette(main_dc,hpal,0);
+ SelectObject(main_dc,font);
+ SetBkMode(main_dc,TRANSPARENT);
+ main_dc2 = CreateCompatibleDC(main_dc);
+ SetMapMode(main_dc2,GetMapMode((HDC) mainPtr));
+ //SelectPalette(main_dc2,hpal,0);
+ main_dc3 = CreateCompatibleDC(main_dc);
+ SetMapMode(main_dc3,GetMapMode((HDC) mainPtr));
+ //SelectPalette(main_dc3,hpal,0);
+
+ mixed_gworld = load_pict(903,main_dc);
+
+ pc_gworld = load_pict(902,main_dc);
+ dlogpics_gworld = load_pict(850,main_dc);
+
+ buttons_gworld = load_pict(5001,main_dc);
+ pattern_gworld = CreateCompatibleBitmap(main_dc,192,256);
+ dialog_pattern_gworld = CreateCompatibleBitmap(main_dc,192,256);
+}
+
+void lose_graphics()
+{
+ DeleteObject(title_gworld);
+ DeleteObject(pc_gworld);
+ DeleteObject(mixed_gworld);
+ DeleteObject(dlogpics_gworld);
+ DeleteObject(dlg_buttons_gworld);
+ DeleteObject(pattern_gworld);
+ DeleteObject(dialog_pattern_gworld);
+ //DeleteObject(hpal);
+ DeleteDC(main_dc);
+ DeleteDC(main_dc2);
+ DeleteDC(main_dc3);
+ DeleteObject(font);
+ DeleteObject(underline_font);
+ DeleteObject(italic_font);
+ DeleteObject(bold_font);
+
+ DeleteObject(sword_curs);
+}
+
+void redraw_screen()
+{
+ draw_main_screen();
+ display_party(6,1);
+ draw_items(1);
+}
+
+void draw_main_screen()
+{
+ RECT source_rect, dest_rec,dest_rect;
+ RECT reg_rect;
+ RECT top_pic_from = {3,16,41,54};
+
+
+ paint_pattern(NULL,3,whole_win_rect,3);
+
+ dest_rec = source_rect = title_from;
+ OffsetRect(&dest_rec,20,6);
+
+ rect_draw_some_item (title_gworld,source_rect, title_gworld,dest_rec, 1,1);
+ dest_rec = top_pic_from;
+ OffsetRect(&dest_rec,20,6);
+ rect_draw_some_item (title_gworld,top_pic_from, title_gworld,dest_rec, 0,1);
+
+ dest_rect = dest_rec;
+ dest_rect.top = dest_rect.bottom;
+ dest_rect.bottom = dest_rect.top + 50;
+ dest_rect.right += 40;
+ dest_rect.left -=5;
+ SelectObject(main_dc,bold_font);
+ char_win_draw_string(main_dc,dest_rect,"Your party:",0,10);
+
+ dest_rec = whole_win_rect;
+ InflateRect(&dest_rec,-10,-10);
+
+ if ((ulx >= 5) && (uly >= 5) &&
+ (whole_win_rect.right - 30 > frame_rect.right))
+ frame_dlog_rect(mainPtr,frame_rect,0);
+
+ frame_dlog_rect(mainPtr,pc_info_rect,0); // draw the frame
+
+ dest_rect = pc_area_buttons[5][0];
+ dest_rect.right = whole_win_rect.right - 30; //What is this for? Commenting it out has no effect.
+ dest_rect.left += 60;
+ OffsetRect(&dest_rect,0,21);
+ if (file_in_mem == TRUE)
+ char_win_draw_string(main_dc,dest_rect,"Click on character to edit it.",0,10);
+ else char_win_draw_string(main_dc,dest_rect,"Select Open from File menu.",0,10);
+ OffsetRect(&dest_rect,0,12);
+ if (file_in_mem == TRUE)
+ char_win_draw_string(main_dc,dest_rect,"Press 'I' button to identify item, and 'D' button to drop item.",0,10);
+ OffsetRect(&dest_rect,0,16);
+ if (file_in_mem == TRUE)
+ char_win_draw_string(main_dc,dest_rect,"Back up save file before editing it!",0,10);
+ OffsetRect(&dest_rect,275,0);
+ char_win_draw_string(main_dc,dest_rect,"Released under the GNU GPL, Version 2",0,10);
+
+ reg_rect.right = pc_info_rect.right + 100;
+ reg_rect.left = reg_rect.right - 170;
+ reg_rect.top = pc_info_rect.top - 70;
+ reg_rect.bottom = pc_info_rect.top;
+
+}
+
+void do_button_action(short,short which_button)
+{
+ long dummy;
+
+ current_pressed_button = which_button;
+ display_party(6,0);
+ play_sound(34);
+ Delay(10,&dummy);
+ current_pressed_button = -1;
+ display_party(6,0);
+}
+
+
+//extern Rect pc_area_buttons[6][6] ; // 0 - whole 1 - pic 2 - name 3 - stat strs 4,5 - later
+//extern Rect item_string_rects[24][4]; // 0 - name 1 - drop 2 - id 3 -
+void draw_items(short clear_first)
+//short clear_first; // 0 - redraw over, 1 - don't redraw over
+{
+ short i;
+ char to_draw[256];
+ RECT d_from = {28,12,42,24},i_from = {42,12,56,24};
+
+ if (file_in_mem == FALSE)
+ return;
+
+// dest_rect = item_string_rects[0][0];
+// dest_rect.bottom += 3;
+// OffsetRect(&dest_rect,0,-14);
+
+ if (clear_first == 1) {
+ for (i = 0; i < 24; i++)
+ paint_pattern(NULL,1,item_string_rects[i][0],3);
+// paint_pattern(NULL,1,dest_rect,3);
+ }
+
+ // frame_dlog_rect(mainPtr,frame_rect,0);
+ if (adven[current_active_pc].main_status != 1){
+ frame_dlog_rect(mainPtr,pc_info_rect,0); // re draw entire frame
+ frame_dlog_rect(mainPtr,info_area_rect,0); // draw the frame
+ frame_dlog_rect(mainPtr,pc_race_rect,0); // draw the frame
+ return; // If PC is dead, it has no items
+ }
+ for (i = 0; i < 24; i++) // Loop through items and draw each
+ if (adven[current_active_pc].items[i].variety > 0) { // i.e. does item exist
+ sprintf((char *) to_draw, "");
+ if (adven[current_active_pc].items[i].item_properties % 2 == 0)
+ sprintf((char *) to_draw, "%d. %s ",i + 1,adven[current_active_pc].items[i].name);
+ else if (adven[current_active_pc].items[i].charges > 0)
+ sprintf((char *) to_draw, "%d. %s (%d)",i + 1,adven[current_active_pc].items[i].full_name,
+ adven[current_active_pc].items[i].charges);
+ else sprintf((char *) to_draw, "%d. %s ",i + 1,adven[current_active_pc].items[i].full_name);
+
+ char_win_draw_string(main_dc,item_string_rects[i][0],(char *) to_draw,0,10);
+
+ //Draw id/drop buttons
+ rect_draw_some_item(mixed_gworld,d_from,mixed_gworld,item_string_rects[i][1],1,1);
+ rect_draw_some_item(mixed_gworld,i_from,mixed_gworld,item_string_rects[i][2],1,1);
+ }
+ frame_dlog_rect(mainPtr,pc_info_rect,0); // re draw entire frame
+ frame_dlog_rect(mainPtr,name_rect,0); // draw the frame
+ frame_dlog_rect(mainPtr,pc_race_rect,0); // draw the frame
+ frame_dlog_rect(mainPtr,info_area_rect,0); // draw the frame
+
+}
+
+void display_party(short,short clear_first)
+//short mode; // 0 - 5 this pc, 6 - all
+//short clear_first; // 0 - redraw over, 1 - don't redraw over
+{
+ short i;
+ char to_draw[256],skill_value[256];
+
+ RECT from_base = {0,0,28,36},from_rect;
+ COLORREF colors[4] = {RGB(0,0,0),RGB(255,0,0),RGB(0,0,102),RGB(255,255,255)};
+ //UINT c[4];
+
+
+ short k,string_num, cur_rect=0;
+ RECT no_party_rect,temp_rect;
+
+ /*c[0] = GetNearestPaletteIndex(hpal,colors[0]);
+ c[1] = GetNearestPaletteIndex(hpal,colors[1]);
+ c[2] = GetNearestPaletteIndex(hpal,colors[2]);
+ c[3] = GetNearestPaletteIndex(hpal,colors[3]);*/
+ if (clear_first == 1) { // first erase what's already there
+ for (i = 0; i < 6; i++)
+ paint_pattern(NULL,1,pc_area_buttons[i][0],3);
+ paint_pattern(NULL,1,name_rect,3);
+ paint_pattern(NULL,1,pc_race_rect,3);
+ paint_pattern(NULL,1,info_area_rect,3);
+ frame_dlog_rect(mainPtr,pc_info_rect,0); // re-draw the frame
+ }
+
+
+ SelectObject(main_dc,bold_font);
+ if (file_in_mem == FALSE) {
+ no_party_rect=pc_info_rect;
+ no_party_rect.top+=5;
+ no_party_rect.left+=5;
+ char_win_draw_string(main_dc,no_party_rect,"No party loaded.",0,10);
+ }
+ else {
+
+ char buffer[256];
+
+ from_rect = title_from; //draw gold, food and day variables
+ from_rect.top = from_rect.bottom-10;
+ from_rect.left += 57;
+ from_rect.right += 300;
+ if(party_in_scen == FALSE)
+ sprintf(buffer,"Food: %d Gold: %d Day: %ld",party.food,party.gold,(party.age/3700)+1);
+ else{
+ if(store_flags[0] == 5790)
+ sprintf(buffer,"Food: %d Gold: %d Day: %ld Party is outdoor",party.food,party.gold,(party.age/3700)+1);
+ else
+ sprintf(buffer,"Food: %d Gold: %d Day: %ld Party in %s",party.food,party.gold,(party.age/3700)+1,town_strs[0]);
+ }
+ char_win_draw_string(main_dc,from_rect,buffer,0,10);
+
+ /* from_rect = title_from; //town variable
+ from_rect.top = from_rect.bottom - 10;
+ from_rect.left += 300;
+ from_rect.right = from_rect.left + 300;
+ if(store_flags[0] == 5790)
+ sprintf(buffer,"Party is outdoor");
+ else
+ sprintf(buffer,"In Town : %s ",town_strs[0]);
+ char_win_draw_string(main_dc,from_rect,buffer,0,10);*/
+
+ from_rect = title_from;
+ from_rect.bottom += 385;
+ from_rect.top = from_rect.bottom - 14;
+ from_rect.left -= 40;
+ from_rect.right = from_rect.left + 604;
+ if (party_in_scen == FALSE)
+ char_win_draw_string(main_dc,from_rect," Party not in a scenario.",0,10);
+ else {
+ char buf[256];
+ sprintf(buf," Party is in : %s.",party.scen_name);
+ char_win_draw_string(main_dc,from_rect,buf,0,10);
+ }
+ from_rect.left -= 1;
+ from_rect.top -= 1;
+ frame_dlog_rect(mainPtr,from_rect,0);
+
+ for (i = 0; i < 6; i++) {
+ if (i == current_active_pc)
+ SetTextColor(main_dc,colors[1]);
+ else SetTextColor(main_dc,colors[0]);
+
+ from_rect = (current_pressed_button == i) ? ed_buttons_from[1] : ed_buttons_from[0];
+
+ if ((current_pressed_button < 0) || (current_pressed_button == i))
+ rect_draw_some_item(buttons_gworld,from_rect,buttons_gworld,pc_area_buttons[i][0],0,1);
+ SetTextColor(main_dc,colors[0]);
+
+ // pc_record_type adven[6] is the records that contains characters
+ // main_status determins 0 - not exist, 1 - alive, OK, 2 - dead, 3 - stoned, 4 - dust
+ if (adven[i].main_status != 0) { // PC exists?
+ from_rect = from_base;
+ // draw PC graphic
+ OffsetRect(&from_rect,56 * (adven[i].which_graphic / 8),36 * (adven[i].which_graphic % 8));
+ rect_draw_some_item(pc_gworld,from_rect,pc_gworld,pc_area_buttons[i][1],0,1);
+ frame_dlog_rect(mainPtr,pc_area_buttons[i][1],0); // re-draw the frame
+
+ //frame_dlog_rect((GrafPtr) mainPtr,pc_area_buttons[i][1],0);
+ // draw name
+ //TextSize(9);
+ if( (strlen(adven[i].name)) >= 0) {
+ //TextFace(0);
+ SelectObject(main_dc,font);
+ sprintf((char *) to_draw, "%-s", (char *) adven[i].name);
+ //TextSize(6);
+ }
+ else {
+ sprintf((char *) to_draw, "%-s", (char *) adven[i].name);
+ }
+
+ if (i == current_active_pc)
+ SetTextColor(main_dc,colors[1]);
+ else SetTextColor(main_dc,colors[3]);
+ win_draw_string(main_dc,pc_area_buttons[i][2],to_draw,1,10);
+ SelectObject(main_dc,bold_font);
+
+
+ if (i == current_active_pc){
+ sprintf((char *) to_draw, "%-.18s ", (char *) adven[i].name);
+ if( (strlen(adven[i].name)) > 12)
+ SelectObject(main_dc,font);
+ SetTextColor(main_dc,colors[0]);
+ win_draw_string(main_dc,name_rect,to_draw,1,10);
+ SelectObject(main_dc,bold_font);
+ }
+ if ((current_pressed_button < 0) || (current_pressed_button == i))
+ switch (adven[i].main_status) {
+ // draw statistics
+ case 1:
+ if (i == current_active_pc) {
+ //Draw in race
+ if (adven[i].race == 0)
+ char_win_draw_string(main_dc,pc_race_rect,"Human ",1,10);
+ if (adven[i].race == 1)
+ char_win_draw_string(main_dc,pc_race_rect,"Nephilim ",1,10);
+ if (adven[i].race == 2)
+ char_win_draw_string(main_dc,pc_race_rect,"Slithzerikai ",1,10);
+ // Draw in skills
+
+ sprintf((char *) to_draw, "Skills:");
+ win_draw_string(main_dc,skill_rect,to_draw,0,10);
+ sprintf((char *) to_draw, "Hp: %d/%d Sp: %d/%d",adven[i].cur_health,adven[i].max_health,adven[i].cur_sp,
+ adven[i].max_sp);
+ win_draw_string(main_dc,hp_sp_rect,to_draw,0,10);
+
+
+ SelectObject(main_dc,font);
+ string_num=1;
+ for( k = 0; k < 19 ; ++k)
+ {
+ temp_rect = pc_skills_rect[k];
+ temp_rect.left = pc_skills_rect[k].left + ((k < 10) ? 90 : 83);
+
+ get_str(to_draw,9,string_num);
+ win_draw_string(main_dc,pc_skills_rect[k],to_draw,0,9);
+
+ sprintf((char *) skill_value,"%d",adven[i].skills[k]);
+ OffsetRect(&temp_rect,-8,0);
+ temp_rect.right += 10;
+ win_draw_string(main_dc,temp_rect,skill_value,0,9);
+ //frame_dlog_rect((GrafPtr) mainPtr,pc_skills_rect[k],0);
+ string_num+=2;
+ }
+ //end skills
+
+ //Write in pc Status
+ SelectObject(main_dc,bold_font);
+ sprintf((char *) to_draw, "Status:");
+ win_draw_string(main_dc,status_rect,to_draw,0,10);
+
+ SelectObject(main_dc,font);
+ //for(k = 0 ; k < 10; k++)
+ //frame_dlog_rect((GrafPtr) mainPtr,pc_status_rect[k],0);
+ if (adven[i].status[0] > 0)
+ if(cur_rect <= 9) {
+ char_win_draw_string(main_dc,pc_status_rect[cur_rect],"Poisoned Weap.",0,9);
+ cur_rect++;
+ }
+ if (adven[i].status[1] > 0)
+ if(cur_rect <= 9) {
+ char_win_draw_string(main_dc,pc_status_rect[cur_rect],"Blessed",0,9);
+ cur_rect++;
+ }
+ else if(adven[i].status[1] < 0)
+ if(cur_rect <= 9) {
+ char_win_draw_string(main_dc,pc_status_rect[cur_rect],"Cursed",0,9);
+ cur_rect++;
+ }
+ if (adven[i].status[2] > 0)
+ if(cur_rect <= 9) {
+ char_win_draw_string(main_dc,pc_status_rect[cur_rect],"Poisoned",0,9);
+ cur_rect++;
+ }
+ if (adven[i].status[3] > 0)
+ if(cur_rect <= 9) {
+ char_win_draw_string(main_dc,pc_status_rect[cur_rect],"Hasted",0,9);
+ cur_rect++;
+ }
+ else if(adven[i].status[3] < 0)
+ if(cur_rect <= 9) {
+ char_win_draw_string(main_dc,pc_status_rect[cur_rect],"Slowed",0,9);
+ cur_rect++;
+ }
+ if (adven[i].status[4] > 0)
+ if(cur_rect <= 9) {
+ char_win_draw_string(main_dc,pc_status_rect[cur_rect],"Invulnerable",0,9);
+ cur_rect++;
+ }
+ if (adven[i].status[5] > 0)
+ if(cur_rect <= 9) {
+ char_win_draw_string(main_dc,pc_status_rect[cur_rect],"Magic Resistant",0,9);
+ cur_rect++;
+ }
+ if (adven[i].status[6] > 0)
+ if(cur_rect <= 9) {
+ char_win_draw_string(main_dc,pc_status_rect[cur_rect],"Webbed",0,9);
+ cur_rect++;
+ }
+ if (adven[i].status[7] > 0)
+ if(cur_rect <= 9) {
+ char_win_draw_string(main_dc,pc_status_rect[cur_rect],"Diseased",0,9);
+ cur_rect++;
+ }
+ if (adven[i].status[8] > 0)
+ if(cur_rect <= 9) {
+ char_win_draw_string(main_dc,pc_status_rect[cur_rect],"Sanctury",0,9);
+ cur_rect++;
+ }
+ if (adven[i].status[9] > 0)
+ if(cur_rect <= 9) {
+ char_win_draw_string(main_dc,pc_status_rect[cur_rect],"Dumbfounded",0,9);
+ cur_rect++;
+ }
+ if (adven[i].status[10] > 0)
+ if(cur_rect <= 9) {
+ char_win_draw_string(main_dc,pc_status_rect[cur_rect],"Martyr's Shield",0,9);
+ cur_rect++;
+ }
+ if (adven[i].status[11] > 0)
+ if(cur_rect <= 9) {
+ char_win_draw_string(main_dc,pc_status_rect[cur_rect],"Asleep",0,9);
+ cur_rect++;
+ }
+ if (adven[i].status[12] > 0)
+ if(cur_rect <= 9) {
+ char_win_draw_string(main_dc,pc_status_rect[cur_rect],"Paralyzed",0,9);
+ cur_rect++;
+ }
+ if (adven[i].status[13] > 0)
+ if(cur_rect <= 9) {
+ char_win_draw_string(main_dc,pc_status_rect[cur_rect],"Acid",0,9);
+ cur_rect++;
+ }
+ //end pc status section
+
+ //Write in Traits
+ SelectObject(main_dc,bold_font);
+ sprintf((char *) to_draw, "Traits:");
+ win_draw_string(main_dc,traits_rect,to_draw,0,10);
+ SelectObject(main_dc,font);
+ cur_rect=0;
+ if (adven[i].traits[0] == 1)
+ if(cur_rect <= 15) {
+ char_win_draw_string(main_dc,pc_traits_rect[cur_rect],"Toughness",0,9);
+ cur_rect++;
+ }
+ if (adven[i].traits[1] == 1)
+ if(cur_rect <= 15) {
+ char_win_draw_string(main_dc,pc_traits_rect[cur_rect],"Magically Apt",0,9);
+ cur_rect++;
+ }
+ if (adven[i].traits[2] == 1)
+ if(cur_rect <= 15) {
+ char_win_draw_string(main_dc,pc_traits_rect[cur_rect],"Ambidextrous",0,9);
+ cur_rect++;
+ }
+ if (adven[i].traits[3] == 1)
+ if(cur_rect <= 15) {
+ char_win_draw_string(main_dc,pc_traits_rect[cur_rect],"Nimble Fingers",0,9);
+ cur_rect++;
+ }
+ if (adven[i].traits[4] == 1)
+ if(cur_rect <= 15) {
+ char_win_draw_string(main_dc,pc_traits_rect[cur_rect],"Cave Lore",0,9);
+ cur_rect++;
+ }
+
+ if (adven[i].traits[5] == 1)
+ if(cur_rect <= 15) {
+ char_win_draw_string(main_dc,pc_traits_rect[cur_rect],"Woodsman",0,9);
+ cur_rect++;
+ }
+ if (adven[i].traits[6] == 1)
+ if(cur_rect <= 15) {
+ char_win_draw_string(main_dc,pc_traits_rect[cur_rect],"Good Constitution",0,9);
+ cur_rect++;
+ }
+ if (adven[i].traits[7] == 1)
+ if(cur_rect <= 15) {
+ char_win_draw_string(main_dc,pc_traits_rect[cur_rect],"Highly Alert",0,9);
+ cur_rect++;
+ }
+ if (adven[i].traits[8] == 1)
+ if(cur_rect <= 15) {
+ char_win_draw_string(main_dc,pc_traits_rect[cur_rect],"Exceptional Str.",0,9);
+ cur_rect++;
+ }
+ if (adven[i].traits[9] == 1)
+ if(cur_rect <= 15) {
+ char_win_draw_string(main_dc,pc_traits_rect[cur_rect],"Recuperation",0,9);
+ cur_rect++;
+ }
+ if (adven[i].traits[10] == 1)
+ if(cur_rect <= 15) {
+ char_win_draw_string(main_dc,pc_traits_rect[cur_rect],"Sluggish",0,9);
+ cur_rect++;
+ }
+ if (adven[i].traits[11] == 1)
+ if(cur_rect <= 15) {
+ char_win_draw_string(main_dc,pc_traits_rect[cur_rect],"Magically Inept",0,9);
+ cur_rect++;
+ }
+ if (adven[i].traits[12] == 1)
+ if(cur_rect <= 14) {
+ char_win_draw_string(main_dc,pc_traits_rect[cur_rect],"Frail",0,9);
+ cur_rect++;
+ }
+ if (adven[i].traits[13] == 1)
+ if(cur_rect <= 14) {
+ char_win_draw_string(main_dc,pc_traits_rect[cur_rect],"Chronic Disease",0,9);
+ cur_rect++;
+ }
+ if (adven[i].traits[14] == 1)
+ if(cur_rect <= 13) {
+ char_win_draw_string(main_dc,pc_traits_rect[cur_rect],"Bad Back",0,9);
+ cur_rect++;
+ }
+
+ //end traits
+
+
+ SetTextColor(main_dc,colors[0]);
+ SelectObject(main_dc,bold_font);
+ char_win_draw_string(main_dc,pc_area_buttons[i][3],"Alive ",1,10);
+ SelectObject(main_dc,bold_font);
+ }
+ break;
+ case 2:
+ if (i == current_active_pc){
+ SetTextColor(main_dc,colors[0]);
+ SelectObject(main_dc,bold_font);
+ char_win_draw_string(main_dc,pc_area_buttons[i][3],"Dead ",1,10);
+ SelectObject(main_dc,bold_font);
+ break;
+ }
+ case 3:
+ if (i == current_active_pc){
+ SetTextColor(main_dc,colors[0]);
+ SelectObject(main_dc,bold_font);
+ char_win_draw_string(main_dc,pc_area_buttons[i][3],"Dust ",1,10);
+ SelectObject(main_dc,bold_font);
+ break;
+ }
+ case 4:
+ if (i == current_active_pc){
+ SetTextColor(main_dc,colors[0]);
+ SelectObject(main_dc,bold_font);
+ char_win_draw_string(main_dc,pc_area_buttons[i][3],"Stone ",1,10);
+ SelectObject(main_dc,bold_font);
+ break;
+ }
+ case 5:
+ if (i == current_active_pc){
+ SetTextColor(main_dc,colors[0]);
+ SelectObject(main_dc,bold_font);
+ char_win_draw_string(main_dc,pc_area_buttons[i][3],"Fled ",1,10);
+ SelectObject(main_dc,bold_font);
+ break;
+ }
+ case 6:
+ if (i == current_active_pc){
+ SetTextColor(main_dc,colors[0]);
+ SelectObject(main_dc,bold_font);
+ char_win_draw_string(main_dc,pc_area_buttons[i][3],"Surface ",1,10);
+ SelectObject(main_dc,bold_font);
+ break;
+ }
+ default:
+ if (i == current_active_pc){
+ SetTextColor(main_dc,colors[0]);
+ SelectObject(main_dc,bold_font);
+ char_win_draw_string(main_dc,pc_area_buttons[i][3],"Absent ",1,10);
+ SelectObject(main_dc,bold_font);
+ break;
+ }
+ }
+ //frame_dlog_rect((GrafPtr) mainPtr,pc_area_buttons[i][0],0);
+
+
+ }
+
+ } // Closes the for i=6 loop
+ SetTextColor(main_dc,colors[0]);
+
+ for(i = 0; i < 5; i++)
+ if ((current_pressed_button < 0) || (current_pressed_button == i + 10)) {
+ if (clear_first == 1) { // first erase what's already there
+ paint_pattern(NULL,1,edit_rect[i][0],3);
+ }
+
+ from_rect = (current_pressed_button == i + 10) ? ed_buttons_from[1] : ed_buttons_from[0];
+ rect_draw_some_item(buttons_gworld,from_rect,buttons_gworld,edit_rect[i][0],0,1);
+ SetTextColor(main_dc,colors[3]);
+ switch(i) {
+ case 0:
+ char_win_draw_string(main_dc,edit_rect[0][1]," Add|Mage|Spells ",0,10);
+ break;
+ case 1:
+ char_win_draw_string(main_dc,edit_rect[1][1]," Add|Priest|Spells ",0,10);
+ break;
+ case 2:
+ char_win_draw_string(main_dc,edit_rect[2][1]," Edit|Traits",0,10);
+ break;
+ case 3:
+ char_win_draw_string(main_dc,edit_rect[3][1]," Edit|Skills",0,10);
+ break;
+ case 4:
+ char_win_draw_string(main_dc,edit_rect[4][1]," Edit| XP",0,10);
+ break;
+ default:
+ break;
+ }
+ SetTextColor(main_dc,colors[0]);
+
+ }
+
+ }
+SetTextColor(main_dc,colors[0]);
+}
+
+void display_strings_event_filter (short item_hit)
+{
+
+
+
+ switch (item_hit) {
+ case 1:
+ dialog_not_toast = FALSE;
+ break;
+ }
+}
+
+void display_strings(short str1a,short str1b,short str2a,short str2b,
+ char *title,short sound_num,short graphic_num,short parent_num)
+{
+
+
+ char sign_text[256];
+
+
+
+ make_cursor_sword();
+
+ store_str1a = str1a;
+ store_str1b = str1b;
+ store_str2a = str2a;
+ store_str2b = str2b;
+
+ if ((str1a <= 0) || (str1b <= 0))
+ return;
+ store_which_string_dlog = 970;
+ if (strlen(title) > 0)
+ store_which_string_dlog += 2;
+ if ((str2a > 0) && (str2b > 0))
+ store_which_string_dlog++;
+ cd_create_dialog_parent_num(store_which_string_dlog,parent_num);
+
+ cd_activate_item(store_which_string_dlog,2,0);
+
+ csp(store_which_string_dlog,store_which_string_dlog,graphic_num);
+
+ get_str(sign_text,str1a,str1b);
+ csit(store_which_string_dlog,4,(char *) sign_text);
+ if ((str2a > 0) && (str2b > 0)) {
+ get_str(sign_text,str2a,str2b);
+ csit(store_which_string_dlog,5,(char *) sign_text);
+ }
+ if (strlen(title) > 0)
+ csit(store_which_string_dlog,6,title);
+ csp(store_which_string_dlog,3,graphic_num);
+ if (sound_num >= 0)
+ play_sound(sound_num);
+ while (dialog_not_toast)
+ ModalDialog();
+
+ cd_kill_dialog(store_which_string_dlog,0);
+}
+
+void get_str(char *str,short i, short j)
+{
+ GetIndString(str, i, j);
+}
+
+void char_win_draw_string(HDC dest_window,RECT dest_rect,char *str,short mode,short line_height)
+{
+ char store_s[256];
+
+ strcpy((char *) store_s,str);
+ win_draw_string( dest_window, dest_rect,store_s, mode, line_height);
+
+}
+
+// mode: 0 - align up and left, 1 - center on one line
+// str is a c string, 256 characters
+// uses current font
+void win_draw_string(HDC dest_hdc,RECT dest_rect,char *str,short mode,short)
+{
+ short i;
+
+// this will need formatting for '|' line breaks
+ for (i = 0; i < 256; i++) {
+ if (str[i] == '|')
+ str[i] = 13;
+ if (str[i] == '_')
+ str[i] = 34;
+ }
+ // if dest is main window, add ulx, uly
+ if (dest_hdc == main_dc)
+ OffsetRect(&dest_rect,ulx,uly);
+ switch (mode) {
+ case 0:
+ dest_rect.bottom += 6;
+ DrawText(dest_hdc,str,strlen((char *)str),&dest_rect,DT_LEFT | DT_WORDBREAK); break;
+ case 1:
+ dest_rect.bottom += 6; dest_rect.top -= 6;
+ DrawText(dest_hdc,str,strlen((char *)str),&dest_rect,
+ DT_CENTER | DT_VCENTER | DT_NOCLIP | DT_SINGLELINE); break;
+ case 2: case 3:
+ dest_rect.bottom += 6; dest_rect.top -= 6;
+ DrawText(dest_hdc,str,strlen((char *)str),&dest_rect,
+ DT_LEFT | DT_VCENTER | DT_NOCLIP | DT_SINGLELINE); break;
+ }
+ // not yet done adjusts for 1, 2, 3
+
+}
+
+short string_length(char *str,HDC hdc)
+{
+ short text_len[257];
+ short total_width = 0,i,len;
+ char p_str[256];
+
+ for (i = 0; i < 257; i++)
+ text_len[i]= 0;
+
+ strcpy((char *) p_str,str);
+ MeasureText(256,p_str,text_len,hdc);
+ len = strlen((char *)str);
+
+ for (i = 0; i < 257; i++)
+ if ((text_len[i] > total_width) && (i <= len))
+ total_width = text_len[i];
+ return total_width;
+}
+
+// Note ... this expects a str len of at most 256 and
+// len_array pointing to a 256 long array of shorts
+void MeasureText(short str_len,char *str, short *len_array,HDC hdc)
+{
+ short text_len[257];
+ short i;
+ char p_str[257];
+ SIZE val_returned;
+ char *store_array;
+ short *store2;
+
+ store_array = (char *) len_array;
+ for (i = 0; i < 256; i++)
+ text_len[i] = 0;
+ for (i = 1; i < str_len; i++) {
+ strncpy(p_str,str,i);
+ p_str[i] = 0;
+ GetTextExtentPoint32(hdc,p_str,i, &val_returned);
+ text_len[i] = val_returned.cx;
+ }
+ for (i = 0; i < 256; i++) {
+ store2 = (short *) store_array;
+ *store2 = text_len[i];
+ store_array += 2;
+ }
+ }
+
+
+void GetIndString(char *str,short i, short j) {
+ UINT resnum = 0,len;
+ short k;
+
+ resnum = i * 300 + j;
+
+ len = LoadString(store_hInstance,resnum,str,256);
+ if (len == 0) {
+ sprintf(str,"");
+ return;
+ }
+ for (k = 0; k < 256; k++) {
+ if (str[k] == '|')
+ str[k] = 13;
+ if (str[k] == '_')
+ str[k] = 34;
+ }
+}
+
+
+void make_cursor_sword()
+{
+ SetCursor(sword_curs);
+}
diff --git a/Win32/Blades of Exile Char Editor/graphics.h b/Win32/Blades of Exile Char Editor/graphics.h
new file mode 100644
index 00000000..3c6712ed
--- /dev/null
+++ b/Win32/Blades of Exile Char Editor/graphics.h
@@ -0,0 +1,25 @@
+void init_main_buttons();
+void Set_up_win ();
+void redraw_screen();
+void draw_main_screen();
+void do_button_action(short which_pc,short which_button);
+void draw_items(short clear_first);
+void display_party(short mode,short clear_first);
+
+
+void char_win_draw_string(HDC dest_window,RECT dest_rect,char *str,short mode,short line_height);
+void win_draw_string(HDC dest_hdc,RECT dest_rect,char *str,short mode,short line_height);
+void display_strings_event_filter (short item_hit);
+void display_strings(short str1a,short str1b,short str2a,short str2b,
+ char *title,short sound_num,short graphic_num,short parent_num);
+void c2p(char *str) ;
+void p2c(char *str);
+void get_str(char *,short i, short j);
+short string_length(char *str,HDC hdc);
+void make_cursor_sword();
+
+void MeasureText(short str_len,char *str, short *len_array,HDC hdc);
+void GetIndString(char *str,short i, short j) ;
+
+void lose_graphics();
+
diff --git a/Win32/Blades of Exile Char Editor/graphutl.cpp b/Win32/Blades of Exile Char Editor/graphutl.cpp
new file mode 100644
index 00000000..7336c4e8
--- /dev/null
+++ b/Win32/Blades of Exile Char Editor/graphutl.cpp
@@ -0,0 +1,333 @@
+#define xmin(a,b) ((a) < (b) ? (a) : (b))
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include "global.h"
+
+
+#include "edsound.h"
+
+#include "graphutl.h"
+
+extern HWND mainPtr;
+//extern HPALETTE hpal;
+extern HDC main_dc,main_dc2,main_dc3;
+extern short ulx,uly;
+extern HBITMAP mixed_gworld,dialog_pattern_gworld,pattern_gworld,status_pattern_gworld;
+extern char file_path_name[256];
+
+ int elements[5] = {COLOR_ACTIVEBORDER,COLOR_ACTIVECAPTION,
+ COLOR_WINDOWFRAME,COLOR_SCROLLBAR,COLOR_BTNFACE};
+ COLORREF store_element_colors[5];
+short dlog_pat_placed = 0;
+short current_pattern = -1;
+
+HBITMAP load_pict(short pict_num,HDC model_hdc)
+{
+ HBITMAP got_bitmap;
+
+ switch(pict_num) {
+ case 700: case 701: case 702: got_bitmap = ReadBMP("images/STATAREA.BMP"); break;
+ case 703: got_bitmap = ReadBMP("images/TEXTBAR.BMP"); break;
+ case 704: got_bitmap = ReadBMP("images/BUTTONS.BMP"); break;
+ case 705: got_bitmap = ReadBMP("images/TERSCRN.BMP"); break;
+ case 800: got_bitmap = ReadBMP("images/TER1.BMP"); break;
+ case 801: got_bitmap = ReadBMP("images/TER2.BMP"); break;
+ case 802: got_bitmap = ReadBMP("images/TER3.BMP"); break;
+ case 803: got_bitmap = ReadBMP("images/TER4.BMP"); break;
+ case 804: got_bitmap = ReadBMP("images/TER5.BMP"); break;
+ case 805: got_bitmap = ReadBMP("images/TER6.BMP"); break;
+ case 820: got_bitmap = ReadBMP("images/TERANIM.BMP"); break;
+ case 821: got_bitmap = ReadBMP("images/FIELDS.BMP"); break;
+ case 830: got_bitmap = ReadBMP("images/STARTUP.BMP"); break;
+ case 850: got_bitmap = ReadBMP("images/DLOGPICS.BMP"); break;
+ case 860: got_bitmap = ReadBMP("images/TALKPORT.BMP"); break;
+ case 875: got_bitmap = ReadBMP("images/DLOGMAPS.BMP"); break;
+ case 880: got_bitmap = ReadBMP("images/MISSILES.BMP"); break;
+ case 900: got_bitmap = ReadBMP("images/TINYOBJ.BMP"); break;
+ case 901: got_bitmap = ReadBMP("images/OBJECTS.BMP"); break;
+ case 902: got_bitmap = ReadBMP("images/PCS.BMP"); break;
+ case 905: got_bitmap = ReadBMP("images/PCS.BMP"); break;
+ case 903: case 904: got_bitmap = ReadBMP("images/MIXED.BMP"); break;
+ case 1100: case 1200: got_bitmap = ReadBMP("images/MONST1.BMP"); break;
+ case 1101: case 1201: got_bitmap = ReadBMP("images/MONST2.BMP"); break;
+ case 1102: case 1202: got_bitmap = ReadBMP("images/MONST3.BMP"); break;
+ case 1103: case 1203: got_bitmap = ReadBMP("images/MONST4.BMP"); break;
+ case 1104: case 1204: got_bitmap = ReadBMP("images/MONST5.BMP"); break;
+ case 1105: case 1205: got_bitmap = ReadBMP("images/MONST6.BMP"); break;
+ case 1106: case 1206: got_bitmap = ReadBMP("images/MONST7.BMP"); break;
+ case 1107: case 1207: got_bitmap = ReadBMP("images/MONST8.BMP"); break;
+ case 1108: case 1208: got_bitmap = ReadBMP("images/MONST9.BMP"); break;
+ case 1109: case 1209: got_bitmap = ReadBMP("images/MONST10.BMP"); break;
+ case 1400: got_bitmap = ReadBMP("images/STSCICON.BMP"); break;
+ case 1401: got_bitmap = ReadBMP("images/HELPPICS.BMP"); break;
+ case 1402: got_bitmap = ReadBMP("images/APPIC.BMP"); break;
+ case 1500: case 1501: case 1502: case 1503: case 1504: case 1505: case 1506: case 1507:
+ got_bitmap = ReadBMP("images/BIGMAPS.BMP"); break;
+ case 2000: got_bitmap = ReadBMP("images/DLOGBTNS.BMP"); break;
+ case 3000: got_bitmap = ReadBMP("images/START.BMP"); break;
+ case 3001: got_bitmap = ReadBMP("images/SPIDLOGO.BMP"); break;
+ case 5000: got_bitmap = ReadBMP("images/BLEDTITL.BMP"); break;
+ case 5001: got_bitmap = ReadBMP("images/PCEDBTNS.BMP"); break;
+
+ default: got_bitmap = NULL;
+ }
+ return got_bitmap;
+}
+
+void rect_draw_some_item(HBITMAP src,RECT src_rect,HBITMAP dest,RECT dest_rect,
+ short trans, short main_win) {
+ HDC hdcMem,hdcMem2,hdcMem3,destDC;
+ HBITMAP transbmp;
+ COLORREF white = RGB(255,255,255),oldcolor;
+
+ HBRUSH hbrush,old_brush;
+ UINT c;
+ HBITMAP store,store2;
+ Boolean dlog_draw = FALSE;
+
+ if (main_win == 2) {
+ destDC = (HDC) dest;
+ main_win = 1;
+ dlog_draw = TRUE;
+ hdcMem = CreateCompatibleDC(destDC);
+ SelectObject(hdcMem, src);
+ SetMapMode(hdcMem,GetMapMode((HDC) mainPtr));
+ //SelectPalette(hdcMem,hpal,0);
+ }
+ else {
+ destDC = main_dc;
+ hdcMem = main_dc2;
+ store = (HBITMAP) SelectObject(hdcMem,src);
+ }
+
+ if (trans != 1) {
+ if (main_win == 0) { // Not transparent, into bitmap
+ hdcMem2 = main_dc3;
+ store2 = (HBITMAP) SelectObject(hdcMem2, dest);
+ StretchBlt(hdcMem2,dest_rect.left,dest_rect.top,dest_rect.right - dest_rect.left,
+ dest_rect.bottom - dest_rect.top,
+ hdcMem,src_rect.left,src_rect.top,src_rect.right - src_rect.left,
+ src_rect.bottom - src_rect.top,(trans >= 0) ? SRCCOPY : SRCAND);
+ SelectObject(hdcMem2,store2);
+ }
+
+ else { // Not transparent, onto screen
+ if (trans == 2) {
+ //c = GetNearestPaletteIndex(hpal,x);
+ hbrush = CreateSolidBrush(PALETTEINDEX(c));
+ old_brush = (HBRUSH) SelectObject(destDC,hbrush);
+
+ }
+ if (dlog_draw == FALSE)
+ SetViewportOrgEx(destDC,ulx,uly, NULL);
+
+ StretchBlt(destDC,dest_rect.left,dest_rect.top,dest_rect.right - dest_rect.left,
+ dest_rect.bottom - dest_rect.top,
+ hdcMem,src_rect.left,src_rect.top,src_rect.right - src_rect.left,
+ src_rect.bottom - src_rect.top,(trans == 0) ? SRCCOPY : PATCOPY);
+ if (trans == 2) {
+ SelectObject(destDC,old_brush);
+ if (DeleteObject(hbrush) == 0)
+ play_sound(1);
+ }
+ if (dlog_draw == FALSE)
+ SetViewportOrgEx(destDC,0,0,NULL);
+
+
+ }
+ } // end of non-transparent draws
+ else {
+ if (main_win == 0) {
+ hdcMem3 = CreateCompatibleDC(hdcMem);
+ SelectObject(hdcMem3, dest);
+ SetMapMode(hdcMem3,GetMapMode((HDC) mainPtr));
+ //SelectPalette(hdcMem3,hpal,0);
+ transbmp = CreateBitmap(src_rect.right - src_rect.left,
+ src_rect.bottom - src_rect.top,1,1,NULL);
+ hdcMem2 = CreateCompatibleDC(destDC);
+ SelectObject(hdcMem2, transbmp);
+ oldcolor = SetBkColor(hdcMem, white);
+ StretchBlt(hdcMem2,0,0,dest_rect.right - dest_rect.left,
+ dest_rect.bottom - dest_rect.top,
+ hdcMem,src_rect.left,src_rect.top,src_rect.right - src_rect.left,
+ src_rect.bottom - src_rect.top,SRCCOPY);
+ SetBkColor(hdcMem, oldcolor);
+
+ StretchBlt(hdcMem3,dest_rect.left,dest_rect.top,dest_rect.right - dest_rect.left,
+ dest_rect.bottom - dest_rect.top,
+ hdcMem,src_rect.left,src_rect.top,src_rect.right - src_rect.left,
+ src_rect.bottom - src_rect.top,SRCINVERT);
+ StretchBlt(hdcMem3,dest_rect.left,dest_rect.top,dest_rect.right - dest_rect.left,
+ dest_rect.bottom - dest_rect.top,
+ hdcMem2,0,0,src_rect.right - src_rect.left,
+ src_rect.bottom - src_rect.top,SRCAND);
+ StretchBlt(hdcMem3,dest_rect.left,dest_rect.top,dest_rect.right - dest_rect.left,
+ dest_rect.bottom - dest_rect.top,
+ hdcMem,src_rect.left,src_rect.top,src_rect.right - src_rect.left,
+ src_rect.bottom - src_rect.top,SRCINVERT);
+ DeleteDC(hdcMem3);
+ DeleteDC(hdcMem2);
+
+ DeleteObject(transbmp);
+ }
+ else {
+ if (dlog_draw == FALSE)
+ SetViewportOrgEx(destDC,ulx,uly,NULL);
+ transbmp = CreateBitmap(src_rect.right - src_rect.left,
+ src_rect.bottom - src_rect.top,1,1,NULL);
+ hdcMem2 = CreateCompatibleDC(destDC);
+ SelectObject(hdcMem2, transbmp);
+ oldcolor = SetBkColor(hdcMem, white);
+ StretchBlt(hdcMem2,0,0,dest_rect.right - dest_rect.left,
+ dest_rect.bottom - dest_rect.top,
+ hdcMem,src_rect.left,src_rect.top,src_rect.right - src_rect.left,
+ src_rect.bottom - src_rect.top,SRCCOPY);
+
+ SetBkColor(hdcMem, oldcolor);
+
+ StretchBlt(destDC,dest_rect.left,dest_rect.top,dest_rect.right - dest_rect.left,
+ dest_rect.bottom - dest_rect.top,
+ hdcMem,src_rect.left,src_rect.top,src_rect.right - src_rect.left,
+ src_rect.bottom - src_rect.top,SRCINVERT);
+ StretchBlt(destDC,dest_rect.left,dest_rect.top,dest_rect.right - dest_rect.left,
+ dest_rect.bottom - dest_rect.top,
+ hdcMem2,0,0,src_rect.right - src_rect.left,
+ src_rect.bottom - src_rect.top,SRCAND);
+ StretchBlt(destDC,dest_rect.left,dest_rect.top,dest_rect.right - dest_rect.left,
+ dest_rect.bottom - dest_rect.top,
+ hdcMem,src_rect.left,src_rect.top,src_rect.right - src_rect.left,
+ src_rect.bottom - src_rect.top,SRCINVERT);
+ if (dlog_draw == FALSE)
+ SetViewportOrgEx(destDC,0,0,NULL);
+ DeleteDC(hdcMem2);
+
+ DeleteObject(transbmp);
+
+
+ }
+ }
+ if (dlog_draw == TRUE)
+ DeleteDC(hdcMem);
+ else SelectObject(hdcMem,store);
+}
+
+ void fry_dc(HWND hwnd,HDC dc)
+ {
+ if (ReleaseDC(hwnd,dc) == 0)
+ PostQuitMessage(0);
+ }
+
+void DisposeGWorld(HBITMAP bitmap)
+{
+ DeleteObject(bitmap);
+}
+
+void SectRect(RECT *a, RECT *b, RECT *c)
+ {
+ IntersectRect(c,a,b);
+ }
+
+Boolean Button()
+{
+ MSG msg;
+
+ if (PeekMessage(&msg,mainPtr,WM_MOUSEFIRST,WM_MOUSELAST,PM_REMOVE) > 0)
+ if ((msg.message == WM_LBUTTONDOWN) || (msg.message == WM_CHAR)
+ || (msg.message == WM_KEYDOWN))
+ return TRUE;
+ if (PeekMessage(&msg,mainPtr,WM_KEYFIRST,WM_KEYLAST,PM_REMOVE) > 0)
+ if ((msg.message == WM_LBUTTONDOWN) || (msg.message == WM_CHAR)
+ || (msg.message == WM_KEYDOWN))
+ return TRUE;
+ return FALSE;
+}
+
+
+// which_mode is 0 ... dest is a bitmap
+// is 1 ... ignore dest ... paint on mainPtr
+// is 2 ... dest is a dialog, use the dialog pattern
+// both pattern gworlds are 192 x 256
+void paint_pattern(HBITMAP dest,short which_mode,RECT dest_rect,short which_pattern)
+{
+ HBITMAP source_pat;
+ RECT pattern_source = {32,168,96,232}, pat_dest_orig = {0,0,64,64},pat_dest;
+ short i,j;
+
+ RECT draw_from_orig = {0,0,192,256},draw_from,draw_to;
+ short store_ulx,store_uly;
+
+ if (which_mode == 1)
+ OffsetRect(&dest_rect,ulx, uly);
+ else if (which_mode == 3)
+ which_mode = 1;
+ if (which_mode == 2) {
+ source_pat = dialog_pattern_gworld;
+ if (dlog_pat_placed == 0) {
+ dlog_pat_placed = 1;
+ OffsetRect(&pattern_source, 64 * 2,0);
+ for (i = 0; i < 3; i++)
+ for (j = 0; j < 4; j++) {
+ pat_dest = pat_dest_orig;
+ OffsetRect(&pat_dest,64 * i, 64 * j);
+ rect_draw_some_item(mixed_gworld,pattern_source,
+ dialog_pattern_gworld,pat_dest,0,0);
+ }
+ }
+ }
+ else {
+ source_pat = pattern_gworld;
+ if (current_pattern != which_pattern) {
+ current_pattern = which_pattern;
+ OffsetRect(&pattern_source, 64 * (which_pattern % 5),
+ 64 * (which_pattern / 5));
+ for (i = 0; i < 3; i++)
+ for (j = 0; j < 4; j++) {
+ pat_dest = pat_dest_orig;
+ OffsetRect(&pat_dest,64 * i, 64 * j);
+ rect_draw_some_item(mixed_gworld,pattern_source,
+ pattern_gworld,pat_dest,0,0);
+ }
+ }
+ }
+
+ // now patterns are loaded, so have fun
+ // first nullify ul shifting
+ store_ulx = ulx;
+ store_uly = uly;
+ ulx = uly = 0;
+ for (i = 0; i < (dest_rect.right / 192) + 1; i++)
+ for (j = 0; j < (dest_rect.bottom / 256) + 1; j++) {
+ draw_to = draw_from_orig;
+ OffsetRect(&draw_to,192 * i, 256 * j);
+ IntersectRect(&draw_to,&draw_to,&dest_rect);
+ if (draw_to.right != 0) {
+ draw_from = draw_to;
+ OffsetRect(&draw_from, -192 * i, -256 * j);
+ switch (which_mode) {
+ case 0:
+ rect_draw_some_item(source_pat,draw_from,
+ dest,draw_to,0,0); break;
+ case 1:
+ rect_draw_some_item(source_pat,draw_from,
+ source_pat,draw_to,0,1); break;
+ case 2:
+ rect_draw_some_item(source_pat,draw_from,
+ dest,draw_to,0,2); break;
+ }
+ }
+ }
+ ulx = store_ulx;
+ uly = store_uly;
+}
+
+/* GK */
+
+HBITMAP ReadBMP(char * fileName)
+{
+ return (HBITMAP) LoadImage(0, fileName, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
+}
diff --git a/Win32/Blades of Exile Char Editor/graphutl.h b/Win32/Blades of Exile Char Editor/graphutl.h
new file mode 100644
index 00000000..7222672c
--- /dev/null
+++ b/Win32/Blades of Exile Char Editor/graphutl.h
@@ -0,0 +1,16 @@
+#ifndef _GRAPHUTL_H
+ #define _GRAPHUTL_H
+
+HBITMAP load_pict(short pict_num,HDC model_hdc);
+void rect_draw_some_item(HBITMAP src,RECT src_rect,HBITMAP dest,RECT dest_rect,
+ short trans, short main_win) ;
+ void fry_dc(HWND hwnd,HDC dc) ;
+ void DisposeGWorld(HBITMAP bitmap);
+void SectRect(RECT *a, RECT *b, RECT *c);
+Boolean Button();
+void paint_pattern(HBITMAP dest,short which_mode,RECT dest_rect,short which_pattern);
+
+/* GK */
+HBITMAP ReadBMP(char * fileName);
+
+#endif