mirror of
https://github.com/libretro/jumpnbump-libretro.git
synced 2026-11-07 10:36:00 -10:00
2068 lines
60 KiB
C
2068 lines
60 KiB
C
#ifdef _WIN32
|
|
#include <direct.h>
|
|
#else
|
|
#include <unistd.h>
|
|
#endif
|
|
|
|
#include "globals.h"
|
|
#include "network.h"
|
|
|
|
#ifndef M_PI
|
|
#define M_PI 3.14159265358979323846264338327950288
|
|
#endif
|
|
|
|
int flies_enabled = 0;
|
|
int flip = 0;
|
|
|
|
struct {
|
|
int x, y;
|
|
int old_x, old_y;
|
|
int old_draw_x, old_draw_y;
|
|
int back[2];
|
|
int back_defined[2];
|
|
} flies[NUM_FLIES];
|
|
|
|
|
|
gob_t rabbit_gobs = { 0 };
|
|
gob_t font_gobs = { 0 };
|
|
gob_t object_gobs = { 0 };
|
|
gob_t number_gobs = { 0 };
|
|
|
|
int endscore_reached;
|
|
|
|
main_info_t main_info;
|
|
player_t player[JNB_MAX_PLAYERS];
|
|
player_anim_t player_anims[7];
|
|
object_t objects[NUM_OBJECTS];
|
|
|
|
unsigned char *datafile_buffer = NULL;
|
|
|
|
unsigned char background_pic[JNB_WIDTH*JNB_HEIGHT];
|
|
unsigned char mask_pic[JNB_WIDTH*JNB_HEIGHT];
|
|
|
|
char pal[768];
|
|
char cur_pal[768];
|
|
|
|
int ai[JNB_MAX_PLAYERS];
|
|
|
|
unsigned int ban_map[17][22] = {
|
|
{1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
|
{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0},
|
|
{1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0},
|
|
{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1},
|
|
{1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1},
|
|
{1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
|
|
{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1},
|
|
{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1},
|
|
{1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1},
|
|
{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 1, 0, 0, 0, 0, 0, 0, 0, 1},
|
|
{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1},
|
|
{1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1},
|
|
{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
|
|
{1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1},
|
|
{2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 0, 0, 0, 0, 0, 1, 3, 3, 3, 1, 1, 1},
|
|
{2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
|
|
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
|
|
};
|
|
|
|
#define GET_BAN_MAP_XY(x,y) ban_map[(y) >> 4][(x) >> 4]
|
|
|
|
struct {
|
|
int num_frames;
|
|
int restart_frame;
|
|
struct {
|
|
int image;
|
|
int ticks;
|
|
} frame[10];
|
|
} object_anims[8] = {
|
|
{
|
|
6, 0,
|
|
{
|
|
{0, 3},
|
|
{1, 3},
|
|
{2, 3},
|
|
{3, 3},
|
|
{4, 3},
|
|
{5, 3},
|
|
{0, 0},
|
|
{0, 0},
|
|
{0, 0},
|
|
{0, 0}
|
|
}
|
|
}, {
|
|
9, 0,
|
|
{
|
|
{6, 2},
|
|
{7, 2},
|
|
{8, 2},
|
|
{9, 2},
|
|
{10, 2},
|
|
{11, 2},
|
|
{12, 2},
|
|
{13, 2},
|
|
{14, 2},
|
|
{0, 0}
|
|
}
|
|
}, {
|
|
5, 0,
|
|
{
|
|
{15, 3},
|
|
{16, 3},
|
|
{16, 3},
|
|
{17, 3},
|
|
{18, 3},
|
|
{19, 3},
|
|
{0, 0},
|
|
{0, 0},
|
|
{0, 0},
|
|
{0, 0}
|
|
}
|
|
}, {
|
|
10, 0,
|
|
{
|
|
{20, 2},
|
|
{21, 2},
|
|
{22, 2},
|
|
{23, 2},
|
|
{24, 2},
|
|
{25, 2},
|
|
{24, 2},
|
|
{23, 2},
|
|
{22, 2},
|
|
{21, 2}
|
|
}
|
|
}, {
|
|
10, 0,
|
|
{
|
|
{26, 2},
|
|
{27, 2},
|
|
{28, 2},
|
|
{29, 2},
|
|
{30, 2},
|
|
{31, 2},
|
|
{30, 2},
|
|
{29, 2},
|
|
{28, 2},
|
|
{27, 2}
|
|
}
|
|
}, {
|
|
10, 0,
|
|
{
|
|
{32, 2},
|
|
{33, 2},
|
|
{34, 2},
|
|
{35, 2},
|
|
{36, 2},
|
|
{37, 2},
|
|
{36, 2},
|
|
{35, 2},
|
|
{34, 2},
|
|
{33, 2}
|
|
}
|
|
}, {
|
|
10, 0,
|
|
{
|
|
{38, 2},
|
|
{39, 2},
|
|
{40, 2},
|
|
{41, 2},
|
|
{42, 2},
|
|
{43, 2},
|
|
{42, 2},
|
|
{41, 2},
|
|
{40, 2},
|
|
{39, 2}
|
|
}
|
|
}, {
|
|
4, 0,
|
|
{
|
|
{76, 4},
|
|
{77, 4},
|
|
{78, 4},
|
|
{79, 4},
|
|
{0, 0},
|
|
{0, 0},
|
|
{0, 0},
|
|
{0, 0},
|
|
{0, 0},
|
|
{0, 0}
|
|
}
|
|
}
|
|
};
|
|
|
|
struct {
|
|
struct {
|
|
short num_pobs;
|
|
struct {
|
|
int x, y;
|
|
int image;
|
|
gob_t *pob_data;
|
|
} pobs[NUM_LEFTOVERS];
|
|
} page[2];
|
|
} leftovers;
|
|
|
|
int client_player_num = -1;
|
|
int pogostick, bunnies_in_space, jetpack, lord_of_the_flies, blood_is_thicker_than_water;
|
|
|
|
void draw_leftovers(int page)
|
|
{
|
|
int c1;
|
|
|
|
for (c1 = leftovers.page[page].num_pobs - 1; c1 >= 0; c1--)
|
|
put_pob(page, leftovers.page[page].pobs[c1].x, leftovers.page[page].pobs[c1].y, leftovers.page[page].pobs[c1].image, leftovers.page[page].pobs[c1].pob_data, 1, mask_pic);
|
|
|
|
leftovers.page[page].num_pobs = 0;
|
|
}
|
|
|
|
int add_leftovers(int page, int x, int y, int image, gob_t *pob_data)
|
|
{
|
|
|
|
if (leftovers.page[page].num_pobs >= NUM_LEFTOVERS)
|
|
return 1;
|
|
|
|
leftovers.page[page].pobs[leftovers.page[page].num_pobs].x = x;
|
|
leftovers.page[page].pobs[leftovers.page[page].num_pobs].y = y;
|
|
leftovers.page[page].pobs[leftovers.page[page].num_pobs].image = image;
|
|
leftovers.page[page].pobs[leftovers.page[page].num_pobs].pob_data = pob_data;
|
|
leftovers.page[page].num_pobs++;
|
|
|
|
return 0;
|
|
}
|
|
|
|
void add_object(int type, int x, int y, int x_add, int y_add, int anim, int frame)
|
|
{
|
|
int c1;
|
|
|
|
for (c1 = 0; c1 < NUM_OBJECTS; c1++) {
|
|
if (objects[c1].used == 0) {
|
|
objects[c1].used = 1;
|
|
objects[c1].type = type;
|
|
objects[c1].x = (long) x << 16;
|
|
objects[c1].y = (long) y << 16;
|
|
objects[c1].x_add = x_add;
|
|
objects[c1].y_add = y_add;
|
|
objects[c1].x_acc = 0;
|
|
objects[c1].y_acc = 0;
|
|
objects[c1].anim = anim;
|
|
objects[c1].frame = frame;
|
|
objects[c1].ticks = object_anims[anim].frame[frame].ticks;
|
|
objects[c1].image = object_anims[anim].frame[frame].image;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
int init_program(void)
|
|
{
|
|
unsigned char *handle = (unsigned char *) NULL;
|
|
int c1 = 0, c2 = 0;
|
|
sfx_data fly;
|
|
int player_anim_data[] = {
|
|
1, 0, 0, 0x7fff, 0, 0, 0, 0, 0, 0,
|
|
4, 0, 0, 4, 1, 4, 2, 4, 3, 4,
|
|
1, 0, 4, 0x7fff, 0, 0, 0, 0, 0, 0,
|
|
4, 2, 5, 8, 6, 10, 7, 3, 6, 3,
|
|
1, 0, 6, 0x7fff, 0, 0, 0, 0, 0, 0,
|
|
2, 1, 5, 8, 4, 0x7fff, 0, 0, 0, 0,
|
|
1, 0, 8, 5, 0, 0, 0, 0, 0, 0
|
|
};
|
|
|
|
srand(time(NULL));
|
|
|
|
memset(&main_info, 0, sizeof(main_info));
|
|
|
|
for (c1 = 0; c1 < 7; c1++) {
|
|
player_anims[c1].num_frames = player_anim_data[c1 * 10];
|
|
player_anims[c1].restart_frame = player_anim_data[c1 * 10 + 1];
|
|
for (c2 = 0; c2 < 4; c2++) {
|
|
player_anims[c1].frame[c2].image = player_anim_data[c1 * 10 + c2 * 2 + 2];
|
|
player_anims[c1].frame[c2].ticks = player_anim_data[c1 * 10 + c2 * 2 + 3];
|
|
}
|
|
}
|
|
|
|
if ((handle = dat_open("menu.pcx")) == 0) {
|
|
strcpy(main_info.error_str, "Error loading 'menu.pcx', aborting...\n");
|
|
return 1;
|
|
}
|
|
if (read_pcx(handle, background_pic, JNB_WIDTH*JNB_HEIGHT, pal) != 0) {
|
|
strcpy(main_info.error_str, "Error loading 'menu.pcx', aborting...\n");
|
|
return 1;
|
|
}
|
|
|
|
if ((handle = dat_open("rabbit.gob")) == 0) {
|
|
strcpy(main_info.error_str, "Error loading 'rabbit.gob', aborting...\n");
|
|
return 1;
|
|
}
|
|
if (register_gob(handle, &rabbit_gobs, dat_filelen("rabbit.gob"))) {
|
|
return 1;
|
|
}
|
|
|
|
if ((handle = dat_open("objects.gob")) == 0) {
|
|
strcpy(main_info.error_str, "Error loading 'objects.gob', aborting...\n");
|
|
return 1;
|
|
}
|
|
if (register_gob(handle, &object_gobs, dat_filelen("objects.gob"))) {
|
|
return 1;
|
|
}
|
|
|
|
if ((handle = dat_open("font.gob")) == 0) {
|
|
strcpy(main_info.error_str, "Error loading 'font.gob', aborting...\n");
|
|
return 1;
|
|
}
|
|
if (register_gob(handle, &font_gobs, dat_filelen("font.gob"))) {
|
|
return 1;
|
|
}
|
|
|
|
if ((handle = dat_open("numbers.gob")) == 0) {
|
|
strcpy(main_info.error_str, "Error loading 'numbers.gob', aborting...\n");
|
|
return 1;
|
|
}
|
|
if (register_gob(handle, &number_gobs, dat_filelen("numbers.gob"))) {
|
|
return 1;
|
|
}
|
|
|
|
open_screen();
|
|
dj_init();
|
|
|
|
if (main_info.no_sound == 0) {
|
|
dj_autodetect_sd();
|
|
dj_set_mixing_freq(20000);
|
|
dj_set_stereo(0);
|
|
dj_set_auto_mix(0);
|
|
dj_set_dma_time(8);
|
|
dj_set_num_sfx_channels(5);
|
|
dj_set_sfx_volume(64);
|
|
dj_set_nosound(1);
|
|
dj_start();
|
|
|
|
if ((handle = dat_open("jump.mod")) == 0) {
|
|
strcpy(main_info.error_str, "Error loading 'jump.mod', aborting...\n");
|
|
return 1;
|
|
}
|
|
if (dj_load_mod(handle, 0, MOD_MENU) != 0) {
|
|
strcpy(main_info.error_str, "Error loading 'jump.mod', aborting...\n");
|
|
return 1;
|
|
}
|
|
|
|
if ((handle = dat_open("bump.mod")) == 0) {
|
|
strcpy(main_info.error_str, "Error loading 'bump.mod', aborting...\n");
|
|
return 1;
|
|
}
|
|
if (dj_load_mod(handle, 0, MOD_GAME) != 0) {
|
|
strcpy(main_info.error_str, "Error loading 'bump.mod', aborting...\n");
|
|
return 1;
|
|
}
|
|
|
|
if ((handle = dat_open("scores.mod")) == 0) {
|
|
strcpy(main_info.error_str, "Error loading 'scores.mod', aborting...\n");
|
|
return 1;
|
|
}
|
|
if (dj_load_mod(handle, 0, MOD_SCORES) != 0) {
|
|
strcpy(main_info.error_str, "Error loading 'scores.mod', aborting...\n");
|
|
return 1;
|
|
}
|
|
|
|
if ((handle = dat_open("jump.smp")) == 0) {
|
|
strcpy(main_info.error_str, "Error loading 'jump.smp', aborting...\n");
|
|
return 1;
|
|
}
|
|
if (dj_load_sfx(handle, 0, dat_filelen("jump.smp"), DJ_SFX_TYPE_SMP, SFX_JUMP) != 0) {
|
|
strcpy(main_info.error_str, "Error loading 'jump.smp', aborting...\n");
|
|
return 1;
|
|
}
|
|
|
|
if ((handle = dat_open("death.smp")) == 0) {
|
|
strcpy(main_info.error_str, "Error loading 'death.smp', aborting...\n");
|
|
return 1;
|
|
}
|
|
if (dj_load_sfx(handle, 0, dat_filelen("death.smp"), DJ_SFX_TYPE_SMP, SFX_DEATH) != 0) {
|
|
strcpy(main_info.error_str, "Error loading 'death.smp', aborting...\n");
|
|
return 1;
|
|
}
|
|
|
|
if ((handle = dat_open("spring.smp")) == 0) {
|
|
strcpy(main_info.error_str, "Error loading 'spring.smp', aborting...\n");
|
|
return 1;
|
|
}
|
|
if (dj_load_sfx(handle, 0, dat_filelen("spring.smp"), DJ_SFX_TYPE_SMP, SFX_SPRING) != 0) {
|
|
strcpy(main_info.error_str, "Error loading 'spring.smp', aborting...\n");
|
|
return 1;
|
|
}
|
|
|
|
if ((handle = dat_open("splash.smp")) == 0) {
|
|
strcpy(main_info.error_str, "Error loading 'splash.smp', aborting...\n");
|
|
return 1;
|
|
}
|
|
if (dj_load_sfx(handle, 0, dat_filelen("splash.smp"), DJ_SFX_TYPE_SMP, SFX_SPLASH) != 0) {
|
|
strcpy(main_info.error_str, "Error loading 'splash.smp', aborting...\n");
|
|
return 1;
|
|
}
|
|
|
|
if ((handle = dat_open("fly.smp")) == 0) {
|
|
strcpy(main_info.error_str, "Error loading 'fly.smp', aborting...\n");
|
|
return 1;
|
|
}
|
|
if (dj_load_sfx(handle, 0, dat_filelen("fly.smp"), DJ_SFX_TYPE_SMP, SFX_FLY) != 0) {
|
|
strcpy(main_info.error_str, "Error loading 'fly.smp', aborting...\n");
|
|
return 1;
|
|
}
|
|
|
|
dj_get_sfx_settings(SFX_FLY, &fly);
|
|
fly.priority = 10;
|
|
fly.default_freq = SFX_FLY_FREQ;
|
|
fly.loop = 1;
|
|
fly.loop_start = 0;
|
|
fly.loop_length = fly.length;
|
|
dj_set_sfx_settings(SFX_FLY, &fly);
|
|
}
|
|
|
|
memset(mask_pic, 0, JNB_WIDTH*JNB_HEIGHT);
|
|
register_mask(mask_pic);
|
|
|
|
/* fix dark font */
|
|
for (c1 = 0; c1 < 16; c1++) {
|
|
pal[(240 + c1) * 3 + 0] = c1 << 2;
|
|
pal[(240 + c1) * 3 + 1] = c1 << 2;
|
|
pal[(240 + c1) * 3 + 2] = c1 << 2;
|
|
}
|
|
|
|
setpalette(0, 256, pal);
|
|
|
|
for(c1 = 0; c1 < JNB_MAX_PLAYERS; c1++) // reset player values
|
|
{
|
|
ai[c1] = 0;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void deinit_program(void)
|
|
{
|
|
free_gob(&rabbit_gobs);
|
|
free_gob(&object_gobs);
|
|
free_gob(&font_gobs);
|
|
free_gob(&number_gobs);
|
|
|
|
dj_stop();
|
|
dj_free_mod(MOD_MENU);
|
|
dj_free_mod(MOD_GAME);
|
|
dj_free_mod(MOD_SCORES);
|
|
dj_free_sfx(SFX_DEATH);
|
|
dj_free_sfx(SFX_SPRING);
|
|
dj_free_sfx(SFX_SPLASH);
|
|
dj_free_sfx(SFX_FLY);
|
|
dj_free_sfx(SFX_JUMP);
|
|
dj_deinit();
|
|
}
|
|
|
|
static void flip_pixels(unsigned char *pixels)
|
|
{
|
|
int x,y;
|
|
unsigned char temp;
|
|
|
|
assert(pixels);
|
|
for (y = 0; y < JNB_HEIGHT; y++) {
|
|
for (x = 0; x < (352/2); x++) {
|
|
temp = pixels[y*JNB_WIDTH+x];
|
|
pixels[y*JNB_WIDTH+x] = pixels[y*JNB_WIDTH+(352-x)-1];
|
|
pixels[y*JNB_WIDTH+(352-x)-1] = temp;
|
|
}
|
|
}
|
|
}
|
|
|
|
void get_closest_player_to_point(int x,int y,int *dist,int *closest_player)
|
|
{
|
|
int c1;
|
|
int cur_dist = 0;
|
|
|
|
*dist = 0x7fff;
|
|
for (c1 = 0; c1 < JNB_MAX_PLAYERS; c1++) {
|
|
if (player[c1].enabled == 1) {
|
|
cur_dist = (int)sqrt((x - ((player[c1].x >> 16) + 8)) * (x - ((player[c1].x >> 16) + 8)) + (y - ((player[c1].y >> 16) + 8)) * (y - ((player[c1].y >> 16) + 8)));
|
|
if (cur_dist < *dist) {
|
|
*closest_player = c1;
|
|
*dist = cur_dist;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
int init_level()
|
|
{
|
|
unsigned char *handle;
|
|
int c1, c2;
|
|
int s1, s2;
|
|
|
|
if ((handle = dat_open("level.pcx")) == 0) {
|
|
strcpy(main_info.error_str, "Error loading 'level.pcx', aborting...\n");
|
|
return 1;
|
|
}
|
|
if (read_pcx(handle, background_pic, JNB_WIDTH*JNB_HEIGHT, pal) != 0) {
|
|
strcpy(main_info.error_str, "Error loading 'level.pcx', aborting...\n");
|
|
return 1;
|
|
}
|
|
if (flip)
|
|
flip_pixels(background_pic);
|
|
|
|
if ((handle = dat_open("mask.pcx")) == 0) {
|
|
strcpy(main_info.error_str, "Error loading 'mask.pcx', aborting...\n");
|
|
return 1;
|
|
}
|
|
if (read_pcx(handle, mask_pic, JNB_WIDTH*JNB_HEIGHT, 0) != 0) {
|
|
strcpy(main_info.error_str, "Error loading 'mask.pcx', aborting...\n");
|
|
return 1;
|
|
}
|
|
if (flip)
|
|
flip_pixels(mask_pic);
|
|
|
|
if (read_level() != 0) {
|
|
strcpy(main_info.error_str, "Error loading 'levelmap.txt', aborting...\n");
|
|
return 1;
|
|
}
|
|
|
|
for (c1 = 0; c1 < JNB_MAX_PLAYERS; c1++) {
|
|
if (player[c1].enabled == 1) {
|
|
player[c1].bumps = 0;
|
|
for (c2 = 0; c2 < JNB_MAX_PLAYERS; c2++)
|
|
player[c1].bumped[c2] = 0;
|
|
position_player(c1);
|
|
add_leftovers(0, 360, 34 + c1 * 64, 0, &number_gobs);
|
|
add_leftovers(1, 360, 34 + c1 * 64, 0, &number_gobs);
|
|
add_leftovers(0, 376, 34 + c1 * 64, 0, &number_gobs);
|
|
add_leftovers(1, 376, 34 + c1 * 64, 0, &number_gobs);
|
|
}
|
|
}
|
|
|
|
for (c1 = 0; c1 < NUM_OBJECTS; c1++)
|
|
objects[c1].used = 0;
|
|
|
|
for (c1 = 0; c1 < 16; c1++) {
|
|
for (c2 = 0; c2 < 22; c2++) {
|
|
if (ban_map[c1][c2] == BAN_SPRING)
|
|
add_object(OBJ_SPRING, c2 << 4, c1 << 4, 0, 0, OBJ_ANIM_SPRING, 5);
|
|
}
|
|
}
|
|
|
|
while (1) {
|
|
s1 = rnd(22);
|
|
s2 = rnd(16);
|
|
if (ban_map[s2][s1] == BAN_VOID) {
|
|
add_object(OBJ_YEL_BUTFLY, (s1 << 4) + 8, (s2 << 4) + 8, (rnd(65535) - 32768) * 2, (rnd(65535) - 32768) * 2, 0, 0);
|
|
break;
|
|
}
|
|
}
|
|
while (1) {
|
|
s1 = rnd(22);
|
|
s2 = rnd(16);
|
|
if (ban_map[s2][s1] == BAN_VOID) {
|
|
add_object(OBJ_YEL_BUTFLY, (s1 << 4) + 8, (s2 << 4) + 8, (rnd(65535) - 32768) * 2, (rnd(65535) - 32768) * 2, 0, 0);
|
|
break;
|
|
}
|
|
}
|
|
while (1) {
|
|
s1 = rnd(22);
|
|
s2 = rnd(16);
|
|
if (ban_map[s2][s1] == BAN_VOID) {
|
|
add_object(OBJ_PINK_BUTFLY, (s1 << 4) + 8, (s2 << 4) + 8, (rnd(65535) - 32768) * 2, (rnd(65535) - 32768) * 2, 0, 0);
|
|
break;
|
|
}
|
|
}
|
|
while (1) {
|
|
s1 = rnd(22);
|
|
s2 = rnd(16);
|
|
if (ban_map[s2][s1] == BAN_VOID) {
|
|
add_object(OBJ_PINK_BUTFLY, (s1 << 4) + 8, (s2 << 4) + 8, (rnd(65535) - 32768) * 2, (rnd(65535) - 32768) * 2, 0, 0);
|
|
break;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void deinit_level(void)
|
|
{
|
|
dj_set_nosound(1);
|
|
dj_stop_mod();
|
|
}
|
|
|
|
static void update_flies(void)
|
|
{
|
|
int c1;
|
|
int closest_player = 0, dist;
|
|
int s1, s2, s3, s4;
|
|
|
|
/* get center of fly swarm */
|
|
s1 = s2 = 0;
|
|
for (c1 = 0; c1 < NUM_FLIES; c1++) {
|
|
s1 += flies[c1].x;
|
|
s2 += flies[c1].y;
|
|
}
|
|
s1 /= NUM_FLIES;
|
|
s2 /= NUM_FLIES;
|
|
|
|
/* get closest player to fly swarm */
|
|
get_closest_player_to_point(s1, s2, &dist, &closest_player);
|
|
/* update fly swarm sound */
|
|
s3 = 32 - dist / 3;
|
|
if (s3 < 0)
|
|
s3 = 0;
|
|
dj_set_sfx_channel_volume(4, (char)(s3));
|
|
|
|
for (c1 = 0; c1 < NUM_FLIES; c1++) {
|
|
/* get closest player to fly */
|
|
get_closest_player_to_point(flies[c1].x, flies[c1].y, &dist, &closest_player);
|
|
flies[c1].old_x = flies[c1].x;
|
|
flies[c1].old_y = flies[c1].y;
|
|
s3 = 0;
|
|
if ((s1 - flies[c1].x) > 30)
|
|
s3 += 1;
|
|
else if ((s1 - flies[c1].x) < -30)
|
|
s3 -= 1;
|
|
if (dist < 30) {
|
|
if (((player[closest_player].x >> 16) + 8) > flies[c1].x) {
|
|
if (lord_of_the_flies == 0)
|
|
s3 -= 1;
|
|
else
|
|
s3 += 1;
|
|
} else {
|
|
if (lord_of_the_flies == 0)
|
|
s3 += 1;
|
|
else
|
|
s3 -= 1;
|
|
}
|
|
}
|
|
s4 = rnd(3) - 1 + s3;
|
|
if ((flies[c1].x + s4) < 16)
|
|
s4 = 0;
|
|
if ((flies[c1].x + s4) > 351)
|
|
s4 = 0;
|
|
if (GET_BAN_MAP_XY(flies[c1].x + s4, flies[c1].y) != BAN_VOID)
|
|
s4 = 0;
|
|
flies[c1].x += s4;
|
|
s3 = 0;
|
|
if ((s2 - flies[c1].y) > 30)
|
|
s3 += 1;
|
|
else if ((s2 - flies[c1].y) < -30)
|
|
s3 -= 1;
|
|
if (dist < 30) {
|
|
if (((player[closest_player].y >> 16) + 8) > flies[c1].y) {
|
|
if (lord_of_the_flies == 0)
|
|
s3 -= 1;
|
|
else
|
|
s3 += 1;
|
|
} else {
|
|
if (lord_of_the_flies == 0)
|
|
s3 += 1;
|
|
else
|
|
s3 -= 1;
|
|
}
|
|
}
|
|
s4 = rnd(3) - 1 + s3;
|
|
if ((flies[c1].y + s4) < 0)
|
|
s4 = 0;
|
|
if ((flies[c1].y + s4) > 239)
|
|
s4 = 0;
|
|
if (GET_BAN_MAP_XY(flies[c1].x, flies[c1].y + s4) != BAN_VOID)
|
|
s4 = 0;
|
|
flies[c1].y += s4;
|
|
}
|
|
}
|
|
|
|
static void player_kill(int c1, int c2)
|
|
{
|
|
if (player[c1].y_add >= 0) {
|
|
if (is_server)
|
|
serverSendKillPacket(c1, c2);
|
|
} else {
|
|
if (player[c2].y_add < 0)
|
|
player[c2].y_add = 0;
|
|
}
|
|
}
|
|
|
|
static void collision_check(void)
|
|
{
|
|
int c1 = 0, c2 = 0, c3 = 0;
|
|
int l1;
|
|
|
|
/* collision check */
|
|
for (c3 = 0; c3 < 6; c3++) {
|
|
if (c3 == 0) {
|
|
c1 = 0;
|
|
c2 = 1;
|
|
} else if (c3 == 1) {
|
|
c1 = 0;
|
|
c2 = 2;
|
|
} else if (c3 == 2) {
|
|
c1 = 0;
|
|
c2 = 3;
|
|
} else if (c3 == 3) {
|
|
c1 = 1;
|
|
c2 = 2;
|
|
} else if (c3 == 4) {
|
|
c1 = 1;
|
|
c2 = 3;
|
|
} else if (c3 == 5) {
|
|
c1 = 2;
|
|
c2 = 3;
|
|
}
|
|
if (player[c1].enabled == 1 && player[c2].enabled == 1) {
|
|
if (labs(player[c1].x - player[c2].x) < (12L << 16) && labs(player[c1].y - player[c2].y) < (12L << 16)) {
|
|
if ((labs(player[c1].y - player[c2].y) >> 16) > 5) {
|
|
if (player[c1].y < player[c2].y) {
|
|
player_kill(c1,c2);
|
|
} else {
|
|
player_kill(c2,c1);
|
|
}
|
|
} else {
|
|
if (player[c1].x < player[c2].x) {
|
|
if (player[c1].x_add > 0)
|
|
player[c1].x = player[c2].x - (12L << 16);
|
|
else if (player[c2].x_add < 0)
|
|
player[c2].x = player[c1].x + (12L << 16);
|
|
else {
|
|
player[c1].x -= player[c1].x_add;
|
|
player[c2].x -= player[c2].x_add;
|
|
}
|
|
l1 = player[c2].x_add;
|
|
player[c2].x_add = player[c1].x_add;
|
|
player[c1].x_add = l1;
|
|
if (player[c1].x_add > 0)
|
|
player[c1].x_add = -player[c1].x_add;
|
|
if (player[c2].x_add < 0)
|
|
player[c2].x_add = -player[c2].x_add;
|
|
} else {
|
|
if (player[c1].x_add > 0)
|
|
player[c2].x = player[c1].x - (12L << 16);
|
|
else if (player[c2].x_add < 0)
|
|
player[c1].x = player[c2].x + (12L << 16);
|
|
else {
|
|
player[c1].x -= player[c1].x_add;
|
|
player[c2].x -= player[c2].x_add;
|
|
}
|
|
l1 = player[c2].x_add;
|
|
player[c2].x_add = player[c1].x_add;
|
|
player[c1].x_add = l1;
|
|
if (player[c1].x_add < 0)
|
|
player[c1].x_add = -player[c1].x_add;
|
|
if (player[c2].x_add > 0)
|
|
player[c2].x_add = -player[c2].x_add;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
static int mod_vol, sfx_vol;
|
|
static int end_loop_flag = 0;
|
|
static int fade_flag = 0;
|
|
static int update_palette = 0;
|
|
static int mod_fade_direction;
|
|
|
|
void end_game(void)
|
|
{
|
|
int c1, c2;
|
|
unsigned char *handle;
|
|
|
|
main_info.view_page = 0;
|
|
main_info.draw_page = 1;
|
|
|
|
dj_stop_sfx_channel(4);
|
|
|
|
deinit_level();
|
|
|
|
memset(mask_pic, 0, JNB_WIDTH*JNB_HEIGHT);
|
|
register_mask(mask_pic);
|
|
|
|
register_background(NULL, NULL);
|
|
|
|
draw_begin();
|
|
|
|
put_text(main_info.view_page, 100, 50, "DOTT", 2);
|
|
put_text(main_info.view_page, 160, 50, "JIFFY", 2);
|
|
put_text(main_info.view_page, 220, 50, "FIZZ", 2);
|
|
put_text(main_info.view_page, 280, 50, "MIJJI", 2);
|
|
put_text(main_info.view_page, 40, 80, "DOTT", 2);
|
|
put_text(main_info.view_page, 40, 110, "JIFFY", 2);
|
|
put_text(main_info.view_page, 40, 140, "FIZZ", 2);
|
|
put_text(main_info.view_page, 40, 170, "MIJJI", 2);
|
|
|
|
for (c1 = 0; c1 < JNB_MAX_PLAYERS; c1++) {
|
|
char str1[100];
|
|
if (!player[c1].enabled)
|
|
continue;
|
|
|
|
for (c2 = 0; c2 < JNB_MAX_PLAYERS; c2++) {
|
|
if (!player[c2].enabled) {
|
|
continue;
|
|
}
|
|
if (c2 != c1) {
|
|
sprintf(str1, "%d", player[c1].bumped[c2]);
|
|
put_text(main_info.view_page, 100 + c2 * 60, 80 + c1 * 30, str1, 2);
|
|
} else
|
|
put_text(main_info.view_page, 100 + c2 * 60, 80 + c1 * 30, "-", 2);
|
|
}
|
|
sprintf(str1, "%d", player[c1].bumps);
|
|
put_text(main_info.view_page, 350, 80 + c1 * 30, str1, 2);
|
|
}
|
|
|
|
put_text(main_info.view_page, 200, 230, "Press ESC to continue", 2);
|
|
|
|
draw_end();
|
|
|
|
flippage(main_info.view_page);
|
|
|
|
/* fix dark font */
|
|
for (c1 = 0; c1 < 16; c1++) {
|
|
pal[(240 + c1) * 3 + 0] = c1 << 2;
|
|
pal[(240 + c1) * 3 + 1] = c1 << 2;
|
|
pal[(240 + c1) * 3 + 2] = c1 << 2;
|
|
}
|
|
|
|
memset(cur_pal, 0, 768);
|
|
|
|
setpalette(0, 256, cur_pal);
|
|
|
|
mod_vol = 0;
|
|
dj_ready_mod(MOD_SCORES);
|
|
dj_set_mod_volume((char)mod_vol);
|
|
dj_start_mod();
|
|
dj_set_nosound(0);
|
|
}
|
|
|
|
|
|
int end_loop(void)
|
|
{
|
|
int c1;
|
|
|
|
if (mod_vol < 35)
|
|
mod_vol++;
|
|
dj_set_mod_volume((char)mod_vol);
|
|
for (c1 = 0; c1 < 768; c1++) {
|
|
if (cur_pal[c1] < pal[c1])
|
|
cur_pal[c1]++;
|
|
}
|
|
setpalette(0, 256, cur_pal);
|
|
flippage(main_info.view_page);
|
|
|
|
return key_pressed(1);
|
|
}
|
|
|
|
void game_init(void) {
|
|
int s1, s2;
|
|
int c1;
|
|
|
|
memset(cur_pal, 0, 768);
|
|
setpalette(0, 256, cur_pal);
|
|
|
|
flippage(1);
|
|
register_background(background_pic, pal);
|
|
flippage(0);
|
|
|
|
if (flies_enabled) {
|
|
s1 = rnd(250) + 50;
|
|
s2 = rnd(150) + 50;
|
|
|
|
for (c1 = 0; c1 < NUM_FLIES; c1++) {
|
|
while (1) {
|
|
flies[c1].x = s1 + rnd(101) - 50;
|
|
flies[c1].y = s2 + rnd(101) - 50;
|
|
if (GET_BAN_MAP_XY(flies[c1].x, flies[c1].y) == BAN_VOID)
|
|
break;
|
|
}
|
|
flies[c1].back_defined[0] = 0;
|
|
flies[c1].back_defined[1] = 0;
|
|
}
|
|
}
|
|
|
|
if (flies_enabled) {
|
|
dj_play_sfx(SFX_FLY, SFX_FLY_FREQ, 0, 0, 0, 4);
|
|
}
|
|
|
|
dj_set_nosound(0);
|
|
|
|
lord_of_the_flies = bunnies_in_space = jetpack = pogostick = blood_is_thicker_than_water = 0;
|
|
main_info.page_info[0].num_pobs = 0;
|
|
main_info.page_info[1].num_pobs = 0;
|
|
main_info.view_page = 0;
|
|
main_info.draw_page = 1;
|
|
|
|
mod_vol = sfx_vol = 0;
|
|
end_loop_flag = 0;
|
|
mod_fade_direction = 1;
|
|
dj_ready_mod(MOD_GAME);
|
|
dj_set_mod_volume((char)mod_vol);
|
|
dj_set_sfx_volume((char)mod_vol);
|
|
dj_start_mod();
|
|
|
|
endscore_reached = 0;
|
|
}
|
|
|
|
int game_loop(void) {
|
|
|
|
int i, c2;
|
|
|
|
if (endscore_reached || (key_pressed(1) == 1)) {
|
|
end_loop_flag = 1;
|
|
memset(pal, 0, 768);
|
|
mod_fade_direction = 0;
|
|
}
|
|
|
|
steer_players();
|
|
|
|
collision_check();
|
|
|
|
main_info.page_info[main_info.draw_page].num_pobs = 0;
|
|
for (i = 0; i < JNB_MAX_PLAYERS; i++) {
|
|
if (player[i].enabled == 1)
|
|
main_info.page_info[main_info.draw_page].num_pobs++;
|
|
}
|
|
|
|
update_objects();
|
|
|
|
if (flies_enabled) {
|
|
update_flies();
|
|
}
|
|
|
|
for (i = 0, c2 = 0; i < JNB_MAX_PLAYERS; i++) {
|
|
if (player[i].enabled == 1) {
|
|
main_info.page_info[main_info.draw_page].pobs[c2].x = player[i].x >> 16;
|
|
main_info.page_info[main_info.draw_page].pobs[c2].y = player[i].y >> 16;
|
|
main_info.page_info[main_info.draw_page].pobs[c2].image = player[i].image + i * 18;
|
|
main_info.page_info[main_info.draw_page].pobs[c2].pob_data = &rabbit_gobs;
|
|
c2++;
|
|
}
|
|
}
|
|
|
|
draw_begin();
|
|
|
|
draw_pobs(main_info.draw_page);
|
|
|
|
if (flies_enabled)
|
|
draw_flies(main_info.draw_page);
|
|
|
|
draw_end();
|
|
|
|
if (mod_fade_direction == 1) {
|
|
if (mod_vol < 30) {
|
|
mod_vol++;
|
|
dj_set_mod_volume((char)mod_vol);
|
|
}
|
|
if (sfx_vol < 64) {
|
|
sfx_vol++;
|
|
dj_set_sfx_volume((char)sfx_vol);
|
|
}
|
|
} else {
|
|
if (mod_vol > 0) {
|
|
mod_vol--;
|
|
dj_set_mod_volume((char)mod_vol);
|
|
}
|
|
if (sfx_vol > 0) {
|
|
sfx_vol--;
|
|
dj_set_sfx_volume((char)sfx_vol);
|
|
}
|
|
}
|
|
|
|
fade_flag = 0;
|
|
for (i = 0; i < 768; i++) {
|
|
if (cur_pal[i] < pal[i]) {
|
|
cur_pal[i]++;
|
|
fade_flag = 1;
|
|
} else if (cur_pal[i] > pal[i]) {
|
|
cur_pal[i]--;
|
|
fade_flag = 1;
|
|
}
|
|
}
|
|
if (fade_flag == 1)
|
|
update_palette = 1;
|
|
|
|
if (fade_flag == 0 && end_loop_flag == 1)
|
|
return 1;
|
|
|
|
if (update_palette == 1) {
|
|
setpalette(0, 256, cur_pal);
|
|
update_palette = 0;
|
|
}
|
|
|
|
main_info.draw_page ^= 1;
|
|
main_info.view_page ^= 1;
|
|
|
|
flippage(main_info.view_page);
|
|
|
|
draw_begin();
|
|
|
|
if (flies_enabled)
|
|
redraw_flies_background(main_info.draw_page);
|
|
|
|
redraw_pob_backgrounds(main_info.draw_page);
|
|
|
|
draw_leftovers(main_info.draw_page);
|
|
|
|
draw_end();
|
|
|
|
return 0;
|
|
}
|
|
|
|
unsigned short rnd(unsigned short max)
|
|
{
|
|
#if (RAND_MAX < 0x7fff)
|
|
#error "rand returns too small values"
|
|
#elif (RAND_MAX == 0x7fff)
|
|
return (unsigned short)((rand()*2) % (int)max);
|
|
#else
|
|
return (unsigned short)(rand() % (int)max);
|
|
#endif
|
|
}
|
|
|
|
static void player_action_left(int c1)
|
|
{
|
|
int s1 = 0, s2 = 0;
|
|
int below_left, below, below_right;
|
|
|
|
s1 = (player[c1].x >> 16);
|
|
s2 = (player[c1].y >> 16);
|
|
below_left = GET_BAN_MAP_XY(s1, s2 + 16);
|
|
below = GET_BAN_MAP_XY(s1 + 8, s2 + 16);
|
|
below_right = GET_BAN_MAP_XY(s1 + 15, s2 + 16);
|
|
|
|
if (below == BAN_ICE) {
|
|
if (player[c1].x_add > 0)
|
|
player[c1].x_add -= 1024;
|
|
else
|
|
player[c1].x_add -= 768;
|
|
} else if ((below_left != BAN_SOLID && below_right == BAN_ICE) || (below_left == BAN_ICE && below_right != BAN_SOLID)) {
|
|
if (player[c1].x_add > 0)
|
|
player[c1].x_add -= 1024;
|
|
else
|
|
player[c1].x_add -= 768;
|
|
} else {
|
|
if (player[c1].x_add > 0) {
|
|
player[c1].x_add -= 16384;
|
|
if (player[c1].x_add > -98304L && player[c1].in_water == 0 && below == BAN_SOLID)
|
|
add_object(OBJ_SMOKE, (player[c1].x >> 16) + 2 + rnd(9), (player[c1].y >> 16) + 13 + rnd(5), 0, -16384 - rnd(8192), OBJ_ANIM_SMOKE, 0);
|
|
} else
|
|
player[c1].x_add -= 12288;
|
|
}
|
|
if (player[c1].x_add < -98304L)
|
|
player[c1].x_add = -98304L;
|
|
player[c1].direction = 1;
|
|
if (player[c1].anim == 0) {
|
|
player[c1].anim = 1;
|
|
player[c1].frame = 0;
|
|
player[c1].frame_tick = 0;
|
|
player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
|
|
}
|
|
}
|
|
|
|
|
|
static void player_action_right(int c1)
|
|
{
|
|
int s1 = 0, s2 = 0;
|
|
int below_left, below, below_right;
|
|
|
|
s1 = (player[c1].x >> 16);
|
|
s2 = (player[c1].y >> 16);
|
|
below_left = GET_BAN_MAP_XY(s1, s2 + 16);
|
|
below = GET_BAN_MAP_XY(s1 + 8, s2 + 16);
|
|
below_right = GET_BAN_MAP_XY(s1 + 15, s2 + 16);
|
|
|
|
if (below == BAN_ICE) {
|
|
if (player[c1].x_add < 0)
|
|
player[c1].x_add += 1024;
|
|
else
|
|
player[c1].x_add += 768;
|
|
} else if ((below_left != BAN_SOLID && below_right == BAN_ICE) || (below_left == BAN_ICE && below_right != BAN_SOLID)) {
|
|
if (player[c1].x_add > 0)
|
|
player[c1].x_add += 1024;
|
|
else
|
|
player[c1].x_add += 768;
|
|
} else {
|
|
if (player[c1].x_add < 0) {
|
|
player[c1].x_add += 16384;
|
|
if (player[c1].x_add < 98304L && player[c1].in_water == 0 && below == BAN_SOLID)
|
|
add_object(OBJ_SMOKE, (player[c1].x >> 16) + 2 + rnd(9), (player[c1].y >> 16) + 13 + rnd(5), 0, -16384 - rnd(8192), OBJ_ANIM_SMOKE, 0);
|
|
} else
|
|
player[c1].x_add += 12288;
|
|
}
|
|
if (player[c1].x_add > 98304L)
|
|
player[c1].x_add = 98304L;
|
|
player[c1].direction = 0;
|
|
if (player[c1].anim == 0) {
|
|
player[c1].anim = 1;
|
|
player[c1].frame = 0;
|
|
player[c1].frame_tick = 0;
|
|
player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
|
|
}
|
|
}
|
|
|
|
int map_tile(int pos_x, int pos_y)
|
|
{
|
|
int tile;
|
|
|
|
pos_x = pos_x >> 4;
|
|
pos_y = pos_y >> 4;
|
|
|
|
if(pos_x < 0 || pos_x >= 17 || pos_y < 0 || pos_y >= 22)
|
|
return BAN_VOID;
|
|
|
|
tile = ban_map[pos_y][pos_x];
|
|
return tile;
|
|
}
|
|
|
|
void cpu_move(void)
|
|
{
|
|
int lm, rm, jm;
|
|
int i, j;
|
|
int cur_posx, cur_posy, tar_posx, tar_posy;
|
|
int players_distance;
|
|
player_t* target = NULL;
|
|
int nearest_distance = -1;
|
|
|
|
for (i = 0; i < JNB_MAX_PLAYERS; i++)
|
|
{
|
|
nearest_distance = -1;
|
|
if(ai[i] && player[i].enabled) // this player is a computer
|
|
{ // get nearest target
|
|
for (j = 0; j < JNB_MAX_PLAYERS; j++)
|
|
{
|
|
int deltax, deltay;
|
|
|
|
if(i == j || !player[j].enabled)
|
|
continue;
|
|
|
|
deltax = player[j].x - player[i].x;
|
|
deltay = player[j].y - player[i].y;
|
|
players_distance = deltax*deltax + deltay*deltay;
|
|
|
|
if (players_distance < nearest_distance || nearest_distance == -1)
|
|
{
|
|
target = &player[j];
|
|
nearest_distance = players_distance;
|
|
}
|
|
}
|
|
|
|
if(target == NULL)
|
|
continue;
|
|
|
|
cur_posx = player[i].x >> 16;
|
|
cur_posy = player[i].y >> 16;
|
|
tar_posx = target->x >> 16;
|
|
tar_posy = target->y >> 16;
|
|
|
|
/** nearest player found, get him */
|
|
/* here goes the artificial intelligence code */
|
|
|
|
/* X-axis movement */
|
|
if(tar_posx > cur_posx) // if true target is on the right side
|
|
{ // go after him
|
|
lm=0;
|
|
rm=1;
|
|
}
|
|
else // target on the left side
|
|
{
|
|
lm=1;
|
|
rm=0;
|
|
}
|
|
|
|
if(cur_posy - tar_posy < 32 && cur_posy - tar_posy > 0 &&
|
|
tar_posx - cur_posx < 32+8 && tar_posx - cur_posx > -32)
|
|
{
|
|
lm = !lm;
|
|
rm = !rm;
|
|
}
|
|
else if(tar_posx - cur_posx < 4+8 && tar_posx - cur_posx > -4)
|
|
{ // makes the bunnies less "nervous"
|
|
lm=0;
|
|
lm=0;
|
|
}
|
|
|
|
/* Y-axis movement */
|
|
if(map_tile(cur_posx, cur_posy+16) != BAN_VOID &&
|
|
((i == 0 && key_pressed(KEY_PL1_JUMP)) ||
|
|
(i == 1 && key_pressed(KEY_PL2_JUMP)) ||
|
|
(i == 2 && key_pressed(KEY_PL3_JUMP)) ||
|
|
(i == 3 && key_pressed(KEY_PL4_JUMP))))
|
|
jm=0; // if we are on ground and jump key is being pressed,
|
|
//first we have to release it or else we won't be able to jump more than once
|
|
|
|
else if(map_tile(cur_posx, cur_posy-8) != BAN_VOID &&
|
|
map_tile(cur_posx, cur_posy-8) != BAN_WATER)
|
|
jm=0; // don't jump if there is something over it
|
|
|
|
else if(map_tile(cur_posx-(lm*8)+(rm*16), cur_posy) != BAN_VOID &&
|
|
map_tile(cur_posx-(lm*8)+(rm*16), cur_posy) != BAN_WATER &&
|
|
cur_posx > 16 && cur_posx < 352-16-8) // obstacle, jump
|
|
jm=1; // if there is something on the way, jump over it
|
|
|
|
else if(((i == 0 && key_pressed(KEY_PL1_JUMP)) ||
|
|
(i == 1 && key_pressed(KEY_PL2_JUMP)) ||
|
|
(i == 2 && key_pressed(KEY_PL3_JUMP)) ||
|
|
(i == 3 && key_pressed(KEY_PL4_JUMP))) &&
|
|
(map_tile(cur_posx-(lm*8)+(rm*16), cur_posy+8) != BAN_VOID &&
|
|
map_tile(cur_posx-(lm*8)+(rm*16), cur_posy+8) != BAN_WATER))
|
|
jm=1; // this makes it possible to jump over 2 tiles
|
|
|
|
else if(cur_posy - tar_posy < 32 && cur_posy - tar_posy > 0 &&
|
|
tar_posx - cur_posx < 32+8 && tar_posx - cur_posx > -32) // don't jump - running away
|
|
jm=0;
|
|
|
|
else if(tar_posy <= cur_posy) // target on the upper side
|
|
jm=1;
|
|
else // target below
|
|
jm=0;
|
|
|
|
/** Artificial intelligence done, now apply movements */
|
|
addkey(((KEY_PL1_LEFT + 0x10 * i) & 0x7fff) | (lm ? 0x0 : 0x8000));
|
|
addkey(((KEY_PL1_RIGHT + 0x10 * i) & 0x7fff) | (rm ? 0x0 : 0x8000));
|
|
addkey(((KEY_PL1_JUMP + 0x10 * i) & 0x7fff) | (jm ? 0x0 : 0x8000));
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
#define GET_BAN_MAP_IN_WATER(s1, s2) (GET_BAN_MAP_XY((s1), ((s2) + 7)) == BAN_VOID || GET_BAN_MAP_XY(((s1) + 15), ((s2) + 7)) == BAN_VOID) && (GET_BAN_MAP_XY((s1), ((s2) + 8)) == BAN_WATER || GET_BAN_MAP_XY(((s1) + 15), ((s2) + 8)) == BAN_WATER)
|
|
|
|
|
|
void steer_players(void)
|
|
{
|
|
int c1, c2;
|
|
int s1 = 0, s2 = 0;
|
|
|
|
cpu_move();
|
|
update_player_actions();
|
|
|
|
for (c1 = 0; c1 < JNB_MAX_PLAYERS; c1++) {
|
|
|
|
if (player[c1].enabled == 1) {
|
|
|
|
if (player[c1].dead_flag == 0) {
|
|
|
|
if (player[c1].action_left && player[c1].action_right) {
|
|
if (player[c1].direction == 0) {
|
|
if (player[c1].action_right) {
|
|
player_action_right(c1);
|
|
}
|
|
} else {
|
|
if (player[c1].action_left) {
|
|
player_action_left(c1);
|
|
}
|
|
}
|
|
} else if (player[c1].action_left) {
|
|
player_action_left(c1);
|
|
} else if (player[c1].action_right) {
|
|
player_action_right(c1);
|
|
} else if ((!player[c1].action_left) && (!player[c1].action_right)) {
|
|
int below_left, below, below_right;
|
|
|
|
s1 = (player[c1].x >> 16);
|
|
s2 = (player[c1].y >> 16);
|
|
below_left = GET_BAN_MAP_XY(s1, s2 + 16);
|
|
below = GET_BAN_MAP_XY(s1 + 8, s2 + 16);
|
|
below_right = GET_BAN_MAP_XY(s1 + 15, s2 + 16);
|
|
if (below == BAN_SOLID || below == BAN_SPRING || (((below_left == BAN_SOLID || below_left == BAN_SPRING) && below_right != BAN_ICE) || (below_left != BAN_ICE && (below_right == BAN_SOLID || below_right == BAN_SPRING)))) {
|
|
if (player[c1].x_add < 0) {
|
|
player[c1].x_add += 16384;
|
|
if (player[c1].x_add > 0)
|
|
player[c1].x_add = 0;
|
|
} else {
|
|
player[c1].x_add -= 16384;
|
|
if (player[c1].x_add < 0)
|
|
player[c1].x_add = 0;
|
|
}
|
|
if (player[c1].x_add != 0 && GET_BAN_MAP_XY((s1 + 8), (s2 + 16)) == BAN_SOLID)
|
|
add_object(OBJ_SMOKE, (player[c1].x >> 16) + 2 + rnd(9), (player[c1].y >> 16) + 13 + rnd(5), 0, -16384 - rnd(8192), OBJ_ANIM_SMOKE, 0);
|
|
}
|
|
if (player[c1].anim == 1) {
|
|
player[c1].anim = 0;
|
|
player[c1].frame = 0;
|
|
player[c1].frame_tick = 0;
|
|
player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
|
|
}
|
|
}
|
|
if (jetpack == 0) {
|
|
/* no jetpack */
|
|
if (pogostick == 1 || (player[c1].jump_ready == 1 && player[c1].action_up)) {
|
|
s1 = (player[c1].x >> 16);
|
|
s2 = (player[c1].y >> 16);
|
|
if (s2 < -16)
|
|
s2 = -16;
|
|
/* jump */
|
|
if (GET_BAN_MAP_XY(s1, (s2 + 16)) == BAN_SOLID || GET_BAN_MAP_XY(s1, (s2 + 16)) == BAN_ICE || GET_BAN_MAP_XY((s1 + 15), (s2 + 16)) == BAN_SOLID || GET_BAN_MAP_XY((s1 + 15), (s2 + 16)) == BAN_ICE) {
|
|
player[c1].y_add = -280000L;
|
|
player[c1].anim = 2;
|
|
player[c1].frame = 0;
|
|
player[c1].frame_tick = 0;
|
|
player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
|
|
player[c1].jump_ready = 0;
|
|
player[c1].jump_abort = 1;
|
|
if (pogostick == 0)
|
|
dj_play_sfx(SFX_JUMP, (unsigned short)(SFX_JUMP_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
|
|
else
|
|
dj_play_sfx(SFX_SPRING, (unsigned short)(SFX_SPRING_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
|
|
}
|
|
/* jump out of water */
|
|
if (GET_BAN_MAP_IN_WATER(s1, s2)) {
|
|
player[c1].y_add = -196608L;
|
|
player[c1].in_water = 0;
|
|
player[c1].anim = 2;
|
|
player[c1].frame = 0;
|
|
player[c1].frame_tick = 0;
|
|
player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
|
|
player[c1].jump_ready = 0;
|
|
player[c1].jump_abort = 1;
|
|
if (pogostick == 0)
|
|
dj_play_sfx(SFX_JUMP, (unsigned short)(SFX_JUMP_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
|
|
else
|
|
dj_play_sfx(SFX_SPRING, (unsigned short)(SFX_SPRING_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
|
|
}
|
|
}
|
|
/* fall down by gravity */
|
|
if (pogostick == 0 && (!player[c1].action_up)) {
|
|
player[c1].jump_ready = 1;
|
|
if (player[c1].in_water == 0 && player[c1].y_add < 0 && player[c1].jump_abort == 1) {
|
|
if (bunnies_in_space == 0)
|
|
/* normal gravity */
|
|
player[c1].y_add += 32768;
|
|
else
|
|
/* light gravity */
|
|
player[c1].y_add += 16384;
|
|
if (player[c1].y_add > 0)
|
|
player[c1].y_add = 0;
|
|
}
|
|
}
|
|
} else {
|
|
/* with jetpack */
|
|
if (player[c1].action_up) {
|
|
player[c1].y_add -= 16384;
|
|
if (player[c1].y_add < -400000L)
|
|
player[c1].y_add = -400000L;
|
|
if (GET_BAN_MAP_IN_WATER(s1, s2))
|
|
player[c1].in_water = 0;
|
|
if (rnd(100) < 50)
|
|
add_object(OBJ_SMOKE, (player[c1].x >> 16) + 6 + rnd(5), (player[c1].y >> 16) + 10 + rnd(5), 0, 16384 + rnd(8192), OBJ_ANIM_SMOKE, 0);
|
|
}
|
|
}
|
|
|
|
player[c1].x += player[c1].x_add;
|
|
if ((player[c1].x >> 16) < 0) {
|
|
player[c1].x = 0;
|
|
player[c1].x_add = 0;
|
|
}
|
|
if ((player[c1].x >> 16) + 15 > 351) {
|
|
player[c1].x = 336L << 16;
|
|
player[c1].x_add = 0;
|
|
}
|
|
{
|
|
if (player[c1].y > 0) {
|
|
s2 = (player[c1].y >> 16);
|
|
} else {
|
|
/* check top line only */
|
|
s2 = 0;
|
|
}
|
|
|
|
s1 = (player[c1].x >> 16);
|
|
if (GET_BAN_MAP_XY(s1, s2) == BAN_SOLID || GET_BAN_MAP_XY(s1, s2) == BAN_ICE || GET_BAN_MAP_XY(s1, s2) == BAN_SPRING || GET_BAN_MAP_XY(s1, (s2 + 15)) == BAN_SOLID || GET_BAN_MAP_XY(s1, (s2 + 15)) == BAN_ICE || GET_BAN_MAP_XY(s1, (s2 + 15)) == BAN_SPRING) {
|
|
player[c1].x = (((s1 + 16) & 0xfff0)) << 16;
|
|
player[c1].x_add = 0;
|
|
}
|
|
|
|
s1 = (player[c1].x >> 16);
|
|
if (GET_BAN_MAP_XY((s1 + 15), s2) == BAN_SOLID || GET_BAN_MAP_XY((s1 + 15), s2) == BAN_ICE || GET_BAN_MAP_XY((s1 + 15), s2) == BAN_SPRING || GET_BAN_MAP_XY((s1 + 15), (s2 + 15)) == BAN_SOLID || GET_BAN_MAP_XY((s1 + 15), (s2 + 15)) == BAN_ICE || GET_BAN_MAP_XY((s1 + 15), (s2 + 15)) == BAN_SPRING) {
|
|
player[c1].x = (((s1 + 16) & 0xfff0) - 16) << 16;
|
|
player[c1].x_add = 0;
|
|
}
|
|
}
|
|
|
|
player[c1].y += player[c1].y_add;
|
|
|
|
s1 = (player[c1].x >> 16);
|
|
s2 = (player[c1].y >> 16);
|
|
if (s2 < 0)
|
|
s2 = 0;
|
|
if (GET_BAN_MAP_XY((s1 + 8), (s2 + 15)) == BAN_SPRING || ((GET_BAN_MAP_XY(s1, (s2 + 15)) == BAN_SPRING && GET_BAN_MAP_XY((s1 + 15), (s2 + 15)) != BAN_SOLID) || (GET_BAN_MAP_XY(s1, (s2 + 15)) != BAN_SOLID && GET_BAN_MAP_XY((s1 + 15), (s2 + 15)) == BAN_SPRING))) {
|
|
player[c1].y = ((player[c1].y >> 16) & 0xfff0) << 16;
|
|
player[c1].y_add = -400000L;
|
|
player[c1].anim = 2;
|
|
player[c1].frame = 0;
|
|
player[c1].frame_tick = 0;
|
|
player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
|
|
player[c1].jump_ready = 0;
|
|
player[c1].jump_abort = 0;
|
|
for (c2 = 0; c2 < NUM_OBJECTS; c2++) {
|
|
if (objects[c2].used == 1 && objects[c2].type == OBJ_SPRING) {
|
|
if (GET_BAN_MAP_XY((s1 + 8), (s2 + 15)) == BAN_SPRING) {
|
|
if ((objects[c2].x >> 20) == ((s1 + 8) >> 4) && (objects[c2].y >> 20) == ((s2 + 15) >> 4)) {
|
|
objects[c2].frame = 0;
|
|
objects[c2].ticks = object_anims[objects[c2].anim].frame[objects[c2].frame].ticks;
|
|
objects[c2].image = object_anims[objects[c2].anim].frame[objects[c2].frame].image;
|
|
break;
|
|
}
|
|
} else {
|
|
if (GET_BAN_MAP_XY(s1, (s2 + 15)) == BAN_SPRING) {
|
|
if ((objects[c2].x >> 20) == (s1 >> 4) && (objects[c2].y >> 20) == ((s2 + 15) >> 4)) {
|
|
objects[c2].frame = 0;
|
|
objects[c2].ticks = object_anims[objects[c2].anim].frame[objects[c2].frame].ticks;
|
|
objects[c2].image = object_anims[objects[c2].anim].frame[objects[c2].frame].image;
|
|
break;
|
|
}
|
|
} else if (GET_BAN_MAP_XY((s1 + 15), (s2 + 15)) == BAN_SPRING) {
|
|
if ((objects[c2].x >> 20) == ((s1 + 15) >> 4) && (objects[c2].y >> 20) == ((s2 + 15) >> 4)) {
|
|
objects[c2].frame = 0;
|
|
objects[c2].ticks = object_anims[objects[c2].anim].frame[objects[c2].frame].ticks;
|
|
objects[c2].image = object_anims[objects[c2].anim].frame[objects[c2].frame].image;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
dj_play_sfx(SFX_SPRING, (unsigned short)(SFX_SPRING_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
|
|
}
|
|
s1 = (player[c1].x >> 16);
|
|
s2 = (player[c1].y >> 16);
|
|
if (s2 < 0)
|
|
s2 = 0;
|
|
if (GET_BAN_MAP_XY(s1, s2) == BAN_SOLID || GET_BAN_MAP_XY(s1, s2) == BAN_ICE || GET_BAN_MAP_XY(s1, s2) == BAN_SPRING || GET_BAN_MAP_XY((s1 + 15), s2) == BAN_SOLID || GET_BAN_MAP_XY((s1 + 15), s2) == BAN_ICE || GET_BAN_MAP_XY((s1 + 15), s2) == BAN_SPRING) {
|
|
player[c1].y = (((s2 + 16) & 0xfff0)) << 16;
|
|
player[c1].y_add = 0;
|
|
player[c1].anim = 0;
|
|
player[c1].frame = 0;
|
|
player[c1].frame_tick = 0;
|
|
player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
|
|
}
|
|
s1 = (player[c1].x >> 16);
|
|
s2 = (player[c1].y >> 16);
|
|
if (s2 < 0)
|
|
s2 = 0;
|
|
if (GET_BAN_MAP_XY((s1 + 8), (s2 + 8)) == BAN_WATER) {
|
|
if (player[c1].in_water == 0) {
|
|
/* falling into water */
|
|
player[c1].in_water = 1;
|
|
player[c1].anim = 4;
|
|
player[c1].frame = 0;
|
|
player[c1].frame_tick = 0;
|
|
player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
|
|
if (player[c1].y_add >= 32768) {
|
|
add_object(OBJ_SPLASH, (player[c1].x >> 16) + 8, ((player[c1].y >> 16) & 0xfff0) + 15, 0, 0, OBJ_ANIM_SPLASH, 0);
|
|
if (blood_is_thicker_than_water == 0)
|
|
dj_play_sfx(SFX_SPLASH, (unsigned short)(SFX_SPLASH_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
|
|
else
|
|
dj_play_sfx(SFX_SPLASH, (unsigned short)(SFX_SPLASH_FREQ + rnd(2000) - 5000), 64, 0, 0, -1);
|
|
}
|
|
}
|
|
/* slowly move up to water surface */
|
|
player[c1].y_add -= 1536;
|
|
if (player[c1].y_add < 0 && player[c1].anim != 5) {
|
|
player[c1].anim = 5;
|
|
player[c1].frame = 0;
|
|
player[c1].frame_tick = 0;
|
|
player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
|
|
}
|
|
if (player[c1].y_add < -65536L)
|
|
player[c1].y_add = -65536L;
|
|
if (player[c1].y_add > 65535L)
|
|
player[c1].y_add = 65535L;
|
|
if (GET_BAN_MAP_XY(s1, (s2 + 15)) == BAN_SOLID || GET_BAN_MAP_XY(s1, (s2 + 15)) == BAN_ICE || GET_BAN_MAP_XY((s1 + 15), (s2 + 15)) == BAN_SOLID || GET_BAN_MAP_XY((s1 + 15), (s2 + 15)) == BAN_ICE) {
|
|
player[c1].y = (((s2 + 16) & 0xfff0) - 16) << 16;
|
|
player[c1].y_add = 0;
|
|
}
|
|
} else if (GET_BAN_MAP_XY(s1, (s2 + 15)) == BAN_SOLID || GET_BAN_MAP_XY(s1, (s2 + 15)) == BAN_ICE || GET_BAN_MAP_XY(s1, (s2 + 15)) == BAN_SPRING || GET_BAN_MAP_XY((s1 + 15), (s2 + 15)) == BAN_SOLID || GET_BAN_MAP_XY((s1 + 15), (s2 + 15)) == BAN_ICE || GET_BAN_MAP_XY((s1 + 15), (s2 + 15)) == BAN_SPRING) {
|
|
player[c1].in_water = 0;
|
|
player[c1].y = (((s2 + 16) & 0xfff0) - 16) << 16;
|
|
player[c1].y_add = 0;
|
|
if (player[c1].anim != 0 && player[c1].anim != 1) {
|
|
player[c1].anim = 0;
|
|
player[c1].frame = 0;
|
|
player[c1].frame_tick = 0;
|
|
player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
|
|
}
|
|
} else {
|
|
if (player[c1].in_water == 0) {
|
|
if (bunnies_in_space == 0)
|
|
player[c1].y_add += 12288;
|
|
else
|
|
player[c1].y_add += 6144;
|
|
if (player[c1].y_add > 327680L)
|
|
player[c1].y_add = 327680L;
|
|
} else {
|
|
player[c1].y = (player[c1].y & 0xffff0000) + 0x10000;
|
|
player[c1].y_add = 0;
|
|
}
|
|
player[c1].in_water = 0;
|
|
}
|
|
if (player[c1].y_add > 36864 && player[c1].anim != 3 && player[c1].in_water == 0) {
|
|
player[c1].anim = 3;
|
|
player[c1].frame = 0;
|
|
player[c1].frame_tick = 0;
|
|
player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
|
|
}
|
|
|
|
}
|
|
|
|
player[c1].frame_tick++;
|
|
if (player[c1].frame_tick >= player_anims[player[c1].anim].frame[player[c1].frame].ticks) {
|
|
player[c1].frame++;
|
|
if (player[c1].frame >= player_anims[player[c1].anim].num_frames) {
|
|
if (player[c1].anim != 6)
|
|
player[c1].frame = player_anims[player[c1].anim].restart_frame;
|
|
else
|
|
position_player(c1);
|
|
}
|
|
player[c1].frame_tick = 0;
|
|
}
|
|
player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
void position_player(int player_num)
|
|
{
|
|
int c1;
|
|
int s1, s2;
|
|
|
|
while (1) {
|
|
while (1) {
|
|
s1 = rnd(22);
|
|
s2 = rnd(16);
|
|
if (ban_map[s2][s1] == BAN_VOID && (ban_map[s2 + 1][s1] == BAN_SOLID || ban_map[s2 + 1][s1] == BAN_ICE))
|
|
break;
|
|
}
|
|
for (c1 = 0; c1 < JNB_MAX_PLAYERS; c1++) {
|
|
if (c1 != player_num && player[c1].enabled == 1) {
|
|
if (abs((s1 << 4) - (player[c1].x >> 16)) < 32 && abs((s2 << 4) - (player[c1].y >> 16)) < 32)
|
|
break;
|
|
}
|
|
}
|
|
if (c1 == JNB_MAX_PLAYERS) {
|
|
player[player_num].x = (long) s1 << 20;
|
|
player[player_num].y = (long) s2 << 20;
|
|
player[player_num].x_add = player[player_num].y_add = 0;
|
|
player[player_num].direction = 0;
|
|
player[player_num].jump_ready = 1;
|
|
player[player_num].in_water = 0;
|
|
player[player_num].anim = 0;
|
|
player[player_num].frame = 0;
|
|
player[player_num].frame_tick = 0;
|
|
player[player_num].image = player_anims[player[player_num].anim].frame[player[player_num].frame].image;
|
|
|
|
if (is_server) {
|
|
player[player_num].dead_flag = 0;
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
void update_objects(void)
|
|
{
|
|
int c1;
|
|
int s1 = 0;
|
|
|
|
for (c1 = 0; c1 < NUM_OBJECTS; c1++) {
|
|
if (objects[c1].used == 1) {
|
|
switch (objects[c1].type) {
|
|
case OBJ_SPRING:
|
|
objects[c1].ticks--;
|
|
if (objects[c1].ticks <= 0) {
|
|
objects[c1].frame++;
|
|
if (objects[c1].frame >= object_anims[objects[c1].anim].num_frames) {
|
|
objects[c1].frame--;
|
|
objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
|
|
} else {
|
|
objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
|
|
objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
|
|
}
|
|
}
|
|
if (objects[c1].used == 1)
|
|
add_pob(main_info.draw_page, objects[c1].x >> 16, objects[c1].y >> 16, objects[c1].image, &object_gobs);
|
|
break;
|
|
case OBJ_SPLASH:
|
|
objects[c1].ticks--;
|
|
if (objects[c1].ticks <= 0) {
|
|
objects[c1].frame++;
|
|
if (objects[c1].frame >= object_anims[objects[c1].anim].num_frames)
|
|
objects[c1].used = 0;
|
|
else {
|
|
objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
|
|
objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
|
|
}
|
|
}
|
|
if (objects[c1].used == 1)
|
|
add_pob(main_info.draw_page, objects[c1].x >> 16, objects[c1].y >> 16, objects[c1].image, &object_gobs);
|
|
break;
|
|
case OBJ_SMOKE:
|
|
objects[c1].x += objects[c1].x_add;
|
|
objects[c1].y += objects[c1].y_add;
|
|
objects[c1].ticks--;
|
|
if (objects[c1].ticks <= 0) {
|
|
objects[c1].frame++;
|
|
if (objects[c1].frame >= object_anims[objects[c1].anim].num_frames)
|
|
objects[c1].used = 0;
|
|
else {
|
|
objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
|
|
objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
|
|
}
|
|
}
|
|
if (objects[c1].used == 1)
|
|
add_pob(main_info.draw_page, objects[c1].x >> 16, objects[c1].y >> 16, objects[c1].image, &object_gobs);
|
|
break;
|
|
case OBJ_YEL_BUTFLY:
|
|
case OBJ_PINK_BUTFLY:
|
|
objects[c1].x_acc += rnd(128) - 64;
|
|
if (objects[c1].x_acc < -1024)
|
|
objects[c1].x_acc = -1024;
|
|
if (objects[c1].x_acc > 1024)
|
|
objects[c1].x_acc = 1024;
|
|
objects[c1].x_add += objects[c1].x_acc;
|
|
if (objects[c1].x_add < -32768)
|
|
objects[c1].x_add = -32768;
|
|
if (objects[c1].x_add > 32768)
|
|
objects[c1].x_add = 32768;
|
|
objects[c1].x += objects[c1].x_add;
|
|
if ((objects[c1].x >> 16) < 16) {
|
|
objects[c1].x = 16 << 16;
|
|
objects[c1].x_add = -objects[c1].x_add >> 2;
|
|
objects[c1].x_acc = 0;
|
|
} else if ((objects[c1].x >> 16) > 350) {
|
|
objects[c1].x = 350 << 16;
|
|
objects[c1].x_add = -objects[c1].x_add >> 2;
|
|
objects[c1].x_acc = 0;
|
|
}
|
|
if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] != 0) {
|
|
if (objects[c1].x_add < 0) {
|
|
objects[c1].x = (((objects[c1].x >> 16) + 16) & 0xfff0) << 16;
|
|
} else {
|
|
objects[c1].x = ((((objects[c1].x >> 16) - 16) & 0xfff0) + 15) << 16;
|
|
}
|
|
objects[c1].x_add = -objects[c1].x_add >> 2;
|
|
objects[c1].x_acc = 0;
|
|
}
|
|
objects[c1].y_acc += rnd(64) - 32;
|
|
if (objects[c1].y_acc < -1024)
|
|
objects[c1].y_acc = -1024;
|
|
if (objects[c1].y_acc > 1024)
|
|
objects[c1].y_acc = 1024;
|
|
objects[c1].y_add += objects[c1].y_acc;
|
|
if (objects[c1].y_add < -32768)
|
|
objects[c1].y_add = -32768;
|
|
if (objects[c1].y_add > 32768)
|
|
objects[c1].y_add = 32768;
|
|
objects[c1].y += objects[c1].y_add;
|
|
if ((objects[c1].y >> 16) < 0) {
|
|
objects[c1].y = 0;
|
|
objects[c1].y_add = -objects[c1].y_add >> 2;
|
|
objects[c1].y_acc = 0;
|
|
} else if ((objects[c1].y >> 16) > 255) {
|
|
objects[c1].y = 255 << 16;
|
|
objects[c1].y_add = -objects[c1].y_add >> 2;
|
|
objects[c1].y_acc = 0;
|
|
}
|
|
if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] != 0) {
|
|
if (objects[c1].y_add < 0) {
|
|
objects[c1].y = (((objects[c1].y >> 16) + 16) & 0xfff0) << 16;
|
|
} else {
|
|
objects[c1].y = ((((objects[c1].y >> 16) - 16) & 0xfff0) + 15) << 16;
|
|
}
|
|
objects[c1].y_add = -objects[c1].y_add >> 2;
|
|
objects[c1].y_acc = 0;
|
|
}
|
|
if (objects[c1].type == OBJ_YEL_BUTFLY) {
|
|
if (objects[c1].x_add < 0 && objects[c1].anim != OBJ_ANIM_YEL_BUTFLY_LEFT) {
|
|
objects[c1].anim = OBJ_ANIM_YEL_BUTFLY_LEFT;
|
|
objects[c1].frame = 0;
|
|
objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
|
|
objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
|
|
} else if (objects[c1].x_add > 0 && objects[c1].anim != OBJ_ANIM_YEL_BUTFLY_RIGHT) {
|
|
objects[c1].anim = OBJ_ANIM_YEL_BUTFLY_RIGHT;
|
|
objects[c1].frame = 0;
|
|
objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
|
|
objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
|
|
}
|
|
} else {
|
|
if (objects[c1].x_add < 0 && objects[c1].anim != OBJ_ANIM_PINK_BUTFLY_LEFT) {
|
|
objects[c1].anim = OBJ_ANIM_PINK_BUTFLY_LEFT;
|
|
objects[c1].frame = 0;
|
|
objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
|
|
objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
|
|
} else if (objects[c1].x_add > 0 && objects[c1].anim != OBJ_ANIM_PINK_BUTFLY_RIGHT) {
|
|
objects[c1].anim = OBJ_ANIM_PINK_BUTFLY_RIGHT;
|
|
objects[c1].frame = 0;
|
|
objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
|
|
objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
|
|
}
|
|
}
|
|
objects[c1].ticks--;
|
|
if (objects[c1].ticks <= 0) {
|
|
objects[c1].frame++;
|
|
if (objects[c1].frame >= object_anims[objects[c1].anim].num_frames)
|
|
objects[c1].frame = object_anims[objects[c1].anim].restart_frame;
|
|
else {
|
|
objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
|
|
objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
|
|
}
|
|
}
|
|
if (objects[c1].used == 1)
|
|
add_pob(main_info.draw_page, objects[c1].x >> 16, objects[c1].y >> 16, objects[c1].image, &object_gobs);
|
|
break;
|
|
case OBJ_FUR:
|
|
if (rnd(100) < 30)
|
|
add_object(OBJ_FLESH_TRACE, objects[c1].x >> 16, objects[c1].y >> 16, 0, 0, OBJ_ANIM_FLESH_TRACE, 0);
|
|
if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 0) {
|
|
objects[c1].y_add += 3072;
|
|
if (objects[c1].y_add > 196608L)
|
|
objects[c1].y_add = 196608L;
|
|
} else if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 2) {
|
|
if (objects[c1].x_add < 0) {
|
|
if (objects[c1].x_add < -65536L)
|
|
objects[c1].x_add = -65536L;
|
|
objects[c1].x_add += 1024;
|
|
if (objects[c1].x_add > 0)
|
|
objects[c1].x_add = 0;
|
|
} else {
|
|
if (objects[c1].x_add > 65536L)
|
|
objects[c1].x_add = 65536L;
|
|
objects[c1].x_add -= 1024;
|
|
if (objects[c1].x_add < 0)
|
|
objects[c1].x_add = 0;
|
|
}
|
|
objects[c1].y_add += 1024;
|
|
if (objects[c1].y_add < -65536L)
|
|
objects[c1].y_add = -65536L;
|
|
if (objects[c1].y_add > 65536L)
|
|
objects[c1].y_add = 65536L;
|
|
}
|
|
objects[c1].x += objects[c1].x_add;
|
|
if ((objects[c1].y >> 16) > 0 && (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 1 || ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 3)) {
|
|
if (objects[c1].x_add < 0) {
|
|
objects[c1].x = (((objects[c1].x >> 16) + 16) & 0xfff0) << 16;
|
|
objects[c1].x_add = -objects[c1].x_add >> 2;
|
|
} else {
|
|
objects[c1].x = ((((objects[c1].x >> 16) - 16) & 0xfff0) + 15) << 16;
|
|
objects[c1].x_add = -objects[c1].x_add >> 2;
|
|
}
|
|
}
|
|
objects[c1].y += objects[c1].y_add;
|
|
if ((objects[c1].x >> 16) < -5 || (objects[c1].x >> 16) > 405 || (objects[c1].y >> 16) > 260)
|
|
objects[c1].used = 0;
|
|
if ((objects[c1].y >> 16) > 0 && (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] != 0)) {
|
|
if (objects[c1].y_add < 0) {
|
|
if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] != 2) {
|
|
objects[c1].y = (((objects[c1].y >> 16) + 16) & 0xfff0) << 16;
|
|
objects[c1].x_add >>= 2;
|
|
objects[c1].y_add = -objects[c1].y_add >> 2;
|
|
}
|
|
} else {
|
|
if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 1) {
|
|
if (objects[c1].y_add > 131072L) {
|
|
objects[c1].y = ((((objects[c1].y >> 16) - 16) & 0xfff0) + 15) << 16;
|
|
objects[c1].x_add >>= 2;
|
|
objects[c1].y_add = -objects[c1].y_add >> 2;
|
|
} else
|
|
objects[c1].used = 0;
|
|
} else if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 3) {
|
|
objects[c1].y = ((((objects[c1].y >> 16) - 16) & 0xfff0) + 15) << 16;
|
|
if (objects[c1].y_add > 131072L)
|
|
objects[c1].y_add = -objects[c1].y_add >> 2;
|
|
else
|
|
objects[c1].y_add = 0;
|
|
}
|
|
}
|
|
}
|
|
if (objects[c1].x_add < 0 && objects[c1].x_add > -16384)
|
|
objects[c1].x_add = -16384;
|
|
if (objects[c1].x_add > 0 && objects[c1].x_add < 16384)
|
|
objects[c1].x_add = 16384;
|
|
if (objects[c1].used == 1) {
|
|
s1 = (int)(atan2(objects[c1].y_add, objects[c1].x_add) * 4 / M_PI);
|
|
if (s1 < 0)
|
|
s1 += 8;
|
|
if (s1 < 0)
|
|
s1 = 0;
|
|
if (s1 > 7)
|
|
s1 = 7;
|
|
add_pob(main_info.draw_page, objects[c1].x >> 16, objects[c1].y >> 16, objects[c1].frame + s1, &object_gobs);
|
|
}
|
|
break;
|
|
case OBJ_FLESH:
|
|
if (rnd(100) < 30) {
|
|
if (objects[c1].frame == 76)
|
|
add_object(OBJ_FLESH_TRACE, objects[c1].x >> 16, objects[c1].y >> 16, 0, 0, OBJ_ANIM_FLESH_TRACE, 1);
|
|
else if (objects[c1].frame == 77)
|
|
add_object(OBJ_FLESH_TRACE, objects[c1].x >> 16, objects[c1].y >> 16, 0, 0, OBJ_ANIM_FLESH_TRACE, 2);
|
|
else if (objects[c1].frame == 78)
|
|
add_object(OBJ_FLESH_TRACE, objects[c1].x >> 16, objects[c1].y >> 16, 0, 0, OBJ_ANIM_FLESH_TRACE, 3);
|
|
}
|
|
if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 0) {
|
|
objects[c1].y_add += 3072;
|
|
if (objects[c1].y_add > 196608L)
|
|
objects[c1].y_add = 196608L;
|
|
} else if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 2) {
|
|
if (objects[c1].x_add < 0) {
|
|
if (objects[c1].x_add < -65536L)
|
|
objects[c1].x_add = -65536L;
|
|
objects[c1].x_add += 1024;
|
|
if (objects[c1].x_add > 0)
|
|
objects[c1].x_add = 0;
|
|
} else {
|
|
if (objects[c1].x_add > 65536L)
|
|
objects[c1].x_add = 65536L;
|
|
objects[c1].x_add -= 1024;
|
|
if (objects[c1].x_add < 0)
|
|
objects[c1].x_add = 0;
|
|
}
|
|
objects[c1].y_add += 1024;
|
|
if (objects[c1].y_add < -65536L)
|
|
objects[c1].y_add = -65536L;
|
|
if (objects[c1].y_add > 65536L)
|
|
objects[c1].y_add = 65536L;
|
|
}
|
|
objects[c1].x += objects[c1].x_add;
|
|
if ((objects[c1].y >> 16) > 0 && (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 1 || ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 3)) {
|
|
if (objects[c1].x_add < 0) {
|
|
objects[c1].x = (((objects[c1].x >> 16) + 16) & 0xfff0) << 16;
|
|
objects[c1].x_add = -objects[c1].x_add >> 2;
|
|
} else {
|
|
objects[c1].x = ((((objects[c1].x >> 16) - 16) & 0xfff0) + 15) << 16;
|
|
objects[c1].x_add = -objects[c1].x_add >> 2;
|
|
}
|
|
}
|
|
objects[c1].y += objects[c1].y_add;
|
|
if ((objects[c1].x >> 16) < -5 || (objects[c1].x >> 16) > 405 || (objects[c1].y >> 16) > 260)
|
|
objects[c1].used = 0;
|
|
if ((objects[c1].y >> 16) > 0 && (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] != 0)) {
|
|
if (objects[c1].y_add < 0) {
|
|
if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] != 2) {
|
|
objects[c1].y = (((objects[c1].y >> 16) + 16) & 0xfff0) << 16;
|
|
objects[c1].x_add >>= 2;
|
|
objects[c1].y_add = -objects[c1].y_add >> 2;
|
|
}
|
|
} else {
|
|
if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 1) {
|
|
if (objects[c1].y_add > 131072L) {
|
|
objects[c1].y = ((((objects[c1].y >> 16) - 16) & 0xfff0) + 15) << 16;
|
|
objects[c1].x_add >>= 2;
|
|
objects[c1].y_add = -objects[c1].y_add >> 2;
|
|
} else {
|
|
if (rnd(100) < 10) {
|
|
s1 = rnd(4) - 2;
|
|
add_leftovers(0, objects[c1].x >> 16, (objects[c1].y >> 16) + s1, objects[c1].frame, &object_gobs);
|
|
add_leftovers(1, objects[c1].x >> 16, (objects[c1].y >> 16) + s1, objects[c1].frame, &object_gobs);
|
|
}
|
|
objects[c1].used = 0;
|
|
}
|
|
} else if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 3) {
|
|
objects[c1].y = ((((objects[c1].y >> 16) - 16) & 0xfff0) + 15) << 16;
|
|
if (objects[c1].y_add > 131072L)
|
|
objects[c1].y_add = -objects[c1].y_add >> 2;
|
|
else
|
|
objects[c1].y_add = 0;
|
|
}
|
|
}
|
|
}
|
|
if (objects[c1].x_add < 0 && objects[c1].x_add > -16384)
|
|
objects[c1].x_add = -16384;
|
|
if (objects[c1].x_add > 0 && objects[c1].x_add < 16384)
|
|
objects[c1].x_add = 16384;
|
|
if (objects[c1].used == 1)
|
|
add_pob(main_info.draw_page, objects[c1].x >> 16, objects[c1].y >> 16, objects[c1].frame, &object_gobs);
|
|
break;
|
|
case OBJ_FLESH_TRACE:
|
|
objects[c1].ticks--;
|
|
if (objects[c1].ticks <= 0) {
|
|
objects[c1].frame++;
|
|
if (objects[c1].frame >= object_anims[objects[c1].anim].num_frames)
|
|
objects[c1].used = 0;
|
|
else {
|
|
objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
|
|
objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
|
|
}
|
|
}
|
|
if (objects[c1].used == 1)
|
|
add_pob(main_info.draw_page, objects[c1].x >> 16, objects[c1].y >> 16, objects[c1].image, &object_gobs);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
int add_pob(int page, int x, int y, int image, gob_t *pob_data)
|
|
{
|
|
if (main_info.page_info[page].num_pobs >= NUM_POBS)
|
|
return 1;
|
|
|
|
main_info.page_info[page].pobs[main_info.page_info[page].num_pobs].x = x;
|
|
main_info.page_info[page].pobs[main_info.page_info[page].num_pobs].y = y;
|
|
main_info.page_info[page].pobs[main_info.page_info[page].num_pobs].image = image;
|
|
main_info.page_info[page].pobs[main_info.page_info[page].num_pobs].pob_data = pob_data;
|
|
main_info.page_info[page].num_pobs++;
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
void draw_flies(int page)
|
|
{
|
|
int c2;
|
|
|
|
for (c2 = 0; c2 < NUM_FLIES; c2++) {
|
|
flies[c2].back[main_info.draw_page] = get_pixel(main_info.draw_page, flies[c2].x, flies[c2].y);
|
|
flies[c2].back_defined[main_info.draw_page] = 1;
|
|
if (mask_pic[(flies[c2].y * JNB_WIDTH) + flies[c2].x] == 0)
|
|
set_pixel(main_info.draw_page, flies[c2].x, flies[c2].y, 0);
|
|
}
|
|
}
|
|
|
|
void draw_pobs(int page)
|
|
{
|
|
int c1;
|
|
int back_buf_ofs;
|
|
|
|
back_buf_ofs = 0;
|
|
|
|
for (c1 = main_info.page_info[page].num_pobs - 1; c1 >= 0; c1--) {
|
|
main_info.page_info[page].pobs[c1].back_buf_ofs = back_buf_ofs;
|
|
get_block(page, main_info.page_info[page].pobs[c1].x - pob_hs_x(main_info.page_info[page].pobs[c1].image, main_info.page_info[page].pobs[c1].pob_data), main_info.page_info[page].pobs[c1].y - pob_hs_y(main_info.page_info[page].pobs[c1].image, main_info.page_info[page].pobs[c1].pob_data), pob_width(main_info.page_info[page].pobs[c1].image, main_info.page_info[page].pobs[c1].pob_data), pob_height(main_info.page_info[page].pobs[c1].image, main_info.page_info[page].pobs[c1].pob_data), (unsigned char *)main_info.pob_backbuf[page] + back_buf_ofs);
|
|
back_buf_ofs += pob_width(main_info.page_info[page].pobs[c1].image, main_info.page_info[page].pobs[c1].pob_data) * pob_height(main_info.page_info[page].pobs[c1].image, main_info.page_info[page].pobs[c1].pob_data);
|
|
put_pob(page, main_info.page_info[page].pobs[c1].x, main_info.page_info[page].pobs[c1].y, main_info.page_info[page].pobs[c1].image, main_info.page_info[page].pobs[c1].pob_data, 1, mask_pic);
|
|
}
|
|
}
|
|
|
|
|
|
void redraw_flies_background(int page)
|
|
{
|
|
int c2;
|
|
|
|
for (c2 = NUM_FLIES - 1; c2 >= 0; c2--) {
|
|
if (flies[c2].back_defined[page] == 1)
|
|
set_pixel(page, flies[c2].old_draw_x, flies[c2].old_draw_y, flies[c2].back[page]);
|
|
flies[c2].old_draw_x = flies[c2].x;
|
|
flies[c2].old_draw_y = flies[c2].y;
|
|
}
|
|
}
|
|
|
|
|
|
void redraw_pob_backgrounds(int page)
|
|
{
|
|
int c1;
|
|
|
|
for (c1 = 0; c1 < main_info.page_info[page].num_pobs; c1++)
|
|
put_block(page, main_info.page_info[page].pobs[c1].x - pob_hs_x(main_info.page_info[page].pobs[c1].image, main_info.page_info[page].pobs[c1].pob_data), main_info.page_info[page].pobs[c1].y - pob_hs_y(main_info.page_info[page].pobs[c1].image, main_info.page_info[page].pobs[c1].pob_data), pob_width(main_info.page_info[page].pobs[c1].image, main_info.page_info[page].pobs[c1].pob_data), pob_height(main_info.page_info[page].pobs[c1].image, main_info.page_info[page].pobs[c1].pob_data), (unsigned char *)main_info.pob_backbuf[page] + main_info.page_info[page].pobs[c1].back_buf_ofs);
|
|
}
|
|
|
|
int read_level(void)
|
|
{
|
|
unsigned char *handle;
|
|
int c1, c2;
|
|
int chr;
|
|
|
|
if ((handle = dat_open("levelmap.txt")) == 0) {
|
|
strcpy(main_info.error_str, "Error loading 'levelmap.txt', aborting...\n");
|
|
return 1;
|
|
}
|
|
|
|
for (c1 = 0; c1 < 16; c1++) {
|
|
for (c2 = 0; c2 < 22; c2++) {
|
|
while (1) {
|
|
chr = (int) *(handle++);
|
|
if (chr >= '0' && chr <= '4')
|
|
break;
|
|
}
|
|
if (flip)
|
|
ban_map[c1][21-c2] = chr - '0';
|
|
else
|
|
ban_map[c1][c2] = chr - '0';
|
|
}
|
|
}
|
|
|
|
for (c2 = 0; c2 < 22; c2++)
|
|
ban_map[16][c2] = BAN_SOLID;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
unsigned char *dat_open(char *file_name)
|
|
{
|
|
int num;
|
|
int c1;
|
|
char name[21];
|
|
int ofs;
|
|
unsigned char *ptr;
|
|
|
|
if (datafile_buffer == NULL)
|
|
return 0;
|
|
|
|
memset(name, 0, sizeof(name));
|
|
|
|
num = ( (datafile_buffer[0] << 0) +
|
|
(datafile_buffer[1] << 8) +
|
|
(datafile_buffer[2] << 16) +
|
|
(datafile_buffer[3] << 24) );
|
|
|
|
ptr = datafile_buffer + 4;
|
|
|
|
for (c1 = 0; c1 < num; c1++) {
|
|
|
|
memcpy(name, ptr, 12);
|
|
ptr += 12;
|
|
|
|
if (strnicmp(name, file_name, strlen(file_name)) == 0) {
|
|
ofs = ( (ptr[0] << 0) +
|
|
(ptr[1] << 8) +
|
|
(ptr[2] << 16) +
|
|
(ptr[3] << 24) );
|
|
|
|
return (datafile_buffer + ofs);
|
|
}
|
|
ptr += 8;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
int dat_filelen(char *file_name)
|
|
{
|
|
unsigned char *ptr;
|
|
int num;
|
|
int c1;
|
|
char name[21];
|
|
int len;
|
|
|
|
memset(name, 0, sizeof(name));
|
|
|
|
num = ( (datafile_buffer[0] << 0) +
|
|
(datafile_buffer[1] << 8) +
|
|
(datafile_buffer[2] << 16) +
|
|
(datafile_buffer[3] << 24) );
|
|
|
|
ptr = datafile_buffer + 4;
|
|
|
|
for (c1 = 0; c1 < num; c1++) {
|
|
|
|
memcpy(name, ptr, 12);
|
|
ptr += 12;
|
|
|
|
if (strnicmp(name, file_name, strlen(file_name)) == 0) {
|
|
|
|
ptr += 4;
|
|
len = ( (ptr[0] << 0) +
|
|
(ptr[1] << 8) +
|
|
(ptr[2] << 16) +
|
|
(ptr[3] << 24) );
|
|
|
|
return len;
|
|
}
|
|
ptr += 8;
|
|
}
|
|
|
|
return 0;
|
|
}
|