mirror of
https://github.com/coop-deluxe/sm64coopdx.git
synced 2024-12-03 17:27:27 +00:00
Merge pull request #501 from coop-deluxe/dev
This commit is contained in:
commit
f85b8419af
142 changed files with 3286 additions and 2831 deletions
14
Makefile
14
Makefile
|
@ -45,7 +45,7 @@ COOPNET ?= 1
|
|||
# Enable docker build workarounds
|
||||
DOCKERBUILD ?= 0
|
||||
# Sets your optimization level for building.
|
||||
# A choose is chosen by default for you.
|
||||
# A choice is made by default for you.
|
||||
OPT_LEVEL ?= -1
|
||||
# Enable compiling with more debug info.
|
||||
DEBUG_INFO_LEVEL ?= 2
|
||||
|
@ -66,8 +66,6 @@ ifeq ($(shell arch),arm64)
|
|||
else
|
||||
MIN_MACOS_VERSION ?= 10.15
|
||||
endif
|
||||
# Homebrew Prefix
|
||||
BREW_PREFIX ?= $(shell brew --prefix)
|
||||
# Make some small adjustments for handheld devices
|
||||
HANDHELD ?= 0
|
||||
|
||||
|
@ -122,6 +120,10 @@ endif
|
|||
|
||||
ifeq ($(HOST_OS),Darwin)
|
||||
OSX_BUILD := 1
|
||||
|
||||
ifndef BREW_PREFIX
|
||||
BREW_PREFIX := $(shell brew --prefix)
|
||||
endif
|
||||
endif
|
||||
|
||||
# MXE overrides
|
||||
|
@ -1327,9 +1329,6 @@ $(SOUND_BIN_DIR)/tbl_header: $(SOUND_BIN_DIR)/sound_data.ctl
|
|||
$(SOUND_BIN_DIR)/samples_offsets.inc.c: $(SOUND_BIN_DIR)/sound_data.ctl
|
||||
@true
|
||||
|
||||
$(SOUND_BIN_DIR)/sequences_offsets.inc.c: $(SOUND_BIN_DIR)/sound_data.ctl
|
||||
@true
|
||||
|
||||
$(SOUND_BIN_DIR)/sequences.bin: $(SOUND_BANK_FILES) sound/sequences.json $(SOUND_SEQUENCE_DIRS) $(SOUND_SEQUENCE_FILES) $(ENDIAN_BITWIDTH)
|
||||
@$(PRINT) "$(GREEN)Generating: $(BLUE)$@ $(NO_COL)\n"
|
||||
$(V)$(PYTHON) $(TOOLS_DIR)/assemble_sound.py --sequences $@ $(SOUND_BIN_DIR)/sequences_header $(SOUND_BIN_DIR)/bank_sets sound/sound_banks/ sound/sequences.json $(SOUND_SEQUENCE_FILES) $(C_DEFINES) $$(cat $(ENDIAN_BITWIDTH))
|
||||
|
@ -1340,6 +1339,9 @@ $(SOUND_BIN_DIR)/bank_sets: $(SOUND_BIN_DIR)/sequences.bin
|
|||
$(SOUND_BIN_DIR)/sequences_header: $(SOUND_BIN_DIR)/sequences.bin
|
||||
@true
|
||||
|
||||
$(SOUND_BIN_DIR)/sequences_offsets.inc.c: $(SOUND_BIN_DIR)/sequences.bin
|
||||
@true
|
||||
|
||||
$(SOUND_BIN_DIR)/%.m64: $(SOUND_BIN_DIR)/%.o
|
||||
$(call print,Converting to M64:,$<,$@)
|
||||
$(V)$(OBJCOPY) -j .rodata $< -O binary $@
|
||||
|
|
|
@ -13,3 +13,6 @@ Interestingly enough though, the goal of the project has slowly evolved over tim
|
|||
|
||||
## Lua
|
||||
sm64coopdx is moddable via Lua, similar to Roblox and Garry's Mod's Lua APIs. To get started, click [here](docs/lua/lua.md) to see the Lua documentation.
|
||||
|
||||
## Wiki
|
||||
The wiki is made using GitHub's wiki feature, you can go to the wiki tab or click [here](https://github.com/coop-deluxe/sm64coopdx/wiki).
|
||||
|
|
|
@ -88,7 +88,7 @@ override_allowed_functions = {
|
|||
|
||||
override_disallowed_functions = {
|
||||
"src/audio/external.h": [ " func_" ],
|
||||
"src/engine/math_util.h": [ "atan2s", "atan2f", "vec3s_sub" ],
|
||||
"src/engine/math_util.h": [ "atan2f", "vec3s_sub" ],
|
||||
"src/engine/surface_load.h": [ "alloc_surface_poools" ],
|
||||
"src/engine/surface_collision.h": [ " debug_", "f32_find_wall_collision" ],
|
||||
"src/game/mario_actions_airborne.c": [ "^[us]32 act_.*" ],
|
||||
|
@ -114,7 +114,7 @@ override_disallowed_functions = {
|
|||
"src/pc/lua/utils/smlua_obj_utils.h": [ "spawn_object_remember_field" ],
|
||||
"src/game/camera.h": [ "update_camera", "init_camera", "stub_camera", "^reset_camera", "move_point_along_spline" ],
|
||||
"src/game/behavior_actions.h": [ "bhv_dust_smoke_loop", "bhv_init_room" ],
|
||||
"src/pc/lua/utils/smlua_audio_utils.h": [ "smlua_audio_utils_override", "audio_custom_shutdown", "smlua_audio_custom_init", "smlua_audio_custom_deinit", "audio_sample_destroy_pending_copies", "audio_custom_update_volume" ],
|
||||
"src/pc/lua/utils/smlua_audio_utils.h": [ "smlua_audio_utils_override", "audio_custom_shutdown", "smlua_audio_custom_deinit", "audio_sample_destroy_pending_copies", "audio_custom_update_volume" ],
|
||||
"src/pc/djui/djui_hud_utils.h": [ "djui_hud_render_texture", "djui_hud_render_texture_raw", "djui_hud_render_texture_tile", "djui_hud_render_texture_tile_raw" ],
|
||||
"src/pc/lua/utils/smlua_level_utils.h": [ "smlua_level_util_reset" ],
|
||||
"src/pc/lua/utils/smlua_text_utils.h": [ "smlua_text_utils_init", "smlua_text_utils_shutdown", "smlua_text_utils_reset_all" ],
|
||||
|
|
|
@ -1,77 +1,5 @@
|
|||
math.randomseed(get_time())
|
||||
|
||||
|
||||
--------------
|
||||
-- CObjects --
|
||||
--------------
|
||||
|
||||
_CObjectPool = {}
|
||||
|
||||
_CObject = {
|
||||
__index = function (t,k)
|
||||
return _get_field(t['_lot'], t['_pointer'], k, t)
|
||||
end,
|
||||
__newindex = function (t,k,v)
|
||||
_set_field(t['_lot'], t['_pointer'], k, v, t)
|
||||
end,
|
||||
__tostring = function(t)
|
||||
return 'CObject: ' .. t['_lot'] .. ', [' .. string.format('0x%08X', t['_pointer']) .. ']'
|
||||
end,
|
||||
__eq = function (a, b)
|
||||
return a['_pointer'] == b['_pointer'] and a['_lot'] == b['_lot'] and a['_pointer'] ~= nil and a['_lot'] ~= nil
|
||||
end
|
||||
}
|
||||
|
||||
function _NewCObject(lot, pointer)
|
||||
if _CObjectPool[lot] == nil then
|
||||
_CObjectPool[lot] = {}
|
||||
end
|
||||
|
||||
if _CObjectPool[lot][pointer] == nil then
|
||||
local obj = {}
|
||||
rawset(obj, '_pointer', pointer)
|
||||
rawset(obj, '_lot', lot)
|
||||
setmetatable(obj, _CObject)
|
||||
_CObjectPool[lot][pointer] = obj
|
||||
return obj
|
||||
end
|
||||
|
||||
return _CObjectPool[lot][pointer]
|
||||
end
|
||||
|
||||
local _CPointerPool = {}
|
||||
|
||||
_CPointer = {
|
||||
__index = function (t,k)
|
||||
return nil
|
||||
end,
|
||||
__newindex = function (t,k,v)
|
||||
end,
|
||||
__tostring = function(t)
|
||||
return 'CPointer: ' .. t['_lvt'] .. ', [' .. string.format('0x%08X', t['_pointer']) .. ']'
|
||||
end,
|
||||
__eq = function (a, b)
|
||||
return a['_pointer'] == b['_pointer'] and a['_pointer'] ~= nil and a['_lvt'] ~= nil
|
||||
end
|
||||
}
|
||||
|
||||
function _NewCPointer(lvt, pointer)
|
||||
if _CPointerPool[lvt] == nil then
|
||||
_CPointerPool[lvt] = {}
|
||||
end
|
||||
|
||||
if _CPointerPool[lvt][pointer] == nil then
|
||||
local obj = {}
|
||||
rawset(obj, '_pointer', pointer)
|
||||
rawset(obj, '_lvt', lvt)
|
||||
setmetatable(obj, _CPointer)
|
||||
_CPointerPool[lvt][pointer] = obj
|
||||
return obj
|
||||
end
|
||||
|
||||
return _CPointerPool[lvt][pointer]
|
||||
end
|
||||
|
||||
_SyncTable = {
|
||||
__index = function (t,k)
|
||||
local _table = rawget(t, '_table')
|
||||
|
|
|
@ -2,78 +2,6 @@
|
|||
|
||||
math.randomseed(get_time())
|
||||
|
||||
|
||||
--------------
|
||||
-- CObjects --
|
||||
--------------
|
||||
|
||||
_CObjectPool = {}
|
||||
|
||||
_CObject = {
|
||||
__index = function (t,k)
|
||||
return _get_field(t['_lot'], t['_pointer'], k, t)
|
||||
end,
|
||||
__newindex = function (t,k,v)
|
||||
_set_field(t['_lot'], t['_pointer'], k, v, t)
|
||||
end,
|
||||
__tostring = function(t)
|
||||
return 'CObject: ' .. t['_lot'] .. ', [' .. string.format('0x%08X', t['_pointer']) .. ']'
|
||||
end,
|
||||
__eq = function (a, b)
|
||||
return a['_pointer'] == b['_pointer'] and a['_lot'] == b['_lot'] and a['_pointer'] ~= nil and a['_lot'] ~= nil
|
||||
end
|
||||
}
|
||||
|
||||
function _NewCObject(lot, pointer)
|
||||
if _CObjectPool[lot] == nil then
|
||||
_CObjectPool[lot] = {}
|
||||
end
|
||||
|
||||
if _CObjectPool[lot][pointer] == nil then
|
||||
local obj = {}
|
||||
rawset(obj, '_pointer', pointer)
|
||||
rawset(obj, '_lot', lot)
|
||||
setmetatable(obj, _CObject)
|
||||
_CObjectPool[lot][pointer] = obj
|
||||
return obj
|
||||
end
|
||||
|
||||
return _CObjectPool[lot][pointer]
|
||||
end
|
||||
|
||||
local _CPointerPool = {}
|
||||
|
||||
_CPointer = {
|
||||
__index = function (t,k)
|
||||
return nil
|
||||
end,
|
||||
__newindex = function (t,k,v)
|
||||
end,
|
||||
__tostring = function(t)
|
||||
return 'CPointer: ' .. t['_lvt'] .. ', [' .. string.format('0x%08X', t['_pointer']) .. ']'
|
||||
end,
|
||||
__eq = function (a, b)
|
||||
return a['_pointer'] == b['_pointer'] and a['_pointer'] ~= nil and a['_lvt'] ~= nil
|
||||
end
|
||||
}
|
||||
|
||||
function _NewCPointer(lvt, pointer)
|
||||
if _CPointerPool[lvt] == nil then
|
||||
_CPointerPool[lvt] = {}
|
||||
end
|
||||
|
||||
if _CPointerPool[lvt][pointer] == nil then
|
||||
local obj = {}
|
||||
rawset(obj, '_pointer', pointer)
|
||||
rawset(obj, '_lvt', lvt)
|
||||
setmetatable(obj, _CPointer)
|
||||
_CPointerPool[lvt][pointer] = obj
|
||||
return obj
|
||||
end
|
||||
|
||||
return _CPointerPool[lvt][pointer]
|
||||
end
|
||||
|
||||
_SyncTable = {
|
||||
__index = function (t,k)
|
||||
local _table = rawget(t, '_table')
|
||||
|
@ -3779,6 +3707,9 @@ INT_TWIRL = (1 << 8)
|
|||
--- @type InteractionFlag
|
||||
INT_GROUND_POUND_OR_TWIRL = (INT_GROUND_POUND | INT_TWIRL)
|
||||
|
||||
--- @type InteractionFlag
|
||||
INT_LUA = (1 << 31)
|
||||
|
||||
--- @class InteractionType
|
||||
|
||||
--- @type InteractionType
|
||||
|
@ -5571,7 +5502,7 @@ MARIO_HAND_RIGHT_OPEN = 5
|
|||
MAX_KEYS = 512
|
||||
|
||||
--- @type integer
|
||||
MAX_KEY_VALUE_LENGTH = 256
|
||||
MAX_KEY_VALUE_LENGTH = 512
|
||||
|
||||
--- @type integer
|
||||
PACKET_LENGTH = 3000
|
||||
|
@ -9230,7 +9161,10 @@ HOOK_ON_LANGUAGE_CHANGED = 44
|
|||
HOOK_ON_MODS_LOADED = 45
|
||||
|
||||
--- @type LuaHookedEventType
|
||||
HOOK_MAX = 46
|
||||
HOOK_ON_NAMETAGS_RENDER = 46
|
||||
|
||||
--- @type LuaHookedEventType
|
||||
HOOK_MAX = 47
|
||||
|
||||
--- @class LuaModMenuElementType
|
||||
|
||||
|
@ -12557,10 +12491,10 @@ SPTASK_STATE_FINISHED_DP = 4
|
|||
MAX_VERSION_LENGTH = 32
|
||||
|
||||
--- @type integer
|
||||
MINOR_VERSION_NUMBER = 2
|
||||
MINOR_VERSION_NUMBER = 3
|
||||
|
||||
--- @type string
|
||||
SM64COOPDX_VERSION = "v1.0.3"
|
||||
SM64COOPDX_VERSION = "v1.0.4"
|
||||
|
||||
--- @type integer
|
||||
VERSION_NUMBER = 37
|
||||
|
|
|
@ -3070,6 +3070,11 @@ function djui_hud_get_font()
|
|||
-- ...
|
||||
end
|
||||
|
||||
--- @return number
|
||||
function djui_hud_get_fov_coeff()
|
||||
-- ...
|
||||
end
|
||||
|
||||
--- @return number
|
||||
function djui_hud_get_mouse_x()
|
||||
-- ...
|
||||
|
@ -3220,6 +3225,11 @@ function djui_open_pause_menu()
|
|||
-- ...
|
||||
end
|
||||
|
||||
--- @return number
|
||||
function get_current_fov()
|
||||
-- ...
|
||||
end
|
||||
|
||||
--- @param message string
|
||||
--- @param lines integer
|
||||
function djui_popup_create(message, lines)
|
||||
|
@ -5024,6 +5034,19 @@ function approach_s32(current, target, inc, dec)
|
|||
-- ...
|
||||
end
|
||||
|
||||
--- @param y number
|
||||
--- @param x number
|
||||
--- @return integer
|
||||
function atan2s(y, x)
|
||||
-- ...
|
||||
end
|
||||
|
||||
--- @param sm64Angle integer
|
||||
--- @return number
|
||||
function coss(sm64Angle)
|
||||
-- ...
|
||||
end
|
||||
|
||||
--- @param dest Vec3f
|
||||
--- @param a Vec3f
|
||||
--- @param b Vec3f
|
||||
|
@ -5040,6 +5063,34 @@ function get_pos_from_transform_mtx(dest, objMtx, camMtx)
|
|||
-- ...
|
||||
end
|
||||
|
||||
--- @param a integer
|
||||
--- @param b integer
|
||||
--- @return integer
|
||||
function max(a, b)
|
||||
-- ...
|
||||
end
|
||||
|
||||
--- @param a number
|
||||
--- @param b number
|
||||
--- @return number
|
||||
function maxf(a, b)
|
||||
-- ...
|
||||
end
|
||||
|
||||
--- @param a integer
|
||||
--- @param b integer
|
||||
--- @return integer
|
||||
function min(a, b)
|
||||
-- ...
|
||||
end
|
||||
|
||||
--- @param a number
|
||||
--- @param b number
|
||||
--- @return number
|
||||
function minf(a, b)
|
||||
-- ...
|
||||
end
|
||||
|
||||
--- @param dest Mat4
|
||||
--- @param upDir Vec3f
|
||||
--- @param pos Vec3f
|
||||
|
@ -5156,6 +5207,12 @@ function not_zero(value, replacement)
|
|||
-- ...
|
||||
end
|
||||
|
||||
--- @param sm64Angle integer
|
||||
--- @return number
|
||||
function sins(sm64Angle)
|
||||
-- ...
|
||||
end
|
||||
|
||||
--- @param m MarioState
|
||||
--- @param result Vec4f
|
||||
--- @param t number
|
||||
|
@ -5164,6 +5221,18 @@ function spline_get_weights(m, result, t, c)
|
|||
-- ...
|
||||
end
|
||||
|
||||
--- @param x integer
|
||||
--- @return integer
|
||||
function sqr(x)
|
||||
-- ...
|
||||
end
|
||||
|
||||
--- @param x number
|
||||
--- @return number
|
||||
function sqrf(x)
|
||||
-- ...
|
||||
end
|
||||
|
||||
--- @param dest Vec3f
|
||||
--- @param a Vec3f
|
||||
--- @return void*
|
||||
|
@ -5454,6 +5523,12 @@ function network_player_set_description(np, description, r, g, b, a)
|
|||
-- ...
|
||||
end
|
||||
|
||||
--- @param np NetworkPlayer
|
||||
--- @param location string
|
||||
function network_player_set_override_location(np, location)
|
||||
-- ...
|
||||
end
|
||||
|
||||
--- @param np NetworkPlayer
|
||||
--- @param part PlayerPart
|
||||
--- @param color Color
|
||||
|
@ -7807,6 +7882,11 @@ function camera_freeze()
|
|||
-- ...
|
||||
end
|
||||
|
||||
--- @return boolean
|
||||
function camera_get_checking_surfaces()
|
||||
-- ...
|
||||
end
|
||||
|
||||
--- @return boolean
|
||||
function camera_is_frozen()
|
||||
-- ...
|
||||
|
@ -7826,6 +7906,11 @@ function camera_romhack_allow_dpad_usage(allow)
|
|||
-- ...
|
||||
end
|
||||
|
||||
--- @param value boolean
|
||||
function camera_set_checking_surfaces(value)
|
||||
-- ...
|
||||
end
|
||||
|
||||
--- @param rco RomhackCameraOverride
|
||||
function camera_set_romhack_override(rco)
|
||||
-- ...
|
||||
|
@ -8123,43 +8208,34 @@ function clampf(a, b, c)
|
|||
-- ...
|
||||
end
|
||||
|
||||
--- @param a integer
|
||||
--- @param b integer
|
||||
--- @param degreesAngle number
|
||||
--- @return integer
|
||||
function max(a, b)
|
||||
function degrees_to_sm64(degreesAngle)
|
||||
-- ...
|
||||
end
|
||||
|
||||
--- @param a number
|
||||
--- @param b number
|
||||
--- @return number
|
||||
function maxf(a, b)
|
||||
function hypotf(a, b)
|
||||
-- ...
|
||||
end
|
||||
|
||||
--- @param a integer
|
||||
--- @param b integer
|
||||
--- @param radiansAngle number
|
||||
--- @return integer
|
||||
function min(a, b)
|
||||
function radians_to_sm64(radiansAngle)
|
||||
-- ...
|
||||
end
|
||||
|
||||
--- @param a number
|
||||
--- @param b number
|
||||
--- @param sm64Angle integer
|
||||
--- @return number
|
||||
function minf(a, b)
|
||||
function sm64_to_degrees(sm64Angle)
|
||||
-- ...
|
||||
end
|
||||
|
||||
--- @param x integer
|
||||
--- @return integer
|
||||
function sqr(x)
|
||||
-- ...
|
||||
end
|
||||
|
||||
--- @param x number
|
||||
--- @param sm64Angle integer
|
||||
--- @return number
|
||||
function sqrf(x)
|
||||
function sm64_to_radians(sm64Angle)
|
||||
-- ...
|
||||
end
|
||||
|
||||
|
@ -8181,6 +8257,11 @@ function deref_s32_pointer(pointer)
|
|||
-- ...
|
||||
end
|
||||
|
||||
--- @return boolean
|
||||
function djui_attempting_to_open_playerlist()
|
||||
-- ...
|
||||
end
|
||||
|
||||
--- @return boolean
|
||||
function djui_is_playerlist_open()
|
||||
-- ...
|
||||
|
@ -8211,6 +8292,12 @@ function djui_set_popup_disabled_override(value)
|
|||
-- ...
|
||||
end
|
||||
|
||||
--- @param localIndex integer
|
||||
--- @return string
|
||||
function get_coopnet_id(localIndex)
|
||||
-- ...
|
||||
end
|
||||
|
||||
--- @return integer
|
||||
function get_current_save_file_num()
|
||||
-- ...
|
||||
|
|
|
@ -192,29 +192,34 @@ function update_mod_menu_element_name(index, name)
|
|||
-- ...
|
||||
end
|
||||
|
||||
--- @param index integer The index of the element in the order in which they were hooked
|
||||
--- @param value boolean The boolean value to change to
|
||||
--- Updates a mod menu checkbox element's boolean value
|
||||
--- - NOTE: `index` is zero-indexed
|
||||
function update_mod_menu_element_checkbox(index, value)
|
||||
-- ...
|
||||
end
|
||||
|
||||
--- @param index integer The index of the element in the order in which they were hooked
|
||||
--- @param value number The number value to change to
|
||||
--- Updates a mod menu slider element's numerical value
|
||||
--- - NOTE: `index` is zero-indexed
|
||||
function update_mod_menu_element_slider(index, value)
|
||||
-- ...
|
||||
end
|
||||
|
||||
--- @param index integer The index of the element in the order in which they were hooked
|
||||
--- @param value string The text to change to
|
||||
--- Updates a mod menu inputbox element's string value
|
||||
--- - NOTE: `index` is zero-indexed
|
||||
function update_mod_menu_element_inputbox(index, value)
|
||||
-- ...
|
||||
end
|
||||
|
||||
---------------
|
||||
-- functions --
|
||||
---------------
|
||||
|
||||
--- @param t number Angle
|
||||
--- @return number
|
||||
function sins(t)
|
||||
-- ...
|
||||
end
|
||||
|
||||
--- @param t number Angle
|
||||
--- @return number
|
||||
function coss(t)
|
||||
-- ...
|
||||
end
|
||||
|
||||
--- @param y number
|
||||
--- @param x number
|
||||
--- @return integer
|
||||
function atan2s(y, x)
|
||||
-- ...
|
||||
end
|
||||
|
||||
--- @param objFieldTable table<any, "u32"|"s32"|"f32">
|
||||
--- Keys must start with `o` and values must be `"u32"`, `"s32"`, or `"f32"`
|
||||
function define_custom_obj_fields(objFieldTable)
|
||||
|
@ -382,4 +387,4 @@ end
|
|||
--- Shoots a raycast from `startX`, `startY`, and `startZ` in the direction of `dirX`, `dirY`, and `dirZ`
|
||||
function collision_find_surface_on_ray(startX, startY, startZ, dirX, dirY, dirZ, precision)
|
||||
-- ...
|
||||
end
|
||||
end
|
||||
|
|
|
@ -537,6 +537,7 @@
|
|||
--- @class Controller
|
||||
--- @field public buttonDown integer
|
||||
--- @field public buttonPressed integer
|
||||
--- @field public buttonReleased integer
|
||||
--- @field public extStickX integer
|
||||
--- @field public extStickY integer
|
||||
--- @field public port integer
|
||||
|
@ -1125,6 +1126,7 @@
|
|||
--- @field public modelIndex integer
|
||||
--- @field public name string
|
||||
--- @field public onRxSeqId integer
|
||||
--- @field public overrideLocation string
|
||||
--- @field public overrideModelIndex integer
|
||||
--- @field public overridePalette PlayerPalette
|
||||
--- @field public overridePaletteIndex integer
|
||||
|
|
|
@ -149,12 +149,12 @@ static void DynOS_Actor_Generate(const SysPath &aPackFolder, Array<Pair<u64, Str
|
|||
// If there is an existing binary file for this layout, skip and go to the next actor
|
||||
SysPath _BinFilename = fstring("%s/%s.bin", aPackFolder.c_str(), _GeoRootName.begin());
|
||||
if (fs_sys_file_exists(_BinFilename.c_str())) {
|
||||
#ifdef DEVELOPMENT
|
||||
|
||||
// Compress file to gain some space
|
||||
if (!DynOS_Bin_IsCompressed(_BinFilename)) {
|
||||
if (configCompressOnStartup && !DynOS_Bin_IsCompressed(_BinFilename)) {
|
||||
DynOS_Bin_Compress(_BinFilename);
|
||||
}
|
||||
#endif
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -260,14 +260,14 @@ void DynOS_Actor_GeneratePack(const SysPath &aPackFolder) {
|
|||
if (SysPath(_PackEnt->d_name) == ".") continue;
|
||||
if (SysPath(_PackEnt->d_name) == "..") continue;
|
||||
|
||||
#ifdef DEVELOPMENT
|
||||
// Compress .bin files to gain some space
|
||||
SysPath _Filename = fstring("%s/%s", aPackFolder.c_str(), _PackEnt->d_name);
|
||||
if (SysPath(_PackEnt->d_name).find(".bin") != SysPath::npos && !DynOS_Bin_IsCompressed(_Filename)) {
|
||||
DynOS_Bin_Compress(_Filename);
|
||||
continue;
|
||||
if (configCompressOnStartup) {
|
||||
SysPath _Filename = fstring("%s/%s", aPackFolder.c_str(), _PackEnt->d_name);
|
||||
if (SysPath(_PackEnt->d_name).find(".bin") != SysPath::npos && !DynOS_Bin_IsCompressed(_Filename)) {
|
||||
DynOS_Bin_Compress(_Filename);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// For each subfolder, read tokens from model.inc.c and geo.inc.c
|
||||
SysPath _Folder = fstring("%s/%s", aPackFolder.c_str(), _PackEnt->d_name);
|
||||
|
|
|
@ -691,13 +691,13 @@ void DynOS_Col_Generate(const SysPath &aPackFolder, Array<Pair<u64, String>> _Ac
|
|||
// If there is an existing binary file for this collision, skip and go to the next actor
|
||||
SysPath _ColFilename = fstring("%s/%s.col", aPackFolder.c_str(), _ColRootName.begin());
|
||||
if (fs_sys_file_exists(_ColFilename.c_str())) {
|
||||
#ifdef DEVELOPMENT
|
||||
|
||||
// Compress file to gain some space
|
||||
if (!DynOS_Bin_IsCompressed(_ColFilename)) {
|
||||
if (configCompressOnStartup && !DynOS_Bin_IsCompressed(_ColFilename)) {
|
||||
DynOS_Bin_Compress(_ColFilename);
|
||||
}
|
||||
|
||||
continue;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Init
|
||||
|
|
|
@ -1119,12 +1119,12 @@ static bool DynOS_Lvl_GeneratePack_Internal(const SysPath &aPackFolder, Array<Pa
|
|||
// If there is an existing binary file for this level, skip and go to the next level
|
||||
SysPath _LvlFilename = fstring("%s/%s.lvl", aPackFolder.c_str(), _LvlRootName.begin());
|
||||
if (fs_sys_file_exists(_LvlFilename.c_str())) {
|
||||
#ifdef DEVELOPMENT
|
||||
|
||||
// Compress file to gain some space
|
||||
if (!DynOS_Bin_IsCompressed(_LvlFilename)) {
|
||||
if (configCompressOnStartup && !DynOS_Bin_IsCompressed(_LvlFilename)) {
|
||||
DynOS_Bin_Compress(_LvlFilename);
|
||||
}
|
||||
#endif
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -1247,15 +1247,14 @@ void DynOS_Lvl_GeneratePack(const SysPath &aPackFolder) {
|
|||
if (SysPath(_PackEnt->d_name) == ".") continue;
|
||||
if (SysPath(_PackEnt->d_name) == "..") continue;
|
||||
|
||||
#ifdef DEVELOPMENT
|
||||
// Compress .lvl files to gain some space
|
||||
// TODO: is this required anymore?
|
||||
/*SysPath _Filename = fstring("%s/%s", aPackFolder.c_str(), _PackEnt->d_name);
|
||||
if (SysPath(_PackEnt->d_name).find(".lvl") != SysPath::npos && !DynOS_Bin_IsCompressed(_Filename)) {
|
||||
DynOS_Bin_Compress(_Filename);
|
||||
continue;
|
||||
}*/
|
||||
#endif
|
||||
if (configCompressOnStartup) {
|
||||
SysPath _Filename = fstring("%s/%s", aPackFolder.c_str(), _PackEnt->d_name);
|
||||
if (SysPath(_PackEnt->d_name).find(".lvl") != SysPath::npos && !DynOS_Bin_IsCompressed(_Filename)) {
|
||||
DynOS_Bin_Compress(_Filename);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// For each subfolder, read tokens from script.c
|
||||
SysPath _Folder = fstring("%s/%s", aPackFolder.c_str(), _PackEnt->d_name);
|
||||
|
|
|
@ -36,14 +36,18 @@ char *DynOS_Read_Buffer(FILE* aFile, GfxData* aGfxData) {
|
|||
aGfxData->mModelIdentifier = (u32) _Length;
|
||||
}
|
||||
|
||||
// Remove comments
|
||||
char *_OrigFileBuffer = New<char>(_Length + 1);
|
||||
char *pOrigFileBuffer = _OrigFileBuffer;
|
||||
rewind(aFile);
|
||||
_OrigFileBuffer[fread(_OrigFileBuffer, 1, _Length, aFile)] = 0;
|
||||
|
||||
// Remove comments
|
||||
char *_FileBuffer = New<char>(_Length + 1);
|
||||
char *pFileBuffer = _FileBuffer;
|
||||
char _Previous = 0;
|
||||
char _Current = 0;
|
||||
s32 _CommentType = 0;
|
||||
while (fread(&_Current, 1, 1, aFile)) {
|
||||
while ((_Current = *pOrigFileBuffer++)) {
|
||||
if (_CommentType == COMMENT_NONE) {
|
||||
if (_Current == '/') {
|
||||
_CommentType = COMMENT_START;
|
||||
|
@ -79,6 +83,7 @@ char *DynOS_Read_Buffer(FILE* aFile, GfxData* aGfxData) {
|
|||
_Previous = _Current;
|
||||
}
|
||||
*(pFileBuffer++) = 0;
|
||||
Delete(_OrigFileBuffer);
|
||||
|
||||
// Remove ifdef blocks
|
||||
// Doesn't support nested blocks
|
||||
|
|
|
@ -1,8 +1,13 @@
|
|||
#include "dynos.cpp.h"
|
||||
extern "C" {
|
||||
#include "pc/loading.h"
|
||||
}
|
||||
|
||||
void DynOS_Gfx_GeneratePacks(const char* directory) {
|
||||
LOADING_SCREEN_MUTEX(snprintf(gCurrLoadingSegment.str, 256, "Generating DynOS Packs In Path:\n\\#808080\\%s", directory));
|
||||
LOADING_SCREEN_MUTEX(
|
||||
loading_screen_reset_progress_bar();
|
||||
snprintf(gCurrLoadingSegment.str, 256, "Generating DynOS Packs In Path:\n\\#808080\\%s", directory);
|
||||
);
|
||||
|
||||
DIR *modsDir = opendir(directory);
|
||||
if (!modsDir) { return; }
|
||||
|
|
|
@ -1975,6 +1975,7 @@ static const void* sDynosBuiltinFuncs[] = {
|
|||
define_builtin(bhv_star_number_loop),
|
||||
define_builtin(spawn_star_number),
|
||||
define_builtin(bhv_ferris_wheel_platform_init),
|
||||
define_builtin(geo_mario_cap_display_list),
|
||||
};
|
||||
|
||||
const void* DynOS_Builtin_Func_GetFromName(const char* aDataName) {
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -176,6 +176,7 @@ static void *DynOS_Warp_UpdateWarp(void *aCmd, bool aIsLevelInitDone) {
|
|||
gMarioState->numCoins = 0;
|
||||
gMarioState->input = 0;
|
||||
gMarioState->controller->buttonPressed = 0;
|
||||
gMarioState->controller->buttonReleased = 0;
|
||||
gHudDisplay.coins = 0;
|
||||
|
||||
// Set up new level values
|
||||
|
@ -337,6 +338,7 @@ static void *DynOS_Warp_UpdateExit(void *aCmd, bool aIsLevelInitDone) {
|
|||
gMarioState->numCoins = 0;
|
||||
gMarioState->input = 0;
|
||||
gMarioState->controller->buttonPressed = 0;
|
||||
gMarioState->controller->buttonReleased = 0;
|
||||
gHudDisplay.coins = 0;
|
||||
|
||||
// Set up new level values
|
||||
|
|
|
@ -1309,6 +1309,7 @@
|
|||
| INT_HIT_FROM_BELOW | (1 << 7) |
|
||||
| INT_TWIRL | (1 << 8) |
|
||||
| INT_GROUND_POUND_OR_TWIRL | (INT_GROUND_POUND | INT_TWIRL) |
|
||||
| INT_LUA | (1 << 31) |
|
||||
|
||||
### [enum InteractionType](#InteractionType)
|
||||
| Identifier | Value |
|
||||
|
@ -3297,7 +3298,8 @@
|
|||
| HOOK_ON_ATTACK_OBJECT | 43 |
|
||||
| HOOK_ON_LANGUAGE_CHANGED | 44 |
|
||||
| HOOK_ON_MODS_LOADED | 45 |
|
||||
| HOOK_MAX | 46 |
|
||||
| HOOK_ON_NAMETAGS_RENDER | 46 |
|
||||
| HOOK_MAX | 47 |
|
||||
|
||||
### [enum LuaModMenuElementType](#LuaModMenuElementType)
|
||||
| Identifier | Value |
|
||||
|
|
|
@ -2170,6 +2170,24 @@
|
|||
|
||||
<br />
|
||||
|
||||
## [djui_hud_get_fov_coeff](#djui_hud_get_fov_coeff)
|
||||
|
||||
### Lua Example
|
||||
`local numberValue = djui_hud_get_fov_coeff()`
|
||||
|
||||
### Parameters
|
||||
- None
|
||||
|
||||
### Returns
|
||||
- `number`
|
||||
|
||||
### C Prototype
|
||||
`f32 djui_hud_get_fov_coeff();`
|
||||
|
||||
[:arrow_up_small:](#)
|
||||
|
||||
<br />
|
||||
|
||||
## [djui_hud_get_mouse_x](#djui_hud_get_mouse_x)
|
||||
|
||||
### Lua Example
|
||||
|
@ -2658,6 +2676,24 @@
|
|||
|
||||
<br />
|
||||
|
||||
## [get_current_fov](#get_current_fov)
|
||||
|
||||
### Lua Example
|
||||
`local numberValue = get_current_fov()`
|
||||
|
||||
### Parameters
|
||||
- None
|
||||
|
||||
### Returns
|
||||
- `number`
|
||||
|
||||
### C Prototype
|
||||
`f32 get_current_fov();`
|
||||
|
||||
[:arrow_up_small:](#)
|
||||
|
||||
<br />
|
||||
|
||||
---
|
||||
# functions from djui_popup.h
|
||||
|
||||
|
|
|
@ -99,6 +99,47 @@
|
|||
|
||||
<br />
|
||||
|
||||
## [atan2s](#atan2s)
|
||||
|
||||
### Lua Example
|
||||
`local integerValue = atan2s(y, x)`
|
||||
|
||||
### Parameters
|
||||
| Field | Type |
|
||||
| ----- | ---- |
|
||||
| y | `number` |
|
||||
| x | `number` |
|
||||
|
||||
### Returns
|
||||
- `integer`
|
||||
|
||||
### C Prototype
|
||||
`s16 atan2s(f32 y, f32 x);`
|
||||
|
||||
[:arrow_up_small:](#)
|
||||
|
||||
<br />
|
||||
|
||||
## [coss](#coss)
|
||||
|
||||
### Lua Example
|
||||
`local numberValue = coss(sm64Angle)`
|
||||
|
||||
### Parameters
|
||||
| Field | Type |
|
||||
| ----- | ---- |
|
||||
| sm64Angle | `integer` |
|
||||
|
||||
### Returns
|
||||
- `number`
|
||||
|
||||
### C Prototype
|
||||
`f32 coss(s16 sm64Angle);`
|
||||
|
||||
[:arrow_up_small:](#)
|
||||
|
||||
<br />
|
||||
|
||||
## [find_vector_perpendicular_to_plane](#find_vector_perpendicular_to_plane)
|
||||
|
||||
### Lua Example
|
||||
|
@ -144,6 +185,90 @@
|
|||
|
||||
<br />
|
||||
|
||||
## [max](#max)
|
||||
|
||||
### Lua Example
|
||||
`local integerValue = max(a, b)`
|
||||
|
||||
### Parameters
|
||||
| Field | Type |
|
||||
| ----- | ---- |
|
||||
| a | `integer` |
|
||||
| b | `integer` |
|
||||
|
||||
### Returns
|
||||
- `integer`
|
||||
|
||||
### C Prototype
|
||||
`s16 max(s16 a, s16 b);`
|
||||
|
||||
[:arrow_up_small:](#)
|
||||
|
||||
<br />
|
||||
|
||||
## [maxf](#maxf)
|
||||
|
||||
### Lua Example
|
||||
`local numberValue = maxf(a, b)`
|
||||
|
||||
### Parameters
|
||||
| Field | Type |
|
||||
| ----- | ---- |
|
||||
| a | `number` |
|
||||
| b | `number` |
|
||||
|
||||
### Returns
|
||||
- `number`
|
||||
|
||||
### C Prototype
|
||||
`f32 maxf(f32 a, f32 b);`
|
||||
|
||||
[:arrow_up_small:](#)
|
||||
|
||||
<br />
|
||||
|
||||
## [min](#min)
|
||||
|
||||
### Lua Example
|
||||
`local integerValue = min(a, b)`
|
||||
|
||||
### Parameters
|
||||
| Field | Type |
|
||||
| ----- | ---- |
|
||||
| a | `integer` |
|
||||
| b | `integer` |
|
||||
|
||||
### Returns
|
||||
- `integer`
|
||||
|
||||
### C Prototype
|
||||
`s16 min(s16 a, s16 b);`
|
||||
|
||||
[:arrow_up_small:](#)
|
||||
|
||||
<br />
|
||||
|
||||
## [minf](#minf)
|
||||
|
||||
### Lua Example
|
||||
`local numberValue = minf(a, b)`
|
||||
|
||||
### Parameters
|
||||
| Field | Type |
|
||||
| ----- | ---- |
|
||||
| a | `number` |
|
||||
| b | `number` |
|
||||
|
||||
### Returns
|
||||
- `number`
|
||||
|
||||
### C Prototype
|
||||
`f32 minf(f32 a, f32 b);`
|
||||
|
||||
[:arrow_up_small:](#)
|
||||
|
||||
<br />
|
||||
|
||||
## [mtxf_align_terrain_normal](#mtxf_align_terrain_normal)
|
||||
|
||||
### Lua Example
|
||||
|
@ -514,6 +639,26 @@
|
|||
|
||||
<br />
|
||||
|
||||
## [sins](#sins)
|
||||
|
||||
### Lua Example
|
||||
`local numberValue = sins(sm64Angle)`
|
||||
|
||||
### Parameters
|
||||
| Field | Type |
|
||||
| ----- | ---- |
|
||||
| sm64Angle | `integer` |
|
||||
|
||||
### Returns
|
||||
- `number`
|
||||
|
||||
### C Prototype
|
||||
`f32 sins(s16 sm64Angle);`
|
||||
|
||||
[:arrow_up_small:](#)
|
||||
|
||||
<br />
|
||||
|
||||
## [spline_get_weights](#spline_get_weights)
|
||||
|
||||
### Lua Example
|
||||
|
@ -537,6 +682,46 @@
|
|||
|
||||
<br />
|
||||
|
||||
## [sqr](#sqr)
|
||||
|
||||
### Lua Example
|
||||
`local integerValue = sqr(x)`
|
||||
|
||||
### Parameters
|
||||
| Field | Type |
|
||||
| ----- | ---- |
|
||||
| x | `integer` |
|
||||
|
||||
### Returns
|
||||
- `integer`
|
||||
|
||||
### C Prototype
|
||||
`s16 sqr(s16 x);`
|
||||
|
||||
[:arrow_up_small:](#)
|
||||
|
||||
<br />
|
||||
|
||||
## [sqrf](#sqrf)
|
||||
|
||||
### Lua Example
|
||||
`local numberValue = sqrf(x)`
|
||||
|
||||
### Parameters
|
||||
| Field | Type |
|
||||
| ----- | ---- |
|
||||
| x | `number` |
|
||||
|
||||
### Returns
|
||||
- `number`
|
||||
|
||||
### C Prototype
|
||||
`f32 sqrf(f32 x);`
|
||||
|
||||
[:arrow_up_small:](#)
|
||||
|
||||
<br />
|
||||
|
||||
## [vec3f_add](#vec3f_add)
|
||||
|
||||
### Lua Example
|
||||
|
@ -1378,6 +1563,27 @@
|
|||
|
||||
<br />
|
||||
|
||||
## [network_player_set_override_location](#network_player_set_override_location)
|
||||
|
||||
### Lua Example
|
||||
`network_player_set_override_location(np, location)`
|
||||
|
||||
### Parameters
|
||||
| Field | Type |
|
||||
| ----- | ---- |
|
||||
| np | [NetworkPlayer](structs.md#NetworkPlayer) |
|
||||
| location | `string` |
|
||||
|
||||
### Returns
|
||||
- None
|
||||
|
||||
### C Prototype
|
||||
`void network_player_set_override_location(struct NetworkPlayer *np, const char *location);`
|
||||
|
||||
[:arrow_up_small:](#)
|
||||
|
||||
<br />
|
||||
|
||||
## [network_player_set_override_palette_color](#network_player_set_override_palette_color)
|
||||
|
||||
### Lua Example
|
||||
|
|
|
@ -824,6 +824,24 @@
|
|||
|
||||
<br />
|
||||
|
||||
## [camera_get_checking_surfaces](#camera_get_checking_surfaces)
|
||||
|
||||
### Lua Example
|
||||
`local booleanValue = camera_get_checking_surfaces()`
|
||||
|
||||
### Parameters
|
||||
- None
|
||||
|
||||
### Returns
|
||||
- `boolean`
|
||||
|
||||
### C Prototype
|
||||
`bool camera_get_checking_surfaces(void);`
|
||||
|
||||
[:arrow_up_small:](#)
|
||||
|
||||
<br />
|
||||
|
||||
## [camera_is_frozen](#camera_is_frozen)
|
||||
|
||||
### Lua Example
|
||||
|
@ -900,6 +918,26 @@
|
|||
|
||||
<br />
|
||||
|
||||
## [camera_set_checking_surfaces](#camera_set_checking_surfaces)
|
||||
|
||||
### Lua Example
|
||||
`camera_set_checking_surfaces(value)`
|
||||
|
||||
### Parameters
|
||||
| Field | Type |
|
||||
| ----- | ---- |
|
||||
| value | `boolean` |
|
||||
|
||||
### Returns
|
||||
- None
|
||||
|
||||
### C Prototype
|
||||
`void camera_set_checking_surfaces(bool value);`
|
||||
|
||||
[:arrow_up_small:](#)
|
||||
|
||||
<br />
|
||||
|
||||
## [camera_set_romhack_override](#camera_set_romhack_override)
|
||||
|
||||
### Lua Example
|
||||
|
@ -1763,31 +1801,30 @@
|
|||
|
||||
<br />
|
||||
|
||||
## [max](#max)
|
||||
## [degrees_to_sm64](#degrees_to_sm64)
|
||||
|
||||
### Lua Example
|
||||
`local integerValue = max(a, b)`
|
||||
`local integerValue = degrees_to_sm64(degreesAngle)`
|
||||
|
||||
### Parameters
|
||||
| Field | Type |
|
||||
| ----- | ---- |
|
||||
| a | `integer` |
|
||||
| b | `integer` |
|
||||
| degreesAngle | `number` |
|
||||
|
||||
### Returns
|
||||
- `integer`
|
||||
|
||||
### C Prototype
|
||||
`s32 max(s32 a, s32 b);`
|
||||
`s16 degrees_to_sm64(f32 degreesAngle);`
|
||||
|
||||
[:arrow_up_small:](#)
|
||||
|
||||
<br />
|
||||
|
||||
## [maxf](#maxf)
|
||||
## [hypotf](#hypotf)
|
||||
|
||||
### Lua Example
|
||||
`local numberValue = maxf(a, b)`
|
||||
`local numberValue = hypotf(a, b)`
|
||||
|
||||
### Parameters
|
||||
| Field | Type |
|
||||
|
@ -1799,89 +1836,67 @@
|
|||
- `number`
|
||||
|
||||
### C Prototype
|
||||
`f32 maxf(f32 a, f32 b);`
|
||||
`f32 hypotf(f32 a, f32 b);`
|
||||
|
||||
[:arrow_up_small:](#)
|
||||
|
||||
<br />
|
||||
|
||||
## [min](#min)
|
||||
## [radians_to_sm64](#radians_to_sm64)
|
||||
|
||||
### Lua Example
|
||||
`local integerValue = min(a, b)`
|
||||
`local integerValue = radians_to_sm64(radiansAngle)`
|
||||
|
||||
### Parameters
|
||||
| Field | Type |
|
||||
| ----- | ---- |
|
||||
| a | `integer` |
|
||||
| b | `integer` |
|
||||
| radiansAngle | `number` |
|
||||
|
||||
### Returns
|
||||
- `integer`
|
||||
|
||||
### C Prototype
|
||||
`s32 min(s32 a, s32 b);`
|
||||
`s16 radians_to_sm64(f32 radiansAngle);`
|
||||
|
||||
[:arrow_up_small:](#)
|
||||
|
||||
<br />
|
||||
|
||||
## [minf](#minf)
|
||||
## [sm64_to_degrees](#sm64_to_degrees)
|
||||
|
||||
### Lua Example
|
||||
`local numberValue = minf(a, b)`
|
||||
`local numberValue = sm64_to_degrees(sm64Angle)`
|
||||
|
||||
### Parameters
|
||||
| Field | Type |
|
||||
| ----- | ---- |
|
||||
| a | `number` |
|
||||
| b | `number` |
|
||||
| sm64Angle | `integer` |
|
||||
|
||||
### Returns
|
||||
- `number`
|
||||
|
||||
### C Prototype
|
||||
`f32 minf(f32 a, f32 b);`
|
||||
`f32 sm64_to_degrees(s16 sm64Angle);`
|
||||
|
||||
[:arrow_up_small:](#)
|
||||
|
||||
<br />
|
||||
|
||||
## [sqr](#sqr)
|
||||
## [sm64_to_radians](#sm64_to_radians)
|
||||
|
||||
### Lua Example
|
||||
`local integerValue = sqr(x)`
|
||||
`local numberValue = sm64_to_radians(sm64Angle)`
|
||||
|
||||
### Parameters
|
||||
| Field | Type |
|
||||
| ----- | ---- |
|
||||
| x | `integer` |
|
||||
|
||||
### Returns
|
||||
- `integer`
|
||||
|
||||
### C Prototype
|
||||
`s32 sqr(s32 x);`
|
||||
|
||||
[:arrow_up_small:](#)
|
||||
|
||||
<br />
|
||||
|
||||
## [sqrf](#sqrf)
|
||||
|
||||
### Lua Example
|
||||
`local numberValue = sqrf(x)`
|
||||
|
||||
### Parameters
|
||||
| Field | Type |
|
||||
| ----- | ---- |
|
||||
| x | `number` |
|
||||
| sm64Angle | `integer` |
|
||||
|
||||
### Returns
|
||||
- `number`
|
||||
|
||||
### C Prototype
|
||||
`f32 sqrf(f32 x);`
|
||||
`f32 sm64_to_radians(s16 sm64Angle);`
|
||||
|
||||
[:arrow_up_small:](#)
|
||||
|
||||
|
@ -1953,6 +1968,24 @@
|
|||
|
||||
<br />
|
||||
|
||||
## [djui_attempting_to_open_playerlist](#djui_attempting_to_open_playerlist)
|
||||
|
||||
### Lua Example
|
||||
`local booleanValue = djui_attempting_to_open_playerlist()`
|
||||
|
||||
### Parameters
|
||||
- None
|
||||
|
||||
### Returns
|
||||
- `boolean`
|
||||
|
||||
### C Prototype
|
||||
`bool djui_attempting_to_open_playerlist(void);`
|
||||
|
||||
[:arrow_up_small:](#)
|
||||
|
||||
<br />
|
||||
|
||||
## [djui_is_playerlist_open](#djui_is_playerlist_open)
|
||||
|
||||
### Lua Example
|
||||
|
@ -2066,6 +2099,26 @@
|
|||
|
||||
<br />
|
||||
|
||||
## [get_coopnet_id](#get_coopnet_id)
|
||||
|
||||
### Lua Example
|
||||
`local stringValue = get_coopnet_id(localIndex)`
|
||||
|
||||
### Parameters
|
||||
| Field | Type |
|
||||
| ----- | ---- |
|
||||
| localIndex | `integer` |
|
||||
|
||||
### Returns
|
||||
- `string`
|
||||
|
||||
### C Prototype
|
||||
`const char* get_coopnet_id(s8 localIndex);`
|
||||
|
||||
[:arrow_up_small:](#)
|
||||
|
||||
<br />
|
||||
|
||||
## [get_current_save_file_num](#get_current_save_file_num)
|
||||
|
||||
### Lua Example
|
||||
|
|
|
@ -748,6 +748,7 @@
|
|||
- [djui_hud_get_color](functions-3.md#djui_hud_get_color)
|
||||
- [djui_hud_get_filter](functions-3.md#djui_hud_get_filter)
|
||||
- [djui_hud_get_font](functions-3.md#djui_hud_get_font)
|
||||
- [djui_hud_get_fov_coeff](functions-3.md#djui_hud_get_fov_coeff)
|
||||
- [djui_hud_get_mouse_x](functions-3.md#djui_hud_get_mouse_x)
|
||||
- [djui_hud_get_mouse_y](functions-3.md#djui_hud_get_mouse_y)
|
||||
- [djui_hud_get_raw_mouse_x](functions-3.md#djui_hud_get_raw_mouse_x)
|
||||
|
@ -772,6 +773,7 @@
|
|||
- [djui_hud_set_rotation_interpolated](functions-3.md#djui_hud_set_rotation_interpolated)
|
||||
- [djui_hud_world_pos_to_screen_pos](functions-3.md#djui_hud_world_pos_to_screen_pos)
|
||||
- [djui_open_pause_menu](functions-3.md#djui_open_pause_menu)
|
||||
- [get_current_fov](functions-3.md#get_current_fov)
|
||||
|
||||
<br />
|
||||
|
||||
|
@ -1134,8 +1136,14 @@
|
|||
- [anim_spline_poll](functions-4.md#anim_spline_poll)
|
||||
- [approach_f32](functions-4.md#approach_f32)
|
||||
- [approach_s32](functions-4.md#approach_s32)
|
||||
- [atan2s](functions-4.md#atan2s)
|
||||
- [coss](functions-4.md#coss)
|
||||
- [find_vector_perpendicular_to_plane](functions-4.md#find_vector_perpendicular_to_plane)
|
||||
- [get_pos_from_transform_mtx](functions-4.md#get_pos_from_transform_mtx)
|
||||
- [max](functions-4.md#max)
|
||||
- [maxf](functions-4.md#maxf)
|
||||
- [min](functions-4.md#min)
|
||||
- [minf](functions-4.md#minf)
|
||||
- [mtxf_align_terrain_normal](functions-4.md#mtxf_align_terrain_normal)
|
||||
- [mtxf_align_terrain_triangle](functions-4.md#mtxf_align_terrain_triangle)
|
||||
- [mtxf_billboard](functions-4.md#mtxf_billboard)
|
||||
|
@ -1153,7 +1161,10 @@
|
|||
- [mtxf_to_mtx](functions-4.md#mtxf_to_mtx)
|
||||
- [mtxf_translate](functions-4.md#mtxf_translate)
|
||||
- [not_zero](functions-4.md#not_zero)
|
||||
- [sins](functions-4.md#sins)
|
||||
- [spline_get_weights](functions-4.md#spline_get_weights)
|
||||
- [sqr](functions-4.md#sqr)
|
||||
- [sqrf](functions-4.md#sqrf)
|
||||
- [vec3f_add](functions-4.md#vec3f_add)
|
||||
- [vec3f_combine](functions-4.md#vec3f_combine)
|
||||
- [vec3f_copy](functions-4.md#vec3f_copy)
|
||||
|
@ -1205,6 +1216,7 @@
|
|||
- [network_player_is_override_palette_same](functions-4.md#network_player_is_override_palette_same)
|
||||
- [network_player_reset_override_palette](functions-4.md#network_player_reset_override_palette)
|
||||
- [network_player_set_description](functions-4.md#network_player_set_description)
|
||||
- [network_player_set_override_location](functions-4.md#network_player_set_override_location)
|
||||
- [network_player_set_override_palette_color](functions-4.md#network_player_set_override_palette_color)
|
||||
|
||||
<br />
|
||||
|
@ -1641,10 +1653,12 @@
|
|||
- [camera_config_set_x_sensitivity](functions-5.md#camera_config_set_x_sensitivity)
|
||||
- [camera_config_set_y_sensitivity](functions-5.md#camera_config_set_y_sensitivity)
|
||||
- [camera_freeze](functions-5.md#camera_freeze)
|
||||
- [camera_get_checking_surfaces](functions-5.md#camera_get_checking_surfaces)
|
||||
- [camera_is_frozen](functions-5.md#camera_is_frozen)
|
||||
- [camera_reset_overrides](functions-5.md#camera_reset_overrides)
|
||||
- [camera_romhack_allow_centering](functions-5.md#camera_romhack_allow_centering)
|
||||
- [camera_romhack_allow_dpad_usage](functions-5.md#camera_romhack_allow_dpad_usage)
|
||||
- [camera_set_checking_surfaces](functions-5.md#camera_set_checking_surfaces)
|
||||
- [camera_set_romhack_override](functions-5.md#camera_set_romhack_override)
|
||||
- [camera_unfreeze](functions-5.md#camera_unfreeze)
|
||||
|
||||
|
@ -1706,12 +1720,11 @@
|
|||
- smlua_math_utils.h
|
||||
- [clamp](functions-5.md#clamp)
|
||||
- [clampf](functions-5.md#clampf)
|
||||
- [max](functions-5.md#max)
|
||||
- [maxf](functions-5.md#maxf)
|
||||
- [min](functions-5.md#min)
|
||||
- [minf](functions-5.md#minf)
|
||||
- [sqr](functions-5.md#sqr)
|
||||
- [sqrf](functions-5.md#sqrf)
|
||||
- [degrees_to_sm64](functions-5.md#degrees_to_sm64)
|
||||
- [hypotf](functions-5.md#hypotf)
|
||||
- [radians_to_sm64](functions-5.md#radians_to_sm64)
|
||||
- [sm64_to_degrees](functions-5.md#sm64_to_degrees)
|
||||
- [sm64_to_radians](functions-5.md#sm64_to_radians)
|
||||
|
||||
<br />
|
||||
|
||||
|
@ -1719,12 +1732,14 @@
|
|||
- [allocate_mario_action](functions-5.md#allocate_mario_action)
|
||||
- [course_is_main_course](functions-5.md#course_is_main_course)
|
||||
- [deref_s32_pointer](functions-5.md#deref_s32_pointer)
|
||||
- [djui_attempting_to_open_playerlist](functions-5.md#djui_attempting_to_open_playerlist)
|
||||
- [djui_is_playerlist_open](functions-5.md#djui_is_playerlist_open)
|
||||
- [djui_is_popup_disabled](functions-5.md#djui_is_popup_disabled)
|
||||
- [djui_menu_get_font](functions-5.md#djui_menu_get_font)
|
||||
- [djui_popup_create_global](functions-5.md#djui_popup_create_global)
|
||||
- [djui_reset_popup_disabled_override](functions-5.md#djui_reset_popup_disabled_override)
|
||||
- [djui_set_popup_disabled_override](functions-5.md#djui_set_popup_disabled_override)
|
||||
- [get_coopnet_id](functions-5.md#get_coopnet_id)
|
||||
- [get_current_save_file_num](functions-5.md#get_current_save_file_num)
|
||||
- [get_date_and_time](functions-5.md#get_date_and_time)
|
||||
- [get_dialog_box_state](functions-5.md#get_dialog_box_state)
|
||||
|
|
|
@ -137,6 +137,7 @@ The lua functions sent to `hook_event()` will be automatically called by SM64 wh
|
|||
| HOOK_ON_ATTACK_OBJECT | Called when a player attacks an object. May be double-fired in some cases, you'll need to write special code for this | [MarioState](structs.md#MarioState) attacker, [Object](structs.md#Object) victim, `integer` interactionId |
|
||||
| HOOK_ON_LANGUAGE_CHANGED | Called when the language is changed | `string` language |
|
||||
| HOOK_ON_MODS_LOADED | Called directly after every mod file is loaded in by smlua | None |
|
||||
| HOOK_ON_NAMETAGS_RENDER | Called when nametags are rendered. Return a `string` to change what renders on the nametag, return an empty `string` to render nothing. | `string` playerIndex |
|
||||
|
||||
### Parameters
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@ Setting up Visual Studio Code will allow you to have all of the modern benefits
|
|||
|
||||
---
|
||||
|
||||
5. Add a new item containing the location of `<your repro>/autogen/lua_definitions`
|
||||
5. Add a new item containing the location of `<your repo>/autogen/lua_definitions`
|
||||
|
||||
![lua-definitions](https://user-images.githubusercontent.com/12403224/158046824-1894318a-7ce9-41ef-bacc-17f95fa05f31.png)
|
||||
|
||||
|
|
|
@ -745,6 +745,7 @@
|
|||
| ----- | ---- | ------ |
|
||||
| buttonDown | `integer` | |
|
||||
| buttonPressed | `integer` | |
|
||||
| buttonReleased | `integer` | |
|
||||
| extStickX | `integer` | |
|
||||
| extStickY | `integer` | |
|
||||
| port | `integer` | |
|
||||
|
@ -1543,6 +1544,7 @@
|
|||
| modelIndex | `integer` | read-only |
|
||||
| name | `string` | read-only |
|
||||
| onRxSeqId | `integer` | read-only |
|
||||
| overrideLocation | `string` | read-only |
|
||||
| overrideModelIndex | `integer` | |
|
||||
| overridePalette | [PlayerPalette](structs.md#PlayerPalette) | |
|
||||
| palette | [PlayerPalette](structs.md#PlayerPalette) | read-only |
|
||||
|
|
|
@ -28,9 +28,10 @@ struct Controller
|
|||
/*0x0C*/ f32 stickMag; // distance from center [0, 64]
|
||||
/*0x10*/ u16 buttonDown;
|
||||
/*0x12*/ u16 buttonPressed;
|
||||
/*0x14*/ OSContStatus *statusData;
|
||||
/*0x18*/ OSContPad *controllerData;
|
||||
/*0x1C*/ s32 port;
|
||||
/*0x14*/ u16 buttonReleased;
|
||||
/*0x18*/ OSContStatus *statusData;
|
||||
/*0x1C*/ OSContPad *controllerData;
|
||||
/*0x20*/ s32 port;
|
||||
/*ext */ s16 extStickX; // additional (right) stick values
|
||||
/*ext */ s16 extStickY;
|
||||
};
|
||||
|
|
|
@ -63,7 +63,8 @@ const LevelScript level_intro_mario_head_regular[] = {
|
|||
TRANSITION(/*transType*/ WARP_TRANSITION_FADE_FROM_STAR, /*time*/ 20, /*color*/ 0x00, 0x00, 0x00),
|
||||
SLEEP(/*frames*/ 20),
|
||||
CALL_LOOP(/*arg*/ 1, /*func*/ lvl_intro_update),
|
||||
JUMP_IF(/*op*/ OP_EQ, /*arg*/ 100, script_intro_L1),
|
||||
// JUMP_IF(/*op*/ OP_EQ, /*arg*/ 100, script_intro_L1),
|
||||
JUMP_IF(/*op*/ OP_EQ, /*arg*/ 100, script_intro_L4),
|
||||
JUMP_IF(/*op*/ OP_EQ, /*arg*/ 101, script_intro_L2),
|
||||
JUMP(script_intro_L4),
|
||||
};
|
||||
|
@ -88,7 +89,8 @@ const LevelScript level_intro_mario_head_dizzy[] = {
|
|||
TRANSITION(/*transType*/ WARP_TRANSITION_FADE_FROM_STAR, /*time*/ 20, /*color*/ 0x00, 0x00, 0x00),
|
||||
SLEEP(/*frames*/ 20),
|
||||
CALL_LOOP(/*arg*/ 2, /*func*/ lvl_intro_update),
|
||||
JUMP_IF(/*op*/ OP_EQ, /*arg*/ 100, script_intro_L1),
|
||||
// JUMP_IF(/*op*/ OP_EQ, /*arg*/ 100, script_intro_L1),
|
||||
JUMP_IF(/*op*/ OP_EQ, /*arg*/ 100, script_intro_L4),
|
||||
JUMP_IF(/*op*/ OP_EQ, /*arg*/ 101, script_intro_L2),
|
||||
JUMP(script_intro_L4),
|
||||
};
|
||||
|
|
1
lib/coopnet/README.md
Normal file
1
lib/coopnet/README.md
Normal file
|
@ -0,0 +1 @@
|
|||
Source code for coopnet is available at https://github.com/Isaac0-dev/coopnet
|
Binary file not shown.
Binary file not shown.
|
@ -4,7 +4,7 @@ if not _G.charSelectExists then
|
|||
if not first then
|
||||
first = true
|
||||
play_sound(SOUND_MENU_CAMERA_BUZZ, gGlobalSoundSource)
|
||||
djui_chat_message_create("\\#ffffa0\\Extra Characters requires Character Select to be enabled.\nPlease rehost with it enabled.")
|
||||
djui_chat_message_create("\\#ffffa0\\[CS] VL-Tone & Cjes Luigi requires Character Select to be enabled.\nPlease rehost with it enabled.")
|
||||
end
|
||||
end)
|
||||
return
|
||||
|
@ -13,4 +13,4 @@ end
|
|||
MOD_VERSION = "v4.1"
|
||||
|
||||
E_MODEL_VL = smlua_model_util_get_id("vl_geo")
|
||||
E_MODEL_CJES = smlua_model_util_get_id("cjes_geo")
|
||||
E_MODEL_CJES = smlua_model_util_get_id("cjes_geo")
|
||||
|
|
|
@ -33,7 +33,7 @@ VOICETABLE_BIRDO = {
|
|||
[CHAR_SOUND_SO_LONGA_BOWSER] = "birdo_solonga_bowser.ogg",
|
||||
[CHAR_SOUND_SNORING1] = "birdo_snoring1.ogg",
|
||||
[CHAR_SOUND_SNORING2] = "birdo_snoring2.ogg",
|
||||
[CHAR_SOUND_SNORING3] = { "birdo_snoring2.ogg", "birdo_snoring1.ogg", "birdo_snoring3.ogg" },
|
||||
[CHAR_SOUND_SNORING3] = { "birdo_snoring1.ogg", "birdo_snoring2.ogg" },
|
||||
[CHAR_SOUND_TWIRL_BOUNCE] = "birdo_twirl_bounce.ogg",
|
||||
[CHAR_SOUND_UH] = "birdo_uh.ogg",
|
||||
[CHAR_SOUND_UH2] = "birdo_uh2.ogg",
|
||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -66,7 +66,7 @@ local PALETTE_TOADETTE = {
|
|||
[SHIRT] = { r = 0xFF, g = 0x00, b = 0x00 },
|
||||
[GLOVES] = { r = 0xFF, g = 0xFF, b = 0xFF },
|
||||
[SHOES] = { r = 0x68, g = 0x40, b = 0x1B },
|
||||
[HAIR] = { r = 0xFF, g = 0x00, b = 0x00 },
|
||||
[HAIR] = { r = 0x73, g = 0x06, b = 0x00 },
|
||||
[SKIN] = { r = 0xFE, g = 0xD5, b = 0xA1 },
|
||||
[CAP] = { r = 0xF3, g = 0x00, b = 0x80 },
|
||||
[EMBLEM] = { r = 0xF3, g = 0x00, b = 0x80 }
|
||||
|
@ -74,4 +74,4 @@ local PALETTE_TOADETTE = {
|
|||
|
||||
_G.CT_TOADETTE = _G.charSelect.character_add("Toadette", {"A very bubbly female toad", "who has a hobby of construction!", "Although she hates the union.", "Wonder why?", "", "Voiced by: Melissa Mekrose."}, "FluffaMario & AngelicMiracles", { r = 255, g = 70, b = 161 }, E_MODEL_TOADETTE, CT_TOAD, TEX_TOADETTE)
|
||||
_G.charSelect.character_add_voice(E_MODEL_TOADETTE, VOICETABLE_TOADETTE)
|
||||
_G.charSelect.character_add_palette_preset(E_MODEL_TOADETTE, PALETTE_TOADETTE)
|
||||
_G.charSelect.character_add_palette_preset(E_MODEL_TOADETTE, PALETTE_TOADETTE)
|
||||
|
|
|
@ -3,11 +3,19 @@
|
|||
|
||||
if not _G.charSelectExists then return end
|
||||
|
||||
local voiceTables = {
|
||||
[VOICETABLE_TOADETTE] = true,
|
||||
[VOICETABLE_YOSHI] = true,
|
||||
[VOICETABLE_PEACH] = true,
|
||||
[VOICETABLE_DAISY] = true,
|
||||
[VOICETABLE_BIRDO] = true
|
||||
}
|
||||
|
||||
--- @param m MarioState
|
||||
local function mario_update(m)
|
||||
if is_player_active(m) == 0 then return end
|
||||
local voiceTable = charSelect.character_get_voice(m)
|
||||
if voiceTable then
|
||||
if voiceTables[voiceTable] then
|
||||
return charSelect.voice.snore(m)
|
||||
end
|
||||
end
|
||||
|
@ -16,7 +24,7 @@ end
|
|||
--- @param sound CharacterSound
|
||||
local function character_sound(m, sound)
|
||||
local voiceTable = charSelect.character_get_voice(m)
|
||||
if voiceTable then
|
||||
if voiceTables[voiceTable] then
|
||||
return charSelect.voice.sound(m, sound)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -118,7 +118,7 @@ charBeingSet = false
|
|||
|
||||
stopPalettes = false
|
||||
for i in pairs(gActiveMods) do
|
||||
if (gActiveMods[i].incompatible ~= nil and gActiveMods[i].incompatible:find("gamemode")) and not (gActiveMods[i].name:find("Personal Star Counter EX+")) then
|
||||
if (gActiveMods[i].incompatible ~= nil and gActiveMods[i].incompatible:find("gamemode")) and not (gActiveMods[i].name:find("Personal Star Counter")) then
|
||||
stopPalettes = true
|
||||
end
|
||||
end
|
||||
|
|
|
@ -12,6 +12,55 @@
|
|||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wreturn-local-addr"
|
||||
|
||||
#if defined(__clang__) || defined(__GNUC__)
|
||||
|
||||
// Use built-in functions when using Clang or GCC
|
||||
inline f32 minf(f32 a, f32 b) {
|
||||
return __builtin_fminf(a, b);
|
||||
}
|
||||
|
||||
inline f32 maxf(f32 a, f32 b) {
|
||||
return __builtin_fmaxf(a, b);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
// Fallback to the original implementation for iDO
|
||||
inline f32 minf(f32 a, f32 b) {
|
||||
return (a <= b) ? a : b;
|
||||
}
|
||||
|
||||
inline f32 maxf(f32 a, f32 b) {
|
||||
return (a > b) ? a : b;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// The sqr, min, max, and trig functions do not have/need built-ins, so it's safe to leave them as is
|
||||
inline s16 (min)(s16 a, s16 b) {
|
||||
return (a <= b) ? a : b;
|
||||
}
|
||||
|
||||
inline s16 (max)(s16 a, s16 b) {
|
||||
return (a > b) ? a : b;
|
||||
}
|
||||
|
||||
inline f32 sqrf(f32 x) {
|
||||
return x * x;
|
||||
}
|
||||
|
||||
inline s16 (sqr)(s16 x) {
|
||||
return x * x;
|
||||
}
|
||||
|
||||
inline f32 sins(s16 sm64Angle) {
|
||||
return gSineTable[(u16) (sm64Angle) >> 4];
|
||||
}
|
||||
|
||||
inline f32 coss(s16 sm64Angle) {
|
||||
return gCosineTable[(u16) (sm64Angle) >> 4];
|
||||
}
|
||||
|
||||
/// Copy vector 'src' to 'dest'
|
||||
void *vec3f_copy(Vec3f dest, Vec3f src) {
|
||||
dest[0] = src[0];
|
||||
|
@ -244,77 +293,67 @@ void mtxf_translate(Mat4 dest, Vec3f b) {
|
|||
* angle allows a bank rotation of the camera.
|
||||
*/
|
||||
void mtxf_lookat(Mat4 mtx, Vec3f from, Vec3f to, s16 roll) {
|
||||
register f32 invLength;
|
||||
f32 dx;
|
||||
f32 dz;
|
||||
f32 xColY;
|
||||
f32 yColY;
|
||||
f32 zColY;
|
||||
f32 xColZ;
|
||||
f32 yColZ;
|
||||
f32 zColZ;
|
||||
f32 xColX;
|
||||
f32 yColX;
|
||||
f32 zColX;
|
||||
Vec3f forward, right, up;
|
||||
f32 sinRoll, cosRoll;
|
||||
f32 dx, dz, xzDist;
|
||||
f32 invLength;
|
||||
|
||||
forward[0] = from[0] - to[0];
|
||||
forward[1] = from[1] - to[1];
|
||||
forward[2] = from[2] - to[2];
|
||||
invLength = 1.0f / sqrtf(forward[0] * forward[0] + forward[1] * forward[1] + forward[2] * forward[2]);
|
||||
forward[0] *= invLength;
|
||||
forward[1] *= invLength;
|
||||
forward[2] *= invLength;
|
||||
|
||||
dx = to[0] - from[0];
|
||||
dz = to[2] - from[2];
|
||||
xzDist = dx * dx + dz * dz;
|
||||
if (xzDist != 0.0f) {
|
||||
invLength = -1.0f / sqrtf(xzDist);
|
||||
dx *= invLength;
|
||||
dz *= invLength;
|
||||
} else {
|
||||
dx = dz = 0.0f;
|
||||
}
|
||||
|
||||
sinRoll = sins(roll);
|
||||
cosRoll = coss(roll);
|
||||
|
||||
invLength = -1.0 / sqrtf(dx * dx + dz * dz);
|
||||
dx *= invLength;
|
||||
dz *= invLength;
|
||||
up[0] = sinRoll * dz;
|
||||
up[1] = cosRoll;
|
||||
up[2] = -sinRoll * dx;
|
||||
|
||||
yColY = coss(roll);
|
||||
xColY = sins(roll) * dz;
|
||||
zColY = -sins(roll) * dx;
|
||||
right[0] = up[1] * forward[2] - up[2] * forward[1];
|
||||
right[1] = up[2] * forward[0] - up[0] * forward[2];
|
||||
right[2] = up[0] * forward[1] - up[1] * forward[0];
|
||||
|
||||
xColZ = to[0] - from[0];
|
||||
yColZ = to[1] - from[1];
|
||||
zColZ = to[2] - from[2];
|
||||
invLength = 1.0f / sqrtf(right[0] * right[0] + right[1] * right[1] + right[2] * right[2]);
|
||||
right[0] *= invLength;
|
||||
right[1] *= invLength;
|
||||
right[2] *= invLength;
|
||||
|
||||
invLength = -1.0 / sqrtf(xColZ * xColZ + yColZ * yColZ + zColZ * zColZ);
|
||||
xColZ *= invLength;
|
||||
yColZ *= invLength;
|
||||
zColZ *= invLength;
|
||||
up[0] = forward[1] * right[2] - forward[2] * right[1];
|
||||
up[1] = forward[2] * right[0] - forward[0] * right[2];
|
||||
up[2] = forward[0] * right[1] - forward[1] * right[0];
|
||||
|
||||
mtx[0][0] = right[0];
|
||||
mtx[1][0] = right[1];
|
||||
mtx[2][0] = right[2];
|
||||
mtx[3][0] = -(from[0] * right[0] + from[1] * right[1] + from[2] * right[2]);
|
||||
|
||||
xColX = yColY * zColZ - zColY * yColZ;
|
||||
yColX = zColY * xColZ - xColY * zColZ;
|
||||
zColX = xColY * yColZ - yColY * xColZ;
|
||||
mtx[0][1] = up[0];
|
||||
mtx[1][1] = up[1];
|
||||
mtx[2][1] = up[2];
|
||||
mtx[3][1] = -(from[0] * up[0] + from[1] * up[1] + from[2] * up[2]);
|
||||
|
||||
invLength = 1.0 / sqrtf(xColX * xColX + yColX * yColX + zColX * zColX);
|
||||
mtx[0][2] = forward[0];
|
||||
mtx[1][2] = forward[1];
|
||||
mtx[2][2] = forward[2];
|
||||
mtx[3][2] = -(from[0] * forward[0] + from[1] * forward[1] + from[2] * forward[2]);
|
||||
|
||||
xColX *= invLength;
|
||||
yColX *= invLength;
|
||||
zColX *= invLength;
|
||||
|
||||
xColY = yColZ * zColX - zColZ * yColX;
|
||||
yColY = zColZ * xColX - xColZ * zColX;
|
||||
zColY = xColZ * yColX - yColZ * xColX;
|
||||
|
||||
invLength = 1.0 / sqrtf(xColY * xColY + yColY * yColY + zColY * zColY);
|
||||
xColY *= invLength;
|
||||
yColY *= invLength;
|
||||
zColY *= invLength;
|
||||
|
||||
mtx[0][0] = xColX;
|
||||
mtx[1][0] = yColX;
|
||||
mtx[2][0] = zColX;
|
||||
mtx[3][0] = -(from[0] * xColX + from[1] * yColX + from[2] * zColX);
|
||||
|
||||
mtx[0][1] = xColY;
|
||||
mtx[1][1] = yColY;
|
||||
mtx[2][1] = zColY;
|
||||
mtx[3][1] = -(from[0] * xColY + from[1] * yColY + from[2] * zColY);
|
||||
|
||||
mtx[0][2] = xColZ;
|
||||
mtx[1][2] = yColZ;
|
||||
mtx[2][2] = zColZ;
|
||||
mtx[3][2] = -(from[0] * xColZ + from[1] * yColZ + from[2] * zColZ);
|
||||
|
||||
mtx[0][3] = 0;
|
||||
mtx[1][3] = 0;
|
||||
mtx[2][3] = 0;
|
||||
mtx[3][3] = 1;
|
||||
mtx[0][3] = mtx[1][3] = mtx[2][3] = 0.0f;
|
||||
mtx[3][3] = 1.0f;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -823,58 +862,36 @@ f32 approach_f32(f32 current, f32 target, f32 inc, f32 dec) {
|
|||
* the resulting angle is in range [0, 0x2000] (1/8 of a circle).
|
||||
*/
|
||||
static u16 atan2_lookup(f32 y, f32 x) {
|
||||
u16 ret;
|
||||
|
||||
if (x == 0) {
|
||||
ret = gArctanTable[0];
|
||||
} else {
|
||||
s32 index = (s32)(y / x * 1024 + 0.5f);
|
||||
if (index >= 0x401 || index < 0) { index = 0; }
|
||||
ret = gArctanTable[index];
|
||||
}
|
||||
return ret;
|
||||
s16 idx = (s16)(y / x * 1024.0f + 0.5f);
|
||||
idx = (idx >= 0 && idx < 0x401) ? idx : 0;
|
||||
return gArctanTable[idx];
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute the angle from (0, 0) to (x, y) as a s16. Given that terrain is in
|
||||
* the xz-plane, this is commonly called with (z, x) to get a yaw angle.
|
||||
*/
|
||||
s16 atan2s(f32 y, f32 x) {
|
||||
u16 ret;
|
||||
inline s16 atan2s(f32 y, f32 x) {
|
||||
// Extract sign bits: 1 if negative, 0 otherwise
|
||||
u8 signx = (x < 0.0f);
|
||||
u8 signy = (y < 0.0f);
|
||||
|
||||
if (x >= 0) {
|
||||
if (y >= 0) {
|
||||
if (y >= x) {
|
||||
ret = atan2_lookup(x, y);
|
||||
} else {
|
||||
ret = 0x4000 - atan2_lookup(y, x);
|
||||
}
|
||||
} else {
|
||||
y = -y;
|
||||
if (y < x) {
|
||||
ret = 0x4000 + atan2_lookup(y, x);
|
||||
} else {
|
||||
ret = 0x8000 - atan2_lookup(x, y);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
x = -x;
|
||||
if (y < 0) {
|
||||
y = -y;
|
||||
if (y >= x) {
|
||||
ret = 0x8000 + atan2_lookup(x, y);
|
||||
} else {
|
||||
ret = 0xC000 - atan2_lookup(y, x);
|
||||
}
|
||||
} else {
|
||||
if (y < x) {
|
||||
ret = 0xC000 + atan2_lookup(y, x);
|
||||
} else {
|
||||
ret = -atan2_lookup(x, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
// Take absolute values
|
||||
f32 absx = absx(x);
|
||||
f32 absy = absx(y);
|
||||
|
||||
// Compute the angle in the first octant
|
||||
u16 angle = atan2_lookup(min(absx, absy), max(absy, absx));
|
||||
|
||||
// Create an index based on the signs and swap status
|
||||
u8 idx = ((absy > absx) << 2) | (signx << 1) | signy;
|
||||
|
||||
// Combined lookup tables for offsets and sign multipliers
|
||||
static const s16 offsets[] = {0x4000, 0x4000, 0xC000, 0xC000, 0x0000, 0x8000, 0x0000, 0x8000};
|
||||
static const s8 signs[] = {-1, 1, 1, -1, 1, -1, -1, 1};
|
||||
|
||||
// Ensure the result fits into 16 bits via an explicit cast on angle
|
||||
return (offsets[idx] + (signs[idx] * (s16)angle)) & 0xFFFF;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -24,9 +24,6 @@ extern f32 gSineTable[];
|
|||
extern f32 gCosineTable[];
|
||||
#endif
|
||||
|
||||
#define sins(x) gSineTable[(u16) (x) >> 4]
|
||||
#define coss(x) gCosineTable[(u16) (x) >> 4]
|
||||
|
||||
#if defined(min)
|
||||
#undef min
|
||||
#endif
|
||||
|
@ -35,13 +32,45 @@ extern f32 gCosineTable[];
|
|||
#undef max
|
||||
#endif
|
||||
|
||||
#define min(a, b) ((a) <= (b) ? (a) : (b))
|
||||
#define max(a, b) ((a) > (b) ? (a) : (b))
|
||||
// Inline Function prototypes
|
||||
f32 minf(f32 a, f32 b);
|
||||
s16 min(s16 a, s16 b);
|
||||
f32 maxf(f32 a, f32 b);
|
||||
s16 max(s16 a, s16 b);
|
||||
f32 sqrf(f32 x);
|
||||
s16 sqr(s16 x);
|
||||
f32 sins(s16 sm64Angle);
|
||||
f32 coss(s16 sm64Angle);
|
||||
|
||||
#define sqr(x) ((x) * (x))
|
||||
#define min(a, b) _Generic((a), \
|
||||
f32: minf, \
|
||||
default: min \
|
||||
)(a, b)
|
||||
|
||||
#define max(a, b) _Generic((a), \
|
||||
f32: maxf, \
|
||||
default: max \
|
||||
)(a, b)
|
||||
|
||||
#define sqr(x) _Generic((x), \
|
||||
f32: sqrf, \
|
||||
default: sqr \
|
||||
)(x)
|
||||
|
||||
#if defined(__clang__) || defined(__GNUC__)
|
||||
|
||||
#define absx(x) _Generic((x), \
|
||||
f32: __builtin_fabsf, \
|
||||
double: __builtin_fabs, \
|
||||
default: __builtin_abs \
|
||||
)(x)
|
||||
|
||||
#else
|
||||
|
||||
#define absx(x) ((x) < 0 ? -(x) : (x))
|
||||
|
||||
#endif
|
||||
|
||||
#include "../../include/libc/stdlib.h"
|
||||
|
||||
void *vec3f_copy(Vec3f dest, Vec3f src);
|
||||
|
|
|
@ -253,6 +253,10 @@ void bhv_normal_cap_loop(void) {
|
|||
if (cap_set_hitbox() == 1)
|
||||
save_file_clear_flags(SAVE_FLAG_CAP_ON_GROUND);
|
||||
|
||||
if (o->globalPlayerIndex >= MAX_PLAYERS) {
|
||||
o->globalPlayerIndex = 0;
|
||||
}
|
||||
|
||||
obj_set_model(o, gMarioStates[network_local_index_from_global(o->globalPlayerIndex)].character->capModelId);
|
||||
}
|
||||
|
||||
|
|
|
@ -251,6 +251,10 @@ static void chain_chomp_sub_act_lunge(void) {
|
|||
}
|
||||
}
|
||||
|
||||
static u8 chain_chomp_released_trigger_cutscene_continue_dialog(void) {
|
||||
return (o->oChainChompReleaseStatus != CHAIN_CHOMP_RELEASED_END_CUTSCENE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fall to the ground and interrupt mario into a cutscene action.
|
||||
*/
|
||||
|
@ -260,9 +264,20 @@ static void chain_chomp_released_trigger_cutscene(void) {
|
|||
|
||||
//! Can delay this if we get into a cutscene-unfriendly action after the
|
||||
// last post ground pound and before this
|
||||
if (o->oMoveFlags & OBJ_MOVE_MASK_ON_GROUND) {
|
||||
o->oChainChompReleaseStatus = CHAIN_CHOMP_RELEASED_LUNGE_AROUND;
|
||||
o->oTimer = 0;
|
||||
// hack: get the nearest wooden post, this will work properly 99% of the time
|
||||
struct Object* woodenPost = cur_obj_nearest_object_with_behavior(bhvWoodenPost);
|
||||
struct MarioState* marioState = nearest_mario_state_to_object(woodenPost);
|
||||
if (&gMarioStates[0] == marioState) {
|
||||
if (set_mario_npc_dialog(&gMarioStates[0], 2, chain_chomp_released_trigger_cutscene_continue_dialog) == 2
|
||||
&& (o->oMoveFlags & OBJ_MOVE_MASK_ON_GROUND) && cutscene_object(CUTSCENE_STAR_SPAWN, o) == 1) {
|
||||
o->oChainChompReleaseStatus = CHAIN_CHOMP_RELEASED_LUNGE_AROUND;
|
||||
o->oTimer = 0;
|
||||
}
|
||||
} else {
|
||||
if (o->oMoveFlags & OBJ_MOVE_MASK_ON_GROUND) {
|
||||
o->oChainChompReleaseStatus = CHAIN_CHOMP_RELEASED_LUNGE_AROUND;
|
||||
o->oTimer = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -118,16 +118,16 @@ static void eyerok_boss_act_wake_up(void) {
|
|||
}
|
||||
}
|
||||
|
||||
u8 eyerok_boss_act_show_intro_text_continue_dialog(void) { return o->oAction == EYEROK_BOSS_ACT_SHOW_INTRO_TEXT; }
|
||||
static u8 eyerok_boss_act_show_intro_text_continue_dialog(void) {
|
||||
return o->oAction == EYEROK_BOSS_ACT_SHOW_INTRO_TEXT;
|
||||
}
|
||||
|
||||
static void eyerok_boss_act_show_intro_text(void) {
|
||||
// todo: get dialog working again
|
||||
/*struct MarioState* marioState = nearest_mario_state_to_object(o);
|
||||
struct MarioState* marioState = nearest_mario_state_to_object(o);
|
||||
if (should_start_or_continue_dialog(marioState, o) && cur_obj_update_dialog_with_cutscene(&gMarioStates[0], 2, 0, CUTSCENE_DIALOG, gBehaviorValues.dialogs.EyerokIntroDialog, eyerok_boss_act_show_intro_text_continue_dialog)) {
|
||||
o->oAction = EYEROK_BOSS_ACT_FIGHT;
|
||||
network_send_object_reliability(o, TRUE);
|
||||
}*/
|
||||
o->oAction = EYEROK_BOSS_ACT_FIGHT;
|
||||
}
|
||||
}
|
||||
|
||||
static void eyerok_boss_act_fight(void) {
|
||||
|
|
|
@ -32,6 +32,9 @@ void bhv_piranha_plant_bubble_loop(void) {
|
|||
f32 scale = 0;
|
||||
s32 i;
|
||||
s32 frame = parent->header.gfx.animInfo.animFrame;
|
||||
if (frame < 0) {
|
||||
frame = 0;
|
||||
}
|
||||
// TODO: rename lastFrame if it is inaccurate
|
||||
if (parent->header.gfx.animInfo.curAnim == NULL) { return; }
|
||||
s32 lastFrame = parent->header.gfx.animInfo.curAnim->loopEnd - 2;
|
||||
|
|
|
@ -122,6 +122,7 @@ void piranha_plant_act_woken_up(void) {
|
|||
*/
|
||||
o->oDamageOrCoinValue = 3;
|
||||
#endif
|
||||
|
||||
if (o->oTimer == 0)
|
||||
stop_secondary_music(50);
|
||||
|
||||
|
@ -270,6 +271,9 @@ void piranha_plant_act_biting(void) {
|
|||
|
||||
cur_obj_init_animation_with_sound(0);
|
||||
|
||||
cur_obj_set_hitbox_radius_and_height(150.0f, 100.0f);
|
||||
cur_obj_set_hurtbox_radius_and_height(150.0f, 100.0f);
|
||||
|
||||
// Play a bite sound effect on certain frames.
|
||||
if (is_item_in_array(frame, sPiranhaPlantBiteSoundFrames)) {
|
||||
cur_obj_play_sound_2(SOUND_OBJ2_PIRANHA_PLANT_BITE);
|
||||
|
@ -368,9 +372,6 @@ void bhv_piranha_plant_loop(void) {
|
|||
sync_object_init_field(o, &o->oTimer);
|
||||
}
|
||||
|
||||
cur_obj_set_hitbox_radius_and_height(150.0f, 100.0f);
|
||||
cur_obj_set_hurtbox_radius_and_height(150.0f, 100.0f);
|
||||
|
||||
CUR_OBJ_CALL_ACTION_FUNCTION(TablePiranhaPlantActions);
|
||||
// In WF, hide all Piranha Plants once high enough up.
|
||||
if (gCurrLevelNum == LEVEL_WF) {
|
||||
|
|
|
@ -70,17 +70,14 @@ static inline void shift_UV_NORMAL(struct ScrollTarget *scroll, u16 vertcount, s
|
|||
verts[0]->n.flag++;
|
||||
} else {
|
||||
if (bhv < SCROLL_UV_X) {
|
||||
u8 bhvIndex = MIN(bhv, 2);
|
||||
for (i = 0; i < vertcount; i++) {
|
||||
verts[i]->n.ob[bhvIndex] = scroll->interpF32[i];
|
||||
scroll->prevF32[i] = scroll->interpF32[i];
|
||||
}
|
||||
} else {
|
||||
u8 bhvIndex = MIN(bhv-SCROLL_UV_X, 1);
|
||||
for (i = 0; i < vertcount; i++) {
|
||||
verts[i]->n.tc[bhvIndex] = scroll->interpS16[i];
|
||||
scroll->prevS16[i] = scroll->interpS16[i];
|
||||
}
|
||||
}
|
||||
scroll->needInterp = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -122,26 +122,28 @@ s16 newcam_saved_defmode = -1;
|
|||
extern bool gDjuiInMainMenu;
|
||||
|
||||
///This is called at every level initialisation.
|
||||
void newcam_init(struct Camera *c, UNUSED u8 dv) {
|
||||
void newcam_init(struct Camera *c, u8 isSoftReset) {
|
||||
newcam_tilt = 1500;
|
||||
newcam_yaw = -c->yaw+0x4000; //Mario and the camera's yaw have this offset between them.
|
||||
newcam_mode = NC_MODE_NORMAL;
|
||||
///This here will dictate what modes the camera will start in at the beginning of a level. Below are some examples.
|
||||
switch (gCurrLevelNum) {
|
||||
case LEVEL_BITDW: newcam_yaw = 0x4000; /*newcam_mode = NC_MODE_8D;*/ newcam_tilt = 4000; break;
|
||||
case LEVEL_BITFS: newcam_yaw = 0x4000; /*newcam_mode = NC_MODE_8D;*/ newcam_tilt = 4000; break;
|
||||
case LEVEL_BITS: newcam_yaw = 0x4000; /*newcam_mode = NC_MODE_8D;*/ newcam_tilt = 4000; break;
|
||||
case LEVEL_WF: newcam_yaw = 0x4000; newcam_tilt = 2000; break;
|
||||
case LEVEL_RR: newcam_yaw = 0x6000; newcam_tilt = 2000; break;
|
||||
case LEVEL_CCM: if (gCurrAreaIndex == 1) {newcam_yaw = -0x4000; newcam_tilt = 2000; } else newcam_mode = NC_MODE_SLIDE; break;
|
||||
case LEVEL_WDW: newcam_yaw = 0x2000; newcam_tilt = 3000; break;
|
||||
case 27: newcam_mode = NC_MODE_SLIDE; break;
|
||||
case LEVEL_TTM: if (gCurrAreaIndex == 2) newcam_mode = NC_MODE_SLIDE; break;
|
||||
}
|
||||
if (!isSoftReset) {
|
||||
switch (gCurrLevelNum) {
|
||||
case LEVEL_BITDW: newcam_yaw = 0x4000; /*newcam_mode = NC_MODE_8D;*/ newcam_tilt = 4000; break;
|
||||
case LEVEL_BITFS: newcam_yaw = 0x4000; /*newcam_mode = NC_MODE_8D;*/ newcam_tilt = 4000; break;
|
||||
case LEVEL_BITS: newcam_yaw = 0x4000; /*newcam_mode = NC_MODE_8D;*/ newcam_tilt = 4000; break;
|
||||
case LEVEL_WF: newcam_yaw = 0x4000; newcam_tilt = 2000; break;
|
||||
case LEVEL_RR: newcam_yaw = 0x6000; newcam_tilt = 2000; break;
|
||||
case LEVEL_CCM: if (gCurrAreaIndex == 1) {newcam_yaw = -0x4000; newcam_tilt = 2000; } else newcam_mode = NC_MODE_SLIDE; break;
|
||||
case LEVEL_WDW: newcam_yaw = 0x2000; newcam_tilt = 3000; break;
|
||||
case 27: newcam_mode = NC_MODE_SLIDE; break;
|
||||
case LEVEL_TTM: if (gCurrAreaIndex == 2) newcam_mode = NC_MODE_SLIDE; break;
|
||||
}
|
||||
|
||||
// clear these out when entering a new level to prevent "camera mode buffering"
|
||||
newcam_saved_defmode = -1;
|
||||
newcam_saved_mode = -1;
|
||||
// clear these out when entering a new level to prevent "camera mode buffering"
|
||||
newcam_saved_defmode = -1;
|
||||
newcam_saved_mode = -1;
|
||||
}
|
||||
|
||||
// this will be set in init_settings() if enabled
|
||||
newcam_active = 0;
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
#include "pc/lua/smlua_hooks.h"
|
||||
#include "pc/djui/djui.h"
|
||||
#include "first_person_cam.h"
|
||||
#include "rendering_graph_node.h"
|
||||
|
||||
#define CBUTTON_MASK (U_CBUTTONS | D_CBUTTONS | L_CBUTTONS | R_CBUTTONS)
|
||||
|
||||
|
@ -907,20 +908,21 @@ void pan_ahead_of_player(struct Camera *c) {
|
|||
}
|
||||
|
||||
s16 find_in_bounds_yaw_wdw_bob_thi(UNUSED Vec3f pos, UNUSED Vec3f origin, s16 yaw) {
|
||||
// switch (gCurrLevelArea) {
|
||||
// case AREA_WDW_MAIN:
|
||||
// yaw = clamp_positions_and_find_yaw(pos, origin, 4508.f, -3739.f, 4508.f, -3739.f);
|
||||
// break;
|
||||
// case AREA_BOB:
|
||||
// yaw = clamp_positions_and_find_yaw(pos, origin, 8000.f, -8000.f, 7050.f, -8000.f);
|
||||
// break;
|
||||
// case AREA_THI_HUGE:
|
||||
// yaw = clamp_positions_and_find_yaw(pos, origin, 8192.f, -8192.f, 8192.f, -8192.f);
|
||||
// break;
|
||||
// case AREA_THI_TINY:
|
||||
// yaw = clamp_positions_and_find_yaw(pos, origin, 2458.f, -2458.f, 2458.f, -2458.f);
|
||||
// break;
|
||||
// }
|
||||
if (!gCameraUseCourseSpecificSettings) { return yaw; }
|
||||
switch (gCurrLevelArea) {
|
||||
case AREA_WDW_MAIN:
|
||||
yaw = clamp_positions_and_find_yaw(pos, origin, 4508.f, -3739.f, 4508.f, -3739.f);
|
||||
break;
|
||||
case AREA_BOB:
|
||||
yaw = clamp_positions_and_find_yaw(pos, origin, 8000.f, -8000.f, 7050.f, -8000.f);
|
||||
break;
|
||||
case AREA_THI_HUGE:
|
||||
yaw = clamp_positions_and_find_yaw(pos, origin, 8192.f, -8192.f, 8192.f, -8192.f);
|
||||
break;
|
||||
case AREA_THI_TINY:
|
||||
yaw = clamp_positions_and_find_yaw(pos, origin, 2458.f, -2458.f, 2458.f, -2458.f);
|
||||
break;
|
||||
}
|
||||
return yaw;
|
||||
}
|
||||
|
||||
|
@ -1925,14 +1927,18 @@ s32 update_behind_mario_camera(struct Camera *c, Vec3f focus, Vec3f pos) {
|
|||
dist = 300.f;
|
||||
}
|
||||
vec3f_set_dist_and_angle(focus, pos, dist, pitch, yaw);
|
||||
if (gCurrLevelArea == AREA_WDW_MAIN) {
|
||||
yaw = clamp_positions_and_find_yaw(pos, focus, 4508.f, -3739.f, 4508.f, -3739.f);
|
||||
}
|
||||
if (gCurrLevelArea == AREA_THI_HUGE) {
|
||||
yaw = clamp_positions_and_find_yaw(pos, focus, 8192.f, -8192.f, 8192.f, -8192.f);
|
||||
}
|
||||
if (gCurrLevelArea == AREA_THI_TINY) {
|
||||
yaw = clamp_positions_and_find_yaw(pos, focus, 2458.f, -2458.f, 2458.f, -2458.f);
|
||||
|
||||
if (!gCameraUseCourseSpecificSettings) { return yaw; }
|
||||
switch (gCurrLevelArea) {
|
||||
case AREA_WDW_MAIN:
|
||||
yaw = clamp_positions_and_find_yaw(pos, focus, 4508.f, -3739.f, 4508.f, -3739.f);
|
||||
break;
|
||||
case AREA_THI_HUGE:
|
||||
yaw = clamp_positions_and_find_yaw(pos, focus, 8192.f, -8192.f, 8192.f, -8192.f);
|
||||
break;
|
||||
case AREA_THI_TINY:
|
||||
yaw = clamp_positions_and_find_yaw(pos, focus, 2458.f, -2458.f, 2458.f, -2458.f);
|
||||
break;
|
||||
}
|
||||
|
||||
return yaw;
|
||||
|
@ -2424,7 +2430,7 @@ s16 update_default_camera(struct Camera *c) {
|
|||
c->pos[1] = ceilHeight;
|
||||
}
|
||||
}
|
||||
if (gCurrLevelArea == AREA_WDW_TOWN) {
|
||||
if (gCameraUseCourseSpecificSettings && gCurrLevelArea == AREA_WDW_TOWN) {
|
||||
yaw = clamp_positions_and_find_yaw(c->pos, c->focus, 2254.f, -3789.f, 3790.f, -2253.f);
|
||||
}
|
||||
return yaw;
|
||||
|
@ -3085,7 +3091,7 @@ void update_lakitu(struct Camera *c) {
|
|||
distToFloor = find_floor(gLakituState.pos[0],
|
||||
gLakituState.pos[1] + 20.0f,
|
||||
gLakituState.pos[2], &floor);
|
||||
gCheckingSurfaceCollisionsForCamera = false;
|
||||
gCheckingSurfaceCollisionsForCamera = FALSE;
|
||||
if (distToFloor != gLevelValues.floorLowerLimit) {
|
||||
if (gLakituState.pos[1] < (distToFloor += 100.0f)) {
|
||||
gLakituState.pos[1] = distToFloor;
|
||||
|
@ -3500,103 +3506,106 @@ void init_camera(struct Camera *c) {
|
|||
marioOffset[2] = 400.f;
|
||||
|
||||
// Set the camera's starting position or start a cutscene for certain levels
|
||||
switch (gCurrLevelNum) {
|
||||
case LEVEL_BOWSER_1:
|
||||
if (!sSoftResettingCamera) {
|
||||
switch (gCurrLevelNum) {
|
||||
case LEVEL_BOWSER_1:
|
||||
#ifndef VERSION_JP
|
||||
if (gCurrDemoInput == NULL) {
|
||||
if (gCurrDemoInput == NULL) {
|
||||
// Make sure Bowser is in a state that we'd start speaking to him in.
|
||||
obj = find_object_with_behavior(bhvBowser);
|
||||
if (obj != NULL && obj->oAction != 5) { break; }
|
||||
|
||||
start_cutscene(c, CUTSCENE_ENTER_BOWSER_ARENA);
|
||||
} else if (gSecondCameraFocus != NULL) {
|
||||
gSecondCameraFocus->oBowserUnk88 = 2;
|
||||
}
|
||||
#else
|
||||
// Make sure Bowser is in a state that we'd start speaking to him in.
|
||||
obj = find_object_with_behavior(bhvBowser);
|
||||
if (obj != NULL && obj->oAction != 5) { break; }
|
||||
|
||||
start_cutscene(c, CUTSCENE_ENTER_BOWSER_ARENA);
|
||||
} else if (gSecondCameraFocus != NULL) {
|
||||
gSecondCameraFocus->oBowserUnk88 = 2;
|
||||
}
|
||||
#else
|
||||
// Make sure Bowser is in a state that we'd start speaking to him in.
|
||||
obj = find_object_with_behavior(bhvBowser);
|
||||
if (obj != NULL && obj->oAction != 5) { break; }
|
||||
|
||||
start_cutscene(c, CUTSCENE_ENTER_BOWSER_ARENA);
|
||||
#endif
|
||||
break;
|
||||
case LEVEL_BOWSER_2:
|
||||
// Make sure Bowser is in a state that we'd start speaking to him in.
|
||||
obj = find_object_with_behavior(bhvBowser);
|
||||
if (obj != NULL && obj->oAction != 5) { break; }
|
||||
break;
|
||||
case LEVEL_BOWSER_2:
|
||||
// Make sure Bowser is in a state that we'd start speaking to him in.
|
||||
obj = find_object_with_behavior(bhvBowser);
|
||||
if (obj != NULL && obj->oAction != 5) { break; }
|
||||
|
||||
start_cutscene(c, CUTSCENE_ENTER_BOWSER_ARENA);
|
||||
break;
|
||||
case LEVEL_BOWSER_3:
|
||||
// Make sure Bowser is in a state that we'd start speaking to him in.
|
||||
obj = find_object_with_behavior(bhvBowser);
|
||||
if (obj != NULL && obj->oAction != 5) { break; }
|
||||
start_cutscene(c, CUTSCENE_ENTER_BOWSER_ARENA);
|
||||
break;
|
||||
case LEVEL_BOWSER_3:
|
||||
// Make sure Bowser is in a state that we'd start speaking to him in.
|
||||
obj = find_object_with_behavior(bhvBowser);
|
||||
if (obj != NULL && obj->oAction != 5) { break; }
|
||||
|
||||
start_cutscene(c, CUTSCENE_ENTER_BOWSER_ARENA);
|
||||
break;
|
||||
start_cutscene(c, CUTSCENE_ENTER_BOWSER_ARENA);
|
||||
break;
|
||||
|
||||
//! Hardcoded position checks determine which cutscene to play when Mario enters castle grounds.
|
||||
case LEVEL_CASTLE_GROUNDS:
|
||||
if (is_within_100_units_of_mario(-1328.f, 260.f, 4664.f) != 1) {
|
||||
marioOffset[0] = -400.f;
|
||||
marioOffset[2] = -800.f;
|
||||
}
|
||||
if (is_within_100_units_of_mario(-6901.f, 2376.f, -6509.f) == 1) {
|
||||
start_cutscene(c, CUTSCENE_EXIT_WATERFALL);
|
||||
}
|
||||
if (is_within_100_units_of_mario(5408.f, 4500.f, 3637.f) == 1) {
|
||||
start_cutscene(c, CUTSCENE_EXIT_FALL_WMOTR);
|
||||
}
|
||||
gLakituState.mode = CAMERA_MODE_FREE_ROAM;
|
||||
break;
|
||||
case LEVEL_SA:
|
||||
marioOffset[2] = 200.f;
|
||||
break;
|
||||
case LEVEL_CASTLE_COURTYARD:
|
||||
marioOffset[2] = -300.f;
|
||||
break;
|
||||
case LEVEL_LLL:
|
||||
gCameraMovementFlags |= CAM_MOVE_ZOOMED_OUT;
|
||||
break;
|
||||
case LEVEL_CASTLE:
|
||||
marioOffset[2] = 150.f;
|
||||
break;
|
||||
case LEVEL_RR:
|
||||
vec3f_set(sFixedModeBasePosition, -2985.f, 478.f, -5568.f);
|
||||
break;
|
||||
}
|
||||
if ((c->mode == CAMERA_MODE_8_DIRECTIONS) || c->mode == CAMERA_MODE_ROM_HACK) {
|
||||
gCameraMovementFlags |= CAM_MOVE_ZOOMED_OUT;
|
||||
}
|
||||
switch (gCurrLevelArea) {
|
||||
case AREA_SSL_EYEROK:
|
||||
vec3f_set(marioOffset, 0.f, 500.f, -100.f);
|
||||
break;
|
||||
case AREA_CCM_SLIDE:
|
||||
marioOffset[2] = -300.f;
|
||||
break;
|
||||
case AREA_THI_WIGGLER:
|
||||
marioOffset[2] = -300.f;
|
||||
break;
|
||||
case AREA_SL_IGLOO:
|
||||
marioOffset[2] = -300.f;
|
||||
break;
|
||||
case AREA_SL_OUTSIDE:
|
||||
if (is_within_100_units_of_mario(257.f, 2150.f, 1399.f) == 1) {
|
||||
//! Hardcoded position checks determine which cutscene to play when Mario enters castle grounds.
|
||||
case LEVEL_CASTLE_GROUNDS:
|
||||
if (is_within_100_units_of_mario(-1328.f, 260.f, 4664.f) != 1) {
|
||||
marioOffset[0] = -400.f;
|
||||
marioOffset[2] = -800.f;
|
||||
}
|
||||
if (is_within_100_units_of_mario(-6901.f, 2376.f, -6509.f) == 1) {
|
||||
start_cutscene(c, CUTSCENE_EXIT_WATERFALL);
|
||||
}
|
||||
if (is_within_100_units_of_mario(5408.f, 4500.f, 3637.f) == 1) {
|
||||
start_cutscene(c, CUTSCENE_EXIT_FALL_WMOTR);
|
||||
}
|
||||
gLakituState.mode = CAMERA_MODE_FREE_ROAM;
|
||||
break;
|
||||
case LEVEL_SA:
|
||||
marioOffset[2] = 200.f;
|
||||
break;
|
||||
case LEVEL_CASTLE_COURTYARD:
|
||||
marioOffset[2] = -300.f;
|
||||
}
|
||||
break;
|
||||
case AREA_CCM_OUTSIDE:
|
||||
break;
|
||||
case LEVEL_LLL:
|
||||
gCameraMovementFlags |= CAM_MOVE_ZOOMED_OUT;
|
||||
break;
|
||||
case LEVEL_CASTLE:
|
||||
marioOffset[2] = 150.f;
|
||||
break;
|
||||
case LEVEL_RR:
|
||||
vec3f_set(sFixedModeBasePosition, -2985.f, 478.f, -5568.f);
|
||||
break;
|
||||
}
|
||||
|
||||
if ((c->mode == CAMERA_MODE_8_DIRECTIONS) || c->mode == CAMERA_MODE_ROM_HACK) {
|
||||
gCameraMovementFlags |= CAM_MOVE_ZOOMED_OUT;
|
||||
break;
|
||||
case AREA_TTM_OUTSIDE:
|
||||
gLakituState.mode = CAMERA_MODE_RADIAL;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (gCurrLevelArea) {
|
||||
case AREA_SSL_EYEROK:
|
||||
vec3f_set(marioOffset, 0.f, 500.f, -100.f);
|
||||
break;
|
||||
case AREA_CCM_SLIDE:
|
||||
marioOffset[2] = -300.f;
|
||||
break;
|
||||
case AREA_THI_WIGGLER:
|
||||
marioOffset[2] = -300.f;
|
||||
break;
|
||||
case AREA_SL_IGLOO:
|
||||
marioOffset[2] = -300.f;
|
||||
break;
|
||||
case AREA_SL_OUTSIDE:
|
||||
if (is_within_100_units_of_mario(257.f, 2150.f, 1399.f) == 1) {
|
||||
marioOffset[2] = -300.f;
|
||||
}
|
||||
break;
|
||||
case AREA_CCM_OUTSIDE:
|
||||
gCameraMovementFlags |= CAM_MOVE_ZOOMED_OUT;
|
||||
break;
|
||||
case AREA_TTM_OUTSIDE:
|
||||
gLakituState.mode = CAMERA_MODE_RADIAL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (sSoftResettingCamera) {
|
||||
c->cutscene = 0;
|
||||
sSoftResettingCamera = FALSE;
|
||||
} else {
|
||||
// Set the camera pos to marioOffset (relative to Mario), added to Mario's position
|
||||
offset_rotated(c->pos, sMarioCamState->pos, marioOffset, sMarioCamState->faceAngle);
|
||||
|
@ -3621,8 +3630,10 @@ void init_camera(struct Camera *c) {
|
|||
c->yaw = gLakituState.yaw;
|
||||
c->nextYaw = gLakituState.yaw;
|
||||
|
||||
newcam_init(c, 0);
|
||||
newcam_init(c, sSoftResettingCamera);
|
||||
newcam_init_settings();
|
||||
|
||||
sSoftResettingCamera = FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -12027,7 +12038,7 @@ Gfx *geo_camera_fov(s32 callContext, struct GraphNode *g, UNUSED void *context)
|
|||
}
|
||||
}
|
||||
|
||||
perspective->fov = gFOVState.fov;
|
||||
perspective->fov = get_first_person_enabled() ? gFirstPersonCamera.fov : not_zero(gFOVState.fov, gOverrideFOV);
|
||||
shake_camera_fov(perspective);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -12299,9 +12310,9 @@ void mode_rom_hack_camera(struct Camera *c) {
|
|||
if (gMarioStates[0].controller->buttonPressed & U_JPAD) {
|
||||
sRomHackYaw = DEGREES(180 + 90) - gMarioStates[0].faceAngle[1];
|
||||
} else if (gMarioStates[0].controller->buttonDown & L_JPAD) {
|
||||
sRomHackYaw -= DEGREES(1) * (camera_config_is_x_inverted() ? -1 : 1);
|
||||
sRomHackYaw -= DEGREES(0.5) * (camera_config_is_x_inverted() ? -1 : 1);
|
||||
} else if (gMarioStates[0].controller->buttonDown & R_JPAD) {
|
||||
sRomHackYaw += DEGREES(1) * (camera_config_is_x_inverted() ? -1 : 1);
|
||||
sRomHackYaw += DEGREES(0.5) * (camera_config_is_x_inverted() ? -1 : 1);
|
||||
} else if (gMarioStates[0].controller->buttonPressed & D_JPAD) {
|
||||
sRomHackYaw = snap_to_45_degrees(sRomHackYaw);
|
||||
}
|
||||
|
@ -12331,6 +12342,22 @@ void mode_rom_hack_camera(struct Camera *c) {
|
|||
pos[1] = mPos[1] + desiredHeight;
|
||||
pos[2] = mPos[2] + sins(sRomHackYaw) * desiredDist;
|
||||
|
||||
// Move camera down for hangable ceilings
|
||||
if (sMarioCamState->action & ACT_FLAG_HANGING) {
|
||||
f32 marioCeilHeight = sMarioGeometry.currCeilHeight;
|
||||
f32 marioFloorHeight = sMarioGeometry.currFloorHeight;
|
||||
|
||||
if (marioFloorHeight < marioCeilHeight - 400.f) {
|
||||
marioFloorHeight = marioCeilHeight - 400.f;
|
||||
}
|
||||
|
||||
f32 goalHeight = marioFloorHeight + (marioCeilHeight - marioFloorHeight) * 0.4f;
|
||||
|
||||
if (pos[1] - 400 > goalHeight) {
|
||||
pos[1] -= 400;
|
||||
}
|
||||
}
|
||||
|
||||
if (rom_hack_cam_can_see_mario(pos)) {
|
||||
// we can see mario, no need to adjust
|
||||
c->pos[0] = pos[0];
|
||||
|
|
|
@ -476,8 +476,8 @@ void read_controller_inputs(void) {
|
|||
controller->rawStickY = controller->controllerData->stick_y;
|
||||
controller->extStickX = controller->controllerData->ext_stick_x;
|
||||
controller->extStickY = controller->controllerData->ext_stick_y;
|
||||
controller->buttonPressed = controller->controllerData->button
|
||||
& (controller->controllerData->button ^ controller->buttonDown);
|
||||
controller->buttonPressed = (~controller->buttonDown & controller->controllerData->button);
|
||||
controller->buttonReleased = (~controller->controllerData->button & controller->buttonDown);
|
||||
// 0.5x A presses are a good meme
|
||||
controller->buttonDown = controller->controllerData->button;
|
||||
adjust_analog_stick(controller);
|
||||
|
@ -488,6 +488,7 @@ void read_controller_inputs(void) {
|
|||
controller->extStickX = 0;
|
||||
controller->extStickY = 0;
|
||||
controller->buttonPressed = 0;
|
||||
controller->buttonReleased = 0;
|
||||
controller->buttonDown = 0;
|
||||
controller->stickX = 0;
|
||||
controller->stickY = 0;
|
||||
|
@ -505,6 +506,7 @@ void read_controller_inputs(void) {
|
|||
gPlayer3Controller->stickY = gPlayer1Controller->stickY;
|
||||
gPlayer3Controller->stickMag = gPlayer1Controller->stickMag;
|
||||
gPlayer3Controller->buttonPressed = gPlayer1Controller->buttonPressed;
|
||||
gPlayer3Controller->buttonReleased = gPlayer1Controller->buttonReleased;
|
||||
gPlayer3Controller->buttonDown = gPlayer1Controller->buttonDown;*/
|
||||
}
|
||||
|
||||
|
|
|
@ -666,18 +666,5 @@ void render_hud(void) {
|
|||
if (hudDisplayFlags & HUD_DISPLAY_FLAG_TIMER && showHud) {
|
||||
render_hud_timer();
|
||||
}
|
||||
|
||||
extern bool configLuaProfiler;
|
||||
if (configLuaProfiler) {
|
||||
extern void lua_profiler_update_counters();
|
||||
lua_profiler_update_counters();
|
||||
}
|
||||
#ifdef DEVELOPMENT
|
||||
extern bool configCtxProfiler;
|
||||
if (configCtxProfiler) {
|
||||
extern void ctx_profiler_update_counters();
|
||||
ctx_profiler_update_counters();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3269,7 +3269,7 @@ void print_hud_course_complete_coins(s16 x, s16 y) {
|
|||
gMarioStates[0].numLives++;
|
||||
}
|
||||
} else {
|
||||
if (gCourseCompleteCoins % gLevelValues.numCoinsToLife == 0 && gCourseCompleteCoins > 0) {
|
||||
if (gLevelValues.numCoinsToLife != 0 && gCourseCompleteCoins % gLevelValues.numCoinsToLife == 0 && gCourseCompleteCoins > 0) {
|
||||
play_sound(SOUND_GENERAL_COLLECT_1UP, gGlobalSoundSource);
|
||||
gMarioStates[0].numLives++;
|
||||
}
|
||||
|
|
|
@ -88,7 +88,6 @@ static u32 sBackwardKnockbackActions[][3] = {
|
|||
};
|
||||
|
||||
static u8 sDisplayingDoorText = FALSE;
|
||||
static u8 sCanInteractDoor = TRUE;
|
||||
static u8 sJustTeleported = FALSE;
|
||||
u8 gPssSlideStarted = FALSE;
|
||||
extern u8 gLastCollectedStarOrKey;
|
||||
|
@ -158,8 +157,9 @@ u32 determine_interaction(struct MarioState *m, struct Object *o) {
|
|||
}
|
||||
|
||||
if (interaction == 0 && action & ACT_FLAG_ATTACKING) {
|
||||
u32 flags = (o->oInteractType & INTERACT_PLAYER) ? (MARIO_PUNCHING | MARIO_KICKING) : (MARIO_PUNCHING | MARIO_KICKING | MARIO_TRIPPING);
|
||||
if (m->flags & flags) {
|
||||
u32 flags = (MARIO_PUNCHING | MARIO_KICKING | MARIO_TRIPPING);
|
||||
if ((action == ACT_PUNCHING || action == ACT_MOVE_PUNCHING || action == ACT_JUMP_KICK) ||
|
||||
(m->flags & flags && interaction & INT_LUA)) {
|
||||
s16 dYawToObject = mario_obj_angle_to_object(m, o) - m->faceAngle[1];
|
||||
|
||||
if (m->flags & MARIO_PUNCHING) {
|
||||
|
@ -237,6 +237,7 @@ u32 determine_interaction(struct MarioState *m, struct Object *o) {
|
|||
u32 attack_object(struct MarioState* m, struct Object *o, s32 interaction) {
|
||||
if (!o) { return 0; }
|
||||
u32 attackType = 0;
|
||||
interaction &= ~INT_LUA;
|
||||
|
||||
switch (interaction) {
|
||||
case INT_GROUND_POUND:
|
||||
|
@ -672,7 +673,8 @@ u32 determine_knockback_action(struct MarioState *m, UNUSED s32 arg) {
|
|||
if (!is_player_active(m2)) { continue; }
|
||||
if (m2->marioObj == NULL) { continue; }
|
||||
if (m2->marioObj != m->interactObj) { continue; }
|
||||
if (m2->action == ACT_JUMP_KICK) { scaler = 2; }
|
||||
if (m2->action == ACT_JUMP_KICK) { scaler = 2.0f; }
|
||||
if (m2->action == ACT_DIVE) { scaler += fabs(m2->forwardVel * 0.01); }
|
||||
if (m2->flags & MARIO_METAL_CAP) { scaler *= 1.25f; }
|
||||
break;
|
||||
}
|
||||
|
@ -1048,7 +1050,7 @@ u32 interact_warp(struct MarioState *m, UNUSED u32 interactType, struct Object *
|
|||
u32 display_door_dialog(struct MarioState *m, u32 actionArg) {
|
||||
if (!m) { return FALSE; }
|
||||
if (m != &gMarioStates[0]) { return FALSE; }
|
||||
return sCanInteractDoor ? set_mario_action(m, ACT_READING_AUTOMATIC_DIALOG, actionArg) : FALSE;
|
||||
return (!sDisplayingDoorText) ? set_mario_action(m, ACT_READING_AUTOMATIC_DIALOG, actionArg) : FALSE;
|
||||
}
|
||||
|
||||
u8 prevent_interact_door(struct MarioState* m, struct Object* o) {
|
||||
|
@ -1082,7 +1084,6 @@ u32 interact_warp_door(struct MarioState *m, UNUSED u32 interactType, struct Obj
|
|||
if (!(saveFlags & SAVE_FLAG_HAVE_KEY_2)) {
|
||||
if (display_door_dialog(m, (saveFlags & SAVE_FLAG_HAVE_KEY_1) ? gBehaviorValues.dialogs.KeyDoor1HaveDialog : gBehaviorValues.dialogs.KeyDoor1DontHaveDialog)) {
|
||||
sDisplayingDoorText = TRUE;
|
||||
sCanInteractDoor = FALSE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -1094,7 +1095,6 @@ u32 interact_warp_door(struct MarioState *m, UNUSED u32 interactType, struct Obj
|
|||
if (!(saveFlags & SAVE_FLAG_HAVE_KEY_1)) {
|
||||
if (display_door_dialog(m, (saveFlags & SAVE_FLAG_HAVE_KEY_2) ? gBehaviorValues.dialogs.KeyDoor2HaveDialog : gBehaviorValues.dialogs.KeyDoor2DontHaveDialog)) {
|
||||
sDisplayingDoorText = TRUE;
|
||||
sCanInteractDoor = FALSE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -1225,16 +1225,8 @@ u32 interact_door(struct MarioState *m, UNUSED u32 interactType, struct Object *
|
|||
|
||||
text += requiredNumStars - numStars;
|
||||
|
||||
if ((requiredNumStars == 70) || display_door_dialog(m, text)) {
|
||||
if (requiredNumStars == 70) {
|
||||
m->interactObj = o;
|
||||
m->usedObj = o;
|
||||
set_mario_action(m, ACT_ENTERING_STAR_DOOR, should_push_or_pull_door(m, o));
|
||||
}
|
||||
sDisplayingDoorText = TRUE;
|
||||
sCanInteractDoor = FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
sDisplayingDoorText = TRUE;
|
||||
return set_mario_action(m, ACT_READING_AUTOMATIC_DIALOG, text);
|
||||
}
|
||||
} else if (m->action == ACT_IDLE && sDisplayingDoorText == TRUE && requiredNumStars == 70) {
|
||||
m->interactObj = o;
|
||||
|
@ -1327,10 +1319,11 @@ static u8 resolve_player_collision(struct MarioState* m, struct MarioState* m2)
|
|||
}
|
||||
|
||||
u8 determine_player_damage_value(u32 interaction) {
|
||||
if (interaction & INT_GROUND_POUND_OR_TWIRL) { return 3; }
|
||||
if (interaction & INT_GROUND_POUND) { return 4; }
|
||||
if (interaction & (INT_TWIRL | INT_PUNCH | INT_TRIP)) { return 3; }
|
||||
if (interaction & INT_KICK) { return 2; }
|
||||
if (interaction & INT_ATTACK_SLIDE) { return 1; }
|
||||
return 2;
|
||||
if (interaction & INT_SLIDE_KICK) { return 2; }
|
||||
return 1;
|
||||
}
|
||||
|
||||
u8 player_is_sliding(struct MarioState* m) {
|
||||
|
@ -1877,7 +1870,7 @@ u32 interact_breakable(struct MarioState *m, UNUSED u32 interactType, struct Obj
|
|||
|
||||
m->interactObj = o;
|
||||
|
||||
switch (interaction) {
|
||||
switch (interaction & ~INT_LUA) {
|
||||
case INT_HIT_FROM_ABOVE:
|
||||
bounce_off_object(m, o, 30.0f); //! Not in the 0x8F mask
|
||||
break;
|
||||
|
@ -1909,7 +1902,7 @@ u32 interact_koopa_shell(struct MarioState *m, UNUSED u32 interactType, struct O
|
|||
if (!(m->action & ACT_FLAG_RIDING_SHELL)) {
|
||||
u32 interaction = determine_interaction(m, o);
|
||||
|
||||
if (interaction == INT_HIT_FROM_ABOVE || m->action == ACT_WALKING
|
||||
if (interaction & INT_HIT_FROM_ABOVE || m->action == ACT_WALKING
|
||||
|| m->action == ACT_HOLD_WALKING) {
|
||||
m->interactObj = o;
|
||||
m->usedObj = o;
|
||||
|
@ -2322,13 +2315,12 @@ void mario_process_interactions(struct MarioState *m) {
|
|||
check_kick_or_punch_wall(m);
|
||||
m->flags &= ~MARIO_PUNCHING & ~MARIO_KICKING & ~MARIO_TRIPPING;
|
||||
|
||||
if (!(m->marioObj->collidedObjInteractTypes & (INTERACT_WARP_DOOR | INTERACT_DOOR))) {
|
||||
sDisplayingDoorText = FALSE;
|
||||
sCanInteractDoor = TRUE;
|
||||
}
|
||||
if (!(m->marioObj->collidedObjInteractTypes & INTERACT_WARP)) {
|
||||
if (m == &gMarioStates[0]) {
|
||||
// limit to only local mario
|
||||
// limit to only local mario
|
||||
if (m == &gMarioStates[0]) {
|
||||
if (!(m->marioObj->collidedObjInteractTypes & (INTERACT_WARP_DOOR | INTERACT_DOOR))) {
|
||||
sDisplayingDoorText = FALSE;
|
||||
}
|
||||
if (!(m->marioObj->collidedObjInteractTypes & INTERACT_WARP)) {
|
||||
sJustTeleported = FALSE;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -53,6 +53,7 @@ enum InteractionFlag {
|
|||
INT_HIT_FROM_BELOW = /* 0x00000080 */ (1 << 7),
|
||||
INT_TWIRL = /* 0x00000100 */ (1 << 8),
|
||||
INT_GROUND_POUND_OR_TWIRL = (INT_GROUND_POUND | INT_TWIRL),
|
||||
INT_LUA = /* 0x10000000 */ (1 << 31) ,
|
||||
};
|
||||
|
||||
#define INT_ATTACK_NOT_FROM_BELOW (INT_GROUND_POUND_OR_TWIRL | INT_PUNCH | INT_KICK | INT_TRIP | INT_SLIDE_KICK | INT_FAST_ATTACK_OR_SHELL | INT_HIT_FROM_ABOVE)
|
||||
|
|
|
@ -251,7 +251,7 @@ u16 level_control_timer(s32 timerOp) {
|
|||
|
||||
u32 pressed_pause(void) {
|
||||
if (gServerSettings.pauseAnywhere) {
|
||||
if (get_dialog_id() < 0 && !gWarpTransition.isActive && sDelayedWarpOp == WARP_OP_NONE) {
|
||||
if (get_dialog_id() < 0) {
|
||||
return gPlayer1Controller->buttonPressed & START_BUTTON;
|
||||
}
|
||||
} else {
|
||||
|
@ -1121,7 +1121,7 @@ void update_hud_values(void) {
|
|||
play_sound(SOUND_GENERAL_COLLECT_1UP, gGlobalSoundSource);
|
||||
}
|
||||
} else {
|
||||
if (gHudDisplay.coins % gLevelValues.numCoinsToLife == 0 && gHudDisplay.coins > 0) {
|
||||
if (gLevelValues.numCoinsToLife != 0 && gHudDisplay.coins % gLevelValues.numCoinsToLife == 0 && gHudDisplay.coins > 0) {
|
||||
gMarioState->numLives++;
|
||||
play_sound(SOUND_GENERAL_COLLECT_1UP, gGlobalSoundSource);
|
||||
}
|
||||
|
|
|
@ -389,7 +389,7 @@ u8 should_start_or_continue_dialog(struct MarioState* m, struct Object* object)
|
|||
// 0 = not in dialog
|
||||
// 1 = starting dialog
|
||||
// 2 = speaking
|
||||
s32 set_mario_npc_dialog(struct MarioState* m, s32 actionArg, UNUSED u8 (*inContinueDialogFunction)(void)) {
|
||||
s32 set_mario_npc_dialog(struct MarioState* m, s32 actionArg, u8 (*inContinueDialogFunction)(void)) {
|
||||
if (!m) { return 0; }
|
||||
|
||||
s32 dialogState = 0;
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include "memory.h"
|
||||
#include "print.h"
|
||||
#include "pc/debuglog.h"
|
||||
#include "pc/lua/smlua.h"
|
||||
|
||||
#define ALIGN16(val) (((val) + 0xF) & ~0xF)
|
||||
|
||||
|
@ -222,7 +223,7 @@ void growing_array_free(struct GrowingArray **array) {
|
|||
if (*array) {
|
||||
for (u32 i = 0; i != (*array)->capacity; ++i) {
|
||||
if ((*array)->buffer[i]) {
|
||||
free((*array)->buffer[i]);
|
||||
smlua_free((*array)->buffer[i]);
|
||||
}
|
||||
}
|
||||
free((*array)->buffer);
|
||||
|
|
|
@ -2635,7 +2635,8 @@ s32 cur_obj_is_mario_ground_pounding_platform(void) {
|
|||
if (!is_player_active(&gMarioStates[i])) { continue; }
|
||||
if (!gMarioStates[i].marioObj) { continue; }
|
||||
if (gMarioStates[i].marioObj->platform == o) {
|
||||
if ((determine_interaction(&gMarioStates[i], o) & INT_GROUND_POUND) || (gMarioStates[i].action == ACT_GROUND_POUND_LAND)) {
|
||||
u32 interaction = determine_interaction(&gMarioStates[i], o);
|
||||
if ((gMarioStates[i].action == ACT_GROUND_POUND_LAND) || (interaction & INT_GROUND_POUND && interaction & INT_LUA)) {
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -237,7 +237,7 @@ void patch_mtx_interpolated(f32 delta) {
|
|||
u16 perspNorm;
|
||||
f32 fovInterpolated = delta_interpolate_f32(sPerspectiveNode->prevFov, sPerspectiveNode->fov, delta);
|
||||
f32 near = MIN(sPerspectiveNode->near, gProjectionMaxNearValue);
|
||||
guPerspective(sPerspectiveMtx, &perspNorm, get_first_person_enabled() ? gFirstPersonCamera.fov : not_zero(fovInterpolated, gOverrideFOV), sPerspectiveAspect, get_first_person_enabled() ? 1 : not_zero(near, gOverrideNear), not_zero(sPerspectiveNode->far, gOverrideFar), 1.0f);
|
||||
guPerspective(sPerspectiveMtx, &perspNorm, fovInterpolated, sPerspectiveAspect, get_first_person_enabled() ? 1 : not_zero(near, gOverrideNear), not_zero(sPerspectiveNode->far, gOverrideFar), 1.0f);
|
||||
gSPMatrix(sPerspectivePos, VIRTUAL_TO_PHYSICAL(sPerspectiveNode), G_MTX_PROJECTION | G_MTX_LOAD | G_MTX_NOPUSH);
|
||||
}
|
||||
|
||||
|
@ -488,7 +488,7 @@ static void geo_process_perspective(struct GraphNodePerspective *node) {
|
|||
gProjectionVanillaNearValue = node->near;
|
||||
gProjectionVanillaFarValue = node->far;
|
||||
f32 near = MIN(node->near, gProjectionMaxNearValue);
|
||||
guPerspective(mtx, &perspNorm, not_zero(node->prevFov, gOverrideFOV), aspect, get_first_person_enabled() ? 1 : not_zero(near, gOverrideNear), not_zero(node->far, gOverrideFar), 1.0f);
|
||||
guPerspective(mtx, &perspNorm, node->prevFov, aspect, get_first_person_enabled() ? 1 : not_zero(near, gOverrideNear), not_zero(node->far, gOverrideFar), 1.0f);
|
||||
|
||||
sPerspectiveNode = node;
|
||||
sPerspectiveMtx = mtx;
|
||||
|
@ -616,7 +616,7 @@ static void geo_process_translation_rotation(struct GraphNodeTranslationRotation
|
|||
Mat4 mtxf;
|
||||
Vec3f translation;
|
||||
|
||||
// Sanity check our stack index, If we above or equal to our stack size. Return to prevent OOB\.
|
||||
// Sanity check our stack index, If we above or equal to our stack size. Return to prevent OOB.
|
||||
if ((gMatStackIndex + 1) >= MATRIX_STACK_SIZE) { LOG_ERROR("Preventing attempt to exceed the maximum size %i for our matrix stack with size of %i.", MATRIX_STACK_SIZE - 1, gMatStackIndex); return; }
|
||||
|
||||
vec3s_to_vec3f(translation, node->translation);
|
||||
|
@ -1156,7 +1156,7 @@ static s32 obj_is_in_view(struct GraphNodeObject *node, Mat4 matrix) {
|
|||
// visibly pop in or out at the edge of the screen.
|
||||
//
|
||||
// Half of the fov in in-game angle units instead of degrees.
|
||||
s16 halfFov = ((get_first_person_enabled() ? gFirstPersonCamera.fov : not_zero(gCurGraphNodeCamFrustum->fov, gOverrideFOV)) / 2.0f + 1.0f) * 32768.0f / 180.0f + 0.5f;
|
||||
s16 halfFov = (gCurGraphNodeCamFrustum->fov / 2.0f + 1.0f) * 32768.0f / 180.0f + 0.5f;
|
||||
|
||||
f32 divisor = coss(halfFov);
|
||||
if (divisor == 0) { divisor = 1; }
|
||||
|
|
|
@ -140,7 +140,7 @@ void patch_scroll_targets_before(void) {
|
|||
}
|
||||
}
|
||||
|
||||
#define SHORT_RANGE 32767
|
||||
#define SHORT_RANGE 0x7FFF
|
||||
|
||||
void patch_scroll_targets_interpolated(f32 delta) {
|
||||
f32 antiDelta = 1.0f - delta;
|
||||
|
|
|
@ -186,6 +186,10 @@ unsigned int configDjuiThemeFont = FONT_NORMAL;
|
|||
unsigned int configDjuiScale = 0;
|
||||
// other
|
||||
unsigned int configRulesVersion = 0;
|
||||
bool configCompressOnStartup = false;
|
||||
|
||||
// secrets
|
||||
bool configExCoopTheme = false;
|
||||
|
||||
static const struct ConfigOption options[] = {
|
||||
// window settings
|
||||
|
@ -311,7 +315,27 @@ static const struct ConfigOption options[] = {
|
|||
{.name = "djui_theme_font", .type = CONFIG_TYPE_UINT, .uintValue = &configDjuiThemeFont},
|
||||
{.name = "djui_scale", .type = CONFIG_TYPE_UINT, .uintValue = &configDjuiScale},
|
||||
// other
|
||||
{.name = "rules_version", .type = CONFIG_TYPE_UINT, .uintValue = &configRulesVersion}
|
||||
{.name = "rules_version", .type = CONFIG_TYPE_UINT, .uintValue = &configRulesVersion},
|
||||
{.name = "compress_on_startup", .type = CONFIG_TYPE_BOOL, .boolValue = &configCompressOnStartup},
|
||||
};
|
||||
|
||||
struct SecretConfigOption {
|
||||
const char *name;
|
||||
enum ConfigOptionType type;
|
||||
union {
|
||||
bool *boolValue;
|
||||
unsigned int *uintValue;
|
||||
float* floatValue;
|
||||
char* stringValue;
|
||||
u64* u64Value;
|
||||
u8 (*colorValue)[3];
|
||||
};
|
||||
int maxStringLength;
|
||||
bool inConfig;
|
||||
};
|
||||
|
||||
static struct SecretConfigOption secret_options[] = {
|
||||
{.name = "ex_coop_theme", .type = CONFIG_TYPE_BOOL, .boolValue = &configExCoopTheme},
|
||||
};
|
||||
|
||||
// FunctionConfigOption functions
|
||||
|
@ -619,6 +643,15 @@ static void configfile_load_internal(const char *filename, bool* error) {
|
|||
}
|
||||
}
|
||||
|
||||
// secret options
|
||||
for (unsigned int i = 0; i < ARRAY_LEN(secret_options); i++) {
|
||||
if (strcmp(tokens[0], secret_options[i].name) == 0) {
|
||||
secret_options[i].inConfig = true;
|
||||
option = (const struct ConfigOption *) &secret_options[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (option == NULL) {
|
||||
#ifdef DEVELOPMENT
|
||||
printf("unknown option '%s'\n", tokens[0]);
|
||||
|
@ -689,6 +722,12 @@ NEXT_OPTION:
|
|||
if (configDjuiTheme >= DJUI_THEME_MAX) { configDjuiTheme = 0; }
|
||||
if (configDjuiScale >= 5) { configDjuiScale = 0; }
|
||||
|
||||
if (configExCoopTheme) {
|
||||
configDjuiTheme = DJUI_THEME_LIGHT;
|
||||
configDjuiThemeCenter = false;
|
||||
configDjuiThemeFont = 1;
|
||||
}
|
||||
|
||||
#ifndef COOPNET
|
||||
configNetworkSystem = NS_SOCKET;
|
||||
#endif
|
||||
|
@ -708,6 +747,42 @@ void configfile_load(void) {
|
|||
#endif
|
||||
}
|
||||
|
||||
static void configfile_save_option(FILE *file, const struct ConfigOption *option, bool isSecret) {
|
||||
if (isSecret) {
|
||||
const struct SecretConfigOption *secret_option = (const struct SecretConfigOption *) option;
|
||||
if (!secret_option->inConfig) { return; }
|
||||
}
|
||||
switch (option->type) {
|
||||
case CONFIG_TYPE_BOOL:
|
||||
fprintf(file, "%s %s\n", option->name, *option->boolValue ? "true" : "false");
|
||||
break;
|
||||
case CONFIG_TYPE_UINT:
|
||||
fprintf(file, "%s %u\n", option->name, *option->uintValue);
|
||||
break;
|
||||
case CONFIG_TYPE_FLOAT:
|
||||
fprintf(file, "%s %f\n", option->name, *option->floatValue);
|
||||
break;
|
||||
case CONFIG_TYPE_BIND:
|
||||
fprintf(file, "%s ", option->name);
|
||||
for (int i = 0; i < MAX_BINDS; ++i)
|
||||
fprintf(file, "%04x ", option->uintValue[i]);
|
||||
fprintf(file, "\n");
|
||||
break;
|
||||
case CONFIG_TYPE_STRING:
|
||||
fprintf(file, "%s %s\n", option->name, option->stringValue);
|
||||
break;
|
||||
case CONFIG_TYPE_U64:
|
||||
fprintf(file, "%s %llu\n", option->name, *option->u64Value);
|
||||
break;
|
||||
case CONFIG_TYPE_COLOR:
|
||||
fprintf(file, "%s %02x %02x %02x\n", option->name, (*option->colorValue)[0], (*option->colorValue)[1], (*option->colorValue)[2]);
|
||||
break;
|
||||
default:
|
||||
LOG_ERROR("Configfile wrote bad type '%d': %s", (int)option->type, option->name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Writes the config file to 'filename'
|
||||
void configfile_save(const char *filename) {
|
||||
FILE *file;
|
||||
|
@ -722,36 +797,12 @@ void configfile_save(const char *filename) {
|
|||
|
||||
for (unsigned int i = 0; i < ARRAY_LEN(options); i++) {
|
||||
const struct ConfigOption *option = &options[i];
|
||||
configfile_save_option(file, option, false);
|
||||
}
|
||||
|
||||
switch (option->type) {
|
||||
case CONFIG_TYPE_BOOL:
|
||||
fprintf(file, "%s %s\n", option->name, *option->boolValue ? "true" : "false");
|
||||
break;
|
||||
case CONFIG_TYPE_UINT:
|
||||
fprintf(file, "%s %u\n", option->name, *option->uintValue);
|
||||
break;
|
||||
case CONFIG_TYPE_FLOAT:
|
||||
fprintf(file, "%s %f\n", option->name, *option->floatValue);
|
||||
break;
|
||||
case CONFIG_TYPE_BIND:
|
||||
fprintf(file, "%s ", option->name);
|
||||
for (int i = 0; i < MAX_BINDS; ++i)
|
||||
fprintf(file, "%04x ", option->uintValue[i]);
|
||||
fprintf(file, "\n");
|
||||
break;
|
||||
case CONFIG_TYPE_STRING:
|
||||
fprintf(file, "%s %s\n", option->name, option->stringValue);
|
||||
break;
|
||||
case CONFIG_TYPE_U64:
|
||||
fprintf(file, "%s %llu\n", option->name, *option->u64Value);
|
||||
break;
|
||||
case CONFIG_TYPE_COLOR:
|
||||
fprintf(file, "%s %02x %02x %02x\n", option->name, (*option->colorValue)[0], (*option->colorValue)[1], (*option->colorValue)[2]);
|
||||
break;
|
||||
default:
|
||||
LOG_ERROR("Configfile wrote bad type '%d': %s", (int)option->type, option->name);
|
||||
break;
|
||||
}
|
||||
for (unsigned int i = 0; i < ARRAY_LEN(secret_options); i++) {
|
||||
const struct ConfigOption *option = (const struct ConfigOption *) &secret_options[i];
|
||||
configfile_save_option(file, option, true);
|
||||
}
|
||||
|
||||
// save function options
|
||||
|
|
|
@ -135,6 +135,10 @@ extern unsigned int configDjuiThemeFont;
|
|||
extern unsigned int configDjuiScale;
|
||||
// other
|
||||
extern unsigned int configRulesVersion;
|
||||
extern bool configCompressOnStartup;
|
||||
|
||||
// secrets
|
||||
extern bool configExCoopTheme;
|
||||
|
||||
void enable_queued_mods(void);
|
||||
void enable_queued_dynos_packs(void);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#include <stdio.h>
|
||||
#ifdef HAVE_SDL2
|
||||
#include <SDL2/SDL.h>
|
||||
#else
|
||||
#else
|
||||
#ifdef HAVE_SDL
|
||||
|
||||
#include <SDL/SDL.h>
|
||||
|
@ -145,7 +145,7 @@ const char* translate_bind_to_name(int bind) {
|
|||
if (sc == 0) { return name; }
|
||||
|
||||
#ifdef HAVE_SDL2
|
||||
const char* sname = SDL_GetScancodeName(sc);
|
||||
const char* sname = SDL_GetKeyName(SDL_GetKeyFromScancode(sc));
|
||||
if (strlen(sname) <= 9) { return sname; }
|
||||
|
||||
char* space = strchr(sname, ' ');
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
#include "utils/misc.h"
|
||||
#include "debug_context.h"
|
||||
#include "debuglog.h"
|
||||
#include "game/print.h"
|
||||
#include "game/hud.h"
|
||||
#include "gfx_dimensions.h"
|
||||
|
||||
static u32 sCtxDepth[CTX_MAX] = { 0 };
|
||||
|
@ -16,20 +14,6 @@ static f64 sCtxTime[CTX_MAX] = { 0 };
|
|||
static f64 sCtxStartTimeStack[MAX_TIME_STACK] = { 0 };
|
||||
static u32 sCtxStackIndex = 0;
|
||||
|
||||
static char* sDebugContextNames[] = {
|
||||
"NONE",
|
||||
"FRAME",
|
||||
"NET",
|
||||
"INTERP",
|
||||
"GAME",
|
||||
"SMLUA",
|
||||
"AUDIO",
|
||||
"RENDER",
|
||||
"LEVEL",
|
||||
"HOOK",
|
||||
"MAX",
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
void debug_context_begin(enum DebugContext ctx) {
|
||||
|
@ -71,29 +55,18 @@ void debug_context_reset(void) {
|
|||
}
|
||||
|
||||
bool debug_context_within(enum DebugContext ctx) {
|
||||
if (ctx > CTX_MAX) { return false; }
|
||||
if (ctx >= CTX_MAX) { return false; }
|
||||
return sCtxDepth[ctx] > 0;
|
||||
}
|
||||
|
||||
#ifdef DEVELOPMENT
|
||||
|
||||
void ctx_profiler_update_counters(void) {
|
||||
s32 y = SCREEN_HEIGHT - 60;
|
||||
for (s32 i = 1; i < CTX_MAX; i++) {
|
||||
const char *name = sDebugContextNames[i];
|
||||
s32 counterUs = (s32) (sCtxTime[i] * 1000000.0);
|
||||
char text[256];
|
||||
snprintf(text, 256, " %05d", counterUs);
|
||||
memcpy(text, name, MIN(12, strlen(name)));
|
||||
for (s32 j = 0; j != 12; ++j) {
|
||||
char c = text[j];
|
||||
if (c >= 'a' && c <= 'z') c -= ('a' - 'A');
|
||||
if ((c < '0' || c > '9') && (c < 'A' || c > 'Z')) c = ' ';
|
||||
text[j] = c;
|
||||
}
|
||||
print_text(GFX_DIMENSIONS_RECT_FROM_LEFT_EDGE(4), y, text);
|
||||
y -= 18;
|
||||
}
|
||||
void debug_context_set_time(enum DebugContext ctx, f64 time) {
|
||||
if (ctx >= CTX_MAX) { return; }
|
||||
sCtxTime[ctx] = time;
|
||||
}
|
||||
|
||||
#endif
|
||||
f64 debug_context_get_time(enum DebugContext ctx) {
|
||||
if (ctx >= CTX_MAX) { return 0.0; }
|
||||
return sCtxTime[ctx];
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -1,15 +1,17 @@
|
|||
#pragma once
|
||||
|
||||
#include <PR/ultratypes.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#define CTX_BEGIN(_ctx) debug_context_begin(_ctx)
|
||||
#define CTX_END(_ctx) debug_context_end(_ctx)
|
||||
#define CTX_WITHIN(_ctx) debug_context_within(_ctx)
|
||||
#define CTX_TIME(_ctx, time) debug_context_set_time(_ctx, time)
|
||||
#define CTX_EXTENT(_ctx, _f) { CTX_BEGIN(_ctx); _f(); CTX_END(_ctx); }
|
||||
|
||||
enum DebugContext {
|
||||
CTX_NONE,
|
||||
CTX_FRAME,
|
||||
CTX_TOTAL,
|
||||
CTX_NETWORK,
|
||||
CTX_INTERP,
|
||||
CTX_GAME_LOOP,
|
||||
|
@ -26,3 +28,5 @@ void debug_context_begin(enum DebugContext ctx);
|
|||
void debug_context_end(enum DebugContext ctx);
|
||||
void debug_context_reset(void);
|
||||
bool debug_context_within(enum DebugContext ctx);
|
||||
void debug_context_set_time(enum DebugContext ctx, f64 time);
|
||||
f64 debug_context_get_time(enum DebugContext ctx);
|
|
@ -5,7 +5,9 @@
|
|||
#include "djui_panel_pause.h"
|
||||
#include "djui_panel_join.h"
|
||||
#include "djui_panel_join_message.h"
|
||||
#include "djui_ctx_display.h"
|
||||
#include "djui_fps_display.h"
|
||||
#include "djui_lua_profiler.h"
|
||||
#include "../debuglog.h"
|
||||
#include "pc/cliopts.h"
|
||||
#include "game/level_update.h"
|
||||
|
@ -52,6 +54,8 @@ void djui_shutdown(void) {
|
|||
}
|
||||
|
||||
djui_fps_display_destroy();
|
||||
djui_ctx_display_destroy();
|
||||
djui_lua_profiler_destroy();
|
||||
|
||||
gDjuiShuttingDown = false;
|
||||
sDjuiInited = false;
|
||||
|
@ -97,6 +101,8 @@ void djui_init(void) {
|
|||
djui_console_create();
|
||||
|
||||
djui_fps_display_create();
|
||||
djui_ctx_display_create();
|
||||
djui_lua_profiler_create();
|
||||
|
||||
sDjuiInited = true;
|
||||
}
|
||||
|
@ -128,6 +134,11 @@ void djui_lua_error(char* text, struct DjuiColor color) {
|
|||
sDjuiLuaErrorTimeout = 30 * 5;
|
||||
}
|
||||
|
||||
void djui_lua_error_clear(void) {
|
||||
sDjuiLuaErrorTimeout = 0;
|
||||
djui_base_set_visible(&sDjuiLuaError->base, false);
|
||||
}
|
||||
|
||||
void djui_reset_hud_params(void) {
|
||||
djui_hud_set_resolution(RESOLUTION_DJUI);
|
||||
djui_hud_set_font(FONT_NORMAL);
|
||||
|
@ -158,6 +169,8 @@ void djui_render(void) {
|
|||
}
|
||||
|
||||
djui_fps_display_render();
|
||||
djui_ctx_display_render();
|
||||
djui_lua_profiler_render();
|
||||
|
||||
if (sDjuiLuaErrorTimeout > 0) {
|
||||
sDjuiLuaErrorTimeout--;
|
||||
|
|
|
@ -46,6 +46,7 @@ void djui_init(void);
|
|||
void djui_init_late(void);
|
||||
void djui_connect_menu_open(void);
|
||||
void djui_lua_error(char* text, struct DjuiColor color);
|
||||
void djui_lua_error_clear(void);
|
||||
void djui_render(void);
|
||||
void djui_reset_hud_params(void);
|
||||
|
||||
|
|
141
src/pc/djui/djui_ctx_display.c
Normal file
141
src/pc/djui/djui_ctx_display.c
Normal file
|
@ -0,0 +1,141 @@
|
|||
#include "djui_ctx_display.h"
|
||||
|
||||
#include "djui.h"
|
||||
#include "pc/pc_main.h"
|
||||
#include "pc/debug_context.h"
|
||||
|
||||
#ifdef DEVELOPMENT
|
||||
|
||||
static char* sDebugContextNames[] = {
|
||||
"NONE",
|
||||
"TOTAL",
|
||||
"NET",
|
||||
"INTERP",
|
||||
"GAME",
|
||||
"SMLUA",
|
||||
"AUDIO",
|
||||
"RENDER",
|
||||
"LEVEL",
|
||||
"HOOK",
|
||||
"OTHER",
|
||||
"MAX",
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
struct DjuiCtxEntry {
|
||||
struct DjuiText *name;
|
||||
struct DjuiText *timing;
|
||||
};
|
||||
|
||||
struct DjuiCtxDisplay {
|
||||
struct DjuiCtxEntry topEntry;
|
||||
struct DjuiCtxEntry entries[CTX_MAX];
|
||||
struct DjuiBase base;
|
||||
};
|
||||
|
||||
|
||||
struct DjuiCtxDisplay *sCtxDisplay = NULL;
|
||||
|
||||
void djui_ctx_display_update(void) {
|
||||
#ifdef DEVELOPMENT
|
||||
if (!configCtxProfiler || sCtxDisplay == NULL) { return; }
|
||||
|
||||
// Time we have for a indivdual frame. If we exceed it. We are in the red.
|
||||
f64 frameTime = 1.0 / 30.0;
|
||||
s32 frameTimeMs = (s32)(frameTime * 1000000.0);
|
||||
|
||||
struct DjuiCtxEntry *topEntry = &sCtxDisplay->topEntry;
|
||||
|
||||
// If we've exceeded our available frame time. Make the top entry timing red - For dramatic effect.
|
||||
// Otherwise. It's green!
|
||||
if (debug_context_get_time(CTX_TOTAL) > frameTime) {
|
||||
djui_base_set_color(&topEntry->timing->base, 255, 69, 0, 240);
|
||||
} else {
|
||||
djui_base_set_color(&topEntry->timing->base, 124, 252, 0, 240);
|
||||
}
|
||||
|
||||
djui_text_set_text(topEntry->name, "FRAME");
|
||||
char timing[32];
|
||||
snprintf(timing, 32, "%05d", frameTimeMs);
|
||||
djui_text_set_text(topEntry->timing, timing);
|
||||
|
||||
// Draw the counters.
|
||||
for (s32 i = CTX_TOTAL; i < CTX_MAX; i++) {
|
||||
struct DjuiCtxEntry *entry = &sCtxDisplay->entries[i];
|
||||
|
||||
const char *name = sDebugContextNames[i];
|
||||
djui_text_set_text(entry->name, name);
|
||||
|
||||
// The timing is in microseconds.
|
||||
s32 counterMs = (s32)(debug_context_get_time(i) * 1000000.0);
|
||||
char timing[32];
|
||||
snprintf(timing, 32, "%05d", counterMs);
|
||||
djui_text_set_text(entry->timing, timing);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void djui_ctx_display_render(void) {
|
||||
#ifdef DEVELOPMENT
|
||||
if (!configCtxProfiler || sCtxDisplay == NULL) { return; }
|
||||
|
||||
djui_rect_render(&sCtxDisplay->base);
|
||||
djui_base_render(&sCtxDisplay->base);
|
||||
#endif
|
||||
}
|
||||
|
||||
void djui_ctx_display_on_destroy(UNUSED struct DjuiBase* base) {
|
||||
free(sCtxDisplay);
|
||||
}
|
||||
|
||||
void djui_ctx_display_initialize_entry(struct DjuiBase *base, struct DjuiCtxEntry *entry, f64 offset) {
|
||||
struct DjuiText *name = djui_text_create(base, "");
|
||||
djui_text_set_alignment(name, DJUI_HALIGN_LEFT, DJUI_VALIGN_TOP);
|
||||
djui_base_set_size_type(&name->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
|
||||
djui_base_set_size(&name->base, 1.0f, name->fontScale * 2);
|
||||
djui_base_set_location(&name->base, 0, -name->fontScale / 3.0f + offset);
|
||||
djui_base_set_color(&name->base, 255, 255, 255, 240);
|
||||
|
||||
struct DjuiText *timing = djui_text_create(base, "");
|
||||
djui_text_set_alignment(timing, DJUI_HALIGN_RIGHT, DJUI_VALIGN_TOP);
|
||||
djui_base_set_size_type(&timing->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
|
||||
djui_base_set_size(&timing->base, 1.0f, timing->fontScale * 2);
|
||||
djui_base_set_location(&timing->base, 0, -timing->fontScale / 3.0f + offset);
|
||||
djui_base_set_color(&timing->base, 255, 255, 255, 240);
|
||||
|
||||
entry->name = name;
|
||||
entry->timing = timing;
|
||||
}
|
||||
|
||||
void djui_ctx_display_create(void) {
|
||||
struct DjuiCtxDisplay *ctxDisplay = calloc(1, sizeof(struct DjuiCtxDisplay));
|
||||
struct DjuiBase *base = &ctxDisplay->base;
|
||||
djui_base_init(NULL, base, NULL, djui_ctx_display_on_destroy);
|
||||
djui_base_set_size(base, 220.0f, 39.0f + ((CTX_MAX - 2) * 26.0f));
|
||||
djui_base_set_color(base, 0, 0, 0, 240);
|
||||
djui_base_set_border_color(base, 0, 0, 0, 200);
|
||||
djui_base_set_border_width(base, 4);
|
||||
djui_base_set_padding(base, 4, 4, 4, 4);
|
||||
djui_base_set_location(base, 0, 52.0f);
|
||||
|
||||
{
|
||||
f64 offset = 4.0;
|
||||
|
||||
djui_ctx_display_initialize_entry(base, &ctxDisplay->topEntry, offset);
|
||||
offset += 35.0;
|
||||
|
||||
for (s32 i = CTX_TOTAL; i < CTX_MAX; i++) {
|
||||
djui_ctx_display_initialize_entry(base, &ctxDisplay->entries[i], offset);
|
||||
offset += 22.0;
|
||||
}
|
||||
}
|
||||
|
||||
sCtxDisplay = ctxDisplay;
|
||||
}
|
||||
|
||||
void djui_ctx_display_destroy(void) {
|
||||
if (sCtxDisplay) {
|
||||
djui_base_destroy(&sCtxDisplay->base);
|
||||
}
|
||||
}
|
7
src/pc/djui/djui_ctx_display.h
Normal file
7
src/pc/djui/djui_ctx_display.h
Normal file
|
@ -0,0 +1,7 @@
|
|||
#pragma once
|
||||
#include "djui.h"
|
||||
|
||||
void djui_ctx_display_update(void);
|
||||
void djui_ctx_display_render(void);
|
||||
void djui_ctx_display_create(void);
|
||||
void djui_ctx_display_destroy(void);
|
|
@ -20,7 +20,7 @@ static void djui_font_normal_render_char(char* c) {
|
|||
}
|
||||
|
||||
static f32 djui_font_normal_char_width(char* c) {
|
||||
if (*c == ' ') { return 0.30f; }
|
||||
if (*c == ' ') { return configExCoopTheme ? 6 / 32.0f : 0.30f; }
|
||||
extern const f32 font_normal_widths[];
|
||||
return djui_unicode_get_sprite_width(c, font_normal_widths, 32.0f);
|
||||
}
|
||||
|
@ -62,7 +62,7 @@ static f32 djui_font_title_char_width(char* text) {
|
|||
if (c == ' ') { return 0.30f; }
|
||||
c = djui_unicode_get_base_char(text);
|
||||
extern const f32 font_title_widths[];
|
||||
return font_title_widths[(u8)c - '!'] * 1.1f;
|
||||
return font_title_widths[(u8)c - '!'] * (configExCoopTheme ? 1.0f : 1.1f);
|
||||
}
|
||||
|
||||
static const struct DjuiFont sDjuiFontTitle = {
|
||||
|
|
|
@ -131,11 +131,13 @@ void djui_gfx_render_texture_tile(const u8* texture, u32 w, u32 h, u32 bitSize,
|
|||
}
|
||||
|
||||
f32 aspect = tileH ? ((f32)tileW / (f32)tileH) : 1;
|
||||
f32 halfPxX = 1024.0f / (f32)w;
|
||||
f32 halfPxY = 1024.0f / (f32)h;
|
||||
// I don't know why adding 1 to all of the UVs seems to fix rendering, but it does...
|
||||
vtx[0] = (Vtx) {{{ 0, -1, 0 }, 0, { ( tileX * 2048.0f) / (f32)w, ((tileY + tileH) * 2048.0f) / (f32)h }, { 0xff, 0xff, 0xff, 0xff }}};
|
||||
vtx[1] = (Vtx) {{{ 1 * aspect, -1, 0 }, 0, { ((tileX + tileW) * 2048.0f) / (f32)w, ((tileY + tileH) * 2048.0f) / (f32)h }, { 0xff, 0xff, 0xff, 0xff }}};
|
||||
vtx[2] = (Vtx) {{{ 1 * aspect, 0, 0 }, 0, { ((tileX + tileW) * 2048.0f) / (f32)w, ( tileY * 2048.0f) / (f32)h }, { 0xff, 0xff, 0xff, 0xff }}};
|
||||
vtx[3] = (Vtx) {{{ 0, 0, 0 }, 0, { ( tileX * 2048.0f) / (f32)w, ( tileY * 2048.0f) / (f32)h }, { 0xff, 0xff, 0xff, 0xff }}};
|
||||
vtx[0] = (Vtx) {{{ 0, -1, 0 }, 0, { ( tileX * 2048.0f) / (f32)w - halfPxX, ((tileY + tileH) * 2048.0f) / (f32)h - halfPxY }, { 0xff, 0xff, 0xff, 0xff }}};
|
||||
vtx[1] = (Vtx) {{{ 1 * aspect, -1, 0 }, 0, { ((tileX + tileW) * 2048.0f) / (f32)w - halfPxX, ((tileY + tileH) * 2048.0f) / (f32)h - halfPxY }, { 0xff, 0xff, 0xff, 0xff }}};
|
||||
vtx[2] = (Vtx) {{{ 1 * aspect, 0, 0 }, 0, { ((tileX + tileW) * 2048.0f) / (f32)w - halfPxX, ( tileY * 2048.0f) / (f32)h - halfPxY }, { 0xff, 0xff, 0xff, 0xff }}};
|
||||
vtx[3] = (Vtx) {{{ 0, 0, 0 }, 0, { ( tileX * 2048.0f) / (f32)w - halfPxX, ( tileY * 2048.0f) / (f32)h - halfPxY }, { 0xff, 0xff, 0xff, 0xff }}};
|
||||
|
||||
gSPClearGeometryMode(gDisplayListHead++, G_LIGHTING);
|
||||
gDPSetCombineMode(gDisplayListHead++, G_CC_FADEA, G_CC_FADEA);
|
||||
|
|
|
@ -614,6 +614,19 @@ static void hud_rotate_and_translate_vec3f(Vec3f vec, Mat4* mtx, Vec3f out) {
|
|||
out[2] += (*mtx)[3][2];
|
||||
}
|
||||
|
||||
f32 get_current_fov() {
|
||||
return get_first_person_enabled() ? gFirstPersonCamera.fov : not_zero(gFOVState.fov, gOverrideFOV) + gFOVState.fovOffset;
|
||||
}
|
||||
|
||||
f32 djui_hud_get_fov_coeff() {
|
||||
// fov of 45.0 is the default fov
|
||||
f32 fov = get_current_fov();
|
||||
f32 fovDefault = tanf(45.f * ((f32)M_PI / 360.0f));
|
||||
f32 fovCurrent = tanf(fov * ((f32)M_PI / 360.0f));
|
||||
|
||||
return (fovDefault / fovCurrent) * 1.13f;
|
||||
}
|
||||
|
||||
bool djui_hud_world_pos_to_screen_pos(Vec3f pos, Vec3f out) {
|
||||
if (!gCamera) { return false; }
|
||||
hud_rotate_and_translate_vec3f(pos, &gCamera->mtx, out);
|
||||
|
@ -624,15 +637,10 @@ bool djui_hud_world_pos_to_screen_pos(Vec3f pos, Vec3f out) {
|
|||
out[0] *= 256.0f / -out[2];
|
||||
out[1] *= 256.0f / out[2];
|
||||
|
||||
// fov of 45.0 is the default fov
|
||||
f32 fov = get_first_person_enabled() ? gFirstPersonCamera.fov : not_zero(45.0f, gOverrideFOV);
|
||||
f32 fovDefault = tanf(fov * ((f32)M_PI / 360.0f));
|
||||
f32 fovCurrent = tanf((fov + gFOVState.fovOffset) * ((f32)M_PI / 360.0f));
|
||||
f32 fovCoeff = djui_hud_get_fov_coeff();
|
||||
|
||||
f32 fovDifference = (fovDefault / fovCurrent) * 1.13f;
|
||||
|
||||
out[0] *= fovDifference;
|
||||
out[1] *= fovDifference;
|
||||
out[0] *= fovCoeff;
|
||||
out[1] *= fovCoeff;
|
||||
|
||||
out[0] += djui_hud_get_screen_width() / 2.0f;
|
||||
out[1] += djui_hud_get_screen_height() / 2.0f;
|
||||
|
|
|
@ -87,6 +87,8 @@ void djui_hud_render_texture_tile_interpolated(struct TextureInfo* texInfo, f32
|
|||
void djui_hud_render_rect(f32 x, f32 y, f32 width, f32 height);
|
||||
void djui_hud_render_rect_interpolated(f32 prevX, f32 prevY, f32 prevWidth, f32 prevHeight, f32 x, f32 y, f32 width, f32 height);
|
||||
|
||||
f32 get_current_fov();
|
||||
f32 djui_hud_get_fov_coeff();
|
||||
bool djui_hud_world_pos_to_screen_pos(Vec3f pos, Vec3f out);
|
||||
bool djui_hud_is_pause_menu_created(void);
|
||||
|
||||
|
|
|
@ -235,15 +235,18 @@ bool djui_interactable_on_key_down(int scancode) {
|
|||
}
|
||||
}
|
||||
|
||||
if ((gDjuiPlayerList != NULL || gDjuiModList != NULL) && gServerSettings.enablePlayerList) {
|
||||
if ((gDjuiPlayerList != NULL || gDjuiModList != NULL)) {
|
||||
for (int i = 0; i < MAX_BINDS; i++) {
|
||||
if (scancode == (int)configKeyPlayerList[i] && !gDjuiInMainMenu && gNetworkType != NT_NONE) {
|
||||
if (gDjuiPlayerList != NULL) {
|
||||
djui_base_set_visible(&gDjuiPlayerList->base, true);
|
||||
}
|
||||
if (gDjuiModList != NULL) {
|
||||
djui_base_set_visible(&gDjuiModList->base, true);
|
||||
if (gServerSettings.enablePlayerList) {
|
||||
if (gDjuiPlayerList != NULL) {
|
||||
djui_base_set_visible(&gDjuiPlayerList->base, true);
|
||||
}
|
||||
if (gDjuiModList != NULL) {
|
||||
djui_base_set_visible(&gDjuiModList->base, true);
|
||||
}
|
||||
}
|
||||
gAttemptingToOpenPlayerlist = true;
|
||||
break;
|
||||
}
|
||||
if (gDjuiPlayerList->base.visible) {
|
||||
|
@ -295,6 +298,7 @@ void djui_interactable_on_key_up(int scancode) {
|
|||
if (gDjuiModList != NULL) {
|
||||
djui_base_set_visible(&gDjuiModList->base, false);
|
||||
}
|
||||
gAttemptingToOpenPlayerlist = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -405,17 +409,15 @@ void djui_interactable_update(void) {
|
|||
if (gInteractableFocus) {
|
||||
u16 mainButtons = PAD_BUTTON_A | PAD_BUTTON_B;
|
||||
if ((mouseButtons & MOUSE_BUTTON_1) && !(sLastMouseButtons && MOUSE_BUTTON_1) && !djui_cursor_inside_base(gInteractableFocus)) {
|
||||
// clicked outside of focused
|
||||
// if (!gDjuiChatBoxFocus && gDjuiChatBox != NULL && gInteractableFocus != &gDjuiChatBox->chatInput->base) {
|
||||
// djui_interactable_set_input_focus(NULL);
|
||||
// }
|
||||
djui_interactable_set_input_focus(NULL);
|
||||
// clicked outside of focus
|
||||
if (!gDjuiChatBoxFocus) {
|
||||
djui_interactable_set_input_focus(NULL);
|
||||
}
|
||||
} else if ((padButtons & mainButtons) && !(sLastInteractablePad.button & mainButtons)) {
|
||||
// pressed main face button
|
||||
// if (!gDjuiChatBoxFocus && gDjuiChatBox != NULL && gInteractableFocus != &gDjuiChatBox->chatInput->base) {
|
||||
// djui_interactable_set_input_focus(NULL);
|
||||
// }
|
||||
djui_interactable_set_input_focus(NULL);
|
||||
if (!gDjuiChatBoxFocus) {
|
||||
djui_interactable_set_input_focus(NULL);
|
||||
}
|
||||
} else {
|
||||
djui_interactable_on_focus(gInteractableFocus);
|
||||
}
|
||||
|
|
162
src/pc/djui/djui_lua_profiler.c
Normal file
162
src/pc/djui/djui_lua_profiler.c
Normal file
|
@ -0,0 +1,162 @@
|
|||
#include "djui_lua_profiler.h"
|
||||
|
||||
#include "djui.h"
|
||||
#include "pc/pc_main.h"
|
||||
#include "pc/mods/mod.h"
|
||||
#include "pc/mods/mods.h"
|
||||
|
||||
#define MAX_PROFILED_MODS 16
|
||||
#define REFRESH_RATE 30
|
||||
|
||||
struct DjuiPrfCounter {
|
||||
f64 start;
|
||||
f64 end;
|
||||
f64 sum;
|
||||
f64 display;
|
||||
};
|
||||
|
||||
struct DjuiPrfEntry {
|
||||
struct DjuiText *name;
|
||||
struct DjuiText *timing;
|
||||
struct DjuiPrfCounter counter;
|
||||
};
|
||||
|
||||
struct DjuiPrfDisplay {
|
||||
struct DjuiPrfEntry entries[MAX_PROFILED_MODS];
|
||||
struct DjuiBase base;
|
||||
};
|
||||
|
||||
static struct DjuiPrfDisplay *sPrfDisplay = NULL;
|
||||
static u8 sPrfDisplayCount = 0;
|
||||
|
||||
void lua_profiler_start_counter(UNUSED struct Mod *mod) {
|
||||
if (!configLuaProfiler || sPrfDisplay == NULL) { return; }
|
||||
|
||||
#ifndef WAPI_DUMMY
|
||||
for (s32 i = 0; i != MIN(MAX_PROFILED_MODS, gActiveMods.entryCount); ++i) {
|
||||
if (gActiveMods.entries[i] == mod) {
|
||||
f64 freq = SDL_GetPerformanceFrequency();
|
||||
f64 curr = SDL_GetPerformanceCounter();
|
||||
sPrfDisplay->entries[i].counter.start = curr / freq;
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void lua_profiler_stop_counter(UNUSED struct Mod *mod) {
|
||||
if (!configLuaProfiler || sPrfDisplay == NULL) { return; }
|
||||
|
||||
#ifndef WAPI_DUMMY
|
||||
for (s32 i = 0; i != MIN(MAX_PROFILED_MODS, gActiveMods.entryCount); ++i) {
|
||||
if (gActiveMods.entries[i] == mod) {
|
||||
f64 freq = SDL_GetPerformanceFrequency();
|
||||
f64 curr = SDL_GetPerformanceCounter();
|
||||
|
||||
struct DjuiPrfCounter *counter = &sPrfDisplay->entries[i].counter;
|
||||
counter->end = curr / freq;
|
||||
counter->sum += counter->end - counter->start;
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void djui_lua_profiler_initialize_entry(struct DjuiBase *base, struct DjuiPrfEntry *entry, f64 offset) {
|
||||
struct DjuiText *name = djui_text_create(base, "");
|
||||
djui_text_set_alignment(name, DJUI_HALIGN_LEFT, DJUI_VALIGN_TOP);
|
||||
djui_base_set_size_type(&name->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
|
||||
djui_base_set_size(&name->base, 1.0f, name->fontScale * 2);
|
||||
djui_base_set_location(&name->base, 0, -name->fontScale / 3.0f + offset);
|
||||
djui_base_set_color(&name->base, 255, 255, 255, 240);
|
||||
|
||||
struct DjuiText *timing = djui_text_create(base, "");
|
||||
djui_text_set_alignment(timing, DJUI_HALIGN_RIGHT, DJUI_VALIGN_TOP);
|
||||
djui_base_set_size_type(&timing->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
|
||||
djui_base_set_size(&timing->base, 1.0f, timing->fontScale * 2);
|
||||
djui_base_set_location(&timing->base, 0, -timing->fontScale / 3.0f + offset);
|
||||
djui_base_set_color(&timing->base, 255, 255, 255, 240);
|
||||
|
||||
entry->name = name;
|
||||
entry->timing = timing;
|
||||
}
|
||||
|
||||
void djui_lua_profiler_update(void) {
|
||||
if (!configLuaProfiler || sPrfDisplay == NULL) { return; }
|
||||
|
||||
if (sPrfDisplayCount != gActiveMods.entryCount) {
|
||||
for (s32 i = 0; i < MAX(sPrfDisplayCount, gActiveMods.entryCount); i++) {
|
||||
struct DjuiPrfEntry *entry = &sPrfDisplay->entries[i];
|
||||
if (i >= sPrfDisplayCount) {
|
||||
djui_lua_profiler_initialize_entry(&sPrfDisplay->base, entry, 4.0 + (i * 22.0));
|
||||
}
|
||||
if (i >= gActiveMods.entryCount) {
|
||||
djui_base_destroy(&entry->name->base);
|
||||
djui_base_destroy(&entry->timing->base);
|
||||
entry->name = NULL;
|
||||
entry->timing = NULL;
|
||||
}
|
||||
}
|
||||
sPrfDisplayCount = gActiveMods.entryCount;
|
||||
}
|
||||
|
||||
// Draw the counters.
|
||||
for (s32 i = 0; i < MIN(MAX_PROFILED_MODS, gActiveMods.entryCount); i++) {
|
||||
struct DjuiPrfEntry *entry = &sPrfDisplay->entries[i];
|
||||
struct DjuiPrfCounter *counter = &entry->counter;
|
||||
|
||||
if (gGlobalTimer % REFRESH_RATE == 0) {
|
||||
counter->display = counter->sum / (f64) REFRESH_RATE;
|
||||
counter->sum = 0;
|
||||
}
|
||||
|
||||
char name[256];
|
||||
memset(name, 0, 256);
|
||||
const char *modName = gActiveMods.entries[i]->relativePath;
|
||||
memcpy(name, modName, MIN(16, strlen(modName) - (gActiveMods.entries[i]->isDirectory ? 0 : 4)));
|
||||
for (s32 j = 0; j != 16; ++j) {
|
||||
char c = name[j];
|
||||
if (c >= 'a' && c <= 'z') c -= ('a' - 'A');
|
||||
if ((c < '0' || c > '9') && (c < 'A' || c > 'Z')) c = ' ';
|
||||
name[j] = c;
|
||||
}
|
||||
djui_text_set_text(entry->name, name);
|
||||
|
||||
// The timing is in microseconds.
|
||||
s32 counterMs = (s32)(counter->display * 1000000.0);
|
||||
char timing[32];
|
||||
snprintf(timing, 32, "%05d", counterMs);
|
||||
djui_text_set_text(entry->timing, timing);
|
||||
}
|
||||
}
|
||||
|
||||
void djui_lua_profiler_render(void) {
|
||||
if (!configLuaProfiler || sPrfDisplay == NULL) { return; }
|
||||
|
||||
djui_rect_render(&sPrfDisplay->base);
|
||||
djui_base_render(&sPrfDisplay->base);
|
||||
}
|
||||
|
||||
void djui_lua_profiler_on_destroy(UNUSED struct DjuiBase* base) {
|
||||
free(sPrfDisplay);
|
||||
}
|
||||
|
||||
void djui_lua_profiler_create(void) {
|
||||
struct DjuiPrfDisplay *prfDisplay = calloc(1, sizeof(struct DjuiPrfDisplay));
|
||||
struct DjuiBase *base = &prfDisplay->base;
|
||||
djui_base_init(NULL, base, NULL, djui_lua_profiler_on_destroy);
|
||||
djui_base_set_size(base, 290.0f, MAX_PROFILED_MODS * 26.0f);
|
||||
djui_base_set_color(base, 0, 0, 0, 240);
|
||||
djui_base_set_border_color(base, 0, 0, 0, 200);
|
||||
djui_base_set_border_width(base, 4);
|
||||
djui_base_set_padding(base, 4, 4, 4, 4);
|
||||
djui_base_set_location(base, 0, 300.0f);
|
||||
|
||||
sPrfDisplay = prfDisplay;
|
||||
}
|
||||
|
||||
void djui_lua_profiler_destroy(void) {
|
||||
if (sPrfDisplay) {
|
||||
djui_base_destroy(&sPrfDisplay->base);
|
||||
}
|
||||
}
|
11
src/pc/djui/djui_lua_profiler.h
Normal file
11
src/pc/djui/djui_lua_profiler.h
Normal file
|
@ -0,0 +1,11 @@
|
|||
#pragma once
|
||||
#include "djui.h"
|
||||
#include "pc/mods/mod.h"
|
||||
|
||||
void lua_profiler_start_counter(UNUSED struct Mod *mod);
|
||||
void lua_profiler_stop_counter(UNUSED struct Mod *mod);
|
||||
|
||||
void djui_lua_profiler_update(void);
|
||||
void djui_lua_profiler_render(void);
|
||||
void djui_lua_profiler_create(void);
|
||||
void djui_lua_profiler_destroy(void);
|
|
@ -58,6 +58,7 @@ struct DjuiPanel* djui_panel_add(struct DjuiBase* caller, struct DjuiThreePanel*
|
|||
panel->defaultElementBase = defaultElementBase;
|
||||
panel->on_back = threePanel->on_back;
|
||||
panel->on_panel_destroy = NULL;
|
||||
panel->temporary = threePanel->temporary;
|
||||
sPanelList = panel;
|
||||
|
||||
// find better defaultElementBase
|
||||
|
@ -118,6 +119,7 @@ void djui_panel_back(void) {
|
|||
|
||||
// set the previous active
|
||||
sPanelList = sPanelList->parent;
|
||||
if (sPanelList->temporary) { sPanelList = sPanelList->parent; }
|
||||
|
||||
// reset move amount
|
||||
sMoveAmount = 0;
|
||||
|
|
|
@ -25,30 +25,32 @@ static void djui_panel_main_quit(struct DjuiBase* caller) {
|
|||
}
|
||||
|
||||
void djui_panel_main_create(struct DjuiBase* caller) {
|
||||
struct DjuiThreePanel* panel = djui_panel_menu_create("", false);
|
||||
struct DjuiThreePanel* panel = djui_panel_menu_create(configExCoopTheme ? "\\#ff0800\\SM\\#1be700\\64\\#00b3ff\\EX\n\\#ffef00\\COOP" : "", false);
|
||||
{
|
||||
struct DjuiBase* body = djui_three_panel_get_body(panel);
|
||||
{
|
||||
struct DjuiImage* logo = djui_image_create(body, texture_coopdx_logo, 2048, 1024, 32);
|
||||
if (configDjuiThemeCenter) {
|
||||
djui_base_set_size(&logo->base, 550, 275);
|
||||
} else {
|
||||
djui_base_set_size(&logo->base, 480, 240);
|
||||
if (!configExCoopTheme) {
|
||||
struct DjuiImage* logo = djui_image_create(body, texture_coopdx_logo, 2048, 1024, 32);
|
||||
if (configDjuiThemeCenter) {
|
||||
djui_base_set_size(&logo->base, 550, 275);
|
||||
} else {
|
||||
djui_base_set_size(&logo->base, 480, 240);
|
||||
}
|
||||
djui_base_set_alignment(&logo->base, DJUI_HALIGN_CENTER, DJUI_VALIGN_TOP);
|
||||
djui_base_set_location_type(&logo->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
|
||||
djui_base_set_location(&logo->base, 0, -30);
|
||||
}
|
||||
djui_base_set_alignment(&logo->base, DJUI_HALIGN_CENTER, DJUI_VALIGN_TOP);
|
||||
djui_base_set_location_type(&logo->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
|
||||
djui_base_set_location(&logo->base, 0, -30);
|
||||
|
||||
struct DjuiButton* button1 = djui_button_create(body, DLANG(MAIN, HOST), DJUI_BUTTON_STYLE_NORMAL, djui_panel_host_create);
|
||||
djui_base_set_location(&button1->base, 0, -30);
|
||||
if (!configExCoopTheme) { djui_base_set_location(&button1->base, 0, -30); }
|
||||
djui_cursor_input_controlled_center(&button1->base);
|
||||
|
||||
struct DjuiButton* button2 = djui_button_create(body, DLANG(MAIN, JOIN), DJUI_BUTTON_STYLE_NORMAL, djui_panel_join_create);
|
||||
djui_base_set_location(&button2->base, 0, -30);
|
||||
if (!configExCoopTheme) { djui_base_set_location(&button2->base, 0, -30); }
|
||||
struct DjuiButton* button3 = djui_button_create(body, DLANG(MAIN, OPTIONS), DJUI_BUTTON_STYLE_NORMAL, djui_panel_options_create);
|
||||
djui_base_set_location(&button3->base, 0, -30);
|
||||
if (!configExCoopTheme) { djui_base_set_location(&button3->base, 0, -30); }
|
||||
struct DjuiButton* button4 = djui_button_create(body, DLANG(MAIN, QUIT), DJUI_BUTTON_STYLE_BACK, djui_panel_main_quit);
|
||||
djui_base_set_location(&button4->base, 0, -30);
|
||||
if (!configExCoopTheme) { djui_base_set_location(&button4->base, 0, -30); }
|
||||
}
|
||||
|
||||
// these two cannot co-exist for some reason
|
||||
|
|
|
@ -13,6 +13,13 @@ char* sRainbowColors[] = {
|
|||
"\\#ffef40\\",
|
||||
};
|
||||
|
||||
char* sExCoopRainbowColors[] = {
|
||||
"\\#ff0800\\",
|
||||
"\\#1be700\\",
|
||||
"\\#00b3ff\\",
|
||||
"\\#ffef00\\",
|
||||
};
|
||||
|
||||
char sRainbowText[RAINBOW_TEXT_LEN + 1] = { 0 };
|
||||
|
||||
static void generate_rainbow_text(char* text) {
|
||||
|
@ -28,7 +35,7 @@ static void generate_rainbow_text(char* text) {
|
|||
}
|
||||
s32 restrictSize = RAINBOW_TEXT_LEN - (s32)(dst - sRainbowText);
|
||||
if (restrictSize <= 0) { break; }
|
||||
snprintf(dst, restrictSize, "%s", sRainbowColors[i++ % 4]);
|
||||
snprintf(dst, restrictSize, "%s", configExCoopTheme ? sExCoopRainbowColors[i++ % 4] : sRainbowColors[i++ % 4]);
|
||||
dst = &sRainbowText[strlen(sRainbowText)];
|
||||
|
||||
restrictSize = RAINBOW_TEXT_LEN - (s32)(dst - sRainbowText);
|
||||
|
@ -75,7 +82,11 @@ struct DjuiThreePanel* djui_panel_menu_create(char* headerText, bool forcedLeftS
|
|||
djui_base_set_location(&header->base, 0, DJUI_PANEL_HEADER_OFFSET);
|
||||
djui_text_set_alignment(header, DJUI_HALIGN_CENTER, DJUI_VALIGN_BOTTOM);
|
||||
djui_text_set_font(header, hudFontHeader ? gDjuiFonts[2] : gDjuiFonts[1]);
|
||||
djui_text_set_font_scale(header, gDjuiFonts[1]->defaultFontScale * (hudFontHeader ? 0.7f : 1.0f) * (strlen(headerText) > 15 ? 0.9f : 1.0f));
|
||||
if (configExCoopTheme) {
|
||||
djui_text_set_font_scale(header, gDjuiFonts[1]->defaultFontScale);
|
||||
} else {
|
||||
djui_text_set_font_scale(header, gDjuiFonts[1]->defaultFontScale * (hudFontHeader ? 0.7f : 1.0f) * (strlen(headerText) > 15 ? 0.9f : 1.0f));
|
||||
}
|
||||
|
||||
struct DjuiFlowLayout* body = djui_flow_layout_create(&panel->base);
|
||||
djui_base_set_alignment(&body->base, DJUI_HALIGN_CENTER, DJUI_VALIGN_CENTER);
|
||||
|
|
|
@ -89,16 +89,23 @@ void djui_panel_main_menu_create(struct DjuiBase* caller) {
|
|||
djui_themes_init();
|
||||
|
||||
{
|
||||
djui_checkbox_create(body, DLANG(DJUI_THEMES, CENTER), &configDjuiThemeCenter, djui_panel_menu_options_djui_setting_change);
|
||||
struct DjuiCheckbox* center = djui_checkbox_create(body, DLANG(DJUI_THEMES, CENTER), &configDjuiThemeCenter, djui_panel_menu_options_djui_setting_change);
|
||||
if (configExCoopTheme) { djui_base_set_enabled(¢er->base, false); }
|
||||
|
||||
char* themeChoices[DJUI_THEME_MAX];
|
||||
for (int i = 0; i < DJUI_THEME_MAX; i++) {
|
||||
themeChoices[i] = (char*)gDjuiThemes[i]->name;
|
||||
}
|
||||
djui_selectionbox_create(body, DLANG(DJUI_THEMES, DJUI_THEME), themeChoices, DJUI_THEME_MAX, &configDjuiTheme, djui_panel_menu_options_djui_setting_change);
|
||||
struct DjuiSelectionbox* theme = djui_selectionbox_create(body, DLANG(DJUI_THEMES, DJUI_THEME), themeChoices, DJUI_THEME_MAX, &configDjuiTheme, djui_panel_menu_options_djui_setting_change);
|
||||
if (configExCoopTheme) { djui_base_set_enabled(&theme->base, false); }
|
||||
|
||||
char* djuiScaleChoices[5] = {DLANG(DJUI_THEMES, AUTO), "x0.5", "x0.85", "x1.0", "x1.5"};
|
||||
djui_selectionbox_create(body, DLANG(DJUI_THEMES, DJUI_SCALE), djuiScaleChoices, 5, &configDjuiScale, djui_panel_menu_options_djui_setting_change);
|
||||
struct DjuiSelectionbox* scale = djui_selectionbox_create(body, DLANG(DJUI_THEMES, DJUI_SCALE), djuiScaleChoices, 5, &configDjuiScale, djui_panel_menu_options_djui_setting_change);
|
||||
if (configExCoopTheme) { djui_base_set_enabled(&scale->base, false); }
|
||||
|
||||
char* djuiFontChoices[2] = {DLANG(DJUI_THEMES, FONT_NORMAL), DLANG(DJUI_THEMES, FONT_ALIASED)};
|
||||
djui_selectionbox_create(body, DLANG(DJUI_THEMES, DJUI_FONT), djuiFontChoices, 2, &configDjuiThemeFont, djui_panel_menu_options_djui_setting_change);
|
||||
struct DjuiSelectionbox* font = djui_selectionbox_create(body, DLANG(DJUI_THEMES, DJUI_FONT), djuiFontChoices, 2, &configDjuiThemeFont, djui_panel_menu_options_djui_setting_change);
|
||||
if (configExCoopTheme) { djui_base_set_enabled(&font->base, false); }
|
||||
|
||||
if (gDjuiInMainMenu) {
|
||||
// get level choices
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include "pc/utils/misc.h"
|
||||
|
||||
struct DjuiThreePanel* gDjuiPlayerList = NULL;
|
||||
bool gAttemptingToOpenPlayerlist = false;
|
||||
|
||||
static struct DjuiFlowLayout* djuiRow[MAX_PLAYERS] = { 0 };
|
||||
static struct DjuiImage* djuiImages[MAX_PLAYERS] = { 0 };
|
||||
|
@ -53,7 +54,11 @@ static void playerlist_update_row(u8 i, struct NetworkPlayer *np) {
|
|||
djui_base_set_color(&djuiTextDescriptions[i]->base, np->descriptionR, np->descriptionG, np->descriptionB, np->descriptionA);
|
||||
djui_text_set_text(djuiTextDescriptions[i], np->description);
|
||||
|
||||
djui_text_set_text(djuiTextLocations[i], get_level_name(np->currCourseNum, np->currLevelNum, np->currAreaIndex));
|
||||
djui_text_set_text(djuiTextLocations[i],
|
||||
np->overrideLocation[0] == '\0'
|
||||
? get_level_name(np->currCourseNum, np->currLevelNum, np->currAreaIndex)
|
||||
: np->overrideLocation
|
||||
);
|
||||
djui_text_set_text(djuiTextAct[i], sActNum);
|
||||
}
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#include "djui.h"
|
||||
|
||||
extern struct DjuiThreePanel* gDjuiPlayerList;
|
||||
extern bool gAttemptingToOpenPlayerlist;
|
||||
|
||||
extern const u8 sPlayerListSize;
|
||||
extern u8 sPageIndex;
|
||||
|
|
|
@ -21,16 +21,7 @@ void djui_panel_rules_create(struct DjuiBase* caller) {
|
|||
struct DjuiThreePanel* panel = djui_panel_menu_create(DLANG(RULES, RULES_TITLE), false);
|
||||
struct DjuiBase* body = djui_three_panel_get_body(panel);
|
||||
{
|
||||
snprintf(sRules, 512, "%s\n\
|
||||
%s\n\
|
||||
%s\n\
|
||||
%s\n\
|
||||
%s",
|
||||
DLANG(RULES, RULE_1),
|
||||
DLANG(RULES, RULE_2),
|
||||
DLANG(RULES, RULE_3),
|
||||
DLANG(RULES, RULE_4),
|
||||
DLANG(RULES, RULE_5));
|
||||
snprintf(sRules, 512, "%s\n%s\n%s\n%s\n%s", DLANG(RULES, RULE_1), DLANG(RULES, RULE_2), DLANG(RULES, RULE_3), DLANG(RULES, RULE_4), DLANG(RULES, RULE_5));
|
||||
|
||||
struct DjuiText* text1 = djui_text_create(body, sRules);
|
||||
djui_base_set_location(&text1->base, 0, 0);
|
||||
|
@ -65,6 +56,7 @@ DLANG(RULES, RULE_5));
|
|||
|
||||
}
|
||||
|
||||
panel->temporary = true;
|
||||
djui_panel_add(caller, panel, NULL);
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
void djui_progress_bar_render_pre(struct DjuiBase* base, UNUSED bool* unused) {
|
||||
struct DjuiProgressBar* progress = (struct DjuiProgressBar*)base;
|
||||
progress->smoothValue = progress->smoothValue * 0.95f + *progress->value * 0.05f;
|
||||
progress->smoothValue = progress->smoothValue * progress->smoothenHigh + *progress->value * progress->smoothenLow;
|
||||
float min = progress->min;
|
||||
float max = progress->max;
|
||||
djui_base_set_size(&progress->rectValue->base, ((f32)progress->smoothValue - min) / ((f32)max - min), 1.0f);
|
||||
|
@ -13,7 +13,7 @@ void djui_progress_bar_render_pre_infinite(struct DjuiBase* base, UNUSED bool* u
|
|||
float min = progress->min;
|
||||
float max = progress->max;
|
||||
|
||||
progress->smoothValue = progress->smoothValue * 0.95f + *progress->value * 0.05f;
|
||||
progress->smoothValue = progress->smoothValue * progress->smoothenHigh + *progress->value * progress->smoothenLow;
|
||||
float modValue = progress->smoothValue - ((int)progress->smoothValue);
|
||||
float x = (modValue - min - 0.25f) / (max - min - 0.25f);
|
||||
float w = 0.25f;
|
||||
|
@ -43,6 +43,8 @@ struct DjuiProgressBar* djui_progress_bar_create(struct DjuiBase* parent, float*
|
|||
progress->smoothValue = *value;
|
||||
progress->min = min;
|
||||
progress->max = max;
|
||||
progress->smoothenHigh = 0.95f;
|
||||
progress->smoothenLow = 0.05f;
|
||||
|
||||
djui_base_init(parent, base, NULL, djui_progress_bar_destroy);
|
||||
djui_base_set_size_type(base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
|
||||
|
|
|
@ -9,6 +9,8 @@ struct DjuiProgressBar {
|
|||
float smoothValue;
|
||||
float min;
|
||||
float max;
|
||||
float smoothenHigh;
|
||||
float smoothenLow;
|
||||
};
|
||||
|
||||
struct DjuiProgressBar* djui_progress_bar_create(struct DjuiBase* parent, float* value, float min, float max, bool infinite);
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
#pragma once
|
||||
#include "djui.h"
|
||||
|
||||
#define DJUI_THEME_CENTERED_WIDTH 1.25f
|
||||
#define DJUI_THEME_CENTERED_HEIGHT 0.88f
|
||||
#define DJUI_THEME_CENTERED_WIDTH 1.3f
|
||||
#define DJUI_THEME_CENTERED_HEIGHT 0.9f
|
||||
|
||||
enum DjuiThemeType {
|
||||
DJUI_THEME_LIGHT,
|
||||
|
|
|
@ -6,6 +6,7 @@ struct DjuiThreePanel {
|
|||
struct DjuiScreenValue minHeaderSize;
|
||||
struct DjuiScreenValue bodySize;
|
||||
struct DjuiScreenValue minFooterSize;
|
||||
bool temporary;
|
||||
bool (*on_back)(struct DjuiBase*);
|
||||
};
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include <ctype.h>
|
||||
#ifdef _WIN32
|
||||
#include <direct.h>
|
||||
#include <fileapi.h>
|
||||
#endif
|
||||
|
||||
#include "macros.h"
|
||||
|
@ -292,18 +293,32 @@ bool fs_sys_filename_is_portable(char const *filename) {
|
|||
/* these operate on the real file system */
|
||||
|
||||
bool fs_sys_path_exists(const char *name) {
|
||||
#ifdef _WIN32
|
||||
return GetFileAttributesA(name) != INVALID_FILE_ATTRIBUTES;
|
||||
#else
|
||||
struct stat st;
|
||||
return (stat(name, &st) == 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool fs_sys_file_exists(const char *name) {
|
||||
#ifdef _WIN32
|
||||
DWORD attribs = GetFileAttributesA(name);
|
||||
return attribs != INVALID_FILE_ATTRIBUTES && !(attribs & FILE_ATTRIBUTE_DIRECTORY);
|
||||
#else
|
||||
struct stat st;
|
||||
return (stat(name, &st) == 0 && S_ISREG(st.st_mode));
|
||||
#endif
|
||||
}
|
||||
|
||||
bool fs_sys_dir_exists(const char *name) {
|
||||
#ifdef _WIN32
|
||||
DWORD attribs = GetFileAttributesA(name);
|
||||
return attribs != INVALID_FILE_ATTRIBUTES && (attribs & FILE_ATTRIBUTE_DIRECTORY);
|
||||
#else
|
||||
struct stat st;
|
||||
return (stat(name, &st) == 0 && S_ISDIR(st.st_mode));
|
||||
#endif
|
||||
}
|
||||
|
||||
bool fs_sys_dir_is_empty(const char *name) {
|
||||
|
|
|
@ -113,7 +113,7 @@ static void gfx_dummy_wm_start_text_input(void) {
|
|||
static void gfx_dummy_wm_stop_text_input(void) {
|
||||
}
|
||||
|
||||
static void gfx_dummy_wm_set_clipboard_text(UNUSED char* text) {
|
||||
static void gfx_dummy_wm_set_clipboard_text(UNUSED const char* text) {
|
||||
}
|
||||
|
||||
static void gfx_dummy_wm_set_cursor_visible(UNUSED bool visible) {
|
||||
|
|
|
@ -719,26 +719,40 @@ void gfx_dxgi_start_text_input(void) { inTextInput = TRUE; }
|
|||
void gfx_dxgi_stop_text_input(void) { inTextInput = FALSE; }
|
||||
|
||||
static char* gfx_dxgi_get_clipboard_text(void) {
|
||||
static char clipboard_buf[WAPI_CLIPBOARD_BUFSIZ];
|
||||
clipboard_buf[0] = '\0';
|
||||
|
||||
if (OpenClipboard(NULL)) {
|
||||
HANDLE clip = GetClipboardData(CF_TEXT);
|
||||
LPCWSTR text = (LPCWSTR)GetClipboardData(CF_UNICODETEXT);
|
||||
if (text != NULL) {
|
||||
WideCharToMultiByte(CP_UTF8, 0, text, (-1), clipboard_buf, WAPI_CLIPBOARD_BUFSIZ, NULL, NULL);
|
||||
}
|
||||
CloseClipboard();
|
||||
return (char*)clip;
|
||||
}
|
||||
return NULL;
|
||||
|
||||
clipboard_buf[WAPI_CLIPBOARD_BUFSIZ - 1] = '\0';
|
||||
return clipboard_buf;
|
||||
}
|
||||
|
||||
void gfx_dxgi_set_clipboard_text(char* text) {
|
||||
if (OpenClipboard(NULL)) {
|
||||
HGLOBAL clipbuffer;
|
||||
char *buffer;
|
||||
EmptyClipboard();
|
||||
clipbuffer = GlobalAlloc(GMEM_DDESHARE, strlen(text) + 1);
|
||||
buffer = (char *) GlobalLock(clipbuffer);
|
||||
strcpy(buffer, LPCSTR(text));
|
||||
GlobalUnlock(clipbuffer);
|
||||
SetClipboardData(CF_TEXT, clipbuffer);
|
||||
CloseClipboard();
|
||||
void gfx_dxgi_set_clipboard_text(const char* text) {
|
||||
if (!OpenClipboard(NULL)) { return; }
|
||||
EmptyClipboard();
|
||||
|
||||
int cch = MultiByteToWideChar(CP_UTF8, 0, text, (-1), NULL, 0);
|
||||
if (cch > 0) {
|
||||
HGLOBAL hMem = GlobalAlloc(GMEM_MOVEABLE, cch * sizeof(WCHAR));
|
||||
if (hMem != NULL) {
|
||||
LPWSTR wcsBuffer = (LPWSTR)GlobalLock(hMem);
|
||||
if (wcsBuffer != NULL) {
|
||||
MultiByteToWideChar(CP_UTF8, 0, text, (-1), wcsBuffer, cch);
|
||||
GlobalUnlock(hMem);
|
||||
SetClipboardData(CF_UNICODETEXT, hMem);
|
||||
} else {
|
||||
GlobalFree(hMem);
|
||||
}
|
||||
}
|
||||
}
|
||||
CloseClipboard();
|
||||
}
|
||||
|
||||
void gfx_dxgi_set_cursor_visible(bool visible) { ShowCursor(visible); }
|
||||
|
|
|
@ -67,6 +67,7 @@ static struct ShaderProgram shader_program_pool[CC_MAX_SHADERS];
|
|||
static uint8_t shader_program_pool_size = 0;
|
||||
static uint8_t shader_program_pool_index = 0;
|
||||
static GLuint opengl_vbo;
|
||||
static GLuint opengl_vao;
|
||||
|
||||
static int tex_cache_size = 0;
|
||||
static int num_textures = 0;
|
||||
|
@ -707,6 +708,11 @@ static void gfx_opengl_init(void) {
|
|||
glGenBuffers(1, &opengl_vbo);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, opengl_vbo);
|
||||
|
||||
if (vmajor >= 3 && !is_es) {
|
||||
glGenVertexArrays(1, &opengl_vao);
|
||||
glBindVertexArray(opengl_vao);
|
||||
}
|
||||
|
||||
glDepthFunc(GL_LEQUAL);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
|
|
@ -6,6 +6,10 @@
|
|||
#include <stdbool.h>
|
||||
#include <assert.h>
|
||||
|
||||
#ifdef __SSE__
|
||||
#include <xmmintrin.h>
|
||||
#endif
|
||||
|
||||
#define STB_IMAGE_IMPLEMENTATION
|
||||
#include <stb/stb_image.h>
|
||||
|
||||
|
@ -106,8 +110,8 @@ static struct RSP {
|
|||
float modelview_matrix_stack[11][4][4];
|
||||
uint8_t modelview_matrix_stack_size;
|
||||
|
||||
float MP_matrix[4][4];
|
||||
float P_matrix[4][4];
|
||||
ALIGNED16 float MP_matrix[4][4];
|
||||
ALIGNED16 float P_matrix[4][4];
|
||||
|
||||
Light_t current_lights[MAX_LIGHTS + 1];
|
||||
float current_lights_coeffs[MAX_LIGHTS][3];
|
||||
|
@ -760,19 +764,46 @@ static void gfx_sp_pop_matrix(uint32_t count) {
|
|||
}
|
||||
|
||||
static float gfx_adjust_x_for_aspect_ratio(float x) {
|
||||
return x * (4.0f / 3.0f) / ((float)gfx_current_dimensions.width / (float)gfx_current_dimensions.height);
|
||||
return x * gfx_current_dimensions.x_adjust_ratio;
|
||||
}
|
||||
|
||||
static void OPTIMIZE_O3 gfx_sp_vertex(size_t n_vertices, size_t dest_index, const Vtx *vertices, bool luaVertexColor) {
|
||||
float globalLightCached[2][3];
|
||||
if (rsp.geometry_mode & G_LIGHTING) {
|
||||
for (int i = 0; i < 2; i++) {
|
||||
for (int j = 0; j < 3; j++)
|
||||
globalLightCached[i][j] = gLightingColor[i][j] / 255.0f;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef __SSE__
|
||||
__m128 mat0 = _mm_load_ps(rsp.MP_matrix[0]);
|
||||
__m128 mat1 = _mm_load_ps(rsp.MP_matrix[1]);
|
||||
__m128 mat2 = _mm_load_ps(rsp.MP_matrix[2]);
|
||||
__m128 mat3 = _mm_load_ps(rsp.MP_matrix[3]);
|
||||
#endif
|
||||
|
||||
for (size_t i = 0; i < n_vertices; i++, dest_index++) {
|
||||
const Vtx_t *v = &vertices[i].v;
|
||||
const Vtx_tn *vn = &vertices[i].n;
|
||||
struct LoadedVertex *d = &rsp.loaded_vertices[dest_index];
|
||||
|
||||
#ifdef __SSE__
|
||||
__m128 ob0 = _mm_set1_ps(v->ob[0]);
|
||||
__m128 ob1 = _mm_set1_ps(v->ob[1]);
|
||||
__m128 ob2 = _mm_set1_ps(v->ob[2]);
|
||||
|
||||
__m128 pos = _mm_add_ps(_mm_add_ps(_mm_add_ps(_mm_mul_ps(ob0, mat0), _mm_mul_ps(ob1, mat1)), _mm_mul_ps(ob2, mat2)), mat3);
|
||||
float x = pos[0];
|
||||
float y = pos[1];
|
||||
float z = pos[2];
|
||||
float w = pos[3];
|
||||
#else
|
||||
float x = v->ob[0] * rsp.MP_matrix[0][0] + v->ob[1] * rsp.MP_matrix[1][0] + v->ob[2] * rsp.MP_matrix[2][0] + rsp.MP_matrix[3][0];
|
||||
float y = v->ob[0] * rsp.MP_matrix[0][1] + v->ob[1] * rsp.MP_matrix[1][1] + v->ob[2] * rsp.MP_matrix[2][1] + rsp.MP_matrix[3][1];
|
||||
float z = v->ob[0] * rsp.MP_matrix[0][2] + v->ob[1] * rsp.MP_matrix[1][2] + v->ob[2] * rsp.MP_matrix[2][2] + rsp.MP_matrix[3][2];
|
||||
float w = v->ob[0] * rsp.MP_matrix[0][3] + v->ob[1] * rsp.MP_matrix[1][3] + v->ob[2] * rsp.MP_matrix[2][3] + rsp.MP_matrix[3][3];
|
||||
#endif
|
||||
|
||||
x = gfx_adjust_x_for_aspect_ratio(x);
|
||||
|
||||
|
@ -792,9 +823,9 @@ static void OPTIMIZE_O3 gfx_sp_vertex(size_t n_vertices, size_t dest_index, cons
|
|||
rsp.lights_changed = false;
|
||||
}
|
||||
|
||||
int r = rsp.current_lights[rsp.current_num_lights - 1].col[0] * gLightingColor[1][0] / 255.0f;
|
||||
int g = rsp.current_lights[rsp.current_num_lights - 1].col[1] * gLightingColor[1][1] / 255.0f;
|
||||
int b = rsp.current_lights[rsp.current_num_lights - 1].col[2] * gLightingColor[1][2] / 255.0f;
|
||||
float r = rsp.current_lights[rsp.current_num_lights - 1].col[0] * globalLightCached[1][0];
|
||||
float g = rsp.current_lights[rsp.current_num_lights - 1].col[1] * globalLightCached[1][1];
|
||||
float b = rsp.current_lights[rsp.current_num_lights - 1].col[2] * globalLightCached[1][2];
|
||||
|
||||
for (int32_t i = 0; i < rsp.current_num_lights - 1; i++) {
|
||||
float intensity = 0;
|
||||
|
@ -803,15 +834,15 @@ static void OPTIMIZE_O3 gfx_sp_vertex(size_t n_vertices, size_t dest_index, cons
|
|||
intensity += vn->n[2] * rsp.current_lights_coeffs[i][2];
|
||||
intensity /= 127.0f;
|
||||
if (intensity > 0.0f) {
|
||||
r += intensity * rsp.current_lights[i].col[0] * gLightingColor[0][0] / 255.0f;
|
||||
g += intensity * rsp.current_lights[i].col[1] * gLightingColor[0][1] / 255.0f;
|
||||
b += intensity * rsp.current_lights[i].col[2] * gLightingColor[0][2] / 255.0f;
|
||||
r += intensity * rsp.current_lights[i].col[0] * globalLightCached[0][0];
|
||||
g += intensity * rsp.current_lights[i].col[1] * globalLightCached[0][1];
|
||||
b += intensity * rsp.current_lights[i].col[2] * globalLightCached[0][2];
|
||||
}
|
||||
}
|
||||
|
||||
d->color.r = r > 255 ? 255 : r;
|
||||
d->color.g = g > 255 ? 255 : g;
|
||||
d->color.b = b > 255 ? 255 : b;
|
||||
d->color.r = r > 255.0f ? 255 : (uint8_t)r;
|
||||
d->color.g = g > 255.0f ? 255 : (uint8_t)g;
|
||||
d->color.b = b > 255.0f ? 255 : (uint8_t)b;
|
||||
|
||||
if (rsp.geometry_mode & G_TEXTURE_GEN) {
|
||||
float dotx = 0, doty = 0;
|
||||
|
@ -1823,6 +1854,7 @@ void gfx_start_frame(void) {
|
|||
gfx_current_dimensions.height = 1;
|
||||
}
|
||||
gfx_current_dimensions.aspect_ratio = ((float)gfx_current_dimensions.width / (float)gfx_current_dimensions.height);
|
||||
gfx_current_dimensions.x_adjust_ratio = (4.0f / 3.0f) / gfx_current_dimensions.aspect_ratio;
|
||||
}
|
||||
|
||||
void gfx_run(Gfx *commands) {
|
||||
|
|
|
@ -9,6 +9,7 @@ struct GfxWindowManagerAPI;
|
|||
struct GfxDimensions {
|
||||
uint32_t width, height;
|
||||
float aspect_ratio;
|
||||
float x_adjust_ratio;
|
||||
};
|
||||
|
||||
extern struct GfxDimensions gfx_current_dimensions;
|
||||
|
|
|
@ -211,8 +211,8 @@ static bool gfx_sdl_has_focus(void) {
|
|||
|
||||
static void gfx_sdl_start_text_input(void) { return; }
|
||||
static void gfx_sdl_stop_text_input(void) { return; }
|
||||
static char* gfx_sdl_get_clipboard_text(void) { return NULL; }
|
||||
static void gfx_sdl_set_clipboard_text(char* text) { return; }
|
||||
static char* gfx_sdl_get_clipboard_text(void) { return ""; }
|
||||
static void gfx_sdl_set_clipboard_text(UNUSED const char* text) { return; }
|
||||
static void gfx_sdl_set_cursor_visible(bool visible) { SDL_ShowCursor(visible ? SDL_ENABLE : SDL_DISABLE); }
|
||||
|
||||
struct GfxWindowManagerAPI gfx_sdl = {
|
||||
|
|
|
@ -304,8 +304,19 @@ static bool gfx_sdl_has_focus(void) {
|
|||
|
||||
static void gfx_sdl_start_text_input(void) { SDL_StartTextInput(); }
|
||||
static void gfx_sdl_stop_text_input(void) { SDL_StopTextInput(); }
|
||||
static char* gfx_sdl_get_clipboard_text(void) { return SDL_GetClipboardText(); }
|
||||
static void gfx_sdl_set_clipboard_text(char* text) { SDL_SetClipboardText(text); }
|
||||
|
||||
static char* gfx_sdl_get_clipboard_text(void) {
|
||||
static char clipboard_buf[WAPI_CLIPBOARD_BUFSIZ];
|
||||
|
||||
char* text = SDL_GetClipboardText();
|
||||
strncpy(clipboard_buf, text, WAPI_CLIPBOARD_BUFSIZ - 1);
|
||||
SDL_free(text);
|
||||
|
||||
clipboard_buf[WAPI_CLIPBOARD_BUFSIZ - 1] = '\0';
|
||||
return clipboard_buf;
|
||||
}
|
||||
|
||||
static void gfx_sdl_set_clipboard_text(const char* text) { SDL_SetClipboardText(text); }
|
||||
static void gfx_sdl_set_cursor_visible(bool visible) { SDL_ShowCursor(visible ? SDL_ENABLE : SDL_DISABLE); }
|
||||
|
||||
struct GfxWindowManagerAPI gfx_sdl = {
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
// special value for window position that signifies centered position
|
||||
#define WAPI_WIN_CENTERPOS 0xFFFFFFFF
|
||||
|
||||
#define WAPI_CLIPBOARD_BUFSIZ 1024
|
||||
|
||||
typedef bool (*kb_callback_t)(int code);
|
||||
|
||||
struct GfxWindowManagerAPI {
|
||||
|
@ -23,7 +25,7 @@ struct GfxWindowManagerAPI {
|
|||
void (*start_text_input)(void);
|
||||
void (*stop_text_input)(void);
|
||||
char* (*get_clipboard_text)(void);
|
||||
void (*set_clipboard_text)(char*);
|
||||
void (*set_clipboard_text)(const char*);
|
||||
void (*set_cursor_visible)(bool);
|
||||
void (*delay)(unsigned int ms);
|
||||
int (*get_max_msaa)(void);
|
||||
|
|
|
@ -17,6 +17,7 @@ struct LoadingSegment gCurrLoadingSegment = { "", 0 };
|
|||
struct LoadingScreen {
|
||||
struct DjuiBase base;
|
||||
struct DjuiImage* splashImage;
|
||||
struct DjuiText* splashText;
|
||||
struct DjuiText* loadingDesc;
|
||||
struct DjuiProgressBar *loadingBar;
|
||||
};
|
||||
|
@ -32,6 +33,10 @@ void loading_screen_set_segment_text(const char* text) {
|
|||
snprintf(gCurrLoadingSegment.str, 256, text);
|
||||
}
|
||||
|
||||
void loading_screen_reset_progress_bar(void) {
|
||||
sLoading->loadingBar->smoothValue = 0;
|
||||
}
|
||||
|
||||
static void loading_screen_produce_frame_callback(void) {
|
||||
if (sLoading) { djui_base_render(&sLoading->base); }
|
||||
}
|
||||
|
@ -49,12 +54,19 @@ static bool loading_screen_on_render(struct DjuiBase* base) {
|
|||
windowWidth /= scale;
|
||||
windowHeight /= scale;
|
||||
|
||||
f32 loadingDescY1 = windowHeight * 0.5f + sLoading->splashImage->base.height.value * 0.25f;
|
||||
f32 loadingDescY2 = windowHeight * 0.5f + sLoading->splashImage->base.height.value * 0.55f;
|
||||
f32 loadingDescY1 = windowHeight * 0.5f - sLoading->loadingDesc->base.height.value * 0.5f;
|
||||
f32 loadingDescY2 = windowHeight * 0.5f + sLoading->loadingDesc->base.height.value * 0.5f;
|
||||
|
||||
// fill the screen
|
||||
djui_base_set_size(base, windowWidth, windowHeight);
|
||||
|
||||
// splash logo
|
||||
if (configExCoopTheme) {
|
||||
djui_base_set_location(&sLoading->splashText->base, 0, loadingDescY1 - sLoading->splashText->base.height.value);
|
||||
} else {
|
||||
djui_base_set_location(&sLoading->splashImage->base, 0, loadingDescY1 - sLoading->splashImage->base.height.value);
|
||||
}
|
||||
|
||||
{
|
||||
// loading text description
|
||||
char buffer[256] = "";
|
||||
|
@ -73,7 +85,7 @@ static bool loading_screen_on_render(struct DjuiBase* base) {
|
|||
}
|
||||
|
||||
// loading bar
|
||||
djui_base_set_location(&sLoading->loadingBar->base, windowWidth / 4, loadingDescY2);
|
||||
djui_base_set_location(&sLoading->loadingBar->base, windowWidth / 4, loadingDescY2 + 64);
|
||||
djui_base_set_visible(&sLoading->loadingBar->base, gCurrLoadingSegment.percentage > 0 && strlen(gCurrLoadingSegment.str) > 0);
|
||||
|
||||
djui_base_compute(base);
|
||||
|
@ -95,12 +107,26 @@ static void init_loading_screen(void) {
|
|||
|
||||
djui_base_init(NULL, base, loading_screen_on_render, loading_screen_destroy);
|
||||
|
||||
{
|
||||
// splash image
|
||||
// splash text (easter egg)
|
||||
if (configExCoopTheme) {
|
||||
struct DjuiText* splashDjuiText = djui_text_create(base, "\\#ff0800\\SM\\#1be700\\64\\#00b3ff\\EX\n\\#ffef00\\COOP");
|
||||
djui_base_set_location_type(&splashDjuiText->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
|
||||
djui_base_set_location(&splashDjuiText->base, 0, 0);
|
||||
djui_text_set_font(splashDjuiText, gDjuiFonts[1]);
|
||||
djui_text_set_font_scale(splashDjuiText, gDjuiFonts[1]->defaultFontScale);
|
||||
djui_text_set_alignment(splashDjuiText, DJUI_HALIGN_CENTER, DJUI_VALIGN_CENTER);
|
||||
djui_base_set_size_type(&splashDjuiText->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
|
||||
djui_base_set_size(&splashDjuiText->base, 1.0f, gDjuiFonts[1]->defaultFontScale * 3.0f);
|
||||
|
||||
load->splashText = splashDjuiText;
|
||||
|
||||
// splash image
|
||||
} else {
|
||||
struct DjuiImage* splashImage = djui_image_create(base, texture_coopdx_logo, 2048, 1024, 32);
|
||||
djui_base_set_location_type(&splashImage->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
|
||||
djui_base_set_alignment(&splashImage->base, DJUI_HALIGN_CENTER, DJUI_VALIGN_TOP);
|
||||
djui_base_set_location(&splashImage->base, 0, -100);
|
||||
djui_base_set_alignment(&splashImage->base, DJUI_HALIGN_CENTER, DJUI_VALIGN_CENTER);
|
||||
djui_base_set_size(&splashImage->base, 1024, 512);
|
||||
djui_base_set_size(&splashImage->base, 512, 256);
|
||||
|
||||
load->splashImage = splashImage;
|
||||
}
|
||||
|
@ -112,11 +138,11 @@ static void init_loading_screen(void) {
|
|||
djui_base_set_location(&text->base, 0, 0);
|
||||
|
||||
djui_base_set_size_type(&text->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
|
||||
djui_base_set_size(&text->base, 1.0f, gDjuiFonts[0]->defaultFontScale * 4.5f); // 3 lines
|
||||
djui_base_set_size(&text->base, 1.0f, gDjuiFonts[0]->defaultFontScale * 3.0f);
|
||||
djui_base_set_color(&text->base, 220, 220, 220, 255);
|
||||
djui_text_set_alignment(text, DJUI_HALIGN_CENTER, DJUI_VALIGN_TOP);
|
||||
djui_text_set_font(text, gDjuiFonts[0]);
|
||||
djui_text_set_font_scale(text, gDjuiFonts[0]->defaultFontScale * 1.5f);
|
||||
djui_text_set_font_scale(text, gDjuiFonts[0]->defaultFontScale);
|
||||
|
||||
load->loadingDesc = text;
|
||||
}
|
||||
|
@ -127,7 +153,9 @@ static void init_loading_screen(void) {
|
|||
djui_base_set_location_type(&progressBar->base, DJUI_SVT_ABSOLUTE, DJUI_SVT_ABSOLUTE);
|
||||
djui_base_set_location(&progressBar->base, 0, 0);
|
||||
djui_base_set_visible(&progressBar->base, false);
|
||||
djui_base_set_size(&progressBar->base, 0.5f, 32);
|
||||
progressBar->base.width.value = 0.5;
|
||||
progressBar->smoothenHigh = 0.75f;
|
||||
progressBar->smoothenLow = 0.25f;
|
||||
|
||||
load->loadingBar = progressBar;
|
||||
}
|
||||
|
|
|
@ -32,6 +32,7 @@ extern pthread_mutex_t gLoadingThreadMutex;
|
|||
extern bool gIsThreaded;
|
||||
|
||||
void loading_screen_set_segment_text(const char* text);
|
||||
void loading_screen_reset_progress_bar(void);
|
||||
void render_loading_screen(void);
|
||||
void loading_screen_reset(void);
|
||||
void render_rom_setup_screen(void);
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include "smlua.h"
|
||||
#include "smlua_cobject_map.h"
|
||||
#include "game/hardcoded.h"
|
||||
#include "pc/mods/mods.h"
|
||||
#include "pc/mods/mods_utils.h"
|
||||
|
@ -281,8 +282,7 @@ static void smlua_load_script(struct Mod* mod, struct ModFile* file, u16 remoteI
|
|||
|
||||
void smlua_init(void) {
|
||||
smlua_shutdown();
|
||||
smlua_cobject_allowlist_init();
|
||||
smlua_cpointer_allowlist_init();
|
||||
smlua_pointer_user_data_init();
|
||||
|
||||
gLuaState = luaL_newstate();
|
||||
lua_State* L = gLuaState;
|
||||
|
@ -364,8 +364,7 @@ void smlua_shutdown(void) {
|
|||
smlua_text_utils_reset_all();
|
||||
smlua_audio_utils_reset_all();
|
||||
audio_custom_shutdown();
|
||||
smlua_cobject_allowlist_shutdown();
|
||||
smlua_cpointer_allowlist_shutdown();
|
||||
smlua_pointer_user_data_shutdown();
|
||||
smlua_clear_hooks();
|
||||
smlua_model_util_clear();
|
||||
smlua_level_util_reset();
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
#include "types.h"
|
||||
|
||||
#include "smlua_cobject.h"
|
||||
#include "smlua_cobject_allowlist.h"
|
||||
#include "smlua_cobject_autogen.h"
|
||||
#include "smlua_utils.h"
|
||||
#include "smlua_functions.h"
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "object_fields.h"
|
||||
#include "pc/djui/djui_hud_utils.h"
|
||||
#include "pc/lua/smlua.h"
|
||||
#include "pc/lua/smlua_cobject_map.h"
|
||||
#include "pc/lua/utils/smlua_anim_utils.h"
|
||||
#include "pc/lua/utils/smlua_collision_utils.h"
|
||||
#include "pc/lua/utils/smlua_obj_utils.h"
|
||||
|
@ -381,38 +382,30 @@ struct LuaObjectField* smlua_get_custom_field(lua_State* L, u32 lot, int keyInde
|
|||
|
||||
static int smlua__get_field(lua_State* L) {
|
||||
LUA_STACK_CHECK_BEGIN();
|
||||
if (!smlua_functions_valid_param_count(L, 4)) { return 0; }
|
||||
|
||||
enum LuaObjectType lot = smlua_to_integer(L, 1);
|
||||
if (!gSmLuaConvertSuccess) { return 0; }
|
||||
CObject *cobj = lua_touserdata(L, 1);
|
||||
enum LuaObjectType lot = cobj->lot;
|
||||
u64 pointer = (u64)(intptr_t) cobj->pointer;
|
||||
const char *key = smlua_to_string(L, 2);
|
||||
|
||||
u64 pointer = smlua_to_integer(L, 2);
|
||||
if (!gSmLuaConvertSuccess) { return 0; }
|
||||
|
||||
const char* key = smlua_to_string(L, 3);
|
||||
if (!gSmLuaConvertSuccess) {
|
||||
LOG_LUA_LINE("Tried to get a non-string field of cobject");
|
||||
return 0;
|
||||
// Legacy support
|
||||
if (strcmp(key, "_pointer") == 0) {
|
||||
lua_pushinteger(L, pointer);
|
||||
return 1;
|
||||
}
|
||||
if (strcmp(key, "_lot") == 0) {
|
||||
lua_pushinteger(L, cobj->lot);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (pointer == 0) {
|
||||
LOG_LUA_LINE("_get_field on null pointer");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!smlua_valid_lot(lot)) {
|
||||
LOG_LUA_LINE("_get_field on invalid LOT '%u'", lot);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!smlua_cobject_allowlist_contains(lot, pointer)) {
|
||||
LOG_LUA_LINE("_get_field received a pointer not in allow list. '%u', '%llu", lot, (u64)pointer);
|
||||
if (cobj->freed) {
|
||||
LOG_LUA_LINE("_get_field on freed object");
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct LuaObjectField* data = smlua_get_object_field(lot, key);
|
||||
if (data == NULL) {
|
||||
data = smlua_get_custom_field(L, lot, 3);
|
||||
data = smlua_get_custom_field(L, lot, 2);
|
||||
}
|
||||
if (data == NULL) {
|
||||
LOG_LUA_LINE("_get_field on invalid key '%s', lot '%d'", key, lot);
|
||||
|
@ -470,38 +463,20 @@ static int smlua__get_field(lua_State* L) {
|
|||
|
||||
static int smlua__set_field(lua_State* L) {
|
||||
LUA_STACK_CHECK_BEGIN();
|
||||
if (!smlua_functions_valid_param_count(L, 5)) { return 0; }
|
||||
|
||||
enum LuaObjectType lot = smlua_to_integer(L, 1);
|
||||
if (!gSmLuaConvertSuccess) { return 0; }
|
||||
CObject *cobj = lua_touserdata(L, 1);
|
||||
enum LuaObjectType lot = cobj->lot;
|
||||
u64 pointer = (u64)(intptr_t) cobj->pointer;
|
||||
const char *key = smlua_to_string(L, 2);
|
||||
|
||||
u64 pointer = smlua_to_integer(L, 2);
|
||||
if (!gSmLuaConvertSuccess) { return 0; }
|
||||
|
||||
const char* key = smlua_to_string(L, 3);
|
||||
if (!gSmLuaConvertSuccess) {
|
||||
LOG_LUA_LINE("Tried to set a non-string field of cobject");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (pointer == 0) {
|
||||
LOG_LUA_LINE("_set_field on null pointer");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!smlua_valid_lot(lot)) {
|
||||
LOG_LUA_LINE("_set_field on invalid LOT '%u'", lot);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!smlua_cobject_allowlist_contains(lot, pointer)) {
|
||||
LOG_LUA_LINE("_set_field received a pointer not in allow list. '%u', '%llu", lot, (u64)pointer);
|
||||
if (cobj->freed) {
|
||||
LOG_LUA_LINE("_set_field on freed object");
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct LuaObjectField* data = smlua_get_object_field(lot, key);
|
||||
if (data == NULL) {
|
||||
data = smlua_get_custom_field(L, lot, 3);
|
||||
data = smlua_get_custom_field(L, lot, 2);
|
||||
}
|
||||
|
||||
if (data == NULL) {
|
||||
|
@ -517,18 +492,18 @@ static int smlua__set_field(lua_State* L) {
|
|||
void* valuePointer = NULL;
|
||||
u8* p = ((u8*)(intptr_t)pointer) + data->valueOffset;
|
||||
switch (data->valueType) {
|
||||
case LVT_BOOL:*(u8*) p = smlua_to_boolean(L, 4); break;
|
||||
case LVT_U8: *(u8*) p = smlua_to_integer(L, 4); break;
|
||||
case LVT_U16: *(u16*)p = smlua_to_integer(L, 4); break;
|
||||
case LVT_U32: *(u32*)p = smlua_to_integer(L, 4); break;
|
||||
case LVT_S8: *(s8*) p = smlua_to_integer(L, 4); break;
|
||||
case LVT_S16: *(s16*)p = smlua_to_integer(L, 4); break;
|
||||
case LVT_S32: *(s32*)p = smlua_to_integer(L, 4); break;
|
||||
case LVT_F32: *(f32*)p = smlua_to_number(L, 4); break;
|
||||
case LVT_U64: *(s64*)p = smlua_to_integer(L, 4); break;
|
||||
case LVT_BOOL:*(u8*) p = smlua_to_boolean(L, 3); break;
|
||||
case LVT_U8: *(u8*) p = smlua_to_integer(L, 3); break;
|
||||
case LVT_U16: *(u16*)p = smlua_to_integer(L, 3); break;
|
||||
case LVT_U32: *(u32*)p = smlua_to_integer(L, 3); break;
|
||||
case LVT_S8: *(s8*) p = smlua_to_integer(L, 3); break;
|
||||
case LVT_S16: *(s16*)p = smlua_to_integer(L, 3); break;
|
||||
case LVT_S32: *(s32*)p = smlua_to_integer(L, 3); break;
|
||||
case LVT_F32: *(f32*)p = smlua_to_number(L, 3); break;
|
||||
case LVT_U64: *(s64*)p = smlua_to_integer(L, 3); break;
|
||||
|
||||
case LVT_COBJECT_P:
|
||||
valuePointer = smlua_to_cobject(L, 4, data->lot);
|
||||
valuePointer = smlua_to_cobject(L, 3, data->lot);
|
||||
if (gSmLuaConvertSuccess) {
|
||||
*(u8**)p = valuePointer;
|
||||
}
|
||||
|
@ -548,7 +523,7 @@ static int smlua__set_field(lua_State* L) {
|
|||
case LVT_OBJECTANIMPOINTER_P:
|
||||
case LVT_COLLISION_P:
|
||||
case LVT_TRAJECTORY_P:
|
||||
valuePointer = smlua_to_cpointer(L, 4, data->valueType);
|
||||
valuePointer = smlua_to_cpointer(L, 3, data->valueType);
|
||||
if (gSmLuaConvertSuccess) {
|
||||
*(u8**)p = valuePointer;
|
||||
}
|
||||
|
@ -567,6 +542,43 @@ static int smlua__set_field(lua_State* L) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
int smlua__eq(lua_State *L) {
|
||||
CObject *a = lua_touserdata(L, 1);
|
||||
CObject *b = lua_touserdata(L, 2);
|
||||
lua_pushboolean(L, a->lot == b->lot && a->pointer == b->pointer);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int smlua__gc(lua_State *L) {
|
||||
CObject *cobj = lua_touserdata(L, 1);
|
||||
if (!cobj->freed) {
|
||||
switch (cobj->lot) {
|
||||
case LOT_SURFACE: {
|
||||
smlua_pointer_user_data_delete((uintptr_t) cobj->pointer);
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int smlua_cpointer_get(lua_State* L) {
|
||||
CPointer *cptr = lua_touserdata(L, 1);
|
||||
const char *key = smlua_to_string(L, 2);
|
||||
|
||||
// Legacy support
|
||||
if (strcmp(key, "_pointer") == 0) {
|
||||
lua_pushinteger(L, (u64)(intptr_t) cptr->pointer);
|
||||
return 1;
|
||||
}
|
||||
if (strcmp(key, "_lot") == 0) {
|
||||
lua_pushinteger(L, cptr->lvt);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int smlua_cpointer_set(UNUSED lua_State* L) { return 0; }
|
||||
|
||||
//////////
|
||||
// bind //
|
||||
//////////
|
||||
|
@ -574,6 +586,27 @@ static int smlua__set_field(lua_State* L) {
|
|||
void smlua_cobject_init_globals(void) {
|
||||
lua_State* L = gLuaState;
|
||||
|
||||
// Create metatables
|
||||
luaL_newmetatable(L, "CObject");
|
||||
luaL_Reg cObjectMethods[] = {
|
||||
{ "__index", smlua__get_field },
|
||||
{ "__newindex", smlua__set_field },
|
||||
{ "__eq", smlua__eq },
|
||||
{ "__gc", smlua__gc },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
luaL_setfuncs(L, cObjectMethods, 0);
|
||||
lua_pop(L, 1);
|
||||
luaL_newmetatable(L, "CPointer");
|
||||
luaL_Reg cPointerMethods[] = {
|
||||
{ "__index", smlua_cpointer_get },
|
||||
{ "__newindex", smlua_cpointer_set },
|
||||
{ "__eq", smlua__eq },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
luaL_setfuncs(L, cPointerMethods, 0);
|
||||
lua_pop(L, 1);
|
||||
|
||||
#define EXPOSE_GLOBAL_ARRAY(lot, ptr, iterator) \
|
||||
{ \
|
||||
lua_newtable(L); \
|
||||
|
@ -662,8 +695,4 @@ void smlua_bind_cobject(void) {
|
|||
lua_State* L = gLuaState;
|
||||
|
||||
smlua_bind_function(L, "define_custom_obj_fields", smlua_func_define_custom_obj_fields);
|
||||
|
||||
smlua_bind_function(L, "_get_field", smlua__get_field);
|
||||
smlua_bind_function(L, "_set_field", smlua__set_field);
|
||||
|
||||
}
|
||||
|
|
|
@ -65,6 +65,18 @@ struct LuaObjectTable {
|
|||
u16 fieldCount;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
void *pointer;
|
||||
u16 lot;
|
||||
bool freed;
|
||||
} CObject;
|
||||
|
||||
typedef struct {
|
||||
void *pointer;
|
||||
u16 lvt;
|
||||
bool freed;
|
||||
} CPointer;
|
||||
|
||||
bool smlua_valid_lot(u16 lot);
|
||||
bool smlua_valid_lvt(u16 lvt);
|
||||
struct LuaObjectField* smlua_get_object_field_from_ot(struct LuaObjectTable* ot, const char* key);
|
||||
|
|
|
@ -1,102 +0,0 @@
|
|||
#include <stdio.h>
|
||||
#include "smlua.h"
|
||||
#include "data/dynos_cmap.cpp.h"
|
||||
|
||||
#define LOT_COUNT (LOT_MAX + (LOT_AUTOGEN_MAX - LOT_AUTOGEN_MIN))
|
||||
static void* sObjectAllowList[LOT_COUNT] = { NULL };
|
||||
static u64 sCachedObjectAllowed[LOT_COUNT] = { 0 };
|
||||
|
||||
static u16 smlua_lot_mapping(u16 lot) {
|
||||
if (lot >= LOT_MAX) {
|
||||
return LOT_MAX + (lot - LOT_AUTOGEN_MIN);
|
||||
} else {
|
||||
return lot;
|
||||
}
|
||||
}
|
||||
|
||||
void smlua_cobject_allowlist_init(void) {
|
||||
smlua_cobject_allowlist_shutdown();
|
||||
}
|
||||
|
||||
void smlua_cobject_allowlist_shutdown(void) {
|
||||
for (s32 i = 0; i < LOT_COUNT; i++) {
|
||||
sCachedObjectAllowed[i] = 0;
|
||||
|
||||
if (sObjectAllowList[i]) {
|
||||
hmap_clear(sObjectAllowList[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void smlua_cobject_allowlist_add(u16 lot, u64 pointer) {
|
||||
if (pointer == 0) { return; }
|
||||
if (!smlua_valid_lot(lot)) { return; }
|
||||
|
||||
u16 m = smlua_lot_mapping(lot);
|
||||
if (sCachedObjectAllowed[m] == pointer) { return; }
|
||||
sCachedObjectAllowed[m] = pointer;
|
||||
|
||||
if (!sObjectAllowList[m]) {
|
||||
sObjectAllowList[m] = hmap_create();
|
||||
}
|
||||
|
||||
if (!hmap_get(sObjectAllowList[m], pointer)) {
|
||||
hmap_put(sObjectAllowList[m], pointer, (void*)1);
|
||||
}
|
||||
}
|
||||
|
||||
bool smlua_cobject_allowlist_contains(u16 lot, u64 pointer) {
|
||||
if (pointer == 0) { return false; }
|
||||
if (!smlua_valid_lot(lot)) { return false; }
|
||||
|
||||
u16 m = smlua_lot_mapping(lot);
|
||||
if (sCachedObjectAllowed[m] == pointer) { return true; }
|
||||
|
||||
if (!sObjectAllowList[m]) { return false; }
|
||||
return hmap_get(sObjectAllowList[m], pointer) != 0;
|
||||
}
|
||||
|
||||
/////////////////////////////
|
||||
|
||||
static void* sPointerAllowList[LVT_MAX] = { 0 };
|
||||
static u64 sCachedPointerAllowed[LVT_MAX] = { 0 };
|
||||
|
||||
void smlua_cpointer_allowlist_init(void) {
|
||||
smlua_cpointer_allowlist_shutdown();
|
||||
}
|
||||
|
||||
void smlua_cpointer_allowlist_shutdown(void) {
|
||||
for (s32 i = 0; i < LVT_MAX; i++) {
|
||||
sCachedPointerAllowed[i] = 0;
|
||||
|
||||
if (sPointerAllowList[i]) {
|
||||
hmap_clear(sPointerAllowList[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void smlua_cpointer_allowlist_add(u16 lvt, u64 pointer) {
|
||||
if (pointer == 0) { return; }
|
||||
if (!smlua_valid_lvt(lvt)) { return; }
|
||||
|
||||
if (sCachedPointerAllowed[lvt] == pointer) { return; }
|
||||
sCachedPointerAllowed[lvt] = pointer;
|
||||
|
||||
if (!sPointerAllowList[lvt]) {
|
||||
sPointerAllowList[lvt] = hmap_create();
|
||||
}
|
||||
|
||||
if (!hmap_get(sPointerAllowList[lvt], pointer)) {
|
||||
hmap_put(sPointerAllowList[lvt], pointer, (void*)1);
|
||||
}
|
||||
}
|
||||
|
||||
bool smlua_cpointer_allowlist_contains(u16 lvt, u64 pointer) {
|
||||
if (pointer == 0) { return false; }
|
||||
if (!smlua_valid_lvt(lvt)) { return false; }
|
||||
|
||||
if (sCachedPointerAllowed[lvt] == pointer) { return true; }
|
||||
|
||||
if (!sPointerAllowList[lvt]) { return false; }
|
||||
return hmap_get(sPointerAllowList[lvt], pointer) != 0;
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue