forked from Ports/perfect_dark
Compare commits
142
Commits
port-debugger
...
fixes
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6d63e12034 | ||
|
|
23ce248dce | ||
|
|
fa7ef3df64 | ||
|
|
0fd290c8c3 | ||
|
|
b20abed21e | ||
|
|
c4f12ad0a5 | ||
|
|
60989596d5 | ||
|
|
256323a109 | ||
|
|
1e46e68933 | ||
|
|
32a1cb9f26 | ||
|
|
9f30f50b79 | ||
|
|
514bf7affd | ||
|
|
7477a6ce44 | ||
|
|
f7c0cb8b03 | ||
|
|
accb882a36 | ||
|
|
0750c54200 | ||
|
|
b81b7e260b | ||
|
|
3f47f1ec6f | ||
|
|
f9d847df3b | ||
|
|
c110f9cf42 | ||
|
|
cce73d91ce | ||
|
|
3360eb429d | ||
|
|
132e59d3ec | ||
|
|
c166cf0f15 | ||
|
|
20fc4c6cc7 | ||
|
|
309bd45a01 | ||
|
|
45139a9293 | ||
|
|
998eee9c61 | ||
|
|
d8962763b7 | ||
|
|
783791064b | ||
|
|
8106349540 | ||
|
|
bed3bf52d0 | ||
|
|
f25721da8f | ||
|
|
7c949ed9d7 | ||
|
|
8470d50f21 | ||
|
|
27b2dcc27d | ||
|
|
2626434b69 | ||
|
|
11df50b3ad | ||
|
|
ccb3c8668d | ||
|
|
d58a423e5f | ||
|
|
fc70da875e | ||
|
|
d4ac8b155d | ||
|
|
0946cd18c6 | ||
|
|
23aafa4ffa | ||
|
|
426f9c6890 | ||
|
|
cc3886888a | ||
|
|
55ca51d8cc | ||
|
|
f251653317 | ||
|
|
bcb8c2720a | ||
|
|
246d737663 | ||
|
|
425b51e51c | ||
|
|
6e6ffad1a1 | ||
|
|
2028ae7412 | ||
|
|
0c82545ba9 | ||
|
|
2550ce72f4 | ||
|
|
50481b77d0 | ||
|
|
4ee8f3c077 | ||
|
|
0df84ff180 | ||
|
|
a6374b016d | ||
|
|
75d1b8ffd2 | ||
|
|
8165b5005e | ||
|
|
2d0375da2e | ||
|
|
4bcfeddca7 | ||
|
|
2d390ae5ce | ||
|
|
c303c81f88 | ||
|
|
6b0c4a11e2 | ||
|
|
7f68c46959 | ||
|
|
f3f2a593e8 | ||
|
|
79711364bb | ||
|
|
0896860d58 | ||
|
|
e1dd49fc3a | ||
|
|
b53a62189b | ||
|
|
77dc12e41f | ||
|
|
42ef08d662 | ||
|
|
f5cbfe6692 | ||
|
|
550f1d3182 | ||
|
|
7a728c7feb | ||
|
|
857e755b92 | ||
|
|
8ea7e7b410 | ||
|
|
6dd3ec7fda | ||
|
|
bb4fcffeb5 | ||
|
|
498e1667a4 | ||
|
|
19541418b0 | ||
|
|
75952f0395 | ||
|
|
04d280cd42 | ||
|
|
58c2f9d8fa | ||
|
|
6591281d99 | ||
|
|
5fd4a431b1 | ||
|
|
27223802be | ||
|
|
09df313d09 | ||
|
|
01b78105ff | ||
|
|
618a1f3386 | ||
|
|
4bd6dd8617 | ||
|
|
eabd7a438f | ||
|
|
e8a69f39db | ||
|
|
38cb1557d0 | ||
|
|
97444de634 | ||
|
|
d9185982f8 | ||
|
|
790374e95f | ||
|
|
9c98fe7976 | ||
|
|
9bffab7e3e | ||
|
|
8037431686 | ||
|
|
a040b29d40 | ||
|
|
5a3d45de65 | ||
|
|
5a90152991 | ||
|
|
8891bbf7ec | ||
|
|
abf2ae8115 | ||
|
|
20bd9ddcbb | ||
|
|
1d7dd064fe | ||
|
|
629dbfe924 | ||
|
|
f72f93a270 | ||
|
|
57eead9078 | ||
|
|
094d80a5cf | ||
|
|
11bf7aa638 | ||
|
|
79a47809da | ||
|
|
33aa747386 | ||
|
|
a70868fba0 | ||
|
|
c866940873 | ||
|
|
0973f70301 | ||
|
|
54b62c044f | ||
|
|
d5b4e0916c | ||
|
|
45f25c704a | ||
|
|
d8aefc33fc | ||
|
|
cdd116830d | ||
|
|
11d02dd8f2 | ||
|
|
73631e8d5f | ||
|
|
a1136f4d61 | ||
|
|
8bfaaf63ed | ||
|
|
2d59929261 | ||
|
|
86e6e54792 | ||
|
|
f12ae756ef | ||
|
|
062de5bb7b | ||
|
|
400865ec25 | ||
|
|
0d6c557982 | ||
|
|
75e34ace8c | ||
|
|
a2428aac1e | ||
|
|
816d83a0b5 | ||
|
|
039eb8b562 | ||
|
|
872aa3a4a4 | ||
|
|
4b8e1d52b5 | ||
|
|
52992009db | ||
|
|
d7c4843eea |
No files matched your search
@@ -268,7 +268,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
needs: [build-x86_64-linux]
|
needs: [build-x86_64-linux]
|
||||||
container:
|
container:
|
||||||
image: bilelmoussaoui/flatpak-github-actions:freedesktop-23.08
|
image: ghcr.io/flathub-infra/flatpak-github-actions:freedesktop-25.08
|
||||||
options: --privileged
|
options: --privileged
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
@@ -279,23 +279,16 @@ jobs:
|
|||||||
|
|
||||||
- uses: flatpak/flatpak-github-actions/flatpak-builder@v6
|
- uses: flatpak/flatpak-github-actions/flatpak-builder@v6
|
||||||
with:
|
with:
|
||||||
bundle: io.github.fgsfdsfgs.perfect_dark.flatpak
|
bundle: io.github.perfect_dark_pc_port.perfect_dark.flatpak
|
||||||
manifest-path: dist/linux/io.github.fgsfdsfgs.perfect_dark.yaml
|
manifest-path: dist/linux/io.github.perfect_dark_pc_port.perfect_dark.yaml
|
||||||
cache-key: flatpak-builder-${{ github.sha }}
|
cache-key: flatpak-builder-${{ github.sha }}
|
||||||
upload-artifact: false
|
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
|
- name: Upload artifact
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: io.github.fgsfdsfgs.perfect_dark.flatpak
|
name: io.github.perfect_dark_pc_port.perfect_dark.flatpak
|
||||||
path: io.github.fgsfdsfgs.perfect_dark.flatpak
|
path: io.github.perfect_dark_pc_port.perfect_dark.flatpak
|
||||||
retention-days: 0
|
retention-days: 0
|
||||||
|
|
||||||
|
|
||||||
@@ -323,7 +316,7 @@ jobs:
|
|||||||
zip -r ../ci-release/pd-i686-windows.zip pd-i686-windows
|
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-x86_64-windows.zip pd-x86_64-windows
|
||||||
zip -r ../ci-release/pd-arm64-nswitch.zip pd-arm64-nswitch
|
zip -r ../ci-release/pd-arm64-nswitch.zip pd-arm64-nswitch
|
||||||
mv io.github.fgsfdsfgs.perfect_dark.flatpak/io.github.fgsfdsfgs.perfect_dark.flatpak ../ci-release/
|
mv io.github.perfect_dark_pc_port.perfect_dark.flatpak/io.github.perfect_dark_pc_port.perfect_dark.flatpak ../ci-release/
|
||||||
popd
|
popd
|
||||||
git tag --force ci-dev-build port
|
git tag --force ci-dev-build port
|
||||||
git push --force origin ci-dev-build
|
git push --force origin ci-dev-build
|
||||||
|
|||||||
Vendored
+14
@@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
"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
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -21,6 +21,7 @@ set(CMAKE_C_STANDARD 11)
|
|||||||
set(CMAKE_C_EXTENSIONS OFF)
|
set(CMAKE_C_EXTENSIONS OFF)
|
||||||
set(CMAKE_CXX_STANDARD 20)
|
set(CMAKE_CXX_STANDARD 20)
|
||||||
set(CMAKE_CXX_EXTENSIONS OFF)
|
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
|
# On first build set the build type to RelWithDebInfo if it's not already set
|
||||||
if (NOT EXISTS ${CMAKE_BINARY_DIR}/CMakeCache.txt)
|
if (NOT EXISTS ${CMAKE_BINARY_DIR}/CMakeCache.txt)
|
||||||
@@ -187,6 +188,7 @@ add_compile_options(
|
|||||||
-Wno-unused-but-set-variable
|
-Wno-unused-but-set-variable
|
||||||
-Wno-unused-value
|
-Wno-unused-value
|
||||||
-Wno-unused-variable
|
-Wno-unused-variable
|
||||||
|
-fdiagnostics-color=always
|
||||||
)
|
)
|
||||||
|
|
||||||
# C specific flags
|
# C specific flags
|
||||||
|
|||||||
@@ -98,7 +98,7 @@ Controls can be rebound in `pd.ini`. Default control scheme is as follows:
|
|||||||
| Aim mode | RMB/Z | LT | R Trigger |
|
| Aim mode | RMB/Z | LT | R Trigger |
|
||||||
| Use / Cancel | E | N/A | B |
|
| Use / Cancel | E | N/A | B |
|
||||||
| Use / Accept | N/A | A | A |
|
| Use / Accept | N/A | A | A |
|
||||||
| Crouch cycle | N/A | L3 | `0x80000000` (Extra) |
|
| Crouch cycle | N/A | LS Click | `0x80000000` (Extra) |
|
||||||
| Half-Crouch | Shift | N/A | `0x40000000` (Extra) |
|
| Half-Crouch | Shift | N/A | `0x40000000` (Extra) |
|
||||||
| Full-Crouch | Control | N/A | `0x20000000` (Extra) |
|
| Full-Crouch | Control | N/A | `0x20000000` (Extra) |
|
||||||
| Reload | R | X | X `(0x40)` |
|
| Reload | R | X | X `(0x40)` |
|
||||||
@@ -205,7 +205,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`;
|
* 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;
|
* 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;
|
* [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/graphic/Fast3D), 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/fast), Emill and MaikelChan for the libultraship version of fast3d that this port uses;
|
||||||
* lieff for [minimp3](https://github.com/lieff/minimp3);
|
* lieff for [minimp3](https://github.com/lieff/minimp3);
|
||||||
* Mouse Injector and 1964GEPD authors for some of the 60FPS- and mouselook-related fixes;
|
* Mouse Injector and 1964GEPD authors for some of the 60FPS- and mouselook-related fixes;
|
||||||
* Raf for the 64-bit port;
|
* Raf for the 64-bit port;
|
||||||
|
|||||||
+2
-2
@@ -1,8 +1,8 @@
|
|||||||
[Desktop Entry]
|
[Desktop Entry]
|
||||||
Name=Perfect Dark
|
Name=Perfect Dark
|
||||||
Comment=Modern source port of Perfect Dark
|
Comment=Modern source port of Perfect Dark
|
||||||
Exec=io.github.fgsfdsfgs.perfect_dark.sh
|
Exec=io.github.perfect_dark_pc_port.perfect_dark.sh
|
||||||
Icon=io.github.fgsfdsfgs.perfect_dark
|
Icon=io.github.perfect_dark_pc_port.perfect_dark
|
||||||
Terminal=false
|
Terminal=false
|
||||||
Type=Application
|
Type=Application
|
||||||
Categories=Game;ActionGame;
|
Categories=Game;ActionGame;
|
||||||
+6
-5
@@ -1,12 +1,12 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<component type="desktop-application">
|
<component type="desktop-application">
|
||||||
<id>io.github.fgsfdsfgs.perfect_dark</id>
|
<id>io.github.perfect_dark_pc_port.perfect_dark</id>
|
||||||
<name>Perfect Dark</name>
|
<name>Perfect Dark</name>
|
||||||
<developer id="io.github.fgsfdsfgs.perfect_dark">
|
<developer id="io.github.perfect_dark_pc_port.perfect_dark">
|
||||||
<name>Perfect Dark Contributors</name>
|
<name>Perfect Dark Contributors</name>
|
||||||
<url>https://github.com/fgsfdsfgs/perfect_dark/graphs/contributors</url>
|
<url>https://github.com/fgsfdsfgs/perfect_dark/graphs/contributors</url>
|
||||||
</developer>
|
</developer>
|
||||||
<launchable type="desktop-id">io.github.fgsfdsfgs.perfect_dark.desktop</launchable>
|
<launchable type="desktop-id">io.github.perfect_dark_pc_port.perfect_dark.desktop</launchable>
|
||||||
<summary>Modern cross-platform port of Perfect Dark</summary>
|
<summary>Modern cross-platform port of Perfect Dark</summary>
|
||||||
<metadata_license>CC0-1.0</metadata_license>
|
<metadata_license>CC0-1.0</metadata_license>
|
||||||
<project_license>MIT</project_license>
|
<project_license>MIT</project_license>
|
||||||
@@ -17,8 +17,9 @@
|
|||||||
<!--
|
<!--
|
||||||
<screenshots>
|
<screenshots>
|
||||||
<screenshot type="default">
|
<screenshot type="default">
|
||||||
<image type="source">https://gitlab.com/fpiesche/dxx-rebirth-assets/-/raw/c6e7e79eebe92905f84f07a635ffab5122a94bd1/d1x/screenshots/retromode.png</image>
|
<image type="source"></image>
|
||||||
<caption>"Retro mode": the default graphics setup, like the original game but in high resolution</caption>
|
<caption>Screenshot</caption>
|
||||||
|
</screenshot>
|
||||||
<screenshots>
|
<screenshots>
|
||||||
-->
|
-->
|
||||||
<categories>
|
<categories>
|
||||||
File renamed without changes.
File renamed without changes.
+7
-7
@@ -1,8 +1,8 @@
|
|||||||
app-id: io.github.fgsfdsfgs.perfect_dark
|
app-id: io.github.perfect_dark_pc_port.perfect_dark
|
||||||
runtime: org.freedesktop.Platform
|
runtime: org.freedesktop.Platform
|
||||||
runtime-version: "23.08"
|
runtime-version: "25.08"
|
||||||
sdk: org.freedesktop.Sdk
|
sdk: org.freedesktop.Sdk
|
||||||
command: io.github.fgsfdsfgs.perfect_dark.sh
|
command: io.github.perfect_dark_pc_port.perfect_dark.sh
|
||||||
|
|
||||||
finish-args:
|
finish-args:
|
||||||
- --device=all
|
- --device=all
|
||||||
@@ -24,13 +24,13 @@ modules:
|
|||||||
- type: file
|
- type: file
|
||||||
path: bin/pd.pal.x86_64
|
path: bin/pd.pal.x86_64
|
||||||
- type: file
|
- type: file
|
||||||
path: io.github.fgsfdsfgs.perfect_dark.sh
|
path: io.github.perfect_dark_pc_port.perfect_dark.sh
|
||||||
- type: file
|
- type: file
|
||||||
path: io.github.fgsfdsfgs.perfect_dark.png
|
path: io.github.perfect_dark_pc_port.perfect_dark.png
|
||||||
- type: file
|
- type: file
|
||||||
path: io.github.fgsfdsfgs.perfect_dark.metainfo.xml
|
path: io.github.perfect_dark_pc_port.perfect_dark.metainfo.xml
|
||||||
- type: file
|
- type: file
|
||||||
path: io.github.fgsfdsfgs.perfect_dark.desktop
|
path: io.github.perfect_dark_pc_port.perfect_dark.desktop
|
||||||
build-commands: []
|
build-commands: []
|
||||||
post-install:
|
post-install:
|
||||||
# Install the binaries
|
# Install the binaries
|
||||||
@@ -45,8 +45,10 @@ void gfx_run(Gfx* commands);
|
|||||||
void gfx_end_frame(void);
|
void gfx_end_frame(void);
|
||||||
void gfx_set_target_fps(int);
|
void gfx_set_target_fps(int);
|
||||||
void gfx_set_texture_filter(enum FilteringMode mode);
|
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_clear(void);
|
||||||
void gfx_texture_cache_delete(const uint8_t *orig_addr);
|
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);
|
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_resize_framebuffer(int fb, uint32_t width, uint32_t height, int upscale, int autoresize);
|
||||||
void gfx_set_framebuffer(int fb, float noise_scale) ;
|
void gfx_set_framebuffer(int fb, float noise_scale) ;
|
||||||
|
|||||||
+202
-6
@@ -33,6 +33,10 @@ struct ShaderProgram {
|
|||||||
GLint frame_count_location;
|
GLint frame_count_location;
|
||||||
GLint noise_scale_location;
|
GLint noise_scale_location;
|
||||||
GLint three_point_filter_locations[2];
|
GLint three_point_filter_locations[2];
|
||||||
|
GLint decal_mode_location;
|
||||||
|
GLint decal_scale_location;
|
||||||
|
int decal_mode;
|
||||||
|
float decal_scale;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Framebuffer {
|
struct Framebuffer {
|
||||||
@@ -40,6 +44,8 @@ struct Framebuffer {
|
|||||||
bool has_depth_buffer;
|
bool has_depth_buffer;
|
||||||
uint32_t msaa_level;
|
uint32_t msaa_level;
|
||||||
bool invert_y;
|
bool invert_y;
|
||||||
|
bool depth_copy_checked;
|
||||||
|
bool depth_copy_failed;
|
||||||
|
|
||||||
GLuint fbo, clrbuf, clrbuf_msaa, rbo;
|
GLuint fbo, clrbuf, clrbuf_msaa, rbo;
|
||||||
};
|
};
|
||||||
@@ -54,8 +60,23 @@ static uint32_t frame_count;
|
|||||||
static std::vector<Framebuffer> framebuffers;
|
static std::vector<Framebuffer> framebuffers;
|
||||||
static size_t current_framebuffer;
|
static size_t current_framebuffer;
|
||||||
static float current_noise_scale;
|
static float current_noise_scale;
|
||||||
|
static int current_anisotropy_level;
|
||||||
static FilteringMode current_filter_mode = FILTER_LINEAR;
|
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 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 int gl_glsl_version = 130;
|
||||||
static char gl_glsl_version_str[16] = "130";
|
static char gl_glsl_version_str[16] = "130";
|
||||||
@@ -118,6 +139,7 @@ static void gfx_opengl_unload_shader(struct ShaderProgram* old_prg) {
|
|||||||
|
|
||||||
static void gfx_opengl_load_shader(struct ShaderProgram* new_prg) {
|
static void gfx_opengl_load_shader(struct ShaderProgram* new_prg) {
|
||||||
// if (!new_prg) return;
|
// if (!new_prg) return;
|
||||||
|
current_shader_program = new_prg;
|
||||||
glUseProgram(new_prg->opengl_program_id);
|
glUseProgram(new_prg->opengl_program_id);
|
||||||
gfx_opengl_vertex_array_set_attribs(new_prg);
|
gfx_opengl_vertex_array_set_attribs(new_prg);
|
||||||
gfx_opengl_set_uniforms(new_prg);
|
gfx_opengl_set_uniforms(new_prg);
|
||||||
@@ -380,6 +402,9 @@ 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 int frame_count;");
|
||||||
append_line(fs_buf, &fs_len, "uniform float noise_scale;");
|
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(in vec3 value) {");
|
||||||
append_line(fs_buf, &fs_len, " float random = dot(sin(value), vec3(12.9898, 78.233, 37.719));");
|
append_line(fs_buf, &fs_len, " float random = dot(sin(value), vec3(12.9898, 78.233, 37.719));");
|
||||||
@@ -440,6 +465,15 @@ static struct ShaderProgram* gfx_opengl_create_and_load_new_shader(uint64_t shad
|
|||||||
|
|
||||||
append_line(fs_buf, &fs_len, "void main() {");
|
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++) {
|
for (int i = 0; i < 2; i++) {
|
||||||
if (cc_features.used_textures[i]) {
|
if (cc_features.used_textures[i]) {
|
||||||
bool s = cc_features.clamp[i][0], t = cc_features.clamp[i][1];
|
bool s = cc_features.clamp[i][0], t = cc_features.clamp[i][1];
|
||||||
@@ -650,6 +684,14 @@ static struct ShaderProgram* gfx_opengl_create_and_load_new_shader(uint64_t shad
|
|||||||
prg->noise_scale_location = glGetUniformLocation(shader_program, "noise_scale");
|
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[0] = glGetUniformLocation(shader_program, "three_point_filter0");
|
||||||
prg->three_point_filter_locations[1] = glGetUniformLocation(shader_program, "three_point_filter1");
|
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);
|
gfx_opengl_load_shader(prg);
|
||||||
|
|
||||||
@@ -669,6 +711,7 @@ static void gfx_opengl_shader_get_info(struct ShaderProgram* prg, uint8_t* num_i
|
|||||||
|
|
||||||
static void gfx_opengl_clear_shaders(void) {
|
static void gfx_opengl_clear_shaders(void) {
|
||||||
glUseProgram(0);
|
glUseProgram(0);
|
||||||
|
current_shader_program = nullptr;
|
||||||
for (auto& pair : shader_program_pool) {
|
for (auto& pair : shader_program_pool) {
|
||||||
glDeleteProgram(pair.second.opengl_program_id);
|
glDeleteProgram(pair.second.opengl_program_id);
|
||||||
}
|
}
|
||||||
@@ -692,8 +735,11 @@ static void gfx_opengl_select_texture(int tile, GLuint texture_id, bool linear_f
|
|||||||
current_textures_linear_filter[tile] = linear_filter;
|
current_textures_linear_filter[tile] = linear_filter;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void gfx_opengl_upload_texture(const uint8_t* rgba32_buf, uint32_t width, uint32_t height) {
|
static void gfx_opengl_upload_texture(const uint8_t* rgba32_buf, uint32_t width, uint32_t height, bool gen_mipmaps) {
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, rgba32_buf);
|
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) {
|
static uint32_t gfx_cm_to_opengl(uint32_t val) {
|
||||||
@@ -710,16 +756,35 @@ static uint32_t gfx_cm_to_opengl(uint32_t val) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void gfx_opengl_set_sampler_parameters(int tile, bool linear_filter, uint32_t cms, uint32_t cmt) {
|
static void gfx_opengl_set_sampler_parameters(int tile, bool linear_filter, uint32_t cms, uint32_t cmt, bool mipmaps) {
|
||||||
const GLint filter = linear_filter && (current_filter_mode == FILTER_LINEAR) ? GL_LINEAR : GL_NEAREST;
|
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;
|
||||||
|
|
||||||
glActiveTexture(GL_TEXTURE0 + tile);
|
glActiveTexture(GL_TEXTURE0 + tile);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, 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_WRAP_S, gfx_cm_to_opengl(cms));
|
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));
|
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) {
|
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) {
|
if (depth_test) {
|
||||||
glEnable(GL_DEPTH_TEST);
|
glEnable(GL_DEPTH_TEST);
|
||||||
glDepthMask(depth_update ? GL_TRUE : GL_FALSE);
|
glDepthMask(depth_update ? GL_TRUE : GL_FALSE);
|
||||||
@@ -789,10 +854,116 @@ 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) {
|
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);
|
// 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);
|
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * buf_vbo_len, buf_vbo, GL_STREAM_DRAW);
|
||||||
glDrawArrays(GL_TRIANGLES, 0, 3 * buf_vbo_num_tris);
|
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,
|
typedef void (APIENTRY *DEBUGPROC)(GLenum source,
|
||||||
@@ -969,6 +1140,11 @@ static void gfx_opengl_init(void) {
|
|||||||
gfx_framebuffers_enabled = false;
|
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) {
|
if ((GLVersion.major < 4 || GLVersion.minor < 4) && !GLAD_GL_ARB_texture_mirror_clamp_to_edge) {
|
||||||
// GL_MIRROR_CLAMP_TO_EDGE unsupported
|
// GL_MIRROR_CLAMP_TO_EDGE unsupported
|
||||||
gl_mirror_clamp = GL_MIRRORED_REPEAT;
|
gl_mirror_clamp = GL_MIRRORED_REPEAT;
|
||||||
@@ -1117,6 +1293,7 @@ static void gfx_opengl_update_framebuffer_parameters(int fb_id, uint32_t width,
|
|||||||
fb.has_depth_buffer = has_depth_buffer;
|
fb.has_depth_buffer = has_depth_buffer;
|
||||||
fb.msaa_level = msaa_level;
|
fb.msaa_level = msaa_level;
|
||||||
fb.invert_y = opengl_invert_y;
|
fb.invert_y = opengl_invert_y;
|
||||||
|
depth_copy_dirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool gfx_opengl_start_draw_to_framebuffer(int fb_id, float noise_scale) {
|
bool gfx_opengl_start_draw_to_framebuffer(int fb_id, float noise_scale) {
|
||||||
@@ -1127,6 +1304,7 @@ bool gfx_opengl_start_draw_to_framebuffer(int fb_id, float noise_scale) {
|
|||||||
}
|
}
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, fb.fbo);
|
glBindFramebuffer(GL_FRAMEBUFFER, fb.fbo);
|
||||||
current_framebuffer = fb_id;
|
current_framebuffer = fb_id;
|
||||||
|
depth_copy_dirty = true;
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
@@ -1144,6 +1322,7 @@ void gfx_opengl_clear_framebuffer(bool clear_color, bool clear_depth) {
|
|||||||
if (clear_depth) {
|
if (clear_depth) {
|
||||||
glDepthMask(GL_TRUE);
|
glDepthMask(GL_TRUE);
|
||||||
mask |= GL_DEPTH_BUFFER_BIT;
|
mask |= GL_DEPTH_BUFFER_BIT;
|
||||||
|
depth_copy_dirty = true;
|
||||||
}
|
}
|
||||||
glClear(mask);
|
glClear(mask);
|
||||||
if (clear_depth) {
|
if (clear_depth) {
|
||||||
@@ -1244,6 +1423,20 @@ FilteringMode gfx_opengl_get_texture_filter(void) {
|
|||||||
return current_filter_mode;
|
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_name,
|
||||||
gfx_opengl_get_max_texture_size,
|
gfx_opengl_get_max_texture_size,
|
||||||
@@ -1279,5 +1472,8 @@ struct GfxRenderingAPI gfx_opengl_api = {
|
|||||||
gfx_opengl_select_texture_fb,
|
gfx_opengl_select_texture_fb,
|
||||||
gfx_opengl_delete_texture,
|
gfx_opengl_delete_texture,
|
||||||
gfx_opengl_set_texture_filter,
|
gfx_opengl_set_texture_filter,
|
||||||
gfx_opengl_get_texture_filter
|
gfx_opengl_get_texture_filter,
|
||||||
|
gfx_opengl_set_mipmap_filter,
|
||||||
|
gfx_opengl_set_anisotropy_level,
|
||||||
|
gfx_opengl_get_max_anisotropy_level
|
||||||
};
|
};
|
||||||
+76
-39
@@ -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 });
|
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->select_texture(i, texture_id, false);
|
||||||
gfx_rapi->set_sampler_parameters(i, false, 0, 0);
|
gfx_rapi->set_sampler_parameters(i, false, 0, 0, rdp.tex_lod);
|
||||||
*n = node;
|
*n = node;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -585,8 +585,30 @@ void gfx_texture_cache_delete(const uint8_t* orig_addr) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void import_texture_rgba16(int tile, const LoadedTexture& loaded_texture, bool importReplacement) {
|
void gfx_texture_cache_delete_range(const uint8_t* start, const uint8_t* end) {
|
||||||
const RawTexMetadata* metadata = &loaded_texture.raw_tex_metadata;
|
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) {
|
||||||
const uint8_t* addr = loaded_texture.addr;
|
const uint8_t* addr = loaded_texture.addr;
|
||||||
const uint32_t size_bytes = loaded_texture.size_bytes;
|
const uint32_t size_bytes = loaded_texture.size_bytes;
|
||||||
const uint32_t full_image_line_size_bytes =
|
const uint32_t full_image_line_size_bytes =
|
||||||
@@ -612,11 +634,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 width = rdp.texture_tile[tile].line_size_bytes / 2;
|
||||||
const uint32_t height = size_bytes / 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);
|
gfx_rapi->upload_texture(tex_upload_buffer, width, height, gen_mipmaps);
|
||||||
// DumpTexture(loaded_texture.otr_path, rgba32_buf, width, height);
|
// DumpTexture(loaded_texture.otr_path, rgba32_buf, width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void import_texture_rgba32(int tile, const LoadedTexture& loaded_texture, bool importReplacement) {
|
static void import_texture_rgba32(int tile, const LoadedTexture& loaded_texture, bool gen_mipmaps) {
|
||||||
const RawTexMetadata* metadata = &loaded_texture.raw_tex_metadata;
|
const RawTexMetadata* metadata = &loaded_texture.raw_tex_metadata;
|
||||||
const uint8_t* addr = loaded_texture.addr;
|
const uint8_t* addr = loaded_texture.addr;
|
||||||
const uint32_t size_bytes = loaded_texture.size_bytes;
|
const uint32_t size_bytes = loaded_texture.size_bytes;
|
||||||
@@ -633,11 +655,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 width = rdp.texture_tile[tile].line_size_bytes / 2;
|
||||||
const uint32_t height = (size_bytes / 2) / rdp.texture_tile[tile].line_size_bytes;
|
const uint32_t height = (size_bytes / 2) / rdp.texture_tile[tile].line_size_bytes;
|
||||||
gfx_rapi->upload_texture(tex_upload_buffer, width, height);
|
gfx_rapi->upload_texture(tex_upload_buffer, width, height, gen_mipmaps);
|
||||||
// DumpTexture(loaded_texture.otr_path, addr, width, height);
|
// DumpTexture(loaded_texture.otr_path, addr, width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void import_texture_ia4(int tile, const LoadedTexture& loaded_texture, bool importReplacement) {
|
static void import_texture_ia4(int tile, const LoadedTexture& loaded_texture, bool gen_mipmaps) {
|
||||||
const RawTexMetadata* metadata = &loaded_texture.raw_tex_metadata;
|
const RawTexMetadata* metadata = &loaded_texture.raw_tex_metadata;
|
||||||
const uint8_t* addr = loaded_texture.addr;
|
const uint8_t* addr = loaded_texture.addr;
|
||||||
const uint32_t size_bytes = loaded_texture.size_bytes;
|
const uint32_t size_bytes = loaded_texture.size_bytes;
|
||||||
@@ -662,11 +684,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 width = rdp.texture_tile[tile].line_size_bytes * 2;
|
||||||
const uint32_t height = size_bytes / 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);
|
gfx_rapi->upload_texture(tex_upload_buffer, width, height, gen_mipmaps);
|
||||||
// DumpTexture(loaded_texture.otr_path, rgba32_buf, width, height);
|
// DumpTexture(loaded_texture.otr_path, rgba32_buf, width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void import_texture_ia8(int tile, const LoadedTexture& loaded_texture, bool importReplacement) {
|
static void import_texture_ia8(int tile, const LoadedTexture& loaded_texture, bool gen_mipmaps) {
|
||||||
const RawTexMetadata* metadata = &loaded_texture.raw_tex_metadata;
|
const RawTexMetadata* metadata = &loaded_texture.raw_tex_metadata;
|
||||||
const uint8_t* addr = loaded_texture.addr;
|
const uint8_t* addr = loaded_texture.addr;
|
||||||
const uint32_t size_bytes = loaded_texture.size_bytes;
|
const uint32_t size_bytes = loaded_texture.size_bytes;
|
||||||
@@ -688,11 +710,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 width = rdp.texture_tile[tile].line_size_bytes;
|
||||||
const uint32_t height = size_bytes / 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);
|
gfx_rapi->upload_texture(tex_upload_buffer, width, height, gen_mipmaps);
|
||||||
// DumpTexture(loaded_texture.otr_path, rgba32_buf, width, height);
|
// DumpTexture(loaded_texture.otr_path, rgba32_buf, width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void import_texture_ia16(int tile, const LoadedTexture& loaded_texture, bool importReplacement) {
|
static void import_texture_ia16(int tile, const LoadedTexture& loaded_texture, bool gen_mipmaps) {
|
||||||
const RawTexMetadata* metadata = &loaded_texture.raw_tex_metadata;
|
const RawTexMetadata* metadata = &loaded_texture.raw_tex_metadata;
|
||||||
const uint8_t* addr = loaded_texture.addr;
|
const uint8_t* addr = loaded_texture.addr;
|
||||||
const uint32_t size_bytes = loaded_texture.size_bytes;
|
const uint32_t size_bytes = loaded_texture.size_bytes;
|
||||||
@@ -714,11 +736,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 width = rdp.texture_tile[tile].line_size_bytes / 2;
|
||||||
const uint32_t height = size_bytes / 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);
|
gfx_rapi->upload_texture(tex_upload_buffer, width, height, gen_mipmaps);
|
||||||
// DumpTexture(loaded_texture.otr_path, rgba32_buf, width, height);
|
// DumpTexture(loaded_texture.otr_path, rgba32_buf, width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void import_texture_i4(int tile, const LoadedTexture& loaded_texture, bool importReplacement) {
|
static void import_texture_i4(int tile, const LoadedTexture& loaded_texture, bool gen_mipmaps) {
|
||||||
const RawTexMetadata* metadata = &loaded_texture.raw_tex_metadata;
|
const RawTexMetadata* metadata = &loaded_texture.raw_tex_metadata;
|
||||||
const uint8_t* addr = loaded_texture.addr;
|
const uint8_t* addr = loaded_texture.addr;
|
||||||
const uint32_t size_bytes = loaded_texture.size_bytes;
|
const uint32_t size_bytes = loaded_texture.size_bytes;
|
||||||
@@ -741,11 +763,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 width = rdp.texture_tile[tile].line_size_bytes * 2;
|
||||||
const uint32_t height = size_bytes / 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);
|
gfx_rapi->upload_texture(tex_upload_buffer, width, height, gen_mipmaps);
|
||||||
// DumpTexture(loaded_texture.otr_path, rgba32_buf, width, height);
|
// DumpTexture(loaded_texture.otr_path, rgba32_buf, width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void import_texture_i8(int tile, const LoadedTexture& loaded_texture, bool importReplacement) {
|
static void import_texture_i8(int tile, const LoadedTexture& loaded_texture, bool gen_mipmaps) {
|
||||||
const RawTexMetadata* metadata = &loaded_texture.raw_tex_metadata;
|
const RawTexMetadata* metadata = &loaded_texture.raw_tex_metadata;
|
||||||
const uint8_t* addr = loaded_texture.addr;
|
const uint8_t* addr = loaded_texture.addr;
|
||||||
const uint32_t size_bytes = loaded_texture.size_bytes;
|
const uint32_t size_bytes = loaded_texture.size_bytes;
|
||||||
@@ -766,7 +788,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 width = rdp.texture_tile[tile].line_size_bytes;
|
||||||
const uint32_t height = size_bytes / 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);
|
gfx_rapi->upload_texture(tex_upload_buffer, width, height, gen_mipmaps);
|
||||||
// DumpTexture(loaded_texture.otr_path, rgba32_buf, width, height);
|
// DumpTexture(loaded_texture.otr_path, rgba32_buf, width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -791,8 +813,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 importReplacement) {
|
static void import_texture_ci4(int tile, const LoadedTexture& loaded_texture, bool gen_mipmaps) {
|
||||||
const RawTexMetadata* metadata = &loaded_texture.raw_tex_metadata;
|
const RawTexMetadata* metadata = &loaded_texture.raw_tex_metadata;
|
||||||
const uint8_t* addr = loaded_texture.addr;
|
const uint8_t* addr = loaded_texture.addr;
|
||||||
const uint32_t size_bytes = loaded_texture.size_bytes;
|
const uint32_t size_bytes = loaded_texture.size_bytes;
|
||||||
const uint32_t full_image_line_size_bytes =
|
const uint32_t full_image_line_size_bytes =
|
||||||
@@ -816,11 +838,11 @@ static void import_texture_ci4(int tile, const LoadedTexture& loaded_texture, bo
|
|||||||
const uint32_t width = result_line_size * 2;
|
const uint32_t width = result_line_size * 2;
|
||||||
const uint32_t height = size_bytes / result_line_size;
|
const uint32_t height = size_bytes / result_line_size;
|
||||||
|
|
||||||
gfx_rapi->upload_texture(tex_upload_buffer, width, height);
|
gfx_rapi->upload_texture(tex_upload_buffer, width, height, gen_mipmaps);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void import_texture_ci8(int tile, const LoadedTexture& loaded_texture, bool importReplacement) {
|
static void import_texture_ci8(int tile, const LoadedTexture& loaded_texture, bool gen_mipmaps) {
|
||||||
const RawTexMetadata* metadata = &loaded_texture.raw_tex_metadata;
|
const RawTexMetadata* metadata = &loaded_texture.raw_tex_metadata;
|
||||||
const uint8_t* addr = loaded_texture.addr;
|
const uint8_t* addr = loaded_texture.addr;
|
||||||
const uint32_t size_bytes = loaded_texture.size_bytes;
|
const uint32_t size_bytes = loaded_texture.size_bytes;
|
||||||
const uint32_t full_image_line_size_bytes =
|
const uint32_t full_image_line_size_bytes =
|
||||||
@@ -842,8 +864,7 @@ static void import_texture_ci8(int tile, const LoadedTexture& loaded_texture, bo
|
|||||||
const uint32_t width = result_line_size;
|
const uint32_t width = result_line_size;
|
||||||
const uint32_t height = size_bytes / result_line_size;
|
const uint32_t height = size_bytes / result_line_size;
|
||||||
|
|
||||||
gfx_rapi->upload_texture(tex_upload_buffer, width, height);
|
gfx_rapi->upload_texture(tex_upload_buffer, width, height, gen_mipmaps);
|
||||||
// DumpTexture(loaded_texture.otr_path, rgba32_buf, width, height);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void import_texture(int i, int tile, bool importReplacement) {
|
static void import_texture(int i, int tile, bool importReplacement) {
|
||||||
@@ -885,35 +906,35 @@ static void import_texture(int i, int tile, bool importReplacement) {
|
|||||||
|
|
||||||
if (fmt == G_IM_FMT_RGBA) {
|
if (fmt == G_IM_FMT_RGBA) {
|
||||||
if (siz == G_IM_SIZ_16b) {
|
if (siz == G_IM_SIZ_16b) {
|
||||||
import_texture_rgba16(tile, loaded_texture, importReplacement);
|
import_texture_rgba16(tile, loaded_texture, rdp.tex_lod);
|
||||||
} else if (siz == G_IM_SIZ_32b) {
|
} else if (siz == G_IM_SIZ_32b) {
|
||||||
import_texture_rgba32(tile, loaded_texture, importReplacement);
|
import_texture_rgba32(tile, loaded_texture, rdp.tex_lod);
|
||||||
} else {
|
} else {
|
||||||
sysFatalError("Bad size for RGBA texture in tile %d: %02x", tile, siz);
|
sysFatalError("Bad size for RGBA texture in tile %d: %02x", tile, siz);
|
||||||
}
|
}
|
||||||
} else if (fmt == G_IM_FMT_IA) {
|
} else if (fmt == G_IM_FMT_IA) {
|
||||||
if (siz == G_IM_SIZ_4b) {
|
if (siz == G_IM_SIZ_4b) {
|
||||||
import_texture_ia4(tile, loaded_texture, importReplacement);
|
import_texture_ia4(tile, loaded_texture, rdp.tex_lod);
|
||||||
} else if (siz == G_IM_SIZ_8b) {
|
} else if (siz == G_IM_SIZ_8b) {
|
||||||
import_texture_ia8(tile, loaded_texture, importReplacement);
|
import_texture_ia8(tile, loaded_texture, rdp.tex_lod);
|
||||||
} else if (siz == G_IM_SIZ_16b) {
|
} else if (siz == G_IM_SIZ_16b) {
|
||||||
import_texture_ia16(tile, loaded_texture, importReplacement);
|
import_texture_ia16(tile, loaded_texture, rdp.tex_lod);
|
||||||
} else {
|
} else {
|
||||||
sysFatalError("Bad size for IA texture in tile %d: %02x", tile, siz);
|
sysFatalError("Bad size for IA texture in tile %d: %02x", tile, siz);
|
||||||
}
|
}
|
||||||
} else if (fmt == G_IM_FMT_CI) {
|
} else if (fmt == G_IM_FMT_CI) {
|
||||||
if (siz == G_IM_SIZ_4b) {
|
if (siz == G_IM_SIZ_4b) {
|
||||||
import_texture_ci4(tile, loaded_texture, importReplacement);
|
import_texture_ci4(tile, loaded_texture, rdp.tex_lod);
|
||||||
} else if (siz == G_IM_SIZ_8b) {
|
} else if (siz == G_IM_SIZ_8b) {
|
||||||
import_texture_ci8(tile, loaded_texture, importReplacement);
|
import_texture_ci8(tile, loaded_texture, rdp.tex_lod);
|
||||||
} else {
|
} else {
|
||||||
sysFatalError("Bad size for CI texture in tile %d: %02x", tile, siz);
|
sysFatalError("Bad size for CI texture in tile %d: %02x", tile, siz);
|
||||||
}
|
}
|
||||||
} else if (fmt == G_IM_FMT_I) {
|
} else if (fmt == G_IM_FMT_I) {
|
||||||
if (siz == G_IM_SIZ_4b) {
|
if (siz == G_IM_SIZ_4b) {
|
||||||
import_texture_i4(tile, loaded_texture, importReplacement);
|
import_texture_i4(tile, loaded_texture, rdp.tex_lod);
|
||||||
} else if (siz == G_IM_SIZ_8b) {
|
} else if (siz == G_IM_SIZ_8b) {
|
||||||
import_texture_i8(tile, loaded_texture, importReplacement);
|
import_texture_i8(tile, loaded_texture, rdp.tex_lod);
|
||||||
} else {
|
} else {
|
||||||
sysFatalError("Bad size for I texture in tile %d: %02x", tile, siz);
|
sysFatalError("Bad size for I texture in tile %d: %02x", tile, siz);
|
||||||
}
|
}
|
||||||
@@ -1383,7 +1404,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 ||
|
if (linear_filter != rendering_state.textures[i]->second.linear_filter ||
|
||||||
cms != rendering_state.textures[i]->second.cms || cmt != rendering_state.textures[i]->second.cmt) {
|
cms != rendering_state.textures[i]->second.cms || cmt != rendering_state.textures[i]->second.cmt) {
|
||||||
gfx_flush();
|
gfx_flush();
|
||||||
gfx_rapi->set_sampler_parameters(i, linear_filter, cms, cmt);
|
gfx_rapi->set_sampler_parameters(i, linear_filter, cms, cmt, rdp.tex_lod);
|
||||||
rendering_state.textures[i]->second.linear_filter = linear_filter;
|
rendering_state.textures[i]->second.linear_filter = linear_filter;
|
||||||
rendering_state.textures[i]->second.cms = cms;
|
rendering_state.textures[i]->second.cms = cms;
|
||||||
rendering_state.textures[i]->second.cmt = cmt;
|
rendering_state.textures[i]->second.cmt = cmt;
|
||||||
@@ -1641,11 +1662,18 @@ 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) {
|
static void gfx_adjust_viewport_or_scissor(XYWidthHeight* area, bool preserve_aspect = false) {
|
||||||
// HACK: assume all target framebuffers have the same aspect
|
// HACK: assume all target framebuffers have the same aspect
|
||||||
area->width *= RATIO_X;
|
// Use floor/ceil to ensure scissor fully contains the logical region
|
||||||
area->x *= RATIO_X;
|
// and prevents sub-pixel gaps at viewport edges
|
||||||
area->height *= RATIO_Y;
|
float x1 = area->x * RATIO_X;
|
||||||
area->y = SCREEN_HEIGHT - area->y;
|
float y1 = (SCREEN_HEIGHT - area->y) * RATIO_Y;
|
||||||
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;
|
||||||
|
|
||||||
if (preserve_aspect) {
|
if (preserve_aspect) {
|
||||||
// preserve native aspect ratio
|
// preserve native aspect ratio
|
||||||
const float ratio = gfx_current_native_aspect / gfx_current_dimensions.aspect_ratio;
|
const float ratio = gfx_current_native_aspect / gfx_current_dimensions.aspect_ratio;
|
||||||
@@ -2692,7 +2720,7 @@ extern "C" void gfx_set_target_fps(int fps) {
|
|||||||
gfx_wapi->set_target_fps(fps);
|
gfx_wapi->set_target_fps(fps);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" void gfx_set_texture_filter(enum FilteringMode mode) {
|
extern "C" void reset_texture_state() {
|
||||||
gfx_texture_cache_clear();
|
gfx_texture_cache_clear();
|
||||||
if (rendering_state.shader_program) {
|
if (rendering_state.shader_program) {
|
||||||
gfx_rapi->unload_shader(rendering_state.shader_program);
|
gfx_rapi->unload_shader(rendering_state.shader_program);
|
||||||
@@ -2701,9 +2729,18 @@ extern "C" void gfx_set_texture_filter(enum FilteringMode mode) {
|
|||||||
gfx_rapi->clear_shaders();
|
gfx_rapi->clear_shaders();
|
||||||
color_combiner_pool.clear();
|
color_combiner_pool.clear();
|
||||||
prev_combiner = color_combiner_pool.end();
|
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);
|
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) {
|
extern "C" int gfx_create_framebuffer(uint32_t width, uint32_t height, int upscale, int autoresize) {
|
||||||
int fb = gfx_rapi->create_framebuffer();
|
int fb = gfx_rapi->create_framebuffer();
|
||||||
gfx_resize_framebuffer(fb, width, height, upscale, autoresize);
|
gfx_resize_framebuffer(fb, width, height, upscale, autoresize);
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ struct GfxClipParameters {
|
|||||||
};
|
};
|
||||||
|
|
||||||
enum FilteringMode { FILTER_NONE, FILTER_LINEAR, FILTER_THREE_POINT };
|
enum FilteringMode { FILTER_NONE, FILTER_LINEAR, FILTER_THREE_POINT };
|
||||||
|
enum MipmapFilteringMode { MIPMAP_DISABLED, MIPMAP_NEAREST, MIPMAP_LINEAR };
|
||||||
|
|
||||||
struct GfxRenderingAPI {
|
struct GfxRenderingAPI {
|
||||||
const char* (*get_name)(void);
|
const char* (*get_name)(void);
|
||||||
@@ -26,8 +27,8 @@ struct GfxRenderingAPI {
|
|||||||
void (*clear_shaders)(void);
|
void (*clear_shaders)(void);
|
||||||
uint32_t (*new_texture)(void);
|
uint32_t (*new_texture)(void);
|
||||||
void (*select_texture)(int tile, uint32_t texture_id, bool linear_filter);
|
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);
|
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);
|
void (*set_sampler_parameters)(int sampler, bool linear_filter, uint32_t cms, uint32_t cmt, bool mipmaps);
|
||||||
void (*set_depth_mode)(bool depth_test, bool depth_update, bool depth_compare, bool depth_source_prim, uint16_t zmode);
|
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_depth_range)(float znear, float zfar);
|
||||||
void (*set_viewport)(int x, int y, int width, int height);
|
void (*set_viewport)(int x, int y, int width, int height);
|
||||||
@@ -52,6 +53,9 @@ struct GfxRenderingAPI {
|
|||||||
void (*delete_texture)(uint32_t texID);
|
void (*delete_texture)(uint32_t texID);
|
||||||
void (*set_texture_filter)(enum FilteringMode mode);
|
void (*set_texture_filter)(enum FilteringMode mode);
|
||||||
enum FilteringMode (*get_texture_filter)(void);
|
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
|
#endif
|
||||||
@@ -108,8 +108,8 @@ static void gfx_sdl_init(const struct GfxWindowInitSettings *set) {
|
|||||||
int posY = set->y;
|
int posY = set->y;
|
||||||
int display_in_use = SDL_GetWindowDisplayIndex(wnd);
|
int display_in_use = SDL_GetWindowDisplayIndex(wnd);
|
||||||
if (display_in_use < 0) { // Fallback to default if out of bounds
|
if (display_in_use < 0) { // Fallback to default if out of bounds
|
||||||
posX = 100;
|
posX = SDL_WINDOWPOS_UNDEFINED;
|
||||||
posY = 100;
|
posY = SDL_WINDOWPOS_UNDEFINED;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (set->centered) {
|
if (set->centered) {
|
||||||
|
|||||||
+10
-3
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
|
|
||||||
OpenGL, OpenGL ES loader generated by glad 0.1.36 on Wed Nov 20 09:57:47 2024.
|
OpenGL, OpenGL ES loader generated by glad 0.1.36 on Wed Oct 8 13:10:56 2025.
|
||||||
|
|
||||||
Language/Generator: C/C++
|
Language/Generator: C/C++
|
||||||
Specification: gl
|
Specification: gl
|
||||||
@@ -10,6 +10,7 @@
|
|||||||
GL_APPLE_framebuffer_multisample,
|
GL_APPLE_framebuffer_multisample,
|
||||||
GL_ARB_depth_clamp,
|
GL_ARB_depth_clamp,
|
||||||
GL_ARB_framebuffer_object,
|
GL_ARB_framebuffer_object,
|
||||||
|
GL_ARB_texture_filter_anisotropic,
|
||||||
GL_ARB_texture_mirror_clamp_to_edge,
|
GL_ARB_texture_mirror_clamp_to_edge,
|
||||||
GL_ARB_vertex_array_object,
|
GL_ARB_vertex_array_object,
|
||||||
GL_EXT_depth_clamp,
|
GL_EXT_depth_clamp,
|
||||||
@@ -17,6 +18,7 @@
|
|||||||
GL_EXT_framebuffer_multisample,
|
GL_EXT_framebuffer_multisample,
|
||||||
GL_EXT_framebuffer_object,
|
GL_EXT_framebuffer_object,
|
||||||
GL_EXT_gpu_shader4,
|
GL_EXT_gpu_shader4,
|
||||||
|
GL_EXT_texture_filter_anisotropic,
|
||||||
GL_EXT_texture_mirror_clamp_to_edge,
|
GL_EXT_texture_mirror_clamp_to_edge,
|
||||||
GL_KHR_debug,
|
GL_KHR_debug,
|
||||||
GL_NV_depth_clamp,
|
GL_NV_depth_clamp,
|
||||||
@@ -27,9 +29,9 @@
|
|||||||
Reproducible: False
|
Reproducible: False
|
||||||
|
|
||||||
Commandline:
|
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_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"
|
--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"
|
||||||
Online:
|
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_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
|
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
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@@ -668,6 +670,7 @@ PFNGLWAITSYNCPROC glad_glWaitSync = NULL;
|
|||||||
int GLAD_GL_APPLE_framebuffer_multisample = 0;
|
int GLAD_GL_APPLE_framebuffer_multisample = 0;
|
||||||
int GLAD_GL_ARB_depth_clamp = 0;
|
int GLAD_GL_ARB_depth_clamp = 0;
|
||||||
int GLAD_GL_ARB_framebuffer_object = 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_texture_mirror_clamp_to_edge = 0;
|
||||||
int GLAD_GL_ARB_vertex_array_object = 0;
|
int GLAD_GL_ARB_vertex_array_object = 0;
|
||||||
int GLAD_GL_EXT_depth_clamp = 0;
|
int GLAD_GL_EXT_depth_clamp = 0;
|
||||||
@@ -675,6 +678,7 @@ int GLAD_GL_EXT_framebuffer_blit = 0;
|
|||||||
int GLAD_GL_EXT_framebuffer_multisample = 0;
|
int GLAD_GL_EXT_framebuffer_multisample = 0;
|
||||||
int GLAD_GL_EXT_framebuffer_object = 0;
|
int GLAD_GL_EXT_framebuffer_object = 0;
|
||||||
int GLAD_GL_EXT_gpu_shader4 = 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_EXT_texture_mirror_clamp_to_edge = 0;
|
||||||
int GLAD_GL_KHR_debug = 0;
|
int GLAD_GL_KHR_debug = 0;
|
||||||
int GLAD_GL_NV_depth_clamp = 0;
|
int GLAD_GL_NV_depth_clamp = 0;
|
||||||
@@ -1435,12 +1439,14 @@ static int find_extensionsGL(void) {
|
|||||||
if (!get_exts()) return 0;
|
if (!get_exts()) return 0;
|
||||||
GLAD_GL_ARB_depth_clamp = has_ext("GL_ARB_depth_clamp");
|
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_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_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_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_blit = has_ext("GL_EXT_framebuffer_blit");
|
||||||
GLAD_GL_EXT_framebuffer_multisample = has_ext("GL_EXT_framebuffer_multisample");
|
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_framebuffer_object = has_ext("GL_EXT_framebuffer_object");
|
||||||
GLAD_GL_EXT_gpu_shader4 = has_ext("GL_EXT_gpu_shader4");
|
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_KHR_debug = has_ext("GL_KHR_debug");
|
||||||
GLAD_GL_NV_depth_clamp = has_ext("GL_NV_depth_clamp");
|
GLAD_GL_NV_depth_clamp = has_ext("GL_NV_depth_clamp");
|
||||||
free_exts();
|
free_exts();
|
||||||
@@ -1800,6 +1806,7 @@ static int find_extensionsGLES2(void) {
|
|||||||
if (!get_exts()) return 0;
|
if (!get_exts()) return 0;
|
||||||
GLAD_GL_APPLE_framebuffer_multisample = has_ext("GL_APPLE_framebuffer_multisample");
|
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_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_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_KHR_debug = has_ext("GL_KHR_debug");
|
||||||
GLAD_GL_NV_framebuffer_multisample = has_ext("GL_NV_framebuffer_multisample");
|
GLAD_GL_NV_framebuffer_multisample = has_ext("GL_NV_framebuffer_multisample");
|
||||||
|
|||||||
+21
-3
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
|
|
||||||
OpenGL, OpenGL ES loader generated by glad 0.1.36 on Wed Nov 20 09:57:47 2024.
|
OpenGL, OpenGL ES loader generated by glad 0.1.36 on Wed Oct 8 13:10:56 2025.
|
||||||
|
|
||||||
Language/Generator: C/C++
|
Language/Generator: C/C++
|
||||||
Specification: gl
|
Specification: gl
|
||||||
@@ -10,6 +10,7 @@
|
|||||||
GL_APPLE_framebuffer_multisample,
|
GL_APPLE_framebuffer_multisample,
|
||||||
GL_ARB_depth_clamp,
|
GL_ARB_depth_clamp,
|
||||||
GL_ARB_framebuffer_object,
|
GL_ARB_framebuffer_object,
|
||||||
|
GL_ARB_texture_filter_anisotropic,
|
||||||
GL_ARB_texture_mirror_clamp_to_edge,
|
GL_ARB_texture_mirror_clamp_to_edge,
|
||||||
GL_ARB_vertex_array_object,
|
GL_ARB_vertex_array_object,
|
||||||
GL_EXT_depth_clamp,
|
GL_EXT_depth_clamp,
|
||||||
@@ -17,6 +18,7 @@
|
|||||||
GL_EXT_framebuffer_multisample,
|
GL_EXT_framebuffer_multisample,
|
||||||
GL_EXT_framebuffer_object,
|
GL_EXT_framebuffer_object,
|
||||||
GL_EXT_gpu_shader4,
|
GL_EXT_gpu_shader4,
|
||||||
|
GL_EXT_texture_filter_anisotropic,
|
||||||
GL_EXT_texture_mirror_clamp_to_edge,
|
GL_EXT_texture_mirror_clamp_to_edge,
|
||||||
GL_KHR_debug,
|
GL_KHR_debug,
|
||||||
GL_NV_depth_clamp,
|
GL_NV_depth_clamp,
|
||||||
@@ -27,9 +29,9 @@
|
|||||||
Reproducible: False
|
Reproducible: False
|
||||||
|
|
||||||
Commandline:
|
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_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"
|
--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"
|
||||||
Online:
|
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_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
|
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
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
@@ -2721,6 +2723,8 @@ GLAPI PFNGLGETINTERNALFORMATIVPROC glad_glGetInternalformativ;
|
|||||||
#define glGetInternalformativ glad_glGetInternalformativ
|
#define glGetInternalformativ glad_glGetInternalformativ
|
||||||
#endif
|
#endif
|
||||||
#define GL_INDEX 0x8222
|
#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_MIRROR_CLAMP_TO_EDGE 0x8743
|
||||||
#define GL_READ_FRAMEBUFFER_EXT 0x8CA8
|
#define GL_READ_FRAMEBUFFER_EXT 0x8CA8
|
||||||
#define GL_DRAW_FRAMEBUFFER_EXT 0x8CA9
|
#define GL_DRAW_FRAMEBUFFER_EXT 0x8CA9
|
||||||
@@ -2808,6 +2812,8 @@ GLAPI PFNGLGETINTERNALFORMATIVPROC glad_glGetInternalformativ;
|
|||||||
#define GL_MIN_PROGRAM_TEXEL_OFFSET_EXT 0x8904
|
#define GL_MIN_PROGRAM_TEXEL_OFFSET_EXT 0x8904
|
||||||
#define GL_MAX_PROGRAM_TEXEL_OFFSET_EXT 0x8905
|
#define GL_MAX_PROGRAM_TEXEL_OFFSET_EXT 0x8905
|
||||||
#define GL_VERTEX_ATTRIB_ARRAY_INTEGER_EXT 0x88FD
|
#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_OUTPUT_SYNCHRONOUS 0x8242
|
||||||
#define GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH 0x8243
|
#define GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH 0x8243
|
||||||
#define GL_DEBUG_CALLBACK_FUNCTION 0x8244
|
#define GL_DEBUG_CALLBACK_FUNCTION 0x8244
|
||||||
@@ -2910,6 +2916,10 @@ GLAPI int GLAD_GL_ARB_depth_clamp;
|
|||||||
#define GL_ARB_framebuffer_object 1
|
#define GL_ARB_framebuffer_object 1
|
||||||
GLAPI int GLAD_GL_ARB_framebuffer_object;
|
GLAPI int GLAD_GL_ARB_framebuffer_object;
|
||||||
#endif
|
#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
|
#ifndef GL_ARB_texture_mirror_clamp_to_edge
|
||||||
#define GL_ARB_texture_mirror_clamp_to_edge 1
|
#define GL_ARB_texture_mirror_clamp_to_edge 1
|
||||||
GLAPI int GLAD_GL_ARB_texture_mirror_clamp_to_edge;
|
GLAPI int GLAD_GL_ARB_texture_mirror_clamp_to_edge;
|
||||||
@@ -3093,6 +3103,10 @@ typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIUIVEXTPROC)(GLuint index, GLenum pn
|
|||||||
GLAPI PFNGLGETVERTEXATTRIBIUIVEXTPROC glad_glGetVertexAttribIuivEXT;
|
GLAPI PFNGLGETVERTEXATTRIBIUIVEXTPROC glad_glGetVertexAttribIuivEXT;
|
||||||
#define glGetVertexAttribIuivEXT glad_glGetVertexAttribIuivEXT
|
#define glGetVertexAttribIuivEXT glad_glGetVertexAttribIuivEXT
|
||||||
#endif
|
#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
|
#ifndef GL_KHR_debug
|
||||||
#define GL_KHR_debug 1
|
#define GL_KHR_debug 1
|
||||||
GLAPI int GLAD_GL_KHR_debug;
|
GLAPI int GLAD_GL_KHR_debug;
|
||||||
@@ -3181,6 +3195,10 @@ GLAPI PFNGLRESOLVEMULTISAMPLEFRAMEBUFFERAPPLEPROC glad_glResolveMultisampleFrame
|
|||||||
#define GL_EXT_depth_clamp 1
|
#define GL_EXT_depth_clamp 1
|
||||||
GLAPI int GLAD_GL_EXT_depth_clamp;
|
GLAPI int GLAD_GL_EXT_depth_clamp;
|
||||||
#endif
|
#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
|
#ifndef GL_EXT_texture_mirror_clamp_to_edge
|
||||||
#define GL_EXT_texture_mirror_clamp_to_edge 1
|
#define GL_EXT_texture_mirror_clamp_to_edge 1
|
||||||
GLAPI int GLAD_GL_EXT_texture_mirror_clamp_to_edge;
|
GLAPI int GLAD_GL_EXT_texture_mirror_clamp_to_edge;
|
||||||
|
|||||||
@@ -39,6 +39,8 @@ s32 videoGetCenterWindow(void);
|
|||||||
void videoSetCenterWindow(s32 center);
|
void videoSetCenterWindow(s32 center);
|
||||||
u32 videoGetTextureFilter(void);
|
u32 videoGetTextureFilter(void);
|
||||||
s32 videoGetTextureFilter2D(void);
|
s32 videoGetTextureFilter2D(void);
|
||||||
|
u32 videoGetAnisotropicFilter(void);
|
||||||
|
u32 videoGetMaxAnisotropyLevel(void);
|
||||||
s32 videoGetDetailTextures(void);
|
s32 videoGetDetailTextures(void);
|
||||||
s32 videoGetDisplayModeIndex(void);
|
s32 videoGetDisplayModeIndex(void);
|
||||||
s32 videoGetDisplayMode(displaymode *out, const s32 index);
|
s32 videoGetDisplayMode(displaymode *out, const s32 index);
|
||||||
@@ -47,21 +49,25 @@ s32 videoGetVsync(void);
|
|||||||
s32 videoGetFramerateLimit(void);
|
s32 videoGetFramerateLimit(void);
|
||||||
s32 videoGetDisplayFPS(void);
|
s32 videoGetDisplayFPS(void);
|
||||||
s32 videoGetMSAA(void);
|
s32 videoGetMSAA(void);
|
||||||
|
f32 videoGetGlareBrightness(void);
|
||||||
|
f32 videoGetOverexposureScale(void);
|
||||||
|
|
||||||
f32 videoGetAverageFPS(void);
|
f32 videoGetAverageFPS(void);
|
||||||
f64 videoGetLastRenderTime(void);
|
|
||||||
|
|
||||||
void videoSetWindowOffset(s32 x, s32 y);
|
void videoSetWindowOffset(s32 x, s32 y);
|
||||||
void videoSetFullscreen(s32 fs);
|
void videoSetFullscreen(s32 fs);
|
||||||
void videoSetFullscreenMode(s32 mode);
|
void videoSetFullscreenMode(s32 mode);
|
||||||
void videoSetTextureFilter(u32 filter);
|
void videoSetTextureFilter(u32 filter);
|
||||||
void videoSetTextureFilter2D(s32 filter);
|
void videoSetTextureFilter2D(s32 filter);
|
||||||
|
void videoSetAnisotropicFilter(u32 filter);
|
||||||
void videoSetDetailTextures(s32 detail);
|
void videoSetDetailTextures(s32 detail);
|
||||||
void videoSetDisplayMode(const s32 index);
|
void videoSetDisplayMode(const s32 index);
|
||||||
void videoSetVsync(const s32 vsync);
|
void videoSetVsync(const s32 vsync);
|
||||||
void videoSetFramerateLimit(const s32 limit);
|
void videoSetFramerateLimit(const s32 limit);
|
||||||
void videoSetDisplayFPS(const s32 displayfps);
|
void videoSetDisplayFPS(const s32 displayfps);
|
||||||
void videoSetMSAA(const s32 msaa);
|
void videoSetMSAA(const s32 msaa);
|
||||||
|
void videoSetGlareBrightness(f32 bright);
|
||||||
|
void videoSetOverexposureScale(f32 scale);
|
||||||
|
|
||||||
s32 videoCreateFramebuffer(u32 w, u32 h, s32 upscale, s32 autoresize);
|
s32 videoCreateFramebuffer(u32 w, u32 h, s32 upscale, s32 autoresize);
|
||||||
void videoSetFramebuffer(s32 target);
|
void videoSetFramebuffer(s32 target);
|
||||||
@@ -72,6 +78,7 @@ s32 videoFramebuffersSupported(void);
|
|||||||
|
|
||||||
void videoResetTextureCache(void);
|
void videoResetTextureCache(void);
|
||||||
void videoFreeCachedTexture(const void *texptr);
|
void videoFreeCachedTexture(const void *texptr);
|
||||||
|
void videoFreeCachedTextures(const void *start, const void *end);
|
||||||
|
|
||||||
void videoShutdown(void);
|
void videoShutdown(void);
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -114,7 +114,7 @@ s32 fsInit(void)
|
|||||||
if (!portable) {
|
if (!portable) {
|
||||||
if (fsFileSize("./" DEFAULT_BASEDIR_NAME) >= 0) {
|
if (fsFileSize("./" DEFAULT_BASEDIR_NAME) >= 0) {
|
||||||
path = "./" DEFAULT_BASEDIR_NAME;
|
path = "./" DEFAULT_BASEDIR_NAME;
|
||||||
} else if (fsFileSize("$H/" DEFAULT_BASEDIR_NAME)) {
|
} else if (fsFileSize("$H/" DEFAULT_BASEDIR_NAME) >= 0) {
|
||||||
path = "$H/" DEFAULT_BASEDIR_NAME;
|
path = "$H/" DEFAULT_BASEDIR_NAME;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+33
-25
@@ -75,7 +75,7 @@ static s32 connectedMask = 0;
|
|||||||
static s32 numJoysticks = 0;
|
static s32 numJoysticks = 0;
|
||||||
|
|
||||||
static s32 useHIDAPI = 1;
|
static s32 useHIDAPI = 1;
|
||||||
static s32 useRawInput = 1;
|
static s32 useRawInput = 0;
|
||||||
|
|
||||||
static s32 mouseEnabled = 1;
|
static s32 mouseEnabled = 1;
|
||||||
static s32 mouseX, mouseY;
|
static s32 mouseX, mouseY;
|
||||||
@@ -195,7 +195,7 @@ void inputSetDefaultKeyBinds(s32 cidx, s32 n64mode)
|
|||||||
{ CK_RTRIG, VK_MOUSE_RIGHT, SDL_SCANCODE_Z },
|
{ CK_RTRIG, VK_MOUSE_RIGHT, SDL_SCANCODE_Z },
|
||||||
{ CK_LTRIG, SDL_SCANCODE_F, SDL_SCANCODE_X },
|
{ CK_LTRIG, SDL_SCANCODE_F, SDL_SCANCODE_X },
|
||||||
{ CK_ZTRIG, VK_MOUSE_LEFT, SDL_SCANCODE_SPACE },
|
{ CK_ZTRIG, VK_MOUSE_LEFT, SDL_SCANCODE_SPACE },
|
||||||
{ CK_START, SDL_SCANCODE_RETURN, SDL_SCANCODE_TAB },
|
{ CK_START, SDL_SCANCODE_TAB, 0 },
|
||||||
{ CK_DPAD_D, SDL_SCANCODE_Q, VK_MOUSE_MIDDLE },
|
{ CK_DPAD_D, SDL_SCANCODE_Q, VK_MOUSE_MIDDLE },
|
||||||
{ CK_DPAD_U, 0, 0 },
|
{ CK_DPAD_U, 0, 0 },
|
||||||
{ CK_Y, VK_MOUSE_WHEEL_DN, 0 },
|
{ CK_Y, VK_MOUSE_WHEEL_DN, 0 },
|
||||||
@@ -209,7 +209,9 @@ void inputSetDefaultKeyBinds(s32 cidx, s32 n64mode)
|
|||||||
{ CK_STICK_YNEG, SDL_SCANCODE_DOWN, 0 },
|
{ CK_STICK_YNEG, SDL_SCANCODE_DOWN, 0 },
|
||||||
{ CK_STICK_YPOS, SDL_SCANCODE_UP, 0 },
|
{ CK_STICK_YPOS, SDL_SCANCODE_UP, 0 },
|
||||||
{ CK_4000, SDL_SCANCODE_LSHIFT, 0 },
|
{ CK_4000, SDL_SCANCODE_LSHIFT, 0 },
|
||||||
{ CK_2000, SDL_SCANCODE_LCTRL, 0 }
|
{ CK_2000, SDL_SCANCODE_LCTRL, 0 },
|
||||||
|
{ CK_ACCEPT, SDL_SCANCODE_RETURN, SDL_SCANCODE_E },
|
||||||
|
{ CK_CANCEL, VK_MOUSE_RIGHT, 0 },
|
||||||
};
|
};
|
||||||
|
|
||||||
static const u32 pcjoybinds[][2] = {
|
static const u32 pcjoybinds[][2] = {
|
||||||
@@ -693,6 +695,7 @@ s32 inputInit(void)
|
|||||||
// the two hints below enable Rumble and Motion Sensor for PS4/5 pads connected via bluetooth
|
// 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_PS4_RUMBLE, "1");
|
||||||
SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_PS5_RUMBLE, "1");
|
SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_PS5_RUMBLE, "1");
|
||||||
|
SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_STEAM, "1");
|
||||||
#endif
|
#endif
|
||||||
#if SDL_VERSION_ATLEAST(2, 23, 2)
|
#if SDL_VERSION_ATLEAST(2, 23, 2)
|
||||||
SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_COMBINE_JOY_CONS, "1");
|
SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_COMBINE_JOY_CONS, "1");
|
||||||
@@ -702,11 +705,19 @@ s32 inputInit(void)
|
|||||||
#endif
|
#endif
|
||||||
#if SDL_VERSION_ATLEAST(2, 26, 0)
|
#if SDL_VERSION_ATLEAST(2, 26, 0)
|
||||||
SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_WII, "1");
|
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
|
#endif
|
||||||
}
|
}
|
||||||
if (useRawInput) {
|
if (useRawInput) {
|
||||||
SDL_SetHint(SDL_HINT_JOYSTICK_RAWINPUT, "1");
|
SDL_SetHint(SDL_HINT_JOYSTICK_RAWINPUT, "1");
|
||||||
|
#ifdef SDL_HINT_JOYSTICK_RAWINPUT_CORRELATE_XINPUT
|
||||||
SDL_SetHint(SDL_HINT_JOYSTICK_RAWINPUT_CORRELATE_XINPUT, "1");
|
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)) {
|
if (!SDL_WasInit(SDL_INIT_GAMECONTROLLER | SDL_INIT_HAPTIC)) {
|
||||||
@@ -745,6 +756,9 @@ s32 inputInit(void)
|
|||||||
|
|
||||||
inputLoadBinds();
|
inputLoadBinds();
|
||||||
|
|
||||||
|
// Explicitly stop text input to prevent key events being swallowed on certain Wayland systems
|
||||||
|
inputStopTextInput();
|
||||||
|
|
||||||
return connectedMask;
|
return connectedMask;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1241,26 +1255,24 @@ void inputMouseGetRawDelta(s32 *dx, s32 *dy)
|
|||||||
|
|
||||||
void inputMouseGetScaledDelta(f32* dx, f32* dy)
|
void inputMouseGetScaledDelta(f32* dx, f32* dy)
|
||||||
{
|
{
|
||||||
f32 mdx = 0.f, mdy = 0.f;
|
f32 mdx = 0.f, mdy = 0.f;
|
||||||
|
if (mouseLocked) {
|
||||||
if (mouseLocked) {
|
mdx = mouseDX * (0.022f / 3.5f) * mouseSensX;
|
||||||
mdx = mouseSensX * ((f32)mouseDX / 3.5f) * 0.022f;
|
mdy = mouseDY * (0.022f / 3.5f) * mouseSensY;
|
||||||
mdy = mouseSensY * ((f32)mouseDY / 3.5f) * 0.022f;
|
}
|
||||||
}
|
if (dx) *dx = mdx;
|
||||||
if (dx) *dx = mdx;
|
if (dy) *dy = mdy;
|
||||||
if (dy) *dy = mdy;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void inputMouseGetAbsScaledDelta(f32* dx, f32* dy)
|
void inputMouseGetAbsScaledDelta(f32* dx, f32* dy)
|
||||||
{
|
{
|
||||||
f32 mdx = 0.f, mdy = 0.f;
|
f32 mdx = 0.f, mdy = 0.f;
|
||||||
|
if (mouseLocked) {
|
||||||
if (mouseLocked) {
|
mdx = mouseDX * (0.022f / 3.5f) * fabsf(mouseSensX);
|
||||||
mdx = fabsf(mouseSensX) * ((f32)mouseDX / 3.5f) * 0.022f;
|
mdy = mouseDY * (0.022f / 3.5f) * fabsf(mouseSensY);
|
||||||
mdy = fabsf(mouseSensY) * ((f32)mouseDY / 3.5f) * 0.022f;
|
}
|
||||||
}
|
if (dx) *dx = mdx;
|
||||||
if (dx) *dx = mdx;
|
if (dy) *dy = mdy;
|
||||||
if (dy) *dy = mdy;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void inputMouseGetSpeed(f32 *x, f32 *y)
|
void inputMouseGetSpeed(f32 *x, f32 *y)
|
||||||
@@ -1453,10 +1465,6 @@ s32 inputTextHandler(char *out, const u32 outSize, s32 *curCol, s32 oskCharsOnly
|
|||||||
} else {
|
} else {
|
||||||
out[0] = '\0';
|
out[0] = '\0';
|
||||||
}
|
}
|
||||||
} else if (key == VK_RETURN) {
|
|
||||||
if (out[0] && *curCol) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
} else if (key == VK_ESCAPE) {
|
} else if (key == VK_ESCAPE) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -1509,8 +1517,8 @@ PD_CONSTRUCTOR static void inputConfigInit(void)
|
|||||||
{
|
{
|
||||||
configRegisterInt("Input.MouseEnabled", &mouseEnabled, 0, 1);
|
configRegisterInt("Input.MouseEnabled", &mouseEnabled, 0, 1);
|
||||||
configRegisterInt("Input.MouseLockMode", &mouseLockMode, MLOCK_OFF, MLOCK_AUTO);
|
configRegisterInt("Input.MouseLockMode", &mouseLockMode, MLOCK_OFF, MLOCK_AUTO);
|
||||||
configRegisterFloat("Input.MouseSpeedX", &mouseSensX, -10.f, 10.f);
|
configRegisterFloat("Input.MouseSpeedX", &mouseSensX, -30.f, 30.f);
|
||||||
configRegisterFloat("Input.MouseSpeedY", &mouseSensY, -10.f, 10.f);
|
configRegisterFloat("Input.MouseSpeedY", &mouseSensY, -30.f, 30.f);
|
||||||
configRegisterInt("Input.FakeGamepads", &fakeControllers, 0, 4);
|
configRegisterInt("Input.FakeGamepads", &fakeControllers, 0, 4);
|
||||||
configRegisterInt("Input.FirstGamepadNum", &firstController, 0, 3);
|
configRegisterInt("Input.FirstGamepadNum", &firstController, 0, 3);
|
||||||
configRegisterInt("Input.UseHIDAPI", &useHIDAPI, 0, 1);
|
configRegisterInt("Input.UseHIDAPI", &useHIDAPI, 0, 1);
|
||||||
|
|||||||
@@ -169,6 +169,9 @@ PD_CONSTRUCTOR static void gameConfigInit(void)
|
|||||||
configRegisterInt("Game.SkipIntro", &g_SkipIntro, 0, 1);
|
configRegisterInt("Game.SkipIntro", &g_SkipIntro, 0, 1);
|
||||||
configRegisterInt("Game.DisableMpDeathMusic", &g_MusicDisableMpDeath, 0, 1);
|
configRegisterInt("Game.DisableMpDeathMusic", &g_MusicDisableMpDeath, 0, 1);
|
||||||
configRegisterInt("Game.GEMuzzleFlashes", &g_BgunGeMuzzleFlashes, 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_PLAYERS; ++j) {
|
||||||
const s32 i = j + 1;
|
const s32 i = j + 1;
|
||||||
configRegisterFloat(strFmt("Game.Player%d.FovY", i), &g_PlayerExtCfg[j].fovy, 5.f, 175.f);
|
configRegisterFloat(strFmt("Game.Player%d.FovY", i), &g_PlayerExtCfg[j].fovy, 5.f, 175.f);
|
||||||
@@ -178,6 +181,7 @@ 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.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.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.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.CrouchMode", i), &g_PlayerExtCfg[j].crouchmode, 0, CROUCHMODE_TOGGLE_ANALOG);
|
||||||
configRegisterInt(strFmt("Game.Player%d.ExtendedControls", i), &g_PlayerExtCfg[j].extcontrols, 0, 1);
|
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);
|
configRegisterUInt(strFmt("Game.Player%d.CrosshairColour", i), &g_PlayerExtCfg[j].crosshaircolour, 0, 0xFFFFFFFF);
|
||||||
|
|||||||
+3
-3
@@ -420,7 +420,7 @@ s32 modTextureLoad(u16 num, void *dst, u32 dstSize)
|
|||||||
{
|
{
|
||||||
static s32 dirExists = -1;
|
static s32 dirExists = -1;
|
||||||
if (dirExists < 0) {
|
if (dirExists < 0) {
|
||||||
dirExists = (fsFileSize(MOD_TEXTURES_DIR "/") >= 0);
|
dirExists = (fsFileSize(MOD_TEXTURES_DIR) >= 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!dirExists) {
|
if (!dirExists) {
|
||||||
@@ -442,7 +442,7 @@ void *modSequenceLoad(u16 num, u32 *outSize)
|
|||||||
{
|
{
|
||||||
static s32 dirExists = -1;
|
static s32 dirExists = -1;
|
||||||
if (dirExists < 0) {
|
if (dirExists < 0) {
|
||||||
dirExists = (fsFileSize(MOD_SEQUENCES_DIR "/") >= 0);
|
dirExists = (fsFileSize(MOD_SEQUENCES_DIR) >= 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!dirExists) {
|
if (!dirExists) {
|
||||||
@@ -478,7 +478,7 @@ s32 modAnimationLoadDescriptor(u16 num, struct animtableentry *anim)
|
|||||||
{
|
{
|
||||||
static s32 dirExists = -1;
|
static s32 dirExists = -1;
|
||||||
if (dirExists < 0) {
|
if (dirExists < 0) {
|
||||||
dirExists = (fsFileSize(MOD_ANIMATIONS_DIR "/") >= 0);
|
dirExists = (fsFileSize(MOD_ANIMATIONS_DIR) >= 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!dirExists) {
|
if (!dirExists) {
|
||||||
|
|||||||
+1
-1
@@ -809,7 +809,7 @@ static MenuItemHandlerResult menuhandlerSetupSetDefault(s32 operation, struct me
|
|||||||
s32 selected = g_Menus[g_MpPlayerNum].mpsetup.slotindex;
|
s32 selected = g_Menus[g_MpPlayerNum].mpsetup.slotindex;
|
||||||
// clicked on "clear default"
|
// clicked on "clear default"
|
||||||
if (selected == g_MpSetupFile.defaultsetup - 1) {
|
if (selected == g_MpSetupFile.defaultsetup - 1) {
|
||||||
g_MpSetupFile.defaultsetup = -1;
|
g_MpSetupFile.defaultsetup = 0;
|
||||||
strcpy(g_LabelSetDefault, "Set Default\n");
|
strcpy(g_LabelSetDefault, "Set Default\n");
|
||||||
} else {
|
} else {
|
||||||
g_MpSetupFile.defaultsetup = selected + 1;
|
g_MpSetupFile.defaultsetup = selected + 1;
|
||||||
|
|||||||
+121
-6
@@ -170,8 +170,6 @@ static MenuItemHandlerResult menuhandlerMouseSpeedX(s32 operation, struct menuit
|
|||||||
inputMouseGetSpeed(&x, &y);
|
inputMouseGetSpeed(&x, &y);
|
||||||
if (x < 0.f) {
|
if (x < 0.f) {
|
||||||
data->slider.value = 0;
|
data->slider.value = 0;
|
||||||
} else if (x > 10.f) {
|
|
||||||
data->slider.value = 1000;
|
|
||||||
} else {
|
} else {
|
||||||
data->slider.value = x * 100.f + 0.5f;
|
data->slider.value = x * 100.f + 0.5f;
|
||||||
}
|
}
|
||||||
@@ -182,6 +180,7 @@ static MenuItemHandlerResult menuhandlerMouseSpeedX(s32 operation, struct menuit
|
|||||||
break;
|
break;
|
||||||
case MENUOP_GETSLIDERLABEL:
|
case MENUOP_GETSLIDERLABEL:
|
||||||
sprintf(data->slider.label, "%.2f", (f32)data->slider.value / 100.f);
|
sprintf(data->slider.label, "%.2f", (f32)data->slider.value / 100.f);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -196,8 +195,6 @@ static MenuItemHandlerResult menuhandlerMouseSpeedY(s32 operation, struct menuit
|
|||||||
inputMouseGetSpeed(&x, &y);
|
inputMouseGetSpeed(&x, &y);
|
||||||
if (y < 0.f) {
|
if (y < 0.f) {
|
||||||
data->slider.value = 0;
|
data->slider.value = 0;
|
||||||
} else if (y > 10.f) {
|
|
||||||
data->slider.value = 1000;
|
|
||||||
} else {
|
} else {
|
||||||
data->slider.value = y * 100.f + 0.5f;
|
data->slider.value = y * 100.f + 0.5f;
|
||||||
}
|
}
|
||||||
@@ -208,6 +205,7 @@ static MenuItemHandlerResult menuhandlerMouseSpeedY(s32 operation, struct menuit
|
|||||||
break;
|
break;
|
||||||
case MENUOP_GETSLIDERLABEL:
|
case MENUOP_GETSLIDERLABEL:
|
||||||
sprintf(data->slider.label, "%.2f", (f32)data->slider.value / 100.f);
|
sprintf(data->slider.label, "%.2f", (f32)data->slider.value / 100.f);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -325,7 +323,7 @@ struct menuitem g_ExtendedMouseMenuItems[] = {
|
|||||||
0,
|
0,
|
||||||
MENUITEMFLAG_LITERAL_TEXT | MENUITEMFLAG_SLIDER_WIDE,
|
MENUITEMFLAG_LITERAL_TEXT | MENUITEMFLAG_SLIDER_WIDE,
|
||||||
(uintptr_t)"Mouse Speed X",
|
(uintptr_t)"Mouse Speed X",
|
||||||
1000,
|
3000,
|
||||||
menuhandlerMouseSpeedX,
|
menuhandlerMouseSpeedX,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -333,7 +331,7 @@ struct menuitem g_ExtendedMouseMenuItems[] = {
|
|||||||
0,
|
0,
|
||||||
MENUITEMFLAG_LITERAL_TEXT | MENUITEMFLAG_SLIDER_WIDE,
|
MENUITEMFLAG_LITERAL_TEXT | MENUITEMFLAG_SLIDER_WIDE,
|
||||||
(uintptr_t)"Mouse Speed Y",
|
(uintptr_t)"Mouse Speed Y",
|
||||||
1000,
|
3000,
|
||||||
menuhandlerMouseSpeedY,
|
menuhandlerMouseSpeedY,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -910,6 +908,20 @@ static MenuItemHandlerResult menuhandlerTexFilter2D(s32 operation, struct menuit
|
|||||||
return 0;
|
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)
|
static MenuItemHandlerResult menuhandlerDisplayFPS(s32 operation, struct menuitem *item, union handlerdata *data)
|
||||||
{
|
{
|
||||||
switch (operation) {
|
switch (operation) {
|
||||||
@@ -996,6 +1008,34 @@ static MenuItemHandlerResult menuhandlerScreenShake(s32 operation, struct menuit
|
|||||||
return 0;
|
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[] = {
|
struct menuitem g_ExtendedVideoMenuItems[] = {
|
||||||
{
|
{
|
||||||
MENUITEMTYPE_CHECKBOX,
|
MENUITEMTYPE_CHECKBOX,
|
||||||
@@ -1101,6 +1141,14 @@ struct menuitem g_ExtendedVideoMenuItems[] = {
|
|||||||
0,
|
0,
|
||||||
menuhandlerTexFilter2D,
|
menuhandlerTexFilter2D,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
MENUITEMTYPE_SLIDER,
|
||||||
|
0,
|
||||||
|
MENUITEMFLAG_LITERAL_TEXT | MENUITEMFLAG_SLIDER_WIDE,
|
||||||
|
(uintptr_t)"Anisotropic Filtering",
|
||||||
|
8,
|
||||||
|
menuhandlerAnisotropicFiltering,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
MENUITEMTYPE_CHECKBOX,
|
MENUITEMTYPE_CHECKBOX,
|
||||||
0,
|
0,
|
||||||
@@ -1149,6 +1197,30 @@ struct menuitem g_ExtendedVideoMenuItems[] = {
|
|||||||
0,
|
0,
|
||||||
NULL,
|
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,
|
MENUITEMTYPE_SELECTABLE,
|
||||||
0,
|
0,
|
||||||
@@ -1293,6 +1365,22 @@ static MenuItemHandlerResult menuhandlerCrosshairSway(s32 operation, struct menu
|
|||||||
return 0;
|
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)
|
static MenuItemHandlerResult menuhandlerCrosshairR(s32 operation, struct menuitem* item, union handlerdata* data)
|
||||||
{
|
{
|
||||||
u32 newColor;
|
u32 newColor;
|
||||||
@@ -1514,6 +1602,14 @@ struct menuitem g_ExtendedGameMenuItems[] = {
|
|||||||
20,
|
20,
|
||||||
menuhandlerCrosshairSway,
|
menuhandlerCrosshairSway,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
MENUITEMTYPE_SLIDER,
|
||||||
|
0,
|
||||||
|
MENUITEMFLAG_LITERAL_TEXT | MENUITEMFLAG_SLIDER_WIDE,
|
||||||
|
(uintptr_t)"Crosshair Edge Deadzone",
|
||||||
|
10,
|
||||||
|
menuhandlerCrosshairEdgeBoundary,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
MENUITEMTYPE_SLIDER,
|
MENUITEMTYPE_SLIDER,
|
||||||
0,
|
0,
|
||||||
@@ -1925,3 +2021,22 @@ struct menudialogdef g_ExtendedMenuDialog = {
|
|||||||
MENUDIALOGFLAG_LITERAL_TEXT,
|
MENUDIALOGFLAG_LITERAL_TEXT,
|
||||||
NULL,
|
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();
|
||||||
|
}
|
||||||
@@ -462,6 +462,9 @@ void mainLoop(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (g_Vars.coopplayernum >= 0 || g_Vars.antiplayernum >= 0) {
|
if (g_Vars.coopplayernum >= 0 || g_Vars.antiplayernum >= 0) {
|
||||||
|
if (g_MpSetup.chrslots & 0xfff0) {
|
||||||
|
g_MpSetup.storedbotbits = g_MpSetup.chrslots & 0xfff0;
|
||||||
|
}
|
||||||
g_MpSetup.chrslots = 0x03;
|
g_MpSetup.chrslots = 0x03;
|
||||||
mpReset();
|
mpReset();
|
||||||
} else if (g_Vars.perfectbuddynum) {
|
} else if (g_Vars.perfectbuddynum) {
|
||||||
|
|||||||
+55
-8
@@ -45,15 +45,19 @@ static s32 vidFramerateLimit = 0;
|
|||||||
static s32 vidDisplayFPS = 0;
|
static s32 vidDisplayFPS = 0;
|
||||||
static f32 vidDisplayFPSInterval = 1.f;
|
static f32 vidDisplayFPSInterval = 1.f;
|
||||||
static f32 vidAvgFPS = 0;
|
static f32 vidAvgFPS = 0;
|
||||||
static f64 vidLastRenderTime;
|
|
||||||
|
|
||||||
static s32 vidNumModes = 1;
|
static s32 vidNumModes = 1;
|
||||||
static displaymode vidModeDefault;
|
static displaymode vidModeDefault;
|
||||||
static displaymode *vidModes = &vidModeDefault;
|
static displaymode *vidModes = &vidModeDefault;
|
||||||
|
|
||||||
|
static f32 vidGlareBrightness = 1.f;
|
||||||
|
static f32 vidOverexposureScale = 1.f;
|
||||||
|
|
||||||
static s32 texFilter = FILTER_LINEAR;
|
static s32 texFilter = FILTER_LINEAR;
|
||||||
static s32 texFilter2D = true;
|
static s32 texFilter2D = true;
|
||||||
static s32 texDetail = false;
|
static s32 texDetail = false;
|
||||||
|
static s32 texMipmapFilter = MIPMAP_LINEAR;
|
||||||
|
static u32 texAnisotropicFilter = 4;
|
||||||
|
|
||||||
static u32 dlcount = 0;
|
static u32 dlcount = 0;
|
||||||
static u32 frames = 0;
|
static u32 frames = 0;
|
||||||
@@ -63,6 +67,7 @@ static f64 fpsTime = 0.0;
|
|||||||
static s32 fpsNumFrames = 0;
|
static s32 fpsNumFrames = 0;
|
||||||
|
|
||||||
static s32 videoInitDisplayModes(void);
|
static s32 videoInitDisplayModes(void);
|
||||||
|
void optionsMenuInit();
|
||||||
|
|
||||||
s32 videoInit(void)
|
s32 videoInit(void)
|
||||||
{
|
{
|
||||||
@@ -100,6 +105,9 @@ s32 videoInit(void)
|
|||||||
videoSetFramerateLimit(vidFramerateLimit);
|
videoSetFramerateLimit(vidFramerateLimit);
|
||||||
|
|
||||||
gfx_set_texture_filter((enum FilteringMode)texFilter);
|
gfx_set_texture_filter((enum FilteringMode)texFilter);
|
||||||
|
gfx_set_mipmap_filter((enum MipmapFilteringMode)texMipmapFilter);
|
||||||
|
videoSetAnisotropicFilter(texAnisotropicFilter);
|
||||||
|
optionsMenuInit();
|
||||||
|
|
||||||
initDone = true;
|
initDone = true;
|
||||||
return 0;
|
return 0;
|
||||||
@@ -139,23 +147,17 @@ void videoEndFrame(void)
|
|||||||
const f64 flipTime = wmAPI->get_time();
|
const f64 flipTime = wmAPI->get_time();
|
||||||
accumDelta += flipTime - endTime;
|
accumDelta += flipTime - endTime;
|
||||||
endTime = flipTime;
|
endTime = flipTime;
|
||||||
vidLastRenderTime = endTime - startTime;
|
|
||||||
|
|
||||||
if (endTime >= fpsTime) {
|
if (endTime >= fpsTime) {
|
||||||
char tmp[128];
|
char tmp[128];
|
||||||
vidAvgFPS = fpsNumFrames ? ((f64)fpsNumFrames / accumDelta) : 0.f;
|
vidAvgFPS = fpsNumFrames ? ((f64)fpsNumFrames / accumDelta) : 0.f;
|
||||||
fpsNumFrames = 0;
|
fpsNumFrames = 0;
|
||||||
accumDelta = 0.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;
|
fpsTime = endTime + vidDisplayFPSInterval;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
f64 videoGetLastRenderTime(void)
|
|
||||||
{
|
|
||||||
return vidLastRenderTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
f32 videoGetAverageFPS(void)
|
f32 videoGetAverageFPS(void)
|
||||||
{
|
{
|
||||||
@@ -369,11 +371,31 @@ u32 videoGetTextureFilter(void)
|
|||||||
return texFilter;
|
return texFilter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u32 videoGetAnisotropicFilter()
|
||||||
|
{
|
||||||
|
return texAnisotropicFilter;
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 videoGetMaxAnisotropyLevel()
|
||||||
|
{
|
||||||
|
return renderingAPI->get_max_anisotropy_level();
|
||||||
|
}
|
||||||
|
|
||||||
s32 videoGetDetailTextures(void)
|
s32 videoGetDetailTextures(void)
|
||||||
{
|
{
|
||||||
return texDetail;
|
return texDetail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
f32 videoGetGlareBrightness(void)
|
||||||
|
{
|
||||||
|
return vidGlareBrightness;
|
||||||
|
}
|
||||||
|
|
||||||
|
f32 videoGetOverexposureScale(void)
|
||||||
|
{
|
||||||
|
return vidOverexposureScale;
|
||||||
|
}
|
||||||
|
|
||||||
void videoSetWindowOffset(s32 x, s32 y)
|
void videoSetWindowOffset(s32 x, s32 y)
|
||||||
{
|
{
|
||||||
gfx_current_game_window_viewport.x = x;
|
gfx_current_game_window_viewport.x = x;
|
||||||
@@ -441,12 +463,28 @@ void videoSetTextureFilter2D(s32 filter)
|
|||||||
texFilter2D = !!filter;
|
texFilter2D = !!filter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void videoSetAnisotropicFilter(u32 level)
|
||||||
|
{
|
||||||
|
texAnisotropicFilter = level;
|
||||||
|
renderingAPI->set_anisotropy_level(level);
|
||||||
|
}
|
||||||
|
|
||||||
void videoSetDetailTextures(s32 detail)
|
void videoSetDetailTextures(s32 detail)
|
||||||
{
|
{
|
||||||
texDetail = !!detail;
|
texDetail = !!detail;
|
||||||
gfx_detail_textures_enabled = (bool)texDetail;
|
gfx_detail_textures_enabled = (bool)texDetail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void videoSetGlareBrightness(f32 bright)
|
||||||
|
{
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
|
||||||
s32 videoCreateFramebuffer(u32 w, u32 h, s32 upscale, s32 autoresize)
|
s32 videoCreateFramebuffer(u32 w, u32 h, s32 upscale, s32 autoresize)
|
||||||
{
|
{
|
||||||
return gfx_create_framebuffer(w, h, upscale, autoresize);
|
return gfx_create_framebuffer(w, h, upscale, autoresize);
|
||||||
@@ -515,6 +553,11 @@ void videoFreeCachedTexture(const void *texptr)
|
|||||||
gfx_texture_cache_delete(texptr);
|
gfx_texture_cache_delete(texptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void videoFreeCachedTextures(const void *start, const void *end)
|
||||||
|
{
|
||||||
|
gfx_texture_cache_delete_range(start, end);
|
||||||
|
}
|
||||||
|
|
||||||
void videoShutdown(void)
|
void videoShutdown(void)
|
||||||
{
|
{
|
||||||
free(vidModes);
|
free(vidModes);
|
||||||
@@ -538,4 +581,8 @@ PD_CONSTRUCTOR static void videoConfigInit(void)
|
|||||||
configRegisterInt("Video.TextureFilter", &texFilter, 0, 2);
|
configRegisterInt("Video.TextureFilter", &texFilter, 0, 2);
|
||||||
configRegisterInt("Video.TextureFilter2D", &texFilter2D, 0, 1);
|
configRegisterInt("Video.TextureFilter2D", &texFilter2D, 0, 1);
|
||||||
configRegisterInt("Video.DetailTextures", &texDetail, 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);
|
||||||
}
|
}
|
||||||
@@ -7,7 +7,7 @@
|
|||||||
#include "game/game_0b2150.h"
|
#include "game/game_0b2150.h"
|
||||||
#include "game/tex.h"
|
#include "game/tex.h"
|
||||||
#include "game/sky.h"
|
#include "game/sky.h"
|
||||||
#include "game/game_13c510.h"
|
#include "game/artifact.h"
|
||||||
#include "game/bg.h"
|
#include "game/bg.h"
|
||||||
#include "game/stagetable.h"
|
#include "game/stagetable.h"
|
||||||
#include "game/room.h"
|
#include "game/room.h"
|
||||||
@@ -21,8 +21,73 @@
|
|||||||
#include "lib/lib_17ce0.h"
|
#include "lib/lib_17ce0.h"
|
||||||
#include "game/player.h"
|
#include "game/player.h"
|
||||||
#include "game/prop.h"
|
#include "game/prop.h"
|
||||||
|
#include "video.h"
|
||||||
#endif
|
#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;
|
u8 *var800a41a0;
|
||||||
u32 var800a41a4;
|
u32 var800a41a4;
|
||||||
u32 var800a41a8;
|
u32 var800a41a8;
|
||||||
@@ -44,11 +109,25 @@ void artifactsTick(void)
|
|||||||
schedIncrementFrontArtifacts();
|
schedIncrementFrontArtifacts();
|
||||||
}
|
}
|
||||||
|
|
||||||
u16 func0f13c574(f32 arg0)
|
u16 floatToN64Depth(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 value = arg0 * 8.0f;
|
||||||
u32 left;
|
u32 left; // forms the most significant byte of the final u16
|
||||||
u32 right = value;
|
u32 right = value; // forms the least significant byte of the final u16
|
||||||
|
|
||||||
if (value > 0x3f800) {
|
if (value > 0x3f800) {
|
||||||
right = value & 0x7ff;
|
right = value & 0x7ff;
|
||||||
@@ -87,7 +166,7 @@ u16 func0f13c574(f32 arg0)
|
|||||||
return left << 13 | (right << 2);
|
return left << 13 | (right << 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
s32 func0f13c710(f32 arg0)
|
s32 artifactsFloatToInt(f32 arg0)
|
||||||
{
|
{
|
||||||
if (arg0 > 0.0f) {
|
if (arg0 > 0.0f) {
|
||||||
if (arg0 > 2147483520.0f) {
|
if (arg0 > 2147483520.0f) {
|
||||||
@@ -168,6 +247,12 @@ void artifactsCalculateGlaresForRoom(s32 roomnum)
|
|||||||
struct coord *campos = &g_Vars.currentplayer->cam_pos;
|
struct coord *campos = &g_Vars.currentplayer->cam_pos;
|
||||||
struct artifact *artifact;
|
struct artifact *artifact;
|
||||||
|
|
||||||
|
#ifndef PLATFORM_N64
|
||||||
|
if (videoGetGlareBrightness() <= 0.f) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (g_Rooms[roomnum].gfxdata != NULL && g_Rooms[roomnum].loaded240) {
|
if (g_Rooms[roomnum].gfxdata != NULL && g_Rooms[roomnum].loaded240) {
|
||||||
numlights = g_Rooms[roomnum].gfxdata->numlights;
|
numlights = g_Rooms[roomnum].gfxdata->numlights;
|
||||||
|
|
||||||
@@ -232,8 +317,8 @@ void artifactsCalculateGlaresForRoom(s32 roomnum)
|
|||||||
|
|
||||||
if (spdc[3] > 0.0001f) {
|
if (spdc[3] > 0.0001f) {
|
||||||
f20 = 1.0f / spdc[3];
|
f20 = 1.0f / spdc[3];
|
||||||
x = func0f13c710(viewleft + (1.0f + spdc[0] * f20) * (viewwidth * 0.5f));
|
x = artifactsFloatToInt(viewleft + (1.0f + spdc[0] * f20) * (viewwidth * 0.5f));
|
||||||
y = func0f13c710(viewtop + (1.0f - spdc[1] * f20) * (viewheight * 0.5f));
|
y = artifactsFloatToInt(viewtop + (1.0f - spdc[1] * f20) * (viewheight * 0.5f));
|
||||||
f0 = (spdc[2] * f20 * 511.0f + 511.0f) * 32.0f;
|
f0 = (spdc[2] * f20 * 511.0f + 511.0f) * 32.0f;
|
||||||
|
|
||||||
if (f0 < 32576.0f) {
|
if (f0 < 32576.0f) {
|
||||||
@@ -335,8 +420,8 @@ void artifactsCalculateGlaresForRoom(s32 roomnum)
|
|||||||
f20 = -9999.0f;
|
f20 = -9999.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
xi = func0f13c710(viewleft + (1.0f + spdc[0] * f20) * (viewwidth * 0.5f));
|
xi = artifactsFloatToInt(viewleft + (1.0f + spdc[0] * f20) * (viewwidth * 0.5f));
|
||||||
yi = func0f13c710(viewtop + (1.0f - spdc[1] * f20) * (viewheight * 0.5f));
|
yi = artifactsFloatToInt(viewtop + (1.0f - spdc[1] * f20) * (viewheight * 0.5f));
|
||||||
f0 = (spdc[2] * f20 * 511.0f + 511.0f) * 32.0f;
|
f0 = (spdc[2] * f20 * 511.0f + 511.0f) * 32.0f;
|
||||||
|
|
||||||
if (g_ZbufPtr1
|
if (g_ZbufPtr1
|
||||||
@@ -357,14 +442,20 @@ void artifactsCalculateGlaresForRoom(s32 roomnum)
|
|||||||
|
|
||||||
if (index < MAX_ARTIFACTS) {
|
if (index < MAX_ARTIFACTS) {
|
||||||
#ifndef PLATFORM_N64
|
#ifndef PLATFORM_N64
|
||||||
artifact->unk02 = artifactTestLos(&spec, &g_BgRooms[roomnum].pos, xi, yi);
|
artifact->visiblelos = artifactTestLos(&spec, &g_BgRooms[roomnum].pos, xi, yi);
|
||||||
#endif
|
#endif
|
||||||
artifact->unk04 = func0f13c574(f0) >> 2;
|
/**
|
||||||
artifact->unk08 = &g_ZbufPtr1[viGetWidth() * yi + xi];
|
* 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->light = &roomlights[i];
|
artifact->light = &roomlights[i];
|
||||||
artifact->type = ARTIFACTTYPE_GLARE;
|
artifact->type = ARTIFACTTYPE_GLARE;
|
||||||
artifact->unk0c.u16_2 = xi;
|
artifact->screenx = xi;
|
||||||
artifact->unk0c.u16_1 = yi;
|
artifact->screeny = yi;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -375,7 +466,7 @@ void artifactsCalculateGlaresForRoom(s32 roomnum)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
u8 func0f13d3c4(u8 arg0, u8 arg1)
|
u8 artifactsClamp(u8 arg0, u8 arg1)
|
||||||
{
|
{
|
||||||
if (arg1 >= arg0 + 7) {
|
if (arg1 >= arg0 + 7) {
|
||||||
return arg0 + 7;
|
return arg0 + 7;
|
||||||
@@ -423,18 +514,18 @@ Gfx *artifactsRenderGlaresForRoom(Gfx *gdl, s32 roomnum)
|
|||||||
u16 min;
|
u16 min;
|
||||||
u16 max;
|
u16 max;
|
||||||
f32 lightop_cur_frac;
|
f32 lightop_cur_frac;
|
||||||
s32 t2;
|
s32 numgood;
|
||||||
struct light *light;
|
struct light *light;
|
||||||
u8 *s3;
|
u8 *s3;
|
||||||
s32 k;
|
s32 k;
|
||||||
s32 count;
|
s32 count;
|
||||||
u16 t4;
|
u16 actualdepth;
|
||||||
f32 add;
|
f32 add;
|
||||||
s32 l;
|
s32 l;
|
||||||
f32 brightness;
|
f32 brightness;
|
||||||
s32 avg;
|
s32 tolerance;
|
||||||
f32 f0;
|
f32 f0;
|
||||||
s32 v1;
|
s32 difference;
|
||||||
s32 r;
|
s32 r;
|
||||||
s32 g;
|
s32 g;
|
||||||
s32 b;
|
s32 b;
|
||||||
@@ -448,6 +539,13 @@ Gfx *artifactsRenderGlaresForRoom(Gfx *gdl, s32 roomnum)
|
|||||||
f32 f24;
|
f32 f24;
|
||||||
bool extra;
|
bool extra;
|
||||||
f32 f26;
|
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();
|
artifacts = schedGetFrontArtifacts();
|
||||||
lightop_cur_frac = roomGetLightOpCurFrac(roomnum);
|
lightop_cur_frac = roomGetLightOpCurFrac(roomnum);
|
||||||
@@ -460,6 +558,12 @@ Gfx *artifactsRenderGlaresForRoom(Gfx *gdl, s32 roomnum)
|
|||||||
struct light *light2 = artifacts[i].light;
|
struct light *light2 = artifacts[i].light;
|
||||||
count = 0;
|
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++) {
|
for (j = i; j < MAX_ARTIFACTS && artifacts[j].type == ARTIFACTTYPE_GLARE && artifacts[j].light == light2; j++) {
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
@@ -470,52 +574,70 @@ Gfx *artifactsRenderGlaresForRoom(Gfx *gdl, s32 roomnum)
|
|||||||
if (roomnum == light->roomnum) {
|
if (roomnum == light->roomnum) {
|
||||||
lightindex = ((uintptr_t)light - (uintptr_t)g_BgLightsFileData) / sizeof(struct light);
|
lightindex = ((uintptr_t)light - (uintptr_t)g_BgLightsFileData) / sizeof(struct light);
|
||||||
s3 = &var800a41a0[lightindex * 3];
|
s3 = &var800a41a0[lightindex * 3];
|
||||||
t2 = 0;
|
numgood = 0;
|
||||||
min = 0xffff;
|
min = 0xffff;
|
||||||
max = 0;
|
max = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* loop to determine the min & max depth of
|
||||||
|
* the sub-artifacts composing this room light.
|
||||||
|
*/
|
||||||
for (k = i; k < i + count; k++) {
|
for (k = i; k < i + count; k++) {
|
||||||
if (artifacts[k].unk04 > max) {
|
if (artifacts[k].expecteddepth > max) {
|
||||||
max = artifacts[k].unk04;
|
max = artifacts[k].expecteddepth;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (artifacts[k].unk04 < min) {
|
if (artifacts[k].expecteddepth < min) {
|
||||||
min = artifacts[k].unk04;
|
min = artifacts[k].expecteddepth;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
avg = (max - min) >> 1;
|
/**
|
||||||
|
* 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;
|
||||||
|
|
||||||
if (avg < 25) {
|
if (tolerance < 25) {
|
||||||
avg = 25;
|
tolerance = 25;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (k = i; k < i + count; k++) {
|
for (k = i; k < i + count; k++) {
|
||||||
#ifdef PLATFORM_N64
|
#ifdef PLATFORM_N64
|
||||||
u16 tmp;
|
u16 expecteddepth;
|
||||||
t4 = (artifacts[k].unk02 & 0xfffc) >> 2;
|
actualdepth = (artifacts[k].actualdepth & 0xfffc) >> 2;
|
||||||
tmp = artifacts[k].unk04;
|
expecteddepth = artifacts[k].expecteddepth;
|
||||||
|
|
||||||
if (tmp < t4) {
|
if (expecteddepth < actualdepth) {
|
||||||
v1 = t4 - tmp;
|
difference = actualdepth - expecteddepth;
|
||||||
} else {
|
} else {
|
||||||
v1 = tmp - t4;
|
difference = expecteddepth - actualdepth;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (avg >= v1) {
|
if (difference <= tolerance) {
|
||||||
t2++;
|
numgood++;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
t2 += artifacts[k].unk02;
|
numgood += artifacts[k].visiblelos;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
artifacts[k].type = ARTIFACTTYPE_FREE;
|
artifacts[k].type = ARTIFACTTYPE_FREE;
|
||||||
}
|
}
|
||||||
|
|
||||||
s3[0] = func0f13d3c4(s3[0], t2 * 2);
|
s3[0] = artifactsClamp(s3[0], numgood * 2);
|
||||||
|
|
||||||
if (t2 > 0) {
|
if (numgood > 0) {
|
||||||
|
#ifndef PLATFORM_N64
|
||||||
|
brightness = viGetFovY() / pfov;
|
||||||
|
#else
|
||||||
brightness = viGetFovY() * 0.017453292f;
|
brightness = viGetFovY() * 0.017453292f;
|
||||||
|
#endif
|
||||||
add = cosf(brightness) / sinf(brightness) * 14.6f;
|
add = cosf(brightness) / sinf(brightness) * 14.6f;
|
||||||
|
|
||||||
if (lightIsHealthy(roomnum, lightindex - g_Rooms[roomnum].gfxdata->lightsindex)) {
|
if (lightIsHealthy(roomnum, lightindex - g_Rooms[roomnum].gfxdata->lightsindex)) {
|
||||||
@@ -545,6 +667,9 @@ Gfx *artifactsRenderGlaresForRoom(Gfx *gdl, s32 roomnum)
|
|||||||
}
|
}
|
||||||
|
|
||||||
f0 = s3[2] * (1.0f / 255.0f);
|
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));
|
skySetOverexposure((s32) ((f32)f0 * r), (s32) ((f32)f0 * g), (s32) ((f32)f0 * b));
|
||||||
|
|
||||||
@@ -594,6 +719,10 @@ Gfx *artifactsRenderGlaresForRoom(Gfx *gdl, s32 roomnum)
|
|||||||
alpha *= (s3[1] / 255.0f);
|
alpha *= (s3[1] / 255.0f);
|
||||||
alpha *= (s3[0] / 8.0f);
|
alpha *= (s3[0] / 8.0f);
|
||||||
|
|
||||||
|
#ifndef PLATFORM_N64
|
||||||
|
alpha *= brightscale;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (USINGDEVICE(DEVICE_NIGHTVISION)) {
|
if (USINGDEVICE(DEVICE_NIGHTVISION)) {
|
||||||
alpha *= lightop_cur_frac * 7.0f;
|
alpha *= lightop_cur_frac * 7.0f;
|
||||||
}
|
}
|
||||||
+15
-1
@@ -15,7 +15,7 @@
|
|||||||
#include "game/sky.h"
|
#include "game/sky.h"
|
||||||
#include "game/stars.h"
|
#include "game/stars.h"
|
||||||
#include "game/dyntex.h"
|
#include "game/dyntex.h"
|
||||||
#include "game/game_13c510.h"
|
#include "game/artifact.h"
|
||||||
#include "game/game_1531a0.h"
|
#include "game/game_1531a0.h"
|
||||||
#include "game/gfxmemory.h"
|
#include "game/gfxmemory.h"
|
||||||
#include "game/gfxreplace.h"
|
#include "game/gfxreplace.h"
|
||||||
@@ -135,6 +135,9 @@ s32 g_BgMostAttemptedDrawSlots = 0;
|
|||||||
s32 g_BgNumRoomLoadCandidates = 0;
|
s32 g_BgNumRoomLoadCandidates = 0;
|
||||||
u16 g_BgFrameCount = 0xfffe;
|
u16 g_BgFrameCount = 0xfffe;
|
||||||
s32 g_BgNumPortalCameraCacheItems = 0;
|
s32 g_BgNumPortalCameraCacheItems = 0;
|
||||||
|
#ifndef PLATFORM_N64
|
||||||
|
bool g_BgHitXluDisabled = false;
|
||||||
|
#endif
|
||||||
|
|
||||||
void bgUnpausePropsInRoom(u32 roomnum, bool tintedglassonly)
|
void bgUnpausePropsInRoom(u32 roomnum, bool tintedglassonly)
|
||||||
{
|
{
|
||||||
@@ -4590,6 +4593,10 @@ bool bgTestHitInRoom(struct coord *frompos, struct coord *topos, s32 roomnum, st
|
|||||||
numbatches = g_Rooms[roomnum].numvtxbatches;
|
numbatches = g_Rooms[roomnum].numvtxbatches;
|
||||||
|
|
||||||
for (i = 0; i < numbatches; batch++, i++) {
|
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);
|
j = bg0f1612e4(&batch->bbmin, &batch->bbmax, &from, &dist, &sp94, &hitthing->pos);
|
||||||
|
|
||||||
if (j == 0) {
|
if (j == 0) {
|
||||||
@@ -6417,6 +6424,10 @@ void bgCalculateGlaresForVisibleRooms(void)
|
|||||||
|
|
||||||
g_NumRoomsWithGlares = 0;
|
g_NumRoomsWithGlares = 0;
|
||||||
|
|
||||||
|
// disable line-of-sight hits for transparent background
|
||||||
|
// surfaces before testing for light obstructions
|
||||||
|
g_BgHitXluDisabled = true;
|
||||||
|
|
||||||
if (!g_Vars.mplayerisrunning) {
|
if (!g_Vars.mplayerisrunning) {
|
||||||
for (i = 1; i < g_Vars.roomcount; i++) {
|
for (i = 1; i < g_Vars.roomcount; i++) {
|
||||||
if (g_Rooms[i].flags & ROOMFLAG_ONSCREEN) {
|
if (g_Rooms[i].flags & ROOMFLAG_ONSCREEN) {
|
||||||
@@ -6427,6 +6438,9 @@ void bgCalculateGlaresForVisibleRooms(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// re-enable background hits for transparent surfaces
|
||||||
|
g_BgHitXluDisabled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
+4
-4
@@ -8477,7 +8477,7 @@ glabel var7f1aca90
|
|||||||
/* f0a71e4: 100002d5 */ b .L0f0a7d3c
|
/* f0a71e4: 100002d5 */ b .L0f0a7d3c
|
||||||
/* f0a71e8: 8fbf0034 */ lw $ra,0x34($sp)
|
/* f0a71e8: 8fbf0034 */ lw $ra,0x34($sp)
|
||||||
.L0f0a71ec:
|
.L0f0a71ec:
|
||||||
/* f0a71ec: 0fc5d9ad */ jal zbufDrawArtifactsOffscreen
|
/* f0a71ec: 0fc5d9ad */ jal zbufSaveArtifactDepths
|
||||||
/* f0a71f0: 8fa4014c */ lw $a0,0x14c($sp)
|
/* f0a71f0: 8fa4014c */ lw $a0,0x14c($sp)
|
||||||
/* f0a71f4: afa2014c */ sw $v0,0x14c($sp)
|
/* f0a71f4: afa2014c */ sw $v0,0x14c($sp)
|
||||||
/* f0a71f8: 0c002ca0 */ jal viPrepareZbuf
|
/* f0a71f8: 0c002ca0 */ jal viPrepareZbuf
|
||||||
@@ -9318,7 +9318,7 @@ glabel var7f1aca90
|
|||||||
/* f0a71e4: 100002d5 */ b .L0f0a7d3c
|
/* f0a71e4: 100002d5 */ b .L0f0a7d3c
|
||||||
/* f0a71e8: 8fbf0034 */ lw $ra,0x34($sp)
|
/* f0a71e8: 8fbf0034 */ lw $ra,0x34($sp)
|
||||||
.L0f0a71ec:
|
.L0f0a71ec:
|
||||||
/* f0a71ec: 0fc5d9ad */ jal zbufDrawArtifactsOffscreen
|
/* f0a71ec: 0fc5d9ad */ jal zbufSaveArtifactDepths
|
||||||
/* f0a71f0: 8fa4014c */ lw $a0,0x14c($sp)
|
/* f0a71f0: 8fa4014c */ lw $a0,0x14c($sp)
|
||||||
/* f0a71f4: afa2014c */ sw $v0,0x14c($sp)
|
/* f0a71f4: afa2014c */ sw $v0,0x14c($sp)
|
||||||
/* f0a71f8: 0c002ca0 */ jal viPrepareZbuf
|
/* f0a71f8: 0c002ca0 */ jal viPrepareZbuf
|
||||||
@@ -10159,7 +10159,7 @@ glabel var7f1aca90
|
|||||||
/* f0a4f30: 100002cd */ beqz $zero,.NB0f0a5a68
|
/* f0a4f30: 100002cd */ beqz $zero,.NB0f0a5a68
|
||||||
/* f0a4f34: 8fbf0034 */ lw $ra,0x34($sp)
|
/* f0a4f34: 8fbf0034 */ lw $ra,0x34($sp)
|
||||||
.NB0f0a4f38:
|
.NB0f0a4f38:
|
||||||
/* f0a4f38: 0fc5c4d5 */ jal zbufDrawArtifactsOffscreen
|
/* f0a4f38: 0fc5c4d5 */ jal zbufSaveArtifactDepths
|
||||||
/* f0a4f3c: 8fa40144 */ lw $a0,0x144($sp)
|
/* f0a4f3c: 8fa40144 */ lw $a0,0x144($sp)
|
||||||
/* f0a4f40: afa20144 */ sw $v0,0x144($sp)
|
/* f0a4f40: afa20144 */ sw $v0,0x144($sp)
|
||||||
/* f0a4f44: 0c002d00 */ jal viPrepareZbuf
|
/* f0a4f44: 0c002d00 */ jal viPrepareZbuf
|
||||||
@@ -10957,7 +10957,7 @@ void bgunRender(Gfx **gdlptr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef PLATFORM_N64 // TODO
|
#ifdef PLATFORM_N64 // TODO
|
||||||
gdl = zbufDrawArtifactsOffscreen(gdl);
|
gdl = zbufSaveArtifactDepths(gdl);
|
||||||
#endif
|
#endif
|
||||||
gdl = viPrepareZbuf(gdl);
|
gdl = viPrepareZbuf(gdl);
|
||||||
gdl = vi0000b1d0(gdl);
|
gdl = vi0000b1d0(gdl);
|
||||||
|
|||||||
+87
-42
@@ -329,11 +329,11 @@ void bmoveUpdateSpeedTheta(void)
|
|||||||
f32 bmoveGetSpeedVertaLimit(f32 value)
|
f32 bmoveGetSpeedVertaLimit(f32 value)
|
||||||
{
|
{
|
||||||
if (value > 0) {
|
if (value > 0) {
|
||||||
return (viGetFovY() * value * -0.7f) / 60.0f;
|
return (viGetFovY() * value * -0.7f) / PLAYER_DEFAULT_FOV;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (value < 0) {
|
if (value < 0) {
|
||||||
return (viGetFovY() * -value * 0.7f) / 60.0f;
|
return (viGetFovY() * -value * 0.7f) / PLAYER_DEFAULT_FOV;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -341,7 +341,7 @@ f32 bmoveGetSpeedVertaLimit(f32 value)
|
|||||||
|
|
||||||
void bmoveUpdateSpeedVerta(f32 value)
|
void bmoveUpdateSpeedVerta(f32 value)
|
||||||
{
|
{
|
||||||
f32 mult = viGetFovY() / 60.0f;
|
f32 mult = viGetFovY() / PLAYER_DEFAULT_FOV;
|
||||||
f32 limit = bmoveGetSpeedVertaLimit(value);
|
f32 limit = bmoveGetSpeedVertaLimit(value);
|
||||||
|
|
||||||
if (value > 0) {
|
if (value > 0) {
|
||||||
@@ -384,11 +384,11 @@ void bmoveUpdateSpeedVerta(f32 value)
|
|||||||
f32 bmoveGetSpeedThetaControlLimit(f32 value)
|
f32 bmoveGetSpeedThetaControlLimit(f32 value)
|
||||||
{
|
{
|
||||||
if (value > 0) {
|
if (value > 0) {
|
||||||
return (viGetFovY() * value * -0.7f) / 60.0f;
|
return (viGetFovY() * value * -0.7f) / PLAYER_DEFAULT_FOV;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (value < 0) {
|
if (value < 0) {
|
||||||
return (viGetFovY() * -value * 0.7f) / 60.0f;
|
return (viGetFovY() * -value * 0.7f) / PLAYER_DEFAULT_FOV;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -396,7 +396,7 @@ f32 bmoveGetSpeedThetaControlLimit(f32 value)
|
|||||||
|
|
||||||
void bmoveUpdateSpeedThetaControl(f32 value)
|
void bmoveUpdateSpeedThetaControl(f32 value)
|
||||||
{
|
{
|
||||||
f32 mult = viGetFovY() / 60.0f;
|
f32 mult = viGetFovY() / PLAYER_DEFAULT_FOV;
|
||||||
f32 limit = bmoveGetSpeedThetaControlLimit(value);
|
f32 limit = bmoveGetSpeedThetaControlLimit(value);
|
||||||
|
|
||||||
if (value > 0) {
|
if (value > 0) {
|
||||||
@@ -436,6 +436,38 @@ 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.
|
* Calculate the lookahead angle.
|
||||||
*
|
*
|
||||||
@@ -1412,31 +1444,31 @@ void bmoveProcessInput(bool allowc1x, bool allowc1y, bool allowc1buttons, bool i
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifndef PLATFORM_N64
|
#ifndef PLATFORM_N64
|
||||||
// Handle turning and looking up/down via mouselook when aiming
|
// Handle turning and looking (x/y) via mouselook when aiming
|
||||||
if (g_Vars.currentplayer->insightaimmode && allowmcross && bgunGetWeaponNum(HAND_RIGHT) != WEAPON_HORIZONSCANNER) {
|
bool allowcross = allowmcross;
|
||||||
if (g_Vars.currentplayer->swivelpos[0] > 0.9f) {
|
if (g_Vars.currentplayer->insightaimmode && allowcross && bgunGetWeaponNum(HAND_RIGHT) != WEAPON_HORIZONSCANNER) {
|
||||||
movedata.aimturnrightspeed = (g_Vars.currentplayer->swivelpos[0] - 0.9f) / 0.1f;
|
float edge_boundary = PLAYER_EXTCFG().crosshairedgeboundary;
|
||||||
movedata.aimturnleftspeed = 0.f;
|
if (g_Vars.currentplayer->swivelpos[0] > edge_boundary) {
|
||||||
} else if (g_Vars.currentplayer->swivelpos[0] < -0.9f) {
|
movedata.aimturnrightspeed += (g_Vars.currentplayer->swivelpos[0] - edge_boundary) / (1.0f - edge_boundary);
|
||||||
movedata.aimturnleftspeed = (g_Vars.currentplayer->swivelpos[0] - -0.9f) / -0.1f;
|
} else if (g_Vars.currentplayer->swivelpos[0] < -edge_boundary) {
|
||||||
movedata.aimturnrightspeed = 0.f;
|
movedata.aimturnleftspeed += (g_Vars.currentplayer->swivelpos[0] + edge_boundary) / -(1.0f - edge_boundary);
|
||||||
}
|
}
|
||||||
f32 vertaup = 0.f, vertadown = 0.f;
|
f32 vertaup = 0.f, vertadown = 0.f;
|
||||||
if (g_Vars.currentplayer->swivelpos[1] > 0.9f) {
|
if (g_Vars.currentplayer->swivelpos[1] > edge_boundary) {
|
||||||
vertaup = (g_Vars.currentplayer->swivelpos[1] - 0.9f) / 0.1f;
|
vertaup = (g_Vars.currentplayer->swivelpos[1] - edge_boundary) / (1.0f - edge_boundary);
|
||||||
} else if (g_Vars.currentplayer->swivelpos[1] < -0.9f) {
|
} else if (g_Vars.currentplayer->swivelpos[1] < -edge_boundary) {
|
||||||
vertadown = (g_Vars.currentplayer->swivelpos[1] - -0.9f) / -0.1f;
|
vertadown = (g_Vars.currentplayer->swivelpos[1] + edge_boundary) / -(1.0f - edge_boundary);
|
||||||
}
|
}
|
||||||
// Uninvert pitch if needed
|
// Uninvert pitch if needed
|
||||||
if (movedata.invertpitch) {
|
if (movedata.invertpitch) {
|
||||||
movedata.speedvertaup = vertadown;
|
movedata.speedvertaup += vertadown;
|
||||||
movedata.speedvertadown = vertaup;
|
movedata.speedvertadown += vertaup;
|
||||||
} else {
|
} else {
|
||||||
movedata.speedvertaup = vertaup;
|
movedata.speedvertaup += vertaup;
|
||||||
movedata.speedvertadown = vertadown;
|
movedata.speedvertadown += vertadown;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Reset mouse aim position when not mouse aiming
|
// Reset mouse aim position when not aiming
|
||||||
g_Vars.currentplayer->swivelpos[0] = 0.f;
|
g_Vars.currentplayer->swivelpos[0] = 0.f;
|
||||||
g_Vars.currentplayer->swivelpos[1] = 0.f;
|
g_Vars.currentplayer->swivelpos[1] = 0.f;
|
||||||
}
|
}
|
||||||
@@ -1801,7 +1833,12 @@ void bmoveProcessInput(bool allowc1x, bool allowc1y, bool allowc1buttons, bool i
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef PLATFORM_N64
|
||||||
if (controlmode == CONTROLMODE_12 || controlmode == CONTROLMODE_14 || controlmode == CONTROLMODE_PC) {
|
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;
|
movedata.disablelookahead = true;
|
||||||
}
|
}
|
||||||
} // end 1.x
|
} // end 1.x
|
||||||
@@ -1960,6 +1997,22 @@ void bmoveProcessInput(bool allowc1x, bool allowc1y, bool allowc1buttons, bool i
|
|||||||
lookahead = g_Vars.currentplayer->cachedlookahead;
|
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
|
if (g_Vars.currentplayer->movecentrerelease
|
||||||
&& movedata.analogwalk < 40 && movedata.analogwalk > -40) {
|
&& movedata.analogwalk < 40 && movedata.analogwalk > -40) {
|
||||||
g_Vars.currentplayer->movecentrerelease = false;
|
g_Vars.currentplayer->movecentrerelease = false;
|
||||||
@@ -2032,7 +2085,7 @@ void bmoveProcessInput(bool allowc1x, bool allowc1y, bool allowc1buttons, bool i
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (movedata.cannaturalpitch) {
|
if (movedata.cannaturalpitch) {
|
||||||
tmp = viGetFovY() / 60.0f;
|
tmp = viGetFovY() / PLAYER_DEFAULT_FOV;
|
||||||
fVar25 = movedata.analogpitch / 70.0f;
|
fVar25 = movedata.analogpitch / 70.0f;
|
||||||
|
|
||||||
if (fVar25 > 1) {
|
if (fVar25 > 1) {
|
||||||
@@ -2073,7 +2126,7 @@ void bmoveProcessInput(bool allowc1x, bool allowc1y, bool allowc1buttons, bool i
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (movedata.cannaturalturn) {
|
if (movedata.cannaturalturn) {
|
||||||
tmp = viGetFovY() / 60.0f;
|
tmp = viGetFovY() / PLAYER_DEFAULT_FOV;
|
||||||
fVar25 = movedata.analogturn / 70.0f;
|
fVar25 = movedata.analogturn / 70.0f;
|
||||||
|
|
||||||
if (fVar25 > 1) {
|
if (fVar25 > 1) {
|
||||||
@@ -2186,15 +2239,8 @@ void bmoveProcessInput(bool allowc1x, bool allowc1y, bool allowc1buttons, bool i
|
|||||||
x = g_Vars.currentplayer->speedtheta * 0.3f + g_Vars.currentplayer->gunextraaimx;
|
x = g_Vars.currentplayer->speedtheta * 0.3f + g_Vars.currentplayer->gunextraaimx;
|
||||||
y = -g_Vars.currentplayer->speedverta * 0.1f + g_Vars.currentplayer->gunextraaimy;
|
y = -g_Vars.currentplayer->speedverta * 0.1f + g_Vars.currentplayer->gunextraaimy;
|
||||||
#else
|
#else
|
||||||
f32 xscale, yscale;
|
// Crosshair swivel movement system
|
||||||
if (movedata.freelookdx || movedata.freelookdy) {
|
bmoveApplyCrosshairSwivel(&movedata, mlookscale, &x, &y);
|
||||||
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
|
#endif
|
||||||
|
|
||||||
bgunSwivelWithDamp(x, y, PAL ? 0.955f : 0.963f);
|
bgunSwivelWithDamp(x, y, PAL ? 0.955f : 0.963f);
|
||||||
@@ -2216,6 +2262,13 @@ void bmoveProcessInput(bool allowc1x, bool allowc1y, bool allowc1buttons, bool i
|
|||||||
y = (y < -1.f) ? -1.f : ((y > 1.f) ? 1.f : y);
|
y = (y < -1.f) ? -1.f : ((y > 1.f) ? 1.f : y);
|
||||||
g_Vars.currentplayer->swivelpos[0] = x;
|
g_Vars.currentplayer->swivelpos[0] = x;
|
||||||
g_Vars.currentplayer->swivelpos[1] = y;
|
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);
|
bgunSwivelWithDamp(x, y, 0.01f);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -2390,14 +2443,6 @@ void bmoveTick(bool allowc1x, bool allowc1y, bool allowc1buttons, bool ignorec2)
|
|||||||
|
|
||||||
void bmoveUpdateVerta(void)
|
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) {
|
if (g_Vars.currentplayer->vv_verta > 90) {
|
||||||
g_Vars.currentplayer->vv_verta = 90;
|
g_Vars.currentplayer->vv_verta = 90;
|
||||||
} else if (g_Vars.currentplayer->vv_verta < -90) {
|
} else if (g_Vars.currentplayer->vv_verta < -90) {
|
||||||
|
|||||||
+2
-1
@@ -262,7 +262,8 @@ void botSpawn(struct chrdata *chr, u8 respawning)
|
|||||||
func0f02e9a0(chr, 0);
|
func0f02e9a0(chr, 0);
|
||||||
|
|
||||||
#ifndef PLATFORM_N64
|
#ifndef PLATFORM_N64
|
||||||
if ((g_MpSetup.options & MPOPTION_SPAWNWITHWEAPON)
|
if (g_Vars.normmplayerisrunning
|
||||||
|
&& (g_MpSetup.options & MPOPTION_SPAWNWITHWEAPON)
|
||||||
&& g_MpSetup.weapons[0] != MPWEAPON_NONE
|
&& g_MpSetup.weapons[0] != MPWEAPON_NONE
|
||||||
&& g_MpSetup.weapons[0] != MPWEAPON_DISABLED
|
&& g_MpSetup.weapons[0] != MPWEAPON_DISABLED
|
||||||
&& g_MpSetup.weapons[0] != MPWEAPON_SHIELD) {
|
&& g_MpSetup.weapons[0] != MPWEAPON_SHIELD) {
|
||||||
|
|||||||
+28
-4
@@ -165,6 +165,17 @@ void cheatActivate(s32 cheat_id)
|
|||||||
setCurrentPlayerNum(prevplayernum);
|
setCurrentPlayerNum(prevplayernum);
|
||||||
break;
|
break;
|
||||||
case CHEAT_ALLGUNS:
|
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
|
// Give all guns if only one player playing
|
||||||
if (PLAYERCOUNT() == 1 && g_Vars.normmplayerisrunning == false) {
|
if (PLAYERCOUNT() == 1 && g_Vars.normmplayerisrunning == false) {
|
||||||
prevplayernum = g_Vars.currentplayernum;
|
prevplayernum = g_Vars.currentplayernum;
|
||||||
@@ -176,6 +187,7 @@ void cheatActivate(s32 cheat_id)
|
|||||||
|
|
||||||
setCurrentPlayerNum(prevplayernum);
|
setCurrentPlayerNum(prevplayernum);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -203,6 +215,16 @@ void cheatDeactivate(s32 cheat_id)
|
|||||||
setCurrentPlayerNum(prevplayernum);
|
setCurrentPlayerNum(prevplayernum);
|
||||||
break;
|
break;
|
||||||
case CHEAT_ALLGUNS:
|
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) {
|
if (PLAYERCOUNT() == 1 && g_Vars.normmplayerisrunning == false) {
|
||||||
prevplayernum = g_Vars.currentplayernum;
|
prevplayernum = g_Vars.currentplayernum;
|
||||||
|
|
||||||
@@ -213,6 +235,7 @@ void cheatDeactivate(s32 cheat_id)
|
|||||||
|
|
||||||
setCurrentPlayerNum(prevplayernum);
|
setCurrentPlayerNum(prevplayernum);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -309,7 +332,7 @@ MenuItemHandlerResult cheatCheckboxMenuHandler(s32 operation, struct menuitem *i
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (g_CheatsEnabledBank1 & (1 << item->param)) {
|
if (g_CheatsEnabledBank1 & (1 << (item->param - 32))) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -334,11 +357,12 @@ MenuItemHandlerResult cheatCheckboxMenuHandler(s32 operation, struct menuitem *i
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Bank 1
|
// Bank 1
|
||||||
if (g_CheatsEnabledBank1 & (1 << item->param)) {
|
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 (1);
|
if (1);
|
||||||
g_CheatsEnabledBank1 = g_CheatsEnabledBank1 & ~(1 << item->param);
|
g_CheatsEnabledBank1 = g_CheatsEnabledBank1 & ~(1 << (item->param - 32));
|
||||||
} else {
|
} else {
|
||||||
g_CheatsEnabledBank1 = g_CheatsEnabledBank1 | 1 << item->param;
|
g_CheatsEnabledBank1 = g_CheatsEnabledBank1 | (1 << (item->param - 32));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+24
-1
@@ -2633,6 +2633,19 @@ s32 chrTick(struct prop *prop)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if VERSION >= VERSION_NTSC_1_0
|
#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 (!g_Vars.normmplayerisrunning && needsupdate) {
|
||||||
if (chr->actiontype == ACT_DEAD
|
if (chr->actiontype == ACT_DEAD
|
||||||
|| (chr->actiontype == ACT_DRUGGEDKO && (chr->chrflags & CHRCFLAG_KEEPCORPSEKO) == 0)) {
|
|| (chr->actiontype == ACT_DRUGGEDKO && (chr->chrflags & CHRCFLAG_KEEPCORPSEKO) == 0)) {
|
||||||
@@ -4544,7 +4557,17 @@ void chrTestHit(struct prop *prop, struct shotdata *shotdata, bool isshooting, b
|
|||||||
|
|
||||||
if (hitpart) {
|
if (hitpart) {
|
||||||
if (chrGetShield(chr) > 0.0f) {
|
if (chrGetShield(chr) > 0.0f) {
|
||||||
var8005efc0 = 10.0f / model->scale;
|
#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;
|
||||||
}
|
}
|
||||||
|
|
||||||
child = prop->child;
|
child = prop->child;
|
||||||
|
|||||||
+35
-8
@@ -7199,7 +7199,14 @@ bool chrTrySurrender(struct chrdata *chr)
|
|||||||
bool chrFadeOut(struct chrdata *chr)
|
bool chrFadeOut(struct chrdata *chr)
|
||||||
{
|
{
|
||||||
chrBeginDead(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);
|
chrFadeCorpse(chr);
|
||||||
|
#endif
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -8197,6 +8204,12 @@ void chrTickSurrender(struct chrdata *chr)
|
|||||||
|
|
||||||
void chrFadeCorpse(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) {
|
if (chr->actiontype == ACT_DEAD || chr->actiontype == ACT_DRUGGEDKO) {
|
||||||
chr->act_dead.fadenow = true;
|
chr->act_dead.fadenow = true;
|
||||||
}
|
}
|
||||||
@@ -8204,6 +8217,12 @@ void chrFadeCorpse(struct chrdata *chr)
|
|||||||
|
|
||||||
void chrFadeCorpseWhenOffScreen(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) {
|
if (chr->actiontype == ACT_DEAD) {
|
||||||
chr->act_dead.fadewheninvis = true;
|
chr->act_dead.fadewheninvis = true;
|
||||||
}
|
}
|
||||||
@@ -13459,6 +13478,10 @@ void cutsceneStart(u32 ailistid)
|
|||||||
* - Run BG scripts
|
* - Run BG scripts
|
||||||
* - Choose which corpses to fade
|
* - 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)
|
void chraTickBg(void)
|
||||||
{
|
{
|
||||||
s32 i;
|
s32 i;
|
||||||
@@ -13470,10 +13493,10 @@ void chraTickBg(void)
|
|||||||
#if VERSION >= VERSION_NTSC_1_0
|
#if VERSION >= VERSION_NTSC_1_0
|
||||||
s32 spawnslen;
|
s32 spawnslen;
|
||||||
#endif
|
#endif
|
||||||
struct chrdata *onscreen[5];
|
struct chrdata *onscreen[MAX_CORPSES_LIMIT];
|
||||||
struct chrdata *offscreen[5];
|
struct chrdata *offscreen[MAX_CORPSES_LIMIT];
|
||||||
#if VERSION >= VERSION_NTSC_1_0
|
#if VERSION >= VERSION_NTSC_1_0
|
||||||
struct chrdata *spawns[10];
|
struct chrdata *spawns[MAX_CORPSES_LIMIT];
|
||||||
#endif
|
#endif
|
||||||
s32 writeindex;
|
s32 writeindex;
|
||||||
s32 maxdeadonscreen;
|
s32 maxdeadonscreen;
|
||||||
@@ -13599,7 +13622,7 @@ void chraTickBg(void)
|
|||||||
spawns[spawnslen] = chr;
|
spawns[spawnslen] = chr;
|
||||||
spawnslen++;
|
spawnslen++;
|
||||||
|
|
||||||
if (spawnslen >= 10) {
|
if (spawnslen >= (g_MaxCorpses > 0 ? g_MaxCorpses : 10)) {
|
||||||
writeindex = rngRandom() % spawnslen;
|
writeindex = rngRandom() % spawnslen;
|
||||||
chrFadeCorpse(spawns[writeindex]);
|
chrFadeCorpse(spawns[writeindex]);
|
||||||
spawns[writeindex] = spawns[spawnslen - 1];
|
spawns[writeindex] = spawns[spawnslen - 1];
|
||||||
@@ -13620,12 +13643,16 @@ void chraTickBg(void)
|
|||||||
// 5 chrs (alive or dead) to keep the number of polygons low.
|
// 5 chrs (alive or dead) to keep the number of polygons low.
|
||||||
maxdeadonscreen = 5 - numaliveonscreen;
|
maxdeadonscreen = 5 - numaliveonscreen;
|
||||||
|
|
||||||
|
if (g_MaxCorpses > 0) {
|
||||||
|
maxdeadonscreen = g_MaxCorpses;
|
||||||
|
}
|
||||||
|
|
||||||
// If the game is lagging, take the number of 60ths over 6 since the
|
// 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,
|
// 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.
|
// 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
|
// 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.
|
// weapons - the lag spike from changing guns triggers a lower corpse limit.
|
||||||
if (g_Vars.lvupdate60 > 6) {
|
if (g_Vars.lvupdate60 > 6 && g_MaxCorpses == 0) {
|
||||||
maxdeadonscreen = maxdeadonscreen - g_Vars.lvupdate60 + 6;
|
maxdeadonscreen = maxdeadonscreen - g_Vars.lvupdate60 + 6;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -13651,7 +13678,7 @@ void chraTickBg(void)
|
|||||||
#else
|
#else
|
||||||
// Decide which corpses to fade.
|
// Decide which corpses to fade.
|
||||||
// NTSC Beta implements its engagement counter here.
|
// NTSC Beta implements its engagement counter here.
|
||||||
if (numdeadonscreen) {
|
if (numdeadonscreen && g_MaxCorpses >= 0) {
|
||||||
numdeadonscreen = 0;
|
numdeadonscreen = 0;
|
||||||
#if VERSION >= VERSION_NTSC_1_0
|
#if VERSION >= VERSION_NTSC_1_0
|
||||||
onscreenlen = 0;
|
onscreenlen = 0;
|
||||||
@@ -13690,7 +13717,7 @@ void chraTickBg(void)
|
|||||||
onscreen[onscreenlen] = chr;
|
onscreen[onscreenlen] = chr;
|
||||||
onscreenlen++;
|
onscreenlen++;
|
||||||
|
|
||||||
if (onscreenlen >= (VERSION >= VERSION_NTSC_1_0 ? 2 : 3)) {
|
if (onscreenlen >= (g_MaxCorpses > 0 ? g_MaxCorpses : (VERSION >= VERSION_NTSC_1_0 ? 2 : 3))) {
|
||||||
writeindex = rngRandom() % onscreenlen;
|
writeindex = rngRandom() % onscreenlen;
|
||||||
chrFadeCorpseWhenOffScreen(onscreen[writeindex]);
|
chrFadeCorpseWhenOffScreen(onscreen[writeindex]);
|
||||||
onscreen[writeindex] = onscreen[onscreenlen - 1];
|
onscreen[writeindex] = onscreen[onscreenlen - 1];
|
||||||
@@ -13705,7 +13732,7 @@ void chraTickBg(void)
|
|||||||
offscreenlen++;
|
offscreenlen++;
|
||||||
|
|
||||||
// Allow up to 5 corpses off-screen
|
// Allow up to 5 corpses off-screen
|
||||||
if (offscreenlen >= (VERSION >= VERSION_NTSC_1_0 ? 5 : 6)) {
|
if (offscreenlen >= (g_MaxCorpses > 0 ? g_MaxCorpses : (VERSION >= VERSION_NTSC_1_0 ? 5 : 6))) {
|
||||||
writeindex = rngRandom() % offscreenlen;
|
writeindex = rngRandom() % offscreenlen;
|
||||||
|
|
||||||
if (offscreen[writeindex]->actiontype != ACT_DEAD) {
|
if (offscreen[writeindex]->actiontype != ACT_DEAD) {
|
||||||
|
|||||||
@@ -2330,7 +2330,7 @@ bool aiGiveObjectToChr(void)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
something = propPickupByPlayer(obj->prop, 0);
|
something = propPickupByPlayer(obj->prop, 1);
|
||||||
propExecuteTickOperation(obj->prop, something);
|
propExecuteTickOperation(obj->prop, something);
|
||||||
playernum = playermgrGetPlayerNumByProp(chr->prop);
|
playernum = playermgrGetPlayerNumByProp(chr->prop);
|
||||||
obj2->hidden = (playernum << 28) | (obj2->hidden & 0x0fffffff);
|
obj2->hidden = (playernum << 28) | (obj2->hidden & 0x0fffffff);
|
||||||
|
|||||||
@@ -35,7 +35,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct explosion *g_Explosions;
|
struct explosion *g_Explosions;
|
||||||
s32 g_MaxExplosions;
|
s32 g_MaxExplosions = MAX_EXPLOSIONS_DEFAULT;
|
||||||
|
|
||||||
s32 g_ExplosionShakeTotalTimer = 0;
|
s32 g_ExplosionShakeTotalTimer = 0;
|
||||||
s32 g_ExplosionShakeIntensityTimer = 0;
|
s32 g_ExplosionShakeIntensityTimer = 0;
|
||||||
|
|||||||
@@ -14,12 +14,6 @@ void explosionsReset(void)
|
|||||||
g_ExplosionShakeIntensityTimer = 0;
|
g_ExplosionShakeIntensityTimer = 0;
|
||||||
g_ExplosionDamageTxScale = 1;
|
g_ExplosionDamageTxScale = 1;
|
||||||
|
|
||||||
g_MaxExplosions = MAX_EXPLOSIONS;
|
|
||||||
|
|
||||||
if (g_Vars.stagenum >= STAGE_TITLE) {
|
|
||||||
g_MaxExplosions = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (g_MaxExplosions == 0) {
|
if (g_MaxExplosions == 0) {
|
||||||
g_Explosions = NULL;
|
g_Explosions = NULL;
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ void explosionsStop(void)
|
|||||||
viShake(0);
|
viShake(0);
|
||||||
|
|
||||||
if (g_Explosions) {
|
if (g_Explosions) {
|
||||||
for (i = 0; i < MAX_EXPLOSIONS; i++) {
|
for (i = 0; i < g_MaxExplosions; i++) {
|
||||||
if (g_Explosions[i].prop) {
|
if (g_Explosions[i].prop) {
|
||||||
propDelist(g_Explosions[i].prop);
|
propDelist(g_Explosions[i].prop);
|
||||||
propDisable(g_Explosions[i].prop);
|
propDisable(g_Explosions[i].prop);
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
#include "lib/str.h"
|
#include "lib/str.h"
|
||||||
#include "data.h"
|
#include "data.h"
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
#include "mpsetups.h"
|
||||||
|
|
||||||
// bss
|
// bss
|
||||||
struct fileguid g_FilemgrFileToCopy;
|
struct fileguid g_FilemgrFileToCopy;
|
||||||
@@ -2732,6 +2733,10 @@ MenuItemHandlerResult filemgrChooseAgentListMenuHandler(s32 operation, struct me
|
|||||||
g_GameFileGuid.fileid = file->fileid;
|
g_GameFileGuid.fileid = file->fileid;
|
||||||
g_GameFileGuid.deviceserial = file->deviceserial;
|
g_GameFileGuid.deviceserial = file->deviceserial;
|
||||||
filemgrSaveOrLoad(&g_GameFileGuid, FILEOP_LOAD_GAME, 0);
|
filemgrSaveOrLoad(&g_GameFileGuid, FILEOP_LOAD_GAME, 0);
|
||||||
|
|
||||||
|
// load the setup file when loading the agent
|
||||||
|
mpsetupCopyAllFromPak();
|
||||||
|
mpsetupLoadCurrentFile();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|||||||
+22
-8
@@ -111,15 +111,29 @@ void gfxReset(void)
|
|||||||
g_VtxSizesByPlayerCount[PLAYERCOUNT() - 1] = strtol(argFindByPrefix(1, "-mvtx"), NULL, 0) * 1024;
|
g_VtxSizesByPlayerCount[PLAYERCOUNT() - 1] = strtol(argFindByPrefix(1, "-mvtx"), NULL, 0) * 1024;
|
||||||
}
|
}
|
||||||
|
|
||||||
// %d Players : Allocating %d bytes for master dl's\n
|
{
|
||||||
g_GfxBuffers[0] = mempAlloc(g_GfxSizesByPlayerCount[PLAYERCOUNT() - 1] * NUM_GFXTASKS, MEMPOOL_STAGE);
|
u32 gfxsize = g_GfxSizesByPlayerCount[PLAYERCOUNT() - 1];
|
||||||
g_GfxBuffers[1] = g_GfxBuffers[0] + g_GfxSizesByPlayerCount[PLAYERCOUNT() - 1];
|
u32 vtxsize = g_VtxSizesByPlayerCount[PLAYERCOUNT() - 1];
|
||||||
g_GfxBuffers[2] = g_GfxBuffers[1] + g_GfxSizesByPlayerCount[PLAYERCOUNT() - 1];
|
|
||||||
|
|
||||||
// Allocating %d bytes for mtxvtx space\n
|
#ifndef PLATFORM_N64
|
||||||
g_VtxBuffers[0] = mempAlloc(g_VtxSizesByPlayerCount[PLAYERCOUNT() - 1] * NUM_GFXTASKS, MEMPOOL_STAGE);
|
// Each extra rendered decal needs display list commands and per-frame colours
|
||||||
g_VtxBuffers[1] = g_VtxBuffers[0] + g_VtxSizesByPlayerCount[PLAYERCOUNT() - 1];
|
if (g_DecalLimitMultiplier > 1) {
|
||||||
g_VtxBuffers[2] = g_VtxBuffers[1] + g_VtxSizesByPlayerCount[PLAYERCOUNT() - 1];
|
u32 extradecals = 360 * (g_DecalLimitMultiplier - 1);
|
||||||
|
gfxsize = ALIGN16(gfxsize + extradecals * 6 * sizeof(Gfx));
|
||||||
|
vtxsize = ALIGN16(vtxsize + extradecals * 32);
|
||||||
|
}
|
||||||
|
#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;
|
||||||
|
}
|
||||||
|
|
||||||
g_GfxActiveBufferIndex = 0;
|
g_GfxActiveBufferIndex = 0;
|
||||||
g_GfxRequestedDisplayList = false;
|
g_GfxRequestedDisplayList = false;
|
||||||
|
|||||||
@@ -12,11 +12,15 @@ void invReset(void)
|
|||||||
{
|
{
|
||||||
s32 i;
|
s32 i;
|
||||||
|
|
||||||
|
#ifndef PLATFORM_N64
|
||||||
|
g_Vars.currentplayer->equipallguns = cheatIsActive(CHEAT_ALLGUNS);
|
||||||
|
#else
|
||||||
if (PLAYERCOUNT() == 1 && g_Vars.normmplayerisrunning == false) {
|
if (PLAYERCOUNT() == 1 && g_Vars.normmplayerisrunning == false) {
|
||||||
g_Vars.currentplayer->equipallguns = cheatIsActive(CHEAT_ALLGUNS);
|
g_Vars.currentplayer->equipallguns = cheatIsActive(CHEAT_ALLGUNS);
|
||||||
} else {
|
} else {
|
||||||
g_Vars.currentplayer->equipallguns = false;
|
g_Vars.currentplayer->equipallguns = false;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
for (i = 0; i != ARRAYCOUNT(g_Vars.currentplayer->gunheldarr); i++) {
|
for (i = 0; i != ARRAYCOUNT(g_Vars.currentplayer->gunheldarr); i++) {
|
||||||
g_Vars.currentplayer->gunheldarr[i].totaltime240_60 = -1;
|
g_Vars.currentplayer->gunheldarr[i].totaltime240_60 = -1;
|
||||||
|
|||||||
+1
-1
@@ -28,7 +28,7 @@
|
|||||||
#include "game/portal.h"
|
#include "game/portal.h"
|
||||||
#include "game/fmb.h"
|
#include "game/fmb.h"
|
||||||
#include "game/sky.h"
|
#include "game/sky.h"
|
||||||
#include "game/game_13c510.h"
|
#include "game/artifact.h"
|
||||||
#include "game/game_1531a0.h"
|
#include "game/game_1531a0.h"
|
||||||
#include "game/zbuf.h"
|
#include "game/zbuf.h"
|
||||||
#include "game/challenge.h"
|
#include "game/challenge.h"
|
||||||
|
|||||||
+1
-1
@@ -1996,7 +1996,7 @@ MenuItemHandlerResult menuhandlerMissionList(s32 operation, struct menuitem *ite
|
|||||||
texSelect(&gdl, g_TexGeneralConfigs + 13 + stageindex, 2, 0, 2, true, NULL);
|
texSelect(&gdl, g_TexGeneralConfigs + 13 + stageindex, 2, 0, 2, true, NULL);
|
||||||
gDPSetCycleType(gdl++, G_CYC_1CYCLE);
|
gDPSetCycleType(gdl++, G_CYC_1CYCLE);
|
||||||
gDPSetCombineMode(gdl++, G_CC_CUSTOM_00, G_CC_CUSTOM_00);
|
gDPSetCombineMode(gdl++, G_CC_CUSTOM_00, G_CC_CUSTOM_00);
|
||||||
gDPSetTextureFilter(gdl++, G_TF_POINT);
|
gDPSetTextureFilter(gdl++, G_TF_AVERAGE);
|
||||||
gDPSetEnvColorViaWord(gdl++, 0xffffff00 | ((renderdata->colour & 0xff) * 255 / 256));
|
gDPSetEnvColorViaWord(gdl++, 0xffffff00 | ((renderdata->colour & 0xff) * 255 / 256));
|
||||||
#else
|
#else
|
||||||
texSelect(&gdl, g_TexGeneralConfigs + 13 + stageindex, 1, 0, 2, true, NULL);
|
texSelect(&gdl, g_TexGeneralConfigs + 13 + stageindex, 1, 0, 2, true, NULL);
|
||||||
|
|||||||
+44
-6
@@ -147,6 +147,33 @@ s32 g_MouseDimmedMode = false;
|
|||||||
s32 g_MouseEndDeferredSlider = false;
|
s32 g_MouseEndDeferredSlider = false;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
s32 menuAlt1Pressed(s32 playerNum)
|
||||||
|
{
|
||||||
|
const s32 rshoulderKey = VK_JOY1_RSHOULDER + playerNum * INPUT_MAX_CONTROLLER_BUTTONS;
|
||||||
|
|
||||||
|
if (playerNum == 0) {
|
||||||
|
return inputKeyJustPressed(VK_LCTRL) || inputKeyJustPressed(rshoulderKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
return inputKeyJustPressed(rshoulderKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
s32 menuAlt2Pressed(s32 playerNum)
|
||||||
|
{
|
||||||
|
const s32 lshoulderKey = VK_JOY1_LSHOULDER + playerNum * INPUT_MAX_CONTROLLER_BUTTONS;
|
||||||
|
|
||||||
|
if (playerNum == 0) {
|
||||||
|
return inputKeyJustPressed(VK_LALT) || inputKeyJustPressed(lshoulderKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
return inputKeyJustPressed(lshoulderKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
s32 menuAltAnyPressed(s32 playerNum)
|
||||||
|
{
|
||||||
|
return menuAlt1Pressed(playerNum) || menuAlt2Pressed(playerNum);
|
||||||
|
}
|
||||||
|
|
||||||
void menuPlaySound(s32 menusound)
|
void menuPlaySound(s32 menusound)
|
||||||
{
|
{
|
||||||
s32 sound = -1;
|
s32 sound = -1;
|
||||||
@@ -1901,6 +1928,10 @@ Gfx *menuRenderModel(Gfx *gdl, struct menumodel *menumodel, s32 modeltype)
|
|||||||
totalfilelen += 0x4000;
|
totalfilelen += 0x4000;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef PLATFORM_N64
|
||||||
|
videoFreeCachedTextures(menumodel->allocstart, menumodel->allocstart + menumodel->alloclen);
|
||||||
|
#endif
|
||||||
|
|
||||||
texInitPool(&texpool, menumodel->allocstart + totalfilelen, menumodel->alloclen - totalfilelen);
|
texInitPool(&texpool, menumodel->allocstart + totalfilelen, menumodel->alloclen - totalfilelen);
|
||||||
|
|
||||||
menumodel->headnum = headnum;
|
menumodel->headnum = headnum;
|
||||||
@@ -1933,6 +1964,10 @@ Gfx *menuRenderModel(Gfx *gdl, struct menumodel *menumodel, s32 modeltype)
|
|||||||
totalfilelen = ALIGN64(fileGetInflatedSize(menumodel->newparams, LOADTYPE_MODEL)) + 0x4000;
|
totalfilelen = ALIGN64(fileGetInflatedSize(menumodel->newparams, LOADTYPE_MODEL)) + 0x4000;
|
||||||
if (1);
|
if (1);
|
||||||
|
|
||||||
|
#ifndef PLATFORM_N64
|
||||||
|
videoFreeCachedTextures(menumodel->allocstart, menumodel->allocstart + menumodel->alloclen);
|
||||||
|
#endif
|
||||||
|
|
||||||
texInitPool(&texpool, &menumodel->allocstart[(u32)totalfilelen], menumodel->alloclen - totalfilelen);
|
texInitPool(&texpool, &menumodel->allocstart[(u32)totalfilelen], menumodel->alloclen - totalfilelen);
|
||||||
|
|
||||||
menumodel->headnum = -1;
|
menumodel->headnum = -1;
|
||||||
@@ -3581,8 +3616,8 @@ void func0f0f820c(struct menudialogdef *dialogdef, s32 root)
|
|||||||
|
|
||||||
g_MpPlayerNum = prevplayernum;
|
g_MpPlayerNum = prevplayernum;
|
||||||
|
|
||||||
g_MenuData.unk008 = root;
|
g_MenuData.prevmenuroot = root;
|
||||||
g_MenuData.unk00c = dialogdef;
|
g_MenuData.prevmenudialog = dialogdef;
|
||||||
}
|
}
|
||||||
|
|
||||||
void menuSetBackground(s32 bg)
|
void menuSetBackground(s32 bg)
|
||||||
@@ -3656,7 +3691,7 @@ void menuPushRootDialog(struct menudialogdef *dialogdef, s32 root)
|
|||||||
g_Menus[g_MpPlayerNum].unk820 = 1;
|
g_Menus[g_MpPlayerNum].unk820 = 1;
|
||||||
|
|
||||||
g_MenuData.root = root;
|
g_MenuData.root = root;
|
||||||
g_MenuData.unk008 = -1;
|
g_MenuData.prevmenuroot = -1;
|
||||||
g_MenuData.unk5d5_02 = false;
|
g_MenuData.unk5d5_02 = false;
|
||||||
|
|
||||||
if (root == MENUROOT_MAINMENU
|
if (root == MENUROOT_MAINMENU
|
||||||
@@ -3978,13 +4013,13 @@ void menuReset(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
g_MenuData.unk668 = -1;
|
g_MenuData.unk668 = -1;
|
||||||
g_MenuData.unk00c = 0;
|
g_MenuData.prevmenudialog = 0;
|
||||||
g_MenuData.unk008 = -1;
|
g_MenuData.prevmenuroot = -1;
|
||||||
g_MenuData.count = 0;
|
g_MenuData.count = 0;
|
||||||
g_MenuData.root = 0;
|
g_MenuData.root = 0;
|
||||||
g_MenuData.unk010 = 0;
|
g_MenuData.unk010 = 0;
|
||||||
g_MenuData.bg = 0;
|
g_MenuData.bg = 0;
|
||||||
g_MenuData.unk5d5_06 = false;
|
g_MenuData.isdialogopen = false;
|
||||||
g_MenuData.nextbg = 255;
|
g_MenuData.nextbg = 255;
|
||||||
g_MenuData.bannernum = -1;
|
g_MenuData.bannernum = -1;
|
||||||
|
|
||||||
@@ -4579,6 +4614,9 @@ 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);
|
s32 adjustment = (s32)(inputs->yaxis * g_Vars.diffframe60freal / 20) - (s32)(inputs->updownheld * g_Vars.diffframe60freal);
|
||||||
#else
|
#else
|
||||||
s32 adjustment = inputs->yaxis * g_Vars.diffframe60 / 20 - inputs->updownheld * g_Vars.diffframe60;
|
s32 adjustment = inputs->yaxis * g_Vars.diffframe60 / 20 - inputs->updownheld * g_Vars.diffframe60;
|
||||||
|
#endif
|
||||||
|
#ifndef PLATFORM_N64
|
||||||
|
adjustment -= inputs->mousescroll * (LINEHEIGHT + 1);
|
||||||
#endif
|
#endif
|
||||||
dialog->dstscroll += adjustment;
|
dialog->dstscroll += adjustment;
|
||||||
|
|
||||||
|
|||||||
+19
-2
@@ -1334,7 +1334,7 @@ Gfx *menuitemKeyboardRender(Gfx *gdl, struct menurendercontext *context)
|
|||||||
// make the button yellow if it's active
|
// make the button yellow if it's active
|
||||||
if (g_MenuKeyboardPlayer == g_MpPlayerNum) {
|
if (g_MenuKeyboardPlayer == g_MpPlayerNum) {
|
||||||
textcolour = (textcolour & 0xff) | 0xffff0000;
|
textcolour = (textcolour & 0xff) | 0xffff0000;
|
||||||
kbtext = (char *)"ESC: CANCEL ENTER: OK";
|
kbtext = (char *)"ESC: OK";
|
||||||
} else {
|
} else {
|
||||||
kbtext = (char *)"TYPE WITH KEYBOARD";
|
kbtext = (char *)"TYPE WITH KEYBOARD";
|
||||||
}
|
}
|
||||||
@@ -1531,6 +1531,14 @@ bool menuitemKeyboardTick(struct menuitem *item, struct menuinputs *inputs, u32
|
|||||||
|
|
||||||
u8 maxlen = item->param == 0 ? 10 : item->param;
|
u8 maxlen = item->param == 0 ? 10 : item->param;
|
||||||
#ifndef PLATFORM_N64
|
#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) {
|
if (g_MenuKeyboardPlayer == g_MpPlayerNum) {
|
||||||
// match caps state to keyboard shift/caps if typing with keyboard
|
// match caps state to keyboard shift/caps if typing with keyboard
|
||||||
const u32 kmod = inputGetKeyModState();
|
const u32 kmod = inputGetKeyModState();
|
||||||
@@ -1541,7 +1549,7 @@ bool menuitemKeyboardTick(struct menuitem *item, struct menuinputs *inputs, u32
|
|||||||
// handle text input
|
// handle text input
|
||||||
s32 prevpos = strlen(kb->string);
|
s32 prevpos = strlen(kb->string);
|
||||||
s32 pos = prevpos;
|
s32 pos = prevpos;
|
||||||
s32 result = inputTextHandler(kb->string, maxlen-1, &pos, true);
|
s32 result = inputTextHandler(kb->string, maxlen + 1, &pos, true);
|
||||||
if (result == -1) {
|
if (result == -1) {
|
||||||
// cancel
|
// cancel
|
||||||
kb->row = 5;
|
kb->row = 5;
|
||||||
@@ -3220,6 +3228,9 @@ bool menuitemScrollableTick(struct menuitem *item, struct menudialog *dialog, st
|
|||||||
intval = intval + (s32)(((f32)inputs->updownheld + (f32)inputs->updownheld) * g_Vars.diffframe60freal);
|
intval = intval + (s32)(((f32)inputs->updownheld + (f32)inputs->updownheld) * g_Vars.diffframe60freal);
|
||||||
#else
|
#else
|
||||||
intval += inputs->updownheld * 2 * g_Vars.diffframe60;
|
intval += inputs->updownheld * 2 * g_Vars.diffframe60;
|
||||||
|
#endif
|
||||||
|
#ifndef PLATFORM_N64
|
||||||
|
intval += inputs->mousescroll * (LINEHEIGHT - 2) * 3;
|
||||||
#endif
|
#endif
|
||||||
data->scrollable.scrolloffset += intval;
|
data->scrollable.scrolloffset += intval;
|
||||||
|
|
||||||
@@ -3743,6 +3754,9 @@ bool menuitemRankingTick(struct menuinputs *inputs, u32 tickflags, union menuite
|
|||||||
intval = intval + (s32)(((f32)inputs->updownheld + (f32)inputs->updownheld) * g_Vars.diffframe60freal);
|
intval = intval + (s32)(((f32)inputs->updownheld + (f32)inputs->updownheld) * g_Vars.diffframe60freal);
|
||||||
#else
|
#else
|
||||||
intval += inputs->updownheld * 2 * g_Vars.diffframe60;
|
intval += inputs->updownheld * 2 * g_Vars.diffframe60;
|
||||||
|
#endif
|
||||||
|
#ifndef PLATFORM_N64
|
||||||
|
intval += inputs->mousescroll * (LINEHEIGHT - 1);
|
||||||
#endif
|
#endif
|
||||||
data->ranking.scrolloffset += intval;
|
data->ranking.scrolloffset += intval;
|
||||||
|
|
||||||
@@ -4038,6 +4052,9 @@ bool menuitemPlayerStatsTick(struct menuitem *item, struct menudialog *dialog, s
|
|||||||
intval = intval + (s32)(((f32)inputs->updownheld + (f32)inputs->updownheld) * g_Vars.diffframe60freal);
|
intval = intval + (s32)(((f32)inputs->updownheld + (f32)inputs->updownheld) * g_Vars.diffframe60freal);
|
||||||
#else
|
#else
|
||||||
intval += inputs->updownheld * 2 * g_Vars.diffframe60;
|
intval += inputs->updownheld * 2 * g_Vars.diffframe60;
|
||||||
|
#endif
|
||||||
|
#ifndef PLATFORM_N64
|
||||||
|
intval += inputs->mousescroll * (LINEHEIGHT - 1);
|
||||||
#endif
|
#endif
|
||||||
data->dropdown.scrolloffset += intval;
|
data->dropdown.scrolloffset += intval;
|
||||||
|
|
||||||
|
|||||||
+31
-25
@@ -59,7 +59,7 @@ void menuTick(void)
|
|||||||
s32 i;
|
s32 i;
|
||||||
s32 j;
|
s32 j;
|
||||||
s32 k;
|
s32 k;
|
||||||
s32 sp344;
|
s32 isdialogopen;
|
||||||
s32 sp340 = true;
|
s32 sp340 = true;
|
||||||
s32 anyopen = false;
|
s32 anyopen = false;
|
||||||
|
|
||||||
@@ -285,7 +285,13 @@ void menuTick(void)
|
|||||||
var8006294c = 1;
|
var8006294c = 1;
|
||||||
|
|
||||||
if (g_MenuData.root == MENUROOT_MPSETUP || g_MenuData.root == MENUROOT_4MBMAINMENU) {
|
if (g_MenuData.root == MENUROOT_MPSETUP || g_MenuData.root == MENUROOT_4MBMAINMENU) {
|
||||||
if (g_MenuData.unk008 == -1) {
|
if (g_MenuData.prevmenuroot == -1) {
|
||||||
|
#ifndef PLATFORM_N64
|
||||||
|
if (g_MpSetup.storedbotbits) {
|
||||||
|
g_MpSetup.chrslots |= g_MpSetup.storedbotbits;
|
||||||
|
g_MpSetup.storedbotbits = 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
g_MpSetup.chrslots &= 0xfff0;
|
g_MpSetup.chrslots &= 0xfff0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -295,7 +301,7 @@ void menuTick(void)
|
|||||||
if (g_Menus[i].curdialog) {
|
if (g_Menus[i].curdialog) {
|
||||||
g_Menus[i].playernum = g_MpNumJoined++;
|
g_Menus[i].playernum = g_MpNumJoined++;
|
||||||
|
|
||||||
if (g_MenuData.unk008 == -1) {
|
if (g_MenuData.prevmenuroot == -1) {
|
||||||
g_MpSetup.chrslots |= (1 << i);
|
g_MpSetup.chrslots |= (1 << i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -485,31 +491,31 @@ void menuTick(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
g_MpPlayerNum = 0;
|
g_MpPlayerNum = 0;
|
||||||
sp344 = false;
|
isdialogopen = false;
|
||||||
|
|
||||||
for (i = 0; i < ARRAYCOUNT(g_Menus); i++) {
|
for (i = 0; i < ARRAYCOUNT(g_Menus); i++) {
|
||||||
if (g_Menus[i].curdialog) {
|
if (g_Menus[i].curdialog) {
|
||||||
sp344 = true;
|
isdialogopen = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((g_MenuData.unk5d5_06 || g_MenuData.unk008 != -1) && sp344 == false) {
|
if ((g_MenuData.isdialogopen || g_MenuData.prevmenuroot != -1) && isdialogopen == false) {
|
||||||
if ((g_MenuData.root == MENUROOT_MPSETUP || g_MenuData.root == MENUROOT_4MBMAINMENU)
|
if ((g_MenuData.root == MENUROOT_MPSETUP || g_MenuData.root == MENUROOT_4MBMAINMENU)
|
||||||
&& g_MenuData.unk008 == -1) {
|
&& g_MenuData.prevmenuroot == -1) {
|
||||||
if (g_Vars.mpsetupmenu == MPSETUPMENU_GENERAL) {
|
if (g_Vars.mpsetupmenu == MPSETUPMENU_GENERAL) {
|
||||||
g_MenuData.unk008 = MENUROOT_MAINMENU;
|
g_MenuData.prevmenuroot = MENUROOT_MAINMENU;
|
||||||
g_MenuData.unk00c = IS4MB() ? &g_CiMenuViaPauseMenuDialog : &g_CiMenuViaPcMenuDialog;
|
g_MenuData.prevmenudialog = IS4MB() ? &g_CiMenuViaPauseMenuDialog : &g_CiMenuViaPcMenuDialog;
|
||||||
} else if (IS4MB()) {
|
} else if (IS4MB()) {
|
||||||
g_MenuData.unk008 = MENUROOT_4MBMAINMENU;
|
g_MenuData.prevmenuroot = MENUROOT_4MBMAINMENU;
|
||||||
g_MenuData.unk00c = &g_MainMenu4MbMenuDialog;
|
g_MenuData.prevmenudialog = &g_MainMenu4MbMenuDialog;
|
||||||
} else {
|
} else {
|
||||||
g_MenuData.unk008 = MENUROOT_MPSETUP;
|
g_MenuData.prevmenuroot = MENUROOT_MPSETUP;
|
||||||
g_MenuData.unk00c = &g_CombatSimulatorMenuDialog;
|
g_MenuData.prevmenudialog = &g_CombatSimulatorMenuDialog;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (g_MenuData.unk008 != -1) {
|
if (g_MenuData.prevmenuroot != -1) {
|
||||||
if (g_MenuData.unk008 == -5) {
|
if (g_MenuData.prevmenuroot == -5) {
|
||||||
// Match is beginning
|
// Match is beginning
|
||||||
mpStartMatch();
|
mpStartMatch();
|
||||||
menuStop();
|
menuStop();
|
||||||
@@ -518,7 +524,7 @@ void menuTick(void)
|
|||||||
bossfileSave();
|
bossfileSave();
|
||||||
g_Vars.modifiedfiles &= ~MODFILE_MPSETUP;
|
g_Vars.modifiedfiles &= ~MODFILE_MPSETUP;
|
||||||
}
|
}
|
||||||
} else if (g_MenuData.unk008 == -6) {
|
} else if (g_MenuData.prevmenuroot == -6) {
|
||||||
// Match is ending
|
// Match is ending
|
||||||
s32 playernum = 0;
|
s32 playernum = 0;
|
||||||
|
|
||||||
@@ -541,17 +547,17 @@ void menuTick(void)
|
|||||||
setCurrentPlayerNum(playernum);
|
setCurrentPlayerNum(playernum);
|
||||||
endscreenPushCoop();
|
endscreenPushCoop();
|
||||||
setCurrentPlayerNum(prevplayernum);
|
setCurrentPlayerNum(prevplayernum);
|
||||||
sp344 = true;
|
isdialogopen = true;
|
||||||
}
|
}
|
||||||
} else if (g_Vars.antiplayernum >= 0) {
|
} else if (g_Vars.antiplayernum >= 0) {
|
||||||
s32 prevplayernum = g_Vars.currentplayernum;
|
s32 prevplayernum = g_Vars.currentplayernum;
|
||||||
setCurrentPlayerNum(playernum);
|
setCurrentPlayerNum(playernum);
|
||||||
endscreenPushAnti();
|
endscreenPushAnti();
|
||||||
setCurrentPlayerNum(prevplayernum);
|
setCurrentPlayerNum(prevplayernum);
|
||||||
sp344 = true;
|
isdialogopen = true;
|
||||||
} else {
|
} else {
|
||||||
mpPushEndscreenDialog(playernum, i);
|
mpPushEndscreenDialog(playernum, i);
|
||||||
sp344 = true;
|
isdialogopen = true;
|
||||||
|
|
||||||
if (g_PlayerConfigsArray[i].fileguid.fileid && g_PlayerConfigsArray[i].fileguid.deviceserial) {
|
if (g_PlayerConfigsArray[i].fileguid.fileid && g_PlayerConfigsArray[i].fileguid.deviceserial) {
|
||||||
func0f0fd548(i);
|
func0f0fd548(i);
|
||||||
@@ -561,7 +567,7 @@ void menuTick(void)
|
|||||||
playernum++;
|
playernum++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (g_MenuData.unk008 == -7) {
|
} else if (g_MenuData.prevmenuroot == -7) {
|
||||||
menuStop();
|
menuStop();
|
||||||
g_FileState = FILESTATE_CHANGINGAGENT;
|
g_FileState = FILESTATE_CHANGINGAGENT;
|
||||||
gamefileLoadDefaults(&g_GameFile);
|
gamefileLoadDefaults(&g_GameFile);
|
||||||
@@ -570,8 +576,8 @@ void menuTick(void)
|
|||||||
musicQueueStopAllEvent();
|
musicQueueStopAllEvent();
|
||||||
} else {
|
} else {
|
||||||
bool startmusic = false;
|
bool startmusic = false;
|
||||||
menuPushRootDialog(g_MenuData.unk00c, g_MenuData.unk008);
|
menuPushRootDialog(g_MenuData.prevmenudialog, g_MenuData.prevmenuroot);
|
||||||
sp344 = true;
|
isdialogopen = true;
|
||||||
|
|
||||||
if (g_MenuData.root == MENUROOT_MPSETUP || g_MenuData.root == MENUROOT_4MBMAINMENU) {
|
if (g_MenuData.root == MENUROOT_MPSETUP || g_MenuData.root == MENUROOT_4MBMAINMENU) {
|
||||||
startmusic = true;
|
startmusic = true;
|
||||||
@@ -597,8 +603,8 @@ void menuTick(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
g_MenuData.unk00c = NULL;
|
g_MenuData.prevmenudialog = NULL;
|
||||||
g_MenuData.unk008 = -1;
|
g_MenuData.prevmenuroot = -1;
|
||||||
} else {
|
} else {
|
||||||
switch (g_MenuData.root) {
|
switch (g_MenuData.root) {
|
||||||
case MENUROOT_ENDSCREEN:
|
case MENUROOT_ENDSCREEN:
|
||||||
@@ -750,5 +756,5 @@ void menuTick(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
g_ScaleX = 1;
|
g_ScaleX = 1;
|
||||||
g_MenuData.unk5d5_06 = sp344 ? true : false;
|
g_MenuData.isdialogopen = isdialogopen ? true : false;
|
||||||
}
|
}
|
||||||
@@ -139,6 +139,7 @@ struct mpweapon g_MpWeapons[NUM_MPWEAPONS] = {
|
|||||||
.extcontrols = true, \
|
.extcontrols = true, \
|
||||||
.crosshaircolour = 0x00ff0028, \
|
.crosshaircolour = 0x00ff0028, \
|
||||||
.crosshairsize = 2, \
|
.crosshairsize = 2, \
|
||||||
|
.crosshairedgeboundary = 0.7f, \
|
||||||
.crosshairhealth = CROSSHAIR_HEALTH_OFF, \
|
.crosshairhealth = CROSSHAIR_HEALTH_OFF, \
|
||||||
.usereloads = false, \
|
.usereloads = false, \
|
||||||
}
|
}
|
||||||
@@ -600,7 +601,7 @@ void mpInit(bool resetplayers)
|
|||||||
g_MpSetup.chrslots = 0;
|
g_MpSetup.chrslots = 0;
|
||||||
|
|
||||||
for (i = 0; i < ARRAYCOUNT(g_Menus); i++) {
|
for (i = 0; i < ARRAYCOUNT(g_Menus); i++) {
|
||||||
g_Menus[i].mpsetup.showpresets = 1;
|
g_Menus[i].mpsetupext.showpresets = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef PLATFORM_N64
|
#ifndef PLATFORM_N64
|
||||||
|
|||||||
@@ -11,6 +11,8 @@
|
|||||||
* Players cannot score unless their briefcase is at the home base.
|
* Players cannot score unless their briefcase is at the home base.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
extern struct menudialogdef g_ExtGameOptionsMenuDialog;
|
||||||
|
|
||||||
struct menuitem g_CtcOptionsMenuItems[] = {
|
struct menuitem g_CtcOptionsMenuItems[] = {
|
||||||
{
|
{
|
||||||
MENUITEMTYPE_CHECKBOX,
|
MENUITEMTYPE_CHECKBOX,
|
||||||
@@ -60,40 +62,6 @@ struct menuitem g_CtcOptionsMenuItems[] = {
|
|||||||
MPOPTION_NOAUTOAIM,
|
MPOPTION_NOAUTOAIM,
|
||||||
menuhandlerMpCheckboxOption,
|
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,
|
MENUITEMTYPE_CHECKBOX,
|
||||||
0,
|
0,
|
||||||
@@ -143,7 +111,8 @@ struct menudialogdef g_CtcOptionsMenuDialog = {
|
|||||||
g_CtcOptionsMenuItems,
|
g_CtcOptionsMenuItems,
|
||||||
mpOptionsMenuDialog,
|
mpOptionsMenuDialog,
|
||||||
MENUDIALOGFLAG_MPLOCKABLE,
|
MENUDIALOGFLAG_MPLOCKABLE,
|
||||||
NULL,
|
&g_ExtGameOptionsMenuDialog,
|
||||||
|
// NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct weaponobj g_CtcTokenObj0;
|
struct weaponobj g_CtcTokenObj0;
|
||||||
|
|||||||
@@ -6,6 +6,8 @@
|
|||||||
* There are no callback functions or special logic.
|
* There are no callback functions or special logic.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
extern struct menudialogdef g_ExtGameOptionsMenuDialog;
|
||||||
|
|
||||||
struct menuitem g_MpCombatOptionsMenuItems[] = {
|
struct menuitem g_MpCombatOptionsMenuItems[] = {
|
||||||
{
|
{
|
||||||
MENUITEMTYPE_CHECKBOX,
|
MENUITEMTYPE_CHECKBOX,
|
||||||
@@ -55,40 +57,6 @@ struct menuitem g_MpCombatOptionsMenuItems[] = {
|
|||||||
MPOPTION_NOAUTOAIM,
|
MPOPTION_NOAUTOAIM,
|
||||||
menuhandlerMpCheckboxOption,
|
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,
|
MENUITEMTYPE_SEPARATOR,
|
||||||
0,
|
0,
|
||||||
@@ -138,5 +106,5 @@ struct menudialogdef g_MpCombatOptionsMenuDialog = {
|
|||||||
g_MpCombatOptionsMenuItems,
|
g_MpCombatOptionsMenuItems,
|
||||||
mpOptionsMenuDialog,
|
mpOptionsMenuDialog,
|
||||||
MENUDIALOGFLAG_MPLOCKABLE,
|
MENUDIALOGFLAG_MPLOCKABLE,
|
||||||
NULL,
|
&g_ExtGameOptionsMenuDialog,
|
||||||
};
|
};
|
||||||
@@ -7,6 +7,8 @@
|
|||||||
* cannot use weapons while uplinking.
|
* cannot use weapons while uplinking.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
extern struct menudialogdef g_ExtGameOptionsMenuDialog;
|
||||||
|
|
||||||
#define HTM_NUM_TERMINALS 1
|
#define HTM_NUM_TERMINALS 1
|
||||||
|
|
||||||
struct menuitem g_HtmOptionsMenuItems[] = {
|
struct menuitem g_HtmOptionsMenuItems[] = {
|
||||||
@@ -58,40 +60,6 @@ struct menuitem g_HtmOptionsMenuItems[] = {
|
|||||||
MPOPTION_NOAUTOAIM,
|
MPOPTION_NOAUTOAIM,
|
||||||
menuhandlerMpCheckboxOption,
|
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,
|
MENUITEMTYPE_CHECKBOX,
|
||||||
0,
|
0,
|
||||||
@@ -149,7 +117,7 @@ struct menudialogdef g_HtmOptionsMenuDialog = {
|
|||||||
g_HtmOptionsMenuItems,
|
g_HtmOptionsMenuItems,
|
||||||
mpOptionsMenuDialog,
|
mpOptionsMenuDialog,
|
||||||
MENUDIALOGFLAG_MPLOCKABLE,
|
MENUDIALOGFLAG_MPLOCKABLE,
|
||||||
NULL,
|
&g_ExtGameOptionsMenuDialog,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct weaponobj g_HtmUplinkObj;
|
struct weaponobj g_HtmUplinkObj;
|
||||||
|
|||||||
@@ -9,6 +9,8 @@
|
|||||||
* slightly slower but still have full access to their weaponry.
|
* slightly slower but still have full access to their weaponry.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
extern struct menudialogdef g_ExtGameOptionsMenuDialog;
|
||||||
|
|
||||||
struct menuitem g_HtbOptionsMenuItems[] = {
|
struct menuitem g_HtbOptionsMenuItems[] = {
|
||||||
{
|
{
|
||||||
MENUITEMTYPE_CHECKBOX,
|
MENUITEMTYPE_CHECKBOX,
|
||||||
@@ -58,40 +60,6 @@ struct menuitem g_HtbOptionsMenuItems[] = {
|
|||||||
MPOPTION_NOAUTOAIM,
|
MPOPTION_NOAUTOAIM,
|
||||||
menuhandlerMpCheckboxOption,
|
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,
|
MENUITEMTYPE_CHECKBOX,
|
||||||
0,
|
0,
|
||||||
@@ -149,7 +117,7 @@ struct menudialogdef g_HtbOptionsMenuDialog = {
|
|||||||
g_HtbOptionsMenuItems,
|
g_HtbOptionsMenuItems,
|
||||||
mpOptionsMenuDialog,
|
mpOptionsMenuDialog,
|
||||||
MENUDIALOGFLAG_MPLOCKABLE,
|
MENUDIALOGFLAG_MPLOCKABLE,
|
||||||
NULL,
|
&g_ExtGameOptionsMenuDialog,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct defaultobj *var800869ec = NULL;
|
struct defaultobj *var800869ec = NULL;
|
||||||
|
|||||||
@@ -13,6 +13,8 @@
|
|||||||
* Points are awarded to each player in the hill at the time that it is won.
|
* 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)
|
MenuItemHandlerResult menuhandlerMpHillTime(s32 operation, struct menuitem *item, union handlerdata *data)
|
||||||
{
|
{
|
||||||
switch (operation) {
|
switch (operation) {
|
||||||
@@ -79,40 +81,6 @@ struct menuitem g_KohOptionsMenuItems[] = {
|
|||||||
MPOPTION_NOAUTOAIM,
|
MPOPTION_NOAUTOAIM,
|
||||||
menuhandlerMpCheckboxOption,
|
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,
|
MENUITEMTYPE_CHECKBOX,
|
||||||
0,
|
0,
|
||||||
@@ -178,7 +146,7 @@ struct menudialogdef g_KohOptionsMenuDialog = {
|
|||||||
g_KohOptionsMenuItems,
|
g_KohOptionsMenuItems,
|
||||||
mpOptionsMenuDialog,
|
mpOptionsMenuDialog,
|
||||||
MENUDIALOGFLAG_MPLOCKABLE,
|
MENUDIALOGFLAG_MPLOCKABLE,
|
||||||
NULL,
|
&g_ExtGameOptionsMenuDialog,
|
||||||
};
|
};
|
||||||
|
|
||||||
void kohReadSave(struct savebuffer *buffer, u8 version)
|
void kohReadSave(struct savebuffer *buffer, u8 version)
|
||||||
|
|||||||
@@ -7,6 +7,8 @@
|
|||||||
* chosen as the victim.
|
* chosen as the victim.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
extern struct menudialogdef g_ExtGameOptionsMenuDialog;
|
||||||
|
|
||||||
struct menuitem g_PacOptionsMenuItems[] = {
|
struct menuitem g_PacOptionsMenuItems[] = {
|
||||||
{
|
{
|
||||||
MENUITEMTYPE_CHECKBOX,
|
MENUITEMTYPE_CHECKBOX,
|
||||||
@@ -56,40 +58,6 @@ struct menuitem g_PacOptionsMenuItems[] = {
|
|||||||
MPOPTION_NOAUTOAIM,
|
MPOPTION_NOAUTOAIM,
|
||||||
menuhandlerMpCheckboxOption,
|
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,
|
MENUITEMTYPE_CHECKBOX,
|
||||||
0,
|
0,
|
||||||
@@ -147,7 +115,7 @@ struct menudialogdef g_PacOptionsMenuDialog = {
|
|||||||
g_PacOptionsMenuItems,
|
g_PacOptionsMenuItems,
|
||||||
mpOptionsMenuDialog,
|
mpOptionsMenuDialog,
|
||||||
MENUDIALOGFLAG_MPLOCKABLE,
|
MENUDIALOGFLAG_MPLOCKABLE,
|
||||||
NULL,
|
&g_ExtGameOptionsMenuDialog,
|
||||||
};
|
};
|
||||||
|
|
||||||
void pacReset(void)
|
void pacReset(void)
|
||||||
|
|||||||
+57
-35
@@ -43,33 +43,6 @@ extern struct menudialogdef g_FilemgrErrorMenuDialog;
|
|||||||
extern s32 g_MpWeaponSetNum;
|
extern s32 g_MpWeaponSetNum;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static inline s32 menuAlt1Pressed(s32 playerNum)
|
|
||||||
{
|
|
||||||
const s32 rshoulderKey = VK_JOY1_RSHOULDER + playerNum * INPUT_MAX_CONTROLLER_BUTTONS;
|
|
||||||
|
|
||||||
if (playerNum == 0) {
|
|
||||||
return inputKeyJustPressed(VK_LCTRL) || inputKeyJustPressed(rshoulderKey);
|
|
||||||
}
|
|
||||||
|
|
||||||
return inputKeyJustPressed(rshoulderKey);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline s32 menuAlt2Pressed(s32 playerNum)
|
|
||||||
{
|
|
||||||
const s32 lshoulderKey = VK_JOY1_LSHOULDER + playerNum * INPUT_MAX_CONTROLLER_BUTTONS;
|
|
||||||
|
|
||||||
if (playerNum == 0) {
|
|
||||||
return inputKeyJustPressed(VK_LALT) || inputKeyJustPressed(lshoulderKey);
|
|
||||||
}
|
|
||||||
|
|
||||||
return inputKeyJustPressed(lshoulderKey);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline s32 menuAltPressed(s32 playerNum)
|
|
||||||
{
|
|
||||||
return menuAlt1Pressed(playerNum) || menuAlt2Pressed(playerNum);
|
|
||||||
}
|
|
||||||
|
|
||||||
MenuItemHandlerResult menuhandlerMpDropOut(s32 operation, struct menuitem *item, union handlerdata *data)
|
MenuItemHandlerResult menuhandlerMpDropOut(s32 operation, struct menuitem *item, union handlerdata *data)
|
||||||
{
|
{
|
||||||
if (operation == MENUOP_SET) {
|
if (operation == MENUOP_SET) {
|
||||||
@@ -2285,7 +2258,7 @@ MenuItemHandlerResult mpPlayerNameMenuHandler(s32 operation, struct menuitem *it
|
|||||||
|
|
||||||
MenuItemHandlerResult mpLoadSettingsMenuHandler(s32 operation, struct menuitem *item, union handlerdata *data)
|
MenuItemHandlerResult mpLoadSettingsMenuHandler(s32 operation, struct menuitem *item, union handlerdata *data)
|
||||||
{
|
{
|
||||||
u8 presets = g_Menus[g_MpPlayerNum].mpsetup.showpresets;
|
u8 presets = g_Menus[g_MpPlayerNum].mpsetupext.showpresets;
|
||||||
s32 numpresets = mpGetNumUnlockedPresets()*presets;
|
s32 numpresets = mpGetNumUnlockedPresets()*presets;
|
||||||
|
|
||||||
switch (operation) {
|
switch (operation) {
|
||||||
@@ -2594,9 +2567,9 @@ MenuDialogHandlerResult menudialogMpSimulant(s32 operation, struct menudialogdef
|
|||||||
MenuDialogHandlerResult mpLoadSettingsDialogHandler(s32 operation, struct menudialogdef *dialogdef, union handlerdata *data)
|
MenuDialogHandlerResult mpLoadSettingsDialogHandler(s32 operation, struct menudialogdef *dialogdef, union handlerdata *data)
|
||||||
{
|
{
|
||||||
if (operation == MENUOP_TICK) {
|
if (operation == MENUOP_TICK) {
|
||||||
if (menuAltPressed(g_MpPlayerNum)) {
|
if (menuAltAnyPressed(g_MpPlayerNum)) {
|
||||||
u8 presets = g_Menus[g_MpPlayerNum].mpsetup.showpresets;
|
u8 presets = g_Menus[g_MpPlayerNum].mpsetupext.showpresets;
|
||||||
g_Menus[g_MpPlayerNum].mpsetup.showpresets = 1 - presets;
|
g_Menus[g_MpPlayerNum].mpsetupext.showpresets = 1 - presets;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5421,10 +5394,6 @@ MenuDialogHandlerResult menudialogCombatSimulator(s32 operation, struct menudial
|
|||||||
g_Vars.waitingtojoin[1] = false;
|
g_Vars.waitingtojoin[1] = false;
|
||||||
g_Vars.waitingtojoin[2] = false;
|
g_Vars.waitingtojoin[2] = false;
|
||||||
g_Vars.waitingtojoin[3] = false;
|
g_Vars.waitingtojoin[3] = false;
|
||||||
|
|
||||||
// load the setup file when entering the Combat Simulator
|
|
||||||
mpsetupCopyAllFromPak();
|
|
||||||
mpsetupLoadCurrentFile();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (g_Menus[g_MpPlayerNum].curdialog
|
if (g_Menus[g_MpPlayerNum].curdialog
|
||||||
@@ -6186,3 +6155,56 @@ void func0f17fcb0(s32 silent)
|
|||||||
sndStart(var80095200, SFX_EXPLOSION_809A, NULL, -1, -1, -1, -1, -1);
|
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,
|
||||||
|
};
|
||||||
@@ -859,6 +859,11 @@ PakErr2 pakReadHeaderAtOffset(s8 device, u32 offset, struct pakfileheader *heade
|
|||||||
return PAK_ERR2_BADOFFSET;
|
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)) {
|
if (!pakRetrieveHeaderFromCache(device, blocknum, headerptr)) {
|
||||||
result = pakReadWriteBlock(device, PFS(device), g_Paks[device].pdnoteindex, 0, offset, sizeof(sp38), sp38);
|
result = pakReadWriteBlock(device, PFS(device), g_Paks[device].pdnoteindex, 0, offset, sizeof(sp38), sp38);
|
||||||
|
|
||||||
|
|||||||
+2
-1
@@ -1114,7 +1114,8 @@ void playerSpawn(void)
|
|||||||
invGiveSingleWeapon(WEAPON_NIGHTVISION);
|
invGiveSingleWeapon(WEAPON_NIGHTVISION);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((g_MpSetup.options & MPOPTION_SPAWNWITHWEAPON)
|
if (g_Vars.normmplayerisrunning
|
||||||
|
&& (g_MpSetup.options & MPOPTION_SPAWNWITHWEAPON)
|
||||||
&& g_MpSetup.weapons[0] != MPWEAPON_NONE
|
&& g_MpSetup.weapons[0] != MPWEAPON_NONE
|
||||||
&& g_MpSetup.weapons[0] != MPWEAPON_DISABLED
|
&& g_MpSetup.weapons[0] != MPWEAPON_DISABLED
|
||||||
&& g_MpSetup.weapons[0] != MPWEAPON_SHIELD) {
|
&& g_MpSetup.weapons[0] != MPWEAPON_SHIELD) {
|
||||||
|
|||||||
+15
-8
@@ -983,7 +983,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)
|
bool shotTestLos(struct coord *gunpos2d, struct coord *gundir2d, struct coord *gunpos3d, struct coord *gundir3d, struct coord *endpos3d)
|
||||||
{
|
{
|
||||||
struct prop **propptr;
|
struct prop **propptr;
|
||||||
struct hitthing sp664;
|
struct hitthing hitthing;
|
||||||
struct coord delta;
|
struct coord delta;
|
||||||
struct shotdata shotdata;
|
struct shotdata shotdata;
|
||||||
s32 i;
|
s32 i;
|
||||||
@@ -992,6 +992,8 @@ bool shotTestLos(struct coord *gunpos2d, struct coord *gundir2d, struct coord *g
|
|||||||
RoomNum spb8[8];
|
RoomNum spb8[8];
|
||||||
RoomNum *roomsptr;
|
RoomNum *roomsptr;
|
||||||
struct prop *prop;
|
struct prop *prop;
|
||||||
|
s16 texturenum;
|
||||||
|
u32 surfacetype;
|
||||||
|
|
||||||
shotdata.gunpos3d.x = gunpos3d->x;
|
shotdata.gunpos3d.x = gunpos3d->x;
|
||||||
shotdata.gunpos3d.y = gunpos3d->y;
|
shotdata.gunpos3d.y = gunpos3d->y;
|
||||||
@@ -1040,11 +1042,11 @@ bool shotTestLos(struct coord *gunpos2d, struct coord *gundir2d, struct coord *g
|
|||||||
|
|
||||||
// Check for BG hits first
|
// Check for BG hits first
|
||||||
for (i = 0; rooms[i] != -1; i++) {
|
for (i = 0; rooms[i] != -1; i++) {
|
||||||
if (bgTestHitInRoom(&shotdata.gunpos3d, endpos3d, rooms[i], &sp664)) {
|
if (bgTestHitInRoom(&shotdata.gunpos3d, endpos3d, rooms[i], &hitthing)) {
|
||||||
// check if it's far enough away from the end point
|
// check if it's far enough away from the end point
|
||||||
if (fabsf(sp664.pos.x - endpos3d->x) >= 0.1f ||
|
if (fabsf(hitthing.pos.x - endpos3d->x) >= 0.1f ||
|
||||||
fabsf(sp664.pos.y - endpos3d->y) >= 0.1f ||
|
fabsf(hitthing.pos.y - endpos3d->y) >= 0.1f ||
|
||||||
fabsf(sp664.pos.z - endpos3d->z) >= 0.1f) {
|
fabsf(hitthing.pos.z - endpos3d->z) >= 0.1f) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1062,17 +1064,22 @@ bool shotTestLos(struct coord *gunpos2d, struct coord *gundir2d, struct coord *g
|
|||||||
prop = *propptr;
|
prop = *propptr;
|
||||||
if (prop) {
|
if (prop) {
|
||||||
if (prop->type == PROPTYPE_CHR
|
if (prop->type == PROPTYPE_CHR
|
||||||
|| (prop->type == PROPTYPE_PLAYER && prop->chr && (g_Vars.in_cutscene || playermgrGetPlayerNumByProp(prop) != g_Vars.currentplayernum))) {
|
|| (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))) {
|
||||||
chrTestHit(prop, &shotdata, false, true);
|
chrTestHit(prop, &shotdata, false, true);
|
||||||
} else if (prop->type == PROPTYPE_WEAPON || prop->type == PROPTYPE_DOOR
|
} else if (prop->type == PROPTYPE_WEAPON || (prop->type == PROPTYPE_DOOR && ((struct doorobj *)prop->obj)->doortype != DOORTYPE_LASER)
|
||||||
|| (prop->type == PROPTYPE_OBJ && prop->obj->type != OBJTYPE_GLASS && prop->obj->type != OBJTYPE_TINTEDGLASS)) {
|
|| (prop->type == PROPTYPE_OBJ && prop->obj->type != OBJTYPE_GLASS && prop->obj->type != OBJTYPE_TINTEDGLASS)) {
|
||||||
objTestHit(prop, &shotdata);
|
objTestHit(prop, &shotdata);
|
||||||
}
|
}
|
||||||
if (shotdata.hits[0].prop) {
|
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
|
// ignore some glass parts and shields
|
||||||
if (shotdata.hits[0].slowsbullet && shotdata.hits[0].hitthing.texturenum != 10000) {
|
if (shotdata.hits[0].slowsbullet && texturenum != 10000 &&
|
||||||
|
surfacetype != SURFACETYPE_GLASS && surfacetype != SURFACETYPE_GLASSXLU) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
shotdata.hits[0].prop = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
propptr--;
|
propptr--;
|
||||||
|
|||||||
@@ -17201,6 +17201,12 @@ void currentPlayerQueuePickupWeaponHudmsg(u32 weaponnum, bool dual)
|
|||||||
{
|
{
|
||||||
char buffer[100] = "";
|
char buffer[100] = "";
|
||||||
|
|
||||||
|
// Suppress pickup HUD during cutscenes
|
||||||
|
if (g_Vars.in_cutscene)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
weaponGetPickupText(buffer, weaponnum, dual);
|
weaponGetPickupText(buffer, weaponnum, dual);
|
||||||
hudmsgCreateWithFlags(buffer, HUDMSGTYPE_DEFAULT, HUDMSGFLAG_ONLYIFALIVE | HUDMSGFLAG_ALLOWDUPES);
|
hudmsgCreateWithFlags(buffer, HUDMSGTYPE_DEFAULT, HUDMSGFLAG_ONLYIFALIVE | HUDMSGFLAG_ALLOWDUPES);
|
||||||
}
|
}
|
||||||
@@ -17217,6 +17223,13 @@ s32 propPickupByPlayer(struct prop *prop, bool showhudmsg)
|
|||||||
return TICKOP_NONE;
|
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) {
|
switch (obj->type) {
|
||||||
case OBJTYPE_KEY:
|
case OBJTYPE_KEY:
|
||||||
if (g_Vars.in_cutscene == false) {
|
if (g_Vars.in_cutscene == false) {
|
||||||
|
|||||||
+55
-3
@@ -1400,6 +1400,14 @@ void setupLoadFiles(s32 stagenum)
|
|||||||
numobjs += g_Vars.numaibuddies; // the buddy's weapon
|
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_WEAPON);
|
||||||
numobjs += setupCountCommandType(OBJTYPE_KEY);
|
numobjs += setupCountCommandType(OBJTYPE_KEY);
|
||||||
numobjs += setupCountCommandType(OBJTYPE_HAT);
|
numobjs += setupCountCommandType(OBJTYPE_HAT);
|
||||||
@@ -1460,6 +1468,34 @@ void setupLoadFiles(s32 stagenum)
|
|||||||
g_Vars.maxprops = numobjs + numchrs + extra + 40;
|
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)
|
void setupCreateProps(s32 stagenum)
|
||||||
{
|
{
|
||||||
s32 withchrs = !argFindByPrefix(1, "-nochr") && !argFindByPrefix(1, "-noprop");
|
s32 withchrs = !argFindByPrefix(1, "-nochr") && !argFindByPrefix(1, "-noprop");
|
||||||
@@ -1503,6 +1539,12 @@ void setupCreateProps(s32 stagenum)
|
|||||||
numchrs += g_Vars.numaibuddies;
|
numchrs += g_Vars.numaibuddies;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef PLATFORM_N64
|
||||||
|
if (!g_Vars.normmplayerisrunning) {
|
||||||
|
numchrs += g_MaxCorpses < 0 ? MAX_CORPSES_LIMIT : g_MaxCorpses;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
chrmgrConfigure(numchrs);
|
chrmgrConfigure(numchrs);
|
||||||
} else {
|
} else {
|
||||||
chrmgrConfigure(0);
|
chrmgrConfigure(0);
|
||||||
@@ -1532,6 +1574,12 @@ void setupCreateProps(s32 stagenum)
|
|||||||
botmgrRemoveAll();
|
botmgrRemoveAll();
|
||||||
index = 0;
|
index = 0;
|
||||||
|
|
||||||
|
bool nodoors = (g_MpSetup.options & MPOPTION_NODOORS) != 0;
|
||||||
|
|
||||||
|
if (nodoors) {
|
||||||
|
setupMarkLiftDoors();
|
||||||
|
}
|
||||||
|
|
||||||
obj = (struct defaultobj *)g_StageSetup.props;
|
obj = (struct defaultobj *)g_StageSetup.props;
|
||||||
|
|
||||||
while (obj->type != OBJTYPE_END) {
|
while (obj->type != OBJTYPE_END) {
|
||||||
@@ -1552,11 +1600,15 @@ void setupCreateProps(s32 stagenum)
|
|||||||
bodyAllocateChr(stagenum, (struct packedchr *) obj, index);
|
bodyAllocateChr(stagenum, (struct packedchr *) obj, index);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case OBJTYPE_DOOR:
|
case OBJTYPE_DOOR: {
|
||||||
if (withobjs && (obj->flags2 & diffflag) == 0) {
|
struct doorobj *door = (struct doorobj *) obj;
|
||||||
setupCreateDoor((struct doorobj *)obj, index);
|
// 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);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case OBJTYPE_DOORSCALE:
|
case OBJTYPE_DOORSCALE:
|
||||||
{
|
{
|
||||||
struct doorscaleobj *scale = (struct doorscaleobj *)obj;
|
struct doorscaleobj *scale = (struct doorscaleobj *)obj;
|
||||||
|
|||||||
+10
-5
@@ -1349,12 +1349,17 @@ Gfx *sightDrawZoom(Gfx *gdl, bool sighton, f32 crossx, f32 crossy)
|
|||||||
viewbottom += 1;
|
viewbottom += 1;
|
||||||
viewtop += 1;
|
viewtop += 1;
|
||||||
}
|
}
|
||||||
|
// Align box correctly for widescreen
|
||||||
|
const f32 leftx = sightGetAdjustedX(viewleft + marginleft);
|
||||||
|
const f32 rightx = sightGetAdjustedX(viewright - marginright);
|
||||||
|
#define BOXLEFT leftx
|
||||||
|
#define BOXRIGHT rightx
|
||||||
|
#else
|
||||||
|
#define BOXLEFT (viewleft + marginleft)
|
||||||
|
#define BOXRIGHT (viewright - marginright)
|
||||||
#endif
|
#endif
|
||||||
|
#define BOXBOTTOM (viewbottom - marginbottom)
|
||||||
#define BOXLEFT (viewleft + marginleft)
|
#define BOXTOP (viewtop + margintop)
|
||||||
#define BOXRIGHT (viewright - marginright)
|
|
||||||
#define BOXBOTTOM (viewbottom - marginbottom)
|
|
||||||
#define BOXTOP (viewtop + margintop)
|
|
||||||
|
|
||||||
if (cornerwidth > BOXRIGHT - BOXLEFT) {
|
if (cornerwidth > BOXRIGHT - BOXLEFT) {
|
||||||
cornerwidth = BOXRIGHT - BOXLEFT;
|
cornerwidth = BOXRIGHT - BOXLEFT;
|
||||||
|
|||||||
+19
-6
@@ -17,7 +17,7 @@
|
|||||||
#ifndef PLATFORM_N64
|
#ifndef PLATFORM_N64
|
||||||
#include "video.h"
|
#include "video.h"
|
||||||
#include "game/gfxmemory.h"
|
#include "game/gfxmemory.h"
|
||||||
#include "game/game_13c510.h"
|
#include "game/artifact.h"
|
||||||
#include "game/player.h"
|
#include "game/player.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -2518,11 +2518,11 @@ void skyCreateSunArtifact(struct artifact *artifact, s32 x, s32 y)
|
|||||||
sunpos.x = env->suns[i].pos[0];
|
sunpos.x = env->suns[i].pos[0];
|
||||||
sunpos.y = env->suns[i].pos[1];
|
sunpos.y = env->suns[i].pos[1];
|
||||||
sunpos.z = env->suns[i].pos[2];
|
sunpos.z = env->suns[i].pos[2];
|
||||||
artifact->unk02 = artifactTestLos(&sunpos, &zero, x, y) * 0xfffc;
|
artifact->visiblelos = artifactTestLos(&sunpos, &zero, x, y) * 0xfffc;
|
||||||
#endif
|
#endif
|
||||||
artifact->unk08 = &g_ZbufPtr1[(s32)camGetScreenWidth() * y + x];
|
artifact->zbufptr = &g_ZbufPtr1[(s32)camGetScreenWidth() * y + x];
|
||||||
artifact->unk0c.u16_2 = x;
|
artifact->screenx = x;
|
||||||
artifact->unk0c.u16_1 = y;
|
artifact->screeny = y;
|
||||||
artifact->type = ARTIFACTTYPE_CIRCLE;
|
artifact->type = ARTIFACTTYPE_CIRCLE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2533,7 +2533,13 @@ f32 skyGetArtifactGroupIntensityFrac(struct artifact *artifacts)
|
|||||||
s32 i;
|
s32 i;
|
||||||
|
|
||||||
for (i = 0; i < 8; i++) {
|
for (i = 0; i < 8; i++) {
|
||||||
if (artifacts[i].type == ARTIFACTTYPE_CIRCLE && artifacts[i].unk02 == 0xfffc) {
|
const u16 test =
|
||||||
|
#ifdef PLATFORM_N64
|
||||||
|
artifacts[i].actualdepth;
|
||||||
|
#else
|
||||||
|
artifacts[i].visiblelos;
|
||||||
|
#endif
|
||||||
|
if (artifacts[i].type == ARTIFACTTYPE_CIRCLE && test == 0xfffc) {
|
||||||
sum += 0.125f;
|
sum += 0.125f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3068,6 +3074,13 @@ Gfx *skyRenderArtifacts(Gfx *gdl)
|
|||||||
|
|
||||||
void skySetOverexposure(s32 r, s32 g, s32 b)
|
void skySetOverexposure(s32 r, s32 g, s32 b)
|
||||||
{
|
{
|
||||||
|
#ifndef PLATFORM_N64
|
||||||
|
const f32 scale = videoGetOverexposureScale();
|
||||||
|
r *= scale;
|
||||||
|
g *= scale;
|
||||||
|
b *= scale;
|
||||||
|
#endif
|
||||||
|
|
||||||
g_Vars.currentplayer->overexposurered = sqrtf(g_Vars.currentplayer->overexposurered * g_Vars.currentplayer->overexposurered + r * r);
|
g_Vars.currentplayer->overexposurered = sqrtf(g_Vars.currentplayer->overexposurered * g_Vars.currentplayer->overexposurered + r * r);
|
||||||
g_Vars.currentplayer->overexposuregreen = sqrtf(g_Vars.currentplayer->overexposuregreen * g_Vars.currentplayer->overexposuregreen + g * g);
|
g_Vars.currentplayer->overexposuregreen = sqrtf(g_Vars.currentplayer->overexposuregreen * g_Vars.currentplayer->overexposuregreen + g * g);
|
||||||
g_Vars.currentplayer->overexposureblue = sqrtf(g_Vars.currentplayer->overexposureblue * g_Vars.currentplayer->overexposureblue + b * b);
|
g_Vars.currentplayer->overexposureblue = sqrtf(g_Vars.currentplayer->overexposureblue * g_Vars.currentplayer->overexposureblue + b * b);
|
||||||
|
|||||||
+1
-1
@@ -1544,7 +1544,7 @@ bool frIsAmmoWasted(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check if there are any explosions
|
// Check if there are any explosions
|
||||||
for (i = 0; i != MAX_EXPLOSIONS; i++) {
|
for (i = 0; i != g_MaxExplosions; i++) {
|
||||||
if (g_Explosions[i].prop) {
|
if (g_Explosions[i].prop) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-2
@@ -58,14 +58,16 @@ void vtxstoreFixRefs(void *find, void *replacement)
|
|||||||
struct modeldef *modeldef = model->definition;
|
struct modeldef *modeldef = model->definition;
|
||||||
struct modelnode *node = modeldef->rootnode;
|
struct modelnode *node = modeldef->rootnode;
|
||||||
struct modelrodata_dl *rodata;
|
struct modelrodata_dl *rodata;
|
||||||
|
struct modelrwdata_dl *rwdata;
|
||||||
|
|
||||||
while (node) {
|
while (node) {
|
||||||
switch (node->type & 0xff) {
|
switch (node->type & 0xff) {
|
||||||
case MODELNODETYPE_DL:
|
case MODELNODETYPE_DL:
|
||||||
rodata = &node->rodata->dl;
|
rodata = &node->rodata->dl;
|
||||||
|
rwdata = (struct modelrwdata_dl *)&model->rwdatas[rodata->rwdataindex];
|
||||||
|
|
||||||
if (model->rwdatas[rodata->rwdataindex] == (uintptr_t) find) {
|
if (rwdata->vertices == find) {
|
||||||
model->rwdatas[rodata->rwdataindex] = (uintptr_t) replacement;
|
rwdata->vertices = replacement;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case MODELNODETYPE_DISTANCE:
|
case MODELNODETYPE_DISTANCE:
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ u32 var8009cc6c;
|
|||||||
s32 g_WallhitsCriticalSpareLimit;
|
s32 g_WallhitsCriticalSpareLimit;
|
||||||
s32 g_WallhitsGoalSpareLimit;
|
s32 g_WallhitsGoalSpareLimit;
|
||||||
f32 g_WallhitTargetBloodRatio;
|
f32 g_WallhitTargetBloodRatio;
|
||||||
|
s32 g_DecalLimitMultiplier = 1;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialises an array of room numbers and a linked list of structs.
|
* Initialises an array of room numbers and a linked list of structs.
|
||||||
@@ -81,6 +82,19 @@ void wallhitReset(void)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef PLATFORM_N64
|
||||||
|
if (g_DecalLimitMultiplier > 1) {
|
||||||
|
g_WallhitsMax *= g_DecalLimitMultiplier;
|
||||||
|
g_MinPropWallhits *= g_DecalLimitMultiplier;
|
||||||
|
g_MaxPropWallhits *= g_DecalLimitMultiplier;
|
||||||
|
g_MinBgWallhitsPerRoom *= g_DecalLimitMultiplier;
|
||||||
|
g_MaxBgWallhitsPerRoom *= g_DecalLimitMultiplier;
|
||||||
|
var8009cc6c *= g_DecalLimitMultiplier;
|
||||||
|
g_WallhitsCriticalSpareLimit *= g_DecalLimitMultiplier;
|
||||||
|
g_WallhitsGoalSpareLimit *= g_DecalLimitMultiplier;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
g_WallhitCountsPerRoom = NULL;
|
g_WallhitCountsPerRoom = NULL;
|
||||||
g_WallhitsNumSettled = 0;
|
g_WallhitsNumSettled = 0;
|
||||||
g_WallhitsNumFree = 0;
|
g_WallhitsNumFree = 0;
|
||||||
|
|||||||
+26
-18
@@ -177,23 +177,31 @@ u16 *zbufGetArtifactsCfb(s32 index)
|
|||||||
return addr;
|
return addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
Gfx *zbufDrawArtifactsOffscreen(Gfx *gdl)
|
/**
|
||||||
|
* This method is designed to save artifact depths
|
||||||
|
* prior to drawing the hands and weapon on-screen
|
||||||
|
* since drawing them requires clearing the zbuffer
|
||||||
|
* to avoid clipping the gun model on floors and walls.
|
||||||
|
*
|
||||||
|
* TODO: determine if this works with the PC port
|
||||||
|
*/
|
||||||
|
Gfx *zbufSaveArtifactDepths(Gfx *gdl)
|
||||||
{
|
{
|
||||||
struct artifact *artifacts = schedGetWriteArtifacts();
|
struct artifact *artifacts = schedGetWriteArtifacts();
|
||||||
u32 stack;
|
u32 stack;
|
||||||
u16 *sp4c = g_ZbufPtr1;
|
u16 *zbuf = g_ZbufPtr1;
|
||||||
u32 s4 = 0;
|
u32 numsamples = 0;
|
||||||
u16 *sp44;
|
u16 *samples;
|
||||||
u16 *s2;
|
u16 *thissample;
|
||||||
u16 *image;
|
u16 *zbufrow;
|
||||||
s32 i;
|
s32 i;
|
||||||
|
|
||||||
viGetBackBuffer();
|
viGetBackBuffer();
|
||||||
sp44 = zbufGetArtifactsCfb(g_SchedWriteArtifactsIndex);
|
samples = zbufGetArtifactsCfb(g_SchedWriteArtifactsIndex);
|
||||||
g_SchedSpecialArtifactIndexes[g_SchedWriteArtifactsIndex] = 1;
|
g_SchedSpecialArtifactIndexes[g_SchedWriteArtifactsIndex] = 1;
|
||||||
|
|
||||||
gDPPipeSync(gdl++);
|
gDPPipeSync(gdl++);
|
||||||
gDPSetColorImage(gdl++, G_IM_FMT_RGBA, G_IM_SIZ_16b, viGetBufWidth(), OS_PHYSICAL_TO_K0(sp44));
|
gDPSetColorImage(gdl++, G_IM_FMT_RGBA, G_IM_SIZ_16b, viGetBufWidth(), OS_PHYSICAL_TO_K0(samples));
|
||||||
gDPSetScissor(gdl++, G_SC_NON_INTERLACE, 0, 0, SCREEN_320, SCREEN_240);
|
gDPSetScissor(gdl++, G_SC_NON_INTERLACE, 0, 0, SCREEN_320, SCREEN_240);
|
||||||
gDPSetCycleType(gdl++, G_CYC_COPY);
|
gDPSetCycleType(gdl++, G_CYC_COPY);
|
||||||
gDPSetTile(gdl++, G_IM_FMT_RGBA, G_IM_SIZ_16b, 0, 0x0000, 5, 0, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOLOD);
|
gDPSetTile(gdl++, G_IM_FMT_RGBA, G_IM_SIZ_16b, 0, 0x0000, 5, 0, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOLOD);
|
||||||
@@ -220,24 +228,24 @@ Gfx *zbufDrawArtifactsOffscreen(Gfx *gdl)
|
|||||||
if (1);
|
if (1);
|
||||||
|
|
||||||
if (artifacts[i].type != ARTIFACTTYPE_FREE) {
|
if (artifacts[i].type != ARTIFACTTYPE_FREE) {
|
||||||
s2 = &sp44[s4];
|
thissample = &samples[numsamples];
|
||||||
image = &sp4c[artifacts[i].unk0c.u16_1 * viGetWidth()];
|
zbufrow = &zbuf[artifacts[i].screeny * viGetWidth()];
|
||||||
|
|
||||||
gDPPipeSync(gdl++);
|
gDPPipeSync(gdl++);
|
||||||
gDPSetTextureImage(gdl++, G_IM_FMT_RGBA, G_IM_SIZ_16b, SCREEN_320, image);
|
gDPSetTextureImage(gdl++, G_IM_FMT_RGBA, G_IM_SIZ_16b, SCREEN_320, zbufrow);
|
||||||
gDPLoadSync(gdl++);
|
gDPLoadSync(gdl++);
|
||||||
gDPLoadBlock(gdl++, 5, 0, 0, viGetWidth() - 1, 0);
|
gDPLoadBlock(gdl++, 5, 0, 0, viGetWidth() - 1, 0);
|
||||||
gDPPipeSync(gdl++);
|
gDPPipeSync(gdl++);
|
||||||
|
|
||||||
gSPTextureRectangle(gdl++,
|
gSPTextureRectangle(gdl++,
|
||||||
s4 << 2, 0,
|
numsamples << 2, 0,
|
||||||
(s4 + 3) << 2, 0,
|
(numsamples + 3) << 2, 0,
|
||||||
G_TX_RENDERTILE, (artifacts[i].unk0c.u16_2 * 32) + 16, 0x0010, 0x1000, 0);
|
G_TX_RENDERTILE, (artifacts[i].screenx * 32) + 16, 0x0010, 0x1000, 0);
|
||||||
|
|
||||||
artifacts[i].unk0c.u16p = s2;
|
artifacts[i].depthptr = thissample;
|
||||||
s4++;
|
numsamples++;
|
||||||
|
|
||||||
if (s2);
|
if (thissample);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -251,7 +259,7 @@ Gfx *zbufDrawArtifactsOffscreen(Gfx *gdl)
|
|||||||
gDPSetTexturePersp(gdl++, G_TP_PERSP);
|
gDPSetTexturePersp(gdl++, G_TP_PERSP);
|
||||||
gDPSetColorDither(gdl++, G_CD_BAYER);
|
gDPSetColorDither(gdl++, G_CD_BAYER);
|
||||||
|
|
||||||
if (sp44);
|
if (samples);
|
||||||
|
|
||||||
return gdl;
|
return gdl;
|
||||||
}
|
}
|
||||||
@@ -201,6 +201,8 @@ extern u32 g_SkyStageNum;
|
|||||||
extern bool g_SkyLightningActive;
|
extern bool g_SkyLightningActive;
|
||||||
extern struct explosion *g_Explosions;
|
extern struct explosion *g_Explosions;
|
||||||
extern s32 g_MaxExplosions;
|
extern s32 g_MaxExplosions;
|
||||||
|
extern s32 g_DecalLimitMultiplier;
|
||||||
|
extern s32 g_MaxCorpses;
|
||||||
extern struct smoke *g_Smokes;
|
extern struct smoke *g_Smokes;
|
||||||
extern s32 g_MaxSmokes;
|
extern s32 g_MaxSmokes;
|
||||||
extern Mtx var800a3448;
|
extern Mtx var800a3448;
|
||||||
@@ -295,6 +297,7 @@ extern s32 g_JpnMaxCacheItems;
|
|||||||
extern s32 var8009d370jf;
|
extern s32 var8009d370jf;
|
||||||
#ifndef PLATFORM_N64
|
#ifndef PLATFORM_N64
|
||||||
extern bool g_ValidGbcRomFound;
|
extern bool g_ValidGbcRomFound;
|
||||||
|
extern bool g_BgHitXluDisabled;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -18,7 +18,6 @@
|
|||||||
#define MAX_CHRSPERSQUADRON 16
|
#define MAX_CHRSPERSQUADRON 16
|
||||||
#define MAX_CHRSPERTEAM 32
|
#define MAX_CHRSPERTEAM 32
|
||||||
#define MAX_CHRWAYPOINTS 6
|
#define MAX_CHRWAYPOINTS 6
|
||||||
#define MAX_EXPLOSIONS 6
|
|
||||||
#define MAX_EYESPYDARTS 8
|
#define MAX_EYESPYDARTS 8
|
||||||
#define MAX_MPCHRS (MAX_PLAYERS + MAX_BOTS)
|
#define MAX_MPCHRS (MAX_PLAYERS + MAX_BOTS)
|
||||||
#define MAX_MPPLAYERCONFIGS (MAX_PLAYERS + 2)
|
#define MAX_MPPLAYERCONFIGS (MAX_PLAYERS + 2)
|
||||||
@@ -28,6 +27,9 @@
|
|||||||
#define MAX_ROOMPROPLISTCHUNKS 256
|
#define MAX_ROOMPROPLISTCHUNKS 256
|
||||||
#define MAX_SQUADRONS 16
|
#define MAX_SQUADRONS 16
|
||||||
#define MAX_TEAMS 8
|
#define MAX_TEAMS 8
|
||||||
|
#define MAX_EXPLOSIONS_DEFAULT 6
|
||||||
|
#define MAX_DECAL_LIMIT_MULTIPLIER 10
|
||||||
|
#define MAX_CORPSES_LIMIT 64
|
||||||
|
|
||||||
#define NUM_BOTDIFFS 6
|
#define NUM_BOTDIFFS 6
|
||||||
#define NUM_CYCLEABLE_WEAPONS 45
|
#define NUM_CYCLEABLE_WEAPONS 45
|
||||||
@@ -2898,6 +2900,7 @@
|
|||||||
#define MPOPTION_AUTORANDOMWEAPON_END 0x01000000
|
#define MPOPTION_AUTORANDOMWEAPON_END 0x01000000
|
||||||
#define MPOPTION_FRIENDLYFIRE 0x02000000
|
#define MPOPTION_FRIENDLYFIRE 0x02000000
|
||||||
#define MPOPTION_NOPLAYERONRADAR 0x04000000
|
#define MPOPTION_NOPLAYERONRADAR 0x04000000
|
||||||
|
#define MPOPTION_NODOORS 0x08000000
|
||||||
|
|
||||||
#define MPPAUSEMODE_UNPAUSED 0
|
#define MPPAUSEMODE_UNPAUSED 0
|
||||||
#define MPPAUSEMODE_PAUSED 1
|
#define MPPAUSEMODE_PAUSED 1
|
||||||
|
|||||||
@@ -6,10 +6,10 @@
|
|||||||
|
|
||||||
void artifactsClear(void);
|
void artifactsClear(void);
|
||||||
void artifactsTick(void);
|
void artifactsTick(void);
|
||||||
u16 func0f13c574(f32 arg0);
|
u16 floatToN64Depth(f32 arg0);
|
||||||
s32 func0f13c710(f32 arg0);
|
s32 artifactsFloatToInt(f32 arg0);
|
||||||
void artifactsCalculateGlaresForRoom(s32 roomnum);
|
void artifactsCalculateGlaresForRoom(s32 roomnum);
|
||||||
u8 func0f13d3c4(u8 arg0, u8 arg1);
|
u8 artifactsClamp(u8 arg0, u8 arg1);
|
||||||
Gfx *artifactsConfigureForGlares(Gfx *gdl);
|
Gfx *artifactsConfigureForGlares(Gfx *gdl);
|
||||||
Gfx *artifactsUnconfigureForGlares(Gfx *gdl);
|
Gfx *artifactsUnconfigureForGlares(Gfx *gdl);
|
||||||
Gfx *artifactsRenderGlaresForRoom(Gfx *gdl, s32 roomnum);
|
Gfx *artifactsRenderGlaresForRoom(Gfx *gdl, s32 roomnum);
|
||||||
@@ -113,6 +113,10 @@ MenuItemHandlerResult menuhandlerRepairPak(s32 operation, struct menuitem *item,
|
|||||||
MenuItemHandlerResult menuhandlerRetrySavePak(s32 operation, struct menuitem *item, union handlerdata *data);
|
MenuItemHandlerResult menuhandlerRetrySavePak(s32 operation, struct menuitem *item, union handlerdata *data);
|
||||||
MenuItemHandlerResult menuhandlerWarnRepairPak(s32 operation, struct menuitem *item, union handlerdata *data);
|
MenuItemHandlerResult menuhandlerWarnRepairPak(s32 operation, struct menuitem *item, union handlerdata *data);
|
||||||
|
|
||||||
|
s32 menuAlt1Pressed(s32 playerNum);
|
||||||
|
s32 menuAlt2Pressed(s32 playerNum);
|
||||||
|
s32 menuAltAnyPressed(s32 playerNum);
|
||||||
|
|
||||||
extern const char var7f1b2658[];
|
extern const char var7f1b2658[];
|
||||||
extern const char var7f1b265c[];
|
extern const char var7f1b265c[];
|
||||||
extern const char var7f1b2660[];
|
extern const char var7f1b2660[];
|
||||||
|
|||||||
@@ -10,6 +10,6 @@ void zbufAllocate(void);
|
|||||||
void zbufSwap(void);
|
void zbufSwap(void);
|
||||||
Gfx *zbufConfigureRdp(Gfx *gdl);
|
Gfx *zbufConfigureRdp(Gfx *gdl);
|
||||||
Gfx *zbufClear(Gfx *gdl);
|
Gfx *zbufClear(Gfx *gdl);
|
||||||
Gfx *zbufDrawArtifactsOffscreen(Gfx *gdl);
|
Gfx *zbufSaveArtifactDepths(Gfx *gdl);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
+25
-13
@@ -3494,17 +3494,19 @@ struct audioconfig {
|
|||||||
|
|
||||||
struct artifact {
|
struct artifact {
|
||||||
u16 type;
|
u16 type;
|
||||||
u16 unk02;
|
u16 actualdepth;
|
||||||
u16 unk04;
|
u16 expecteddepth;
|
||||||
u16 unk06;
|
u16 *zbufptr;
|
||||||
u16 *unk08;
|
#ifndef PLATFORM_N64
|
||||||
|
u16 visiblelos;
|
||||||
|
#endif
|
||||||
union {
|
union {
|
||||||
u16 *u16p;
|
u16 *depthptr;
|
||||||
struct {
|
struct {
|
||||||
u16 u16_1;
|
u16 screeny;
|
||||||
u16 u16_2;
|
u16 screenx;
|
||||||
};
|
};
|
||||||
} unk0c;
|
};
|
||||||
struct light *light;
|
struct light *light;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -3774,10 +3776,13 @@ struct menudata_main {
|
|||||||
struct menudata_mpsetup {
|
struct menudata_mpsetup {
|
||||||
u32 slotindex;
|
u32 slotindex;
|
||||||
u32 slotcount;
|
u32 slotcount;
|
||||||
u8 showpresets;
|
|
||||||
u32 unke24;
|
u32 unke24;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct menudata_mpsetup_ext {
|
||||||
|
u8 showpresets;
|
||||||
|
};
|
||||||
|
|
||||||
struct menudata_mppause {
|
struct menudata_mppause {
|
||||||
u32 unke1c;
|
u32 unke1c;
|
||||||
u32 unke20;
|
u32 unke20;
|
||||||
@@ -3988,9 +3993,10 @@ struct menu {
|
|||||||
struct menudata_filemgr fm;
|
struct menudata_filemgr fm;
|
||||||
struct menudata_main4mb main4mb;
|
struct menudata_main4mb main4mb;
|
||||||
struct menudata_training training;
|
struct menudata_training training;
|
||||||
|
struct menudata_mpsetup mpsetup;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct menudata_mpsetup mpsetup;
|
struct menudata_mpsetup_ext mpsetupext;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct gamefile {
|
struct gamefile {
|
||||||
@@ -4101,6 +4107,11 @@ struct mpsetup {
|
|||||||
/*0x800acba0*/ u8 weapons[NUM_MPWEAPONSLOTS];
|
/*0x800acba0*/ u8 weapons[NUM_MPWEAPONSLOTS];
|
||||||
/*0x800acba6*/ u8 paused;
|
/*0x800acba6*/ u8 paused;
|
||||||
/*0x800acba8*/ struct fileguid fileguid;
|
/*0x800acba8*/ struct fileguid fileguid;
|
||||||
|
#ifndef PLATFORM_N64
|
||||||
|
// Used to restore the non-player bits of chrslots upon entering Combat
|
||||||
|
// Simulator, after playing Co-Op/Counter-Op with a human sim.
|
||||||
|
u16 storedbotbits;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
struct bossfile {
|
struct bossfile {
|
||||||
@@ -4785,8 +4796,8 @@ struct menudata_5d8 {
|
|||||||
struct menudata {
|
struct menudata {
|
||||||
/*0x000*/ s32 count;
|
/*0x000*/ s32 count;
|
||||||
/*0x004*/ s32 root;
|
/*0x004*/ s32 root;
|
||||||
/*0x008*/ s32 unk008; // also a menuroot constant
|
/*0x008*/ s32 prevmenuroot; // also a menuroot constant
|
||||||
/*0x00c*/ struct menudialogdef *unk00c;
|
/*0x00c*/ struct menudialogdef *prevmenudialog;
|
||||||
/*0x010*/ f32 unk010;
|
/*0x010*/ f32 unk010;
|
||||||
/*0x014*/ u8 bg;
|
/*0x014*/ u8 bg;
|
||||||
/*0x015*/ u8 nextbg;
|
/*0x015*/ u8 nextbg;
|
||||||
@@ -4800,7 +4811,7 @@ struct menudata {
|
|||||||
/*0x5d5*/ u8 usezbuf : 1;
|
/*0x5d5*/ u8 usezbuf : 1;
|
||||||
/*0x5d5*/ u8 unk5d5_04 : 1;
|
/*0x5d5*/ u8 unk5d5_04 : 1;
|
||||||
/*0x5d5*/ u8 unk5d5_05 : 1;
|
/*0x5d5*/ u8 unk5d5_05 : 1;
|
||||||
/*0x5d5*/ u8 unk5d5_06 : 1;
|
/*0x5d5*/ u8 isdialogopen : 1;
|
||||||
/*0x5d5*/ u8 unk5d5_07 : 1;
|
/*0x5d5*/ u8 unk5d5_07 : 1;
|
||||||
/*0x5d5*/ u8 unk5d5_08 : 1;
|
/*0x5d5*/ u8 unk5d5_08 : 1;
|
||||||
/*0x5d8*/ struct menudata_5d8 unk5d8[12];
|
/*0x5d8*/ struct menudata_5d8 unk5d8[12];
|
||||||
@@ -6154,6 +6165,7 @@ struct extplayerconfig {
|
|||||||
s32 extcontrols;
|
s32 extcontrols;
|
||||||
u32 crosshaircolour;
|
u32 crosshaircolour;
|
||||||
u32 crosshairsize;
|
u32 crosshairsize;
|
||||||
|
f32 crosshairedgeboundary;
|
||||||
s32 crosshairhealth;
|
s32 crosshairhealth;
|
||||||
s32 usereloads;
|
s32 usereloads;
|
||||||
};
|
};
|
||||||
|
|||||||
+8
-8
@@ -540,20 +540,20 @@ void schedUpdatePendingArtifacts(void)
|
|||||||
struct artifact *artifact = &artifacts[i];
|
struct artifact *artifact = &artifacts[i];
|
||||||
|
|
||||||
if (artifact->type != ARTIFACTTYPE_FREE) {
|
if (artifact->type != ARTIFACTTYPE_FREE) {
|
||||||
u16 *unk08 = artifact->unk08;
|
u16 *currdepthptr = artifact->zbufptr;
|
||||||
u16 value08 = unk08[0];
|
u16 currdepth = *currdepthptr;
|
||||||
|
|
||||||
if (g_SchedSpecialArtifactIndexes[g_SchedPendingArtifactsIndex] == 1) {
|
if (g_SchedSpecialArtifactIndexes[g_SchedPendingArtifactsIndex] == 1) {
|
||||||
u16 *unk0c = artifact->unk0c.u16p;
|
u16 *prevdepthptr = artifact->depthptr;
|
||||||
u16 value0c = unk0c[0];
|
u16 prevdepth = *prevdepthptr;
|
||||||
|
|
||||||
if (value0c > value08) {
|
if (currdepth < prevdepth) {
|
||||||
artifact->unk02 = value08;
|
artifact->actualdepth = currdepth;
|
||||||
} else {
|
} else {
|
||||||
artifact->unk02 = value0c;
|
artifact->actualdepth = prevdepth;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
artifact->unk02 = value08;
|
artifact->actualdepth = currdepth;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user