Compare commits

...

89 Commits
v1.1.0 ... main

Author SHA1 Message Date
Jack Garrard ad79fe1732
Merge pull request #61 from speyejack/main
Release v1.4.0
2023-09-27 01:02:37 -07:00
Jack Garrard ca5cef2ff4 Merge branch 'main' into dev 2023-09-27 00:25:19 -07:00
Jack Garrard f548de2117
Merge pull request #60 from speyejack/main
Release v1.1.0 - v1.3.0
2023-09-12 15:01:30 -07:00
Jack Garrard cdac0a8679 Merge commit 'd5b49b2' 2023-09-12 13:36:12 -07:00
Jack Garrard 3570175752 Merge commit '4339847' 2023-09-12 13:35:35 -07:00
Jack Garrard cf97f2b214
Merge pull request #56 from speyejack/readme-update
Readme update
2023-09-11 16:11:26 -07:00
Jack Garrard 6b81465197
Merge pull request #58 from Istador/auto-reconnect-again
fix: add auto reconnect again
2023-09-11 16:10:11 -07:00
Jack Garrard 800ade7842 Update website link to say online instead of implying smo directly 2023-09-11 12:51:47 -07:00
Jack Garrard d0dfb63519 Simplify the readme for the average user and direct to website 2023-09-11 00:44:52 -07:00
Robin C. Ladiges b4d90d1d85
fix: add auto reconnect again 2023-09-07 19:30:57 +02:00
Jack Garrard f27875f65f
Fix extra curly bracket 2023-09-03 18:39:03 -07:00
Jack Garrard 44f8ece7ce
Merge pull request #52 from piplup55/rework/ryujinx-mod-manager
Change Workflow
2023-09-03 17:01:50 -07:00
Jack Garrard 83a1d70e01 Update readme to mention website 2023-09-02 20:37:05 -07:00
Jack Garrard 1da9626a44
Merge pull request #39 from speyejack/udp-client
Allow udp communication for movement
2023-09-02 13:48:46 -07:00
Jack Garrard 8acb8700bf
Merge branch 'dev' into udp-client 2023-09-02 13:35:38 -07:00
Jack Garrard d5b49b2ea9
Merge pull request #37 from speyejack/packet-acceptance
Packet acceptance
2023-09-02 13:03:18 -07:00
Jack Garrard 7064122902
Merge branch 'dev' into packet-acceptance 2023-09-02 12:58:53 -07:00
Jack Garrard 8d94cf7856
Merge pull request #54 from Istador/resend-packets
fix: `TagInf` and `CaptureInf` synchronization issues
2023-08-25 18:51:28 -07:00
Jack Garrard 9bf07b3e0d
Merge pull request #53 from Istador/isit-with-active
fix: mark player as not a seeker when H&S is disabled
2023-08-24 23:42:13 -07:00
Jack Garrard 125e2bdde2
Merge pull request #55 from Istador/ui-improvements
UI improvements
2023-08-24 23:11:31 -07:00
Robin C. Ladiges 45cd4442c8
recycle the reconnect error to warn about the default Ryujinx profile ID 2023-07-08 20:45:53 +02:00
Robin C. Ladiges c736878df1
`Toggle H&S Gravity` with real toggle functionality 2023-07-08 04:31:56 +02:00
Robin C. Ladiges 366ad5e888
remove reconnect button 2023-07-07 23:46:11 +02:00
Robin C. Ladiges f810e8f07d
fix: send empty TagInf and CaptureInf on first connection
Because other players might still have old values saved in their puppet.
2023-06-24 04:09:47 +02:00
Robin C. Ladiges 2bef6f796e
fix: resend CaptureInf packet on reconnect and for new players 2023-06-24 02:42:54 +02:00
Robin C. Ladiges 4835692672
fix: resend TagInf packet on reconnect and for new players 2023-06-24 01:27:14 +02:00
Robin C. Ladiges 27b9a095f7
fix: mark player as not a seeker when H&S is disabled
If a player is a seeker and then disables H&S, they should no longer be considered as a seeker by other players.
(Because staying as a seeker will kill hiders when touching them).
2023-06-23 04:18:41 +02:00
Piplup b86322f346
z 2023-06-06 14:35:44 +01:00
piplup 936e0fd49f addressed feedback 2023-06-05 21:56:27 +01:00
piplup 4d242a5e44 forgot to rename 2023-06-05 21:06:58 +01:00
piplup 41719e1f9f a 2023-06-05 21:02:29 +01:00
piplup f8a3deefc4 a 2023-06-05 20:58:28 +01:00
piplup cd8bf4e257 Update dev-release.yml 2023-06-05 20:54:14 +01:00
Robin C. Ladiges 4339847da5 fix yuzu build
Accidentially moved it into the wrong directory.
2022-12-16 16:24:37 -06:00
Robin C. Ladiges f60fc956d6 for Emulators => for Ryujinx & for yuzu 2022-12-16 13:21:07 -06:00
Robin C. Ladiges 7f6df57f4a patch out deprecated ::set-output
::set-output currently triggers deprecation warnings and will stop working at 2023-06-01.

https://github.blog/changelog/2022-10-11-github-actions-deprecating-save-state-and-set-output-commands/
2022-12-16 13:21:07 -06:00
Robin C. Ladiges 6a5b5146b8 use devkitpro docker image
installing it via pacman everytime is unsupported and will lead to http 403 errors.
2022-12-16 13:21:07 -06:00
Robin C. Ladiges 36f9343f83 don't send empty GameInf and CostumeInf packets and resend them on reconnect
Resend because: on server restarts the server will lose the stage and costume information.

If only one client is connected to the server, the packets currently aren't resent, so the server doesn't know in which stage the client is and what
costume it wears
(which I'd like to display on the website).

With more then one client connected it already works, because when another client joins the server, the client will send both packets.
2022-12-16 13:19:54 -06:00
Jack Garrard 76d61a8067 Success and receive spelling 2022-10-29 18:21:58 -07:00
Jack Garrard 8c992649fd Remove tabs 2022-10-29 18:16:43 -07:00
Jack Garrard 477f1c9e7d Add a poll time to wait properly 2022-10-29 18:12:53 -07:00
Jack Garrard 4ab6b56598 Use valread and check if it returns zero for udp 2022-10-29 17:46:20 -07:00
Jack Garrard 158f782a2a Change socket client recvTcp to use if guards 2022-10-29 17:41:54 -07:00
Jack Garrard 7e128679ab Split apart tcp and udp recv functions 2022-10-29 17:37:30 -07:00
Jack Garrard 1fc3a78943 Shutdown send/recv threads before socket reinit 2022-10-29 17:17:38 -07:00
Jack Garrard 627e07cd65 Fix missing semicolon 2022-10-27 04:54:30 -07:00
Jack Garrard 57333d71e9 Fix recv buf size calculation 2022-10-27 04:52:27 -07:00
Jack Garrard 4171390f42 Allow hole punch packets to get through before udp fully recved 2022-10-27 04:51:36 -07:00
Jack Garrard 5c04bb1006 Use if guard for alloc in udp recv 2022-10-27 04:46:36 -07:00
Jack Garrard 04fc8cb309 Increased max packet size again 2022-10-27 03:22:01 -07:00
Jack Garrard a58471c19f New lines for logger output 2022-10-27 03:21:54 -07:00
Jack Garrard 0147f4d738 Change send patch to follow make file rules 2022-10-27 02:12:00 -07:00
Jack Garrard 000d24a7db Made makefile use python3 instead of python3.8 2022-10-27 02:11:28 -07:00
Jack Garrard 78b532a316 Prevent udp error from killing tcp connection 2022-10-27 02:10:44 -07:00
Jack Garrard efef24fbbe Fix variable names again 2022-10-27 02:09:59 -07:00
Jack Garrard 3e5c0c89e5 Merge branch 'packet-acceptance' into udp-client 2022-10-27 01:03:39 -07:00
Jack Garrard 64b56c32da Add race protection to message queues 2022-10-27 01:02:32 -07:00
Jack Garrard 89415e6f96 Hopefully prevent close socket race condition 2022-10-27 01:00:58 -07:00
Jack Garrard e6871da878 Readd missing variable 2022-10-27 00:27:29 -07:00
Jack Garrard 24e724a824 Hopefully prevent close socket race condition 2022-10-27 00:26:26 -07:00
Jack Garrard 28c7f92453 Refactor member variable names 2022-10-27 00:25:37 -07:00
Jack Garrard 4a5a10f910 Convert receive buffer to be on heap 2022-10-26 03:33:42 -07:00
Jack Garrard bf646b2b3d Add a newline to debug statement 2022-10-26 03:31:32 -07:00
Jack Garrard 53f91b8695 Clean up 2022-10-26 02:44:09 -07:00
Jack Garrard a9c3ec4006 Fix a stack exhausion bug 2022-10-26 02:44:04 -07:00
Jack Garrard 4655b0755e Remove udp connection attempt in init and leave default port at 0 2022-10-25 19:41:09 -07:00
Jack Garrard 93c750ccf7 Remove tabs 2022-10-25 19:33:58 -07:00
Jack Garrard 655368241f Made default port be a higher port 2022-10-25 18:07:26 -07:00
Jack Garrard ed83827cc1 Add udp status to debug menu 2022-10-23 18:37:08 -07:00
Jack Garrard 2654650804 Reset recv udp flag on connection close 2022-10-23 17:52:34 -07:00
Jack Garrard 694c9e73d6 Allow for a udp handshake 2022-10-23 16:37:47 -07:00
Jack Garrard 968f513bf2 Merge branch 'packet-acceptance' into udp-client 2022-10-23 14:41:48 -07:00
Jack Garrard 7c17db2d93 Fix free issue from wrong heap if unknown packet 2022-10-23 14:41:16 -07:00
Jack Garrard ba7612a304 Fix a changed variable 2022-10-21 12:59:35 -07:00
Jack Garrard d666707e24 Merge branch 'packet-acceptance' into udp-client 2022-10-21 12:37:57 -07:00
Jack Garrard 1fd02147b6 Add a flag to only send udp if client has received udp packets 2022-10-21 12:27:01 -07:00
Jack Garrard f6408e2b1e Merge branch 'dev' into packet-acceptance 2022-10-15 00:18:57 -07:00
Jack Garrard 2f5ed106fa Hopefully fix emulators 2022-09-05 12:44:54 -07:00
Jack Garrard b163749c77 Remove extra word 2022-09-05 03:28:27 -07:00
Jack Garrard 009755ceba Add pollfd to socket.h 2022-09-05 03:26:14 -07:00
Jack Garrard f417d39f3b Comment out extra udpaddress 2022-09-05 03:26:01 -07:00
Jack Garrard 66c8bb9e1b Closer to working 2022-09-05 03:19:33 -07:00
CraftyBoss 13c873aae0
Merge pull request #35 from Istador/emu-build
separate build for emulators
2022-09-04 20:11:38 -07:00
Robin C. Ladiges 65d6ffb4fc
separate build for emulators 2022-09-05 02:30:30 +02:00
CraftyBoss cc4c1d7c67 Merge branch 'dev' of https://github.com/CraftyBoss/SuperMarioOdysseyOnline into dev 2022-09-04 02:23:16 -07:00
CraftyBoss d4eabffff1 executor table re-impl, shine sync changes, send/recv netcode refactored 2022-09-04 02:23:02 -07:00
Jack Garrard 19c6d800bd More changes while testing 2022-09-03 01:57:57 -07:00
Jack Garrard 1204e27adb Attempt at full udp client 2022-08-30 15:18:44 -07:00
Jack Garrard b18671f113 Move packet type check to after packet data recv 2022-08-27 01:56:20 -07:00
93 changed files with 3276 additions and 812 deletions

View File

@ -27,7 +27,7 @@ runs:
shell : bash
run: |
cd ./starlight_patch_100/
zip -rmT9 ${{ inputs.filename }}.zip ./*
zip -rmT9 "${{ inputs.filename }}.zip" ./*
-
name : Attach to release
uses : actions/upload-release-asset@v1
@ -36,5 +36,10 @@ runs:
with:
upload_url : ${{ inputs.upload_url }}
asset_path : ./starlight_patch_100/${{ inputs.filename }}.zip
asset_name : ${{ inputs.filename }}.zip
asset_name : "${{ inputs.filename }}.zip"
asset_content_type : application/zip
-
name : Cleanup artifacts
shell : bash
run: |
rm -rf ./starlight_patch_100/

View File

@ -10,6 +10,10 @@ inputs:
description : 'filename prefix'
required : false
default : ''
emu:
description : 'what system the build is for: Switch or Emulators'
required : false
default : 'Switch'
outputs:
@ -27,8 +31,8 @@ runs:
shell : bash
run: |
VERS=${{ inputs.tag }}
echo "::set-output name=version::${VERS:1}"
echo "::set-output name=filename::${{ inputs.prefix }}SMO_Online${{ (inputs.tag != '' && format('_{0}', inputs.tag)) || '' }}"
echo "version=${VERS:1}" >>$GITHUB_OUTPUT
echo "filename=${{ inputs.prefix }}SMO_Online${{ (inputs.tag != '' && format('_{0}', inputs.tag)) || '' }}_for_${{ inputs.emu }}" >>$GITHUB_OUTPUT
-
name : Set up Docker Buildx
uses : docker/setup-buildx-action@v2
@ -49,13 +53,25 @@ runs:
name : Build mod
shell : bash
run: |
docker run --rm \
-u `id -u`:`id -g` \
-v "/$PWD/":/app/ \
docker run --rm \
-u `id -u`:`id -g` \
-v "/$PWD/":/app/ \
-e ISEMU=${{ (inputs.emu != 'Switch' && '1') || '0' }} \
${{ (steps.env.outputs.version != '' && format('-e BUILDVER={0}', steps.env.outputs.version)) || '' }} \
smoo-build-env \
;
cp -r ./romfs/ ./starlight_patch_100/atmosphere/contents/0100000000010000/.
-
name : Emulators
shell : bash
if : ${{ inputs.emu == 'Emulators' }}
run: |
cd ./starlight_patch_100/
mkdir ./SMOO/
mv ./atmosphere/contents/0100000000010000/exefs ./SMOO/exefs
mv ./atmosphere/contents/0100000000010000/romfs ./SMOO/romfs
mv ./atmosphere/exefs_patches/StarlightBase/3CA12DFAAF9C82DA064D1698DF79CDA1.ips ./SMOO/exefs/
rm -rf ./atmosphere/
-
name : Upload artifacts
uses : actions/upload-artifact@v3

View File

@ -20,6 +20,9 @@ on:
jobs:
build:
strategy:
matrix:
emu : [ Switch, Emulators ]
runs-on: ubuntu-latest
steps:
-
@ -28,3 +31,5 @@ jobs:
-
name : Build artifacts
uses : ./.github/actions/build
with:
emu : ${{ matrix.emu }}

View File

@ -19,9 +19,13 @@ concurrency:
jobs:
build:
strategy:
matrix:
emu : [ Switch, Emulators ]
runs-on: ubuntu-latest
outputs:
filename: ${{ steps.build.outputs.filename }}
filename1: ${{ steps.set-output.outputs.filename-Switch }}
filename2: ${{ steps.set-output.outputs.filename-Emulators }}
steps:
-
name : Checkout
@ -31,13 +35,20 @@ jobs:
id : env
shell : bash
run: |
echo "::set-output name=prefix::$(date +'%Y%m%d_%H%M%S_' --utc)"
echo "prefix=$(date +'%Y%m%d_%H%M%S_' --utc)" >>$GITHUB_OUTPUT
-
name : Build artifacts
id : build
uses : ./.github/actions/build
with:
prefix : ${{ steps.env.outputs.prefix }}
emu : ${{ matrix.emu }}
-
name : Set output
id : set-output
shell : bash
run : |
echo "filename-${{ matrix.emu }}=${{ steps.build.outputs.filename }}" >>$GITHUB_OUTPUT
attach:
needs: build
@ -52,12 +63,19 @@ jobs:
shell : bash
run: |
url=`curl -sS --fail ${{ github.api_url }}/repos/${{ github.repository }}/releases/tags/${{ env.TAG }} | jq .upload_url -r`
echo "::set-output name=upload_url::$url"
echo "upload_url=$url" >>$GITHUB_OUTPUT
-
name : Attach build artifacts to release
name : Attach build artifacts to release (Switch)
uses : ./.github/actions/attach
with:
filename : ${{ needs.build.outputs.filename }}
filename : ${{ needs.build.outputs.filename1 }}
upload_url : ${{ steps.release.outputs.upload_url }}
GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }}
-
name : Attach build artifacts to release (Emulators)
uses : ./.github/actions/attach
with:
filename : ${{ needs.build.outputs.filename2 }}
upload_url : ${{ steps.release.outputs.upload_url }}
GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }}

View File

@ -12,9 +12,13 @@ on:
jobs:
build:
strategy:
matrix:
emu : [ Switch, Emulators ]
runs-on: ubuntu-latest
outputs:
filename: ${{ steps.build.outputs.filename }}
filename1: ${{ steps.set-output.outputs.filename-Switch }}
filename2: ${{ steps.set-output.outputs.filename-Emulators }}
steps:
-
name : Checkout
@ -25,6 +29,13 @@ jobs:
uses : ./.github/actions/build
with:
tag : ${{ github.ref_name }}
emu : ${{ matrix.emu }}
-
name : Set output
id : set-output
shell : bash
run : |
echo "::set-output name=filename-${{ matrix.emu }}::${{ steps.build.outputs.filename }}"
release:
needs: build
@ -41,9 +52,16 @@ jobs:
tag : ${{ github.ref_name }}
GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }}
-
name : Attach build artifacts to release
name : Attach build artifacts to release (Switch)
uses : ./.github/actions/attach
with:
filename : ${{ needs.build.outputs.filename }}
filename : ${{ needs.build.outputs.filename1 }}
upload_url : ${{ steps.release.outputs.upload_url }}
GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }}
-
name : Attach build artifacts to release (Emulators)
uses : ./.github/actions/attach
with:
filename : ${{ needs.build.outputs.filename2 }}
upload_url : ${{ steps.release.outputs.upload_url }}
GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }}

1
.gitignore vendored
View File

@ -6,5 +6,6 @@ Crash Reports/**
.cache/**
Custom Stage Builds/**
*.lst
*.disabled
compile_commands.json

View File

@ -1,26 +1,13 @@
FROM ubuntu:20.04 as builder
FROM devkitpro/devkita64:latest as builder
# install dependencies
RUN apt-get update \
&& apt-get install -y \
curl \
apt-transport-https \
python3 \
python3-pip \
&& pip install keystone-engine \
;
# install devkitpro
RUN ln -s /proc/self/mounts /etc/mtab \
&& mkdir /devkitpro/ \
&& echo "deb [signed-by=/devkitpro/pub.gpg] https://apt.devkitpro.org stable main" >/etc/apt/sources.list.d/devkitpro.list \
&& curl --fail -o /devkitpro/pub.gpg https://apt.devkitpro.org/devkitpro-pub.gpg \
&& apt-get update \
&& DEBIAN_FRONTEND=noninteractive apt-get install -y devkitpro-pacman \
&& dkp-pacman --noconfirm -S switch-dev \
&& pip3 install keystone-engine \
;
WORKDIR /app/
ENV DEVKITPRO /opt/devkitpro
ENTRYPOINT make

View File

@ -45,15 +45,15 @@ emu:
mv $(shell basename $(CURDIR))$(SMOVER).nso starlight_patch_$(SMOVER)/yuzu/subsdk1
# builds and sends project to FTP server hosted on provided IP
send: all
python3.8 scripts/sendPatch.py $(IP) $(PROJNAME)
python3 scripts/sendPatch.py $(IP) $(PROJNAME)
log: all
python3.8 scripts/tcpServer.py $(SERVERIP)
python3 scripts/tcpServer.py $(SERVERIP)
sendlog: all
python3.8 scripts/sendPatch.py $(IP) $(PROJNAME) $(USER) $(PASS)
python3.8 scripts/tcpServer.py $(SERVERIP)
python3 scripts/sendPatch.py $(IP) $(PROJNAME) $(USER) $(PASS)
python3 scripts/tcpServer.py $(SERVERIP)
clean:
$(MAKE) clean -f MakefileNSO
@rm -fr starlight_patch_*
@rm -fr starlight_patch_*

View File

@ -32,7 +32,8 @@ include $(DEVKITPRO)/libnx/switch_rules
#---------------------------------------------------------------------------------
TARGET ?= $(notdir $(CURDIR))$(SMOVER)
BUILD ?= build$(SMOVER)
SOURCES := source/sead/time source/sead source/puppets source/server/hns source/server/gamemode source/server source/layouts source/states source/cameras source/nx source
SOURCES := source/sead/time source/sead source/puppets source/server/hns source/server/gamemode source/server/gamemode/modifiers source/server source/layouts source/states source/cameras source/nx source
SOURCES += source/al/execute
DATA := data
INCLUDES := include include/sead

View File

@ -10,63 +10,45 @@ Welcome to the official repository for the Super Mario Odyssey Online mod! Have
* Moon Collection is shared between all players
* Custom Configuration Menu (Accessible by holding ZL and selecting any option in the pause/start menu)
* Support for custom gamemodes (WIP)
### Available Gamemodes
* Hide and Seek
## SMO Version Support
## Installation and Usage
For the typical installation along with how to setup and use muliplayer/hide and seek, please visit the [Super Mario Odyssey Online website](https://smoo.it).
* 1.0
<details>
## Installation Tutorial
<summary>Developer build instructions</summary>
Before installing, Ensure that your switch is hacked. If not, follow [This Guide](https://switch.homebrew.guide/) to get your switch setup for modding. Make sure you set up a way to block Nintendo's servers as you will need to have your switch connected to the internet for this mod to work!
### Building Prerequisites
1. Download the latest mod build from either [Gamebanana](https://gamebanana.com/mods/384214) or from the [Releases](https://github.com/CraftyBoss/SuperMarioOdysseyOnline/releases) tab. (Alternatively, build from source)
2. Extract the downloaded zip onto the root of your Switch's SD card.
3. If you need to host an online server, head over to the [Super Mario Odyssey Online Server](https://github.com/Sanae6/SmoOnlineServer) repository and follow the instructions there to set up the server.
4. Launch the game! Upon first time bootup, the mod should ask for a server IP to save to the games common save file. This IP address will be the server you wish to connect to every time you launch the game with the mod installed. (Note: un-installing the mod and launching the game will remove the server IP from the common save file.)
- [devkitPro](https://devkitpro.org/)
- Python 3
- The [Keystone-Engine](https://www.keystone-engine.org/) Python Module
## Gamemode Info
### Hide and Seek
* Depending on Group size, select who will start as seekers at the beginning of each round and a kingdom to hide in.
* Each player has a timer on the top right of the screen that will increase while they are hiding during a round.
* When a seeker gets close enough to a player, the player will die and respawn as a seeker.
* During the round, hiders who die by other means will also become seekers upon respawning.
* If a hider loads into a new stage (via a pipe, door, etc.) the hider will get 5 seconds of tag invincibility to prevent spawn point camping.
* The player with the most time at the end of a round (or set of rounds) is considered the winner.
* While not a concrete rule, it's generally agreed upon that hiding should not be done out of bounds, inside objects that don't sync across games yet, and inside objects that completely conceal a player from others (such as trees).
### Building
## Gamemode Controls
### Hide and Seek
- Left D-Pad: Decrease time
- Right D-Pad: Increase Time
- L + D-Pad Down: Reset Time
- D-Pad Up: Switch from Hider/Seeker
Build has only been tested on WSL2 running Ubuntu 20.04.1.
## Building Prerequisites
Just run:
```
DEVKITPRO={path_to_devkitpro} make
```
- [devkitPro](https://devkitpro.org/)
- Python 3
- The [Keystone-Engine](https://www.keystone-engine.org/) Python Module
On Ubuntu (and other Debian-based systems), devkitPro will be installed to `/opt/devkitpro` by default:
## Building
```
DEVKITPRO=/opt/devkitpro/ make
```
Build has only been tested on WSL2 running Ubuntu 20.04.1.
### Installing (Atmosphère)
Just run:
```
DEVKITPRO={path_to_devkitpro} make
```
After a successful build, simply transfer the `atmosphere` folder located inside `starlight_patch_100` to the root of your switch's SD card.
</details>
On Ubuntu (and other Debian-based systems), devkitPro will be installed to `/opt/devkitpro` by default:
## Troubleshooting
```
DEVKITPRO=/opt/devkitpro/ make
```
## Installing (Atmosphère)
After a successful build, simply transfer the `atmosphere` folder located inside `starlight_patch_100` to the root of your switch's SD card.
The [Super Mario Odyssey Online website](https://smoo.it) has a FAQ section that should solve many issues.
However, for any further questions or help not covered by the site, please visit the [CraftyBoss Community Discord Server](discord.gg/jYCueK2BqD) and ask in the `help`/`help-2` channel.
---

View File

@ -1,10 +1,13 @@
#!/bin/bash
ISEMU=${1:-0}
export DOCKER_BUILDKIT=1
docker build . -t smoo-client-build
docker run --rm \
-u $(id -u):$(id -g) \
-v "/$PWD/":/app/ \
-e ISEMU=${ISEMU} \
smoo-client-build \
;
docker rmi smoo-client-build

View File

@ -33,6 +33,7 @@ class PuppetActor : public al::LiveActor {
virtual void movement(void) override;
virtual void makeActorAlive(void) override;
virtual void makeActorDead(void) override;
virtual void calcAnim(void) override;
virtual void attackSensor(al::HitSensor *, al::HitSensor *) override;
virtual bool receiveMsg(const al::SensorMsg*, al::HitSensor*, al::HitSensor*) override;
@ -92,3 +93,8 @@ class PuppetActor : public al::LiveActor {
float mClosingSpeed = 0;
};
PlayerCostumeInfo* initMarioModelPuppet(al::LiveActor* player, const al::ActorInitInfo& initInfo,
char const* bodyName, char const* capName, int subActorNum,
al::AudioKeeper* audioKeeper);
PlayerHeadCostumeInfo* initMarioHeadCostumeInfo(al::LiveActor* player, const al::ActorInitInfo &initInfo, const char* headModelName, const char* capModelName, const char* headType, const char* headSuffix);

View File

@ -7,6 +7,7 @@
#include "RenderTargetColor.h"
#include "RenderTargetDepth.h"
#include "DrawContext.h"
#include "sead/gfx/seadFrameBuffer.h"

View File

@ -19,6 +19,7 @@
#include "al/sensor/HitSensorKeeper.h"
#include "al/switch/StageSwitchKeeper.h"
#include "al/actor/SubActorKeeper.h"
#include "al/model/ModelKeeper.h"
// vtable for LiveActor: 1C4EB58
@ -31,7 +32,6 @@ namespace al
class ActorScoreKeeper;
class Collider;
class CollisionParts;
class ModelKeeper;
class ShadowKeeper;
class ActorPrePassLightKeeper;
class ActorOcclusionKeeper;
@ -93,11 +93,13 @@ namespace al
virtual al::CameraDirector *getCameraDirector() const { return this->mSceneInfo->mCameraDirector; };
virtual void initStageSwitchKeeper() { this->mStageSwitchKeeper = new StageSwitchKeeper(); };
virtual void control();
virtual void updateCollider();
void initSubActorKeeper(al::SubActorKeeper *);
const char *mActorName; // 0x48
al::ActorPoseKeeperBase *mPoseKeeper; // 0x50
al::ActorExecuteInfo *mLayoutExecuteInfo; // 0x58

View File

@ -1,14 +1,13 @@
#pragma once
#include "al/LiveActor/LiveActor.h"
#include "al/action/ActionEffectCtrl.h"
#include "al/resource/ActorResource.h"
#include "sead/math/seadVector.h"
namespace al
{
class LiveActor;
class ActorResource;
class ActionAnimCtrl;
class NerveActionCtrl;
class ActionFlagCtrl;

View File

@ -6,6 +6,7 @@
#include "al/scene/SceneObjHolder.h"
#include "al/layout/LayoutInitInfo.h"
#include "game/GameData/GameDataHolderBase.h"
#include "al/gfx/GraphicsSystemInfo.h"
namespace al {
@ -19,7 +20,6 @@ namespace al {
struct ScreenCoverCtrl;
struct ShadowDirector;
struct ModelGroup;
struct GraphicsSystemInfo;
struct PlayerHolder;
struct ModelDrawBufferCounter;

View File

@ -1,7 +1,8 @@
#pragma once
#include "al/actor/ActorInitInfo.h"
#include "container/seadPtrArray.h"
namespace al {
struct SubActorInfo {
struct LiveActor* mActor;
@ -10,6 +11,13 @@ namespace al {
};
class SubActorKeeper {
public:
SubActorKeeper(al::LiveActor*);
static SubActorKeeper *tryCreate(al::LiveActor*, char const*, int);
static SubActorKeeper *create(al::LiveActor*);
void registerSubActor(al::LiveActor*, unsigned int);
void init(al::ActorInitInfo const&, char const*, int);
al::LiveActor* mRootActor;
sead::PtrArray<SubActorInfo> mArray;
};

View File

@ -31,9 +31,9 @@ class ChangeStageInfo {
sead::FixedSafeString<0x80> changeStageId; // 0x0 (Size: 0x98)
sead::FixedSafeString<0x80> changeStageName; // 0xA0
sead::FixedSafeString<0x80> placementString; // 0x138
sead::FixedSafeString<0x80> placementString; // 0x130
bool isReturn; // 0x1C8
int scenarioNo; // 0x1CC or 0x134
int scenarioNo; // 0x1CC
SubScenarioType subType; // 0x1D0
sead::FixedSafeString<0x80> wipeType; // 0x1D8
int hintPriority; // 0x270

View File

@ -1,8 +1,48 @@
#pragma once
#include "al/async/FunctorBase.h"
#include "IUseExecutor.h"
#include "ExecuteSystemInitInfo.h"
#include "ExecuteRequestKeeper.h"
#include "ExecuteTableHolderDraw.h"
#include "ExecuteTableHolderUpdate.h"
#include "container/seadPtrArray.h"
#include "container/seadBuffer.h"
namespace al
{
class LiveActor;
class LayoutActor;
class ExecuteDirector {
public:
public:
ExecuteDirector(int);
virtual ~ExecuteDirector();
void init(al::ExecuteSystemInitInfo const&);
void registerActorUpdate(al::LiveActor*, char const*);
void registerActorDraw(al::LiveActor*, char const*);
void registerActorModelDraw(al::LiveActor*, char const*);
void registerLayoutUpdate(al::LayoutActor*, char const*);
void registerLayoutDraw(al::LayoutActor*, char const*);
void registerUser(al::IUseExecutor*, char const*);
void registerFunctor(al::FunctorBase const&, char const*);
void registerFunctorDraw(al::FunctorBase const&, char const*);
void createExecutorListTable();
void execute(char const*) const;
void executeList(char const*, char const*) const;
void draw(char const*) const;
void drawList(char const*, char const*) const;
void isActiveDraw(char const*) const;
int mRequestMax; // 0x8
int mUpdateTableCount;
al::ExecuteTableHolderUpdate **mUpdateTables;
int mDrawTableCount;
al::ExecuteTableHolderDraw **mDrawTables;
al::ExecuteRequestKeeper *mRequestKeeper;
};
} // namespace al

View File

@ -0,0 +1,11 @@
#pragma once
namespace al {
struct ExecuteOrder
{
const char *mListName;
const char *mExecuteGroup;
int mListMaxSize;
const char *mGroupType;
};
}

View File

@ -0,0 +1,25 @@
#pragma once
#include "types.h"
namespace al {
struct LiveActor;
}
namespace al {
class ExecuteRequestKeeper {
public:
ExecuteRequestKeeper(int);
void executeRequestActorMovementAllOn();
void executeRequestActorMovementAllOff();
void executeRequestActorDrawAllOn();
void executeRequestActorDrawAllOff();
void request(al::LiveActor*, int);
void *mActorMovementAllOn; // 0x0
void *mActorMovementAllOff; // 0x8
void *mActorDrawAllOn; // 0x10
void *mActorDrawAllOff; // 0x18
};
}

View File

@ -0,0 +1,9 @@
#pragma once
#include "agl/DrawContext.h"
namespace al {
struct ExecuteSystemInitInfo {
agl::DrawContext *mDrawCtx;
};
}

View File

@ -0,0 +1,12 @@
#pragma once
#include "ExecuteOrder.h"
namespace al {
struct ExecuteTable
{
const char *mName;
const al::ExecuteOrder* mExecuteOrders;
int mExecuteOrderCount;
};
}

View File

@ -0,0 +1,65 @@
#pragma once
#include <cstring>
#include <string_view>
#include "ExecuteOrder.h"
#include "al/async/FunctorBase.h"
#include "al/execute/ExecuteTable.h"
#include "al/execute/ExecutorListBase.h"
#include "al/execute/IUseExecutor.h"
#include "container/seadPtrArray.h"
#include "types.h"
namespace al {
struct ExecuteSystemInitInfo;
struct ExecutorListActorModelDrawBase;
struct ExecutorListActorDraw;
struct ExecutorListLayoutDrawBase;
struct ExecutorListIUseExecutorDraw;
struct ExecutorListFunctor;
struct ExecutorListBase;
struct LiveActor;
struct LayoutActor;
}
namespace al {
class ExecuteTableHolderDraw {
public:
ExecuteTableHolderDraw();
virtual ~ExecuteTableHolderDraw();
void init(char const*, al::ExecuteSystemInitInfo const&, al::ExecuteOrder const*, int);
void registerExecutorListActorModel(al::ExecutorListActorModelDrawBase*);
void registerExecutorListActor(al::ExecutorListActorDraw*);
void registerExecutorListLayout(al::ExecutorListLayoutDrawBase*);
void registerExecutorListUser(al::ExecutorListIUseExecutorDraw*);
void registerExecutorListFunctor(al::ExecutorListFunctor*);
void registerExecutorListAll(al::ExecutorListBase*);
void tryRegisterActor(al::LiveActor*, char const*);
void tryRegisterActorModel(al::LiveActor*, char const*);
void tryRegisterLayout(al::LayoutActor*, char const*);
void tryRegisterUser(al::IUseExecutor*, char const*);
void tryRegisterFunctor(al::FunctorBase const&, char const*);
void createExecutorListTable();
void execute() const;
void executeList(char const*) const;
bool isActive() const;
const char* mName;
sead::PtrArray<al::ExecutorListBase> mActiveExecutors;
sead::PtrArray<al::ExecutorListBase> mExecutorsAll;
sead::PtrArray<al::ExecutorListActorDraw> mExecutorsActor;
sead::PtrArray<al::ExecutorListActorModelDrawBase> mExecutorsActorModel;
sead::PtrArray<al::ExecutorListLayoutDrawBase> mExecutorsLayout;
sead::PtrArray<al::ExecutorListIUseExecutorDraw> mExecutorsUser;
sead::PtrArray<al::ExecutorListFunctor> mExecutorsFunctor;
};
}
extern "C" al::ExecuteTable gameDrawTable[]; // pointer to original draw table found in the exefs
extern const al::ExecuteTable drawTable[];
extern int drawTableSize;

View File

@ -0,0 +1,58 @@
#pragma once
#include "ExecuteOrder.h"
#include "al/async/FunctorBase.h"
#include "al/execute/ExecuteTable.h"
#include "al/execute/ExecutorListBase.h"
#include "al/execute/IUseExecutor.h"
#include "ExecuteSystemInitInfo.h"
#include "container/seadPtrArray.h"
#include "types.h"
namespace al {
struct ExecutorListActorExecuteBase;
struct ExecutorListLayoutUpdate;
struct ExecutorListIUseExecutorUpdate;
struct ExecutorListFunctor;
struct ExecutorListBase;
struct LiveActor;
struct LayoutActor;
}
namespace al {
class ExecuteTableHolderUpdate {
public:
ExecuteTableHolderUpdate();
virtual ~ExecuteTableHolderUpdate();
void init(char const*, al::ExecuteSystemInitInfo const&, al::ExecuteOrder const*, int);
void registerExecutorListActor(al::ExecutorListActorExecuteBase*);
void registerExecutorListLayout(al::ExecutorListLayoutUpdate*);
void registerExecutorListUser(al::ExecutorListIUseExecutorUpdate*);
void registerExecutorListFunctor(al::ExecutorListFunctor*);
void registerExecutorListAll(al::ExecutorListBase*);
void tryRegisterActor(al::LiveActor*, char const*);
void tryRegisterLayout(al::LayoutActor*, char const*);
void tryRegisterUser(al::IUseExecutor*, char const*);
void tryRegisterFunctor(al::FunctorBase const&, char const*);
void createExecutorListTable();
void execute() const;
void executeList(char const*) const;
const char *mName;
sead::PtrArray<al::ExecutorListBase> mActiveExecutors;
sead::PtrArray<al::ExecutorListBase> mExecutorsAll;
sead::PtrArray<al::ExecutorListActorExecuteBase> mExecutorsActor;
sead::PtrArray<al::ExecutorListLayoutUpdate> mExecutorsLayout;
sead::PtrArray<al::ExecutorListIUseExecutorUpdate> mExecutorsUser;
sead::PtrArray<al::ExecutorListFunctor> mExecutorsFunctor;
};
} // namespace al
extern "C" al::ExecuteTable gameUpdateTable[]; // pointer to original update table found in the exefs
extern const al::ExecuteTable updateTable[];
extern int updateTableSize;

View File

@ -0,0 +1,15 @@
#pragma once
#include "types.h"
namespace al {
class ExecutorListBase {
public:
ExecutorListBase(char const*);
virtual ~ExecutorListBase();
virtual void executeList() const;
virtual bool isActive() const;
const char *mName;
};
}

View File

@ -0,0 +1,193 @@
#pragma once
#include "al/execute/ExecuteDirector.h"
#include "al/model/ModelMaterialCategory.h"
#include "al/resource/Resource.h"
#include "container/seadPtrArray.h"
#include "gfx/seadCamera.h"
#include "UniformBlock.h"
#include "types.h"
namespace al {
struct GraphicsInitArg;
struct GraphicsUpdateInfo;
struct GraphicsCalcGpuInfo;
struct PartsGraphics;
struct GraphicsRenderInfo;
struct GraphicsCopyInfo;
struct GraphicsComputeInfo;
struct AreaObjDirector;
struct EffectSystem;
struct SceneCameraInfo;
struct ShaderHolder;
struct GBufferArray;
struct Projection;
struct RenderVariables;
struct ShaderCubeMapKeeper;
struct ShaderMirrorDirector;
struct SubCameraRenderer;
struct GraphicsParamFilePath;
struct PlayerHolder;
}
namespace agl {
struct DrawContext;
namespace utl {
struct ParameterOfBool { char size[0x20]; };
struct ParameterOfInt { char size[0x20]; };
struct ParameterOfFloat { char size[0x20]; };
struct IParameterObj { char size[0x30]; };
struct IParameterIO { char size[0x1D0]; };
}
}
namespace al {
class GraphicsSystemInfo {
public:
GraphicsSystemInfo();
~GraphicsSystemInfo();
void getModelEnv() const;
void getDrawContext() const;
void getShaderCubeMapKeeper() const;
void getViewIndexedUboArray(char const*) const;
void setViewIndexedUboArray(char const*, sead::PtrArray<al::UniformBlock> const*);
void initAtmosScatter(al::ExecuteDirector*);
void init(al::GraphicsInitArg const&, al::AreaObjDirector*, al::ExecuteDirector*, al::EffectSystem*, al::PlayerHolder*, al::SceneCameraInfo*, al::ShaderHolder*);
void initProjectResource();
void initStageResource(al::Resource const*, char const*, char const*);
void endInit();
void initAfterPlacement();
void initAfterCreateDrawTable();
void setDrawEnv(int, al::GBufferArray*, sead::Camera const*, al::Projection const*);
void clearGraphicsRequest();
void cancelLerp();
void updateGraphics();
void updatePartsGraphics(al::GraphicsUpdateInfo const&);
void preDrawGraphics(al::SceneCameraInfo const*);
void calcGpuPartsGraphics(al::GraphicsCalcGpuInfo const&);
void updateViewGpu(int, sead::Camera const*, al::Projection const*);
void updateViewVolume(sead::Matrix34f const&, sead::Matrix44<float> const&);
void clearViewVolume();
void tryGetAtmosLightDir(sead::Vector3f*) const;
void tryDirectionalLightInfo(sead::Vector3f*) const;
void activateDirLitColorTex() const;
void activateDirLitColorTex(agl::DrawContext*) const;
void registPartsGraphics(al::PartsGraphics*);
void drawSystemPartsGraphics(al::GraphicsRenderInfo const*) const;
void doPartsGraphicsCommandBufferCopy(al::GraphicsCopyInfo const&) const;
void doPartsGraphicsCompute(al::GraphicsComputeInfo const&) const;
void drawPartsGraphics(al::GraphicsRenderInfo const&, al::RenderVariables const&) const;
void drawPartsGraphicsGBufferAfterSky(al::GraphicsRenderInfo const&) const;
void drawPartsGraphicsDeferred(al::GraphicsRenderInfo const&) const;
void drawPartsGraphicsLdr(al::GraphicsRenderInfo const&) const;
void drawPartsGraphicsIndirect(al::GraphicsRenderInfo const&, al::RenderVariables const&) const;
void drawPartsGraphicsCubemap(al::GraphicsRenderInfo const&) const;
void *qword0;
void *qword8;
void *qword10;
void *qword18;
char gap20[5];
char byte25;
u16 word26;
int dword28;
int dword2C;
int dword30;
int dword34;
int dword38;
int dword3C;
char byte40;
int dword44;
char byte48;
int dword4C;
int dword50;
int dword54;
int dword58;
int dword5C;
void *qword60;
char char68;
al::ShaderCubeMapKeeper **field_70;
char gap78[56];
al::ShadowDirector *field_B0;
char gapB8[16];
al::ShaderMirrorDirector *field_C8;
char gapD0[320];
char char210;
void *qword218;
void *qword220;
void *qword228;
void *qword230;
al::MaterialCategoryKeeper *mMaterialCategoryKeeper;
void *qword240;
void *qword248;
void *qword250;
void *qword258;
void *qword260;
void *qword268;
void *qword270;
void *qword278;
void *qword280;
al::GpuMemAllocator *field_288;
char gap290[8];
void *qword298;
void *qword2A0;
char gap2A8[8];
void *qword2B0;
al::SubCameraRenderer *field_2B8;
void *qword2C0;
void *qword2C8;
void *qword2D0;
void *qword2D8;
void *qword2E0;
void *qword2E8;
int dword2F0;
__attribute__((packed)) __attribute__((aligned(1))) void *qword2F4;
__attribute__((packed)) __attribute__((aligned(1))) void *qword2FC;
__attribute__((packed)) __attribute__((aligned(1))) void *qword304;
int dword30C;
al::GraphicsParamFilePath *mParamFilePath;
agl::utl::IParameterIO agl__utl__iparameterio318;
agl::utl::IParameterObj agl__utl__iparameterobj4E8;
agl::utl::ParameterOfInt field_518;
agl::utl::ParameterOfInt field_538;
agl::utl::ParameterOfBool field_558;
agl::utl::ParameterOfBool field_578;
agl::utl::ParameterOfInt field_598;
agl::utl::IParameterIO field_5B8;
agl::utl::IParameterObj field_788;
agl::utl::ParameterOfBool field_7B8;
agl::utl::ParameterOfBool field_7D8;
agl::utl::ParameterOfBool field_7F8;
agl::utl::ParameterOfFloat field_818;
agl::utl::ParameterOfFloat field_838;
agl::utl::ParameterOfFloat field_858;
agl::utl::ParameterOfFloat field_878;
agl::utl::ParameterOfFloat field_898;
agl::utl::ParameterOfFloat field_8B8;
agl::utl::ParameterOfFloat field_8D8;
agl::utl::ParameterOfFloat field_8F8;
void *qword918;
void *qword920;
void *qword928;
void *qword930;
void *qword938;
void *qword940;
void *qword948;
void *qword950;
void *qword958;
int dword960;
void *qword968;
void *qword970;
int dword978;
void *qword980;
al::ModelOcclusionCullingDirector *field_988;
void *qword990;
al::ModelShaderHolder *field_998;
al::PrepassTriangleCulling *field_9A0;
char byte9A8;
void *field_9B0;
};
}

View File

@ -0,0 +1,12 @@
#pragma once
#include "types.h"
namespace al {
class UniformBlock {
UniformBlock();
~UniformBlock();
void swap();
};
}

View File

@ -0,0 +1,107 @@
#pragma once
#include "agl/DisplayList.h"
#include "al/resource/Resource.h"
#include "math/seadMatrix.h"
#include "nn/g3d/ResModel.h"
namespace al {
struct ShaderHolder;
struct ModelShaderHolder;
struct ModelOcclusionCullingDirector;
struct ShadowDirector;
struct PrepassTriangleCulling;
struct ModelLodCtrl;
struct DitherAnimator;
struct ModelMaterialCategory;
struct GpuMemAllocator;
}
namespace nn { namespace g3d {
struct Sphere;
}}
namespace al {
class ModelCtrl {
public:
ModelCtrl();
~ModelCtrl();
void initialize(nn::g3d::ResModel*, int, int, sead::Heap*, al::ShaderHolder*);
void tryBindShader();
void tryUpdateModelAdditionalInfoUbo(int);
void updateWorldMatrix(sead::Matrix34f const&, sead::Vector3f const&);
void updateGpuBuffer(int);
void calcBounding();
void getLodLevel() const;
void getLodLevelDepthShadow() const;
void calcBoundingLod(int);
void updateQueryBox();
void updateModelDrawBuffer(int);
void updateGpuBufferAll();
void isShapeVisible(int) const;
void setCubeMapIndexAllShape(int);
void recreateDisplayList();
void setMaterialProgrammable(int, bool);
void isMaterialProgrammable(int);
void setSkeletonUpdateInfo(bool, sead::Matrix34f const&, sead::Vector3f const&);
void setDirtyTexture();
void onZPrePass();
void offZPrePass();
void getEnvTexInfo(int) const;
void requestModelAdditionalInfoUbo();
void setLodCtrl(al::ModelLodCtrl*);
void getLodLevelMax() const;
void getLodLevelMaterial() const;
void getLodLevelNoClamp() const;
void setLodLevelForce(int);
void updateLodCtrl();
void setDitherAnimator(al::DitherAnimator*);
void updateDitherAnimator();
void checkChangeDisplayList();
void addToDrawerCulling();
void removeFromDrawerCulling();
void updateSubMesh();
void setModelMaterialCategory(al::ModelMaterialCategory const*);
void setModelAlphaMask(float);
void setModelUvOffset(sead::Vector2f const&);
void setModelProjMtx0(sead::Matrix44<float> const&);
void setModelProjMtx1(sead::Matrix44<float> const&);
void setModelProjMtx2(sead::Matrix44<float> const&);
void setModelProgProjMtx0(sead::Matrix44<float> const&);
void setModelProgProjMtx1(sead::Matrix44<float> const&);
void setModelProgProjMtx2(sead::Matrix44<float> const&);
void setModelProgProjMtx3(sead::Matrix44<float> const&);
void setModelProgConstant0(float);
void setModelProgConstant1(float);
void setModelProgConstant2(float);
void setModelProgConstant3(float);
void setModelProgConstant4(float);
void setModelProgConstant5(float);
void setModelProgConstant6(float);
void setModelProgConstant7(float);
void setNormalAxisXScale(float);
void calcCameraToBoundingSphereDistance() const;
void isUseLocalShadowMap() const;
void validateOcclusionQuery();
void invalidateOcclusionQuery();
void isValidOcclusionQuery() const;
void createUniqShader();
void isCreateUniqShader(int);
void getUniqModelShader(int);
void getUniqModelShaderAssgin(int);
void pushDisplayListModel(agl::DisplayList*);
void pushDisplayListShape(agl::DisplayList*, int);
void getModelShapeCtrl(int) const;
void initResource(al::Resource*, al::Resource*);
void initModel(al::GpuMemAllocator*, al::ModelShaderHolder*, al::ModelOcclusionCullingDirector*, al::ShadowDirector*, al::PrepassTriangleCulling*, int, int);
void tryCreateCulledIndexBuffer();
void show();
void hide();
void calc(sead::Matrix34f const&, sead::Vector3f const&);
void calcView();
void calcModelObjBoundingWithOffset(nn::g3d::Sphere*) const;
void setCameraInfo(sead::Matrix34f const*, sead::Matrix34f const*, sead::Matrix44<float> const*, sead::Matrix44<float> const*);
void getShapeObj(int) const;
};
}

View File

@ -0,0 +1,46 @@
#pragma once
#include "al/resource/ActorResource.h"
#include "math/seadMatrix.h"
#include "types.h"
#include "ModelCtrl.h"
namespace al {
struct ModelLodCtrl;
struct DitherAnimator;
struct GpuMemAllocator;
struct ModelShaderHolder;
struct ModelOcclusionCullingDirector;
struct ShadowDirector;
struct PrepassTriangleCulling;
}
namespace al {
class ModelKeeper {
public:
ModelKeeper();
virtual ~ModelKeeper();
void initResource(al::ActorResource const*);
void createMatAnimForProgram(int);
void getAnimResource() const;
void getModelResource() const;
void setDisplayRootJointMtxPtr(sead::Matrix34f const*);
void setModelLodCtrl(al::ModelLodCtrl*);
void setDitherAnimator(al::DitherAnimator*);
void initModel(int, al::GpuMemAllocator*, al::ModelShaderHolder*, al::ModelOcclusionCullingDirector*, al::ShadowDirector*, al::PrepassTriangleCulling*);
void show();
void hide();
void update();
void updateLast();
void calc(sead::Matrix34f const&, sead::Vector3f const&);
void getBaseMtx() const;
void getWorldMtxPtrByIndex(int) const;
const char *mResourceName;
al::ModelCtrl *mModelCtrl;
const al::ActorResource *mResource;
char gap20[67];
bool field_63;
};
}

View File

@ -0,0 +1,19 @@
#pragma once
#include "ModelCtrl.h"
#include "al/byaml/ByamlIter.h"
namespace al {
struct MaterialCategoryKeeper;
class ModelMaterialCategory {
public:
ModelMaterialCategory(al::ModelCtrl*, al::MaterialCategoryKeeper*);
void init(char const*);
void init(al::ByamlIter const&);
void getCategoryIdFromMaterialName(char const*) const;
void getCategoryIdFromMaterialIndex(int) const;
static void tryCreate(al::ModelCtrl*, al::Resource const*, char const*, al::MaterialCategoryKeeper*);
static void tryCreate(al::ModelCtrl*, char const*, al::MaterialCategoryKeeper*);
};
}

View File

@ -0,0 +1,42 @@
#pragma once
#include "al/LiveActor/LiveActor.h"
#include "types.h"
namespace al {
class PartsModel : public al::LiveActor {
public:
PartsModel(char const*);
void endClipped() override;
void calcAnim() override;
void attackSensor(al::HitSensor*, al::HitSensor*) override;
bool receiveMsg(al::SensorMsg const*, al::HitSensor*, al::HitSensor*) override;
void initPartsDirect(al::LiveActor*, al::ActorInitInfo const&, char const*, sead::Matrix34f const*, sead::Vector3f const&, sead::Vector3f const&, sead::Vector3f const&, bool);
void initPartsSuffix(al::LiveActor*, al::ActorInitInfo const&, char const*, char const*, sead::Matrix34f const*, bool);
void initPartsMtx(al::LiveActor*, al::ActorInitInfo const&, char const*, sead::Matrix34f const*, bool);
void initPartsFixFile(al::LiveActor*, al::ActorInitInfo const&, char const*, char const*, char const*);
void initPartsFixFileNoRegister(al::LiveActor*, al::ActorInitInfo const&, char const*,
char const*, char const*);
void updatePose();
void offSyncAppearAndHide();
void onSyncAppearAndHide();
void *unkPtr1; // 0x108
void* unkPtr2; // 0x110
int unkInt1; // 0x118
int unkInt2; // 0x11C
int unkInt3; // 0x120
int unkInt4; // 0x124
int unkInt5; // 0x128
int unkInt6; // 0x12C
int unkInt7; // 0x130
float unkFloat1; // 0x134
float unkFloat2; // 0x138
float unkFloat3; // 0x13C
bool unkBool; // 0x140
bool unkBool2; // 0x141
bool unkBool3; // 0x142
};
}

View File

@ -0,0 +1,35 @@
#pragma once
#include "prim/seadSafeString.h"
#include "types.h"
#include "Resource.h"
namespace al {
class AnimInfoTable { char size[0x18]; };
struct InitResourceDataAnim {
al::AnimInfoTable *mInfoTable; // 0x0
al::AnimInfoTable *mFclAnim; // 0x8
al::AnimInfoTable *mFtsAnim; // 0x10
al::AnimInfoTable *mFtpAnim; // 0x18
al::AnimInfoTable *mInfoTable2; // 0x18
};
class ActorResource {
public:
ActorResource(sead::SafeString const&, al::Resource*, al::Resource*);
virtual ~ActorResource();
void initResourceData(char const*, bool);
sead::FixedSafeString<0x80> unkStr; // 0x8
al::Resource *mResourceModel; // 0xA0
al::Resource *mResourceAnim; // 0xA8
bool unkBool1; // 0xB0
al::InitResourceDataAnim *mAnimResData; // 0xB8
void *unkPtr2; // 0xC0
};
}
static_assert(sizeof(al::ActorResource) == 0xC8, "ActorResource Size");

View File

@ -0,0 +1,20 @@
#pragma once
#include "Resource.h"
#include "types.h"
namespace al {
class ActorResourceHolder {
ActorResourceHolder(int);
~ActorResourceHolder();
void tryFindActorResource(sead::SafeString const&);
void findActorResourceImpl(sead::SafeString const&);
void createActorResource(sead::SafeString const&, al::Resource*, al::Resource*);
void removeAll();
void eraseResourceUser(al::Resource*);
void freeErasedActorResource();
};
}

View File

@ -0,0 +1,48 @@
#pragma once
#include <heap/seadHeap.h>
#include <prim/seadSafeString.h>
#include <resource/seadArchiveRes.h>
#include <filedevice/seadArchiveFileDevice.h>
#include "nn/g3d/g3d_ResFile.h"
namespace al {
class Resource {
public:
Resource(sead::SafeString const&);
Resource(sead::SafeString const&, sead::ArchiveRes*);
bool isExistFile(sead::SafeString const&) const;
bool isExistByml(char const*) const;
int getSize() const;
int getEntryNum(sead::SafeString const&) const;
const char *getEntryName(sead::BufferedSafeString*, sead::SafeString const&, unsigned int) const;
void getFileSize(sead::SafeString const&) const;
void getByml(sead::SafeString const&) const;
void getFile(sead::SafeString const&) const;
void tryGetByml(sead::SafeString const&) const;
void getKcl(sead::SafeString const&) const;
void tryGetKcl(sead::SafeString const&) const;
void getPa(sead::SafeString const&) const;
void tryGetPa(sead::SafeString const&) const;
void getOtherFile(sead::SafeString const&) const;
const char* getArchiveName() const;
bool tryCreateResGraphicsFile(sead::SafeString const&, nn::g3d::ResFile*);
void cleanupResGraphicsFile();
sead::ArchiveRes* mArc; // 0x0
sead::ArchiveFileDevice *mFileDevice; // 0x8
sead::FixedSafeString<0x80> mArcName; // 0x10
sead::Heap* mCurrentHeap; // 0xA8
void *unkPtr; // 0xB0
nn::g3d::ResFile *mResGfxFile; // 0xB8
};
} // namespace al
static_assert(sizeof(al::Resource) == 0xC0, "al::Resource Size");

View File

@ -5,11 +5,19 @@
#include "al/audio/AudioKeeper.h"
#include "al/camera/CameraDirector.h"
#include "al/scene/SceneObjHolder.h"
#include "prim/seadSafeString.h"
namespace al
{
class GraphicsInitArg;
class StageResourceKeeper;
class LiveActorKit;
class LayoutKit;
class SceneStopCtrl;
class SceneMsgCtrl;
class ScreenCoverCtrl;
class AudioDirector;
class Scene : public al::NerveExecutor, public al::IUseAudioKeeper, public al::IUseCamera, public al::IUseSceneObjHolder
{
@ -32,6 +40,17 @@ namespace al
void initLiveActorKitWithGraphics(al::GraphicsInitArg const &, al::SceneInitInfo const &, int, int, int);
unsigned char _28[0xD8-0x28];
bool mIsAlive;
sead::FixedSafeString<0x40> mName;
al::StageResourceKeeper *mStageResourceKeeper;
al::LiveActorKit *mActorKit;
al::LayoutKit *mLayoutKit;
al::SceneObjHolder *mSceneObjHolder;
al::SceneStopCtrl *mSceneStopCtrl;
al::SceneMsgCtrl *mSceneMsgCtrl;
al::ScreenCoverCtrl *mScreenCoverCtrl;
al::AudioDirector *mAudioDirector;
al::AudioKeeper *mAudioKeeper;
al::NerveKeeper *mNerveKeeper;
};
};

View File

@ -8,6 +8,6 @@ namespace al
{
public:
virtual al::SceneCreator* getSceneCreator() const = 0;
virtual al::SceneCreator* setSceneCreator() const = 0;
virtual void setSceneCreator(al::SceneCreator* ) = 0;
};
};

View File

@ -1,12 +1,61 @@
#pragma once
#include "al/audio/AudioDirector.h"
#include "al/nerve/NerveExecutor.h"
#include "al/audio/AudioKeeper.h"
#include "al/scene/SceneCreator.h"
#include "game/System/GameDrawInfo.h"
namespace al {
class GameSystemInfo;
class SequenceInitInfo;
class AudioSystemInfo;
class Scene;
class Sequence : public al::NerveExecutor, public al::IUseAudioKeeper, public al::IUseSceneCreator {
public:
Sequence(const char *seqName);
Sequence(const char* name);
virtual ~Sequence() override;
virtual void init(const al::SequenceInitInfo& initInfo);
virtual void update();
virtual void kill();
virtual void drawMain() const;
virtual void drawSub() const;
virtual bool isDisposable() { return false; }
al::Scene* getCurrentScene() const;
al::SceneCreator* getSceneCreator() const override;
void setSceneCreator(al::SceneCreator* sceneCreator) override;
al::AudioKeeper* getAudioKeeper() const override;
void initAudio(const al::GameSystemInfo&, const char*, int, int, int, const char*);
void initAudioKeeper(const char*);
void initDrawSystemInfo(const al::SequenceInitInfo&);
al::AudioSystemInfo* getAudioSystemInfo();
al::GameDrawInfo* getDrawInfo() const {
return mGameDrawInfo;
}
al::AudioDirector* getAudioDirector() const {
return mAudioDirector;
}
void setNextScene(al::Scene* scene) {
mNextScene = scene;
}
const sead::SafeString& getName() const {
return mName;
}
const sead::FixedSafeString<0x40> mName;
al::Scene* mNextScene;
al::Scene* mCurrentScene;
al::SceneCreator* mSceneCreator;
al::AudioDirector* mAudioDirector;
al::AudioKeeper* mAudioKeeper;
al::GameDrawInfo* mGameDrawInfo;
bool mIsAlive;
};
}

View File

@ -10,6 +10,7 @@
#include "al/util/MathUtil.h"
#include "al/util/NerveUtil.h"
#include "al/util/CameraUtil.h"
#include "al/util/KitUtil.h"
namespace al
{

17
include/al/util/KitUtil.h Normal file
View File

@ -0,0 +1,17 @@
#pragma once
#include "al/scene/Scene.h"
namespace al {
class LayoutKit;
class LiveActorKit;
void updateKitList(al::Scene *,char const*,char const*);
void updateKitList(al::Scene*, char const*);
void executeUpdateList(al::LayoutKit *,char const*,char const*);
void executeUpdateList(al::LiveActorKit*, char const*, char const*);
void executeDrawList(al::LiveActorKit const*,char const*,char const*);
}

View File

@ -26,6 +26,9 @@ namespace al {
void onSyncClippingSubActor(LiveActor*, const LiveActor*);
void onSyncHideSubActor(LiveActor*, const LiveActor*);
void onSyncAlphaMaskSubActor(LiveActor*, const LiveActor*);
void onSyncAppearSubActor(al::LiveActor *,al::LiveActor const*);
void onSyncAppearSubActor(al::LiveActor *,char const*);
void onSyncAppearSubActorAll(al::LiveActor *);
void setMaterialProgrammable(LiveActor*);
void startAction(LiveActor*, char const*);
void startAction(IUseLayoutAction*, const char *, const char *);
@ -41,6 +44,8 @@ namespace al {
void turnToTarget(LiveActor*, const al::LiveActor *, float);
void expandClippingRadiusByShadowLength(LiveActor *,sead::Vector3f *, float);
void addPartialSklAnimPartsListRecursive(al::LiveActor*, char const*, int);
void setMaterialProgrammable(al::LiveActor *);
void initJointLocalXRotator(const LiveActor *,const float *,const char *);
void initJointLocalYRotator(const LiveActor *,const float *,const char *);
@ -56,7 +61,23 @@ namespace al {
void initActorPoseTQGSV(al::LiveActor *);
void initActorPoseTQGMSV(al::LiveActor *);
void initActorPoseT(al::LiveActor *,sead::Vector3<float> const&);
void initActorPoseTR(al::LiveActor *,sead::Vector3<float> const&,sead::Vector3<float> const&);
void initActorPoseTR(al::LiveActor*, sead::Vector3<float> const&, sead::Vector3<float> const&);
void initActorSRT(al::LiveActor*, al::ActorInitInfo const&);
void initActorSceneInfo(al::LiveActor *, al::ActorInitInfo const&);
void initActorModelKeeper(al::LiveActor *,al::ActorInitInfo const&,al::ActorResource const*,int);
void initActorModelKeeper(al::LiveActor*, al::ActorInitInfo const&, char const*, int,
char const*);
void initActorEffectKeeper(al::LiveActor*, al::ActorInitInfo const&, char const*);
void initActorActionKeeper(al::LiveActor *,al::ActorInitInfo const&,char const*,char const*);
void initActorActionKeeper(al::LiveActor*, al::ActorResource const*, char const*, char const*);
void initActorClipping(al::LiveActor *,al::ActorInitInfo const&);
void initPartialSklAnim(al::LiveActor*, int, int, int);
bool tryGetActorInitFileIterAndName(al::ByamlIter *,sead::BufferedSafeStringBase<char> *,al::Resource const*,char const*,char const*);
bool tryGetActorInitFileIter(al::ByamlIter *,al::Resource const*,char const*,char const*);
bool tryGetActorInitFileIterAndName(al::ByamlIter *,sead::BufferedSafeStringBase<char> *,al::LiveActor const*,char const*,char const*);
bool tryGetActorInitFileIter(al::ByamlIter *,al::LiveActor const*,char const*,char const*);
void initLayoutPartsActor(LayoutActor*, LayoutActor*, const LayoutInitInfo&, char const*,
char const*);

View File

@ -0,0 +1,17 @@
#pragma once
#include "al/LiveActor/LiveActor.h"
#include "al/resource/ActorResourceHolder.h"
#include "al/resource/ActorResource.h"
namespace al {
al::ActorResource *findOrCreateActorResource(al::ActorResourceHolder *,char const*,char const*);
al::ActorResource* findOrCreateActorResourceWithAnimResource(al::ActorResourceHolder*,
char const*, char const*,
char const*, bool);
al::Resource *getModelResource(al::LiveActor const*);
al::Resource *getModelResourceYaml(al::LiveActor const*,char const*,char const*);
}

View File

@ -51,7 +51,7 @@ class Shine : public al::LiveActor , public IUseDimension {
QuestInfo *shineQuestInfo; // 0x278
void *unkPtr1; // 0x280
ActorDimensionKeeper *mDimensionKeeper; // 0x288
int shineId; // 0x290
int mShineIdx; // 0x290
bool mIsMainShine;
void *qword298;
void *qword2A0;

View File

@ -7,6 +7,7 @@
#include "al/scene/SceneObjHolder.h"
#include "container/seadPtrArray.h"
#include "prim/seadSafeString.h"
#include "types.h"
#include "UniqueObjInfo.h"
#include "GameProgressData.h"
@ -43,7 +44,48 @@ class ShineInfo;
class GameDataFile
{
public:
GameDataFile(GameDataHolder *);
GameDataFile(GameDataHolder*);
struct HintInfo {
void clear(void);
bool isDisableByWorldWarpHole(bool) const;
bool isEnableUnlock(int, bool, int, bool) const;
bool isHintStatusUnlock(int, int, bool) const;
bool isHintStatusUnlockByNpc(void) const;
bool isHintStatusUnlockByAmiibo(void) const;
bool isEnableNameUnlockByScenario(int, int, bool) const;
sead::FixedSafeString<0x80> mStageName; // 0x0
sead::FixedSafeString<0x80> mObjId; // 0x98
sead::FixedSafeString<0x40> mScenarioName; // 0x130
const char *mObjectName; // 0x188
sead::Vector3f mTrans; // 0x190
sead::Vector3f mTransAgain; // 0x19C
void *unkPtr1; // 0x1A8
void *unkPtr2; // 0x1B0
void *unkPtr3; // 0x1B8
void *unkPtr4; // 0x1C0
s32 mMainScenarioNo; // 0x1C8
int mWorldIndex; // 0x1CC
bool mIsMoonRock; // 0x1D0
bool unkBool1; // 0x1D1
bool mIsAchievement; // 0x1D2
bool mIsGrand; // 0x1D3
bool mIsShopMoon; // 0x1D4
int unkInt; // 0x1D8
int unkInt2; // 0x1DC
void *unkPtr6; // 0x1E0
void *unkPtr7; // 0x1E8
int mUniqueID; // 0x1F0
int mHintIdx; // 0x1F4
sead::FixedSafeString<0x20> mOptionalID; // 0x1F8
uint mProcessBitflag; // 0x230
bool unkBool2; // 0x234
bool unkBool3; // 0x235
};
static_assert(sizeof(HintInfo) == 0x238, "size of HintInfo");
void initializeData(void);
void tryReadByamlData(uchar const*);
void tryFindCoinCollectInfo(char const*,char const*);
@ -151,7 +193,7 @@ class GameDataFile
void wearCostume(char const*);
void wearCap(char const*);
void addHackDictionary(char const*);
void findShine(int,int);
HintInfo* findShine(int worldIndex, int shineIndex);
void calcShineNumInOneShine(int,int);
void checkAchievementShine(int,int);
void winRace(void);
@ -195,7 +237,7 @@ class GameDataFile
void tryFindUniqueId(ShineInfo const*);
void findUnlockShineNumCurrentWorld(bool *);
void trySetCollectedBgm(char const*,char const*);
// void setGotShine(GameDataFile::HintInfo const*);
void setGotShine(GameDataFile::HintInfo const*);
// void tryWriteByByaml(al::ByamlWriter *);
int getTotalShineNum(void);
@ -229,7 +271,7 @@ class GameDataFile
void getPlayerHitPointData(void);
void getLastUpdateTime(void);
void getPlayTimeTotal(void);
void getMainScenarioNo(int);
int getMainScenarioNo(int) const;
void getCollectedBgmMaxNum(void);
int getScenarioNo(void) const;
void getMiniGameName(int);
@ -314,6 +356,21 @@ class GameDataFile
bool isGameClear(void) const;
bool isEmpty(void) const;
bool isKidsMode(void) const;
// custom methods
// custom impl of findShine that uses shine UID instead of index to get the right HintInfo
HintInfo* findShine(int shineUid) {
for (int x = 0; x < 0x400; x++) {
GameDataFile::HintInfo* curInfo = &mShineHintList[x];
if (curInfo->mUniqueID == shineUid) {
return curInfo;
}
}
return nullptr;
}
// end custom methods
ShineInfo **mShineInfoArray;
ShineInfo **mShineInfoArray2;
@ -349,7 +406,7 @@ class GameDataFile
void *qword5E8;
void *qword5F0;
u16 word5F8;
bool byte5FA;
bool mIsEnableCap;
void *qword600;
int dword608;
bool byte60C;
@ -403,7 +460,7 @@ class GameDataFile
bool byte901;
int dword904;
sead::FixedSafeString<0x80> char908;
void *char9A0;
HintInfo *mShineHintList; // 0x9A0
sead::PtrArrayImpl sead__ptrarrayimpl9A8;
sead::PtrArrayImpl sead__ptrarrayimpl9B8;
sead::PtrArrayImpl sead__ptrarrayimpl9C8;

View File

@ -67,6 +67,12 @@ public:
// checks save file if shine is collected by shine index only (0 through 725)
static bool isGotShine(GameDataHolderAccessor, int);
// checks save file if shine is collected using the shines ShineInfo
static bool isGotShine(GameDataHolderAccessor, ShineInfo const*);
// checks save file if shine is collected using the shines stage and obj ID
static bool isGotShine(GameDataHolderAccessor, const char *stageName, const char *objID);
// Gets Index for X Kingdom
static s32 getWorldIndexWaterfall(void);
static s32 getWorldIndexMoon(void);
@ -151,5 +157,19 @@ public:
static bool isUnlockFirstForest(void);
static bool isUnlockFirstSea(void);
};
};
namespace CustomGameDataFunction {
static GameDataFile::HintInfo* getHintInfoByUniqueID(GameDataHolderAccessor accessor, int uid) {
return accessor.mData->mGameDataFile->findShine(uid);
}
static const GameDataFile::HintInfo* getHintInfoByIndex(GameDataHolderAccessor accessor, int index) {
return &accessor.mData->mGameDataFile->mShineHintList[index];
}
static const GameDataFile::HintInfo* getHintInfoByIndex(al::LiveActor* actor, int index) {
GameDataHolderAccessor accessor(actor);
return getHintInfoByIndex(accessor, index);
}
}

View File

@ -21,12 +21,18 @@
#include "HakoniwaStateSimpleDemo.h"
#include "HakoniwaStateBootLoadData.h"
namespace al
{
namespace al {
class WipeHolder;
class ScreenCaptureExecutor;
class BootLayout;
} // namespace al
class SeadAudioPlayer;
class AudioBusSendFader;
class SimpleAudioUser;
} // namespace al
class BootLayout;
class TimeBalloonSequenceInfo;
class CollectBgmPlayer;
class LoadLayoutCtrl;
class HakoniwaSequence : public al::Sequence {
public:
@ -40,36 +46,59 @@ class HakoniwaSequence : public al::Sequence {
void update(void);
bool isEnableSave(void);
void drawMain(void);
al::Scene *getCurrentScene(void) const; // {return this->curScene}
al::Scene* getCurrentScene(void) const; // {return this->curScene}
void* qword20;
void* qword28;
void* qword30;
void* qword38;
void* qword40;
void* qword48;
void* qword50;
void* qword58;
void* qword60;
void* qword68;
void* qword70;
void* qword78;
void* qword80;
void* qword88;
al::AudioDirector *mAudioDirector; // 0x90
void *qword98;
void *qwordA0;
void *qwordA8;
al::Scene *curScene; // 0xB0
GameDataHolderAccessor mGameDataHolder; // 0xB8
al::GamePadSystem *mGamepadSys; // 0xC0
HakoniwaStateDemoOpening *mDemoOpening; // 0xC8
HakoniwaStateDemoEnding *mDemoEnding; // 0xD0
void exeBootLoadData();
void exeDemoOpening();
void exeLoadWorldResource();
void exeLoadWorldResourceWithBoot();
void exeLoadStage();
void exePlayStage();
void exeDemoWorldWarp();
void exeDemoEnding();
void exeDestroy();
void exeMiss();
void exeMissCoinSub();
void exeMissEnd();
void exeDemoLava();
void exeFadeToNewGame();
al::Scene *curScene; // 0xB0
GameDataHolderAccessor mGameDataHolder; // 0xB8
al::GamePadSystem *mGamepadSys; // 0xC0
HakoniwaStateDemoOpening *mDemoOpening; // 0xC8
HakoniwaStateDemoEnding *mDemoEnding; // 0xD0
HakoniwaStateDemoWorldWarp *mDemoWorldWarp; // 0xD8
HakoniwaStateSimpleDemo *mSimpleDemo; // 0xE0
HakoniwaStateBootLoadData *mBootLoadData; // 0xE8
HakoniwaStateDeleteScene *mDeleteScene; // 0xF0
al::LayoutKit* mLytKit; // 0xF8
unsigned char padding_168[0x108];
WorldResourceLoader* mResourceLoader; // 0x208
HakoniwaStateSimpleDemo *mSimpleDemo; // 0xE0
HakoniwaStateBootLoadData *mBootLoadData; // 0xE8
HakoniwaStateDeleteScene *mDeleteScene; // 0xF0
al::LayoutKit* mLytKit; // 0xF8
bool mYBalls;
sead::FixedSafeString<0x80> stageName;
int scenarioNum;
al::ScreenCaptureExecutor* mScreenCapExecutor;
al::WipeHolder* mWipeHolder;
bool mMissEnd;
al::SimpleLayoutAppearWaitEnd* mCounterMiss;
int mCurCoins;
int mFinalCoins;
BootLayout* mBootLayout;
al::EffectSystem* mEffectSystem;
al::AsyncFunctorThread* mInitThread;
bool mInitialized;
al::SeadAudioPlayer* mSeAudioPlayer;
al::SeadAudioPlayer* mBgmAudioPlayer;
al::AudioBusSendFader* mBusSendFader;
WorldResourceLoader* mResourceLoader;
sead::Heap* mPlayerResHeap;
sead::FixedSafeString<0x80> mCapName;
sead::FixedSafeString<0x80> mCostumeName;
al::SimpleAudioUser* mPlayerAudioUser;
bool mHackEnd;
TimeBalloonSequenceInfo* mBalloonSeqInfo;
CollectBgmPlayer* mCollectBgmPlayer;
sead::FixedSafeString<0x80> mLanguage;
int mFileId;
LoadLayoutCtrl* mLoadLayoutCtrl;
bool mKidsMode;
};

View File

@ -30,7 +30,7 @@ class ShineInfo {
sead::FixedSafeString<0x80> stageName = sead::FixedSafeString<0x80>(); // 0x0 (Size: 0x98)
sead::FixedSafeString<0x80> objectId = sead::FixedSafeString<0x80>(); // 0xA0
sead::FixedSafeString<0x80> scenObjId = sead::FixedSafeString<0x80>(); // 0x138
sead::FixedSafeString<0x80> mShineLabel = sead::FixedSafeString<0x80>(); // 0x138
int shineId; // 1C8
const QuestInfo *curQuest; // 1D0

View File

@ -24,6 +24,7 @@ class PlayerActorBase : public al::LiveActor, public IUsePlayerHack {
virtual int getPortNo(void);
virtual sead::Matrix34f *getViewMtx(void) const;
virtual IUsePlayerCollision* getPlayerCollision(void) const;
virtual PlayerHackKeeper* getPlayerHackKeeper() const override;
virtual bool isEnableDemo(void);
virtual void startDemo(void);
@ -60,7 +61,6 @@ class PlayerActorBase : public al::LiveActor, public IUsePlayerHack {
virtual void sendCollisionMsg(void);
virtual bool receivePushMsg(al::SensorMsg const*,al::HitSensor *,al::HitSensor *,float);
virtual PlayerHackKeeper* getPlayerHackKeeper() const override;
sead::Matrix34f* mViewMtx; // 0x110
int mPortNo; // 0x118

View File

@ -0,0 +1,9 @@
#pragma once
#include "al/resource/Resource.h"
#include "game/Player/PlayerCostumeInfo.h"
namespace PlayerCostumeFunction {
PlayerBodyCostumeInfo *createBodyCostumeInfo(al::Resource *,char const*);
PlayerHeadCostumeInfo *createHeadCostumeInfo(al::Resource *,char const*,bool);
}

View File

@ -1,11 +1,26 @@
#pragma once
#include "al/LiveActor/LiveActor.h"
#include "al/actor/ActorInitInfo.h"
#include "al/actor/SubActorKeeper.h"
#include "al/byaml/ByamlIter.h"
#include "al/model/ModelCtrl.h"
#include "al/model/ModelMaterialCategory.h"
#include "al/model/PartsModel.h"
#include "al/resource/ActorResource.h"
#include "al/string/StringTmp.h"
#include "al/util.hpp"
#include "al/util/LiveActorUtil.h"
#include "al/util/ResourceUtil.h"
#include "game/Player/PlayerCostumeFunction.h"
#include "game/Player/PlayerJointControlPartsDynamics.h"
#include "game/Player/PlayerConst.h"
#include "rs/util/LiveActorUtil.h"
#include "PlayerCostumeInfo.h"
#include "math/seadVector.h"
namespace al {
class Resource;
@ -31,7 +46,33 @@ class PlayerFunction
static al::Resource *initCapModelActor(al::LiveActor *, al::ActorInitInfo const &, char const *);
static al::Resource *initCapModelActorDemo(al::LiveActor *, al::ActorInitInfo const &, char const *);
static PlayerCostumeInfo *initMarioModelActor(al::LiveActor *player, const al::ActorInitInfo &initInfo, const char *modelName, const char *capType, al::AudioKeeper *keeper, bool isCloset);
// joint, init, pconst, nosescale, earscale
static PlayerCostumeInfo *initMarioModelActorDemo(PlayerJointControlPartsDynamics **jointCtrlPtr, al::LiveActor *player, const al::ActorInitInfo &initInfo, char const *bodyName, char const *capName, PlayerConst const *pConst,sead::Vector3f *noseScale, sead::Vector3f *earScale, bool isCloset);
static PlayerCostumeInfo *initMarioModelCommon(al::LiveActor *player, const al::ActorInitInfo &initInfo, char const *bodyName, char const *capName, int subActorNum, bool isDemo, al::AudioKeeper *audioKeeper, bool guessIsChromaKey, bool isCloset);
static PlayerCostumeInfo* initMarioModelActorDemo(PlayerJointControlPartsDynamics** jointCtrlPtr,
al::LiveActor* player, const al::ActorInitInfo& initInfo,
char const* bodyName, char const* capName,
PlayerConst const* pConst, sead::Vector3f* noseScale,
sead::Vector3f* earScale, bool isCloset);
static PlayerCostumeInfo* initMarioModelCommon(al::LiveActor* player,
const al::ActorInitInfo& initInfo,
char const* bodyName, char const* capName,
int subActorNum, bool isDemo,
al::AudioKeeper* audioKeeper,
bool guessIsChromaKey, bool isCloset);
// not a real symbol, func at 0x445A24
static void initMarioAudio(al::LiveActor* player, const al::ActorInitInfo& initInfo,
al::Resource* modelRes, bool isDemo,
al::AudioKeeper* audioKeeper);
// not a real symbol, func at 0x448B8C
static void initMarioSubModel(al::LiveActor* subactor, const al::ActorInitInfo& initInfo,
bool isInvisible, bool isDemo, bool isChromaKey,
bool isCloset);
// not a real symbol, func at 0x445128
static PlayerHeadCostumeInfo* initMarioHeadCostumeInfo(al::LiveActor* player,
const al::ActorInitInfo& initInfo,
const char*, const char*,
const char*, const char*, bool, bool,
bool, bool, bool);
// not a real symbol, func at 0x445DF4
static void initMarioDepthModel(al::LiveActor *player, bool isDemo, bool isChromaKey);
};

View File

@ -44,7 +44,7 @@ class StageSceneLayout : public al::NerveStateBase {
void startShineChipCompleteAnim(void);
void tryStartDemoGetLifeMaxUpItem(bool);
void startCloset(void);
void startShineCountAnim(bool);
void startShineCountAnim(bool isGameClear);
void exeAppear(void);
void exeWait(void);

View File

@ -29,7 +29,6 @@ class StageSceneStateServerConfig : public al::HostStateBase<al::Scene>, public
enum ServerConfigOption {
GAMEMODECONFIG,
GAMEMODESWITCH,
RECONNECT,
SETIP,
SETPORT
};
@ -42,11 +41,9 @@ class StageSceneStateServerConfig : public al::HostStateBase<al::Scene>, public
void exeMainMenu();
void exeOpenKeyboardIP();
void exeOpenKeyboardPort();
void exeRestartServer();
void exeGamemodeConfig();
void exeGamemodeSelect();
void exeSaveData();
void exeConnectError();
void endSubMenu();
@ -63,7 +60,7 @@ class StageSceneStateServerConfig : public al::HostStateBase<al::Scene>, public
SimpleLayoutMenu* mCurrentMenu = nullptr;
CommonVerticalList* mCurrentList = nullptr;
// Root Page, contains buttons for gamemode config, server reconnecting, and server ip address changing
// Root Page, contains buttons for gamemode config, and server ip address changing
SimpleLayoutMenu* mMainOptions = nullptr;
CommonVerticalList *mMainOptionsList = nullptr;
// Sub-Page of Mode config, used to select a gamemode for the client to use
@ -86,9 +83,7 @@ namespace {
NERVE_HEADER(StageSceneStateServerConfig, MainMenu)
NERVE_HEADER(StageSceneStateServerConfig, OpenKeyboardIP)
NERVE_HEADER(StageSceneStateServerConfig, OpenKeyboardPort)
NERVE_HEADER(StageSceneStateServerConfig, RestartServer)
NERVE_HEADER(StageSceneStateServerConfig, GamemodeConfig)
NERVE_HEADER(StageSceneStateServerConfig, GamemodeSelect)
NERVE_HEADER(StageSceneStateServerConfig, SaveData)
NERVE_HEADER(StageSceneStateServerConfig, ConnectError)
}
}

View File

@ -37,8 +37,8 @@ namespace al {
al::GameDrawInfo *mDrawInfo; // 0x38 from Application::sInstance + 0x30
ProjectNfpDirector *mProjNfpDirector; // 0x48
al::HtmlViewer *mHtmlViewer; // 0x50
ApplicationMessageReceiver *mMessageReciever; // 0x58
ApplicationMessageReceiver *mMessageReceiver; // 0x58
al::WaveVibrationHolder *mWaveVibrationHolder; // 0x60
void *gap2;
};
}
}

View File

@ -1,7 +1,48 @@
#pragma once
class WorldResourceLoader {
public:
void loadWorldResource(int,int,bool,char const *);
bool requestLoadWorldHomeStageResource(int worldIndex, int scenario);
};
#include "al/async/AsyncFunctorThread.h"
#include "al/hio/HioNode.h"
#include "game/GameData/GameDataHolder.h"
#include "heap/seadHeap.h"
class WorldResourceLoader : public al::HioNode {
public:
WorldResourceLoader(GameDataHolder *);
virtual ~WorldResourceLoader();
void loadResource(void);
void cancelLoadWorldResource(void);
void tryDestroyWorldResource(void);
bool requestLoadWorldHomeStageResource(int worldIndex, int scenario);
bool isEndLoadWorldResource(void) const; // { return mResourceLoadThread->isDone(); };
void requestLoadWorldResourceCommon(int);
void requestLoadWorldResource(int);
void createResourcePlayer(void);
void tryDestroyWorldResourceOnlyCap(void);
void calcLoadPercent(void);
void getLoadWorldId(void);
bool tryLoadResource(char const*,char const*,char const*);
void loadWorldResource(int,int,bool,char const*);
void calcWorldResourceHeapSize(void);
al::AsyncFunctorThread* mResourceLoadThread; // 0x8
sead::Heap* mWorldResHeap = nullptr; // 0x10
sead::Heap* mCapHeap = nullptr; // 0x18
sead::Heap* mWaterfallHeap = nullptr; // 0x20
int mCurWorld = -1; // 0x28
int mCurScenario = -1; // 0x2C
bool unkBool = true; // 0x30
bool mIsCancelLoad = true; // 0x31
void *unkPtr4 = nullptr; // 0x38
void* unkPtr5 = nullptr; // 0x40
int unkInt3 = 0; // 0x48
bool unkBool3 = true; // 0x4C
int unkInt4 = 0; // 0x50
int unkInt5 = 1; // 0x5C
GameDataHolder* mDataHolder; // 0x58
bool mIsDoneLoadingArcs = false; // 0x60
int mArcCount = 0; // 0x64
};
static_assert(sizeof(WorldResourceLoader) == 0x68, "WorldResourceLoader size");

View File

@ -14,14 +14,6 @@
#include "game/GameData/GameDataFunction.h"
#define RAD(deg) (deg * (M_PI / 180)) // converts Degrees to Radians
#define DEG(rad) (rad * (180 / M_PI)) // converts Radians to Degrees
#define BTOC(bool) (bool ? "True" : "False") // converts boolean to true/false char
#define ACNT(arr) (sizeof(arr) / sizeof(arr[0])) // returns size of inputted array
// used to convert macro values to strings
#define STRINGIFY(x) #x
#define TOSTRING(x) STRINGIFY(x)
bool isPartOf(const char* w1, const char* w2);
int indexOf(char *w1, char c1);

View File

@ -55,12 +55,6 @@ static bool isInGame = false;
static bool debugMode = false;
static bool isSmallMode = true;
static float scale = 0.3f;
extern float camDist;
constexpr const char* captureNames[] = {
"AnagramAlphabetCharacter", "Byugo", "Bubble", "Bull", "Car", "ElectricWire",
"KillerLauncherMagnum", "KuriboPossessed",

View File

@ -2,6 +2,12 @@
#include "../types.h"
struct pollfd
{
s32 fd;
s16 events;
s16 revents;
};
struct in_addr
{
@ -38,13 +44,19 @@ s32 Connect(s32 socket, const sockaddr* address, u32 addressLen);
Result Close(s32 socket);
s32 Send(s32 socket, const void* data, ulong dataLen, s32 flags);
s32 SendTo(s32 socket, const void* data, ulong dataLen, s32 flags, const struct sockaddr* to, u32 toLen);
s32 Recv(s32 socket, void* out, ulong outLen, s32 flags);
s32 RecvFrom(s32 socket, void* out, ulong outLen, s32 flags, struct sockaddr* from, u32* fromLen);
s32 GetSockName(s32 socket, struct sockaddr* name, u32* dataLen);
u16 InetHtons(u16 val);
u16 InetNtohs(u16 val);
s32 InetAton(const char* addressStr, in_addr* addressOut);
struct hostent* GetHostByName(const char* name);
u32 GetLastErrno();
s32 Bind(s32 fd, sockaddr* addr, u32 addrlen);
s32 Poll(struct pollfd* fd, u64 addr, s32 timeout);
} }

View File

@ -6,7 +6,7 @@
struct PACKED GameInf : Packet {
GameInf() : Packet() {this->mType = PacketType::GAMEINF; mPacketSize = sizeof(GameInf) - sizeof(Packet);};
bool1 is2D = false;
u8 scenarioNo = -1;
u8 scenarioNo = 255;
char stageName[0x40] = {};
bool operator==(const GameInf &rhs) const {
@ -19,4 +19,4 @@ struct PACKED GameInf : Packet {
bool operator!=(const GameInf& rhs) const { return !operator==(rhs); }
};
};

View File

@ -0,0 +1,7 @@
#pragma once
#include "Packet.h"
struct PACKED HolePunch : Packet {
HolePunch() : Packet() {this->mType = PacketType::HOLEPUNCH; mPacketSize = sizeof(HolePunch) - sizeof(Packet);};
};

View File

@ -26,6 +26,8 @@ enum PacketType : short {
CAPTUREINF,
CHANGESTAGE,
CMD,
UDPINIT,
HOLEPUNCH,
End // end of enum for bounds checking
};
@ -43,7 +45,9 @@ USED static const char *packetNames[] = {
"Moon Collection",
"Capture Info",
"Change Stage",
"Server Command"
"Server Command",
"Udp Initialization",
"Hole punch",
};
enum SenderType {
@ -83,4 +87,6 @@ struct PACKED Packet {
#include "packets/CaptureInf.h"
#include "packets/HackCapInf.h"
#include "packets/ChangeStagePacket.h"
#include "packets/InitPacket.h"
#include "packets/InitPacket.h"
#include "packets/UdpPacket.h"
#include "packets/HolePunchPacket.h"

View File

@ -0,0 +1,8 @@
#pragma once
#include "Packet.h"
struct PACKED UdpInit : Packet {
UdpInit() : Packet() {this->mType = PacketType::UDPINIT; mPacketSize = sizeof(UdpInit) - sizeof(Packet);};
u16 port = 0;
};

View File

@ -11,6 +11,10 @@
namespace rs {
bool updateNormalStateExcludeGraphics(al::Scene*);
void updateEffectSystemEnv(al::Scene *);
bool isModeE3Rom(void);
bool isModeE3LiveRom(void);

View File

@ -2,8 +2,8 @@
#include "al/LiveActor/LiveActor.h"
namespace rs
{
namespace rs {
void createPlayerSklRetargettingInfo(al::LiveActor *,sead::Vector3f const&);
void initItemByPlacementInfo(al::LiveActor *, al::ActorInitInfo const &, bool);
float setShadowDropLength(al::LiveActor *,al::ActorInitInfo const&,char const*);
} // namespace rs

View File

@ -34,6 +34,11 @@ public:
Element peek(BlockType block_type) const;
bool jam(Element message, BlockType block_type);
// custom funcs
inline u32 getCount() {return mMessageQueueInner.Count;}
inline u32 getMaxCount() {return mMessageQueueInner.MaxCount;}
inline bool isFull() const {return mMessageQueueInner.Count == mMessageQueueInner.MaxCount;}
static constexpr Element cNullElement = 0;
private:

View File

@ -15,6 +15,7 @@
#include "al/async/FunctorV0M.hpp"
#include "al/LiveActor/LiveActor.h"
#include "al/layout/LayoutInitInfo.h"
#include "al/layout/SimpleLayoutAppearWaitEnd.h"
#include "al/layout/WindowConfirmWait.h"
#include "al/util.hpp"
#include "al/layout/LayoutActor.h"
@ -32,8 +33,7 @@
#include "game/GameData/GameDataHolderWriter.h"
#include "game/GameData/GameDataFunction.h"
#include "heap/seadFrameHeap.h"
#include "heap/seadHeap.h"
#include "heap/seadExpHeap.h"
#include "layouts/HideAndSeekIcon.h"
#include "rs/util.hpp"
@ -66,6 +66,7 @@
#include "puppets/PuppetInfo.h"
#include <cstddef>
#include <stdlib.h>
#define MAXPUPINDEX 32
@ -85,12 +86,9 @@ class Client {
void init(al::LayoutInitInfo const &initInfo, GameDataHolderAccessor holder);
bool StartThreads();
bool startThread();
void readFunc();
void recvFunc();
static void restartConnection();
bool isDone() { return mReadThread->isDone(); };
static bool isSocketActive() { return sInstance ? sInstance->mSocket->isConnected() : false; };
bool isPlayerConnected(int index) { return mPuppetInfoArr[index]->isConnected; }
static bool isNeedUpdateShines();
@ -104,16 +102,21 @@ class Client {
static void sendShineCollectPacket(int shineId);
static void sendTagInfPacket();
static void sendCaptureInfPacket(const PlayerActorHakoniwa *player);
void resendInitPackets();
int getCollectedShinesCount() { return curCollectedShines.size(); }
int getShineID(int index) { if (index < curCollectedShines.size()) { return curCollectedShines[index]; } return -1; }
static void setStageInfo(GameDataHolderAccessor holder);
static void update();
static void clearArrays();
static bool tryAddPuppet(PuppetActor *puppet);
static bool tryAddDebugPuppet(PuppetActor* puppet);
static bool isFirstConnect() { return sInstance ? sInstance->mIsFirstConnect : false;}
static const char *getClientName() { return sInstance ? sInstance->mUsername.cstr() : "Player"; }
static PuppetActor *getPuppet(int idx);
@ -126,24 +129,12 @@ class Client {
static PuppetActor* getDebugPuppet();
static sead::Heap *getClientHeap() { return sInstance ? sInstance->mHeap : nullptr; }
static int getMaxPlayerCount() { return sInstance ? sInstance->maxPuppets + 1 : 10;}
static void updateStates();
static void clearArrays();
static Keyboard* getKeyboard();
static const char* getCurrentIP();
static void setLastUsedIP(const char* ip);
static const int getCurrentPort();
static void setLastUsedPort(const int port);
static void setTagState(bool state);
static int getConnectCount() {
if (sInstance)
return sInstance->mConnectCount;
@ -156,6 +147,22 @@ class Client {
return nullptr;
}
static Keyboard* getKeyboard();
static const char* getCurrentIP();
static nn::account::Uid getClientId() { return sInstance ? sInstance->mUserID : nn::account::Uid::EmptyId;}
static sead::FixedSafeString<0x20> getUsername() { return sInstance ? sInstance->mUsername : sead::FixedSafeString<0x20>::cEmptyString;}
static void setStageInfo(GameDataHolderAccessor holder);
static void setLastUsedIP(const char* ip);
static void setLastUsedPort(const int port);
static void setTagState(bool state);
static void setSceneInfo(const al::ActorInitInfo& initInfo, const StageScene *stageScene);
static bool tryRegisterShine(Shine* shine);
@ -167,11 +174,8 @@ class Client {
static bool openKeyboardIP();
static bool openKeyboardPort();
static void showConnect();
static void showConnectError(const char16_t* msg);
static void hideConnect();
static void showUIMessage(const char16_t* msg);
static void hideUIMessage();
void resetCollectedShines();
@ -190,6 +194,8 @@ class Client {
void updateTagInfo(TagInf *packet);
void updateCaptureInfo(CaptureInf* packet);
void sendToStage(ChangeStagePacket* packet);
void sendUdpHolePunch();
void sendUdpInit();
void disconnectPlayer(PlayerDC *packet);
PuppetInfo* findPuppetInfo(const nn::account::Uid& id, bool isFindAvailable);
@ -198,9 +204,7 @@ class Client {
// --- General Server Members ---
// currently, only readThread is used to recieve and update PuppetInfo, while the main game thread is used to send packets without queueing them up first, which might cause performance issues
al::AsyncFunctorThread *mReadThread = nullptr; // TODO: use this thread to send any queued packets
// al::AsyncFunctorThread *mRecvThread; // TODO: use this thread to recieve packets and update PuppetInfo
al::AsyncFunctorThread *mReadThread = nullptr; // processes data queued in the SocketClient's RecvQueue
int mConnectCount = 0;
@ -212,7 +216,7 @@ class Client {
// --- Server Syncing Members ---
// array of shine IDs for checking if multiple shines have been collected in quick sucession, all moons within the players stage that match the ID will be deleted
// array of shine IDs for checking if multiple shines have been collected in quick succession, all moons within the players stage that match the ID will be deleted
sead::SafeArray<int, 128> curCollectedShines;
int collectedShineCount = 0;
@ -221,7 +225,10 @@ class Client {
// Backups for our last player/game packets, used for example to re-send them for newly connected clients
PlayerInf lastPlayerInfPacket = PlayerInf();
GameInf lastGameInfPacket = GameInf();
GameInf emptyGameInfPacket = GameInf();
CostumeInf lastCostumeInfPacket = CostumeInf();
TagInf lastTagInfPacket = TagInf();
CaptureInf lastCaptureInfPacket = CaptureInf();
Keyboard* mKeyboard = nullptr; // keyboard for setting server IP
@ -230,11 +237,11 @@ class Client {
int mServerPort = 0;
bool waitForGameInit = true;
bool isFirstConnect = true;
bool mIsFirstConnect = true;
// --- Game Layouts ---
al::WindowConfirmWait* mConnectionWait;
al::WindowConfirmWait* mUIMessage;
al::SimpleLayoutAppearWaitEnd *mConnectStatus;
// --- Game Info ---
@ -257,7 +264,7 @@ class Client {
u8 mScenario = 0;
sead::FrameHeap *mHeap = nullptr; // Custom FrameHeap used for all Client related memory
sead::ExpHeap *mHeap = nullptr; // Custom FrameHeap used for all Client related memory
// --- Puppet Info ---

View File

@ -1,6 +1,8 @@
#pragma once
#include "SocketBase.hpp"
#include "al/async/AsyncFunctorThread.h"
#include "heap/seadHeap.h"
#include "nn/result.h"
#include "sead/math/seadVector.h"
#include "sead/math/seadQuat.h"
@ -12,27 +14,78 @@
#include "syssocket/sockdefines.h"
#include "thread/seadMessageQueue.h"
#include "thread/seadMutex.h"
#include "types.h"
#include "packets/Packet.h"
class Client;
class SocketClient : public SocketBase {
public:
SocketClient(const char *name) : SocketBase(name) {
mPacketQueue = sead::PtrArray<Packet>();
mPacketQueue.tryAllocBuffer(maxBufSize, nullptr);
};
SocketClient(const char* name, sead::Heap* heap, Client* client);
nn::Result init(const char* ip, u16 port) override;
bool tryReconnect();
bool closeSocket() override;
bool SEND(Packet *packet);
bool RECV();
void printPacket(Packet* packet);
bool isConnected() {return socket_log_state == SOCKET_LOG_CONNECTED; }
sead::PtrArray<Packet> mPacketQueue;
bool startThreads();
void endThreads();
void waitForThreads();
bool send(Packet* packet);
bool recv();
bool queuePacket(Packet *packet);
bool trySendQueue();
void sendFunc();
void recvFunc();
Packet *tryGetPacket(sead::MessageQueue::BlockType blockType = sead::MessageQueue::BlockType::Blocking);
void printPacket(Packet* packet);
bool isConnected() { return socket_log_state == SOCKET_LOG_CONNECTED; }
u16 getLocalUdpPort();
s32 setPeerUdpPort(u16 port);
const char* getUdpStateChar();
u32 getSendCount() { return mSendQueue.getCount(); }
u32 getSendMaxCount() { return mSendQueue.getMaxCount(); }
u32 getRecvCount() { return mRecvQueue.getCount(); }
u32 getRecvMaxCount() { return mRecvQueue.getMaxCount(); }
void clearMessageQueues();
void setQueueOpen(bool value) { mPacketQueueOpen = value; }
void setIsFirstConn(bool value) { mIsFirstConnect = value; }
private:
sead::Heap* mHeap = nullptr;
Client* client = nullptr;
al::AsyncFunctorThread* mRecvThread = nullptr;
al::AsyncFunctorThread* mSendThread = nullptr;
sead::MessageQueue mRecvQueue;
sead::MessageQueue mSendQueue;
char* recvBuf = nullptr;
int maxBufSize = 100;
bool mIsFirstConnect = true;
bool mPacketQueueOpen = true;
int pollTime = 0;
bool mHasRecvUdp;
s32 mUdpSocket;
sockaddr mUdpAddress;
bool recvTcp();
bool recvUdp();
/**
* @param str a string containing an IPv4 address or a hostname that can be resolved via DNS
@ -41,3 +94,5 @@ class SocketClient : public SocketBase {
*/
bool stringToIPAddress(const char* str, in_addr* out);
};
typedef void (SocketClient::*SocketThreadFunc)(void);

View File

@ -3,8 +3,10 @@
#include <heap/seadDisposer.h>
#include <heap/seadHeap.h>
#include <container/seadSafeArray.h>
#include "al/util.hpp"
#include "server/gamemode/GameModeBase.hpp"
#include "server/gamemode/GameModeInfoBase.hpp"
#include "server/gamemode/modifiers/ModeModifierBase.hpp"
class GameModeManager {
SEAD_SINGLETON_DISPOSER(GameModeManager)
@ -29,6 +31,7 @@ public:
T* createModeInfo();
sead::Heap* getHeap() { return mHeap; }
static sead::Heap* getSceneHeap() { return al::getSceneHeap(); }
void toggleActive();
void setActive(bool active) { mActive = active; }
void setPaused(bool paused);
@ -47,6 +50,7 @@ private:
GameModeBase* mCurModeBase = nullptr;
GameModeInfoBase *mModeInfo = nullptr;
GameModeInitInfo *mLastInitInfo = nullptr;
ModeModifierBase *mCurModifier = nullptr;
};
template<class T>

View File

@ -0,0 +1,18 @@
#pragma once
#include "ModeModifierBase.hpp"
#include "game/StageScene/StageScene.h"
class GravityModifier : public ModeModifierBase {
public:
GravityModifier(GameModeBase* modeInfo);
void enable() override;
void disable() override;
void update() override;
void setCamTicket(al::CameraTicket *ticket) {mTicket = ticket;};
private:
al::CameraTicket *mTicket = nullptr;
};

