Login

Subversion Repositories NedoOS

Rev

Rev 957 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

#ifndef ENGINE_C
#define ENGINE_C
//#include <evo.h>
//#include "sprite_pool.c"

#define STATE_PLAY 0
#define STATE_TALK 1
#define STATE_GAMEOVER 2
#define STATE_WIN 3
#define STATE_MENU 4

static u8 state = STATE_MENU;

#define GHOST 16
#define FAIRY 32
#define BAT 48
#define INJAN 260
#define BOOK 276
#define KNIFES 292
#define ICE 528
#define FIARY2 784
#define FROG 800
#define ICEBALL 816
#define FIREBALL 544
#define EYE 560
#define FIARY3 1040
#define SHARP_ICE 1056
#define KNIFE_LEFT 1552

//#define DEFAULT_BULLET 0x102
//#define MARISA_BULLET 0x143
//#define CIRNO_BULLET 0x100
//#define SAKUYA_BULLET 0x140
//#define FLAN_BULLET 0x101
//#define BULLET2 0x141
#define DEFAULT_BULLET 0x510
#define MARISA_BULLET 0x51a
#define CIRNO_BULLET 0x50c
#define SAKUYA_BULLET 0x514
#define FLAN_BULLET 0x50e
#define BULLET2 0x516


#define CIRNO 512
#define FLANDRE 768
#define MARISA 1024
#define MAID 1536
#define PATCHULY 1792
#define FAIRY_MB 2048
static u8 keys[40];
static u8 is_npc_right_type(Npc *n, u8 type);
//static u16 score;
static u8 hp;
static i16 scroll_pos;
static i16 hor_scroll_pos = 0;
static u32 level_loop;
static i8 scroll_speed;
static i8 hor_scroll_speed = 0;
static i8 immortality = -1;
static u8 schedule = 0;
static u8 add_cnt = 0;
static u8 push_counter = 0;
static void (*process_level)();
static u16 bullet_sprite = DEFAULT_BULLET;

void wait_for_space()
{
    while (1)
    {
        keyboard(keys);
        if (keys[KEY_SPACE])
            break;
        swap_screen();
    }
}

static void push_npc(i16 x, i16 y, i8 dx, i8 dy, u16 tile, u8 type, u16 hp, u16 bonus)
{
    i8 npc = find_free_npc();

    if (npc != -1)
    {
        npcs[npc].sprite.tile = tile;
       if (x < 16) x = 16;
       if (x > 296) x = 296;
        npcs[npc].sprite.x = x;
        npcs[npc].sprite.y = y;
        npcs[npc].sprite.dx = dx;
        npcs[npc].sprite.dy = dy;
        npcs[npc].hp = hp;
        npcs[npc].type = type;
        npcs[npc].take_bonus = bonus;
    }
}

static void push_bonus(u16 type, u16 x, u16 y, i8 dx, i8 dy)
{
    i8 b = find_free_bonus();
    if (b >= 0)
    {
        bonuses[b].x = x;
        bonuses[b].y = y;
        bonuses[b].tile = type;
        bonuses[b].dx = dx;
        bonuses[b].dy = dy;
    }
}

static void push_bullet(u16 x, u16 y, i8 dx, i8 dy)
{
    i8 b = find_free_bullet();
    if (b != -1)
    {
        bullets[b].x = x;
        bullets[b].y = y;
        bullets[b].dx = dx;
        bullets[b].dy = dy;
        bullets[b].tile = bullet_sprite;
    }
}

static void push_star(u16 x, u16 y)
{
    push_bullet(x + 2, y + 3, 2, 3);
    push_bullet(x + 3, y + 0, 3, 0);
    push_bullet(x + 3, y - 2, 3, -2);
    push_bullet(x + 1, y - 4, 1, -4);
    push_bullet(x - 1, y - 4, -1, -4);
    push_bullet(x - 4, y - 3, -4, -3);
    push_bullet(x - 4, y - 1, -4, -1);
    push_bullet(x - 4, y + 2, -4, 2);
    push_bullet(x - 2, y + 3, -2, 3);
}

static void npc_type_shoot(u8 type, i8 dx, i8 dy)
{
    static u8 npc;
    for (npc = 0; npc < NPC_count; npc++)
    {
        if (is_npc_right_type(&npcs[npc], type))
        {
            push_bullet(npcs[npc].sprite.x + 16, npcs[npc].sprite.y + 16, dx, dy);
        }
    }
}

static i16 abs(i16 v)
{
    if (v < 0)
        return -v;

    return v;
}

static i16 sign(i16 v)
{
    if (v < 0)
        return -1;

    return 1;
}

static i16 min(i16 x, i16 y)
{
    return x < y ? x : y;
}

static i16 max(i16 x, i16 y)
{
    return x > y ? x : y;
}

static void npc_aimed_shoot(u8 type)
{
    i16 dx;
    i16 dy;
    static u8 npc;
    for (npc = 0; npc < NPC_count; npc++)
    {
        if (is_npc_right_type(&npcs[npc], type))
        {
            dx = player.x - npcs[npc].sprite.x;
            dy = player.y - npcs[npc].sprite.y;
            dx = sign(dx) * min(abs(dx) / 8, 5);
            dy = sign(dy) * min(abs(dy) / 8, 5);

            push_bullet(npcs[npc].sprite.x + 16, npcs[npc].sprite.y + 16, dx, dy);
        }
    }
}

static void npc_shoot(i8 dx, u8 dy)
{
    static u8 npc;
    for (npc = 0; npc < NPC_count; npc++)
    {
        if (is_npc_active(&npcs[npc]))
        {
            push_bullet(npcs[npc].sprite.x + 16, npcs[npc].sprite.y + 16, dx, dy);
        }
    }
}

static void npc_type_star(u8 type)
{
    static u8 npc;
    for (npc = 0; npc < NPC_count; npc++)
    {
        if (is_npc_right_type(&npcs[npc], type))
        {
            push_star(npcs[npc].sprite.x + 16, npcs[npc].sprite.y + 16);
        }
    }
}

static void npc_by_type_set_speed(u8 type, i8 dx, i8 dy)
{
    static u8 npc;
    for (npc = 0; npc < NPC_count; npc++)
    {
        if (is_npc_right_type(&npcs[npc], type))
        {
            npcs[npc].sprite.dx = dx;
            npcs[npc].sprite.dy = dy;
        }
    }
}

static void user_fire()
{
    i8 bullet = find_free_my_bullet();
    if (bullet > -1)
    {
        my_bullets[bullet].tile = MY_BULLET;
        my_bullets[bullet].x = player.x + 8;
        my_bullets[bullet].y = player.y - 8;
        my_bullets[bullet].dx = 0;
        my_bullets[bullet].dy = -16;
    }
}

static u8 is_npc_right_type(Npc *n, u8 type)
{
    return n->type == type && is_npc_active(n);
}

static u8 is_player_collide_with_bullet(MovableSprite *bullet)
{
    return bullet->x < player.x + 28 &&
           bullet->x + 8 > player.x + 4 &&
           bullet->y < player.y + 28 &&
           bullet->y + 8 > player.y + 4;
}

static u8 is_player_collide_with_enemy(MovableSprite *enemy)
{
    return enemy->x + 4 < player.x + 28 &&
           enemy->x + 28 > player.x &&
           enemy->y + 4 < player.y + 28 &&
           enemy->y + 28 > player.y;
}

static u8 is_enemy_collide_with_bullet(MovableSprite *enemy, MovableSprite *bullet)
{
    return enemy->x < bullet->x + 8 &&
           enemy->x + 28 > bullet->x &&
           enemy->y + 4 < bullet->y + 16 &&
           enemy->y + 28 > bullet->y;
}

static MovableSprite *is_player_collide_with_pups()
{
    static u8 cnt;
    for (cnt = 0; cnt < MAX_BONUS_COUNT; cnt++)
    {
        if (bonuses[cnt].y < MAX_Y_RES &&
            bonuses[cnt].x < player.x + 28 &&
            bonuses[cnt].x + 8 > player.x + 4 &&
            bonuses[cnt].y < player.y + 28 &&
            bonuses[cnt].y + 8 > player.y + 4)
        {
            bonuses[cnt].y = MAX_Y_RES + 1;
            return &bonuses[cnt];
        }
    }

    return 0;
}

static u8 is_player_collide()
{
#ifdef CHEAT
if (cheat_on) return 0;
#endif
    for (cnt = 0; cnt < BULLETS_count; cnt++)
        if (is_bullet_active(&bullets[cnt]) && is_player_collide_with_bullet(&bullets[cnt]))
        {
            return 1;
        }

    for (cnt = 0; cnt < NPC_count; cnt++)
        if (is_npc_active(&npcs[cnt]) && is_player_collide_with_enemy(&npcs[cnt].sprite))
        {
            npcs[cnt].hp--;
            return 1;
        }

    return 0;
}

static void enemy_collision()
{
    static u8 ec, cnt;
    u8 is_played = 0;
    for (cnt = 0; cnt < MY_BULLETS_max; cnt++)
        if (is_bullet_active(&my_bullets[cnt]))
            for (ec = 0; ec < NPC_count; ec++)
                if (is_npc_active(&npcs[ec]) && is_enemy_collide_with_bullet(&npcs[ec].sprite, &my_bullets[cnt]))
                {
                    if (my_bullets[cnt].tile == MY_BULLET)
                        my_bullets[cnt].tile = MY_BULLET + 2;

                    if (!is_played)
                    {
                        sfx_play(0, -3);
                        is_played = 1;
                    }
                    npcs[ec].hp--;
                    score ++;
                }
}

static Npc *find_npc_by_type(u8 type)
{
    u8 i;
    for (i = 0; i < NPC_count; i++)
    {
        if (is_npc_right_type(&npcs[i], type))
        {
            return &npcs[i];
        }
    }

    return 0;
}
#endif