mirror of
https://github.com/coop-deluxe/sm64coopdx.git
synced 2026-04-26 12:01:43 +00:00
Merge 1f184c360b into ba54cbd1d0
This commit is contained in:
commit
d924d7002f
11 changed files with 2317 additions and 2246 deletions
2
Makefile
2
Makefile
|
|
@ -92,7 +92,7 @@ WINDOWS_AUTO_BUILDER ?= 0
|
|||
# Setup extra cflags
|
||||
EXTRA_CFLAGS ?=
|
||||
EXTRA_CPP_FLAGS ?=
|
||||
EXTRA_CFLAGS += -Wno-format-security -Wno-trigraphs
|
||||
EXTRA_CFLAGS += -Wno-format-security -Wno-trigraphs -Wno-missing-braces -Wno-missing-field-initializers
|
||||
|
||||
dev:; @$(MAKE) DEVELOPMENT=1
|
||||
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ usf_types = ['u8', 'u16', 'u32', 'u64', 's8', 's16', 's32', 's64', 'f32', 'f64']
|
|||
vec_types = list(VEC_TYPES.keys())
|
||||
typedef_pointers = ['BehaviorScript', 'ObjectAnimPointer', 'Collision', 'LevelScript', 'Trajectory', 'Texture']
|
||||
cobject_function_identifier = 'FUNCTION'
|
||||
cobject_property_identifier = 'PROPERTY'
|
||||
|
||||
type_mappings = {
|
||||
'char': 's8',
|
||||
|
|
@ -149,14 +150,10 @@ def translate_type_to_lvt(ptype, allowArrays=False):
|
|||
if ptype == cobject_function_identifier:
|
||||
return "LVT_FUNCTION"
|
||||
|
||||
if "struct" in ptype:
|
||||
if pointerLvl > 1:
|
||||
return "LVT_???"
|
||||
if pointerLvl == 1:
|
||||
return "LVT_COBJECT_P"
|
||||
return "LVT_COBJECT"
|
||||
if ptype == cobject_property_identifier:
|
||||
return "LVT_PROPERTY"
|
||||
|
||||
if ptype in override_types:
|
||||
if "struct" in ptype or ptype in override_types:
|
||||
if pointerLvl > 1:
|
||||
return "LVT_???"
|
||||
if pointerLvl == 1:
|
||||
|
|
@ -174,16 +171,8 @@ def translate_type_to_lot(ptype, allowArrays=True):
|
|||
pointerLvl = 0
|
||||
lvt = translate_type_to_lvt(ptype, allowArrays=allowArrays)
|
||||
|
||||
if ptype == 'void':
|
||||
return 'LOT_NONE'
|
||||
|
||||
if ptype == 'const char*':
|
||||
return 'LOT_NONE'
|
||||
|
||||
if ptype == 'ByteString':
|
||||
return 'LOT_NONE'
|
||||
|
||||
if 'unsigned' not in ptype and (ptype == 'char*' or ('char' in ptype and '[' in ptype)):
|
||||
if ptype == ('void', 'const char*', 'ByteString') \
|
||||
or 'unsigned' not in ptype and (ptype == 'char*' or ('char' in ptype and '[' in ptype)):
|
||||
return 'LOT_NONE'
|
||||
|
||||
# Remove array symbols so they can be identified
|
||||
|
|
@ -199,13 +188,7 @@ def translate_type_to_lot(ptype, allowArrays=True):
|
|||
if '[' in ptype or '{' in ptype:
|
||||
return 'LOT_???'
|
||||
|
||||
if 'enum ' in ptype:
|
||||
return 'LOT_NONE'
|
||||
|
||||
if ptype in usf_types:
|
||||
return 'LOT_NONE'
|
||||
|
||||
if extract_integer_datatype(ptype):
|
||||
if 'enum ' in ptype or ptype in usf_types or extract_integer_datatype(ptype):
|
||||
return 'LOT_NONE'
|
||||
|
||||
# Strip out our pointer stars to get the true type.
|
||||
|
|
@ -214,22 +197,10 @@ def translate_type_to_lot(ptype, allowArrays=True):
|
|||
pointerLvl = ptype.count("*")
|
||||
ptype = ptype.replace("*", "").strip()
|
||||
|
||||
if ptype == 'bool':
|
||||
return 'LOT_NONE'
|
||||
|
||||
if ptype in vec_types:
|
||||
return 'LOT_' + ptype.upper()
|
||||
|
||||
if ptype == 'float':
|
||||
return 'LOT_NONE'
|
||||
|
||||
if ptype == 'LuaFunction':
|
||||
return 'LOT_NONE'
|
||||
|
||||
if ptype == 'LuaTable':
|
||||
return 'LOT_NONE'
|
||||
|
||||
if ptype == cobject_function_identifier:
|
||||
if ptype in ('bool', 'float', 'LuaFunction', 'LuaTable', cobject_function_identifier, cobject_property_identifier):
|
||||
return 'LOT_NONE'
|
||||
|
||||
if ptype in override_types:
|
||||
|
|
@ -291,22 +262,10 @@ def translate_type_to_lua(ptype):
|
|||
return '`number`', None
|
||||
return '`integer`', None
|
||||
|
||||
if ptype == 'char':
|
||||
if ptype in ('char', 'int', 'lua_Integer'):
|
||||
return '`integer`', None
|
||||
|
||||
if ptype == 'int':
|
||||
return '`integer`', None
|
||||
|
||||
if ptype == 'lua_Integer':
|
||||
return '`integer`', None
|
||||
|
||||
if ptype == 'float':
|
||||
return '`number`', None
|
||||
|
||||
if ptype == 'lua_Number':
|
||||
return '`number`', None
|
||||
|
||||
if ptype == 'double':
|
||||
if ptype in ('float', 'lua_Number', 'double'):
|
||||
return '`number`', None
|
||||
|
||||
if ptype == 'bool':
|
||||
|
|
@ -324,6 +283,9 @@ def translate_type_to_lua(ptype):
|
|||
if ptype == cobject_function_identifier:
|
||||
return cobject_function_identifier, None
|
||||
|
||||
if ptype == cobject_property_identifier:
|
||||
return cobject_property_identifier, None
|
||||
|
||||
if ptype.count('*') == 1 and '???' not in translate_type_to_lvt(ptype):
|
||||
ptype = ptype.replace('const', '').replace('*', '').strip()
|
||||
s = '`Pointer` <`%s`>' % translate_type_to_lua(ptype)[0].replace('`', '').strip()
|
||||
|
|
|
|||
|
|
@ -264,10 +264,17 @@ def table_to_string(table):
|
|||
|
||||
for row in table:
|
||||
for i in range(columns):
|
||||
if '#' in row[i]:
|
||||
if '#' in row[i] or row[i][-1] == '\\':
|
||||
continue
|
||||
if len(row[i]) > column_width[i]:
|
||||
column_width[i] = len(row[i])
|
||||
|
||||
for row in table:
|
||||
for i in range(columns):
|
||||
if row[i][-1] == '\\':
|
||||
row[i] = row[i][:-1]
|
||||
row[i+1] = row[i][column_width[i]:] + row[i+1]
|
||||
row[i] = row[i][:column_width[i]]
|
||||
|
||||
s = ''
|
||||
for row in table:
|
||||
|
|
@ -327,12 +334,21 @@ def parse_struct(struct_str, sortFields = False):
|
|||
|
||||
# handle function members
|
||||
if field['type'].startswith(cobject_function_identifier):
|
||||
field_function = field['identifier']
|
||||
field_type, field_id = field['type'].split()
|
||||
field_function = field['identifier']
|
||||
field['type'] = field_type.strip()
|
||||
field['identifier'] = field_id.strip('"').strip()
|
||||
field['identifier'] = field_id.strip()
|
||||
field['function'] = field_function.strip()
|
||||
|
||||
# handle property members
|
||||
if field['type'].startswith(cobject_property_identifier):
|
||||
field_type, field_id, field_get = field['type'].split()
|
||||
field_set = field['identifier']
|
||||
field['type'] = field_type.strip()
|
||||
field['identifier'] = field_id.strip()
|
||||
field['get'] = field_get.strip()
|
||||
field['set'] = field_set.strip()
|
||||
|
||||
struct['fields'].append(field)
|
||||
|
||||
if identifier == 'Object':
|
||||
|
|
@ -496,9 +512,6 @@ def get_struct_field_info(struct, field):
|
|||
if fid in override_field_mutable[sid] or '*' in override_field_mutable[sid]:
|
||||
fimmutable = 'false'
|
||||
|
||||
if ftype == cobject_function_identifier:
|
||||
fimmutable = 'true'
|
||||
|
||||
if not ('char' in ftype and '[' in ftype and 'unsigned' not in ftype):
|
||||
array_match = re.search(r'\[([^\]]+)\]', ftype)
|
||||
if array_match:
|
||||
|
|
@ -549,27 +562,26 @@ def build_struct(struct):
|
|||
startStr += '#ifndef ' + override_field_version_excludes[fid] + '\n'
|
||||
endStr += '\n#endif'
|
||||
startStr += ' { '
|
||||
if ftype == cobject_function_identifier:
|
||||
row.append(startStr )
|
||||
row.append('"%s", ' % fid )
|
||||
row.append('%s, ' % lvt )
|
||||
row.append('(size_t) "%s", ' % field['function'])
|
||||
row.append('%s, ' % fimmutable )
|
||||
row.append('%s, ' % lot )
|
||||
row.append('%s, ' % size )
|
||||
row.append('sizeof(const char *)' )
|
||||
row.append(endStr )
|
||||
field_functions.append(field['function'])
|
||||
row.append(startStr)
|
||||
row.append('"%s", ' % fid)
|
||||
row.append('%s, ' % lvt)
|
||||
if field.get('function'):
|
||||
row.append('.function = "%s"\\' % field['function'])
|
||||
elif field.get('get'):
|
||||
row.append('.get = "%s", ' % field['get'])
|
||||
row.append('.set = "%s"\\' % field['set'])
|
||||
else:
|
||||
row.append(startStr )
|
||||
row.append('"%s", ' % fid )
|
||||
row.append('%s, ' % lvt )
|
||||
row.append('offsetof(%s%s, %s), ' % (struct_str, name, field['identifier']))
|
||||
row.append('%s, ' % fimmutable )
|
||||
row.append('%s, ' % lot )
|
||||
row.append('%s, ' % size )
|
||||
row.append('sizeof(%s)' % ftype )
|
||||
row.append(endStr )
|
||||
row.append('%s, ' % fimmutable)
|
||||
row.append('%s, ' % lot )
|
||||
if size != 1:
|
||||
row.append('%s, ' % size )
|
||||
row.append('sizeof(%s)' % ftype )
|
||||
else: row[-1] = row[-1][:-2]
|
||||
row.extend(['\\'] * (8 - len(row)))
|
||||
row.append(endStr)
|
||||
if field.get('function'):
|
||||
field_functions.append(field['function'])
|
||||
field_table.append(row)
|
||||
|
||||
field_table_str, field_count = table_to_string(field_table)
|
||||
|
|
@ -726,6 +738,10 @@ def doc_struct_field(struct, field):
|
|||
flink = doc_find_function_link(field['function'])
|
||||
return '| %s | [`%s`](%s) |\n' % (fid, field['function'], flink), True
|
||||
|
||||
if ftype == cobject_property_identifier:
|
||||
ftype = get_function_signature(field['get'])
|
||||
ftype = f"`{ftype[ftype.rfind(':')+2:]}`"
|
||||
|
||||
restrictions = ('', 'read-only')[fimmutable == 'true']
|
||||
|
||||
global total_fields
|
||||
|
|
@ -854,6 +870,9 @@ def def_struct(struct):
|
|||
# try to get the function signature
|
||||
if ftype == cobject_function_identifier:
|
||||
ftype = get_function_signature(field['function'])
|
||||
elif ftype == cobject_property_identifier:
|
||||
ftype = get_function_signature(field['get'])
|
||||
ftype = f"{ftype[ftype.rfind(':')+2:]}"
|
||||
else:
|
||||
ftype = translate_to_def(ftype)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import os
|
||||
import re
|
||||
import sys
|
||||
from common import cobject_function_identifier
|
||||
from common import cobject_function_identifier, cobject_property_identifier
|
||||
|
||||
def extract_structs(filename):
|
||||
with open(filename) as file:
|
||||
|
|
@ -38,7 +38,10 @@ def extract_structs(filename):
|
|||
txt = txt.replace(' ', ' ')
|
||||
|
||||
# handle function members (NOT function pointers)
|
||||
txt = re.sub(f'{cobject_function_identifier}\\((.*),(.*)\\)', f'{cobject_function_identifier} \\1 \\2', txt)
|
||||
txt = re.sub(f'{cobject_function_identifier}\\((.*),(.*)\\)', f'{cobject_function_identifier} \\1\\2', txt)
|
||||
|
||||
# handle property members
|
||||
txt = re.sub(f'{cobject_property_identifier}\\((.*),(.*),(.*)\\)', f'{cobject_property_identifier} \\1\\2\\3', txt)
|
||||
|
||||
# strip macros
|
||||
txt = re.sub(r'[^a-zA-Z0-9_][A-Z0-9_]+\(.*\)', '', txt)
|
||||
|
|
|
|||
|
|
@ -1199,6 +1199,10 @@
|
|||
--- @field public isStream boolean
|
||||
--- @field public baseVolume number
|
||||
--- @field public loaded boolean
|
||||
--- @field public position number
|
||||
--- @field public looping boolean
|
||||
--- @field public frequency number
|
||||
--- @field public volume number
|
||||
|
||||
--- @class ModFs
|
||||
--- @field public mod Mod
|
||||
|
|
|
|||
|
|
@ -1747,6 +1747,10 @@
|
|||
| isStream | `boolean` | read-only |
|
||||
| baseVolume | `number` | |
|
||||
| loaded | `boolean` | read-only |
|
||||
| position | `number` | |
|
||||
| looping | `boolean` | |
|
||||
| frequency | `number` | |
|
||||
| volume | `number` | |
|
||||
|
||||
[:arrow_up_small:](#)
|
||||
|
||||
|
|
|
|||
|
|
@ -21,6 +21,11 @@
|
|||
// Optional parameters must be contiguous until the last parameter (a mandatory parameter following an optional parameter is not allowed)
|
||||
#define OPTIONAL
|
||||
|
||||
// A macro to tell autogen the field `name` is a property member of the struct that calls `get` or `set` accessors
|
||||
// - get: fun(self) -> value
|
||||
// - set: fun(self, value)
|
||||
#define PROPERTY(name, get, set)
|
||||
|
||||
// A macro to tell autogen the field `name` is a function member of the struct that calls `c_function`
|
||||
#define FUNCTION(name, c_function)
|
||||
|
||||
|
|
|
|||
|
|
@ -101,6 +101,7 @@ static const char *sLuaLvtNames[] = {
|
|||
[LVT_LUATABLE] = "LuaTable",
|
||||
[LVT_POINTER] = "pointer",
|
||||
[LVT_FUNCTION] = "function",
|
||||
[LVT_PROPERTY] = "property",
|
||||
[LVT_MAX] = "unknown",
|
||||
};
|
||||
|
||||
|
|
@ -552,22 +553,30 @@ static int smlua__get_field(lua_State* L) {
|
|||
|
||||
// CObject function members
|
||||
if (data->valueType == LVT_FUNCTION) {
|
||||
const char *function = (const char *) data->valueOffset;
|
||||
lua_getglobal(L, function);
|
||||
lua_getglobal(L, data->function);
|
||||
LUA_STACK_CHECK_END(L);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// CObject property
|
||||
if (data->valueType == LVT_PROPERTY) {
|
||||
lua_getglobal(L, data->get);
|
||||
lua_pushvalue(L, 1);
|
||||
smlua_pcall(L, 1, 1, 0);
|
||||
LUA_STACK_CHECK_END(L);
|
||||
return 1;
|
||||
}
|
||||
|
||||
u8* p = ((u8*)(intptr_t)pointer) + data->valueOffset;
|
||||
if (data->count == 1) {
|
||||
if (smlua_push_field(L, p, data)) {
|
||||
LOG_LUA_LINE("_get_field on unimplemented type '%d', key '%s'", data->valueType, key);
|
||||
if (data->count > 1) {
|
||||
smlua_push_object(L, LOT_ARRAY, p, data);
|
||||
if (!gSmLuaConvertSuccess) {
|
||||
LOG_LUA_LINE("_get_field failed to retrieve value type '%d', key '%s'", data->valueType, key);
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
smlua_push_object(L, LOT_ARRAY, p, data);
|
||||
if (!gSmLuaConvertSuccess) {
|
||||
LOG_LUA_LINE("_set_field failed to retrieve value type '%d', key '%s'", data->valueType, key);
|
||||
if (smlua_push_field(L, p, data)) {
|
||||
LOG_LUA_LINE("_get_field on unimplemented type '%d', key '%s'", data->valueType, key);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
@ -633,7 +642,17 @@ static int smlua__set_field(lua_State* L) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (data->immutable) {
|
||||
// CObject property
|
||||
if (data->valueType == LVT_PROPERTY) {
|
||||
lua_getglobal(L, data->set);
|
||||
lua_pushvalue(L, 1);
|
||||
lua_pushvalue(L, 3);
|
||||
smlua_pcall(L, 2, 1, 0);
|
||||
LUA_STACK_CHECK_END(L);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (data->immutable || data->valueType == LVT_FUNCTION) {
|
||||
LOG_LUA_LINE("_set_field on immutable key '%s'", key);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -652,6 +671,41 @@ static int smlua__set_field(lua_State* L) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
int smlua__iter(lua_State *L) {
|
||||
lua_rawgeti(L, 1, 1);
|
||||
int i = lua_tointeger(L, -1);
|
||||
lua_pop(L, 1);
|
||||
|
||||
lua_rawgeti(L, 1, 2);
|
||||
const CObject *cobj = lua_touserdata(L, -1);
|
||||
lua_pop(L, 1);
|
||||
|
||||
extern struct LuaObjectTable sLuaObjectAutogenTable[];
|
||||
struct LuaObjectTable* ot = &sLuaObjectAutogenTable[cobj->lot - LOT_AUTOGEN_MIN - 1];
|
||||
if (i >= ot->fieldCount) { return 0; }
|
||||
|
||||
u8* pointer = (u8*)(intptr_t) cobj->pointer;
|
||||
struct LuaObjectField* data = &ot->fields[i];
|
||||
lua_pushstring(L, data->key);
|
||||
smlua_push_field(L, pointer, data);
|
||||
|
||||
lua_pushinteger(L, ++i);
|
||||
lua_rawseti(L, 1, 1);
|
||||
|
||||
return 2;
|
||||
}
|
||||
|
||||
int smlua__pairs(lua_State *L) {
|
||||
lua_pushcfunction(L, smlua__iter);
|
||||
|
||||
lua_newtable(L);
|
||||
lua_pushinteger(L, 0); lua_rawseti(L, -2, 1);
|
||||
lua_pushvalue (L, 1); lua_rawseti(L, -2, 2);
|
||||
|
||||
lua_pushnil(L);
|
||||
return 3;
|
||||
}
|
||||
|
||||
int smlua__eq(lua_State *L) {
|
||||
const CObject *a = lua_touserdata(L, 1);
|
||||
const CObject *b = lua_touserdata(L, 2);
|
||||
|
|
@ -704,6 +758,7 @@ void smlua_cobject_init_globals(void) {
|
|||
luaL_Reg cObjectMethods[] = {
|
||||
{ "__index", smlua__get_field },
|
||||
{ "__newindex", smlua__set_field },
|
||||
{ "__pairs", smlua__pairs },
|
||||
{ "__eq", smlua__eq },
|
||||
{ "__bnot", smlua__bnot },
|
||||
{ "__metatable", NULL },
|
||||
|
|
|
|||
|
|
@ -36,17 +36,27 @@ enum LuaValueType {
|
|||
LVT_LUATABLE,
|
||||
LVT_POINTER,
|
||||
LVT_FUNCTION,
|
||||
LVT_PROPERTY,
|
||||
LVT_MAX,
|
||||
};
|
||||
|
||||
struct LuaObjectField {
|
||||
const char* key;
|
||||
enum LuaValueType valueType;
|
||||
size_t valueOffset;
|
||||
bool immutable;
|
||||
u16 lot;
|
||||
u16 count;
|
||||
u32 size;
|
||||
union {
|
||||
struct {
|
||||
size_t valueOffset;
|
||||
bool immutable;
|
||||
u16 lot;
|
||||
u16 count;
|
||||
u32 size;
|
||||
};
|
||||
const char* function;
|
||||
struct {
|
||||
const char* get;
|
||||
const char* set;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
struct LuaObjectTable {
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -33,6 +33,11 @@ struct ModAudio {
|
|||
bool isStream;
|
||||
f32 baseVolume;
|
||||
bool loaded;
|
||||
|
||||
PROPERTY(position, audio_stream_get_position, audio_stream_set_position);
|
||||
PROPERTY(looping, audio_stream_get_looping, audio_stream_set_looping);
|
||||
PROPERTY(frequency, audio_stream_get_frequency, audio_stream_set_frequency);
|
||||
PROPERTY(volume, audio_stream_get_volume, audio_stream_set_volume);
|
||||
};
|
||||
|
||||
/* |description|Loads an `audio` stream by `filename` (with extension)|descriptionEnd| */
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue