mirror of
https://github.com/luksamuk/engine-psx.git
synced 2025-04-28 13:28:02 +03:00
Add shield
This commit is contained in:
parent
2b1f52cdb6
commit
5b35c90259
16 changed files with 118 additions and 43 deletions
Binary file not shown.
Binary file not shown.
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 20 KiB |
Binary file not shown.
Before Width: | Height: | Size: 9.4 KiB After Width: | Height: | Size: 10 KiB |
|
@ -396,6 +396,22 @@ duration = 2
|
|||
frames = [[216, 16, 16, 16]]
|
||||
loopback = 0
|
||||
|
||||
# ============
|
||||
|
||||
[shield]
|
||||
|
||||
[[shield.animations]]
|
||||
id = 0
|
||||
name = "default"
|
||||
duration = 4
|
||||
frames = [
|
||||
[50, 200, 48, 48],
|
||||
[98, 200, 48, 48],
|
||||
[50, 200, 48, 48, 1, 0],
|
||||
[98, 200, 48, 48],
|
||||
]
|
||||
loopback = 0
|
||||
|
||||
# ============
|
||||
# Dummy objects
|
||||
# ============
|
||||
|
|
|
@ -51,4 +51,5 @@
|
|||
<tile id="12" type="startpos"/>
|
||||
<tile id="13" type="explosion"/>
|
||||
<tile id="14" type="monitor_image"/>
|
||||
<tile id="15" type="shield"/>
|
||||
</tileset>
|
||||
|
|
BIN
assets/sfx/SHIELD.ogg
Normal file
BIN
assets/sfx/SHIELD.ogg
Normal file
Binary file not shown.
BIN
assets/sfx/SKIDDING.ogg
Normal file
BIN
assets/sfx/SKIDDING.ogg
Normal file
Binary file not shown.
Binary file not shown.
|
@ -6,8 +6,8 @@ for f in *.ogg; do
|
|||
rm "${f%%.ogg}.WAV";
|
||||
done
|
||||
|
||||
for f in *.wav; do
|
||||
ffmpeg -y -i "$f" -acodec pcm_s16le -ac 1 -ar 22050 "${f%%.wav}_2.WAV";
|
||||
wav2vag "${f%%.wav}_2.WAV" "${f%%.wav}.VAG";
|
||||
rm "${f%%.wav}_2.WAV";
|
||||
done
|
||||
# for f in *.wav; do
|
||||
# ffmpeg -y -i "$f" -acodec pcm_s16le -ac 1 -ar 22050 "${f%%.wav}_2.WAV";
|
||||
# wav2vag "${f%%.wav}_2.WAV" "${f%%.wav}.VAG";
|
||||
# rm "${f%%.wav}_2.WAV";
|
||||
# done
|
||||
|
|
|
@ -26,6 +26,7 @@ typedef enum {
|
|||
OBJ_GOAL_SIGN = 0x09,
|
||||
OBJ_EXPLOSION = 0x0a,
|
||||
OBJ_MONITOR_IMAGE = 0x0b,
|
||||
OBJ_SHIELD = 0x0c,
|
||||
} ObjectType;
|
||||
|
||||
#define MASK_FLIP_FLIPX 0x1 // Flip on X axis
|
||||
|
|
|
@ -75,6 +75,7 @@ typedef struct {
|
|||
uint8_t framecount;
|
||||
uint8_t holding_jump;
|
||||
uint16_t iframes;
|
||||
uint8_t shield;
|
||||
|
||||
PlayerAction action;
|
||||
|
||||
|
@ -102,7 +103,6 @@ CharaAnim *player_get_animation_by_name(Player *player, const char *name);
|
|||
void player_update(Player *player);
|
||||
void player_draw(Player *player, VECTOR *screen_pos);
|
||||
|
||||
void player_set_hurt(Player *player, int32_t hazard_x);
|
||||
void player_set_ring_loss(Player *player, int32_t hazard_x, uint8_t num_rings);
|
||||
void player_do_damage(Player *player, int32_t hazard_x);
|
||||
|
||||
#endif
|
||||
|
|
3
iso.xml
3
iso.xml
|
@ -244,6 +244,9 @@
|
|||
<file name="RINGLOSS.VAG"
|
||||
type="data"
|
||||
source="${PROJECT_SOURCE_DIR}/assets/sfx/RINGLOSS.VAG" />
|
||||
<file name="SHIELD.VAG"
|
||||
type="data"
|
||||
source="${PROJECT_SOURCE_DIR}/assets/sfx/SHIELD.VAG" />
|
||||
</dir>
|
||||
|
||||
<dir name="BGM">
|
||||
|
|
|
@ -275,7 +275,10 @@ begin_render_routine:
|
|||
poly->tpage = getTPage(1, 0, 576, 0);
|
||||
poly->clut = getClut(0, 481);
|
||||
|
||||
sort_prim(poly, state->id == OBJ_RING ? OTZ_LAYER_OBJECTS : OTZ_LAYER_PLAYER);
|
||||
sort_prim(poly,
|
||||
((state->id == OBJ_RING) || (state->id == OBJ_SHIELD))
|
||||
? OTZ_LAYER_OBJECTS
|
||||
: OTZ_LAYER_PLAYER);
|
||||
|
||||
if(!in_fragment && (typedata->fragment != NULL)) {
|
||||
in_fragment = 1;
|
||||
|
|
|
@ -23,6 +23,7 @@ extern SoundEffect sfx_sprn;
|
|||
extern SoundEffect sfx_chek;
|
||||
extern SoundEffect sfx_death;
|
||||
extern SoundEffect sfx_ringl;
|
||||
extern SoundEffect sfx_shield;
|
||||
extern int debug_mode;
|
||||
|
||||
extern uint8_t level_ring_count;
|
||||
|
@ -44,6 +45,7 @@ static void _checkpoint_update(ObjectState *state, ObjectTableEntry *, VECTOR *p
|
|||
static void _spikes_update(ObjectState *state, ObjectTableEntry *, VECTOR *pos);
|
||||
static void _explosion_update(ObjectState *state, ObjectTableEntry *, VECTOR *);
|
||||
static void _monitor_image_update(ObjectState *state, ObjectTableEntry *, VECTOR *);
|
||||
static void _shield_update(ObjectState *state, ObjectTableEntry *, VECTOR *);
|
||||
|
||||
// Player hitbox information. Calculated once per frame.
|
||||
static int32_t player_vx, player_vy; // Top left corner of player hitbox
|
||||
|
@ -104,6 +106,7 @@ object_update(ObjectState *state, ObjectTableEntry *typedata, VECTOR *pos)
|
|||
case OBJ_SPIKES: _spikes_update(state, typedata, pos); break;
|
||||
case OBJ_EXPLOSION: _explosion_update(state, typedata, pos); break;
|
||||
case OBJ_MONITOR_IMAGE: _monitor_image_update(state, typedata, pos); break;
|
||||
case OBJ_SHIELD: _shield_update(state, typedata, pos); break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -473,14 +476,7 @@ _spikes_update(ObjectState *state, ObjectTableEntry *, VECTOR *pos)
|
|||
((player_vx >= solidity_vx - 8) && ((player_vx + 8) <= solidity_vx + 32)))
|
||||
{
|
||||
if(player.action != ACTION_HURT && player.iframes == 0) {
|
||||
if(level_ring_count > 0) {
|
||||
player_set_ring_loss(&player, (solidity_vx + 16) << 12, level_ring_count);
|
||||
level_ring_count = 0;
|
||||
sound_play_vag(sfx_ringl, 0);
|
||||
} else {
|
||||
player_set_hurt(&player, (solidity_vx + 16) << 12);
|
||||
sound_play_vag(sfx_death, 0);
|
||||
}
|
||||
player_do_damage(&player, (solidity_vx + 16) << 12);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -520,6 +516,7 @@ static void
|
|||
_monitor_image_update(ObjectState *state, ObjectTableEntry *, VECTOR *)
|
||||
{
|
||||
state->timer++;
|
||||
PoolObject *newobj;
|
||||
|
||||
// Monitor images ascend for 15 frames, then stay still for 15 more
|
||||
if(state->timer <= 15) state->freepos->vy -= (ONE << 1);
|
||||
|
@ -527,11 +524,39 @@ _monitor_image_update(ObjectState *state, ObjectTableEntry *, VECTOR *)
|
|||
state->props |= OBJ_FLAG_DESTROYED;
|
||||
|
||||
switch(state->anim_state.animation) {
|
||||
case MONITOR_KIND_NONE:
|
||||
sound_play_vag(sfx_death, 0);
|
||||
break;
|
||||
case MONITOR_KIND_RING:
|
||||
sound_play_vag(sfx_ring, 0);
|
||||
level_ring_count += 10;
|
||||
break;
|
||||
case MONITOR_KIND_SHIELD:
|
||||
player.shield = 1;
|
||||
newobj = object_pool_create(OBJ_SHIELD);
|
||||
newobj->freepos.vx = player.pos.vx;
|
||||
newobj->freepos.vy = player.pos.vy + (20 << 12);
|
||||
sound_play_vag(sfx_shield, 0);
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
_shield_update(ObjectState *state, ObjectTableEntry *, VECTOR *)
|
||||
{
|
||||
// Just stay with the player and disappear if player gets hurt
|
||||
if(!player.shield) {
|
||||
state->props |= OBJ_FLAG_DESTROYED;
|
||||
return;
|
||||
}
|
||||
|
||||
state->freepos->vx = player.pos.vx;
|
||||
state->freepos->vy = player.pos.vy + (20 << 12);
|
||||
|
||||
// Compensate position since it is drawn before player update
|
||||
state->freepos->vx += player.vel.vx;
|
||||
state->freepos->vy += player.vel.vy;
|
||||
}
|
||||
|
|
78
src/player.c
78
src/player.c
|
@ -30,24 +30,26 @@
|
|||
|
||||
extern int debug_mode;
|
||||
|
||||
SoundEffect sfx_jump = { 0 };
|
||||
SoundEffect sfx_skid = { 0 };
|
||||
SoundEffect sfx_roll = { 0 };
|
||||
SoundEffect sfx_dash = { 0 };
|
||||
SoundEffect sfx_relea = { 0 };
|
||||
SoundEffect sfx_dropd = { 0 };
|
||||
SoundEffect sfx_ring = { 0 };
|
||||
SoundEffect sfx_pop = { 0 };
|
||||
SoundEffect sfx_sprn = { 0 };
|
||||
SoundEffect sfx_chek = { 0 };
|
||||
SoundEffect sfx_death = { 0 };
|
||||
SoundEffect sfx_ringl = { 0 };
|
||||
SoundEffect sfx_jump = { 0 };
|
||||
SoundEffect sfx_skid = { 0 };
|
||||
SoundEffect sfx_roll = { 0 };
|
||||
SoundEffect sfx_dash = { 0 };
|
||||
SoundEffect sfx_relea = { 0 };
|
||||
SoundEffect sfx_dropd = { 0 };
|
||||
SoundEffect sfx_ring = { 0 };
|
||||
SoundEffect sfx_pop = { 0 };
|
||||
SoundEffect sfx_sprn = { 0 };
|
||||
SoundEffect sfx_chek = { 0 };
|
||||
SoundEffect sfx_death = { 0 };
|
||||
SoundEffect sfx_ringl = { 0 };
|
||||
SoundEffect sfx_shield = { 0 };
|
||||
|
||||
// TODO: Maybe shouldn't be extern?
|
||||
extern TileMap16 map16;
|
||||
extern TileMap128 map128;
|
||||
extern LevelData leveldata;
|
||||
extern Camera camera;
|
||||
extern uint8_t level_ring_count;
|
||||
|
||||
void
|
||||
load_player(Player *player,
|
||||
|
@ -64,6 +66,7 @@ load_player(Player *player,
|
|||
player->airdirlock = 0;
|
||||
player->framecount = 0;
|
||||
player->iframes = 0;
|
||||
player->shield = 0;
|
||||
|
||||
player_set_animation_direct(player, ANIM_STOPPED);
|
||||
player->anim_frame = player->anim_timer = 0;
|
||||
|
@ -80,18 +83,19 @@ load_player(Player *player,
|
|||
|
||||
player->action = ACTION_NONE;
|
||||
|
||||
if(sfx_jump.addr == 0) sfx_jump = sound_load_vag("\\SFX\\JUMP.VAG;1");
|
||||
if(sfx_skid.addr == 0) sfx_skid = sound_load_vag("\\SFX\\SKIDDING.VAG;1");
|
||||
if(sfx_roll.addr == 0) sfx_roll = sound_load_vag("\\SFX\\ROLL.VAG;1");
|
||||
if(sfx_dash.addr == 0) sfx_dash = sound_load_vag("\\SFX\\DASH.VAG;1");
|
||||
if(sfx_relea.addr == 0) sfx_relea = sound_load_vag("\\SFX\\RELEA.VAG;1");
|
||||
if(sfx_dropd.addr == 0) sfx_dropd = sound_load_vag("\\SFX\\DROPD.VAG;1");
|
||||
if(sfx_ring.addr == 0) sfx_ring = sound_load_vag("\\SFX\\RING.VAG;1");
|
||||
if(sfx_pop.addr == 0) sfx_pop = sound_load_vag("\\SFX\\POP.VAG;1");
|
||||
if(sfx_sprn.addr == 0) sfx_sprn = sound_load_vag("\\SFX\\SPRN.VAG;1");
|
||||
if(sfx_chek.addr == 0) sfx_chek = sound_load_vag("\\SFX\\CHEK.VAG;1");
|
||||
if(sfx_death.addr == 0) sfx_death = sound_load_vag("\\SFX\\DEATH.VAG;1");
|
||||
if(sfx_ringl.addr == 0) sfx_ringl = sound_load_vag("\\SFX\\RINGLOSS.VAG;1");
|
||||
if(sfx_jump.addr == 0) sfx_jump = sound_load_vag("\\SFX\\JUMP.VAG;1");
|
||||
if(sfx_skid.addr == 0) sfx_skid = sound_load_vag("\\SFX\\SKIDDING.VAG;1");
|
||||
if(sfx_roll.addr == 0) sfx_roll = sound_load_vag("\\SFX\\ROLL.VAG;1");
|
||||
if(sfx_dash.addr == 0) sfx_dash = sound_load_vag("\\SFX\\DASH.VAG;1");
|
||||
if(sfx_relea.addr == 0) sfx_relea = sound_load_vag("\\SFX\\RELEA.VAG;1");
|
||||
if(sfx_dropd.addr == 0) sfx_dropd = sound_load_vag("\\SFX\\DROPD.VAG;1");
|
||||
if(sfx_ring.addr == 0) sfx_ring = sound_load_vag("\\SFX\\RING.VAG;1");
|
||||
if(sfx_pop.addr == 0) sfx_pop = sound_load_vag("\\SFX\\POP.VAG;1");
|
||||
if(sfx_sprn.addr == 0) sfx_sprn = sound_load_vag("\\SFX\\SPRN.VAG;1");
|
||||
if(sfx_chek.addr == 0) sfx_chek = sound_load_vag("\\SFX\\CHEK.VAG;1");
|
||||
if(sfx_death.addr == 0) sfx_death = sound_load_vag("\\SFX\\DEATH.VAG;1");
|
||||
if(sfx_ringl.addr == 0) sfx_ringl = sound_load_vag("\\SFX\\RINGLOSS.VAG;1");
|
||||
if(sfx_shield.addr == 0) sfx_shield = sound_load_vag("\\SFX\\SHIELD.VAG;1");
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -715,8 +719,28 @@ player_draw(Player *player, VECTOR *pos)
|
|||
player->anim_dir < 0);
|
||||
}
|
||||
|
||||
void _player_set_hurt(Player *player, int32_t hazard_x);
|
||||
void _player_set_ring_loss(Player *player, int32_t hazard_x, uint8_t num_rings);
|
||||
|
||||
void
|
||||
player_set_hurt(Player *player, int32_t hazard_x)
|
||||
player_do_damage(Player *player, int32_t hazard_x)
|
||||
{
|
||||
// TODO: Missing death routine
|
||||
if((player->shield > 0)
|
||||
|| (level_ring_count == 0)) { // TODO: Remove this in favor of a death
|
||||
player->shield = 0;
|
||||
_player_set_hurt(player, hazard_x);
|
||||
sound_play_vag(sfx_death, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
_player_set_ring_loss(player, hazard_x, level_ring_count);
|
||||
level_ring_count = 0;
|
||||
sound_play_vag(sfx_ringl, 0);
|
||||
}
|
||||
|
||||
void
|
||||
_player_set_hurt(Player *player, int32_t hazard_x)
|
||||
{
|
||||
player->action = ACTION_HURT;
|
||||
player->grnd = 0;
|
||||
|
@ -733,9 +757,9 @@ player_set_hurt(Player *player, int32_t hazard_x)
|
|||
#define RING_START_SPD_DIRECT 4
|
||||
|
||||
void
|
||||
player_set_ring_loss(Player *player, int32_t hazard_x, uint8_t num_rings)
|
||||
_player_set_ring_loss(Player *player, int32_t hazard_x, uint8_t num_rings)
|
||||
{
|
||||
player_set_hurt(player, hazard_x);
|
||||
_player_set_hurt(player, hazard_x);
|
||||
|
||||
num_rings = num_rings > 32 ? 32 : num_rings;
|
||||
|
||||
|
|
|
@ -42,6 +42,7 @@ class ObjectId(Enum):
|
|||
# or effect.
|
||||
EXPLOSION = 0x0a
|
||||
MONITOR_IMAGE = 0x0b
|
||||
SHIELD = 0x0c
|
||||
|
||||
@staticmethod
|
||||
def get(name):
|
||||
|
@ -58,6 +59,7 @@ class ObjectId(Enum):
|
|||
"switch": ObjectId.SWITCH,
|
||||
"explosion": ObjectId.EXPLOSION,
|
||||
"monitor_image": ObjectId.MONITOR_IMAGE,
|
||||
"shield": ObjectId.SHIELD,
|
||||
}
|
||||
result = switch.get(name.lower())
|
||||
assert result is not None, f"Unknown common object {name}"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue