* use doxygen
* add documenting guide based on https://github.com/zeldaret/oot/blob/main/docs/Documenting.md
* exclude stdlib readme from doxygen
* refuse to configure matching iQue on macOS (EGCS compiler is not built for macOS, so iQue won't build. We still enable iQue builds on macOS by using gcc-papermario via --non-matching.)
* use proper doxygen bug comment style
* document common EVT API funcs nicely
* add doxygen ci
* add \vars command
This commit is contained in:
Alex Bates 2024-01-09 23:56:08 +00:00 committed by GitHub
parent 029de584b7
commit 37f59877e5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
46 changed files with 4755 additions and 407 deletions

31
.github/workflows/docs.yaml vendored Normal file
View File

@ -0,0 +1,31 @@
name: Docs
on:
push:
branches:
- master
jobs:
doxygen:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Install Doxygen
run: sudo apt-get install doxygen
- name: Generate docs
run: doxygen
# deploy to gh pages if repo is pmret/papermario
- name: Deploy to gh-pages
if: github.repository != 'pmret/papermario'
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./docs/html
- name: Deploy to papermar.io
if: github.repository == 'pmret/papermario'
uses: appleboy/scp-action@master
with:
host: ${{ secrets.HOST }}
username: ${{ secrets.USERNAME }}
password: ${{ secrets.PASSWORD }}
source: "docs/html/"
target: "/var/www/papermar.io/html/docs"
strip_components: 2

View File

@ -50,14 +50,14 @@
}, },
"C_Cpp.autoAddFileAssociations": false, "C_Cpp.autoAddFileAssociations": false,
"C_Cpp.default.cStandard": "c89", "C_Cpp.default.cStandard": "c89",
"C_Cpp.doxygen.generateOnType": false,
"files.exclude": { "files.exclude": {
"**/.git": true, "**/.git": true,
"**/.splat_cache": true, "**/.splat_cache": true,
".ninja*": true, ".ninja*": true,
"ver/current": true, "ver/current": true,
"expected": true, "expected": true,
"**/*.i": true, "**/*.i": true
"docs/doxygen": true
}, },
"[python]": { "[python]": {
"editor.formatOnType": true, "editor.formatOnType": true,

2860
Doxyfile Normal file

File diff suppressed because it is too large Load Diff

262
DoxygenLayout.xml Normal file
View File

@ -0,0 +1,262 @@
<?xml version="1.0" encoding="UTF-8"?>
<doxygenlayout version="1.0">
<!-- Generated by doxygen 1.10.0 -->
<!-- Navigation index tabs for HTML output -->
<navindex>
<tab type="mainpage" visible="yes" title=""/>
<tab type="pages" visible="yes" title="" intro=""/>
<tab type="topics" visible="yes" title="" intro=""/>
<tab type="modules" visible="yes" title="" intro="">
<tab type="modulelist" visible="yes" title="" intro=""/>
<tab type="modulemembers" visible="yes" title="" intro=""/>
</tab>
<tab type="namespaces" visible="yes" title="">
<tab type="namespacelist" visible="yes" title="" intro=""/>
<tab type="namespacemembers" visible="yes" title="" intro=""/>
</tab>
<tab type="concepts" visible="yes" title="">
</tab>
<tab type="interfaces" visible="yes" title="">
<tab type="interfacelist" visible="yes" title="" intro=""/>
<tab type="interfaceindex" visible="$ALPHABETICAL_INDEX" title=""/>
<tab type="interfacehierarchy" visible="yes" title="" intro=""/>
</tab>
<tab type="classes" visible="yes" title="">
<tab type="classlist" visible="yes" title="" intro=""/>
<tab type="classindex" visible="$ALPHABETICAL_INDEX" title=""/>
<tab type="hierarchy" visible="yes" title="" intro=""/>
<tab type="classmembers" visible="yes" title="" intro=""/>
</tab>
<tab type="structs" visible="yes" title="">
<tab type="structlist" visible="yes" title="" intro=""/>
<tab type="structindex" visible="$ALPHABETICAL_INDEX" title=""/>
</tab>
<tab type="exceptions" visible="yes" title="">
<tab type="exceptionlist" visible="yes" title="" intro=""/>
<tab type="exceptionindex" visible="$ALPHABETICAL_INDEX" title=""/>
<tab type="exceptionhierarchy" visible="yes" title="" intro=""/>
</tab>
<tab type="files" visible="yes" title="">
<tab type="filelist" visible="yes" title="" intro=""/>
<tab type="globals" visible="yes" title="" intro=""/>
</tab>
<tab type="examples" visible="yes" title="" intro=""/>
</navindex>
<!-- Layout definition for a class page -->
<class>
<detaileddescription title=""/>
<includes visible="$SHOW_HEADERFILE"/>
<inheritancegraph visible="yes"/>
<collaborationgraph visible="yes"/>
<memberdecl>
<nestedclasses visible="yes" title=""/>
<publictypes title=""/>
<services title=""/>
<interfaces title=""/>
<publicslots title=""/>
<signals title=""/>
<publicmethods title=""/>
<publicstaticmethods title=""/>
<publicattributes title=""/>
<publicstaticattributes title=""/>
<protectedtypes title=""/>
<protectedslots title=""/>
<protectedmethods title=""/>
<protectedstaticmethods title=""/>
<protectedattributes title=""/>
<protectedstaticattributes title=""/>
<packagetypes title=""/>
<packagemethods title=""/>
<packagestaticmethods title=""/>
<packageattributes title=""/>
<packagestaticattributes title=""/>
<properties title=""/>
<events title=""/>
<privatetypes title=""/>
<privateslots title=""/>
<privatemethods title=""/>
<privatestaticmethods title=""/>
<privateattributes title=""/>
<privatestaticattributes title=""/>
<friends title=""/>
<related title="" subtitle=""/>
<membergroups visible="yes"/>
</memberdecl>
<memberdef>
<inlineclasses title=""/>
<typedefs title=""/>
<enums title=""/>
<services title=""/>
<interfaces title=""/>
<constructors title=""/>
<functions title=""/>
<related title=""/>
<variables title=""/>
<properties title=""/>
<events title=""/>
</memberdef>
<allmemberslink visible="yes"/>
<usedfiles visible="$SHOW_USED_FILES"/>
<authorsection visible="yes"/>
</class>
<!-- Layout definition for a namespace page -->
<namespace>
<detaileddescription title=""/>
<memberdecl>
<nestednamespaces visible="yes" title=""/>
<constantgroups visible="yes" title=""/>
<interfaces visible="yes" title=""/>
<classes visible="yes" title=""/>
<concepts visible="yes" title=""/>
<structs visible="yes" title=""/>
<exceptions visible="yes" title=""/>
<typedefs title=""/>
<sequences title=""/>
<dictionaries title=""/>
<enums title=""/>
<functions title=""/>
<variables title=""/>
<properties title=""/>
<membergroups visible="yes"/>
</memberdecl>
<memberdef>
<inlineclasses title=""/>
<typedefs title=""/>
<sequences title=""/>
<dictionaries title=""/>
<enums title=""/>
<functions title=""/>
<variables title=""/>
<properties title=""/>
</memberdef>
<authorsection visible="yes"/>
</namespace>
<!-- Layout definition for a concept page -->
<concept>
<detaileddescription title=""/>
<includes visible="$SHOW_HEADERFILE"/>
<definition visible="yes" title=""/>
<authorsection visible="yes"/>
</concept>
<!-- Layout definition for a file page -->
<file>
<detaileddescription title=" "/>
<includes visible="$SHOW_INCLUDE_FILES"/>
<includegraph visible="yes"/>
<includedbygraph visible="yes"/>
<sourcelink visible="yes"/>
<memberdecl>
<interfaces visible="yes" title=""/>
<classes visible="yes" title=""/>
<structs visible="yes" title=""/>
<exceptions visible="yes" title=""/>
<namespaces visible="yes" title=""/>
<concepts visible="yes" title=""/>
<constantgroups visible="yes" title=""/>
<defines title=""/>
<typedefs title=""/>
<sequences title=""/>
<dictionaries title=""/>
<enums title=""/>
<functions title=""/>
<variables title=""/>
<properties title=""/>
<membergroups visible="yes"/>
</memberdecl>
<memberdef>
<inlineclasses title=""/>
<defines title=""/>
<typedefs title=""/>
<sequences title=""/>
<dictionaries title=""/>
<enums title=""/>
<functions title=""/>
<variables title=""/>
<properties title=""/>
</memberdef>
<authorsection/>
</file>
<!-- Layout definition for a group page -->
<group>
<detaileddescription title=""/>
<groupgraph visible="yes"/>
<memberdecl>
<nestedgroups visible="yes" title=""/>
<modules visible="yes" title=""/>
<dirs visible="yes" title=""/>
<files visible="yes" title=""/>
<namespaces visible="yes" title=""/>
<concepts visible="yes" title=""/>
<classes visible="yes" title=""/>
<defines title=""/>
<typedefs title=""/>
<sequences title=""/>
<dictionaries title=""/>
<enums title=""/>
<enumvalues title=""/>
<functions title=""/>
<variables title=""/>
<signals title=""/>
<publicslots title=""/>
<protectedslots title=""/>
<privateslots title=""/>
<events title=""/>
<properties title=""/>
<friends title=""/>
<membergroups visible="yes"/>
</memberdecl>
<memberdef>
<pagedocs/>
<inlineclasses title=""/>
<defines title=""/>
<typedefs title=""/>
<sequences title=""/>
<dictionaries title=""/>
<enums title=""/>
<enumvalues title=""/>
<functions title=""/>
<variables title=""/>
<signals title=""/>
<publicslots title=""/>
<protectedslots title=""/>
<privateslots title=""/>
<events title=""/>
<properties title=""/>
<friends title=""/>
</memberdef>
<authorsection visible="yes"/>
</group>
<!-- Layout definition for a C++20 module page -->
<module>
<detaileddescription title=""/>
<exportedmodules visible="yes"/>
<memberdecl>
<concepts visible="yes" title=""/>
<classes visible="yes" title=""/>
<enums title=""/>
<typedefs title=""/>
<functions title=""/>
<variables title=""/>
<membergroups title=""/>
</memberdecl>
<memberdecl>
<files visible="yes"/>
</memberdecl>
</module>
<!-- Layout definition for a directory page -->
<directory>
<detaileddescription title=""/>
<directorygraph visible="yes"/>
<memberdecl>
<dirs visible="yes"/>
<files visible="yes"/>
</memberdecl>
</directory>
</doxygenlayout>

80
docs/Documenting.md Normal file
View File

@ -0,0 +1,80 @@
# Documentation Style Guide
This project uses [Doxygen](https://www.doxygen.nl/index.html) to generate documentation pages from comments found in the source files. This guide focuses on writing compatible comments and ensuring consistency across the codebase.
To generate a doxygen manual for the project, ensure you have doxygen installed and then cd into the project root directory and run `doxygen`.
## Documenting Functions
For functions, a description of the function's purpose should go above the function:
```c
/// Creates a foo.
void foo(void);
```
Further considerations:
- Any comments inside the function should follow the usual `//` or `/**/` comment styles.
- For documenting return values, place a `@return` at the bottom of the function comment followed by the description of the return value. This should only be done if the name of the function is not self-explanatory and is well-understood.
- For documenting parameters, place a `@param` between the comment and the @return (if applicable) followed by the name of the parameter and a brief description. This should only be done if the name of the parameter is not self-explanatory and is well-understood.
- All `@param`s should come before `@return` and be in the same order the parameters appear in the function declaration. Note that this does not mean you should add empty `@params` for parameters deemed self-explanatory.
A full example would be as follows: (however in practice functions such as this would be considered self-explanatory)
```c
/// A cool function that multiplies a number by 2.
/// @param bar the input
/// @return bar multiplied by 2
s32 foo(s32 bar) {
return 2*bar;
}
```
## Documenting EVT API Functions
Use `@evtapi` to mark functions as EVT API functions, and use `@param` to document the parameters as passed to `EVT_CALL`. Do not use `@return`. See [include/script_api/common.h](../include/script_api/common.h) for examples.
## Documenting Variables
Documentation of variables should include what this variable is used for if the name is not completely clear and if applicable whether a set of defines or enumerations should be used alongside it (which should be linked with `@see`, see below)
```c
/// My description of this variable.
s32 foo;
```
## Documenting Files
File documentation should go near the top of the file, below includes. It should only feature information that is general to the file.
```c
/// @file file_name.c
/// My description of this file.
```
## Documenting Fields
Struct fields can be documented in the same way as variables, but you may prefer to document them in an end-of-line comment instead.
## Other
### Documenting Bugs:
Bugs should be documented on the line above where the bug begins.
```c
/// @bug description
```
### Linking related information:
`@see` should be used to provide links to related information where appropriate, for example:
```c
/// Savefile data.
/// @see SaveContext
SaveContext gSaveContext;
```
In the case of functions, `@see` should come before the first `@param`.
### Markdown
You can use Markdown in your doc comments.
### LaTeX
You can embed [LaTeX](https://wikipedia.org/wiki/LaTeX) in your doc comments if useful to do so.
For inline rendering:
```c
/**
* \f$ \textrm{Your LaTeX Here} \f$
*/
```
For centered rendering on a separate line:
```c
/**
* \f[ \textrm{Your LaTeX Here} \f]
*/
```

View File

@ -0,0 +1,18 @@
<!-- HTML footer for doxygen 1.10.0-->
<!-- start footer part -->
<!--BEGIN GENERATE_TREEVIEW-->
<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
<ul>
$navpath
<li class="footer">$generatedby <a href="https://www.doxygen.org/index.html"><img class="footer" src="$relpath^doxygen.svg" width="104" height="31" alt="doxygen"/></a> $doxygenversion </li>
</ul>
</div>
<!--END GENERATE_TREEVIEW-->
<!--BEGIN !GENERATE_TREEVIEW-->
<hr class="footer"/><address class="footer"><small>
$generatedby&#160;<a href="https://www.doxygen.org/index.html"><img class="footer" src="$relpath^doxygen.svg" width="104" height="31" alt="doxygen"/></a> $doxygenversion
</small></address>
<!--END !GENERATE_TREEVIEW-->
<script src="theme.js"></script>
</body>
</html>

18
docs/doxytheme/theme.css Normal file
View File

@ -0,0 +1,18 @@
/* Fix scrollbar color */
:root { color-scheme: dark }
@media (prefers-color-scheme: light) {
:root { color-scheme: light }
}
.memname {
font-family: var(--font-family-monospace);
}
/* The alias @evtapi is used to mark EVT API functions with a .evtapi child */
.memitem:has(.evtapi) {
.memproto {
td.memname .el { display: none }
td.memname::before { content: "EVT_CALL(" }
td.memname::after { content: "," }
}
}

49
docs/doxytheme/theme.js Normal file
View File

@ -0,0 +1,49 @@
// Make @evtapi prototype use EVT_CALL and params
for (const item of document.querySelectorAll(".memitem:has(.evtapi)")) {
// <a id="..." /> appears 2 children before item
const id = item.previousElementSibling.previousElementSibling.id
const tbody = item.querySelector(".memproto tbody")
const name = tbody.querySelector("td.memname").childNodes[1].textContent.trim()
const params = [`<a class="el" href="#${id}">${name}</a>`]
for (const param of item.querySelectorAll(".params:not(.vars) .paramname")) {
params.push(param.textContent.trim())
}
const proto = `EVT_CALL(${params.join(", ")})`
tbody.innerHTML = `<tr>${proto}</tr>`
// Find its link
const tr = document.getElementById(`r_${id}`)
tr.innerHTML = `<td class="memItemLeft" align="right" valign="top"></td><td class="memItemRight" valign="bottom">${proto}</td>`
}
// Combine @vars tables
for (const table of document.querySelectorAll("table.vars + table.vars")) {
const tbody = table.querySelector("tbody")
table.previousElementSibling.querySelector("tbody").append(...tbody.childNodes)
table.remove()
}
// Wrap @vars tables in a description
for (const table of document.querySelectorAll("table.vars")) {
const dl = document.createElement("dl")
const dt = document.createElement("dt")
dt.textContent = "Variables"
dl.appendChild(dt)
const dd = document.createElement("dd")
dd.innerHTML = table.outerHTML // makes copy of table
dl.appendChild(dd)
table.replaceWith(dl)
}
// Remove spaces in [in]/[out]/[in,out]
// These can appear because of spaces between the @vars arg separators
for (const paramdir of document.querySelectorAll("table.vars .paramdir")) {
paramdir.textContent = paramdir.textContent.replace(/\s/g, "")
}

BIN
docs/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

File diff suppressed because it is too large Load Diff

View File

@ -480,7 +480,7 @@ b32 check_input_jump(void) {
return FALSE; return FALSE;
} }
// @bug? collider flags not properly masked with COLLIDER_FLAG_SURFACE_TYPE /// @bug? collider flags not properly masked with COLLIDER_FLAG_SURFACE_TYPE
surfaceType = get_collider_flags((u16)gCollisionStatus.curFloor); surfaceType = get_collider_flags((u16)gCollisionStatus.curFloor);
if ((surfaceType == SURFACE_TYPE_SLIDE) && phys_should_player_be_sliding()) { if ((surfaceType == SURFACE_TYPE_SLIDE) && phys_should_player_be_sliding()) {
return FALSE; return FALSE;

View File

@ -297,10 +297,10 @@ void appendGfx_background_texture(void) {
0, 0, 295, extraHeight - 1, 0, 0, 0, 295, extraHeight - 1, 0,
G_TX_WRAP, G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD); G_TX_WRAP, G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
gSPTextureRectangle(gMainGfxPos++, bgMinX * 4, (lineHeight * i + bgMinY) * 4, gSPTextureRectangle(gMainGfxPos++, bgMinX * 4, (lineHeight * i + bgMinY) * 4,
(2 * bgXOffset + (bgMinX - 1)) * 4, (bgMaxY - 1 + bgMinY) * 4, // @bug xh = 2 * bgXOffset + (bgMinX - 1) * 4 (2 * bgXOffset + (bgMinX - 1)) * 4, (bgMaxY - 1 + bgMinY) * 4, /// @bug xh = 2 * bgXOffset + (bgMinX - 1) * 4
G_TX_RENDERTILE, bgMaxX * 32 - bgXOffset * 16, 0, 4096, 1024); G_TX_RENDERTILE, bgMaxX * 32 - bgXOffset * 16, 0, 4096, 1024);
gSPTextureRectangle(gMainGfxPos++, bgXOffset * 2 + bgMinX * 4, (lineHeight * i + bgMinY) * 4, gSPTextureRectangle(gMainGfxPos++, bgXOffset * 2 + bgMinX * 4, (lineHeight * i + bgMinY) * 4,
(bgMaxX + bgMinX - 1) * 4, (bgMaxY - 1 + bgMinY) * 4, // @bug xh = 2 * bgXOffset + (bgMinX - 1) * 4 (bgMaxX + bgMinX - 1) * 4, (bgMaxY - 1 + bgMinY) * 4, /// @bug xh = 2 * bgXOffset + (bgMinX - 1) * 4
G_TX_RENDERTILE, 0, 0, 4096, 1024); G_TX_RENDERTILE, 0, 0, 4096, 1024);
} }
} }

View File

@ -297,12 +297,12 @@ void func_80027BAC(s32 arg0, s32 arg1) {
} }
} }
// Logic for the drawing the scene background. In normal operation, it draws the regular background. /// Logic for the drawing the scene background. In normal operation, it draws the regular background.
// While opening pause menu, it does the following: /// While opening pause menu, it does the following:
// * Extracts coverage from the current framebuffer and saves it to nuGfxCfb[1] on the first frame. /// * Extracts coverage from the current framebuffer and saves it to nuGfxCfb[1] on the first frame.
// * Copies the current framebuffer to the depth buffer to save it and applies a filter on the /// * Copies the current framebuffer to the depth buffer to save it and applies a filter on the
// saved framebuffer based on the saved coverage values one frame later. /// saved framebuffer based on the saved coverage values one frame later.
// * Draws the saved framebuffer to the current framebuffer while the pause screen is opened, fading it in over time. /// * Draws the saved framebuffer to the current framebuffer while the pause screen is opened, fading it in over time.
void gfx_draw_background(void) { void gfx_draw_background(void) {
Camera* camera; Camera* camera;
s32 bgRenderState; s32 bgRenderState;
@ -360,9 +360,9 @@ void gfx_draw_background(void) {
gDPSetTexturePersp(gMainGfxPos++, G_TP_NONE); gDPSetTexturePersp(gMainGfxPos++, G_TP_NONE);
gDPSetTextureLUT(gMainGfxPos++, G_TT_NONE); gDPSetTextureLUT(gMainGfxPos++, G_TT_NONE);
gDPSetRenderMode(gMainGfxPos++, G_RM_OPA_SURF, G_RM_OPA_SURF2); gDPSetRenderMode(gMainGfxPos++, G_RM_OPA_SURF, G_RM_OPA_SURF2);
// @bug In 1-cycle mode, the two combiner cycles should be identical. Using Texel1 here in the second cycle, /// @bug In 1-cycle mode, the two combiner cycles should be identical. Using Texel1 here in the second cycle,
// which is the actual cycle of the combiner used on hardware in 1-cycle mode, actually samples the next /// which is the actual cycle of the combiner used on hardware in 1-cycle mode, actually samples the next
// pixel's texel value instead of the current pixel's. This results in a one-pixel offset. /// pixel's texel value instead of the current pixel's. This results in a one-pixel offset.
gDPSetCombineMode(gMainGfxPos++, PM_CC_43, PM_CC_44); gDPSetCombineMode(gMainGfxPos++, PM_CC_43, PM_CC_44);
gDPSetPrimColor(gMainGfxPos++, 0, 0, 40, 40, 40, gPauseBackgroundFade); gDPSetPrimColor(gMainGfxPos++, 0, 0, 40, 40, 40, gPauseBackgroundFade);
gDPSetTextureFilter(gMainGfxPos++, G_TF_POINT); gDPSetTextureFilter(gMainGfxPos++, G_TF_POINT);
@ -371,8 +371,8 @@ void gfx_draw_background(void) {
gDPLoadTextureTile(gMainGfxPos++, nuGfxZBuffer + (i * SCREEN_WIDTH * SCREEN_COPY_TILE_HEIGHT), G_IM_FMT_RGBA, G_IM_SIZ_16b, SCREEN_WIDTH, gDPLoadTextureTile(gMainGfxPos++, nuGfxZBuffer + (i * SCREEN_WIDTH * SCREEN_COPY_TILE_HEIGHT), G_IM_FMT_RGBA, G_IM_SIZ_16b, SCREEN_WIDTH,
SCREEN_HEIGHT, 0, 0, SCREEN_WIDTH - 1, SCREEN_COPY_TILE_HEIGHT - 1, 0, G_TX_NOMIRROR | G_TX_WRAP, SCREEN_HEIGHT, 0, 0, SCREEN_WIDTH - 1, SCREEN_COPY_TILE_HEIGHT - 1, 0, G_TX_NOMIRROR | G_TX_WRAP,
G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD); G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
// @bug Due to the previous issue with the incorrect second cycle combiner, the devs added a 1-pixel offset to texture coordinates /// @bug Due to the previous issue with the incorrect second cycle combiner, the devs added a 1-pixel offset to texture coordinates
// in this texrect to compensate for the combiner error. /// in this texrect to compensate for the combiner error.
gSPTextureRectangle(gMainGfxPos++, gSPTextureRectangle(gMainGfxPos++,
// ulx, uly, lrx, lry // ulx, uly, lrx, lry
0 << 2, i * a, SCREEN_WIDTH << 2, a + (i * (SCREEN_COPY_TILE_HEIGHT << 2)), 0 << 2, i * a, SCREEN_WIDTH << 2, a + (i * (SCREEN_COPY_TILE_HEIGHT << 2)),

View File

@ -166,8 +166,9 @@ void initialize_battle(void) {
gBattleStatus.inputBitmask = -1; gBattleStatus.inputBitmask = -1;
gOverrideFlags &= ~GLOBAL_OVERRIDES_ENABLE_FLOOR_REFLECTION; gOverrideFlags &= ~GLOBAL_OVERRIDES_ENABLE_FLOOR_REFLECTION;
/// @bug? why just 16
for (i = 0; i < 16; i++) { for (i = 0; i < 16; i++) {
battleStatus->pushInputBuffer[i] = 0; // @bug? why just 16 battleStatus->pushInputBuffer[i] = 0;
} }
battleStatus->inputBufferPos = 0; battleStatus->inputBufferPos = 0;

View File

@ -24,11 +24,11 @@ f32 D_802938A4 = 0.0f;
s16 D_802938A8 = 4; s16 D_802938A8 = 4;
EffectInstance* gDamageCountEffects[] = { EffectInstance* gDamageCountEffects[] = {
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
}; };
@ -151,7 +151,7 @@ void create_target_list(Actor* actor, b32 targetHomePos) {
for (j = 0; j < numParts; targetPart = targetPart->nextPart, j++) { for (j = 0; j < numParts; targetPart = targetPart->nextPart, j++) {
if (!(targetPart->flags & ACTOR_PART_FLAG_NO_TARGET)) { if (!(targetPart->flags & ACTOR_PART_FLAG_NO_TARGET)) {
ActorPartBlueprint* partBlueprint = targetPart->staticData; ActorPartBlueprint* partBlueprint = targetPart->staticData;
if (!(targetPart->flags & ACTOR_PART_FLAG_USE_ABSOLUTE_POSITION)) { if (!(targetPart->flags & ACTOR_PART_FLAG_USE_ABSOLUTE_POSITION)) {
sampleRow = !targetHomePos; // required to match sampleRow = !targetHomePos; // required to match
if (sampleRow) { if (sampleRow) {
@ -237,7 +237,7 @@ void create_target_list(Actor* actor, b32 targetHomePos) {
} else { } else {
targetDataList->layer = 1; targetDataList->layer = 1;
} }
numTargets++; numTargets++;
targetDataList++; targetDataList++;
} }
@ -252,7 +252,7 @@ void create_target_list(Actor* actor, b32 targetHomePos) {
} while (0); } while (0);
actor->targetListLength = numTargets; actor->targetListLength = numTargets;
// @bug this should be % 4 /// @bug this should be % 4
sampleCol = battleStatus->sampleTargetHomeIndex & 4; sampleCol = battleStatus->sampleTargetHomeIndex & 4;
sampleRow = battleStatus->sampleTargetHomeIndex / 4; sampleRow = battleStatus->sampleTargetHomeIndex / 4;
@ -269,7 +269,7 @@ void create_target_list(Actor* actor, b32 targetHomePos) {
if (target->actorID == ACTOR_PLAYER || target->actorID == ACTOR_PARTNER) { if (target->actorID == ACTOR_PLAYER || target->actorID == ACTOR_PARTNER) {
continue; continue;
} }
// sanity check condition -- function should never reach this point with this flag set // sanity check condition -- function should never reach this point with this flag set
if (battleStatus->curTargetListFlags & TARGET_FLAG_OVERRIDE) { if (battleStatus->curTargetListFlags & TARGET_FLAG_OVERRIDE) {
removeTarget = TRUE; removeTarget = TRUE;
@ -296,7 +296,7 @@ void create_target_list(Actor* actor, b32 targetHomePos) {
goto FIRST_PASS_REMOVE; goto FIRST_PASS_REMOVE;
} }
} }
// target passed all checks, do not remove // target passed all checks, do not remove
removeTarget = FALSE; removeTarget = FALSE;
@ -371,7 +371,7 @@ void create_target_list(Actor* actor, b32 targetHomePos) {
// search the target list for any targets below the current target (same column, higher row) // search the target list for any targets below the current target (same column, higher row)
// skip the current target if any are found // skip the current target if any are found
s32 foundAbove = FALSE; s32 foundAbove = FALSE;
do { do {
for (j = 0; j < numTargets; j++) { for (j = 0; j < numTargets; j++) {
otherTarget = &targetDataList[j]; otherTarget = &targetDataList[j];
@ -397,7 +397,7 @@ void create_target_list(Actor* actor, b32 targetHomePos) {
// search the target list for any targets in front of the current target (same row, lower column) // search the target list for any targets in front of the current target (same row, lower column)
// skip the current target if any are found // skip the current target if any are found
s32 foundInFront = FALSE; s32 foundInFront = FALSE;
for (j = 0; j < numTargets; j++) { for (j = 0; j < numTargets; j++) {
otherTarget = &targetDataList[j]; otherTarget = &targetDataList[j];
if (target != otherTarget) { if (target != otherTarget) {
@ -546,14 +546,15 @@ s32 func_80263064(Actor* actor, Actor* targetActor, b32 unused) {
part = part->nextPart; part = part->nextPart;
continue; continue;
} }
if (!(part->flags & ACTOR_PART_FLAG_PRIMARY_TARGET)) { if (!(part->flags & ACTOR_PART_FLAG_PRIMARY_TARGET)) {
// @bug part list position is not advanced, all further loop iterations will be stuck here /// @bug part list position is not advanced, all further loop iterations will be stuck here
// nanaian: I think this is intended and should probably be a break. this flag makes multi-target attacks select this part only
continue; continue;
} }
partData = part->staticData; partData = part->staticData;
if (!(part->flags & ACTOR_PART_FLAG_USE_ABSOLUTE_POSITION)) { if (!(part->flags & ACTOR_PART_FLAG_USE_ABSOLUTE_POSITION)) {
x = targetActor->curPos.x; x = targetActor->curPos.x;
y = targetActor->curPos.y; y = targetActor->curPos.y;
@ -594,7 +595,7 @@ s32 func_80263064(Actor* actor, Actor* targetActor, b32 unused) {
target->priorityOffset = 0; target->priorityOffset = 0;
target++; target++;
count++; count++;
part = part->nextPart; part = part->nextPart;
} }

View File

@ -640,7 +640,7 @@ HitResult calc_enemy_damage_target(Actor* attacker) {
statusInflicted2 = one; statusInflicted2 = one;
} }
// @bug? repeated paralyze and dizzy infliction /// @bug? repeated paralyze and dizzy infliction
if (battleStatus->curAttackStatus & STATUS_FLAG_PARALYZE && try_inflict_status(target, STATUS_KEY_PARALYZE, STATUS_TURN_MOD_PARALYZE)) { if (battleStatus->curAttackStatus & STATUS_FLAG_PARALYZE && try_inflict_status(target, STATUS_KEY_PARALYZE, STATUS_TURN_MOD_PARALYZE)) {
statusInflicted = one; statusInflicted = one;
statusInflicted2 = one; statusInflicted2 = one;
@ -875,7 +875,7 @@ s32 dispatch_damage_event_actor(Actor* actor, s32 damageAmount, s32 originalEven
show_damage_fx(actor, actor->targetData[0].truePos.x, actor->targetData[0].truePos.y, actor->targetData[0].truePos.z, battleStatus->lastAttackDamage); show_damage_fx(actor, actor->targetData[0].truePos.x, actor->targetData[0].truePos.y, actor->targetData[0].truePos.z, battleStatus->lastAttackDamage);
} }
actor->targetActorID = savedTargetActorID; actor->targetActorID = savedTargetActorID;
} else { } else {
show_next_damage_popup(state->goalPos.x, state->goalPos.y, state->goalPos.z, battleStatus->lastAttackDamage, 0); show_next_damage_popup(state->goalPos.x, state->goalPos.y, state->goalPos.z, battleStatus->lastAttackDamage, 0);
show_damage_fx(actor, state->goalPos.x, state->goalPos.y, state->goalPos.z, battleStatus->lastAttackDamage); show_damage_fx(actor, state->goalPos.x, state->goalPos.y, state->goalPos.z, battleStatus->lastAttackDamage);
@ -3185,7 +3185,7 @@ ApiStatus AfflictActor(Evt* script, s32 isInitialCall) {
switch (statusTypeKey) { switch (statusTypeKey) {
case STATUS_KEY_FROZEN: case STATUS_KEY_FROZEN:
statusDurationKey = STATUS_TURN_MOD_PARALYZE; // @bug should be STATUS_TURN_MOD_FROZEN statusDurationKey = STATUS_TURN_MOD_PARALYZE; /// @bug should be STATUS_TURN_MOD_FROZEN
break; break;
case STATUS_KEY_SLEEP: case STATUS_KEY_SLEEP:
statusDurationKey = STATUS_TURN_MOD_SLEEP; statusDurationKey = STATUS_TURN_MOD_SLEEP;

View File

@ -3901,7 +3901,7 @@ void add_part_decor_sparkles(ActorPart* part, s32 idx) {
x = part->curPos.x; x = part->curPos.x;
y = part->curPos.y + (part->size.y / 2); y = part->curPos.y + (part->size.y / 2);
z = part->curPos.z - 5.0f; z = part->curPos.z - 5.0f;
// @bug this should be % 4 /// @bug this should be % 4
if ((gGameStatusPtr->frameCounter / 4) == 0) { if ((gGameStatusPtr->frameCounter / 4) == 0) {
fx_sparkles(FX_SPARKLES_1, x, y, z, 10.0f); fx_sparkles(FX_SPARKLES_1, x, y, z, 10.0f);
} }

View File

@ -444,7 +444,7 @@ EvtScript N(EVS_HandlePhase) = {
EVT_CALL(UseBattleCamPreset, BTL_CAM_DEFAULT) EVT_CALL(UseBattleCamPreset, BTL_CAM_DEFAULT)
EVT_CALL(MoveBattleCamOver, 4) EVT_CALL(MoveBattleCamOver, 4)
EVT_END_IF EVT_END_IF
EVT_END_IF // @bug END_IF with no IF EVT_END_IF /// @bug END_IF with no IF
EVT_CASE_EQ(PHASE_ENEMY_BEGIN) EVT_CASE_EQ(PHASE_ENEMY_BEGIN)
// trying showing the scene where Goompa congratulates the player for dealing damage to Jr Troopa // trying showing the scene where Goompa congratulates the player for dealing damage to Jr Troopa
EVT_CALL(GetActorVar, ACTOR_SELF, AVAR_HitReact_State, LVar0) EVT_CALL(GetActorVar, ACTOR_SELF, AVAR_HitReact_State, LVar0)

View File

@ -1268,7 +1268,7 @@ EvtScript N(EVS_UseDrainingShockwave) = {
EVT_WAIT(2) EVT_WAIT(2)
EVT_CALL(SetTargetActor, ACTOR_SELF, ACTOR_PARTNER) EVT_CALL(SetTargetActor, ACTOR_SELF, ACTOR_PARTNER)
EVT_CALL(SetGoalToTarget, ACTOR_SELF) EVT_CALL(SetGoalToTarget, ACTOR_SELF)
// @bug missing a call to GetPartEventFlags, LVar0 is invalid in next block //// @bug missing a call to GetPartEventFlags, LVar0 is invalid in next block
EVT_IF_FLAG(LVar0, ACTOR_EVENT_FLAG_ENCHANTED) EVT_IF_FLAG(LVar0, ACTOR_EVENT_FLAG_ENCHANTED)
EVT_SET(LVar1, DMG_BOOSTED_SHOCKWAVE_P) EVT_SET(LVar1, DMG_BOOSTED_SHOCKWAVE_P)
EVT_ELSE EVT_ELSE
@ -1290,7 +1290,7 @@ EvtScript N(EVS_UseDrainingShockwave) = {
EVT_WAIT(4) EVT_WAIT(4)
EVT_CALL(SetTargetActor, ACTOR_SELF, ACTOR_PARTNER) EVT_CALL(SetTargetActor, ACTOR_SELF, ACTOR_PARTNER)
EVT_CALL(SetGoalToTarget, ACTOR_SELF) EVT_CALL(SetGoalToTarget, ACTOR_SELF)
// @bug missing a call to GetPartEventFlags, LVar0 is invalid in next block /// @bug missing a call to GetPartEventFlags, LVar0 is invalid in next block
EVT_IF_FLAG(LVar0, ACTOR_EVENT_FLAG_ENCHANTED) EVT_IF_FLAG(LVar0, ACTOR_EVENT_FLAG_ENCHANTED)
EVT_SET(LVar1, DMG_BOOSTED_SHOCKWAVE_P) EVT_SET(LVar1, DMG_BOOSTED_SHOCKWAVE_P)
EVT_ELSE EVT_ELSE
@ -1301,7 +1301,7 @@ EvtScript N(EVS_UseDrainingShockwave) = {
EVT_END_THREAD EVT_END_THREAD
EVT_WAIT(2) EVT_WAIT(2)
EVT_CALL(SetGoalToTarget, ACTOR_SELF) EVT_CALL(SetGoalToTarget, ACTOR_SELF)
// @bug missing a call to GetPartEventFlags, LVar0 is invalid in next block /// @bug missing a call to GetPartEventFlags, LVar0 is invalid in next block
EVT_IF_FLAG(LVar0, ACTOR_EVENT_FLAG_ENCHANTED) EVT_IF_FLAG(LVar0, ACTOR_EVENT_FLAG_ENCHANTED)
EVT_SET(LVar1, DMG_BOOSTED_SHOCKWAVE) EVT_SET(LVar1, DMG_BOOSTED_SHOCKWAVE)
EVT_ELSE EVT_ELSE

View File

@ -1502,7 +1502,7 @@ EvtScript N(EVS_UseDrainingShockwave) = {
EVT_WAIT(2) EVT_WAIT(2)
EVT_CALL(SetTargetActor, ACTOR_SELF, ACTOR_PARTNER) EVT_CALL(SetTargetActor, ACTOR_SELF, ACTOR_PARTNER)
EVT_CALL(SetGoalToTarget, ACTOR_SELF) EVT_CALL(SetGoalToTarget, ACTOR_SELF)
// @bug missing a call to GetPartEventFlags, LVar0 is invalid in next block /// @bug missing a call to GetPartEventFlags, LVar0 is invalid in next block
EVT_IF_FLAG(LVar0, ACTOR_EVENT_FLAG_ENCHANTED) EVT_IF_FLAG(LVar0, ACTOR_EVENT_FLAG_ENCHANTED)
EVT_SET(LVar1, DMG_BOOSTED_SHOCKWAVE_P) EVT_SET(LVar1, DMG_BOOSTED_SHOCKWAVE_P)
EVT_ELSE EVT_ELSE
@ -1524,7 +1524,7 @@ EvtScript N(EVS_UseDrainingShockwave) = {
EVT_WAIT(4) EVT_WAIT(4)
EVT_CALL(SetTargetActor, ACTOR_SELF, ACTOR_PARTNER) EVT_CALL(SetTargetActor, ACTOR_SELF, ACTOR_PARTNER)
EVT_CALL(SetGoalToTarget, ACTOR_SELF) EVT_CALL(SetGoalToTarget, ACTOR_SELF)
// @bug missing a call to GetPartEventFlags, LVar0 is invalid in next block /// @bug missing a call to GetPartEventFlags, LVar0 is invalid in next block
EVT_IF_FLAG(LVar0, ACTOR_EVENT_FLAG_ENCHANTED) EVT_IF_FLAG(LVar0, ACTOR_EVENT_FLAG_ENCHANTED)
EVT_SET(LVar1, DMG_BOOSTED_SHOCKWAVE_P) EVT_SET(LVar1, DMG_BOOSTED_SHOCKWAVE_P)
EVT_ELSE EVT_ELSE
@ -1535,7 +1535,7 @@ EvtScript N(EVS_UseDrainingShockwave) = {
EVT_END_THREAD EVT_END_THREAD
EVT_WAIT(2) EVT_WAIT(2)
EVT_CALL(SetGoalToTarget, ACTOR_SELF) EVT_CALL(SetGoalToTarget, ACTOR_SELF)
// @bug missing a call to GetPartEventFlags, LVar0 is invalid in next block /// @bug missing a call to GetPartEventFlags, LVar0 is invalid in next block
EVT_IF_FLAG(LVar0, ACTOR_EVENT_FLAG_ENCHANTED) EVT_IF_FLAG(LVar0, ACTOR_EVENT_FLAG_ENCHANTED)
EVT_SET(LVar1, DMG_BOOSTED_SHOCKWAVE) EVT_SET(LVar1, DMG_BOOSTED_SHOCKWAVE)
EVT_ELSE EVT_ELSE

View File

@ -1095,7 +1095,7 @@ EvtScript N(EVS_Attack_BodySlam) = {
EVT_CALL(SetGoalToTarget, ACTOR_SELF) EVT_CALL(SetGoalToTarget, ACTOR_SELF)
EVT_CALL(SetAnimation, ACTOR_SELF, PRT_MAIN, ANIM_BattleBowser_Land) EVT_CALL(SetAnimation, ACTOR_SELF, PRT_MAIN, ANIM_BattleBowser_Land)
EVT_CALL(GetPartEventFlags, ACTOR_SELF, PRT_MAIN, LVar1) EVT_CALL(GetPartEventFlags, ACTOR_SELF, PRT_MAIN, LVar1)
EVT_IF_FLAG(LVar1, ACTOR_EVENT_FLAG_STAR_ROD_ENCHANTED) // @bug checks wrong event flag, never uses 12 damage attack EVT_IF_FLAG(LVar1, ACTOR_EVENT_FLAG_STAR_ROD_ENCHANTED) /// @bug checks wrong event flag, never uses 12 damage attack
EVT_SET(LVar0, DMG_BOOSTED_BODY_SLAM) EVT_SET(LVar0, DMG_BOOSTED_BODY_SLAM)
EVT_ELSE EVT_ELSE
EVT_SET(LVar0, DMG_BODY_SLAM) EVT_SET(LVar0, DMG_BODY_SLAM)
@ -1418,7 +1418,7 @@ EvtScript N(EVS_UseDrainingShockwave) = {
EVT_WAIT(2) EVT_WAIT(2)
EVT_CALL(SetTargetActor, ACTOR_SELF, ACTOR_PARTNER) EVT_CALL(SetTargetActor, ACTOR_SELF, ACTOR_PARTNER)
EVT_CALL(SetGoalToTarget, ACTOR_SELF) EVT_CALL(SetGoalToTarget, ACTOR_SELF)
// @bug missing a call to GetPartEventFlags, LVar0 is invalid in next block /// @bug missing a call to GetPartEventFlags, LVar0 is invalid in next block
EVT_IF_FLAG(LVar0, ACTOR_EVENT_FLAG_ENCHANTED) EVT_IF_FLAG(LVar0, ACTOR_EVENT_FLAG_ENCHANTED)
EVT_SET(LVar1, DMG_BOOSTED_SHOCKWAVE_P) EVT_SET(LVar1, DMG_BOOSTED_SHOCKWAVE_P)
EVT_ELSE EVT_ELSE
@ -1440,7 +1440,7 @@ EvtScript N(EVS_UseDrainingShockwave) = {
EVT_WAIT(4) EVT_WAIT(4)
EVT_CALL(SetTargetActor, ACTOR_SELF, ACTOR_PARTNER) EVT_CALL(SetTargetActor, ACTOR_SELF, ACTOR_PARTNER)
EVT_CALL(SetGoalToTarget, ACTOR_SELF) EVT_CALL(SetGoalToTarget, ACTOR_SELF)
// @bug missing a call to GetPartEventFlags, LVar0 is invalid in next block /// @bug missing a call to GetPartEventFlags, LVar0 is invalid in next block
EVT_IF_FLAG(LVar0, ACTOR_EVENT_FLAG_ENCHANTED) EVT_IF_FLAG(LVar0, ACTOR_EVENT_FLAG_ENCHANTED)
EVT_SET(LVar1, DMG_BOOSTED_SHOCKWAVE_P) EVT_SET(LVar1, DMG_BOOSTED_SHOCKWAVE_P)
EVT_ELSE EVT_ELSE
@ -1451,7 +1451,7 @@ EvtScript N(EVS_UseDrainingShockwave) = {
EVT_END_THREAD EVT_END_THREAD
EVT_WAIT(2) EVT_WAIT(2)
EVT_CALL(SetGoalToTarget, ACTOR_SELF) EVT_CALL(SetGoalToTarget, ACTOR_SELF)
// @bug missing a call to GetPartEventFlags, LVar0 is invalid in next block /// @bug missing a call to GetPartEventFlags, LVar0 is invalid in next block
EVT_IF_FLAG(LVar0, ACTOR_EVENT_FLAG_ENCHANTED) EVT_IF_FLAG(LVar0, ACTOR_EVENT_FLAG_ENCHANTED)
EVT_SET(LVar1, DMG_BOOSTED_SHOCKWAVE) EVT_SET(LVar1, DMG_BOOSTED_SHOCKWAVE)
EVT_ELSE EVT_ELSE

View File

@ -67,7 +67,7 @@ StageList A(Stages) = {
STAGE("kpa_01", A(kpa_01)), STAGE("kpa_01", A(kpa_01)),
STAGE("kpa_01b", A(kpa_01b)), STAGE("kpa_01b", A(kpa_01b)),
STAGE("kpa_02", A(kpa_02)), STAGE("kpa_02", A(kpa_02)),
STAGE("kpa_03", A(kpa_04)), // @bug should be &A(kpa_03) STAGE("kpa_03", A(kpa_04)), /// @bug should be A(kpa_03)
STAGE("kpa_04", A(kpa_04)), STAGE("kpa_04", A(kpa_04)),
STAGE("kpa_04b", A(kpa_04b)), STAGE("kpa_04b", A(kpa_04b)),
STAGE("kpa_04c", A(kpa_04c)), STAGE("kpa_04c", A(kpa_04c)),

View File

@ -872,7 +872,7 @@ EvtScript N(EVS_HandlePhase) = {
EVT_BREAK_SWITCH EVT_BREAK_SWITCH
EVT_END_IF EVT_END_IF
EVT_CALL(GetStatusFlags, ACTOR_SELF, LVar0) EVT_CALL(GetStatusFlags, ACTOR_SELF, LVar0)
EVT_IF_FLAG(LVar0, STATUS_FLAGS_DOJO | STATUS_FLAG_POISON | STATUS_KEY_SHRINK) // @bug STATUS_KEY_SHRINK used instead of STATUS_FLAG_SHRINK EVT_IF_FLAG(LVar0, STATUS_FLAGS_DOJO | STATUS_FLAG_POISON | STATUS_KEY_SHRINK) /// @bug STATUS_KEY_SHRINK used instead of STATUS_FLAG_SHRINK
EVT_BREAK_SWITCH EVT_BREAK_SWITCH
EVT_END_IF EVT_END_IF
EVT_SET_CONST(LVarA, ANIM_Chan_Run) EVT_SET_CONST(LVarA, ANIM_Chan_Run)

View File

@ -2513,7 +2513,7 @@ void btl_state_update_player_menu(void) {
battleStatus->lastPlayerMenuSelection[BTL_MENU_IDX_MAIN] = battleStatus->curSubmenu = battle_menu_submenuIDs[submenuResult - 1]; battleStatus->lastPlayerMenuSelection[BTL_MENU_IDX_MAIN] = battleStatus->curSubmenu = battle_menu_submenuIDs[submenuResult - 1];
for (i = 0; i < ARRAY_COUNT(battleStatus->submenuMoves); i++) { for (i = 0; i < ARRAY_COUNT(battleStatus->submenuMoves); i++) {
battleStatus->submenuMoves[i] = 0; battleStatus->submenuMoves[i] = 0;
battleStatus->submenuIcons[0] = 0; ///< @bug ? battleStatus->submenuIcons[0] = 0; /// @bug ?
battleStatus->submenuStatus[i] = 0; battleStatus->submenuStatus[i] = 0;
} }

View File

@ -62,7 +62,7 @@ API_CALLABLE(N(AddFP)) {
PlayerData* playerData = &gPlayerData; PlayerData* playerData = &gPlayerData;
s32 amt = evt_get_variable(script, *script->ptrReadPos); s32 amt = evt_get_variable(script, *script->ptrReadPos);
// @bug Should be playerData->curFP /// @bug Should be playerData->curFP
s32 newFP = playerData->curHP + amt; s32 newFP = playerData->curHP + amt;
if (newFP > playerData->curMaxFP) { if (newFP > playerData->curMaxFP) {

View File

@ -66,7 +66,7 @@ API_CALLABLE(N(AdjustMultibonkChance)) {
script->varTable[0] = 99; script->varTable[0] = 99;
// @bug this value is not reset between Multibonk uses /// @bug this value is not reset between Multibonk uses
N(MultibonkChance) *= targetActor->actorBlueprint->powerBounceChance; N(MultibonkChance) *= targetActor->actorBlueprint->powerBounceChance;
N(MultibonkChance) /= 100; N(MultibonkChance) /= 100;
if (N(MultibonkChance) < rand_int(100)) { if (N(MultibonkChance) < rand_int(100)) {

View File

@ -85,7 +85,7 @@ s32 PartnerWishAnims[][5] = {
[PARTNER_WISH_ANIM_PRAY] ANIM_BattleWatt_Sleep, [PARTNER_WISH_ANIM_PRAY] ANIM_BattleWatt_Sleep,
[PARTNER_WISH_ANIM_UNUSED] ANIM_BattleWatt_Sleep, [PARTNER_WISH_ANIM_UNUSED] ANIM_BattleWatt_Sleep,
[PARTNER_WISH_ANIM_RETURN] ANIM_BattleWatt_Run, [PARTNER_WISH_ANIM_RETURN] ANIM_BattleWatt_Run,
[PARTNER_WISH_ANIM_IDLE] ANIM_BattleParakarry_Idle, // @bug uses wrong sprite! [PARTNER_WISH_ANIM_IDLE] ANIM_BattleParakarry_Idle, /// @bug uses wrong sprite!
}, },
[PARTNER_SUSHIE] { [PARTNER_SUSHIE] {
[PARTNER_WISH_ANIM_WALK] ANIM_BattleSushie_Run, [PARTNER_WISH_ANIM_WALK] ANIM_BattleSushie_Run,

View File

@ -225,7 +225,7 @@ EffectInstance* create_effect_instance(EffectBlueprint* effectBp) {
} }
effectGraphics->renderWorld = effectBp->renderWorld; effectGraphics->renderWorld = effectBp->renderWorld;
// @bug? null check for renderUI instead of renderWorld /// @bug? null check for renderUI instead of renderWorld
if (effectGraphics->renderUI == NULL) { if (effectGraphics->renderUI == NULL) {
effectGraphics->renderUI = stub_effect_delegate; effectGraphics->renderUI = stub_effect_delegate;
} }

View File

@ -1346,7 +1346,7 @@ s32 create_shadow_from_data(ShadowBlueprint* bp, f32 x, f32 y, f32 z) {
return shadow->listIndex; return shadow->listIndex;
} }
s32 MakeEntity(Evt* script, s32 isInitialCall) { ApiStatus MakeEntity(Evt* script, s32 isInitialCall) {
Bytecode* args = script->ptrReadPos; Bytecode* args = script->ptrReadPos;
EntityBlueprint* entityData; EntityBlueprint* entityData;
s32 x, y, z; s32 x, y, z;

View File

@ -32,8 +32,8 @@ ApiStatus PollMusicEvents(Evt* script, s32 isInitialCall) {
} }
cur++; cur++;
} }
// @bug? can cur ever be NULL here? /// @bug? can cur ever be NULL here?
// condition should probably be if (cur->musicEventID != -1) /// condition should probably be if (cur->musicEventID != -1)
if (cur != NULL) { if (cur != NULL) {
EvtScript* newSource = cur->scripts[scriptSelector]; EvtScript* newSource = cur->scripts[scriptSelector];
if (RunningMusicEvents[musicEventID] != NULL) { if (RunningMusicEvents[musicEventID] != NULL) {

View File

@ -11,7 +11,7 @@ extern u8 gSpriteShadingData[0x100];
extern Addr sprite_shading_profiles_data_ROM_START; extern Addr sprite_shading_profiles_data_ROM_START;
s32 SetSpriteShading(Evt* script, s32 isInitialCall) { ApiStatus SetSpriteShading(Evt* script, s32 isInitialCall) {
Bytecode* args = script->ptrReadPos; Bytecode* args = script->ptrReadPos;
s32 profileID = evt_get_variable(script, *args++); s32 profileID = evt_get_variable(script, *args++);
s32 shadingGroupOffset = (profileID >> 0x10) * 8; s32 shadingGroupOffset = (profileID >> 0x10) * 8;

View File

@ -385,7 +385,7 @@ void get_path_position(f32 alpha, Vec3f* outPos, s32 numVectors, f32* normalized
outPos->z = ((az + bz) * curProgress) + pathPoints[i].z; outPos->z = ((az + bz) * curProgress) + pathPoints[i].z;
} }
s32 LoadPath(Evt* script, s32 isInitialCall) { ApiStatus LoadPath(Evt* script, s32 isInitialCall) {
Bytecode* args = script->ptrReadPos; Bytecode* args = script->ptrReadPos;
s32 time = evt_get_variable(script, *args++); s32 time = evt_get_variable(script, *args++);
Vec3f* vectorList = (Vec3f*) evt_get_variable(script, *args++); Vec3f* vectorList = (Vec3f*) evt_get_variable(script, *args++);

View File

@ -780,7 +780,7 @@ ApiStatus func_802CF56C(Evt* script, s32 isInitialCall) {
return ApiStatus_DONE2; return ApiStatus_DONE2;
} }
s32 BringPartnerOut(Evt* script, s32 isInitialCall) { ApiStatus BringPartnerOut(Evt* script, s32 isInitialCall) {
Bytecode* args = script->ptrReadPos; Bytecode* args = script->ptrReadPos;
NpcBlueprint bp; NpcBlueprint bp;
NpcBlueprint* bpPointer = &bp; NpcBlueprint* bpPointer = &bp;

View File

@ -212,7 +212,8 @@ ApiStatus func_802D1380(Evt* script, s32 isInitialCall) {
return ApiStatus_DONE1; return ApiStatus_DONE1;
} }
s32 player_jump(Evt* script, s32 isInitialCall, s32 mode) { /// Internal function for PlayerJump(), PlayerJump1(), and PlayerJump2().
ApiStatus player_jump(Evt* script, s32 isInitialCall, s32 mode) {
Bytecode* args = script->ptrReadPos; Bytecode* args = script->ptrReadPos;
PlayerStatus* playerStatus = &gPlayerStatus; PlayerStatus* playerStatus = &gPlayerStatus;
f32 xTemp; f32 xTemp;
@ -331,9 +332,9 @@ s32 player_jump(Evt* script, s32 isInitialCall, s32 mode) {
handle_floor_behavior(); handle_floor_behavior();
} }
} }
return TRUE; return ApiStatus_DONE1;
} }
return FALSE; return ApiStatus_BLOCK;
} }
ApiStatus PlayerJump(Evt* script, s32 isInitialCall) { ApiStatus PlayerJump(Evt* script, s32 isInitialCall) {

View File

@ -1857,7 +1857,7 @@ void imgfx_mesh_make_wavy(ImgFXState* state) {
//TODO find better match //TODO find better match
v1 = (Vtx*)((state->firstVtxIdx + i) * sizeof(Vtx) + (s32)imgfx_vtxBuf); v1 = (Vtx*)((state->firstVtxIdx + i) * sizeof(Vtx) + (s32)imgfx_vtxBuf);
vx = v1->v.ob[0]; vx = v1->v.ob[0];
v1->v.ob[0] = (vx + (sin_rad(angle1) * state->ints.wavy.mag.x)); // @bug? should be sin_deg? v1->v.ob[0] = (vx + (sin_rad(angle1) * state->ints.wavy.mag.x)); /// @bug? should be sin_deg?
v2 = (Vtx*)((state->firstVtxIdx + i) * sizeof(Vtx) + (s32)imgfx_vtxBuf); v2 = (Vtx*)((state->firstVtxIdx + i) * sizeof(Vtx) + (s32)imgfx_vtxBuf);
vy = v2->v.ob[1]; vy = v2->v.ob[1];

View File

@ -1726,7 +1726,7 @@ s32 npc_render_with_double_pal_blending(Npc* npc, s32 yaw, Matrix4f mtx) {
} }
// blend next palettes // blend next palettes
outColor = npc->copiedPalettes[1]; // @bug? should this be index 3? outColor = npc->copiedPalettes[1]; /// @bug? should this be index 3?
color2 = npc->originalPalettesList[npc->blendPalD]; color2 = npc->originalPalettesList[npc->blendPalD];
color1 = npc->originalPalettesList[npc->blendPalC]; color1 = npc->originalPalettesList[npc->blendPalC];
npc->adjustedPalettes[3] = npc->copiedPalettes[3]; npc->adjustedPalettes[3] = npc->copiedPalettes[3];

View File

@ -85,7 +85,7 @@ EvtScript N(EVS_SecretPurcahseOrder_Moustafa) = {
EVT_SET(GB_StoryProgress, STORY_CH2_BOUGHT_SECRET_ITEMS) EVT_SET(GB_StoryProgress, STORY_CH2_BOUGHT_SECRET_ITEMS)
EVT_CALL(func_802D2C14, 0) EVT_CALL(func_802D2C14, 0)
EVT_EXEC_WAIT(N(EVS_JumpAway)) EVT_EXEC_WAIT(N(EVS_JumpAway))
EVT_END_IF // @bug unmatched endif in script EVT_END_IF /// @bug unmatched endif in script
EVT_RETURN EVT_RETURN
EVT_END EVT_END
}; };

View File

@ -3,7 +3,7 @@
API_CALLABLE(N(SpawnDirectedShootingStarFX)) { API_CALLABLE(N(SpawnDirectedShootingStarFX)) {
Bytecode* args = script->ptrReadPos; Bytecode* args = script->ptrReadPos;
f32 type = evt_get_float_variable(script, *args++); // @bug? s32 accessed as a float f32 type = evt_get_float_variable(script, *args++); /// @bug? s32 accessed as a float
f32 startX = evt_get_float_variable(script, *args++); f32 startX = evt_get_float_variable(script, *args++);
f32 startY = evt_get_float_variable(script, *args++); f32 startY = evt_get_float_variable(script, *args++);
f32 startZ = evt_get_float_variable(script, *args++); f32 startZ = evt_get_float_variable(script, *args++);

View File

@ -917,7 +917,7 @@ API_CALLABLE(func_802428C8_A2CB08) {
f32 temp_f24 = sin_deg(angle3); f32 temp_f24 = sin_deg(angle3);
xPos = effect->data.somethingRotating->pos.x + sin_deg(angle) * radius * temp_f24 ; xPos = effect->data.somethingRotating->pos.x + sin_deg(angle) * radius * temp_f24 ;
yPos = effect->data.somethingRotating->pos.y + cos_deg(angle3) * radius; yPos = effect->data.somethingRotating->pos.y + cos_deg(angle3) * radius;
// @bug should be `zPos = effect->data.somethingRotating->pos.z + cos_deg(angle) * radius * temp_f24;` /// @bug should be `zPos = effect->data.somethingRotating->pos.z + cos_deg(angle) * radius * temp_f24;`
zPos = effect->data.somethingRotating->pos.z + sin_deg(angle) * radius * temp_f24; zPos = effect->data.somethingRotating->pos.z + sin_deg(angle) * radius * temp_f24;
path->endPoint.x = xPos; path->endPoint.x = xPos;
path->endPoint.y = yPos; path->endPoint.y = yPos;

View File

@ -8,7 +8,7 @@ API_CALLABLE(N(AdjustFightingSoundsPos)) {
s32 y = evt_get_variable(script, *args++); s32 y = evt_get_variable(script, *args++);
s32 z = evt_get_variable(script, *args++); s32 z = evt_get_variable(script, *args++);
// @bug need to use real sound id, not environmental sound id /// @bug need to use real sound id, not environmental sound id
sfx_adjust_env_sound_pos(SOUND_LOOP_FIGHTING, SOUND_SPACE_DEFAULT, x, y, z); sfx_adjust_env_sound_pos(SOUND_LOOP_FIGHTING, SOUND_SPACE_DEFAULT, x, y, z);
return ApiStatus_DONE2; return ApiStatus_DONE2;

View File

@ -143,7 +143,7 @@ EvtScript N(EVS_NpcAI_FrostClubba_Napping) = {
NpcSettings N(NpcSettings_FrostClubba_Napping) = { NpcSettings N(NpcSettings_FrostClubba_Napping) = {
.height = 36, .height = 36,
.radius = 34, .radius = 34,
.level = ACTOR_LEVEL_CLUBBA, // @bug should be ACTOR_LEVEL_WHITE_CLUBBA .level = ACTOR_LEVEL_CLUBBA, /// @bug should be ACTOR_LEVEL_WHITE_CLUBBA
.ai = &N(EVS_NpcAI_FrostClubba_Napping), .ai = &N(EVS_NpcAI_FrostClubba_Napping),
.onHit = &EnemyNpcHit, .onHit = &EnemyNpcHit,
.onDefeat = &EnemyNpcDefeat, .onDefeat = &EnemyNpcDefeat,

View File

@ -3,7 +3,7 @@
NpcSettings N(NpcSettings_JungleFuzzy) = { NpcSettings N(NpcSettings_JungleFuzzy) = {
.height = 20, .height = 20,
.radius = 22, .radius = 22,
.level = ACTOR_LEVEL_FUZZY, // @bug should be ACTOR_LEVEL_JUNGLE_FUZZY .level = ACTOR_LEVEL_FUZZY, /// @bug should be ACTOR_LEVEL_JUNGLE_FUZZY
.onHit = &EnemyNpcHit, .onHit = &EnemyNpcHit,
.onDefeat = &EnemyNpcDefeat, .onDefeat = &EnemyNpcDefeat,
}; };

View File

@ -116,7 +116,7 @@ void N(SentinelAI_Descend)(Evt* script, MobileAISettings* aiSettings, EnemyDetec
f32 posX, posY, posZ, hitDepth; f32 posX, posY, posZ, hitDepth;
s32 color; s32 color;
// @bug need to use real sound id, not environmental sound id /// @bug need to use real sound id, not environmental sound id
sfx_adjust_env_sound_pos(SOUND_LOOP_SENTINEL_ALARM, SOUND_SPACE_FULL, npc->pos.x, npc->pos.y, npc->pos.z); sfx_adjust_env_sound_pos(SOUND_LOOP_SENTINEL_ALARM, SOUND_SPACE_FULL, npc->pos.x, npc->pos.y, npc->pos.z);
if (!basic_ai_check_player_dist(territory, enemy, aiSettings->chaseRadius, aiSettings->chaseOffsetDist, 1)) { if (!basic_ai_check_player_dist(territory, enemy, aiSettings->chaseRadius, aiSettings->chaseOffsetDist, 1)) {
enemy->varTable[0] &= ~SENTINEL_AI_FLAG_CHASING; enemy->varTable[0] &= ~SENTINEL_AI_FLAG_CHASING;

View File

@ -2325,7 +2325,7 @@ s32 partner_get_out(Npc* partner) {
add_vec2D_polar(&x, &z, 2.0f, gCameras[gCurrentCameraID].curYaw); add_vec2D_polar(&x, &z, 2.0f, gCameras[gCurrentCameraID].curYaw);
hitDepth = 1000.0f; hitDepth = 1000.0f;
if (npc_raycast_down_around(COLLIDER_FLAG_IGNORE_PLAYER, &x, &y, &z, &hitDepth, partner->yaw, partner->collisionDiameter)) { if (npc_raycast_down_around(COLLIDER_FLAG_IGNORE_PLAYER, &x, &y, &z, &hitDepth, partner->yaw, partner->collisionDiameter)) {
// @bug? collider flags not properly masked with COLLIDER_FLAG_SURFACE_TYPE /// @bug? collider flags not properly masked with COLLIDER_FLAG_SURFACE_TYPE
s32 surfaceType = get_collider_flags(NpcHitQueryColliderID); s32 surfaceType = get_collider_flags(NpcHitQueryColliderID);
if ((surfaceType == SURFACE_TYPE_SPIKES || surfaceType == SURFACE_TYPE_LAVA) || (hitDepth > 100.0f)) { if ((surfaceType == SURFACE_TYPE_SPIKES || surfaceType == SURFACE_TYPE_LAVA) || (hitDepth > 100.0f)) {

View File

@ -428,7 +428,7 @@ API_CALLABLE(GetPushBlock) {
s32 cellIndex; s32 cellIndex;
if (gridX >= blockGrid->numCellsX || gridX < 0 || gridZ >= blockGrid->numCellsZ || gridZ < 0) { if (gridX >= blockGrid->numCellsX || gridX < 0 || gridZ >= blockGrid->numCellsZ || gridZ < 0) {
// @bug: sets error value and then performs lookup anyway -- return statement forgotten here /// @bug: sets error value and then performs lookup anyway -- return statement forgotten here
evt_set_variable(script, outVar, PUSH_GRID_OUT_OF_BOUNDS); evt_set_variable(script, outVar, PUSH_GRID_OUT_OF_BOUNDS);
} }
cellIndex = gridX + (gridZ * blockGrid->numCellsX); cellIndex = gridX + (gridZ * blockGrid->numCellsX);

View File

@ -662,8 +662,11 @@ class Configure:
task = "cc_272" task = "cc_272"
cflags = cflags.replace("gcc_272", "") cflags = cflags.replace("gcc_272", "")
elif "egcs" in cflags: elif "egcs" in cflags:
task = "cc_egcs" if sys.platform == "darwin" and non_matching:
cflags = cflags.replace("egcs", "") print(f"warning: using default compiler for {seg.name} because egcs is not supported on macOS")
else:
task = "cc_egcs"
cflags = cflags.replace("egcs", "")
elif "gcc_modern" in cflags: elif "gcc_modern" in cflags:
task = "cc_modern" task = "cc_modern"
cflags = cflags.replace("gcc_modern", "") cflags = cflags.replace("gcc_modern", "")
@ -1378,6 +1381,12 @@ if __name__ == "__main__":
for version in versions: for version in versions:
print(f"configure: configuring version {version}") print(f"configure: configuring version {version}")
if version == "ique" and not args.non_matching and sys.platform == "darwin":
print(
"configure: refusing to build iQue Player version on macOS because EGCS compiler is not available (use --non-matching to use default compiler)"
)
continue
configure = Configure(version) configure = Configure(version)
if not first_configure: if not first_configure:
@ -1391,7 +1400,7 @@ if __name__ == "__main__":
all_rom_oks.append(str(configure.rom_ok_path())) all_rom_oks.append(str(configure.rom_ok_path()))
assert first_configure assert first_configure, "no versions configured"
first_configure.make_current(ninja) first_configure.make_current(ninja)
if non_matching: if non_matching: