Initial commit

This commit is contained in:
Synthasmagoria 2026-09-23 15:54:19 +02:00
commit dd58a721ec
8 changed files with 617 additions and 0 deletions

View file

@ -0,0 +1,184 @@
///@param {Id.Buffer} memory
///@param {Pointer} system
///@param {Id.vertex_format} vertex_format
///@param {Id.vertex_buffer} vertex_buffer
///@param {Real} projectile_count
///@param {Struct.Texturepage} texturepage
///@param {Id.DsList} effects
function _ProjectileEffectSystem(memory, system, vertex_format, vertex_buffer, projectile_count, texturepage, effects) constructor {
self.memory = memory;
self.system = system;
self.vertex_format = vertex_format;
self.vertex_buffer = vertex_buffer;
self.projectile_count = projectile_count;
self.texturepage = texturepage;
self.effects = effects;
}
///@param {Function} create_func
///@param {Real} interval
///@param {Id.DsList} list
function _ProjectileEffectSystemEffect(create_func, interval, list) constructor {
self.interval = interval;
self.time = 0;
self.instances = list;
self.create_func = create_func;
}
///@param {Real} projectile_count
///@return {_ProjectileEffectSystem}
function pem_create(projectile_count, texturepage) {
vertex_format_begin();
vertex_format_add_position_3d();
vertex_format_add_color();
vertex_format_add_texcoord();
vertex_format_add_custom(vertex_type_float3, vertex_usage_color); // Position
vertex_format_add_custom(vertex_type_float2, vertex_usage_color); // Scale
vertex_format_add_custom(vertex_type_float1, vertex_usage_color); // Angle
vertex_format_add_custom(vertex_type_float3, vertex_usage_color); // Rotation direction
vertex_format_add_custom(vertex_type_float1, vertex_usage_color); // Animation
vertex_format_add_custom(vertex_type_float3, vertex_usage_color); // Hue saturation value
var _vertex_format = vertex_format_end();
var _buffer = buffer_create(pem_get_size(projectile_count), buffer_fixed, 1);
buffer_fill(_buffer, 0, buffer_u32, 0, buffer_get_size(_buffer));
var _ptr = buffer_get_address(_buffer);
pem_init(_ptr, projectile_count, TEXTUREPAGE_SIZE);
var _vertex_buffer = vertex_create_buffer_from_buffer_ext(
_buffer,
_vertex_format,
pem_get_vertex_buffer_offset(),
projectile_count * 6);
return new _ProjectileEffectSystem(_buffer, _ptr, _vertex_format, _vertex_buffer, projectile_count, texturepage, ds_list_create());
}
///@param {Struct._ProjectileEffectSystem} system
///@param {Function} create_func
///@param {Real} interval
function pem_effect_add(system, create_func, interval) {
if (interval <= 0.0) {
printerr("Interval cannot be equal or lower than 0.0", ERROR_LOC);
return;
}
var _effect = new _ProjectileEffectSystemEffect(create_func, interval, ds_list_create());
ds_list_add(system.effects, _effect);
}
///@param {Struct._ProjectileEffectSystem} system
///@param {Real} index
///@param {Id.Instance} inst
function pem_effect_instance_add(system, index, inst) {
ds_list_add(system.effects[|index].instances, inst);
}
///@param {Struct._ProjectileEffectSystemEffect} effect
function _pem_effect_destroy(effect) {
ds_list_destroy(effect.instances);
}
///@param {Struct._ProjectileEffectSystem} system
function pem_update_vertex_buffer(system) {
vertex_update_buffer_from_buffer(
system.vertex_buffer,
0,
system.memory,
pem_get_vertex_buffer_offset(),
pem_get_vertex_buffer_size(system.projectile_count));
}
///@param {Struct._ProjectileEffectSystem} system
function pem_destroy(system) {
buffer_delete(system.memory);
vertex_format_delete(system.vertex_format);
vertex_delete_buffer(system.vertex_buffer);
for (var i = 0, n = ds_list_size(system.effects); i < n; i++) {
_pem_effect_destroy(system.effects[|i]);
}
ds_list_destroy(system.effects);
}
///@param {Struct._ProjectileEffectSystem} system
function pem_update(system) {
for (var i = 0, n = ds_list_size(system.effects); i < n; i++) {
var _effect = system.effects[|i];
_effect.time += 1.0;
while (_effect.time >= _effect.interval) {
_effect.time -= _effect.interval;
for (var j = 0, nn = ds_list_size(_effect.instances); j < nn; j++) {
if (!instance_exists(_effect.instances[|j])) {
ds_list_delete(_effect.instances, j);
j--;
nn--;
continue;
}
_effect.create_func(system, _effect.instances[|j]);
}
}
}
_pem_update(system.system);
pem_update_vertex_buffer(system);
}
///@param {Struct._ProjectileEffectSystem} system
function pem_set(system) {
_pem_set(system.system);
}
///@param {Struct._ProjectileEffectSystem} system
function pem_draw(system) {
shader_set(shdProjectileEffect);
vertex_submit(system.vertex_buffer, pr_trianglelist, system.texturepage.texture);
shader_reset();
}
///@param {Struct._ProjectileEffectSystem} system
///@param {Real} x
///@param {Real} y
///@param {Asset.GMSprite} sprite_index
function pem_instance_create_from_sprite(system, x, y, sprite_index) {
var _info = texturepage_sprite_get_info(system.texturepage, sprite_index);
if (_info == -1) {
printerr($"Couldn't create effect instance with sprite {sprite_get_name(sprite_index)}. It wasn't on the texture page", ERROR_LOC);
return;
}
return pem_instance_create_from_info(x, y, _info);
}
///@param {Struct._ProjectileEffectSystem} system
///@param {Real} x
///@param {Real} y
///@param {Real} sprite_origin
///@param {Asset.GMSprite} sprite_index
function pem_instance_create_from_sprite_ext(system, x, y, origin, sprite_index) {
var _info = texturepage_sprite_get_info(system.texturepage, sprite_index);
if (_info == -1) {
printerr("Couldn't create effect instance with sprite {sprite_get_name(sprite_index)}. It wasn't on the texture page", ERROR_LOC);
return;
}
return pem_instance_create_from_info_ext(x, y, origin, _info);
}
///@param {Real} x
///@param {Real} y
///@param {Struct.TexturepageEntryInfo} info
function pem_instance_create_from_info(x, y, info) {
return pem_instance_create(
x, y,
sprite_get_width(info.sprite_index), sprite_get_height(info.sprite_index),
sprite_get_xoffset(info.sprite_index), sprite_get_yoffset(info.sprite_index),
info.uvs[UvData.Left], info.uvs[UvData.Top], info.uvs[UvData.Right], info.uvs[UvData.Bottom],
sprite_get_number(info.sprite_index));
}
///@param {Real} x
///@param {Real} y
///@param {Real} sprite_origin
///@param {Struct.TexturepageEntryInfo} info
function pem_instance_create_from_info_ext(x, y, sprite_origin, info) {
return pem_instance_create_origin(
x, y,
sprite_get_width(info.sprite_index), sprite_get_height(info.sprite_index),
sprite_origin,
info.uvs[UvData.Left], info.uvs[UvData.Top], info.uvs[UvData.Right], info.uvs[UvData.Bottom],
sprite_get_number(info.sprite_index));
}