forked from KolibriOS/kolibrios
dadd9561ac
git-svn-id: svn://kolibrios.org@8526 a494cfbc-eb01-0410-851d-a64ba20cac60
3591 lines
95 KiB
C
Executable File
3591 lines
95 KiB
C
Executable File
/*
|
|
* main.c
|
|
* Copyright (C) 1998 Brainchild Design - http://brainchilddesign.com/
|
|
*
|
|
* Copyright (C) 2001 Chuck Mason <cemason@users.sourceforge.net>
|
|
*
|
|
* Copyright (C) 2002 Florian Schulze <crow@icculus.org>
|
|
*
|
|
* This file is part of Jump'n'Bump.
|
|
*
|
|
* Jump'n'Bump is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* Jump'n'Bump is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
*/
|
|
|
|
#include "globals.h"
|
|
#include <fcntl.h>
|
|
#ifndef _MSC_VER
|
|
#include <unistd.h>
|
|
#endif
|
|
|
|
#ifdef BZLIB_SUPPORT
|
|
#include "bzlib.h"
|
|
#endif
|
|
|
|
#ifdef ZLIB_SUPPORT
|
|
#include "zlib.h"
|
|
#endif
|
|
|
|
#ifdef USE_NET
|
|
#include "SDL_net.h"
|
|
#endif /* USE_NET */
|
|
|
|
#ifndef M_PI
|
|
#define M_PI 3.14159265358979323846
|
|
#endif
|
|
|
|
gob_t rabbit_gobs = { 0 };
|
|
gob_t font_gobs = { 0 };
|
|
gob_t object_gobs = { 0 };
|
|
gob_t number_gobs = { 0 };
|
|
|
|
main_info_t main_info;
|
|
player_t player[JNB_MAX_PLAYERS];
|
|
player_anim_t player_anims[7];
|
|
object_t objects[NUM_OBJECTS];
|
|
joy_t joy;
|
|
mouse_t mouse;
|
|
|
|
char datfile_name[2048];
|
|
|
|
char *background_pic;
|
|
char *mask_pic;
|
|
int flip = 0;
|
|
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}
|
|
}
|
|
}
|
|
};
|
|
|
|
int flies_enabled = 1;
|
|
|
|
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];
|
|
|
|
struct {
|
|
struct {
|
|
short num_pobs;
|
|
struct {
|
|
int x, y;
|
|
int image;
|
|
gob_t *pob_data;
|
|
} pobs[NUM_LEFTOVERS];
|
|
} page[2];
|
|
} leftovers;
|
|
|
|
int pogostick, bunnies_in_space, jetpack, lord_of_the_flies, blood_is_thicker_than_water;
|
|
|
|
|
|
#ifndef _MSC_VER
|
|
int filelength(int handle)
|
|
{
|
|
struct stat buf;
|
|
|
|
if (fstat(handle, &buf) == -1) {
|
|
perror("filelength");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
return buf.st_size;
|
|
}
|
|
#endif
|
|
|
|
|
|
/* networking shite. */
|
|
|
|
int client_player_num = -1;
|
|
int is_server = 1;
|
|
int is_net = 0;
|
|
|
|
#ifdef USE_NET
|
|
TCPsocket sock = NULL;
|
|
SDLNet_SocketSet socketset = NULL;
|
|
|
|
typedef struct
|
|
{
|
|
TCPsocket sock;
|
|
IPaddress addr;
|
|
SDLNet_SocketSet socketset;
|
|
} NetInfo;
|
|
|
|
NetInfo net_info[JNB_MAX_PLAYERS];
|
|
#endif
|
|
|
|
typedef struct
|
|
{
|
|
unsigned long cmd;
|
|
long arg;
|
|
long arg2;
|
|
long arg3;
|
|
long arg4;
|
|
} NetPacket;
|
|
|
|
#define NETPKTBUFSIZE (4 + 4 + 4 + 4 + 4)
|
|
|
|
#define NETCMD_NACK (0xF00DF00D + 0)
|
|
#define NETCMD_ACK (0xF00DF00D + 1)
|
|
#define NETCMD_HELLO (0xF00DF00D + 2)
|
|
#define NETCMD_GREENLIGHT (0xF00DF00D + 3)
|
|
#define NETCMD_MOVE (0xF00DF00D + 4)
|
|
#define NETCMD_BYE (0xF00DF00D + 5)
|
|
#define NETCMD_POSITION (0xF00DF00D + 6)
|
|
#define NETCMD_ALIVE (0xF00DF00D + 7)
|
|
#define NETCMD_KILL (0xF00DF00D + 8)
|
|
|
|
|
|
#ifdef USE_NET
|
|
void bufToPacket(const char *buf, NetPacket *pkt)
|
|
{
|
|
SDLNet_Write32(*((Uint32*) (buf + 0)), &pkt->cmd);
|
|
SDLNet_Write32(*((Uint32*) (buf + 4)), &pkt->arg);
|
|
SDLNet_Write32(*((Uint32*) (buf + 8)), &pkt->arg2);
|
|
SDLNet_Write32(*((Uint32*) (buf + 12)), &pkt->arg3);
|
|
SDLNet_Write32(*((Uint32*) (buf + 16)), &pkt->arg4);
|
|
/*
|
|
pkt->cmd = ntohl(*((unsigned long *) (buf + 0)));
|
|
pkt->arg = (long) ntohl(*((unsigned long *) (buf + 4)));
|
|
pkt->arg2 = (long) ntohl(*((unsigned long *) (buf + 8)));
|
|
pkt->arg3 = (long) ntohl(*((unsigned long *) (buf + 12)));
|
|
pkt->arg4 = (long) ntohl(*((unsigned long *) (buf + 16)));
|
|
*/
|
|
}
|
|
|
|
|
|
void packetToBuf(const NetPacket *pkt, char *buf)
|
|
{
|
|
*((Uint32*) (buf + 0)) = SDLNet_Read32(&pkt->cmd);
|
|
*((Uint32*) (buf + 4)) = SDLNet_Read32(&pkt->arg);
|
|
*((Uint32*) (buf + 8)) = SDLNet_Read32(&pkt->arg2);
|
|
*((Uint32*) (buf + 12)) = SDLNet_Read32(&pkt->arg3);
|
|
*((Uint32*) (buf + 16)) = SDLNet_Read32(&pkt->arg4);
|
|
/*
|
|
*((unsigned long *) (buf + 0)) = htonl(pkt->cmd);
|
|
*((unsigned long *) (buf + 4)) = htonl((unsigned long) pkt->arg);
|
|
*((unsigned long *) (buf + 8)) = htonl((unsigned long) pkt->arg2);
|
|
*((unsigned long *) (buf + 12)) = htonl((unsigned long) pkt->arg3);
|
|
*((unsigned long *) (buf + 16)) = htonl((unsigned long) pkt->arg4);
|
|
*/
|
|
}
|
|
|
|
|
|
void sendPacketToSock(TCPsocket s, NetPacket *pkt)
|
|
{
|
|
int bytes_left = NETPKTBUFSIZE;
|
|
int bw;
|
|
char buf[NETPKTBUFSIZE];
|
|
char *ptr = buf;
|
|
|
|
packetToBuf(pkt, buf);
|
|
while (bytes_left > 0) {
|
|
bw = SDLNet_TCP_Send(s, ptr, bytes_left);
|
|
if (bw < 0) {
|
|
fprintf(stderr, "SERVER: SDLNet_TCP_Send(): %s\n", SDLNet_GetError());
|
|
SDLNet_TCP_Close(s);
|
|
exit(42);
|
|
} else if (bw == 0) {
|
|
SDL_Delay(1);
|
|
} else {
|
|
bytes_left -= bw;
|
|
ptr += bw;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void sendPacket(int playerid, NetPacket *pkt)
|
|
{
|
|
if ( (playerid < JNB_MAX_PLAYERS) && (playerid >= 0)) {
|
|
if ((player[playerid].enabled) && (playerid != client_player_num)) {
|
|
sendPacketToSock(net_info[playerid].sock, pkt);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void sendPacketToAll(NetPacket *pkt)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < JNB_MAX_PLAYERS; i++) {
|
|
sendPacket(i, pkt);
|
|
}
|
|
}
|
|
|
|
/** read a packet from the given TCPsocket
|
|
Returns -1 if some error occured, 0 if there was no data available and 1 if a
|
|
packet was successfully read.
|
|
Note: the socket has to be in the supplied socketset.
|
|
TODO: this function will bomb if a packet arrives in pieces, there is no
|
|
inherent guarantee that the next call will be made on the same socket. */
|
|
int grabPacket(TCPsocket s, SDLNet_SocketSet ss, NetPacket *pkt)
|
|
{
|
|
static char buf[NETPKTBUFSIZE];
|
|
static int buf_count = 0;
|
|
int rc;
|
|
|
|
if (SDLNet_CheckSockets(ss, 0) <= 0)
|
|
return 0;
|
|
|
|
if(!SDLNet_SocketReady(s))
|
|
return 0;
|
|
|
|
rc = SDLNet_TCP_Recv(s, &buf[buf_count], NETPKTBUFSIZE - buf_count);
|
|
if (rc <= 0) {
|
|
/* closed connection? */
|
|
return -1;
|
|
} else if (rc != NETPKTBUFSIZE) {
|
|
/* we got a partial packet. Store what we got in the static buffer and
|
|
return so that the next call can read the rest. Hopefully. */
|
|
buf_count = rc;
|
|
return 0;
|
|
} else {
|
|
buf_count = 0;
|
|
bufToPacket(buf, pkt);
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
|
|
int serverRecvPacket(NetPacket *pkt)
|
|
{
|
|
int rc;
|
|
int i;
|
|
|
|
assert(is_server);
|
|
|
|
for (i = 0; i < JNB_MAX_PLAYERS; i++) {
|
|
TCPsocket s = net_info[i].sock;
|
|
|
|
if ((i == client_player_num) || (!player[i].enabled))
|
|
continue;
|
|
|
|
rc = grabPacket(s, net_info[i].socketset, pkt);
|
|
if (rc < 0) {
|
|
NetPacket pkt;
|
|
|
|
player[i].enabled = 0;
|
|
SDLNet_TCP_Close(s);
|
|
pkt.cmd = NETCMD_BYE;
|
|
pkt.arg = i;
|
|
pkt.arg2 = 0;
|
|
pkt.arg3 = 0;
|
|
pkt.arg4 = 0;
|
|
sendPacketToAll(&pkt);
|
|
} else if (rc > 0) {
|
|
return(i); /* it's all good. */
|
|
}
|
|
}
|
|
|
|
return(-1); /* no packets available currently. */
|
|
}
|
|
|
|
|
|
void wait_for_greenlight(void)
|
|
{
|
|
NetPacket pkt;
|
|
int i;
|
|
|
|
printf("CLIENT: Waiting for greenlight...\n");
|
|
|
|
do {
|
|
int rc;
|
|
while ((rc = grabPacket(sock, socketset, &pkt)) == 0) {
|
|
SDL_Delay(100); /* nap and then try again. */
|
|
}
|
|
|
|
if (rc < 0) {
|
|
printf("CLIENT: Lost connection.\n");
|
|
SDLNet_TCP_Close(sock);
|
|
exit(42);
|
|
}
|
|
} while (pkt.cmd != NETCMD_GREENLIGHT);
|
|
|
|
printf("CLIENT: Got greenlight.\n");
|
|
|
|
for (i = 0; i < JNB_MAX_PLAYERS; i++) {
|
|
if (pkt.arg & (1 << i)) {
|
|
printf("CLIENT: There is a player #%d.\n", i);
|
|
player[i].enabled = 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
static int buggered_off = 0;
|
|
|
|
|
|
void tellServerGoodbye(void)
|
|
{
|
|
NetPacket pkt;
|
|
|
|
if (!buggered_off) {
|
|
buggered_off = 1;
|
|
pkt.cmd = NETCMD_BYE;
|
|
pkt.arg = client_player_num;
|
|
pkt.arg2 = 0;
|
|
pkt.arg3 = 0;
|
|
pkt.arg4 = 0;
|
|
sendPacketToSock(sock, &pkt);
|
|
}
|
|
}
|
|
#endif /* USE_NET */
|
|
|
|
|
|
void processMovePacket(NetPacket *pkt)
|
|
{
|
|
int playerid = pkt->arg;
|
|
int movetype = ((pkt->arg2 >> 16) & 0xFF);
|
|
int newval = ((pkt->arg2 >> 0) & 0xFF);
|
|
|
|
if (movetype == MOVEMENT_LEFT) {
|
|
player[playerid].action_left = newval;
|
|
} else if (movetype == MOVEMENT_RIGHT) {
|
|
player[playerid].action_right = newval;
|
|
} else if (movetype == MOVEMENT_UP) {
|
|
player[playerid].action_up = newval;
|
|
} else {
|
|
printf("bogus MOVE packet!\n");
|
|
}
|
|
|
|
player[playerid].x = pkt->arg3;
|
|
player[playerid].y = pkt->arg4;
|
|
}
|
|
|
|
|
|
void tellServerPlayerMoved(int playerid, int movement_type, int newval)
|
|
{
|
|
NetPacket pkt;
|
|
|
|
pkt.cmd = NETCMD_MOVE;
|
|
pkt.arg = playerid;
|
|
pkt.arg2 = ( ((movement_type & 0xFF) << 16) | ((newval & 0xFF) << 0) );
|
|
pkt.arg3 = player[playerid].x;
|
|
pkt.arg4 = player[playerid].y;
|
|
|
|
if (is_server) {
|
|
processMovePacket(&pkt);
|
|
#ifdef USE_NET
|
|
if (is_net)
|
|
sendPacketToAll(&pkt);
|
|
} else {
|
|
sendPacketToSock(sock, &pkt);
|
|
#endif
|
|
}
|
|
}
|
|
|
|
|
|
#ifdef USE_NET
|
|
void tellServerNewPosition(void)
|
|
{
|
|
NetPacket pkt;
|
|
pkt.cmd = NETCMD_POSITION;
|
|
pkt.arg = client_player_num;
|
|
pkt.arg2 = player[client_player_num].x;
|
|
pkt.arg3 = player[client_player_num].y;
|
|
|
|
if (is_server) {
|
|
sendPacketToAll(&pkt);
|
|
} else {
|
|
sendPacketToSock(sock, &pkt);
|
|
}
|
|
}
|
|
#endif /* USE_NET */
|
|
|
|
|
|
void processKillPacket(NetPacket *pkt)
|
|
{
|
|
int c1 = pkt->arg;
|
|
int c2 = pkt->arg2;
|
|
int x = pkt->arg3;
|
|
int y = pkt->arg4;
|
|
int c4 = 0;
|
|
int s1 = 0;
|
|
|
|
player[c1].y_add = -player[c1].y_add;
|
|
if (player[c1].y_add > -262144L)
|
|
player[c1].y_add = -262144L;
|
|
player[c1].jump_abort = 1;
|
|
player[c2].dead_flag = 1;
|
|
if (player[c2].anim != 6) {
|
|
player[c2].anim = 6;
|
|
player[c2].frame = 0;
|
|
player[c2].frame_tick = 0;
|
|
player[c2].image = player_anims[player[c2].anim].frame[player[c2].frame].image + player[c2].direction * 9;
|
|
if (main_info.no_gore == 0) {
|
|
for (c4 = 0; c4 < 6; c4++)
|
|
add_object(OBJ_FUR, (x >> 16) + 6 + rnd(5), (y >> 16) + 6 + rnd(5), (rnd(65535) - 32768) * 3, (rnd(65535) - 32768) * 3, 0, 44 + c2 * 8);
|
|
for (c4 = 0; c4 < 6; c4++)
|
|
add_object(OBJ_FLESH, (x >> 16) + 6 + rnd(5), (y >> 16) + 6 + rnd(5), (rnd(65535) - 32768) * 3, (rnd(65535) - 32768) * 3, 0, 76);
|
|
for (c4 = 0; c4 < 6; c4++)
|
|
add_object(OBJ_FLESH, (x >> 16) + 6 + rnd(5), (y >> 16) + 6 + rnd(5), (rnd(65535) - 32768) * 3, (rnd(65535) - 32768) * 3, 0, 77);
|
|
for (c4 = 0; c4 < 8; c4++)
|
|
add_object(OBJ_FLESH, (x >> 16) + 6 + rnd(5), (y >> 16) + 6 + rnd(5), (rnd(65535) - 32768) * 3, (rnd(65535) - 32768) * 3, 0, 78);
|
|
for (c4 = 0; c4 < 10; c4++)
|
|
add_object(OBJ_FLESH, (x >> 16) + 6 + rnd(5), (y >> 16) + 6 + rnd(5), (rnd(65535) - 32768) * 3, (rnd(65535) - 32768) * 3, 0, 79);
|
|
}
|
|
dj_play_sfx(SFX_DEATH, (unsigned short)(SFX_DEATH_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
|
|
player[c1].bumps++;
|
|
player[c1].bumped[c2]++;
|
|
s1 = player[c1].bumps % 100;
|
|
add_leftovers(0, 360, 34 + c1 * 64, s1 / 10, &number_gobs);
|
|
add_leftovers(1, 360, 34 + c1 * 64, s1 / 10, &number_gobs);
|
|
add_leftovers(0, 376, 34 + c1 * 64, s1 - (s1 / 10) * 10, &number_gobs);
|
|
add_leftovers(1, 376, 34 + c1 * 64, s1 - (s1 / 10) * 10, &number_gobs);
|
|
}
|
|
}
|
|
|
|
|
|
#ifdef USE_NET
|
|
void processPositionPacket(NetPacket *pkt)
|
|
{
|
|
int playerid = pkt->arg;
|
|
|
|
player[playerid].x = pkt->arg2;
|
|
player[playerid].y = pkt->arg3;
|
|
}
|
|
|
|
|
|
void processAlivePacket(NetPacket *pkt)
|
|
{
|
|
int playerid = pkt->arg;
|
|
|
|
player[playerid].dead_flag = 0;
|
|
player[playerid].x = pkt->arg2;
|
|
player[playerid].y = pkt->arg3;
|
|
}
|
|
|
|
|
|
void serverTellEveryoneGoodbye(void)
|
|
{
|
|
int i;
|
|
|
|
if (!buggered_off) {
|
|
buggered_off = 1;
|
|
for (i = 0; i < JNB_MAX_PLAYERS; i++) {
|
|
if (player[i].enabled) {
|
|
NetPacket pkt;
|
|
|
|
pkt.cmd = NETCMD_BYE;
|
|
pkt.arg = i;
|
|
pkt.arg2 = 0;
|
|
pkt.arg3 = 0;
|
|
pkt.arg4 = 0;
|
|
sendPacketToAll(&pkt);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
int server_said_bye = 0;
|
|
|
|
|
|
int update_players_from_server(void)
|
|
{
|
|
NetPacket pkt;
|
|
int rc;
|
|
|
|
assert(!is_server);
|
|
|
|
while ((rc = grabPacket(sock, socketset, &pkt)) != 0) {
|
|
if (rc < 0) {
|
|
printf("CLIENT: Lost connection.\n");
|
|
pkt.cmd = NETCMD_BYE;
|
|
pkt.arg = client_player_num;
|
|
}
|
|
|
|
if (pkt.cmd == NETCMD_BYE) {
|
|
if (pkt.arg == client_player_num) {
|
|
SDLNet_FreeSocketSet(socketset);
|
|
SDLNet_TCP_Close(sock);
|
|
sock = NULL;
|
|
server_said_bye = 1;
|
|
return(0);
|
|
} else {
|
|
player[pkt.arg].enabled = 0;
|
|
}
|
|
} else if (pkt.cmd == NETCMD_MOVE) {
|
|
processMovePacket(&pkt);
|
|
} else if (pkt.cmd == NETCMD_ALIVE) {
|
|
processAlivePacket(&pkt);
|
|
} else if (pkt.cmd == NETCMD_POSITION) {
|
|
processPositionPacket(&pkt);
|
|
} else if (pkt.cmd == NETCMD_KILL) {
|
|
processKillPacket(&pkt);
|
|
} else {
|
|
printf("CLIENT: Got an unknown packet: 0x%lX.\n", pkt.cmd);
|
|
}
|
|
}
|
|
|
|
return(1);
|
|
}
|
|
|
|
|
|
void serverSendAlive(int playerid)
|
|
{
|
|
NetPacket pkt;
|
|
|
|
assert(is_server);
|
|
pkt.cmd = NETCMD_ALIVE;
|
|
pkt.arg = playerid;
|
|
pkt.arg2 = player[playerid].x;
|
|
pkt.arg3 = player[playerid].y;
|
|
sendPacketToAll(&pkt);
|
|
}
|
|
#endif /* USE_NET */
|
|
|
|
|
|
void serverSendKillPacket(int killer, int victim)
|
|
{
|
|
NetPacket pkt;
|
|
|
|
assert(is_server);
|
|
pkt.cmd = NETCMD_KILL;
|
|
pkt.arg = killer;
|
|
pkt.arg2 = victim;
|
|
pkt.arg3 = player[victim].x;
|
|
pkt.arg4 = player[victim].y;
|
|
processKillPacket(&pkt);
|
|
#ifdef USE_NET
|
|
if (is_net)
|
|
sendPacketToAll(&pkt);
|
|
#endif
|
|
}
|
|
|
|
|
|
#ifdef USE_NET
|
|
void update_players_from_clients(void)
|
|
{
|
|
int i;
|
|
NetPacket pkt;
|
|
int playerid;
|
|
|
|
assert(is_server);
|
|
|
|
while ((playerid = serverRecvPacket(&pkt)) >= 0) {
|
|
if (pkt.cmd == NETCMD_BYE) {
|
|
pkt.arg = playerid; /* just in case. */
|
|
sendPacketToAll(&pkt);
|
|
player[playerid].enabled = 0;
|
|
SDLNet_FreeSocketSet(net_info[playerid].socketset);
|
|
SDLNet_TCP_Close(net_info[playerid].sock);
|
|
} else if (pkt.cmd == NETCMD_POSITION) {
|
|
pkt.arg = playerid; /* just in case. */
|
|
processPositionPacket(&pkt);
|
|
for (i = 0; i < JNB_MAX_PLAYERS; i++) {
|
|
if (i != playerid) {
|
|
sendPacket(i, &pkt);
|
|
}
|
|
}
|
|
} else if (pkt.cmd == NETCMD_MOVE) {
|
|
pkt.arg = playerid; /* just in case. */
|
|
/*
|
|
pkt.arg3 = player[playerid].x;
|
|
pkt.arg4 = player[playerid].y;
|
|
*/
|
|
processMovePacket(&pkt);
|
|
sendPacketToAll(&pkt);
|
|
} else {
|
|
printf("SERVER: Got unknown packet (0x%lX).\n", pkt.cmd);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void init_server(const char *netarg)
|
|
{
|
|
NetPacket pkt;
|
|
IPaddress addr;
|
|
int i;
|
|
int wait_for_clients = ((netarg == NULL) ? 0 : atoi(netarg));
|
|
char *ipstr;
|
|
|
|
/** assign player number zero as default for the server */
|
|
if(-1 == client_player_num)
|
|
client_player_num = 0;
|
|
|
|
if ((wait_for_clients >= JNB_MAX_PLAYERS) || (wait_for_clients < 0)) {
|
|
printf("SERVER: Waiting for bogus client count (%d).\n", wait_for_clients);
|
|
exit(42);
|
|
}
|
|
|
|
if (SDLNet_Init() < 0) {
|
|
exit(42);
|
|
}
|
|
atexit(SDLNet_Quit);
|
|
|
|
SDLNet_ResolveHost(&addr, NULL, JNB_INETPORT);
|
|
ipstr = SDLNet_ResolveIP(&addr);
|
|
SDLNet_ResolveHost(&addr, ipstr, JNB_INETPORT);
|
|
printf("SERVER: we are %s (%i.%i.%i.%i:%i).\n", ipstr, (addr.host >> 0) & 0xff, (addr.host >> 8) & 0xff, (addr.host >> 16) & 0xff, (addr.host >> 24) & 0xff, addr.port);
|
|
net_info[client_player_num].addr = addr;
|
|
|
|
addr.host = INADDR_ANY;
|
|
sock = SDLNet_TCP_Open(&addr);
|
|
if (sock == NULL) {
|
|
fprintf(stderr, "SERVER: SDLNet_TCP_Open(): %s\n", SDLNet_GetError());
|
|
exit(42);
|
|
}
|
|
|
|
player[client_player_num].enabled = 1;
|
|
|
|
printf("SERVER: waiting for (%d) clients...\n", wait_for_clients);
|
|
|
|
socketset = SDLNet_AllocSocketSet(JNB_MAX_PLAYERS + 1);
|
|
SDLNet_TCP_AddSocket(socketset, sock);
|
|
|
|
while (wait_for_clients > 0)
|
|
{
|
|
char buf[NETPKTBUFSIZE];
|
|
IPaddress *from;
|
|
int negatory = 1;
|
|
int br;
|
|
TCPsocket s;
|
|
|
|
/* Wait for events */
|
|
SDLNet_CheckSockets(socketset, ~0);
|
|
if ( SDLNet_SocketReady(sock) ) {
|
|
s = SDLNet_TCP_Accept(sock);
|
|
|
|
if (s == NULL)
|
|
{
|
|
fprintf(stderr, "SERVER: SDLNet_TCP_Accept(): %s", SDLNet_GetError());
|
|
SDLNet_TCP_Close(sock);
|
|
exit(42);
|
|
}
|
|
} else
|
|
continue;
|
|
|
|
br = SDLNet_TCP_Recv(s, buf, NETPKTBUFSIZE);
|
|
if (br < 0) {
|
|
fprintf(stderr, "SERVER: SDLNet_TCP_Recv(): %s\n", SDLNet_GetError());
|
|
SDLNet_TCP_Close(s);
|
|
SDLNet_TCP_Close(sock);
|
|
exit(42);
|
|
}
|
|
|
|
from = SDLNet_TCP_GetPeerAddress(s);
|
|
ipstr = SDLNet_ResolveIP(from);
|
|
printf("SERVER: Got data from %s (%i.%i.%i.%i:%i).\n", ipstr, (from->host >> 0) & 0xff, (from->host >> 8) & 0xff, (from->host >> 16) & 0xff, (from->host >> 24) & 0xff, from->port);
|
|
|
|
if (br != NETPKTBUFSIZE) {
|
|
printf("SERVER: Bogus packet.\n");
|
|
continue;
|
|
}
|
|
|
|
bufToPacket(buf, &pkt);
|
|
if (pkt.cmd != NETCMD_HELLO) {
|
|
printf("SERVER: Bogus packet.\n");
|
|
continue;
|
|
}
|
|
|
|
printf("SERVER: Client claims to be player #%ld.\n", pkt.arg);
|
|
|
|
if (-1 == pkt.arg) {
|
|
int i;
|
|
for(i=0; i!=JNB_MAX_PLAYERS; ++i) {
|
|
if(!player[i].enabled) {
|
|
printf("SERVER: assigning %d as player number\n", i);
|
|
pkt.arg = i;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if ((pkt.arg>=JNB_MAX_PLAYERS)||(pkt.arg<0)) {
|
|
printf("SERVER: (that's an invalid player number.)\n");
|
|
} else if (player[pkt.arg].enabled) {
|
|
printf("SERVER: (that player number is already taken.)\n");
|
|
} else {
|
|
negatory = 0;
|
|
}
|
|
|
|
if (negatory) {
|
|
printf("SERVER: Forbidding connection.\n");
|
|
pkt.cmd = NETCMD_NACK;
|
|
sendPacketToSock(s, &pkt);
|
|
SDLNet_TCP_Close(s);
|
|
} else {
|
|
player[pkt.arg].enabled = 1;
|
|
net_info[pkt.arg].sock = s;
|
|
net_info[pkt.arg].addr = *from;
|
|
net_info[pkt.arg].socketset = SDLNet_AllocSocketSet(1);
|
|
SDLNet_TCP_AddSocket(net_info[pkt.arg].socketset, net_info[pkt.arg].sock);
|
|
wait_for_clients--;
|
|
printf("SERVER: Granting connection. (%d) to go.\n", wait_for_clients);
|
|
pkt.cmd = NETCMD_ACK;
|
|
sendPacket(pkt.arg, &pkt);
|
|
}
|
|
}
|
|
|
|
SDLNet_TCP_Close(sock); /* done with the listen socket. */
|
|
SDLNet_FreeSocketSet(socketset);
|
|
sock = NULL;
|
|
socketset = NULL;
|
|
|
|
printf("SERVER: Got all our connections. Greenlighting clients...\n");
|
|
|
|
pkt.cmd = NETCMD_GREENLIGHT;
|
|
pkt.arg = 0;
|
|
for (i = 0; i < JNB_MAX_PLAYERS; i++) {
|
|
if (player[i].enabled) {
|
|
pkt.arg |= (1 << i);
|
|
}
|
|
}
|
|
sendPacketToAll(&pkt);
|
|
}
|
|
|
|
|
|
void connect_to_server(char *netarg)
|
|
{
|
|
NetPacket pkt;
|
|
char buf[NETPKTBUFSIZE];
|
|
char *ipstr;
|
|
IPaddress hent;
|
|
IPaddress addr;
|
|
int br;
|
|
|
|
if (netarg == NULL) {
|
|
printf("CLIENT: Need to specify host to connect to.\n");
|
|
exit(42);
|
|
}
|
|
|
|
if (SDLNet_Init() < 0) {
|
|
exit(42);
|
|
}
|
|
atexit(SDLNet_Quit);
|
|
|
|
SDLNet_ResolveHost(&addr, NULL, JNB_INETPORT);
|
|
ipstr = SDLNet_ResolveIP(&addr);
|
|
SDLNet_ResolveHost(&addr, ipstr, JNB_INETPORT);
|
|
printf("CLIENT: we are %s (%i.%i.%i.%i:%i).\n", ipstr, (addr.host >> 0) & 0xff, (addr.host >> 8) & 0xff, (addr.host >> 16) & 0xff, (addr.host >> 24) & 0xff, addr.port);
|
|
|
|
if (SDLNet_ResolveHost(&hent, netarg, JNB_INETPORT) < 0) {
|
|
fprintf(stderr, "CLIENT: couldn't find host: %s\n", SDLNet_GetError());
|
|
exit(42);
|
|
}
|
|
|
|
sock = SDLNet_TCP_Open(&hent);
|
|
if (sock == NULL) {
|
|
fprintf(stderr, "CLIENT: SDLNet_TCP_Open(): %s\n", SDLNet_GetError());
|
|
exit(42);
|
|
}
|
|
|
|
socketset = SDLNet_AllocSocketSet(1);
|
|
SDLNet_TCP_AddSocket(socketset, sock);
|
|
|
|
printf("CLIENT: connected to %s...\n", SDLNet_ResolveIP(&hent));
|
|
|
|
printf("CLIENT: Sending HELLO packet...\n");
|
|
pkt.cmd = NETCMD_HELLO;
|
|
pkt.arg = client_player_num;
|
|
sendPacketToSock(sock, &pkt);
|
|
|
|
printf("CLIENT: Waiting for ACK from server...\n");
|
|
|
|
br = SDLNet_TCP_Recv(sock, buf, NETPKTBUFSIZE);
|
|
if (br < 0) {
|
|
fprintf(stderr, "CLIENT: recv(): %s\n", SDLNet_GetError());
|
|
SDLNet_FreeSocketSet(socketset);
|
|
SDLNet_TCP_Close(sock);
|
|
exit(42);
|
|
}
|
|
|
|
if (br != NETPKTBUFSIZE) {
|
|
printf("CLIENT: Bogus packet size (%d of %d). FIXME.\n", br, NETPKTBUFSIZE);
|
|
SDLNet_FreeSocketSet(socketset);
|
|
SDLNet_TCP_Close(sock);
|
|
exit(42);
|
|
}
|
|
|
|
bufToPacket(buf, &pkt);
|
|
|
|
if (pkt.cmd == NETCMD_NACK) {
|
|
printf("CLIENT: Server forbid us from playing.\n");
|
|
SDLNet_FreeSocketSet(socketset);
|
|
SDLNet_TCP_Close(sock);
|
|
exit(42);
|
|
}
|
|
|
|
if (pkt.cmd != NETCMD_ACK) {
|
|
printf("CLIENT: Unexpected packet (cmd=0x%lX).\n", pkt.cmd);
|
|
SDLNet_FreeSocketSet(socketset);
|
|
SDLNet_TCP_Close(sock);
|
|
exit(42);
|
|
}
|
|
|
|
client_player_num = pkt.arg;
|
|
player[client_player_num].enabled = 1;
|
|
net_info[client_player_num].addr = addr;
|
|
printf("CLIENT: Server accepted our connection.\n");
|
|
|
|
wait_for_greenlight();
|
|
}
|
|
#endif /* USE_NET */
|
|
|
|
|
|
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;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
static void update_flies(int update_count)
|
|
{
|
|
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;
|
|
|
|
if (update_count == 1) {
|
|
/* 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 check_cheats(void)
|
|
{
|
|
if (strncmp(last_keys, "kcitsogop", strlen("kcitsogop")) == 0) {
|
|
pogostick ^= 1;
|
|
last_keys[0] = 0;
|
|
}
|
|
if (strncmp(last_keys, "ecapsniseinnub", strlen("ecapsniseinnub")) == 0) {
|
|
bunnies_in_space ^= 1;
|
|
last_keys[0] = 0;
|
|
}
|
|
if (strncmp(last_keys, "kcaptej", strlen("kcaptej")) == 0) {
|
|
jetpack ^= 1;
|
|
last_keys[0] = 0;
|
|
}
|
|
if (strncmp(last_keys, "seilfehtfodrol", strlen("seilfehtfodrol")) == 0) {
|
|
lord_of_the_flies ^= 1;
|
|
last_keys[0] = 0;
|
|
}
|
|
if (strncmp(last_keys, "retawnahtrekcihtsidoolb", strlen("retawnahtrekcihtsidoolb")) == 0) {
|
|
char blood[32] = {
|
|
63,32,32,53,17,17,42, 7,
|
|
7,28, 0, 0,24, 0, 0,19,
|
|
0, 0,12, 0, 0, 7, 0, 0
|
|
};
|
|
char water[32] = {
|
|
63,63,63,40,53,62,19,42,
|
|
60, 0,33,60, 3,32,46, 3,
|
|
26,33, 3,19,21, 1, 8, 8
|
|
};
|
|
int i;
|
|
|
|
blood_is_thicker_than_water ^= 1;
|
|
if (blood_is_thicker_than_water == 1) {
|
|
for (i=0; i<32; i++)
|
|
pal[432+i] = blood[i];
|
|
} else {
|
|
for (i=0; i<32; i++)
|
|
pal[432+i] = water[i];
|
|
}
|
|
register_background(background_pic, pal);
|
|
recalculate_gob(&object_gobs, pal);
|
|
last_keys[0] = 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 void game_loop(void) {
|
|
int mod_vol, sfx_vol;
|
|
int update_count = 1;
|
|
int end_loop_flag = 0;
|
|
int fade_flag = 0;
|
|
int update_palette = 0;
|
|
int mod_fade_direction;
|
|
int i;
|
|
|
|
mod_vol = sfx_vol = 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();
|
|
|
|
intr_sysupdate();
|
|
|
|
while (1) {
|
|
while (update_count) {
|
|
|
|
if (key_pressed(1) == 1) {
|
|
#ifdef USE_NET
|
|
if (is_net) {
|
|
if (is_server) {
|
|
serverTellEveryoneGoodbye();
|
|
} else {
|
|
tellServerGoodbye();
|
|
}
|
|
}
|
|
#endif
|
|
end_loop_flag = 1;
|
|
memset(pal, 0, 768);
|
|
mod_fade_direction = 0;
|
|
}
|
|
|
|
check_cheats();
|
|
|
|
#ifdef USE_NET
|
|
if (is_net) {
|
|
if (is_server) {
|
|
update_players_from_clients();
|
|
} else {
|
|
if (!update_players_from_server()) {
|
|
break; /* got a BYE packet */
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
|
|
steer_players();
|
|
|
|
dj_mix();
|
|
|
|
collision_check();
|
|
|
|
dj_mix();
|
|
|
|
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();
|
|
|
|
dj_mix();
|
|
|
|
if (flies_enabled) {
|
|
update_flies(update_count);
|
|
}
|
|
|
|
dj_mix();
|
|
|
|
if (update_count == 1) {
|
|
int c2;
|
|
|
|
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);
|
|
|
|
dj_mix();
|
|
|
|
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)
|
|
break;
|
|
|
|
if (update_count == 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);
|
|
|
|
wait_vrt(1);
|
|
|
|
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();
|
|
}
|
|
|
|
update_count--;
|
|
}
|
|
|
|
#ifdef USE_NET
|
|
if (is_net) {
|
|
if ( (player[client_player_num].dead_flag == 0) &&
|
|
(
|
|
(player[client_player_num].action_left) ||
|
|
(player[client_player_num].action_right) ||
|
|
(player[client_player_num].action_up) ||
|
|
(player[client_player_num].jump_ready == 0)
|
|
)
|
|
) {
|
|
tellServerNewPosition();
|
|
}
|
|
}
|
|
#endif
|
|
|
|
update_count = intr_sysupdate();
|
|
|
|
#ifdef USE_NET
|
|
if (is_net) {
|
|
if ((server_said_bye) || ((fade_flag == 0) && (end_loop_flag == 1)))
|
|
break;
|
|
} else
|
|
#endif
|
|
if ((fade_flag == 0) && (end_loop_flag == 1))
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
static int menu_loop(void)
|
|
{
|
|
unsigned char *handle;
|
|
int mod_vol;
|
|
int c1, c2;
|
|
int s1, s2;
|
|
|
|
for(c1 = 0; c1 < JNB_MAX_PLAYERS; c1++) // reset player values
|
|
{
|
|
ai[c1] = 0;
|
|
}
|
|
|
|
while (1) {
|
|
|
|
if (!is_net)
|
|
if (menu() != 0)
|
|
deinit_program();
|
|
|
|
if (key_pressed(1) == 1) {
|
|
return 0;
|
|
}
|
|
if (init_level(0, pal) != 0) {
|
|
deinit_level();
|
|
deinit_program();
|
|
}
|
|
|
|
memset(cur_pal, 0, 768);
|
|
setpalette(0, 256, cur_pal);
|
|
|
|
recalculate_gob(&rabbit_gobs, pal);
|
|
recalculate_gob(&object_gobs, pal);
|
|
recalculate_gob(&number_gobs, 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;
|
|
|
|
game_loop();
|
|
|
|
#ifdef USE_NET
|
|
if (is_net) {
|
|
if (is_server) {
|
|
serverTellEveryoneGoodbye();
|
|
SDLNet_TCP_Close(sock);
|
|
sock = NULL;
|
|
} else {
|
|
if (!server_said_bye) {
|
|
tellServerGoodbye();
|
|
}
|
|
|
|
SDLNet_TCP_Close(sock);
|
|
sock = NULL;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
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];
|
|
|
|
for (c2 = 0; c2 < JNB_MAX_PLAYERS; c2++) {
|
|
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);
|
|
|
|
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;
|
|
}
|
|
|
|
/* 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);
|
|
|
|
while (key_pressed(1) == 0) {
|
|
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]++;
|
|
}
|
|
dj_mix();
|
|
intr_sysupdate();
|
|
wait_vrt(0);
|
|
setpalette(0, 256, cur_pal);
|
|
flippage(main_info.view_page);
|
|
}
|
|
while (key_pressed(1) == 1) {
|
|
dj_mix();
|
|
intr_sysupdate();
|
|
}
|
|
|
|
memset(pal, 0, 768);
|
|
|
|
while (mod_vol > 0) {
|
|
mod_vol--;
|
|
dj_set_mod_volume((char)mod_vol);
|
|
for (c1 = 0; c1 < 768; c1++) {
|
|
if (cur_pal[c1] > pal[c1])
|
|
cur_pal[c1]--;
|
|
}
|
|
dj_mix();
|
|
wait_vrt(0);
|
|
setpalette(0, 256, cur_pal);
|
|
flippage(main_info.view_page);
|
|
}
|
|
|
|
fillpalette(0, 0, 0);
|
|
|
|
dj_set_nosound(1);
|
|
dj_stop_mod();
|
|
|
|
if (is_net)
|
|
return 0; /* don't go back to menu if in net game. */
|
|
}
|
|
}
|
|
|
|
|
|
int main(int argc, char *argv[])
|
|
{
|
|
int result;
|
|
|
|
if (init_program(argc, argv, pal) != 0)
|
|
deinit_program();
|
|
|
|
if (main_info.fireworks == 1) {
|
|
fireworks();
|
|
deinit_program();
|
|
}
|
|
|
|
result = menu_loop();
|
|
|
|
deinit_program();
|
|
|
|
return result;
|
|
}
|
|
|
|
|
|
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 */
|
|
if(lm)
|
|
{
|
|
SDLKey key;
|
|
if(i == 0)
|
|
key = KEY_PL1_LEFT;
|
|
else if(i == 1)
|
|
key = KEY_PL2_LEFT;
|
|
else if(i == 2)
|
|
key = KEY_PL3_LEFT;
|
|
else
|
|
key = KEY_PL4_LEFT;
|
|
|
|
key &= 0x7f;
|
|
addkey(key);
|
|
}
|
|
else
|
|
{
|
|
SDLKey key;
|
|
if(i == 0)
|
|
key = KEY_PL1_LEFT;
|
|
else if(i == 1)
|
|
key = KEY_PL2_LEFT;
|
|
else if(i == 2)
|
|
key = KEY_PL3_LEFT;
|
|
else
|
|
key = KEY_PL4_LEFT;
|
|
|
|
key &= 0x7f;
|
|
addkey(key | 0x8000);
|
|
}
|
|
|
|
if(rm)
|
|
{
|
|
SDLKey key;
|
|
if(i == 0)
|
|
key = KEY_PL1_RIGHT;
|
|
else if(i == 1)
|
|
key = KEY_PL2_RIGHT;
|
|
else if(i == 2)
|
|
key = KEY_PL3_RIGHT;
|
|
else
|
|
key = KEY_PL4_RIGHT;
|
|
|
|
key &= 0x7f;
|
|
addkey(key);
|
|
}
|
|
else
|
|
{
|
|
SDLKey key;
|
|
if(i == 0)
|
|
key = KEY_PL1_RIGHT;
|
|
else if(i == 1)
|
|
key = KEY_PL2_RIGHT;
|
|
else if(i == 2)
|
|
key = KEY_PL3_RIGHT;
|
|
else
|
|
key = KEY_PL4_RIGHT;
|
|
|
|
key &= 0x7f;
|
|
addkey(key | 0x8000);
|
|
}
|
|
|
|
if(jm)
|
|
{
|
|
SDLKey key;
|
|
if(i == 0)
|
|
key = KEY_PL1_JUMP;
|
|
else if(i == 1)
|
|
key = KEY_PL2_JUMP;
|
|
else if(i == 2)
|
|
key = KEY_PL3_JUMP;
|
|
else
|
|
key = KEY_PL4_JUMP;
|
|
|
|
key &= 0x7f;
|
|
addkey(key);
|
|
}
|
|
else
|
|
{
|
|
SDLKey key;
|
|
if(i == 0)
|
|
key = KEY_PL1_JUMP;
|
|
else if(i == 1)
|
|
key = KEY_PL2_JUMP;
|
|
else if(i == 2)
|
|
key = KEY_PL3_JUMP;
|
|
else
|
|
key = KEY_PL4_JUMP;
|
|
|
|
key &= 0x7f;
|
|
addkey(key | 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 (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) {
|
|
#ifdef USE_NET
|
|
if (is_net)
|
|
serverSendAlive(player_num);
|
|
#endif
|
|
player[player_num].dead_flag = 0;
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
|
|
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;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
|
|
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);
|
|
if (scale_up)
|
|
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) * 4;
|
|
else
|
|
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 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 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 init_level(int level, char *pal)
|
|
{
|
|
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);
|
|
register_mask(mask_pic);
|
|
|
|
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);
|
|
}
|
|
}
|
|
|
|
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();
|
|
}
|
|
|
|
|
|
#ifndef PATH_MAX
|
|
#define PATH_MAX 1024
|
|
#endif
|
|
#ifndef O_BINARY
|
|
#define O_BINARY 0
|
|
#endif
|
|
|
|
unsigned char *datafile_buffer = NULL;
|
|
|
|
static void preread_datafile(const char *fname)
|
|
{
|
|
int fd = 0;
|
|
int len;
|
|
|
|
#ifdef ZLIB_SUPPORT
|
|
char *gzfilename;
|
|
gzFile gzf;
|
|
#endif
|
|
|
|
#ifdef BZLIB_SUPPORT
|
|
char *bzfilename;
|
|
BZFILE *bzf;
|
|
#endif
|
|
|
|
#ifdef BZLIB_SUPPORT
|
|
bzfilename = malloc(strlen(fname) + 5);
|
|
strcpy(bzfilename, fname);
|
|
strcat(bzfilename, ".bz2");
|
|
bzf = BZ2_bzopen(bzfilename, "rb");
|
|
free(bzfilename);
|
|
bzfilename = NULL;
|
|
|
|
if (bzf != NULL) {
|
|
int bufsize = 0;
|
|
int bufpos = 0;
|
|
int br;
|
|
unsigned char *ptr;
|
|
do {
|
|
if (bufpos >= bufsize) {
|
|
bufsize += 1024 * 1024;
|
|
datafile_buffer = (unsigned char *) realloc(datafile_buffer, bufsize);
|
|
if (datafile_buffer == NULL) {
|
|
perror("realloc()");
|
|
exit(42);
|
|
}
|
|
}
|
|
|
|
br = BZ2_bzread(bzf, datafile_buffer + bufpos, bufsize - bufpos);
|
|
if (br == -1) {
|
|
fprintf(stderr, "gzread failed.\n");
|
|
exit(42);
|
|
}
|
|
|
|
bufpos += br;
|
|
} while (br>0);
|
|
|
|
/* try to shrink buffer... */
|
|
ptr = (unsigned char *) realloc(datafile_buffer, bufpos);
|
|
if (ptr != NULL)
|
|
datafile_buffer = ptr;
|
|
|
|
BZ2_bzclose(bzf);
|
|
return;
|
|
}
|
|
|
|
/* drop through and try for an gzip compressed or uncompressed datafile... */
|
|
#endif
|
|
|
|
#ifdef ZLIB_SUPPORT
|
|
gzfilename = malloc(strlen(fname) + 4);
|
|
strcpy(gzfilename, fname);
|
|
strcat(gzfilename, ".gz");
|
|
gzf = gzopen(gzfilename, "rb");
|
|
free(gzfilename);
|
|
gzfilename = NULL;
|
|
|
|
if (gzf != NULL) {
|
|
int bufsize = 0;
|
|
int bufpos = 0;
|
|
unsigned char *ptr;
|
|
do {
|
|
int br;
|
|
if (bufpos >= bufsize) {
|
|
bufsize += 1024 * 1024;
|
|
datafile_buffer = (unsigned char *) realloc(datafile_buffer, bufsize);
|
|
if (datafile_buffer == NULL) {
|
|
perror("realloc()");
|
|
exit(42);
|
|
}
|
|
}
|
|
|
|
br = gzread(gzf, datafile_buffer + bufpos, bufsize - bufpos);
|
|
if (br == -1) {
|
|
fprintf(stderr, "gzread failed.\n");
|
|
exit(42);
|
|
}
|
|
|
|
bufpos += br;
|
|
} while (!gzeof(gzf));
|
|
|
|
/* try to shrink buffer... */
|
|
ptr = (unsigned char *) realloc(datafile_buffer, bufpos);
|
|
if (ptr != NULL)
|
|
datafile_buffer = ptr;
|
|
|
|
gzclose(gzf);
|
|
return;
|
|
}
|
|
|
|
/* drop through and try for an uncompressed datafile... */
|
|
#endif
|
|
|
|
fd = open(fname, O_RDONLY | O_BINARY);
|
|
if (fd == -1) {
|
|
fprintf(stderr, "can't open %s:", fname);
|
|
perror("");
|
|
exit(42);
|
|
}
|
|
|
|
len = filelength(fd);
|
|
datafile_buffer = (unsigned char *) malloc(len);
|
|
if (datafile_buffer == NULL) {
|
|
perror("malloc()");
|
|
close(fd);
|
|
exit(42);
|
|
}
|
|
|
|
if (read(fd, datafile_buffer, len) != len) {
|
|
perror("read()");
|
|
close(fd);
|
|
exit(42);
|
|
}
|
|
|
|
close(fd);
|
|
}
|
|
|
|
|
|
int init_program(int argc, char *argv[], char *pal)
|
|
{
|
|
char *netarg = NULL;
|
|
unsigned char *handle = (unsigned char *) NULL;
|
|
int c1 = 0, c2 = 0;
|
|
int load_flag = 0;
|
|
int force2, force3;
|
|
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
|
|
};
|
|
|
|
#ifdef USE_NET
|
|
memset(&net_info, 0, sizeof(net_info));
|
|
#endif
|
|
|
|
#ifdef DOS
|
|
if (__djgpp_nearptr_enable() == 0)
|
|
return 1;
|
|
#endif
|
|
|
|
srand(time(NULL));
|
|
|
|
if (hook_keyb_handler() != 0)
|
|
return 1;
|
|
|
|
memset(&main_info, 0, sizeof(main_info));
|
|
|
|
strcpy(datfile_name, DATA_PATH);
|
|
|
|
force2 = force3 = 0;
|
|
|
|
if (argc > 1) {
|
|
for (c1 = 1; c1 < argc; c1++) {
|
|
if (stricmp(argv[c1], "-nosound") == 0)
|
|
main_info.no_sound = 1;
|
|
else if (stricmp(argv[c1], "-musicnosound") == 0)
|
|
main_info.music_no_sound = 1;
|
|
else if (stricmp(argv[c1], "-nogore") == 0)
|
|
main_info.no_gore = 1;
|
|
else if (stricmp(argv[c1], "-noflies") == 0)
|
|
flies_enabled = 0;
|
|
else if (stricmp(argv[c1], "-nojoy") == 0)
|
|
main_info.joy_enabled = 0;
|
|
else if (stricmp(argv[c1], "-fireworks") == 0)
|
|
main_info.fireworks = 1;
|
|
#ifdef USE_SDL
|
|
else if (stricmp(argv[c1], "-fullscreen") == 0)
|
|
fs_toggle();
|
|
#endif
|
|
else if (stricmp(argv[c1], "-scaleup") == 0)
|
|
set_scaling(1);
|
|
else if (stricmp(argv[c1], "-mirror") == 0)
|
|
flip = 1;
|
|
else if (stricmp(argv[c1], "-dat") == 0) {
|
|
if (c1 < (argc - 1)) {
|
|
FILE *f;
|
|
|
|
if ((f = fopen(argv[c1 + 1], "rb")) != NULL) {
|
|
fclose(f);
|
|
strcpy(datfile_name, argv[c1 + 1]);
|
|
}
|
|
}
|
|
} else if (stricmp(argv[c1], "-player") == 0) {
|
|
if (c1 < (argc - 1)) {
|
|
if (client_player_num < 0)
|
|
client_player_num = atoi(argv[c1 + 1]);
|
|
}
|
|
#ifdef USE_NET
|
|
} else if (stricmp(argv[c1], "-server") == 0) {
|
|
if (c1 < (argc - 1)) {
|
|
is_server = 1;
|
|
is_net = 1;
|
|
netarg = argv[c1 + 1];
|
|
}
|
|
} else if (stricmp(argv[c1], "-connect") == 0) {
|
|
if (c1 < (argc - 1)) {
|
|
is_server = 0;
|
|
is_net = 1;
|
|
netarg = argv[c1 + 1];
|
|
}
|
|
#endif
|
|
} else if (stricmp(argv[c1], "-mouse") == 0) {
|
|
if (c1 < (argc - 1)) {
|
|
if (stricmp(argv[c1 + 1], "2") == 0)
|
|
force2 = 1;
|
|
if (stricmp(argv[c1 + 1], "3") == 0)
|
|
force3 = 1;
|
|
}
|
|
}
|
|
else if (strstr(argv[1],"-v")) {
|
|
printf("jumpnbump %s compiled %s at %s with",JNB_VERSION,__DATE__,__TIME__);
|
|
#ifndef USE_NET
|
|
printf("out");
|
|
#endif
|
|
printf(" network support.\n");
|
|
return 1;
|
|
}
|
|
else if (strstr(argv[1],"-h")) {
|
|
printf("Usage: jumpnbump [OPTION]...\n");
|
|
printf("\n");
|
|
printf(" -h this help\n");
|
|
printf(" -v print version\n");
|
|
printf(" -dat level.dat play a different level\n");
|
|
#ifdef USE_NET
|
|
printf(" -server playercount start as server waiting for players\n");
|
|
printf(" -connect host connect to server\n");
|
|
#endif
|
|
printf(" -player num set main player to num (0-3). Needed for networking\n");
|
|
printf(" -fireworks screensaver mode\n");
|
|
printf(" -fullscreen run in fullscreen mode\n");
|
|
printf(" -nosound play without sound\n");
|
|
printf(" -nogore play without blood\n");
|
|
printf(" -noflies disable flies\n");
|
|
printf(" -mirror play with mirrored level\n");
|
|
printf(" -scaleup play with doubled resolution (800x512)\n");
|
|
printf(" -musicnosound play with music but without sound\n");
|
|
printf("\n");
|
|
return 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
preread_datafile(datfile_name);
|
|
|
|
#if 0
|
|
/** It should not be necessary to assign a default player number here. The
|
|
server assigns one in init_server, the client gets one assigned by the server,
|
|
all provided the user didn't choose one on the commandline. */
|
|
if (is_net) {
|
|
if (client_player_num < 0)
|
|
client_player_num = 0;
|
|
player[client_player_num].enabled = 1;
|
|
}
|
|
#endif
|
|
|
|
main_info.pob_backbuf[0] = malloc(screen_pitch*screen_height);
|
|
main_info.pob_backbuf[1] = malloc(screen_pitch*screen_height);
|
|
|
|
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"))) {
|
|
/* error */
|
|
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"))) {
|
|
/* error */
|
|
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"))) {
|
|
/* error */
|
|
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"))) {
|
|
/* error */
|
|
return 1;
|
|
}
|
|
|
|
if (read_level() != 0) {
|
|
strcpy(main_info.error_str, "Error loading 'levelmap.txt', aborting...\n");
|
|
return 1;
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
if ((background_pic = malloc(JNB_WIDTH*JNB_HEIGHT)) == NULL)
|
|
return 1;
|
|
if ((mask_pic = malloc(JNB_WIDTH*JNB_HEIGHT)) == NULL)
|
|
return 1;
|
|
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);
|
|
|
|
init_inputs();
|
|
|
|
recalculate_gob(&font_gobs, pal);
|
|
|
|
if (main_info.joy_enabled == 1 && main_info.fireworks == 0) {
|
|
load_flag = 0;
|
|
put_text(0, 200, 40, "JOYSTICK CALIBRATION", 2);
|
|
put_text(0, 200, 100, "Move the joystick to the", 2);
|
|
put_text(0, 200, 115, "UPPER LEFT", 2);
|
|
put_text(0, 200, 130, "and press button A", 2);
|
|
put_text(0, 200, 200, "Or press ESC to use", 2);
|
|
put_text(0, 200, 215, "previous settings", 2);
|
|
if (calib_joy(0) != 0)
|
|
load_flag = 1;
|
|
else {
|
|
register_background(NULL, NULL);
|
|
|
|
main_info.view_page = 1;
|
|
flippage(1);
|
|
|
|
wait_vrt(0);
|
|
|
|
put_text(1, 200, 40, "JOYSTICK CALIBRATION", 2);
|
|
put_text(1, 200, 100, "Move the joystick to the", 2);
|
|
put_text(1, 200, 115, "LOWER RIGHT", 2);
|
|
put_text(1, 200, 130, "and press button A", 2);
|
|
put_text(1, 200, 200, "Or press ESC to use", 2);
|
|
put_text(1, 200, 215, "previous settings", 2);
|
|
if (calib_joy(1) != 0)
|
|
load_flag = 1;
|
|
else {
|
|
register_background(NULL, NULL);
|
|
flippage(0);
|
|
|
|
wait_vrt(0);
|
|
|
|
put_text(0, 200, 40, "JOYSTICK CALIBRATION", 2);
|
|
put_text(0, 200, 100, "Move the joystick to the", 2);
|
|
put_text(0, 200, 115, "CENTER", 2);
|
|
put_text(0, 200, 130, "and press button A", 2);
|
|
put_text(0, 200, 200, "Or press ESC to use", 2);
|
|
put_text(0, 200, 215, "previous settings", 2);
|
|
if (calib_joy(2) != 0)
|
|
load_flag = 1;
|
|
else {
|
|
if (joy.calib_data.x1 == joy.calib_data.x2)
|
|
joy.calib_data.x1 -= 10;
|
|
if (joy.calib_data.x3 == joy.calib_data.x2)
|
|
joy.calib_data.x3 += 10;
|
|
if (joy.calib_data.y1 == joy.calib_data.y2)
|
|
joy.calib_data.y1 -= 10;
|
|
if (joy.calib_data.y3 == joy.calib_data.y2)
|
|
joy.calib_data.y3 += 10;
|
|
write_calib_data();
|
|
}
|
|
}
|
|
}
|
|
if (load_flag == 1) {
|
|
if ((handle = dat_open("calib.dat")) == 0) {
|
|
strcpy(main_info.error_str, "Error loading 'calib.dat', aborting...\n");
|
|
return 1;
|
|
}
|
|
joy.calib_data.x1 = (handle[0]) + (handle[1] << 8) + (handle[2] << 16) + (handle[3] << 24); handle += 4;
|
|
joy.calib_data.x2 = (handle[0]) + (handle[1] << 8) + (handle[2] << 16) + (handle[3] << 24); handle += 4;
|
|
joy.calib_data.x3 = (handle[0]) + (handle[1] << 8) + (handle[2] << 16) + (handle[3] << 24); handle += 4;
|
|
joy.calib_data.y1 = (handle[0]) + (handle[1] << 8) + (handle[2] << 16) + (handle[3] << 24); handle += 4;
|
|
joy.calib_data.y2 = (handle[0]) + (handle[1] << 8) + (handle[2] << 16) + (handle[3] << 24); handle += 4;
|
|
joy.calib_data.y3 = (handle[0]) + (handle[1] << 8) + (handle[2] << 16) + (handle[3] << 24); handle += 4;
|
|
}
|
|
}
|
|
|
|
#ifdef USE_NET
|
|
if (is_net) {
|
|
if (is_server) {
|
|
init_server(netarg);
|
|
} else {
|
|
connect_to_server(netarg);
|
|
}
|
|
}
|
|
#endif
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
void deinit_program(void)
|
|
{
|
|
#ifdef DOS
|
|
__dpmi_regs regs;
|
|
#endif
|
|
|
|
dj_stop();
|
|
dj_free_mod(MOD_MENU);
|
|
dj_free_mod(MOD_GAME);
|
|
dj_free_sfx(SFX_DEATH);
|
|
dj_free_sfx(SFX_SPRING);
|
|
dj_free_sfx(SFX_SPLASH);
|
|
dj_deinit();
|
|
|
|
if (background_pic != 0)
|
|
free(background_pic);
|
|
if (mask_pic != 0)
|
|
free(mask_pic);
|
|
|
|
remove_keyb_handler();
|
|
|
|
#ifdef DOS
|
|
regs.x.ax = 0x3;
|
|
__dpmi_int(0x10, ®s);
|
|
#endif
|
|
|
|
if (main_info.error_str[0] != 0) {
|
|
printf(main_info.error_str);
|
|
#ifdef _MSC_VER
|
|
MessageBox(0, main_info.error_str, "Jump'n'Bump", 0);
|
|
#endif
|
|
exit(1);
|
|
} else
|
|
exit(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
|
|
}
|
|
|
|
|
|
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;
|
|
}
|
|
|
|
|
|
void write_calib_data(void)
|
|
{
|
|
FILE *handle;
|
|
int c1;
|
|
int len, num;
|
|
char *mem;
|
|
int ofs;
|
|
|
|
if ((handle = fopen(datfile_name, "rb")) == NULL)
|
|
return;
|
|
len = filelength(fileno(handle));
|
|
if ((mem = malloc(len)) == NULL)
|
|
return;
|
|
fread(mem, 1, len, handle);
|
|
fclose(handle);
|
|
|
|
ofs = 4;
|
|
num = *(int *) (&mem[0]);
|
|
for (c1 = 0; c1 < num; c1++) {
|
|
if (strnicmp(&mem[ofs], "calib.dat", strlen("calib.dat")) == 0) {
|
|
ofs = *(int *) (&mem[ofs + 12]);
|
|
break;
|
|
}
|
|
ofs += 20;
|
|
}
|
|
|
|
mem[ofs] = joy.calib_data.x1 & 0xff;
|
|
mem[ofs + 1] = (joy.calib_data.x1 >> 8) & 0xff;
|
|
mem[ofs + 2] = (joy.calib_data.x1 >> 16) & 0xff;
|
|
mem[ofs + 3] = (joy.calib_data.x1 >> 24) & 0xff;
|
|
mem[ofs + 4] = joy.calib_data.x2 & 0xff;
|
|
mem[ofs + 5] = (joy.calib_data.x2 >> 8) & 0xff;
|
|
mem[ofs + 6] = (joy.calib_data.x2 >> 16) & 0xff;
|
|
mem[ofs + 7] = (joy.calib_data.x2 >> 24) & 0xff;
|
|
mem[ofs + 8] = joy.calib_data.x3 & 0xff;
|
|
mem[ofs + 9] = (joy.calib_data.x3 >> 8) & 0xff;
|
|
mem[ofs + 10] = (joy.calib_data.x3 >> 16) & 0xff;
|
|
mem[ofs + 11] = (joy.calib_data.x3 >> 24) & 0xff;
|
|
mem[ofs + 12] = joy.calib_data.y1 & 0xff;
|
|
mem[ofs + 13] = (joy.calib_data.y1 >> 8) & 0xff;
|
|
mem[ofs + 14] = (joy.calib_data.y1 >> 16) & 0xff;
|
|
mem[ofs + 15] = (joy.calib_data.y1 >> 24) & 0xff;
|
|
mem[ofs + 16] = joy.calib_data.y2 & 0xff;
|
|
mem[ofs + 17] = (joy.calib_data.y2 >> 8) & 0xff;
|
|
mem[ofs + 18] = (joy.calib_data.y2 >> 16) & 0xff;
|
|
mem[ofs + 19] = (joy.calib_data.y2 >> 24) & 0xff;
|
|
mem[ofs + 20] = joy.calib_data.y3 & 0xff;
|
|
mem[ofs + 21] = (joy.calib_data.y3 >> 8) & 0xff;
|
|
mem[ofs + 22] = (joy.calib_data.y3 >> 16) & 0xff;
|
|
mem[ofs + 23] = (joy.calib_data.y3 >> 24) & 0xff;
|
|
|
|
if ((handle = fopen(datfile_name, "wb")) == NULL)
|
|
return;
|
|
fwrite(mem, 1, len, handle);
|
|
fclose(handle);
|
|
|
|
}
|