View File

@ -0,0 +1,24 @@
#pragma once
#include <cmath>
#include "game/StageScene/StageScene.h"
class GameModeBase;
class ModeModifierBase {
public:
ModeModifierBase(GameModeBase* mode) : mMode(mode) {}
bool isActive() const { return mIsEnabled; }
virtual void init(StageScene *scene) { mScene = scene; }
virtual void enable() { mIsEnabled = true; }
virtual void disable() { mIsEnabled = false; }
virtual void update() {}
protected:
GameModeBase* mMode = nullptr;
StageScene *mScene = nullptr;
bool mIsEnabled = false;
};

View File

@ -0,0 +1,34 @@
#pragma once
#include "al/factory/Factory.h"
#include "server/gamemode/GameModeBase.hpp"
#include "server/gamemode/modifiers/GravityModifier.hpp"
#include "server/gamemode/modifiers/ModeModifierBase.hpp"
#include "server/gamemode/modifiers/NoCapModifier.hpp"
typedef ModeModifierBase* (*createMod)(GameModeBase* mode);
template <class T>
ModeModifierBase* createModifier(GameModeBase* mode)
{
return new T(mode);
};
__attribute((used)) constexpr al::NameToCreator<createMod> modifierTable[] = {
{"Gravity", &createModifier<GravityModifier>},
{"NoCap", &createModifier<NoCapModifier>}
};
constexpr const char* modifierNames[] = {
"Sticky Gravity",
"Cappy-Less"
};
class ModifierFactory : public al::Factory<createMod> {
public:
ModifierFactory(const char *fName) {
this->factoryName = fName;
this->actorTable = modifierTable;
this->factoryCount = sizeof(modifierTable)/sizeof(modifierTable[0]);
};
};

View File

@ -0,0 +1,11 @@
#pragma once
#include "server/gamemode/modifiers/ModeModifierBase.hpp"
class NoCapModifier : public ModeModifierBase {
public:
NoCapModifier(GameModeBase* modeInfo);
void enable() override;
void disable() override;
};

View File

@ -9,11 +9,13 @@ public:
HideAndSeekConfigMenu();
void initMenu(const al::LayoutInitInfo &initInfo) override;
const sead::WFixedSafeString<0x200> *getStringData() override;
const sead::WFixedSafeString<0x200>* getStringData() override;
bool updateMenu(int selectIndex) override;
const int getMenuSize() override { return mItemCount; }
private:
static constexpr int mItemCount = 2;
};
static constexpr int mItemCount = 1;
sead::SafeArray<sead::WFixedSafeString<0x200>, mItemCount>* gravityOn = nullptr;
sead::SafeArray<sead::WFixedSafeString<0x200>, mItemCount>* gravityOff = nullptr;
};

View File

@ -61,6 +61,14 @@ typedef __builtin_va_list va_list;
#define va_start(v,l) __builtin_va_start(v,l)
#define va_end(v) __builtin_va_end(v)
#define RAD(deg) (deg * (M_PI / 180)) // converts Degrees to Radians
#define DEG(rad) (rad * (180 / M_PI)) // converts Radians to Degrees
#define BTOC(bool) (bool ? "True" : "False") // converts boolean to true/false char
#define ACNT(arr) (sizeof(arr) / sizeof(arr[0])) // returns size of inputted array
// used to convert macro values to strings
#define STRINGIFY(x) #x
#define TOSTRING(x) STRINGIFY(x)
//using u64 = std::uint64_t;
//using s64 = std::int64_t;

View File

@ -1 +1,8 @@
_ZN14PlayerFunction20initMarioModelCommonEPN2al9LiveActorERKNS0_13ActorInitInfoEPKcS7_ibPNS0_11AudioKeeperEbb = 0x444028 - 0x2C63000;
_ZN14PlayerFunction20initMarioModelCommonEPN2al9LiveActorERKNS0_13ActorInitInfoEPKcS7_ibPNS0_11AudioKeeperEbb = 0x444028 - 0x2C63000;
_ZN14PlayerFunction14initMarioAudioEPN2al9LiveActorERKNS0_13ActorInitInfoEPNS0_8ResourceEbPNS0_11AudioKeeperE = 0x445A24 - 0x2C63000;
_ZN14PlayerFunction17initMarioSubModelEPN2al9LiveActorERKNS0_13ActorInitInfoEbbbb = 0x448B8C - 0x2C63000;
_ZN14PlayerFunction24initMarioHeadCostumeInfoEPN2al9LiveActorERKNS0_13ActorInitInfoEPKcS7_S7_S7_bbbbb = 0x445128 - 0x2C63000;
_ZN14PlayerFunction19initMarioDepthModelEPN2al9LiveActorEbb = 0x445DF4 - 0x2C63000;
gameDrawTable = 0x1DDFB38 - 0x2C63000;
gameUpdateTable = 0x1DDFAD8 - 0x2C63000;

View File

@ -90,6 +90,13 @@ B59E28 B seadPrintHook // sead::system::print
20CA78 BL startCounterHook // starts coin counter if a gamemode is not active
20CAA8 BL startCounterHook // starts purple coin counter if gamemode is not active
// Other HUD Changes
20CB4C BL modeE3Hook // PlayGuideMenuLyt at StageSceneStateLayout::start+140
20CA5C BL modeE3Hook // MapMini::appearSlideIn at StageSceneStateLayout::start+50
20D160 BL modeE3Hook // MapMini::end at StageSceneStateLayout::exeEnd+8C
20D154 BL playGuideEndHook
// Pause Menu Changes
4EAEC4 B overrideNerveHook // makes any button on pause menu run a specific nerve
@ -112,4 +119,9 @@ B59E28 B seadPrintHook // sead::system::print
5C00B0 BL borderPullBackHook // hooks over isFirstStep in WorldEndBorderKeeper::exePullBack so we can kill the player if they reach the border of the map
// 4E46BC NOP // removes call to setEnableData for one of the commonverticallists in the options menu, which makes all entries in the menu look the same
// 4E46BC NOP // removes call to setEnableData for one of the commonverticallists in the options menu, which makes all entries in the menu look the same
8912B8 B drawTableHook
// 891394 BL drawInitHook
// 91328 BL updateInitHook

View File

@ -45,7 +45,7 @@
//4EAE58: // forces StageSceneStatePauseMenu to immediately select continue
// MOV X0, #1
20CB4C BL modeE3Hook // PlayGuideMenuLyt at StageSceneStateLayout::start+140
20CA5C BL modeE3Hook // MapMini::appearSlideIn at StageSceneStateLayout::start+50
20D160 BL modeE3Hook // MapMini::end at StageSceneStateLayout::exeEnd+8C
20D154 BL playGuideEndHook
// very wip stuff for implementing custom executors
// 4D1814 BL updateStateHook
// 87C90C BL updateDrawHook

View File

@ -35,36 +35,37 @@ if '.' not in consoleIP:
print(sys.argv[0], "ERROR: Please specify with `IP=[Your console's IP]`")
sys.exit(-1)
isNeedOtherSwitch = True
altSwitchIP = sys.argv[2]
if '.' not in altSwitchIP:
isNeedOtherSwitch = False
isNeedOtherSwitch = False
consolePort = 5000
if len(sys.argv) < 4:
if len(sys.argv) < 3:
projName = 'StarlightBase'
else:
projName = sys.argv[3]
projName = sys.argv[2]
if len(sys.argv) < 5:
user = 'crafty'
passwd = 'boss'
else:
user = sys.argv[3]
passwd = sys.argv[4]
curDir = os.curdir
ftp = FTP()
otherftp = FTP()
print(f'Connecting to {consoleIP}... ', end='')
ftp.connect(consoleIP, consolePort)
print('logging into server...', end='')
ftp.login('crafty','boss')
ftp.login(user,passwd)
print('Connected!')
if isNeedOtherSwitch:
print(f'Connecting to {altSwitchIP}... ', end='')
otherftp.connect(altSwitchIP, consolePort)
print('logging into server...', end='')
otherftp.login('crafty','boss')
otherftp.login(user,passwd)
print('Connected!')
patchDirectories = []

View File

@ -0,0 +1,480 @@
#include <string_view>
#include "al/execute/ExecuteOrder.h"
#include "al/execute/ExecuteTable.h"
#include "al/execute/ExecuteTableHolderDraw.h"
#include "al/execute/ExecuteTableHolderUpdate.h"
static constexpr al::ExecuteOrder drawTableArr[] = {
// 3D(カリング)
{"カリング", "ActorModelDrawCulling", 512, "システム"},
// 3D(デプスシャドウ)
{"デプスシャドウ[キャラクター]", "ActorModelDrawDepthShadow", 192, ""},
{"デプスシャドウ[地形]", "ActorModelDrawDepthShadow", 192, ""},
{"デプスシャドウ[マーチングキューブ]", "ActorModelDrawDepthShadowMarchingCube", 16, ""},
{"デプスシャドウ[独自]", "Functor", 16, ""},
// 3D(デプスシャドウプレイヤー)
{"デプスシャドウ[プレイヤー]", "ActorModelDrawDepthShadow", 128, ""},
{"Mii[顔モデル](デプスシャドウ)", "Draw", 8, ""},
// 3D(スタティックデプスシャドウ)
{"スタティックデプスシャドウ[地形]", "ActorModelDrawStaticDepthShadow", 128, ""},
// ワールドAo
{"ワールドAo[地形]", "ActorModelDrawWorldAo", 192, ""},
// 3D(海用デプス)
{"海用デプス[浜辺]", "ActorModelDrawWorldAo", 8, ""},
{"海用デプス[高さ]", "ActorModelDrawWorldAo", 8, ""},
// 3D(空)
{"", "ActorModelDraw", 8, "地形"},
// 3D(不透明Zプリパス)
{"Zプリパス[カリング]", "ActorModelDrawDepthOnly", 512, "地形"},
{"Zプリパス[キャラクター]", "ActorModelDrawDepthOnly", 128, ""},
{"Zプリパス[地形]", "ActorModelDrawDepthOnly", 128, "地形"},
{"Zプリパス[遠景]", "ActorModelDrawDepthOnly", 128, "地形"},
{"Zプリパス[ディザ]", "ActorModelDrawDepthDither", 196, ""},
{"プレイヤー", "ActorModelDrawDepthDither", 196, "プレイヤー"},
// 3D(ディファード地形)
{"地形オブジェ[地形前]", "ActorModelDrawDeferred", 128, "地形オブジェ"},
{"地形オブジェ[地形前ディファードのみ]", "ActorModelDrawDeferredOnly", 32, "地形オブジェ"},
{"地形オブジェ[地形前ディファード不透明のみ]", "ActorModelDrawDeferredOpa", 16, "地形オブジェ"},
{"敵[地形前]", "ActorModelDrawDeferred", 16, ""},
{"敵[地形前ディファード不透明のみ]", "ActorModelDrawDeferredOpa", 16, ""},
{"[地形前]", "ActorModelDrawDeferred", 16, ""},
{"[地形前ディファード不透明のみ]", "ActorModelDrawDeferredOpa", 16, ""},
{"プレイヤー[地形前]", "ActorModelDrawDeferred", 16, "プレイヤー"},
{"地形[浮遊]", "ActorModelDrawDeferred", 32, "地形"},
{"地形", "ActorModelDrawDeferred", 256, "地形"},
{"地形[ディファード]", "ActorModelDrawDeferredOnly", 32, "地形"},
{"地形[ディファードのみ]", "ActorModelDrawDeferredOnly", 32, "地形"},
{"地形[ディファード不透明]", "ActorModelDrawDeferredOpa", 16, "地形"},
{"地形[ディファード不透明のみ]", "ActorModelDrawDeferredOpa", 64, "地形"},
{"地形[埋没]", "ActorModelDrawDeferred", 32, "地形"},
// 3D(ディファード鏡映り込みなし)
{"地形[鏡映り込みなし]", "ActorModelDrawDeferred", 32, "地形"},
// 3D(ディファードキャラクター)
{"シャドウマスク[地形オブジェ]", "Draw", 3, ""},
{"足跡", "ActorModelDrawDeferredFootPrint", 4, "プレイヤー"},
{"地形オブジェ", "ActorModelDrawDeferred", 128, "地形オブジェ"},
{"地形オブジェ[ディファードのみ]", "ActorModelDrawDeferredOnly", 16, "地形オブジェ"},
{"地形オブジェ[ディファード不透明のみ]", "ActorModelDrawDeferredOpa", 16, "地形オブジェ"},
{"地形オブジェ[マーチングキューブ]", "ActorModelDrawDeferredMarchingCube", 32, "地形オブジェ"},
{"地形[地形オブジェ後]", "ActorModelDrawDeferred", 32, "地形"},
{"敵[シルエット前]", "ActorModelDrawDeferred", 128, ""},
{"アクター描画[シルエット前]", "ActorDraw", 8, "アクター"},
{"シルエット[プレイヤー]", "ActorModelDrawDeferredSilhouette", 196, "プレイヤー"},
{"シルエット[オブジェ]", "ActorModelDrawDeferredSilhouette", 64, "地形オブジェ"},
{"シルエットモデル[敵]", "ActorModelDrawDeferred", 64, ""},
{"地形[シルエット後]", "ActorModelDrawDeferred", 32, "地形"},
{"地形オブジェ[シルエット後]", "ActorModelDrawDeferred", 32, "地形オブジェ"},
{"シャドウマスク[敵]", "Draw", 3, ""},
{"", "ActorModelDrawDeferred", 128, ""},
{"敵[ディファードのみ]", "ActorModelDrawDeferredOnly", 16, ""},
{"敵[ディファード不透明のみ]", "ActorModelDrawDeferredOpa", 16, ""},
{"", "ActorModelDrawDeferred", 96, ""},
{"[ディファードのみ]", "ActorModelDrawDeferredOnly", 8, ""},
{"[ディファード不透明のみ]", "ActorModelDrawDeferredOpa", 8, ""},
{"Mii[顔モデル]", "Draw", 4, "システム"},
{"シャドウマスク[アイテム]", "Draw", 3, ""},
{"アイテム", "ActorModelDrawDeferred", 64, "アイテム"},
{"アイテム[ディファードのみ]", "ActorModelDrawDeferredOnly", 8, "アイテム"},
{"アイテム[ディファード不透明のみ]", "ActorModelDrawDeferredOpa", 8, "アイテム"},
// 3D(ディファード異空間)
{"異空間オブジェ", "ActorModelDrawDeferred", 64, "地形オブジェ"},
// 3D(ディファードプレイヤー)
{"シャドウマスク[プレイヤー]", "Draw", 4, ""},
{"プレイヤー", "ActorModelDrawDeferred", 196, "プレイヤー"},
{"プレイヤー装飾", "ActorModelDrawDeferred", 32, "プレイヤー"},
{"プレイヤー装飾[ディファード不透明のみ]", "ActorModelDrawDeferredOpa", 16, "プレイヤー"},
// 3D(ディファード中景)
{"地形オブジェ[キャラ後]", "ActorModelDrawDeferred", 32, "地形オブジェ"},
{"シャドウマスク[ブロック]", "Draw", 3, ""},
{"中景", "ActorModelDrawDeferred", 8, "地形"},
{"中景[ディファードのみ]", "ActorModelDrawDeferredOnly", 8, "地形"},
{"中景[ディファード不透明のみ]", "ActorModelDrawDeferredOpa", 8, "地形"},
{"大気散乱", "Draw", 1, "地形"},
{"ディファード空", "ActorModelDrawDeferredSky", 16, "地形"},
{"ディファード空[デモ]", "ActorModelDrawDeferredSky", 8, "地形"},
// 3D(ディファード半透明)
{"地形[ディファード半透明]", "ActorModelDrawDeferredXlu", 8, "地形"},
{"地形[ディファード半透明のみ]", "ActorModelDrawDeferredXlu", 8, "地形"},
{"地形オブジェ[ディファード半透明]", "ActorModelDrawDeferredXlu", 8, "地形オブジェ"},
{"地形オブジェ[ディファード半透明のみ]", "ActorModelDrawDeferredXlu", 8, "地形オブジェ"},
{"敵[ディファード半透明]", "ActorModelDrawDeferredXlu", 8, ""},
{"敵[ディファード半透明のみ]", "ActorModelDrawDeferredXlu", 8, ""},
{"[ディファード半透明]", "ActorModelDrawDeferredXlu", 8, ""},
{"[ディファード半透明のみ]", "ActorModelDrawDeferredXlu", 8, ""},
{"アイテム[ディファード半透明]", "ActorModelDrawDeferredXlu", 8, "アイテム"},
{"アイテム[ディファード半透明のみ]", "ActorModelDrawDeferredXlu", 8, "アイテム"},
{"プレイヤー装飾[ディファード半透明]", "ActorModelDrawDeferredXlu", 8, "プレイヤー"},
{"プレイヤー装飾[ディファード半透明のみ]", "ActorModelDrawDeferredXlu", 16, "プレイヤー"},
{"シャドウマスク[モデルライト後]", "Draw", 4, ""},
{"アクター描画", "ActorDraw", 8, "アクター"},
// 3D(デプスクリアプレイヤー)
{"プレイヤー", "ActorModelDrawDepthForce", 196, "プレイヤー"},
{"プレイヤー装飾[ディファード不透明のみ]", "ActorModelDrawDepthForce", 16, "プレイヤー"},
{"プレイヤー装飾[ディファード半透明のみ]", "ActorModelDrawDepthForce", 16, "プレイヤー"},
{"プレイヤー装飾[フォワードのみ]", "ActorModelDrawDepthForce", 16, "プレイヤー"},
{"プレイヤー装飾[インダイレクトのみ]", "ActorModelDrawDepthForce", 16, "プレイヤー"},
// 3D(フォワード遠景)
{"遠景[ライトバッファ]", "ActorModelDraw", 8, "地形"},
{"遠景[ライトバッファのみ]", "ActorModelDrawForwardOnly", 8, "地形"},
{"大気散乱雲遠距離[ライトバッファ]", "ActorModelDraw", 8, "地形"},
{"大気散乱雲遠距離[ライトバッファのみ]", "ActorModelDrawForwardOnly", 8, "地形"},
{"大気散乱雲[ライトバッファ]", "ActorModelDraw", 8, "地形"},
{"大気散乱雲[ライトバッファのみ]", "ActorModelDrawForwardOnly", 8, "地形"},
{"大気散乱雲近距離[ライトバッファ]", "ActorModelDraw", 8, "地形"},
{"大気散乱雲近距離[ライトバッファのみ]", "ActorModelDrawForwardOnly", 8, "地形"},
// 3D(フォワードプレイヤー)
{"Zプリパス[プレイヤー]", "ActorModelDrawDepthOnly", 32, "プレイヤー"},
{"プレイヤー[地形前]", "ActorModelDrawForwardForce", 16, "プレイヤー"},
{"プレイヤー", "ActorModelDrawForwardForce", 196, "プレイヤー"},
{"Zプリパス[プレイヤー装飾]", "ActorModelDrawDepthDither", 128, "プレイヤー"},
{"プレイヤー装飾", "ActorModelDrawForwardForce", 32, "プレイヤー"},
{"プレイヤー装飾[ディファード不透明のみ]", "ActorModelDrawForwardForce", 16, "プレイヤー"},
// 3D(フォワード)
{"半透明Zプリパス", "ActorModelDrawDepthXlu", 8, "地形"},
{"フォワードZプリパス[ディザ]", "ActorModelDrawDepthDither", 8, "地形"},
{"中景[フォワード]", "ActorModelDraw", 8, "地形"},
{"中景[フォワードのみ]", "ActorModelDrawForwardOnly", 8, "地形"},
{"大気散乱雲[フォワード]", "ActorModelDraw", 8, "地形"},
{"大気散乱雲[フォワードのみ]", "ActorModelDrawForwardOnly", 8, "地形"},
{"地形[フォワード]", "ActorModelDraw", 32, "地形"},
{"地形[フォワードのみ]", "ActorModelDrawForwardOnly", 48, "地形"},
{"地形オブジェ[フォワード]", "ActorModelDraw", 32, "地形オブジェ"},
{"地形オブジェ[フォワードのみ]", "ActorModelDrawForwardOnly", 32, "地形オブジェ"},
{"敵[フォワード]", "ActorModelDraw", 32, ""},
{"敵[フォワードのみ]", "ActorModelDrawForwardOnly", 16, ""},
{"[フォワード]", "ActorModelDraw", 32, ""},
{"[フォワードのみ]", "ActorModelDrawForwardOnly", 8, ""},
{"アイテム[フォワード]", "ActorModelDraw", 32, "アイテム"},
{"アイテム[フォワードのみ]", "ActorModelDrawForwardOnly", 8, "アイテム"},
{"プレイヤー[フォワード]", "ActorModelDraw", 8, "プレイヤー"},
{"プレイヤー装飾[フォワード]", "ActorModelDraw", 8, "プレイヤー"},
{"プレイヤー装飾[フォワードのみ]", "ActorModelDrawForwardOnly", 16, "プレイヤー"},
{"アクター描画[フォワード]", "ActorDraw", 8, "アクター"},
// 3D(インダイレクト)
{"半透明Zプリパス[インダイレクト]", "ActorModelDrawDepthIndirect", 8, "地形"},
{"インダイレクトZプリパス[ディザ]", "ActorModelDrawDepthDitherIndirect", 8, "地形"},
{"地形[インダイレクト]", "ActorModelDrawIndirect", 32, "地形"},
{"地形[インダイレクトのみ]", "ActorModelDrawIndirectOnly", 16, "地形"},
{"地形オブジェ[インダイレクト]", "ActorModelDrawIndirect", 32, "地形オブジェ"},
{"地形オブジェ[インダイレクトのみ]", "ActorModelDrawIndirectOnly", 32, "地形オブジェ"},
{"コイン[インダイレクト]", "ActorModelDrawIndirect", 8, "アイテム"},
{"ルート土管内側[インダイレクト]", "ActorModelDrawIndirect", 32, "地形オブジェ"},
{"ルート土管外側[インダイレクト]", "ActorModelDrawIndirect", 32, "地形オブジェ"},
{"敵[インダイレクト]", "ActorModelDrawIndirect", 32, ""},
{"敵[インダイレクトのみ]", "ActorModelDrawIndirectOnly", 8, ""},
{"[インダイレクト]", "ActorModelDrawIndirect", 32, ""},
{"[インダイレクトのみ]", "ActorModelDrawIndirectOnly", 8, ""},
{"アイテム[インダイレクト]", "ActorModelDrawIndirect", 32, "アイテム"},
{"アイテム[インダイレクトのみ]", "ActorModelDrawIndirectOnly", 32, "アイテム"},
{"プレイヤー装飾[インダイレクト]", "ActorModelDrawIndirect", 8, "プレイヤー"},
{"プレイヤー装飾[インダイレクトのみ]", "ActorModelDrawIndirectOnly", 8, "プレイヤー"},
{"アクター描画[インダイレクト]", "ActorDraw", 8, "アクター"},
// 3D(インダイレクト後フォワード)
{"半透明Zプリパス[インダイレクト後]", "ActorModelDrawDepthIndirect", 8, "地形"},
{"地形オブジェ[フォワードインダイレクト後のみ]", "ActorModelDrawForwardOnly", 8,
"地形オブジェ"},
{"敵[フォワードインダイレクト後]", "ActorModelDraw", 32, ""},
// 3D(インダイレクト後遠景)
{"大気散乱雲[インダイレクト後]", "ActorModelDraw", 8, "地形"},
{"大気散乱雲[インダイレクト後のみ]", "ActorModelDrawForwardOnly", 8, "地形"},
// 3D(フォグ後インダイレクト)
{"地形[インダイレクトフォグ後]", "ActorModelDrawIndirect", 8, "地形"},
{"地形[インダイレクトフォグ後のみ]", "ActorModelDrawIndirectOnly", 8, "地形"},
{"敵[インダイレクトフォグ後]", "ActorModelDrawIndirect", 8, ""},
{"敵[インダイレクトフォグ後のみ]", "ActorModelDrawIndirectOnly", 8, ""},
{"アイテム[インダイレクトフォグ後]", "ActorModelDrawIndirect", 32, "アイテム"},
{"アイテム[インダイレクトフォグ後のみ]", "ActorModelDrawIndirectOnly", 32, "アイテム"},
// 3D(フォグ後遠景)
{"遠景[フォグ後]", "ActorModelDraw", 8, "地形"},
{"遠景[フォグ後のみ]", "ActorModelDrawForwardOnly", 8, "地形"},
{"大気散乱雲[フォグ後]", "ActorModelDraw", 8, "地形"},
{"大気散乱雲[フォグ後のみ]", "ActorModelDrawForwardOnly", 8, "地形"},
// 3D(フォグ後)
{"半透明Zプリパス[フォグ後]", "ActorModelDrawDepthXlu", 8, "地形"},
{"地形[フォグ後]", "ActorModelDraw", 8, "地形"},
{"地形[フォグ後のみ]", "ActorModelDrawForwardOnly", 8, "地形"},
{"地形オブジェ[フォグ後]", "ActorModelDraw", 8, "地形オブジェ"},
{"地形オブジェ[フォグ後のみ]", "ActorModelDrawForwardOnly", 8, "地形オブジェ"},
{"敵[フォグ後]", "ActorModelDraw", 8, ""},
{"敵[フォグ後のみ]", "ActorModelDrawForwardOnly", 8, ""},
{"[フォグ後]", "ActorModelDraw", 8, ""},
{"[フォグ後のみ]", "ActorModelDrawForwardOnly", 8, ""},
// 3D(クロマキーZプリパス)
{"Zプリパス[プレイヤークロマキー]", "ActorModelDrawDepthChromakey", 208, "プレイヤー"},
{"Zプリパス[NPCクロマキー]", "ActorModelDrawDepthChromakey", 32, ""},
{"Zプリパス[ディザクロマキー]", "ActorModelDrawDitherChromakey", 208, "プレイヤー"},
// 3D(クロマキープレイヤー)
{"プレイヤー[クロマキー]", "ActorModelDrawPlayerChromakey", 208, "プレイヤー"},
{"プレイヤー[クロマキー不透明]", "ActorModelDrawPlayerChromakeyOpa", 208, "プレイヤー"},
{"プレイヤー[クロマキー半透明]", "ActorModelDrawPlayerChromakeyXlu", 64, "プレイヤー"},
// 3D(クロマキーキャラクター)
{"[クロマキー]", "ActorModelDrawCharacterChromakey", 32, ""},
// 2Dバック(メイン画面)
{"2Dバック", "LayoutDraw", 64, "レイアウト"},
// 2Dベース(メイン画面)
{"2Dベース", "LayoutDraw", 32, "レイアウト"},
{"2D情報バルーン", "LayoutDraw", 64, "レイアウト"},
{"2D会話バルーン", "LayoutDraw", 128, "レイアウト"},
{"", "LayoutDraw", 256, "レイアウト"},
{"2Dフィルターバルーン", "LayoutDraw", 64, "レイアウト"},
{"2Dフィルター", "LayoutDraw", 32, "レイアウト"},
{"2D(メイン画面のみ)", "LayoutDraw", 32, "レイアウト"},
{"2Dガイド", "LayoutDraw", 64, "レイアウト"},
{"2Dカウンター", "LayoutDraw", 32, "レイアウト"},
{"2Dマップアイコン", "LayoutDraw", 32, "レイアウト"},
{"2D通知", "LayoutDraw", 8, "レイアウト"},
// 2Dエフェクト(メイン画面)
{"2Dベースエフェクト", "Draw", 1, "エフェクト"},
// 2Dオーバー(メイン画面)
{"2Dヘッド", "LayoutDraw", 16, "レイアウト"},
{"2Dポーズ", "LayoutDraw", 32, "レイアウト"},
{"2Dランキング", "LayoutDraw", 4, "レイアウト"},
{"2Dライン", "LayoutDraw", 8, "レイアウト"},
{"2Dアイコン[最低]", "LayoutDraw", 32, "レイアウト"},
{"2Dアイコン[低]", "LayoutDraw", 32, "レイアウト"},
{"2Dアイコン[中]", "LayoutDraw", 16, "レイアウト"},
{"2Dアイコン[高]", "LayoutDraw", 356, "レイアウト"},
{"2Dアイコン[最高]", "LayoutDraw", 16, "レイアウト"},
{"2Dカーソル", "LayoutDraw", 12, "レイアウト"},
{"2Dリスト", "LayoutDraw", 12, "レイアウト"},
{"2Dリストアイコン", "LayoutDraw", 256, "レイアウト"},
{"2Dリストカーソル", "LayoutDraw", 8, "レイアウト"},
{"2Dゲームオーバー", "LayoutDraw", 8, "レイアウト"},
{"2Dカバー", "LayoutDraw", 8, "レイアウト"},
{"2Dエフェクト", "Draw", 1, "エフェクト"},
{"2Dワイプ[ウィンドウ前]", "LayoutDraw", 4, "レイアウト"},
{"2Dウィンドウ", "LayoutDraw", 24, "レイアウト"},
{"2Dウィンドウカウンター", "LayoutDraw", 8, "レイアウト"},
{"2Dワイプ", "LayoutDraw", 48, "レイアウト"},
{"2Dリザルト", "LayoutDraw", 4, "レイアウト"},
// 2D(デモ画面)
{"2Dデモベース", "LayoutDraw", 16, "レイアウト"},
{"2Dデモ", "LayoutDraw", 96, "レイアウト"},
{"2Dデモ情報バルーン", "LayoutDraw", 16, "レイアウト"},
{"2Dデモライン", "LayoutDraw", 8, "レイアウト"},
{"2Dデモアイコン", "LayoutDraw", 196, "レイアウト"},
{"2Dデモアイコンオーバー", "LayoutDraw", 128, "レイアウト"},
{"2Dデモアイコンプレイヤー", "LayoutDraw", 4, "レイアウト"},
{"2Dデモカーソル", "LayoutDraw", 8, "レイアウト"},
// ポストエフェクトマスク
{"ポストエフェクトマスク", "ActorModelDrawPostEffectMask", 32, "地形"},
// アクター描画(独自レンダーターゲット)
{"アクター描画[独自レンダーターゲット]", "ActorDraw", 8, "アクター"},
// アクター描画(プロジェクト固有)
{"アクター描画(プロジェクト固有)", "ActorDraw", 8, "アクター"},
// モデル描画バッファ更新
{"モデル描画バッファ更新", "ActorModelDrawUpdate", 1024, "システム"},
// 3D(ワールドマップディファード)
{"ワールドマップ地形", "ActorModelDrawDeferred", 128, "地形"},
{"ワールドマップ地形[ディファードのみ]", "ActorModelDrawDeferredOnly", 8, "地形"},
{"ワールドマップディファード空", "ActorModelDrawDeferredSky", 8, "地形"},
{"ワールドマップ地形[ディファード半透明]", "ActorModelDrawDeferredXlu", 16, "地形"},
// 3D(ワールドマップフォワード)
{"ワールドマップ地形[フォワード]", "ActorModelDraw", 32, "地形"},
{"ワールドマップ地形[フォワードのみ]", "ActorModelDrawForwardOnly", 8, "地形"},
{"ワールドマップ地形オブジェ[フォワード]", "ActorModelDraw", 8, "地形オブジェ"},
// 2D(ワールドマップ画面)
{"2Dワールドマップベース", "LayoutDraw", 32, "レイアウト"},
{"2Dワールドマップ", "LayoutDraw", 32, "レイアウト"},
// 2D(ムーンゲット画面)
{"2D(ムーンゲット)", "LayoutDraw", 8, "レイアウト"},
{"2Dカウンター(ムーンゲット)", "LayoutDraw", 1, "レイアウト"},
{"2Dワイプ(ムーンゲット)", "LayoutDraw", 4, "レイアウト"},
// 2D(スナップショット)
{"2Dスナップショット", "LayoutDraw", 3, "レイアウト"},
// 2D(撮影用)
{"2D撮影用", "LayoutDraw", 16, "レイアウト"},
// 2D(ミス)
{"2Dミス", "LayoutDraw", 2, "レイアウト"},
// Custom Entries
{"PuppetActor", "ActorModelDrawDeferred", 512, "ボス"}
};
static constexpr al::ExecuteOrder updateTableArr[] = {
// Update Table Name: 更新
{"ステージ同期カウンタ", "Execute", 1, "システム"},
{"乗り物(カメラ前)[Movement]", "ActorMovement", 8, "乗り物"},
{"カメラ前プレイヤー[Movement]", "ActorMovement", 16, "プレイヤー"},
{"カメラ前プレイヤー", "ActorMovementCalcAnim", 16, "プレイヤー"},
{"カメラ", "Execute", 1, "カメラ"},
{"クリッピング", "Execute", 1, "システム"},
{"センサー", "Execute", 1, "システム"},
{"試作用処理1", "Execute", 2, "システム"},
{"試作用処理2", "Execute", 8, "システム"},
{"試作用処理3", "Execute", 2, "システム"},
{"試作用処理4", "Execute", 1, "システム"},
{"", "ActorMovementCalcAnim", 16, "地形"},
{"", "ActorMovement", 16, "地形"},
{"遠景", "ActorMovementCalcAnim", 8, "地形"},
{"コリジョン地形", "ActorMovementCalcAnim", 256, "地形"},
{"コリジョン地形[デモ]", "ActorMovementCalcAnim", 64, "地形"},
{"コリジョン地形[Movement]", "ActorMovement", 32, "地形"},
{"コリジョン地形装飾", "ActorMovementCalcAnim", 32, "地形"},
{"コリジョン地形装飾[Movement]", "ActorMovement", 32, "地形"},
{"コリジョン地形オブジェ", "ActorMovementCalcAnim", 64, "地形オブジェ"},
{"コリジョン地形オブジェ[Movement]", "ActorMovement", 32, "地形オブジェ"},
{"コリジョンディレクター", "Execute", 1, "システム"},
{"地形オブジェ", "ActorMovementCalcAnim", 128, "地形オブジェ"},
{"地形オブジェ[Movement]", "ActorMovement", 32, "地形オブジェ"},
{"地形オブジェ装飾", "ActorMovementCalcAnim", 32, "地形オブジェ"},
{"乗り物", "ActorMovementCalcAnim", 32, "乗り物"},
{"エフェクトオブジェ", "ActorMovement", 32, "エフェクト"},
{"デモプレイヤーロケーター", "ActorMovementCalcAnim", 4, "プレイヤー"},
{"デモプレイヤー前処理", "ActorMovement", 16, "プレイヤー"},
{"プレイヤー前処理", "Functor", 1, "プレイヤー"},
{"プレイヤー[Movement]", "ActorMovement", 16, "プレイヤー"},
{"プレイヤー", "ActorMovementCalcAnim", 128, "プレイヤー"},
{"プレイヤー後処理", "Functor", 1, "プレイヤー"},
{"プレイヤー装飾", "ActorMovementCalcAnim", 64, "プレイヤー"},
{"プレイヤー装飾2", "ActorMovementCalcAnim", 64, "プレイヤー"},
{"帽子(武器)", "ActorMovementCalcAnim", 1, "アイテム"},
{"帽子(表示)", "ActorMovementCalcAnim", 16, "アイテム"},
{"", "ActorMovementCalcAnim", 128, ""},
{"敵[Movement]", "ActorMovement", 32, ""},
{"敵装飾", "ActorMovementCalcAnim", 32, ""},
{"敵装飾[Movement]", "ActorMovement", 32, ""},
{"デモ", "ActorMovementCalcAnim", 32, "地形"},
{"デモ装飾", "ActorMovementCalcAnim", 32, "地形"},
{"デモオブジェクト", "ActorMovement", 32, "地形"},
{"", "ActorMovementCalcAnim", 64, ""},
{"NPC装飾", "ActorMovementCalcAnim", 32, ""},
{"帽子装着位置更新", "Functor", 8, "システム"},
{"NPCイベントディレクター", "Execute", 1, "システム"},
{"エリア監視オブジェ", "Execute", 8, "システム"},
{"通知レイアウト更新", "Execute", 3, "システム"},
{"バルーン位置更新", "Execute", 1, "システム"},
{"ネットワーク", "Execute", 2, "システム"},
{"プレイヤーゴースト管理", "Execute", 1, "プレイヤー"},
{"エコーエミッター管理", "Execute", 1, "地形オブジェ"},
{"メッシュ変形モデル管理", "Execute", 1, "地形オブジェ"},
{"アイテム", "ActorMovementCalcAnim", 64, "アイテム"},
{"アイテム[デモ]", "ActorMovementCalcAnim", 64, "アイテム"},
{"アイテム[Movement]", "ActorMovement", 16, "アイテム"},
{"シャドウマスク", "ActorMovement", 64, ""},
{"グラフィックス要求者", "ActorMovement", 64, "システム"},
{"プロジェクト用グラフィックス", "Execute", 64, "システム"},
{"監視オブジェ", "ActorMovement", 32, "システム"},
{"キッズルートガイド管理", "ActorMovement", 1, "システム"},
{"キッズルートガイド", "ActorMovementCalcAnim", 4, "システム"},
{"サウンド制御", "ActorMovement", 10, "システム"},
{"ステージスイッチディレクター", "Execute", 1, "システム"},
{"", "LayoutUpdate", 404, "レイアウト"},
{"2D(ポーズ無視)", "LayoutUpdate", 360, "レイアウト"},
{"エフェクト(前処理)", "Functor", 1, "エフェクト"},
{"エフェクト(3D)", "Execute", 1, "エフェクト"},
{"エフェクト(プレイヤー)", "Execute", 1, "エフェクト"},
{"エフェクト(Zソート)", "Execute", 1, "エフェクト"},
{"エフェクト(カメラデモ)", "Execute", 1, "エフェクト"},
{"エフェクト(カメラ前エフェクト)", "Execute", 1, "エフェクト"},
{"エフェクト(ベース2D)", "Execute", 1, "エフェクト"},
{"エフェクト(2D)", "Execute", 1, "エフェクト"},
{"エフェクト(後処理)", "Functor", 1, "エフェクト"},
// Update Table Name: ビュー更新(コア1)
{"ビュー更新(コア1)", "ActorCalcView", 512, "システム"},
// Update Table Name: ビュー更新(コア2)
{"ビュー更新(コア2)", "ActorCalcView", 1024, "システム"},
// Update Table Name: スナップショット
{"スナップショット[CalcAnim]", "ActorCalcAnim", 16, "NPC"},
{"スナップショット[ActorMovement]", "ActorMovement", 1, "地形オブジェ"},
// Custom Tables
{"PuppetActor", "ActorMovementCalcAnim", 512, "ボス"}
};
static constexpr int getUpdateTableIndex(const char* listName) {
for (int i = 0; i < sizeof(updateTableArr) / sizeof(updateTableArr[0]); i++) {
if (std::string_view(updateTableArr[i].mListName)==listName) {
return i;
}
}
return 0;
}
static constexpr al::ExecuteTable createUpdateTable(const char* tableName, const char* startListName, const char* endListName) {
al::ExecuteTable drawTable;
drawTable.mName = tableName;
int startIndex = getUpdateTableIndex(startListName);
drawTable.mExecuteOrders = &updateTableArr[startIndex];
drawTable.mExecuteOrderCount = (getUpdateTableIndex(endListName) - startIndex) + 1;
return drawTable;
}
static constexpr int getDrawTableIndex(const char* listName, const char *groupName) {
for (int i = 0; i < sizeof(drawTableArr)/sizeof(drawTableArr[0]); i++) {
if (std::string_view(drawTableArr[i].mListName)==listName && std::string_view(drawTableArr[i].mExecuteGroup)==groupName) {
return i;
}
}
return 0;
}
static constexpr al::ExecuteTable createDrawTable(const char* tableName, const char* startListName, const char *groupStartName, const char* endListName, const char *groupEndName) {
al::ExecuteTable drawTable;
drawTable.mName = tableName;
int startIndex = getDrawTableIndex(startListName, groupStartName);
drawTable.mExecuteOrders = &drawTableArr[startIndex];
drawTable.mExecuteOrderCount = (getDrawTableIndex(endListName, groupEndName) - startIndex) + 1;
return drawTable;
}
constexpr al::ExecuteTable drawTable[] = {
createDrawTable("3D(カリング)", "カリング", "ActorModelDrawCulling", "カリング", "ActorModelDrawCulling"),
createDrawTable("3D(デプスシャドウ)", "デプスシャドウ[キャラクター]", "ActorModelDrawDepthShadow", "デプスシャドウ[独自]", "Functor"),
createDrawTable("3D(デプスシャドウプレイヤー)", "デプスシャドウ[プレイヤー]", "ActorModelDrawDepthShadow", "Mii[顔モデル](デプスシャドウ)", "Draw"),
createDrawTable("3D(スタティックデプスシャドウ)", "スタティックデプスシャドウ[地形]", "ActorModelDrawStaticDepthShadow", "スタティックデプスシャドウ[地形]", "ActorModelDrawStaticDepthShadow"),
createDrawTable("ワールドAo", "ワールドAo[地形]", "ActorModelDrawWorldAo", "ワールドAo[地形]", "ActorModelDrawWorldAo"),
createDrawTable("3D(海用デプス)", "海用デプス[浜辺]", "ActorModelDrawWorldAo", "海用デプス[高さ]", "ActorModelDrawWorldAo"),
createDrawTable("3D(空)", "", "ActorModelDraw", "", "ActorModelDraw"),
createDrawTable("3D(不透明Zプリパス)", "Zプリパス[カリング]", "ActorModelDrawDepthOnly", "プレイヤー", "ActorModelDrawDepthDither"),
createDrawTable("3D(ディファード地形)", "地形オブジェ[地形前]", "ActorModelDrawDeferred", "地形[埋没]", "ActorModelDrawDeferred"),
createDrawTable("3D(ディファード鏡映り込みなし)", "地形[鏡映り込みなし]", "ActorModelDrawDeferred", "地形[鏡映り込みなし]", "ActorModelDrawDeferred"),
createDrawTable("3D(ディファードキャラクター)", "シャドウマスク[地形オブジェ]", "Draw", "アイテム[ディファード不透明のみ]", "ActorModelDrawDeferredOpa"),
createDrawTable("3D(ディファード異空間)", "異空間オブジェ", "ActorModelDrawDeferred", "異空間オブジェ", "ActorModelDrawDeferred"),
createDrawTable("3D(ディファードプレイヤー)", "シャドウマスク[プレイヤー]", "Draw", "プレイヤー装飾[ディファード不透明のみ]", "ActorModelDrawDeferredOpa"),
createDrawTable("3D(ディファード中景)", "地形オブジェ[キャラ後]", "ActorModelDrawDeferred", "ディファード空[デモ]", "ActorModelDrawDeferredSky"),
createDrawTable("3D(ディファード半透明)", "地形[ディファード半透明]", "ActorModelDrawDeferredXlu", "アクター描画", "ActorDraw"),
createDrawTable("3D(デプスクリアプレイヤー)", "プレイヤー", "ActorModelDrawDepthForce", "プレイヤー装飾[インダイレクトのみ]", "ActorModelDrawDepthForce"),
createDrawTable("3D(フォワード遠景)", "遠景[ライトバッファ]", "ActorModelDraw", "大気散乱雲近距離[ライトバッファのみ]", "ActorModelDrawForwardOnly"),
createDrawTable("3D(フォワードプレイヤー)", "Zプリパス[プレイヤー]", "ActorModelDrawDepthOnly", "プレイヤー装飾[ディファード不透明のみ]", "ActorModelDrawForwardForce"),
createDrawTable("3D(フォワード)", "半透明Zプリパス", "ActorModelDrawDepthXlu", "アクター描画[フォワード]", "ActorDraw"),
createDrawTable("3D(インダイレクト)", "半透明Zプリパス[インダイレクト]", "ActorModelDrawDepthIndirect", "アクター描画[インダイレクト]", "ActorDraw"),
createDrawTable("3D(インダイレクト後フォワード)", "半透明Zプリパス[インダイレクト後]", "ActorModelDrawDepthIndirect", "敵[フォワードインダイレクト後]", "ActorModelDraw"),
createDrawTable("3D(インダイレクト後遠景)", "大気散乱雲[インダイレクト後]", "ActorModelDraw", "大気散乱雲[インダイレクト後のみ]", "ActorModelDrawForwardOnly"),
createDrawTable("3D(フォグ後インダイレクト)", "地形[インダイレクトフォグ後]", "ActorModelDrawIndirect", "アイテム[インダイレクトフォグ後のみ]", "ActorModelDrawIndirectOnly"),
createDrawTable("3D(フォグ後遠景)", "遠景[フォグ後]", "ActorModelDraw", "大気散乱雲[フォグ後のみ]", "ActorModelDrawForwardOnly"),
createDrawTable("3D(フォグ後)", "半透明Zプリパス[フォグ後]", "ActorModelDrawDepthXlu", "[フォグ後のみ]", "ActorModelDrawForwardOnly"),
createDrawTable("3D(クロマキーZプリパス)", "Zプリパス[プレイヤークロマキー]", "ActorModelDrawDepthChromakey", "Zプリパス[ディザクロマキー]", "ActorModelDrawDitherChromakey"),
createDrawTable("3D(クロマキープレイヤー)", "プレイヤー[クロマキー]", "ActorModelDrawPlayerChromakey", "プレイヤー[クロマキー半透明]", "ActorModelDrawPlayerChromakeyXlu"),
createDrawTable("3D(クロマキーキャラクター)", "[クロマキー]", "ActorModelDrawCharacterChromakey", "[クロマキー]", "ActorModelDrawCharacterChromakey"),
createDrawTable("2Dバック(メイン画面)", "2Dバック", "LayoutDraw", "2Dバック", "LayoutDraw"),
createDrawTable("2Dベース(メイン画面)", "2Dベース", "LayoutDraw", "2D通知", "LayoutDraw"),
createDrawTable("2Dエフェクト(メイン画面)", "2Dベースエフェクト", "Draw", "2Dベースエフェクト", "Draw"),
createDrawTable("2Dオーバー(メイン画面)", "2Dヘッド", "LayoutDraw", "2Dリザルト", "LayoutDraw"),
createDrawTable("2D(デモ画面)", "2Dデモベース", "LayoutDraw", "2Dデモカーソル", "LayoutDraw"),
createDrawTable("ポストエフェクトマスク", "ポストエフェクトマスク", "ActorModelDrawPostEffectMask", "ポストエフェクトマスク", "ActorModelDrawPostEffectMask"),
createDrawTable("アクター描画(独自レンダーターゲット)", "アクター描画[独自レンダーターゲット]", "ActorDraw", "アクター描画[独自レンダーターゲット]", "ActorDraw"),
createDrawTable("アクター描画(プロジェクト固有)", "アクター描画(プロジェクト固有)", "ActorDraw", "アクター描画(プロジェクト固有)", "ActorDraw"),
createDrawTable("モデル描画バッファ更新", "モデル描画バッファ更新", "ActorModelDrawUpdate", "モデル描画バッファ更新", "ActorModelDrawUpdate"),
createDrawTable("3D(ワールドマップディファード)", "ワールドマップ地形", "ActorModelDrawDeferred", "ワールドマップ地形[ディファード半透明]", "ActorModelDrawDeferredXlu"),
createDrawTable("3D(ワールドマップフォワード)", "ワールドマップ地形[フォワード]", "ActorModelDraw", "ワールドマップ地形オブジェ[フォワード]", "ActorModelDraw"),
createDrawTable("2D(ワールドマップ画面)", "2Dワールドマップベース", "LayoutDraw", "2Dワールドマップ", "LayoutDraw"),
createDrawTable("2D(ムーンゲット画面)", "2D(ムーンゲット)", "LayoutDraw", "2Dワイプ(ムーンゲット)", "LayoutDraw"),
createDrawTable("2D(スナップショット)", "2Dスナップショット", "LayoutDraw", "2Dスナップショット", "LayoutDraw"),
createDrawTable("2D(撮影用)", "2D撮影用", "LayoutDraw", "2D撮影用", "LayoutDraw"),
createDrawTable("2D(ミス)", "2Dミス", "LayoutDraw", "2Dミス", "LayoutDraw"),
// Custom Tables
createDrawTable("OnlineDrawExecutors", "PuppetActor", "ActorModelDrawDeferred", "PuppetActor", "ActorModelDrawDeferred"),
};
int drawTableSize = sizeof(drawTable)/sizeof(drawTable[0]);
constexpr al::ExecuteTable updateTable[] = {
createUpdateTable("更新", "ステージ同期カウンタ", "エフェクト(後処理)"),
createUpdateTable("ビュー更新(コア1)", "ビュー更新(コア1)", "ビュー更新(コア1)"),
createUpdateTable("ビュー更新(コア2)", "ビュー更新(コア2)", "ビュー更新(コア2)"),
createUpdateTable("スナップショット", "スナップショット[CalcAnim]", "スナップショット[ActorMovement]"),
// Custom Tables
createUpdateTable("OnlineUpdateExecutors", "PuppetActor", "PuppetActor"),
};
int updateTableSize = sizeof(updateTable)/sizeof(updateTable[0]);

View File

@ -1,26 +1,23 @@
#include <sys/types.h>
#include "al/execute/ExecuteDirector.h"
#include "al/execute/ExecuteOrder.h"
#include "al/execute/ExecuteTable.h"
#include "al/execute/ExecuteTableHolderDraw.h"
#include "al/execute/ExecuteTableHolderUpdate.h"
#include "al/scene/Scene.h"
#include "al/util/GraphicsUtil.h"
#include "al/util/KitUtil.h"
#include "basis/seadNew.h"
#include "logger.hpp"
#include "rs/util.hpp"
#include "server/Client.hpp"
#include "al/LiveActor/LiveActor.h"
#include "al/actor/ActorInitInfo.h"
#include "al/actor/Placement.h"
#include "al/byaml/ByamlIter.h"
#include "al/nerve/Nerve.h"
#include "al/nerve/NerveExecutor.h"
#include "al/nerve/NerveKeeper.h"
#include "al/util.hpp"
#include "al/util/ControllerUtil.h"
#include "al/util/LiveActorUtil.h"
#include "al/util/NerveUtil.h"
#include "game/Actors/WorldEndBorderKeeper.h"
#include "game/Layouts/CoinCounter.h"
#include "game/Player/Actions/PlayerActionGroundMoveControl.h"
#include "game/Player/PlayerActorHakoniwa.h"
#include "game/Player/PlayerConst.h"
#include "game/Player/States/PlayerStateRunHakoniwa.h"
#include "game/StageScene/StageSceneStateOption.h"
#include "game/StageScene/StageSceneStatePauseMenu.h"
#include "game/StageScene/StageSceneStateServerConfig.hpp"
#include "logger.hpp"
#include "main.hpp"
#include "al/byaml/writer/ByamlWriter.h"
#include "math/seadVector.h"
@ -74,7 +71,7 @@ bool saveReadHook(int* padRumbleInt, al::ByamlIter const& saveByml, char const*
bool registerShineToList(Shine* shineActor) {
if (shineActor->shineId >= 0) {
if (shineActor->mShineIdx >= 0) {
Client::tryRegisterShine(shineActor);
}
@ -169,3 +166,41 @@ bool borderPullBackHook(WorldEndBorderKeeper* thisPtr) {
return isFirstStep;
}
void drawTableHook(al::ExecuteDirector* thisPtr, const al::ExecuteSystemInitInfo &initInfo) {
thisPtr->mUpdateTableCount = updateTableSize;
thisPtr->mUpdateTables = new al::ExecuteTableHolderUpdate*[thisPtr->mUpdateTableCount]();
for (int i = 0; i < thisPtr->mUpdateTableCount; i++) {
thisPtr->mUpdateTables[i] = new al::ExecuteTableHolderUpdate();
const al::ExecuteTable &curTable = updateTable[i];
// Logger::log("Update Table Name: %s Count: %d\n", curTable.mName, curTable.mExecuteOrderCount);
thisPtr->mUpdateTables[i]->init(curTable.mName, initInfo, curTable.mExecuteOrders, curTable.mExecuteOrderCount);
}
thisPtr->mDrawTableCount = drawTableSize;
thisPtr->mDrawTables = new al::ExecuteTableHolderDraw*[thisPtr->mDrawTableCount]();
for (int i = 0; i < thisPtr->mDrawTableCount; i++) {
thisPtr->mDrawTables[i] = new al::ExecuteTableHolderDraw();
const al::ExecuteTable* curTable = &drawTable[i];
// Logger::log("Draw Table Name: %s Count: %d\n", curTable->mName, curTable->mExecuteOrderCount);
thisPtr->mDrawTables[i]->init(curTable->mName, initInfo, curTable->mExecuteOrders, curTable->mExecuteOrderCount);
}
thisPtr->mRequestKeeper = new al::ExecuteRequestKeeper(thisPtr->mRequestMax);
}
void updateStateHook(al::Scene* scene) {
al::executeUpdateList(scene->mActorKit, "OnlineUpdateExecutors", "PuppetActor");
rs::updateEffectSystemEnv(scene);
}
void updateDrawHook(al::ExecuteDirector* thisPtr, const char* listName, const char* kit) {
thisPtr->drawList("OnlineDrawExecutors", "PuppetActor");
Logger::log("Updating Draw List for: %s %s\n", listName, kit);
thisPtr->drawList(listName, kit);
}

View File

@ -1,9 +1,16 @@
#include "main.hpp"
#include <cmath>
#include <math.h>
#include "al/execute/ExecuteOrder.h"
#include "al/execute/ExecuteTable.h"
#include "al/execute/ExecuteTableHolderDraw.h"
#include "al/util/GraphicsUtil.h"
#include "container/seadSafeArray.h"
#include "game/GameData/GameDataHolderAccessor.h"
#include "game/Player/PlayerActorBase.h"
#include "game/Player/PlayerActorHakoniwa.h"
#include "game/Player/PlayerHackKeeper.h"
#include "heap/seadHeap.h"
#include "math/seadVector.h"
#include "server/Client.hpp"
#include "puppets/PuppetInfo.h"
@ -78,14 +85,14 @@ void drawMainHook(HakoniwaSequence *curSequence, sead::Viewport *viewport, sead:
// Application::sInstance->mFramework->mGpuPerf->drawResult((agl::DrawContext *)drawContext, frameBuffer);
// }
Time::calcTime(); // this needs to be ran every frame, so running it here works
Time::calcTime(); // this needs to be ran every frame, so running it here works
if(!debugMode) {
al::executeDraw(curSequence->mLytKit, "2Dバック(メイン画面)");
return;
}
//int dispWidth = al::getLayoutDisplayWidth();
// int dispWidth = al::getLayoutDisplayWidth();
int dispHeight = al::getLayoutDisplayHeight();
gTextWriter->mViewport = viewport;
@ -102,10 +109,21 @@ void drawMainHook(HakoniwaSequence *curSequence, sead::Viewport *viewport, sead:
gTextWriter->setCursorFromTopLeft(sead::Vector2f(10.f, (dispHeight / 3) + 30.f));
gTextWriter->setScaleFromFontHeight(20.f);
sead::Heap* clientHeap = Client::getClientHeap();
sead::Heap *gmHeap = GameModeManager::instance()->getHeap();
if (clientHeap) {
gTextWriter->printf("Client Heap Free Size: %f/%f\n", clientHeap->getFreeSize() * 0.001f, clientHeap->getSize() * 0.001f);
gTextWriter->printf("Gamemode Heap Free Size: %f/%f\n", gmHeap->getFreeSize() * 0.001f, gmHeap->getSize()* 0.001f);
}
gTextWriter->printf("Client Socket Connection Status: %s\n", Client::instance()->mSocket->getStateChar());
gTextWriter->printf("nn::socket::GetLastErrno: 0x%x\n", Client::instance()->mSocket->socket_errno);
gTextWriter->printf("Packet Queue Length: %d\n", Client::instance()->mSocket->mPacketQueue.size());
gTextWriter->printf("Total Connected Players: %d\n", Client::getConnectCount() + 1);
gTextWriter->printf("Udp socket status: %s\n", Client::instance()->mSocket->getUdpStateChar());
//gTextWriter->printf("nn::socket::GetLastErrno: 0x%x\n", Client::instance()->mSocket->socket_errno);
gTextWriter->printf("Connected Players: %d/%d\n", Client::getConnectCount() + 1, Client::getMaxPlayerCount());
gTextWriter->printf("Send Queue Count: %d/%d\n", Client::instance()->mSocket->getSendCount(), Client::instance()->mSocket->getSendMaxCount());
gTextWriter->printf("Recv Queue Count: %d/%d\n", Client::instance()->mSocket->getRecvCount(), Client::instance()->mSocket->getRecvMaxCount());
al::Scene *curScene = curSequence->curScene;
@ -142,31 +160,33 @@ void drawMainHook(HakoniwaSequence *curSequence, sead::Viewport *viewport, sead:
PuppetInfo* curPupInfo = curPuppet->getInfo();
// al::LiveActor *curCapture = curPuppet->getCapture(debugCaptureIndex);
if (curModel && curPupInfo) {
// al::LiveActor *curCapture = curPuppet->getCapture(debugCaptureIndex);
gTextWriter->printf("Puppet Index: %d\n", debugPuppetIndex);
gTextWriter->printf("Player Name: %s\n", curPupInfo->puppetName);
gTextWriter->printf("Connection Status: %s\n", curPupInfo->isConnected ? "Online" : "Offline");
gTextWriter->printf("Is in Same Stage: %s\n", curPupInfo->isInSameStage ? "True" : "False");
gTextWriter->printf("Is in Capture: %s\n", curPupInfo->isCaptured ? "True" : "False");
gTextWriter->printf("Puppet Stage: %s\n", curPupInfo->stageName);
gTextWriter->printf("Puppet Scenario: %u\n", curPupInfo->scenarioNo);
gTextWriter->printf("Puppet Costume: H: %s B: %s\n", curPupInfo->costumeHead, curPupInfo->costumeBody);
//gTextWriter->printf("Packet Coords:\nX: %f\nY: %f\nZ: %f\n", curPupInfo->playerPos.x, curPupInfo->playerPos.y, curPupInfo->playerPos.z);
// if (curModel) {
// sead::Vector3f* pupPos = al::getTrans(curModel);
// gTextWriter->printf("In-Game Coords:\nX: %f\nY: %f\nZ: %f\n", pupPos->x, pupPos->y, pupPos->z);
// }
gTextWriter->printf("Puppet Index: %d\n", debugPuppetIndex);
gTextWriter->printf("Player Name: %s\n", curPupInfo->puppetName);
gTextWriter->printf("Connection Status: %s\n", curPupInfo->isConnected ? "Online" : "Offline");
gTextWriter->printf("Is in Same Stage: %s\n", curPupInfo->isInSameStage ? "True" : "False");
gTextWriter->printf("Is in Capture: %s\n", curPupInfo->isCaptured ? "True" : "False");
gTextWriter->printf("Puppet Stage: %s\n", curPupInfo->stageName);
gTextWriter->printf("Puppet Scenario: %u\n", curPupInfo->scenarioNo);
gTextWriter->printf("Puppet Costume: H: %s B: %s\n", curPupInfo->costumeHead, curPupInfo->costumeBody);
//gTextWriter->printf("Packet Coords:\nX: %f\nY: %f\nZ: %f\n", curPupInfo->playerPos.x, curPupInfo->playerPos.y, curPupInfo->playerPos.z);
// if (curModel) {
// sead::Vector3f* pupPos = al::getTrans(curModel);
// gTextWriter->printf("In-Game Coords:\nX: %f\nY: %f\nZ: %f\n", pupPos->x, pupPos->y, pupPos->z);
// }
if(curPupInfo->isCaptured) {
gTextWriter->printf("Current Capture: %s\n", curPupInfo->curHack);
gTextWriter->printf("Current Packet Animation: %s\n", curPupInfo->curAnimStr);
gTextWriter->printf("Animation Index: %d\n", curPupInfo->curAnim);
}else {
gTextWriter->printf("Current Packet Animation: %s\n", curPupInfo->curAnimStr);
gTextWriter->printf("Animation Index: %d\n", curPupInfo->curAnim);
if (curModel) {
gTextWriter->printf("Current Animation: %s\n", al::getActionName(curModel));
if(curPupInfo->isCaptured) {
gTextWriter->printf("Current Capture: %s\n", curPupInfo->curHack);
gTextWriter->printf("Current Packet Animation: %s\n", curPupInfo->curAnimStr);
gTextWriter->printf("Animation Index: %d\n", curPupInfo->curAnim);
}else {
gTextWriter->printf("Current Packet Animation: %s\n", curPupInfo->curAnimStr);
gTextWriter->printf("Animation Index: %d\n", curPupInfo->curAnim);
if (curModel) {
gTextWriter->printf("Current Animation: %s\n", al::getActionName(curModel));
}
}
}
}
@ -253,10 +273,14 @@ void drawMainHook(HakoniwaSequence *curSequence, sead::Viewport *viewport, sead:
}
void sendShinePacket(GameDataHolderWriter thisPtr, Shine* curShine) {
void sendShinePacket(GameDataHolderAccessor thisPtr, Shine* curShine) {
if (!curShine->isGot()) {
Client::sendShineCollectPacket(curShine->shineId);
GameDataFile::HintInfo* curHintInfo =
&thisPtr.mData->mGameDataFile->mShineHintList[curShine->mShineIdx];
Client::sendShineCollectPacket(curHintInfo->mUniqueID);
}
GameDataFunction::setGotShine(thisPtr, curShine->curShineInfo);
@ -331,11 +355,7 @@ bool hakoniwaSequenceHook(HakoniwaSequence* sequence) {
GameModeManager::instance()->setPaused(stageScene->isPause());
Client::setStageInfo(stageScene->mHolder);
Client::updateStates();
if (Client::isNeedUpdateShines()) {
Client::updateShines();
}
Client::update();
updatePlayerInfo(stageScene->mHolder, playerBase, isYukimaru);

View File

@ -1,6 +1,9 @@
#include <cmath>
#include <cstddef>
#include "al/model/PartsModel.h"
#include "al/util/SensorUtil.h"
#include "game/Player/PlayerCostumeFunction.h"
#include "game/Player/PlayerCostumeInfo.h"
#include "rs/util/SensorUtil.h"
#include "server/Client.hpp"
#include "al/LiveActor/LiveActor.h"
@ -52,7 +55,7 @@ void PuppetActor::init(al::ActorInitInfo const &initInfo) {
al::LiveActor *normalModel = new al::LiveActor("Normal");
mCostumeInfo = PlayerFunction::initMarioModelCommon(normalModel, initInfo, bodyName, capName, 0, false, nullptr, false, false);
mCostumeInfo = initMarioModelPuppet(normalModel, initInfo, bodyName, capName, 0, nullptr);
normalModel->mActorActionKeeper->mPadAndCamCtrl->mRumbleCount = 0; // set rumble count to zero so that no rumble actions will run
@ -100,6 +103,10 @@ void PuppetActor::movement() {
al::LiveActor::movement();
}
void PuppetActor::calcAnim() {
al::LiveActor::calcAnim();
}
void PuppetActor::control() {
if(mInfo) {
@ -405,4 +412,217 @@ void PuppetActor::emitJoinEffect() {
al::tryDeleteEffect(this, "Disappear"); // remove previous effect (if played previously)
al::tryEmitEffect(this, "Disappear", nullptr);
}
const char *executorName = "";
PlayerCostumeInfo* initMarioModelPuppet(al::LiveActor* player,
const al::ActorInitInfo& initInfo,
const char* bodyName, const char* capName,
int subActorNum,
al::AudioKeeper* audioKeeper) {
// Logger::log("Loading Resources for Mario Puppet Model.\n");
al::ActorResource* modelRes = al::findOrCreateActorResourceWithAnimResource(
initInfo.mResourceHolder, al::StringTmp<0x100>("ObjectData/%s", bodyName).cstr(),
al::StringTmp<0x100>("ObjectData/%s", "PlayerAnimation").cstr(), 0, false);
// Logger::log("Creating Body Costume Info.\n");
PlayerBodyCostumeInfo* bodyInfo =
PlayerCostumeFunction::createBodyCostumeInfo(modelRes->mResourceModel, bodyName);
// Logger::log("Initializing Basic Actor Data.\n");
al::initActorSceneInfo(player, initInfo);
al::initActorPoseTQGSV(player);
al::initActorSRT(player, initInfo);
al::initActorModelKeeper(player, initInfo,
al::StringTmp<0x100>("ObjectData/%s", bodyName).cstr(), 6,
al::StringTmp<0x100>("ObjectData/%s", "PlayerAnimation").cstr());
// Logger::log("Creating Material Category for Player Type\n");
al::ModelMaterialCategory::tryCreate(
player->mModelKeeper->mModelCtrl, "Player",
initInfo.mActorSceneInfo.mGfxSysInfo->mMaterialCategoryKeeper);
// Logger::log("Initing Skeleton.\n");
al::initPartialSklAnim(player, 1, 1, 32);
al::addPartialSklAnimPartsListRecursive(player, "Spine1", 0);
// Logger::log("Setting Up Executor Info.\n");
al::initExecutorUpdate(player, initInfo, executorName);
al::initExecutorDraw(player, initInfo, executorName);
al::initExecutorModelUpdate(player, initInfo);
// Logger::log("Getting InitEffect Byml from resource.\n");
al::ByamlIter iter;
if (al::tryGetActorInitFileIter(&iter, modelRes->mResourceModel, "InitEffect", 0)) {
const char *effectKeeperName;
if (iter.tryGetStringByKey(&effectKeeperName, "Name")) {
// Logger::log("Initializing Effect Keeper.\n");
al::initActorEffectKeeper(player, initInfo, effectKeeperName);
}
}
// Logger::log("Initing Player Audio.\n");
PlayerFunction::initMarioAudio(player, initInfo, modelRes->mResourceModel, false, audioKeeper);
al::initActorActionKeeper(player, modelRes, bodyName, 0);
al::setMaterialProgrammable(player);
// Logger::log("Creating Sub-Actor Keeper.\n");
al::SubActorKeeper* actorKeeper = al::SubActorKeeper::tryCreate(player, 0, subActorNum);
if (actorKeeper) {
player->initSubActorKeeper(actorKeeper);
}
actorKeeper->init(initInfo, 0, subActorNum);
// Logger::log("Initializing Sub-Actors.\n");
int subModelNum = al::getSubActorNum(player);
if (subModelNum >= 1) {
for (int i = 0; i < subModelNum; i++) {
al::LiveActor* subActor = al::getSubActor(player, i);
const char* actorName = subActor->getName();
if (!al::isEqualString(actorName, "シルエットモデル")) {
al::initExecutorUpdate(subActor, initInfo, executorName);
al::initExecutorDraw(subActor, initInfo, executorName);
al::setMaterialProgrammable(subActor);
}
}
}
// Logger::log("Creating Clipping.\n");
al::initActorClipping(player, initInfo);
al::invalidateClipping(player);
// Logger::log("Getting Cap Model/Head Model Name.\n");
const char *capModelName;
if (bodyInfo->mIsUseHeadSuffix) {
if (al::isEqualString(bodyInfo->costumeName, capName)) {
capModelName = "";
} else {
capModelName = capName;
}
} else {
capModelName = "";
}
const char *headType;
if (!al::isEqualSubString(capName, "Mario64")) {
if (bodyInfo->mIsUseShortHead && al::isEqualString(capName, "MarioPeach")) {
headType = "Short";
} else {
headType = "";
}
} else if (al::isEqualString(bodyInfo->costumeName, "Mario64")) {
headType = "";
} else if (al::isEqualString(bodyInfo->costumeName, "Mario64Metal")) {
headType = "Metal";
} else {
headType = "Other";
}
// Logger::log("Creating Head Costume Info. Cap Model: %s. Head Type: %s. Cap Name: %s.\n", capModelName, headType, capName);
PlayerHeadCostumeInfo* headInfo = initMarioHeadCostumeInfo(
player, initInfo, "", capName, headType, capModelName);
// Logger::log("Creating Costume Info.\n");
PlayerCostumeInfo* costumeInfo = new PlayerCostumeInfo();
costumeInfo->init(bodyInfo, headInfo);
if (costumeInfo->isNeedBodyHair()) {
Logger::log("Creating Body Hair Parts Model.\n");
al::PartsModel* partsModel = new al::PartsModel("");
partsModel->initPartsFixFile(
player, initInfo,
al::StringTmp<0x100>("%sHair%s", bodyName,
costumeInfo->isEnableHairNoCap() ? "NoCap" : "")
.cstr(),
0, "Hair");
al::initExecutorUpdate(partsModel, initInfo, executorName);
al::initExecutorDraw(partsModel, initInfo, executorName);
al::setMaterialProgrammable(partsModel);
partsModel->makeActorDead();
al::onSyncAppearSubActor(player, partsModel);
al::onSyncClippingSubActor(player, partsModel);
al::onSyncAlphaMaskSubActor(player, partsModel);
al::onSyncHideSubActor(player, partsModel);
}
// Logger::log("Initing Depth Model.\n");
PlayerFunction::initMarioDepthModel(player, false, false);
// Logger::log("Creating Retarget Info.\n");
rs::createPlayerSklRetargettingInfo(player, sead::Vector3f::ones);
// Logger::log("Making Player Model Dead.\n");
player->makeActorDead();
return costumeInfo;
}
PlayerHeadCostumeInfo* initMarioHeadCostumeInfo(al::LiveActor* player,
const al::ActorInitInfo &initInfo,
const char* headModelName, const char* capModelName,
const char* headType, const char* headSuffix) {
al::PartsModel* headModel = new al::PartsModel(headModelName);
al::StringTmp<0x80> headArcName("%sHead%s", capModelName, headType);
al::StringTmp<0x100> arcSuffix("Head");
if (headSuffix) arcSuffix.format("Head%s", headSuffix);
headModel->initPartsFixFile(player, initInfo, headArcName.cstr(), 0, arcSuffix.cstr());
al::setMaterialProgrammable(headModel);
al::initExecutorUpdate(headModel, initInfo, executorName);
al::initExecutorDraw(headModel, initInfo, executorName);
headModel->makeActorDead();
al::onSyncAppearSubActor(player, headModel);
al::onSyncClippingSubActor(player, headModel);
al::onSyncAlphaMaskSubActor(player, headModel);
al::onSyncHideSubActor(player, headModel);
al::PartsModel* capEyesModel = new al::PartsModel("キャップの目");
capEyesModel->initPartsFixFile(headModel, initInfo, "CapManHeroEyes", "", 0);
al::onSyncClippingSubActor(headModel, capEyesModel);
al::onSyncAlphaMaskSubActor(headModel, capEyesModel);
al::onSyncHideSubActor(headModel, capEyesModel);
al::setMaterialProgrammable(headModel);
headModel->makeActorDead();
return PlayerCostumeFunction::createHeadCostumeInfo(al::getModelResource(headModel), capModelName, false);
}

View File

@ -17,7 +17,7 @@ PuppetHolder::PuppetHolder(int size) {
* @brief resizes puppet ptr array by creating a new ptr array and storing previous ptrs in it, before freeing the previous array
*
* @param size the size of the new ptr array
* @return returns true if resizing was sucessful
* @return returns true if resizing was successful
*/
bool PuppetHolder::resizeHolder(int size) {
@ -106,4 +106,4 @@ bool PuppetHolder::checkInfoIsInStage(PuppetInfo *info) {
void PuppetHolder::setStageInfo(const char *stageName, u8 scenarioNo) {
mStageName = stageName;
mScenarioNo = scenarioNo;
}
}

View File

@ -151,14 +151,14 @@ void operator delete[](void* ptr, sead::Heap*, const std::nothrow_t&) noexcept
// operator delete(void*, sead::Heap*, s32)
void operator delete(void* ptr, sead::Heap*, s32)
void operator delete(void* ptr, sead::Heap* heap, s32)
{
sead::system::DeleteImpl(ptr);
heap->free(ptr);
}
void operator delete[](void* ptr, sead::Heap*, s32)
void operator delete[](void* ptr, sead::Heap*heap, s32)
{
sead::system::DeleteImpl(ptr);
heap->free(ptr);
}
void operator delete(void* ptr, sead::Heap*, s32, const std::nothrow_t&) noexcept

File diff suppressed because it is too large Load Diff

View File

@ -6,8 +6,11 @@
SocketBase::SocketBase(const char *name)
{
strcpy(this->sockName, name);
#if EMU
this->sock_flags = 0x80;
#else
this->sock_flags = 0;
#endif
}
const char *SocketBase::getStateChar() {
@ -69,12 +72,13 @@ s32 SocketBase::getFd() {
bool SocketBase::closeSocket() {
this->socket_log_state = SOCKET_LOG_DISCONNECTED; // probably not safe to assume socket will be closed
if (this->socket_log_state != SOCKET_LOG_DISCONNECTED) {
nn::Result result = nn::socket::Close(this->socket_log_socket);
if (result.isSuccess()) {
this->socket_log_state = SOCKET_LOG_DISCONNECTED;
}
return result.isSuccess();
}
nn::Result result = nn::socket::Close(this->socket_log_socket);
return result.isSuccess();
return true;
}

View File

@ -1,14 +1,36 @@
#include "server/SocketClient.hpp"
#include <cstdlib>
#include <cstring>
#include <basis/seadNew.h>
#include "SocketBase.hpp"
#include "al/async/FunctorV0M.hpp"
#include "logger.hpp"
#include "nn/result.h"
#include "nn/socket.h"
#include "packets/Packet.h"
#include "packets/UdpPacket.h"
#include "server/Client.hpp"
#include "thread/seadMessageQueue.h"
#include "types.h"
SocketClient::SocketClient(const char* name, sead::Heap* heap, Client* client) : mHeap(heap), SocketBase(name) {
this->client = client;
#if EMU
this->pollTime = 0;
#else
this->pollTime = -1;
#endif
mRecvThread = new al::AsyncFunctorThread("SocketRecvThread", al::FunctorV0M<SocketClient*, SocketThreadFunc>(this, &SocketClient::recvFunc), 0, 0x1000, {0});
mSendThread = new al::AsyncFunctorThread("SocketSendThread", al::FunctorV0M<SocketClient*, SocketThreadFunc>(this, &SocketClient::sendFunc), 0, 0x1000, {0});
mRecvQueue.allocate(maxBufSize, mHeap);
mSendQueue.allocate(maxBufSize, mHeap);
recvBuf = (char*)mHeap->alloc(MAXPACKSIZE+1);
};
nn::Result SocketClient::init(const char* ip, u16 port) {
this->sock_ip = ip;
@ -16,6 +38,7 @@ nn::Result SocketClient::init(const char* ip, u16 port) {
in_addr hostAddress = { 0 };
sockaddr serverAddress = { 0 };
sockaddr udpAddress = { 0 };
Logger::log("SocketClient::init: %s:%d sock %s\n", ip, port, getStateChar());
@ -65,56 +88,205 @@ nn::Result SocketClient::init(const char* ip, u16 port) {
return result;
}
if ((this->mUdpSocket = nn::socket::Socket(2, 2, 17)) < 0) {
Logger::log("Udp Socket failed to create");
this->socket_errno = nn::socket::GetLastErrno();
this->socket_log_state = SOCKET_LOG_UNAVAILABLE;
return -1;
}
udpAddress.address = hostAddress;
udpAddress.port = 0;
udpAddress.family = 2;
this->mUdpAddress = udpAddress;
this->mHasRecvUdp = false;
this->mPacketQueueOpen = true;
this->socket_log_state = SOCKET_LOG_CONNECTED;
Logger::log("Socket fd: %d\n", socket_log_socket);
startThreads(); // start recv and send threads after succesful connection
// send init packet to server once we connect (an issue with the server prevents this from working properly, waiting for a fix to implement)
PlayerConnect initPacket;
initPacket.mUserID = Client::getClientId();
strcpy(initPacket.clientName, Client::getUsername().cstr());
if (mIsFirstConnect) {
initPacket.conType = ConnectionTypes::INIT;
mIsFirstConnect = false;
} else {
initPacket.conType = ConnectionTypes::RECONNECT;
}
send(&initPacket);
// on a reconnect, resend some maybe missing packets
if (initPacket.conType == ConnectionTypes::RECONNECT) {
client->resendInitPackets();
} else {
// empty TagInf
TagInf tagInf;
tagInf.mUserID = initPacket.mUserID;
tagInf.isIt = false;
tagInf.minutes = 0;
tagInf.seconds = 0;
tagInf.updateType = static_cast<TagUpdateType>(TagUpdateType::STATE | TagUpdateType::TIME);
send(&tagInf);
// empty CaptureInf
CaptureInf capInf;
capInf.mUserID = initPacket.mUserID;
strcpy(capInf.hackName, "");
send(&capInf);
}
return result;
}
bool SocketClient::SEND(Packet *packet) {
u16 SocketClient::getLocalUdpPort() {
sockaddr udpAddress = { 0 };
u32 size = sizeof(udpAddress);
if (this->socket_log_state != SOCKET_LOG_CONNECTED)
nn::Result result;
if((result = nn::socket::GetSockName(this->mUdpSocket, &udpAddress, &size)).isFailure()) {
this->socket_errno = nn::socket::GetLastErrno();
return 0;
}
return nn::socket::InetNtohs(udpAddress.port);
}
s32 SocketClient::setPeerUdpPort(u16 port) {
u16 net_port = nn::socket::InetHtons(port);
this->mUdpAddress.port = net_port;
nn::Result result;
if((result = nn::socket::Connect(this->mUdpSocket, &this->mUdpAddress, sizeof(this->mUdpAddress))).isFailure()) {
Logger::log("Udp socket connection failed to connect to port %d!\n", port);
this->socket_errno = nn::socket::GetLastErrno();
return -1;
}
return 0;
}
const char* SocketClient::getUdpStateChar() {
if (this->mUdpAddress.port == 0) {
return "Waiting for handshake";
}
if (!this->mHasRecvUdp) {
return "Waiting for holepunch";
}
return "Utilizing UDP";
}
bool SocketClient::send(Packet *packet) {
if (this->socket_log_state != SOCKET_LOG_CONNECTED || packet == nullptr)
return false;
char* buffer = reinterpret_cast<char*>(packet);
int valread = 0;
if (packet->mType != PLAYERINF && packet->mType != HACKCAPINF)
Logger::log("Sending packet: %s\n", packetNames[packet->mType]);
int fd = -1;
if ((packet->mType != PLAYERINF && packet->mType != HACKCAPINF && packet->mType != HOLEPUNCH)
|| (!this->mHasRecvUdp && packet->mType != HOLEPUNCH)
|| this->mUdpAddress.port == 0) {
if ((valread = nn::socket::Send(this->socket_log_socket, buffer, packet->mPacketSize + sizeof(Packet), 0) > 0)) {
if (packet->mType != PLAYERINF && packet->mType != HACKCAPINF) {
Logger::log("Sending packet: %s\n", packetNames[packet->mType]);
}
fd = this->socket_log_socket;
} else {
fd = this->mUdpSocket;
}
if ((valread = nn::socket::Send(fd, buffer, packet->mPacketSize + sizeof(Packet), 0) > 0)) {
return true;
} else {
Logger::log("Failed to Fully Send Packet! Result: %d Type: %s Packet Size: %d\n", valread, packetNames[packet->mType], packet->mPacketSize);
this->socket_errno = nn::socket::GetLastErrno();
this->closeSocket();
return false;
return this->tryReconnect();
}
return true;
}
bool SocketClient::RECV() {
bool SocketClient::recv() {
if (this->socket_log_state != SOCKET_LOG_CONNECTED) {
Logger::log("Unable To Receive! Socket Not Connected.\n");
this->socket_errno = nn::socket::GetLastErrno();
return false;
return this->tryReconnect();
}
const int fd_count = 2;
struct pollfd pfds[fd_count] = {{0}, {0}};
// TCP Connection
pfds[0].fd = this->socket_log_socket;
pfds[0].events = 1;
pfds[0].revents = 0;
// UDP Connection
pfds[1].fd = this->mUdpSocket;
pfds[1].events = 1;
pfds[1].revents = 0;
int result = nn::socket::Poll(pfds, fd_count, this->pollTime);
if (result == 0) {
return true;
} else if (result < 0) {
Logger::log("Error occurred when polling for packets\n");
this->socket_errno = nn::socket::GetLastErrno();
return this->tryReconnect();
}
s32 index = -1;
for (int i = 0; i < fd_count; i++){
if (pfds[i].revents & 1) {
index = i;
break;
}
}
switch (index) {
case 0:
return recvTcp();
case 1:
return recvUdp();
default:
return true;
}
}
bool SocketClient::recvTcp() {
int headerSize = sizeof(Packet);
char headerBuf[sizeof(Packet)] = {};
int valread = 0;
s32 fd = this->socket_log_socket;
// read only the size of a header
while(valread < headerSize) {
int result = nn::socket::Recv(this->socket_log_socket, headerBuf + valread,
headerSize - valread, this->sock_flags);
int result = 0;
result = nn::socket::Recv(fd, recvBuf + valread,
headerSize - valread, this->sock_flags);
this->socket_errno = nn::socket::GetLastErrno();
if(result > 0) {
valread += result;
} else {
@ -122,74 +294,125 @@ bool SocketClient::RECV() {
return true;
} else {
Logger::log("Header Read Failed! Value: %d Total Read: %d\n", result, valread);
this->closeSocket();
return false;
return this->tryReconnect();
}
}
}
if(valread > 0) {
Packet* header = reinterpret_cast<Packet*>(headerBuf);
int fullSize = header->mPacketSize + sizeof(Packet);
if (header->mType > PacketType::UNKNOWN && header->mType < PacketType::End &&
fullSize <= MAXPACKSIZE && fullSize > 0 && valread == sizeof(Packet)) {
if (header->mType != PLAYERINF && header->mType != HACKCAPINF) {
Logger::log("Received packet (from %02X%02X):", header->mUserID.data[0],
header->mUserID.data[1]);
Logger::disableName();
Logger::log(" Size: %d", header->mPacketSize);
Logger::log(" Type: %d", header->mType);
if(packetNames[header->mType])
Logger::log(" Type String: %s\n", packetNames[header->mType]);
Logger::enableName();
}
char* packetBuf = (char*)malloc(fullSize);
if (packetBuf) {
memcpy(packetBuf, headerBuf, sizeof(Packet));
while (valread < fullSize) {
int result = nn::socket::Recv(this->socket_log_socket, packetBuf + valread,
fullSize - valread, this->sock_flags);
this->socket_errno = nn::socket::GetLastErrno();
if (result > 0) {
valread += result;
} else {
free(packetBuf);
Logger::log("Packet Read Failed! Value: %d\nPacket Size: %d\nPacket Type: %s\n", result, header->mPacketSize, packetNames[header->mType]);
this->closeSocket();
return false;
}
}
Packet *packet = reinterpret_cast<Packet*>(packetBuf);
if(mPacketQueue.size() < maxBufSize - 1) {
mPacketQueue.pushBack(packet);
} else {
free(packetBuf);
}
}
} else {
Logger::log("Failed to aquire valid data! Packet Type: %d Full Packet Size %d valread size: %d", header->mType, fullSize, valread);
}
return true;
} else { // if we error'd, close the socket
if(valread <= 0) { // if we error'd, close the socket
Logger::log("valread was zero! Disconnecting.\n");
this->socket_errno = nn::socket::GetLastErrno();
this->closeSocket();
return false;
return this->tryReconnect();
}
Packet* header = reinterpret_cast<Packet*>(recvBuf);
int fullSize = header->mPacketSize + sizeof(Packet);
if (!(fullSize <= MAXPACKSIZE && fullSize > 0 && valread == sizeof(Packet))) {
Logger::log("Failed to acquire valid data! Packet Type: %d Full Packet Size %d valread size: %d\n", header->mType, fullSize, valread);
return true;
}
if (header->mType != PLAYERINF && header->mType != HACKCAPINF) {
Logger::log("Received packet (from %02X%02X):", header->mUserID.data[0],
header->mUserID.data[1]);
Logger::disableName();
Logger::log(" Size: %d", header->mPacketSize);
Logger::log(" Type: %d", header->mType);
if(packetNames[header->mType])
Logger::log(" Type String: %s\n", packetNames[header->mType]);
Logger::enableName();
}
char* packetBuf = (char*)mHeap->alloc(fullSize);
if (!packetBuf) {
return true;
}
memcpy(packetBuf, recvBuf, sizeof(Packet));
while (valread < fullSize) {
int result = nn::socket::Recv(fd, packetBuf + valread,
fullSize - valread, this->sock_flags);
this->socket_errno = nn::socket::GetLastErrno();
if (result > 0) {
valread += result;
} else {
mHeap->free(packetBuf);
Logger::log("Packet Read Failed! Value: %d\nPacket Size: %d\nPacket Type: %s\n", result, header->mPacketSize, packetNames[header->mType]);
return this->tryReconnect();
}
}
if (!(header->mType > PacketType::UNKNOWN && header->mType < PacketType::End)) {
Logger::log("Failed to acquire valid packet type! Packet Type: %d Full Packet Size %d valread size: %d\n", header->mType, fullSize, valread);
mHeap->free(packetBuf);
return true;
}
Packet *packet = reinterpret_cast<Packet*>(packetBuf);
if (!mRecvQueue.isFull() && mPacketQueueOpen) {
mRecvQueue.push((s64)packet, sead::MessageQueue::BlockType::NonBlocking);
} else {
mHeap->free(packetBuf);
}
return true;
}
bool SocketClient::recvUdp() {
int headerSize = sizeof(Packet);
s32 fd = this->mUdpSocket;
int valread = nn::socket::Recv(fd, recvBuf, MAXPACKSIZE, this->sock_flags);
if (valread == 0) {
Logger::log("Udp connection valread was zero. Disconnecting.\n");
return this->tryReconnect();
}
if (valread < headerSize){
return true;
}
Packet* header = reinterpret_cast<Packet*>(recvBuf);
int fullSize = header->mPacketSize + sizeof(Packet);
// Verify packet size is appropriate
if (valread < fullSize || valread > MAXPACKSIZE || fullSize > MAXPACKSIZE){
return true;
}
// Verify type of packet
if (!(header->mType > PacketType::UNKNOWN && header->mType < PacketType::End)) {
Logger::log("Failed to acquire valid packet type! Packet Type: %d Full Packet Size %d valread size: %d\n", header->mType, fullSize, valread);
return true;
}
this->mHasRecvUdp = true;
char* packetBuf = (char*)mHeap->alloc(fullSize);
if (!packetBuf) {
return true;
}
memcpy(packetBuf, recvBuf, fullSize);
Packet *packet = reinterpret_cast<Packet*>(packetBuf);
if(!mRecvQueue.isFull()) {
mRecvQueue.push((s64)packet, sead::MessageQueue::BlockType::NonBlocking);
} else {
mHeap->free(packetBuf);
}
return true;
}
// prints packet to debug logger
@ -208,10 +431,28 @@ void SocketClient::printPacket(Packet *packet) {
}
}
bool SocketClient::tryReconnect() {
Logger::log("Attempting to Reconnect.\n");
if (closeSocket()) { // unfortunately we cannot use the same fd from the previous connection, so close the socket entirely and attempt a new connection.
if (init(sock_ip, port).isSuccess()) { // call init again
Logger::log("Reconnect Successful.\n");
return true;
}
}
return false;
}
bool SocketClient::closeSocket() {
Logger::log("Closing Socket.\n");
mHasRecvUdp = false;
mUdpAddress.port = 0;
mPacketQueueOpen = false;
bool result = false;
if (!(result = SocketBase::closeSocket())) {
@ -240,3 +481,105 @@ bool SocketClient::stringToIPAddress(const char* str, in_addr* out) {
return false;
}
/**
* @brief starts client read thread
*
* @return true if read thread was successfully started
* @return false if read thread was unable to start, or thread was already started.
*/
bool SocketClient::startThreads() {
Logger::log("Recv Thread isDone: %s\n", BTOC(this->mRecvThread->isDone()));
Logger::log("Send Thread isDone: %s\n", BTOC(this->mSendThread->isDone()));
if(this->mRecvThread->isDone() && this->mSendThread->isDone()) {
this->mRecvThread->start();
this->mSendThread->start();
Logger::log("Socket threads succesfully started.\n");
return true;
}else {
Logger::log("Socket threads failed to start.\n");
return false;
}
}
void SocketClient::endThreads() {
mRecvThread->mDelegateThread->destroy();
mSendThread->mDelegateThread->destroy();
}
void SocketClient::waitForThreads() {
while (!mRecvThread->isDone()){}
while (!mSendThread->isDone()){}
}
void SocketClient::sendFunc() {
Logger::log("Starting Send Thread.\n");
while (trySendQueue() || socket_log_state != SOCKET_LOG_DISCONNECTED) {}
Logger::log("Sending packet failed!\n");
Logger::log("Ending Send Thread.\n");
}
void SocketClient::recvFunc() {
nn::socket::Recv(this->socket_log_socket, nullptr, 0, 0);
Logger::log("Starting Recv Thread.\n");
while (recv() || socket_log_state != SOCKET_LOG_DISCONNECTED) {}
// Free up all blocked threads
mSendQueue.push(0, sead::MessageQueue::BlockType::NonBlocking);
mRecvQueue.push(0, sead::MessageQueue::BlockType::NonBlocking);
Logger::log("Receiving Packet Failed!\n");
Logger::log("Ending Recv Thread.\n");
}
bool SocketClient::queuePacket(Packet* packet) {
if (socket_log_state == SOCKET_LOG_CONNECTED && mPacketQueueOpen) {
mSendQueue.push((s64)packet,
sead::MessageQueue::BlockType::NonBlocking); // as this is non-blocking, it
// will always return true.
return true;
} else {
mHeap->free(packet);
return false;
}
}
bool SocketClient::trySendQueue() {
Packet* curPacket = (Packet*)mSendQueue.pop(sead::MessageQueue::BlockType::Blocking);
bool successful = send(curPacket);
mHeap->free(curPacket);
return successful;
}
Packet* SocketClient::tryGetPacket(sead::MessageQueue::BlockType blockType) {
return socket_log_state == SOCKET_LOG_CONNECTED ? (Packet*)mRecvQueue.pop(blockType) : nullptr;
}
void SocketClient::clearMessageQueues() {
bool prevQueueOpenness = this->mPacketQueueOpen;
this->mPacketQueueOpen = false;
while (mSendQueue.getCount() > 0) {
Packet* curPacket = (Packet*)mSendQueue.pop(sead::MessageQueue::BlockType::Blocking);
mHeap->free(curPacket);
}
while (mRecvQueue.getCount() > 0) {
Packet* curPacket = (Packet*)mRecvQueue.pop(sead::MessageQueue::BlockType::Blocking);
mHeap->free(curPacket);
}
this->mPacketQueueOpen = prevQueueOpenness;
}

View File

@ -1,16 +1,19 @@
#include "server/gamemode/GameModeManager.hpp"
#include <cstring>
#include <heap/seadFrameHeap.h>
#include <heap/seadExpHeap.h>
#include <basis/seadNew.h>
#include <heap/seadHeapMgr.h>
#include "al/util.hpp"
#include "basis/seadNew.h"
#include "heap/seadHeapMgr.h"
#include "logger.hpp"
#include "server/gamemode/GameModeBase.hpp"
#include "server/gamemode/GameModeFactory.hpp"
#include "server/gamemode/modifiers/ModeModifierBase.hpp"
#include "server/gamemode/modifiers/ModifierFactory.hpp"
SEAD_SINGLETON_DISPOSER_IMPL(GameModeManager)
GameModeManager::GameModeManager() {
mHeap = sead::FrameHeap::create(0x100000, "GameModeHeap", al::getSequenceHeap(), 8,
mHeap = sead::ExpHeap::create(0x50000, "GameModeHeap", al::getSequenceHeap(), 8,
sead::Heap::HeapDirection::cHeapDirection_Reverse, false);
setMode(GameMode::HIDEANDSEEK);
}
@ -84,6 +87,7 @@ void GameModeManager::initScene(const GameModeInitInfo& info) {
}
if (mCurModeBase) {
sead::ScopedCurrentHeapSetter heapSetter(GameModeManager::getSceneHeap());
mCurModeBase->init(*mLastInitInfo);
if (mCurModeBase->isModeActive())
mWasSceneTrans = true;

View File

@ -0,0 +1,46 @@
#include "server/gamemode/modifiers/GravityModifier.hpp"
#include "helpers.hpp"
#include "math/seadVector.h"
#include "rs/util.hpp"
GravityModifier::GravityModifier(GameModeBase* mode) : ModeModifierBase(mode) {}
void GravityModifier::enable() {
ModeModifierBase::enable();
if(mTicket && mScene)
al::startCamera(mScene, mTicket, -1);
}
void GravityModifier::disable() {
ModeModifierBase::disable();
if(mTicket && mScene)
al::endCamera(mScene, mTicket, -1, false);
}
void GravityModifier::update() {
sead::Vector3f gravity;
PlayerActorBase *playerBase = rs::getPlayerActor(mScene);
if (rs::calcOnGroundNormalOrGravityDir(&gravity, playerBase, playerBase->getPlayerCollision())) {
gravity = -gravity;
al::normalize(&gravity);
al::setGravity(playerBase, gravity);
al::setGravity(((PlayerActorHakoniwa*)playerBase)->mHackCap, gravity);
}
if (al::isPadHoldL(-1)) {
if (al::isPadTriggerRight(-1)) {
if (al::isActiveCamera(mTicket)) {
al::endCamera(mScene, mTicket, -1, false);
} else {
al::startCamera(mScene, mTicket, -1);
}
}
} else if (al::isPadTriggerZL(-1)) {
if (al::isPadTriggerLeft(-1)) {
killMainPlayer(((PlayerActorHakoniwa*)playerBase));
}
}
}

View File

@ -0,0 +1,18 @@
#include "server/gamemode/modifiers/NoCapModifier.hpp"
#include "game/GameData/GameDataFunction.h"
#include "server/gamemode/GameModeBase.hpp"
#include "game/GameData/GameDataHolderAccessor.h"
#include "helpers.hpp"
#include "math/seadVector.h"
#include "rs/util.hpp"
#include "server/gamemode/GameModeManager.hpp"
NoCapModifier::NoCapModifier(GameModeBase* mode) : ModeModifierBase(mode) {}
void NoCapModifier::enable() {
ModeModifierBase::enable();
}
void NoCapModifier::disable() {
ModeModifierBase::disable();
}

View File

@ -5,20 +5,27 @@
#include "server/hns/HideAndSeekMode.hpp"
#include "server/Client.hpp"
HideAndSeekConfigMenu::HideAndSeekConfigMenu() : GameModeConfigMenu() {}
HideAndSeekConfigMenu::HideAndSeekConfigMenu() : GameModeConfigMenu() {
gravityOn = new sead::SafeArray<sead::WFixedSafeString<0x200>, mItemCount>();
gravityOn->mBuffer[0].copy(u"Toggle H&S Gravity (ON)");
gravityOff = new sead::SafeArray<sead::WFixedSafeString<0x200>, mItemCount>();
gravityOff->mBuffer[0].copy(u"Toggle H&S Gravity (OFF)");
}
void HideAndSeekConfigMenu::initMenu(const al::LayoutInitInfo &initInfo) {
}
const sead::WFixedSafeString<0x200> *HideAndSeekConfigMenu::getStringData() {
sead::SafeArray<sead::WFixedSafeString<0x200>, mItemCount>* gamemodeConfigOptions =
new sead::SafeArray<sead::WFixedSafeString<0x200>, mItemCount>();
gamemodeConfigOptions->mBuffer[0].copy(u"Toggle H&S Gravity On");
gamemodeConfigOptions->mBuffer[1].copy(u"Toggle H&S Gravity Off");
return gamemodeConfigOptions->mBuffer;
const sead::WFixedSafeString<0x200>* HideAndSeekConfigMenu::getStringData() {
HideAndSeekInfo *curMode = GameModeManager::instance()->getInfo<HideAndSeekInfo>();
return (
GameModeManager::instance()->isMode(GameMode::HIDEANDSEEK)
&& curMode != nullptr
&& curMode->mIsUseGravity
? gravityOn->mBuffer
: gravityOff->mBuffer
);
}
bool HideAndSeekConfigMenu::updateMenu(int selectIndex) {
@ -35,13 +42,7 @@ bool HideAndSeekConfigMenu::updateMenu(int selectIndex) {
switch (selectIndex) {
case 0: {
if (GameModeManager::instance()->isMode(GameMode::HIDEANDSEEK)) {
curMode->mIsUseGravity = true;
}
return true;
}
case 1: {
if (GameModeManager::instance()->isMode(GameMode::HIDEANDSEEK)) {
curMode->mIsUseGravity = false;
curMode->mIsUseGravity = !curMode->mIsUseGravity;
}
return true;
}
@ -50,4 +51,4 @@ bool HideAndSeekConfigMenu::updateMenu(int selectIndex) {
return false;
}
}
}

View File

@ -32,8 +32,6 @@ void HideAndSeekMode::init(const GameModeInitInfo& info) {
GameModeInfoBase* curGameInfo = GameModeManager::instance()->getInfo<HideAndSeekInfo>();
sead::ScopedCurrentHeapSetter heapSetter(GameModeManager::instance()->getHeap());
if (curGameInfo) Logger::log("Gamemode info found: %s %s\n", GameModeFactory::getModeString(curGameInfo->mMode), GameModeFactory::getModeString(info.mMode));
else Logger::log("No gamemode info found\n");
if (curGameInfo && curGameInfo->mMode == mMode) {
@ -74,6 +72,8 @@ void HideAndSeekMode::begin() {
MapMini* compass = mCurScene->mSceneLayout->mMapMiniLyt;
al::SimpleLayoutAppearWaitEnd* playGuideLyt = mCurScene->mSceneLayout->mPlayGuideMenuLyt;
mInvulnTime = 0;
if(coinCounter->mIsAlive)
coinCounter->tryEnd();
if(coinCollect->mIsAlive)
@ -84,6 +84,8 @@ void HideAndSeekMode::begin() {
playGuideLyt->end();
GameModeBase::begin();
Client::sendTagInfPacket();
}
void HideAndSeekMode::end() {
@ -97,6 +99,8 @@ void HideAndSeekMode::end() {
MapMini* compass = mCurScene->mSceneLayout->mMapMiniLyt;
al::SimpleLayoutAppearWaitEnd* playGuideLyt = mCurScene->mSceneLayout->mPlayGuideMenuLyt;
mInvulnTime = 0.0f;
if(!coinCounter->mIsAlive)
coinCounter->tryStart();
if(!coinCollect->mIsAlive)
@ -107,6 +111,8 @@ void HideAndSeekMode::end() {
playGuideLyt->appear();
GameModeBase::end();
Client::sendTagInfPacket();
}
void HideAndSeekMode::update() {

View File

@ -111,7 +111,7 @@ void Logger::log(const char* fmt, ...) {
}
bool Logger::pingSocket() {
return socket_log("ping") > 0; // if value is greater than zero, than the socket recieved our message, otherwise the connection was lost.
return socket_log("ping") > 0; // if value is greater than zero, than the socket received our message, otherwise the connection was lost.
}
void tryInitSocket() {
@ -119,4 +119,4 @@ void tryInitSocket() {
#if DEBUGLOG
Logger::createInstance(); // creates a static instance for debug logger
#endif
}
}

View File

@ -41,14 +41,13 @@ StageSceneStateServerConfig::StageSceneStateServerConfig(const char *name, al::S
mMainOptionsList->unkInt1 = 1;
mMainOptionsList->initDataNoResetSelected(5);
mMainOptionsList->initDataNoResetSelected(4);
sead::SafeArray<sead::WFixedSafeString<0x200>, 5>* mainMenuOptions =
new sead::SafeArray<sead::WFixedSafeString<0x200>, 5>();
sead::SafeArray<sead::WFixedSafeString<0x200>, 4>* mainMenuOptions =
new sead::SafeArray<sead::WFixedSafeString<0x200>, 4>();
mainMenuOptions->mBuffer[ServerConfigOption::GAMEMODECONFIG].copy(u"Gamemode Config");
mainMenuOptions->mBuffer[ServerConfigOption::GAMEMODESWITCH].copy(u"Change Gamemode");
mainMenuOptions->mBuffer[ServerConfigOption::RECONNECT].copy(u"Reconnect to Server");
mainMenuOptions->mBuffer[ServerConfigOption::SETIP].copy(u"Change Server IP");
mainMenuOptions->mBuffer[ServerConfigOption::SETPORT].copy(u"Change Server Port");
@ -101,11 +100,6 @@ StageSceneStateServerConfig::StageSceneStateServerConfig(const char *name, al::S
entry.mList = new CommonVerticalList(entry.mLayout, initInfo, true);
al::setPaneString(entry.mLayout, "TxtOption", u"Gamemode Configuration", 0);
entry.mList->initDataNoResetSelected(entry.mMenu->getMenuSize());
entry.mList->addStringData(entry.mMenu->getStringData(), "TxtContent");
}
@ -115,6 +109,15 @@ StageSceneStateServerConfig::StageSceneStateServerConfig(const char *name, al::S
void StageSceneStateServerConfig::init() {
initNerve(&nrvStageSceneStateServerConfigMainMenu, 0);
#ifdef EMU
char ryujinx[0x10] = { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
nn::account::Uid user;
nn::account::GetLastOpenedUser(&user);
if (memcmp(user.data, ryujinx, 0x10) == 0) {
Client::showUIMessage(u"Error: Ryujinx default profile detected.\nYou have to create a new user profile!");
}
#endif
}
void StageSceneStateServerConfig::appear(void) {
@ -176,10 +179,6 @@ void StageSceneStateServerConfig::exeMainMenu() {
al::setNerve(this, &nrvStageSceneStateServerConfigGamemodeSelect);
break;
}
case ServerConfigOption::RECONNECT: {
al::setNerve(this, &nrvStageSceneStateServerConfigRestartServer);
break;
}
case ServerConfigOption::SETIP: {
al::setNerve(this, &nrvStageSceneStateServerConfigOpenKeyboardIP);
break;
@ -233,32 +232,16 @@ void StageSceneStateServerConfig::exeOpenKeyboardPort() {
}
}
void StageSceneStateServerConfig::exeRestartServer() {
if (al::isFirstStep(this)) {
mCurrentList->deactivate();
Client::showConnect();
Client::restartConnection();
}
if (Client::isSocketActive()) {
Client::hideConnect();
al::startHitReaction(mCurrentMenu, "リセット", 0);
al::setNerve(this, &nrvStageSceneStateServerConfigMainMenu);
} else {
al::setNerve(this, &nrvStageSceneStateServerConfigConnectError);
}
}
void StageSceneStateServerConfig::exeGamemodeConfig() {
if (al::isFirstStep(this)) {
mGamemodeConfigMenu = &mGamemodeConfigMenus[GameModeManager::instance()->getGameMode()];
mGamemodeConfigMenu->mList->initDataNoResetSelected(mGamemodeConfigMenu->mMenu->getMenuSize());
mGamemodeConfigMenu->mList->addStringData(mGamemodeConfigMenu->mMenu->getStringData(), "TxtContent");
mCurrentList = mGamemodeConfigMenu->mList;
mCurrentMenu = mGamemodeConfigMenu->mLayout;
subMenuStart();
}
@ -290,18 +273,6 @@ void StageSceneStateServerConfig::exeGamemodeSelect() {
}
}
void StageSceneStateServerConfig::exeConnectError() {
if (al::isFirstStep(this)) {
Client::showConnectError(u"Failed to Reconnect!");
}
if (al::isGreaterEqualStep(this, 60)) { // close after 1 second
Client::hideConnect();
al::startHitReaction(mCurrentMenu, "リセット", 0);
al::setNerve(this, &nrvStageSceneStateServerConfigMainMenu);
}
}
void StageSceneStateServerConfig::exeSaveData() {
if (al::isFirstStep(this)) {
@ -373,9 +344,7 @@ namespace {
NERVE_IMPL(StageSceneStateServerConfig, MainMenu)
NERVE_IMPL(StageSceneStateServerConfig, OpenKeyboardIP)
NERVE_IMPL(StageSceneStateServerConfig, OpenKeyboardPort)
NERVE_IMPL(StageSceneStateServerConfig, RestartServer)
NERVE_IMPL(StageSceneStateServerConfig, GamemodeConfig)
NERVE_IMPL(StageSceneStateServerConfig, GamemodeSelect)
NERVE_IMPL(StageSceneStateServerConfig, SaveData)
NERVE_IMPL(StageSceneStateServerConfig, ConnectError)
}
}