-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathentity_api.wiz
More file actions
368 lines (253 loc) · 13.1 KB
/
Copy pathentity_api.wiz
File metadata and controls
368 lines (253 loc) · 13.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
// Copyright (c) 2021, Marcus Rowe <undisbeliever@gmail.com>.
// Distributed under The MIT License, see the LICENSE file for more details.
import "src/memmap";
import "game/metasprites";
let PLAYER_ENTITY_ID = 0;
// Entity Variables
// ================
namespace entities {
let N_ENTITIES = 21;
struct pos {
sx : u8,
px : u8
};
namespace MovementState {
let RIGHT_COLLISION = 1 << 0;
let LEFT_COLLISION = 1 << 1;
let UP_COLLISION = 1 << 2;
let DOWN_COLLISION = 1 << 3;
let X_AXIS_COLLISION = RIGHT_COLLISION | LEFT_COLLISION;
let Y_AXIS_COLLISION = UP_COLLISION | DOWN_COLLISION;
let TILE_COLLISION = X_AXIS_COLLISION | Y_AXIS_COLLISION;
};
namespace CollisionState {
let PLAYER_SWORD = 1 << 1;
let PLAYER_BOMB = 1 << 2;
let ANY_PLAYER_WEAPON = 1 << 6;
let PLAYER_HURTBOX = 1 << 7;
let ANY_PLAYER_WEAPON_BIT = 6;
let PLAYER_HURTBOX_BIT = 7;
};
struct _u8pair {
first : u8,
second : u8,
};
struct U8Aabb {
left : u8,
right : u8,
top : u8,
bottom : u8,
};
in zeropage {
// The entityId of the current entity
//
// This variable is only valid during an entity's process function.
//
// (byte index)
var currentEntityId : u8;
// Collision flags
// (bitfield of `entities.CollisionState`)
var collisionState : u8;
}
// Entity 0 is always the player
namespace SoA {
let LAST_INDEX = (N_ENTITIES - 1) * 2;
// Byte access size
let BA_SIZE = N_ENTITIES * 2 - 1;
in lowram_roomstate {
// Process function for the entity. Called once per frame by the entity loop.
//
// If the entity's health is 0 after this function is returned, the entity will be removed from the entity SoA.
//
// INPUT: entityId: index into `entities.SoA` Structure-of-Arrays.
//
// NOTE: `currentEntityId` will contain a copy of `entityId` to provide an easy
// way to restore the X register if it gets overwritten.
//
// NOTE: The player entity (entityId 0) MUST NOT change this variable.
//
// DB = 0x7e
#[mem8, idx8]
var process_function : [func(entityId : u8 in y) ; N_ENTITIES];
// Metasprite draw function.
//
// INPUT: Y = entityId: index into `entities.SoA` Structure-of-Arrays.
//
// DB = 0x7e
#[mem8, idx8]
var ms_draw_function : [func(msFrame : u16 in yy, xPos : u16 in metasprites.xPos, yPos : u16 in metasprites.yPos) ; N_ENTITIES];
}
in wram7e_roomstate {
var xPos : [pos ; N_ENTITIES];
var xPos_u16 @ &xPos[0] : [u16 ; N_ENTITIES];
var xPos_sx @ &xPos[0].sx : [u8 ; BA_SIZE];
var xPos_px @ &xPos[0].px : [u8 ; BA_SIZE];
var yPos : [pos ; N_ENTITIES];
var yPos_u16 @ &yPos[0] : [u16 ; N_ENTITIES];
var yPos_sx @ &yPos[0].sx : [u8 ; BA_SIZE];
var yPos_px @ &yPos[0].px : [u8 ; BA_SIZE];
// Previous position of the entity
//
// You SHOULD NOT write to these variables.
// They will be automatically updated in the MetaSprite draw function
//
// (2x uint8)
var _previousPosition : [ _u8pair ; N_ENTITIES];
var previousXpos @ &_previousPosition[0].first : [u8 ; BA_SIZE];
var previousYpos @ &_previousPosition[0].second : [u8 ; BA_SIZE];
var _zPosAndDeathFunction : [_u8pair ; N_ENTITIES];
// Z position of the entity
// (byte)
var zPos @ &_zPosAndDeathFunction[0].first : [u8 ; BA_SIZE];
// Function to call when the entity's health is 0.
// NOTE: bit 7 of this variable is unused.
// NOTE: bit 7 is reused by `entity_rom_data` to determine if the entity is an enemy or not.
// (array index into DeathFunctionsTable)
var deathFunction @ &_zPosAndDeathFunction[0].second : [u8 ; BA_SIZE ];
// ------------------------------------------------------------------------------------
// IMPORTANT NOTE: MetaSprite variables should not be directly modified by entity code.
// Please use the provided functions instead.
// ------------------------------------------------------------------------------------
var _msAnimationIdAndPfIndex : [_u8pair ; N_ENTITIES];
// The id of the MetaSprite animation.
// NOTE: This variable might not be the current animation.
var msAnimationId @ &_msAnimationIdAndPfIndex[0].first : [ u8 ; BA_SIZE];
// Index into the MetaSprite animation process function table.
//
// (byte index into function table)
var msAnimationProcessFunctionIndex @ &_msAnimationIdAndPfIndex[0].second : [u8 ; BA_SIZE];
// MetaSprite frame table address.
// Points to a addr table of `metasprites.MsDataFormat` data structure
var metaSpriteFrameTable : [u16 ; N_ENTITIES];
// MetaSprite animation table address.
// Points to a addr table of `metasprites.AnimationDataFormat` data structure
var msAnimationTable : [u16 ; N_ENTITIES];
// Address of the start of the current MetaSprite animation.
// (word address pointing to `metasprites.AnimationDataFormat` data)
var msAnimationAddr : [u16 ; N_ENTITIES];
// Current position within the MetaSprite animation
// (word address pointing into the middle of `metasprites.AnimationDataFormat` data)
var msAnimationPos : [u16 ; N_ENTITIES];
// Address of the current MetaSprite Frame.
// (word address pointing to a `metasprites.MsDataFormat` data structure)
var msFrameAddr : [u16 ; N_ENTITIES];
// Counter value until the next animation frame.
// Data format depends on the animation's process function.
var msAnimationCounter : [u16 ; N_ENTITIES];
var _shadowSizeAndIsEnemy : [ _u8pair ; N_ENTITIES];
// The size of the shadow underneath the entity
var shadowSize @ &_shadowSizeAndIsEnemy[0].first : [ metasprites.ShadowSize ; BA_SIZE ];
// If non-zero, the entity is an enemy.
// If this entity is an enemy, `_enemyCount` will be decremented when the entity is despawned.
// NOTE: This variable MUST NOT be changed by the entity code.
// (byte flag)
var _isEnemy @ &_shadowSizeAndIsEnemy[0].second : [ u8 ; BA_SIZE ];
// Signed 16 bit X velocity
var xVelocity : [ u16 ; N_ENTITIES ];
var xVelocity_sx @ &<:xVelocity[0] : [u8 ; BA_SIZE];
var xVelocity_px @ &>:xVelocity[0] : [u8 ; BA_SIZE];
// Signed 16 bit Y velocity
var yVelocity : [ u16 ; N_ENTITIES ];
var yVelocity_sx @ &<:yVelocity[0] : [u8 ; BA_SIZE];
var yVelocity_px @ &>:yVelocity[0] : [u8 ; BA_SIZE];
var tileHitbox : [ _u8pair ; N_ENTITIES ];
var tileHitbox_halfWidth @ &tileHitbox[0].first : [u8 ; BA_SIZE];
var tileHitbox_halfHeight @ &tileHitbox[0].second : [u8 ; BA_SIZE];
var _movementStateAndIframeCounter : [ _u8pair ; N_ENTITIES ];
// Updated by `metatiles.move_entity_and_collision_test` or `entities.base.process_collisions`
// (bitfield of `entities.MovementState`)
var movementState @ &_movementStateAndIframeCounter[0].first : [u8 ; BA_SIZE];
// Updated by `base.process_collisions`
// Invincibility frames counter
var iframeCounter @ &_movementStateAndIframeCounter[0].second : [u8 ; BA_SIZE];
var _healthAndAttackPower : [ _u8pair ; N_ENTITIES ];
// Entity health
var health @ &_healthAndAttackPower[0].first : [u8 ; BA_SIZE];
// Attack Power stat
var attackPower @ &_healthAndAttackPower[0].second : [u8 ; BA_SIZE];
// Vision parameters
// (two bytes, depends on the vision system used)
var _visionAB : [ _u8pair ; N_ENTITIES ];
var visionA @ &_visionAB[0].first : [u8 ; BA_SIZE];
var visionB @ &_visionAB[0].second : [u8 ; BA_SIZE];
// ::TODO should I add a third vision variable?::
// ::: Currently small end of vision_cone is constant::
// Custom entity variables.
//
// NOTE: if I add more vars here then I need to clear them in `spawn_entity`
var var_0 : [ u16 ; N_ENTITIES ];
var var_1 : [ u16 ; N_ENTITIES ];
var var_2 : [ u16 ; N_ENTITIES ];
var var_3 : [ u16 ; N_ENTITIES ];
var var_4 : [ u16 ; N_ENTITIES ];
var var_5 : [ u16 ; N_ENTITIES ];
var var_6 : [ u16 ; N_ENTITIES ];
var var_7 : [ u16 ; N_ENTITIES ];
// Split vars into low/high pairs (to easily allocate a byte variable)
var var_0_l @ &<:var_0[0] : [u8 ; BA_SIZE];
var var_0_h @ &>:var_0[0] : [u8 ; BA_SIZE];
var var_1_l @ &<:var_1[0] : [u8 ; BA_SIZE];
var var_1_h @ &>:var_1[0] : [u8 ; BA_SIZE];
var var_2_l @ &<:var_2[0] : [u8 ; BA_SIZE];
var var_2_h @ &>:var_2[0] : [u8 ; BA_SIZE];
var var_3_l @ &<:var_3[0] : [u8 ; BA_SIZE];
var var_3_h @ &>:var_3[0] : [u8 ; BA_SIZE];
}
}
}
// Player variables from the entities SoA
// ======================================
namespace player {
in wram7e_roomstate {
var xVelocity @ &entities.SoA.xVelocity[0] : u16;
var yVelocity @ &entities.SoA.yVelocity[0] : u16;
var xPos @ &entities.SoA.xPos[0] : entities.pos;
var yPos @ &entities.SoA.yPos[0] : entities.pos;
var zPos : u8 in entities.SoA.zPos[0];
var previousXpos : u8 in entities.SoA.previousXpos[0];
var previousYpos : u8 in entities.SoA.previousYpos[0];
// Skipping most of the MetaSprite variables.
var shadowSize : metasprites.ShadowSize in entities.SoA.shadowSize[0];
var tileHitbox_halfWidth : u8 in entities.SoA.tileHitbox_halfWidth[0];
var tileHitbox_halfHeight : u8 in entities.SoA.tileHitbox_halfHeight[0];
var movementState : u8 in entities.SoA.movementState[0];
var iframeCounter : u8 in entities.SoA.iframeCounter[0];
var health : u8 in entities.SoA.health[0];
var swordAttackPower : u8 in entities.SoA.attackPower[0];
var visionA : u8 in entities.SoA.visionA[0];
var visionB : u8 in entities.SoA.visionB[0];
}
}
// Engine functions that can be called in the entity context
// =========================================================
namespace entities {
// Audio functions
import "audio";
let queue_sound_effect = audio.queue_sound_effect;
// Gamestate functions
import "game/gamestate";
let is_gs_flag_clear = gamestate.is_flag_clear__keep_y;
let set_gs_flag = gamestate.set_game_flag__keep_y;
// NOTE: clobbers Y
let gs_increment_key_count__clobbers_y = gamestate.increment_key_count;
// MetaSprite functions
import "game/metasprites";
let set_ms_animation_x = metasprites.set_entity_animation_x;
let set_ms_animation = metasprites.set_entity_animation;
let set_ms_animation_if_changed = metasprites.set_entity_animation_if_changed;
let stop_ms_animation = metasprites.stop_entity_animation;
let is_ms_non_looping_animation_running = metasprites.is_entity_non_looping_animation_running;
// MetaTile functions
import "game/metatiles";
let move_entity_and_tile_collision_test = metatiles.move_entity_and_collision_test;
let move_entity_and_tile_collision_test__projectile_bounded = metatiles.move_entity_and_collision_test__projectile_bounded;
let move_entity_and_tile_collision_test__bounded = metatiles.move_entity_and_collision_test__bounded;
let get_tile_index_under_entity = metatiles.get_tile_index_under_entity;
let set_tile_solid = metatiles.set_tile_solid;
let reset_tile_properties__clobbers_y = metatiles.reset_tile_properties;
// Entityloop functions
import "game/entityloop";
let is_all_enemies_defeated = entityloop.is_all_enemies_defeated;
let get_enemy_count_a = entityloop.get_enemy_count_a;
let spawn_entity__clobbers_y = entityloop.spawn_entity;
}