Merge branch 'coop' into coopnet

This commit is contained in:
MysterD 2023-04-14 10:53:58 -07:00
commit 6c7e7778d1
69 changed files with 563 additions and 290 deletions

View file

@ -11522,7 +11522,7 @@ MAX_LOCAL_VERSION_LENGTH = 12
MAX_VERSION_LENGTH = 10 MAX_VERSION_LENGTH = 10
--- @type integer --- @type integer
MINOR_VERSION_NUMBER = 0 MINOR_VERSION_NUMBER = 1
--- @type integer --- @type integer
PATCH_VERSION_NUMBER = 0 PATCH_VERSION_NUMBER = 0

View file

@ -222,8 +222,12 @@ function djui_hud_render_texture_tile_interpolated(texInfo, prevX, prevY, prevSc
end end
--- @param levelNum number --- @param levelNum number
--- @param func fun(areaNum:number, bhv:table) --- @param func fun(areaIndex:number, bhvData:table, macroBhvIds:table, macroBhvArgs:table)
--- @return nil --- @return nil
--- When `func` is called, arguments are filled depending on the level command:
--- - `AREA` command: only `areaIndex` is filled. It's a number.
--- - `OBJECT` command: only `bhvData` is filled. `bhvData` is a table with two fields: `behavior` and `behaviorArg`.
--- - `MACRO` command: only `macroBhvIds` and `macroBhvArgs` are filled. `macrobhvIds` is a list of behavior ids. `macroBhvArgs` is a list of behavior params. Both lists have the same size and start at index 0.
function level_script_parse(levelNum, func) function level_script_parse(levelNum, func)
-- ... -- ...
end end

View file

@ -2,47 +2,47 @@
CONNECTED = "@ se ha conectado" CONNECTED = "@ se ha conectado"
DISCONNECTED = "@ se ha desconectado" DISCONNECTED = "@ se ha desconectado"
LEFT_THIS_LEVEL = "@ ha salido del nivel" LEFT_THIS_LEVEL = "@ ha salido del nivel"
ENTERED_THIS_LEVEL = "@ ha entrado al nivel" ENTERED_THIS_LEVEL = "@ se ha unido a tu nivel"
ENTERED = "@ se ha unido\n#" ENTERED = "@ ha entrado a \n#"
SERVER_CLOSED = "\\#ffa0a0\\Desconectado:\\#dcdcdc\\ servidor cerrado" SERVER_CLOSED = "\\#ffa0a0\\Desconectado:\\#dcdcdc\\ El servidor ha sido cerrado."
DISCORD_ERROR = "Discord ha lanzado un error.\nPara solucionarlo, intenta: \n1. Cerrar el juego.\n2. Reiniciar Discord.\n3. Iniciar el juego." DISCORD_ERROR = "Discord ha lanzado un error.\nPara solucionarlo, intenta: \n1. Cerrar el juego.\n2. Reiniciar Discord.\n3. Iniciar el juego."
DISCORD_DETECT = "\\#ffa0a0\\Error:\\#c8c8c8\\ No se ha podido detectar Discord.\n\\#a0a0a0\\Prueba a cerrar el juego, reiniciar Discord, e iniciar el juego otra vez." DISCORD_DETECT = "\\#ffa0a0\\Error:\\#c8c8c8\\ No se ha podido detectar Discord.\n\\#a0a0a0\\Prueba a cerrar el juego, reiniciar Discord, e iniciar el juego otra vez."
DISCONNECT_FULL = "\\#ffa0a0\\Desconectado:\\#c8c8c8\\ La partida está llena." DISCONNECT_FULL = "\\#ffa0a0\\Desconectado:\\#c8c8c8\\ La partida está llena"
DISCONNECT_KICK = "\\#ffa0a0\\Desconectado:\\#c8c8c8\\ Has sido expulsado del servidor." DISCONNECT_KICK = "\\#ffa0a0\\Desconectado:\\#c8c8c8\\ has sido\nexpulsado del servidor"
DISCONNECT_BAN = "\\#ffa0a0\\Desconectado:\\#c8c8c8\\ Has sido vetado del servidor." DISCONNECT_BAN = "\\#ffa0a0\\Desconectado:\\#c8c8c8\\ has sido\nbaneado del servidor"
DISCONNECT_REJOIN = "\\#ffa0a0\\Desconectado:\\#c8c8c8\\ Uniendose de nuevo..." DISCONNECT_REJOIN = "\\#ffa0a0\\Desconectado:\\#c8c8c8\\ Uniéndose de nuevo..."
DISCONNECT_CLOSED = "\\#ffa0a0\\Desconectado:\\#c8c8c8\\ El anfitrión ha cerrado la conexion." DISCONNECT_CLOSED = "\\#ffa0a0\\Desconectado:\\#c8c8c8\\ El alfitrión ha cerrado el servidor"
DISCONNECT_BIG_MOD = "El servidor tenía un mod demasiado pesado.\nSaliendo." DISCONNECT_BIG_MOD = "\\#ffa0a0\\Desconectado:\\#c8c8c8\\ El servidor tenía\nun mod demasiado pesado"
DIED = "@ ha muerto" DIED = "@ ha muerto."
DEBUG_FLY = "@ está en estado de vuelo libre debug" DEBUG_FLY = "@ Está en estado de vuelo libre debug."
IMPORT_MOD_SUCCESS = "\\#a0ffa0\\Mod \n\\#c8c8c8\\'@'\n\\#a0ffa0\\Importado" IMPORT_MOD_SUCCESS = "El mod \\#c8c8c8\\'@'\\#a0ffa0\\\nha sido importado con éxito."
IMPORT_DYNOS_SUCCESS = "\\#a0ffa0\\DynOS pack \n\\#c8c8c8\\'@'\n\\#a0ffa0\\Importado" IMPORT_DYNOS_SUCCESS = "El pack de DynOS \\#c8c8c8\\'@'\\#a0ffa0\\\nha sido importado con éxito."
IMPORT_FAIL = "\\#ffa0a0\\Fallo al importar \\#c8c8c8\\\n'@'" IMPORT_FAIL = "\n\\#ffa0a0\\Error al importar archivo. \\#c8c8c8\\\n'@'"
IMPORT_FAIL_INGAME = "\\#ffa0a0\\No se puede importar mientras se está en juego" IMPORT_FAIL_INGAME = "\\#ffa0a0\\No se pueden importar archivos\nen medio de una partida."
[CHAT] [CHAT]
KICKING = Expulsando a '@'!" KICKING = '@' ha sido expulsado!"
BANNING = Vetando a '@'!" BANNING = '@' ha sido baneado!"
SERVER_ONLY = "Solo el servidor puede usar este comando." SERVER_ONLY = "Solo el anfitrión puede usar este comando."
PERM_BANNING = Vetando permanentemente a '@'!" PERM_BANNING = '@' ha sido baneado permanentemente!"
ADD_MODERATOR = Añadiendo a '@' como Moderador!" ADD_MODERATOR = '@' ahora es un moderador!"
PLAYERS = "Jugadores" PLAYERS = "Jugadores"
NO_PERMS = "No tienes permiso para usar este comando." NO_PERMS = "No tienes permiso para usar este comando."
PLAYER_NOT_FOUND = "No se ha podido encontrar al jugador." PLAYER_NOT_FOUND = "No se ha podido encontrar al jugador."
SELF_KICK = "No te puedes expulsar a tí mismo." SELF_KICK = "No te puedes expulsar a tí mismo."
SELF_BAN = "No te puedes vetar a tí mismo." SELF_BAN = "No te puedes banear a tí mismo."
SELF_MOD = "No te puedes hacerte moderador a tí mismo." SELF_MOD = "No puedes hacerte moderador a tí mismo."
KICK_CONFIRM = "¿Seguro que quieres expulsar a '@'?\nEscribe '\\#a0ffa0\\/confirm\\#fff982\\' para expusar." KICK_CONFIRM = "¿Seguro que quieres expulsar a '@'?\nEscribe '\\#a0ffa0\\/confirm\\#fff982\\' para expulsar."
BAN_CONFIRM = "¿Seguro que quieres vetar a '@'?\nEscribe '\\#a0ffa0\\/confirm\\#fff982\\' para vetar." BAN_CONFIRM = "¿Seguro que quieres banear a '@'?\nEscribe '\\#a0ffa0\\/confirm\\#fff982\\' para banear."
PERM_BAN_CONFIRM = "¿Seguro que quieres vetar permanentemente a '@'?\nEscribe '\\#a0ffa0\\/confirm\\#fff982\\' para vetar." PERM_BAN_CONFIRM = "¿Seguro que quieres banear permanentemente a '@'?\nEscribe '\\#a0ffa0\\/confirm\\#fff982\\' para banear."
MOD_CONFIRM = "¿Seguro que quieres convertir a '@' en moderador?\Escribe '\\#a0ffa0\\/confirm\\#fff982\\'." MOD_CONFIRM = "¿Seguro que quieres hacer moderador a '@'?\nEscribe '\\#a0ffa0\\/confirm\\#fff982\\'."
PLAYERS_DESC = "/players - Mostrar lista de todos los jugadores y sus IDs" PLAYERS_DESC = "/players - Muestra la lista de todos los jugadores y sus IDs."
KICK_DESC = "/kick [NAME|ID] - Expulsar al jugador de la partida actual" KICK_DESC = "/kick [NAME|ID] - Expulsa al jugador de la partida actual."
BAN_DESC = "/ban [NAME|ID] - Vetar al jugador de la partida actual" BAN_DESC = "/ban [NAME|ID] - Banea al jugador de la partida actual."
PERM_BAN_DESC = "/permban [NAME|ID] - Vetar al jugador de todas tus partidas" PERM_BAN_DESC = "/permban [NAME|ID] - Banea al jugador de todas tus partidas."
MOD_DESC = "/moderator [NAME|ID] - Permitir a este jugador usar comandos como /kick, /ban o /permban de cualquier juego que alojes" MOD_DESC = "/moderator [NAME|ID] - Permite a un jugador usar comandos como /kick, /ban o /permban de cualquier partida que crees."
UNRECOGNIZED = "Comando de chat desconocido." UNRECOGNIZED = "Comando desconocido."
MOD_GRANTED = "\\#fff982\\Ahora eres un Moderador." MOD_GRANTED = "\\#fff982\\Ahora eres un moderador."
[MENU] [MENU]
BACK = "Volver" BACK = "Volver"
@ -52,37 +52,37 @@ YES = "Sí"
[CAMERA] [CAMERA]
CAMERA = "CÁMARA" CAMERA = "CÁMARA"
FREE_CAMERA = "Cámara Libre" FREE_CAMERA = "Cámara libre"
ANALOG_CAMERA = "Cámara Analógica" ANALOG_CAMERA = "Cámara analógica"
MOUSE_LOOK = "Moviemiento con Ratón" MOUSE_LOOK = "Movimiento con mouse"
INVERT_X = "Invertir eje X" INVERT_X = "Invertir eje X"
INVERT_Y = "Invertir eje Y" INVERT_Y = "Invertir eje Y"
X_SENSITIVITY = "Sensibilidad Eje X" X_SENSITIVITY = "Sensibilidad eje X"
Y_SENSITIVITY = "Sensibilidad Eje Y" Y_SENSITIVITY = "Sensibilidad eje Y"
AGGRESSION = "Agresíon" AGGRESSION = "Agresn"
PAN_LEVEL = "Nivel Seguimiento" PAN_LEVEL = "Nivel de seguimiento"
DECELERATION = "Deceleración" DECELERATION = "Deceleración"
[CHEATS] [CHEATS]
CHEATS = "TRUCOS" CHEATS = "TRUCOS"
MOON_JUMP = "Salto Lunar" MOON_JUMP = "Salto lunar"
GOD_MODE = "Modo Dios" GOD_MODE = "Modo Dios"
INFINITE_LIVES = "Vidas Ilimitadas" INFINITE_LIVES = "Vidas infinitas"
SUPER_SPEED = "Super Velocidad" SUPER_SPEED = "Super velocidad"
RESPONSIVE_CONTROLS = "Controles Responsivos" RESPONSIVE_CONTROLS = "Controles responsivos"
RAPID_FIRE = "Pulsación Rápida (A)" RAPID_FIRE = "Pulsación rápida (A)"
BLJ_ANYWHERE = "BLJ en cualquier parte" BLJ_ANYWHERE = "BLJ donde sea"
ALWAYS_TRIPLE_JUMP = "Siempre hacer Triple Salto" ALWAYS_TRIPLE_JUMP = "Siempre hacer triple salto"
[CONTROLS] [CONTROLS]
CONTROLS = "CONTROLES" CONTROLS = "CONTROLES"
N64_BINDS = "Asignaciones N64" N64_BINDS = "Botones N64"
EXTRA_BINDS = "Asignaciones Extra" EXTRA_BINDS = "Botones Extra"
BACKGROUND_GAMEPAD = "Mando en segundo plano" BACKGROUND_GAMEPAD = "Mando en segundo plano"
GAMEPAD = "Mando" GAMEPAD = "Mando"
DEADZONE = "Zona muerta" DEADZONE = "Zona muerta"
RUMBLE_STRENGTH = "Fuerza de Vibración" RUMBLE_STRENGTH = "Fuerza de vibración"
CHAT = "Chat" CHAT = "Chat"
PLAYERS = "Jugadores" PLAYERS = "Jugadores"
@ -111,12 +111,12 @@ C_RIGHT = "C Derecha"
[DISPLAY] [DISPLAY]
DISPLAY = "PANTALLA" DISPLAY = "PANTALLA"
FULLSCREEN = "Pantalla completa" FULLSCREEN = "Pantalla completa"
PRELOAD_TEXTURES = "Precargar Texturas" PRELOAD_TEXTURES = "Precargar texturas"
VSYNC = "Sincronización Vertical" VSYNC = "Sincronización vertical"
UNCAPPED_FRAMERATE = "FPS sin límite" UNCAPPED_FRAMERATE = "FPS sin límite"
FRAME_LIMIT = "Límite de FPS" FRAME_LIMIT = "Límite de FPS"
FAST = "Rápido" FAST = "Rápida"
ACCURATE = "Preciso" ACCURATE = "Precisa"
INTERPOLATION = "Interpolación" INTERPOLATION = "Interpolación"
NEAREST = "Más cercano" NEAREST = "Más cercano"
LINEAR = "Lineal" LINEAR = "Lineal"
@ -128,33 +128,33 @@ D1P5X = "1.5x"
D3X = "3x" D3X = "3x"
D10X = "10x" D10X = "10x"
D100X = "100x" D100X = "100x"
DRAW_DISTANCE = "Distancia de Dibujado" DRAW_DISTANCE = "Distancia de dibujado"
DYNOS_PACKS = "Packs DynOS" DYNOS_PACKS = "Packs de DynOS"
[DYNOS] [DYNOS]
DYNOS = "DYNOS" DYNOS = "DYNOS"
[HOST_MESSAGE] [HOST_MESSAGE]
INFO_TITLE = "INFO" INFO_TITLE = "INFO"
WARN_DISCORD = "Invita a amigos haciendo click derecho en su nombre en Discord y seleccionando\n'\\#d0d0ff\\Invitar a unirse\\#c8c8c8\\'.\n\nPuedes invitar en canales de un servidor también presionando el\nbotón \\#d0d0ff\\+\\#c8c8c8\\ al lado del cuadro de texto del chat.\n\nEl estado de Actividad Actual \\#ffa0a0\\debe estar\\#c8c8c8\\ activado en tus \najustes de Discord.\n\nEstár invisible \\#ffa0a0\\te prevendrá\\#c8c8c8\\ de crear invitaciones." WARN_DISCORD = "Invita a amigos haciendo click derecho en su nombre en Discord y seleccionando\n'\\#d0d0ff\\Invitar a unirse\\#c8c8c8\\'.\n\nPuedes invitar en canales de un servidor también presionando el botón \\#d0d0ff\\+\\#c8c8c8\\ al lado del cuadro de texto del chat.\n\nEl estado de Actividad Actual \\#ffa0a0\\debe estar\\#c8c8c8\\ activado en tus ajustes de Discord.\n\nEstar invisible \\#ffa0a0\\te prevendrá\\#c8c8c8\\ de crear invitaciones."
WARN_DISCORD2 = "\\#ffa0a0\\Error:\\#c8c8c8\\ No se ha detectado a Discord.\n\n\\#a0a0a0\\Prueba a cerrar el juego,\nreiniciar Discord,\ny abrir el juego de nuevo." WARN_DISCORD2 = "\\#ffa0a0\\Error:\\#c8c8c8\\ No se ha detectado Discord.\n\n\\#a0a0a0\\Prueba a cerrar el juego,\nreiniciar Discord,\ny abrir el juego de nuevo."
WARN_SOCKET = "Las conexiones directas \\#ffa0a0\\requieren\\#c8c8c8\\ que abras los puertos en tu rúter.\n\nAbre el puerto '\\#d0d0ff\\%d\\#c8c8c8\\' con protocolo UDP." WARN_SOCKET = "Las conexiones directas \\#ffa0a0\\requieren\\#c8c8c8\\ que abras los puertos en tu router.\n\nAbre el puerto '\\#d0d0ff\\%d\\#c8c8c8\\' con protocolo UDP."
HOST = "Alojar" HOST = "Crear"
[HOST_MODS] [HOST_MODS]
ROMHACKS = "ROMHACKS" ROMHACKS = "ROMHACKS"
MODS = "MODS" MODS = "MODS"
[HOST_SAVE] [HOST_SAVE]
SAVE_TITLE = "GUARDAR" SAVE_TITLE = "RANURAS DE\nGUARDADO"
ERASE_TITLE = "BORRAR" ERASE_TITLE = "BORRAR"
CONFIRM = "¿Seguro que quieres borrar esta partida?" CONFIRM = "¿Seguro que quieres borrar esta partida?"
ERASE = "Borrar" ERASE = "Borrar"
[HOST_SETTINGS] [HOST_SETTINGS]
SETTINGS = "AJUSTES" SETTINGS = "AJUSTES"
NONSOLID = "Intangible" NONSOLID = "No Sólida"
SOLID = "Tangible" SOLID = "Sólida"
FRIENDLY_FIRE = "Fuego Amigo" FRIENDLY_FIRE = "Fuego Amigo"
PLAYER_INTERACTION = "Interacción entre jugadores" PLAYER_INTERACTION = "Interacción entre jugadores"
WEAK = "Poca" WEAK = "Poca"
@ -163,7 +163,7 @@ TOO_MUCH = "Demasiada"
KNOCKBACK_STRENGTH = "Fuerza de retroceso" KNOCKBACK_STRENGTH = "Fuerza de retroceso"
LEAVE_LEVEL = "Salir del nivel" LEAVE_LEVEL = "Salir del nivel"
STAY_IN_LEVEL = "Seguir en el nivel" STAY_IN_LEVEL = "Seguir en el nivel"
NONSTOP = "Siguiente misión" NONSTOP = "Sin parar"
ON_STAR_COLLECTION = "Al conseguir una estrella" ON_STAR_COLLECTION = "Al conseguir una estrella"
SKIP_INTRO_CUTSCENE = "Saltar cinemática de introducción" SKIP_INTRO_CUTSCENE = "Saltar cinemática de introducción"
SHARE_LIVES = "Compartir vidas" SHARE_LIVES = "Compartir vidas"
@ -172,33 +172,33 @@ BUBBLE_ON_DEATH = "Burbuja al morir"
AMOUNT_OF_PLAYERS = "Número de jugadores" AMOUNT_OF_PLAYERS = "Número de jugadores"
[HOST] [HOST]
SERVER_TITLE = "SERVIDOR" SERVER_TITLE = "PARTIDA"
HOST_TITLE = "ALOJAR" HOST_TITLE = "CREAR"
DISCORD = "Discord" DISCORD = "Discord"
COOPNET = "CoopNet" COOPNET = "CoopNet"
DIRECT_CONNECTION = "Conexión Directa" DIRECT_CONNECTION = "Conexión Directa"
NETWORK_SYSTEM = "Modo de conexión" NETWORK_SYSTEM = "Modo de conexión"
PORT = "Puerto" PORT = "Puerto"
SAVE_SLOT = "Ranura de Guardado" SAVE_SLOT = "Ranuras"
SETTINGS = "Ajustes" SETTINGS = "Ajustes"
MODS = "Mods" MODS = "Mods"
ROMHACKS = "Rom-Hacks" ROMHACKS = "Rom-Hacks"
APPLY = "Aplicar" APPLY = "Aplicar"
HOST = "Alojar" HOST = "Crear"
[JOIN_MESSAGE] [JOIN_MESSAGE]
JOINING = "UNIENDOSE" JOINING = "UNIÉNDOSE"
[JOIN] [JOIN]
JOIN_TITLE = "UNIRSE" JOIN_TITLE = "UNIRSE"
JOIN_DISCORD = "Para unirte a un lobby en \\#d0d0ff\\Discord\\#c8c8c8\\:\n\nManten el juego abierto y acepta la invitación.\n\nSi la invitación dice que la partida ha terminado, haz click en el nombre de la persona que te invitó para refrescarla." JOIN_DISCORD = "Para unirte a un lobby en \\#d0d0ff\\Discord\\#c8c8c8\\:\n\nMantén el juego abierto y acepta la invitación.\n\nSi la invitación dice que la partida ha terminado, haz click en el nombre de la persona que te invitó para\nrefrescarla."
JOIN_SOCKET = "Introduce la IP y el puerto de \\#d0d0ff\\conexión directa\\#c8c8c8\\:" JOIN_SOCKET = "Introduce la IP y el puerto de la \\#d0d0ff\\conexión directa\\#c8c8c8\\:"
JOIN = "Unirse" JOIN = "Unirse"
[MAIN] [MAIN]
QUIT_TITLE = "SALIR" QUIT_TITLE = "SALIR"
QUIT_CONFIRM = "¿Seguro que quieres salir?" QUIT_CONFIRM = "¿Seguro que quieres salir?"
HOST = "Alojar" HOST = "Crear"
JOIN = "Unirse" JOIN = "Unirse"
OPTIONS = "Opciones" OPTIONS = "Opciones"
QUIT = "Salir" QUIT = "Salir"
@ -206,9 +206,9 @@ QUIT = "Salir"
[MENU_OPTIONS] [MENU_OPTIONS]
MAIN_MENU = "MENÚ PRINCIPAL" MAIN_MENU = "MENÚ PRINCIPAL"
LEVEL = "Nivel" LEVEL = "Nivel"
USE_STAGE_MUSIC = "Usar Música del Nivel" USE_STAGE_MUSIC = "Usar música del nivel"
RANDOM_STAGE = "Nivel Aleatório" RANDOM_STAGE = "Nivel aleatorio"
PLAY_VANILLA_DEMOS = "Reproducir Demostraciones Vanilla" PLAY_VANILLA_DEMOS = "Demos originales"
[MISC] [MISC]
DEBUG_TITLE = "DEPURACIÓN" DEBUG_TITLE = "DEPURACIÓN"
@ -217,10 +217,10 @@ LUA_PROFILER = "Perfilador de Lua"
DEBUG_PRINT = "Mensajes de Depuración" DEBUG_PRINT = "Mensajes de Depuración"
DEBUG_INFO = "Información de Depuración" DEBUG_INFO = "Información de Depuración"
DEBUG_ERRORS = "Errores de Depuración" DEBUG_ERRORS = "Errores de Depuración"
MISC_TITLE = "MISCELÁNEO" MISC_TITLE = "OTROS"
PAUSE_IN_SINGLEPLAYER = "Pausa en Modo de Un jugador" PAUSE_IN_SINGLEPLAYER = "Pausa en modo de un jugador"
DISABLE_POPUPS = "Deshabilitar Mensajes Emergentes" DISABLE_POPUPS = "Deshabilitar mensajes emergentes"
MENU_OPTIONS = "Opciones del Menú" MENU_OPTIONS = "Opciones del menú"
DEBUG = "Depuración" DEBUG = "Depuración"
LANGUAGE = "Idioma" LANGUAGE = "Idioma"
@ -234,26 +234,26 @@ CAMERA = "Cámara"
CONTROLS = "Controles" CONTROLS = "Controles"
DISPLAY = "Pantalla" DISPLAY = "Pantalla"
SOUND = "Sonido" SOUND = "Sonido"
MISC = "Misceláneo" MISC = "Otros"
[PAUSE] [PAUSE]
QUIT_TITLE = "SALIR" QUIT_TITLE = "SALIR"
QUIT_HOST = "¿Seguro que quieres dejar de alojar?" QUIT_HOST = "¿Seguro que quieres finalizar la partida?"
QUIT_CLIENT = "¿Seguro que te quieres desconectar?" QUIT_CLIENT = "¿Seguro que te quieres desconectar?"
PAUSE_TITLE = "PAUSA" PAUSE_TITLE = "PAUSA"
PLAYER = "Jugador" PLAYER = "Jugador"
DYNOS_PACKS = "Packs DynOS" DYNOS_PACKS = "Packs de DynOS"
OPTIONS = "Opciones" OPTIONS = "Opciones"
CHEATS = "Trucos" CHEATS = "Trucos"
SERVER_SETTINGS = "Ajustes del Servidor" SERVER_SETTINGS = "Ajustes de la partida"
RESUME = "Continuar" RESUME = "Continuar"
STOP_HOSTING = "Dejar de Alojar" STOP_HOSTING = "Finalizar partida"
DISCONNECT = "Desconectarse" DISCONNECT = "Desconectarse"
[PLAYER] [PLAYER]
PLAYER_TITLE = "JUGADOR" PLAYER_TITLE = "JUGADOR"
OVERALLS = "Tirantes" OVERALLS = "Overoles"
SHIRT = "Camisa" SHIRT = "Camiseta"
GLOVES = "Guantes" GLOVES = "Guantes"
SHOES = "Zapatos" SHOES = "Zapatos"
HAIR = "Pelo" HAIR = "Pelo"
@ -268,7 +268,7 @@ BLUE = "Azul"
PLAYER = "Jugador" PLAYER = "Jugador"
NAME = "Nombre" NAME = "Nombre"
MODEL = "Modelo" MODEL = "Modelo"
PALETTE_PRESET = "Perfil de Paleta" PALETTE_PRESET = "Paletas predeterminadas"
EDIT_PALETTE = "Editar Paleta" EDIT_PALETTE = "Editar Paleta"
[PALETTE] [PALETTE]
@ -304,20 +304,20 @@ RASPBERRY = "Frambuesa"
BUBBLEGUM = "Chicle" BUBBLEGUM = "Chicle"
ICE_MARIO = "Mario de Hielo" ICE_MARIO = "Mario de Hielo"
ICE_LUIGI = "Luigi de Hielo" ICE_LUIGI = "Luigi de Hielo"
CUSTOM = "Personalizado" CUSTOM = "Personalizada"
[PLAYER_LIST] [PLAYER_LIST]
PLAYERS = "JUGADORES" PLAYERS = "JUGADORES"
NAME = "nombre" NAME = "nombre"
LOCATION = "localización" LOCATION = "localización"
ACT = "recorrido" ACT = "acto"
[SOUND] [SOUND]
SOUND = "SONIDO" SOUND = "SONIDO"
MASTER_VOLUME = "Volumen Maestro" MASTER_VOLUME = "Volumen General"
MUSIC_VOLUME = "Volumen Música" MUSIC_VOLUME = "Volumen de Música"
SFX_VOLUME = "Volumen Efectos de Sonido" SFX_VOLUME = "Volumen de Efectos de Sonido"
ENV_VOLUME = "Volumen Entorno" ENV_VOLUME = "Volumen de Entorno"
[LANGUAGE] [LANGUAGE]
LANGUAGE = "IDIOMA" LANGUAGE = "IDIOMA"

View file

@ -28,6 +28,14 @@ for i = 0, (MAX_PLAYERS - 1) do
s.rank = 0 s.rank = 0
end end
local sKnockbackActions = {
ACT_SOFT_FORWARD_GROUND_KB, ACT_FORWARD_GROUND_KB, ACT_HARD_FORWARD_GROUND_KB,
ACT_FORWARD_AIR_KB, ACT_FORWARD_AIR_KB, ACT_HARD_FORWARD_AIR_KB,
ACT_FORWARD_WATER_KB, ACT_FORWARD_WATER_KB, ACT_FORWARD_WATER_KB,
ACT_SOFT_BACKWARD_GROUND_KB, ACT_BACKWARD_GROUND_KB, ACT_HARD_BACKWARD_GROUND_KB,
ACT_BACKWARD_AIR_KB, ACT_BACKWARD_AIR_KB, ACT_HARD_BACKWARD_AIR_KB,
ACT_BACKWARD_WATER_KB, ACT_BACKWARD_WATER_KB, ACT_BACKWARD_WATER_KB
}
------------ ------------
-- hammer -- -- hammer --
------------ ------------
@ -361,6 +369,27 @@ function mario_update(m)
local s = gPlayerSyncTable[m.playerIndex] local s = gPlayerSyncTable[m.playerIndex]
local np = gNetworkPlayers[m.playerIndex] local np = gNetworkPlayers[m.playerIndex]
-- increase knockback animations
local animInfo = nil
if m.marioObj ~= nil then
animInfo = m.marioObj.header.gfx.animInfo
end
for i, value in ipairs(sKnockbackActions) do
if m.action == value then
local frame = animInfo.animFrame
local loopEnd = frame
if animInfo.curAnim ~= nil then
loopEnd = animInfo.curAnim.loopEnd
end
if frame < loopEnd - 2 then
frame = frame + 1
end
animInfo.animFrame = frame
end
end
-- clear invincibilities -- clear invincibilities
m.invincTimer = 0 m.invincTimer = 0
if m.knockbackTimer > 5 then if m.knockbackTimer > 5 then

View file

@ -1163,7 +1163,7 @@ function act_walking(m)
end end
function act_hold_walking(m) function act_hold_walking(m)
if m.heldObj.behavior == bhvJumpingBox then if m.heldObj ~= nil and m.heldObj.behavior == bhvJumpingBox then
return set_mario_action(m, ACT_CRAZY_BOX_BOUNCE, 0) return set_mario_action(m, ACT_CRAZY_BOX_BOUNCE, 0)
end end

View file

@ -2195,27 +2195,46 @@ possibility.\
Good luck and\ Good luck and\
frustration resistance.") frustration resistance.")
-- smlua_text_utils_dialog_replace(DIALOG_063,1,5,30,200, "It's really a shame but\
-- this level was way too\
-- big for the level importer\
-- so I had to split it\
-- into two parts.\
-- That means I CAN'T place\
-- red coins in the whole\
-- level. Sad, isn't it?\
-- I know that you would\
-- enjoy collecting 30\
-- red coins, right?\
-- Well then, instead,\
-- the red coins are all\
-- beyond the cannon.\
-- And since they are so\
-- close together\
-- I won't tell you how\
-- many there are.\
-- \
-- (Well, honestly, I forgot\
-- how many I placed.)")
smlua_text_utils_dialog_replace(DIALOG_063,1,5,30,200, "It's really a shame but\ smlua_text_utils_dialog_replace(DIALOG_063,1,5,30,200, "It's really a shame but\
this level was way too\ this level was way too\
big for the level importer\ big for the level importer\
so I had to split it\ so I had to split it\
into two parts.\ into two parts.\
That means I CAN'T place\ Nah! Just kidding!\
You're no longer playing\
a Nintendo 64 rom-hack.\
It's the pc port we're\
talking about!\
That means I CAN place\
red coins in the whole\ red coins in the whole\
level. Sad, isn't it?\ level. Great, isn't it?\
I know that you would\ I know that you would\
enjoy collecting 30\ enjoy collecting 30\
red coins, right?\ red coins. So, after 9\
Well then, instead,\ years, it's finally\
the red coins are all\ possible. Have fun!")
beyond the cannon.\
And since they are so\
close together\
I won't tell you how\
many there are.\
\
(Well, honestly, I forgot\
how many I placed.)")
smlua_text_utils_dialog_replace(DIALOG_064,1,5,30,200, "You should already know\ smlua_text_utils_dialog_replace(DIALOG_064,1,5,30,200, "You should already know\
the concept of this\ the concept of this\

View file

@ -161,6 +161,8 @@ u32 get_mario_spawn_type(struct Object *o) {
} }
struct ObjectWarpNode *area_get_warp_node(u8 id) { struct ObjectWarpNode *area_get_warp_node(u8 id) {
if (!gCurrentArea || !gCurrentArea->warpNodes) { return NULL; }
struct ObjectWarpNode *node = NULL; struct ObjectWarpNode *node = NULL;
for (node = gCurrentArea->warpNodes; node != NULL; node = node->next) { for (node = gCurrentArea->warpNodes; node != NULL; node = node->next) {

View file

@ -170,5 +170,5 @@ static void (*sBetaBooKeyActions[])(void) = { beta_boo_key_inside_boo_loop, beta
* Update function for bhvBetaBooKey. * Update function for bhvBetaBooKey.
*/ */
void bhv_beta_boo_key_loop(void) { void bhv_beta_boo_key_loop(void) {
cur_obj_call_action_function(sBetaBooKeyActions); CUR_OBJ_CALL_ACTION_FUNCTION(sBetaBooKeyActions);
} }

View file

@ -555,7 +555,7 @@ void bhv_boo_loop(void) {
//PARTIAL_UPDATE //PARTIAL_UPDATE
cur_obj_update_floor_and_walls(); cur_obj_update_floor_and_walls();
cur_obj_call_action_function(sBooActions); CUR_OBJ_CALL_ACTION_FUNCTION(sBooActions);
cur_obj_move_standard(78); cur_obj_move_standard(78);
boo_approach_target_opacity_and_update_scale(); boo_approach_target_opacity_and_update_scale();
@ -793,7 +793,7 @@ void bhv_big_boo_loop(void) {
o->oGraphYOffset = o->oBooBaseScale * 60.0f; o->oGraphYOffset = o->oBooBaseScale * 60.0f;
cur_obj_update_floor_and_walls(); cur_obj_update_floor_and_walls();
cur_obj_call_action_function(sBooGivingStarActions); CUR_OBJ_CALL_ACTION_FUNCTION(sBooGivingStarActions);
cur_obj_move_standard(78); cur_obj_move_standard(78);
boo_approach_target_opacity_and_update_scale(); boo_approach_target_opacity_and_update_scale();
@ -870,7 +870,7 @@ void bhv_boo_with_cage_loop(void) {
//PARTIAL_UPDATE //PARTIAL_UPDATE
cur_obj_update_floor_and_walls(); cur_obj_update_floor_and_walls();
cur_obj_call_action_function(sBooWithCageActions); CUR_OBJ_CALL_ACTION_FUNCTION(sBooWithCageActions);
cur_obj_move_standard(78); cur_obj_move_standard(78);
boo_approach_target_opacity_and_update_scale(); boo_approach_target_opacity_and_update_scale();

View file

@ -59,7 +59,7 @@ void bhv_bowser_tail_anchor_init(void) {
} }
void bhv_bowser_tail_anchor_loop(void) { void bhv_bowser_tail_anchor_loop(void) {
cur_obj_call_action_function(sBowserTailAnchorActions); CUR_OBJ_CALL_ACTION_FUNCTION(sBowserTailAnchorActions);
o->oParentRelativePosX = 90.0f; o->oParentRelativePosX = 90.0f;
if (o->parentObj->oAction == 4) if (o->parentObj->oAction == 4)
o->parentObj->oIntangibleTimer = -1; o->parentObj->oIntangibleTimer = -1;
@ -1204,7 +1204,7 @@ void bowser_free_update(void) {
o->oBowserUnk10E = 0; o->oBowserUnk10E = 0;
cur_obj_update_floor_and_walls(); cur_obj_update_floor_and_walls();
cur_obj_call_action_function(sBowserActions); CUR_OBJ_CALL_ACTION_FUNCTION(sBowserActions);
cur_obj_move_standard(-78); cur_obj_move_standard(-78);
if (bowser_check_fallen_off_stage()) if (bowser_check_fallen_off_stage())
o->oAction = 2; // bowser go home? o->oAction = 2; // bowser go home?
@ -1657,7 +1657,7 @@ void bhv_falling_bowser_platform_loop(void) {
} }
} }
cur_obj_call_action_function(sFallingBowserPlatformActions); CUR_OBJ_CALL_ACTION_FUNCTION(sFallingBowserPlatformActions);
} }
void bowser_flame_despawn(void) { void bowser_flame_despawn(void) {

View file

@ -275,7 +275,7 @@ void (*sBowserPuzzlePieceActions[])(void) = {
void bhv_lll_bowser_puzzle_piece_loop(void) { void bhv_lll_bowser_puzzle_piece_loop(void) {
bhv_lll_bowser_puzzle_piece_update(); bhv_lll_bowser_puzzle_piece_update();
cur_obj_call_action_function(sBowserPuzzlePieceActions); CUR_OBJ_CALL_ACTION_FUNCTION(sBowserPuzzlePieceActions);
o->oPosX = o->oBowserPuzzlePieceOffsetX + o->oHomeX; o->oPosX = o->oBowserPuzzlePieceOffsetX + o->oHomeX;
o->oPosY = o->oBowserPuzzlePieceOffsetY + o->oHomeY; o->oPosY = o->oBowserPuzzlePieceOffsetY + o->oHomeY;

View file

@ -28,7 +28,7 @@ void (*sBirdChirpChirpActions[])(void) = { bub_spawner_act_0, bub_spawner_act_1,
bub_spawner_act_2, bub_spawner_act_3 }; bub_spawner_act_2, bub_spawner_act_3 };
void bhv_bub_spawner_loop(void) { void bhv_bub_spawner_loop(void) {
cur_obj_call_action_function(sBirdChirpChirpActions); CUR_OBJ_CALL_ACTION_FUNCTION(sBirdChirpChirpActions);
} }
void bub_move_vertically(s32 a0) { void bub_move_vertically(s32 a0) {
@ -136,7 +136,7 @@ void bhv_bub_loop(void) {
} }
o->oWallHitboxRadius = 30.0f; o->oWallHitboxRadius = 30.0f;
cur_obj_update_floor_and_walls(); cur_obj_update_floor_and_walls();
cur_obj_call_action_function(sCheepCheepActions); CUR_OBJ_CALL_ACTION_FUNCTION(sCheepCheepActions);
cur_obj_move_using_fvel_and_gravity(); cur_obj_move_using_fvel_and_gravity();
if (o->parentObj->oAction == 2) if (o->parentObj->oAction == 2)
obj_mark_for_deletion(o); obj_mark_for_deletion(o);

View file

@ -86,7 +86,7 @@ void (*sBulletBillActions[])(void) = { bullet_bill_act_0, bullet_bill_act_1, bul
bullet_bill_act_3, bullet_bill_act_4 }; bullet_bill_act_3, bullet_bill_act_4 };
void bhv_bullet_bill_loop(void) { void bhv_bullet_bill_loop(void) {
cur_obj_call_action_function(sBulletBillActions); CUR_OBJ_CALL_ACTION_FUNCTION(sBulletBillActions);
if (cur_obj_check_interacted()) if (cur_obj_check_interacted())
o->oAction = 4; o->oAction = 4;
} }

View file

@ -237,7 +237,7 @@ void bhv_cannon_base_loop(void) {
cur_obj_push_mario_away_from_cylinder(220, 300); cur_obj_push_mario_away_from_cylinder(220, 300);
} }
cur_obj_call_action_function(sOpenedCannonActions); CUR_OBJ_CALL_ACTION_FUNCTION(sOpenedCannonActions);
if (o->oCannonUnkF8) if (o->oCannonUnkF8)
o->oCannonUnkF8++; o->oCannonUnkF8++;
o->oInteractStatus = 0; o->oInteractStatus = 0;

View file

@ -65,5 +65,5 @@ void bhv_cap_switch_loop(void) {
sync_object_init_field(o, &capSwitchForcePress); sync_object_init_field(o, &capSwitchForcePress);
} }
cur_obj_call_action_function(sCapSwitchActions); CUR_OBJ_CALL_ACTION_FUNCTION(sCapSwitchActions);
} }

View file

@ -193,7 +193,7 @@ void (*sChuckyaActions[])(void) = { chuckya_act_0, chuckya_act_1, chuckya_act_2,
void chuckya_move(void) { void chuckya_move(void) {
cur_obj_update_floor_and_walls(); cur_obj_update_floor_and_walls();
cur_obj_call_action_function(sChuckyaActions); CUR_OBJ_CALL_ACTION_FUNCTION(sChuckyaActions);
cur_obj_move_standard(-30); cur_obj_move_standard(-30);
if (o->oInteractStatus & INT_STATUS_GRABBED_MARIO) { if (o->oInteractStatus & INT_STATUS_GRABBED_MARIO) {
o->oAction = 1; o->oAction = 1;

View file

@ -255,7 +255,7 @@ void coin_inside_boo_act_0(void) {
void (*sCoinInsideBooActions[])(void) = { coin_inside_boo_act_0, coin_inside_boo_act_1 }; void (*sCoinInsideBooActions[])(void) = { coin_inside_boo_act_0, coin_inside_boo_act_1 };
void bhv_coin_inside_boo_loop(void) { void bhv_coin_inside_boo_loop(void) {
cur_obj_call_action_function(sCoinInsideBooActions); CUR_OBJ_CALL_ACTION_FUNCTION(sCoinInsideBooActions);
} }
void bhv_coin_sparkles_loop(void) { void bhv_coin_sparkles_loop(void) {

View file

@ -154,7 +154,7 @@ struct SpawnParticlesInfo D_8032F3FC = { 0, 5, MODEL_WHITE_PARTICLE_DL, 0,
2.0f, 2.0f }; 2.0f, 2.0f };
void bhv_elevator_loop(void) { void bhv_elevator_loop(void) {
cur_obj_call_action_function(sElevatorActions); CUR_OBJ_CALL_ACTION_FUNCTION(sElevatorActions);
// allow bubbled players to pass through // allow bubbled players to pass through
if (gMarioStates[0].action == ACT_BUBBLED) { if (gMarioStates[0].action == ACT_BUBBLED) {

View file

@ -214,5 +214,5 @@ void bhv_exclamation_box_init(void) {
void bhv_exclamation_box_loop(void) { void bhv_exclamation_box_loop(void) {
cur_obj_scale(2.0f); cur_obj_scale(2.0f);
cur_obj_call_action_function(sExclamationBoxActions); CUR_OBJ_CALL_ACTION_FUNCTION(sExclamationBoxActions);
} }

View file

@ -73,7 +73,7 @@ static void (*sFishSpawnerActions[])(void) = {
}; };
void bhv_fish_spawner_loop(void) { void bhv_fish_spawner_loop(void) {
cur_obj_call_action_function(sFishSpawnerActions); CUR_OBJ_CALL_ACTION_FUNCTION(sFishSpawnerActions);
} }
/** /**
@ -276,7 +276,7 @@ void bhv_fish_loop(void)
} }
// Call fish action methods and apply physics engine. // Call fish action methods and apply physics engine.
cur_obj_call_action_function(sFishActions); CUR_OBJ_CALL_ACTION_FUNCTION(sFishActions);
cur_obj_move_using_fvel_and_gravity(); cur_obj_move_using_fvel_and_gravity();
// If the parent object has action set to two, then delete the fish object. // If the parent object has action set to two, then delete the fish object.

View file

@ -99,7 +99,7 @@ void (*sHeaveHoActions[])(void) = { heave_ho_act_0, heave_ho_act_1, heave_ho_act
void heave_ho_move(void) { void heave_ho_move(void) {
cur_obj_update_floor_and_walls(); cur_obj_update_floor_and_walls();
cur_obj_call_action_function(sHeaveHoActions); CUR_OBJ_CALL_ACTION_FUNCTION(sHeaveHoActions);
cur_obj_move_standard(-78); cur_obj_move_standard(-78);
if (o->oMoveFlags & OBJ_MOVE_MASK_IN_WATER) if (o->oMoveFlags & OBJ_MOVE_MASK_IN_WATER)
o->oGraphYOffset = -15.0f; o->oGraphYOffset = -15.0f;

View file

@ -41,7 +41,7 @@ void jumping_box_free_update(void) {
obj_set_hitbox(o, &sJumpingBoxHitbox); obj_set_hitbox(o, &sJumpingBoxHitbox);
cur_obj_update_floor_and_walls(); cur_obj_update_floor_and_walls();
cur_obj_move_standard(78); cur_obj_move_standard(78);
cur_obj_call_action_function(sJumpingBoxActions); CUR_OBJ_CALL_ACTION_FUNCTION(sJumpingBoxActions);
} }
void bhv_jumping_box_loop(void) { void bhv_jumping_box_loop(void) {

View file

@ -365,7 +365,7 @@ void king_bobomb_move(void) {
cur_obj_move_standard(-78); cur_obj_move_standard(-78);
else else
cur_obj_move_using_fvel_and_gravity(); cur_obj_move_using_fvel_and_gravity();
cur_obj_call_action_function(sKingBobombActions); CUR_OBJ_CALL_ACTION_FUNCTION(sKingBobombActions);
exec_anim_sound_state(sKingBobombSoundStates); exec_anim_sound_state(sKingBobombSoundStates);
s32 distanceToPlayer = dist_between_objects(o, gMarioStates[0].marioObj); s32 distanceToPlayer = dist_between_objects(o, gMarioStates[0].marioObj);
if (distanceToPlayer < 5000.0f * draw_distance_scalar()) if (distanceToPlayer < 5000.0f * draw_distance_scalar())

View file

@ -60,7 +60,7 @@ void bhv_lll_rotating_block_fire_bars_loop(void) {
sync_object_init(o, 4000.0f); sync_object_init(o, 4000.0f);
sync_object_init_field(o, &o->oAngleVelYaw); sync_object_init_field(o, &o->oAngleVelYaw);
} }
cur_obj_call_action_function(sRotatingCwFireBarsActions); CUR_OBJ_CALL_ACTION_FUNCTION(sRotatingCwFireBarsActions);
if (o->oBehParams2ndByte == 0) if (o->oBehParams2ndByte == 0)
load_object_collision_model(); load_object_collision_model();
} }

View file

@ -33,7 +33,7 @@ void mr_i_piranha_particle_act_1(void) {
void (*sMrIParticleActions[])(void) = { mr_i_piranha_particle_act_0, mr_i_piranha_particle_act_1 }; void (*sMrIParticleActions[])(void) = { mr_i_piranha_particle_act_0, mr_i_piranha_particle_act_1 };
void bhv_mr_i_particle_loop(void) { void bhv_mr_i_particle_loop(void) {
cur_obj_call_action_function(sMrIParticleActions); CUR_OBJ_CALL_ACTION_FUNCTION(sMrIParticleActions);
} }
void spawn_mr_i_particle(void) { void spawn_mr_i_particle(void) {
@ -283,7 +283,7 @@ void bhv_mr_i_loop(void) {
s32 distanceToPlayer = player ? dist_between_objects(o, player) : 10000; s32 distanceToPlayer = player ? dist_between_objects(o, player) : 10000;
obj_set_hitbox(o, &sMrIHitbox); obj_set_hitbox(o, &sMrIHitbox);
cur_obj_call_action_function(sMrIActions); CUR_OBJ_CALL_ACTION_FUNCTION(sMrIActions);
if (o->oAction != 3) { if (o->oAction != 3) {
if (distanceToPlayer > 3000.0f || o->activeFlags & ACTIVE_FLAG_IN_DIFFERENT_ROOM) { if (distanceToPlayer > 3000.0f || o->activeFlags & ACTIVE_FLAG_IN_DIFFERENT_ROOM) {
o->oAction = 0; o->oAction = 0;

View file

@ -369,7 +369,7 @@ void bhv_piranha_plant_loop(void) {
cur_obj_set_hitbox_radius_and_height(150.0f, 100.0f); cur_obj_set_hitbox_radius_and_height(150.0f, 100.0f);
cur_obj_set_hurtbox_radius_and_height(150.0f, 100.0f); cur_obj_set_hurtbox_radius_and_height(150.0f, 100.0f);
cur_obj_call_action_function(TablePiranhaPlantActions); CUR_OBJ_CALL_ACTION_FUNCTION(TablePiranhaPlantActions);
// In WF, hide all Piranha Plants once high enough up. // In WF, hide all Piranha Plants once high enough up.
if (gCurrLevelNum == LEVEL_WF) { if (gCurrLevelNum == LEVEL_WF) {
struct Object* player = gMarioStates[0].marioObj; struct Object* player = gMarioStates[0].marioObj;

View file

@ -63,5 +63,5 @@ void bhv_grindel_thwomp_loop(void) {
sync_object_init_field(o, &o->oTimer); sync_object_init_field(o, &o->oTimer);
sync_object_init_field(o, &o->oVelY); sync_object_init_field(o, &o->oVelY);
} }
cur_obj_call_action_function(sGrindelThwompActions); CUR_OBJ_CALL_ACTION_FUNCTION(sGrindelThwompActions);
} }

View file

@ -85,6 +85,6 @@ void bhv_tox_box_loop(void) {
sync_object_init_field(o, &o->oToxBoxMovementStep); sync_object_init_field(o, &o->oToxBoxMovementStep);
} }
} }
cur_obj_call_action_function(sToxBoxActions); CUR_OBJ_CALL_ACTION_FUNCTION(sToxBoxActions);
load_object_collision_model(); load_object_collision_model();
} }

View file

@ -164,5 +164,5 @@ void bhv_tumbling_bridge_loop(void) {
} }
} }
cur_obj_call_action_function(sTumblingBridgeActions); CUR_OBJ_CALL_ACTION_FUNCTION(sTumblingBridgeActions);
} }

View file

@ -160,7 +160,7 @@ void bhv_tuxies_mother_loop(void) {
} }
o->activeFlags |= ACTIVE_FLAG_UNK10; o->activeFlags |= ACTIVE_FLAG_UNK10;
cur_obj_update_floor_and_walls(); cur_obj_update_floor_and_walls();
cur_obj_call_action_function(sTuxiesMotherActions); CUR_OBJ_CALL_ACTION_FUNCTION(sTuxiesMotherActions);
cur_obj_move_standard(-78); cur_obj_move_standard(-78);
play_penguin_walking_sound(PENGUIN_WALK_BIG); play_penguin_walking_sound(PENGUIN_WALK_BIG);
o->oInteractStatus = 0; o->oInteractStatus = 0;
@ -289,7 +289,7 @@ void small_penguin_free_actions(void) {
cur_obj_become_tangible(); cur_obj_become_tangible();
cur_obj_enable_rendering(); cur_obj_enable_rendering();
cur_obj_update_floor_and_walls(); cur_obj_update_floor_and_walls();
cur_obj_call_action_function(sSmallPenguinActions); CUR_OBJ_CALL_ACTION_FUNCTION(sSmallPenguinActions);
cur_obj_move_standard(-78); cur_obj_move_standard(-78);
play_penguin_walking_sound(PENGUIN_WALK_BABY); play_penguin_walking_sound(PENGUIN_WALK_BABY);
} }

View file

@ -149,7 +149,7 @@ void bhv_tweester_loop(void) {
} }
obj_set_hitbox(o, &sTweesterHitbox); obj_set_hitbox(o, &sTweesterHitbox);
cur_obj_call_action_function(sTweesterActions); CUR_OBJ_CALL_ACTION_FUNCTION(sTweesterActions);
o->oInteractStatus = 0; o->oInteractStatus = 0;
} }

View file

@ -504,7 +504,7 @@ void ukiki_free_loop(void) {
s32 steepSlopeAngleDegrees; s32 steepSlopeAngleDegrees;
cur_obj_update_floor_and_walls(); cur_obj_update_floor_and_walls();
cur_obj_call_action_function(sUkikiActions); CUR_OBJ_CALL_ACTION_FUNCTION(sUkikiActions);
if (o->oAction == UKIKI_ACT_GO_TO_CAGE || o->oAction == UKIKI_ACT_RETURN_HOME) { if (o->oAction == UKIKI_ACT_GO_TO_CAGE || o->oAction == UKIKI_ACT_RETURN_HOME) {
steepSlopeAngleDegrees = -88; steepSlopeAngleDegrees = -88;

View file

@ -103,5 +103,5 @@ void (*sUkikiCageActions[])(void) = {
* Main behavior loop for the cage. Only calls the relevant action. * Main behavior loop for the cage. Only calls the relevant action.
*/ */
void bhv_ukiki_cage_loop(void) { void bhv_ukiki_cage_loop(void) {
cur_obj_call_action_function(sUkikiCageActions); CUR_OBJ_CALL_ACTION_FUNCTION(sUkikiCageActions);
} }

View file

@ -284,7 +284,7 @@ void bhv_whomp_loop(void) {
} }
cur_obj_update_floor_and_walls(); cur_obj_update_floor_and_walls();
cur_obj_call_action_function(sWhompActions); CUR_OBJ_CALL_ACTION_FUNCTION(sWhompActions);
cur_obj_move_standard(-20); cur_obj_move_standard(-20);
if (o->oAction != 9) { if (o->oAction != 9) {
// o->oBehParams2ndByte here seems to be a flag // o->oBehParams2ndByte here seems to be a flag

View file

@ -3297,11 +3297,6 @@ void soft_reset_camera(struct Camera* c) {
* Reset all the camera variables to their arcane defaults * Reset all the camera variables to their arcane defaults
*/ */
void reset_camera(struct Camera *c) { void reset_camera(struct Camera *c) {
UNUSED s32 unused = 0;
UNUSED u8 unused1[16];
UNUSED struct LinearTransitionPoint *start = &sModeInfo.transitionStart;
UNUSED struct LinearTransitionPoint *end = &sModeInfo.transitionEnd;
gCamera = c; gCamera = c;
gCameraMovementFlags = 0; gCameraMovementFlags = 0;
s2ndRotateFlags = 0; s2ndRotateFlags = 0;
@ -3315,7 +3310,6 @@ void reset_camera(struct Camera *c) {
unused8032CFCC = 0; unused8032CFCC = 0;
gSecondCameraFocus = NULL; gSecondCameraFocus = NULL;
sCButtonsPressed = 0; sCButtonsPressed = 0;
vec3f_copy(sModeTransition.marioPos, sMarioCamState->pos);
sModeTransition.framesLeft = 0; sModeTransition.framesLeft = 0;
unused8032CFCC = -1; unused8032CFCC = -1;
unused8032CFC8 = -1; unused8032CFC8 = -1;
@ -3340,11 +3334,19 @@ void reset_camera(struct Camera *c) {
sCSideButtonYaw = 0; sCSideButtonYaw = 0;
s8DirModeBaseYaw = 0; s8DirModeBaseYaw = 0;
s8DirModeYawOffset = 0; s8DirModeYawOffset = 0;
if (c) {
c->doorStatus = DOOR_DEFAULT; c->doorStatus = DOOR_DEFAULT;
}
if (sMarioCamState) {
vec3f_copy(sModeTransition.marioPos, sMarioCamState->pos);
sMarioCamState->headRotation[0] = 0; sMarioCamState->headRotation[0] = 0;
sMarioCamState->headRotation[1] = 0; sMarioCamState->headRotation[1] = 0;
sMarioCamState->cameraEvent = 0; sMarioCamState->cameraEvent = 0;
sMarioCamState->usedObj = NULL; sMarioCamState->usedObj = NULL;
}
gLakituState.shakeMagnitude[0] = 0; gLakituState.shakeMagnitude[0] = 0;
gLakituState.shakeMagnitude[1] = 0; gLakituState.shakeMagnitude[1] = 0;
gLakituState.shakeMagnitude[2] = 0; gLakituState.shakeMagnitude[2] = 0;
@ -3355,12 +3357,14 @@ void reset_camera(struct Camera *c) {
gLakituState.unusedVec1[1] = 0.f; gLakituState.unusedVec1[1] = 0.f;
gLakituState.unusedVec1[2] = 0.f; gLakituState.unusedVec1[2] = 0.f;
gLakituState.lastFrameAction = 0; gLakituState.lastFrameAction = 0;
set_fov_function(CAM_FOV_DEFAULT); set_fov_function(CAM_FOV_DEFAULT);
sFOVState.fov = 45.f; sFOVState.fov = 45.f;
sFOVState.fovOffset = 0.f; sFOVState.fovOffset = 0.f;
sFOVState.unusedIsSleeping = 0; sFOVState.unusedIsSleeping = 0;
sFOVState.shakeAmplitude = 0.f; sFOVState.shakeAmplitude = 0.f;
sFOVState.shakePhase = 0; sFOVState.shakePhase = 0;
sObjectCutscene = 0; sObjectCutscene = 0;
gRecentCutscene = 0; gRecentCutscene = 0;
unused8033B30C = 0; unused8033B30C = 0;

View file

@ -59,7 +59,7 @@ enum InteractionFlag {
(INT_SLIDE_KICK | INT_FAST_ATTACK_OR_SHELL) (INT_SLIDE_KICK | INT_FAST_ATTACK_OR_SHELL)
u8 sDelayInvincTimer; u8 sDelayInvincTimer;
s16 sInvulnerable; s16 gInteractionInvulnerable;
u32 interact_coin(struct MarioState *, u32, struct Object *); u32 interact_coin(struct MarioState *, u32, struct Object *);
u32 interact_water_ring(struct MarioState *, u32, struct Object *); u32 interact_water_ring(struct MarioState *, u32, struct Object *);
u32 interact_star_or_key(struct MarioState *, u32, struct Object *); u32 interact_star_or_key(struct MarioState *, u32, struct Object *);
@ -824,7 +824,7 @@ u32 take_damage_from_interact_object(struct MarioState *m) {
u32 take_damage_and_knock_back(struct MarioState *m, struct Object *o) { u32 take_damage_and_knock_back(struct MarioState *m, struct Object *o) {
u32 damage; u32 damage;
if (!sInvulnerable && !(m->flags & MARIO_VANISH_CAP) if (!gInteractionInvulnerable && !(m->flags & MARIO_VANISH_CAP)
&& !(o->oInteractionSubtype & INT_SUBTYPE_DELAY_INVINCIBILITY)) { && !(o->oInteractionSubtype & INT_SUBTYPE_DELAY_INVINCIBILITY)) {
o->oInteractStatus = INT_STATUS_INTERACTED | INT_STATUS_ATTACKED_MARIO; o->oInteractStatus = INT_STATUS_INTERACTED | INT_STATUS_ATTACKED_MARIO;
m->interactObj = o; m->interactObj = o;
@ -1309,7 +1309,7 @@ static u8 resolve_player_collision(struct MarioState* m, struct MarioState* m2)
velY = fmax(fmin(55.0f, 15.0f + fabs(m->vel[1])), 35.0f); velY = fmax(fmin(55.0f, 15.0f + fabs(m->vel[1])), 35.0f);
} else if (m->action == ACT_DOUBLE_JUMP) { } else if (m->action == ACT_DOUBLE_JUMP) {
mario_stop_riding_and_holding(m); mario_stop_riding_and_holding(m);
set_mario_action(m, (m->specialTripleJump && m->playerIndex == 0) ? ACT_SPECIAL_TRIPLE_JUMP : ACT_TRIPLE_JUMP, 0); set_mario_action(m, (m->specialTripleJump && m->playerIndex == 0) ? ACT_SPECIAL_TRIPLE_JUMP : m->flags & MARIO_WING_CAP ? ACT_FLYING_TRIPLE_JUMP : ACT_TRIPLE_JUMP, 0);
velY = fmax(fmin(60.0f, 20.0f + fabs(m->vel[1])), 40.0f); velY = fmax(fmin(60.0f, 20.0f + fabs(m->vel[1])), 40.0f);
} else { } else {
mario_stop_riding_and_holding(m); mario_stop_riding_and_holding(m);
@ -1353,6 +1353,8 @@ u8 player_is_sliding(struct MarioState* m) {
} }
u8 passes_pvp_interaction_checks(struct MarioState* attacker, struct MarioState* victim) { u8 passes_pvp_interaction_checks(struct MarioState* attacker, struct MarioState* victim) {
if (!attacker || !victim) { return false; }
// attacked // attacked
u8 isInCutscene = ((attacker->action & ACT_GROUP_MASK) == ACT_GROUP_CUTSCENE) || ((victim->action & ACT_GROUP_MASK) == ACT_GROUP_CUTSCENE); u8 isInCutscene = ((attacker->action & ACT_GROUP_MASK) == ACT_GROUP_CUTSCENE) || ((victim->action & ACT_GROUP_MASK) == ACT_GROUP_CUTSCENE);
isInCutscene = isInCutscene || (attacker->action == ACT_IN_CANNON) || (victim->action == ACT_IN_CANNON); isInCutscene = isInCutscene || (attacker->action == ACT_IN_CANNON) || (victim->action == ACT_IN_CANNON);
@ -1587,7 +1589,7 @@ u32 interact_strong_wind(struct MarioState *m, UNUSED u32 interactType, struct O
u32 interact_flame(struct MarioState *m, UNUSED u32 interactType, struct Object *o) { u32 interact_flame(struct MarioState *m, UNUSED u32 interactType, struct Object *o) {
u32 burningAction = ACT_BURNING_JUMP; u32 burningAction = ACT_BURNING_JUMP;
if (!sInvulnerable && !(m->flags & MARIO_METAL_CAP) && !(m->flags & MARIO_VANISH_CAP) if (!gInteractionInvulnerable && !(m->flags & MARIO_METAL_CAP) && !(m->flags & MARIO_VANISH_CAP)
&& !(o->oInteractionSubtype & INT_SUBTYPE_DELAY_INVINCIBILITY)) { && !(o->oInteractionSubtype & INT_SUBTYPE_DELAY_INVINCIBILITY)) {
queue_rumble_data_mario(m, 5, 80); queue_rumble_data_mario(m, 5, 80);
@ -1614,7 +1616,7 @@ u32 interact_flame(struct MarioState *m, UNUSED u32 interactType, struct Object
} }
u32 interact_snufit_bullet(struct MarioState *m, UNUSED u32 interactType, struct Object *o) { u32 interact_snufit_bullet(struct MarioState *m, UNUSED u32 interactType, struct Object *o) {
if (!sInvulnerable && !(m->flags & MARIO_VANISH_CAP)) { if (!gInteractionInvulnerable && !(m->flags & MARIO_VANISH_CAP)) {
if (m->flags & MARIO_METAL_CAP) { if (m->flags & MARIO_METAL_CAP) {
o->oInteractStatus = INT_STATUS_INTERACTED | INT_STATUS_WAS_ATTACKED; o->oInteractStatus = INT_STATUS_INTERACTED | INT_STATUS_WAS_ATTACKED;
play_sound(SOUND_ACTION_UNKNOWN458, m->marioObj->header.gfx.cameraToObject); play_sound(SOUND_ACTION_UNKNOWN458, m->marioObj->header.gfx.cameraToObject);
@ -1679,7 +1681,7 @@ u32 interact_bully(struct MarioState *m, UNUSED u32 interactType, struct Object
return TRUE; return TRUE;
} }
else if (!sInvulnerable && !(m->flags & MARIO_VANISH_CAP) else if (!gInteractionInvulnerable && !(m->flags & MARIO_VANISH_CAP)
&& !(o->oInteractionSubtype & INT_SUBTYPE_DELAY_INVINCIBILITY)) { && !(o->oInteractionSubtype & INT_SUBTYPE_DELAY_INVINCIBILITY)) {
o->oInteractStatus = INT_STATUS_INTERACTED; o->oInteractStatus = INT_STATUS_INTERACTED;
m->invincTimer = 2; m->invincTimer = 2;
@ -1699,7 +1701,7 @@ u32 interact_bully(struct MarioState *m, UNUSED u32 interactType, struct Object
} }
u32 interact_shock(struct MarioState *m, UNUSED u32 interactType, struct Object *o) { u32 interact_shock(struct MarioState *m, UNUSED u32 interactType, struct Object *o) {
if (!sInvulnerable && !(m->flags & MARIO_VANISH_CAP) if (!gInteractionInvulnerable && !(m->flags & MARIO_VANISH_CAP)
&& !(o->oInteractionSubtype & INT_SUBTYPE_DELAY_INVINCIBILITY)) { && !(o->oInteractionSubtype & INT_SUBTYPE_DELAY_INVINCIBILITY)) {
u32 actionArg = (m->action & (ACT_FLAG_AIR | ACT_FLAG_ON_POLE | ACT_FLAG_HANGING)) == 0; u32 actionArg = (m->action & (ACT_FLAG_AIR | ACT_FLAG_ON_POLE | ACT_FLAG_HANGING)) == 0;
@ -1916,7 +1918,7 @@ u32 interact_koopa_shell(struct MarioState *m, UNUSED u32 interactType, struct O
u32 check_object_grab_mario(struct MarioState *m, UNUSED u32 interactType, struct Object *o) { u32 check_object_grab_mario(struct MarioState *m, UNUSED u32 interactType, struct Object *o) {
if (m != &gMarioStates[0]) { return false; } if (m != &gMarioStates[0]) { return false; }
if ((!(m->action & (ACT_FLAG_AIR | ACT_FLAG_INVULNERABLE | ACT_FLAG_ATTACKING)) || !sInvulnerable) if ((!(m->action & (ACT_FLAG_AIR | ACT_FLAG_INVULNERABLE | ACT_FLAG_ATTACKING)) || !gInteractionInvulnerable)
&& (o->oInteractionSubtype & INT_SUBTYPE_GRABS_MARIO)) { && (o->oInteractionSubtype & INT_SUBTYPE_GRABS_MARIO)) {
if (object_facing_mario(m, o, 0x2AAA)) { if (object_facing_mario(m, o, 0x2AAA)) {
mario_stop_riding_and_holding(m); mario_stop_riding_and_holding(m);
@ -2222,7 +2224,7 @@ void check_kick_or_punch_wall(struct MarioState *m) {
void mario_process_interactions(struct MarioState *m) { void mario_process_interactions(struct MarioState *m) {
sDelayInvincTimer = FALSE; sDelayInvincTimer = FALSE;
sInvulnerable = (m->action & ACT_FLAG_INVULNERABLE) || m->invincTimer != 0; gInteractionInvulnerable = (m->action & ACT_FLAG_INVULNERABLE) || m->invincTimer != 0;
if (!(m->action & ACT_FLAG_INTANGIBLE) && m->collidedObjInteractTypes != 0 && is_player_active(m)) { if (!(m->action & ACT_FLAG_INTANGIBLE) && m->collidedObjInteractTypes != 0 && is_player_active(m)) {
s32 i; s32 i;

View file

@ -98,6 +98,7 @@ enum InteractionType {
#define INT_STATUS_STOP_RIDING (1 << 22) /* 0x00400000 */ #define INT_STATUS_STOP_RIDING (1 << 22) /* 0x00400000 */
#define INT_STATUS_TOUCHED_BOB_OMB (1 << 23) /* 0x00800000 */ #define INT_STATUS_TOUCHED_BOB_OMB (1 << 23) /* 0x00800000 */
extern s16 gInteractionInvulnerable;
extern u8 gPssSlideStarted; extern u8 gPssSlideStarted;
s16 mario_obj_angle_to_object(struct MarioState *m, struct Object *o); s16 mario_obj_angle_to_object(struct MarioState *m, struct Object *o);

View file

@ -176,7 +176,11 @@ void set_anim_to_frame(struct MarioState *m, s16 animFrame) {
s32 is_anim_past_frame(struct MarioState *m, s16 animFrame) { s32 is_anim_past_frame(struct MarioState *m, s16 animFrame) {
s32 isPastFrame; s32 isPastFrame;
s32 acceleratedFrame = animFrame << 0x10; s32 acceleratedFrame = animFrame << 0x10;
if (!m || !m->marioObj) { return TRUE; }
struct AnimInfo *animInfo = &m->marioObj->header.gfx.animInfo; struct AnimInfo *animInfo = &m->marioObj->header.gfx.animInfo;
if (!animInfo->curAnim) { return TRUE; }
struct Animation *curAnim = animInfo->curAnim; struct Animation *curAnim = animInfo->curAnim;
if (animInfo->animAccel) { if (animInfo->animAccel) {

View file

@ -2282,6 +2282,8 @@ s32 cur_obj_follow_path(UNUSED s32 unusedArg) {
f32 objToNextXZ; f32 objToNextXZ;
f32 objToNextX, objToNextY, objToNextZ; f32 objToNextX, objToNextY, objToNextZ;
if (o == NULL) { return PATH_NONE; }
if (o->oPathedPrevWaypointFlags == 0) { if (o->oPathedPrevWaypointFlags == 0) {
o->oPathedPrevWaypoint = o->oPathedStartWaypoint; o->oPathedPrevWaypoint = o->oPathedStartWaypoint;
o->oPathedPrevWaypointFlags = WAYPOINT_FLAGS_INITIALIZED; o->oPathedPrevWaypointFlags = WAYPOINT_FLAGS_INITIALIZED;
@ -2295,12 +2297,15 @@ s32 cur_obj_follow_path(UNUSED s32 unusedArg) {
struct Waypoint* tmpWaypoint = (lastWaypoint + 1); struct Waypoint* tmpWaypoint = (lastWaypoint + 1);
if (tmpWaypoint == NULL) { tmpWaypoint = lastWaypoint; } if (tmpWaypoint == NULL) { tmpWaypoint = lastWaypoint; }
if (tmpWaypoint->flags != WAYPOINT_FLAGS_END) { if (tmpWaypoint && tmpWaypoint->flags != WAYPOINT_FLAGS_END) {
targetWaypoint = tmpWaypoint; targetWaypoint = tmpWaypoint;
} else { } else {
targetWaypoint = startWaypoint; targetWaypoint = startWaypoint;
} }
if (lastWaypoint == NULL) { return PATH_NONE; }
if (targetWaypoint == NULL) { return PATH_NONE; }
o->oPathedPrevWaypointFlags = lastWaypoint->flags | WAYPOINT_FLAGS_INITIALIZED; o->oPathedPrevWaypointFlags = lastWaypoint->flags | WAYPOINT_FLAGS_INITIALIZED;
prevToNextX = targetWaypoint->pos[0] - lastWaypoint->pos[0]; prevToNextX = targetWaypoint->pos[0] - lastWaypoint->pos[0];
@ -2320,7 +2325,7 @@ s32 cur_obj_follow_path(UNUSED s32 unusedArg) {
o->oPathedPrevWaypoint = targetWaypoint; o->oPathedPrevWaypoint = targetWaypoint;
struct Waypoint* tmpWaypoint2 = (targetWaypoint + 1); struct Waypoint* tmpWaypoint2 = (targetWaypoint + 1);
if (tmpWaypoint2 == NULL) { tmpWaypoint2 = targetWaypoint; } if (tmpWaypoint2 == NULL) { tmpWaypoint2 = targetWaypoint; }
if (tmpWaypoint2->flags == WAYPOINT_FLAGS_END) { if (tmpWaypoint2 && tmpWaypoint2->flags == WAYPOINT_FLAGS_END) {
return PATH_REACHED_END; return PATH_REACHED_END;
} else { } else {
return PATH_REACHED_WAYPOINT; return PATH_REACHED_WAYPOINT;
@ -2658,8 +2663,11 @@ s32 cur_obj_move_up_and_down(s32 a0) {
return FALSE; return FALSE;
} }
void cur_obj_call_action_function(void (*actionFunctions[])(void)) { void cur_obj_call_action_function(void (*actionFunctions[])(void), uint32_t actionFunctionsLength) {
if (!actionFunctions) { return; }
if ((uint32_t)o->oAction >= actionFunctionsLength) { return; }
void (*actionFunction)(void) = actionFunctions[o->oAction]; void (*actionFunction)(void) = actionFunctions[o->oAction];
if (!actionFunction) { return; }
actionFunction(); actionFunction();
} }

View file

@ -256,6 +256,8 @@ struct GraphNode_802A45E4 {
/*0x22*/ s16 unk22; /*0x22*/ s16 unk22;
}; };
#define CUR_OBJ_CALL_ACTION_FUNCTION(_action_func) cur_obj_call_action_function(_action_func, (sizeof(_action_func) / sizeof(&_action_func[0])))
void obj_set_hitbox(struct Object *obj, struct ObjectHitbox *hitbox); void obj_set_hitbox(struct Object *obj, struct ObjectHitbox *hitbox);
s32 signum_positive(s32 x); s32 signum_positive(s32 x);
f32 absf(f32 x); f32 absf(f32 x);
@ -273,7 +275,7 @@ void cur_obj_scale_over_time(s32 a0, s32 a1, f32 sp10, f32 sp14);
void cur_obj_set_pos_to_home_with_debug(void); void cur_obj_set_pos_to_home_with_debug(void);
s32 cur_obj_is_mario_on_platform(void); s32 cur_obj_is_mario_on_platform(void);
s32 cur_obj_move_up_and_down(s32 a0); s32 cur_obj_move_up_and_down(s32 a0);
void cur_obj_call_action_function(void (*actionFunctions[])(void)); void cur_obj_call_action_function(void (*actionFunctions[])(void), uint32_t actionFunctionsLength);
void spawn_base_star_with_no_lvl_exit(void); void spawn_base_star_with_no_lvl_exit(void);
s32 bit_shift_left(s32 a0); s32 bit_shift_left(s32 a0);
s32 cur_obj_mario_far_away(void); s32 cur_obj_mario_far_away(void);

View file

@ -337,6 +337,7 @@ void bhv_mario_update(void) {
update_character_anim_offset(gMarioState); update_character_anim_offset(gMarioState);
// reset mario state to the local player // reset mario state to the local player
gInteractionInvulnerable = false;
gMarioState = &gMarioStates[0]; gMarioState = &gMarioStates[0];
} }

View file

@ -1554,7 +1554,7 @@ void geo_process_node_and_siblings(struct GraphNode *firstNode) {
} }
} }
} else { } else {
if (curGraphNode->type == GRAPH_NODE_TYPE_OBJECT) { if (curGraphNode && curGraphNode->type == GRAPH_NODE_TYPE_OBJECT) {
((struct GraphNodeObject *) curGraphNode)->throwMatrix = NULL; ((struct GraphNodeObject *) curGraphNode)->throwMatrix = NULL;
} }
} }

View file

@ -98,6 +98,7 @@ void djui_render(void) {
gDjuiHudUtilsZ = 0; gDjuiHudUtilsZ = 0;
create_dl_ortho_matrix(); create_dl_ortho_matrix();
djui_gfx_displaylist_begin();
smlua_call_event_hooks(HOOK_ON_HUD_RENDER); smlua_call_event_hooks(HOOK_ON_HUD_RENDER);
@ -119,4 +120,5 @@ void djui_render(void) {
djui_cursor_update(); djui_cursor_update();
djui_interactable_update(); djui_interactable_update();
djui_gfx_displaylist_end();
} }

View file

@ -4,8 +4,14 @@
#define G_TEXOVERRIDE_DJUI 0xe0 #define G_TEXOVERRIDE_DJUI 0xe0
#define G_DJUI_SIMPLE_VERT 0x11 #define G_DJUI_SIMPLE_VERT 0x11
#define G_DJUI_SIMPLE_TRI2 0x12 #define G_DJUI_SIMPLE_TRI2 0x12
#define G_TEXADDR_DJUI 0x13
#define G_EXECUTE_DJUI 0xdd #define G_EXECUTE_DJUI 0xdd
#define gsSPTextureAddrDjui(c) \
{{ \
(_SHIFTL(G_TEXADDR_DJUI,24,8)|_SHIFTL(~(u32)(c),0,24)),(u32)(0) \
}}
#define gSetClippingDjui(pkt, cmd, x1, y1, x2, y2) \ #define gSetClippingDjui(pkt, cmd, x1, y1, x2, y2) \
{ \ { \
Gfx *_g = (Gfx *)(pkt); \ Gfx *_g = (Gfx *)(pkt); \

View file

@ -6,6 +6,25 @@
#include "src/pc/pc_main.h" #include "src/pc/pc_main.h"
#include "src/pc/gfx/gfx_window_manager_api.h" #include "src/pc/gfx/gfx_window_manager_api.h"
#include "gfx_dimensions.h" #include "gfx_dimensions.h"
#include "djui_gfx.h"
const Gfx dl_djui_display_list_begin[] = {
gsSPTextureAddrDjui(1),
gsSPEndDisplayList(),
};
const Gfx dl_djui_display_list_end[] = {
gsSPTextureAddrDjui(0),
gsSPEndDisplayList(),
};
void djui_gfx_displaylist_begin(void) {
gSPDisplayList(gDisplayListHead++, dl_djui_display_list_begin);
}
void djui_gfx_displaylist_end(void) {
gSPDisplayList(gDisplayListHead++, dl_djui_display_list_end);
}
static const Vtx vertex_djui_simple_rect[] = { static const Vtx vertex_djui_simple_rect[] = {
{{{ 0, -1, 0}, 0, { 0, 0 }, { 0xff, 0xff, 0xff, 0xff }}}, {{{ 0, -1, 0}, 0, { 0, 0 }, { 0xff, 0xff, 0xff, 0xff }}},

View file

@ -9,6 +9,9 @@ extern const Gfx dl_djui_simple_rect[];
extern const Gfx dl_djui_img_begin[]; extern const Gfx dl_djui_img_begin[];
extern const Gfx dl_djui_img_end[]; extern const Gfx dl_djui_img_end[];
void djui_gfx_displaylist_begin(void);
void djui_gfx_displaylist_end(void);
f32 djui_gfx_get_scale(void); f32 djui_gfx_get_scale(void);
void djui_gfx_render_texture(const u8* texture, u32 w, u32 h, u32 bitSize); void djui_gfx_render_texture(const u8* texture, u32 w, u32 h, u32 bitSize);

View file

@ -91,6 +91,7 @@ struct InterpHud {
f32 scaleH; f32 scaleH;
f32 width; f32 width;
f32 height; f32 height;
enum HudUtilsResolution resolution;
}; };
static struct InterpHud sInterpHuds[MAX_INTERP_HUD] = { 0 }; static struct InterpHud sInterpHuds[MAX_INTERP_HUD] = { 0 };
static u16 sInterpHudCount = 0; static u16 sInterpHudCount = 0;
@ -102,12 +103,14 @@ void patch_djui_hud_before(void) {
void patch_djui_hud(f32 delta) { void patch_djui_hud(f32 delta) {
f32 savedZ = gDjuiHudUtilsZ; f32 savedZ = gDjuiHudUtilsZ;
Gfx* savedHeadPos = gDisplayListHead; Gfx* savedHeadPos = gDisplayListHead;
enum HudUtilsResolution savedResolution = sResolution;
for (u16 i = 0; i < sInterpHudCount; i++) { for (u16 i = 0; i < sInterpHudCount; i++) {
struct InterpHud* interp = &sInterpHuds[i]; struct InterpHud* interp = &sInterpHuds[i];
f32 x = delta_interpolate_f32(interp->prevX, interp->x, delta); f32 x = delta_interpolate_f32(interp->prevX, interp->x, delta);
f32 y = delta_interpolate_f32(interp->prevY, interp->y, delta); f32 y = delta_interpolate_f32(interp->prevY, interp->y, delta);
f32 scaleW = delta_interpolate_f32(interp->prevScaleW, interp->scaleW, delta); f32 scaleW = delta_interpolate_f32(interp->prevScaleW, interp->scaleW, delta);
f32 scaleH = delta_interpolate_f32(interp->prevScaleH, interp->scaleH, delta); f32 scaleH = delta_interpolate_f32(interp->prevScaleH, interp->scaleH, delta);
sResolution = interp->resolution;
gDjuiHudUtilsZ = interp->z; gDjuiHudUtilsZ = interp->z;
gDisplayListHead = interp->headPos; gDisplayListHead = interp->headPos;
@ -125,6 +128,7 @@ void patch_djui_hud(f32 delta) {
djui_hud_size_translate(&translatedH); djui_hud_size_translate(&translatedH);
create_dl_scale_matrix(DJUI_MTX_NOPUSH, interp->width * translatedW, interp->height * translatedH, 1.0f); create_dl_scale_matrix(DJUI_MTX_NOPUSH, interp->width * translatedW, interp->height * translatedH, 1.0f);
} }
sResolution = savedResolution;
gDisplayListHead = savedHeadPos; gDisplayListHead = savedHeadPos;
gDjuiHudUtilsZ = savedZ; gDjuiHudUtilsZ = savedZ;
} }
@ -326,6 +330,7 @@ void djui_hud_render_texture_interpolated(struct TextureInfo* texInfo, f32 prevX
interp->width = texInfo->width; interp->width = texInfo->width;
interp->height = texInfo->height; interp->height = texInfo->height;
interp->z = savedZ; interp->z = savedZ;
interp->resolution = sResolution;
} }
void djui_hud_render_texture_tile_interpolated(struct TextureInfo* texInfo, f32 prevX, f32 prevY, f32 prevScaleW, f32 prevScaleH, f32 x, f32 y, f32 scaleW, f32 scaleH, u32 tileX, u32 tileY, u32 tileW, u32 tileH) { void djui_hud_render_texture_tile_interpolated(struct TextureInfo* texInfo, f32 prevX, f32 prevY, f32 prevScaleW, f32 prevScaleH, f32 x, f32 y, f32 scaleW, f32 scaleH, u32 tileX, u32 tileY, u32 tileW, u32 tileH) {

View file

@ -8,16 +8,11 @@
// events // // events //
//////////// ////////////
static void djui_paginated_prev(struct DjuiBase* base) { static struct DjuiButton* sPrevButton = NULL;
struct DjuiPaginated* paginated = (struct DjuiPaginated*)base->parent; static struct DjuiButton* sNextButton = NULL;
paginated->startIndex -= paginated->showCount; static struct DjuiText* sPageNumText = NULL;
if (paginated->startIndex < 0) { paginated->startIndex = 0; }
}
static void djui_paginated_next(struct DjuiBase* base) {
struct DjuiPaginated* paginated = (struct DjuiPaginated*)base->parent;
paginated->startIndex += paginated->showCount;
static s32 djui_paginated_get_count(struct DjuiPaginated* paginated) {
s32 count = 0; s32 count = 0;
struct DjuiBaseChild* dbc = paginated->layout->base.child; struct DjuiBaseChild* dbc = paginated->layout->base.child;
while (dbc != NULL) { while (dbc != NULL) {
@ -25,6 +20,35 @@ static void djui_paginated_next(struct DjuiBase* base) {
dbc = dbc->next; dbc = dbc->next;
} }
return count;
}
static void djui_paginated_prev(struct DjuiBase* base) {
struct DjuiPaginated* paginated = (struct DjuiPaginated*)base->parent;
paginated->startIndex -= paginated->showCount;
djui_base_set_enabled(&sPrevButton->base, (paginated->startIndex > 0));
djui_base_set_enabled(&sNextButton->base, true);
char pageNumString[32] = { 0 };
snprintf(pageNumString, 32, "%d/%d", paginated->startIndex / paginated->showCount + 1, djui_paginated_get_count(paginated) / paginated->showCount + 1);
djui_text_set_text(sPageNumText, pageNumString);
if (paginated->startIndex < 0) { paginated->startIndex = 0; }
}
static void djui_paginated_next(struct DjuiBase* base) {
struct DjuiPaginated* paginated = (struct DjuiPaginated*)base->parent;
paginated->startIndex += paginated->showCount;
s32 count = djui_paginated_get_count(paginated);
djui_base_set_enabled(&sNextButton->base, (paginated->startIndex < count - 8));
djui_base_set_enabled(&sPrevButton->base, true);
char pageNumString[32] = { 0 };
snprintf(pageNumString, 32, "%d/%d", paginated->startIndex / paginated->showCount + 1, count / paginated->showCount + 1);
djui_text_set_text(sPageNumText, pageNumString);
if (paginated->startIndex >= count) { paginated->startIndex -= paginated->showCount; } if (paginated->startIndex >= count) { paginated->startIndex -= paginated->showCount; }
} }
@ -57,6 +81,10 @@ void djui_paginated_calculate_height(struct DjuiPaginated* paginated) {
} }
djui_base_set_size(&paginated->base, paginated->base.width.value, height); djui_base_set_size(&paginated->base, paginated->base.width.value, height);
char pageNumString[32] = { 0 };
snprintf(pageNumString, 32, "%d/%d", paginated->startIndex / paginated->showCount + 1, count / paginated->showCount + 1);
djui_text_set_text(sPageNumText, pageNumString);
} }
bool djui_paginated_render(struct DjuiBase* base) { bool djui_paginated_render(struct DjuiBase* base) {
@ -112,22 +140,23 @@ struct DjuiPaginated* djui_paginated_create(struct DjuiBase* parent, u32 showCou
paginated->layout = layout; paginated->layout = layout;
} }
{ sPrevButton = djui_button_create(&paginated->base, "<", DJUI_BUTTON_STYLE_NORMAL, djui_paginated_prev);
struct DjuiButton* button = djui_button_create(&paginated->base, "<", DJUI_BUTTON_STYLE_NORMAL, djui_paginated_prev); djui_base_set_alignment(&sPrevButton->base, DJUI_HALIGN_LEFT, DJUI_VALIGN_BOTTOM);
djui_base_set_alignment(&button->base, DJUI_HALIGN_LEFT, DJUI_VALIGN_BOTTOM); djui_base_set_size_type(&sPrevButton->base, DJUI_SVT_ABSOLUTE, DJUI_SVT_ABSOLUTE);
djui_base_set_size_type(&button->base, DJUI_SVT_ABSOLUTE, DJUI_SVT_ABSOLUTE); djui_base_set_size(&sPrevButton->base, 128, 32);
djui_base_set_size(&button->base, 128, 32); djui_base_set_enabled(&sPrevButton->base, false);
paginated->prevButton = button; paginated->prevButton = sPrevButton;
}
{ sPageNumText = djui_text_create(&paginated->base, "");
struct DjuiButton* button = djui_button_create(&paginated->base, ">", DJUI_BUTTON_STYLE_NORMAL, djui_paginated_next); djui_base_set_color(&sPageNumText->base, 200, 200, 200, 255);
djui_base_set_alignment(&button->base, DJUI_HALIGN_RIGHT, DJUI_VALIGN_BOTTOM); djui_base_set_alignment(&sPageNumText->base, DJUI_HALIGN_CENTER, DJUI_VALIGN_BOTTOM);
djui_base_set_size_type(&button->base, DJUI_SVT_ABSOLUTE, DJUI_SVT_ABSOLUTE); sPageNumText->base.y.value -= 30;
djui_base_set_size(&button->base, 128, 32);
djui_interactable_hook_click(&button->base, djui_paginated_next); sNextButton = djui_button_create(&paginated->base, ">", DJUI_BUTTON_STYLE_NORMAL, djui_paginated_next);
paginated->nextButton = button; djui_base_set_alignment(&sNextButton->base, DJUI_HALIGN_RIGHT, DJUI_VALIGN_BOTTOM);
} djui_base_set_size_type(&sNextButton->base, DJUI_SVT_ABSOLUTE, DJUI_SVT_ABSOLUTE);
djui_base_set_size(&sNextButton->base, 128, 32);
paginated->nextButton = sNextButton;
return paginated; return paginated;
} }

View file

@ -189,6 +189,18 @@ static const uint8_t missing_texture[MISSING_W * MISSING_H * 4] = {
0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF,
}; };
static bool sOnlyTextureChangeOnAddrChange = false;
static void gfx_update_loaded_texture(uint8_t tile_number, uint32_t size_bytes, const uint8_t* addr) {
if (!sOnlyTextureChangeOnAddrChange) {
rdp.textures_changed[tile_number] = true;
} else if (!rdp.textures_changed[tile_number]) {
rdp.textures_changed[tile_number] = rdp.loaded_texture[tile_number].addr != addr;
}
rdp.loaded_texture[tile_number].size_bytes = size_bytes;
rdp.loaded_texture[tile_number].addr = addr;
}
////////////////////////////////// //////////////////////////////////
// forward declaration for djui // // forward declaration for djui //
////////////////////////////////// //////////////////////////////////
@ -210,15 +222,9 @@ static unsigned long get_time(void) {
static void gfx_flush(void) { static void gfx_flush(void) {
if (buf_vbo_len > 0) { if (buf_vbo_len > 0) {
/*int num = buf_vbo_num_tris;
unsigned long t0 = get_time();*/
gfx_rapi->draw_triangles(buf_vbo, buf_vbo_len, buf_vbo_num_tris); gfx_rapi->draw_triangles(buf_vbo, buf_vbo_len, buf_vbo_num_tris);
buf_vbo_len = 0; buf_vbo_len = 0;
buf_vbo_num_tris = 0; buf_vbo_num_tris = 0;
/*unsigned long t1 = get_time();
if (t1 - t0 > 1000) {
printf("f: %d %d\n", num, (int)(t1 - t0));
}*/
} }
} }
@ -1241,9 +1247,12 @@ static void gfx_dp_set_tile(uint8_t fmt, uint32_t siz, uint32_t line, uint32_t t
rdp.texture_tile.cms = cms; rdp.texture_tile.cms = cms;
rdp.texture_tile.cmt = cmt; rdp.texture_tile.cmt = cmt;
rdp.texture_tile.line_size_bytes = line * 8; rdp.texture_tile.line_size_bytes = line * 8;
if (!sOnlyTextureChangeOnAddrChange) {
// I don't know if we ever need to set these...
rdp.textures_changed[0] = true; rdp.textures_changed[0] = true;
rdp.textures_changed[1] = true; rdp.textures_changed[1] = true;
} }
}
if (tile == G_TX_LOADTILE) { if (tile == G_TX_LOADTILE) {
rdp.texture_to_load.tile_number = tmem / 256; rdp.texture_to_load.tile_number = tmem / 256;
@ -1256,10 +1265,13 @@ static void gfx_dp_set_tile_size(uint8_t tile, uint16_t uls, uint16_t ult, uint1
rdp.texture_tile.ult = ult; rdp.texture_tile.ult = ult;
rdp.texture_tile.lrs = lrs; rdp.texture_tile.lrs = lrs;
rdp.texture_tile.lrt = lrt; rdp.texture_tile.lrt = lrt;
if (!sOnlyTextureChangeOnAddrChange) {
// I don't know if we ever need to set these...
rdp.textures_changed[0] = true; rdp.textures_changed[0] = true;
rdp.textures_changed[1] = true; rdp.textures_changed[1] = true;
} }
} }
}
static void gfx_dp_load_tlut(uint8_t tile, UNUSED uint32_t high_index) { static void gfx_dp_load_tlut(uint8_t tile, UNUSED uint32_t high_index) {
if (tile != G_TX_LOADTILE) { return; } if (tile != G_TX_LOADTILE) { return; }
@ -1290,9 +1302,7 @@ static void gfx_dp_load_block(uint8_t tile, uint32_t uls, uint32_t ult, uint32_t
break; break;
} }
uint32_t size_bytes = (lrs + 1) << word_size_shift; uint32_t size_bytes = (lrs + 1) << word_size_shift;
rdp.loaded_texture[rdp.texture_to_load.tile_number].size_bytes = size_bytes; gfx_update_loaded_texture(rdp.texture_to_load.tile_number, size_bytes, rdp.texture_to_load.addr);
rdp.loaded_texture[rdp.texture_to_load.tile_number].addr = rdp.texture_to_load.addr;
rdp.textures_changed[rdp.texture_to_load.tile_number] = true;
} }
static void gfx_dp_load_tile(uint8_t tile, uint32_t uls, uint32_t ult, uint32_t lrs, uint32_t lrt) { static void gfx_dp_load_tile(uint8_t tile, uint32_t uls, uint32_t ult, uint32_t lrs, uint32_t lrt) {
@ -1318,15 +1328,11 @@ static void gfx_dp_load_tile(uint8_t tile, uint32_t uls, uint32_t ult, uint32_t
} }
uint32_t size_bytes = (((lrs >> G_TEXTURE_IMAGE_FRAC) + 1) * ((lrt >> G_TEXTURE_IMAGE_FRAC) + 1)) << word_size_shift; uint32_t size_bytes = (((lrs >> G_TEXTURE_IMAGE_FRAC) + 1) * ((lrt >> G_TEXTURE_IMAGE_FRAC) + 1)) << word_size_shift;
rdp.loaded_texture[rdp.texture_to_load.tile_number].size_bytes = size_bytes; gfx_update_loaded_texture(rdp.texture_to_load.tile_number, size_bytes, rdp.texture_to_load.addr);
rdp.loaded_texture[rdp.texture_to_load.tile_number].addr = rdp.texture_to_load.addr;
rdp.texture_tile.uls = uls; rdp.texture_tile.uls = uls;
rdp.texture_tile.ult = ult; rdp.texture_tile.ult = ult;
rdp.texture_tile.lrs = lrs; rdp.texture_tile.lrs = lrs;
rdp.texture_tile.lrt = lrt; rdp.texture_tile.lrt = lrt;
rdp.textures_changed[rdp.texture_to_load.tile_number] = true;
} }
static uint8_t color_comb_component(uint32_t v) { static uint8_t color_comb_component(uint32_t v) {
@ -1977,10 +1983,7 @@ static void OPTIMIZE_O3 djui_gfx_dp_execute_override(void) {
uint32_t wordSizeShift = (sDjuiOverrideB == 32) ? 2 : 1; uint32_t wordSizeShift = (sDjuiOverrideB == 32) ? 2 : 1;
uint32_t lrs = (sDjuiOverrideW * sDjuiOverrideH) - 1; uint32_t lrs = (sDjuiOverrideW * sDjuiOverrideH) - 1;
uint32_t sizeBytes = (lrs + 1) << wordSizeShift; uint32_t sizeBytes = (lrs + 1) << wordSizeShift;
rdp.loaded_texture[rdp.texture_to_load.tile_number].size_bytes = sizeBytes; gfx_update_loaded_texture(rdp.texture_to_load.tile_number, sizeBytes, rdp.texture_to_load.addr);
rdp.textures_changed[rdp.texture_to_load.tile_number] = rdp.loaded_texture[rdp.texture_to_load.tile_number].addr != rdp.texture_to_load.addr;
rdp.loaded_texture[rdp.texture_to_load.tile_number].addr = rdp.texture_to_load.addr;
//rdp.textures_changed[rdp.texture_to_load.tile_number] = true;
// gsDPSetTile // gsDPSetTile
uint32_t line = (((sDjuiOverrideW * 2) + 7) >> 3); uint32_t line = (((sDjuiOverrideW * 2) + 7) >> 3);
@ -2135,6 +2138,9 @@ void OPTIMIZE_O3 djui_gfx_run_dl(Gfx* cmd) {
djui_gfx_sp_simple_tri1(C0(16, 8) / 2, C0(8, 8) / 2, C0(0, 8) / 2); djui_gfx_sp_simple_tri1(C0(16, 8) / 2, C0(8, 8) / 2, C0(0, 8) / 2);
djui_gfx_sp_simple_tri1(C1(16, 8) / 2, C1(8, 8) / 2, C1(0, 8) / 2); djui_gfx_sp_simple_tri1(C1(16, 8) / 2, C1(8, 8) / 2, C1(0, 8) / 2);
break; break;
case G_TEXADDR_DJUI:
sOnlyTextureChangeOnAddrChange = !(C0(0, 24) & 0x01);
break;
case G_EXECUTE_DJUI: case G_EXECUTE_DJUI:
djui_gfx_dp_execute_djui(cmd->words.w1); djui_gfx_dp_execute_djui(cmd->words.w1);
break; break;

View file

@ -4016,7 +4016,7 @@ char gSmluaConstants[] = ""
"COOP_OBJ_FLAG_INITIALIZED = (1 << 3)\n" "COOP_OBJ_FLAG_INITIALIZED = (1 << 3)\n"
"VERSION_TEXT = 'beta'\n" "VERSION_TEXT = 'beta'\n"
"VERSION_NUMBER = 33\n" "VERSION_NUMBER = 33\n"
"MINOR_VERSION_NUMBER = 0\n" "MINOR_VERSION_NUMBER = 1\n"
"PATCH_VERSION_NUMBER = 0\n" "PATCH_VERSION_NUMBER = 0\n"
"MAX_VERSION_LENGTH = 10\n" "MAX_VERSION_LENGTH = 10\n"
"MAX_LOCAL_VERSION_LENGTH = 12\n" "MAX_LOCAL_VERSION_LENGTH = 12\n"

View file

@ -473,66 +473,104 @@ struct LuaLevelScriptParse {
struct LuaLevelScriptParse sLevelScriptParse = { 0 }; struct LuaLevelScriptParse sLevelScriptParse = { 0 };
s32 smlua_func_level_script_parse_callback(u8 type, void *cmd) { s32 smlua_func_level_script_parse_callback(u8 type, void *cmd) {
if (type != 0x24 && type != 0x39 && type != 0x1F) { u32 areaIndex, bhvId, bhvArgs;
return 0; u32 *pAreaIndex = NULL, *pBhvId = NULL, *pBhvArgs = NULL;
MacroObject *pMacroData = NULL;
// Gather arguments
switch (type) {
// AREA
case 0x1F: {
areaIndex = (u8) dynos_level_cmd_get(cmd, 2);
pAreaIndex = &areaIndex;
} break;
// OBJECT_WITH_ACTS
case 0x24: {
const BehaviorScript *bhv = (const BehaviorScript *) dynos_level_cmd_get(cmd, 20);
if (bhv) {
bhvId = (u32) get_id_from_behavior(bhv);
bhvArgs = (u32) dynos_level_cmd_get(cmd, 16);
pBhvId = &bhvId;
pBhvArgs = &bhvArgs;
} }
} break;
// OBJECT_WITH_ACTS_EXT
case 0x3F: {
const char *bhvStr = dynos_level_get_token(dynos_level_cmd_get(cmd, 20));
if (bhvStr) {
bhvId = (u32) smlua_get_any_integer_mod_variable(bhvStr);
bhvArgs = (u32) dynos_level_cmd_get(cmd, 16);
pBhvId = &bhvId;
pBhvArgs = &bhvArgs;
}
} break;
// OBJECT_WITH_ACTS_EXT2
case 0x40: {
const char *bhvStr = dynos_level_get_token(dynos_level_cmd_get(cmd, 24));
if (bhvStr) {
bhvId = (u32) smlua_get_any_integer_mod_variable(bhvStr);
bhvArgs = (u32) dynos_level_cmd_get(cmd, 16);
pBhvId = &bhvId;
pBhvArgs = &bhvArgs;
}
} break;
// MACRO_OBJECTS
case 0x39: {
pMacroData = (MacroObject *) dynos_level_cmd_get(cmd, 4);
} break;
// None of the above
default: return 0;
}
// Retrieve Lua state
lua_State* L = gLuaState; lua_State* L = gLuaState;
if (L == NULL) { return 0; } if (L == NULL) { return 0; }
struct LuaLevelScriptParse* preprocess = &sLevelScriptParse; struct LuaLevelScriptParse* preprocess = &sLevelScriptParse;
lua_rawgeti(L, LUA_REGISTRYINDEX, preprocess->reference); lua_rawgeti(L, LUA_REGISTRYINDEX, preprocess->reference);
if (type == 0x1F) { // Push 'areaIndex'
u8 area = (u8) dynos_level_cmd_get(cmd, 2); if (pAreaIndex) {
lua_pushinteger(L, area); lua_pushinteger(L, *pAreaIndex);
} else { } else {
lua_pushnil(L); lua_pushnil(L);
} }
if (type == 0x24) { // Push 'bhvData'
const BehaviorScript *bhv = (const BehaviorScript *) dynos_level_cmd_get(cmd, 20); if (pBhvId && pBhvArgs) {
u32 behaviorArg = (u32) dynos_level_cmd_get(cmd, 16);
lua_newtable(L); lua_newtable(L);
lua_pushstring(L, "behavior"); lua_pushstring(L, "behavior");
lua_pushinteger(L, get_id_from_behavior(bhv)); lua_pushinteger(L, *pBhvId);
lua_settable(L, -3); lua_settable(L, -3);
lua_pushstring(L, "behaviorArg"); lua_pushstring(L, "behaviorArg");
lua_pushinteger(L, behaviorArg); lua_pushinteger(L, *pBhvArgs);
lua_settable(L, -3); lua_settable(L, -3);
} else { } else {
lua_pushnil(L); lua_pushnil(L);
} }
if (type == 0x39) { // Push 'macroBhvIds' and 'macroBhvArgs'
MacroObject *data = (MacroObject *) dynos_level_cmd_get(cmd, 4); if (pMacroData) {
int i = 0;
s32 len = 0;
lua_newtable(L); lua_newtable(L);
int t = lua_gettop(gLuaState); s32 macroBhvIdsIdx = lua_gettop(gLuaState);
lua_newtable(L); lua_newtable(L);
int args = lua_gettop(gLuaState); s32 macroBhvArgsIdx = lua_gettop(gLuaState);
while (data[len++] != MACRO_OBJECT_END()) { for (s32 i = 0; *pMacroData != MACRO_OBJECT_END(); pMacroData += 5, i++) {
s32 presetId = (s32) ((data[len - 1] & 0x1FF) - 0x1F); s32 presetId = (s32) ((pMacroData[0] & 0x1FF) - 0x1F);
const BehaviorScript *bhv = (const BehaviorScript *) MacroObjectPresets[presetId].behavior;
s32 presetParams = MacroObjectPresets[presetId].param; s32 presetParams = MacroObjectPresets[presetId].param;
s32 objParams = (data[4] & 0xFF00) + (presetParams & 0x00FF); s32 objParams = (pMacroData[4] & 0xFF00) | (presetParams & 0x00FF);
u32 behaviorArg = ((objParams & 0x00FF) << 16) + (objParams & 0xFF00); s32 bhvParams = ((objParams & 0x00FF) << 16) | (objParams & 0xFF00);
lua_pushinteger(L, i); lua_pushinteger(L, i);
lua_pushinteger(L, get_id_from_behavior(bhv)); lua_pushinteger(L, get_id_from_behavior(MacroObjectPresets[presetId].behavior));
lua_settable(L, t); lua_settable(L, macroBhvIdsIdx);
lua_pushinteger(L, i); lua_pushinteger(L, i);
lua_pushinteger(L, behaviorArg); lua_pushinteger(L, bhvParams);
lua_settable(L, args); lua_settable(L, macroBhvArgsIdx);
i++;
len += 4;
} }
} else { } else {
lua_pushnil(L); lua_pushnil(L);

View file

@ -271,8 +271,12 @@ static bool smlua_sync_table_send_field(u8 toLocalIndex, int stackIndex, bool al
// send over the network // send over the network
if (!gLuaInitializingScript) { if (!gLuaInitializingScript) {
if (sUnwoundLntsCount < 2) {
LOG_ERROR("Sent sync table field packet with an invalid key count: %u", sUnwoundLntsCount);
} else {
network_send_lua_sync_table(toLocalIndex, seq, modRemoteIndex, sUnwoundLntsCount, sUnwoundLnts, &lntValue); network_send_lua_sync_table(toLocalIndex, seq, modRemoteIndex, sUnwoundLntsCount, sUnwoundLnts, &lntValue);
} }
}
/////////////// ///////////////
@ -311,6 +315,12 @@ void smlua_set_sync_table_field_from_network(u64 seq, u16 modRemoteIndex, u16 ln
return; return;
} }
// sanity check key count
if (lntKeyCount < 2) {
LOG_ERROR("Received sync table field packet with an invalid key count: %u", lntKeyCount);
return;
}
lua_getglobal(L, "_G"); // get global table lua_getglobal(L, "_G"); // get global table
lua_getfield(L, LUA_REGISTRYINDEX, mod->relativePath); // get the file's "global" table lua_getfield(L, LUA_REGISTRYINDEX, mod->relativePath); // get the file's "global" table
lua_remove(L, -2); // remove global table lua_remove(L, -2); // remove global table

View file

@ -152,6 +152,9 @@ void mod_activate(struct Mod* mod) {
} }
void mod_clear(struct Mod* mod) { void mod_clear(struct Mod* mod) {
if (!mod) { return; }
if (mod->files) {
for (int j = 0; j < mod->fileCount; j++) { for (int j = 0; j < mod->fileCount; j++) {
struct ModFile* file = &mod->files[j]; struct ModFile* file = &mod->files[j];
if (file->fp != NULL) { if (file->fp != NULL) {
@ -163,6 +166,7 @@ void mod_clear(struct Mod* mod) {
file->cachedPath = NULL; file->cachedPath = NULL;
} }
} }
}
if (mod->name != NULL) { if (mod->name != NULL) {
free(mod->name); free(mod->name);
@ -437,15 +441,10 @@ bool mod_load(struct Mods* mods, char* basePath, char* modName) {
valid = true; valid = true;
} else if (is_directory(fullPath)) { } else if (is_directory(fullPath)) {
char tmpPath[SYS_MAX_PATH] = { 0 }; char tmpPath[SYS_MAX_PATH] = { 0 };
char path1[SYS_MAX_PATH] = { 0 };
char path2[SYS_MAX_PATH] = { 0 };
if (!concat_path(tmpPath, fullPath, "main.lua")) { if (!concat_path(tmpPath, fullPath, "main.lua")) {
LOG_ERROR("Failed to concat path '%s' + '%s'", fullPath, "main.lua"); LOG_ERROR("Failed to concat path '%s' + '%s'", fullPath, "main.lua");
return true; return true;
} }
if ((concat_path(path1, fullPath, "c-update.lua") && path_exists(path1)) || (concat_path(path2, fullPath, "m-update.lua") && path_exists(path2))) {
return true;
}
valid = path_exists(tmpPath); valid = path_exists(tmpPath);
} }
@ -513,13 +512,11 @@ bool mod_load(struct Mods* mods, char* basePath, char* modName) {
// print // print
LOG_INFO(" %s", mod->name); LOG_INFO(" %s", mod->name);
if (isDirectory) {
for (int i = 0; i < mod->fileCount; i++) { for (int i = 0; i < mod->fileCount; i++) {
struct ModFile* file = &mod->files[i]; struct ModFile* file = &mod->files[i];
mod_cache_add(mod, file, true); mod_cache_add(mod, file, true);
LOG_INFO(" - %s", file->relativePath); LOG_INFO(" - %s", file->relativePath);
} }
}
return true; return true;
} }

View file

@ -56,6 +56,7 @@ static bool mod_import_lua(char* src) {
static bool mod_import_zip(char* path, bool* isLua, bool* isDynos) { static bool mod_import_zip(char* path, bool* isLua, bool* isDynos) {
LOG_INFO("Importing zip mod: %s", path); LOG_INFO("Importing zip mod: %s", path);
char luaPath[SYS_MAX_PATH] = { 0 };
mz_zip_archive zip_archive = { 0 }; mz_zip_archive zip_archive = { 0 };
mz_bool status = mz_zip_reader_init_file(&zip_archive, path, 0); mz_bool status = mz_zip_reader_init_file(&zip_archive, path, 0);
if (!status) { if (!status) {
@ -75,6 +76,7 @@ static bool mod_import_zip(char* path, bool* isLua, bool* isDynos) {
} }
if (str_ends_with(file_stat.m_filename, ".lua")) { if (str_ends_with(file_stat.m_filename, ".lua")) {
path_get_folder(file_stat.m_filename, luaPath);
*isLua = true; *isLua = true;
break; break;
} else if (str_ends_with(file_stat.m_filename, ".tex")) { } else if (str_ends_with(file_stat.m_filename, ".tex")) {
@ -99,12 +101,32 @@ static bool mod_import_zip(char* path, bool* isLua, bool* isDynos) {
snprintf(dstDirectory, SYS_MAX_PATH, "%s", (char*)fs_get_write_path(DYNOS_PACKS_FOLDER)); snprintf(dstDirectory, SYS_MAX_PATH, "%s", (char*)fs_get_write_path(DYNOS_PACKS_FOLDER));
} else { } else {
LOG_ERROR("Could not figure out what type of mod this is"); LOG_ERROR("Could not figure out what type of mod this is");
mz_zip_reader_end(&zip_archive);
return false; return false;
} }
// create mod/dynos path if it doesn't exist
if (!fs_sys_dir_exists(dstDirectory)) { if (!fs_sys_dir_exists(dstDirectory)) {
fs_sys_mkdir(dstDirectory); fs_sys_mkdir(dstDirectory);
} }
// erase and create lua path
if (*isLua && strlen(luaPath) > 0) {
if (!concat_path(dst, dstDirectory, luaPath)) {
LOG_ERROR("Failed to concat path for base lua directory");
mz_zip_reader_end(&zip_archive);
return false;
}
if (fs_sys_dir_exists(dst)) {
mods_delete_folder(dst);
}
if (!fs_sys_mkdir(dst)) {
LOG_ERROR("Failed to mkdir for base lua directory");
mz_zip_reader_end(&zip_archive);
return false;
}
}
// Extract the archive // Extract the archive
for (int i = 0; i < (int)mz_zip_reader_get_num_files(&zip_archive); i++) { for (int i = 0; i < (int)mz_zip_reader_get_num_files(&zip_archive); i++) {
mz_zip_archive_file_stat file_stat; mz_zip_archive_file_stat file_stat;
@ -159,6 +181,8 @@ static bool mod_import_zip(char* path, bool* isLua, bool* isDynos) {
FILE* fout = fopen(dst, "wb"); FILE* fout = fopen(dst, "wb");
if (fout == NULL) { if (fout == NULL) {
LOG_ERROR("Failed to open dst path for zip mod import"); LOG_ERROR("Failed to open dst path for zip mod import");
mz_free((void*)p);
mz_zip_reader_end(&zip_archive);
return false; return false;
} }

View file

@ -132,6 +132,16 @@ void discord_activity_update(bool hosting) {
LOGFILE_INFO(LFT_DISCORD, "truncating details"); LOGFILE_INFO(LFT_DISCORD, "truncating details");
} }
if (!app.activities) {
LOGFILE_INFO(LFT_DISCORD, "no activities");
return;
}
if (!app.activities->update_activity) {
LOGFILE_INFO(LFT_DISCORD, "no update_activity");
return;
}
app.activities->update_activity(app.activities, &gCurActivity, NULL, on_activity_update_callback); app.activities->update_activity(app.activities, &gCurActivity, NULL, on_activity_update_callback);
LOGFILE_INFO(LFT_DISCORD, "set activity"); LOGFILE_INFO(LFT_DISCORD, "set activity");
} }

View file

@ -6,7 +6,7 @@
#include "behavior_table.h" #include "behavior_table.h"
#include "model_ids.h" #include "model_ids.h"
#define MAX_LOCAL_STATE_HISTORY 20 #define MAX_LOCAL_STATE_HISTORY 30
struct StateHistory { struct StateHistory {
struct MarioState m; struct MarioState m;
struct Object marioObj; struct Object marioObj;
@ -40,16 +40,16 @@ void lag_compensation_store(void) {
} }
struct MarioState* lag_compensation_get_local_state(struct NetworkPlayer* otherNp) { struct MarioState* lag_compensation_get_local_state(struct NetworkPlayer* otherNp) {
if (!otherNp) { return NULL; } if (!otherNp) { return &gMarioStates[0]; }
if (gNetworkType == NT_NONE) { return NULL; } if (gNetworkType == NT_NONE) { return &gMarioStates[0]; }
if (!sLocalStateHistoryReady) { return NULL; } if (!sLocalStateHistoryReady) { return &gMarioStates[0]; }
s32 pingToTicks = (otherNp->ping / 1000.0f) * 30; s32 pingToTicks = (otherNp->ping / 1000.0f) * 30;
if (pingToTicks > (MAX_LOCAL_STATE_HISTORY-1)) { if (pingToTicks > (MAX_LOCAL_STATE_HISTORY-1)) {
pingToTicks = (MAX_LOCAL_STATE_HISTORY-1); pingToTicks = (MAX_LOCAL_STATE_HISTORY-1);
} }
//LOG_INFO("Ping: %s :: %u :: %d", otherNp->name, otherNp->ping, pingToTicks); //LOG_INFO("Ping: %s :: %u :: %d", otherNp->name, otherNp->ping, pingToTicks);
if (pingToTicks == 0) { return NULL; } if (pingToTicks == 0) { return &gMarioStates[0]; }
s32 index = (s32)sLocalStateHistoryIndex - pingToTicks; s32 index = (s32)sLocalStateHistoryIndex - pingToTicks;
while (index < 0) { index += MAX_LOCAL_STATE_HISTORY; } while (index < 0) { index += MAX_LOCAL_STATE_HISTORY; }

View file

@ -52,8 +52,8 @@ void packet_process(struct Packet* p) {
case PACKET_JOIN: network_receive_join(p); break; case PACKET_JOIN: network_receive_join(p); break;
case PACKET_CHAT: network_receive_chat(p); break; case PACKET_CHAT: network_receive_chat(p); break;
case PACKET_KICK: network_receive_kick(p); break; case PACKET_KICK: network_receive_kick(p); break;
case PACKET_COMMAND: network_recieve_chat_command(p); break; case PACKET_COMMAND: network_receive_chat_command(p); break;
case PACKET_MODERATOR: network_recieve_moderator(p); break; case PACKET_MODERATOR: network_receive_moderator(p); break;
case PACKET_KEEP_ALIVE: network_receive_keep_alive(p); break; case PACKET_KEEP_ALIVE: network_receive_keep_alive(p); break;
case PACKET_LEAVING: network_receive_leaving(p); break; case PACKET_LEAVING: network_receive_leaving(p); break;
case PACKET_SAVE_FILE: network_receive_save_file(p); break; case PACKET_SAVE_FILE: network_receive_save_file(p); break;

View file

@ -234,11 +234,11 @@ void network_receive_kick(struct Packet* p);
// packet_command_mod.c // packet_command_mod.c
void network_send_chat_command(u8 localIndex, enum ChatConfirmCommand CCC); void network_send_chat_command(u8 localIndex, enum ChatConfirmCommand CCC);
void network_recieve_chat_command(struct Packet* p); void network_receive_chat_command(struct Packet* p);
// packet_moderator.c // packet_moderator.c
void network_send_moderator(u8 localIndex); void network_send_moderator(u8 localIndex);
void network_recieve_moderator(struct Packet* p); void network_receive_moderator(struct Packet* p);
// packet_keep_alive.c // packet_keep_alive.c
void network_send_keep_alive(u8 localIndex); void network_send_keep_alive(u8 localIndex);

View file

@ -138,7 +138,7 @@ void network_receive_area(struct Packet* p) {
LOG_INFO("rx area"); LOG_INFO("rx area");
if (p == NULL) { if (p == NULL) {
LOG_ERROR("rx area: the packet was NULL, failed to recieve the area."); LOG_ERROR("rx area: the packet was NULL, failed to receive the area.");
return; return;
} }

View file

@ -18,7 +18,7 @@ void network_send_chat_command(u8 globalIndex, enum ChatConfirmCommand ccc) {
} }
} }
void network_recieve_chat_command(struct Packet *p) { void network_receive_chat_command(struct Packet *p) {
if (!moderator_list_contains(gNetworkSystem->get_id_str(p->localIndex))) { if (!moderator_list_contains(gNetworkSystem->get_id_str(p->localIndex))) {
return; return;
} }
@ -59,7 +59,7 @@ void network_send_moderator(u8 localIndex) {
network_send_to(localIndex, &p); network_send_to(localIndex, &p);
} }
void network_recieve_moderator(struct Packet *p) { void network_receive_moderator(struct Packet *p) {
if ((gIsModerator) || (network_player_any_connected() && gNetworkPlayers[p->localIndex].type != NPT_SERVER)) { if ((gIsModerator) || (network_player_any_connected() && gNetworkPlayers[p->localIndex].type != NPT_SERVER)) {
return; return;
} }

View file

@ -332,6 +332,11 @@ static void open_mod_file(struct Mod* mod, struct ModFile* file) {
} }
void network_receive_download(struct Packet* p) { void network_receive_download(struct Packet* p) {
if (!p) {
LOG_ERROR("Received null packet");
return;
}
SOFT_ASSERT(gNetworkType == NT_CLIENT); SOFT_ASSERT(gNetworkType == NT_CLIENT);
if (p->localIndex != UNKNOWN_LOCAL_INDEX) { if (p->localIndex != UNKNOWN_LOCAL_INDEX) {
if (gNetworkPlayerServer == NULL || gNetworkPlayerServer->localIndex != p->localIndex) { if (gNetworkPlayerServer == NULL || gNetworkPlayerServer->localIndex != p->localIndex) {
@ -343,9 +348,13 @@ void network_receive_download(struct Packet* p) {
// read the chunk // read the chunk
u64 receiveOffset = 0; u64 receiveOffset = 0;
u64 chunkLength = 0; u64 chunkLength = 0;
u8 chunk[CHUNK_SIZE] = { 0 }; u8 chunk[CHUNK_SIZE+1] = { 0 };
packet_read(p, &receiveOffset, sizeof(u64)); packet_read(p, &receiveOffset, sizeof(u64));
packet_read(p, &chunkLength, sizeof(u64)); packet_read(p, &chunkLength, sizeof(u64));
if (chunkLength > CHUNK_SIZE) {
LOG_ERROR("Received improper chunk length");
return;
}
packet_read(p, &chunk, sizeof(u8) * chunkLength); packet_read(p, &chunk, sizeof(u8) * chunkLength);
// mark the offset group as received // mark the offset group as received
@ -379,6 +388,10 @@ after_group:;
u64 fileStartOffset = 0; u64 fileStartOffset = 0;
for (u64 modIndex = 0; modIndex < gRemoteMods.entryCount; modIndex++) { for (u64 modIndex = 0; modIndex < gRemoteMods.entryCount; modIndex++) {
struct Mod* mod = gRemoteMods.entries[modIndex]; struct Mod* mod = gRemoteMods.entries[modIndex];
if (!mod) {
LOG_ERROR("Null mod");
continue;
}
// skip past mods to get to the right offset // skip past mods to get to the right offset
if ((fileStartOffset + mod->size) < receiveOffset) { if ((fileStartOffset + mod->size) < receiveOffset) {
@ -386,6 +399,11 @@ after_group:;
continue; continue;
} }
if (mod->fileCount > 0 && !mod->files) {
LOG_ERROR("Null mod files");
continue;
}
for (u64 fileIndex = 0; fileIndex < mod->fileCount; fileIndex++) { for (u64 fileIndex = 0; fileIndex < mod->fileCount; fileIndex++) {
struct ModFile* modFile = &mod->files[fileIndex]; struct ModFile* modFile = &mod->files[fileIndex];

View file

@ -11,6 +11,11 @@ void network_send_lua_custom(bool broadcast) {
u16 zero = 0; u16 zero = 0;
s32 paramIndex = 1; s32 paramIndex = 1;
if (!L) {
LOG_ERROR("Sent lua custom packet when lua is dead");
return;
}
// figure out mod index // figure out mod index
if (gLuaActiveMod == NULL) { if (gLuaActiveMod == NULL) {
LOG_LUA_LINE("Could not figure out the current active mod!"); LOG_LUA_LINE("Could not figure out the current active mod!");
@ -99,6 +104,11 @@ void network_receive_lua_custom(struct Packet* p) {
packet_read(p, &modIndex, sizeof(u16)); packet_read(p, &modIndex, sizeof(u16));
packet_read(p, &keyCount, sizeof(u8)); packet_read(p, &keyCount, sizeof(u8));
if (!L) {
LOG_ERROR("Received lua custom packet when lua is dead");
return;
}
lua_newtable(L); lua_newtable(L);
s32 tableIndex = lua_gettop(L); s32 tableIndex = lua_gettop(L);
for(u16 i = 0; i < keyCount; i++) { for(u16 i = 0; i < keyCount; i++) {

View file

@ -36,6 +36,7 @@ void network_send_lua_sync_table(u8 toLocalIndex, u64 seq, u16 modRemoteIndex, u
//LOG_INFO(" %s", smlua_lnt_to_str(&lntKeys[i])); //LOG_INFO(" %s", smlua_lnt_to_str(&lntKeys[i]));
} }
//LOG_INFO(" -> %s", smlua_lnt_to_str(lntValue)); //LOG_INFO(" -> %s", smlua_lnt_to_str(lntValue));
//LOG_INFO(" count %u", lntKeyCount);
if (!packet_write_lnt(&p, lntValue)) { return; } if (!packet_write_lnt(&p, lntValue)) { return; }
@ -66,6 +67,7 @@ void network_receive_lua_sync_table(struct Packet* p) {
//LOG_INFO(" %s", smlua_lnt_to_str(&lntKeys[i])); //LOG_INFO(" %s", smlua_lnt_to_str(&lntKeys[i]));
} }
//LOG_INFO(" -> %s", smlua_lnt_to_str(&lntValue)); //LOG_INFO(" -> %s", smlua_lnt_to_str(&lntValue));
//LOG_INFO(" count %u", lntKeyCount);
if (!packet_read_lnt(p, &lntValue)) { goto cleanup; } if (!packet_read_lnt(p, &lntValue)) { goto cleanup; }

View file

@ -28,7 +28,10 @@ void network_send_mod_list_request(void) {
} }
void network_receive_mod_list_request(UNUSED struct Packet* p) { void network_receive_mod_list_request(UNUSED struct Packet* p) {
SOFT_ASSERT(gNetworkType == NT_SERVER); if (gNetworkType != NT_SERVER) {
LOG_ERROR("Network type should be server!");
return;
}
LOG_INFO("received mod list request"); LOG_INFO("received mod list request");
network_send_mod_list(); network_send_mod_list();

View file

@ -59,6 +59,11 @@ void network_send_spawn_objects_to(u8 sendToLocalIndex, struct Object* objects[]
return; return;
} }
if (objectCount == 0) {
LOG_ERROR("Tried to send 0 objects");
return;
}
SOFT_ASSERT(objectCount < MAX_SPAWN_OBJECTS_PER_PACKET); SOFT_ASSERT(objectCount < MAX_SPAWN_OBJECTS_PER_PACKET);
// prevent sending spawn objects during credits // prevent sending spawn objects during credits
if (gCurrActStarNum == 99) { if (gCurrActStarNum == 99) {
@ -74,6 +79,11 @@ void network_send_spawn_objects_to(u8 sendToLocalIndex, struct Object* objects[]
for (u8 i = 0; i < objectCount; i++) { for (u8 i = 0; i < objectCount; i++) {
struct Object* o = objects[i]; struct Object* o = objects[i];
if (!o) {
LOG_ERROR("Tried to send null object");
return;
}
u32 model = models[i]; u32 model = models[i];
u32 parentId = generate_parent_id(objects, i, true); u32 parentId = generate_parent_id(objects, i, true);
u32 behaviorId = get_id_from_behavior(o->behavior); u32 behaviorId = get_id_from_behavior(o->behavior);
@ -96,12 +106,16 @@ void network_send_spawn_objects_to(u8 sendToLocalIndex, struct Object* objects[]
if (sendToLocalIndex == PACKET_DESTINATION_BROADCAST) { if (sendToLocalIndex == PACKET_DESTINATION_BROADCAST) {
network_send(&p); network_send(&p);
if (objects[0] && objects[0]->behavior) {
LOG_INFO("tx spawn objects (BROADCAST) | %u", get_id_from_behavior(objects[0]->behavior)); LOG_INFO("tx spawn objects (BROADCAST) | %u", get_id_from_behavior(objects[0]->behavior));
}
} else { } else {
network_send_to(sendToLocalIndex, &p); network_send_to(sendToLocalIndex, &p);
if (objects[0] && objects[0]->behavior) {
LOG_INFO("tx spawn objects to %d | %u", gNetworkPlayers[sendToLocalIndex].globalIndex, get_id_from_behavior(objects[0]->behavior)); LOG_INFO("tx spawn objects to %d | %u", gNetworkPlayers[sendToLocalIndex].globalIndex, get_id_from_behavior(objects[0]->behavior));
} }
} }
}
void network_receive_spawn_objects(struct Packet* p) { void network_receive_spawn_objects(struct Packet* p) {
LOG_INFO("rx spawn objects"); LOG_INFO("rx spawn objects");

View file

@ -3,7 +3,7 @@
#define VERSION_TEXT "beta" #define VERSION_TEXT "beta"
#define VERSION_NUMBER 33 #define VERSION_NUMBER 33
#define MINOR_VERSION_NUMBER 0 #define MINOR_VERSION_NUMBER 1
#define PATCH_VERSION_NUMBER 0 #define PATCH_VERSION_NUMBER 0
#define MAX_VERSION_LENGTH 10 #define MAX_VERSION_LENGTH 10

View file

@ -14,6 +14,7 @@ u64 osClockRate = 62500000;
s32 osPiStartDma(UNUSED OSIoMesg *mb, UNUSED s32 priority, UNUSED s32 direction, s32 osPiStartDma(UNUSED OSIoMesg *mb, UNUSED s32 priority, UNUSED s32 direction,
uintptr_t devAddr, void *vAddr, size_t nbytes, uintptr_t devAddr, void *vAddr, size_t nbytes,
UNUSED OSMesgQueue *mq) { UNUSED OSMesgQueue *mq) {
if (!vAddr || !devAddr) { return 0; }
memcpy(vAddr, (const void *) devAddr, nbytes); memcpy(vAddr, (const void *) devAddr, nbytes);
return 0; return 0;
} }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 9.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB