forked from Ports/perfect_dark
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
be0293f555 | ||
|
|
54d35b47a0 | ||
|
|
04a518840f | ||
|
|
68df5343ba | ||
|
|
aead1bc4c4 | ||
|
|
b86cc88991 | ||
|
|
d946e332ae | ||
|
|
57041735cb | ||
|
|
f3ce20fb6e | ||
|
|
75d1886da1 | ||
|
|
a582068c21 | ||
|
|
4c1e9ece94 | ||
|
|
a9ccc61f96 | ||
|
|
110876b036 | ||
|
|
ae7b21cf56 | ||
|
|
e8a57d7f6f | ||
|
|
2362444efd | ||
|
|
f5251fa1b9 | ||
|
|
da4e5e4832 | ||
|
|
5ebce756ed | ||
|
|
839ef7cc44 | ||
|
|
c597915466 | ||
|
|
5db911a58b | ||
|
|
5425c21c83 | ||
|
|
abe04c0dda | ||
|
|
7721297dc8 | ||
|
|
44c5a4c213 | ||
|
|
7677b40b06 | ||
|
|
f948fc06f2 | ||
|
|
26c24d62aa | ||
|
|
9a484c1aea | ||
|
|
3f45d41de6 | ||
|
|
6ddebf8aa6 | ||
|
|
6d20ed25fb | ||
|
|
112f6da972 | ||
|
|
80cd44d8e2 | ||
|
|
3ff2f9e0ec | ||
|
|
8b8eedcdfc | ||
|
|
1398f5d0f5 | ||
|
|
4d96fab71f | ||
|
|
796241d443 | ||
|
|
3455708e38 | ||
|
|
ae0ba57c24 | ||
|
|
f7435e0ead | ||
|
|
fceacee0e2 | ||
|
|
a5a2970b67 | ||
|
|
0d6a5f2d0f | ||
|
|
c5ab7d20df | ||
|
|
d53dd8c48f | ||
|
|
edced1d0e2 | ||
|
|
7cc389bc69 | ||
|
|
5e03342562 | ||
|
|
30e987eb50 | ||
|
|
e5f142b110 | ||
|
|
95bf97a2c1 | ||
|
|
f52fa8f759 | ||
|
|
ff4321673b | ||
|
|
7590f0bdc3 | ||
|
|
70882d8a32 | ||
|
|
045d5d2e46 | ||
|
|
7fabc68e95 | ||
|
|
948a3e0c51 | ||
|
|
7ffc1d393b | ||
|
|
aba98349ae | ||
|
|
9625cd7d28 | ||
|
|
0e2de3b746 | ||
|
|
32417c164c | ||
|
|
1db33f278b | ||
|
|
abc6612641 | ||
|
|
57b1e37397 | ||
|
|
3f3c091289 | ||
|
|
41ddcc7822 | ||
|
|
6708bf2aa6 | ||
|
|
c16aa70a66 | ||
|
|
60c30e9b67 | ||
|
|
bc01ff558f | ||
|
|
8c844874e7 | ||
|
|
2e18ffdad9 | ||
|
|
b2ea9aa5f2 | ||
|
|
b9a51e4a62 | ||
|
|
b72d7f54e1 | ||
|
|
d8b21f78e0 | ||
|
|
0d0de5b0d4 | ||
|
|
7667d37ff0 | ||
|
|
cf7c4d4239 | ||
|
|
adcf56ed34 | ||
|
|
5e65e84210 | ||
|
|
63a9a26908 | ||
|
|
f4530633d6 | ||
|
|
94e244a236 | ||
|
|
92d3a9f564 | ||
|
|
44a67e60e8 | ||
|
|
634eecb35d | ||
|
|
a0db91a0c9 | ||
|
|
6b105d0be0 | ||
|
|
11febd7ace | ||
|
|
dface4696c | ||
|
|
0669ce5668 | ||
|
|
6d3ea5b0fd | ||
|
|
409e955883 | ||
|
|
f006f9ba7b | ||
|
|
6a03e8d9cf | ||
|
|
a1af5b655a | ||
|
|
edeafa596d | ||
|
|
b954e3ce80 | ||
|
|
bfa4035642 | ||
|
|
35be4d589e | ||
|
|
884a30f970 | ||
|
|
7288947390 | ||
|
|
c444e76ecb | ||
|
|
c4b1a8d4a2 | ||
|
|
7c8b1176c7 | ||
|
|
c5a088e7b8 | ||
|
|
8e443d4830 | ||
|
|
2cb52b749c | ||
|
|
de14f90daf | ||
|
|
9afc7e113e | ||
|
|
fbfe4b4564 | ||
|
|
4cb99506cb | ||
|
|
562e763fbd | ||
|
|
952de6e82b | ||
|
|
7ec54e6d0b | ||
|
|
e6df6014c7 | ||
|
|
e688a1c6e6 | ||
|
|
e44298d0c2 | ||
|
|
31cd8fc28a | ||
|
|
a46ce32ad4 | ||
|
|
31d8aae704 | ||
|
|
4b30f52b32 | ||
|
|
c8d42bbf20 | ||
|
|
511d6ca299 | ||
|
|
33f6d643be | ||
|
|
c2d09135f7 | ||
|
|
9f6b21e870 | ||
|
|
4eca4a1f07 | ||
|
|
4439fdf411 | ||
|
|
6ac8a1a0f6 | ||
|
|
f4ec781b8e | ||
|
|
5e256ea406 | ||
|
|
5abb0e484e | ||
|
|
16c247a24e | ||
|
|
0737c688d7 | ||
|
|
9de245eab6 | ||
|
|
a3cc54d33a | ||
|
|
a261246e64 | ||
|
|
2e195fe21a | ||
|
|
36a692991f | ||
|
|
ca0e3c3060 | ||
|
|
39474e97a7 | ||
|
|
b74cd095a1 | ||
|
|
96e1c57f61 | ||
|
|
f6ee8bbf71 | ||
|
|
188faeecf6 | ||
|
|
2c0a0a1337 | ||
|
|
7f92551d5a | ||
|
|
f54dbb596e | ||
|
|
aa3c5a85b7 | ||
|
|
f46e112c3d | ||
|
|
bcb5b3f5c1 | ||
|
|
65589e2fd2 | ||
|
|
54fbd8ba54 | ||
|
|
49129dd3e7 | ||
|
|
7bfa2b9425 | ||
|
|
53fbbb8a10 | ||
|
|
7bee9cdcfc | ||
|
|
928544ae5f | ||
|
|
312c752205 | ||
|
|
a5d1c25fea | ||
|
|
7abebe7405 | ||
|
|
ebc126f837 | ||
|
|
67bc9c4858 | ||
|
|
c4a3c18208 | ||
|
|
cf1b87a833 | ||
|
|
fb123603ca | ||
|
|
b3ab58da3b | ||
|
|
6374fc834c | ||
|
|
6df31649f5 | ||
|
|
9de6b580ba | ||
|
|
8eb6880694 | ||
|
|
fe4d86fae1 | ||
|
|
8492670bad | ||
|
|
04f95ed1d1 | ||
|
|
ee037c10ce | ||
|
|
cbf65e53b9 | ||
|
|
8c2b15d649 | ||
|
|
2134571b9a | ||
|
|
a541c79eda | ||
|
|
454086be6b | ||
|
|
6bd5997059 | ||
|
|
99911b2290 | ||
|
|
95d8b0692f | ||
|
|
e85cc3b309 | ||
|
|
2a01d562c3 | ||
|
|
51daf45c19 | ||
|
|
c9bd2bfd54 | ||
|
|
6225f62412 | ||
|
|
d2ffd73dea | ||
|
|
02329b64a1 | ||
|
|
aae0f70dd3 | ||
|
|
41d9cb4578 | ||
|
|
370047b1b0 | ||
|
|
6fc99e4c23 |
No files matched your search
@@ -2,7 +2,7 @@ name: C/C++ CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ "port" ]
|
||||
branches: [ "port", "port-net" ]
|
||||
pull_request:
|
||||
branches: [ "port" ]
|
||||
workflow_dispatch:
|
||||
@@ -268,7 +268,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
needs: [build-x86_64-linux]
|
||||
container:
|
||||
image: ghcr.io/flathub-infra/flatpak-github-actions:freedesktop-25.08
|
||||
image: bilelmoussaoui/flatpak-github-actions:freedesktop-23.08
|
||||
options: --privileged
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
@@ -279,16 +279,23 @@ jobs:
|
||||
|
||||
- uses: flatpak/flatpak-github-actions/flatpak-builder@v6
|
||||
with:
|
||||
bundle: io.github.perfect_dark_pc_port.perfect_dark.flatpak
|
||||
manifest-path: dist/linux/io.github.perfect_dark_pc_port.perfect_dark.yaml
|
||||
bundle: io.github.fgsfdsfgs.perfect_dark.flatpak
|
||||
manifest-path: dist/linux/io.github.fgsfdsfgs.perfect_dark.yaml
|
||||
cache-key: flatpak-builder-${{ github.sha }}
|
||||
upload-artifact: false
|
||||
|
||||
# - name: Build Flatpak bundle
|
||||
# run: |
|
||||
# cd dist/linux/
|
||||
# flatpak-builder build --force-clean io.github.fgsfdsfgs.perfect_dark.yaml
|
||||
# flatpak build-export export build
|
||||
# flatpak build-bundle export io.github.fgsfdsfgs.perfect_dark.flatpak io.github.fgsfdsfgs.perfect_dark
|
||||
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: io.github.perfect_dark_pc_port.perfect_dark.flatpak
|
||||
path: io.github.perfect_dark_pc_port.perfect_dark.flatpak
|
||||
name: io.github.fgsfdsfgs.perfect_dark.flatpak
|
||||
path: io.github.fgsfdsfgs.perfect_dark.flatpak
|
||||
retention-days: 0
|
||||
|
||||
|
||||
@@ -316,7 +323,7 @@ jobs:
|
||||
zip -r ../ci-release/pd-i686-windows.zip pd-i686-windows
|
||||
zip -r ../ci-release/pd-x86_64-windows.zip pd-x86_64-windows
|
||||
zip -r ../ci-release/pd-arm64-nswitch.zip pd-arm64-nswitch
|
||||
mv io.github.perfect_dark_pc_port.perfect_dark.flatpak/io.github.perfect_dark_pc_port.perfect_dark.flatpak ../ci-release/
|
||||
mv io.github.fgsfdsfgs.perfect_dark.flatpak/io.github.fgsfdsfgs.perfect_dark.flatpak ../ci-release/
|
||||
popd
|
||||
git tag --force ci-dev-build port
|
||||
git push --force origin ci-dev-build
|
||||
|
||||
Vendored
-14
@@ -1,14 +0,0 @@
|
||||
{
|
||||
"clang-format.enable": false,
|
||||
"C_Cpp.clang_format_style": "none",
|
||||
"[c]": {
|
||||
"editor.formatOnSave": false,
|
||||
"editor.formatOnPaste": false,
|
||||
"editor.formatOnType": false
|
||||
},
|
||||
"[cpp]": {
|
||||
"editor.formatOnSave": false,
|
||||
"editor.formatOnPaste": false,
|
||||
"editor.formatOnType": false
|
||||
}
|
||||
}
|
||||
+1
-3
@@ -21,7 +21,6 @@ set(CMAKE_C_STANDARD 11)
|
||||
set(CMAKE_C_EXTENSIONS OFF)
|
||||
set(CMAKE_CXX_STANDARD 20)
|
||||
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||
|
||||
# On first build set the build type to RelWithDebInfo if it's not already set
|
||||
if (NOT EXISTS ${CMAKE_BINARY_DIR}/CMakeCache.txt)
|
||||
@@ -188,7 +187,6 @@ add_compile_options(
|
||||
-Wno-unused-but-set-variable
|
||||
-Wno-unused-value
|
||||
-Wno-unused-variable
|
||||
-fdiagnostics-color=always
|
||||
)
|
||||
|
||||
# C specific flags
|
||||
@@ -246,7 +244,7 @@ list(APPEND LIBS "${GL_LIBRARY}")
|
||||
# Platform-specific extra libs
|
||||
if(NOT EXTRA_LIBRARIES)
|
||||
if(WIN32)
|
||||
set(EXTRA_LIBRARIES dbghelp -static-libstdc++)
|
||||
set(EXTRA_LIBRARIES ws2_32 winmm dbghelp -static-libstdc++)
|
||||
elseif(NINTENDO_SWITCH)
|
||||
set(EXTRA_LIBRARIES stdc++ pthread)
|
||||
else()
|
||||
|
||||
@@ -1,4 +1,14 @@
|
||||
# Perfect Dark port
|
||||
# Perfect Dark port (`port-net`)
|
||||
|
||||
## Experimental netplay branch
|
||||
|
||||
This branch of the port contains an **extremely** early and experimental implementation of network play.
|
||||
**DISCLAIMER:** This is **NOT READY** for prime time. Use at your own risk if you are not a developer.
|
||||
**Do not create issues about problems in this branch until this disclaimer is gone.**
|
||||
|
||||
See [this file](https://github.com/perfect-dark-pc-port/perfect_dark/blob/port-net/docs/netplay.md) for more information on how this works.
|
||||
|
||||
## Original description
|
||||
|
||||
This repository contains a work-in-progress port of the [Perfect Dark decompilation](https://github.com/n64decomp/perfect_dark) to modern platforms.
|
||||
|
||||
@@ -43,14 +53,13 @@ There are minor graphics- and gameplay-related issues, and possibly occasional c
|
||||
|
||||
## Download
|
||||
|
||||
Latest [automatic builds](https://github.com/fgsfdsfgs/perfect_dark/releases/tag/ci-dev-build) for supported platforms:
|
||||
* [x86_64-windows](https://github.com/fgsfdsfgs/perfect_dark/releases/download/ci-dev-build/pd-x86_64-windows.zip)
|
||||
* [i686-windows](https://github.com/fgsfdsfgs/perfect_dark/releases/download/ci-dev-build/pd-i686-windows.zip)
|
||||
* [x86_64-linux](https://github.com/fgsfdsfgs/perfect_dark/releases/download/ci-dev-build/pd-x86_64-linux.tar.gz)
|
||||
* [i686-linux](https://github.com/fgsfdsfgs/perfect_dark/releases/download/ci-dev-build/pd-i686-linux.tar.gz)
|
||||
* [arm64-nswitch](https://github.com/fgsfdsfgs/perfect_dark/releases/download/ci-dev-build/pd-arm64-nswitch.zip)
|
||||
Latest [automatic builds](https://github.com/perfect-dark-pc-port/perfect_dark/actions) of the netplay branch for supported platforms:
|
||||
* [x86_64-windows (`port-net`)](https://nightly.link/perfect-dark-pc-port/perfect_dark/workflows/c-cpp/port-net/pd-x86_64-windows.zip)
|
||||
* [i686-windows (`port-net`)](https://nightly.link/perfect-dark-pc-port/perfect_dark/workflows/c-cpp/port-net/pd-i686-windows.zip)
|
||||
* [x86_64-linux (`port-net`)](https://nightly.link/perfect-dark-pc-port/perfect_dark/workflows/c-cpp/port-net/pd-x86_64-linux.zip)
|
||||
* [i686-linux (`port-net`)](https://nightly.link/perfect-dark-pc-port/perfect_dark/workflows/c-cpp/port-net/pd-i686-linux.zip)
|
||||
|
||||
If you are looking for netplay builds (the `port-net` branch), see [this link](https://github.com/fgsfdsfgs/perfect_dark/blob/port-net/README.md#download).
|
||||
If you are looking for regular builds (the `port` branch), see [this link](https://github.com/perfect-dark-pc-port/perfect_dark/blob/port/README.md#download).
|
||||
|
||||
## Running
|
||||
|
||||
@@ -70,7 +79,9 @@ Optionally, you can also put your Perfect Dark for GameBoy Color ROM named `pd.g
|
||||
|
||||
Optionally, you can move the data folder to `~/.local/share/perfectdark` on Linux or `~/Library/Application Support/perfectdark` on MacOS.
|
||||
|
||||
Additional information can be found in the [wiki](https://github.com/fgsfdsfgs/perfect_dark/wiki).
|
||||
Note that users with different ROMs can't play netgames with each other.
|
||||
|
||||
Additional information can be found in the [wiki](https://github.com/perfect-dark-pc-port/perfect_dark/wiki).
|
||||
|
||||
A GPU supporting OpenGL 3.0/ES3.0 or above is required to run the port.
|
||||
|
||||
@@ -80,6 +91,8 @@ The Nintendo Switch build ZIP comes with all 3 regions in different folders: `pe
|
||||
|
||||
Take the folder for the region you want and put it into the `/switch` folder on your SD card, then put your ROM into the `data` folder inside of the folder you extracted as described above.
|
||||
|
||||
`port-net` currently does not work on the Switch.
|
||||
|
||||
## Controls
|
||||
|
||||
1964GEPD-style and Xbox-style bindings are implemented.
|
||||
@@ -98,7 +111,7 @@ Controls can be rebound in `pd.ini`. Default control scheme is as follows:
|
||||
| Aim mode | RMB/Z | LT | R Trigger |
|
||||
| Use / Cancel | E | N/A | B |
|
||||
| Use / Accept | N/A | A | A |
|
||||
| Crouch cycle | N/A | LS Click | `0x80000000` (Extra) |
|
||||
| Crouch cycle | N/A | L3 | `0x80000000` (Extra) |
|
||||
| Half-Crouch | Shift | N/A | `0x40000000` (Extra) |
|
||||
| Full-Crouch | Control | N/A | `0x20000000` (Extra) |
|
||||
| Reload | R | X | X `(0x40)` |
|
||||
@@ -118,7 +131,7 @@ Controls can be rebound in `pd.ini`. Default control scheme is as follows:
|
||||
3. Install dependencies:
|
||||
`pacman -S mingw-w64-x86_64-toolchain mingw-w64-x86_64-SDL2 mingw-w64-x86_64-zlib mingw-w64-x86_64-cmake mingw-w64-x86_64-python3 mingw-w64-i686-toolchain mingw-w64-i686-SDL2 mingw-w64-i686-zlib mingw-w64-i686-cmake mingw-w64-i686-python3 make git`
|
||||
4. Get the source code:
|
||||
`git clone --recursive https://github.com/fgsfdsfgs/perfect_dark.git && cd perfect_dark`
|
||||
`git clone -b port-net --recursive https://github.com/perfect-dark-pc-port/perfect_dark.git && cd perfect_dark`
|
||||
5. Run `cmake -G"Unix Makefiles" -Bbuild .`.
|
||||
* Add ` -DROMID=pal-final` or ` -DROMID=jpn-final` at the end of the command if you want to build a PAL or JPN executable respectively.\
|
||||
6. Run `cmake --build build -j4 -- -O`.
|
||||
@@ -130,7 +143,7 @@ Controls can be rebound in `pd.ini`. Default control scheme is as follows:
|
||||
1. Ensure you have gcc, g++ (version 10.0+), make, cmake, git, python3 and SDL2 (version 2.0.12+), libGL and ZLib installed on your system.
|
||||
* If you wish to crosscompile, you will also need to have libraries and compilers for the target platform installed, e.g. `gcc-multilib` and `g++-multilib` for x86_64 -> i686 crosscompilation.
|
||||
2. Get the source code:
|
||||
`git clone --recursive https://github.com/fgsfdsfgs/perfect_dark.git && cd perfect_dark`
|
||||
`git clone -b port-net --recursive https://github.com/perfect-dark-pc-port/perfect_dark.git && cd perfect_dark`
|
||||
3. Run the following command:
|
||||
* ```cmake -G"Unix Makefiles" -Bbuild .```
|
||||
* Add ` -DROMID=pal-final` or ` -DROMID=jpn-final` at the end of the command if you want to build a PAL or JPN executable respectively.
|
||||
@@ -154,7 +167,7 @@ Controls can be rebound in `pd.ini`. Default control scheme is as follows:
|
||||
* This installs SDL2 system-wide and this is how the automatic builds are done. The game will also look for it in the executable path, so you could
|
||||
download it locally instead.
|
||||
4. Get the source code:
|
||||
`git clone --recursive https://github.com/fgsfdsfgs/perfect_dark.git && cd perfect_dark`
|
||||
`git clone --recursive https://github.com/perfect-dark-pc-port/perfect_dark.git && cd perfect_dark`
|
||||
5. Configure:
|
||||
* Execute command: `cmake -G"Unix Makefiles" -Bbuild -DCMAKE_OSX_ARCHITECTURES=x86_64 .`
|
||||
* Replace `x86_64` with `arm64` if building for an ARM64 Mac.
|
||||
@@ -180,7 +193,7 @@ Controls can be rebound in `pd.ini`. Default control scheme is as follows:
|
||||
```
|
||||
* If in MSYS2 or `dkp-pacman` doesn't work, replace it with just `pacman`.
|
||||
4. Get the source code:
|
||||
`git clone --recursive https://github.com/fgsfdsfgs/perfect_dark.git && cd perfect_dark`
|
||||
`git clone --recursive https://github.com/perfect-dark-pc-port/perfect_dark.git && cd perfect_dark`
|
||||
5. Ensure devkitA64 environment variables are set:
|
||||
* Execute command: `source /opt/devkitpro/switchvars.sh`
|
||||
* If your `$DEVKITPRO` path is different, substitute that instead or set the variables manually.
|
||||
@@ -205,7 +218,7 @@ It might be possible to build and run the game on platforms that are not specifi
|
||||
* Ryan Dwyer for the above, additional help, and `pd-extract`;
|
||||
* doomhack for the only other publicly available [PD porting effort](https://github.com/doomhack/perfect_dark) I could find;
|
||||
* [sm64-port](https://github.com/sm64-port/sm64-port) authors for the audio mixer and some other changes;
|
||||
* [Ship of Harkinian team](https://github.com/Kenix3/libultraship/tree/main/src/fast), Emill and MaikelChan for the libultraship version of fast3d that this port uses;
|
||||
* [Ship of Harkinian team](https://github.com/Kenix3/libultraship/tree/main/src/graphic/Fast3D), Emill and MaikelChan for the libultraship version of fast3d that this port uses;
|
||||
* lieff for [minimp3](https://github.com/lieff/minimp3);
|
||||
* Mouse Injector and 1964GEPD authors for some of the 60FPS- and mouselook-related fixes;
|
||||
* Raf for the 64-bit port;
|
||||
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
[Desktop Entry]
|
||||
Name=Perfect Dark
|
||||
Comment=Modern source port of Perfect Dark
|
||||
Exec=io.github.perfect_dark_pc_port.perfect_dark.sh
|
||||
Icon=io.github.perfect_dark_pc_port.perfect_dark
|
||||
Exec=io.github.fgsfdsfgs.perfect_dark.sh
|
||||
Icon=io.github.fgsfdsfgs.perfect_dark
|
||||
Terminal=false
|
||||
Type=Application
|
||||
Categories=Game;ActionGame;
|
||||
+5
-6
@@ -1,12 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<component type="desktop-application">
|
||||
<id>io.github.perfect_dark_pc_port.perfect_dark</id>
|
||||
<id>io.github.fgsfdsfgs.perfect_dark</id>
|
||||
<name>Perfect Dark</name>
|
||||
<developer id="io.github.perfect_dark_pc_port.perfect_dark">
|
||||
<developer id="io.github.fgsfdsfgs.perfect_dark">
|
||||
<name>Perfect Dark Contributors</name>
|
||||
<url>https://github.com/fgsfdsfgs/perfect_dark/graphs/contributors</url>
|
||||
</developer>
|
||||
<launchable type="desktop-id">io.github.perfect_dark_pc_port.perfect_dark.desktop</launchable>
|
||||
<launchable type="desktop-id">io.github.fgsfdsfgs.perfect_dark.desktop</launchable>
|
||||
<summary>Modern cross-platform port of Perfect Dark</summary>
|
||||
<metadata_license>CC0-1.0</metadata_license>
|
||||
<project_license>MIT</project_license>
|
||||
@@ -17,9 +17,8 @@
|
||||
<!--
|
||||
<screenshots>
|
||||
<screenshot type="default">
|
||||
<image type="source"></image>
|
||||
<caption>Screenshot</caption>
|
||||
</screenshot>
|
||||
<image type="source">https://gitlab.com/fpiesche/dxx-rebirth-assets/-/raw/c6e7e79eebe92905f84f07a635ffab5122a94bd1/d1x/screenshots/retromode.png</image>
|
||||
<caption>"Retro mode": the default graphics setup, like the original game but in high resolution</caption>
|
||||
<screenshots>
|
||||
-->
|
||||
<categories>
|
||||
File renamed without changes.
File renamed without changes.
+7
-7
@@ -1,8 +1,8 @@
|
||||
app-id: io.github.perfect_dark_pc_port.perfect_dark
|
||||
app-id: io.github.fgsfdsfgs.perfect_dark
|
||||
runtime: org.freedesktop.Platform
|
||||
runtime-version: "25.08"
|
||||
runtime-version: "23.08"
|
||||
sdk: org.freedesktop.Sdk
|
||||
command: io.github.perfect_dark_pc_port.perfect_dark.sh
|
||||
command: io.github.fgsfdsfgs.perfect_dark.sh
|
||||
|
||||
finish-args:
|
||||
- --device=all
|
||||
@@ -24,13 +24,13 @@ modules:
|
||||
- type: file
|
||||
path: bin/pd.pal.x86_64
|
||||
- type: file
|
||||
path: io.github.perfect_dark_pc_port.perfect_dark.sh
|
||||
path: io.github.fgsfdsfgs.perfect_dark.sh
|
||||
- type: file
|
||||
path: io.github.perfect_dark_pc_port.perfect_dark.png
|
||||
path: io.github.fgsfdsfgs.perfect_dark.png
|
||||
- type: file
|
||||
path: io.github.perfect_dark_pc_port.perfect_dark.metainfo.xml
|
||||
path: io.github.fgsfdsfgs.perfect_dark.metainfo.xml
|
||||
- type: file
|
||||
path: io.github.perfect_dark_pc_port.perfect_dark.desktop
|
||||
path: io.github.fgsfdsfgs.perfect_dark.desktop
|
||||
build-commands: []
|
||||
post-install:
|
||||
# Install the binaries
|
||||
@@ -0,0 +1,47 @@
|
||||
## Experimental netplay branch
|
||||
|
||||
This branch contains a **highly experimental** implementation of network play.
|
||||
|
||||
Currently only Combat Sim is partially working with experimental 8 player support and really bad netcode.
|
||||
Expect nothing to work right.
|
||||
|
||||
### Hosting
|
||||
|
||||
1. Forward the server port (`27100` by default, can be changed in `pd.ini`).
|
||||
* You can also use something like ZeroTier or Hamachi if you can't port forward.
|
||||
3. Choose `Network Game` -> `Host Game`, configure the player cap, press `Start Game`.
|
||||
4. Configure Combat Sim as desired, but do not start it yet. Keep in mind:
|
||||
* You can save and load the settings as normal.
|
||||
* Your player will have the config of Combat Sim player 1.
|
||||
5. Wait for everyone to join. You can use the console (press `~`) to chat in the meantime.
|
||||
6. Hit Enter/Start. During the game no more players will be able to join.
|
||||
7. After game is over, you will be kicked back to Combat Sim settings, at which point people can join again and the process repeats from step 3.
|
||||
|
||||
### Joining
|
||||
|
||||
1. Your player will have the config of Combat Sim player 1, so set that up beforehand in the Combat Sim menu.
|
||||
2. Choose `Network Game` -> `Join Game`, enter the address (and port if it's not 27100), press `Start Game`.
|
||||
3. If the message says `Waiting for host`, wait until the host configures the game. You can use the console (press `~`) to chat in the meantime or `ESC` to disconnect.
|
||||
4. The game will start automatically.
|
||||
5. After the game is over, press Enter/Start on the stats screen and you will be kicked back to the `Waiting for host` screen, at which point the process repeats from step 3.
|
||||
|
||||
### Misc
|
||||
|
||||
* Everyone has to have the same ROM. The game only compares the file name, but different regions in one game will definitely break everything.
|
||||
* Press `~` to bring up the console, press `F9` for network stats.
|
||||
* You can chat at any time during a net game by entering messages in the console and hitting Enter.
|
||||
* Server port and other network settings can be configured in `pd.ini`.
|
||||
* For a 4+ player game I would recommend changing `Net.Server.UpdateFrames` to `2` in `pd.ini` on the server to lower the bandwidth usage.
|
||||
* You can paste stuff into the `Enter Address` prompt by hitting `CTRL+V`.
|
||||
* Expect nothing to work right.
|
||||
|
||||
### Known issues
|
||||
|
||||
* Clients see rocket rotation incorrectly.
|
||||
* Clients can't use Slayer fly-by-wire rockets and they will not correctly sync if the server uses them.
|
||||
* Clients can't use the alt fire mode on the FarSight and probably a couple other guns.
|
||||
* Cloaking device is not synced.
|
||||
* Most likely only Combat works properly.
|
||||
* Sims don't work in netgames.
|
||||
* Bandwidth consumption on the server is pretty large on the default settings, especially with 8 players.
|
||||
|
||||
Vendored
+10
@@ -0,0 +1,10 @@
|
||||
#ifndef _WIN32
|
||||
#ifndef _POSIX_C_SOURCE
|
||||
#define _POSIX_C_SOURCE 200809L
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define ENET_IMPLEMENTATION 1
|
||||
#define ENET_NO_PRAGMA_LINK 1
|
||||
|
||||
#include "external/enet.h"
|
||||
Vendored
+2
@@ -0,0 +1,2 @@
|
||||
#define MINIMP3_IMPLEMENTATION
|
||||
#include "external/minimp3.h"
|
||||
@@ -45,10 +45,8 @@ void gfx_run(Gfx* commands);
|
||||
void gfx_end_frame(void);
|
||||
void gfx_set_target_fps(int);
|
||||
void gfx_set_texture_filter(enum FilteringMode mode);
|
||||
void gfx_set_mipmap_filter(enum MipmapFilteringMode mode);
|
||||
void gfx_texture_cache_clear(void);
|
||||
void gfx_texture_cache_delete(const uint8_t *orig_addr);
|
||||
void gfx_texture_cache_delete_range(const uint8_t *start, const uint8_t *end);
|
||||
int gfx_create_framebuffer(uint32_t width, uint32_t height, int upscale, int autoresize);
|
||||
void gfx_resize_framebuffer(int fb, uint32_t width, uint32_t height, int upscale, int autoresize);
|
||||
void gfx_set_framebuffer(int fb, float noise_scale) ;
|
||||
|
||||
+7
-203
@@ -33,10 +33,6 @@ struct ShaderProgram {
|
||||
GLint frame_count_location;
|
||||
GLint noise_scale_location;
|
||||
GLint three_point_filter_locations[2];
|
||||
GLint decal_mode_location;
|
||||
GLint decal_scale_location;
|
||||
int decal_mode;
|
||||
float decal_scale;
|
||||
};
|
||||
|
||||
struct Framebuffer {
|
||||
@@ -44,8 +40,6 @@ struct Framebuffer {
|
||||
bool has_depth_buffer;
|
||||
uint32_t msaa_level;
|
||||
bool invert_y;
|
||||
bool depth_copy_checked;
|
||||
bool depth_copy_failed;
|
||||
|
||||
GLuint fbo, clrbuf, clrbuf_msaa, rbo;
|
||||
};
|
||||
@@ -60,23 +54,8 @@ static uint32_t frame_count;
|
||||
static std::vector<Framebuffer> framebuffers;
|
||||
static size_t current_framebuffer;
|
||||
static float current_noise_scale;
|
||||
static int current_anisotropy_level;
|
||||
static FilteringMode current_filter_mode = FILTER_LINEAR;
|
||||
static MipmapFilteringMode current_mipmap_filter_mode = MIPMAP_LINEAR;
|
||||
static bool current_textures_linear_filter[2] = {false, false};
|
||||
static struct ShaderProgram* current_shader_program;
|
||||
|
||||
// N64 decal depth mode: pixels only pass when close to the stored depth, using a copy of the depth buffer
|
||||
#define DECAL_DEPTH_TEXTURE_UNIT 2
|
||||
// Height of the N64 frame; the RDP's depth slope tolerance is measured in N64 pixels
|
||||
#define DECAL_N64_SCREEN_HEIGHT 240.0f
|
||||
static bool depth_copy_supported;
|
||||
static bool depth_copy_dirty = true;
|
||||
static size_t depth_copy_source;
|
||||
static GLuint depth_copy_fbo, depth_copy_tex;
|
||||
static uint32_t depth_copy_width, depth_copy_height;
|
||||
static bool current_depth_test;
|
||||
static bool current_depth_decal;
|
||||
|
||||
static int gl_glsl_version = 130;
|
||||
static char gl_glsl_version_str[16] = "130";
|
||||
@@ -139,7 +118,6 @@ static void gfx_opengl_unload_shader(struct ShaderProgram* old_prg) {
|
||||
|
||||
static void gfx_opengl_load_shader(struct ShaderProgram* new_prg) {
|
||||
// if (!new_prg) return;
|
||||
current_shader_program = new_prg;
|
||||
glUseProgram(new_prg->opengl_program_id);
|
||||
gfx_opengl_vertex_array_set_attribs(new_prg);
|
||||
gfx_opengl_set_uniforms(new_prg);
|
||||
@@ -402,9 +380,6 @@ static struct ShaderProgram* gfx_opengl_create_and_load_new_shader(uint64_t shad
|
||||
|
||||
append_line(fs_buf, &fs_len, "uniform int frame_count;");
|
||||
append_line(fs_buf, &fs_len, "uniform float noise_scale;");
|
||||
append_line(fs_buf, &fs_len, "uniform int uDecalMode;");
|
||||
append_line(fs_buf, &fs_len, "uniform highp float uDecalPixelScale;");
|
||||
append_line(fs_buf, &fs_len, "uniform highp sampler2D uDepthTex;");
|
||||
|
||||
append_line(fs_buf, &fs_len, "float random(in vec3 value) {");
|
||||
append_line(fs_buf, &fs_len, " float random = dot(sin(value), vec3(12.9898, 78.233, 37.719));");
|
||||
@@ -465,15 +440,6 @@ static struct ShaderProgram* gfx_opengl_create_and_load_new_shader(uint64_t shad
|
||||
|
||||
append_line(fs_buf, &fs_len, "void main() {");
|
||||
|
||||
// RDP decal Z mode: pass only if |z - stored z| <= dz (the per-pixel depth slope), and never over cleared depth.
|
||||
// The slope is computed before anything can discard, since derivatives are undefined after a neighbor discards.
|
||||
append_line(fs_buf, &fs_len, " highp float decalSlope = fwidth(gl_FragCoord.z);");
|
||||
append_line(fs_buf, &fs_len, " if (uDecalMode != 0) {");
|
||||
append_line(fs_buf, &fs_len, " highp float storedZ = texelFetch(uDepthTex, ivec2(gl_FragCoord.xy), 0).r;");
|
||||
append_line(fs_buf, &fs_len, " highp float dz = max(decalSlope * uDecalPixelScale, 1.0 / 262144.0);");
|
||||
append_line(fs_buf, &fs_len, " if (storedZ >= 1.0 || abs(gl_FragCoord.z - storedZ) > dz) discard;");
|
||||
append_line(fs_buf, &fs_len, " }");
|
||||
|
||||
for (int i = 0; i < 2; i++) {
|
||||
if (cc_features.used_textures[i]) {
|
||||
bool s = cc_features.clamp[i][0], t = cc_features.clamp[i][1];
|
||||
@@ -684,14 +650,6 @@ static struct ShaderProgram* gfx_opengl_create_and_load_new_shader(uint64_t shad
|
||||
prg->noise_scale_location = glGetUniformLocation(shader_program, "noise_scale");
|
||||
prg->three_point_filter_locations[0] = glGetUniformLocation(shader_program, "three_point_filter0");
|
||||
prg->three_point_filter_locations[1] = glGetUniformLocation(shader_program, "three_point_filter1");
|
||||
prg->decal_mode_location = glGetUniformLocation(shader_program, "uDecalMode");
|
||||
prg->decal_scale_location = glGetUniformLocation(shader_program, "uDecalPixelScale");
|
||||
prg->decal_mode = 0;
|
||||
prg->decal_scale = 0.0f;
|
||||
if (prg->decal_mode_location >= 0) {
|
||||
glUniform1i(prg->decal_mode_location, 0);
|
||||
glUniform1i(glGetUniformLocation(shader_program, "uDepthTex"), DECAL_DEPTH_TEXTURE_UNIT);
|
||||
}
|
||||
|
||||
gfx_opengl_load_shader(prg);
|
||||
|
||||
@@ -711,7 +669,6 @@ static void gfx_opengl_shader_get_info(struct ShaderProgram* prg, uint8_t* num_i
|
||||
|
||||
static void gfx_opengl_clear_shaders(void) {
|
||||
glUseProgram(0);
|
||||
current_shader_program = nullptr;
|
||||
for (auto& pair : shader_program_pool) {
|
||||
glDeleteProgram(pair.second.opengl_program_id);
|
||||
}
|
||||
@@ -735,11 +692,8 @@ static void gfx_opengl_select_texture(int tile, GLuint texture_id, bool linear_f
|
||||
current_textures_linear_filter[tile] = linear_filter;
|
||||
}
|
||||
|
||||
static void gfx_opengl_upload_texture(const uint8_t* rgba32_buf, uint32_t width, uint32_t height, bool gen_mipmaps) {
|
||||
static void gfx_opengl_upload_texture(const uint8_t* rgba32_buf, uint32_t width, uint32_t height) {
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, rgba32_buf);
|
||||
if (gen_mipmaps || current_filter_mode == FILTER_THREE_POINT) {
|
||||
glGenerateMipmap(GL_TEXTURE_2D);
|
||||
}
|
||||
}
|
||||
|
||||
static uint32_t gfx_cm_to_opengl(uint32_t val) {
|
||||
@@ -756,35 +710,16 @@ static uint32_t gfx_cm_to_opengl(uint32_t val) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void gfx_opengl_set_sampler_parameters(int tile, bool linear_filter, uint32_t cms, uint32_t cmt, bool mipmaps) {
|
||||
const GLint min_filters[3][3] = {
|
||||
// MIPMAP_DISABLED MIPMAP_NEAREST MIPMAP_LINEAR
|
||||
{ GL_NEAREST, GL_NEAREST_MIPMAP_NEAREST, GL_NEAREST_MIPMAP_LINEAR }, // FILTER_NONE
|
||||
{ GL_LINEAR, GL_LINEAR_MIPMAP_NEAREST, GL_LINEAR_MIPMAP_LINEAR }, // FILTER_BILINEAR
|
||||
{ GL_NEAREST, GL_NEAREST, GL_NEAREST }, // FILTER_THREE_POINT
|
||||
};
|
||||
|
||||
mipmaps = mipmaps && (current_mipmap_filter_mode != MIPMAP_DISABLED);
|
||||
const int mip_idx = mipmaps ? current_mipmap_filter_mode : 0;
|
||||
const GLint min_filter = linear_filter ? min_filters[current_filter_mode][mip_idx] : GL_LINEAR;
|
||||
const GLint max_filter = linear_filter && (current_filter_mode == FILTER_LINEAR) ? GL_LINEAR : GL_LINEAR;
|
||||
|
||||
static void gfx_opengl_set_sampler_parameters(int tile, bool linear_filter, uint32_t cms, uint32_t cmt) {
|
||||
const GLint filter = linear_filter && (current_filter_mode == FILTER_LINEAR) ? GL_LINEAR : GL_NEAREST;
|
||||
glActiveTexture(GL_TEXTURE0 + tile);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, max_filter);
|
||||
|
||||
if (mipmaps) {
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY, current_anisotropy_level);
|
||||
}
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, gfx_cm_to_opengl(cms));
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, gfx_cm_to_opengl(cmt));
|
||||
}
|
||||
|
||||
static void gfx_opengl_set_depth_mode(bool depth_test, bool depth_update, bool depth_compare, bool depth_source_prim, uint16_t zmode) {
|
||||
current_depth_test = depth_test;
|
||||
current_depth_decal = depth_test && depth_compare && zmode == ZMODE_DEC;
|
||||
|
||||
if (depth_test) {
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDepthMask(depth_update ? GL_TRUE : GL_FALSE);
|
||||
@@ -854,116 +789,10 @@ static void gfx_opengl_set_use_alpha(bool use_alpha, bool modulate) {
|
||||
}
|
||||
}
|
||||
|
||||
static bool gfx_opengl_update_depth_copy(void) {
|
||||
if (!depth_copy_supported) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Framebuffer& fb = framebuffers[current_framebuffer];
|
||||
if ((current_framebuffer != 0 && !fb.has_depth_buffer) || fb.depth_copy_failed) {
|
||||
return false;
|
||||
}
|
||||
if (!depth_copy_dirty && depth_copy_source == current_framebuffer && depth_copy_width == fb.width &&
|
||||
depth_copy_height == fb.height) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (depth_copy_tex == 0 || depth_copy_width != fb.width || depth_copy_height != fb.height) {
|
||||
if (depth_copy_tex == 0) {
|
||||
glGenTextures(1, &depth_copy_tex);
|
||||
glGenFramebuffers(1, &depth_copy_fbo);
|
||||
}
|
||||
|
||||
GLint active_texture;
|
||||
glGetIntegerv(GL_ACTIVE_TEXTURE, &active_texture);
|
||||
glActiveTexture(GL_TEXTURE0 + DECAL_DEPTH_TEXTURE_UNIT);
|
||||
glBindTexture(GL_TEXTURE_2D, depth_copy_tex);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, fb.width, fb.height, 0, GL_DEPTH_STENCIL,
|
||||
GL_UNSIGNED_INT_24_8, NULL);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glActiveTexture(active_texture);
|
||||
|
||||
const GLenum no_draw_buffer = GL_NONE;
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, depth_copy_fbo);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, depth_copy_tex, 0);
|
||||
glDrawBuffers(1, &no_draw_buffer);
|
||||
glReadBuffer(GL_NONE);
|
||||
|
||||
depth_copy_width = fb.width;
|
||||
depth_copy_height = fb.height;
|
||||
}
|
||||
|
||||
const bool check_errors = !fb.depth_copy_checked;
|
||||
if (check_errors) {
|
||||
for (int i = 0; i < 16 && glGetError() != GL_NO_ERROR; i++) {
|
||||
}
|
||||
}
|
||||
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, fb.fbo);
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, depth_copy_fbo);
|
||||
glBlitFramebuffer(0, 0, fb.width, fb.height, 0, 0, fb.width, fb.height, GL_DEPTH_BUFFER_BIT, GL_NEAREST);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, fb.fbo);
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
|
||||
if (check_errors) {
|
||||
fb.depth_copy_checked = true;
|
||||
if (glGetError() != GL_NO_ERROR) {
|
||||
fb.depth_copy_failed = true;
|
||||
sysLogPrintf(LOG_WARNING, "GL: could not copy depth buffer of framebuffer %u, decal edges will not be clipped",
|
||||
(unsigned)current_framebuffer);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
depth_copy_dirty = false;
|
||||
depth_copy_source = current_framebuffer;
|
||||
return true;
|
||||
}
|
||||
|
||||
static void gfx_opengl_set_decal_uniforms(struct ShaderProgram* prg, bool enabled) {
|
||||
if (prg == nullptr || prg->decal_mode_location < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
const int mode = enabled ? 1 : 0;
|
||||
if (prg->decal_mode != mode) {
|
||||
glUniform1i(prg->decal_mode_location, mode);
|
||||
prg->decal_mode = mode;
|
||||
}
|
||||
|
||||
const float scale = framebuffers[current_framebuffer].height / DECAL_N64_SCREEN_HEIGHT;
|
||||
if (enabled && prg->decal_scale != scale) {
|
||||
glUniform1f(prg->decal_scale_location, scale);
|
||||
prg->decal_scale = scale;
|
||||
}
|
||||
}
|
||||
|
||||
static void gfx_opengl_draw_triangles(float buf_vbo[], size_t buf_vbo_len, size_t buf_vbo_num_tris) {
|
||||
// printf("flushing %d tris\n", buf_vbo_num_tris);
|
||||
if (current_depth_decal) {
|
||||
// The shader replaces the depth test like the RDP does; fall back to polygon offset if depth can't be copied
|
||||
const bool decal = gfx_opengl_update_depth_copy();
|
||||
glDepthFunc(decal ? GL_ALWAYS : GL_LEQUAL);
|
||||
if (decal) {
|
||||
glDisable(GL_POLYGON_OFFSET_FILL);
|
||||
} else {
|
||||
glEnable(GL_POLYGON_OFFSET_FILL);
|
||||
}
|
||||
gfx_opengl_set_decal_uniforms(current_shader_program, decal);
|
||||
} else {
|
||||
gfx_opengl_set_decal_uniforms(current_shader_program, false);
|
||||
}
|
||||
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * buf_vbo_len, buf_vbo, GL_STREAM_DRAW);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 3 * buf_vbo_num_tris);
|
||||
|
||||
if (current_depth_test && current_depth_mask) {
|
||||
depth_copy_dirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
typedef void (APIENTRY *DEBUGPROC)(GLenum source,
|
||||
@@ -1140,11 +969,6 @@ static void gfx_opengl_init(void) {
|
||||
gfx_framebuffers_enabled = false;
|
||||
}
|
||||
|
||||
depth_copy_supported = GLVersion.major >= 3 && gfx_opengl_supports_framebuffers() && glDrawBuffers && glReadBuffer;
|
||||
if (!depth_copy_supported) {
|
||||
sysLogPrintf(LOG_WARNING, "GL: depth buffer copies unsupported, decal edges will not be clipped");
|
||||
}
|
||||
|
||||
if ((GLVersion.major < 4 || GLVersion.minor < 4) && !GLAD_GL_ARB_texture_mirror_clamp_to_edge) {
|
||||
// GL_MIRROR_CLAMP_TO_EDGE unsupported
|
||||
gl_mirror_clamp = GL_MIRRORED_REPEAT;
|
||||
@@ -1293,7 +1117,6 @@ static void gfx_opengl_update_framebuffer_parameters(int fb_id, uint32_t width,
|
||||
fb.has_depth_buffer = has_depth_buffer;
|
||||
fb.msaa_level = msaa_level;
|
||||
fb.invert_y = opengl_invert_y;
|
||||
depth_copy_dirty = true;
|
||||
}
|
||||
|
||||
bool gfx_opengl_start_draw_to_framebuffer(int fb_id, float noise_scale) {
|
||||
@@ -1304,7 +1127,6 @@ bool gfx_opengl_start_draw_to_framebuffer(int fb_id, float noise_scale) {
|
||||
}
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, fb.fbo);
|
||||
current_framebuffer = fb_id;
|
||||
depth_copy_dirty = true;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
@@ -1322,7 +1144,6 @@ void gfx_opengl_clear_framebuffer(bool clear_color, bool clear_depth) {
|
||||
if (clear_depth) {
|
||||
glDepthMask(GL_TRUE);
|
||||
mask |= GL_DEPTH_BUFFER_BIT;
|
||||
depth_copy_dirty = true;
|
||||
}
|
||||
glClear(mask);
|
||||
if (clear_depth) {
|
||||
@@ -1423,21 +1244,7 @@ FilteringMode gfx_opengl_get_texture_filter(void) {
|
||||
return current_filter_mode;
|
||||
}
|
||||
|
||||
void gfx_opengl_set_mipmap_filter(MipmapFilteringMode mode) {
|
||||
current_mipmap_filter_mode = mode;
|
||||
}
|
||||
|
||||
static int gfx_opengl_get_max_anisotropy_level() {
|
||||
GLfloat max_aniso_level;
|
||||
glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY, &max_aniso_level);
|
||||
return (int)max_aniso_level;
|
||||
}
|
||||
|
||||
static void gfx_opengl_set_anisotropy_level(int level) {
|
||||
current_anisotropy_level = level;
|
||||
}
|
||||
|
||||
struct GfxRenderingAPI gfx_opengl_api = {
|
||||
struct GfxRenderingAPI gfx_opengl_api = {
|
||||
gfx_opengl_get_name,
|
||||
gfx_opengl_get_max_texture_size,
|
||||
gfx_opengl_get_clip_parameters,
|
||||
@@ -1472,8 +1279,5 @@ struct GfxRenderingAPI gfx_opengl_api = {
|
||||
gfx_opengl_select_texture_fb,
|
||||
gfx_opengl_delete_texture,
|
||||
gfx_opengl_set_texture_filter,
|
||||
gfx_opengl_get_texture_filter,
|
||||
gfx_opengl_set_mipmap_filter,
|
||||
gfx_opengl_set_anisotropy_level,
|
||||
gfx_opengl_get_max_anisotropy_level
|
||||
gfx_opengl_get_texture_filter
|
||||
};
|
||||
+39
-76
@@ -551,7 +551,7 @@ static bool gfx_texture_cache_lookup(int i, const TextureCacheKey& key) {
|
||||
node->second.lru_location = gfx_texture_cache.lru.insert(gfx_texture_cache.lru.end(), { it });
|
||||
|
||||
gfx_rapi->select_texture(i, texture_id, false);
|
||||
gfx_rapi->set_sampler_parameters(i, false, 0, 0, rdp.tex_lod);
|
||||
gfx_rapi->set_sampler_parameters(i, false, 0, 0);
|
||||
*n = node;
|
||||
return false;
|
||||
}
|
||||
@@ -585,30 +585,8 @@ void gfx_texture_cache_delete(const uint8_t* orig_addr) {
|
||||
}
|
||||
}
|
||||
|
||||
void gfx_texture_cache_delete_range(const uint8_t* start, const uint8_t* end) {
|
||||
gfx_flush();
|
||||
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
if (rendering_state.textures[i]
|
||||
&& rendering_state.textures[i]->first.texture_addr >= start
|
||||
&& rendering_state.textures[i]->first.texture_addr < end) {
|
||||
rdp.textures_changed[i] = true;
|
||||
rendering_state.textures[i] = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
for (auto it = gfx_texture_cache.map.begin(); it != gfx_texture_cache.map.end(); ) {
|
||||
if (it->first.texture_addr >= start && it->first.texture_addr < end) {
|
||||
gfx_texture_cache.lru.erase(it->second.lru_location);
|
||||
gfx_texture_cache.free_texture_ids.push_back(it->second.texture_id);
|
||||
it = gfx_texture_cache.map.erase(it);
|
||||
} else {
|
||||
++it;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void import_texture_rgba16(int tile, const LoadedTexture& loaded_texture, bool gen_mipmaps) {
|
||||
static void import_texture_rgba16(int tile, const LoadedTexture& loaded_texture, bool importReplacement) {
|
||||
const RawTexMetadata* metadata = &loaded_texture.raw_tex_metadata;
|
||||
const uint8_t* addr = loaded_texture.addr;
|
||||
const uint32_t size_bytes = loaded_texture.size_bytes;
|
||||
const uint32_t full_image_line_size_bytes =
|
||||
@@ -634,11 +612,11 @@ static void import_texture_rgba16(int tile, const LoadedTexture& loaded_texture,
|
||||
const uint32_t width = rdp.texture_tile[tile].line_size_bytes / 2;
|
||||
const uint32_t height = size_bytes / rdp.texture_tile[tile].line_size_bytes;
|
||||
|
||||
gfx_rapi->upload_texture(tex_upload_buffer, width, height, gen_mipmaps);
|
||||
gfx_rapi->upload_texture(tex_upload_buffer, width, height);
|
||||
// DumpTexture(loaded_texture.otr_path, rgba32_buf, width, height);
|
||||
}
|
||||
|
||||
static void import_texture_rgba32(int tile, const LoadedTexture& loaded_texture, bool gen_mipmaps) {
|
||||
static void import_texture_rgba32(int tile, const LoadedTexture& loaded_texture, bool importReplacement) {
|
||||
const RawTexMetadata* metadata = &loaded_texture.raw_tex_metadata;
|
||||
const uint8_t* addr = loaded_texture.addr;
|
||||
const uint32_t size_bytes = loaded_texture.size_bytes;
|
||||
@@ -655,11 +633,11 @@ static void import_texture_rgba32(int tile, const LoadedTexture& loaded_texture,
|
||||
|
||||
const uint32_t width = rdp.texture_tile[tile].line_size_bytes / 2;
|
||||
const uint32_t height = (size_bytes / 2) / rdp.texture_tile[tile].line_size_bytes;
|
||||
gfx_rapi->upload_texture(tex_upload_buffer, width, height, gen_mipmaps);
|
||||
gfx_rapi->upload_texture(tex_upload_buffer, width, height);
|
||||
// DumpTexture(loaded_texture.otr_path, addr, width, height);
|
||||
}
|
||||
|
||||
static void import_texture_ia4(int tile, const LoadedTexture& loaded_texture, bool gen_mipmaps) {
|
||||
static void import_texture_ia4(int tile, const LoadedTexture& loaded_texture, bool importReplacement) {
|
||||
const RawTexMetadata* metadata = &loaded_texture.raw_tex_metadata;
|
||||
const uint8_t* addr = loaded_texture.addr;
|
||||
const uint32_t size_bytes = loaded_texture.size_bytes;
|
||||
@@ -684,11 +662,11 @@ static void import_texture_ia4(int tile, const LoadedTexture& loaded_texture, bo
|
||||
const uint32_t width = rdp.texture_tile[tile].line_size_bytes * 2;
|
||||
const uint32_t height = size_bytes / rdp.texture_tile[tile].line_size_bytes;
|
||||
|
||||
gfx_rapi->upload_texture(tex_upload_buffer, width, height, gen_mipmaps);
|
||||
gfx_rapi->upload_texture(tex_upload_buffer, width, height);
|
||||
// DumpTexture(loaded_texture.otr_path, rgba32_buf, width, height);
|
||||
}
|
||||
|
||||
static void import_texture_ia8(int tile, const LoadedTexture& loaded_texture, bool gen_mipmaps) {
|
||||
static void import_texture_ia8(int tile, const LoadedTexture& loaded_texture, bool importReplacement) {
|
||||
const RawTexMetadata* metadata = &loaded_texture.raw_tex_metadata;
|
||||
const uint8_t* addr = loaded_texture.addr;
|
||||
const uint32_t size_bytes = loaded_texture.size_bytes;
|
||||
@@ -710,11 +688,11 @@ static void import_texture_ia8(int tile, const LoadedTexture& loaded_texture, bo
|
||||
const uint32_t width = rdp.texture_tile[tile].line_size_bytes;
|
||||
const uint32_t height = size_bytes / rdp.texture_tile[tile].line_size_bytes;
|
||||
|
||||
gfx_rapi->upload_texture(tex_upload_buffer, width, height, gen_mipmaps);
|
||||
gfx_rapi->upload_texture(tex_upload_buffer, width, height);
|
||||
// DumpTexture(loaded_texture.otr_path, rgba32_buf, width, height);
|
||||
}
|
||||
|
||||
static void import_texture_ia16(int tile, const LoadedTexture& loaded_texture, bool gen_mipmaps) {
|
||||
static void import_texture_ia16(int tile, const LoadedTexture& loaded_texture, bool importReplacement) {
|
||||
const RawTexMetadata* metadata = &loaded_texture.raw_tex_metadata;
|
||||
const uint8_t* addr = loaded_texture.addr;
|
||||
const uint32_t size_bytes = loaded_texture.size_bytes;
|
||||
@@ -736,11 +714,11 @@ static void import_texture_ia16(int tile, const LoadedTexture& loaded_texture, b
|
||||
const uint32_t width = rdp.texture_tile[tile].line_size_bytes / 2;
|
||||
const uint32_t height = size_bytes / rdp.texture_tile[tile].line_size_bytes;
|
||||
|
||||
gfx_rapi->upload_texture(tex_upload_buffer, width, height, gen_mipmaps);
|
||||
gfx_rapi->upload_texture(tex_upload_buffer, width, height);
|
||||
// DumpTexture(loaded_texture.otr_path, rgba32_buf, width, height);
|
||||
}
|
||||
|
||||
static void import_texture_i4(int tile, const LoadedTexture& loaded_texture, bool gen_mipmaps) {
|
||||
static void import_texture_i4(int tile, const LoadedTexture& loaded_texture, bool importReplacement) {
|
||||
const RawTexMetadata* metadata = &loaded_texture.raw_tex_metadata;
|
||||
const uint8_t* addr = loaded_texture.addr;
|
||||
const uint32_t size_bytes = loaded_texture.size_bytes;
|
||||
@@ -763,11 +741,11 @@ static void import_texture_i4(int tile, const LoadedTexture& loaded_texture, boo
|
||||
const uint32_t width = rdp.texture_tile[tile].line_size_bytes * 2;
|
||||
const uint32_t height = size_bytes / rdp.texture_tile[tile].line_size_bytes;
|
||||
|
||||
gfx_rapi->upload_texture(tex_upload_buffer, width, height, gen_mipmaps);
|
||||
gfx_rapi->upload_texture(tex_upload_buffer, width, height);
|
||||
// DumpTexture(loaded_texture.otr_path, rgba32_buf, width, height);
|
||||
}
|
||||
|
||||
static void import_texture_i8(int tile, const LoadedTexture& loaded_texture, bool gen_mipmaps) {
|
||||
static void import_texture_i8(int tile, const LoadedTexture& loaded_texture, bool importReplacement) {
|
||||
const RawTexMetadata* metadata = &loaded_texture.raw_tex_metadata;
|
||||
const uint8_t* addr = loaded_texture.addr;
|
||||
const uint32_t size_bytes = loaded_texture.size_bytes;
|
||||
@@ -788,7 +766,7 @@ static void import_texture_i8(int tile, const LoadedTexture& loaded_texture, boo
|
||||
const uint32_t width = rdp.texture_tile[tile].line_size_bytes;
|
||||
const uint32_t height = size_bytes / rdp.texture_tile[tile].line_size_bytes;
|
||||
|
||||
gfx_rapi->upload_texture(tex_upload_buffer, width, height, gen_mipmaps);
|
||||
gfx_rapi->upload_texture(tex_upload_buffer, width, height);
|
||||
// DumpTexture(loaded_texture.otr_path, rgba32_buf, width, height);
|
||||
}
|
||||
|
||||
@@ -813,8 +791,8 @@ static inline void palette_to_rgba32(const uint16_t palentry, uint8_t *rgba32_bu
|
||||
}
|
||||
}
|
||||
|
||||
static void import_texture_ci4(int tile, const LoadedTexture& loaded_texture, bool gen_mipmaps) {
|
||||
const RawTexMetadata* metadata = &loaded_texture.raw_tex_metadata;
|
||||
static void import_texture_ci4(int tile, const LoadedTexture& loaded_texture, bool importReplacement) {
|
||||
const RawTexMetadata* metadata = &loaded_texture.raw_tex_metadata;
|
||||
const uint8_t* addr = loaded_texture.addr;
|
||||
const uint32_t size_bytes = loaded_texture.size_bytes;
|
||||
const uint32_t full_image_line_size_bytes =
|
||||
@@ -838,11 +816,11 @@ static void import_texture_ci4(int tile, const LoadedTexture& loaded_texture, bo
|
||||
const uint32_t width = result_line_size * 2;
|
||||
const uint32_t height = size_bytes / result_line_size;
|
||||
|
||||
gfx_rapi->upload_texture(tex_upload_buffer, width, height, gen_mipmaps);
|
||||
gfx_rapi->upload_texture(tex_upload_buffer, width, height);
|
||||
}
|
||||
|
||||
static void import_texture_ci8(int tile, const LoadedTexture& loaded_texture, bool gen_mipmaps) {
|
||||
const RawTexMetadata* metadata = &loaded_texture.raw_tex_metadata;
|
||||
static void import_texture_ci8(int tile, const LoadedTexture& loaded_texture, bool importReplacement) {
|
||||
const RawTexMetadata* metadata = &loaded_texture.raw_tex_metadata;
|
||||
const uint8_t* addr = loaded_texture.addr;
|
||||
const uint32_t size_bytes = loaded_texture.size_bytes;
|
||||
const uint32_t full_image_line_size_bytes =
|
||||
@@ -864,7 +842,8 @@ static void import_texture_ci8(int tile, const LoadedTexture& loaded_texture, bo
|
||||
const uint32_t width = result_line_size;
|
||||
const uint32_t height = size_bytes / result_line_size;
|
||||
|
||||
gfx_rapi->upload_texture(tex_upload_buffer, width, height, gen_mipmaps);
|
||||
gfx_rapi->upload_texture(tex_upload_buffer, width, height);
|
||||
// DumpTexture(loaded_texture.otr_path, rgba32_buf, width, height);
|
||||
}
|
||||
|
||||
static void import_texture(int i, int tile, bool importReplacement) {
|
||||
@@ -906,35 +885,35 @@ static void import_texture(int i, int tile, bool importReplacement) {
|
||||
|
||||
if (fmt == G_IM_FMT_RGBA) {
|
||||
if (siz == G_IM_SIZ_16b) {
|
||||
import_texture_rgba16(tile, loaded_texture, rdp.tex_lod);
|
||||
import_texture_rgba16(tile, loaded_texture, importReplacement);
|
||||
} else if (siz == G_IM_SIZ_32b) {
|
||||
import_texture_rgba32(tile, loaded_texture, rdp.tex_lod);
|
||||
import_texture_rgba32(tile, loaded_texture, importReplacement);
|
||||
} else {
|
||||
sysFatalError("Bad size for RGBA texture in tile %d: %02x", tile, siz);
|
||||
}
|
||||
} else if (fmt == G_IM_FMT_IA) {
|
||||
if (siz == G_IM_SIZ_4b) {
|
||||
import_texture_ia4(tile, loaded_texture, rdp.tex_lod);
|
||||
import_texture_ia4(tile, loaded_texture, importReplacement);
|
||||
} else if (siz == G_IM_SIZ_8b) {
|
||||
import_texture_ia8(tile, loaded_texture, rdp.tex_lod);
|
||||
import_texture_ia8(tile, loaded_texture, importReplacement);
|
||||
} else if (siz == G_IM_SIZ_16b) {
|
||||
import_texture_ia16(tile, loaded_texture, rdp.tex_lod);
|
||||
import_texture_ia16(tile, loaded_texture, importReplacement);
|
||||
} else {
|
||||
sysFatalError("Bad size for IA texture in tile %d: %02x", tile, siz);
|
||||
}
|
||||
} else if (fmt == G_IM_FMT_CI) {
|
||||
if (siz == G_IM_SIZ_4b) {
|
||||
import_texture_ci4(tile, loaded_texture, rdp.tex_lod);
|
||||
import_texture_ci4(tile, loaded_texture, importReplacement);
|
||||
} else if (siz == G_IM_SIZ_8b) {
|
||||
import_texture_ci8(tile, loaded_texture, rdp.tex_lod);
|
||||
import_texture_ci8(tile, loaded_texture, importReplacement);
|
||||
} else {
|
||||
sysFatalError("Bad size for CI texture in tile %d: %02x", tile, siz);
|
||||
}
|
||||
} else if (fmt == G_IM_FMT_I) {
|
||||
if (siz == G_IM_SIZ_4b) {
|
||||
import_texture_i4(tile, loaded_texture, rdp.tex_lod);
|
||||
import_texture_i4(tile, loaded_texture, importReplacement);
|
||||
} else if (siz == G_IM_SIZ_8b) {
|
||||
import_texture_i8(tile, loaded_texture, rdp.tex_lod);
|
||||
import_texture_i8(tile, loaded_texture, importReplacement);
|
||||
} else {
|
||||
sysFatalError("Bad size for I texture in tile %d: %02x", tile, siz);
|
||||
}
|
||||
@@ -1404,7 +1383,7 @@ static void gfx_sp_tri1(uint8_t vtx1_idx, uint8_t vtx2_idx, uint8_t vtx3_idx, bo
|
||||
if (linear_filter != rendering_state.textures[i]->second.linear_filter ||
|
||||
cms != rendering_state.textures[i]->second.cms || cmt != rendering_state.textures[i]->second.cmt) {
|
||||
gfx_flush();
|
||||
gfx_rapi->set_sampler_parameters(i, linear_filter, cms, cmt, rdp.tex_lod);
|
||||
gfx_rapi->set_sampler_parameters(i, linear_filter, cms, cmt);
|
||||
rendering_state.textures[i]->second.linear_filter = linear_filter;
|
||||
rendering_state.textures[i]->second.cms = cms;
|
||||
rendering_state.textures[i]->second.cmt = cmt;
|
||||
@@ -1662,18 +1641,11 @@ static void gfx_sp_extra_geometry_mode(uint32_t clear, uint32_t set) {
|
||||
|
||||
static void gfx_adjust_viewport_or_scissor(XYWidthHeight* area, bool preserve_aspect = false) {
|
||||
// HACK: assume all target framebuffers have the same aspect
|
||||
// Use floor/ceil to ensure scissor fully contains the logical region
|
||||
// and prevents sub-pixel gaps at viewport edges
|
||||
float x1 = area->x * RATIO_X;
|
||||
float y1 = (SCREEN_HEIGHT - area->y) * RATIO_Y;
|
||||
float x2 = (area->x + area->width) * RATIO_X;
|
||||
float y2 = (SCREEN_HEIGHT - area->y + area->height) * RATIO_Y;
|
||||
|
||||
area->x = std::floor(x1);
|
||||
area->y = std::floor(y1);
|
||||
area->width = std::ceil(x2) - area->x;
|
||||
area->height = std::ceil(y2) - area->y;
|
||||
|
||||
area->width *= RATIO_X;
|
||||
area->x *= RATIO_X;
|
||||
area->height *= RATIO_Y;
|
||||
area->y = SCREEN_HEIGHT - area->y;
|
||||
area->y *= RATIO_Y;
|
||||
if (preserve_aspect) {
|
||||
// preserve native aspect ratio
|
||||
const float ratio = gfx_current_native_aspect / gfx_current_dimensions.aspect_ratio;
|
||||
@@ -2720,7 +2692,7 @@ extern "C" void gfx_set_target_fps(int fps) {
|
||||
gfx_wapi->set_target_fps(fps);
|
||||
}
|
||||
|
||||
extern "C" void reset_texture_state() {
|
||||
extern "C" void gfx_set_texture_filter(enum FilteringMode mode) {
|
||||
gfx_texture_cache_clear();
|
||||
if (rendering_state.shader_program) {
|
||||
gfx_rapi->unload_shader(rendering_state.shader_program);
|
||||
@@ -2729,18 +2701,9 @@ extern "C" void reset_texture_state() {
|
||||
gfx_rapi->clear_shaders();
|
||||
color_combiner_pool.clear();
|
||||
prev_combiner = color_combiner_pool.end();
|
||||
}
|
||||
|
||||
extern "C" void gfx_set_texture_filter(enum FilteringMode mode) {
|
||||
reset_texture_state();
|
||||
gfx_rapi->set_texture_filter(mode);
|
||||
}
|
||||
|
||||
extern "C" void gfx_set_mipmap_filter(enum MipmapFilteringMode mode) {
|
||||
reset_texture_state();
|
||||
gfx_rapi->set_mipmap_filter(mode);
|
||||
}
|
||||
|
||||
extern "C" int gfx_create_framebuffer(uint32_t width, uint32_t height, int upscale, int autoresize) {
|
||||
int fb = gfx_rapi->create_framebuffer();
|
||||
gfx_resize_framebuffer(fb, width, height, upscale, autoresize);
|
||||
|
||||
@@ -13,7 +13,6 @@ struct GfxClipParameters {
|
||||
};
|
||||
|
||||
enum FilteringMode { FILTER_NONE, FILTER_LINEAR, FILTER_THREE_POINT };
|
||||
enum MipmapFilteringMode { MIPMAP_DISABLED, MIPMAP_NEAREST, MIPMAP_LINEAR };
|
||||
|
||||
struct GfxRenderingAPI {
|
||||
const char* (*get_name)(void);
|
||||
@@ -27,8 +26,8 @@ struct GfxRenderingAPI {
|
||||
void (*clear_shaders)(void);
|
||||
uint32_t (*new_texture)(void);
|
||||
void (*select_texture)(int tile, uint32_t texture_id, bool linear_filter);
|
||||
void (*upload_texture)(const uint8_t* rgba32_buf, uint32_t width, uint32_t height, bool gen_mipmaps);
|
||||
void (*set_sampler_parameters)(int sampler, bool linear_filter, uint32_t cms, uint32_t cmt, bool mipmaps);
|
||||
void (*upload_texture)(const uint8_t* rgba32_buf, uint32_t width, uint32_t height);
|
||||
void (*set_sampler_parameters)(int sampler, bool linear_filter, uint32_t cms, uint32_t cmt);
|
||||
void (*set_depth_mode)(bool depth_test, bool depth_update, bool depth_compare, bool depth_source_prim, uint16_t zmode);
|
||||
void (*set_depth_range)(float znear, float zfar);
|
||||
void (*set_viewport)(int x, int y, int width, int height);
|
||||
@@ -53,9 +52,6 @@ struct GfxRenderingAPI {
|
||||
void (*delete_texture)(uint32_t texID);
|
||||
void (*set_texture_filter)(enum FilteringMode mode);
|
||||
enum FilteringMode (*get_texture_filter)(void);
|
||||
void (*set_mipmap_filter)(enum MipmapFilteringMode mode);
|
||||
void (*set_anisotropy_level)(int);
|
||||
int (*get_max_anisotropy_level)(void);
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -108,8 +108,8 @@ static void gfx_sdl_init(const struct GfxWindowInitSettings *set) {
|
||||
int posY = set->y;
|
||||
int display_in_use = SDL_GetWindowDisplayIndex(wnd);
|
||||
if (display_in_use < 0) { // Fallback to default if out of bounds
|
||||
posX = SDL_WINDOWPOS_UNDEFINED;
|
||||
posY = SDL_WINDOWPOS_UNDEFINED;
|
||||
posX = 100;
|
||||
posY = 100;
|
||||
}
|
||||
|
||||
if (set->centered) {
|
||||
|
||||
+3
-10
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
|
||||
OpenGL, OpenGL ES loader generated by glad 0.1.36 on Wed Oct 8 13:10:56 2025.
|
||||
OpenGL, OpenGL ES loader generated by glad 0.1.36 on Wed Nov 20 09:57:47 2024.
|
||||
|
||||
Language/Generator: C/C++
|
||||
Specification: gl
|
||||
@@ -10,7 +10,6 @@
|
||||
GL_APPLE_framebuffer_multisample,
|
||||
GL_ARB_depth_clamp,
|
||||
GL_ARB_framebuffer_object,
|
||||
GL_ARB_texture_filter_anisotropic,
|
||||
GL_ARB_texture_mirror_clamp_to_edge,
|
||||
GL_ARB_vertex_array_object,
|
||||
GL_EXT_depth_clamp,
|
||||
@@ -18,7 +17,6 @@
|
||||
GL_EXT_framebuffer_multisample,
|
||||
GL_EXT_framebuffer_object,
|
||||
GL_EXT_gpu_shader4,
|
||||
GL_EXT_texture_filter_anisotropic,
|
||||
GL_EXT_texture_mirror_clamp_to_edge,
|
||||
GL_KHR_debug,
|
||||
GL_NV_depth_clamp,
|
||||
@@ -29,9 +27,9 @@
|
||||
Reproducible: False
|
||||
|
||||
Commandline:
|
||||
--profile="core" --api="gl=4.1,gles2=3.0" --generator="c" --spec="gl" --no-loader --local-files --extensions="GL_APPLE_framebuffer_multisample,GL_ARB_depth_clamp,GL_ARB_framebuffer_object,GL_ARB_texture_filter_anisotropic,GL_ARB_texture_mirror_clamp_to_edge,GL_ARB_vertex_array_object,GL_EXT_depth_clamp,GL_EXT_framebuffer_blit,GL_EXT_framebuffer_multisample,GL_EXT_framebuffer_object,GL_EXT_gpu_shader4,GL_EXT_texture_filter_anisotropic,GL_EXT_texture_mirror_clamp_to_edge,GL_KHR_debug,GL_NV_depth_clamp,GL_NV_framebuffer_multisample"
|
||||
--profile="core" --api="gl=4.1,gles2=3.0" --generator="c" --spec="gl" --no-loader --local-files --extensions="GL_APPLE_framebuffer_multisample,GL_ARB_depth_clamp,GL_ARB_framebuffer_object,GL_ARB_texture_mirror_clamp_to_edge,GL_ARB_vertex_array_object,GL_EXT_depth_clamp,GL_EXT_framebuffer_blit,GL_EXT_framebuffer_multisample,GL_EXT_framebuffer_object,GL_EXT_gpu_shader4,GL_EXT_texture_mirror_clamp_to_edge,GL_KHR_debug,GL_NV_depth_clamp,GL_NV_framebuffer_multisample"
|
||||
Online:
|
||||
https://glad.dav1d.de/#profile=core&language=c&specification=gl&api=gl%3D4.1&api=gles2%3D3.0&extensions=GL_APPLE_framebuffer_multisample&extensions=GL_ARB_depth_clamp&extensions=GL_ARB_framebuffer_object&extensions=GL_ARB_texture_filter_anisotropic&extensions=GL_ARB_texture_mirror_clamp_to_edge&extensions=GL_ARB_vertex_array_object&extensions=GL_EXT_depth_clamp&extensions=GL_EXT_framebuffer_blit&extensions=GL_EXT_framebuffer_multisample&extensions=GL_EXT_framebuffer_object&extensions=GL_EXT_gpu_shader4&extensions=GL_EXT_texture_filter_anisotropic&extensions=GL_EXT_texture_mirror_clamp_to_edge&extensions=GL_KHR_debug&extensions=GL_NV_depth_clamp&extensions=GL_NV_framebuffer_multisample
|
||||
https://glad.dav1d.de/#profile=core&language=c&specification=gl&api=gl%3D4.1&api=gles2%3D3.0&extensions=GL_APPLE_framebuffer_multisample&extensions=GL_ARB_depth_clamp&extensions=GL_ARB_framebuffer_object&extensions=GL_ARB_texture_mirror_clamp_to_edge&extensions=GL_ARB_vertex_array_object&extensions=GL_EXT_depth_clamp&extensions=GL_EXT_framebuffer_blit&extensions=GL_EXT_framebuffer_multisample&extensions=GL_EXT_framebuffer_object&extensions=GL_EXT_gpu_shader4&extensions=GL_EXT_texture_mirror_clamp_to_edge&extensions=GL_KHR_debug&extensions=GL_NV_depth_clamp&extensions=GL_NV_framebuffer_multisample
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
@@ -670,7 +668,6 @@ PFNGLWAITSYNCPROC glad_glWaitSync = NULL;
|
||||
int GLAD_GL_APPLE_framebuffer_multisample = 0;
|
||||
int GLAD_GL_ARB_depth_clamp = 0;
|
||||
int GLAD_GL_ARB_framebuffer_object = 0;
|
||||
int GLAD_GL_ARB_texture_filter_anisotropic = 0;
|
||||
int GLAD_GL_ARB_texture_mirror_clamp_to_edge = 0;
|
||||
int GLAD_GL_ARB_vertex_array_object = 0;
|
||||
int GLAD_GL_EXT_depth_clamp = 0;
|
||||
@@ -678,7 +675,6 @@ int GLAD_GL_EXT_framebuffer_blit = 0;
|
||||
int GLAD_GL_EXT_framebuffer_multisample = 0;
|
||||
int GLAD_GL_EXT_framebuffer_object = 0;
|
||||
int GLAD_GL_EXT_gpu_shader4 = 0;
|
||||
int GLAD_GL_EXT_texture_filter_anisotropic = 0;
|
||||
int GLAD_GL_EXT_texture_mirror_clamp_to_edge = 0;
|
||||
int GLAD_GL_KHR_debug = 0;
|
||||
int GLAD_GL_NV_depth_clamp = 0;
|
||||
@@ -1439,14 +1435,12 @@ static int find_extensionsGL(void) {
|
||||
if (!get_exts()) return 0;
|
||||
GLAD_GL_ARB_depth_clamp = has_ext("GL_ARB_depth_clamp");
|
||||
GLAD_GL_ARB_framebuffer_object = has_ext("GL_ARB_framebuffer_object");
|
||||
GLAD_GL_ARB_texture_filter_anisotropic = has_ext("GL_ARB_texture_filter_anisotropic");
|
||||
GLAD_GL_ARB_texture_mirror_clamp_to_edge = has_ext("GL_ARB_texture_mirror_clamp_to_edge");
|
||||
GLAD_GL_ARB_vertex_array_object = has_ext("GL_ARB_vertex_array_object");
|
||||
GLAD_GL_EXT_framebuffer_blit = has_ext("GL_EXT_framebuffer_blit");
|
||||
GLAD_GL_EXT_framebuffer_multisample = has_ext("GL_EXT_framebuffer_multisample");
|
||||
GLAD_GL_EXT_framebuffer_object = has_ext("GL_EXT_framebuffer_object");
|
||||
GLAD_GL_EXT_gpu_shader4 = has_ext("GL_EXT_gpu_shader4");
|
||||
GLAD_GL_EXT_texture_filter_anisotropic = has_ext("GL_EXT_texture_filter_anisotropic");
|
||||
GLAD_GL_KHR_debug = has_ext("GL_KHR_debug");
|
||||
GLAD_GL_NV_depth_clamp = has_ext("GL_NV_depth_clamp");
|
||||
free_exts();
|
||||
@@ -1806,7 +1800,6 @@ static int find_extensionsGLES2(void) {
|
||||
if (!get_exts()) return 0;
|
||||
GLAD_GL_APPLE_framebuffer_multisample = has_ext("GL_APPLE_framebuffer_multisample");
|
||||
GLAD_GL_EXT_depth_clamp = has_ext("GL_EXT_depth_clamp");
|
||||
GLAD_GL_EXT_texture_filter_anisotropic = has_ext("GL_EXT_texture_filter_anisotropic");
|
||||
GLAD_GL_EXT_texture_mirror_clamp_to_edge = has_ext("GL_EXT_texture_mirror_clamp_to_edge");
|
||||
GLAD_GL_KHR_debug = has_ext("GL_KHR_debug");
|
||||
GLAD_GL_NV_framebuffer_multisample = has_ext("GL_NV_framebuffer_multisample");
|
||||
|
||||
+3
-21
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
|
||||
OpenGL, OpenGL ES loader generated by glad 0.1.36 on Wed Oct 8 13:10:56 2025.
|
||||
OpenGL, OpenGL ES loader generated by glad 0.1.36 on Wed Nov 20 09:57:47 2024.
|
||||
|
||||
Language/Generator: C/C++
|
||||
Specification: gl
|
||||
@@ -10,7 +10,6 @@
|
||||
GL_APPLE_framebuffer_multisample,
|
||||
GL_ARB_depth_clamp,
|
||||
GL_ARB_framebuffer_object,
|
||||
GL_ARB_texture_filter_anisotropic,
|
||||
GL_ARB_texture_mirror_clamp_to_edge,
|
||||
GL_ARB_vertex_array_object,
|
||||
GL_EXT_depth_clamp,
|
||||
@@ -18,7 +17,6 @@
|
||||
GL_EXT_framebuffer_multisample,
|
||||
GL_EXT_framebuffer_object,
|
||||
GL_EXT_gpu_shader4,
|
||||
GL_EXT_texture_filter_anisotropic,
|
||||
GL_EXT_texture_mirror_clamp_to_edge,
|
||||
GL_KHR_debug,
|
||||
GL_NV_depth_clamp,
|
||||
@@ -29,9 +27,9 @@
|
||||
Reproducible: False
|
||||
|
||||
Commandline:
|
||||
--profile="core" --api="gl=4.1,gles2=3.0" --generator="c" --spec="gl" --no-loader --local-files --extensions="GL_APPLE_framebuffer_multisample,GL_ARB_depth_clamp,GL_ARB_framebuffer_object,GL_ARB_texture_filter_anisotropic,GL_ARB_texture_mirror_clamp_to_edge,GL_ARB_vertex_array_object,GL_EXT_depth_clamp,GL_EXT_framebuffer_blit,GL_EXT_framebuffer_multisample,GL_EXT_framebuffer_object,GL_EXT_gpu_shader4,GL_EXT_texture_filter_anisotropic,GL_EXT_texture_mirror_clamp_to_edge,GL_KHR_debug,GL_NV_depth_clamp,GL_NV_framebuffer_multisample"
|
||||
--profile="core" --api="gl=4.1,gles2=3.0" --generator="c" --spec="gl" --no-loader --local-files --extensions="GL_APPLE_framebuffer_multisample,GL_ARB_depth_clamp,GL_ARB_framebuffer_object,GL_ARB_texture_mirror_clamp_to_edge,GL_ARB_vertex_array_object,GL_EXT_depth_clamp,GL_EXT_framebuffer_blit,GL_EXT_framebuffer_multisample,GL_EXT_framebuffer_object,GL_EXT_gpu_shader4,GL_EXT_texture_mirror_clamp_to_edge,GL_KHR_debug,GL_NV_depth_clamp,GL_NV_framebuffer_multisample"
|
||||
Online:
|
||||
https://glad.dav1d.de/#profile=core&language=c&specification=gl&api=gl%3D4.1&api=gles2%3D3.0&extensions=GL_APPLE_framebuffer_multisample&extensions=GL_ARB_depth_clamp&extensions=GL_ARB_framebuffer_object&extensions=GL_ARB_texture_filter_anisotropic&extensions=GL_ARB_texture_mirror_clamp_to_edge&extensions=GL_ARB_vertex_array_object&extensions=GL_EXT_depth_clamp&extensions=GL_EXT_framebuffer_blit&extensions=GL_EXT_framebuffer_multisample&extensions=GL_EXT_framebuffer_object&extensions=GL_EXT_gpu_shader4&extensions=GL_EXT_texture_filter_anisotropic&extensions=GL_EXT_texture_mirror_clamp_to_edge&extensions=GL_KHR_debug&extensions=GL_NV_depth_clamp&extensions=GL_NV_framebuffer_multisample
|
||||
https://glad.dav1d.de/#profile=core&language=c&specification=gl&api=gl%3D4.1&api=gles2%3D3.0&extensions=GL_APPLE_framebuffer_multisample&extensions=GL_ARB_depth_clamp&extensions=GL_ARB_framebuffer_object&extensions=GL_ARB_texture_mirror_clamp_to_edge&extensions=GL_ARB_vertex_array_object&extensions=GL_EXT_depth_clamp&extensions=GL_EXT_framebuffer_blit&extensions=GL_EXT_framebuffer_multisample&extensions=GL_EXT_framebuffer_object&extensions=GL_EXT_gpu_shader4&extensions=GL_EXT_texture_mirror_clamp_to_edge&extensions=GL_KHR_debug&extensions=GL_NV_depth_clamp&extensions=GL_NV_framebuffer_multisample
|
||||
*/
|
||||
|
||||
|
||||
@@ -2723,8 +2721,6 @@ GLAPI PFNGLGETINTERNALFORMATIVPROC glad_glGetInternalformativ;
|
||||
#define glGetInternalformativ glad_glGetInternalformativ
|
||||
#endif
|
||||
#define GL_INDEX 0x8222
|
||||
#define GL_TEXTURE_MAX_ANISOTROPY 0x84FE
|
||||
#define GL_MAX_TEXTURE_MAX_ANISOTROPY 0x84FF
|
||||
#define GL_MIRROR_CLAMP_TO_EDGE 0x8743
|
||||
#define GL_READ_FRAMEBUFFER_EXT 0x8CA8
|
||||
#define GL_DRAW_FRAMEBUFFER_EXT 0x8CA9
|
||||
@@ -2812,8 +2808,6 @@ GLAPI PFNGLGETINTERNALFORMATIVPROC glad_glGetInternalformativ;
|
||||
#define GL_MIN_PROGRAM_TEXEL_OFFSET_EXT 0x8904
|
||||
#define GL_MAX_PROGRAM_TEXEL_OFFSET_EXT 0x8905
|
||||
#define GL_VERTEX_ATTRIB_ARRAY_INTEGER_EXT 0x88FD
|
||||
#define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE
|
||||
#define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 0x84FF
|
||||
#define GL_DEBUG_OUTPUT_SYNCHRONOUS 0x8242
|
||||
#define GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH 0x8243
|
||||
#define GL_DEBUG_CALLBACK_FUNCTION 0x8244
|
||||
@@ -2916,10 +2910,6 @@ GLAPI int GLAD_GL_ARB_depth_clamp;
|
||||
#define GL_ARB_framebuffer_object 1
|
||||
GLAPI int GLAD_GL_ARB_framebuffer_object;
|
||||
#endif
|
||||
#ifndef GL_ARB_texture_filter_anisotropic
|
||||
#define GL_ARB_texture_filter_anisotropic 1
|
||||
GLAPI int GLAD_GL_ARB_texture_filter_anisotropic;
|
||||
#endif
|
||||
#ifndef GL_ARB_texture_mirror_clamp_to_edge
|
||||
#define GL_ARB_texture_mirror_clamp_to_edge 1
|
||||
GLAPI int GLAD_GL_ARB_texture_mirror_clamp_to_edge;
|
||||
@@ -3103,10 +3093,6 @@ typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIUIVEXTPROC)(GLuint index, GLenum pn
|
||||
GLAPI PFNGLGETVERTEXATTRIBIUIVEXTPROC glad_glGetVertexAttribIuivEXT;
|
||||
#define glGetVertexAttribIuivEXT glad_glGetVertexAttribIuivEXT
|
||||
#endif
|
||||
#ifndef GL_EXT_texture_filter_anisotropic
|
||||
#define GL_EXT_texture_filter_anisotropic 1
|
||||
GLAPI int GLAD_GL_EXT_texture_filter_anisotropic;
|
||||
#endif
|
||||
#ifndef GL_KHR_debug
|
||||
#define GL_KHR_debug 1
|
||||
GLAPI int GLAD_GL_KHR_debug;
|
||||
@@ -3195,10 +3181,6 @@ GLAPI PFNGLRESOLVEMULTISAMPLEFRAMEBUFFERAPPLEPROC glad_glResolveMultisampleFrame
|
||||
#define GL_EXT_depth_clamp 1
|
||||
GLAPI int GLAD_GL_EXT_depth_clamp;
|
||||
#endif
|
||||
#ifndef GL_EXT_texture_filter_anisotropic
|
||||
#define GL_EXT_texture_filter_anisotropic 1
|
||||
GLAPI int GLAD_GL_EXT_texture_filter_anisotropic;
|
||||
#endif
|
||||
#ifndef GL_EXT_texture_mirror_clamp_to_edge
|
||||
#define GL_EXT_texture_mirror_clamp_to_edge 1
|
||||
GLAPI int GLAD_GL_EXT_texture_mirror_clamp_to_edge;
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
#ifndef _IN_CONSOLE_H
|
||||
#define _IN_CONSOLE_H
|
||||
|
||||
#include <PR/ultratypes.h>
|
||||
#include "types.h"
|
||||
|
||||
void conInit(void);
|
||||
Gfx *conRender(Gfx *gdl);
|
||||
void conTick(void);
|
||||
void conPrint(s32 showmsg, const char *s);
|
||||
void conPrintf(s32 showmsg, const char *fmt, ...);
|
||||
void conPrintLn(s32 showmsg, const char *s);
|
||||
s32 conIsOpen(void);
|
||||
|
||||
#endif
|
||||
Vendored
+5100
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,163 @@
|
||||
#ifndef _IN_NET_H
|
||||
#define _IN_NET_H
|
||||
|
||||
#include "types.h"
|
||||
#include "constants.h"
|
||||
#include "net/netbuf.h"
|
||||
|
||||
#define NET_PROTOCOL_VER 12
|
||||
|
||||
#define NET_QUERY_MAGIC "PDQM\x01"
|
||||
|
||||
#define NET_MAX_CLIENTS MAX_PLAYERS
|
||||
#define NET_MAX_NAME MAX_PLAYERNAME
|
||||
#define NET_MAX_ADDR 256
|
||||
|
||||
#define NET_BUFSIZE 1440
|
||||
|
||||
#define NET_DEFAULT_PORT 27100
|
||||
|
||||
#define NET_NULL_CLIENT 0xFF
|
||||
#define NET_NULL_PROP 0
|
||||
|
||||
#define NETCHAN_DEFAULT 0
|
||||
#define NETCHAN_CONTROL 1
|
||||
#define NETCHAN_COUNT 2
|
||||
|
||||
#define DISCONNECT_UNKNOWN 0
|
||||
#define DISCONNECT_SHUTDOWN 1
|
||||
#define DISCONNECT_VERSION 2
|
||||
#define DISCONNECT_KICKED 3
|
||||
#define DISCONNECT_BANNED 4
|
||||
#define DISCONNECT_TIMEOUT 5
|
||||
#define DISCONNECT_FULL 6
|
||||
#define DISCONNECT_LATE 7
|
||||
#define DISCONNECT_FILES 8
|
||||
|
||||
#define CLSTATE_DISCONNECTED 0
|
||||
#define CLSTATE_CONNECTING 1
|
||||
#define CLSTATE_AUTH 2
|
||||
#define CLSTATE_LOBBY 3
|
||||
#define CLSTATE_GAME 4
|
||||
|
||||
#define UCMD_FIRE (1 << 0)
|
||||
#define UCMD_ACTIVATE (1 << 1)
|
||||
#define UCMD_RELOAD (1 << 2)
|
||||
#define UCMD_AIMMODE (1 << 3)
|
||||
#define UCMD_DUCK (1 << 4)
|
||||
#define UCMD_SQUAT (1 << 5)
|
||||
#define UCMD_ZOOMIN (1 << 6)
|
||||
#define UCMD_SELECT (1 << 7)
|
||||
#define UCMD_SELECT_DUAL (1 << 8)
|
||||
#define UCMD_EYESSHUT (1 << 9)
|
||||
#define UCMD_SECONDARY (1 << 10)
|
||||
#define UCMD_RESPAWN (1 << 27)
|
||||
#define UCMD_CHAT (1 << 28)
|
||||
#define UCMD_IMPORTANT_MASK (UCMD_FIRE | UCMD_ACTIVATE | UCMD_RELOAD | UCMD_AIMMODE | UCMD_SELECT | UCMD_SELECT_DUAL)
|
||||
#define UCMD_FL_FORCEPOS (1 << 29)
|
||||
#define UCMD_FL_FORCEANGLE (1 << 30)
|
||||
#define UCMD_FL_FORCEGROUND (1 << 31)
|
||||
#define UCMD_FL_FORCEMASK (UCMD_FL_FORCEPOS | UCMD_FL_FORCEANGLE | UCMD_FL_FORCEGROUND)
|
||||
|
||||
struct netplayermove {
|
||||
u32 tick; // g_NetTIck value when this struct was written; if 0, this struct is invalid
|
||||
u32 ucmd; // player commands (UCMD_)
|
||||
f32 leanofs; // analog lean value (-1 .. 1; equal to player->swaytarget / 75.f)
|
||||
f32 crouchofs; // analog crouch value (-90 for SQUAT, 0 for STAND; player->crouchofs)
|
||||
f32 zoomfov; // manual zoom fov for the current gun; synced only if UCMD_AIMING is set
|
||||
f32 movespeed[2]; // move inputs, [0] is forward, [1] is sideways; used mostly for animation
|
||||
f32 angles[2]; // view angles, [0] is theta, [1] is verta
|
||||
f32 crosspos[2]; // crosshair position in aiming mode; normalized to default aspect ratio
|
||||
s8 weaponnum; // switch to this weapon if UCMD_SELECT is set
|
||||
struct coord pos; // player position at g_NetTick == tick
|
||||
};
|
||||
|
||||
struct netclient {
|
||||
struct _ENetPeer *peer;
|
||||
u32 id; // remote client number, server is always 0, even on clients
|
||||
u32 state; // CLSTATE_
|
||||
u32 flags; // CLFLAG_
|
||||
|
||||
struct {
|
||||
char name[NET_MAX_NAME];
|
||||
u16 options;
|
||||
u8 headnum;
|
||||
u8 bodynum;
|
||||
u8 team;
|
||||
f32 fovy;
|
||||
f32 fovzoommult;
|
||||
} settings;
|
||||
|
||||
struct mpplayerconfig *config;
|
||||
struct player *player;
|
||||
u8 playernum;
|
||||
|
||||
struct netplayermove outmove[2]; // last 2 outgoing player inputs, newest one first
|
||||
struct netplayermove inmove[2]; // last 2 incoming player inputs, newest one first
|
||||
u32 inmovetick; // last inmove tick which was applied to the player
|
||||
u32 outmoveack; // last acked outmove tick
|
||||
u32 forcetick; // tick on which the client's position was forced, or 0 if not forcing
|
||||
u32 lerpticks; // how many ticks we've been lerping the position
|
||||
|
||||
struct netbuf out; // outbound messages are written here, except broadcasts
|
||||
struct netbuf in; // incoming packets are fed here
|
||||
|
||||
u8 out_data[NET_BUFSIZE]; // buffer for out
|
||||
};
|
||||
|
||||
extern s32 g_NetMode;
|
||||
|
||||
extern s32 g_NetJoinLatch;
|
||||
extern s32 g_NetHostLatch;
|
||||
|
||||
// net frame, ticks at 60 fps, starts at 0 when the server is started
|
||||
extern u32 g_NetTick;
|
||||
extern u32 g_NetNextSyncId;
|
||||
|
||||
extern u64 g_NetRngSeeds[2];
|
||||
extern u32 g_NetRngLatch;
|
||||
|
||||
extern u32 g_NetInterpTicks;
|
||||
extern u32 g_NetServerPort;
|
||||
extern char g_NetLastJoinAddr[NET_MAX_ADDR + 1];
|
||||
|
||||
extern s32 g_NetDebugDraw;
|
||||
|
||||
extern s32 g_NetMaxClients;
|
||||
extern s32 g_NetNumClients;
|
||||
extern struct netclient g_NetClients[NET_MAX_CLIENTS + 1]; // last is an extra temporary client
|
||||
extern struct netclient *g_NetLocalClient;
|
||||
|
||||
extern struct netbuf g_NetMsg;
|
||||
extern struct netbuf g_NetMsgRel;
|
||||
|
||||
const char *netFormatClientAddr(const struct netclient *cl);
|
||||
|
||||
void netInit(void);
|
||||
s32 netDisconnect(void);
|
||||
void netStartFrame(void);
|
||||
void netEndFrame(void);
|
||||
|
||||
s32 netStartServer(u16 port, s32 maxclients);
|
||||
s32 netStartClient(const char *addr);
|
||||
|
||||
u32 netSend(struct netclient *dstcl, struct netbuf *buf, const s32 reliable, const s32 chan);
|
||||
|
||||
void netChat(struct netclient *dst, const char *text);
|
||||
void netChatPrintf(struct netclient *dst, const char *fmt, ...);
|
||||
|
||||
void netServerStageStart(void);
|
||||
void netServerStageEnd(void);
|
||||
void netServerKick(struct netclient *cl, const u32 reason);
|
||||
|
||||
struct netclient *netClientForPlayerNum(s32 playernum);
|
||||
|
||||
void netClientSyncRng(void);
|
||||
void netClientSettingsChanged(void);
|
||||
|
||||
void netPlayersAllocate(void);
|
||||
void netSyncIdsAllocate(void);
|
||||
|
||||
Gfx *netDebugRender(Gfx *gdl);
|
||||
|
||||
#endif // _IN_NET_H
|
||||
@@ -0,0 +1,50 @@
|
||||
#ifndef _IN_NETBUF_H
|
||||
#define _IN_NETBUF_H
|
||||
|
||||
#include "types.h"
|
||||
|
||||
struct netbuf {
|
||||
u8 *data;
|
||||
u32 size;
|
||||
u32 rp;
|
||||
u32 wp;
|
||||
u32 error;
|
||||
};
|
||||
|
||||
void netbufStartRead(struct netbuf *buf);
|
||||
void netbufStartReadData(struct netbuf *buf, const void *data, u32 size);
|
||||
s32 netbufReadLeft(const struct netbuf *buf);
|
||||
u32 netbufReadData(struct netbuf *buf, void *out, u32 num);
|
||||
u8 netbufReadU8(struct netbuf *buf);
|
||||
u16 netbufReadU16(struct netbuf *buf);
|
||||
u32 netbufReadU32(struct netbuf *buf);
|
||||
u64 netbufReadU64(struct netbuf *buf);
|
||||
s8 netbufReadS8(struct netbuf *buf);
|
||||
s16 netbufReadS16(struct netbuf *buf);
|
||||
s32 netbufReadS32(struct netbuf *buf);
|
||||
s64 netbufReadS64(struct netbuf *buf);
|
||||
f32 netbufReadF32(struct netbuf *buf);
|
||||
char *netbufReadStr(struct netbuf *buf);
|
||||
u32 netbufReadCoord(struct netbuf *buf, struct coord *out);
|
||||
u32 netbufReadMtxf(struct netbuf *buf, Mtxf *out);
|
||||
u32 netbufReadSkip(struct netbuf *buf, u32 count);
|
||||
|
||||
void netbufStartWrite(struct netbuf *buf);
|
||||
s32 netbufWriteLeft(const struct netbuf *buf);
|
||||
u32 netbufWriteData(struct netbuf *buf, const void *data, u32 num);
|
||||
u32 netbufWriteU8(struct netbuf *buf, const u8 v);
|
||||
u32 netbufWriteU16(struct netbuf *buf, const u16 v);
|
||||
u32 netbufWriteU32(struct netbuf *buf, const u32 v);
|
||||
u32 netbufWriteU64(struct netbuf *buf, const u64 v);
|
||||
u32 netbufWriteS8(struct netbuf *buf, const s8 v);
|
||||
u32 netbufWriteS16(struct netbuf *buf, const s16 v);
|
||||
u32 netbufWriteS32(struct netbuf *buf, const s32 v);
|
||||
u32 netbufWriteS64(struct netbuf *buf, const s64 v);
|
||||
u32 netbufWriteF32(struct netbuf *buf, const f32 v);
|
||||
u32 netbufWriteStr(struct netbuf *buf, const char *v);
|
||||
u32 netbufWriteCoord(struct netbuf *buf, const struct coord *v);
|
||||
u32 netbufWriteMtxf(struct netbuf *buf, const Mtxf *in);
|
||||
|
||||
void netbufReset(struct netbuf *buf);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,10 @@
|
||||
#ifndef _IN_NETENET_H
|
||||
#define _IN_NETENET_H
|
||||
|
||||
#define ENET_NO_PRAGMA_LINK 1
|
||||
#include "external/enet.h"
|
||||
#undef bool
|
||||
#undef near
|
||||
#undef far
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,74 @@
|
||||
#ifndef _IN_NETMSG_H
|
||||
#define _IN_NETMSG_H
|
||||
|
||||
#include <PR/ultratypes.h>
|
||||
#include "net/net.h"
|
||||
#include "net/netbuf.h"
|
||||
|
||||
#define SVC_BAD 0x00 // trash
|
||||
#define SVC_NOP 0x01 // does nothing
|
||||
#define SVC_AUTH 0x02 // auth response, sent in response to CLC_AUTH
|
||||
#define SVC_CHAT 0x03 // chat message
|
||||
#define SVC_STAGE_START 0x10 // start level
|
||||
#define SVC_STAGE_END 0x11 // end level
|
||||
#define SVC_PLAYER_MOVE 0x20 // player movement and inputs
|
||||
#define SVC_PLAYER_GUNS 0x21 // player gun state
|
||||
#define SVC_PLAYER_STATS 0x22 // player stats (health etc)
|
||||
#define SVC_PROP_MOVE 0x30 // prop movement
|
||||
#define SVC_PROP_SPAWN 0x31 // new prop spawned
|
||||
#define SVC_PROP_DAMAGE 0x32 // prop was damaged
|
||||
#define SVC_PROP_PICKUP 0x33 // prop was picked up
|
||||
#define SVC_PROP_USE 0x34 // door/lift/etc was used
|
||||
#define SVC_PROP_DOOR 0x35 // door state changed
|
||||
#define SVC_PROP_LIFT 0x36 // lift state changed
|
||||
#define SVC_CHR_DAMAGE 0x42 // chr was damaged
|
||||
#define SVC_CHR_DISARM 0x43 // chr's weapons were dropped
|
||||
|
||||
#define CLC_BAD 0x00 // trash
|
||||
#define CLC_NOP 0x01 // does nothing
|
||||
#define CLC_AUTH 0x02 // auth request, sent immediately after connecting
|
||||
#define CLC_CHAT 0x03 // chat message
|
||||
#define CLC_MOVE 0x04 // player input
|
||||
#define CLC_SETTINGS 0x05 // player settings changed
|
||||
|
||||
u32 netmsgClcAuthWrite(struct netbuf *dst);
|
||||
u32 netmsgClcAuthRead(struct netbuf *src, struct netclient *srccl);
|
||||
u32 netmsgClcChatWrite(struct netbuf *dst, const char *str);
|
||||
u32 netmsgClcChatRead(struct netbuf *src, struct netclient *srccl);
|
||||
u32 netmsgClcMoveWrite(struct netbuf *dst);
|
||||
u32 netmsgClcMoveRead(struct netbuf *src, struct netclient *srccl);
|
||||
u32 netmsgClcSettingsWrite(struct netbuf *dst);
|
||||
u32 netmsgClcSettingsRead(struct netbuf *src, struct netclient *srccl);
|
||||
|
||||
u32 netmsgSvcAuthWrite(struct netbuf *dst, struct netclient *authcl);
|
||||
u32 netmsgSvcAuthRead(struct netbuf *src, struct netclient *srccl);
|
||||
u32 netmsgSvcChatWrite(struct netbuf *dst, const char *str);
|
||||
u32 netmsgSvcChatRead(struct netbuf *src, struct netclient *srccl);
|
||||
u32 netmsgSvcStageStartWrite(struct netbuf *dst);
|
||||
u32 netmsgSvcStageStartRead(struct netbuf *src, struct netclient *srccl);
|
||||
u32 netmsgSvcStageEndWrite(struct netbuf *dst);
|
||||
u32 netmsgSvcStageEndRead(struct netbuf *src, struct netclient *srccl);
|
||||
u32 netmsgSvcPlayerMoveWrite(struct netbuf *dst, struct netclient *movecl);
|
||||
u32 netmsgSvcPlayerMoveRead(struct netbuf *src, struct netclient *srccl);
|
||||
u32 netmsgSvcPlayerStatsWrite(struct netbuf *dst, struct netclient *actcl);
|
||||
u32 netmsgSvcPlayerStatsRead(struct netbuf *src, struct netclient *srccl);
|
||||
u32 netmsgSvcPropSpawnWrite(struct netbuf *dst, struct prop *prop);
|
||||
u32 netmsgSvcPropSpawnRead(struct netbuf *src, struct netclient *srccl);
|
||||
u32 netmsgSvcPropMoveWrite(struct netbuf *dst, struct prop *prop, struct coord *initrot);
|
||||
u32 netmsgSvcPropMoveRead(struct netbuf *src, struct netclient *srccl);
|
||||
u32 netmsgSvcPropDamageWrite(struct netbuf *dst, struct prop *prop, f32 damage, struct coord *pos, s32 weaponnum, s32 playernum);
|
||||
u32 netmsgSvcPropDamageRead(struct netbuf *src, struct netclient *srccl);
|
||||
u32 netmsgSvcPropPickupWrite(struct netbuf *dst, struct netclient *actcl, struct prop *prop, const s32 tickop);
|
||||
u32 netmsgSvcPropPickupRead(struct netbuf *src, struct netclient *srccl);
|
||||
u32 netmsgSvcPropUseWrite(struct netbuf *dst, struct prop *prop, struct netclient *usercl, const s32 tickop);
|
||||
u32 netmsgSvcPropUseRead(struct netbuf *src, struct netclient *srccl);
|
||||
u32 netmsgSvcPropDoorWrite(struct netbuf *dst, struct prop *prop, struct netclient *usercl);
|
||||
u32 netmsgSvcPropDoorRead(struct netbuf *src, struct netclient *srccl);
|
||||
u32 netmsgSvcPropLiftWrite(struct netbuf *dst, struct prop *prop);
|
||||
u32 netmsgSvcPropLiftRead(struct netbuf *src, struct netclient *srccl);
|
||||
u32 netmsgSvcChrDamageWrite(struct netbuf *dst, struct chrdata *chr, f32 damage, struct coord *vector, struct gset *gset, struct prop *aprop, s32 hitpart, bool damageshield, struct prop *prop2, s32 side, s16 *arg11, bool explosion, struct coord *explosionpos);
|
||||
u32 netmsgSvcChrDamageRead(struct netbuf *src, struct netclient *srccl);
|
||||
u32 netmsgSvcChrDisarmWrite(struct netbuf *dst, struct chrdata *chr, struct prop *attacker, u8 weaponnum, f32 wpndamage, struct coord *wpnpos);
|
||||
u32 netmsgSvcChrDisarmRead(struct netbuf *src, struct netclient *srccl);
|
||||
|
||||
#endif
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
extern u8 *g_RomFile;
|
||||
extern u32 g_RomFileSize;
|
||||
extern const char *g_RomName;
|
||||
|
||||
s32 romdataInit(void);
|
||||
|
||||
|
||||
@@ -7,10 +7,14 @@ extern "C" {
|
||||
|
||||
#include <PR/ultratypes.h>
|
||||
|
||||
enum LogLevel {
|
||||
LOG_NOTE,
|
||||
LOG_WARNING,
|
||||
LOG_ERROR,
|
||||
#define LOGFLAG_NOCON (1 << 6)
|
||||
#define LOGFLAG_SHOWMSG (1 << 7)
|
||||
|
||||
enum loglevel {
|
||||
LOG_NOTE = 0,
|
||||
LOG_CHAT = 0 | LOGFLAG_SHOWMSG,
|
||||
LOG_WARNING = 1 | LOGFLAG_SHOWMSG,
|
||||
LOG_ERROR = 2 | LOGFLAG_SHOWMSG,
|
||||
};
|
||||
|
||||
void sysInitArgs(s32 argc, const char **argv);
|
||||
@@ -21,6 +25,7 @@ const char *sysArgGetString(const char *arg);
|
||||
s32 sysArgGetInt(const char *arg, s32 defval);
|
||||
|
||||
u64 sysGetMicroseconds(void);
|
||||
f32 sysGetSeconds(void);
|
||||
|
||||
void sysFatalError(const char *fmt, ...) __attribute__((noreturn));
|
||||
|
||||
|
||||
@@ -12,4 +12,18 @@ char *strParseToken(char *str, char *out, s32 *outCount);
|
||||
char *strFmt(const char *fmt, ...);
|
||||
char *strDuplicate(const char *str);
|
||||
|
||||
static inline f32 lerpf(const f32 a, const f32 b, const f32 t) {
|
||||
return a + (b - a) * t;
|
||||
}
|
||||
|
||||
static inline f32 lerpanglef(const f32 a, const f32 b, const f32 t) {
|
||||
f32 d = b - a;
|
||||
if (d > 180.f) {
|
||||
d -= 360.f;
|
||||
} else if (d < -180.f) {
|
||||
d += 360.f;
|
||||
}
|
||||
return a + d * t;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -39,8 +39,6 @@ s32 videoGetCenterWindow(void);
|
||||
void videoSetCenterWindow(s32 center);
|
||||
u32 videoGetTextureFilter(void);
|
||||
s32 videoGetTextureFilter2D(void);
|
||||
u32 videoGetAnisotropicFilter(void);
|
||||
u32 videoGetMaxAnisotropyLevel(void);
|
||||
s32 videoGetDetailTextures(void);
|
||||
s32 videoGetDisplayModeIndex(void);
|
||||
s32 videoGetDisplayMode(displaymode *out, const s32 index);
|
||||
@@ -49,25 +47,23 @@ s32 videoGetVsync(void);
|
||||
s32 videoGetFramerateLimit(void);
|
||||
s32 videoGetDisplayFPS(void);
|
||||
s32 videoGetMSAA(void);
|
||||
f32 videoGetGlareBrightness(void);
|
||||
f32 videoGetOverexposureScale(void);
|
||||
|
||||
f32 videoGetAverageFPS(void);
|
||||
f64 videoGetLastRenderTime(void);
|
||||
|
||||
void videoCapFramerate(s32 limit);
|
||||
|
||||
void videoSetWindowOffset(s32 x, s32 y);
|
||||
void videoSetFullscreen(s32 fs);
|
||||
void videoSetFullscreenMode(s32 mode);
|
||||
void videoSetTextureFilter(u32 filter);
|
||||
void videoSetTextureFilter2D(s32 filter);
|
||||
void videoSetAnisotropicFilter(u32 filter);
|
||||
void videoSetDetailTextures(s32 detail);
|
||||
void videoSetDisplayMode(const s32 index);
|
||||
void videoSetVsync(const s32 vsync);
|
||||
void videoSetFramerateLimit(const s32 limit);
|
||||
void videoSetDisplayFPS(const s32 displayfps);
|
||||
void videoSetMSAA(const s32 msaa);
|
||||
void videoSetGlareBrightness(f32 bright);
|
||||
void videoSetOverexposureScale(f32 scale);
|
||||
|
||||
s32 videoCreateFramebuffer(u32 w, u32 h, s32 upscale, s32 autoresize);
|
||||
void videoSetFramebuffer(s32 target);
|
||||
@@ -78,7 +74,6 @@ s32 videoFramebuffersSupported(void);
|
||||
|
||||
void videoResetTextureCache(void);
|
||||
void videoFreeCachedTexture(const void *texptr);
|
||||
void videoFreeCachedTextures(const void *start, const void *end);
|
||||
|
||||
void videoShutdown(void);
|
||||
|
||||
|
||||
@@ -0,0 +1,220 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include "platform.h"
|
||||
#include "types.h"
|
||||
#include "constants.h"
|
||||
#include "data.h"
|
||||
#include "bss.h"
|
||||
#include "config.h"
|
||||
#include "video.h"
|
||||
#include "input.h"
|
||||
#include "console.h"
|
||||
#include "system.h"
|
||||
#include "utils.h"
|
||||
#include "net/net.h"
|
||||
#include "game/hudmsg.h"
|
||||
#include "game/game_1531a0.h"
|
||||
#include "lib/vi.h"
|
||||
|
||||
#define CON_ROWS 80
|
||||
#define CON_COLS 56
|
||||
#define CON_VISROWS 10
|
||||
#define CON_MSGROWS 4
|
||||
#define CON_MSGTIMER 3.f
|
||||
|
||||
static char conBuf[CON_ROWS][CON_COLS + 1];
|
||||
static char conInput[CON_COLS + 1];
|
||||
static char *conVisRows[CON_VISROWS];
|
||||
static s32 conPrintRow = 0;
|
||||
static s32 conPrintCol = 0;
|
||||
static s32 conMsgRows = 0;
|
||||
static f32 conMsgTimer = 0.f;
|
||||
static s32 conInputCol = 0;
|
||||
static u32 conTextColour = 0x00ff00ff;
|
||||
static s32 conOpen = 0;
|
||||
static s32 conButton = 0;
|
||||
|
||||
void conInit(void)
|
||||
{
|
||||
memset(conBuf, 0, sizeof(conBuf));
|
||||
memset(conInput, 0, sizeof(conInput));
|
||||
memset(conVisRows, 0, sizeof(conVisRows));
|
||||
conPrintRow = conPrintCol = 0;
|
||||
conOpen = 0;
|
||||
conMsgRows = 0;
|
||||
conMsgTimer = 0.0f;
|
||||
conInputCol = 0;
|
||||
}
|
||||
|
||||
void conPrint(s32 showmsg, const char *str)
|
||||
{
|
||||
if (!str || !*str) {
|
||||
return;
|
||||
}
|
||||
|
||||
const s32 oldRow = conPrintRow;
|
||||
|
||||
for (const char *s = str; *s; ++s) {
|
||||
char ch = *s;
|
||||
switch (ch) {
|
||||
case '\n':
|
||||
if (conPrintCol) {
|
||||
conPrintCol = 0;
|
||||
conPrintRow = (conPrintRow + 1) % CON_ROWS;
|
||||
}
|
||||
break;
|
||||
case '\r':
|
||||
break;
|
||||
case '\t':
|
||||
ch = ' ';
|
||||
/* fallthrough */
|
||||
default:
|
||||
conBuf[conPrintRow][conPrintCol++] = ch;
|
||||
if (conPrintCol == CON_COLS) {
|
||||
conPrintCol = 0;
|
||||
conPrintRow = (conPrintRow + 1) % CON_ROWS;
|
||||
}
|
||||
break;
|
||||
}
|
||||
conBuf[conPrintRow][conPrintCol] = '\0';
|
||||
}
|
||||
|
||||
if (conPrintRow != oldRow) {
|
||||
// scroll time
|
||||
for (s32 i = 0; i < ARRAYCOUNT(conVisRows); ++i) {
|
||||
s32 row = conPrintRow - i - 1;
|
||||
if (row < 0) {
|
||||
row = CON_ROWS + row;
|
||||
}
|
||||
conVisRows[i] = &conBuf[row][0];
|
||||
}
|
||||
if (showmsg) {
|
||||
if (conMsgRows < CON_MSGROWS) {
|
||||
if (conPrintRow > oldRow) {
|
||||
conMsgRows += conPrintRow - oldRow;
|
||||
} else {
|
||||
conMsgRows += conPrintRow + (CON_ROWS - oldRow);
|
||||
}
|
||||
}
|
||||
conMsgTimer = sysGetSeconds() + CON_MSGTIMER;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void conPrintLn(s32 showmsg, const char *s)
|
||||
{
|
||||
char tmp[4096];
|
||||
snprintf(tmp, sizeof(tmp), "%s\n", s);
|
||||
conPrint(showmsg, tmp);
|
||||
}
|
||||
|
||||
void conPrintf(s32 showmsg, const char *fmt, ...)
|
||||
{
|
||||
char tmp[4096];
|
||||
tmp[sizeof(tmp) - 1] = '\0';
|
||||
tmp[0] = '\0';
|
||||
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
vsnprintf(tmp, sizeof(tmp), fmt, args);
|
||||
va_end(args);
|
||||
|
||||
conPrint(showmsg, tmp);
|
||||
}
|
||||
|
||||
static inline Gfx *conRenderMsgs(Gfx *gdl)
|
||||
{
|
||||
if (conMsgRows) {
|
||||
s32 x, y;
|
||||
const u32 c = (conTextColour & 0xffffff00) | 0xa0;
|
||||
for (s32 i = 0; i < conMsgRows; ++i) {
|
||||
char *s = conVisRows[i];
|
||||
if (s) {
|
||||
x = 4;
|
||||
y = 4 + 8 * (conMsgRows - i - 1);
|
||||
gdl = textRenderProjected(gdl, &x, &y, s, g_CharsHandelGothicXs, g_FontHandelGothicXs, c, viGetWidth(), viGetHeight(), 0, 0);
|
||||
}
|
||||
}
|
||||
const f32 t = sysGetSeconds();
|
||||
if (conMsgTimer <= t) {
|
||||
conMsgTimer = t + CON_MSGTIMER;
|
||||
--conMsgRows;
|
||||
}
|
||||
} else {
|
||||
conMsgTimer = 0;
|
||||
}
|
||||
|
||||
return gdl;
|
||||
}
|
||||
|
||||
Gfx *conRender(Gfx *gdl)
|
||||
{
|
||||
if (!g_CharsHandelGothicXs || !g_FontHandelGothicXs) {
|
||||
return gdl;
|
||||
}
|
||||
|
||||
gdl = text0f153628(gdl);
|
||||
|
||||
if (!conOpen) {
|
||||
gSPExtraGeometryModeEXT(gdl++, G_ASPECT_MODE_EXT, G_ASPECT_LEFT_EXT);
|
||||
gdl = conRenderMsgs(gdl);
|
||||
} else {
|
||||
s32 x, y;
|
||||
gSPExtraGeometryModeEXT(gdl++, G_ASPECT_MODE_EXT, G_ASPECT_CENTER_EXT);
|
||||
gdl = hudmsgRenderBox(gdl, 16, 0, SCREEN_WIDTH_LO - 16, 4 + 8 * (CON_VISROWS + 1), 1.f, conTextColour, 0.9f);
|
||||
for (s32 i = 0; i < CON_VISROWS; ++i) {
|
||||
char *s = conVisRows[i];
|
||||
if (s) {
|
||||
x = 18;
|
||||
y = 4 + 8 * (CON_VISROWS - i - 1);
|
||||
gdl = textRenderProjected(gdl, &x, &y, s, g_CharsHandelGothicXs, g_FontHandelGothicXs, conTextColour, viGetWidth(), viGetHeight(), 0, 0);
|
||||
}
|
||||
}
|
||||
char tmp[CON_COLS + 3];
|
||||
snprintf(tmp, sizeof(tmp), "> %s", conInput);
|
||||
x = 18;
|
||||
y = 4 + 8 * CON_VISROWS;
|
||||
gdl = textRenderProjected(gdl, &x, &y, tmp, g_CharsHandelGothicXs, g_FontHandelGothicXs, conTextColour, viGetWidth(), viGetHeight(), 0, 0);
|
||||
}
|
||||
|
||||
gSPClearExtraGeometryModeEXT(gdl++, G_ASPECT_MODE_EXT);
|
||||
|
||||
gdl = text0f153780(gdl);
|
||||
|
||||
return gdl;
|
||||
}
|
||||
|
||||
void conTick(void)
|
||||
{
|
||||
const s32 button = inputKeyPressed(VK_GRAVE);
|
||||
if (button && !conButton) {
|
||||
conOpen = !conOpen;
|
||||
g_MenuKeyboardPlayer = -1;
|
||||
if (conOpen) {
|
||||
inputClearLastTextChar();
|
||||
inputStartTextInput();
|
||||
} else {
|
||||
inputStopTextInput();
|
||||
}
|
||||
}
|
||||
|
||||
conButton = button;
|
||||
|
||||
if (conOpen) {
|
||||
if (inputTextHandler(conInput, CON_COLS, &conInputCol, false)) {
|
||||
if (g_NetMode) {
|
||||
netChat(NULL, conInput);
|
||||
}
|
||||
conInput[0] = '\0';
|
||||
conInputCol = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
s32 conIsOpen(void)
|
||||
{
|
||||
return conOpen;
|
||||
}
|
||||
+1
-1
@@ -114,7 +114,7 @@ s32 fsInit(void)
|
||||
if (!portable) {
|
||||
if (fsFileSize("./" DEFAULT_BASEDIR_NAME) >= 0) {
|
||||
path = "./" DEFAULT_BASEDIR_NAME;
|
||||
} else if (fsFileSize("$H/" DEFAULT_BASEDIR_NAME) >= 0) {
|
||||
} else if (fsFileSize("$H/" DEFAULT_BASEDIR_NAME)) {
|
||||
path = "$H/" DEFAULT_BASEDIR_NAME;
|
||||
}
|
||||
}
|
||||
|
||||
+25
-33
@@ -75,7 +75,7 @@ static s32 connectedMask = 0;
|
||||
static s32 numJoysticks = 0;
|
||||
|
||||
static s32 useHIDAPI = 1;
|
||||
static s32 useRawInput = 0;
|
||||
static s32 useRawInput = 1;
|
||||
|
||||
static s32 mouseEnabled = 1;
|
||||
static s32 mouseX, mouseY;
|
||||
@@ -195,7 +195,7 @@ void inputSetDefaultKeyBinds(s32 cidx, s32 n64mode)
|
||||
{ CK_RTRIG, VK_MOUSE_RIGHT, SDL_SCANCODE_Z },
|
||||
{ CK_LTRIG, SDL_SCANCODE_F, SDL_SCANCODE_X },
|
||||
{ CK_ZTRIG, VK_MOUSE_LEFT, SDL_SCANCODE_SPACE },
|
||||
{ CK_START, SDL_SCANCODE_TAB, 0 },
|
||||
{ CK_START, SDL_SCANCODE_RETURN, SDL_SCANCODE_TAB },
|
||||
{ CK_DPAD_D, SDL_SCANCODE_Q, VK_MOUSE_MIDDLE },
|
||||
{ CK_DPAD_U, 0, 0 },
|
||||
{ CK_Y, VK_MOUSE_WHEEL_DN, 0 },
|
||||
@@ -209,9 +209,7 @@ void inputSetDefaultKeyBinds(s32 cidx, s32 n64mode)
|
||||
{ CK_STICK_YNEG, SDL_SCANCODE_DOWN, 0 },
|
||||
{ CK_STICK_YPOS, SDL_SCANCODE_UP, 0 },
|
||||
{ CK_4000, SDL_SCANCODE_LSHIFT, 0 },
|
||||
{ CK_2000, SDL_SCANCODE_LCTRL, 0 },
|
||||
{ CK_ACCEPT, SDL_SCANCODE_RETURN, SDL_SCANCODE_E },
|
||||
{ CK_CANCEL, VK_MOUSE_RIGHT, 0 },
|
||||
{ CK_2000, SDL_SCANCODE_LCTRL, 0 }
|
||||
};
|
||||
|
||||
static const u32 pcjoybinds[][2] = {
|
||||
@@ -695,7 +693,6 @@ s32 inputInit(void)
|
||||
// the two hints below enable Rumble and Motion Sensor for PS4/5 pads connected via bluetooth
|
||||
SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_PS4_RUMBLE, "1");
|
||||
SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_PS5_RUMBLE, "1");
|
||||
SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_STEAM, "1");
|
||||
#endif
|
||||
#if SDL_VERSION_ATLEAST(2, 23, 2)
|
||||
SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_COMBINE_JOY_CONS, "1");
|
||||
@@ -705,19 +702,11 @@ s32 inputInit(void)
|
||||
#endif
|
||||
#if SDL_VERSION_ATLEAST(2, 26, 0)
|
||||
SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_WII, "1");
|
||||
#endif
|
||||
#if SDL_VERSION_ATLEAST(2, 30, 0)
|
||||
SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_STEAMDECK, "1");
|
||||
#endif
|
||||
}
|
||||
if (useRawInput) {
|
||||
SDL_SetHint(SDL_HINT_JOYSTICK_RAWINPUT, "1");
|
||||
#ifdef SDL_HINT_JOYSTICK_RAWINPUT_CORRELATE_XINPUT
|
||||
SDL_SetHint(SDL_HINT_JOYSTICK_RAWINPUT_CORRELATE_XINPUT, "1");
|
||||
#elif defined(SDL_HINT_JOYSTICK_HIDAPI_CORRELATE_XINPUT)
|
||||
// old name for SDL_HINT_JOYSTICK_RAWINPUT_CORRELATE_XINPUT before SDL2.0.16
|
||||
SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_CORRELATE_XINPUT, "1");
|
||||
#endif
|
||||
}
|
||||
|
||||
if (!SDL_WasInit(SDL_INIT_GAMECONTROLLER | SDL_INIT_HAPTIC)) {
|
||||
@@ -756,9 +745,6 @@ s32 inputInit(void)
|
||||
|
||||
inputLoadBinds();
|
||||
|
||||
// Explicitly stop text input to prevent key events being swallowed on certain Wayland systems
|
||||
inputStopTextInput();
|
||||
|
||||
return connectedMask;
|
||||
}
|
||||
|
||||
@@ -1255,24 +1241,26 @@ void inputMouseGetRawDelta(s32 *dx, s32 *dy)
|
||||
|
||||
void inputMouseGetScaledDelta(f32* dx, f32* dy)
|
||||
{
|
||||
f32 mdx = 0.f, mdy = 0.f;
|
||||
if (mouseLocked) {
|
||||
mdx = mouseDX * (0.022f / 3.5f) * mouseSensX;
|
||||
mdy = mouseDY * (0.022f / 3.5f) * mouseSensY;
|
||||
}
|
||||
if (dx) *dx = mdx;
|
||||
if (dy) *dy = mdy;
|
||||
f32 mdx = 0.f, mdy = 0.f;
|
||||
|
||||
if (mouseLocked) {
|
||||
mdx = mouseSensX * ((f32)mouseDX / 3.5f) * 0.022f;
|
||||
mdy = mouseSensY * ((f32)mouseDY / 3.5f) * 0.022f;
|
||||
}
|
||||
if (dx) *dx = mdx;
|
||||
if (dy) *dy = mdy;
|
||||
}
|
||||
|
||||
void inputMouseGetAbsScaledDelta(f32* dx, f32* dy)
|
||||
{
|
||||
f32 mdx = 0.f, mdy = 0.f;
|
||||
if (mouseLocked) {
|
||||
mdx = mouseDX * (0.022f / 3.5f) * fabsf(mouseSensX);
|
||||
mdy = mouseDY * (0.022f / 3.5f) * fabsf(mouseSensY);
|
||||
}
|
||||
if (dx) *dx = mdx;
|
||||
if (dy) *dy = mdy;
|
||||
f32 mdx = 0.f, mdy = 0.f;
|
||||
|
||||
if (mouseLocked) {
|
||||
mdx = fabsf(mouseSensX) * ((f32)mouseDX / 3.5f) * 0.022f;
|
||||
mdy = fabsf(mouseSensY) * ((f32)mouseDY / 3.5f) * 0.022f;
|
||||
}
|
||||
if (dx) *dx = mdx;
|
||||
if (dy) *dy = mdy;
|
||||
}
|
||||
|
||||
void inputMouseGetSpeed(f32 *x, f32 *y)
|
||||
@@ -1465,6 +1453,10 @@ s32 inputTextHandler(char *out, const u32 outSize, s32 *curCol, s32 oskCharsOnly
|
||||
} else {
|
||||
out[0] = '\0';
|
||||
}
|
||||
} else if (key == VK_RETURN) {
|
||||
if (out[0] && *curCol) {
|
||||
return 1;
|
||||
}
|
||||
} else if (key == VK_ESCAPE) {
|
||||
return -1;
|
||||
}
|
||||
@@ -1517,8 +1509,8 @@ PD_CONSTRUCTOR static void inputConfigInit(void)
|
||||
{
|
||||
configRegisterInt("Input.MouseEnabled", &mouseEnabled, 0, 1);
|
||||
configRegisterInt("Input.MouseLockMode", &mouseLockMode, MLOCK_OFF, MLOCK_AUTO);
|
||||
configRegisterFloat("Input.MouseSpeedX", &mouseSensX, -30.f, 30.f);
|
||||
configRegisterFloat("Input.MouseSpeedY", &mouseSensY, -30.f, 30.f);
|
||||
configRegisterFloat("Input.MouseSpeedX", &mouseSensX, -10.f, 10.f);
|
||||
configRegisterFloat("Input.MouseSpeedY", &mouseSensY, -10.f, 10.f);
|
||||
configRegisterInt("Input.FakeGamepads", &fakeControllers, 0, 4);
|
||||
configRegisterInt("Input.FirstGamepadNum", &firstController, 0, 3);
|
||||
configRegisterInt("Input.UseHIDAPI", &useHIDAPI, 0, 1);
|
||||
|
||||
+18
-7
@@ -16,7 +16,9 @@
|
||||
#include "config.h"
|
||||
#include "mod.h"
|
||||
#include "system.h"
|
||||
#include "console.h"
|
||||
#include "utils.h"
|
||||
#include "net/net.h"
|
||||
|
||||
u32 g_OsMemSize = 0;
|
||||
s32 g_OsMemSizeMb = 16;
|
||||
@@ -69,7 +71,7 @@ static void gameInit(void)
|
||||
{
|
||||
osMemSize = g_OsMemSizeMb * 1024 * 1024;
|
||||
|
||||
for (s32 i = 0; i < MAX_PLAYERS; ++i) {
|
||||
for (s32 i = 0; i < MAX_LOCAL_PLAYERS; ++i) {
|
||||
struct extplayerconfig *cfg = g_PlayerExtCfg + i;
|
||||
cfg->fovzoommult = cfg->fovzoom ? cfg->fovy / 60.0f : 1.0f;
|
||||
}
|
||||
@@ -86,6 +88,7 @@ static void gameInit(void)
|
||||
static void cleanup(void)
|
||||
{
|
||||
sysLogPrintf(LOG_NOTE, "shutdown");
|
||||
netDisconnect();
|
||||
inputSaveBinds();
|
||||
configSave(CONFIG_PATH);
|
||||
videoShutdown();
|
||||
@@ -101,6 +104,7 @@ int main(int argc, const char **argv)
|
||||
crashInit();
|
||||
}
|
||||
|
||||
conInit();
|
||||
sysInit();
|
||||
fsInit();
|
||||
configInit();
|
||||
@@ -108,6 +112,7 @@ int main(int argc, const char **argv)
|
||||
inputInit();
|
||||
audioInit();
|
||||
romdataInit();
|
||||
netInit();
|
||||
|
||||
g_ValidGbcRomFound = romdataCheckGbcRom();
|
||||
|
||||
@@ -136,6 +141,8 @@ int main(int argc, const char **argv)
|
||||
|
||||
g_StageNum = sysArgGetInt("--boot-stage", STAGE_TITLE);
|
||||
|
||||
g_FileAutoSelect = sysArgGetInt("--profile", -1);
|
||||
|
||||
if (g_StageNum == STAGE_TITLE && (sysArgCheck("--skip-intro") || g_SkipIntro)) {
|
||||
// shorthand for --boot-stage 0x26
|
||||
g_StageNum = STAGE_CITRAINING;
|
||||
@@ -144,11 +151,19 @@ int main(int argc, const char **argv)
|
||||
g_StageNum = STAGE_TITLE;
|
||||
}
|
||||
|
||||
if (g_NetJoinLatch || g_NetHostLatch) {
|
||||
if (g_FileAutoSelect < 0) {
|
||||
// default to profile 0 if going into a net game
|
||||
g_FileAutoSelect = 0;
|
||||
}
|
||||
// skip the intro if going into a net game
|
||||
g_StageNum = STAGE_CITRAINING;
|
||||
}
|
||||
|
||||
if (g_StageNum != STAGE_TITLE) {
|
||||
sysLogPrintf(LOG_NOTE, "boot stage set to 0x%02x", g_StageNum);
|
||||
}
|
||||
|
||||
g_FileAutoSelect = sysArgGetInt("--profile", -1);
|
||||
if (g_FileAutoSelect >= 0) {
|
||||
sysLogPrintf(LOG_NOTE, "player profile set to %d", g_FileAutoSelect);
|
||||
}
|
||||
@@ -169,10 +184,7 @@ PD_CONSTRUCTOR static void gameConfigInit(void)
|
||||
configRegisterInt("Game.SkipIntro", &g_SkipIntro, 0, 1);
|
||||
configRegisterInt("Game.DisableMpDeathMusic", &g_MusicDisableMpDeath, 0, 1);
|
||||
configRegisterInt("Game.GEMuzzleFlashes", &g_BgunGeMuzzleFlashes, 0, 1);
|
||||
configRegisterInt("Game.MaxExplosions", &g_MaxExplosions, 6, 96);
|
||||
configRegisterInt("Game.DecalLimitMultiplier", &g_DecalLimitMultiplier, 1, MAX_DECAL_LIMIT_MULTIPLIER);
|
||||
configRegisterInt("Game.MaxCorpses", &g_MaxCorpses, -1, MAX_CORPSES_LIMIT); // -1 = never fade
|
||||
for (s32 j = 0; j < MAX_PLAYERS; ++j) {
|
||||
for (s32 j = 0; j < MAX_LOCAL_PLAYERS; ++j) {
|
||||
const s32 i = j + 1;
|
||||
configRegisterFloat(strFmt("Game.Player%d.FovY", i), &g_PlayerExtCfg[j].fovy, 5.f, 175.f);
|
||||
configRegisterInt(strFmt("Game.Player%d.FovAffectsZoom", i), &g_PlayerExtCfg[j].fovzoom, 0, 1);
|
||||
@@ -181,7 +193,6 @@ PD_CONSTRUCTOR static void gameConfigInit(void)
|
||||
configRegisterFloat(strFmt("Game.Player%d.MouseAimSpeedY", i), &g_PlayerExtCfg[j].mouseaimspeedy, 0.f, 10.f);
|
||||
configRegisterFloat(strFmt("Game.Player%d.RadialMenuSpeed", i), &g_PlayerExtCfg[j].radialmenuspeed, 0.f, 10.f);
|
||||
configRegisterFloat(strFmt("Game.Player%d.CrosshairSway", i), &g_PlayerExtCfg[j].crosshairsway, 0.f, 10.f);
|
||||
configRegisterFloat(strFmt("Game.Player%d.CrosshairEdgeBoundary", i), &g_PlayerExtCfg[j].crosshairedgeboundary, 0.0f, 1.0f);
|
||||
configRegisterInt(strFmt("Game.Player%d.CrouchMode", i), &g_PlayerExtCfg[j].crouchmode, 0, CROUCHMODE_TOGGLE_ANALOG);
|
||||
configRegisterInt(strFmt("Game.Player%d.ExtendedControls", i), &g_PlayerExtCfg[j].extcontrols, 0, 1);
|
||||
configRegisterUInt(strFmt("Game.Player%d.CrosshairColour", i), &g_PlayerExtCfg[j].crosshaircolour, 0, 0xFFFFFFFF);
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
#include "mixer.h"
|
||||
#include "platform.h"
|
||||
|
||||
#define MINIMP3_IMPLEMENTATION
|
||||
#include "external/minimp3.h"
|
||||
|
||||
#ifdef __SSE4_1__
|
||||
|
||||
+3
-3
@@ -420,7 +420,7 @@ s32 modTextureLoad(u16 num, void *dst, u32 dstSize)
|
||||
{
|
||||
static s32 dirExists = -1;
|
||||
if (dirExists < 0) {
|
||||
dirExists = (fsFileSize(MOD_TEXTURES_DIR) >= 0);
|
||||
dirExists = (fsFileSize(MOD_TEXTURES_DIR "/") >= 0);
|
||||
}
|
||||
|
||||
if (!dirExists) {
|
||||
@@ -442,7 +442,7 @@ void *modSequenceLoad(u16 num, u32 *outSize)
|
||||
{
|
||||
static s32 dirExists = -1;
|
||||
if (dirExists < 0) {
|
||||
dirExists = (fsFileSize(MOD_SEQUENCES_DIR) >= 0);
|
||||
dirExists = (fsFileSize(MOD_SEQUENCES_DIR "/") >= 0);
|
||||
}
|
||||
|
||||
if (!dirExists) {
|
||||
@@ -478,7 +478,7 @@ s32 modAnimationLoadDescriptor(u16 num, struct animtableentry *anim)
|
||||
{
|
||||
static s32 dirExists = -1;
|
||||
if (dirExists < 0) {
|
||||
dirExists = (fsFileSize(MOD_ANIMATIONS_DIR) >= 0);
|
||||
dirExists = (fsFileSize(MOD_ANIMATIONS_DIR "/") >= 0);
|
||||
}
|
||||
|
||||
if (!dirExists) {
|
||||
|
||||
+1
-1
@@ -809,7 +809,7 @@ static MenuItemHandlerResult menuhandlerSetupSetDefault(s32 operation, struct me
|
||||
s32 selected = g_Menus[g_MpPlayerNum].mpsetup.slotindex;
|
||||
// clicked on "clear default"
|
||||
if (selected == g_MpSetupFile.defaultsetup - 1) {
|
||||
g_MpSetupFile.defaultsetup = 0;
|
||||
g_MpSetupFile.defaultsetup = -1;
|
||||
strcpy(g_LabelSetDefault, "Set Default\n");
|
||||
} else {
|
||||
g_MpSetupFile.defaultsetup = selected + 1;
|
||||
|
||||
+1127
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,305 @@
|
||||
#include <string.h>
|
||||
#include "types.h"
|
||||
#include "platform.h"
|
||||
#include "system.h"
|
||||
#include "net/netbuf.h"
|
||||
|
||||
/* read */
|
||||
|
||||
void netbufStartRead(struct netbuf *buf)
|
||||
{
|
||||
buf->error = 0;
|
||||
buf->wp = buf->size;
|
||||
buf->rp = 0;
|
||||
}
|
||||
|
||||
void netbufStartReadData(struct netbuf *buf, const void *data, u32 size)
|
||||
{
|
||||
buf->size = size;
|
||||
buf->data = (void *)data;
|
||||
netbufStartRead(buf);
|
||||
}
|
||||
|
||||
s32 netbufReadLeft(const struct netbuf *buf)
|
||||
{
|
||||
return buf->wp - buf->rp;
|
||||
}
|
||||
|
||||
static inline u32 netbufCanRead(struct netbuf *buf, const u32 num)
|
||||
{
|
||||
if (buf->error || buf->rp + num > buf->wp) {
|
||||
sysLogPrintf(LOG_ERROR, "NET: could not read %u bytes", num);
|
||||
__builtin_trap();
|
||||
buf->error = 1;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
u32 netbufReadData(struct netbuf *buf, void *out, u32 num)
|
||||
{
|
||||
if (netbufCanRead(buf, num)) {
|
||||
memcpy(out, buf->data + buf->rp, num);
|
||||
buf->rp += num;
|
||||
return num;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
u8 netbufReadU8(struct netbuf *buf)
|
||||
{
|
||||
if (netbufCanRead(buf, 1)) {
|
||||
return buf->data[buf->rp++];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
u16 netbufReadU16(struct netbuf *buf)
|
||||
{
|
||||
if (netbufCanRead(buf, 2)) {
|
||||
const u16 ret = *(u16 *)&buf->data[buf->rp];
|
||||
buf->rp += sizeof(ret);
|
||||
return PD_LE16(ret);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
u32 netbufReadU32(struct netbuf *buf)
|
||||
{
|
||||
if (netbufCanRead(buf, 4)) {
|
||||
const u32 ret = *(u32 *)&buf->data[buf->rp];
|
||||
buf->rp += sizeof(ret);
|
||||
return PD_LE32(ret);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
u64 netbufReadU64(struct netbuf *buf)
|
||||
{
|
||||
if (netbufCanRead(buf, 8)) {
|
||||
const u64 ret = *(u64 *)&buf->data[buf->rp];
|
||||
buf->rp += sizeof(ret);
|
||||
return PD_LE64(ret);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
s8 netbufReadS8(struct netbuf *buf) {
|
||||
return (s8)netbufReadU8(buf);
|
||||
}
|
||||
|
||||
s16 netbufReadS16(struct netbuf *buf) {
|
||||
return (s16)netbufReadU16(buf);
|
||||
}
|
||||
|
||||
s32 netbufReadS32(struct netbuf *buf) {
|
||||
return (s32)netbufReadU32(buf);
|
||||
}
|
||||
|
||||
s64 netbufReadS64(struct netbuf *buf) {
|
||||
return (s64)netbufReadU64(buf);
|
||||
}
|
||||
|
||||
f32 netbufReadF32(struct netbuf *buf)
|
||||
{
|
||||
union {
|
||||
f32 f;
|
||||
u32 i;
|
||||
} hack;
|
||||
hack.i = netbufReadU32(buf);
|
||||
return hack.f;
|
||||
}
|
||||
|
||||
char *netbufReadStr(struct netbuf *buf)
|
||||
{
|
||||
const u16 len = netbufReadU16(buf);
|
||||
if (netbufCanRead(buf, len)) {
|
||||
char *ret = (char *)&buf->data[buf->rp];
|
||||
buf->rp += len;
|
||||
return ret;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
u32 netbufReadCoord(struct netbuf *buf, struct coord *out)
|
||||
{
|
||||
if (netbufCanRead(buf, sizeof(*out))) {
|
||||
out->x = netbufReadF32(buf);
|
||||
out->y = netbufReadF32(buf);
|
||||
out->z = netbufReadF32(buf);
|
||||
return sizeof(*out);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
u32 netbufReadMtxf(struct netbuf *buf, Mtxf *out)
|
||||
{
|
||||
if (netbufCanRead(buf, sizeof(*out))) {
|
||||
for (s32 i = 0; i < 4; ++i) {
|
||||
for (s32 j = 0; j < 4; ++j) {
|
||||
out->m[i][j] = netbufReadF32(buf);
|
||||
}
|
||||
}
|
||||
return sizeof(*out);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
u32 netbufReadSkip(struct netbuf *buf, u32 count)
|
||||
{
|
||||
if (netbufCanRead(buf, count)) {
|
||||
buf->rp += count;
|
||||
return count;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* write */
|
||||
|
||||
void netbufStartWrite(struct netbuf *buf)
|
||||
{
|
||||
buf->wp = 0;
|
||||
buf->error = 0;
|
||||
}
|
||||
|
||||
static inline u32 netbufCanWrite(struct netbuf *buf, const u32 num)
|
||||
{
|
||||
if (buf->error || buf->wp + num > buf->size) {
|
||||
buf->error = 1;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
s32 netbufWriteLeft(const struct netbuf *buf)
|
||||
{
|
||||
return buf->size - buf->wp;
|
||||
}
|
||||
|
||||
u32 netbufWriteData(struct netbuf *buf, const void *data, u32 num)
|
||||
{
|
||||
if (netbufCanWrite(buf, num)) {
|
||||
memcpy(buf->data + buf->wp, data, num);
|
||||
buf->wp += num;
|
||||
return num;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
u32 netbufWriteU8(struct netbuf *buf, const u8 v)
|
||||
{
|
||||
if (netbufCanWrite(buf, sizeof(v))) {
|
||||
buf->data[buf->wp++] = v;
|
||||
return sizeof(v);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
u32 netbufWriteU16(struct netbuf *buf, const u16 v)
|
||||
{
|
||||
if (netbufCanWrite(buf, sizeof(v))) {
|
||||
*(u16 *)&buf->data[buf->wp] = PD_LE16(v);
|
||||
buf->wp += sizeof(v);
|
||||
return sizeof(v);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
u32 netbufWriteU32(struct netbuf *buf, const u32 v)
|
||||
{
|
||||
if (netbufCanWrite(buf, sizeof(v))) {
|
||||
*(u32 *)&buf->data[buf->wp] = PD_LE32(v);
|
||||
buf->wp += sizeof(v);
|
||||
return sizeof(v);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
u32 netbufWriteU64(struct netbuf *buf, const u64 v)
|
||||
{
|
||||
if (netbufCanWrite(buf, sizeof(v))) {
|
||||
*(u64 *)&buf->data[buf->wp] = PD_LE64(v);
|
||||
buf->wp += sizeof(v);
|
||||
return sizeof(v);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
u32 netbufWriteS8(struct netbuf *buf, const s8 v)
|
||||
{
|
||||
return netbufWriteU8(buf, (u8)v);
|
||||
}
|
||||
|
||||
u32 netbufWriteS16(struct netbuf *buf, const s16 v)
|
||||
{
|
||||
return netbufWriteU16(buf, (u16)v);
|
||||
}
|
||||
|
||||
u32 netbufWriteS32(struct netbuf *buf, const s32 v)
|
||||
{
|
||||
return netbufWriteU32(buf, (u32)v);
|
||||
}
|
||||
|
||||
u32 netbufWriteS64(struct netbuf *buf, const s64 v)
|
||||
{
|
||||
return netbufWriteU64(buf, (u64)v);
|
||||
}
|
||||
|
||||
u32 netbufWriteF32(struct netbuf *buf, const f32 v)
|
||||
{
|
||||
const union {
|
||||
f32 f;
|
||||
u32 i;
|
||||
} hack = { .f = v };
|
||||
return netbufWriteU32(buf, hack.i);
|
||||
}
|
||||
|
||||
u32 netbufWriteStr(struct netbuf *buf, const char *v)
|
||||
{
|
||||
if (!v) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
u32 len = strlen(v) + 1;
|
||||
if (len > 0xFFFF) {
|
||||
len = 0xFFFF;
|
||||
}
|
||||
|
||||
if (netbufCanWrite(buf, len + sizeof(u16))) {
|
||||
netbufWriteU16(buf, len);
|
||||
netbufWriteData(buf, v, len);
|
||||
buf->data[buf->wp - 1] = 0;
|
||||
return sizeof(u16) + len;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
u32 netbufWriteCoord(struct netbuf *buf, const struct coord *v)
|
||||
{
|
||||
if (netbufCanWrite(buf, sizeof(*v))) {
|
||||
netbufWriteF32(buf, v->x);
|
||||
netbufWriteF32(buf, v->y);
|
||||
netbufWriteF32(buf, v->z);
|
||||
return sizeof(*v);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
u32 netbufWriteMtxf(struct netbuf *buf, const Mtxf *in)
|
||||
{
|
||||
if (netbufCanWrite(buf, sizeof(*in))) {
|
||||
for (s32 i = 0; i < 4; ++i) {
|
||||
for (s32 j = 0; j < 4; ++j) {
|
||||
netbufWriteF32(buf, in->m[i][j]);
|
||||
}
|
||||
}
|
||||
return sizeof(*in);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void netbufReset(struct netbuf *buf)
|
||||
{
|
||||
memset(buf, 0, sizeof(*buf));
|
||||
}
|
||||
@@ -0,0 +1,422 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include <PR/ultratypes.h>
|
||||
#include "platform.h"
|
||||
#include "data.h"
|
||||
#include "types.h"
|
||||
#include "game/mainmenu.h"
|
||||
#include "game/menu.h"
|
||||
#include "game/gamefile.h"
|
||||
#include "game/filelist.h"
|
||||
#include "video.h"
|
||||
#include "input.h"
|
||||
#include "config.h"
|
||||
#include "mpsetups.h"
|
||||
#include "net/net.h"
|
||||
|
||||
extern MenuItemHandlerResult menuhandlerMainMenuCombatSimulator(s32 operation, struct menuitem *item, union handlerdata *data);
|
||||
extern MenuItemHandlerResult menuhandlerMpAdvancedSetup(s32 operation, struct menuitem *item, union handlerdata *data);
|
||||
extern struct menuitem g_MpPlayerSetup234MenuItems[];
|
||||
extern struct menudialogdef g_NetJoinPlayerSetupMenuDialog;
|
||||
|
||||
static s32 g_NetMenuMaxPlayers = NET_MAX_CLIENTS;
|
||||
static s32 g_NetMenuPort = NET_DEFAULT_PORT;
|
||||
static char g_NetJoinAddr[NET_MAX_ADDR + 1];
|
||||
static s32 g_NetJoinAddrPtr = 0;
|
||||
|
||||
/* host */
|
||||
|
||||
static MenuItemHandlerResult menuhandlerHostMaxPlayers(s32 operation, struct menuitem *item, union handlerdata *data)
|
||||
{
|
||||
switch (operation) {
|
||||
case MENUOP_GETSLIDER:
|
||||
data->slider.value = g_NetMenuMaxPlayers;
|
||||
break;
|
||||
case MENUOP_SET:
|
||||
if (data->slider.value) {
|
||||
g_NetMenuMaxPlayers = data->slider.value;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static MenuItemHandlerResult menuhandlerHostPort(s32 operation, struct menuitem *item, union handlerdata *data)
|
||||
{
|
||||
if (operation == MENUOP_SET) {
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static char *menuhandlerHostPortValue(struct menuitem *item)
|
||||
{
|
||||
static char tmp[16];
|
||||
snprintf(tmp, sizeof(tmp), "%u\n", g_NetMenuPort);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
MenuItemHandlerResult menuhandlerHostStart(s32 operation, struct menuitem *item, union handlerdata *data)
|
||||
{
|
||||
if (operation == MENUOP_SET) {
|
||||
if (netStartServer(g_NetMenuPort, g_NetMenuMaxPlayers) == 0) {
|
||||
// load the setup file when entering the Combat Simulator
|
||||
mpsetupCopyAllFromPak();
|
||||
mpsetupLoadCurrentFile();
|
||||
menuhandlerMainMenuCombatSimulator(MENUOP_SET, NULL, NULL);
|
||||
menuhandlerMpAdvancedSetup(MENUOP_SET, NULL, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct menuitem g_NetHostMenuItems[] = {
|
||||
{
|
||||
MENUITEMTYPE_SLIDER,
|
||||
0,
|
||||
MENUITEMFLAG_LITERAL_TEXT,
|
||||
(uintptr_t)"Max Players",
|
||||
NET_MAX_CLIENTS,
|
||||
menuhandlerHostMaxPlayers,
|
||||
},
|
||||
{
|
||||
MENUITEMTYPE_SELECTABLE,
|
||||
0,
|
||||
MENUITEMFLAG_LITERAL_TEXT,
|
||||
(uintptr_t)"Port\n",
|
||||
(uintptr_t)&menuhandlerHostPortValue,
|
||||
menuhandlerHostPort,
|
||||
},
|
||||
{
|
||||
MENUITEMTYPE_SELECTABLE,
|
||||
0,
|
||||
0,
|
||||
L_MPMENU_036, // "Start Game"
|
||||
0,
|
||||
menuhandlerHostStart,
|
||||
},
|
||||
{
|
||||
MENUITEMTYPE_SEPARATOR,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
NULL,
|
||||
},
|
||||
{
|
||||
MENUITEMTYPE_SELECTABLE,
|
||||
0,
|
||||
MENUITEMFLAG_SELECTABLE_CLOSESDIALOG,
|
||||
L_OPTIONS_213, // "Back"
|
||||
0,
|
||||
NULL,
|
||||
},
|
||||
{ MENUITEMTYPE_END },
|
||||
};
|
||||
|
||||
struct menudialogdef g_NetHostMenuDialog = {
|
||||
MENUDIALOGTYPE_DEFAULT,
|
||||
(uintptr_t)"Host Network Game",
|
||||
g_NetHostMenuItems,
|
||||
NULL,
|
||||
MENUDIALOGFLAG_LITERAL_TEXT | MENUDIALOGFLAG_STARTSELECTS,
|
||||
NULL,
|
||||
};
|
||||
|
||||
/* join */
|
||||
|
||||
static const char *menutextJoinAddress(struct menuitem *item)
|
||||
{
|
||||
static char tmp[256 + 1];
|
||||
if (item && item->flags & MENUITEMFLAG_SELECTABLE_CENTRE) {
|
||||
// in centered dialog
|
||||
if (g_NetMode == NETMODE_NONE) {
|
||||
snprintf(tmp, sizeof(tmp), "%s_\n", g_NetJoinAddr);
|
||||
} else if (g_NetLocalClient->state == CLSTATE_CONNECTING) {
|
||||
snprintf(tmp, sizeof(tmp), "Connecting to %s...\n", g_NetJoinAddr);
|
||||
} else if (g_NetLocalClient->state == CLSTATE_AUTH) {
|
||||
snprintf(tmp, sizeof(tmp), "Authenticating with %s...\n", g_NetJoinAddr);
|
||||
} else if (g_NetLocalClient->state == CLSTATE_LOBBY) {
|
||||
snprintf(tmp, sizeof(tmp), "Waiting for host...\n");
|
||||
}
|
||||
} else {
|
||||
// label
|
||||
snprintf(tmp, sizeof(tmp), "%s\n", g_NetJoinAddr);
|
||||
}
|
||||
return tmp;
|
||||
}
|
||||
|
||||
static MenuItemHandlerResult menuhandlerJoining(s32 operation, struct menuitem *item, union handlerdata *data)
|
||||
{
|
||||
if (inputKeyPressed(VK_ESCAPE)) {
|
||||
netDisconnect();
|
||||
menuPopDialog();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct menuitem g_NetJoiningMenuItems[] = {
|
||||
{
|
||||
MENUITEMTYPE_LABEL,
|
||||
0,
|
||||
MENUITEMFLAG_SELECTABLE_CENTRE,
|
||||
(uintptr_t)&menutextJoinAddress,
|
||||
0,
|
||||
NULL,
|
||||
},
|
||||
{
|
||||
MENUITEMTYPE_SEPARATOR,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
NULL,
|
||||
},
|
||||
{
|
||||
MENUITEMTYPE_SELECTABLE,
|
||||
0,
|
||||
MENUITEMFLAG_SELECTABLE_CENTRE | MENUITEMFLAG_LITERAL_TEXT,
|
||||
(uintptr_t)"ESC to abort\n",
|
||||
0,
|
||||
menuhandlerJoining,
|
||||
},
|
||||
{ MENUITEMTYPE_END },
|
||||
};
|
||||
|
||||
struct menudialogdef g_NetJoiningDialog = {
|
||||
MENUDIALOGTYPE_SUCCESS,
|
||||
(uintptr_t)"Joining Game...",
|
||||
g_NetJoiningMenuItems,
|
||||
NULL,
|
||||
MENUDIALOGFLAG_LITERAL_TEXT | MENUDIALOGFLAG_IGNOREBACK | MENUDIALOGFLAG_STARTSELECTS,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static MenuItemHandlerResult menuhandlerEnterJoinAddress(s32 operation, struct menuitem *item, union handlerdata *data);
|
||||
|
||||
struct menuitem g_NetJoinAddressMenuItems[] = {
|
||||
{
|
||||
MENUITEMTYPE_LABEL,
|
||||
0,
|
||||
MENUITEMFLAG_SELECTABLE_CENTRE,
|
||||
(uintptr_t)&menutextJoinAddress,
|
||||
0,
|
||||
NULL,
|
||||
},
|
||||
{
|
||||
MENUITEMTYPE_SEPARATOR,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
NULL,
|
||||
},
|
||||
{
|
||||
MENUITEMTYPE_SELECTABLE,
|
||||
0,
|
||||
MENUITEMFLAG_SELECTABLE_CENTRE | MENUITEMFLAG_LITERAL_TEXT,
|
||||
(uintptr_t)"ESC to return\n",
|
||||
0,
|
||||
menuhandlerEnterJoinAddress,
|
||||
},
|
||||
{ MENUITEMTYPE_END },
|
||||
};
|
||||
|
||||
struct menudialogdef g_NetJoinAddressDialog = {
|
||||
MENUDIALOGTYPE_SUCCESS,
|
||||
(uintptr_t)"Enter Address",
|
||||
g_NetJoinAddressMenuItems,
|
||||
NULL,
|
||||
MENUDIALOGFLAG_LITERAL_TEXT | MENUDIALOGFLAG_IGNOREBACK | MENUDIALOGFLAG_STARTSELECTS,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static MenuItemHandlerResult menuhandlerEnterJoinAddress(s32 operation, struct menuitem *item, union handlerdata *data)
|
||||
{
|
||||
if (!menuIsDialogOpen(&g_NetJoinAddressDialog)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (inputTextHandler(g_NetJoinAddr, NET_MAX_ADDR, &g_NetJoinAddrPtr, false) < 0) {
|
||||
// escape has been pressed, stop editing
|
||||
inputStopTextInput();
|
||||
menuPopDialog();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static MenuItemHandlerResult menuhandlerJoinAddress(s32 operation, struct menuitem *item, union handlerdata *data)
|
||||
{
|
||||
if (operation == MENUOP_SET) {
|
||||
inputClearLastKey();
|
||||
inputClearLastTextChar();
|
||||
inputStartTextInput();
|
||||
g_NetJoinAddrPtr = strlen(g_NetJoinAddr);
|
||||
menuPushDialog(&g_NetJoinAddressDialog);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
MenuItemHandlerResult menuhandlerJoinStart(s32 operation, struct menuitem *item, union handlerdata *data)
|
||||
{
|
||||
if (operation == MENUOP_SET) {
|
||||
if (netStartClient(g_NetJoinAddr) == 0) {
|
||||
menuPushDialog(&g_NetJoiningDialog);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static MenuItemHandlerResult menuhandlerJoinPlayerSetup(s32 operation, struct menuitem *item, union handlerdata *data)
|
||||
{
|
||||
if (operation == MENUOP_SET) {
|
||||
// load MP player file
|
||||
filelistCreate(0, FILETYPE_MPPLAYER);
|
||||
filelistsTick();
|
||||
menuPushDialog(&g_NetJoinPlayerSetupMenuDialog);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct menuitem g_NetJoinMenuItems[] = {
|
||||
{
|
||||
MENUITEMTYPE_SELECTABLE,
|
||||
0,
|
||||
MENUITEMFLAG_LITERAL_TEXT,
|
||||
(uintptr_t)"Address: \n",
|
||||
(uintptr_t)&menutextJoinAddress,
|
||||
menuhandlerJoinAddress,
|
||||
},
|
||||
{
|
||||
MENUITEMTYPE_SELECTABLE,
|
||||
0,
|
||||
0,
|
||||
L_MPMENU_028, // "Player Setup"
|
||||
0,
|
||||
menuhandlerJoinPlayerSetup,
|
||||
},
|
||||
{
|
||||
MENUITEMTYPE_SELECTABLE,
|
||||
0,
|
||||
0,
|
||||
L_MPMENU_036, // "Start Game"
|
||||
0,
|
||||
menuhandlerJoinStart,
|
||||
},
|
||||
{
|
||||
MENUITEMTYPE_SEPARATOR,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
NULL,
|
||||
},
|
||||
{
|
||||
MENUITEMTYPE_SELECTABLE,
|
||||
0,
|
||||
MENUITEMFLAG_SELECTABLE_CLOSESDIALOG,
|
||||
L_OPTIONS_213, // "Back"
|
||||
0,
|
||||
NULL,
|
||||
},
|
||||
{ MENUITEMTYPE_END },
|
||||
};
|
||||
|
||||
struct menudialogdef g_NetJoinMenuDialog = {
|
||||
MENUDIALOGTYPE_DEFAULT,
|
||||
(uintptr_t)"Join Network Game",
|
||||
g_NetJoinMenuItems,
|
||||
NULL,
|
||||
MENUDIALOGFLAG_LITERAL_TEXT | MENUDIALOGFLAG_STARTSELECTS,
|
||||
NULL,
|
||||
};
|
||||
|
||||
/* main */
|
||||
|
||||
MenuItemHandlerResult menuhandlerHostGame(s32 operation, struct menuitem *item, union handlerdata *data)
|
||||
{
|
||||
if (operation == MENUOP_SET) {
|
||||
g_NetMenuPort = g_NetServerPort;
|
||||
g_NetMenuMaxPlayers = g_NetMaxClients;
|
||||
menuPushDialog(&g_NetHostMenuDialog);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
MenuItemHandlerResult menuhandlerJoinGame(s32 operation, struct menuitem *item, union handlerdata *data)
|
||||
{
|
||||
if (operation == MENUOP_SET) {
|
||||
if (g_NetJoinAddr[0] == '\0') {
|
||||
strncpy(g_NetJoinAddr, g_NetLastJoinAddr, NET_MAX_ADDR);
|
||||
g_NetJoinAddrPtr = strlen(g_NetJoinAddr);
|
||||
}
|
||||
menuPushDialog(&g_NetJoinMenuDialog);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct menuitem g_NetMenuItems[] = {
|
||||
{
|
||||
MENUITEMTYPE_SELECTABLE,
|
||||
0,
|
||||
MENUITEMFLAG_LITERAL_TEXT,
|
||||
(uintptr_t)"Host Game\n",
|
||||
0,
|
||||
menuhandlerHostGame,
|
||||
},
|
||||
{
|
||||
MENUITEMTYPE_SELECTABLE,
|
||||
0,
|
||||
MENUITEMFLAG_LITERAL_TEXT,
|
||||
(uintptr_t)"Join Game\n",
|
||||
0,
|
||||
menuhandlerJoinGame,
|
||||
},
|
||||
{
|
||||
MENUITEMTYPE_SEPARATOR,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
NULL,
|
||||
},
|
||||
{
|
||||
MENUITEMTYPE_SELECTABLE,
|
||||
0,
|
||||
MENUITEMFLAG_SELECTABLE_CLOSESDIALOG,
|
||||
L_OPTIONS_213, // "Back"
|
||||
0,
|
||||
NULL,
|
||||
},
|
||||
{ MENUITEMTYPE_END },
|
||||
};
|
||||
|
||||
struct menudialogdef g_NetMenuDialog = {
|
||||
MENUDIALOGTYPE_DEFAULT,
|
||||
(uintptr_t)"Network Game",
|
||||
g_NetMenuItems,
|
||||
NULL,
|
||||
MENUDIALOGFLAG_MPLOCKABLE | MENUDIALOGFLAG_LITERAL_TEXT | MENUDIALOGFLAG_STARTSELECTS,
|
||||
NULL,
|
||||
};
|
||||
|
||||
struct menudialogdef g_NetJoinPlayerSetupMenuDialog = {
|
||||
MENUDIALOGTYPE_DEFAULT,
|
||||
L_MPMENU_028, // "Player Setup"
|
||||
g_MpPlayerSetup234MenuItems,
|
||||
NULL,
|
||||
MENUDIALOGFLAG_DROPOUTONCLOSE | MENUDIALOGFLAG_STARTSELECTS,
|
||||
NULL,
|
||||
};
|
||||
File diff suppressed because it is too large.
Load diff
+6
-121
@@ -170,6 +170,8 @@ static MenuItemHandlerResult menuhandlerMouseSpeedX(s32 operation, struct menuit
|
||||
inputMouseGetSpeed(&x, &y);
|
||||
if (x < 0.f) {
|
||||
data->slider.value = 0;
|
||||
} else if (x > 10.f) {
|
||||
data->slider.value = 1000;
|
||||
} else {
|
||||
data->slider.value = x * 100.f + 0.5f;
|
||||
}
|
||||
@@ -180,7 +182,6 @@ static MenuItemHandlerResult menuhandlerMouseSpeedX(s32 operation, struct menuit
|
||||
break;
|
||||
case MENUOP_GETSLIDERLABEL:
|
||||
sprintf(data->slider.label, "%.2f", (f32)data->slider.value / 100.f);
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -195,6 +196,8 @@ static MenuItemHandlerResult menuhandlerMouseSpeedY(s32 operation, struct menuit
|
||||
inputMouseGetSpeed(&x, &y);
|
||||
if (y < 0.f) {
|
||||
data->slider.value = 0;
|
||||
} else if (y > 10.f) {
|
||||
data->slider.value = 1000;
|
||||
} else {
|
||||
data->slider.value = y * 100.f + 0.5f;
|
||||
}
|
||||
@@ -205,7 +208,6 @@ static MenuItemHandlerResult menuhandlerMouseSpeedY(s32 operation, struct menuit
|
||||
break;
|
||||
case MENUOP_GETSLIDERLABEL:
|
||||
sprintf(data->slider.label, "%.2f", (f32)data->slider.value / 100.f);
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -323,7 +325,7 @@ struct menuitem g_ExtendedMouseMenuItems[] = {
|
||||
0,
|
||||
MENUITEMFLAG_LITERAL_TEXT | MENUITEMFLAG_SLIDER_WIDE,
|
||||
(uintptr_t)"Mouse Speed X",
|
||||
3000,
|
||||
1000,
|
||||
menuhandlerMouseSpeedX,
|
||||
},
|
||||
{
|
||||
@@ -331,7 +333,7 @@ struct menuitem g_ExtendedMouseMenuItems[] = {
|
||||
0,
|
||||
MENUITEMFLAG_LITERAL_TEXT | MENUITEMFLAG_SLIDER_WIDE,
|
||||
(uintptr_t)"Mouse Speed Y",
|
||||
3000,
|
||||
1000,
|
||||
menuhandlerMouseSpeedY,
|
||||
},
|
||||
{
|
||||
@@ -908,20 +910,6 @@ static MenuItemHandlerResult menuhandlerTexFilter2D(s32 operation, struct menuit
|
||||
return 0;
|
||||
}
|
||||
|
||||
static MenuItemHandlerResult menuhandlerAnisotropicFiltering(s32 operation, struct menuitem *item, union handlerdata *data)
|
||||
{
|
||||
switch (operation) {
|
||||
case MENUOP_GETSLIDER:
|
||||
data->slider.value = videoGetAnisotropicFilter();
|
||||
break;
|
||||
case MENUOP_SET:
|
||||
videoSetAnisotropicFilter(data->slider.value);
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static MenuItemHandlerResult menuhandlerDisplayFPS(s32 operation, struct menuitem *item, union handlerdata *data)
|
||||
{
|
||||
switch (operation) {
|
||||
@@ -1008,34 +996,6 @@ static MenuItemHandlerResult menuhandlerScreenShake(s32 operation, struct menuit
|
||||
return 0;
|
||||
}
|
||||
|
||||
static MenuItemHandlerResult menuhandlerGlareBrightness(s32 operation, struct menuitem *item, union handlerdata *data)
|
||||
{
|
||||
switch (operation) {
|
||||
case MENUOP_GETSLIDER:
|
||||
data->slider.value = videoGetGlareBrightness() * 10.f + 0.5f;
|
||||
break;
|
||||
case MENUOP_SET:
|
||||
videoSetGlareBrightness((f32)data->slider.value / 10.f);
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static MenuItemHandlerResult menuhandlerOverexposureScale(s32 operation, struct menuitem *item, union handlerdata *data)
|
||||
{
|
||||
switch (operation) {
|
||||
case MENUOP_GETSLIDER:
|
||||
data->slider.value = videoGetOverexposureScale() * 10.f + 0.5f;
|
||||
break;
|
||||
case MENUOP_SET:
|
||||
videoSetOverexposureScale((f32)data->slider.value / 10.f);
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct menuitem g_ExtendedVideoMenuItems[] = {
|
||||
{
|
||||
MENUITEMTYPE_CHECKBOX,
|
||||
@@ -1141,14 +1101,6 @@ struct menuitem g_ExtendedVideoMenuItems[] = {
|
||||
0,
|
||||
menuhandlerTexFilter2D,
|
||||
},
|
||||
{
|
||||
MENUITEMTYPE_SLIDER,
|
||||
0,
|
||||
MENUITEMFLAG_LITERAL_TEXT | MENUITEMFLAG_SLIDER_WIDE,
|
||||
(uintptr_t)"Anisotropic Filtering",
|
||||
8,
|
||||
menuhandlerAnisotropicFiltering,
|
||||
},
|
||||
{
|
||||
MENUITEMTYPE_CHECKBOX,
|
||||
0,
|
||||
@@ -1197,30 +1149,6 @@ struct menuitem g_ExtendedVideoMenuItems[] = {
|
||||
0,
|
||||
NULL,
|
||||
},
|
||||
{
|
||||
MENUITEMTYPE_SLIDER,
|
||||
0,
|
||||
MENUITEMFLAG_LITERAL_TEXT | MENUITEMFLAG_SLIDER_WIDE,
|
||||
(uintptr_t)"Glare Brightness",
|
||||
10,
|
||||
menuhandlerGlareBrightness,
|
||||
},
|
||||
{
|
||||
MENUITEMTYPE_SLIDER,
|
||||
0,
|
||||
MENUITEMFLAG_LITERAL_TEXT | MENUITEMFLAG_SLIDER_WIDE,
|
||||
(uintptr_t)"Overexposure Scale",
|
||||
10,
|
||||
menuhandlerOverexposureScale,
|
||||
},
|
||||
{
|
||||
MENUITEMTYPE_SEPARATOR,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
NULL,
|
||||
},
|
||||
{
|
||||
MENUITEMTYPE_SELECTABLE,
|
||||
0,
|
||||
@@ -1365,22 +1293,6 @@ static MenuItemHandlerResult menuhandlerCrosshairSway(s32 operation, struct menu
|
||||
return 0;
|
||||
}
|
||||
|
||||
static MenuItemHandlerResult menuhandlerCrosshairEdgeBoundary(s32 operation, struct menuitem* item, union handlerdata *data)
|
||||
{
|
||||
switch (operation) {
|
||||
case MENUOP_GETSLIDER:
|
||||
data->slider.value = (s32)(g_PlayerExtCfg[g_ExtMenuPlayer].crosshairedgeboundary * 10.f + 0.5f);
|
||||
break;
|
||||
case MENUOP_SET:
|
||||
g_PlayerExtCfg[g_ExtMenuPlayer].crosshairedgeboundary = (f32)data->slider.value / 10.f;
|
||||
break;
|
||||
case MENUOP_GETSLIDERLABEL:
|
||||
sprintf(data->slider.label, "%d", (s32)data->slider.value);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static MenuItemHandlerResult menuhandlerCrosshairR(s32 operation, struct menuitem* item, union handlerdata* data)
|
||||
{
|
||||
u32 newColor;
|
||||
@@ -1602,14 +1514,6 @@ struct menuitem g_ExtendedGameMenuItems[] = {
|
||||
20,
|
||||
menuhandlerCrosshairSway,
|
||||
},
|
||||
{
|
||||
MENUITEMTYPE_SLIDER,
|
||||
0,
|
||||
MENUITEMFLAG_LITERAL_TEXT | MENUITEMFLAG_SLIDER_WIDE,
|
||||
(uintptr_t)"Crosshair Edge Deadzone",
|
||||
10,
|
||||
menuhandlerCrosshairEdgeBoundary,
|
||||
},
|
||||
{
|
||||
MENUITEMTYPE_SLIDER,
|
||||
0,
|
||||
@@ -2021,22 +1925,3 @@ struct menudialogdef g_ExtendedMenuDialog = {
|
||||
MENUDIALOGFLAG_LITERAL_TEXT,
|
||||
NULL,
|
||||
};
|
||||
|
||||
void updateMaxAnisotropyLevel()
|
||||
{
|
||||
for (int i = 0; i < ARRAYCOUNT(g_ExtendedVideoMenuItems); ++i) {
|
||||
struct menuitem *item = &g_ExtendedVideoMenuItems[i];
|
||||
const char *text = menuResolveParam2Text(item);
|
||||
|
||||
if (text && strstr(text, "Anisotropic Filtering") != NULL) {
|
||||
item->param3 = videoGetMaxAnisotropyLevel();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void optionsMenuInit()
|
||||
{
|
||||
updateMaxAnisotropyLevel();
|
||||
}
|
||||
+23
-15
@@ -73,6 +73,9 @@
|
||||
#include "data.h"
|
||||
#include "types.h"
|
||||
#include "system.h"
|
||||
#include "console.h"
|
||||
#include "net/net.h"
|
||||
#include "net/netmsg.h"
|
||||
|
||||
extern u8 *g_MempHeap;
|
||||
extern u32 g_MempHeapSize;
|
||||
@@ -421,6 +424,9 @@ void mainLoop(void)
|
||||
|
||||
if (argFindByPrefix(1, "-ma")) {
|
||||
g_MainMemaHeapSize = strtol(argFindByPrefix(1, "-ma"), NULL, 0) * 1024;
|
||||
if (g_NetMode && g_NetMaxClients > MAX_LOCAL_PLAYERS) {
|
||||
g_MainMemaHeapSize *= MAX_PLAYERS / MAX_LOCAL_PLAYERS;
|
||||
}
|
||||
}
|
||||
|
||||
memaReset(mempAlloc(g_MainMemaHeapSize, MEMPOOL_STAGE), g_MainMemaHeapSize);
|
||||
@@ -462,10 +468,15 @@ void mainLoop(void)
|
||||
}
|
||||
|
||||
if (g_Vars.coopplayernum >= 0 || g_Vars.antiplayernum >= 0) {
|
||||
if (g_MpSetup.chrslots & 0xfff0) {
|
||||
g_MpSetup.storedbotbits = g_MpSetup.chrslots & 0xfff0;
|
||||
}
|
||||
#ifdef PLATFORM_N64
|
||||
g_MpSetup.chrslots = 0x03;
|
||||
#else
|
||||
if (g_Vars.antiplayernum < 0) {
|
||||
// Counter-Operative now uses a different approach which allows more than 2 players.
|
||||
// Co-Operative, on the other hand, is currently limited to 2 players.
|
||||
g_MpSetup.chrslots = 0x03;
|
||||
}
|
||||
#endif
|
||||
mpReset();
|
||||
} else if (g_Vars.perfectbuddynum) {
|
||||
mpReset();
|
||||
@@ -473,16 +484,8 @@ void mainLoop(void)
|
||||
&& (numplayers >= 2 || g_Vars.lvmpbotlevel || argFindByPrefix(1, "-play"))) {
|
||||
g_MpSetup.chrslots = 1;
|
||||
|
||||
if (numplayers >= 2) {
|
||||
g_MpSetup.chrslots |= 1 << 1;
|
||||
}
|
||||
|
||||
if (numplayers >= 3) {
|
||||
g_MpSetup.chrslots |= 1 << 2;
|
||||
}
|
||||
|
||||
if (numplayers >= 4) {
|
||||
g_MpSetup.chrslots |= 1 << 3;
|
||||
for (s32 i = 1; i < numplayers; ++i) {
|
||||
g_MpSetup.chrslots |= 1 << i;
|
||||
}
|
||||
|
||||
g_MpSetup.stagenum = g_StageNum;
|
||||
@@ -566,6 +569,9 @@ void mainTick(void)
|
||||
gdl = profileRender(gdl);
|
||||
}
|
||||
|
||||
gdl = conRender(gdl);
|
||||
gdl = netDebugRender(gdl);
|
||||
|
||||
gDPFullSync(gdl++);
|
||||
gSPEndDisplayList(gdl++);
|
||||
}
|
||||
@@ -593,7 +599,7 @@ void mainEndStage(void)
|
||||
s32 prevplayernum = g_Vars.currentplayernum;
|
||||
s32 i;
|
||||
|
||||
for (i = 0; i < PLAYERCOUNT(); i++) {
|
||||
for (i = 0; i < LOCALPLAYERCOUNT(); i++) {
|
||||
setCurrentPlayerNum(i);
|
||||
endscreenPushCoop();
|
||||
}
|
||||
@@ -604,7 +610,7 @@ void mainEndStage(void)
|
||||
s32 prevplayernum = g_Vars.currentplayernum;
|
||||
s32 i;
|
||||
|
||||
for (i = 0; i < PLAYERCOUNT(); i++) {
|
||||
for (i = 0; i < LOCALPLAYERCOUNT(); i++) {
|
||||
setCurrentPlayerNum(i);
|
||||
endscreenPushAnti();
|
||||
}
|
||||
@@ -617,6 +623,8 @@ void mainEndStage(void)
|
||||
endscreenPrepare();
|
||||
musicStartMenu();
|
||||
}
|
||||
|
||||
netServerStageEnd();
|
||||
}
|
||||
|
||||
g_MainIsEndscreen = true;
|
||||
|
||||
@@ -24,7 +24,9 @@
|
||||
#include "video.h"
|
||||
#include "audio.h"
|
||||
#include "input.h"
|
||||
#include "console.h"
|
||||
#include "mixer.h"
|
||||
#include "net/net.h"
|
||||
|
||||
/*
|
||||
* private typedefs and defines
|
||||
@@ -240,6 +242,14 @@ void schedSubmitTask(OSSched *sc, OSScTask *t)
|
||||
void schedStartFrame(OSSched *sc)
|
||||
{
|
||||
videoStartFrame();
|
||||
if (g_Vars.diffframe60) {
|
||||
if (g_NetMode) {
|
||||
videoCapFramerate(120);
|
||||
netStartFrame();
|
||||
} else {
|
||||
videoCapFramerate(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void schedAudioFrame(OSSched *sc)
|
||||
@@ -270,6 +280,8 @@ void schedAudioFrame(OSSched *sc)
|
||||
*/
|
||||
void schedEndFrame(OSSched *sc)
|
||||
{
|
||||
static bool netDebugKey = false;
|
||||
|
||||
sc->frameCount++;
|
||||
|
||||
#if PAL
|
||||
@@ -289,11 +301,22 @@ void schedEndFrame(OSSched *sc)
|
||||
}
|
||||
|
||||
inputUpdate();
|
||||
conTick();
|
||||
|
||||
const bool newKey = inputKeyPressed(VK_F9);
|
||||
if (!netDebugKey && newKey) {
|
||||
g_NetDebugDraw = !g_NetDebugDraw;
|
||||
}
|
||||
netDebugKey = newKey;
|
||||
|
||||
joyStartReadData(&g_PiMesgQueue);
|
||||
joyReadData();
|
||||
joy00014238();
|
||||
|
||||
if (g_Vars.diffframe60) {
|
||||
netEndFrame();
|
||||
}
|
||||
|
||||
sndHandleRetrace();
|
||||
schedAudioFrame(sc);
|
||||
schedRenderCrashPeriodically(sc->frameCount);
|
||||
|
||||
@@ -50,6 +50,10 @@ u8 *preprocessMpConfigs(u8* data, u32 size, u32* outSize)
|
||||
PD_SWAP_VAL(cfg->setup.options);
|
||||
PD_SWAP_VAL(cfg->setup.teamscorelimit);
|
||||
PD_SWAP_VAL(cfg->setup.chrslots);
|
||||
#if MAX_PLAYERS > 4
|
||||
// make space for the extra players
|
||||
cfg->setup.chrslots = (cfg->setup.chrslots & 0x000f) | ((cfg->setup.chrslots & 0x0ff0) << 4);
|
||||
#endif
|
||||
// TODO: are these required or are they always 0?
|
||||
PD_SWAP_VAL(cfg->setup.fileguid.deviceserial);
|
||||
PD_SWAP_VAL(cfg->setup.fileguid.fileid);
|
||||
|
||||
+5
-5
@@ -55,10 +55,10 @@
|
||||
|
||||
u8 *g_RomFile;
|
||||
u32 g_RomFileSize;
|
||||
const char *g_RomName = ROMDATA_ROM_NAME;
|
||||
|
||||
static u8 *romDataSeg;
|
||||
static u32 romDataSegSize;
|
||||
static const char *romName = ROMDATA_ROM_NAME;
|
||||
|
||||
enum loadsource {
|
||||
SRC_UNLOADED = 0,
|
||||
@@ -190,12 +190,12 @@ static inline void romdataWrongRomError(const char *fmt, ...)
|
||||
|
||||
static inline void romdataLoadRom(void)
|
||||
{
|
||||
sysLogPrintf(LOG_NOTE, "ROM file: %s", romName);
|
||||
sysLogPrintf(LOG_NOTE, "ROM file: %s", g_RomName);
|
||||
|
||||
g_RomFile = fsFileLoad(romName, &g_RomFileSize);
|
||||
g_RomFile = fsFileLoad(g_RomName, &g_RomFileSize);
|
||||
|
||||
if (!g_RomFile) {
|
||||
sysFatalError("Could not open ROM file %s.\nEnsure that it is in the %s directory.", romName, fsFullPath(""));
|
||||
sysFatalError("Could not open ROM file %s.\nEnsure that it is in the %s directory.", g_RomName, fsFullPath(""));
|
||||
}
|
||||
|
||||
// zips are not guaranteed to start with PK, but might as well at least try
|
||||
@@ -383,7 +383,7 @@ s32 romdataInit(void)
|
||||
{
|
||||
const char *altRomName = sysArgGetString("--rom-file");
|
||||
if (altRomName) {
|
||||
romName = altRomName;
|
||||
g_RomName = altRomName;
|
||||
}
|
||||
|
||||
romdataLoadRom();
|
||||
|
||||
+14
-2
@@ -12,6 +12,7 @@
|
||||
#include <SDL.h>
|
||||
#include <PR/ultratypes.h>
|
||||
#include "platform.h"
|
||||
#include "console.h"
|
||||
#include "system.h"
|
||||
|
||||
#ifdef PLATFORM_WIN32
|
||||
@@ -157,6 +158,12 @@ u64 sysGetMicroseconds(void)
|
||||
return ((u64)tv.tv_sec * USEC_IN_SEC + (u64)tv.tv_usec) - startTick;
|
||||
}
|
||||
|
||||
float sysGetSeconds(void)
|
||||
{
|
||||
u64 t = sysGetMicroseconds();
|
||||
return (f32)t / 1000000.f;
|
||||
}
|
||||
|
||||
s32 sysLogIsOpen(void)
|
||||
{
|
||||
return (logPath[0] != '\0');
|
||||
@@ -183,8 +190,13 @@ void sysLogPrintf(s32 level, const char *fmt, ...)
|
||||
}
|
||||
}
|
||||
|
||||
FILE *fout = (level == LOG_NOTE) ? stdout : stderr;
|
||||
fprintf(fout, "%s%s\n", prefix[level], logmsg);
|
||||
FILE *fout = ((level & 0x0f) == LOG_NOTE) ? stdout : stderr;
|
||||
fprintf(fout, "%s%s\n", prefix[level & 0x0f], logmsg);
|
||||
fflush(fout);
|
||||
|
||||
if ((level & LOGFLAG_NOCON) == 0) {
|
||||
conPrintLn((level & LOGFLAG_SHOWMSG) != 0, logmsg);
|
||||
}
|
||||
}
|
||||
|
||||
void sysFatalError(const char *fmt, ...)
|
||||
|
||||
+13
-52
@@ -45,19 +45,15 @@ static s32 vidFramerateLimit = 0;
|
||||
static s32 vidDisplayFPS = 0;
|
||||
static f32 vidDisplayFPSInterval = 1.f;
|
||||
static f32 vidAvgFPS = 0;
|
||||
static f64 vidLastRenderTime;
|
||||
|
||||
static s32 vidNumModes = 1;
|
||||
static displaymode vidModeDefault;
|
||||
static displaymode *vidModes = &vidModeDefault;
|
||||
|
||||
static f32 vidGlareBrightness = 1.f;
|
||||
static f32 vidOverexposureScale = 1.f;
|
||||
|
||||
static s32 texFilter = FILTER_LINEAR;
|
||||
static s32 texFilter2D = true;
|
||||
static s32 texDetail = false;
|
||||
static s32 texMipmapFilter = MIPMAP_LINEAR;
|
||||
static u32 texAnisotropicFilter = 4;
|
||||
|
||||
static u32 dlcount = 0;
|
||||
static u32 frames = 0;
|
||||
@@ -67,7 +63,6 @@ static f64 fpsTime = 0.0;
|
||||
static s32 fpsNumFrames = 0;
|
||||
|
||||
static s32 videoInitDisplayModes(void);
|
||||
void optionsMenuInit();
|
||||
|
||||
s32 videoInit(void)
|
||||
{
|
||||
@@ -105,9 +100,6 @@ s32 videoInit(void)
|
||||
videoSetFramerateLimit(vidFramerateLimit);
|
||||
|
||||
gfx_set_texture_filter((enum FilteringMode)texFilter);
|
||||
gfx_set_mipmap_filter((enum MipmapFilteringMode)texMipmapFilter);
|
||||
videoSetAnisotropicFilter(texAnisotropicFilter);
|
||||
optionsMenuInit();
|
||||
|
||||
initDone = true;
|
||||
return 0;
|
||||
@@ -147,17 +139,23 @@ void videoEndFrame(void)
|
||||
const f64 flipTime = wmAPI->get_time();
|
||||
accumDelta += flipTime - endTime;
|
||||
endTime = flipTime;
|
||||
vidLastRenderTime = endTime - startTime;
|
||||
|
||||
if (endTime >= fpsTime) {
|
||||
char tmp[128];
|
||||
vidAvgFPS = fpsNumFrames ? ((f64)fpsNumFrames / accumDelta) : 0.f;
|
||||
fpsNumFrames = 0;
|
||||
accumDelta = 0.0;
|
||||
snprintf(tmp, sizeof(tmp), "fps %4.1f frt %lf frm %u", vidAvgFPS, vidLastRenderTime, frames);
|
||||
wmAPI->set_window_title(tmp);
|
||||
fpsTime = endTime + vidDisplayFPSInterval;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
f64 videoGetLastRenderTime(void)
|
||||
{
|
||||
return vidLastRenderTime;
|
||||
}
|
||||
|
||||
f32 videoGetAverageFPS(void)
|
||||
{
|
||||
@@ -371,31 +369,11 @@ u32 videoGetTextureFilter(void)
|
||||
return texFilter;
|
||||
}
|
||||
|
||||
u32 videoGetAnisotropicFilter()
|
||||
{
|
||||
return texAnisotropicFilter;
|
||||
}
|
||||
|
||||
u32 videoGetMaxAnisotropyLevel()
|
||||
{
|
||||
return renderingAPI->get_max_anisotropy_level();
|
||||
}
|
||||
|
||||
s32 videoGetDetailTextures(void)
|
||||
{
|
||||
return texDetail;
|
||||
}
|
||||
|
||||
f32 videoGetGlareBrightness(void)
|
||||
{
|
||||
return vidGlareBrightness;
|
||||
}
|
||||
|
||||
f32 videoGetOverexposureScale(void)
|
||||
{
|
||||
return vidOverexposureScale;
|
||||
}
|
||||
|
||||
void videoSetWindowOffset(s32 x, s32 y)
|
||||
{
|
||||
gfx_current_game_window_viewport.x = x;
|
||||
@@ -463,26 +441,18 @@ void videoSetTextureFilter2D(s32 filter)
|
||||
texFilter2D = !!filter;
|
||||
}
|
||||
|
||||
void videoSetAnisotropicFilter(u32 level)
|
||||
{
|
||||
texAnisotropicFilter = level;
|
||||
renderingAPI->set_anisotropy_level(level);
|
||||
}
|
||||
|
||||
void videoSetDetailTextures(s32 detail)
|
||||
{
|
||||
texDetail = !!detail;
|
||||
gfx_detail_textures_enabled = (bool)texDetail;
|
||||
}
|
||||
|
||||
void videoSetGlareBrightness(f32 bright)
|
||||
void videoCapFramerate(s32 limit)
|
||||
{
|
||||
vidGlareBrightness = (bright < 0.f ? 0.f : (bright > 1.f ? 1.f : bright));
|
||||
}
|
||||
|
||||
void videoSetOverexposureScale(f32 scale)
|
||||
{
|
||||
vidOverexposureScale = (scale < 0.f ? 0.f : (scale > 1.f ? 1.f : scale));
|
||||
if (vidFramerateLimit > 0 && vidFramerateLimit < limit) {
|
||||
limit = vidFramerateLimit;
|
||||
}
|
||||
wmAPI->set_target_fps(limit ? limit : vidFramerateLimit);
|
||||
}
|
||||
|
||||
s32 videoCreateFramebuffer(u32 w, u32 h, s32 upscale, s32 autoresize)
|
||||
@@ -553,11 +523,6 @@ void videoFreeCachedTexture(const void *texptr)
|
||||
gfx_texture_cache_delete(texptr);
|
||||
}
|
||||
|
||||
void videoFreeCachedTextures(const void *start, const void *end)
|
||||
{
|
||||
gfx_texture_cache_delete_range(start, end);
|
||||
}
|
||||
|
||||
void videoShutdown(void)
|
||||
{
|
||||
free(vidModes);
|
||||
@@ -581,8 +546,4 @@ PD_CONSTRUCTOR static void videoConfigInit(void)
|
||||
configRegisterInt("Video.TextureFilter", &texFilter, 0, 2);
|
||||
configRegisterInt("Video.TextureFilter2D", &texFilter2D, 0, 1);
|
||||
configRegisterInt("Video.DetailTextures", &texDetail, 0, 1);
|
||||
configRegisterInt("Video.MipmapFilter", &texMipmapFilter, 0, 2);
|
||||
configRegisterInt("Video.AnisotropicFilter", &texAnisotropicFilter, 0, 16);
|
||||
configRegisterFloat("Video.GlareBrightness", &vidGlareBrightness, 0.f, 1.f);
|
||||
configRegisterFloat("Video.OverexposureScale", &vidOverexposureScale, 0.f, 1.f);
|
||||
}
|
||||
+29
-29
@@ -26,7 +26,7 @@
|
||||
#include "data.h"
|
||||
#include "types.h"
|
||||
|
||||
struct activemenu g_AmMenus[MAX_PLAYERS];
|
||||
struct activemenu g_AmMenus[MAX_LOCAL_PLAYERS];
|
||||
struct fontchar *g_AmFont1;
|
||||
struct font *g_AmFont2;
|
||||
s32 g_AmIndex;
|
||||
@@ -547,7 +547,7 @@ void amReset(void)
|
||||
g_AmFont1 = g_CharsHandelGothicSm;
|
||||
g_AmFont2 = g_FontHandelGothicSm;
|
||||
#else
|
||||
if (PLAYERCOUNT() >= 2) {
|
||||
if (LOCALPLAYERCOUNT() >= 2) {
|
||||
g_AmFont1 = g_CharsHandelGothicXs;
|
||||
g_AmFont2 = g_FontHandelGothicXs;
|
||||
} else {
|
||||
@@ -578,7 +578,7 @@ s16 amCalculateSlotWidth(void)
|
||||
}
|
||||
|
||||
#if VERSION >= VERSION_NTSC_1_0
|
||||
if (PLAYERCOUNT() > 1) {
|
||||
if (LOCALPLAYERCOUNT() > 1) {
|
||||
max += 3;
|
||||
} else {
|
||||
max += 4;
|
||||
@@ -762,32 +762,32 @@ void amClose(void)
|
||||
bool amIsCramped(void)
|
||||
{
|
||||
#if VERSION == VERSION_JPN_FINAL
|
||||
if (PLAYERCOUNT() >= 3 && g_AmMenus[g_AmIndex].screenindex != 1) {
|
||||
if (LOCALPLAYERCOUNT() >= 3 && g_AmMenus[g_AmIndex].screenindex != 1) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (IS4MB() && PLAYERCOUNT() == 2) {
|
||||
if (IS4MB() && LOCALPLAYERCOUNT() == 2) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (optionsGetScreenSplit() == SCREENSPLIT_VERTICAL
|
||||
&& PLAYERCOUNT() == 2
|
||||
&& LOCALPLAYERCOUNT() == 2
|
||||
&& g_AmMenus[g_AmIndex].screenindex != 1) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
#else
|
||||
return (g_AmMenus[g_AmIndex].screenindex == 0 && PLAYERCOUNT() >= 3)
|
||||
|| (IS4MB() && PLAYERCOUNT() == 2)
|
||||
|| (PLAYERCOUNT() == 2 && optionsGetScreenSplit() == SCREENSPLIT_VERTICAL);
|
||||
return (g_AmMenus[g_AmIndex].screenindex == 0 && LOCALPLAYERCOUNT() >= 3)
|
||||
|| (IS4MB() && LOCALPLAYERCOUNT() == 2)
|
||||
|| (LOCALPLAYERCOUNT() == 2 && optionsGetScreenSplit() == SCREENSPLIT_VERTICAL);
|
||||
#endif
|
||||
}
|
||||
|
||||
void amCalculateSlotPosition(s16 column, s16 row, s16 *x, s16 *y)
|
||||
{
|
||||
#if VERSION == VERSION_JPN_FINAL
|
||||
s32 playercount = PLAYERCOUNT();
|
||||
s32 playercount = LOCALPLAYERCOUNT();
|
||||
|
||||
*x = g_AmMenus[g_AmIndex].xradius * (column - 1);
|
||||
*y = (row - 1) * 50;
|
||||
@@ -841,7 +841,7 @@ void amCalculateSlotPosition(s16 column, s16 row, s16 *x, s16 *y)
|
||||
}
|
||||
}
|
||||
#elif VERSION >= VERSION_NTSC_1_0
|
||||
s32 playercount = PLAYERCOUNT();
|
||||
s32 playercount = LOCALPLAYERCOUNT();
|
||||
|
||||
*x = g_AmMenus[g_AmIndex].xradius * (column - 1);
|
||||
*y = (row - 1) * 50;
|
||||
@@ -893,7 +893,7 @@ void amCalculateSlotPosition(s16 column, s16 row, s16 *x, s16 *y)
|
||||
}
|
||||
}
|
||||
#else
|
||||
s32 playercount = PLAYERCOUNT();
|
||||
s32 playercount = LOCALPLAYERCOUNT();
|
||||
|
||||
*x = g_AmMenus[g_AmIndex].xradius * (column - 1);
|
||||
*y = (row - 1) * 50;
|
||||
@@ -973,15 +973,15 @@ Gfx *amRenderAibotInfo(Gfx *gdl, s32 buddynum)
|
||||
#endif
|
||||
|
||||
#if VERSION >= VERSION_NTSC_1_0
|
||||
if (PLAYERCOUNT() == 1 && optionsGetEffectiveScreenSize() != SCREENSIZE_FULL) {
|
||||
if (LOCALPLAYERCOUNT() == 1 && optionsGetEffectiveScreenSize() != SCREENSIZE_FULL) {
|
||||
wide = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if VERSION >= VERSION_NTSC_1_0
|
||||
if ((PLAYERCOUNT() == 2 && (optionsGetScreenSplit() == SCREENSPLIT_VERTICAL || IS4MB())) || PLAYERCOUNT() >= 3)
|
||||
if ((LOCALPLAYERCOUNT() == 2 && (optionsGetScreenSplit() == SCREENSPLIT_VERTICAL || IS4MB())) || LOCALPLAYERCOUNT() >= 3)
|
||||
#else
|
||||
if ((PLAYERCOUNT() == 2 && optionsGetScreenSplit() == SCREENSPLIT_VERTICAL) || PLAYERCOUNT() >= 3)
|
||||
if ((LOCALPLAYERCOUNT() == 2 && optionsGetScreenSplit() == SCREENSPLIT_VERTICAL) || LOCALPLAYERCOUNT() >= 3)
|
||||
#endif
|
||||
{
|
||||
if ((g_Vars.currentplayernum % 2) == 0) {
|
||||
@@ -1014,7 +1014,7 @@ Gfx *amRenderAibotInfo(Gfx *gdl, s32 buddynum)
|
||||
- (s32)(textwidth * 0.5f)
|
||||
+ offset;
|
||||
|
||||
if (PLAYERCOUNT() >= 2) {
|
||||
if (LOCALPLAYERCOUNT() >= 2) {
|
||||
y = viGetViewTop() + 5;
|
||||
} else {
|
||||
y = viGetViewTop() + 10;
|
||||
@@ -1030,12 +1030,12 @@ Gfx *amRenderAibotInfo(Gfx *gdl, s32 buddynum)
|
||||
gdl = func0f1574d0jf(gdl, &x, &y, aibotname, g_AmFont1, g_AmFont2, -1,
|
||||
0x000000ff, SCREEN_320, SCREEN_240, 0, 0);
|
||||
|
||||
y += (PLAYERCOUNT() >= 2) ? 0 : (s32)(textheight * 1.1f);
|
||||
y += (LOCALPLAYERCOUNT() >= 2) ? 0 : (s32)(textheight * 1.1f);
|
||||
#else
|
||||
gdl = textRender(gdl, &x, &y, aibotname, g_AmFont1, g_AmFont2, -1,
|
||||
0x000000ff, SCREEN_320, SCREEN_240, 0, 0);
|
||||
|
||||
y += (PLAYERCOUNT() >= 2) ? 0 : (s32)(textheight * 1.1f);
|
||||
y += (LOCALPLAYERCOUNT() >= 2) ? 0 : (s32)(textheight * 1.1f);
|
||||
textMeasure(&textheight, &textwidth, weaponname, g_AmFont1, g_AmFont2, 0);
|
||||
|
||||
x = viGetViewLeft() / g_ScaleX
|
||||
@@ -1064,7 +1064,7 @@ Gfx *amRenderAibotInfo(Gfx *gdl, s32 buddynum)
|
||||
- (s32)(textwidth * 0.5f)
|
||||
+ offset;
|
||||
|
||||
if (PLAYERCOUNT() >= 2) {
|
||||
if (LOCALPLAYERCOUNT() >= 2) {
|
||||
y = viGetViewTop() + 5;
|
||||
} else {
|
||||
y = viGetViewTop() + 10;
|
||||
@@ -1123,7 +1123,7 @@ Gfx *amRenderSlot(Gfx *gdl, char *text, s16 x, s16 y, s32 mode, s32 flags)
|
||||
paddingtop = 6;
|
||||
paddingbottom = 6;
|
||||
|
||||
if (PLAYERCOUNT() >= 2) {
|
||||
if (LOCALPLAYERCOUNT() >= 2) {
|
||||
paddingtop = 5;
|
||||
paddingbottom = 3;
|
||||
}
|
||||
@@ -1262,7 +1262,7 @@ Gfx *amRender(Gfx *gdl)
|
||||
#endif
|
||||
|
||||
#ifndef PLATFORM_N64
|
||||
const s32 playercount = PLAYERCOUNT();
|
||||
const s32 playercount = LOCALPLAYERCOUNT();
|
||||
if (playercount < 2 || (playercount == 2 && optionsGetScreenSplit() == SCREENSPLIT_HORIZONTAL)) {
|
||||
gSPSetExtraGeometryModeEXT(gdl++, G_ASPECT_CENTER_EXT);
|
||||
}
|
||||
@@ -1487,7 +1487,7 @@ Gfx *amRender(Gfx *gdl)
|
||||
above = 6;
|
||||
below = 6;
|
||||
|
||||
if (PLAYERCOUNT() >= 2) {
|
||||
if (LOCALPLAYERCOUNT() >= 2) {
|
||||
above = 5;
|
||||
below = 3;
|
||||
}
|
||||
@@ -1510,7 +1510,7 @@ Gfx *amRender(Gfx *gdl)
|
||||
halfwidth = 1;
|
||||
above = 2;
|
||||
below = 0;
|
||||
} else if (PLAYERCOUNT() >= 2) {
|
||||
} else if (LOCALPLAYERCOUNT() >= 2) {
|
||||
s32 textheight;
|
||||
s32 textwidth;
|
||||
char text[32];
|
||||
@@ -1592,16 +1592,16 @@ Gfx *amRender(Gfx *gdl)
|
||||
}
|
||||
#endif
|
||||
|
||||
barwidth = PLAYERCOUNT() >= 2 ? 48 : 64;
|
||||
barheight = PLAYERCOUNT() >= 2 ? 7 : 11;
|
||||
barwidth = LOCALPLAYERCOUNT() >= 2 ? 48 : 64;
|
||||
barheight = LOCALPLAYERCOUNT() >= 2 ? 7 : 11;
|
||||
xoffset = 0;
|
||||
|
||||
#if VERSION >= VERSION_NTSC_1_0
|
||||
if ((PLAYERCOUNT() == 2 && (optionsGetScreenSplit() == SCREENSPLIT_VERTICAL || IS4MB())) || PLAYERCOUNT() >= 3) {
|
||||
if ((LOCALPLAYERCOUNT() == 2 && (optionsGetScreenSplit() == SCREENSPLIT_VERTICAL || IS4MB())) || LOCALPLAYERCOUNT() >= 3) {
|
||||
xoffset = (g_Vars.currentplayernum & 1) == 0 ? 8 : -8;
|
||||
}
|
||||
|
||||
if (PLAYERCOUNT() == 1 && optionsGetEffectiveScreenSize() != SCREENSIZE_FULL) {
|
||||
if (LOCALPLAYERCOUNT() == 1 && optionsGetEffectiveScreenSize() != SCREENSIZE_FULL) {
|
||||
part1left = viGetViewLeft() / g_ScaleX + 32;
|
||||
} else {
|
||||
part1left = (s32) ((viGetViewWidth() / g_ScaleX) * 0.5f)
|
||||
@@ -1610,7 +1610,7 @@ Gfx *amRender(Gfx *gdl)
|
||||
+ xoffset;
|
||||
}
|
||||
#else
|
||||
if ((PLAYERCOUNT() == 2 && optionsGetScreenSplit() == SCREENSPLIT_VERTICAL) || PLAYERCOUNT() >= 3) {
|
||||
if ((LOCALPLAYERCOUNT() == 2 && optionsGetScreenSplit() == SCREENSPLIT_VERTICAL) || LOCALPLAYERCOUNT() >= 3) {
|
||||
xoffset = (g_Vars.currentplayernum & 1) == 0 ? 8 : -8;
|
||||
}
|
||||
|
||||
@@ -1636,7 +1636,7 @@ Gfx *amRender(Gfx *gdl)
|
||||
gDPSetRenderMode(gdl++, G_RM_XLU_SURF, G_RM_XLU_SURF2);
|
||||
gDPSetCombineMode(gdl++, G_CC_PRIMITIVE, G_CC_PRIMITIVE);
|
||||
|
||||
y = viGetViewTop() + viGetViewHeight() - (PLAYERCOUNT() >= 2 ? 19 : 34);
|
||||
y = viGetViewTop() + viGetViewHeight() - (LOCALPLAYERCOUNT() >= 2 ? 19 : 34);
|
||||
|
||||
// NTSC beta doesn't scale the health bar when hi-res is on,
|
||||
// and it only matches if part2left is an inline expression
|
||||
|
||||
@@ -22,7 +22,7 @@ void amTick(void)
|
||||
s32 prevplayernum = g_Vars.currentplayernum;
|
||||
s32 i;
|
||||
|
||||
for (i = 0; i < PLAYERCOUNT(); i++) {
|
||||
for (i = 0; i < LOCALPLAYERCOUNT(); i++) {
|
||||
setCurrentPlayerNum(i);
|
||||
g_AmIndex = g_Vars.currentplayernum;
|
||||
|
||||
|
||||
+1
-15
@@ -15,7 +15,7 @@
|
||||
#include "game/sky.h"
|
||||
#include "game/stars.h"
|
||||
#include "game/dyntex.h"
|
||||
#include "game/artifact.h"
|
||||
#include "game/game_13c510.h"
|
||||
#include "game/game_1531a0.h"
|
||||
#include "game/gfxmemory.h"
|
||||
#include "game/gfxreplace.h"
|
||||
@@ -135,9 +135,6 @@ s32 g_BgMostAttemptedDrawSlots = 0;
|
||||
s32 g_BgNumRoomLoadCandidates = 0;
|
||||
u16 g_BgFrameCount = 0xfffe;
|
||||
s32 g_BgNumPortalCameraCacheItems = 0;
|
||||
#ifndef PLATFORM_N64
|
||||
bool g_BgHitXluDisabled = false;
|
||||
#endif
|
||||
|
||||
void bgUnpausePropsInRoom(u32 roomnum, bool tintedglassonly)
|
||||
{
|
||||
@@ -4593,10 +4590,6 @@ bool bgTestHitInRoom(struct coord *frompos, struct coord *topos, s32 roomnum, st
|
||||
numbatches = g_Rooms[roomnum].numvtxbatches;
|
||||
|
||||
for (i = 0; i < numbatches; batch++, i++) {
|
||||
#ifndef PLATFORM_N64
|
||||
if (g_BgHitXluDisabled && batch->type == VTXBATCHTYPE_XLU)
|
||||
continue;
|
||||
#endif
|
||||
j = bg0f1612e4(&batch->bbmin, &batch->bbmax, &from, &dist, &sp94, &hitthing->pos);
|
||||
|
||||
if (j == 0) {
|
||||
@@ -6424,10 +6417,6 @@ void bgCalculateGlaresForVisibleRooms(void)
|
||||
|
||||
g_NumRoomsWithGlares = 0;
|
||||
|
||||
// disable line-of-sight hits for transparent background
|
||||
// surfaces before testing for light obstructions
|
||||
g_BgHitXluDisabled = true;
|
||||
|
||||
if (!g_Vars.mplayerisrunning) {
|
||||
for (i = 1; i < g_Vars.roomcount; i++) {
|
||||
if (g_Rooms[i].flags & ROOMFLAG_ONSCREEN) {
|
||||
@@ -6438,9 +6427,6 @@ void bgCalculateGlaresForVisibleRooms(void)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// re-enable background hits for transparent surfaces
|
||||
g_BgHitXluDisabled = false;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1016,7 +1016,7 @@ void eyespyProcessInput(bool allowbuttons)
|
||||
// Make eyespy look horizontally
|
||||
if (domovecentre) {
|
||||
if (g_Vars.currentplayer->eyespy->verta > 0.0f && forwardspeed != 0) {
|
||||
if (controlmode != CONTROLMODE_PC) {
|
||||
if (controlmode < CONTROLMODE_PC) {
|
||||
if (g_Vars.currentplayer->eyespy->verta < 180.0f) {
|
||||
tmp = g_Vars.currentplayer->eyespy->verta;
|
||||
|
||||
|
||||
+60
-10
@@ -54,9 +54,11 @@
|
||||
#include "data.h"
|
||||
#include "types.h"
|
||||
#ifndef PLATFORM_N64
|
||||
#include "platform.h"
|
||||
#include "game/stagetable.h"
|
||||
#include "video.h"
|
||||
#include "platform.h"
|
||||
#include "net/net.h"
|
||||
#include "net/netmsg.h"
|
||||
#endif
|
||||
|
||||
#define GUNLOADSTATE_FLUX 0
|
||||
@@ -4481,7 +4483,7 @@ struct defaultobj *bgunCreateThrownProjectile2(struct chrdata *chr, struct gset
|
||||
* 2 = fumbling grenade from right hand (due to nbomb)
|
||||
* 3 = fumbling grenade from left hand (actually not possible)
|
||||
*/
|
||||
void bgunCreateThrownProjectile(s32 handnum, struct gset *gset)
|
||||
struct defaultobj *bgunCreateThrownProjectile(s32 handnum, struct gset *gset)
|
||||
{
|
||||
struct coord velocity = {0, 0, 0};
|
||||
Mtxf sp1f4;
|
||||
@@ -4511,6 +4513,13 @@ void bgunCreateThrownProjectile(s32 handnum, struct gset *gset)
|
||||
struct trainingdata *data;
|
||||
u32 stack;
|
||||
|
||||
#ifndef PLATFORM_N64
|
||||
// don't do anything if we're not the authority
|
||||
if (g_NetMode == NETMODE_CLIENT) {
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (handnum >= 2) {
|
||||
droppinggrenade = true;
|
||||
handnum -= 2;
|
||||
@@ -4676,7 +4685,16 @@ void bgunCreateThrownProjectile(s32 handnum, struct gset *gset)
|
||||
weapon->base.hidden |= OBJHFLAG_THROWNKNIFE;
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef PLATFORM_N64
|
||||
if (obj && g_NetMode == NETMODE_SERVER) {
|
||||
netmsgSvcPropSpawnWrite(&g_NetMsgRel, obj->prop);
|
||||
netmsgSvcPropMoveWrite(&g_NetMsgRel, obj->prop, NULL);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
void bgunUpdateHeldRocket(s32 handnum)
|
||||
@@ -4780,6 +4798,12 @@ void bgunCreateFiredProjectile(s32 handnum)
|
||||
f32 spd4[4];
|
||||
f32 spc4[4];
|
||||
|
||||
#ifndef PLATFORM_N64
|
||||
if (g_NetMode == NETMODE_CLIENT) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
hand = g_Vars.currentplayer->hands + handnum;
|
||||
|
||||
playerprop = g_Vars.currentplayer->prop;
|
||||
@@ -4992,6 +5016,12 @@ void bgunCreateFiredProjectile(s32 handnum)
|
||||
weapon->base.prop = NULL;
|
||||
weapon->base.model = NULL;
|
||||
}
|
||||
#ifndef PLATFORM_N64
|
||||
else if (g_NetMode == NETMODE_SERVER) {
|
||||
netmsgSvcPropSpawnWrite(&g_NetMsgRel, weapon->base.prop);
|
||||
netmsgSvcPropMoveWrite(&g_NetMsgRel, weapon->base.prop, NULL);
|
||||
}
|
||||
#endif
|
||||
#else
|
||||
// NTSC beta doesn't have any of the failure checks
|
||||
Mtxf sp78;
|
||||
@@ -6322,6 +6352,13 @@ void bgunDisarm(struct prop *attackerprop)
|
||||
s32 modelnum;
|
||||
s32 i;
|
||||
bool drop;
|
||||
struct defaultobj *obj;
|
||||
#ifndef PLATFORM_N64
|
||||
// don't do anything if we're not the authority
|
||||
if (g_NetMode == NETMODE_CLIENT) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!weaponHasFlag(weaponnum, WEAPONFLAG_UNDROPPABLE) && weaponnum <= WEAPON_RCP45) {
|
||||
#if VERSION >= VERSION_NTSC_1_0
|
||||
@@ -6339,6 +6376,12 @@ void bgunDisarm(struct prop *attackerprop)
|
||||
return;
|
||||
}
|
||||
|
||||
#ifndef PLATFORM_N64
|
||||
if (g_NetMode == NETMODE_SERVER) {
|
||||
netmsgSvcChrDisarmWrite(&g_NetMsgRel, player->prop->chr, attackerprop, weaponnum, 0.f, NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
chr = player->prop->chr;
|
||||
drop = true;
|
||||
|
||||
@@ -6367,7 +6410,7 @@ void bgunDisarm(struct prop *attackerprop)
|
||||
&& player->hands[i].stateminor == HANDSTATEMINOR_ATTACK_THROW_0) {
|
||||
#endif
|
||||
drop = false;
|
||||
bgunCreateThrownProjectile(i + 2, &player->hands[i].gset);
|
||||
obj = bgunCreateThrownProjectile(i + 2, &player->hands[i].gset);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6391,6 +6434,13 @@ void bgunDisarm(struct prop *attackerprop)
|
||||
}
|
||||
|
||||
objDrop(prop2, true);
|
||||
|
||||
#ifndef PLATFORM_N64
|
||||
if (g_NetMode == NETMODE_SERVER) {
|
||||
netmsgSvcPropSpawnWrite(&g_NetMsgRel, prop2);
|
||||
netmsgSvcPropMoveWrite(&g_NetMsgRel, prop2, NULL);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8477,7 +8527,7 @@ glabel var7f1aca90
|
||||
/* f0a71e4: 100002d5 */ b .L0f0a7d3c
|
||||
/* f0a71e8: 8fbf0034 */ lw $ra,0x34($sp)
|
||||
.L0f0a71ec:
|
||||
/* f0a71ec: 0fc5d9ad */ jal zbufSaveArtifactDepths
|
||||
/* f0a71ec: 0fc5d9ad */ jal zbufDrawArtifactsOffscreen
|
||||
/* f0a71f0: 8fa4014c */ lw $a0,0x14c($sp)
|
||||
/* f0a71f4: afa2014c */ sw $v0,0x14c($sp)
|
||||
/* f0a71f8: 0c002ca0 */ jal viPrepareZbuf
|
||||
@@ -9318,7 +9368,7 @@ glabel var7f1aca90
|
||||
/* f0a71e4: 100002d5 */ b .L0f0a7d3c
|
||||
/* f0a71e8: 8fbf0034 */ lw $ra,0x34($sp)
|
||||
.L0f0a71ec:
|
||||
/* f0a71ec: 0fc5d9ad */ jal zbufSaveArtifactDepths
|
||||
/* f0a71ec: 0fc5d9ad */ jal zbufDrawArtifactsOffscreen
|
||||
/* f0a71f0: 8fa4014c */ lw $a0,0x14c($sp)
|
||||
/* f0a71f4: afa2014c */ sw $v0,0x14c($sp)
|
||||
/* f0a71f8: 0c002ca0 */ jal viPrepareZbuf
|
||||
@@ -10159,7 +10209,7 @@ glabel var7f1aca90
|
||||
/* f0a4f30: 100002cd */ beqz $zero,.NB0f0a5a68
|
||||
/* f0a4f34: 8fbf0034 */ lw $ra,0x34($sp)
|
||||
.NB0f0a4f38:
|
||||
/* f0a4f38: 0fc5c4d5 */ jal zbufSaveArtifactDepths
|
||||
/* f0a4f38: 0fc5c4d5 */ jal zbufDrawArtifactsOffscreen
|
||||
/* f0a4f3c: 8fa40144 */ lw $a0,0x144($sp)
|
||||
/* f0a4f40: afa20144 */ sw $v0,0x144($sp)
|
||||
/* f0a4f44: 0c002d00 */ jal viPrepareZbuf
|
||||
@@ -10957,7 +11007,7 @@ void bgunRender(Gfx **gdlptr)
|
||||
}
|
||||
|
||||
#ifdef PLATFORM_N64 // TODO
|
||||
gdl = zbufSaveArtifactDepths(gdl);
|
||||
gdl = zbufDrawArtifactsOffscreen(gdl);
|
||||
#endif
|
||||
gdl = viPrepareZbuf(gdl);
|
||||
gdl = vi0000b1d0(gdl);
|
||||
@@ -11732,7 +11782,7 @@ void bgunSetTriggerOn(s32 handnum, bool on)
|
||||
s32 bgunConsiderToggleGunFunction(s32 usedowntime, bool trigpressed, bool fromactivemenu, bool fromdedicatedbutton)
|
||||
{
|
||||
#ifndef PLATFORM_N64
|
||||
const bool extcontrols = PLAYER_EXTCFG().extcontrols;
|
||||
const bool extcontrols = PLAYER_EXTCFG().extcontrols || g_Vars.currentplayer->isremote;
|
||||
bool docontinue;
|
||||
#endif
|
||||
switch (bgunGetWeaponNum(HAND_RIGHT)) {
|
||||
@@ -11851,7 +11901,7 @@ void bgun0f0a8c50(void)
|
||||
case WEAPON_LAPTOPGUN:
|
||||
case WEAPON_DRAGON:
|
||||
case WEAPON_REMOTEMINE:
|
||||
if (PLAYER_EXTCFG().extcontrols) {
|
||||
if (PLAYER_EXTCFG().extcontrols || g_Vars.currentplayer->isremote) {
|
||||
return;
|
||||
}
|
||||
break;
|
||||
@@ -12754,7 +12804,7 @@ Gfx *bgunDrawHud(Gfx *gdl)
|
||||
{
|
||||
struct player *player = g_Vars.currentplayer;
|
||||
s32 bottom = viGetViewTop() + viGetViewHeight() - 13;
|
||||
s32 playercount = PLAYERCOUNT();
|
||||
s32 playercount = LOCALPLAYERCOUNT();
|
||||
s32 playernum = g_Vars.currentplayernum;
|
||||
struct gunctrl *ctrl;
|
||||
s32 secs60;
|
||||
|
||||
+252
-93
@@ -42,6 +42,10 @@
|
||||
#include <math.h>
|
||||
#include "input.h"
|
||||
#include "video.h"
|
||||
#include "system.h"
|
||||
#include "utils.h"
|
||||
#include "net/net.h"
|
||||
#include "net/netmsg.h"
|
||||
|
||||
static void bgunProcessQuickDetonate(struct movedata *data, u32 c1buttons, u32 c1buttonsthisframe, u32 buttons1, u32 buttons2) {
|
||||
if ((((c1buttons & (buttons1)) && (c1buttonsthisframe & (buttons2)))
|
||||
@@ -105,6 +109,159 @@ static void bgunProcessInputAltButton(struct movedata *data, s8 contpad, s32 i)
|
||||
}
|
||||
}
|
||||
|
||||
static inline void bmoveProcessRemoteInput(const bool allowc1buttons)
|
||||
{
|
||||
struct player *pl = g_Vars.currentplayer;
|
||||
if (!pl->client) {
|
||||
return;
|
||||
}
|
||||
|
||||
struct netplayermove *inmove = &pl->client->inmove[0];
|
||||
struct netplayermove *inmoveprev = &pl->client->inmove[1];
|
||||
s32 moveticks = inmove->tick - inmoveprev->tick;
|
||||
if (moveticks > g_NetInterpTicks) {
|
||||
moveticks = g_NetInterpTicks;
|
||||
}
|
||||
|
||||
const bool handled = (pl->client->inmovetick >= inmove->tick);
|
||||
|
||||
if (!inmove->tick) {
|
||||
// no input
|
||||
inmove->pos = inmoveprev->pos = pl->prop->pos;
|
||||
inmove->angles[0] = inmoveprev->angles[0] = pl->vv_theta;
|
||||
inmove->angles[1] = inmoveprev->angles[1] = pl->vv_verta;
|
||||
inmove->ucmd = 0;
|
||||
}
|
||||
|
||||
if (inmove->ucmd & UCMD_DUCK) {
|
||||
pl->crouchpos = CROUCHPOS_DUCK;
|
||||
} else if (inmove->ucmd & UCMD_SQUAT) {
|
||||
pl->crouchpos = CROUCHPOS_SQUAT;
|
||||
} else {
|
||||
pl->crouchpos = CROUCHPOS_STAND;
|
||||
}
|
||||
|
||||
pl->bondactivateorreload = 0;
|
||||
|
||||
pl->eyesshut = (inmove->ucmd & UCMD_EYESSHUT) != 0;
|
||||
|
||||
pl->speedtheta = 0.f; // TODO: figure out if anglespeed is even required
|
||||
pl->speedverta = 0.f;
|
||||
pl->crouchoffset = inmove->crouchofs;
|
||||
|
||||
pl->oldcrosspos[0] = pl->crosspos[0];
|
||||
pl->oldcrosspos[1] = pl->crosspos[1];
|
||||
pl->crosspos[0] = inmove->crosspos[0];
|
||||
pl->crosspos[1] = inmove->crosspos[1];
|
||||
|
||||
// denormalize crosspos x
|
||||
pl->crosspos[0] -= (f32)(SCREEN_WIDTH_LO / 2);
|
||||
pl->crosspos[0] = (f32)(SCREEN_WIDTH_LO / 2) + pl->crosspos[0] / pl->aspect * SCREEN_ASPECT;
|
||||
|
||||
pl->crosspos2[0] = pl->crosspos[0];
|
||||
pl->crosspos2[1] = pl->crosspos[1];
|
||||
|
||||
pl->insightaimmode = (inmove->ucmd & UCMD_AIMMODE) != 0;
|
||||
if (pl->insightaimmode) {
|
||||
pl->gunzoomfovs[0] = pl->gunzoomfovs[1] = pl->gunzoomfovs[2] = inmove->zoomfov;
|
||||
}
|
||||
|
||||
f32 zoomfov = 0.f;
|
||||
if (pl->insightaimmode) {
|
||||
zoomfov = currentPlayerGetGunZoomFov();
|
||||
}
|
||||
if (bgunGetWeaponNum(HAND_RIGHT) == WEAPON_AR34 && pl->hands[HAND_RIGHT].gset.weaponfunc == FUNC_SECONDARY) {
|
||||
zoomfov = currentPlayerGetGunZoomFov();
|
||||
}
|
||||
if (zoomfov <= 0.f) {
|
||||
zoomfov = pl->client->settings.fovy;
|
||||
}
|
||||
playerTweenFovY(zoomfov);
|
||||
playerUpdateZoom();
|
||||
|
||||
for (s32 h = 0; h < 2; ++h) {
|
||||
pl->hands[h].crosspos[0] = pl->crosspos[0];
|
||||
pl->hands[h].crosspos[1] = pl->crosspos[1];
|
||||
}
|
||||
|
||||
if (inmove->ucmd & UCMD_SELECT) {
|
||||
pl->gunctrl.dualwielding = (inmove->ucmd & UCMD_SELECT_DUAL) != 0;
|
||||
if (inmove->weaponnum >= 0) {
|
||||
bgunEquipWeapon(inmove->weaponnum);
|
||||
}
|
||||
}
|
||||
|
||||
if ((inmove->ucmd & UCMD_SECONDARY) && !bgunIsUsingSecondaryFunction()) {
|
||||
bgunConsiderToggleGunFunction(0, false, false, true);
|
||||
} else if (!(inmove->ucmd & UCMD_SECONDARY) && bgunIsUsingSecondaryFunction()) {
|
||||
// do not switch back to primary if in the process of throwing laptop
|
||||
if (!(bgunGetWeaponNum(HAND_RIGHT) == WEAPON_LAPTOPGUN && pl->hands[HAND_RIGHT].state == HANDSTATE_ATTACK)) {
|
||||
bgunConsiderToggleGunFunction(0, false, false, true);
|
||||
}
|
||||
}
|
||||
|
||||
const bool fireguns = (inmove->ucmd & UCMD_FIRE) && !pl->waitforzrelease && allowc1buttons;
|
||||
|
||||
bgunTickGameplay(fireguns);
|
||||
|
||||
if (fireguns && g_NetMode == NETMODE_SERVER) {
|
||||
netmsgSvcPlayerStatsWrite(&g_NetMsgRel, pl->client);
|
||||
}
|
||||
|
||||
if (!handled && (inmove->ucmd & UCMD_RELOAD)) {
|
||||
pl->bondactivateorreload |= JO_ACTION_RELOAD;
|
||||
}
|
||||
|
||||
if (g_NetMode == NETMODE_SERVER) {
|
||||
if (!handled && (inmove->ucmd & UCMD_ACTIVATE)) {
|
||||
pl->bondactivateorreload |= JO_ACTION_ACTIVATE;
|
||||
}
|
||||
|
||||
if (g_Vars.bondvisible && (bgunIsFiring(HAND_RIGHT) || bgunIsFiring(HAND_LEFT))) {
|
||||
f32 noiseradius = 0.f;
|
||||
if (bgunIsFiring(HAND_RIGHT) && bgunGetNoiseRadius(HAND_RIGHT) > noiseradius) {
|
||||
noiseradius = bgunGetNoiseRadius(HAND_RIGHT);
|
||||
}
|
||||
if (bgunIsFiring(HAND_LEFT) && bgunGetNoiseRadius(HAND_LEFT) > noiseradius) {
|
||||
noiseradius = bgunGetNoiseRadius(HAND_LEFT);
|
||||
}
|
||||
chrsCheckForNoise(noiseradius);
|
||||
}
|
||||
}
|
||||
|
||||
bgunSetSightVisible(GUNSIGHTREASON_NOTAIMING, pl->insightaimmode);
|
||||
|
||||
const bool forcepos = !inmoveprev->tick || !moveticks || (inmove->ucmd & UCMD_FL_FORCEANGLE);
|
||||
|
||||
// lerp towards the current speeds and angles
|
||||
const f32 dt = (forcepos ? 1.f : (1.f / (f32)moveticks));
|
||||
f32 t = (forcepos ? 1.f : ((f32)pl->client->lerpticks / (f32)moveticks));
|
||||
if (t > 1.f) {
|
||||
t = 1.f;
|
||||
}
|
||||
pl->speedgo = pl->speedforwards = lerpf(inmoveprev->movespeed[0], inmove->movespeed[0], t);
|
||||
pl->speedstrafe = pl->speedsideways = lerpf(inmoveprev->movespeed[1], inmove->movespeed[1], t);
|
||||
pl->vv_theta = lerpanglef(pl->vv_theta, inmove->angles[0], dt);
|
||||
pl->vv_verta = lerpanglef(pl->vv_verta, inmove->angles[1], dt);
|
||||
|
||||
if (pl->bondmovemode == MOVEMODE_GRAB) {
|
||||
bgrabUpdateSpeedTheta();
|
||||
} else if (pl->bondmovemode == MOVEMODE_WALK) {
|
||||
if (bmoveGetCrouchPos() != CROUCHPOS_STAND) {
|
||||
pl->speedmaxtime60 = 0;
|
||||
}
|
||||
bwalkSetSwayTargetf(inmove->leanofs);
|
||||
} else if (pl->bondmovemode == MOVEMODE_BIKE) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
if (inmove->movespeed[0] > 0.95f) {
|
||||
pl->speedmaxtime60 += g_Vars.lvupdate60;
|
||||
} else {
|
||||
pl->speedmaxtime60 = 0;
|
||||
}
|
||||
}
|
||||
|
||||
#endif // PLATFORM_N64
|
||||
|
||||
void bmoveSetControlDef(u32 controldef)
|
||||
@@ -313,6 +470,39 @@ void bmoveApplyMoveData(struct movedata *data)
|
||||
} else if (g_Vars.currentplayer->bondmovemode == MOVEMODE_WALK) {
|
||||
bwalkApplyMoveData(data);
|
||||
}
|
||||
|
||||
#ifndef PLATFORM_N64
|
||||
// record some inputs if this is a local player
|
||||
if (g_NetMode && !g_Vars.currentplayer->isremote) {
|
||||
g_Vars.currentplayer->ucmd = 0;
|
||||
if (g_Vars.currentplayer->isdead) {
|
||||
if (g_NetMode == NETMODE_CLIENT) {
|
||||
if (joyGetButtons(optionsGetContpadNum1(g_Vars.currentplayerstats->mpindex), 0xb000)) {
|
||||
g_Vars.currentplayer->ucmd |= UCMD_RESPAWN;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (data->triggeron) {
|
||||
g_Vars.currentplayer->ucmd |= UCMD_FIRE;
|
||||
}
|
||||
if (data->aiming) {
|
||||
g_Vars.currentplayer->ucmd |= UCMD_AIMMODE;
|
||||
}
|
||||
if (g_Vars.currentplayer->bondactivateorreload & JO_ACTION_ACTIVATE) {
|
||||
g_Vars.currentplayer->ucmd |= UCMD_ACTIVATE;
|
||||
}
|
||||
if (g_Vars.currentplayer->bondactivateorreload & JO_ACTION_RELOAD) {
|
||||
g_Vars.currentplayer->ucmd |= UCMD_RELOAD;
|
||||
}
|
||||
if (data->eyesshut) {
|
||||
g_Vars.currentplayer->ucmd |= UCMD_EYESSHUT;
|
||||
}
|
||||
if (data->weaponbackoffset || data->weaponforwardoffset) {
|
||||
g_Vars.currentplayer->ucmd |= UCMD_SELECT;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void bmoveUpdateSpeedTheta(void)
|
||||
@@ -329,11 +519,11 @@ void bmoveUpdateSpeedTheta(void)
|
||||
f32 bmoveGetSpeedVertaLimit(f32 value)
|
||||
{
|
||||
if (value > 0) {
|
||||
return (viGetFovY() * value * -0.7f) / PLAYER_DEFAULT_FOV;
|
||||
return (viGetFovY() * value * -0.7f) / 60.0f;
|
||||
}
|
||||
|
||||
if (value < 0) {
|
||||
return (viGetFovY() * -value * 0.7f) / PLAYER_DEFAULT_FOV;
|
||||
return (viGetFovY() * -value * 0.7f) / 60.0f;
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -341,7 +531,7 @@ f32 bmoveGetSpeedVertaLimit(f32 value)
|
||||
|
||||
void bmoveUpdateSpeedVerta(f32 value)
|
||||
{
|
||||
f32 mult = viGetFovY() / PLAYER_DEFAULT_FOV;
|
||||
f32 mult = viGetFovY() / 60.0f;
|
||||
f32 limit = bmoveGetSpeedVertaLimit(value);
|
||||
|
||||
if (value > 0) {
|
||||
@@ -384,11 +574,11 @@ void bmoveUpdateSpeedVerta(f32 value)
|
||||
f32 bmoveGetSpeedThetaControlLimit(f32 value)
|
||||
{
|
||||
if (value > 0) {
|
||||
return (viGetFovY() * value * -0.7f) / PLAYER_DEFAULT_FOV;
|
||||
return (viGetFovY() * value * -0.7f) / 60.0f;
|
||||
}
|
||||
|
||||
if (value < 0) {
|
||||
return (viGetFovY() * -value * 0.7f) / PLAYER_DEFAULT_FOV;
|
||||
return (viGetFovY() * -value * 0.7f) / 60.0f;
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -396,7 +586,7 @@ f32 bmoveGetSpeedThetaControlLimit(f32 value)
|
||||
|
||||
void bmoveUpdateSpeedThetaControl(f32 value)
|
||||
{
|
||||
f32 mult = viGetFovY() / PLAYER_DEFAULT_FOV;
|
||||
f32 mult = viGetFovY() / 60.0f;
|
||||
f32 limit = bmoveGetSpeedThetaControlLimit(value);
|
||||
|
||||
if (value > 0) {
|
||||
@@ -436,38 +626,6 @@ void bmoveUpdateSpeedThetaControl(f32 value)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply crosshair swivel based on camera movement with input detection
|
||||
*/
|
||||
static void bmoveApplyCrosshairSwivel(struct movedata *movedata, f32 mlookscale, f32 *x, f32 *y)
|
||||
{
|
||||
#ifdef PLATFORM_N64
|
||||
*x = g_Vars.currentplayer->speedtheta * 0.3f + g_Vars.currentplayer->gunextraaimx;
|
||||
*y = -g_Vars.currentplayer->speedverta * 0.1f + g_Vars.currentplayer->gunextraaimy;
|
||||
#else
|
||||
f32 xscale, yscale;
|
||||
bool mouse_active = (movedata->freelookdx || movedata->freelookdy);
|
||||
bool joystick_active = (movedata->c1stickxraw != 0 || movedata->c1stickyraw != 0);
|
||||
|
||||
if ((mouse_active) && joystick_active) {
|
||||
// Mouse + joystick sway
|
||||
xscale = PLAYER_EXTCFG().crosshairsway * 0.80f; // 80% for precision+joystick sway
|
||||
yscale = PLAYER_EXTCFG().crosshairsway * 0.80f; // 80% for precision+joystick sway
|
||||
} else if (mouse_active) {
|
||||
// Mouse sway
|
||||
xscale = PLAYER_EXTCFG().crosshairsway * 0.20f; // 20% for mouse sway
|
||||
yscale = PLAYER_EXTCFG().crosshairsway * 0.30f; // 30% for mouse sway
|
||||
} else {
|
||||
// Joystick only or no input - full sway
|
||||
xscale = yscale = PLAYER_EXTCFG().crosshairsway;
|
||||
}
|
||||
// Joystick x/y scaling
|
||||
// 0.3f for x, 0.1f for y
|
||||
*x = g_Vars.currentplayer->speedtheta * 0.3f * xscale + g_Vars.currentplayer->gunextraaimx;
|
||||
*y = -g_Vars.currentplayer->speedverta * 0.1f * yscale + g_Vars.currentplayer->gunextraaimy;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the lookahead angle.
|
||||
*
|
||||
@@ -750,6 +908,14 @@ void bmoveProcessInput(bool allowc1x, bool allowc1y, bool allowc1buttons, bool i
|
||||
#endif
|
||||
|
||||
controlmode = optionsGetControlMode(g_Vars.currentplayerstats->mpindex);
|
||||
|
||||
#ifndef PLATFORM_N64
|
||||
if (g_Vars.currentplayer->isremote || controlmode == CONTROLMODE_NA) {
|
||||
bmoveProcessRemoteInput(allowc1buttons);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
weaponnum = bgunGetWeaponNum(HAND_RIGHT);
|
||||
canmanualzoom = weaponHasAimFlag(weaponnum, INVAIMFLAG_MANUALZOOM);
|
||||
contpad1 = optionsGetContpadNum1(g_Vars.currentplayerstats->mpindex);
|
||||
@@ -1065,7 +1231,7 @@ void bmoveProcessInput(bool allowc1x, bool allowc1y, bool allowc1buttons, bool i
|
||||
}
|
||||
|
||||
// Handle B button activation
|
||||
if (allowc1buttons && controlmode != CONTROLMODE_PC) {
|
||||
if (allowc1buttons && controlmode < CONTROLMODE_PC) {
|
||||
for (i = 0; i < numsamples; i++) {
|
||||
if (joyGetButtonsOnSample(i, contpad1, c1allowedbuttons & B_BUTTON)
|
||||
|| joyGetButtonsOnSample(i, contpad2, c2allowedbuttons & B_BUTTON)) {
|
||||
@@ -1444,31 +1610,31 @@ void bmoveProcessInput(bool allowc1x, bool allowc1y, bool allowc1buttons, bool i
|
||||
}
|
||||
|
||||
#ifndef PLATFORM_N64
|
||||
// Handle turning and looking (x/y) via mouselook when aiming
|
||||
bool allowcross = allowmcross;
|
||||
if (g_Vars.currentplayer->insightaimmode && allowcross && bgunGetWeaponNum(HAND_RIGHT) != WEAPON_HORIZONSCANNER) {
|
||||
float edge_boundary = PLAYER_EXTCFG().crosshairedgeboundary;
|
||||
if (g_Vars.currentplayer->swivelpos[0] > edge_boundary) {
|
||||
movedata.aimturnrightspeed += (g_Vars.currentplayer->swivelpos[0] - edge_boundary) / (1.0f - edge_boundary);
|
||||
} else if (g_Vars.currentplayer->swivelpos[0] < -edge_boundary) {
|
||||
movedata.aimturnleftspeed += (g_Vars.currentplayer->swivelpos[0] + edge_boundary) / -(1.0f - edge_boundary);
|
||||
// Handle turning and looking up/down via mouselook when aiming
|
||||
if (g_Vars.currentplayer->insightaimmode && allowmcross && bgunGetWeaponNum(HAND_RIGHT) != WEAPON_HORIZONSCANNER) {
|
||||
if (g_Vars.currentplayer->swivelpos[0] > 0.9f) {
|
||||
movedata.aimturnrightspeed = (g_Vars.currentplayer->swivelpos[0] - 0.9f) / 0.1f;
|
||||
movedata.aimturnleftspeed = 0.f;
|
||||
} else if (g_Vars.currentplayer->swivelpos[0] < -0.9f) {
|
||||
movedata.aimturnleftspeed = (g_Vars.currentplayer->swivelpos[0] - -0.9f) / -0.1f;
|
||||
movedata.aimturnrightspeed = 0.f;
|
||||
}
|
||||
f32 vertaup = 0.f, vertadown = 0.f;
|
||||
if (g_Vars.currentplayer->swivelpos[1] > edge_boundary) {
|
||||
vertaup = (g_Vars.currentplayer->swivelpos[1] - edge_boundary) / (1.0f - edge_boundary);
|
||||
} else if (g_Vars.currentplayer->swivelpos[1] < -edge_boundary) {
|
||||
vertadown = (g_Vars.currentplayer->swivelpos[1] + edge_boundary) / -(1.0f - edge_boundary);
|
||||
if (g_Vars.currentplayer->swivelpos[1] > 0.9f) {
|
||||
vertaup = (g_Vars.currentplayer->swivelpos[1] - 0.9f) / 0.1f;
|
||||
} else if (g_Vars.currentplayer->swivelpos[1] < -0.9f) {
|
||||
vertadown = (g_Vars.currentplayer->swivelpos[1] - -0.9f) / -0.1f;
|
||||
}
|
||||
// Uninvert pitch if needed
|
||||
if (movedata.invertpitch) {
|
||||
movedata.speedvertaup += vertadown;
|
||||
movedata.speedvertadown += vertaup;
|
||||
movedata.speedvertaup = vertadown;
|
||||
movedata.speedvertadown = vertaup;
|
||||
} else {
|
||||
movedata.speedvertaup += vertaup;
|
||||
movedata.speedvertadown += vertadown;
|
||||
movedata.speedvertaup = vertaup;
|
||||
movedata.speedvertadown = vertadown;
|
||||
}
|
||||
} else {
|
||||
// Reset mouse aim position when not aiming
|
||||
// Reset mouse aim position when not mouse aiming
|
||||
g_Vars.currentplayer->swivelpos[0] = 0.f;
|
||||
g_Vars.currentplayer->swivelpos[1] = 0.f;
|
||||
}
|
||||
@@ -1535,7 +1701,7 @@ void bmoveProcessInput(bool allowc1x, bool allowc1y, bool allowc1buttons, bool i
|
||||
for (i = 0; i < numsamples; i++) {
|
||||
if (joyGetButtonsOnSample(i, contpad1, c1allowedbuttons & usemask)) {
|
||||
if (g_Vars.currentplayer->usedowntime >= -1) {
|
||||
if (controlmode != CONTROLMODE_PC) {
|
||||
if (controlmode < CONTROLMODE_PC) {
|
||||
if (joyGetButtonsPressedOnSample(i, contpad1, shootbuttons & c1allowedbuttons)
|
||||
&& g_Vars.currentplayer->usedowntime >= 0
|
||||
&& bgunConsiderToggleGunFunction(g_Vars.currentplayer->usedowntime, true, false, 0) != USETIMER_CONTINUE) {
|
||||
@@ -1560,7 +1726,7 @@ void bmoveProcessInput(bool allowc1x, bool allowc1y, bool allowc1buttons, bool i
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if ((controlmode != CONTROLMODE_PC) && g_Vars.currentplayer->usedowntime >= -2) {
|
||||
if ((controlmode < CONTROLMODE_PC) && g_Vars.currentplayer->usedowntime >= -2) {
|
||||
bgunConsiderToggleGunFunction(g_Vars.currentplayer->usedowntime, false, false, 0);
|
||||
}
|
||||
}
|
||||
@@ -1711,7 +1877,7 @@ void bmoveProcessInput(bool allowc1x, bool allowc1y, bool allowc1buttons, bool i
|
||||
#ifdef PLATFORM_N64
|
||||
if (allowc1buttons) {
|
||||
#else
|
||||
if (allowc1buttons && (controlmode != CONTROLMODE_PC || (PLAYER_EXTCFG().crouchmode & CROUCHMODE_ANALOG))) {
|
||||
if (allowc1buttons && (controlmode < CONTROLMODE_PC || (PLAYER_EXTCFG().crouchmode & CROUCHMODE_ANALOG))) {
|
||||
#endif
|
||||
for (i = 0; i < numsamples; i++) {
|
||||
if (!canmanualzoom && aimonhist[i]) {
|
||||
@@ -1795,7 +1961,7 @@ void bmoveProcessInput(bool allowc1x, bool allowc1y, bool allowc1buttons, bool i
|
||||
}
|
||||
|
||||
// Handle mine detonation
|
||||
if (controlmode != CONTROLMODE_PC) {
|
||||
if (controlmode < CONTROLMODE_PC) {
|
||||
if ((((c1buttons & invbuttons) && (c1buttonsthisframe & B_BUTTON))
|
||||
|| ((c1buttons & B_BUTTON) && (c1buttonsthisframe & invbuttons)))
|
||||
&& weaponnum == WEAPON_REMOTEMINE) {
|
||||
@@ -1828,17 +1994,12 @@ void bmoveProcessInput(bool allowc1x, bool allowc1y, bool allowc1buttons, bool i
|
||||
movedata.triggeron = g_Vars.currentplayer->waitforzrelease == false
|
||||
&& (c1buttons & shootbuttons)
|
||||
&& g_Vars.currentplayer->pausemode == PAUSEMODE_UNPAUSED;
|
||||
if (controlmode != CONTROLMODE_PC) {
|
||||
if (controlmode < CONTROLMODE_PC) {
|
||||
movedata.triggeron = movedata.triggeron && ((c1buttons & invbuttons) == 0);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef PLATFORM_N64
|
||||
if (controlmode == CONTROLMODE_12 || controlmode == CONTROLMODE_14 || controlmode == CONTROLMODE_PC) {
|
||||
#else
|
||||
// The PC controls walk with an analog stick like 1.1, so look ahead works there (see below)
|
||||
if (controlmode == CONTROLMODE_12 || controlmode == CONTROLMODE_14) {
|
||||
#endif
|
||||
movedata.disablelookahead = true;
|
||||
}
|
||||
} // end 1.x
|
||||
@@ -1997,22 +2158,6 @@ void bmoveProcessInput(bool allowc1x, bool allowc1y, bool allowc1buttons, bool i
|
||||
lookahead = g_Vars.currentplayer->cachedlookahead;
|
||||
}
|
||||
|
||||
#ifndef PLATFORM_N64
|
||||
// PC controls pitch with the right stick or mouse (natural pitch), which the N64 code never
|
||||
// treats as manual pitch. Do what C-up/C-down does: stop the centring until the next walk,
|
||||
// or until the walk stops if already walking.
|
||||
// A deliberate stick deflection only: a resting stick can drift past the small dead zone
|
||||
if (controlmode == CONTROLMODE_PC
|
||||
&& (movedata.analogpitch > 15 || movedata.analogpitch < -15 || movedata.freelookdy != 0.0f)) {
|
||||
g_Vars.currentplayer->docentreupdown = false;
|
||||
g_Vars.currentplayer->automovecentre = false;
|
||||
|
||||
if (movedata.canlookahead && (movedata.analogwalk > 60 || movedata.analogwalk < -60)) {
|
||||
g_Vars.currentplayer->movecentrerelease = true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (g_Vars.currentplayer->movecentrerelease
|
||||
&& movedata.analogwalk < 40 && movedata.analogwalk > -40) {
|
||||
g_Vars.currentplayer->movecentrerelease = false;
|
||||
@@ -2085,7 +2230,7 @@ void bmoveProcessInput(bool allowc1x, bool allowc1y, bool allowc1buttons, bool i
|
||||
}
|
||||
} else {
|
||||
if (movedata.cannaturalpitch) {
|
||||
tmp = viGetFovY() / PLAYER_DEFAULT_FOV;
|
||||
tmp = viGetFovY() / 60.0f;
|
||||
fVar25 = movedata.analogpitch / 70.0f;
|
||||
|
||||
if (fVar25 > 1) {
|
||||
@@ -2126,7 +2271,7 @@ void bmoveProcessInput(bool allowc1x, bool allowc1y, bool allowc1buttons, bool i
|
||||
}
|
||||
|
||||
if (movedata.cannaturalturn) {
|
||||
tmp = viGetFovY() / PLAYER_DEFAULT_FOV;
|
||||
tmp = viGetFovY() / 60.0f;
|
||||
fVar25 = movedata.analogturn / 70.0f;
|
||||
|
||||
if (fVar25 > 1) {
|
||||
@@ -2239,8 +2384,15 @@ void bmoveProcessInput(bool allowc1x, bool allowc1y, bool allowc1buttons, bool i
|
||||
x = g_Vars.currentplayer->speedtheta * 0.3f + g_Vars.currentplayer->gunextraaimx;
|
||||
y = -g_Vars.currentplayer->speedverta * 0.1f + g_Vars.currentplayer->gunextraaimy;
|
||||
#else
|
||||
// Crosshair swivel movement system
|
||||
bmoveApplyCrosshairSwivel(&movedata, mlookscale, &x, &y);
|
||||
f32 xscale, yscale;
|
||||
if (movedata.freelookdx || movedata.freelookdy) {
|
||||
xscale = PLAYER_EXTCFG().crosshairsway * 0.20f;
|
||||
yscale = PLAYER_EXTCFG().crosshairsway * 0.30f;
|
||||
} else {
|
||||
xscale = yscale = PLAYER_EXTCFG().crosshairsway;
|
||||
}
|
||||
x = g_Vars.currentplayer->speedtheta * 0.3f * xscale + g_Vars.currentplayer->gunextraaimx;
|
||||
y = -g_Vars.currentplayer->speedverta * 0.1f * yscale + g_Vars.currentplayer->gunextraaimy;
|
||||
#endif
|
||||
|
||||
bgunSwivelWithDamp(x, y, PAL ? 0.955f : 0.963f);
|
||||
@@ -2262,13 +2414,6 @@ void bmoveProcessInput(bool allowc1x, bool allowc1y, bool allowc1buttons, bool i
|
||||
y = (y < -1.f) ? -1.f : ((y > 1.f) ? 1.f : y);
|
||||
g_Vars.currentplayer->swivelpos[0] = x;
|
||||
g_Vars.currentplayer->swivelpos[1] = y;
|
||||
|
||||
// The stick still offsets the crosshair, as in the stick-only path below, so gyro (sent as mouse)
|
||||
// and stick aiming combine
|
||||
x += (movedata.c1stickxraw * 0.65f) / 80.0f;
|
||||
y += (movedata.c1stickyraw * 0.65f) / 80.0f;
|
||||
x = (x < -1.f) ? -1.f : ((x > 1.f) ? 1.f : x);
|
||||
y = (y < -1.f) ? -1.f : ((y > 1.f) ? 1.f : y);
|
||||
bgunSwivelWithDamp(x, y, 0.01f);
|
||||
return;
|
||||
}
|
||||
@@ -2443,6 +2588,14 @@ void bmoveTick(bool allowc1x, bool allowc1y, bool allowc1buttons, bool ignorec2)
|
||||
|
||||
void bmoveUpdateVerta(void)
|
||||
{
|
||||
while (g_Vars.currentplayer->vv_verta < -180) {
|
||||
g_Vars.currentplayer->vv_verta += 360;
|
||||
}
|
||||
|
||||
while (g_Vars.currentplayer->vv_verta >= 180) {
|
||||
g_Vars.currentplayer->vv_verta -= 360;
|
||||
}
|
||||
|
||||
if (g_Vars.currentplayer->vv_verta > 90) {
|
||||
g_Vars.currentplayer->vv_verta = 90;
|
||||
} else if (g_Vars.currentplayer->vv_verta < -90) {
|
||||
@@ -2558,7 +2711,13 @@ void bmoveUpdateHead(f32 arg0, f32 arg1, f32 arg2, Mtxf *arg3, f32 arg4)
|
||||
bheadUpdate(sp244, arg2);
|
||||
mtx4LoadXRotation(BADDEG2RAD(360 - g_Vars.currentplayer->vv_verta360), &sp180);
|
||||
|
||||
#ifdef PLATFORM_N64
|
||||
if (optionsGetHeadRoll(g_Vars.currentplayerstats->mpindex)) {
|
||||
#else
|
||||
// in net games only allow headroll in the death animation
|
||||
// TODO: figure out how to deal with headroll in other situations
|
||||
if (optionsGetHeadRoll(g_Vars.currentplayerstats->mpindex) && (!g_NetMode || g_Vars.currentplayer->isdead)) {
|
||||
#endif
|
||||
mtx00016d58(&sp116,
|
||||
0, 0, 0,
|
||||
-g_Vars.currentplayer->headlook.x, -g_Vars.currentplayer->headlook.y, -g_Vars.currentplayer->headlook.z,
|
||||
|
||||
+72
-3
@@ -27,7 +27,69 @@
|
||||
#include "data.h"
|
||||
#include "types.h"
|
||||
#ifndef PLATFORM_N64
|
||||
extern f32 fabsf(f32);
|
||||
#include "net/net.h"
|
||||
#include "system.h"
|
||||
#include "utils.h"
|
||||
|
||||
static inline void lerpcoord(struct coord *c, const struct coord *a, const struct coord *b, const f32 t) {
|
||||
c->x = lerpf(a->x, b->x, t);
|
||||
c->y = lerpf(a->y, b->y, t);
|
||||
c->z = lerpf(a->z, b->z, t);
|
||||
}
|
||||
|
||||
static void bwalkUpdateRemote(void)
|
||||
{
|
||||
struct player *pl = g_Vars.currentplayer;
|
||||
const struct netplayermove *inmove = &pl->client->inmove[0];
|
||||
const struct netplayermove *inmoveprev = &pl->client->inmove[1];
|
||||
struct coord delta;
|
||||
u16 cdtype = CDTYPE_ALL;
|
||||
s32 moveticks = inmove->tick - inmoveprev->tick;
|
||||
if (moveticks > g_NetInterpTicks) {
|
||||
moveticks = g_NetInterpTicks;
|
||||
}
|
||||
|
||||
pl->client->inmovetick = inmove->tick;
|
||||
|
||||
pl->bondshotspeed.x = 0.f;
|
||||
pl->bondshotspeed.y = 0.f;
|
||||
pl->bondshotspeed.z = 0.f;
|
||||
pl->bondbreathing = 0.f;
|
||||
|
||||
const bool forcepos = !inmoveprev->tick ||
|
||||
(inmove->ucmd & UCMD_FL_FORCEPOS) ||
|
||||
(fabsf(pl->prop->pos.x - inmove->pos.x) > 512.f) ||
|
||||
(fabsf(pl->prop->pos.y - inmove->pos.y) > 512.f) ||
|
||||
(fabsf(pl->prop->pos.z - inmove->pos.z) > 512.f);
|
||||
|
||||
delta.x = 0.f;
|
||||
delta.y = 0.f;
|
||||
delta.z = 0.f;
|
||||
|
||||
// extrapolate
|
||||
bwalk0f0c69b8();
|
||||
|
||||
if (forcepos) {
|
||||
// no interpolation, set position and lock the lad in place
|
||||
pl->prop->pos = inmove->pos;
|
||||
pl->client->lerpticks = g_NetInterpTicks + 1;
|
||||
cdtype = CDTYPE_PLAYERS; // don't get stuck in the local client
|
||||
} else if (!moveticks) {
|
||||
// duplicate move, reposition to correct coords
|
||||
delta.x = inmove->pos.x - pl->prop->pos.x;
|
||||
delta.x = inmove->pos.y - pl->prop->pos.y;
|
||||
delta.x = inmove->pos.z - pl->prop->pos.z;
|
||||
bwalk0f0c63bc(&delta, pl->swaytarget == 0.0f, cdtype);
|
||||
} else if (pl->client->lerpticks <= moveticks) {
|
||||
// lerp towards the correct position
|
||||
const f32 dt = (f32)1.f / (f32)moveticks;
|
||||
delta.x = g_Vars.lvupdate60freal * (inmove->pos.x - pl->prop->pos.x) * dt;
|
||||
delta.y = g_Vars.lvupdate60freal * (inmove->pos.y - pl->prop->pos.y) * dt;
|
||||
delta.z = g_Vars.lvupdate60freal * (inmove->pos.z - pl->prop->pos.z) * dt;
|
||||
bwalk0f0c63bc(&delta, pl->swaytarget == 0.0f, cdtype);
|
||||
pl->client->lerpticks += g_Vars.lvupdate60;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void bwalkInit(void)
|
||||
@@ -454,7 +516,7 @@ bool bwalkCalculateNewPositionWithPush(struct coord *delta, f32 rotateamount, bo
|
||||
}
|
||||
} else if (chr->chrflags & CHRCFLAG_PUSHABLE) {
|
||||
if (g_Vars.antiplayernum < 0
|
||||
|| g_Vars.currentplayer != g_Vars.anti
|
||||
|| PLAYER_IS_NOT_ANTI(g_Vars.currentplayer)
|
||||
|| (chr->hidden & CHRHFLAG_ANTINONINTERACTABLE) == 0) {
|
||||
canpush = true;
|
||||
}
|
||||
@@ -788,7 +850,7 @@ void bwalkUpdateVertical(void)
|
||||
// Maybe reset counter-op's radius - not sure why
|
||||
// Maybe it gets set to 0 when they die?
|
||||
if (g_Vars.antiplayernum >= 0
|
||||
&& g_Vars.currentplayer == g_Vars.anti
|
||||
&& PLAYER_IS_ANTI(g_Vars.currentplayer)
|
||||
&& g_Vars.currentplayer->bond2.radius != 30
|
||||
&& cdTestVolume(&g_Vars.currentplayer->prop->pos, 30, g_Vars.currentplayer->prop->rooms, CDTYPE_ALL, CHECKVERTICAL_YES, ymax - g_Vars.currentplayer->prop->pos.y, ymin - g_Vars.currentplayer->prop->pos.y)) {
|
||||
g_Vars.currentplayer->prop->chr->radius = 30;
|
||||
@@ -1843,7 +1905,14 @@ void bwalkTick(void)
|
||||
bwalkUpdatePrevPos();
|
||||
bwalkUpdateTheta();
|
||||
bmoveUpdateVerta();
|
||||
|
||||
#ifndef PLATFORM_N64
|
||||
if (g_Vars.currentplayer->isremote) {
|
||||
bwalkUpdateRemote();
|
||||
} else
|
||||
#endif
|
||||
bwalk0f0c69b8();
|
||||
|
||||
bwalkUpdateVertical();
|
||||
|
||||
#if VERSION >= VERSION_NTSC_1_0
|
||||
|
||||
+1
-2
@@ -262,8 +262,7 @@ void botSpawn(struct chrdata *chr, u8 respawning)
|
||||
func0f02e9a0(chr, 0);
|
||||
|
||||
#ifndef PLATFORM_N64
|
||||
if (g_Vars.normmplayerisrunning
|
||||
&& (g_MpSetup.options & MPOPTION_SPAWNWITHWEAPON)
|
||||
if ((g_MpSetup.options & MPOPTION_SPAWNWITHWEAPON)
|
||||
&& g_MpSetup.weapons[0] != MPWEAPON_NONE
|
||||
&& g_MpSetup.weapons[0] != MPWEAPON_DISABLED
|
||||
&& g_MpSetup.weapons[0] != MPWEAPON_SHIELD) {
|
||||
|
||||
+10
-4
@@ -136,7 +136,7 @@ void challengeDetermineUnlockedFeatures(void)
|
||||
}
|
||||
|
||||
// Now same as above, but per player
|
||||
for (j = 0; j < MAX_PLAYERS; j++) {
|
||||
for (j = 0; j < MAX_LOCAL_PLAYERS; j++) {
|
||||
numgifted = 0;
|
||||
|
||||
for (challengeindex = 0; challengeindex < ARRAYCOUNT(g_MpChallenges); challengeindex++) {
|
||||
@@ -197,7 +197,7 @@ void challengeDetermineUnlockedFeatures(void)
|
||||
}
|
||||
|
||||
for (challengeindex = 0; challengeindex < ARRAYCOUNT(g_MpChallenges); challengeindex++) {
|
||||
for (prev = 0; prev < MAX_PLAYERS; prev++) {
|
||||
for (prev = 0; prev < MAX_LOCAL_PLAYERS; prev++) {
|
||||
if (challengeIsAvailableToPlayer(prev, challengeindex)) {
|
||||
for (i = 0; i < ARRAYCOUNT(g_MpChallenges[challengeindex].unlockfeatures); i++) {
|
||||
if (g_MpChallenges[challengeindex].unlockfeatures[i] == j) {
|
||||
@@ -249,7 +249,7 @@ void challengePerformSanityChecks(void)
|
||||
}
|
||||
}
|
||||
|
||||
// Turn off all simulants and turn them on if enabled
|
||||
// Turn off all simulants (and players 5-8 if supported) and turn them on if enabled
|
||||
// for this number of players
|
||||
g_MpSetup.chrslots &= 0x000f;
|
||||
|
||||
@@ -265,8 +265,14 @@ void challengePerformSanityChecks(void)
|
||||
g_Vars.mphilltime = 10;
|
||||
}
|
||||
} else if (!challengeIsFeatureUnlocked(MPFEATURE_8BOTS)) {
|
||||
// Limit to 4 players and 4 simulants
|
||||
// Limit to 4 players and 4 simulants in local games
|
||||
#ifndef PLATFORM_N64
|
||||
g_MpSetup.chrslots &= (g_NetMode ? 0x0fff : 0x0f0f);
|
||||
#elif MAX_PLAYERS > 4
|
||||
g_MpSetup.chrslots &= 0x0f0f;
|
||||
#else
|
||||
g_MpSetup.chrslots &= 0x00ff;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+4
-28
@@ -165,17 +165,6 @@ void cheatActivate(s32 cheat_id)
|
||||
setCurrentPlayerNum(prevplayernum);
|
||||
break;
|
||||
case CHEAT_ALLGUNS:
|
||||
#ifndef PLATFORM_N64
|
||||
// Give all guns to all players
|
||||
prevplayernum = g_Vars.currentplayernum;
|
||||
|
||||
for (playernum = 0; playernum < PLAYERCOUNT(); playernum++) {
|
||||
setCurrentPlayerNum(playernum);
|
||||
invSetAllGuns(true);
|
||||
}
|
||||
|
||||
setCurrentPlayerNum(prevplayernum);
|
||||
#else
|
||||
// Give all guns if only one player playing
|
||||
if (PLAYERCOUNT() == 1 && g_Vars.normmplayerisrunning == false) {
|
||||
prevplayernum = g_Vars.currentplayernum;
|
||||
@@ -187,7 +176,6 @@ void cheatActivate(s32 cheat_id)
|
||||
|
||||
setCurrentPlayerNum(prevplayernum);
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -215,16 +203,6 @@ void cheatDeactivate(s32 cheat_id)
|
||||
setCurrentPlayerNum(prevplayernum);
|
||||
break;
|
||||
case CHEAT_ALLGUNS:
|
||||
#ifndef PLATFORM_N64
|
||||
prevplayernum = g_Vars.currentplayernum;
|
||||
|
||||
for (playernum = 0; playernum < PLAYERCOUNT(); playernum++) {
|
||||
setCurrentPlayerNum(playernum);
|
||||
invSetAllGuns(false);
|
||||
}
|
||||
|
||||
setCurrentPlayerNum(prevplayernum);
|
||||
#else
|
||||
if (PLAYERCOUNT() == 1 && g_Vars.normmplayerisrunning == false) {
|
||||
prevplayernum = g_Vars.currentplayernum;
|
||||
|
||||
@@ -235,7 +213,6 @@ void cheatDeactivate(s32 cheat_id)
|
||||
|
||||
setCurrentPlayerNum(prevplayernum);
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -332,7 +309,7 @@ MenuItemHandlerResult cheatCheckboxMenuHandler(s32 operation, struct menuitem *i
|
||||
return false;
|
||||
}
|
||||
|
||||
if (g_CheatsEnabledBank1 & (1 << (item->param - 32))) {
|
||||
if (g_CheatsEnabledBank1 & (1 << item->param)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -357,12 +334,11 @@ MenuItemHandlerResult cheatCheckboxMenuHandler(s32 operation, struct menuitem *i
|
||||
}
|
||||
} else {
|
||||
// Bank 1
|
||||
if (g_CheatsEnabledBank1 & (1 << (item->param - 32))) {
|
||||
// We need to subtract 32 on lines like these to avoid undefined behavior, namely ensuring that all cheats are toggled correctly and regardless of build optimiaztion
|
||||
if (g_CheatsEnabledBank1 & (1 << item->param)) {
|
||||
if (1);
|
||||
g_CheatsEnabledBank1 = g_CheatsEnabledBank1 & ~(1 << (item->param - 32));
|
||||
g_CheatsEnabledBank1 = g_CheatsEnabledBank1 & ~(1 << item->param);
|
||||
} else {
|
||||
g_CheatsEnabledBank1 = g_CheatsEnabledBank1 | (1 << (item->param - 32));
|
||||
g_CheatsEnabledBank1 = g_CheatsEnabledBank1 | 1 << item->param;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+15
-28
@@ -49,6 +49,8 @@
|
||||
#include "types.h"
|
||||
#ifndef PLATFORM_N64
|
||||
#include "video.h"
|
||||
#include "net/net.h"
|
||||
#include "net/netmsg.h"
|
||||
#endif
|
||||
|
||||
void rng2SetSeed(u32 seed);
|
||||
@@ -2633,19 +2635,6 @@ s32 chrTick(struct prop *prop)
|
||||
}
|
||||
|
||||
#if VERSION >= VERSION_NTSC_1_0
|
||||
#ifndef PLATFORM_N64
|
||||
if (g_MaxCorpses != 0 && !g_Vars.normmplayerisrunning && needsupdate) {
|
||||
// Kept corpses are drawn rather than deleted, and don't count towards the visible chr budget
|
||||
if (chr->actiontype != ACT_DEAD
|
||||
&& (chr->actiontype != ACT_DRUGGEDKO || (chr->chrflags & CHRCFLAG_KEEPCORPSEKO))) {
|
||||
var8009cdb0++;
|
||||
|
||||
if (var8009cdb0 > 30) {
|
||||
needsupdate = false;
|
||||
}
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
if (!g_Vars.normmplayerisrunning && needsupdate) {
|
||||
if (chr->actiontype == ACT_DEAD
|
||||
|| (chr->actiontype == ACT_DRUGGEDKO && (chr->chrflags & CHRCFLAG_KEEPCORPSEKO) == 0)) {
|
||||
@@ -4557,17 +4546,7 @@ void chrTestHit(struct prop *prop, struct shotdata *shotdata, bool isshooting, b
|
||||
|
||||
if (hitpart) {
|
||||
if (chrGetShield(chr) > 0.0f) {
|
||||
#ifndef PLATFORM_N64
|
||||
/**
|
||||
* var8005efc0 > 0.0f adds a padding to bbox hit detection
|
||||
* in modelTestBboxNodeForHit() that accounts for a character's
|
||||
* surrounding shield. We skip this step on PC when checking
|
||||
* line-of-sight hits to light artifacts because lights should
|
||||
* be visible through the transparent shield.
|
||||
*/
|
||||
if (g_BgHitXluDisabled == false)
|
||||
#endif
|
||||
var8005efc0 = 10.0f / model->scale;
|
||||
var8005efc0 = 10.0f / model->scale;
|
||||
}
|
||||
|
||||
child = prop->child;
|
||||
@@ -4683,7 +4662,7 @@ void chrHit(struct shotdata *shotdata, struct hit *hit)
|
||||
hit->model, hit->hitthing.unk28 / 2, sp90);
|
||||
|
||||
if (g_Vars.antiplayernum >= 0
|
||||
&& g_Vars.currentplayer == g_Vars.anti
|
||||
&& PLAYER_IS_ANTI(g_Vars.currentplayer)
|
||||
&& (chr->hidden & CHRHFLAG_ANTINONINTERACTABLE)) {
|
||||
return;
|
||||
}
|
||||
@@ -4714,9 +4693,17 @@ void chrHit(struct shotdata *shotdata, struct hit *hit)
|
||||
|| weapon->weaponnum == WEAPON_TIMEDMINE
|
||||
|| weapon->weaponnum == WEAPON_REMOTEMINE
|
||||
|| weapon->weaponnum == WEAPON_PROXIMITYMINE) {
|
||||
objSetDropped(hit->prop, DROPTYPE_DEFAULT);
|
||||
chr->hidden |= CHRHFLAG_DROPPINGITEM;
|
||||
objDamage(&weapon->base, gsetGetDamage(&shotdata->gset), &sp98, shotdata->gset.weaponnum, g_Vars.currentplayernum);
|
||||
#ifndef PLATFORM_N64
|
||||
if (g_NetMode == NETMODE_SERVER) {
|
||||
netmsgSvcChrDisarmWrite(&g_NetMsgRel, chr, g_Vars.currentplayer->prop, weapon->weaponnum, gsetGetDamage(&shotdata->gset), &sp98);
|
||||
}
|
||||
if (g_NetMode != NETMODE_CLIENT)
|
||||
#endif
|
||||
{
|
||||
objSetDropped(hit->prop, DROPTYPE_DEFAULT);
|
||||
chr->hidden |= CHRHFLAG_DROPPINGITEM;
|
||||
objDamage(&weapon->base, gsetGetDamage(&shotdata->gset), &sp98, shotdata->gset.weaponnum, g_Vars.currentplayernum);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
+139
-41
@@ -56,6 +56,10 @@
|
||||
#include "lib/vi.h"
|
||||
#include "data.h"
|
||||
#include "types.h"
|
||||
#ifndef PLATFORM_N64
|
||||
#include "net/net.h"
|
||||
#include "net/netmsg.h"
|
||||
#endif
|
||||
|
||||
s32 g_RecentQuipsPlayed[5];
|
||||
u32 var8009cd84;
|
||||
@@ -4038,7 +4042,7 @@ void chrChoke(struct chrdata *chr, s32 choketype)
|
||||
if (soundnum >= 0) {
|
||||
if (chr->prop->type == PROPTYPE_PLAYER) {
|
||||
if (g_Vars.players[playernum]->chokehandle == NULL) {
|
||||
sndStart(var80095200, soundnum, &g_Vars.players[playernum]->chokehandle, -1, -1, -1, -1, -1);
|
||||
playerSndStart(var80095200, soundnum, &g_Vars.players[playernum]->chokehandle, playernum, -1, -1, -1);
|
||||
}
|
||||
} else {
|
||||
psStopSound(chr->prop, PSTYPE_CHRTALK, 0);
|
||||
@@ -4101,6 +4105,12 @@ bool func0f034080(struct chrdata *chr, struct modelnode *node, struct prop *prop
|
||||
*/
|
||||
void chrDamageByMisc(struct chrdata *chr, f32 damage, struct coord *vector, struct gset *gset, struct prop *prop)
|
||||
{
|
||||
#ifndef PLATFORM_N64
|
||||
if (g_NetMode == NETMODE_CLIENT) {
|
||||
// don't do anything if we're not the authority
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
chrDamage(chr, damage, vector, gset, prop, HITPART_GENERAL,
|
||||
false, // damageshield
|
||||
NULL, // prop2
|
||||
@@ -4114,6 +4124,12 @@ void chrDamageByMisc(struct chrdata *chr, f32 damage, struct coord *vector, stru
|
||||
|
||||
void chrDamageByLaser(struct chrdata *chr, f32 damage, struct coord *vector, struct gset *gset, struct prop *prop)
|
||||
{
|
||||
#ifndef PLATFORM_N64
|
||||
if (g_NetMode == NETMODE_CLIENT) {
|
||||
// don't do anything if we're not the authority
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
chrDamage(chr, damage, vector, gset, prop, HITPART_GENERAL,
|
||||
true, // damageshield
|
||||
chr->prop, // prop2
|
||||
@@ -4127,6 +4143,12 @@ void chrDamageByLaser(struct chrdata *chr, f32 damage, struct coord *vector, str
|
||||
|
||||
void func0f0341dc(struct chrdata *chr, f32 damage, struct coord *vector, struct gset *gset, struct prop *prop, s32 hitpart, struct prop *prop2, struct modelnode *node, struct model *model, s32 side, s16 *arg10)
|
||||
{
|
||||
#ifndef PLATFORM_N64
|
||||
if (g_NetMode == NETMODE_CLIENT) {
|
||||
// don't do anything if we're not the authority
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
chrDamage(chr, damage, vector, gset, prop, hitpart,
|
||||
true, // damageshield
|
||||
prop2, // prop2
|
||||
@@ -4148,6 +4170,13 @@ void func0f034248(struct chrdata *chr, f32 damage, struct coord *vector, struct
|
||||
s32 side = 0;
|
||||
s32 hitpart = HITPART_GENERAL;
|
||||
|
||||
#ifndef PLATFORM_N64
|
||||
if (g_NetMode == NETMODE_CLIENT) {
|
||||
// don't do anything if we're not the authority
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (chrGetShield(chr) >= 0 && chr->model) {
|
||||
chrCalculateShieldHit(chr, &chr->prop->pos, vector, &node, &hitpart, &model, &side);
|
||||
}
|
||||
@@ -4172,6 +4201,13 @@ void chrDamageByImpact(struct chrdata *chr, f32 damage, struct coord *vector, st
|
||||
struct model *model = NULL;
|
||||
s32 side = 0;
|
||||
|
||||
#ifndef PLATFORM_N64
|
||||
if (g_NetMode == NETMODE_CLIENT) {
|
||||
// don't do anything if we're not the authority
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (chrGetShield(chr) >= 0 && chr->model) {
|
||||
chrCalculateShieldHit(chr, &chr->prop->pos, vector, &node, &hitpart, &model, &side);
|
||||
}
|
||||
@@ -4189,6 +4225,12 @@ void chrDamageByImpact(struct chrdata *chr, f32 damage, struct coord *vector, st
|
||||
|
||||
void chrDamageByExplosion(struct chrdata *chr, f32 damage, struct coord *vector, struct prop *prop, struct coord *explosionpos)
|
||||
{
|
||||
#ifndef PLATFORM_N64
|
||||
if (g_NetMode == NETMODE_CLIENT) {
|
||||
// don't do anything if we're not the authority
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
chrDamage(chr, damage, vector, NULL, prop, HITPART_GENERAL,
|
||||
true, // damageshield
|
||||
chr->prop, // prop2
|
||||
@@ -4272,6 +4314,13 @@ void chrDamage(struct chrdata *chr, f32 damage, struct coord *vector, struct gse
|
||||
s32 aplayernum = -1;
|
||||
s32 choketype = CHOKETYPE_NONE;
|
||||
|
||||
#ifndef PLATFORM_N64
|
||||
if (g_NetMode == NETMODE_SERVER) {
|
||||
netmsgSvcChrDamageWrite(&g_NetMsgRel, chr, damage, vector, gset, aprop, hitpart,
|
||||
damageshield, prop2, side, arg11, explosion, explosionpos);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (hitpart == HITPART_HEAD) {
|
||||
choketype = CHOKETYPE_GURGLE;
|
||||
}
|
||||
@@ -4302,7 +4351,7 @@ void chrDamage(struct chrdata *chr, f32 damage, struct coord *vector, struct gse
|
||||
// Don't damage if attacker was anti and chr is non-interactable by anti
|
||||
if (g_Vars.antiplayernum >= 0
|
||||
&& aprop
|
||||
&& aprop == g_Vars.anti->prop
|
||||
&& PROP_IS_FOR_ANTI_PLAYER(aprop)
|
||||
&& (chr->hidden & CHRHFLAG_ANTINONINTERACTABLE)) {
|
||||
return;
|
||||
}
|
||||
@@ -4454,7 +4503,9 @@ void chrDamage(struct chrdata *chr, f32 damage, struct coord *vector, struct gse
|
||||
}
|
||||
|
||||
// Anti shooting other enemies is lethal
|
||||
if (aprop && aprop == g_Vars.anti->prop && vprop != g_Vars.bond->prop) {
|
||||
if (aprop
|
||||
&& PROP_IS_FOR_ANTI_PLAYER(aprop)
|
||||
&& vprop != g_Vars.bond->prop) {
|
||||
damage *= 100;
|
||||
}
|
||||
} else {
|
||||
@@ -4855,6 +4906,12 @@ void chrDamage(struct chrdata *chr, f32 damage, struct coord *vector, struct gse
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef PLATFORM_N64
|
||||
if (g_NetMode == NETMODE_SERVER && g_Vars.currentplayer->client) {
|
||||
netmsgSvcPlayerStatsWrite(&g_NetMsgRel, g_Vars.currentplayer->client);
|
||||
}
|
||||
#endif
|
||||
|
||||
setCurrentPlayerNum(prevplayernum);
|
||||
return;
|
||||
}
|
||||
@@ -7199,14 +7256,7 @@ bool chrTrySurrender(struct chrdata *chr)
|
||||
bool chrFadeOut(struct chrdata *chr)
|
||||
{
|
||||
chrBeginDead(chr);
|
||||
#ifndef PLATFORM_N64
|
||||
// Scripted removals still fade when corpses are kept forever
|
||||
if (chr->actiontype == ACT_DEAD || chr->actiontype == ACT_DRUGGEDKO) {
|
||||
chr->act_dead.fadenow = true;
|
||||
}
|
||||
#else
|
||||
chrFadeCorpse(chr);
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -8204,12 +8254,6 @@ void chrTickSurrender(struct chrdata *chr)
|
||||
|
||||
void chrFadeCorpse(struct chrdata *chr)
|
||||
{
|
||||
#ifndef PLATFORM_N64
|
||||
if (g_MaxCorpses < 0 && chr->aibot == NULL) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (chr->actiontype == ACT_DEAD || chr->actiontype == ACT_DRUGGEDKO) {
|
||||
chr->act_dead.fadenow = true;
|
||||
}
|
||||
@@ -8217,12 +8261,6 @@ void chrFadeCorpse(struct chrdata *chr)
|
||||
|
||||
void chrFadeCorpseWhenOffScreen(struct chrdata *chr)
|
||||
{
|
||||
#ifndef PLATFORM_N64
|
||||
if (g_MaxCorpses < 0 && chr->aibot == NULL) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (chr->actiontype == ACT_DEAD) {
|
||||
chr->act_dead.fadewheninvis = true;
|
||||
}
|
||||
@@ -8298,7 +8336,7 @@ void chrAlertOthersOfInjury(struct chrdata *chr, bool dying)
|
||||
s32 numinrange = 0;
|
||||
s32 numchrs = chrsGetNumSlots();
|
||||
|
||||
if (g_Vars.antiplayernum >= 0 && chr->prop == g_Vars.anti->prop) {
|
||||
if (g_Vars.antiplayernum >= 0 && PROP_IS_FOR_ANTI_PLAYER(chr->prop)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -13478,10 +13516,6 @@ void cutsceneStart(u32 ailistid)
|
||||
* - Run BG scripts
|
||||
* - Choose which corpses to fade
|
||||
*/
|
||||
// 0 keeps the original corpse limits, -1 never fades corpses, otherwise the number of corpses kept on screen,
|
||||
// off screen and spawned
|
||||
s32 g_MaxCorpses = 0;
|
||||
|
||||
void chraTickBg(void)
|
||||
{
|
||||
s32 i;
|
||||
@@ -13493,10 +13527,10 @@ void chraTickBg(void)
|
||||
#if VERSION >= VERSION_NTSC_1_0
|
||||
s32 spawnslen;
|
||||
#endif
|
||||
struct chrdata *onscreen[MAX_CORPSES_LIMIT];
|
||||
struct chrdata *offscreen[MAX_CORPSES_LIMIT];
|
||||
struct chrdata *onscreen[5];
|
||||
struct chrdata *offscreen[5];
|
||||
#if VERSION >= VERSION_NTSC_1_0
|
||||
struct chrdata *spawns[MAX_CORPSES_LIMIT];
|
||||
struct chrdata *spawns[10];
|
||||
#endif
|
||||
s32 writeindex;
|
||||
s32 maxdeadonscreen;
|
||||
@@ -13537,7 +13571,7 @@ void chraTickBg(void)
|
||||
|
||||
if (targetprop && (targetprop->type == PROPTYPE_CHR || targetprop->type == PROPTYPE_PLAYER)) {
|
||||
if ((targetprop->type == PROPTYPE_PLAYER
|
||||
&& !(g_Vars.antiplayernum >= 0 && g_Vars.anti && g_Vars.anti->prop == targetprop)
|
||||
&& !(g_Vars.antiplayernum >= 0 && g_Vars.anti && PROP_IS_FOR_ANTI_PLAYER(targetprop))
|
||||
&& chrCompareTeams(chr, targetprop->chr, COMPARE_ENEMIES))
|
||||
|| CHRRACE(targetprop->chr) == RACE_EYESPY) {
|
||||
s32 time60;
|
||||
@@ -13622,7 +13656,7 @@ void chraTickBg(void)
|
||||
spawns[spawnslen] = chr;
|
||||
spawnslen++;
|
||||
|
||||
if (spawnslen >= (g_MaxCorpses > 0 ? g_MaxCorpses : 10)) {
|
||||
if (spawnslen >= 10) {
|
||||
writeindex = rngRandom() % spawnslen;
|
||||
chrFadeCorpse(spawns[writeindex]);
|
||||
spawns[writeindex] = spawns[spawnslen - 1];
|
||||
@@ -13643,16 +13677,12 @@ void chraTickBg(void)
|
||||
// 5 chrs (alive or dead) to keep the number of polygons low.
|
||||
maxdeadonscreen = 5 - numaliveonscreen;
|
||||
|
||||
if (g_MaxCorpses > 0) {
|
||||
maxdeadonscreen = g_MaxCorpses;
|
||||
}
|
||||
|
||||
// If the game is lagging, take the number of 60ths over 6 since the
|
||||
// previous frame and reduce the limit by that amount. So if it's been, say,
|
||||
// 8 60ths since the last frame then the max corpses will be reduced by 2.
|
||||
// This is why corpses are more likely to fade on screen when you change
|
||||
// weapons - the lag spike from changing guns triggers a lower corpse limit.
|
||||
if (g_Vars.lvupdate60 > 6 && g_MaxCorpses == 0) {
|
||||
if (g_Vars.lvupdate60 > 6) {
|
||||
maxdeadonscreen = maxdeadonscreen - g_Vars.lvupdate60 + 6;
|
||||
}
|
||||
|
||||
@@ -13678,7 +13708,7 @@ void chraTickBg(void)
|
||||
#else
|
||||
// Decide which corpses to fade.
|
||||
// NTSC Beta implements its engagement counter here.
|
||||
if (numdeadonscreen && g_MaxCorpses >= 0) {
|
||||
if (numdeadonscreen) {
|
||||
numdeadonscreen = 0;
|
||||
#if VERSION >= VERSION_NTSC_1_0
|
||||
onscreenlen = 0;
|
||||
@@ -13717,7 +13747,7 @@ void chraTickBg(void)
|
||||
onscreen[onscreenlen] = chr;
|
||||
onscreenlen++;
|
||||
|
||||
if (onscreenlen >= (g_MaxCorpses > 0 ? g_MaxCorpses : (VERSION >= VERSION_NTSC_1_0 ? 2 : 3))) {
|
||||
if (onscreenlen >= (VERSION >= VERSION_NTSC_1_0 ? 2 : 3)) {
|
||||
writeindex = rngRandom() % onscreenlen;
|
||||
chrFadeCorpseWhenOffScreen(onscreen[writeindex]);
|
||||
onscreen[writeindex] = onscreen[onscreenlen - 1];
|
||||
@@ -13732,7 +13762,7 @@ void chraTickBg(void)
|
||||
offscreenlen++;
|
||||
|
||||
// Allow up to 5 corpses off-screen
|
||||
if (offscreenlen >= (g_MaxCorpses > 0 ? g_MaxCorpses : (VERSION >= VERSION_NTSC_1_0 ? 5 : 6))) {
|
||||
if (offscreenlen >= (VERSION >= VERSION_NTSC_1_0 ? 5 : 6)) {
|
||||
writeindex = rngRandom() % offscreenlen;
|
||||
|
||||
if (offscreen[writeindex]->actiontype != ACT_DEAD) {
|
||||
@@ -15327,6 +15357,68 @@ void func0f04b740(void)
|
||||
// empty
|
||||
}
|
||||
|
||||
bool chrSetPos(struct chrdata *chr, struct coord *pos, RoomNum *rooms, f32 theta, bool findground)
|
||||
{
|
||||
const f32 angle = BADDEG2RAD(360.f - theta);
|
||||
|
||||
if (findground) {
|
||||
const u32 oldhidden = chr->hidden;
|
||||
chr->hidden |= CHRHFLAG_WARPONSCREEN;
|
||||
const bool ret = chrMoveToPos(chr, pos, rooms, angle, true);
|
||||
if ((oldhidden & CHRHFLAG_WARPONSCREEN) == 0) {
|
||||
chr->hidden &= ~CHRHFLAG_WARPONSCREEN;
|
||||
}
|
||||
}
|
||||
|
||||
bool newrooms = false;
|
||||
for (s32 i = 0; i < ARRAYCOUNT(chr->prop->rooms) && rooms[i] >= 0; ++i) {
|
||||
if (chr->prop->rooms[i] != rooms[i]) {
|
||||
newrooms = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
propSetPerimEnabled(chr->prop, false);
|
||||
|
||||
chr->prop->pos = *pos;
|
||||
|
||||
const f32 ground = cdFindGroundInfoAtCyl(pos, chr->radius, rooms, &chr->floorcol,
|
||||
&chr->floortype, NULL, &chr->floorroom, NULL, NULL);
|
||||
|
||||
chr->ground = ground;
|
||||
chr->manground = ground;
|
||||
chr->sumground = ground * (PAL ? 8.4175090789795f : 9.999998f);
|
||||
|
||||
if (newrooms) {
|
||||
propDeregisterRooms(chr->prop);
|
||||
roomsCopy(rooms, chr->prop->rooms);
|
||||
chr0f0220ac(chr);
|
||||
}
|
||||
|
||||
modelSetRootPosition(chr->model, pos);
|
||||
|
||||
const u16 nodetype = chr->model->definition->rootnode->type;
|
||||
|
||||
if ((nodetype & 0xff) == MODELNODETYPE_CHRINFO) {
|
||||
union modelrwdata *rwdata = modelGetNodeRwData(chr->model, chr->model->definition->rootnode);
|
||||
rwdata->chrinfo.ground = ground;
|
||||
}
|
||||
|
||||
chrSetLookAngle(chr, angle);
|
||||
|
||||
if (chr->prop->type == PROPTYPE_PLAYER) {
|
||||
struct player *player = g_Vars.players[playermgrGetPlayerNumByProp(chr->prop)];
|
||||
player->vv_manground = ground;
|
||||
player->vv_ground = ground;
|
||||
player->vv_theta = theta;
|
||||
player->unk1c64 = 1;
|
||||
}
|
||||
|
||||
propSetPerimEnabled(chr->prop, true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool chrMoveToPos(struct chrdata *chr, struct coord *pos, RoomNum *rooms, f32 angle, bool force)
|
||||
{
|
||||
struct coord pos2;
|
||||
@@ -15334,7 +15426,7 @@ bool chrMoveToPos(struct chrdata *chr, struct coord *pos, RoomNum *rooms, f32 an
|
||||
bool result = false;
|
||||
u32 nodetype;
|
||||
union modelrwdata *rwdata;
|
||||
struct player *player;
|
||||
struct player *player = NULL;
|
||||
f32 ground;
|
||||
|
||||
pos2.x = pos->x;
|
||||
@@ -15384,6 +15476,12 @@ bool chrMoveToPos(struct chrdata *chr, struct coord *pos, RoomNum *rooms, f32 an
|
||||
player->unk1c64 = 1;
|
||||
}
|
||||
|
||||
#ifndef PLATFORM_N64
|
||||
if (g_NetMode == NETMODE_SERVER && player && player->isremote) {
|
||||
player->ucmd |= UCMD_FL_FORCEPOS | UCMD_FL_FORCEANGLE | UCMD_FL_FORCEGROUND;
|
||||
}
|
||||
#endif
|
||||
|
||||
result = true;
|
||||
}
|
||||
|
||||
|
||||
@@ -52,6 +52,10 @@
|
||||
#include "data.h"
|
||||
#include "types.h"
|
||||
|
||||
#ifndef PLATFORM_N64
|
||||
#include "game/mplayer/mplayer.h"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @cmd 0000
|
||||
*/
|
||||
@@ -2330,7 +2334,7 @@ bool aiGiveObjectToChr(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
something = propPickupByPlayer(obj->prop, 1);
|
||||
something = propPickupByPlayer(obj->prop, 0);
|
||||
propExecuteTickOperation(obj->prop, something);
|
||||
playernum = playermgrGetPlayerNumByProp(chr->prop);
|
||||
obj2->hidden = (playernum << 28) | (obj2->hidden & 0x0fffffff);
|
||||
@@ -6039,11 +6043,35 @@ bool aiSetChrPresetToChrNearPad(void)
|
||||
bool aiChrSetTeam(void)
|
||||
{
|
||||
u8 *cmd = g_Vars.ailist + g_Vars.aioffset;
|
||||
#ifdef PLATFORM_N64
|
||||
struct chrdata *chr = chrFindById(g_Vars.chrdata, cmd[2]);
|
||||
|
||||
if (chr) {
|
||||
chr->team = cmd[3];
|
||||
}
|
||||
#else
|
||||
u32 playernum;
|
||||
if (cmd[2] == CHR_ANTI && g_Vars.antiplayernum >= 0) {
|
||||
// There can be multiple counter-op players, so set this for all.
|
||||
for (playernum = 0; playernum < PLAYERCOUNT(); playernum++) {
|
||||
struct player *player = g_Vars.players[playernum];
|
||||
|
||||
if (player && PLAYER_IS_ANTI(player)) {
|
||||
struct chrdata *chr = player->prop->chr;
|
||||
|
||||
if (chr) {
|
||||
chr->team = cmd[3];
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
struct chrdata *chr = chrFindById(g_Vars.chrdata, cmd[2]);
|
||||
|
||||
if (chr) {
|
||||
chr->team = cmd[3];
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
g_Vars.aioffset += 4;
|
||||
|
||||
|
||||
+57
-12
@@ -292,6 +292,27 @@ char *endscreenMenuTextAccuracy(struct menuitem *item)
|
||||
return g_StringPointer;
|
||||
}
|
||||
|
||||
#if MAX_COOPCHRS > 2
|
||||
static bool enscreenAnyAntiAborted(void) {
|
||||
size_t num;
|
||||
|
||||
if (g_Vars.antiplayernum < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (num = 0; num < PLAYERCOUNT(); num++) {
|
||||
if (PLAYERNUM_IS_ANTI(num) && g_Vars.players[num] && g_Vars.players[num]->aborted) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
#define ANTI_ABORTED() (enscreenAnyAntiAborted())
|
||||
#else
|
||||
#define ANTI_ABORTED() (g_Vars.anti->aborted)
|
||||
#endif
|
||||
|
||||
char *endscreenMenuTextMissionStatus(struct menuitem *item)
|
||||
{
|
||||
if (g_CheatsActiveBank0 || g_CheatsActiveBank1) {
|
||||
@@ -312,7 +333,7 @@ char *endscreenMenuTextMissionStatus(struct menuitem *item)
|
||||
return langGet(L_OPTIONS_295); // "Aborted"
|
||||
}
|
||||
|
||||
if (g_Vars.anti->aborted) {
|
||||
if (ANTI_ABORTED()) {
|
||||
return langGet(L_OPTIONS_295); // "Aborted"
|
||||
}
|
||||
|
||||
@@ -320,7 +341,7 @@ char *endscreenMenuTextMissionStatus(struct menuitem *item)
|
||||
return langGet(L_OPTIONS_293); // "Failed"
|
||||
}
|
||||
} else {
|
||||
if (g_Vars.anti->aborted) {
|
||||
if (ANTI_ABORTED()) {
|
||||
return langGet(L_OPTIONS_295); // "Aborted"
|
||||
}
|
||||
|
||||
@@ -1700,14 +1721,22 @@ void endscreenPushCoop(void)
|
||||
#endif
|
||||
{
|
||||
// Failed or aborted
|
||||
if (optionsGetScreenSplit() == SCREENSPLIT_VERTICAL) {
|
||||
if (optionsGetScreenSplit() == SCREENSPLIT_VERTICAL
|
||||
#ifndef PLATFORM_N64
|
||||
|| LOCALPLAYERCOUNT() >= 3
|
||||
#endif
|
||||
) {
|
||||
menuPushRootDialog(&g_2PMissionEndscreenFailedVMenuDialog, MENUROOT_MPENDSCREEN);
|
||||
} else {
|
||||
menuPushRootDialog(&g_2PMissionEndscreenFailedHMenuDialog, MENUROOT_MPENDSCREEN);
|
||||
}
|
||||
} else {
|
||||
// Completed
|
||||
if (optionsGetScreenSplit() == SCREENSPLIT_VERTICAL) {
|
||||
if (optionsGetScreenSplit() == SCREENSPLIT_VERTICAL
|
||||
#ifndef PLATFORM_N64
|
||||
|| LOCALPLAYERCOUNT() >= 3
|
||||
#endif
|
||||
) {
|
||||
menuPushRootDialog(&g_2PMissionEndscreenCompletedVMenuDialog, MENUROOT_MPENDSCREEN);
|
||||
} else {
|
||||
menuPushRootDialog(&g_2PMissionEndscreenCompletedHMenuDialog, MENUROOT_MPENDSCREEN);
|
||||
@@ -1787,20 +1816,28 @@ void endscreenPushAnti(void)
|
||||
|
||||
if (g_Vars.currentplayer == g_Vars.bond) {
|
||||
#if VERSION >= VERSION_NTSC_1_0 && defined(DEBUG)
|
||||
if (!g_Vars.anti->aborted && (g_Vars.bond->isdead || g_Vars.bond->aborted || !objectiveIsAllComplete()) && !debugIsSetCompleteEnabled())
|
||||
if (!ANTI_ABORTED() && (g_Vars.bond->isdead || g_Vars.bond->aborted || !objectiveIsAllComplete()) && !debugIsSetCompleteEnabled())
|
||||
#else
|
||||
if (!g_Vars.anti->aborted && (g_Vars.bond->isdead || g_Vars.bond->aborted || !objectiveIsAllComplete()))
|
||||
if (!ANTI_ABORTED() && (g_Vars.bond->isdead || g_Vars.bond->aborted || !objectiveIsAllComplete()))
|
||||
#endif
|
||||
{
|
||||
// Bond - failed or aborted
|
||||
if (optionsGetScreenSplit() == SCREENSPLIT_VERTICAL) {
|
||||
if (optionsGetScreenSplit() == SCREENSPLIT_VERTICAL
|
||||
#ifndef PLATFORM_N64
|
||||
|| LOCALPLAYERCOUNT() >= 3
|
||||
#endif
|
||||
) {
|
||||
menuPushRootDialog(&g_2PMissionEndscreenFailedVMenuDialog, MENUROOT_MPENDSCREEN);
|
||||
} else {
|
||||
menuPushRootDialog(&g_2PMissionEndscreenFailedHMenuDialog, MENUROOT_MPENDSCREEN);
|
||||
}
|
||||
} else {
|
||||
// Bond - completed
|
||||
if (optionsGetScreenSplit() == SCREENSPLIT_VERTICAL) {
|
||||
if (optionsGetScreenSplit() == SCREENSPLIT_VERTICAL
|
||||
#ifndef PLATFORM_N64
|
||||
|| LOCALPLAYERCOUNT() >= 3
|
||||
#endif
|
||||
) {
|
||||
menuPushRootDialog(&g_2PMissionEndscreenCompletedVMenuDialog, MENUROOT_MPENDSCREEN);
|
||||
} else {
|
||||
menuPushRootDialog(&g_2PMissionEndscreenCompletedHMenuDialog, MENUROOT_MPENDSCREEN);
|
||||
@@ -1810,20 +1847,28 @@ void endscreenPushAnti(void)
|
||||
filemgrSaveOrLoad(&g_GameFileGuid, FILEOP_SAVE_GAME_000, 0);
|
||||
} else {
|
||||
#if VERSION >= VERSION_NTSC_1_0 && defined(DEBUG)
|
||||
if (!g_Vars.anti->aborted && (g_Vars.bond->isdead || g_Vars.bond->aborted || !objectiveIsAllComplete()) && !debugIsSetCompleteEnabled())
|
||||
if (!ANTI_ABORTED() && (g_Vars.bond->isdead || g_Vars.bond->aborted || !objectiveIsAllComplete()) && !debugIsSetCompleteEnabled())
|
||||
#else
|
||||
if (!g_Vars.anti->aborted && (g_Vars.bond->isdead || g_Vars.bond->aborted || !objectiveIsAllComplete()))
|
||||
if (!ANTI_ABORTED() && (g_Vars.bond->isdead || g_Vars.bond->aborted || !objectiveIsAllComplete()))
|
||||
#endif
|
||||
{
|
||||
// Anti - completed
|
||||
if (optionsGetScreenSplit() == SCREENSPLIT_VERTICAL) {
|
||||
if (optionsGetScreenSplit() == SCREENSPLIT_VERTICAL
|
||||
#ifndef PLATFORM_N64
|
||||
|| LOCALPLAYERCOUNT() >= 3
|
||||
#endif
|
||||
) {
|
||||
menuPushRootDialog(&g_2PMissionEndscreenCompletedVMenuDialog, MENUROOT_MPENDSCREEN);
|
||||
} else {
|
||||
menuPushRootDialog(&g_2PMissionEndscreenCompletedHMenuDialog, MENUROOT_MPENDSCREEN);
|
||||
}
|
||||
} else {
|
||||
// Anti - failed or aborted
|
||||
if (optionsGetScreenSplit() == SCREENSPLIT_VERTICAL) {
|
||||
if (optionsGetScreenSplit() == SCREENSPLIT_VERTICAL
|
||||
#ifndef PLATFORM_N64
|
||||
|| LOCALPLAYERCOUNT() >= 3
|
||||
#endif
|
||||
) {
|
||||
menuPushRootDialog(&g_2PMissionEndscreenFailedVMenuDialog, MENUROOT_MPENDSCREEN);
|
||||
} else {
|
||||
menuPushRootDialog(&g_2PMissionEndscreenFailedHMenuDialog, MENUROOT_MPENDSCREEN);
|
||||
|
||||
+16
-4
@@ -35,7 +35,7 @@
|
||||
#endif
|
||||
|
||||
struct explosion *g_Explosions;
|
||||
s32 g_MaxExplosions = MAX_EXPLOSIONS_DEFAULT;
|
||||
s32 g_MaxExplosions;
|
||||
|
||||
s32 g_ExplosionShakeTotalTimer = 0;
|
||||
s32 g_ExplosionShakeIntensityTimer = 0;
|
||||
@@ -847,7 +847,7 @@ void explosionInflictDamage(struct prop *expprop)
|
||||
minfrac = (minfrac * 0.7f + 0.3f) * type->damage;
|
||||
|
||||
if (g_Vars.antiplayernum >= 0
|
||||
&& g_Vars.antiplayernum == exp->owner
|
||||
&& EXPLOSION_OWNER_IS_ANTI_PLAYER(exp->owner)
|
||||
&& (obj->flags2 & OBJFLAG2_IMMUNETOANTI)) {
|
||||
// anti cannot damage this obj
|
||||
} else if (isfirstframe) {
|
||||
@@ -997,8 +997,16 @@ void explosionInflictDamage(struct prop *expprop)
|
||||
ownerprop = g_Vars.bond->prop;
|
||||
} else if (g_Vars.coopplayernum >= 0 && exp->owner == g_Vars.coopplayernum) {
|
||||
ownerprop = g_Vars.coop->prop;
|
||||
} else if (g_Vars.antiplayernum >= 0 && exp->owner == g_Vars.antiplayernum) {
|
||||
} else if (g_Vars.antiplayernum >= 0 && EXPLOSION_OWNER_IS_ANTI_PLAYER(exp->owner)) {
|
||||
#if PLATFORM_N64
|
||||
ownerprop = g_Vars.anti->prop;
|
||||
#else
|
||||
struct chrdata *ownerchr = mpGetChrFromPlayerIndex(exp->owner);
|
||||
|
||||
if (ownerchr) {
|
||||
ownerprop = ownerchr->prop;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
chrDamageByExplosion(chr, minfrac, &spa0, ownerprop, &expprop->pos);
|
||||
@@ -1212,8 +1220,12 @@ u32 explosionTick(struct prop *prop)
|
||||
|
||||
if (g_Vars.normmplayerisrunning) {
|
||||
chr = mpGetChrFromPlayerIndex(exp->owner);
|
||||
} else if (g_Vars.antiplayernum >= 0 && exp->owner == g_Vars.antiplayernum) {
|
||||
} else if (g_Vars.antiplayernum >= 0 && EXPLOSION_OWNER_IS_ANTI_PLAYER(exp->owner)) {
|
||||
#if PLATFORM_N64
|
||||
chr = g_Vars.anti->prop->chr;
|
||||
#else
|
||||
chr = mpGetChrFromPlayerIndex(exp->owner);
|
||||
#endif
|
||||
} else if (g_Vars.coopplayernum >= 0 && exp->owner == g_Vars.coopplayernum) {
|
||||
chr = g_Vars.coop->prop->chr;
|
||||
} else {
|
||||
|
||||
@@ -14,6 +14,12 @@ void explosionsReset(void)
|
||||
g_ExplosionShakeIntensityTimer = 0;
|
||||
g_ExplosionDamageTxScale = 1;
|
||||
|
||||
g_MaxExplosions = MAX_EXPLOSIONS;
|
||||
|
||||
if (g_Vars.stagenum >= STAGE_TITLE) {
|
||||
g_MaxExplosions = 0;
|
||||
}
|
||||
|
||||
if (g_MaxExplosions == 0) {
|
||||
g_Explosions = NULL;
|
||||
} else {
|
||||
|
||||
@@ -14,7 +14,7 @@ void explosionsStop(void)
|
||||
viShake(0);
|
||||
|
||||
if (g_Explosions) {
|
||||
for (i = 0; i < g_MaxExplosions; i++) {
|
||||
for (i = 0; i < MAX_EXPLOSIONS; i++) {
|
||||
if (g_Explosions[i].prop) {
|
||||
propDelist(g_Explosions[i].prop);
|
||||
propDisable(g_Explosions[i].prop);
|
||||
|
||||
+1
-1
@@ -24,7 +24,7 @@
|
||||
|
||||
s32 g_FilelistKnownPlugCounts[5];
|
||||
|
||||
struct filelist *g_FileLists[MAX_PLAYERS] = { NULL };
|
||||
struct filelist *g_FileLists[MAX_LOCAL_PLAYERS] = { NULL };
|
||||
bool var80075bd0[] = { true, true, true, true };
|
||||
bool var80075be0[] = { false, false, false, false };
|
||||
u32 var80075bf0 = false;
|
||||
|
||||
+8
-13
@@ -19,14 +19,13 @@
|
||||
#include "lib/str.h"
|
||||
#include "data.h"
|
||||
#include "types.h"
|
||||
#include "mpsetups.h"
|
||||
|
||||
// bss
|
||||
struct fileguid g_FilemgrFileToCopy;
|
||||
struct fileguid var800a21e8;
|
||||
|
||||
#if VERSION >= VERSION_JPN_FINAL
|
||||
struct fileguid g_FilemgrFileToDelete[MAX_PLAYERS];
|
||||
struct fileguid g_FilemgrFileToDelete[MAX_LOCAL_PLAYERS];
|
||||
#else
|
||||
struct fileguid g_FilemgrFileToDelete;
|
||||
#endif
|
||||
@@ -971,7 +970,7 @@ void filemgrDeleteCurrentFile(void)
|
||||
filemgrPushErrorDialog(FILEERROR_DELETEFAILED);
|
||||
} else {
|
||||
// If deleting a loaded MP player, reset them to default
|
||||
for (i = 0; i < MAX_PLAYERS; i++) {
|
||||
for (i = 0; i < MAX_LOCAL_PLAYERS; i++) {
|
||||
if (g_FilemgrFileToDelete[g_MpPlayerNum].fileid == g_PlayerConfigsArray[i].fileguid.fileid
|
||||
&& g_FilemgrFileToDelete[g_MpPlayerNum].deviceserial == g_PlayerConfigsArray[i].fileguid.deviceserial) {
|
||||
mpPlayerSetDefaults(i, true);
|
||||
@@ -998,7 +997,7 @@ void filemgrDeleteCurrentFile(void)
|
||||
filemgrPushErrorDialog(FILEERROR_DELETEFAILED);
|
||||
} else {
|
||||
// If deleting a loaded MP player, reset them to default
|
||||
for (i = 0; i < MAX_PLAYERS; i++) {
|
||||
for (i = 0; i < MAX_LOCAL_PLAYERS; i++) {
|
||||
if (g_FilemgrFileToDelete.fileid == g_PlayerConfigsArray[i].fileguid.fileid
|
||||
&& g_FilemgrFileToDelete.deviceserial == g_PlayerConfigsArray[i].fileguid.deviceserial) {
|
||||
mpPlayerSetDefaults(i, true);
|
||||
@@ -1845,7 +1844,7 @@ bool filemgrIsFileInUse(struct filelistfile *file)
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < MAX_PLAYERS; i++) {
|
||||
for (i = 0; i < MAX_LOCAL_PLAYERS; i++) {
|
||||
if ((g_MpSetup.chrslots & (1 << i))
|
||||
&& g_PlayerConfigsArray[i].fileguid.fileid == file->fileid
|
||||
&& g_PlayerConfigsArray[i].fileguid.deviceserial == file->deviceserial) {
|
||||
@@ -1983,7 +1982,7 @@ bool filemgrIsFileInUse(struct filelistfile *file)
|
||||
return true;
|
||||
}
|
||||
|
||||
for (i = 0; i < MAX_PLAYERS; i++) {
|
||||
for (i = 0; i < MAX_LOCAL_PLAYERS; i++) {
|
||||
if ((g_MpSetup.chrslots & (1 << i))
|
||||
&& g_PlayerConfigsArray[i].fileguid.fileid == file->fileid
|
||||
&& g_PlayerConfigsArray[i].fileguid.deviceserial == file->deviceserial) {
|
||||
@@ -2421,7 +2420,7 @@ MenuDialogHandlerResult pakChoosePakMenuDialog(s32 operation, struct menudialogd
|
||||
if (g_Vars.stagenum != STAGE_BOOTPAKMENU) {
|
||||
s32 i;
|
||||
|
||||
for (i = 0; i < MAX_PLAYERS; i++) {
|
||||
for (i = 0; i < MAX_LOCAL_PLAYERS; i++) {
|
||||
if (g_Menus[g_MpPlayerNum].fm.unke24 & (1 << i)) {
|
||||
g_Vars.pakstocheck &= 0xfff0;
|
||||
g_Vars.pakstocheck |= 0x0008;
|
||||
@@ -2446,7 +2445,7 @@ MenuDialogHandlerResult pakChoosePakMenuDialog(s32 operation, struct menudialogd
|
||||
{
|
||||
s32 i;
|
||||
|
||||
for (i = 0; i < MAX_PLAYERS; i++) {
|
||||
for (i = 0; i < MAX_LOCAL_PLAYERS; i++) {
|
||||
if (g_Menus[g_MpPlayerNum].fm.unke24 & (1 << i)) {
|
||||
pak0f1169c8(i, STAGE_BOOTPAKMENU == g_Vars.stagenum);
|
||||
}
|
||||
@@ -2733,10 +2732,6 @@ MenuItemHandlerResult filemgrChooseAgentListMenuHandler(s32 operation, struct me
|
||||
g_GameFileGuid.fileid = file->fileid;
|
||||
g_GameFileGuid.deviceserial = file->deviceserial;
|
||||
filemgrSaveOrLoad(&g_GameFileGuid, FILEOP_LOAD_GAME, 0);
|
||||
|
||||
// load the setup file when loading the agent
|
||||
mpsetupCopyAllFromPak();
|
||||
mpsetupLoadCurrentFile();
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -2772,7 +2767,7 @@ MenuDialogHandlerResult filemgrMainMenuDialog(s32 operation, struct menudialogde
|
||||
mpInit(true);
|
||||
|
||||
// Set MP player names to "Player 1" through 4 if blank
|
||||
for (i = 0; i < MAX_PLAYERS; i++) {
|
||||
for (i = 0; i < MAX_LOCAL_PLAYERS; i++) {
|
||||
if (g_PlayerConfigsArray[i].base.name[0] == '\0') {
|
||||
sprintf(g_PlayerConfigsArray[i].base.name, "%s %d\n", langGet(L_MISC_437), i + 1);
|
||||
}
|
||||
|
||||
@@ -167,7 +167,7 @@ f32 func0f0b131c(s32 hand)
|
||||
weapon = weaponFindById(bgunGetWeaponNum2(0));
|
||||
x = weapon->posx;
|
||||
|
||||
if (PLAYERCOUNT() == 2 && optionsGetScreenSplit() == SCREENSPLIT_VERTICAL) {
|
||||
if (LOCALPLAYERCOUNT() == 2 && optionsGetScreenSplit() == SCREENSPLIT_VERTICAL) {
|
||||
x -= 3.5f;
|
||||
|
||||
if (g_Vars.currentplayernum == 0) {
|
||||
@@ -178,7 +178,7 @@ f32 func0f0b131c(s32 hand)
|
||||
weapon = weaponFindById(bgunGetWeaponNum2(1));
|
||||
x = -weapon->posx;
|
||||
|
||||
if (PLAYERCOUNT() == 2 && optionsGetScreenSplit() == SCREENSPLIT_VERTICAL) {
|
||||
if (LOCALPLAYERCOUNT() == 2 && optionsGetScreenSplit() == SCREENSPLIT_VERTICAL) {
|
||||
x += 3.5f;
|
||||
|
||||
if (g_Vars.currentplayernum == 0) {
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#include "game/game_0b2150.h"
|
||||
#include "game/tex.h"
|
||||
#include "game/sky.h"
|
||||
#include "game/artifact.h"
|
||||
#include "game/game_13c510.h"
|
||||
#include "game/bg.h"
|
||||
#include "game/stagetable.h"
|
||||
#include "game/room.h"
|
||||
@@ -21,73 +21,8 @@
|
||||
#include "lib/lib_17ce0.h"
|
||||
#include "game/player.h"
|
||||
#include "game/prop.h"
|
||||
#include "video.h"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Artifacts are points of interest in the z-buffer.
|
||||
*
|
||||
* They correspond to:
|
||||
* - Individual circles in the lens flare effect from the sun.
|
||||
* - Individual corners of each light fixture's box.
|
||||
*
|
||||
* The game needs to do line of sight checks to these points. The collision
|
||||
* system would normally be used for line of sight checks, but it only works
|
||||
* with basic geometric volumes and also doesn't take into account the player's
|
||||
* gun. Instead, the checks are done by reading from the previous frame's
|
||||
* z-buffer.
|
||||
*
|
||||
* Typically, the z-buffer would be read by the scheduler after a graphics frame
|
||||
* is rendered, but this only works if the z-buffer is a complete image.
|
||||
* PD draws the scene, then clears the z-buffer before drawing the player's gun,
|
||||
* so the z-buffer at the end only contains the player's gun. To work around
|
||||
* this, the GPU is given commands to read the z-buffer as a texture and copy
|
||||
* depth values to a safe place before clearing it. Then once the frame is
|
||||
* rendered, the scheduler compares the saved depths with the current z-buffer
|
||||
* and updates the artifact, applying the minimum of the two depths.
|
||||
*
|
||||
* The scheduler maintains 3 arrays of artifacts, each referenced by indexes
|
||||
* which rotate between them.
|
||||
* - Artifacts are written by the main thread using the write index.
|
||||
* The write and front indexes are then incremented.
|
||||
* - The same artifacts are updated by the scheduler using the pending index.
|
||||
* The pending index is then updated.
|
||||
* - The artifacts are then rendered on a later frame using the front index.
|
||||
*
|
||||
* In each artifacts array, the first several slots are reserved for the sun
|
||||
* flare artifacts. The quantity depends on the number of suns in the stage
|
||||
* (Skedar Ruins has 3) and there are 8 artifacts per sun. The remaining slots
|
||||
* are used for light fixture corners. The array is big enough to handle at
|
||||
* least 90 lights on screen at a time.
|
||||
*
|
||||
* The initial state of the indexes are write=0, front=1, pending=0.
|
||||
* These are set in sched_reset_artifacts.
|
||||
*
|
||||
* The detailed workflow is:
|
||||
* - CPU: Light artifacts are determined and added to write artifacts (0) array
|
||||
* - CPU: Constructs the gdl in this order:
|
||||
* - Render scene
|
||||
* - Copy relevant parts of z-buffer to write depths (0) array
|
||||
* - Clear z-buffer and render gun
|
||||
* - Render artifacts by reading from front artifacts (1) array
|
||||
* - CPU: increments write (0 -> 1) and front (1 -> 2) indexes
|
||||
* - GPU: Executes above task. g_ArtifactDepths0 now contains depths, and is
|
||||
* pointed to by pending.
|
||||
* - Scheduler: Reads the z-buffer, which at this point only contains the gun
|
||||
* depth information, and updates the artifact with the minimum of the two
|
||||
* - Scheduler: Increments pending (0 -> 1)
|
||||
*
|
||||
* It appears that the front index should be initialised to 2 instead, so that
|
||||
* it's one frame behind the others rather than two frames behind.
|
||||
*
|
||||
* There's no doubt this went through several iterations before landing on this
|
||||
* implementation. It's likely that this was implemented using a single and full
|
||||
* z-buffer and it worked well until they decided to clear the z-buffer before
|
||||
* rendering the gun. There is evidence in zbuf.c that they allocated a second
|
||||
* z-buffer and swapped it. But when memory got too tight they had to change it
|
||||
* to this texture read method.
|
||||
*/
|
||||
|
||||
u8 *var800a41a0;
|
||||
u32 var800a41a4;
|
||||
u32 var800a41a8;
|
||||
@@ -109,25 +44,11 @@ void artifactsTick(void)
|
||||
schedIncrementFrontArtifacts();
|
||||
}
|
||||
|
||||
u16 floatToN64Depth(f32 arg0)
|
||||
u16 func0f13c574(f32 arg0)
|
||||
{
|
||||
/**
|
||||
* Method to convert a 32 bit floating point depth value to the
|
||||
* unsigned 16 bit integer format used by the zbuffer on the N64.
|
||||
* The argument arg0 represents z normalized to [0, 1] * 32704.0f.
|
||||
*
|
||||
* It works by converting the depth value to a large, unsigned 32 bit
|
||||
* integer before scaling back down to an unsigned 16 bit integer.
|
||||
* The scaling is done using bit shift operations on the most & least
|
||||
* significant bytes of the resulting 16 bit integer, likely because
|
||||
* bit shift operations are faster than division. The segmentation of
|
||||
* this calculation at values 0x3f800, 0x3f000, etc. is probably
|
||||
* intended to reduce z-fighting by adding more differentiation for
|
||||
* distant z values.
|
||||
*/
|
||||
u32 value = arg0 * 8.0f;
|
||||
u32 left; // forms the most significant byte of the final u16
|
||||
u32 right = value; // forms the least significant byte of the final u16
|
||||
u32 left;
|
||||
u32 right = value;
|
||||
|
||||
if (value > 0x3f800) {
|
||||
right = value & 0x7ff;
|
||||
@@ -166,7 +87,7 @@ u16 floatToN64Depth(f32 arg0)
|
||||
return left << 13 | (right << 2);
|
||||
}
|
||||
|
||||
s32 artifactsFloatToInt(f32 arg0)
|
||||
s32 func0f13c710(f32 arg0)
|
||||
{
|
||||
if (arg0 > 0.0f) {
|
||||
if (arg0 > 2147483520.0f) {
|
||||
@@ -247,12 +168,6 @@ void artifactsCalculateGlaresForRoom(s32 roomnum)
|
||||
struct coord *campos = &g_Vars.currentplayer->cam_pos;
|
||||
struct artifact *artifact;
|
||||
|
||||
#ifndef PLATFORM_N64
|
||||
if (videoGetGlareBrightness() <= 0.f) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (g_Rooms[roomnum].gfxdata != NULL && g_Rooms[roomnum].loaded240) {
|
||||
numlights = g_Rooms[roomnum].gfxdata->numlights;
|
||||
|
||||
@@ -317,8 +232,8 @@ void artifactsCalculateGlaresForRoom(s32 roomnum)
|
||||
|
||||
if (spdc[3] > 0.0001f) {
|
||||
f20 = 1.0f / spdc[3];
|
||||
x = artifactsFloatToInt(viewleft + (1.0f + spdc[0] * f20) * (viewwidth * 0.5f));
|
||||
y = artifactsFloatToInt(viewtop + (1.0f - spdc[1] * f20) * (viewheight * 0.5f));
|
||||
x = func0f13c710(viewleft + (1.0f + spdc[0] * f20) * (viewwidth * 0.5f));
|
||||
y = func0f13c710(viewtop + (1.0f - spdc[1] * f20) * (viewheight * 0.5f));
|
||||
f0 = (spdc[2] * f20 * 511.0f + 511.0f) * 32.0f;
|
||||
|
||||
if (f0 < 32576.0f) {
|
||||
@@ -420,8 +335,8 @@ void artifactsCalculateGlaresForRoom(s32 roomnum)
|
||||
f20 = -9999.0f;
|
||||
}
|
||||
|
||||
xi = artifactsFloatToInt(viewleft + (1.0f + spdc[0] * f20) * (viewwidth * 0.5f));
|
||||
yi = artifactsFloatToInt(viewtop + (1.0f - spdc[1] * f20) * (viewheight * 0.5f));
|
||||
xi = func0f13c710(viewleft + (1.0f + spdc[0] * f20) * (viewwidth * 0.5f));
|
||||
yi = func0f13c710(viewtop + (1.0f - spdc[1] * f20) * (viewheight * 0.5f));
|
||||
f0 = (spdc[2] * f20 * 511.0f + 511.0f) * 32.0f;
|
||||
|
||||
if (g_ZbufPtr1
|
||||
@@ -442,20 +357,14 @@ void artifactsCalculateGlaresForRoom(s32 roomnum)
|
||||
|
||||
if (index < MAX_ARTIFACTS) {
|
||||
#ifndef PLATFORM_N64
|
||||
artifact->visiblelos = artifactTestLos(&spec, &g_BgRooms[roomnum].pos, xi, yi);
|
||||
artifact->unk02 = artifactTestLos(&spec, &g_BgRooms[roomnum].pos, xi, yi);
|
||||
#endif
|
||||
/**
|
||||
* the original game performs artifact depth comparison
|
||||
* using the N64 depth values divided by 4. This is
|
||||
* accomplished by bit shifting the N64 depth value
|
||||
* to the right using >> 2
|
||||
*/
|
||||
artifact->expecteddepth = floatToN64Depth(f0) >> 2;
|
||||
artifact->zbufptr = &g_ZbufPtr1[viGetWidth() * yi + xi];
|
||||
artifact->unk04 = func0f13c574(f0) >> 2;
|
||||
artifact->unk08 = &g_ZbufPtr1[viGetWidth() * yi + xi];
|
||||
artifact->light = &roomlights[i];
|
||||
artifact->type = ARTIFACTTYPE_GLARE;
|
||||
artifact->screenx = xi;
|
||||
artifact->screeny = yi;
|
||||
artifact->unk0c.u16_2 = xi;
|
||||
artifact->unk0c.u16_1 = yi;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -466,7 +375,7 @@ void artifactsCalculateGlaresForRoom(s32 roomnum)
|
||||
}
|
||||
}
|
||||
|
||||
u8 artifactsClamp(u8 arg0, u8 arg1)
|
||||
u8 func0f13d3c4(u8 arg0, u8 arg1)
|
||||
{
|
||||
if (arg1 >= arg0 + 7) {
|
||||
return arg0 + 7;
|
||||
@@ -514,18 +423,18 @@ Gfx *artifactsRenderGlaresForRoom(Gfx *gdl, s32 roomnum)
|
||||
u16 min;
|
||||
u16 max;
|
||||
f32 lightop_cur_frac;
|
||||
s32 numgood;
|
||||
s32 t2;
|
||||
struct light *light;
|
||||
u8 *s3;
|
||||
s32 k;
|
||||
s32 count;
|
||||
u16 actualdepth;
|
||||
u16 t4;
|
||||
f32 add;
|
||||
s32 l;
|
||||
f32 brightness;
|
||||
s32 tolerance;
|
||||
s32 avg;
|
||||
f32 f0;
|
||||
s32 difference;
|
||||
s32 v1;
|
||||
s32 r;
|
||||
s32 g;
|
||||
s32 b;
|
||||
@@ -539,13 +448,6 @@ Gfx *artifactsRenderGlaresForRoom(Gfx *gdl, s32 roomnum)
|
||||
f32 f24;
|
||||
bool extra;
|
||||
f32 f26;
|
||||
#ifndef PLATFORM_N64
|
||||
const f32 pfov = g_Vars.currentplayerstats ? PLAYER_DEFAULT_FOV : 60.f;
|
||||
const f32 brightscale = videoGetGlareBrightness();
|
||||
if (brightscale <= 0.f) {
|
||||
return gdl;
|
||||
}
|
||||
#endif
|
||||
|
||||
artifacts = schedGetFrontArtifacts();
|
||||
lightop_cur_frac = roomGetLightOpCurFrac(roomnum);
|
||||
@@ -558,12 +460,6 @@ Gfx *artifactsRenderGlaresForRoom(Gfx *gdl, s32 roomnum)
|
||||
struct light *light2 = artifacts[i].light;
|
||||
count = 0;
|
||||
|
||||
/**
|
||||
* light arifacts are created from several, closely spaced
|
||||
* textures that give the appearance of a dynamic light glare
|
||||
* as the character moves. Loop to count all the sub-artifacts
|
||||
* in this light.
|
||||
*/
|
||||
for (j = i; j < MAX_ARTIFACTS && artifacts[j].type == ARTIFACTTYPE_GLARE && artifacts[j].light == light2; j++) {
|
||||
count++;
|
||||
}
|
||||
@@ -574,70 +470,52 @@ Gfx *artifactsRenderGlaresForRoom(Gfx *gdl, s32 roomnum)
|
||||
if (roomnum == light->roomnum) {
|
||||
lightindex = ((uintptr_t)light - (uintptr_t)g_BgLightsFileData) / sizeof(struct light);
|
||||
s3 = &var800a41a0[lightindex * 3];
|
||||
numgood = 0;
|
||||
t2 = 0;
|
||||
min = 0xffff;
|
||||
max = 0;
|
||||
|
||||
/**
|
||||
* loop to determine the min & max depth of
|
||||
* the sub-artifacts composing this room light.
|
||||
*/
|
||||
for (k = i; k < i + count; k++) {
|
||||
if (artifacts[k].expecteddepth > max) {
|
||||
max = artifacts[k].expecteddepth;
|
||||
if (artifacts[k].unk04 > max) {
|
||||
max = artifacts[k].unk04;
|
||||
}
|
||||
|
||||
if (artifacts[k].expecteddepth < min) {
|
||||
min = artifacts[k].expecteddepth;
|
||||
if (artifacts[k].unk04 < min) {
|
||||
min = artifacts[k].unk04;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Define a depth tolerance from the min & max
|
||||
* depths of sub-artifacts for a given light.
|
||||
* This will be used to determine which light
|
||||
* artifacts are visible when comparing depth
|
||||
* values of lights to other items rendered
|
||||
* on screen. Without this, the lights would
|
||||
* constantly flicker due to z-fighting caused
|
||||
* by the low precision of the N64 depth.
|
||||
*/
|
||||
tolerance = (max - min) >> 1;
|
||||
avg = (max - min) >> 1;
|
||||
|
||||
if (tolerance < 25) {
|
||||
tolerance = 25;
|
||||
if (avg < 25) {
|
||||
avg = 25;
|
||||
}
|
||||
|
||||
for (k = i; k < i + count; k++) {
|
||||
#ifdef PLATFORM_N64
|
||||
u16 expecteddepth;
|
||||
actualdepth = (artifacts[k].actualdepth & 0xfffc) >> 2;
|
||||
expecteddepth = artifacts[k].expecteddepth;
|
||||
u16 tmp;
|
||||
t4 = (artifacts[k].unk02 & 0xfffc) >> 2;
|
||||
tmp = artifacts[k].unk04;
|
||||
|
||||
if (expecteddepth < actualdepth) {
|
||||
difference = actualdepth - expecteddepth;
|
||||
if (tmp < t4) {
|
||||
v1 = t4 - tmp;
|
||||
} else {
|
||||
difference = expecteddepth - actualdepth;
|
||||
v1 = tmp - t4;
|
||||
}
|
||||
|
||||
if (difference <= tolerance) {
|
||||
numgood++;
|
||||
if (avg >= v1) {
|
||||
t2++;
|
||||
}
|
||||
#else
|
||||
numgood += artifacts[k].visiblelos;
|
||||
t2 += artifacts[k].unk02;
|
||||
#endif
|
||||
|
||||
artifacts[k].type = ARTIFACTTYPE_FREE;
|
||||
}
|
||||
|
||||
s3[0] = artifactsClamp(s3[0], numgood * 2);
|
||||
s3[0] = func0f13d3c4(s3[0], t2 * 2);
|
||||
|
||||
if (numgood > 0) {
|
||||
#ifndef PLATFORM_N64
|
||||
brightness = viGetFovY() / pfov;
|
||||
#else
|
||||
if (t2 > 0) {
|
||||
brightness = viGetFovY() * 0.017453292f;
|
||||
#endif
|
||||
add = cosf(brightness) / sinf(brightness) * 14.6f;
|
||||
|
||||
if (lightIsHealthy(roomnum, lightindex - g_Rooms[roomnum].gfxdata->lightsindex)) {
|
||||
@@ -667,9 +545,6 @@ Gfx *artifactsRenderGlaresForRoom(Gfx *gdl, s32 roomnum)
|
||||
}
|
||||
|
||||
f0 = s3[2] * (1.0f / 255.0f);
|
||||
#ifndef PLATFORM_N64
|
||||
f0 *= (60.f / pfov);
|
||||
#endif
|
||||
|
||||
skySetOverexposure((s32) ((f32)f0 * r), (s32) ((f32)f0 * g), (s32) ((f32)f0 * b));
|
||||
|
||||
@@ -719,10 +594,6 @@ Gfx *artifactsRenderGlaresForRoom(Gfx *gdl, s32 roomnum)
|
||||
alpha *= (s3[1] / 255.0f);
|
||||
alpha *= (s3[0] / 8.0f);
|
||||
|
||||
#ifndef PLATFORM_N64
|
||||
alpha *= brightscale;
|
||||
#endif
|
||||
|
||||
if (USINGDEVICE(DEVICE_NIGHTVISION)) {
|
||||
alpha *= lightop_cur_frac * 7.0f;
|
||||
}
|
||||
@@ -2183,7 +2183,7 @@ Gfx *text0f156a24(Gfx *gdl, s32 x, s32 y, struct fontchar *char1, s32 arg4, s32
|
||||
if (y + char1->baseline >= arg5) {
|
||||
if (arg5 + arg7 >= y + char1->baseline + char1->height + 2) {
|
||||
if (g_TextRotated90) {
|
||||
gSPTextureRectangleFlip(gdl++,
|
||||
gSPTextureRectangleFlipEXT(gdl++,
|
||||
((y - char1->baseline) - ((char1->height + 2) * var8007fad0)) * 4,
|
||||
x * 4,
|
||||
(y - char1->baseline) * 4,
|
||||
@@ -2194,7 +2194,7 @@ Gfx *text0f156a24(Gfx *gdl, s32 x, s32 y, struct fontchar *char1, s32 arg4, s32
|
||||
1024 / var8007fad0,
|
||||
-1024);
|
||||
} else {
|
||||
gSPTextureRectangle(gdl++,
|
||||
gSPTextureRectangleEXT(gdl++,
|
||||
x * 4,
|
||||
(y + char1->baseline) * 4,
|
||||
(x + char1->width * var8007fad0 + 2) * 4,
|
||||
@@ -2207,7 +2207,7 @@ Gfx *text0f156a24(Gfx *gdl, s32 x, s32 y, struct fontchar *char1, s32 arg4, s32
|
||||
}
|
||||
} else {
|
||||
if (arg5 + arg7 >= y + char1->baseline) {
|
||||
gSPTextureRectangle(gdl++,
|
||||
gSPTextureRectangleEXT(gdl++,
|
||||
x * 4,
|
||||
(y + char1->baseline) * 4,
|
||||
(x + char1->width * var8007fad0 + 2) * 4,
|
||||
@@ -2221,7 +2221,7 @@ Gfx *text0f156a24(Gfx *gdl, s32 x, s32 y, struct fontchar *char1, s32 arg4, s32
|
||||
}
|
||||
} else {
|
||||
if (y + char1->baseline + char1->height + 2 >= arg5) {
|
||||
gSPTextureRectangle(gdl++,
|
||||
gSPTextureRectangleEXT(gdl++,
|
||||
x * 4,
|
||||
arg5 * 4,
|
||||
(x + char1->width * var8007fad0 + 2) * 4,
|
||||
|
||||
+4
-4
@@ -258,7 +258,7 @@ void gamefileLoadDefaults(struct gamefile *file)
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAYCOUNT(g_MpChallenges); i++) {
|
||||
for (j = 1; j < MAX_PLAYERS + 1; j++) {
|
||||
for (j = 1; j < MAX_LOCAL_PLAYERS + 1; j++) {
|
||||
challengeSetCompletedByAnyPlayerWithNumPlayers(i, j, false);
|
||||
}
|
||||
}
|
||||
@@ -362,7 +362,7 @@ s32 gamefileLoad(s32 device)
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAYCOUNT(g_MpChallenges); i++) {
|
||||
for (j = 1; j < MAX_PLAYERS + 1; j++) {
|
||||
for (j = 1; j < MAX_LOCAL_PLAYERS + 1; j++) {
|
||||
challengeSetCompletedByAnyPlayerWithNumPlayers(i, j, savebufferReadBits(&buffer, 1));
|
||||
}
|
||||
}
|
||||
@@ -537,7 +537,7 @@ s32 gamefileSave(s32 device, s32 fileid, u16 deviceserial)
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAYCOUNT(g_MpChallenges); i++) {
|
||||
for (j = 1; j < MAX_PLAYERS + 1; j++) {
|
||||
for (j = 1; j < MAX_LOCAL_PLAYERS + 1; j++) {
|
||||
savebufferOr(&buffer, challengeIsCompletedByAnyPlayerWithNumPlayers(i, j), 1);
|
||||
}
|
||||
}
|
||||
@@ -598,7 +598,7 @@ void gamefileUnlockEverything(void)
|
||||
|
||||
// unlock all challenges
|
||||
for (i = 0; i < ARRAYCOUNT(g_MpChallenges); ++i) {
|
||||
for (j = 0; j < MAX_PLAYERS; ++j) {
|
||||
for (j = 0; j < MAX_LOCAL_PLAYERS; ++j) {
|
||||
g_MpChallenges[i].completions[j] = 0xff;
|
||||
}
|
||||
}
|
||||
|
||||
+29
-21
@@ -57,6 +57,12 @@ u32 g_GfxSizesByPlayerCount[] = {
|
||||
0x00018000 * GFX_SIZE_MULTIPLIER,
|
||||
0x00020000 * GFX_SIZE_MULTIPLIER,
|
||||
0x00028000 * GFX_SIZE_MULTIPLIER,
|
||||
#ifndef PLATFORM_N64
|
||||
0x00030000 * GFX_SIZE_MULTIPLIER,
|
||||
0x00038000 * GFX_SIZE_MULTIPLIER,
|
||||
0x00040000 * GFX_SIZE_MULTIPLIER,
|
||||
0x00048000 * GFX_SIZE_MULTIPLIER,
|
||||
#endif
|
||||
};
|
||||
|
||||
u32 g_VtxSizesByPlayerCount[] = {
|
||||
@@ -64,6 +70,12 @@ u32 g_VtxSizesByPlayerCount[] = {
|
||||
0x00018000,
|
||||
0x00020000,
|
||||
0x00028000,
|
||||
#ifndef PLATFORM_N64
|
||||
0x00030000,
|
||||
0x00038000,
|
||||
0x00040000,
|
||||
0x00048000,
|
||||
#endif
|
||||
};
|
||||
|
||||
s32 g_GfxNumSwapsPerBuffer[NUM_GFXTASKS] = {0, 1};
|
||||
@@ -104,37 +116,33 @@ void gfxReset(void)
|
||||
// ******** Extra Amount required = %dK ber buffer\n
|
||||
// ******** Total of %dK (Double Buffered)\n
|
||||
g_GfxSizesByPlayerCount[PLAYERCOUNT() - 1] = (gfx + gfxtra) * GFX_SIZE_MULTIPLIER;
|
||||
#ifndef PLATFORM_N64
|
||||
if (PLAYERCOUNT() > MAX_LOCAL_PLAYERS) {
|
||||
g_GfxSizesByPlayerCount[PLAYERCOUNT() - 1] *= MAX_PLAYERS / MAX_LOCAL_PLAYERS;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (argFindByPrefix(1, "-mvtx")) {
|
||||
// Argument specified mtxvtx_size\n
|
||||
g_VtxSizesByPlayerCount[PLAYERCOUNT() - 1] = strtol(argFindByPrefix(1, "-mvtx"), NULL, 0) * 1024;
|
||||
}
|
||||
|
||||
{
|
||||
u32 gfxsize = g_GfxSizesByPlayerCount[PLAYERCOUNT() - 1];
|
||||
u32 vtxsize = g_VtxSizesByPlayerCount[PLAYERCOUNT() - 1];
|
||||
|
||||
#ifndef PLATFORM_N64
|
||||
// Each extra rendered decal needs display list commands and per-frame colours
|
||||
if (g_DecalLimitMultiplier > 1) {
|
||||
u32 extradecals = 360 * (g_DecalLimitMultiplier - 1);
|
||||
gfxsize = ALIGN16(gfxsize + extradecals * 6 * sizeof(Gfx));
|
||||
vtxsize = ALIGN16(vtxsize + extradecals * 32);
|
||||
if (PLAYERCOUNT() > MAX_LOCAL_PLAYERS) {
|
||||
g_VtxSizesByPlayerCount[PLAYERCOUNT() - 1] *= MAX_PLAYERS / MAX_LOCAL_PLAYERS;
|
||||
}
|
||||
#endif
|
||||
|
||||
// %d Players : Allocating %d bytes for master dl's\n
|
||||
g_GfxBuffers[0] = mempAlloc(gfxsize * NUM_GFXTASKS, MEMPOOL_STAGE);
|
||||
g_GfxBuffers[1] = g_GfxBuffers[0] + gfxsize;
|
||||
g_GfxBuffers[2] = g_GfxBuffers[1] + gfxsize;
|
||||
|
||||
// Allocating %d bytes for mtxvtx space\n
|
||||
g_VtxBuffers[0] = mempAlloc(vtxsize * NUM_GFXTASKS, MEMPOOL_STAGE);
|
||||
g_VtxBuffers[1] = g_VtxBuffers[0] + vtxsize;
|
||||
g_VtxBuffers[2] = g_VtxBuffers[1] + vtxsize;
|
||||
}
|
||||
|
||||
// %d Players : Allocating %d bytes for master dl's\n
|
||||
g_GfxBuffers[0] = mempAlloc(g_GfxSizesByPlayerCount[PLAYERCOUNT() - 1] * NUM_GFXTASKS, MEMPOOL_STAGE);
|
||||
g_GfxBuffers[1] = g_GfxBuffers[0] + g_GfxSizesByPlayerCount[PLAYERCOUNT() - 1];
|
||||
g_GfxBuffers[2] = g_GfxBuffers[1] + g_GfxSizesByPlayerCount[PLAYERCOUNT() - 1];
|
||||
|
||||
// Allocating %d bytes for mtxvtx space\n
|
||||
g_VtxBuffers[0] = mempAlloc(g_VtxSizesByPlayerCount[PLAYERCOUNT() - 1] * NUM_GFXTASKS, MEMPOOL_STAGE);
|
||||
g_VtxBuffers[1] = g_VtxBuffers[0] + g_VtxSizesByPlayerCount[PLAYERCOUNT() - 1];
|
||||
g_VtxBuffers[2] = g_VtxBuffers[1] + g_VtxSizesByPlayerCount[PLAYERCOUNT() - 1];
|
||||
|
||||
g_GfxActiveBufferIndex = 0;
|
||||
g_GfxRequestedDisplayList = false;
|
||||
g_GfxMemPos = g_VtxBuffers[0];
|
||||
|
||||
+22
-15
@@ -86,7 +86,7 @@ u8 hudmsgsAreActive(void)
|
||||
s32 hudmsgIsZoomRangeVisible(void)
|
||||
{
|
||||
return optionsGetShowZoomRange(g_Vars.currentplayerstats->mpindex)
|
||||
&& (PLAYERCOUNT() == 1
|
||||
&& (LOCALPLAYERCOUNT() == 1
|
||||
|| !g_Vars.mplayerisrunning
|
||||
|| g_Vars.coopplayernum >= 0
|
||||
|| g_Vars.antiplayernum >= 0)
|
||||
@@ -131,7 +131,7 @@ Gfx *hudmsgRenderMissionTimer(Gfx *gdl, u32 alpha)
|
||||
viewleft = viGetViewLeft() / g_ScaleX;
|
||||
viewtop = viGetViewTop();
|
||||
viewheight = viGetViewHeight();
|
||||
playercount = PLAYERCOUNT();
|
||||
playercount = LOCALPLAYERCOUNT();
|
||||
playernum = g_Vars.currentplayernum;
|
||||
|
||||
timery = viewheight;
|
||||
@@ -234,7 +234,7 @@ Gfx *hudmsgRenderZoomRange(Gfx *gdl, u32 alpha)
|
||||
texty = viewheight + viewtop - 1;
|
||||
maxzoom = 1.0f;
|
||||
weaponnum = g_Vars.currentplayer->hands[0].gset.weaponnum;
|
||||
playercount = PLAYERCOUNT();
|
||||
playercount = LOCALPLAYERCOUNT();
|
||||
|
||||
texty -= 17;
|
||||
|
||||
@@ -374,7 +374,7 @@ s32 hudmsg0f0ddb1c(s32 *arg0, s32 arg1)
|
||||
|
||||
*arg0 = 24;
|
||||
|
||||
if (PLAYERCOUNT() == 2
|
||||
if (LOCALPLAYERCOUNT() == 2
|
||||
&& optionsGetScreenSplit() == SCREENSPLIT_VERTICAL
|
||||
&& (!g_InCutscene || g_MainIsEndscreen)) {
|
||||
result -= *arg0 * 2 / 3;
|
||||
@@ -388,7 +388,7 @@ s32 hudmsg0f0ddb1c(s32 *arg0, s32 arg1)
|
||||
|
||||
result = result + viewwidth - *arg0 - arg1 - 11;
|
||||
|
||||
if (PLAYERCOUNT() == 1 || (PLAYERCOUNT() == 2 && g_InCutscene && !g_MainIsEndscreen)) {
|
||||
if (LOCALPLAYERCOUNT() == 1 || (LOCALPLAYERCOUNT() == 2 && g_InCutscene && !g_MainIsEndscreen)) {
|
||||
result -= 16;
|
||||
|
||||
#if VERSION < VERSION_JPN_FINAL
|
||||
@@ -403,7 +403,7 @@ s32 hudmsg0f0ddb1c(s32 *arg0, s32 arg1)
|
||||
|
||||
*arg0 = 24;
|
||||
|
||||
if (PLAYERCOUNT() == 2 && optionsGetScreenSplit() == SCREENSPLIT_VERTICAL) {
|
||||
if (LOCALPLAYERCOUNT() == 2 && optionsGetScreenSplit() == SCREENSPLIT_VERTICAL) {
|
||||
result -= *arg0 * 2 / 3;
|
||||
|
||||
if (g_Vars.currentplayernum == 0) {
|
||||
@@ -415,7 +415,7 @@ s32 hudmsg0f0ddb1c(s32 *arg0, s32 arg1)
|
||||
|
||||
result = result + viewwidth - *arg0 - arg1 - 11;
|
||||
|
||||
if (PLAYERCOUNT() == 1) {
|
||||
if (LOCALPLAYERCOUNT() == 1) {
|
||||
result -= 16;
|
||||
}
|
||||
#endif
|
||||
@@ -857,7 +857,7 @@ void hudmsgCalculatePosition(struct hudmessage *msg)
|
||||
#if VERSION >= VERSION_NTSC_1_0
|
||||
s32 offset = (msg->alignh == HUDMSGALIGN_XMIDDLE) ? 10 : 0;
|
||||
|
||||
if (PLAYERCOUNT() >= 3) {
|
||||
if (LOCALPLAYERCOUNT() >= 3) {
|
||||
viewwidth -= offset;
|
||||
|
||||
if (g_Vars.currentplayernum == 0 || g_Vars.currentplayernum == 2) {
|
||||
@@ -865,7 +865,7 @@ void hudmsgCalculatePosition(struct hudmessage *msg)
|
||||
}
|
||||
}
|
||||
|
||||
if (PLAYERCOUNT() == 2 && (optionsGetScreenSplit() == SCREENSPLIT_VERTICAL || IS4MB())) {
|
||||
if (LOCALPLAYERCOUNT() == 2 && (optionsGetScreenSplit() == SCREENSPLIT_VERTICAL || IS4MB())) {
|
||||
#if VERSION >= VERSION_PAL_FINAL
|
||||
if (!g_InCutscene || g_MainIsEndscreen)
|
||||
#endif
|
||||
@@ -888,7 +888,7 @@ void hudmsgCalculatePosition(struct hudmessage *msg)
|
||||
|
||||
x = viewleft + v0 + msg->xmargin + 3;
|
||||
|
||||
if (PLAYERCOUNT() == 2
|
||||
if (LOCALPLAYERCOUNT() == 2
|
||||
&& (optionsGetScreenSplit() == SCREENSPLIT_VERTICAL || IS4MB())
|
||||
&& (!g_InCutscene || g_MainIsEndscreen)) {
|
||||
if (IS4MB()) {
|
||||
@@ -904,7 +904,7 @@ void hudmsgCalculatePosition(struct hudmessage *msg)
|
||||
x += 4;
|
||||
}
|
||||
}
|
||||
} else if (PLAYERCOUNT() >= 3) {
|
||||
} else if (LOCALPLAYERCOUNT() >= 3) {
|
||||
if ((msg->playernum % 2) == 0) {
|
||||
x--;
|
||||
} else {
|
||||
@@ -933,13 +933,13 @@ void hudmsgCalculatePosition(struct hudmessage *msg)
|
||||
case HUDMSGALIGN_BOTTOM:
|
||||
y = viewtop + viewheight - msg->height - msg->ymargin - 14;
|
||||
|
||||
if (PLAYERCOUNT() == 2 && (g_InCutscene == 0 || g_MainIsEndscreen)) {
|
||||
if (LOCALPLAYERCOUNT() == 2 && (g_InCutscene == 0 || g_MainIsEndscreen)) {
|
||||
if (IS4MB() || (optionsGetScreenSplit() != SCREENSPLIT_VERTICAL && msg->playernum == 0)) {
|
||||
y += 8;
|
||||
} else {
|
||||
y += 3;
|
||||
}
|
||||
} else if (PLAYERCOUNT() >= 3) {
|
||||
} else if (LOCALPLAYERCOUNT() >= 3) {
|
||||
if (msg->playernum <= 1) {
|
||||
y += 8;
|
||||
} else {
|
||||
@@ -987,6 +987,13 @@ void hudmsgCreateFromArgs(char *text, s32 type, s32 conf00, s32 conf01, s32 conf
|
||||
return;
|
||||
}
|
||||
|
||||
#ifndef PLATFORM_N64
|
||||
if (g_NetMode && g_Vars.currentplayernum != 0) {
|
||||
// do not create hudmsgs for other net players
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
for (j = 0; text[j] != '\0'; j++) {
|
||||
hash = hash + text[j];
|
||||
}
|
||||
@@ -1284,7 +1291,7 @@ void hudmsgsTick(void)
|
||||
&& msg->type != HUDMSGTYPE_CUTSCENESUBTITLE
|
||||
&& msg->type != HUDMSGTYPE_INGAMESUBTITLE
|
||||
#endif
|
||||
&& PLAYERCOUNT() == 1) {
|
||||
&& LOCALPLAYERCOUNT() == 1) {
|
||||
#if VERSION >= VERSION_NTSC_1_0
|
||||
sndStart(var80095200, SFX_HUDMSG, NULL, -1, -1, -1, -1, -1);
|
||||
#else
|
||||
@@ -1383,7 +1390,7 @@ Gfx *hudmsgsRender(Gfx *gdl)
|
||||
s32 timerthing = 255;
|
||||
s32 spdc = true;
|
||||
#ifndef PLATFORM_N64
|
||||
const s32 playercount = PLAYERCOUNT();
|
||||
const s32 playercount = LOCALPLAYERCOUNT();
|
||||
#endif
|
||||
|
||||
#if PAL
|
||||
|
||||
@@ -12,15 +12,11 @@ void invReset(void)
|
||||
{
|
||||
s32 i;
|
||||
|
||||
#ifndef PLATFORM_N64
|
||||
g_Vars.currentplayer->equipallguns = cheatIsActive(CHEAT_ALLGUNS);
|
||||
#else
|
||||
if (PLAYERCOUNT() == 1 && g_Vars.normmplayerisrunning == false) {
|
||||
g_Vars.currentplayer->equipallguns = cheatIsActive(CHEAT_ALLGUNS);
|
||||
} else {
|
||||
g_Vars.currentplayer->equipallguns = false;
|
||||
}
|
||||
#endif
|
||||
|
||||
for (i = 0; i != ARRAYCOUNT(g_Vars.currentplayer->gunheldarr); i++) {
|
||||
g_Vars.currentplayer->gunheldarr[i].totaltime240_60 = -1;
|
||||
|
||||
+48
-5
@@ -28,7 +28,7 @@
|
||||
#include "game/portal.h"
|
||||
#include "game/fmb.h"
|
||||
#include "game/sky.h"
|
||||
#include "game/artifact.h"
|
||||
#include "game/game_13c510.h"
|
||||
#include "game/game_1531a0.h"
|
||||
#include "game/zbuf.h"
|
||||
#include "game/challenge.h"
|
||||
@@ -97,6 +97,8 @@
|
||||
#include "lib/vi.h"
|
||||
#include "types.h"
|
||||
#ifndef PLATFORM_N64
|
||||
#include "net/net.h"
|
||||
#include "net/netmsg.h"
|
||||
#include "video.h"
|
||||
#endif
|
||||
|
||||
@@ -322,6 +324,16 @@ void lvReset(s32 stagenum)
|
||||
s32 i;
|
||||
s32 j;
|
||||
|
||||
#ifndef PLATFORM_N64
|
||||
if (g_NetMode == NETMODE_SERVER) {
|
||||
// if we're a server, signal to clients that the level is changing
|
||||
netServerStageStart();
|
||||
} else if (g_NetMode == NETMODE_CLIENT) {
|
||||
// if we're a client, now is the time to apply the server's RNG seeds
|
||||
netClientSyncRng();
|
||||
}
|
||||
#endif
|
||||
|
||||
tilesReset();
|
||||
bgReset(g_Vars.stagenum);
|
||||
bgBuildTables(g_Vars.stagenum);
|
||||
@@ -338,9 +350,9 @@ void lvReset(s32 stagenum)
|
||||
}
|
||||
|
||||
if (g_Vars.mplayerisrunning == false) {
|
||||
g_Vars.playerstats[0].mpindex = 4;
|
||||
g_PlayerConfigsArray[4].contpad1 = 0;
|
||||
g_PlayerConfigsArray[4].contpad2 = 1;
|
||||
g_Vars.playerstats[0].mpindex = MAX_PLAYERS;
|
||||
g_PlayerConfigsArray[MAX_PLAYERS].contpad1 = 0;
|
||||
g_PlayerConfigsArray[MAX_PLAYERS].contpad2 = 1;
|
||||
}
|
||||
|
||||
for (i = 0; i != ARRAYCOUNT(g_Vars.playerstats); i++) {
|
||||
@@ -463,6 +475,12 @@ void lvReset(s32 stagenum)
|
||||
pheadReset();
|
||||
}
|
||||
|
||||
#ifndef PLATFORM_N64
|
||||
if (g_NetMode) {
|
||||
netSyncIdsAllocate();
|
||||
}
|
||||
#endif
|
||||
|
||||
modelmgrSetLvResetting(false);
|
||||
var80084018 = 1;
|
||||
schedResetArtifacts();
|
||||
@@ -1125,6 +1143,13 @@ Gfx *lvRender(Gfx *gdl)
|
||||
struct player *player;
|
||||
struct chrdata *chr;
|
||||
|
||||
#ifndef PLATFORM_N64
|
||||
if (g_NetMode) {
|
||||
// tick all players, we'll skip the rendering
|
||||
forcesingleplayer = false;
|
||||
}
|
||||
#endif
|
||||
|
||||
playercount = forcesingleplayer ? 1 : PLAYERCOUNT();
|
||||
|
||||
gSPClipRatio(gdl++, FRUSTRATIO_2);
|
||||
@@ -1717,12 +1742,21 @@ Gfx *lvRender(Gfx *gdl)
|
||||
}
|
||||
|
||||
if (g_Vars.currentplayer->dostartnewlife) {
|
||||
playerStartNewLife();
|
||||
#ifndef PLATFORM_N64
|
||||
if (g_NetMode != NETMODE_CLIENT)
|
||||
#endif
|
||||
playerStartNewLife();
|
||||
}
|
||||
}
|
||||
|
||||
artifactsTick();
|
||||
|
||||
#ifndef PLATFORM_N64
|
||||
if ((g_NetMode && i) || i >= MAX_LOCAL_PLAYERS) {
|
||||
gdl = savedgdl;
|
||||
}
|
||||
#endif
|
||||
|
||||
if ((g_Vars.coopplayernum >= 0 || g_Vars.antiplayernum >= 0)
|
||||
#if VERSION >= VERSION_NTSC_1_0
|
||||
&& playerHasSharedViewport()
|
||||
@@ -2275,6 +2309,9 @@ void lvTick(void)
|
||||
|
||||
if (elapsed < TICKS(g_MpTimeLimit60) && nexttime >= TICKS(g_MpTimeLimit60)) {
|
||||
// Match is ending due to time limit reached
|
||||
#ifndef PLATFORM_N64
|
||||
if (g_NetMode != NETMODE_CLIENT)
|
||||
#endif
|
||||
mainEndStage();
|
||||
}
|
||||
|
||||
@@ -2328,6 +2365,12 @@ void lvTick(void)
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef PLATFORM_N64
|
||||
if (g_NetMode == NETMODE_CLIENT) {
|
||||
g_NumReasonsToEndMpMatch = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (g_NumReasonsToEndMpMatch > 0 && numdying == 0) {
|
||||
mainEndStage();
|
||||
}
|
||||
|
||||
+241
-60
@@ -33,6 +33,9 @@
|
||||
#include "lib/str.h"
|
||||
#include "data.h"
|
||||
#include "types.h"
|
||||
#ifndef PLATFORM_N64
|
||||
#include "net/net.h"
|
||||
#endif
|
||||
|
||||
u8 g_InventoryWeapon;
|
||||
|
||||
@@ -41,6 +44,11 @@ struct menudialogdef g_CiControlPlayer2MenuDialog;
|
||||
struct menudialogdef g_CinemaMenuDialog;
|
||||
#ifndef PLATFORM_N64
|
||||
extern struct menudialogdef g_ExtendedMenuDialog;
|
||||
extern struct menudialogdef g_NetMenuDialog;
|
||||
extern MenuItemHandlerResult menuhandlerJoinGame(s32 operation, struct menuitem *item, union handlerdata *data);
|
||||
extern MenuItemHandlerResult menuhandlerJoinStart(s32 operation, struct menuitem *item, union handlerdata *data);
|
||||
extern MenuItemHandlerResult menuhandlerHostGame(s32 operation, struct menuitem *item, union handlerdata *data);
|
||||
extern MenuItemHandlerResult menuhandlerHostStart(s32 operation, struct menuitem *item, union handlerdata *data);
|
||||
#endif
|
||||
|
||||
char *menuTextCurrentStageName(struct menuitem *item)
|
||||
@@ -740,6 +748,7 @@ MenuItemHandlerResult menuhandlerAcceptMission(s32 operation, struct menuitem *i
|
||||
setNumPlayers(1);
|
||||
}
|
||||
} else if (g_MissionConfig.isanti) {
|
||||
#ifdef PLATFORM_N64
|
||||
if (g_Vars.pendingantiplayernum == 1) {
|
||||
g_Vars.bondplayernum = 0;
|
||||
g_Vars.antiplayernum = 1;
|
||||
@@ -749,7 +758,27 @@ MenuItemHandlerResult menuhandlerAcceptMission(s32 operation, struct menuitem *i
|
||||
}
|
||||
|
||||
g_Vars.coopplayernum = -1;
|
||||
|
||||
setNumPlayers(2);
|
||||
#else
|
||||
u32 contmask = joyGetConnectedControllers();
|
||||
u32 plrcount = 0;
|
||||
u32 tmpmask;
|
||||
|
||||
// Count all players
|
||||
tmpmask = contmask;
|
||||
while (tmpmask) {
|
||||
plrcount += (tmpmask & 0x1);
|
||||
tmpmask >>= 1;
|
||||
}
|
||||
|
||||
g_Vars.bondplayernum = g_Vars.pendingantiplayernum ^ 1;
|
||||
g_Vars.antiplayernum = (g_Vars.bondplayernum == 0 ? 1 : 0);
|
||||
g_Vars.coopplayernum = -1;
|
||||
|
||||
setNumPlayers(plrcount);
|
||||
g_MpSetup.chrslots = contmask;
|
||||
#endif
|
||||
} else {
|
||||
// Solo
|
||||
g_Vars.bondplayernum = 0;
|
||||
@@ -1537,6 +1566,8 @@ MenuItemHandlerResult menuhandlerAntiRadar(s32 operation, struct menuitem *item,
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef PLATFORM_N64
|
||||
|
||||
MenuItemHandlerResult menuhandlerAntiPlayer(s32 operation, struct menuitem *item, union handlerdata *data)
|
||||
{
|
||||
const u16 labels[] = {L_OPTIONS_271, L_OPTIONS_272};
|
||||
@@ -1603,6 +1634,100 @@ struct menuitem g_AntiOptionsMenuItems[] = {
|
||||
{ MENUITEMTYPE_END },
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
MenuItemHandlerResult menuhandlerAntiMainPlayer(s32 operation, struct menuitem *item, union handlerdata *data)
|
||||
{
|
||||
static const char *labels[] = {
|
||||
"Player 1",
|
||||
"Player 2",
|
||||
"Player 3",
|
||||
"Player 4",
|
||||
};
|
||||
|
||||
// For consistency with the main save format,
|
||||
// the main player is (pendingantiplayernum XOR 1)
|
||||
|
||||
// g_Vars.(bond|anti|coop)playernum is based on the n'th player slot, not the n'th controller;
|
||||
// that is, it's not based on g_MpSetup.chrslots.
|
||||
// Because of this, it's easier just to change the label.
|
||||
|
||||
u32 tmpmask = joyGetConnectedControllers();
|
||||
u32 plrcount = 0;
|
||||
u32 labelidx = 0;
|
||||
while (tmpmask) {
|
||||
plrcount += (tmpmask & 0x1);
|
||||
if (plrcount <= data->dropdown.value) {
|
||||
labelidx += 1;
|
||||
}
|
||||
tmpmask >>= 1;
|
||||
}
|
||||
|
||||
switch (operation) {
|
||||
case MENUOP_GETOPTIONCOUNT:
|
||||
data->dropdown.value = plrcount;
|
||||
break;
|
||||
case MENUOP_GETOPTIONTEXT:
|
||||
return (s32) (labels[labelidx]);
|
||||
case MENUOP_SET:
|
||||
g_Vars.pendingantiplayernum = data->dropdown.value ^ 1;
|
||||
g_Vars.modifiedfiles |= MODFILE_GAME;
|
||||
break;
|
||||
case MENUOP_GETSELECTEDINDEX:
|
||||
data->dropdown.value = g_Vars.pendingantiplayernum ^ 1;
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct menuitem g_AntiOptionsMenuItems[] = {
|
||||
{
|
||||
MENUITEMTYPE_CHECKBOX,
|
||||
0,
|
||||
0,
|
||||
L_OPTIONS_267, // "Radar On"
|
||||
0,
|
||||
menuhandlerAntiRadar,
|
||||
},
|
||||
{
|
||||
MENUITEMTYPE_DROPDOWN,
|
||||
0,
|
||||
MENUITEMFLAG_LITERAL_TEXT,
|
||||
(uintptr_t)"Main Player",
|
||||
0,
|
||||
menuhandlerAntiMainPlayer,
|
||||
},
|
||||
{
|
||||
MENUITEMTYPE_SEPARATOR,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
NULL,
|
||||
},
|
||||
{
|
||||
MENUITEMTYPE_SELECTABLE,
|
||||
0,
|
||||
0,
|
||||
L_OPTIONS_269, // "Continue"
|
||||
0,
|
||||
menuhandlerBuddyOptionsContinue,
|
||||
},
|
||||
{
|
||||
MENUITEMTYPE_SELECTABLE,
|
||||
0,
|
||||
MENUITEMFLAG_SELECTABLE_CLOSESDIALOG,
|
||||
L_OPTIONS_270, // "Cancel"
|
||||
0,
|
||||
NULL,
|
||||
},
|
||||
{ MENUITEMTYPE_END },
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
struct menudialogdef g_AntiOptionsMenuDialog = {
|
||||
MENUDIALOGTYPE_DEFAULT,
|
||||
L_OPTIONS_266, // "Counter-Operative Options"
|
||||
@@ -1996,7 +2121,7 @@ MenuItemHandlerResult menuhandlerMissionList(s32 operation, struct menuitem *ite
|
||||
texSelect(&gdl, g_TexGeneralConfigs + 13 + stageindex, 2, 0, 2, true, NULL);
|
||||
gDPSetCycleType(gdl++, G_CYC_1CYCLE);
|
||||
gDPSetCombineMode(gdl++, G_CC_CUSTOM_00, G_CC_CUSTOM_00);
|
||||
gDPSetTextureFilter(gdl++, G_TF_AVERAGE);
|
||||
gDPSetTextureFilter(gdl++, G_TF_POINT);
|
||||
gDPSetEnvColorViaWord(gdl++, 0xffffff00 | ((renderdata->colour & 0xff) * 255 / 256));
|
||||
#else
|
||||
texSelect(&gdl, g_TexGeneralConfigs + 13 + stageindex, 1, 0, 2, true, NULL);
|
||||
@@ -2682,7 +2807,7 @@ struct menuitem g_MissionDisplayOptionsMenuItems[] = {
|
||||
0,
|
||||
0,
|
||||
L_OPTIONS_205, // "Sight on Screen"
|
||||
0x00000004,
|
||||
MAX_PLAYERS,
|
||||
menuhandlerSightOnScreen,
|
||||
},
|
||||
{
|
||||
@@ -2690,7 +2815,7 @@ struct menuitem g_MissionDisplayOptionsMenuItems[] = {
|
||||
0,
|
||||
0,
|
||||
L_OPTIONS_206, // "Always Show Target"
|
||||
0x00000004,
|
||||
MAX_PLAYERS,
|
||||
menuhandlerAlwaysShowTarget,
|
||||
},
|
||||
{
|
||||
@@ -2698,7 +2823,7 @@ struct menuitem g_MissionDisplayOptionsMenuItems[] = {
|
||||
0,
|
||||
0,
|
||||
L_OPTIONS_207, // "Show Zoom Range"
|
||||
0x00000004,
|
||||
MAX_PLAYERS,
|
||||
menuhandlerShowZoomRange,
|
||||
},
|
||||
{
|
||||
@@ -2706,7 +2831,7 @@ struct menuitem g_MissionDisplayOptionsMenuItems[] = {
|
||||
0,
|
||||
0,
|
||||
L_OPTIONS_208, // "Ammo on Screen"
|
||||
0x00000004,
|
||||
MAX_PLAYERS,
|
||||
menuhandlerAmmoOnScreen,
|
||||
},
|
||||
{
|
||||
@@ -2714,7 +2839,7 @@ struct menuitem g_MissionDisplayOptionsMenuItems[] = {
|
||||
0,
|
||||
0,
|
||||
L_OPTIONS_209, // "Show Gun Function"
|
||||
0x00000004,
|
||||
MAX_PLAYERS,
|
||||
menuhandlerShowGunFunction,
|
||||
},
|
||||
{
|
||||
@@ -2722,7 +2847,7 @@ struct menuitem g_MissionDisplayOptionsMenuItems[] = {
|
||||
0,
|
||||
0,
|
||||
L_OPTIONS_210, // "Paintball"
|
||||
0x00000004,
|
||||
MAX_PLAYERS,
|
||||
menuhandlerPaintball,
|
||||
},
|
||||
{
|
||||
@@ -2730,7 +2855,7 @@ struct menuitem g_MissionDisplayOptionsMenuItems[] = {
|
||||
0,
|
||||
0,
|
||||
L_MPWEAPONS_169, // "In-Game Subtitles"
|
||||
0x00000004,
|
||||
MAX_PLAYERS,
|
||||
menuhandlerInGameSubtitles,
|
||||
},
|
||||
{
|
||||
@@ -2738,7 +2863,7 @@ struct menuitem g_MissionDisplayOptionsMenuItems[] = {
|
||||
0,
|
||||
0,
|
||||
L_MPWEAPONS_168, // "Cutscene Subtitles"
|
||||
0x00000004,
|
||||
MAX_PLAYERS,
|
||||
menuhandlerCutsceneSubtitles,
|
||||
},
|
||||
{
|
||||
@@ -2746,7 +2871,7 @@ struct menuitem g_MissionDisplayOptionsMenuItems[] = {
|
||||
0,
|
||||
0,
|
||||
L_OPTIONS_212, // "Show Mission Time"
|
||||
0x00000004,
|
||||
MAX_PLAYERS,
|
||||
menuhandlerShowMissionTime,
|
||||
},
|
||||
{
|
||||
@@ -2783,7 +2908,7 @@ struct menuitem g_2PMissionDisplayOptionsVMenuItems[] = {
|
||||
0,
|
||||
0,
|
||||
L_MPWEAPONS_145, // "Sight on Screen"
|
||||
0x00000004,
|
||||
MAX_PLAYERS,
|
||||
menuhandlerSightOnScreen,
|
||||
},
|
||||
{
|
||||
@@ -2791,7 +2916,7 @@ struct menuitem g_2PMissionDisplayOptionsVMenuItems[] = {
|
||||
0,
|
||||
0,
|
||||
L_MPWEAPONS_146, // "Target"
|
||||
0x00000004,
|
||||
MAX_PLAYERS,
|
||||
menuhandlerAlwaysShowTarget,
|
||||
},
|
||||
{
|
||||
@@ -2799,7 +2924,7 @@ struct menuitem g_2PMissionDisplayOptionsVMenuItems[] = {
|
||||
0,
|
||||
0,
|
||||
L_MPWEAPONS_147, // "Zoom Range"
|
||||
0x00000004,
|
||||
MAX_PLAYERS,
|
||||
menuhandlerShowZoomRange,
|
||||
},
|
||||
{
|
||||
@@ -2807,7 +2932,7 @@ struct menuitem g_2PMissionDisplayOptionsVMenuItems[] = {
|
||||
0,
|
||||
0,
|
||||
L_MPWEAPONS_148, // "Show Ammo"
|
||||
0x00000004,
|
||||
MAX_PLAYERS,
|
||||
menuhandlerAmmoOnScreen,
|
||||
},
|
||||
{
|
||||
@@ -2815,7 +2940,7 @@ struct menuitem g_2PMissionDisplayOptionsVMenuItems[] = {
|
||||
0,
|
||||
0,
|
||||
L_MPWEAPONS_149, // "Gun Function"
|
||||
0x00000004,
|
||||
MAX_PLAYERS,
|
||||
menuhandlerShowGunFunction,
|
||||
},
|
||||
{
|
||||
@@ -2823,7 +2948,7 @@ struct menuitem g_2PMissionDisplayOptionsVMenuItems[] = {
|
||||
0,
|
||||
0,
|
||||
L_MPWEAPONS_150, // "Paintball"
|
||||
0x00000004,
|
||||
MAX_PLAYERS,
|
||||
menuhandlerPaintball,
|
||||
},
|
||||
{
|
||||
@@ -2835,7 +2960,7 @@ struct menuitem g_2PMissionDisplayOptionsVMenuItems[] = {
|
||||
#else
|
||||
L_MPWEAPONS_169, // "In-Game Subtitles"
|
||||
#endif
|
||||
0x00000004,
|
||||
MAX_PLAYERS,
|
||||
menuhandlerInGameSubtitles,
|
||||
},
|
||||
{
|
||||
@@ -2847,7 +2972,7 @@ struct menuitem g_2PMissionDisplayOptionsVMenuItems[] = {
|
||||
#else
|
||||
L_MPWEAPONS_168, // "Cutscene Subtitles"
|
||||
#endif
|
||||
0x00000004,
|
||||
MAX_PLAYERS,
|
||||
menuhandlerCutsceneSubtitles,
|
||||
},
|
||||
{
|
||||
@@ -2855,7 +2980,7 @@ struct menuitem g_2PMissionDisplayOptionsVMenuItems[] = {
|
||||
0,
|
||||
0,
|
||||
L_MPWEAPONS_152, // "Mission Time"
|
||||
0x00000004,
|
||||
MAX_PLAYERS,
|
||||
menuhandlerShowMissionTime,
|
||||
},
|
||||
{
|
||||
@@ -2892,7 +3017,7 @@ struct menuitem g_CiDisplayMenuItems[] = {
|
||||
0,
|
||||
0,
|
||||
L_OPTIONS_205, // "Sight on Screen"
|
||||
0x00000004,
|
||||
MAX_PLAYERS,
|
||||
menuhandlerSightOnScreen,
|
||||
},
|
||||
{
|
||||
@@ -2900,7 +3025,7 @@ struct menuitem g_CiDisplayMenuItems[] = {
|
||||
0,
|
||||
0,
|
||||
L_OPTIONS_206, // "Always Show Target"
|
||||
0x00000004,
|
||||
MAX_PLAYERS,
|
||||
menuhandlerAlwaysShowTarget,
|
||||
},
|
||||
{
|
||||
@@ -2908,7 +3033,7 @@ struct menuitem g_CiDisplayMenuItems[] = {
|
||||
0,
|
||||
0,
|
||||
L_OPTIONS_207, // "Show Zoom Range"
|
||||
0x00000004,
|
||||
MAX_PLAYERS,
|
||||
menuhandlerShowZoomRange,
|
||||
},
|
||||
{
|
||||
@@ -2916,7 +3041,7 @@ struct menuitem g_CiDisplayMenuItems[] = {
|
||||
0,
|
||||
0,
|
||||
L_OPTIONS_208, // "Ammo on Screen"
|
||||
0x00000004,
|
||||
MAX_PLAYERS,
|
||||
menuhandlerAmmoOnScreen,
|
||||
},
|
||||
{
|
||||
@@ -2924,7 +3049,7 @@ struct menuitem g_CiDisplayMenuItems[] = {
|
||||
0,
|
||||
0,
|
||||
L_OPTIONS_209, // "Show Gun Function"
|
||||
0x00000004,
|
||||
MAX_PLAYERS,
|
||||
menuhandlerShowGunFunction,
|
||||
},
|
||||
{
|
||||
@@ -2932,7 +3057,7 @@ struct menuitem g_CiDisplayMenuItems[] = {
|
||||
0,
|
||||
0,
|
||||
L_OPTIONS_210, // "Paintball"
|
||||
0x00000004,
|
||||
MAX_PLAYERS,
|
||||
menuhandlerPaintball,
|
||||
},
|
||||
{
|
||||
@@ -2940,7 +3065,7 @@ struct menuitem g_CiDisplayMenuItems[] = {
|
||||
0,
|
||||
0,
|
||||
L_MPWEAPONS_169, // "In-Game Subtitles"
|
||||
0x00000004,
|
||||
MAX_PLAYERS,
|
||||
menuhandlerInGameSubtitles,
|
||||
},
|
||||
{
|
||||
@@ -2948,7 +3073,7 @@ struct menuitem g_CiDisplayMenuItems[] = {
|
||||
0,
|
||||
0,
|
||||
L_MPWEAPONS_168, // "Cutscene Subtitles"
|
||||
0x00000004,
|
||||
MAX_PLAYERS,
|
||||
menuhandlerCutsceneSubtitles,
|
||||
},
|
||||
{
|
||||
@@ -2956,7 +3081,7 @@ struct menuitem g_CiDisplayMenuItems[] = {
|
||||
0,
|
||||
0,
|
||||
L_OPTIONS_212, // "Show Mission Time"
|
||||
0x00000004,
|
||||
MAX_PLAYERS,
|
||||
menuhandlerShowMissionTime,
|
||||
},
|
||||
{
|
||||
@@ -2995,7 +3120,7 @@ struct menuitem g_CiDisplayPlayer2MenuItems[] = {
|
||||
0,
|
||||
0,
|
||||
L_OPTIONS_205, // "Sight on Screen"
|
||||
0x00000005,
|
||||
MAX_PLAYERS + 1,
|
||||
menuhandlerSightOnScreen,
|
||||
},
|
||||
{
|
||||
@@ -3003,7 +3128,7 @@ struct menuitem g_CiDisplayPlayer2MenuItems[] = {
|
||||
0,
|
||||
0,
|
||||
L_OPTIONS_206, // "Always Show Target"
|
||||
0x00000005,
|
||||
MAX_PLAYERS + 1,
|
||||
menuhandlerAlwaysShowTarget,
|
||||
},
|
||||
{
|
||||
@@ -3011,7 +3136,7 @@ struct menuitem g_CiDisplayPlayer2MenuItems[] = {
|
||||
0,
|
||||
0,
|
||||
L_OPTIONS_207, // "Show Zoom Range"
|
||||
0x00000005,
|
||||
MAX_PLAYERS + 1,
|
||||
menuhandlerShowZoomRange,
|
||||
},
|
||||
{
|
||||
@@ -3019,7 +3144,7 @@ struct menuitem g_CiDisplayPlayer2MenuItems[] = {
|
||||
0,
|
||||
0,
|
||||
L_OPTIONS_208, // "Ammo on Screen"
|
||||
0x00000005,
|
||||
MAX_PLAYERS + 1,
|
||||
menuhandlerAmmoOnScreen,
|
||||
},
|
||||
{
|
||||
@@ -3027,7 +3152,7 @@ struct menuitem g_CiDisplayPlayer2MenuItems[] = {
|
||||
0,
|
||||
0,
|
||||
L_OPTIONS_209, // "Show Gun Function"
|
||||
0x00000005,
|
||||
MAX_PLAYERS + 1,
|
||||
menuhandlerShowGunFunction,
|
||||
},
|
||||
{
|
||||
@@ -3035,7 +3160,7 @@ struct menuitem g_CiDisplayPlayer2MenuItems[] = {
|
||||
0,
|
||||
0,
|
||||
L_OPTIONS_210, // "Paintball"
|
||||
0x00000005,
|
||||
MAX_PLAYERS + 1,
|
||||
menuhandlerPaintball,
|
||||
},
|
||||
{
|
||||
@@ -3043,7 +3168,7 @@ struct menuitem g_CiDisplayPlayer2MenuItems[] = {
|
||||
0,
|
||||
0,
|
||||
L_MPWEAPONS_169, // "In-Game Subtitles"
|
||||
0x00000005,
|
||||
MAX_PLAYERS + 1,
|
||||
menuhandlerInGameSubtitles,
|
||||
},
|
||||
{
|
||||
@@ -3051,7 +3176,7 @@ struct menuitem g_CiDisplayPlayer2MenuItems[] = {
|
||||
0,
|
||||
0,
|
||||
L_MPWEAPONS_168, // "Cutscene Subtitles"
|
||||
0x00000005,
|
||||
MAX_PLAYERS + 1,
|
||||
menuhandlerCutsceneSubtitles,
|
||||
},
|
||||
{
|
||||
@@ -3059,7 +3184,7 @@ struct menuitem g_CiDisplayPlayer2MenuItems[] = {
|
||||
0,
|
||||
0,
|
||||
L_OPTIONS_212, // "Show Mission Time"
|
||||
0x00000005,
|
||||
MAX_PLAYERS + 1,
|
||||
menuhandlerShowMissionTime,
|
||||
},
|
||||
{
|
||||
@@ -3104,7 +3229,7 @@ struct menuitem g_MissionControlOptionsMenuItems[] = {
|
||||
0,
|
||||
0,
|
||||
L_OPTIONS_195, // "Reverse Pitch"
|
||||
0x00000004,
|
||||
MAX_PLAYERS,
|
||||
menuhandlerReversePitch,
|
||||
},
|
||||
{
|
||||
@@ -3112,7 +3237,7 @@ struct menuitem g_MissionControlOptionsMenuItems[] = {
|
||||
0,
|
||||
0,
|
||||
L_OPTIONS_196, // "Look Ahead"
|
||||
0x00000004,
|
||||
MAX_PLAYERS,
|
||||
menuhandlerLookAhead,
|
||||
},
|
||||
{
|
||||
@@ -3120,7 +3245,7 @@ struct menuitem g_MissionControlOptionsMenuItems[] = {
|
||||
0,
|
||||
0,
|
||||
L_OPTIONS_197, // "Head Roll"
|
||||
0x00000004,
|
||||
MAX_PLAYERS,
|
||||
menuhandlerHeadRoll,
|
||||
},
|
||||
{
|
||||
@@ -3128,7 +3253,7 @@ struct menuitem g_MissionControlOptionsMenuItems[] = {
|
||||
0,
|
||||
0,
|
||||
L_OPTIONS_198, // "Auto-Aim"
|
||||
0x00000004,
|
||||
MAX_PLAYERS,
|
||||
menuhandlerAutoAim,
|
||||
},
|
||||
{
|
||||
@@ -3136,7 +3261,7 @@ struct menuitem g_MissionControlOptionsMenuItems[] = {
|
||||
0,
|
||||
0,
|
||||
L_OPTIONS_199, // "Aim Control"
|
||||
0x00000004,
|
||||
MAX_PLAYERS,
|
||||
menuhandlerAimControl,
|
||||
},
|
||||
{
|
||||
@@ -3182,7 +3307,7 @@ struct menuitem g_CiControlOptionsMenuItems2[] = {
|
||||
0,
|
||||
0,
|
||||
L_MPWEAPONS_271, // ""
|
||||
0x00000004,
|
||||
MAX_PLAYERS,
|
||||
menuhandlerReversePitch,
|
||||
},
|
||||
{
|
||||
@@ -3190,7 +3315,7 @@ struct menuitem g_CiControlOptionsMenuItems2[] = {
|
||||
0,
|
||||
0,
|
||||
L_MPWEAPONS_272, // ""
|
||||
0x00000004,
|
||||
MAX_PLAYERS,
|
||||
menuhandlerLookAhead,
|
||||
},
|
||||
{
|
||||
@@ -3198,7 +3323,7 @@ struct menuitem g_CiControlOptionsMenuItems2[] = {
|
||||
0,
|
||||
0,
|
||||
L_MPWEAPONS_273, // ""
|
||||
0x00000004,
|
||||
MAX_PLAYERS,
|
||||
menuhandlerHeadRoll,
|
||||
},
|
||||
{
|
||||
@@ -3206,7 +3331,7 @@ struct menuitem g_CiControlOptionsMenuItems2[] = {
|
||||
0,
|
||||
0,
|
||||
L_MPWEAPONS_274, // ""
|
||||
0x00000004,
|
||||
MAX_PLAYERS,
|
||||
menuhandlerAutoAim,
|
||||
},
|
||||
{
|
||||
@@ -3214,7 +3339,7 @@ struct menuitem g_CiControlOptionsMenuItems2[] = {
|
||||
0,
|
||||
0,
|
||||
L_MPWEAPONS_275, // ""
|
||||
0x00000004,
|
||||
MAX_PLAYERS,
|
||||
menuhandlerAimControl,
|
||||
},
|
||||
{
|
||||
@@ -3260,7 +3385,7 @@ struct menuitem g_CiControlOptionsMenuItems[] = {
|
||||
0,
|
||||
0,
|
||||
L_OPTIONS_195, // "Reverse Pitch"
|
||||
0x00000004,
|
||||
MAX_PLAYERS,
|
||||
menuhandlerReversePitch,
|
||||
},
|
||||
{
|
||||
@@ -3268,7 +3393,7 @@ struct menuitem g_CiControlOptionsMenuItems[] = {
|
||||
0,
|
||||
0,
|
||||
L_OPTIONS_196, // "Look Ahead"
|
||||
0x00000004,
|
||||
MAX_PLAYERS,
|
||||
menuhandlerLookAhead,
|
||||
},
|
||||
{
|
||||
@@ -3276,7 +3401,7 @@ struct menuitem g_CiControlOptionsMenuItems[] = {
|
||||
0,
|
||||
0,
|
||||
L_OPTIONS_197, // "Head Roll"
|
||||
0x00000004,
|
||||
MAX_PLAYERS,
|
||||
menuhandlerHeadRoll,
|
||||
},
|
||||
{
|
||||
@@ -3284,7 +3409,7 @@ struct menuitem g_CiControlOptionsMenuItems[] = {
|
||||
0,
|
||||
0,
|
||||
L_OPTIONS_198, // "Auto-Aim"
|
||||
0x00000004,
|
||||
MAX_PLAYERS,
|
||||
menuhandlerAutoAim,
|
||||
},
|
||||
{
|
||||
@@ -3292,7 +3417,7 @@ struct menuitem g_CiControlOptionsMenuItems[] = {
|
||||
0,
|
||||
0,
|
||||
L_OPTIONS_199, // "Aim Control"
|
||||
0x00000004,
|
||||
MAX_PLAYERS,
|
||||
menuhandlerAimControl,
|
||||
},
|
||||
{
|
||||
@@ -3337,7 +3462,7 @@ struct menuitem g_CiControlPlayer2MenuItems[] = {
|
||||
0,
|
||||
0,
|
||||
L_OPTIONS_195, // "Reverse Pitch"
|
||||
0x00000005,
|
||||
MAX_PLAYERS + 1,
|
||||
menuhandlerReversePitch,
|
||||
},
|
||||
{
|
||||
@@ -3345,7 +3470,7 @@ struct menuitem g_CiControlPlayer2MenuItems[] = {
|
||||
0,
|
||||
0,
|
||||
L_OPTIONS_196, // "Look Ahead"
|
||||
0x00000005,
|
||||
MAX_PLAYERS + 1,
|
||||
menuhandlerLookAhead,
|
||||
},
|
||||
{
|
||||
@@ -3353,7 +3478,7 @@ struct menuitem g_CiControlPlayer2MenuItems[] = {
|
||||
0,
|
||||
0,
|
||||
L_OPTIONS_197, // "Head Roll"
|
||||
0x00000005,
|
||||
MAX_PLAYERS + 1,
|
||||
menuhandlerHeadRoll,
|
||||
},
|
||||
{
|
||||
@@ -3361,7 +3486,7 @@ struct menuitem g_CiControlPlayer2MenuItems[] = {
|
||||
0,
|
||||
0,
|
||||
L_OPTIONS_198, // "Auto-Aim"
|
||||
0x00000005,
|
||||
MAX_PLAYERS + 1,
|
||||
menuhandlerAutoAim,
|
||||
},
|
||||
{
|
||||
@@ -3369,7 +3494,7 @@ struct menuitem g_CiControlPlayer2MenuItems[] = {
|
||||
0,
|
||||
0,
|
||||
L_OPTIONS_199, // "Aim Control"
|
||||
0x00000005,
|
||||
MAX_PLAYERS + 1,
|
||||
menuhandlerAimControl,
|
||||
},
|
||||
{
|
||||
@@ -3736,7 +3861,11 @@ struct menudialogdef g_CiOptionsViaPcMenuDialog = {
|
||||
L_OPTIONS_180, // "Options"
|
||||
g_CiOptionsMenuItems,
|
||||
menudialog0010559c,
|
||||
#ifdef PLATFORM_N64
|
||||
0,
|
||||
#else
|
||||
MENUDIALOGFLAG_IGNOREBACK,
|
||||
#endif
|
||||
NULL,
|
||||
};
|
||||
|
||||
@@ -4846,7 +4975,7 @@ MenuItemHandlerResult menuhandlerMainMenuCooperative(s32 operation, struct menui
|
||||
MenuItemHandlerResult menuhandlerMainMenuCounterOperative(s32 operation, struct menuitem *item, union handlerdata *data)
|
||||
{
|
||||
if (operation == MENUOP_CHECKDISABLED) {
|
||||
if ((joyGetConnectedControllers() & 2) == 0) {
|
||||
if ((joyGetConnectedControllers() & ~0x1) == 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -4865,6 +4994,11 @@ MenuDialogHandlerResult menudialogMainMenu(s32 operation, struct menudialogdef *
|
||||
switch (operation) {
|
||||
case MENUOP_OPEN:
|
||||
g_Menus[g_MpPlayerNum].main.unke2c = 0;
|
||||
#ifndef PLATFORM_N64
|
||||
if (g_NetMode) {
|
||||
netDisconnect();
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
case MENUOP_TICK:
|
||||
if (g_Menus[g_MpPlayerNum].curdialog &&
|
||||
@@ -4872,6 +5006,17 @@ MenuDialogHandlerResult menudialogMainMenu(s32 operation, struct menudialogdef *
|
||||
g_MissionConfig.iscoop = false;
|
||||
g_MissionConfig.isanti = false;
|
||||
}
|
||||
#ifndef PLATFORM_N64
|
||||
if (g_NetJoinLatch) {
|
||||
menuhandlerJoinGame(MENUOP_SET, NULL, NULL);
|
||||
menuhandlerJoinStart(MENUOP_SET, NULL, NULL);
|
||||
g_NetJoinLatch = false;
|
||||
} else if (g_NetHostLatch) {
|
||||
menuhandlerHostGame(MENUOP_SET, NULL, NULL);
|
||||
menuhandlerHostStart(MENUOP_SET, NULL, NULL);
|
||||
g_NetHostLatch = false;
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -4905,7 +5050,11 @@ struct menuitem g_MainMenuMenuItems[] = {
|
||||
{
|
||||
MENUITEMTYPE_SELECTABLE,
|
||||
0,
|
||||
#ifdef PLATFORM_N64
|
||||
MENUITEMFLAG_SELECTABLE_CLOSESDIALOG | MENUITEMFLAG_BIGFONT,
|
||||
#else
|
||||
MENUITEMFLAG_SELECTABLE_CLOSESDIALOG | MENUITEMFLAG_BIGFONT | MENUITEMFLAG_ALWAYSDISABLED,
|
||||
#endif
|
||||
L_MISC_446, // "Carrington Institute"
|
||||
0x00000001,
|
||||
NULL,
|
||||
@@ -4913,7 +5062,11 @@ struct menuitem g_MainMenuMenuItems[] = {
|
||||
{
|
||||
MENUITEMTYPE_SELECTABLE,
|
||||
0,
|
||||
#ifdef PLATFORM_N64
|
||||
MENUITEMFLAG_BIGFONT,
|
||||
#else
|
||||
MENUITEMFLAG_BIGFONT | MENUITEMFLAG_ALWAYSDISABLED,
|
||||
#endif
|
||||
(uintptr_t)&mainMenuTextLabel,
|
||||
0x00000002,
|
||||
menuhandlerMainMenuSoloMissions,
|
||||
@@ -4921,7 +5074,11 @@ struct menuitem g_MainMenuMenuItems[] = {
|
||||
{
|
||||
MENUITEMTYPE_SELECTABLE,
|
||||
1,
|
||||
#ifdef PLATFORM_N64
|
||||
MENUITEMFLAG_BIGFONT,
|
||||
#else
|
||||
MENUITEMFLAG_BIGFONT | MENUITEMFLAG_ALWAYSDISABLED,
|
||||
#endif
|
||||
(uintptr_t)&mainMenuTextLabel,
|
||||
0x00000003,
|
||||
menuhandlerMainMenuCombatSimulator,
|
||||
@@ -4929,7 +5086,11 @@ struct menuitem g_MainMenuMenuItems[] = {
|
||||
{
|
||||
MENUITEMTYPE_SELECTABLE,
|
||||
2,
|
||||
#ifdef PLATFORM_N64
|
||||
MENUITEMFLAG_BIGFONT,
|
||||
#else
|
||||
MENUITEMFLAG_BIGFONT | MENUITEMFLAG_ALWAYSDISABLED,
|
||||
#endif
|
||||
(uintptr_t)&mainMenuTextLabel,
|
||||
0x00000004,
|
||||
menuhandlerMainMenuCooperative,
|
||||
@@ -4937,29 +5098,45 @@ struct menuitem g_MainMenuMenuItems[] = {
|
||||
{
|
||||
MENUITEMTYPE_SELECTABLE,
|
||||
3,
|
||||
#ifdef PLATFORM_N64
|
||||
MENUITEMFLAG_BIGFONT,
|
||||
#else
|
||||
MENUITEMFLAG_BIGFONT | MENUITEMFLAG_ALWAYSDISABLED,
|
||||
#endif
|
||||
(uintptr_t)&mainMenuTextLabel,
|
||||
0x00000005,
|
||||
menuhandlerMainMenuCounterOperative,
|
||||
},
|
||||
#ifndef PLATFORM_N64
|
||||
{
|
||||
MENUITEMTYPE_SELECTABLE,
|
||||
4,
|
||||
MENUITEMFLAG_SELECTABLE_OPENSDIALOG | MENUITEMFLAG_BIGFONT | MENUITEMFLAG_LITERAL_TEXT,
|
||||
(uintptr_t)"Network Game",
|
||||
0x00000006,
|
||||
(void *)&g_NetMenuDialog,
|
||||
},
|
||||
#endif
|
||||
{
|
||||
MENUITEMTYPE_SELECTABLE,
|
||||
0,
|
||||
MENUITEMFLAG_SELECTABLE_OPENSDIALOG | MENUITEMFLAG_BIGFONT,
|
||||
L_OPTIONS_187, // "Change Agent..."
|
||||
0x00000006,
|
||||
0x00000007,
|
||||
(void *)&g_ChangeAgentMenuDialog,
|
||||
},
|
||||
/*
|
||||
#ifndef PLATFORM_N64
|
||||
{
|
||||
MENUITEMTYPE_SELECTABLE,
|
||||
0,
|
||||
MENUITEMFLAG_SELECTABLE_OPENSDIALOG | MENUITEMFLAG_BIGFONT | MENUITEMFLAG_LITERAL_TEXT,
|
||||
(uintptr_t)"Exit Game",
|
||||
0x00000007,
|
||||
0x00000008,
|
||||
(void *)&g_ExitGameMenuDialog,
|
||||
},
|
||||
#endif
|
||||
*/
|
||||
{ MENUITEMTYPE_END },
|
||||
};
|
||||
|
||||
@@ -4968,7 +5145,11 @@ struct menudialogdef g_CiMenuViaPcMenuDialog = {
|
||||
L_OPTIONS_116, // "Perfect Menu"
|
||||
g_MainMenuMenuItems,
|
||||
menudialogMainMenu,
|
||||
#ifdef PLATFORM_N64
|
||||
MENUDIALOGFLAG_STARTSELECTS,
|
||||
#else
|
||||
MENUDIALOGFLAG_STARTSELECTS | MENUDIALOGFLAG_IGNOREBACK,
|
||||
#endif
|
||||
&g_CiOptionsViaPcMenuDialog,
|
||||
};
|
||||
|
||||
|
||||
+24
-24
@@ -49,9 +49,10 @@
|
||||
#include "data.h"
|
||||
#include "types.h"
|
||||
#ifndef PLATFORM_N64
|
||||
#include "platform.h"
|
||||
#include "video.h"
|
||||
#include "input.h"
|
||||
#include "platform.h"
|
||||
#include "net/net.h"
|
||||
#define BLUR_OFS 10
|
||||
#else
|
||||
#define BLUR_OFS 30
|
||||
@@ -1928,10 +1929,6 @@ Gfx *menuRenderModel(Gfx *gdl, struct menumodel *menumodel, s32 modeltype)
|
||||
totalfilelen += 0x4000;
|
||||
#endif
|
||||
|
||||
#ifndef PLATFORM_N64
|
||||
videoFreeCachedTextures(menumodel->allocstart, menumodel->allocstart + menumodel->alloclen);
|
||||
#endif
|
||||
|
||||
texInitPool(&texpool, menumodel->allocstart + totalfilelen, menumodel->alloclen - totalfilelen);
|
||||
|
||||
menumodel->headnum = headnum;
|
||||
@@ -1964,10 +1961,6 @@ Gfx *menuRenderModel(Gfx *gdl, struct menumodel *menumodel, s32 modeltype)
|
||||
totalfilelen = ALIGN64(fileGetInflatedSize(menumodel->newparams, LOADTYPE_MODEL)) + 0x4000;
|
||||
if (1);
|
||||
|
||||
#ifndef PLATFORM_N64
|
||||
videoFreeCachedTextures(menumodel->allocstart, menumodel->allocstart + menumodel->alloclen);
|
||||
#endif
|
||||
|
||||
texInitPool(&texpool, &menumodel->allocstart[(u32)totalfilelen], menumodel->alloclen - totalfilelen);
|
||||
|
||||
menumodel->headnum = -1;
|
||||
@@ -3570,7 +3563,7 @@ void menuClose(void)
|
||||
void func0f0f8120(void)
|
||||
{
|
||||
#ifdef AVOID_UB
|
||||
u32 mpindex = g_MpPlayerNum % MAX_PLAYERS;
|
||||
u32 mpindex = g_MpPlayerNum % MAX_LOCAL_PLAYERS;
|
||||
struct menudialog *prev = g_Menus[mpindex].curdialog;
|
||||
s32 i;
|
||||
#else
|
||||
@@ -3585,9 +3578,6 @@ void func0f0f8120(void)
|
||||
}
|
||||
|
||||
#ifdef AVOID_UB
|
||||
mpindex = g_MpPlayerNum;
|
||||
if (mpindex >= MAX_PLAYERS)
|
||||
mpindex -= MAX_PLAYERS;
|
||||
if (g_Menus[mpindex].curdialog == prev) {
|
||||
while (g_Menus[mpindex].depth > 0) {
|
||||
menuPopDialog();
|
||||
@@ -3616,8 +3606,8 @@ void func0f0f820c(struct menudialogdef *dialogdef, s32 root)
|
||||
|
||||
g_MpPlayerNum = prevplayernum;
|
||||
|
||||
g_MenuData.prevmenuroot = root;
|
||||
g_MenuData.prevmenudialog = dialogdef;
|
||||
g_MenuData.unk008 = root;
|
||||
g_MenuData.unk00c = dialogdef;
|
||||
}
|
||||
|
||||
void menuSetBackground(s32 bg)
|
||||
@@ -3691,7 +3681,7 @@ void menuPushRootDialog(struct menudialogdef *dialogdef, s32 root)
|
||||
g_Menus[g_MpPlayerNum].unk820 = 1;
|
||||
|
||||
g_MenuData.root = root;
|
||||
g_MenuData.prevmenuroot = -1;
|
||||
g_MenuData.unk008 = -1;
|
||||
g_MenuData.unk5d5_02 = false;
|
||||
|
||||
if (root == MENUROOT_MAINMENU
|
||||
@@ -4013,13 +4003,13 @@ void menuReset(void)
|
||||
}
|
||||
|
||||
g_MenuData.unk668 = -1;
|
||||
g_MenuData.prevmenudialog = 0;
|
||||
g_MenuData.prevmenuroot = -1;
|
||||
g_MenuData.unk00c = 0;
|
||||
g_MenuData.unk008 = -1;
|
||||
g_MenuData.count = 0;
|
||||
g_MenuData.root = 0;
|
||||
g_MenuData.unk010 = 0;
|
||||
g_MenuData.bg = 0;
|
||||
g_MenuData.isdialogopen = false;
|
||||
g_MenuData.unk5d5_06 = false;
|
||||
g_MenuData.nextbg = 255;
|
||||
g_MenuData.bannernum = -1;
|
||||
|
||||
@@ -4614,9 +4604,6 @@ void dialogTick(struct menudialog *dialog, struct menuinputs *inputs, u32 tickfl
|
||||
s32 adjustment = (s32)(inputs->yaxis * g_Vars.diffframe60freal / 20) - (s32)(inputs->updownheld * g_Vars.diffframe60freal);
|
||||
#else
|
||||
s32 adjustment = inputs->yaxis * g_Vars.diffframe60 / 20 - inputs->updownheld * g_Vars.diffframe60;
|
||||
#endif
|
||||
#ifndef PLATFORM_N64
|
||||
adjustment -= inputs->mousescroll * (LINEHEIGHT + 1);
|
||||
#endif
|
||||
dialog->dstscroll += adjustment;
|
||||
|
||||
@@ -5560,7 +5547,7 @@ Gfx *menuRender(Gfx *gdl)
|
||||
} else {
|
||||
s32 i;
|
||||
|
||||
for (i = 0; i < MAX_PLAYERS; i++) {
|
||||
for (i = 0; i < MAX_LOCAL_PLAYERS; i++) {
|
||||
g_MpPlayerNum = i;
|
||||
gdl = menuRenderDialogs(gdl);
|
||||
}
|
||||
@@ -5593,7 +5580,20 @@ Gfx *menuRender(Gfx *gdl)
|
||||
|
||||
gdl = text0f153628(gdl);
|
||||
|
||||
for (i = 0; i < MAX_PLAYERS; i++) {
|
||||
#ifndef PLATFORM_N64
|
||||
if (g_NetMode) {
|
||||
if (g_NetMode == NETMODE_SERVER) {
|
||||
sprintf(text, "Server: %d/%d %04x", g_NetNumClients, g_NetMaxClients, g_MpSetup.chrslots);
|
||||
} else {
|
||||
sprintf(text, "Client: ID %u", g_NetLocalClient->id);
|
||||
}
|
||||
x = viewleft + 2;
|
||||
y = viewbottom - 9;
|
||||
colour = 0x00ff00ff;
|
||||
gdl = textRenderProjected(gdl, &x, &y, text, g_CharsHandelGothicSm, g_FontHandelGothicSm, colour, viGetWidth(), viGetHeight(), 0, 0);
|
||||
} else
|
||||
#endif
|
||||
for (i = 0; i < MAX_LOCAL_PLAYERS; i++) {
|
||||
// Figure out what text will be displayed. The text calculated
|
||||
// here is for measuring purposes only and isn't rendered.
|
||||
// Amusingly, there's a %d placeholder in the text which isn't
|
||||
|
||||
+16
-30
@@ -24,6 +24,7 @@
|
||||
#include "types.h"
|
||||
#ifndef PLATFORM_N64
|
||||
#include "input.h"
|
||||
#include "console.h"
|
||||
#define MENU_KEYBOARD_ROWS 6
|
||||
#else
|
||||
#define MENU_KEYBOARD_ROWS 5
|
||||
@@ -1334,7 +1335,7 @@ Gfx *menuitemKeyboardRender(Gfx *gdl, struct menurendercontext *context)
|
||||
// make the button yellow if it's active
|
||||
if (g_MenuKeyboardPlayer == g_MpPlayerNum) {
|
||||
textcolour = (textcolour & 0xff) | 0xffff0000;
|
||||
kbtext = (char *)"ESC: OK";
|
||||
kbtext = (char *)"ESC: CANCEL ENTER: OK";
|
||||
} else {
|
||||
kbtext = (char *)"TYPE WITH KEYBOARD";
|
||||
}
|
||||
@@ -1531,14 +1532,6 @@ bool menuitemKeyboardTick(struct menuitem *item, struct menuinputs *inputs, u32
|
||||
|
||||
u8 maxlen = item->param == 0 ? 10 : item->param;
|
||||
#ifndef PLATFORM_N64
|
||||
if (g_MenuKeyboardPlayer != g_MpPlayerNum && inputKeyJustPressed(VK_A + ('i' - 'a'))) {
|
||||
inputClearLastKey();
|
||||
inputClearLastTextChar();
|
||||
g_MenuKeyboardPlayer = g_MpPlayerNum;
|
||||
inputStartTextInput();
|
||||
menuPlaySound(MENUSOUND_SELECT);
|
||||
}
|
||||
|
||||
if (g_MenuKeyboardPlayer == g_MpPlayerNum) {
|
||||
// match caps state to keyboard shift/caps if typing with keyboard
|
||||
const u32 kmod = inputGetKeyModState();
|
||||
@@ -1549,7 +1542,7 @@ bool menuitemKeyboardTick(struct menuitem *item, struct menuinputs *inputs, u32
|
||||
// handle text input
|
||||
s32 prevpos = strlen(kb->string);
|
||||
s32 pos = prevpos;
|
||||
s32 result = inputTextHandler(kb->string, maxlen + 1, &pos, true);
|
||||
s32 result = inputTextHandler(kb->string, maxlen-1, &pos, true);
|
||||
if (result == -1) {
|
||||
// cancel
|
||||
kb->row = 5;
|
||||
@@ -1608,15 +1601,17 @@ bool menuitemKeyboardTick(struct menuitem *item, struct menuinputs *inputs, u32
|
||||
}
|
||||
} else if (kb->row == 5) {
|
||||
#ifndef PLATFORM_N64
|
||||
if (g_MenuKeyboardPlayer == -1) {
|
||||
g_MenuKeyboardPlayer = g_MpPlayerNum;
|
||||
inputClearLastTextChar();
|
||||
inputStartTextInput();
|
||||
menuPlaySound(MENUSOUND_SELECT);
|
||||
} else {
|
||||
g_MenuKeyboardPlayer = -1;
|
||||
inputStopTextInput();
|
||||
menuPlaySound(MENUSOUND_KEYBOARDCANCEL);
|
||||
if (!conIsOpen()) {
|
||||
if (g_MenuKeyboardPlayer == -1) {
|
||||
g_MenuKeyboardPlayer = g_MpPlayerNum;
|
||||
inputClearLastTextChar();
|
||||
inputStartTextInput();
|
||||
menuPlaySound(MENUSOUND_SELECT);
|
||||
} else {
|
||||
g_MenuKeyboardPlayer = -1;
|
||||
inputStopTextInput();
|
||||
menuPlaySound(MENUSOUND_KEYBOARDCANCEL);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
@@ -3228,9 +3223,6 @@ bool menuitemScrollableTick(struct menuitem *item, struct menudialog *dialog, st
|
||||
intval = intval + (s32)(((f32)inputs->updownheld + (f32)inputs->updownheld) * g_Vars.diffframe60freal);
|
||||
#else
|
||||
intval += inputs->updownheld * 2 * g_Vars.diffframe60;
|
||||
#endif
|
||||
#ifndef PLATFORM_N64
|
||||
intval += inputs->mousescroll * (LINEHEIGHT - 2) * 3;
|
||||
#endif
|
||||
data->scrollable.scrolloffset += intval;
|
||||
|
||||
@@ -3754,9 +3746,6 @@ bool menuitemRankingTick(struct menuinputs *inputs, u32 tickflags, union menuite
|
||||
intval = intval + (s32)(((f32)inputs->updownheld + (f32)inputs->updownheld) * g_Vars.diffframe60freal);
|
||||
#else
|
||||
intval += inputs->updownheld * 2 * g_Vars.diffframe60;
|
||||
#endif
|
||||
#ifndef PLATFORM_N64
|
||||
intval += inputs->mousescroll * (LINEHEIGHT - 1);
|
||||
#endif
|
||||
data->ranking.scrolloffset += intval;
|
||||
|
||||
@@ -4052,9 +4041,6 @@ bool menuitemPlayerStatsTick(struct menuitem *item, struct menudialog *dialog, s
|
||||
intval = intval + (s32)(((f32)inputs->updownheld + (f32)inputs->updownheld) * g_Vars.diffframe60freal);
|
||||
#else
|
||||
intval += inputs->updownheld * 2 * g_Vars.diffframe60;
|
||||
#endif
|
||||
#ifndef PLATFORM_N64
|
||||
intval += inputs->mousescroll * (LINEHEIGHT - 1);
|
||||
#endif
|
||||
data->dropdown.scrolloffset += intval;
|
||||
|
||||
@@ -4385,7 +4371,7 @@ Gfx *menuitemControllerRenderText(Gfx *gdl, s32 curmode, struct menurendercontex
|
||||
// during development the second player in the 2.x styles had to
|
||||
// choose their control style separately to player 1, in which case
|
||||
// there would have been 2.5, 2.6, 2.7 and 2.8 for player 2.
|
||||
if (curmode > CONTROLMODE_24 && curmode != CONTROLMODE_PC) {
|
||||
if (curmode > CONTROLMODE_24 && curmode < CONTROLMODE_PC) {
|
||||
if (textnum == menuitemControllerGetButtonAction(prevmode + 4, i)) {
|
||||
colour = labelcolour;
|
||||
}
|
||||
@@ -4470,7 +4456,7 @@ Gfx *menuitemControllerRender(Gfx *gdl, struct menurendercontext *context)
|
||||
data->prevmode = -1;
|
||||
}
|
||||
} else {
|
||||
if (g_Menus[g_MpPlayerNum].main.controlmode >= CONTROLMODE_21 && g_Menus[g_MpPlayerNum].main.controlmode != CONTROLMODE_PC) {
|
||||
if (g_Menus[g_MpPlayerNum].main.controlmode >= CONTROLMODE_21 && g_Menus[g_MpPlayerNum].main.controlmode < CONTROLMODE_PC) {
|
||||
data->controlgroup = 1;
|
||||
data->contfadetimer = 0;
|
||||
data->prevmode = -1;
|
||||
|
||||
+77
-40
@@ -27,6 +27,9 @@
|
||||
#include "lib/snd.h"
|
||||
#include "data.h"
|
||||
#include "types.h"
|
||||
#ifndef PLATFORM_N64
|
||||
#include "net/net.h"
|
||||
#endif
|
||||
|
||||
u8 g_FileState = 0;
|
||||
u8 var80062944 = 0;
|
||||
@@ -59,7 +62,7 @@ void menuTick(void)
|
||||
s32 i;
|
||||
s32 j;
|
||||
s32 k;
|
||||
s32 isdialogopen;
|
||||
s32 sp344;
|
||||
s32 sp340 = true;
|
||||
s32 anyopen = false;
|
||||
|
||||
@@ -218,13 +221,19 @@ void menuTick(void)
|
||||
viBlack(false);
|
||||
g_MpNumJoined = 0;
|
||||
|
||||
#ifndef PLATFORM_N64
|
||||
if (g_NetMode) {
|
||||
g_Vars.mpsetupmenu = MPSETUPMENU_ADVSETUP;
|
||||
g_MpSetup.chrslots = 1;
|
||||
} else
|
||||
#endif
|
||||
if (g_Vars.usingadvsetup) {
|
||||
g_Vars.mpsetupmenu = MPSETUPMENU_ADVSETUP;
|
||||
} else {
|
||||
g_Vars.mpsetupmenu = MPSETUPMENU_GENERAL;
|
||||
}
|
||||
|
||||
for (i = 0; i < MAX_PLAYERS; i++) {
|
||||
for (i = 0; i < MAX_LOCAL_PLAYERS; i++) {
|
||||
g_Vars.waitingtojoin[i] = false;
|
||||
|
||||
if (g_MpSetup.chrslots & (1 << i)) {
|
||||
@@ -233,6 +242,13 @@ void menuTick(void)
|
||||
if (g_Vars.mpsetupmenu == MPSETUPMENU_ADVSETUP) {
|
||||
g_MpNumJoined++;
|
||||
func0f17fcb0(true);
|
||||
#ifndef PLATFORM_N64
|
||||
if (g_NetMode == NETMODE_CLIENT) {
|
||||
// autodump client into waiting screen while host is changing settings
|
||||
extern struct menudialogdef g_NetJoiningDialog;
|
||||
menuPushDialog(&g_NetJoiningDialog);
|
||||
}
|
||||
#endif
|
||||
} else if (g_MpNumJoined == 0) {
|
||||
g_MpNumJoined++;
|
||||
|
||||
@@ -285,14 +301,12 @@ void menuTick(void)
|
||||
var8006294c = 1;
|
||||
|
||||
if (g_MenuData.root == MENUROOT_MPSETUP || g_MenuData.root == MENUROOT_4MBMAINMENU) {
|
||||
if (g_MenuData.prevmenuroot == -1) {
|
||||
#ifndef PLATFORM_N64
|
||||
if (g_MpSetup.storedbotbits) {
|
||||
g_MpSetup.chrslots |= g_MpSetup.storedbotbits;
|
||||
g_MpSetup.storedbotbits = 0;
|
||||
}
|
||||
#endif
|
||||
if (g_MenuData.unk008 == -1) {
|
||||
#if MAX_PLAYERS > 4
|
||||
g_MpSetup.chrslots &= 0xff00;
|
||||
#else
|
||||
g_MpSetup.chrslots &= 0xfff0;
|
||||
#endif
|
||||
}
|
||||
|
||||
g_MpNumJoined = 0;
|
||||
@@ -301,17 +315,29 @@ void menuTick(void)
|
||||
if (g_Menus[i].curdialog) {
|
||||
g_Menus[i].playernum = g_MpNumJoined++;
|
||||
|
||||
if (g_MenuData.prevmenuroot == -1) {
|
||||
if (g_MenuData.unk008 == -1) {
|
||||
g_MpSetup.chrslots |= (1 << i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef PLATFORM_N64
|
||||
if (g_NetMode == NETMODE_SERVER && g_MenuData.unk008 == -1) {
|
||||
s32 slot = 1;
|
||||
for (i = 1; i < g_NetMaxClients; ++i) {
|
||||
if (g_NetClients[i].state >= CLSTATE_LOBBY) {
|
||||
g_MpSetup.chrslots |= (1 << slot);
|
||||
++slot;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
mpCalculateLockIfLastWinnerOrLoser();
|
||||
challengePerformSanityChecks();
|
||||
}
|
||||
|
||||
for (i = 0; i < MAX_PLAYERS; i++) {
|
||||
for (i = 0; i < MAX_LOCAL_PLAYERS; i++) {
|
||||
g_MpPlayerNum = i;
|
||||
|
||||
if (g_Menus[g_MpPlayerNum].curdialog) {
|
||||
@@ -323,7 +349,7 @@ void menuTick(void)
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < MAX_PLAYERS; i++) {
|
||||
for (i = 0; i < MAX_LOCAL_PLAYERS; i++) {
|
||||
g_MpPlayerNum = i;
|
||||
|
||||
if (g_Menus[g_MpPlayerNum].curdialog) {
|
||||
@@ -347,7 +373,7 @@ void menuTick(void)
|
||||
// Limit to 2 players? But in a roundabout kind of way
|
||||
canjoin = true;
|
||||
|
||||
for (j = 0; j < MAX_PLAYERS; j++) {
|
||||
for (j = 0; j < MAX_LOCAL_PLAYERS; j++) {
|
||||
if (g_Vars.waitingtojoin[j]) {
|
||||
canjoin = false;
|
||||
}
|
||||
@@ -361,6 +387,12 @@ void menuTick(void)
|
||||
canjoin = true;
|
||||
}
|
||||
|
||||
#ifndef PLATFORM_N64
|
||||
if (g_NetMode) {
|
||||
canjoin = false;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (g_BossFile.locktype == MPLOCKTYPE_CHALLENGE) {
|
||||
g_PlayerConfigsArray[i].base.team = 0;
|
||||
}
|
||||
@@ -491,31 +523,31 @@ void menuTick(void)
|
||||
}
|
||||
|
||||
g_MpPlayerNum = 0;
|
||||
isdialogopen = false;
|
||||
sp344 = false;
|
||||
|
||||
for (i = 0; i < ARRAYCOUNT(g_Menus); i++) {
|
||||
if (g_Menus[i].curdialog) {
|
||||
isdialogopen = true;
|
||||
sp344 = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ((g_MenuData.isdialogopen || g_MenuData.prevmenuroot != -1) && isdialogopen == false) {
|
||||
if ((g_MenuData.unk5d5_06 || g_MenuData.unk008 != -1) && sp344 == false) {
|
||||
if ((g_MenuData.root == MENUROOT_MPSETUP || g_MenuData.root == MENUROOT_4MBMAINMENU)
|
||||
&& g_MenuData.prevmenuroot == -1) {
|
||||
&& g_MenuData.unk008 == -1) {
|
||||
if (g_Vars.mpsetupmenu == MPSETUPMENU_GENERAL) {
|
||||
g_MenuData.prevmenuroot = MENUROOT_MAINMENU;
|
||||
g_MenuData.prevmenudialog = IS4MB() ? &g_CiMenuViaPauseMenuDialog : &g_CiMenuViaPcMenuDialog;
|
||||
g_MenuData.unk008 = MENUROOT_MAINMENU;
|
||||
g_MenuData.unk00c = IS4MB() ? &g_CiMenuViaPauseMenuDialog : &g_CiMenuViaPcMenuDialog;
|
||||
} else if (IS4MB()) {
|
||||
g_MenuData.prevmenuroot = MENUROOT_4MBMAINMENU;
|
||||
g_MenuData.prevmenudialog = &g_MainMenu4MbMenuDialog;
|
||||
g_MenuData.unk008 = MENUROOT_4MBMAINMENU;
|
||||
g_MenuData.unk00c = &g_MainMenu4MbMenuDialog;
|
||||
} else {
|
||||
g_MenuData.prevmenuroot = MENUROOT_MPSETUP;
|
||||
g_MenuData.prevmenudialog = &g_CombatSimulatorMenuDialog;
|
||||
g_MenuData.unk008 = MENUROOT_MPSETUP;
|
||||
g_MenuData.unk00c = &g_CombatSimulatorMenuDialog;
|
||||
}
|
||||
}
|
||||
|
||||
if (g_MenuData.prevmenuroot != -1) {
|
||||
if (g_MenuData.prevmenuroot == -5) {
|
||||
if (g_MenuData.unk008 != -1) {
|
||||
if (g_MenuData.unk008 == -5) {
|
||||
// Match is beginning
|
||||
mpStartMatch();
|
||||
menuStop();
|
||||
@@ -524,7 +556,7 @@ void menuTick(void)
|
||||
bossfileSave();
|
||||
g_Vars.modifiedfiles &= ~MODFILE_MPSETUP;
|
||||
}
|
||||
} else if (g_MenuData.prevmenuroot == -6) {
|
||||
} else if (g_MenuData.unk008 == -6) {
|
||||
// Match is ending
|
||||
s32 playernum = 0;
|
||||
|
||||
@@ -532,7 +564,12 @@ void menuTick(void)
|
||||
func0f0fd548(4);
|
||||
}
|
||||
|
||||
for (i = 0; i < MAX_PLAYERS; i++) {
|
||||
#ifdef PLATFORM_N64
|
||||
for (i = 0; i < MAX_LOCAL_PLAYERS; i++) {
|
||||
#else
|
||||
const s32 maxplayers = g_NetMode ? 1 : MAX_LOCAL_PLAYERS;
|
||||
for (i = 0; i < maxplayers; i++) {
|
||||
#endif
|
||||
if (g_MpSetup.chrslots & (1 << i)) {
|
||||
if (g_Vars.coopplayernum >= 0) {
|
||||
if (g_Vars.stagenum == STAGE_DEEPSEA) {
|
||||
@@ -547,17 +584,17 @@ void menuTick(void)
|
||||
setCurrentPlayerNum(playernum);
|
||||
endscreenPushCoop();
|
||||
setCurrentPlayerNum(prevplayernum);
|
||||
isdialogopen = true;
|
||||
sp344 = true;
|
||||
}
|
||||
} else if (g_Vars.antiplayernum >= 0) {
|
||||
s32 prevplayernum = g_Vars.currentplayernum;
|
||||
setCurrentPlayerNum(playernum);
|
||||
endscreenPushAnti();
|
||||
setCurrentPlayerNum(prevplayernum);
|
||||
isdialogopen = true;
|
||||
sp344 = true;
|
||||
} else {
|
||||
mpPushEndscreenDialog(playernum, i);
|
||||
isdialogopen = true;
|
||||
sp344 = true;
|
||||
|
||||
if (g_PlayerConfigsArray[i].fileguid.fileid && g_PlayerConfigsArray[i].fileguid.deviceserial) {
|
||||
func0f0fd548(i);
|
||||
@@ -567,7 +604,7 @@ void menuTick(void)
|
||||
playernum++;
|
||||
}
|
||||
}
|
||||
} else if (g_MenuData.prevmenuroot == -7) {
|
||||
} else if (g_MenuData.unk008 == -7) {
|
||||
menuStop();
|
||||
g_FileState = FILESTATE_CHANGINGAGENT;
|
||||
gamefileLoadDefaults(&g_GameFile);
|
||||
@@ -576,8 +613,8 @@ void menuTick(void)
|
||||
musicQueueStopAllEvent();
|
||||
} else {
|
||||
bool startmusic = false;
|
||||
menuPushRootDialog(g_MenuData.prevmenudialog, g_MenuData.prevmenuroot);
|
||||
isdialogopen = true;
|
||||
menuPushRootDialog(g_MenuData.unk00c, g_MenuData.unk008);
|
||||
sp344 = true;
|
||||
|
||||
if (g_MenuData.root == MENUROOT_MPSETUP || g_MenuData.root == MENUROOT_4MBMAINMENU) {
|
||||
startmusic = true;
|
||||
@@ -603,8 +640,8 @@ void menuTick(void)
|
||||
}
|
||||
}
|
||||
|
||||
g_MenuData.prevmenudialog = NULL;
|
||||
g_MenuData.prevmenuroot = -1;
|
||||
g_MenuData.unk00c = NULL;
|
||||
g_MenuData.unk008 = -1;
|
||||
} else {
|
||||
switch (g_MenuData.root) {
|
||||
case MENUROOT_ENDSCREEN:
|
||||
@@ -622,12 +659,12 @@ void menuTick(void)
|
||||
} else if (g_Vars.coopplayernum >= 0 || g_Vars.antiplayernum >= 0) {
|
||||
struct mpplayerconfig tmp;
|
||||
|
||||
tmp = g_PlayerConfigsArray[4];
|
||||
g_PlayerConfigsArray[4] = g_PlayerConfigsArray[0];
|
||||
tmp = g_PlayerConfigsArray[MAX_PLAYERS];
|
||||
g_PlayerConfigsArray[MAX_PLAYERS] = g_PlayerConfigsArray[0];
|
||||
g_PlayerConfigsArray[0] = tmp;
|
||||
|
||||
tmp = g_PlayerConfigsArray[5];
|
||||
g_PlayerConfigsArray[5] = g_PlayerConfigsArray[1];
|
||||
tmp = g_PlayerConfigsArray[MAX_PLAYERS + 1];
|
||||
g_PlayerConfigsArray[MAX_PLAYERS + 1] = g_PlayerConfigsArray[1];
|
||||
g_PlayerConfigsArray[1] = tmp;
|
||||
}
|
||||
|
||||
@@ -756,5 +793,5 @@ void menuTick(void)
|
||||
}
|
||||
|
||||
g_ScaleX = 1;
|
||||
g_MenuData.isdialogopen = isdialogopen ? true : false;
|
||||
g_MenuData.unk5d5_06 = sp344 ? true : false;
|
||||
}
|
||||
@@ -19,6 +19,9 @@
|
||||
#include "lib/main.h"
|
||||
#include "data.h"
|
||||
#include "types.h"
|
||||
#ifndef PLATFORM_N64
|
||||
#include "net/net.h"
|
||||
#endif
|
||||
|
||||
struct menudialogdef g_MpEndscreenChallengeCompletedMenuDialog;
|
||||
struct menudialogdef g_MpEndscreenIndGameOverMenuDialog;
|
||||
@@ -102,6 +105,11 @@ MenuItemHandlerResult menuhandlerMpEndGame(s32 operation, struct menuitem *item,
|
||||
{
|
||||
if (operation == MENUOP_SET) {
|
||||
g_Vars.currentplayer->aborted = true;
|
||||
#ifndef PLATFORM_N64
|
||||
if (g_NetMode == NETMODE_CLIENT) {
|
||||
netDisconnect();
|
||||
} else
|
||||
#endif
|
||||
mainEndStage();
|
||||
}
|
||||
|
||||
@@ -165,6 +173,11 @@ MenuItemHandlerResult menuhandlerMpPause(s32 operation, struct menuitem *item, u
|
||||
}
|
||||
|
||||
if (operation == MENUOP_CHECKHIDDEN) {
|
||||
#ifndef PLATFORM_N64
|
||||
if (g_NetMode) {
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
if (PLAYERCOUNT() == 1) {
|
||||
return true;
|
||||
}
|
||||
@@ -787,7 +800,11 @@ void mpPushPauseDialog(void)
|
||||
menuPushRootDialog(&g_MpPausePlayerRankingMenuDialog, MENUROOT_MPPAUSE);
|
||||
}
|
||||
} else {
|
||||
if (optionsGetScreenSplit() == SCREENSPLIT_VERTICAL) {
|
||||
if (optionsGetScreenSplit() == SCREENSPLIT_VERTICAL
|
||||
#ifndef PLATFORM_N64
|
||||
|| LOCALPLAYERCOUNT() >= 3
|
||||
#endif
|
||||
) {
|
||||
menuPushRootDialog(&g_2PMissionPauseVMenuDialog, MENUROOT_MPPAUSE);
|
||||
} else {
|
||||
menuPushRootDialog(&g_2PMissionPauseHMenuDialog, MENUROOT_MPPAUSE);
|
||||
@@ -831,6 +848,9 @@ void mpPushEndscreenDialog(u32 arg0, u32 playernum)
|
||||
&& g_PlayerConfigsArray[g_MpPlayerNum].fileguid.fileid == 0
|
||||
&& g_PlayerConfigsArray[g_MpPlayerNum].fileguid.deviceserial == 0) {
|
||||
g_PlayerConfigsArray[g_MpPlayerNum].options |= OPTION_ASKEDSAVEPLAYER;
|
||||
#ifndef PLATFORM_N64
|
||||
if (!g_NetMode)
|
||||
#endif
|
||||
menuPushDialog(&g_MpEndscreenSavePlayerMenuDialog);
|
||||
}
|
||||
}
|
||||
|
||||
+94
-51
@@ -28,9 +28,12 @@
|
||||
#include "lib/lib_317f0.h"
|
||||
#include "data.h"
|
||||
#include "types.h"
|
||||
#ifndef PLATFORM_N64
|
||||
#include "net/net.h"
|
||||
#include "fs.h"
|
||||
#include "system.h"
|
||||
#include "mpsetups.h"
|
||||
#endif
|
||||
|
||||
// bss
|
||||
struct chrdata *g_MpAllChrPtrs[MAX_MPCHRS];
|
||||
@@ -38,7 +41,7 @@ struct mpchrconfig *g_MpAllChrConfigPtrs[MAX_MPCHRS];
|
||||
s32 g_MpNumChrs;
|
||||
u32 var800ac534;
|
||||
struct mpbotconfig g_BotConfigsArray[MAX_BOTS];
|
||||
u8 g_MpSimulantDifficultiesPerNumPlayers[MAX_BOTS][MAX_PLAYERS];
|
||||
u8 g_MpSimulantDifficultiesPerNumPlayers[MAX_BOTS][MAX_LOCAL_PLAYERS];
|
||||
struct mpplayerconfig g_PlayerConfigsArray[MAX_MPPLAYERCONFIGS];
|
||||
u8 g_AmBotCommands[9];
|
||||
struct mpsetup g_MpSetup;
|
||||
@@ -139,12 +142,11 @@ struct mpweapon g_MpWeapons[NUM_MPWEAPONS] = {
|
||||
.extcontrols = true, \
|
||||
.crosshaircolour = 0x00ff0028, \
|
||||
.crosshairsize = 2, \
|
||||
.crosshairedgeboundary = 0.7f, \
|
||||
.crosshairhealth = CROSSHAIR_HEALTH_OFF, \
|
||||
.usereloads = false, \
|
||||
}
|
||||
|
||||
struct extplayerconfig g_PlayerExtCfg[MAX_PLAYERS] = {
|
||||
struct extplayerconfig g_PlayerExtCfg[MAX_LOCAL_PLAYERS] = {
|
||||
PLAYER_EXT_CFG_DEFAULT,
|
||||
PLAYER_EXT_CFG_DEFAULT,
|
||||
PLAYER_EXT_CFG_DEFAULT,
|
||||
@@ -159,11 +161,18 @@ struct extplayerconfig g_PlayerExtCfg[MAX_PLAYERS] = {
|
||||
* value 0 will return 0.1
|
||||
* value 127 will return 1
|
||||
* value 255 will return 10
|
||||
* in a netgame it's always 1
|
||||
*/
|
||||
f32 mpHandicapToDamageScale(u8 value)
|
||||
{
|
||||
f32 tmp;
|
||||
|
||||
#ifndef PLATFORM_N64
|
||||
if (g_NetMode) {
|
||||
return 1.f;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (value < 127) {
|
||||
return (value / 127.0f) * (value / 127.0f) * 0.9f + 0.1f;
|
||||
}
|
||||
@@ -197,22 +206,38 @@ void mpStartMatch(void)
|
||||
s32 stagenum;
|
||||
|
||||
#ifndef PLATFORM_N64
|
||||
if (g_MpSetup.options & MPOPTION_AUTORANDOMWEAPON_START) {
|
||||
if (g_MpWeaponSetNum == WEAPONSET_RANDOM
|
||||
|| g_MpWeaponSetNum == WEAPONSET_RANDOMFIVE) {
|
||||
mpApplyWeaponSet();
|
||||
if (g_NetMode == NETMODE_SERVER) {
|
||||
g_MpSetup.chrslots &= 0xff00;
|
||||
g_MpSetup.chrslots |= 1;
|
||||
s32 slot = 1;
|
||||
for (s32 i = 1; i < g_NetMaxClients; ++i) {
|
||||
if (g_NetClients[i].state >= CLSTATE_LOBBY) {
|
||||
g_MpSetup.chrslots |= (1 << slot);
|
||||
++slot;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (g_NetMode != NETMODE_CLIENT)
|
||||
#endif
|
||||
{
|
||||
#ifndef PLATFORM_N64
|
||||
if (g_MpSetup.options & MPOPTION_AUTORANDOMWEAPON_START) {
|
||||
if (g_MpWeaponSetNum == WEAPONSET_RANDOM || g_MpWeaponSetNum == WEAPONSET_RANDOMFIVE) {
|
||||
mpApplyWeaponSet();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
mpConfigureQuickTeamSimulants();
|
||||
mpConfigureQuickTeamSimulants();
|
||||
|
||||
if (!challengeIsFeatureUnlocked(MPFEATURE_ONEHITKILLS)) {
|
||||
g_MpSetup.options &= ~MPOPTION_ONEHITKILLS;
|
||||
}
|
||||
if (!challengeIsFeatureUnlocked(MPFEATURE_ONEHITKILLS)) {
|
||||
g_MpSetup.options &= ~MPOPTION_ONEHITKILLS;
|
||||
}
|
||||
|
||||
if (!challengeIsFeatureUnlocked(MPFEATURE_SLOWMOTION)) {
|
||||
g_MpSetup.options &= ~(MPOPTION_SLOWMOTION_ON | MPOPTION_SLOWMOTION_SMART);
|
||||
if (!challengeIsFeatureUnlocked(MPFEATURE_SLOWMOTION)) {
|
||||
g_MpSetup.options &= ~(MPOPTION_SLOWMOTION_ON | MPOPTION_SLOWMOTION_SMART);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < MAX_PLAYERS; i++) {
|
||||
@@ -255,7 +280,15 @@ void mpReset(void)
|
||||
g_Vars.lvmpbotlevel = true;
|
||||
}
|
||||
|
||||
if (g_Vars.coopplayernum >= 0 || g_Vars.antiplayernum >= 0) {
|
||||
#ifdef PLATFORM_N64
|
||||
if (g_Vars.coopplayernum >= 0 || g_Vars.antiplayernum >= 0)
|
||||
#else
|
||||
// Counter-Operative now uses a different approach which allows more than 2 players.
|
||||
// Co-Operative, on the other hand, is currently limited to 2 players.
|
||||
// Due to the change in approach, it's better to ignore 2.x controls for Counter-Operative.
|
||||
if (g_Vars.coopplayernum >= 0)
|
||||
#endif
|
||||
{
|
||||
struct mpplayerconfig tmp;
|
||||
|
||||
tmp = g_PlayerConfigsArray[MAX_PLAYERS];
|
||||
@@ -438,7 +471,7 @@ void mpPlayerSetDefaults(s32 playernum, bool autonames)
|
||||
g_PlayerConfigsArray[playernum].controlmode = CONTROLMODE_11;
|
||||
|
||||
#ifndef PLATFORM_N64
|
||||
if (g_PlayerExtCfg[playernum % MAX_PLAYERS].extcontrols) {
|
||||
if (g_PlayerExtCfg[playernum % MAX_LOCAL_PLAYERS].extcontrols) {
|
||||
g_PlayerConfigsArray[playernum].controlmode = CONTROLMODE_PC;
|
||||
}
|
||||
#endif
|
||||
@@ -506,9 +539,9 @@ void mpPlayerSetDefaults(s32 playernum, bool autonames)
|
||||
g_PlayerConfigsArray[playernum].survivormedals = 0;
|
||||
g_PlayerConfigsArray[playernum].title = MPPLAYERTITLE_BEGINNER;
|
||||
|
||||
if (playernum < MAX_PLAYERS) {
|
||||
if (playernum < MAX_LOCAL_PLAYERS) {
|
||||
for (i = 0; i < ARRAYCOUNT(g_MpChallenges); i++) {
|
||||
for (j = 1; j <= MAX_PLAYERS; j++) {
|
||||
for (j = 1; j <= MAX_LOCAL_PLAYERS; j++) {
|
||||
challengeSetCompletedByPlayerWithNumPlayers(playernum, i, j, false);
|
||||
}
|
||||
}
|
||||
@@ -601,7 +634,7 @@ void mpInit(bool resetplayers)
|
||||
g_MpSetup.chrslots = 0;
|
||||
|
||||
for (i = 0; i < ARRAYCOUNT(g_Menus); i++) {
|
||||
g_Menus[i].mpsetupext.showpresets = 1;
|
||||
g_Menus[i].mpsetup.showpresets = 1;
|
||||
}
|
||||
|
||||
#ifndef PLATFORM_N64
|
||||
@@ -1392,7 +1425,7 @@ Gfx *mpRenderModalText(Gfx *gdl)
|
||||
&& g_Vars.currentplayer->redbloodfinished
|
||||
&& g_Vars.currentplayer->deathanimfinished
|
||||
&& !(g_Vars.coopplayernum >= 0 && ((g_Vars.bond->isdead && g_Vars.coop->isdead) || !g_Vars.currentplayer->coopcanrestart || g_InCutscene))
|
||||
&& !(g_Vars.antiplayernum >= 0 && ((g_Vars.currentplayer != g_Vars.anti || g_InCutscene)))
|
||||
&& !(g_Vars.antiplayernum >= 0 && ((PLAYER_IS_NOT_ANTI(g_Vars.currentplayer) || g_InCutscene)))
|
||||
&& g_NumReasonsToEndMpMatch == 0) {
|
||||
// Render "Press START" text
|
||||
gdl = text0f153628(gdl);
|
||||
@@ -2540,10 +2573,12 @@ void mpEndMatch(void)
|
||||
}
|
||||
|
||||
#ifndef PLATFORM_N64
|
||||
if (g_MpSetup.options & MPOPTION_AUTORANDOMWEAPON_END) {
|
||||
if (g_MpWeaponSetNum == WEAPONSET_RANDOM
|
||||
|| g_MpWeaponSetNum == WEAPONSET_RANDOMFIVE) {
|
||||
mpApplyWeaponSet();
|
||||
if (g_NetMode != NETMODE_CLIENT) {
|
||||
if (g_MpSetup.options & MPOPTION_AUTORANDOMWEAPON_END) {
|
||||
if (g_MpWeaponSetNum == WEAPONSET_RANDOM
|
||||
|| g_MpWeaponSetNum == WEAPONSET_RANDOMFIVE) {
|
||||
mpApplyWeaponSet();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -2705,10 +2740,10 @@ void mpFindUnusedHeadAndBody(u8 *mpheadnum, u8 *mpbodynum)
|
||||
|
||||
s32 mpChooseRandomLockPlayer(void)
|
||||
{
|
||||
s32 start = rngRandom() % 4;
|
||||
s32 start = rngRandom() % MAX_PLAYERS;
|
||||
s32 i;
|
||||
|
||||
for (i = (start + 1) % 4;; i = (i + 1) % 4) {
|
||||
for (i = (start + 1) % MAX_PLAYERS;; i = (i + 1) % MAX_PLAYERS) {
|
||||
if ((g_MpSetup.chrslots & (1 << i)) || i == start) {
|
||||
break;
|
||||
}
|
||||
@@ -3152,11 +3187,11 @@ void mpCreateBotFromProfile(s32 botnum, u8 profilenum)
|
||||
g_BotConfigsArray[botnum].type = g_BotProfiles[profilenum].type;
|
||||
g_BotConfigsArray[botnum].difficulty = g_BotProfiles[profilenum].difficulty;
|
||||
|
||||
for (i = 0; i < MAX_PLAYERS; i++) {
|
||||
for (i = 0; i < MAX_LOCAL_PLAYERS; i++) {
|
||||
g_MpSimulantDifficultiesPerNumPlayers[botnum][i] = g_BotConfigsArray[botnum].difficulty;
|
||||
}
|
||||
|
||||
g_MpSetup.chrslots |= 1 << (botnum + 4);
|
||||
g_MpSetup.chrslots |= 1 << (botnum + MAX_PLAYERS);
|
||||
strcpy(g_BotConfigsArray[botnum].base.name, "Sim\n");
|
||||
g_BotConfigsArray[botnum].base.team = team;
|
||||
|
||||
@@ -3185,7 +3220,7 @@ void mpSetBotDifficulty(s32 botnum, s32 difficulty)
|
||||
|
||||
g_BotConfigsArray[botnum].difficulty = difficulty;
|
||||
|
||||
for (i = 0; i < MAX_PLAYERS; i++) {
|
||||
for (i = 0; i < MAX_LOCAL_PLAYERS; i++) {
|
||||
g_MpSimulantDifficultiesPerNumPlayers[botnum][i] = g_BotConfigsArray[botnum].difficulty;
|
||||
}
|
||||
}
|
||||
@@ -3199,7 +3234,7 @@ s32 mpGetSlotForNewBot(void)
|
||||
{
|
||||
s32 i = 0;
|
||||
|
||||
while (i < MAX_BOTS - 1 && g_MpSetup.chrslots & (1 << (i + 4))) {
|
||||
while (i < MAX_BOTS - 1 && g_MpSetup.chrslots & (1 << (i + MAX_PLAYERS))) {
|
||||
i++;
|
||||
}
|
||||
|
||||
@@ -3208,7 +3243,7 @@ s32 mpGetSlotForNewBot(void)
|
||||
|
||||
void mpRemoveSimulant(s32 index)
|
||||
{
|
||||
g_MpSetup.chrslots &= ~(1 << (index + 4));
|
||||
g_MpSetup.chrslots &= ~(1 << (index + MAX_PLAYERS));
|
||||
g_BotConfigsArray[index].base.name[0] = '\0';
|
||||
func0f1881d4(index);
|
||||
mpGenerateBotNames();
|
||||
@@ -3231,7 +3266,11 @@ void mpCopySimulant(s32 index)
|
||||
|
||||
bool mpHasSimulants(void)
|
||||
{
|
||||
#if MAX_PLAYERS > 4
|
||||
if ((g_MpSetup.chrslots & 0xff00) != 0) {
|
||||
#else
|
||||
if ((g_MpSetup.chrslots & 0xfff0) != 0) {
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -3243,7 +3282,7 @@ bool mpHasUnusedBotSlots(void)
|
||||
s32 numvacant = challengeIsFeatureUnlocked(MPFEATURE_8BOTS) ? MAX_BOTS : 4;
|
||||
s32 i;
|
||||
|
||||
for (i = 4; i < MAX_MPCHRS; i++) {
|
||||
for (i = MAX_PLAYERS; i < MAX_MPCHRS; i++) {
|
||||
if (g_MpSetup.chrslots & (1 << i)) {
|
||||
numvacant--;
|
||||
}
|
||||
@@ -3261,9 +3300,9 @@ bool mpIsSimSlotEnabled(s32 slot)
|
||||
s32 numfree = MAX_BOTS;
|
||||
s32 i;
|
||||
|
||||
if ((g_MpSetup.chrslots & (1 << (slot + 4))) == 0) {
|
||||
if ((g_MpSetup.chrslots & (1 << (slot + MAX_PLAYERS))) == 0) {
|
||||
for (i = 0; i < MAX_BOTS; i++) {
|
||||
if (g_MpSetup.chrslots & (1 << (i + 4))) {
|
||||
if (g_MpSetup.chrslots & (1 << (i + MAX_PLAYERS))) {
|
||||
numfree--;
|
||||
}
|
||||
}
|
||||
@@ -3315,9 +3354,9 @@ void mpGenerateBotNames(void)
|
||||
}
|
||||
|
||||
// Count the number of bots using each profile (MeatSim, TurtleSim etc)
|
||||
for (i = 4; i < MAX_MPCHRS; i++) {
|
||||
for (i = MAX_PLAYERS; i < MAX_MPCHRS; i++) {
|
||||
if (g_MpSetup.chrslots & (1 << i)) {
|
||||
profilenum = mpFindBotProfile(g_BotConfigsArray[i - 4].type, g_BotConfigsArray[i - 4].difficulty);
|
||||
profilenum = mpFindBotProfile(g_BotConfigsArray[i - MAX_PLAYERS].type, g_BotConfigsArray[i - MAX_PLAYERS].difficulty);
|
||||
|
||||
if (profilenum >= 0 && profilenum < ARRAYCOUNT(g_BotProfiles)) {
|
||||
counts[profilenum]++;
|
||||
@@ -3336,20 +3375,20 @@ void mpGenerateBotNames(void)
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 4; i < MAX_MPCHRS; i++) {
|
||||
for (i = MAX_PLAYERS; i < MAX_MPCHRS; i++) {
|
||||
if (g_MpSetup.chrslots & (1 << i)) {
|
||||
profilenum = mpFindBotProfile(g_BotConfigsArray[i - 4].type, g_BotConfigsArray[i - 4].difficulty);
|
||||
profilenum = mpFindBotProfile(g_BotConfigsArray[i - MAX_PLAYERS].type, g_BotConfigsArray[i - MAX_PLAYERS].difficulty);
|
||||
|
||||
if (profilenum >= 0 && profilenum < ARRAYCOUNT(g_BotProfiles)) {
|
||||
if (counts[profilenum] >= 0) {
|
||||
// Multiple bots using this profile - append the number
|
||||
counts[profilenum]++;
|
||||
sprintf(name, "%s:%d\n", langGet(g_BotProfiles[profilenum].name), counts[profilenum]);
|
||||
strcpy(g_BotConfigsArray[i - 4].base.name, name);
|
||||
strcpy(g_BotConfigsArray[i - MAX_PLAYERS].base.name, name);
|
||||
} else {
|
||||
// One bots using this profile - just use the profile name
|
||||
sprintf(name, "%s\n", langGet(g_BotProfiles[profilenum].name));
|
||||
strcpy(g_BotConfigsArray[i - 4].base.name, name);
|
||||
strcpy(g_BotConfigsArray[i - MAX_PLAYERS].base.name, name);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3398,7 +3437,7 @@ s32 func0f18d074(s32 index)
|
||||
|
||||
for (i = 0; i < MAX_BOTS; i++) {
|
||||
if (&g_BotConfigsArray[i].base == g_MpAllChrConfigPtrs[index]) {
|
||||
return i + 4;
|
||||
return i + MAX_PLAYERS;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3520,13 +3559,13 @@ void mpplayerfileLoadWad(s32 playernum, struct savebuffer *buffer, s32 arg2)
|
||||
|
||||
#ifndef PLATFORM_N64
|
||||
// override with PC controls if enabled in the config
|
||||
if (g_PlayerExtCfg[playernum % MAX_PLAYERS].extcontrols) {
|
||||
if (g_PlayerExtCfg[playernum % MAX_LOCAL_PLAYERS].extcontrols) {
|
||||
g_PlayerConfigsArray[playernum].controlmode = CONTROLMODE_PC;
|
||||
}
|
||||
#endif
|
||||
|
||||
for (i = 0; i < ARRAYCOUNT(g_MpChallenges); i++) {
|
||||
for (j = 1; j < MAX_PLAYERS + 1; j++) {
|
||||
for (j = 1; j < MAX_LOCAL_PLAYERS + 1; j++) {
|
||||
challengeSetCompletedByPlayerWithNumPlayers(playernum, i, j, savebufferReadBits(buffer, 1));
|
||||
}
|
||||
}
|
||||
@@ -3666,7 +3705,7 @@ void mpplayerfileSaveWad(s32 playernum, struct savebuffer *buffer)
|
||||
savebufferOr(buffer, g_PlayerConfigsArray[playernum].options, 12);
|
||||
|
||||
for (i = 0; i < ARRAYCOUNT(g_MpChallenges); i++) {
|
||||
for (j = 1; j < MAX_PLAYERS + 1; j++) {
|
||||
for (j = 1; j < MAX_LOCAL_PLAYERS + 1; j++) {
|
||||
savebufferOr(buffer, challengeIsCompletedByPlayerWithNumPlayers(playernum, i, j), 1);
|
||||
}
|
||||
}
|
||||
@@ -3851,7 +3890,7 @@ void mpApplyConfig(struct mpconfigfull *config)
|
||||
for (i = 0; i < MAX_BOTS; i++) {
|
||||
g_BotConfigsArray[i].type = config->config.simulants[i].type;
|
||||
|
||||
for (j = 0; j < MAX_PLAYERS; j++) {
|
||||
for (j = 0; j < MAX_LOCAL_PLAYERS; j++) {
|
||||
g_MpSimulantDifficultiesPerNumPlayers[i][j] = config->config.simulants[i].difficulties[j];
|
||||
}
|
||||
|
||||
@@ -3908,11 +3947,15 @@ void mp0f18dec4(s32 slot)
|
||||
mpApplyConfig(config);
|
||||
|
||||
#if VERSION >= VERSION_JPN_FINAL
|
||||
#if MAX_PLAYERS > 4
|
||||
g_MpSetup.chrslots &= 0xff;
|
||||
#else
|
||||
g_MpSetup.chrslots &= 0x0f;
|
||||
#endif
|
||||
|
||||
for (i = 0; i < MAX_BOTS; i++) {
|
||||
if (g_BotConfigsArray[i].difficulty != BOTDIFF_DISABLED) {
|
||||
g_MpSetup.chrslots |= 1 << (i + 4);
|
||||
g_MpSetup.chrslots |= 1 << (i + MAX_PLAYERS);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -3973,12 +4016,12 @@ void mpsetupfileLoadWad(struct savebuffer *buffer, u8 version)
|
||||
g_BotConfigsArray[i].type = savebufferReadBits(buffer, 5);
|
||||
g_BotConfigsArray[i].difficulty = savebufferReadBits(buffer, 3);
|
||||
|
||||
for (j = 0; j < MAX_PLAYERS; j++) {
|
||||
for (j = 0; j < MAX_LOCAL_PLAYERS; j++) {
|
||||
g_MpSimulantDifficultiesPerNumPlayers[i][j] = g_BotConfigsArray[i].difficulty;
|
||||
}
|
||||
|
||||
if (g_BotConfigsArray[i].difficulty != BOTDIFF_DISABLED) {
|
||||
g_MpSetup.chrslots |= 1 << (i + 4);
|
||||
g_MpSetup.chrslots |= 1 << (i + MAX_PLAYERS);
|
||||
}
|
||||
|
||||
g_BotConfigsArray[i].base.mpheadnum = savebufferReadBits(buffer, 7);
|
||||
@@ -4005,7 +4048,7 @@ void mpsetupfileLoadWad(struct savebuffer *buffer, u8 version)
|
||||
g_MpSetup.scorelimit = savebufferReadBits(buffer, 7);
|
||||
g_MpSetup.teamscorelimit = savebufferReadBits(buffer, 9);
|
||||
|
||||
for (i = 0; i < MAX_PLAYERS; i++) {
|
||||
for (i = 0; i < MAX_LOCAL_PLAYERS; i++) {
|
||||
g_PlayerConfigsArray[i].base.team = savebufferReadBits(buffer, 3);
|
||||
}
|
||||
|
||||
@@ -4021,7 +4064,7 @@ void mpsetupfileSaveWad(struct savebuffer *buffer)
|
||||
savebufferWriteString_ext(buffer, g_MpSetup.name, MPSETUP_MAXNAME + 1);
|
||||
|
||||
for (i = 0; i < MAX_BOTS; i++) {
|
||||
if (g_MpSetup.chrslots & (1 << (i + 4))) {
|
||||
if (g_MpSetup.chrslots & (1 << (i + MAX_PLAYERS))) {
|
||||
numsims++;
|
||||
}
|
||||
}
|
||||
@@ -4037,7 +4080,7 @@ void mpsetupfileSaveWad(struct savebuffer *buffer)
|
||||
for (i = 0; i < MAX_BOTS; i++) {
|
||||
savebufferOr(buffer, g_BotConfigsArray[i].type, 5);
|
||||
|
||||
if (g_MpSetup.chrslots & (1 << (i + 4))) {
|
||||
if (g_MpSetup.chrslots & (1 << (i + MAX_PLAYERS))) {
|
||||
savebufferOr(buffer, g_BotConfigsArray[i].difficulty, 3);
|
||||
} else {
|
||||
savebufferOr(buffer, BOTDIFF_DISABLED, 3);
|
||||
@@ -4073,7 +4116,7 @@ void mpsetupfileSaveWad(struct savebuffer *buffer)
|
||||
savebufferOr(buffer, g_MpSetup.scorelimit, 7);
|
||||
savebufferOr(buffer, g_MpSetup.teamscorelimit, 9);
|
||||
|
||||
for (i = 0; i < MAX_PLAYERS; i++) {
|
||||
for (i = 0; i < MAX_LOCAL_PLAYERS; i++) {
|
||||
savebufferOr(buffer, g_PlayerConfigsArray[i].base.team, 3);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1039,7 +1039,7 @@ struct prop *scenarioCreateObj(s32 modelnum, s16 padnum, f32 arg2, u32 flags, u3
|
||||
*/
|
||||
void scenarioCreateHudmsg(s32 playernum, char *message)
|
||||
{
|
||||
if (playernum >= 0 && playernum < PLAYERCOUNT()) {
|
||||
if (playernum >= 0 && playernum < LOCALPLAYERCOUNT()) {
|
||||
s32 prevplayernum = g_Vars.currentplayernum;
|
||||
|
||||
setCurrentPlayerNum(playernum);
|
||||
|
||||
@@ -11,8 +11,6 @@
|
||||
* Players cannot score unless their briefcase is at the home base.
|
||||
*/
|
||||
|
||||
extern struct menudialogdef g_ExtGameOptionsMenuDialog;
|
||||
|
||||
struct menuitem g_CtcOptionsMenuItems[] = {
|
||||
{
|
||||
MENUITEMTYPE_CHECKBOX,
|
||||
@@ -62,6 +60,40 @@ struct menuitem g_CtcOptionsMenuItems[] = {
|
||||
MPOPTION_NOAUTOAIM,
|
||||
menuhandlerMpCheckboxOption,
|
||||
},
|
||||
#ifndef PLATFORM_N64
|
||||
{
|
||||
MENUITEMTYPE_CHECKBOX,
|
||||
0,
|
||||
MENUITEMFLAG_LOCKABLEMINOR | MENUITEMFLAG_LITERAL_TEXT,
|
||||
(uintptr_t)"Start Armed",
|
||||
MPOPTION_SPAWNWITHWEAPON,
|
||||
menuhandlerMpCheckboxOption,
|
||||
},
|
||||
{
|
||||
MENUITEMTYPE_CHECKBOX,
|
||||
0,
|
||||
MENUITEMFLAG_LOCKABLEMINOR | MENUITEMFLAG_LITERAL_TEXT,
|
||||
(uintptr_t)"No Drug Blur",
|
||||
MPOPTION_NODRUGBLUR,
|
||||
menuhandlerMpCheckboxOption,
|
||||
},
|
||||
{
|
||||
MENUITEMTYPE_CHECKBOX,
|
||||
0,
|
||||
MENUITEMFLAG_LOCKABLEMINOR,
|
||||
L_OPTIONS_257, // "Friendly Fire"
|
||||
MPOPTION_FRIENDLYFIRE,
|
||||
menuhandlerMpDisplayTeam,
|
||||
},
|
||||
{
|
||||
MENUITEMTYPE_CHECKBOX,
|
||||
0,
|
||||
MENUITEMFLAG_LOCKABLEMINOR | MENUITEMFLAG_LITERAL_TEXT,
|
||||
(uintptr_t)"No Player on Radar",
|
||||
MPOPTION_NOPLAYERONRADAR,
|
||||
menuhandlerMpCheckboxOption,
|
||||
},
|
||||
#endif
|
||||
{
|
||||
MENUITEMTYPE_CHECKBOX,
|
||||
0,
|
||||
@@ -111,8 +143,7 @@ struct menudialogdef g_CtcOptionsMenuDialog = {
|
||||
g_CtcOptionsMenuItems,
|
||||
mpOptionsMenuDialog,
|
||||
MENUDIALOGFLAG_MPLOCKABLE,
|
||||
&g_ExtGameOptionsMenuDialog,
|
||||
// NULL,
|
||||
NULL,
|
||||
};
|
||||
|
||||
struct weaponobj g_CtcTokenObj0;
|
||||
|
||||
@@ -6,8 +6,6 @@
|
||||
* There are no callback functions or special logic.
|
||||
*/
|
||||
|
||||
extern struct menudialogdef g_ExtGameOptionsMenuDialog;
|
||||
|
||||
struct menuitem g_MpCombatOptionsMenuItems[] = {
|
||||
{
|
||||
MENUITEMTYPE_CHECKBOX,
|
||||
@@ -57,6 +55,40 @@ struct menuitem g_MpCombatOptionsMenuItems[] = {
|
||||
MPOPTION_NOAUTOAIM,
|
||||
menuhandlerMpCheckboxOption,
|
||||
},
|
||||
#ifndef PLATFORM_N64
|
||||
{
|
||||
MENUITEMTYPE_CHECKBOX,
|
||||
0,
|
||||
MENUITEMFLAG_LOCKABLEMINOR | MENUITEMFLAG_LITERAL_TEXT,
|
||||
(uintptr_t)"Start Armed",
|
||||
MPOPTION_SPAWNWITHWEAPON,
|
||||
menuhandlerMpCheckboxOption,
|
||||
},
|
||||
{
|
||||
MENUITEMTYPE_CHECKBOX,
|
||||
0,
|
||||
MENUITEMFLAG_LOCKABLEMINOR | MENUITEMFLAG_LITERAL_TEXT,
|
||||
(uintptr_t)"No Drug Blur",
|
||||
MPOPTION_NODRUGBLUR,
|
||||
menuhandlerMpCheckboxOption,
|
||||
},
|
||||
{
|
||||
MENUITEMTYPE_CHECKBOX,
|
||||
0,
|
||||
MENUITEMFLAG_LOCKABLEMINOR,
|
||||
L_OPTIONS_257, // "Friendly Fire"
|
||||
MPOPTION_FRIENDLYFIRE,
|
||||
menuhandlerMpDisplayTeam,
|
||||
},
|
||||
{
|
||||
MENUITEMTYPE_CHECKBOX,
|
||||
0,
|
||||
MENUITEMFLAG_LOCKABLEMINOR | MENUITEMFLAG_LITERAL_TEXT,
|
||||
(uintptr_t)"No Player on Radar",
|
||||
MPOPTION_NOPLAYERONRADAR,
|
||||
menuhandlerMpCheckboxOption,
|
||||
},
|
||||
#endif
|
||||
{
|
||||
MENUITEMTYPE_SEPARATOR,
|
||||
0,
|
||||
@@ -106,5 +138,5 @@ struct menudialogdef g_MpCombatOptionsMenuDialog = {
|
||||
g_MpCombatOptionsMenuItems,
|
||||
mpOptionsMenuDialog,
|
||||
MENUDIALOGFLAG_MPLOCKABLE,
|
||||
&g_ExtGameOptionsMenuDialog,
|
||||
NULL,
|
||||
};
|
||||
@@ -7,8 +7,6 @@
|
||||
* cannot use weapons while uplinking.
|
||||
*/
|
||||
|
||||
extern struct menudialogdef g_ExtGameOptionsMenuDialog;
|
||||
|
||||
#define HTM_NUM_TERMINALS 1
|
||||
|
||||
struct menuitem g_HtmOptionsMenuItems[] = {
|
||||
@@ -60,6 +58,40 @@ struct menuitem g_HtmOptionsMenuItems[] = {
|
||||
MPOPTION_NOAUTOAIM,
|
||||
menuhandlerMpCheckboxOption,
|
||||
},
|
||||
#ifndef PLATFORM_N64
|
||||
{
|
||||
MENUITEMTYPE_CHECKBOX,
|
||||
0,
|
||||
MENUITEMFLAG_LOCKABLEMINOR | MENUITEMFLAG_LITERAL_TEXT,
|
||||
(uintptr_t)"Start Armed",
|
||||
MPOPTION_SPAWNWITHWEAPON,
|
||||
menuhandlerMpCheckboxOption,
|
||||
},
|
||||
{
|
||||
MENUITEMTYPE_CHECKBOX,
|
||||
0,
|
||||
MENUITEMFLAG_LOCKABLEMINOR | MENUITEMFLAG_LITERAL_TEXT,
|
||||
(uintptr_t)"No Drug Blur",
|
||||
MPOPTION_NODRUGBLUR,
|
||||
menuhandlerMpCheckboxOption,
|
||||
},
|
||||
{
|
||||
MENUITEMTYPE_CHECKBOX,
|
||||
0,
|
||||
MENUITEMFLAG_LOCKABLEMINOR,
|
||||
L_OPTIONS_257, // "Friendly Fire"
|
||||
MPOPTION_FRIENDLYFIRE,
|
||||
menuhandlerMpDisplayTeam,
|
||||
},
|
||||
{
|
||||
MENUITEMTYPE_CHECKBOX,
|
||||
0,
|
||||
MENUITEMFLAG_LOCKABLEMINOR | MENUITEMFLAG_LITERAL_TEXT,
|
||||
(uintptr_t)"No Player on Radar",
|
||||
MPOPTION_NOPLAYERONRADAR,
|
||||
menuhandlerMpCheckboxOption,
|
||||
},
|
||||
#endif
|
||||
{
|
||||
MENUITEMTYPE_CHECKBOX,
|
||||
0,
|
||||
@@ -117,7 +149,7 @@ struct menudialogdef g_HtmOptionsMenuDialog = {
|
||||
g_HtmOptionsMenuItems,
|
||||
mpOptionsMenuDialog,
|
||||
MENUDIALOGFLAG_MPLOCKABLE,
|
||||
&g_ExtGameOptionsMenuDialog,
|
||||
NULL,
|
||||
};
|
||||
|
||||
struct weaponobj g_HtmUplinkObj;
|
||||
|
||||
@@ -9,8 +9,6 @@
|
||||
* slightly slower but still have full access to their weaponry.
|
||||
*/
|
||||
|
||||
extern struct menudialogdef g_ExtGameOptionsMenuDialog;
|
||||
|
||||
struct menuitem g_HtbOptionsMenuItems[] = {
|
||||
{
|
||||
MENUITEMTYPE_CHECKBOX,
|
||||
@@ -60,6 +58,40 @@ struct menuitem g_HtbOptionsMenuItems[] = {
|
||||
MPOPTION_NOAUTOAIM,
|
||||
menuhandlerMpCheckboxOption,
|
||||
},
|
||||
#ifndef PLATFORM_N64
|
||||
{
|
||||
MENUITEMTYPE_CHECKBOX,
|
||||
0,
|
||||
MENUITEMFLAG_LOCKABLEMINOR | MENUITEMFLAG_LITERAL_TEXT,
|
||||
(uintptr_t)"Start Armed",
|
||||
MPOPTION_SPAWNWITHWEAPON,
|
||||
menuhandlerMpCheckboxOption,
|
||||
},
|
||||
{
|
||||
MENUITEMTYPE_CHECKBOX,
|
||||
0,
|
||||
MENUITEMFLAG_LOCKABLEMINOR | MENUITEMFLAG_LITERAL_TEXT,
|
||||
(uintptr_t)"No Drug Blur",
|
||||
MPOPTION_NODRUGBLUR,
|
||||
menuhandlerMpCheckboxOption,
|
||||
},
|
||||
{
|
||||
MENUITEMTYPE_CHECKBOX,
|
||||
0,
|
||||
MENUITEMFLAG_LOCKABLEMINOR,
|
||||
L_OPTIONS_257, // "Friendly Fire"
|
||||
MPOPTION_FRIENDLYFIRE,
|
||||
menuhandlerMpDisplayTeam,
|
||||
},
|
||||
{
|
||||
MENUITEMTYPE_CHECKBOX,
|
||||
0,
|
||||
MENUITEMFLAG_LOCKABLEMINOR | MENUITEMFLAG_LITERAL_TEXT,
|
||||
(uintptr_t)"No Player on Radar",
|
||||
MPOPTION_NOPLAYERONRADAR,
|
||||
menuhandlerMpCheckboxOption,
|
||||
},
|
||||
#endif
|
||||
{
|
||||
MENUITEMTYPE_CHECKBOX,
|
||||
0,
|
||||
@@ -117,7 +149,7 @@ struct menudialogdef g_HtbOptionsMenuDialog = {
|
||||
g_HtbOptionsMenuItems,
|
||||
mpOptionsMenuDialog,
|
||||
MENUDIALOGFLAG_MPLOCKABLE,
|
||||
&g_ExtGameOptionsMenuDialog,
|
||||
NULL,
|
||||
};
|
||||
|
||||
struct defaultobj *var800869ec = NULL;
|
||||
|
||||
@@ -13,8 +13,6 @@
|
||||
* Points are awarded to each player in the hill at the time that it is won.
|
||||
*/
|
||||
|
||||
extern struct menudialogdef g_ExtGameOptionsMenuDialog;
|
||||
|
||||
MenuItemHandlerResult menuhandlerMpHillTime(s32 operation, struct menuitem *item, union handlerdata *data)
|
||||
{
|
||||
switch (operation) {
|
||||
@@ -81,6 +79,40 @@ struct menuitem g_KohOptionsMenuItems[] = {
|
||||
MPOPTION_NOAUTOAIM,
|
||||
menuhandlerMpCheckboxOption,
|
||||
},
|
||||
#ifndef PLATFORM_N64
|
||||
{
|
||||
MENUITEMTYPE_CHECKBOX,
|
||||
0,
|
||||
MENUITEMFLAG_LOCKABLEMINOR | MENUITEMFLAG_LITERAL_TEXT,
|
||||
(uintptr_t)"Start Armed",
|
||||
MPOPTION_SPAWNWITHWEAPON,
|
||||
menuhandlerMpCheckboxOption,
|
||||
},
|
||||
{
|
||||
MENUITEMTYPE_CHECKBOX,
|
||||
0,
|
||||
MENUITEMFLAG_LOCKABLEMINOR | MENUITEMFLAG_LITERAL_TEXT,
|
||||
(uintptr_t)"No Drug Blur",
|
||||
MPOPTION_NODRUGBLUR,
|
||||
menuhandlerMpCheckboxOption,
|
||||
},
|
||||
{
|
||||
MENUITEMTYPE_CHECKBOX,
|
||||
0,
|
||||
MENUITEMFLAG_LOCKABLEMINOR,
|
||||
L_OPTIONS_257, // "Friendly Fire"
|
||||
MPOPTION_FRIENDLYFIRE,
|
||||
menuhandlerMpDisplayTeam,
|
||||
},
|
||||
{
|
||||
MENUITEMTYPE_CHECKBOX,
|
||||
0,
|
||||
MENUITEMFLAG_LOCKABLEMINOR | MENUITEMFLAG_LITERAL_TEXT,
|
||||
(uintptr_t)"No Player on Radar",
|
||||
MPOPTION_NOPLAYERONRADAR,
|
||||
menuhandlerMpCheckboxOption,
|
||||
},
|
||||
#endif
|
||||
{
|
||||
MENUITEMTYPE_CHECKBOX,
|
||||
0,
|
||||
@@ -146,7 +178,7 @@ struct menudialogdef g_KohOptionsMenuDialog = {
|
||||
g_KohOptionsMenuItems,
|
||||
mpOptionsMenuDialog,
|
||||
MENUDIALOGFLAG_MPLOCKABLE,
|
||||
&g_ExtGameOptionsMenuDialog,
|
||||
NULL,
|
||||
};
|
||||
|
||||
void kohReadSave(struct savebuffer *buffer, u8 version)
|
||||
|
||||
@@ -7,8 +7,6 @@
|
||||
* chosen as the victim.
|
||||
*/
|
||||
|
||||
extern struct menudialogdef g_ExtGameOptionsMenuDialog;
|
||||
|
||||
struct menuitem g_PacOptionsMenuItems[] = {
|
||||
{
|
||||
MENUITEMTYPE_CHECKBOX,
|
||||
@@ -58,6 +56,40 @@ struct menuitem g_PacOptionsMenuItems[] = {
|
||||
MPOPTION_NOAUTOAIM,
|
||||
menuhandlerMpCheckboxOption,
|
||||
},
|
||||
#ifndef PLATFORM_N64
|
||||
{
|
||||
MENUITEMTYPE_CHECKBOX,
|
||||
0,
|
||||
MENUITEMFLAG_LOCKABLEMINOR | MENUITEMFLAG_LITERAL_TEXT,
|
||||
(uintptr_t)"Start Armed",
|
||||
MPOPTION_SPAWNWITHWEAPON,
|
||||
menuhandlerMpCheckboxOption,
|
||||
},
|
||||
{
|
||||
MENUITEMTYPE_CHECKBOX,
|
||||
0,
|
||||
MENUITEMFLAG_LOCKABLEMINOR | MENUITEMFLAG_LITERAL_TEXT,
|
||||
(uintptr_t)"No Drug Blur",
|
||||
MPOPTION_NODRUGBLUR,
|
||||
menuhandlerMpCheckboxOption,
|
||||
},
|
||||
{
|
||||
MENUITEMTYPE_CHECKBOX,
|
||||
0,
|
||||
MENUITEMFLAG_LOCKABLEMINOR,
|
||||
L_OPTIONS_257, // "Friendly Fire"
|
||||
MPOPTION_FRIENDLYFIRE,
|
||||
menuhandlerMpDisplayTeam,
|
||||
},
|
||||
{
|
||||
MENUITEMTYPE_CHECKBOX,
|
||||
0,
|
||||
MENUITEMFLAG_LOCKABLEMINOR | MENUITEMFLAG_LITERAL_TEXT,
|
||||
(uintptr_t)"No Player on Radar",
|
||||
MPOPTION_NOPLAYERONRADAR,
|
||||
menuhandlerMpCheckboxOption,
|
||||
},
|
||||
#endif
|
||||
{
|
||||
MENUITEMTYPE_CHECKBOX,
|
||||
0,
|
||||
@@ -115,7 +147,7 @@ struct menudialogdef g_PacOptionsMenuDialog = {
|
||||
g_PacOptionsMenuItems,
|
||||
mpOptionsMenuDialog,
|
||||
MENUDIALOGFLAG_MPLOCKABLE,
|
||||
&g_ExtGameOptionsMenuDialog,
|
||||
NULL,
|
||||
};
|
||||
|
||||
void pacReset(void)
|
||||
|
||||
+71
-65
@@ -24,9 +24,12 @@
|
||||
#include "data.h"
|
||||
#include "gbiex.h"
|
||||
#include "types.h"
|
||||
#ifndef PLATFORM_N64
|
||||
#include "net/net.h"
|
||||
#include "system.h"
|
||||
#include "input.h"
|
||||
#include "mpsetups.h"
|
||||
#endif
|
||||
|
||||
struct menuitem g_MpCharacterMenuItems[];
|
||||
struct menudialogdef g_MpAddSimulantMenuDialog;
|
||||
@@ -2258,7 +2261,7 @@ MenuItemHandlerResult mpPlayerNameMenuHandler(s32 operation, struct menuitem *it
|
||||
|
||||
MenuItemHandlerResult mpLoadSettingsMenuHandler(s32 operation, struct menuitem *item, union handlerdata *data)
|
||||
{
|
||||
u8 presets = g_Menus[g_MpPlayerNum].mpsetupext.showpresets;
|
||||
u8 presets = g_Menus[g_MpPlayerNum].mpsetup.showpresets;
|
||||
s32 numpresets = mpGetNumUnlockedPresets()*presets;
|
||||
|
||||
switch (operation) {
|
||||
@@ -2392,7 +2395,7 @@ MenuItemHandlerResult mpLoadPlayerMenuHandler(s32 operation, struct menuitem *it
|
||||
file = &g_FileLists[0]->files[data->list.value];
|
||||
available = true;
|
||||
|
||||
for (i = 0; i < MAX_PLAYERS; i++) {
|
||||
for (i = 0; i < MAX_LOCAL_PLAYERS; i++) {
|
||||
if (file->fileid == g_PlayerConfigsArray[i].fileguid.fileid
|
||||
&& file->deviceserial == g_PlayerConfigsArray[i].fileguid.deviceserial) {
|
||||
if ((g_MpSetup.chrslots & (1 << i)) == 0) {
|
||||
@@ -2523,6 +2526,15 @@ MenuItemHandlerResult menuhandlerMpHandicapPlayer(s32 operation, struct menuitem
|
||||
char *mpMenuTextHandicapPlayerName(struct menuitem *item)
|
||||
{
|
||||
if (g_MpSetup.chrslots & (1 << item->param)) {
|
||||
#ifndef PLATFORM_N64
|
||||
if (g_NetMode) {
|
||||
// use client names directly, as the config names are not set yet
|
||||
struct netclient *cl = netClientForPlayerNum(item->param);
|
||||
if (cl) {
|
||||
return cl->settings.name;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return g_PlayerConfigsArray[item->param].base.name;
|
||||
}
|
||||
|
||||
@@ -2568,8 +2580,8 @@ MenuDialogHandlerResult mpLoadSettingsDialogHandler(s32 operation, struct menudi
|
||||
{
|
||||
if (operation == MENUOP_TICK) {
|
||||
if (menuAltAnyPressed(g_MpPlayerNum)) {
|
||||
u8 presets = g_Menus[g_MpPlayerNum].mpsetupext.showpresets;
|
||||
g_Menus[g_MpPlayerNum].mpsetupext.showpresets = 1 - presets;
|
||||
u8 presets = g_Menus[g_MpPlayerNum].mpsetup.showpresets;
|
||||
g_Menus[g_MpPlayerNum].mpsetup.showpresets = 1 - presets;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2850,6 +2862,40 @@ struct menuitem g_MpHandicapsMenuItems[] = {
|
||||
0x000000ff,
|
||||
menuhandlerMpHandicapPlayer,
|
||||
},
|
||||
#if MAX_PLAYERS > 4
|
||||
{
|
||||
MENUITEMTYPE_SLIDER,
|
||||
4,
|
||||
MENUITEMFLAG_LESSLEFTPADDING | MENUITEMFLAG_LOCKABLEMINOR,
|
||||
(uintptr_t)&mpMenuTextHandicapPlayerName,
|
||||
0x000000ff,
|
||||
menuhandlerMpHandicapPlayer,
|
||||
},
|
||||
{
|
||||
MENUITEMTYPE_SLIDER,
|
||||
5,
|
||||
MENUITEMFLAG_LESSLEFTPADDING | MENUITEMFLAG_LOCKABLEMINOR,
|
||||
(uintptr_t)&mpMenuTextHandicapPlayerName,
|
||||
0x000000ff,
|
||||
menuhandlerMpHandicapPlayer,
|
||||
},
|
||||
{
|
||||
MENUITEMTYPE_SLIDER,
|
||||
6,
|
||||
MENUITEMFLAG_LESSLEFTPADDING | MENUITEMFLAG_LOCKABLEMINOR,
|
||||
(uintptr_t)&mpMenuTextHandicapPlayerName,
|
||||
0x000000ff,
|
||||
menuhandlerMpHandicapPlayer,
|
||||
},
|
||||
{
|
||||
MENUITEMTYPE_SLIDER,
|
||||
7,
|
||||
MENUITEMFLAG_LESSLEFTPADDING | MENUITEMFLAG_LOCKABLEMINOR,
|
||||
(uintptr_t)&mpMenuTextHandicapPlayerName,
|
||||
0x000000ff,
|
||||
menuhandlerMpHandicapPlayer,
|
||||
},
|
||||
#endif
|
||||
{
|
||||
MENUITEMTYPE_SEPARATOR,
|
||||
0,
|
||||
@@ -2948,7 +2994,7 @@ MenuItemHandlerResult mpAddChangeSimulantMenuHandler(s32 operation, struct menui
|
||||
if (botnum < 0) {
|
||||
botnum = mpGetSlotForNewBot();
|
||||
creating = 1;
|
||||
} else if ((g_MpSetup.chrslots & (1 << (botnum + 4))) == 0) {
|
||||
} else if ((g_MpSetup.chrslots & (1 << (botnum + MAX_PLAYERS))) == 0) {
|
||||
creating = 1;
|
||||
}
|
||||
|
||||
@@ -3206,7 +3252,7 @@ MenuItemHandlerResult menuhandlerMpSimulantSlot(s32 operation, struct menuitem *
|
||||
case MENUOP_SET:
|
||||
g_Menus[g_MpPlayerNum].mpsetup.slotindex = item->param;
|
||||
|
||||
if ((g_MpSetup.chrslots & (1 << (item->param + 4))) == 0) {
|
||||
if ((g_MpSetup.chrslots & (1 << (item->param + MAX_PLAYERS))) == 0) {
|
||||
menuPushDialog(&g_MpAddSimulantMenuDialog);
|
||||
} else if (IS4MB()) {
|
||||
menuPushDialog(&g_MpEditSimulant4MbMenuDialog);
|
||||
@@ -3232,7 +3278,7 @@ char *mpMenuTextSimulantName(struct menuitem *item)
|
||||
{
|
||||
s32 index = item->param;
|
||||
|
||||
if (g_BotConfigsArray[index].base.name[0] == '\0' || (g_MpSetup.chrslots & 1 << (index + 4)) == 0) {
|
||||
if (g_BotConfigsArray[index].base.name[0] == '\0' || (g_MpSetup.chrslots & 1 << (index + MAX_PLAYERS)) == 0) {
|
||||
return "";
|
||||
}
|
||||
|
||||
@@ -3244,7 +3290,7 @@ char *func0f17d3dc(struct menuitem *item)
|
||||
s32 index = item->param;
|
||||
|
||||
if (g_BotConfigsArray[index].base.name[0] == '\0'
|
||||
|| ((g_MpSetup.chrslots & 1 << (index + 4)) == 0)) {
|
||||
|| ((g_MpSetup.chrslots & 1 << (index + MAX_PLAYERS)) == 0)) {
|
||||
return "";
|
||||
}
|
||||
|
||||
@@ -3642,7 +3688,7 @@ MenuItemHandlerResult menuhandlerMpHumansVsSimulants(s32 operation, struct menui
|
||||
if (g_MpSetup.chrslots & (1 << i)) {
|
||||
struct mpchrconfig *mpchr = MPCHR(i);
|
||||
|
||||
mpchr->team = i < 4 ? 0 : 1;
|
||||
mpchr->team = i < MAX_PLAYERS ? 0 : 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3655,7 +3701,7 @@ MenuItemHandlerResult menuhandlerMpHumansVsSimulants(s32 operation, struct menui
|
||||
MenuItemHandlerResult menuhandlerMpHumanSimulantPairs(s32 operation, struct menuitem *item, union handlerdata *data)
|
||||
{
|
||||
if (operation == MENUOP_SET) {
|
||||
u8 team_ids[4] = {0, 1, 2, 3};
|
||||
u8 team_ids[MAX_PLAYERS] = {0, 1, 2, 3, 4, 5, 6, 7};
|
||||
s32 i;
|
||||
s32 playerindex = 0;
|
||||
s32 simindex = 0;
|
||||
@@ -3664,7 +3710,7 @@ MenuItemHandlerResult menuhandlerMpHumanSimulantPairs(s32 operation, struct menu
|
||||
if (g_MpSetup.chrslots & (1 << i)) {
|
||||
struct mpchrconfig *mpchr = MPCHR(i);
|
||||
|
||||
if (i < 4) {
|
||||
if (i < MAX_PLAYERS) {
|
||||
mpchr->team = team_ids[playerindex++];
|
||||
} else {
|
||||
mpchr->team = team_ids[simindex++];
|
||||
@@ -3687,6 +3733,15 @@ char *mpMenuTextChrNameForTeamSetup(struct menuitem *item)
|
||||
struct mpchrconfig *mpchr = mpGetChrConfigBySlotNum(item->param);
|
||||
|
||||
if (mpchr) {
|
||||
#ifndef PLATFORM_N64
|
||||
if (g_NetMode) {
|
||||
// use client names directly, as the config names are not set yet
|
||||
struct netclient *cl = netClientForPlayerNum(item->param);
|
||||
if (cl) {
|
||||
return cl->settings.name;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return mpchr->name;
|
||||
}
|
||||
|
||||
@@ -5394,6 +5449,10 @@ MenuDialogHandlerResult menudialogCombatSimulator(s32 operation, struct menudial
|
||||
g_Vars.waitingtojoin[1] = false;
|
||||
g_Vars.waitingtojoin[2] = false;
|
||||
g_Vars.waitingtojoin[3] = false;
|
||||
|
||||
// load the setup file when entering the Combat Simulator
|
||||
mpsetupCopyAllFromPak();
|
||||
mpsetupLoadCurrentFile();
|
||||
}
|
||||
|
||||
if (g_Menus[g_MpPlayerNum].curdialog
|
||||
@@ -5430,7 +5489,7 @@ void mpCloseDialogsForNewSetup(void)
|
||||
s32 k;
|
||||
|
||||
// Loop through each player
|
||||
for (i = 0; i < MAX_PLAYERS; i++) {
|
||||
for (i = 0; i < MAX_LOCAL_PLAYERS; i++) {
|
||||
g_MpPlayerNum = i;
|
||||
|
||||
// If they have a menu open
|
||||
@@ -6155,56 +6214,3 @@ void func0f17fcb0(s32 silent)
|
||||
sndStart(var80095200, SFX_EXPLOSION_809A, NULL, -1, -1, -1, -1, -1);
|
||||
}
|
||||
}
|
||||
|
||||
struct menuitem g_MpExtGameOptionsMenuItems[] = {
|
||||
{
|
||||
MENUITEMTYPE_CHECKBOX,
|
||||
0,
|
||||
MENUITEMFLAG_LOCKABLEMINOR | MENUITEMFLAG_LITERAL_TEXT,
|
||||
(uintptr_t)"Start Armed",
|
||||
MPOPTION_SPAWNWITHWEAPON,
|
||||
menuhandlerMpCheckboxOption,
|
||||
},
|
||||
{
|
||||
MENUITEMTYPE_CHECKBOX,
|
||||
0,
|
||||
MENUITEMFLAG_LOCKABLEMINOR | MENUITEMFLAG_LITERAL_TEXT,
|
||||
(uintptr_t)"No Drug Blur",
|
||||
MPOPTION_NODRUGBLUR,
|
||||
menuhandlerMpCheckboxOption,
|
||||
},
|
||||
{
|
||||
MENUITEMTYPE_CHECKBOX,
|
||||
0,
|
||||
MENUITEMFLAG_LOCKABLEMINOR,
|
||||
L_OPTIONS_257, // "Friendly Fire"
|
||||
MPOPTION_FRIENDLYFIRE,
|
||||
menuhandlerMpDisplayTeam,
|
||||
},
|
||||
{
|
||||
MENUITEMTYPE_CHECKBOX,
|
||||
0,
|
||||
MENUITEMFLAG_LOCKABLEMINOR | MENUITEMFLAG_LITERAL_TEXT,
|
||||
(uintptr_t)"No Player on Radar",
|
||||
MPOPTION_NOPLAYERONRADAR,
|
||||
menuhandlerMpCheckboxOption,
|
||||
},
|
||||
{
|
||||
MENUITEMTYPE_CHECKBOX,
|
||||
0,
|
||||
MENUITEMFLAG_LOCKABLEMINOR | MENUITEMFLAG_LITERAL_TEXT,
|
||||
(uintptr_t)"No Doors",
|
||||
MPOPTION_NODOORS,
|
||||
menuhandlerMpCheckboxOption,
|
||||
},
|
||||
{ MENUITEMTYPE_END },
|
||||
};
|
||||
|
||||
struct menudialogdef g_ExtGameOptionsMenuDialog = {
|
||||
MENUDIALOGTYPE_DEFAULT,
|
||||
(uintptr_t) "More Options\n",
|
||||
g_MpExtGameOptionsMenuItems,
|
||||
NULL,
|
||||
MENUDIALOGFLAG_LITERAL_TEXT,
|
||||
NULL,
|
||||
};
|
||||
+2
-2
@@ -343,7 +343,7 @@ bool musicIsAnyPlayerInAmbientRoom(void)
|
||||
return false;
|
||||
}
|
||||
|
||||
for (i = 0; i < PLAYERCOUNT(); i++) {
|
||||
for (i = 0; i < LOCALPLAYERCOUNT(); i++) {
|
||||
if (g_Vars.players[i]->prop
|
||||
&& g_Vars.players[i]->prop->rooms
|
||||
&& g_Vars.players[i]->prop->rooms[0] != -1) {
|
||||
@@ -521,7 +521,7 @@ void _musicStartMpDeath(f32 arg0)
|
||||
void musicStartMpDeath(void)
|
||||
{
|
||||
#ifndef PLATFORM_N64
|
||||
if (g_MusicDisableMpDeath) {
|
||||
if (g_MusicDisableMpDeath || (g_NetMode && g_Vars.currentplayernum != 0)) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
+1
-1
@@ -324,7 +324,7 @@ Gfx *nbombCreateGdl(void)
|
||||
Gfx *gdl;
|
||||
s32 index = 0;
|
||||
|
||||
if (PLAYERCOUNT() >= 2) {
|
||||
if (LOCALPLAYERCOUNT() >= 2) {
|
||||
index = 1;
|
||||
}
|
||||
|
||||
|
||||
+7
-12
@@ -234,7 +234,7 @@ struct pak g_Paks[5]; // controller paks + EEPROM
|
||||
u32 var800a317c;
|
||||
#endif
|
||||
|
||||
OSPfs g_Pfses[MAX_PLAYERS];
|
||||
OSPfs g_Pfses[MAX_LOCAL_PLAYERS];
|
||||
u32 var800a3320;
|
||||
u32 var800a3324;
|
||||
u32 var800a3328;
|
||||
@@ -859,11 +859,6 @@ PakErr2 pakReadHeaderAtOffset(s8 device, u32 offset, struct pakfileheader *heade
|
||||
return PAK_ERR2_BADOFFSET;
|
||||
}
|
||||
|
||||
if (offset > g_Paks[device].pdnumbytes - sizeof(sp38)) {
|
||||
// not enough bytes left for a header
|
||||
return PAK_ERR2_BADOFFSET;
|
||||
}
|
||||
|
||||
if (!pakRetrieveHeaderFromCache(device, blocknum, headerptr)) {
|
||||
result = pakReadWriteBlock(device, PFS(device), g_Paks[device].pdnoteindex, 0, offset, sizeof(sp38), sp38);
|
||||
|
||||
@@ -4430,7 +4425,7 @@ void pak0f11c6d0(void)
|
||||
{
|
||||
s32 i;
|
||||
|
||||
for (i = 0; i < MAX_PLAYERS; i++) {
|
||||
for (i = 0; i < MAX_LOCAL_PLAYERS; i++) {
|
||||
switch (g_Paks[i].state) {
|
||||
case PAKSTATE_PROBE:
|
||||
case PAKSTATE_MEM_DISPATCH:
|
||||
@@ -5446,14 +5441,14 @@ void pakDisableRumbleForAllPlayers(void)
|
||||
s32 i;
|
||||
|
||||
#if VERSION >= VERSION_NTSC_1_0
|
||||
for (i = 0; i < MAX_PLAYERS; i++) {
|
||||
for (i = 0; i < MAX_LOCAL_PLAYERS; i++) {
|
||||
if (g_Paks[i].type == PAKTYPE_RUMBLE) {
|
||||
g_Paks[i].rumblestate = RUMBLESTATE_DISABLED_STOPPING;
|
||||
joyStopRumble(i, true);
|
||||
}
|
||||
}
|
||||
#else
|
||||
for (i = 0; i < MAX_PLAYERS; i++) {
|
||||
for (i = 0; i < MAX_LOCAL_PLAYERS; i++) {
|
||||
pakDisableRumbleForPlayer(i);
|
||||
}
|
||||
#endif
|
||||
@@ -5464,13 +5459,13 @@ void pakEnableRumbleForAllPlayers(void)
|
||||
s32 i;
|
||||
|
||||
#if VERSION >= VERSION_NTSC_FINAL
|
||||
for (i = 0; i < MAX_PLAYERS; i++) {
|
||||
for (i = 0; i < MAX_LOCAL_PLAYERS; i++) {
|
||||
if (g_Paks[i].type == PAKTYPE_RUMBLE && g_Paks[i].rumblestate == RUMBLESTATE_DISABLED_STOPPED) {
|
||||
g_Paks[i].rumblestate = RUMBLESTATE_ENABLING;
|
||||
}
|
||||
}
|
||||
#else
|
||||
for (i = 0; i < MAX_PLAYERS; i++) {
|
||||
for (i = 0; i < MAX_LOCAL_PLAYERS; i++) {
|
||||
pakEnableRumbleForPlayer(i);
|
||||
}
|
||||
#endif
|
||||
@@ -5994,7 +5989,7 @@ bool gbpakIsAnyPerfectDark(void)
|
||||
#ifdef PLATFORM_N64
|
||||
s8 i;
|
||||
|
||||
for (i = 0; i < MAX_PLAYERS; i++) {
|
||||
for (i = 0; i < MAX_LOCAL_PLAYERS; i++) {
|
||||
if (gbpakIdentifyGame(i) == GBGAME_PD) {
|
||||
return true;
|
||||
}
|
||||
|
||||
+140
-19
@@ -71,9 +71,11 @@
|
||||
#include "data.h"
|
||||
#include "types.h"
|
||||
#ifndef PLATFORM_N64
|
||||
#include "platform.h"
|
||||
#include "video.h"
|
||||
#include "input.h"
|
||||
#include "platform.h"
|
||||
#include "net/net.h"
|
||||
#include "net/netmsg.h"
|
||||
#endif
|
||||
|
||||
s32 g_DefaultWeapons[2];
|
||||
@@ -183,7 +185,10 @@ u32 var80070748 = 0;
|
||||
u32 var8007074c = 0;
|
||||
|
||||
bool g_PlayersWithControl[] = {
|
||||
true, true, true, true,
|
||||
#if MAX_PLAYERS > 4
|
||||
true, true, true, true
|
||||
#endif
|
||||
};
|
||||
|
||||
bool g_PlayerInvincible = false;
|
||||
@@ -602,7 +607,7 @@ void playerStartNewLife(void)
|
||||
if (cmd);
|
||||
if (cmd);
|
||||
|
||||
if (g_Vars.antiplayernum < 0 || g_Vars.currentplayer != g_Vars.anti) {
|
||||
if (g_Vars.antiplayernum < 0 || PLAYER_IS_NOT_ANTI(g_Vars.currentplayer)) {
|
||||
while (cmd[0] != INTROCMD_END) {
|
||||
switch (cmd[0]) {
|
||||
case INTROCMD_SPAWN:
|
||||
@@ -976,7 +981,7 @@ void playerSpawn(void)
|
||||
}
|
||||
|
||||
if (g_Vars.mplayerisrunning) {
|
||||
if (g_Vars.antiplayernum >= 0 && g_Vars.currentplayer == g_Vars.anti) {
|
||||
if (g_Vars.antiplayernum >= 0 && PLAYER_IS_ANTI(g_Vars.currentplayer)) {
|
||||
numsqdists = 0;
|
||||
force = false;
|
||||
|
||||
@@ -1114,8 +1119,7 @@ void playerSpawn(void)
|
||||
invGiveSingleWeapon(WEAPON_NIGHTVISION);
|
||||
}
|
||||
|
||||
if (g_Vars.normmplayerisrunning
|
||||
&& (g_MpSetup.options & MPOPTION_SPAWNWITHWEAPON)
|
||||
if ((g_MpSetup.options & MPOPTION_SPAWNWITHWEAPON)
|
||||
&& g_MpSetup.weapons[0] != MPWEAPON_NONE
|
||||
&& g_MpSetup.weapons[0] != MPWEAPON_DISABLED
|
||||
&& g_MpSetup.weapons[0] != MPWEAPON_SHIELD) {
|
||||
@@ -1152,6 +1156,12 @@ void playerSpawn(void)
|
||||
}
|
||||
|
||||
playerUpdatePerimInfo();
|
||||
|
||||
#ifndef PLATFORM_N64
|
||||
if (g_NetMode == NETMODE_SERVER && g_Vars.currentplayer->client) {
|
||||
netmsgSvcPlayerStatsWrite(&g_NetMsgRel, g_Vars.currentplayer->client);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void playerResetBond(struct playerbond *pb, struct coord *pos)
|
||||
@@ -1194,7 +1204,7 @@ void playerChooseBodyAndHead(s32 *bodynum, s32 *headnum, s32 *arg2)
|
||||
bool solo;
|
||||
|
||||
if (g_Vars.antiplayernum >= 0
|
||||
&& g_Vars.currentplayer == g_Vars.anti
|
||||
&& PLAYER_IS_ANTI(g_Vars.currentplayer)
|
||||
&& g_Vars.antiheadnum >= 0
|
||||
&& g_Vars.antibodynum >= 0) {
|
||||
*headnum = g_Vars.antiheadnum;
|
||||
@@ -1536,7 +1546,7 @@ void playerTickChrBody(void)
|
||||
|
||||
#if VERSION >= VERSION_NTSC_1_0
|
||||
if (g_Vars.antiplayernum >= 0
|
||||
&& g_Vars.currentplayer == g_Vars.anti
|
||||
&& PLAYER_IS_ANTI(g_Vars.currentplayer)
|
||||
&& g_Vars.currentplayer->vv_eyeheight > 159) {
|
||||
g_Vars.currentplayer->vv_eyeheight = 159;
|
||||
}
|
||||
@@ -2097,6 +2107,15 @@ void playerTickCutscene(bool arg0)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef PLATFORM_N64
|
||||
if (g_Vars.stagenum == STAGE_CITRAINING) {
|
||||
if (g_CutsceneCurTotalFrame60f > 10 && (g_NetHostLatch || g_NetJoinLatch)) {
|
||||
// just booted up and host/join was requested from command line, skip the intro cutscene
|
||||
g_CutsceneSkipRequested = true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
f32 playerGetCutsceneBlurFrac(void)
|
||||
@@ -2883,6 +2902,12 @@ s16 playerGetFbHeight(void)
|
||||
#if VERSION >= VERSION_NTSC_1_0
|
||||
bool playerHasSharedViewport(void)
|
||||
{
|
||||
#ifndef PLATFORM_N64
|
||||
if (g_NetMode) {
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
if ((g_Vars.coopplayernum >= 0 || g_Vars.antiplayernum >= 0)
|
||||
&& menuGetRoot() == MENUROOT_MPENDSCREEN
|
||||
&& var8009dfc0 == 0) {
|
||||
@@ -2903,14 +2928,14 @@ s16 playerGetViewportWidth(void)
|
||||
if ((!g_InCutscene || g_MainIsEndscreen) && menuGetRoot() != MENUROOT_COOPCONTINUE)
|
||||
#endif
|
||||
{
|
||||
if (PLAYERCOUNT() >= 3) {
|
||||
if (LOCALPLAYERCOUNT() >= 3) {
|
||||
// 3/4 players
|
||||
width = g_ViModes[g_ViRes].width / 2;
|
||||
|
||||
if (g_Vars.currentplayernum == 0 || g_Vars.currentplayernum == 2) {
|
||||
width--;
|
||||
}
|
||||
} else if (PLAYERCOUNT() == 2) {
|
||||
} else if (LOCALPLAYERCOUNT() == 2) {
|
||||
if (optionsGetScreenSplit() == SCREENSPLIT_VERTICAL || g_Vars.fourmeg2player) {
|
||||
// 2 players vsplit
|
||||
width = g_ViModes[g_ViRes].width / 2;
|
||||
@@ -2943,7 +2968,7 @@ s16 playerGetViewportLeft(void)
|
||||
#endif
|
||||
s16 left;
|
||||
|
||||
if (PLAYERCOUNT() >= 3 && something != 0) {
|
||||
if (LOCALPLAYERCOUNT() >= 3 && something != 0) {
|
||||
if (g_Vars.currentplayernum == 1 || g_Vars.currentplayernum == 3) {
|
||||
// 3/4 players - right side
|
||||
left = g_ViModes[g_ViRes].width / 2 + g_ViModes[g_ViRes].fbwidth - g_ViModes[g_ViRes].width;
|
||||
@@ -2951,7 +2976,7 @@ s16 playerGetViewportLeft(void)
|
||||
// 3/4 players - left side
|
||||
left = g_ViModes[g_ViRes].fbwidth - g_ViModes[g_ViRes].width;
|
||||
}
|
||||
} else if (PLAYERCOUNT() == 2 && something != 0) {
|
||||
} else if (LOCALPLAYERCOUNT() == 2 && something != 0) {
|
||||
if (optionsGetScreenSplit() == SCREENSPLIT_VERTICAL || g_Vars.fourmeg2player) {
|
||||
if (g_Vars.currentplayernum == 1) {
|
||||
// 2 players vsplit - right side
|
||||
@@ -2976,7 +3001,7 @@ s16 playerGetViewportHeight(void)
|
||||
{
|
||||
s16 height;
|
||||
|
||||
if (PLAYERCOUNT() >= 2
|
||||
if (LOCALPLAYERCOUNT() >= 2
|
||||
#if VERSION >= VERSION_NTSC_1_0
|
||||
&& !playerHasSharedViewport()
|
||||
#else
|
||||
@@ -2991,7 +3016,7 @@ s16 playerGetViewportHeight(void)
|
||||
height = tmp / 2;
|
||||
}
|
||||
|
||||
if (PLAYERCOUNT() == 2) {
|
||||
if (LOCALPLAYERCOUNT() == 2) {
|
||||
if (optionsGetScreenSplit() == SCREENSPLIT_VERTICAL) {
|
||||
height = tmp;
|
||||
} else if (g_Vars.currentplayernum == 0 && IS8MB()) {
|
||||
@@ -3027,7 +3052,7 @@ s16 playerGetViewportTop(void)
|
||||
{
|
||||
s16 top;
|
||||
|
||||
if (PLAYERCOUNT() >= 2
|
||||
if (LOCALPLAYERCOUNT() >= 2
|
||||
#if VERSION >= VERSION_NTSC_1_0
|
||||
&& !playerHasSharedViewport()
|
||||
#else
|
||||
@@ -3038,12 +3063,12 @@ s16 playerGetViewportTop(void)
|
||||
top = g_ViModes[g_ViRes].fulltop;
|
||||
|
||||
#if VERSION >= VERSION_NTSC_1_0
|
||||
if (optionsGetScreenSplit() != SCREENSPLIT_VERTICAL || PLAYERCOUNT() != 2)
|
||||
if (optionsGetScreenSplit() != SCREENSPLIT_VERTICAL || LOCALPLAYERCOUNT() != 2)
|
||||
#else
|
||||
if (optionsGetScreenSplit() != SCREENSPLIT_VERTICAL)
|
||||
#endif
|
||||
{
|
||||
if (PLAYERCOUNT() == 2
|
||||
if (LOCALPLAYERCOUNT() == 2
|
||||
&& g_Vars.currentplayernum == 1
|
||||
&& optionsGetScreenSplit() != SCREENSPLIT_VERTICAL
|
||||
&& !g_Vars.fourmeg2player) {
|
||||
@@ -3570,6 +3595,11 @@ void playerTick(bool arg0)
|
||||
bool pause = false;
|
||||
f32 newspeed;
|
||||
|
||||
#ifndef PLATFORM_N64
|
||||
if (mode == CONTROLMODE_NA) {
|
||||
// TODO
|
||||
} else
|
||||
#endif
|
||||
if (mode == CONTROLMODE_23
|
||||
|| mode == CONTROLMODE_24
|
||||
|| mode == CONTROLMODE_22
|
||||
@@ -4744,8 +4774,15 @@ Gfx *playerRenderHud(Gfx *gdl)
|
||||
chr->chrflags |= CHRCFLAG_HIDDEN;
|
||||
}
|
||||
|
||||
if (g_Vars.antiplayernum >= 0 && g_Vars.currentplayer == g_Vars.anti) {
|
||||
if (g_Vars.antiplayernum >= 0 && PLAYER_IS_ANTI(g_Vars.currentplayer)) {
|
||||
// Anti
|
||||
#ifndef PLATFORM_N64
|
||||
if (g_NetMode == NETMODE_SERVER && g_Vars.currentplayer->isremote) {
|
||||
if (g_Vars.currentplayer->client->inmove[0].ucmd & UCMD_RESPAWN) {
|
||||
g_Vars.currentplayer->dostartnewlife = true;
|
||||
}
|
||||
} else if (g_NetMode != NETMODE_CLIENT)
|
||||
#endif
|
||||
if (joyGetButtons(optionsGetContpadNum1(g_Vars.currentplayerstats->mpindex), 0xb000) && !mpIsPaused()) {
|
||||
g_Vars.currentplayer->dostartnewlife = true;
|
||||
}
|
||||
@@ -4759,8 +4796,12 @@ Gfx *playerRenderHud(Gfx *gdl)
|
||||
f32 stealhealth;
|
||||
f32 shield;
|
||||
|
||||
canrestart = joyGetButtons(optionsGetContpadNum1(g_Vars.currentplayerstats->mpindex), 0xb000)
|
||||
&& !mpIsPaused();
|
||||
#ifndef PLATFORM_N64
|
||||
if (g_NetMode == NETMODE_SERVER && g_Vars.currentplayer->isremote) {
|
||||
canrestart = (g_Vars.currentplayer->client->inmove[0].ucmd & UCMD_RESPAWN) != 0;
|
||||
} else if (g_NetMode != NETMODE_CLIENT)
|
||||
#endif
|
||||
canrestart = joyGetButtons(optionsGetContpadNum1(g_Vars.currentplayerstats->mpindex), 0xb000) && !mpIsPaused();
|
||||
|
||||
// Get ready to respawn.
|
||||
// The other player's health will be halved.
|
||||
@@ -4866,6 +4907,13 @@ Gfx *playerRenderHud(Gfx *gdl)
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef PLATFORM_N64
|
||||
if (g_NetMode == NETMODE_SERVER && g_Vars.currentplayer->isremote) {
|
||||
if (!mpIsPaused() && g_NumReasonsToEndMpMatch == 0 && (g_Vars.currentplayer->client->inmove[0].ucmd & UCMD_RESPAWN)) {
|
||||
canrestart = true;
|
||||
}
|
||||
} else if (g_NetMode != NETMODE_CLIENT)
|
||||
#endif
|
||||
if (joyGetButtons(optionsGetContpadNum1(g_Vars.currentplayerstats->mpindex), 0xb000)
|
||||
&& !mpIsPaused()
|
||||
&& g_NumReasonsToEndMpMatch == 0) {
|
||||
@@ -4949,6 +4997,12 @@ void playerDie(bool force)
|
||||
struct chrdata *chr = g_Vars.currentplayer->prop->chr;
|
||||
s32 shooter;
|
||||
|
||||
#ifndef PLATFORM_N64
|
||||
if (g_NetMode == NETMODE_CLIENT) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (chr->lastshooter >= 0 && chr->timeshooter > 0) {
|
||||
shooter = chr->lastshooter;
|
||||
} else {
|
||||
@@ -4956,6 +5010,12 @@ void playerDie(bool force)
|
||||
}
|
||||
|
||||
playerDieByShooter(shooter, force);
|
||||
|
||||
#ifndef PLATFORM_N64
|
||||
if (g_NetMode == NETMODE_SERVER && g_Vars.currentplayer->client) {
|
||||
netmsgSvcPlayerStatsWrite(&g_NetMsgRel, g_Vars.currentplayer->client);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void playerDieByShooter(u32 shooter, bool force)
|
||||
@@ -5878,3 +5938,64 @@ void player0f0c3320(Mtxf *matrices, s32 count)
|
||||
mtxF2L(&sp40, matrices + i);
|
||||
}
|
||||
}
|
||||
|
||||
struct sndstate *playerSndStart(s32 arg0, s16 sound, struct sndstate **handle, s32 playernum, f32 pitch, s32 fxbus, s32 fxmix)
|
||||
{
|
||||
s32 vol = -1;
|
||||
s32 pan = -1;
|
||||
#ifndef PLATFORM_N64
|
||||
const struct player *pl = g_Vars.players[playernum];
|
||||
if (g_NetMode && playernum != 0 && pl && pl->prop) {
|
||||
// auto attenuate sounds for remote players
|
||||
psGetTheoreticalVolPan(&pl->prop->pos, pl->prop->rooms, sound, &vol, &pan);
|
||||
}
|
||||
#endif
|
||||
return sndStart(arg0, sound, handle, vol, pan, pitch, fxbus, fxmix);
|
||||
}
|
||||
|
||||
#ifndef PLATFORM_N64
|
||||
|
||||
f32 playerGetDefaultFovY(s32 playernum)
|
||||
{
|
||||
if (g_NetMode) {
|
||||
const struct player *pl = g_Vars.players[playernum % MAX_PLAYERS];
|
||||
if (pl && pl->client) {
|
||||
return pl->client->settings.fovy;
|
||||
}
|
||||
}
|
||||
return g_PlayerExtCfg[playernum % MAX_LOCAL_PLAYERS].fovy;
|
||||
}
|
||||
|
||||
f32 playerGetZoomFovMult(s32 playernum)
|
||||
{
|
||||
if (g_NetMode) {
|
||||
const struct player *pl = g_Vars.players[playernum % MAX_PLAYERS];
|
||||
if (pl && pl->client) {
|
||||
return pl->client->settings.fovzoommult;
|
||||
}
|
||||
}
|
||||
return g_PlayerExtCfg[playernum % MAX_LOCAL_PLAYERS].fovzoommult;
|
||||
}
|
||||
|
||||
s32 playerGetCount(void)
|
||||
{
|
||||
s32 count = 0;
|
||||
for (s32 i = 0; i < MAX_PLAYERS; ++i) {
|
||||
count += (g_Vars.players[i] != NULL);
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
s32 playerGetLocalCount(void)
|
||||
{
|
||||
if (g_NetMode) {
|
||||
return 1;
|
||||
}
|
||||
const s32 playercount = playerGetCount();
|
||||
if (playercount > MAX_LOCAL_PLAYERS) {
|
||||
return MAX_LOCAL_PLAYERS;
|
||||
}
|
||||
return playercount;
|
||||
}
|
||||
|
||||
#endif
|
||||
+36
-1
@@ -10,6 +10,9 @@
|
||||
#include "lib/rng.h"
|
||||
#include "data.h"
|
||||
#include "types.h"
|
||||
#ifndef PLATFORM_N64
|
||||
#include "net/net.h"
|
||||
#endif
|
||||
|
||||
void playermgrInit(void)
|
||||
{
|
||||
@@ -26,10 +29,16 @@ void playermgrInit(void)
|
||||
|
||||
void playermgrReset(void)
|
||||
{
|
||||
#if MAX_PLAYERS > 4
|
||||
for (s32 i = 0; i < MAX_PLAYERS; ++i) {
|
||||
g_Vars.players[i] = NULL;
|
||||
}
|
||||
#else
|
||||
g_Vars.players[0] = NULL;
|
||||
g_Vars.players[1] = NULL;
|
||||
g_Vars.players[2] = NULL;
|
||||
g_Vars.players[3] = NULL;
|
||||
#endif
|
||||
|
||||
g_Vars.currentplayer = NULL;
|
||||
g_Vars.currentplayerindex = 0;
|
||||
@@ -48,10 +57,16 @@ void playermgrReset(void)
|
||||
|
||||
void playermgrAllocatePlayers(s32 count)
|
||||
{
|
||||
#if MAX_PLAYERS > 4
|
||||
for (s32 i = 0; i < MAX_PLAYERS; ++i) {
|
||||
g_Vars.players[i] = NULL;
|
||||
}
|
||||
#else
|
||||
g_Vars.players[0] = NULL;
|
||||
g_Vars.players[1] = NULL;
|
||||
g_Vars.players[2] = NULL;
|
||||
g_Vars.players[3] = NULL;
|
||||
#endif
|
||||
|
||||
if (count > 0) {
|
||||
s32 i;
|
||||
@@ -60,6 +75,12 @@ void playermgrAllocatePlayers(s32 count)
|
||||
playermgrAllocatePlayer(i);
|
||||
}
|
||||
|
||||
#ifndef PLATFORM_N64
|
||||
if (g_NetMode && g_StageNum != STAGE_TITLE && g_StageNum != STAGE_CITRAINING) {
|
||||
netPlayersAllocate();
|
||||
}
|
||||
#endif
|
||||
|
||||
setCurrentPlayerNum(0);
|
||||
g_Vars.bond = g_Vars.players[g_Vars.bondplayernum];
|
||||
|
||||
@@ -591,7 +612,7 @@ void playermgrAllocatePlayer(s32 index)
|
||||
g_Vars.players[index]->introanimnum = 0;
|
||||
g_Vars.players[index]->lastsighton = 0;
|
||||
|
||||
for (i = 0; i < MAX_PLAYERS; i++) {
|
||||
for (i = 0; i < ARRAYCOUNT(g_Vars.players[index]->targetset); i++) {
|
||||
g_Vars.players[index]->targetset[i] = 0;
|
||||
}
|
||||
|
||||
@@ -643,6 +664,12 @@ void playermgrAllocatePlayer(s32 index)
|
||||
g_Vars.players[index]->disguised = false;
|
||||
g_Vars.players[index]->dostartnewlife = false;
|
||||
|
||||
#ifndef PLATFORM_N64
|
||||
g_Vars.players[index]->client = NULL;
|
||||
g_Vars.players[index]->ucmd = (g_NetMode == NETMODE_SERVER) ? UCMD_FL_FORCEMASK : 0;
|
||||
g_Vars.players[index]->isremote = false;
|
||||
#endif
|
||||
|
||||
g_Vars.bondvisible = true;
|
||||
g_Vars.bondcollisions = true;
|
||||
}
|
||||
@@ -806,6 +833,14 @@ void playermgrShuffle(void)
|
||||
g_Vars.playerorder[i] = i;
|
||||
}
|
||||
|
||||
#ifndef PLATFORM_N64
|
||||
if (g_NetMode) {
|
||||
// don't shuffle in netgames
|
||||
// why is this a thing anyway?
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Randomly swap numbers with later elements
|
||||
for (i = 0; i < MAX_PLAYERS - 1; i++) {
|
||||
s32 otherindex = rngRandom() % (MAX_PLAYERS - i);
|
||||
|
||||
@@ -148,6 +148,12 @@ void playerReset(void)
|
||||
g_PlayersWithControl[1] = true;
|
||||
g_PlayersWithControl[2] = true;
|
||||
g_PlayersWithControl[3] = true;
|
||||
#if MAX_PLAYERS > 4
|
||||
g_PlayersWithControl[4] = true;
|
||||
g_PlayersWithControl[5] = true;
|
||||
g_PlayersWithControl[6] = true;
|
||||
g_PlayersWithControl[7] = true;
|
||||
#endif
|
||||
g_PlayerInvincible = false;
|
||||
|
||||
playerSetTickMode(TICKMODE_GE_FADEIN);
|
||||
@@ -180,7 +186,8 @@ void playerReset(void)
|
||||
cmd = (struct cmd32 *)((uintptr_t)cmd + 8);
|
||||
break;
|
||||
case INTROCMD_WEAPON:
|
||||
if (cmd->param3 == 0 && g_Vars.currentplayer != g_Vars.anti) {
|
||||
if (cmd->param3 == 0 && PLAYER_IS_NOT_ANTI(g_Vars.currentplayer)) {
|
||||
|
||||
modelmgrLoadProjectileModeldefs(cmd->param1);
|
||||
|
||||
if (cmd->param2 >= 0) {
|
||||
@@ -207,7 +214,7 @@ void playerReset(void)
|
||||
cmd = (struct cmd32 *)((uintptr_t)cmd + 16);
|
||||
break;
|
||||
case INTROCMD_AMMO:
|
||||
if (cmd->param3 == 0 && g_Vars.currentplayer != g_Vars.anti) {
|
||||
if (cmd->param3 == 0 && PLAYER_IS_NOT_ANTI(g_Vars.currentplayer)) {
|
||||
bgunSetAmmoQuantity(cmd->param1, cmd->param2);
|
||||
}
|
||||
cmd = (struct cmd32 *)((uintptr_t)cmd + 16);
|
||||
|
||||
+34
-16
@@ -39,6 +39,10 @@
|
||||
#include "lib/lib_317f0.h"
|
||||
#include "data.h"
|
||||
#include "types.h"
|
||||
#ifndef PLATFORM_N64
|
||||
#include "net/net.h"
|
||||
#include "net/netmsg.h"
|
||||
#endif
|
||||
|
||||
s16 *g_RoomPropListChunkIndexes;
|
||||
struct roomproplistchunk *g_RoomPropListChunks;
|
||||
@@ -167,6 +171,10 @@ struct prop *propAllocate(void)
|
||||
prop->propupdate60err = 2;
|
||||
prop->opawallhits = NULL;
|
||||
prop->xluwallhits = NULL;
|
||||
#ifndef PLATFORM_N64
|
||||
// NOTE: this will be automatically overwritten at the start of the stage for the setup props
|
||||
prop->syncid = (g_NetMode == NETMODE_SERVER) ? g_NetNextSyncId++ : 0;
|
||||
#endif
|
||||
g_Vars.propstates[prop->propstateindex].propcount++;
|
||||
|
||||
g_Vars.allocstateindex++;
|
||||
@@ -199,6 +207,9 @@ void propFree(struct prop *prop)
|
||||
prop->prev = NULL;
|
||||
prop->chr = NULL;
|
||||
prop->rooms[0] = -1;
|
||||
#ifndef PLATFORM_N64
|
||||
prop->syncid = 0;
|
||||
#endif
|
||||
g_Vars.freeprops = prop;
|
||||
}
|
||||
|
||||
@@ -983,7 +994,7 @@ struct prop *shotCalculateHits(s32 handnum, bool isshooting, struct coord *gunpo
|
||||
bool shotTestLos(struct coord *gunpos2d, struct coord *gundir2d, struct coord *gunpos3d, struct coord *gundir3d, struct coord *endpos3d)
|
||||
{
|
||||
struct prop **propptr;
|
||||
struct hitthing hitthing;
|
||||
struct hitthing sp664;
|
||||
struct coord delta;
|
||||
struct shotdata shotdata;
|
||||
s32 i;
|
||||
@@ -992,8 +1003,6 @@ bool shotTestLos(struct coord *gunpos2d, struct coord *gundir2d, struct coord *g
|
||||
RoomNum spb8[8];
|
||||
RoomNum *roomsptr;
|
||||
struct prop *prop;
|
||||
s16 texturenum;
|
||||
u32 surfacetype;
|
||||
|
||||
shotdata.gunpos3d.x = gunpos3d->x;
|
||||
shotdata.gunpos3d.y = gunpos3d->y;
|
||||
@@ -1042,11 +1051,11 @@ bool shotTestLos(struct coord *gunpos2d, struct coord *gundir2d, struct coord *g
|
||||
|
||||
// Check for BG hits first
|
||||
for (i = 0; rooms[i] != -1; i++) {
|
||||
if (bgTestHitInRoom(&shotdata.gunpos3d, endpos3d, rooms[i], &hitthing)) {
|
||||
if (bgTestHitInRoom(&shotdata.gunpos3d, endpos3d, rooms[i], &sp664)) {
|
||||
// check if it's far enough away from the end point
|
||||
if (fabsf(hitthing.pos.x - endpos3d->x) >= 0.1f ||
|
||||
fabsf(hitthing.pos.y - endpos3d->y) >= 0.1f ||
|
||||
fabsf(hitthing.pos.z - endpos3d->z) >= 0.1f) {
|
||||
if (fabsf(sp664.pos.x - endpos3d->x) >= 0.1f ||
|
||||
fabsf(sp664.pos.y - endpos3d->y) >= 0.1f ||
|
||||
fabsf(sp664.pos.z - endpos3d->z) >= 0.1f) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1064,22 +1073,17 @@ bool shotTestLos(struct coord *gunpos2d, struct coord *gundir2d, struct coord *g
|
||||
prop = *propptr;
|
||||
if (prop) {
|
||||
if (prop->type == PROPTYPE_CHR
|
||||
|| (prop->type == PROPTYPE_PLAYER && prop->chr && (g_Vars.in_cutscene || playermgrGetPlayerNumByProp(prop) != g_Vars.currentplayernum
|
||||
|| g_Vars.currentplayer->eyespy && g_Vars.currentplayer->eyespy->mode == EYESPYMODE_CAMSPY))) {
|
||||
|| (prop->type == PROPTYPE_PLAYER && prop->chr && (g_Vars.in_cutscene || playermgrGetPlayerNumByProp(prop) != g_Vars.currentplayernum))) {
|
||||
chrTestHit(prop, &shotdata, false, true);
|
||||
} else if (prop->type == PROPTYPE_WEAPON || (prop->type == PROPTYPE_DOOR && ((struct doorobj *)prop->obj)->doortype != DOORTYPE_LASER)
|
||||
} else if (prop->type == PROPTYPE_WEAPON || prop->type == PROPTYPE_DOOR
|
||||
|| (prop->type == PROPTYPE_OBJ && prop->obj->type != OBJTYPE_GLASS && prop->obj->type != OBJTYPE_TINTEDGLASS)) {
|
||||
objTestHit(prop, &shotdata);
|
||||
}
|
||||
if (shotdata.hits[0].prop) {
|
||||
texturenum = (prop->type == PROPTYPE_CHR || prop->type == PROPTYPE_PLAYER) ? -1 : shotdata.hits[0].hitthing.texturenum;
|
||||
surfacetype = (texturenum >= 0 && texturenum < NUM_TEXTURES) ? g_Textures[texturenum].surfacetype : SURFACETYPE_DEFAULT;
|
||||
// ignore some glass parts and shields
|
||||
if (shotdata.hits[0].slowsbullet && texturenum != 10000 &&
|
||||
surfacetype != SURFACETYPE_GLASS && surfacetype != SURFACETYPE_GLASSXLU) {
|
||||
if (shotdata.hits[0].slowsbullet && shotdata.hits[0].hitthing.texturenum != 10000) {
|
||||
return false;
|
||||
}
|
||||
shotdata.hits[0].prop = NULL;
|
||||
}
|
||||
}
|
||||
propptr--;
|
||||
@@ -1622,6 +1626,13 @@ bool currentPlayerInteract(bool eyespy)
|
||||
prop = propFindForInteract(eyespy);
|
||||
|
||||
if (prop) {
|
||||
#ifndef PLATFORM_N64
|
||||
// if we aren't the authority, don't do anything
|
||||
if (g_NetMode == NETMODE_CLIENT) {
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
switch (prop->type) {
|
||||
case PROPTYPE_OBJ:
|
||||
case PROPTYPE_WEAPON:
|
||||
@@ -1640,6 +1651,12 @@ bool currentPlayerInteract(bool eyespy)
|
||||
|
||||
propExecuteTickOperation(prop, op);
|
||||
|
||||
#ifndef PLATFORM_N64
|
||||
if (g_NetMode == NETMODE_SERVER) {
|
||||
netmsgSvcPropUseWrite(&g_NetMsgRel, prop, g_Vars.currentplayer->client, op);
|
||||
}
|
||||
#endif
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -2456,7 +2473,8 @@ void propsTestForPickup(void)
|
||||
|
||||
if (g_Vars.currentplayer->bondmovemode != MOVEMODE_CUTSCENE
|
||||
&& !g_PlayerInvincible
|
||||
&& g_Vars.currentplayer != g_Vars.anti) {
|
||||
&& PLAYER_IS_NOT_ANTI(g_Vars.currentplayer)
|
||||
) {
|
||||
roomsCopy(g_Vars.currentplayer->prop->rooms, allrooms);
|
||||
|
||||
for (i = 0; g_Vars.currentplayer->prop->rooms[i] != -1; i++) {
|
||||
|
||||
+145
-25
@@ -77,6 +77,10 @@
|
||||
#include "textures.h"
|
||||
#include "types.h"
|
||||
#include "string.h"
|
||||
#ifndef PLATFORM_N64
|
||||
#include "net/net.h"
|
||||
#include "net/netmsg.h"
|
||||
#endif
|
||||
|
||||
void rng2SetSeed(u32 seed);
|
||||
|
||||
@@ -155,6 +159,13 @@ bool doorCallLift(struct prop *doorprop, bool allowclose)
|
||||
struct doorobj *door = doorprop->door;
|
||||
bool handled = false;
|
||||
|
||||
#ifndef PLATFORM_N64
|
||||
if (g_NetMode == NETMODE_CLIENT) {
|
||||
// don't automatically do anything with lifts
|
||||
return handled;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (door->base.hidden & OBJHFLAG_LIFTDOOR) {
|
||||
struct linkliftdoorobj *link = g_LiftDoors;
|
||||
|
||||
@@ -5094,6 +5105,11 @@ void liftGoToStop(struct liftobj *lift, s32 stopnum)
|
||||
// Sanity check to make sure lift is actually not moving
|
||||
if (lift->dist == 0 && lift->speed == 0) {
|
||||
lift->levelaim = stopnum;
|
||||
#ifndef PLATFORM_N64
|
||||
if (g_NetMode == NETMODE_SERVER) {
|
||||
netmsgSvcPropLiftWrite(&g_NetMsgRel, lift->base.prop);
|
||||
}
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -5140,6 +5156,12 @@ void liftGoToStop(struct liftobj *lift, s32 stopnum)
|
||||
lift->speed = -lift->speed;
|
||||
lift->levelaim = stopnum;
|
||||
}
|
||||
|
||||
#ifndef PLATFORM_N64
|
||||
if (g_NetMode == NETMODE_SERVER) {
|
||||
netmsgSvcPropLiftWrite(&g_NetMsgRel, lift->base.prop);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6666,6 +6688,12 @@ s32 projectileTick(struct defaultobj *obj, bool *embedded)
|
||||
}
|
||||
|
||||
if (projectile->speed.f[0] == 0.0f && projectile->speed.f[2] == 0.0f && projectile->unk0dc == 0.0f) {
|
||||
#ifndef PLATFORM_N64
|
||||
if (g_NetMode == NETMODE_SERVER) {
|
||||
// sliding object has stopped, sync the final position just in case
|
||||
netmsgSvcPropMoveWrite(&g_NetMsgRel, prop, NULL);
|
||||
}
|
||||
#endif
|
||||
objFreeProjectile(obj);
|
||||
}
|
||||
|
||||
@@ -8126,6 +8154,13 @@ void liftTick(struct prop *prop)
|
||||
stop = (stop + 1) % 4;
|
||||
} while (lift->pads[stop] < 0);
|
||||
|
||||
#ifndef PLATFORM_N64
|
||||
if (g_NetMode == NETMODE_CLIENT) {
|
||||
// don't start if we're not the authority
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
liftGoToStop(lift, stop);
|
||||
}
|
||||
}
|
||||
@@ -9128,7 +9163,7 @@ void autogunTickShoot(struct prop *autogunprop)
|
||||
// (ie. autogun is a Defense autogun or a thrown laptop)
|
||||
if (g_Vars.normmplayerisrunning
|
||||
|| (targetprop && (targetprop->type == PROPTYPE_CHR))
|
||||
|| (g_Vars.antiplayernum >= 0 && targetprop && targetprop == g_Vars.anti->prop)) {
|
||||
|| (g_Vars.antiplayernum >= 0 && targetprop && PROP_IS_FOR_ANTI_PLAYER(targetprop))) {
|
||||
if (cdExamLos08(&gunpos, gunrooms, &hitpos, CDTYPE_ALL, GEOFLAG_BLOCK_SHOOT) == CDRESULT_COLLISION) {
|
||||
#if VERSION >= VERSION_PAL_FINAL
|
||||
cdGetPos(&hitpos, 11480, "prop/propobj.c");
|
||||
@@ -11005,7 +11040,7 @@ s32 objTickPlayer(struct prop *prop)
|
||||
|
||||
if (obj->hidden & OBJHFLAG_ISRETICK) {
|
||||
obj->hidden &= ~OBJHFLAG_ISRETICK;
|
||||
} else if ((obj->hidden & OBJHFLAG_PROJECTILE) && (obj->projectile->flags & PROJECTILEFLAG_SLIDING) == 0) {
|
||||
} else if ((obj->hidden & OBJHFLAG_PROJECTILE) && obj->projectile && (obj->projectile->flags & PROJECTILEFLAG_SLIDING) == 0) {
|
||||
prop->flags &= ~PROPFLAG_ONTHISSCREENTHISTICK;
|
||||
obj->hidden |= OBJHFLAG_ISRETICK;
|
||||
return TICKOP_RETICK;
|
||||
@@ -14217,6 +14252,12 @@ void objBounce(struct defaultobj *obj, struct coord *gundir2d)
|
||||
projectile->speed.z += 3.3333333f * dir.z;
|
||||
projectile->ownerprop = g_Vars.currentplayer->prop;
|
||||
projectile->bouncecount = 1;
|
||||
|
||||
#ifndef PLATFORM_N64
|
||||
if (g_NetMode == NETMODE_SERVER) {
|
||||
netmsgSvcPropMoveWrite(&g_NetMsgRel, obj->prop, &rot);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14294,6 +14335,11 @@ void objApplyMomentum(struct defaultobj *obj, struct coord *speed, f32 rotation,
|
||||
projectile->unk0ec = 0.07852732f;
|
||||
projectile->unk0f0 = 6.6666665f;
|
||||
}
|
||||
#ifndef PLATFORM_N64
|
||||
if (g_NetMode == NETMODE_SERVER) {
|
||||
netmsgSvcPropMoveWrite(&g_NetMsgRel, obj->prop, NULL);
|
||||
}
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -14324,6 +14370,12 @@ void objApplyMomentum(struct defaultobj *obj, struct coord *speed, f32 rotation,
|
||||
projectile->unk0ec = 0.07852732f;
|
||||
projectile->unk0f0 = 1.6666666f;
|
||||
}
|
||||
|
||||
#ifndef PLATFORM_N64
|
||||
if (g_NetMode == NETMODE_SERVER) {
|
||||
netmsgSvcPropMoveWrite(&g_NetMsgRel, obj->prop, NULL);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15363,6 +15415,23 @@ void objTakeGunfire(struct defaultobj *obj, f32 damage, struct coord *pos, s32 w
|
||||
|
||||
void objDamage(struct defaultobj *obj, f32 damage, struct coord *pos, s32 weaponnum, s32 playernum)
|
||||
{
|
||||
#ifndef PLATFORM_N64
|
||||
// if we aren't the authority, don't do anything, unless called from netmsg handler
|
||||
if (g_NetMode == NETMODE_CLIENT) {
|
||||
if (damage < 0.f) {
|
||||
// HACK: negative damage means we were called from netmsg.c
|
||||
damage = -damage;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
} else if (g_NetMode == NETMODE_SERVER) {
|
||||
if (obj->prop && obj->prop->type != PROPTYPE_CHR) {
|
||||
// chr damage is handled by a separate message
|
||||
netmsgSvcPropDamageWrite(&g_NetMsgRel, obj->prop, damage, pos, weaponnum, playernum);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// Store the attacker playernum into the object's "hidden" field
|
||||
#if VERSION >= VERSION_NTSC_1_0
|
||||
// ...but not for deployed laptop guns in multiplayer, because those bits
|
||||
@@ -15893,7 +15962,10 @@ void objHit(struct shotdata *shotdata, struct hit *hit)
|
||||
}
|
||||
}
|
||||
|
||||
if (g_Vars.antiplayernum < 0 || g_Vars.currentplayer != g_Vars.anti || (obj->flags2 & OBJFLAG2_IMMUNETOANTI) == 0) {
|
||||
if (g_Vars.antiplayernum < 0
|
||||
|| PLAYER_IS_NOT_ANTI(g_Vars.currentplayer)
|
||||
|| (obj->flags2 & OBJFLAG2_IMMUNETOANTI) == 0) {
|
||||
|
||||
if (hit->hitthing.texturenum != 10000) {
|
||||
f32 damage = gsetGetDamage(&shotdata->gset);
|
||||
|
||||
@@ -15950,6 +16022,10 @@ void objHit(struct shotdata *shotdata, struct hit *hit)
|
||||
pushdir.y = shotdata->gundir3d.y;
|
||||
pushdir.z = shotdata->gundir3d.z;
|
||||
|
||||
#ifndef PLATFORM_N64
|
||||
// don't push anything if we're not the authority
|
||||
if (g_NetMode != NETMODE_CLIENT)
|
||||
#endif
|
||||
func0f082e84(obj, &spa4, &pushdir, &spb0, true);
|
||||
} else {
|
||||
bool bounce = false;
|
||||
@@ -15972,6 +16048,13 @@ void objHit(struct shotdata *shotdata, struct hit *hit)
|
||||
bounce = false;
|
||||
}
|
||||
|
||||
#ifndef PLATFORM_N64
|
||||
// don't bounce anything if we're not the authority
|
||||
if (g_NetMode == NETMODE_CLIENT) {
|
||||
bounce = false;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (bounce) {
|
||||
objBounce(obj, &shotdata->gundir2d);
|
||||
}
|
||||
@@ -16830,7 +16913,7 @@ void ammotypePlayPickupSound(u32 ammotype)
|
||||
case AMMOTYPE_CLOAK:
|
||||
case AMMOTYPE_BOOST:
|
||||
case AMMOTYPE_TOKEN:
|
||||
sndStart(var80095200, SFX_PICKUP_AMMO, NULL, -1, -1, -1, -1, -1);
|
||||
playerSndStart(var80095200, SFX_PICKUP_AMMO, NULL, g_Vars.currentplayernum, -1, -1, -1);
|
||||
break;
|
||||
case AMMOTYPE_REMOTE_MINE:
|
||||
case AMMOTYPE_PROXY_MINE:
|
||||
@@ -16839,10 +16922,10 @@ void ammotypePlayPickupSound(u32 ammotype)
|
||||
case AMMOTYPE_MICROCAMERA:
|
||||
case AMMOTYPE_PLASTIQUE:
|
||||
case AMMOTYPE_ECM_MINE:
|
||||
sndStart(var80095200, SFX_PICKUP_MINE, NULL, -1, -1, -1, -1, -1);
|
||||
playerSndStart(var80095200, SFX_PICKUP_MINE, NULL, g_Vars.currentplayernum, -1, -1, -1);
|
||||
break;
|
||||
case AMMOTYPE_KNIFE:
|
||||
sndStart(var80095200, SFX_PICKUP_KNIFE, NULL, -1, -1, -1, -1, -1);
|
||||
playerSndStart(var80095200, SFX_PICKUP_KNIFE, NULL, g_Vars.currentplayernum, -1, -1, -1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -16907,7 +16990,7 @@ void weaponPlayPickupSound(s32 weaponnum)
|
||||
sound = SFX_PICKUP_GUN;
|
||||
}
|
||||
|
||||
sndStart(var80095200, sound, NULL, -1, -1, -1, -1, -1);
|
||||
playerSndStart(var80095200, sound, NULL, g_Vars.currentplayernum, -1, -1, -1);
|
||||
}
|
||||
|
||||
void ammotypeGetPickupMessage(char *dst, s32 ammotype, s32 qty)
|
||||
@@ -17201,12 +17284,6 @@ void currentPlayerQueuePickupWeaponHudmsg(u32 weaponnum, bool dual)
|
||||
{
|
||||
char buffer[100] = "";
|
||||
|
||||
// Suppress pickup HUD during cutscenes
|
||||
if (g_Vars.in_cutscene)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
weaponGetPickupText(buffer, weaponnum, dual);
|
||||
hudmsgCreateWithFlags(buffer, HUDMSGTYPE_DEFAULT, HUDMSGFLAG_ONLYIFALIVE | HUDMSGFLAG_ALLOWDUPES);
|
||||
}
|
||||
@@ -17223,17 +17300,10 @@ s32 propPickupByPlayer(struct prop *prop, bool showhudmsg)
|
||||
return TICKOP_NONE;
|
||||
}
|
||||
|
||||
// Suppress HUD pickup messages during cutscenes (e.g. items given at
|
||||
// mission start via aiGiveObjectToChr)
|
||||
if (g_Vars.in_cutscene)
|
||||
{
|
||||
showhudmsg = false;
|
||||
}
|
||||
|
||||
switch (obj->type) {
|
||||
case OBJTYPE_KEY:
|
||||
if (g_Vars.in_cutscene == false) {
|
||||
sndStart(var80095200, SFX_PICKUP_KEYCARD, NULL, -1, -1, -1, -1, -1);
|
||||
playerSndStart(var80095200, SFX_PICKUP_KEYCARD, NULL, g_Vars.currentplayernum, -1, -1, -1);
|
||||
}
|
||||
|
||||
if (showhudmsg) {
|
||||
@@ -17273,7 +17343,7 @@ s32 propPickupByPlayer(struct prop *prop, bool showhudmsg)
|
||||
}
|
||||
|
||||
if (g_Vars.in_cutscene == false) {
|
||||
sndStart(var80095200, SFX_PICKUP_AMMO, NULL, -1, -1, -1, -1, -1);
|
||||
playerSndStart(var80095200, SFX_PICKUP_AMMO, NULL, g_Vars.currentplayernum, -1, -1, -1);
|
||||
}
|
||||
|
||||
result = TICKOP_FREE;
|
||||
@@ -17293,6 +17363,11 @@ s32 propPickupByPlayer(struct prop *prop, bool showhudmsg)
|
||||
|
||||
if (sp64) {
|
||||
weaponPlayPickupSound(weapon->weaponnum);
|
||||
#ifndef PLATFORM_N64
|
||||
if (g_NetMode == NETMODE_SERVER && g_Vars.currentplayer->client) {
|
||||
netmsgSvcPropPickupWrite(&g_NetMsgRel, g_Vars.currentplayer->client, prop, sp64);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
return sp64;
|
||||
@@ -17303,6 +17378,11 @@ s32 propPickupByPlayer(struct prop *prop, bool showhudmsg)
|
||||
|
||||
if (sp64) {
|
||||
weaponPlayPickupSound(weapon->weaponnum);
|
||||
#ifndef PLATFORM_N64
|
||||
if (g_NetMode == NETMODE_SERVER && g_Vars.currentplayer->client) {
|
||||
netmsgSvcPropPickupWrite(&g_NetMsgRel, g_Vars.currentplayer->client, prop, sp64);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
return sp64;
|
||||
@@ -17416,7 +17496,7 @@ s32 propPickupByPlayer(struct prop *prop, bool showhudmsg)
|
||||
playerSetShieldFrac(((struct shieldobj *) prop->obj)->amount);
|
||||
|
||||
if (!g_Vars.in_cutscene) {
|
||||
sndStart(var80095200, SFX_PICKUP_SHIELD, NULL, -1, -1, -1, -1, -1);
|
||||
playerSndStart(var80095200, SFX_PICKUP_SHIELD, NULL, g_Vars.currentplayernum, -1, -1, -1);
|
||||
}
|
||||
|
||||
if (showhudmsg) {
|
||||
@@ -17453,7 +17533,7 @@ s32 propPickupByPlayer(struct prop *prop, bool showhudmsg)
|
||||
case OBJTYPE_TINTEDGLASS:
|
||||
default:
|
||||
if (g_Vars.in_cutscene == false) {
|
||||
sndStart(var80095200, SFX_PICKUP_KEYCARD, NULL, -1, -1, -1, -1, -1);
|
||||
playerSndStart(var80095200, SFX_PICKUP_KEYCARD, NULL, g_Vars.currentplayernum, -1, -1, -1);
|
||||
}
|
||||
|
||||
if (showhudmsg) {
|
||||
@@ -17470,6 +17550,13 @@ s32 propPickupByPlayer(struct prop *prop, bool showhudmsg)
|
||||
break;
|
||||
}
|
||||
|
||||
#ifndef PLATFORM_N64
|
||||
if (result != TICKOP_NONE && g_NetMode == NETMODE_SERVER && g_Vars.currentplayer->client) {
|
||||
netmsgSvcPropPickupWrite(&g_NetMsgRel, g_Vars.currentplayer->client, prop, result);
|
||||
netmsgSvcPlayerStatsWrite(&g_NetMsgRel, g_Vars.currentplayer->client);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (result == TICKOP_FREE && (obj->hidden & OBJHFLAG_TAGGED) == 0) {
|
||||
objFree(obj, false, obj->hidden2 & OBJH2FLAG_CANREGEN);
|
||||
return TICKOP_FREE;
|
||||
@@ -17494,6 +17581,13 @@ s32 objTestForPickup(struct prop *prop)
|
||||
return TICKOP_NONE;
|
||||
}
|
||||
|
||||
#ifndef PLATFORM_N64
|
||||
// if we aren't the authority, don't do anything
|
||||
if (g_NetMode == NETMODE_CLIENT) {
|
||||
return TICKOP_NONE;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (func0f085194(obj) && obj->type != OBJTYPE_HAT) {
|
||||
if (obj->flags & OBJFLAG_UNCOLLECTABLE) {
|
||||
return TICKOP_NONE;
|
||||
@@ -19079,6 +19173,13 @@ void doorsCheckAutomatic(void)
|
||||
s16 *propnumptr;
|
||||
s16 propnums[256];
|
||||
|
||||
#ifndef PLATFORM_N64
|
||||
if (g_NetMode == NETMODE_CLIENT) {
|
||||
// don't do anything if we're not the authority
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
roomGetProps(g_Vars.currentplayer->prop->rooms, propnums, 256);
|
||||
propnumptr = propnums;
|
||||
|
||||
@@ -19855,6 +19956,11 @@ void doorSetMode(struct doorobj *door, s32 newmode)
|
||||
} else {
|
||||
door->mode = newmode;
|
||||
}
|
||||
#ifndef PLATFORM_N64
|
||||
if (g_NetMode == NETMODE_SERVER) {
|
||||
netmsgSvcPropDoorWrite(&g_NetMsgRel, door->base.prop, g_Vars.currentplayer->client);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -20965,7 +21071,7 @@ Gfx *countdownTimerRender(Gfx *gdl)
|
||||
u32 stack;
|
||||
s32 viewright = viGetViewLeft() + (viGetViewWidth() >> 1);
|
||||
s32 y = viGetViewTop() + viGetViewHeight() - 18;
|
||||
s32 playercount = PLAYERCOUNT();
|
||||
s32 playercount = LOCALPLAYERCOUNT();
|
||||
char *fmt = ":\n";
|
||||
|
||||
if (playercount == 2) {
|
||||
@@ -21220,6 +21326,13 @@ void weaponCreateForPlayerDrop(s32 weaponnum)
|
||||
struct chrdata *chr;
|
||||
u32 stack2;
|
||||
|
||||
#ifndef PLATFORM_N64
|
||||
// don't do anything if we're not the authority
|
||||
if (g_NetMode == NETMODE_CLIENT) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
chr = g_Vars.currentplayer->prop->chr;
|
||||
prop = weaponCreateForChr(chr, playermgrGetModelOfWeapon(weaponnum), weaponnum, OBJFLAG_WEAPON_AICANNOTUSE, NULL, NULL);
|
||||
|
||||
@@ -21230,6 +21343,13 @@ void weaponCreateForPlayerDrop(s32 weaponnum)
|
||||
if (weaponnum == WEAPON_BRIEFCASE2) {
|
||||
scenarioHandleDroppedToken(chr, prop);
|
||||
}
|
||||
|
||||
#ifndef PLATFORM_N64
|
||||
if (g_NetMode == NETMODE_SERVER) {
|
||||
netmsgSvcPropSpawnWrite(&g_NetMsgRel, prop);
|
||||
netmsgSvcPropMoveWrite(&g_NetMsgRel, prop, NULL);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+10
-5
@@ -338,7 +338,7 @@ void psTickChannel(s32 channelnum)
|
||||
|
||||
if (lvIsPaused()
|
||||
|| (mpIsPaused() && (channel->flags2 & PSFLAG2_MPPAUSABLE))
|
||||
|| (mpIsPaused() && PLAYERCOUNT() == 1)) {
|
||||
|| (mpIsPaused() && LOCALPLAYERCOUNT() == 1)) {
|
||||
channel->currentvol = -1;
|
||||
newvol = 0;
|
||||
}
|
||||
@@ -1171,7 +1171,7 @@ s32 psCalculateVol(struct coord *pos, f32 dist1, f32 dist2, f32 dist3, RoomNum *
|
||||
}
|
||||
|
||||
// Figure out which player is closest and store their distance in playerdist
|
||||
for (i = 0; i < PLAYERCOUNT(); i++) {
|
||||
for (i = 0; i < LOCALPLAYERCOUNT(); i++) {
|
||||
struct player *player = g_Vars.players[i];
|
||||
s32 camroom;
|
||||
|
||||
@@ -1283,12 +1283,17 @@ s32 psCalculatePan2(struct coord *pos, s32 arg1, f32 arg2, struct pschannel *cha
|
||||
s32 degrees;
|
||||
f32 f2;
|
||||
|
||||
if (PLAYERCOUNT() < 2) {
|
||||
struct coord *campos = &g_Vars.currentplayer->cam_pos;
|
||||
if (LOCALPLAYERCOUNT() < 2) {
|
||||
#ifdef PLATFORM_N64
|
||||
struct player *player = g_Vars.currentplayer;
|
||||
#else
|
||||
struct player *player = g_Vars.players[0] ? g_Vars.players[0] : g_Vars.currentplayer;
|
||||
#endif
|
||||
struct coord *campos = &player->cam_pos;
|
||||
f32 sp3c;
|
||||
f32 sp38;
|
||||
|
||||
f2 = -(atan2f(pos->x - campos->x, pos->z - campos->z) * 180.0f / M_PI + g_Vars.currentplayer->vv_theta);
|
||||
f2 = -(atan2f(pos->x - campos->x, pos->z - campos->z) * 180.0f / M_PI + player->vv_theta);
|
||||
|
||||
if (arg2 >= 0.0f) {
|
||||
sp3c = sinf(0.017453292f * f2);
|
||||
|
||||
+2
-2
@@ -252,7 +252,7 @@ Gfx *radarRender(Gfx *gdl)
|
||||
|
||||
tconfig = g_TexRadarConfigs;
|
||||
playernum = g_Vars.currentplayernum;
|
||||
playercount = PLAYERCOUNT();
|
||||
playercount = LOCALPLAYERCOUNT();
|
||||
|
||||
if (g_Vars.mplayerisrunning) {
|
||||
if (g_Vars.normmplayerisrunning && (g_MpSetup.options & MPOPTION_NORADAR)) {
|
||||
@@ -341,7 +341,7 @@ Gfx *radarRender(Gfx *gdl)
|
||||
gDPSetSubpixelOffsetEXT(gdl++, 0, 0);
|
||||
if (!(g_MpSetup.options & MPOPTION_NOPLAYERONRADAR)) {
|
||||
#endif
|
||||
for (i = 0; i < playercount; i++) {
|
||||
for (i = 0; i < PLAYERCOUNT(); i++) {
|
||||
if (i != playernum) {
|
||||
if (g_Vars.players[i]->isdead == false
|
||||
&& (g_Vars.players[i]->prop->chr->hidden & CHRHFLAG_CLOAKED) == 0
|
||||
|
||||
@@ -12,7 +12,17 @@ void roomsReset(void)
|
||||
{
|
||||
s32 i;
|
||||
|
||||
#if MAX_PLAYERS > 4
|
||||
if (PLAYERCOUNT() > 4) {
|
||||
g_RoomMtxNumSlots = 400;
|
||||
} else if (PLAYERCOUNT() > 2) {
|
||||
g_RoomMtxNumSlots = 200;
|
||||
} else {
|
||||
g_RoomMtxNumSlots = 120;
|
||||
}
|
||||
#else
|
||||
g_RoomMtxNumSlots = PLAYERCOUNT() >= 2 ? 200 : 120;
|
||||
#endif
|
||||
|
||||
g_RoomMtxAges = mempAlloc(ALIGN16(g_RoomMtxNumSlots), MEMPOOL_STAGE);
|
||||
g_RoomMtxLinkedRooms = mempAlloc(ALIGN16(g_RoomMtxNumSlots * sizeof(*g_RoomMtxLinkedRooms)), MEMPOOL_STAGE);
|
||||
|
||||
+4
-56
@@ -1400,14 +1400,6 @@ void setupLoadFiles(s32 stagenum)
|
||||
numobjs += g_Vars.numaibuddies; // the buddy's weapon
|
||||
}
|
||||
|
||||
#ifndef PLATFORM_N64
|
||||
// Kept corpses hold on to their slots, so reserve extra ones for spawned chrs and their weapons
|
||||
if (!g_Vars.normmplayerisrunning) {
|
||||
numchrs += g_MaxCorpses < 0 ? MAX_CORPSES_LIMIT : g_MaxCorpses;
|
||||
numobjs += g_MaxCorpses < 0 ? MAX_CORPSES_LIMIT : g_MaxCorpses;
|
||||
}
|
||||
#endif
|
||||
|
||||
numobjs += setupCountCommandType(OBJTYPE_WEAPON);
|
||||
numobjs += setupCountCommandType(OBJTYPE_KEY);
|
||||
numobjs += setupCountCommandType(OBJTYPE_HAT);
|
||||
@@ -1468,34 +1460,6 @@ void setupLoadFiles(s32 stagenum)
|
||||
g_Vars.maxprops = numobjs + numchrs + extra + 40;
|
||||
}
|
||||
|
||||
static void setupMarkLiftDoors()
|
||||
{
|
||||
s32 index = 0;
|
||||
|
||||
struct defaultobj *obj = (struct defaultobj *)g_StageSetup.props;
|
||||
while (obj->type != OBJTYPE_END) {
|
||||
if (obj->type == OBJTYPE_LIFT) {
|
||||
struct liftobj *lift = (struct liftobj *)obj;
|
||||
for (int i = 0; i < ARRAYCOUNT(lift->doors); i++) {
|
||||
if (lift->doors[i]) {
|
||||
s32 doorindex = index + *(s32*)&lift->doors[i];
|
||||
struct doorobj *door = (struct doorobj *)setupGetCmdByIndex(doorindex);
|
||||
// we use this 'extra1' field here to mark the door, since its not used anywhere else
|
||||
door->extra1 = 1;
|
||||
|
||||
if (door->sibling) {
|
||||
s32 siblingidx = *(s32 *) &door->sibling + doorindex;
|
||||
struct doorobj *sibling = (struct doorobj *) setupGetCmdByIndex(siblingidx);
|
||||
sibling->extra1 = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
obj = (struct defaultobj *) ((u32 *) obj + setupGetCmdLength((u32 *) obj));
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
||||
void setupCreateProps(s32 stagenum)
|
||||
{
|
||||
s32 withchrs = !argFindByPrefix(1, "-nochr") && !argFindByPrefix(1, "-noprop");
|
||||
@@ -1539,12 +1503,6 @@ void setupCreateProps(s32 stagenum)
|
||||
numchrs += g_Vars.numaibuddies;
|
||||
}
|
||||
|
||||
#ifndef PLATFORM_N64
|
||||
if (!g_Vars.normmplayerisrunning) {
|
||||
numchrs += g_MaxCorpses < 0 ? MAX_CORPSES_LIMIT : g_MaxCorpses;
|
||||
}
|
||||
#endif
|
||||
|
||||
chrmgrConfigure(numchrs);
|
||||
} else {
|
||||
chrmgrConfigure(0);
|
||||
@@ -1574,12 +1532,6 @@ void setupCreateProps(s32 stagenum)
|
||||
botmgrRemoveAll();
|
||||
index = 0;
|
||||
|
||||
bool nodoors = (g_MpSetup.options & MPOPTION_NODOORS) != 0;
|
||||
|
||||
if (nodoors) {
|
||||
setupMarkLiftDoors();
|
||||
}
|
||||
|
||||
obj = (struct defaultobj *)g_StageSetup.props;
|
||||
|
||||
while (obj->type != OBJTYPE_END) {
|
||||
@@ -1600,15 +1552,11 @@ void setupCreateProps(s32 stagenum)
|
||||
bodyAllocateChr(stagenum, (struct packedchr *) obj, index);
|
||||
}
|
||||
break;
|
||||
case OBJTYPE_DOOR: {
|
||||
struct doorobj *door = (struct doorobj *) obj;
|
||||
// dont skip doors that are locked or are lift doors
|
||||
bool skipdoor = nodoors && g_Vars.normmplayerisrunning && door->keyflags == 0 && door->extra1 == 0;
|
||||
if (!skipdoor && withobjs && (obj->flags2 & diffflag) == 0) {
|
||||
setupCreateDoor(door, index);
|
||||
case OBJTYPE_DOOR:
|
||||
if (withobjs && (obj->flags2 & diffflag) == 0) {
|
||||
setupCreateDoor((struct doorobj *)obj, index);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case OBJTYPE_DOORSCALE:
|
||||
{
|
||||
struct doorscaleobj *scale = (struct doorscaleobj *)obj;
|
||||
@@ -2125,7 +2073,7 @@ void setupCreateProps(s32 stagenum)
|
||||
slotnum = (slotnum + 1) % maxsimulants;
|
||||
}
|
||||
|
||||
if ((g_MpSetup.chrslots & (1 << (slotnum + 4)))
|
||||
if ((g_MpSetup.chrslots & (1 << (slotnum + MAX_PLAYERS)))
|
||||
&& mpIsSimSlotEnabled(slotnum)) {
|
||||
botmgrAllocateBot(chrnum, slotnum);
|
||||
chrnum++;
|
||||
|
||||
Loaded 100 of 118 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user