aboutsummaryrefslogtreecommitdiff
path: root/src/entities.c
diff options
context:
space:
mode:
authorJuan J. Martinez <jjm@usebox.net>2023-11-05 11:22:55 +0000
committerJuan J. Martinez <jjm@usebox.net>2023-11-05 11:31:28 +0000
commit2fbdf974338bde8576efdae40a819a76b2391033 (patch)
tree64d41a37470143f142344f9a439d96de3e7918c2 /src/entities.c
downloadkitsunes-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.c534
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*
+}
+