diff options
author | Juan J. Martinez <jjm@usebox.net> | 2023-11-05 11:22:55 +0000 |
---|---|---|
committer | Juan J. Martinez <jjm@usebox.net> | 2023-11-05 11:31:28 +0000 |
commit | 2fbdf974338bde8576efdae40a819a76b2391033 (patch) | |
tree | 64d41a37470143f142344f9a439d96de3e7918c2 /src/entities.c | |
download | kitsunes-curse-2fbdf974338bde8576efdae40a819a76b2391033.tar.gz kitsunes-curse-2fbdf974338bde8576efdae40a819a76b2391033.zip |
Initial import of the open source release
Diffstat (limited to 'src/entities.c')
-rw-r--r-- | src/entities.c | 534 |
1 files changed, 534 insertions, 0 deletions
diff --git a/src/entities.c b/src/entities.c new file mode 100644 index 0000000..47f68b6 --- /dev/null +++ b/src/entities.c @@ -0,0 +1,534 @@ +/* + Kitsune's Curse + Copyright (C) 2020-2023 Juan J. Martinez <jjm@usebox.net> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <https://www.gnu.org/licenses/>. + */ +#include <stdint.h> +#include <string.h> + +#include "main.h" + +#define LOCAL +#include "entities.h" + +//#define ET_DEBUG + +struct st_entity *sp_free; +struct st_entity entities[MAX_ENTITIES]; + +void init_entities() +{ + uint8_t i; + + memset(entities, 0, sizeof(struct st_entity) * MAX_ENTITIES); + + for (i = 0; i < MAX_ENTITIES - 1; ++i) + entities[i].n = entities + i + 1; + + sp_used = NULL; + sp_free = entities; + sp_collect = 0; +} + +#pragma save +#pragma disable_warning 59 +uint8_t new_entity() +{ + // new entity on sp_new on success + + /* + if (!sp_free) + return 0; + + sp_new = sp_free; + sp_free = sp_free->n; + sp_new->n = sp_used; + sp_used = sp_new; + + return 1; + */ + + // *INDENT-OFF* + __asm; + + ; check MSB + ld a, (_sp_free + 1) + ld l, a + or a +#ifndef ET_DEBUG + ret z +#else + jr nz, new_entity_free + + ld hl, #0x4a + call _set_hw_border + + xor a + ld l, a + ret +new_entity_free: +#endif + + ld hl, (_sp_free) + ld (_sp_new), hl + + ld bc, #ET_SIZE_PT + + add hl, bc + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + ld (_sp_free), hl + + ld hl, (_sp_new) + add hl, bc + ld a, (_sp_used) + ld (hl), a + inc hl + ld a, (_sp_used + 1) + ld (hl), a + + ld hl, (_sp_new) + ld (_sp_used), hl + + ld l, #1 + __endasm; + // *INDENT-ON* +} +#pragma restore + +void destroy_entity() +{ + // entity on sp_it + sp_it->type = ET_UNUSED; + sp_collect++; +} + +void free_entities() +{ + /* + if (!sp_used) + return; + + // current, previous + for (sp_it = sp_it2 = sp_used; sp_it && sp_collect;) + { + if (sp_it->type == ET_UNUSED) + { + sp_collect--; + + if (sp_it == sp_used) + { + sp_it2 = sp_free; + sp_free = sp_used; + sp_used = sp_used->n; + sp_free->n = sp_it2; + sp_it = sp_it2 = sp_used; + continue; + } + else + { + sp_it2->n = sp_it->n; + sp_it->n = sp_free; + sp_free = sp_it; + sp_it = sp_it2->n; + continue; + } + } + sp_it2 = sp_it; + sp_it = sp_it->n; + } + */ + + // *INDENT-OFF* + __asm; + + ; check MSB + ld a, (_sp_used + 1) + or a + ret z + + ld hl, (_sp_used) + ld (_sp_it2), hl + ld (_sp_it), hl + + ld bc, #ET_SIZE_PT + +free_entities_loop: + ; hl holds it + + ; check MSB + ld a, (_sp_collect) + or a + ret z + ld a, h + or a + ret z + + ld a, (hl) + or a + jr z, free_entities_unused + + ; next + + ; it2 is it + ld (_sp_it2), hl + + ; it to it->n + add hl, bc + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + ld (_sp_it), hl + + jr free_entities_loop + +free_entities_unused: + ld a, (_sp_collect) + dec a + ld (_sp_collect), a + + ld a, (_sp_used) + cp l + jr nz, free_entities_not_used + ld a, (_sp_used + 1) + cp h + jr nz, free_entities_not_used + + ; it2 = free + ld hl, (_sp_free) + ld (_sp_it2), hl + + ; free = used + ld hl, (_sp_used) + ld (_sp_free), hl + + ; used = used->n + add hl, bc + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + ld (_sp_used), hl + + ; free->n = it2 + ld hl, (_sp_it2) + ex de, hl + ld hl, (_sp_free) + add hl, bc + ld (hl), e + inc hl + ld (hl), d + + ; it = it2 = used + ld hl, (_sp_used) + ld (_sp_it2), hl + ld (_sp_it), hl + + jr free_entities_loop + +free_entities_not_used: + ; it2->n = it->n + add hl, bc + ld e, (hl) + inc hl + ld d, (hl) + ld hl, (_sp_it2) + add hl, bc + ld (hl), e + inc hl + ld (hl), d + + ; it->n = free + ld hl, (_sp_free) + ex de, hl + ld hl, (_sp_it) + add hl, bc + ld (hl), e + inc hl + ld (hl), d + + ; free = it + ld hl, (_sp_it) + ld (_sp_free), hl + + ; it = it2->n + ld hl, (_sp_it2) + add hl, bc + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + ld (_sp_it), hl + + jp free_entities_loop + __endasm; + // *INDENT-ON* +} + +#pragma save +#pragma disable_warning 85 +#pragma disable_warning 59 +uint8_t check_for_point(struct st_entity *s, uint8_t x, uint8_t y, uint8_t w, uint8_t h) +{ + // return (y < s->y + h && y >= s->y && x < s->x + w && x >= s->x); + // *INDENT-OFF* + __asm; + + ld hl, #2 + add hl, sp + + ld e, (hl) + inc hl + ld d, (hl) + + ex de, hl + ld bc, #4 + add hl, bc + ld a, (hl) + inc hl + inc hl + ld h, (hl) + ld l, a + ex de, hl + + inc hl + ld c, (hl) + inc hl + ld b, (hl) + inc hl + ld a, (hl) + inc hl + ld h, (hl) + ld l, a + + ; de s (x, y) + ; bc (x, y) + ; hl (w, h) + + ld a, b + cp d + jr c, check_for_point_fail + + ld a, d + add h + cp b + jr c, check_for_point_fail + + ld a, c + cp e + jr c, check_for_point_fail + + ld a, e + add l + cp c + jr c, check_for_point_fail + + ld l, #1 + ret + +check_for_point_fail: + ld l, #0 + + __endasm; + // *INDENT-ON* +} +#pragma restore + +void draw_entities() +{ + /* + draw_player(); + + for (sp_it = sp_used; sp_it; sp_it = sp_it->n) + { + it_x = &sp_it->x; + it_y = &sp_it->y; + it_ox = &sp_it->ox; + it_oy = &sp_it->oy; + it_frame = &sp_it->frame; + it_param = &sp_it->param; + it_extra = &sp_it->extra; + + sp_it->draw(); + } + */ + + // *INDENT-OFF* + __asm; + call _draw_player + + ld hl, (_sp_used) + + ld a, h + or l + jr z, draw_entities_done + +draw_entities_loop: + + ld (_sp_it), hl + + ld bc, #2 + + add hl, bc + ld (_it_frame), hl + add hl, bc + ld (_it_x), hl + inc hl + ld (_it_ox), hl + inc hl + ld (_it_y), hl + inc hl + ld (_it_oy), hl + inc hl + ld (_it_param), hl + inc hl + ld (_it_extra), hl + inc hl + add hl, bc + + push hl + ld a, (hl) + inc hl + ld h, (hl) + ld l, a + call ___sdcc_call_hl + pop hl + + inc hl + inc hl + + ld a, (hl) + inc hl + ld h, (hl) + ld l, a + or h + jr nz, draw_entities_loop + +draw_entities_done: + + __endasm; + // *INDENT-ON* +} + +void update_entities() +{ + /* + for (sp_it = sp_used; sp_it; sp_it = sp_it->n) + { + if (sp_it->type == ET_UNUSED) + continue; + + it_frame = &sp_it->frame; + it_x = &sp_it->x; + it_y = &sp_it->y; + + sp_it->ox = *it_x; + it_ox = &sp_it->ox; + sp_it->oy = *it_y; + it_oy = &sp_it->oy; + + it_delay = &sp_it->delay; + it_param = &sp_it->param; + it_extra = &sp_it->extra; + + sp_it->update(); + } + + if (sp_collect) + free_entities(); + + update_player(); + */ + // *INDENT-OFF* + __asm; + + ld hl, (_sp_used) + + ld a, h + or l + jr z, update_entities_done + +update_entities_loop: + + ld a, (hl) + or a + jr nz, update_entities_no_skip + + ld bc, #ET_SIZE_PT + jr update_entities_next + +update_entities_no_skip: + ld (_sp_it), hl + + inc hl + inc hl + ld (_it_frame), hl + inc hl + ld (_it_delay), hl + inc hl + ld (_it_x), hl + ld a, (hl) + inc hl + ld (_it_ox), hl + ld (hl), a + inc hl + ld (_it_y), hl + ld a, (hl) + inc hl + ld (_it_oy), hl + ld (hl), a + inc hl + ld (_it_param), hl + inc hl + ld (_it_extra), hl + inc hl + + push hl + ld a, (hl) + inc hl + ld h, (hl) + ld l, a + call ___sdcc_call_hl + pop hl + + ld bc, #4 + +update_entities_next: + add hl, bc + + ld a, (hl) + inc hl + ld h, (hl) + ld l, a + or h + jr nz, update_entities_loop + +update_entities_done: + ld a, (_sp_collect) + or a + jr z, update_entities_exit + + call _free_entities + +update_entities_exit: + call _update_player + + __endasm; + // *INDENT-ON* +} + |