mirror of
https://github.com/fallout2-ce/fallout2-ce.git
synced 2026-07-27 16:47:11 -07:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
dcd450a9b7 | ||
|
|
bfbf692cc0 | ||
|
|
2714dc1ea1 | ||
|
|
8604d9c401 | ||
|
|
b9261c3da2 | ||
|
|
ed7176b796 | ||
|
|
6cac53d20b | ||
|
|
ad3860790c | ||
|
|
bffe81d0b3 | ||
|
|
6ab08bd22b | ||
|
|
060c79fc20 | ||
|
|
ac64fde502 | ||
|
|
7496afa4f8 | ||
|
|
66955f893a | ||
|
|
9ee4cb4a26 | ||
|
|
a5cefd6c8b | ||
|
|
d040ea814a | ||
|
|
03145e4fcd | ||
|
|
812079004c | ||
|
|
6224af6178 | ||
|
|
a8d3cdd148 | ||
|
|
95cc863fde | ||
|
|
cc1562b056 | ||
|
|
07f3c82444 | ||
|
|
9976728e04 | ||
|
|
5922d15b1c | ||
|
|
248d6dfb92 | ||
|
|
73cc93a3e4 | ||
|
|
34259269a4 | ||
|
|
11217974c6 | ||
|
|
0e13989f9c | ||
|
|
57dcf42b5c | ||
|
|
c2c26db5d9 | ||
|
|
b6ee5fcbe9 | ||
|
|
0e11569397 | ||
|
|
4b137dac5f | ||
|
|
1f6d5ebbc9 | ||
|
|
462baa0a04 | ||
|
|
b74f3c368b | ||
|
|
a05ab09e1b | ||
|
|
1b0cd6d757 | ||
|
|
b8dea116ee | ||
|
|
e11f1af9ae | ||
|
|
9c34b26fec | ||
|
|
9a6d45541f | ||
|
|
f4775775b8 | ||
|
|
a48d744cde | ||
|
|
16dbe1122e | ||
|
|
b0cb70ffa6 | ||
|
|
512530c653 | ||
|
|
982d4cc0f9 | ||
|
|
3b951b8578 | ||
|
|
17a4ee8a68 | ||
|
|
c85cda4b48 | ||
|
|
c7ca358295 | ||
|
|
96296417c6 | ||
|
|
737076a126 | ||
|
|
c0908cf14f | ||
|
|
343911f736 | ||
|
|
281c1aa82a | ||
|
|
18afce71b0 | ||
|
|
9599d63f45 | ||
|
|
ce351988b5 | ||
|
|
feb3821565 | ||
|
|
54eaff26ea | ||
|
|
5a7ffde45e | ||
|
|
1c0385ad11 | ||
|
|
0fe6d88a3a | ||
|
|
7596d4d721 | ||
|
|
8333e553e2 | ||
|
|
6f62cfd466 | ||
|
|
280b55ab05 | ||
|
|
e02dcdf69d | ||
|
|
b5701fb9b9 | ||
|
|
c569b879f6 | ||
|
|
b36ac50425 | ||
|
|
029a84a113 | ||
|
|
e6fddd6905 | ||
|
|
b0b69bd780 | ||
|
|
6de4ac87df | ||
|
|
502c920656 | ||
|
|
c383fc6b95 | ||
|
|
4b03c714b4 | ||
|
|
0d93279a10 | ||
|
|
510d7bfe95 | ||
|
|
19d0d2919f | ||
|
|
42f01c8d45 | ||
|
|
0474199b5c | ||
|
|
8a4ce6c658 | ||
|
|
884034f0bf | ||
|
|
602ef7c1e1 | ||
|
|
897ff2bbd2 | ||
|
|
9ade107e95 | ||
|
|
1698cfa04b | ||
|
|
59639c60a3 | ||
|
|
f056f0e131 | ||
|
|
dc90beb696 | ||
|
|
90da2164f2 | ||
|
|
9d9e09e80f | ||
|
|
cd51e0cdd7 | ||
|
|
d49869f45c | ||
|
|
3a541d4b67 | ||
|
|
7471f9cdbe | ||
|
|
fe9ba9171e | ||
|
|
6c03e4e293 | ||
|
|
3f25c9265b | ||
|
|
fa475c754e | ||
|
|
5e9cf96106 | ||
|
|
a70912d311 | ||
|
|
67351b8b09 | ||
|
|
e0e0a1ee7d | ||
|
|
fa11122f87 | ||
|
|
ef54463fcc | ||
|
|
2255481d50 | ||
|
|
03a7e2e1b1 | ||
|
|
19bcfebe0d | ||
|
|
393d89f8c4 | ||
|
|
9c6286f94a | ||
|
|
fa058f24b4 | ||
|
|
b2420bdc80 | ||
|
|
23bee9fd62 | ||
|
|
3ec827d5c1 | ||
|
|
c692fc91af | ||
|
|
a38151bf2c | ||
|
|
b689b3a757 | ||
|
|
e7d68c4f72 | ||
|
|
bc43bdc99c | ||
|
|
e5aa4a3518 | ||
|
|
4e98093d6c | ||
|
|
1342fd3ecf | ||
|
|
3015f39368 | ||
|
|
37f7ecc1c3 | ||
|
|
bdf2c219ab | ||
|
|
3488833c2e | ||
|
|
4821cab724 | ||
|
|
0851354c8a | ||
|
|
2f42818a33 | ||
|
|
12367acb33 | ||
|
|
caa8b06d4f | ||
|
|
2b63360b95 | ||
|
|
8dd8d1c312 | ||
|
|
8ee0f478ad | ||
|
|
9c6daa4abe | ||
|
|
01f264e0c2 | ||
|
|
1bbd586cbb | ||
|
|
223930c464 | ||
|
|
40510539ee | ||
|
|
c47113ca29 | ||
|
|
ad9b8586e9 | ||
|
|
5b151634a5 | ||
|
|
7627092478 | ||
|
|
b60fe43b06 | ||
|
|
21aec548af | ||
|
|
beb010cd0f | ||
|
|
b23d05f850 | ||
|
|
e16659d96d | ||
|
|
4c1020af5f | ||
|
|
a4105d5826 | ||
|
|
ddae4df4ab | ||
|
|
74a9a9e530 | ||
|
|
223d214f57 | ||
|
|
a52fd4e70a | ||
|
|
266c727870 | ||
|
|
54d230432b | ||
|
|
9663532e44 | ||
|
|
a4e9123bcc | ||
|
|
08691ce319 | ||
|
|
d03fd5e43f | ||
|
|
7ddd8f2894 | ||
|
|
93a341bbaa | ||
|
|
d2c4538656 | ||
|
|
8a5c3bc97b | ||
|
|
db57fe6a5e | ||
|
|
56d798dd12 | ||
|
|
90942c46b2 | ||
|
|
1cda2beef7 | ||
|
|
8754a5d6c9 | ||
|
|
65f43804b3 | ||
|
|
9b150257fb | ||
|
|
32c7883f82 | ||
|
|
1c73fb7240 | ||
|
|
cce1bb223e | ||
|
|
624076ae9b | ||
|
|
8d61a19dbe | ||
|
|
0264c00ab8 | ||
|
|
e1f22b8218 | ||
|
|
fe4c125474 | ||
|
|
56d27400ac | ||
|
|
b5681984cd | ||
|
|
a541d0f24a | ||
|
|
20a41088c6 | ||
|
|
16ab9cb958 | ||
|
|
5f9ceb7f5d | ||
|
|
a1c1e03da0 | ||
|
|
ac0a044a32 | ||
|
|
4aae167bd8 | ||
|
|
2e5be31ed4 | ||
|
|
45278f66a5 | ||
|
|
2205077d36 | ||
|
|
67f966f7a9 | ||
|
|
463968d798 | ||
|
|
109dc6680c | ||
|
|
23c5f070fa | ||
|
|
fd9843f8dc | ||
|
|
443070226f | ||
|
|
db63d8a085 | ||
|
|
f203cfcc83 | ||
|
|
9ceb490f72 | ||
|
|
5b7a676b35 | ||
|
|
e50e26cf87 | ||
|
|
f59c072d68 | ||
|
|
79c396c1a0 | ||
|
|
9bb053b3ba | ||
|
|
3168c2ec09 |
@@ -75,6 +75,51 @@ jobs:
|
||||
path: os/android/app/build/outputs/apk/debug/app-debug.apk
|
||||
retention-days: 7
|
||||
|
||||
ios:
|
||||
name: iOS
|
||||
|
||||
runs-on: macos-11
|
||||
|
||||
steps:
|
||||
- name: Clone
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Cache cmake build
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: build
|
||||
key: ios-cmake-v1
|
||||
|
||||
- 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 \
|
||||
# EOL
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
cmake \
|
||||
--build build \
|
||||
-j $(sysctl -n hw.physicalcpu) \
|
||||
--target package \
|
||||
# EOL
|
||||
|
||||
# TODO: Should be a part of packaging.
|
||||
- name: Prepare for uploading
|
||||
run: |
|
||||
cp build/fallout2-ce.zip build/fallout2-ce.ipa
|
||||
|
||||
- name: Upload
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: fallout2-ce.ipa
|
||||
path: build/fallout2-ce.ipa
|
||||
retention-days: 7
|
||||
|
||||
linux:
|
||||
name: Linux (${{ matrix.arch }})
|
||||
|
||||
|
||||
@@ -56,6 +56,48 @@ jobs:
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
ios:
|
||||
name: iOS
|
||||
|
||||
runs-on: macos-11
|
||||
|
||||
steps:
|
||||
- name: Clone
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Cache cmake build
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: build
|
||||
key: ios-cmake-v1
|
||||
|
||||
- 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 \
|
||||
# EOL
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
cmake \
|
||||
--build build \
|
||||
-j $(sysctl -n hw.physicalcpu) \
|
||||
--target package \
|
||||
# EOL
|
||||
|
||||
- name: Upload
|
||||
run: |
|
||||
cd build
|
||||
cp fallout2-ce.zip fallout2-ce-ios.ipa
|
||||
gh release upload ${{ github.ref_name }} fallout2-ce-ios.ipa
|
||||
rm fallout2-ce-ios.ipa
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
linux:
|
||||
name: Linux (${{ matrix.arch }})
|
||||
|
||||
|
||||
+63
-27
@@ -5,8 +5,13 @@ set(CMAKE_POLICY_DEFAULT_CMP0077 NEW)
|
||||
set(EXECUTABLE_NAME fallout2-ce)
|
||||
|
||||
if (APPLE)
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET "10.11" CACHE STRING "")
|
||||
set(CMAKE_OSX_ARCHITECTURES "x86_64;arm64" CACHE STRING "")
|
||||
if(IOS)
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET "11" CACHE STRING "")
|
||||
set(CMAKE_OSX_ARCHITECTURES "arm64" CACHE STRING "")
|
||||
else()
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET "10.11" CACHE STRING "")
|
||||
set(CMAKE_OSX_ARCHITECTURES "x86_64;arm64" CACHE STRING "")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
project(${EXECUTABLE_NAME})
|
||||
@@ -52,8 +57,6 @@ target_sources(${EXECUTABLE_NAME} PUBLIC
|
||||
"src/combat.h"
|
||||
"src/config.cc"
|
||||
"src/config.h"
|
||||
"src/core.cc"
|
||||
"src/core.h"
|
||||
"src/credits.cc"
|
||||
"src/credits.h"
|
||||
"src/critter.cc"
|
||||
@@ -80,8 +83,6 @@ target_sources(${EXECUTABLE_NAME} PUBLIC
|
||||
"src/display_monitor.h"
|
||||
"src/draw.cc"
|
||||
"src/draw.h"
|
||||
"src/electronic_registration.cc"
|
||||
"src/electronic_registration.h"
|
||||
"src/elevator.cc"
|
||||
"src/elevator.h"
|
||||
"src/endgame.cc"
|
||||
@@ -104,8 +105,6 @@ target_sources(${EXECUTABLE_NAME} PUBLIC
|
||||
"src/game_mouse.h"
|
||||
"src/game_movie.cc"
|
||||
"src/game_movie.h"
|
||||
"src/game_palette.cc"
|
||||
"src/game_palette.h"
|
||||
"src/game_sound.cc"
|
||||
"src/game_sound.h"
|
||||
"src/game_vars.h"
|
||||
@@ -115,10 +114,10 @@ target_sources(${EXECUTABLE_NAME} PUBLIC
|
||||
"src/geometry.h"
|
||||
"src/graph_lib.cc"
|
||||
"src/graph_lib.h"
|
||||
"src/grayscale.cc"
|
||||
"src/grayscale.h"
|
||||
"src/heap.cc"
|
||||
"src/heap.h"
|
||||
"src/input.cc"
|
||||
"src/input.h"
|
||||
"src/interface.cc"
|
||||
"src/interface.h"
|
||||
"src/interpreter_extra.cc"
|
||||
@@ -131,6 +130,8 @@ target_sources(${EXECUTABLE_NAME} PUBLIC
|
||||
"src/inventory.h"
|
||||
"src/item.cc"
|
||||
"src/item.h"
|
||||
"src/kb.cc"
|
||||
"src/kb.h"
|
||||
"src/light.cc"
|
||||
"src/light.h"
|
||||
"src/lips.cc"
|
||||
@@ -153,6 +154,8 @@ target_sources(${EXECUTABLE_NAME} PUBLIC
|
||||
"src/mmx.h"
|
||||
"src/mouse_manager.cc"
|
||||
"src/mouse_manager.h"
|
||||
"src/mouse.cc"
|
||||
"src/mouse.h"
|
||||
"src/movie_effect.cc"
|
||||
"src/movie_effect.h"
|
||||
"src/movie_lib.cc"
|
||||
@@ -214,6 +217,8 @@ target_sources(${EXECUTABLE_NAME} PUBLIC
|
||||
"src/stat.h"
|
||||
"src/string_parsers.cc"
|
||||
"src/string_parsers.h"
|
||||
"src/svga.cc"
|
||||
"src/svga.h"
|
||||
"src/text_font.cc"
|
||||
"src/text_font.h"
|
||||
"src/text_object.cc"
|
||||
@@ -223,8 +228,8 @@ target_sources(${EXECUTABLE_NAME} PUBLIC
|
||||
"src/trait_defs.h"
|
||||
"src/trait.cc"
|
||||
"src/trait.h"
|
||||
"src/trap.cc"
|
||||
"src/trap.h"
|
||||
"src/vcr.cc"
|
||||
"src/vcr.h"
|
||||
"src/version.cc"
|
||||
"src/version.h"
|
||||
"src/widget.cc"
|
||||
@@ -254,10 +259,25 @@ target_sources(${EXECUTABLE_NAME} PUBLIC
|
||||
"src/platform_compat.h"
|
||||
"src/pointer_registry.cc"
|
||||
"src/pointer_registry.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_lists.cc"
|
||||
"src/sfall_lists.h"
|
||||
"src/sfall_opcodes.cc"
|
||||
"src/sfall_opcodes.h"
|
||||
)
|
||||
|
||||
if(IOS)
|
||||
target_sources(${EXECUTABLE_NAME} PUBLIC
|
||||
"src/platform/ios/paths.h"
|
||||
"src/platform/ios/paths.mm"
|
||||
)
|
||||
endif()
|
||||
|
||||
if(WIN32)
|
||||
target_compile_definitions(${EXECUTABLE_NAME} PUBLIC
|
||||
_CRT_SECURE_NO_WARNINGS
|
||||
@@ -287,13 +307,21 @@ 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")
|
||||
|
||||
set_target_properties(${EXECUTABLE_NAME} PROPERTIES MACOSX_BUNDLE_INFO_PLIST "${CMAKE_SOURCE_DIR}/os/macos/Info.plist")
|
||||
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")
|
||||
else()
|
||||
set_target_properties(${EXECUTABLE_NAME} PROPERTIES MACOSX_BUNDLE_INFO_PLIST "${CMAKE_SOURCE_DIR}/os/macos/Info.plist")
|
||||
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.1.0")
|
||||
set(MACOSX_BUNDLE_BUNDLE_VERSION "1.1.0")
|
||||
set(MACOSX_BUNDLE_SHORT_VERSION_STRING "1.2.0")
|
||||
set(MACOSX_BUNDLE_BUNDLE_VERSION "1.2.0")
|
||||
endif()
|
||||
|
||||
add_subdirectory("third_party/fpattern")
|
||||
@@ -315,23 +343,31 @@ target_link_libraries(${EXECUTABLE_NAME} ${SDL2_LIBRARIES})
|
||||
target_include_directories(${EXECUTABLE_NAME} PRIVATE ${SDL2_INCLUDE_DIRS})
|
||||
|
||||
if(APPLE)
|
||||
install(TARGETS ${EXECUTABLE_NAME} DESTINATION .)
|
||||
install(CODE "
|
||||
include(BundleUtilities)
|
||||
fixup_bundle(${CMAKE_BINARY_DIR}/${MACOSX_BUNDLE_BUNDLE_NAME}.app \"\" \"\")
|
||||
"
|
||||
COMPONENT Runtime)
|
||||
if(IOS)
|
||||
install(TARGETS ${EXECUTABLE_NAME} DESTINATION "Payload")
|
||||
|
||||
if (CPACK_BUNDLE_APPLE_CERT_APP)
|
||||
set(CPACK_GENERATOR "ZIP")
|
||||
set(CPACK_INCLUDE_TOPLEVEL_DIRECTORY OFF)
|
||||
set(CPACK_PACKAGE_FILE_NAME "fallout2-ce")
|
||||
else()
|
||||
install(TARGETS ${EXECUTABLE_NAME} DESTINATION .)
|
||||
install(CODE "
|
||||
execute_process(COMMAND codesign --deep --force --options runtime --sign \"${CPACK_BUNDLE_APPLE_CERT_APP}\" ${CMAKE_BINARY_DIR}/${MACOSX_BUNDLE_BUNDLE_NAME}.app)
|
||||
include(BundleUtilities)
|
||||
fixup_bundle(${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")
|
||||
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")
|
||||
endif()
|
||||
|
||||
include(CPack)
|
||||
endif()
|
||||
|
||||
@@ -44,6 +44,16 @@ $ sudo apt install libsdl2-2.0-0
|
||||
|
||||
- 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.
|
||||
|
||||
### iOS
|
||||
|
||||
> **NOTE**: See Android note on controls.
|
||||
|
||||
- Download `fallout2-ce.ipa`. Use sideloading applications ([AltStore](https://altstore.io/) or [Sideloadly](https://sideloadly.io/)) to install it to your device. Alternatively you can always build from source with your own signing certificate.
|
||||
|
||||
- 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)).
|
||||
|
||||
## Contributing
|
||||
|
||||
Integrating Sfall goodies is the top priority. Quality of life updates are OK too. Please no large scale refactorings at this time as we need to reconcile changes from Reference Edition, which will make this process slow and error-prone. In any case open up an issue with your suggestion or to notify other people that something is being worked on.
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -9,8 +9,8 @@ android {
|
||||
applicationId 'com.alexbatalov.fallout2ce'
|
||||
minSdk 21
|
||||
targetSdk 32
|
||||
versionCode 2
|
||||
versionName '1.1.0'
|
||||
versionCode 3
|
||||
versionName '1.2.0'
|
||||
externalNativeBuild {
|
||||
cmake {
|
||||
arguments '-DANDROID_STL=c++_static'
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,405 @@
|
||||
package org.libsdl.app;
|
||||
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.hardware.Sensor;
|
||||
import android.hardware.SensorEvent;
|
||||
import android.hardware.SensorEventListener;
|
||||
import android.hardware.SensorManager;
|
||||
import android.os.Build;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.util.Log;
|
||||
import android.view.Display;
|
||||
import android.view.InputDevice;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.Surface;
|
||||
import android.view.SurfaceHolder;
|
||||
import android.view.SurfaceView;
|
||||
import android.view.View;
|
||||
import android.view.WindowManager;
|
||||
|
||||
|
||||
/**
|
||||
SDLSurface. This is what we draw on, so we need to know when it's created
|
||||
in order to do anything useful.
|
||||
|
||||
Because of this, that's where we set up the SDL thread
|
||||
*/
|
||||
public class SDLSurface extends SurfaceView implements SurfaceHolder.Callback,
|
||||
View.OnKeyListener, View.OnTouchListener, SensorEventListener {
|
||||
|
||||
// Sensors
|
||||
protected SensorManager mSensorManager;
|
||||
protected Display mDisplay;
|
||||
|
||||
// Keep track of the surface size to normalize touch events
|
||||
protected float mWidth, mHeight;
|
||||
|
||||
// Is SurfaceView ready for rendering
|
||||
public boolean mIsSurfaceReady;
|
||||
|
||||
// Startup
|
||||
public SDLSurface(Context context) {
|
||||
super(context);
|
||||
getHolder().addCallback(this);
|
||||
|
||||
setFocusable(true);
|
||||
setFocusableInTouchMode(true);
|
||||
requestFocus();
|
||||
setOnKeyListener(this);
|
||||
setOnTouchListener(this);
|
||||
|
||||
mDisplay = ((WindowManager)context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
|
||||
mSensorManager = (SensorManager)context.getSystemService(Context.SENSOR_SERVICE);
|
||||
|
||||
setOnGenericMotionListener(SDLActivity.getMotionListener());
|
||||
|
||||
// Some arbitrary defaults to avoid a potential division by zero
|
||||
mWidth = 1.0f;
|
||||
mHeight = 1.0f;
|
||||
|
||||
mIsSurfaceReady = false;
|
||||
}
|
||||
|
||||
public void handlePause() {
|
||||
enableSensor(Sensor.TYPE_ACCELEROMETER, false);
|
||||
}
|
||||
|
||||
public void handleResume() {
|
||||
setFocusable(true);
|
||||
setFocusableInTouchMode(true);
|
||||
requestFocus();
|
||||
setOnKeyListener(this);
|
||||
setOnTouchListener(this);
|
||||
enableSensor(Sensor.TYPE_ACCELEROMETER, true);
|
||||
}
|
||||
|
||||
public Surface getNativeSurface() {
|
||||
return getHolder().getSurface();
|
||||
}
|
||||
|
||||
// Called when we have a valid drawing surface
|
||||
@Override
|
||||
public void surfaceCreated(SurfaceHolder holder) {
|
||||
Log.v("SDL", "surfaceCreated()");
|
||||
SDLActivity.onNativeSurfaceCreated();
|
||||
}
|
||||
|
||||
// Called when we lose the surface
|
||||
@Override
|
||||
public void surfaceDestroyed(SurfaceHolder holder) {
|
||||
Log.v("SDL", "surfaceDestroyed()");
|
||||
|
||||
// Transition to pause, if needed
|
||||
SDLActivity.mNextNativeState = SDLActivity.NativeState.PAUSED;
|
||||
SDLActivity.handleNativeState();
|
||||
|
||||
mIsSurfaceReady = false;
|
||||
SDLActivity.onNativeSurfaceDestroyed();
|
||||
}
|
||||
|
||||
// Called when the surface is resized
|
||||
@Override
|
||||
public void surfaceChanged(SurfaceHolder holder,
|
||||
int format, int width, int height) {
|
||||
Log.v("SDL", "surfaceChanged()");
|
||||
|
||||
if (SDLActivity.mSingleton == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
mWidth = width;
|
||||
mHeight = height;
|
||||
int nDeviceWidth = width;
|
||||
int nDeviceHeight = height;
|
||||
try
|
||||
{
|
||||
if (Build.VERSION.SDK_INT >= 17) {
|
||||
DisplayMetrics realMetrics = new DisplayMetrics();
|
||||
mDisplay.getRealMetrics( realMetrics );
|
||||
nDeviceWidth = realMetrics.widthPixels;
|
||||
nDeviceHeight = realMetrics.heightPixels;
|
||||
}
|
||||
} catch(Exception ignored) {
|
||||
}
|
||||
|
||||
synchronized(SDLActivity.getContext()) {
|
||||
// In case we're waiting on a size change after going fullscreen, send a notification.
|
||||
SDLActivity.getContext().notifyAll();
|
||||
}
|
||||
|
||||
Log.v("SDL", "Window size: " + width + "x" + height);
|
||||
Log.v("SDL", "Device size: " + nDeviceWidth + "x" + nDeviceHeight);
|
||||
SDLActivity.nativeSetScreenResolution(width, height, nDeviceWidth, nDeviceHeight, mDisplay.getRefreshRate());
|
||||
SDLActivity.onNativeResize();
|
||||
|
||||
// Prevent a screen distortion glitch,
|
||||
// for instance when the device is in Landscape and a Portrait App is resumed.
|
||||
boolean skip = false;
|
||||
int requestedOrientation = SDLActivity.mSingleton.getRequestedOrientation();
|
||||
|
||||
if (requestedOrientation == ActivityInfo.SCREEN_ORIENTATION_PORTRAIT || requestedOrientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT) {
|
||||
if (mWidth > mHeight) {
|
||||
skip = true;
|
||||
}
|
||||
} else if (requestedOrientation == ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE || requestedOrientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE) {
|
||||
if (mWidth < mHeight) {
|
||||
skip = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Special Patch for Square Resolution: Black Berry Passport
|
||||
if (skip) {
|
||||
double min = Math.min(mWidth, mHeight);
|
||||
double max = Math.max(mWidth, mHeight);
|
||||
|
||||
if (max / min < 1.20) {
|
||||
Log.v("SDL", "Don't skip on such aspect-ratio. Could be a square resolution.");
|
||||
skip = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Don't skip in MultiWindow.
|
||||
if (skip) {
|
||||
if (Build.VERSION.SDK_INT >= 24) {
|
||||
if (SDLActivity.mSingleton.isInMultiWindowMode()) {
|
||||
Log.v("SDL", "Don't skip in Multi-Window");
|
||||
skip = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (skip) {
|
||||
Log.v("SDL", "Skip .. Surface is not ready.");
|
||||
mIsSurfaceReady = false;
|
||||
return;
|
||||
}
|
||||
|
||||
/* If the surface has been previously destroyed by onNativeSurfaceDestroyed, recreate it here */
|
||||
SDLActivity.onNativeSurfaceChanged();
|
||||
|
||||
/* Surface is ready */
|
||||
mIsSurfaceReady = true;
|
||||
|
||||
SDLActivity.mNextNativeState = SDLActivity.NativeState.RESUMED;
|
||||
SDLActivity.handleNativeState();
|
||||
}
|
||||
|
||||
// Key events
|
||||
@Override
|
||||
public boolean onKey(View v, int keyCode, KeyEvent event) {
|
||||
return SDLActivity.handleKeyEvent(v, keyCode, event, null);
|
||||
}
|
||||
|
||||
// Touch events
|
||||
@Override
|
||||
public boolean onTouch(View v, MotionEvent event) {
|
||||
/* Ref: http://developer.android.com/training/gestures/multi.html */
|
||||
int touchDevId = event.getDeviceId();
|
||||
final int pointerCount = event.getPointerCount();
|
||||
int action = event.getActionMasked();
|
||||
int pointerFingerId;
|
||||
int i = -1;
|
||||
float x,y,p;
|
||||
|
||||
/*
|
||||
* Prevent id to be -1, since it's used in SDL internal for synthetic events
|
||||
* Appears when using Android emulator, eg:
|
||||
* adb shell input mouse tap 100 100
|
||||
* adb shell input touchscreen tap 100 100
|
||||
*/
|
||||
if (touchDevId < 0) {
|
||||
touchDevId -= 1;
|
||||
}
|
||||
|
||||
// 12290 = Samsung DeX mode desktop mouse
|
||||
// 12290 = 0x3002 = 0x2002 | 0x1002 = SOURCE_MOUSE | SOURCE_TOUCHSCREEN
|
||||
// 0x2 = SOURCE_CLASS_POINTER
|
||||
if (event.getSource() == InputDevice.SOURCE_MOUSE || event.getSource() == (InputDevice.SOURCE_MOUSE | InputDevice.SOURCE_TOUCHSCREEN)) {
|
||||
int mouseButton = 1;
|
||||
try {
|
||||
Object object = event.getClass().getMethod("getButtonState").invoke(event);
|
||||
if (object != null) {
|
||||
mouseButton = (Integer) object;
|
||||
}
|
||||
} catch(Exception ignored) {
|
||||
}
|
||||
|
||||
// We need to check if we're in relative mouse mode and get the axis offset rather than the x/y values
|
||||
// if we are. We'll leverage our existing mouse motion listener
|
||||
SDLGenericMotionListener_API12 motionListener = SDLActivity.getMotionListener();
|
||||
x = motionListener.getEventX(event);
|
||||
y = motionListener.getEventY(event);
|
||||
|
||||
SDLActivity.onNativeMouse(mouseButton, action, x, y, motionListener.inRelativeMode());
|
||||
} else {
|
||||
switch(action) {
|
||||
case MotionEvent.ACTION_MOVE:
|
||||
for (i = 0; i < pointerCount; i++) {
|
||||
pointerFingerId = event.getPointerId(i);
|
||||
x = event.getX(i) / mWidth;
|
||||
y = event.getY(i) / mHeight;
|
||||
p = event.getPressure(i);
|
||||
if (p > 1.0f) {
|
||||
// may be larger than 1.0f on some devices
|
||||
// see the documentation of getPressure(i)
|
||||
p = 1.0f;
|
||||
}
|
||||
SDLActivity.onNativeTouch(touchDevId, pointerFingerId, action, x, y, p);
|
||||
}
|
||||
break;
|
||||
|
||||
case MotionEvent.ACTION_UP:
|
||||
case MotionEvent.ACTION_DOWN:
|
||||
// Primary pointer up/down, the index is always zero
|
||||
i = 0;
|
||||
/* fallthrough */
|
||||
case MotionEvent.ACTION_POINTER_UP:
|
||||
case MotionEvent.ACTION_POINTER_DOWN:
|
||||
// Non primary pointer up/down
|
||||
if (i == -1) {
|
||||
i = event.getActionIndex();
|
||||
}
|
||||
|
||||
pointerFingerId = event.getPointerId(i);
|
||||
x = event.getX(i) / mWidth;
|
||||
y = event.getY(i) / mHeight;
|
||||
p = event.getPressure(i);
|
||||
if (p > 1.0f) {
|
||||
// may be larger than 1.0f on some devices
|
||||
// see the documentation of getPressure(i)
|
||||
p = 1.0f;
|
||||
}
|
||||
SDLActivity.onNativeTouch(touchDevId, pointerFingerId, action, x, y, p);
|
||||
break;
|
||||
|
||||
case MotionEvent.ACTION_CANCEL:
|
||||
for (i = 0; i < pointerCount; i++) {
|
||||
pointerFingerId = event.getPointerId(i);
|
||||
x = event.getX(i) / mWidth;
|
||||
y = event.getY(i) / mHeight;
|
||||
p = event.getPressure(i);
|
||||
if (p > 1.0f) {
|
||||
// may be larger than 1.0f on some devices
|
||||
// see the documentation of getPressure(i)
|
||||
p = 1.0f;
|
||||
}
|
||||
SDLActivity.onNativeTouch(touchDevId, pointerFingerId, MotionEvent.ACTION_UP, x, y, p);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Sensor events
|
||||
public void enableSensor(int sensortype, boolean enabled) {
|
||||
// TODO: This uses getDefaultSensor - what if we have >1 accels?
|
||||
if (enabled) {
|
||||
mSensorManager.registerListener(this,
|
||||
mSensorManager.getDefaultSensor(sensortype),
|
||||
SensorManager.SENSOR_DELAY_GAME, null);
|
||||
} else {
|
||||
mSensorManager.unregisterListener(this,
|
||||
mSensorManager.getDefaultSensor(sensortype));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAccuracyChanged(Sensor sensor, int accuracy) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSensorChanged(SensorEvent event) {
|
||||
if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
|
||||
|
||||
// Since we may have an orientation set, we won't receive onConfigurationChanged events.
|
||||
// We thus should check here.
|
||||
int newOrientation;
|
||||
|
||||
float x, y;
|
||||
switch (mDisplay.getRotation()) {
|
||||
case Surface.ROTATION_90:
|
||||
x = -event.values[1];
|
||||
y = event.values[0];
|
||||
newOrientation = SDLActivity.SDL_ORIENTATION_LANDSCAPE;
|
||||
break;
|
||||
case Surface.ROTATION_270:
|
||||
x = event.values[1];
|
||||
y = -event.values[0];
|
||||
newOrientation = SDLActivity.SDL_ORIENTATION_LANDSCAPE_FLIPPED;
|
||||
break;
|
||||
case Surface.ROTATION_180:
|
||||
x = -event.values[0];
|
||||
y = -event.values[1];
|
||||
newOrientation = SDLActivity.SDL_ORIENTATION_PORTRAIT_FLIPPED;
|
||||
break;
|
||||
case Surface.ROTATION_0:
|
||||
default:
|
||||
x = event.values[0];
|
||||
y = event.values[1];
|
||||
newOrientation = SDLActivity.SDL_ORIENTATION_PORTRAIT;
|
||||
break;
|
||||
}
|
||||
|
||||
if (newOrientation != SDLActivity.mCurrentOrientation) {
|
||||
SDLActivity.mCurrentOrientation = newOrientation;
|
||||
SDLActivity.onNativeOrientationChanged(newOrientation);
|
||||
}
|
||||
|
||||
SDLActivity.onNativeAccel(-x / SensorManager.GRAVITY_EARTH,
|
||||
y / SensorManager.GRAVITY_EARTH,
|
||||
event.values[2] / SensorManager.GRAVITY_EARTH);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// Captured pointer events for API 26.
|
||||
public boolean onCapturedPointerEvent(MotionEvent event)
|
||||
{
|
||||
int action = event.getActionMasked();
|
||||
|
||||
float x, y;
|
||||
switch (action) {
|
||||
case MotionEvent.ACTION_SCROLL:
|
||||
x = event.getAxisValue(MotionEvent.AXIS_HSCROLL, 0);
|
||||
y = event.getAxisValue(MotionEvent.AXIS_VSCROLL, 0);
|
||||
SDLActivity.onNativeMouse(0, action, x, y, false);
|
||||
return true;
|
||||
|
||||
case MotionEvent.ACTION_HOVER_MOVE:
|
||||
case MotionEvent.ACTION_MOVE:
|
||||
x = event.getX(0);
|
||||
y = event.getY(0);
|
||||
SDLActivity.onNativeMouse(0, action, x, y, true);
|
||||
return true;
|
||||
|
||||
case MotionEvent.ACTION_BUTTON_PRESS:
|
||||
case MotionEvent.ACTION_BUTTON_RELEASE:
|
||||
|
||||
// Change our action value to what SDL's code expects.
|
||||
if (action == MotionEvent.ACTION_BUTTON_PRESS) {
|
||||
action = MotionEvent.ACTION_DOWN;
|
||||
} else { /* MotionEvent.ACTION_BUTTON_RELEASE */
|
||||
action = MotionEvent.ACTION_UP;
|
||||
}
|
||||
|
||||
x = event.getX(0);
|
||||
y = event.getY(0);
|
||||
int button = event.getButtonState();
|
||||
|
||||
SDLActivity.onNativeMouse(button, action, x, y, true);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
Vendored
+89
-89
@@ -1,89 +1,89 @@
|
||||
@rem
|
||||
@rem Copyright 2015 the original author or authors.
|
||||
@rem
|
||||
@rem Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@rem you may not use this file except in compliance with the License.
|
||||
@rem You may obtain a copy of the License at
|
||||
@rem
|
||||
@rem https://www.apache.org/licenses/LICENSE-2.0
|
||||
@rem
|
||||
@rem Unless required by applicable law or agreed to in writing, software
|
||||
@rem distributed under the License is distributed on an "AS IS" BASIS,
|
||||
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@rem See the License for the specific language governing permissions and
|
||||
@rem limitations under the License.
|
||||
@rem
|
||||
|
||||
@if "%DEBUG%" == "" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Gradle startup script for Windows
|
||||
@rem
|
||||
@rem ##########################################################################
|
||||
|
||||
@rem Set local scope for the variables with windows NT shell
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%" == "" set DIRNAME=.
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
|
||||
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
|
||||
|
||||
@rem Find java.exe
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if "%ERRORLEVEL%" == "0" goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:findJavaFromJavaHome
|
||||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||
exit /b 1
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
||||
:omega
|
||||
@rem
|
||||
@rem Copyright 2015 the original author or authors.
|
||||
@rem
|
||||
@rem Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@rem you may not use this file except in compliance with the License.
|
||||
@rem You may obtain a copy of the License at
|
||||
@rem
|
||||
@rem https://www.apache.org/licenses/LICENSE-2.0
|
||||
@rem
|
||||
@rem Unless required by applicable law or agreed to in writing, software
|
||||
@rem distributed under the License is distributed on an "AS IS" BASIS,
|
||||
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@rem See the License for the specific language governing permissions and
|
||||
@rem limitations under the License.
|
||||
@rem
|
||||
|
||||
@if "%DEBUG%" == "" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Gradle startup script for Windows
|
||||
@rem
|
||||
@rem ##########################################################################
|
||||
|
||||
@rem Set local scope for the variables with windows NT shell
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%" == "" set DIRNAME=.
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
|
||||
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
|
||||
|
||||
@rem Find java.exe
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if "%ERRORLEVEL%" == "0" goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:findJavaFromJavaHome
|
||||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||
exit /b 1
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
||||
:omega
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleDisplayName</key>
|
||||
<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>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>${MACOSX_BUNDLE_BUNDLE_NAME}</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<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>NSHighResolutionCapable</key>
|
||||
<string>True</string>
|
||||
<key>UIApplicationSupportsIndirectInputEvents</key>
|
||||
<true/>
|
||||
<key>UIFileSharingEnabled</key>
|
||||
<true/>
|
||||
<key>UILaunchStoryboardName</key>
|
||||
<string>LaunchScreen</string>
|
||||
<key>UIRequiresFullScreen</key>
|
||||
<true/>
|
||||
<key>UIStatusBarHidden</key>
|
||||
<true/>
|
||||
<key>UISupportedInterfaceOrientations</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
<key>UISupportedInterfaceOrientations~ipad</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
<string>UIInterfaceOrientationPortraitUpsideDown</string>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="21225" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
|
||||
<scenes>
|
||||
<!--View Controller-->
|
||||
<scene sceneID="EHf-IW-A2E">
|
||||
<objects>
|
||||
<viewController id="01J-lp-oVM" sceneMemberID="viewController">
|
||||
<view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
|
||||
<rect key="frame" x="0.0" y="0.0" width="834" height="1194"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<viewLayoutGuide key="safeArea" id="Bcu-3y-fUS"/>
|
||||
<color key="backgroundColor" white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
</view>
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
</scene>
|
||||
</scenes>
|
||||
</document>
|
||||
+255
-231
File diff suppressed because it is too large
Load Diff
@@ -4,6 +4,8 @@
|
||||
#include "combat_defs.h"
|
||||
#include "obj_types.h"
|
||||
|
||||
namespace fallout {
|
||||
|
||||
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);
|
||||
@@ -21,4 +23,6 @@ bool actionCheckPush(Object* a1, Object* a2);
|
||||
int actionPush(Object* a1, Object* a2);
|
||||
int _action_can_talk_to(Object* a1, Object* a2);
|
||||
|
||||
} // namespace fallout
|
||||
|
||||
#endif /* ACTIONS_H */
|
||||
|
||||
+262
-271
File diff suppressed because it is too large
Load Diff
+13
-9
@@ -4,11 +4,13 @@
|
||||
#include "combat_defs.h"
|
||||
#include "obj_types.h"
|
||||
|
||||
namespace fallout {
|
||||
|
||||
typedef enum AnimationRequestOptions {
|
||||
ANIMATION_REQUEST_UNRESERVED = 0x01,
|
||||
ANIMATION_REQUEST_RESERVED = 0x02,
|
||||
ANIMATION_REQUEST_NO_STAND = 0x04,
|
||||
ANIMATION_REQUEST_0x100 = 0x100,
|
||||
ANIMATION_REQUEST_PING = 0x100,
|
||||
ANIMATION_REQUEST_INSIGNIFICANT = 0x200,
|
||||
} AnimationRequestOptions;
|
||||
|
||||
@@ -98,12 +100,12 @@ typedef int(AnimationCallback)(void* a1, void* a2);
|
||||
// Signature of animation callback accepting 3 parameters.
|
||||
typedef int(AnimationCallback3)(void* a1, void* a2, void* a3);
|
||||
|
||||
typedef struct STRUCT_530014_28 {
|
||||
typedef struct StraightPathNode {
|
||||
int tile;
|
||||
int elevation;
|
||||
int x;
|
||||
int y;
|
||||
} STRUCT_530014_28;
|
||||
} StraightPathNode;
|
||||
|
||||
typedef Object* PathBuilderCallback(Object* object, int tile, int elevation);
|
||||
|
||||
@@ -140,15 +142,15 @@ int animationRegisterSetLightDistance(Object* owner, int lightDistance, int dela
|
||||
int animationRegisterToggleOutline(Object* object, bool outline, int delay);
|
||||
int animationRegisterPlaySoundEffect(Object* owner, const char* soundEffectName, int delay);
|
||||
int animationRegisterAnimateForever(Object* owner, int anim, int delay);
|
||||
int reg_anim_26(int a1, int a2);
|
||||
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, STRUCT_530014_28* pathNodes, Object** a5, int a6);
|
||||
int _make_straight_path_func(Object* a1, int from, int to, STRUCT_530014_28* a4, Object** a5, int a6, Object* (*a7)(Object*, int, int));
|
||||
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);
|
||||
void _object_animate();
|
||||
int _check_move(int* a1);
|
||||
int _dude_move(int a1);
|
||||
int _dude_run(int a1);
|
||||
int _check_move(int* actionPointsPtr);
|
||||
int _dude_move(int actionPoints);
|
||||
int _dude_run(int actionPoints);
|
||||
void _dude_fidget();
|
||||
void _dude_stand(Object* obj, int rotation, int fid);
|
||||
void _dude_standup(Object* a1);
|
||||
@@ -156,4 +158,6 @@ void animationStop();
|
||||
|
||||
int animationRegisterSetLightIntensity(Object* owner, int lightDistance, int lightIntensity, int delay);
|
||||
|
||||
} // namespace fallout
|
||||
|
||||
#endif /* ANIMATION_H */
|
||||
|
||||
+118
-101
@@ -8,12 +8,14 @@
|
||||
#include "debug.h"
|
||||
#include "draw.h"
|
||||
#include "game.h"
|
||||
#include "game_config.h"
|
||||
#include "memory.h"
|
||||
#include "object.h"
|
||||
#include "proto.h"
|
||||
#include "settings.h"
|
||||
#include "sfall_config.h"
|
||||
|
||||
namespace fallout {
|
||||
|
||||
typedef struct ArtListDescription {
|
||||
int flags;
|
||||
char name[16];
|
||||
@@ -32,8 +34,10 @@ static int artReadList(const char* path, char** out_arr, int* out_count);
|
||||
static int artCacheGetFileSizeImpl(int a1, int* out_size);
|
||||
static int artCacheReadDataImpl(int a1, int* a2, unsigned char* data);
|
||||
static void artCacheFreeImpl(void* ptr);
|
||||
static int artReadFrameData(unsigned char* data, File* stream, int count);
|
||||
static int artReadFrameData(unsigned char* data, File* stream, int count, int* paddingPtr);
|
||||
static int artReadHeader(Art* art, File* stream);
|
||||
static int artGetDataSize(Art* art);
|
||||
static int paddingForSize(int size);
|
||||
|
||||
// 0x5002D8
|
||||
static char gDefaultJumpsuitMaleFileName[] = "hmjmps";
|
||||
@@ -130,18 +134,14 @@ int artInit()
|
||||
File* stream;
|
||||
char string[200];
|
||||
|
||||
int cacheSize;
|
||||
if (!configGetInt(&gGameConfig, GAME_CONFIG_SYSTEM_KEY, GAME_CONFIG_ART_CACHE_SIZE_KEY, &cacheSize)) {
|
||||
cacheSize = 8;
|
||||
}
|
||||
|
||||
int cacheSize = settings.system.art_cache_size;
|
||||
if (!cacheInit(&gArtCache, artCacheGetFileSizeImpl, artCacheReadDataImpl, artCacheFreeImpl, cacheSize << 20)) {
|
||||
debugPrint("cache_init failed in art_init\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
char* language;
|
||||
if (configGetString(&gGameConfig, GAME_CONFIG_SYSTEM_KEY, GAME_CONFIG_LANGUAGE_KEY, &language) && compat_stricmp(language, ENGLISH) != 0) {
|
||||
const char* language = settings.system.language.c_str();
|
||||
if (compat_stricmp(language, ENGLISH) != 0) {
|
||||
strcpy(gArtLanguage, language);
|
||||
gArtLanguageInitialized = true;
|
||||
}
|
||||
@@ -149,28 +149,13 @@ int artInit()
|
||||
bool critterDbSelected = false;
|
||||
for (int objectType = 0; objectType < OBJ_TYPE_COUNT; objectType++) {
|
||||
gArtListDescriptions[objectType].flags = 0;
|
||||
sprintf(path, "%s%s%s\\%s.lst", _cd_path_base, "art\\", gArtListDescriptions[objectType].name, gArtListDescriptions[objectType].name);
|
||||
|
||||
int oldDb;
|
||||
if (objectType == OBJ_TYPE_CRITTER) {
|
||||
oldDb = _db_current();
|
||||
critterDbSelected = true;
|
||||
_db_select(_critter_db_handle);
|
||||
}
|
||||
snprintf(path, sizeof(path), "%s%s%s\\%s.lst", _cd_path_base, "art\\", gArtListDescriptions[objectType].name, gArtListDescriptions[objectType].name);
|
||||
|
||||
if (artReadList(path, &(gArtListDescriptions[objectType].fileNames), &(gArtListDescriptions[objectType].fileNamesLength)) != 0) {
|
||||
debugPrint("art_read_lst failed in art_init\n");
|
||||
if (critterDbSelected) {
|
||||
_db_select(oldDb);
|
||||
}
|
||||
cacheFree(&gArtCache);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (objectType == OBJ_TYPE_CRITTER) {
|
||||
critterDbSelected = false;
|
||||
_db_select(oldDb);
|
||||
}
|
||||
}
|
||||
|
||||
_anon_alias = (int*)internal_malloc(sizeof(*_anon_alias) * gArtListDescriptions[OBJ_TYPE_CRITTER].fileNamesLength);
|
||||
@@ -193,7 +178,7 @@ int artInit()
|
||||
gArtCritterFidShoudRunData[critterIndex] = 0;
|
||||
}
|
||||
|
||||
sprintf(path, "%s%s%s\\%s.lst", _cd_path_base, "art\\", gArtListDescriptions[OBJ_TYPE_CRITTER].name, gArtListDescriptions[OBJ_TYPE_CRITTER].name);
|
||||
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) {
|
||||
@@ -229,16 +214,16 @@ int artInit()
|
||||
|
||||
char* critterFileNames = gArtListDescriptions[OBJ_TYPE_CRITTER].fileNames;
|
||||
for (int critterIndex = 0; critterIndex < gArtListDescriptions[OBJ_TYPE_CRITTER].fileNamesLength; critterIndex++) {
|
||||
if (compat_stricmp(critterFileNames, "hmjmps") == 0) {
|
||||
if (compat_stricmp(critterFileNames, jumpsuitMaleFileName) == 0) {
|
||||
_art_vault_person_nums[DUDE_NATIVE_LOOK_JUMPSUIT][GENDER_MALE] = critterIndex;
|
||||
} else if (compat_stricmp(critterFileNames, "hfjmps") == 0) {
|
||||
} else if (compat_stricmp(critterFileNames, jumpsuitFemaleFileName) == 0) {
|
||||
_art_vault_person_nums[DUDE_NATIVE_LOOK_JUMPSUIT][GENDER_FEMALE] = critterIndex;
|
||||
}
|
||||
|
||||
if (compat_stricmp(critterFileNames, "hmwarr") == 0) {
|
||||
if (compat_stricmp(critterFileNames, tribalMaleFileName) == 0) {
|
||||
_art_vault_person_nums[DUDE_NATIVE_LOOK_TRIBAL][GENDER_MALE] = critterIndex;
|
||||
_art_vault_guy_num = critterIndex;
|
||||
} else if (compat_stricmp(critterFileNames, "hfprim") == 0) {
|
||||
} else if (compat_stricmp(critterFileNames, tribalFemaleFileName) == 0) {
|
||||
_art_vault_person_nums[DUDE_NATIVE_LOOK_TRIBAL][GENDER_FEMALE] = critterIndex;
|
||||
}
|
||||
|
||||
@@ -284,7 +269,7 @@ int artInit()
|
||||
return -1;
|
||||
}
|
||||
|
||||
sprintf(path, "%s%s%s\\%s.lst", _cd_path_base, "art\\", gArtListDescriptions[OBJ_TYPE_HEAD].name, gArtListDescriptions[OBJ_TYPE_HEAD].name);
|
||||
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) {
|
||||
@@ -655,19 +640,19 @@ char* artBuildFilePath(int fid)
|
||||
return NULL;
|
||||
}
|
||||
if (v10) {
|
||||
sprintf(_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);
|
||||
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);
|
||||
} else {
|
||||
sprintf(_art_name, "%s%s%s\\%s%c%c.frm", _cd_path_base, "art\\", gArtListDescriptions[1].name, gArtListDescriptions[1].fileNames + v8, v11, v12);
|
||||
snprintf(_art_name, sizeof(_art_name), "%s%s%s\\%s%c%c.frm", _cd_path_base, "art\\", gArtListDescriptions[1].name, gArtListDescriptions[1].fileNames + v8, v11, v12);
|
||||
}
|
||||
} else if (type == 8) {
|
||||
v9 = _head2[v4];
|
||||
if (v9 == 'f') {
|
||||
sprintf(_art_name, "%s%s%s\\%s%c%c%d.frm", _cd_path_base, "art\\", gArtListDescriptions[8].name, gArtListDescriptions[8].fileNames + v8, _head1[v4], 102, v5);
|
||||
snprintf(_art_name, sizeof(_art_name), "%s%s%s\\%s%c%c%d.frm", _cd_path_base, "art\\", gArtListDescriptions[8].name, gArtListDescriptions[8].fileNames + v8, _head1[v4], 102, v5);
|
||||
} else {
|
||||
sprintf(_art_name, "%s%s%s\\%s%c%c.frm", _cd_path_base, "art\\", gArtListDescriptions[8].name, gArtListDescriptions[8].fileNames + v8, _head1[v4], v9);
|
||||
snprintf(_art_name, sizeof(_art_name), "%s%s%s\\%s%c%c.frm", _cd_path_base, "art\\", gArtListDescriptions[8].name, gArtListDescriptions[8].fileNames + v8, _head1[v4], v9);
|
||||
}
|
||||
} else {
|
||||
sprintf(_art_name, "%s%s%s\\%s", _cd_path_base, "art\\", gArtListDescriptions[type].name, gArtListDescriptions[type].fileNames + v8);
|
||||
snprintf(_art_name, sizeof(_art_name), "%s%s%s\\%s", _cd_path_base, "art\\", gArtListDescriptions[type].name, gArtListDescriptions[type].fileNames + v8);
|
||||
}
|
||||
|
||||
return _art_name;
|
||||
@@ -850,9 +835,9 @@ ArtFrame* artGetFrame(Art* art, int frame, int rotation)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ArtFrame* frm = (ArtFrame*)((unsigned char*)art + sizeof(*art) + art->dataOffsets[rotation]);
|
||||
ArtFrame* frm = (ArtFrame*)((unsigned char*)art + sizeof(*art) + art->dataOffsets[rotation] + art->padding[rotation]);
|
||||
for (int index = 0; index < frame; index++) {
|
||||
frm = (ArtFrame*)((unsigned char*)frm + sizeof(*frm) + frm->size);
|
||||
frm = (ArtFrame*)((unsigned char*)frm + sizeof(*frm) + frm->size + paddingForSize(frm->size));
|
||||
}
|
||||
return frm;
|
||||
}
|
||||
@@ -861,12 +846,6 @@ ArtFrame* artGetFrame(Art* art, int frame, int rotation)
|
||||
bool artExists(int fid)
|
||||
{
|
||||
bool result = false;
|
||||
int oldDb = -1;
|
||||
|
||||
if (FID_TYPE(fid) == OBJ_TYPE_CRITTER) {
|
||||
oldDb = _db_current();
|
||||
_db_select(_critter_db_handle);
|
||||
}
|
||||
|
||||
char* filePath = artBuildFilePath(fid);
|
||||
if (filePath != NULL) {
|
||||
@@ -876,10 +855,6 @@ bool artExists(int fid)
|
||||
}
|
||||
}
|
||||
|
||||
if (oldDb != -1) {
|
||||
_db_select(oldDb);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -889,12 +864,6 @@ bool artExists(int fid)
|
||||
bool _art_fid_valid(int fid)
|
||||
{
|
||||
bool result = false;
|
||||
int oldDb = -1;
|
||||
|
||||
if (FID_TYPE(fid) == OBJ_TYPE_CRITTER) {
|
||||
oldDb = _db_current();
|
||||
_db_select(_critter_db_handle);
|
||||
}
|
||||
|
||||
char* filePath = artBuildFilePath(fid);
|
||||
if (filePath != NULL) {
|
||||
@@ -904,10 +873,6 @@ bool _art_fid_valid(int fid)
|
||||
}
|
||||
}
|
||||
|
||||
if (oldDb != -1) {
|
||||
_db_select(oldDb);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -954,18 +919,12 @@ int artAliasFid(int fid)
|
||||
// 0x419A78
|
||||
static int artCacheGetFileSizeImpl(int fid, int* sizePtr)
|
||||
{
|
||||
int oldDb = -1;
|
||||
int result = -1;
|
||||
|
||||
if (FID_TYPE(fid) == OBJ_TYPE_CRITTER) {
|
||||
oldDb = _db_current();
|
||||
_db_select(_critter_db_handle);
|
||||
}
|
||||
|
||||
char* artFilePath = artBuildFilePath(fid);
|
||||
if (artFilePath != NULL) {
|
||||
int fileSize;
|
||||
bool loaded = false;
|
||||
File* stream = NULL;
|
||||
|
||||
if (gArtLanguageInitialized) {
|
||||
char* pch = strchr(artFilePath, '\\');
|
||||
@@ -974,27 +933,23 @@ static int artCacheGetFileSizeImpl(int fid, int* sizePtr)
|
||||
}
|
||||
|
||||
char localizedPath[COMPAT_MAX_PATH];
|
||||
sprintf(localizedPath, "art\\%s\\%s", gArtLanguage, pch);
|
||||
snprintf(localizedPath, sizeof(localizedPath), "art\\%s\\%s", gArtLanguage, pch);
|
||||
|
||||
if (dbGetFileSize(localizedPath, &fileSize) == 0) {
|
||||
loaded = true;
|
||||
stream = fileOpen(localizedPath, "rb");
|
||||
}
|
||||
|
||||
if (stream == NULL) {
|
||||
stream = fileOpen(artFilePath, "rb");
|
||||
}
|
||||
|
||||
if (stream != NULL) {
|
||||
Art art;
|
||||
if (artReadHeader(&art, stream) == 0) {
|
||||
*sizePtr = artGetDataSize(&art);
|
||||
result = 0;
|
||||
}
|
||||
fileClose(stream);
|
||||
}
|
||||
|
||||
if (!loaded) {
|
||||
if (dbGetFileSize(artFilePath, &fileSize) == 0) {
|
||||
loaded = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (loaded) {
|
||||
*sizePtr = fileSize;
|
||||
result = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (oldDb != -1) {
|
||||
_db_select(oldDb);
|
||||
}
|
||||
|
||||
return result;
|
||||
@@ -1003,14 +958,8 @@ static int artCacheGetFileSizeImpl(int fid, int* sizePtr)
|
||||
// 0x419B78
|
||||
static int artCacheReadDataImpl(int fid, int* sizePtr, unsigned char* data)
|
||||
{
|
||||
int oldDb = -1;
|
||||
int result = -1;
|
||||
|
||||
if (FID_TYPE(fid) == OBJ_TYPE_CRITTER) {
|
||||
oldDb = _db_current();
|
||||
_db_select(_critter_db_handle);
|
||||
}
|
||||
|
||||
char* artFileName = artBuildFilePath(fid);
|
||||
if (artFileName != NULL) {
|
||||
bool loaded = false;
|
||||
@@ -1021,7 +970,7 @@ static int artCacheReadDataImpl(int fid, int* sizePtr, unsigned char* data)
|
||||
}
|
||||
|
||||
char localizedPath[COMPAT_MAX_PATH];
|
||||
sprintf(localizedPath, "art\\%s\\%s", gArtLanguage, pch);
|
||||
snprintf(localizedPath, sizeof(localizedPath), "art\\%s\\%s", gArtLanguage, pch);
|
||||
|
||||
if (artRead(localizedPath, data) == 0) {
|
||||
loaded = true;
|
||||
@@ -1035,16 +984,11 @@ static int artCacheReadDataImpl(int fid, int* sizePtr, unsigned char* data)
|
||||
}
|
||||
|
||||
if (loaded) {
|
||||
// TODO: Why it adds 74?
|
||||
*sizePtr = ((Art*)data)->field_3A + 74;
|
||||
*sizePtr = artGetDataSize((Art*)data);
|
||||
result = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (oldDb != -1) {
|
||||
_db_select(oldDb);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -1096,9 +1040,10 @@ out:
|
||||
}
|
||||
|
||||
// 0x419D60
|
||||
static int artReadFrameData(unsigned char* data, File* stream, int count)
|
||||
static int artReadFrameData(unsigned char* data, File* stream, int count, int* paddingPtr)
|
||||
{
|
||||
unsigned char* ptr = data;
|
||||
int padding = 0;
|
||||
for (int index = 0; index < count; index++) {
|
||||
ArtFrame* frame = (ArtFrame*)ptr;
|
||||
|
||||
@@ -1110,8 +1055,12 @@ static int artReadFrameData(unsigned char* data, File* stream, int count)
|
||||
if (fileRead(ptr + sizeof(ArtFrame), frame->size, 1, stream) != 1) return -1;
|
||||
|
||||
ptr += sizeof(ArtFrame) + frame->size;
|
||||
ptr += paddingForSize(frame->size);
|
||||
padding += paddingForSize(frame->size);
|
||||
}
|
||||
|
||||
*paddingPtr = padding;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1125,7 +1074,7 @@ static int artReadHeader(Art* art, File* stream)
|
||||
if (fileReadInt16List(stream, art->xOffsets, ROTATION_COUNT) == -1) return -1;
|
||||
if (fileReadInt16List(stream, art->yOffsets, ROTATION_COUNT) == -1) return -1;
|
||||
if (fileReadInt32List(stream, art->dataOffsets, ROTATION_COUNT) == -1) return -1;
|
||||
if (fileReadInt32(stream, &(art->field_3A)) == -1) return -1;
|
||||
if (fileReadInt32(stream, &(art->dataSize)) == -1) return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1144,9 +1093,16 @@ int artRead(const char* path, unsigned char* data)
|
||||
return -3;
|
||||
}
|
||||
|
||||
int currentPadding = paddingForSize(sizeof(Art));
|
||||
int previousPadding = 0;
|
||||
|
||||
for (int index = 0; index < ROTATION_COUNT; index++) {
|
||||
art->padding[index] = currentPadding;
|
||||
|
||||
if (index == 0 || art->dataOffsets[index - 1] != art->dataOffsets[index]) {
|
||||
if (artReadFrameData(data + sizeof(Art) + art->dataOffsets[index], stream, art->frameCount) != 0) {
|
||||
art->padding[index] += previousPadding;
|
||||
currentPadding += previousPadding;
|
||||
if (artReadFrameData(data + sizeof(Art) + art->dataOffsets[index] + art->padding[index], stream, art->frameCount, &previousPadding) != 0) {
|
||||
fileClose(stream);
|
||||
return -5;
|
||||
}
|
||||
@@ -1174,6 +1130,7 @@ int artWriteFrameData(unsigned char* data, File* stream, int count)
|
||||
if (fileWrite(ptr + sizeof(ArtFrame), frame->size, 1, stream) != 1) return -1;
|
||||
|
||||
ptr += sizeof(ArtFrame) + frame->size;
|
||||
ptr += paddingForSize(frame->size);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -1191,7 +1148,7 @@ int artWriteHeader(Art* art, File* stream)
|
||||
if (fileWriteInt16List(stream, art->xOffsets, ROTATION_COUNT) == -1) return -1;
|
||||
if (fileWriteInt16List(stream, art->yOffsets, ROTATION_COUNT) == -1) return -1;
|
||||
if (fileWriteInt32List(stream, art->dataOffsets, ROTATION_COUNT) == -1) return -1;
|
||||
if (fileWriteInt32(stream, art->field_3A) == -1) return -1;
|
||||
if (fileWriteInt32(stream, art->dataSize) == -1) return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1218,7 +1175,7 @@ int artWrite(const char* path, unsigned char* data)
|
||||
|
||||
for (int index = 0; index < ROTATION_COUNT; index++) {
|
||||
if (index == 0 || art->dataOffsets[index - 1] != art->dataOffsets[index]) {
|
||||
if (artWriteFrameData(data + sizeof(Art) + art->dataOffsets[index], stream, art->frameCount) != 0) {
|
||||
if (artWriteFrameData(data + sizeof(Art) + art->dataOffsets[index] + art->padding[index], stream, art->frameCount) != 0) {
|
||||
fileClose(stream);
|
||||
return -1;
|
||||
}
|
||||
@@ -1228,3 +1185,63 @@ int artWrite(const char* path, unsigned char* data)
|
||||
fileClose(stream);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int artGetDataSize(Art* art)
|
||||
{
|
||||
int dataSize = sizeof(*art) + art->dataSize;
|
||||
|
||||
for (int index = 0; index < ROTATION_COUNT; index++) {
|
||||
if (index == 0 || art->dataOffsets[index - 1] != art->dataOffsets[index]) {
|
||||
// Assume worst case - every frame is unaligned and need
|
||||
// max padding.
|
||||
dataSize += (sizeof(int) - 1) * art->frameCount;
|
||||
}
|
||||
}
|
||||
|
||||
return dataSize;
|
||||
}
|
||||
|
||||
static int paddingForSize(int size)
|
||||
{
|
||||
return (sizeof(int) - size % sizeof(int)) % sizeof(int);
|
||||
}
|
||||
|
||||
FrmImage::FrmImage()
|
||||
{
|
||||
_key = nullptr;
|
||||
_data = nullptr;
|
||||
_width = 0;
|
||||
_height = 0;
|
||||
}
|
||||
|
||||
FrmImage::~FrmImage()
|
||||
{
|
||||
unlock();
|
||||
}
|
||||
|
||||
bool FrmImage::lock(unsigned int fid)
|
||||
{
|
||||
if (isLocked()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
_data = artLockFrameDataReturningSize(fid, &_key, &_width, &_height);
|
||||
if (!_data) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void FrmImage::unlock()
|
||||
{
|
||||
if (isLocked()) {
|
||||
artUnlock(_key);
|
||||
_key = nullptr;
|
||||
_data = nullptr;
|
||||
_width = 0;
|
||||
_height = 0;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace fallout
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
#include "platform_compat.h"
|
||||
#include "proto_types.h"
|
||||
|
||||
namespace fallout {
|
||||
|
||||
typedef enum Head {
|
||||
HEAD_INVALID,
|
||||
HEAD_MARCUS,
|
||||
@@ -65,7 +67,6 @@ typedef enum Background {
|
||||
BACKGROUND_COUNT,
|
||||
} Background;
|
||||
|
||||
#pragma pack(2)
|
||||
typedef struct Art {
|
||||
int field_0;
|
||||
short framesPerSecond;
|
||||
@@ -74,9 +75,9 @@ typedef struct Art {
|
||||
short xOffsets[6];
|
||||
short yOffsets[6];
|
||||
int dataOffsets[6];
|
||||
int field_3A;
|
||||
int padding[6];
|
||||
int dataSize;
|
||||
} Art;
|
||||
#pragma pack()
|
||||
|
||||
typedef struct ArtFrame {
|
||||
short width;
|
||||
@@ -149,4 +150,26 @@ int buildFid(int objectType, int frmId, int animType, int a4, int rotation);
|
||||
int artRead(const char* path, unsigned char* data);
|
||||
int artWrite(const char* path, unsigned char* data);
|
||||
|
||||
class FrmImage {
|
||||
public:
|
||||
FrmImage();
|
||||
~FrmImage();
|
||||
|
||||
bool isLocked() const { return _key != nullptr; }
|
||||
bool lock(unsigned int fid);
|
||||
void unlock();
|
||||
|
||||
int getWidth() const { return _width; }
|
||||
int getHeight() const { return _height; }
|
||||
unsigned char* getData() const { return _data; }
|
||||
|
||||
private:
|
||||
CacheEntry* _key;
|
||||
unsigned char* _data;
|
||||
int _width;
|
||||
int _height;
|
||||
};
|
||||
|
||||
} // namespace fallout
|
||||
|
||||
#endif
|
||||
|
||||
+62
-42
@@ -9,34 +9,52 @@
|
||||
#include "memory_manager.h"
|
||||
#include "pointer_registry.h"
|
||||
#include "sound.h"
|
||||
#include "sound_decoder.h"
|
||||
|
||||
static bool _defaultCompressionFunc(char* filePath);
|
||||
namespace fallout {
|
||||
|
||||
typedef enum AudioFlags {
|
||||
AUDIO_IN_USE = 0x01,
|
||||
AUDIO_COMPRESSED = 0x02,
|
||||
} AudioFileFlags;
|
||||
|
||||
typedef struct Audio {
|
||||
int flags;
|
||||
int stream;
|
||||
SoundDecoder* soundDecoder;
|
||||
int fileSize;
|
||||
int sampleRate;
|
||||
int channels;
|
||||
int position;
|
||||
} Audio;
|
||||
|
||||
static bool defaultCompressionFunc(char* filePath);
|
||||
static int audioSoundDecoderReadHandler(int fileHandle, void* buf, unsigned int size);
|
||||
|
||||
// 0x5108BC
|
||||
static AudioFileIsCompressedProc* _queryCompressedFunc = _defaultCompressionFunc;
|
||||
static AudioQueryCompressedFunc* queryCompressedFunc = defaultCompressionFunc;
|
||||
|
||||
// 0x56CB00
|
||||
static int gAudioListLength;
|
||||
|
||||
// 0x56CB04
|
||||
static AudioFile* gAudioList;
|
||||
static Audio* gAudioList;
|
||||
|
||||
// 0x41A2B0
|
||||
static bool _defaultCompressionFunc(char* filePath)
|
||||
static bool defaultCompressionFunc(char* filePath)
|
||||
{
|
||||
char* pch = strrchr(filePath, '.');
|
||||
if (pch != NULL) {
|
||||
strcpy(pch + 1, "war");
|
||||
strcpy(pch + 1, "raw");
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// 0x41A2D0
|
||||
static int audioSoundDecoderReadHandler(int fileHandle, void* buffer, unsigned int size)
|
||||
static int audioSoundDecoderReadHandler(int handle, void* buffer, unsigned int size)
|
||||
{
|
||||
return fileRead(buffer, 1, size, (File*)intToPtr(fileHandle));
|
||||
return fileRead(buffer, 1, size, (File*)intToPtr(handle));
|
||||
}
|
||||
|
||||
// AudioOpen
|
||||
@@ -44,10 +62,10 @@ static int audioSoundDecoderReadHandler(int fileHandle, void* buffer, unsigned i
|
||||
int audioOpen(const char* fname, int flags, ...)
|
||||
{
|
||||
char path[80];
|
||||
sprintf(path, "%s", fname);
|
||||
snprintf(path, sizeof(path), "%s", fname);
|
||||
|
||||
int compression;
|
||||
if (_queryCompressedFunc(path)) {
|
||||
if (queryCompressedFunc(path)) {
|
||||
compression = 2;
|
||||
} else {
|
||||
compression = 0;
|
||||
@@ -82,27 +100,27 @@ int audioOpen(const char* fname, int flags, ...)
|
||||
|
||||
int index;
|
||||
for (index = 0; index < gAudioListLength; index++) {
|
||||
if ((gAudioList[index].flags & AUDIO_FILE_IN_USE) == 0) {
|
||||
if ((gAudioList[index].flags & AUDIO_IN_USE) == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (index == gAudioListLength) {
|
||||
if (gAudioList != NULL) {
|
||||
gAudioList = (AudioFile*)internal_realloc_safe(gAudioList, sizeof(*gAudioList) * (gAudioListLength + 1), __FILE__, __LINE__); // "..\int\audio.c", 216
|
||||
gAudioList = (Audio*)internal_realloc_safe(gAudioList, sizeof(*gAudioList) * (gAudioListLength + 1), __FILE__, __LINE__); // "..\int\audio.c", 216
|
||||
} else {
|
||||
gAudioList = (AudioFile*)internal_malloc_safe(sizeof(*gAudioList), __FILE__, __LINE__); // "..\int\audio.c", 218
|
||||
gAudioList = (Audio*)internal_malloc_safe(sizeof(*gAudioList), __FILE__, __LINE__); // "..\int\audio.c", 218
|
||||
}
|
||||
gAudioListLength++;
|
||||
}
|
||||
|
||||
AudioFile* audioFile = &(gAudioList[index]);
|
||||
audioFile->flags = AUDIO_FILE_IN_USE;
|
||||
audioFile->fileHandle = ptrToInt(stream);
|
||||
Audio* audioFile = &(gAudioList[index]);
|
||||
audioFile->flags = AUDIO_IN_USE;
|
||||
audioFile->stream = ptrToInt(stream);
|
||||
|
||||
if (compression == 2) {
|
||||
audioFile->flags |= AUDIO_FILE_COMPRESSED;
|
||||
audioFile->soundDecoder = soundDecoderInit(audioSoundDecoderReadHandler, audioFile->fileHandle, &(audioFile->field_14), &(audioFile->field_10), &(audioFile->fileSize));
|
||||
audioFile->flags |= AUDIO_COMPRESSED;
|
||||
audioFile->soundDecoder = soundDecoderInit(audioSoundDecoderReadHandler, audioFile->stream, &(audioFile->channels), &(audioFile->sampleRate), &(audioFile->fileSize));
|
||||
audioFile->fileSize *= 2;
|
||||
} else {
|
||||
audioFile->fileSize = fileGetSize(stream);
|
||||
@@ -114,30 +132,30 @@ int audioOpen(const char* fname, int flags, ...)
|
||||
}
|
||||
|
||||
// 0x41A50C
|
||||
int audioClose(int fileHandle)
|
||||
int audioClose(int handle)
|
||||
{
|
||||
AudioFile* audioFile = &(gAudioList[fileHandle - 1]);
|
||||
fileClose((File*)intToPtr(audioFile->fileHandle, true));
|
||||
Audio* audioFile = &(gAudioList[handle - 1]);
|
||||
fileClose((File*)intToPtr(audioFile->stream, true));
|
||||
|
||||
if ((audioFile->flags & AUDIO_FILE_COMPRESSED) != 0) {
|
||||
if ((audioFile->flags & AUDIO_COMPRESSED) != 0) {
|
||||
soundDecoderFree(audioFile->soundDecoder);
|
||||
}
|
||||
|
||||
memset(audioFile, 0, sizeof(AudioFile));
|
||||
memset(audioFile, 0, sizeof(Audio));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 0x41A574
|
||||
int audioRead(int fileHandle, void* buffer, unsigned int size)
|
||||
int audioRead(int handle, void* buffer, unsigned int size)
|
||||
{
|
||||
AudioFile* audioFile = &(gAudioList[fileHandle - 1]);
|
||||
Audio* audioFile = &(gAudioList[handle - 1]);
|
||||
|
||||
int bytesRead;
|
||||
if ((audioFile->flags & AUDIO_FILE_COMPRESSED) != 0) {
|
||||
if ((audioFile->flags & AUDIO_COMPRESSED) != 0) {
|
||||
bytesRead = soundDecoderDecode(audioFile->soundDecoder, buffer, size);
|
||||
} else {
|
||||
bytesRead = fileRead(buffer, 1, size, (File*)intToPtr(audioFile->fileHandle));
|
||||
bytesRead = fileRead(buffer, 1, size, (File*)intToPtr(audioFile->stream));
|
||||
}
|
||||
|
||||
audioFile->position += bytesRead;
|
||||
@@ -146,13 +164,13 @@ int audioRead(int fileHandle, void* buffer, unsigned int size)
|
||||
}
|
||||
|
||||
// 0x41A5E0
|
||||
long audioSeek(int fileHandle, long offset, int origin)
|
||||
long audioSeek(int handle, long offset, int origin)
|
||||
{
|
||||
int pos;
|
||||
unsigned char* buf;
|
||||
int v10;
|
||||
|
||||
AudioFile* audioFile = &(gAudioList[fileHandle - 1]);
|
||||
Audio* audioFile = &(gAudioList[handle - 1]);
|
||||
|
||||
switch (origin) {
|
||||
case SEEK_SET:
|
||||
@@ -168,11 +186,11 @@ long audioSeek(int fileHandle, long offset, int origin)
|
||||
assert(false && "Should be unreachable");
|
||||
}
|
||||
|
||||
if ((audioFile->flags & AUDIO_FILE_COMPRESSED) != 0) {
|
||||
if ((audioFile->flags & AUDIO_COMPRESSED) != 0) {
|
||||
if (pos < audioFile->position) {
|
||||
soundDecoderFree(audioFile->soundDecoder);
|
||||
fileSeek((File*)intToPtr(audioFile->fileHandle), 0, SEEK_SET);
|
||||
audioFile->soundDecoder = soundDecoderInit(audioSoundDecoderReadHandler, audioFile->fileHandle, &(audioFile->field_14), &(audioFile->field_10), &(audioFile->fileSize));
|
||||
fileSeek((File*)intToPtr(audioFile->stream), 0, SEEK_SET);
|
||||
audioFile->soundDecoder = soundDecoderInit(audioSoundDecoderReadHandler, audioFile->stream, &(audioFile->channels), &(audioFile->sampleRate), &(audioFile->fileSize));
|
||||
audioFile->position = 0;
|
||||
audioFile->fileSize *= 2;
|
||||
|
||||
@@ -180,11 +198,11 @@ long audioSeek(int fileHandle, long offset, int origin)
|
||||
buf = (unsigned char*)internal_malloc_safe(4096, __FILE__, __LINE__); // "..\int\audio.c", 361
|
||||
while (pos > 4096) {
|
||||
pos -= 4096;
|
||||
audioRead(fileHandle, buf, 4096);
|
||||
audioRead(handle, buf, 4096);
|
||||
}
|
||||
|
||||
if (pos != 0) {
|
||||
audioRead(fileHandle, buf, pos);
|
||||
audioRead(handle, buf, pos);
|
||||
}
|
||||
|
||||
internal_free_safe(buf, __FILE__, __LINE__); // // "..\int\audio.c", 367
|
||||
@@ -194,11 +212,11 @@ long audioSeek(int fileHandle, long offset, int origin)
|
||||
v10 = audioFile->position - pos;
|
||||
while (v10 > 1024) {
|
||||
v10 -= 1024;
|
||||
audioRead(fileHandle, buf, 1024);
|
||||
audioRead(handle, buf, 1024);
|
||||
}
|
||||
|
||||
if (v10 != 0) {
|
||||
audioRead(fileHandle, buf, v10);
|
||||
audioRead(handle, buf, v10);
|
||||
}
|
||||
|
||||
// TODO: Probably leaks memory.
|
||||
@@ -206,21 +224,21 @@ long audioSeek(int fileHandle, long offset, int origin)
|
||||
|
||||
return audioFile->position;
|
||||
} else {
|
||||
return fileSeek((File*)intToPtr(audioFile->fileHandle), offset, origin);
|
||||
return fileSeek((File*)intToPtr(audioFile->stream), offset, origin);
|
||||
}
|
||||
}
|
||||
|
||||
// 0x41A78C
|
||||
long audioGetSize(int fileHandle)
|
||||
long audioGetSize(int handle)
|
||||
{
|
||||
AudioFile* audioFile = &(gAudioList[fileHandle - 1]);
|
||||
Audio* audioFile = &(gAudioList[handle - 1]);
|
||||
return audioFile->fileSize;
|
||||
}
|
||||
|
||||
// 0x41A7A8
|
||||
long audioTell(int fileHandle)
|
||||
long audioTell(int handle)
|
||||
{
|
||||
AudioFile* audioFile = &(gAudioList[fileHandle - 1]);
|
||||
Audio* audioFile = &(gAudioList[handle - 1]);
|
||||
return audioFile->position;
|
||||
}
|
||||
|
||||
@@ -233,9 +251,9 @@ int audioWrite(int handle, const void* buf, unsigned int size)
|
||||
}
|
||||
|
||||
// 0x41A7D4
|
||||
int audioInit(AudioFileIsCompressedProc* isCompressedProc)
|
||||
int audioInit(AudioQueryCompressedFunc* func)
|
||||
{
|
||||
_queryCompressedFunc = isCompressedProc;
|
||||
queryCompressedFunc = func;
|
||||
gAudioList = NULL;
|
||||
gAudioListLength = 0;
|
||||
|
||||
@@ -252,3 +270,5 @@ void audioExit()
|
||||
gAudioListLength = 0;
|
||||
gAudioList = NULL;
|
||||
}
|
||||
|
||||
} // namespace fallout
|
||||
|
||||
+11
-7
@@ -1,16 +1,20 @@
|
||||
#ifndef AUDIO_H
|
||||
#define AUDIO_H
|
||||
|
||||
#include "audio_file.h"
|
||||
namespace fallout {
|
||||
|
||||
typedef bool(AudioQueryCompressedFunc)(char* filePath);
|
||||
|
||||
int audioOpen(const char* fname, int mode, ...);
|
||||
int audioClose(int fileHandle);
|
||||
int audioRead(int fileHandle, void* buffer, unsigned int size);
|
||||
long audioSeek(int fileHandle, long offset, int origin);
|
||||
long audioGetSize(int fileHandle);
|
||||
long audioTell(int fileHandle);
|
||||
int audioClose(int handle);
|
||||
int audioRead(int handle, void* buffer, unsigned int size);
|
||||
long audioSeek(int handle, long offset, int origin);
|
||||
long audioGetSize(int handle);
|
||||
long audioTell(int handle);
|
||||
int audioWrite(int handle, const void* buf, unsigned int size);
|
||||
int audioInit(AudioFileIsCompressedProc* isCompressedProc);
|
||||
int audioInit(AudioQueryCompressedFunc* func);
|
||||
void audioExit();
|
||||
|
||||
} // namespace fallout
|
||||
|
||||
#endif /* AUDIO_H */
|
||||
|
||||
+63
-4
@@ -6,6 +6,8 @@
|
||||
|
||||
#include <SDL.h>
|
||||
|
||||
namespace fallout {
|
||||
|
||||
#define AUDIO_ENGINE_SOUND_BUFFERS 8
|
||||
|
||||
struct AudioEngineSoundBuffer {
|
||||
@@ -32,6 +34,11 @@ static SDL_AudioSpec gAudioEngineSpec;
|
||||
static SDL_AudioDeviceID gAudioEngineDeviceId = -1;
|
||||
static AudioEngineSoundBuffer gAudioEngineSoundBuffers[AUDIO_ENGINE_SOUND_BUFFERS];
|
||||
|
||||
static bool audioEngineIsInitialized()
|
||||
{
|
||||
return gAudioEngineDeviceId != -1;
|
||||
}
|
||||
|
||||
static bool soundBufferIsValid(int soundBufferIndex)
|
||||
{
|
||||
return soundBufferIndex >= 0 && soundBufferIndex < AUDIO_ENGINE_SOUND_BUFFERS;
|
||||
@@ -111,30 +118,36 @@ bool audioEngineInit()
|
||||
|
||||
void audioEngineExit()
|
||||
{
|
||||
if (gAudioEngineDeviceId != -1) {
|
||||
if (audioEngineIsInitialized()) {
|
||||
SDL_CloseAudioDevice(gAudioEngineDeviceId);
|
||||
gAudioEngineDeviceId = -1;
|
||||
}
|
||||
|
||||
SDL_QuitSubSystem(SDL_INIT_AUDIO);
|
||||
if (SDL_WasInit(SDL_INIT_AUDIO)) {
|
||||
SDL_QuitSubSystem(SDL_INIT_AUDIO);
|
||||
}
|
||||
}
|
||||
|
||||
void audioEnginePause()
|
||||
{
|
||||
if (gAudioEngineDeviceId != -1) {
|
||||
if (audioEngineIsInitialized()) {
|
||||
SDL_PauseAudioDevice(gAudioEngineDeviceId, 1);
|
||||
}
|
||||
}
|
||||
|
||||
void audioEngineResume()
|
||||
{
|
||||
if (gAudioEngineDeviceId != -1) {
|
||||
if (audioEngineIsInitialized()) {
|
||||
SDL_PauseAudioDevice(gAudioEngineDeviceId, 0);
|
||||
}
|
||||
}
|
||||
|
||||
int audioEngineCreateSoundBuffer(unsigned int size, int bitsPerSample, int channels, int rate)
|
||||
{
|
||||
if (!audioEngineIsInitialized()) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (int index = 0; index < AUDIO_ENGINE_SOUND_BUFFERS; index++) {
|
||||
AudioEngineSoundBuffer* soundBuffer = &(gAudioEngineSoundBuffers[index]);
|
||||
std::lock_guard<std::recursive_mutex> lock(soundBuffer->mutex);
|
||||
@@ -160,6 +173,10 @@ int audioEngineCreateSoundBuffer(unsigned int size, int bitsPerSample, int chann
|
||||
|
||||
bool audioEngineSoundBufferRelease(int soundBufferIndex)
|
||||
{
|
||||
if (!audioEngineIsInitialized()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!soundBufferIsValid(soundBufferIndex)) {
|
||||
return false;
|
||||
}
|
||||
@@ -184,6 +201,10 @@ bool audioEngineSoundBufferRelease(int soundBufferIndex)
|
||||
|
||||
bool audioEngineSoundBufferSetVolume(int soundBufferIndex, int volume)
|
||||
{
|
||||
if (!audioEngineIsInitialized()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!soundBufferIsValid(soundBufferIndex)) {
|
||||
return false;
|
||||
}
|
||||
@@ -202,6 +223,10 @@ bool audioEngineSoundBufferSetVolume(int soundBufferIndex, int volume)
|
||||
|
||||
bool audioEngineSoundBufferGetVolume(int soundBufferIndex, int* volumePtr)
|
||||
{
|
||||
if (!audioEngineIsInitialized()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!soundBufferIsValid(soundBufferIndex)) {
|
||||
return false;
|
||||
}
|
||||
@@ -220,6 +245,10 @@ bool audioEngineSoundBufferGetVolume(int soundBufferIndex, int* volumePtr)
|
||||
|
||||
bool audioEngineSoundBufferSetPan(int soundBufferIndex, int pan)
|
||||
{
|
||||
if (!audioEngineIsInitialized()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!soundBufferIsValid(soundBufferIndex)) {
|
||||
return false;
|
||||
}
|
||||
@@ -239,6 +268,10 @@ bool audioEngineSoundBufferSetPan(int soundBufferIndex, int pan)
|
||||
|
||||
bool audioEngineSoundBufferPlay(int soundBufferIndex, unsigned int flags)
|
||||
{
|
||||
if (!audioEngineIsInitialized()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!soundBufferIsValid(soundBufferIndex)) {
|
||||
return false;
|
||||
}
|
||||
@@ -261,6 +294,10 @@ bool audioEngineSoundBufferPlay(int soundBufferIndex, unsigned int flags)
|
||||
|
||||
bool audioEngineSoundBufferStop(int soundBufferIndex)
|
||||
{
|
||||
if (!audioEngineIsInitialized()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!soundBufferIsValid(soundBufferIndex)) {
|
||||
return false;
|
||||
}
|
||||
@@ -279,6 +316,10 @@ bool audioEngineSoundBufferStop(int soundBufferIndex)
|
||||
|
||||
bool audioEngineSoundBufferGetCurrentPosition(int soundBufferIndex, unsigned int* readPosPtr, unsigned int* writePosPtr)
|
||||
{
|
||||
if (!audioEngineIsInitialized()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!soundBufferIsValid(soundBufferIndex)) {
|
||||
return false;
|
||||
}
|
||||
@@ -310,6 +351,10 @@ bool audioEngineSoundBufferGetCurrentPosition(int soundBufferIndex, unsigned int
|
||||
|
||||
bool audioEngineSoundBufferSetCurrentPosition(int soundBufferIndex, unsigned int pos)
|
||||
{
|
||||
if (!audioEngineIsInitialized()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!soundBufferIsValid(soundBufferIndex)) {
|
||||
return false;
|
||||
}
|
||||
@@ -328,6 +373,10 @@ bool audioEngineSoundBufferSetCurrentPosition(int soundBufferIndex, unsigned int
|
||||
|
||||
bool audioEngineSoundBufferLock(int soundBufferIndex, unsigned int writePos, unsigned int writeBytes, void** audioPtr1, unsigned int* audioBytes1, void** audioPtr2, unsigned int* audioBytes2, unsigned int flags)
|
||||
{
|
||||
if (!audioEngineIsInitialized()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!soundBufferIsValid(soundBufferIndex)) {
|
||||
return false;
|
||||
}
|
||||
@@ -385,6 +434,10 @@ bool audioEngineSoundBufferLock(int soundBufferIndex, unsigned int writePos, uns
|
||||
|
||||
bool audioEngineSoundBufferUnlock(int soundBufferIndex, void* audioPtr1, unsigned int audioBytes1, void* audioPtr2, unsigned int audioBytes2)
|
||||
{
|
||||
if (!audioEngineIsInitialized()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!soundBufferIsValid(soundBufferIndex)) {
|
||||
return false;
|
||||
}
|
||||
@@ -403,6 +456,10 @@ bool audioEngineSoundBufferUnlock(int soundBufferIndex, void* audioPtr1, unsigne
|
||||
|
||||
bool audioEngineSoundBufferGetStatus(int soundBufferIndex, unsigned int* statusPtr)
|
||||
{
|
||||
if (!audioEngineIsInitialized()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!soundBufferIsValid(soundBufferIndex)) {
|
||||
return false;
|
||||
}
|
||||
@@ -430,3 +487,5 @@ bool audioEngineSoundBufferGetStatus(int soundBufferIndex, unsigned int* statusP
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace fallout
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user