mirror of
https://github.com/fallout2-ce/fallout2-ce.git
synced 2026-07-27 16:47:11 -07:00
Compare commits
91
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d4bb81a919 | ||
|
|
7ea5265a01 | ||
|
|
649d255ca2 | ||
|
|
64af575bdf | ||
|
|
03d703b734 | ||
|
|
19dfece38e | ||
|
|
7c361af576 | ||
|
|
0dc93bab88 | ||
|
|
64bb2af1fd | ||
|
|
cf56c0ecef | ||
|
|
161d114306 | ||
|
|
4823bd328f | ||
|
|
62f4dae07e | ||
|
|
f05831648b | ||
|
|
692cef5c98 | ||
|
|
d68790a096 | ||
|
|
97cd20d21e | ||
|
|
f4bb72b9e8 | ||
|
|
f56a96ec9c | ||
|
|
2504c64735 | ||
|
|
8a14b2b3ed | ||
|
|
bdf5d253ba | ||
|
|
9d2462ef44 | ||
|
|
be9169b234 | ||
|
|
aa54707d60 | ||
|
|
61947f5fb9 | ||
|
|
cead52bbd1 | ||
|
|
f80a61d359 | ||
|
|
34b3232422 | ||
|
|
a323a1292c | ||
|
|
cf6b3e75f3 | ||
|
|
a1dafba37a | ||
|
|
f264827cd6 | ||
|
|
544eb92d8e | ||
|
|
1e9b81dd17 | ||
|
|
b5c420274f | ||
|
|
1a77361231 | ||
|
|
ed2db51afd | ||
|
|
53ff2293a1 | ||
|
|
c4e722612f | ||
|
|
8f3ccca71b | ||
|
|
386b6c26c7 | ||
|
|
51b0c3c8c0 | ||
|
|
00a05e5279 | ||
|
|
a65a426e27 | ||
|
|
a697f0b868 | ||
|
|
9e8eaa13f5 | ||
|
|
14839db4f9 | ||
|
|
e1f5f83ebd | ||
|
|
6e6f82414e | ||
|
|
6f0f68d5aa | ||
|
|
141c67575f | ||
|
|
a7a7f0b63c | ||
|
|
f1d436b144 | ||
|
|
5939e41da6 | ||
|
|
7079da6e90 | ||
|
|
1680e885f2 | ||
|
|
b31737d4f7 | ||
|
|
270f974926 | ||
|
|
92cc37560a | ||
|
|
3abdbcb53b | ||
|
|
b7cacdc6da | ||
|
|
a98d9d6c26 | ||
|
|
0a64cf4f6b | ||
|
|
b97c9864aa | ||
|
|
8d0009aa45 | ||
|
|
511d53a615 | ||
|
|
f17dd19116 | ||
|
|
c28c62727f | ||
|
|
b14f518714 | ||
|
|
6a0bed4433 | ||
|
|
ce27eb55a1 | ||
|
|
c240657d0d | ||
|
|
0a73abe67d | ||
|
|
54228248ef | ||
|
|
4eba423399 | ||
|
|
de98136699 | ||
|
|
b27b0f03fc | ||
|
|
9d6f86424e | ||
|
|
bb65d8d32a | ||
|
|
c9139f762d | ||
|
|
beb3c537a4 | ||
|
|
b71f1e7d18 | ||
|
|
b7f2b32b92 | ||
|
|
75776e4b5b | ||
|
|
5304823f8f | ||
|
|
5860ee2ffd | ||
|
|
550e6f035a | ||
|
|
26978dedc5 | ||
|
|
47434c4038 | ||
|
|
23e9eab72d |
@@ -17,15 +17,5 @@
|
||||
|
||||
- *Preview builds are not available for pull requests from forked repositories.* To enable preview builds, submit the PR from a branch within this repository.
|
||||
|
||||
- *Formatting issues? You have two options:*
|
||||
1. **Fix formatting automatically** using the following Docker command: *(If you're using Windows, remove `--user $(id -u):$(id -g)`)*
|
||||
```bash
|
||||
docker run --rm \
|
||||
-v $(pwd):/app --workdir /app \
|
||||
--user $(id -u):$(id -g) silkeh/clang:18 \
|
||||
bash -c 'find src -type f -name \*.cc -o -name \*.h | xargs clang-format -i'
|
||||
```
|
||||
2. **Skip formatting check** by adding the `skip-formatting` label to this PR.
|
||||
|
||||
--->
|
||||
|
||||
|
||||
@@ -98,10 +98,18 @@ target_sources(${EXECUTABLE_NAME} PUBLIC
|
||||
"src/file_find.h"
|
||||
"src/file_utils.cc"
|
||||
"src/file_utils.h"
|
||||
"src/fo1db/fo1_assoc.cc"
|
||||
"src/fo1db/fo1_assoc.h"
|
||||
"src/fo1db/fo1_db.cc"
|
||||
"src/fo1db/fo1_db.h"
|
||||
"src/fo1db/fo1_lzss.cc"
|
||||
"src/fo1db/fo1_lzss.h"
|
||||
"src/font_manager.cc"
|
||||
"src/font_manager.h"
|
||||
"src/game_config.cc"
|
||||
"src/game_config.h"
|
||||
"src/game_config_migration.cc"
|
||||
"src/game_config_migration.h"
|
||||
"src/game_dialog.cc"
|
||||
"src/game_dialog.h"
|
||||
"src/game_memory.cc"
|
||||
@@ -112,6 +120,8 @@ target_sources(${EXECUTABLE_NAME} PUBLIC
|
||||
"src/game_movie.h"
|
||||
"src/game_sound.cc"
|
||||
"src/game_sound.h"
|
||||
"src/game_variant.cc"
|
||||
"src/game_variant.h"
|
||||
"src/game_vars.h"
|
||||
"src/game.cc"
|
||||
"src/game.h"
|
||||
@@ -172,6 +182,8 @@ target_sources(${EXECUTABLE_NAME} PUBLIC
|
||||
"src/obj_types.h"
|
||||
"src/object.cc"
|
||||
"src/object.h"
|
||||
"src/opcode_context.cc"
|
||||
"src/opcode_context.h"
|
||||
"src/options.cc"
|
||||
"src/options.h"
|
||||
"src/palette.cc"
|
||||
@@ -286,8 +298,11 @@ target_sources(${EXECUTABLE_NAME} PUBLIC
|
||||
"src/sfall_metarules.h"
|
||||
"src/sfall_opcodes.cc"
|
||||
"src/sfall_opcodes.h"
|
||||
"src/sfall_script_hooks.cc"
|
||||
"src/sfall_arrays.cc"
|
||||
"src/sfall_arrays.h"
|
||||
"src/sfall_animation.cc"
|
||||
"src/sfall_animation.h"
|
||||
"src/sfall_callbacks.cc"
|
||||
"src/sfall_callbacks.h"
|
||||
"src/touch.cc"
|
||||
@@ -315,6 +330,10 @@ if(WIN32)
|
||||
)
|
||||
endif()
|
||||
|
||||
if(MSVC)
|
||||
target_compile_options(${EXECUTABLE_NAME} PRIVATE /EHsc)
|
||||
endif()
|
||||
|
||||
if(WIN32)
|
||||
target_link_libraries(${EXECUTABLE_NAME}
|
||||
winmm
|
||||
@@ -431,6 +450,7 @@ endif()
|
||||
|
||||
add_subdirectory("third_party/fpattern")
|
||||
target_link_libraries(${EXECUTABLE_NAME} fpattern::fpattern)
|
||||
target_link_libraries(${EXECUTABLE_NAME} fpattern_windows::fpattern_windows)
|
||||
|
||||
target_link_libraries(${EXECUTABLE_NAME} ${ZLIB_LIBRARIES})
|
||||
target_include_directories(${EXECUTABLE_NAME} PRIVATE ${ZLIB_INCLUDE_DIRS})
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
# Contributing
|
||||
|
||||
This file is currently a shell to be filled in over time. For now, it only captures project-specific maintenance notes that are easy to miss.
|
||||
|
||||
## Updating SDL
|
||||
|
||||
SDL is pinned for native builds in `third_party/sdl2/CMakeLists.txt`. Right now, Android also relies on checked-in Java bindings in `os/android/app/src/main/java/org/libsdl/app`, and those bindings must match the SDL version fetched by CMake.
|
||||
|
||||
When updating SDL:
|
||||
|
||||
1. Update the SDL tag in `third_party/sdl2/CMakeLists.txt`.
|
||||
2. Run an Android build once so Gradle/CMake fetch the new SDL source tree.
|
||||
3. Copy the Android Java bindings from the fetched SDL checkout into `os/android/app/src/main/java/org/libsdl/app`.
|
||||
Source path pattern:
|
||||
`os/android/app/.cxx/<Variant>/<Hash>/arm64-v8a/_deps/sdl2-src/android-project/app/src/main/java/org/libsdl/app`
|
||||
4. Rebuild Android and confirm the SDL sync guard passes.
|
||||
|
||||
The Android build contains a guard in `os/android/app/build.gradle` that fails if the checked-in Java bindings drift from the fetched native SDL source.
|
||||
|
||||
This is a hack, not a good long-term setup. The Java bindings are still duplicated in the repo instead of being sourced from the same SDL tree as the native build. That should be improved so Android does not depend on a manual copy/sync step.
|
||||
@@ -84,7 +84,7 @@ $ mv app /Applications/Fallout2
|
||||
|
||||
### Browser
|
||||
|
||||
> **NOTE**: WebAssebly build with emscripten
|
||||
> **NOTE**: WebAssembly build with emscripten
|
||||
```
|
||||
docker run --rm -v $(pwd):/src emscripten/emsdk:3.1.74 sh -c 'git config --global --add safe.directory "*" && mkdir -p build && cd build && emcmake cmake ../ -DCMAKE_TOOLCHAIN_FILE=../cmake/toolchain/Emscripten.cmake && emmake make'
|
||||
```
|
||||
@@ -96,59 +96,35 @@ The main configuration file is `fallout2.cfg`. There are several important setti
|
||||
|
||||
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, enable/disable fullscreen mode and configure IFACE settings (the control bar at the bottom of the game screen).
|
||||
Additional settings for screen resolution, UI customization, and map options are now integrated into the main `fallout2.cfg` file (previously part of `f2_res.ini` from Mash's HRP). When Fallout 2 CE starts, if it detects an existing `f2_res.ini` file, it automatically migrates these settings into `fallout2.cfg`. After migration, `fallout2.cfg` becomes the single source of truth for this configuration.
|
||||
|
||||
The following settings can be configured in `fallout2.cfg` under the `[screen]` and `[ui]` sections:
|
||||
|
||||
```ini
|
||||
[MAIN]
|
||||
SCR_WIDTH=1280
|
||||
SCR_HEIGHT=720
|
||||
WINDOWED=1 ; 0 = fullscreen
|
||||
SCALE_2X=1 ; 0 = original scale, 1 = 2x - requires increasing the minimum resolution from 640x480 to 1280x960.
|
||||
[screen]
|
||||
resolution_x=1600 ; actual game window size (screen resolution), in pixels
|
||||
resolution_y=1080
|
||||
windowed=1 ; 0 = fullscreen
|
||||
scale=2 ; 1 = original scale, 2 = 2x scale, etc. (e.g. at scale 2 and screen resolution 1920x1080, in-game resolution will be 960x540, thus every pixel is twice as wide and tall)
|
||||
|
||||
[IFACE]
|
||||
; if IFACE_BAR_MODE=0 - the bottom of the map view window sits at the top of the IFACE Bar.
|
||||
; if IFACE_BAR_MODE=1 - the bottom of the map view window extends to the base of the screen and is overlapped by the IFACE Bar.
|
||||
IFACE_BAR_MODE=0
|
||||
|
||||
;if IFACE_BAR_SIDE_ART=0 - Black, No Iface-bar side art used.
|
||||
;if IFACE_BAR_SIDE_ART=1 - Metal (grey) look Iface-bar side art used.
|
||||
;if IFACE_BAR_SIDE_ART=2 - Leather look Iface-bar side art used.
|
||||
;if IFACE_BAR_SIDE_ART=3-6 - Alternative Metal look Iface-bar side art used.
|
||||
;if IFACE_BAR_SIDE_ART=7 - Alternative Leather look Iface-bar side art used.
|
||||
;if IFACE_BAR_SIDE_ART=8 - Metal (brown) look Iface-bar side art used.
|
||||
IFACE_BAR_SIDE_ART=2
|
||||
|
||||
;if IFACE_BAR_SIDES_ORI=0 - Iface-bar side graphics extend from the Iface-Bar to the Screen edges.
|
||||
;if IFACE_BAR_SIDES_ORI=1 - Iface-bar side graphics extend from the Screen edges to the Iface-Bar.
|
||||
IFACE_BAR_SIDES_ORI=0
|
||||
|
||||
;This will increase the width of the interface bar expanding the area used to display text.
|
||||
;if IFACE_BAR_WIDTH=640 - Interface bar will remain at it's original width.
|
||||
;if IFACE_BAR_WIDTH=800 - Interface bar will use 800pix wide asset from f2_res.dat.
|
||||
;IFACE_BAR_WIDTH=640
|
||||
|
||||
[STATIC_SCREENS]
|
||||
;if SPLASH_SCRN_SIZE=0 - Splash screen shows at original size if it fits, otherwise scales down while preserving aspect ratio.
|
||||
;if SPLASH_SCRN_SIZE=1 - Splash screen scales to fit the screen while preserving aspect ratio.
|
||||
;if SPLASH_SCRN_SIZE=2 - Splash screen stretches to fill the entire screen.
|
||||
SPLASH_SCRN_SIZE=0
|
||||
|
||||
[MAPS]
|
||||
;if IGNORE_MAP_EDGES=0 - Hi-Res map scroll edges are enabled.
|
||||
;if IGNORE_MAP_EDGES=1 - Hi-Res map scroll edges are ignored.
|
||||
IGNORE_MAP_EDGES=0
|
||||
[ui]
|
||||
iface_bar_mode=0 ; 0 = interface bar below game window, 1 = interface bar overlaps game window
|
||||
iface_bar_width=800 ; Width of interface bar (640 = original, 800 = extended)
|
||||
iface_bar_side_art=2 ; Interface bar side art style (0=black, 1=metal grey, 2=leather, 3-8=alternative styles)
|
||||
iface_bar_sides_ori=0 ; Side graphics orientation (0=extend from bar to edges, 1=extend from edges to bar)
|
||||
splash_screen_size=1 ; Splash screen scaling (0=original size, 1=fit preserving aspect, 2=stretch to fill)
|
||||
ignore_map_edges=0 ; Hi-res map scroll edges (0=enabled, 1=ignored)
|
||||
```
|
||||
|
||||
Recommendations:
|
||||
**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. For a sample f2_res.ini configuration file, containing all currently working settings use this link: [f2_res.ini](https://raw.githubusercontent.com/fallout2-ce/fallout2-ce/refs/heads/mainmenu/files/f2_res.ini)
|
||||
In time this stuff will receive in-game interface, right now you have to do it manually. To see all currently working fallout2.cfg settings, just run the game once and quit. It will be automatically updated with defaults for every supported setting.
|
||||
*Note*: Use of the IFACE_BAR settings requires the `f2_res.dat` file, which contains graphical assets. Various versions are available, but one compatible with the above settings can be found here: [f2_res.dat](https://github.com/fallout2-ce/fallout2-ce/raw/refs/heads/main/files/f2_res.dat)
|
||||
|
||||
*Note*: use of the IFACE_BAR settings requires the f2_res.dat file, which contains graphical assets. Various versions are available, but one compatible with the above f2_res.ini be found here: [f2_res.dat](https://github.com/fallout2-ce/fallout2-ce/raw/refs/heads/mainmenu/files/f2_res.dat)
|
||||
|
||||
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.
|
||||
The second 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.
|
||||
|
||||
For a sample ddraw.ini configuration file, containing all currently working settings use this link: [ddraw.ini](https://raw.githubusercontent.com/fallout2-ce/fallout2-ce/refs/heads/main/files/ddraw.ini)
|
||||
|
||||
|
||||
@@ -0,0 +1,124 @@
|
||||
# Sfall Compatibility
|
||||
|
||||
This document tracks Fallout 2 CE compatibility with sfall. This is for modders who need to know which Sfall features work in CE.
|
||||
|
||||
For now, this covers opcodes/metarules, and hooks. In the future, it will include other ways of modifying the engine (like ini files), and other Sfall-specific behaviour.
|
||||
|
||||
## Settings (ddraw.ini → fallout2.cfg)
|
||||
|
||||
Some settings previously read from `ddraw.ini` have been moved into `fallout2.cfg`. The table below maps each setting to its new location. `HiResMode` had no effect in CE and has been removed.
|
||||
|
||||
| ddraw.ini section | ddraw.ini key | fallout2.cfg section | fallout2.cfg key |
|
||||
| --- | --- | --- | --- |
|
||||
| `Misc` | `SkipOpeningMovies` | `ui` | `skip_opening_movies` |
|
||||
| `Misc` | `DisplayKarmaChanges` | `ui` | `display_karma_changes` |
|
||||
| `Misc` | `DisplayBonusDamage` | `ui` | `display_bonus_damage` |
|
||||
| `Misc` | `NumbersInDialogue` | `ui` | `numbers_in_dialogue` |
|
||||
| `Misc` | `AutoQuickSave` | `ui` | `auto_quick_save` |
|
||||
| `Main` | `EnableHighResolutionStencil` | `ui` | `enable_high_resolution_stencil` |
|
||||
| `Misc` | `ConsoleOutputPath` | `debug` | `console_output_path` |
|
||||
| `Misc` | `GaplessMusic` | `sound` | `gapless_music` |
|
||||
| `Misc` | `ScreenshotsFormat` | `system` | `screenshots_format` |
|
||||
| `Misc` | `UseWalkDistance` | `qol` | `use_walk_distance` |
|
||||
| `Misc` | `AutoOpenDoors` | `qol` | `auto_open_doors` |
|
||||
|
||||
## Opcodes / Metarules
|
||||
|
||||
See [`https://sfall-team.github.io/sfall/`](https://sfall-team.github.io/sfall/) for documentation on specific functions.
|
||||
|
||||
| Group | Opcodes In Group | Compatibility | Notes |
|
||||
| --- | --- | --- | --- |
|
||||
| Direct memory access| read_byte,short,int,string<br>write_byte,short,int,string<br>call_offset_vX | đźš« | Not possible. Open an issue if you need functionality not covered by other opcodes. |
|
||||
| Stats | get/set_pc_base_stat<br>get/set_pc_extra_stat<br>get/set_critter_base_stat<br>get/set_critter_extra_stat | âś… | CE uses engine stat helpers here instead of sfall's direct proto-field behavior, so derived-stat update behavior can differ. |
|
||||
| Stats / Alter min/max | get/set_stat_min/max<br>set_pc_stat_min/max<br>set_npc_stat_min/max | not implemented | - |
|
||||
| Skills | get/set_critter_skill_points<br>get/set_available_skill_points<br>set_skill_max<br>set_critter_skill_mod<br>set_base_skill_mod<br>mod_skill_points_per_level | not implemented | - |
|
||||
| Graphics | graphics_funcs_available<br>force_graphics_refresh<br>get_screen_width<br>get_screen_height<br>set_palette | implemented: only get_screen_width, get_screen_height | - |
|
||||
| Shaders | load_shader<br>free_shader<br>activate_shader<br>deactivate_shader<br>set/get_shader_* | đźš« | likely will not implement direct compatibility
|
||||
| Perks and traits | set_perk_image<br>set_perk_*<br>set_pyromaniac_mod<br>apply_heaveho_fix<br>set_swiftlearner_mod<br>has/set_fake_perk<br>has/set_fake_trait<br>set_selectable_perk<br>set_perkbox_title<br>show/hide_real_perks<br>perk_add_mode<br>clear_selectable_perks<br>add/remove_trait<br>seq_perk_freq | not implemented | - |
|
||||
| Virtual file system | fs_create<br>fs_copy<br>fs_find<br>fs_read/write_*<br>fs_delete<br>fs_size<br>fs_pos<br>fs_seek<br>fs_resize | đźš« | Open an issue if you have a use case for these |
|
||||
| Combat / Knockback | set_weapon_knockback<br>set_target_knockback<br>set_attacker_knockback<br>remove_weapon_knockback<br>remove_target_knockback<br>remove_attacker_knockback | not implemented | - |
|
||||
| Maps and encounters | in_world_map<br>force_encounter<br>force_encounter_with_flags<br>set_map_time_multi<br>get/set_map_enter_position<br>exec_map_update_scripts<br>get/set_terrain_name<br>set_town_title<br>get/set_can_rest_on_map<br>set_rest_heal_time<br>set_rest_mode<br>set_worldmap_heal_time | implemented: in_world_map, force_encounter, force_encounter_with_flags, set_map_time_multi | - |
|
||||
| Maps and encounters / Worldmap | get_world_map_x/y_pos<br>set_world_map_pos | âś… | - |
|
||||
| Audio | eax_available<br>set_eax_environment<br>play_sfall_sound<br>stop_sfall_sound | not implemented | *eax* opcodes will not be implemented |
|
||||
| Combat / Weapons and ammo | get/set_weapon_ammo_pid<br>get/set_weapon_ammo_count | âś… | - |
|
||||
| Sfall / Version | sfall_ver_major<br>sfall_ver_minor<br>sfall_ver_build | âś… | CE currently reports `4.3.4` |
|
||||
| Utility / Math | log, exponent, round, sqrt, abs, sin, cos, tan, arctan, ceil, ^, floor2, div | âś… | - |
|
||||
| Keyboard and mouse | key_pressed<br>tap_key<br>get_mouse_x/y<br>get_mouse_buttons | âś… | - |
|
||||
| Lists | list_begin<br>list_next<br>list_end<br>list_as_array<br>party_member_list | âś… | - |
|
||||
| Explosions | set_attack_explosion_pattern<br>set_attack_explosion_art<br>set_attack_explosion_radius<br>set_attack_is_explosion_fire<br>set_explosion_radius<br>set_dynamite_damage<br>set_plastic_damage<br>get_explosion_damage<br>set_explosion_max_targets<br>item_make_explosive | âś… except item_make_explosive | - |
|
||||
| Animations | reg_anim_combat_check<br>reg_anim_destroy<br>reg_anim_animate_and_hide<br>reg_anim_light<br>reg_anim_change_fid<br>reg_anim_take_out<br>reg_anim_turn_towards<br>reg_anim_callback<br>reg_anim_animate_and_move | âś… except reg_anim_callback | - |
|
||||
| Art and appearance | art_exists<br>refresh_pc_art<br>art_cache_clear<br>set_hero_race<br>set_hero_style | implemented: art_exists, refresh_pc_art, art_cache_clear | - |
|
||||
| Tiles and paths | get_tile_fid<br>tile_under_cursor<br>tile_light<br>tile_get_objs<br>tile_refresh_display<br>obj_blocking_tile<br>tile_by_position<br>get_tile_ground_fid<br>get_tile_roof_fid<br>obj_blocking_line<br>path_find_to<br>objects_in_radius | âś… except objects_in_radius | - |
|
||||
| Utility | sprintf<br>typeof<br>atoi<br>atof | âś… | - |
|
||||
| Utility / Strings | string_split<br>substr<br>strlen<br>charcode<br>get_string_pointer<br>string_find<br>string_find_from<br>string_format<br>string_format_array<br>string_replace<br>string_to_case<br>string_compare | âś… | `get_string_pointer` is deprecated and intentionally omitted. |
|
||||
| Interface / Tags | show_iface_tag<br>hide_iface_tag<br>is_iface_tag_active<br>set_iface_tag_text<br>add_iface_tag | âś… except set_iface_tag_text, add_iface_tag | CE only handles built-in interface tags here; custom tag creation/text is not supported yet. |
|
||||
| Global variables | set_sfall_global<br>get_sfall_global_int<br>get_sfall_global_float | âś… except get_sfall_global_float | Current CE storage is int-backed; `set_sfall_global` stores integer values |
|
||||
| Hooks / Hook functions | init_hook<br>get_sfall_arg<br>get_sfall_args<br>get_sfall_arg_at<br>set_sfall_return<br>set_sfall_arg<br>register_hook<br>register_hook_proc<br>register_hook_proc_spec | âś… | See below for implemented hooks. `init_hook` is deprecated and will not be implemented. register_hook_proc and register_hook_proc_spec both add hooks to the *end* of the hook list, instead of beginning and end, respectively. |
|
||||
| Arrays / Array functions | create_array<br>temp_array<br>fix_array<br>get/set_array<br>resize_array<br>free_array<br>scan_array<br>len_array<br>save/load_array<br>array_key<br>arrayexpr | âś… except save_array, load_array | - |
|
||||
| Perks and traits / NPC perks | set_fake_perk_npc<br>set_fake_trait_npc<br>set_selectable_perk_npc<br>has_fake_perk_npc<br>has_fake_trait_npc | not implemented | - |
|
||||
| Global scripts / Global script functions | set_global_script_repeat<br>set_global_script_type<br>available_global_script_types | âś… except available_global_script_types | - |
|
||||
| Combat | attack_is_aimed<br>block_combat<br>force_aimed_shots<br>disable_aimed_shots<br>get_attack_type<br>get/set_bodypart_hit_modifier<br>combat_data<br>get/set/reset_critical_table<br>get_last_target<br>get_last_attacker<br>set_critter_burst_disable<br>get/set_critter_current_ap<br>set_spray_settings<br>get/set_combat_free_move | implemented: get_attack_type, get_bodypart_hit_modifier, combat_data, set_bodypart_hit_modifier, get_critter_current_ap, set_critter_current_ap, get_combat_free_move, set_combat_free_move | - |
|
||||
| Car | set_car_current_town<br>car_gas_amount<br>set_car_intface_art | implemented: all except set_car_intface_art | - |
|
||||
| Interface / Windows and images | art_frame_data<br>interface_art_draw<br>interface_print<br>draw_image<br>draw_image_scaled<br>get_window_under_mouse<br>create_win<br>get_window_attribute<br>message_box<br>set_window_flag<br>win_fill_color<br>interface_overlay<br>dialog_message<br>get_text_width<br>hide_window<br>show_window<br>create_message_window | implemented: only message_box, get_text_width, show_window, create_message_window | - |
|
||||
| Interface / Outline | outlined_object<br>get_outline<br>set_outline | âś… | - |
|
||||
| Interface / Main interface | intface_is_hidden<br>intface_redraw<br>intface_hide<br>intface_show<br>set_quest_failure_value | implemented: only intface_redraw | `intface_redraw` only supports the zero-argument form; the optional-argument path is explicitly unimplemented. |
|
||||
| Interface / Inventory | display_stats<br>inventory_redraw<br>critter_inven_obj2<br>get_current_inven_size<br>item_weight | implemented: critter_inven_obj2, item_weight | - |
|
||||
| Interface / Cursor | get/set_cursor_mode | âś… | - |
|
||||
| Locks | lock_is_jammed<br>unjam_lock<br>set_unjam_locks_time | not implemented | - |
|
||||
| INI settings | get_ini_setting<br>get_ini_string<br>get_ini_section<br>get_ini_sections<br>get_ini_config<br>get_ini_config_db<br>set_ini_setting | âś… except get_ini_config, get_ini_config_db | `modified_ini` is intentionally omitted as deprecated. |
|
||||
| Objects and scripts | set_self<br>set_dude_obj<br>real_dude_obj<br>remove_script<br>get/set_script<br>obj_is_carrying_obj<br>loot_obj<br>dialog_obj<br>obj_under_cursor<br>get/set_object_data<br>get/set_flags<br>set_unique_id<br>set_scr_name<br>obj_is_openable<br>get/set_proto_data<br>get_object_ai_data | implemented: set_self, get_script, obj_is_carrying_obj, loot_obj, dialog_obj, obj_under_cursor, get_object_data, get_flags, set_flags, obj_is_openable, get_proto_data, set_proto_data | - |
|
||||
| Other / Game management | set_movie_path<br>stop/resume_game<br>mark_movie_played<br>game_loaded<br>get_game_mode<br>get_uptime<br>signal_close_game | implemented: game_loaded, get_game_mode, get_uptime, signal_close_game | - |
|
||||
| Gameplay tweaks | set_pickpocket_max<br>set_hit_chance_max<br>set_xp_mod<br>set_critter_hit_chance_mod<br>set_base_hit_chance_mod<br>set_hp_per_level_mod<br>get_unspent_ap_bonus<br>gdialog_get_barter_mod<br>set_unspent_ap_bonus<br>get/set_unspent_ap_perk_bonus<br>set_inven_ap_cost<br>set_base_pickpocket_mod<br>set_critter_pickpocket_mod<br>get_inven_ap_cost<br>set_drugs_data<br>get_kill_counter<br>mod_kill_counter<br>set_pipboy_available | implemented: gdialog_get_barter_mod | - |
|
||||
| NPCs | inc_npc_level<br>get_npc_level<br>npc_engine_level_up | not implemented | - |
|
||||
| Other | get_year<br>set_dm/df_model<br>active_hand<br>toggle_active_hand<br>get/set_viewport_x/y<br>hero_select_win<br>get_light_level<br>message_str_game<br>sneak_success<br>create_spatial<br>unwield_slot<br>add_g_timer_event<br>add_extra_msg_file<br>get_metarule_table<br>metarule_exist<br>remove_timer_event<br>spatial_radius | implemented: get_year, active_hand, toggle_active_hand, get_light_level, message_str_game, add_extra_msg_file, metarule_exist | `input_funcs_available`, `nb_create_char` are deprecated in sfall and intentionally absent in CE. `add_extra_msg_file` does not support the explicit `fileNumber` form in CE. |
|
||||
|
||||
## Hooks
|
||||
|
||||
| Hook | ID | Compatibility | Notes |
|
||||
| --- | --- | --- | --- |
|
||||
| ToHit | `HOOK_TOHIT` | âś… | - |
|
||||
| AfterHitRoll | `HOOK_AFTERHITROLL` | đźš« | Et tu |
|
||||
| CalcAPCost | `HOOK_CALCAPCOST` | âś… | - |
|
||||
| DeathAnim1 | `HOOK_DEATHANIM1` | đźš« | Use DEATHANIM2 instead |
|
||||
| DeathAnim2 | `HOOK_DEATHANIM2` | âś… | - |
|
||||
| CombatDamage | `HOOK_COMBATDAMAGE` | âś… | - |
|
||||
| OnDeath | `HOOK_ONDEATH` | đźš« | - |
|
||||
| FindTarget | `HOOK_FINDTARGET` | đźš« | (maybe) |
|
||||
| UseObjOn | `HOOK_USEOBJON` | âś… | - |
|
||||
| UseObj | `HOOK_USEOBJ` | âś… | CE notes an sfall-matching inconsistency around return code `2` behavior between interface contexts. |
|
||||
| RemoveInvenObj | `HOOK_REMOVEINVENOBJ` | đźš« | - |
|
||||
| BarterPrice | `HOOK_BARTERPRICE` | âś… | - |
|
||||
| MoveCost | `HOOK_MOVECOST` | đźš« | - |
|
||||
| ItemDamage | `HOOK_ITEMDAMAGE` | đźš« | - |
|
||||
| AmmoCost | `HOOK_AMMOCOST` | đźš« | Et tu |
|
||||
| KeyPress | `HOOK_KEYPRESS` | âś… | Third hook arg is currently `0`; CE doesn't use VK codes. |
|
||||
| MouseClick | `HOOK_MOUSECLICK` | âś… | - |
|
||||
| UseSkill | `HOOK_USESKILL` | đźš« | - |
|
||||
| Steal | `HOOK_STEAL` | đźš« | Et tu |
|
||||
| WithinPerception | `HOOK_WITHINPERCEPTION` | âś… | - |
|
||||
| InventoryMove | `HOOK_INVENTORYMOVE` | âś… | - |
|
||||
| InvenWield | `HOOK_INVENWIELD` | đźš« | - |
|
||||
| AdjustFID | `HOOK_ADJUSTFID` | đźš« | - |
|
||||
| CombatTurn | `HOOK_COMBATTURN` | âś… | - |
|
||||
| StdProcedure | `HOOK_STDPROCEDURE` | đźš« | Et tu |
|
||||
| StdProcedureEnd | `HOOK_STDPROCEDURE_END` | đźš« | - |
|
||||
| CarTravel | `HOOK_CARTRAVEL` | đźš« | - |
|
||||
| SetGlobalVar | `HOOK_SETGLOBALVAR` | đźš« | - |
|
||||
| RestTimer | `HOOK_RESTTIMER` | đźš« | Et tu |
|
||||
| GameModeChange | `HOOK_GAMEMODECHANGE` | âś… | - |
|
||||
| UseAnimObj | `HOOK_USEANIMOBJ` | đźš« | Et tu; (maybe) |
|
||||
| ExplosiveTimer | `HOOK_EXPLOSIVETIMER` | đźš« | - |
|
||||
| DescriptionObj | `HOOK_DESCRIPTIONOBJ` | đźš« | Et tu |
|
||||
| UseSkillOn | `HOOK_USESKILLON` | đźš« | Et tu |
|
||||
| OnExplosion | `HOOK_ONEXPLOSION` | đźš« | (maybe) |
|
||||
| SubCombatDamage | `HOOK_SUBCOMBATDAMAGE` | đźš« | (maybe) |
|
||||
| SetLighting | `HOOK_SETLIGHTING` | đźš« | Et tu; (maybe) |
|
||||
| Sneak | `HOOK_SNEAK` | đźš« | - |
|
||||
| TargetObject | `HOOK_TARGETOBJECT` | đźš« | (maybe) |
|
||||
| Encounter | `HOOK_ENCOUNTER` | đźš« | Et tu |
|
||||
| AdjustPoison | `HOOK_ADJUSTPOISON` | đźš« | (maybe) |
|
||||
| AdjustRads | `HOOK_ADJUSTRADS` | đźš« | (maybe) |
|
||||
| RollCheck | `HOOK_ROLLCHECK` | đźš« | - |
|
||||
| BestWeapon | `HOOK_BESTWEAPON` | đźš« | - |
|
||||
| CanUseWeapon | `HOOK_CANUSEWEAPON` | đźš« | - |
|
||||
| BuildSfxWeapon | `HOOK_BUILDSFXWEAPON` | đźš« | - |
|
||||
@@ -3,10 +3,6 @@
|
||||
;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
|
||||
[Main]
|
||||
|
||||
;Set to one to hide areas outside map bounds when using higher than 640x480 resolution, and to zero to disable
|
||||
;EnableHighResolutionStencil=1
|
||||
|
||||
|
||||
;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
|
||||
[Misc]
|
||||
|
||||
@@ -72,13 +68,6 @@ TownMapHotkeysFix=1
|
||||
;Must be non-zero to use the edit/get/reset_critical script functions
|
||||
;OverrideCriticalTable=2
|
||||
|
||||
;Set to 1 to get notification of karma changes in the notification window
|
||||
DisplayKarmaChanges=0
|
||||
|
||||
;Set to 1 to skip the 3 opening movies
|
||||
;Set to 2 to also skip the splash screen
|
||||
SkipOpeningMovies=0
|
||||
|
||||
;Change the Skilldex cursor FRM numbers
|
||||
;Default is 293 for all skills
|
||||
Lockpick=293
|
||||
@@ -99,18 +88,9 @@ Repair=293
|
||||
;Syntax is 'city id:global id', with each city/global pair separated by a comma.
|
||||
;CityRepsList=0:5001,2:5003,3:5004,4:5005,5:5006,6:5007,7:5008,8:5009,10:5011,11:5012,60:1640
|
||||
|
||||
;Set this to a valid path to save a copy of the console contents
|
||||
;ConsoleOutputPath=console.txt
|
||||
|
||||
;Set to 1 to add additional pages of save slots !!! can be implemented !!!
|
||||
;ExtraSaveSlots=1
|
||||
|
||||
;To use more than one save slot for quick saving (F6 key) without picking a slot beforehand, set the next two lines
|
||||
;Quick save will cyclically overwrite saves from the first slot on the specified page to the last slot on the n-th page
|
||||
;AutoQuickSave sets how many pages you want to use for quick saving (valid range: 1..10)
|
||||
;Set to 0 to disable
|
||||
AutoQuickSave=0
|
||||
|
||||
;These lines allow you to control the karma FRMs displayed on the character screen
|
||||
;Number of KarmaPoints should be 1 less than number of KarmaFRMs
|
||||
;KarmaFRMs=47,48,49
|
||||
@@ -122,9 +102,6 @@ ScienceOnCritters=0
|
||||
;Set to 1 to fix the bug that caused bonus HtH damage to not be applied correctly.
|
||||
BonusHtHDamageFix=1
|
||||
|
||||
;Set to 1 to display additional points of damage from Bonus HtH/Ranged Damage perks in the inventory
|
||||
;DisplayBonusDamage=1
|
||||
|
||||
;Set to 1 to remove the limits that stop the game from rolling critical successes/failures in the first few days of game time
|
||||
RemoveCriticalTimelimits=0
|
||||
|
||||
@@ -170,9 +147,6 @@ RemoveCriticalTimelimits=0
|
||||
;You need to use the message_str_game script function to get messages from the files
|
||||
;ExtraGameMsgFileList=
|
||||
|
||||
;Set to 1 to display numbered dialogue options
|
||||
NumbersInDialogue=0
|
||||
|
||||
;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
|
||||
; Configuration ini files
|
||||
;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
|
||||
@@ -197,11 +171,6 @@ NumbersInDialogue=0
|
||||
;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
|
||||
[Scripts]
|
||||
|
||||
;Comma-separated list of masked paths to load global scripts from
|
||||
;Only use single backslash \ as the directory separator
|
||||
;Paths outside of scripts folder are supported
|
||||
;GlobalScriptPaths=scripts\gl_*.int,scripts\sfall\gl*.int
|
||||
|
||||
;Uncomment the option to specify an additional directory for ini files used by scripts
|
||||
;The game will search for ini files first relative to this directory and then relative to the root directory if not found
|
||||
;The path length is limited to 61 characters
|
||||
|
||||
@@ -0,0 +1,115 @@
|
||||
[debug]
|
||||
;Set this to a valid path to save a copy of the console contents
|
||||
console_output_path=
|
||||
mode=log
|
||||
output_map_data_info=1
|
||||
show_load_info=1
|
||||
show_script_messages=1
|
||||
show_tile_num=1
|
||||
window_height=192
|
||||
window_width=300
|
||||
|
||||
[mapper]
|
||||
default_f8_as_game=1
|
||||
fix_map_inventory=0
|
||||
fix_map_objects=0
|
||||
ignore_rebuild_errors=0
|
||||
librarian=0
|
||||
override_librarian=0
|
||||
rebuild_protos=0
|
||||
run_mapper_as_game=0
|
||||
save_text_maps=0
|
||||
show_pid_numbers=0
|
||||
sort_script_list=0
|
||||
use_art_not_protos=0
|
||||
|
||||
[preferences]
|
||||
brightness=1.000000
|
||||
combat_difficulty=1
|
||||
combat_looks=1
|
||||
combat_messages=1
|
||||
combat_speed=50
|
||||
combat_taunts=1
|
||||
game_difficulty=1
|
||||
item_highlight=1
|
||||
language_filter=0
|
||||
mouse_sensitivity=1.000000
|
||||
player_speedup=0
|
||||
running=1
|
||||
running_burning_guy=1
|
||||
subtitles=1
|
||||
target_highlight=1
|
||||
text_base_delay=6.000000
|
||||
text_line_delay=2.000000
|
||||
violence_level=3
|
||||
|
||||
[screen]
|
||||
resolution_x=640
|
||||
resolution_y=480
|
||||
scale=1
|
||||
windowed=1
|
||||
|
||||
[sound]
|
||||
cache_size=448
|
||||
debug=1
|
||||
debug_sfxc=1
|
||||
gapless_music=1
|
||||
initialize=1
|
||||
master_volume=22281
|
||||
music=1
|
||||
music_path1=data\sound\music\
|
||||
music_path2=sound\music\
|
||||
music_volume=22281
|
||||
sndfx_volume=22281
|
||||
sounds=1
|
||||
speech=1
|
||||
speech_volume=22281
|
||||
|
||||
[system]
|
||||
art_cache_size=8
|
||||
color_cycling=1
|
||||
critter_dat=critter.dat
|
||||
critter_patches=data
|
||||
cycle_speed_factor=1
|
||||
executable=game
|
||||
free_space=20480
|
||||
hashing=1
|
||||
interrupt_walk=1
|
||||
language=english
|
||||
master_dat=master.dat
|
||||
master_patches=data
|
||||
screenshots_format=png
|
||||
scroll_lock=0
|
||||
splash=5
|
||||
|
||||
[ui]
|
||||
;Speed up or slow down all UI animations such as screen fade, dialog window show/hide, AC numbers roll, etc.
|
||||
anim_speed=2.000000
|
||||
;To use more than one save slot for quick saving (F6 key) without picking a slot beforehand
|
||||
;Quick save will cyclically overwrite saves from the first slot on the specified page to the last slot on the n-th page
|
||||
;auto_quick_save sets how many pages you want to use for quick saving (valid range: 1..10)
|
||||
;Set to 0 to disable
|
||||
auto_quick_save=3
|
||||
;Set to 1 to display additional points of damage from Bonus HtH/Ranged Damage perks in the inventory
|
||||
display_bonus_damage=1
|
||||
;Set to 1 to get notification of karma changes in the notification window
|
||||
display_karma_changes=0
|
||||
;Set to one to hide areas outside map bounds when using higher than 640x480 resolution, and to zero to disable
|
||||
enable_high_resolution_stencil=1
|
||||
iface_bar_mode=0
|
||||
iface_bar_side_art=2
|
||||
iface_bar_sides_ori=0
|
||||
iface_bar_width=800
|
||||
ignore_map_edges=0
|
||||
;Set to 1 to display numbered dialogue options
|
||||
numbers_in_dialogue=0
|
||||
;Set to 1 to skip the 3 opening movies
|
||||
;Set to 2 to also skip the splash screen
|
||||
skip_opening_movies=0
|
||||
splash_screen_size=1
|
||||
|
||||
[qol]
|
||||
; Automatically open doors that are unlocked and has no script attached.
|
||||
auto_open_doors=0
|
||||
; Overrides distance at which walk animation is used when using an object.
|
||||
use_walk_distance=5
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,61 @@
|
||||
#
|
||||
# enddeath.txt
|
||||
#
|
||||
# format of each line is:
|
||||
#
|
||||
# gvar, value, worldAreaKnown, worldAreaNotKnown, minLevel, %, narrator file
|
||||
#
|
||||
# Where:
|
||||
#
|
||||
# gvar is the GVAR_* number for the variable controlling the slide.
|
||||
#
|
||||
# value is the value that the gvar must be >= to for this slide
|
||||
# to be shown
|
||||
#
|
||||
# worldAreaKnown is the # of a worldmap area that has to be known
|
||||
# in order to get this one as an option
|
||||
#
|
||||
# worldAreaNotKnown is the # of a worldmap area that has to be *not*
|
||||
# known in order to get this one as an option
|
||||
#
|
||||
# minLevel is the minimum player level in order to get this one as
|
||||
# an option
|
||||
#
|
||||
# % is the % chance of a given line to occur
|
||||
#
|
||||
# narrator file is the base filename (no path path or extension) used
|
||||
# for the narrator voice-over and subtitles. Maximum of 8 characters.
|
||||
#
|
||||
|
||||
|
||||
#####
|
||||
# Generic Deaths
|
||||
#####
|
||||
-1, 0, -1, -1, 0, 20, NAR_3
|
||||
-1, 0, -1, -1, 0, 20, NAR_4
|
||||
-1, 0, -1, -1, 0, 20, NAR_5
|
||||
-1, 0, -1, -1, 0, 20, NAR_6
|
||||
-1, 0, 8, -1, 0, 20, NAR_8
|
||||
|
||||
#####
|
||||
# Specific Deaths
|
||||
#####
|
||||
-1, 0, -1, 0, 200, 0, nar_dth3
|
||||
-1, 0, -1, 0, 200, 0, nar_dth4
|
||||
-1, 0, -1, 0, 200, 0, nar_dth5
|
||||
-1, 0, -1, 0, 200, 0, nar_dth6
|
||||
-1, 0, -1, 0, 200, 0, nar_dth7
|
||||
-1, 0, -1, 0, 200, 0, nar_dth8
|
||||
-1, 0, -1, 0, 200, 0, nar_dth9
|
||||
|
||||
# Special Radiation Death
|
||||
491, 999, 3, -1, 150, 0, NAR_7
|
||||
|
||||
#####
|
||||
# Joke Deaths
|
||||
#####
|
||||
-1, 0, -1, -1, 10, 1, nar_jdd1
|
||||
-1, 0, -1, -1, 10, 1, nar_jdd3
|
||||
-1, 0, -1, -1, 10, 1, nar_jdd4
|
||||
-1, 0, -1, -1, 10, 1, nar_jdd5
|
||||
-1, 0, -1, -1, 10, 1, nar_jdd6
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,104 @@
|
||||
|
||||
;
|
||||
; Party Member valid option data
|
||||
;
|
||||
|
||||
;
|
||||
; Warning: Adding a party member here means you must also add it to party.h!
|
||||
;
|
||||
|
||||
;
|
||||
; Note: Party Member level-up float messages are found in game\misc.msg!
|
||||
;
|
||||
|
||||
|
||||
[Party Member 0] ; Player -- Not actually used!
|
||||
party_member_pid=16777216
|
||||
area_attack_mode=always, sometimes, be_sure, be_careful, be_absolutely_sure
|
||||
attack_who=whomever_attacking_me, strongest, weakest, whomever, closest
|
||||
best_weapon=no_pref, melee, melee_over_ranged, ranged_over_melee, ranged, unarmed, unarmed_over_thrown, random
|
||||
chem_use=clean, stims_when_hurt_little, stims_when_hurt_lots, sometimes, anytime, always
|
||||
distance=stay_close, charge, snipe, on_your_own, stay
|
||||
run_away_mode=none, coward, finger_hurts, bleeding, not_feeling_good, tourniquet, never
|
||||
disposition=none, custom, coward, defensive, aggressive, berserk
|
||||
level_minimum=0
|
||||
level_up_every=0
|
||||
level_pids=-1
|
||||
|
||||
[Party Member 1] ; pMIan_PID
|
||||
party_member_pid=16777292
|
||||
area_attack_mode=always, sometimes, be_sure, be_careful, be_absolutely_sure
|
||||
attack_who=whomever_attacking_me, strongest, weakest, whomever, closest
|
||||
best_weapon=no_pref, melee, ranged_over_melee, ranged
|
||||
chem_use=clean, stims_when_hurt_little, stims_when_hurt_lots, sometimes, anytime
|
||||
distance=stay_close, charge, snipe, on_your_own, stay
|
||||
run_away_mode=none, not_feeling_good, tourniquet, never
|
||||
disposition=none, custom, defensive, aggressive, berserk
|
||||
level_minimum=3
|
||||
level_up_every=3
|
||||
level_pids=16777530,16777531,16777532,16777533
|
||||
|
||||
[Party Member 2] ; pMDog_PID
|
||||
party_member_pid=16777338
|
||||
area_attack_mode=
|
||||
attack_who=whomever_attacking_me, strongest, weakest, whomever, closest
|
||||
best_weapon=unarmed
|
||||
chem_use=clean
|
||||
distance=stay_close, charge, on_your_own, stay
|
||||
run_away_mode=none, not_feeling_good, tourniquet, never
|
||||
disposition=none, custom, aggressive, berserk
|
||||
level_minimum=4
|
||||
level_up_every=3
|
||||
level_pids=16777542,16777543,16777544,16777545
|
||||
|
||||
[Party Member 3] ; pMTycho_PID
|
||||
party_member_pid=16777426
|
||||
area_attack_mode=always, sometimes, be_sure, be_careful, be_absolutely_sure
|
||||
attack_who=whomever_attacking_me, strongest, weakest, whomever, closest
|
||||
best_weapon=no_pref, ranged_over_melee, ranged, unarmed
|
||||
chem_use=clean, stims_when_hurt_little, stims_when_hurt_lots, sometimes, anytime
|
||||
distance=stay_close, charge, snipe, on_your_own, stay
|
||||
run_away_mode=none, not_feeling_good, tourniquet, never
|
||||
disposition=none, custom, defensive, aggressive, berserk
|
||||
level_minimum=4
|
||||
level_up_every=3
|
||||
level_pids=16777534,16777535,16777536,16777537
|
||||
|
||||
[Party Member 4] ; pMKatja_PID
|
||||
party_member_pid=16777518
|
||||
area_attack_mode=sometimes, be_sure, be_careful, be_absolutely_sure
|
||||
attack_who=whomever_attacking_me, weakest, whomever, closest
|
||||
best_weapon=no_pref, melee, melee_over_ranged, ranged_over_melee, ranged, unarmed
|
||||
chem_use=stims_when_hurt_little, stims_when_hurt_lots
|
||||
distance=stay_close, charge, on_your_own, stay
|
||||
run_away_mode=none, coward, finger_hurts, bleeding, not_feeling_good
|
||||
disposition=none, custom, defensive, aggressive, coward
|
||||
level_minimum=4
|
||||
level_up_every=2
|
||||
level_pids=16777538,16777539,16777540,16777541
|
||||
|
||||
[Party Member 5] ; pMTandi_PID
|
||||
party_member_pid=16777279
|
||||
area_attack_mode=always, sometimes, be_sure, be_careful, be_absolutely_sure
|
||||
attack_who=whomever_attacking_me, strongest, weakest, whomever, closest
|
||||
best_weapon=no_pref, melee, melee_over_ranged, ranged_over_melee, ranged, unarmed
|
||||
chem_use=clean, stims_when_hurt_little, stims_when_hurt_lots, sometimes, anytime, always
|
||||
distance=stay_close, charge, snipe, on_your_own, stay
|
||||
run_away_mode=none, coward, finger_hurts, bleeding, not_feeling_good, tourniquet, never
|
||||
disposition=none, custom, coward, defensive, aggressive, berserk
|
||||
level_minimum=0
|
||||
level_up_every=0
|
||||
level_pids=-1
|
||||
|
||||
[Party Member 6] ; pMMrHandyC_PID
|
||||
party_member_pid=16777529
|
||||
area_attack_mode=always, sometimes, be_sure, be_careful, be_absolutely_sure
|
||||
attack_who=whomever_attacking_me, strongest, weakest, whomever, closest
|
||||
best_weapon=no_pref, melee, melee_over_ranged, ranged_over_melee, ranged, unarmed
|
||||
chem_use=clean
|
||||
distance=stay_close, charge, snipe, on_your_own, stay
|
||||
run_away_mode=none, coward, finger_hurts, bleeding, not_feeling_good, tourniquet, never
|
||||
disposition=none, custom, coward, defensive, aggressive, berserk
|
||||
level_minimum=0
|
||||
level_up_every=0
|
||||
level_pids=-1
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,402 @@
|
||||
;
|
||||
; Fallout team quotes
|
||||
;
|
||||
; The fonts used to display this file are the reverse of the
|
||||
; credits.txt file. In other words, the font used to display
|
||||
; titles in credits.txt (the lines with the '@') is the font
|
||||
; used to display these quotes. Putting an '@' at the start of
|
||||
; a line in this file will use the font used to display the
|
||||
; names in the credits.txt file (currently 104).
|
||||
;
|
||||
; Max line length with the current font (103) is about 63.
|
||||
; Anything longer than that won't be displayed, as it won't fit
|
||||
; on the screen.
|
||||
;
|
||||
; All lines are automatically centered on the display.
|
||||
;
|
||||
; See top of credits.txt for additional info.
|
||||
;
|
||||
@Quotes from the Fallout team:
|
||||
(Press ESC if you don't want to see some raw language)
|
||||
|
||||
|
||||
I asked for anatomically correct, but not naked!
|
||||
- Tim C.
|
||||
|
||||
I appreciate the fact that ?? is only speaking to us when spoken to.
|
||||
- Leonard
|
||||
|
||||
So now that you are past the learning curve,
|
||||
you can blow up people much faster, right?
|
||||
- Tim C.
|
||||
|
||||
So how fast can _you_ draw a bunny?
|
||||
- JT
|
||||
|
||||
I didn't do it yet today because I was waiting for Leonard's head.
|
||||
- Scott C.
|
||||
|
||||
|
||||
|
||||
Did you see Steven Spielberg go by?
|
||||
- Tim C.
|
||||
No, I was taking a piss.
|
||||
- Mark Harrison
|
||||
|
||||
|
||||
|
||||
Blueberry muffins are one of Man's crowning achievements.
|
||||
- JT
|
||||
|
||||
Out of my way. I'm a fucking genius.
|
||||
- Jason
|
||||
|
||||
Dismemberment is just inherently funny.
|
||||
- JT
|
||||
|
||||
I had a wooden one, but Spence broke it.
|
||||
- Jesse
|
||||
|
||||
You can say penis, but you can't say cocksucker.
|
||||
- Leonard
|
||||
|
||||
It's fun to make fun of people who are stupid.
|
||||
- JT
|
||||
|
||||
Crap is the hardest stuff to make.
|
||||
- Michael
|
||||
|
||||
No, I haven't shot anyone today.
|
||||
- JT
|
||||
|
||||
|
||||
|
||||
But 15 _is_ an even number!
|
||||
- Leonard
|
||||
But 15 isn't divisible by 2.
|
||||
- Tim.
|
||||
You know what I mean. I meant 15 is prime.
|
||||
- Leonard
|
||||
|
||||
|
||||
|
||||
I'll be going on to death at the end of the day.
|
||||
- Michael
|
||||
|
||||
I'm tired of looking at that peanut.
|
||||
- Tim C.
|
||||
|
||||
I only wash my nose. It's the only thing that gets dirty.
|
||||
- Fred
|
||||
|
||||
I'm going to jiujitsu his ass.
|
||||
- Leonard
|
||||
|
||||
I'll have to remember or else I'll forget.
|
||||
- Jesse
|
||||
|
||||
You never know what wacky things I'm going to do with my hand.
|
||||
- Tim C.
|
||||
|
||||
Sorry I'm late, but Mary needed marbles and I had lost mine.
|
||||
- Chris T.
|
||||
|
||||
It's fun hitting other people's balls.
|
||||
- Tim C.
|
||||
|
||||
I'm going to kill this game.
|
||||
- Mark Morgan
|
||||
|
||||
Do you want help putting on your bikini?
|
||||
- Fred to Tim C.
|
||||
|
||||
I like to get them in the butt.
|
||||
- Tim C.
|
||||
|
||||
I need more peasants!
|
||||
- Fred
|
||||
|
||||
If I hadn't had sex, I would have called Tom or Jesse.
|
||||
- Scotty
|
||||
|
||||
Did you know you can talk to people who don't have heads?
|
||||
- Jesse
|
||||
|
||||
We'll have a little bowl hair-cut kid so you
|
||||
can't tell if it's a boy or a girl when you're killing it.
|
||||
- Leonard
|
||||
|
||||
It's just a flag!
|
||||
- Scotty
|
||||
|
||||
I'll tell them to give me more exploding peasants.
|
||||
- Fred
|
||||
|
||||
Do you need help changing his pants?
|
||||
- Leonard
|
||||
|
||||
I was getting home and getting ready to get some,
|
||||
and I remembered it was a holiday.
|
||||
- Scotty
|
||||
|
||||
I'd rather drink a bottle of urine than THAT!
|
||||
- Scotty
|
||||
|
||||
Rusty wants any body he can have.
|
||||
- Gus
|
||||
|
||||
Nick's are worn and falling apart and orange.
|
||||
- Jesse
|
||||
|
||||
I never let work interfere with my cooking.
|
||||
- Tim C.
|
||||
|
||||
I don't want you to stop making them,
|
||||
because it's the only time I get any.
|
||||
- Scotty
|
||||
|
||||
I vote for Hate.
|
||||
- Jason
|
||||
|
||||
That reminds me of Toxic Avenger, the unrated version.
|
||||
- Scotty
|
||||
|
||||
You know, we should lock down sex.
|
||||
- Chris T.
|
||||
|
||||
How do I kill people? I need some dead bodies.
|
||||
- Robert H.
|
||||
|
||||
Don't quote me on that.
|
||||
- Leonard
|
||||
|
||||
|
||||
|
||||
I had a weird dream involving Scotty,
|
||||
and I don't even want to remember it.
|
||||
- Jesse
|
||||
What?!
|
||||
- Scotty
|
||||
|
||||
|
||||
|
||||
I don't know what we're going to do about it.
|
||||
I guess we're going to have to start cutting heads.
|
||||
- Tim C.
|
||||
|
||||
Well, that's true and that's untrue.
|
||||
- Gus
|
||||
|
||||
But I like being a woman!
|
||||
- Scotty
|
||||
|
||||
I'm used to playing with myself.
|
||||
- Scotty
|
||||
|
||||
That's the essence of art -- making it all work together.
|
||||
- Leonard
|
||||
|
||||
Did I tell you I broke my thingy?
|
||||
- Dave
|
||||
|
||||
I want more randomness in my randomology.
|
||||
- Robert H.
|
||||
|
||||
I can't finish the AI without drugs.
|
||||
- Tim C.
|
||||
|
||||
Please do not make fun of my poop.
|
||||
- Tim C.
|
||||
|
||||
I know how to tell males from females now.
|
||||
- Tim C.
|
||||
|
||||
Excuse me, my butt did that.
|
||||
- Jesse
|
||||
|
||||
|
||||
|
||||
I'm going to kick you in the butt.
|
||||
- Robert H. to Tim C.
|
||||
Because it's soft as a baby's behind.
|
||||
- Jesse.
|
||||
How do you know?
|
||||
- Scotty
|
||||
|
||||
|
||||
|
||||
I can do Troy. I used to be his monkey.
|
||||
- Chris T.
|
||||
|
||||
I had one once, but I pumped it too hard and I broke it.
|
||||
- Scotty
|
||||
|
||||
I stripped and wiped.
|
||||
- Scotty
|
||||
|
||||
Why can't I be a lesbian?
|
||||
- Shanna
|
||||
|
||||
I wonder what that thing hanging there is.
|
||||
- Shanna
|
||||
|
||||
I need more intelligence.
|
||||
- Nick
|
||||
|
||||
At the same time, I want to make sure that
|
||||
I don't have dead people stand up.
|
||||
- Tim C.
|
||||
|
||||
I'd model dust, if I could.
|
||||
- Jason
|
||||
|
||||
I'm on top now.
|
||||
- Evan
|
||||
|
||||
I do a good cow.
|
||||
- Greg B.
|
||||
|
||||
If he's on top of me, I'm gonna be pissed!
|
||||
- Shanna
|
||||
|
||||
If I was a girl, I'd do him.
|
||||
- Evan
|
||||
|
||||
You won't be here when I get off.
|
||||
- Mike Krueger
|
||||
|
||||
Well, I was playing with it last night but I
|
||||
couldn't get anything to come out!
|
||||
- Mike Krueger
|
||||
|
||||
Stop shaking my monkey!
|
||||
- Matt Murakami
|
||||
|
||||
I like people who say poop.
|
||||
- Savina
|
||||
|
||||
It's not unstable, it's just buggy.
|
||||
There's a difference.
|
||||
- Chris J.
|
||||
|
||||
Instead of sexual urges, they get
|
||||
sucking blood urges.
|
||||
- Scotty
|
||||
|
||||
I like little boys who wear skirts.
|
||||
- Mike Krueger
|
||||
|
||||
His iguana-stick is way too long.
|
||||
- Leonard
|
||||
|
||||
Fallout is "By Americans, For Americans" and
|
||||
the rest of the world can just get stuffed.
|
||||
- Scotty
|
||||
|
||||
All the Brotherhood do it. They know how.
|
||||
- Nick
|
||||
|
||||
I'm going to teach you to script,
|
||||
that'll be torture.
|
||||
- Nick
|
||||
|
||||
His little thing looks better anyway.
|
||||
- Evan
|
||||
|
||||
He TOLD me to touch it!
|
||||
- Nick
|
||||
|
||||
I'm really scared of the people on the Internet.
|
||||
They're all dumb. Except for that one guy.
|
||||
- Scotty
|
||||
|
||||
|
||||
|
||||
I haven't touched it for two months.
|
||||
- Nick
|
||||
Well, you better start touching it.
|
||||
- Evan
|
||||
|
||||
|
||||
|
||||
You can never be paranoid enough.
|
||||
- Scotty
|
||||
|
||||
You should be 14-18 when you blow the Master.
|
||||
- Jess
|
||||
|
||||
Oh, wait a minute, talk to Jesse.
|
||||
Jesse usually has lots of drugs.
|
||||
- Scotty
|
||||
|
||||
I burnt my part, for one thing.
|
||||
- Mark H.
|
||||
|
||||
I'm usually a lot happier about the
|
||||
game when I'm not playing it.
|
||||
- Scotty
|
||||
|
||||
You gotta take it easy, this is my first time.
|
||||
- Dave Hendee
|
||||
|
||||
It's really quick to get it up.
|
||||
- Mark H.
|
||||
|
||||
I can find the hole without looking now.
|
||||
- Ed H.
|
||||
|
||||
I've actually had it both ways, but I'm not sure why...
|
||||
- Dan S.
|
||||
|
||||
I can touch it everywhere and it seems to work.
|
||||
- Scotty
|
||||
|
||||
OK, I was sleeping with Ian...
|
||||
- Gus
|
||||
|
||||
What is the sound of one man working on another?
|
||||
- Dan S.
|
||||
|
||||
I hate being fucked.
|
||||
- Gus
|
||||
|
||||
I think our game has a high potential
|
||||
for being very violent.
|
||||
- Jason A.
|
||||
|
||||
I'm not going to be beaten by cheesecake.
|
||||
- Tim C.
|
||||
|
||||
I have new respect for crowbars.
|
||||
(pause)
|
||||
Well, at least it isn't about sex.
|
||||
- Scotty
|
||||
|
||||
That thing is a little too
|
||||
big to stick right there.
|
||||
- Matt G.
|
||||
|
||||
|
||||
|
||||
I'm not going to do the cows.
|
||||
- Dan S.
|
||||
The cows are glad to hear that.
|
||||
- Robert H.
|
||||
|
||||
|
||||
|
||||
But I love faggot pizza.
|
||||
- Scotty
|
||||
|
||||
It won't crash any more. In theory.
|
||||
- Mark H.
|
||||
|
||||
I wasn't wearing anything
|
||||
the first time I won the game.
|
||||
- Tim C.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@FIN
|
||||
+100
-3
@@ -2,12 +2,97 @@ plugins {
|
||||
id 'com.android.application'
|
||||
}
|
||||
|
||||
def sdlJavaBindingsDir = file('src/main/java/org/libsdl/app')
|
||||
|
||||
def findFetchedSdlJavaBindingsDir = { String variantName ->
|
||||
String variantCap = variantName.capitalize()
|
||||
File intermediatesVariantDir = file("build/intermediates/cxx/${variantCap}")
|
||||
if (!intermediatesVariantDir.isDirectory()) {
|
||||
throw new GradleException("SDL sync check failed: missing active CXX intermediates under ${intermediatesVariantDir}. Run externalNativeBuild${variantCap} first.")
|
||||
}
|
||||
|
||||
File[] activeHashDirs = intermediatesVariantDir.listFiles()
|
||||
if (activeHashDirs == null) {
|
||||
throw new GradleException("SDL sync check failed: could not list active CXX intermediates under ${intermediatesVariantDir}.")
|
||||
}
|
||||
|
||||
activeHashDirs = activeHashDirs.findAll { it.isDirectory() }.sort { a, b -> a.name <=> b.name }
|
||||
if (activeHashDirs.size() != 1) {
|
||||
throw new GradleException(
|
||||
"SDL sync check failed: expected exactly one active CXX hash directory under ${intermediatesVariantDir}, found ${activeHashDirs*.name}."
|
||||
)
|
||||
}
|
||||
|
||||
File fetchedDir = file(".cxx/${variantCap}/${activeHashDirs[0].name}/arm64-v8a/_deps/sdl2-src/android-project/app/src/main/java/org/libsdl/app")
|
||||
|
||||
if (!fetchedDir.isDirectory()) {
|
||||
throw new GradleException("SDL sync check failed: could not locate fetched SDL Java bindings under ${fetchedDir}.")
|
||||
}
|
||||
|
||||
return fetchedDir
|
||||
}
|
||||
|
||||
def assertSdlJavaBindingsMatch = { String variantName ->
|
||||
File fetchedDir = findFetchedSdlJavaBindingsDir(variantName)
|
||||
|
||||
if (!sdlJavaBindingsDir.isDirectory()) {
|
||||
throw new GradleException("SDL sync check failed: committed SDL Java bindings directory is missing or unreadable: ${sdlJavaBindingsDir}.")
|
||||
}
|
||||
|
||||
File[] committedFiles = sdlJavaBindingsDir.listFiles()
|
||||
if (committedFiles == null) {
|
||||
throw new GradleException("SDL sync check failed: could not list committed SDL Java bindings directory: ${sdlJavaBindingsDir}.")
|
||||
}
|
||||
|
||||
File[] fetchedFiles = fetchedDir.listFiles()
|
||||
if (fetchedFiles == null) {
|
||||
throw new GradleException("SDL sync check failed: could not list fetched SDL Java bindings directory: ${fetchedDir}.")
|
||||
}
|
||||
|
||||
Set<String> committedNames = committedFiles
|
||||
.findAll { it.isFile() && it.name.endsWith('.java') }
|
||||
.collect { it.name }
|
||||
.toSet()
|
||||
Set<String> fetchedNames = fetchedFiles
|
||||
.findAll { it.isFile() && it.name.endsWith('.java') }
|
||||
.collect { it.name }
|
||||
.toSet()
|
||||
|
||||
Set<String> missingFromCommitted = fetchedNames - committedNames
|
||||
Set<String> extraInCommitted = committedNames - fetchedNames
|
||||
|
||||
if (!missingFromCommitted.isEmpty() || !extraInCommitted.isEmpty()) {
|
||||
throw new GradleException(
|
||||
"SDL Android Java bindings are out of sync with native SDL for ${variantName}.\n" +
|
||||
"Fetched SDL dir: ${fetchedDir}\n" +
|
||||
"Missing from committed bindings: ${missingFromCommitted.sort()}\n" +
|
||||
"Extra committed bindings: ${extraInCommitted.sort()}\n" +
|
||||
"Sync os/android/app/src/main/java/org/libsdl/app from the fetched SDL android-project sources."
|
||||
)
|
||||
}
|
||||
|
||||
List<String> changedFiles = committedNames.findAll { fileName ->
|
||||
File committedFile = new File(sdlJavaBindingsDir, fileName)
|
||||
File fetchedFile = new File(fetchedDir, fileName)
|
||||
committedFile.getText('UTF-8') != fetchedFile.getText('UTF-8')
|
||||
}.sort()
|
||||
|
||||
if (!changedFiles.isEmpty()) {
|
||||
throw new GradleException(
|
||||
"SDL Android Java bindings are out of sync with native SDL for ${variantName}.\n" +
|
||||
"Fetched SDL dir: ${fetchedDir}\n" +
|
||||
"Changed files: ${changedFiles}\n" +
|
||||
"Sync os/android/app/src/main/java/org/libsdl/app from the fetched SDL android-project sources."
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
android {
|
||||
compileSdk 32
|
||||
|
||||
defaultConfig {
|
||||
applicationId 'com.alexbatalov.fallout2ce'
|
||||
minSdk 21
|
||||
minSdk 24
|
||||
targetSdk 32
|
||||
versionCode 4
|
||||
versionName '1.3.0'
|
||||
@@ -78,8 +163,20 @@ android {
|
||||
}
|
||||
|
||||
applicationVariants.all { variant ->
|
||||
tasks["merge${variant.name.capitalize()}Assets"]
|
||||
.dependsOn("externalNativeBuild${variant.name.capitalize()}")
|
||||
String variantCap = variant.name.capitalize()
|
||||
String syncCheckTaskName = "checkSdlJavaBindingsSync${variantCap}"
|
||||
|
||||
if (!project.hasProperty('EXCLUDE_NATIVE_LIBS')) {
|
||||
tasks.register(syncCheckTaskName) {
|
||||
dependsOn("externalNativeBuild${variantCap}")
|
||||
doLast {
|
||||
assertSdlJavaBindingsMatch(variant.name)
|
||||
}
|
||||
}
|
||||
|
||||
tasks["merge${variantCap}Assets"]
|
||||
.dependsOn(syncCheckTaskName)
|
||||
}
|
||||
}
|
||||
|
||||
if (!project.hasProperty('EXCLUDE_NATIVE_LIBS')) {
|
||||
|
||||
@@ -186,7 +186,7 @@ class HIDDeviceBLESteamController extends BluetoothGattCallback implements HIDDe
|
||||
// Because on Chromebooks we show up as a dual-mode device, it will attempt to connect TRANSPORT_AUTO, which will use TRANSPORT_BREDR instead
|
||||
// of TRANSPORT_LE. Let's force ourselves to connect low energy.
|
||||
private BluetoothGatt connectGatt(boolean managed) {
|
||||
if (Build.VERSION.SDK_INT >= 23) {
|
||||
if (Build.VERSION.SDK_INT >= 23 /* Android 6.0 (M) */) {
|
||||
try {
|
||||
return mDevice.connectGatt(mManager.getContext(), managed, this, TRANSPORT_LE);
|
||||
} catch (Exception e) {
|
||||
@@ -429,7 +429,7 @@ class HIDDeviceBLESteamController extends BluetoothGattCallback implements HIDDe
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (newState == 0) {
|
||||
mIsConnected = false;
|
||||
}
|
||||
|
||||
@@ -170,7 +170,7 @@ public class HIDDeviceManager {
|
||||
Log.i(TAG," Interface protocol: " + mUsbInterface.getInterfaceProtocol());
|
||||
Log.i(TAG," Endpoint count: " + mUsbInterface.getEndpointCount());
|
||||
|
||||
// Get endpoint details
|
||||
// Get endpoint details
|
||||
for (int epi = 0; epi < mUsbInterface.getEndpointCount(); epi++)
|
||||
{
|
||||
UsbEndpoint mEndpoint = mUsbInterface.getEndpoint(epi);
|
||||
@@ -251,6 +251,8 @@ public class HIDDeviceManager {
|
||||
0x20d6, // PowerA
|
||||
0x24c6, // PowerA
|
||||
0x2c22, // Qanba
|
||||
0x2dc8, // 8BitDo
|
||||
0x9886, // ASTRO Gaming
|
||||
};
|
||||
|
||||
if (usbInterface.getInterfaceClass() == UsbConstants.USB_CLASS_VENDOR_SPEC &&
|
||||
@@ -271,15 +273,20 @@ public class HIDDeviceManager {
|
||||
final int XB1_IFACE_SUBCLASS = 71;
|
||||
final int XB1_IFACE_PROTOCOL = 208;
|
||||
final int[] SUPPORTED_VENDORS = {
|
||||
0x03f0, // HP
|
||||
0x044f, // Thrustmaster
|
||||
0x045e, // Microsoft
|
||||
0x0738, // Mad Catz
|
||||
0x0b05, // ASUS
|
||||
0x0e6f, // PDP
|
||||
0x0f0d, // Hori
|
||||
0x10f5, // Turtle Beach
|
||||
0x1532, // Razer Wildcat
|
||||
0x20d6, // PowerA
|
||||
0x24c6, // PowerA
|
||||
0x2dc8, /* 8BitDo */
|
||||
0x2dc8, // 8BitDo
|
||||
0x2e24, // Hyperkin
|
||||
0x3537, // GameSir
|
||||
};
|
||||
|
||||
if (usbInterface.getId() == 0 &&
|
||||
@@ -353,13 +360,19 @@ public class HIDDeviceManager {
|
||||
private void initializeBluetooth() {
|
||||
Log.d(TAG, "Initializing Bluetooth");
|
||||
|
||||
if (Build.VERSION.SDK_INT <= 30 &&
|
||||
if (Build.VERSION.SDK_INT >= 31 /* Android 12 */ &&
|
||||
mContext.getPackageManager().checkPermission(android.Manifest.permission.BLUETOOTH_CONNECT, mContext.getPackageName()) != PackageManager.PERMISSION_GRANTED) {
|
||||
Log.d(TAG, "Couldn't initialize Bluetooth, missing android.permission.BLUETOOTH_CONNECT");
|
||||
return;
|
||||
}
|
||||
|
||||
if (Build.VERSION.SDK_INT <= 30 /* Android 11.0 (R) */ &&
|
||||
mContext.getPackageManager().checkPermission(android.Manifest.permission.BLUETOOTH, mContext.getPackageName()) != PackageManager.PERMISSION_GRANTED) {
|
||||
Log.d(TAG, "Couldn't initialize Bluetooth, missing android.permission.BLUETOOTH");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE) || (Build.VERSION.SDK_INT < 18)) {
|
||||
if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE) || (Build.VERSION.SDK_INT < 18 /* Android 4.3 (JELLY_BEAN_MR2) */)) {
|
||||
Log.d(TAG, "Couldn't initialize Bluetooth, this version of Android does not support Bluetooth LE");
|
||||
return;
|
||||
}
|
||||
@@ -524,7 +537,7 @@ public class HIDDeviceManager {
|
||||
for (HIDDevice device : mDevicesById.values()) {
|
||||
device.setFrozen(frozen);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -573,12 +586,18 @@ public class HIDDeviceManager {
|
||||
try {
|
||||
final int FLAG_MUTABLE = 0x02000000; // PendingIntent.FLAG_MUTABLE, but don't require SDK 31
|
||||
int flags;
|
||||
if (Build.VERSION.SDK_INT >= 31) {
|
||||
if (Build.VERSION.SDK_INT >= 31 /* Android 12.0 (S) */) {
|
||||
flags = FLAG_MUTABLE;
|
||||
} else {
|
||||
flags = 0;
|
||||
}
|
||||
mUsbManager.requestPermission(usbDevice, PendingIntent.getBroadcast(mContext, 0, new Intent(HIDDeviceManager.ACTION_USB_PERMISSION), flags));
|
||||
if (Build.VERSION.SDK_INT >= 33 /* Android 14.0 (U) */) {
|
||||
Intent intent = new Intent(HIDDeviceManager.ACTION_USB_PERMISSION);
|
||||
intent.setPackage(mContext.getPackageName());
|
||||
mUsbManager.requestPermission(usbDevice, PendingIntent.getBroadcast(mContext, 0, intent, flags));
|
||||
} else {
|
||||
mUsbManager.requestPermission(usbDevice, PendingIntent.getBroadcast(mContext, 0, new Intent(HIDDeviceManager.ACTION_USB_PERMISSION), flags));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.v(TAG, "Couldn't request permission for USB device " + usbDevice);
|
||||
HIDDeviceOpenResult(deviceID, false);
|
||||
|
||||
@@ -52,7 +52,7 @@ class HIDDeviceUSB implements HIDDevice {
|
||||
@Override
|
||||
public String getSerialNumber() {
|
||||
String result = null;
|
||||
if (Build.VERSION.SDK_INT >= 21) {
|
||||
if (Build.VERSION.SDK_INT >= 21 /* Android 5.0 (LOLLIPOP) */) {
|
||||
try {
|
||||
result = mDevice.getSerialNumber();
|
||||
}
|
||||
@@ -74,7 +74,7 @@ class HIDDeviceUSB implements HIDDevice {
|
||||
@Override
|
||||
public String getManufacturerName() {
|
||||
String result = null;
|
||||
if (Build.VERSION.SDK_INT >= 21) {
|
||||
if (Build.VERSION.SDK_INT >= 21 /* Android 5.0 (LOLLIPOP) */) {
|
||||
result = mDevice.getManufacturerName();
|
||||
}
|
||||
if (result == null) {
|
||||
@@ -86,7 +86,7 @@ class HIDDeviceUSB implements HIDDevice {
|
||||
@Override
|
||||
public String getProductName() {
|
||||
String result = null;
|
||||
if (Build.VERSION.SDK_INT >= 21) {
|
||||
if (Build.VERSION.SDK_INT >= 21 /* Android 5.0 (LOLLIPOP) */) {
|
||||
result = mDevice.getProductName();
|
||||
}
|
||||
if (result == null) {
|
||||
|
||||
@@ -29,6 +29,7 @@ public class SDL {
|
||||
|
||||
// This function stores the current activity (SDL or not)
|
||||
public static void setContext(Context context) {
|
||||
SDLAudioManager.setContext(context);
|
||||
mContext = context;
|
||||
}
|
||||
|
||||
@@ -37,6 +38,10 @@ public class SDL {
|
||||
}
|
||||
|
||||
public static void loadLibrary(String libraryName) throws UnsatisfiedLinkError, SecurityException, NullPointerException {
|
||||
loadLibrary(libraryName, mContext);
|
||||
}
|
||||
|
||||
public static void loadLibrary(String libraryName, Context context) throws UnsatisfiedLinkError, SecurityException, NullPointerException {
|
||||
|
||||
if (libraryName == null) {
|
||||
throw new NullPointerException("No library name provided.");
|
||||
@@ -52,10 +57,10 @@ public class SDL {
|
||||
// To use ReLinker, just add it as a dependency. For more information, see
|
||||
// https://github.com/KeepSafe/ReLinker for ReLinker's repository.
|
||||
//
|
||||
Class<?> relinkClass = mContext.getClassLoader().loadClass("com.getkeepsafe.relinker.ReLinker");
|
||||
Class<?> relinkListenerClass = mContext.getClassLoader().loadClass("com.getkeepsafe.relinker.ReLinker$LoadListener");
|
||||
Class<?> contextClass = mContext.getClassLoader().loadClass("android.content.Context");
|
||||
Class<?> stringClass = mContext.getClassLoader().loadClass("java.lang.String");
|
||||
Class<?> relinkClass = context.getClassLoader().loadClass("com.getkeepsafe.relinker.ReLinker");
|
||||
Class<?> relinkListenerClass = context.getClassLoader().loadClass("com.getkeepsafe.relinker.ReLinker$LoadListener");
|
||||
Class<?> contextClass = context.getClassLoader().loadClass("android.content.Context");
|
||||
Class<?> stringClass = context.getClassLoader().loadClass("java.lang.String");
|
||||
|
||||
// Get a 'force' instance of the ReLinker, so we can ensure libraries are reinstalled if
|
||||
// they've changed during updates.
|
||||
@@ -65,7 +70,7 @@ public class SDL {
|
||||
|
||||
// Actually load the library!
|
||||
Method loadMethod = relinkInstanceClass.getDeclaredMethod("loadLibrary", contextClass, stringClass, stringClass, relinkListenerClass);
|
||||
loadMethod.invoke(relinkInstance, mContext, libraryName, null, null);
|
||||
loadMethod.invoke(relinkInstance, context, libraryName, null, null);
|
||||
}
|
||||
catch (final Throwable e) {
|
||||
// Fall back
|
||||
|
||||
@@ -60,8 +60,8 @@ import java.util.Locale;
|
||||
public class SDLActivity extends Activity implements View.OnSystemUiVisibilityChangeListener {
|
||||
private static final String TAG = "SDL";
|
||||
private static final int SDL_MAJOR_VERSION = 2;
|
||||
private static final int SDL_MINOR_VERSION = 26;
|
||||
private static final int SDL_MICRO_VERSION = 1;
|
||||
private static final int SDL_MINOR_VERSION = 32;
|
||||
private static final int SDL_MICRO_VERSION = 8;
|
||||
/*
|
||||
// Display InputType.SOURCE/CLASS of events and devices
|
||||
//
|
||||
@@ -89,11 +89,11 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
||||
| InputDevice.SOURCE_CLASS_POSITION
|
||||
| InputDevice.SOURCE_CLASS_TRACKBALL);
|
||||
|
||||
if (s2 != 0) cls += "Some_Unkown";
|
||||
if (s2 != 0) cls += "Some_Unknown";
|
||||
|
||||
s2 = s_copy & InputDevice.SOURCE_ANY; // keep source only, no class;
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
if (Build.VERSION.SDK_INT >= 23) {
|
||||
tst = InputDevice.SOURCE_BLUETOOTH_STYLUS;
|
||||
if ((s & tst) == tst) src += " BLUETOOTH_STYLUS";
|
||||
s2 &= ~tst;
|
||||
@@ -107,7 +107,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
||||
if ((s & tst) == tst) src += " GAMEPAD";
|
||||
s2 &= ~tst;
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
if (Build.VERSION.SDK_INT >= 21) {
|
||||
tst = InputDevice.SOURCE_HDMI;
|
||||
if ((s & tst) == tst) src += " HDMI";
|
||||
s2 &= ~tst;
|
||||
@@ -146,7 +146,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
||||
if ((s & tst) == tst) src += " TOUCHSCREEN";
|
||||
s2 &= ~tst;
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
|
||||
if (Build.VERSION.SDK_INT >= 18) {
|
||||
tst = InputDevice.SOURCE_TOUCH_NAVIGATION;
|
||||
if ((s & tst) == tst) src += " TOUCH_NAVIGATION";
|
||||
s2 &= ~tst;
|
||||
@@ -163,14 +163,14 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
||||
if (s == FLAG_TAINTED) src += " FLAG_TAINTED";
|
||||
s2 &= ~FLAG_TAINTED;
|
||||
|
||||
if (s2 != 0) src += " Some_Unkown";
|
||||
if (s2 != 0) src += " Some_Unknown";
|
||||
|
||||
Log.v(TAG, prefix + "int=" + s_copy + " CLASS={" + cls + " } source(s):" + src);
|
||||
}
|
||||
*/
|
||||
|
||||
public static boolean mIsResumedCalled, mHasFocus;
|
||||
public static final boolean mHasMultiWindow = (Build.VERSION.SDK_INT >= 24);
|
||||
public static final boolean mHasMultiWindow = (Build.VERSION.SDK_INT >= 24 /* Android 7.0 (N) */);
|
||||
|
||||
// Cursor types
|
||||
// private static final int SDL_SYSTEM_CURSOR_NONE = -1;
|
||||
@@ -224,9 +224,9 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
||||
|
||||
protected static SDLGenericMotionListener_API12 getMotionListener() {
|
||||
if (mMotionListener == null) {
|
||||
if (Build.VERSION.SDK_INT >= 26) {
|
||||
if (Build.VERSION.SDK_INT >= 26 /* Android 8.0 (O) */) {
|
||||
mMotionListener = new SDLGenericMotionListener_API26();
|
||||
} else if (Build.VERSION.SDK_INT >= 24) {
|
||||
} else if (Build.VERSION.SDK_INT >= 24 /* Android 7.0 (N) */) {
|
||||
mMotionListener = new SDLGenericMotionListener_API24();
|
||||
} else {
|
||||
mMotionListener = new SDLGenericMotionListener_API12();
|
||||
@@ -281,7 +281,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
||||
// Load the .so
|
||||
public void loadLibraries() {
|
||||
for (String lib : getLibraries()) {
|
||||
SDL.loadLibrary(lib);
|
||||
SDL.loadLibrary(lib, this);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -393,7 +393,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
||||
mHIDDeviceManager = HIDDeviceManager.acquire(this);
|
||||
|
||||
// Set up the surface
|
||||
mSurface = createSDLSurface(getApplication());
|
||||
mSurface = createSDLSurface(this);
|
||||
|
||||
mLayout = new RelativeLayout(this);
|
||||
mLayout.addView(mSurface);
|
||||
@@ -404,7 +404,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
||||
SDLActivity.onNativeOrientationChanged(mCurrentOrientation);
|
||||
|
||||
try {
|
||||
if (Build.VERSION.SDK_INT < 24) {
|
||||
if (Build.VERSION.SDK_INT < 24 /* Android 7.0 (N) */) {
|
||||
mCurrentLocale = getContext().getResources().getConfiguration().locale;
|
||||
} else {
|
||||
mCurrentLocale = getContext().getResources().getConfiguration().getLocales().get(0);
|
||||
@@ -588,6 +588,8 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
||||
mHIDDeviceManager = null;
|
||||
}
|
||||
|
||||
SDLAudioManager.release(this);
|
||||
|
||||
if (SDLActivity.mBrokenLibraries) {
|
||||
super.onDestroy();
|
||||
return;
|
||||
@@ -766,7 +768,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
||||
}
|
||||
break;
|
||||
case COMMAND_CHANGE_WINDOW_STYLE:
|
||||
if (Build.VERSION.SDK_INT >= 19) {
|
||||
if (Build.VERSION.SDK_INT >= 19 /* Android 4.4 (KITKAT) */) {
|
||||
if (context instanceof Activity) {
|
||||
Window window = ((Activity) context).getWindow();
|
||||
if (window != null) {
|
||||
@@ -788,6 +790,9 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
||||
window.clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
||||
SDLActivity.mFullscreenModeActive = false;
|
||||
}
|
||||
if (Build.VERSION.SDK_INT >= 28 /* Android 9 (Pie) */) {
|
||||
window.getAttributes().layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Log.e(TAG, "error handling message, getContext() returned no Activity");
|
||||
@@ -841,7 +846,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
||||
msg.obj = data;
|
||||
boolean result = commandHandler.sendMessage(msg);
|
||||
|
||||
if (Build.VERSION.SDK_INT >= 19) {
|
||||
if (Build.VERSION.SDK_INT >= 19 /* Android 4.4 (KITKAT) */) {
|
||||
if (command == COMMAND_CHANGE_WINDOW_STYLE) {
|
||||
// Ensure we don't return until the resize has actually happened,
|
||||
// or 500ms have passed.
|
||||
@@ -969,15 +974,18 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
||||
/* If set, hint "explicitly controls which UI orientations are allowed". */
|
||||
if (hint.contains("LandscapeRight") && hint.contains("LandscapeLeft")) {
|
||||
orientation_landscape = ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE;
|
||||
} else if (hint.contains("LandscapeRight")) {
|
||||
orientation_landscape = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
|
||||
} else if (hint.contains("LandscapeLeft")) {
|
||||
orientation_landscape = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
|
||||
} else if (hint.contains("LandscapeRight")) {
|
||||
orientation_landscape = ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE;
|
||||
}
|
||||
|
||||
if (hint.contains("Portrait") && hint.contains("PortraitUpsideDown")) {
|
||||
/* exact match to 'Portrait' to distinguish with PortraitUpsideDown */
|
||||
boolean contains_Portrait = hint.contains("Portrait ") || hint.endsWith("Portrait");
|
||||
|
||||
if (contains_Portrait && hint.contains("PortraitUpsideDown")) {
|
||||
orientation_portrait = ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT;
|
||||
} else if (hint.contains("Portrait")) {
|
||||
} else if (contains_Portrait) {
|
||||
orientation_portrait = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
|
||||
} else if (hint.contains("PortraitUpsideDown")) {
|
||||
orientation_portrait = ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT;
|
||||
@@ -990,8 +998,8 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
||||
/* No valid hint, nothing is explicitly allowed */
|
||||
if (!is_portrait_allowed && !is_landscape_allowed) {
|
||||
if (resizable) {
|
||||
/* All orientations are allowed */
|
||||
req = ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR;
|
||||
/* All orientations are allowed, respecting user orientation lock setting */
|
||||
req = ActivityInfo.SCREEN_ORIENTATION_FULL_USER;
|
||||
} else {
|
||||
/* Fixed window and nothing specified. Get orientation from w/h of created window */
|
||||
req = (w > h ? ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE : ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT);
|
||||
@@ -1000,8 +1008,8 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
||||
/* At least one orientation is allowed */
|
||||
if (resizable) {
|
||||
if (is_portrait_allowed && is_landscape_allowed) {
|
||||
/* hint allows both landscape and portrait, promote to full sensor */
|
||||
req = ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR;
|
||||
/* hint allows both landscape and portrait, promote to full user */
|
||||
req = ActivityInfo.SCREEN_ORIENTATION_FULL_USER;
|
||||
} else {
|
||||
/* Use the only one allowed "orientation" */
|
||||
req = (is_landscape_allowed ? orientation_landscape : orientation_portrait);
|
||||
@@ -1090,7 +1098,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
||||
// thus SDK version 27. If we are in DeX mode and not API 27 or higher, as a result,
|
||||
// we should stick to relative mode.
|
||||
//
|
||||
if ((Build.VERSION.SDK_INT < 27) && isDeXMode()) {
|
||||
if (Build.VERSION.SDK_INT < 27 /* Android 8.1 (O_MR1) */ && isDeXMode()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1180,7 +1188,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
||||
* This method is called by SDL using JNI.
|
||||
*/
|
||||
public static boolean isDeXMode() {
|
||||
if (Build.VERSION.SDK_INT < 24) {
|
||||
if (Build.VERSION.SDK_INT < 24 /* Android 7.0 (N) */) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
@@ -1340,23 +1348,6 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
||||
}
|
||||
}
|
||||
|
||||
if ((source & InputDevice.SOURCE_KEYBOARD) == InputDevice.SOURCE_KEYBOARD) {
|
||||
if (event.getAction() == KeyEvent.ACTION_DOWN) {
|
||||
if (isTextInputEvent(event)) {
|
||||
if (ic != null) {
|
||||
ic.commitText(String.valueOf((char) event.getUnicodeChar()), 1);
|
||||
} else {
|
||||
SDLInputConnection.nativeCommitText(String.valueOf((char) event.getUnicodeChar()), 1);
|
||||
}
|
||||
}
|
||||
onNativeKeyDown(keyCode);
|
||||
return true;
|
||||
} else if (event.getAction() == KeyEvent.ACTION_UP) {
|
||||
onNativeKeyUp(keyCode);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if ((source & InputDevice.SOURCE_MOUSE) == InputDevice.SOURCE_MOUSE) {
|
||||
// on some devices key events are sent for mouse BUTTON_BACK/FORWARD presses
|
||||
// they are ignored here because sending them as mouse input to SDL is messy
|
||||
@@ -1371,6 +1362,21 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
||||
}
|
||||
}
|
||||
|
||||
if (event.getAction() == KeyEvent.ACTION_DOWN) {
|
||||
if (isTextInputEvent(event)) {
|
||||
if (ic != null) {
|
||||
ic.commitText(String.valueOf((char) event.getUnicodeChar()), 1);
|
||||
} else {
|
||||
SDLInputConnection.nativeCommitText(String.valueOf((char) event.getUnicodeChar()), 1);
|
||||
}
|
||||
}
|
||||
onNativeKeyDown(keyCode);
|
||||
return true;
|
||||
} else if (event.getAction() == KeyEvent.ACTION_UP) {
|
||||
onNativeKeyUp(keyCode);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1617,7 +1623,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
||||
private final Runnable rehideSystemUi = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (Build.VERSION.SDK_INT >= 19) {
|
||||
if (Build.VERSION.SDK_INT >= 19 /* Android 4.4 (KITKAT) */) {
|
||||
int flags = View.SYSTEM_UI_FLAG_FULLSCREEN |
|
||||
View.SYSTEM_UI_FLAG_HIDE_NAVIGATION |
|
||||
View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY |
|
||||
@@ -1670,7 +1676,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
||||
Bitmap bitmap = Bitmap.createBitmap(colors, width, height, Bitmap.Config.ARGB_8888);
|
||||
++mLastCursorID;
|
||||
|
||||
if (Build.VERSION.SDK_INT >= 24) {
|
||||
if (Build.VERSION.SDK_INT >= 24 /* Android 7.0 (N) */) {
|
||||
try {
|
||||
mCursors.put(mLastCursorID, PointerIcon.create(bitmap, hotSpotX, hotSpotY));
|
||||
} catch (Exception e) {
|
||||
@@ -1686,7 +1692,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
||||
* This method is called by SDL using JNI.
|
||||
*/
|
||||
public static void destroyCustomCursor(int cursorID) {
|
||||
if (Build.VERSION.SDK_INT >= 24) {
|
||||
if (Build.VERSION.SDK_INT >= 24 /* Android 7.0 (N) */) {
|
||||
try {
|
||||
mCursors.remove(cursorID);
|
||||
} catch (Exception e) {
|
||||
@@ -1700,7 +1706,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
||||
*/
|
||||
public static boolean setCustomCursor(int cursorID) {
|
||||
|
||||
if (Build.VERSION.SDK_INT >= 24) {
|
||||
if (Build.VERSION.SDK_INT >= 24 /* Android 7.0 (N) */) {
|
||||
try {
|
||||
mSurface.setPointerIcon(mCursors.get(cursorID));
|
||||
} catch (Exception e) {
|
||||
@@ -1755,7 +1761,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
||||
cursor_type = 1002; //PointerIcon.TYPE_HAND;
|
||||
break;
|
||||
}
|
||||
if (Build.VERSION.SDK_INT >= 24) {
|
||||
if (Build.VERSION.SDK_INT >= 24 /* Android 7.0 (N) */) {
|
||||
try {
|
||||
mSurface.setPointerIcon(PointerIcon.getSystemIcon(SDL.getContext(), cursor_type));
|
||||
} catch (Exception e) {
|
||||
@@ -1769,7 +1775,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
||||
* This method is called by SDL using JNI.
|
||||
*/
|
||||
public static void requestPermission(String permission, int requestCode) {
|
||||
if (Build.VERSION.SDK_INT < 23) {
|
||||
if (Build.VERSION.SDK_INT < 23 /* Android 6.0 (M) */) {
|
||||
nativePermissionResult(requestCode, true);
|
||||
return;
|
||||
}
|
||||
@@ -1798,7 +1804,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
||||
i.setData(Uri.parse(url));
|
||||
|
||||
int flags = Intent.FLAG_ACTIVITY_NO_HISTORY | Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
|
||||
if (Build.VERSION.SDK_INT >= 21) {
|
||||
if (Build.VERSION.SDK_INT >= 21 /* Android 5.0 (LOLLIPOP) */) {
|
||||
flags |= Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
|
||||
} else {
|
||||
flags |= Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET;
|
||||
@@ -2002,6 +2008,18 @@ class SDLInputConnection extends BaseInputConnection {
|
||||
|
||||
@Override
|
||||
public boolean deleteSurroundingText(int beforeLength, int afterLength) {
|
||||
if (Build.VERSION.SDK_INT <= 29 /* Android 10.0 (Q) */) {
|
||||
// Workaround to capture backspace key. Ref: http://stackoverflow.com/questions>/14560344/android-backspace-in-webview-baseinputconnection
|
||||
// and https://bugzilla.libsdl.org/show_bug.cgi?id=2265
|
||||
if (beforeLength > 0 && afterLength == 0) {
|
||||
// backspace(s)
|
||||
while (beforeLength-- > 0) {
|
||||
nativeGenerateScancodeForUnichar('\b');
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!super.deleteSurroundingText(beforeLength, afterLength)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user