Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * main.c
  3.  * Copyright (C) 1998 Brainchild Design - http://brainchilddesign.com/
  4.  *
  5.  * Copyright (C) 2001 Chuck Mason <cemason@users.sourceforge.net>
  6.  *
  7.  * Copyright (C) 2002 Florian Schulze <crow@icculus.org>
  8.  *
  9.  * This file is part of Jump'n'Bump.
  10.  *
  11.  * Jump'n'Bump is free software; you can redistribute it and/or modify
  12.  * it under the terms of the GNU General Public License as published by
  13.  * the Free Software Foundation; either version 2 of the License, or
  14.  * (at your option) any later version.
  15.  *
  16.  * Jump'n'Bump is distributed in the hope that it will be useful,
  17.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  19.  * GNU General Public License for more details.
  20.  *
  21.  * You should have received a copy of the GNU General Public License
  22.  * along with this program; if not, write to the Free Software
  23.  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  24.  */
  25.  
  26. #include "globals.h"
  27. #include <fcntl.h>
  28. #ifndef _MSC_VER
  29. #include <unistd.h>
  30. #endif
  31.  
  32. #ifdef BZLIB_SUPPORT
  33. #include "bzlib.h"
  34. #endif
  35.  
  36. #ifdef ZLIB_SUPPORT
  37. #include "zlib.h"
  38. #endif
  39.  
  40. #ifdef USE_NET
  41. #include "SDL_net.h"
  42. #endif /* USE_NET */
  43.  
  44. #ifndef M_PI
  45. #define M_PI            3.14159265358979323846
  46. #endif
  47.  
  48. gob_t rabbit_gobs = { 0 };
  49. gob_t font_gobs = { 0 };
  50. gob_t object_gobs = { 0 };
  51. gob_t number_gobs = { 0 };
  52.  
  53. main_info_t main_info;
  54. player_t player[JNB_MAX_PLAYERS];
  55. player_anim_t player_anims[7];
  56. object_t objects[NUM_OBJECTS];
  57. joy_t joy;
  58. mouse_t mouse;
  59.  
  60. char datfile_name[2048];
  61.  
  62. char *background_pic;
  63. char *mask_pic;
  64. int flip = 0;
  65. char pal[768];
  66. char cur_pal[768];
  67.  
  68. int ai[JNB_MAX_PLAYERS];
  69.  
  70. unsigned int ban_map[17][22] = {
  71.         {1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
  72.         {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0},
  73.         {1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0},
  74.         {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1},
  75.         {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1},
  76.         {1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
  77.         {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1},
  78.         {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1},
  79.         {1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1},
  80.         {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 1, 0, 0, 0, 0, 0, 0, 0, 1},
  81.         {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1},
  82.         {1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1},
  83.         {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
  84.         {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1},
  85.         {2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 0, 0, 0, 0, 0, 1, 3, 3, 3, 1, 1, 1},
  86.         {2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
  87.         {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
  88. };
  89.  
  90. #define GET_BAN_MAP_XY(x,y) ban_map[(y) >> 4][(x) >> 4]
  91.  
  92. struct {
  93.         int num_frames;
  94.         int restart_frame;
  95.         struct {
  96.                 int image;
  97.                 int ticks;
  98.         } frame[10];
  99. } object_anims[8] = {
  100.         {
  101.                 6, 0, {
  102.                         {
  103.                         0, 3}, {
  104.                         1, 3}, {
  105.                         2, 3}, {
  106.                         3, 3}, {
  107.                         4, 3}, {
  108.                         5, 3}, {
  109.                         0, 0}, {
  110.                         0, 0}, {
  111.                         0, 0}, {
  112.                         0, 0}
  113.                 }
  114.         }, {
  115.                 9, 0, {
  116.                         {
  117.                         6, 2}, {
  118.                         7, 2}, {
  119.                         8, 2}, {
  120.                         9, 2}, {
  121.                         10, 2}, {
  122.                         11, 2}, {
  123.                         12, 2}, {
  124.                         13, 2}, {
  125.                         14, 2}, {
  126.                         0, 0}
  127.                 }
  128.         }, {
  129.                 5, 0, {
  130.                         {
  131.                         15, 3}, {
  132.                         16, 3}, {
  133.                         16, 3}, {
  134.                         17, 3}, {
  135.                         18, 3}, {
  136.                         19, 3}, {
  137.                         0, 0}, {
  138.                         0, 0}, {
  139.                         0, 0}, {
  140.                         0, 0}
  141.                 }
  142.         }, {
  143.                 10, 0, {
  144.                         {
  145.                         20, 2}, {
  146.                         21, 2}, {
  147.                         22, 2}, {
  148.                         23, 2}, {
  149.                         24, 2}, {
  150.                         25, 2}, {
  151.                         24, 2}, {
  152.                         23, 2}, {
  153.                         22, 2}, {
  154.                         21, 2}
  155.                 }
  156.         }, {
  157.                 10, 0, {
  158.                         {
  159.                         26, 2}, {
  160.                         27, 2}, {
  161.                         28, 2}, {
  162.                         29, 2}, {
  163.                         30, 2}, {
  164.                         31, 2}, {
  165.                         30, 2}, {
  166.                         29, 2}, {
  167.                         28, 2}, {
  168.                         27, 2}
  169.                 }
  170.         }, {
  171.                 10, 0, {
  172.                         {
  173.                         32, 2}, {
  174.                         33, 2}, {
  175.                         34, 2}, {
  176.                         35, 2}, {
  177.                         36, 2}, {
  178.                         37, 2}, {
  179.                         36, 2}, {
  180.                         35, 2}, {
  181.                         34, 2}, {
  182.                         33, 2}
  183.                 }
  184.         }, {
  185.                 10, 0, {
  186.                         {
  187.                         38, 2}, {
  188.                         39, 2}, {
  189.                         40, 2}, {
  190.                         41, 2}, {
  191.                         42, 2}, {
  192.                         43, 2}, {
  193.                         42, 2}, {
  194.                         41, 2}, {
  195.                         40, 2}, {
  196.                         39, 2}
  197.                 }
  198.         }, {
  199.                 4, 0, {
  200.                         {
  201.                         76, 4}, {
  202.                         77, 4}, {
  203.                         78, 4}, {
  204.                         79, 4}, {
  205.                         0, 0}, {
  206.                         0, 0}, {
  207.                         0, 0}, {
  208.                         0, 0}, {
  209.                         0, 0}, {
  210.                         0, 0}
  211.                 }
  212.         }
  213. };
  214.  
  215. int flies_enabled = 1;
  216.  
  217. struct {
  218.         int x, y;
  219.         int old_x, old_y;
  220.         int old_draw_x, old_draw_y;
  221.         int back[2];
  222.         int back_defined[2];
  223. } flies[NUM_FLIES];
  224.  
  225. struct {
  226.         struct {
  227.                 short num_pobs;
  228.                 struct {
  229.                         int x, y;
  230.                         int image;
  231.                         gob_t *pob_data;
  232.                 } pobs[NUM_LEFTOVERS];
  233.         } page[2];
  234. } leftovers;
  235.  
  236. int pogostick, bunnies_in_space, jetpack, lord_of_the_flies, blood_is_thicker_than_water;
  237.  
  238.  
  239. #ifndef _MSC_VER
  240. int filelength(int handle)
  241. {
  242.         struct stat buf;
  243.  
  244.         if (fstat(handle, &buf) == -1) {
  245.                 perror("filelength");
  246.                 exit(EXIT_FAILURE);
  247.         }
  248.  
  249.         return buf.st_size;
  250. }
  251. #endif
  252.  
  253.  
  254. /* networking shite. */
  255.  
  256. int client_player_num = -1;
  257. int is_server = 1;
  258. int is_net = 0;
  259.  
  260. #ifdef USE_NET
  261. TCPsocket sock = NULL;
  262. SDLNet_SocketSet socketset = NULL;
  263.  
  264. typedef struct
  265. {
  266.         TCPsocket sock;
  267.         IPaddress addr;
  268.         SDLNet_SocketSet socketset;
  269. } NetInfo;
  270.  
  271. NetInfo net_info[JNB_MAX_PLAYERS];
  272. #endif
  273.  
  274. typedef struct
  275. {
  276.         unsigned long cmd;
  277.         long arg;
  278.         long arg2;
  279.         long arg3;
  280.         long arg4;
  281. } NetPacket;
  282.  
  283. #define NETPKTBUFSIZE (4 + 4 + 4 + 4 + 4)
  284.  
  285. #define NETCMD_NACK         (0xF00DF00D + 0)
  286. #define NETCMD_ACK          (0xF00DF00D + 1)
  287. #define NETCMD_HELLO        (0xF00DF00D + 2)
  288. #define NETCMD_GREENLIGHT   (0xF00DF00D + 3)
  289. #define NETCMD_MOVE         (0xF00DF00D + 4)
  290. #define NETCMD_BYE          (0xF00DF00D + 5)
  291. #define NETCMD_POSITION     (0xF00DF00D + 6)
  292. #define NETCMD_ALIVE        (0xF00DF00D + 7)
  293. #define NETCMD_KILL         (0xF00DF00D + 8)
  294.  
  295.  
  296. #ifdef USE_NET
  297. void bufToPacket(const char *buf, NetPacket *pkt)
  298. {
  299.         SDLNet_Write32(*((Uint32*) (buf +  0)), &pkt->cmd);
  300.         SDLNet_Write32(*((Uint32*) (buf +  4)), &pkt->arg);
  301.         SDLNet_Write32(*((Uint32*) (buf +  8)), &pkt->arg2);
  302.         SDLNet_Write32(*((Uint32*) (buf + 12)), &pkt->arg3);
  303.         SDLNet_Write32(*((Uint32*) (buf + 16)), &pkt->arg4);
  304. /*
  305.         pkt->cmd               =        ntohl(*((unsigned long *) (buf +  0)));
  306.         pkt->arg               = (long) ntohl(*((unsigned long *) (buf +  4)));
  307.         pkt->arg2              = (long) ntohl(*((unsigned long *) (buf +  8)));
  308.         pkt->arg3              = (long) ntohl(*((unsigned long *) (buf + 12)));
  309.         pkt->arg4              = (long) ntohl(*((unsigned long *) (buf + 16)));
  310. */
  311. }
  312.  
  313.  
  314. void packetToBuf(const NetPacket *pkt, char *buf)
  315. {
  316.         *((Uint32*) (buf +  0)) = SDLNet_Read32(&pkt->cmd);
  317.         *((Uint32*) (buf +  4)) = SDLNet_Read32(&pkt->arg);
  318.         *((Uint32*) (buf +  8)) = SDLNet_Read32(&pkt->arg2);
  319.         *((Uint32*) (buf + 12)) = SDLNet_Read32(&pkt->arg3);
  320.         *((Uint32*) (buf + 16)) = SDLNet_Read32(&pkt->arg4);
  321. /*
  322.         *((unsigned long *) (buf +  0)) = htonl(pkt->cmd);
  323.         *((unsigned long *) (buf +  4)) = htonl((unsigned long) pkt->arg);
  324.         *((unsigned long *) (buf +  8)) = htonl((unsigned long) pkt->arg2);
  325.         *((unsigned long *) (buf + 12)) = htonl((unsigned long) pkt->arg3);
  326.         *((unsigned long *) (buf + 16)) = htonl((unsigned long) pkt->arg4);
  327. */
  328. }
  329.  
  330.  
  331. void sendPacketToSock(TCPsocket s, NetPacket *pkt)
  332. {
  333.         int bytes_left = NETPKTBUFSIZE;
  334.         int bw;
  335.         char buf[NETPKTBUFSIZE];
  336.         char *ptr = buf;
  337.  
  338.         packetToBuf(pkt, buf);
  339.         while (bytes_left > 0) {
  340.                 bw = SDLNet_TCP_Send(s, ptr, bytes_left);
  341.                 if (bw < 0) {
  342.                         fprintf(stderr, "SERVER: SDLNet_TCP_Send(): %s\n", SDLNet_GetError());
  343.                         SDLNet_TCP_Close(s);
  344.                         exit(42);
  345.                 } else if (bw == 0) {
  346.                         SDL_Delay(1);
  347.                 } else {
  348.                         bytes_left -= bw;
  349.                         ptr += bw;
  350.                 }
  351.         }
  352. }
  353.  
  354.  
  355. void sendPacket(int playerid, NetPacket *pkt)
  356. {
  357.         if ( (playerid < JNB_MAX_PLAYERS) && (playerid >= 0)) {
  358.                 if ((player[playerid].enabled) && (playerid != client_player_num)) {
  359.                         sendPacketToSock(net_info[playerid].sock, pkt);
  360.                 }
  361.         }
  362. }
  363.  
  364.  
  365. void sendPacketToAll(NetPacket *pkt)
  366. {
  367.         int i;
  368.  
  369.         for (i = 0; i < JNB_MAX_PLAYERS; i++) {
  370.                 sendPacket(i, pkt);
  371.         }
  372. }
  373.  
  374. /** read a packet from the given TCPsocket
  375. Returns -1 if some error occured, 0 if there was no data available and 1 if a
  376. packet was successfully read.
  377. Note: the socket has to be in the supplied socketset.
  378. TODO: this function will bomb if a packet arrives in pieces, there is no
  379. inherent guarantee that the next call will be made on the same socket. */
  380. int grabPacket(TCPsocket s, SDLNet_SocketSet ss, NetPacket *pkt)
  381. {
  382.         static char buf[NETPKTBUFSIZE];
  383.         static int buf_count = 0;
  384.         int rc;
  385.  
  386.         if (SDLNet_CheckSockets(ss, 0) <= 0)
  387.                 return 0;
  388.  
  389.         if(!SDLNet_SocketReady(s))
  390.                 return 0;
  391.  
  392.         rc = SDLNet_TCP_Recv(s, &buf[buf_count], NETPKTBUFSIZE - buf_count);
  393.         if (rc <= 0) {
  394.                 /* closed connection? */
  395.                 return -1;
  396.         } else if (rc != NETPKTBUFSIZE) {
  397.                 /* we got a partial packet. Store what we got in the static buffer and
  398.                 return so that the next call can read the rest. Hopefully. */
  399.                 buf_count = rc;
  400.                 return 0;
  401.         } else {
  402.                 buf_count = 0;
  403.                 bufToPacket(buf, pkt);
  404.                 return 1;
  405.         }
  406. }
  407.  
  408.  
  409. int serverRecvPacket(NetPacket *pkt)
  410. {
  411.         int rc;
  412.         int i;
  413.  
  414.         assert(is_server);
  415.  
  416.         for (i = 0; i < JNB_MAX_PLAYERS; i++) {
  417.                 TCPsocket s = net_info[i].sock;
  418.  
  419.                 if ((i == client_player_num) || (!player[i].enabled))
  420.                         continue;
  421.  
  422.                 rc = grabPacket(s, net_info[i].socketset, pkt);
  423.                 if (rc < 0) {
  424.                         NetPacket pkt;
  425.  
  426.                         player[i].enabled = 0;
  427.                         SDLNet_TCP_Close(s);
  428.                         pkt.cmd = NETCMD_BYE;
  429.                         pkt.arg = i;
  430.                         pkt.arg2 = 0;
  431.                         pkt.arg3 = 0;
  432.                         pkt.arg4 = 0;
  433.                         sendPacketToAll(&pkt);
  434.                 } else if (rc > 0) {
  435.                         return(i);  /* it's all good. */
  436.                 }
  437.         }
  438.  
  439.         return(-1);  /* no packets available currently. */
  440. }
  441.  
  442.  
  443. void wait_for_greenlight(void)
  444. {
  445.         NetPacket pkt;
  446.         int i;
  447.  
  448.         printf("CLIENT: Waiting for greenlight...\n");
  449.  
  450.         do {
  451.                 int rc;
  452.                 while ((rc = grabPacket(sock, socketset, &pkt)) == 0) {
  453.                         SDL_Delay(100);  /* nap and then try again. */
  454.                 }
  455.  
  456.                 if (rc < 0) {
  457.                         printf("CLIENT: Lost connection.\n");
  458.                         SDLNet_TCP_Close(sock);
  459.                         exit(42);
  460.                 }
  461.         } while (pkt.cmd != NETCMD_GREENLIGHT);
  462.  
  463.         printf("CLIENT: Got greenlight.\n");
  464.  
  465.         for (i = 0; i < JNB_MAX_PLAYERS; i++) {
  466.                 if (pkt.arg & (1 << i)) {
  467.                         printf("CLIENT: There is a player #%d.\n", i);
  468.                         player[i].enabled = 1;
  469.                 }
  470.         }
  471. }
  472.  
  473.  
  474. static int buggered_off = 0;
  475.  
  476.  
  477. void tellServerGoodbye(void)
  478. {
  479.         NetPacket pkt;
  480.  
  481.         if (!buggered_off) {
  482.                 buggered_off = 1;
  483.                 pkt.cmd = NETCMD_BYE;
  484.                 pkt.arg = client_player_num;
  485.                 pkt.arg2 = 0;
  486.                 pkt.arg3 = 0;
  487.                 pkt.arg4 = 0;
  488.                 sendPacketToSock(sock, &pkt);
  489.         }
  490. }
  491. #endif /* USE_NET */
  492.  
  493.  
  494. void processMovePacket(NetPacket *pkt)
  495. {
  496.         int playerid = pkt->arg;
  497.         int movetype = ((pkt->arg2 >> 16) & 0xFF);
  498.         int newval   = ((pkt->arg2 >>  0) & 0xFF);
  499.  
  500.         if (movetype == MOVEMENT_LEFT) {
  501.                 player[playerid].action_left = newval;
  502.         } else if (movetype == MOVEMENT_RIGHT) {
  503.                 player[playerid].action_right = newval;
  504.         } else if (movetype == MOVEMENT_UP) {
  505.                 player[playerid].action_up = newval;
  506.         } else {
  507.                 printf("bogus MOVE packet!\n");
  508.         }
  509.  
  510.         player[playerid].x = pkt->arg3;
  511.         player[playerid].y = pkt->arg4;
  512. }
  513.  
  514.  
  515. void tellServerPlayerMoved(int playerid, int movement_type, int newval)
  516. {
  517.         NetPacket pkt;
  518.  
  519.         pkt.cmd = NETCMD_MOVE;
  520.         pkt.arg = playerid;
  521.         pkt.arg2 = ( ((movement_type & 0xFF) << 16) | ((newval & 0xFF) << 0) );
  522.         pkt.arg3 = player[playerid].x;
  523.         pkt.arg4 = player[playerid].y;
  524.  
  525.         if (is_server) {
  526.                 processMovePacket(&pkt);
  527. #ifdef USE_NET
  528.                 if (is_net)
  529.                         sendPacketToAll(&pkt);
  530.         } else {
  531.                 sendPacketToSock(sock, &pkt);
  532. #endif
  533.         }
  534. }
  535.  
  536.  
  537. #ifdef USE_NET
  538. void tellServerNewPosition(void)
  539. {
  540.         NetPacket pkt;
  541.         pkt.cmd = NETCMD_POSITION;
  542.         pkt.arg = client_player_num;
  543.         pkt.arg2 = player[client_player_num].x;
  544.         pkt.arg3 = player[client_player_num].y;
  545.  
  546.         if (is_server) {
  547.                 sendPacketToAll(&pkt);
  548.         } else {
  549.                 sendPacketToSock(sock, &pkt);
  550.         }
  551. }
  552. #endif /* USE_NET */
  553.  
  554.  
  555. void processKillPacket(NetPacket *pkt)
  556. {
  557.         int c1 = pkt->arg;
  558.         int c2 = pkt->arg2;
  559.         int x = pkt->arg3;
  560.         int y = pkt->arg4;
  561.         int c4 = 0;
  562.         int s1 = 0;
  563.  
  564.         player[c1].y_add = -player[c1].y_add;
  565.         if (player[c1].y_add > -262144L)
  566.                 player[c1].y_add = -262144L;
  567.         player[c1].jump_abort = 1;
  568.         player[c2].dead_flag = 1;
  569.         if (player[c2].anim != 6) {
  570.                 player[c2].anim = 6;
  571.                 player[c2].frame = 0;
  572.                 player[c2].frame_tick = 0;
  573.                 player[c2].image = player_anims[player[c2].anim].frame[player[c2].frame].image + player[c2].direction * 9;
  574.                 if (main_info.no_gore == 0) {
  575.                         for (c4 = 0; c4 < 6; c4++)
  576.                                 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);
  577.                         for (c4 = 0; c4 < 6; c4++)
  578.                                 add_object(OBJ_FLESH, (x >> 16) + 6 + rnd(5), (y >> 16) + 6 + rnd(5), (rnd(65535) - 32768) * 3, (rnd(65535) - 32768) * 3, 0, 76);
  579.                         for (c4 = 0; c4 < 6; c4++)
  580.                                 add_object(OBJ_FLESH, (x >> 16) + 6 + rnd(5), (y >> 16) + 6 + rnd(5), (rnd(65535) - 32768) * 3, (rnd(65535) - 32768) * 3, 0, 77);
  581.                         for (c4 = 0; c4 < 8; c4++)
  582.                                 add_object(OBJ_FLESH, (x >> 16) + 6 + rnd(5), (y >> 16) + 6 + rnd(5), (rnd(65535) - 32768) * 3, (rnd(65535) - 32768) * 3, 0, 78);
  583.                         for (c4 = 0; c4 < 10; c4++)
  584.                                 add_object(OBJ_FLESH, (x >> 16) + 6 + rnd(5), (y >> 16) + 6 + rnd(5), (rnd(65535) - 32768) * 3, (rnd(65535) - 32768) * 3, 0, 79);
  585.                 }
  586.                 dj_play_sfx(SFX_DEATH, (unsigned short)(SFX_DEATH_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
  587.                 player[c1].bumps++;
  588.                 player[c1].bumped[c2]++;
  589.                 s1 = player[c1].bumps % 100;
  590.                 add_leftovers(0, 360, 34 + c1 * 64, s1 / 10, &number_gobs);
  591.                 add_leftovers(1, 360, 34 + c1 * 64, s1 / 10, &number_gobs);
  592.                 add_leftovers(0, 376, 34 + c1 * 64, s1 - (s1 / 10) * 10, &number_gobs);
  593.                 add_leftovers(1, 376, 34 + c1 * 64, s1 - (s1 / 10) * 10, &number_gobs);
  594.         }
  595. }
  596.  
  597.  
  598. #ifdef USE_NET
  599. void processPositionPacket(NetPacket *pkt)
  600. {
  601.         int playerid = pkt->arg;
  602.  
  603.         player[playerid].x = pkt->arg2;
  604.         player[playerid].y = pkt->arg3;
  605. }
  606.  
  607.  
  608. void processAlivePacket(NetPacket *pkt)
  609. {
  610.         int playerid = pkt->arg;
  611.  
  612.         player[playerid].dead_flag = 0;
  613.         player[playerid].x = pkt->arg2;
  614.         player[playerid].y = pkt->arg3;
  615. }
  616.  
  617.  
  618. void serverTellEveryoneGoodbye(void)
  619. {
  620.         int i;
  621.  
  622.         if (!buggered_off) {
  623.                 buggered_off = 1;
  624.                 for (i = 0; i < JNB_MAX_PLAYERS; i++) {
  625.                         if (player[i].enabled) {
  626.                                 NetPacket pkt;
  627.  
  628.                                 pkt.cmd = NETCMD_BYE;
  629.                                 pkt.arg = i;
  630.                                 pkt.arg2 = 0;
  631.                                 pkt.arg3 = 0;
  632.                                 pkt.arg4 = 0;
  633.                                 sendPacketToAll(&pkt);
  634.                         }
  635.                 }
  636.         }
  637. }
  638.  
  639.  
  640. int server_said_bye = 0;
  641.  
  642.  
  643. int update_players_from_server(void)
  644. {
  645.         NetPacket pkt;
  646.         int rc;
  647.  
  648.         assert(!is_server);
  649.  
  650.         while ((rc = grabPacket(sock, socketset, &pkt)) != 0) {
  651.                 if (rc < 0) {
  652.                         printf("CLIENT: Lost connection.\n");
  653.                         pkt.cmd = NETCMD_BYE;
  654.                         pkt.arg = client_player_num;
  655.                 }
  656.  
  657.                 if (pkt.cmd == NETCMD_BYE) {
  658.                         if (pkt.arg == client_player_num) {
  659.                                 SDLNet_FreeSocketSet(socketset);
  660.                                 SDLNet_TCP_Close(sock);
  661.                                 sock = NULL;
  662.                                 server_said_bye = 1;
  663.                                 return(0);
  664.                         } else {
  665.                                 player[pkt.arg].enabled = 0;
  666.                         }
  667.                 } else if (pkt.cmd == NETCMD_MOVE) {
  668.                         processMovePacket(&pkt);
  669.                 } else if (pkt.cmd == NETCMD_ALIVE) {
  670.                         processAlivePacket(&pkt);
  671.                 } else if (pkt.cmd == NETCMD_POSITION) {
  672.                         processPositionPacket(&pkt);
  673.                 } else if (pkt.cmd == NETCMD_KILL) {
  674.                         processKillPacket(&pkt);
  675.                 } else {
  676.                         printf("CLIENT: Got an unknown packet: 0x%lX.\n", pkt.cmd);
  677.                 }
  678.         }
  679.  
  680.         return(1);
  681. }
  682.  
  683.  
  684. void serverSendAlive(int playerid)
  685. {
  686.         NetPacket pkt;
  687.  
  688.         assert(is_server);
  689.         pkt.cmd = NETCMD_ALIVE;
  690.         pkt.arg = playerid;
  691.         pkt.arg2 = player[playerid].x;
  692.         pkt.arg3 = player[playerid].y;
  693.         sendPacketToAll(&pkt);
  694. }
  695. #endif /* USE_NET */
  696.  
  697.  
  698. void serverSendKillPacket(int killer, int victim)
  699. {
  700.         NetPacket pkt;
  701.  
  702.         assert(is_server);
  703.         pkt.cmd = NETCMD_KILL;
  704.         pkt.arg = killer;
  705.         pkt.arg2 = victim;
  706.         pkt.arg3 = player[victim].x;
  707.         pkt.arg4 = player[victim].y;
  708.         processKillPacket(&pkt);
  709. #ifdef USE_NET
  710.         if (is_net)
  711.                 sendPacketToAll(&pkt);
  712. #endif
  713. }
  714.  
  715.  
  716. #ifdef USE_NET
  717. void update_players_from_clients(void)
  718. {
  719.         int i;
  720.         NetPacket pkt;
  721.         int playerid;
  722.  
  723.         assert(is_server);
  724.  
  725.         while ((playerid = serverRecvPacket(&pkt)) >= 0) {
  726.                 if (pkt.cmd == NETCMD_BYE) {
  727.                         pkt.arg = playerid;  /* just in case. */
  728.                         sendPacketToAll(&pkt);
  729.                         player[playerid].enabled = 0;
  730.                         SDLNet_FreeSocketSet(net_info[playerid].socketset);
  731.                         SDLNet_TCP_Close(net_info[playerid].sock);
  732.                 } else if (pkt.cmd == NETCMD_POSITION) {
  733.                         pkt.arg = playerid;  /* just in case. */
  734.                         processPositionPacket(&pkt);
  735.                         for (i = 0; i < JNB_MAX_PLAYERS; i++) {
  736.                                 if (i != playerid) {
  737.                                         sendPacket(i, &pkt);
  738.                                 }
  739.                         }
  740.                 } else if (pkt.cmd == NETCMD_MOVE) {
  741.                         pkt.arg = playerid;  /* just in case. */
  742.                         /*
  743.                         pkt.arg3 = player[playerid].x;
  744.                         pkt.arg4 = player[playerid].y;
  745.                         */
  746.                         processMovePacket(&pkt);
  747.                         sendPacketToAll(&pkt);
  748.                 } else {
  749.                         printf("SERVER: Got unknown packet (0x%lX).\n", pkt.cmd);
  750.                 }
  751.         }
  752. }
  753.  
  754.  
  755. void init_server(const char *netarg)
  756. {
  757.         NetPacket pkt;
  758.         IPaddress addr;
  759.         int i;
  760.         int wait_for_clients = ((netarg == NULL) ? 0 : atoi(netarg));
  761.         char *ipstr;
  762.  
  763.         /** assign player number zero as default for the server */
  764.         if(-1 == client_player_num)
  765.                 client_player_num = 0;
  766.  
  767.         if ((wait_for_clients >= JNB_MAX_PLAYERS) || (wait_for_clients < 0)) {
  768.                 printf("SERVER: Waiting for bogus client count (%d).\n", wait_for_clients);
  769.                 exit(42);
  770.         }
  771.  
  772.         if (SDLNet_Init() < 0) {
  773.                 exit(42);
  774.         }
  775.         atexit(SDLNet_Quit);
  776.  
  777.         SDLNet_ResolveHost(&addr, NULL, JNB_INETPORT);
  778.         ipstr = SDLNet_ResolveIP(&addr);
  779.         SDLNet_ResolveHost(&addr, ipstr, JNB_INETPORT);
  780.         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);
  781.         net_info[client_player_num].addr = addr;
  782.  
  783.         addr.host = INADDR_ANY;
  784.         sock = SDLNet_TCP_Open(&addr);
  785.         if (sock == NULL) {
  786.                 fprintf(stderr, "SERVER: SDLNet_TCP_Open(): %s\n", SDLNet_GetError());
  787.                 exit(42);
  788.         }
  789.  
  790.         player[client_player_num].enabled = 1;
  791.  
  792.         printf("SERVER: waiting for (%d) clients...\n", wait_for_clients);
  793.  
  794.         socketset = SDLNet_AllocSocketSet(JNB_MAX_PLAYERS + 1);
  795.         SDLNet_TCP_AddSocket(socketset, sock);
  796.  
  797.         while (wait_for_clients > 0)
  798.         {
  799.                 char buf[NETPKTBUFSIZE];
  800.                 IPaddress *from;
  801.                 int negatory = 1;
  802.                 int br;
  803.                 TCPsocket s;
  804.  
  805.                 /* Wait for events */
  806.                 SDLNet_CheckSockets(socketset, ~0);
  807.                 if ( SDLNet_SocketReady(sock) ) {
  808.                         s = SDLNet_TCP_Accept(sock);
  809.  
  810.                         if (s == NULL)
  811.                         {
  812.                                 fprintf(stderr, "SERVER: SDLNet_TCP_Accept(): %s", SDLNet_GetError());
  813.                                 SDLNet_TCP_Close(sock);
  814.                                 exit(42);
  815.                         }
  816.                 } else
  817.                         continue;
  818.  
  819.                 br = SDLNet_TCP_Recv(s, buf, NETPKTBUFSIZE);
  820.                 if (br < 0) {
  821.                         fprintf(stderr, "SERVER: SDLNet_TCP_Recv(): %s\n", SDLNet_GetError());
  822.                         SDLNet_TCP_Close(s);
  823.                         SDLNet_TCP_Close(sock);
  824.                         exit(42);
  825.                 }
  826.  
  827.                 from = SDLNet_TCP_GetPeerAddress(s);
  828.                 ipstr = SDLNet_ResolveIP(from);
  829.                 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);
  830.  
  831.                 if (br != NETPKTBUFSIZE) {
  832.                         printf("SERVER: Bogus packet.\n");
  833.                         continue;
  834.                 }
  835.  
  836.                 bufToPacket(buf, &pkt);
  837.                 if (pkt.cmd != NETCMD_HELLO) {
  838.                         printf("SERVER: Bogus packet.\n");
  839.                         continue;
  840.                 }
  841.  
  842.                 printf("SERVER: Client claims to be player #%ld.\n", pkt.arg);
  843.  
  844.                 if (-1 == pkt.arg) {
  845.                         int i;
  846.                         for(i=0; i!=JNB_MAX_PLAYERS; ++i) {
  847.                                 if(!player[i].enabled) {
  848.                                         printf("SERVER: assigning %d as player number\n", i);
  849.                                         pkt.arg = i;
  850.                                         break;
  851.                                 }
  852.                         }
  853.                 }
  854.  
  855.                 if ((pkt.arg>=JNB_MAX_PLAYERS)||(pkt.arg<0)) {
  856.                         printf("SERVER:  (that's an invalid player number.)\n");
  857.                 } else if (player[pkt.arg].enabled) {
  858.                         printf("SERVER:  (that player number is already taken.)\n");
  859.                 } else {
  860.                         negatory = 0;
  861.                 }
  862.  
  863.                 if (negatory) {
  864.                         printf("SERVER: Forbidding connection.\n");
  865.                         pkt.cmd = NETCMD_NACK;
  866.                         sendPacketToSock(s, &pkt);
  867.                         SDLNet_TCP_Close(s);
  868.                 } else {
  869.                         player[pkt.arg].enabled = 1;
  870.                         net_info[pkt.arg].sock = s;
  871.                         net_info[pkt.arg].addr = *from;
  872.                         net_info[pkt.arg].socketset = SDLNet_AllocSocketSet(1);
  873.                         SDLNet_TCP_AddSocket(net_info[pkt.arg].socketset, net_info[pkt.arg].sock);
  874.                         wait_for_clients--;
  875.                         printf("SERVER: Granting connection. (%d) to go.\n", wait_for_clients);
  876.                         pkt.cmd = NETCMD_ACK;
  877.                         sendPacket(pkt.arg, &pkt);
  878.                 }
  879.         }
  880.  
  881.         SDLNet_TCP_Close(sock);  /* done with the listen socket. */
  882.         SDLNet_FreeSocketSet(socketset);
  883.         sock = NULL;
  884.         socketset = NULL;
  885.  
  886.         printf("SERVER: Got all our connections. Greenlighting clients...\n");
  887.  
  888.         pkt.cmd = NETCMD_GREENLIGHT;
  889.         pkt.arg = 0;
  890.         for (i = 0; i < JNB_MAX_PLAYERS; i++) {
  891.                 if (player[i].enabled) {
  892.                         pkt.arg |= (1 << i);
  893.                 }
  894.         }
  895.         sendPacketToAll(&pkt);
  896. }
  897.  
  898.  
  899. void connect_to_server(char *netarg)
  900. {
  901.         NetPacket pkt;
  902.         char buf[NETPKTBUFSIZE];
  903.         char *ipstr;
  904.         IPaddress hent;
  905.         IPaddress addr;
  906.         int br;
  907.  
  908.         if (netarg == NULL) {
  909.                 printf("CLIENT: Need to specify host to connect to.\n");
  910.                 exit(42);
  911.         }
  912.  
  913.         if (SDLNet_Init() < 0) {
  914.                 exit(42);
  915.         }
  916.         atexit(SDLNet_Quit);
  917.  
  918.         SDLNet_ResolveHost(&addr, NULL, JNB_INETPORT);
  919.         ipstr = SDLNet_ResolveIP(&addr);
  920.         SDLNet_ResolveHost(&addr, ipstr, JNB_INETPORT);
  921.         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);
  922.  
  923.         if (SDLNet_ResolveHost(&hent, netarg, JNB_INETPORT) < 0) {
  924.                 fprintf(stderr, "CLIENT: couldn't find host: %s\n", SDLNet_GetError());
  925.                 exit(42);
  926.         }
  927.  
  928.         sock = SDLNet_TCP_Open(&hent);
  929.         if (sock == NULL) {
  930.                 fprintf(stderr, "CLIENT: SDLNet_TCP_Open(): %s\n", SDLNet_GetError());
  931.                 exit(42);
  932.         }
  933.  
  934.         socketset = SDLNet_AllocSocketSet(1);
  935.         SDLNet_TCP_AddSocket(socketset, sock);
  936.  
  937.         printf("CLIENT: connected to %s...\n", SDLNet_ResolveIP(&hent));
  938.  
  939.         printf("CLIENT: Sending HELLO packet...\n");
  940.         pkt.cmd = NETCMD_HELLO;
  941.         pkt.arg = client_player_num;
  942.         sendPacketToSock(sock, &pkt);
  943.  
  944.         printf("CLIENT: Waiting for ACK from server...\n");
  945.  
  946.         br = SDLNet_TCP_Recv(sock, buf, NETPKTBUFSIZE);
  947.         if (br < 0) {
  948.                 fprintf(stderr, "CLIENT: recv(): %s\n", SDLNet_GetError());
  949.                 SDLNet_FreeSocketSet(socketset);
  950.                 SDLNet_TCP_Close(sock);
  951.                 exit(42);
  952.         }
  953.  
  954.         if (br != NETPKTBUFSIZE) {
  955.                 printf("CLIENT: Bogus packet size (%d of %d). FIXME.\n", br, NETPKTBUFSIZE);
  956.                 SDLNet_FreeSocketSet(socketset);
  957.                 SDLNet_TCP_Close(sock);
  958.                 exit(42);
  959.         }
  960.  
  961.         bufToPacket(buf, &pkt);
  962.  
  963.         if (pkt.cmd == NETCMD_NACK) {
  964.                 printf("CLIENT: Server forbid us from playing.\n");
  965.                 SDLNet_FreeSocketSet(socketset);
  966.                 SDLNet_TCP_Close(sock);
  967.                 exit(42);
  968.         }
  969.  
  970.         if (pkt.cmd != NETCMD_ACK) {
  971.                 printf("CLIENT: Unexpected packet (cmd=0x%lX).\n", pkt.cmd);
  972.                 SDLNet_FreeSocketSet(socketset);
  973.                 SDLNet_TCP_Close(sock);
  974.                 exit(42);
  975.         }
  976.  
  977.         client_player_num = pkt.arg;
  978.         player[client_player_num].enabled = 1;
  979.         net_info[client_player_num].addr = addr;
  980.         printf("CLIENT: Server accepted our connection.\n");
  981.  
  982.         wait_for_greenlight();
  983. }
  984. #endif /* USE_NET */
  985.  
  986.  
  987. static void flip_pixels(unsigned char *pixels)
  988. {
  989.         int x,y;
  990.         unsigned char temp;
  991.  
  992.         assert(pixels);
  993.         for (y = 0; y < JNB_HEIGHT; y++) {
  994.                 for (x = 0; x < (352/2); x++) {
  995.                         temp = pixels[y*JNB_WIDTH+x];
  996.                         pixels[y*JNB_WIDTH+x] = pixels[y*JNB_WIDTH+(352-x)-1];
  997.                         pixels[y*JNB_WIDTH+(352-x)-1] = temp;
  998.                 }
  999.         }
  1000. }
  1001.  
  1002.  
  1003. void get_closest_player_to_point(int x,int y,int *dist,int *closest_player)
  1004. {
  1005.         int c1;
  1006.         int cur_dist = 0;
  1007.  
  1008.         *dist = 0x7fff;
  1009.         for (c1 = 0; c1 < JNB_MAX_PLAYERS; c1++) {
  1010.                 if (player[c1].enabled == 1) {
  1011.                         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)));
  1012.                         if (cur_dist < *dist) {
  1013.                                 *closest_player = c1;
  1014.                                 *dist = cur_dist;
  1015.                         }
  1016.                 }
  1017.         }
  1018. }
  1019.  
  1020.  
  1021. static void update_flies(int update_count)
  1022. {
  1023.         int c1;
  1024.         int closest_player = 0, dist;
  1025.         int s1, s2, s3, s4;
  1026.  
  1027.         /* get center of fly swarm */
  1028.         s1 = s2 = 0;
  1029.         for (c1 = 0; c1 < NUM_FLIES; c1++) {
  1030.                 s1 += flies[c1].x;
  1031.                 s2 += flies[c1].y;
  1032.         }
  1033.         s1 /= NUM_FLIES;
  1034.         s2 /= NUM_FLIES;
  1035.  
  1036.         if (update_count == 1) {
  1037.                 /* get closest player to fly swarm */
  1038.                 get_closest_player_to_point(s1, s2, &dist, &closest_player);
  1039.                 /* update fly swarm sound */
  1040.                 s3 = 32 - dist / 3;
  1041.                 if (s3 < 0)
  1042.                         s3 = 0;
  1043.                 dj_set_sfx_channel_volume(4, (char)(s3));
  1044.         }
  1045.  
  1046.         for (c1 = 0; c1 < NUM_FLIES; c1++) {
  1047.                 /* get closest player to fly */
  1048.                 get_closest_player_to_point(flies[c1].x, flies[c1].y, &dist, &closest_player);
  1049.                 flies[c1].old_x = flies[c1].x;
  1050.                 flies[c1].old_y = flies[c1].y;
  1051.                 s3 = 0;
  1052.                 if ((s1 - flies[c1].x) > 30)
  1053.                         s3 += 1;
  1054.                 else if ((s1 - flies[c1].x) < -30)
  1055.                         s3 -= 1;
  1056.                 if (dist < 30) {
  1057.                         if (((player[closest_player].x >> 16) + 8) > flies[c1].x) {
  1058.                                 if (lord_of_the_flies == 0)
  1059.                                         s3 -= 1;
  1060.                                 else
  1061.                                         s3 += 1;
  1062.                         } else {
  1063.                                 if (lord_of_the_flies == 0)
  1064.                                         s3 += 1;
  1065.                                 else
  1066.                                         s3 -= 1;
  1067.                         }
  1068.                 }
  1069.                 s4 = rnd(3) - 1 + s3;
  1070.                 if ((flies[c1].x + s4) < 16)
  1071.                         s4 = 0;
  1072.                 if ((flies[c1].x + s4) > 351)
  1073.                         s4 = 0;
  1074.                 if (GET_BAN_MAP_XY(flies[c1].x + s4, flies[c1].y) != BAN_VOID)
  1075.                         s4 = 0;
  1076.                 flies[c1].x += s4;
  1077.                 s3 = 0;
  1078.                 if ((s2 - flies[c1].y) > 30)
  1079.                         s3 += 1;
  1080.                 else if ((s2 - flies[c1].y) < -30)
  1081.                         s3 -= 1;
  1082.                 if (dist < 30) {
  1083.                         if (((player[closest_player].y >> 16) + 8) > flies[c1].y) {
  1084.                                 if (lord_of_the_flies == 0)
  1085.                                         s3 -= 1;
  1086.                                 else
  1087.                                         s3 += 1;
  1088.                         } else {
  1089.                                 if (lord_of_the_flies == 0)
  1090.                                         s3 += 1;
  1091.                                 else
  1092.                                         s3 -= 1;
  1093.                         }
  1094.                 }
  1095.                 s4 = rnd(3) - 1 + s3;
  1096.                 if ((flies[c1].y + s4) < 0)
  1097.                         s4 = 0;
  1098.                 if ((flies[c1].y + s4) > 239)
  1099.                         s4 = 0;
  1100.                 if (GET_BAN_MAP_XY(flies[c1].x, flies[c1].y + s4) != BAN_VOID)
  1101.                         s4 = 0;
  1102.                 flies[c1].y += s4;
  1103.         }
  1104. }
  1105.  
  1106.  
  1107. static void player_kill(int c1, int c2)
  1108. {
  1109.         if (player[c1].y_add >= 0) {
  1110.                 if (is_server)
  1111.                         serverSendKillPacket(c1, c2);
  1112.         } else {
  1113.                 if (player[c2].y_add < 0)
  1114.                         player[c2].y_add = 0;
  1115.         }
  1116. }
  1117.  
  1118.  
  1119. static void check_cheats(void)
  1120. {
  1121.         if (strncmp(last_keys, "kcitsogop", strlen("kcitsogop")) == 0) {
  1122.                 pogostick ^= 1;
  1123.                 last_keys[0] = 0;
  1124.         }
  1125.         if (strncmp(last_keys, "ecapsniseinnub", strlen("ecapsniseinnub")) == 0) {
  1126.                 bunnies_in_space ^= 1;
  1127.                 last_keys[0] = 0;
  1128.         }
  1129.         if (strncmp(last_keys, "kcaptej", strlen("kcaptej")) == 0) {
  1130.                 jetpack ^= 1;
  1131.                 last_keys[0] = 0;
  1132.         }
  1133.         if (strncmp(last_keys, "seilfehtfodrol", strlen("seilfehtfodrol")) == 0) {
  1134.                 lord_of_the_flies ^= 1;
  1135.                 last_keys[0] = 0;
  1136.         }
  1137.         if (strncmp(last_keys, "retawnahtrekcihtsidoolb", strlen("retawnahtrekcihtsidoolb")) == 0) {
  1138.                 char blood[32] = {
  1139.                         63,32,32,53,17,17,42, 7,
  1140.                          7,28, 0, 0,24, 0, 0,19,
  1141.                          0, 0,12, 0, 0, 7, 0, 0
  1142.                 };
  1143.                 char water[32] = {
  1144.                         63,63,63,40,53,62,19,42,
  1145.                         60, 0,33,60, 3,32,46, 3,
  1146.                         26,33, 3,19,21, 1, 8, 8
  1147.                 };
  1148.                 int i;
  1149.  
  1150.                 blood_is_thicker_than_water ^= 1;
  1151.                 if (blood_is_thicker_than_water == 1) {
  1152.                         for (i=0; i<32; i++)
  1153.                                 pal[432+i] = blood[i];
  1154.                 } else {
  1155.                         for (i=0; i<32; i++)
  1156.                                 pal[432+i] = water[i];
  1157.                 }
  1158.                 register_background(background_pic, pal);
  1159.                 recalculate_gob(&object_gobs, pal);
  1160.                 last_keys[0] = 0;
  1161.         }
  1162. }
  1163.  
  1164.  
  1165. static void collision_check(void)
  1166. {
  1167.         int c1 = 0, c2 = 0, c3 = 0;
  1168.         int l1;
  1169.  
  1170.         /* collision check */
  1171.         for (c3 = 0; c3 < 6; c3++) {
  1172.                 if (c3 == 0) {
  1173.                         c1 = 0;
  1174.                         c2 = 1;
  1175.                 } else if (c3 == 1) {
  1176.                         c1 = 0;
  1177.                         c2 = 2;
  1178.                 } else if (c3 == 2) {
  1179.                         c1 = 0;
  1180.                         c2 = 3;
  1181.                 } else if (c3 == 3) {
  1182.                         c1 = 1;
  1183.                         c2 = 2;
  1184.                 } else if (c3 == 4) {
  1185.                         c1 = 1;
  1186.                         c2 = 3;
  1187.                 } else if (c3 == 5) {
  1188.                         c1 = 2;
  1189.                         c2 = 3;
  1190.                 }
  1191.                 if (player[c1].enabled == 1 && player[c2].enabled == 1) {
  1192.                         if (labs(player[c1].x - player[c2].x) < (12L << 16) && labs(player[c1].y - player[c2].y) < (12L << 16)) {
  1193.                                 if ((labs(player[c1].y - player[c2].y) >> 16) > 5) {
  1194.                                         if (player[c1].y < player[c2].y) {
  1195.                                                 player_kill(c1,c2);
  1196.                                         } else {
  1197.                                                 player_kill(c2,c1);
  1198.                                         }
  1199.                                 } else {
  1200.                                         if (player[c1].x < player[c2].x) {
  1201.                                                 if (player[c1].x_add > 0)
  1202.                                                         player[c1].x = player[c2].x - (12L << 16);
  1203.                                                 else if (player[c2].x_add < 0)
  1204.                                                         player[c2].x = player[c1].x + (12L << 16);
  1205.                                                 else {
  1206.                                                         player[c1].x -= player[c1].x_add;
  1207.                                                         player[c2].x -= player[c2].x_add;
  1208.                                                 }
  1209.                                                 l1 = player[c2].x_add;
  1210.                                                 player[c2].x_add = player[c1].x_add;
  1211.                                                 player[c1].x_add = l1;
  1212.                                                 if (player[c1].x_add > 0)
  1213.                                                         player[c1].x_add = -player[c1].x_add;
  1214.                                                 if (player[c2].x_add < 0)
  1215.                                                         player[c2].x_add = -player[c2].x_add;
  1216.                                         } else {
  1217.                                                 if (player[c1].x_add > 0)
  1218.                                                         player[c2].x = player[c1].x - (12L << 16);
  1219.                                                 else if (player[c2].x_add < 0)
  1220.                                                         player[c1].x = player[c2].x + (12L << 16);
  1221.                                                 else {
  1222.                                                         player[c1].x -= player[c1].x_add;
  1223.                                                         player[c2].x -= player[c2].x_add;
  1224.                                                 }
  1225.                                                 l1 = player[c2].x_add;
  1226.                                                 player[c2].x_add = player[c1].x_add;
  1227.                                                 player[c1].x_add = l1;
  1228.                                                 if (player[c1].x_add < 0)
  1229.                                                         player[c1].x_add = -player[c1].x_add;
  1230.                                                 if (player[c2].x_add > 0)
  1231.                                                         player[c2].x_add = -player[c2].x_add;
  1232.                                         }
  1233.                                 }
  1234.                         }
  1235.                 }
  1236.         }
  1237. }
  1238.  
  1239. static void game_loop(void) {
  1240.         int mod_vol, sfx_vol;
  1241.         int update_count = 1;
  1242.         int end_loop_flag = 0;
  1243.         int fade_flag = 0;
  1244.         int update_palette = 0;
  1245.         int mod_fade_direction;
  1246.         int i;
  1247.  
  1248.         mod_vol = sfx_vol = 0;
  1249.         mod_fade_direction = 1;
  1250.         dj_ready_mod(MOD_GAME);
  1251.         dj_set_mod_volume((char)mod_vol);
  1252.         dj_set_sfx_volume((char)mod_vol);
  1253.         dj_start_mod();
  1254.  
  1255.         intr_sysupdate();
  1256.  
  1257.         while (1) {
  1258.                 while (update_count) {
  1259.  
  1260.                         if (key_pressed(1) == 1) {
  1261. #ifdef USE_NET
  1262.                                 if (is_net) {
  1263.                                         if (is_server) {
  1264.                                                 serverTellEveryoneGoodbye();
  1265.                                         } else {
  1266.                                                 tellServerGoodbye();
  1267.                                         }
  1268.                                 }
  1269. #endif
  1270.                                 end_loop_flag = 1;
  1271.                                 memset(pal, 0, 768);
  1272.                                 mod_fade_direction = 0;
  1273.                         }
  1274.  
  1275.                         check_cheats();
  1276.  
  1277. #ifdef USE_NET
  1278.                         if (is_net) {
  1279.                                 if (is_server) {
  1280.                                         update_players_from_clients();
  1281.                                 } else {
  1282.                                         if (!update_players_from_server()) {
  1283.                                                 break;  /* got a BYE packet */
  1284.                                         }
  1285.                                 }
  1286.                         }
  1287. #endif
  1288.  
  1289.                         steer_players();
  1290.  
  1291.                         dj_mix();
  1292.  
  1293.                         collision_check();
  1294.  
  1295.                         dj_mix();
  1296.  
  1297.                         main_info.page_info[main_info.draw_page].num_pobs = 0;
  1298.                         for (i = 0; i < JNB_MAX_PLAYERS; i++) {
  1299.                                 if (player[i].enabled == 1)
  1300.                                         main_info.page_info[main_info.draw_page].num_pobs++;
  1301.                         }
  1302.  
  1303.                         update_objects();
  1304.  
  1305.                         dj_mix();
  1306.  
  1307.                         if (flies_enabled) {
  1308.                                 update_flies(update_count);
  1309.                         }
  1310.  
  1311.                         dj_mix();
  1312.  
  1313.                         if (update_count == 1) {
  1314.                                 int c2;
  1315.  
  1316.                                 for (i = 0, c2 = 0; i < JNB_MAX_PLAYERS; i++) {
  1317.                                         if (player[i].enabled == 1) {
  1318.                                                 main_info.page_info[main_info.draw_page].pobs[c2].x = player[i].x >> 16;
  1319.                                                 main_info.page_info[main_info.draw_page].pobs[c2].y = player[i].y >> 16;
  1320.                                                 main_info.page_info[main_info.draw_page].pobs[c2].image = player[i].image + i * 18;
  1321.                                                 main_info.page_info[main_info.draw_page].pobs[c2].pob_data = &rabbit_gobs;
  1322.                                                 c2++;
  1323.                                         }
  1324.                                 }
  1325.  
  1326.                                 draw_begin();
  1327.  
  1328.                                 draw_pobs(main_info.draw_page);
  1329.  
  1330.                                 dj_mix();
  1331.  
  1332.                                 if (flies_enabled)
  1333.                                         draw_flies(main_info.draw_page);
  1334.  
  1335.                                 draw_end();
  1336.                         }
  1337.  
  1338.                         if (mod_fade_direction == 1) {
  1339.                                 if (mod_vol < 30) {
  1340.                                         mod_vol++;
  1341.                                         dj_set_mod_volume((char)mod_vol);
  1342.                                 }
  1343.                                 if (sfx_vol < 64) {
  1344.                                         sfx_vol++;
  1345.                                         dj_set_sfx_volume((char)sfx_vol);
  1346.                                 }
  1347.                         } else {
  1348.                                 if (mod_vol > 0) {
  1349.                                         mod_vol--;
  1350.                                         dj_set_mod_volume((char)mod_vol);
  1351.                                 }
  1352.                                 if (sfx_vol > 0) {
  1353.                                         sfx_vol--;
  1354.                                         dj_set_sfx_volume((char)sfx_vol);
  1355.                                 }
  1356.                         }
  1357.  
  1358.                         fade_flag = 0;
  1359.                         for (i = 0; i < 768; i++) {
  1360.                                 if (cur_pal[i] < pal[i]) {
  1361.                                         cur_pal[i]++;
  1362.                                         fade_flag = 1;
  1363.                                 } else if (cur_pal[i] > pal[i]) {
  1364.                                         cur_pal[i]--;
  1365.                                         fade_flag = 1;
  1366.                                 }
  1367.                         }
  1368.                         if (fade_flag == 1)
  1369.                                 update_palette = 1;
  1370.                         if (fade_flag == 0 && end_loop_flag == 1)
  1371.                                 break;
  1372.  
  1373.                         if (update_count == 1) {
  1374.                                 if (update_palette == 1) {
  1375.                                         setpalette(0, 256, cur_pal);
  1376.                                         update_palette = 0;
  1377.                                 }
  1378.  
  1379.                                 main_info.draw_page ^= 1;
  1380.                                 main_info.view_page ^= 1;
  1381.  
  1382.                                 flippage(main_info.view_page);
  1383.  
  1384.                                 wait_vrt(1);
  1385.  
  1386.                                 draw_begin();
  1387.  
  1388.                                 if (flies_enabled)
  1389.                                         redraw_flies_background(main_info.draw_page);
  1390.  
  1391.                                 redraw_pob_backgrounds(main_info.draw_page);
  1392.  
  1393.                                 draw_leftovers(main_info.draw_page);
  1394.  
  1395.                                 draw_end();
  1396.                         }
  1397.  
  1398.                         update_count--;
  1399.                 }
  1400.  
  1401. #ifdef USE_NET
  1402.                 if (is_net) {
  1403.                         if ( (player[client_player_num].dead_flag == 0) &&
  1404.                                 (
  1405.                                  (player[client_player_num].action_left) ||
  1406.                                  (player[client_player_num].action_right) ||
  1407.                                  (player[client_player_num].action_up) ||
  1408.                                  (player[client_player_num].jump_ready == 0)
  1409.                                 )
  1410.                            ) {
  1411.                                 tellServerNewPosition();
  1412.                         }
  1413.                 }
  1414. #endif
  1415.  
  1416.                 update_count = intr_sysupdate();
  1417.  
  1418. #ifdef USE_NET
  1419.                 if (is_net) {
  1420.                         if ((server_said_bye) || ((fade_flag == 0) && (end_loop_flag == 1)))
  1421.                                 break;
  1422.                 } else
  1423. #endif
  1424.                 if ((fade_flag == 0) && (end_loop_flag == 1))
  1425.                         break;
  1426.         }
  1427. }
  1428.  
  1429.  
  1430. static int menu_loop(void)
  1431. {
  1432.         unsigned char *handle;
  1433.         int mod_vol;
  1434.         int c1, c2;
  1435.         int s1, s2;
  1436.  
  1437.         for(c1 = 0; c1 < JNB_MAX_PLAYERS; c1++)         // reset player values
  1438.         {
  1439.                 ai[c1] = 0;
  1440.         }
  1441.  
  1442.         while (1) {
  1443.  
  1444.                 if (!is_net)
  1445.                         if (menu() != 0)
  1446.                                 deinit_program();
  1447.  
  1448.                 if (key_pressed(1) == 1) {
  1449.                         return 0;
  1450.                 }
  1451.                 if (init_level(0, pal) != 0) {
  1452.                         deinit_level();
  1453.                         deinit_program();
  1454.                 }
  1455.  
  1456.                 memset(cur_pal, 0, 768);
  1457.                 setpalette(0, 256, cur_pal);
  1458.  
  1459.                 recalculate_gob(&rabbit_gobs, pal);
  1460.                 recalculate_gob(&object_gobs, pal);
  1461.                 recalculate_gob(&number_gobs, pal);
  1462.  
  1463.                 flippage(1);
  1464.                 register_background(background_pic, pal);
  1465.                 flippage(0);
  1466.  
  1467.                 if (flies_enabled) {
  1468.                         s1 = rnd(250) + 50;
  1469.                         s2 = rnd(150) + 50;
  1470.  
  1471.                         for (c1 = 0; c1 < NUM_FLIES; c1++) {
  1472.                                 while (1) {
  1473.                                         flies[c1].x = s1 + rnd(101) - 50;
  1474.                                         flies[c1].y = s2 + rnd(101) - 50;
  1475.                                         if (GET_BAN_MAP_XY(flies[c1].x, flies[c1].y) == BAN_VOID)
  1476.                                                 break;
  1477.                                 }
  1478.                                 flies[c1].back_defined[0] = 0;
  1479.                                 flies[c1].back_defined[1] = 0;
  1480.                         }
  1481.                 }
  1482.  
  1483.                 if (flies_enabled)
  1484.                         dj_play_sfx(SFX_FLY, SFX_FLY_FREQ, 0, 0, 0, 4);
  1485.  
  1486.                 dj_set_nosound(0);
  1487.  
  1488.                 lord_of_the_flies = bunnies_in_space = jetpack = pogostick = blood_is_thicker_than_water = 0;
  1489.                 main_info.page_info[0].num_pobs = 0;
  1490.                 main_info.page_info[1].num_pobs = 0;
  1491.                 main_info.view_page = 0;
  1492.                 main_info.draw_page = 1;
  1493.  
  1494.                 game_loop();
  1495.  
  1496. #ifdef USE_NET
  1497.                 if (is_net) {
  1498.                         if (is_server) {
  1499.                                 serverTellEveryoneGoodbye();
  1500.                                 SDLNet_TCP_Close(sock);
  1501.                                 sock = NULL;
  1502.                         } else {
  1503.                                 if (!server_said_bye) {
  1504.                                         tellServerGoodbye();
  1505.                                 }
  1506.  
  1507.                                 SDLNet_TCP_Close(sock);
  1508.                                 sock = NULL;
  1509.                         }
  1510.                 }
  1511. #endif
  1512.  
  1513.                 main_info.view_page = 0;
  1514.                 main_info.draw_page = 1;
  1515.  
  1516.                 dj_stop_sfx_channel(4);
  1517.  
  1518.                 deinit_level();
  1519.  
  1520.                 memset(mask_pic, 0, JNB_WIDTH*JNB_HEIGHT);
  1521.                 register_mask(mask_pic);
  1522.  
  1523.                 register_background(NULL, NULL);
  1524.  
  1525.                 draw_begin();
  1526.  
  1527.                 put_text(main_info.view_page, 100, 50, "DOTT", 2);
  1528.                 put_text(main_info.view_page, 160, 50, "JIFFY", 2);
  1529.                 put_text(main_info.view_page, 220, 50, "FIZZ", 2);
  1530.                 put_text(main_info.view_page, 280, 50, "MIJJI", 2);
  1531.                 put_text(main_info.view_page, 40, 80, "DOTT", 2);
  1532.                 put_text(main_info.view_page, 40, 110, "JIFFY", 2);
  1533.                 put_text(main_info.view_page, 40, 140, "FIZZ", 2);
  1534.                 put_text(main_info.view_page, 40, 170, "MIJJI", 2);
  1535.  
  1536.                 for (c1 = 0; c1 < JNB_MAX_PLAYERS; c1++) {
  1537.                         char str1[100];
  1538.  
  1539.                         for (c2 = 0; c2 < JNB_MAX_PLAYERS; c2++) {
  1540.                                 if (c2 != c1) {
  1541.                                         sprintf(str1, "%d", player[c1].bumped[c2]);
  1542.                                         put_text(main_info.view_page, 100 + c2 * 60, 80 + c1 * 30, str1, 2);
  1543.                                 } else
  1544.                                         put_text(main_info.view_page, 100 + c2 * 60, 80 + c1 * 30, "-", 2);
  1545.                         }
  1546.                         sprintf(str1, "%d", player[c1].bumps);
  1547.                         put_text(main_info.view_page, 350, 80 + c1 * 30, str1, 2);
  1548.                 }
  1549.  
  1550.                 put_text(main_info.view_page, 200, 230, "Press ESC to continue", 2);
  1551.  
  1552.                 draw_end();
  1553.  
  1554.                 flippage(main_info.view_page);
  1555.  
  1556.                 if ((handle = dat_open("menu.pcx")) == 0) {
  1557.                         strcpy(main_info.error_str, "Error loading 'menu.pcx', aborting...\n");
  1558.                         return 1;
  1559.                 }
  1560.                 if (read_pcx(handle, background_pic, JNB_WIDTH*JNB_HEIGHT, pal) != 0) {
  1561.                         strcpy(main_info.error_str, "Error loading 'menu.pcx', aborting...\n");
  1562.                         return 1;
  1563.                 }
  1564.  
  1565.                 /* fix dark font */
  1566.                 for (c1 = 0; c1 < 16; c1++) {
  1567.                         pal[(240 + c1) * 3 + 0] = c1 << 2;
  1568.                         pal[(240 + c1) * 3 + 1] = c1 << 2;
  1569.                         pal[(240 + c1) * 3 + 2] = c1 << 2;
  1570.                 }
  1571.  
  1572.                 memset(cur_pal, 0, 768);
  1573.  
  1574.                 setpalette(0, 256, cur_pal);
  1575.  
  1576.                 mod_vol = 0;
  1577.                 dj_ready_mod(MOD_SCORES);
  1578.                 dj_set_mod_volume((char)mod_vol);
  1579.                 dj_start_mod();
  1580.                 dj_set_nosound(0);
  1581.  
  1582.                 while (key_pressed(1) == 0) {
  1583.                         if (mod_vol < 35)
  1584.                                 mod_vol++;
  1585.                         dj_set_mod_volume((char)mod_vol);
  1586.                         for (c1 = 0; c1 < 768; c1++) {
  1587.                                 if (cur_pal[c1] < pal[c1])
  1588.                                         cur_pal[c1]++;
  1589.                         }
  1590.                         dj_mix();
  1591.                         intr_sysupdate();
  1592.                         wait_vrt(0);
  1593.                         setpalette(0, 256, cur_pal);
  1594.                         flippage(main_info.view_page);
  1595.                 }
  1596.                 while (key_pressed(1) == 1) {
  1597.                         dj_mix();
  1598.                         intr_sysupdate();
  1599.                 }
  1600.  
  1601.                 memset(pal, 0, 768);
  1602.  
  1603.                 while (mod_vol > 0) {
  1604.                         mod_vol--;
  1605.                         dj_set_mod_volume((char)mod_vol);
  1606.                         for (c1 = 0; c1 < 768; c1++) {
  1607.                                 if (cur_pal[c1] > pal[c1])
  1608.                                         cur_pal[c1]--;
  1609.                         }
  1610.                         dj_mix();
  1611.                         wait_vrt(0);
  1612.                         setpalette(0, 256, cur_pal);
  1613.                         flippage(main_info.view_page);
  1614.                 }
  1615.  
  1616.                 fillpalette(0, 0, 0);
  1617.  
  1618.                 dj_set_nosound(1);
  1619.                 dj_stop_mod();
  1620.  
  1621.                 if (is_net)
  1622.                         return 0; /* don't go back to menu if in net game. */
  1623.         }
  1624. }
  1625.  
  1626.  
  1627. int main(int argc, char *argv[])
  1628. {
  1629.         int result;
  1630.  
  1631.         if (init_program(argc, argv, pal) != 0)
  1632.                 deinit_program();
  1633.  
  1634.         if (main_info.fireworks == 1) {
  1635.                 fireworks();
  1636.                 deinit_program();
  1637.         }
  1638.  
  1639.         result = menu_loop();
  1640.  
  1641.         deinit_program();
  1642.  
  1643.         return result;
  1644. }
  1645.  
  1646.  
  1647. static void player_action_left(int c1)
  1648. {
  1649.         int s1 = 0, s2 = 0;
  1650.         int below_left, below, below_right;
  1651.  
  1652.     s1 = (player[c1].x >> 16);
  1653.     s2 = (player[c1].y >> 16);
  1654.         below_left = GET_BAN_MAP_XY(s1, s2 + 16);
  1655.         below = GET_BAN_MAP_XY(s1 + 8, s2 + 16);
  1656.         below_right = GET_BAN_MAP_XY(s1 + 15, s2 + 16);
  1657.  
  1658.     if (below == BAN_ICE) {
  1659.         if (player[c1].x_add > 0)
  1660.             player[c1].x_add -= 1024;
  1661.         else
  1662.             player[c1].x_add -= 768;
  1663.     } else if ((below_left != BAN_SOLID && below_right == BAN_ICE) || (below_left == BAN_ICE && below_right != BAN_SOLID)) {
  1664.         if (player[c1].x_add > 0)
  1665.             player[c1].x_add -= 1024;
  1666.         else
  1667.             player[c1].x_add -= 768;
  1668.     } else {
  1669.         if (player[c1].x_add > 0) {
  1670.             player[c1].x_add -= 16384;
  1671.             if (player[c1].x_add > -98304L && player[c1].in_water == 0 && below == BAN_SOLID)
  1672.                 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);
  1673.         } else
  1674.             player[c1].x_add -= 12288;
  1675.     }
  1676.     if (player[c1].x_add < -98304L)
  1677.         player[c1].x_add = -98304L;
  1678.     player[c1].direction = 1;
  1679.     if (player[c1].anim == 0) {
  1680.         player[c1].anim = 1;
  1681.         player[c1].frame = 0;
  1682.         player[c1].frame_tick = 0;
  1683.         player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
  1684.     }
  1685. }
  1686.  
  1687.  
  1688. static void player_action_right(int c1)
  1689. {
  1690.         int s1 = 0, s2 = 0;
  1691.         int below_left, below, below_right;
  1692.  
  1693.     s1 = (player[c1].x >> 16);
  1694.     s2 = (player[c1].y >> 16);
  1695.         below_left = GET_BAN_MAP_XY(s1, s2 + 16);
  1696.         below = GET_BAN_MAP_XY(s1 + 8, s2 + 16);
  1697.         below_right = GET_BAN_MAP_XY(s1 + 15, s2 + 16);
  1698.  
  1699.     if (below == BAN_ICE) {
  1700.         if (player[c1].x_add < 0)
  1701.             player[c1].x_add += 1024;
  1702.         else
  1703.             player[c1].x_add += 768;
  1704.     } else if ((below_left != BAN_SOLID && below_right == BAN_ICE) || (below_left == BAN_ICE && below_right != BAN_SOLID)) {
  1705.         if (player[c1].x_add > 0)
  1706.             player[c1].x_add += 1024;
  1707.         else
  1708.             player[c1].x_add += 768;
  1709.     } else {
  1710.         if (player[c1].x_add < 0) {
  1711.             player[c1].x_add += 16384;
  1712.             if (player[c1].x_add < 98304L && player[c1].in_water == 0 && below == BAN_SOLID)
  1713.                 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);
  1714.         } else
  1715.             player[c1].x_add += 12288;
  1716.     }
  1717.     if (player[c1].x_add > 98304L)
  1718.         player[c1].x_add = 98304L;
  1719.     player[c1].direction = 0;
  1720.     if (player[c1].anim == 0) {
  1721.         player[c1].anim = 1;
  1722.         player[c1].frame = 0;
  1723.         player[c1].frame_tick = 0;
  1724.         player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
  1725.     }
  1726. }
  1727.  
  1728. int map_tile(int pos_x, int pos_y)
  1729. {
  1730. int tile;
  1731.  
  1732. pos_x = pos_x >> 4;
  1733. pos_y = pos_y >> 4;
  1734.  
  1735. if(pos_x < 0 || pos_x >= 17 || pos_y < 0 || pos_y >= 22)
  1736.   return BAN_VOID;
  1737.  
  1738. tile = ban_map[pos_y][pos_x];
  1739. return tile;
  1740. }
  1741.  
  1742. void cpu_move(void)
  1743. {
  1744.         int lm, rm, jm;
  1745.         int i, j;
  1746.         int cur_posx, cur_posy, tar_posx, tar_posy;
  1747.         int players_distance;
  1748.         player_t* target = NULL;
  1749.         int nearest_distance = -1;
  1750.  
  1751.         for (i = 0; i < JNB_MAX_PLAYERS; i++)
  1752.                 {
  1753.           nearest_distance = -1;
  1754.                 if(ai[i] && player[i].enabled)          // this player is a computer
  1755.                         {               // get nearest target
  1756.                         for (j = 0; j < JNB_MAX_PLAYERS; j++)
  1757.                                 {
  1758.                                 int deltax, deltay;
  1759.  
  1760.                                 if(i == j || !player[j].enabled)
  1761.                                         continue;
  1762.  
  1763.                                 deltax = player[j].x - player[i].x;
  1764.                                 deltay = player[j].y - player[i].y;
  1765.                                 players_distance = deltax*deltax + deltay*deltay;
  1766.  
  1767.                                 if (players_distance < nearest_distance || nearest_distance == -1)
  1768.                                         {
  1769.                                         target = &player[j];
  1770.                                         nearest_distance = players_distance;
  1771.                                         }
  1772.                                 }
  1773.  
  1774.                         if(target == NULL)
  1775.                                 continue;
  1776.  
  1777.                         cur_posx = player[i].x >> 16;
  1778.                         cur_posy = player[i].y >> 16;
  1779.                         tar_posx = target->x >> 16;
  1780.                         tar_posy = target->y >> 16;
  1781.  
  1782.                         /** nearest player found, get him */
  1783.                         /* here goes the artificial intelligence code */
  1784.  
  1785.                         /* X-axis movement */
  1786.                         if(tar_posx > cur_posx)       // if true target is on the right side
  1787.                                 {    // go after him
  1788.                                 lm=0;
  1789.                                 rm=1;
  1790.                                 }
  1791.                         else    // target on the left side
  1792.                                 {
  1793.                                 lm=1;
  1794.                                 rm=0;
  1795.                                 }
  1796.  
  1797.                         if(cur_posy - tar_posy < 32 && cur_posy - tar_posy > 0 &&
  1798.               tar_posx - cur_posx < 32+8 && tar_posx - cur_posx > -32)
  1799.                                 {
  1800.                                 lm = !lm;
  1801.                                 rm = !rm;
  1802.                                 }
  1803.                         else if(tar_posx - cur_posx < 4+8 && tar_posx - cur_posx > -4)
  1804.                                 {      // makes the bunnies less "nervous"
  1805.                                 lm=0;
  1806.                                 lm=0;
  1807.                                 }
  1808.  
  1809.                         /* Y-axis movement */
  1810.                         if(map_tile(cur_posx, cur_posy+16) != BAN_VOID &&
  1811.                                 ((i == 0 && key_pressed(KEY_PL1_JUMP)) ||
  1812.                                 (i == 1 && key_pressed(KEY_PL2_JUMP)) ||
  1813.                                 (i == 2 && key_pressed(KEY_PL3_JUMP)) ||
  1814.                                 (i == 3 && key_pressed(KEY_PL4_JUMP))))
  1815.                                         jm=0;   // if we are on ground and jump key is being pressed,
  1816.                                                                         //first we have to release it or else we won't be able to jump more than once
  1817.  
  1818.                         else if(map_tile(cur_posx, cur_posy-8) != BAN_VOID &&
  1819.                                 map_tile(cur_posx, cur_posy-8) != BAN_WATER)
  1820.                                         jm=0;   // don't jump if there is something over it
  1821.  
  1822.                         else if(map_tile(cur_posx-(lm*8)+(rm*16), cur_posy) != BAN_VOID &&
  1823.                                 map_tile(cur_posx-(lm*8)+(rm*16), cur_posy) != BAN_WATER &&
  1824.                                 cur_posx > 16 && cur_posx < 352-16-8)  // obstacle, jump
  1825.                                         jm=1;   // if there is something on the way, jump over it
  1826.  
  1827.                         else if(((i == 0 && key_pressed(KEY_PL1_JUMP)) ||
  1828.                                                         (i == 1 && key_pressed(KEY_PL2_JUMP)) ||
  1829.                                                         (i == 2 && key_pressed(KEY_PL3_JUMP)) ||
  1830.                                                         (i == 3 && key_pressed(KEY_PL4_JUMP))) &&
  1831.                                                         (map_tile(cur_posx-(lm*8)+(rm*16), cur_posy+8) != BAN_VOID &&
  1832.                                                         map_tile(cur_posx-(lm*8)+(rm*16), cur_posy+8) != BAN_WATER))
  1833.                                         jm=1;   // this makes it possible to jump over 2 tiles
  1834.  
  1835.                         else if(cur_posy - tar_posy < 32 && cur_posy - tar_posy > 0 &&
  1836.               tar_posx - cur_posx < 32+8 && tar_posx - cur_posx > -32)  // don't jump - running away
  1837.                                 jm=0;
  1838.  
  1839.                         else if(tar_posy <= cur_posy)   // target on the upper side
  1840.                                 jm=1;
  1841.                         else   // target below
  1842.                                 jm=0;
  1843.  
  1844.                         /** Artificial intelligence done, now apply movements */
  1845.                         if(lm)
  1846.                                 {
  1847.                                 SDLKey key;
  1848.                                 if(i == 0)
  1849.                                         key = KEY_PL1_LEFT;
  1850.                                 else if(i == 1)
  1851.                                         key = KEY_PL2_LEFT;
  1852.                                 else if(i == 2)
  1853.                                         key = KEY_PL3_LEFT;
  1854.                                 else
  1855.                                         key = KEY_PL4_LEFT;
  1856.  
  1857.                                 key &= 0x7f;
  1858.                                 addkey(key);
  1859.                                 }
  1860.                         else
  1861.                                 {
  1862.                                 SDLKey key;
  1863.                                 if(i == 0)
  1864.                                         key = KEY_PL1_LEFT;
  1865.                                 else if(i == 1)
  1866.                                         key = KEY_PL2_LEFT;
  1867.                                 else if(i == 2)
  1868.                                         key = KEY_PL3_LEFT;
  1869.                                 else
  1870.                                         key = KEY_PL4_LEFT;
  1871.  
  1872.                                 key &= 0x7f;
  1873.                                 addkey(key | 0x8000);
  1874.                                 }
  1875.  
  1876.                         if(rm)
  1877.                                 {
  1878.                                 SDLKey key;
  1879.                                 if(i == 0)
  1880.                                         key = KEY_PL1_RIGHT;
  1881.                                 else if(i == 1)
  1882.                                         key = KEY_PL2_RIGHT;
  1883.                                 else if(i == 2)
  1884.                                         key = KEY_PL3_RIGHT;
  1885.                                 else
  1886.                                         key = KEY_PL4_RIGHT;
  1887.  
  1888.                                 key &= 0x7f;
  1889.                                 addkey(key);
  1890.                                 }
  1891.                         else
  1892.                                 {
  1893.                                 SDLKey key;
  1894.                                 if(i == 0)
  1895.                                         key = KEY_PL1_RIGHT;
  1896.                                 else if(i == 1)
  1897.                                         key = KEY_PL2_RIGHT;
  1898.                                 else if(i == 2)
  1899.                                         key = KEY_PL3_RIGHT;
  1900.                                 else
  1901.                                         key = KEY_PL4_RIGHT;
  1902.  
  1903.                                 key &= 0x7f;
  1904.                                 addkey(key | 0x8000);
  1905.                                 }
  1906.  
  1907.                         if(jm)
  1908.                                 {
  1909.                                 SDLKey key;
  1910.                                 if(i == 0)
  1911.                                         key = KEY_PL1_JUMP;
  1912.                                 else if(i == 1)
  1913.                                         key = KEY_PL2_JUMP;
  1914.                                 else if(i == 2)
  1915.                                         key = KEY_PL3_JUMP;
  1916.                                 else
  1917.                                         key = KEY_PL4_JUMP;
  1918.  
  1919.                                 key &= 0x7f;
  1920.                                 addkey(key);
  1921.                                 }
  1922.                         else
  1923.                                 {
  1924.                                 SDLKey key;
  1925.                                 if(i == 0)
  1926.                                         key = KEY_PL1_JUMP;
  1927.                                 else if(i == 1)
  1928.                                         key = KEY_PL2_JUMP;
  1929.                                 else if(i == 2)
  1930.                                         key = KEY_PL3_JUMP;
  1931.                                 else
  1932.                                         key = KEY_PL4_JUMP;
  1933.  
  1934.                                 key &= 0x7f;
  1935.                                 addkey(key | 0x8000);
  1936.                                 }
  1937.                         }
  1938.                 }
  1939. }
  1940.  
  1941.  
  1942. #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)
  1943.  
  1944.  
  1945. void steer_players(void)
  1946. {
  1947.         int c1, c2;
  1948.         int s1 = 0, s2 = 0;
  1949.  
  1950.         cpu_move();
  1951.         update_player_actions();
  1952.  
  1953.         for (c1 = 0; c1 < JNB_MAX_PLAYERS; c1++) {
  1954.  
  1955.                 if (player[c1].enabled == 1) {
  1956.  
  1957.                         if (player[c1].dead_flag == 0) {
  1958.  
  1959.                                 if (player[c1].action_left && player[c1].action_right) {
  1960.                                         if (player[c1].direction == 0) {
  1961.                                                 if (player[c1].action_right) {
  1962.                                                         player_action_right(c1);
  1963.                                                 }
  1964.                                         } else {
  1965.                                                 if (player[c1].action_left) {
  1966.                                                         player_action_left(c1);
  1967.                                                 }
  1968.                                         }
  1969.                                 } else if (player[c1].action_left) {
  1970.                                         player_action_left(c1);
  1971.                                 } else if (player[c1].action_right) {
  1972.                                         player_action_right(c1);
  1973.                                 } else if ((!player[c1].action_left) && (!player[c1].action_right)) {
  1974.                                         int below_left, below, below_right;
  1975.  
  1976.                                         s1 = (player[c1].x >> 16);
  1977.                                         s2 = (player[c1].y >> 16);
  1978.                                         below_left = GET_BAN_MAP_XY(s1, s2 + 16);
  1979.                                         below = GET_BAN_MAP_XY(s1 + 8, s2 + 16);
  1980.                                         below_right = GET_BAN_MAP_XY(s1 + 15, s2 + 16);
  1981.                                         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)))) {
  1982.                                                 if (player[c1].x_add < 0) {
  1983.                                                         player[c1].x_add += 16384;
  1984.                                                         if (player[c1].x_add > 0)
  1985.                                                                 player[c1].x_add = 0;
  1986.                                                 } else {
  1987.                                                         player[c1].x_add -= 16384;
  1988.                                                         if (player[c1].x_add < 0)
  1989.                                                                 player[c1].x_add = 0;
  1990.                                                 }
  1991.                                                 if (player[c1].x_add != 0 && GET_BAN_MAP_XY((s1 + 8), (s2 + 16)) == BAN_SOLID)
  1992.                                                         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);
  1993.                                         }
  1994.                                         if (player[c1].anim == 1) {
  1995.                                                 player[c1].anim = 0;
  1996.                                                 player[c1].frame = 0;
  1997.                                                 player[c1].frame_tick = 0;
  1998.                                                 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
  1999.                                         }
  2000.                                 }
  2001.                                 if (jetpack == 0) {
  2002.                                         /* no jetpack */
  2003.                                         if (pogostick == 1 || (player[c1].jump_ready == 1 && player[c1].action_up)) {
  2004.                                                 s1 = (player[c1].x >> 16);
  2005.                                                 s2 = (player[c1].y >> 16);
  2006.                                                 if (s2 < -16)
  2007.                                                         s2 = -16;
  2008.                                                 /* jump */
  2009.                                                 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) {
  2010.                                                         player[c1].y_add = -280000L;
  2011.                                                         player[c1].anim = 2;
  2012.                                                         player[c1].frame = 0;
  2013.                                                         player[c1].frame_tick = 0;
  2014.                                                         player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
  2015.                                                         player[c1].jump_ready = 0;
  2016.                                                         player[c1].jump_abort = 1;
  2017.                                                         if (pogostick == 0)
  2018.                                                                 dj_play_sfx(SFX_JUMP, (unsigned short)(SFX_JUMP_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
  2019.                                                         else
  2020.                                                                 dj_play_sfx(SFX_SPRING, (unsigned short)(SFX_SPRING_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
  2021.                                                 }
  2022.                                                 /* jump out of water */
  2023.                                                 if (GET_BAN_MAP_IN_WATER(s1, s2)) {
  2024.                                                         player[c1].y_add = -196608L;
  2025.                                                         player[c1].in_water = 0;
  2026.                                                         player[c1].anim = 2;
  2027.                                                         player[c1].frame = 0;
  2028.                                                         player[c1].frame_tick = 0;
  2029.                                                         player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
  2030.                                                         player[c1].jump_ready = 0;
  2031.                                                         player[c1].jump_abort = 1;
  2032.                                                         if (pogostick == 0)
  2033.                                                                 dj_play_sfx(SFX_JUMP, (unsigned short)(SFX_JUMP_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
  2034.                                                         else
  2035.                                                                 dj_play_sfx(SFX_SPRING, (unsigned short)(SFX_SPRING_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
  2036.                                                 }
  2037.                                         }
  2038.                                         /* fall down by gravity */
  2039.                                         if (pogostick == 0 && (!player[c1].action_up)) {
  2040.                                                 player[c1].jump_ready = 1;
  2041.                                                 if (player[c1].in_water == 0 && player[c1].y_add < 0 && player[c1].jump_abort == 1) {
  2042.                                                         if (bunnies_in_space == 0)
  2043.                                                                 /* normal gravity */
  2044.                                                                 player[c1].y_add += 32768;
  2045.                                                         else
  2046.                                                                 /* light gravity */
  2047.                                                                 player[c1].y_add += 16384;
  2048.                                                         if (player[c1].y_add > 0)
  2049.                                                                 player[c1].y_add = 0;
  2050.                                                 }
  2051.                                         }
  2052.                                 } else {
  2053.                                         /* with jetpack */
  2054.                                         if (player[c1].action_up) {
  2055.                                                 player[c1].y_add -= 16384;
  2056.                                                 if (player[c1].y_add < -400000L)
  2057.                                                         player[c1].y_add = -400000L;
  2058.                                                 if (GET_BAN_MAP_IN_WATER(s1, s2))
  2059.                                                         player[c1].in_water = 0;
  2060.                                                 if (rnd(100) < 50)
  2061.                                                         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);
  2062.                                         }
  2063.                                 }
  2064.  
  2065.                                 player[c1].x += player[c1].x_add;
  2066.                                 if ((player[c1].x >> 16) < 0) {
  2067.                                         player[c1].x = 0;
  2068.                                         player[c1].x_add = 0;
  2069.                                 }
  2070.                                 if ((player[c1].x >> 16) + 15 > 351) {
  2071.                                         player[c1].x = 336L << 16;
  2072.                                         player[c1].x_add = 0;
  2073.                                 }
  2074.                                 {
  2075.                                         if (player[c1].y > 0) {
  2076.                                                 s2 = (player[c1].y >> 16);
  2077.                                         } else {
  2078.                                                 /* check top line only */
  2079.                                                 s2 = 0;
  2080.                                         }
  2081.  
  2082.                                         s1 = (player[c1].x >> 16);
  2083.                                         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) {
  2084.                                                 player[c1].x = (((s1 + 16) & 0xfff0)) << 16;
  2085.                                                 player[c1].x_add = 0;
  2086.                                         }
  2087.  
  2088.                                         s1 = (player[c1].x >> 16);
  2089.                                         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) {
  2090.                                                 player[c1].x = (((s1 + 16) & 0xfff0) - 16) << 16;
  2091.                                                 player[c1].x_add = 0;
  2092.                                         }
  2093.                                 }
  2094.  
  2095.                                 player[c1].y += player[c1].y_add;
  2096.  
  2097.                                 s1 = (player[c1].x >> 16);
  2098.                                 s2 = (player[c1].y >> 16);
  2099.                                 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))) {
  2100.                                         player[c1].y = ((player[c1].y >> 16) & 0xfff0) << 16;
  2101.                                         player[c1].y_add = -400000L;
  2102.                                         player[c1].anim = 2;
  2103.                                         player[c1].frame = 0;
  2104.                                         player[c1].frame_tick = 0;
  2105.                                         player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
  2106.                                         player[c1].jump_ready = 0;
  2107.                                         player[c1].jump_abort = 0;
  2108.                                         for (c2 = 0; c2 < NUM_OBJECTS; c2++) {
  2109.                                                 if (objects[c2].used == 1 && objects[c2].type == OBJ_SPRING) {
  2110.                                                         if (GET_BAN_MAP_XY((s1 + 8), (s2 + 15)) == BAN_SPRING) {
  2111.                                                                 if ((objects[c2].x >> 20) == ((s1 + 8) >> 4) && (objects[c2].y >> 20) == ((s2 + 15) >> 4)) {
  2112.                                                                         objects[c2].frame = 0;
  2113.                                                                         objects[c2].ticks = object_anims[objects[c2].anim].frame[objects[c2].frame].ticks;
  2114.                                                                         objects[c2].image = object_anims[objects[c2].anim].frame[objects[c2].frame].image;
  2115.                                                                         break;
  2116.                                                                 }
  2117.                                                         } else {
  2118.                                                                 if (GET_BAN_MAP_XY(s1, (s2 + 15)) == BAN_SPRING) {
  2119.                                                                         if ((objects[c2].x >> 20) == (s1 >> 4) && (objects[c2].y >> 20) == ((s2 + 15) >> 4)) {
  2120.                                                                                 objects[c2].frame = 0;
  2121.                                                                                 objects[c2].ticks = object_anims[objects[c2].anim].frame[objects[c2].frame].ticks;
  2122.                                                                                 objects[c2].image = object_anims[objects[c2].anim].frame[objects[c2].frame].image;
  2123.                                                                                 break;
  2124.                                                                         }
  2125.                                                                 } else if (GET_BAN_MAP_XY((s1 + 15), (s2 + 15)) == BAN_SPRING) {
  2126.                                                                         if ((objects[c2].x >> 20) == ((s1 + 15) >> 4) && (objects[c2].y >> 20) == ((s2 + 15) >> 4)) {
  2127.                                                                                 objects[c2].frame = 0;
  2128.                                                                                 objects[c2].ticks = object_anims[objects[c2].anim].frame[objects[c2].frame].ticks;
  2129.                                                                                 objects[c2].image = object_anims[objects[c2].anim].frame[objects[c2].frame].image;
  2130.                                                                                 break;
  2131.                                                                         }
  2132.                                                                 }
  2133.                                                         }
  2134.                                                 }
  2135.                                         }
  2136.                                         dj_play_sfx(SFX_SPRING, (unsigned short)(SFX_SPRING_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
  2137.                                 }
  2138.                                 s1 = (player[c1].x >> 16);
  2139.                                 s2 = (player[c1].y >> 16);
  2140.                                 if (s2 < 0)
  2141.                                         s2 = 0;
  2142.                                 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) {
  2143.                                         player[c1].y = (((s2 + 16) & 0xfff0)) << 16;
  2144.                                         player[c1].y_add = 0;
  2145.                                         player[c1].anim = 0;
  2146.                                         player[c1].frame = 0;
  2147.                                         player[c1].frame_tick = 0;
  2148.                                         player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
  2149.                                 }
  2150.                                 s1 = (player[c1].x >> 16);
  2151.                                 s2 = (player[c1].y >> 16);
  2152.                                 if (s2 < 0)
  2153.                                         s2 = 0;
  2154.                                 if (GET_BAN_MAP_XY((s1 + 8), (s2 + 8)) == BAN_WATER) {
  2155.                                         if (player[c1].in_water == 0) {
  2156.                                                 /* falling into water */
  2157.                                                 player[c1].in_water = 1;
  2158.                                                 player[c1].anim = 4;
  2159.                                                 player[c1].frame = 0;
  2160.                                                 player[c1].frame_tick = 0;
  2161.                                                 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
  2162.                                                 if (player[c1].y_add >= 32768) {
  2163.                                                         add_object(OBJ_SPLASH, (player[c1].x >> 16) + 8, ((player[c1].y >> 16) & 0xfff0) + 15, 0, 0, OBJ_ANIM_SPLASH, 0);
  2164.                                                         if (blood_is_thicker_than_water == 0)
  2165.                                                                 dj_play_sfx(SFX_SPLASH, (unsigned short)(SFX_SPLASH_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
  2166.                                                         else
  2167.                                                                 dj_play_sfx(SFX_SPLASH, (unsigned short)(SFX_SPLASH_FREQ + rnd(2000) - 5000), 64, 0, 0, -1);
  2168.                                                 }
  2169.                                         }
  2170.                                         /* slowly move up to water surface */
  2171.                                         player[c1].y_add -= 1536;
  2172.                                         if (player[c1].y_add < 0 && player[c1].anim != 5) {
  2173.                                                 player[c1].anim = 5;
  2174.                                                 player[c1].frame = 0;
  2175.                                                 player[c1].frame_tick = 0;
  2176.                                                 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
  2177.                                         }
  2178.                                         if (player[c1].y_add < -65536L)
  2179.                                                 player[c1].y_add = -65536L;
  2180.                                         if (player[c1].y_add > 65535L)
  2181.                                                 player[c1].y_add = 65535L;
  2182.                                         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) {
  2183.                                                 player[c1].y = (((s2 + 16) & 0xfff0) - 16) << 16;
  2184.                                                 player[c1].y_add = 0;
  2185.                                         }
  2186.                                 } 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) {
  2187.                                         player[c1].in_water = 0;
  2188.                                         player[c1].y = (((s2 + 16) & 0xfff0) - 16) << 16;
  2189.                                         player[c1].y_add = 0;
  2190.                                         if (player[c1].anim != 0 && player[c1].anim != 1) {
  2191.                                                 player[c1].anim = 0;
  2192.                                                 player[c1].frame = 0;
  2193.                                                 player[c1].frame_tick = 0;
  2194.                                                 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
  2195.                                         }
  2196.                                 } else {
  2197.                                         if (player[c1].in_water == 0) {
  2198.                                                 if (bunnies_in_space == 0)
  2199.                                                         player[c1].y_add += 12288;
  2200.                                                 else
  2201.                                                         player[c1].y_add += 6144;
  2202.                                                 if (player[c1].y_add > 327680L)
  2203.                                                         player[c1].y_add = 327680L;
  2204.                                         } else {
  2205.                                                 player[c1].y = (player[c1].y & 0xffff0000) + 0x10000;
  2206.                                                 player[c1].y_add = 0;
  2207.                                         }
  2208.                                         player[c1].in_water = 0;
  2209.                                 }
  2210.                                 if (player[c1].y_add > 36864 && player[c1].anim != 3 && player[c1].in_water == 0) {
  2211.                                         player[c1].anim = 3;
  2212.                                         player[c1].frame = 0;
  2213.                                         player[c1].frame_tick = 0;
  2214.                                         player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
  2215.                                 }
  2216.  
  2217.                         }
  2218.  
  2219.                         player[c1].frame_tick++;
  2220.                         if (player[c1].frame_tick >= player_anims[player[c1].anim].frame[player[c1].frame].ticks) {
  2221.                                 player[c1].frame++;
  2222.                                 if (player[c1].frame >= player_anims[player[c1].anim].num_frames) {
  2223.                                         if (player[c1].anim != 6)
  2224.                                                 player[c1].frame = player_anims[player[c1].anim].restart_frame;
  2225.                                         else
  2226.                                                 position_player(c1);
  2227.                                 }
  2228.                                 player[c1].frame_tick = 0;
  2229.                         }
  2230.                         player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
  2231.  
  2232.                 }
  2233.  
  2234.         }
  2235.  
  2236. }
  2237.  
  2238.  
  2239. void position_player(int player_num)
  2240. {
  2241.         int c1;
  2242.         int s1, s2;
  2243.  
  2244.         while (1) {
  2245.                 while (1) {
  2246.                         s1 = rnd(22);
  2247.                         s2 = rnd(16);
  2248.                         if (ban_map[s2][s1] == BAN_VOID && (ban_map[s2 + 1][s1] == BAN_SOLID || ban_map[s2 + 1][s1] == BAN_ICE))
  2249.                                 break;
  2250.                 }
  2251.                 for (c1 = 0; c1 < JNB_MAX_PLAYERS; c1++) {
  2252.                         if (c1 != player_num && player[c1].enabled == 1) {
  2253.                                 if (abs((s1 << 4) - (player[c1].x >> 16)) < 32 && abs((s2 << 4) - (player[c1].y >> 16)) < 32)
  2254.                                         break;
  2255.                         }
  2256.                 }
  2257.                 if (c1 == JNB_MAX_PLAYERS) {
  2258.                         player[player_num].x = (long) s1 << 20;
  2259.                         player[player_num].y = (long) s2 << 20;
  2260.                         player[player_num].x_add = player[player_num].y_add = 0;
  2261.                         player[player_num].direction = 0;
  2262.                         player[player_num].jump_ready = 1;
  2263.                         player[player_num].in_water = 0;
  2264.                         player[player_num].anim = 0;
  2265.                         player[player_num].frame = 0;
  2266.                         player[player_num].frame_tick = 0;
  2267.                         player[player_num].image = player_anims[player[player_num].anim].frame[player[player_num].frame].image;
  2268.  
  2269.                         if (is_server) {
  2270. #ifdef USE_NET
  2271.                                 if (is_net)
  2272.                                         serverSendAlive(player_num);
  2273. #endif
  2274.                                 player[player_num].dead_flag = 0;
  2275.                         }
  2276.  
  2277.                         break;
  2278.                 }
  2279.         }
  2280.  
  2281. }
  2282.  
  2283.  
  2284. void add_object(int type, int x, int y, int x_add, int y_add, int anim, int frame)
  2285. {
  2286.         int c1;
  2287.  
  2288.         for (c1 = 0; c1 < NUM_OBJECTS; c1++) {
  2289.                 if (objects[c1].used == 0) {
  2290.                         objects[c1].used = 1;
  2291.                         objects[c1].type = type;
  2292.                         objects[c1].x = (long) x << 16;
  2293.                         objects[c1].y = (long) y << 16;
  2294.                         objects[c1].x_add = x_add;
  2295.                         objects[c1].y_add = y_add;
  2296.                         objects[c1].x_acc = 0;
  2297.                         objects[c1].y_acc = 0;
  2298.                         objects[c1].anim = anim;
  2299.                         objects[c1].frame = frame;
  2300.                         objects[c1].ticks = object_anims[anim].frame[frame].ticks;
  2301.                         objects[c1].image = object_anims[anim].frame[frame].image;
  2302.                         break;
  2303.                 }
  2304.         }
  2305.  
  2306. }
  2307.  
  2308.  
  2309. void update_objects(void)
  2310. {
  2311.         int c1;
  2312.         int s1 = 0;
  2313.  
  2314.         for (c1 = 0; c1 < NUM_OBJECTS; c1++) {
  2315.                 if (objects[c1].used == 1) {
  2316.                         switch (objects[c1].type) {
  2317.                         case OBJ_SPRING:
  2318.                                 objects[c1].ticks--;
  2319.                                 if (objects[c1].ticks <= 0) {
  2320.                                         objects[c1].frame++;
  2321.                                         if (objects[c1].frame >= object_anims[objects[c1].anim].num_frames) {
  2322.                                                 objects[c1].frame--;
  2323.                                                 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
  2324.                                         } else {
  2325.                                                 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
  2326.                                                 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
  2327.                                         }
  2328.                                 }
  2329.                                 if (objects[c1].used == 1)
  2330.                                         add_pob(main_info.draw_page, objects[c1].x >> 16, objects[c1].y >> 16, objects[c1].image, &object_gobs);
  2331.                                 break;
  2332.                         case OBJ_SPLASH:
  2333.                                 objects[c1].ticks--;
  2334.                                 if (objects[c1].ticks <= 0) {
  2335.                                         objects[c1].frame++;
  2336.                                         if (objects[c1].frame >= object_anims[objects[c1].anim].num_frames)
  2337.                                                 objects[c1].used = 0;
  2338.                                         else {
  2339.                                                 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
  2340.                                                 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
  2341.                                         }
  2342.                                 }
  2343.                                 if (objects[c1].used == 1)
  2344.                                         add_pob(main_info.draw_page, objects[c1].x >> 16, objects[c1].y >> 16, objects[c1].image, &object_gobs);
  2345.                                 break;
  2346.                         case OBJ_SMOKE:
  2347.                                 objects[c1].x += objects[c1].x_add;
  2348.                                 objects[c1].y += objects[c1].y_add;
  2349.                                 objects[c1].ticks--;
  2350.                                 if (objects[c1].ticks <= 0) {
  2351.                                         objects[c1].frame++;
  2352.                                         if (objects[c1].frame >= object_anims[objects[c1].anim].num_frames)
  2353.                                                 objects[c1].used = 0;
  2354.                                         else {
  2355.                                                 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
  2356.                                                 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
  2357.                                         }
  2358.                                 }
  2359.                                 if (objects[c1].used == 1)
  2360.                                         add_pob(main_info.draw_page, objects[c1].x >> 16, objects[c1].y >> 16, objects[c1].image, &object_gobs);
  2361.                                 break;
  2362.                         case OBJ_YEL_BUTFLY:
  2363.                         case OBJ_PINK_BUTFLY:
  2364.                                 objects[c1].x_acc += rnd(128) - 64;
  2365.                                 if (objects[c1].x_acc < -1024)
  2366.                                         objects[c1].x_acc = -1024;
  2367.                                 if (objects[c1].x_acc > 1024)
  2368.                                         objects[c1].x_acc = 1024;
  2369.                                 objects[c1].x_add += objects[c1].x_acc;
  2370.                                 if (objects[c1].x_add < -32768)
  2371.                                         objects[c1].x_add = -32768;
  2372.                                 if (objects[c1].x_add > 32768)
  2373.                                         objects[c1].x_add = 32768;
  2374.                                 objects[c1].x += objects[c1].x_add;
  2375.                                 if ((objects[c1].x >> 16) < 16) {
  2376.                                         objects[c1].x = 16 << 16;
  2377.                                         objects[c1].x_add = -objects[c1].x_add >> 2;
  2378.                                         objects[c1].x_acc = 0;
  2379.                                 } else if ((objects[c1].x >> 16) > 350) {
  2380.                                         objects[c1].x = 350 << 16;
  2381.                                         objects[c1].x_add = -objects[c1].x_add >> 2;
  2382.                                         objects[c1].x_acc = 0;
  2383.                                 }
  2384.                                 if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] != 0) {
  2385.                                         if (objects[c1].x_add < 0) {
  2386.                                                 objects[c1].x = (((objects[c1].x >> 16) + 16) & 0xfff0) << 16;
  2387.                                         } else {
  2388.                                                 objects[c1].x = ((((objects[c1].x >> 16) - 16) & 0xfff0) + 15) << 16;
  2389.                                         }
  2390.                                         objects[c1].x_add = -objects[c1].x_add >> 2;
  2391.                                         objects[c1].x_acc = 0;
  2392.                                 }
  2393.                                 objects[c1].y_acc += rnd(64) - 32;
  2394.                                 if (objects[c1].y_acc < -1024)
  2395.                                         objects[c1].y_acc = -1024;
  2396.                                 if (objects[c1].y_acc > 1024)
  2397.                                         objects[c1].y_acc = 1024;
  2398.                                 objects[c1].y_add += objects[c1].y_acc;
  2399.                                 if (objects[c1].y_add < -32768)
  2400.                                         objects[c1].y_add = -32768;
  2401.                                 if (objects[c1].y_add > 32768)
  2402.                                         objects[c1].y_add = 32768;
  2403.                                 objects[c1].y += objects[c1].y_add;
  2404.                                 if ((objects[c1].y >> 16) < 0) {
  2405.                                         objects[c1].y = 0;
  2406.                                         objects[c1].y_add = -objects[c1].y_add >> 2;
  2407.                                         objects[c1].y_acc = 0;
  2408.                                 } else if ((objects[c1].y >> 16) > 255) {
  2409.                                         objects[c1].y = 255 << 16;
  2410.                                         objects[c1].y_add = -objects[c1].y_add >> 2;
  2411.                                         objects[c1].y_acc = 0;
  2412.                                 }
  2413.                                 if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] != 0) {
  2414.                                         if (objects[c1].y_add < 0) {
  2415.                                                 objects[c1].y = (((objects[c1].y >> 16) + 16) & 0xfff0) << 16;
  2416.                                         } else {
  2417.                                                 objects[c1].y = ((((objects[c1].y >> 16) - 16) & 0xfff0) + 15) << 16;
  2418.                                         }
  2419.                                         objects[c1].y_add = -objects[c1].y_add >> 2;
  2420.                                         objects[c1].y_acc = 0;
  2421.                                 }
  2422.                                 if (objects[c1].type == OBJ_YEL_BUTFLY) {
  2423.                                         if (objects[c1].x_add < 0 && objects[c1].anim != OBJ_ANIM_YEL_BUTFLY_LEFT) {
  2424.                                                 objects[c1].anim = OBJ_ANIM_YEL_BUTFLY_LEFT;
  2425.                                                 objects[c1].frame = 0;
  2426.                                                 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
  2427.                                                 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
  2428.                                         } else if (objects[c1].x_add > 0 && objects[c1].anim != OBJ_ANIM_YEL_BUTFLY_RIGHT) {
  2429.                                                 objects[c1].anim = OBJ_ANIM_YEL_BUTFLY_RIGHT;
  2430.                                                 objects[c1].frame = 0;
  2431.                                                 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
  2432.                                                 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
  2433.                                         }
  2434.                                 } else {
  2435.                                         if (objects[c1].x_add < 0 && objects[c1].anim != OBJ_ANIM_PINK_BUTFLY_LEFT) {
  2436.                                                 objects[c1].anim = OBJ_ANIM_PINK_BUTFLY_LEFT;
  2437.                                                 objects[c1].frame = 0;
  2438.                                                 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
  2439.                                                 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
  2440.                                         } else if (objects[c1].x_add > 0 && objects[c1].anim != OBJ_ANIM_PINK_BUTFLY_RIGHT) {
  2441.                                                 objects[c1].anim = OBJ_ANIM_PINK_BUTFLY_RIGHT;
  2442.                                                 objects[c1].frame = 0;
  2443.                                                 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
  2444.                                                 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
  2445.                                         }
  2446.                                 }
  2447.                                 objects[c1].ticks--;
  2448.                                 if (objects[c1].ticks <= 0) {
  2449.                                         objects[c1].frame++;
  2450.                                         if (objects[c1].frame >= object_anims[objects[c1].anim].num_frames)
  2451.                                                 objects[c1].frame = object_anims[objects[c1].anim].restart_frame;
  2452.                                         else {
  2453.                                                 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
  2454.                                                 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
  2455.                                         }
  2456.                                 }
  2457.                                 if (objects[c1].used == 1)
  2458.                                         add_pob(main_info.draw_page, objects[c1].x >> 16, objects[c1].y >> 16, objects[c1].image, &object_gobs);
  2459.                                 break;
  2460.                         case OBJ_FUR:
  2461.                                 if (rnd(100) < 30)
  2462.                                         add_object(OBJ_FLESH_TRACE, objects[c1].x >> 16, objects[c1].y >> 16, 0, 0, OBJ_ANIM_FLESH_TRACE, 0);
  2463.                                 if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 0) {
  2464.                                         objects[c1].y_add += 3072;
  2465.                                         if (objects[c1].y_add > 196608L)
  2466.                                                 objects[c1].y_add = 196608L;
  2467.                                 } else if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 2) {
  2468.                                         if (objects[c1].x_add < 0) {
  2469.                                                 if (objects[c1].x_add < -65536L)
  2470.                                                         objects[c1].x_add = -65536L;
  2471.                                                 objects[c1].x_add += 1024;
  2472.                                                 if (objects[c1].x_add > 0)
  2473.                                                         objects[c1].x_add = 0;
  2474.                                         } else {
  2475.                                                 if (objects[c1].x_add > 65536L)
  2476.                                                         objects[c1].x_add = 65536L;
  2477.                                                 objects[c1].x_add -= 1024;
  2478.                                                 if (objects[c1].x_add < 0)
  2479.                                                         objects[c1].x_add = 0;
  2480.                                         }
  2481.                                         objects[c1].y_add += 1024;
  2482.                                         if (objects[c1].y_add < -65536L)
  2483.                                                 objects[c1].y_add = -65536L;
  2484.                                         if (objects[c1].y_add > 65536L)
  2485.                                                 objects[c1].y_add = 65536L;
  2486.                                 }
  2487.                                 objects[c1].x += objects[c1].x_add;
  2488.                                 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)) {
  2489.                                         if (objects[c1].x_add < 0) {
  2490.                                                 objects[c1].x = (((objects[c1].x >> 16) + 16) & 0xfff0) << 16;
  2491.                                                 objects[c1].x_add = -objects[c1].x_add >> 2;
  2492.                                         } else {
  2493.                                                 objects[c1].x = ((((objects[c1].x >> 16) - 16) & 0xfff0) + 15) << 16;
  2494.                                                 objects[c1].x_add = -objects[c1].x_add >> 2;
  2495.                                         }
  2496.                                 }
  2497.                                 objects[c1].y += objects[c1].y_add;
  2498.                                 if ((objects[c1].x >> 16) < -5 || (objects[c1].x >> 16) > 405 || (objects[c1].y >> 16) > 260)
  2499.                                         objects[c1].used = 0;
  2500.                                 if ((objects[c1].y >> 16) > 0 && (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] != 0)) {
  2501.                                         if (objects[c1].y_add < 0) {
  2502.                                                 if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] != 2) {
  2503.                                                         objects[c1].y = (((objects[c1].y >> 16) + 16) & 0xfff0) << 16;
  2504.                                                         objects[c1].x_add >>= 2;
  2505.                                                         objects[c1].y_add = -objects[c1].y_add >> 2;
  2506.                                                 }
  2507.                                         } else {
  2508.                                                 if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 1) {
  2509.                                                         if (objects[c1].y_add > 131072L) {
  2510.                                                                 objects[c1].y = ((((objects[c1].y >> 16) - 16) & 0xfff0) + 15) << 16;
  2511.                                                                 objects[c1].x_add >>= 2;
  2512.                                                                 objects[c1].y_add = -objects[c1].y_add >> 2;
  2513.                                                         } else
  2514.                                                                 objects[c1].used = 0;
  2515.                                                 } else if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 3) {
  2516.                                                         objects[c1].y = ((((objects[c1].y >> 16) - 16) & 0xfff0) + 15) << 16;
  2517.                                                         if (objects[c1].y_add > 131072L)
  2518.                                                                 objects[c1].y_add = -objects[c1].y_add >> 2;
  2519.                                                         else
  2520.                                                                 objects[c1].y_add = 0;
  2521.                                                 }
  2522.                                         }
  2523.                                 }
  2524.                                 if (objects[c1].x_add < 0 && objects[c1].x_add > -16384)
  2525.                                         objects[c1].x_add = -16384;
  2526.                                 if (objects[c1].x_add > 0 && objects[c1].x_add < 16384)
  2527.                                         objects[c1].x_add = 16384;
  2528.                                 if (objects[c1].used == 1) {
  2529.                                         s1 = (int)(atan2(objects[c1].y_add, objects[c1].x_add) * 4 / M_PI);
  2530.                                         if (s1 < 0)
  2531.                                                 s1 += 8;
  2532.                                         if (s1 < 0)
  2533.                                                 s1 = 0;
  2534.                                         if (s1 > 7)
  2535.                                                 s1 = 7;
  2536.                                         add_pob(main_info.draw_page, objects[c1].x >> 16, objects[c1].y >> 16, objects[c1].frame + s1, &object_gobs);
  2537.                                 }
  2538.                                 break;
  2539.                         case OBJ_FLESH:
  2540.                                 if (rnd(100) < 30) {
  2541.                                         if (objects[c1].frame == 76)
  2542.                                                 add_object(OBJ_FLESH_TRACE, objects[c1].x >> 16, objects[c1].y >> 16, 0, 0, OBJ_ANIM_FLESH_TRACE, 1);
  2543.                                         else if (objects[c1].frame == 77)
  2544.                                                 add_object(OBJ_FLESH_TRACE, objects[c1].x >> 16, objects[c1].y >> 16, 0, 0, OBJ_ANIM_FLESH_TRACE, 2);
  2545.                                         else if (objects[c1].frame == 78)
  2546.                                                 add_object(OBJ_FLESH_TRACE, objects[c1].x >> 16, objects[c1].y >> 16, 0, 0, OBJ_ANIM_FLESH_TRACE, 3);
  2547.                                 }
  2548.                                 if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 0) {
  2549.                                         objects[c1].y_add += 3072;
  2550.                                         if (objects[c1].y_add > 196608L)
  2551.                                                 objects[c1].y_add = 196608L;
  2552.                                 } else if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 2) {
  2553.                                         if (objects[c1].x_add < 0) {
  2554.                                                 if (objects[c1].x_add < -65536L)
  2555.                                                         objects[c1].x_add = -65536L;
  2556.                                                 objects[c1].x_add += 1024;
  2557.                                                 if (objects[c1].x_add > 0)
  2558.                                                         objects[c1].x_add = 0;
  2559.                                         } else {
  2560.                                                 if (objects[c1].x_add > 65536L)
  2561.                                                         objects[c1].x_add = 65536L;
  2562.                                                 objects[c1].x_add -= 1024;
  2563.                                                 if (objects[c1].x_add < 0)
  2564.                                                         objects[c1].x_add = 0;
  2565.                                         }
  2566.                                         objects[c1].y_add += 1024;
  2567.                                         if (objects[c1].y_add < -65536L)
  2568.                                                 objects[c1].y_add = -65536L;
  2569.                                         if (objects[c1].y_add > 65536L)
  2570.                                                 objects[c1].y_add = 65536L;
  2571.                                 }
  2572.                                 objects[c1].x += objects[c1].x_add;
  2573.                                 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)) {
  2574.                                         if (objects[c1].x_add < 0) {
  2575.                                                 objects[c1].x = (((objects[c1].x >> 16) + 16) & 0xfff0) << 16;
  2576.                                                 objects[c1].x_add = -objects[c1].x_add >> 2;
  2577.                                         } else {
  2578.                                                 objects[c1].x = ((((objects[c1].x >> 16) - 16) & 0xfff0) + 15) << 16;
  2579.                                                 objects[c1].x_add = -objects[c1].x_add >> 2;
  2580.                                         }
  2581.                                 }
  2582.                                 objects[c1].y += objects[c1].y_add;
  2583.                                 if ((objects[c1].x >> 16) < -5 || (objects[c1].x >> 16) > 405 || (objects[c1].y >> 16) > 260)
  2584.                                         objects[c1].used = 0;
  2585.                                 if ((objects[c1].y >> 16) > 0 && (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] != 0)) {
  2586.                                         if (objects[c1].y_add < 0) {
  2587.                                                 if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] != 2) {
  2588.                                                         objects[c1].y = (((objects[c1].y >> 16) + 16) & 0xfff0) << 16;
  2589.                                                         objects[c1].x_add >>= 2;
  2590.                                                         objects[c1].y_add = -objects[c1].y_add >> 2;
  2591.                                                 }
  2592.                                         } else {
  2593.                                                 if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 1) {
  2594.                                                         if (objects[c1].y_add > 131072L) {
  2595.                                                                 objects[c1].y = ((((objects[c1].y >> 16) - 16) & 0xfff0) + 15) << 16;
  2596.                                                                 objects[c1].x_add >>= 2;
  2597.                                                                 objects[c1].y_add = -objects[c1].y_add >> 2;
  2598.                                                         } else {
  2599.                                                                 if (rnd(100) < 10) {
  2600.                                                                         s1 = rnd(4) - 2;
  2601.                                                                         add_leftovers(0, objects[c1].x >> 16, (objects[c1].y >> 16) + s1, objects[c1].frame, &object_gobs);
  2602.                                                                         add_leftovers(1, objects[c1].x >> 16, (objects[c1].y >> 16) + s1, objects[c1].frame, &object_gobs);
  2603.                                                                 }
  2604.                                                                 objects[c1].used = 0;
  2605.                                                         }
  2606.                                                 } else if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 3) {
  2607.                                                         objects[c1].y = ((((objects[c1].y >> 16) - 16) & 0xfff0) + 15) << 16;
  2608.                                                         if (objects[c1].y_add > 131072L)
  2609.                                                                 objects[c1].y_add = -objects[c1].y_add >> 2;
  2610.                                                         else
  2611.                                                                 objects[c1].y_add = 0;
  2612.                                                 }
  2613.                                         }
  2614.                                 }
  2615.                                 if (objects[c1].x_add < 0 && objects[c1].x_add > -16384)
  2616.                                         objects[c1].x_add = -16384;
  2617.                                 if (objects[c1].x_add > 0 && objects[c1].x_add < 16384)
  2618.                                         objects[c1].x_add = 16384;
  2619.                                 if (objects[c1].used == 1)
  2620.                                         add_pob(main_info.draw_page, objects[c1].x >> 16, objects[c1].y >> 16, objects[c1].frame, &object_gobs);
  2621.                                 break;
  2622.                         case OBJ_FLESH_TRACE:
  2623.                                 objects[c1].ticks--;
  2624.                                 if (objects[c1].ticks <= 0) {
  2625.                                         objects[c1].frame++;
  2626.                                         if (objects[c1].frame >= object_anims[objects[c1].anim].num_frames)
  2627.                                                 objects[c1].used = 0;
  2628.                                         else {
  2629.                                                 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
  2630.                                                 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
  2631.                                         }
  2632.                                 }
  2633.                                 if (objects[c1].used == 1)
  2634.                                         add_pob(main_info.draw_page, objects[c1].x >> 16, objects[c1].y >> 16, objects[c1].image, &object_gobs);
  2635.                                 break;
  2636.                         }
  2637.                 }
  2638.         }
  2639.  
  2640. }
  2641.  
  2642.  
  2643. int add_pob(int page, int x, int y, int image, gob_t *pob_data)
  2644. {
  2645.  
  2646.         if (main_info.page_info[page].num_pobs >= NUM_POBS)
  2647.                 return 1;
  2648.  
  2649.         main_info.page_info[page].pobs[main_info.page_info[page].num_pobs].x = x;
  2650.         main_info.page_info[page].pobs[main_info.page_info[page].num_pobs].y = y;
  2651.         main_info.page_info[page].pobs[main_info.page_info[page].num_pobs].image = image;
  2652.         main_info.page_info[page].pobs[main_info.page_info[page].num_pobs].pob_data = pob_data;
  2653.         main_info.page_info[page].num_pobs++;
  2654.  
  2655.         return 0;
  2656.  
  2657. }
  2658.  
  2659.  
  2660. void draw_flies(int page)
  2661. {
  2662.         int c2;
  2663.  
  2664.         for (c2 = 0; c2 < NUM_FLIES; c2++) {
  2665.                 flies[c2].back[main_info.draw_page] = get_pixel(main_info.draw_page, flies[c2].x, flies[c2].y);
  2666.                 flies[c2].back_defined[main_info.draw_page] = 1;
  2667.                 if (mask_pic[(flies[c2].y * JNB_WIDTH) + flies[c2].x] == 0)
  2668.                         set_pixel(main_info.draw_page, flies[c2].x, flies[c2].y, 0);
  2669.         }
  2670. }
  2671.  
  2672. void draw_pobs(int page)
  2673. {
  2674.         int c1;
  2675.         int back_buf_ofs;
  2676.  
  2677.         back_buf_ofs = 0;
  2678.  
  2679.         for (c1 = main_info.page_info[page].num_pobs - 1; c1 >= 0; c1--) {
  2680.                 main_info.page_info[page].pobs[c1].back_buf_ofs = back_buf_ofs;
  2681.                 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);
  2682.                 if (scale_up)
  2683.                         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;
  2684.                 else
  2685.                         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);
  2686.                 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);
  2687.         }
  2688.  
  2689. }
  2690.  
  2691.  
  2692. void redraw_flies_background(int page)
  2693. {
  2694.         int c2;
  2695.  
  2696.         for (c2 = NUM_FLIES - 1; c2 >= 0; c2--) {
  2697.                 if (flies[c2].back_defined[page] == 1)
  2698.                         set_pixel(page, flies[c2].old_draw_x, flies[c2].old_draw_y, flies[c2].back[page]);
  2699.                 flies[c2].old_draw_x = flies[c2].x;
  2700.                 flies[c2].old_draw_y = flies[c2].y;
  2701.         }
  2702. }
  2703.  
  2704.  
  2705. void redraw_pob_backgrounds(int page)
  2706. {
  2707.         int c1;
  2708.  
  2709.         for (c1 = 0; c1 < main_info.page_info[page].num_pobs; c1++)
  2710.                 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);
  2711.  
  2712. }
  2713.  
  2714.  
  2715. int add_leftovers(int page, int x, int y, int image, gob_t *pob_data)
  2716. {
  2717.  
  2718.         if (leftovers.page[page].num_pobs >= NUM_LEFTOVERS)
  2719.                 return 1;
  2720.  
  2721.         leftovers.page[page].pobs[leftovers.page[page].num_pobs].x = x;
  2722.         leftovers.page[page].pobs[leftovers.page[page].num_pobs].y = y;
  2723.         leftovers.page[page].pobs[leftovers.page[page].num_pobs].image = image;
  2724.         leftovers.page[page].pobs[leftovers.page[page].num_pobs].pob_data = pob_data;
  2725.         leftovers.page[page].num_pobs++;
  2726.  
  2727.         return 0;
  2728.  
  2729. }
  2730.  
  2731.  
  2732. void draw_leftovers(int page)
  2733. {
  2734.         int c1;
  2735.  
  2736.         for (c1 = leftovers.page[page].num_pobs - 1; c1 >= 0; c1--)
  2737.                 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);
  2738.  
  2739.         leftovers.page[page].num_pobs = 0;
  2740.  
  2741. }
  2742.  
  2743.  
  2744. int init_level(int level, char *pal)
  2745. {
  2746.         unsigned char *handle;
  2747.         int c1, c2;
  2748.         int s1, s2;
  2749.  
  2750.         if ((handle = dat_open("level.pcx")) == 0) {
  2751.                 strcpy(main_info.error_str, "Error loading 'level.pcx', aborting...\n");
  2752.                 return 1;
  2753.         }
  2754.         if (read_pcx(handle, background_pic, JNB_WIDTH*JNB_HEIGHT, pal) != 0) {
  2755.                 strcpy(main_info.error_str, "Error loading 'level.pcx', aborting...\n");
  2756.                 return 1;
  2757.         }
  2758.         if (flip)
  2759.                 flip_pixels(background_pic);
  2760.         if ((handle = dat_open("mask.pcx")) == 0) {
  2761.                 strcpy(main_info.error_str, "Error loading 'mask.pcx', aborting...\n");
  2762.                 return 1;
  2763.         }
  2764.         if (read_pcx(handle, mask_pic, JNB_WIDTH*JNB_HEIGHT, 0) != 0) {
  2765.                 strcpy(main_info.error_str, "Error loading 'mask.pcx', aborting...\n");
  2766.                 return 1;
  2767.         }
  2768.         if (flip)
  2769.                 flip_pixels(mask_pic);
  2770.         register_mask(mask_pic);
  2771.  
  2772.         for (c1 = 0; c1 < JNB_MAX_PLAYERS; c1++) {
  2773.                 if (player[c1].enabled == 1) {
  2774.                         player[c1].bumps = 0;
  2775.                         for (c2 = 0; c2 < JNB_MAX_PLAYERS; c2++)
  2776.                                 player[c1].bumped[c2] = 0;
  2777.                         position_player(c1);
  2778.                 }
  2779.         }
  2780.  
  2781.         for (c1 = 0; c1 < NUM_OBJECTS; c1++)
  2782.                 objects[c1].used = 0;
  2783.  
  2784.         for (c1 = 0; c1 < 16; c1++) {
  2785.                 for (c2 = 0; c2 < 22; c2++) {
  2786.                         if (ban_map[c1][c2] == BAN_SPRING)
  2787.                                 add_object(OBJ_SPRING, c2 << 4, c1 << 4, 0, 0, OBJ_ANIM_SPRING, 5);
  2788.                 }
  2789.         }
  2790.  
  2791.         while (1) {
  2792.                 s1 = rnd(22);
  2793.                 s2 = rnd(16);
  2794.                 if (ban_map[s2][s1] == BAN_VOID) {
  2795.                         add_object(OBJ_YEL_BUTFLY, (s1 << 4) + 8, (s2 << 4) + 8, (rnd(65535) - 32768) * 2, (rnd(65535) - 32768) * 2, 0, 0);
  2796.                         break;
  2797.                 }
  2798.         }
  2799.         while (1) {
  2800.                 s1 = rnd(22);
  2801.                 s2 = rnd(16);
  2802.                 if (ban_map[s2][s1] == BAN_VOID) {
  2803.                         add_object(OBJ_YEL_BUTFLY, (s1 << 4) + 8, (s2 << 4) + 8, (rnd(65535) - 32768) * 2, (rnd(65535) - 32768) * 2, 0, 0);
  2804.                         break;
  2805.                 }
  2806.         }
  2807.         while (1) {
  2808.                 s1 = rnd(22);
  2809.                 s2 = rnd(16);
  2810.                 if (ban_map[s2][s1] == BAN_VOID) {
  2811.                         add_object(OBJ_PINK_BUTFLY, (s1 << 4) + 8, (s2 << 4) + 8, (rnd(65535) - 32768) * 2, (rnd(65535) - 32768) * 2, 0, 0);
  2812.                         break;
  2813.                 }
  2814.         }
  2815.         while (1) {
  2816.                 s1 = rnd(22);
  2817.                 s2 = rnd(16);
  2818.                 if (ban_map[s2][s1] == BAN_VOID) {
  2819.                         add_object(OBJ_PINK_BUTFLY, (s1 << 4) + 8, (s2 << 4) + 8, (rnd(65535) - 32768) * 2, (rnd(65535) - 32768) * 2, 0, 0);
  2820.                         break;
  2821.                 }
  2822.         }
  2823.  
  2824.         return 0;
  2825.  
  2826. }
  2827.  
  2828.  
  2829. void deinit_level(void)
  2830. {
  2831.         dj_set_nosound(1);
  2832.         dj_stop_mod();
  2833. }
  2834.  
  2835.  
  2836. #ifndef PATH_MAX
  2837. #define PATH_MAX 1024
  2838. #endif
  2839. #ifndef O_BINARY
  2840. #define O_BINARY 0
  2841. #endif
  2842.  
  2843. unsigned char *datafile_buffer = NULL;
  2844.  
  2845. static void preread_datafile(const char *fname)
  2846. {
  2847.     int fd = 0;
  2848.     int len;
  2849.  
  2850. #ifdef ZLIB_SUPPORT
  2851.     char *gzfilename;
  2852.     gzFile gzf;
  2853. #endif
  2854.  
  2855. #ifdef BZLIB_SUPPORT
  2856.     char *bzfilename;
  2857.     BZFILE *bzf;
  2858. #endif
  2859.  
  2860. #ifdef BZLIB_SUPPORT
  2861.     bzfilename = malloc(strlen(fname) + 5);
  2862.     strcpy(bzfilename, fname);
  2863.     strcat(bzfilename, ".bz2");
  2864.     bzf = BZ2_bzopen(bzfilename, "rb");
  2865.     free(bzfilename);
  2866.     bzfilename = NULL;
  2867.  
  2868.     if (bzf != NULL) {
  2869.         int bufsize = 0;
  2870.         int bufpos = 0;
  2871.         int br;
  2872.         unsigned char *ptr;
  2873.         do {
  2874.             if (bufpos >= bufsize) {
  2875.                 bufsize += 1024 * 1024;
  2876.                 datafile_buffer = (unsigned char *) realloc(datafile_buffer, bufsize);
  2877.                 if (datafile_buffer == NULL) {
  2878.                     perror("realloc()");
  2879.                     exit(42);
  2880.                 }
  2881.             }
  2882.  
  2883.             br = BZ2_bzread(bzf, datafile_buffer + bufpos, bufsize - bufpos);
  2884.             if (br == -1) {
  2885.                 fprintf(stderr, "gzread failed.\n");
  2886.                 exit(42);
  2887.             }
  2888.  
  2889.             bufpos += br;
  2890.         } while (br>0);
  2891.  
  2892.         /* try to shrink buffer... */
  2893.         ptr = (unsigned char *) realloc(datafile_buffer, bufpos);
  2894.         if (ptr != NULL)
  2895.             datafile_buffer = ptr;
  2896.  
  2897.         BZ2_bzclose(bzf);
  2898.         return;
  2899.     }
  2900.  
  2901.     /* drop through and try for an gzip compressed or uncompressed datafile... */
  2902. #endif
  2903.  
  2904. #ifdef ZLIB_SUPPORT
  2905.     gzfilename = malloc(strlen(fname) + 4);
  2906.     strcpy(gzfilename, fname);
  2907.     strcat(gzfilename, ".gz");
  2908.     gzf = gzopen(gzfilename, "rb");
  2909.     free(gzfilename);
  2910.     gzfilename = NULL;
  2911.  
  2912.     if (gzf != NULL) {
  2913.         int bufsize = 0;
  2914.         int bufpos = 0;
  2915.         unsigned char *ptr;
  2916.         do {
  2917.             int br;
  2918.             if (bufpos >= bufsize) {
  2919.                 bufsize += 1024 * 1024;
  2920.                 datafile_buffer = (unsigned char *) realloc(datafile_buffer, bufsize);
  2921.                 if (datafile_buffer == NULL) {
  2922.                     perror("realloc()");
  2923.                     exit(42);
  2924.                 }
  2925.             }
  2926.  
  2927.             br = gzread(gzf, datafile_buffer + bufpos, bufsize - bufpos);
  2928.             if (br == -1) {
  2929.                 fprintf(stderr, "gzread failed.\n");
  2930.                 exit(42);
  2931.             }
  2932.  
  2933.             bufpos += br;
  2934.         } while (!gzeof(gzf));
  2935.  
  2936.         /* try to shrink buffer... */
  2937.         ptr = (unsigned char *) realloc(datafile_buffer, bufpos);
  2938.         if (ptr != NULL)
  2939.             datafile_buffer = ptr;
  2940.  
  2941.         gzclose(gzf);
  2942.         return;
  2943.     }
  2944.  
  2945.     /* drop through and try for an uncompressed datafile... */
  2946. #endif
  2947.  
  2948.     fd = open(fname, O_RDONLY | O_BINARY);
  2949.     if (fd == -1) {
  2950.         fprintf(stderr, "can't open %s:", fname);
  2951.         perror("");
  2952.         exit(42);
  2953.     }
  2954.  
  2955.     len = filelength(fd);
  2956.     datafile_buffer = (unsigned char *) malloc(len);
  2957.     if (datafile_buffer == NULL) {
  2958.         perror("malloc()");
  2959.         close(fd);
  2960.         exit(42);
  2961.     }
  2962.  
  2963.     if (read(fd, datafile_buffer, len) != len) {
  2964.         perror("read()");
  2965.         close(fd);
  2966.         exit(42);
  2967.     }
  2968.  
  2969.     close(fd);
  2970. }
  2971.  
  2972.  
  2973. int init_program(int argc, char *argv[], char *pal)
  2974. {
  2975.         char *netarg = NULL;
  2976.         unsigned char *handle = (unsigned char *) NULL;
  2977.         int c1 = 0, c2 = 0;
  2978.         int load_flag = 0;
  2979.         int force2, force3;
  2980.         sfx_data fly;
  2981.         int player_anim_data[] = {
  2982.                 1, 0, 0, 0x7fff, 0, 0, 0, 0, 0, 0,
  2983.                 4, 0, 0, 4, 1, 4, 2, 4, 3, 4,
  2984.                 1, 0, 4, 0x7fff, 0, 0, 0, 0, 0, 0,
  2985.                 4, 2, 5, 8, 6, 10, 7, 3, 6, 3,
  2986.                 1, 0, 6, 0x7fff, 0, 0, 0, 0, 0, 0,
  2987.                 2, 1, 5, 8, 4, 0x7fff, 0, 0, 0, 0,
  2988.                 1, 0, 8, 5, 0, 0, 0, 0, 0, 0
  2989.         };
  2990.  
  2991. #ifdef USE_NET
  2992.         memset(&net_info, 0, sizeof(net_info));
  2993. #endif
  2994.  
  2995. #ifdef DOS
  2996.         if (__djgpp_nearptr_enable() == 0)
  2997.                 return 1;
  2998. #endif
  2999.  
  3000.         srand(time(NULL));
  3001.  
  3002.         if (hook_keyb_handler() != 0)
  3003.                 return 1;
  3004.  
  3005.         memset(&main_info, 0, sizeof(main_info));
  3006.  
  3007.         strcpy(datfile_name, DATA_PATH);
  3008.  
  3009.         force2 = force3 = 0;
  3010.  
  3011.         if (argc > 1) {
  3012.                 for (c1 = 1; c1 < argc; c1++) {
  3013.                         if (stricmp(argv[c1], "-nosound") == 0)
  3014.                                 main_info.no_sound = 1;
  3015.                         else if (stricmp(argv[c1], "-musicnosound") == 0)
  3016.                                 main_info.music_no_sound = 1;
  3017.                         else if (stricmp(argv[c1], "-nogore") == 0)
  3018.                                 main_info.no_gore = 1;
  3019.                         else if (stricmp(argv[c1], "-noflies") == 0)
  3020.                                 flies_enabled = 0;
  3021.                         else if (stricmp(argv[c1], "-nojoy") == 0)
  3022.                                 main_info.joy_enabled = 0;
  3023.                         else if (stricmp(argv[c1], "-fireworks") == 0)
  3024.                                 main_info.fireworks = 1;
  3025. #ifdef USE_SDL
  3026.                         else if (stricmp(argv[c1], "-fullscreen") == 0)
  3027.                                 fs_toggle();
  3028. #endif
  3029.                         else if (stricmp(argv[c1], "-scaleup") == 0)
  3030.                                 set_scaling(1);
  3031.                         else if (stricmp(argv[c1], "-mirror") == 0)
  3032.                                 flip = 1;
  3033.                         else if (stricmp(argv[c1], "-dat") == 0) {
  3034.                                 if (c1 < (argc - 1)) {
  3035.                                         FILE *f;
  3036.  
  3037.                                         if ((f = fopen(argv[c1 + 1], "rb")) != NULL) {
  3038.                                                 fclose(f);
  3039.                                                 strcpy(datfile_name, argv[c1 + 1]);
  3040.                                         }
  3041.                                 }
  3042.                         } else if (stricmp(argv[c1], "-player") == 0) {
  3043.                                 if (c1 < (argc - 1)) {
  3044.                                         if (client_player_num < 0)
  3045.                                                 client_player_num = atoi(argv[c1 + 1]);
  3046.                                 }
  3047. #ifdef USE_NET
  3048.                         } else if (stricmp(argv[c1], "-server") == 0) {
  3049.                                 if (c1 < (argc - 1)) {
  3050.                                         is_server = 1;
  3051.                                         is_net = 1;
  3052.                                         netarg = argv[c1 + 1];
  3053.                                 }
  3054.                         } else if (stricmp(argv[c1], "-connect") == 0) {
  3055.                                 if (c1 < (argc - 1)) {
  3056.                                         is_server = 0;
  3057.                                         is_net = 1;
  3058.                                         netarg = argv[c1 + 1];
  3059.                                 }
  3060. #endif
  3061.                         } else if (stricmp(argv[c1], "-mouse") == 0) {
  3062.                                 if (c1 < (argc - 1)) {
  3063.                                         if (stricmp(argv[c1 + 1], "2") == 0)
  3064.                                                 force2 = 1;
  3065.                                         if (stricmp(argv[c1 + 1], "3") == 0)
  3066.                                                 force3 = 1;
  3067.                                 }
  3068.                         }
  3069.                         else if (strstr(argv[1],"-v")) {
  3070.                                 printf("jumpnbump %s compiled %s at %s with",JNB_VERSION,__DATE__,__TIME__);
  3071. #ifndef USE_NET
  3072.                                 printf("out");
  3073. #endif
  3074.                                 printf(" network support.\n");
  3075.                                 return 1;
  3076.                         }
  3077.                         else if (strstr(argv[1],"-h")) {
  3078.                                 printf("Usage: jumpnbump [OPTION]...\n");
  3079.                                 printf("\n");
  3080.                                 printf("  -h                       this help\n");
  3081.                                 printf("  -v                       print version\n");
  3082.                                 printf("  -dat level.dat           play a different level\n");
  3083. #ifdef USE_NET
  3084.                                 printf("  -server playercount      start as server waiting for players\n");
  3085.                                 printf("  -connect host            connect to server\n");
  3086. #endif
  3087.                                 printf("  -player num              set main player to num (0-3). Needed for networking\n");
  3088.                                 printf("  -fireworks               screensaver mode\n");
  3089.                                 printf("  -fullscreen              run in fullscreen mode\n");
  3090.                                 printf("  -nosound                 play without sound\n");
  3091.                                 printf("  -nogore                  play without blood\n");
  3092.                                 printf("  -noflies                 disable flies\n");
  3093.                                 printf("  -mirror                  play with mirrored level\n");
  3094.                                 printf("  -scaleup                 play with doubled resolution (800x512)\n");
  3095.                                 printf("  -musicnosound            play with music but without sound\n");
  3096.                                 printf("\n");
  3097.                                 return 1;
  3098.                         }
  3099.                 }
  3100.         }
  3101.  
  3102.         preread_datafile(datfile_name);
  3103.  
  3104. #if 0
  3105. /** It should not be necessary to assign a default player number here. The
  3106. server assigns one in init_server, the client gets one assigned by the server,
  3107. all provided the user didn't choose one on the commandline. */
  3108.         if (is_net) {
  3109.                 if (client_player_num < 0)
  3110.                         client_player_num = 0;
  3111.                 player[client_player_num].enabled = 1;
  3112.         }
  3113. #endif
  3114.  
  3115.         main_info.pob_backbuf[0] = malloc(screen_pitch*screen_height);
  3116.         main_info.pob_backbuf[1] = malloc(screen_pitch*screen_height);
  3117.  
  3118.         for (c1 = 0; c1 < 7; c1++) {
  3119.                 player_anims[c1].num_frames = player_anim_data[c1 * 10];
  3120.                 player_anims[c1].restart_frame = player_anim_data[c1 * 10 + 1];
  3121.                 for (c2 = 0; c2 < 4; c2++) {
  3122.                         player_anims[c1].frame[c2].image = player_anim_data[c1 * 10 + c2 * 2 + 2];
  3123.                         player_anims[c1].frame[c2].ticks = player_anim_data[c1 * 10 + c2 * 2 + 3];
  3124.                 }
  3125.         }
  3126.  
  3127.         if ((handle = dat_open("menu.pcx")) == 0) {
  3128.                 strcpy(main_info.error_str, "Error loading 'menu.pcx', aborting...\n");
  3129.                 return 1;
  3130.         }
  3131.         if (read_pcx(handle, background_pic, JNB_WIDTH*JNB_HEIGHT, pal) != 0) {
  3132.                 strcpy(main_info.error_str, "Error loading 'menu.pcx', aborting...\n");
  3133.                 return 1;
  3134.         }
  3135.  
  3136.         if ((handle = dat_open("rabbit.gob")) == 0) {
  3137.                 strcpy(main_info.error_str, "Error loading 'rabbit.gob', aborting...\n");
  3138.                 return 1;
  3139.         }
  3140.         if (register_gob(handle, &rabbit_gobs, dat_filelen("rabbit.gob"))) {
  3141.                 /* error */
  3142.                 return 1;
  3143.         }
  3144.  
  3145.         if ((handle = dat_open("objects.gob")) == 0) {
  3146.                 strcpy(main_info.error_str, "Error loading 'objects.gob', aborting...\n");
  3147.                 return 1;
  3148.         }
  3149.         if (register_gob(handle, &object_gobs, dat_filelen("objects.gob"))) {
  3150.                 /* error */
  3151.                 return 1;
  3152.         }
  3153.  
  3154.         if ((handle = dat_open("font.gob")) == 0) {
  3155.                 strcpy(main_info.error_str, "Error loading 'font.gob', aborting...\n");
  3156.                 return 1;
  3157.         }
  3158.         if (register_gob(handle, &font_gobs, dat_filelen("font.gob"))) {
  3159.                 /* error */
  3160.                 return 1;
  3161.         }
  3162.  
  3163.         if ((handle = dat_open("numbers.gob")) == 0) {
  3164.                 strcpy(main_info.error_str, "Error loading 'numbers.gob', aborting...\n");
  3165.                 return 1;
  3166.         }
  3167.         if (register_gob(handle, &number_gobs, dat_filelen("numbers.gob"))) {
  3168.                 /* error */
  3169.                 return 1;
  3170.         }
  3171.  
  3172.         if (read_level() != 0) {
  3173.                 strcpy(main_info.error_str, "Error loading 'levelmap.txt', aborting...\n");
  3174.                 return 1;
  3175.         }
  3176.  
  3177.         dj_init();
  3178.  
  3179.         if (main_info.no_sound == 0) {
  3180.                 dj_autodetect_sd();
  3181.                 dj_set_mixing_freq(20000);
  3182.                 dj_set_stereo(0);
  3183.                 dj_set_auto_mix(0);
  3184.                 dj_set_dma_time(8);
  3185.                 dj_set_num_sfx_channels(5);
  3186.                 dj_set_sfx_volume(64);
  3187.                 dj_set_nosound(1);
  3188.                 dj_start();
  3189.  
  3190.                 if ((handle = dat_open("jump.mod")) == 0) {
  3191.                         strcpy(main_info.error_str, "Error loading 'jump.mod', aborting...\n");
  3192.                         return 1;
  3193.                 }
  3194.                 if (dj_load_mod(handle, 0, MOD_MENU) != 0) {
  3195.                         strcpy(main_info.error_str, "Error loading 'jump.mod', aborting...\n");
  3196.                         return 1;
  3197.                 }
  3198.  
  3199.                 if ((handle = dat_open("bump.mod")) == 0) {
  3200.                         strcpy(main_info.error_str, "Error loading 'bump.mod', aborting...\n");
  3201.                         return 1;
  3202.                 }
  3203.                 if (dj_load_mod(handle, 0, MOD_GAME) != 0) {
  3204.                         strcpy(main_info.error_str, "Error loading 'bump.mod', aborting...\n");
  3205.                         return 1;
  3206.                 }
  3207.  
  3208.                 if ((handle = dat_open("scores.mod")) == 0) {
  3209.                         strcpy(main_info.error_str, "Error loading 'scores.mod', aborting...\n");
  3210.                         return 1;
  3211.                 }
  3212.                 if (dj_load_mod(handle, 0, MOD_SCORES) != 0) {
  3213.                         strcpy(main_info.error_str, "Error loading 'scores.mod', aborting...\n");
  3214.                         return 1;
  3215.                 }
  3216.  
  3217.                 if ((handle = dat_open("jump.smp")) == 0) {
  3218.                         strcpy(main_info.error_str, "Error loading 'jump.smp', aborting...\n");
  3219.                         return 1;
  3220.                 }
  3221.                 if (dj_load_sfx(handle, 0, dat_filelen("jump.smp"), DJ_SFX_TYPE_SMP, SFX_JUMP) != 0) {
  3222.                         strcpy(main_info.error_str, "Error loading 'jump.smp', aborting...\n");
  3223.                         return 1;
  3224.                 }
  3225.  
  3226.                 if ((handle = dat_open("death.smp")) == 0) {
  3227.                         strcpy(main_info.error_str, "Error loading 'death.smp', aborting...\n");
  3228.                         return 1;
  3229.                 }
  3230.                 if (dj_load_sfx(handle, 0, dat_filelen("death.smp"), DJ_SFX_TYPE_SMP, SFX_DEATH) != 0) {
  3231.                         strcpy(main_info.error_str, "Error loading 'death.smp', aborting...\n");
  3232.                         return 1;
  3233.                 }
  3234.  
  3235.                 if ((handle = dat_open("spring.smp")) == 0) {
  3236.                         strcpy(main_info.error_str, "Error loading 'spring.smp', aborting...\n");
  3237.                         return 1;
  3238.                 }
  3239.                 if (dj_load_sfx(handle, 0, dat_filelen("spring.smp"), DJ_SFX_TYPE_SMP, SFX_SPRING) != 0) {
  3240.                         strcpy(main_info.error_str, "Error loading 'spring.smp', aborting...\n");
  3241.                         return 1;
  3242.                 }
  3243.  
  3244.                 if ((handle = dat_open("splash.smp")) == 0) {
  3245.                         strcpy(main_info.error_str, "Error loading 'splash.smp', aborting...\n");
  3246.                         return 1;
  3247.                 }
  3248.                 if (dj_load_sfx(handle, 0, dat_filelen("splash.smp"), DJ_SFX_TYPE_SMP, SFX_SPLASH) != 0) {
  3249.                         strcpy(main_info.error_str, "Error loading 'splash.smp', aborting...\n");
  3250.                         return 1;
  3251.                 }
  3252.  
  3253.                 if ((handle = dat_open("fly.smp")) == 0) {
  3254.                         strcpy(main_info.error_str, "Error loading 'fly.smp', aborting...\n");
  3255.                         return 1;
  3256.                 }
  3257.                 if (dj_load_sfx(handle, 0, dat_filelen("fly.smp"), DJ_SFX_TYPE_SMP, SFX_FLY) != 0) {
  3258.                         strcpy(main_info.error_str, "Error loading 'fly.smp', aborting...\n");
  3259.                         return 1;
  3260.                 }
  3261.  
  3262.                 dj_get_sfx_settings(SFX_FLY, &fly);
  3263.                 fly.priority = 10;
  3264.                 fly.default_freq = SFX_FLY_FREQ;
  3265.                 fly.loop = 1;
  3266.                 fly.loop_start = 0;
  3267.                 fly.loop_length = fly.length;
  3268.                 dj_set_sfx_settings(SFX_FLY, &fly);
  3269.         }
  3270.  
  3271.         if ((background_pic = malloc(JNB_WIDTH*JNB_HEIGHT)) == NULL)
  3272.                 return 1;
  3273.         if ((mask_pic = malloc(JNB_WIDTH*JNB_HEIGHT)) == NULL)
  3274.                 return 1;
  3275.         memset(mask_pic, 0, JNB_WIDTH*JNB_HEIGHT);
  3276.         register_mask(mask_pic);
  3277.  
  3278.         /* fix dark font */
  3279.         for (c1 = 0; c1 < 16; c1++) {
  3280.                 pal[(240 + c1) * 3 + 0] = c1 << 2;
  3281.                 pal[(240 + c1) * 3 + 1] = c1 << 2;
  3282.                 pal[(240 + c1) * 3 + 2] = c1 << 2;
  3283.         }
  3284.  
  3285.         setpalette(0, 256, pal);
  3286.  
  3287.         init_inputs();
  3288.  
  3289.         recalculate_gob(&font_gobs, pal);
  3290.  
  3291.         if (main_info.joy_enabled == 1 && main_info.fireworks == 0) {
  3292.                 load_flag = 0;
  3293.                 put_text(0, 200, 40, "JOYSTICK CALIBRATION", 2);
  3294.                 put_text(0, 200, 100, "Move the joystick to the", 2);
  3295.                 put_text(0, 200, 115, "UPPER LEFT", 2);
  3296.                 put_text(0, 200, 130, "and press button A", 2);
  3297.                 put_text(0, 200, 200, "Or press ESC to use", 2);
  3298.                 put_text(0, 200, 215, "previous settings", 2);
  3299.                 if (calib_joy(0) != 0)
  3300.                         load_flag = 1;
  3301.                 else {
  3302.                         register_background(NULL, NULL);
  3303.  
  3304.                         main_info.view_page = 1;
  3305.                         flippage(1);
  3306.  
  3307.                         wait_vrt(0);
  3308.  
  3309.                         put_text(1, 200, 40, "JOYSTICK CALIBRATION", 2);
  3310.                         put_text(1, 200, 100, "Move the joystick to the", 2);
  3311.                         put_text(1, 200, 115, "LOWER RIGHT", 2);
  3312.                         put_text(1, 200, 130, "and press button A", 2);
  3313.                         put_text(1, 200, 200, "Or press ESC to use", 2);
  3314.                         put_text(1, 200, 215, "previous settings", 2);
  3315.                         if (calib_joy(1) != 0)
  3316.                                 load_flag = 1;
  3317.                         else {
  3318.                                 register_background(NULL, NULL);
  3319.                                 flippage(0);
  3320.  
  3321.                                 wait_vrt(0);
  3322.  
  3323.                                 put_text(0, 200, 40, "JOYSTICK CALIBRATION", 2);
  3324.                                 put_text(0, 200, 100, "Move the joystick to the", 2);
  3325.                                 put_text(0, 200, 115, "CENTER", 2);
  3326.                                 put_text(0, 200, 130, "and press button A", 2);
  3327.                                 put_text(0, 200, 200, "Or press ESC to use", 2);
  3328.                                 put_text(0, 200, 215, "previous settings", 2);
  3329.                                 if (calib_joy(2) != 0)
  3330.                                         load_flag = 1;
  3331.                                 else {
  3332.                                         if (joy.calib_data.x1 == joy.calib_data.x2)
  3333.                                                 joy.calib_data.x1 -= 10;
  3334.                                         if (joy.calib_data.x3 == joy.calib_data.x2)
  3335.                                                 joy.calib_data.x3 += 10;
  3336.                                         if (joy.calib_data.y1 == joy.calib_data.y2)
  3337.                                                 joy.calib_data.y1 -= 10;
  3338.                                         if (joy.calib_data.y3 == joy.calib_data.y2)
  3339.                                                 joy.calib_data.y3 += 10;
  3340.                                         write_calib_data();
  3341.                                 }
  3342.                         }
  3343.                 }
  3344.                 if (load_flag == 1) {
  3345.                         if ((handle = dat_open("calib.dat")) == 0) {
  3346.                                 strcpy(main_info.error_str, "Error loading 'calib.dat', aborting...\n");
  3347.                                 return 1;
  3348.                         }
  3349.                         joy.calib_data.x1 = (handle[0]) + (handle[1] << 8) + (handle[2] << 16) + (handle[3] << 24); handle += 4;
  3350.                         joy.calib_data.x2 = (handle[0]) + (handle[1] << 8) + (handle[2] << 16) + (handle[3] << 24); handle += 4;
  3351.                         joy.calib_data.x3 = (handle[0]) + (handle[1] << 8) + (handle[2] << 16) + (handle[3] << 24); handle += 4;
  3352.                         joy.calib_data.y1 = (handle[0]) + (handle[1] << 8) + (handle[2] << 16) + (handle[3] << 24); handle += 4;
  3353.                         joy.calib_data.y2 = (handle[0]) + (handle[1] << 8) + (handle[2] << 16) + (handle[3] << 24); handle += 4;
  3354.                         joy.calib_data.y3 = (handle[0]) + (handle[1] << 8) + (handle[2] << 16) + (handle[3] << 24); handle += 4;
  3355.                 }
  3356.         }
  3357.  
  3358. #ifdef USE_NET
  3359.         if (is_net) {
  3360.                 if (is_server) {
  3361.                         init_server(netarg);
  3362.                 } else {
  3363.                         connect_to_server(netarg);
  3364.                 }
  3365.         }
  3366. #endif
  3367.  
  3368.         return 0;
  3369.  
  3370. }
  3371.  
  3372. void deinit_program(void)
  3373. {
  3374. #ifdef DOS
  3375.         __dpmi_regs regs;
  3376. #endif
  3377.  
  3378.         dj_stop();
  3379.         dj_free_mod(MOD_MENU);
  3380.         dj_free_mod(MOD_GAME);
  3381.         dj_free_sfx(SFX_DEATH);
  3382.         dj_free_sfx(SFX_SPRING);
  3383.         dj_free_sfx(SFX_SPLASH);
  3384.         dj_deinit();
  3385.  
  3386.         if (background_pic != 0)
  3387.                 free(background_pic);
  3388.         if (mask_pic != 0)
  3389.                 free(mask_pic);
  3390.  
  3391.         remove_keyb_handler();
  3392.  
  3393. #ifdef DOS
  3394.         regs.x.ax = 0x3;
  3395.         __dpmi_int(0x10, &regs);
  3396. #endif
  3397.  
  3398.         if (main_info.error_str[0] != 0) {
  3399.                 printf(main_info.error_str);
  3400. #ifdef _MSC_VER
  3401.                 MessageBox(0, main_info.error_str, "Jump'n'Bump", 0);
  3402. #endif
  3403.                 exit(1);
  3404.         } else
  3405.                 exit(0);
  3406.  
  3407. }
  3408.  
  3409.  
  3410. unsigned short rnd(unsigned short max)
  3411. {
  3412. #if (RAND_MAX < 0x7fff)
  3413. #error "rand returns too small values"
  3414. #elif (RAND_MAX == 0x7fff)
  3415.         return (unsigned short)((rand()*2) % (int)max);
  3416. #else
  3417.         return (unsigned short)(rand() % (int)max);
  3418. #endif
  3419. }
  3420.  
  3421.  
  3422. int read_level(void)
  3423. {
  3424.         unsigned char *handle;
  3425.         int c1, c2;
  3426.         int chr;
  3427.  
  3428.         if ((handle = dat_open("levelmap.txt")) == 0) {
  3429.                 strcpy(main_info.error_str, "Error loading 'levelmap.txt', aborting...\n");
  3430.                 return 1;
  3431.         }
  3432.  
  3433.         for (c1 = 0; c1 < 16; c1++) {
  3434.                 for (c2 = 0; c2 < 22; c2++) {
  3435.                         while (1) {
  3436.                                 chr = (int) *(handle++);
  3437.                                 if (chr >= '0' && chr <= '4')
  3438.                                         break;
  3439.                         }
  3440.                         if (flip)
  3441.                                 ban_map[c1][21-c2] = chr - '0';
  3442.                         else
  3443.                                 ban_map[c1][c2] = chr - '0';
  3444.                 }
  3445.         }
  3446.  
  3447.         for (c2 = 0; c2 < 22; c2++)
  3448.                 ban_map[16][c2] = BAN_SOLID;
  3449.  
  3450.         return 0;
  3451.  
  3452. }
  3453.  
  3454.  
  3455. unsigned char *dat_open(char *file_name)
  3456. {
  3457.         int num;
  3458.         int c1;
  3459.         char name[21];
  3460.         int ofs;
  3461.         unsigned char *ptr;
  3462.  
  3463.         if (datafile_buffer == NULL)
  3464.                 return 0;
  3465.  
  3466.         memset(name, 0, sizeof(name));
  3467.  
  3468.         num = ( (datafile_buffer[0] <<  0) +
  3469.                 (datafile_buffer[1] <<  8) +
  3470.                 (datafile_buffer[2] << 16) +
  3471.                 (datafile_buffer[3] << 24) );
  3472.  
  3473.         ptr = datafile_buffer + 4;
  3474.  
  3475.         for (c1 = 0; c1 < num; c1++) {
  3476.  
  3477.                 memcpy(name, ptr, 12);
  3478.                 ptr += 12;
  3479.  
  3480.                 if (strnicmp(name, file_name, strlen(file_name)) == 0) {
  3481.                         ofs = ( (ptr[0] <<  0) +
  3482.                                 (ptr[1] <<  8) +
  3483.                                 (ptr[2] << 16) +
  3484.                                 (ptr[3] << 24) );
  3485.  
  3486.                         return (datafile_buffer + ofs);
  3487.                 }
  3488.                 ptr += 8;
  3489.         }
  3490.  
  3491.         return 0;
  3492. }
  3493.  
  3494.  
  3495. int dat_filelen(char *file_name)
  3496. {
  3497.         unsigned char *ptr;
  3498.         int num;
  3499.         int c1;
  3500.         char name[21];
  3501.         int len;
  3502.  
  3503.         memset(name, 0, sizeof(name));
  3504.  
  3505.         num = ( (datafile_buffer[0] <<  0) +
  3506.                 (datafile_buffer[1] <<  8) +
  3507.                 (datafile_buffer[2] << 16) +
  3508.                 (datafile_buffer[3] << 24) );
  3509.  
  3510.         ptr = datafile_buffer + 4;
  3511.  
  3512.         for (c1 = 0; c1 < num; c1++) {
  3513.  
  3514.                 memcpy(name, ptr, 12);
  3515.                 ptr += 12;
  3516.  
  3517.                 if (strnicmp(name, file_name, strlen(file_name)) == 0) {
  3518.  
  3519.                         ptr += 4;
  3520.                         len = ( (ptr[0] <<  0) +
  3521.                                 (ptr[1] <<  8) +
  3522.                                 (ptr[2] << 16) +
  3523.                                 (ptr[3] << 24) );
  3524.  
  3525.                         return len;
  3526.                 }
  3527.                 ptr += 8;
  3528.         }
  3529.  
  3530.         return 0;
  3531. }
  3532.  
  3533.  
  3534. void write_calib_data(void)
  3535. {
  3536.         FILE *handle;
  3537.         int c1;
  3538.         int len, num;
  3539.         char *mem;
  3540.         int ofs;
  3541.  
  3542.         if ((handle = fopen(datfile_name, "rb")) == NULL)
  3543.                 return;
  3544.         len = filelength(fileno(handle));
  3545.         if ((mem = malloc(len)) == NULL)
  3546.                 return;
  3547.         fread(mem, 1, len, handle);
  3548.         fclose(handle);
  3549.  
  3550.         ofs = 4;
  3551.         num = *(int *) (&mem[0]);
  3552.         for (c1 = 0; c1 < num; c1++) {
  3553.                 if (strnicmp(&mem[ofs], "calib.dat", strlen("calib.dat")) == 0) {
  3554.                         ofs = *(int *) (&mem[ofs + 12]);
  3555.                         break;
  3556.                 }
  3557.                 ofs += 20;
  3558.         }
  3559.  
  3560.         mem[ofs] = joy.calib_data.x1 & 0xff;
  3561.         mem[ofs + 1] = (joy.calib_data.x1 >> 8) & 0xff;
  3562.         mem[ofs + 2] = (joy.calib_data.x1 >> 16) & 0xff;
  3563.         mem[ofs + 3] = (joy.calib_data.x1 >> 24) & 0xff;
  3564.         mem[ofs + 4] = joy.calib_data.x2 & 0xff;
  3565.         mem[ofs + 5] = (joy.calib_data.x2 >> 8) & 0xff;
  3566.         mem[ofs + 6] = (joy.calib_data.x2 >> 16) & 0xff;
  3567.         mem[ofs + 7] = (joy.calib_data.x2 >> 24) & 0xff;
  3568.         mem[ofs + 8] = joy.calib_data.x3 & 0xff;
  3569.         mem[ofs + 9] = (joy.calib_data.x3 >> 8) & 0xff;
  3570.         mem[ofs + 10] = (joy.calib_data.x3 >> 16) & 0xff;
  3571.         mem[ofs + 11] = (joy.calib_data.x3 >> 24) & 0xff;
  3572.         mem[ofs + 12] = joy.calib_data.y1 & 0xff;
  3573.         mem[ofs + 13] = (joy.calib_data.y1 >> 8) & 0xff;
  3574.         mem[ofs + 14] = (joy.calib_data.y1 >> 16) & 0xff;
  3575.         mem[ofs + 15] = (joy.calib_data.y1 >> 24) & 0xff;
  3576.         mem[ofs + 16] = joy.calib_data.y2 & 0xff;
  3577.         mem[ofs + 17] = (joy.calib_data.y2 >> 8) & 0xff;
  3578.         mem[ofs + 18] = (joy.calib_data.y2 >> 16) & 0xff;
  3579.         mem[ofs + 19] = (joy.calib_data.y2 >> 24) & 0xff;
  3580.         mem[ofs + 20] = joy.calib_data.y3 & 0xff;
  3581.         mem[ofs + 21] = (joy.calib_data.y3 >> 8) & 0xff;
  3582.         mem[ofs + 22] = (joy.calib_data.y3 >> 16) & 0xff;
  3583.         mem[ofs + 23] = (joy.calib_data.y3 >> 24) & 0xff;
  3584.  
  3585.         if ((handle = fopen(datfile_name, "wb")) == NULL)
  3586.                 return;
  3587.         fwrite(mem, 1, len, handle);
  3588.         fclose(handle);
  3589.  
  3590. }
  3591.