209 Commits

Author SHA1 Message Date
Alexander Batalov
9fb917c357 Bump version to 1.3.0 2024-04-21 12:46:24 +03:00
Alexander Batalov
aa31185b35 Update release workflow 2024-04-21 11:23:18 +03:00
Alexander Batalov
ec0685ea19 Normalize and resolve asset bundle paths 2024-04-06 16:41:49 +03:00
Alexander Batalov
2c7ab7f5c8 Detect alternative default music directory 2024-04-06 16:33:16 +03:00
Alexander Batalov
8de73ad774 Refactor file find
Fixes #352
2024-04-06 12:47:11 +03:00
Alexander Batalov
3ceacf1001 Fix warning 2024-04-06 12:01:48 +03:00
Alexander Batalov
31afb4d568 Bump actions to v4 2024-03-03 11:27:37 +03:00
Alexander Batalov
95cbba3920 Bump zlib to 1.3.1 2024-03-03 09:39:06 +03:00
sonilyan
16b044ae31 Fix obj_can_see_obj not working in release build (#350) 2024-02-15 05:04:57 +03:00
sonilyan
caea9cb4fb Fix yaam no damage (#351) 2024-02-15 05:02:56 +03:00
Alexander Batalov
8325823493 Expose game data files to iOS Files app
Fixes #343
2024-01-16 23:42:25 +03:00
Alexander Batalov
8e1e8d483c Review db_total
Fixes #327
2024-01-16 22:37:06 +03:00
Alexander Batalov
1b18c2baa3 Fix custom patch file name template
Follow-up to #309
2024-01-16 22:35:16 +03:00
Alexander Batalov
70d5830f00 Force LF on .mm 2024-01-16 19:04:14 +03:00
yabisiktir
401df384ef modernize-use-nullptr (#332) 2024-01-16 18:57:49 +03:00
Vlad
59af02cca9 Variable naming, part 2 (#320) 2024-01-16 16:33:08 +03:00
c6
c6565ac96a Sfall: add VersionString, ConfigFile, PatchFile (#309) 2024-01-16 15:56:21 +03:00
Jo
16f4ab7787 Improve pointer comparsion for Nevada and Sonora mods (#291) 2024-01-16 15:42:32 +03:00
Vasilii Rogin
e23c4eddda Use delay_ms instead of spinwait (#262) 2024-01-16 15:24:49 +03:00
λP.(P izzy)
601f0c7b44 fix CMake condition to allow build on OpenBSD & FreeBSD (#341) 2024-01-16 15:06:47 +03:00
sonilyan
f411d75643 Add overriddenSelf initialization for scriptRead (#329) 2023-10-31 13:46:25 +03:00
Vasilii Rogin
81fce5f4a2 Fix wrong pointer dereferecing in aiFindAttackers (#324) 2023-10-09 20:50:59 +03:00
Eir Nym
0e447c55a8 Upgrade zlib to 1.3 (#323) 2023-09-28 17:26:52 +03:00
Alexander Batalov
91806d8ccb Fix missing include 2023-09-03 22:31:52 +03:00
Alexander Batalov
a30fb4cfdd Add mapper_refresh_rotation 2023-09-03 22:21:14 +03:00
Alexander Batalov
def8effa9f Add handle_new_map 2023-09-03 21:42:17 +03:00
Alexander Batalov
d46ee07583 Add mapper_destroy_highlight_obj 2023-09-03 21:30:59 +03:00
Alexander Batalov
ee19238667 Add update_toolname 2023-09-03 20:48:23 +03:00
Alexander Batalov
0d83cff24e Add place_entrance_hex 2023-09-03 20:24:36 +03:00
Alexander Batalov
30a3bf9b71 Add pick_region 2023-09-03 20:23:50 +03:00
Alexander Batalov
8c61b0bd8c Add sort_rect 2023-09-03 19:15:50 +03:00
Alexander Batalov
6e9f1ae517 Add op_set_self 2023-09-03 18:23:19 +03:00
Alexander Batalov
ad3e0eb752 Add op_explosions_metarule 2023-09-03 16:51:29 +03:00
Alexander Batalov
b40bfcc64a Add some metarules 2023-09-03 16:26:52 +03:00
Alexander Batalov
b706756ec9 Add op_get_script 2023-09-03 13:34:16 +03:00
Alexander Batalov
427672741a Add op_list_as_array 2023-09-02 22:06:37 +03:00
Alexander Batalov
bb3513956c Add op_force_encounter 2023-09-02 21:34:41 +03:00
Alexander Batalov
84aecfa823 Add draw_rect 2023-09-02 20:07:02 +03:00
Alexander Batalov
7f920fe13b Add erase_rect 2023-09-02 19:57:14 +03:00
Alexander Batalov
9178abc53d Add toolbar_proto 2023-09-02 19:47:15 +03:00
Alexander Batalov
84288612ef Add map_toggle_block_obj_viewing_on 2023-09-02 19:43:56 +03:00
Alexander Batalov
4a94b19f60 Add proto_subdata_setup_pid_button 2023-09-02 19:36:17 +03:00
Alexander Batalov
b0b161ceb5 Add proto_subdata_setup_fid_button 2023-09-02 19:31:16 +03:00
Alexander Batalov
1c2fd05bcd Add proto_subdata_setup_int_button 2023-09-02 18:33:32 +03:00
Alexander Batalov
e0b18a8785 Add target_exit 2023-09-02 18:08:21 +03:00
Alexander Batalov
8929941d13 Add target_init 2023-09-02 18:07:37 +03:00
Alexander Batalov
8d2d5df65f Add target_new 2023-09-02 17:54:17 +03:00
Alexander Batalov
fe47d88035 Add target_remove_tid 2023-09-02 17:47:43 +03:00
Alexander Batalov
29e81f3bf4 Add target_remove 2023-09-02 17:37:21 +03:00
Alexander Batalov
05b4c125e6 Add target_save 2023-09-02 17:19:51 +03:00
Alexander Batalov
96573a7209 Add target_remove_all 2023-09-02 17:14:49 +03:00
Alexander Batalov
caf28a7286 Add target_tid_ptr 2023-09-02 17:07:43 +03:00
Alexander Batalov
25a3de62e7 Add target_ptr 2023-09-02 17:05:26 +03:00
Alexander Batalov
fd3cd887b6 Add target_load 2023-09-02 16:40:18 +03:00
Alexander Batalov
c3a6d07dc4 Add target_find_free_subnode 2023-09-02 16:24:07 +03:00
Alexander Batalov
ed7ffac816 Add target_header_load 2023-09-02 15:31:23 +03:00
Alexander Batalov
59c43590cc Add target_header_save 2023-09-02 15:29:59 +03:00
Alexander Batalov
f14f37f970 Add target_override_protection 2023-09-02 14:39:31 +03:00
Alexander Batalov
cba1fc8f61 Add map_scr_remove_spatial 2023-07-25 11:56:20 +03:00
Alexander Batalov
8329d2fcf6 Add map_scr_remove_all_spatials 2023-07-25 11:14:41 +03:00
Alexander Batalov
1de7ef0151 Add init_mapper_protos 2023-07-24 15:19:18 +03:00
Alexander Batalov
f1f4cac316 Add proto_choose_container_flags 2023-07-24 15:15:06 +03:00
Alexander Batalov
6ce6639f10 Add proto_wall_light_str 2023-07-24 10:57:31 +03:00
Alexander Batalov
c5ad0c294f Add proto_critter_flags_redraw 2023-07-24 10:53:04 +03:00
Alexander Batalov
f780969178 Add proto_critter_flags_modify 2023-07-24 10:46:31 +03:00
Alexander Batalov
f3f61abc18 Add critter_flag_unset 2023-07-24 09:07:02 +03:00
Alexander Batalov
369a54f836 Add critter_flag_set 2023-07-24 09:04:11 +03:00
Alexander Batalov
e9f3b34888 Add mp_pick_kill_type 2023-07-24 08:55:43 +03:00
Alexander Batalov
c1258cbb4c Add proto_pick_ai_packet 2023-07-24 08:43:27 +03:00
Alexander Batalov
49804a52e6 Add combat_ai_name 2023-07-24 08:29:19 +03:00
Alexander Batalov
e0e0db219c Add combat_ai_num 2023-07-24 08:27:42 +03:00
Alexander Batalov
f93aa710a4 Add target_pick_local_var 2023-07-24 08:20:15 +03:00
Alexander Batalov
ca206da4af Add target_pick_map_var 2023-07-24 08:17:04 +03:00
Alexander Batalov
f6461a44dc Add target_pick_global_var 2023-07-24 08:13:45 +03:00
Alexander Batalov
3a271a399f Add pick_rot 2023-07-24 08:10:46 +03:00
Alexander Batalov
ac1f4477ef Add target_make_path 2023-07-24 08:08:01 +03:00
Alexander Batalov
708862ca24 Add target_overriden 2023-07-24 08:03:25 +03:00
Alexander Batalov
57711cae5f Add mapper_edit_exit 2023-07-24 07:17:21 +03:00
Alexander Batalov
f6e9a9d975 Make MapDirErase public 2023-07-24 07:15:58 +03:00
Alexander Batalov
4cd40b33af Add mapper_edit_init 2023-07-24 06:50:07 +03:00
Alexander Batalov
053e70dde4 Add gmouse_set_mapper_mode 2023-07-23 14:27:52 +03:00
Alexander Batalov
4b51b2f29b Add tile_toggle_roof 2023-07-23 14:15:20 +03:00
Alexander Batalov
cdfd308193 Add mapper_main 2023-07-23 11:01:03 +03:00
Alexander Batalov
7327588fc3 Add MapperInit 2023-07-23 10:35:16 +03:00
Alexander Batalov
d16f0010ac Add bookmarkInit 2023-07-23 10:26:43 +03:00
Alexander Batalov
a27b2496d4 Add bookmarkExit 2023-07-23 10:25:58 +03:00
Alexander Batalov
a2d61dc7c4 Add bookmarkHide 2023-07-23 10:23:55 +03:00
Alexander Batalov
093d4f23d8 Add bookmarkUnHide 2023-07-23 10:22:42 +03:00
Alexander Batalov
3331ad02b0 Add categoryInit 2023-07-23 10:20:54 +03:00
Alexander Batalov
661c689029 Add categoryExit 2023-07-23 10:19:02 +03:00
Alexander Batalov
b1049fceb1 Add categoryToggleState 2023-07-23 10:17:52 +03:00
Alexander Batalov
f933bff8ae Add categoryHide 2023-07-23 10:16:59 +03:00
Alexander Batalov
9f08c73b3c Add categoryUnhide 2023-07-23 10:15:51 +03:00
Alexander Batalov
4eaea0e3c0 Add proto_user_is_librarian 2023-07-23 10:10:09 +03:00
Alexander Batalov
c652312157 Add print_toolbar_name 2023-07-23 10:01:58 +03:00
Alexander Batalov
8cc48cf52a Add update_high_obj_name 2023-07-23 09:55:58 +03:00
Alexander Batalov
9faa427a28 Add clear_toolname 2023-07-23 09:52:59 +03:00
Alexander Batalov
480094a3eb Add redraw_toolname 2023-07-23 09:49:22 +03:00
Alexander Batalov
1366b050b0 Add mapper_inven_unwield 2023-07-23 09:44:09 +03:00
Alexander Batalov
e68c2a4784 Add mapper_mark_exit_grid 2023-07-23 09:39:13 +03:00
Alexander Batalov
78ae0fb3bf Add mapper_mark_all_exit_grids 2023-07-23 09:25:56 +03:00
Alexander Batalov
127de14318 Add win_get_num_i 2023-07-23 07:20:56 +03:00
Alexander Batalov
28d1d410d5 Add get_num_i 2023-07-23 06:08:23 +03:00
Alexander Batalov
4b65bdf021 Add scripts_request_townmap 2023-07-22 17:09:19 +03:00
Alexander Batalov
cbb9cbc6fd Clarify some proto params 2023-07-22 17:00:24 +03:00
Alexander Batalov
c72d8778ba Add proto_new 2023-07-22 16:53:01 +03:00
Alexander Batalov
d6c3d74b3f Clarify proto_make_path address 2023-07-22 15:36:51 +03:00
Alexander Batalov
3c7248af5f Add proto_item_init 2023-07-22 15:34:32 +03:00
Alexander Batalov
fd9fa80204 Add proto_item_subdata_init 2023-07-22 15:22:05 +03:00
Alexander Batalov
3d5cb4c3f4 Add proto_scenery_init 2023-07-22 15:07:39 +03:00
Alexander Batalov
01a68af4a4 Add proto_scenery_subdata_init 2023-07-22 15:05:00 +03:00
Alexander Batalov
6a75ec07e9 Add proto_wall_init 2023-07-22 14:59:32 +03:00
Alexander Batalov
1d310eb626 Add proto_tile_init 2023-07-22 14:58:47 +03:00
Alexander Batalov
ffc440c809 Add proto_misc_init 2023-07-22 14:53:22 +03:00
Alexander Batalov
a4daffa30e Add proto_copy_proto 2023-07-22 14:49:56 +03:00
Alexander Batalov
ccabbd7688 Add proto_is_subtype 2023-07-22 14:46:51 +03:00
Alexander Batalov
d27eafe03a Fix win_get_str return code 2023-07-21 11:22:57 +03:00
Alexander Batalov
7a45ac72f0 Add reading mapper config 2023-07-21 11:10:15 +03:00
Alexander Batalov
f6cfc1fa3a Clarify GNW_check_menu_bars param 2023-07-21 11:02:54 +03:00
Alexander Batalov
6dcbcb97ad Add process_pull_down 2023-07-21 10:50:33 +03:00
Alexander Batalov
769599c463 Fix closing same file twice
Closes #318
2023-07-21 08:04:10 +03:00
Alexander Batalov
50d7c71db1 Clarify dragging flags 2023-07-20 11:13:01 +03:00
Alexander Batalov
b07a7bcefd Complete win_drag 2023-07-20 10:20:05 +03:00
Alexander Batalov
867d28ac62 Add rect_clip 2023-07-20 10:13:21 +03:00
Alexander Batalov
d9a173678a Cleanup timed msgs code 2023-07-20 09:39:15 +03:00
Alexander Batalov
dde3255b07 Fix endless loop while cleaning up timed msgs 2023-07-20 09:21:26 +03:00
Alexander Batalov
1506ae7048 Add win_timed_msg 2023-07-20 08:53:26 +03:00
Alexander Batalov
ce5d07e09c Add win_yes_no 2023-07-19 21:27:20 +03:00
Alexander Batalov
2d8a637f7d Force debug window font 2023-07-19 12:05:39 +03:00
Alexander Batalov
8414effc04 Fix GNW color indexes 2023-07-19 12:01:20 +03:00
Alexander Batalov
3a17818ceb Handle debug mode
Closes #298
2023-07-19 11:51:13 +03:00
Alexander Batalov
90d1545bb2 Uninline debug_register_func 2023-07-19 11:45:55 +03:00
Alexander Batalov
a7628ccaea Fix bufferDrawLine
Missing 1 pixel in the middle of the vertical line.
2023-07-19 11:43:10 +03:00
Alexander Batalov
3af2a49250 Review debug_register_log 2023-07-19 11:39:01 +03:00
Vlad
ffe90eef49 Improve code readability (#315) 2023-07-13 13:35:26 +03:00
Alexander Batalov
c4c2806071 Fix game time calculations (#307) 2023-07-13 13:04:31 +03:00
Alexander Batalov
fe035d8514 Improve loadsave.cc readability 2023-06-16 08:12:38 +03:00
c6
cf98070cd0 Add Sfall AutoQuickSave (#305) 2023-06-16 08:01:44 +03:00
Austin Hurst
0ffcb107af Implement SCALE_2X for Fallout 2 (#306) 2023-06-16 07:18:15 +03:00
Alexander Batalov
cf5f865a23 Add load/save global vars (#296) 2023-06-03 08:06:49 +03:00
Alexander Batalov
37e4822ed5 Add keyboard opcodes (#295) 2023-06-01 19:01:03 +03:00
Alexander Batalov
bf639a2c4a Fix copying files on case-sensitive file systems
Closes #273
2023-06-01 17:10:36 +03:00
Alexander Batalov
89839be3af Add global scripts (#294) 2023-05-31 21:48:44 +03:00
Alexander Batalov
ec722475b6 Add op_create_message_window
See #200
2023-05-30 14:21:50 +03:00
Alexander Batalov
32ed3c3271 Add FixNamespaceComments 2023-05-30 12:56:51 +03:00
Alexander Batalov
03bf507893 Add ini opcodes (#293) 2023-05-30 12:52:55 +03:00
Alexander Batalov
681b7c388b Fix sfall opcode comments 2023-05-30 09:12:51 +03:00
Vasilii Rogin
fe0d767521 Add SFall arrays (#269)
Co-authored-by: Alexander Batalov <alex.batalov@gmail.com>
2023-05-30 09:06:55 +03:00
Alexander Batalov
62c5c4757c Fix comparing pointers and integers
See #189
2023-05-24 21:52:50 +03:00
Vasilii Rogin
70b0b61664 Delete critter from combat during _partyFixMultipleMembers (#277)
Co-authored-by: Alexander Batalov <alex.batalov@gmail.com>
2023-05-24 21:32:09 +03:00
Vasilii Rogin
53a4437be9 Remove trailing comma after reading strParseIntWithKey (#259) 2023-05-23 23:51:04 +03:00
Vasilii Rogin
42c541012c Fix crash in _map_age_dead_critters (#258)
Co-authored-by: Alexander Batalov <alex.batalov@gmail.com>
2023-05-23 23:50:37 +03:00
Vlad
61293bd39c Fix ruined stack in rm_mult_objs_from_inven and name remaining opcodes (#289) 2023-05-23 23:45:18 +03:00
Alexander Batalov
d641fefc13 Fix open door sound
See alexbatalov/fallout1-ce#71
2023-05-23 23:43:00 +03:00
Alexander Batalov
666e5cf62d Fix mouse events processing
See alexbatalov/fallout1-ce#55
2023-05-23 23:32:11 +03:00
Alexander Batalov
2565900f90 Fix clang-format args
Looks like clang-format in Ubuntu does not recognize glob pattern as
macOS does. Previous solution without xargs reported status code of
find itself, not clang-format.
2023-05-18 23:32:16 +03:00
Alexander Batalov
6b6fa3f111 Fix code format check 2023-05-09 18:42:47 +03:00
Alexander Batalov
a06097aef5 Improve touch controls (#283) 2023-05-09 18:36:20 +03:00
Alexander Batalov
efdc2e0199 Bump setup-java to v3 (#278) 2023-05-01 07:54:14 +03:00
Alexander Batalov
d6a74468da Use Xcode for macOS builds (#275) 2023-05-01 07:10:04 +03:00
Alexander Batalov
fcf8a87603 Ignore channels in acm files (#274) 2023-04-27 10:14:41 +03:00
Alexander Batalov
a8815229a0 Add compat_access (#272) 2023-04-26 20:12:22 +03:00
Alexander Arkhipov
aa99b2e1d3 Convert file paths to correct case (#214) 2023-04-26 17:45:36 +03:00
Vasilii Rogin
63d8300c61 Add clang format (#270) 2023-04-26 15:35:02 +03:00
Alexander Batalov
81c3ff9b1a Improve iOS icon (#271) 2023-04-26 15:11:24 +03:00
Alexander Batalov
a0652e2646 Use Xcode for iOS builds (#267) 2023-04-26 14:11:26 +03:00
Alexander Batalov
df3ac30de6 Add blocking objects opcodes 2023-04-20 11:22:47 +03:00
Alexander Batalov
6ca1329720 Add op_get_attack_type 2023-04-20 10:51:20 +03:00
Alexander Batalov
129361836f Add op_get_mouse_buttons 2023-04-20 10:31:32 +03:00
Alexander Batalov
cf4921de1e Add op_tile_under_cursor 2023-04-20 10:25:13 +03:00
Alexander Batalov
ecc6a8679b Add math opcodes 2023-04-20 09:53:50 +03:00
Alexander Batalov
a39f149817 Add date/time opcodes 2023-04-19 19:10:09 +03:00
Alexander Batalov
540cc1e08b Add combat opcodes 2023-04-19 10:03:04 +03:00
Alexander Batalov
ef34fdb519 Add proto data opcodes 2023-04-19 09:21:38 +03:00
Alexander Batalov
9b02f600de Add worldmap opcodes 2023-04-19 09:09:17 +03:00
Alexander Batalov
0bb07dbd50 Add pc base stats opcodes 2023-04-19 09:02:54 +03:00
Vasilii Rogin
0a85ce520b Use stack on the heap for roof fill (#263) 2023-04-18 11:06:07 +03:00
Vasilii Rogin
99bc14cf3a Add sFall movie timer options (#261) 2023-04-14 19:03:21 +03:00
Vasilii Rogin
527e152297 Allow messageIndex to be zero (#264) 2023-04-14 18:40:37 +03:00
Alexander Batalov
c8d45854ba Normalize line endings when reading text files
Closes #250
2023-04-11 20:00:38 +03:00
Alexander Batalov
11472e8be9 Fix soundOpenData flags 2023-04-11 17:27:34 +03:00
Alexander Batalov
69e4adf5b3 Add HQ music support
See #239
2023-04-11 16:37:01 +03:00
Alexander Batalov
a2eabd668b Fix missing speech in some Russian localizations
Closes #246
2023-04-11 14:03:55 +03:00
Alexander Batalov
6d1273d325 Improve button functions readability 2023-04-11 09:01:14 +03:00
TomArnaez
e23b39abaa Fix crash in inventory list (#256) 2023-02-28 22:11:08 +03:00
Alexander Batalov
117b1d7b44 Fix iPad settings
Follow-up to alexbatalov/fallout1-ce#29
2023-02-28 20:31:19 +03:00
Alexander Batalov
6398f8a79e Fix itemDropAll
See #253
2023-02-28 16:11:48 +03:00
Alexander Batalov
81b9345303 Update config 2023-02-18 19:06:20 +03:00
Alexander Batalov
249892716e Get rid of mmx stuff 2023-02-18 18:14:30 +03:00
Alexander Batalov
3e8227a62b Extract mainmenu 2023-02-17 15:55:14 +03:00
Alexander Batalov
1570f860e8 Remove unnecessary calls 2023-02-17 15:53:42 +03:00
Alexander Batalov
d7c4589a55 Extract preferences 2023-02-17 12:33:26 +03:00
Alexander Batalov
0a9a1dc7ca Fix faulty frms
Closes #235
2023-02-16 15:46:49 +03:00
Alexander Batalov
42346f66b2 Update readme 2023-02-15 12:47:32 +03:00
Alexander Batalov
7ac651b736 Adjust modal dialogs position 2023-02-15 11:37:00 +03:00
Alexander Batalov
0bb822ba60 Fix "Affect player speed" font
Closes #245
2023-02-15 09:23:46 +03:00
Alexander Batalov
075de8f837 Review sound IO functions 2023-02-13 11:51:09 +03:00
Alexander Batalov
36b5ceba8a Improve sound_decoder.cc accuracy 2023-02-13 11:02:17 +03:00
Alexander Batalov
f5d3cfb5e3 Fix Fast Metabolism trait 2023-02-12 23:12:36 +03:00
Alexander Batalov
81210f46af Fix storing pointers in game global variables 2023-02-10 11:05:42 +03:00
Alexander Batalov
c14f671a0d Add object and string concatenation
Fixes #232
2023-02-10 09:27:10 +03:00
Alexander Batalov
33141672ed Use screen borders for scrolling worldmap 2023-02-10 09:00:59 +03:00
Alexander Batalov
28083cfea9 Fix talking head mood transition 2023-02-09 19:40:25 +03:00
Alexander Batalov
c9864741f3 Fix crash in artLockFrameDataReturningSize
Closes #231
2023-02-09 19:27:25 +03:00
Jiří Malák
5a230efd2b Properly handle path with spaces (#228) 2023-01-29 08:56:03 +03:00
Alexander Batalov
3aea6a98ef Fix loading custom interface frms 2023-01-21 15:24:18 +03:00
Alexander Batalov
ba49abcea6 Fix some scripts not being properly removed
Closes #224
2023-01-21 13:15:18 +03:00
Alexander Batalov
47f5be8340 Fix HP being used as AP 2023-01-20 14:16:43 +03:00
Alexander Batalov
d435185e9e Fix missing melee damage info 2023-01-20 14:12:03 +03:00
200 changed files with 17346 additions and 8945 deletions

View File

@@ -1,2 +1,3 @@
BasedOnStyle: WebKit
AllowShortIfStatementsOnASingleLine: WithoutElse
FixNamespaceComments: true

1
.gitattributes vendored
View File

@@ -7,6 +7,7 @@
*.java text eol=lf
*.json text eol=lf
*.md text eol=lf
*.mm text eol=lf
*.plist text eol=lf
*.pro text eol=lf
*.properties text eol=lf

View File

@@ -26,11 +26,23 @@ jobs:
sudo apt install cppcheck
- name: Clone
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: cppcheck
run: cppcheck --std=c++17 src/
code-format:
name: Code format check
runs-on: ubuntu-latest
steps:
- name: Clone
uses: actions/checkout@v4
- name: clang-format
run: find src -type f -name \*.cc -o -name \*.h | xargs clang-format --dry-run --Werror
android:
name: Android
@@ -38,17 +50,17 @@ jobs:
steps:
- name: Clone
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Setup Java
uses: actions/setup-java@v2
uses: actions/setup-java@v3
with:
distribution: temurin
java-version: 11
cache: gradle
- name: Cache cmake build
uses: actions/cache@v3
uses: actions/cache@v4
with:
path: os/android/app/.cxx
key: android-cmake-v1
@@ -69,7 +81,7 @@ jobs:
./gradlew assembleDebug
- name: Upload
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: fallout2-ce-debug.apk
path: os/android/app/build/outputs/apk/debug/app-debug.apk
@@ -78,43 +90,44 @@ jobs:
ios:
name: iOS
runs-on: macos-11
runs-on: macos-12
steps:
- name: Clone
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Cache cmake build
uses: actions/cache@v3
uses: actions/cache@v4
with:
path: build
key: ios-cmake-v1
key: ios-cmake-v2
- name: Configure
run: |
cmake \
-B build \
-D CMAKE_BUILD_TYPE=RelWithDebInfo \
-D CMAKE_TOOLCHAIN_FILE=cmake/toolchain/ios.toolchain.cmake \
-D ENABLE_BITCODE=0 \
-D PLATFORM=OS64 \
-G Xcode \
-D CMAKE_XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY='' \
# EOL
- name: Build
run: |
cmake \
--build build \
--config RelWithDebInfo \
-j $(sysctl -n hw.physicalcpu) \
--target package \
# EOL
# TODO: Should be a part of packaging.
- name: Prepare for uploading
- name: Pack
run: |
cp build/fallout2-ce.zip build/fallout2-ce.ipa
cd build
cpack -C RelWithDebInfo
- name: Upload
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: fallout2-ce.ipa
path: build/fallout2-ce.ipa
@@ -134,7 +147,7 @@ jobs:
steps:
- name: Clone
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Dependencies (x86)
if: matrix.arch == 'x86'
@@ -151,7 +164,7 @@ jobs:
sudo apt install libsdl2-dev zlib1g-dev
- name: Cache cmake build
uses: actions/cache@v3
uses: actions/cache@v4
with:
path: build
key: linux-${{ matrix.arch }}-cmake-v1
@@ -181,7 +194,7 @@ jobs:
# EOL
- name: Upload
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: fallout2-ce-linux-${{ matrix.arch }}
path: build/fallout2-ce
@@ -194,34 +207,40 @@ jobs:
steps:
- name: Clone
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Cache cmake build
uses: actions/cache@v3
uses: actions/cache@v4
with:
path: build
key: macos-cmake-v3
key: macos-cmake-v4
- name: Configure
run: |
cmake \
-B build \
-D CMAKE_BUILD_TYPE=RelWithDebInfo \
-G Xcode \
-D CMAKE_XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY='' \
# EOL
- name: Build
run: |
cmake \
--build build \
--config RelWithDebInfo \
-j $(sysctl -n hw.physicalcpu) \
--target package \
# EOL
- name: Pack
run: |
cd build
cpack -C RelWithDebInfo
- name: Upload
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: fallout2-ce-macos.dmg
path: build/fallout2-ce.dmg
path: build/Fallout II Community Edition.dmg
retention-days: 7
windows:
@@ -240,10 +259,10 @@ jobs:
steps:
- name: Clone
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Cache cmake build
uses: actions/cache@v3
uses: actions/cache@v4
with:
path: build
key: windows-${{ matrix.arch }}-cmake-v1
@@ -264,7 +283,7 @@ jobs:
# EOL
- name: Upload
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: fallout2-ce-windows-${{ matrix.arch }}
path: build/RelWithDebInfo/fallout2-ce.exe

View File

@@ -17,17 +17,17 @@ jobs:
steps:
- name: Clone
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Setup Java
uses: actions/setup-java@v2
uses: actions/setup-java@v3
with:
distribution: temurin
java-version: 11
cache: gradle
- name: Cache cmake build
uses: actions/cache@v3
uses: actions/cache@v4
with:
path: os/android/app/.cxx
key: android-cmake-v1
@@ -51,7 +51,7 @@ jobs:
run: |
cd os/android/app/build/outputs/apk/release
cp app-release.apk fallout2-ce-android.apk
gh release upload ${{ github.ref_name }} fallout2-ce-android.apk
gh release upload ${{ github.event.release.tag_name }} fallout2-ce-android.apk
rm fallout2-ce-android.apk
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@@ -59,14 +59,14 @@ jobs:
ios:
name: iOS
runs-on: macos-11
runs-on: macos-12
steps:
- name: Clone
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Cache cmake build
uses: actions/cache@v3
uses: actions/cache@v4
with:
path: build
key: ios-cmake-v1
@@ -75,25 +75,31 @@ jobs:
run: |
cmake \
-B build \
-D CMAKE_BUILD_TYPE=RelWithDebInfo \
-D CMAKE_TOOLCHAIN_FILE=cmake/toolchain/ios.toolchain.cmake \
-D ENABLE_BITCODE=0 \
-D PLATFORM=OS64 \
-G Xcode \
-D CMAKE_XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY='' \
# EOL
- name: Build
run: |
cmake \
--build build \
--config RelWithDebInfo \
-j $(sysctl -n hw.physicalcpu) \
--target package \
# EOL
- name: Pack
run: |
cd build
cpack -C RelWithDebInfo
- name: Upload
run: |
cd build
cp fallout2-ce.zip fallout2-ce-ios.ipa
gh release upload ${{ github.ref_name }} fallout2-ce-ios.ipa
cp fallout2-ce.ipa fallout2-ce-ios.ipa
gh release upload ${{ github.event.release.tag_name }} fallout2-ce-ios.ipa
rm fallout2-ce-ios.ipa
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@@ -112,7 +118,7 @@ jobs:
steps:
- name: Clone
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Dependencies (x86)
if: matrix.arch == 'x86'
@@ -129,7 +135,7 @@ jobs:
sudo apt install libsdl2-dev zlib1g-dev
- name: Cache cmake build
uses: actions/cache@v3
uses: actions/cache@v4
with:
path: build
key: linux-${{ matrix.arch }}-cmake-v1
@@ -162,7 +168,7 @@ jobs:
run: |
cd build
tar -czvf fallout2-ce-linux-${{ matrix.arch }}.tar.gz fallout2-ce
gh release upload ${{ github.ref_name }} fallout2-ce-linux-${{ matrix.arch }}.tar.gz
gh release upload ${{ github.event.release.tag_name }} fallout2-ce-linux-${{ matrix.arch }}.tar.gz
rm fallout2-ce-linux-${{ matrix.arch }}.tar.gz
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@@ -174,16 +180,16 @@ jobs:
steps:
- name: Clone
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Import code signing certificates
uses: apple-actions/import-codesign-certs@v1
uses: apple-actions/import-codesign-certs@v2
with:
p12-file-base64: ${{ secrets.APPLE_DEVELOPER_CERTIFICATE_P12_FILE_BASE64 }}
p12-password: ${{ secrets.APPLE_DEVELOPER_CERTIFICATE_P12_PASSWORD }}
- name: Cache cmake build
uses: actions/cache@v3
uses: actions/cache@v4
with:
path: build
key: macos-cmake-v3
@@ -192,41 +198,44 @@ jobs:
run: |
cmake \
-B build \
-D CMAKE_BUILD_TYPE=RelWithDebInfo \
-D CPACK_BUNDLE_APPLE_CERT_APP="${{ secrets.APPLE_DEVELOPER_CERTIFICATE_IDENTITY }}" \
-G Xcode \
-D CMAKE_XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY="${{ secrets.APPLE_DEVELOPER_CERTIFICATE_IDENTITY }}" \
-D CMAKE_XCODE_ATTRIBUTE_CODE_SIGN_INJECT_BASE_ENTITLEMENTS="NO" \
-D CMAKE_XCODE_ATTRIBUTE_OTHER_CODE_SIGN_FLAGS="--options=runtime --timestamp" \
# EOL
- name: Build
run: |
cmake \
--build build \
--config RelWithDebInfo \
-j $(sysctl -n hw.physicalcpu) \
--target package \
# EOL
- name: Pack
run: |
cd build
cpack -C RelWithDebInfo
- name: Notarize
run: |
brew install mitchellh/gon/gon
cat << EOF > config.json
{
"notarize": {
"path": "build/fallout2-ce.dmg",
"bundle_id": "$(/usr/libexec/PlistBuddy -c "Print :CFBundleIdentifier" build/fallout2-ce.app/Contents/Info.plist)",
"staple": true
}
}
EOF
gon config.json
rm config.json
env:
AC_USERNAME: ${{ secrets.APPLE_DEVELOPER_AC_USERNAME }}
AC_PASSWORD: ${{ secrets.APPLE_DEVELOPER_AC_PASSWORD }}
xcrun notarytool submit \
"build/Fallout II Community Edition.dmg" \
--apple-id "${{ secrets.APPLE_DEVELOPER_AC_USERNAME }}" \
--team-id "${{ secrets.APPLE_DEVELOPER_AC_TEAM }}" \
--password "${{ secrets.APPLE_DEVELOPER_AC_PASSWORD }}" \
--wait
- name: Staple
run: |
xcrun stapler staple \
"build/Fallout II Community Edition.dmg"
- name: Upload
run: |
cd build
cp fallout2-ce.dmg fallout2-ce-macos.dmg
gh release upload ${{ github.ref_name }} fallout2-ce-macos.dmg
cp "Fallout II Community Edition.dmg" fallout2-ce-macos.dmg
gh release upload ${{ github.event.release.tag_name }} fallout2-ce-macos.dmg
rm fallout2-ce-macos.dmg
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@@ -247,10 +256,10 @@ jobs:
steps:
- name: Clone
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Cache cmake build
uses: actions/cache@v3
uses: actions/cache@v4
with:
path: build
key: windows-${{ matrix.arch }}-cmake-v1
@@ -274,7 +283,7 @@ jobs:
run: |
cd build/RelWithDebInfo
7z a fallout2-ce-windows-${{ matrix.arch }}.zip fallout2-ce.exe
gh release upload ${{ github.ref_name }} fallout2-ce-windows-${{ matrix.arch }}.zip
gh release upload ${{ github.event.release.tag_name }} fallout2-ce-windows-${{ matrix.arch }}.zip
rm fallout2-ce-windows-${{ matrix.arch }}.zip
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

View File

@@ -4,7 +4,7 @@ set(CMAKE_POLICY_DEFAULT_CMP0077 NEW)
set(EXECUTABLE_NAME fallout2-ce)
if (APPLE)
if(APPLE)
if(IOS)
set(CMAKE_OSX_DEPLOYMENT_TARGET "11" CACHE STRING "")
set(CMAKE_OSX_ARCHITECTURES "arm64" CACHE STRING "")
@@ -20,7 +20,7 @@ set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED YES)
set(CMAKE_CXX_EXTENSIONS NO)
if (ANDROID)
if(ANDROID)
add_library(${EXECUTABLE_NAME} SHARED)
else()
add_executable(${EXECUTABLE_NAME} WIN32 MACOSX_BUNDLE)
@@ -140,6 +140,8 @@ target_sources(${EXECUTABLE_NAME} PUBLIC
"src/loadsave.h"
"src/main.cc"
"src/main.h"
"src/mainmenu.cc"
"src/mainmenu.h"
"src/map_defs.h"
"src/map.cc"
"src/map.h"
@@ -150,8 +152,6 @@ target_sources(${EXECUTABLE_NAME} PUBLIC
"src/memory.h"
"src/message.cc"
"src/message.h"
"src/mmx.cc"
"src/mmx.h"
"src/mouse_manager.cc"
"src/mouse_manager.h"
"src/mouse.cc"
@@ -253,22 +253,38 @@ target_sources(${EXECUTABLE_NAME} PUBLIC
target_sources(${EXECUTABLE_NAME} PUBLIC
"src/audio_engine.cc"
"src/audio_engine.h"
"src/delay.cc"
"src/delay.h"
"src/fps_limiter.cc"
"src/fps_limiter.h"
"src/platform_compat.cc"
"src/platform_compat.h"
"src/pointer_registry.cc"
"src/pointer_registry.h"
"src/preferences.cc"
"src/preferences.h"
"src/settings.cc"
"src/settings.h"
"src/sfall_config.cc"
"src/sfall_config.h"
"src/sfall_global_vars.cc"
"src/sfall_global_vars.h"
"src/sfall_global_scripts.cc"
"src/sfall_global_scripts.h"
"src/sfall_ini.cc"
"src/sfall_ini.h"
"src/sfall_kb_helpers.cc"
"src/sfall_kb_helpers.h"
"src/sfall_lists.cc"
"src/sfall_lists.h"
"src/sfall_metarules.cc"
"src/sfall_metarules.h"
"src/sfall_opcodes.cc"
"src/sfall_opcodes.h"
"src/sfall_arrays.cc"
"src/sfall_arrays.h"
"src/touch.cc"
"src/touch.h"
)
if(IOS)
@@ -282,11 +298,8 @@ if(WIN32)
target_compile_definitions(${EXECUTABLE_NAME} PUBLIC
_CRT_SECURE_NO_WARNINGS
_CRT_NONSTDC_NO_WARNINGS
)
else()
target_compile_definitions(${EXECUTABLE_NAME} PRIVATE
$<$<CONFIG:Debug>:_DEBUG>
$<$<CONFIG:RelWithDebInfo>:_DEBUG>
NOMINMAX
WIN32_LEAN_AND_MEAN
)
endif()
@@ -296,7 +309,7 @@ if(WIN32)
)
endif()
if (WIN32)
if(WIN32)
target_sources(${EXECUTABLE_NAME} PUBLIC
"os/windows/fallout2-ce.ico"
"os/windows/fallout2-ce.rc"
@@ -304,31 +317,54 @@ if (WIN32)
endif()
if(APPLE)
target_sources(${EXECUTABLE_NAME} PUBLIC "os/macos/fallout2-ce.icns")
set_source_files_properties("os/macos/fallout2-ce.icns" PROPERTIES MACOSX_PACKAGE_LOCATION "Resources")
if(IOS)
target_sources(${EXECUTABLE_NAME} PUBLIC "os/ios/LaunchScreen.storyboard")
set_source_files_properties("os/ios/LaunchScreen.storyboard" PROPERTIES MACOSX_PACKAGE_LOCATION "Resources")
set_target_properties(${EXECUTABLE_NAME} PROPERTIES MACOSX_BUNDLE_INFO_PLIST "${CMAKE_SOURCE_DIR}/os/ios/Info.plist")
set_target_properties(${EXECUTABLE_NAME} PROPERTIES XCODE_ATTRIBUTE_TARGETED_DEVICE_FAMILY "1,2")
set(RESOURCES
"os/ios/AppIcon.xcassets"
"os/ios/LaunchScreen.storyboard"
)
target_sources(${EXECUTABLE_NAME} PUBLIC ${RESOURCES})
set_source_files_properties(${RESOURCES} PROPERTIES MACOSX_PACKAGE_LOCATION "Resources")
set_target_properties(${EXECUTABLE_NAME} PROPERTIES
MACOSX_BUNDLE_INFO_PLIST "${CMAKE_SOURCE_DIR}/os/ios/Info.plist"
XCODE_ATTRIBUTE_ASSETCATALOG_COMPILER_APPICON_NAME "AppIcon"
XCODE_ATTRIBUTE_PRODUCT_BUNDLE_IDENTIFIER "com.alexbatalov.fallout2-ce"
XCODE_ATTRIBUTE_TARGETED_DEVICE_FAMILY "1,2"
)
set(MACOSX_BUNDLE_BUNDLE_NAME "${EXECUTABLE_NAME}")
set(MACOSX_BUNDLE_DISPLAY_NAME "Fallout 2")
else()
set_target_properties(${EXECUTABLE_NAME} PROPERTIES MACOSX_BUNDLE_INFO_PLIST "${CMAKE_SOURCE_DIR}/os/macos/Info.plist")
set(RESOURCES
"os/macos/fallout2-ce.icns"
)
target_sources(${EXECUTABLE_NAME} PUBLIC ${RESOURCES})
set_source_files_properties(${RESOURCES} PROPERTIES MACOSX_PACKAGE_LOCATION "Resources")
set_target_properties(${EXECUTABLE_NAME} PROPERTIES
OUTPUT_NAME "Fallout II Community Edition"
MACOSX_BUNDLE_INFO_PLIST "${CMAKE_SOURCE_DIR}/os/macos/Info.plist"
XCODE_ATTRIBUTE_EXECUTABLE_NAME "${EXECUTABLE_NAME}"
XCODE_ATTRIBUTE_PRODUCT_BUNDLE_IDENTIFIER "com.alexbatalov.fallout2-ce"
)
set(MACOSX_BUNDLE_ICON_FILE "fallout2-ce.icns")
set(MACOSX_BUNDLE_BUNDLE_NAME "Fallout II: Community Edition")
set(MACOSX_BUNDLE_DISPLAY_NAME "Fallout II")
endif()
set(MACOSX_BUNDLE_GUI_IDENTIFIER "com.alexbatalov.fallout2-ce")
set(MACOSX_BUNDLE_BUNDLE_NAME "${EXECUTABLE_NAME}")
set(MACOSX_BUNDLE_ICON_FILE "fallout2-ce.icns")
set(MACOSX_BUNDLE_DISPLAY_NAME "Fallout 2")
set(MACOSX_BUNDLE_SHORT_VERSION_STRING "1.2.0")
set(MACOSX_BUNDLE_BUNDLE_VERSION "1.2.0")
set(MACOSX_BUNDLE_SHORT_VERSION_STRING "1.3.0")
set(MACOSX_BUNDLE_BUNDLE_VERSION "1.3.0")
endif()
add_subdirectory("third_party/fpattern")
target_link_libraries(${EXECUTABLE_NAME} ${FPATTERN_LIBRARY})
target_include_directories(${EXECUTABLE_NAME} PRIVATE ${FPATTERN_INCLUDE_DIR})
if(NOT ${CMAKE_SYSTEM_NAME} MATCHES "Linux")
if((NOT ${CMAKE_SYSTEM_NAME} MATCHES "Linux") AND (NOT ${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD") AND (NOT ${CMAKE_SYSTEM_NAME} MATCHES "OpenBSD"))
add_subdirectory("third_party/zlib")
add_subdirectory("third_party/sdl2")
else()
@@ -349,24 +385,13 @@ if(APPLE)
set(CPACK_GENERATOR "ZIP")
set(CPACK_INCLUDE_TOPLEVEL_DIRECTORY OFF)
set(CPACK_PACKAGE_FILE_NAME "fallout2-ce")
set(CPACK_ARCHIVE_FILE_EXTENSION "ipa")
else()
install(TARGETS ${EXECUTABLE_NAME} DESTINATION .)
install(CODE "
include(BundleUtilities)
fixup_bundle(${CMAKE_BINARY_DIR}/${MACOSX_BUNDLE_BUNDLE_NAME}.app \"\" \"\")
"
COMPONENT Runtime)
if (CPACK_BUNDLE_APPLE_CERT_APP)
install(CODE "
execute_process(COMMAND codesign --deep --force --options runtime --sign \"${CPACK_BUNDLE_APPLE_CERT_APP}\" ${CMAKE_BINARY_DIR}/${MACOSX_BUNDLE_BUNDLE_NAME}.app)
"
COMPONENT Runtime)
endif()
set(CPACK_GENERATOR "DragNDrop")
set(CPACK_DMG_DISABLE_APPLICATIONS_SYMLINK ON)
set(CPACK_PACKAGE_FILE_NAME "fallout2-ce")
set(CPACK_PACKAGE_FILE_NAME "Fallout II Community Edition")
endif()
include(CPack)

View File

@@ -1,8 +1,14 @@
# Fallout 2 Community Edition
Fallout 2 Community Edition is a fully working re-implementation of Fallout 2, with the same original gameplay, engine bugfixes, and some quality of life improvements, that works (mostly) hassle-free on multiple platforms.
Popular Fallout 2 total conversion mods are partially supported. Original versions of Nevada and Sonora (that do not rely on extended features provided by Sfall) likely work, although there is no complete walkthrough confirmation yet. [Fallout 2 Restoration Project](https://github.com/BGforgeNet/Fallout2_Restoration_Project), [Fallout Et Tu](https://github.com/rotators/Fo1in2) and [Olympus 2207](https://olympus2207.com) are not yet supported. Other mods (particularly Resurrection and Yesterday) are not tested.
There is also [Fallout Community Edition](https://github.com/alexbatalov/fallout1-ce).
## Installation
You must own the game to play. Purchase your copy on [GOG](https://www.gog.com/game/fallout_2) or [Steam](https://store.steampowered.com/app/38410). Download latest release or build from source.
You must own the game to play. Purchase your copy on [GOG](https://www.gog.com/game/fallout_2) or [Steam](https://store.steampowered.com/app/38410). Download latest [release](https://github.com/alexbatalov/fallout2-ce/releases) or build from source. You can also check latest [debug](https://github.com/alexbatalov/fallout2-ce/actions) build intended for testers.
### Windows
@@ -36,13 +42,19 @@ $ sudo apt install libsdl2-2.0-0
### Android
> **NOTE**: Fallout 2 was designed with mouse in mind. There are many controls that require precise cursor positioning, which is not possible with fingers. When playing on Android you'll use fingers to move mouse cursor, not a character, or a map. Double tap to "click" left mouse button in the current cursor position, triple tap to "click" right mouse button. It might feel awkward at first, but it's super handy - you can play with just a thumb. This is not set in stone and might change in the future.
> **NOTE**: Fallout 2 was designed with mouse in mind. There are many controls that require precise cursor positioning, which is not possible with fingers. Current control scheme resembles trackpad usage:
- One finger moves mouse cursor around.
- Tap one finger for left mouse click.
- Tap two fingers for right mouse click (switches mouse cursor mode).
- Move two fingers to scroll current view (map view, worldmap view, inventory scrollers).
- Use Windows installation as a base - it contains data assets needed to play. Copy `Fallout2` folder to your device, for example to `Downloads`. You need `master.dat`, `critter.dat`, `patch000.dat`, and `data` folder.
> **NOTE**: From Android standpoint release and debug builds are different apps. Both apps require their own copy of game assets and have their own savegames. This is intentional. As a gamer just stick with release version and check for updates.
- Use Windows installation as a base - it contains data assets needed to play. Copy `Fallout2` folder to your device, for example to `Downloads`. You need `master.dat`, `critter.dat`, `patch000.dat`, and `data` folder. Watch for file names - keep (or make) them lowercased (see [Configuration](#configuration)).
- Download `fallout2-ce.apk` and copy it to your device. Open it with file explorer, follow instructions (install from unknown source).
- When you run the game for the first time it will immediately present file picker. Select the folder from the first step. Wait until this data is copied. A loading dialog will appear, just wait for about 30 seconds. The game will start automatically.
- When you run the game for the first time it will immediately present file picker. Select the folder from the first step. Wait until this data is copied. A loading dialog will appear, just wait for about 30 seconds. If you're installing total conversion mod or localized version with a large number of unpacked resources in `data` folder it can take up to 20 minutes. Once copied, the game will start automatically.
### iOS
@@ -52,7 +64,31 @@ $ sudo apt install libsdl2-2.0-0
- Run the game once. You'll see error message saying "Couldn't find/load text fonts". This step is needed for iOS to expose the game via File Sharing feature.
- Use Finder (macOS Catalina and later) or iTunes (Windows and macOS Mojave or earlier) to copy `master.dat`, `critter.dat`, `patch000.dat`, and `data` folder to "Fallout 2" app ([how-to](https://support.apple.com/HT210598)).
- Use Finder (macOS Catalina and later) or iTunes (Windows and macOS Mojave or earlier) to copy `master.dat`, `critter.dat`, `patch000.dat`, and `data` folder to "Fallout 2" app ([how-to](https://support.apple.com/HT210598)). Watch for file names - keep (or make) them lowercased (see [Configuration](#configuration)).
## Configuration
The main configuration file is `fallout2.cfg`. There are several important settings you might need to adjust for your installation. Depending on your Fallout distribution main game assets `master.dat`, `critter.dat`, `patch000.dat`, and `data` folder might be either all lowercased, or all uppercased. You can either update `master_dat`, `critter_dat`, `master_patches` and `critter_patches` settings to match your file names, or rename files to match entries in your `fallout2.cfg`.
The `sound` folder (with `music` folder inside) might be located either in `data` folder, or be in the Fallout folder. Update `music_path1` setting to match your hierarchy, usually it's `data/sound/music/` or `sound/music/`. Make sure it matches your path exactly (so it might be `SOUND/MUSIC/` if you've installed Fallout from CD). Music files themselves (with `ACM` extension) should be all uppercased, regardless of `sound` and `music` folders.
The second configuration file is `f2_res.ini`. Use it to change game window size and enable/disable fullscreen mode.
```ini
[MAIN]
SCR_WIDTH=1280
SCR_HEIGHT=720
WINDOWED=1
```
Recommendations:
- **Desktops**: Use any size you see fit.
- **Tablets**: Set these values to logical resolution of your device, for example iPad Pro 11 is 1668x2388 (pixels), but it's logical resolution is 834x1194 (points).
- **Mobile phones**: Set height to 480, calculate width according to your device screen (aspect) ratio, for example Samsung S21 is 20:9 device, so the width should be 480 * 20 / 9 = 1067.
In time this stuff will receive in-game interface, right now you have to do it manually.
The third configuration file is `ddraw.ini` (part of Sfall). There are dozens of options that adjust or override engine behaviour and gameplay mechanics. This file is intended for modders and advanced users. Currently only a small subset of these settings are actually implemented.
## Contributing

View File

@@ -9,8 +9,8 @@ android {
applicationId 'com.alexbatalov.fallout2ce'
minSdk 21
targetSdk 32
versionCode 3
versionName '1.2.0'
versionCode 4
versionName '1.3.0'
externalNativeBuild {
cmake {
arguments '-DANDROID_STL=c++_static'

Binary file not shown.

After

Width:  |  Height:  |  Size: 1009 KiB

View File

@@ -0,0 +1,14 @@
{
"images" : [
{
"filename" : "AppIcon.png",
"idiom" : "universal",
"platform" : "ios",
"size" : "1024x1024"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@@ -0,0 +1,6 @@
{
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@@ -8,8 +8,6 @@
<string>${MACOSX_BUNDLE_DISPLAY_NAME}</string>
<key>CFBundleExecutable</key>
<string>${MACOSX_BUNDLE_EXECUTABLE_NAME}</string>
<key>CFBundleIconFile</key>
<string>${MACOSX_BUNDLE_ICON_FILE}</string>
<key>CFBundleIdentifier</key>
<string>${MACOSX_BUNDLE_GUI_IDENTIFIER}</string>
<key>CFBundleInfoDictionaryVersion</key>
@@ -22,12 +20,12 @@
<string>${MACOSX_BUNDLE_SHORT_VERSION_STRING}</string>
<key>CFBundleVersion</key>
<string>${MACOSX_BUNDLE_BUNDLE_VERSION}</string>
<key>LSApplicationCategoryType</key>
<string>public.app-category.role-playing-games</string>
<key>LSMinimumSystemVersion</key>
<string>11.0</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>LSSupportsOpeningDocumentsInPlace</key>
<true/>
<key>NSHighResolutionCapable</key>
<string>True</string>
<key>UIApplicationSupportsIndirectInputEvents</key>
@@ -49,8 +47,6 @@
<array>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
</array>
</dict>
</plist>

View File

@@ -3,7 +3,7 @@
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<string>en</string>
<key>CFBundleDisplayName</key>
<string>${MACOSX_BUNDLE_DISPLAY_NAME}</string>
<key>CFBundleExecutable</key>
@@ -28,6 +28,8 @@
<string>${MACOSX_BUNDLE_COPYRIGHT}</string>
<key>NSHighResolutionCapable</key>
<string>True</string>
<key>LSApplicationCategoryType</key>
<string>public.app-category.role-playing-games</string>
<key>LSMinimumSystemVersion</key>
<string>10.11</string>
<key>SDL_FILESYSTEM_BASE_DIR_TYPE</key>

View File

@@ -48,6 +48,9 @@ typedef enum ScienceRepairTargetType {
// 0x5106D0
static bool _action_in_explode = false;
// 0x5106D4
int rotation;
// 0x5106E0
static const int gNormalDeathAnimations[DAMAGE_TYPE_COUNT] = {
ANIM_DANCING_AUTOFIRE,
@@ -85,7 +88,7 @@ static int _is_next_to(Object* a1, Object* a2);
static int _action_climb_ladder(Object* a1, Object* a2);
static int _action_use_skill_in_combat_error(Object* critter);
static int _pick_fall(Object* obj, int anim);
static int _report_explosion(Attack* attack, Object* a2);
static int _report_explosion(Attack* attack, Object* sourceObj);
static int _finished_explosion(Object* a1, Object* a2);
static int _compute_explosion_damage(int min, int max, Object* defender, int* knockbackDistancePtr);
static int _can_talk_to(Object* a1, Object* a2);
@@ -118,7 +121,7 @@ int actionKnockdown(Object* obj, int* anim, int maxDistance, int rotation, int d
int tile;
for (distance = 1; distance <= maxDistance; distance++) {
tile = tileGetTileInDirection(obj->tile, rotation, distance);
if (_obj_blocking_at(obj, tile, obj->elevation) != NULL) {
if (_obj_blocking_at(obj, tile, obj->elevation) != nullptr) {
distance--;
break;
}
@@ -184,7 +187,7 @@ int _pick_death(Object* attacker, Object* defender, Object* weapon, int damage,
int damageType = weaponGetDamageType(attacker, weapon);
if (weapon != NULL && weapon->pid == PROTO_ID_MOLOTOV_COCKTAIL) {
if (weapon != nullptr && weapon->pid == PROTO_ID_MOLOTOV_COCKTAIL) {
normalViolenceLevelDamageThreshold = 5;
maximumBloodViolenceLevelDamageThreshold = 15;
damageType = DAMAGE_TYPE_FIRE;
@@ -196,7 +199,7 @@ int _pick_death(Object* attacker, Object* defender, Object* weapon, int damage,
maximumBloodViolenceLevelDamageThreshold = 1;
}
if (weapon != NULL && weaponGetPerk(weapon) == PERK_WEAPON_FLAMEBOY) {
if (weapon != nullptr && weaponGetPerk(weapon) == PERK_WEAPON_FLAMEBOY) {
normalViolenceLevelDamageThreshold /= 3;
maximumBloodViolenceLevelDamageThreshold /= 3;
}
@@ -368,9 +371,9 @@ void _show_damage_to_object(Object* defender, int damage, int flags, Object* wea
while (true) {
int tile = tileGetTileInDirection(defender->tile, (rotation + randomRotation) % ROTATION_COUNT, distance);
if (!isExitGridAt(tile, defender->elevation)) {
Object* obstacle = NULL;
_make_straight_path(defender, defender->tile, tile, NULL, &obstacle, 4);
if (obstacle == NULL) {
Object* obstacle = nullptr;
_make_straight_path(defender, defender->tile, tile, nullptr, &obstacle, 4);
if (obstacle == nullptr) {
animationRegisterRotateToTile(defender, tile);
animationRegisterMoveToTileStraight(defender, tile, defender->elevation, anim, 0);
break;
@@ -440,7 +443,7 @@ void _show_damage_to_object(Object* defender, int damage, int flags, Object* wea
}
}
if (weapon != NULL) {
if (weapon != nullptr) {
if ((flags & DAM_EXPLODE) != 0) {
animationRegisterCallbackForced(defender, weapon, (AnimationCallback*)_obj_drop, -1);
fid = buildFid(OBJ_TYPE_MISC, 10, 0, 0, 0);
@@ -541,7 +544,7 @@ void _show_damage(Attack* attack, int attackerAnimation, int delay)
_show_damage_to_object(attack->attacker, attack->attackerDamage, attack->attackerFlags, attack->weapon, 1, 0, 0, attackerAnimation, attack->attacker, -1);
}
} else {
if (attack->defender != NULL) {
if (attack->defender != nullptr) {
// NOTE: Uninline.
bool hitFromFront = _is_hit_from_front(attack->defender, attack->attacker);
@@ -606,7 +609,7 @@ int _action_melee(Attack* attack, int anim)
fid = buildFid(OBJ_TYPE_CRITTER, attack->attacker->fid & 0xFFF, anim, (attack->attacker->fid & 0xF000) >> 12, attack->attacker->rotation + 1);
art = artLock(fid, &cache_entry);
if (art != NULL) {
if (art != nullptr) {
delay = artGetActionFrame(art);
} else {
delay = 0;
@@ -646,7 +649,7 @@ int _action_melee(Attack* attack, int anim)
} else {
fid = buildFid(OBJ_TYPE_CRITTER, attack->defender->fid & 0xFFF, ANIM_DODGE_ANIM, (attack->defender->fid & 0xF000) >> 12, attack->defender->rotation + 1);
art = artLock(fid, &cache_entry);
if (art != NULL) {
if (art != nullptr) {
int dodgeDelay = artGetActionFrame(art);
artUnlock(cache_entry);
@@ -690,14 +693,14 @@ int _action_ranged(Attack* attack, int anim)
{
Object* adjacentObjects[ROTATION_COUNT];
for (int rotation = 0; rotation < ROTATION_COUNT; rotation++) {
adjacentObjects[rotation] = NULL;
adjacentObjects[rotation] = nullptr;
}
reg_anim_begin(ANIMATION_REQUEST_RESERVED);
_register_priority(1);
Object* projectile = NULL;
Object* replacedWeapon = NULL;
Object* projectile = nullptr;
Object* replacedWeapon = nullptr;
int weaponFid = -1;
Proto* weaponProto;
@@ -707,7 +710,7 @@ int _action_ranged(Attack* attack, int anim)
int fid = buildFid(OBJ_TYPE_CRITTER, attack->attacker->fid & 0xFFF, anim, (attack->attacker->fid & 0xF000) >> 12, attack->attacker->rotation + 1);
CacheEntry* artHandle;
Art* art = artLock(fid, &artHandle);
int delay = (art != NULL) ? artGetActionFrame(art) : 0;
int delay = (art != nullptr) ? artGetActionFrame(art) : 0;
artUnlock(artHandle);
weaponGetRange(attack->attacker, attack->hitMode);
@@ -758,11 +761,11 @@ int _action_ranged(Attack* attack, int anim)
itemRemove(attack->attacker, weapon, 1);
replacedWeapon = itemReplace(attack->attacker, weapon, weaponFlags & OBJECT_IN_ANY_HAND);
objectSetFid(projectile, projectileProto->fid, NULL);
objectSetFid(projectile, projectileProto->fid, nullptr);
_cAIPrepWeaponItem(attack->attacker, weapon);
if (attack->attacker == gDude) {
if (replacedWeapon == NULL) {
if (replacedWeapon == nullptr) {
if ((weaponFlags & OBJECT_IN_LEFT_HAND) != 0) {
leftItemAction = INTERFACE_ITEM_ACTION_DEFAULT;
} else if ((weaponFlags & OBJECT_IN_RIGHT_HAND) != 0) {
@@ -772,25 +775,25 @@ int _action_ranged(Attack* attack, int anim)
interfaceUpdateItems(false, leftItemAction, rightItemAction);
}
_obj_connect(weapon, attack->attacker->tile, attack->attacker->elevation, NULL);
_obj_connect(weapon, attack->attacker->tile, attack->attacker->elevation, nullptr);
} else {
objectCreateWithFidPid(&projectile, projectileProto->fid, -1);
}
objectHide(projectile, NULL);
objectHide(projectile, nullptr);
// SFALL
if (explosionEmitsLight() && projectile->lightIntensity == 0) {
objectSetLight(projectile, projectileProto->item.lightDistance, projectileProto->item.lightIntensity, NULL);
objectSetLight(projectile, projectileProto->item.lightDistance, projectileProto->item.lightIntensity, nullptr);
} else {
objectSetLight(projectile, 9, projectile->lightIntensity, NULL);
objectSetLight(projectile, 9, projectile->lightIntensity, nullptr);
}
int projectileOrigin = _combat_bullet_start(attack->attacker, attack->defender);
objectSetLocation(projectile, projectileOrigin, attack->attacker->elevation, NULL);
objectSetLocation(projectile, projectileOrigin, attack->attacker->elevation, nullptr);
int projectileRotation = tileGetRotationTo(attack->attacker->tile, attack->defender->tile);
objectSetRotation(projectile, projectileRotation, NULL);
objectSetRotation(projectile, projectileRotation, nullptr);
animationRegisterUnsetFlag(projectile, OBJECT_HIDDEN, delay);
@@ -800,7 +803,7 @@ int _action_ranged(Attack* attack, int anim)
int explosionCenterTile;
if ((attack->attackerFlags & DAM_HIT) != 0) {
animationRegisterMoveToTileStraight(projectile, attack->defender->tile, attack->defender->elevation, ANIM_WALK, 0);
delay = _make_straight_path(projectile, projectileOrigin, attack->defender->tile, NULL, NULL, 32) - 1;
delay = _make_straight_path(projectile, projectileOrigin, attack->defender->tile, nullptr, nullptr, 32) - 1;
explosionCenterTile = attack->defender->tile;
} else {
animationRegisterMoveToTileStraight(projectile, attack->tile, attack->defender->elevation, ANIM_WALK, 0);
@@ -862,10 +865,10 @@ int _action_ranged(Attack* attack, int anim)
for (int rotation = startRotation; rotation < endRotation; rotation++) {
if (objectCreateWithFidPid(&(adjacentObjects[rotation]), explosionFid, -1) != -1) {
objectHide(adjacentObjects[rotation], NULL);
objectHide(adjacentObjects[rotation], nullptr);
int adjacentTile = tileGetTileInDirection(explosionCenterTile, rotation, 1);
objectSetLocation(adjacentObjects[rotation], adjacentTile, projectile->elevation, NULL);
objectSetLocation(adjacentObjects[rotation], adjacentTile, projectile->elevation, nullptr);
int delay;
if (rotation != ROTATION_NE) {
@@ -920,7 +923,7 @@ int _action_ranged(Attack* attack, int anim)
}
// SFALL
if (projectile != NULL && (isGrenade || damageType == explosionGetDamageType())) {
if (projectile != nullptr && (isGrenade || damageType == explosionGetDamageType())) {
// CE: Use custom callback to hide projectile instead of relying on
// `animationRegisterHideObjectForced`. The problem is that completing
// `ANIM_KIND_HIDE` removes (frees) object entirely. When this happens
@@ -931,12 +934,12 @@ int _action_ranged(Attack* attack, int anim)
// `opDestroyObject` for self-deleting objects (mark it hidden +
// no-save).
animationRegisterCallbackForced(attack, projectile, hideProjectile, -1);
} else if (anim == ANIM_THROW_ANIM && projectile != NULL) {
} else if (anim == ANIM_THROW_ANIM && projectile != nullptr) {
animationRegisterSetFid(projectile, weaponFid, -1);
}
for (int rotation = 0; rotation < ROTATION_COUNT; rotation++) {
if (adjacentObjects[rotation] != NULL) {
if (adjacentObjects[rotation] != nullptr) {
animationRegisterHideObjectForced(adjacentObjects[rotation]);
}
}
@@ -944,7 +947,7 @@ int _action_ranged(Attack* attack, int anim)
if ((attack->attackerFlags & (DAM_KNOCKED_OUT | DAM_KNOCKED_DOWN | DAM_DEAD)) == 0) {
if (anim == ANIM_THROW_ANIM) {
bool takeOutAnimationRegistered = false;
if (replacedWeapon != NULL) {
if (replacedWeapon != nullptr) {
int weaponAnimationCode = weaponGetAnimationCode(replacedWeapon);
if (weaponAnimationCode != 0) {
animationRegisterTakeOutWeapon(attack->attacker, weaponAnimationCode, -1);
@@ -963,13 +966,13 @@ int _action_ranged(Attack* attack, int anim)
if (reg_anim_end() == -1) {
debugPrint("Something went wrong with a ranged attack sequence!\n");
if (projectile != NULL && (isGrenade || damageType == DAMAGE_TYPE_EXPLOSION || anim != ANIM_THROW_ANIM)) {
objectDestroy(projectile, NULL);
if (projectile != nullptr && (isGrenade || damageType == DAMAGE_TYPE_EXPLOSION || anim != ANIM_THROW_ANIM)) {
objectDestroy(projectile, nullptr);
}
for (int rotation = 0; rotation < ROTATION_COUNT; rotation++) {
if (adjacentObjects[rotation] != NULL) {
objectDestroy(adjacentObjects[rotation], NULL);
if (adjacentObjects[rotation] != nullptr) {
objectDestroy(adjacentObjects[rotation], nullptr);
}
}
@@ -1059,7 +1062,7 @@ int _action_climb_ladder(Object* a1, Object* a2)
// 0x411F2C
int _action_use_an_item_on_object(Object* a1, Object* a2, Object* a3)
{
Proto* proto = NULL;
Proto* proto = nullptr;
int type = FID_TYPE(a2->fid);
int sceneryType = -1;
if (type == OBJ_TYPE_SCENERY) {
@@ -1070,7 +1073,7 @@ int _action_use_an_item_on_object(Object* a1, Object* a2, Object* a3)
sceneryType = proto->scenery.type;
}
if (sceneryType != SCENERY_TYPE_LADDER_UP || a3 != NULL) {
if (sceneryType != SCENERY_TYPE_LADDER_UP || a3 != nullptr) {
if (a1 == gDude) {
int anim = FID_ANIM_TYPE(gDude->fid);
if (anim == ANIM_WALK || anim == ANIM_RUNNING) {
@@ -1102,7 +1105,7 @@ int _action_use_an_item_on_object(Object* a1, Object* a2, Object* a3)
animationRegisterCallbackForced(a1, a2, (AnimationCallback*)_is_next_to, -1);
if (a3 == NULL) {
if (a3 == nullptr) {
animationRegisterCallback(a1, a2, (AnimationCallback*)_check_scenery_ap_cost, -1);
}
@@ -1123,11 +1126,11 @@ int _action_use_an_item_on_object(Object* a1, Object* a2, Object* a3)
anim = ANIM_MAGIC_HANDS_MIDDLE;
}
if (sceneryType != SCENERY_TYPE_STAIRS && a3 == NULL) {
if (sceneryType != SCENERY_TYPE_STAIRS && a3 == nullptr) {
animationRegisterAnimate(a1, anim, -1);
}
if (a3 != NULL) {
if (a3 != nullptr) {
// TODO: Get rid of cast.
animationRegisterCallback3(a1, a2, a3, (AnimationCallback3*)_obj_use_item_on, -1);
} else {
@@ -1147,7 +1150,7 @@ int _action_use_an_item_on_object(Object* a1, Object* a2, Object* a3)
// 0x412114
int _action_use_an_object(Object* a1, Object* a2)
{
return _action_use_an_item_on_object(a1, a2, NULL);
return _action_use_an_item_on_object(a1, a2, nullptr);
}
// 0x412134
@@ -1190,7 +1193,7 @@ int actionPickUp(Object* critter, Object* item)
int actionFrame;
CacheEntry* cacheEntry;
Art* art = artLock(fid, &cacheEntry);
if (art != NULL) {
if (art != nullptr) {
actionFrame = artGetActionFrame(art);
} else {
actionFrame = -1;
@@ -1222,7 +1225,7 @@ int actionPickUp(Object* critter, Object* item)
int actionFrame;
CacheEntry* cacheEntry;
Art* art = artLock(fid, &cacheEntry);
if (art == NULL) {
if (art == nullptr) {
actionFrame = artGetActionFrame(art);
artUnlock(cacheEntry);
} else {
@@ -1419,34 +1422,34 @@ int actionUseSkill(Object* a1, Object* a2, int skill)
Object* partyMember = partyMemberGetBestInSkill(skill);
if (partyMember == gDude) {
partyMember = NULL;
partyMember = nullptr;
}
// Only dude can perform stealing.
if (skill == SKILL_STEAL) {
partyMember = NULL;
partyMember = nullptr;
}
if (partyMember != NULL) {
if (partyMember != nullptr) {
if (partyMemberGetBestSkill(partyMember) != skill) {
partyMember = NULL;
partyMember = nullptr;
}
}
if (partyMember != NULL) {
if (partyMember != nullptr) {
performer = partyMember;
int anim = FID_ANIM_TYPE(partyMember->fid);
if (anim != ANIM_WALK && anim != ANIM_RUNNING) {
if (anim != ANIM_STAND) {
performer = gDude;
partyMember = NULL;
partyMember = nullptr;
}
} else {
reg_anim_clear(partyMember);
}
}
if (partyMember != NULL) {
if (partyMember != nullptr) {
bool isDude = false;
if (objectGetDistanceBetween(gDude, a2) <= 1) {
isDude = true;
@@ -1461,11 +1464,11 @@ int actionUseSkill(Object* a1, Object* a2, int skill)
if (isDude) {
performer = gDude;
partyMember = NULL;
partyMember = nullptr;
}
}
if (partyMember == NULL) {
if (partyMember == nullptr) {
int anim = FID_ANIM_TYPE(performer->fid);
if (anim == ANIM_WALK || anim == ANIM_RUNNING) {
reg_anim_clear(performer);
@@ -1494,7 +1497,7 @@ int actionUseSkill(Object* a1, Object* a2, int skill)
CacheEntry* artHandle;
Art* art = artLock(fid, &artHandle);
if (art != NULL) {
if (art != nullptr) {
artGetActionFrame(art);
artUnlock(artHandle);
}
@@ -1542,7 +1545,7 @@ int _pick_fall(Object* obj, int anim)
rotation = obj->rotation;
for (i = 1; i < 3; i++) {
tile_num = tileGetTileInDirection(obj->tile, rotation, i);
if (_obj_blocking_at(obj, tile_num, obj->elevation) != NULL) {
if (_obj_blocking_at(obj, tile_num, obj->elevation) != nullptr) {
anim = ANIM_FALL_BACK;
break;
}
@@ -1551,7 +1554,7 @@ int _pick_fall(Object* obj, int anim)
rotation = (obj->rotation + 3) % ROTATION_COUNT;
for (i = 1; i < 3; i++) {
tile_num = tileGetTileInDirection(obj->tile, rotation, i);
if (_obj_blocking_at(obj, tile_num, obj->elevation) != NULL) {
if (_obj_blocking_at(obj, tile_num, obj->elevation) != nullptr) {
anim = ANIM_FALL_FRONT;
break;
}
@@ -1576,14 +1579,14 @@ bool _action_explode_running()
// action_explode
// 0x412CF4
int actionExplode(int tile, int elevation, int minDamage, int maxDamage, Object* a5, bool a6)
int actionExplode(int tile, int elevation, int minDamage, int maxDamage, Object* sourceObj, bool animate)
{
if (a6 && _action_in_explode) {
if (animate && _action_in_explode) {
return -2;
}
Attack* attack = (Attack*)internal_malloc(sizeof(*attack));
if (attack == NULL) {
if (attack == nullptr) {
return -1;
}
@@ -1594,35 +1597,35 @@ int actionExplode(int tile, int elevation, int minDamage, int maxDamage, Object*
return -1;
}
objectHide(explosion, NULL);
objectHide(explosion, nullptr);
explosion->flags |= OBJECT_NO_SAVE;
objectSetLocation(explosion, tile, elevation, NULL);
objectSetLocation(explosion, tile, elevation, nullptr);
Object* adjacentExplosions[ROTATION_COUNT];
for (int rotation = 0; rotation < ROTATION_COUNT; rotation++) {
int fid = buildFid(OBJ_TYPE_MISC, 10, 0, 0, 0);
if (objectCreateWithFidPid(&(adjacentExplosions[rotation]), fid, -1) == -1) {
while (--rotation >= 0) {
objectDestroy(adjacentExplosions[rotation], NULL);
objectDestroy(adjacentExplosions[rotation], nullptr);
}
objectDestroy(explosion, NULL);
objectDestroy(explosion, nullptr);
internal_free(attack);
return -1;
}
objectHide(adjacentExplosions[rotation], NULL);
objectHide(adjacentExplosions[rotation], nullptr);
adjacentExplosions[rotation]->flags |= OBJECT_NO_SAVE;
int adjacentTile = tileGetTileInDirection(tile, rotation, 1);
objectSetLocation(adjacentExplosions[rotation], adjacentTile, elevation, NULL);
objectSetLocation(adjacentExplosions[rotation], adjacentTile, elevation, nullptr);
}
Object* critter = _obj_blocking_at(NULL, tile, elevation);
if (critter != NULL) {
Object* critter = _obj_blocking_at(nullptr, tile, elevation);
if (critter != nullptr) {
if (FID_TYPE(critter->fid) != OBJ_TYPE_CRITTER || (critter->data.critter.combat.results & DAM_DEAD) != 0) {
critter = NULL;
critter = nullptr;
}
}
@@ -1633,7 +1636,7 @@ int actionExplode(int tile, int elevation, int minDamage, int maxDamage, Object*
gameUiDisable(1);
if (critter != NULL) {
if (critter != nullptr) {
if (reg_anim_clear(critter) == -2) {
debugPrint("Cannot clear target's animation for action_explode!\n");
}
@@ -1653,7 +1656,7 @@ int actionExplode(int tile, int elevation, int minDamage, int maxDamage, Object*
attackComputeDeathFlags(attack);
if (a6) {
if (animate) {
_action_in_explode = true;
reg_anim_begin(ANIMATION_REQUEST_RESERVED);
@@ -1668,22 +1671,22 @@ int actionExplode(int tile, int elevation, int minDamage, int maxDamage, Object*
animationRegisterAnimateAndHide(adjacentExplosions[rotation], ANIM_STAND, 0);
}
animationRegisterCallbackForced(explosion, 0, (AnimationCallback*)_combat_explode_scenery, -1);
animationRegisterCallbackForced(explosion, nullptr, (AnimationCallback*)_combat_explode_scenery, -1);
animationRegisterHideObjectForced(explosion);
for (int rotation = 0; rotation < ROTATION_COUNT; rotation++) {
animationRegisterHideObjectForced(adjacentExplosions[rotation]);
}
animationRegisterCallbackForced(attack, a5, (AnimationCallback*)_report_explosion, -1);
animationRegisterCallbackForced(NULL, NULL, (AnimationCallback*)_finished_explosion, -1);
animationRegisterCallbackForced(attack, sourceObj, (AnimationCallback*)_report_explosion, -1);
animationRegisterCallbackForced(nullptr, nullptr, (AnimationCallback*)_finished_explosion, -1);
if (reg_anim_end() == -1) {
_action_in_explode = false;
objectDestroy(explosion, NULL);
objectDestroy(explosion, nullptr);
for (int rotation = 0; rotation < ROTATION_COUNT; rotation++) {
objectDestroy(adjacentExplosions[rotation], NULL);
objectDestroy(adjacentExplosions[rotation], nullptr);
}
internal_free(attack);
@@ -1694,7 +1697,7 @@ int actionExplode(int tile, int elevation, int minDamage, int maxDamage, Object*
_show_damage_extras(attack);
} else {
if (critter != NULL) {
if (critter != nullptr) {
if ((attack->defenderFlags & DAM_DEAD) != 0) {
critterKill(critter, -1, false);
}
@@ -1706,14 +1709,14 @@ int actionExplode(int tile, int elevation, int minDamage, int maxDamage, Object*
}
}
_report_explosion(attack, a5);
_report_explosion(attack, sourceObj);
_combat_explode_scenery(explosion, NULL);
_combat_explode_scenery(explosion, nullptr);
objectDestroy(explosion, NULL);
objectDestroy(explosion, nullptr);
for (int rotation = 0; rotation < ROTATION_COUNT; rotation++) {
objectDestroy(adjacentExplosions[rotation], NULL);
objectDestroy(adjacentExplosions[rotation], nullptr);
}
}
@@ -1721,10 +1724,10 @@ int actionExplode(int tile, int elevation, int minDamage, int maxDamage, Object*
}
// 0x413144
int _report_explosion(Attack* attack, Object* a2)
int _report_explosion(Attack* attack, Object* sourceObj)
{
bool mainTargetWasDead;
if (attack->defender != NULL) {
if (attack->defender != nullptr) {
mainTargetWasDead = (attack->defender->data.critter.combat.results & DAM_DEAD) != 0;
} else {
mainTargetWasDead = false;
@@ -1739,48 +1742,48 @@ int _report_explosion(Attack* attack, Object* a2)
_combat_display(attack);
_apply_damage(attack, false);
Object* anyDefender = NULL;
Object* anyDefender = nullptr;
int xp = 0;
if (a2 != NULL) {
if (attack->defender != NULL && attack->defender != a2) {
if (sourceObj != nullptr) {
if (attack->defender != nullptr && attack->defender != sourceObj) {
if ((attack->defender->data.critter.combat.results & DAM_DEAD) != 0) {
if (a2 == gDude && !mainTargetWasDead) {
if (sourceObj == gDude && !mainTargetWasDead) {
xp += critterGetExp(attack->defender);
}
} else {
_critter_set_who_hit_me(attack->defender, a2);
_critter_set_who_hit_me(attack->defender, sourceObj);
anyDefender = attack->defender;
}
}
for (int index = 0; index < attack->extrasLength; index++) {
Object* critter = attack->extras[index];
if (critter != a2) {
if (critter != sourceObj) {
if ((critter->data.critter.combat.results & DAM_DEAD) != 0) {
if (a2 == gDude && !extrasWasDead[index]) {
if (sourceObj == gDude && !extrasWasDead[index]) {
xp += critterGetExp(critter);
}
} else {
_critter_set_who_hit_me(critter, a2);
_critter_set_who_hit_me(critter, sourceObj);
if (anyDefender == NULL) {
if (anyDefender == nullptr) {
anyDefender = critter;
}
}
}
}
if (anyDefender != NULL) {
if (anyDefender != nullptr) {
if (!isInCombat()) {
STRUCT_664980 combat;
CombatStartData combat;
combat.attacker = anyDefender;
combat.defender = a2;
combat.defender = sourceObj;
combat.actionPointsBonus = 0;
combat.accuracyBonus = 0;
combat.damageBonus = 0;
combat.minDamage = 0;
combat.maxDamage = INT_MAX;
combat.field_1C = 0;
combat.overrideAttackResults = 0;
scriptsRequestCombat(&combat);
}
}
@@ -1789,7 +1792,7 @@ int _report_explosion(Attack* attack, Object* a2)
internal_free(attack);
gameUiEnable();
if (a2 == gDude) {
if (sourceObj == gDude) {
_combat_give_exps(xp);
}
@@ -1816,7 +1819,7 @@ int _compute_explosion_damage(int min, int max, Object* defender, int* knockback
damage = 0;
}
if (knockbackDistancePtr != NULL) {
if (knockbackDistancePtr != nullptr) {
if ((defender->flags & OBJECT_MULTIHEX) == 0) {
*knockbackDistancePtr = damage / 10;
}
@@ -1847,7 +1850,7 @@ int actionTalk(Object* a1, Object* a2)
} else {
reg_anim_begin(a1 == gDude ? ANIMATION_REQUEST_RESERVED : ANIMATION_REQUEST_UNRESERVED);
if (objectGetDistanceBetween(a1, a2) >= 9 || _combat_is_shot_blocked(a1, a1->tile, a2->tile, a2, NULL)) {
if (objectGetDistanceBetween(a1, a2) >= 9 || _combat_is_shot_blocked(a1, a1->tile, a2->tile, a2, nullptr)) {
animationRegisterRunToObject(a1, a2, -1, 0);
}
}
@@ -1860,7 +1863,7 @@ int actionTalk(Object* a1, Object* a2)
// 0x413420
int _can_talk_to(Object* a1, Object* a2)
{
if (_combat_is_shot_blocked(a1, a1->tile, a2->tile, a2, NULL) || objectGetDistanceBetween(a1, a2) >= 9) {
if (_combat_is_shot_blocked(a1, a1->tile, a2->tile, a2, nullptr) || objectGetDistanceBetween(a1, a2) >= 9) {
if (a1 == gDude) {
// You cannot get there. (used in actions.c)
MessageListItem messageListItem;
@@ -1887,7 +1890,7 @@ int _talk_to(Object* a1, Object* a2)
void actionDamage(int tile, int elevation, int minDamage, int maxDamage, int damageType, bool animated, bool bypassArmor)
{
Attack* attack = (Attack*)internal_malloc(sizeof(*attack));
if (attack == NULL) {
if (attack == nullptr) {
return;
}
@@ -1897,19 +1900,19 @@ void actionDamage(int tile, int elevation, int minDamage, int maxDamage, int dam
return;
}
objectHide(attacker, NULL);
objectHide(attacker, nullptr);
attacker->flags |= OBJECT_NO_SAVE;
objectSetLocation(attacker, tile, elevation, NULL);
objectSetLocation(attacker, tile, elevation, nullptr);
Object* defender = _obj_blocking_at(NULL, tile, elevation);
Object* defender = _obj_blocking_at(nullptr, tile, elevation);
attackInit(attack, attacker, defender, HIT_MODE_PUNCH, HIT_LOCATION_TORSO);
attack->tile = tile;
attack->attackerFlags = DAM_HIT;
gameUiDisable(1);
if (defender != NULL) {
if (defender != nullptr) {
reg_anim_clear(defender);
int damage;
@@ -1928,25 +1931,25 @@ void actionDamage(int tile, int elevation, int minDamage, int maxDamage, int dam
reg_anim_begin(ANIMATION_REQUEST_RESERVED);
animationRegisterPlaySoundEffect(attacker, "whc1xxx1", 0);
_show_damage(attack, gMaximumBloodDeathAnimations[damageType], 0);
animationRegisterCallbackForced(attack, NULL, (AnimationCallback*)_report_dmg, 0);
animationRegisterCallbackForced(attack, nullptr, (AnimationCallback*)_report_dmg, 0);
animationRegisterHideObjectForced(attacker);
if (reg_anim_end() == -1) {
objectDestroy(attacker, NULL);
objectDestroy(attacker, nullptr);
internal_free(attack);
return;
}
} else {
if (defender != NULL) {
if (defender != nullptr) {
if ((attack->defenderFlags & DAM_DEAD) != 0) {
critterKill(defender, -1, 1);
}
}
// NOTE: Uninline.
_report_dmg(attack, NULL);
_report_dmg(attack, nullptr);
objectDestroy(attacker, NULL);
objectDestroy(attacker, nullptr);
}
gameUiEnable();
@@ -1968,7 +1971,7 @@ int _report_dmg(Attack* attack, Object* a2)
int _compute_dmg_damage(int min, int max, Object* obj, int* knockbackDistancePtr, int damageType)
{
if (!_critter_flag_check(obj->pid, CRITTER_NO_KNOCKBACK)) {
knockbackDistancePtr = NULL;
knockbackDistancePtr = nullptr;
}
int damage = randomBetween(min, max) - critterGetStat(obj, STAT_DAMAGE_THRESHOLD + damageType);
@@ -1980,7 +1983,7 @@ int _compute_dmg_damage(int min, int max, Object* obj, int* knockbackDistancePtr
damage = 0;
}
if (knockbackDistancePtr != NULL) {
if (knockbackDistancePtr != nullptr) {
if ((obj->flags & OBJECT_MULTIHEX) == 0 && damageType != DAMAGE_TYPE_ELECTRICAL) {
*knockbackDistancePtr = damage / 10;
}
@@ -2024,7 +2027,7 @@ bool actionCheckPush(Object* a1, Object* a2)
// TODO: Check.
Object* whoHitMe = a2->data.critter.combat.whoHitMe;
if (whoHitMe != NULL
if (whoHitMe != nullptr
&& whoHitMe->data.critter.combat.team == a1->data.critter.combat.team) {
return false;
}
@@ -2061,32 +2064,32 @@ int actionPush(Object* a1, Object* a2)
int tile;
do {
tile = tileGetTileInDirection(a2->tile, rotation, 1);
if (_obj_blocking_at(a2, tile, a2->elevation) == NULL) {
if (_obj_blocking_at(a2, tile, a2->elevation) == nullptr) {
break;
}
tile = tileGetTileInDirection(a2->tile, (rotation + 1) % ROTATION_COUNT, 1);
if (_obj_blocking_at(a2, tile, a2->elevation) == NULL) {
if (_obj_blocking_at(a2, tile, a2->elevation) == nullptr) {
break;
}
tile = tileGetTileInDirection(a2->tile, (rotation + 5) % ROTATION_COUNT, 1);
if (_obj_blocking_at(a2, tile, a2->elevation) == NULL) {
if (_obj_blocking_at(a2, tile, a2->elevation) == nullptr) {
break;
}
tile = tileGetTileInDirection(a2->tile, (rotation + 2) % ROTATION_COUNT, 1);
if (_obj_blocking_at(a2, tile, a2->elevation) == NULL) {
if (_obj_blocking_at(a2, tile, a2->elevation) == nullptr) {
break;
}
tile = tileGetTileInDirection(a2->tile, (rotation + 4) % ROTATION_COUNT, 1);
if (_obj_blocking_at(a2, tile, a2->elevation) == NULL) {
if (_obj_blocking_at(a2, tile, a2->elevation) == nullptr) {
break;
}
tile = tileGetTileInDirection(a2->tile, (rotation + 3) % ROTATION_COUNT, 1);
if (_obj_blocking_at(a2, tile, a2->elevation) == NULL) {
if (_obj_blocking_at(a2, tile, a2->elevation) == nullptr) {
break;
}
@@ -2112,7 +2115,7 @@ int actionPush(Object* a1, Object* a2)
// 0x413970
int _action_can_talk_to(Object* a1, Object* a2)
{
if (pathfinderFindPath(a1, a1->tile, a2->tile, NULL, 0, _obj_sight_blocking_at) == 0) {
if (pathfinderFindPath(a1, a1->tile, a2->tile, nullptr, 0, _obj_sight_blocking_at) == 0) {
return -1;
}

View File

@@ -6,6 +6,8 @@
namespace fallout {
extern int rotation;
int _action_attack(Attack* attack);
int _action_use_an_item_on_object(Object* a1, Object* a2, Object* a3);
int _action_use_an_object(Object* a1, Object* a2);
@@ -13,10 +15,10 @@ int actionPickUp(Object* critter, Object* item);
int _action_loot_container(Object* critter, Object* container);
int _action_skill_use(int a1);
int actionUseSkill(Object* a1, Object* a2, int skill);
bool _is_hit_from_front(Object* a1, Object* a2);
bool _is_hit_from_front(Object* attacker, Object* defender);
bool _can_see(Object* a1, Object* a2);
bool _action_explode_running();
int actionExplode(int tile, int elevation, int minDamage, int maxDamage, Object* a5, bool a6);
int actionExplode(int tile, int elevation, int minDamage, int maxDamage, Object* sourceObj, bool animate);
int actionTalk(Object* a1, Object* a2);
void actionDamage(int tile, int elevation, int minDamage, int maxDamage, int damageType, bool animated, bool bypassArmor);
bool actionCheckPush(Object* a1, Object* a2);

View File

@@ -503,11 +503,11 @@ int reg_anim_end()
// 0x413D6C
static int _anim_preload(Object* object, int fid, CacheEntry** cacheEntryPtr)
{
*cacheEntryPtr = NULL;
*cacheEntryPtr = nullptr;
if (artLock(fid, cacheEntryPtr) != NULL) {
if (artLock(fid, cacheEntryPtr) != nullptr) {
artUnlock(*cacheEntryPtr);
*cacheEntryPtr = NULL;
*cacheEntryPtr = nullptr;
return 0;
}
@@ -528,7 +528,7 @@ static void _anim_cleanup()
AnimationSequence* animationSequence = &(gAnimationSequences[gAnimationSequenceCurrentIndex]);
for (int index = 0; index < gAnimationDescriptionCurrentIndex; index++) {
AnimationDescription* animationDescription = &(animationSequence->animations[index]);
if (animationDescription->artCacheKey != NULL) {
if (animationDescription->artCacheKey != nullptr) {
artUnlock(animationDescription->artCacheKey);
}
@@ -551,7 +551,7 @@ static int _check_registry(Object* obj)
return -1;
}
if (obj == NULL) {
if (obj == nullptr) {
return 0;
}
@@ -580,7 +580,7 @@ static int _check_registry(Object* obj)
// 0x413EC8
int animationIsBusy(Object* a1)
{
if (gAnimationDescriptionCurrentIndex >= ANIMATION_DESCRIPTION_LIST_CAPACITY || a1 == NULL) {
if (gAnimationDescriptionCurrentIndex >= ANIMATION_DESCRIPTION_LIST_CAPACITY || a1 == nullptr) {
return 0;
}
@@ -885,7 +885,7 @@ int animationRegisterAnimateReversed(Object* owner, int anim, int delay)
animationDescription->owner = owner;
animationDescription->anim = anim;
animationDescription->delay = delay;
animationDescription->artCacheKey = NULL;
animationDescription->artCacheKey = nullptr;
int fid = buildFid(FID_TYPE(owner->fid), owner->fid & 0xFFF, animationDescription->anim, (owner->fid & 0xF000) >> 12, owner->rotation + 1);
@@ -914,7 +914,7 @@ int animationRegisterAnimateAndHide(Object* owner, int anim, int delay)
animationDescription->owner = owner;
animationDescription->anim = anim;
animationDescription->delay = delay;
animationDescription->artCacheKey = NULL;
animationDescription->artCacheKey = nullptr;
int fid = buildFid(FID_TYPE(owner->fid), owner->fid & 0xFFF, anim, (owner->fid & 0xF000) >> 12, owner->rotation + 1);
@@ -941,7 +941,7 @@ int animationRegisterRotateToTile(Object* owner, int tile)
AnimationDescription* animationDescription = &(animationSequence->animations[gAnimationDescriptionCurrentIndex]);
animationDescription->kind = ANIM_KIND_ROTATE_TO_TILE;
animationDescription->delay = -1;
animationDescription->artCacheKey = NULL;
animationDescription->artCacheKey = nullptr;
animationDescription->owner = owner;
animationDescription->tile = tile;
@@ -962,7 +962,7 @@ int animationRegisterRotateClockwise(Object* owner)
AnimationDescription* animationDescription = &(animationSequence->animations[gAnimationDescriptionCurrentIndex]);
animationDescription->kind = ANIM_KIND_ROTATE_CLOCKWISE;
animationDescription->delay = -1;
animationDescription->artCacheKey = NULL;
animationDescription->artCacheKey = nullptr;
animationDescription->owner = owner;
gAnimationDescriptionCurrentIndex++;
@@ -982,7 +982,7 @@ int animationRegisterRotateCounterClockwise(Object* owner)
AnimationDescription* animationDescription = &(animationSequence->animations[gAnimationDescriptionCurrentIndex]);
animationDescription->kind = ANIM_KIND_ROTATE_COUNTER_CLOCKWISE;
animationDescription->delay = -1;
animationDescription->artCacheKey = NULL;
animationDescription->artCacheKey = nullptr;
animationDescription->owner = owner;
gAnimationDescriptionCurrentIndex++;
@@ -1004,7 +1004,7 @@ int animationRegisterHideObject(Object* object)
AnimationDescription* animationDescription = &(animationSequence->animations[gAnimationDescriptionCurrentIndex]);
animationDescription->kind = ANIM_KIND_HIDE;
animationDescription->delay = -1;
animationDescription->artCacheKey = NULL;
animationDescription->artCacheKey = nullptr;
animationDescription->extendedFlags = 0;
animationDescription->owner = object;
gAnimationDescriptionCurrentIndex++;
@@ -1024,7 +1024,7 @@ int animationRegisterHideObjectForced(Object* object)
AnimationDescription* animationDescription = &(animationSequence->animations[gAnimationDescriptionCurrentIndex]);
animationDescription->kind = ANIM_KIND_HIDE;
animationDescription->delay = -1;
animationDescription->artCacheKey = NULL;
animationDescription->artCacheKey = nullptr;
animationDescription->extendedFlags = ANIMATION_SEQUENCE_FORCED;
animationDescription->owner = object;
gAnimationDescriptionCurrentIndex++;
@@ -1035,7 +1035,7 @@ int animationRegisterHideObjectForced(Object* object)
// 0x414E98
int animationRegisterCallback(void* a1, void* a2, AnimationCallback* proc, int delay)
{
if (_check_registry(NULL) == -1 || proc == NULL) {
if (_check_registry(nullptr) == -1 || proc == nullptr) {
_anim_cleanup();
return -1;
}
@@ -1044,7 +1044,7 @@ int animationRegisterCallback(void* a1, void* a2, AnimationCallback* proc, int d
AnimationDescription* animationDescription = &(animationSequence->animations[gAnimationDescriptionCurrentIndex]);
animationDescription->kind = ANIM_KIND_CALLBACK;
animationDescription->extendedFlags = 0;
animationDescription->artCacheKey = NULL;
animationDescription->artCacheKey = nullptr;
animationDescription->param2 = a2;
animationDescription->param1 = a1;
animationDescription->callback = proc;
@@ -1060,7 +1060,7 @@ int animationRegisterCallback(void* a1, void* a2, AnimationCallback* proc, int d
// 0x414F20
int animationRegisterCallback3(void* a1, void* a2, void* a3, AnimationCallback3* proc, int delay)
{
if (_check_registry(NULL) == -1 || proc == NULL) {
if (_check_registry(nullptr) == -1 || proc == nullptr) {
_anim_cleanup();
return -1;
}
@@ -1069,7 +1069,7 @@ int animationRegisterCallback3(void* a1, void* a2, void* a3, AnimationCallback3*
AnimationDescription* animationDescription = &(animationSequence->animations[gAnimationDescriptionCurrentIndex]);
animationDescription->kind = ANIM_KIND_CALLBACK3;
animationDescription->extendedFlags = 0;
animationDescription->artCacheKey = NULL;
animationDescription->artCacheKey = nullptr;
animationDescription->param2 = a2;
animationDescription->param1 = a1;
animationDescription->callback3 = proc;
@@ -1084,7 +1084,7 @@ int animationRegisterCallback3(void* a1, void* a2, void* a3, AnimationCallback3*
// 0x414FAC
int animationRegisterCallbackForced(void* a1, void* a2, AnimationCallback* proc, int delay)
{
if (_check_registry(NULL) == -1 || proc == NULL) {
if (_check_registry(nullptr) == -1 || proc == nullptr) {
_anim_cleanup();
return -1;
}
@@ -1093,7 +1093,7 @@ int animationRegisterCallbackForced(void* a1, void* a2, AnimationCallback* proc,
AnimationDescription* animationDescription = &(animationSequence->animations[gAnimationDescriptionCurrentIndex]);
animationDescription->kind = ANIM_KIND_CALLBACK;
animationDescription->extendedFlags = ANIMATION_SEQUENCE_FORCED;
animationDescription->artCacheKey = NULL;
animationDescription->artCacheKey = nullptr;
animationDescription->param2 = a2;
animationDescription->param1 = a1;
animationDescription->callback = proc;
@@ -1121,7 +1121,7 @@ int animationRegisterSetFlag(Object* object, int flag, int delay)
AnimationSequence* animationSequence = &(gAnimationSequences[gAnimationSequenceCurrentIndex]);
AnimationDescription* animationDescription = &(animationSequence->animations[gAnimationDescriptionCurrentIndex]);
animationDescription->kind = ANIM_KIND_SET_FLAG;
animationDescription->artCacheKey = NULL;
animationDescription->artCacheKey = nullptr;
animationDescription->owner = object;
animationDescription->objectFlag = flag;
animationDescription->delay = delay;
@@ -1146,7 +1146,7 @@ int animationRegisterUnsetFlag(Object* object, int flag, int delay)
AnimationSequence* animationSequence = &(gAnimationSequences[gAnimationSequenceCurrentIndex]);
AnimationDescription* animationDescription = &(animationSequence->animations[gAnimationDescriptionCurrentIndex]);
animationDescription->kind = ANIM_KIND_UNSET_FLAG;
animationDescription->artCacheKey = NULL;
animationDescription->artCacheKey = nullptr;
animationDescription->owner = object;
animationDescription->objectFlag = flag;
animationDescription->delay = delay;
@@ -1227,7 +1227,7 @@ int animationRegisterSetLightDistance(Object* owner, int lightDistance, int dela
AnimationSequence* animationSequence = &(gAnimationSequences[gAnimationSequenceCurrentIndex]);
AnimationDescription* animationDescription = &(animationSequence->animations[gAnimationDescriptionCurrentIndex]);
animationDescription->kind = ANIM_KIND_SET_LIGHT_DISTANCE;
animationDescription->artCacheKey = NULL;
animationDescription->artCacheKey = nullptr;
animationDescription->owner = owner;
animationDescription->lightDistance = lightDistance;
animationDescription->delay = delay;
@@ -1250,7 +1250,7 @@ int animationRegisterToggleOutline(Object* object, bool outline, int delay)
AnimationSequence* animationSequence = &(gAnimationSequences[gAnimationSequenceCurrentIndex]);
AnimationDescription* animationDescription = &(animationSequence->animations[gAnimationDescriptionCurrentIndex]);
animationDescription->kind = ANIM_KIND_TOGGLE_OUTLINE;
animationDescription->artCacheKey = NULL;
animationDescription->artCacheKey = nullptr;
animationDescription->owner = object;
animationDescription->outline = outline;
animationDescription->delay = delay;
@@ -1272,10 +1272,10 @@ int animationRegisterPlaySoundEffect(Object* owner, const char* soundEffectName,
AnimationDescription* animationDescription = &(animationSequence->animations[gAnimationDescriptionCurrentIndex]);
animationDescription->kind = ANIM_KIND_CALLBACK;
animationDescription->owner = owner;
if (soundEffectName != NULL) {
if (soundEffectName != nullptr) {
int volume = _gsound_compute_relative_volume(owner);
animationDescription->param1 = soundEffectLoadWithVolume(soundEffectName, owner, volume);
if (animationDescription->param1 != NULL) {
if (animationDescription->param1 != nullptr) {
animationDescription->callback = (AnimationCallback*)_gsnd_anim_sound;
} else {
animationDescription->kind = ANIM_KIND_CONTINUE;
@@ -1284,7 +1284,7 @@ int animationRegisterPlaySoundEffect(Object* owner, const char* soundEffectName,
animationDescription->kind = ANIM_KIND_CONTINUE;
}
animationDescription->artCacheKey = NULL;
animationDescription->artCacheKey = nullptr;
animationDescription->delay = delay;
gAnimationDescriptionCurrentIndex++;
@@ -1323,7 +1323,7 @@ int animationRegisterAnimateForever(Object* owner, int anim, int delay)
// 0x415598
int animationRegisterPing(int flags, int delay)
{
if (_check_registry(NULL) == -1) {
if (_check_registry(nullptr) == -1) {
_anim_cleanup();
return -1;
}
@@ -1337,9 +1337,9 @@ int animationRegisterPing(int flags, int delay)
AnimationSequence* animationSequence = &(gAnimationSequences[gAnimationSequenceCurrentIndex]);
AnimationDescription* animationDescription = &(animationSequence->animations[gAnimationDescriptionCurrentIndex]);
animationDescription->owner = NULL;
animationDescription->owner = nullptr;
animationDescription->kind = ANIM_KIND_PING;
animationDescription->artCacheKey = NULL;
animationDescription->artCacheKey = nullptr;
animationDescription->animationSequenceIndex = animationSequenceIndex;
animationDescription->delay = delay;
@@ -1711,11 +1711,12 @@ int _make_path(Object* object, int from, int to, unsigned char* rotations, int a
return pathfinderFindPath(object, from, to, rotations, a5, _obj_blocking_at);
}
// TODO: move pathfinding into another unit
// 0x415EFC
int pathfinderFindPath(Object* object, int from, int to, unsigned char* rotations, int a5, PathBuilderCallback* callback)
{
if (a5) {
if (callback(object, to, object->elevation) != NULL) {
if (callback(object, to, object->elevation) != nullptr) {
return 0;
}
}
@@ -1754,7 +1755,7 @@ int pathfinderFindPath(Object* object, int from, int to, unsigned char* rotation
while (1) {
int v63 = -1;
PathNode* prev = NULL;
PathNode* prev = nullptr;
int v12 = 0;
for (int index = 0; v12 < openPathNodeListLength; index += 1) {
PathNode* curr = &(gOpenPathNodeList[index]);
@@ -1800,7 +1801,7 @@ int pathfinderFindPath(Object* object, int from, int to, unsigned char* rotation
if (tile != to) {
Object* v24 = callback(object, tile, object->elevation);
if (v24 != NULL) {
if (v24 != nullptr) {
if (!canUseDoor(object, v24)) {
continue;
}
@@ -1840,14 +1841,14 @@ int pathfinderFindPath(Object* object, int from, int to, unsigned char* rotation
if (isCritter) {
Object* o = objectFindFirstAtLocation(object->elevation, v27->tile);
while (o != NULL) {
while (o != nullptr) {
if (o->pid >= FIRST_RADIOACTIVE_GOO_PID && o->pid <= LAST_RADIOACTIVE_GOO_PID) {
break;
}
o = objectFindNextAtLocation();
}
if (o != NULL) {
if (o != nullptr) {
if (critterType == KILL_TYPE_GECKO) {
v27->cost += 100;
} else {
@@ -1870,7 +1871,7 @@ int pathfinderFindPath(Object* object, int from, int to, unsigned char* rotation
break;
}
if (v39 != NULL) {
if (v39 != nullptr) {
*v39 = temp.rotation & 0xFF;
v39 += 1;
}
@@ -1884,7 +1885,7 @@ int pathfinderFindPath(Object* object, int from, int to, unsigned char* rotation
memcpy(&temp, v36, sizeof(temp));
}
if (rotations != NULL) {
if (rotations != nullptr) {
// Looks like array resevering, probably because A* finishes it's path from end to start,
// this probably reverses it start-to-end.
unsigned char* beginning = rotations;
@@ -1939,19 +1940,19 @@ static int _tile_idistance(int tile1, int tile2)
}
// 0x4163AC
int _make_straight_path(Object* a1, int from, int to, StraightPathNode* straightPathNodeList, Object** obstaclePtr, int a6)
int _make_straight_path(Object* obj, int from, int to, StraightPathNode* straightPathNodeList, Object** obstaclePtr, int a6)
{
return _make_straight_path_func(a1, from, to, straightPathNodeList, obstaclePtr, a6, _obj_blocking_at);
return _make_straight_path_func(obj, from, to, straightPathNodeList, obstaclePtr, a6, _obj_blocking_at);
}
// TODO: Rather complex, but understandable, needs testing.
//
// 0x4163C8
int _make_straight_path_func(Object* a1, int from, int to, StraightPathNode* straightPathNodeList, Object** obstaclePtr, int a6, PathBuilderCallback* callback)
int _make_straight_path_func(Object* obj, int from, int to, StraightPathNode* straightPathNodeList, Object** obstaclePtr, int a6, PathBuilderCallback* callback)
{
if (obstaclePtr != NULL) {
Object* obstacle = callback(a1, from, a1->elevation);
if (obstacle != NULL) {
if (obstaclePtr != nullptr) {
Object* obstacle = callback(obj, from, obj->elevation);
if (obstacle != nullptr) {
if (obstacle != *obstaclePtr && (a6 != 32 || (obstacle->flags & OBJECT_SHOOT_THRU) == 0)) {
*obstaclePtr = obstacle;
return 0;
@@ -1961,13 +1962,13 @@ int _make_straight_path_func(Object* a1, int from, int to, StraightPathNode* str
int fromX;
int fromY;
tileToScreenXY(from, &fromX, &fromY, a1->elevation);
tileToScreenXY(from, &fromX, &fromY, obj->elevation);
fromX += 16;
fromY += 8;
int toX;
int toY;
tileToScreenXY(to, &toX, &toY, a1->elevation);
tileToScreenXY(to, &toX, &toY, obj->elevation);
toX += 16;
toY += 8;
@@ -2005,7 +2006,7 @@ int _make_straight_path_func(Object* a1, int from, int to, StraightPathNode* str
if (ddx <= ddy) {
int middle = ddx - ddy / 2;
while (true) {
tile = tileFromScreenXY(tileX, tileY, a1->elevation);
tile = tileFromScreenXY(tileX, tileY, obj->elevation);
v22 += 1;
if (v22 == a6) {
@@ -2013,12 +2014,12 @@ int _make_straight_path_func(Object* a1, int from, int to, StraightPathNode* str
return 0;
}
if (straightPathNodeList != NULL) {
if (straightPathNodeList != nullptr) {
StraightPathNode* pathNode = &(straightPathNodeList[pathNodeIndex]);
pathNode->tile = tile;
pathNode->elevation = a1->elevation;
pathNode->elevation = obj->elevation;
tileToScreenXY(tile, &fromX, &fromY, a1->elevation);
tileToScreenXY(tile, &fromX, &fromY, obj->elevation);
pathNode->x = tileX - fromX - 16;
pathNode->y = tileY - fromY - 8;
}
@@ -2028,8 +2029,8 @@ int _make_straight_path_func(Object* a1, int from, int to, StraightPathNode* str
}
if (tileY == toY) {
if (obstaclePtr != NULL) {
*obstaclePtr = NULL;
if (obstaclePtr != nullptr) {
*obstaclePtr = nullptr;
}
break;
}
@@ -2043,11 +2044,11 @@ int _make_straight_path_func(Object* a1, int from, int to, StraightPathNode* str
middle += ddx;
if (tile != prevTile) {
if (obstaclePtr != NULL) {
Object* obj = callback(a1, tile, a1->elevation);
if (obj != NULL) {
if (obj != *obstaclePtr && (a6 != 32 || (obj->flags & OBJECT_SHOOT_THRU) == 0)) {
*obstaclePtr = obj;
if (obstaclePtr != nullptr) {
Object* obstacle = callback(obj, tile, obj->elevation);
if (obstacle != nullptr) {
if (obstacle != *obstaclePtr && (a6 != 32 || (obstacle->flags & OBJECT_SHOOT_THRU) == 0)) {
*obstaclePtr = obstacle;
break;
}
}
@@ -2058,7 +2059,7 @@ int _make_straight_path_func(Object* a1, int from, int to, StraightPathNode* str
} else {
int middle = ddy - ddx / 2;
while (true) {
tile = tileFromScreenXY(tileX, tileY, a1->elevation);
tile = tileFromScreenXY(tileX, tileY, obj->elevation);
v22 += 1;
if (v22 == a6) {
@@ -2066,12 +2067,12 @@ int _make_straight_path_func(Object* a1, int from, int to, StraightPathNode* str
return 0;
}
if (straightPathNodeList != NULL) {
if (straightPathNodeList != nullptr) {
StraightPathNode* pathNode = &(straightPathNodeList[pathNodeIndex]);
pathNode->tile = tile;
pathNode->elevation = a1->elevation;
pathNode->elevation = obj->elevation;
tileToScreenXY(tile, &fromX, &fromY, a1->elevation);
tileToScreenXY(tile, &fromX, &fromY, obj->elevation);
pathNode->x = tileX - fromX - 16;
pathNode->y = tileY - fromY - 8;
}
@@ -2081,8 +2082,8 @@ int _make_straight_path_func(Object* a1, int from, int to, StraightPathNode* str
}
if (tileX == toX) {
if (obstaclePtr != NULL) {
*obstaclePtr = NULL;
if (obstaclePtr != nullptr) {
*obstaclePtr = nullptr;
}
break;
}
@@ -2096,11 +2097,11 @@ int _make_straight_path_func(Object* a1, int from, int to, StraightPathNode* str
middle += ddy;
if (tile != prevTile) {
if (obstaclePtr != NULL) {
Object* obj = callback(a1, tile, a1->elevation);
if (obj != NULL) {
if (obj != *obstaclePtr && (a6 != 32 || (obj->flags & OBJECT_SHOOT_THRU) == 0)) {
*obstaclePtr = obj;
if (obstaclePtr != nullptr) {
Object* obstacle = callback(obj, tile, obj->elevation);
if (obstacle != nullptr) {
if (obstacle != *obstaclePtr && (a6 != 32 || (obstacle->flags & OBJECT_SHOOT_THRU) == 0)) {
*obstaclePtr = obstacle;
break;
}
}
@@ -2115,20 +2116,20 @@ int _make_straight_path_func(Object* a1, int from, int to, StraightPathNode* str
return 0;
}
if (straightPathNodeList != NULL) {
if (straightPathNodeList != nullptr) {
StraightPathNode* pathNode = &(straightPathNodeList[pathNodeIndex]);
pathNode->tile = tile;
pathNode->elevation = a1->elevation;
pathNode->elevation = obj->elevation;
tileToScreenXY(tile, &fromX, &fromY, a1->elevation);
tileToScreenXY(tile, &fromX, &fromY, obj->elevation);
pathNode->x = tileX - fromX - 16;
pathNode->y = tileY - fromY - 8;
}
pathNodeIndex += 1;
} else {
if (pathNodeIndex > 0 && straightPathNodeList != NULL) {
straightPathNodeList[pathNodeIndex - 1].elevation = a1->elevation;
if (pathNodeIndex > 0 && straightPathNodeList != nullptr) {
straightPathNodeList[pathNodeIndex - 1].elevation = obj->elevation;
}
}
@@ -2195,8 +2196,8 @@ int _make_stair_path(Object* object, int from, int fromElevation, int to, int to
toX += 16;
toY += 8;
if (obstaclePtr != NULL) {
*obstaclePtr = NULL;
if (obstaclePtr != nullptr) {
*obstaclePtr = nullptr;
}
int ddx = 2 * abs(toX - fromX);
@@ -2242,7 +2243,7 @@ int _make_stair_path(Object* object, int from, int fromElevation, int to, int to
return 0;
}
if (a6 != NULL) {
if (a6 != nullptr) {
StraightPathNode* pathNode = &(a6[pathNodeIndex]);
pathNode->tile = tile;
pathNode->elevation = elevation;
@@ -2269,9 +2270,9 @@ int _make_stair_path(Object* object, int from, int fromElevation, int to, int to
middle += ddy;
if (tile != prevTile) {
if (obstaclePtr != NULL) {
if (obstaclePtr != nullptr) {
*obstaclePtr = _obj_blocking_at(object, tile, object->elevation);
if (*obstaclePtr != NULL) {
if (*obstaclePtr != nullptr) {
break;
}
}
@@ -2289,7 +2290,7 @@ int _make_stair_path(Object* object, int from, int fromElevation, int to, int to
return 0;
}
if (a6 != NULL) {
if (a6 != nullptr) {
StraightPathNode* pathNode = &(a6[pathNodeIndex]);
pathNode->tile = tile;
pathNode->elevation = elevation;
@@ -2316,9 +2317,9 @@ int _make_stair_path(Object* object, int from, int fromElevation, int to, int to
middle += ddx;
if (tile != prevTile) {
if (obstaclePtr != NULL) {
if (obstaclePtr != nullptr) {
*obstaclePtr = _obj_blocking_at(object, tile, object->elevation);
if (*obstaclePtr != NULL) {
if (*obstaclePtr != nullptr) {
break;
}
}
@@ -2332,7 +2333,7 @@ int _make_stair_path(Object* object, int from, int fromElevation, int to, int to
return 0;
}
if (a6 != NULL) {
if (a6 != nullptr) {
StraightPathNode* pathNode = &(a6[pathNodeIndex]);
pathNode->tile = tile;
pathNode->elevation = elevation;
@@ -2345,7 +2346,7 @@ int _make_stair_path(Object* object, int from, int fromElevation, int to, int to
pathNodeIndex++;
} else {
if (pathNodeIndex > 0) {
if (a6 != NULL) {
if (a6 != nullptr) {
a6[pathNodeIndex - 1].elevation = toElevation;
}
}
@@ -2447,7 +2448,7 @@ static int animateMoveObjectToTileStraight(Object* obj, int tile, int elevation,
v15 = 32;
}
sad->field_1C = _make_straight_path(obj, obj->tile, tile, sad->straightPathNodeList, NULL, v15);
sad->field_1C = _make_straight_path(obj, obj->tile, tile, sad->straightPathNodeList, nullptr, v15);
if (sad->field_1C == 0) {
sad->field_20 = -1000;
return -1;
@@ -2478,7 +2479,7 @@ static int _anim_move_on_stairs(Object* obj, int tile, int elevation, int anim,
sad->animationTimestamp = 0;
sad->ticksPerFrame = animationComputeTicksPerFrame(obj, sad->fid);
sad->animationSequenceIndex = animationSequenceIndex;
sad->field_1C = _make_stair_path(obj, obj->tile, obj->elevation, tile, elevation, sad->straightPathNodeList, NULL);
sad->field_1C = _make_stair_path(obj, obj->tile, obj->elevation, tile, elevation, sad->straightPathNodeList, nullptr);
if (sad->field_1C == 0) {
sad->field_20 = -1000;
return -1;
@@ -2513,7 +2514,7 @@ static int _check_for_falling(Object* obj, int anim, int a3)
sad->animationTimestamp = 0;
sad->ticksPerFrame = animationComputeTicksPerFrame(obj, sad->fid);
sad->animationSequenceIndex = a3;
sad->field_1C = _make_straight_path_func(obj, obj->tile, obj->tile, sad->straightPathNodeList, 0, 16, _obj_blocking_at);
sad->field_1C = _make_straight_path_func(obj, obj->tile, obj->tile, sad->straightPathNodeList, nullptr, 16, _obj_blocking_at);
if (sad->field_1C == 0) {
sad->field_20 = -1000;
return -1;
@@ -2556,7 +2557,7 @@ static void _object_move(int index)
CacheEntry* cacheHandle;
Art* art = artLock(object->fid, &cacheHandle);
if (art != NULL) {
if (art != nullptr) {
artGetFrameOffsets(art, object->frame, object->rotation, &frameX, &frameY);
artUnlock(cacheHandle);
} else {
@@ -2576,7 +2577,7 @@ static void _object_move(int index)
int nextTile = tileGetTileInDirection(object->tile, rotation, 1);
Object* obstacle = _obj_blocking_at(object, nextTile, object->elevation);
if (obstacle != NULL) {
if (obstacle != nullptr) {
if (!canUseDoor(object, obstacle)) {
sad->field_1C = _make_path(object, object->tile, sad->field_24, sad->rotations, 1);
if (sad->field_1C != 0) {
@@ -2663,7 +2664,7 @@ static void _object_straight_move(int index)
CacheEntry* cacheHandle;
Art* art = artLock(object->fid, &cacheHandle);
if (art != NULL) {
if (art != nullptr) {
int lastFrame = artGetFrameCount(art) - 1;
artUnlock(cacheHandle);
@@ -2796,7 +2797,7 @@ void _object_animate()
if ((sad->flags & ANIM_SAD_REVERSE) == 0) {
CacheEntry* cacheHandle;
Art* art = artLock(object->fid, &cacheHandle);
if (art != NULL) {
if (art != nullptr) {
if ((sad->flags & ANIM_SAD_FOREVER) == 0 && object->frame == artGetFrameCount(art) - 1) {
sad->field_20 = -1000;
artUnlock(cacheHandle);
@@ -2834,7 +2835,7 @@ void _object_animate()
CacheEntry* cacheHandle;
Art* art = artLock(object->fid, &cacheHandle);
if (art != NULL) {
if (art != nullptr) {
artGetFrameOffsets(art, object->frame, object->rotation, &x, &y);
artUnlock(cacheHandle);
}
@@ -2857,7 +2858,7 @@ void _object_animate()
CacheEntry* cacheHandle;
Art* art = artLock(object->fid, &cacheHandle);
if (art != NULL) {
if (art != nullptr) {
artGetRotationOffsets(art, object->rotation, &x, &y);
artUnlock(cacheHandle);
} else {
@@ -2869,7 +2870,7 @@ void _object_animate()
rectUnion(&dirtyRect, &tempRect, &dirtyRect);
art = artLock(object->fid, &cacheHandle);
if (art != NULL) {
if (art != nullptr) {
int frame;
if ((sad->flags & ANIM_SAD_REVERSE) != 0) {
frame = artGetFrameCount(art) - 1;
@@ -3051,7 +3052,7 @@ void _dude_fidget()
int candidatesLength = 0;
Object* object = objectFindFirstAtElevation(gDude->elevation);
while (object != NULL) {
while (object != nullptr) {
if (candidatesLength >= 100) {
break;
}
@@ -3128,7 +3129,7 @@ void _dude_stand(Object* obj, int rotation, int fid)
int takeOutFid = buildFid(FID_TYPE(obj->fid), obj->fid & 0xFFF, ANIM_TAKE_OUT, weaponAnimationCode, obj->rotation + 1);
CacheEntry* takeOutFrmHandle;
Art* takeOutFrm = artLock(takeOutFid, &takeOutFrmHandle);
if (takeOutFrm != NULL) {
if (takeOutFrm != nullptr) {
int frameCount = artGetFrameCount(takeOutFrm);
for (int frame = 0; frame < frameCount; frame++) {
int offsetX;
@@ -3142,7 +3143,7 @@ void _dude_stand(Object* obj, int rotation, int fid)
CacheEntry* standFrmHandle;
int standFid = buildFid(FID_TYPE(obj->fid), obj->fid & 0xFFF, ANIM_STAND, 0, obj->rotation + 1);
Art* standFrm = artLock(standFid, &standFrmHandle);
if (standFrm != NULL) {
if (standFrm != nullptr) {
int offsetX;
int offsetY;
if (artGetRotationOffsets(standFrm, obj->rotation, &offsetX, &offsetY) == 0) {
@@ -3293,7 +3294,7 @@ static unsigned int animationComputeTicksPerFrame(Object* object, int fid)
CacheEntry* handle;
Art* frm = artLock(fid, &handle);
if (frm != NULL) {
if (frm != nullptr) {
fps = artGetFramesPerSecond(frm);
artUnlock(handle);
} else {
@@ -3321,7 +3322,7 @@ int animationRegisterSetLightIntensity(Object* owner, int lightDistance, int lig
AnimationSequence* animationSequence = &(gAnimationSequences[gAnimationSequenceCurrentIndex]);
AnimationDescription* animationDescription = &(animationSequence->animations[gAnimationDescriptionCurrentIndex]);
animationDescription->kind = ANIM_KIND_SET_LIGHT_INTENSITY;
animationDescription->artCacheKey = NULL;
animationDescription->artCacheKey = nullptr;
animationDescription->owner = owner;
animationDescription->lightDistance = lightDistance;
animationDescription->lightIntensity = lightIntensity;

View File

@@ -92,7 +92,7 @@ typedef enum AnimationType {
LAST_SF_DEATH_ANIM = ANIM_FALL_FRONT_BLOOD_SF,
} AnimationType;
#define FID_ANIM_TYPE(value) ((value) & 0xFF0000) >> 16
#define FID_ANIM_TYPE(value) ((value)&0xFF0000) >> 16
// Signature of animation callback accepting 2 parameters.
typedef int(AnimationCallback)(void* a1, void* a2);
@@ -145,8 +145,8 @@ int animationRegisterAnimateForever(Object* owner, int anim, int delay);
int animationRegisterPing(int flags, int delay);
int _make_path(Object* object, int from, int to, unsigned char* a4, int a5);
int pathfinderFindPath(Object* object, int from, int to, unsigned char* rotations, int a5, PathBuilderCallback* callback);
int _make_straight_path(Object* a1, int from, int to, StraightPathNode* straightPathNodeList, Object** obstaclePtr, int a6);
int _make_straight_path_func(Object* a1, int from, int to, StraightPathNode* straightPathNodeList, Object** obstaclePtr, int a6, PathBuilderCallback* callback);
int _make_straight_path(Object* object, int from, int to, StraightPathNode* straightPathNodeList, Object** obstaclePtr, int a6);
int _make_straight_path_func(Object* object, int from, int to, StraightPathNode* straightPathNodeList, Object** obstaclePtr, int a6, PathBuilderCallback* callback);
void _object_animate();
int _check_move(int* actionPointsPtr);
int _dude_move(int actionPoints);

View File

@@ -53,17 +53,17 @@ static char gDefaultTribalFemaleFileName[] = "hfprim";
// 0x510738
static ArtListDescription gArtListDescriptions[OBJ_TYPE_COUNT] = {
{ 0, "items", 0, 0, 0 },
{ 0, "critters", 0, 0, 0 },
{ 0, "scenery", 0, 0, 0 },
{ 0, "walls", 0, 0, 0 },
{ 0, "tiles", 0, 0, 0 },
{ 0, "misc", 0, 0, 0 },
{ 0, "intrface", 0, 0, 0 },
{ 0, "inven", 0, 0, 0 },
{ 0, "heads", 0, 0, 0 },
{ 0, "backgrnd", 0, 0, 0 },
{ 0, "skilldex", 0, 0, 0 },
{ 0, "items", nullptr, nullptr, 0 },
{ 0, "critters", nullptr, nullptr, 0 },
{ 0, "scenery", nullptr, nullptr, 0 },
{ 0, "walls", nullptr, nullptr, 0 },
{ 0, "tiles", nullptr, nullptr, 0 },
{ 0, "misc", nullptr, nullptr, 0 },
{ 0, "intrface", nullptr, nullptr, 0 },
{ 0, "inven", nullptr, nullptr, 0 },
{ 0, "heads", nullptr, nullptr, 0 },
{ 0, "backgrnd", nullptr, nullptr, 0 },
{ 0, "skilldex", nullptr, nullptr, 0 },
};
// This flag denotes that localized arts should be looked up first. Used
@@ -159,7 +159,7 @@ int artInit()
}
_anon_alias = (int*)internal_malloc(sizeof(*_anon_alias) * gArtListDescriptions[OBJ_TYPE_CRITTER].fileNamesLength);
if (_anon_alias == NULL) {
if (_anon_alias == nullptr) {
gArtListDescriptions[OBJ_TYPE_CRITTER].fileNamesLength = 0;
debugPrint("Out of memory for anon_alias in art_init\n");
cacheFree(&gArtCache);
@@ -167,7 +167,7 @@ int artInit()
}
gArtCritterFidShoudRunData = (int*)internal_malloc(sizeof(*gArtCritterFidShoudRunData) * gArtListDescriptions[1].fileNamesLength);
if (gArtCritterFidShoudRunData == NULL) {
if (gArtCritterFidShoudRunData == nullptr) {
gArtListDescriptions[OBJ_TYPE_CRITTER].fileNamesLength = 0;
debugPrint("Out of memory for artCritterFidShouldRunData in art_init\n");
cacheFree(&gArtCache);
@@ -181,34 +181,34 @@ int artInit()
snprintf(path, sizeof(path), "%s%s%s\\%s.lst", _cd_path_base, "art\\", gArtListDescriptions[OBJ_TYPE_CRITTER].name, gArtListDescriptions[OBJ_TYPE_CRITTER].name);
stream = fileOpen(path, "rt");
if (stream == NULL) {
if (stream == nullptr) {
debugPrint("Unable to open %s in art_init\n", path);
cacheFree(&gArtCache);
return -1;
}
// SFALL: Modify player model settings.
char* jumpsuitMaleFileName = NULL;
char* jumpsuitMaleFileName = nullptr;
configGetString(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_DUDE_NATIVE_LOOK_JUMPSUIT_MALE_KEY, &jumpsuitMaleFileName);
if (jumpsuitMaleFileName == NULL || jumpsuitMaleFileName[0] == '\0') {
if (jumpsuitMaleFileName == nullptr || jumpsuitMaleFileName[0] == '\0') {
jumpsuitMaleFileName = gDefaultJumpsuitMaleFileName;
}
char* jumpsuitFemaleFileName = NULL;
char* jumpsuitFemaleFileName = nullptr;
configGetString(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_DUDE_NATIVE_LOOK_JUMPSUIT_FEMALE_KEY, &jumpsuitFemaleFileName);
if (jumpsuitFemaleFileName == NULL || jumpsuitFemaleFileName[0] == '\0') {
if (jumpsuitFemaleFileName == nullptr || jumpsuitFemaleFileName[0] == '\0') {
jumpsuitFemaleFileName = gDefaultJumpsuitFemaleFileName;
}
char* tribalMaleFileName = NULL;
char* tribalMaleFileName = nullptr;
configGetString(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_DUDE_NATIVE_LOOK_TRIBAL_MALE_KEY, &tribalMaleFileName);
if (tribalMaleFileName == NULL || tribalMaleFileName[0] == '\0') {
if (tribalMaleFileName == nullptr || tribalMaleFileName[0] == '\0') {
tribalMaleFileName = gDefaultTribalMaleFileName;
}
char* tribalFemaleFileName = NULL;
char* tribalFemaleFileName = nullptr;
configGetString(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_DUDE_NATIVE_LOOK_TRIBAL_FEMALE_KEY, &tribalFemaleFileName);
if (tribalFemaleFileName == NULL || tribalFemaleFileName[0] == '\0') {
if (tribalFemaleFileName == nullptr || tribalFemaleFileName[0] == '\0') {
tribalFemaleFileName = gDefaultTribalFemaleFileName;
}
@@ -236,11 +236,11 @@ int artInit()
}
char* sep1 = strchr(string, ',');
if (sep1 != NULL) {
if (sep1 != nullptr) {
_anon_alias[critterIndex] = atoi(sep1 + 1);
char* sep2 = strchr(sep1 + 1, ',');
if (sep2 != NULL) {
if (sep2 != nullptr) {
gArtCritterFidShoudRunData[critterIndex] = atoi(sep2 + 1);
} else {
gArtCritterFidShoudRunData[critterIndex] = 0;
@@ -262,7 +262,7 @@ int artInit()
}
gHeadDescriptions = (HeadDescription*)internal_malloc(sizeof(*gHeadDescriptions) * gArtListDescriptions[OBJ_TYPE_HEAD].fileNamesLength);
if (gHeadDescriptions == NULL) {
if (gHeadDescriptions == nullptr) {
gArtListDescriptions[OBJ_TYPE_HEAD].fileNamesLength = 0;
debugPrint("Out of memory for head_info in art_init\n");
cacheFree(&gArtCache);
@@ -272,7 +272,7 @@ int artInit()
snprintf(path, sizeof(path), "%s%s%s\\%s.lst", _cd_path_base, "art\\", gArtListDescriptions[OBJ_TYPE_HEAD].name, gArtListDescriptions[OBJ_TYPE_HEAD].name);
stream = fileOpen(path, "rt");
if (stream == NULL) {
if (stream == nullptr) {
debugPrint("Unable to open %s in art_init\n", path);
cacheFree(&gArtCache);
return -1;
@@ -284,14 +284,14 @@ int artInit()
}
char* sep1 = strchr(string, ',');
if (sep1 != NULL) {
if (sep1 != nullptr) {
*sep1 = '\0';
} else {
sep1 = string;
}
char* sep2 = strchr(sep1, ',');
if (sep2 != NULL) {
if (sep2 != nullptr) {
*sep2 = '\0';
} else {
sep2 = sep1;
@@ -300,7 +300,7 @@ int artInit()
gHeadDescriptions[headIndex].goodFidgetCount = atoi(sep1 + 1);
char* sep3 = strchr(sep2, ',');
if (sep3 != NULL) {
if (sep3 != nullptr) {
*sep3 = '\0';
} else {
sep3 = sep2;
@@ -309,7 +309,7 @@ int artInit()
gHeadDescriptions[headIndex].neutralFidgetCount = atoi(sep2 + 1);
char* sep4 = strpbrk(sep3 + 1, " ,;\t\n");
if (sep4 != NULL) {
if (sep4 != nullptr) {
*sep4 = '\0';
}
@@ -336,10 +336,10 @@ void artExit()
for (int index = 0; index < OBJ_TYPE_COUNT; index++) {
internal_free(gArtListDescriptions[index].fileNames);
gArtListDescriptions[index].fileNames = NULL;
gArtListDescriptions[index].fileNames = nullptr;
internal_free(gArtListDescriptions[index].field_18);
gArtListDescriptions[index].field_18 = NULL;
gArtListDescriptions[index].field_18 = nullptr;
}
internal_free(gHeadDescriptions);
@@ -348,7 +348,7 @@ void artExit()
// 0x418F1C
char* artGetObjectTypeName(int objectType)
{
return objectType >= OBJ_TYPE_ITEM && objectType < OBJ_TYPE_COUNT ? gArtListDescriptions[objectType].name : NULL;
return objectType >= OBJ_TYPE_ITEM && objectType < OBJ_TYPE_COUNT ? gArtListDescriptions[objectType].name : nullptr;
}
// 0x418F34
@@ -396,7 +396,7 @@ void artRender(int fid, unsigned char* dest, int width, int height, int pitch)
CacheEntry* handle;
Art* frm = artLock(fid, &handle);
if (frm == NULL) {
if (frm == nullptr) {
return;
}
@@ -438,14 +438,22 @@ void artRender(int fid, unsigned char* dest, int width, int height, int pitch)
artUnlock(handle);
}
// mapper2.exe: 0x40A03C
int art_list_str(int fid, char* name)
{
// TODO: Incomplete.
return -1;
}
// 0x419160
Art* artLock(int fid, CacheEntry** handlePtr)
{
if (handlePtr == NULL) {
return NULL;
if (handlePtr == nullptr) {
return nullptr;
}
Art* art = NULL;
Art* art = nullptr;
cacheLock(&gArtCache, fid, (void**)&art, handlePtr);
return art;
}
@@ -456,44 +464,44 @@ unsigned char* artLockFrameData(int fid, int frame, int direction, CacheEntry**
Art* art;
ArtFrame* frm;
art = NULL;
art = nullptr;
if (handlePtr) {
cacheLock(&gArtCache, fid, (void**)&art, handlePtr);
}
if (art != NULL) {
if (art != nullptr) {
frm = artGetFrame(art, frame, direction);
if (frm != NULL) {
if (frm != nullptr) {
return (unsigned char*)frm + sizeof(*frm);
}
}
return NULL;
return nullptr;
}
// 0x4191CC
unsigned char* artLockFrameDataReturningSize(int fid, CacheEntry** handlePtr, int* widthPtr, int* heightPtr)
{
*handlePtr = NULL;
*handlePtr = nullptr;
Art* art;
Art* art = nullptr;
cacheLock(&gArtCache, fid, (void**)&art, handlePtr);
if (art == NULL) {
return NULL;
if (art == nullptr) {
return nullptr;
}
// NOTE: Uninline.
*widthPtr = artGetWidth(art, 0, 0);
if (*widthPtr == -1) {
return NULL;
return nullptr;
}
// NOTE: Uninline.
*heightPtr = artGetHeight(art, 0, 0);
if (*heightPtr == -1) {
return NULL;
return nullptr;
}
// NOTE: Uninline.
@@ -626,18 +634,18 @@ char* artBuildFilePath(int fid)
type = FID_TYPE(v2);
if (v3 >= gArtListDescriptions[type].fileNamesLength) {
return NULL;
return nullptr;
}
if (type < OBJ_TYPE_ITEM || type >= OBJ_TYPE_COUNT) {
return NULL;
return nullptr;
}
v8 = v3 * 13;
if (type == 1) {
if (_art_get_code(v4, v5, &v11, &v12) == -1) {
return NULL;
return nullptr;
}
if (v10) {
snprintf(_art_name, sizeof(_art_name), "%s%s%s\\%s%c%c.fr%c", _cd_path_base, "art\\", gArtListDescriptions[1].name, gArtListDescriptions[1].fileNames + v8, v11, v12, v10 + 47);
@@ -663,7 +671,7 @@ char* artBuildFilePath(int fid)
static int artReadList(const char* path, char** artListPtr, int* artListSizePtr)
{
File* stream = fileOpen(path, "rt");
if (stream == NULL) {
if (stream == nullptr) {
return -1;
}
@@ -679,14 +687,14 @@ static int artReadList(const char* path, char** artListPtr, int* artListSizePtr)
char* artList = (char*)internal_malloc(13 * count);
*artListPtr = artList;
if (artList == NULL) {
if (artList == nullptr) {
fileClose(stream);
return -1;
}
while (fileReadString(string, sizeof(string), stream)) {
char* brk = strpbrk(string, " ,;\r\t\n");
if (brk != NULL) {
if (brk != nullptr) {
*brk = '\0';
}
@@ -704,7 +712,7 @@ static int artReadList(const char* path, char** artListPtr, int* artListSizePtr)
// 0x419760
int artGetFramesPerSecond(Art* art)
{
if (art == NULL) {
if (art == nullptr) {
return 10;
}
@@ -714,13 +722,13 @@ int artGetFramesPerSecond(Art* art)
// 0x419778
int artGetActionFrame(Art* art)
{
return art == NULL ? -1 : art->actionFrame;
return art == nullptr ? -1 : art->actionFrame;
}
// 0x41978C
int artGetFrameCount(Art* art)
{
return art == NULL ? -1 : art->frameCount;
return art == nullptr ? -1 : art->frameCount;
}
// 0x4197A0
@@ -729,7 +737,7 @@ int artGetWidth(Art* art, int frame, int direction)
ArtFrame* frm;
frm = artGetFrame(art, frame, direction);
if (frm == NULL) {
if (frm == nullptr) {
return -1;
}
@@ -742,7 +750,7 @@ int artGetHeight(Art* art, int frame, int direction)
ArtFrame* frm;
frm = artGetFrame(art, frame, direction);
if (frm == NULL) {
if (frm == nullptr) {
return -1;
}
@@ -755,23 +763,23 @@ int artGetSize(Art* art, int frame, int direction, int* widthPtr, int* heightPtr
ArtFrame* frm;
frm = artGetFrame(art, frame, direction);
if (frm == NULL) {
if (widthPtr != NULL) {
if (frm == nullptr) {
if (widthPtr != nullptr) {
*widthPtr = 0;
}
if (heightPtr != NULL) {
if (heightPtr != nullptr) {
*heightPtr = 0;
}
return -1;
}
if (widthPtr != NULL) {
if (widthPtr != nullptr) {
*widthPtr = frm->width;
}
if (heightPtr != NULL) {
if (heightPtr != nullptr) {
*heightPtr = frm->height;
}
@@ -784,7 +792,7 @@ int artGetFrameOffsets(Art* art, int frame, int direction, int* xPtr, int* yPtr)
ArtFrame* frm;
frm = artGetFrame(art, frame, direction);
if (frm == NULL) {
if (frm == nullptr) {
return -1;
}
@@ -797,7 +805,7 @@ int artGetFrameOffsets(Art* art, int frame, int direction, int* xPtr, int* yPtr)
// 0x41984C
int artGetRotationOffsets(Art* art, int rotation, int* xPtr, int* yPtr)
{
if (art == NULL) {
if (art == nullptr) {
return -1;
}
@@ -813,8 +821,8 @@ unsigned char* artGetFrameData(Art* art, int frame, int direction)
ArtFrame* frm;
frm = artGetFrame(art, frame, direction);
if (frm == NULL) {
return NULL;
if (frm == nullptr) {
return nullptr;
}
return (unsigned char*)frm + sizeof(*frm);
@@ -824,15 +832,15 @@ unsigned char* artGetFrameData(Art* art, int frame, int direction)
ArtFrame* artGetFrame(Art* art, int frame, int rotation)
{
if (rotation < 0 || rotation >= 6) {
return NULL;
return nullptr;
}
if (art == NULL) {
return NULL;
if (art == nullptr) {
return nullptr;
}
if (frame < 0 || frame >= art->frameCount) {
return NULL;
return nullptr;
}
ArtFrame* frm = (ArtFrame*)((unsigned char*)art + sizeof(*art) + art->dataOffsets[rotation] + art->padding[rotation]);
@@ -848,7 +856,7 @@ bool artExists(int fid)
bool result = false;
char* filePath = artBuildFilePath(fid);
if (filePath != NULL) {
if (filePath != nullptr) {
int fileSize;
if (dbGetFileSize(filePath, &fileSize) != -1) {
result = true;
@@ -866,7 +874,7 @@ bool _art_fid_valid(int fid)
bool result = false;
char* filePath = artBuildFilePath(fid);
if (filePath != NULL) {
if (filePath != nullptr) {
int fileSize;
if (dbGetFileSize(filePath, &fileSize) != -1) {
result = true;
@@ -922,13 +930,13 @@ static int artCacheGetFileSizeImpl(int fid, int* sizePtr)
int result = -1;
char* artFilePath = artBuildFilePath(fid);
if (artFilePath != NULL) {
if (artFilePath != nullptr) {
bool loaded = false;
File* stream = NULL;
File* stream = nullptr;
if (gArtLanguageInitialized) {
char* pch = strchr(artFilePath, '\\');
if (pch == NULL) {
if (pch == nullptr) {
pch = artFilePath;
}
@@ -938,11 +946,11 @@ static int artCacheGetFileSizeImpl(int fid, int* sizePtr)
stream = fileOpen(localizedPath, "rb");
}
if (stream == NULL) {
if (stream == nullptr) {
stream = fileOpen(artFilePath, "rb");
}
if (stream != NULL) {
if (stream != nullptr) {
Art art;
if (artReadHeader(&art, stream) == 0) {
*sizePtr = artGetDataSize(&art);
@@ -961,11 +969,11 @@ static int artCacheReadDataImpl(int fid, int* sizePtr, unsigned char* data)
int result = -1;
char* artFileName = artBuildFilePath(fid);
if (artFileName != NULL) {
if (artFileName != nullptr) {
bool loaded = false;
if (gArtLanguageInitialized) {
char* pch = strchr(artFileName, '\\');
if (pch == NULL) {
if (pch == nullptr) {
pch = artFileName;
}
@@ -1076,14 +1084,53 @@ static int artReadHeader(Art* art, File* stream)
if (fileReadInt32List(stream, art->dataOffsets, ROTATION_COUNT) == -1) return -1;
if (fileReadInt32(stream, &(art->dataSize)) == -1) return -1;
// CE: Fix malformed `frm` files with `dataSize` set to 0 in Nevada.
if (art->dataSize == 0) {
art->dataSize = fileGetSize(stream);
}
return 0;
}
// NOTE: Original function was slightly different, but never used. Basically
// it's a memory allocating variant of `artRead` (which reads data into given
// buffer). This function is useful to load custom `frm` files since `Art` now
// needs more memory then it's on-disk size (due to memory padding).
//
// 0x419EC0
Art* artLoad(const char* path)
{
File* stream = fileOpen(path, "rb");
if (stream == nullptr) {
return nullptr;
}
Art header;
if (artReadHeader(&header, stream) != 0) {
fileClose(stream);
return nullptr;
}
fileClose(stream);
unsigned char* data = reinterpret_cast<unsigned char*>(internal_malloc(artGetDataSize(&header)));
if (data == nullptr) {
return nullptr;
}
if (artRead(path, data) != 0) {
internal_free(data);
return nullptr;
}
return reinterpret_cast<Art*>(data);
}
// 0x419FC0
int artRead(const char* path, unsigned char* data)
{
File* stream = fileOpen(path, "rb");
if (stream == NULL) {
if (stream == nullptr) {
return -2;
}
@@ -1158,12 +1205,12 @@ int artWriteHeader(Art* art, File* stream)
// 0x41A1E8
int artWrite(const char* path, unsigned char* data)
{
if (data == NULL) {
if (data == nullptr) {
return -1;
}
File* stream = fileOpen(path, "wb");
if (stream == NULL) {
if (stream == nullptr) {
return -1;
}

View File

@@ -123,6 +123,7 @@ char* artGetObjectTypeName(int objectType);
int artIsObjectTypeHidden(int objectType);
int artGetFidgetCount(int headFid);
void artRender(int fid, unsigned char* dest, int width, int height, int pitch);
int art_list_str(int fid, char* name);
Art* artLock(int fid, CacheEntry** cache_entry);
unsigned char* artLockFrameData(int fid, int frame, int direction, CacheEntry** out_cache_entry);
unsigned char* artLockFrameDataReturningSize(int fid, CacheEntry** out_cache_entry, int* widthPtr, int* heightPtr);
@@ -147,6 +148,7 @@ int _art_alias_num(int a1);
int artCritterFidShouldRun(int a1);
int artAliasFid(int fid);
int buildFid(int objectType, int frmId, int animType, int a4, int rotation);
Art* artLoad(const char* path);
int artRead(const char* path, unsigned char* data);
int artWrite(const char* path, unsigned char* data);

View File

@@ -7,7 +7,6 @@
#include "db.h"
#include "debug.h"
#include "memory_manager.h"
#include "pointer_registry.h"
#include "sound.h"
#include "sound_decoder.h"
@@ -20,7 +19,7 @@ typedef enum AudioFlags {
typedef struct Audio {
int flags;
int stream;
File* stream;
SoundDecoder* soundDecoder;
int fileSize;
int sampleRate;
@@ -29,7 +28,7 @@ typedef struct Audio {
} Audio;
static bool defaultCompressionFunc(char* filePath);
static int audioSoundDecoderReadHandler(int fileHandle, void* buf, unsigned int size);
static int audioSoundDecoderReadHandler(void* data, void* buf, unsigned int size);
// 0x5108BC
static AudioQueryCompressedFunc* queryCompressedFunc = defaultCompressionFunc;
@@ -44,7 +43,7 @@ static Audio* gAudioList;
static bool defaultCompressionFunc(char* filePath)
{
char* pch = strrchr(filePath, '.');
if (pch != NULL) {
if (pch != nullptr) {
strcpy(pch + 1, "raw");
}
@@ -52,14 +51,14 @@ static bool defaultCompressionFunc(char* filePath)
}
// 0x41A2D0
static int audioSoundDecoderReadHandler(int handle, void* buffer, unsigned int size)
static int audioSoundDecoderReadHandler(void* data, void* buffer, unsigned int size)
{
return fileRead(buffer, 1, size, (File*)intToPtr(handle));
return fileRead(buffer, 1, size, reinterpret_cast<File*>(data));
}
// AudioOpen
// 0x41A2EC
int audioOpen(const char* fname, int flags, ...)
int audioOpen(const char* fname, int* sampleRate)
{
char path[80];
snprintf(path, sizeof(path), "%s", fname);
@@ -71,29 +70,8 @@ int audioOpen(const char* fname, int flags, ...)
compression = 0;
}
char mode[4];
memset(mode, 0, 4);
// NOTE: Original implementation is slightly different, it uses separate
// variable to track index where to set 't' and 'b'.
char* pm = mode;
if (flags & 1) {
*pm++ = 'w';
} else if (flags & 2) {
*pm++ = 'w';
*pm++ = '+';
} else {
*pm++ = 'r';
}
if (flags & 0x100) {
*pm++ = 't';
} else if (flags & 0x200) {
*pm++ = 'b';
}
File* stream = fileOpen(path, mode);
if (stream == NULL) {
File* stream = fileOpen(path, "rb");
if (stream == nullptr) {
debugPrint("AudioOpen: Couldn't open %s for read\n", path);
return -1;
}
@@ -106,7 +84,7 @@ int audioOpen(const char* fname, int flags, ...)
}
if (index == gAudioListLength) {
if (gAudioList != NULL) {
if (gAudioList != nullptr) {
gAudioList = (Audio*)internal_realloc_safe(gAudioList, sizeof(*gAudioList) * (gAudioListLength + 1), __FILE__, __LINE__); // "..\int\audio.c", 216
} else {
gAudioList = (Audio*)internal_malloc_safe(sizeof(*gAudioList), __FILE__, __LINE__); // "..\int\audio.c", 218
@@ -116,12 +94,14 @@ int audioOpen(const char* fname, int flags, ...)
Audio* audioFile = &(gAudioList[index]);
audioFile->flags = AUDIO_IN_USE;
audioFile->stream = ptrToInt(stream);
audioFile->stream = stream;
if (compression == 2) {
audioFile->flags |= AUDIO_COMPRESSED;
audioFile->soundDecoder = soundDecoderInit(audioSoundDecoderReadHandler, audioFile->stream, &(audioFile->channels), &(audioFile->sampleRate), &(audioFile->fileSize));
audioFile->fileSize *= 2;
*sampleRate = audioFile->sampleRate;
} else {
audioFile->fileSize = fileGetSize(stream);
}
@@ -135,7 +115,7 @@ int audioOpen(const char* fname, int flags, ...)
int audioClose(int handle)
{
Audio* audioFile = &(gAudioList[handle - 1]);
fileClose((File*)intToPtr(audioFile->stream, true));
fileClose(audioFile->stream);
if ((audioFile->flags & AUDIO_COMPRESSED) != 0) {
soundDecoderFree(audioFile->soundDecoder);
@@ -155,7 +135,7 @@ int audioRead(int handle, void* buffer, unsigned int size)
if ((audioFile->flags & AUDIO_COMPRESSED) != 0) {
bytesRead = soundDecoderDecode(audioFile->soundDecoder, buffer, size);
} else {
bytesRead = fileRead(buffer, 1, size, (File*)intToPtr(audioFile->stream));
bytesRead = fileRead(buffer, 1, size, audioFile->stream);
}
audioFile->position += bytesRead;
@@ -189,7 +169,7 @@ long audioSeek(int handle, long offset, int origin)
if ((audioFile->flags & AUDIO_COMPRESSED) != 0) {
if (pos < audioFile->position) {
soundDecoderFree(audioFile->soundDecoder);
fileSeek((File*)intToPtr(audioFile->stream), 0, SEEK_SET);
fileSeek(audioFile->stream, 0, SEEK_SET);
audioFile->soundDecoder = soundDecoderInit(audioSoundDecoderReadHandler, audioFile->stream, &(audioFile->channels), &(audioFile->sampleRate), &(audioFile->fileSize));
audioFile->position = 0;
audioFile->fileSize *= 2;
@@ -224,7 +204,7 @@ long audioSeek(int handle, long offset, int origin)
return audioFile->position;
} else {
return fileSeek((File*)intToPtr(audioFile->stream), offset, origin);
return fileSeek(audioFile->stream, offset, origin);
}
}
@@ -254,7 +234,7 @@ int audioWrite(int handle, const void* buf, unsigned int size)
int audioInit(AudioQueryCompressedFunc* func)
{
queryCompressedFunc = func;
gAudioList = NULL;
gAudioList = nullptr;
gAudioListLength = 0;
return soundSetDefaultFileIO(audioOpen, audioClose, audioRead, audioWrite, audioSeek, audioTell, audioGetSize);
@@ -263,12 +243,12 @@ int audioInit(AudioQueryCompressedFunc* func)
// 0x41A818
void audioExit()
{
if (gAudioList != NULL) {
if (gAudioList != nullptr) {
internal_free_safe(gAudioList, __FILE__, __LINE__); // "..\int\audio.c", 406
}
gAudioListLength = 0;
gAudioList = NULL;
gAudioList = nullptr;
}
} // namespace fallout

View File

@@ -5,7 +5,7 @@ namespace fallout {
typedef bool(AudioQueryCompressedFunc)(char* filePath);
int audioOpen(const char* fname, int mode, ...);
int audioOpen(const char* fname, int* sampleRate);
int audioClose(int handle);
int audioRead(int handle, void* buffer, unsigned int size);
long audioSeek(int handle, long offset, int origin);

View File

@@ -106,7 +106,7 @@ bool audioEngineInit()
desiredSpec.samples = 1024;
desiredSpec.callback = audioEngineMixin;
gAudioEngineDeviceId = SDL_OpenAudioDevice(NULL, 0, &desiredSpec, &gAudioEngineSpec, SDL_AUDIO_ALLOW_ANY_CHANGE);
gAudioEngineDeviceId = SDL_OpenAudioDevice(nullptr, 0, &desiredSpec, &gAudioEngineSpec, SDL_AUDIO_ALLOW_ANY_CHANGE);
if (gAudioEngineDeviceId == -1) {
return false;
}
@@ -191,10 +191,10 @@ bool audioEngineSoundBufferRelease(int soundBufferIndex)
soundBuffer->active = false;
free(soundBuffer->data);
soundBuffer->data = NULL;
soundBuffer->data = nullptr;
SDL_FreeAudioStream(soundBuffer->stream);
soundBuffer->stream = NULL;
soundBuffer->stream = nullptr;
return true;
}
@@ -331,11 +331,11 @@ bool audioEngineSoundBufferGetCurrentPosition(int soundBufferIndex, unsigned int
return false;
}
if (readPosPtr != NULL) {
if (readPosPtr != nullptr) {
*readPosPtr = soundBuffer->pos;
}
if (writePosPtr != NULL) {
if (writePosPtr != nullptr) {
*writePosPtr = soundBuffer->pos;
if (soundBuffer->playing) {
@@ -388,12 +388,12 @@ bool audioEngineSoundBufferLock(int soundBufferIndex, unsigned int writePos, uns
return false;
}
if (audioBytes1 == NULL) {
if (audioBytes1 == nullptr) {
return false;
}
if ((flags & AUDIO_ENGINE_SOUND_BUFFER_LOCK_FROM_WRITE_POS) != 0) {
if (!audioEngineSoundBufferGetCurrentPosition(soundBufferIndex, NULL, &writePos)) {
if (!audioEngineSoundBufferGetCurrentPosition(soundBufferIndex, nullptr, &writePos)) {
return false;
}
}
@@ -406,11 +406,11 @@ bool audioEngineSoundBufferLock(int soundBufferIndex, unsigned int writePos, uns
*(unsigned char**)audioPtr1 = (unsigned char*)soundBuffer->data + writePos;
*audioBytes1 = writeBytes;
if (audioPtr2 != NULL) {
*audioPtr2 = NULL;
if (audioPtr2 != nullptr) {
*audioPtr2 = nullptr;
}
if (audioBytes2 != NULL) {
if (audioBytes2 != nullptr) {
*audioBytes2 = 0;
}
} else {
@@ -418,11 +418,11 @@ bool audioEngineSoundBufferLock(int soundBufferIndex, unsigned int writePos, uns
*(unsigned char**)audioPtr1 = (unsigned char*)soundBuffer->data + writePos;
*audioBytes1 = soundBuffer->size - writePos;
if (audioPtr2 != NULL) {
if (audioPtr2 != nullptr) {
*(unsigned char**)audioPtr2 = (unsigned char*)soundBuffer->data;
}
if (audioBytes2 != NULL) {
if (audioBytes2 != nullptr) {
*audioBytes2 = writeBytes - (soundBuffer->size - writePos);
}
}
@@ -471,7 +471,7 @@ bool audioEngineSoundBufferGetStatus(int soundBufferIndex, unsigned int* statusP
return false;
}
if (statusPtr == NULL) {
if (statusPtr == nullptr) {
return false;
}

View File

@@ -7,7 +7,6 @@
#include "debug.h"
#include "memory_manager.h"
#include "platform_compat.h"
#include "pointer_registry.h"
#include "sound.h"
#include "sound_decoder.h"
@@ -20,7 +19,7 @@ typedef enum AudioFileFlags {
typedef struct AudioFile {
int flags;
int stream;
FILE* stream;
SoundDecoder* soundDecoder;
int fileSize;
int sampleRate;
@@ -29,7 +28,7 @@ typedef struct AudioFile {
} AudioFile;
static bool defaultCompressionFunc(char* filePath);
static int audioFileSoundDecoderReadHandler(int handle, void* buffer, unsigned int size);
static int audioFileSoundDecoderReadHandler(void* data, void* buffer, unsigned int size);
// 0x5108C0
static AudioFileQueryCompressedFunc* queryCompressedFunc = defaultCompressionFunc;
@@ -44,7 +43,7 @@ static int gAudioFileListLength;
static bool defaultCompressionFunc(char* filePath)
{
char* pch = strrchr(filePath, '.');
if (pch != NULL) {
if (pch != nullptr) {
strcpy(pch + 1, "raw");
}
@@ -52,13 +51,13 @@ static bool defaultCompressionFunc(char* filePath)
}
// 0x41A870
static int audioFileSoundDecoderReadHandler(int handle, void* buffer, unsigned int size)
static int audioFileSoundDecoderReadHandler(void* data, void* buffer, unsigned int size)
{
return fread(buffer, 1, size, (FILE*)intToPtr(handle));
return fread(buffer, 1, size, reinterpret_cast<FILE*>(data));
}
// 0x41A88C
int audioFileOpen(const char* fname, int flags, ...)
int audioFileOpen(const char* fname, int* sampleRate)
{
char path[COMPAT_MAX_PATH];
strcpy(path, fname);
@@ -70,29 +69,8 @@ int audioFileOpen(const char* fname, int flags, ...)
compression = 0;
}
char mode[4];
memset(mode, '\0', 4);
// NOTE: Original implementation is slightly different, it uses separate
// variable to track index where to set 't' and 'b'.
char* pm = mode;
if (flags & 0x01) {
*pm++ = 'w';
} else if (flags & 0x02) {
*pm++ = 'w';
*pm++ = '+';
} else {
*pm++ = 'r';
}
if (flags & 0x0100) {
*pm++ = 't';
} else if (flags & 0x0200) {
*pm++ = 'b';
}
FILE* stream = compat_fopen(path, mode);
if (stream == NULL) {
FILE* stream = compat_fopen(path, "rb");
if (stream == nullptr) {
return -1;
}
@@ -104,7 +82,7 @@ int audioFileOpen(const char* fname, int flags, ...)
}
if (index == gAudioFileListLength) {
if (gAudioFileList != NULL) {
if (gAudioFileList != nullptr) {
gAudioFileList = (AudioFile*)internal_realloc_safe(gAudioFileList, sizeof(*gAudioFileList) * (gAudioFileListLength + 1), __FILE__, __LINE__); // "..\int\audiof.c", 207
} else {
gAudioFileList = (AudioFile*)internal_malloc_safe(sizeof(*gAudioFileList), __FILE__, __LINE__); // "..\int\audiof.c", 209
@@ -114,12 +92,14 @@ int audioFileOpen(const char* fname, int flags, ...)
AudioFile* audioFile = &(gAudioFileList[index]);
audioFile->flags = AUDIO_FILE_IN_USE;
audioFile->stream = ptrToInt(stream);
audioFile->stream = stream;
if (compression == 2) {
audioFile->flags |= AUDIO_FILE_COMPRESSED;
audioFile->soundDecoder = soundDecoderInit(audioFileSoundDecoderReadHandler, audioFile->stream, &(audioFile->channels), &(audioFile->sampleRate), &(audioFile->fileSize));
audioFile->fileSize *= 2;
*sampleRate = audioFile->sampleRate;
} else {
audioFile->fileSize = getFileSize(stream);
}
@@ -133,7 +113,7 @@ int audioFileOpen(const char* fname, int flags, ...)
int audioFileClose(int handle)
{
AudioFile* audioFile = &(gAudioFileList[handle - 1]);
fclose((FILE*)intToPtr(audioFile->stream, true));
fclose(audioFile->stream);
if ((audioFile->flags & AUDIO_FILE_COMPRESSED) != 0) {
soundDecoderFree(audioFile->soundDecoder);
@@ -155,7 +135,7 @@ int audioFileRead(int handle, void* buffer, unsigned int size)
if ((ptr->flags & AUDIO_FILE_COMPRESSED) != 0) {
bytesRead = soundDecoderDecode(ptr->soundDecoder, buffer, size);
} else {
bytesRead = fread(buffer, 1, size, (FILE*)intToPtr(ptr->stream));
bytesRead = fread(buffer, 1, size, ptr->stream);
}
ptr->position += bytesRead;
@@ -190,7 +170,7 @@ long audioFileSeek(int handle, long offset, int origin)
if (a4 <= audioFile->position) {
soundDecoderFree(audioFile->soundDecoder);
fseek((FILE*)intToPtr(audioFile->stream), 0, 0);
fseek(audioFile->stream, 0, 0);
audioFile->soundDecoder = soundDecoderInit(audioFileSoundDecoderReadHandler, audioFile->stream, &(audioFile->channels), &(audioFile->sampleRate), &(audioFile->fileSize));
audioFile->fileSize *= 2;
@@ -222,7 +202,7 @@ long audioFileSeek(int handle, long offset, int origin)
return audioFile->position;
}
return fseek((FILE*)intToPtr(audioFile->stream), offset, origin);
return fseek(audioFile->stream, offset, origin);
}
// 0x41AD20
@@ -251,7 +231,7 @@ int audioFileWrite(int handle, const void* buffer, unsigned int size)
int audioFileInit(AudioFileQueryCompressedFunc* func)
{
queryCompressedFunc = func;
gAudioFileList = NULL;
gAudioFileList = nullptr;
gAudioFileListLength = 0;
return soundSetDefaultFileIO(audioFileOpen, audioFileClose, audioFileRead, audioFileWrite, audioFileSeek, audioFileTell, audioFileGetSize);
@@ -260,12 +240,12 @@ int audioFileInit(AudioFileQueryCompressedFunc* func)
// 0x41ADAC
void audioFileExit()
{
if (gAudioFileList != NULL) {
if (gAudioFileList != nullptr) {
internal_free_safe(gAudioFileList, __FILE__, __LINE__); // "..\int\audiof.c", 405
}
gAudioFileListLength = 0;
gAudioFileList = NULL;
gAudioFileList = nullptr;
}
} // namespace fallout

View File

@@ -5,7 +5,7 @@ namespace fallout {
typedef bool(AudioFileQueryCompressedFunc)(char* filePath);
int audioFileOpen(const char* fname, int flags, ...);
int audioFileOpen(const char* fname, int* sampleRate);
int audioFileClose(int handle);
int audioFileRead(int handle, void* buf, unsigned int size);
long audioFileSeek(int handle, long offset, int origin);

View File

@@ -336,7 +336,7 @@ void automapShow(bool isInGame, bool isUsingScanner)
KEY_LOWERCASE_S,
frmImages[AUTOMAP_FRM_BUTTON_UP].getData(),
frmImages[AUTOMAP_FRM_BUTTON_DOWN].getData(),
NULL,
nullptr,
BUTTON_FLAG_TRANSPARENT);
if (scannerBtn != -1) {
buttonSetCallbacks(scannerBtn, _gsound_red_butt_press, _gsound_red_butt_release);
@@ -353,7 +353,7 @@ void automapShow(bool isInGame, bool isUsingScanner)
KEY_ESCAPE,
frmImages[AUTOMAP_FRM_BUTTON_UP].getData(),
frmImages[AUTOMAP_FRM_BUTTON_DOWN].getData(),
NULL,
nullptr,
BUTTON_FLAG_TRANSPARENT);
if (cancelBtn != -1) {
buttonSetCallbacks(cancelBtn, _gsound_red_butt_press, _gsound_red_butt_release);
@@ -370,7 +370,7 @@ void automapShow(bool isInGame, bool isUsingScanner)
KEY_LOWERCASE_H,
frmImages[AUTOMAP_FRM_SWITCH_UP].getData(),
frmImages[AUTOMAP_FRM_SWITCH_DOWN].getData(),
NULL,
nullptr,
BUTTON_FLAG_TRANSPARENT | BUTTON_FLAG_0x01);
if (switchBtn != -1) {
buttonSetCallbacks(switchBtn, _gsound_toggle_butt_press_, _gsound_toggle_butt_press_);
@@ -435,19 +435,19 @@ void automapShow(bool isInGame, bool isUsingScanner)
}
if ((gAutomapFlags & AUTOMAP_WITH_SCANNER) == 0) {
Object* scanner = NULL;
Object* scanner = nullptr;
Object* item1 = critterGetItem1(gDude);
if (item1 != NULL && item1->pid == PROTO_ID_MOTION_SENSOR) {
if (item1 != nullptr && item1->pid == PROTO_ID_MOTION_SENSOR) {
scanner = item1;
} else {
Object* item2 = critterGetItem2(gDude);
if (item2 != NULL && item2->pid == PROTO_ID_MOTION_SENSOR) {
if (item2 != nullptr && item2->pid == PROTO_ID_MOTION_SENSOR) {
scanner = item2;
}
}
if (scanner != NULL && miscItemGetCharges(scanner) > 0) {
if (scanner != nullptr && miscItemGetCharges(scanner) > 0) {
needsRefresh = true;
gAutomapFlags |= AUTOMAP_WITH_SCANNER;
miscItemConsumeCharge(scanner);
@@ -457,8 +457,8 @@ void automapShow(bool isInGame, bool isUsingScanner)
MessageListItem messageListItem;
// 17 - The motion sensor is not installed.
// 18 - The motion sensor has no charges remaining.
const char* title = getmsg(&gMiscMessageList, &messageListItem, scanner != NULL ? 18 : 17);
showDialogBox(title, NULL, 0, 165, 140, _colorTable[32328], NULL, _colorTable[32328], 0);
const char* title = getmsg(&gMiscMessageList, &messageListItem, scanner != nullptr ? 18 : 17);
showDialogBox(title, nullptr, 0, 165, 140, _colorTable[32328], nullptr, _colorTable[32328], 0);
}
}
@@ -512,7 +512,7 @@ static void automapRenderInMapWindow(int window, int elevation, unsigned char* b
unsigned char* windowBuffer = windowGetBuffer(window);
blitBufferToBuffer(backgroundData, AUTOMAP_WINDOW_WIDTH, AUTOMAP_WINDOW_HEIGHT, AUTOMAP_WINDOW_WIDTH, windowBuffer, AUTOMAP_WINDOW_WIDTH);
for (Object* object = objectFindFirstAtElevation(elevation); object != NULL; object = objectFindNextAtElevation()) {
for (Object* object = objectFindFirstAtElevation(elevation); object != nullptr; object = objectFindNextAtElevation()) {
if (object->tile == -1) {
continue;
}
@@ -626,7 +626,7 @@ int automapRenderInPipboyWindow(int window, int map, int elevation)
unsigned char sceneryColor = _colorTable[480];
gAutomapEntry.data = (unsigned char*)internal_malloc(11024);
if (gAutomapEntry.data == NULL) {
if (gAutomapEntry.data == nullptr) {
debugPrint("\nAUTOMAP: Error allocating data buffer!\n");
return -1;
}
@@ -694,9 +694,9 @@ int automapSaveCurrent()
bool dataBuffersAllocated = false;
gAutomapEntry.data = (unsigned char*)internal_malloc(11024);
if (gAutomapEntry.data != NULL) {
if (gAutomapEntry.data != nullptr) {
gAutomapEntry.compressedData = (unsigned char*)internal_malloc(11024);
if (gAutomapEntry.compressedData != NULL) {
if (gAutomapEntry.compressedData != nullptr) {
dataBuffersAllocated = true;
}
}
@@ -712,7 +712,7 @@ int automapSaveCurrent()
snprintf(path, sizeof(path), "%s\\%s", "MAPS", AUTOMAP_DB);
File* stream1 = fileOpen(path, "r+b");
if (stream1 == NULL) {
if (stream1 == nullptr) {
debugPrint("\nAUTOMAP: Error opening automap database file!\n");
debugPrint("Error continued: automap_pip_save: path: %s", path);
internal_free(gAutomapEntry.data);
@@ -743,7 +743,7 @@ int automapSaveCurrent()
snprintf(path, sizeof(path), "%s\\%s", "MAPS", AUTOMAP_TMP);
File* stream2 = fileOpen(path, "wb");
if (stream2 == NULL) {
if (stream2 == nullptr) {
debugPrint("\nAUTOMAP: Error creating temp file!\n");
internal_free(gAutomapEntry.data);
internal_free(gAutomapEntry.compressedData);
@@ -928,7 +928,7 @@ err:
// 0x41C8CC
static int automapLoadEntry(int map, int elevation)
{
gAutomapEntry.compressedData = NULL;
gAutomapEntry.compressedData = nullptr;
char path[COMPAT_MAX_PATH];
snprintf(path, sizeof(path), "%s\\%s", "MAPS", AUTOMAP_DB);
@@ -936,7 +936,7 @@ static int automapLoadEntry(int map, int elevation)
bool success = true;
File* stream = fileOpen(path, "r+b");
if (stream == NULL) {
if (stream == nullptr) {
debugPrint("\nAUTOMAP: Error opening automap database file!\n");
debugPrint("Error continued: AM_ReadEntry: path: %s", path);
return -1;
@@ -970,7 +970,7 @@ static int automapLoadEntry(int map, int elevation)
if (gAutomapEntry.isCompressed == 1) {
gAutomapEntry.compressedData = (unsigned char*)internal_malloc(11024);
if (gAutomapEntry.compressedData == NULL) {
if (gAutomapEntry.compressedData == nullptr) {
debugPrint("\nAUTOMAP: Error allocating decompression buffer!\n");
fileClose(stream);
return -1;
@@ -1003,7 +1003,7 @@ out:
return -1;
}
if (gAutomapEntry.compressedData != NULL) {
if (gAutomapEntry.compressedData != nullptr) {
internal_free(gAutomapEntry.compressedData);
}
@@ -1073,7 +1073,7 @@ static void _decode_map_data(int elevation)
_obj_process_seen();
Object* object = objectFindFirstAtElevation(elevation);
while (object != NULL) {
while (object != nullptr) {
if (object->tile != -1 && (object->flags & OBJECT_SEEN) != 0) {
int contentType;
@@ -1109,7 +1109,7 @@ static int automapCreate()
snprintf(path, sizeof(path), "%s\\%s", "MAPS", AUTOMAP_DB);
File* stream = fileOpen(path, "wb");
if (stream == NULL) {
if (stream == nullptr) {
debugPrint("\nAUTOMAP: Error creating automap database file!\n");
return -1;
}
@@ -1129,7 +1129,7 @@ static int automapCreate()
static int _copy_file_data(File* stream1, File* stream2, int length)
{
void* buffer = internal_malloc(0xFFFF);
if (buffer == NULL) {
if (buffer == nullptr) {
return -1;
}
@@ -1164,7 +1164,7 @@ int automapGetHeader(AutomapHeader** automapHeaderPtr)
snprintf(path, sizeof(path), "%s\\%s", "MAPS", AUTOMAP_DB);
File* stream = fileOpen(path, "rb");
if (stream == NULL) {
if (stream == nullptr) {
debugPrint("\nAUTOMAP: Error opening database file for reading!\n");
debugPrint("Error continued: ReadAMList: path: %s", path);
return -1;

View File

@@ -1,8 +1,6 @@
#include "autorun.h"
#ifdef _WIN32
#define WIN32_LEAN_AND_MEAN
#define NOMINMAX
#include <windows.h>
#endif
@@ -17,7 +15,7 @@ namespace fallout {
bool autorunMutexCreate()
{
#ifdef _WIN32
gInterplayGenericAutorunMutex = CreateMutexA(NULL, FALSE, "InterplayGenericAutorunMutex");
gInterplayGenericAutorunMutex = CreateMutexA(nullptr, FALSE, "InterplayGenericAutorunMutex");
if (GetLastError() == ERROR_ALREADY_EXISTS) {
CloseHandle(gInterplayGenericAutorunMutex);
return false;
@@ -31,7 +29,7 @@ bool autorunMutexCreate()
void autorunMutexClose()
{
#ifdef _WIN32
if (gInterplayGenericAutorunMutex != NULL) {
if (gInterplayGenericAutorunMutex != nullptr) {
CloseHandle(gInterplayGenericAutorunMutex);
}
#endif

View File

@@ -51,7 +51,7 @@ bool cacheInit(Cache* cache, CacheSizeProc* sizeProc, CacheReadProc* readProc, C
cache->readProc = readProc;
cache->freeProc = freeProc;
if (cache->entries == NULL) {
if (cache->entries == nullptr) {
return false;
}
@@ -64,7 +64,7 @@ bool cacheInit(Cache* cache, CacheSizeProc* sizeProc, CacheReadProc* readProc, C
// 0x41FD50
bool cacheFree(Cache* cache)
{
if (cache == NULL) {
if (cache == nullptr) {
return false;
}
@@ -78,14 +78,14 @@ bool cacheFree(Cache* cache)
cache->entriesCapacity = 0;
cache->hits = 0;
if (cache->entries != NULL) {
if (cache->entries != nullptr) {
internal_free(cache->entries);
cache->entries = NULL;
cache->entries = nullptr;
}
cache->sizeProc = NULL;
cache->readProc = NULL;
cache->freeProc = NULL;
cache->sizeProc = nullptr;
cache->readProc = nullptr;
cache->freeProc = nullptr;
return true;
}
@@ -93,11 +93,11 @@ bool cacheFree(Cache* cache)
// 0x41FDE8
bool cacheLock(Cache* cache, int key, void** data, CacheEntry** cacheEntryPtr)
{
if (cache == NULL || data == NULL || cacheEntryPtr == NULL) {
if (cache == nullptr || data == nullptr || cacheEntryPtr == nullptr) {
return false;
}
*cacheEntryPtr = NULL;
*cacheEntryPtr = nullptr;
int index;
int rc = cacheFindIndexForKey(cache, key, &index);
@@ -148,7 +148,7 @@ bool cacheLock(Cache* cache, int key, void** data, CacheEntry** cacheEntryPtr)
// 0x4200B8
bool cacheUnlock(Cache* cache, CacheEntry* cacheEntry)
{
if (cache == NULL || cacheEntry == NULL) {
if (cache == nullptr || cacheEntry == nullptr) {
return false;
}
@@ -169,7 +169,7 @@ bool cacheUnlock(Cache* cache, CacheEntry* cacheEntry)
// 0x42012C
bool cacheFlush(Cache* cache)
{
if (cache == NULL) {
if (cache == nullptr) {
return false;
}
@@ -196,7 +196,7 @@ bool cacheFlush(Cache* cache)
// 0x42019C
bool cachePrintStats(Cache* cache, char* dest, size_t size)
{
if (cache == NULL || dest == NULL) {
if (cache == nullptr || dest == nullptr) {
return false;
}
@@ -211,7 +211,7 @@ bool cachePrintStats(Cache* cache, char* dest, size_t size)
static bool cacheFetchEntryForKey(Cache* cache, int key, int* indexPtr)
{
CacheEntry* cacheEntry = (CacheEntry*)internal_malloc(sizeof(*cacheEntry));
if (cacheEntry == NULL) {
if (cacheEntry == nullptr) {
return false;
}
@@ -376,7 +376,7 @@ static bool cacheEntryInit(CacheEntry* cacheEntry)
{
cacheEntry->key = 0;
cacheEntry->size = 0;
cacheEntry->data = NULL;
cacheEntry->data = nullptr;
cacheEntry->referenceCount = 0;
cacheEntry->hits = 0;
cacheEntry->flags = 0;
@@ -389,7 +389,7 @@ static bool cacheEntryInit(CacheEntry* cacheEntry)
// 0x420740
static bool cacheEntryFree(Cache* cache, CacheEntry* cacheEntry)
{
if (cacheEntry->data != NULL) {
if (cacheEntry->data != nullptr) {
heapBlockDeallocate(&(cache->heap), &(cacheEntry->heapHandleIndex));
}
@@ -420,12 +420,12 @@ static bool cacheClean(Cache* cache)
// 0x4207D4
static bool cacheResetStatistics(Cache* cache)
{
if (cache == NULL) {
if (cache == nullptr) {
return false;
}
CacheEntry** entries = (CacheEntry**)internal_malloc(sizeof(*entries) * cache->entriesLength);
if (entries == NULL) {
if (entries == nullptr) {
return false;
}
@@ -462,7 +462,7 @@ static bool cacheEnsureSize(Cache* cache, int size)
}
CacheEntry** entries = (CacheEntry**)internal_malloc(sizeof(*entries) * cache->entriesLength);
if (entries != NULL) {
if (entries != nullptr) {
memcpy(entries, cache->entries, sizeof(*entries) * cache->entriesLength);
qsort(entries, cache->entriesLength, sizeof(*entries), cacheEntriesCompareByUsage);
@@ -562,7 +562,7 @@ static bool cacheSetCapacity(Cache* cache, int newCapacity)
}
CacheEntry** entries = (CacheEntry**)internal_realloc(cache->entries, sizeof(*cache->entries) * newCapacity);
if (entries == NULL) {
if (entries == nullptr) {
return false;
}

File diff suppressed because it is too large Load Diff

View File

@@ -21,9 +21,9 @@
#include "message.h"
#include "mouse.h"
#include "object.h"
#include "options.h"
#include "palette.h"
#include "platform_compat.h"
#include "preferences.h"
#include "proto.h"
#include "settings.h"
#include "sfall_config.h"
@@ -107,10 +107,10 @@ static int gPremadeCharacterCount = PREMADE_CHARACTER_COUNT;
static int gCharacterSelectorWindow = -1;
// 0x51C7FC
static unsigned char* gCharacterSelectorWindowBuffer = NULL;
static unsigned char* gCharacterSelectorWindowBuffer = nullptr;
// 0x51C800
static unsigned char* gCharacterSelectorBackground = NULL;
static unsigned char* gCharacterSelectorBackground = nullptr;
// 0x51C804
static int gCharacterSelectorWindowPreviousButton = -1;
@@ -269,7 +269,7 @@ static bool characterSelectorWindowInit()
}
gCharacterSelectorWindowBuffer = windowGetBuffer(gCharacterSelectorWindow);
if (gCharacterSelectorWindowBuffer == NULL) {
if (gCharacterSelectorWindowBuffer == nullptr) {
return characterSelectorWindowFatalError(false);
}
@@ -287,7 +287,7 @@ static bool characterSelectorWindowInit()
CS_WINDOW_WIDTH);
gCharacterSelectorBackground = (unsigned char*)internal_malloc(CS_WINDOW_BACKGROUND_WIDTH * CS_WINDOW_BACKGROUND_HEIGHT);
if (gCharacterSelectorBackground == NULL)
if (gCharacterSelectorBackground == nullptr)
return characterSelectorWindowFatalError(false);
blitBufferToBuffer(backgroundFrmImage.getData() + CS_WINDOW_WIDTH * CS_WINDOW_BACKGROUND_Y + CS_WINDOW_BACKGROUND_X,
@@ -323,7 +323,7 @@ static bool characterSelectorWindowInit()
500,
_previousButtonNormalFrmImage.getData(),
_previousButtonPressedFrmImage.getData(),
NULL,
nullptr,
0);
if (gCharacterSelectorWindowPreviousButton == -1) {
return characterSelectorWindowFatalError(false);
@@ -353,7 +353,7 @@ static bool characterSelectorWindowInit()
501,
_nextButtonNormalFrmImage.getData(),
_nextButtonPressedFrmImage.getData(),
NULL,
nullptr,
0);
if (gCharacterSelectorWindowNextButton == -1) {
return characterSelectorWindowFatalError(false);
@@ -383,7 +383,7 @@ static bool characterSelectorWindowInit()
KEY_LOWERCASE_T,
_takeButtonNormalFrmImage.getData(),
_takeButtonPressedFrmImage.getData(),
NULL,
nullptr,
BUTTON_FLAG_TRANSPARENT);
if (gCharacterSelectorWindowTakeButton == -1) {
return characterSelectorWindowFatalError(false);
@@ -412,7 +412,7 @@ static bool characterSelectorWindowInit()
KEY_LOWERCASE_M,
_modifyButtonNormalFrmImage.getData(),
_modifyButtonPressedFrmImage.getData(),
NULL,
nullptr,
BUTTON_FLAG_TRANSPARENT);
if (gCharacterSelectorWindowModifyButton == -1) {
return characterSelectorWindowFatalError(false);
@@ -442,7 +442,7 @@ static bool characterSelectorWindowInit()
KEY_LOWERCASE_C,
_createButtonNormalFrmImage.getData(),
_createButtonPressedFrmImage.getData(),
NULL,
nullptr,
BUTTON_FLAG_TRANSPARENT);
if (gCharacterSelectorWindowCreateButton == -1) {
return characterSelectorWindowFatalError(false);
@@ -472,7 +472,7 @@ static bool characterSelectorWindowInit()
KEY_ESCAPE,
_backButtonNormalFrmImage.getData(),
_backButtonPressedFrmImage.getData(),
NULL,
nullptr,
BUTTON_FLAG_TRANSPARENT);
if (gCharacterSelectorWindowBackButton == -1) {
return characterSelectorWindowFatalError(false);
@@ -546,9 +546,9 @@ static void characterSelectorWindowFree()
_backButtonNormalFrmImage.unlock();
_backButtonPressedFrmImage.unlock();
if (gCharacterSelectorBackground != NULL) {
if (gCharacterSelectorBackground != nullptr) {
internal_free(gCharacterSelectorBackground);
gCharacterSelectorBackground = NULL;
gCharacterSelectorBackground = nullptr;
}
windowDestroy(gCharacterSelectorWindow);
@@ -595,7 +595,7 @@ static bool characterSelectorWindowRenderFace()
int faceFid = buildFid(OBJ_TYPE_INTERFACE, gCustomPremadeCharacterDescriptions[gCurrentPremadeCharacter].face, 0, 0, 0);
if (faceFrmImage.lock(faceFid)) {
unsigned char* data = faceFrmImage.getData();
if (data != NULL) {
if (data != nullptr) {
int width = faceFrmImage.getWidth();
int height = faceFrmImage.getHeight();
blitBufferToBufferTrans(data, width, height, width, (gCharacterSelectorWindowBuffer + CS_WINDOW_WIDTH * 23 + 27), CS_WINDOW_WIDTH);
@@ -806,13 +806,13 @@ static bool characterSelectorWindowRenderStats()
// MELEE DAMAGE
y += vh;
str = statGetName(STAT_ARMOR_CLASS);
str = statGetName(STAT_MELEE_DAMAGE);
strcpy(text, str);
length = fontGetStringWidth(text);
fontDrawText(gCharacterSelectorWindowBuffer + CS_WINDOW_WIDTH * y + CS_WINDOW_SECONDARY_STAT_MID_X - length, text, length, CS_WINDOW_WIDTH, _colorTable[992]);
value = critterGetStat(gDude, STAT_ARMOR_CLASS);
value = critterGetStat(gDude, STAT_MELEE_DAMAGE);
snprintf(text, sizeof(text), " %d", value);
length = fontGetStringWidth(text);
@@ -870,7 +870,7 @@ static bool characterSelectorWindowRenderBio()
premadeCharactersLocalizePath(path);
File* stream = fileOpen(path, "rt");
if (stream != NULL) {
if (stream != nullptr) {
int y = 40;
int lineHeight = fontGetLineHeight();
@@ -901,24 +901,24 @@ void premadeCharactersInit()
{
char* fileNamesString;
configGetString(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_PREMADE_CHARACTERS_FILE_NAMES_KEY, &fileNamesString);
if (fileNamesString != NULL && *fileNamesString == '\0') {
fileNamesString = NULL;
if (fileNamesString != nullptr && *fileNamesString == '\0') {
fileNamesString = nullptr;
}
char* faceFidsString;
configGetString(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_PREMADE_CHARACTERS_FACE_FIDS_KEY, &faceFidsString);
if (faceFidsString != NULL && *faceFidsString == '\0') {
faceFidsString = NULL;
if (faceFidsString != nullptr && *faceFidsString == '\0') {
faceFidsString = nullptr;
}
if (fileNamesString != NULL && faceFidsString != NULL) {
if (fileNamesString != nullptr && faceFidsString != nullptr) {
int fileNamesLength = 0;
for (char* pch = fileNamesString; pch != NULL; pch = strchr(pch + 1, ',')) {
for (char* pch = fileNamesString; pch != nullptr; pch = strchr(pch + 1, ',')) {
fileNamesLength++;
}
int faceFidsLength = 0;
for (char* pch = faceFidsString; pch != NULL; pch = strchr(pch + 1, ',')) {
for (char* pch = faceFidsString; pch != nullptr; pch = strchr(pch + 1, ',')) {
faceFidsLength++;
}
@@ -929,7 +929,7 @@ void premadeCharactersInit()
char* pch;
pch = strchr(fileNamesString, ',');
if (pch != NULL) {
if (pch != nullptr) {
*pch = '\0';
}
@@ -940,20 +940,20 @@ void premadeCharactersInit()
snprintf(gCustomPremadeCharacterDescriptions[index].fileName, sizeof(gCustomPremadeCharacterDescriptions[index].fileName), "premade\\%s", fileNamesString);
if (pch != NULL) {
if (pch != nullptr) {
*pch = ',';
}
fileNamesString = pch + 1;
pch = strchr(faceFidsString, ',');
if (pch != NULL) {
if (pch != nullptr) {
*pch = '\0';
}
gCustomPremadeCharacterDescriptions[index].face = atoi(faceFidsString);
if (pch != NULL) {
if (pch != nullptr) {
*pch = ',';
}

View File

@@ -51,7 +51,7 @@ static bool _colorsInited = false;
static double gBrightness = 1.0;
// 0x51DF20
static ColorTransitionCallback* gColorPaletteTransitionCallback = NULL;
static ColorTransitionCallback* gColorPaletteTransitionCallback = nullptr;
// 0x51DF24
static MallocProc* gColorPaletteMallocProc = colorPaletteMallocDefaultImpl;
@@ -63,7 +63,7 @@ static ReallocProc* gColorPaletteReallocProc = colorPaletteReallocDefaultImpl;
static FreeProc* gColorPaletteFreeProc = colorPaletteFreeDefaultImpl;
// 0x51DF30
static ColorFileNameManger* gColorFileNameMangler = NULL;
static ColorFileNameManger* gColorFileNameMangler = nullptr;
// 0x51DF34
unsigned char _cmap[768] = {
@@ -114,7 +114,7 @@ static ColorPaletteFileOpenProc* gColorPaletteFileOpenProc;
// 0x4C7200
static int colorPaletteFileOpen(const char* filePath, int flags)
{
if (gColorPaletteFileOpenProc != NULL) {
if (gColorPaletteFileOpenProc != nullptr) {
return gColorPaletteFileOpenProc(filePath, flags);
}
@@ -126,7 +126,7 @@ static int colorPaletteFileOpen(const char* filePath, int flags)
// 0x4C7218
static int colorPaletteFileRead(int fd, void* buffer, size_t size)
{
if (gColorPaletteFileReadProc != NULL) {
if (gColorPaletteFileReadProc != nullptr) {
return gColorPaletteFileReadProc(fd, buffer, size);
}
@@ -138,7 +138,7 @@ static int colorPaletteFileRead(int fd, void* buffer, size_t size)
// 0x4C7230
static int colorPaletteFileClose(int fd)
{
if (gColorPaletteFileCloseProc != NULL) {
if (gColorPaletteFileCloseProc != nullptr) {
return gColorPaletteFileCloseProc(fd);
}
@@ -201,7 +201,7 @@ void colorPaletteFadeBetween(unsigned char* oldPalette, unsigned char* newPalett
palette[index] = oldPalette[index] - (oldPalette[index] - newPalette[index]) * step / steps;
}
if (gColorPaletteTransitionCallback != NULL) {
if (gColorPaletteTransitionCallback != nullptr) {
if (step % 128 == 0) {
gColorPaletteTransitionCallback();
}
@@ -391,7 +391,7 @@ static void _setMixTableColor(int a1)
// 0x4C78E4
bool colorPaletteLoad(const char* path)
{
if (gColorFileNameMangler != NULL) {
if (gColorFileNameMangler != nullptr) {
path = gColorFileNameMangler(path);
}
@@ -547,7 +547,7 @@ unsigned char* _getColorBlendTable(int ch)
{
unsigned char* ptr;
if (_blendTable[ch] == NULL) {
if (_blendTable[ch] == nullptr) {
ptr = (unsigned char*)gColorPaletteMallocProc(4100);
*(int*)ptr = 1;
_blendTable[ch] = ptr + 4;
@@ -564,12 +564,12 @@ unsigned char* _getColorBlendTable(int ch)
void _freeColorBlendTable(int a1)
{
unsigned char* v2 = _blendTable[a1];
if (v2 != NULL) {
if (v2 != nullptr) {
int* count = (int*)(v2 - sizeof(int));
*count -= 1;
if (*count == 0) {
gColorPaletteFreeProc(count);
_blendTable[a1] = NULL;
_blendTable[a1] = nullptr;
}
}
}
@@ -636,7 +636,7 @@ bool colorPopColorPalette()
memcpy(_colorTable, entry->colorTable, sizeof(_colorTable));
free(entry);
gColorPaletteStack[gColorPaletteStackSize] = NULL;
gColorPaletteStack[gColorPaletteStackSize] = nullptr;
_setIntensityTables();

File diff suppressed because it is too large Load Diff

View File

@@ -33,14 +33,14 @@ void _combat_update_critter_outline_for_los(Object* critter, bool a2);
void _combat_over_from_load();
void _combat_give_exps(int exp_points);
void _combat_turn_run();
void _combat(STRUCT_664980* attack);
void attackInit(Attack* attack, Object* a2, Object* a3, int a4, int a5);
int _combat_attack(Object* a1, Object* a2, int a3, int a4);
int _combat_bullet_start(const Object* a1, const Object* a2);
void _compute_explosion_on_extras(Attack* attack, int a2, bool isGrenade, int a4);
void _combat(CombatStartData* csd);
void attackInit(Attack* attack, Object* attacker, Object* defender, int hitMode, int hitLocation);
int _combat_attack(Object* attacker, Object* defender, int hitMode, int hitLocation);
int _combat_bullet_start(const Object* attacker, const Object* target);
void _compute_explosion_on_extras(Attack* attack, bool isFromAttacker, bool isGrenade, bool noDamage);
int _determine_to_hit(Object* a1, Object* a2, int hitLocation, int hitMode);
int _determine_to_hit_no_range(Object* a1, Object* a2, int a3, int a4, unsigned char* a5);
int _determine_to_hit_from_tile(Object* a1, int a2, Object* a3, int a4, int a5);
int _determine_to_hit_no_range(Object* attacker, Object* defender, int hitLocation, int hitMode, unsigned char* a5);
int _determine_to_hit_from_tile(Object* attacker, int tile, Object* defender, int hitLocation, int hitMode);
void attackComputeDeathFlags(Attack* attack);
void _apply_damage(Attack* attack, bool animated);
void _combat_display(Attack* attack);
@@ -48,11 +48,11 @@ void _combat_anim_begin();
void _combat_anim_finished();
int _combat_check_bad_shot(Object* attacker, Object* defender, int hitMode, bool aiming);
bool _combat_to_hit(Object* target, int* accuracy);
void _combat_attack_this(Object* a1);
void _combat_attack_this(Object* target);
void _combat_outline_on();
void _combat_outline_off();
void _combat_highlight_change();
bool _combat_is_shot_blocked(Object* a1, int from, int to, Object* a4, int* a5);
bool _combat_is_shot_blocked(Object* sourceObj, int from, int to, Object* targetObj, int* numCrittersOnLof);
int _combat_player_knocked_out_by();
int _combat_explode_scenery(Object* a1, Object* a2);
void _combat_delete_critter(Object* obj);
@@ -71,6 +71,10 @@ int unarmedGetKickHitMode(bool isSecondary);
bool unarmedIsPenetrating(int hitMode);
bool damageModGetBonusHthDamageFix();
bool damageModGetDisplayBonusDamage();
int combat_get_hit_location_penalty(int hit_location);
void combat_set_hit_location_penalty(int hit_location, int penalty);
void combat_reset_hit_location_penalty();
Attack* combat_get_data();
static inline bool isInCombat()
{

File diff suppressed because it is too large Load Diff

View File

@@ -30,6 +30,8 @@ void aiReset();
int aiExit();
int aiLoad(File* stream);
int aiSave(File* stream);
int combat_ai_num();
char* combat_ai_name(int packet_num);
int aiGetAreaAttackMode(Object* obj);
int aiGetRunAwayMode(Object* obj);
int aiGetBestWeapon(Object* obj);

View File

@@ -86,7 +86,7 @@ typedef enum HitLocation {
HIT_LOCATION_SPECIFIC_COUNT = HIT_LOCATION_COUNT - 1,
} HitLocation;
typedef struct STRUCT_664980 {
typedef struct CombatStartData {
Object* attacker;
Object* defender;
int actionPointsBonus;
@@ -94,10 +94,10 @@ typedef struct STRUCT_664980 {
int damageBonus;
int minDamage;
int maxDamage;
int field_1C; // probably bool, indicating field_20 and field_24 used
int field_20; // flags on attacker
int field_24; // flags on defender
} STRUCT_664980;
int overrideAttackResults;
int attackerResults;
int targetResults;
} CombatStartData;
typedef struct Attack {
Object* attacker;

View File

@@ -31,11 +31,11 @@ static char gConfigLastSectionKey[CONFIG_FILE_MAX_LINE_LENGTH] = "unknown";
// 0x42BD90
bool configInit(Config* config)
{
if (config == NULL) {
if (config == nullptr) {
return false;
}
if (dictionaryInit(config, CONFIG_INITIAL_CAPACITY, sizeof(ConfigSection), NULL) != 0) {
if (dictionaryInit(config, CONFIG_INITIAL_CAPACITY, sizeof(ConfigSection), nullptr) != 0) {
return false;
}
@@ -45,7 +45,7 @@ bool configInit(Config* config)
// 0x42BDBC
void configFree(Config* config)
{
if (config == NULL) {
if (config == nullptr) {
return;
}
@@ -58,7 +58,7 @@ void configFree(Config* config)
char** value = (char**)keyValueEntry->value;
internal_free(*value);
*value = NULL;
*value = nullptr;
}
dictionaryFree(section);
@@ -78,7 +78,7 @@ void configFree(Config* config)
// 0x42BE38
bool configParseCommandLineArguments(Config* config, int argc, char** argv)
{
if (config == NULL) {
if (config == nullptr) {
return false;
}
@@ -88,7 +88,7 @@ bool configParseCommandLineArguments(Config* config, int argc, char** argv)
// Find opening bracket.
pch = strchr(string, '[');
if (pch == NULL) {
if (pch == nullptr) {
continue;
}
@@ -96,7 +96,7 @@ bool configParseCommandLineArguments(Config* config, int argc, char** argv)
// Find closing bracket.
pch = strchr(sectionKey, ']');
if (pch == NULL) {
if (pch == nullptr) {
continue;
}
@@ -120,7 +120,7 @@ bool configParseCommandLineArguments(Config* config, int argc, char** argv)
// 0x42BF48
bool configGetString(Config* config, const char* sectionKey, const char* key, char** valuePtr)
{
if (config == NULL || sectionKey == NULL || key == NULL || valuePtr == NULL) {
if (config == nullptr || sectionKey == nullptr || key == nullptr || valuePtr == nullptr) {
return false;
}
@@ -146,7 +146,7 @@ bool configGetString(Config* config, const char* sectionKey, const char* key, ch
// 0x42BF90
bool configSetString(Config* config, const char* sectionKey, const char* key, const char* value)
{
if (config == NULL || sectionKey == NULL || key == NULL || value == NULL) {
if (config == nullptr || sectionKey == nullptr || key == nullptr || value == nullptr) {
return false;
}
@@ -167,13 +167,13 @@ bool configSetString(Config* config, const char* sectionKey, const char* key, co
char** existingValue = (char**)keyValueEntry->value;
internal_free(*existingValue);
*existingValue = NULL;
*existingValue = nullptr;
dictionaryRemoveValue(section, key);
}
char* valueCopy = internal_strdup(value);
if (valueCopy == NULL) {
if (valueCopy == nullptr) {
return false;
}
@@ -188,7 +188,7 @@ bool configSetString(Config* config, const char* sectionKey, const char* key, co
// 0x42C05C
bool configGetInt(Config* config, const char* sectionKey, const char* key, int* valuePtr, unsigned char base /* = 0 */)
{
if (valuePtr == NULL) {
if (valuePtr == nullptr) {
return false;
}
@@ -220,7 +220,7 @@ bool configGetInt(Config* config, const char* sectionKey, const char* key, int*
// 0x42C090
bool configGetIntList(Config* config, const char* sectionKey, const char* key, int* arr, int count)
{
if (arr == NULL || count < 2) {
if (arr == nullptr || count < 2) {
return false;
}
@@ -234,7 +234,7 @@ bool configGetIntList(Config* config, const char* sectionKey, const char* key, i
while (1) {
char* pch = strchr(string, ',');
if (pch == NULL) {
if (pch == nullptr) {
break;
}
@@ -272,7 +272,7 @@ bool configSetInt(Config* config, const char* sectionKey, const char* key, int v
// 0x42C280
bool configRead(Config* config, const char* filePath, bool isDb)
{
if (config == NULL || filePath == NULL) {
if (config == nullptr || filePath == nullptr) {
return false;
}
@@ -280,24 +280,28 @@ bool configRead(Config* config, const char* filePath, bool isDb)
if (isDb) {
File* stream = fileOpen(filePath, "rb");
if (stream != NULL) {
while (fileReadString(string, sizeof(string), stream) != NULL) {
configParseLine(config, string);
}
fileClose(stream);
// CE: Return `false` if file does not exists in database.
if (stream == nullptr) {
return false;
}
while (fileReadString(string, sizeof(string), stream) != nullptr) {
configParseLine(config, string);
}
fileClose(stream);
} else {
FILE* stream = compat_fopen(filePath, "rt");
if (stream != NULL) {
while (fgets(string, sizeof(string), stream) != NULL) {
configParseLine(config, string);
}
fclose(stream);
// CE: Return `false` if file does not exists on the file system.
if (stream == nullptr) {
return false;
}
// FIXME: This function returns `true` even if the file was not actually
// read. I'm pretty sure it's bug.
while (compat_fgets(string, sizeof(string), stream) != nullptr) {
configParseLine(config, string);
}
fclose(stream);
}
return true;
@@ -308,13 +312,13 @@ bool configRead(Config* config, const char* filePath, bool isDb)
// 0x42C324
bool configWrite(Config* config, const char* filePath, bool isDb)
{
if (config == NULL || filePath == NULL) {
if (config == nullptr || filePath == nullptr) {
return false;
}
if (isDb) {
File* stream = fileOpen(filePath, "wt");
if (stream == NULL) {
if (stream == nullptr) {
return false;
}
@@ -334,7 +338,7 @@ bool configWrite(Config* config, const char* filePath, bool isDb)
fileClose(stream);
} else {
FILE* stream = compat_fopen(filePath, "wt");
if (stream == NULL) {
if (stream == nullptr) {
return false;
}
@@ -377,7 +381,7 @@ static bool configParseLine(Config* config, char* string)
// Find comment marker and truncate the string.
pch = strchr(string, ';');
if (pch != NULL) {
if (pch != nullptr) {
*pch = '\0';
}
@@ -393,7 +397,7 @@ static bool configParseLine(Config* config, char* string)
// keys there.
// Skip leading whitespace.
while (isspace(*string)) {
while (isspace(static_cast<unsigned char>(*string))) {
string++;
}
@@ -403,7 +407,7 @@ static bool configParseLine(Config* config, char* string)
// Find closing bracket.
pch = strchr(sectionKey, ']');
if (pch != NULL) {
if (pch != nullptr) {
*pch = '\0';
strcpy(gConfigLastSectionKey, sectionKey);
return configTrimString(gConfigLastSectionKey);
@@ -427,13 +431,13 @@ static bool configParseLine(Config* config, char* string)
// 0x42C594
static bool configParseKeyValue(char* string, char* key, char* value)
{
if (string == NULL || key == NULL || value == NULL) {
if (string == nullptr || key == nullptr || value == nullptr) {
return false;
}
// Find equals character.
char* pch = strchr(string, '=');
if (pch == NULL) {
if (pch == nullptr) {
return false;
}
@@ -458,7 +462,7 @@ static bool configParseKeyValue(char* string, char* key, char* value)
// 0x42C638
static bool configEnsureSectionExists(Config* config, const char* sectionKey)
{
if (config == NULL || sectionKey == NULL) {
if (config == nullptr || sectionKey == nullptr) {
return false;
}
@@ -468,7 +472,7 @@ static bool configEnsureSectionExists(Config* config, const char* sectionKey)
}
ConfigSection section;
if (dictionaryInit(&section, CONFIG_INITIAL_CAPACITY, sizeof(char**), NULL) == -1) {
if (dictionaryInit(&section, CONFIG_INITIAL_CAPACITY, sizeof(char**), nullptr) == -1) {
return false;
}
@@ -484,7 +488,7 @@ static bool configEnsureSectionExists(Config* config, const char* sectionKey)
// 0x42C698
static bool configTrimString(char* string)
{
if (string == NULL) {
if (string == nullptr) {
return false;
}
@@ -496,7 +500,7 @@ static bool configTrimString(char* string)
// Starting from the end of the string, loop while it's a whitespace and
// decrement string length.
char* pch = string + length - 1;
while (length != 0 && isspace(*pch)) {
while (length != 0 && isspace(static_cast<unsigned char>(*pch))) {
length--;
pch--;
}
@@ -507,7 +511,7 @@ static bool configTrimString(char* string)
// Starting from the beginning of the string loop while it's a whitespace
// and decrement string length.
pch = string;
while (isspace(*pch)) {
while (isspace(static_cast<unsigned char>(*pch))) {
pch++;
length--;
}
@@ -521,7 +525,7 @@ static bool configTrimString(char* string)
// 0x42C718
bool configGetDouble(Config* config, const char* sectionKey, const char* key, double* valuePtr)
{
if (valuePtr == NULL) {
if (valuePtr == nullptr) {
return false;
}
@@ -530,7 +534,7 @@ bool configGetDouble(Config* config, const char* sectionKey, const char* key, do
return false;
}
*valuePtr = strtod(stringValue, NULL);
*valuePtr = strtod(stringValue, nullptr);
return true;
}
@@ -547,7 +551,7 @@ bool configSetDouble(Config* config, const char* sectionKey, const char* key, do
// NOTE: Boolean-typed variant of [configGetInt].
bool configGetBool(Config* config, const char* sectionKey, const char* key, bool* valuePtr)
{
if (valuePtr == NULL) {
if (valuePtr == nullptr) {
return false;
}

View File

@@ -9,6 +9,7 @@
#include "cycle.h"
#include "db.h"
#include "debug.h"
#include "delay.h"
#include "draw.h"
#include "game_mouse.h"
#include "input.h"
@@ -67,7 +68,7 @@ void creditsOpen(const char* filePath, int backgroundFid, bool useReversedStyle)
char localizedPath[COMPAT_MAX_PATH];
if (_message_make_path(localizedPath, sizeof(localizedPath), filePath)) {
gCreditsFile = fileOpen(localizedPath, "rt");
if (gCreditsFile != NULL) {
if (gCreditsFile != nullptr) {
soundContinueAll();
colorCycleDisable();
@@ -84,7 +85,7 @@ void creditsOpen(const char* filePath, int backgroundFid, bool useReversedStyle)
soundContinueAll();
if (window != -1) {
unsigned char* windowBuffer = windowGetBuffer(window);
if (windowBuffer != NULL) {
if (windowBuffer != nullptr) {
unsigned char* backgroundBuffer = (unsigned char*)internal_malloc(windowWidth * windowHeight);
if (backgroundBuffer) {
soundContinueAll();
@@ -105,7 +106,7 @@ void creditsOpen(const char* filePath, int backgroundFid, bool useReversedStyle)
}
unsigned char* intermediateBuffer = (unsigned char*)internal_malloc(windowWidth * windowHeight);
if (intermediateBuffer != NULL) {
if (intermediateBuffer != nullptr) {
memset(intermediateBuffer, 0, windowWidth * windowHeight);
fontSetCurrent(gCreditsWindowTitleFont);
@@ -117,7 +118,7 @@ void creditsOpen(const char* filePath, int backgroundFid, bool useReversedStyle)
int lineHeight = std::max(titleFontLineHeight, nameFontLineHeight);
int stringBufferSize = windowWidth * lineHeight;
unsigned char* stringBuffer = (unsigned char*)internal_malloc(stringBufferSize);
if (stringBuffer != NULL) {
if (stringBuffer != nullptr) {
blitBufferToBuffer(backgroundBuffer,
windowWidth,
windowHeight,
@@ -172,8 +173,7 @@ void creditsOpen(const char* filePath, int backgroundFid, bool useReversedStyle)
windowBuffer,
windowWidth);
while (getTicksSince(tick) < CREDITS_WINDOW_SCROLLING_DELAY) {
}
delay_ms(CREDITS_WINDOW_SCROLLING_DELAY - (getTicks() - tick));
tick = getTicks();
@@ -215,8 +215,7 @@ void creditsOpen(const char* filePath, int backgroundFid, bool useReversedStyle)
windowBuffer,
windowWidth);
while (getTicksSince(tick) < CREDITS_WINDOW_SCROLLING_DELAY) {
}
delay_ms(CREDITS_WINDOW_SCROLLING_DELAY - (getTicks() - tick));
tick = getTicks();

View File

@@ -135,7 +135,7 @@ static const int gRadiationEffectPenalties[RADIATION_LEVEL_COUNT][RADIATION_EFFE
};
// 0x518438
static Object* _critterClearObj = NULL;
static Object* _critterClearObj = nullptr;
// scrname.msg
//
@@ -247,7 +247,7 @@ char* critterGetName(Object* obj)
}
}
char* name = NULL;
char* name = nullptr;
if (obj->field_80 != -1) {
MessageListItem messageListItem;
messageListItem.num = 101 + obj->field_80;
@@ -256,7 +256,7 @@ char* critterGetName(Object* obj)
}
}
if (name == NULL || *name == '\0') {
if (name == nullptr || *name == '\0') {
name = protoGetName(obj->pid);
}
@@ -347,8 +347,8 @@ int critterAdjustPoison(Object* critter, int amount)
if (newPoison > 0) {
critter->data.critter.poison = newPoison;
_queue_clear_type(EVENT_TYPE_POISON, NULL);
queueAddEvent(10 * (505 - 5 * newPoison), gDude, NULL, EVENT_TYPE_POISON);
_queue_clear_type(EVENT_TYPE_POISON, nullptr);
queueAddEvent(10 * (505 - 5 * newPoison), gDude, nullptr, EVENT_TYPE_POISON);
// You have been poisoned!
messageListItem.num = 3000;
@@ -429,23 +429,23 @@ int critterAdjustRadiation(Object* obj, int amount)
}
if (amount > 0) {
Object* geigerCounter = NULL;
Object* geigerCounter = nullptr;
Object* item1 = critterGetItem1(gDude);
if (item1 != NULL) {
if (item1 != nullptr) {
if (item1->pid == PROTO_ID_GEIGER_COUNTER_I || item1->pid == PROTO_ID_GEIGER_COUNTER_II) {
geigerCounter = item1;
}
}
Object* item2 = critterGetItem2(gDude);
if (item2 != NULL) {
if (item2 != nullptr) {
if (item2->pid == PROTO_ID_GEIGER_COUNTER_I || item2->pid == PROTO_ID_GEIGER_COUNTER_II) {
geigerCounter = item2;
}
}
if (geigerCounter != NULL) {
if (geigerCounter != nullptr) {
if (miscItemIsOn(geigerCounter)) {
if (amount > 5) {
// The geiger counter is clicking wildly.
@@ -517,14 +517,14 @@ int _critter_check_rads(Object* obj)
else
radiationLevel = RADIATION_LEVEL_NONE;
if (statRoll(obj, STAT_ENDURANCE, gRadiationEnduranceModifiers[radiationLevel], NULL) <= ROLL_FAILURE) {
if (statRoll(obj, STAT_ENDURANCE, gRadiationEnduranceModifiers[radiationLevel], nullptr) <= ROLL_FAILURE) {
radiationLevel++;
}
if (radiationLevel > _old_rad_level) {
// Create timer event for applying radiation damage.
RadiationEvent* radiationEvent = (RadiationEvent*)internal_malloc(sizeof(*radiationEvent));
if (radiationEvent == NULL) {
if (radiationEvent == nullptr) {
return 0;
}
@@ -630,7 +630,7 @@ int radiationEventProcess(Object* obj, void* data)
if (!radiationEvent->isHealing) {
// Schedule healing stats event in 7 days.
RadiationEvent* newRadiationEvent = (RadiationEvent*)internal_malloc(sizeof(*newRadiationEvent));
if (newRadiationEvent != NULL) {
if (newRadiationEvent != nullptr) {
_queue_clear_type(EVENT_TYPE_RADIATION, _clear_rad_damage);
newRadiationEvent->radiationLevel = radiationEvent->radiationLevel;
newRadiationEvent->isHealing = 1;
@@ -647,7 +647,7 @@ int radiationEventProcess(Object* obj, void* data)
int radiationEventRead(File* stream, void** dataPtr)
{
RadiationEvent* radiationEvent = (RadiationEvent*)internal_malloc(sizeof(*radiationEvent));
if (radiationEvent == NULL) {
if (radiationEvent == nullptr) {
return -1;
}
@@ -770,7 +770,7 @@ char* killTypeGetName(int killType)
MessageListItem messageListItem;
return getmsg(&gProtoMessageList, &messageListItem, 1450 + killType);
} else {
return NULL;
return nullptr;
}
} else {
return byte_501494;
@@ -785,7 +785,7 @@ char* killTypeGetDescription(int killType)
MessageListItem messageListItem;
return getmsg(&gProtoMessageList, &messageListItem, 1469 + killType);
} else {
return NULL;
return nullptr;
}
} else {
return byte_501494;
@@ -927,7 +927,7 @@ int critterGetExp(Object* critter)
// 0x42DCDC
bool critterIsActive(Object* critter)
{
if (critter == NULL) {
if (critter == nullptr) {
return false;
}
@@ -949,7 +949,7 @@ bool critterIsActive(Object* critter)
// 0x42DD18
bool critterIsDead(Object* critter)
{
if (critter == NULL) {
if (critter == nullptr) {
return false;
}
@@ -971,7 +971,7 @@ bool critterIsDead(Object* critter)
// 0x42DD58
bool critterIsCrippled(Object* critter)
{
if (critter == NULL) {
if (critter == nullptr) {
return false;
}
@@ -985,7 +985,7 @@ bool critterIsCrippled(Object* critter)
// 0x42DD80
bool _critter_is_prone(Object* critter)
{
if (critter == NULL) {
if (critter == nullptr) {
return false;
}
@@ -996,15 +996,15 @@ bool _critter_is_prone(Object* critter)
int anim = FID_ANIM_TYPE(critter->fid);
return (critter->data.critter.combat.results & (DAM_KNOCKED_OUT | DAM_KNOCKED_DOWN)) != 0
|| (anim >= FIRST_KNOCKDOWN_AND_DEATH_ANIM && anim <= LAST_KNOCKDOWN_AND_DEATH_ANIM)
|| (anim >= FIRST_SF_DEATH_ANIM && anim <= LAST_SF_DEATH_ANIM);
|| (anim >= FIRST_KNOCKDOWN_AND_DEATH_ANIM && anim <= LAST_KNOCKDOWN_AND_DEATH_ANIM)
|| (anim >= FIRST_SF_DEATH_ANIM && anim <= LAST_SF_DEATH_ANIM);
}
// critter_body_type
// 0x42DDC4
int critterGetBodyType(Object* critter)
{
if (critter == NULL) {
if (critter == nullptr) {
debugPrint("\nError: critter_body_type: pobj was NULL!");
return 0;
}
@@ -1022,7 +1022,7 @@ int critterGetBodyType(Object* critter)
int gcdLoad(const char* path)
{
File* stream = fileOpen(path, "rb");
if (stream == NULL) {
if (stream == nullptr) {
return -1;
}
@@ -1094,7 +1094,7 @@ int protoCritterDataRead(File* stream, CritterProtoData* critterData)
int gcdSave(const char* path)
{
File* stream = fileOpen(path, "wb");
if (stream == NULL) {
if (stream == nullptr) {
return -1;
}
@@ -1166,7 +1166,7 @@ void dudeEnableState(int state)
proto->critter.data.flags |= (1 << state);
if (state == DUDE_STATE_SNEAKING) {
sneakEventProcess(NULL, NULL);
sneakEventProcess(nullptr, nullptr);
}
indicatorBarRefresh();
@@ -1197,7 +1197,7 @@ int sneakEventProcess(Object* obj, void* data)
int time;
int sneak = skillGetValue(gDude, SKILL_SNEAK);
if (skillRoll(gDude, SKILL_SNEAK, 0, NULL) < ROLL_SUCCESS) {
if (skillRoll(gDude, SKILL_SNEAK, 0, nullptr) < ROLL_SUCCESS) {
time = 600;
_sneak_working = false;
@@ -1218,7 +1218,7 @@ int sneakEventProcess(Object* obj, void* data)
_sneak_working = true;
}
queueAddEvent(time, gDude, NULL, EVENT_TYPE_SNEAK);
queueAddEvent(time, gDude, nullptr, EVENT_TYPE_SNEAK);
return 0;
}
@@ -1276,7 +1276,7 @@ int _critter_wake_clear(Object* obj, void* data)
obj->data.critter.combat.results &= ~(DAM_KNOCKED_OUT | DAM_KNOCKED_DOWN);
int fid = buildFid(FID_TYPE(obj->fid), obj->fid & 0xFFF, ANIM_STAND, (obj->fid & 0xF000) >> 12, obj->rotation + 1);
objectSetFid(obj, fid, 0);
objectSetFid(obj, fid, nullptr);
return 0;
}
@@ -1284,16 +1284,16 @@ int _critter_wake_clear(Object* obj, void* data)
// 0x42E4C0
int _critter_set_who_hit_me(Object* a1, Object* a2)
{
if (a1 == NULL) {
if (a1 == nullptr) {
return -1;
}
if (a2 != NULL && FID_TYPE(a2->fid) != OBJ_TYPE_CRITTER) {
if (a2 != nullptr && FID_TYPE(a2->fid) != OBJ_TYPE_CRITTER) {
return -1;
}
if (PID_TYPE(a1->pid) == OBJ_TYPE_CRITTER) {
if (a2 == NULL || a1->data.critter.combat.team != a2->data.critter.combat.team || (statRoll(a1, STAT_INTELLIGENCE, -1, NULL) < 2 && (!objectIsPartyMember(a1) || !objectIsPartyMember(a2)))) {
if (a2 == nullptr || a1->data.critter.combat.team != a2->data.critter.combat.team || (statRoll(a1, STAT_INTELLIGENCE, -1, nullptr) < 2 && (!objectIsPartyMember(a1) || !objectIsPartyMember(a2)))) {
a1->data.critter.combat.whoHitMe = a2;
if (a2 == gDude) {
reactionSetValue(a1, -3);
@@ -1373,7 +1373,7 @@ bool critterIsEncumbered(Object* critter)
// 0x42E690
bool critterIsFleeing(Object* critter)
{
return critter != NULL
return critter != nullptr
? (critter->data.critter.combat.maneuver & CRITTER_MANUEVER_FLEEING) != 0
: false;
}
@@ -1396,4 +1396,40 @@ bool _critter_flag_check(int pid, int flag)
return (proto->critter.data.flags & flag) != 0;
}
// 0x42E6F0
void critter_flag_set(int pid, int flag)
{
Proto* proto;
if (pid == -1) {
return;
}
if (PID_TYPE(pid) != OBJ_TYPE_CRITTER) {
return;
}
protoGetProto(pid, &proto);
proto->critter.data.flags |= flag;
}
// 0x42E71C
void critter_flag_unset(int pid, int flag)
{
Proto* proto;
if (pid == -1) {
return;
}
if (PID_TYPE(pid) != OBJ_TYPE_CRITTER) {
return;
}
protoGetProto(pid, &proto);
proto->critter.data.flags &= ~flag;
}
} // namespace fallout

View File

@@ -70,6 +70,8 @@ int critterGetMovementPointCostAdjustedForCrippledLegs(Object* critter, int a2);
bool critterIsEncumbered(Object* critter);
bool critterIsFleeing(Object* a1);
bool _critter_flag_check(int pid, int flag);
void critter_flag_set(int pid, int flag);
void critter_flag_unset(int pid, int flag);
} // namespace fallout

View File

@@ -11,7 +11,7 @@
namespace fallout {
// 0x5184AC
DatafileLoader* gDatafileLoader = NULL;
DatafileLoader* gDatafileLoader = nullptr;
// 0x5184B0
DatafileNameMangler* gDatafileNameMangler = datafileDefaultNameManglerImpl;
@@ -90,24 +90,24 @@ unsigned char* datafileReadRaw(char* path, int* widthPtr, int* heightPtr)
{
char* mangledPath = gDatafileNameMangler(path);
char* dot = strrchr(mangledPath, '.');
if (dot != NULL) {
if (dot != nullptr) {
if (compat_stricmp(dot + 1, "pcx") == 0) {
return pcxRead(mangledPath, widthPtr, heightPtr, gDatafilePalette);
}
}
if (gDatafileLoader != NULL) {
if (gDatafileLoader != nullptr) {
return gDatafileLoader(mangledPath, gDatafilePalette, widthPtr, heightPtr);
}
return NULL;
return nullptr;
}
// 0x42EFCC
unsigned char* datafileRead(char* path, int* widthPtr, int* heightPtr)
{
unsigned char* v1 = datafileReadRaw(path, widthPtr, heightPtr);
if (v1 != NULL) {
if (v1 != nullptr) {
sub_42EE84(v1, gDatafilePalette, *widthPtr, *heightPtr);
}
return v1;
@@ -121,12 +121,12 @@ unsigned char* sub_42EFF4(char* path)
int width;
int height;
unsigned char* v3 = datafileReadRaw(path, &width, &height);
if (v3 != NULL) {
if (v3 != nullptr) {
internal_free_safe(v3, __FILE__, __LINE__); // "..\\int\\DATAFILE.C", 148
return gDatafilePalette;
}
return NULL;
return nullptr;
}
// NOTE: Unused.
@@ -177,17 +177,17 @@ unsigned char* datafileLoad(char* path, int* sizePtr)
{
const char* mangledPath = gDatafileNameMangler(path);
File* stream = fileOpen(mangledPath, "rb");
if (stream == NULL) {
return NULL;
if (stream == nullptr) {
return nullptr;
}
int size = fileGetSize(stream);
unsigned char* data = (unsigned char*)internal_malloc_safe(size, __FILE__, __LINE__); // "..\\int\\DATAFILE.C", 185
if (data == NULL) {
if (data == nullptr) {
// NOTE: This code is unreachable, internal_malloc_safe never fails.
// Otherwise it leaks stream.
*sizePtr = 0;
return NULL;
return nullptr;
}
fileRead(data, 1, size, stream);

View File

@@ -19,7 +19,7 @@ static int _db_list_compare(const void* p1, const void* p2);
// Generic file progress report handler.
//
// 0x51DEEC
static FileReadProgressHandler* gFileReadProgressHandler = NULL;
static FileReadProgressHandler* gFileReadProgressHandler = nullptr;
// Bytes read so far while tracking progress.
//
@@ -50,13 +50,13 @@ static FileList* gFileListHead;
// 0x4C5D30
int dbOpen(const char* filePath1, int a2, const char* filePath2, int a4)
{
if (filePath1 != NULL) {
if (filePath1 != nullptr) {
if (!xbaseOpen(filePath1)) {
return -1;
}
}
if (filePath2 != NULL) {
if (filePath2 != nullptr) {
xbaseOpen(filePath2);
}
@@ -64,15 +64,15 @@ int dbOpen(const char* filePath1, int a2, const char* filePath2, int a4)
}
// 0x4C5D58
int _db_total()
int db_total()
{
return 0;
return 1;
}
// 0x4C5D60
void dbExit()
{
xbaseReopenAll(NULL);
xbaseReopenAll(nullptr);
}
// TODO: sizePtr should be long*.
@@ -84,7 +84,7 @@ int dbGetFileSize(const char* filePath, int* sizePtr)
assert(sizePtr); // "de", "db.c", 109
File* stream = xfileOpen(filePath, "rb");
if (stream == NULL) {
if (stream == nullptr) {
return -1;
}
@@ -102,12 +102,12 @@ int dbGetFileContents(const char* filePath, void* ptr)
assert(ptr); // "buf", "db.c", 142
File* stream = xfileOpen(filePath, "rb");
if (stream == NULL) {
if (stream == nullptr) {
return -1;
}
long size = xfileGetSize(stream);
if (gFileReadProgressHandler != NULL) {
if (gFileReadProgressHandler != nullptr) {
unsigned char* byteBuffer = (unsigned char*)ptr;
long remainingSize = size;
@@ -166,7 +166,7 @@ int filePrintFormatted(File* stream, const char* format, ...)
// 0x4C5F24
int fileReadChar(File* stream)
{
if (gFileReadProgressHandler != NULL) {
if (gFileReadProgressHandler != nullptr) {
int ch = xfileReadChar(stream);
gFileReadProgressBytesRead++;
@@ -184,9 +184,9 @@ int fileReadChar(File* stream)
// 0x4C5F70
char* fileReadString(char* string, size_t size, File* stream)
{
if (gFileReadProgressHandler != NULL) {
if (xfileReadString(string, size, stream) == NULL) {
return NULL;
if (gFileReadProgressHandler != nullptr) {
if (xfileReadString(string, size, stream) == nullptr) {
return nullptr;
}
gFileReadProgressBytesRead += strlen(string);
@@ -210,7 +210,7 @@ int fileWriteString(const char* string, File* stream)
// 0x4C5FFC
size_t fileRead(void* ptr, size_t size, size_t count, File* stream)
{
if (gFileReadProgressHandler != NULL) {
if (gFileReadProgressHandler != nullptr) {
unsigned char* byteBuffer = (unsigned char*)ptr;
size_t totalBytesRead = 0;
@@ -602,7 +602,7 @@ int fileWriteUInt32List(File* stream, unsigned int* arr, int count)
int fileNameListInit(const char* pattern, char*** fileNameListPtr, int a3, int a4)
{
FileList* fileList = (FileList*)malloc(sizeof(*fileList));
if (fileList == NULL) {
if (fileList == nullptr) {
return 0;
}
@@ -638,9 +638,9 @@ int fileNameListInit(const char* pattern, char*** fileNameListPtr, int a3, int a
char fileName[COMPAT_MAX_FNAME];
char extension[COMPAT_MAX_EXT];
compat_windows_path_to_native(name);
compat_splitpath(name, NULL, dir, fileName, extension);
compat_splitpath(name, nullptr, dir, fileName, extension);
if (!isWildcard || *dir == '\0' || (strchr(dir, '\\') == NULL && strchr(dir, '/') == NULL)) {
if (!isWildcard || *dir == '\0' || (strchr(dir, '\\') == nullptr && strchr(dir, '/') == nullptr)) {
// NOTE: Quick and dirty fix to buffer overflow. See RE to
// understand the problem.
char path[COMPAT_MAX_PATH];
@@ -663,7 +663,7 @@ int fileNameListInit(const char* pattern, char*** fileNameListPtr, int a3, int a
// 0x4C6868
void fileNameListFree(char*** fileNameListPtr, int a2)
{
if (gFileListHead == NULL) {
if (gFileListHead == nullptr) {
return;
}
@@ -672,7 +672,7 @@ void fileNameListFree(char*** fileNameListPtr, int a2)
while (*fileNameListPtr != currentFileList->xlist.fileNames) {
previousFileList = currentFileList;
currentFileList = currentFileList->next;
if (currentFileList == NULL) {
if (currentFileList == nullptr) {
return;
}
}
@@ -699,11 +699,11 @@ int fileGetSize(File* stream)
// 0x4C68C4
void fileSetReadProgressHandler(FileReadProgressHandler* handler, int size)
{
if (handler != NULL && size != 0) {
if (handler != nullptr && size != 0) {
gFileReadProgressHandler = handler;
gFileReadProgressChunkSize = size;
} else {
gFileReadProgressHandler = NULL;
gFileReadProgressHandler = nullptr;
gFileReadProgressChunkSize = 0;
}
}

View File

@@ -12,7 +12,7 @@ typedef void FileReadProgressHandler();
typedef char* StrdupProc(const char* string);
int dbOpen(const char* filePath1, int a2, const char* filePath2, int a4);
int _db_total();
int db_total();
void dbExit();
int dbGetFileSize(const char* filePath, int* sizePtr);
int dbGetFileContents(const char* filePath, void* ptr);

View File

@@ -9,6 +9,7 @@
#include "character_editor.h"
#include "color.h"
#include "debug.h"
#include "delay.h"
#include "draw.h"
#include "game.h"
#include "game_sound.h"
@@ -156,12 +157,12 @@ int showDialogBox(const char* title, const char** body, int bodyLength, int x, i
bool v86 = false;
bool hasTwoButtons = false;
if (a8 != NULL) {
if (a8 != nullptr) {
hasTwoButtons = true;
}
bool hasTitle = false;
if (title != NULL) {
if (title != nullptr) {
hasTitle = true;
}
@@ -206,8 +207,8 @@ int showDialogBox(const char* title, const char** body, int bodyLength, int x, i
}
// Maintain original position in original resolution, otherwise center it.
if (screenGetWidth() != 640) x = (screenGetWidth() - backgroundFrmImage.getWidth()) / 2;
if (screenGetHeight() != 480) y = (screenGetHeight() - backgroundFrmImage.getHeight()) / 2;
x += (screenGetWidth() - 640) / 2;
y += (screenGetHeight() - 480) / 2;
int win = windowCreate(x,
y,
backgroundFrmImage.getWidth(),
@@ -297,7 +298,7 @@ int showDialogBox(const char* title, const char** body, int bodyLength, int x, i
500,
buttonNormalFrmImage.getData(),
buttonPressedFrmImage.getData(),
NULL,
nullptr,
BUTTON_FLAG_TRANSPARENT);
if (btn != -1) {
buttonSetCallbacks(btn, _gsound_red_butt_press, _gsound_red_butt_release);
@@ -338,7 +339,7 @@ int showDialogBox(const char* title, const char** body, int bodyLength, int x, i
501,
buttonNormalFrmImage.getData(),
buttonPressedFrmImage.getData(),
0,
nullptr,
BUTTON_FLAG_TRANSPARENT);
if (btn != -1) {
buttonSetCallbacks(btn, _gsound_red_butt_press, _gsound_red_butt_release);
@@ -403,7 +404,7 @@ int showDialogBox(const char* title, const char** body, int bodyLength, int x, i
501,
buttonNormalFrmImage.getData(),
buttonPressedFrmImage.getData(),
NULL,
nullptr,
BUTTON_FLAG_TRANSPARENT);
if (btn != -1) {
buttonSetCallbacks(btn, _gsound_red_butt_press, _gsound_red_butt_release);
@@ -596,8 +597,8 @@ int showLoadFileDialog(char* title, char** fileList, char* dest, int fileListLen
int backgroundHeight = frmImages[FILE_DIALOG_FRM_BACKGROUND].getHeight();
// Maintain original position in original resolution, otherwise center it.
if (screenGetWidth() != 640) x = (screenGetWidth() - backgroundWidth) / 2;
if (screenGetHeight() != 480) y = (screenGetHeight() - backgroundHeight) / 2;
x += (screenGetWidth() - 640) / 2;
y += (screenGetHeight() - 480) / 2;
int win = windowCreate(x, y, backgroundWidth, backgroundHeight, 256, WINDOW_MODAL | WINDOW_MOVE_ON_TOP);
if (win == -1) {
return -1;
@@ -643,7 +644,7 @@ int showLoadFileDialog(char* title, char** fileList, char* dest, int fileListLen
500,
frmImages[FILE_DIALOG_FRM_LITTLE_RED_BUTTON_NORMAL].getData(),
frmImages[FILE_DIALOG_FRM_LITTLE_RED_BUTTON_PRESSED].getData(),
NULL,
nullptr,
BUTTON_FLAG_TRANSPARENT);
if (doneBtn != -1) {
buttonSetCallbacks(doneBtn, _gsound_red_butt_press, _gsound_red_butt_release);
@@ -660,7 +661,7 @@ int showLoadFileDialog(char* title, char** fileList, char* dest, int fileListLen
501,
frmImages[FILE_DIALOG_FRM_LITTLE_RED_BUTTON_NORMAL].getData(),
frmImages[FILE_DIALOG_FRM_LITTLE_RED_BUTTON_PRESSED].getData(),
NULL,
nullptr,
BUTTON_FLAG_TRANSPARENT);
if (cancelBtn != -1) {
buttonSetCallbacks(cancelBtn, _gsound_red_butt_press, _gsound_red_butt_release);
@@ -677,7 +678,7 @@ int showLoadFileDialog(char* title, char** fileList, char* dest, int fileListLen
505,
frmImages[FILE_DIALOG_FRM_SCROLL_UP_ARROW_NORMAL].getData(),
frmImages[FILE_DIALOG_FRM_SCROLL_UP_ARROW_PRESSED].getData(),
NULL,
nullptr,
BUTTON_FLAG_TRANSPARENT);
if (scrollUpBtn != -1) {
buttonSetCallbacks(cancelBtn, _gsound_red_butt_press, _gsound_red_butt_release);
@@ -694,7 +695,7 @@ int showLoadFileDialog(char* title, char** fileList, char* dest, int fileListLen
503,
frmImages[FILE_DIALOG_FRM_SCROLL_DOWN_ARROW_NORMAL].getData(),
frmImages[FILE_DIALOG_FRM_SCROLL_DOWN_ARROW_PRESSED].getData(),
NULL,
nullptr,
BUTTON_FLAG_TRANSPARENT);
if (scrollUpBtn != -1) {
buttonSetCallbacks(cancelBtn, _gsound_red_butt_press, _gsound_red_butt_release);
@@ -710,12 +711,12 @@ int showLoadFileDialog(char* title, char** fileList, char* dest, int fileListLen
-1,
-1,
502,
NULL,
NULL,
NULL,
nullptr,
nullptr,
nullptr,
0);
if (title != NULL) {
if (title != nullptr) {
fontDrawText(windowBuffer + backgroundWidth * FILE_DIALOG_TITLE_Y + FILE_DIALOG_TITLE_X, title, backgroundWidth, backgroundWidth, _colorTable[18979]);
}
@@ -885,8 +886,8 @@ int showLoadFileDialog(char* title, char** fileList, char* dest, int fileListLen
}
unsigned int delay = (scrollCounter > 14.4) ? 1000 / scrollDelay : 1000 / 24;
while (getTicksSince(scrollTick) < delay) {
}
delay_ms(delay - (getTicks() - scrollTick));
if (_game_user_wants_to_quit != 0) {
rc = 1;
@@ -909,8 +910,7 @@ int showLoadFileDialog(char* title, char** fileList, char* dest, int fileListLen
doubleClickSelectedFileIndex = -2;
}
while (getTicksSince(tick) < (1000 / 24)) {
}
delay_ms(1000 / 24 - (getTicks() - tick));
}
if (_game_user_wants_to_quit) {
@@ -962,8 +962,8 @@ int showSaveFileDialog(char* title, char** fileList, char* dest, int fileListLen
int backgroundHeight = frmImages[FILE_DIALOG_FRM_BACKGROUND].getHeight();
// Maintain original position in original resolution, otherwise center it.
if (screenGetWidth() != 640) x = (screenGetWidth() - backgroundWidth) / 2;
if (screenGetHeight() != 480) y = (screenGetHeight() - backgroundHeight) / 2;
x += (screenGetWidth() - 640) / 2;
y += (screenGetHeight() - 480) / 2;
int win = windowCreate(x, y, backgroundWidth, backgroundHeight, 256, WINDOW_MODAL | WINDOW_MOVE_ON_TOP);
if (win == -1) {
return -1;
@@ -1009,7 +1009,7 @@ int showSaveFileDialog(char* title, char** fileList, char* dest, int fileListLen
500,
frmImages[FILE_DIALOG_FRM_LITTLE_RED_BUTTON_NORMAL].getData(),
frmImages[FILE_DIALOG_FRM_LITTLE_RED_BUTTON_PRESSED].getData(),
NULL,
nullptr,
BUTTON_FLAG_TRANSPARENT);
if (doneBtn != -1) {
buttonSetCallbacks(doneBtn, _gsound_red_butt_press, _gsound_red_butt_release);
@@ -1026,7 +1026,7 @@ int showSaveFileDialog(char* title, char** fileList, char* dest, int fileListLen
501,
frmImages[FILE_DIALOG_FRM_LITTLE_RED_BUTTON_NORMAL].getData(),
frmImages[FILE_DIALOG_FRM_LITTLE_RED_BUTTON_PRESSED].getData(),
NULL,
nullptr,
BUTTON_FLAG_TRANSPARENT);
if (cancelBtn != -1) {
buttonSetCallbacks(cancelBtn, _gsound_red_butt_press, _gsound_red_butt_release);
@@ -1043,7 +1043,7 @@ int showSaveFileDialog(char* title, char** fileList, char* dest, int fileListLen
505,
frmImages[FILE_DIALOG_FRM_SCROLL_UP_ARROW_NORMAL].getData(),
frmImages[FILE_DIALOG_FRM_SCROLL_UP_ARROW_PRESSED].getData(),
NULL,
nullptr,
BUTTON_FLAG_TRANSPARENT);
if (scrollUpBtn != -1) {
buttonSetCallbacks(cancelBtn, _gsound_red_butt_press, _gsound_red_butt_release);
@@ -1060,7 +1060,7 @@ int showSaveFileDialog(char* title, char** fileList, char* dest, int fileListLen
503,
frmImages[FILE_DIALOG_FRM_SCROLL_DOWN_ARROW_NORMAL].getData(),
frmImages[FILE_DIALOG_FRM_SCROLL_DOWN_ARROW_PRESSED].getData(),
NULL,
nullptr,
BUTTON_FLAG_TRANSPARENT);
if (scrollUpBtn != -1) {
buttonSetCallbacks(cancelBtn, _gsound_red_butt_press, _gsound_red_butt_release);
@@ -1076,12 +1076,12 @@ int showSaveFileDialog(char* title, char** fileList, char* dest, int fileListLen
-1,
-1,
502,
NULL,
NULL,
NULL,
nullptr,
nullptr,
nullptr,
0);
if (title != NULL) {
if (title != nullptr) {
fontDrawText(windowBuffer + backgroundWidth * FILE_DIALOG_TITLE_Y + FILE_DIALOG_TITLE_X, title, backgroundWidth, backgroundWidth, _colorTable[18979]);
}
@@ -1335,8 +1335,7 @@ int showSaveFileDialog(char* title, char** fileList, char* dest, int fileListLen
// FIXME: Missing windowRefresh makes blinking useless.
unsigned int delay = (scrollCounter > 14.4) ? 1000 / scrollDelay : 1000 / 24;
while (getTicksSince(scrollTick) < delay) {
}
delay_ms(delay - (getTicks() - scrollTick));
if (_game_user_wants_to_quit != 0) {
rc = 1;
@@ -1369,8 +1368,7 @@ int showSaveFileDialog(char* title, char** fileList, char* dest, int fileListLen
doubleClickSelectedFileIndex = -2;
}
while (getTicksSince(tick) < (1000 / 24)) {
}
delay_ms(1000 / 24 - (getTicks() - tick));
}
if (_game_user_wants_to_quit != 0) {

View File

@@ -22,7 +22,7 @@ static void _debug_putc(int ch);
static void _debug_scroll();
// 0x51DEF8
static FILE* _fd = NULL;
static FILE* _fd = nullptr;
// 0x51DEFC
static int _curx = 0;
@@ -31,7 +31,7 @@ static int _curx = 0;
static int _cury = 0;
// 0x51DF04
static DebugPrintProc* gDebugPrintProc = NULL;
static DebugPrintProc* gDebugPrintProc = nullptr;
// 0x4C6CD0
void _GNW_debug_init()
@@ -43,9 +43,9 @@ void _GNW_debug_init()
void _debug_register_mono()
{
if (gDebugPrintProc != _debug_mono) {
if (_fd != NULL) {
if (_fd != nullptr) {
fclose(_fd);
_fd = NULL;
_fd = nullptr;
}
gDebugPrintProc = _debug_mono;
@@ -56,8 +56,8 @@ void _debug_register_mono()
// 0x4C6D18
void _debug_register_log(const char* fileName, const char* mode)
{
if ((mode[0] == 'w' && mode[1] == 'a') && mode[1] == 't') {
if (_fd != NULL) {
if ((mode[0] == 'w' || mode[0] == 'a') && mode[1] == 't') {
if (_fd != nullptr) {
fclose(_fd);
}
@@ -70,9 +70,9 @@ void _debug_register_log(const char* fileName, const char* mode)
void _debug_register_screen()
{
if (gDebugPrintProc != _debug_screen) {
if (_fd != NULL) {
if (_fd != nullptr) {
fclose(_fd);
_fd = NULL;
_fd = nullptr;
}
gDebugPrintProc = _debug_screen;
@@ -83,12 +83,12 @@ void _debug_register_screen()
void _debug_register_env()
{
const char* type = getenv("DEBUGACTIVE");
if (type == NULL) {
if (type == nullptr) {
return;
}
char* copy = (char*)internal_malloc(strlen(type) + 1);
if (copy == NULL) {
if (copy == nullptr) {
return;
}
@@ -104,14 +104,8 @@ void _debug_register_env()
// NOTE: Uninline.
_debug_register_screen();
} else if (strcmp(copy, "gnw") == 0) {
if (gDebugPrintProc != _win_debug) {
if (_fd != NULL) {
fclose(_fd);
_fd = NULL;
}
gDebugPrintProc = _win_debug;
}
// NOTE: Uninline.
_debug_register_func(_win_debug);
}
internal_free(copy);
@@ -121,9 +115,9 @@ void _debug_register_env()
void _debug_register_func(DebugPrintProc* proc)
{
if (gDebugPrintProc != proc) {
if (_fd != NULL) {
if (_fd != nullptr) {
fclose(_fd);
_fd = NULL;
_fd = nullptr;
}
gDebugPrintProc = proc;
@@ -138,7 +132,7 @@ int debugPrint(const char* format, ...)
int rc;
if (gDebugPrintProc != NULL) {
if (gDebugPrintProc != nullptr) {
char string[260];
vsnprintf(string, sizeof(string), format, args);
@@ -158,7 +152,7 @@ int debugPrint(const char* format, ...)
// 0x4C6F94
static int _debug_puts(char* string)
{
if (gDebugPrintProc != NULL) {
if (gDebugPrintProc != nullptr) {
return gDebugPrintProc(string);
}
@@ -172,7 +166,7 @@ static void _debug_clear()
int x;
int y;
buffer = NULL;
buffer = nullptr;
if (gDebugPrintProc == _debug_mono) {
buffer = (char*)0xB0000;
@@ -180,7 +174,7 @@ static void _debug_clear()
buffer = (char*)0xB8000;
}
if (buffer != NULL) {
if (buffer != nullptr) {
for (y = 0; y < 25; y++) {
for (x = 0; x < 80; x++) {
*buffer++ = ' ';
@@ -208,7 +202,7 @@ static int _debug_mono(char* string)
static int _debug_log(char* string)
{
if (gDebugPrintProc == _debug_log) {
if (_fd == NULL) {
if (_fd == nullptr) {
return -1;
}
@@ -306,7 +300,7 @@ static void _debug_scroll()
// 0x4C71E8
void _debug_exit(void)
{
if (_fd != NULL) {
if (_fd != nullptr) {
fclose(_fd);
}
}

11
src/delay.cc Normal file
View File

@@ -0,0 +1,11 @@
#include "delay.h"
#include <SDL.h>
void delay_ms(int ms)
{
if (ms <= 0) {
return;
}
SDL_Delay(ms);
}

6
src/delay.h Normal file
View File

@@ -0,0 +1,6 @@
#ifndef DELAY_H
#define DELAY_H
void delay_ms(int ms);
#endif

View File

@@ -51,14 +51,14 @@ DBase* dbaseOpen(const char* filePath)
assert(filePath); // "filename", "dfile.c", 74
FILE* stream = compat_fopen(filePath, "rb");
if (stream == NULL) {
return NULL;
if (stream == nullptr) {
return nullptr;
}
DBase* dbase = (DBase*)malloc(sizeof(*dbase));
if (dbase == NULL) {
if (dbase == nullptr) {
fclose(stream);
return NULL;
return nullptr;
}
memset(dbase, 0, sizeof(*dbase));
@@ -95,7 +95,7 @@ DBase* dbaseOpen(const char* filePath)
}
dbase->entries = (DBaseEntry*)malloc(sizeof(*dbase->entries) * dbase->entriesLength);
if (dbase->entries == NULL) {
if (dbase->entries == nullptr) {
goto err;
}
@@ -112,7 +112,7 @@ DBase* dbaseOpen(const char* filePath)
}
entry->path = (char*)malloc(pathLength + 1);
if (entry->path == NULL) {
if (entry->path == nullptr) {
break;
}
@@ -158,7 +158,7 @@ err:
fclose(stream);
return NULL;
return nullptr;
}
// Closes [dbase], all open file handles, frees all associated resources,
@@ -170,24 +170,24 @@ bool dbaseClose(DBase* dbase)
assert(dbase); // "dbase", "dfile.c", 173
DFile* curr = dbase->dfileHead;
while (curr != NULL) {
while (curr != nullptr) {
DFile* next = curr->next;
dfileClose(curr);
curr = next;
}
if (dbase->entries != NULL) {
if (dbase->entries != nullptr) {
for (int index = 0; index < dbase->entriesLength; index++) {
DBaseEntry* entry = &(dbase->entries[index]);
char* entryName = entry->path;
if (entryName != NULL) {
if (entryName != nullptr) {
free(entryName);
}
}
free(dbase->entries);
}
if (dbase->path != NULL) {
if (dbase->path != nullptr) {
free(dbase->path);
}
@@ -258,15 +258,15 @@ int dfileClose(DFile* stream)
}
}
if (stream->decompressionStream != NULL) {
if (stream->decompressionStream != nullptr) {
free(stream->decompressionStream);
}
if (stream->decompressionBuffer != NULL) {
if (stream->decompressionBuffer != nullptr) {
free(stream->decompressionBuffer);
}
if (stream->stream != NULL) {
if (stream->stream != nullptr) {
fclose(stream->stream);
}
@@ -275,8 +275,8 @@ int dfileClose(DFile* stream)
//
// NOTE: Compiled code is slightly different.
DFile* curr = stream->dbase->dfileHead;
DFile* prev = NULL;
while (curr != NULL) {
DFile* prev = nullptr;
while (curr != nullptr) {
if (curr == stream) {
break;
}
@@ -285,8 +285,8 @@ int dfileClose(DFile* stream)
curr = curr->next;
}
if (curr != NULL) {
if (prev == NULL) {
if (curr != nullptr) {
if (prev == nullptr) {
stream->dbase->dfileHead = stream->next;
} else {
prev->next = stream->next;
@@ -309,7 +309,7 @@ DFile* dfileOpen(DBase* dbase, const char* filePath, const char* mode)
assert(filePath); // dfile.c, 296
assert(mode); // dfile.c, 297
return dfileOpenInternal(dbase, filePath, mode, 0);
return dfileOpenInternal(dbase, filePath, mode, nullptr);
}
// [vfprintf].
@@ -363,7 +363,7 @@ char* dfileReadString(char* string, int size, DFile* stream)
assert(stream); // "stream", "dfile.c", 409
if ((stream->flags & DFILE_EOF) != 0 || (stream->flags & DFILE_ERROR) != 0) {
return NULL;
return nullptr;
}
char* pch = string;
@@ -391,7 +391,7 @@ char* dfileReadString(char* string, int size, DFile* stream)
if (pch == string) {
// No character was set into the buffer.
return NULL;
return nullptr;
}
*pch = '\0';
@@ -633,7 +633,7 @@ static int dbaseFindEntryByFilePath(const void* a1, const void* a2)
static DFile* dfileOpenInternal(DBase* dbase, const char* filePath, const char* mode, DFile* dfile)
{
DBaseEntry* entry = (DBaseEntry*)bsearch(filePath, dbase->entries, dbase->entriesLength, sizeof(*dbase->entries), dbaseFindEntryByFilePath);
if (entry == NULL) {
if (entry == nullptr) {
goto err;
}
@@ -641,10 +641,10 @@ static DFile* dfileOpenInternal(DBase* dbase, const char* filePath, const char*
goto err;
}
if (dfile == NULL) {
if (dfile == nullptr) {
dfile = (DFile*)malloc(sizeof(*dfile));
if (dfile == NULL) {
return NULL;
if (dfile == nullptr) {
return nullptr;
}
memset(dfile, 0, sizeof(*dfile));
@@ -656,9 +656,9 @@ static DFile* dfileOpenInternal(DBase* dbase, const char* filePath, const char*
goto err;
}
if (dfile->stream != NULL) {
if (dfile->stream != nullptr) {
fclose(dfile->stream);
dfile->stream = NULL;
dfile->stream = nullptr;
}
dfile->compressedBytesRead = 0;
@@ -670,7 +670,7 @@ static DFile* dfileOpenInternal(DBase* dbase, const char* filePath, const char*
// Open stream to .DAT file.
dfile->stream = compat_fopen(dbase->path, "rb");
if (dfile->stream == NULL) {
if (dfile->stream == nullptr) {
goto err;
}
@@ -684,14 +684,14 @@ static DFile* dfileOpenInternal(DBase* dbase, const char* filePath, const char*
// buffer. This step is not needed when previous instance of dfile is
// passed via parameter, which might already have stream and
// buffer allocated.
if (dfile->decompressionStream == NULL) {
if (dfile->decompressionStream == nullptr) {
dfile->decompressionStream = (z_streamp)malloc(sizeof(*dfile->decompressionStream));
if (dfile->decompressionStream == NULL) {
if (dfile->decompressionStream == nullptr) {
goto err;
}
dfile->decompressionBuffer = (unsigned char*)malloc(DFILE_DECOMPRESSION_BUFFER_SIZE);
if (dfile->decompressionBuffer == NULL) {
if (dfile->decompressionBuffer == nullptr) {
goto err;
}
}
@@ -709,14 +709,14 @@ static DFile* dfileOpenInternal(DBase* dbase, const char* filePath, const char*
// Entry is not compressed, there is no need to keep decompression
// stream and decompression buffer (in case [dfile] was passed via
// parameter).
if (dfile->decompressionStream != NULL) {
if (dfile->decompressionStream != nullptr) {
free(dfile->decompressionStream);
dfile->decompressionStream = NULL;
dfile->decompressionStream = nullptr;
}
if (dfile->decompressionBuffer != NULL) {
if (dfile->decompressionBuffer != nullptr) {
free(dfile->decompressionBuffer);
dfile->decompressionBuffer = NULL;
dfile->decompressionBuffer = nullptr;
}
}
@@ -728,11 +728,11 @@ static DFile* dfileOpenInternal(DBase* dbase, const char* filePath, const char*
err:
if (dfile != NULL) {
if (dfile != nullptr) {
dfileClose(dfile);
}
return NULL;
return nullptr;
}
// 0x4E5F9C

View File

@@ -28,10 +28,10 @@ int _topDialogLine = 0;
int _topDialogReply = 0;
// 0x5184E4
DialogFunc1* _replyWinDrawCallback = NULL;
DialogFunc1* _replyWinDrawCallback = nullptr;
// 0x5184E8
DialogFunc2* _optionsWinDrawCallback = NULL;
DialogFunc2* _optionsWinDrawCallback = nullptr;
// 0x5184EC
int gDialogBorderX = 7;
@@ -171,7 +171,7 @@ STRUCT_56DAE0_FIELD_4* _getReply()
STRUCT_56DAE0_FIELD_4_FIELD_C* v1;
v0 = &(_dialog[_tods].field_4[_dialog[_tods].field_C]);
if (v0->field_C == NULL) {
if (v0->field_C == nullptr) {
v0->field_14 = 1;
v1 = (STRUCT_56DAE0_FIELD_4_FIELD_C*)internal_malloc_safe(sizeof(STRUCT_56DAE0_FIELD_4_FIELD_C), __FILE__, __LINE__); // "..\\int\\DIALOG.C", 789
} else {
@@ -195,20 +195,20 @@ void _replyAddOption(const char* a1, const char* a2, int a3)
v17 = v18->field_14 - 1;
v18->field_C[v17].kind = 2;
if (a1 != NULL) {
if (a1 != nullptr) {
v14 = (char*)internal_malloc_safe(strlen(a1) + 1, __FILE__, __LINE__); // "..\\int\\DIALOG.C", 805
strcpy(v14, a1);
v18->field_C[v17].field_0 = v14;
} else {
v18->field_C[v17].field_0 = NULL;
v18->field_C[v17].field_0 = nullptr;
}
if (a2 != NULL) {
if (a2 != nullptr) {
v15 = (char*)internal_malloc_safe(strlen(a2) + 1, __FILE__, __LINE__); // "..\\int\\DIALOG.C", 810
strcpy(v15, a2);
v18->field_C[v17].string = v15;
} else {
v18->field_C[v17].string = NULL;
v18->field_C[v17].string = nullptr;
}
v18->field_C[v17].field_18 = windowGetFont();
@@ -228,12 +228,12 @@ void _replyAddOptionProc(const char* a1, int a2, int a3)
v5->field_C[v13].kind = 1;
if (a1 != NULL) {
if (a1 != nullptr) {
v11 = (char*)internal_malloc_safe(strlen(a1) + 1, __FILE__, __LINE__); // "..\\int\\DIALOG.C", 830
strcpy(v11, a1);
v5->field_C[v13].field_0 = v11;
} else {
v5->field_C[v13].field_0 = NULL;
v5->field_C[v13].field_0 = nullptr;
}
v5->field_C[v13].proc = a2;
@@ -246,12 +246,12 @@ void _replyAddOptionProc(const char* a1, int a2, int a3)
// 0x42F714
void _optionFree(STRUCT_56DAE0_FIELD_4_FIELD_C* a1)
{
if (a1->field_0 != NULL) {
if (a1->field_0 != nullptr) {
internal_free_safe(a1->field_0, __FILE__, __LINE__); // "..\\int\\DIALOG.C", 844
}
if (a1->kind == 2) {
if (a1->string != NULL) {
if (a1->string != nullptr) {
internal_free_safe(a1->string, __FILE__, __LINE__); // "..\\int\\DIALOG.C", 846
}
}
@@ -269,7 +269,7 @@ void _replyFree()
for (i = 0; i < ptr->field_8; i++) {
v6 = &(_dialog[_tods].field_4[i]);
if (v6->field_C != NULL) {
if (v6->field_C != nullptr) {
for (j = 0; j < v6->field_14; j++) {
_optionFree(&(v6->field_C[j]));
}
@@ -277,20 +277,20 @@ void _replyFree()
internal_free_safe(v6->field_C, __FILE__, __LINE__); // "..\\int\\DIALOG.C", 857
}
if (v6->field_8 != NULL) {
if (v6->field_8 != nullptr) {
internal_free_safe(v6->field_8, __FILE__, __LINE__); // "..\\int\\DIALOG.C", 860
}
if (v6->field_4 != NULL) {
if (v6->field_4 != nullptr) {
internal_free_safe(v6->field_4, __FILE__, __LINE__); // "..\\int\\DIALOG.C", 862
}
if (v6->field_0 != NULL) {
if (v6->field_0 != nullptr) {
internal_free_safe(v6->field_0, __FILE__, __LINE__); // "..\\int\\DIALOG.C", 864
}
}
if (ptr->field_4 != NULL) {
if (ptr->field_4 != nullptr) {
internal_free_safe(ptr->field_4, __FILE__, __LINE__); // "..\\int\\DIALOG.C", 867
}
}
@@ -305,9 +305,9 @@ int _endDialog()
_topDialogReply = _dialog[_tods].field_10;
_replyFree();
if (gDialogReplyTitle != NULL) {
if (gDialogReplyTitle != nullptr) {
internal_free_safe(gDialogReplyTitle, __FILE__, __LINE__); // "..\\int\\DIALOG.C", 986
gDialogReplyTitle = NULL;
gDialogReplyTitle = nullptr;
}
--_tods;
@@ -414,7 +414,7 @@ int _dialogStart(Program* a1)
ptr = &(_dialog[_tods]);
ptr->field_0 = a1;
ptr->field_4 = 0;
ptr->field_4 = nullptr;
ptr->field_8 = 0;
ptr->field_C = -1;
ptr->field_10 = -1;
@@ -449,11 +449,11 @@ int _dialogGotoReply(const char* a1)
return 1;
}
if (a1 != NULL) {
if (a1 != nullptr) {
ptr = &(_dialog[_tods]);
for (i = 0; i < ptr->field_8; i++) {
v5 = &(ptr->field_4[i]);
if (v5->field_4 != NULL && compat_stricmp(v5->field_4, a1) == 0) {
if (v5->field_4 != nullptr && compat_stricmp(v5->field_4, a1) == 0) {
ptr->field_10 = i;
return 0;
}
@@ -470,15 +470,15 @@ int _dialogGotoReply(const char* a1)
// 0x430E84
int dialogSetReplyTitle(const char* a1)
{
if (gDialogReplyTitle != NULL) {
if (gDialogReplyTitle != nullptr) {
internal_free_safe(gDialogReplyTitle, __FILE__, __LINE__); // "..\\int\\DIALOG.C", 2561
}
if (a1 != NULL) {
if (a1 != nullptr) {
gDialogReplyTitle = (char*)internal_malloc_safe(strlen(a1) + 1, __FILE__, __LINE__); // "..\\int\\DIALOG.C", 2564
strcpy(gDialogReplyTitle, a1);
} else {
gDialogReplyTitle = NULL;
gDialogReplyTitle = nullptr;
}
return 0;
@@ -586,22 +586,22 @@ int _dialogSetScrollUp(int a1, int a2, char* a3, char* a4, char* a5, char* a6, i
_upButton = a1;
dword_56DBD8 = a2;
if (off_56DBE0 != NULL) {
if (off_56DBE0 != nullptr) {
internal_free_safe(off_56DBE0, __FILE__, __LINE__); // "..\\int\\DIALOG.C", 2750
}
off_56DBE0 = a3;
if (off_56DBE4 != NULL) {
if (off_56DBE4 != nullptr) {
internal_free_safe(off_56DBE4, __FILE__, __LINE__); // "..\\int\\DIALOG.C", 2752
}
off_56DBE4 = a4;
if (off_56DBE8 != NULL) {
if (off_56DBE8 != nullptr) {
internal_free_safe(off_56DBE8, __FILE__, __LINE__); // "..\\int\\DIALOG.C", 2754
}
off_56DBE8 = a5;
if (off_56DBEC != NULL) {
if (off_56DBEC != nullptr) {
internal_free_safe(off_56DBEC, __FILE__, __LINE__); // "..\\int\\DIALOG.C", 2756
}
off_56DBEC = a5;
@@ -617,22 +617,22 @@ int _dialogSetScrollDown(int a1, int a2, char* a3, char* a4, char* a5, char* a6,
_downButton = a1;
dword_56DBB8 = a2;
if (off_56DBC0 != NULL) {
if (off_56DBC0 != nullptr) {
internal_free_safe(off_56DBC0, __FILE__, __LINE__); // "..\\int\\DIALOG.C", 2765
}
off_56DBC0 = a3;
if (off_56DBC4 != NULL) {
if (off_56DBC4 != nullptr) {
internal_free_safe(off_56DBC4, __FILE__, __LINE__); // "..\\int\\DIALOG.C", 2767
}
off_56DBC4 = a4;
if (off_56DBC8 != NULL) {
if (off_56DBC8 != nullptr) {
internal_free_safe(off_56DBC8, __FILE__, __LINE__); // "..\\int\\DIALOG.C", 2769
}
off_56DBC8 = a5;
if (off_56DBCC != NULL) {
if (off_56DBCC != nullptr) {
internal_free_safe(off_56DBCC, __FILE__, __LINE__); // "..\\int\\DIALOG.C", 2771
}
off_56DBCC = a6;

View File

@@ -52,11 +52,11 @@ int dictionaryInit(Dictionary* dictionary, int initialCapacity, size_t valueSize
dictionary->valueSize = valueSize;
dictionary->entriesLength = 0;
if (io != NULL) {
if (io != nullptr) {
memcpy(&(dictionary->io), io, sizeof(*io));
} else {
dictionary->io.readProc = NULL;
dictionary->io.writeProc = NULL;
dictionary->io.readProc = nullptr;
dictionary->io.writeProc = nullptr;
dictionary->io.field_8 = 0;
dictionary->io.field_C = 0;
}
@@ -65,11 +65,11 @@ int dictionaryInit(Dictionary* dictionary, int initialCapacity, size_t valueSize
if (initialCapacity != 0) {
dictionary->entries = (DictionaryEntry*)gDictionaryMallocProc(sizeof(*dictionary->entries) * initialCapacity);
if (dictionary->entries == NULL) {
if (dictionary->entries == nullptr) {
rc = -1;
}
} else {
dictionary->entries = NULL;
dictionary->entries = nullptr;
}
if (rc != -1) {
@@ -91,7 +91,7 @@ int dictionarySetCapacity(Dictionary* dictionary, int newCapacity)
}
DictionaryEntry* entries = (DictionaryEntry*)gDictionaryReallocProc(dictionary->entries, sizeof(*dictionary->entries) * newCapacity);
if (entries == NULL) {
if (entries == nullptr) {
return -1;
}
@@ -110,16 +110,16 @@ int dictionaryFree(Dictionary* dictionary)
for (int index = 0; index < dictionary->entriesLength; index++) {
DictionaryEntry* entry = &(dictionary->entries[index]);
if (entry->key != NULL) {
if (entry->key != nullptr) {
gDictionaryFreeProc(entry->key);
}
if (entry->value != NULL) {
if (entry->value != nullptr) {
gDictionaryFreeProc(entry->value);
}
}
if (dictionary->entries != NULL) {
if (dictionary->entries != nullptr) {
gDictionaryFreeProc(dictionary->entries);
}
@@ -224,23 +224,23 @@ int dictionaryAddValue(Dictionary* dictionary, const char* key, const void* valu
// Make a copy of the key.
char* keyCopy = (char*)gDictionaryMallocProc(strlen(key) + 1);
if (keyCopy == NULL) {
if (keyCopy == nullptr) {
return -1;
}
strcpy(keyCopy, key);
// Make a copy of the value.
void* valueCopy = NULL;
if (value != NULL && dictionary->valueSize != 0) {
void* valueCopy = nullptr;
if (value != nullptr && dictionary->valueSize != 0) {
valueCopy = gDictionaryMallocProc(dictionary->valueSize);
if (valueCopy == NULL) {
if (valueCopy == nullptr) {
gDictionaryFreeProc(keyCopy);
return -1;
}
}
if (valueCopy != NULL && dictionary->valueSize != 0) {
if (valueCopy != nullptr && dictionary->valueSize != 0) {
memcpy(valueCopy, value, dictionary->valueSize);
}
@@ -282,7 +282,7 @@ int dictionaryRemoveValue(Dictionary* dictionary, const char* key)
// Free key and value (which are copies).
gDictionaryFreeProc(entry->key);
if (entry->value != NULL) {
if (entry->value != nullptr) {
gDictionaryFreeProc(entry->value);
}
@@ -397,16 +397,16 @@ int dictionaryLoad(FILE* stream, Dictionary* dictionary, int a3)
for (int index = 0; index < dictionary->entriesLength; index++) {
DictionaryEntry* entry = &(dictionary->entries[index]);
if (entry->key != NULL) {
if (entry->key != nullptr) {
gDictionaryFreeProc(entry->key);
}
if (entry->value != NULL) {
if (entry->value != nullptr) {
gDictionaryFreeProc(entry->value);
}
}
if (dictionary->entries != NULL) {
if (dictionary->entries != nullptr) {
gDictionaryFreeProc(dictionary->entries);
}
@@ -414,21 +414,21 @@ int dictionaryLoad(FILE* stream, Dictionary* dictionary, int a3)
return -1;
}
dictionary->entries = NULL;
dictionary->entries = nullptr;
if (dictionary->entriesCapacity <= 0) {
return 0;
}
dictionary->entries = (DictionaryEntry*)gDictionaryMallocProc(sizeof(*dictionary->entries) * dictionary->entriesCapacity);
if (dictionary->entries == NULL) {
if (dictionary->entries == nullptr) {
return -1;
}
for (int index = 0; index < dictionary->entriesLength; index++) {
DictionaryEntry* entry = &(dictionary->entries[index]);
entry->key = NULL;
entry->value = NULL;
entry->key = nullptr;
entry->value = nullptr;
}
if (dictionary->entriesLength <= 0) {
@@ -443,21 +443,21 @@ int dictionaryLoad(FILE* stream, Dictionary* dictionary, int a3)
}
entry->key = (char*)gDictionaryMallocProc(keyLength + 1);
if (entry->key == NULL) {
if (entry->key == nullptr) {
return -1;
}
if (fgets(entry->key, keyLength + 1, stream) == NULL) {
if (compat_fgets(entry->key, keyLength + 1, stream) == nullptr) {
return -1;
}
if (dictionary->valueSize != 0) {
entry->value = gDictionaryMallocProc(dictionary->valueSize);
if (entry->value == NULL) {
if (entry->value == nullptr) {
return -1;
}
if (dictionary->io.readProc != NULL) {
if (dictionary->io.readProc != nullptr) {
if (dictionary->io.readProc(stream, entry->value, dictionary->valueSize, a3) != 0) {
return -1;
}
@@ -523,7 +523,7 @@ int dictionaryWrite(FILE* stream, Dictionary* dictionary, int a3)
return -1;
}
if (dictionary->io.writeProc != NULL) {
if (dictionary->io.writeProc != nullptr) {
if (dictionary->valueSize != 0) {
if (dictionary->io.writeProc(stream, entry->value, dictionary->valueSize, a3) != 0) {
return -1;
@@ -544,7 +544,7 @@ int dictionaryWrite(FILE* stream, Dictionary* dictionary, int a3)
// 0x4DA498
void dictionarySetMemoryProcs(MallocProc* mallocProc, ReallocProc* reallocProc, FreeProc* freeProc)
{
if (mallocProc != NULL && reallocProc != NULL && freeProc != NULL) {
if (mallocProc != nullptr && reallocProc != nullptr && freeProc != nullptr) {
gDictionaryMallocProc = mallocProc;
gDictionaryReallocProc = reallocProc;
gDictionaryFreeProc = freeProc;

View File

@@ -2,30 +2,9 @@
namespace fallout {
enum InputType {
INPUT_TYPE_MOUSE,
INPUT_TYPE_TOUCH,
} InputType;
static int gLastInputType = INPUT_TYPE_MOUSE;
static int gTouchMouseLastX = 0;
static int gTouchMouseLastY = 0;
static int gTouchMouseDeltaX = 0;
static int gTouchMouseDeltaY = 0;
static int gTouchFingers = 0;
static unsigned int gTouchGestureLastTouchDownTimestamp = 0;
static unsigned int gTouchGestureLastTouchUpTimestamp = 0;
static int gTouchGestureTaps = 0;
static bool gTouchGestureHandled = false;
static int gMouseWheelDeltaX = 0;
static int gMouseWheelDeltaY = 0;
extern int screenGetWidth();
extern int screenGetHeight();
// 0x4E0400
bool directInputInit()
{
@@ -71,49 +50,22 @@ bool mouseDeviceUnacquire()
// 0x4E053C
bool mouseDeviceGetData(MouseData* mouseState)
{
if (gLastInputType == INPUT_TYPE_TOUCH) {
mouseState->x = gTouchMouseDeltaX;
mouseState->y = gTouchMouseDeltaY;
mouseState->buttons[0] = 0;
mouseState->buttons[1] = 0;
mouseState->wheelX = 0;
mouseState->wheelY = 0;
gTouchMouseDeltaX = 0;
gTouchMouseDeltaY = 0;
// CE: This function is sometimes called outside loops calling `get_input`
// and subsequently `GNW95_process_message`, so mouse events might not be
// handled by SDL yet.
//
// TODO: Move mouse events processing into `GNW95_process_message` and
// update mouse position manually.
SDL_PumpEvents();
if (gTouchFingers == 0) {
if (SDL_GetTicks() - gTouchGestureLastTouchUpTimestamp > 150) {
if (!gTouchGestureHandled) {
if (gTouchGestureTaps == 2) {
mouseState->buttons[0] = 1;
gTouchGestureHandled = true;
} else if (gTouchGestureTaps == 3) {
mouseState->buttons[1] = 1;
gTouchGestureHandled = true;
}
}
}
} else if (gTouchFingers == 1) {
if (SDL_GetTicks() - gTouchGestureLastTouchDownTimestamp > 150) {
if (gTouchGestureTaps == 1) {
mouseState->buttons[0] = 1;
gTouchGestureHandled = true;
} else if (gTouchGestureTaps == 2) {
mouseState->buttons[1] = 1;
gTouchGestureHandled = true;
}
}
}
} else {
Uint32 buttons = SDL_GetRelativeMouseState(&(mouseState->x), &(mouseState->y));
mouseState->buttons[0] = (buttons & SDL_BUTTON(SDL_BUTTON_LEFT)) != 0;
mouseState->buttons[1] = (buttons & SDL_BUTTON(SDL_BUTTON_RIGHT)) != 0;
mouseState->wheelX = gMouseWheelDeltaX;
mouseState->wheelY = gMouseWheelDeltaY;
Uint32 buttons = SDL_GetRelativeMouseState(&(mouseState->x), &(mouseState->y));
mouseState->buttons[0] = (buttons & SDL_BUTTON(SDL_BUTTON_LEFT)) != 0;
mouseState->buttons[1] = (buttons & SDL_BUTTON(SDL_BUTTON_RIGHT)) != 0;
mouseState->wheelX = gMouseWheelDeltaX;
mouseState->wheelY = gMouseWheelDeltaY;
gMouseWheelDeltaX = 0;
gMouseWheelDeltaY = 0;
}
gMouseWheelDeltaX = 0;
gMouseWheelDeltaY = 0;
return true;
}
@@ -174,70 +126,6 @@ void handleMouseEvent(SDL_Event* event)
gMouseWheelDeltaX += event->wheel.x;
gMouseWheelDeltaY += event->wheel.y;
}
if (gLastInputType != INPUT_TYPE_MOUSE) {
// Reset touch data.
gTouchMouseLastX = 0;
gTouchMouseLastY = 0;
gTouchMouseDeltaX = 0;
gTouchMouseDeltaY = 0;
gTouchFingers = 0;
gTouchGestureLastTouchDownTimestamp = 0;
gTouchGestureLastTouchUpTimestamp = 0;
gTouchGestureTaps = 0;
gTouchGestureHandled = false;
gLastInputType = INPUT_TYPE_MOUSE;
}
}
void handleTouchEvent(SDL_Event* event)
{
int windowWidth = screenGetWidth();
int windowHeight = screenGetHeight();
if (event->tfinger.type == SDL_FINGERDOWN) {
gTouchFingers++;
gTouchMouseLastX = (int)(event->tfinger.x * windowWidth);
gTouchMouseLastY = (int)(event->tfinger.y * windowHeight);
gTouchMouseDeltaX = 0;
gTouchMouseDeltaY = 0;
if (event->tfinger.timestamp - gTouchGestureLastTouchDownTimestamp > 250) {
gTouchGestureTaps = 0;
gTouchGestureHandled = false;
}
gTouchGestureLastTouchDownTimestamp = event->tfinger.timestamp;
} else if (event->tfinger.type == SDL_FINGERMOTION) {
int prevX = gTouchMouseLastX;
int prevY = gTouchMouseLastY;
gTouchMouseLastX = (int)(event->tfinger.x * windowWidth);
gTouchMouseLastY = (int)(event->tfinger.y * windowHeight);
gTouchMouseDeltaX += gTouchMouseLastX - prevX;
gTouchMouseDeltaY += gTouchMouseLastY - prevY;
} else if (event->tfinger.type == SDL_FINGERUP) {
gTouchFingers--;
int prevX = gTouchMouseLastX;
int prevY = gTouchMouseLastY;
gTouchMouseLastX = (int)(event->tfinger.x * windowWidth);
gTouchMouseLastY = (int)(event->tfinger.y * windowHeight);
gTouchMouseDeltaX += gTouchMouseLastX - prevX;
gTouchMouseDeltaY += gTouchMouseLastY - prevY;
gTouchGestureTaps++;
gTouchGestureLastTouchUpTimestamp = event->tfinger.timestamp;
}
if (gLastInputType != INPUT_TYPE_TOUCH) {
// Reset mouse data.
SDL_GetRelativeMouseState(NULL, NULL);
gLastInputType = INPUT_TYPE_TOUCH;
}
}
} // namespace fallout

View File

@@ -118,7 +118,7 @@ int displayMonitorInit()
fontSetCurrent(oldFont);
gDisplayMonitorBackgroundFrmData = (unsigned char*)internal_malloc(DISPLAY_MONITOR_WIDTH * DISPLAY_MONITOR_HEIGHT);
if (gDisplayMonitorBackgroundFrmData == NULL) {
if (gDisplayMonitorBackgroundFrmData == nullptr) {
return -1;
}
@@ -158,16 +158,16 @@ int displayMonitorInit()
-1,
-1,
-1,
NULL,
NULL,
NULL,
nullptr,
nullptr,
nullptr,
0);
if (gDisplayMonitorScrollUpButton != -1) {
buttonSetMouseCallbacks(gDisplayMonitorScrollUpButton,
displayMonitorScrollUpOnMouseEnter,
displayMonitorOnMouseExit,
displayMonitorScrollUpOnMouseDown,
NULL);
nullptr);
}
gDisplayMonitorScrollDownButton = buttonCreate(gInterfaceBarWindow,
@@ -179,16 +179,16 @@ int displayMonitorInit()
-1,
-1,
-1,
NULL,
NULL,
NULL,
nullptr,
nullptr,
nullptr,
0);
if (gDisplayMonitorScrollDownButton != -1) {
buttonSetMouseCallbacks(gDisplayMonitorScrollDownButton,
displayMonitorScrollDownOnMouseEnter,
displayMonitorOnMouseExit,
displayMonitorScrollDownOnMouseDown,
NULL);
nullptr);
}
gDisplayMonitorEnabled = true;
@@ -257,7 +257,7 @@ void displayMonitorAddMessage(char* str)
}
// TODO: Refactor these two loops.
char* v1 = NULL;
char* v1 = nullptr;
while (true) {
while (fontGetStringWidth(str) < DISPLAY_MONITOR_WIDTH - _max_disp - knobWidth) {
char* temp = gDisplayMonitorLines[_disp_start];
@@ -274,7 +274,7 @@ void displayMonitorAddMessage(char* str)
gDisplayMonitorLines[_disp_start][DISPLAY_MONITOR_LINE_LENGTH - 1] = '\0';
_disp_start = (_disp_start + 1) % gDisplayMonitorLinesCapacity;
if (v1 == NULL) {
if (v1 == nullptr) {
fontSetCurrent(oldFont);
_disp_curr = _disp_start;
displayMonitorRefresh();
@@ -283,20 +283,20 @@ void displayMonitorAddMessage(char* str)
str = v1 + 1;
*v1 = ' ';
v1 = NULL;
v1 = nullptr;
}
char* space = strrchr(str, ' ');
if (space == NULL) {
if (space == nullptr) {
break;
}
if (v1 != NULL) {
if (v1 != nullptr) {
*v1 = ' ';
}
v1 = space;
if (space != NULL) {
if (space != nullptr) {
*space = '\0';
}
}
@@ -347,7 +347,7 @@ static void displayMonitorRefresh()
}
unsigned char* buf = windowGetBuffer(gInterfaceBarWindow);
if (buf == NULL) {
if (buf == nullptr) {
return;
}
@@ -438,11 +438,11 @@ static void consoleFileInit()
{
char* consoleFilePath;
configGetString(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_CONSOLE_OUTPUT_FILE_KEY, &consoleFilePath);
if (consoleFilePath != NULL && *consoleFilePath == '\0') {
consoleFilePath = NULL;
if (consoleFilePath != nullptr && *consoleFilePath == '\0') {
consoleFilePath = nullptr;
}
if (consoleFilePath != NULL) {
if (consoleFilePath != nullptr) {
gConsoleFileStream.open(consoleFilePath);
}
}

View File

@@ -3,7 +3,6 @@
#include <string.h>
#include "color.h"
#include "mmx.h"
#include "svga.h"
namespace fallout {
@@ -28,7 +27,7 @@ void bufferDrawLine(unsigned char* buf, int pitch, int x1, int y1, int x2, int y
p1 = buf + pitch * y1 + x1;
p2 = buf + pitch * y2 + x2;
while (p1 < p2) {
while (p1 <= p2) {
*p1 = color;
*p2 = color;
p1 += pitch;
@@ -208,13 +207,13 @@ void blitBufferToBufferStretchTrans(unsigned char* src, int srcWidth, int srcHei
// 0x4D36D4
void blitBufferToBuffer(unsigned char* src, int width, int height, int srcPitch, unsigned char* dest, int destPitch)
{
mmxBlit(dest, destPitch, src, srcPitch, width, height);
srcCopy(dest, destPitch, src, srcPitch, width, height);
}
// 0x4D3704
void blitBufferToBufferTrans(unsigned char* src, int width, int height, int srcPitch, unsigned char* dest, int destPitch)
{
mmxBlitTrans(dest, destPitch, src, srcPitch, width, height);
transSrcCopy(dest, destPitch, src, srcPitch, width, height);
}
// 0x4D387C
@@ -311,4 +310,33 @@ void bufferOutline(unsigned char* buf, int width, int height, int pitch, int col
}
}
// 0x4E0DB0
void srcCopy(unsigned char* dest, int destPitch, unsigned char* src, int srcPitch, int width, int height)
{
for (int y = 0; y < height; y++) {
memcpy(dest, src, width);
dest += destPitch;
src += srcPitch;
}
}
// 0x4E0ED5
void transSrcCopy(unsigned char* dest, int destPitch, unsigned char* src, int srcPitch, int width, int height)
{
int destSkip = destPitch - width;
int srcSkip = srcPitch - width;
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
unsigned char c = *src++;
if (c != 0) {
*dest = c;
}
dest++;
}
src += srcSkip;
dest += destSkip;
}
}
} // namespace fallout

View File

@@ -15,6 +15,8 @@ void _buf_texture(unsigned char* buf, int width, int height, int pitch, void* a5
void _lighten_buf(unsigned char* buf, int width, int height, int pitch);
void _swap_color_buf(unsigned char* buf, int width, int height, int pitch, int color1, int color2);
void bufferOutline(unsigned char* buf, int width, int height, int pitch, int a5);
void srcCopy(unsigned char* dest, int destPitch, unsigned char* src, int srcPitch, int width, int height);
void transSrcCopy(unsigned char* dest, int destPitch, unsigned char* src, int srcPitch, int width, int height);
} // namespace fallout

View File

@@ -8,6 +8,7 @@
#include "art.h"
#include "cycle.h"
#include "debug.h"
#include "delay.h"
#include "draw.h"
#include "game_mouse.h"
#include "game_sound.h"
@@ -453,8 +454,7 @@ int elevatorSelectLevel(int elevator, int* mapPtr, int* elevationPtr, int* tileP
windowRefresh(gElevatorWindow);
while (getTicksSince(tick) < delay) {
}
delay_ms(delay - (getTicks() - tick));
renderPresent();
sharedFpsLimiter.throttle();
@@ -593,10 +593,10 @@ static int elevatorWindowInit(int elevator)
500 + level,
_elevatorFrmImages[ELEVATOR_FRM_BUTTON_UP].getData(),
_elevatorFrmImages[ELEVATOR_FRM_BUTTON_DOWN].getData(),
NULL,
nullptr,
BUTTON_FLAG_TRANSPARENT);
if (btn != -1) {
buttonSetCallbacks(btn, _gsound_red_butt_press, NULL);
buttonSetCallbacks(btn, _gsound_red_butt_press, nullptr);
}
y += 60;
}
@@ -650,11 +650,11 @@ void elevatorsInit()
{
char* elevatorsFileName;
configGetString(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_ELEVATORS_FILE_KEY, &elevatorsFileName);
if (elevatorsFileName != NULL && *elevatorsFileName == '\0') {
elevatorsFileName = NULL;
if (elevatorsFileName != nullptr && *elevatorsFileName == '\0') {
elevatorsFileName = nullptr;
}
if (elevatorsFileName != NULL) {
if (elevatorsFileName != nullptr) {
Config elevatorsConfig;
if (configInit(&elevatorsConfig)) {
if (configRead(&elevatorsConfig, elevatorsFileName, false)) {

View File

@@ -112,7 +112,7 @@ static int _endgame_maybe_done = 0;
// enddeath.txt
//
// 0x518678
static EndgameDeathEnding* gEndgameDeathEndings = NULL;
static EndgameDeathEnding* gEndgameDeathEndings = nullptr;
// The number of death endings in [gEndgameDeathEndings] array.
//
@@ -248,7 +248,7 @@ void endgamePlayMovie()
creditsOpen("credits.txt", -1, false);
backgroundSoundDelete();
backgroundSoundSetEndCallback(NULL);
backgroundSoundSetEndCallback(nullptr);
tickersRemove(_endgame_movie_bk_process);
backgroundSoundDelete();
colorPaletteLoad("color.pal");
@@ -286,7 +286,7 @@ static int endgameEndingHandleContinuePlaying()
MessageListItem messageListItem;
messageListItem.num = 30;
if (messageListGetItem(&gMiscMessageList, &messageListItem)) {
rc = showDialogBox(messageListItem.text, NULL, 0, 169, 117, _colorTable[32328], NULL, _colorTable[32328], DIALOG_BOX_YES_NO);
rc = showDialogBox(messageListItem.text, nullptr, 0, 169, 117, _colorTable[32328], nullptr, _colorTable[32328], DIALOG_BOX_YES_NO);
if (rc == 0) {
_game_user_wants_to_quit = 2;
}
@@ -317,7 +317,7 @@ static void endgameEndingRenderPanningScene(int direction, const char* narratorF
CacheEntry* backgroundHandle;
Art* background = artLock(fid, &backgroundHandle);
if (background != NULL) {
if (background != nullptr) {
int width = artGetWidth(background, 0, 0);
int height = artGetHeight(background, 0, 0);
unsigned char* backgroundData = artGetFrameData(background, 0, 0);
@@ -449,12 +449,12 @@ static void endgameEndingRenderStaticScene(int fid, const char* narratorFileName
{
CacheEntry* backgroundHandle;
Art* background = artLock(fid, &backgroundHandle);
if (background == NULL) {
if (background == nullptr) {
return;
}
unsigned char* backgroundData = artGetFrameData(background, 0, 0);
if (backgroundData != NULL) {
if (backgroundData != nullptr) {
blitBufferToBuffer(backgroundData, ENDGAME_ENDING_WINDOW_WIDTH, ENDGAME_ENDING_WINDOW_HEIGHT, ENDGAME_ENDING_WINDOW_WIDTH, gEndgameEndingSlideshowWindowBuffer, ENDGAME_ENDING_WINDOW_WIDTH);
windowRefresh(gEndgameEndingSlideshowWindow);
@@ -584,7 +584,7 @@ static int endgameEndingSlideshowWindowInit()
}
gEndgameEndingSlideshowWindowBuffer = windowGetBuffer(gEndgameEndingSlideshowWindow);
if (gEndgameEndingSlideshowWindowBuffer == NULL) {
if (gEndgameEndingSlideshowWindowBuffer == nullptr) {
return -1;
}
@@ -600,17 +600,17 @@ static int endgameEndingSlideshowWindowInit()
snprintf(gEndgameEndingSubtitlesLocalizedPath, sizeof(gEndgameEndingSubtitlesLocalizedPath), "text\\%s\\cuts\\", settings.system.language.c_str());
gEndgameEndingSubtitles = (char**)internal_malloc(sizeof(*gEndgameEndingSubtitles) * ENDGAME_ENDING_MAX_SUBTITLES);
if (gEndgameEndingSubtitles == NULL) {
if (gEndgameEndingSubtitles == nullptr) {
gEndgameEndingSubtitlesEnabled = false;
return 0;
}
for (int index = 0; index < ENDGAME_ENDING_MAX_SUBTITLES; index++) {
gEndgameEndingSubtitles[index] = NULL;
gEndgameEndingSubtitles[index] = nullptr;
}
gEndgameEndingSubtitlesTimings = (unsigned int*)internal_malloc(sizeof(*gEndgameEndingSubtitlesTimings) * ENDGAME_ENDING_MAX_SUBTITLES);
if (gEndgameEndingSubtitlesTimings == NULL) {
if (gEndgameEndingSubtitlesTimings == nullptr) {
internal_free(gEndgameEndingSubtitles);
gEndgameEndingSubtitlesEnabled = false;
return 0;
@@ -628,7 +628,7 @@ static void endgameEndingSlideshowWindowFree()
internal_free(gEndgameEndingSubtitlesTimings);
internal_free(gEndgameEndingSubtitles);
gEndgameEndingSubtitles = NULL;
gEndgameEndingSubtitles = nullptr;
gEndgameEndingSubtitlesEnabled = false;
}
@@ -637,7 +637,7 @@ static void endgameEndingSlideshowWindowFree()
fontSetCurrent(gEndgameEndingSlideshowOldFont);
speechSetEndCallback(NULL);
speechSetEndCallback(nullptr);
windowDestroy(gEndgameEndingSlideshowWindow);
windowDestroy(gEndgameEndingOverlay);
@@ -741,7 +741,7 @@ static void endgameEndingLoadPalette(int type, int id)
// Remove extension from file name.
char* pch = strrchr(fileName, '.');
if (pch != NULL) {
if (pch != nullptr) {
*pch = '\0';
}
@@ -766,7 +766,7 @@ static int endgameEndingSubtitlesLoad(const char* filePath)
endgameEndingSubtitlesFree();
File* stream = fileOpen(filePath, "rt");
if (stream == NULL) {
if (stream == nullptr) {
return -1;
}
@@ -778,14 +778,14 @@ static int endgameEndingSubtitlesLoad(const char* filePath)
// Find and clamp string at EOL.
pch = strchr(string, '\n');
if (pch != NULL) {
if (pch != nullptr) {
*pch = '\0';
}
// Find separator. The value before separator is ignored (as opposed to
// movie subtitles, where the value before separator is a timing).
pch = strchr(string, ':');
if (pch != NULL) {
if (pch != nullptr) {
if (gEndgameEndingSubtitlesLength < ENDGAME_ENDING_MAX_SUBTITLES) {
gEndgameEndingSubtitles[gEndgameEndingSubtitlesLength] = internal_strdup(pch + 1);
gEndgameEndingSubtitlesLength++;
@@ -817,7 +817,7 @@ static void endgameEndingRefreshSubtitles()
}
char* text = gEndgameEndingSubtitles[gEndgameEndingSubtitlesCurrentLine];
if (text == NULL) {
if (text == nullptr) {
return;
}
@@ -856,9 +856,9 @@ static void endgameEndingRefreshSubtitles()
static void endgameEndingSubtitlesFree()
{
for (int index = 0; index < gEndgameEndingSubtitlesLength; index++) {
if (gEndgameEndingSubtitles[index] != NULL) {
if (gEndgameEndingSubtitles[index] != nullptr) {
internal_free(gEndgameEndingSubtitles[index]);
gEndgameEndingSubtitles[index] = NULL;
gEndgameEndingSubtitles[index] = nullptr;
}
}
@@ -878,7 +878,7 @@ static void _endgame_movie_bk_process()
{
if (_endgame_maybe_done) {
backgroundSoundLoad("10labone", 11, 14, 16);
backgroundSoundSetEndCallback(NULL);
backgroundSoundSetEndCallback(nullptr);
tickersRemove(_endgame_movie_bk_process);
}
}
@@ -894,15 +894,15 @@ static int endgameEndingInit()
EndgameEnding* entries;
size_t narratorFileNameLength;
if (gEndgameEndings != NULL) {
if (gEndgameEndings != nullptr) {
internal_free(gEndgameEndings);
gEndgameEndings = NULL;
gEndgameEndings = nullptr;
}
gEndgameEndingsLength = 0;
stream = fileOpen("data\\endgame.txt", "rt");
if (stream == NULL) {
if (stream == nullptr) {
return -1;
}
@@ -917,28 +917,28 @@ static int endgameEndingInit()
}
tok = strtok(ch, delim);
if (tok == NULL) {
if (tok == nullptr) {
continue;
}
entry.gvar = atoi(tok);
tok = strtok(NULL, delim);
if (tok == NULL) {
tok = strtok(nullptr, delim);
if (tok == nullptr) {
continue;
}
entry.value = atoi(tok);
tok = strtok(NULL, delim);
if (tok == NULL) {
tok = strtok(nullptr, delim);
if (tok == nullptr) {
continue;
}
entry.art_num = atoi(tok);
tok = strtok(NULL, delim);
if (tok == NULL) {
tok = strtok(nullptr, delim);
if (tok == nullptr) {
continue;
}
@@ -949,15 +949,15 @@ static int endgameEndingInit()
entry.voiceOverBaseName[narratorFileNameLength - 1] = '\0';
}
tok = strtok(NULL, delim);
if (tok != NULL) {
tok = strtok(nullptr, delim);
if (tok != nullptr) {
entry.direction = atoi(tok);
} else {
entry.direction = 1;
}
entries = (EndgameEnding*)internal_realloc(gEndgameEndings, sizeof(*entries) * (gEndgameEndingsLength + 1));
if (entries == NULL) {
if (entries == nullptr) {
goto err;
}
@@ -983,9 +983,9 @@ err:
// 0x44095C
static void endgameEndingFree()
{
if (gEndgameEndings != NULL) {
if (gEndgameEndings != nullptr) {
internal_free(gEndgameEndings);
gEndgameEndings = NULL;
gEndgameEndings = nullptr;
}
gEndgameEndingsLength = 0;
@@ -1007,7 +1007,7 @@ int endgameDeathEndingInit()
strcpy(gEndgameDeathEndingFileName, "narrator\\nar_5");
stream = fileOpen("data\\enddeath.txt", "rt");
if (stream == NULL) {
if (stream == nullptr) {
return -1;
}
@@ -1022,49 +1022,49 @@ int endgameDeathEndingInit()
}
tok = strtok(ch, delim);
if (tok == NULL) {
if (tok == nullptr) {
continue;
}
entry.gvar = atoi(tok);
tok = strtok(NULL, delim);
if (tok == NULL) {
tok = strtok(nullptr, delim);
if (tok == nullptr) {
continue;
}
entry.value = atoi(tok);
tok = strtok(NULL, delim);
if (tok == NULL) {
tok = strtok(nullptr, delim);
if (tok == nullptr) {
continue;
}
entry.worldAreaKnown = atoi(tok);
tok = strtok(NULL, delim);
if (tok == NULL) {
tok = strtok(nullptr, delim);
if (tok == nullptr) {
continue;
}
entry.worldAreaNotKnown = atoi(tok);
tok = strtok(NULL, delim);
if (tok == NULL) {
tok = strtok(nullptr, delim);
if (tok == nullptr) {
continue;
}
entry.min_level = atoi(tok);
tok = strtok(NULL, delim);
if (tok == NULL) {
tok = strtok(nullptr, delim);
if (tok == nullptr) {
continue;
}
entry.percentage = atoi(tok);
tok = strtok(NULL, delim);
if (tok == NULL) {
tok = strtok(nullptr, delim);
if (tok == nullptr) {
continue;
}
@@ -1079,7 +1079,7 @@ int endgameDeathEndingInit()
}
entries = (EndgameDeathEnding*)internal_realloc(gEndgameDeathEndings, sizeof(*entries) * (gEndgameDeathEndingsLength + 1));
if (entries == NULL) {
if (entries == nullptr) {
goto err;
}
@@ -1103,9 +1103,9 @@ err:
// 0x440BA8
int endgameDeathEndingExit()
{
if (gEndgameDeathEndings != NULL) {
if (gEndgameDeathEndings != nullptr) {
internal_free(gEndgameDeathEndings);
gEndgameDeathEndings = NULL;
gEndgameDeathEndings = nullptr;
gEndgameDeathEndingsLength = 0;
}

View File

@@ -61,7 +61,7 @@ ExternalProcedure* externalProcedureFind(const char* identifier)
unsigned int v2 = v1;
ExternalProcedure* externalProcedure = &(gExternalProcedures[v1]);
if (externalProcedure->program != NULL) {
if (externalProcedure->program != nullptr) {
if (compat_stricmp(externalProcedure->name, identifier) == 0) {
return externalProcedure;
}
@@ -74,14 +74,14 @@ ExternalProcedure* externalProcedureFind(const char* identifier)
}
externalProcedure = &(gExternalProcedures[v1]);
if (externalProcedure->program != NULL) {
if (externalProcedure->program != nullptr) {
if (compat_stricmp(externalProcedure->name, identifier) == 0) {
return externalProcedure;
}
}
} while (v1 != v2);
return NULL;
return nullptr;
}
// 0x441018
@@ -108,7 +108,7 @@ ExternalProcedure* externalProcedureAdd(const char* identifier)
}
} while (v1 != a2);
return NULL;
return nullptr;
}
// 0x4410AC
@@ -140,7 +140,7 @@ ExternalVariable* externalVariableFind(const char* identifier)
}
} while (v1 != v2);
return NULL;
return nullptr;
}
// 0x44118C
@@ -167,14 +167,14 @@ ExternalVariable* externalVariableAdd(const char* identifier)
}
} while (v1 != v2);
return NULL;
return nullptr;
}
// 0x44127C
int externalVariableSetValue(Program* program, const char* name, ProgramValue& programValue)
{
ExternalVariable* exportedVariable = externalVariableFind(name);
if (exportedVariable == NULL) {
if (exportedVariable == nullptr) {
return 1;
}
@@ -183,7 +183,7 @@ int externalVariableSetValue(Program* program, const char* name, ProgramValue& p
}
if ((programValue.opcode & VALUE_TYPE_MASK) == VALUE_TYPE_STRING) {
if (program != NULL) {
if (program != nullptr) {
const char* stringValue = programGetString(program, programValue.opcode, programValue.integerValue);
exportedVariable->value.opcode = VALUE_TYPE_DYNAMIC_STRING;
@@ -201,7 +201,7 @@ int externalVariableSetValue(Program* program, const char* name, ProgramValue& p
int externalVariableGetValue(Program* program, const char* name, ProgramValue& value)
{
ExternalVariable* exportedVariable = externalVariableFind(name);
if (exportedVariable == NULL) {
if (exportedVariable == nullptr) {
return 1;
}
@@ -221,7 +221,7 @@ int externalVariableCreate(Program* program, const char* identifier)
const char* programName = program->name;
ExternalVariable* exportedVariable = externalVariableFind(identifier);
if (exportedVariable != NULL) {
if (exportedVariable != nullptr) {
if (compat_stricmp(exportedVariable->programName, programName) != 0) {
return 1;
}
@@ -231,7 +231,7 @@ int externalVariableCreate(Program* program, const char* identifier)
}
} else {
exportedVariable = externalVariableAdd(identifier);
if (exportedVariable == NULL) {
if (exportedVariable == nullptr) {
return 1;
}
@@ -254,7 +254,7 @@ void _removeProgramReferences(Program* program)
ExternalProcedure* externalProcedure = &(gExternalProcedures[index]);
if (externalProcedure->program == program) {
externalProcedure->name[0] = '\0';
externalProcedure->program = NULL;
externalProcedure->program = nullptr;
}
}
}
@@ -285,12 +285,12 @@ void externalVariablesClear()
Program* externalProcedureGetProgram(const char* identifier, int* addressPtr, int* argumentCountPtr)
{
ExternalProcedure* externalProcedure = externalProcedureFind(identifier);
if (externalProcedure == NULL) {
return NULL;
if (externalProcedure == nullptr) {
return nullptr;
}
if (externalProcedure->program == NULL) {
return NULL;
if (externalProcedure->program == nullptr) {
return nullptr;
}
*addressPtr = externalProcedure->address;
@@ -303,13 +303,13 @@ Program* externalProcedureGetProgram(const char* identifier, int* addressPtr, in
int externalProcedureCreate(Program* program, const char* identifier, int address, int argumentCount)
{
ExternalProcedure* externalProcedure = externalProcedureFind(identifier);
if (externalProcedure != NULL) {
if (externalProcedure != nullptr) {
if (program != externalProcedure->program) {
return 1;
}
} else {
externalProcedure = externalProcedureAdd(identifier);
if (externalProcedure == NULL) {
if (externalProcedure == nullptr) {
return 1;
}
@@ -330,14 +330,14 @@ void _exportClearAllVariables()
ExternalVariable* exportedVariable = &(gExternalVariables[index]);
if (exportedVariable->name[0] != '\0') {
if ((exportedVariable->value.opcode & VALUE_TYPE_MASK) == VALUE_TYPE_STRING) {
if (exportedVariable->stringValue != NULL) {
if (exportedVariable->stringValue != nullptr) {
internal_free_safe(exportedVariable->stringValue, __FILE__, __LINE__); // "..\\int\\EXPORT.C", 387
}
}
if (exportedVariable->programName != NULL) {
if (exportedVariable->programName != nullptr) {
internal_free_safe(exportedVariable->programName, __FILE__, __LINE__); // "..\\int\\EXPORT.C", 393
exportedVariable->programName = NULL;
exportedVariable->programName = nullptr;
}
exportedVariable->name[0] = '\0';

View File

@@ -16,33 +16,40 @@ bool fileFindFirst(const char* path, DirectoryFileFindData* findData)
return false;
}
#else
strcpy(findData->path, path);
char drive[COMPAT_MAX_DRIVE];
char dir[COMPAT_MAX_DIR];
compat_splitpath(path, drive, dir, NULL, NULL);
char fname[COMPAT_MAX_FNAME];
char ext[COMPAT_MAX_EXT];
compat_splitpath(path, drive, dir, fname, ext);
// Reassemble file name and extension to serve as a pattern. It has to be
// lowercased because underlying `fpattern` implementation uses lowercased
// char-by-char matching.
compat_makepath(findData->pattern, nullptr, nullptr, fname, ext);
compat_strlwr(findData->pattern);
char basePath[COMPAT_MAX_PATH];
compat_makepath(basePath, drive, dir, NULL, NULL);
compat_makepath(basePath, drive, dir, nullptr, nullptr);
findData->dir = opendir(basePath);
if (findData->dir == NULL) {
if (findData->dir == nullptr) {
return false;
}
findData->entry = readdir(findData->dir);
while (findData->entry != NULL) {
char entryPath[COMPAT_MAX_PATH];
compat_makepath(entryPath, drive, dir, fileFindGetName(findData), NULL);
if (fpattern_match(findData->path, entryPath)) {
while (findData->entry != nullptr) {
char entryName[COMPAT_MAX_FNAME];
strcpy(entryName, fileFindGetName(findData));
compat_strlwr(entryName);
if (fpattern_match(findData->pattern, entryName)) {
break;
}
findData->entry = readdir(findData->dir);
}
if (findData->entry == NULL) {
if (findData->entry == nullptr) {
closedir(findData->dir);
findData->dir = NULL;
findData->dir = nullptr;
return false;
}
#endif
@@ -58,23 +65,20 @@ bool fileFindNext(DirectoryFileFindData* findData)
return false;
}
#else
char drive[COMPAT_MAX_DRIVE];
char dir[COMPAT_MAX_DIR];
compat_splitpath(findData->path, drive, dir, NULL, NULL);
findData->entry = readdir(findData->dir);
while (findData->entry != NULL) {
char entryPath[COMPAT_MAX_PATH];
compat_makepath(entryPath, drive, dir, fileFindGetName(findData), NULL);
if (fpattern_match(findData->path, entryPath)) {
while (findData->entry != nullptr) {
char entryName[COMPAT_MAX_FNAME];
strcpy(entryName, fileFindGetName(findData));
compat_strlwr(entryName);
if (fpattern_match(findData->pattern, entryName)) {
break;
}
findData->entry = readdir(findData->dir);
}
if (findData->entry == NULL) {
if (findData->entry == nullptr) {
closedir(findData->dir);
findData->dir = NULL;
findData->dir = nullptr;
return false;
}
#endif
@@ -88,7 +92,7 @@ bool findFindClose(DirectoryFileFindData* findData)
#if defined(_MSC_VER)
FindClose(findData->hFind);
#else
if (findData->dir != NULL) {
if (findData->dir != nullptr) {
if (closedir(findData->dir) != 0) {
return false;
}

View File

@@ -2,8 +2,6 @@
#define FILE_FIND_H
#if defined(_WIN32)
#define WIN32_LEAN_AND_MEAN
#define NOMINMAX
#include <windows.h>
#else
#include <dirent.h>
@@ -39,7 +37,7 @@ typedef struct DirectoryFileFindData {
#else
DIR* dir;
struct dirent* entry;
char path[COMPAT_MAX_PATH];
char pattern[COMPAT_MAX_FNAME];
#endif
} DirectoryFileFindData;

View File

@@ -19,7 +19,7 @@ static void fileCopy(const char* existingFilePath, const char* newFilePath);
int fileCopyDecompressed(const char* existingFilePath, const char* newFilePath)
{
FILE* stream = compat_fopen(existingFilePath, "rb");
if (stream == NULL) {
if (stream == nullptr) {
return -1;
}
@@ -32,7 +32,7 @@ int fileCopyDecompressed(const char* existingFilePath, const char* newFilePath)
gzFile inStream = compat_gzopen(existingFilePath, "rb");
FILE* outStream = compat_fopen(newFilePath, "wb");
if (inStream != NULL && outStream != NULL) {
if (inStream != nullptr && outStream != nullptr) {
for (;;) {
int ch = gzgetc(inStream);
if (ch == -1) {
@@ -45,11 +45,11 @@ int fileCopyDecompressed(const char* existingFilePath, const char* newFilePath)
gzclose(inStream);
fclose(outStream);
} else {
if (inStream != NULL) {
if (inStream != nullptr) {
gzclose(inStream);
}
if (outStream != NULL) {
if (outStream != nullptr) {
fclose(outStream);
}
@@ -66,7 +66,7 @@ int fileCopyDecompressed(const char* existingFilePath, const char* newFilePath)
int fileCopyCompressed(const char* existingFilePath, const char* newFilePath)
{
FILE* inStream = compat_fopen(existingFilePath, "rb");
if (inStream == NULL) {
if (inStream == nullptr) {
return -1;
}
@@ -82,7 +82,7 @@ int fileCopyCompressed(const char* existingFilePath, const char* newFilePath)
fileCopy(existingFilePath, newFilePath);
} else {
gzFile outStream = compat_gzopen(newFilePath, "wb");
if (outStream == NULL) {
if (outStream == nullptr) {
fclose(inStream);
return -1;
}
@@ -108,7 +108,7 @@ int fileCopyCompressed(const char* existingFilePath, const char* newFilePath)
int _gzdecompress_file(const char* existingFilePath, const char* newFilePath)
{
FILE* stream = compat_fopen(existingFilePath, "rb");
if (stream == NULL) {
if (stream == nullptr) {
return -1;
}
@@ -120,12 +120,12 @@ int _gzdecompress_file(const char* existingFilePath, const char* newFilePath)
// TODO: Is it broken?
if (magic[0] != 0x1F || magic[1] != 0x8B) {
gzFile gzstream = compat_gzopen(existingFilePath, "rb");
if (gzstream == NULL) {
if (gzstream == nullptr) {
return -1;
}
stream = compat_fopen(newFilePath, "wb");
if (stream == NULL) {
if (stream == nullptr) {
gzclose(gzstream);
return -1;
}
@@ -150,17 +150,9 @@ int _gzdecompress_file(const char* existingFilePath, const char* newFilePath)
static void fileCopy(const char* existingFilePath, const char* newFilePath)
{
char nativeExistingFilePath[COMPAT_MAX_PATH];
strcpy(nativeExistingFilePath, existingFilePath);
compat_windows_path_to_native(nativeExistingFilePath);
char nativeNewFilePath[COMPAT_MAX_PATH];
strcpy(nativeNewFilePath, newFilePath);
compat_windows_path_to_native(nativeNewFilePath);
FILE* in = fopen(nativeExistingFilePath, "rb");
FILE* out = fopen(nativeNewFilePath, "wb");
if (in != NULL && out != NULL) {
FILE* in = compat_fopen(existingFilePath, "rb");
FILE* out = compat_fopen(newFilePath, "wb");
if (in != nullptr && out != nullptr) {
std::vector<unsigned char> buffer(0xFFFF);
size_t bytesRead;
@@ -179,11 +171,11 @@ static void fileCopy(const char* existingFilePath, const char* newFilePath)
}
}
if (in != NULL) {
if (in != nullptr) {
fclose(in);
}
if (out != NULL) {
if (out != nullptr) {
fclose(out);
}
}

View File

@@ -82,7 +82,7 @@ int interfaceFontsInit()
for (int font = 0; font < INTERFACE_FONT_MAX; font++) {
if (interfaceFontLoad(font) == -1) {
gInterfaceFontDescriptors[font].maxHeight = 0;
gInterfaceFontDescriptors[font].data = NULL;
gInterfaceFontDescriptors[font].data = nullptr;
} else {
++gInterfaceFontsLength;
@@ -107,7 +107,7 @@ int interfaceFontsInit()
void interfaceFontsExit()
{
for (int font = 0; font < INTERFACE_FONT_MAX; font++) {
if (gInterfaceFontDescriptors[font].data != NULL) {
if (gInterfaceFontDescriptors[font].data != nullptr) {
internal_free_safe(gInterfaceFontDescriptors[font].data, __FILE__, __LINE__); // FONTMGR.C, 124
}
}
@@ -122,7 +122,7 @@ static int interfaceFontLoad(int font_index)
snprintf(path, sizeof(path), "font%d.aaf", font_index);
File* stream = fileOpen(path, "rb");
if (stream == NULL) {
if (stream == nullptr) {
return -1;
}
@@ -189,7 +189,7 @@ static int interfaceFontLoad(int font_index)
int glyphDataSize = fileSize - 2060;
fontDescriptor->data = (unsigned char*)internal_malloc_safe(glyphDataSize, __FILE__, __LINE__); // FONTMGR.C, 259
if (fontDescriptor->data == NULL) {
if (fontDescriptor->data == nullptr) {
fileClose(stream);
return -1;
}
@@ -213,7 +213,7 @@ static void interfaceFontSetCurrentImpl(int font)
font -= 100;
if (gInterfaceFontDescriptors[font].data != NULL) {
if (gInterfaceFontDescriptors[font].data != nullptr) {
gCurrentInterfaceFont = font;
gCurrentInterfaceFontDescriptor = &(gInterfaceFontDescriptors[font]);
}

View File

@@ -3,12 +3,6 @@
#include <stdio.h>
#include <string.h>
#ifdef _WIN32
#include <io.h>
#else
#include <unistd.h> // access
#endif
#include "actions.h"
#include "animation.h"
#include "art.h"
@@ -50,13 +44,17 @@
#include "perk.h"
#include "pipboy.h"
#include "platform_compat.h"
#include "preferences.h"
#include "proto.h"
#include "queue.h"
#include "random.h"
#include "scripts.h"
#include "settings.h"
#include "sfall_arrays.h"
#include "sfall_config.h"
#include "sfall_global_scripts.h"
#include "sfall_global_vars.h"
#include "sfall_ini.h"
#include "sfall_lists.h"
#include "skill.h"
#include "skilldex.h"
@@ -67,6 +65,7 @@
#include "trait.h"
#include "version.h"
#include "window_manager.h"
#include "window_manager_private.h"
#include "worldmap.h"
namespace fallout {
@@ -101,7 +100,7 @@ static int gGameState = GAME_STATE_0;
static bool gIsMapper = false;
// 0x5186C0
int* gGameGlobalVars = NULL;
int* gGameGlobalVars = nullptr;
// 0x5186C4
int gGameGlobalVarsLength = 0;
@@ -117,6 +116,9 @@ int _game_user_wants_to_quit = 0;
// 0x58E940
MessageList gMiscMessageList;
// CE: Sonora folks like to store objects in global variables.
static void** gGameGlobalPointers = nullptr;
// 0x442580
int gameInitWithOptions(const char* windowTitle, bool isMapper, int font, int a4, int argc, char** argv)
{
@@ -167,12 +169,26 @@ int gameInitWithOptions(const char* windowTitle, bool isMapper, int font, int a4
showSplash();
}
// CE: Handle debug mode (exactly as seen in `mapper2.exe`).
const char* debugMode = settings.debug.mode.c_str();
if (compat_stricmp(debugMode, "environment") == 0) {
_debug_register_env();
} else if (compat_stricmp(debugMode, "screen") == 0) {
_debug_register_screen();
} else if (compat_stricmp(debugMode, "log") == 0) {
_debug_register_log("debug.log", "wt");
} else if (compat_stricmp(debugMode, "mono") == 0) {
_debug_register_mono();
} else if (compat_stricmp(debugMode, "gnw") == 0) {
_debug_register_func(_win_debug);
}
interfaceFontsInit();
fontManagerAdd(&gModernFontManager);
fontSetCurrent(font);
screenshotHandlerConfigure(KEY_F12, gameTakeScreenshot);
pauseHandlerConfigure(-1, NULL);
pauseHandlerConfigure(-1, nullptr);
tileDisable();
@@ -340,8 +356,8 @@ int gameInitWithOptions(const char* windowTitle, bool isMapper, int font, int a4
// SFALL
premadeCharactersInit();
if (!sfallGlobalVarsInit()) {
debugPrint("Failed on sfallGlobalVarsInit");
if (!sfall_gl_vars_init()) {
debugPrint("Failed on sfall_gl_vars_init");
return -1;
}
@@ -350,6 +366,20 @@ int gameInitWithOptions(const char* windowTitle, bool isMapper, int font, int a4
return -1;
}
if (!sfallArraysInit()) {
debugPrint("Failed on sfallArraysInit");
return -1;
}
if (!sfall_gl_scr_init()) {
debugPrint("Failed on sfall_gl_scr_init");
return -1;
}
char* customConfigBasePath;
configGetString(&gSfallConfig, SFALL_CONFIG_SCRIPTS_KEY, SFALL_CONFIG_INI_CONFIG_FOLDER, &customConfigBasePath);
sfall_ini_set_base_path(customConfigBasePath);
messageListRepositorySetStandardMessageList(STANDARD_MESSAGE_LIST_MISC, &gMiscMessageList);
return 0;
@@ -394,9 +424,11 @@ void gameReset()
_init_options_menu();
// SFALL
sfallGlobalVarsReset();
sfall_gl_vars_reset();
sfallListsReset();
messageListRepositoryReset();
sfallArraysReset();
sfall_gl_scr_reset();
}
// 0x442C34
@@ -405,8 +437,10 @@ void gameExit()
debugPrint("\nGame Exit\n");
// SFALL
sfall_gl_scr_exit();
sfallArraysExit();
sfallListsExit();
sfallGlobalVarsExit();
sfall_gl_vars_exit();
premadeCharactersExit();
tileDisable();
@@ -565,7 +599,7 @@ int gameHandleKey(int eventCode, bool isInCombatMode)
case KEY_LOWERCASE_A:
if (interfaceBarEnabled()) {
if (!isInCombatMode) {
_combat(NULL);
_combat(nullptr);
}
}
break;
@@ -627,7 +661,7 @@ int gameHandleKey(int eventCode, bool isInCombatMode)
MessageListItem messageListItem;
char title[128];
strcpy(title, getmsg(&gMiscMessageList, &messageListItem, 7));
showDialogBox(title, NULL, 0, 192, 116, _colorTable[32328], NULL, _colorTable[32328], 0);
showDialogBox(title, nullptr, 0, 192, 116, _colorTable[32328], nullptr, _colorTable[32328], 0);
} else {
soundPlayFile("ib1p1xx1");
pipboyOpen(PIPBOY_OPEN_INTENT_UNSPECIFIED);
@@ -695,7 +729,7 @@ int gameHandleKey(int eventCode, bool isInCombatMode)
MessageListItem messageListItem;
char title[128];
strcpy(title, getmsg(&gMiscMessageList, &messageListItem, 7));
showDialogBox(title, NULL, 0, 192, 116, _colorTable[32328], NULL, _colorTable[32328], 0);
showDialogBox(title, nullptr, 0, 192, 116, _colorTable[32328], nullptr, _colorTable[32328], 0);
} else {
soundPlayFile("ib1p1xx1");
pipboyOpen(PIPBOY_OPEN_INTENT_REST);
@@ -993,7 +1027,18 @@ int gameSetGlobalVar(int var, int value)
// 0x443CC8
static int gameLoadGlobalVars()
{
return globalVarsRead("data\\vault13.gam", "GAME_GLOBAL_VARS:", &gGameGlobalVarsLength, &gGameGlobalVars);
if (globalVarsRead("data\\vault13.gam", "GAME_GLOBAL_VARS:", &gGameGlobalVarsLength, &gGameGlobalVars) != 0) {
return -1;
}
gGameGlobalPointers = reinterpret_cast<void**>(internal_malloc(sizeof(*gGameGlobalPointers) * gGameGlobalVarsLength));
if (gGameGlobalPointers == nullptr) {
return -1;
}
memset(gGameGlobalPointers, 0, sizeof(*gGameGlobalPointers) * gGameGlobalVarsLength);
return 0;
}
// 0x443CE8
@@ -1002,18 +1047,18 @@ int globalVarsRead(const char* path, const char* section, int* variablesListLeng
_inven_reset_dude();
File* stream = fileOpen(path, "rt");
if (stream == NULL) {
if (stream == nullptr) {
return -1;
}
if (*variablesListLengthPtr != 0) {
internal_free(*variablesListPtr);
*variablesListPtr = NULL;
*variablesListPtr = nullptr;
*variablesListLengthPtr = 0;
}
char string[260];
if (section != NULL) {
if (section != nullptr) {
while (fileReadString(string, 258, stream)) {
if (strncmp(string, section, 16) == 0) {
break;
@@ -1031,19 +1076,19 @@ int globalVarsRead(const char* path, const char* section, int* variablesListLeng
}
char* semicolon = strchr(string, ';');
if (semicolon != NULL) {
if (semicolon != nullptr) {
*semicolon = '\0';
}
*variablesListLengthPtr = *variablesListLengthPtr + 1;
*variablesListPtr = (int*)internal_realloc(*variablesListPtr, sizeof(int) * *variablesListLengthPtr);
if (*variablesListPtr == NULL) {
if (*variablesListPtr == nullptr) {
exit(1);
}
char* equals = strchr(string, '=');
if (equals != NULL) {
if (equals != nullptr) {
sscanf(equals + 1, "%d", *variablesListPtr + *variablesListLengthPtr - 1);
} else {
*variablesListPtr[*variablesListLengthPtr - 1] = 0;
@@ -1130,9 +1175,14 @@ static int gameTakeScreenshot(int width, int height, unsigned char* buffer, unsi
static void gameFreeGlobalVars()
{
gGameGlobalVarsLength = 0;
if (gGameGlobalVars != NULL) {
if (gGameGlobalVars != nullptr) {
internal_free(gGameGlobalVars);
gGameGlobalVars = NULL;
gGameGlobalVars = nullptr;
}
if (gGameGlobalPointers != nullptr) {
internal_free(gGameGlobalPointers);
gGameGlobalPointers = nullptr;
}
}
@@ -1158,7 +1208,7 @@ static void showHelp()
int win = windowCreate(helpWindowX, helpWindowY, HELP_SCREEN_WIDTH, HELP_SCREEN_HEIGHT, 0, WINDOW_HIDDEN | WINDOW_MOVE_ON_TOP);
if (win != -1) {
unsigned char* windowBuffer = windowGetBuffer(win);
if (windowBuffer != NULL) {
if (windowBuffer != nullptr) {
FrmImage backgroundFrmImage;
int backgroundFid = buildFid(OBJ_TYPE_INTERFACE, 297, 0, 0, 0);
if (backgroundFrmImage.lock(backgroundFid)) {
@@ -1245,7 +1295,7 @@ int showQuitConfirmationDialog()
MessageListItem messageListItem;
messageListItem.num = 0;
if (messageListGetItem(&gMiscMessageList, &messageListItem)) {
rc = showDialogBox(messageListItem.text, 0, 0, 169, 117, _colorTable[32328], NULL, _colorTable[32328], DIALOG_BOX_YES_NO);
rc = showDialogBox(messageListItem.text, nullptr, 0, 169, 117, _colorTable[32328], nullptr, _colorTable[32328], DIALOG_BOX_YES_NO);
if (rc != 0) {
_game_user_wants_to_quit = 2;
}
@@ -1278,17 +1328,17 @@ static int gameDbInit()
int patch_index;
char filename[COMPAT_MAX_PATH];
main_file_name = NULL;
patch_file_name = NULL;
main_file_name = nullptr;
patch_file_name = nullptr;
main_file_name = settings.system.master_dat_path.c_str();
if (*main_file_name == '\0') {
main_file_name = NULL;
main_file_name = nullptr;
}
patch_file_name = settings.system.master_patches_path.c_str();
if (*patch_file_name == '\0') {
patch_file_name = NULL;
patch_file_name = nullptr;
}
int master_db_handle = dbOpen(main_file_name, 0, patch_file_name, 1);
@@ -1299,12 +1349,12 @@ static int gameDbInit()
main_file_name = settings.system.critter_dat_path.c_str();
if (*main_file_name == '\0') {
main_file_name = NULL;
main_file_name = nullptr;
}
patch_file_name = settings.system.critter_patches_path.c_str();
if (*patch_file_name == '\0') {
patch_file_name = NULL;
patch_file_name = nullptr;
}
int critter_db_handle = dbOpen(main_file_name, 0, patch_file_name, 1);
@@ -1313,14 +1363,25 @@ static int gameDbInit()
return -1;
}
for (patch_index = 0; patch_index < 1000; patch_index++) {
snprintf(filename, sizeof(filename), "patch%03d.dat", patch_index);
// SFALL: custom patch file name.
char* path_file_name_template = nullptr;
configGetString(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_PATCH_FILE, &path_file_name_template);
if (path_file_name_template == nullptr || *path_file_name_template == '\0') {
path_file_name_template = "patch%03d.dat";
}
if (access(filename, 0) == 0) {
dbOpen(filename, 0, NULL, 1);
for (patch_index = 0; patch_index < 1000; patch_index++) {
snprintf(filename, sizeof(filename), path_file_name_template, patch_index);
if (compat_access(filename, 0) == 0) {
dbOpen(filename, 0, nullptr, 1);
}
}
if (compat_access("f2_res.dat", 0) == 0) {
dbOpen("f2_res.dat", 0, nullptr, 1);
}
return 0;
}
@@ -1342,7 +1403,7 @@ static void showSplash()
char filePath[64];
snprintf(filePath, sizeof(filePath), "%ssplash%d.rix", path, splash);
stream = fileOpen(filePath, "rb");
if (stream != NULL) {
if (stream != nullptr) {
break;
}
@@ -1353,12 +1414,12 @@ static void showSplash()
}
}
if (stream == NULL) {
if (stream == nullptr) {
return;
}
unsigned char* palette = reinterpret_cast<unsigned char*>(internal_malloc(768));
if (palette == NULL) {
if (palette == nullptr) {
fileClose(stream);
return;
}
@@ -1377,7 +1438,7 @@ static void showSplash()
fileRead(&height, sizeof(height), 1, stream);
unsigned char* data = reinterpret_cast<unsigned char*>(internal_malloc(width * height));
if (data == NULL) {
if (data == nullptr) {
internal_free(palette);
fileClose(stream);
return;
@@ -1422,7 +1483,7 @@ static void showSplash()
}
unsigned char* scaled = reinterpret_cast<unsigned char*>(internal_malloc(scaledWidth * scaledHeight));
if (scaled != NULL) {
if (scaled != nullptr) {
blitBufferToBufferStretch(data, width, height, width, scaled, scaledWidth, scaledHeight, scaledWidth);
int x = screenWidth > scaledWidth ? (screenWidth - scaledWidth) / 2 : 0;
@@ -1471,7 +1532,7 @@ int gameShowDeathDialog(const char* message)
int oldUserWantsToQuit = _game_user_wants_to_quit;
_game_user_wants_to_quit = 0;
int rc = showDialogBox(message, 0, 0, 169, 117, _colorTable[32328], NULL, _colorTable[32328], DIALOG_BOX_LARGE);
int rc = showDialogBox(message, nullptr, 0, 169, 117, _colorTable[32328], nullptr, _colorTable[32328], DIALOG_BOX_LARGE);
_game_user_wants_to_quit = oldUserWantsToQuit;
@@ -1492,6 +1553,28 @@ int gameShowDeathDialog(const char* message)
return rc;
}
void* gameGetGlobalPointer(int var)
{
if (var < 0 || var >= gGameGlobalVarsLength) {
debugPrint("ERROR: attempt to reference global pointer out of range: %d", var);
return nullptr;
}
return gGameGlobalPointers[var];
}
int gameSetGlobalPointer(int var, void* value)
{
if (var < 0 || var >= gGameGlobalVarsLength) {
debugPrint("ERROR: attempt to reference global var out of range: %d", var);
return -1;
}
gGameGlobalPointers[var] = value;
return 0;
}
int GameMode::currentGameMode = 0;
void GameMode::enterGameMode(int gameMode)

View File

@@ -38,6 +38,8 @@ void gameUpdateState();
int showQuitConfirmationDialog();
int gameShowDeathDialog(const char* message);
void* gameGetGlobalPointer(int var);
int gameSetGlobalPointer(int var, void* value);
class GameMode {
public:

View File

@@ -1,13 +1,17 @@
#include "game_config.h"
#include "sfall_config.h"
#include <stdio.h>
#include <string.h>
#include "db.h"
#include "main.h"
#include "platform_compat.h"
namespace fallout {
static void gameConfigResolvePath(const char* section, const char* key);
// A flag indicating if [gGameConfig] was initialized.
//
// 0x5186D0
@@ -120,15 +124,55 @@ bool gameConfigInit(bool isMapper, int argc, char** argv)
configSetInt(&gGameConfig, GAME_CONFIG_MAPPER_KEY, GAME_CONFIG_SORT_SCRIPT_LIST_KEY, 0);
}
// CE: Detect alternative default music directory.
char alternativeMusicPath[COMPAT_MAX_PATH];
strcpy(alternativeMusicPath, "data\\sound\\music\\*.acm");
compat_windows_path_to_native(alternativeMusicPath);
compat_resolve_path(alternativeMusicPath);
char** acms;
int acmsLength = fileNameListInit(alternativeMusicPath, &acms, 0, 0);
if (acmsLength != -1) {
if (acmsLength > 0) {
configSetString(&gGameConfig, GAME_CONFIG_SOUND_KEY, GAME_CONFIG_MUSIC_PATH1_KEY, "data\\sound\\music\\");
configSetString(&gGameConfig, GAME_CONFIG_SOUND_KEY, GAME_CONFIG_MUSIC_PATH2_KEY, "data\\sound\\music\\");
}
fileNameListFree(&acms, 0);
}
// SFALL: Custom config file name.
char* customConfigFileName = nullptr;
configGetString(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_CONFIG_FILE, &customConfigFileName);
const char* configFileName = customConfigFileName != nullptr && *customConfigFileName != '\0'
? customConfigFileName
: DEFAULT_GAME_CONFIG_FILE_NAME;
// Make `fallout2.cfg` file path.
char* executable = argv[0];
char* ch = strrchr(executable, '\\');
if (ch != NULL) {
if (ch != nullptr) {
*ch = '\0';
snprintf(gGameConfigFilePath, sizeof(gGameConfigFilePath), "%s\\%s", executable, GAME_CONFIG_FILE_NAME);
if (isMapper) {
snprintf(gGameConfigFilePath,
sizeof(gGameConfigFilePath),
"%s\\%s",
executable,
MAPPER_CONFIG_FILE_NAME);
} else {
snprintf(gGameConfigFilePath,
sizeof(gGameConfigFilePath),
"%s\\%s",
executable,
configFileName);
}
*ch = '\\';
} else {
strcpy(gGameConfigFilePath, GAME_CONFIG_FILE_NAME);
if (isMapper) {
strcpy(gGameConfigFilePath, MAPPER_CONFIG_FILE_NAME);
} else {
strcpy(gGameConfigFilePath, configFileName);
}
}
// Read contents of `fallout2.cfg` into config. The values from the file
@@ -139,6 +183,15 @@ bool gameConfigInit(bool isMapper, int argc, char** argv)
// whatever was loaded from `fallout2.cfg`.
configParseCommandLineArguments(&gGameConfig, argc, argv);
// CE: Normalize and resolve asset bundle paths.
gameConfigResolvePath(GAME_CONFIG_SYSTEM_KEY, GAME_CONFIG_MASTER_DAT_KEY);
gameConfigResolvePath(GAME_CONFIG_SYSTEM_KEY, GAME_CONFIG_MASTER_PATCHES_KEY);
gameConfigResolvePath(GAME_CONFIG_SYSTEM_KEY, GAME_CONFIG_CRITTER_DAT_KEY);
gameConfigResolvePath(GAME_CONFIG_SYSTEM_KEY, GAME_CONFIG_CRITTER_PATCHES_KEY);
gameConfigResolvePath(GAME_CONFIG_SYSTEM_KEY, GAME_CONFIG_CRITTER_PATCHES_KEY);
gameConfigResolvePath(GAME_CONFIG_SOUND_KEY, GAME_CONFIG_MUSIC_PATH1_KEY);
gameConfigResolvePath(GAME_CONFIG_SOUND_KEY, GAME_CONFIG_MUSIC_PATH2_KEY);
gGameConfigInitialized = true;
return true;
@@ -184,4 +237,12 @@ bool gameConfigExit(bool shouldSave)
return result;
}
static void gameConfigResolvePath(const char* section, const char* key)
{
char* path;
configGetString(&gGameConfig, section, key, &path);
compat_windows_path_to_native(path);
compat_resolve_path(path);
}
} // namespace fallout

View File

@@ -5,8 +5,8 @@
namespace fallout {
// The file name of the main config file.
#define GAME_CONFIG_FILE_NAME "fallout2.cfg"
#define DEFAULT_GAME_CONFIG_FILE_NAME "fallout2.cfg"
#define MAPPER_CONFIG_FILE_NAME "mapper2.cfg"
#define GAME_CONFIG_SYSTEM_KEY "system"
#define GAME_CONFIG_PREFERENCES_KEY "preferences"

View File

@@ -13,6 +13,7 @@
#include "critter.h"
#include "cycle.h"
#include "debug.h"
#include "delay.h"
#include "dialog.h"
#include "display_monitor.h"
#include "draw.h"
@@ -154,7 +155,7 @@ static int gGameDialogOptionEntriesLength = 0;
static int gGameDialogReviewEntriesLength = 0;
// 0x5186E0
static unsigned char* gGameDialogDisplayBuffer = NULL;
static unsigned char* gGameDialogDisplayBuffer = nullptr;
// 0x5186E4
static int gGameDialogReplyWindow = -1;
@@ -172,10 +173,10 @@ static int _boxesWereDisabled = 0;
static int gGameDialogFidgetFid = 0;
// 0x5186F8
static CacheEntry* gGameDialogFidgetFrmHandle = NULL;
static CacheEntry* gGameDialogFidgetFrmHandle = nullptr;
// 0x5186FC
static Art* gGameDialogFidgetFrm = NULL;
static Art* gGameDialogFidgetFrm = nullptr;
// 0x518700
static int gGameDialogBackground = 2;
@@ -184,10 +185,10 @@ static int gGameDialogBackground = 2;
static int _lipsFID = 0;
// 0x518708
static CacheEntry* _lipsKey = NULL;
static CacheEntry* _lipsKey = nullptr;
// 0x51870C
static Art* _lipsFp = NULL;
static Art* _lipsFp = nullptr;
// 0x518710
static bool gGameDialogLipSyncStarted = false;
@@ -214,13 +215,13 @@ static int _gdReenterLevel = 0;
static bool _gdReplyTooBig = false;
// 0x518730
static Object* _peon_table_obj = NULL;
static Object* _peon_table_obj = nullptr;
// 0x518734
static Object* _barterer_table_obj = NULL;
static Object* _barterer_table_obj = nullptr;
// 0x518738
static Object* _barterer_temp_obj = NULL;
static Object* _barterer_temp_obj = nullptr;
// 0x51873C
static int gGameDialogBarterModifier = 0;
@@ -266,10 +267,10 @@ static int gGameDialogOldCenterTile = -1;
static int gGameDialogOldDudeTile = -1;
// 0x5187E4
static unsigned char* _light_BlendTable = NULL;
static unsigned char* _light_BlendTable = nullptr;
// 0x5187E8
static unsigned char* _dark_BlendTable = NULL;
static unsigned char* _dark_BlendTable = nullptr;
// 0x5187EC
static int _dialogue_just_started = 0;
@@ -302,7 +303,7 @@ static int gGameDialogReviewWindowButtonFrmIds[GAME_DIALOG_REVIEW_WINDOW_BUTTON_
};
// 0x518848
Object* gGameDialogSpeaker = NULL;
Object* gGameDialogSpeaker = nullptr;
// 0x51884C
bool gGameDialogSpeakerIsPartyMember = false;
@@ -382,11 +383,11 @@ static int _dialogue_subwin_len = 0;
// 0x51891C
static GameDialogButtonData gGameDialogDispositionButtonsData[5] = {
{ 438, 37, 397, 395, 396, NULL, NULL, NULL, 2098, 4 },
{ 438, 67, 394, 392, 393, NULL, NULL, NULL, 2103, 3 },
{ 438, 96, 406, 404, 405, NULL, NULL, NULL, 2102, 2 },
{ 438, 126, 400, 398, 399, NULL, NULL, NULL, 2111, 1 },
{ 438, 156, 403, 401, 402, NULL, NULL, NULL, 2099, 0 },
{ 438, 37, 397, 395, 396, nullptr, nullptr, nullptr, 2098, 4 },
{ 438, 67, 394, 392, 393, nullptr, nullptr, nullptr, 2103, 3 },
{ 438, 96, 406, 404, 405, nullptr, nullptr, nullptr, 2102, 2 },
{ 438, 126, 400, 398, 399, nullptr, nullptr, nullptr, 2111, 1 },
{ 438, 156, 403, 401, 402, nullptr, nullptr, nullptr, 2099, 0 },
};
// 0x5189E4
@@ -443,12 +444,12 @@ static STRUCT_5189E4 _custom_settings[PARTY_MEMBER_CUSTOMIZATION_OPTION_COUNT][6
// 0x518B04
static GameDialogButtonData _custom_button_info[PARTY_MEMBER_CUSTOMIZATION_OPTION_COUNT] = {
{ 95, 9, 410, 409, -1, NULL, NULL, NULL, 0, 0 },
{ 96, 38, 416, 415, -1, NULL, NULL, NULL, 1, 0 },
{ 96, 68, 418, 417, -1, NULL, NULL, NULL, 2, 0 },
{ 96, 98, 414, 413, -1, NULL, NULL, NULL, 3, 0 },
{ 96, 127, 408, 407, -1, NULL, NULL, NULL, 4, 0 },
{ 96, 157, 412, 411, -1, NULL, NULL, NULL, 5, 0 },
{ 95, 9, 410, 409, -1, nullptr, nullptr, nullptr, 0, 0 },
{ 96, 38, 416, 415, -1, nullptr, nullptr, nullptr, 1, 0 },
{ 96, 68, 418, 417, -1, nullptr, nullptr, nullptr, 2, 0 },
{ 96, 98, 414, 413, -1, nullptr, nullptr, nullptr, 3, 0 },
{ 96, 127, 408, 407, -1, nullptr, nullptr, nullptr, 4, 0 },
{ 96, 157, 412, 411, -1, nullptr, nullptr, nullptr, 5, 0 },
};
// 0x518BF4
@@ -668,7 +669,7 @@ bool _gdialogActive()
// 0x444D3C
void gameDialogEnter(Object* speaker, int a2)
{
if (speaker == NULL) {
if (speaker == nullptr) {
debugPrint("\nError: gdialogEnter: target was NULL!");
return;
}
@@ -823,7 +824,7 @@ void _gdialogSystemEnter()
// 0x445050
void gameDialogStartLips(const char* audioFileName)
{
if (audioFileName == NULL) {
if (audioFileName == nullptr) {
debugPrint("\nGDialog: Bleep!");
soundPlayFile("censor");
return;
@@ -887,11 +888,11 @@ int _gdialogInitFromScript(int headFid, int reaction)
gGameDialogSpeakerIsPartyMember = objectIsPartyMember(gGameDialogSpeaker);
_oldFont = fontGetCurrent();
fontSetCurrent(101);
dialogSetReplyWindow(135, 225, 379, 58, NULL);
dialogSetReplyWindow(135, 225, 379, 58, nullptr);
dialogSetReplyColor(0.3f, 0.3f, 0.3f);
dialogSetOptionWindow(127, 335, 393, 117, NULL);
dialogSetOptionWindow(127, 335, 393, 117, nullptr);
dialogSetOptionColor(0.2f, 0.2f, 0.2f);
dialogSetReplyTitle(NULL);
dialogSetReplyTitle(nullptr);
_dialogRegisterWinDrawCallbacks(_demo_copy_title, _demo_copy_options);
gameDialogHighlightsInit();
colorCycleDisable();
@@ -965,17 +966,17 @@ int _gdialogExitFromScript()
fontSetCurrent(_oldFont);
if (gGameDialogFidgetFrm != NULL) {
if (gGameDialogFidgetFrm != nullptr) {
artUnlock(gGameDialogFidgetFrmHandle);
gGameDialogFidgetFrm = NULL;
gGameDialogFidgetFrm = nullptr;
}
if (_lipsKey != NULL) {
if (_lipsKey != nullptr) {
if (artUnlock(_lipsKey) == -1) {
debugPrint("Failure unlocking lips frame!\n");
}
_lipsKey = NULL;
_lipsFp = NULL;
_lipsKey = nullptr;
_lipsFp = nullptr;
_lipsFID = 0;
}
@@ -1303,7 +1304,7 @@ int gameDialogReviewWindowInit(int* win)
gGameDialogReviewWindowOldFont = fontGetCurrent();
if (win == NULL) {
if (win == nullptr) {
return -1;
}
@@ -1361,7 +1362,7 @@ int gameDialogReviewWindowInit(int* win)
KEY_ARROW_UP,
_reviewFrmImages[GAME_DIALOG_REVIEW_WINDOW_BUTTON_FRM_ARROW_UP_NORMAL].getData(),
_reviewFrmImages[GAME_DIALOG_REVIEW_WINDOW_BUTTON_FRM_ARROW_UP_PRESSED].getData(),
NULL,
nullptr,
BUTTON_FLAG_TRANSPARENT);
if (upBtn == -1) {
gameDialogReviewWindowFree(win);
@@ -1381,7 +1382,7 @@ int gameDialogReviewWindowInit(int* win)
KEY_ARROW_DOWN,
_reviewFrmImages[GAME_DIALOG_REVIEW_WINDOW_BUTTON_FRM_ARROW_DOWN_NORMAL].getData(),
_reviewFrmImages[GAME_DIALOG_REVIEW_WINDOW_BUTTON_FRM_ARROW_DOWN_PRESSED].getData(),
NULL,
nullptr,
BUTTON_FLAG_TRANSPARENT);
if (downBtn == -1) {
gameDialogReviewWindowFree(win);
@@ -1401,7 +1402,7 @@ int gameDialogReviewWindowInit(int* win)
KEY_ESCAPE,
_reviewFrmImages[GAME_DIALOG_REVIEW_WINDOW_BUTTON_FRM_DONE_NORMAL].getData(),
_reviewFrmImages[GAME_DIALOG_REVIEW_WINDOW_BUTTON_FRM_DONE_PRESSED].getData(),
NULL,
nullptr,
BUTTON_FLAG_TRANSPARENT);
if (doneBtn == -1) {
gameDialogReviewWindowFree(win);
@@ -1438,7 +1439,7 @@ int gameDialogReviewWindowFree(int* win)
fontSetCurrent(gGameDialogReviewWindowOldFont);
if (win == NULL) {
if (win == nullptr) {
return -1;
}
@@ -1521,7 +1522,7 @@ void gameDialogReviewWindowUpdate(int win, int origin)
int v20 = fontGetLineHeight() + 2;
unsigned char* windowBuffer = windowGetBuffer(win);
if (windowBuffer == NULL) {
if (windowBuffer == nullptr) {
debugPrint("\nError: gdialog: review: can't find buffer!");
return;
}
@@ -1551,7 +1552,7 @@ void gameDialogReviewWindowUpdate(int win, int origin)
replyText = _scr_get_msg_str(dialogReviewEntry->replyMessageListId, dialogReviewEntry->replyMessageId);
}
if (replyText == NULL) {
if (replyText == nullptr) {
showMesageBox("\nGDialog::Error Grabbing text message!");
exit(1);
}
@@ -1560,7 +1561,7 @@ void gameDialogReviewWindowUpdate(int win, int origin)
y = text_to_rect_wrapped(windowBuffer + 113,
&entriesRect,
replyText,
NULL,
nullptr,
fontGetLineHeight(),
640,
_colorTable[768] | 0x2000000);
@@ -1584,7 +1585,7 @@ void gameDialogReviewWindowUpdate(int win, int origin)
optionText = _scr_get_msg_str(dialogReviewEntry->optionMessageListId, dialogReviewEntry->optionMessageId);
}
if (optionText == NULL) {
if (optionText == nullptr) {
showMesageBox("\nGDialog::Error Grabbing text message!");
exit(1);
}
@@ -1593,7 +1594,7 @@ void gameDialogReviewWindowUpdate(int win, int origin)
y = text_to_rect_wrapped(windowBuffer + 113,
&entriesRect,
optionText,
NULL,
nullptr,
fontGetLineHeight(),
640,
_colorTable[15855] | 0x2000000);
@@ -1619,9 +1620,9 @@ void dialogReviewEntriesClear()
entry->replyMessageListId = 0;
entry->replyMessageId = 0;
if (entry->replyText != NULL) {
if (entry->replyText != nullptr) {
internal_free(entry->replyText);
entry->replyText = NULL;
entry->replyText = nullptr;
}
entry->optionMessageListId = 0;
@@ -1665,9 +1666,9 @@ int gameDialogAddReviewText(const char* string)
entry->replyMessageListId = -4;
entry->replyMessageId = -4;
if (entry->replyText != NULL) {
if (entry->replyText != nullptr) {
internal_free(entry->replyText);
entry->replyText = NULL;
entry->replyText = nullptr;
}
entry->replyText = (char*)internal_malloc(strlen(string) + 1);
@@ -1675,7 +1676,7 @@ int gameDialogAddReviewText(const char* string)
entry->optionMessageListId = -3;
entry->optionMessageId = -3;
entry->optionText = NULL;
entry->optionText = nullptr;
gGameDialogReviewEntriesLength++;
@@ -1693,7 +1694,7 @@ int gameDialogSetReviewOptionMessage(int messageListId, int messageId)
GameDialogReviewEntry* entry = &(gDialogReviewEntries[gGameDialogReviewEntriesLength - 1]);
entry->optionMessageListId = messageListId;
entry->optionMessageId = messageId;
entry->optionText = NULL;
entry->optionText = nullptr;
return 0;
}
@@ -1739,22 +1740,22 @@ int _gdProcessInit()
}
// Top part of the reply window - scroll up.
upBtn = buttonCreate(gGameDialogReplyWindow, 1, 1, 377, 28, -1, -1, KEY_ARROW_UP, -1, NULL, NULL, NULL, 32);
upBtn = buttonCreate(gGameDialogReplyWindow, 1, 1, 377, 28, -1, -1, KEY_ARROW_UP, -1, nullptr, nullptr, nullptr, 32);
if (upBtn == -1) {
goto err_1;
}
buttonSetCallbacks(upBtn, _gsound_red_butt_press, _gsound_red_butt_release);
buttonSetMouseCallbacks(upBtn, _reply_arrow_up, _reply_arrow_restore, 0, 0);
buttonSetMouseCallbacks(upBtn, _reply_arrow_up, _reply_arrow_restore, nullptr, nullptr);
// Bottom part of the reply window - scroll down.
downBtn = buttonCreate(gGameDialogReplyWindow, 1, 29, 377, 28, -1, -1, KEY_ARROW_DOWN, -1, NULL, NULL, NULL, 32);
downBtn = buttonCreate(gGameDialogReplyWindow, 1, 29, 377, 28, -1, -1, KEY_ARROW_DOWN, -1, nullptr, nullptr, nullptr, 32);
if (downBtn == -1) {
goto err_1;
}
buttonSetCallbacks(downBtn, _gsound_red_butt_press, _gsound_red_butt_release);
buttonSetMouseCallbacks(downBtn, _reply_arrow_down, _reply_arrow_restore, 0, 0);
buttonSetMouseCallbacks(downBtn, _reply_arrow_down, _reply_arrow_restore, nullptr, nullptr);
optionsWindowX = (screenGetWidth() - GAME_DIALOG_WINDOW_WIDTH) / 2 + GAME_DIALOG_OPTIONS_WINDOW_X;
optionsWindowY = (screenGetHeight() - GAME_DIALOG_WINDOW_HEIGHT) / 2 + GAME_DIALOG_OPTIONS_WINDOW_Y;
@@ -2132,7 +2133,7 @@ void gameDialogOptionOnMouseEnter(int index)
text_to_rect_wrapped(windowGetBuffer(gGameDialogOptionsWindow),
&_optionRect,
dialogOptionEntry->text,
NULL,
nullptr,
fontGetLineHeight(),
393,
color);
@@ -2180,7 +2181,7 @@ void gameDialogOptionOnMouseExit(int index)
text_to_rect_wrapped(windowGetBuffer(gGameDialogOptionsWindow),
&_optionRect,
dialogOptionEntry->text,
NULL,
nullptr,
fontGetLineHeight(),
393,
color);
@@ -2233,7 +2234,7 @@ void _gdProcessUpdate()
if (gDialogReplyMessageListId > 0) {
char* s = _scr_get_msg_str_speech(gDialogReplyMessageListId, gDialogReplyMessageId, 1);
if (s == NULL) {
if (s == nullptr) {
showMesageBox("\n'GDialog::Error Grabbing text message!");
exit(1);
}
@@ -2276,7 +2277,7 @@ void _gdProcessUpdate()
if (dialogOptionEntry->messageListId >= 0) {
char* text = _scr_get_msg_str_speech(dialogOptionEntry->messageListId, dialogOptionEntry->messageId, 0);
if (text == NULL) {
if (text == nullptr) {
showMesageBox("\nGDialog::Error Grabbing text message!");
exit(1);
}
@@ -2344,14 +2345,14 @@ void _gdProcessUpdate()
text_to_rect_wrapped(windowGetBuffer(gGameDialogOptionsWindow),
&_optionRect,
dialogOptionEntry->text,
NULL,
nullptr,
fontGetLineHeight(),
393,
color);
_optionRect.top += 2;
dialogOptionEntry->btn = buttonCreate(gGameDialogOptionsWindow, 2, y, width, _optionRect.top - y - 4, 1200 + index, 1300 + index, -1, 49 + index, NULL, NULL, NULL, 0);
dialogOptionEntry->btn = buttonCreate(gGameDialogOptionsWindow, 2, y, width, _optionRect.top - y - 4, 1200 + index, 1300 + index, -1, 49 + index, nullptr, nullptr, nullptr, 0);
if (dialogOptionEntry->btn != -1) {
buttonSetCallbacks(dialogOptionEntry->btn, _gsound_red_butt_press, _gsound_red_butt_release);
} else {
@@ -2391,7 +2392,7 @@ int _gdCreateHeadWindow()
int width = rect->right - rect->left;
int height = rect->bottom - rect->top;
_backgrndBufs[index] = (unsigned char*)internal_malloc(width * height);
if (_backgrndBufs[index] == NULL) {
if (_backgrndBufs[index] == nullptr) {
return -1;
}
@@ -2418,7 +2419,7 @@ int _gdCreateHeadWindow()
void _gdDestroyHeadWindow()
{
if (gGameDialogWindow != -1) {
gGameDialogDisplayBuffer = NULL;
gGameDialogDisplayBuffer = nullptr;
}
if (_dialogue_state == 1) {
@@ -2444,15 +2445,15 @@ void _gdSetupFidget(int headFrmId, int reaction)
if (headFrmId == -1) {
gGameDialogFidgetFid = -1;
gGameDialogFidgetFrm = NULL;
gGameDialogFidgetFrm = nullptr;
gGameDialogFidgetFrmHandle = INVALID_CACHE_ENTRY;
gGameDialogFidgetReaction = -1;
gGameDialogFidgetUpdateDelay = 0;
gGameDialogFidgetLastUpdateTimestamp = 0;
gameDialogRenderTalkingHead(NULL, 0);
gameDialogRenderTalkingHead(nullptr, 0);
_lipsFID = 0;
_lipsKey = NULL;
_lipsFp = 0;
_lipsKey = nullptr;
_lipsFp = nullptr;
return;
}
@@ -2471,8 +2472,8 @@ void _gdSetupFidget(int headFrmId, int reaction)
if (artUnlock(_lipsKey) == -1) {
debugPrint("failure unlocking lips frame!\n");
}
_lipsKey = NULL;
_lipsFp = NULL;
_lipsKey = nullptr;
_lipsFp = nullptr;
_lipsFID = 0;
}
}
@@ -2481,7 +2482,7 @@ void _gdSetupFidget(int headFrmId, int reaction)
_phone_anim = anim;
_lipsFID = buildFid(OBJ_TYPE_HEAD, headFrmId, anim, 0, 0);
_lipsFp = artLock(_lipsFID, &_lipsKey);
if (_lipsFp == NULL) {
if (_lipsFp == nullptr) {
debugPrint("failure!\n");
char stats[200];
@@ -2525,7 +2526,7 @@ void _gdSetupFidget(int headFrmId, int reaction)
debugPrint("Choosing fidget %d out of %d\n", fidget, fidgetCount);
if (gGameDialogFidgetFrm != NULL) {
if (gGameDialogFidgetFrm != nullptr) {
if (artUnlock(gGameDialogFidgetFrmHandle) == -1) {
debugPrint("failure!\n");
}
@@ -2534,7 +2535,7 @@ void _gdSetupFidget(int headFrmId, int reaction)
gGameDialogFidgetFid = buildFid(OBJ_TYPE_HEAD, headFrmId, reaction, fidget, 0);
gGameDialogFidgetFrmCurrentFrame = 0;
gGameDialogFidgetFrm = artLock(gGameDialogFidgetFid, &gGameDialogFidgetFrmHandle);
if (gGameDialogFidgetFrm == NULL) {
if (gGameDialogFidgetFrm == nullptr) {
debugPrint("failure!\n");
char stats[200];
@@ -2550,7 +2551,7 @@ void _gdSetupFidget(int headFrmId, int reaction)
// 0x447598
void gameDialogWaitForFidgetToComplete()
{
if (gGameDialogFidgetFrm == NULL) {
if (gGameDialogFidgetFrm == nullptr) {
return;
}
@@ -2579,7 +2580,7 @@ void gameDialogWaitForFidgetToComplete()
// 0x447614
void _gdPlayTransition(int anim)
{
if (gGameDialogFidgetFrm == NULL) {
if (gGameDialogFidgetFrm == nullptr) {
return;
}
@@ -2593,17 +2594,17 @@ void _gdPlayTransition(int anim)
gameDialogWaitForFidgetToComplete();
if (gGameDialogFidgetFrm != NULL) {
if (gGameDialogFidgetFrm != nullptr) {
if (artUnlock(gGameDialogFidgetFrmHandle) == -1) {
debugPrint("\tError unlocking fidget in transition func...");
}
gGameDialogFidgetFrm = NULL;
gGameDialogFidgetFrm = nullptr;
}
CacheEntry* headFrmHandle;
int headFid = buildFid(OBJ_TYPE_HEAD, gGameDialogHeadFid, anim, 0, 0);
Art* headFrm = artLock(headFid, &headFrmHandle);
if (headFrm == NULL) {
if (headFrm == nullptr) {
debugPrint("\tError locking transition...\n");
}
@@ -2612,11 +2613,16 @@ void _gdPlayTransition(int anim)
int frame = 0;
unsigned int time = 0;
while (frame < artGetFrameCount(headFrm)) {
sharedFpsLimiter.mark();
if (getTicksSince(time) >= delay) {
gameDialogRenderTalkingHead(headFrm, frame);
time = getTicks();
frame++;
}
renderPresent();
sharedFpsLimiter.throttle();
}
if (artUnlock(headFrmHandle) == -1) {
@@ -2678,7 +2684,7 @@ void _demo_copy_title(int win)
}
unsigned char* src = windowGetBuffer(gGameDialogBackgroundWindow);
if (src == NULL) {
if (src == nullptr) {
debugPrint("\nError: demo_copy_title: couldn't get buffer!");
return;
}
@@ -2722,7 +2728,7 @@ void _demo_copy_options(int win)
windowRect.top -= (screenGetHeight() - GAME_DIALOG_WINDOW_HEIGHT) / 2;
unsigned char* src = windowGetBuffer(gGameDialogWindow);
if (src == NULL) {
if (src == nullptr) {
debugPrint("\nError: demo_copy_options: couldn't get buffer!");
return;
}
@@ -2735,7 +2741,7 @@ void _demo_copy_options(int win)
// 0x447914
void _gDialogRefreshOptionsRect(int win, Rect* drawRect)
{
if (drawRect == NULL) {
if (drawRect == nullptr) {
debugPrint("\nError: gDialogRefreshOptionsRect: drawRect NULL!");
return;
}
@@ -2756,7 +2762,7 @@ void _gDialogRefreshOptionsRect(int win, Rect* drawRect)
windowRect.top -= (screenGetHeight() - GAME_DIALOG_WINDOW_HEIGHT) / 2;
unsigned char* src = windowGetBuffer(gGameDialogWindow);
if (src == NULL) {
if (src == nullptr) {
debugPrint("\nError: gDialogRefreshOptionsRect: couldn't get buffer!");
return;
}
@@ -2826,7 +2832,7 @@ void gameDialogTicker()
break;
}
if (gGameDialogFidgetFrm == NULL) {
if (gGameDialogFidgetFrm == nullptr) {
return;
}
@@ -2931,7 +2937,6 @@ void _gdialog_scroll_subwin(int win, int a2, unsigned char* a3, unsigned char* a
int v7;
unsigned char* v9;
Rect rect;
unsigned int tick;
v7 = a6;
v9 = a4;
@@ -2966,9 +2971,7 @@ void _gdialog_scroll_subwin(int win, int a2, unsigned char* a3, unsigned char* a
v7 += 10;
v9 -= 10 * (GAME_DIALOG_WINDOW_WIDTH);
tick = getTicks();
while (getTicksSince(tick) < 33) {
}
delay_ms(33);
renderPresent();
sharedFpsLimiter.throttle();
@@ -3006,9 +3009,7 @@ void _gdialog_scroll_subwin(int win, int a2, unsigned char* a3, unsigned char* a
rect.top += 10;
tick = getTicks();
while (getTicksSince(tick) < 33) {
}
delay_ms(33);
renderPresent();
sharedFpsLimiter.throttle();
@@ -3043,15 +3044,15 @@ static int text_to_rect_wrapped(unsigned char* buffer, Rect* rect, char* string,
int gameDialogDrawText(unsigned char* buffer, Rect* rect, char* string, int* a4, int height, int pitch, int color, int a7)
{
char* start;
if (a4 != NULL) {
if (a4 != nullptr) {
start = string + *a4;
} else {
start = string;
}
int maxWidth = rect->right - rect->left;
char* end = NULL;
while (start != NULL && *start != '\0') {
char* end = nullptr;
while (start != nullptr && *start != '\0') {
if (fontGetStringWidth(start) > maxWidth) {
end = start + 1;
while (*end != '\0' && *end != ' ') {
@@ -3060,18 +3061,18 @@ int gameDialogDrawText(unsigned char* buffer, Rect* rect, char* string, int* a4,
if (*end != '\0') {
char* lookahead = end + 1;
while (lookahead != NULL) {
while (lookahead != nullptr) {
while (*lookahead != '\0' && *lookahead != ' ') {
lookahead++;
}
if (*lookahead == '\0') {
lookahead = NULL;
lookahead = nullptr;
} else {
*lookahead = '\0';
if (fontGetStringWidth(start) >= maxWidth) {
*lookahead = ' ';
lookahead = NULL;
lookahead = nullptr;
} else {
end = lookahead;
*lookahead = ' ';
@@ -3094,7 +3095,7 @@ int gameDialogDrawText(unsigned char* buffer, Rect* rect, char* string, int* a4,
fontDrawText(buffer + pitch * rect->top, start, maxWidth, pitch, color);
}
if (a4 != NULL) {
if (a4 != nullptr) {
*a4 += static_cast<int>(strlen(start)) + 1;
}
@@ -3110,7 +3111,7 @@ int gameDialogDrawText(unsigned char* buffer, Rect* rect, char* string, int* a4,
if (a7 != 0) {
if (rect->bottom - fontGetLineHeight() < rect->top) {
if (end != NULL && *end == '\0') {
if (end != nullptr && *end == '\0') {
*end = ' ';
}
return rect->top;
@@ -3125,24 +3126,24 @@ int gameDialogDrawText(unsigned char* buffer, Rect* rect, char* string, int* a4,
fontDrawText(dest + pitch * rect->top, start, maxWidth, pitch, color);
}
if (a4 != NULL && end != NULL) {
if (a4 != nullptr && end != nullptr) {
*a4 += static_cast<int>(strlen(start)) + 1;
}
rect->top += height;
if (end != NULL) {
if (end != nullptr) {
start = end + 1;
if (*end == '\0') {
*end = ' ';
}
end = NULL;
end = nullptr;
} else {
start = NULL;
start = nullptr;
}
}
if (a4 != NULL) {
if (a4 != nullptr) {
*a4 = 0;
}
@@ -3203,7 +3204,7 @@ int _gdialog_barter_create_win()
}
unsigned char* backgroundData = backgroundFrmImage.getData();
if (backgroundData == NULL) {
if (backgroundData == nullptr) {
return -1;
}
@@ -3227,17 +3228,17 @@ int _gdialog_barter_create_win()
unsigned char* backgroundWindowBuffer = windowGetBuffer(gGameDialogBackgroundWindow);
blitBufferToBuffer(backgroundWindowBuffer + width * (480 - _dialogue_subwin_len), width, _dialogue_subwin_len, width, windowBuffer, width);
_gdialog_scroll_subwin(gGameDialogWindow, 1, backgroundData, windowBuffer, NULL, _dialogue_subwin_len, 0);
_gdialog_scroll_subwin(gGameDialogWindow, 1, backgroundData, windowBuffer, nullptr, _dialogue_subwin_len, 0);
backgroundFrmImage.unlock();
// TRADE
_gdialog_buttons[0] = buttonCreate(gGameDialogWindow, 41, 163, 14, 14, -1, -1, -1, KEY_LOWERCASE_M, _redButtonNormalFrmImage.getData(), _redButtonPressedFrmImage.getData(), 0, BUTTON_FLAG_TRANSPARENT);
_gdialog_buttons[0] = buttonCreate(gGameDialogWindow, 41, 163, 14, 14, -1, -1, -1, KEY_LOWERCASE_M, _redButtonNormalFrmImage.getData(), _redButtonPressedFrmImage.getData(), nullptr, BUTTON_FLAG_TRANSPARENT);
if (_gdialog_buttons[0] != -1) {
buttonSetCallbacks(_gdialog_buttons[0], _gsound_med_butt_press, _gsound_med_butt_release);
// TALK
_gdialog_buttons[1] = buttonCreate(gGameDialogWindow, 584, 162, 14, 14, -1, -1, -1, KEY_LOWERCASE_T, _redButtonNormalFrmImage.getData(), _redButtonPressedFrmImage.getData(), 0, BUTTON_FLAG_TRANSPARENT);
_gdialog_buttons[1] = buttonCreate(gGameDialogWindow, 584, 162, 14, 14, -1, -1, -1, KEY_LOWERCASE_T, _redButtonNormalFrmImage.getData(), _redButtonPressedFrmImage.getData(), nullptr, BUTTON_FLAG_TRANSPARENT);
if (_gdialog_buttons[1] != -1) {
buttonSetCallbacks(_gdialog_buttons[1], _gsound_med_butt_press, _gsound_med_butt_release);
@@ -3253,10 +3254,10 @@ int _gdialog_barter_create_win()
return 0;
}
objectDestroy(_barterer_table_obj, 0);
objectDestroy(_barterer_table_obj, nullptr);
}
objectDestroy(_peon_table_obj, 0);
objectDestroy(_peon_table_obj, nullptr);
}
buttonDestroy(_gdialog_buttons[1]);
@@ -3280,9 +3281,9 @@ void _gdialog_barter_destroy_win()
return;
}
objectDestroy(_barterer_temp_obj, 0);
objectDestroy(_barterer_table_obj, 0);
objectDestroy(_peon_table_obj, 0);
objectDestroy(_barterer_temp_obj, nullptr);
objectDestroy(_barterer_table_obj, nullptr);
objectDestroy(_peon_table_obj, nullptr);
for (int index = 0; index < 9; index++) {
buttonDestroy(_gdialog_buttons[index]);
@@ -3336,7 +3337,7 @@ void _gdialog_barter_cleanup_tables()
itemMoveForce(_barterer_table_obj, gGameDialogSpeaker, item, quantity);
}
if (_barterer_temp_obj != NULL) {
if (_barterer_temp_obj != nullptr) {
inventory = &(_barterer_temp_obj->data.inventory);
length = inventory->length;
for (int index = 0; index < length; index++) {
@@ -3357,7 +3358,7 @@ int partyMemberControlWindowInit()
}
unsigned char* backgroundData = backgroundFrmImage.getData();
if (backgroundData == NULL) {
if (backgroundData == nullptr) {
partyMemberControlWindowFree();
return -1;
}
@@ -3379,11 +3380,11 @@ int partyMemberControlWindowInit()
unsigned char* windowBuffer = windowGetBuffer(gGameDialogWindow);
unsigned char* src = windowGetBuffer(gGameDialogBackgroundWindow);
blitBufferToBuffer(src + (GAME_DIALOG_WINDOW_WIDTH) * (GAME_DIALOG_WINDOW_HEIGHT - _dialogue_subwin_len), GAME_DIALOG_WINDOW_WIDTH, _dialogue_subwin_len, GAME_DIALOG_WINDOW_WIDTH, windowBuffer, GAME_DIALOG_WINDOW_WIDTH);
_gdialog_scroll_subwin(gGameDialogWindow, 1, backgroundData, windowBuffer, 0, _dialogue_subwin_len, 0);
_gdialog_scroll_subwin(gGameDialogWindow, 1, backgroundData, windowBuffer, nullptr, _dialogue_subwin_len, 0);
backgroundFrmImage.unlock();
// TALK
_gdialog_buttons[0] = buttonCreate(gGameDialogWindow, 593, 41, 14, 14, -1, -1, -1, KEY_ESCAPE, _redButtonNormalFrmImage.getData(), _redButtonPressedFrmImage.getData(), NULL, BUTTON_FLAG_TRANSPARENT);
_gdialog_buttons[0] = buttonCreate(gGameDialogWindow, 593, 41, 14, 14, -1, -1, -1, KEY_ESCAPE, _redButtonNormalFrmImage.getData(), _redButtonPressedFrmImage.getData(), nullptr, BUTTON_FLAG_TRANSPARENT);
if (_gdialog_buttons[0] == -1) {
partyMemberControlWindowFree();
return -1;
@@ -3391,7 +3392,7 @@ int partyMemberControlWindowInit()
buttonSetCallbacks(_gdialog_buttons[0], _gsound_med_butt_press, _gsound_med_butt_release);
// TRADE
_gdialog_buttons[1] = buttonCreate(gGameDialogWindow, 593, 97, 14, 14, -1, -1, -1, KEY_LOWERCASE_D, _redButtonNormalFrmImage.getData(), _redButtonPressedFrmImage.getData(), NULL, BUTTON_FLAG_TRANSPARENT);
_gdialog_buttons[1] = buttonCreate(gGameDialogWindow, 593, 97, 14, 14, -1, -1, -1, KEY_LOWERCASE_D, _redButtonNormalFrmImage.getData(), _redButtonPressedFrmImage.getData(), nullptr, BUTTON_FLAG_TRANSPARENT);
if (_gdialog_buttons[1] == -1) {
partyMemberControlWindowFree();
return -1;
@@ -3399,7 +3400,7 @@ int partyMemberControlWindowInit()
buttonSetCallbacks(_gdialog_buttons[1], _gsound_med_butt_press, _gsound_med_butt_release);
// USE BEST WEAPON
_gdialog_buttons[2] = buttonCreate(gGameDialogWindow, 236, 15, 14, 14, -1, -1, -1, KEY_LOWERCASE_W, _redButtonNormalFrmImage.getData(), _redButtonPressedFrmImage.getData(), NULL, BUTTON_FLAG_TRANSPARENT);
_gdialog_buttons[2] = buttonCreate(gGameDialogWindow, 236, 15, 14, 14, -1, -1, -1, KEY_LOWERCASE_W, _redButtonNormalFrmImage.getData(), _redButtonPressedFrmImage.getData(), nullptr, BUTTON_FLAG_TRANSPARENT);
if (_gdialog_buttons[2] == -1) {
partyMemberControlWindowFree();
return -1;
@@ -3407,7 +3408,7 @@ int partyMemberControlWindowInit()
buttonSetCallbacks(_gdialog_buttons[1], _gsound_med_butt_press, _gsound_med_butt_release);
// USE BEST ARMOR
_gdialog_buttons[3] = buttonCreate(gGameDialogWindow, 235, 46, 14, 14, -1, -1, -1, KEY_LOWERCASE_A, _redButtonNormalFrmImage.getData(), _redButtonPressedFrmImage.getData(), NULL, BUTTON_FLAG_TRANSPARENT);
_gdialog_buttons[3] = buttonCreate(gGameDialogWindow, 235, 46, 14, 14, -1, -1, -1, KEY_LOWERCASE_A, _redButtonNormalFrmImage.getData(), _redButtonPressedFrmImage.getData(), nullptr, BUTTON_FLAG_TRANSPARENT);
if (_gdialog_buttons[3] == -1) {
partyMemberControlWindowFree();
return -1;
@@ -3424,7 +3425,7 @@ int partyMemberControlWindowInit()
fid = buildFid(OBJ_TYPE_INTERFACE, buttonData->upFrmId, 0, 0, 0);
Art* upButtonFrm = artLock(fid, &(buttonData->upFrmHandle));
if (upButtonFrm == NULL) {
if (upButtonFrm == nullptr) {
partyMemberControlWindowFree();
return -1;
}
@@ -3435,7 +3436,7 @@ int partyMemberControlWindowInit()
fid = buildFid(OBJ_TYPE_INTERFACE, buttonData->downFrmId, 0, 0, 0);
Art* downButtonFrm = artLock(fid, &(buttonData->downFrmHandle));
if (downButtonFrm == NULL) {
if (downButtonFrm == nullptr) {
partyMemberControlWindowFree();
return -1;
}
@@ -3444,7 +3445,7 @@ int partyMemberControlWindowInit()
fid = buildFid(OBJ_TYPE_INTERFACE, buttonData->disabledFrmId, 0, 0, 0);
Art* disabledButtonFrm = artLock(fid, &(buttonData->disabledFrmHandle));
if (disabledButtonFrm == NULL) {
if (disabledButtonFrm == nullptr) {
partyMemberControlWindowFree();
return -1;
}
@@ -3464,7 +3465,7 @@ int partyMemberControlWindowInit()
-1,
upButtonFrmData,
downButtonFrmData,
NULL,
nullptr,
BUTTON_FLAG_TRANSPARENT | BUTTON_FLAG_0x04 | BUTTON_FLAG_0x01);
if (_gdialog_buttons[v21] == -1) {
partyMemberControlWindowFree();
@@ -3510,17 +3511,17 @@ void partyMemberControlWindowFree()
if (buttonData->upFrmHandle) {
artUnlock(buttonData->upFrmHandle);
buttonData->upFrmHandle = NULL;
buttonData->upFrmHandle = nullptr;
}
if (buttonData->downFrmHandle) {
artUnlock(buttonData->downFrmHandle);
buttonData->downFrmHandle = NULL;
buttonData->downFrmHandle = nullptr;
}
if (buttonData->disabledFrmHandle) {
artUnlock(buttonData->disabledFrmHandle);
buttonData->disabledFrmHandle = NULL;
buttonData->disabledFrmHandle = nullptr;
}
}
@@ -3571,13 +3572,13 @@ void partyMemberControlWindowUpdate()
// Render item in right hand.
Object* item2 = critterGetItem2(gGameDialogSpeaker);
text = item2 != NULL ? itemGetName(item2) : getmsg(&gProtoMessageList, &messageListItem, 10);
text = item2 != nullptr ? itemGetName(item2) : getmsg(&gProtoMessageList, &messageListItem, 10);
snprintf(formattedText, sizeof(formattedText), "%s", text);
fontDrawText(windowBuffer + windowWidth * 20 + 112, formattedText, 110, windowWidth, _colorTable[992]);
// Render armor.
Object* armor = critterGetArmor(gGameDialogSpeaker);
text = armor != NULL ? itemGetName(armor) : getmsg(&gProtoMessageList, &messageListItem, 10);
text = armor != nullptr ? itemGetName(armor) : getmsg(&gProtoMessageList, &messageListItem, 10);
snprintf(formattedText, sizeof(formattedText), "%s", text);
fontDrawText(windowBuffer + windowWidth * 49 + 112, formattedText, 110, windowWidth, _colorTable[992]);
@@ -3585,7 +3586,7 @@ void partyMemberControlWindowUpdate()
CacheEntry* previewHandle;
int previewFid = buildFid(FID_TYPE(gGameDialogSpeaker->fid), gGameDialogSpeaker->fid & 0xFFF, ANIM_STAND, (gGameDialogSpeaker->fid & 0xF000) >> 12, ROTATION_SW);
Art* preview = artLock(previewFid, &previewHandle);
if (preview != NULL) {
if (preview != nullptr) {
int width = artGetWidth(preview, 0, ROTATION_SW);
int height = artGetHeight(preview, 0, ROTATION_SW);
unsigned char* buffer = artGetFrameData(preview, 0, ROTATION_SW);
@@ -3712,8 +3713,8 @@ void partyMemberControlWindowHandleEvents()
if (keyCode == KEY_LOWERCASE_W) {
_inven_unwield(gGameDialogSpeaker, 1);
Object* weapon = _ai_search_inven_weap(gGameDialogSpeaker, 0, NULL);
if (weapon != NULL) {
Object* weapon = _ai_search_inven_weap(gGameDialogSpeaker, 0, nullptr);
if (weapon != nullptr) {
_inven_wield(gGameDialogSpeaker, weapon, 1);
aiAttemptWeaponReload(gGameDialogSpeaker, 0);
@@ -3742,7 +3743,7 @@ void partyMemberControlWindowHandleEvents()
} else if (keyCode == KEY_LOWERCASE_A) {
if (gGameDialogSpeaker->pid != 0x10000A1) {
Object* armor = _ai_search_inven_armor(gGameDialogSpeaker);
if (armor != NULL) {
if (armor != nullptr) {
_inven_wield(gGameDialogSpeaker, armor, 0);
}
}
@@ -3795,7 +3796,7 @@ int partyMemberCustomizationWindowInit()
}
unsigned char* backgroundFrmData = backgroundFrmImage.getData();
if (backgroundFrmData == NULL) {
if (backgroundFrmData == nullptr) {
// FIXME: Leaking background.
partyMemberCustomizationWindowFree();
return -1;
@@ -3825,10 +3826,10 @@ int partyMemberCustomizationWindowInit()
windowBuffer,
GAME_DIALOG_WINDOW_WIDTH);
_gdialog_scroll_subwin(gGameDialogWindow, 1, backgroundFrmData, windowBuffer, NULL, _dialogue_subwin_len, 0);
_gdialog_scroll_subwin(gGameDialogWindow, 1, backgroundFrmData, windowBuffer, nullptr, _dialogue_subwin_len, 0);
backgroundFrmImage.unlock();
_gdialog_buttons[0] = buttonCreate(gGameDialogWindow, 593, 101, 14, 14, -1, -1, -1, 13, _redButtonNormalFrmImage.getData(), _redButtonPressedFrmImage.getData(), 0, BUTTON_FLAG_TRANSPARENT);
_gdialog_buttons[0] = buttonCreate(gGameDialogWindow, 593, 101, 14, 14, -1, -1, -1, 13, _redButtonNormalFrmImage.getData(), _redButtonPressedFrmImage.getData(), nullptr, BUTTON_FLAG_TRANSPARENT);
if (_gdialog_buttons[0] == -1) {
partyMemberCustomizationWindowFree();
return -1;
@@ -3844,7 +3845,7 @@ int partyMemberCustomizationWindowInit()
int upButtonFid = buildFid(OBJ_TYPE_INTERFACE, buttonData->upFrmId, 0, 0, 0);
Art* upButtonFrm = artLock(upButtonFid, &(buttonData->upFrmHandle));
if (upButtonFrm == NULL) {
if (upButtonFrm == nullptr) {
partyMemberCustomizationWindowFree();
return -1;
}
@@ -3855,7 +3856,7 @@ int partyMemberCustomizationWindowInit()
int downButtonFid = buildFid(OBJ_TYPE_INTERFACE, buttonData->downFrmId, 0, 0, 0);
Art* downButtonFrm = artLock(downButtonFid, &(buttonData->downFrmHandle));
if (downButtonFrm == NULL) {
if (downButtonFrm == nullptr) {
partyMemberCustomizationWindowFree();
return -1;
}
@@ -3874,7 +3875,7 @@ int partyMemberCustomizationWindowInit()
buttonData->keyCode,
upButtonFrmData,
downButtonFrmData,
NULL,
nullptr,
BUTTON_FLAG_TRANSPARENT);
if (_gdialog_buttons[optionButton] == -1) {
partyMemberCustomizationWindowFree();
@@ -3913,19 +3914,19 @@ void partyMemberCustomizationWindowFree()
for (int index = 0; index < PARTY_MEMBER_CUSTOMIZATION_OPTION_COUNT; index++) {
GameDialogButtonData* buttonData = &(_custom_button_info[index]);
if (buttonData->upFrmHandle != NULL) {
if (buttonData->upFrmHandle != nullptr) {
artUnlock(buttonData->upFrmHandle);
buttonData->upFrmHandle = NULL;
buttonData->upFrmHandle = nullptr;
}
if (buttonData->downFrmHandle != NULL) {
if (buttonData->downFrmHandle != nullptr) {
artUnlock(buttonData->downFrmHandle);
buttonData->downFrmHandle = NULL;
buttonData->downFrmHandle = nullptr;
}
if (buttonData->disabledFrmHandle != NULL) {
if (buttonData->disabledFrmHandle != nullptr) {
artUnlock(buttonData->disabledFrmHandle);
buttonData->disabledFrmHandle = NULL;
buttonData->disabledFrmHandle = nullptr;
}
}
@@ -4116,13 +4117,13 @@ int _gdCustomSelect(int a1)
backgroundFrmImage.unlock();
int btn1 = buttonCreate(win, 70, 164, 14, 14, -1, -1, -1, KEY_RETURN, _redButtonNormalFrmImage.getData(), _redButtonPressedFrmImage.getData(), NULL, BUTTON_FLAG_TRANSPARENT);
int btn1 = buttonCreate(win, 70, 164, 14, 14, -1, -1, -1, KEY_RETURN, _redButtonNormalFrmImage.getData(), _redButtonPressedFrmImage.getData(), nullptr, BUTTON_FLAG_TRANSPARENT);
if (btn1 == -1) {
windowDestroy(win);
return -1;
}
int btn2 = buttonCreate(win, 176, 163, 14, 14, -1, -1, -1, KEY_ESCAPE, _redButtonNormalFrmImage.getData(), _redButtonPressedFrmImage.getData(), NULL, BUTTON_FLAG_TRANSPARENT);
int btn2 = buttonCreate(win, 176, 163, 14, 14, -1, -1, -1, KEY_ESCAPE, _redButtonNormalFrmImage.getData(), _redButtonPressedFrmImage.getData(), nullptr, BUTTON_FLAG_TRANSPARENT);
if (btn2 == -1) {
windowDestroy(win);
return -1;
@@ -4330,7 +4331,7 @@ int _gdialog_window_create()
}
unsigned char* backgroundFrmData = backgroundFrmImage.getData();
if (backgroundFrmData != NULL) {
if (backgroundFrmData != nullptr) {
_dialogue_subwin_len = backgroundFrmImage.getHeight();
int dialogSubwindowX = (screenGetWidth() - GAME_DIALOG_WINDOW_WIDTH) / 2;
@@ -4345,16 +4346,16 @@ int _gdialog_window_create()
if (_dialogue_just_started) {
windowRefresh(gGameDialogBackgroundWindow);
_gdialog_scroll_subwin(gGameDialogWindow, 1, backgroundFrmData, v10, 0, _dialogue_subwin_len, -1);
_gdialog_scroll_subwin(gGameDialogWindow, 1, backgroundFrmData, v10, nullptr, _dialogue_subwin_len, -1);
_dialogue_just_started = 0;
} else {
_gdialog_scroll_subwin(gGameDialogWindow, 1, backgroundFrmData, v10, 0, _dialogue_subwin_len, 0);
_gdialog_scroll_subwin(gGameDialogWindow, 1, backgroundFrmData, v10, nullptr, _dialogue_subwin_len, 0);
}
// BARTER/TRADE
_gdialog_buttons[0] = buttonCreate(gGameDialogWindow, 593, 41, 14, 14, -1, -1, -1, -1, _redButtonNormalFrmImage.getData(), _redButtonPressedFrmImage.getData(), NULL, BUTTON_FLAG_TRANSPARENT);
_gdialog_buttons[0] = buttonCreate(gGameDialogWindow, 593, 41, 14, 14, -1, -1, -1, -1, _redButtonNormalFrmImage.getData(), _redButtonPressedFrmImage.getData(), nullptr, BUTTON_FLAG_TRANSPARENT);
if (_gdialog_buttons[0] != -1) {
buttonSetMouseCallbacks(_gdialog_buttons[0], NULL, NULL, NULL, gameDialogBarterButtonUpMouseUp);
buttonSetMouseCallbacks(_gdialog_buttons[0], nullptr, nullptr, nullptr, gameDialogBarterButtonUpMouseUp);
buttonSetCallbacks(_gdialog_buttons[0], _gsound_med_butt_press, _gsound_med_butt_release);
// di_rest1.frm - dialog rest button up
@@ -4364,9 +4365,9 @@ int _gdialog_window_create()
int downFid = buildFid(OBJ_TYPE_INTERFACE, 98, 0, 0, 0);
if (_reviewButtonPressedFrmImage.lock(downFid)) {
// REVIEW
_gdialog_buttons[1] = buttonCreate(gGameDialogWindow, 13, 154, 51, 29, -1, -1, -1, -1, _reviewButtonNormalFrmImage.getData(), _reviewButtonPressedFrmImage.getData(), NULL, 0);
_gdialog_buttons[1] = buttonCreate(gGameDialogWindow, 13, 154, 51, 29, -1, -1, -1, -1, _reviewButtonNormalFrmImage.getData(), _reviewButtonPressedFrmImage.getData(), nullptr, 0);
if (_gdialog_buttons[1] != -1) {
buttonSetMouseCallbacks(_gdialog_buttons[1], NULL, NULL, NULL, gameDialogReviewButtonOnMouseUp);
buttonSetMouseCallbacks(_gdialog_buttons[1], nullptr, nullptr, nullptr, gameDialogReviewButtonOnMouseUp);
buttonSetCallbacks(_gdialog_buttons[1], _gsound_red_butt_press, _gsound_red_butt_release);
if (!gGameDialogSpeakerIsPartyMember) {
@@ -4375,9 +4376,9 @@ int _gdialog_window_create()
}
// COMBAT CONTROL
_gdialog_buttons[2] = buttonCreate(gGameDialogWindow, 593, 116, 14, 14, -1, -1, -1, -1, _redButtonNormalFrmImage.getData(), _redButtonPressedFrmImage.getData(), 0, BUTTON_FLAG_TRANSPARENT);
_gdialog_buttons[2] = buttonCreate(gGameDialogWindow, 593, 116, 14, 14, -1, -1, -1, -1, _redButtonNormalFrmImage.getData(), _redButtonPressedFrmImage.getData(), nullptr, BUTTON_FLAG_TRANSPARENT);
if (_gdialog_buttons[2] != -1) {
buttonSetMouseCallbacks(_gdialog_buttons[2], NULL, NULL, NULL, gameDialogCombatControlButtonOnMouseUp);
buttonSetMouseCallbacks(_gdialog_buttons[2], nullptr, nullptr, nullptr, gameDialogCombatControlButtonOnMouseUp);
buttonSetCallbacks(_gdialog_buttons[2], _gsound_med_butt_press, _gsound_med_butt_release);
_gdialog_window_created = true;
@@ -4549,7 +4550,7 @@ void gameDialogRenderTalkingHead(Art* headFrm, int frame)
return;
}
if (headFrm != NULL) {
if (headFrm != nullptr) {
if (frame == 0) {
_totalHotx = 0;
}
@@ -4561,7 +4562,7 @@ void gameDialogRenderTalkingHead(Art* headFrm, int frame)
}
unsigned char* backgroundFrmData = backgroundFrmImage.getData();
if (backgroundFrmData != NULL) {
if (backgroundFrmData != nullptr) {
blitBufferToBuffer(backgroundFrmData, 388, 200, 388, gGameDialogDisplayBuffer, GAME_DIALOG_WINDOW_WIDTH);
} else {
debugPrint("\tError getting background data in display...\n");
@@ -4582,7 +4583,7 @@ void gameDialogRenderTalkingHead(Art* headFrm, int frame)
_totalHotx += a4;
a3 += _totalHotx;
if (data != NULL) {
if (data != nullptr) {
int destWidth = GAME_DIALOG_WINDOW_WIDTH;
int destOffset = destWidth * (200 - height) + a3 + (388 - width) / 2;
if (destOffset + width * v8 > 0) {

View File

@@ -104,7 +104,7 @@ static unsigned int _gmouse_3d_last_move_time = 0;
// actmenu.frm
// 0x518C8C
static Art* gGameMouseActionMenuFrm = NULL;
static Art* gGameMouseActionMenuFrm = nullptr;
// 0x518C90
static CacheEntry* gGameMouseActionMenuFrmHandle = INVALID_CACHE_ENTRY;
@@ -125,11 +125,11 @@ static int _gmouse_3d_menu_frame_hot_x = 0;
static int _gmouse_3d_menu_frame_hot_y = 0;
// 0x518CA8
static unsigned char* gGameMouseActionMenuFrmData = NULL;
static unsigned char* gGameMouseActionMenuFrmData = nullptr;
// actpick.frm
// 0x518CAC
static Art* gGameMouseActionPickFrm = NULL;
static Art* gGameMouseActionPickFrm = nullptr;
// 0x518CB0
static CacheEntry* gGameMouseActionPickFrmHandle = INVALID_CACHE_ENTRY;
@@ -150,11 +150,11 @@ static int _gmouse_3d_pick_frame_hot_x = 0;
static int _gmouse_3d_pick_frame_hot_y = 0;
// 0x518CC8
static unsigned char* gGameMouseActionPickFrmData = NULL;
static unsigned char* gGameMouseActionPickFrmData = nullptr;
// acttohit.frm
// 0x518CCC
static Art* gGameMouseActionHitFrm = NULL;
static Art* gGameMouseActionHitFrm = nullptr;
// 0x518CD0
static CacheEntry* gGameMouseActionHitFrmHandle = INVALID_CACHE_ENTRY;
@@ -169,11 +169,11 @@ static int gGameMouseActionHitFrmHeight = 0;
static int gGameMouseActionHitFrmDataSize = 0;
// 0x518CE0
static unsigned char* gGameMouseActionHitFrmData = NULL;
static unsigned char* gGameMouseActionHitFrmData = nullptr;
// blank.frm
// 0x518CE4
static Art* gGameMouseBouncingCursorFrm = NULL;
static Art* gGameMouseBouncingCursorFrm = nullptr;
// 0x518CE8
static CacheEntry* gGameMouseBouncingCursorFrmHandle = INVALID_CACHE_ENTRY;
@@ -188,11 +188,11 @@ static int gGameMouseBouncingCursorFrmHeight = 0;
static int gGameMouseBouncingCursorFrmDataSize = 0;
// 0x518CF8
static unsigned char* gGameMouseBouncingCursorFrmData = NULL;
static unsigned char* gGameMouseBouncingCursorFrmData = nullptr;
// msef000.frm
// 0x518CFC
static Art* gGameMouseHexCursorFrm = NULL;
static Art* gGameMouseHexCursorFrm = nullptr;
// 0x518D00
static CacheEntry* gGameMouseHexCursorFrmHandle = INVALID_CACHE_ENTRY;
@@ -207,13 +207,13 @@ static int gGameMouseHexCursorHeight = 0;
static int gGameMouseHexCursorDataSize = 0;
// 0x518D10
static unsigned char* gGameMouseHexCursorFrmData = NULL;
static unsigned char* gGameMouseHexCursorFrmData = nullptr;
// 0x518D14
static unsigned char gGameMouseActionMenuItemsLength = 0;
// 0x518D18
static unsigned char* _gmouse_3d_menu_actions_start = NULL;
static unsigned char* _gmouse_3d_menu_actions_start = nullptr;
// 0x518D1C
static unsigned char gGameMouseActionMenuHighlightedItemIndex = 0;
@@ -277,7 +277,7 @@ static int _gmouse_bk_last_cursor = -1;
static bool gGameMouseItemHighlightEnabled = true;
// 0x518D94
static Object* gGameMouseHighlightedItem = NULL;
static Object* gGameMouseHighlightedItem = nullptr;
// 0x518D98
bool _gmouse_clicked_on_edge = false;
@@ -380,7 +380,7 @@ void gameMouseExit()
mouseHideCursor();
mouseSetFrame(NULL, 0, 0, 0, 0, 0, 0);
mouseSetFrame(nullptr, 0, 0, 0, 0, 0, 0);
// NOTE: Uninline.
gameMouseObjectsFree();
@@ -669,7 +669,7 @@ void gameMouseRefresh()
_gmouse_3d_hover_test = true;
Object* pointedObject = gameMouseGetObjectUnderCursor(-1, true, gElevation);
if (pointedObject != NULL) {
if (pointedObject != nullptr) {
int primaryAction = -1;
switch (FID_TYPE(pointedObject->fid)) {
@@ -732,14 +732,14 @@ void gameMouseRefresh()
}
} else if (gGameMouseMode == GAME_MOUSE_MODE_CROSSHAIR) {
Object* pointedObject = gameMouseGetObjectUnderCursor(OBJ_TYPE_CRITTER, false, gElevation);
if (pointedObject == NULL) {
if (pointedObject == nullptr) {
pointedObject = gameMouseGetObjectUnderCursor(-1, false, gElevation);
if (!objectIsDoor(pointedObject)) {
pointedObject = NULL;
pointedObject = nullptr;
}
}
if (pointedObject != NULL) {
if (pointedObject != nullptr) {
bool pointedObjectIsCritter = FID_TYPE(pointedObject->fid) == OBJ_TYPE_CRITTER;
if (settings.preferences.combat_looks) {
@@ -804,7 +804,7 @@ void gameMouseRefresh()
char formattedActionPoints[8];
int color;
int distance = _make_path(gDude, gDude->tile, gGameMouseHexCursor->tile, NULL, 1);
int distance = _make_path(gDude, gDude->tile, gGameMouseHexCursor->tile, nullptr, 1);
if (distance != 0) {
if (!isInCombat()) {
formattedActionPoints[0] = '\0';
@@ -856,11 +856,11 @@ void gameMouseRefresh()
v34 |= 1;
}
if (gGameMouseHighlightedItem != NULL) {
if (gGameMouseHighlightedItem != nullptr) {
if (objectClearOutline(gGameMouseHighlightedItem, &r26) == 0) {
v34 |= 2;
}
gGameMouseHighlightedItem = NULL;
gGameMouseHighlightedItem = nullptr;
}
switch (v34) {
@@ -951,7 +951,7 @@ void _gmouse_handle_event(int mouseX, int mouseY, int mouseState)
if (gGameMouseMode == GAME_MOUSE_MODE_ARROW) {
Object* v5 = gameMouseGetObjectUnderCursor(-1, true, gElevation);
if (v5 != NULL) {
if (v5 != nullptr) {
switch (FID_TYPE(v5->fid)) {
case OBJ_TYPE_ITEM:
actionPickUp(gDude, v5);
@@ -999,14 +999,14 @@ void _gmouse_handle_event(int mouseX, int mouseY, int mouseState)
if (gGameMouseMode == GAME_MOUSE_MODE_CROSSHAIR) {
Object* v7 = gameMouseGetObjectUnderCursor(OBJ_TYPE_CRITTER, false, gElevation);
if (v7 == NULL) {
if (v7 == nullptr) {
v7 = gameMouseGetObjectUnderCursor(-1, false, gElevation);
if (!objectIsDoor(v7)) {
v7 = NULL;
v7 = nullptr;
}
}
if (v7 != NULL) {
if (v7 != nullptr) {
_combat_attack_this(v7);
_gmouse_3d_hover_test = true;
gGameMouseLastY = mouseY;
@@ -1018,7 +1018,7 @@ void _gmouse_handle_event(int mouseX, int mouseY, int mouseState)
if (gGameMouseMode == GAME_MOUSE_MODE_USE_CROSSHAIR) {
Object* object = gameMouseGetObjectUnderCursor(-1, true, gElevation);
if (object != NULL) {
if (object != nullptr) {
Object* weapon;
if (interfaceGetActiveItem(&weapon) != -1) {
if (isInCombat()) {
@@ -1056,7 +1056,7 @@ void _gmouse_handle_event(int mouseX, int mouseY, int mouseState)
|| gGameMouseMode == GAME_MOUSE_MODE_USE_SCIENCE
|| gGameMouseMode == GAME_MOUSE_MODE_USE_REPAIR) {
Object* object = gameMouseGetObjectUnderCursor(-1, 1, gElevation);
if (object == NULL || actionUseSkill(gDude, object, gGameMouseModeSkills[gGameMouseMode - FIRST_GAME_MOUSE_MODE_SKILL]) != -1) {
if (object == nullptr || actionUseSkill(gDude, object, gGameMouseModeSkills[gGameMouseMode - FIRST_GAME_MOUSE_MODE_SKILL]) != -1) {
gameMouseSetCursor(MOUSE_CURSOR_NONE);
gameMouseSetMode(GAME_MOUSE_MODE_MOVE);
}
@@ -1066,7 +1066,7 @@ void _gmouse_handle_event(int mouseX, int mouseY, int mouseState)
if ((mouseState & MOUSE_EVENT_LEFT_BUTTON_DOWN_REPEAT) == MOUSE_EVENT_LEFT_BUTTON_DOWN_REPEAT && gGameMouseMode == GAME_MOUSE_MODE_ARROW) {
Object* v16 = gameMouseGetObjectUnderCursor(-1, true, gElevation);
if (v16 != NULL) {
if (v16 != nullptr) {
int actionMenuItemsCount = 0;
int actionMenuItems[6];
switch (FID_TYPE(v16->fid)) {
@@ -1266,7 +1266,7 @@ int gameMouseSetCursor(int cursor)
CacheEntry* mouseCursorFrmHandle;
int fid = buildFid(OBJ_TYPE_INTERFACE, gGameMouseCursorFrmIds[cursor], 0, 0, 0);
Art* mouseCursorFrm = artLock(fid, &mouseCursorFrmHandle);
if (mouseCursorFrm == NULL) {
if (mouseCursorFrm == nullptr) {
return -1;
}
@@ -1328,6 +1328,12 @@ int gameMouseGetCursor()
return gGameMouseCursor;
}
// 0x44C9F0
void gmouse_set_mapper_mode(int mode)
{
_gmouse_mapper_mode = mode;
}
// 0x44C9F8
void _gmouse_3d_enable_modes()
{
@@ -1420,7 +1426,7 @@ void gameMouseCycleMode()
if (isInCombat()) {
Object* item;
if (interfaceGetActiveItem(&item) == 0) {
if (item != NULL && itemGetType(item) != ITEM_TYPE_WEAPON && mode == GAME_MOUSE_MODE_CROSSHAIR) {
if (item != nullptr && itemGetType(item) != ITEM_TYPE_WEAPON && mode == GAME_MOUSE_MODE_CROSSHAIR) {
mode = GAME_MOUSE_MODE_MOVE;
}
}
@@ -1459,7 +1465,7 @@ int gameMouseSetBouncingCursorFid(int fid)
}
if (!_gmouse_mapper_mode) {
return objectSetFid(gGameMouseBouncingCursor, fid, NULL);
return objectSetFid(gGameMouseBouncingCursor, fid, nullptr);
}
int v1 = 0;
@@ -1614,7 +1620,7 @@ Object* gameMouseGetObjectUnderCursor(int objectType, bool a2, int elevation)
}
}
Object* v4 = NULL;
Object* v4 = nullptr;
if (!v13) {
ObjectWithFlags* entries;
int count = _obj_create_intersect_list(mouseX, mouseY, elevation, objectType, &entries);
@@ -1645,14 +1651,14 @@ int gameMouseRenderPrimaryAction(int x, int y, int menuItem, int width, int heig
CacheEntry* menuItemFrmHandle;
int menuItemFid = buildFid(OBJ_TYPE_INTERFACE, gGameMouseActionMenuItemFrmIds[menuItem], 0, 0, 0);
Art* menuItemFrm = artLock(menuItemFid, &menuItemFrmHandle);
if (menuItemFrm == NULL) {
if (menuItemFrm == nullptr) {
return -1;
}
CacheEntry* arrowFrmHandle;
int arrowFid = buildFid(OBJ_TYPE_INTERFACE, gGameMouseModeFrmIds[GAME_MOUSE_MODE_ARROW], 0, 0, 0);
Art* arrowFrm = artLock(arrowFid, &arrowFrmHandle);
if (arrowFrm == NULL) {
if (arrowFrm == nullptr) {
artUnlock(menuItemFrmHandle);
// FIXME: Why this is success?
return 0;
@@ -1727,11 +1733,11 @@ int _gmouse_3d_pick_frame_hot(int* a1, int* a2)
// 0x44D214
int gameMouseRenderActionMenuItems(int x, int y, const int* menuItems, int menuItemsLength, int width, int height)
{
_gmouse_3d_menu_actions_start = NULL;
_gmouse_3d_menu_actions_start = nullptr;
gGameMouseActionMenuHighlightedItemIndex = 0;
gGameMouseActionMenuItemsLength = 0;
if (menuItems == NULL) {
if (menuItems == nullptr) {
return -1;
}
@@ -1751,7 +1757,7 @@ int gameMouseRenderActionMenuItems(int x, int y, const int* menuItems, int menuI
int fid = buildFid(OBJ_TYPE_INTERFACE, frmId, 0, 0, 0);
menuItemFrms[index] = artLock(fid, &(menuItemFrmHandles[index]));
if (menuItemFrms[index] == NULL) {
if (menuItemFrms[index] == nullptr) {
while (--index >= 0) {
artUnlock(menuItemFrmHandles[index]);
}
@@ -1762,7 +1768,7 @@ int gameMouseRenderActionMenuItems(int x, int y, const int* menuItems, int menuI
int fid = buildFid(OBJ_TYPE_INTERFACE, gGameMouseModeFrmIds[GAME_MOUSE_MODE_ARROW], 0, 0, 0);
CacheEntry* arrowFrmHandle;
Art* arrowFrm = artLock(fid, &arrowFrmHandle);
if (arrowFrm == NULL) {
if (arrowFrm == nullptr) {
// FIXME: Unlock arts.
return -1;
}
@@ -1827,8 +1833,8 @@ int gameMouseRenderActionMenuItems(int x, int y, const int* menuItems, int menuI
gGameMouseActionMenuItemsLength = menuItemsLength;
_gmouse_3d_menu_actions_start = v58;
Sound* sound = soundEffectLoad("iaccuxx1", NULL);
if (sound != NULL) {
Sound* sound = soundEffectLoad("iaccuxx1", nullptr);
if (sound != nullptr) {
soundEffectPlay(sound);
}
@@ -1845,7 +1851,7 @@ int gameMouseHighlightActionMenuItemAtIndex(int menuItemIndex)
CacheEntry* handle;
int fid = buildFid(OBJ_TYPE_INTERFACE, gGameMouseActionMenuItemFrmIds[gGameMouseActionMenuItems[gGameMouseActionMenuHighlightedItemIndex]], 0, 0, 0);
Art* art = artLock(fid, &handle);
if (art == NULL) {
if (art == nullptr) {
return -1;
}
@@ -1857,7 +1863,7 @@ int gameMouseHighlightActionMenuItemAtIndex(int menuItemIndex)
fid = buildFid(OBJ_TYPE_INTERFACE, gGameMouseActionMenuItemFrmIds[gGameMouseActionMenuItems[menuItemIndex]] - 1, 0, 0, 0);
art = artLock(fid, &handle);
if (art == NULL) {
if (art == nullptr) {
return -1;
}
@@ -1876,7 +1882,7 @@ int gameMouseRenderAccuracy(const char* string, int color)
CacheEntry* crosshairFrmHandle;
int fid = buildFid(OBJ_TYPE_INTERFACE, gGameMouseModeFrmIds[GAME_MOUSE_MODE_CROSSHAIR], 0, 0, 0);
Art* crosshairFrm = artLock(fid, &crosshairFrmHandle);
if (crosshairFrm == NULL) {
if (crosshairFrm == nullptr) {
return -1;
}
@@ -1964,7 +1970,7 @@ int gameMouseObjectsInit()
return -1;
}
if (objectSetOutline(gGameMouseHexCursor, OUTLINE_PALETTED | OUTLINE_TYPE_2, NULL) != 0) {
if (objectSetOutline(gGameMouseHexCursor, OUTLINE_PALETTED | OUTLINE_TYPE_2, nullptr) != 0) {
return -1;
}
@@ -1984,7 +1990,7 @@ int gameMouseObjectsInit()
gGameMouseHexCursor->flags |= OBJECT_SHOOT_THRU;
gGameMouseHexCursor->flags |= OBJECT_NO_BLOCK;
_obj_toggle_flat(gGameMouseHexCursor, NULL);
_obj_toggle_flat(gGameMouseHexCursor, nullptr);
int x;
int y;
@@ -2038,8 +2044,8 @@ void gameMouseObjectsFree()
gGameMouseBouncingCursor->flags &= ~OBJECT_NO_SAVE;
gGameMouseHexCursor->flags &= ~OBJECT_NO_SAVE;
objectDestroy(gGameMouseBouncingCursor, NULL);
objectDestroy(gGameMouseHexCursor, NULL);
objectDestroy(gGameMouseBouncingCursor, nullptr);
objectDestroy(gGameMouseHexCursor, nullptr);
gGameMouseObjectsInitialized = false;
}
@@ -2053,35 +2059,35 @@ int gameMouseActionMenuInit()
// actmenu.frm - action menu
fid = buildFid(OBJ_TYPE_INTERFACE, 283, 0, 0, 0);
gGameMouseActionMenuFrm = artLock(fid, &gGameMouseActionMenuFrmHandle);
if (gGameMouseActionMenuFrm == NULL) {
if (gGameMouseActionMenuFrm == nullptr) {
goto err;
}
// actpick.frm - action pick
fid = buildFid(OBJ_TYPE_INTERFACE, 282, 0, 0, 0);
gGameMouseActionPickFrm = artLock(fid, &gGameMouseActionPickFrmHandle);
if (gGameMouseActionPickFrm == NULL) {
if (gGameMouseActionPickFrm == nullptr) {
goto err;
}
// acttohit.frm - action to hit
fid = buildFid(OBJ_TYPE_INTERFACE, 284, 0, 0, 0);
gGameMouseActionHitFrm = artLock(fid, &gGameMouseActionHitFrmHandle);
if (gGameMouseActionHitFrm == NULL) {
if (gGameMouseActionHitFrm == nullptr) {
goto err;
}
// blank.frm - used be mset000.frm for top of bouncing mouse cursor
fid = buildFid(OBJ_TYPE_INTERFACE, 0, 0, 0, 0);
gGameMouseBouncingCursorFrm = artLock(fid, &gGameMouseBouncingCursorFrmHandle);
if (gGameMouseBouncingCursorFrm == NULL) {
if (gGameMouseBouncingCursorFrm == nullptr) {
goto err;
}
// msef000.frm - hex mouse cursor
fid = buildFid(OBJ_TYPE_INTERFACE, 1, 0, 0, 0);
gGameMouseHexCursorFrm = artLock(fid, &gGameMouseHexCursorFrmHandle);
if (gGameMouseHexCursorFrm == NULL) {
if (gGameMouseHexCursorFrm == nullptr) {
goto err;
}
@@ -2128,35 +2134,35 @@ void gameMouseActionMenuFree()
if (gGameMouseBouncingCursorFrmHandle != INVALID_CACHE_ENTRY) {
artUnlock(gGameMouseBouncingCursorFrmHandle);
}
gGameMouseBouncingCursorFrm = NULL;
gGameMouseBouncingCursorFrm = nullptr;
gGameMouseBouncingCursorFrmHandle = INVALID_CACHE_ENTRY;
if (gGameMouseHexCursorFrmHandle != INVALID_CACHE_ENTRY) {
artUnlock(gGameMouseHexCursorFrmHandle);
}
gGameMouseHexCursorFrm = NULL;
gGameMouseHexCursorFrm = nullptr;
gGameMouseHexCursorFrmHandle = INVALID_CACHE_ENTRY;
if (gGameMouseActionHitFrmHandle != INVALID_CACHE_ENTRY) {
artUnlock(gGameMouseActionHitFrmHandle);
}
gGameMouseActionHitFrm = NULL;
gGameMouseActionHitFrm = nullptr;
gGameMouseActionHitFrmHandle = INVALID_CACHE_ENTRY;
if (gGameMouseActionMenuFrmHandle != INVALID_CACHE_ENTRY) {
artUnlock(gGameMouseActionMenuFrmHandle);
}
gGameMouseActionMenuFrm = NULL;
gGameMouseActionMenuFrm = nullptr;
gGameMouseActionMenuFrmHandle = INVALID_CACHE_ENTRY;
if (gGameMouseActionPickFrmHandle != INVALID_CACHE_ENTRY) {
artUnlock(gGameMouseActionPickFrmHandle);
}
gGameMouseActionPickFrm = NULL;
gGameMouseActionPickFrm = nullptr;
gGameMouseActionPickFrmHandle = INVALID_CACHE_ENTRY;
gGameMouseActionPickFrmData = NULL;
gGameMouseActionPickFrmData = nullptr;
gGameMouseActionPickFrmWidth = 0;
gGameMouseActionPickFrmHeight = 0;
gGameMouseActionPickFrmDataSize = 0;
@@ -2195,7 +2201,7 @@ int _gmouse_3d_move_to(int x, int y, int elevation, Rect* a4)
int offsetY = 0;
CacheEntry* hexCursorFrmHandle;
Art* hexCursorFrm = artLock(gGameMouseHexCursor->fid, &hexCursorFrmHandle);
if (hexCursorFrm != NULL) {
if (hexCursorFrm != nullptr) {
artGetRotationOffsets(hexCursorFrm, 0, &offsetX, &offsetY);
int frameOffsetX;
@@ -2284,7 +2290,7 @@ int _gmouse_3d_move_to(int x, int y, int elevation, Rect* a4)
int offsetY = 0;
CacheEntry* hexCursorFrmHandle;
Art* hexCursorFrm = artLock(gGameMouseHexCursor->fid, &hexCursorFrmHandle);
if (hexCursorFrm != NULL) {
if (hexCursorFrm != nullptr) {
artGetRotationOffsets(hexCursorFrm, 0, &offsetX, &offsetY);
int frameOffsetX;
@@ -2413,19 +2419,19 @@ int gameMouseHandleScrolling(int x, int y, int cursor)
// 0x44E544
void _gmouse_remove_item_outline(Object* object)
{
if (gGameMouseHighlightedItem != NULL && gGameMouseHighlightedItem == object) {
if (gGameMouseHighlightedItem != nullptr && gGameMouseHighlightedItem == object) {
Rect rect;
if (objectClearOutline(object, &rect) == 0) {
tileWindowRefreshRect(&rect, gElevation);
}
gGameMouseHighlightedItem = NULL;
gGameMouseHighlightedItem = nullptr;
}
}
// 0x44E580
int objectIsDoor(Object* object)
{
if (object == NULL) {
if (object == nullptr) {
return false;
}
@@ -2458,4 +2464,9 @@ void gameMouseRefreshImmediately()
renderPresent();
}
Object* gmouse_get_outlined_object()
{
return gGameMouseHighlightedItem;
}
} // namespace fallout

View File

@@ -86,6 +86,7 @@ void gameMouseRefresh();
void _gmouse_handle_event(int mouseX, int mouseY, int mouseState);
int gameMouseSetCursor(int cursor);
int gameMouseGetCursor();
void gmouse_set_mapper_mode(int mode);
void gameMouseSetMode(int a1);
int gameMouseGetMode();
void gameMouseCycleMode();
@@ -102,6 +103,7 @@ void gameMouseLoadItemHighlight();
void _gmouse_remove_item_outline(Object* object);
void gameMouseRefreshImmediately();
Object* gmouse_get_outlined_object();
} // namespace fallout

View File

@@ -18,6 +18,7 @@
#include "settings.h"
#include "svga.h"
#include "text_font.h"
#include "touch.h"
#include "window_manager.h"
namespace fallout {
@@ -53,18 +54,18 @@ static const char* gMovieFileNames[MOVIE_COUNT] = {
// 0x518DE4
static const char* gMoviePaletteFilePaths[MOVIE_COUNT] = {
NULL,
nullptr,
"art\\cuts\\introsub.pal",
"art\\cuts\\eldersub.pal",
NULL,
nullptr,
"art\\cuts\\artmrsub.pal",
NULL,
NULL,
NULL,
nullptr,
nullptr,
nullptr,
"art\\cuts\\artmrsub.pal",
NULL,
NULL,
NULL,
nullptr,
nullptr,
nullptr,
"art\\cuts\\artmrsub.pal",
"art\\cuts\\artmrsub.pal",
"art\\cuts\\artmrsub.pal",
@@ -209,7 +210,7 @@ int gameMoviePlay(int movie, int flags)
int oldFont;
if (subtitlesEnabled) {
const char* subtitlesPaletteFilePath;
if (gMoviePaletteFilePaths[movie] != NULL) {
if (gMoviePaletteFilePaths[movie] != nullptr) {
subtitlesPaletteFilePath = gMoviePaletteFilePaths[movie];
} else {
subtitlesPaletteFilePath = "art\\cuts\\subtitle.pal";
@@ -249,6 +250,11 @@ int gameMoviePlay(int movie, int flags)
break;
}
Gesture gesture;
if (touch_get_gesture(&gesture) && gesture.state == kEnded) {
break;
}
int x;
int y;
_mouse_get_raw_state(&x, &y, &buttons);
@@ -332,7 +338,7 @@ static char* gameMovieBuildSubtitlesFilePath(char* movieFilePath)
char* path = movieFilePath;
char* separator = strrchr(path, '\\');
if (separator != NULL) {
if (separator != nullptr) {
path = separator + 1;
}

View File

@@ -68,16 +68,16 @@ static bool gSoundEffectsEnabled = false;
static int _gsound_active_effect_counter;
// 0x518E50
static Sound* gBackgroundSound = NULL;
static Sound* gBackgroundSound = nullptr;
// 0x518E54
static Sound* gSpeechSound = NULL;
static Sound* gSpeechSound = nullptr;
// 0x518E58
static SoundEndCallback* gBackgroundSoundEndCallback = NULL;
static SoundEndCallback* gBackgroundSoundEndCallback = nullptr;
// 0x518E5C
static SoundEndCallback* gSpeechEndCallback = NULL;
static SoundEndCallback* gSpeechEndCallback = nullptr;
// 0x518E60
static char _snd_lookup_weapon_type[WEAPON_SOUND_EFFECT_COUNT] = {
@@ -157,7 +157,7 @@ static int _gsound_speech_volume_get_set(int volume);
static void speechPause();
static void speechResume();
static void _gsound_bkg_proc();
static int gameSoundFileOpen(const char* fname, int access, ...);
static int gameSoundFileOpen(const char* fname, int* sampleRate);
static long _gsound_write_();
static long gameSoundFileTellNotImplemented(int handle);
static int gameSoundFileWrite(int handle, const void* buf, unsigned int size);
@@ -547,7 +547,7 @@ void backgroundSoundSetVolume(int volume)
}
if (gMusicEnabled) {
if (gBackgroundSound != NULL) {
if (gBackgroundSound != nullptr) {
soundSetVolume(gBackgroundSound, (int)(gMusicVolume * 0.94));
}
}
@@ -621,18 +621,18 @@ int backgroundSoundLoad(const char* fileName, int a2, int a3, int a4)
debugPrint("failed because sound could not be allocated.\n");
}
gBackgroundSound = NULL;
gBackgroundSound = nullptr;
return -1;
}
rc = soundSetFileIO(gBackgroundSound, audioFileOpen, audioFileClose, audioFileRead, NULL, audioFileSeek, gameSoundFileTellNotImplemented, audioFileGetSize);
rc = soundSetFileIO(gBackgroundSound, audioFileOpen, audioFileClose, audioFileRead, nullptr, audioFileSeek, gameSoundFileTellNotImplemented, audioFileGetSize);
if (rc != 0) {
if (gGameSoundDebugEnabled) {
debugPrint("failed because file IO could not be set for compression.\n");
}
soundDelete(gBackgroundSound);
gBackgroundSound = NULL;
gBackgroundSound = nullptr;
return -1;
}
@@ -644,7 +644,7 @@ int backgroundSoundLoad(const char* fileName, int a2, int a3, int a4)
}
soundDelete(gBackgroundSound);
gBackgroundSound = NULL;
gBackgroundSound = nullptr;
return -1;
}
@@ -662,7 +662,7 @@ int backgroundSoundLoad(const char* fileName, int a2, int a3, int a4)
}
soundDelete(gBackgroundSound);
gBackgroundSound = NULL;
gBackgroundSound = nullptr;
return -1;
}
@@ -675,13 +675,13 @@ int backgroundSoundLoad(const char* fileName, int a2, int a3, int a4)
}
soundDelete(gBackgroundSound);
gBackgroundSound = NULL;
gBackgroundSound = nullptr;
return -1;
}
}
rc = soundSetCallback(gBackgroundSound, backgroundSoundCallback, NULL);
rc = soundSetCallback(gBackgroundSound, backgroundSoundCallback, nullptr);
if (rc != SOUND_NO_ERROR) {
if (gGameSoundDebugEnabled) {
debugPrint("soundSetCallback failed for background sound\n");
@@ -704,7 +704,7 @@ int backgroundSoundLoad(const char* fileName, int a2, int a3, int a4)
}
soundDelete(gBackgroundSound);
gBackgroundSound = NULL;
gBackgroundSound = nullptr;
return -1;
}
@@ -729,7 +729,7 @@ int backgroundSoundLoad(const char* fileName, int a2, int a3, int a4)
}
soundDelete(gBackgroundSound);
gBackgroundSound = NULL;
gBackgroundSound = nullptr;
return -1;
}
@@ -753,13 +753,13 @@ void backgroundSoundDelete()
if (gGameSoundInitialized && gMusicEnabled && gBackgroundSound) {
if (_gsound_background_fade) {
if (_soundFade(gBackgroundSound, 2000, 0) == 0) {
gBackgroundSound = NULL;
gBackgroundSound = nullptr;
return;
}
}
soundDelete(gBackgroundSound);
gBackgroundSound = NULL;
gBackgroundSound = nullptr;
}
}
@@ -777,7 +777,7 @@ void backgroundSoundRestart(int value)
// 0x450B50
void backgroundSoundPause()
{
if (gBackgroundSound != NULL) {
if (gBackgroundSound != nullptr) {
soundPause(gBackgroundSound);
}
}
@@ -785,7 +785,7 @@ void backgroundSoundPause()
// 0x450B64
void backgroundSoundResume()
{
if (gBackgroundSound != NULL) {
if (gBackgroundSound != nullptr) {
soundResume(gBackgroundSound);
}
}
@@ -838,7 +838,7 @@ void speechSetVolume(int volume)
gSpeechVolume = volume;
if (gSpeechEnabled) {
if (gSpeechSound != NULL) {
if (gSpeechSound != nullptr) {
soundSetVolume(gSpeechSound, (int)(volume * 0.69));
}
}
@@ -894,16 +894,16 @@ int speechLoad(const char* fname, int a2, int a3, int a4)
if (gGameSoundDebugEnabled) {
debugPrint("failed because sound could not be allocated.\n");
}
gSpeechSound = NULL;
gSpeechSound = nullptr;
return -1;
}
if (soundSetFileIO(gSpeechSound, &audioOpen, &audioClose, &audioRead, NULL, &audioSeek, &gameSoundFileTellNotImplemented, &audioGetSize)) {
if (soundSetFileIO(gSpeechSound, audioOpen, audioClose, audioRead, nullptr, audioSeek, gameSoundFileTellNotImplemented, audioGetSize)) {
if (gGameSoundDebugEnabled) {
debugPrint("failed because file IO could not be set for compression.\n");
}
soundDelete(gSpeechSound);
gSpeechSound = NULL;
gSpeechSound = nullptr;
return -1;
}
@@ -912,7 +912,7 @@ int speechLoad(const char* fname, int a2, int a3, int a4)
debugPrint("failed because the file could not be found.\n");
}
soundDelete(gSpeechSound);
gSpeechSound = NULL;
gSpeechSound = nullptr;
return -1;
}
@@ -922,12 +922,12 @@ int speechLoad(const char* fname, int a2, int a3, int a4)
debugPrint("failed because looping could not be set.\n");
}
soundDelete(gSpeechSound);
gSpeechSound = NULL;
gSpeechSound = nullptr;
return -1;
}
}
if (soundSetCallback(gSpeechSound, speechCallback, NULL)) {
if (soundSetCallback(gSpeechSound, speechCallback, nullptr)) {
if (gGameSoundDebugEnabled) {
debugPrint("soundSetCallback failed for speech sound\n");
}
@@ -946,7 +946,7 @@ int speechLoad(const char* fname, int a2, int a3, int a4)
debugPrint("failed on call to soundLoad.\n");
}
soundDelete(gSpeechSound);
gSpeechSound = NULL;
gSpeechSound = nullptr;
return -1;
}
@@ -967,7 +967,7 @@ int speechLoad(const char* fname, int a2, int a3, int a4)
debugPrint("failed starting to play.\n");
}
soundDelete(gSpeechSound);
gSpeechSound = NULL;
gSpeechSound = nullptr;
return -1;
}
@@ -989,7 +989,7 @@ int _gsound_speech_play_preloaded()
return -1;
}
if (gSpeechSound == NULL) {
if (gSpeechSound == nullptr) {
return -1;
}
@@ -1007,7 +1007,7 @@ int _gsound_speech_play_preloaded()
if (speechPlay() != 0) {
soundDelete(gSpeechSound);
gSpeechSound = NULL;
gSpeechSound = nullptr;
return -1;
}
@@ -1019,9 +1019,9 @@ int _gsound_speech_play_preloaded()
void speechDelete()
{
if (gGameSoundInitialized && gSpeechEnabled) {
if (gSpeechSound != NULL) {
if (gSpeechSound != nullptr) {
soundDelete(gSpeechSound);
gSpeechSound = NULL;
gSpeechSound = nullptr;
}
}
}
@@ -1029,7 +1029,7 @@ void speechDelete()
// 0x451054
void speechPause()
{
if (gSpeechSound != NULL) {
if (gSpeechSound != nullptr) {
soundPause(gSpeechSound);
}
}
@@ -1037,7 +1037,7 @@ void speechPause()
// 0x451068
void speechResume()
{
if (gSpeechSound != NULL) {
if (gSpeechSound != nullptr) {
soundResume(gSpeechSound);
}
}
@@ -1055,8 +1055,8 @@ int _gsound_play_sfx_file_volume(const char* a1, int a2)
return -1;
}
v1 = soundEffectLoadWithVolume(a1, NULL, a2);
if (v1 == NULL) {
v1 = soundEffectLoadWithVolume(a1, nullptr, a2);
if (v1 == nullptr) {
return -1;
}
@@ -1069,11 +1069,11 @@ int _gsound_play_sfx_file_volume(const char* a1, int a2)
Sound* soundEffectLoad(const char* name, Object* object)
{
if (!gGameSoundInitialized) {
return NULL;
return nullptr;
}
if (!gSoundEffectsEnabled) {
return NULL;
return nullptr;
}
if (gGameSoundDebugEnabled) {
@@ -1085,16 +1085,16 @@ Sound* soundEffectLoad(const char* name, Object* object)
debugPrint("failed because there are already %d active effects.\n", _gsound_active_effect_counter);
}
return NULL;
return nullptr;
}
Sound* sound = _gsound_get_sound_ready_for_effect();
if (sound == NULL) {
if (sound == nullptr) {
if (gGameSoundDebugEnabled) {
debugPrint("failed.\n");
}
return NULL;
return nullptr;
}
++_gsound_active_effect_counter;
@@ -1110,7 +1110,7 @@ Sound* soundEffectLoad(const char* name, Object* object)
return sound;
}
if (object != NULL) {
if (object != nullptr) {
if (FID_TYPE(object->fid) == OBJ_TYPE_CRITTER && (name[0] == 'H' || name[0] == 'N')) {
char v9 = name[1];
if (v9 == 'A' || v9 == 'F' || v9 == 'M') {
@@ -1179,7 +1179,7 @@ Sound* soundEffectLoad(const char* name, Object* object)
debugPrint("failed.\n");
}
return NULL;
return nullptr;
}
// 0x45145C
@@ -1187,7 +1187,7 @@ Sound* soundEffectLoadWithVolume(const char* name, Object* object, int volume)
{
Sound* sound = soundEffectLoad(name, object);
if (sound != NULL) {
if (sound != nullptr) {
soundSetVolume(sound, (volume * gSoundEffectsVolume) / VOLUME_MAX);
}
@@ -1233,7 +1233,7 @@ int _gsnd_anim_sound(Sound* sound, void* a2)
return 0;
}
if (sound == NULL) {
if (sound == nullptr) {
return 0;
}
@@ -1253,7 +1253,7 @@ int soundEffectPlay(Sound* sound)
return -1;
}
if (sound == NULL) {
if (sound == nullptr) {
return -1;
}
@@ -1319,16 +1319,16 @@ char* sfxBuildCharName(Object* a1, int anim, int extra)
char v9;
if (artCopyFileName(FID_TYPE(a1->fid), a1->fid & 0xFFF, v7) == -1) {
return NULL;
return nullptr;
}
if (anim == ANIM_TAKE_OUT) {
if (_art_get_code(anim, extra, &v8, &v9) == -1) {
return NULL;
return nullptr;
}
} else {
if (_art_get_code(anim, (a1->fid & 0xF000) >> 12, &v8, &v9) == -1) {
return NULL;
return nullptr;
}
}
@@ -1370,7 +1370,7 @@ char* gameSoundBuildInterfaceName(const char* a1)
// 0x451760
char* sfxBuildWeaponName(int effectType, Object* weapon, int hitMode, Object* target)
{
int v6;
int soundVariant;
char weaponSoundCode;
char effectTypeCode;
char materialCode;
@@ -1384,18 +1384,18 @@ char* sfxBuildWeaponName(int effectType, Object* weapon, int hitMode, Object* ta
if (hitMode != HIT_MODE_LEFT_WEAPON_PRIMARY
&& hitMode != HIT_MODE_RIGHT_WEAPON_PRIMARY
&& hitMode != HIT_MODE_PUNCH) {
v6 = 2;
soundVariant = 2;
} else {
v6 = 1;
soundVariant = 1;
}
} else {
v6 = 1;
soundVariant = 1;
}
int damageType = weaponGetDamageType(NULL, weapon);
int damageType = weaponGetDamageType(nullptr, weapon);
// SFALL
if (effectTypeCode != 'H' || target == NULL || damageType == explosionGetDamageType() || damageType == DAMAGE_TYPE_PLASMA || damageType == DAMAGE_TYPE_EMP) {
if (effectTypeCode != 'H' || target == nullptr || damageType == explosionGetDamageType() || damageType == DAMAGE_TYPE_PLASMA || damageType == DAMAGE_TYPE_EMP) {
materialCode = 'X';
} else {
const int type = FID_TYPE(target->fid);
@@ -1438,7 +1438,7 @@ char* sfxBuildWeaponName(int effectType, Object* weapon, int hitMode, Object* ta
}
}
snprintf(_sfx_file_name, sizeof(_sfx_file_name), "W%c%c%1d%cXX%1d", effectTypeCode, weaponSoundCode, v6, materialCode, 1);
snprintf(_sfx_file_name, sizeof(_sfx_file_name), "W%c%c%1d%cXX%1d", effectTypeCode, weaponSoundCode, soundVariant, materialCode, 1);
compat_strupr(_sfx_file_name);
return _sfx_file_name;
}
@@ -1531,8 +1531,8 @@ int soundPlayFile(const char* name)
return -1;
}
Sound* sound = soundEffectLoad(name, NULL);
if (sound == NULL) {
Sound* sound = soundEffectLoad(name, nullptr);
if (sound == nullptr) {
return -1;
}
@@ -1548,14 +1548,10 @@ void _gsound_bkg_proc()
}
// 0x451A08
int gameSoundFileOpen(const char* fname, int flags, ...)
int gameSoundFileOpen(const char* fname, int* sampleRate)
{
if ((flags & 2) != 0) {
return -1;
}
File* stream = fileOpen(fname, "rb");
if (stream == NULL) {
if (stream == nullptr) {
return -1;
}
@@ -1651,7 +1647,7 @@ bool gameSoundIsCompressed(char* filePath)
void speechCallback(void* userData, int a2)
{
if (a2 == 1) {
gSpeechSound = NULL;
gSpeechSound = nullptr;
if (gSpeechEndCallback) {
gSpeechEndCallback();
@@ -1663,7 +1659,7 @@ void speechCallback(void* userData, int a2)
void backgroundSoundCallback(void* userData, int a2)
{
if (a2 == 1) {
gBackgroundSound = NULL;
gBackgroundSound = nullptr;
if (gBackgroundSoundEndCallback) {
gBackgroundSoundEndCallback();
@@ -1697,7 +1693,7 @@ int _gsound_background_allocate(Sound** soundPtr, int a2, int a3)
}
Sound* sound = soundAllocate(type, soundFlags);
if (sound == NULL) {
if (sound == nullptr) {
return -1;
}
@@ -1741,7 +1737,7 @@ int gameSoundFindBackgroundSoundPathWithCopy(char* dest, const char* src)
snprintf(inPath, sizeof(inPath), "%s%s%s", _sound_music_path2, src, ".ACM");
FILE* inStream = compat_fopen(inPath, "rb");
if (inStream == NULL) {
if (inStream == nullptr) {
if (gGameSoundDebugEnabled) {
debugPrint("Unable to find music file %s to copy down.\n", src);
}
@@ -1750,7 +1746,7 @@ int gameSoundFindBackgroundSoundPathWithCopy(char* dest, const char* src)
}
FILE* outStream = compat_fopen(outPath, "wb");
if (outStream == NULL) {
if (outStream == nullptr) {
if (gGameSoundDebugEnabled) {
debugPrint("Unable to open music file %s for copying to.", src);
}
@@ -1761,7 +1757,7 @@ int gameSoundFindBackgroundSoundPathWithCopy(char* dest, const char* src)
}
void* buffer = internal_malloc(0x2000);
if (buffer == NULL) {
if (buffer == nullptr) {
if (gGameSoundDebugEnabled) {
debugPrint("Out of memory in gsound_background_find_with_copy.\n", src);
}
@@ -1971,7 +1967,7 @@ int _gsound_get_music_path(char** out_value, const char* key)
}
copy = (char*)internal_malloc(len + 2);
if (copy == NULL) {
if (copy == nullptr) {
if (gGameSoundDebugEnabled) {
debugPrint("Out of memory in gsound_get_music_path.\n");
}
@@ -2008,7 +2004,7 @@ Sound* _gsound_get_sound_ready_for_effect()
int rc;
Sound* sound = soundAllocate(SOUND_TYPE_MEMORY | SOUND_TYPE_FIRE_AND_FORGET, SOUND_FLAG_0x02 | SOUND_16BIT);
if (sound == NULL) {
if (sound == nullptr) {
if (gGameSoundDebugEnabled) {
debugPrint(" Can't allocate sound for effect. ");
}
@@ -2017,13 +2013,13 @@ Sound* _gsound_get_sound_ready_for_effect()
debugPrint("soundAllocate returned: %d, %s\n", 0, soundGetErrorDescription(0));
}
return NULL;
return nullptr;
}
if (soundEffectsCacheInitialized()) {
rc = soundSetFileIO(sound, soundEffectsCacheFileOpen, soundEffectsCacheFileClose, soundEffectsCacheFileRead, soundEffectsCacheFileWrite, soundEffectsCacheFileSeek, soundEffectsCacheFileTell, soundEffectsCacheFileLength);
} else {
rc = soundSetFileIO(sound, audioOpen, audioClose, audioRead, NULL, audioSeek, gameSoundFileTellNotImplemented, audioGetSize);
rc = soundSetFileIO(sound, audioOpen, audioClose, audioRead, nullptr, audioSeek, gameSoundFileTellNotImplemented, audioGetSize);
}
if (rc != 0) {
@@ -2037,10 +2033,10 @@ Sound* _gsound_get_sound_ready_for_effect()
soundDelete(sound);
return NULL;
return nullptr;
}
rc = soundSetCallback(sound, soundEffectCallback, NULL);
rc = soundSetCallback(sound, soundEffectCallback, nullptr);
if (rc != 0) {
if (gGameSoundDebugEnabled) {
debugPrint("failed because the callback could not be set.\n");
@@ -2052,7 +2048,7 @@ Sound* _gsound_get_sound_ready_for_effect()
soundDelete(sound);
return NULL;
return nullptr;
}
soundSetVolume(sound, gSoundEffectsVolume);
@@ -2066,7 +2062,7 @@ Sound* _gsound_get_sound_ready_for_effect()
bool _gsound_file_exists_f(const char* fname)
{
FILE* f = compat_fopen(fname, "rb");
if (f == NULL) {
if (f == nullptr) {
return false;
}
@@ -2087,17 +2083,17 @@ int _gsound_setup_paths()
// 0x452628
int _gsound_sfx_q_start()
{
return ambientSoundEffectEventProcess(0, NULL);
return ambientSoundEffectEventProcess(nullptr, nullptr);
}
// 0x452634
int ambientSoundEffectEventProcess(Object* a1, void* data)
{
_queue_clear_type(EVENT_TYPE_GSOUND_SFX_EVENT, NULL);
_queue_clear_type(EVENT_TYPE_GSOUND_SFX_EVENT, nullptr);
AmbientSoundEffectEvent* soundEffectEvent = (AmbientSoundEffectEvent*)data;
int ambientSoundEffectIndex = -1;
if (soundEffectEvent != NULL) {
if (soundEffectEvent != nullptr) {
ambientSoundEffectIndex = soundEffectEvent->ambientSoundEffectIndex;
} else {
if (wmSfxMaxCount() > 0) {
@@ -2106,7 +2102,7 @@ int ambientSoundEffectEventProcess(Object* a1, void* data)
}
AmbientSoundEffectEvent* nextSoundEffectEvent = (AmbientSoundEffectEvent*)internal_malloc(sizeof(*nextSoundEffectEvent));
if (nextSoundEffectEvent == NULL) {
if (nextSoundEffectEvent == nullptr) {
return -1;
}
@@ -2117,7 +2113,7 @@ int ambientSoundEffectEventProcess(Object* a1, void* data)
int delay = 10 * randomBetween(15, 20);
if (wmSfxMaxCount() > 0) {
nextSoundEffectEvent->ambientSoundEffectIndex = wmSfxRollNextIdx();
if (queueAddEvent(delay, NULL, nextSoundEffectEvent, EVENT_TYPE_GSOUND_SFX_EVENT) == -1) {
if (queueAddEvent(delay, nullptr, nextSoundEffectEvent, EVENT_TYPE_GSOUND_SFX_EVENT) == -1) {
return -1;
}
}

View File

@@ -9,12 +9,12 @@
namespace fallout {
// 0x51DEF4
static RectListNode* _rectList = NULL;
static RectListNode* _rectList = nullptr;
// 0x4C6900
void _GNW_rect_exit()
{
while (_rectList != NULL) {
while (_rectList != nullptr) {
RectListNode* next = _rectList->next;
internal_free(_rectList);
_rectList = next;
@@ -28,7 +28,7 @@ void _rect_clip_list(RectListNode** rectListNodePtr, Rect* rect)
rectCopy(&v1, rect);
// NOTE: Original code is slightly different.
while (*rectListNodePtr != NULL) {
while (*rectListNodePtr != nullptr) {
RectListNode* rectListNode = *rectListNodePtr;
if (v1.right >= rectListNode->rect.left
&& v1.bottom >= rectListNode->rect.top
@@ -44,7 +44,7 @@ void _rect_clip_list(RectListNode** rectListNodePtr, Rect* rect)
if (v2.top < v1.top) {
RectListNode* newRectListNode = _rect_malloc();
if (newRectListNode == NULL) {
if (newRectListNode == nullptr) {
return;
}
@@ -60,7 +60,7 @@ void _rect_clip_list(RectListNode** rectListNodePtr, Rect* rect)
if (v2.bottom > v1.bottom) {
RectListNode* newRectListNode = _rect_malloc();
if (newRectListNode == NULL) {
if (newRectListNode == nullptr) {
return;
}
@@ -76,7 +76,7 @@ void _rect_clip_list(RectListNode** rectListNodePtr, Rect* rect)
if (v2.left < v1.left) {
RectListNode* newRectListNode = _rect_malloc();
if (newRectListNode == NULL) {
if (newRectListNode == nullptr) {
return;
}
@@ -90,7 +90,7 @@ void _rect_clip_list(RectListNode** rectListNodePtr, Rect* rect)
if (v2.right > v1.right) {
RectListNode* newRectListNode = _rect_malloc();
if (newRectListNode == NULL) {
if (newRectListNode == nullptr) {
return;
}
@@ -107,13 +107,69 @@ void _rect_clip_list(RectListNode** rectListNodePtr, Rect* rect)
}
}
// 0x4C6AAC
RectListNode* rect_clip(Rect* b, Rect* t)
{
RectListNode* list = nullptr;
Rect clipped_t;
if (rectIntersection(t, b, &clipped_t) == 0) {
RectListNode** next = &list;
Rect clipped_b[4];
int k;
clipped_b[0].left = b->left;
clipped_b[0].top = b->top;
clipped_b[0].right = b->right;
clipped_b[0].bottom = clipped_t.top - 1;
clipped_b[1].left = b->left;
clipped_b[1].top = clipped_t.top;
clipped_b[1].right = clipped_t.left - 1;
clipped_b[1].bottom = clipped_t.bottom;
clipped_b[2].left = clipped_t.right + 1;
clipped_b[2].top = clipped_t.top;
clipped_b[2].right = b->right;
clipped_b[2].bottom = clipped_t.bottom;
clipped_b[3].left = b->left;
clipped_b[3].top = clipped_t.bottom + 1;
clipped_b[3].right = b->right;
clipped_b[3].bottom = b->bottom;
for (k = 0; k < 4; k++) {
if (clipped_b[k].left <= clipped_b[k].right && clipped_b[k].top <= clipped_b[k].bottom) {
*next = _rect_malloc();
if (*next == nullptr) {
return nullptr;
}
(*next)->rect = clipped_b[k];
(*next)->next = nullptr;
next = &((*next)->next);
}
}
} else {
list = _rect_malloc();
if (list == nullptr) {
return nullptr;
}
list->rect = *b;
list->next = nullptr;
}
return list;
}
// 0x4C6BB8
RectListNode* _rect_malloc()
{
if (_rectList == NULL) {
if (_rectList == nullptr) {
for (int index = 0; index < 10; index++) {
RectListNode* rectListNode = (RectListNode*)internal_malloc(sizeof(*rectListNode));
if (rectListNode == NULL) {
if (rectListNode == nullptr) {
break;
}
@@ -122,8 +178,8 @@ RectListNode* _rect_malloc()
}
}
if (_rectList == NULL) {
return NULL;
if (_rectList == nullptr) {
return nullptr;
}
RectListNode* rectListNode = _rectList;

View File

@@ -27,6 +27,7 @@ typedef struct RectListNode {
void _GNW_rect_exit();
void _rect_clip_list(RectListNode** rectListNodePtr, Rect* rect);
RectListNode* rect_clip(Rect* b, Rect* t);
RectListNode* _rect_malloc();
void _rect_free(RectListNode* entry);
void rectUnion(const Rect* s1, const Rect* s2, Rect* r);

View File

@@ -52,13 +52,21 @@ unsigned char HighRGB(unsigned char color)
return std::max(std::max(r, g), b);
}
// 0x44ED98
int load_lbm_to_buf(const char* path, unsigned char* buffer, int a3, int a4, int a5, int a6, int a7)
{
// TODO: Incomplete.
return -1;
}
// 0x44F250
int graphCompress(unsigned char* a1, unsigned char* a2, int a3)
{
_dad_2 = NULL;
_rson = NULL;
_lson = NULL;
_text_buf = NULL;
_dad_2 = nullptr;
_rson = nullptr;
_lson = nullptr;
_text_buf = nullptr;
// NOTE: Original code is slightly different, it uses deep nesting or a
// bunch of gotos.
@@ -67,20 +75,20 @@ int graphCompress(unsigned char* a1, unsigned char* a2, int a3)
_dad_2 = (int*)internal_malloc(sizeof(*_dad_2) * 4104);
_text_buf = (unsigned char*)internal_malloc(sizeof(*_text_buf) * 4122);
if (_lson == NULL || _rson == NULL || _dad_2 == NULL || _text_buf == NULL) {
if (_lson == nullptr || _rson == nullptr || _dad_2 == nullptr || _text_buf == nullptr) {
debugPrint("\nGRAPHLIB: Error allocating compression buffers!\n");
if (_dad_2 != NULL) {
if (_dad_2 != nullptr) {
internal_free(_dad_2);
}
if (_rson != NULL) {
if (_rson != nullptr) {
internal_free(_rson);
}
if (_lson != NULL) {
if (_lson != nullptr) {
internal_free(_lson);
}
if (_text_buf != NULL) {
if (_text_buf != nullptr) {
internal_free(_text_buf);
}
@@ -347,7 +355,7 @@ static void _DeleteNode(int a1)
int graphDecompress(unsigned char* src, unsigned char* dest, int length)
{
_text_buf = (unsigned char*)internal_malloc(sizeof(*_text_buf) * 4122);
if (_text_buf == NULL) {
if (_text_buf == nullptr) {
debugPrint("\nGRAPHLIB: Error allocating decompression buffer!\n");
return -1;
}

View File

@@ -4,6 +4,7 @@
namespace fallout {
unsigned char HighRGB(unsigned char color);
int load_lbm_to_buf(const char* path, unsigned char* buffer, int a3, int a4, int a5, int a6, int a7);
int graphCompress(unsigned char* a1, unsigned char* a2, int a3);
int graphDecompress(unsigned char* a1, unsigned char* a2, int a3);
void grayscalePaletteUpdate(int a1, int a2);

View File

@@ -85,23 +85,23 @@ static bool heapBuildMoveableBlocksList(int extentIndex);
// An array of pointers to free heap blocks.
//
// 0x518E9C
static unsigned char** gHeapFreeBlocks = NULL;
static unsigned char** gHeapFreeBlocks = nullptr;
// An array of moveable extents in heap.
//
// 0x518EA0
static HeapMoveableExtent* gHeapMoveableExtents = NULL;
static HeapMoveableExtent* gHeapMoveableExtents = nullptr;
// An array of pointers to moveable heap blocks.
//
// 0x518EA4
static unsigned char** gHeapMoveableBlocks = NULL;
static unsigned char** gHeapMoveableBlocks = nullptr;
// An array of indexes into [gHeapFreeBlocks] array to track which free blocks
// were already reserved for subsequent moving.
//
// 0x518EA8
static int* gHeapReservedFreeBlockIndexes = NULL;
static int* gHeapReservedFreeBlockIndexes = nullptr;
// The length of the [gHeapFreeBlocks] array.
//
@@ -139,26 +139,26 @@ static bool heapInternalsInit()
// it has failed.
do {
gHeapFreeBlocks = (unsigned char**)internal_malloc(sizeof(*gHeapFreeBlocks) * HEAP_FREE_BLOCKS_INITIAL_LENGTH);
if (gHeapFreeBlocks == NULL) {
if (gHeapFreeBlocks == nullptr) {
break;
}
gHeapFreeBlocksLength = HEAP_FREE_BLOCKS_INITIAL_LENGTH;
gHeapMoveableExtents = (HeapMoveableExtent*)internal_malloc(sizeof(*gHeapMoveableExtents) * HEAP_MOVEABLE_EXTENTS_INITIAL_LENGTH);
if (gHeapMoveableExtents == NULL) {
if (gHeapMoveableExtents == nullptr) {
break;
}
gHeapMoveableExtentsLength = HEAP_MOVEABLE_EXTENTS_INITIAL_LENGTH;
gHeapMoveableBlocks = (unsigned char**)internal_malloc(sizeof(*gHeapMoveableBlocks) * HEAP_MOVEABLE_BLOCKS_INITIAL_LENGTH);
if (gHeapMoveableBlocks == NULL) {
if (gHeapMoveableBlocks == nullptr) {
break;
}
gHeapMoveableBlocksLength = HEAP_MOVEABLE_BLOCKS_INITIAL_LENGTH;
gHeapReservedFreeBlockIndexes = (int*)internal_malloc(sizeof(*gHeapReservedFreeBlockIndexes) * HEAP_RESERVED_FREE_BLOCK_INDEXES_INITIAL_LENGTH);
if (gHeapReservedFreeBlockIndexes == NULL) {
if (gHeapReservedFreeBlockIndexes == nullptr) {
break;
}
gHeapReservedFreeBlockIndexesLength = HEAP_RESERVED_FREE_BLOCK_INDEXES_INITIAL_LENGTH;
@@ -175,27 +175,27 @@ static bool heapInternalsInit()
// 0x4533A0
static void heapInternalsFree()
{
if (gHeapReservedFreeBlockIndexes != NULL) {
if (gHeapReservedFreeBlockIndexes != nullptr) {
internal_free(gHeapReservedFreeBlockIndexes);
gHeapReservedFreeBlockIndexes = NULL;
gHeapReservedFreeBlockIndexes = nullptr;
}
gHeapReservedFreeBlockIndexesLength = 0;
if (gHeapMoveableBlocks != NULL) {
if (gHeapMoveableBlocks != nullptr) {
internal_free(gHeapMoveableBlocks);
gHeapMoveableBlocks = NULL;
gHeapMoveableBlocks = nullptr;
}
gHeapMoveableBlocksLength = 0;
if (gHeapMoveableExtents != NULL) {
if (gHeapMoveableExtents != nullptr) {
internal_free(gHeapMoveableExtents);
gHeapMoveableExtents = NULL;
gHeapMoveableExtents = nullptr;
}
gHeapMoveableExtentsLength = 0;
if (gHeapFreeBlocks != NULL) {
if (gHeapFreeBlocks != nullptr) {
internal_free(gHeapFreeBlocks);
gHeapFreeBlocks = NULL;
gHeapFreeBlocks = nullptr;
}
gHeapFreeBlocksLength = 0;
}
@@ -203,7 +203,7 @@ static void heapInternalsFree()
// 0x452974
bool heapInit(Heap* heap, int a2)
{
if (heap == NULL) {
if (heap == nullptr) {
return false;
}
@@ -218,7 +218,7 @@ bool heapInit(Heap* heap, int a2)
if (heapHandleListInit(heap)) {
int size = (a2 >> 10) + a2;
heap->data = (unsigned char*)internal_malloc(size);
if (heap->data != NULL) {
if (heap->data != nullptr) {
heap->size = size;
heap->freeBlocks = 1;
heap->freeSize = heap->size - HEAP_BLOCK_OVERHEAD_SIZE;
@@ -248,24 +248,24 @@ bool heapInit(Heap* heap, int a2)
// 0x452A3C
bool heapFree(Heap* heap)
{
if (heap == NULL) {
if (heap == nullptr) {
return false;
}
for (int index = 0; index < heap->handlesLength; index++) {
HeapHandle* handle = &(heap->handles[index]);
if (handle->state == 4 && handle->data != NULL) {
if (handle->state == 4 && handle->data != nullptr) {
internal_free(handle->data);
}
}
if (heap->handles != NULL) {
if (heap->handles != nullptr) {
internal_free(heap->handles);
heap->handles = NULL;
heap->handles = nullptr;
heap->handlesLength = 0;
}
if (heap->data != NULL) {
if (heap->data != nullptr) {
internal_free(heap->data);
}
@@ -283,7 +283,7 @@ bool heapFree(Heap* heap)
static bool heapHandleListInit(Heap* heap)
{
heap->handles = (HeapHandle*)internal_malloc(sizeof(*heap->handles) * HEAP_HANDLES_INITIAL_LENGTH);
if (heap->handles == NULL) {
if (heap->handles == nullptr) {
debugPrint("Heap Error : Could not initialize handles.\n");
return false;
}
@@ -291,7 +291,7 @@ static bool heapHandleListInit(Heap* heap)
for (int index = 0; index < HEAP_HANDLES_INITIAL_LENGTH; index++) {
HeapHandle* handle = &(heap->handles[index]);
handle->state = HEAP_HANDLE_STATE_INVALID;
handle->data = NULL;
handle->data = nullptr;
}
heap->handlesLength = HEAP_HANDLES_INITIAL_LENGTH;
@@ -309,7 +309,7 @@ bool heapBlockAllocate(Heap* heap, int* handleIndexPtr, int size, int a4)
size += 4 - size % 4;
if (heap == NULL || handleIndexPtr == NULL || size == 0) {
if (heap == nullptr || handleIndexPtr == nullptr || size == 0) {
goto err;
}
@@ -401,7 +401,7 @@ bool heapBlockAllocate(Heap* heap, int* handleIndexPtr, int size, int a4)
}
handle->state = HEAP_HANDLE_STATE_INVALID;
handle->data = NULL;
handle->data = nullptr;
debugPrint("Heap Error: Unknown block state during allocation.\n");
@@ -422,7 +422,7 @@ err:
// 0x452CB4
bool heapBlockDeallocate(Heap* heap, int* handleIndexPtr)
{
if (heap == NULL || handleIndexPtr == NULL) {
if (heap == nullptr || handleIndexPtr == nullptr) {
debugPrint("Heap Error: Could not deallocate block.\n");
return false;
}
@@ -466,7 +466,7 @@ bool heapBlockDeallocate(Heap* heap, int* handleIndexPtr)
// Reset handle
handle->state = HEAP_HANDLE_STATE_INVALID;
handle->data = NULL;
handle->data = nullptr;
return true;
}
@@ -481,7 +481,7 @@ bool heapBlockDeallocate(Heap* heap, int* handleIndexPtr)
// Reset handle
handle->state = HEAP_HANDLE_STATE_INVALID;
handle->data = NULL;
handle->data = nullptr;
return true;
}
@@ -493,7 +493,7 @@ bool heapBlockDeallocate(Heap* heap, int* handleIndexPtr)
// 0x452DE0
bool heapLock(Heap* heap, int handleIndex, unsigned char** bufferPtr)
{
if (heap == NULL) {
if (heap == nullptr) {
debugPrint("Heap Error: Could not lock block");
return false;
}
@@ -554,7 +554,7 @@ bool heapLock(Heap* heap, int handleIndex, unsigned char** bufferPtr)
// 0x452EE4
bool heapUnlock(Heap* heap, int handleIndex)
{
if (heap == NULL) {
if (heap == nullptr) {
debugPrint("Heap Error: Could not unlock block.\n");
return false;
}
@@ -603,7 +603,7 @@ bool heapUnlock(Heap* heap, int handleIndex)
// 0x4532AC
static bool heapPrintStats(Heap* heap, char* dest, size_t size)
{
if (heap == NULL || dest == NULL) {
if (heap == nullptr || dest == nullptr) {
return false;
}
@@ -649,7 +649,7 @@ static bool heapFindFreeHandle(Heap* heap, int* handleIndexPtr)
// If we're here the search above failed, we have to allocate more handles.
HeapHandle* handles = (HeapHandle*)internal_realloc(heap->handles, sizeof(*handles) * (heap->handlesLength + HEAP_HANDLES_INITIAL_LENGTH));
if (handles == NULL) {
if (handles == nullptr) {
return false;
}
@@ -659,7 +659,7 @@ static bool heapFindFreeHandle(Heap* heap, int* handleIndexPtr)
for (int index = heap->handlesLength; index < heap->handlesLength + HEAP_HANDLES_INITIAL_LENGTH; index++) {
HeapHandle* handle = &(heap->handles[index]);
handle->state = HEAP_HANDLE_STATE_INVALID;
handle->data = NULL;
handle->data = nullptr;
}
*handleIndexPtr = heap->handlesLength;
@@ -725,7 +725,7 @@ static bool heapFindFreeBlock(Heap* heap, int size, void** blockPtr, int a4)
// to index all blocks for longest moveable extent.
if (maxBlocksCount > gHeapReservedFreeBlockIndexesLength) {
int* indexes = (int*)internal_realloc(gHeapReservedFreeBlockIndexes, sizeof(*gHeapReservedFreeBlockIndexes) * maxBlocksCount);
if (indexes == NULL) {
if (indexes == nullptr) {
goto system;
}
@@ -921,7 +921,7 @@ system:
if (a4 == 0) {
debugPrint("Allocating block from system memory...\n");
unsigned char* block = (unsigned char*)internal_malloc(size + HEAP_BLOCK_OVERHEAD_SIZE);
if (block == NULL) {
if (block == nullptr) {
debugPrint("fatal error: internal_malloc() failed in heap_find_free_block()!\n");
return false;
}
@@ -952,7 +952,7 @@ static bool heapBuildMoveableBlocksList(int extentIndex)
HeapMoveableExtent* extent = &(gHeapMoveableExtents[extentIndex]);
if (extent->moveableBlocksLength > gHeapMoveableBlocksLength) {
unsigned char** moveableBlocks = (unsigned char**)internal_realloc(gHeapMoveableBlocks, sizeof(*gHeapMoveableBlocks) * extent->moveableBlocksLength);
if (moveableBlocks == NULL) {
if (moveableBlocks == nullptr) {
return false;
}
@@ -990,7 +990,7 @@ static bool heapBuildFreeBlocksList(Heap* heap)
if (heap->freeBlocks > gHeapFreeBlocksLength) {
unsigned char** freeBlocks = (unsigned char**)internal_realloc(gHeapFreeBlocks, sizeof(*freeBlocks) * heap->freeBlocks);
if (freeBlocks == NULL) {
if (freeBlocks == nullptr) {
return false;
}
@@ -1063,7 +1063,7 @@ static bool heapBuildMoveableExtentsList(Heap* heap, int* moveableExtentsLengthP
if (maxExtentsCount > gHeapMoveableExtentsLength) {
HeapMoveableExtent* moveableExtents = (HeapMoveableExtent*)internal_realloc(gHeapMoveableExtents, sizeof(*gHeapMoveableExtents) * maxExtentsCount);
if (moveableExtents == NULL) {
if (moveableExtents == nullptr) {
return false;
}

View File

@@ -4,6 +4,7 @@
#include "audio_engine.h"
#include "color.h"
#include "delay.h"
#include "dinput.h"
#include "draw.h"
#include "kb.h"
@@ -11,6 +12,7 @@
#include "mouse.h"
#include "svga.h"
#include "text_font.h"
#include "touch.h"
#include "vcr.h"
#include "win32.h"
@@ -47,10 +49,10 @@ static void _GNW95_process_key(KeyboardData* data);
static void idleImpl();
// 0x51E234
static IdleFunc* _idle_func = NULL;
static IdleFunc* _idle_func = nullptr;
// 0x51E238
static FocusFunc* _focus_func = NULL;
static FocusFunc* _focus_func = nullptr;
// 0x51E23C
static int gKeyboardKeyRepeatRate = 80;
@@ -148,7 +150,7 @@ int inputInit(int a1)
gPauseKeyCode = KEY_ALT_P;
gPauseHandler = pauseHandlerDefaultImpl;
gScreenshotHandler = screenshotHandlerDefaultImpl;
gTickerListHead = NULL;
gTickerListHead = nullptr;
gScreenshotKeyCode = KEY_ALT_C;
// SFALL: Set idle function.
@@ -167,7 +169,7 @@ void inputExit()
directInputFree();
TickerListNode* curr = gTickerListHead;
while (curr != NULL) {
while (curr != nullptr) {
TickerListNode* next = curr->next;
internal_free(curr);
curr = next;
@@ -198,6 +200,13 @@ int inputGetInput()
return -1;
}
// 0x4C8BC8
void get_input_position(int* x, int* y)
{
*x = _input_mx;
*y = _input_my;
}
// 0x4C8BDC
void _process_bk()
{
@@ -309,7 +318,7 @@ void tickersExecute()
TickerListNode* curr = gTickerListHead;
TickerListNode** currPtr = &(gTickerListHead);
while (curr != NULL) {
while (curr != nullptr) {
TickerListNode* next = curr->next;
if (curr->flags & 1) {
*currPtr = next;
@@ -327,7 +336,7 @@ void tickersExecute()
void tickersAdd(TickerProc* proc)
{
TickerListNode* curr = gTickerListHead;
while (curr != NULL) {
while (curr != nullptr) {
if (curr->proc == proc) {
if ((curr->flags & 0x01) != 0) {
curr->flags &= ~0x01;
@@ -348,7 +357,7 @@ void tickersAdd(TickerProc* proc)
void tickersRemove(TickerProc* proc)
{
TickerListNode* curr = gTickerListHead;
while (curr != NULL) {
while (curr != nullptr) {
if (curr->proc == proc) {
curr->flags |= 0x01;
return;
@@ -430,7 +439,7 @@ void pauseHandlerConfigure(int keyCode, PauseHandler* handler)
{
gPauseKeyCode = keyCode;
if (handler == NULL) {
if (handler == nullptr) {
handler = pauseHandlerDefaultImpl;
}
@@ -443,7 +452,7 @@ void takeScreenshot()
int width = _scr_size.right - _scr_size.left + 1;
int height = _scr_size.bottom - _scr_size.top + 1;
gScreenshotBuffer = (unsigned char*)internal_malloc(width * height);
if (gScreenshotBuffer == NULL) {
if (gScreenshotBuffer == nullptr) {
return;
}
@@ -454,7 +463,7 @@ void takeScreenshot()
_mouse_blit = screenshotBlitter;
WindowDrawingProc2* v1 = _mouse_blit_trans;
_mouse_blit_trans = NULL;
_mouse_blit_trans = nullptr;
windowRefreshAll(&_scr_size);
@@ -487,7 +496,7 @@ int screenshotHandlerDefaultImpl(int width, int height, unsigned char* data, uns
snprintf(fileName, sizeof(fileName), "scr%.5d.bmp", index);
stream = compat_fopen(fileName, "rb");
if (stream == NULL) {
if (stream == nullptr) {
break;
}
@@ -499,7 +508,7 @@ int screenshotHandlerDefaultImpl(int width, int height, unsigned char* data, uns
}
stream = compat_fopen(fileName, "wb");
if (stream == NULL) {
if (stream == nullptr) {
return -1;
}
@@ -598,7 +607,7 @@ void screenshotHandlerConfigure(int keyCode, ScreenshotHandler* handler)
{
gScreenshotKeyCode = keyCode;
if (handler == NULL) {
if (handler == nullptr) {
handler = screenshotHandlerDefaultImpl;
}
@@ -633,12 +642,7 @@ void inputPauseForTocks(unsigned int delay)
// 0x4C93B8
void inputBlockForTocks(unsigned int ms)
{
unsigned int start = SDL_GetTicks();
unsigned int diff;
do {
// NOTE: Uninline
diff = getTicksSince(start);
} while (diff < ms);
delay_ms(ms);
}
// 0x4C93E0
@@ -1026,24 +1030,24 @@ static void buildNormalizedQwertyKeys()
keys[SDL_SCANCODE_F13] = -1;
keys[SDL_SCANCODE_F14] = -1;
keys[SDL_SCANCODE_F15] = -1;
//keys[DIK_KANA] = -1;
//keys[DIK_CONVERT] = -1;
//keys[DIK_NOCONVERT] = -1;
//keys[DIK_YEN] = -1;
// keys[DIK_KANA] = -1;
// keys[DIK_CONVERT] = -1;
// keys[DIK_NOCONVERT] = -1;
// keys[DIK_YEN] = -1;
keys[SDL_SCANCODE_KP_EQUALS] = -1;
//keys[DIK_PREVTRACK] = -1;
//keys[DIK_AT] = -1;
//keys[DIK_COLON] = -1;
//keys[DIK_UNDERLINE] = -1;
//keys[DIK_KANJI] = -1;
// keys[DIK_PREVTRACK] = -1;
// keys[DIK_AT] = -1;
// keys[DIK_COLON] = -1;
// keys[DIK_UNDERLINE] = -1;
// keys[DIK_KANJI] = -1;
keys[SDL_SCANCODE_STOP] = -1;
//keys[DIK_AX] = -1;
//keys[DIK_UNLABELED] = -1;
// keys[DIK_AX] = -1;
// keys[DIK_UNLABELED] = -1;
keys[SDL_SCANCODE_KP_ENTER] = SDL_SCANCODE_KP_ENTER;
keys[SDL_SCANCODE_RCTRL] = SDL_SCANCODE_RCTRL;
keys[SDL_SCANCODE_KP_COMMA] = -1;
keys[SDL_SCANCODE_KP_DIVIDE] = SDL_SCANCODE_KP_DIVIDE;
//keys[DIK_SYSRQ] = 84;
// keys[DIK_SYSRQ] = 84;
keys[SDL_SCANCODE_RALT] = SDL_SCANCODE_RALT;
keys[SDL_SCANCODE_HOME] = SDL_SCANCODE_HOME;
keys[SDL_SCANCODE_UP] = SDL_SCANCODE_UP;
@@ -1084,9 +1088,13 @@ void _GNW95_process_message()
handleMouseEvent(&e);
break;
case SDL_FINGERDOWN:
touch_handle_start(&(e.tfinger));
break;
case SDL_FINGERMOTION:
touch_handle_move(&(e.tfinger));
break;
case SDL_FINGERUP:
handleTouchEvent(&e);
touch_handle_end(&(e.tfinger));
break;
case SDL_KEYDOWN:
case SDL_KEYUP:
@@ -1121,6 +1129,8 @@ void _GNW95_process_message()
}
}
touch_process_gesture();
if (gProgramIsActive && !keyboardIsDisabled()) {
// NOTE: Uninline
int tick = getTicks();
@@ -1187,19 +1197,19 @@ static void _GNW95_process_key(KeyboardData* data)
// 0x4C9EEC
void _GNW95_lost_focus()
{
if (_focus_func != NULL) {
if (_focus_func != nullptr) {
_focus_func(false);
}
while (!gProgramIsActive) {
_GNW95_process_message();
if (_idle_func != NULL) {
if (_idle_func != nullptr) {
_idle_func();
}
}
if (_focus_func != NULL) {
if (_focus_func != nullptr) {
_focus_func(true);
}
}

View File

@@ -13,6 +13,7 @@ typedef int(ScreenshotHandler)(int width, int height, unsigned char* buffer, uns
int inputInit(int a1);
void inputExit();
int inputGetInput();
void get_input_position(int* x, int* y);
void _process_bk();
void enqueueInputEvent(int a1);
void inputEventQueueReset();

View File

@@ -194,11 +194,11 @@ static Rect gInterfaceBarActionPointsBarRect;
// 0x518FE8
static IndicatorDescription gIndicatorDescriptions[INDICATOR_COUNT] = {
{ 102, true, NULL }, // ADDICT
{ 100, false, NULL }, // SNEAK
{ 101, false, NULL }, // LEVEL
{ 103, true, NULL }, // POISONED
{ 104, true, NULL }, // RADIATED
{ 102, true, nullptr }, // ADDICT
{ 100, false, nullptr }, // SNEAK
{ 101, false, nullptr }, // LEVEL
{ 103, true, nullptr }, // POISONED
{ 104, true, nullptr }, // RADIATED
};
// 0x519024
@@ -327,7 +327,7 @@ int interfaceInit()
}
gInterfaceWindowBuffer = windowGetBuffer(gInterfaceBarWindow);
if (gInterfaceWindowBuffer == NULL) {
if (gInterfaceWindowBuffer == nullptr) {
// NOTE: Uninline.
return intface_fatal_error(-1);
}
@@ -357,7 +357,7 @@ int interfaceInit()
return intface_fatal_error(-1);
}
gInventoryButton = buttonCreate(gInterfaceBarWindow, 211 + gInterfaceBarContentOffset, 40, 32, 21, -1, -1, -1, KEY_LOWERCASE_I, _inventoryButtonNormalFrmImage.getData(), _inventoryButtonPressedFrmImage.getData(), NULL, 0);
gInventoryButton = buttonCreate(gInterfaceBarWindow, 211 + gInterfaceBarContentOffset, 40, 32, 21, -1, -1, -1, KEY_LOWERCASE_I, _inventoryButtonNormalFrmImage.getData(), _inventoryButtonPressedFrmImage.getData(), nullptr, 0);
if (gInventoryButton == -1) {
// NOTE: Uninline.
return intface_fatal_error(-1);
@@ -377,7 +377,7 @@ int interfaceInit()
return intface_fatal_error(-1);
}
gOptionsButton = buttonCreate(gInterfaceBarWindow, 210 + gInterfaceBarContentOffset, 61, 34, 34, -1, -1, -1, KEY_LOWERCASE_O, _optionsButtonNormalFrmImage.getData(), _optionsButtonPressedFrmImage.getData(), NULL, 0);
gOptionsButton = buttonCreate(gInterfaceBarWindow, 210 + gInterfaceBarContentOffset, 61, 34, 34, -1, -1, -1, KEY_LOWERCASE_O, _optionsButtonNormalFrmImage.getData(), _optionsButtonPressedFrmImage.getData(), nullptr, 0);
if (gOptionsButton == -1) {
// NOTE: Uninline.
return intface_fatal_error(-1);
@@ -403,7 +403,7 @@ int interfaceInit()
return intface_fatal_error(-1);
}
gSkilldexButton = buttonCreate(gInterfaceBarWindow, 523 + gInterfaceBarContentOffset, 6, 22, 21, -1, -1, -1, KEY_LOWERCASE_S, _skilldexButtonNormalFrmImage.getData(), _skilldexButtonPressedFrmImage.getData(), NULL, BUTTON_FLAG_TRANSPARENT);
gSkilldexButton = buttonCreate(gInterfaceBarWindow, 523 + gInterfaceBarContentOffset, 6, 22, 21, -1, -1, -1, KEY_LOWERCASE_S, _skilldexButtonNormalFrmImage.getData(), _skilldexButtonPressedFrmImage.getData(), nullptr, BUTTON_FLAG_TRANSPARENT);
if (gSkilldexButton == -1) {
// NOTE: Uninline.
return intface_fatal_error(-1);
@@ -430,7 +430,7 @@ int interfaceInit()
return intface_fatal_error(-1);
}
gMapButton = buttonCreate(gInterfaceBarWindow, 526 + gInterfaceBarContentOffset, 39, 41, 19, -1, -1, -1, KEY_TAB, _mapButtonNormalFrmImage.getData(), _mapButtonPressedFrmImage.getData(), NULL, BUTTON_FLAG_TRANSPARENT);
gMapButton = buttonCreate(gInterfaceBarWindow, 526 + gInterfaceBarContentOffset, 39, 41, 19, -1, -1, -1, KEY_TAB, _mapButtonNormalFrmImage.getData(), _mapButtonPressedFrmImage.getData(), nullptr, BUTTON_FLAG_TRANSPARENT);
if (gMapButton == -1) {
// NOTE: Uninline.
return intface_fatal_error(-1);
@@ -451,7 +451,7 @@ int interfaceInit()
return intface_fatal_error(-1);
}
gPipboyButton = buttonCreate(gInterfaceBarWindow, 526 + gInterfaceBarContentOffset, 77, 41, 19, -1, -1, -1, KEY_LOWERCASE_P, _pipboyButtonNormalFrmImage.getData(), _pipboyButtonPressedFrmImage.getData(), NULL, 0);
gPipboyButton = buttonCreate(gInterfaceBarWindow, 526 + gInterfaceBarContentOffset, 77, 41, 19, -1, -1, -1, KEY_LOWERCASE_P, _pipboyButtonNormalFrmImage.getData(), _pipboyButtonPressedFrmImage.getData(), nullptr, 0);
if (gPipboyButton == -1) {
// NOTE: Uninline.
return intface_fatal_error(-1);
@@ -472,7 +472,7 @@ int interfaceInit()
return intface_fatal_error(-1);
}
gCharacterButton = buttonCreate(gInterfaceBarWindow, 526 + gInterfaceBarContentOffset, 58, 41, 19, -1, -1, -1, KEY_LOWERCASE_C, _characterButtonNormalFrmImage.getData(), _characterButtonPressedFrmImage.getData(), NULL, 0);
gCharacterButton = buttonCreate(gInterfaceBarWindow, 526 + gInterfaceBarContentOffset, 58, 41, 19, -1, -1, -1, KEY_LOWERCASE_C, _characterButtonNormalFrmImage.getData(), _characterButtonPressedFrmImage.getData(), nullptr, 0);
if (gCharacterButton == -1) {
// NOTE: Uninline.
return intface_fatal_error(-1);
@@ -502,13 +502,13 @@ int interfaceInit()
memcpy(_itemButtonUp, _itemButtonNormalFrmImage.getData(), sizeof(_itemButtonUp));
memcpy(_itemButtonDown, _itemButtonPressedFrmImage.getData(), sizeof(_itemButtonDown));
gSingleAttackButton = buttonCreate(gInterfaceBarWindow, 267 + gInterfaceBarContentOffset, 26, 188, 67, -1, -1, -1, -20, _itemButtonUp, _itemButtonDown, NULL, BUTTON_FLAG_TRANSPARENT);
gSingleAttackButton = buttonCreate(gInterfaceBarWindow, 267 + gInterfaceBarContentOffset, 26, 188, 67, -1, -1, -1, -20, _itemButtonUp, _itemButtonDown, nullptr, BUTTON_FLAG_TRANSPARENT);
if (gSingleAttackButton == -1) {
// NOTE: Uninline.
return intface_fatal_error(-1);
}
buttonSetRightMouseCallbacks(gSingleAttackButton, -1, KEY_LOWERCASE_N, NULL, NULL);
buttonSetRightMouseCallbacks(gSingleAttackButton, -1, KEY_LOWERCASE_N, nullptr, nullptr);
buttonSetCallbacks(gSingleAttackButton, _gsound_lrg_butt_press, _gsound_lrg_butt_release);
fid = buildFid(OBJ_TYPE_INTERFACE, 6, 0, 0, 0);
@@ -530,7 +530,7 @@ int interfaceInit()
}
// Swap hands button
gChangeHandsButton = buttonCreate(gInterfaceBarWindow, 218 + gInterfaceBarContentOffset, 6, 22, 21, -1, -1, -1, KEY_LOWERCASE_B, _changeHandsButtonNormalFrmImage.getData(), _changeHandsButtonPressedFrmImage.getData(), NULL, BUTTON_FLAG_TRANSPARENT);
gChangeHandsButton = buttonCreate(gInterfaceBarWindow, 218 + gInterfaceBarContentOffset, 6, 22, 21, -1, -1, -1, KEY_LOWERCASE_B, _changeHandsButtonNormalFrmImage.getData(), _changeHandsButtonPressedFrmImage.getData(), nullptr, BUTTON_FLAG_TRANSPARENT);
if (gChangeHandsButton == -1) {
// NOTE: Uninline.
return intface_fatal_error(-1);
@@ -1053,8 +1053,8 @@ int interfaceUpdateItems(bool animated, int leftItemAction, int rightItemAction)
InterfaceItemState* leftItemState = &(gInterfaceItemStates[HAND_LEFT]);
Object* item1 = critterGetItem1(gDude);
if (item1 == leftItemState->item && leftItemState->item != NULL) {
if (leftItemState->item != NULL) {
if (item1 == leftItemState->item && leftItemState->item != nullptr) {
if (leftItemState->item != nullptr) {
leftItemState->isDisabled = dudeIsWeaponDisabled(item1);
leftItemState->itemFid = itemGetInventoryFid(item1);
}
@@ -1064,7 +1064,7 @@ int interfaceUpdateItems(bool animated, int leftItemAction, int rightItemAction)
leftItemState->item = item1;
if (item1 != NULL) {
if (item1 != nullptr) {
leftItemState->isDisabled = dudeIsWeaponDisabled(item1);
leftItemState->primaryHitMode = HIT_MODE_LEFT_WEAPON_PRIMARY;
leftItemState->secondaryHitMode = HIT_MODE_LEFT_WEAPON_SECONDARY;
@@ -1093,7 +1093,7 @@ int interfaceUpdateItems(bool animated, int leftItemAction, int rightItemAction)
// SFALL: Keep selected attack mode.
// CE: Implementation is different.
if (oldItem == NULL) {
if (oldItem == nullptr) {
leftItemState->action = oldAction;
}
}
@@ -1102,8 +1102,8 @@ int interfaceUpdateItems(bool animated, int leftItemAction, int rightItemAction)
InterfaceItemState* rightItemState = &(gInterfaceItemStates[HAND_RIGHT]);
Object* item2 = critterGetItem2(gDude);
if (item2 == rightItemState->item && rightItemState->item != NULL) {
if (rightItemState->item != NULL) {
if (item2 == rightItemState->item && rightItemState->item != nullptr) {
if (rightItemState->item != nullptr) {
rightItemState->isDisabled = dudeIsWeaponDisabled(rightItemState->item);
rightItemState->itemFid = itemGetInventoryFid(rightItemState->item);
}
@@ -1113,7 +1113,7 @@ int interfaceUpdateItems(bool animated, int leftItemAction, int rightItemAction)
rightItemState->item = item2;
if (item2 != NULL) {
if (item2 != nullptr) {
rightItemState->isDisabled = dudeIsWeaponDisabled(item2);
rightItemState->primaryHitMode = HIT_MODE_RIGHT_WEAPON_PRIMARY;
rightItemState->secondaryHitMode = HIT_MODE_RIGHT_WEAPON_SECONDARY;
@@ -1141,7 +1141,7 @@ int interfaceUpdateItems(bool animated, int leftItemAction, int rightItemAction)
// SFALL: Keep selected attack mode.
// CE: Implementation is different.
if (oldItem == NULL) {
if (oldItem == nullptr) {
rightItemState->action = oldAction;
}
}
@@ -1151,7 +1151,7 @@ int interfaceUpdateItems(bool animated, int leftItemAction, int rightItemAction)
Object* newCurrentItem = gInterfaceItemStates[gInterfaceCurrentHand].item;
if (newCurrentItem != oldCurrentItem) {
int animationCode = 0;
if (newCurrentItem != NULL) {
if (newCurrentItem != nullptr) {
if (itemGetType(newCurrentItem) == ITEM_TYPE_WEAPON) {
animationCode = weaponGetAnimationCode(newCurrentItem);
}
@@ -1180,7 +1180,7 @@ int interfaceBarSwapHands(bool animated)
if (animated) {
Object* item = gInterfaceItemStates[gInterfaceCurrentHand].item;
int animationCode = 0;
if (item != NULL) {
if (item != nullptr) {
if (itemGetType(item) == ITEM_TYPE_WEAPON) {
animationCode = weaponGetAnimationCode(item);
}
@@ -1298,7 +1298,7 @@ void _intface_use_item()
gameMouseSetCursor(MOUSE_CURSOR_CROSSHAIR);
gameMouseSetMode(GAME_MOUSE_MODE_CROSSHAIR);
if (!isInCombat()) {
_combat(NULL);
_combat(nullptr);
}
}
} else if (_proto_action_can_use_on(ptr->item->pid)) {
@@ -1389,7 +1389,7 @@ void interfaceBarEndButtonsShow(bool animated)
int fid = buildFid(OBJ_TYPE_INTERFACE, 104, 0, 0, 0);
CacheEntry* handle;
Art* art = artLock(fid, &handle);
if (art == NULL) {
if (art == nullptr) {
return;
}
@@ -1405,7 +1405,7 @@ void interfaceBarEndButtonsShow(bool animated)
if (getTicksSince(time) >= delay) {
unsigned char* src = artGetFrameData(art, frame, 0);
if (src != NULL) {
if (src != nullptr) {
blitBufferToBuffer(src, 57, 58, 57, gInterfaceWindowBuffer + gInterfaceBarWidth * 38 + 580 + gInterfaceBarContentOffset, gInterfaceBarWidth);
windowRefreshRect(gInterfaceBarWindow, &gInterfaceBarEndButtonsRect);
}
@@ -1446,7 +1446,7 @@ void interfaceBarEndButtonsHide(bool animated)
int fid = buildFid(OBJ_TYPE_INTERFACE, 104, 0, 0, 0);
CacheEntry* handle;
Art* art = artLock(fid, &handle);
if (art == NULL) {
if (art == nullptr) {
return;
}
@@ -1465,7 +1465,7 @@ void interfaceBarEndButtonsHide(bool animated)
if (getTicksSince(time) >= delay) {
unsigned char* src = artGetFrameData(art, frame - 1, 0);
unsigned char* dest = gInterfaceWindowBuffer + gInterfaceBarWidth * 38 + 580 + gInterfaceBarContentOffset;
if (src != NULL) {
if (src != nullptr) {
blitBufferToBuffer(src, 57, 58, 57, dest, gInterfaceBarWidth);
windowRefreshRect(gInterfaceBarWindow, &gInterfaceBarEndButtonsRect);
}
@@ -1827,10 +1827,10 @@ static void interfaceBarSwapHandsAnimatePutAwayTakeOutSequence(int previousWeapo
}
// TODO: Get rid of cast.
animationRegisterCallbackForced(NULL, NULL, (AnimationCallback*)_intface_redraw_items_callback, -1);
animationRegisterCallbackForced(nullptr, nullptr, (AnimationCallback*)_intface_redraw_items_callback, -1);
Object* item = gInterfaceItemStates[gInterfaceCurrentHand].item;
if (item != NULL && item->lightDistance > 4) {
if (item != nullptr && item->lightDistance > 4) {
animationRegisterSetLightDistance(gDude, item->lightDistance, 0);
}
@@ -1842,7 +1842,7 @@ static void interfaceBarSwapHandsAnimatePutAwayTakeOutSequence(int previousWeapo
}
// TODO: Get rid of cast.
animationRegisterCallbackForced(NULL, NULL, (AnimationCallback*)_intface_change_fid_callback, -1);
animationRegisterCallbackForced(nullptr, nullptr, (AnimationCallback*)_intface_change_fid_callback, -1);
if (reg_anim_end() == -1) {
return;
@@ -1900,7 +1900,7 @@ static int endTurnButtonInit()
return -1;
}
gEndTurnButton = buttonCreate(gInterfaceBarWindow, 590 + gInterfaceBarContentOffset, 43, 38, 22, -1, -1, -1, 32, _endTurnButtonNormalFrmImage.getData(), _endTurnButtonPressedFrmImage.getData(), NULL, 0);
gEndTurnButton = buttonCreate(gInterfaceBarWindow, 590 + gInterfaceBarContentOffset, 43, 38, 22, -1, -1, -1, 32, _endTurnButtonNormalFrmImage.getData(), _endTurnButtonPressedFrmImage.getData(), nullptr, 0);
if (gEndTurnButton == -1) {
return -1;
}
@@ -1952,7 +1952,7 @@ static int endCombatButtonInit()
return -1;
}
gEndCombatButton = buttonCreate(gInterfaceBarWindow, 590 + gInterfaceBarContentOffset, 65, 38, 22, -1, -1, -1, 13, _endCombatButtonNormalFrmImage.getData(), _endCombatButtonPressedFrmImage.getData(), NULL, 0);
gEndCombatButton = buttonCreate(gInterfaceBarWindow, 590 + gInterfaceBarContentOffset, 65, 38, 22, -1, -1, -1, 13, _endCombatButtonNormalFrmImage.getData(), _endCombatButtonPressedFrmImage.getData(), nullptr, 0);
if (gEndCombatButton == -1) {
return -1;
}
@@ -2034,7 +2034,7 @@ static int _intface_item_reload()
return -1;
}
const char* sfx = sfxBuildWeaponName(WEAPON_SOUND_EFFECT_READY, gInterfaceItemStates[gInterfaceCurrentHand].item, HIT_MODE_RIGHT_WEAPON_PRIMARY, NULL);
const char* sfx = sfxBuildWeaponName(WEAPON_SOUND_EFFECT_READY, gInterfaceItemStates[gInterfaceCurrentHand].item, HIT_MODE_RIGHT_WEAPON_PRIMARY, nullptr);
soundPlayFile(sfx);
return 0;
@@ -2222,7 +2222,7 @@ static int indicatorBarInit()
IndicatorDescription* indicatorDescription = &(gIndicatorDescriptions[index]);
indicatorDescription->data = (unsigned char*)internal_malloc(INDICATOR_BOX_WIDTH * INDICATOR_BOX_HEIGHT);
if (indicatorDescription->data == NULL) {
if (indicatorDescription->data == nullptr) {
debugPrint("\nINTRFACE: Error initializing indicator box graphics! **");
while (--index >= 0) {
@@ -2276,9 +2276,9 @@ static void interfaceBarFree()
for (int index = 0; index < INDICATOR_COUNT; index++) {
IndicatorDescription* indicatorBoxDescription = &(gIndicatorDescriptions[index]);
if (indicatorBoxDescription->data != NULL) {
if (indicatorBoxDescription->data != nullptr) {
internal_free(indicatorBoxDescription->data);
indicatorBoxDescription->data = NULL;
indicatorBoxDescription->data = nullptr;
}
}
}
@@ -2483,30 +2483,26 @@ static void customInterfaceBarInit()
{
gInterfaceBarContentOffset = gInterfaceBarWidth - 640;
char path[COMPAT_MAX_PATH];
snprintf(path, sizeof(path), "art\\intrface\\HR_IFACE_%d.FRM", gInterfaceBarWidth);
if (gInterfaceBarContentOffset > 0 && screenGetWidth() > 640) {
char path[COMPAT_MAX_PATH];
snprintf(path, sizeof(path), "art\\intrface\\HR_IFACE_%d.FRM", gInterfaceBarWidth);
int size;
if (dbGetFileSize(path, &size) != 0 || gInterfaceBarContentOffset <= 0 || screenGetWidth() <= 640) {
gCustomInterfaceBarBackground = artLoad(path);
}
if (gCustomInterfaceBarBackground != nullptr) {
gInterfaceBarIsCustom = true;
} else {
gInterfaceBarContentOffset = 0;
gInterfaceBarWidth = 640;
gInterfaceBarIsCustom = false;
} else {
gInterfaceBarIsCustom = true;
gCustomInterfaceBarBackground = (Art*)(malloc(size));
if (artRead(path, (unsigned char*)gCustomInterfaceBarBackground) != 0) {
gInterfaceBarIsCustom = false;
free(gCustomInterfaceBarBackground);
gCustomInterfaceBarBackground = nullptr;
}
}
}
static void customInterfaceBarExit()
{
if (gCustomInterfaceBarBackground != nullptr) {
free(gCustomInterfaceBarBackground);
internal_free(gCustomInterfaceBarBackground);
gCustomInterfaceBarBackground = nullptr;
}
}
@@ -2585,21 +2581,11 @@ static void sidePanelsShow()
static void sidePanelsDraw(const char* path, int win, bool isLeading)
{
int size;
if (dbGetFileSize(path, &size) != 0) {
return;
}
Art* image = reinterpret_cast<Art*>(internal_malloc(size));
Art* image = artLoad(path);
if (image == nullptr) {
return;
}
if (artRead(path, reinterpret_cast<unsigned char*>(image)) != 0) {
internal_free(image);
return;
}
unsigned char* imageData = artGetFrameData(image, 0, 0);
int imageWidth = artGetWidth(image, 0, 0);
@@ -2630,4 +2616,37 @@ static void sidePanelsDraw(const char* path, int win, bool isLeading)
internal_free(image);
}
// NOTE: Follows Sfall implementation of `GetCurrentAttackMode`. It slightly
// differs from `interfaceGetCurrentHitMode` (can return one of `reload` hit
// modes, the default is `punch`).
//
// 0x45EF6C
bool interface_get_current_attack_mode(int* hit_mode)
{
if (gInterfaceBarWindow == -1) {
return false;
}
switch (gInterfaceItemStates[gInterfaceCurrentHand].action) {
case INTERFACE_ITEM_ACTION_PRIMARY_AIMING:
case INTERFACE_ITEM_ACTION_PRIMARY:
*hit_mode = gInterfaceItemStates[gInterfaceCurrentHand].primaryHitMode;
break;
case INTERFACE_ITEM_ACTION_SECONDARY_AIMING:
case INTERFACE_ITEM_ACTION_SECONDARY:
*hit_mode = gInterfaceItemStates[gInterfaceCurrentHand].secondaryHitMode;
break;
case INTERFACE_ITEM_ACTION_RELOAD:
*hit_mode = gInterfaceCurrentHand == HAND_LEFT
? HIT_MODE_LEFT_WEAPON_RELOAD
: HIT_MODE_RIGHT_WEAPON_RELOAD;
break;
default:
*hit_mode = HIT_MODE_PUNCH;
break;
}
return true;
}
} // namespace fallout

View File

@@ -69,6 +69,7 @@ void interfaceBarEndButtonsRenderRedLights();
int indicatorBarRefresh();
bool indicatorBarShow();
bool indicatorBarHide();
bool interface_get_current_attack_mode(int* hit_mode);
unsigned char* customInterfaceBarGetBackgroundImageData();

View File

@@ -14,6 +14,7 @@
#include "interpreter_lib.h"
#include "memory_manager.h"
#include "platform_compat.h"
#include "sfall_global_scripts.h"
#include "svga.h"
namespace fallout {
@@ -30,20 +31,19 @@ static int _outputStr(char* a1);
static int _checkWait(Program* program);
static char* programGetCurrentProcedureName(Program* s);
static opcode_t stackReadInt16(unsigned char* data, int pos);
static int stackReadInt32(unsigned char* a1, int a2);
static void stackWriteInt16(int value, unsigned char* a2, int a3);
static void stackWriteInt32(int value, unsigned char* stack, int pos);
static void stackPushInt16(unsigned char* a1, int* a2, int value);
static void stackPushInt32(unsigned char* a1, int* a2, int value);
static int stackPopInt32(unsigned char* a1, int* a2);
static opcode_t stackPopInt16(unsigned char* a1, int* a2);
static int stackReadInt32(unsigned char* data, int pos);
static void stackWriteInt16(int value, unsigned char* data, int pos);
static void stackWriteInt32(int value, unsigned char* data, int pos);
static void stackPushInt16(unsigned char* data, int* pointer, int value);
static void stackPushInt32(unsigned char* data, int* pointer, int value);
static int stackPopInt32(unsigned char* data, int* pointer);
static opcode_t stackPopInt16(unsigned char* data, int* pointer);
static void _interpretIncStringRef(Program* program, opcode_t opcode, int value);
static void programReturnStackPushInt16(Program* program, int value);
static opcode_t programReturnStackPopInt16(Program* program);
static int programReturnStackPopInt32(Program* program);
static void _detachProgram(Program* program);
static void _purgeProgram(Program* program);
static void programFree(Program* program);
static opcode_t _getOp(Program* program);
static void programMarkHeap(Program* program);
static void opNoop(Program* program);
@@ -51,7 +51,7 @@ static void opPush(Program* program);
static void opPushBase(Program* program);
static void opPopBase(Program* program);
static void opPopToBase(Program* program);
static void op802C(Program* program);
static void opSetGlobal(Program* program);
static void opDump(Program* program);
static void opDelayedCall(Program* program);
static void opConditionalCall(Program* program);
@@ -87,17 +87,17 @@ static void opLeaveCriticalSection(Program* program);
static void opEnterCriticalSection(Program* program);
static void opJump(Program* program);
static void opCall(Program* program);
static void op801F(Program* program);
static void op801C(Program* program);
static void op801D(Program* program);
static void op8020(Program* program);
static void op8021(Program* program);
static void op8025(Program* program);
static void op8026(Program* program);
static void op8022(Program* program);
static void op8023(Program* program);
static void op8024(Program* program);
static void op801E(Program* program);
static void opPopFlags(Program* program);
static void opPopReturn(Program* program);
static void opPopExit(Program* program);
static void opPopFlagsReturn(Program* program);
static void opPopFlagsExit(Program* program);
static void opPopFlagsReturnValExit(Program* program);
static void opPopFlagsReturnValExitExtern(Program* program);
static void opPopFlagsReturnExtern(Program* program);
static void opPopFlagsExitExtern(Program* program);
static void opPopFlagsReturnValExtern(Program* program);
static void opPopAddress(Program* program);
static void opAtoD(Program* program);
static void opDtoA(Program* program);
static void opExitProgram(Program* program);
@@ -208,7 +208,7 @@ void _interpretOutputFunc(int (*func)(char*))
// 0x467104
int _interpretOutput(const char* format, ...)
{
if (_outputFunc == NULL) {
if (_outputFunc == nullptr) {
return 0;
}
@@ -230,17 +230,17 @@ static char* programGetCurrentProcedureName(Program* program)
int procedureCount = stackReadInt32(program->procedures, 0);
unsigned char* ptr = program->procedures + 4;
int procedureOffset = stackReadInt32(ptr, 16);
int identifierOffset = stackReadInt32(ptr, 0);
int procedureOffset = stackReadInt32(ptr, offsetof(Procedure, bodyOffset));
int identifierOffset = stackReadInt32(ptr, offsetof(Procedure, nameOffset));
for (int index = 0; index < procedureCount; index++) {
int nextProcedureOffset = stackReadInt32(ptr + 24, 16);
int nextProcedureOffset = stackReadInt32(ptr + 24, offsetof(Procedure, bodyOffset));
if (program->instructionPointer >= procedureOffset && program->instructionPointer < nextProcedureOffset) {
return (char*)(program->identifiers + identifierOffset);
}
ptr += 24;
identifierOffset = stackReadInt32(ptr, 0);
identifierOffset = stackReadInt32(ptr, offsetof(Procedure, nameOffset));
}
return _aCouldnTFindPro;
@@ -258,7 +258,7 @@ static char* programGetCurrentProcedureName(Program* program)
debugPrint("\nError during execution: %s\n", string);
if (gInterpreterCurrentProgram == NULL) {
if (gInterpreterCurrentProgram == nullptr) {
debugPrint("No current script");
} else {
char* procedureName = programGetCurrentProcedureName(gInterpreterCurrentProgram);
@@ -402,11 +402,11 @@ void _interpretDecStringRef(Program* program, opcode_t opcode, int value)
static void _detachProgram(Program* program)
{
Program* parent = program->parent;
if (parent != NULL) {
if (parent != nullptr) {
parent->flags &= ~PROGRAM_FLAG_0x20;
parent->flags &= ~PROGRAM_FLAG_0x0100;
if (program == parent->child) {
parent->child = NULL;
parent->child = nullptr;
}
}
}
@@ -421,20 +421,20 @@ static void _purgeProgram(Program* program)
}
// 0x467614
static void programFree(Program* program)
void programFree(Program* program)
{
// NOTE: Uninline.
_detachProgram(program);
Program* curr = program->child;
while (curr != NULL) {
while (curr != nullptr) {
// NOTE: Uninline.
_purgeProgram(curr);
curr->parent = NULL;
curr->parent = nullptr;
Program* next = curr->child;
curr->child = NULL;
curr->child = nullptr;
curr = next;
}
@@ -442,15 +442,15 @@ static void programFree(Program* program)
// NOTE: Uninline.
_purgeProgram(program);
if (program->dynamicStrings != NULL) {
if (program->dynamicStrings != nullptr) {
internal_free_safe(program->dynamicStrings, __FILE__, __LINE__); // "..\\int\\INTRPRET.C", 429
}
if (program->data != NULL) {
if (program->data != nullptr) {
internal_free_safe(program->data, __FILE__, __LINE__); // "..\\int\\INTRPRET.C", 430
}
if (program->name != NULL) {
if (program->name != nullptr) {
internal_free_safe(program->name, __FILE__, __LINE__); // "..\\int\\INTRPRET.C", 431
}
@@ -464,11 +464,11 @@ static void programFree(Program* program)
Program* programCreateByPath(const char* path)
{
File* stream = fileOpen(path, "rb");
if (stream == NULL) {
if (stream == nullptr) {
char err[260];
snprintf(err, sizeof(err), "Couldn't open %s for read\n", path);
programFatalError(err);
return NULL;
return nullptr;
}
int fileSize = fileGetSize(stream);
@@ -483,8 +483,8 @@ Program* programCreateByPath(const char* path)
program->name = (char*)internal_malloc_safe(strlen(path) + 1, __FILE__, __LINE__); // ..\\int\\INTRPRET.C, 466
strcpy(program->name, path);
program->child = NULL;
program->parent = NULL;
program->child = nullptr;
program->parent = nullptr;
program->field_78 = -1;
program->exited = false;
program->basePointer = -1;
@@ -528,7 +528,7 @@ char* programGetString(Program* program, opcode_t opcode, int offset)
return (char*)(program->staticStrings + 4 + offset);
}
return NULL;
return nullptr;
}
// 0x46790C
@@ -554,7 +554,7 @@ static void programMarkHeap(Program* program)
short next_len;
short diff;
if (program->dynamicStrings == NULL) {
if (program->dynamicStrings == nullptr) {
return;
}
@@ -593,7 +593,7 @@ int programPushString(Program* program, char* string)
unsigned char* v20;
unsigned char* v23;
if (program == NULL) {
if (program == nullptr) {
return 0;
}
@@ -604,7 +604,7 @@ int programPushString(Program* program, char* string)
v27++;
}
if (program->dynamicStrings != NULL) {
if (program->dynamicStrings != nullptr) {
// TODO: Needs testing, lots of pointer stuff.
unsigned char* heap = program->dynamicStrings + 4;
while (*(unsigned short*)heap != 0x8000) {
@@ -712,7 +712,7 @@ static void opPopToBase(Program* program)
}
// 0x467DE0
static void op802C(Program* program)
static void opSetGlobal(Program* program)
{
program->basePointer = program->stackValues->size();
}
@@ -745,10 +745,10 @@ static void opDelayedCall(Program* program)
delay += 1000 * _timerFunc() / _timerTick;
}
int flags = stackReadInt32(procedure_ptr, 4);
int flags = stackReadInt32(procedure_ptr, offsetof(Procedure, flags));
stackWriteInt32(delay, procedure_ptr, 8);
stackWriteInt32(flags | PROCEDURE_FLAG_TIMED, procedure_ptr, 4);
stackWriteInt32(delay, procedure_ptr, offsetof(Procedure, time));
stackWriteInt32(flags | PROCEDURE_FLAG_TIMED, procedure_ptr, offsetof(Procedure, flags));
}
// 0x468034
@@ -761,10 +761,10 @@ static void opConditionalCall(Program* program)
}
unsigned char* procedure_ptr = program->procedures + 4 + 24 * data[0];
int flags = stackReadInt32(procedure_ptr, 4);
int flags = stackReadInt32(procedure_ptr, offsetof(Procedure, flags));
stackWriteInt32(flags | PROCEDURE_FLAG_CONDITIONAL, procedure_ptr, 4);
stackWriteInt32(data[1], procedure_ptr, 12);
stackWriteInt32(flags | PROCEDURE_FLAG_CONDITIONAL, procedure_ptr, offsetof(Procedure, flags));
stackWriteInt32(data[1], procedure_ptr, offsetof(Procedure, conditionOffset));
}
// 0x46817C
@@ -788,9 +788,9 @@ static void opCancel(Program* program)
}
Procedure* proc = (Procedure*)(program->procedures + 4 + data * sizeof(*proc));
proc->field_4 = 0;
proc->field_8 = 0;
proc->field_C = 0;
proc->flags = 0;
proc->time = 0;
proc->conditionOffset = 0;
}
// 0x468330
@@ -802,9 +802,9 @@ static void opCancelAll(Program* program)
// TODO: Original code uses different approach, check.
Procedure* proc = (Procedure*)(program->procedures + 4 + index * sizeof(*proc));
proc->field_4 = 0;
proc->field_8 = 0;
proc->field_C = 0;
proc->flags = 0;
proc->time = 0;
proc->conditionOffset = 0;
}
}
@@ -932,7 +932,7 @@ static void opConditionalOperatorNotEqual(Program* program)
result = value[1].integerValue != value[0].integerValue;
break;
case VALUE_TYPE_PTR:
result = (intptr_t)(value[1].integerValue) != (intptr_t)(value[0].pointerValue);
result = (uintptr_t)(value[1].integerValue) != (uintptr_t)(value[0].pointerValue);
break;
default:
assert(false && "Should be unreachable");
@@ -941,7 +941,7 @@ static void opConditionalOperatorNotEqual(Program* program)
case VALUE_TYPE_PTR:
switch (value[0].opcode) {
case VALUE_TYPE_INT:
result = (intptr_t)(value[1].pointerValue) != (intptr_t)(value[0].integerValue);
result = (uintptr_t)(value[1].pointerValue) != (uintptr_t)(value[0].integerValue);
break;
case VALUE_TYPE_PTR:
result = value[1].pointerValue != value[0].pointerValue;
@@ -1028,7 +1028,7 @@ static void opConditionalOperatorEqual(Program* program)
result = value[1].integerValue == value[0].integerValue;
break;
case VALUE_TYPE_PTR:
result = (intptr_t)(value[1].integerValue) == (intptr_t)(value[0].pointerValue);
result = (uintptr_t)(value[1].integerValue) == (uintptr_t)(value[0].pointerValue);
break;
default:
assert(false && "Should be unreachable");
@@ -1037,7 +1037,7 @@ static void opConditionalOperatorEqual(Program* program)
case VALUE_TYPE_PTR:
switch (value[0].opcode) {
case VALUE_TYPE_INT:
result = (intptr_t)(value[1].pointerValue) == (intptr_t)(value[0].integerValue);
result = (uintptr_t)(value[1].pointerValue) == (uintptr_t)(value[0].integerValue);
break;
case VALUE_TYPE_PTR:
result = value[1].pointerValue == value[0].pointerValue;
@@ -1131,7 +1131,12 @@ static void opConditionalOperatorLessThanEquals(Program* program)
case VALUE_TYPE_PTR:
switch (value[0].opcode) {
case VALUE_TYPE_INT:
result = (intptr_t)value[1].pointerValue <= (intptr_t)value[0].integerValue;
if (value[0].integerValue > 0) {
result = (uintptr_t)value[1].pointerValue <= (uintptr_t)value[0].integerValue;
} else {
// (ptr <= int{0 or negative}) means (ptr == nullptr)
result = nullptr == value[1].pointerValue;
}
break;
default:
assert(false && "Should be unreachable");
@@ -1385,7 +1390,12 @@ static void opConditionalOperatorGreaterThan(Program* program)
case VALUE_TYPE_PTR:
switch (value[0].opcode) {
case VALUE_TYPE_INT:
result = (intptr_t)value[1].pointerValue > (intptr_t)value[0].integerValue;
if (value[0].integerValue > 0) {
result = (uintptr_t)value[1].pointerValue > (uintptr_t)value[0].integerValue;
} else {
// (ptr > int{0 or negative}) means (ptr != nullptr)
result = nullptr != value[1].pointerValue;
}
break;
default:
assert(false && "Should be unreachable");
@@ -1491,6 +1501,21 @@ static void opAdd(Program* program)
break;
}
break;
// Sonora folks use "object + string" concatenation for debug purposes.
case VALUE_TYPE_PTR:
switch (value[0].opcode) {
case VALUE_TYPE_STRING:
case VALUE_TYPE_DYNAMIC_STRING:
strings[0] = programGetString(program, value[0].opcode, value[0].integerValue);
tempString = (char*)internal_malloc_safe(strlen(strings[0]) + 80, __FILE__, __LINE__);
snprintf(tempString, strlen(strings[0]) + 80, "%p", value[1].pointerValue);
strcat(tempString, strings[0]);
programStackPushString(program, tempString);
internal_free_safe(tempString, __FILE__, __LINE__);
break;
}
}
}
@@ -2015,19 +2040,19 @@ static void opCall(Program* program)
unsigned char* ptr = program->procedures + 4 + 24 * value;
int flags = stackReadInt32(ptr, 4);
if ((flags & 4) != 0) {
int flags = stackReadInt32(ptr, offsetof(Procedure, flags));
if ((flags & PROCEDURE_FLAG_IMPORTED) != 0) {
// TODO: Incomplete.
} else {
program->instructionPointer = stackReadInt32(ptr, 16);
if ((flags & 0x10) != 0) {
program->instructionPointer = stackReadInt32(ptr, offsetof(Procedure, bodyOffset));
if ((flags & PROCEDURE_FLAG_CRITICAL) != 0) {
program->flags |= PROGRAM_FLAG_CRITICAL_SECTION;
}
}
}
// 0x46B590
static void op801F(Program* program)
static void opPopFlags(Program* program)
{
program->windowId = programStackPopInteger(program);
program->checkWaitFunc = (InterpretCheckWaitFunc*)programStackPopPointer(program);
@@ -2036,13 +2061,13 @@ static void op801F(Program* program)
// pop stack 2 -> set program address
// 0x46B63C
static void op801C(Program* program)
static void opPopReturn(Program* program)
{
program->instructionPointer = programReturnStackPopInteger(program);
}
// 0x46B658
static void op801D(Program* program)
static void opPopExit(Program* program)
{
program->instructionPointer = programReturnStackPopInteger(program);
@@ -2050,37 +2075,37 @@ static void op801D(Program* program)
}
// 0x46B67C
static void op8020(Program* program)
static void opPopFlagsReturn(Program* program)
{
op801F(program);
opPopFlags(program);
program->instructionPointer = programReturnStackPopInteger(program);
}
// 0x46B698
static void op8021(Program* program)
static void opPopFlagsExit(Program* program)
{
op801F(program);
opPopFlags(program);
program->instructionPointer = programReturnStackPopInteger(program);
program->flags |= PROGRAM_FLAG_0x40;
}
// 0x46B6BC
static void op8025(Program* program)
static void opPopFlagsReturnValExit(Program* program)
{
ProgramValue value = programStackPopValue(program);
op801F(program);
opPopFlags(program);
program->instructionPointer = programReturnStackPopInteger(program);
program->flags |= PROGRAM_FLAG_0x40;
programStackPushValue(program, value);
}
// 0x46B73C
static void op8026(Program* program)
static void opPopFlagsReturnValExitExtern(Program* program)
{
ProgramValue value = programStackPopValue(program);
op801F(program);
opPopFlags(program);
Program* v1 = (Program*)programReturnStackPopPointer(program);
v1->checkWaitFunc = (InterpretCheckWaitFunc*)programReturnStackPopPointer(program);
@@ -2094,9 +2119,9 @@ static void op8026(Program* program)
}
// 0x46B808
static void op8022(Program* program)
static void opPopFlagsReturnExtern(Program* program)
{
op801F(program);
opPopFlags(program);
Program* v1 = (Program*)programReturnStackPopPointer(program);
v1->checkWaitFunc = (InterpretCheckWaitFunc*)programReturnStackPopPointer(program);
@@ -2106,9 +2131,9 @@ static void op8022(Program* program)
}
// 0x46B86C
static void op8023(Program* program)
static void opPopFlagsExitExtern(Program* program)
{
op801F(program);
opPopFlags(program);
Program* v1 = (Program*)programReturnStackPopPointer(program);
v1->checkWaitFunc = (InterpretCheckWaitFunc*)programReturnStackPopPointer(program);
@@ -2121,11 +2146,11 @@ static void op8023(Program* program)
// pop value from stack 1 and push it to script popped from stack 2
// 0x46B8D8
static void op8024(Program* program)
static void opPopFlagsReturnValExtern(Program* program)
{
ProgramValue value = programStackPopValue(program);
op801F(program);
opPopFlags(program);
Program* v10 = (Program*)programReturnStackPopPointer(program);
v10->checkWaitFunc = (InterpretCheckWaitFunc*)programReturnStackPopPointer(program);
@@ -2149,7 +2174,7 @@ static void op8024(Program* program)
}
// 0x46BA10
static void op801E(Program* program)
static void opPopAddress(Program* program)
{
programReturnStackPopValue(program);
}
@@ -2223,7 +2248,7 @@ static void opFetchProcedureAddress(Program* program)
{
int procedureIndex = programStackPopInteger(program);
int address = stackReadInt32(program->procedures + 4 + sizeof(Procedure) * procedureIndex, 16);
int address = stackReadInt32(program->procedures + 4 + sizeof(Procedure) * procedureIndex, offsetof(Procedure, bodyOffset));
programStackPushInteger(program, address);
}
@@ -2283,8 +2308,8 @@ static void opExportProcedure(Program* program)
unsigned char* proc_ptr = program->procedures + 4 + sizeof(Procedure) * procedureIndex;
char* procedureName = programGetIdentifier(program, stackReadInt32(proc_ptr, 0));
int procedureAddress = stackReadInt32(proc_ptr, 16);
char* procedureName = programGetIdentifier(program, stackReadInt32(proc_ptr, offsetof(Procedure, nameOffset)));
int procedureAddress = stackReadInt32(proc_ptr, offsetof(Procedure, bodyOffset));
if (externalProcedureCreate(program, procedureName, procedureAddress, argumentCount) != 0) {
char err[256];
@@ -2313,7 +2338,7 @@ static void opExit(Program* program)
program->flags |= PROGRAM_FLAG_EXITED;
Program* parent = program->parent;
if (parent != NULL) {
if (parent != nullptr) {
if ((parent->flags & PROGRAM_FLAG_0x0100) != 0) {
parent->flags &= ~PROGRAM_FLAG_0x0100;
}
@@ -2329,7 +2354,7 @@ static void opExit(Program* program)
static void opDetach(Program* program)
{
Program* parent = program->parent;
if (parent == NULL) {
if (parent == nullptr) {
return;
}
@@ -2337,7 +2362,7 @@ static void opDetach(Program* program)
parent->flags &= ~PROGRAM_FLAG_0x0100;
if (parent->child == program) {
parent->child = NULL;
parent->child = nullptr;
}
}
@@ -2355,7 +2380,7 @@ static void opCallStart(Program* program)
// NOTE: Uninline.
program->child = runScript(name);
if (program->child == NULL) {
if (program->child == nullptr) {
char err[260];
snprintf(err, sizeof(err), "Error spawning child %s", name);
programFatalError(err);
@@ -2379,7 +2404,7 @@ static void opSpawn(Program* program)
// NOTE: Uninline.
program->child = runScript(name);
if (program->child == NULL) {
if (program->child == nullptr) {
char err[260];
snprintf(err, sizeof(err), "Error spawning child %s", name);
programFatalError(err);
@@ -2401,7 +2426,7 @@ static Program* forkProgram(Program* program)
char* name = programStackPopString(program);
Program* forked = runScript(name);
if (forked == NULL) {
if (forked == nullptr) {
char err[256];
snprintf(err, sizeof(err), "couldn't fork script '%s'", name);
programFatalError(err);
@@ -2426,19 +2451,19 @@ static void opExec(Program* program)
Program* parent = program->parent;
Program* fork = forkProgram(program);
if (parent != NULL) {
if (parent != nullptr) {
fork->parent = parent;
parent->child = fork;
}
fork->child = NULL;
fork->child = nullptr;
program->parent = NULL;
program->parent = nullptr;
program->flags |= PROGRAM_FLAG_EXITED;
// probably inlining due to check for null
parent = program->parent;
if (parent != NULL) {
if (parent != nullptr) {
if ((parent->flags & PROGRAM_FLAG_0x0100) != 0) {
parent->flags &= ~PROGRAM_FLAG_0x0100;
}
@@ -2453,9 +2478,9 @@ static void opCheckProcedureArgumentCount(Program* program)
int expectedArgumentCount = programStackPopInteger(program);
int procedureIndex = programStackPopInteger(program);
int actualArgumentCount = stackReadInt32(program->procedures + 4 + 24 * procedureIndex, 20);
int actualArgumentCount = stackReadInt32(program->procedures + 4 + 24 * procedureIndex, offsetof(Procedure, argCount));
if (actualArgumentCount != expectedArgumentCount) {
const char* identifier = programGetIdentifier(program, stackReadInt32(program->procedures + 4 + 24 * procedureIndex, 0));
const char* identifier = programGetIdentifier(program, stackReadInt32(program->procedures + 4 + 24 * procedureIndex, offsetof(Procedure, nameOffset)));
char err[260];
snprintf(err, sizeof(err), "Wrong number of args to procedure %s\n", identifier);
programFatalError(err);
@@ -2476,7 +2501,7 @@ static void opLookupStringProc(Program* program)
// Start with 1 since we've skipped main procedure, which is always at
// index 0.
for (int index = 1; index < procedureCount; index++) {
int offset = stackReadInt32(procedurePtr, 0);
int offset = stackReadInt32(procedurePtr, offsetof(Procedure, nameOffset));
const char* procedureName = programGetIdentifier(program, offset);
if (compat_stricmp(procedureName, procedureNameToLookup) == 0) {
programStackPushInteger(program, index);
@@ -2525,23 +2550,23 @@ void interpreterRegisterOpcodeHandlers()
interpreterRegisterOpcode(OPCODE_SWAPA, opSwapReturnStack);
interpreterRegisterOpcode(OPCODE_POP, opPop);
interpreterRegisterOpcode(OPCODE_DUP, opDuplicate);
interpreterRegisterOpcode(OPCODE_POP_RETURN, op801C);
interpreterRegisterOpcode(OPCODE_POP_EXIT, op801D);
interpreterRegisterOpcode(OPCODE_POP_ADDRESS, op801E);
interpreterRegisterOpcode(OPCODE_POP_FLAGS, op801F);
interpreterRegisterOpcode(OPCODE_POP_FLAGS_RETURN, op8020);
interpreterRegisterOpcode(OPCODE_POP_FLAGS_EXIT, op8021);
interpreterRegisterOpcode(OPCODE_POP_FLAGS_RETURN_EXTERN, op8022);
interpreterRegisterOpcode(OPCODE_POP_FLAGS_EXIT_EXTERN, op8023);
interpreterRegisterOpcode(OPCODE_POP_FLAGS_RETURN_VAL_EXTERN, op8024);
interpreterRegisterOpcode(OPCODE_POP_FLAGS_RETURN_VAL_EXIT, op8025);
interpreterRegisterOpcode(OPCODE_POP_FLAGS_RETURN_VAL_EXIT_EXTERN, op8026);
interpreterRegisterOpcode(OPCODE_POP_RETURN, opPopReturn);
interpreterRegisterOpcode(OPCODE_POP_EXIT, opPopExit);
interpreterRegisterOpcode(OPCODE_POP_ADDRESS, opPopAddress);
interpreterRegisterOpcode(OPCODE_POP_FLAGS, opPopFlags);
interpreterRegisterOpcode(OPCODE_POP_FLAGS_RETURN, opPopFlagsReturn);
interpreterRegisterOpcode(OPCODE_POP_FLAGS_EXIT, opPopFlagsExit);
interpreterRegisterOpcode(OPCODE_POP_FLAGS_RETURN_EXTERN, opPopFlagsReturnExtern);
interpreterRegisterOpcode(OPCODE_POP_FLAGS_EXIT_EXTERN, opPopFlagsExitExtern);
interpreterRegisterOpcode(OPCODE_POP_FLAGS_RETURN_VAL_EXTERN, opPopFlagsReturnValExtern);
interpreterRegisterOpcode(OPCODE_POP_FLAGS_RETURN_VAL_EXIT, opPopFlagsReturnValExit);
interpreterRegisterOpcode(OPCODE_POP_FLAGS_RETURN_VAL_EXIT_EXTERN, opPopFlagsReturnValExitExtern);
interpreterRegisterOpcode(OPCODE_CHECK_PROCEDURE_ARGUMENT_COUNT, opCheckProcedureArgumentCount);
interpreterRegisterOpcode(OPCODE_LOOKUP_PROCEDURE_BY_NAME, opLookupStringProc);
interpreterRegisterOpcode(OPCODE_POP_BASE, opPopBase);
interpreterRegisterOpcode(OPCODE_POP_TO_BASE, opPopToBase);
interpreterRegisterOpcode(OPCODE_PUSH_BASE, opPushBase);
interpreterRegisterOpcode(OPCODE_SET_GLOBAL, op802C);
interpreterRegisterOpcode(OPCODE_SET_GLOBAL, opSetGlobal);
interpreterRegisterOpcode(OPCODE_FETCH_PROCEDURE_ADDRESS, opFetchProcedureAddress);
interpreterRegisterOpcode(OPCODE_DUMP, opDump);
interpreterRegisterOpcode(OPCODE_IF, opIf);
@@ -2632,7 +2657,7 @@ void _interpret(Program* program, int a2)
if ((program->flags & PROGRAM_IS_WAITING) != 0) {
_busy = 1;
if (program->checkWaitFunc != NULL) {
if (program->checkWaitFunc != nullptr) {
if (!program->checkWaitFunc(program)) {
_busy = 0;
continue;
@@ -2640,7 +2665,7 @@ void _interpret(Program* program, int a2)
}
_busy = 0;
program->checkWaitFunc = NULL;
program->checkWaitFunc = nullptr;
program->flags &= ~PROGRAM_IS_WAITING;
}
@@ -2658,7 +2683,7 @@ void _interpret(Program* program, int a2)
unsigned int opcodeIndex = opcode & 0x3FF;
OpcodeHandler* handler = gInterpreterOpcodeHandlers[opcodeIndex];
if (handler == NULL) {
if (handler == nullptr) {
snprintf(err, sizeof(err), "Undefined opcode %x.", opcode);
programFatalError(err);
}
@@ -2667,11 +2692,11 @@ void _interpret(Program* program, int a2)
}
if ((program->flags & PROGRAM_FLAG_EXITED) != 0) {
if (program->parent != NULL) {
if (program->parent != nullptr) {
if (program->parent->flags & PROGRAM_FLAG_0x20) {
program->parent->flags &= ~PROGRAM_FLAG_0x20;
program->parent->child = NULL;
program->parent = NULL;
program->parent->child = nullptr;
program->parent = nullptr;
}
}
}
@@ -2761,11 +2786,11 @@ void _executeProc(Program* program, int procedureIndex)
char err[256];
procedurePtr = program->procedures + 4 + sizeof(Procedure) * procedureIndex;
procedureFlags = stackReadInt32(procedurePtr, 4);
procedureFlags = stackReadInt32(procedurePtr, offsetof(Procedure, flags));
if ((procedureFlags & PROCEDURE_FLAG_IMPORTED) != 0) {
procedureIdentifier = programGetIdentifier(program, stackReadInt32(procedurePtr, 0));
procedureIdentifier = programGetIdentifier(program, stackReadInt32(procedurePtr, offsetof(Procedure, nameOffset)));
externalProgram = externalProcedureGetProgram(procedureIdentifier, &externalProcedureAddress, &externalProcedureArgumentCount);
if (externalProgram != NULL) {
if (externalProgram != nullptr) {
if (externalProcedureArgumentCount == 0) {
} else {
snprintf(err, sizeof(err), "External procedure cannot take arguments in interrupt context");
@@ -2780,7 +2805,7 @@ void _executeProc(Program* program, int procedureIndex)
_setupExternalCall(program, externalProgram, externalProcedureAddress, 28);
procedurePtr = externalProgram->procedures + 4 + sizeof(Procedure) * procedureIndex;
procedureFlags = stackReadInt32(procedurePtr, 4);
procedureFlags = stackReadInt32(procedurePtr, offsetof(Procedure, flags));
if ((procedureFlags & PROCEDURE_FLAG_CRITICAL) != 0) {
// NOTE: Uninline.
@@ -2788,7 +2813,7 @@ void _executeProc(Program* program, int procedureIndex)
_interpret(externalProgram, 0);
}
} else {
procedureAddress = stackReadInt32(procedurePtr, 16);
procedureAddress = stackReadInt32(procedurePtr, offsetof(Procedure, bodyOffset));
// NOTE: Uninline.
_setupCall(program, procedureAddress, 20);
@@ -2811,7 +2836,7 @@ int programFindProcedure(Program* program, const char* name)
unsigned char* ptr = program->procedures + 4;
for (int index = 0; index < procedureCount; index++) {
int identifierOffset = stackReadInt32(ptr, offsetof(Procedure, field_0));
int identifierOffset = stackReadInt32(ptr, offsetof(Procedure, nameOffset));
if (compat_stricmp((char*)(program->identifiers + identifierOffset), name) == 0) {
return index;
}
@@ -2836,12 +2861,12 @@ void _executeProcedure(Program* program, int procedureIndex)
jmp_buf env;
procedurePtr = program->procedures + 4 + sizeof(Procedure) * procedureIndex;
procedureFlags = stackReadInt32(procedurePtr, 4);
procedureFlags = stackReadInt32(procedurePtr, offsetof(Procedure, flags));
if ((procedureFlags & PROCEDURE_FLAG_IMPORTED) != 0) {
procedureIdentifier = programGetIdentifier(program, stackReadInt32(procedurePtr, 0));
procedureIdentifier = programGetIdentifier(program, stackReadInt32(procedurePtr, offsetof(Procedure, nameOffset)));
externalProgram = externalProcedureGetProgram(procedureIdentifier, &externalProcedureAddress, &externalProcedureArgumentCount);
if (externalProgram != NULL) {
if (externalProgram != nullptr) {
if (externalProcedureArgumentCount == 0) {
// NOTE: Uninline.
_setupExternalCall(program, externalProgram, externalProcedureAddress, 32);
@@ -2857,7 +2882,7 @@ void _executeProcedure(Program* program, int procedureIndex)
_interpretOutput(err);
}
} else {
procedureAddress = stackReadInt32(procedurePtr, 16);
procedureAddress = stackReadInt32(procedurePtr, offsetof(Procedure, bodyOffset));
// NOTE: Uninline.
_setupCall(program, procedureAddress, 24);
@@ -2888,19 +2913,19 @@ static void _doEvents()
programListNode = gInterpreterProgramListHead;
time = 1000 * _timerFunc() / _timerTick;
while (programListNode != NULL) {
while (programListNode != nullptr) {
procedureCount = stackReadInt32(programListNode->program->procedures, 0);
procedurePtr = programListNode->program->procedures + 4;
for (procedureIndex = 0; procedureIndex < procedureCount; procedureIndex++) {
procedureFlags = stackReadInt32(procedurePtr, 4);
procedureFlags = stackReadInt32(procedurePtr, offsetof(Procedure, flags));
if ((procedureFlags & PROCEDURE_FLAG_CONDITIONAL) != 0) {
memcpy(env, programListNode->program, sizeof(env));
oldProgramFlags = programListNode->program->flags;
oldInstructionPointer = programListNode->program->instructionPointer;
programListNode->program->flags = 0;
programListNode->program->instructionPointer = stackReadInt32(procedurePtr, 12);
programListNode->program->instructionPointer = stackReadInt32(procedurePtr, offsetof(Procedure, conditionOffset));
_interpret(programListNode->program, -1);
if ((programListNode->program->flags & PROGRAM_FLAG_0x04) == 0) {
@@ -2911,16 +2936,16 @@ static void _doEvents()
if (data != 0) {
// NOTE: Uninline.
stackWriteInt32(0, procedurePtr, 4);
stackWriteInt32(0, procedurePtr, offsetof(Procedure, flags));
_executeProc(programListNode->program, procedureIndex);
}
}
memcpy(programListNode->program, env, sizeof(env));
} else if ((procedureFlags & PROCEDURE_FLAG_TIMED) != 0) {
if ((unsigned int)stackReadInt32(procedurePtr, 8) < time) {
if ((unsigned int)stackReadInt32(procedurePtr, offsetof(Procedure, time)) < time) {
// NOTE: Uninline.
stackWriteInt32(0, procedurePtr, 4);
stackWriteInt32(0, procedurePtr, offsetof(Procedure, flags));
_executeProc(programListNode->program, procedureIndex);
}
}
@@ -2937,12 +2962,12 @@ static void programListNodeFree(ProgramListNode* programListNode)
ProgramListNode* tmp;
tmp = programListNode->next;
if (tmp != NULL) {
if (tmp != nullptr) {
tmp->prev = programListNode->prev;
}
tmp = programListNode->prev;
if (tmp != NULL) {
if (tmp != nullptr) {
tmp->next = programListNode->next;
} else {
gInterpreterProgramListHead = programListNode->next;
@@ -2958,9 +2983,9 @@ void programListNodeCreate(Program* program)
ProgramListNode* programListNode = (ProgramListNode*)internal_malloc_safe(sizeof(*programListNode), __FILE__, __LINE__); // .\\int\\INTRPRET.C, 2907
programListNode->program = program;
programListNode->next = gInterpreterProgramListHead;
programListNode->prev = NULL;
programListNode->prev = nullptr;
if (gInterpreterProgramListHead != NULL) {
if (gInterpreterProgramListHead != nullptr) {
gInterpreterProgramListHead->prev = programListNode;
}
@@ -2985,7 +3010,7 @@ Program* runScript(char* name)
// NOTE: Uninline.
program = programCreateByPath(_interpretMangleName(name));
if (program != NULL) {
if (program != nullptr) {
// NOTE: Uninline.
runProgram(program);
_interpret(program, 24);
@@ -2997,10 +3022,19 @@ Program* runScript(char* name)
// 0x46E1EC
void _updatePrograms()
{
// CE: Implementation is different. Sfall inserts global scripts into
// program list upon creation, so engine does not diffirentiate between
// global and normal scripts. Global scripts in CE are not part of program
// list, so we need a separate call to continue execution (usually
// non-critical calls scheduled from managed windows). One more thing to
// note is that global scripts in CE cannot handle conditional/timed procs
// (which are not used anyway).
sfall_gl_scr_update(_cpuBurstSize);
ProgramListNode* curr = gInterpreterProgramListHead;
while (curr != NULL) {
while (curr != nullptr) {
ProgramListNode* next = curr->next;
if (curr->program != NULL) {
if (curr->program != nullptr) {
_interpret(curr->program, _cpuBurstSize);
if (curr->program->exited) {
@@ -3017,7 +3051,7 @@ void _updatePrograms()
void programListFree()
{
ProgramListNode* curr = gInterpreterProgramListHead;
while (curr != NULL) {
while (curr != nullptr) {
ProgramListNode* next = curr->next;
programListNodeFree(curr);
curr = next;
@@ -3040,12 +3074,12 @@ void interpreterRegisterOpcode(int opcode, OpcodeHandler* handler)
static void interpreterPrintStats()
{
ProgramListNode* programListNode = gInterpreterProgramListHead;
while (programListNode != NULL) {
while (programListNode != nullptr) {
Program* program = programListNode->program;
if (program != NULL) {
if (program != nullptr) {
int total = 0;
if (program->dynamicStrings != NULL) {
if (program->dynamicStrings != nullptr) {
debugPrint("Program %s\n");
unsigned char* heap = program->dynamicStrings + sizeof(int);
@@ -3170,7 +3204,7 @@ void* programStackPopPointer(Program* program)
// uninitialized exported variables designed to hold objects (pointers).
// If this is one theses places simply return NULL.
if (programValue.opcode == VALUE_TYPE_INT && programValue.integerValue == 0) {
return NULL;
return nullptr;
}
if (programValue.opcode != VALUE_TYPE_PTR) {
@@ -3237,7 +3271,7 @@ void* programReturnStackPopPointer(Program* program)
return programValue.pointerValue;
}
bool ProgramValue::isEmpty()
bool ProgramValue::isEmpty() const
{
switch (opcode) {
case VALUE_TYPE_INT:
@@ -3253,4 +3287,67 @@ bool ProgramValue::isEmpty()
return true;
}
// Matches Sfall implementation.
bool ProgramValue::isInt() const
{
return opcode == VALUE_TYPE_INT;
}
// Matches Sfall implementation.
bool ProgramValue::isFloat() const
{
return opcode == VALUE_TYPE_FLOAT;
}
// Matches Sfall implementation.
float ProgramValue::asFloat() const
{
switch (opcode) {
case VALUE_TYPE_INT:
return static_cast<float>(integerValue);
case VALUE_TYPE_FLOAT:
return floatValue;
default:
return 0.0;
}
}
bool ProgramValue::isString() const
{
return opcode == VALUE_TYPE_STRING || opcode == VALUE_TYPE_DYNAMIC_STRING;
}
ProgramValue::ProgramValue()
{
opcode = VALUE_TYPE_INT;
integerValue = 0;
}
ProgramValue::ProgramValue(int value)
{
opcode = VALUE_TYPE_INT;
integerValue = value;
};
ProgramValue::ProgramValue(Object* value)
{
opcode = VALUE_TYPE_PTR;
pointerValue = value;
};
bool ProgramValue::isPointer() const
{
return opcode == VALUE_TYPE_PTR;
}
int ProgramValue::asInt() const
{
switch (opcode) {
case VALUE_TYPE_INT:
return integerValue;
case VALUE_TYPE_FLOAT:
return static_cast<int>(floatValue);
default:
return 0;
}
}
} // namespace fallout

View File

@@ -1,6 +1,7 @@
#ifndef INTERPRETER_H
#define INTERPRETER_H
#include "object.h"
#include <setjmp.h>
#include <vector>
@@ -132,15 +133,20 @@ enum RawValueType {
typedef unsigned short opcode_t;
typedef struct Procedure {
int field_0;
int field_4;
int field_8;
int field_C;
int field_10;
int field_14;
int nameOffset;
int flags;
int time;
int conditionOffset;
int bodyOffset;
int argCount;
} Procedure;
typedef struct ProgramValue {
class ProgramValue {
public:
ProgramValue();
ProgramValue(int value);
ProgramValue(Object* value);
opcode_t opcode;
union {
int integerValue;
@@ -148,8 +154,14 @@ typedef struct ProgramValue {
void* pointerValue;
};
bool isEmpty();
} ProgramValue;
bool isEmpty() const;
bool isInt() const;
bool isFloat() const;
bool isString() const;
float asFloat() const;
bool isPointer() const;
int asInt() const;
};
typedef std::vector<ProgramValue> ProgramStack;
@@ -192,6 +204,7 @@ void _interpretOutputFunc(int (*func)(char*));
int _interpretOutput(const char* format, ...);
[[noreturn]] void programFatalError(const char* str, ...);
void _interpretDecStringRef(Program* program, opcode_t a2, int a3);
void programFree(Program* program);
Program* programCreateByPath(const char* path);
char* programGetString(Program* program, opcode_t opcode, int offset);
char* programGetIdentifier(Program* program, int offset);

File diff suppressed because it is too large Load Diff

View File

@@ -171,7 +171,7 @@ void opFillWin3x3(Program* program)
int imageWidth;
int imageHeight;
unsigned char* imageData = datafileRead(mangledFileName, &imageWidth, &imageHeight);
if (imageData == NULL) {
if (imageData == nullptr) {
programFatalError("cannot load 3x3 file '%s'", mangledFileName);
}
@@ -250,11 +250,11 @@ void opSelectFileList(Program* program)
int fileListLength;
char** fileList = _getFileList(_interpretMangleName(pattern), &fileListLength);
if (fileList != NULL && fileListLength != 0) {
if (fileList != nullptr && fileListLength != 0) {
int selectedIndex = _win_list_select(title,
fileList,
fileListLength,
NULL,
nullptr,
320 - fontGetStringWidth(title) / 2,
200,
_colorTable[0x7FFF] | 0x10000);
@@ -281,7 +281,7 @@ void opTokenize(Program* program)
ProgramValue prevValue = programStackPopValue(program);
char* prev = NULL;
char* prev = nullptr;
if ((prevValue.opcode & VALUE_TYPE_MASK) == VALUE_TYPE_INT) {
if (prevValue.integerValue != 0) {
programFatalError("Error, invalid arg 2 to tokenize. (only accept 0 for int value)");
@@ -293,11 +293,11 @@ void opTokenize(Program* program)
}
char* string = programStackPopString(program);
char* temp = NULL;
char* temp = nullptr;
if (prev != NULL) {
if (prev != nullptr) {
char* start = strstr(string, prev);
if (start != NULL) {
if (start != nullptr) {
start += strlen(prev);
while (*start != ch && *start != '\0') {
start++;
@@ -326,7 +326,7 @@ void opTokenize(Program* program)
length++;
}
if (string != NULL) {
if (string != nullptr) {
temp = (char*)internal_calloc_safe(1, length + 1, __FILE__, __LINE__); // "..\\int\\INTLIB.C", 248
strncpy(temp, string, length);
programStackPushString(program, temp);
@@ -335,7 +335,7 @@ void opTokenize(Program* program)
}
}
if (temp != NULL) {
if (temp != nullptr) {
internal_free_safe(temp, __FILE__, __LINE__); // "..\\int\\INTLIB.C" , 260
}
}
@@ -589,7 +589,7 @@ void opPlayMovie(Program* program)
strcpy(gIntLibPlayMovieFileName, movieFileName);
if (strrchr(gIntLibPlayMovieFileName, '.') == NULL) {
if (strrchr(gIntLibPlayMovieFileName, '.') == nullptr) {
strcat(gIntLibPlayMovieFileName, ".mve");
}
@@ -616,7 +616,7 @@ void opPlayMovieRect(Program* program)
strcpy(gIntLibPlayMovieRectFileName, movieFileName);
if (strrchr(gIntLibPlayMovieRectFileName, '.') == NULL) {
if (strrchr(gIntLibPlayMovieRectFileName, '.') == nullptr) {
strcat(gIntLibPlayMovieRectFileName, ".mve");
}
@@ -659,7 +659,7 @@ static void opDeleteRegion(Program* program)
_selectWindowID(program->windowId);
const char* regionName = value.integerValue != -1 ? programGetString(program, value.opcode, value.integerValue) : NULL;
const char* regionName = value.integerValue != -1 ? programGetString(program, value.opcode, value.integerValue) : nullptr;
_windowDeleteRegion(regionName);
}
@@ -858,7 +858,7 @@ static void opSayReplyTitle(Program* program)
{
ProgramValue value = programStackPopValue(program);
char* string = NULL;
char* string = nullptr;
if ((value.opcode & VALUE_TYPE_MASK) == VALUE_TYPE_STRING) {
string = programGetString(program, value.opcode, value.integerValue);
}
@@ -874,7 +874,7 @@ static void opSayGoToReply(Program* program)
{
ProgramValue value = programStackPopValue(program);
char* string = NULL;
char* string = nullptr;
if ((value.opcode & VALUE_TYPE_MASK) == VALUE_TYPE_STRING) {
string = programGetString(program, value.opcode, value.integerValue);
}
@@ -897,7 +897,7 @@ void opSayReply(Program* program)
if ((v2.opcode & VALUE_TYPE_MASK) == VALUE_TYPE_STRING) {
v1 = programGetString(program, v2.opcode, v2.integerValue);
} else {
v1 = NULL;
v1 = nullptr;
}
if ((v3.opcode & VALUE_TYPE_MASK) == VALUE_TYPE_STRING) {
@@ -930,14 +930,14 @@ void opSayOption(Program* program)
if ((v4.opcode & VALUE_TYPE_MASK) == VALUE_TYPE_STRING) {
v1 = programGetString(program, v4.opcode, v4.integerValue);
} else {
v1 = NULL;
v1 = nullptr;
}
const char* v2;
if ((v3.opcode & VALUE_TYPE_MASK) == VALUE_TYPE_STRING) {
v2 = programGetString(program, v3.opcode, v3.integerValue);
} else {
v2 = NULL;
v2 = nullptr;
}
if (_dialogReply(v1, v2) != 0) {
@@ -1028,14 +1028,14 @@ void opSayMessage(Program* program)
if ((v4.opcode & VALUE_TYPE_MASK) == VALUE_TYPE_STRING) {
v1 = programGetString(program, v4.opcode, v4.integerValue);
} else {
v1 = NULL;
v1 = nullptr;
}
const char* v2;
if ((v3.opcode & VALUE_TYPE_MASK) == VALUE_TYPE_STRING) {
v2 = programGetString(program, v3.opcode, v3.integerValue);
} else {
v2 = NULL;
v2 = nullptr;
}
if (sub_430FD4(v1, v2, _TimeOut) != 0) {
@@ -1201,7 +1201,7 @@ static void opDeleteButton(Program* program)
_selectWindowID(program->windowId);
if ((value.opcode & 0xF7FF) == VALUE_TYPE_INT) {
if (_windowDeleteButton(NULL)) {
if (_windowDeleteButton(nullptr)) {
return;
}
} else {
@@ -1424,13 +1424,13 @@ static void opDeleteKey(Program* program)
if (key == -1) {
gIntLibGenericKeyHandlerProc = 0;
gIntLibGenericKeyHandlerProgram = NULL;
gIntLibGenericKeyHandlerProgram = nullptr;
} else {
if (key > INT_LIB_KEY_HANDLERS_CAPACITY - 1) {
programFatalError("Key out of range");
}
gIntLibKeyHandlerEntries[key].program = NULL;
gIntLibKeyHandlerEntries[key].program = nullptr;
gIntLibKeyHandlerEntries[key].proc = 0;
}
}
@@ -1596,7 +1596,7 @@ void opSayReplyWindow(Program* program)
v1 = _interpretMangleName(v1);
v1 = strdup_safe(v1, __FILE__, __LINE__); // "..\\int\\INTLIB.C", 1510
} else if ((v2.opcode & VALUE_TYPE_MASK) == VALUE_TYPE_INT && v2.integerValue == 0) {
v1 = NULL;
v1 = nullptr;
} else {
programFatalError("Invalid arg 5 given to sayreplywindow");
}
@@ -1644,7 +1644,7 @@ void opSayOptionWindow(Program* program)
v1 = _interpretMangleName(v1);
v1 = strdup_safe(v1, __FILE__, __LINE__); // "..\\int\\INTLIB.C", 1556
} else if ((v2.opcode & VALUE_TYPE_MASK) == VALUE_TYPE_INT && v2.integerValue == 0) {
v1 = NULL;
v1 = nullptr;
} else {
programFatalError("Invalid arg 5 given to sayoptionwindow");
}
@@ -1677,10 +1677,10 @@ void opSayScrollUp(Program* program)
int y = programStackPopInteger(program);
int x = programStackPopInteger(program);
char* v1 = NULL;
char* v2 = NULL;
char* v3 = NULL;
char* v4 = NULL;
char* v1 = nullptr;
char* v2 = nullptr;
char* v3 = nullptr;
char* v4 = nullptr;
int v5 = 0;
if ((v6.opcode & VALUE_TYPE_MASK) == VALUE_TYPE_INT) {
@@ -1749,10 +1749,10 @@ void opSayScrollDown(Program* program)
int y = programStackPopInteger(program);
int x = programStackPopInteger(program);
char* v1 = NULL;
char* v2 = NULL;
char* v3 = NULL;
char* v4 = NULL;
char* v1 = nullptr;
char* v2 = nullptr;
char* v3 = nullptr;
char* v4 = nullptr;
int v5 = 0;
if ((v6.opcode & VALUE_TYPE_MASK) == VALUE_TYPE_INT) {
@@ -1837,7 +1837,7 @@ static void intLibSoundCallback(void* userData, int a2)
{
if (a2 == 1) {
Sound** sound = (Sound**)userData;
*sound = NULL;
*sound = nullptr;
}
}
@@ -1854,7 +1854,7 @@ static int intLibSoundDelete(int value)
int index = value & ~0xA0000000;
Sound* sound = gIntLibSounds[index];
if (sound == NULL) {
if (sound == nullptr) {
return 0;
}
@@ -1864,7 +1864,7 @@ static int intLibSoundDelete(int value)
soundDelete(sound);
gIntLibSounds[index] = NULL;
gIntLibSounds[index] = nullptr;
return 1;
}
@@ -1899,7 +1899,7 @@ static int intLibSoundPlay(char* fileName, int mode)
int index;
for (index = 0; index < INT_LIB_SOUNDS_CAPACITY; index++) {
if (gIntLibSounds[index] == NULL) {
if (gIntLibSounds[index] == nullptr) {
break;
}
}
@@ -1909,7 +1909,7 @@ static int intLibSoundPlay(char* fileName, int mode)
}
Sound* sound = gIntLibSounds[index] = soundAllocate(type, soundFlags);
if (sound == NULL) {
if (sound == nullptr) {
return -1;
}
@@ -1984,7 +1984,7 @@ static int intLibSoundPlay(char* fileName, int mode)
err:
soundDelete(sound);
gIntLibSounds[index] = NULL;
gIntLibSounds[index] = nullptr;
return -1;
}
@@ -2001,7 +2001,7 @@ static int intLibSoundPause(int value)
int index = value & ~0xA0000000;
Sound* sound = gIntLibSounds[index];
if (sound == NULL) {
if (sound == nullptr) {
return 0;
}
@@ -2027,7 +2027,7 @@ static int intLibSoundRewind(int value)
int index = value & ~0xA0000000;
Sound* sound = gIntLibSounds[index];
if (sound == NULL) {
if (sound == nullptr) {
return 0;
}
@@ -2053,7 +2053,7 @@ static int intLibSoundResume(int value)
int index = value & ~0xA0000000;
Sound* sound = gIntLibSounds[index];
if (sound == NULL) {
if (sound == nullptr) {
return 0;
}
@@ -2152,16 +2152,16 @@ void intLibExit()
_intExtraClose_();
for (int index = 0; index < INT_LIB_SOUNDS_CAPACITY; index++) {
if (gIntLibSounds[index] != NULL) {
if (gIntLibSounds[index] != nullptr) {
intLibSoundDelete(index | 0xA0000000);
}
}
_nevs_close();
if (gIntLibProgramDeleteCallbacks != NULL) {
if (gIntLibProgramDeleteCallbacks != nullptr) {
internal_free_safe(gIntLibProgramDeleteCallbacks, __FILE__, __LINE__); // "..\\int\\INTLIB.C", 1976
gIntLibProgramDeleteCallbacks = NULL;
gIntLibProgramDeleteCallbacks = nullptr;
gIntLibProgramDeleteCallbacksLength = 0;
}
}
@@ -2173,7 +2173,7 @@ static bool intLibDoInput(int key)
return false;
}
if (gIntLibGenericKeyHandlerProgram != NULL) {
if (gIntLibGenericKeyHandlerProgram != nullptr) {
if (gIntLibGenericKeyHandlerProc != 0) {
_executeProc(gIntLibGenericKeyHandlerProgram, gIntLibGenericKeyHandlerProc);
}
@@ -2181,7 +2181,7 @@ static bool intLibDoInput(int key)
}
IntLibKeyHandlerEntry* entry = &(gIntLibKeyHandlerEntries[key]);
if (entry->program == NULL) {
if (entry->program == nullptr) {
return false;
}
@@ -2291,13 +2291,13 @@ void intLibRegisterProgramDeleteCallback(IntLibProgramDeleteCallback* callback)
{
int index;
for (index = 0; index < gIntLibProgramDeleteCallbacksLength; index++) {
if (gIntLibProgramDeleteCallbacks[index] == NULL) {
if (gIntLibProgramDeleteCallbacks[index] == nullptr) {
break;
}
}
if (index == gIntLibProgramDeleteCallbacksLength) {
if (gIntLibProgramDeleteCallbacks != NULL) {
if (gIntLibProgramDeleteCallbacks != nullptr) {
gIntLibProgramDeleteCallbacks = (IntLibProgramDeleteCallback**)internal_realloc_safe(gIntLibProgramDeleteCallbacks, sizeof(*gIntLibProgramDeleteCallbacks) * (gIntLibProgramDeleteCallbacksLength + 1), __FILE__, __LINE__); // ..\\int\\INTLIB.C, 2110
} else {
gIntLibProgramDeleteCallbacks = (IntLibProgramDeleteCallback**)internal_malloc_safe(sizeof(*gIntLibProgramDeleteCallbacks), __FILE__, __LINE__); // ..\\int\\INTLIB.C, 2112
@@ -2313,7 +2313,7 @@ void intLibRemoveProgramReferences(Program* program)
{
for (int index = 0; index < INT_LIB_KEY_HANDLERS_CAPACITY; index++) {
if (program == gIntLibKeyHandlerEntries[index].program) {
gIntLibKeyHandlerEntries[index].program = NULL;
gIntLibKeyHandlerEntries[index].program = nullptr;
}
}
@@ -2321,7 +2321,7 @@ void intLibRemoveProgramReferences(Program* program)
for (int index = 0; index < gIntLibProgramDeleteCallbacksLength; index++) {
IntLibProgramDeleteCallback* callback = gIntLibProgramDeleteCallbacks[index];
if (callback != NULL) {
if (callback != nullptr) {
callback(program);
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -23,10 +23,11 @@ int _inven_wield(Object* a1, Object* a2, int a3);
int _invenWieldFunc(Object* a1, Object* a2, int a3, bool a4);
int _inven_unwield(Object* critter_obj, int a2);
int _invenUnwieldFunc(Object* obj, int a2, int a3);
int inventoryOpenLooting(Object* a1, Object* a2);
int inventoryOpenStealing(Object* a1, Object* a2);
void inventoryOpenTrade(int win, Object* a2, Object* a3, Object* a4, int a5);
int inventoryOpenLooting(Object* looter, Object* target);
int inventoryOpenStealing(Object* thief, Object* target);
void inventoryOpenTrade(int win, Object* barterer, Object* playerTable, Object* bartererTable, int barterMod);
int _inven_set_timer(Object* a1);
Object* inven_get_current_target_obj();
} // namespace fallout

File diff suppressed because it is too large Load Diff

View File

@@ -1400,11 +1400,11 @@ static void keyboardBuildFrenchConfiguration()
gLogicalKeyEntries[SDL_SCANCODE_BACKSLASH].rmenu = -1;
gLogicalKeyEntries[SDL_SCANCODE_BACKSLASH].ctrl = -1;
//gLogicalKeyEntries[DIK_OEM_102].unmodified = KEY_LESS;
//gLogicalKeyEntries[DIK_OEM_102].shift = KEY_GREATER;
//gLogicalKeyEntries[DIK_OEM_102].lmenu = -1;
//gLogicalKeyEntries[DIK_OEM_102].rmenu = -1;
//gLogicalKeyEntries[DIK_OEM_102].ctrl = -1;
// gLogicalKeyEntries[DIK_OEM_102].unmodified = KEY_LESS;
// gLogicalKeyEntries[DIK_OEM_102].shift = KEY_GREATER;
// gLogicalKeyEntries[DIK_OEM_102].lmenu = -1;
// gLogicalKeyEntries[DIK_OEM_102].rmenu = -1;
// gLogicalKeyEntries[DIK_OEM_102].ctrl = -1;
switch (gKeyboardLayout) {
case KEYBOARD_LAYOUT_QWERTY:
@@ -1583,11 +1583,11 @@ static void keyboardBuildGermanConfiguration()
gLogicalKeyEntries[SDL_SCANCODE_BACKSLASH].rmenu = -1;
gLogicalKeyEntries[SDL_SCANCODE_BACKSLASH].ctrl = -1;
//gLogicalKeyEntries[DIK_OEM_102].unmodified = KEY_LESS;
//gLogicalKeyEntries[DIK_OEM_102].shift = KEY_GREATER;
//gLogicalKeyEntries[DIK_OEM_102].lmenu = -1;
//gLogicalKeyEntries[DIK_OEM_102].rmenu = KEY_166;
//gLogicalKeyEntries[DIK_OEM_102].ctrl = -1;
// gLogicalKeyEntries[DIK_OEM_102].unmodified = KEY_LESS;
// gLogicalKeyEntries[DIK_OEM_102].shift = KEY_GREATER;
// gLogicalKeyEntries[DIK_OEM_102].lmenu = -1;
// gLogicalKeyEntries[DIK_OEM_102].rmenu = KEY_166;
// gLogicalKeyEntries[DIK_OEM_102].ctrl = -1;
switch (gKeyboardLayout) {
case KEYBOARD_LAYOUT_FRENCH:
@@ -1684,11 +1684,11 @@ static void keyboardBuildItalianConfiguration()
gLogicalKeyEntries[SDL_SCANCODE_GRAVE].rmenu = -1;
gLogicalKeyEntries[SDL_SCANCODE_GRAVE].ctrl = -1;
//gLogicalKeyEntries[DIK_OEM_102].unmodified = KEY_LESS;
//gLogicalKeyEntries[DIK_OEM_102].shift = KEY_GREATER;
//gLogicalKeyEntries[DIK_OEM_102].lmenu = -1;
//gLogicalKeyEntries[DIK_OEM_102].rmenu = -1;
//gLogicalKeyEntries[DIK_OEM_102].ctrl = -1;
// gLogicalKeyEntries[DIK_OEM_102].unmodified = KEY_LESS;
// gLogicalKeyEntries[DIK_OEM_102].shift = KEY_GREATER;
// gLogicalKeyEntries[DIK_OEM_102].lmenu = -1;
// gLogicalKeyEntries[DIK_OEM_102].rmenu = -1;
// gLogicalKeyEntries[DIK_OEM_102].ctrl = -1;
gLogicalKeyEntries[SDL_SCANCODE_1].unmodified = KEY_1;
gLogicalKeyEntries[SDL_SCANCODE_1].shift = KEY_EXCLAMATION;
@@ -1896,11 +1896,11 @@ static void keyboardBuildSpanishConfiguration()
gLogicalKeyEntries[SDL_SCANCODE_RIGHTBRACKET].rmenu = KEY_BRACKET_RIGHT;
gLogicalKeyEntries[SDL_SCANCODE_RIGHTBRACKET].ctrl = -1;
//gLogicalKeyEntries[DIK_OEM_102].unmodified = KEY_LESS;
//gLogicalKeyEntries[DIK_OEM_102].shift = KEY_GREATER;
//gLogicalKeyEntries[DIK_OEM_102].lmenu = -1;
//gLogicalKeyEntries[DIK_OEM_102].rmenu = -1;
//gLogicalKeyEntries[DIK_OEM_102].ctrl = -1;
// gLogicalKeyEntries[DIK_OEM_102].unmodified = KEY_LESS;
// gLogicalKeyEntries[DIK_OEM_102].shift = KEY_GREATER;
// gLogicalKeyEntries[DIK_OEM_102].lmenu = -1;
// gLogicalKeyEntries[DIK_OEM_102].rmenu = -1;
// gLogicalKeyEntries[DIK_OEM_102].ctrl = -1;
gLogicalKeyEntries[SDL_SCANCODE_SEMICOLON].unmodified = KEY_241;
gLogicalKeyEntries[SDL_SCANCODE_SEMICOLON].shift = KEY_209;

View File

@@ -36,16 +36,16 @@ LipsData gLipsData = {
2,
22528,
0,
NULL,
nullptr,
-1,
nullptr,
nullptr,
0,
0,
0,
0,
0,
0,
0,
0,
nullptr,
0,
0,
50,
@@ -221,10 +221,10 @@ static int lipsReadV1(LipsData* lipsData, File* stream)
// NOTE: Original code is different. For unknown reason it assigns values
// from file (integers) and treat them as pointers, which is obviously wrong
// is in this case.
lipsData->sound = NULL;
lipsData->field_14 = NULL;
lipsData->phonemes = NULL;
lipsData->markers = NULL;
lipsData->sound = nullptr;
lipsData->field_14 = nullptr;
lipsData->phonemes = nullptr;
lipsData->markers = nullptr;
return 0;
}
@@ -250,14 +250,14 @@ int lipsLoad(const char* audioFileName, const char* headFileName)
strcat(path, "\\");
sep = strchr(path, '.');
if (sep != NULL) {
if (sep != nullptr) {
*sep = '\0';
}
strcpy(v60, audioFileName);
sep = strchr(v60, '.');
if (sep != NULL) {
if (sep != nullptr) {
*sep = '\0';
}
@@ -271,7 +271,7 @@ int lipsLoad(const char* audioFileName, const char* headFileName)
// FIXME: stream is not closed if any error is encountered during reading.
File* stream = fileOpen(path, "rb");
if (stream != NULL) {
if (stream != nullptr) {
if (fileReadInt32(stream, &(gLipsData.version)) == -1) {
return -1;
}
@@ -304,12 +304,12 @@ int lipsLoad(const char* audioFileName, const char* headFileName)
}
gLipsData.phonemes = (unsigned char*)internal_malloc(gLipsData.field_24);
if (gLipsData.phonemes == NULL) {
if (gLipsData.phonemes == nullptr) {
debugPrint("Out of memory in lips_load_file.'\n");
return -1;
}
if (stream != NULL) {
if (stream != nullptr) {
for (i = 0; i < gLipsData.field_24; i++) {
if (fileReadUInt8(stream, &(gLipsData.phonemes[i])) == -1) {
debugPrint("lips_load_file: Error reading phoneme type.\n");
@@ -326,12 +326,12 @@ int lipsLoad(const char* audioFileName, const char* headFileName)
}
gLipsData.markers = (SpeechMarker*)internal_malloc(sizeof(*speech_marker) * gLipsData.field_2C);
if (gLipsData.markers == NULL) {
if (gLipsData.markers == nullptr) {
debugPrint("Out of memory in lips_load_file.'\n");
return -1;
}
if (stream != NULL) {
if (stream != nullptr) {
for (i = 0; i < gLipsData.field_2C; i++) {
speech_marker = &(gLipsData.markers[i]);
@@ -368,7 +368,7 @@ int lipsLoad(const char* audioFileName, const char* headFileName)
}
}
if (stream != NULL) {
if (stream != nullptr) {
fileClose(stream);
}
@@ -399,34 +399,34 @@ int lipsLoad(const char* audioFileName, const char* headFileName)
// 0x47B5D0
static int _lips_make_speech()
{
if (gLipsData.field_14 != NULL) {
if (gLipsData.field_14 != nullptr) {
internal_free(gLipsData.field_14);
gLipsData.field_14 = NULL;
gLipsData.field_14 = nullptr;
}
char path[COMPAT_MAX_PATH];
char* v1 = _lips_fix_string(gLipsData.field_50, sizeof(gLipsData.field_50));
snprintf(path, sizeof(path), "%s%s\\%s.%s", "SOUND\\SPEECH\\", _lips_subdir_name, v1, "ACM");
if (gLipsData.sound != NULL) {
if (gLipsData.sound != nullptr) {
soundDelete(gLipsData.sound);
gLipsData.sound = NULL;
gLipsData.sound = nullptr;
}
gLipsData.sound = soundAllocate(SOUND_TYPE_MEMORY, SOUND_16BIT);
if (gLipsData.sound == NULL) {
if (gLipsData.sound == nullptr) {
debugPrint("\nsoundAllocate falied in lips_make_speech!");
return -1;
}
if (soundSetFileIO(gLipsData.sound, audioOpen, audioClose, audioRead, NULL, audioSeek, NULL, audioGetSize)) {
if (soundSetFileIO(gLipsData.sound, audioOpen, audioClose, audioRead, nullptr, audioSeek, nullptr, audioGetSize)) {
debugPrint("Ack!");
debugPrint("Error!");
}
if (soundLoad(gLipsData.sound, path)) {
soundDelete(gLipsData.sound);
gLipsData.sound = NULL;
gLipsData.sound = nullptr;
debugPrint("lips_make_speech: soundLoad failed with path ");
debugPrint("%s -- file probably doesn't exist.\n", path);
@@ -441,12 +441,12 @@ static int _lips_make_speech()
// 0x47B730
int lipsFree()
{
if (gLipsData.field_14 != NULL) {
if (gLipsData.field_14 != nullptr) {
internal_free(gLipsData.field_14);
gLipsData.field_14 = NULL;
gLipsData.field_14 = nullptr;
}
if (gLipsData.sound != NULL) {
if (gLipsData.sound != nullptr) {
_head_marker_current = 0;
soundStop(gLipsData.sound);
@@ -455,17 +455,17 @@ int lipsFree()
soundDelete(gLipsData.sound);
gLipsData.sound = NULL;
gLipsData.sound = nullptr;
}
if (gLipsData.phonemes != NULL) {
if (gLipsData.phonemes != nullptr) {
internal_free(gLipsData.phonemes);
gLipsData.phonemes = NULL;
gLipsData.phonemes = nullptr;
}
if (gLipsData.markers != NULL) {
if (gLipsData.markers != nullptr) {
internal_free(gLipsData.markers);
gLipsData.markers = NULL;
gLipsData.markers = nullptr;
}
return 0;

File diff suppressed because it is too large Load Diff

View File

@@ -18,8 +18,9 @@ void _InitLoadSave();
void _ResetLoadSave();
int lsgSaveGame(int mode);
int lsgLoadGame(int mode);
int _isLoadingGame();
bool _isLoadingGame();
void lsgInit();
int MapDirErase(const char* path, const char* extension);
int _MapDirEraseFile_(const char* a1, const char* a2);
} // namespace fallout

View File

@@ -1,6 +1,5 @@
#include "main.h"
#include <ctype.h>
#include <limits.h>
#include <string.h>
@@ -21,21 +20,22 @@
#include "input.h"
#include "kb.h"
#include "loadsave.h"
#include "mainmenu.h"
#include "map.h"
#include "mouse.h"
#include "object.h"
#include "options.h"
#include "palette.h"
#include "platform_compat.h"
#include "preferences.h"
#include "proto.h"
#include "random.h"
#include "scripts.h"
#include "selfrun.h"
#include "settings.h"
#include "sfall_config.h"
#include "sfall_global_scripts.h"
#include "svga.h"
#include "text_font.h"
#include "version.h"
#include "window.h"
#include "window_manager.h"
#include "window_manager_private.h"
@@ -44,35 +44,9 @@
namespace fallout {
#define MAIN_MENU_WINDOW_WIDTH 640
#define MAIN_MENU_WINDOW_HEIGHT 480
#define DEATH_WINDOW_WIDTH 640
#define DEATH_WINDOW_HEIGHT 480
typedef enum MainMenuButton {
MAIN_MENU_BUTTON_INTRO,
MAIN_MENU_BUTTON_NEW_GAME,
MAIN_MENU_BUTTON_LOAD_GAME,
MAIN_MENU_BUTTON_OPTIONS,
MAIN_MENU_BUTTON_CREDITS,
MAIN_MENU_BUTTON_EXIT,
MAIN_MENU_BUTTON_COUNT,
} MainMenuButton;
typedef enum MainMenuOption {
MAIN_MENU_INTRO,
MAIN_MENU_NEW_GAME,
MAIN_MENU_LOAD_GAME,
MAIN_MENU_SCREENSAVER,
MAIN_MENU_TIMEOUT,
MAIN_MENU_CREDITS,
MAIN_MENU_QUOTES,
MAIN_MENU_EXIT,
MAIN_MENU_SELFRUN,
MAIN_MENU_OPTIONS,
} MainMenuOption;
static bool falloutInit(int argc, char** argv);
static int main_reset_system();
static void main_exit_system();
@@ -87,14 +61,6 @@ static void showDeath();
static void _main_death_voiceover_callback();
static int _mainDeathGrabTextFile(const char* fileName, char* dest);
static int _mainDeathWordWrap(char* text, int width, short* beginnings, short* count);
static int mainMenuWindowInit();
static void mainMenuWindowFree();
static void mainMenuWindowHide(bool animate);
static void mainMenuWindowUnhide(bool animate);
static int _main_menu_is_enabled();
static int mainMenuWindowHandleEvents();
static int main_menu_fatal_error();
static void main_menu_play_sound(const char* fileName);
// 0x5194C8
static char _mainMap[] = "artemple.map";
@@ -103,7 +69,7 @@ static char _mainMap[] = "artemple.map";
static int _main_game_paused = 0;
// 0x5194DC
static char** _main_selfrun_list = NULL;
static char** _main_selfrun_list = nullptr;
// 0x5194E0
static int _main_selfrun_count = 0;
@@ -124,54 +90,9 @@ static bool _main_show_death_scene = false;
// 0x5194EC
static bool gMainMenuScreensaverCycle = false;
// 0x5194F0
static int gMainMenuWindow = -1;
// 0x5194F4
static unsigned char* gMainMenuWindowBuffer = NULL;
// 0x519504
static bool _in_main_menu = false;
// 0x519508
static bool gMainMenuWindowInitialized = false;
// 0x51950C
static unsigned int gMainMenuScreensaverDelay = 120000;
// 0x519510
static const int gMainMenuButtonKeyBindings[MAIN_MENU_BUTTON_COUNT] = {
KEY_LOWERCASE_I, // intro
KEY_LOWERCASE_N, // new game
KEY_LOWERCASE_L, // load game
KEY_LOWERCASE_O, // options
KEY_LOWERCASE_C, // credits
KEY_LOWERCASE_E, // exit
};
// 0x519528
static const int _return_values[MAIN_MENU_BUTTON_COUNT] = {
MAIN_MENU_INTRO,
MAIN_MENU_NEW_GAME,
MAIN_MENU_LOAD_GAME,
MAIN_MENU_OPTIONS,
MAIN_MENU_CREDITS,
MAIN_MENU_EXIT,
};
// 0x614838
static bool _main_death_voiceover_done;
// 0x614840
static int gMainMenuButtons[MAIN_MENU_BUTTON_COUNT];
// 0x614858
static bool gMainMenuWindowHidden;
static FrmImage _mainMenuBackgroundFrmImage;
static FrmImage _mainMenuButtonNormalFrmImage;
static FrmImage _mainMenuButtonPressedFrmImage;
// 0x48099C
int falloutMain(int argc, char** argv)
{
@@ -217,17 +138,20 @@ int falloutMain(int argc, char** argv)
randomSeedPrerandom(-1);
// SFALL: Override starting map.
char* mapName = NULL;
char* mapName = nullptr;
if (configGetString(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_STARTING_MAP_KEY, &mapName)) {
if (*mapName == '\0') {
mapName = NULL;
mapName = nullptr;
}
}
char* mapNameCopy = compat_strdup(mapName != NULL ? mapName : _mainMap);
char* mapNameCopy = compat_strdup(mapName != nullptr ? mapName : _mainMap);
_main_load_new(mapNameCopy);
free(mapNameCopy);
// SFALL: AfterNewGameStartHook.
sfall_gl_scr_exec_start_proc();
mainLoop();
paletteFadeTo(gPaletteWhite);
@@ -290,12 +214,8 @@ int falloutMain(int argc, char** argv)
_main_selfrun_play();
break;
case MAIN_MENU_OPTIONS:
mainMenuWindowHide(false);
mouseShowCursor();
showOptionsWithInitialKeyCode(112);
gameMouseSetCursor(MOUSE_CURSOR_ARROW);
mouseShowCursor();
mainMenuWindowUnhide(0);
mainMenuWindowHide(true);
doPreferences(true);
break;
case MAIN_MENU_CREDITS:
mainMenuWindowHide(true);
@@ -337,7 +257,7 @@ static bool falloutInit(int argc, char** argv)
return false;
}
if (_main_selfrun_list != NULL) {
if (_main_selfrun_list != nullptr) {
_main_selfrun_exit();
}
@@ -377,7 +297,7 @@ static int _main_load_new(char* mapFileName)
_game_user_wants_to_quit = 0;
_main_show_death_scene = 0;
gDude->flags &= ~OBJECT_FLAT;
objectShow(gDude, NULL);
objectShow(gDude, nullptr);
mouseHideCursor();
int win = windowCreate(0, 0, screenGetWidth(), screenGetHeight(), _colorTable[0], WINDOW_MODAL | WINDOW_MOVE_ON_TOP);
@@ -407,7 +327,7 @@ static int main_loadgame_new()
gDude->flags &= ~OBJECT_FLAT;
objectShow(gDude, NULL);
objectShow(gDude, nullptr);
mouseHideCursor();
_map_init();
@@ -421,7 +341,7 @@ static int main_loadgame_new()
// 0x480E34
static void main_unload_new()
{
objectHide(gDude, NULL);
objectHide(gDude, nullptr);
_map_exit();
}
@@ -441,6 +361,10 @@ static void mainLoop()
sharedFpsLimiter.mark();
int keyCode = inputGetInput();
// SFALL: MainLoopHook.
sfall_gl_scr_process_main();
gameHandleKey(keyCode, false);
scriptsHandleRequests();
@@ -471,13 +395,13 @@ static void mainLoop()
// 0x480F38
static void _main_selfrun_exit()
{
if (_main_selfrun_list != NULL) {
if (_main_selfrun_list != nullptr) {
selfrunFreeFileList(&_main_selfrun_list);
}
_main_selfrun_count = 0;
_main_selfrun_index = 0;
_main_selfrun_list = NULL;
_main_selfrun_list = nullptr;
}
// 0x480F64
@@ -489,7 +413,7 @@ static void _main_selfrun_record()
char** fileList;
int fileListLength = fileNameListInit("maps\\*.map", &fileList, 0, 0);
if (fileListLength != 0) {
int selectedFileIndex = _win_list_select("Select Map", fileList, fileListLength, 0, 80, 80, 0x10000 | 0x100 | 4);
int selectedFileIndex = _win_list_select("Select Map", fileList, fileListLength, nullptr, 80, 80, 0x10000 | 0x100 | 4);
if (selectedFileIndex != -1) {
// NOTE: It's size is likely 13 chars (on par with SelfrunData
// fields), but due to the padding it takes 16 chars on stack.
@@ -527,7 +451,7 @@ static void _main_selfrun_record()
mainMenuWindowInit();
if (_main_selfrun_list != NULL) {
if (_main_selfrun_list != nullptr) {
_main_selfrun_exit();
}
@@ -600,7 +524,7 @@ static void showDeath()
if (win != -1) {
do {
unsigned char* windowBuffer = windowGetBuffer(win);
if (windowBuffer == NULL) {
if (windowBuffer == nullptr) {
break;
}
@@ -679,7 +603,7 @@ static void showDeath()
sharedFpsLimiter.throttle();
} while (keyCode == -1 && !_main_death_voiceover_done && getTicksSince(time) < delay);
speechSetEndCallback(NULL);
speechSetEndCallback(nullptr);
speechDelete();
@@ -723,7 +647,7 @@ static void _main_death_voiceover_callback()
static int _mainDeathGrabTextFile(const char* fileName, char* dest)
{
const char* p = strrchr(fileName, '\\');
if (p == NULL) {
if (p == nullptr) {
return -1;
}
@@ -731,7 +655,7 @@ static int _mainDeathGrabTextFile(const char* fileName, char* dest)
snprintf(path, sizeof(path), "text\\%s\\cuts\\%s%s", settings.system.language.c_str(), p + 1, ".TXT");
File* stream = fileOpen(path, "rt");
if (stream == NULL) {
if (stream == nullptr) {
return -1;
}
@@ -760,7 +684,7 @@ static int _mainDeathWordWrap(char* text, int width, short* beginnings, short* c
{
while (true) {
char* sep = strchr(text, ':');
if (sep == NULL) {
if (sep == nullptr) {
break;
}
@@ -785,7 +709,7 @@ static int _mainDeathWordWrap(char* text, int width, short* beginnings, short* c
beginnings[index]--;
}
if (p != NULL) {
if (p != nullptr) {
*p = '\0';
beginnings[index]++;
}
@@ -794,319 +718,4 @@ static int _mainDeathWordWrap(char* text, int width, short* beginnings, short* c
return 0;
}
// 0x481650
static int mainMenuWindowInit()
{
int fid;
MessageListItem msg;
int len;
if (gMainMenuWindowInitialized) {
return 0;
}
colorPaletteLoad("color.pal");
int mainMenuWindowX = (screenGetWidth() - MAIN_MENU_WINDOW_WIDTH) / 2;
int mainMenuWindowY = (screenGetHeight() - MAIN_MENU_WINDOW_HEIGHT) / 2;
gMainMenuWindow = windowCreate(mainMenuWindowX,
mainMenuWindowY,
MAIN_MENU_WINDOW_WIDTH,
MAIN_MENU_WINDOW_HEIGHT,
0,
WINDOW_HIDDEN | WINDOW_MOVE_ON_TOP);
if (gMainMenuWindow == -1) {
// NOTE: Uninline.
return main_menu_fatal_error();
}
gMainMenuWindowBuffer = windowGetBuffer(gMainMenuWindow);
// mainmenu.frm
int backgroundFid = buildFid(OBJ_TYPE_INTERFACE, 140, 0, 0, 0);
if (!_mainMenuBackgroundFrmImage.lock(backgroundFid)) {
// NOTE: Uninline.
return main_menu_fatal_error();
}
blitBufferToBuffer(_mainMenuBackgroundFrmImage.getData(), 640, 480, 640, gMainMenuWindowBuffer, 640);
_mainMenuBackgroundFrmImage.unlock();
int oldFont = fontGetCurrent();
fontSetCurrent(100);
// SFALL: Allow to change font color/flags of copyright/version text
// It's the last byte ('3C' by default) that picks the colour used. The first byte supplies additional flags for this option
// 0x010000 - change the color for version string only
// 0x020000 - underline text (only for the version string)
// 0x040000 - monospace font (only for the version string)
int fontSettings = _colorTable[21091], fontSettingsSFall = 0;
configGetInt(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_MAIN_MENU_FONT_COLOR_KEY, &fontSettingsSFall);
if (fontSettingsSFall && !(fontSettingsSFall & 0x010000))
fontSettings = fontSettingsSFall & 0xFF;
// SFALL: Allow to move copyright text
int offsetX = 0, offsetY = 0;
configGetInt(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_MAIN_MENU_CREDITS_OFFSET_X_KEY, &offsetX);
configGetInt(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_MAIN_MENU_CREDITS_OFFSET_Y_KEY, &offsetY);
// Copyright.
msg.num = 20;
if (messageListGetItem(&gMiscMessageList, &msg)) {
windowDrawText(gMainMenuWindow, msg.text, 0, offsetX + 15, offsetY + 460, fontSettings | 0x06000000);
}
// SFALL: Make sure font settings are applied when using 0x010000 flag
if (fontSettingsSFall)
fontSettings = fontSettingsSFall;
// TODO: Allow to move version text
// Version.
char version[VERSION_MAX];
versionGetVersion(version, sizeof(version));
len = fontGetStringWidth(version);
windowDrawText(gMainMenuWindow, version, 0, 615 - len, 460, fontSettings | 0x06000000);
// menuup.frm
fid = buildFid(OBJ_TYPE_INTERFACE, 299, 0, 0, 0);
if (!_mainMenuButtonNormalFrmImage.lock(fid)) {
// NOTE: Uninline.
return main_menu_fatal_error();
}
// menudown.frm
fid = buildFid(OBJ_TYPE_INTERFACE, 300, 0, 0, 0);
if (!_mainMenuButtonPressedFrmImage.lock(fid)) {
// NOTE: Uninline.
return main_menu_fatal_error();
}
for (int index = 0; index < MAIN_MENU_BUTTON_COUNT; index++) {
gMainMenuButtons[index] = -1;
}
// SFALL: Allow to move menu buttons
offsetX = offsetY = 0;
configGetInt(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_MAIN_MENU_OFFSET_X_KEY, &offsetX);
configGetInt(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_MAIN_MENU_OFFSET_Y_KEY, &offsetY);
for (int index = 0; index < MAIN_MENU_BUTTON_COUNT; index++) {
gMainMenuButtons[index] = buttonCreate(gMainMenuWindow,
offsetX + 30,
offsetY + 19 + index * 42 - index,
26,
26,
-1,
-1,
1111,
gMainMenuButtonKeyBindings[index],
_mainMenuButtonNormalFrmImage.getData(),
_mainMenuButtonPressedFrmImage.getData(),
0,
BUTTON_FLAG_TRANSPARENT);
if (gMainMenuButtons[index] == -1) {
// NOTE: Uninline.
return main_menu_fatal_error();
}
buttonSetMask(gMainMenuButtons[index], _mainMenuButtonNormalFrmImage.getData());
}
fontSetCurrent(104);
// SFALL: Allow to change font color of buttons
fontSettings = _colorTable[21091];
fontSettingsSFall = 0;
configGetInt(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_MAIN_MENU_BIG_FONT_COLOR_KEY, &fontSettingsSFall);
if (fontSettingsSFall)
fontSettings = fontSettingsSFall & 0xFF;
for (int index = 0; index < MAIN_MENU_BUTTON_COUNT; index++) {
msg.num = 9 + index;
if (messageListGetItem(&gMiscMessageList, &msg)) {
len = fontGetStringWidth(msg.text);
fontDrawText(gMainMenuWindowBuffer + offsetX + 640 * (offsetY + 42 * index - index + 20) + 126 - (len / 2), msg.text, 640 - (126 - (len / 2)) - 1, 640, fontSettings);
}
}
fontSetCurrent(oldFont);
gMainMenuWindowInitialized = true;
gMainMenuWindowHidden = true;
return 0;
}
// 0x481968
static void mainMenuWindowFree()
{
if (!gMainMenuWindowInitialized) {
return;
}
for (int index = 0; index < MAIN_MENU_BUTTON_COUNT; index++) {
// FIXME: Why it tries to free only invalid buttons?
if (gMainMenuButtons[index] == -1) {
buttonDestroy(gMainMenuButtons[index]);
}
}
_mainMenuButtonPressedFrmImage.unlock();
_mainMenuButtonNormalFrmImage.unlock();
if (gMainMenuWindow != -1) {
windowDestroy(gMainMenuWindow);
}
gMainMenuWindowInitialized = false;
}
// 0x481A00
static void mainMenuWindowHide(bool animate)
{
if (!gMainMenuWindowInitialized) {
return;
}
if (gMainMenuWindowHidden) {
return;
}
soundContinueAll();
if (animate) {
paletteFadeTo(gPaletteBlack);
soundContinueAll();
}
windowHide(gMainMenuWindow);
gMainMenuWindowHidden = true;
}
// 0x481A48
static void mainMenuWindowUnhide(bool animate)
{
if (!gMainMenuWindowInitialized) {
return;
}
if (!gMainMenuWindowHidden) {
return;
}
windowShow(gMainMenuWindow);
if (animate) {
colorPaletteLoad("color.pal");
paletteFadeTo(_cmap);
}
gMainMenuWindowHidden = false;
}
// 0x481AA8
static int _main_menu_is_enabled()
{
return 1;
}
// 0x481AEC
static int mainMenuWindowHandleEvents()
{
_in_main_menu = true;
bool oldCursorIsHidden = cursorIsHidden();
if (oldCursorIsHidden) {
mouseShowCursor();
}
unsigned int tick = getTicks();
int rc = -1;
while (rc == -1) {
sharedFpsLimiter.mark();
int keyCode = inputGetInput();
for (int buttonIndex = 0; buttonIndex < MAIN_MENU_BUTTON_COUNT; buttonIndex++) {
if (keyCode == gMainMenuButtonKeyBindings[buttonIndex] || keyCode == toupper(gMainMenuButtonKeyBindings[buttonIndex])) {
// NOTE: Uninline.
main_menu_play_sound("nmselec1");
rc = _return_values[buttonIndex];
if (buttonIndex == MAIN_MENU_BUTTON_CREDITS && (gPressedPhysicalKeys[SDL_SCANCODE_RSHIFT] != KEY_STATE_UP || gPressedPhysicalKeys[SDL_SCANCODE_LSHIFT] != KEY_STATE_UP)) {
rc = MAIN_MENU_QUOTES;
}
break;
}
}
if (rc == -1) {
if (keyCode == KEY_CTRL_R) {
rc = MAIN_MENU_SELFRUN;
continue;
} else if (keyCode == KEY_PLUS || keyCode == KEY_EQUAL) {
brightnessIncrease();
} else if (keyCode == KEY_MINUS || keyCode == KEY_UNDERSCORE) {
brightnessDecrease();
} else if (keyCode == KEY_UPPERCASE_D || keyCode == KEY_LOWERCASE_D) {
rc = MAIN_MENU_SCREENSAVER;
continue;
} else if (keyCode == 1111) {
if (!(mouseGetEvent() & MOUSE_EVENT_LEFT_BUTTON_REPEAT)) {
// NOTE: Uninline.
main_menu_play_sound("nmselec0");
}
continue;
}
}
if (keyCode == KEY_ESCAPE || _game_user_wants_to_quit == 3) {
rc = MAIN_MENU_EXIT;
// NOTE: Uninline.
main_menu_play_sound("nmselec1");
break;
} else if (_game_user_wants_to_quit == 2) {
_game_user_wants_to_quit = 0;
} else {
if (getTicksSince(tick) >= gMainMenuScreensaverDelay) {
rc = MAIN_MENU_TIMEOUT;
}
}
renderPresent();
sharedFpsLimiter.throttle();
}
if (oldCursorIsHidden) {
mouseHideCursor();
}
_in_main_menu = false;
return rc;
}
// NOTE: Inlined.
//
// 0x481C88
static int main_menu_fatal_error()
{
mainMenuWindowFree();
return -1;
}
// NOTE: Inlined.
//
// 0x481C94
static void main_menu_play_sound(const char* fileName)
{
soundPlayFile(fileName);
}
} // namespace fallout

399
src/mainmenu.cc Normal file
View File

@@ -0,0 +1,399 @@
#include "mainmenu.h"
#include <ctype.h>
#include "art.h"
#include "color.h"
#include "draw.h"
#include "game.h"
#include "game_sound.h"
#include "input.h"
#include "kb.h"
#include "mouse.h"
#include "palette.h"
#include "preferences.h"
#include "sfall_config.h"
#include "svga.h"
#include "text_font.h"
#include "version.h"
#include "window_manager.h"
namespace fallout {
#define MAIN_MENU_WINDOW_WIDTH 640
#define MAIN_MENU_WINDOW_HEIGHT 480
typedef enum MainMenuButton {
MAIN_MENU_BUTTON_INTRO,
MAIN_MENU_BUTTON_NEW_GAME,
MAIN_MENU_BUTTON_LOAD_GAME,
MAIN_MENU_BUTTON_OPTIONS,
MAIN_MENU_BUTTON_CREDITS,
MAIN_MENU_BUTTON_EXIT,
MAIN_MENU_BUTTON_COUNT,
} MainMenuButton;
static int main_menu_fatal_error();
static void main_menu_play_sound(const char* fileName);
// 0x5194F0
static int gMainMenuWindow = -1;
// 0x5194F4
static unsigned char* gMainMenuWindowBuffer = nullptr;
// 0x519504
static bool _in_main_menu = false;
// 0x519508
static bool gMainMenuWindowInitialized = false;
// 0x51950C
static unsigned int gMainMenuScreensaverDelay = 120000;
// 0x519510
static const int gMainMenuButtonKeyBindings[MAIN_MENU_BUTTON_COUNT] = {
KEY_LOWERCASE_I, // intro
KEY_LOWERCASE_N, // new game
KEY_LOWERCASE_L, // load game
KEY_LOWERCASE_O, // options
KEY_LOWERCASE_C, // credits
KEY_LOWERCASE_E, // exit
};
// 0x519528
static const int _return_values[MAIN_MENU_BUTTON_COUNT] = {
MAIN_MENU_INTRO,
MAIN_MENU_NEW_GAME,
MAIN_MENU_LOAD_GAME,
MAIN_MENU_OPTIONS,
MAIN_MENU_CREDITS,
MAIN_MENU_EXIT,
};
// 0x614840
static int gMainMenuButtons[MAIN_MENU_BUTTON_COUNT];
// 0x614858
static bool gMainMenuWindowHidden;
static FrmImage _mainMenuBackgroundFrmImage;
static FrmImage _mainMenuButtonNormalFrmImage;
static FrmImage _mainMenuButtonPressedFrmImage;
// 0x481650
int mainMenuWindowInit()
{
int fid;
MessageListItem msg;
int len;
if (gMainMenuWindowInitialized) {
return 0;
}
colorPaletteLoad("color.pal");
int mainMenuWindowX = (screenGetWidth() - MAIN_MENU_WINDOW_WIDTH) / 2;
int mainMenuWindowY = (screenGetHeight() - MAIN_MENU_WINDOW_HEIGHT) / 2;
gMainMenuWindow = windowCreate(mainMenuWindowX,
mainMenuWindowY,
MAIN_MENU_WINDOW_WIDTH,
MAIN_MENU_WINDOW_HEIGHT,
0,
WINDOW_HIDDEN | WINDOW_MOVE_ON_TOP);
if (gMainMenuWindow == -1) {
// NOTE: Uninline.
return main_menu_fatal_error();
}
gMainMenuWindowBuffer = windowGetBuffer(gMainMenuWindow);
// mainmenu.frm
int backgroundFid = buildFid(OBJ_TYPE_INTERFACE, 140, 0, 0, 0);
if (!_mainMenuBackgroundFrmImage.lock(backgroundFid)) {
// NOTE: Uninline.
return main_menu_fatal_error();
}
blitBufferToBuffer(_mainMenuBackgroundFrmImage.getData(), 640, 480, 640, gMainMenuWindowBuffer, 640);
_mainMenuBackgroundFrmImage.unlock();
int oldFont = fontGetCurrent();
fontSetCurrent(100);
// SFALL: Allow to change font color/flags of copyright/version text
// It's the last byte ('3C' by default) that picks the colour used. The first byte supplies additional flags for this option
// 0x010000 - change the color for version string only
// 0x020000 - underline text (only for the version string)
// 0x040000 - monospace font (only for the version string)
int fontSettings = _colorTable[21091], fontSettingsSFall = 0;
configGetInt(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_MAIN_MENU_FONT_COLOR_KEY, &fontSettingsSFall);
if (fontSettingsSFall && !(fontSettingsSFall & 0x010000))
fontSettings = fontSettingsSFall & 0xFF;
// SFALL: Allow to move copyright text
int offsetX = 0, offsetY = 0;
configGetInt(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_MAIN_MENU_CREDITS_OFFSET_X_KEY, &offsetX);
configGetInt(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_MAIN_MENU_CREDITS_OFFSET_Y_KEY, &offsetY);
// Copyright.
msg.num = 20;
if (messageListGetItem(&gMiscMessageList, &msg)) {
windowDrawText(gMainMenuWindow, msg.text, 0, offsetX + 15, offsetY + 460, fontSettings | 0x06000000);
}
// SFALL: Make sure font settings are applied when using 0x010000 flag
if (fontSettingsSFall)
fontSettings = fontSettingsSFall;
// TODO: Allow to move version text
// Version.
char version[VERSION_MAX];
versionGetVersion(version, sizeof(version));
len = fontGetStringWidth(version);
windowDrawText(gMainMenuWindow, version, 0, 615 - len, 460, fontSettings | 0x06000000);
// menuup.frm
fid = buildFid(OBJ_TYPE_INTERFACE, 299, 0, 0, 0);
if (!_mainMenuButtonNormalFrmImage.lock(fid)) {
// NOTE: Uninline.
return main_menu_fatal_error();
}
// menudown.frm
fid = buildFid(OBJ_TYPE_INTERFACE, 300, 0, 0, 0);
if (!_mainMenuButtonPressedFrmImage.lock(fid)) {
// NOTE: Uninline.
return main_menu_fatal_error();
}
for (int index = 0; index < MAIN_MENU_BUTTON_COUNT; index++) {
gMainMenuButtons[index] = -1;
}
// SFALL: Allow to move menu buttons
offsetX = offsetY = 0;
configGetInt(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_MAIN_MENU_OFFSET_X_KEY, &offsetX);
configGetInt(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_MAIN_MENU_OFFSET_Y_KEY, &offsetY);
for (int index = 0; index < MAIN_MENU_BUTTON_COUNT; index++) {
gMainMenuButtons[index] = buttonCreate(gMainMenuWindow,
offsetX + 30,
offsetY + 19 + index * 42 - index,
26,
26,
-1,
-1,
1111,
gMainMenuButtonKeyBindings[index],
_mainMenuButtonNormalFrmImage.getData(),
_mainMenuButtonPressedFrmImage.getData(),
nullptr,
BUTTON_FLAG_TRANSPARENT);
if (gMainMenuButtons[index] == -1) {
// NOTE: Uninline.
return main_menu_fatal_error();
}
buttonSetMask(gMainMenuButtons[index], _mainMenuButtonNormalFrmImage.getData());
}
fontSetCurrent(104);
// SFALL: Allow to change font color of buttons
fontSettings = _colorTable[21091];
fontSettingsSFall = 0;
configGetInt(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_MAIN_MENU_BIG_FONT_COLOR_KEY, &fontSettingsSFall);
if (fontSettingsSFall)
fontSettings = fontSettingsSFall & 0xFF;
for (int index = 0; index < MAIN_MENU_BUTTON_COUNT; index++) {
msg.num = 9 + index;
if (messageListGetItem(&gMiscMessageList, &msg)) {
len = fontGetStringWidth(msg.text);
fontDrawText(gMainMenuWindowBuffer + offsetX + 640 * (offsetY + 42 * index - index + 20) + 126 - (len / 2), msg.text, 640 - (126 - (len / 2)) - 1, 640, fontSettings);
}
}
fontSetCurrent(oldFont);
gMainMenuWindowInitialized = true;
gMainMenuWindowHidden = true;
return 0;
}
// 0x481968
void mainMenuWindowFree()
{
if (!gMainMenuWindowInitialized) {
return;
}
for (int index = 0; index < MAIN_MENU_BUTTON_COUNT; index++) {
// FIXME: Why it tries to free only invalid buttons?
if (gMainMenuButtons[index] == -1) {
buttonDestroy(gMainMenuButtons[index]);
}
}
_mainMenuButtonPressedFrmImage.unlock();
_mainMenuButtonNormalFrmImage.unlock();
if (gMainMenuWindow != -1) {
windowDestroy(gMainMenuWindow);
}
gMainMenuWindowInitialized = false;
}
// 0x481A00
void mainMenuWindowHide(bool animate)
{
if (!gMainMenuWindowInitialized) {
return;
}
if (gMainMenuWindowHidden) {
return;
}
soundContinueAll();
if (animate) {
paletteFadeTo(gPaletteBlack);
soundContinueAll();
}
windowHide(gMainMenuWindow);
gMainMenuWindowHidden = true;
}
// 0x481A48
void mainMenuWindowUnhide(bool animate)
{
if (!gMainMenuWindowInitialized) {
return;
}
if (!gMainMenuWindowHidden) {
return;
}
windowShow(gMainMenuWindow);
if (animate) {
colorPaletteLoad("color.pal");
paletteFadeTo(_cmap);
}
gMainMenuWindowHidden = false;
}
// 0x481AA8
int _main_menu_is_enabled()
{
return 1;
}
// 0x481AEC
int mainMenuWindowHandleEvents()
{
_in_main_menu = true;
bool oldCursorIsHidden = cursorIsHidden();
if (oldCursorIsHidden) {
mouseShowCursor();
}
unsigned int tick = getTicks();
int rc = -1;
while (rc == -1) {
sharedFpsLimiter.mark();
int keyCode = inputGetInput();
for (int buttonIndex = 0; buttonIndex < MAIN_MENU_BUTTON_COUNT; buttonIndex++) {
if (keyCode == gMainMenuButtonKeyBindings[buttonIndex] || keyCode == toupper(gMainMenuButtonKeyBindings[buttonIndex])) {
// NOTE: Uninline.
main_menu_play_sound("nmselec1");
rc = _return_values[buttonIndex];
if (buttonIndex == MAIN_MENU_BUTTON_CREDITS && (gPressedPhysicalKeys[SDL_SCANCODE_RSHIFT] != KEY_STATE_UP || gPressedPhysicalKeys[SDL_SCANCODE_LSHIFT] != KEY_STATE_UP)) {
rc = MAIN_MENU_QUOTES;
}
break;
}
}
if (rc == -1) {
if (keyCode == KEY_CTRL_R) {
rc = MAIN_MENU_SELFRUN;
continue;
} else if (keyCode == KEY_PLUS || keyCode == KEY_EQUAL) {
brightnessIncrease();
} else if (keyCode == KEY_MINUS || keyCode == KEY_UNDERSCORE) {
brightnessDecrease();
} else if (keyCode == KEY_UPPERCASE_D || keyCode == KEY_LOWERCASE_D) {
rc = MAIN_MENU_SCREENSAVER;
continue;
} else if (keyCode == 1111) {
if (!(mouseGetEvent() & MOUSE_EVENT_LEFT_BUTTON_REPEAT)) {
// NOTE: Uninline.
main_menu_play_sound("nmselec0");
}
continue;
}
}
if (keyCode == KEY_ESCAPE || _game_user_wants_to_quit == 3) {
rc = MAIN_MENU_EXIT;
// NOTE: Uninline.
main_menu_play_sound("nmselec1");
break;
} else if (_game_user_wants_to_quit == 2) {
_game_user_wants_to_quit = 0;
} else {
if (getTicksSince(tick) >= gMainMenuScreensaverDelay) {
rc = MAIN_MENU_TIMEOUT;
}
}
renderPresent();
sharedFpsLimiter.throttle();
}
if (oldCursorIsHidden) {
mouseHideCursor();
}
_in_main_menu = false;
return rc;
}
// NOTE: Inlined.
//
// 0x481C88
static int main_menu_fatal_error()
{
mainMenuWindowFree();
return -1;
}
// NOTE: Inlined.
//
// 0x481C94
static void main_menu_play_sound(const char* fileName)
{
soundPlayFile(fileName);
}
} // namespace fallout

28
src/mainmenu.h Normal file
View File

@@ -0,0 +1,28 @@
#ifndef FALLOUT_MAINMENU_H_
#define FALLOUT_MAINMENU_H_
namespace fallout {
typedef enum MainMenuOption {
MAIN_MENU_INTRO,
MAIN_MENU_NEW_GAME,
MAIN_MENU_LOAD_GAME,
MAIN_MENU_SCREENSAVER,
MAIN_MENU_TIMEOUT,
MAIN_MENU_CREDITS,
MAIN_MENU_QUOTES,
MAIN_MENU_EXIT,
MAIN_MENU_SELFRUN,
MAIN_MENU_OPTIONS,
} MainMenuOption;
int mainMenuWindowInit();
void mainMenuWindowFree();
void mainMenuWindowHide(bool animate);
void mainMenuWindowUnhide(bool animate);
int _main_menu_is_enabled();
int mainMenuWindowHandleEvents();
} // namespace fallout
#endif /* FALLOUT_MAINMENU_H_ */

View File

@@ -104,11 +104,11 @@ int gMapSid = -1;
// local_vars
// 0x519568
int* gMapLocalVars = NULL;
int* gMapLocalVars = nullptr;
// map_vars
// 0x51956C
static int* gMapGlobalVars = NULL;
int* gMapGlobalVars = nullptr;
// local_vars_num
// 0x519570
@@ -116,7 +116,7 @@ int gMapLocalVarsLength = 0;
// map_vars_num
// 0x519574
static int gMapGlobalVarsLength = 0;
int gMapGlobalVarsLength = 0;
// Current elevation.
//
@@ -187,7 +187,7 @@ int isoInit()
}
gIsoWindowBuffer = windowGetBuffer(gIsoWindow);
if (gIsoWindowBuffer == NULL) {
if (gIsoWindowBuffer == nullptr) {
debugPrint("win_get_buf failed in iso_init\n");
return -1;
}
@@ -478,7 +478,7 @@ int _map_malloc_local_var(int a1)
gMapLocalVarsLength += a1;
int* vars = (int*)internal_realloc(gMapLocalVars, sizeof(*vars) * gMapLocalVarsLength);
if (vars == NULL) {
if (vars == nullptr) {
debugPrint("\nError: Ran out of memory!");
}
@@ -502,11 +502,11 @@ void mapSetStart(int tile, int elevation, int rotation)
char* mapGetName(int map, int elevation)
{
if (map < 0 || map >= wmMapMaxCount()) {
return NULL;
return nullptr;
}
if (!elevationIsValid(elevation)) {
return NULL;
return nullptr;
}
MessageListItem messageListItem;
@@ -760,7 +760,7 @@ int mapLoadByName(char* fileName)
rc = -1;
char* extension = strstr(fileName, ".MAP");
if (extension != NULL) {
if (extension != nullptr) {
strcpy(extension, ".SAV");
const char* filePath = mapBuildPath(fileName);
@@ -769,7 +769,7 @@ int mapLoadByName(char* fileName)
strcpy(extension, ".MAP");
if (stream != NULL) {
if (stream != nullptr) {
fileClose(stream);
rc = mapLoadSaved(fileName);
wmMapMusicStart();
@@ -779,14 +779,14 @@ int mapLoadByName(char* fileName)
if (rc == -1) {
const char* filePath = mapBuildPath(fileName);
File* stream = fileOpen(filePath, "rb");
if (stream != NULL) {
if (stream != nullptr) {
rc = mapLoad(stream);
fileClose(stream);
}
if (rc == 0) {
strcpy(gMapHeader.name, fileName);
gDude->data.critter.combat.whoHitMe = NULL;
gDude->data.critter.combat.whoHitMe = nullptr;
}
}
@@ -840,10 +840,10 @@ static int mapLoad(File* stream)
gMapSid = -1;
const char* error = NULL;
const char* error = nullptr;
error = "Invalid file handle";
if (stream == NULL) {
if (stream == nullptr) {
goto err;
}
@@ -925,8 +925,8 @@ static int mapLoad(File* stream)
}
lightSetAmbientIntensity(LIGHT_INTENSITY_MAX, false);
objectSetLocation(gDude, gCenterTile, gElevation, NULL);
objectSetRotation(gDude, gEnteringRotation, NULL);
objectSetLocation(gDude, gCenterTile, gElevation, nullptr);
objectSetRotation(gDude, gEnteringRotation, nullptr);
gMapHeader.field_34 = wmMapMatchNameToIdx(gMapHeader.name);
if ((gMapHeader.flags & 1) == 0) {
@@ -934,11 +934,11 @@ static int mapLoad(File* stream)
snprintf(path, sizeof(path), "maps\\%s", gMapHeader.name);
char* extension = strstr(path, ".MAP");
if (extension == NULL) {
if (extension == nullptr) {
extension = strstr(path, ".map");
}
if (extension != NULL) {
if (extension != nullptr) {
*extension = '\0';
}
@@ -959,7 +959,7 @@ static int mapLoad(File* stream)
int fid = buildFid(OBJ_TYPE_MISC, 12, 0, 0, 0);
objectCreateWithFidPid(&object, fid, -1);
object->flags |= (OBJECT_LIGHT_THRU | OBJECT_NO_SAVE | OBJECT_HIDDEN);
objectSetLocation(object, 1, 0, NULL);
objectSetLocation(object, 1, 0, nullptr);
object->sid = gMapSid;
scriptSetFixedParam(gMapSid, (gMapHeader.flags & 1) == 0);
@@ -980,11 +980,11 @@ static int mapLoad(File* stream)
}
}
error = NULL;
error = nullptr;
err:
if (error != NULL) {
if (error != nullptr) {
char message[100]; // TODO: Size is probably wrong.
snprintf(message, sizeof(message), "%s while loading map.", error);
debugPrint(message);
@@ -998,7 +998,7 @@ err:
interfaceBarShow();
_proto_dude_update_gender();
_map_place_dude_and_mouse();
fileSetReadProgressHandler(NULL, 0);
fileSetReadProgressHandler(nullptr, 0);
isoEnable();
_gmouse_disable_scrolling();
gameMouseSetCursor(MOUSE_CURSOR_WAIT_PLANET);
@@ -1013,7 +1013,7 @@ err:
if (gMapTransition.map > 0) {
if (gMapTransition.rotation >= 0) {
objectSetRotation(gDude, gMapTransition.rotation, NULL);
objectSetRotation(gDude, gMapTransition.rotation, nullptr);
}
} else {
tileWindowRefresh();
@@ -1032,7 +1032,7 @@ err:
rc = -1;
}
fileSetReadProgressHandler(NULL, 0);
fileSetReadProgressHandler(nullptr, 0);
if (gameUiIsDisabled() == 0) {
_gmouse_enable_scrolling();
@@ -1100,7 +1100,7 @@ static int _map_age_dead_critters()
}
Object* obj = objectFindFirst();
while (obj != NULL) {
while (obj != nullptr) {
if (PID_TYPE(obj->pid) == OBJ_TYPE_CRITTER
&& obj != gDude
&& !objectIsPartyMember(obj)
@@ -1127,7 +1127,7 @@ static int _map_age_dead_critters()
Object** objects = (Object**)internal_malloc(sizeof(*objects) * capacity);
obj = objectFindFirst();
while (obj != NULL) {
while (obj != nullptr) {
int type = PID_TYPE(obj->pid);
if (type == OBJ_TYPE_CRITTER) {
if (obj != gDude && critterIsDead(obj)) {
@@ -1137,7 +1137,7 @@ static int _map_age_dead_critters()
if (count >= capacity) {
capacity *= 2;
objects = (Object**)internal_realloc(objects, sizeof(*objects) * capacity);
if (objects == NULL) {
if (objects == nullptr) {
debugPrint("\nError: Out of Memory!");
return -1;
}
@@ -1149,7 +1149,7 @@ static int _map_age_dead_critters()
if (count >= capacity) {
capacity *= 2;
objects = (Object**)internal_realloc(objects, sizeof(*objects) * capacity);
if (objects == NULL) {
if (objects == nullptr) {
debugPrint("\nError: Out of Memory!");
return -1;
}
@@ -1172,7 +1172,7 @@ static int _map_age_dead_critters()
break;
}
objectSetLocation(blood, obj->tile, obj->elevation, NULL);
objectSetLocation(blood, obj->tile, obj->elevation, nullptr);
Proto* proto;
protoGetProto(obj->pid, &proto);
@@ -1187,11 +1187,11 @@ static int _map_age_dead_critters()
}
}
objectSetFrame(blood, frame, NULL);
objectSetFrame(blood, frame, nullptr);
}
reg_anim_clear(obj);
objectDestroy(obj, NULL);
objectDestroy(obj, nullptr);
}
internal_free(objects);
@@ -1212,7 +1212,7 @@ int _map_target_load_area()
// 0x4835B4
int mapSetTransition(MapTransition* transition)
{
if (transition == NULL) {
if (transition == nullptr) {
return -1;
}
@@ -1261,9 +1261,9 @@ int mapHandleTransition()
if (gMapTransition.tile != -1 && gMapTransition.tile != 0
&& gMapHeader.field_34 != MAP_MODOC_BEDNBREAKFAST && gMapHeader.field_34 != MAP_THE_SQUAT_A
&& elevationIsValid(gMapTransition.elevation)) {
objectSetLocation(gDude, gMapTransition.tile, gMapTransition.elevation, NULL);
objectSetLocation(gDude, gMapTransition.tile, gMapTransition.elevation, nullptr);
mapSetElevation(gMapTransition.elevation);
objectSetRotation(gDude, gMapTransition.rotation, NULL);
objectSetRotation(gDude, gMapTransition.rotation, nullptr);
}
if (tileSetCenter(gDude->tile, TILE_SET_CENTER_REFRESH_WINDOW) == -1) {
@@ -1286,7 +1286,7 @@ int mapHandleTransition()
// 0x483784
static void _map_fix_critter_combat_data()
{
for (Object* object = objectFindFirst(); object != NULL; object = objectFindNext()) {
for (Object* object = objectFindFirst(); object != nullptr; object = objectFindNext()) {
if (object->pid == -1) {
continue;
}
@@ -1296,7 +1296,7 @@ static void _map_fix_critter_combat_data()
}
if (object->data.critter.combat.whoHitMeCid == -1) {
object->data.critter.combat.whoHitMe = NULL;
object->data.critter.combat.whoHitMe = nullptr;
}
}
}
@@ -1318,7 +1318,7 @@ static int _map_save()
if (gMapHeader.name[0] != '\0') {
char* mapFileName = mapBuildPath(gMapHeader.name);
File* stream = fileOpen(mapFileName, "wb");
if (stream != NULL) {
if (stream != nullptr) {
rc = _map_save_file(stream);
fileClose(stream);
} else {
@@ -1340,7 +1340,7 @@ static int _map_save()
// 0x483980
static int _map_save_file(File* stream)
{
if (stream == NULL) {
if (stream == nullptr) {
return -1;
}
@@ -1364,13 +1364,13 @@ static int _map_save_file(File* stream)
if (tile == SQUARE_GRID_SIZE) {
Object* object = objectFindFirstAtElevation(elevation);
if (object != NULL) {
if (object != nullptr) {
// TODO: Implementation is slightly different, check in debugger.
while (object != NULL && (object->flags & OBJECT_NO_SAVE)) {
while (object != nullptr && (object->flags & OBJECT_NO_SAVE)) {
object = objectFindNextAtElevation();
}
if (object != NULL) {
if (object != nullptr) {
gMapHeader.flags &= ~_map_data_elev_flags[elevation];
} else {
gMapHeader.flags |= _map_data_elev_flags[elevation];
@@ -1552,7 +1552,7 @@ static int mapGlobalVariablesInit(int count)
if (count != 0) {
gMapGlobalVars = (int*)internal_malloc(sizeof(*gMapGlobalVars) * count);
if (gMapGlobalVars == NULL) {
if (gMapGlobalVars == nullptr) {
return -1;
}
@@ -1567,9 +1567,9 @@ static int mapGlobalVariablesInit(int count)
// 0x484038
static void mapGlobalVariablesFree()
{
if (gMapGlobalVars != NULL) {
if (gMapGlobalVars != nullptr) {
internal_free(gMapGlobalVars);
gMapGlobalVars = NULL;
gMapGlobalVars = nullptr;
gMapGlobalVarsLength = 0;
}
@@ -1597,7 +1597,7 @@ static int mapLocalVariablesInit(int count)
if (count != 0) {
gMapLocalVars = (int*)internal_malloc(sizeof(*gMapLocalVars) * count);
if (gMapLocalVars == NULL) {
if (gMapLocalVars == nullptr) {
return -1;
}
@@ -1612,9 +1612,9 @@ static int mapLocalVariablesInit(int count)
// 0x4840D4
static void mapLocalVariablesFree()
{
if (gMapLocalVars != NULL) {
if (gMapLocalVars != nullptr) {
internal_free(gMapLocalVars);
gMapLocalVars = NULL;
gMapLocalVars = nullptr;
gMapLocalVarsLength = 0;
}
@@ -1638,18 +1638,18 @@ static void _map_place_dude_and_mouse()
{
_obj_clear_seen();
if (gDude != NULL) {
if (gDude != nullptr) {
if (FID_ANIM_TYPE(gDude->fid) != ANIM_STAND) {
objectSetFrame(gDude, 0, 0);
objectSetFrame(gDude, 0, nullptr);
gDude->fid = buildFid(OBJ_TYPE_CRITTER, gDude->fid & 0xFFF, ANIM_STAND, (gDude->fid & 0xF000) >> 12, gDude->rotation + 1);
}
if (gDude->tile == -1) {
objectSetLocation(gDude, gCenterTile, gElevation, NULL);
objectSetRotation(gDude, gMapHeader.enteringRotation, 0);
objectSetLocation(gDude, gCenterTile, gElevation, nullptr);
objectSetRotation(gDude, gMapHeader.enteringRotation, nullptr);
}
objectSetLight(gDude, 4, 0x10000, 0);
objectSetLight(gDude, 4, 0x10000, nullptr);
gDude->flags |= OBJECT_NO_SAVE;
_dude_stand(gDude, gDude->rotation, gDude->fid);
@@ -1746,7 +1746,7 @@ static int mapHeaderWrite(MapHeader* ptr, File* stream)
if (fileWriteInt32(stream, ptr->darkness) == -1) return -1;
if (fileWriteInt32(stream, ptr->globalVariablesCount) == -1) return -1;
if (fileWriteInt32(stream, ptr->field_34) == -1) return -1;
if (fileWriteInt32(stream, ptr->lastVisitTime) == -1) return -1;
if (fileWriteUInt32(stream, ptr->lastVisitTime) == -1) return -1;
if (fileWriteInt32List(stream, ptr->field_3C, 44) == -1) return -1;
return 0;
@@ -1766,7 +1766,7 @@ static int mapHeaderRead(MapHeader* ptr, File* stream)
if (fileReadInt32(stream, &(ptr->darkness)) == -1) return -1;
if (fileReadInt32(stream, &(ptr->globalVariablesCount)) == -1) return -1;
if (fileReadInt32(stream, &(ptr->field_34)) == -1) return -1;
if (fileReadInt32(stream, &(ptr->lastVisitTime)) == -1) return -1;
if (fileReadUInt32(stream, &(ptr->lastVisitTime)) == -1) return -1;
if (fileReadInt32List(stream, ptr->field_3C, 44) == -1) return -1;
return 0;

View File

@@ -54,7 +54,7 @@ typedef struct MapHeader {
int field_34;
// Time in game ticks when PC last visited this map.
int lastVisitTime;
unsigned int lastVisitTime;
int field_3C[44];
} MapHeader;
@@ -69,7 +69,9 @@ typedef void IsoWindowRefreshProc(Rect* rect);
extern int gMapSid;
extern int* gMapLocalVars;
extern int* gMapGlobalVars;
extern int gMapLocalVarsLength;
extern int gMapGlobalVarsLength;
extern int gElevation;
extern MessageList gMapMessageList;

180
src/mapper/map_func.cc Normal file
View File

@@ -0,0 +1,180 @@
#include "mapper/map_func.h"
#include "actions.h"
#include "color.h"
#include "game_mouse.h"
#include "input.h"
#include "map.h"
#include "memory.h"
#include "mouse.h"
#include "proto.h"
#include "svga.h"
#include "tile.h"
#include "window_manager.h"
#include "window_manager_private.h"
namespace fallout {
// 0x5595CC
static bool block_obj_view_on = false;
// 0x4825B0
void setup_map_dirs()
{
// TODO: Incomplete.
}
// 0x4826B4
void copy_proto_lists()
{
// TODO: Incomplete.
}
// 0x482708
void place_entrance_hex()
{
int x;
int y;
int tile;
while (inputGetInput() != -2) {
}
if ((mouseGetEvent() & MOUSE_EVENT_LEFT_BUTTON_DOWN) != 0) {
if (_mouse_click_in(0, 0, _scr_size.right - _scr_size.left, _scr_size.bottom - _scr_size.top - 100)) {
mouseGetPosition(&x, &y);
tile = tileFromScreenXY(x, y, gElevation);
if (tile != -1) {
if (tileSetCenter(tile, TILE_SET_CENTER_FLAG_IGNORE_SCROLL_RESTRICTIONS) == 0) {
mapSetEnteringLocation(tile, gElevation, rotation);
} else {
win_timed_msg("ERROR: Entrance out of range!", _colorTable[31744]);
}
}
}
}
}
// 0x4841C4
void pick_region(Rect* rect)
{
Rect temp;
int x;
int y;
gameMouseSetCursor(MOUSE_CURSOR_PLUS);
gameMouseObjectsHide();
while (1) {
if (inputGetInput() == -2
&& (mouseGetEvent() & MOUSE_EVENT_LEFT_BUTTON_DOWN) != 0) {
break;
}
}
get_input_position(&x, &y);
temp.left = x;
temp.top = y;
temp.right = x;
temp.bottom = y;
while ((mouseGetEvent() & MOUSE_EVENT_LEFT_BUTTON_UP) == 0) {
inputGetInput();
get_input_position(&x, &y);
if (x != temp.right || y != temp.bottom) {
erase_rect(rect);
sort_rect(rect, &temp);
draw_rect(rect, _colorTable[32747]);
}
}
erase_rect(rect);
gameMouseSetCursor(MOUSE_CURSOR_ARROW);
gameMouseObjectsShow();
}
// 0x484294
void sort_rect(Rect* a, Rect* b)
{
if (b->right > b->left) {
a->left = b->left;
a->right = b->right;
} else {
a->left = b->right;
a->right = b->left;
}
if (b->bottom > b->top) {
a->top = b->top;
a->bottom = b->bottom;
} else {
a->top = b->bottom;
a->bottom = b->top;
}
}
// 0x4842D4
void draw_rect(Rect* rect, unsigned char color)
{
int width = rect->right - rect->left;
int height = rect->bottom - rect->top;
int max_dimension;
if (height < width) {
max_dimension = width;
} else {
max_dimension = height;
}
unsigned char* buffer = (unsigned char*)internal_malloc(max_dimension);
if (buffer != NULL) {
memset(buffer, color, max_dimension);
_scr_blit(buffer, width, 1, 0, 0, width, 1, rect->left, rect->top);
_scr_blit(buffer, 1, height, 0, 0, 1, height, rect->left, rect->top);
_scr_blit(buffer, width, 1, 0, 0, width, 1, rect->left, rect->bottom);
_scr_blit(buffer, 1, height, 0, 0, 1, height, rect->right, rect->top);
internal_free(buffer);
}
}
// 0x4843A0
void erase_rect(Rect* rect)
{
Rect r = *rect;
r.bottom = rect->top;
windowRefreshAll(&r);
r.bottom = rect->bottom;
r.left = rect->right;
windowRefreshAll(&r);
r.left = rect->left;
r.top = rect->bottom;
windowRefreshAll(&r);
r.top = rect->top;
r.right = rect->left;
windowRefreshAll(&r);
}
// 0x484400
int toolbar_proto(int type, int id)
{
if (id < proto_max_id(type)) {
return (type << 24) | id;
} else {
return -1;
}
}
// 0x485D44
bool map_toggle_block_obj_viewing_on()
{
return block_obj_view_on;
}
} // namespace fallout

20
src/mapper/map_func.h Normal file
View File

@@ -0,0 +1,20 @@
#ifndef FALLOUT_MAPPER_MAP_FUNC_H_
#define FALLOUT_MAPPER_MAP_FUNC_H_
#include "geometry.h"
namespace fallout {
void setup_map_dirs();
void copy_proto_lists();
void place_entrance_hex();
void pick_region(Rect* rect);
void sort_rect(Rect* a, Rect* b);
void draw_rect(Rect* rect, unsigned char color);
void erase_rect(Rect* rect);
int toolbar_proto(int type, int id);
bool map_toggle_block_obj_viewing_on();
} // namespace fallout
#endif /* FALLOUT_MAPPER_MAP_FUNC_H_ */

1743
src/mapper/mapper.cc Normal file

File diff suppressed because it is too large Load Diff

23
src/mapper/mapper.h Normal file
View File

@@ -0,0 +1,23 @@
#ifndef FALLOUT_MAPPER_MAPPER_H_
#define FALLOUT_MAPPER_MAPPER_H_
#include "map.h"
#include "obj_types.h"
namespace fallout {
extern MapTransition mapInfo;
extern int menu_val_0[8];
extern int menu_val_2[8];
extern int menu_val_1[21];
extern unsigned char* tool;
extern int tool_win;
int mapper_main(int argc, char** argv);
void print_toolbar_name(int object_type);
int mapper_inven_unwield(Object* obj, int right_hand);
} // namespace fallout
#endif /* FALLOUT_MAPPER_MAPPER_H_ */

607
src/mapper/mp_proto.cc Normal file
View File

@@ -0,0 +1,607 @@
#include "mapper/mp_proto.h"
#include <string.h>
#include "art.h"
#include "color.h"
#include "combat_ai.h"
#include "critter.h"
#include "input.h"
#include "kb.h"
#include "mapper/mp_targt.h"
#include "memory.h"
#include "proto.h"
#include "svga.h"
#include "window_manager.h"
#include "window_manager_private.h"
namespace fallout {
#define CRITTER_FLAG_COUNT 10
#define YES 0
#define NO 1
static int proto_choose_container_flags(Proto* proto);
static int proto_subdata_setup_int_button(const char* title, int key, int value, int min_value, int max_value, int* y, int a7);
static int proto_subdata_setup_fid_button(const char* title, int key, int fid, int* y, int a5);
static int proto_subdata_setup_pid_button(const char* title, int key, int pid, int* y, int a5);
static void proto_critter_flags_redraw(int win, int pid);
static int proto_critter_flags_modify(int pid);
static int mp_pick_kill_type();
static char kYes[] = "YES";
static char kNo[] = "NO";
// 0x53DAFC
static char default_proto_builder_name[36] = "EVERTS SCOTTY";
// 0x559924
char* proto_builder_name = default_proto_builder_name;
// 0x559B94
static const char* wall_light_strs[] = {
"North/South",
"East/West",
"North Corner",
"South Corner",
"East Corner",
"West Corner",
};
// 0x559C50
static char* yesno[] = {
kYes,
kNo,
};
// 0x559C58
int edit_window_color = 1;
// 0x559C60
bool can_modify_protos = false;
// 0x559C68
static int subwin = -1;
// 0x559C6C
static int critFlagList[CRITTER_FLAG_COUNT] = {
CRITTER_NO_STEAL,
CRITTER_NO_DROP,
CRITTER_NO_LIMBS,
CRITTER_NO_AGE,
CRITTER_NO_HEAL,
CRITTER_INVULNERABLE,
CRITTER_FLAT,
CRITTER_SPECIAL_DEATH,
CRITTER_LONG_LIMBS,
CRITTER_NO_KNOCKBACK,
};
// 0x559C94
static const char* critFlagStrs[CRITTER_FLAG_COUNT] = {
"_Steal",
"_Drop",
"_Limbs",
"_Ages",
"_Heal",
"Invuln.,",
"_Flattens",
"Special",
"Rng",
"_Knock",
};
// 0x4922F8
void init_mapper_protos()
{
edit_window_color = _colorTable[10570];
can_modify_protos = target_overriden();
}
// 0x492840
int proto_choose_container_flags(Proto* proto)
{
int win = windowCreate(320,
185,
220,
205,
edit_window_color,
WINDOW_MOVE_ON_TOP);
if (win == -1) {
return -1;
}
_win_register_text_button(win,
10,
11,
-1,
-1,
-1,
'1',
"Magic Hands Grnd",
0);
if ((proto->item.data.container.openFlags & 0x1) != 0) {
windowDrawText(win,
yesno[YES],
50,
125,
15,
_colorTable[32747] | 0x10000);
} else {
windowDrawText(win,
yesno[NO],
50,
125,
15,
_colorTable[32747] | 0x10000);
}
_win_register_text_button(win,
10,
32,
-1,
-1,
-1,
'2',
"Cannot Pick Up",
0);
if (_proto_action_can_pickup(proto->pid)) {
windowDrawText(win,
yesno[YES],
50,
125,
36,
_colorTable[32747] | 0x10000);
} else {
windowDrawText(win,
yesno[NO],
50,
125,
36,
_colorTable[32747] | 0x10000);
}
windowDrawBorder(win);
windowRefresh(win);
while (1) {
sharedFpsLimiter.mark();
int input = inputGetInput();
if (input == KEY_ESCAPE
|| input == KEY_BAR
|| input == KEY_RETURN) {
break;
}
if (input == '1') {
proto->item.data.container.openFlags ^= 0x1;
if ((proto->item.data.container.openFlags & 0x1) != 0) {
windowDrawText(win,
yesno[YES],
50,
125,
15,
_colorTable[32747] | 0x10000);
} else {
windowDrawText(win,
yesno[NO],
50,
125,
15,
_colorTable[32747] | 0x10000);
}
windowRefresh(win);
} else if (input == '2') {
proto->item.extendedFlags ^= 0x8000;
if (_proto_action_can_pickup(proto->pid)) {
windowDrawText(win,
yesno[YES],
50,
125,
36,
_colorTable[32747] | 0x10000);
} else {
windowDrawText(win,
yesno[NO],
50,
125,
36,
_colorTable[32747] | 0x10000);
}
windowRefresh(win);
}
renderPresent();
sharedFpsLimiter.throttle();
}
windowDestroy(win);
return 0;
}
// 0x492A3C
int proto_subdata_setup_int_button(const char* title, int key, int value, int min_value, int max_value, int* y, int a7)
{
char text[36];
int button_x;
int value_offset_x;
button_x = 10;
value_offset_x = 90;
if (a7 == 9) {
*y -= 189;
}
if (a7 > 8) {
button_x = 165;
value_offset_x -= 16;
}
_win_register_text_button(subwin,
button_x,
*y,
-1,
-1,
-1,
key,
title,
0);
if (value >= min_value && value < max_value) {
sprintf(text, "%d", value);
windowDrawText(subwin,
text,
38,
button_x + value_offset_x,
*y + 4,
_colorTable[32747] | 0x10000);
} else {
windowDrawText(subwin,
"<ERROR>",
38,
button_x + value_offset_x,
*y + 4,
_colorTable[31744] | 0x10000);
}
*y += 21;
return 0;
}
// 0x492B28
int proto_subdata_setup_fid_button(const char* title, int key, int fid, int* y, int a5)
{
char text[36];
char* pch;
int button_x;
int value_offset_x;
button_x = 10;
value_offset_x = 90;
if (a5 == 9) {
*y -= 189;
}
if (a5 > 8) {
button_x = 165;
value_offset_x -= 16;
}
_win_register_text_button(subwin,
button_x,
*y,
-1,
-1,
-1,
key,
title,
0);
if (art_list_str(fid, text) != -1) {
pch = strchr(text, '.');
if (pch != NULL) {
*pch = '\0';
}
windowDrawText(subwin,
text,
80,
button_x + value_offset_x,
*y + 4,
_colorTable[32747] | 0x10000);
} else {
windowDrawText(subwin,
"None",
80,
button_x + value_offset_x,
*y + 4,
_colorTable[992] | 0x10000);
}
*y += 21;
return 0;
}
// 0x492C20
int proto_subdata_setup_pid_button(const char* title, int key, int pid, int* y, int a5)
{
int button_x;
int value_offset_x;
button_x = 10;
value_offset_x = 90;
if (a5 == 9) {
*y -= 189;
}
if (a5 > 8) {
button_x = 165;
value_offset_x = 74;
}
_win_register_text_button(subwin,
button_x,
*y,
-1,
-1,
-1,
key,
title,
0);
if (pid != -1) {
windowDrawText(subwin,
protoGetName(pid),
49,
button_x + value_offset_x,
*y + 4,
_colorTable[32747] | 0x10000);
} else {
windowDrawText(subwin,
"None",
49,
button_x + value_offset_x,
*y + 4,
_colorTable[992] | 0x10000);
}
*y += 21;
return 0;
}
// 0x495438
const char* proto_wall_light_str(int flags)
{
if ((flags & 0x8000000) != 0) {
return wall_light_strs[1];
}
if ((flags & 0x10000000) != 0) {
return wall_light_strs[2];
}
if ((flags & 0x20000000) != 0) {
return wall_light_strs[3];
}
if ((flags & 0x40000000) != 0) {
return wall_light_strs[4];
}
if ((flags & 0x80000000) != 0) {
return wall_light_strs[5];
}
return wall_light_strs[0];
}
// 0x4960B8
void proto_critter_flags_redraw(int win, int pid)
{
int index;
int color;
int x = 110;
for (index = 0; index < CRITTER_FLAG_COUNT; index++) {
if (_critter_flag_check(pid, critFlagList[index])) {
color = _colorTable[992];
} else {
color = _colorTable[10570];
}
windowDrawText(win, critFlagStrs[index], 44, x, 195, color | 0x10000);
x += 48;
}
}
// 0x496120
int proto_critter_flags_modify(int pid)
{
Proto* proto;
int rc;
int flags = 0;
int index;
if (protoGetProto(pid, &proto) == -1) {
return -1;
}
rc = win_yes_no("Can't be stolen from?", 340, 200, _colorTable[15855]);
if (rc == -1) {
return -1;
}
if (rc == 1) {
flags |= CRITTER_NO_STEAL;
}
rc = win_yes_no("Can't Drop items?", 340, 200, _colorTable[15855]);
if (rc == -1) {
return -1;
}
if (rc == 1) {
flags |= CRITTER_NO_DROP;
}
rc = win_yes_no("Can't lose limbs?", 340, 200, _colorTable[15855]);
if (rc == -1) {
return -1;
}
if (rc == 1) {
flags |= CRITTER_NO_LIMBS;
}
rc = win_yes_no("Dead Bodies Can't Age?", 340, 200, _colorTable[15855]);
if (rc == -1) {
return -1;
}
if (rc == 1) {
flags |= CRITTER_NO_AGE;
}
rc = win_yes_no("Can't Heal by Aging?", 340, 200, _colorTable[15855]);
if (rc == -1) {
return -1;
}
if (rc == 1) {
flags |= CRITTER_NO_HEAL;
}
rc = win_yes_no("Is Invlunerable????", 340, 200, _colorTable[15855]);
if (rc == -1) {
return -1;
}
if (rc == 1) {
flags |= CRITTER_INVULNERABLE;
}
rc = win_yes_no("Can't Flatten on Death?", 340, 200, _colorTable[15855]);
if (rc == -1) {
return -1;
}
if (rc == 1) {
flags |= CRITTER_FLAT;
}
rc = win_yes_no("Has Special Death?", 340, 200, _colorTable[15855]);
if (rc == -1) {
return -1;
}
if (rc == 1) {
flags |= CRITTER_SPECIAL_DEATH;
}
rc = win_yes_no("Has Extra Hand-To-Hand Range?", 340, 200, _colorTable[15855]);
if (rc == -1) {
return -1;
}
if (rc == 1) {
flags |= CRITTER_LONG_LIMBS;
}
rc = win_yes_no("Can't be knocked back?", 340, 200, _colorTable[15855]);
if (rc == -1) {
return -1;
}
if (rc == 1) {
flags |= CRITTER_NO_KNOCKBACK;
}
if (!can_modify_protos) {
win_timed_msg("Can't modify protos!", _colorTable[31744] | 0x10000);
return -1;
}
for (index = 0; index < CRITTER_FLAG_COUNT; index++) {
if ((critFlagList[index] & flags) != 0) {
critter_flag_set(pid, critFlagList[index]);
} else {
critter_flag_unset(pid, critFlagList[index]);
}
}
return 0;
}
// 0x497520
int mp_pick_kill_type()
{
char* names[KILL_TYPE_COUNT];
int index;
for (index = 0; index < KILL_TYPE_COUNT; index++) {
names[index] = killTypeGetName(index);
}
return _win_list_select("Kill Type",
names,
KILL_TYPE_COUNT,
NULL,
50,
100,
_colorTable[15855]);
}
// 0x497568
int proto_pick_ai_packet(int* value)
{
int count;
char** names;
int index;
int rc;
count = combat_ai_num();
if (count <= 0) {
return -1;
}
names = (char**)internal_malloc(sizeof(char*) * count);
for (index = 0; index < count; index++) {
names[index] = (char*)internal_malloc(strlen(combat_ai_name(index)) + 1);
strcpy(names[index], combat_ai_name(index));
}
rc = _win_list_select("AI Packet",
names,
count,
NULL,
50,
100,
_colorTable[15855]);
if (rc != -1) {
*value = rc;
}
for (index = 0; index < count; index++) {
internal_free(names[index]);
}
internal_free(names);
return 0;
}
} // namespace fallout

15
src/mapper/mp_proto.h Normal file
View File

@@ -0,0 +1,15 @@
#ifndef FALLOUT_MAPPER_MP_PROTO_H_
#define FALLOUT_MAPPER_MP_PROTO_H_
namespace fallout {
extern char* proto_builder_name;
extern bool can_modify_protos;
void init_mapper_protos();
const char* proto_wall_light_str(int flags);
int proto_pick_ai_packet(int* value);
} // namespace fallout
#endif /* FALLOUT_MAPPER_MP_PROTO_H_ */

90
src/mapper/mp_scrpt.cc Normal file
View File

@@ -0,0 +1,90 @@
#include "mapper/mp_scrpt.h"
#include "art.h"
#include "object.h"
#include "scripts.h"
#include "tile.h"
namespace fallout {
// 0x49B170
int map_scr_remove_spatial(int tile, int elevation)
{
Script* scr;
Object* obj;
Rect rect;
scr = scriptGetFirstSpatialScript(elevation);
while (scr != NULL) {
if (builtTileGetTile(scr->sp.built_tile) == tile) {
scriptRemove(scr->sid);
scr = scriptGetFirstSpatialScript(elevation);
continue;
}
scr = scriptGetNextSpatialScript();
}
obj = objectFindFirstAtElevation(elevation);
while (obj != NULL) {
if (obj->tile == tile && buildFid(OBJ_TYPE_INTERFACE, 3, 0, 0, 0) == obj->fid) {
objectDestroy(obj, &rect);
tileWindowRefreshRect(&rect, elevation);
obj = objectFindFirstAtElevation(elevation);
continue;
}
obj = objectFindNextAtElevation();
}
return 0;
}
// 0x49B214
int map_scr_remove_all_spatials()
{
int elevation;
Script* scr;
Object* obj;
int sid;
for (elevation = 0; elevation < ELEVATION_COUNT; elevation++) {
scr = scriptGetFirstSpatialScript(elevation);
while (scr != NULL) {
scriptRemove(scr->sid);
scr = scriptGetFirstSpatialScript(elevation);
}
obj = objectFindFirstAtElevation(elevation);
while (obj != NULL) {
if (buildFid(OBJ_TYPE_INTERFACE, 3, 0, 0, 0) == obj->fid) {
objectDestroy(obj, NULL);
obj = objectFindFirstAtElevation(elevation);
continue;
}
obj = objectFindNextAtElevation();
}
}
tileWindowRefresh();
for (sid = 0; sid < 15000; sid++) {
if (scriptGetScript(sid, &scr) != -1) {
if (scr->owner != NULL) {
if (scr->owner->pid == 0x500000C) {
scr->owner->sid = -1;
scriptRemove(sid);
}
}
}
}
return 0;
}
} // namespace fallout

Some files were not shown because too many files have changed in this diff Show More