mirror of
https://github.com/HarbourMasters/Starship.git
synced 2025-04-28 12:27:59 +03:00
Added error handling, merged script, added errors and implemented MessageFactory on xml
This commit is contained in:
parent
40e6d6b788
commit
c103d0974a
14 changed files with 884 additions and 924 deletions
448
example/.vscode/api_definitions.v1.lua
vendored
448
example/.vscode/api_definitions.v1.lua
vendored
|
@ -1,8 +1,8 @@
|
|||
|
||||
Game = {}
|
||||
Assets = {}
|
||||
UIWidgets = {}
|
||||
Events = {}
|
||||
|
||||
---@alias ListenerID number
|
||||
---@class Asset
|
||||
local Asset = {}
|
||||
|
@ -715,6 +715,7 @@ LaserStrength = {
|
|||
}
|
||||
|
||||
---@class PlayerShot
|
||||
PlayerShot = {}
|
||||
---@field obj Object
|
||||
---@field index number
|
||||
---@field vel Vec3f
|
||||
|
@ -731,9 +732,9 @@ LaserStrength = {
|
|||
---@field timer number
|
||||
---@field sourceId number
|
||||
---@field bonus number
|
||||
PlayerShot = {}
|
||||
|
||||
---@class ArwingInfo
|
||||
ArwingInfo = {}
|
||||
---@field rightWingState number
|
||||
---@field leftWingState number
|
||||
---@field upperRightFlapYrot number
|
||||
|
@ -750,9 +751,9 @@ PlayerShot = {}
|
|||
---@field teamFaceXrot number
|
||||
---@field teamFaceYrot number
|
||||
---@field cockpitGlassXrot number
|
||||
ArwingInfo = {}
|
||||
|
||||
---@class PlayerSfx
|
||||
PlayerSfx = {}
|
||||
---@field levelType number
|
||||
---@field form number
|
||||
---@field srcPos number
|
||||
|
@ -763,9 +764,9 @@ ArwingInfo = {}
|
|||
---@field bank number
|
||||
---@field zRot number
|
||||
---@field roll number
|
||||
PlayerSfx = {}
|
||||
|
||||
---@class Player
|
||||
Player = {}
|
||||
---@field unk_000 number
|
||||
---@field unk_004 number
|
||||
---@field unk_008 number
|
||||
|
@ -925,7 +926,6 @@ PlayerSfx = {}
|
|||
---@field arwing ArwingInfo
|
||||
---@field aerobaticPitch number
|
||||
---@field somersault boolean
|
||||
Player = {}
|
||||
|
||||
---@return number
|
||||
function Game.D_AQ_801C4188() end
|
||||
|
@ -1704,64 +1704,68 @@ Assets.sBoostGaugeArrow7 = "__OTR__assets/textures/hud/sBoostGaugeArrow7"
|
|||
---@type Asset
|
||||
Assets.sBoostGaugeArrow8 = "__OTR__assets/textures/hud/sBoostGaugeArrow8"
|
||||
---@class Vec3f
|
||||
Vec3f = {}
|
||||
---@field x number
|
||||
---@field y number
|
||||
---@field z number
|
||||
Vec3f = {}
|
||||
---@return Vec3f
|
||||
function Vec3f:asRef() end
|
||||
---@return f32
|
||||
---@return number
|
||||
function Vec3f:xRef() end
|
||||
---@return f32
|
||||
---@return number
|
||||
function Vec3f:yRef() end
|
||||
---@return f32
|
||||
---@return number
|
||||
function Vec3f:zRef() end
|
||||
---@return number
|
||||
function Vec3f:asArray() end
|
||||
|
||||
---@class Vec3s
|
||||
Vec3s = {}
|
||||
---@field x number
|
||||
---@field y number
|
||||
---@field z number
|
||||
Vec3s = {}
|
||||
---@return Vec3s
|
||||
function Vec3s:asRef() end
|
||||
---@return f32
|
||||
---@return number
|
||||
function Vec3s:xRef() end
|
||||
---@return f32
|
||||
---@return number
|
||||
function Vec3s:yRef() end
|
||||
---@return f32
|
||||
---@return number
|
||||
function Vec3s:zRef() end
|
||||
---@return number
|
||||
function Vec3s:asArray() end
|
||||
|
||||
---@class PosRot
|
||||
PosRot = {}
|
||||
---@field pos Vec3f
|
||||
---@field rot Vec3f
|
||||
PosRot = {}
|
||||
---@return PosRot
|
||||
function PosRot:asRef() end
|
||||
|
||||
---@class CameraPoint
|
||||
CameraPoint = {}
|
||||
---@field eye Vec3f
|
||||
---@field at Vec3f
|
||||
CameraPoint = {}
|
||||
---@return CameraPoint
|
||||
---@return CameraPonumber
|
||||
function CameraPoint:asRef() end
|
||||
|
||||
---@class Triangle
|
||||
---@field vtx number
|
||||
Triangle = {}
|
||||
---@field vtx number
|
||||
---@return Triangle
|
||||
function Triangle:asRef() end
|
||||
|
||||
---@class PlaneF
|
||||
PlaneF = {}
|
||||
---@field normal Vec3f
|
||||
---@field dist number
|
||||
PlaneF = {}
|
||||
---@return PlaneF
|
||||
function PlaneF:asRef() end
|
||||
|
||||
---@class PlaneI
|
||||
PlaneI = {}
|
||||
---@field normal Vec3s
|
||||
---@field dist number
|
||||
PlaneI = {}
|
||||
---@return PlaneI
|
||||
function PlaneI:asRef() end
|
||||
|
||||
|
@ -2655,6 +2659,7 @@ ScreenSize = {
|
|||
}
|
||||
|
||||
---@class OSContPad
|
||||
OSContPad = {}
|
||||
---@field button number
|
||||
---@field stick_x number
|
||||
---@field stick_y number
|
||||
|
@ -2663,19 +2668,18 @@ ScreenSize = {
|
|||
---@field gyro_y number
|
||||
---@field right_stick_x number
|
||||
---@field right_stick_y number
|
||||
OSContPad = {}
|
||||
|
||||
---@class ImVec2
|
||||
ImVec2 = {}
|
||||
---@field x number
|
||||
---@field y number
|
||||
ImVec2 = {}
|
||||
|
||||
---@class ImVec4
|
||||
ImVec4 = {}
|
||||
---@field x number
|
||||
---@field y number
|
||||
---@field z number
|
||||
---@field w number
|
||||
ImVec4 = {}
|
||||
|
||||
---@enum RadioCharacterId
|
||||
RadioCharacterId = {
|
||||
|
@ -4192,6 +4196,7 @@ GroundSurface = {
|
|||
}
|
||||
|
||||
---@class Environment
|
||||
Environment = {}
|
||||
---@field type number
|
||||
---@field unk04 number
|
||||
---@field bgColor number
|
||||
|
@ -4208,7 +4213,6 @@ GroundSurface = {
|
|||
---@field ambR number
|
||||
---@field ambG number
|
||||
---@field ambB number
|
||||
Environment = {}
|
||||
|
||||
---@enum SfxBankId
|
||||
SfxBankId = {
|
||||
|
@ -4843,19 +4847,19 @@ SetupDL = {
|
|||
}
|
||||
|
||||
---@class Color_RGBA32
|
||||
Color_RGBA32 = {}
|
||||
---@field r number
|
||||
---@field g number
|
||||
---@field b number
|
||||
---@field a number
|
||||
Color_RGBA32 = {}
|
||||
|
||||
---@class Limb
|
||||
Limb = {}
|
||||
---@field dList Gfx
|
||||
---@field trans Vec3f
|
||||
---@field rot Vec3s
|
||||
---@field sibling Limb
|
||||
---@field child Limb
|
||||
Limb = {}
|
||||
|
||||
---@param _void nil
|
||||
---@return nil
|
||||
|
@ -5441,21 +5445,57 @@ function Game.D_80178580(index) end
|
|||
---@param index number
|
||||
---@param value number
|
||||
function Game.D_80178580(index, value) end
|
||||
---@class PlanetStats
|
||||
PlanetStats = {}
|
||||
---@return number
|
||||
function PlanetStats:hitCount() end
|
||||
---@param value number
|
||||
---@return number
|
||||
function PlanetStats:hitCount(value) end
|
||||
---@return number
|
||||
function PlanetStats:planetId() end
|
||||
---@param value number
|
||||
---@return number
|
||||
function PlanetStats:planetId(value) end
|
||||
---@return number
|
||||
function PlanetStats:hitCountOver256() end
|
||||
---@param value number
|
||||
---@return number
|
||||
function PlanetStats:hitCountOver256(value) end
|
||||
---@return number
|
||||
function PlanetStats:peppyAlive() end
|
||||
---@param value number
|
||||
---@return number
|
||||
function PlanetStats:peppyAlive(value) end
|
||||
---@return number
|
||||
function PlanetStats:falcoAlive() end
|
||||
---@param value number
|
||||
---@return number
|
||||
function PlanetStats:falcoAlive(value) end
|
||||
---@return number
|
||||
function PlanetStats:slippyAlive() end
|
||||
---@param value number
|
||||
---@return number
|
||||
function PlanetStats:slippyAlive(value) end
|
||||
|
||||
---@class SaveData
|
||||
SaveData = {}
|
||||
---@field planet PlanetData
|
||||
---@field pad10 string
|
||||
---@field soundMode number
|
||||
---@field musicVolume number
|
||||
---@field voiceVolume number
|
||||
---@field sfxVolume number
|
||||
---@field rankingRoute current
|
||||
---@field rankingLives current
|
||||
---@field rankingMedal current
|
||||
---@field rankingRoute number
|
||||
---@field rankingLives number
|
||||
---@field rankingMedal number
|
||||
---@field unk_EA number
|
||||
---@field textLanguage number
|
||||
---@field voiceLanguage number
|
||||
---@field padEE string
|
||||
SaveData = {}
|
||||
---@return PlanetStats[]
|
||||
---@param route number
|
||||
function SaveData:GetPlanetStats(route) end
|
||||
|
||||
---@param _void nil
|
||||
---@return number
|
||||
|
@ -10363,11 +10403,11 @@ ActorCutsceneModels = {
|
|||
}
|
||||
|
||||
---@class Object
|
||||
Object = {}
|
||||
---@field status number
|
||||
---@field id number
|
||||
---@field pos Vec3f
|
||||
---@field rot Vec3f
|
||||
Object = {}
|
||||
---@return Actor
|
||||
function Object:asActor() end
|
||||
---@return Boss
|
||||
|
@ -10386,6 +10426,7 @@ function Object:asEffect() end
|
|||
function Object:asRef() end
|
||||
|
||||
---@class ObjectInfo
|
||||
ObjectInfo = {}
|
||||
---@field draw ObjectFunc
|
||||
---@field dList Gfx
|
||||
---@field drawType number
|
||||
|
@ -10398,22 +10439,22 @@ function Object:asRef() end
|
|||
---@field unk_19 number
|
||||
---@field targetOffset number
|
||||
---@field bonus number
|
||||
ObjectInfo = {}
|
||||
---@return ObjectInfo
|
||||
function ObjectInfo:asRef() end
|
||||
|
||||
---@class Scenery360
|
||||
Scenery360 = {}
|
||||
---@field obj Object
|
||||
---@field info ObjectInfo
|
||||
---@field pathIndex number
|
||||
---@field unk_41 string
|
||||
---@field sfxSource number
|
||||
---@field unk_54 number
|
||||
Scenery360 = {}
|
||||
---@return Scenery360
|
||||
function Scenery360:asRef() end
|
||||
|
||||
---@class Scenery
|
||||
Scenery = {}
|
||||
---@field obj Object
|
||||
---@field info ObjectInfo
|
||||
---@field index number
|
||||
|
@ -10426,11 +10467,11 @@ function Scenery360:asRef() end
|
|||
---@field vel Vec3f
|
||||
---@field sfxSource number
|
||||
---@field pad7C string
|
||||
Scenery = {}
|
||||
---@return Scenery
|
||||
function Scenery:asRef() end
|
||||
|
||||
---@class Sprite
|
||||
Sprite = {}
|
||||
---@field obj Object
|
||||
---@field info ObjectInfo
|
||||
---@field index number
|
||||
|
@ -10438,11 +10479,11 @@ function Scenery:asRef() end
|
|||
---@field sceneryId number
|
||||
---@field destroy number
|
||||
---@field toLeft number
|
||||
Sprite = {}
|
||||
---@return Sprite
|
||||
function Sprite:asRef() end
|
||||
|
||||
---@class Item
|
||||
Item = {}
|
||||
---@field obj Object
|
||||
---@field info ObjectInfo
|
||||
---@field index number
|
||||
|
@ -10457,11 +10498,11 @@ function Sprite:asRef() end
|
|||
---@field unk_58 number
|
||||
---@field sfxSource number
|
||||
---@field width number
|
||||
Item = {}
|
||||
---@return Item
|
||||
function Item:asRef() end
|
||||
|
||||
---@class Effect
|
||||
Effect = {}
|
||||
---@field obj Object
|
||||
---@field info ObjectInfo
|
||||
---@field index number
|
||||
|
@ -10482,11 +10523,11 @@ function Item:asRef() end
|
|||
---@field unk_7A number
|
||||
---@field pad7C string
|
||||
---@field sfxSource number
|
||||
Effect = {}
|
||||
---@return Effect
|
||||
function Effect:asRef() end
|
||||
|
||||
---@class Boss
|
||||
Boss = {}
|
||||
---@field obj Object
|
||||
---@field info ObjectInfo
|
||||
---@field index number
|
||||
|
@ -10517,11 +10558,11 @@ function Effect:asRef() end
|
|||
---@field vwork Vec3f
|
||||
---@field scale number
|
||||
---@field sfxSource number
|
||||
Boss = {}
|
||||
---@return Boss
|
||||
function Boss:asRef() end
|
||||
|
||||
---@class Actor
|
||||
Actor = {}
|
||||
---@field obj Object
|
||||
---@field info ObjectInfo
|
||||
---@field index number
|
||||
|
@ -10560,7 +10601,6 @@ function Boss:asRef() end
|
|||
---@field scale number
|
||||
---@field fwork number
|
||||
---@field vwork Vec3f
|
||||
Actor = {}
|
||||
---@return Actor
|
||||
function Actor:asRef() end
|
||||
|
||||
|
@ -28318,14 +28358,17 @@ EventPriority = {
|
|||
}
|
||||
|
||||
---@class IEvent
|
||||
---@field cancelled boolean
|
||||
IEvent = {}
|
||||
---@field cancelled boolean
|
||||
|
||||
---@class EventListener
|
||||
EventListener = {}
|
||||
---@field priority EventPriority
|
||||
---@field function SmartFunctionCallback
|
||||
EventListener = {}
|
||||
|
||||
---@param _name string
|
||||
---@return std::shared_ptr<Ship::CVar>
|
||||
function CVarGet(_name) end
|
||||
---@param _name string
|
||||
---@param defaultValue number
|
||||
---@return number
|
||||
|
@ -28336,7 +28379,7 @@ function CVarGetInteger(_name, defaultValue) end
|
|||
function CVarGetFloat(_name, defaultValue) end
|
||||
---@param _name string
|
||||
---@param defaultValue string
|
||||
---@return number
|
||||
---@return
|
||||
function CVarGetString(_name, defaultValue) end
|
||||
---@param _name string
|
||||
---@param defaultValue Color_RGBA8
|
||||
|
@ -28524,6 +28567,25 @@ function UIWidgets.EnhancementCheckbox(_text, cvarName, disabled, disabledToolti
|
|||
---@param defaultValue boolean
|
||||
---@return boolean
|
||||
function UIWidgets.PaddedEnhancementCheckbox(_text, cvarName, padTop, padBottom, disabled, disabledTooltipText, disabledGraphic, defaultValue) end
|
||||
---@param _cvarName string
|
||||
---@param _std::span<char any
|
||||
---@param comboArray std::dynamic_extent>
|
||||
---@param defaultIndex number
|
||||
---@param disabled boolean
|
||||
---@param disabledTooltipText string
|
||||
---@param disabledValue number
|
||||
---@return boolean
|
||||
function UIWidgets.EnhancementCombobox(_cvarName, _std::span<char, comboArray, defaultIndex, disabled, disabledTooltipText, disabledValue) end
|
||||
---@param _label string
|
||||
---@param cvarName string
|
||||
---@param _std::span<char any
|
||||
---@param comboArray std::dynamic_extent>
|
||||
---@param defaultIndex number
|
||||
---@param disabled boolean
|
||||
---@param disabledTooltipText string
|
||||
---@param disabledValue number
|
||||
---@return boolean
|
||||
function UIWidgets.LabeledRightAlignedEnhancementCombobox(_label, cvarName, _std::span<char, comboArray, defaultIndex, disabled, disabledTooltipText, disabledValue) end
|
||||
---@param _text string
|
||||
---@param padTop boolean
|
||||
---@param padBottom boolean
|
||||
|
@ -28641,6 +28703,12 @@ function UIWidgets.PopStyleButton(_) end
|
|||
---@param options ButtonOptions
|
||||
---@return boolean
|
||||
function UIWidgets.Button(_label, options) end
|
||||
---@param _label string
|
||||
---@param cvarName string
|
||||
---@param windowPtr std::shared_ptr<Ship::GuiWindow>
|
||||
---@param options ButtonOptions
|
||||
---@return boolean
|
||||
function UIWidgets.WindowButton(_label, cvarName, windowPtr, options) end
|
||||
---@param _tooltip string
|
||||
---@return CheckboxOptions
|
||||
function UIWidgets.DefaultCheckboxOptions(_tooltip) end
|
||||
|
@ -28666,6 +28734,20 @@ function UIWidgets.PushStyleCombobox(arg0) end
|
|||
---@param _ any
|
||||
---@return nil
|
||||
function UIWidgets.PopStyleCombobox(_) end
|
||||
---@param _label string
|
||||
---@param value number
|
||||
---@param _std::span<char any
|
||||
---@param comboArray std::dynamic_extent>
|
||||
---@param options ComboboxOptions
|
||||
---@return boolean
|
||||
function UIWidgets.Combobox(_label, value, _std::span<char, comboArray, options) end
|
||||
---@param _label string
|
||||
---@param cvarName string
|
||||
---@param _std::span<char any
|
||||
---@param comboArray std::dynamic_extent>
|
||||
---@param options ComboboxOptions
|
||||
---@return boolean
|
||||
function UIWidgets.CVarCombobox(_label, cvarName, _std::span<char, comboArray, options) end
|
||||
---@param arg0 color
|
||||
---@return nil
|
||||
function UIWidgets.PushStyleSlider(arg0) end
|
||||
|
@ -28706,7 +28788,7 @@ function UIWidgets.CVarSliderFloat(_label, cvarName, min, max, defaultValue, opt
|
|||
---@return number
|
||||
function ResourceGetCrcByName(_name) end
|
||||
---@param _crc number
|
||||
---@return number
|
||||
---@return
|
||||
function ResourceGetNameByCrc(_crc) end
|
||||
---@param _name string
|
||||
---@return number
|
||||
|
@ -28773,187 +28855,183 @@ function ResourceHasGameVersion(_hash) end
|
|||
---@param _ any
|
||||
---@return number
|
||||
function IsResourceManagerLoaded(_) end
|
||||
---@class ItemDropEvent
|
||||
---@field event IEvent
|
||||
---@field item Item
|
||||
lua.new_usertype<ItemDropEvent>("ItemDropEvent",
|
||||
"event", sol::property(&ItemDropEvent::event, &ItemDropEvent::event),
|
||||
"item", sol::property(&ItemDropEvent::item, &ItemDropEvent::item)
|
||||
);
|
||||
|
||||
lua.new_usertype<PlayerActionBoostEvent>("PlayerActionBoostEvent",
|
||||
"event", sol::property(&PlayerActionBoostEvent::event, &PlayerActionBoostEvent::event),
|
||||
"player", sol::property(&PlayerActionBoostEvent::player, &PlayerActionBoostEvent::player)
|
||||
);
|
||||
|
||||
---@class PlayerActionBoostEvent
|
||||
---@field event IEvent
|
||||
---@field player Player
|
||||
lua.new_usertype<PlayerActionBrakeEvent>("PlayerActionBrakeEvent",
|
||||
"event", sol::property(&PlayerActionBrakeEvent::event, &PlayerActionBrakeEvent::event),
|
||||
"player", sol::property(&PlayerActionBrakeEvent::player, &PlayerActionBrakeEvent::player)
|
||||
);
|
||||
|
||||
---@class PlayerActionBrakeEvent
|
||||
---@field event IEvent
|
||||
---@field player Player
|
||||
lua.new_usertype<PlayerActionPreShootEvent>("PlayerActionPreShootEvent",
|
||||
"event", sol::property(&PlayerActionPreShootEvent::event, &PlayerActionPreShootEvent::event),
|
||||
"player", sol::property(&PlayerActionPreShootEvent::player, &PlayerActionPreShootEvent::player),
|
||||
"laser", sol::property(&PlayerActionPreShootEvent::laser, &PlayerActionPreShootEvent::laser)
|
||||
);
|
||||
|
||||
---@class PlayerActionPreShootEvent
|
||||
---@field event IEvent
|
||||
---@field player Player
|
||||
---@field laser LaserStrength
|
||||
lua.new_usertype<PlayerActionPostShootEvent>("PlayerActionPostShootEvent",
|
||||
"event", sol::property(&PlayerActionPostShootEvent::event, &PlayerActionPostShootEvent::event),
|
||||
"player", sol::property(&PlayerActionPostShootEvent::player, &PlayerActionPostShootEvent::player),
|
||||
"shot", sol::property(&PlayerActionPostShootEvent::shot, &PlayerActionPostShootEvent::shot)
|
||||
);
|
||||
|
||||
---@class PlayerActionPostShootEvent
|
||||
---@field event IEvent
|
||||
---@field player Player
|
||||
---@field shot PlayerShot
|
||||
lua.new_usertype<PlayerActionPreShootChargedEvent>("PlayerActionPreShootChargedEvent",
|
||||
"event", sol::property(&PlayerActionPreShootChargedEvent::event, &PlayerActionPreShootChargedEvent::event),
|
||||
"player", sol::property(&PlayerActionPreShootChargedEvent::player, &PlayerActionPreShootChargedEvent::player)
|
||||
);
|
||||
|
||||
---@class PlayerActionPreShootChargedEvent
|
||||
---@field event IEvent
|
||||
---@field player Player
|
||||
lua.new_usertype<PlayerActionPostShootChargedEvent>("PlayerActionPostShootChargedEvent",
|
||||
"event", sol::property(&PlayerActionPostShootChargedEvent::event, &PlayerActionPostShootChargedEvent::event),
|
||||
"player", sol::property(&PlayerActionPostShootChargedEvent::player, &PlayerActionPostShootChargedEvent::player)
|
||||
);
|
||||
|
||||
---@class PlayerActionPostShootChargedEvent
|
||||
---@field event IEvent
|
||||
---@field player Player
|
||||
lua.new_usertype<PlayerActionPreBombEvent>("PlayerActionPreBombEvent",
|
||||
"event", sol::property(&PlayerActionPreBombEvent::event, &PlayerActionPreBombEvent::event),
|
||||
"player", sol::property(&PlayerActionPreBombEvent::player, &PlayerActionPreBombEvent::player)
|
||||
);
|
||||
|
||||
---@class PlayerActionPreBombEvent
|
||||
---@field event IEvent
|
||||
---@field player Player
|
||||
lua.new_usertype<PlayerActionPostBombEvent>("PlayerActionPostBombEvent",
|
||||
"event", sol::property(&PlayerActionPostBombEvent::event, &PlayerActionPostBombEvent::event),
|
||||
"player", sol::property(&PlayerActionPostBombEvent::player, &PlayerActionPostBombEvent::player)
|
||||
);
|
||||
|
||||
---@class PlayerActionPostBombEvent
|
||||
---@field event IEvent
|
||||
---@field player Player
|
||||
lua.new_usertype<EngineInitEvent>("EngineInitEvent",
|
||||
"event", sol::property(&EngineInitEvent::event, &EngineInitEvent::event)
|
||||
);
|
||||
|
||||
lua.new_usertype<EngineExitEvent>("EngineExitEvent",
|
||||
"event", sol::property(&EngineExitEvent::event, &EngineExitEvent::event)
|
||||
);
|
||||
|
||||
---@class EngineInitEvent
|
||||
---@field event IEvent
|
||||
lua.new_usertype<EngineRenderMenubarEvent>("EngineRenderMenubarEvent",
|
||||
"event", sol::property(&EngineRenderMenubarEvent::event, &EngineRenderMenubarEvent::event)
|
||||
);
|
||||
|
||||
---@class EngineExitEvent
|
||||
---@field event IEvent
|
||||
lua.new_usertype<DisplayPreUpdateEvent>("DisplayPreUpdateEvent",
|
||||
"event", sol::property(&DisplayPreUpdateEvent::event, &DisplayPreUpdateEvent::event)
|
||||
);
|
||||
|
||||
---@class EngineRenderMenubarEvent
|
||||
---@field event IEvent
|
||||
lua.new_usertype<DisplayPostUpdateEvent>("DisplayPostUpdateEvent",
|
||||
"event", sol::property(&DisplayPostUpdateEvent::event, &DisplayPostUpdateEvent::event)
|
||||
);
|
||||
|
||||
---@class DisplayPreUpdateEvent
|
||||
---@field event IEvent
|
||||
lua.new_usertype<GamePreUpdateEvent>("GamePreUpdateEvent",
|
||||
"event", sol::property(&GamePreUpdateEvent::event, &GamePreUpdateEvent::event)
|
||||
);
|
||||
|
||||
---@class DisplayPostUpdateEvent
|
||||
---@field event IEvent
|
||||
lua.new_usertype<GamePostUpdateEvent>("GamePostUpdateEvent",
|
||||
"event", sol::property(&GamePostUpdateEvent::event, &GamePostUpdateEvent::event)
|
||||
);
|
||||
|
||||
---@class GamePreUpdateEvent
|
||||
---@field event IEvent
|
||||
lua.new_usertype<PlayUpdateEvent>("PlayUpdateEvent",
|
||||
"event", sol::property(&PlayUpdateEvent::event, &PlayUpdateEvent::event)
|
||||
);
|
||||
|
||||
---@class GamePostUpdateEvent
|
||||
---@field event IEvent
|
||||
lua.new_usertype<PlayerPreUpdateEvent>("PlayerPreUpdateEvent",
|
||||
"event", sol::property(&PlayerPreUpdateEvent::event, &PlayerPreUpdateEvent::event),
|
||||
"player", sol::property(&PlayerPreUpdateEvent::player, &PlayerPreUpdateEvent::player)
|
||||
);
|
||||
|
||||
---@class PlayUpdateEvent
|
||||
---@field event IEvent
|
||||
lua.new_usertype<PlayerPostUpdateEvent>("PlayerPostUpdateEvent",
|
||||
"event", sol::property(&PlayerPostUpdateEvent::event, &PlayerPostUpdateEvent::event),
|
||||
"player", sol::property(&PlayerPostUpdateEvent::player, &PlayerPostUpdateEvent::player)
|
||||
);
|
||||
|
||||
---@class PlayerPreUpdateEvent
|
||||
---@field event IEvent
|
||||
---@field player Player
|
||||
lua.new_usertype<DrawRadarHUDEvent>("DrawRadarHUDEvent",
|
||||
"event", sol::property(&DrawRadarHUDEvent::event, &DrawRadarHUDEvent::event)
|
||||
);
|
||||
|
||||
---@class PlayerPostUpdateEvent
|
||||
---@field event IEvent
|
||||
---@field player Player
|
||||
lua.new_usertype<DrawRadarMarkArwingEvent>("DrawRadarMarkArwingEvent",
|
||||
"event", sol::property(&DrawRadarMarkArwingEvent::event, &DrawRadarMarkArwingEvent::event),
|
||||
"colorIdx", sol::property(&DrawRadarMarkArwingEvent::colorIdx, &DrawRadarMarkArwingEvent::colorIdx)
|
||||
);
|
||||
|
||||
---@class DrawRadarHUDEvent
|
||||
---@field event IEvent
|
||||
lua.new_usertype<DrawRadarMarkWolfenEvent>("DrawRadarMarkWolfenEvent",
|
||||
"event", sol::property(&DrawRadarMarkWolfenEvent::event, &DrawRadarMarkWolfenEvent::event)
|
||||
);
|
||||
|
||||
---@class DrawRadarMarkArwingEvent
|
||||
---@field event IEvent
|
||||
---@field colorIdx number
|
||||
lua.new_usertype<DrawBoostGaugeHUDEvent>("DrawBoostGaugeHUDEvent",
|
||||
"event", sol::property(&DrawBoostGaugeHUDEvent::event, &DrawBoostGaugeHUDEvent::event)
|
||||
);
|
||||
|
||||
---@class DrawRadarMarkWolfenEvent
|
||||
---@field event IEvent
|
||||
lua.new_usertype<DrawBombCounterHUDEvent>("DrawBombCounterHUDEvent",
|
||||
"event", sol::property(&DrawBombCounterHUDEvent::event, &DrawBombCounterHUDEvent::event)
|
||||
);
|
||||
|
||||
---@class DrawBoostGaugeHUDEvent
|
||||
---@field event IEvent
|
||||
lua.new_usertype<DrawIncomingMsgHUDEvent>("DrawIncomingMsgHUDEvent",
|
||||
"event", sol::property(&DrawIncomingMsgHUDEvent::event, &DrawIncomingMsgHUDEvent::event)
|
||||
);
|
||||
|
||||
---@class DrawBombCounterHUDEvent
|
||||
---@field event IEvent
|
||||
lua.new_usertype<PreSetupRadioMsgEvent>("PreSetupRadioMsgEvent",
|
||||
"event", sol::property(&PreSetupRadioMsgEvent::event, &PreSetupRadioMsgEvent::event),
|
||||
"radioRedBox", sol::property(&PreSetupRadioMsgEvent::radioRedBox, &PreSetupRadioMsgEvent::radioRedBox)
|
||||
);
|
||||
|
||||
---@class DrawIncomingMsgHUDEvent
|
||||
---@field event IEvent
|
||||
lua.new_usertype<DrawGoldRingsHUDEvent>("DrawGoldRingsHUDEvent",
|
||||
"event", sol::property(&DrawGoldRingsHUDEvent::event, &DrawGoldRingsHUDEvent::event)
|
||||
);
|
||||
|
||||
---@class PreSetupRadioMsgEvent
|
||||
---@field event IEvent
|
||||
---@field radioRedBox number
|
||||
lua.new_usertype<DrawLivesCounterHUDEvent>("DrawLivesCounterHUDEvent",
|
||||
"event", sol::property(&DrawLivesCounterHUDEvent::event, &DrawLivesCounterHUDEvent::event)
|
||||
);
|
||||
|
||||
---@class DrawGoldRingsHUDEvent
|
||||
---@field event IEvent
|
||||
lua.new_usertype<DrawTrainingRingPassCountHUDEvent>("DrawTrainingRingPassCountHUDEvent",
|
||||
"event", sol::property(&DrawTrainingRingPassCountHUDEvent::event, &DrawTrainingRingPassCountHUDEvent::event)
|
||||
);
|
||||
|
||||
---@class DrawLivesCounterHUDEvent
|
||||
---@field event IEvent
|
||||
lua.new_usertype<DrawEdgeArrowsHUDEvent>("DrawEdgeArrowsHUDEvent",
|
||||
"event", sol::property(&DrawEdgeArrowsHUDEvent::event, &DrawEdgeArrowsHUDEvent::event)
|
||||
);
|
||||
|
||||
---@class DrawTrainingRingPassCountHUDEvent
|
||||
---@field event IEvent
|
||||
lua.new_usertype<DrawBossHealthHUDEvent>("DrawBossHealthHUDEvent",
|
||||
"event", sol::property(&DrawBossHealthHUDEvent::event, &DrawBossHealthHUDEvent::event)
|
||||
);
|
||||
|
||||
---@class DrawEdgeArrowsHUDEvent
|
||||
---@field event IEvent
|
||||
lua.new_usertype<DrawGlobalHUDPreEvent>("DrawGlobalHUDPreEvent",
|
||||
"event", sol::property(&DrawGlobalHUDPreEvent::event, &DrawGlobalHUDPreEvent::event)
|
||||
);
|
||||
|
||||
---@class DrawBossHealthHUDEvent
|
||||
---@field event IEvent
|
||||
lua.new_usertype<DrawGlobalHUDPostEvent>("DrawGlobalHUDPostEvent",
|
||||
"event", sol::property(&DrawGlobalHUDPostEvent::event, &DrawGlobalHUDPostEvent::event)
|
||||
);
|
||||
|
||||
---@class DrawGlobalHUDPreEvent
|
||||
---@field event IEvent
|
||||
lua.new_usertype<ObjectInitEvent>("ObjectInitEvent",
|
||||
"event", sol::property(&ObjectInitEvent::event, &ObjectInitEvent::event),
|
||||
"type", sol::property(&ObjectInitEvent::type, &ObjectInitEvent::type),
|
||||
"object", sol::property(&ObjectInitEvent::object, &ObjectInitEvent::object)
|
||||
);
|
||||
|
||||
---@class DrawGlobalHUDPostEvent
|
||||
---@field event IEvent
|
||||
lua.new_usertype<ObjectUpdateEvent>("ObjectUpdateEvent",
|
||||
"event", sol::property(&ObjectUpdateEvent::event, &ObjectUpdateEvent::event),
|
||||
"type", sol::property(&ObjectUpdateEvent::type, &ObjectUpdateEvent::type),
|
||||
"object", sol::property(&ObjectUpdateEvent::object, &ObjectUpdateEvent::object)
|
||||
);
|
||||
|
||||
lua.new_usertype<ObjectDrawPreSetupEvent>("ObjectDrawPreSetupEvent",
|
||||
"event", sol::property(&ObjectDrawPreSetupEvent::event, &ObjectDrawPreSetupEvent::event),
|
||||
"type", sol::property(&ObjectDrawPreSetupEvent::type, &ObjectDrawPreSetupEvent::type),
|
||||
"object", sol::property(&ObjectDrawPreSetupEvent::object, &ObjectDrawPreSetupEvent::object)
|
||||
);
|
||||
|
||||
---@class ObjectInitEvent
|
||||
---@field event IEvent
|
||||
---@field type ObjectEventType
|
||||
---@field object Object
|
||||
|
||||
---@class ObjectUpdateEvent
|
||||
---@field event IEvent
|
||||
---@field type ObjectEventType
|
||||
---@field object Object
|
||||
|
||||
---@class ObjectDrawPreSetupEvent
|
||||
---@field event IEvent
|
||||
---@field type ObjectEventType
|
||||
---@field object Object
|
||||
|
||||
---@class ObjectDrawPostSetupEvent
|
||||
---@field event IEvent
|
||||
---@field type ObjectEventType
|
||||
---@field object Object
|
||||
|
||||
---@class ObjectDestroyEvent
|
||||
---@field event IEvent
|
||||
---@field type ObjectEventType
|
||||
---@field object Object
|
||||
lua.new_usertype<ObjectDrawPostSetupEvent>("ObjectDrawPostSetupEvent",
|
||||
"event", sol::property(&ObjectDrawPostSetupEvent::event, &ObjectDrawPostSetupEvent::event),
|
||||
"type", sol::property(&ObjectDrawPostSetupEvent::type, &ObjectDrawPostSetupEvent::type),
|
||||
"object", sol::property(&ObjectDrawPostSetupEvent::object, &ObjectDrawPostSetupEvent::object)
|
||||
);
|
||||
|
||||
lua.new_usertype<ObjectDestroyEvent>("ObjectDestroyEvent",
|
||||
"event", sol::property(&ObjectDestroyEvent::event, &ObjectDestroyEvent::event),
|
||||
"type", sol::property(&ObjectDestroyEvent::type, &ObjectDestroyEvent::type),
|
||||
"object", sol::property(&ObjectDestroyEvent::object, &ObjectDestroyEvent::object)
|
||||
);
|
||||
|
||||
---@enum EventID
|
||||
EventID = {
|
||||
ItemDropEvent = -1,
|
||||
PlayerActionBoostEvent = -1,
|
||||
PlayerActionBrakeEvent = -1,
|
||||
PlayerActionPreShootEvent = -1,
|
||||
PlayerActionPostShootEvent = -1,
|
||||
PlayerActionPreShootChargedEvent = -1,
|
||||
PlayerActionPostShootChargedEvent = -1,
|
||||
PlayerActionPreBombEvent = -1,
|
||||
PlayerActionPostBombEvent = -1,
|
||||
EngineInitEvent = -1,
|
||||
EngineExitEvent = -1,
|
||||
EngineRenderMenubarEvent = -1,
|
||||
DisplayPreUpdateEvent = -1,
|
||||
DisplayPostUpdateEvent = -1,
|
||||
GamePreUpdateEvent = -1,
|
||||
GamePostUpdateEvent = -1,
|
||||
PlayUpdateEvent = -1,
|
||||
PlayerPreUpdateEvent = -1,
|
||||
PlayerPostUpdateEvent = -1,
|
||||
DrawRadarHUDEvent = -1,
|
||||
DrawRadarMarkArwingEvent = -1,
|
||||
DrawRadarMarkWolfenEvent = -1,
|
||||
DrawBoostGaugeHUDEvent = -1,
|
||||
DrawBombCounterHUDEvent = -1,
|
||||
DrawIncomingMsgHUDEvent = -1,
|
||||
PreSetupRadioMsgEvent = -1,
|
||||
DrawGoldRingsHUDEvent = -1,
|
||||
DrawLivesCounterHUDEvent = -1,
|
||||
DrawTrainingRingPassCountHUDEvent = -1,
|
||||
DrawEdgeArrowsHUDEvent = -1,
|
||||
DrawBossHealthHUDEvent = -1,
|
||||
DrawGlobalHUDPreEvent = -1,
|
||||
DrawGlobalHUDPostEvent = -1,
|
||||
ObjectInitEvent = -1,
|
||||
ObjectUpdateEvent = -1,
|
||||
ObjectDrawPreSetupEvent = -1,
|
||||
ObjectDrawPostSetupEvent = -1,
|
||||
ObjectDestroyEvent = -1
|
||||
}
|
||||
|
|
|
@ -325,7 +325,7 @@ extern Vec3f gTeamArrowsViewPos[10];
|
|||
// extern f32 D_ctx_80178028[65];
|
||||
// extern f32 D_ctx_80178130[65];
|
||||
// extern u8 D_ctx_80178238[65];
|
||||
extern Player* gPlayer;
|
||||
extern Player* gPlayer; // sol:array
|
||||
extern f32* gStarOffsetsX;
|
||||
extern f32* gStarOffsetsY;
|
||||
extern u32* gStarFillColors;
|
||||
|
|
|
@ -13,10 +13,11 @@ typedef struct Vec3f {
|
|||
/* 0x4 */ f32 y;
|
||||
/* 0x8 */ f32 z;
|
||||
#ifdef __cplusplus
|
||||
Vec3f* asRef() { return this; } // sol:ignore
|
||||
f32* xRef() { return &x; } // sol:ignore
|
||||
f32* yRef() { return &y; } // sol:ignore
|
||||
f32* zRef() { return &z; } // sol:ignore
|
||||
Vec3f* asRef() { return this; } // sol:not_global
|
||||
f32* xRef() { return &x; } // sol:not_global
|
||||
f32* yRef() { return &y; } // sol:not_global
|
||||
f32* zRef() { return &z; } // sol:not_global
|
||||
f32* asArray() { if(this) return nullptr; return (f32*) this; } // sol:not_global
|
||||
#endif
|
||||
} Vec3f; // size = 0xC
|
||||
|
||||
|
@ -25,10 +26,11 @@ typedef struct Vec3s {
|
|||
/* 0x2 */ s16 y;
|
||||
/* 0x4 */ s16 z;
|
||||
#ifdef __cplusplus
|
||||
Vec3s* asRef() { return this; } // sol:ignore
|
||||
s16* xRef() { return &x; } // sol:ignore
|
||||
s16* yRef() { return &y; } // sol:ignore
|
||||
s16* zRef() { return &z; } // sol:ignore
|
||||
Vec3s* asRef() { return this; } // sol:not_global
|
||||
s16* xRef() { return &x; } // sol:not_global
|
||||
s16* yRef() { return &y; } // sol:not_global
|
||||
s16* zRef() { return &z; } // sol:not_global
|
||||
s16* asArray() { if(this) return nullptr; return (s16*) this; } // sol:not_global
|
||||
#endif
|
||||
} Vec3s; // size = 0x6;
|
||||
|
||||
|
@ -36,7 +38,7 @@ typedef struct PosRot {
|
|||
/* 0x00 */ Vec3f pos;
|
||||
/* 0x0C */ Vec3f rot;
|
||||
#ifdef __cplusplus
|
||||
PosRot* asRef() { return this; } // sol:ignore
|
||||
PosRot* asRef() { return this; } // sol:not_global
|
||||
#endif
|
||||
} PosRot; // size = 0x18
|
||||
|
||||
|
@ -44,14 +46,14 @@ typedef struct CameraPoint {
|
|||
/* 0x00 */ Vec3f eye;
|
||||
/* 0x0C */ Vec3f at;
|
||||
#ifdef __cplusplus
|
||||
CameraPoint* asRef() { return this; } // sol:ignore
|
||||
CameraPoint* asRef() { return this; } // sol:not_global
|
||||
#endif
|
||||
} CameraPoint; // size = 0x18
|
||||
|
||||
typedef struct Triangle {
|
||||
/* 0x0 */ s16 vtx[3];
|
||||
#ifdef __cplusplus
|
||||
Triangle* asRef() { return this; } // sol:ignore
|
||||
Triangle* asRef() { return this; } // sol:not_global
|
||||
#endif
|
||||
} Triangle; // size = 0x6
|
||||
|
||||
|
@ -59,7 +61,7 @@ typedef struct PlaneF {
|
|||
/* 0x0 */ Vec3f normal;
|
||||
/* 0xC */ f32 dist;
|
||||
#ifdef __cplusplus
|
||||
PlaneF* asRef() { return this; } // sol:ignore
|
||||
PlaneF* asRef() { return this; } // sol:not_global
|
||||
#endif
|
||||
} PlaneF; // size = 0x10
|
||||
|
||||
|
@ -67,7 +69,7 @@ typedef struct PlaneI {
|
|||
/* 0x0 */ Vec3s normal;
|
||||
/* 0x8 */ s32 dist;
|
||||
#ifdef __cplusplus
|
||||
PlaneI* asRef() { return this; } // sol:ignore
|
||||
PlaneI* asRef() { return this; } // sol:not_global
|
||||
#endif
|
||||
} PlaneI; // size = 0xC
|
||||
|
||||
|
|
|
@ -149,14 +149,14 @@ typedef struct Object {
|
|||
/* 0x04 */ Vec3f pos;
|
||||
/* 0x10 */ Vec3f rot;
|
||||
#ifdef __cplusplus
|
||||
Actor* asActor() { return (Actor*)this; } // sol:ignore
|
||||
Boss* asBoss() { return (Boss*)this; } // sol:ignore
|
||||
Scenery* asScenery() { return (Scenery*)this; } // sol:ignore
|
||||
Scenery360* asScenery360() { return (Scenery360*)this; } // sol:ignore
|
||||
Sprite* asSprite() { return (Sprite*)this; } // sol:ignore
|
||||
Item* asItem() { return (Item*)this; } // sol:ignore
|
||||
Effect* asEffect() { return (Effect*)this; } // sol:ignore
|
||||
Object* asRef() { return this; } // sol:ignore
|
||||
Actor* asActor() { if(this) return nullptr; return (Actor*)this; } // sol:not_global
|
||||
Boss* asBoss() { if(this) return nullptr; return (Boss*)this; } // sol:not_global
|
||||
Scenery* asScenery() { if(this) return nullptr; return (Scenery*)this; } // sol:not_global
|
||||
Scenery360* asScenery360() { if(this) return nullptr; return (Scenery360*)this; } // sol:not_global
|
||||
Sprite* asSprite() { if(this) return nullptr; return (Sprite*)this; } // sol:not_global
|
||||
Item* asItem() { if(this) return nullptr; return (Item*)this; } // sol:not_global
|
||||
Effect* asEffect() { if(this) return nullptr; return (Effect*)this; } // sol:not_global
|
||||
Object* asRef() { if(this) return nullptr; return this; } // sol:not_global
|
||||
#endif
|
||||
} Object; // size = 0x1C
|
||||
|
||||
|
@ -171,14 +171,14 @@ typedef struct ObjectInfo {
|
|||
/* 0x08 */ ObjectFunc action; // argument must have object type.
|
||||
/* 0x0C */ f32* hitbox;
|
||||
/* 0x10 */ f32 cullDistance; // z coordinate of something
|
||||
/* 0x14 */ s16 unk_14; // can be -1, 0, 1. governs camera-related behavior in effects (billboarding?)
|
||||
/* 0x14 */ s16 unk_14; // can be -1, 0, 1. governs camera-related behavior in effects
|
||||
/* 0x16 */ s16 unk_16; // can be 0, 1, 2. affects death behavior?
|
||||
/* 0x18 */ u8 damage;
|
||||
/* 0x19 */ u8 unk_19; // can be 0, 1, 2. Also camera-related?
|
||||
/* 0x1C */ f32 targetOffset; // target lock y offset. 0.0f can't be targeted
|
||||
/* 0x20 */ u8 bonus; // hits when killed. numbers above 1 indicate the hit+ bonus
|
||||
#ifdef __cplusplus
|
||||
ObjectInfo* asRef() { return this; } // sol:ignore
|
||||
ObjectInfo* asRef() { if(this) return nullptr; return this; } // sol:not_global
|
||||
#endif
|
||||
} ObjectInfo; // size = 0x24
|
||||
|
||||
|
@ -190,7 +190,7 @@ typedef struct Scenery360 {
|
|||
/* 0x48 */ f32 sfxSource[3];
|
||||
/* 0x54 */ f32 unk_54;
|
||||
#ifdef __cplusplus
|
||||
Scenery360* asRef() { return this; } // sol:ignore
|
||||
Scenery360* asRef() { if(this) return nullptr; return this; } // sol:not_global
|
||||
#endif
|
||||
} Scenery360; // size = 0x58
|
||||
|
||||
|
@ -208,7 +208,7 @@ typedef struct Scenery {
|
|||
/* 0x70 */ f32 sfxSource[3];
|
||||
/* 0x7C */ char pad7C[4];
|
||||
#ifdef __cplusplus
|
||||
Scenery* asRef() { return this; } // sol:ignore
|
||||
Scenery* asRef() { if(this) return nullptr; return this; } // sol:not_global
|
||||
#endif
|
||||
} Scenery; // size = 0x80
|
||||
|
||||
|
@ -221,7 +221,7 @@ typedef struct Sprite {
|
|||
/* 0x46 */ s8 destroy;
|
||||
/* 0x48 */ s32 toLeft;
|
||||
#ifdef __cplusplus
|
||||
Sprite* asRef() { return this; } // sol:ignore
|
||||
Sprite* asRef() { if(this) return nullptr; return this; } // sol:not_global
|
||||
#endif
|
||||
} Sprite; // size = 0x4C
|
||||
|
||||
|
@ -241,7 +241,7 @@ typedef struct Item {
|
|||
/* 0x5C */ f32 sfxSource[3];
|
||||
/* 0x68 */ f32 width;
|
||||
#ifdef __cplusplus
|
||||
Item* asRef() { return this; } // sol:ignore
|
||||
Item* asRef() { if(this) return nullptr; return this; } // sol:not_global
|
||||
#endif
|
||||
} Item; // size 0x6C
|
||||
|
||||
|
@ -267,7 +267,7 @@ typedef struct Effect {
|
|||
/* 0x7C */ char pad7C[4];
|
||||
/* 0x80 */ f32 sfxSource[3];
|
||||
#ifdef __cplusplus
|
||||
Effect* asRef() { return this; } // sol:ignore
|
||||
Effect* asRef() { if(this) return nullptr; return this; } // sol:not_global
|
||||
#endif
|
||||
} Effect; // size 0x8C
|
||||
|
||||
|
@ -303,7 +303,7 @@ typedef struct Boss {
|
|||
/* 0x3F8 */ f32 scale;
|
||||
/* 0x3FC */ f32 sfxSource[3];
|
||||
#ifdef __cplusplus
|
||||
Boss* asRef() { return this; } // sol:ignore
|
||||
Boss* asRef() { if(this) return nullptr; return this; } // sol:not_global
|
||||
#endif
|
||||
} Boss; // size = 0x408
|
||||
|
||||
|
@ -354,7 +354,7 @@ typedef struct Actor {
|
|||
/* 0x114 */ f32 fwork[30];
|
||||
/* 0x18C */ Vec3f vwork[30];
|
||||
#ifdef __cplusplus
|
||||
Actor* asRef() { return this; } // sol:ignore
|
||||
Actor* asRef() { if(this) return nullptr; return this; } // sol:not_global
|
||||
#endif
|
||||
} Actor; // size = 0x2F4
|
||||
|
||||
|
|
|
@ -34,6 +34,10 @@ typedef struct PlanetStats {
|
|||
(hitCount > 255 ? hitCount - 256 : hitCount), \
|
||||
((planetId) | ((hitCount > 255 ? 1 : 0) << 4) | (peppyAlive << 5) | (falcoAlive << 6) | (slippyAlive << 7))
|
||||
|
||||
#ifdef __cplusplus
|
||||
#include <vector>
|
||||
#endif
|
||||
|
||||
typedef struct SaveData {
|
||||
/* 0x00 */ PlanetData planet[16];
|
||||
/* 0x10 */ char pad10[0x4];
|
||||
|
@ -50,6 +54,11 @@ typedef struct SaveData {
|
|||
/* 0xEB */ u8 textLanguage; // EU Only text language selection
|
||||
/* 0xEC */ u8 voiceLanguage; // EU Only voice language selection
|
||||
/* 0xED */ char padEE[0x11];
|
||||
#ifdef __cplusplus
|
||||
std::vector<PlanetStats> GetPlanetStats(uint32_t route) { // sol:not_global
|
||||
std::vector<PlanetStats> result; for (auto & stat : stats) result.push_back(stat[route]); return result; // sol:ignore
|
||||
} // sol:ignore
|
||||
#endif
|
||||
} SaveData; // size = 0xFE
|
||||
|
||||
typedef struct {
|
||||
|
|
|
@ -919,50 +919,52 @@ lua["Assets"]["sBoostGaugeArrow8"] = Asset{ sBoostGaugeArrow8 };
|
|||
lua.new_usertype<Vec3f>("Vec3f",
|
||||
"x", sol::property(&Vec3f::x, &Vec3f::x),
|
||||
"y", sol::property(&Vec3f::y, &Vec3f::y),
|
||||
"z", sol::property(&Vec3f::z, &Vec3f::z)
|
||||
,"asRef", &Vec3f::asRef
|
||||
,"xRef", &Vec3f::xRef,
|
||||
"yRef", &Vec3f::yRef,
|
||||
"zRef", &Vec3f::zRef
|
||||
"z", sol::property(&Vec3f::z, &Vec3f::z),
|
||||
"asRef", &Vec3f::asRef,
|
||||
"xRef", &Vec3f::xRef,
|
||||
"yRef", &Vec3f::yRef,
|
||||
"zRef", &Vec3f::zRef,
|
||||
"asArray", &Vec3f::asArray
|
||||
);
|
||||
|
||||
lua.new_usertype<Vec3s>("Vec3s",
|
||||
"x", sol::property(&Vec3s::x, &Vec3s::x),
|
||||
"y", sol::property(&Vec3s::y, &Vec3s::y),
|
||||
"z", sol::property(&Vec3s::z, &Vec3s::z)
|
||||
,"asRef", &Vec3s::asRef
|
||||
,"xRef", &Vec3s::xRef,
|
||||
"yRef", &Vec3s::yRef,
|
||||
"zRef", &Vec3s::zRef
|
||||
"z", sol::property(&Vec3s::z, &Vec3s::z),
|
||||
"asRef", &Vec3s::asRef,
|
||||
"xRef", &Vec3s::xRef,
|
||||
"yRef", &Vec3s::yRef,
|
||||
"zRef", &Vec3s::zRef,
|
||||
"asArray", &Vec3s::asArray
|
||||
);
|
||||
|
||||
lua.new_usertype<PosRot>("PosRot",
|
||||
"pos", sol::property(&PosRot::pos, &PosRot::pos),
|
||||
"rot", sol::property(&PosRot::rot, &PosRot::rot)
|
||||
,"asRef", &PosRot::asRef
|
||||
"rot", sol::property(&PosRot::rot, &PosRot::rot),
|
||||
"asRef", &PosRot::asRef
|
||||
);
|
||||
|
||||
lua.new_usertype<CameraPoint>("CameraPoint",
|
||||
"eye", sol::property(&CameraPoint::eye, &CameraPoint::eye),
|
||||
"at", sol::property(&CameraPoint::at, &CameraPoint::at)
|
||||
,"asRef", &CameraPoint::asRef
|
||||
"at", sol::property(&CameraPoint::at, &CameraPoint::at),
|
||||
"asRef", &CameraPoint::asRef
|
||||
);
|
||||
|
||||
lua.new_usertype<Triangle>("Triangle",
|
||||
"vtx", sol::property(&Triangle::vtx, &Triangle::vtx)
|
||||
,"asRef", &Triangle::asRef
|
||||
"vtx", sol::property(&Triangle::vtx, &Triangle::vtx),
|
||||
"asRef", &Triangle::asRef
|
||||
);
|
||||
|
||||
lua.new_usertype<PlaneF>("PlaneF",
|
||||
"normal", sol::property(&PlaneF::normal, &PlaneF::normal),
|
||||
"dist", sol::property(&PlaneF::dist, &PlaneF::dist)
|
||||
,"asRef", &PlaneF::asRef
|
||||
"dist", sol::property(&PlaneF::dist, &PlaneF::dist),
|
||||
"asRef", &PlaneF::asRef
|
||||
);
|
||||
|
||||
lua.new_usertype<PlaneI>("PlaneI",
|
||||
"normal", sol::property(&PlaneI::normal, &PlaneI::normal),
|
||||
"dist", sol::property(&PlaneI::dist, &PlaneI::dist)
|
||||
,"asRef", &PlaneI::asRef
|
||||
"dist", sol::property(&PlaneI::dist, &PlaneI::dist),
|
||||
"asRef", &PlaneI::asRef
|
||||
);
|
||||
|
||||
lua["Game"]["gIdentityMtx"] = sol::overload([]() -> Mtx { return gIdentityMtx; }, [](Mtx value) { gIdentityMtx = value; });
|
||||
|
@ -3288,6 +3290,15 @@ lua.set_function("RCP_SetupDL_50", RCP_SetupDL_50);
|
|||
lua.set_function("RCP_SetupDL_61", RCP_SetupDL_61);
|
||||
lua["Game"]["gRcpSetupDLs"] = sol::overload([](int index1, int index2) -> Gfx { return gRcpSetupDLs[index1][index2]; }, [](int index1, int index2, Gfx value) { gRcpSetupDLs[index1][index2] = value; });
|
||||
lua["Game"]["D_80178580"] = sol::overload([](int index) -> u8 { return D_80178580[index]; }, [](int index, u8 value) { D_80178580[index] = value; });
|
||||
lua.new_usertype<PlanetStats>("PlanetStats",
|
||||
"hitCount", sol::property([] (PlanetStats& self) -> u16 { return self.hitCount; }, [] (PlanetStats& self, u16 value) { self.hitCount = value; }),
|
||||
"planetId", sol::property([] (PlanetStats& self) -> u8 { return self.planetId; }, [] (PlanetStats& self, u8 value) { self.planetId = value; }),
|
||||
"hitCountOver256", sol::property([] (PlanetStats& self) -> u8 { return self.hitCountOver256; }, [] (PlanetStats& self, u8 value) { self.hitCountOver256 = value; }),
|
||||
"peppyAlive", sol::property([] (PlanetStats& self) -> u8 { return self.peppyAlive; }, [] (PlanetStats& self, u8 value) { self.peppyAlive = value; }),
|
||||
"falcoAlive", sol::property([] (PlanetStats& self) -> u8 { return self.falcoAlive; }, [] (PlanetStats& self, u8 value) { self.falcoAlive = value; }),
|
||||
"slippyAlive", sol::property([] (PlanetStats& self) -> u8 { return self.slippyAlive; }, [] (PlanetStats& self, u8 value) { self.slippyAlive = value; })
|
||||
);
|
||||
|
||||
lua.new_usertype<SaveData>("SaveData",
|
||||
"planet", sol::property(&SaveData::planet, &SaveData::planet),
|
||||
"pad10", sol::property(&SaveData::pad10, &SaveData::pad10),
|
||||
|
@ -4876,8 +4887,8 @@ lua.new_usertype<Object>("Object",
|
|||
"status", sol::property(&Object::status, &Object::status),
|
||||
"id", sol::property(&Object::id, &Object::id),
|
||||
"pos", sol::property(&Object::pos, &Object::pos),
|
||||
"rot", sol::property(&Object::rot, &Object::rot)
|
||||
,"asActor", &Object::asActor,
|
||||
"rot", sol::property(&Object::rot, &Object::rot),
|
||||
"asActor", &Object::asActor,
|
||||
"asBoss", &Object::asBoss,
|
||||
"asScenery", &Object::asScenery,
|
||||
"asScenery360", &Object::asScenery360,
|
||||
|
@ -4899,8 +4910,8 @@ lua.new_usertype<ObjectInfo>("ObjectInfo",
|
|||
"damage", sol::property(&ObjectInfo::damage, &ObjectInfo::damage),
|
||||
"unk_19", sol::property(&ObjectInfo::unk_19, &ObjectInfo::unk_19),
|
||||
"targetOffset", sol::property(&ObjectInfo::targetOffset, &ObjectInfo::targetOffset),
|
||||
"bonus", sol::property(&ObjectInfo::bonus, &ObjectInfo::bonus)
|
||||
,"asRef", &ObjectInfo::asRef
|
||||
"bonus", sol::property(&ObjectInfo::bonus, &ObjectInfo::bonus),
|
||||
"asRef", &ObjectInfo::asRef
|
||||
);
|
||||
|
||||
lua.new_usertype<Scenery360>("Scenery360",
|
||||
|
@ -4909,8 +4920,8 @@ lua.new_usertype<Scenery360>("Scenery360",
|
|||
"pathIndex", sol::property(&Scenery360::pathIndex, &Scenery360::pathIndex),
|
||||
"unk_41", sol::property(&Scenery360::unk_41, &Scenery360::unk_41),
|
||||
"sfxSource", sol::property(&Scenery360::sfxSource, &Scenery360::sfxSource),
|
||||
"unk_54", sol::property(&Scenery360::unk_54, &Scenery360::unk_54)
|
||||
,"asRef", &Scenery360::asRef
|
||||
"unk_54", sol::property(&Scenery360::unk_54, &Scenery360::unk_54),
|
||||
"asRef", &Scenery360::asRef
|
||||
);
|
||||
|
||||
lua.new_usertype<Scenery>("Scenery",
|
||||
|
@ -4925,8 +4936,8 @@ lua.new_usertype<Scenery>("Scenery",
|
|||
"effectVel", sol::property(&Scenery::effectVel, &Scenery::effectVel),
|
||||
"vel", sol::property(&Scenery::vel, &Scenery::vel),
|
||||
"sfxSource", sol::property(&Scenery::sfxSource, &Scenery::sfxSource),
|
||||
"pad7C", sol::property(&Scenery::pad7C, &Scenery::pad7C)
|
||||
,"asRef", &Scenery::asRef
|
||||
"pad7C", sol::property(&Scenery::pad7C, &Scenery::pad7C),
|
||||
"asRef", &Scenery::asRef
|
||||
);
|
||||
|
||||
lua.new_usertype<Sprite>("Sprite",
|
||||
|
@ -4936,8 +4947,8 @@ lua.new_usertype<Sprite>("Sprite",
|
|||
"pad44", sol::property(&Sprite::pad44, &Sprite::pad44),
|
||||
"sceneryId", sol::property(&Sprite::sceneryId, &Sprite::sceneryId),
|
||||
"destroy", sol::property(&Sprite::destroy, &Sprite::destroy),
|
||||
"toLeft", sol::property(&Sprite::toLeft, &Sprite::toLeft)
|
||||
,"asRef", &Sprite::asRef
|
||||
"toLeft", sol::property(&Sprite::toLeft, &Sprite::toLeft),
|
||||
"asRef", &Sprite::asRef
|
||||
);
|
||||
|
||||
lua.new_usertype<Item>("Item",
|
||||
|
@ -4954,8 +4965,8 @@ lua.new_usertype<Item>("Item",
|
|||
"unk_54", sol::property(&Item::unk_54, &Item::unk_54),
|
||||
"unk_58", sol::property(&Item::unk_58, &Item::unk_58),
|
||||
"sfxSource", sol::property(&Item::sfxSource, &Item::sfxSource),
|
||||
"width", sol::property(&Item::width, &Item::width)
|
||||
,"asRef", &Item::asRef
|
||||
"width", sol::property(&Item::width, &Item::width),
|
||||
"asRef", &Item::asRef
|
||||
);
|
||||
|
||||
lua.new_usertype<Effect>("Effect",
|
||||
|
@ -4978,8 +4989,8 @@ lua.new_usertype<Effect>("Effect",
|
|||
"unk_78", sol::property(&Effect::unk_78, &Effect::unk_78),
|
||||
"unk_7A", sol::property(&Effect::unk_7A, &Effect::unk_7A),
|
||||
"pad7C", sol::property(&Effect::pad7C, &Effect::pad7C),
|
||||
"sfxSource", sol::property(&Effect::sfxSource, &Effect::sfxSource)
|
||||
,"asRef", &Effect::asRef
|
||||
"sfxSource", sol::property(&Effect::sfxSource, &Effect::sfxSource),
|
||||
"asRef", &Effect::asRef
|
||||
);
|
||||
|
||||
lua.new_usertype<Boss>("Boss",
|
||||
|
@ -5012,8 +5023,8 @@ lua.new_usertype<Boss>("Boss",
|
|||
"fwork", sol::property(&Boss::fwork, &Boss::fwork),
|
||||
"vwork", sol::property(&Boss::vwork, &Boss::vwork),
|
||||
"scale", sol::property(&Boss::scale, &Boss::scale),
|
||||
"sfxSource", sol::property(&Boss::sfxSource, &Boss::sfxSource)
|
||||
,"asRef", &Boss::asRef
|
||||
"sfxSource", sol::property(&Boss::sfxSource, &Boss::sfxSource),
|
||||
"asRef", &Boss::asRef
|
||||
);
|
||||
|
||||
lua.new_usertype<Actor>("Actor",
|
||||
|
@ -5054,8 +5065,8 @@ lua.new_usertype<Actor>("Actor",
|
|||
"gravity", sol::property(&Actor::gravity, &Actor::gravity),
|
||||
"scale", sol::property(&Actor::scale, &Actor::scale),
|
||||
"fwork", sol::property(&Actor::fwork, &Actor::fwork),
|
||||
"vwork", sol::property(&Actor::vwork, &Actor::vwork)
|
||||
,"asRef", &Actor::asRef
|
||||
"vwork", sol::property(&Actor::vwork, &Actor::vwork),
|
||||
"asRef", &Actor::asRef
|
||||
);
|
||||
|
||||
lua.set_function("Game_SpawnActor", Game_SpawnActor);
|
||||
|
|
|
@ -188,6 +188,8 @@ GameEngine::GameEngine() {
|
|||
"Limb", static_cast<uint32_t>(SF64::ResourceType::Limb), 0);
|
||||
loader->RegisterResourceFactory(std::make_shared<SF64::ResourceFactoryBinaryMessageV0>(), RESOURCE_FORMAT_BINARY,
|
||||
"Message", static_cast<uint32_t>(SF64::ResourceType::Message), 0);
|
||||
loader->RegisterResourceFactory(std::make_shared<SF64::ResourceFactoryXMLMessageV0>(), RESOURCE_FORMAT_XML,
|
||||
"Message", static_cast<uint32_t>(SF64::ResourceType::Message), 0);
|
||||
loader->RegisterResourceFactory(std::make_shared<SF64::ResourceFactoryBinaryMessageLookupV0>(),
|
||||
RESOURCE_FORMAT_BINARY, "MessageTable",
|
||||
static_cast<uint32_t>(SF64::ResourceType::MessageTable), 0);
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#include <stdexcept>
|
||||
#include <algorithm>
|
||||
#include "port/hooks/Events.h"
|
||||
#include "port/notification/notification.h"
|
||||
|
||||
EventSystem* EventSystem::Instance = new EventSystem();
|
||||
|
||||
|
@ -46,11 +47,16 @@ void EventSystem::CallEvent(EventID id, IEvent* event) {
|
|||
std::get<EventCallback>(listener.function)(event);
|
||||
}
|
||||
|
||||
if(is_type(listener.function, sol::function)){
|
||||
if(is_type(listener.function, sol::protected_function)){
|
||||
#undef DEFINE_EVENT
|
||||
#define DEFINE_EVENT(eventName, ...) \
|
||||
if(id == eventName##ID) { \
|
||||
std::get<sol::function>(listener.function)((eventName*)event); \
|
||||
auto result = std::get<sol::protected_function>(listener.function)((eventName*)event); \
|
||||
if(!result.valid()) { \
|
||||
sol::error err = result; \
|
||||
SPDLOG_ERROR(std::string(err.what())); \
|
||||
Notification::Emit({ .message = "Mod error, check log for details", .messageColor = ImVec4(1.0f, 0.5f, 0.5f, 1.0f), .remainingTime = 7.0f }); \
|
||||
} \
|
||||
}
|
||||
#define __LUA__
|
||||
#include "port/hooks/EventList.h"
|
||||
|
|
|
@ -71,7 +71,7 @@ typedef void (*EventCallback)(IEvent*);
|
|||
#include <unordered_map>
|
||||
#include <sol/sol.hpp>
|
||||
|
||||
typedef std::variant<EventCallback, sol::function> SmartFunctionCallback;
|
||||
typedef std::variant<EventCallback, sol::protected_function> SmartFunctionCallback;
|
||||
#define is_type(var, type) std::holds_alternative<type>((var))
|
||||
|
||||
struct EventListener {
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include "port/resource/type/ResourceType.h"
|
||||
#include "port/resource/type/Text.h"
|
||||
#include "port/Engine.h"
|
||||
#include "port/notification/notification.h"
|
||||
|
||||
#define SOL_ALL_SAFETIES_ON 1
|
||||
#include <sol/sol.hpp>
|
||||
|
@ -29,6 +30,9 @@ struct Asset {
|
|||
|
||||
template<typename T>
|
||||
T* Get() {
|
||||
if(this == nullptr){
|
||||
return nullptr;
|
||||
}
|
||||
return (T*) path.data();
|
||||
}
|
||||
|
||||
|
@ -38,7 +42,7 @@ struct Asset {
|
|||
|
||||
static Asset Register(const std::string path) {
|
||||
std::string full = "__OTR__" + path;
|
||||
return Asset{full};
|
||||
return Asset{ full };
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -173,6 +177,7 @@ void ScriptingLayer::Init() {
|
|||
}
|
||||
} catch (const sol::error& e) {
|
||||
SPDLOG_ERROR(std::string(e.what()));
|
||||
Notification::Emit({ .message = "Mod error, check log for details", .messageColor = ImVec4(1.0f, 0.5f, 0.5f, 1.0f), .remainingTime = 7.0f });
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,25 @@
|
|||
#include "MessageFactory.h"
|
||||
#include "../type/Message.h"
|
||||
#include "spdlog/spdlog.h"
|
||||
#include <vector>
|
||||
|
||||
namespace SF64 {
|
||||
|
||||
std::vector<std::string> gASCIIFullTable = {
|
||||
"\0", "\n", "{NP:2}", "{NP:3}", "{NP:4}", "{NP:5}", "{NP:6}", "{NP:7}",
|
||||
"{PRI:0}", "{PRI:1}", "{PRI:2}", "{PRI:3}", " ", "{HSP}", "{QSP}", "{NXT}",
|
||||
"{C:<}", "{C:^}", "{C:>}", "{C:v}", "{^}", "{<}", "{v}", "{>}",
|
||||
"A", "B", "C", "D", "E", "F", "G", "H",
|
||||
"I", "J", "K", "L", "M", "N", "O", "P",
|
||||
"Q", "R", "S", "T", "U", "V", "W", "X",
|
||||
"Y", "Z", "a", "b", "c", "d", "e", "f",
|
||||
"g", "h", "i", "j", "k", "l", "m", "n",
|
||||
"o", "p", "q", "r", "s", "t", "u", "v",
|
||||
"w", "x", "y", "z", "!", "?", "-", ",",
|
||||
".", "0", "1", "2", "3", "4", "5", "6",
|
||||
"7", "8", "9", "'", "(", ")", ":", "|",
|
||||
};
|
||||
|
||||
std::shared_ptr<Ship::IResource> ResourceFactoryBinaryMessageV0::ReadResource(std::shared_ptr<Ship::File> file,
|
||||
std::shared_ptr<Ship::ResourceInitData> initData) {
|
||||
if (!FileHasValidFormatAndReader(file, initData)) {
|
||||
|
@ -20,4 +37,50 @@ std::shared_ptr<Ship::IResource> ResourceFactoryBinaryMessageV0::ReadResource(st
|
|||
|
||||
return msg;
|
||||
}
|
||||
|
||||
std::shared_ptr<Ship::IResource> ResourceFactoryXMLMessageV0::ReadResource(std::shared_ptr<Ship::File> file) {
|
||||
if (!FileHasValidFormatAndReader(file)) {
|
||||
return nullptr;
|
||||
}
|
||||
auto msg = std::make_shared<Message>(file->InitData);
|
||||
auto parent = std::get<std::shared_ptr<tinyxml2::XMLDocument>>(file->Reader)->FirstChildElement("Message");
|
||||
|
||||
tinyxml2::XMLElement* element = parent->FirstChildElement("Line");
|
||||
|
||||
while (element != nullptr) {
|
||||
const char* raw = element->GetText();
|
||||
if (raw == nullptr) {
|
||||
element = element->NextSiblingElement("Line");
|
||||
msg->mMessage.push_back(1);
|
||||
continue;
|
||||
}
|
||||
auto text = std::string(raw);
|
||||
std::string key;
|
||||
for (size_t i = 0; i < text.size(); i++) {
|
||||
auto c = text[i];
|
||||
if (c == '{') {
|
||||
auto end = text.find('}', i);
|
||||
if (end == std::string::npos) {
|
||||
continue;
|
||||
}
|
||||
key = text.substr(i, end - i + 1);
|
||||
i = end;
|
||||
} else {
|
||||
key = text.substr(i, 1);
|
||||
}
|
||||
|
||||
auto it = std::find(gASCIIFullTable.begin(), gASCIIFullTable.end(), key);
|
||||
if (it != gASCIIFullTable.end()) {
|
||||
msg->mMessage.push_back(it - gASCIIFullTable.begin());
|
||||
} else {
|
||||
SPDLOG_ERROR("Unknown key: {}", key);
|
||||
}
|
||||
}
|
||||
msg->mMessage.push_back(1);
|
||||
element = element->NextSiblingElement("Line");
|
||||
} // end
|
||||
|
||||
msg->mMessage.push_back(0);
|
||||
return msg;
|
||||
}
|
||||
} // namespace LUS
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include "Resource.h"
|
||||
#include "ResourceFactoryXML.h"
|
||||
#include "ResourceFactoryBinary.h"
|
||||
|
||||
namespace SF64 {
|
||||
|
@ -9,4 +10,9 @@ class ResourceFactoryBinaryMessageV0 : public Ship::ResourceFactoryBinary {
|
|||
std::shared_ptr<Ship::IResource> ReadResource(std::shared_ptr<Ship::File> file,
|
||||
std::shared_ptr<Ship::ResourceInitData> initData) override;
|
||||
};
|
||||
|
||||
class ResourceFactoryXMLMessageV0 : public Ship::ResourceFactoryXML {
|
||||
public:
|
||||
std::shared_ptr<Ship::IResource> ReadResource(std::shared_ptr<Ship::File> file) override;
|
||||
};
|
||||
}; // namespace LUS
|
||||
|
|
|
@ -1,365 +1,19 @@
|
|||
import re
|
||||
import os
|
||||
import sys
|
||||
from enum import Enum
|
||||
|
||||
blacklist = [
|
||||
'audio',
|
||||
'portable-file-dialogs.h',
|
||||
'rmonint.h',
|
||||
'PR/',
|
||||
'libultra/',
|
||||
'libc/',
|
||||
'dbgproto',
|
||||
'prevent',
|
||||
'piint',
|
||||
'siint',
|
||||
'sf64dma',
|
||||
'osint',
|
||||
'FrameInterpolation',
|
||||
'mods.h'
|
||||
]
|
||||
class OutputType(Enum):
|
||||
NONE = 0
|
||||
LUA = 1
|
||||
CPP = 2
|
||||
|
||||
event_list = []
|
||||
|
||||
def parse_enums(header, as_value=False):
|
||||
try:
|
||||
with open(header, 'r') as file:
|
||||
lines = file.readlines()
|
||||
except IOError:
|
||||
raise RuntimeError("Failed to open header files for enums node in config")
|
||||
|
||||
# Regex pattern to match enum declarations
|
||||
enum_regex = re.compile(r"enum\s+(\w+)\s*(?:\s*:\s*(\w+))?[\s\n\r]*\{")
|
||||
|
||||
in_enum = False
|
||||
enum_index = None
|
||||
enum_name = ""
|
||||
enum = {}
|
||||
|
||||
for line in lines:
|
||||
line = line.strip()
|
||||
|
||||
if not in_enum:
|
||||
# Check if the line matches the enum declaration pattern
|
||||
match = enum_regex.search(line)
|
||||
if match and len(match.groups()) > 1:
|
||||
enum_name = match.group(1)
|
||||
enum[enum_name] = []
|
||||
in_enum = True
|
||||
enum_index = -1
|
||||
continue
|
||||
|
||||
if '}' in line:
|
||||
in_enum = False
|
||||
continue
|
||||
|
||||
# Remove any comments and non-alphanumeric characters
|
||||
line = re.sub(r'(/\*.*?\*/)|(//.*$)|([^a-zA-Z0-9=_\-\.])', '', line)
|
||||
|
||||
if len(line) == 0:
|
||||
continue
|
||||
|
||||
if '=' in line:
|
||||
# Extract the value after the '=' sign
|
||||
value = line.split('=')[1].strip()
|
||||
# Extract the name before the '=' sign
|
||||
name = line.split('=')[0].strip()
|
||||
enum_index = int(value, 0) # Convert the value to an integer with base 0 (detects hex, oct, etc.)
|
||||
enum[enum_name].append({
|
||||
'name': name,
|
||||
'value': enum_index
|
||||
})
|
||||
else:
|
||||
# Increment the enum index if no '=' is found
|
||||
enum_index += 1
|
||||
enum[enum_name].append({
|
||||
'name': line,
|
||||
'value': enum_index
|
||||
})
|
||||
|
||||
for enum_name, values in enum.items():
|
||||
print(f'---@enum {enum_name}')
|
||||
print(f'{enum_name} = {{')
|
||||
for i, entry in enumerate(values):
|
||||
key = entry['name']
|
||||
value = entry['value']
|
||||
if 'ifdef' in key or 'endif' in entry['name'] or 'else' in key:
|
||||
continue
|
||||
key_name = key
|
||||
key_name = key_name.replace('EVENT_PRIORITY_', '')
|
||||
key_name = key_name.replace('SF64_VER_', '')
|
||||
print(f' {key_name} = {value}{"," if i < len(values) - 1 else ""}')
|
||||
print('}')
|
||||
print('')
|
||||
|
||||
def sanitize_type(member_type):
|
||||
member_type = member_type.strip()
|
||||
if len(member_type) == 0:
|
||||
return 'any'
|
||||
member_type = member_type.replace('uint8_t', 'number')
|
||||
member_type = member_type.replace('uint16_t', 'number')
|
||||
member_type = member_type.replace('uint32_t', 'number')
|
||||
member_type = member_type.replace('uint64_t', 'number')
|
||||
member_type = member_type.replace('int8_t', 'number')
|
||||
member_type = member_type.replace('int16_t', 'number')
|
||||
member_type = member_type.replace('int32_t', 'number')
|
||||
member_type = member_type.replace('int64_t', 'number')
|
||||
member_type = member_type.replace('size_t', 'number')
|
||||
member_type = member_type.replace('uintptr_t', 'number')
|
||||
member_type = member_type.replace('...', 'string')
|
||||
member_type = member_type.replace('*', '')
|
||||
member_type = member_type.replace('&', '')
|
||||
member_type = member_type.replace('const', '')
|
||||
member_type = member_type.replace('bool', 'boolean')
|
||||
member_type = member_type.replace('int', 'number')
|
||||
member_type = member_type.replace('float', 'number')
|
||||
member_type = member_type.replace('char', 'string')
|
||||
member_type = member_type.replace('unsigned', 'number')
|
||||
member_type = member_type.replace('u8', 'number')
|
||||
member_type = member_type.replace('u16', 'number')
|
||||
member_type = member_type.replace('u32', 'number')
|
||||
member_type = member_type.replace('u64', 'number')
|
||||
member_type = member_type.replace('s8', 'number')
|
||||
member_type = member_type.replace('s16', 'number')
|
||||
member_type = member_type.replace('s32', 'number')
|
||||
member_type = member_type.replace('s64', 'number')
|
||||
member_type = member_type.replace('void', 'nil')
|
||||
member_type = member_type.replace('f32', 'number')
|
||||
member_type = member_type.replace('f64', 'number')
|
||||
member_type = member_type.replace('double', 'number')
|
||||
member_type = member_type.replace('CONTROLLERBUTTONS_T', 'number')
|
||||
return member_type
|
||||
|
||||
def parse_structs(header):
|
||||
try:
|
||||
with open(header, 'r') as file:
|
||||
lines = file.readlines()
|
||||
except IOError:
|
||||
raise RuntimeError("Failed to open header files for structs node in config")
|
||||
|
||||
struct_regex = re.compile(r"struct\s+(\w+)\s*(?:\s*:\s*(\w+))?[\s\n\r]*\{")
|
||||
|
||||
in_struct = False
|
||||
struct_name = ""
|
||||
found_union = False
|
||||
struct = {}
|
||||
|
||||
for line in lines:
|
||||
line = line.strip()
|
||||
|
||||
if not in_struct:
|
||||
match = struct_regex.search(line)
|
||||
if match and len(match.groups()) > 1:
|
||||
struct_name = match.group(1)
|
||||
struct[struct_name] = []
|
||||
in_struct = True
|
||||
continue
|
||||
|
||||
if 'union' in line:
|
||||
found_union = True
|
||||
continue
|
||||
|
||||
if '}' in line and not found_union:
|
||||
in_struct = False
|
||||
continue
|
||||
|
||||
if '}' in line and found_union:
|
||||
found_union = False
|
||||
continue
|
||||
|
||||
line = re.sub(r'(/\*.*?\*/)', '', line)
|
||||
|
||||
if ';' in line and not ':' in line:
|
||||
# if ':' in line:
|
||||
# member_name = line.split(' ')[-3].split(':')[0]
|
||||
# continue
|
||||
if '[' in line:
|
||||
if len(line.split('[')) > 2:
|
||||
continue
|
||||
member_name = line.split('[')[0].split(' ')[-1]
|
||||
member_type = line.split(' ')[-2]
|
||||
else:
|
||||
member_name = line.split(';')[0].split(' ')[-1]
|
||||
member_type = line.split(';')[0].split(' ')[-2]
|
||||
|
||||
|
||||
struct[struct_name].append(member_name + ' ' + sanitize_type(member_type))
|
||||
|
||||
for struct_name, members in struct.items():
|
||||
if len(members) == 0:
|
||||
continue
|
||||
# TODO: Add support for functions
|
||||
print(f'---@class {struct_name}')
|
||||
for i, key in enumerate(members):
|
||||
key = key.replace('*', '')
|
||||
print(f'---@field {key}')
|
||||
print(f'{struct_name} = {{}}')
|
||||
if struct_name == 'Object':
|
||||
print(f'---@return Actor')
|
||||
print(f'function {struct_name}:asActor() end')
|
||||
print(f'---@return Boss')
|
||||
print(f'function {struct_name}:asBoss() end')
|
||||
print(f'---@return Scenery')
|
||||
print(f'function {struct_name}:asScenery() end')
|
||||
print(f'---@return Scenery360')
|
||||
print(f'function {struct_name}:asScenery360() end')
|
||||
print(f'---@return Sprite')
|
||||
print(f'function {struct_name}:asSprite() end')
|
||||
print(f'---@return Item')
|
||||
print(f'function {struct_name}:asItem() end')
|
||||
print(f'---@return Effect')
|
||||
print(f'function {struct_name}:asEffect() end')
|
||||
print(f'---@return {struct_name}')
|
||||
print(f'function {struct_name}:asRef() end')
|
||||
elif struct_name == 'Object' or struct_name == 'ObjectInfo' or struct_name == 'Actor' or struct_name == 'Boss' or struct_name == 'Scenery' or struct_name == 'Scenery360' or struct_name == 'Sprite' or struct_name == 'Item' or struct_name == 'Effect':
|
||||
print(f'---@return {struct_name}')
|
||||
print(f'function {struct_name}:asRef() end')
|
||||
elif struct_name.startswith('Vec') or struct_name.startswith('Plane') or struct_name == 'PosRot' or struct_name == 'CameraPoint' or struct_name == 'Triangle':
|
||||
print(f'---@return {struct_name}')
|
||||
print(f'function {struct_name}:asRef() end')
|
||||
if struct_name.startswith('Vec'):
|
||||
print(f'---@return f32')
|
||||
print(f'function {struct_name}:xRef() end')
|
||||
print(f'---@return f32')
|
||||
print(f'function {struct_name}:yRef() end')
|
||||
print(f'---@return f32')
|
||||
print(f'function {struct_name}:zRef() end')
|
||||
print('')
|
||||
|
||||
def parse_events(header):
|
||||
try:
|
||||
with open(header, 'r') as file:
|
||||
lines = file.readlines()
|
||||
except IOError:
|
||||
raise RuntimeError("Failed to open header files for events node in config")
|
||||
|
||||
global event_list
|
||||
in_event = False
|
||||
event_name = ""
|
||||
event = {}
|
||||
|
||||
for line in lines:
|
||||
line = line.strip()
|
||||
if not in_event:
|
||||
if 'DEFINE_EVENT' in line:
|
||||
if ');' in line:
|
||||
event_name = line.split('DEFINE_EVENT(')[1].split(')')[0].strip()
|
||||
event[event_name] = ['event IEvent']
|
||||
continue
|
||||
event_name = line.split('DEFINE_EVENT(')[1].split(',')[0].strip()
|
||||
event[event_name] = ['event IEvent']
|
||||
in_event = True
|
||||
continue
|
||||
|
||||
if ');' in line:
|
||||
in_event = False
|
||||
continue
|
||||
|
||||
if len(line) == 0:
|
||||
continue
|
||||
|
||||
if ';' in line:
|
||||
member_name = line.split(';')[0].split(' ')[-1]
|
||||
member_type = line.split(';')[0].split(' ')[-2]
|
||||
event[event_name].append(member_name + ' ' + sanitize_type(member_type))
|
||||
|
||||
for event_name, members in event.items():
|
||||
print(f'---@class {event_name}')
|
||||
event_list.append(event_name)
|
||||
for i, key in enumerate(members):
|
||||
key = key.replace('*', '')
|
||||
print(f'---@field {key}')
|
||||
print('')
|
||||
print('')
|
||||
|
||||
def parse_externs(header, namespace=None):
|
||||
try:
|
||||
with open(header, 'r') as file:
|
||||
lines = file.readlines()
|
||||
except IOError:
|
||||
raise RuntimeError("Failed to open header files for events node in config")
|
||||
|
||||
for line in lines:
|
||||
line = re.sub(r'\s+', ' ', line.strip())
|
||||
if line.startswith('extern') and not 'void*' in line and not '"C"' in line or ('(' in line and ';' in line):
|
||||
if not '(' in line and not '[' in line:
|
||||
var_type = line.split(' ')[1]
|
||||
var_name = line.split(' ')[2].split(';')[0]
|
||||
print(f'---@return {sanitize_type(var_type)}')
|
||||
print(f'function Game.{var_name}() end')
|
||||
print(f'---@param value {sanitize_type(var_type)}')
|
||||
print(f'function Game.{var_name}(value) end')
|
||||
elif '[' in line and not '(' in line:
|
||||
dimension_len = len(line.split('[')) - 1
|
||||
var_name = line.split('[')[0].split(' ')[-1]
|
||||
var_type = line.split(' ')[1]
|
||||
print(f'---@param index number')
|
||||
print(f'---@return {sanitize_type(var_type)}[{dimension_len}]')
|
||||
print(f'function Game.{var_name}(index) end')
|
||||
print(f'---@param index number')
|
||||
print(f'---@param value {sanitize_type(var_type)}')
|
||||
print(f'function Game.{var_name}(index, value) end')
|
||||
elif '(' in line:
|
||||
if 'ALIGN_ASSET' in line:
|
||||
var_name = line.split('[')[0].split(' ')[-1]
|
||||
value = line.split('=')[-1].split(';')[0]
|
||||
print('---@type Asset')
|
||||
print(f'Assets.{var_name} = {value.strip()}')
|
||||
continue
|
||||
if 'define' in line or '\\' in line or 'typedef' in line or '[' in line or 'OSMesg' in line or 'Framebuffer' in line or 'TimerAction' in line or 'TimerTask' in line:
|
||||
continue
|
||||
if '_DEG' in line or 'Fault' in line or 'sol:ignore' in line or '<T>' in line or '<' in line:
|
||||
continue
|
||||
func_name = line.split('(')[0].split(' ')[-1]
|
||||
if len(func_name) == 0:
|
||||
continue
|
||||
if 'CVarExists' in func_name or 'ResourceLoad' in func_name or 'void*' in func_name or 'ResourceClearCache' in func_name: # Report this to LUS
|
||||
continue
|
||||
|
||||
return_type = line.split(' ')[0]
|
||||
args = line.split('(')[1].split(')')[0].strip().split(',')
|
||||
for i, arg in enumerate(args):
|
||||
arg = arg.replace('const ', '')
|
||||
arg = arg.replace(' *', '* ')
|
||||
arg = arg.replace('...', 'varargs')
|
||||
if len(arg.split(' ')) > 2:
|
||||
if '=' in arg:
|
||||
arg = arg.split('=')[0]
|
||||
name = arg.split(' ')[2]
|
||||
type = arg.split(' ')[1]
|
||||
else:
|
||||
name = arg.split(' ')[-1]
|
||||
type = arg.split(' ')[-2]
|
||||
else:
|
||||
name = '_'+arg.split(' ')[-1]
|
||||
type = arg.split(' ')[0]
|
||||
|
||||
name = name.replace('*', '')
|
||||
name = name.replace('end', '_end')
|
||||
if(len(name) == 0):
|
||||
name = f'arg{i}'
|
||||
args[i] = { 'name': name, 'type': type }
|
||||
|
||||
for i, arg in enumerate(args):
|
||||
print(f'---@param {arg["name"]} {sanitize_type(arg["type"])}')
|
||||
|
||||
print(f'---@return {sanitize_type(return_type)}')
|
||||
if namespace:
|
||||
print(f'function {namespace}.{func_name}({', '.join([f'{arg["name"]}' for arg in args])}) end')
|
||||
else:
|
||||
print(f'function {func_name}({', '.join([f'{arg["name"]}' for arg in args])}) end')
|
||||
|
||||
def is_blacklisted(file):
|
||||
for item in blacklist:
|
||||
if item in file:
|
||||
return True
|
||||
return False
|
||||
|
||||
if __name__ == "__main__":
|
||||
print("Game = {}")
|
||||
print("Assets = {}")
|
||||
print("UIWidgets = {}")
|
||||
print("Events = {}")
|
||||
header = """
|
||||
def write_lua_header():
|
||||
print("""
|
||||
Game = {}
|
||||
Assets = {}
|
||||
UIWidgets = {}
|
||||
Events = {}
|
||||
---@alias ListenerID number
|
||||
---@class Asset
|
||||
local Asset = {}
|
||||
|
@ -424,8 +78,432 @@ function gRefGfxMatrix() end
|
|||
---@param b number
|
||||
---@param a number
|
||||
function gDPSetPrimColor(m, l, r, g, b, a) end
|
||||
"""
|
||||
print(header)
|
||||
""")
|
||||
|
||||
export_type = OutputType.NONE
|
||||
event_list = []
|
||||
|
||||
def sanitize_type(member_type):
|
||||
global export_type
|
||||
member_type = member_type.strip()
|
||||
|
||||
if export_type == OutputType.CPP:
|
||||
return member_type
|
||||
|
||||
if len(member_type) == 0:
|
||||
return 'any'
|
||||
|
||||
member_type = member_type.replace('uint8_t', 'number')
|
||||
member_type = member_type.replace('uint16_t', 'number')
|
||||
member_type = member_type.replace('uint32_t', 'number')
|
||||
member_type = member_type.replace('uint64_t', 'number')
|
||||
member_type = member_type.replace('int8_t', 'number')
|
||||
member_type = member_type.replace('int16_t', 'number')
|
||||
member_type = member_type.replace('int32_t', 'number')
|
||||
member_type = member_type.replace('int64_t', 'number')
|
||||
member_type = member_type.replace('size_t', 'number')
|
||||
member_type = member_type.replace('uintptr_t', 'number')
|
||||
member_type = member_type.replace('...', 'string')
|
||||
member_type = member_type.replace('*', '')
|
||||
member_type = member_type.replace('&', '')
|
||||
member_type = member_type.replace('const', '')
|
||||
member_type = member_type.replace('bool', 'boolean')
|
||||
member_type = member_type.replace('int', 'number')
|
||||
member_type = member_type.replace('float', 'number')
|
||||
member_type = member_type.replace('char', 'string')
|
||||
member_type = member_type.replace('unsigned', 'number')
|
||||
member_type = member_type.replace('u8', 'number')
|
||||
member_type = member_type.replace('u16', 'number')
|
||||
member_type = member_type.replace('u32', 'number')
|
||||
member_type = member_type.replace('u64', 'number')
|
||||
member_type = member_type.replace('s8', 'number')
|
||||
member_type = member_type.replace('s16', 'number')
|
||||
member_type = member_type.replace('s32', 'number')
|
||||
member_type = member_type.replace('s64', 'number')
|
||||
member_type = member_type.replace('void', 'nil')
|
||||
member_type = member_type.replace('f32', 'number')
|
||||
member_type = member_type.replace('f64', 'number')
|
||||
member_type = member_type.replace('double', 'number')
|
||||
member_type = member_type.replace('CONTROLLERBUTTONS_T', 'number')
|
||||
|
||||
return member_type
|
||||
|
||||
blacklist = [
|
||||
'audio',
|
||||
'portable-file-dialogs.h',
|
||||
'rmonint.h',
|
||||
'PR/',
|
||||
'libultra/',
|
||||
'libc/',
|
||||
'dbgproto',
|
||||
'prevent',
|
||||
'piint',
|
||||
'siint',
|
||||
'sf64dma',
|
||||
'osint',
|
||||
'FrameInterpolation',
|
||||
'mods.h'
|
||||
]
|
||||
|
||||
def parse_enums(header, as_value=False):
|
||||
try:
|
||||
with open(header, 'r') as file:
|
||||
lines = file.readlines()
|
||||
except IOError:
|
||||
raise RuntimeError("Failed to open header files for enums node in config")
|
||||
|
||||
# Regex pattern to match enum declarations
|
||||
enum_regex = re.compile(r"enum\s+(\w+)\s*(?:\s*:\s*(\w+))?[\s\n\r]*\{")
|
||||
|
||||
in_enum = False
|
||||
enum_index = None
|
||||
enum_name = ""
|
||||
enum = {}
|
||||
|
||||
global export_type
|
||||
|
||||
for line in lines:
|
||||
line = line.strip()
|
||||
|
||||
if not in_enum:
|
||||
# Check if the line matches the enum declaration pattern
|
||||
match = enum_regex.search(line)
|
||||
if match and len(match.groups()) > 1:
|
||||
enum_name = match.group(1)
|
||||
enum[enum_name] = []
|
||||
in_enum = True
|
||||
enum_index = -1
|
||||
continue
|
||||
|
||||
if '}' in line:
|
||||
in_enum = False
|
||||
continue
|
||||
|
||||
# Remove any comments and non-alphanumeric characters
|
||||
line = re.sub(r'(/\*.*?\*/)|(//.*$)|([^a-zA-Z0-9=_\-\.])', '', line)
|
||||
|
||||
if len(line) == 0:
|
||||
continue
|
||||
|
||||
if '=' in line:
|
||||
# Extract the value after the '=' sign
|
||||
value = line.split('=')[1].strip()
|
||||
# Extract the name before the '=' sign
|
||||
name = line.split('=')[0].strip()
|
||||
enum_index = int(value, 0) # Convert the value to an integer with base 0 (detects hex, oct, etc.)
|
||||
enum[enum_name].append({
|
||||
'name': name,
|
||||
'value': enum_index
|
||||
})
|
||||
else:
|
||||
# Increment the enum index if no '=' is found
|
||||
enum_index += 1
|
||||
enum[enum_name].append({
|
||||
'name': line,
|
||||
'value': enum_index
|
||||
})
|
||||
|
||||
for enum_name, values in enum.items():
|
||||
if export_type == OutputType.CPP:
|
||||
print(f'auto enum_{enum_name} = lua["{enum_name}"].force();')
|
||||
for i, entry in enumerate(values):
|
||||
key = entry['name']
|
||||
value = entry['value']
|
||||
if 'ifdef' in key or 'endif' in entry['name'] or 'else' in key:
|
||||
continue
|
||||
key_name = key
|
||||
key_name = key_name.replace('EVENT_PRIORITY_', '')
|
||||
key_name = key_name.replace('SF64_VER_', '')
|
||||
print(f'enum_{enum_name}["{key_name}"] = (uint32_t) {value if as_value else key};')
|
||||
print('')
|
||||
elif export_type == OutputType.LUA:
|
||||
print(f'---@enum {enum_name}')
|
||||
print(f'{enum_name} = {{')
|
||||
for i, entry in enumerate(values):
|
||||
key = entry['name']
|
||||
value = entry['value']
|
||||
if 'ifdef' in key or 'endif' in entry['name'] or 'else' in key:
|
||||
continue
|
||||
key_name = key
|
||||
key_name = key_name.replace('EVENT_PRIORITY_', '')
|
||||
key_name = key_name.replace('SF64_VER_', '')
|
||||
print(f' {key_name} = {value}{"," if i < len(values) - 1 else ""}')
|
||||
print('}')
|
||||
print('')
|
||||
|
||||
def parse_structs(header):
|
||||
try:
|
||||
with open(header, 'r') as file:
|
||||
lines = file.readlines()
|
||||
except IOError:
|
||||
raise RuntimeError("Failed to open header files for structs node in config")
|
||||
|
||||
struct_regex = re.compile(r"struct\s+(\w+)\s*(?:\s*:\s*(\w+))?[\s\n\r]*\{")
|
||||
|
||||
in_struct = False
|
||||
struct_name = ""
|
||||
found_union = False
|
||||
struct = {}
|
||||
|
||||
global export_type
|
||||
|
||||
for line in lines:
|
||||
line = line.strip()
|
||||
|
||||
if not in_struct:
|
||||
match = struct_regex.search(line)
|
||||
if match and len(match.groups()) > 1:
|
||||
struct_name = match.group(1)
|
||||
struct[struct_name] = []
|
||||
in_struct = True
|
||||
continue
|
||||
|
||||
if 'union' in line:
|
||||
found_union = True
|
||||
continue
|
||||
|
||||
if '}' in line and not '{' in line and not found_union:
|
||||
in_struct = False
|
||||
continue
|
||||
|
||||
if '}' in line and found_union:
|
||||
found_union = False
|
||||
continue
|
||||
|
||||
line = re.sub(r'(/\*.*?\*/)', '', line)
|
||||
|
||||
if ';' in line:
|
||||
if ':' in line and not 'sol:not_global' in line and not '::' in line:
|
||||
line = line.replace(' : ', ':')
|
||||
bitfield = line.split(':')[1].split(';')[0].strip()
|
||||
size = int(bitfield)
|
||||
struct[struct_name].append({
|
||||
'name': line.split(':')[0].split(' ')[-1],
|
||||
'export': 'bitfield',
|
||||
'type': sanitize_type('u8' if size < 8 else 'u16' if size < 16 else 'u32' if size < 32 else 'u64')
|
||||
})
|
||||
elif '(' in line:
|
||||
struct[struct_name].append({
|
||||
'name': f'{line.split('(')[0].split(' ')[-1]}',
|
||||
'export': 'function',
|
||||
'type': sanitize_type(line.split('(')[0].split(' ')[-2])
|
||||
})
|
||||
elif '[' in line:
|
||||
if len(line.split('[')) > 2:
|
||||
continue
|
||||
struct[struct_name].append({
|
||||
'name': line.split('[')[0].split(' ')[-1],
|
||||
'export': 'variable',
|
||||
'type': sanitize_type(line.split('[')[0].split(' ')[-2])
|
||||
})
|
||||
else:
|
||||
struct[struct_name].append({
|
||||
'name': line.split(';')[0].split(' ')[-1],
|
||||
'export': 'variable',
|
||||
'type': sanitize_type(line.split(';')[0].split(' ')[-2])
|
||||
})
|
||||
|
||||
for struct_name, members in struct.items():
|
||||
if len(members) == 0:
|
||||
continue
|
||||
|
||||
if export_type == OutputType.CPP:
|
||||
print(f'lua.new_usertype<{struct_name}>("{struct_name}",')
|
||||
for i, member in enumerate(members):
|
||||
key = member['name'].replace('*', '')
|
||||
export = member['export']
|
||||
type = member['type']
|
||||
if export == 'bitfield':
|
||||
print(f' "{key}", sol::property([] ({struct_name}& self) -> {type} {{ return self.{key}; }}, [] ({struct_name}& self, {type} value) {{ self.{key} = value; }}){"," if i < len(members) - 1 else ""}')
|
||||
elif export == 'function':
|
||||
print(f' "{key}", &{struct_name}::{key}{"," if i < len(members) - 1 else ""}')
|
||||
else:
|
||||
print(f' "{key}", sol::property(&{struct_name}::{key}, &{struct_name}::{key}){"," if i < len(members) - 1 else ""}')
|
||||
print(');')
|
||||
print('')
|
||||
elif export_type == OutputType.LUA:
|
||||
print(f'---@class {struct_name}')
|
||||
print(f'{struct_name} = {{}}')
|
||||
for i, member in enumerate(members):
|
||||
key = member['name'].replace('*', '')
|
||||
export = member['export']
|
||||
type = member['type']
|
||||
if export == 'bitfield':
|
||||
print(f'---@return {type}')
|
||||
print(f'function {struct_name}:{key}() end')
|
||||
print(f'---@param value {type}')
|
||||
print(f'---@return {type}')
|
||||
print(f'function {struct_name}:{key}(value) end')
|
||||
elif export == 'function':
|
||||
print(f'---@return {type}')
|
||||
print(f'function {struct_name}:{key}() end')
|
||||
else:
|
||||
print(f'---@field {key} {type}')
|
||||
print('')
|
||||
|
||||
def parse_events(header):
|
||||
try:
|
||||
with open(header, 'r') as file:
|
||||
lines = file.readlines()
|
||||
except IOError:
|
||||
raise RuntimeError("Failed to open header files for events node in config")
|
||||
|
||||
in_event = False
|
||||
event_name = ""
|
||||
event = {}
|
||||
|
||||
global export_type
|
||||
|
||||
for line in lines:
|
||||
line = line.strip()
|
||||
if not in_event:
|
||||
if 'DEFINE_EVENT' in line:
|
||||
if ');' in line:
|
||||
event_name = line.split('DEFINE_EVENT(')[1].split(')')[0].strip()
|
||||
event[event_name] = ['event']
|
||||
continue
|
||||
event_name = line.split('DEFINE_EVENT(')[1].split(',')[0].strip()
|
||||
event[event_name] = ['event']
|
||||
in_event = True
|
||||
continue
|
||||
|
||||
if ');' in line:
|
||||
in_event = False
|
||||
continue
|
||||
|
||||
if len(line) == 0:
|
||||
continue
|
||||
|
||||
if ';' in line:
|
||||
member_name = line.split(';')[0].split(' ')[-1]
|
||||
event[event_name].append(member_name)
|
||||
|
||||
for event_name, members in event.items():
|
||||
print(f'lua.new_usertype<{event_name}>("{event_name}",')
|
||||
for i, key in enumerate(members):
|
||||
key = key.replace('*', '')
|
||||
print(f' "{key}", sol::property(&{event_name}::{key}, &{event_name}::{key}){"," if i < len(members) - 1 else ""}')
|
||||
print(');')
|
||||
print('')
|
||||
|
||||
def parse_externs(header, namespace=None):
|
||||
try:
|
||||
with open(header, 'r') as file:
|
||||
lines = file.readlines()
|
||||
except IOError:
|
||||
raise RuntimeError("Failed to open header files for events node in config")
|
||||
|
||||
global export_type
|
||||
|
||||
for line in lines:
|
||||
line = re.sub(r'\s+', ' ', line.strip())
|
||||
if line.startswith('extern') and not 'void*' in line and not '"C"' in line or ('(' in line and ';' in line):
|
||||
if not '(' in line and not '[' in line:
|
||||
var_type = line.split(' ')[1]
|
||||
var_name = line.split(' ')[2].split(';')[0]
|
||||
if export_type == OutputType.CPP:
|
||||
print(f'lua["Game"]["{var_name}"] = sol::overload([]() -> {var_type} {{ return {var_name}; }}, []({var_type} value) {{ {var_name} = value; }});')
|
||||
elif export_type == OutputType.LUA:
|
||||
print(f'---@return {sanitize_type(var_type)}')
|
||||
print(f'function Game.{var_name}() end')
|
||||
print(f'---@param value {sanitize_type(var_type)}')
|
||||
print(f'function Game.{var_name}(value) end')
|
||||
elif '[' in line and not '(' in line:
|
||||
dimension_len = len(line.split('[')) - 1
|
||||
var_name = line.split('[')[0].split(' ')[-1]
|
||||
var_type = line.split(' ')[1]
|
||||
is_pointer = True #'*' in line
|
||||
if export_type == OutputType.CPP:
|
||||
if dimension_len == 1:
|
||||
print(f'lua["Game"]["{var_name}"] = sol::overload([](int index) -> {var_type}{'' if is_pointer else '*'} {{ return {'' if is_pointer else '&'}{var_name}[index]; }}, [](int index, {var_type} value) {{ {var_name}[index] = value; }});')
|
||||
elif dimension_len == 2:
|
||||
print(f'lua["Game"]["{var_name}"] = sol::overload([](int index1, int index2) -> {var_type}{'' if is_pointer else '*'} {{ return {'' if is_pointer else '&'}{var_name}[index1][index2]; }}, [](int index1, int index2, {var_type} value) {{ {var_name}[index1][index2] = value; }});')
|
||||
elif dimension_len == 3:
|
||||
print('Unsupported 3D array')
|
||||
exit()
|
||||
elif export_type == OutputType.LUA:
|
||||
print(f'---@param index number')
|
||||
print(f'---@return {sanitize_type(var_type)}[{dimension_len}]')
|
||||
print(f'function Game.{var_name}(index) end')
|
||||
print(f'---@param index number')
|
||||
print(f'---@param value {sanitize_type(var_type)}')
|
||||
print(f'function Game.{var_name}(index, value) end')
|
||||
elif '(' in line:
|
||||
if 'ALIGN_ASSET' in line:
|
||||
var_name = line.split('[')[0].split(' ')[-1]
|
||||
value = line.split('=')[-1].split(';')[0]
|
||||
if export_type == OutputType.CPP:
|
||||
print(f'lua["Assets"]["{var_name}"] = Asset{{ {var_name} }};')
|
||||
elif export_type == OutputType.LUA:
|
||||
print('---@type Asset')
|
||||
print(f'Assets.{var_name} = {value.strip()}')
|
||||
continue
|
||||
if 'define' in line or '\\' in line or 'typedef' in line or '[' in line or 'OSMesg' in line or 'Framebuffer' in line or 'TimerAction' in line or 'TimerTask' in line:
|
||||
continue
|
||||
if '_DEG' in line or 'Fault' in line or 'sol:ignore' in line or 'sol:not_global' in line or '<T>' in line:
|
||||
continue
|
||||
func_name = line.split('(')[0].split(' ')[-1]
|
||||
|
||||
if len(func_name) == 0:
|
||||
continue
|
||||
if 'CVarExists' in func_name or 'ResourceLoad' in func_name or 'void*' in func_name or 'ResourceClearCache' in func_name: # Report this to LUS
|
||||
continue
|
||||
|
||||
if export_type == OutputType.CPP:
|
||||
if namespace:
|
||||
print(f'lua["{namespace}"]["{func_name}"] = {namespace}::{func_name};')
|
||||
else:
|
||||
print(f'lua.set_function("{func_name}", {func_name});')
|
||||
elif export_type == OutputType.LUA:
|
||||
return_type = line.split(' ')[0]
|
||||
args = line.split('(')[1].split(')')[0].strip().split(',')
|
||||
for i, arg in enumerate(args):
|
||||
arg = arg.replace('const ', '')
|
||||
arg = arg.replace(' *', '* ')
|
||||
arg = arg.replace('...', 'varargs')
|
||||
if len(arg.split(' ')) > 2:
|
||||
if '=' in arg:
|
||||
arg = arg.split('=')[0]
|
||||
name = arg.split(' ')[2]
|
||||
type = arg.split(' ')[1]
|
||||
else:
|
||||
name = arg.split(' ')[-1]
|
||||
type = arg.split(' ')[-2]
|
||||
else:
|
||||
name = '_'+arg.split(' ')[-1]
|
||||
type = arg.split(' ')[0]
|
||||
|
||||
name = name.replace('*', '')
|
||||
name = name.replace('end', '_end')
|
||||
if(len(name) == 0):
|
||||
name = f'arg{i}'
|
||||
args[i] = { 'name': name, 'type': type }
|
||||
|
||||
for i, arg in enumerate(args):
|
||||
print(f'---@param {arg["name"]} {sanitize_type(arg["type"])}')
|
||||
|
||||
print(f'---@return {sanitize_type(return_type)}')
|
||||
if namespace:
|
||||
print(f'function {namespace}.{func_name}({', '.join([f'{arg["name"]}' for arg in args])}) end')
|
||||
else:
|
||||
print(f'function {func_name}({', '.join([f'{arg["name"]}' for arg in args])}) end')
|
||||
|
||||
def is_blacklisted(file):
|
||||
for item in blacklist:
|
||||
if item in file:
|
||||
return True
|
||||
return False
|
||||
|
||||
if __name__ == "__main__":
|
||||
if len(sys.argv) < 2:
|
||||
print("Usage: python autobind.py <output_type>")
|
||||
exit()
|
||||
|
||||
export_type = OutputType.LUA if sys.argv[1] == 'lua' else OutputType.CPP
|
||||
|
||||
if export_type == OutputType.LUA:
|
||||
write_lua_header()
|
||||
|
||||
for root, dirs, files in os.walk("include"):
|
||||
for file in files:
|
||||
# Join root and file to get full path
|
||||
|
@ -451,8 +529,9 @@ function gDPSetPrimColor(m, l, r, g, b, a) end
|
|||
for file in files:
|
||||
parse_events(os.path.join(root, file))
|
||||
|
||||
print('---@enum EventID')
|
||||
print('EventID = {')
|
||||
for event_name in event_list:
|
||||
print(f' {event_name} = -1' + (',' if event_name != event_list[-1] else ''))
|
||||
print('}')
|
||||
if export_type == OutputType.LUA:
|
||||
print('---@enum EventID')
|
||||
print('EventID = {')
|
||||
for event_name in event_list:
|
||||
print(f' {event_name} = -1' + (',' if event_name != event_list[-1] else ''))
|
||||
print('}')
|
301
tools/def2sol.py
301
tools/def2sol.py
|
@ -1,301 +0,0 @@
|
|||
import re
|
||||
import os
|
||||
|
||||
blacklist = [
|
||||
'audio',
|
||||
'portable-file-dialogs.h',
|
||||
'rmonint.h',
|
||||
'PR/',
|
||||
'libultra/',
|
||||
'libc/',
|
||||
'dbgproto',
|
||||
'prevent',
|
||||
'piint',
|
||||
'siint',
|
||||
'sf64dma',
|
||||
'osint',
|
||||
'FrameInterpolation',
|
||||
'mods.h'
|
||||
]
|
||||
|
||||
def parse_enums(header, as_value=False):
|
||||
try:
|
||||
with open(header, 'r') as file:
|
||||
lines = file.readlines()
|
||||
except IOError:
|
||||
raise RuntimeError("Failed to open header files for enums node in config")
|
||||
|
||||
# Regex pattern to match enum declarations
|
||||
enum_regex = re.compile(r"enum\s+(\w+)\s*(?:\s*:\s*(\w+))?[\s\n\r]*\{")
|
||||
|
||||
in_enum = False
|
||||
enum_index = None
|
||||
enum_name = ""
|
||||
enum = {}
|
||||
|
||||
for line in lines:
|
||||
line = line.strip()
|
||||
|
||||
if not in_enum:
|
||||
# Check if the line matches the enum declaration pattern
|
||||
match = enum_regex.search(line)
|
||||
if match and len(match.groups()) > 1:
|
||||
enum_name = match.group(1)
|
||||
enum[enum_name] = []
|
||||
in_enum = True
|
||||
enum_index = -1
|
||||
continue
|
||||
|
||||
if '}' in line:
|
||||
in_enum = False
|
||||
continue
|
||||
|
||||
# Remove any comments and non-alphanumeric characters
|
||||
line = re.sub(r'(/\*.*?\*/)|(//.*$)|([^a-zA-Z0-9=_\-\.])', '', line)
|
||||
|
||||
if len(line) == 0:
|
||||
continue
|
||||
|
||||
if '=' in line:
|
||||
# Extract the value after the '=' sign
|
||||
value = line.split('=')[1].strip()
|
||||
# Extract the name before the '=' sign
|
||||
name = line.split('=')[0].strip()
|
||||
enum_index = int(value, 0) # Convert the value to an integer with base 0 (detects hex, oct, etc.)
|
||||
enum[enum_name].append({
|
||||
'name': name,
|
||||
'value': enum_index
|
||||
})
|
||||
else:
|
||||
# Increment the enum index if no '=' is found
|
||||
enum_index += 1
|
||||
enum[enum_name].append({
|
||||
'name': line,
|
||||
'value': enum_index
|
||||
})
|
||||
|
||||
for enum_name, values in enum.items():
|
||||
print(f'auto enum_{enum_name} = lua["{enum_name}"].force();')
|
||||
for i, entry in enumerate(values):
|
||||
key = entry['name']
|
||||
value = entry['value']
|
||||
if 'ifdef' in key or 'endif' in entry['name'] or 'else' in key:
|
||||
continue
|
||||
key_name = key
|
||||
key_name = key_name.replace('EVENT_PRIORITY_', '')
|
||||
key_name = key_name.replace('SF64_VER_', '')
|
||||
print(f'enum_{enum_name}["{key_name}"] = (uint32_t) {value if as_value else key};')
|
||||
print('')
|
||||
|
||||
def parse_structs(header):
|
||||
try:
|
||||
with open(header, 'r') as file:
|
||||
lines = file.readlines()
|
||||
except IOError:
|
||||
raise RuntimeError("Failed to open header files for structs node in config")
|
||||
|
||||
struct_regex = re.compile(r"struct\s+(\w+)\s*(?:\s*:\s*(\w+))?[\s\n\r]*\{")
|
||||
|
||||
in_struct = False
|
||||
struct_name = ""
|
||||
found_union = False
|
||||
struct = {}
|
||||
|
||||
for line in lines:
|
||||
line = line.strip()
|
||||
|
||||
if not in_struct:
|
||||
match = struct_regex.search(line)
|
||||
if match and len(match.groups()) > 1:
|
||||
struct_name = match.group(1)
|
||||
struct[struct_name] = []
|
||||
in_struct = True
|
||||
continue
|
||||
|
||||
if 'union' in line:
|
||||
found_union = True
|
||||
continue
|
||||
|
||||
if '}' in line and not found_union:
|
||||
in_struct = False
|
||||
continue
|
||||
|
||||
if '}' in line and found_union:
|
||||
found_union = False
|
||||
continue
|
||||
|
||||
line = re.sub(r'(/\*.*?\*/)', '', line)
|
||||
|
||||
if ';' in line and not ':' in line:
|
||||
# if ':' in line:
|
||||
# member_name = line.split(' ')[-3].split(':')[0]
|
||||
# continue
|
||||
if '[' in line:
|
||||
if len(line.split('[')) > 2:
|
||||
continue
|
||||
member_name = line.split('[')[0].split(' ')[-1]
|
||||
else:
|
||||
member_name = line.split(';')[0].split(' ')[-1]
|
||||
struct[struct_name].append(member_name)
|
||||
|
||||
for struct_name, members in struct.items():
|
||||
if len(members) == 0:
|
||||
continue
|
||||
# TODO: Add support for functions
|
||||
print(f'lua.new_usertype<{struct_name}>("{struct_name}",')
|
||||
for i, key in enumerate(members):
|
||||
key = key.replace('*', '')
|
||||
print(f' "{key}", sol::property(&{struct_name}::{key}, &{struct_name}::{key}){"," if i < len(members) - 1 else ""}')
|
||||
if struct_name == 'Object':
|
||||
print(f' ,"asActor", &{struct_name}::asActor,')
|
||||
print(f' "asBoss", &{struct_name}::asBoss,')
|
||||
print(f' "asScenery", &{struct_name}::asScenery,')
|
||||
print(f' "asScenery360", &{struct_name}::asScenery360,')
|
||||
print(f' "asSprite", &{struct_name}::asSprite,')
|
||||
print(f' "asItem", &{struct_name}::asItem,')
|
||||
print(f' "asEffect", &{struct_name}::asEffect,')
|
||||
print(f' "asRef", &{struct_name}::asRef')
|
||||
elif struct_name == 'Object' or struct_name == 'ObjectInfo' or struct_name == 'Actor' or struct_name == 'Boss' or struct_name == 'Scenery' or struct_name == 'Scenery360' or struct_name == 'Sprite' or struct_name == 'Item' or struct_name == 'Effect':
|
||||
print(f' ,"asRef", &{struct_name}::asRef')
|
||||
elif struct_name.startswith('Vec') or struct_name.startswith('Plane') or struct_name == 'PosRot' or struct_name == 'CameraPoint' or struct_name == 'Triangle':
|
||||
print(f' ,"asRef", &{struct_name}::asRef')
|
||||
if struct_name.startswith('Vec'):
|
||||
print(f' ,"xRef", &{struct_name}::xRef,')
|
||||
print(f' "yRef", &{struct_name}::yRef,')
|
||||
print(f' "zRef", &{struct_name}::zRef')
|
||||
print(');')
|
||||
print('')
|
||||
|
||||
def parse_events(header):
|
||||
try:
|
||||
with open(header, 'r') as file:
|
||||
lines = file.readlines()
|
||||
except IOError:
|
||||
raise RuntimeError("Failed to open header files for events node in config")
|
||||
|
||||
in_event = False
|
||||
event_name = ""
|
||||
event = {}
|
||||
|
||||
for line in lines:
|
||||
line = line.strip()
|
||||
if not in_event:
|
||||
if 'DEFINE_EVENT' in line:
|
||||
if ');' in line:
|
||||
event_name = line.split('DEFINE_EVENT(')[1].split(')')[0].strip()
|
||||
event[event_name] = ['event']
|
||||
continue
|
||||
event_name = line.split('DEFINE_EVENT(')[1].split(',')[0].strip()
|
||||
event[event_name] = ['event']
|
||||
in_event = True
|
||||
continue
|
||||
|
||||
if ');' in line:
|
||||
in_event = False
|
||||
continue
|
||||
|
||||
if len(line) == 0:
|
||||
continue
|
||||
|
||||
if ';' in line:
|
||||
member_name = line.split(';')[0].split(' ')[-1]
|
||||
event[event_name].append(member_name)
|
||||
|
||||
for event_name, members in event.items():
|
||||
# print(f'lua["{event_name}ID"] = {event_name}ID;')
|
||||
print(f'lua.new_usertype<{event_name}>("{event_name}",')
|
||||
for i, key in enumerate(members):
|
||||
key = key.replace('*', '')
|
||||
print(f' "{key}", sol::property(&{event_name}::{key}, &{event_name}::{key}){"," if i < len(members) - 1 else ""}')
|
||||
print(');')
|
||||
print('')
|
||||
|
||||
def parse_externs(header, namespace=None):
|
||||
try:
|
||||
with open(header, 'r') as file:
|
||||
lines = file.readlines()
|
||||
except IOError:
|
||||
raise RuntimeError("Failed to open header files for events node in config")
|
||||
|
||||
for line in lines:
|
||||
line = re.sub(r'\s+', ' ', line.strip())
|
||||
if line.startswith('extern') and not 'void*' in line and not '"C"' in line or ('(' in line and ';' in line):
|
||||
if not '(' in line and not '[' in line:
|
||||
var_type = line.split(' ')[1]
|
||||
var_name = line.split(' ')[2].split(';')[0]
|
||||
# if '*' in line:
|
||||
# print(f'lua["Game"]["{var_name}"] = {var_name};')
|
||||
# else:
|
||||
# print(f'lua["Game"]["{var_name}"] = &{var_name};')
|
||||
print(f'lua["Game"]["{var_name}"] = sol::overload([]() -> {var_type} {{ return {var_name}; }}, []({var_type} value) {{ {var_name} = value; }});')
|
||||
|
||||
# print(f'context["{var_name}"] = sol::property([]() -> {var_type} {{ return {var_name}; }}, []({var_type} value) {{ {var_name} = value; }});')
|
||||
# print(f'lua["{var_name}"] = std::ref({var_name});')
|
||||
# print(f'lua["{var_name}"] = sol::as_pointer({var_name});')
|
||||
# print(f'lua.set("{var_name}", sol::var({var_name}));')
|
||||
elif '[' in line and not '(' in line:
|
||||
dimension_len = len(line.split('[')) - 1
|
||||
var_name = line.split('[')[0].split(' ')[-1]
|
||||
var_type = line.split(' ')[1]
|
||||
is_pointer = True #'*' in line
|
||||
if dimension_len == 1:
|
||||
print(f'lua["Game"]["{var_name}"] = sol::overload([](int index) -> {var_type}{'' if is_pointer else '*'} {{ return {'' if is_pointer else '&'}{var_name}[index]; }}, [](int index, {var_type} value) {{ {var_name}[index] = value; }});')
|
||||
elif dimension_len == 2:
|
||||
print(f'lua["Game"]["{var_name}"] = sol::overload([](int index1, int index2) -> {var_type}{'' if is_pointer else '*'} {{ return {'' if is_pointer else '&'}{var_name}[index1][index2]; }}, [](int index1, int index2, {var_type} value) {{ {var_name}[index1][index2] = value; }});')
|
||||
elif dimension_len == 3:
|
||||
print('Unsupported 3D array')
|
||||
exit()
|
||||
elif '(' in line:
|
||||
if 'ALIGN_ASSET' in line:
|
||||
var_name = line.split('[')[0].split(' ')[-1]
|
||||
# print(f'lua["Assets"]["{var_name}"] = {var_name};')
|
||||
print(f'lua["Assets"]["{var_name}"] = Asset{{ {var_name} }};')
|
||||
continue
|
||||
if 'define' in line or '\\' in line or 'typedef' in line or '[' in line or 'OSMesg' in line or 'Framebuffer' in line or 'TimerAction' in line or 'TimerTask' in line:
|
||||
continue
|
||||
if '_DEG' in line or 'Fault' in line or 'sol:ignore' in line or '<T>' in line:
|
||||
continue
|
||||
func_name = line.split('(')[0].split(' ')[-1]
|
||||
# print('Function:', func_name)
|
||||
if len(func_name) == 0:
|
||||
continue
|
||||
if 'CVarExists' in func_name or 'ResourceLoad' in func_name or 'void*' in func_name or 'ResourceClearCache' in func_name: # Report this to LUS
|
||||
continue
|
||||
|
||||
if namespace:
|
||||
print(f'lua["{namespace}"]["{func_name}"] = {namespace}::{func_name};')
|
||||
else:
|
||||
print(f'lua.set_function("{func_name}", {func_name});')
|
||||
|
||||
def is_blacklisted(file):
|
||||
for item in blacklist:
|
||||
if item in file:
|
||||
return True
|
||||
return False
|
||||
|
||||
if __name__ == "__main__":
|
||||
for root, dirs, files in os.walk("include"):
|
||||
for file in files:
|
||||
# Join root and file to get full path
|
||||
file_path = os.path.join(root, file)
|
||||
# Check if the file is blacklisted
|
||||
if(is_blacklisted(file_path)):
|
||||
continue
|
||||
|
||||
parse_enums(file_path, True if 'scripting.h' in file_path else False)
|
||||
parse_structs(file_path)
|
||||
parse_externs(file_path)
|
||||
|
||||
parse_enums("src/port/hooks/impl/EventSystem.h")
|
||||
parse_structs("src/port/hooks/impl/EventSystem.h")
|
||||
parse_externs("libultraship/src/public/bridge/consolevariablebridge.h")
|
||||
|
||||
parse_enums("src/port/Engine.h")
|
||||
parse_externs("src/port/Engine.h")
|
||||
parse_externs("src/port/ui/UIWidgets.h", 'UIWidgets')
|
||||
parse_externs("libultraship/src/public/bridge/resourcebridge.h")
|
||||
|
||||
for root, dirs, files in os.walk("src/port/hooks/list"):
|
||||
for file in files:
|
||||
parse_events(os.path.join(root, file))
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue