Skip to content

Instantly share code, notes, and snippets.

@BenjaminUrquhart
Created December 20, 2024 09:38
Show Gist options
  • Select an option

  • Save BenjaminUrquhart/5c8ca2efa0d4746d5171f5250f08790d to your computer and use it in GitHub Desktop.

Select an option

Save BenjaminUrquhart/5c8ca2efa0d4746d5171f5250f08790d to your computer and use it in GitHub Desktop.
I will not elaborate. Requires Gamemaker 2022.5 or later as-is.
__get_default_datafile = function() {
switch(os_type) {
case os_windows: return "data.win";
case os_linux: return "game.unx";
default: throw $"Unsupported OS {os_type}";
}
}
__get_event_table = function() {
static event_table = undefined;
if(is_undefined(event_table)) {
var datafile = ""
var num_params = parameter_count()
if (num_params) {
for(var i = 0; i < num_params; i++) {
var param = parameter_string(i)
if(string_lower(param) == "-game") {
datafile = parameter_string(i + 1)
break;
}
}
if(datafile == "") {
datafile = __get_default_datafile()
}
}
else {
datafile = __get_default_datafile()
}
var buff = buffer_load(datafile)
assert(buffer_exists(buff), "Failed to load data file")
try {
var filesize = buffer_get_size(buff)
var found = false
var pos;
// Skip FORM
buffer_seek(buff, buffer_seek_start, 8)
while(buffer_tell(buff) < filesize) {
var chunk = buffer_read_string(buff, 4)
var size = buffer_read(buff, buffer_s32)
pos = buffer_tell(buff)
show_debug_message($"0x{pos <= 8 ? "0" : string(ptr(pos - 8))}: {chunk} (size: {size})")
if(chunk == "OBJT") {
show_debug_message($"Found OBJT chunk")
found = true
break;
}
buffer_seek(buff, buffer_seek_relative, size)
}
assert(found, "failed to locate OBJT chunk")
var num_objects = buffer_read(buff, buffer_s32)
var obj_ptrs = array_create(num_objects, -1)
for(var i = 0; i < num_objects; i++) {
obj_ptrs[i] = buffer_read(buff, buffer_s32)
}
event_table = array_create(num_objects, undefined)
for(var i = 0; i < num_objects; i++) {
buffer_seek(buff, buffer_seek_start, obj_ptrs[i])
var name_ptr = buffer_read(buff, buffer_s32)
buffer_seek(buff, buffer_seek_start, name_ptr)
var name = buffer_read(buff, buffer_string)
show_debug_message(name)
expect(name, object_get_name(i), "Object name mismatch")
buffer_seek(buff, buffer_seek_start, obj_ptrs[i] + 68)
var vertex_count = buffer_read(buff, buffer_s32)
buffer_seek(buff, buffer_seek_relative, 12 + vertex_count * 8)
var event_count = buffer_read(buff, buffer_s32)
var event_ptrs = array_create(event_count, -1)
event_table[i] = array_create(event_count, undefined)
for(var j = 0; j < event_count; j++) {
event_table[i][j] = []
event_ptrs[j] = buffer_read(buff, buffer_s32)
show_debug_message($"Event {j} at 0x{ptr(event_ptrs[j])}")
}
for(var j = 0; j < event_count; j++) {
buffer_seek(buff, buffer_seek_start, event_ptrs[j])
var num_subevents = buffer_read(buff, buffer_s32)
pos = buffer_tell(buff)
for(var k = 0; k < num_subevents; k++) {
buffer_seek(buff, buffer_seek_start, buffer_read(buff, buffer_s32))
array_push(event_table[i][j], buffer_read(buff, buffer_u32))
buffer_seek(buff, buffer_seek_start, pos + (k + 1) * 4)
}
}
}
}
finally {
buffer_delete(buff)
}
//show_debug_message(event_table)
}
return event_table
}
function object_has_event(obj_index, ev_type, ev_subtype) {
return object_exists(obj_index) && array_contains(__get_event_table()[obj_index][ev_type], ev_subtype)
}
function object_get_events(obj_index) {
if(!object_exists(obj_index)) return undefined;
var events = __get_event_table()[obj_index]
var out = {}
var len = array_length(events)
for(var i = 0; i < len; i++) {
var num_subevents = array_length(events[i]);
if(num_subevents) {
out[$ i] = array_create(num_subevents, 0)
array_copy(out[$ i], 0, events[i], 0, num_subevents)
}
}
return out;
}
function assert(value, err) {
if(!value) throw err;
}
function expect(value, expected, err) {
assert(value == expected, $"{err}: {value} != {expected}")
}
function buffer_read_string(buff, length) {
var out = "";
for(var i = 0; i < length; i++) {
out += chr(buffer_read(buff, buffer_u8))
}
return out;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment