Created
December 20, 2024 09:38
-
-
Save BenjaminUrquhart/5c8ca2efa0d4746d5171f5250f08790d to your computer and use it in GitHub Desktop.
I will not elaborate. Requires Gamemaker 2022.5 or later as-is.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| __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