parent
dd8bf60bd0
commit
691867b0e0
@ -1,146 +1,146 @@
|
||||
/* basic types which we need everywhere */
|
||||
|
||||
#ifndef _BC_BASIC_H_
|
||||
|
||||
#define _BC_BASIC_H_
|
||||
|
||||
#define GAME_SPECIAL_ITEMBOMB 10
|
||||
#define GAME_SPECIAL_ITEMFIRE 10
|
||||
#define GAME_SPECIAL_ITEMSHOE 15
|
||||
#define GAME_SPECIAL_ITEMDEATH 25
|
||||
|
||||
#define START_BOMBS 1
|
||||
#define START_RANGE 2
|
||||
#define START_SPEED 16
|
||||
#define SPEEDMUL 1.2
|
||||
|
||||
#define MAX_PLAYERS 8
|
||||
#define MAX_BOMBS 12
|
||||
#define MAX_RANGE 10
|
||||
#define MAX_SPEED 40
|
||||
#define MAX_UPDATERECTS 2048
|
||||
#define MAX_CONNECTS 16 /* maximal number of connection data */
|
||||
#define MAX_SERVERENTRYS 8 /* number of entrys in the server tab */
|
||||
#define MAX_GAMESRVENTRYS 255 /* number of entry which can be get */
|
||||
#define MAX_FIELDSIZE_X 51
|
||||
#define MAX_FIELDSIZE_Y 31
|
||||
#define MIN_FIELDSIZE_X 15
|
||||
#define MIN_FIELDSIZE_Y 9
|
||||
|
||||
|
||||
#define EXPLOSIONTIMEOUT 20
|
||||
#define ANI_FIRETIMEOUT 2
|
||||
#define ANI_BOMBTIMEOUT 1
|
||||
#define ANI_PLAYERTIMEOUT 1
|
||||
#define ANI_PLAYERILLTIMEOUT 1
|
||||
#define ANI_STONETIMEOUT 10
|
||||
|
||||
#define TIME_FACTOR 50
|
||||
#define BOMB_TIMEOUT 5
|
||||
#define IL_TIMEOUT 20
|
||||
|
||||
#define LEN_PLAYERNAME 10
|
||||
#define LEN_SERVERNAME 41
|
||||
#define LEN_PORT 6
|
||||
#define LEN_GAMENAME 32
|
||||
#define LEN_PATHFILENAME 512
|
||||
#define LEN_FILENAME 256
|
||||
#define LEN_TILESETNAME 32
|
||||
|
||||
#define DEFAULT_UDPPORT 11000
|
||||
#define DEFAULT_GMUDPPORT "11100"
|
||||
#define DEFAULT_GAMEMASTER "x.yz.to:11100"
|
||||
#define GAMESRV_TIMEOUT 2000 /* Timeout of the GameSrv_GetEntry */
|
||||
|
||||
#define UDP_TIMEOUT 15000
|
||||
#define BUF_SIZE 1024
|
||||
|
||||
|
||||
enum _backgound { // to load some diffrent logos..
|
||||
BG_start = 0,
|
||||
BG_net,
|
||||
BG_conf
|
||||
};
|
||||
|
||||
|
||||
enum _gametype {
|
||||
GT_single = 0,
|
||||
GT_multi
|
||||
};
|
||||
|
||||
|
||||
enum _multitype {
|
||||
MT_ptpm, // udp ptp master
|
||||
MT_ptps // udp ptp client
|
||||
};
|
||||
|
||||
|
||||
enum _gamestate {
|
||||
GS_startup = 0,
|
||||
GS_quit,
|
||||
GS_wait, // waiting for players to join
|
||||
GS_update,
|
||||
GS_ready,
|
||||
GS_running
|
||||
};
|
||||
|
||||
|
||||
enum _fieldtype {
|
||||
FT_nothing = 0, // Nothing in here
|
||||
FT_stone, // Stones you can bomb away
|
||||
FT_block, // Stones which can't bomb away
|
||||
FT_death, // The bad Powerup
|
||||
FT_fire, // Special Field for the fire
|
||||
FT_bomb,
|
||||
FT_shoe,
|
||||
|
||||
FT_max // just to know how many types there are
|
||||
};
|
||||
|
||||
|
||||
enum _playerillnestype {
|
||||
PI_keys = 0,
|
||||
PI_range,
|
||||
PI_slow,
|
||||
PI_bomb,
|
||||
|
||||
PI_max // just to know what is the last number
|
||||
};
|
||||
|
||||
|
||||
enum _bombstate {
|
||||
BS_off = 0,
|
||||
BS_ticking,
|
||||
BS_exploding
|
||||
};
|
||||
|
||||
|
||||
enum _playerstateflags {
|
||||
PSF_used = 1, // Player Unused | Player Used
|
||||
PSF_net = 2, // Local Player | AI / Network Player
|
||||
PSF_alife = 4, // Player is Dead | Player is Alife
|
||||
PSF_playing = 8, // Watching Player | Playing Player -- as long as one don't delete
|
||||
};
|
||||
|
||||
#define PSFM_used (PSF_used + PSF_playing)
|
||||
#define PSFM_alife (PSF_used + PSF_alife + PSF_playing)
|
||||
#define PS_IS_dead(__ps) (((__ps) & (PSFM_alife)) == (PSFM_used))
|
||||
#define PS_IS_alife(__ps) (((__ps) & (PSFM_alife)) == (PSFM_alife))
|
||||
#define PS_IS_netplayer(__ps) (((__ps) & (PSFM_alife + PSF_net)) == (PSF_net + PSFM_alife))
|
||||
#define PS_IS_playing(__ps) (((__ps) & (PSFM_used)) == (PSFM_used))
|
||||
#define PS_IS_used(__ps) (((__ps) & (PSFM_used)) != 0)
|
||||
|
||||
enum _direction { // to handle directions better
|
||||
left = 0,
|
||||
right,
|
||||
up,
|
||||
down
|
||||
};
|
||||
|
||||
|
||||
struct __point {
|
||||
short int x;
|
||||
short int y;
|
||||
} typedef _point;
|
||||
|
||||
#endif
|
||||
/* basic types which we need everywhere */
|
||||
|
||||
#ifndef _BC_BASIC_H_
|
||||
|
||||
#define _BC_BASIC_H_
|
||||
|
||||
#define GAME_SPECIAL_ITEMBOMB 10
|
||||
#define GAME_SPECIAL_ITEMFIRE 10
|
||||
#define GAME_SPECIAL_ITEMSHOE 15
|
||||
#define GAME_SPECIAL_ITEMDEATH 25
|
||||
|
||||
#define START_BOMBS 1
|
||||
#define START_RANGE 2
|
||||
#define START_SPEED 16
|
||||
#define SPEEDMUL 1.2
|
||||
|
||||
#define MAX_PLAYERS 8
|
||||
#define MAX_BOMBS 12
|
||||
#define MAX_RANGE 10
|
||||
#define MAX_SPEED 40
|
||||
#define MAX_UPDATERECTS 2048
|
||||
#define MAX_CONNECTS 16 /* maximal number of connection data */
|
||||
#define MAX_SERVERENTRYS 8 /* number of entrys in the server tab */
|
||||
#define MAX_GAMESRVENTRYS 255 /* number of entry which can be get */
|
||||
#define MAX_FIELDSIZE_X 51
|
||||
#define MAX_FIELDSIZE_Y 31
|
||||
#define MIN_FIELDSIZE_X 15
|
||||
#define MIN_FIELDSIZE_Y 9
|
||||
|
||||
|
||||
#define EXPLOSIONTIMEOUT 20
|
||||
#define ANI_FIRETIMEOUT 2
|
||||
#define ANI_BOMBTIMEOUT 1
|
||||
#define ANI_PLAYERTIMEOUT 1
|
||||
#define ANI_PLAYERILLTIMEOUT 1
|
||||
#define ANI_STONETIMEOUT 10
|
||||
|
||||
#define TIME_FACTOR 50
|
||||
#define BOMB_TIMEOUT 5
|
||||
#define IL_TIMEOUT 20
|
||||
|
||||
#define LEN_PLAYERNAME 10
|
||||
#define LEN_SERVERNAME 41
|
||||
#define LEN_PORT 6
|
||||
#define LEN_GAMENAME 32
|
||||
#define LEN_PATHFILENAME 512
|
||||
#define LEN_FILENAME 256
|
||||
#define LEN_TILESETNAME 32
|
||||
|
||||
#define DEFAULT_UDPPORT 11000
|
||||
#define DEFAULT_GMUDPPORT "11100"
|
||||
#define DEFAULT_GAMEMASTER "x.yz.to:11100"
|
||||
#define GAMESRV_TIMEOUT 2000 /* Timeout of the GameSrv_GetEntry */
|
||||
|
||||
#define UDP_TIMEOUT 15000
|
||||
#define BUF_SIZE 1024
|
||||
|
||||
|
||||
enum _backgound { // to load some diffrent logos..
|
||||
BG_start = 0,
|
||||
BG_net,
|
||||
BG_conf
|
||||
};
|
||||
|
||||
|
||||
enum _gametype {
|
||||
GT_single = 0,
|
||||
GT_multi
|
||||
};
|
||||
|
||||
|
||||
enum _multitype {
|
||||
MT_ptpm, // udp ptp master
|
||||
MT_ptps // udp ptp client
|
||||
};
|
||||
|
||||
|
||||
enum _gamestate {
|
||||
GS_startup = 0,
|
||||
GS_quit,
|
||||
GS_wait, // waiting for players to join
|
||||
GS_update,
|
||||
GS_ready,
|
||||
GS_running
|
||||
};
|
||||
|
||||
|
||||
enum _fieldtype {
|
||||
FT_nothing = 0, // Nothing in here
|
||||
FT_stone, // Stones you can bomb away
|
||||
FT_block, // Stones which can't bomb away
|
||||
FT_death, // The bad Powerup
|
||||
FT_fire, // Special Field for the fire
|
||||
FT_bomb,
|
||||
FT_shoe,
|
||||
|
||||
FT_max // just to know how many types there are
|
||||
};
|
||||
|
||||
|
||||
enum _playerillnestype {
|
||||
PI_keys = 0,
|
||||
PI_range,
|
||||
PI_slow,
|
||||
PI_bomb,
|
||||
|
||||
PI_max // just to know what is the last number
|
||||
};
|
||||
|
||||
|
||||
enum _bombstate {
|
||||
BS_off = 0,
|
||||
BS_ticking,
|
||||
BS_exploding
|
||||
};
|
||||
|
||||
|
||||
enum _playerstateflags {
|
||||
PSF_used = 1, // Player Unused | Player Used
|
||||
PSF_net = 2, // Local Player | AI / Network Player
|
||||
PSF_alife = 4, // Player is Dead | Player is Alife
|
||||
PSF_playing = 8, // Watching Player | Playing Player -- as long as one don't delete
|
||||
};
|
||||
|
||||
#define PSFM_used (PSF_used + PSF_playing)
|
||||
#define PSFM_alife (PSF_used + PSF_alife + PSF_playing)
|
||||
#define PS_IS_dead(__ps) (((__ps) & (PSFM_alife)) == (PSFM_used))
|
||||
#define PS_IS_alife(__ps) (((__ps) & (PSFM_alife)) == (PSFM_alife))
|
||||
#define PS_IS_netplayer(__ps) (((__ps) & (PSFM_alife + PSF_net)) == (PSF_net + PSFM_alife))
|
||||
#define PS_IS_playing(__ps) (((__ps) & (PSFM_used)) == (PSFM_used))
|
||||
#define PS_IS_used(__ps) (((__ps) & (PSFM_used)) != 0)
|
||||
|
||||
enum _direction { // to handle directions better
|
||||
left = 0,
|
||||
right,
|
||||
up,
|
||||
down
|
||||
};
|
||||
|
||||
|
||||
struct __point {
|
||||
short int x;
|
||||
short int y;
|
||||
} typedef _point;
|
||||
|
||||
#endif
|
||||
|
@ -1,400 +1,400 @@
|
||||
/* everything what have to do with the bombs */
|
||||
|
||||
#include "bomberclone.h"
|
||||
#include "network.h"
|
||||
#include "gfx.h"
|
||||
|
||||
void
|
||||
restore_bomb_screen ()
|
||||
{
|
||||
int p,
|
||||
i;
|
||||
_bomb *bomb;
|
||||
|
||||
for (p = 0; p < MAX_PLAYERS; p++)
|
||||
for (i = 0; i < MAX_BOMBS; i++) {
|
||||
bomb = &bman.players[p].bombs[i];
|
||||
if (bomb->state == BS_ticking) {
|
||||
draw_stone (bomb->pos.x, bomb->pos.y);
|
||||
if (bomb->pos.x > 1)
|
||||
draw_stone (bomb->pos.x - 1, bomb->pos.y);
|
||||
if (bomb->pos.y > 1)
|
||||
draw_stone (bomb->pos.x, bomb->pos.y - 1);
|
||||
if (bomb->pos.x < bman.fieldsize.x)
|
||||
draw_stone (bomb->pos.x + 1, bomb->pos.y);
|
||||
if (bomb->pos.y < bman.fieldsize.y)
|
||||
draw_stone (bomb->pos.x, bomb->pos.y + 1);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
void
|
||||
draw_bomb (_bomb * bomb)
|
||||
{
|
||||
SDL_Rect src,
|
||||
dest;
|
||||
|
||||
/* check the framenumber */
|
||||
if (bomb->frameto-- == 0) {
|
||||
bomb->frameto = ANI_BOMBTIMEOUT;
|
||||
bomb->frame++;
|
||||
};
|
||||
if (bomb->frame < 0 || bomb->frame >= gfx.bomb.frames || bomb->frameto > ANI_BOMBTIMEOUT) {
|
||||
bomb->frame = 0;
|
||||
bomb->frameto = ANI_BOMBTIMEOUT;
|
||||
}
|
||||
|
||||
src.w = src.w = gfx.bomb.image->w;
|
||||
dest.h = src.h = gfx.block.y;
|
||||
|
||||
dest.x = gfx.offset.x + (bomb->pos.x * gfx.block.x);
|
||||
dest.y = gfx.offset.y + (bomb->pos.y * gfx.block.y);
|
||||
|
||||
src.x = 0;
|
||||
src.y = src.h * bomb->frame;
|
||||
|
||||
SDL_BlitSurface (gfx.bomb.image, &src, gfx.screen, &dest);
|
||||
|
||||
gfx_AddUpdateRect (dest.x, dest.y, dest.w, dest.h);
|
||||
};
|
||||
|
||||
|
||||
void
|
||||
bomb_explode (int p, int b)
|
||||
{
|
||||
int d;
|
||||
_bomb *bomb = &bman.players[p].bombs[b];
|
||||
|
||||
d_printf ("Bomb Explode p:%d, b:%d [%d,%d]\n", p, b, bomb->pos.x, bomb->pos.y);
|
||||
|
||||
if (bomb->ex_nr == -1)
|
||||
bomb->ex_nr = bman.last_ex_nr++; // set bomb explosion id
|
||||
|
||||
bomb->to = EXPLOSIONTIMEOUT; /* set the timeout for the fireexplosion */
|
||||
bomb->state = BS_exploding;
|
||||
for (d = 0; d < 4; d++) {
|
||||
bomb->firer[d] = 0;
|
||||
bomb->firerst[d] = -1;
|
||||
}
|
||||
|
||||
if (GT_MP_PTPM) /* from now on only the server let the bomb explode */
|
||||
net_game_send_bomb (p, b);
|
||||
};
|
||||
|
||||
|
||||
void
|
||||
bomb_loop ()
|
||||
{
|
||||
int p,
|
||||
i;
|
||||
_player *player;
|
||||
_bomb *bomb;
|
||||
|
||||
for (p = 0; p < MAX_PLAYERS; p++) {
|
||||
player = &bman.players[p];
|
||||
if ((bman.players[p].state & PSFM_used) != 0) {
|
||||
for (i = 0; i < MAX_BOMBS; i++) {
|
||||
bomb = &player->bombs[i];
|
||||
if (bomb->state == BS_ticking) {
|
||||
if (GT_MP_PTPM || bman.gametype == GT_single) {
|
||||
if (--bomb->to == 0) // bomb will have to explode in the next loop
|
||||
bomb_explode (p, i);
|
||||
else
|
||||
draw_bomb (bomb);
|
||||
}
|
||||
else {
|
||||
if (--bomb->to == 0) { // bomb did not explode -> resend bombdata
|
||||
bomb->to = BOMB_TIMEOUT * TIME_FACTOR;
|
||||
net_game_send_bomb (bman.p_nr, i);
|
||||
bomb->to = bomb->to + ((2 * RESENDCACHE_RETRY) / TIME_FACTOR);
|
||||
}
|
||||
draw_bomb (bomb);
|
||||
}
|
||||
}
|
||||
else if (bomb->state == BS_exploding) {
|
||||
if (bomb->to > 0) {
|
||||
do_explosion (p, i);
|
||||
}
|
||||
if (bomb->to == 0) { // explosion done
|
||||
restore_explosion (bomb);
|
||||
bomb->to = 0;
|
||||
bomb->state = BS_off;
|
||||
}
|
||||
bomb->to--;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
void
|
||||
get_bomb_on (int x, int y, _point bombs[])
|
||||
{
|
||||
int p,
|
||||
b,
|
||||
i;
|
||||
_bomb *bomb;
|
||||
|
||||
for (i = 0, p = 0; p < MAX_PLAYERS; p++)
|
||||
if ((bman.players[p].state & PSFM_used) != 0) {
|
||||
for (b = 0; b < MAX_BOMBS; b++) {
|
||||
bomb = &bman.players[p].bombs[b];
|
||||
if (bomb->state == BS_ticking) {
|
||||
if (bomb->pos.x == x && bomb->pos.y == y) {
|
||||
bombs[i].x = p;
|
||||
bombs[i].y = b;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
bombs[i].x = bombs[i].y = -1;
|
||||
};
|
||||
|
||||
/* if frame == -1 we will draw the framenumber in
|
||||
the field.ex data */
|
||||
void
|
||||
draw_fire (int x, int y, int d, int frame)
|
||||
{
|
||||
SDL_Rect src,
|
||||
dest;
|
||||
|
||||
if (frame == -1) // no giving frame
|
||||
frame = bman.field[x][y].ex[d].frame;
|
||||
|
||||
src.w = src.w = gfx.block.x;
|
||||
dest.h = src.h = gfx.block.y;
|
||||
|
||||
dest.x = gfx.offset.x + x * gfx.block.x;
|
||||
dest.y = gfx.offset.y + y * gfx.block.y;
|
||||
|
||||
src.y = frame * src.w;
|
||||
src.x = d * src.w;
|
||||
|
||||
SDL_BlitSurface (gfx.fire.image, &src, gfx.screen, &dest);
|
||||
gfx_AddUpdateRect (dest.x, dest.y, dest.w, dest.h);
|
||||
};
|
||||
|
||||
|
||||
void
|
||||
restore_explosion (_bomb * bomb)
|
||||
{
|
||||
int i,
|
||||
d;
|
||||
int dx = 0,
|
||||
dy = 0;
|
||||
int _x,
|
||||
_y;
|
||||
|
||||
for (d = 0; d < 4; d++) {
|
||||
switch (d) {
|
||||
case (left):
|
||||
dx = -1;
|
||||
dy = 0;
|
||||
break;
|
||||
case (right):
|
||||
dx = 1;
|
||||
dy = 0;
|
||||
break;
|
||||
case (up):
|
||||
dx = 0;
|
||||
dy = -1;
|
||||
break;
|
||||
case (down):
|
||||
dx = 0;
|
||||
dy = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
_x = bomb->pos.x;
|
||||
_y = bomb->pos.y;
|
||||
|
||||
for (i = 0; i < bomb->firer[d]; i++) {
|
||||
if (--bman.field[_x][_y].ex[d].count == 0) // there was only one explosion so
|
||||
bman.field[_x][_y].ex[d].frame = 0; // reset the framenumber
|
||||
|
||||
if (i == 0 && d == 3)
|
||||
draw_stone (_x, _y);
|
||||
if (i > 0)
|
||||
draw_stone (_x, _y);
|
||||
_x = _x + dx;
|
||||
_y = _y + dy;
|
||||
}
|
||||
|
||||
// delete the stone completly if there was any in the way
|
||||
if (bomb->firer[d] <= bomb->r && bman.field[_x][_y].type != FT_block
|
||||
&& bomb->ex_nr != bman.field[_x][_y].ex_nr) {
|
||||
|
||||
bman.field[_x][_y].ex_nr = bomb->ex_nr;
|
||||
bman.field[_x][_y].frame = 0;
|
||||
bman.field[_x][_y].frameto = 0;
|
||||
if (bman.field[_x][_y].special != FT_nothing) {
|
||||
bman.field[_x][_y].type = bman.field[_x][_y].special;
|
||||
bman.field[_x][_y].special = FT_nothing;
|
||||
d_printf ("field_explode (%d,%d) ex_nr = %d\n", _x, _y, bman.field[_x][_y].ex_nr);
|
||||
}
|
||||
else
|
||||
bman.field[_x][_y].type = FT_nothing;
|
||||
|
||||
draw_stone (_x, _y);
|
||||
|
||||
if (GT_MP_PTPM) /* send only if we are the master */
|
||||
net_game_send_field (_x, _y);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*
|
||||
check the field on which the explosion is
|
||||
*/
|
||||
int
|
||||
explosion_check_field (int x, int y, int p, int b)
|
||||
{
|
||||
_bomb *bomb = &bman.players[p].bombs[b];
|
||||
int pl[MAX_PLAYERS];
|
||||
int i;
|
||||
_point bo[MAX_PLAYERS * MAX_BOMBS];
|
||||
_bomb *tmpbomb;
|
||||
_player *tmpplayer;
|
||||
|
||||
if (x < 0 || x >= bman.fieldsize.x || y < 0 || y >= bman.fieldsize.y)
|
||||
return FT_block;
|
||||
|
||||
get_player_on (x << 8, y << 8, pl);
|
||||
get_bomb_on (x, y, bo);
|
||||
|
||||
// check if any bomb have to explode..
|
||||
for (i = 0; bo[i].x != -1; i++) {
|
||||
tmpbomb = &bman.players[bo[i].x].bombs[bo[i].y];
|
||||
if (tmpbomb != bomb && tmpbomb->state != BS_exploding) {
|
||||
tmpbomb->ex_nr = bomb->ex_nr; // set the ex_nr to identify explosions
|
||||
bomb_explode (bo[i].x, bo[i].y);
|
||||
}
|
||||
}
|
||||
|
||||
// check if any player is in the explosion
|
||||
for (i = 0; pl[i] != -1; i++) {
|
||||
tmpplayer = &bman.players[pl[i]];
|
||||
if (((tmpplayer->state & PSF_alife) != 0)
|
||||
&& (bman.gametype == GT_single
|
||||
|| (GT_MP_PTP && (&bman.players[bman.p_nr] == tmpplayer))))
|
||||
player_died (tmpplayer, p);
|
||||
}
|
||||
|
||||
// let the stones right beside explode
|
||||
if (bman.field[x][y].type != FT_nothing
|
||||
&& bman.field[x][y].type != FT_block && bomb->ex_nr != bman.field[x][y].ex_nr) {
|
||||
if (bman.field[x][y].frame == 0) {
|
||||
bman.field[x][y].frameto = ANI_STONETIMEOUT;
|
||||
bman.field[x][y].frame = 1;
|
||||
}
|
||||
draw_stone (x, y);
|
||||
}
|
||||
|
||||
return bman.field[x][y].type;
|
||||
};
|
||||
|
||||
|
||||
/* draw the explosion as far as she got */
|
||||
void
|
||||
draw_explosion (_bomb * bomb)
|
||||
{
|
||||
int d,
|
||||
r,
|
||||
dx,
|
||||
dy;
|
||||
_point p;
|
||||
|
||||
bomb->frameto--;
|
||||
if (bomb->frameto < 0 || bomb->frameto > ANI_FIRETIMEOUT)
|
||||
bomb->frameto = ANI_FIRETIMEOUT;
|
||||
|
||||
for (d = 0; d < 4; d++) {
|
||||
switch (d) {
|
||||
case (left):
|
||||
dx = -1;
|
||||
dy = 0;
|
||||
break;
|
||||
case (right):
|
||||
dx = 1;
|
||||
dy = 0;
|
||||
break;
|
||||
case (up):
|
||||
dx = 0;
|
||||
dy = -1;
|
||||
break;
|
||||
default:
|
||||
dx = 0;
|
||||
dy = 1;
|
||||
break;
|
||||
}
|
||||
p.x = bomb->pos.x;
|
||||
p.y = bomb->pos.y;
|
||||
|
||||
for (r = 0; r < bomb->firer[d]; r++) {
|
||||
if (bomb->frameto == 0) {
|
||||
bman.field[p.x][p.y].ex[d].frame++;
|
||||
if (bman.field[p.x][p.y].ex[d].frame >= gfx.fire.frames)
|
||||
bman.field[p.x][p.y].ex[d].frame = 0;
|
||||
}
|
||||
draw_fire (p.x, p.y, d, -1);
|
||||
p.x += dx;
|
||||
p.y += dy;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* check the fields and all this */
|
||||
void
|
||||
do_explosion (int p, int b)
|
||||
{
|
||||
_bomb *bomb = &bman.players[p].bombs[b];
|
||||
int dx = 0,
|
||||
dy = 0,
|
||||
d;
|
||||
|
||||
for (d = 0; d < 4; d++) {
|
||||
switch (d) {
|
||||
case (left):
|
||||
dx = -1;
|
||||
dy = 0;
|
||||
break;
|
||||
case (right):
|
||||
dx = 1;
|
||||
dy = 0;
|
||||
break;
|
||||
case (up):
|
||||
dx = 0;
|
||||
dy = -1;
|
||||
break;
|
||||
case (down):
|
||||
dx = 0;
|
||||
dy = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (bomb->firer[d] <= bomb->r) {
|
||||
dx = bomb->firer[d] * dx;
|
||||
dy = bomb->firer[d] * dy;
|
||||
|
||||
if (explosion_check_field (bomb->pos.x + dx, bomb->pos.y + dy, p, b) ==
|
||||
BS_off && bomb->firerst[d] == -1) {
|
||||
bomb->firer[d]++;
|
||||
bman.field[bomb->pos.x + dx][bomb->pos.y + dy].ex[d].count++;
|
||||
bman.field[bomb->pos.x + dx][bomb->pos.y + dy].ex[d].frame = bomb->firer[d];
|
||||
/* if we have a slow pc we can enable this and disable the drawing animation */
|
||||
// draw_fire (bomb->pos.x + dx, bomb->pos.y + dy, d, gfx.fire.frames>>1);
|
||||
}
|
||||
else {
|
||||
bomb->firerst[d] = bomb->firer[d];
|
||||
draw_stone (bomb->pos.x + dx, bomb->pos.y + dy);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* with a slow pc disable this --- maybe option over a config menu */
|
||||
if (bomb->state == BS_exploding)
|
||||
draw_explosion (bomb);
|
||||
};
|
||||
/* everything what have to do with the bombs */
|
||||
|
||||
#include "bomberclone.h"
|
||||
#include "network.h"
|
||||
#include "gfx.h"
|
||||
|
||||
void
|
||||
restore_bomb_screen ()
|
||||
{
|
||||
int p,
|
||||
i;
|
||||
_bomb *bomb;
|
||||
|
||||
for (p = 0; p < MAX_PLAYERS; p++)
|
||||
for (i = 0; i < MAX_BOMBS; i++) {
|
||||
bomb = &bman.players[p].bombs[i];
|
||||
if (bomb->state == BS_ticking) {
|
||||
draw_stone (bomb->pos.x, bomb->pos.y);
|
||||
if (bomb->pos.x > 1)
|
||||
draw_stone (bomb->pos.x - 1, bomb->pos.y);
|
||||
if (bomb->pos.y > 1)
|
||||
draw_stone (bomb->pos.x, bomb->pos.y - 1);
|
||||
if (bomb->pos.x < bman.fieldsize.x)
|
||||
draw_stone (bomb->pos.x + 1, bomb->pos.y);
|
||||
if (bomb->pos.y < bman.fieldsize.y)
|
||||
draw_stone (bomb->pos.x, bomb->pos.y + 1);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
void
|
||||
draw_bomb (_bomb * bomb)
|
||||
{
|
||||
SDL_Rect src,
|
||||
dest;
|
||||
|
||||
/* check the framenumber */
|
||||
if (bomb->frameto-- == 0) {
|
||||
bomb->frameto = ANI_BOMBTIMEOUT;
|
||||
bomb->frame++;
|
||||
};
|
||||
if (bomb->frame < 0 || bomb->frame >= gfx.bomb.frames || bomb->frameto > ANI_BOMBTIMEOUT) {
|
||||
bomb->frame = 0;
|
||||
bomb->frameto = ANI_BOMBTIMEOUT;
|
||||
}
|
||||
|
||||
src.w = src.w = gfx.bomb.image->w;
|
||||
dest.h = src.h = gfx.block.y;
|
||||
|
||||
dest.x = gfx.offset.x + (bomb->pos.x * gfx.block.x);
|
||||
dest.y = gfx.offset.y + (bomb->pos.y * gfx.block.y);
|
||||
|
||||
src.x = 0;
|
||||
src.y = src.h * bomb->frame;
|
||||
|
||||
SDL_BlitSurface (gfx.bomb.image, &src, gfx.screen, &dest);
|
||||
|
||||
gfx_AddUpdateRect (dest.x, dest.y, dest.w, dest.h);
|
||||
};
|
||||
|
||||
|
||||
void
|
||||
bomb_explode (int p, int b)
|
||||
{
|
||||
int d;
|
||||
_bomb *bomb = &bman.players[p].bombs[b];
|
||||
|
||||
d_printf ("Bomb Explode p:%d, b:%d [%d,%d]\n", p, b, bomb->pos.x, bomb->pos.y);
|
||||
|
||||
if (bomb->ex_nr == -1)
|
||||
bomb->ex_nr = bman.last_ex_nr++; // set bomb explosion id
|
||||
|
||||
bomb->to = EXPLOSIONTIMEOUT; /* set the timeout for the fireexplosion */
|
||||
bomb->state = BS_exploding;
|
||||
for (d = 0; d < 4; d++) {
|
||||
bomb->firer[d] = 0;
|
||||
bomb->firerst[d] = -1;
|
||||
}
|
||||
|
||||
if (GT_MP_PTPM) /* from now on only the server let the bomb explode */
|
||||
net_game_send_bomb (p, b);
|
||||
};
|
||||
|
||||
|
||||
void
|
||||
bomb_loop ()
|
||||
{
|
||||
int p,
|
||||
i;
|
||||
_player *player;
|
||||
_bomb *bomb;
|
||||
|
||||
for (p = 0; p < MAX_PLAYERS; p++) {
|
||||
player = &bman.players[p];
|
||||
if ((bman.players[p].state & PSFM_used) != 0) {
|
||||
for (i = 0; i < MAX_BOMBS; i++) {
|
||||
bomb = &player->bombs[i];
|
||||
if (bomb->state == BS_ticking) {
|
||||
if (GT_MP_PTPM || bman.gametype == GT_single) {
|
||||
if (--bomb->to == 0) // bomb will have to explode in the next loop
|
||||
bomb_explode (p, i);
|
||||
else
|
||||
draw_bomb (bomb);
|
||||
}
|
||||
else {
|
||||
if (--bomb->to == 0) { // bomb did not explode -> resend bombdata
|
||||
bomb->to = BOMB_TIMEOUT * TIME_FACTOR;
|
||||
net_game_send_bomb (bman.p_nr, i);
|
||||
bomb->to = bomb->to + ((2 * RESENDCACHE_RETRY) / TIME_FACTOR);
|
||||
}
|
||||
draw_bomb (bomb);
|
||||
}
|
||||
}
|
||||
else if (bomb->state == BS_exploding) {
|
||||
if (bomb->to > 0) {
|
||||
do_explosion (p, i);
|
||||
}
|
||||
if (bomb->to == 0) { // explosion done
|
||||
restore_explosion (bomb);
|
||||
bomb->to = 0;
|
||||
bomb->state = BS_off;
|
||||
}
|
||||
bomb->to--;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
void
|
||||
get_bomb_on (int x, int y, _point bombs[])
|
||||
{
|
||||
int p,
|
||||
b,
|
||||
i;
|
||||
_bomb *bomb;
|
||||
|
||||
for (i = 0, p = 0; p < MAX_PLAYERS; p++)
|
||||
if ((bman.players[p].state & PSFM_used) != 0) {
|
||||
for (b = 0; b < MAX_BOMBS; b++) {
|
||||
bomb = &bman.players[p].bombs[b];
|
||||
if (bomb->state == BS_ticking) {
|
||||
if (bomb->pos.x == x && bomb->pos.y == y) {
|
||||
bombs[i].x = p;
|
||||
bombs[i].y = b;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
bombs[i].x = bombs[i].y = -1;
|
||||
};
|
||||
|
||||
/* if frame == -1 we will draw the framenumber in
|
||||
the field.ex data */
|
||||
void
|
||||
draw_fire (int x, int y, int d, int frame)
|
||||
{
|
||||
SDL_Rect src,
|
||||
dest;
|
||||
|
||||
if (frame == -1) // no giving frame
|
||||
frame = bman.field[x][y].ex[d].frame;
|
||||
|
||||
src.w = src.w = gfx.block.x;
|
||||
dest.h = src.h = gfx.block.y;
|
||||
|
||||
dest.x = gfx.offset.x + x * gfx.block.x;
|
||||
dest.y = gfx.offset.y + y * gfx.block.y;
|
||||
|
||||
src.y = frame * src.w;
|
||||
src.x = d * src.w;
|
||||
|
||||
SDL_BlitSurface (gfx.fire.image, &src, gfx.screen, &dest);
|
||||
gfx_AddUpdateRect (dest.x, dest.y, dest.w, dest.h);
|
||||
};
|
||||
|
||||
|
||||
void
|
||||
restore_explosion (_bomb * bomb)
|
||||
{
|
||||
int i,
|
||||
d;
|
||||
int dx = 0,
|
||||
dy = 0;
|
||||
int _x,
|
||||
_y;
|
||||
|
||||
for (d = 0; d < 4; d++) {
|
||||
switch (d) {
|
||||
case (left):
|
||||
dx = -1;
|
||||
dy = 0;
|
||||
break;
|
||||
case (right):
|
||||
dx = 1;
|
||||
dy = 0;
|
||||
break;
|
||||
case (up):
|
||||
dx = 0;
|
||||
dy = -1;
|
||||
break;
|
||||
case (down):
|
||||
dx = 0;
|
||||
dy = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
_x = bomb->pos.x;
|
||||
_y = bomb->pos.y;
|
||||
|
||||
for (i = 0; i < bomb->firer[d]; i++) {
|
||||
if (--bman.field[_x][_y].ex[d].count == 0) // there was only one explosion so
|
||||
bman.field[_x][_y].ex[d].frame = 0; // reset the framenumber
|
||||
|
||||
if (i == 0 && d == 3)
|
||||
draw_stone (_x, _y);
|
||||
if (i > 0)
|
||||
draw_stone (_x, _y);
|
||||
_x = _x + dx;
|
||||
_y = _y + dy;
|
||||
}
|
||||
|
||||
// delete the stone completly if there was any in the way
|
||||
if (bomb->firer[d] <= bomb->r && bman.field[_x][_y].type != FT_block
|
||||
&& bomb->ex_nr != bman.field[_x][_y].ex_nr) {
|
||||
|
||||
bman.field[_x][_y].ex_nr = bomb->ex_nr;
|
||||
bman.field[_x][_y].frame = 0;
|
||||
bman.field[_x][_y].frameto = 0;
|
||||
if (bman.field[_x][_y].special != FT_nothing) {
|
||||
bman.field[_x][_y].type = bman.field[_x][_y].special;
|
||||
bman.field[_x][_y].special = FT_nothing;
|
||||
d_printf ("field_explode (%d,%d) ex_nr = %d\n", _x, _y, bman.field[_x][_y].ex_nr);
|
||||
}
|
||||
else
|
||||
bman.field[_x][_y].type = FT_nothing;
|
||||
|
||||
draw_stone (_x, _y);
|
||||
|
||||
if (GT_MP_PTPM) /* send only if we are the master */
|
||||
net_game_send_field (_x, _y);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*
|
||||
check the field on which the explosion is
|
||||
*/
|
||||
int
|
||||
explosion_check_field (int x, int y, int p, int b)
|
||||
{
|
||||
_bomb *bomb = &bman.players[p].bombs[b];
|
||||
int pl[MAX_PLAYERS];
|
||||
int i;
|
||||
_point bo[MAX_PLAYERS * MAX_BOMBS];
|
||||
_bomb *tmpbomb;
|
||||
_player *tmpplayer;
|
||||
|
||||
if (x < 0 || x >= bman.fieldsize.x || y < 0 || y >= bman.fieldsize.y)
|
||||
return FT_block;
|
||||
|
||||
get_player_on (x << 8, y << 8, pl);
|
||||
get_bomb_on (x, y, bo);
|
||||
|
||||
// check if any bomb have to explode..
|
||||
for (i = 0; bo[i].x != -1; i++) {
|
||||
tmpbomb = &bman.players[bo[i].x].bombs[bo[i].y];
|
||||
if (tmpbomb != bomb && tmpbomb->state != BS_exploding) {
|
||||
tmpbomb->ex_nr = bomb->ex_nr; // set the ex_nr to identify explosions
|
||||
bomb_explode (bo[i].x, bo[i].y);
|
||||
}
|
||||
}
|
||||
|
||||
// check if any player is in the explosion
|
||||
for (i = 0; pl[i] != -1; i++) {
|
||||
tmpplayer = &bman.players[pl[i]];
|
||||
if (((tmpplayer->state & PSF_alife) != 0)
|
||||
&& (bman.gametype == GT_single
|
||||
|| (GT_MP_PTP && (&bman.players[bman.p_nr] == tmpplayer))))
|
||||
player_died (tmpplayer, p);
|
||||
}
|
||||
|
||||
// let the stones right beside explode
|
||||
if (bman.field[x][y].type != FT_nothing
|
||||
&& bman.field[x][y].type != FT_block && bomb->ex_nr != bman.field[x][y].ex_nr) {
|
||||
if (bman.field[x][y].frame == 0) {
|
||||
bman.field[x][y].frameto = ANI_STONETIMEOUT;
|
||||
bman.field[x][y].frame = 1;
|
||||
}
|
||||
draw_stone (x, y);
|
||||
}
|
||||
|
||||
return bman.field[x][y].type;
|
||||
};
|
||||
|
||||
|
||||
/* draw the explosion as far as she got */
|
||||
void
|
||||
draw_explosion (_bomb * bomb)
|
||||
{
|
||||
int d,
|
||||
r,
|
||||
dx,
|
||||
dy;
|
||||
_point p;
|
||||
|
||||
bomb->frameto--;
|
||||
if (bomb->frameto < 0 || bomb->frameto > ANI_FIRETIMEOUT)
|
||||
bomb->frameto = ANI_FIRETIMEOUT;
|
||||
|
||||
for (d = 0; d < 4; d++) {
|
||||
switch (d) {
|
||||
case (left):
|
||||
dx = -1;
|
||||
dy = 0;
|
||||
break;
|
||||
case (right):
|
||||
dx = 1;
|
||||
dy = 0;
|
||||
break;
|
||||
case (up):
|
||||
dx = 0;
|
||||
dy = -1;
|
||||
break;
|
||||
default:
|
||||
dx = 0;
|
||||
dy = 1;
|
||||
break;
|
||||
}
|
||||
p.x = bomb->pos.x;
|
||||
p.y = bomb->pos.y;
|
||||
|
||||
for (r = 0; r < bomb->firer[d]; r++) {
|
||||
if (bomb->frameto == 0) {
|
||||
bman.field[p.x][p.y].ex[d].frame++;
|
||||
if (bman.field[p.x][p.y].ex[d].frame >= gfx.fire.frames)
|
||||
bman.field[p.x][p.y].ex[d].frame = 0;
|
||||
}
|
||||
draw_fire (p.x, p.y, d, -1);
|
||||
p.x += dx;
|
||||
p.y += dy;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* check the fields and all this */
|
||||
void
|
||||
do_explosion (int p, int b)
|
||||
{
|
||||
_bomb *bomb = &bman.players[p].bombs[b];
|
||||
int dx = 0,
|
||||
dy = 0,
|
||||
d;
|
||||
|
||||
for (d = 0; d < 4; d++) {
|
||||
switch (d) {
|
||||
case (left):
|
||||
dx = -1;
|
||||
dy = 0;
|
||||
break;
|
||||
case (right):
|
||||
dx = 1;
|
||||
dy = 0;
|
||||
break;
|
||||
case (up):
|
||||
dx = 0;
|
||||
dy = -1;
|
||||
break;
|
||||
case (down):
|
||||
dx = 0;
|
||||
dy = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (bomb->firer[d] <= bomb->r) {
|
||||
dx = bomb->firer[d] * dx;
|
||||
dy = bomb->firer[d] * dy;
|
||||
|
||||
if (explosion_check_field (bomb->pos.x + dx, bomb->pos.y + dy, p, b) ==
|
||||
BS_off && bomb->firerst[d] == -1) {
|
||||
bomb->firer[d]++;
|
||||
bman.field[bomb->pos.x + dx][bomb->pos.y + dy].ex[d].count++;
|
||||
bman.field[bomb->pos.x + dx][bomb->pos.y + dy].ex[d].frame = bomb->firer[d];
|
||||
/* if we have a slow pc we can enable this and disable the drawing animation */
|
||||
// draw_fire (bomb->pos.x + dx, bomb->pos.y + dy, d, gfx.fire.frames>>1);
|
||||
}
|
||||
else {
|
||||
bomb->firerst[d] = bomb->firer[d];
|
||||
draw_stone (bomb->pos.x + dx, bomb->pos.y + dy);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* with a slow pc disable this --- maybe option over a config menu */
|
||||
if (bomb->state == BS_exploding)
|
||||
draw_explosion (bomb);
|
||||
};
|
||||
|
@ -1,234 +1,245 @@
|
||||
/* $Id: bomberclone.h,v 1.15 2003/05/07 14:32:02 stpohle Exp $ */
|
||||
/* bomberclone.h */
|
||||
|
||||
#ifndef _BOMBERCLONE_H_
|
||||
#define _BOMBERCLONE_H_
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include <time.h>
|
||||
#include <ctype.h>
|
||||
#include <sys/stat.h>
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#include <winsock.h>
|
||||
#include <sys/stat.h>
|
||||
#ifndef S_ISDIR
|
||||
#define S_ISDIR(a) ((a & _S_IFDIR) == _S_IFDIR)
|
||||
#endif
|
||||
#ifndef S_ISREG
|
||||
#define S_ISREG(a) ((a & _S_IFREG) == _S_IFREG)
|
||||
#endif
|
||||
#else
|
||||
#include <sys/time.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netdb.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <dirent.h>
|
||||
#endif
|
||||
#include <SDL.h>
|
||||
#include "../config.h"
|
||||
#include "gfx.h"
|
||||
#include "network.h"
|
||||
#include "sysfunc.h"
|
||||
|
||||
|
||||
struct __playerilness {
|
||||
int to; // if (to > 0) the ilness is still working
|
||||
int data;
|
||||
} typedef _playerilness;
|
||||
|
||||
|
||||
struct __bomb {
|
||||
_point pos; // lower byte = _X Higher Byte = FX
|
||||
int firer[4]; // range of the fire for the fire for each direction
|
||||
int firerst[4]; /* just save here where the direction was going to stop (-1)
|
||||
if the exp is still growing */
|
||||
int to; // timeout in ms after dropping the bomb. (loops * 0.0005sec)
|
||||
int frame; // frame of the animation
|
||||
int frameto; // timeout for the frame
|
||||
unsigned char r; // range of the bomb
|
||||
unsigned char state; // state of the bomb
|
||||
int ex_nr; // explosion number
|
||||
} typedef _bomb;
|
||||
|
||||
|
||||
struct __player {
|
||||
_gfxplayer *gfx; // pointer to the gfx information
|
||||
int gfx_nr; // number of the player GFX
|
||||
|
||||
int frame; // step of the animation
|
||||
int frameto; // timeout for the animation
|
||||
|
||||
int illframe;
|
||||
int illframeto;
|
||||
|
||||
_point pos; /* position (without the offset)
|
||||
_x = pos.x & 255; fx = pos.x >> 8; */
|
||||
_point old; // the old position
|
||||
signed char d; // direction
|
||||
signed char m; // player is moving ?
|
||||
signed char old_m; // to save the old state..
|
||||
|
||||
int bombs_n; // maximal number of bombs for the player
|
||||
_bomb bombs[MAX_BOMBS]; // number of bombs who are ticking.
|
||||
int range; // range of the bombs
|
||||
int speed; // how fast we can go (0 = slow, 1 = normal... 3 = fastest)
|
||||
int speeddat; // some data i need to do the speed thing
|
||||
_playerilness ill[PI_max]; // all possible types
|
||||
|
||||
char name[LEN_PLAYERNAME]; // name oder name[0] == 0
|
||||
unsigned char state; // status of the player
|
||||
signed char in_nr; // number of the connected player entry
|
||||
|
||||
int points; // points
|
||||
int wins; // wins
|
||||
signed char dead_by; // player who killed this player
|
||||
|
||||
_net_player net; // holds all important network data
|
||||
} typedef _player;
|
||||
|
||||
|
||||
struct __ex_field {
|
||||
unsigned char count;
|
||||
unsigned char frame;
|
||||
} typedef _ex_field;
|
||||
|
||||
|
||||
struct __field {
|
||||
unsigned char type;
|
||||
int frame; // frame (frame > 0 && FS_stone)
|
||||
int frameto; // frame to
|
||||
unsigned char special; // to save special stones
|
||||
_ex_field ex[4]; // count up every explosion there is on this field for ever direction
|
||||
int ex_nr; // number to identify the explosion.
|
||||
} typedef _field;
|
||||
|
||||
|
||||
struct __serverlist {
|
||||
char name[255];
|
||||
} typedef _serverlist;
|
||||
|
||||
|
||||
struct __bomberclone {
|
||||
_point fieldsize; // dimension of the field
|
||||
char datapath[512];
|
||||
|
||||
_player players[MAX_PLAYERS];
|
||||
int p_nr; // Playernumber 0 if you host a game or the number of the one you are.
|
||||
|
||||
_field field[MAX_FIELDSIZE_X][MAX_FIELDSIZE_Y];
|
||||
char fieldpath[512]; // path of the field file
|
||||
|
||||
int last_ex_nr; // number of the last explosion
|
||||
|
||||
unsigned char gametype;
|
||||
unsigned char multitype;
|
||||
unsigned char state;
|
||||
char playername[LEN_PLAYERNAME];
|
||||
int players_nr_s; // number of players at the beginning
|
||||
int players_nr; // number of player who are alife
|
||||
signed char lastwinner; // number of the last winnet
|
||||
|
||||
int maxplayer; // number of max players for the server
|
||||
|
||||
int sock; // the server socket
|
||||
unsigned char net_ai_family;
|
||||
char port[LEN_PORT]; // what port we're using
|
||||
char servername[LEN_SERVERNAME + LEN_PORT + 2]; // holds the name of the current server
|
||||
_serverlist serverlist[MAX_SERVERENTRYS]; // ** CONFIG name of the server we are connected to
|
||||
char gamename[LEN_GAMENAME]; // this will hold the game name
|
||||
char gamemaster[LEN_SERVERNAME + LEN_PORT + 2]; // ** CONFIG ... GameMaster Address
|
||||
unsigned char notifygamemaster;
|
||||
unsigned char askplayername; // ask player for name at startup
|
||||
signed char debug; // 0 = off 1 = on
|
||||
} typedef _bomberclone;
|
||||
|
||||
|
||||
struct __menu {
|
||||
int index;
|
||||
char text[255];
|
||||
} typedef _menu;
|
||||
|
||||
extern _bomberclone bman;
|
||||
extern Uint32 timestamp;
|
||||
extern int debug;
|
||||
|
||||
// Game routines..
|
||||
extern void game_draw_info ();
|
||||
extern void game_loop ();
|
||||
extern void game_end ();
|
||||
extern void game_set_playerposition();
|
||||
|
||||
// everything is declared in field.c
|
||||
extern void draw_field ();
|
||||
extern void draw_stone (int x, int y);
|
||||
extern void field_new (char *filename);
|
||||
extern void field_set_playerposition (int usermap);
|
||||
extern void tileset_random ();
|
||||
|
||||
// everything what is declared in players.c
|
||||
extern void dead_playerani ();
|
||||
extern void draw_player (_player * player);
|
||||
extern void restore_players_screen ();
|
||||
extern void move_player ();
|
||||
extern int stepmove_player ();
|
||||
extern void player_drop_bomb ();
|
||||
extern void get_player_on (short int x, short int y, int pl_nr[]);
|
||||
extern void player_died (_player * player, signed char dead_by);
|
||||
extern void draw_players ();
|
||||
extern void player_animation (_player * player);
|
||||
extern int check_field (short int fx, short int fy, _player * p);
|
||||
extern void player_calcstep (_player * pl);
|
||||
extern void player_calcpos ();
|
||||
extern void player_set_ilness (_player *p, int t);
|
||||
extern void player_clear_ilness (_player *p, int type);
|
||||
extern void player_ilness_loop ();
|
||||
extern void player_check_powerup (_player * p);
|
||||
extern void player_set_gfx (_player *p, signed char gfx_nr);
|
||||
|
||||
// for the bomb..
|
||||
extern void bomb_loop ();
|
||||
extern void restore_bomb_screen ();
|
||||
extern void get_bomb_on (int x, int y, _point bombs[]);
|
||||
extern void draw_fire (int x, int y, int d, int frame);
|
||||
extern void do_explosion (int p, int b);
|
||||
extern void restore_explosion (_bomb * bomb);
|
||||
extern int explosion_check_field (int x, int y, int p, int b);
|
||||
extern void bomb_explode (int p, int b);
|
||||
|
||||
// menus
|
||||
extern void draw_select (int select, _menu menu[], int x, int y);
|
||||
extern int menu_loop (char *menutitle, _menu menu[], int lastselect);
|
||||
extern void draw_menu (char *text, _menu menu[], int *x, int *y);
|
||||
extern void menu_get_text (char *title, char *text, int len);
|
||||
extern void menu_displaymessage (char *title, char *text);
|
||||
extern void menu_displaytext (char *title, char *text, Uint8 r, Uint8 g, Uint8 b);
|
||||
extern char *menu_dir_select (char *title, char *path, signed char dirflags);
|
||||
|
||||
// configuration
|
||||
extern void configuration ();
|
||||
extern void game_init ();
|
||||
extern int ReadConfig();
|
||||
extern int WriteConfig();
|
||||
extern void ReadPrgArgs (int argc, char **argv);
|
||||
|
||||
// debug.c
|
||||
extern void d_in_pl_detail (char *head);
|
||||
extern void d_playerdetail (char *head);
|
||||
extern void d_gamedetail (char *head);
|
||||
extern void d_printf (char *fmt,...);
|
||||
|
||||
|
||||
// single.c
|
||||
extern void single_game_new ();
|
||||
extern void single_create_ai ();
|
||||
extern void single_loop();
|
||||
#endif
|
||||
|
||||
/* $Id: bomberclone.h,v 1.16 2003/05/07 21:28:12 stpohle Exp $ */
|
||||
/* bomberclone.h */
|
||||
|
||||
#ifndef _BOMBERCLONE_H_
|
||||
#define _BOMBERCLONE_H_
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include <time.h>
|
||||
#include <ctype.h>
|
||||
#include <sys/stat.h>
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#include <winsock.h>
|
||||
#include <sys/stat.h>
|
||||
#ifndef S_ISDIR
|
||||
#define S_ISDIR(a) ((a & _S_IFDIR) == _S_IFDIR)
|
||||
#endif
|
||||
#ifndef S_ISREG
|
||||
#define S_ISREG(a) ((a & _S_IFREG) == _S_IFREG)
|
||||
#endif
|
||||
#else
|
||||
#include <sys/time.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netdb.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <dirent.h>
|
||||
#endif
|
||||
#include <SDL.h>
|
||||
#include "../config.h"
|
||||
#include "gfx.h"
|
||||
#include "network.h"
|
||||
#include "sysfunc.h"
|
||||
|
||||
|
||||
struct __playerilness {
|
||||
int to; // if (to > 0) the ilness is still working
|
||||
int data;
|
||||
} typedef _playerilness;
|
||||
|
||||
|
||||
struct __bomb {
|
||||
_point pos; // lower byte = _X Higher Byte = FX
|
||||
int firer[4]; // range of the fire for the fire for each direction
|
||||
int firerst[4]; /* just save here where the direction was going to stop (-1)
|
||||
if the exp is still growing */
|
||||
int to; // timeout in ms after dropping the bomb. (loops * 0.0005sec)
|
||||
int frame; // frame of the animation
|
||||
int frameto; // timeout for the frame
|
||||
unsigned char r; // range of the bomb
|
||||
unsigned char state; // state of the bomb
|
||||
int ex_nr; // explosion number
|
||||
} typedef _bomb;
|
||||
|
||||
|
||||
struct __player {
|
||||
_gfxplayer *gfx; // pointer to the gfx information
|
||||
int gfx_nr; // number of the player GFX
|
||||
|
||||
int frame; // step of the animation
|
||||
int frameto; // timeout for the animation
|
||||
|
||||
int illframe;
|
||||
int illframeto;
|
||||
|
||||
_point pos; /* position (without the offset)
|
||||
_x = pos.x & 255; fx = pos.x >> 8; */
|
||||
_point old; // the old position
|
||||
signed char d; // direction
|
||||
signed char m; // player is moving ?
|
||||
signed char old_m; // to save the old state..
|
||||
|
||||
int bombs_n; // maximal number of bombs for the player
|
||||
_bomb bombs[MAX_BOMBS]; // number of bombs who are ticking.
|
||||
int range; // range of the bombs
|
||||
int speed; // how fast we can go (0 = slow, 1 = normal... 3 = fastest)
|
||||
int speeddat; // some data i need to do the speed thing
|
||||
_playerilness ill[PI_max]; // all possible types
|
||||
|
||||
char name[LEN_PLAYERNAME]; // name oder name[0] == 0
|
||||
unsigned char state; // status of the player
|
||||
signed char in_nr; // number of the connected player entry
|
||||
|
||||
int points; // points
|
||||
int wins; // wins
|
||||
signed char dead_by; // player who killed this player
|
||||
|
||||
_net_player net; // holds all important network data
|
||||
} typedef _player;
|
||||
|
||||
|
||||
struct __ex_field {
|
||||
unsigned char count;
|
||||
unsigned char frame;
|
||||
} typedef _ex_field;
|
||||
|
||||
|
||||
struct __field {
|
||||
unsigned char type;
|
||||
int frame; // frame (frame > 0 && FS_stone)
|
||||
int frameto; // frame to
|
||||
unsigned char special; // to save special stones
|
||||
_ex_field ex[4]; // count up every explosion there is on this field for ever direction
|
||||
int ex_nr; // number to identify the explosion.
|
||||
} typedef _field;
|
||||
|
||||
|
||||
struct __serverlist {
|
||||
char name[255];
|
||||
} typedef _serverlist;
|
||||
|
||||
|
||||
struct __bomberclone {
|
||||
_point fieldsize; // dimension of the field
|
||||
char datapath[512];
|
||||
|
||||
_player players[MAX_PLAYERS];
|
||||
int p_nr; // Playernumber 0 if you host a game or the number of the one you are.
|
||||
|
||||
_field field[MAX_FIELDSIZE_X][MAX_FIELDSIZE_Y];
|
||||
|
||||
int random_map; // random selecting of a map
|
||||
char fieldpath[512]; // path of the field file
|
||||
|
||||
int last_ex_nr; // number of the last explosion
|
||||
|
||||
unsigned char gametype;
|
||||
unsigned char multitype;
|
||||
unsigned char state;
|
||||
char playername[LEN_PLAYERNAME];
|
||||
int players_nr_s; // number of players at the beginning
|
||||
int players_nr; // number of player who are alife
|
||||
signed char lastwinner; // number of the last winnet
|
||||
|
||||
int maxplayer; // number of max players for the server
|
||||
|
||||
int sock; // the server socket
|
||||
unsigned char net_ai_family;
|
||||
char port[LEN_PORT]; // what port we're using
|
||||
char servername[LEN_SERVERNAME + LEN_PORT + 2]; // holds the name of the current server
|
||||
_serverlist serverlist[MAX_SERVERENTRYS]; // ** CONFIG name of the server we are connected to
|
||||
char gamename[LEN_GAMENAME]; // this will hold the game name
|
||||
char gamemaster[LEN_SERVERNAME + LEN_PORT + 2]; // ** CONFIG ... GameMaster Address
|
||||
unsigned char notifygamemaster;
|
||||
unsigned char askplayername; // ask player for name at startup
|
||||
signed char debug; // 0 = off 1 = on
|
||||
} typedef _bomberclone;
|
||||
|
||||
|
||||
struct __menu {
|
||||
int index;
|
||||
char text[255];
|
||||
// int type; // could be visible / disabled / grayed ?? should avoid -2 trick
|
||||
} typedef _menu;
|
||||
|
||||
extern _bomberclone bman;
|
||||
extern Uint32 timestamp;
|
||||
extern int debug;
|
||||
|
||||
// Game routines..
|
||||
extern void game_draw_info ();
|
||||
extern void game_loop ();
|
||||
extern void game_end ();
|
||||
extern void game_set_playerposition();
|
||||
|
||||
// everything is declared in field.c
|
||||
extern void draw_field ();
|
||||
extern void draw_stone (int x, int y);
|
||||
extern void field_new (char *filename);
|
||||
extern void field_set_playerposition (int usermap);
|
||||
extern void tileset_random ();
|
||||
|
||||
// everything what is declared in players.c
|
||||
extern void dead_playerani ();
|
||||
extern void draw_player (_player * player);
|
||||
extern void restore_players_screen ();
|
||||
extern void move_player ();
|
||||
extern int stepmove_player ();
|
||||
extern void player_drop_bomb ();
|
||||
extern void get_player_on (short int x, short int y, int pl_nr[]);
|
||||
extern void player_died (_player * player, signed char dead_by);
|
||||
extern void draw_players ();
|
||||
extern void player_animation (_player * player);
|
||||
extern int check_field (short int fx, short int fy, _player * p);
|
||||
extern void player_calcstep (_player * pl);
|
||||
extern void player_calcpos ();
|
||||
extern void player_set_ilness (_player *p, int t);
|
||||
extern void player_clear_ilness (_player *p, int type);
|
||||
extern void player_ilness_loop ();
|
||||
extern void player_check_powerup (_player * p);
|
||||
extern void player_set_gfx (_player *p, signed char gfx_nr);
|
||||
|
||||
// for the bomb..
|
||||
extern void bomb_loop ();
|
||||
extern void restore_bomb_screen ();
|
||||
extern void get_bomb_on (int x, int y, _point bombs[]);
|
||||
extern void draw_fire (int x, int y, int d, int frame);
|
||||
extern void do_explosion (int p, int b);
|
||||
extern void restore_explosion (_bomb * bomb);
|
||||
extern int explosion_check_field (int x, int y, int p, int b);
|
||||
extern void bomb_explode (int p, int b);
|
||||
|
||||
// menus
|
||||
extern void draw_select (int select, _menu menu[], int x, int y);
|
||||
extern int menu_loop (char *menutitle, _menu menu[], int lastselect);
|
||||
extern void draw_menu (char *text, _menu menu[], int *x, int *y);
|
||||
extern void menu_get_text (char *title, char *text, int len);
|
||||
extern void menu_displaymessage (char *title, char *text);
|
||||
extern void menu_displaytext (char *title, char *text, Uint8 r, Uint8 g, Uint8 b);
|
||||
extern char *menu_dir_select (char *title, char *path, signed char dirflags);
|
||||
|
||||
// configuration
|
||||
extern void configuration ();
|
||||
extern void game_init ();
|
||||
extern int ReadConfig();
|
||||
extern int WriteConfig();
|
||||
extern void ReadPrgArgs (int argc, char **argv);
|
||||
|
||||
// debug.c
|
||||
extern void d_in_pl_detail (char *head);
|
||||
extern void d_playerdetail (char *head);
|
||||
extern void d_gamedetail (char *head);
|
||||
extern void d_printf (char *fmt,...);
|
||||
|
||||
|
||||
// single.c
|
||||
extern void single_game_new ();
|
||||
extern void single_create_ai ();
|
||||
extern void single_loop();
|
||||
|
||||
// mapmenu.c
|
||||
extern void map_random ();
|
||||
extern void tileset_random ();
|
||||
extern void mapmenu ();
|
||||
extern char* getfilename(char* path);
|
||||
extern void init_map_tileset();
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -1,233 +1,233 @@
|
||||
/*
|
||||
chat.c - this file will do everything what have to do with the chat..
|
||||
*/
|
||||
|
||||
#include "bomberclone.h"
|
||||
#include "network.h"
|
||||
#include "packets.h"
|
||||
#include "gfx.h"
|
||||
#include "keybinput.h"
|
||||
#include "chat.h"
|
||||
|
||||
_chat chat;
|
||||
|
||||
/* find a free line or delete the oldest one */
|
||||
int
|
||||
chat_findfreeline ()
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; (i < CHAT_MAX_LINES && chat.lines[i][0] != 0); i++);
|
||||
|
||||
if (i >= CHAT_MAX_LINES) {
|
||||
memcpy (chat.lines[1], chat.lines[0], 255);
|
||||
i = 255;
|
||||
}
|
||||
|
||||
chat.changed = 1;
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
void
|
||||
chat_addline (char *text)
|
||||
{
|
||||
int l;
|
||||
|
||||
l = chat_findfreeline ();
|
||||
|
||||
strncpy (chat.lines[l], text, 255);
|
||||
chat.lineschanged = 1;
|
||||
}
|
||||
|
||||
void
|
||||
chat_drawbox ()
|
||||
{
|
||||
SDL_Rect src;
|
||||
int i;
|
||||
|
||||
if (chat.visible == 0)
|
||||
chat.oldscreen = gfx_copyscreen (&chat.window);
|
||||
|
||||
chat.visible = 1;
|
||||
|
||||
if (gfx_locksurface (gfx.screen))
|
||||
return;
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
src.x = chat.window.x + i;
|
||||
src.w = src.x + chat.window.w - 2;
|
||||
src.y = chat.window.y + i;
|
||||
src.h = src.y + chat.window.h - 2;
|
||||
draw_shadefield (gfx.screen, &src, CHAT_BG_SHADE_BRIGHT);
|
||||
}
|
||||
|
||||
gfx_unlocksurface (gfx.screen);
|
||||
|
||||
src.x = chat.window.x + 2;
|
||||
src.y = chat.window.y + 2;
|
||||
src.w = src.x + chat.window.w - 4;
|
||||
src.h = src.y + chat.window.h - 4 - 16;
|
||||
draw_shadefield (gfx.screen, &src, CHAT_BG_SHADE_DARK);
|
||||
src.x = chat.window.x + 2;
|
||||
src.y = chat.window.y + chat.window.h - 18;
|
||||
src.w = src.x + chat.window.w - 4;
|
||||
src.h = src.y + 16;
|
||||
draw_shadefield (gfx.screen, &src, CHAT_BG_SHADE_DARK >> 1);
|
||||
};
|
||||
|
||||
|
||||
void
|
||||
chat_deletebox ()
|
||||
{
|
||||
SDL_Rect src,
|
||||
dest;
|
||||
|
||||
src.x = 0;
|
||||
src.y = 0;
|
||||
src.w = dest.w = chat.oldscreen->w;
|
||||
src.h = dest.h = chat.oldscreen->h;
|
||||
|
||||
dest.x = chat.window.x;
|
||||
dest.y = chat.window.y;
|
||||
|
||||
SDL_BlitSurface (chat.oldscreen, &src, gfx.screen, &dest);
|
||||
gfx_AddUpdateRect (chat.window.x, chat.window.y, chat.window.w, chat.window.h);
|
||||
|
||||
chat.visible = 0;
|
||||
SDL_FreeSurface (chat.oldscreen);
|
||||
chat.oldscreen = NULL;
|
||||
};
|
||||
|
||||
|
||||
void
|
||||
chat_show (int x1, int y1, int x2, int y2)
|
||||
{
|
||||
if (chat.visible != 0)
|
||||
chat_deletebox ();
|
||||
|
||||
if (x1 == -1 || x2 == -1 || y1 == -1 || y2 == -1 || x2 <= x1 || y2 <= y1)
|
||||
chat.visible = 0;
|
||||
else {
|
||||
chat.window.x = x1;
|
||||
chat.window.y = y1;
|
||||
chat.window.w = x2 - x1;
|
||||
chat.window.h = y2 - y1;
|
||||
chat_drawbox ();
|
||||
keybinput_new (&chat.input);
|
||||
gfx_AddUpdateRect (chat.window.x, chat.window.y, chat.window.w, chat.window.h);
|
||||
chat.changed = 1;
|
||||
chat.lineschanged = 1;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
void
|
||||
chat_clearscreen (signed char all)
|
||||
{
|
||||
SDL_Rect src,
|
||||
dest;
|
||||
|
||||
if (all == 1) {
|
||||
dest.x = chat.window.x + 2;
|
||||
dest.y = chat.window.y + 2;
|
||||
dest.w = dest.x + chat.window.w - 4;
|
||||
dest.h = dest.y + chat.window.h - 4;
|
||||
|
||||
src.x = 2;
|
||||
src.y = 2;
|
||||
src.w = chat.window.w - 4;
|
||||
src.h = chat.window.h - 4;
|
||||
}
|
||||
else {
|
||||
/* redraw only the textline of out input box */
|
||||
dest.x = chat.window.x + 2;
|
||||
dest.y = chat.window.y + chat.window.h - 18;
|
||||
dest.w = src.w = chat.window.w - 4;
|
||||
dest.h = src.h = 16;
|
||||
|
||||
src.x = 2;
|
||||
src.y = chat.window.h - 18;
|
||||
}
|
||||
SDL_BlitSurface (chat.oldscreen, &src, gfx.screen, &dest);
|
||||
|
||||
if (all == 1) {
|
||||
dest.w = dest.x + chat.window.w - 4;
|
||||
dest.h = dest.y + chat.window.h - 4 - 16;
|
||||
draw_shadefield (gfx.screen, &dest, CHAT_BG_SHADE_DARK);
|
||||
}
|
||||
|
||||
src.x = chat.window.x + 2;
|
||||
src.y = chat.window.y + chat.window.h - 18;
|
||||
src.w = src.x + chat.window.w - 4;
|
||||
src.h = src.y + 16;
|
||||
draw_shadefield (gfx.screen, &src, CHAT_BG_SHADE_DARK >> 1);
|
||||
|
||||
gfx_AddUpdateRect (chat.window.x, chat.window.y, chat.window.w, chat.window.h);
|
||||
};
|
||||
|
||||
|
||||
void
|
||||
chat_loop (SDL_Event * event)
|
||||
{
|
||||
int i,
|
||||
y,
|
||||
l,
|
||||
p1,
|
||||
p2,
|
||||
maxchar;
|
||||
char text[255];
|
||||
|
||||
i = keybinput_loop (&chat.input, event);
|
||||
|
||||
if (i == 1 && chat.input.text[0] != 0) {
|
||||
sprintf (text, "%s: %s", bman.playername, chat.input.text);
|
||||
net_send_chat (text, 1);
|
||||
chat_addline (text);
|
||||
keybinput_new (&chat.input);
|
||||
i = 0;
|
||||
}
|
||||
|
||||
if (((i == 0 && chat.input.changed == 1) || chat.changed == 1) && chat.visible == 1) {
|
||||
/* draw the new field */
|
||||
chat_clearscreen (chat.lineschanged);
|
||||
p1 = p2 = 0;
|
||||
maxchar = (chat.window.w - 4) / (gfx.font.size.x - 4);
|
||||
if (chat.lineschanged) {
|
||||
y = chat.window.y + 4;
|
||||
l = chat.startline;
|
||||
while (y < (chat.window.y + chat.window.h - 32) && chat.lines[l][0] != 0) {
|
||||
for (p1 = 0; (p1 < maxchar && chat.lines[l][p2] != 0); p1++)
|
||||
text[p1] = chat.lines[l][p2++];
|
||||
text[p1] = 0;
|
||||
draw_text (chat.window.x + 4, y, text, 1);
|
||||
if (chat.lines[l][p2] == 0) { // the end of the line
|
||||
l++;
|
||||
p2 = 0;
|
||||
}
|
||||
y = y + gfx.font.size.y;
|
||||
}
|
||||
if (chat.lines[l][0] != 0) {
|
||||
chat.startline++;
|
||||
chat.changed = 1;
|
||||
chat.lineschanged = 1;
|
||||
}
|
||||
else {
|
||||
chat.changed = 0;
|
||||
chat.lineschanged = 0;
|
||||
}
|
||||
}
|
||||
if (chat.startline >= CHAT_MAX_LINES)
|
||||
chat.startline = CHAT_MAX_LINES - 5;
|
||||
|
||||
/* draw the input line */
|
||||
if (chat.input.len > maxchar)
|
||||
p2 = chat.input.len - maxchar;
|
||||
|
||||
for (p1 = 0; (p1 < maxchar && chat.input.text[p2] != 0); p1++)
|
||||
text[p1] = chat.input.text[p2++];
|
||||
text[p1] = 0;
|
||||
draw_text (chat.window.x + 4, (chat.window.y + chat.window.h) - 4 - gfx.font.size.y, text,
|
||||
1);
|
||||
}
|
||||
};
|
||||
/*
|
||||
chat.c - this file will do everything what have to do with the chat..
|
||||
*/
|
||||
|
||||
#include "bomberclone.h"
|
||||
#include "network.h"
|
||||
#include "packets.h"
|
||||
#include "gfx.h"
|
||||
#include "keybinput.h"
|
||||
#include "chat.h"
|
||||
|
||||
_chat chat;
|
||||
|
||||
/* find a free line or delete the oldest one */
|
||||
int
|
||||
chat_findfreeline ()
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; (i < CHAT_MAX_LINES && chat.lines[i][0] != 0); i++);
|
||||
|
||||
if (i >= CHAT_MAX_LINES) {
|
||||
memcpy (chat.lines[1], chat.lines[0], 255);
|
||||
i = 255;
|
||||
}
|
||||
|
||||
chat.changed = 1;
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
void
|
||||
chat_addline (char *text)
|
||||
{
|
||||
int l;
|
||||
|
||||
l = chat_findfreeline ();
|
||||
|
||||
strncpy (chat.lines[l], text, 255);
|
||||
chat.lineschanged = 1;
|
||||
}
|
||||
|
||||
void
|
||||
chat_drawbox ()
|
||||
{
|
||||
SDL_Rect src;
|
||||
int i;
|
||||
|
||||
if (chat.visible == 0)
|
||||
chat.oldscreen = gfx_copyscreen (&chat.window);
|
||||
|
||||
chat.visible = 1;
|
||||
|
||||
if (gfx_locksurface (gfx.screen))
|
||||
return;
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
src.x = chat.window.x + i;
|
||||
src.w = src.x + chat.window.w - 2;
|
||||
src.y = chat.window.y + i;
|
||||
src.h = src.y + chat.window.h - 2;
|
||||
draw_shadefield (gfx.screen, &src, CHAT_BG_SHADE_BRIGHT);
|
||||
}
|
||||
|
||||
gfx_unlocksurface (gfx.screen);
|
||||
|
||||
src.x = chat.window.x + 2;
|
||||
src.y = chat.window.y + 2;
|
||||
src.w = src.x + chat.window.w - 4;
|
||||
src.h = src.y + chat.window.h - 4 - 16;
|
||||
draw_shadefield (gfx.screen, &src, CHAT_BG_SHADE_DARK);
|
||||
src.x = chat.window.x + 2;
|
||||
src.y = chat.window.y + chat.window.h - 18;
|
||||
src.w = src.x + chat.window.w - 4;
|
||||
src.h = src.y + 16;
|
||||
draw_shadefield (gfx.screen, &src, CHAT_BG_SHADE_DARK >> 1);
|
||||
};
|
||||
|
||||
|
||||
void
|
||||
chat_deletebox ()
|
||||
{
|
||||
SDL_Rect src,
|
||||
dest;
|
||||
|
||||
src.x = 0;
|
||||
src.y = 0;
|
||||
src.w = dest.w = chat.oldscreen->w;
|
||||
src.h = dest.h = chat.oldscreen->h;
|
||||
|
||||
dest.x = chat.window.x;
|
||||
dest.y = chat.window.y;
|
||||
|
||||
SDL_BlitSurface (chat.oldscreen, &src, gfx.screen, &dest);
|
||||
gfx_AddUpdateRect (chat.window.x, chat.window.y, chat.window.w, chat.window.h);
|
||||
|
||||
chat.visible = 0;
|
||||
SDL_FreeSurface (chat.oldscreen);
|
||||
chat.oldscreen = NULL;
|
||||
};
|
||||
|
||||
|
||||
void
|
||||
chat_show (int x1, int y1, int x2, int y2)
|
||||
{
|
||||
if (chat.visible != 0)
|
||||
chat_deletebox ();
|
||||
|
||||
if (x1 == -1 || x2 == -1 || y1 == -1 || y2 == -1 || x2 <= x1 || y2 <= y1)
|
||||
chat.visible = 0;
|
||||
else {
|
||||
chat.window.x = x1;
|
||||
chat.window.y = y1;
|
||||
chat.window.w = x2 - x1;
|
||||
chat.window.h = y2 - y1;
|
||||
chat_drawbox ();
|
||||
keybinput_new (&chat.input);
|
||||
gfx_AddUpdateRect (chat.window.x, chat.window.y, chat.window.w, chat.window.h);
|
||||
chat.changed = 1;
|
||||
chat.lineschanged = 1;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
void
|
||||
chat_clearscreen (signed char all)
|
||||
{
|
||||
SDL_Rect src,
|
||||
dest;
|
||||
|
||||
if (all == 1) {
|
||||
dest.x = chat.window.x + 2;
|
||||
dest.y = chat.window.y + 2;
|
||||
dest.w = dest.x + chat.window.w - 4;
|
||||
dest.h = dest.y + chat.window.h - 4;
|
||||
|
||||
src.x = 2;
|
||||
src.y = 2;
|
||||
src.w = chat.window.w - 4;
|
||||
src.h = chat.window.h - 4;
|
||||
}
|
||||
else {
|
||||
/* redraw only the textline of out input box */
|
||||
dest.x = chat.window.x + 2;
|
||||
dest.y = chat.window.y + chat.window.h - 18;
|
||||
dest.w = src.w = chat.window.w - 4;
|
||||
dest.h = src.h = 16;
|
||||
|
||||
src.x = 2;
|
||||
src.y = chat.window.h - 18;
|
||||
}
|
||||
SDL_BlitSurface (chat.oldscreen, &src, gfx.screen, &dest);
|
||||
|
||||
if (all == 1) {
|
||||
dest.w = dest.x + chat.window.w - 4;
|
||||
dest.h = dest.y + chat.window.h - 4 - 16;
|
||||
draw_shadefield (gfx.screen, &dest, CHAT_BG_SHADE_DARK);
|
||||
}
|
||||
|
||||
src.x = chat.window.x + 2;
|
||||
src.y = chat.window.y + chat.window.h - 18;
|
||||
src.w = src.x + chat.window.w - 4;
|
||||
src.h = src.y + 16;
|
||||
draw_shadefield (gfx.screen, &src, CHAT_BG_SHADE_DARK >> 1);
|
||||
|
||||
gfx_AddUpdateRect (chat.window.x, chat.window.y, chat.window.w, chat.window.h);
|
||||
};
|
||||
|
||||
|
||||
void
|
||||
chat_loop (SDL_Event * event)
|
||||
{
|
||||
int i,
|
||||
y,
|
||||
l,
|
||||
p1,
|
||||
p2,
|
||||
maxchar;
|
||||
char text[255];
|
||||
|
||||
i = keybinput_loop (&chat.input, event);
|
||||
|
||||
if (i == 1 && chat.input.text[0] != 0) {
|
||||
sprintf (text, "%s: %s", bman.playername, chat.input.text);
|
||||
net_send_chat (text, 1);
|
||||
chat_addline (text);
|
||||
keybinput_new (&chat.input);
|
||||
i = 0;
|
||||
}
|
||||
|
||||
if (((i == 0 && chat.input.changed == 1) || chat.changed == 1) && chat.visible == 1) {
|
||||
/* draw the new field */
|
||||
chat_clearscreen (chat.lineschanged);
|
||||
p1 = p2 = 0;
|
||||
maxchar = (chat.window.w - 4) / (gfx.font.size.x - 4);
|
||||
if (chat.lineschanged) {
|
||||
y = chat.window.y + 4;
|
||||
l = chat.startline;
|
||||
while (y < (chat.window.y + chat.window.h - 32) && chat.lines[l][0] != 0) {
|
||||
for (p1 = 0; (p1 < maxchar && chat.lines[l][p2] != 0); p1++)
|
||||
text[p1] = chat.lines[l][p2++];
|
||||
text[p1] = 0;
|
||||
draw_text (chat.window.x + 4, y, text, 1);
|
||||
if (chat.lines[l][p2] == 0) { // the end of the line
|
||||
l++;
|
||||
p2 = 0;
|
||||
}
|
||||
y = y + gfx.font.size.y;
|
||||
}
|
||||
if (chat.lines[l][0] != 0) {
|
||||
chat.startline++;
|
||||
chat.changed = 1;
|
||||
chat.lineschanged = 1;
|
||||
}
|
||||
else {
|
||||
chat.changed = 0;
|
||||
chat.lineschanged = 0;
|
||||
}
|
||||
}
|
||||
if (chat.startline >= CHAT_MAX_LINES)
|
||||
chat.startline = CHAT_MAX_LINES - 5;
|
||||
|
||||
/* draw the input line */
|
||||
if (chat.input.len > maxchar)
|
||||
p2 = chat.input.len - maxchar;
|
||||
|
||||
for (p1 = 0; (p1 < maxchar && chat.input.text[p2] != 0); p1++)
|
||||
text[p1] = chat.input.text[p2++];
|
||||
text[p1] = 0;
|
||||
draw_text (chat.window.x + 4, (chat.window.y + chat.window.h) - 4 - gfx.font.size.y, text,
|
||||
1);
|
||||
}
|
||||
};
|
||||
|
@ -1,29 +1,29 @@
|
||||
|
||||
#ifndef _CHAT_H_
|
||||
#define _CHAT_H_
|
||||
|
||||
#include "keybinput.h"
|
||||
|
||||
#define CHAT_MAX_LINES 255
|
||||
#define CHAT_BG_SHADE_DARK -64
|
||||
#define CHAT_BG_SHADE_BRIGHT 64
|
||||
|
||||
struct __chat {
|
||||
SDL_Rect window;
|
||||
signed char visible;
|
||||
signed char changed;
|
||||
SDL_Surface *oldscreen;
|
||||
short int startline;
|
||||
char lines[CHAT_MAX_LINES][255];
|
||||
signed char lineschanged;
|
||||
_keybinput input;
|
||||
} typedef _chat;
|
||||
|
||||
extern _chat chat;
|
||||
|
||||
extern void chat_show (int x1, int y1, int x2, int y2);
|
||||
extern void chat_addline (char *text);
|
||||
extern void chat_loop (SDL_Event *event);
|
||||
extern void chat_drawbox ();
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef _CHAT_H_
|
||||
#define _CHAT_H_
|
||||
|
||||
#include "keybinput.h"
|
||||
|
||||
#define CHAT_MAX_LINES 255
|
||||
#define CHAT_BG_SHADE_DARK -64
|
||||
#define CHAT_BG_SHADE_BRIGHT 64
|
||||
|
||||
struct __chat {
|
||||
SDL_Rect window;
|
||||
signed char visible;
|
||||
signed char changed;
|
||||
SDL_Surface *oldscreen;
|
||||
short int startline;
|
||||
char lines[CHAT_MAX_LINES][255];
|
||||
signed char lineschanged;
|
||||
_keybinput input;
|
||||
} typedef _chat;
|
||||
|
||||
extern _chat chat;
|
||||
|
||||
extern void chat_show (int x1, int y1, int x2, int y2);
|
||||
extern void chat_addline (char *text);
|
||||
extern void chat_loop (SDL_Event *event);
|
||||
extern void chat_drawbox ();
|
||||
|
||||
#endif
|
||||
|
@ -1,411 +1,395 @@
|
||||
/* configuration */
|
||||
|
||||
#include <SDL.h>
|
||||
|
||||
#include "basic.h"
|
||||
#include "bomberclone.h"
|
||||
#include "network.h"
|
||||
#include "packets.h"
|
||||
#include "gfx.h"
|
||||
#include "chat.h"
|
||||
|
||||
void
|
||||
game_init ()
|
||||
{
|
||||
int i;
|
||||
|
||||
srand (((int) time (NULL))); // initialize randomgenerator
|
||||
|
||||
// do some init stuff
|
||||
for (i = 0; i < MAX_SERVERENTRYS; i++)
|
||||
bman.serverlist[i].name[0] = 0;
|
||||
|
||||
for (i = 0; i < MAX_PLAYERS; i++) {
|
||||
bman.players[i].gfx = NULL; /* we will select them in the wait_for_players loop */
|
||||
bman.players[i].gfx_nr = -1; /* and even now in the singleplayer menu */
|
||||
}
|
||||
|
||||
chat.visible = 0;
|
||||
chat.startline = 0;
|
||||
for (i = 0; i < CHAT_MAX_LINES; i++)
|
||||
chat.lines[i][0] = 0;
|
||||
|
||||
bman.maxplayer = MAX_PLAYERS;
|
||||
bman.net_ai_family = PF_INET;
|
||||
bman.sock = -1;
|
||||
bman.gamename[0] = 0;
|
||||
sprintf (bman.port, "%d", DEFAULT_UDPPORT);
|
||||
sprintf (bman.gamemaster, DEFAULT_GAMEMASTER);
|
||||
resend_cache.data = NULL;
|
||||
resend_cache.fill = -1;
|
||||
bman.notifygamemaster = 1;
|
||||
bman.askplayername = 1;
|
||||
debug = 0;
|
||||
gfx.res.x = 640;
|
||||
gfx.res.y = 480;
|
||||
gfx.bpp = 16;
|
||||
gfx.tileset[0] = 0;
|
||||
gfx.random_tileset = 1;
|
||||
bman.fieldsize.x = 25;
|
||||
bman.fieldsize.y = 17;
|
||||
sprintf (bman.datapath, "data");
|
||||
bman.fieldpath[0] = 0;
|
||||
};
|
||||
|
||||
int
|
||||
ReadConfig ()
|
||||
{
|
||||
FILE *config;
|
||||
char buf[1024],
|
||||
key2[1024];
|
||||
char *findit,
|
||||
*keyword,
|
||||
*value;
|
||||
int i;
|
||||
char filename[512];
|
||||
|
||||
#ifdef _WIN32
|
||||
sprintf (filename, "%sbomberclone.cfg", s_gethomedir ());
|
||||
#else
|
||||
sprintf (filename, "%s.bomberclone.cfg", s_gethomedir ());
|
||||
#endif
|
||||
|
||||
config = fopen (filename, "r");
|
||||
if (config == NULL) {
|
||||
d_printf ("Error: Config file not found!\n");
|
||||
return -1;
|
||||
}
|
||||
d_printf ("Reading Config-file: %s", filename);
|
||||
/* printf("Reading config file...\n"); */
|
||||
|
||||
while (fgets (buf, sizeof (buf), config) != NULL) {
|
||||
findit = strchr (buf, '\n');
|
||||
if (findit)
|
||||
findit[0] = '\0';
|
||||
if (buf[0] == '\0')
|
||||
continue;
|
||||
|
||||
keyword = buf;
|
||||
while (isspace (*keyword))
|
||||
keyword++;
|
||||
|
||||
value = strchr (buf, '=');
|
||||
if (value == NULL)
|
||||
continue;
|
||||
*value = 0;
|
||||
value++;
|
||||
while (*value == ' ')
|
||||
value++;
|
||||
while (keyword[strlen (keyword) - 1] == ' ')
|
||||
keyword[strlen (keyword) - 1] = 0;
|
||||
while (value[strlen (value) - 1] == ' ')
|
||||
value[strlen (value) - 1] = 0;
|
||||
if (strlen (value) == 0)
|
||||
continue;
|
||||
for (i = 0; i < (int) strlen (keyword); i++)
|
||||
keyword[i] = tolower (keyword[i]);
|
||||
|
||||
if (!strcmp (keyword, "playername")) {
|
||||
if (strlen (value) > LEN_PLAYERNAME) {
|
||||
d_printf
|
||||
("*** Error - playername too long (maximum size permitted is %d characters)!\n\n",
|
||||
LEN_PLAYERNAME);
|
||||
}
|
||||
value[LEN_PLAYERNAME - 1] = 0;
|
||||
strcpy (bman.playername, value);
|
||||
}
|
||||
|
||||
if (!strcmp (keyword, "gamename")) {
|
||||
if (strlen (value) > LEN_GAMENAME) {
|
||||
d_printf
|
||||
("*** Error - servername too long (maximum size permitted is %d characters)!\n\n",
|
||||
LEN_GAMENAME);
|
||||
}
|
||||
value[LEN_GAMENAME - 1] = 0;
|
||||
strcpy (bman.gamename, value);
|
||||
}
|
||||
|
||||
if (!strcmp (keyword, "askplayername")) {
|
||||
bman.askplayername = atoi (value);
|
||||
}
|
||||
if (!strcmp (keyword, "resolutionx")) {
|
||||
gfx.res.x = atoi (value);
|
||||
}
|
||||
if (!strcmp (keyword, "resolutiony")) {
|
||||
gfx.res.y = atoi (value);
|
||||
}
|
||||
if (!strcmp (keyword, "fieldpath")) {
|
||||
if (strlen (value) > 510) {
|
||||
d_printf
|
||||
("*** Error - fieldpath too long (maximum size permitted is %d characters)!\n\n",
|
||||
510);
|
||||
}
|
||||
value[511] = 0;
|
||||
strcpy(bman.fieldpath,value);
|
||||
}
|
||||
if (!strcmp (keyword, "fieldsizex")) {
|
||||
bman.fieldsize.x = atoi (value);
|
||||
}
|
||||
if (!strcmp (keyword, "fieldsizey")) {
|
||||
bman.fieldsize.y = atoi (value);
|
||||
}
|
||||
if (!strcmp (keyword, "fullscreen")) {
|
||||
gfx.fullscreen = atoi (value);
|
||||
}
|
||||
if (!strcmp (keyword, "bitsperpixel")) {
|
||||
gfx.bpp = atoi (value);
|
||||
}
|
||||
if (!strcmp (keyword, "ai_family")) {
|
||||
bman.net_ai_family = atoi (value);
|
||||
}
|
||||
if (!strcmp (keyword, "debug")) {
|
||||
debug = atoi (value);
|
||||
}
|
||||
if (!strcmp (keyword, "notify")) {
|
||||
bman.notifygamemaster = atoi (value);
|
||||
}
|
||||
if (!strcmp (keyword, "masterserver")) {
|
||||
strcpy (bman.gamemaster, value);
|
||||
}
|
||||
if (!strcmp (keyword, "maxplayer")) {
|
||||
bman.maxplayer = atoi (value);
|
||||
}
|
||||
for (i = 0; i < MAX_SERVERENTRYS; i++) {
|
||||
sprintf (key2, "ip%d", i);
|
||||
if (!strcmp (keyword, key2)) {
|
||||
strcpy (bman.serverlist[i].name, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
fclose (config);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
WriteConfig ()
|
||||
{
|
||||
FILE *config;
|
||||
int i;
|
||||
char filename[512];
|
||||
#ifdef _WIN32
|
||||
sprintf (filename, "%sbomberclone.cfg", s_gethomedir ());
|
||||
#else
|
||||
sprintf (filename, "%s.bomberclone.cfg", s_gethomedir ());
|
||||
#endif
|
||||
if ((config = fopen (filename, "w")) == NULL)
|
||||
return -1;
|
||||
fprintf (config, "resolutionx=%d\n", gfx.res.x);
|
||||
fprintf (config, "resolutiony=%d\n", gfx.res.y);
|
||||
fprintf (config, "fullscreen=%d\n", gfx.fullscreen);
|
||||
fprintf (config, "fieldpath=%s\n", bman.fieldpath);
|
||||
fprintf (config, "fieldsizex=%d\n", bman.fieldsize.x);
|
||||
fprintf (config, "fieldsizey=%d\n", bman.fieldsize.y);
|
||||
fprintf (config, "notify=%d\n", bman.notifygamemaster);
|
||||
fprintf (config, "ai_family=%d\n", bman.net_ai_family);
|
||||
fprintf (config, "masterserver=%s\n", bman.gamemaster);
|
||||
fprintf (config, "gamename=%s\n", bman.gamename);
|
||||
fprintf (config, "maxplayer=%d\n", bman.maxplayer);
|
||||
for (i = 0; i < MAX_SERVERENTRYS; i++)
|
||||
fprintf (config, "ip%d=%s\n", i, bman.serverlist[i].name);
|
||||
fprintf (config, "debug=%d\n", debug);
|
||||
fprintf (config, "askplayername=%d\n", bman.askplayername);
|
||||
fprintf (config, "playername=%s\n", bman.playername);
|
||||
fprintf (config, "bitsperpixel=%d\n", gfx.bpp);
|
||||
|
||||
fclose (config);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
change_res ()
|
||||
{
|
||||
int menuselect = 0;
|
||||
_menu menu[] = {
|
||||
{0, "Full Screen"},
|
||||
{1, "640x480"},
|
||||
{2, "800x600"},
|
||||
{3, "1024x768"},
|
||||
{4, "1280x1024"},
|
||||
{5, "BPP"},
|
||||
{6, "Return To Configuration Menu"},
|
||||
{-1, ""}
|
||||
};
|
||||
while (1) {
|
||||
if (gfx.fullscreen)
|
||||
sprintf (menu[0].text, "Disable Fullscreen");
|
||||
else
|
||||
sprintf (menu[0].text, "Enable Full Screen");
|
||||
|
||||
if (gfx.bpp == 16)
|
||||
sprintf (menu[5].text, "16 Bit Per Pixel");
|
||||
else if (gfx.bpp == 24)
|
||||
sprintf (menu[5].text, "24 Bit Per Pixel");
|
||||
else
|
||||
sprintf (menu[5].text, "32 Bit Per Pixel");
|
||||
|
||||
menuselect = menu_loop ("Video Options", menu, menuselect);
|
||||
|
||||
switch (menuselect) {
|
||||
case (0): // Fullscreen
|
||||
if (gfx.fullscreen)
|
||||
gfx.fullscreen = 0;
|
||||
else
|
||||
gfx.fullscreen = 1;
|
||||
break;
|
||||
|
||||
case (1): // 640x480
|
||||
gfx.res.x = 640;
|
||||
gfx.res.y = 480;
|
||||
break;
|
||||
case (2): // 800x600
|
||||
gfx.res.x = 800;
|
||||
gfx.res.y = 600;
|
||||
break;
|
||||
case (3): // 1024x768
|
||||
gfx.res.x = 1024;
|
||||
gfx.res.y = 768;
|
||||
break;
|
||||
case (4): // 1280x1024
|
||||
gfx.res.x = 1280;
|
||||
gfx.res.y = 1024;
|
||||
break;
|
||||
case (5):
|
||||
if (gfx.bpp == 16)
|
||||
gfx.bpp = 24;
|
||||
else if (gfx.bpp == 24)
|
||||
gfx.bpp = 32;
|
||||
else
|
||||
gfx.bpp = 16;
|
||||
break;
|
||||
case (6): // Return
|
||||
menuselect = -1;
|
||||
break;
|
||||
}
|
||||
if (menuselect != -1) {
|
||||
gfx_shutdown ();
|
||||
gfx_init ();
|
||||
}
|
||||
else
|
||||
return;
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
void
|
||||
configuration ()
|
||||
{
|
||||
int menuselect = 0;
|
||||
char text[255];
|
||||
_menu menu[] = {
|
||||
{0, "Player Name:"},
|
||||
{1, "Video Options"},
|
||||
{2, "Sound Options"},
|
||||
{3, "Customize Keyboard"},
|
||||
{4, "Field File:"},
|
||||
{5, "Field Size X:"},
|
||||
{6, "Field Size Y:"},
|
||||
{7, "Prompt For Player Name"},
|
||||
{8, "Debug"},
|
||||
{9, "Save Config"},
|
||||
{10, "Return To Main Manu"},
|
||||
{-1, ""}
|
||||
};
|
||||
|
||||
while (menuselect != -1) {
|
||||
|
||||
sprintf (menu[0].text, "Player Name: %s", bman.playername);
|
||||
if(bman.fieldpath[0])
|
||||
sprintf (menu[4].text, "Field File: %s", bman.fieldpath);
|
||||
else
|
||||
sprintf (menu[4].text, "Field File: <not used>");
|
||||
sprintf (menu[5].text, "Field Size X: %d", bman.fieldsize.x);
|
||||
sprintf (menu[6].text, "Field Size Y: %d", bman.fieldsize.y);
|
||||
|
||||
if (debug == 1)
|
||||
sprintf (menu[8].text, "Debug Messages ON");
|
||||
else
|
||||
sprintf (menu[8].text, "Debug Messages OFF");
|
||||
|
||||
if (bman.askplayername == 1)
|
||||
sprintf (menu[7].text, "Prompt For Name: Yes");
|
||||
else
|
||||
sprintf (menu[7].text, "Prompt For Name: No");
|
||||
|
||||
menuselect = menu_loop ("Configuration", menu, menuselect);
|
||||
|
||||
|
||||
switch (menuselect) {
|
||||
case (0): // Playername
|
||||
menu_get_text ("Enter Playername", bman.playername, LEN_PLAYERNAME - 1);
|
||||
bman.playername[LEN_PLAYERNAME - 1] = 0;
|
||||
break;
|
||||
case (1): // Screen Options
|
||||
change_res ();
|
||||
break;
|
||||
case (2): // Sound Options
|
||||
case (3): // Customize Keyboard
|
||||
break;
|
||||
case (4): // Field File
|
||||
menu_get_text ("Enter the path of a field file", bman.fieldpath, 30);
|
||||
bman.fieldpath[511] = 0;
|
||||
break;
|
||||
case (5): // Change X Fieldsize
|
||||
sprintf (menu[5].text, "%d", bman.fieldsize.x);
|
||||
sprintf (text, "Field Size X (%d - %d)", MIN_FIELDSIZE_X, MAX_FIELDSIZE_X);
|
||||
menu_get_text (text, menu[5].text, 3);
|
||||
bman.fieldsize.x = atoi (menu[5].text) | 1;
|
||||
if (bman.fieldsize.x < MIN_FIELDSIZE_X)
|
||||
bman.fieldsize.x = MIN_FIELDSIZE_X;
|
||||
if (bman.fieldsize.x > MAX_FIELDSIZE_X)
|
||||
bman.fieldsize.x = MAX_FIELDSIZE_X;
|
||||
break;
|
||||
|
||||
case (6): // Change Y Fieldsize
|
||||
sprintf (menu[6].text, "%d", bman.fieldsize.y);
|
||||
sprintf (text, "Field Size Y (%d - %d)", MIN_FIELDSIZE_Y, MAX_FIELDSIZE_Y);
|
||||
menu_get_text (text, menu[6].text, 3);
|
||||
bman.fieldsize.y = atoi (menu[6].text) | 1;
|
||||
if (bman.fieldsize.y < MIN_FIELDSIZE_Y)
|
||||
bman.fieldsize.y = MIN_FIELDSIZE_Y;
|
||||
if (bman.fieldsize.y > MAX_FIELDSIZE_Y)
|
||||
bman.fieldsize.y = MAX_FIELDSIZE_Y;
|
||||
break;
|
||||
|
||||
case (7): // Debugging On / Off
|
||||
if (bman.askplayername == 1)
|
||||
bman.askplayername = 0;
|
||||
else
|
||||
bman.askplayername = 1;
|
||||
break;
|
||||
case (8): // Debugging On / Off
|
||||
if (debug == 1)
|
||||
debug = 0;
|
||||
else {
|
||||
debug = 1;
|
||||
d_printf ("BomberClone ver.%s\n", VERSION);
|
||||
}
|
||||
break;
|
||||
case (9): // Save Configuration
|
||||
WriteConfig ();
|
||||
break;
|
||||
case (10): // Return to main menu
|
||||
menuselect = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
void
|
||||
ReadPrgArgs (int argc, char **argv)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
while (argv[++i] != NULL) {
|
||||
if (!strcmp (argv[i], "-port"))
|
||||
strncpy (bman.port, argv[++i], LEN_PORT);
|
||||
}
|
||||
};
|
||||
/* configuration */
|
||||
|
||||
#include <SDL.h>
|
||||
|
||||
#include "basic.h"
|
||||
#include "bomberclone.h"
|
||||
#include "network.h"
|
||||
#include "packets.h"
|
||||
#include "gfx.h"
|
||||
#include "chat.h"
|
||||
|
||||
void
|
||||
game_init ()
|
||||
{
|
||||
int i;
|
||||
|
||||
srand (((int) time (NULL))); // initialize randomgenerator
|
||||
|
||||
// do some init stuff
|
||||
for (i = 0; i < MAX_SERVERENTRYS; i++)
|
||||
bman.serverlist[i].name[0] = 0;
|
||||
|
||||
for (i = 0; i < MAX_PLAYERS; i++) {
|
||||
bman.players[i].gfx = NULL; /* we will select them in the wait_for_players loop */
|
||||
bman.players[i].gfx_nr = -1; /* and even now in the singleplayer menu */
|
||||
}
|
||||
|
||||
chat.visible = 0;
|
||||
chat.startline = 0;
|
||||
for (i = 0; i < CHAT_MAX_LINES; i++)
|
||||
chat.lines[i][0] = 0;
|
||||
|
||||
bman.maxplayer = MAX_PLAYERS;
|
||||
bman.net_ai_family = PF_INET;
|
||||
bman.sock = -1;
|
||||
bman.gamename[0] = 0;
|
||||
sprintf (bman.port, "%d", DEFAULT_UDPPORT);
|
||||
sprintf (bman.gamemaster, DEFAULT_GAMEMASTER);
|
||||
resend_cache.data = NULL;
|
||||
resend_cache.fill = -1;
|
||||
bman.notifygamemaster = 1;
|
||||
bman.askplayername = 1;
|
||||
debug = 0;
|
||||
gfx.res.x = 640;
|
||||
gfx.res.y = 480;
|
||||
gfx.bpp = 16;
|
||||
gfx.tileset[0] = 0;
|
||||
gfx.random_tileset = 1;
|
||||
bman.fieldsize.x = 25;
|
||||
bman.fieldsize.y = 17;
|
||||
sprintf (bman.datapath, "data");
|
||||
bman.fieldpath[0] = 0;
|
||||
bman.random_map = 1;
|
||||
init_map_tileset();
|
||||
};
|
||||
|
||||
int
|
||||
ReadConfig ()
|
||||
{
|
||||
FILE *config;
|
||||
char buf[1024],
|
||||
key2[1024];
|
||||
char *findit,
|
||||
*keyword,
|
||||
*value;
|
||||
int i;
|
||||
char filename[512];
|
||||
|
||||
#ifdef _WIN32
|
||||
sprintf (filename, "%sbomberclone.cfg", s_gethomedir ());
|
||||
#else
|
||||
sprintf (filename, "%s.bomberclone.cfg", s_gethomedir ());
|
||||
#endif
|
||||
|
||||
config = fopen (filename, "r");
|
||||
if (config == NULL) {
|
||||
d_printf ("Error: Config file not found!\n");
|
||||
return -1;
|
||||
}
|
||||
d_printf ("Reading Config-file: %s", filename);
|
||||
/* printf("Reading config file...\n"); */
|
||||
|
||||
while (fgets (buf, sizeof (buf), config) != NULL) {
|
||||
findit = strchr (buf, '\n');
|
||||
if (findit)
|
||||
findit[0] = '\0';
|
||||
if (buf[0] == '\0')
|
||||
continue;
|
||||
|
||||
keyword = buf;
|
||||
while (isspace (*keyword))
|
||||
keyword++;
|
||||
|
||||
value = strchr (buf, '=');
|
||||
if (value == NULL)
|
||||
continue;
|
||||
*value = 0;
|
||||
value++;
|
||||
while (*value == ' ')
|
||||
value++;
|
||||
while (keyword[strlen (keyword) - 1] == ' ')
|
||||
keyword[strlen (keyword) - 1] = 0;
|
||||
while (value[strlen (value) - 1] == ' ')
|
||||
value[strlen (value) - 1] = 0;
|
||||
if (strlen (value) == 0)
|
||||
continue;
|
||||
for (i = 0; i < (int) strlen (keyword); i++)
|
||||
keyword[i] = tolower (keyword[i]);
|
||||
|
||||
if (!strcmp (keyword, "playername")) {
|
||||
if (strlen (value) > LEN_PLAYERNAME) {
|
||||
d_printf
|
||||
("*** Error - playername too long (maximum size permitted is %d characters)!\n\n",
|
||||
LEN_PLAYERNAME);
|
||||
}
|
||||
value[LEN_PLAYERNAME - 1] = 0;
|
||||
strcpy (bman.playername, value);
|
||||
}
|
||||
|
||||
if (!strcmp (keyword, "gamename")) {
|
||||
if (strlen (value) > LEN_GAMENAME) {
|
||||
d_printf
|
||||
("*** Error - servername too long (maximum size permitted is %d characters)!\n\n",
|
||||
LEN_GAMENAME);
|
||||
}
|
||||
value[LEN_GAMENAME - 1] = 0;
|
||||
strcpy (bman.gamename, value);
|
||||
}
|
||||
|
||||
if (!strcmp (keyword, "askplayername")) {
|
||||
bman.askplayername = atoi (value);
|
||||
}
|
||||
if (!strcmp (keyword, "resolutionx")) {
|
||||
gfx.res.x = atoi (value);
|
||||
}
|
||||
if (!strcmp (keyword, "resolutiony")) {
|
||||
gfx.res.y = atoi (value);
|
||||
}
|
||||
if (!strcmp (keyword, "fieldpath")) {
|
||||
if (strlen (value) > 510) {
|
||||
d_printf
|
||||
("*** Error - fieldpath too long (maximum size permitted is %d characters)!\n\n",
|
||||
510);
|
||||
}
|
||||
value[511] = 0;
|
||||
strcpy(bman.fieldpath,value);
|
||||
}
|
||||
if (!strcmp (keyword, "fieldsizex")) {
|
||||
bman.fieldsize.x = atoi (value);
|
||||
}
|
||||
if (!strcmp (keyword, "fieldsizey")) {
|
||||
bman.fieldsize.y = atoi (value);
|
||||
}
|
||||
if (!strcmp (keyword, "fullscreen")) {
|
||||
gfx.fullscreen = atoi (value);
|
||||
}
|
||||
if (!strcmp (keyword, "bitsperpixel")) {
|
||||
gfx.bpp = atoi (value);
|
||||
}
|
||||
if (!strcmp (keyword, "ai_family")) {
|
||||
bman.net_ai_family = atoi (value);
|
||||
}
|
||||
if (!strcmp (keyword, "debug")) {
|
||||
debug = atoi (value);
|
||||
}
|
||||
if (!strcmp (keyword, "notify")) {
|
||||
bman.notifygamemaster = atoi (value);
|
||||
}
|
||||
if (!strcmp (keyword, "masterserver")) {
|
||||
strcpy (bman.gamemaster, value);
|
||||
}
|
||||
if (!strcmp (keyword, "maxplayer")) {
|
||||
bman.maxplayer = atoi (value);
|
||||
}
|
||||
for (i = 0; i < MAX_SERVERENTRYS; i++) {
|
||||
sprintf (key2, "ip%d", i);
|
||||
if (!strcmp (keyword, key2)) {
|
||||
strcpy (bman.serverlist[i].name, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
fclose (config);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
WriteConfig ()
|
||||
{
|
||||
FILE *config;
|
||||
int i;
|
||||
char filename[512];
|
||||
#ifdef _WIN32
|
||||
sprintf (filename, "%sbomberclone.cfg", s_gethomedir ());
|
||||
#else
|
||||
sprintf (filename, "%s.bomberclone.cfg", s_gethomedir ());
|
||||
#endif
|
||||
if ((config = fopen (filename, "w")) == NULL)
|
||||
return -1;
|
||||
fprintf (config, "resolutionx=%d\n", gfx.res.x);
|
||||
fprintf (config, "resolutiony=%d\n", gfx.res.y);
|
||||
fprintf (config, "fullscreen=%d\n", gfx.fullscreen);
|
||||
fprintf (config, "fieldpath=%s\n", bman.fieldpath);
|
||||
fprintf (config, "fieldsizex=%d\n", bman.fieldsize.x);
|
||||
fprintf (config, "fieldsizey=%d\n", bman.fieldsize.y);
|
||||
fprintf (config, "notify=%d\n", bman.notifygamemaster);
|
||||
fprintf (config, "ai_family=%d\n", bman.net_ai_family);
|
||||
fprintf (config, "masterserver=%s\n", bman.gamemaster);
|
||||
fprintf (config, "gamename=%s\n", bman.gamename);
|
||||
fprintf (config, "maxplayer=%d\n", bman.maxplayer);
|
||||
for (i = 0; i < MAX_SERVERENTRYS; i++)
|
||||
fprintf (config, "ip%d=%s\n", i, bman.serverlist[i].name);
|
||||
fprintf (config, "debug=%d\n", debug);
|
||||
fprintf (config, "askplayername=%d\n", bman.askplayername);
|
||||
fprintf (config, "playername=%s\n", bman.playername);
|
||||
fprintf (config, "bitsperpixel=%d\n", gfx.bpp);
|
||||
|
||||
fclose (config);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
change_res ()
|
||||
{
|
||||
int menuselect = 0;
|
||||
_menu menu[] = {
|
||||
{0, "Full Screen"},
|
||||
{1, "640x480"},
|
||||
{2, "800x600"},
|
||||
{3, "1024x768"},
|
||||
{4, "1280x1024"},
|
||||
{5, "BPP"},
|
||||
{6, "Return To Configuration Menu"},
|
||||
{-1, ""}
|
||||
};
|
||||
while (1) {
|
||||
if (gfx.fullscreen)
|
||||
sprintf (menu[0].text, "Disable Fullscreen");
|
||||
else
|
||||
sprintf (menu[0].text, "Enable Full Screen");
|
||||
|
||||
if (gfx.bpp == 16)
|
||||
sprintf (menu[5].text, "16 Bit Per Pixel");
|
||||
else if (gfx.bpp == 24)
|
||||
sprintf (menu[5].text, "24 Bit Per Pixel");
|
||||
else
|
||||
sprintf (menu[5].text, "32 Bit Per Pixel");
|
||||
|
||||
menuselect = menu_loop ("Video Options", menu, menuselect);
|
||||
|
||||
switch (menuselect) {
|
||||
case (0): // Fullscreen
|
||||
if (gfx.fullscreen)
|
||||
gfx.fullscreen = 0;
|
||||
else
|
||||
gfx.fullscreen = 1;
|
||||
break;
|
||||
|
||||
case (1): // 640x480
|
||||
gfx.res.x = 640;
|
||||
gfx.res.y = 480;
|
||||
break;
|
||||
case (2): // 800x600
|
||||
gfx.res.x = 800;
|
||||
gfx.res.y = 600;
|
||||
break;
|
||||
case (3): // 1024x768
|
||||
gfx.res.x = 1024;
|
||||
gfx.res.y = 768;
|
||||
break;
|
||||
case (4): // 1280x1024
|
||||
gfx.res.x = 1280;
|
||||
gfx.res.y = 1024;
|
||||
break;
|
||||
case (5):
|
||||
if (gfx.bpp == 16)
|
||||
gfx.bpp = 24;
|
||||
else if (gfx.bpp == 24)
|
||||
gfx.bpp = 32;
|
||||
else
|
||||
gfx.bpp = 16;
|
||||
break;
|
||||
case (6): // Return
|
||||
menuselect = -1;
|
||||
break;
|
||||
}
|
||||
if (menuselect != -1) {
|
||||
gfx_shutdown ();
|
||||
gfx_init ();
|
||||
}
|
||||
else
|
||||
return;
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void
|
||||
configuration ()
|
||||
{
|
||||
int menuselect = 0;
|
||||
|
||||
_menu menu[] = {
|
||||
{0, "Player Name:"},
|
||||
{1, "Video Options"},
|
||||
{2, "Sound Options"},
|
||||
{3, "Map Options"},
|
||||
{4, "Customize Keyboard"},
|
||||
{5, "Prompt For Player Name"},
|
||||
{6, "Debug"},
|
||||
{7, "Save Config"},
|
||||
{8, "Return To Main Manu"},
|
||||
{-1, ""}
|
||||
};
|
||||
|
||||
while (menuselect != -1) {
|
||||
|
||||
sprintf (menu[0].text, "Player Name: %s", bman.playername);
|
||||
|
||||
if (bman.askplayername == 1)
|
||||
sprintf (menu[5].text, "Prompt For Name: YES");
|
||||
else
|
||||
sprintf (menu[5].text, "Prompt For Name: NO");
|
||||
|
||||
if (debug == 1)
|
||||
sprintf (menu[6].text, "Debug Messages ON");
|
||||
else
|
||||
sprintf (menu[6].text, "Debug Messages OFF");
|
||||
|
||||
|
||||
menuselect = menu_loop ("Configuration", menu, menuselect);
|
||||
|
||||
|
||||
switch (menuselect) {
|
||||
case (0): // Playername
|
||||
menu_get_text ("Enter Playername", bman.playername, LEN_PLAYERNAME - 1);
|
||||
bman.playername[LEN_PLAYERNAME - 1] = 0;
|
||||
break;
|
||||
|
||||
case (1): // Screen Options
|
||||
change_res ();
|
||||
break;
|
||||
|
||||
case (2): // Sound Options
|
||||
break;
|
||||
|
||||
case (3): // Map Options
|
||||
mapmenu();
|
||||
break;
|
||||
|
||||
case (4): // Customize Keyboard
|
||||
break;
|
||||
|
||||
case (5): // Prompt For Player Name
|
||||
if (bman.askplayername == 1)
|
||||
bman.askplayername = 0;
|
||||
else
|
||||
bman.askplayername = 1;
|
||||
break;
|
||||
|
||||
case (6): // Debugging On / Off
|
||||
if (debug == 1)
|
||||
debug = 0;
|
||||
else {
|
||||
debug = 1;
|
||||
d_printf ("BomberClone ver.%s\n", VERSION);
|
||||
}
|
||||
break;
|
||||
|
||||
case (7): // Save Configuration
|
||||
WriteConfig ();
|
||||
break;
|
||||
|
||||
case (8): // Return to main menu
|
||||
menuselect = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
void
|
||||
ReadPrgArgs (int argc, char **argv)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
while (argv[++i] != NULL) {
|
||||
if (!strcmp (argv[i], "-port"))
|
||||
strncpy (bman.port, argv[++i], LEN_PORT);
|
||||
}
|
||||
};
|
||||
|
@ -1,39 +1,39 @@
|
||||
|
||||
#include "bomberclone.h"
|
||||
#include "network.h"
|
||||
#include "packets.h"
|
||||
|
||||
int debug;
|
||||
|
||||
void d_gamedetail (char *head) {
|
||||
d_playerdetail (head);
|
||||
|
||||
d_printf ("bman.players_nr = %d\n", bman.players_nr);
|
||||
d_printf ("bman.players_nr_s = %d\n", bman.players_nr_s);
|
||||
d_printf ("bman.gametype = %d\n", bman.gametype);
|
||||
d_printf ("bman.multitype = %d\n", bman.multitype);
|
||||
d_printf ("bman.state = %d\n", bman.state);
|
||||
};
|
||||
|
||||
|
||||
void d_printf (char *fmt,...) {
|
||||
va_list args;
|
||||
|
||||
if (debug == 0)
|
||||
return;
|
||||
|
||||
va_start (args, fmt);
|
||||
fprintf (stdout, "[%8d] :", timestamp);
|
||||
vfprintf (stdout, fmt, args);
|
||||
va_end (args);
|
||||
};
|
||||
|
||||
|
||||
void d_playerdetail (char *head) {
|
||||
int i;
|
||||
|
||||
d_printf ("---------------> %s\n", head);
|
||||
d_printf ("Nr Name GFX Sta Pkt Win [Addr]\n");
|
||||
for (i = 0; i < MAX_PLAYERS; i++)
|
||||
d_printf ("%2d %16s %3d %3d %3d %3d [%s:%s]\n",i, bman.players[i].name, bman.players[i].gfx_nr, bman.players[i].state, bman.players[i].points, bman.players[i].wins, bman.players[i].net.addr.host, bman.players[i].net.addr.port);
|
||||
};
|
||||
|
||||
#include "bomberclone.h"
|
||||
#include "network.h"
|
||||
#include "packets.h"
|
||||
|
||||
int debug;
|
||||
|
||||
void d_gamedetail (char *head) {
|
||||
d_playerdetail (head);
|
||||
|
||||
d_printf ("bman.players_nr = %d\n", bman.players_nr);
|
||||
d_printf ("bman.players_nr_s = %d\n", bman.players_nr_s);
|
||||
d_printf ("bman.gametype = %d\n", bman.gametype);
|
||||
d_printf ("bman.multitype = %d\n", bman.multitype);
|
||||
d_printf ("bman.state = %d\n", bman.state);
|
||||
};
|
||||
|
||||
|
||||
void d_printf (char *fmt,...) {
|
||||
va_list args;
|
||||
|
||||
if (debug == 0)
|
||||
return;
|
||||
|
||||
va_start (args, fmt);
|
||||
fprintf (stdout, "[%8d] :", timestamp);
|
||||
vfprintf (stdout, fmt, args);
|
||||
va_end (args);
|
||||
};
|
||||
|
||||
|
||||
void d_playerdetail (char *head) {
|
||||
int i;
|
||||
|
||||
d_printf ("---------------> %s\n", head);
|
||||
d_printf ("Nr Name GFX Sta Pkt Win [Addr]\n");
|
||||
for (i = 0; i < MAX_PLAYERS; i++)
|
||||
d_printf ("%2d %16s %3d %3d %3d %3d [%s:%s]\n",i, bman.players[i].name, bman.players[i].gfx_nr, bman.players[i].state, bman.players[i].points, bman.players[i].wins, bman.players[i].net.addr.host, bman.players[i].net.addr.port);
|
||||
};
|
||||
|
@ -1,402 +1,384 @@
|
||||
/* $Id: field.c,v 1.13 2003/05/07 00:21:05 stpohle Exp $ */
|
||||
/* field.c - procedures which are needed to control the field */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <SDL.h>
|
||||
|
||||
#include "bomberclone.h"
|
||||
#include "gfx.h"
|
||||
|
||||
void
|
||||
draw_stone (int x, int y)
|
||||
{
|
||||
_field *stone = &bman.field[x][y];
|
||||
SDL_Rect dest,
|
||||
src;
|
||||
SDL_Surface *srcimg;
|
||||
int i,
|
||||
d;
|
||||
|
||||
src.w = dest.w = gfx.block.x;
|
||||
src.h = dest.h = gfx.block.y;
|
||||
|
||||
dest.x = x * gfx.block.x + gfx.offset.x;
|
||||
dest.y = y * gfx.block.y + gfx.offset.y;
|
||||
|
||||
src.x = 0;
|
||||
|
||||
if (stone->frame == 0 || stone->type != FT_stone) {
|
||||
srcimg = gfx.field[stone->type].image;
|
||||
src.y = 0;
|
||||
}
|
||||
else {
|
||||
if (stone->frameto == 0) {
|
||||
if (stone->frame < gfx.field[stone->type].frames) {
|
||||
stone->frame++;
|
||||
stone->frameto = ANI_STONETIMEOUT;
|
||||
}
|
||||
}
|
||||
if (stone->frameto > 0)
|
||||
stone->frameto--;
|
||||
if (stone->frame < gfx.field[stone->type].frames) {
|
||||
src.y = stone->frame * gfx.block.y;
|
||||
srcimg = gfx.field[stone->type].image;
|
||||
}
|
||||
else {
|
||||
src.y = 0;
|
||||
srcimg = gfx.field[FT_nothing].image;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (stone->frame > 0)
|
||||
SDL_BlitSurface (gfx.field[FT_nothing].image, NULL, gfx.screen, &dest);
|
||||
|
||||
SDL_BlitSurface (srcimg, &src, gfx.screen, &dest);
|
||||
|
||||
// draw explosions if there is any
|
||||
for (d = 0, i = 0; d < 4; d++)
|
||||
if (stone->ex[d].count > 0) {
|
||||
i = 1; // mark that there is already an explosion
|
||||
draw_fire (x, y, d, -1);
|
||||
}
|
||||
|
||||
if (i == 0) // we don't have to do this anymore because this was happend in draw_fire
|
||||
gfx_AddUpdateRect (dest.x, dest.y, dest.w, dest.h);
|
||||
|
||||
return;
|
||||
};
|
||||
|
||||
|
||||
void
|
||||
draw_field ()
|
||||
{
|
||||
int x,
|
||||
y;
|
||||
|
||||
for (x = 0; x < bman.fieldsize.x; x++)
|
||||
for (y = 0; y < bman.fieldsize.y; y++)
|
||||
draw_stone (x, y);
|
||||
};
|
||||
|
||||
/* read from an open file map, determine field.x and field.y
|
||||
and fill the field.
|
||||
(# correspond to a bloc and @ correspond to a stone,
|
||||
an espace is nothing ' '
|
||||
% are commentary at the beginning of the map */
|
||||
void
|
||||
field_load (FILE * map)
|
||||
{
|
||||
size_t length;
|
||||
char *currentline;
|
||||
char tmp[MAX_FIELDSIZE_X];
|
||||
int sizex = 0;
|
||||
int sizey = 0;
|
||||
int i;
|
||||
int d;
|
||||
|
||||
while ((currentline = fgets (tmp, MAX_FIELDSIZE_X, map))) {
|
||||
length = strlen (currentline);
|
||||
if (currentline[0] == '%')
|
||||
continue;
|
||||
/* now each line correspond to the field */
|
||||
else {
|
||||
for (i = 0; i < length; i++) {
|
||||
switch (currentline[i]) {
|
||||
case '#':
|
||||
bman.field[i][sizey].type = FT_block;
|
||||
break;
|
||||
case '@':
|
||||
bman.field[i][sizey].type = FT_stone;
|
||||
break;
|
||||
case ' ':
|
||||
bman.field[i][sizey].type = FT_nothing;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
for (d = 0; d < 4; d++)
|
||||
bman.field[i][sizey].ex[d].frame = bman.field[i][sizey].ex[d].count = 0;
|
||||
bman.field[i][sizey].ex_nr = -1;
|
||||
bman.field[i][sizey].frame = 0;
|
||||
bman.field[i][sizey].frameto = 0;
|
||||
bman.field[i][sizey].special = FT_nothing;
|
||||
}
|
||||
sizey++;
|
||||
if (sizex < length)
|
||||
sizex = length;
|
||||
}
|
||||
}
|
||||
|
||||
bman.fieldsize.x = sizex - 1;
|
||||
bman.fieldsize.y = sizey;
|
||||
|
||||
/* darw the border so we know everything is right */
|
||||
for (i = 0; i < bman.fieldsize.x; i++)
|
||||
bman.field[i][0].type = bman.field[i][bman.fieldsize.y-1].type = FT_block;
|
||||
for (i = 0; i < bman.fieldsize.y; i++)
|
||||
bman.field[0][i].type = bman.field[bman.fieldsize.x-1][i].type = FT_block;
|
||||
}
|
||||
|
||||
/* will set the playerposition but in a way that we won't start on a block */
|
||||
/* i am just too lazy to write this all again and again */
|
||||
#define PLX bman.players[i].pos.x
|
||||
#define PLY bman.players[i].pos.y
|
||||
void field_set_playerposition (int usermap) {
|
||||
int p, dist, i,j , mx, my, dx = 0, dy = 0;
|
||||
char txt[255];
|
||||
|
||||
p = 50;
|
||||
dist = 8;
|
||||
while (p == 50) {
|
||||
p = 0;
|
||||
dist--;
|
||||
for (i = 0; (p < 50 && i < MAX_PLAYERS);) {
|
||||
if (usermap) {
|
||||
int maxloop = 0;
|
||||
while (maxloop < 200 && (PLX == -1 || PLY == -1)) {
|
||||
maxloop++;
|
||||
PLX = s_random (bman.fieldsize.x - 2) + 1;
|
||||
PLY = s_random (bman.fieldsize.y - 2) + 1;
|
||||
|
||||
for (dx = 10, dy = 10, j = 0; (j < i && j < MAX_PLAYERS && (dx > 1 || dy > 1)); j++) { /* is ther any other player */
|
||||
dx = PLX - bman.players[j].pos.x;
|
||||
if (dx < 0) dx = - dx;
|
||||
dy = PLY - bman.players[j].pos.y;
|
||||
if (dy < 0) dy = - dy;
|
||||
}
|
||||
|
||||
/* check if there is no block */
|
||||
if ((dx > 1 || dy > 1) && ((bman.field[PLX][PLY].type != FT_block && maxloop > 100) ||
|
||||
bman.field[PLX][PLY].type == FT_nothing)) {
|
||||
/* get (up or down) dx and (left or right) dy */
|
||||
dx = s_random (2);
|
||||
if (dx == 0)
|
||||
dx = -1;
|
||||
dy = s_random (2);
|
||||
if (dy == 0)
|
||||
dy = -1;
|
||||
|
||||
/* first check if there is and free place for us */
|
||||
if (!((bman.field[PLX+dx][PLY].type != FT_block && maxloop > 100) ||
|
||||
bman.field[PLX+dx][PLY].type == FT_nothing))
|
||||
dx = -dx;
|
||||
if (!((bman.field[PLX+dx][PLY].type != FT_block && maxloop > 100) ||
|
||||
bman.field[PLX+dx][PLY].type == FT_nothing))
|
||||
PLX = -1;
|
||||
|
||||
if (!((bman.field[PLX][PLY+dy].type != FT_block && maxloop > 100) ||
|
||||
bman.field[PLX][PLY+dy].type == FT_nothing))
|
||||
dy = -dy;
|
||||
if (!((bman.field[PLX][PLY+dy].type != FT_block && maxloop > 100) ||
|
||||
bman.field[PLX][PLY+dy].type == FT_nothing))
|
||||
PLY = -1;
|
||||
}
|
||||
else {
|
||||
PLX = -1;
|
||||
PLY = -1;
|
||||
}
|
||||
|
||||
/* make some space */
|
||||
if (PLX != -1 && PLY != -1) {
|
||||
bman.field[PLX][PLY].type = FT_nothing;
|
||||
bman.field[PLX+dx][PLY].type = FT_nothing;
|
||||
bman.field[PLX][PLY+dy].type = FT_nothing;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (PLX == -1 || PLY == -1) {
|
||||
/* we could not set all fields or we don't run on a usermap */
|
||||
if (usermap) {
|
||||
sprintf (txt,"Not all players could be set (Pl:%d)", i);
|
||||
menu_displaymessage ("MAP - ERROR",txt);
|
||||
}
|
||||
|
||||
/* now there will be some fields deleted */
|
||||
PLX = 2 * (s_random ((bman.fieldsize.x - 1) / 2)) + 1;
|
||||
PLY = 2 * (s_random ((bman.fieldsize.y - 1) / 2)) + 1;
|
||||
|
||||
bman.field[PLX][PLY].type = FT_nothing;
|
||||
|
||||
dx = s_random (4); // bit 1 = up/down bit 2 = left/right
|
||||
/* up and down */
|
||||
if (((dx & 1) == 0 && PLX > 1) || PLX >= bman.fieldsize.x - 2)
|
||||
bman.field[PLX-1][PLY].type = FT_nothing;
|
||||
else
|
||||
bman.field[PLX+1][PLY].type = FT_nothing;
|
||||
/* left and right */
|
||||
if (((dx & 2) == 0 && PLY > 1) || PLY >= bman.fieldsize.y - 2)
|
||||
bman.field[PLX][PLY-1].type = FT_nothing;
|
||||
else
|
||||
bman.field[PLX][PLY+1].type = FT_nothing;
|
||||
}
|
||||
mx = my = 100;
|
||||
for (j = 0; j <= i; j++) { /* search smalest distance */
|
||||
dy = PLY - bman.players[j].pos.y;
|
||||
dx = PLX - bman.players[j].pos.x;
|
||||
if (dy < 0)
|
||||
dy = -dy;
|
||||
if (dx < 0)
|
||||
dx = -dx;
|
||||
|
||||
if (mx > dx && i != j)
|
||||
mx = dx;
|
||||
if (my > dy && i != j)
|
||||
my = dy;
|
||||
}
|
||||
|
||||
if (mx > dist || my > dist)
|
||||
i++;
|
||||
else
|
||||
p++;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < MAX_PLAYERS; i++) {
|
||||
PLX = PLX << 8;
|
||||
PLY = PLY << 8;
|
||||
}
|
||||
};
|
||||
#undef PLX
|
||||
#undef PLY
|
||||
|
||||
|
||||
void
|
||||
field_new (char *filename)
|
||||
{
|
||||
int x,
|
||||
y,
|
||||
d;
|
||||
FILE *fmap;
|
||||
float fkt;
|
||||
int nb_try;
|
||||
fmap = fopen (filename, "r");
|
||||
|
||||
/* if we can't open the given filename for any reason, reverting
|
||||
to default value else, load the file */
|
||||
if (fmap)
|
||||
field_load (fmap);
|
||||
|
||||
/* this is the item factor we multiply it with this so we know
|
||||
how much items we want in the game */
|
||||
fkt = ((float)(bman.fieldsize.x * bman.fieldsize.y))/(25.0 * 17.0);
|
||||
|
||||
// Clean and create the field //
|
||||
if (fmap == NULL) {
|
||||
/* if we can't load the map check first the fieldsize settings */
|
||||
if (bman.fieldsize.x < MIN_FIELDSIZE_X)
|
||||
bman.fieldsize.x = MIN_FIELDSIZE_X;
|
||||
if (bman.fieldsize.x > MAX_FIELDSIZE_X)
|
||||
bman.fieldsize.x = MAX_FIELDSIZE_X;
|
||||
|
||||
for (x = 0; x < bman.fieldsize.x; x++)
|
||||
for (y = 0; y < bman.fieldsize.y; y++) {
|
||||
if ((y == 0) || (y == bman.fieldsize.y - 1))
|
||||
bman.field[x][y].type = FT_block;
|
||||
else if ((x == 0) || (x == bman.fieldsize.x - 1))
|
||||
bman.field[x][y].type = FT_block;
|
||||
else if (((x & 1) == 0) && ((y & 1) == 0))
|
||||
bman.field[x][y].type = FT_block;
|
||||
else {
|
||||
// create random field
|
||||
if ((s_random (256) & 3) == 0)
|
||||
bman.field[x][y].type = FT_nothing;
|
||||
else
|
||||
bman.field[x][y].type = FT_stone;
|
||||
}
|
||||
|
||||
for (d = 0; d < 4; d++)
|
||||
bman.field[x][y].ex[d].frame = bman.field[x][y].ex[d].count = 0;
|
||||
bman.field[x][y].ex_nr = -1;
|
||||
bman.field[x][y].frame = 0;
|
||||
bman.field[x][y].frameto = 0;
|
||||
bman.field[x][y].special = FT_nothing;
|
||||
}
|
||||
}
|
||||
|
||||
/* Set the Playerinformation */
|
||||
field_set_playerposition (fmap != NULL);
|
||||
|
||||
nb_try = 100; // to prevent infinite loops (maybe there are no stones)
|
||||
/* put the fire powerups in the field */
|
||||
for (d = 0, x = 0, y = 0; d < GAME_SPECIAL_ITEMFIRE * fkt; d++) {
|
||||
while (bman.field[x][y].type != FT_stone || bman.field[x][y].special != FT_nothing) {
|
||||
x = ((float) rand () / (float) RAND_MAX) * (bman.fieldsize.x - 1);
|
||||
y = ((float) rand () / (float) RAND_MAX) * (bman.fieldsize.y - 1);
|
||||
nb_try--;
|
||||
if (nb_try < 0)
|
||||
break;
|
||||
}
|
||||
bman.field[x][y].special = FT_fire;
|
||||
x = y = 0;
|
||||
}
|
||||
|
||||
nb_try = 100;
|
||||
/* put the bomb powerups in the field */
|
||||
for (d = 0, x = 0, y = 0; d < GAME_SPECIAL_ITEMBOMB * fkt; d++) {
|
||||
while (bman.field[x][y].type != FT_stone || bman.field[x][y].special != FT_nothing) {
|
||||
x = ((float) rand () / (float) RAND_MAX) * (bman.fieldsize.x - 1);
|
||||
y = ((float) rand () / (float) RAND_MAX) * (bman.fieldsize.y - 1);
|
||||
nb_try--;
|
||||
if (nb_try < 0)
|
||||
break;
|
||||
}
|
||||
bman.field[x][y].special = FT_bomb;
|
||||
x = y = 0;
|
||||
}
|
||||
|
||||
nb_try = 100;
|
||||
/* put the shoe powerup in the field */
|
||||
for (d = 0, x = 0, y = 0; d < GAME_SPECIAL_ITEMSHOE * fkt; d++) {
|
||||
while (bman.field[x][y].type != FT_stone || bman.field[x][y].special != FT_nothing) {
|
||||
x = ((float) rand () / (float) RAND_MAX) * (bman.fieldsize.x - 1);
|
||||
y = ((float) rand () / (float) RAND_MAX) * (bman.fieldsize.y - 1);
|
||||
nb_try--;
|
||||
if (nb_try < 0)
|
||||
break;
|
||||
}
|
||||
bman.field[x][y].special = FT_shoe;
|
||||
x = y = 0;
|
||||
}
|
||||
|
||||
nb_try = 100;
|
||||
/* put the death ?powerups? in the field */
|
||||
for (d = 0, x = 0, y = 0; d < GAME_SPECIAL_ITEMDEATH * fkt; d++) {
|
||||
while (bman.field[x][y].type != FT_stone || bman.field[x][y].special != FT_nothing) {
|
||||
x = ((float) rand () / (float) RAND_MAX) * (bman.fieldsize.x - 1);
|
||||
y = ((float) rand () / (float) RAND_MAX) * (bman.fieldsize.y - 1);
|
||||
nb_try--;
|
||||
if (nb_try < 0)
|
||||
break;
|
||||
}
|
||||
bman.field[x][y].special = FT_death;
|
||||
x = y = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* load a random tileset */
|
||||
void
|
||||
tileset_random () {
|
||||
_direntry *destart, *de, *desel;
|
||||
char path[LEN_PATHFILENAME];
|
||||
int max, sel;
|
||||
|
||||
sprintf (path, "%s/tileset", bman.datapath);
|
||||
desel = destart = s_getdir (path);
|
||||
|
||||
for (max = 0, de = destart; de != NULL; de = de->next)
|
||||
if (de->name[0] != '.' && (de->flags & DF_dir) == DF_dir)
|
||||
max++;
|
||||
|
||||
sel = s_random (max);
|
||||
for (max = 0, de = destart; max <= sel && de != NULL; de = de->next)
|
||||
if (de->name[0] != '.' && (de->flags & DF_dir) == DF_dir) {
|
||||
desel = de;
|
||||
max++;
|
||||
}
|
||||
|
||||
d_printf ("Random Tileset %s (%d)\n", desel->name, sel, max);
|
||||
|
||||
if (desel != NULL)
|
||||
strncpy (gfx.tileset, desel->name, LEN_TILESETNAME);
|
||||
gfx.tileset[LEN_TILESETNAME-1] = 0;
|
||||
}
|
||||
/* $Id: field.c,v 1.14 2003/05/07 21:28:12 stpohle Exp $ */
|
||||
/* field.c - procedures which are needed to control the field */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <SDL.h>
|
||||
|
||||
#include "bomberclone.h"
|
||||
#include "gfx.h"
|
||||
|
||||
void
|
||||
draw_stone (int x, int y)
|
||||
{
|
||||
_field *stone = &bman.field[x][y];
|
||||
SDL_Rect dest,
|
||||
src;
|
||||
SDL_Surface *srcimg;
|
||||
int i,
|
||||
d;
|
||||
|
||||
src.w = dest.w = gfx.block.x;
|
||||
src.h = dest.h = gfx.block.y;
|
||||
|
||||
dest.x = x * gfx.block.x + gfx.offset.x;
|
||||
dest.y = y * gfx.block.y + gfx.offset.y;
|
||||
|
||||
src.x = 0;
|
||||
|
||||
if (stone->frame == 0 || stone->type != FT_stone) {
|
||||
srcimg = gfx.field[stone->type].image;
|
||||
src.y = 0;
|
||||
}
|
||||
else {
|
||||
if (stone->frameto == 0) {
|
||||
if (stone->frame < gfx.field[stone->type].frames) {
|
||||
stone->frame++;
|
||||
stone->frameto = ANI_STONETIMEOUT;
|
||||
}
|
||||
}
|
||||
if (stone->frameto > 0)
|
||||
stone->frameto--;
|
||||
if (stone->frame < gfx.field[stone->type].frames) {
|
||||
src.y = stone->frame * gfx.block.y;
|
||||
srcimg = gfx.field[stone->type].image;
|
||||
}
|
||||
else {
|
||||
src.y = 0;
|
||||
srcimg = gfx.field[FT_nothing].image;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (stone->frame > 0)
|
||||
SDL_BlitSurface (gfx.field[FT_nothing].image, NULL, gfx.screen, &dest);
|
||||
|
||||
SDL_BlitSurface (srcimg, &src, gfx.screen, &dest);
|
||||
|
||||
// draw explosions if there is any
|
||||
for (d = 0, i = 0; d < 4; d++)
|
||||
if (stone->ex[d].count > 0) {
|
||||
i = 1; // mark that there is already an explosion
|
||||
draw_fire (x, y, d, -1);
|
||||
}
|
||||
|
||||
if (i == 0) // we don't have to do this anymore because this was happend in draw_fire
|
||||
gfx_AddUpdateRect (dest.x, dest.y, dest.w, dest.h);
|
||||
|
||||
return;
|
||||
};
|
||||
|
||||
|
||||
void
|
||||
draw_field ()
|
||||
{
|
||||
int x,
|
||||
y;
|
||||
|
||||
for (x = 0; x < bman.fieldsize.x; x++)
|
||||
for (y = 0; y < bman.fieldsize.y; y++)
|
||||
draw_stone (x, y);
|
||||
};
|
||||
|
||||
/* read from an open file map, determine field.x and field.y
|
||||
and fill the field.
|
||||
(# correspond to a bloc and @ correspond to a stone,
|
||||
an espace is nothing ' '
|
||||
% are commentary at the beginning of the map */
|
||||
void
|
||||
field_load (FILE * map)
|
||||
{
|
||||
size_t length;
|
||||
char *currentline;
|
||||
char tmp[MAX_FIELDSIZE_X];
|
||||
int sizex = 0;
|
||||
int sizey = 0;
|
||||
int i;
|
||||
int d;
|
||||
|
||||
while ((currentline = fgets (tmp, MAX_FIELDSIZE_X, map))) {
|
||||
length = strlen (currentline);
|
||||
if (currentline[0] == '%')
|
||||
continue;
|
||||
/* now each line correspond to the field */
|
||||
else {
|
||||
for (i = 0; i < length; i++) {
|
||||
switch (currentline[i]) {
|
||||
case '#':
|
||||
bman.field[i][sizey].type = FT_block;
|
||||
break;
|
||||
case '@':
|
||||
bman.field[i][sizey].type = FT_stone;
|
||||
break;
|
||||
case ' ':
|
||||
bman.field[i][sizey].type = FT_nothing;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
for (d = 0; d < 4; d++)
|
||||
bman.field[i][sizey].ex[d].frame = bman.field[i][sizey].ex[d].count = 0;
|
||||
bman.field[i][sizey].ex_nr = -1;
|
||||
bman.field[i][sizey].frame = 0;
|
||||
bman.field[i][sizey].frameto = 0;
|
||||
bman.field[i][sizey].special = FT_nothing;
|
||||
}
|
||||
sizey++;
|
||||
if (sizex < length)
|
||||
sizex = length;
|
||||
}
|
||||
}
|
||||
|
||||
bman.fieldsize.x = sizex - 1;
|
||||
bman.fieldsize.y = sizey;
|
||||
|
||||
/* darw the border so we know everything is right */
|
||||
for (i = 0; i < bman.fieldsize.x; i++)
|
||||
bman.field[i][0].type = bman.field[i][bman.fieldsize.y-1].type = FT_block;
|
||||
for (i = 0; i < bman.fieldsize.y; i++)
|
||||
bman.field[0][i].type = bman.field[bman.fieldsize.x-1][i].type = FT_block;
|
||||
}
|
||||
|
||||
/* will set the playerposition but in a way that we won't start on a block */
|
||||
/* i am just too lazy to write this all again and again */
|
||||
#define PLX bman.players[i].pos.x
|
||||
#define PLY bman.players[i].pos.y
|
||||
void field_set_playerposition (int usermap) {
|
||||
int p, dist, i,j , mx, my, dx = 0, dy = 0;
|
||||
char txt[255];
|
||||
|
||||
p = 50;
|
||||
dist = 8;
|
||||
while (p == 50) {
|
||||
p = 0;
|
||||
dist--;
|
||||
for (i = 0; (p < 50 && i < MAX_PLAYERS);) {
|
||||
if (usermap) {
|
||||
int maxloop = 0;
|
||||
while (maxloop < 200 && (PLX == -1 || PLY == -1)) {
|
||||
maxloop++;
|
||||
PLX = s_random (bman.fieldsize.x - 2) + 1;
|
||||
PLY = s_random (bman.fieldsize.y - 2) + 1;
|
||||
|
||||
for (dx = 10, dy = 10, j = 0; (j < i && j < MAX_PLAYERS && (dx > 1 || dy > 1)); j++) { /* is ther any other player */
|
||||
dx = PLX - bman.players[j].pos.x;
|
||||
if (dx < 0) dx = - dx;
|
||||
dy = PLY - bman.players[j].pos.y;
|
||||
if (dy < 0) dy = - dy;
|
||||
}
|
||||
|
||||
/* check if there is no block */
|
||||
if ((dx > 1 || dy > 1) && ((bman.field[PLX][PLY].type != FT_block && maxloop > 100) ||
|
||||
bman.field[PLX][PLY].type == FT_nothing)) {
|
||||
/* get (up or down) dx and (left or right) dy */
|
||||
dx = s_random (2);
|
||||
if (dx == 0)
|
||||
dx = -1;
|
||||
dy = s_random (2);
|
||||
if (dy == 0)
|
||||
dy = -1;
|
||||
|
||||
/* first check if there is and free place for us */
|
||||
if (!((bman.field[PLX+dx][PLY].type != FT_block && maxloop > 100) ||
|
||||
bman.field[PLX+dx][PLY].type == FT_nothing))
|
||||
dx = -dx;
|
||||
if (!((bman.field[PLX+dx][PLY].type != FT_block && maxloop > 100) ||
|
||||
bman.field[PLX+dx][PLY].type == FT_nothing))
|
||||
PLX = -1;
|
||||
|
||||
if (!((bman.field[PLX][PLY+dy].type != FT_block && maxloop > 100) ||
|
||||
bman.field[PLX][PLY+dy].type == FT_nothing))
|
||||
dy = -dy;
|
||||
if (!((bman.field[PLX][PLY+dy].type != FT_block && maxloop > 100) ||
|
||||
bman.field[PLX][PLY+dy].type == FT_nothing))
|
||||
PLY = -1;
|
||||
}
|
||||
else {
|
||||
PLX = -1;
|
||||
PLY = -1;
|
||||
}
|
||||
|
||||
/* make some space */
|
||||
if (PLX != -1 && PLY != -1) {
|
||||
bman.field[PLX][PLY].type = FT_nothing;
|
||||
bman.field[PLX+dx][PLY].type = FT_nothing;
|
||||
bman.field[PLX][PLY+dy].type = FT_nothing;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (PLX == -1 || PLY == -1) {
|
||||
/* we could not set all fields or we don't run on a usermap */
|
||||
if (usermap) {
|
||||
sprintf (txt,"Not all players could be set (Pl:%d)", i);
|
||||
menu_displaymessage ("MAP - ERROR",txt);
|
||||
}
|
||||
|
||||
/* now there will be some fields deleted */
|
||||
PLX = 2 * (s_random ((bman.fieldsize.x - 1) / 2)) + 1;
|
||||
PLY = 2 * (s_random ((bman.fieldsize.y - 1) / 2)) + 1;
|
||||
|
||||
bman.field[PLX][PLY].type = FT_nothing;
|
||||
|
||||
dx = s_random (4); // bit 1 = up/down bit 2 = left/right
|
||||
/* up and down */
|
||||
if (((dx & 1) == 0 && PLX > 1) || PLX >= bman.fieldsize.x - 2)
|
||||
bman.field[PLX-1][PLY].type = FT_nothing;
|
||||
else
|
||||
bman.field[PLX+1][PLY].type = FT_nothing;
|
||||
/* left and right */
|
||||
if (((dx & 2) == 0 && PLY > 1) || PLY >= bman.fieldsize.y - 2)
|
||||
bman.field[PLX][PLY-1].type = FT_nothing;
|
||||
else
|
||||
bman.field[PLX][PLY+1].type = FT_nothing;
|
||||
}
|
||||
mx = my = 100;
|
||||
for (j = 0; j <= i; j++) { /* search smalest distance */
|
||||
dy = PLY - bman.players[j].pos.y;
|
||||
dx = PLX - bman.players[j].pos.x;
|
||||
if (dy < 0)
|
||||
dy = -dy;
|
||||
if (dx < 0)
|
||||
dx = -dx;
|
||||
|
||||
if (mx > dx && i != j)
|
||||
mx = dx;
|
||||
if (my > dy && i != j)
|
||||
my = dy;
|
||||
}
|
||||
|
||||
if (mx > dist || my > dist)
|
||||
i++;
|
||||
else
|
||||
p++;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < MAX_PLAYERS; i++) {
|
||||
PLX = PLX << 8;
|
||||
PLY = PLY << 8;
|
||||
}
|
||||
};
|
||||
#undef PLX
|
||||
#undef PLY
|
||||
|
||||
|
||||
void
|
||||
field_new (char *filename)
|
||||
{
|
||||
int x,
|
||||
y,
|
||||
d;
|
||||
FILE *fmap;
|
||||
float fkt;
|
||||
int nb_try;
|
||||
|
||||
if(filename)
|
||||
{
|
||||
fmap = fopen (filename, "r");
|
||||
|
||||
/* if we can't open the given filename for any reason, reverting
|
||||
to default value else, load the file */
|
||||
if (fmap)
|
||||
field_load (fmap);
|
||||
}
|
||||
else
|
||||
{
|
||||
fmap = NULL;
|
||||
}
|
||||
|
||||
/* this is the item factor we multiply it with this so we know
|
||||
how much items we want in the game */
|
||||
fkt = ((float)(bman.fieldsize.x * bman.fieldsize.y))/(25.0 * 17.0);
|
||||
|
||||
// Clean and create the field //
|
||||
if (fmap == NULL) {
|
||||
/* if we can't load the map check first the fieldsize settings */
|
||||
if (bman.fieldsize.x < MIN_FIELDSIZE_X)
|
||||
bman.fieldsize.x = MIN_FIELDSIZE_X;
|
||||
if (bman.fieldsize.x > MAX_FIELDSIZE_X)
|
||||
bman.fieldsize.x = MAX_FIELDSIZE_X;
|
||||
|
||||
for (x = 0; x < bman.fieldsize.x; x++)
|
||||
for (y = 0; y < bman.fieldsize.y; y++) {
|
||||
if ((y == 0) || (y == bman.fieldsize.y - 1))
|
||||
bman.field[x][y].type = FT_block;
|
||||
else if ((x == 0) || (x == bman.fieldsize.x - 1))
|
||||
bman.field[x][y].type = FT_block;
|
||||
else if (((x & 1) == 0) && ((y & 1) == 0))
|
||||
bman.field[x][y].type = FT_block;
|
||||
else {
|
||||
// create random field
|
||||
if ((s_random (256) & 3) == 0)
|
||||
bman.field[x][y].type = FT_nothing;
|
||||
else
|
||||
bman.field[x][y].type = FT_stone;
|
||||
}
|
||||
|
||||
for (d = 0; d < 4; d++)
|
||||
bman.field[x][y].ex[d].frame = bman.field[x][y].ex[d].count = 0;
|
||||
bman.field[x][y].ex_nr = -1;
|
||||
bman.field[x][y].frame = 0;
|
||||
bman.field[x][y].frameto = 0;
|
||||
bman.field[x][y].special = FT_nothing;
|
||||
}
|
||||
}
|
||||
|
||||
/* Set the Playerinformation */
|
||||
field_set_playerposition (fmap != NULL);
|
||||
|
||||
nb_try = 100; // to prevent infinite loops (maybe there are no stones)
|
||||
/* put the fire powerups in the field */
|
||||
for (d = 0, x = 0, y = 0; d < GAME_SPECIAL_ITEMFIRE * fkt; d++) {
|
||||
while (bman.field[x][y].type != FT_stone || bman.field[x][y].special != FT_nothing) {
|
||||
x = ((float) rand () / (float) RAND_MAX) * (bman.fieldsize.x - 1);
|
||||
y = ((float) rand () / (float) RAND_MAX) * (bman.fieldsize.y - 1);
|
||||
nb_try--;
|
||||
if (nb_try < 0)
|
||||
break;
|
||||
}
|
||||
bman.field[x][y].special = FT_fire;
|
||||
x = y = 0;
|
||||
}
|
||||
|
||||
nb_try = 100;
|
||||
/* put the bomb powerups in the field */
|
||||
for (d = 0, x = 0, y = 0; d < GAME_SPECIAL_ITEMBOMB * fkt; d++) {
|
||||
while (bman.field[x][y].type != FT_stone || bman.field[x][y].special != FT_nothing) {
|
||||
x = ((float) rand () / (float) RAND_MAX) * (bman.fieldsize.x - 1);
|
||||
y = ((float) rand () / (float) RAND_MAX) * (bman.fieldsize.y - 1);
|
||||
nb_try--;
|
||||
if (nb_try < 0)
|
||||
break;
|
||||
}
|
||||
bman.field[x][y].special = FT_bomb;
|
||||
x = y = 0;
|
||||
}
|
||||
|
||||
nb_try = 100;
|
||||
/* put the shoe powerup in the field */
|
||||
for (d = 0, x = 0, y = 0; d < GAME_SPECIAL_ITEMSHOE * fkt; d++) {
|
||||
while (bman.field[x][y].type != FT_stone || bman.field[x][y].special != FT_nothing) {
|
||||
x = ((float) rand () / (float) RAND_MAX) * (bman.fieldsize.x - 1);
|
||||
y = ((float) rand () / (float) RAND_MAX) * (bman.fieldsize.y - 1);
|
||||
nb_try--;
|
||||
if (nb_try < 0)
|
||||
break;
|
||||
}
|
||||
bman.field[x][y].special = FT_shoe;
|
||||
x = y = 0;
|
||||
}
|
||||
|
||||
nb_try = 100;
|
||||
/* put the death ?powerups? in the field */
|
||||
for (d = 0, x = 0, y = 0; d < GAME_SPECIAL_ITEMDEATH * fkt; d++) {
|
||||
while (bman.field[x][y].type != FT_stone || bman.field[x][y].special != FT_nothing) {
|
||||
x = ((float) rand () / (float) RAND_MAX) * (bman.fieldsize.x - 1);
|
||||
y = ((float) rand () / (float) RAND_MAX) * (bman.fieldsize.y - 1);
|
||||
nb_try--;
|
||||
if (nb_try < 0)
|
||||
break;
|
||||
}
|
||||
bman.field[x][y].special = FT_death;
|
||||
x = y = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,36 +1,36 @@
|
||||
// Using Fonts in SDL
|
||||
|
||||
#include <string.h>
|
||||
#include <SDL.h>
|
||||
|
||||
#include "bomberclone.h"
|
||||
#include "gfx.h"
|
||||
|
||||
void
|
||||
draw_text (int x, int y, char *text, int white)
|
||||
{
|
||||
int i,
|
||||
c;
|
||||
SDL_Rect src,
|
||||
dest;
|
||||
|
||||
src.y = 0;
|
||||
dest.w = src.w = gfx.font.size.x;
|
||||
dest.h = src.h = gfx.font.size.y;
|
||||
dest.x = x;
|
||||
dest.y = y;
|
||||
|
||||
for (i = 0; text[i] != 0; i++) {
|
||||
c = text[i];
|
||||
src.x = gfx.font.size.x * (c & 15);
|
||||
src.y = gfx.font.size.y * ((c & 240) >> 4);
|
||||
if (white)
|
||||
SDL_BlitSurface (gfx.font.image, &src, gfx.screen, &dest);
|
||||
else
|
||||
SDL_BlitSurface (gfx.font1.image, &src, gfx.screen, &dest);
|
||||
dest.x += gfx.font.size.x-4;
|
||||
}
|
||||
|
||||
gfx_AddUpdateRect (x, y, dest.x - x, dest.h);
|
||||
};
|
||||
|
||||
// Using Fonts in SDL
|
||||
|
||||
#include <string.h>
|
||||
#include <SDL.h>
|
||||
|
||||
#include "bomberclone.h"
|
||||
#include "gfx.h"
|
||||
|
||||
void
|
||||
draw_text (int x, int y, char *text, int white)
|
||||
{
|
||||
int i,
|
||||
c;
|
||||
SDL_Rect src,
|
||||
dest;
|
||||
|
||||
src.y = 0;
|
||||
dest.w = src.w = gfx.font.size.x;
|
||||
dest.h = src.h = gfx.font.size.y;
|
||||
dest.x = x;
|
||||
dest.y = y;
|
||||
|
||||
for (i = 0; text[i] != 0; i++) {
|
||||
c = text[i];
|
||||
src.x = gfx.font.size.x * (c & 15);
|
||||
src.y = gfx.font.size.y * ((c & 240) >> 4);
|
||||
if (white)
|
||||
SDL_BlitSurface (gfx.font.image, &src, gfx.screen, &dest);
|
||||
else
|
||||
SDL_BlitSurface (gfx.font1.image, &src, gfx.screen, &dest);
|
||||
dest.x += gfx.font.size.x-4;
|
||||
}
|
||||
|
||||
gfx_AddUpdateRect (x, y, dest.x - x, dest.h);
|
||||
};
|
||||
|
||||
|
@ -1,255 +1,255 @@
|
||||
/* game.c - procedures for the game. */
|
||||
|
||||
#include <string.h>
|
||||
#include <SDL.h>
|
||||
|
||||
#include "bomberclone.h"
|
||||
#include "gfx.h"
|
||||
#include "network.h"
|
||||
#include "packets.h"
|
||||
#include "chat.h"
|
||||
|
||||
extern int UpdateRects_nr;
|
||||
|
||||
void
|
||||
game_draw_info ()
|
||||
{
|
||||
int i,
|
||||
x,
|
||||
j,
|
||||
gfx_oldRects;
|
||||
char text[255];
|
||||
char scrtext[255];
|
||||
SDL_Rect src, dest;
|
||||
|
||||
redraw_logo (0, 0, gfx.res.x, 3*16);
|
||||
gfx_AddUpdateRect (0,0, gfx.res.x, 3*16);
|
||||
gfx_oldRects = UpdateRects_nr;
|
||||
bman.players_nr = 0;
|
||||
|
||||
/* draw Player names */
|
||||
if (GT_MP_PTP) {
|
||||
for (x = 0, j = 0, i = 0; i < MAX_PLAYERS; i++)
|
||||
if ((bman.players[i].state & PSFM_used) != 0) {
|
||||
|
||||
if (bman.players[i].gfx_nr != -1 && PS_IS_used (bman.players[i].state)) {
|
||||
src.x = 3 * bman.players[i].gfx->smal_size.x;
|
||||
src.y = 0;
|
||||
src.w = dest.w = bman.players[i].gfx->smal_size.x;
|
||||
src.h = dest.h = bman.players[i].gfx->smal_size.y;
|
||||
|
||||
dest.x = x;
|
||||
dest.y = j - 4;
|
||||
|
||||
SDL_BlitSurface (bman.players[i].gfx->smal_image, &src, gfx.screen, &dest);
|
||||
}
|
||||
|
||||
|
||||
sprintf (scrtext, "%10s:%2d", bman.players[i].name, bman.players[i].points);
|
||||
if ((bman.players[i].state & PSFM_alife) != PSFM_alife) { // Player is dead
|
||||
draw_text (x, j, scrtext, 0);
|
||||
if ((bman.players[i].state & PSF_used) != PSF_used)
|
||||
draw_text (x, j, "-------------", 1);
|
||||
}
|
||||
else { // players is alife
|
||||
draw_text (x, j, scrtext, 1);
|
||||
bman.players_nr++;
|
||||
}
|
||||
|
||||
x = x + 170;
|
||||
if (x >= gfx.res.x - (120 + 170)) {
|
||||
x = 0;
|
||||
j = j + 14;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
x = gfx.res.x - 120;
|
||||
sprintf (text, "Bombs: %2d", bman.players[bman.p_nr].bombs_n);
|
||||
draw_text (x, 0, text, 1);
|
||||
sprintf (text, "Range: %2d", bman.players[bman.p_nr].range);
|
||||
draw_text (x, 16, text, 1);
|
||||
sprintf (text, "Speed: %2d", bman.players[bman.p_nr].speed);
|
||||
draw_text (x, 32, text, 1);
|
||||
|
||||
if (bman.state == GS_ready && GT_MP_PTPM)
|
||||
draw_text (100, 32, "Press F4 to start the game", 1);
|
||||
else if (bman.state == GS_ready)
|
||||
draw_text (100, 32, "Waiting for the Server to Start", 1);
|
||||
gfx_AddUpdateRect (100, 32, gfx.res.x - 100, 16);
|
||||
|
||||
redraw_logo (0, gfx.res.y - gfx.font.size.y, gfx.res.x, gfx.res.y);
|
||||
for (x = 0; x < bman.fieldsize.x; x++)
|
||||
draw_stone (x, bman.fieldsize.y-1);
|
||||
|
||||
if (debug) { /* do some debug informations on the screen */
|
||||
sprintf (text, "NET_STAT: [");
|
||||
for (i = 0 ; i < MAX_PLAYERS; i++)
|
||||
sprintf (text, "%s%3d ", text, bman.players[i].net.pkgopt.send_set);
|
||||
text[strlen(text)+1] = 0;
|
||||
text[strlen(text)] = ']';
|
||||
sprintf (text, "%s GFX_RECTS:%d", text, UpdateRects_nr);
|
||||
draw_text (0, gfx.res.y - (gfx.font.size.y << 1), text, 1);
|
||||
|
||||
sprintf (text, "TILESET: %s", gfx.tileset);
|
||||
gfx_AddUpdateRect (0, gfx.res.y - (gfx.font.size.y << 1), gfx.res.x, gfx.font.size.y << 1);
|
||||
}
|
||||
|
||||
if (chat.visible == 0) {
|
||||
SDL_Flip (gfx.screen);
|
||||
chat_show (4, 3*16, gfx.res.x - 4, gfx.offset.y);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
void
|
||||
game_loop ()
|
||||
{
|
||||
SDL_Event event;
|
||||
Uint8 *keys;
|
||||
int done = 0;
|
||||
Uint32 timeloop1;
|
||||
int gameovertimeout = TIME_FACTOR * 5; // gameovertimeout
|
||||
unsigned char key_bomb = 0; // last state of the bomb key
|
||||
|
||||
draw_logo ();
|
||||
draw_field ();
|
||||
if (GT_MP_PTP)
|
||||
net_game_fillsockaddr ();
|
||||
|
||||
SDL_Flip (gfx.screen);
|
||||
|
||||
timestamp = SDL_GetTicks (); // needed for time sync.
|
||||
|
||||
d_gamedetail ("GAME START");
|
||||
|
||||
while (!done && (bman.state == GS_running || bman.state == GS_ready)) {
|
||||
if (SDL_PollEvent (&event) != 0)
|
||||
switch (event.type) {
|
||||
case (SDL_QUIT):
|
||||
done = 1;
|
||||
bman.state = GS_quit;
|
||||
}
|
||||
|
||||
/* keyboard handling */
|
||||
keys = SDL_GetKeyState (NULL);
|
||||
|
||||
/* only do movements if we're alife and GS_running */
|
||||
if ((bman.players[bman.p_nr].state & PSFM_alife) == PSFM_alife && bman.state == GS_running) {
|
||||
if (keys[SDLK_UP]) {
|
||||
bman.players[bman.p_nr].d = up;
|
||||
bman.players[bman.p_nr].m = 1;
|
||||
}
|
||||
if (keys[SDLK_DOWN]) {
|
||||
bman.players[bman.p_nr].d = down;
|
||||
bman.players[bman.p_nr].m = 1;
|
||||
}
|
||||
if (keys[SDLK_RIGHT]) {
|
||||
bman.players[bman.p_nr].d = right;
|
||||
bman.players[bman.p_nr].m = 1;
|
||||
}
|
||||
if (keys[SDLK_LEFT]) {
|
||||
bman.players[bman.p_nr].d = left;
|
||||
bman.players[bman.p_nr].m = 1;
|
||||
}
|
||||
if (keys[SDLK_LCTRL] || keys[SDLK_RCTRL]) {
|
||||
if (key_bomb == 0)
|
||||
player_drop_bomb ();
|
||||
key_bomb = 1;
|
||||
}
|
||||
else
|
||||
key_bomb = 0;
|
||||
if (keys[SDLK_LSHIFT] || keys[SDLK_RSHIFT]) {
|
||||
d_printf ("not in use yet\n");
|
||||
}
|
||||
}
|
||||
else if (GT_MP_PTPM && keys[SDLK_F4] && event.type == SDL_KEYDOWN) {
|
||||
/* Server is starting the game */
|
||||
bman.state = GS_running;
|
||||
net_send_servermode ();
|
||||
}
|
||||
|
||||
if (event.key.keysym.sym == SDLK_ESCAPE && event.type == SDL_KEYDOWN) {
|
||||
bman.state = GS_startup;
|
||||
done = 1;
|
||||
}
|
||||
|
||||
chat_loop (&event);
|
||||
|
||||
restore_players_screen ();
|
||||
restore_bomb_screen ();
|
||||
player_ilness_loop ();
|
||||
if ((bman.players[bman.p_nr].state & PSFM_alife) == PSFM_alife)
|
||||
move_player ();
|
||||
|
||||
player_calcpos ();
|
||||
dead_playerani (); /* we need it to draw dead players */
|
||||
|
||||
if (bman.gametype != GT_single)
|
||||
network_loop ();
|
||||
else
|
||||
single_loop ();
|
||||
|
||||
/* this will even set the variable "bman.player_nr"
|
||||
to let us know how much Players are still left */
|
||||
game_draw_info ();
|
||||
|
||||
bomb_loop ();
|
||||
draw_players ();
|
||||
|
||||
gfx_UpdateRects ();
|
||||
|
||||
/* check if there is only one player left and the game is in multiplayer mode
|
||||
and if there the last dieing animation is done */
|
||||
if ((GT_MP_PTPM) && bman.players_nr < 2)
|
||||
gameovertimeout--;
|
||||
|
||||
/* check if we died and we are in single mode and the animation is done */
|
||||
if (bman.gametype == GT_single && !PS_IS_alife(bman.players[bman.p_nr].state))
|
||||
gameovertimeout--;
|
||||
|
||||
if (gameovertimeout <= 0) {
|
||||
d_printf ("GAME: Game Over 'Cause only one or noone anymore alife\n");
|
||||
done = 1;
|
||||
}
|
||||
|
||||
// calculate time sync.
|
||||
timeloop1 = SDL_GetTicks ();
|
||||
while (timeloop1 - timestamp >= 0 && timeloop1 - timestamp < 20) {
|
||||
s_delay (timeloop1 - timestamp - 1);
|
||||
timeloop1 = SDL_GetTicks ();
|
||||
}
|
||||
|
||||
timestamp = timeloop1;
|
||||
}
|
||||
|
||||
chat_show (-1, -1, -1, -1);
|
||||
|
||||
d_gamedetail ("GAME END");
|
||||
d_printf ("done = %d\n", done);
|
||||
};
|
||||
|
||||
|
||||
/* check which player won */
|
||||
void
|
||||
game_end ()
|
||||
{
|
||||
int i;
|
||||
|
||||
/* count the points */
|
||||
for (i = 0; i < MAX_PLAYERS; i++)
|
||||
if (PS_IS_used (bman.players[i].state)) {
|
||||
if (PS_IS_alife (bman.players[i].state)) {
|
||||
bman.lastwinner = i;
|
||||
bman.players[i].wins++;
|
||||
bman.players[i].points += bman.players_nr_s;
|
||||
}
|
||||
}
|
||||
|
||||
/* check which player is now free ,i.e. disconnected during the game and was playing */
|
||||
for (i = 0; i < MAX_PLAYERS; i++)
|
||||
if ((bman.players[i].state & PSF_used ) == 0)
|
||||
bman.players[i].state = 0;
|
||||
}
|
||||
|
||||
|
||||
/* game.c - procedures for the game. */
|
||||
|
||||
#include <string.h>
|
||||
#include <SDL.h>
|
||||
|
||||
#include "bomberclone.h"
|
||||
#include "gfx.h"
|
||||
#include "network.h"
|
||||
#include "packets.h"
|
||||
#include "chat.h"
|
||||
|
||||
extern int UpdateRects_nr;
|
||||
|
||||
void
|
||||
game_draw_info ()
|
||||
{
|
||||
int i,
|
||||
x,
|
||||
j,
|
||||
gfx_oldRects;
|
||||
char text[255];
|
||||
char scrtext[255];
|
||||
SDL_Rect src, dest;
|
||||
|
||||
redraw_logo (0, 0, gfx.res.x, 3*16);
|
||||
gfx_AddUpdateRect (0,0, gfx.res.x, 3*16);
|
||||
gfx_oldRects = UpdateRects_nr;
|
||||
bman.players_nr = 0;
|
||||
|
||||
/* draw Player names */
|
||||
if (GT_MP_PTP) {
|
||||
for (x = 0, j = 0, i = 0; i < MAX_PLAYERS; i++)
|
||||
if ((bman.players[i].state & PSFM_used) != 0) {
|
||||
|
||||
if (bman.players[i].gfx_nr != -1 && PS_IS_used (bman.players[i].state)) {
|
||||
src.x = 3 * bman.players[i].gfx->smal_size.x;
|
||||
src.y = 0;
|
||||
src.w = dest.w = bman.players[i].gfx->smal_size.x;
|
||||
src.h = dest.h = bman.players[i].gfx->smal_size.y;
|
||||
|
||||
dest.x = x;
|
||||
dest.y = j - 4;
|
||||
|
||||
SDL_BlitSurface (bman.players[i].gfx->smal_image, &src, gfx.screen, &dest);
|
||||
}
|
||||
|
||||
|
||||
sprintf (scrtext, "%10s:%2d", bman.players[i].name, bman.players[i].points);
|
||||
if ((bman.players[i].state & PSFM_alife) != PSFM_alife) { // Player is dead
|
||||
draw_text (x, j, scrtext, 0);
|
||||
if ((bman.players[i].state & PSF_used) != PSF_used)
|
||||
draw_text (x, j, "-------------", 1);
|
||||
}
|
||||
else { // players is alife
|
||||
draw_text (x, j, scrtext, 1);
|
||||
bman.players_nr++;
|
||||
}
|
||||
|
||||
x = x + 170;
|
||||
if (x >= gfx.res.x - (120 + 170)) {
|
||||
x = 0;
|
||||
j = j + 14;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
x = gfx.res.x - 120;
|
||||
sprintf (text, "Bombs: %2d", bman.players[bman.p_nr].bombs_n);
|
||||
draw_text (x, 0, text, 1);
|
||||
sprintf (text, "Range: %2d", bman.players[bman.p_nr].range);
|
||||
draw_text (x, 16, text, 1);
|
||||
sprintf (text, "Speed: %2d", bman.players[bman.p_nr].speed);
|
||||
draw_text (x, 32, text, 1);
|
||||
|
||||
if (bman.state == GS_ready && GT_MP_PTPM)
|
||||
draw_text (100, 32, "Press F4 to start the game", 1);
|
||||
else if (bman.state == GS_ready)
|
||||
draw_text (100, 32, "Waiting for the Server to Start", 1);
|
||||
gfx_AddUpdateRect (100, 32, gfx.res.x - 100, 16);
|
||||
|
||||
redraw_logo (0, gfx.res.y - gfx.font.size.y, gfx.res.x, gfx.res.y);
|
||||
for (x = 0; x < bman.fieldsize.x; x++)
|
||||
draw_stone (x, bman.fieldsize.y-1);
|
||||
|
||||
if (debug) { /* do some debug informations on the screen */
|
||||
sprintf (text, "NET_STAT: [");
|
||||
for (i = 0 ; i < MAX_PLAYERS; i++)
|
||||
sprintf (text, "%s%3d ", text, bman.players[i].net.pkgopt.send_set);
|
||||
text[strlen(text)+1] = 0;
|
||||
text[strlen(text)] = ']';
|
||||
sprintf (text, "%s GFX_RECTS:%d", text, UpdateRects_nr);
|
||||
draw_text (0, gfx.res.y - (gfx.font.size.y << 1), text, 1);
|
||||
|
||||
sprintf (text, "TILESET: %s", gfx.tileset);
|
||||
gfx_AddUpdateRect (0, gfx.res.y - (gfx.font.size.y << 1), gfx.res.x, gfx.font.size.y << 1);
|
||||
}
|
||||
|
||||
if (chat.visible == 0) {
|
||||
SDL_Flip (gfx.screen);
|
||||
chat_show (4, 3*16, gfx.res.x - 4, gfx.offset.y);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
void
|
||||
game_loop ()
|
||||
{
|
||||
SDL_Event event;
|
||||
Uint8 *keys;
|
||||
int done = 0;
|
||||
Uint32 timeloop1;
|
||||
int gameovertimeout = TIME_FACTOR * 5; // gameovertimeout
|
||||
unsigned char key_bomb = 0; // last state of the bomb key
|
||||
|
||||
draw_logo ();
|
||||
draw_field ();
|
||||
if (GT_MP_PTP)
|
||||
net_game_fillsockaddr ();
|
||||
|
||||
SDL_Flip (gfx.screen);
|
||||
|
||||
timestamp = SDL_GetTicks (); // needed for time sync.
|
||||
|
||||
d_gamedetail ("GAME START");
|
||||
|
||||
while (!done && (bman.state == GS_running || bman.state == GS_ready)) {
|
||||
if (SDL_PollEvent (&event) != 0)
|
||||
switch (event.type) {
|
||||
case (SDL_QUIT):
|
||||
done = 1;
|
||||
bman.state = GS_quit;
|
||||
}
|
||||
|
||||
/* keyboard handling */
|
||||
keys = SDL_GetKeyState (NULL);
|
||||
|
||||
/* only do movements if we're alife and GS_running */
|
||||
if ((bman.players[bman.p_nr].state & PSFM_alife) == PSFM_alife && bman.state == GS_running) {
|
||||
if (keys[SDLK_UP]) {
|
||||
bman.players[bman.p_nr].d = up;
|
||||
bman.players[bman.p_nr].m = 1;
|
||||
}
|
||||
if (keys[SDLK_DOWN]) {
|
||||
bman.players[bman.p_nr].d = down;
|
||||
bman.players[bman.p_nr].m = 1;
|
||||
}
|
||||
if (keys[SDLK_RIGHT]) {
|
||||
bman.players[bman.p_nr].d = right;
|
||||
bman.players[bman.p_nr].m = 1;
|
||||
}
|
||||
if (keys[SDLK_LEFT]) {
|
||||
bman.players[bman.p_nr].d = left;
|
||||
bman.players[bman.p_nr].m = 1;
|
||||
}
|
||||
if (keys[SDLK_LCTRL] || keys[SDLK_RCTRL]) {
|
||||
if (key_bomb == 0)
|
||||
player_drop_bomb ();
|
||||
key_bomb = 1;
|
||||
}
|
||||
else
|
||||
key_bomb = 0;
|
||||
if (keys[SDLK_LSHIFT] || keys[SDLK_RSHIFT]) {
|
||||
d_printf ("not in use yet\n");
|
||||
}
|
||||
}
|
||||
else if (GT_MP_PTPM && keys[SDLK_F4] && event.type == SDL_KEYDOWN) {
|
||||
/* Server is starting the game */
|
||||
bman.state = GS_running;
|
||||
net_send_servermode ();
|
||||
}
|
||||
|
||||
if (event.key.keysym.sym == SDLK_ESCAPE && event.type == SDL_KEYDOWN) {
|
||||
bman.state = GS_startup;
|
||||
done = 1;
|
||||
}
|
||||
|
||||
chat_loop (&event);
|
||||
|
||||
restore_players_screen ();
|
||||
restore_bomb_screen ();
|
||||
player_ilness_loop ();
|
||||
if ((bman.players[bman.p_nr].state & PSFM_alife) == PSFM_alife)
|
||||
move_player ();
|
||||
|
||||
player_calcpos ();
|
||||
dead_playerani (); /* we need it to draw dead players */
|
||||
|
||||
if (bman.gametype != GT_single)
|
||||
network_loop ();
|
||||
else
|
||||
single_loop ();
|
||||
|
||||
/* this will even set the variable "bman.player_nr"
|
||||
to let us know how much Players are still left */
|
||||
game_draw_info ();
|
||||
|
||||
bomb_loop ();
|
||||
draw_players ();
|
||||
|
||||
gfx_UpdateRects ();
|
||||
|
||||
/* check if there is only one player left and the game is in multiplayer mode
|
||||
and if there the last dieing animation is done */
|
||||
if ((GT_MP_PTPM) && bman.players_nr < 2)
|
||||
gameovertimeout--;
|
||||
|
||||
/* check if we died and we are in single mode and the animation is done */
|
||||
if (bman.gametype == GT_single && !PS_IS_alife(bman.players[bman.p_nr].state))
|
||||
gameovertimeout--;
|
||||
|
||||
if (gameovertimeout <= 0) {
|
||||
d_printf ("GAME: Game Over 'Cause only one or noone anymore alife\n");
|
||||
done = 1;
|
||||
}
|
||||
|
||||
// calculate time sync.
|
||||
timeloop1 = SDL_GetTicks ();
|
||||
while (timeloop1 - timestamp >= 0 && timeloop1 - timestamp < 20) {
|
||||
s_delay (timeloop1 - timestamp - 1);
|
||||
timeloop1 = SDL_GetTicks ();
|
||||
}
|
||||
|
||||
timestamp = timeloop1;
|
||||
}
|
||||
|
||||
chat_show (-1, -1, -1, -1);
|
||||
|
||||
d_gamedetail ("GAME END");
|
||||
d_printf ("done = %d\n", done);
|
||||
};
|
||||
|
||||
|
||||
/* check which player won */
|
||||
void
|
||||
game_end ()
|
||||
{
|
||||
int i;
|
||||
|
||||
/* count the points */
|
||||
for (i = 0; i < MAX_PLAYERS; i++)
|
||||
if (PS_IS_used (bman.players[i].state)) {
|
||||
if (PS_IS_alife (bman.players[i].state)) {
|
||||
bman.lastwinner = i;
|
||||
bman.players[i].wins++;
|
||||
bman.players[i].points += bman.players_nr_s;
|
||||
}
|
||||
}
|
||||
|
||||
/* check which player is now free ,i.e. disconnected during the game and was playing */
|
||||
for (i = 0; i < MAX_PLAYERS; i++)
|
||||
if ((bman.players[i].state & PSF_used ) == 0)
|
||||
bman.players[i].state = 0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,469 +1,469 @@
|
||||
/*
|
||||
GameServer: this file will hold the protocol for the gameserver communication
|
||||
*/
|
||||
#include "bomberclone.h"
|
||||
#include "network.h"
|
||||
#include "gamesrv.h"
|
||||
|
||||
static int sock = -1;
|
||||
struct game_entry gse[MAX_GAMESRVENTRYS];
|
||||
_menu menu[22];
|
||||
int menuselect = 0;
|
||||
|
||||
/*
|
||||
We want to get a server
|
||||
*/
|
||||
void
|
||||
gamesrv_getserver ()
|
||||
{
|
||||
int i,
|
||||
keypressed = 0,
|
||||
done = 0,
|
||||
ds = 0,
|
||||
gserv = bman.notifygamemaster,
|
||||
bx,
|
||||
by;
|
||||
SDL_Event event;
|
||||
Uint8 *keys;
|
||||
|
||||
menuselect = 0;
|
||||
for (i = 0; i < MAX_GAMESRVENTRYS; i++) {
|
||||
gse[i].name[0] = 0;
|
||||
gse[i].host[0] = 0;
|
||||
gse[i].port[0] = 0;
|
||||
}
|
||||
for (i = 0; i < 21; i++) {
|
||||
menu[i].index = 0;
|
||||
menu[i].text[0] = 0;
|
||||
}
|
||||
if (!gserv) {
|
||||
menu[0].index = 1;
|
||||
sprintf (menu[0].text, "Scan for Games on the MasterServer");
|
||||
}
|
||||
sprintf (menu[10].text, "User defined Server List");
|
||||
menu[20].index = 1;
|
||||
sprintf (menu[20].text, "Enter an IP-Address");
|
||||
menu[21].index = -1;
|
||||
for (i = 1; i <= MAX_SERVERENTRYS; i++) {
|
||||
menu[i + 10].index = 1;
|
||||
sprintf (menu[i + 10].text, "%d) %s", i, bman.serverlist[i - 1].name);
|
||||
}
|
||||
|
||||
draw_logo ();
|
||||
draw_menu ("Select Server", menu, &bx, &by);
|
||||
if (gserv) {
|
||||
if (gamesrv_startudp () == -1)
|
||||
return;
|
||||
gamesrv_browse (1);
|
||||
}
|
||||
draw_select (menuselect, menu, bx, by);
|
||||
|
||||
SDL_Flip (gfx.screen);
|
||||
|
||||
while (menuselect != -1 && done == 0) {
|
||||
|
||||
if (gserv)
|
||||
i = gamesrv_getglist ();
|
||||
/*keyboard */
|
||||
if (SDL_PollEvent (&event) != 0)
|
||||
switch (event.type) {
|
||||
case (SDL_QUIT):
|
||||
bman.state = GS_quit;
|
||||
menuselect = -1;
|
||||
done = 1;
|
||||
}
|
||||
|
||||
keys = SDL_GetKeyState (NULL);
|
||||
|
||||
if (keys[SDLK_ESCAPE] && event.type == SDL_KEYDOWN) {
|
||||
/* we want to quit */
|
||||
done = 1;
|
||||
keypressed = 1;
|
||||
menuselect = -1;
|
||||
}
|
||||
|
||||
if (keys[SDLK_DOWN] && (!keypressed)) {
|
||||
d_printf ("down:%d\n", menu[menuselect].index);
|
||||
menuselect++;
|
||||
while (menu[menuselect].index == 0)
|
||||
menuselect++;
|
||||
if (menu[menuselect].index == -1) {
|
||||
menuselect = 0;
|
||||
while (menu[menuselect].index == 0)
|
||||
menuselect++;
|
||||
}
|
||||
keypressed = 1;
|
||||
ds = 1;
|
||||
}
|
||||
|
||||
if (keys[SDLK_UP] && (!keypressed)) {
|
||||
d_printf ("up\n");
|
||||
menuselect--;
|
||||
while (menu[menuselect].index == 0 && menuselect >= 0)
|
||||
menuselect--;
|
||||
if (menuselect == -1)
|
||||
menuselect = 20;
|
||||
keypressed = 1;
|
||||
ds = 1;
|
||||
}
|
||||
if (keys[SDLK_RETURN] && (!keypressed)) {
|
||||
if (menuselect == 0 && !gserv) {
|
||||
gserv = 1;
|
||||
if (gamesrv_startudp () == -1)
|
||||
return;
|
||||
gamesrv_browse (1);
|
||||
} else done=1;
|
||||
|
||||
|
||||
keypressed = 1;
|
||||
}
|
||||
|
||||
if (event.type == SDL_KEYUP)
|
||||
keypressed = 0;
|
||||
else if (event.type == SDL_KEYDOWN)
|
||||
keypressed = 1;
|
||||
|
||||
if (i) {
|
||||
draw_logo ();
|
||||
draw_menu ("Select Server", menu, &bx, &by);
|
||||
draw_select (menuselect, menu, bx, by);
|
||||
ds = 0;
|
||||
SDL_Flip (gfx.screen);
|
||||
}
|
||||
else if (ds) {
|
||||
draw_select (menuselect, menu, bx, by);
|
||||
ds = 0;
|
||||
SDL_Flip (gfx.screen);
|
||||
}
|
||||
s_delay (250);
|
||||
}
|
||||
|
||||
|
||||
if (menuselect > 0 && menuselect < 10) {
|
||||
i = (menuselect - 1);
|
||||
if (gse[i].name[0] != 0 && gse[i].host[0] != 0 && gse[i].port[0] != 0 &&
|
||||
(gse[i].state == GS_wait || gse[i].state == GS_running
|
||||
|| gse[i].state == GS_ready)) {
|
||||
/* add if we are on Linux + and Windows and ai_family == PF_INET */
|
||||
#ifdef _WIN32
|
||||
if (gse[i].ai_family == PF_INET) {
|
||||
sprintf (bman.servername, "%s:%s", gse[i].host, gse[i].port);
|
||||
bman.net_ai_family = gse[i].ai_family;
|
||||
}
|
||||
#else
|
||||
sprintf (bman.servername, "%s:%s", gse[i].host, gse[i].port);
|
||||
d_printf("%s xxx %s xxx %s",gse[i].host,gse[i].port,bman.servername);
|
||||
bman.net_ai_family = gse[i].ai_family;
|
||||
#endif
|
||||
}
|
||||
} else if (menuselect >= 11 && menuselect < 19)
|
||||
/* User defined Servers */
|
||||
strncpy (bman.servername, bman.serverlist[menuselect - 11].name,
|
||||
LEN_SERVERNAME + LEN_PORT + 2);
|
||||
else if (menuselect == 20) {
|
||||
/* enter address */
|
||||
menu_get_text ("Enter Address", bman.servername, LEN_SERVERNAME + LEN_PORT + 2);}
|
||||
|
||||
|
||||
if (gserv) {
|
||||
gamesrv_browse (0);
|
||||
udp_close (sock);
|
||||
sock = -1;
|
||||
|
||||
#ifdef _WIN32
|
||||
WSACleanup ();
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
int
|
||||
gamesrv_getglist ()
|
||||
{
|
||||
int i,
|
||||
i1,
|
||||
i2,
|
||||
i3,
|
||||
y,
|
||||
nr,
|
||||
rebuild = 0;
|
||||
char buf[BUF_SIZE];
|
||||
char *pos;
|
||||
char txt[255];
|
||||
struct _sockaddr addr;
|
||||
struct game_entry entry;
|
||||
|
||||
while (udp_get (sock, buf, BUF_SIZE, &addr, PF_INET) > 0) {
|
||||
d_printf ("GOT:\n%s\n", buf);
|
||||
|
||||
if (buf[0] == 'E') {
|
||||
for (i = 0; i < MAX_GAMESRVENTRYS; i++) {
|
||||
gse[i].name[0] = 0;
|
||||
gse[i].host[0] = 0;
|
||||
gse[i].port[0] = 0;
|
||||
}
|
||||
for (i = 0; i < 10; i++ ) {
|
||||
menu[i].index = 0;
|
||||
menu[i].text[0] = 0;
|
||||
}
|
||||
sprintf (menu[0].text, "No Games found on Masterserver");
|
||||
menu[0].index = 1;
|
||||
rebuild = 1;
|
||||
if (menuselect<10) menuselect=0;
|
||||
}
|
||||
else {
|
||||
for (pos = buf; pos != 0;) {
|
||||
// go throught the incoming data
|
||||
switch (pos[0]) {
|
||||
case ('P'):
|
||||
sscanf (pos + 1, "%d,%d", &i1, &i2);
|
||||
entry.curplayers = i1;
|
||||
entry.maxplayers = i2;
|
||||
break;
|
||||
case ('V'):
|
||||
sscanf (pos + 1, "%d.%d.%d", &i1, &i2, &i3);
|
||||
entry.version.major = i1;
|
||||
entry.version.minor = i2;
|
||||
entry.version.sub = i3;
|
||||
break;
|
||||
case ('S'):
|
||||
sscanf (pos + 1, "%d,%d,%d", &i1, &i2, &i3);
|
||||
entry.state = i1;
|
||||
entry.multitype = i2;
|
||||
entry.gametype = i3;
|
||||
break;
|
||||
case ('I'):
|
||||
if (pos[1] == '4')
|
||||
entry.ai_family = PF_INET;
|
||||
else if (pos[1] == '6')
|
||||
#ifndef _WIN32
|
||||
entry.ai_family = PF_INET6;
|
||||
#else
|
||||
entry.ai_family = 0;
|
||||
#endif
|
||||
break;
|
||||
case ('N'):
|
||||
for (i = 1; (i - 1 < LEN_GAMENAME) && (pos[i] != 0)
|
||||
&& (pos[i] != '\n'); i++)
|
||||
entry.name[i - 1] = pos[i];
|
||||
entry.name[i-1]=0;
|
||||
break;
|
||||
case ('H'):
|
||||
for (i = 1; (i - 1 < LEN_SERVERNAME) && (pos[i] != 0)
|
||||
&& (pos[i] != '\n'); i++)
|
||||
entry.host[i - 1] = pos[i];
|
||||
entry.host[i-1]=0;
|
||||
break;
|
||||
case ('O'):
|
||||
for (i = 1; (i - 1 < LEN_PORT) && (pos[i] != 0)
|
||||
&& (pos[i] != '\n'); i++)
|
||||
entry.port[i - 1] = pos[i];
|
||||
entry.port[i-1]=0;
|
||||
break;
|
||||
}
|
||||
pos = strchr (pos, '\n');
|
||||
if (pos != 0)
|
||||
pos++;
|
||||
if (pos != 0 && pos[0] == 0)
|
||||
pos = 0;
|
||||
}
|
||||
nr = gamesrv_findentry (entry.host, entry.port);
|
||||
if (nr == -1) {
|
||||
nr = gamesrv_findfree ();
|
||||
if (nr == -1)
|
||||
return -1;
|
||||
}
|
||||
gse[nr] = entry;
|
||||
|
||||
|
||||
sprintf (txt, "%16s ", gse[nr].name);
|
||||
|
||||
if (gse[nr].state == GS_wait)
|
||||
sprintf (txt, "%s Wait ", txt);
|
||||
else if (gse[nr].state == GS_running || gse[nr].state == GS_ready)
|
||||
sprintf (txt, "%sRunning ", txt);
|
||||
else if (gse[nr].state == GS_update)
|
||||
sprintf (txt, "%s Update ", txt);
|
||||
|
||||
sprintf (txt, "%s%d/%d ", txt, gse[nr].curplayers, gse[nr].maxplayers);
|
||||
|
||||
if (gse[nr].ai_family == PF_INET)
|
||||
sprintf (txt, "%s %d.%d.%d IPv4", txt, gse[nr].version.major, gse[nr].version.minor,
|
||||
gse[nr].version.sub);
|
||||
else
|
||||
sprintf (txt, "%s %d.%d.%d IPv6", txt, gse[nr].version.major, gse[nr].version.minor,
|
||||
gse[nr].version.sub);
|
||||
|
||||
for (y = 0; y < 255; y++)
|
||||
menu[nr + 1].text[y] = 0;
|
||||
strncpy (menu[nr + 1].text, txt, 40);
|
||||
rebuild = 1;
|
||||
sprintf (menu[0].text, "Games on the Masterserver");
|
||||
menu[0].index = 0;
|
||||
if (menuselect == 0)
|
||||
menuselect = 1;
|
||||
menu[nr + 1].index = 1;
|
||||
}
|
||||
}
|
||||
return rebuild;
|
||||
}
|
||||
|
||||
int
|
||||
gamesrv_startudp ()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
WSADATA wsaData;
|
||||
|
||||
if (WSAStartup (MAKEWORD (1, 1), &wsaData) != 0) {
|
||||
d_printf ("WSAStartup failed.\n");
|
||||
exit (1);
|
||||
}
|
||||
#endif
|
||||
|
||||
sock = udp_server (DEFAULT_GMUDPPORT, bman.net_ai_family);
|
||||
if (sock == -1) {
|
||||
#ifdef _WIN32
|
||||
WSACleanup ();
|
||||
#endif
|
||||
}
|
||||
return sock;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* find the entry */
|
||||
int
|
||||
gamesrv_findentry (char *host, char *port)
|
||||
{
|
||||
int i,
|
||||
y;
|
||||
|
||||
for (i = 0, y = -1; (i < MAX_GAMESRVENTRYS) && (y == -1); i++) {
|
||||
if (strcmp (gse[i].host, host) == 0 && strcmp (gse[i].port, port) == 0)
|
||||
y = i;
|
||||
}
|
||||
return y;
|
||||
};
|
||||
|
||||
/* Find first free entry */
|
||||
int
|
||||
gamesrv_findfree ()
|
||||
{
|
||||
int i,
|
||||
y;
|
||||
|
||||
for (i = 0, y = -1; (y == -1) && (i < MAX_GAMESRVENTRYS); i++)
|
||||
if (gse[i].host[0] == 0)
|
||||
y = i;
|
||||
|
||||
return y;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*
|
||||
Add and Delete Browsers from Serverbrowselist
|
||||
*/
|
||||
|
||||
|
||||
void
|
||||
gamesrv_browse (int i)
|
||||
{
|
||||
char data[255];
|
||||
struct _sockaddr addr;
|
||||
char host[LEN_SERVERNAME];
|
||||
char port[LEN_PORT];
|
||||
|
||||
d_printf ("** Notify Browser Master Server\n");
|
||||
if (i)
|
||||
sprintf (data, "B\n");
|
||||
else
|
||||
sprintf (data, "E\n");
|
||||
|
||||
network_server_port (bman.gamemaster, host, LEN_SERVERNAME, port, LEN_PORT);
|
||||
dns_filladdr (host, LEN_SERVERNAME, port, LEN_PORT, bman.net_ai_family, &addr);
|
||||
udp_send (sock, data, strlen (data), &addr, bman.net_ai_family);
|
||||
d_printf ("Send: %s\n", data);
|
||||
};
|
||||
|
||||
/*
|
||||
The Server should know that we quit.
|
||||
Delete every entry from our client.
|
||||
*/
|
||||
|
||||
|
||||
void
|
||||
gamesrv_quit ()
|
||||
{
|
||||
char data[255];
|
||||
struct _sockaddr addr;
|
||||
char host[LEN_SERVERNAME];
|
||||
char port[LEN_PORT];
|
||||
int len;
|
||||
|
||||
d_printf ("** Notify GameMaster Server\n");
|
||||
sprintf (data, "D\n");
|
||||
|
||||
len = 4;
|
||||
|
||||
network_server_port (bman.gamemaster, host, LEN_SERVERNAME, port, LEN_PORT);
|
||||
dns_filladdr (host, LEN_SERVERNAME, port, LEN_PORT, bman.net_ai_family, &addr);
|
||||
|
||||
udp_send (bman.sock, data, len, &addr, bman.net_ai_family);
|
||||
d_printf ("** Send \n\n%s\n\n", data);
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
send the mode of the game from the current bman.state and bman.gamename
|
||||
parameter
|
||||
*/
|
||||
void
|
||||
gamesrv_sendmode (int maxplayer, int curplayers)
|
||||
{
|
||||
char data[255];
|
||||
int len = 0;
|
||||
struct _sockaddr addr;
|
||||
char host[LEN_SERVERNAME];
|
||||
char port[LEN_PORT];
|
||||
|
||||
d_printf ("** Notify GameMaster Server\n");
|
||||
|
||||
sprintf (data, "AV%s\n", VERSION);
|
||||
sprintf (data, "%sP%d,%d\n", data, curplayers, maxplayer);
|
||||
sprintf (data, "%sS%d,%d,%d\n", data, bman.state, bman.multitype, bman.gametype);
|
||||
if (bman.net_ai_family == PF_INET)
|
||||
sprintf (data, "%sI4\n", data);
|
||||
else
|
||||
sprintf (data, "%sI6\n", data);
|
||||
sprintf (data, "%sN%s\n", data, bman.gamename);
|
||||
|
||||
len = strlen (data);
|
||||
|
||||
network_server_port (bman.gamemaster, host, LEN_SERVERNAME, port, LEN_PORT);
|
||||
dns_filladdr (host, LEN_SERVERNAME, port, LEN_PORT, bman.net_ai_family, &addr);
|
||||
|
||||
host[0] = 0;
|
||||
port[0] = 0;
|
||||
dns_filladdr (host, LEN_SERVERNAME, port, LEN_PORT, bman.net_ai_family, &addr);
|
||||
|
||||
udp_send (bman.sock, data, len, &addr, bman.net_ai_family);
|
||||
d_printf ("** Send To (%s[:%s])\n\n%s\n\n", host, port, data);
|
||||
};
|
||||
|
||||
|
||||
void
|
||||
gamesrv_sendchat (char *text)
|
||||
{
|
||||
char data[255];
|
||||
struct _sockaddr addr;
|
||||
char host[LEN_SERVERNAME];
|
||||
char port[LEN_PORT];
|
||||
|
||||
network_server_port (bman.gamemaster, host, LEN_SERVERNAME, port, LEN_PORT);
|
||||
dns_filladdr (host, LEN_SERVERNAME, port, LEN_PORT, bman.net_ai_family, &addr);
|
||||
|
||||
sprintf (data, "C%s", text);
|
||||
|
||||
udp_send (bman.sock, data, strlen (data), &addr, bman.net_ai_family);
|
||||
};
|
||||
/*
|
||||
GameServer: this file will hold the protocol for the gameserver communication
|
||||
*/
|
||||
#include "bomberclone.h"
|
||||
#include "network.h"
|
||||
#include "gamesrv.h"
|
||||
|
||||
static int sock = -1;
|
||||
struct game_entry gse[MAX_GAMESRVENTRYS];
|
||||
_menu menu[22];
|
||||
int menuselect = 0;
|
||||
|
||||
/*
|
||||
We want to get a server
|
||||
*/
|
||||
void
|
||||
gamesrv_getserver ()
|
||||
{
|
||||
int i,
|
||||
keypressed = 0,
|
||||
done = 0,
|
||||
ds = 0,
|
||||
gserv = bman.notifygamemaster,
|
||||
bx,
|
||||
by;
|
||||
SDL_Event event;
|
||||
Uint8 *keys;
|
||||
|
||||
menuselect = 0;
|
||||
for (i = 0; i < MAX_GAMESRVENTRYS; i++) {
|
||||
gse[i].name[0] = 0;
|
||||
gse[i].host[0] = 0;
|
||||
gse[i].port[0] = 0;
|
||||
}
|
||||
for (i = 0; i < 21; i++) {
|
||||
menu[i].index = 0;
|
||||
menu[i].text[0] = 0;
|
||||
}
|
||||
if (!gserv) {
|
||||
menu[0].index = 1;
|
||||
sprintf (menu[0].text, "Scan for Games on the MasterServer");
|
||||
}
|
||||
sprintf (menu[10].text, "User defined Server List");
|
||||
menu[20].index = 1;
|
||||
sprintf (menu[20].text, "Enter an IP-Address");
|
||||
menu[21].index = -1;
|
||||
for (i = 1; i <= MAX_SERVERENTRYS; i++) {
|
||||
menu[i + 10].index = 1;
|
||||
sprintf (menu[i + 10].text, "%d) %s", i, bman.serverlist[i - 1].name);
|
||||
}
|
||||
|
||||
draw_logo ();
|
||||
draw_menu ("Select Server", menu, &bx, &by);
|
||||
if (gserv) {
|
||||
if (gamesrv_startudp () == -1)
|
||||
return;
|
||||
gamesrv_browse (1);
|
||||
}
|
||||
draw_select (menuselect, menu, bx, by);
|
||||
|
||||
SDL_Flip (gfx.screen);
|
||||
|
||||
while (menuselect != -1 && done == 0) {
|
||||
|
||||
if (gserv)
|
||||
i = gamesrv_getglist ();
|
||||
/*keyboard */
|
||||
if (SDL_PollEvent (&event) != 0)
|
||||
switch (event.type) {
|
||||
case (SDL_QUIT):
|
||||
bman.state = GS_quit;
|
||||
menuselect = -1;
|
||||
done = 1;
|
||||
}
|
||||
|
||||
keys = SDL_GetKeyState (NULL);
|
||||
|
||||
if (keys[SDLK_ESCAPE] && event.type == SDL_KEYDOWN) {
|
||||
/* we want to quit */
|
||||
done = 1;
|
||||
keypressed = 1;
|
||||
menuselect = -1;
|
||||
}
|
||||
|
||||
if (keys[SDLK_DOWN] && (!keypressed)) {
|
||||
d_printf ("down:%d\n", menu[menuselect].index);
|
||||
menuselect++;
|
||||
while (menu[menuselect].index == 0)
|
||||
menuselect++;
|
||||
if (menu[menuselect].index == -1) {
|
||||
menuselect = 0;
|
||||
while (menu[menuselect].index == 0)
|
||||
menuselect++;
|
||||
}
|
||||
keypressed = 1;
|
||||
ds = 1;
|
||||
}
|
||||
|
||||
if (keys[SDLK_UP] && (!keypressed)) {
|
||||
d_printf ("up\n");
|
||||
menuselect--;
|
||||
while (menu[menuselect].index == 0 && menuselect >= 0)
|
||||
menuselect--;
|
||||
if (menuselect == -1)
|
||||
menuselect = 20;
|
||||
keypressed = 1;
|
||||
ds = 1;
|
||||
}
|
||||
if (keys[SDLK_RETURN] && (!keypressed)) {
|
||||
if (menuselect == 0 && !gserv) {
|
||||
gserv = 1;
|
||||
if (gamesrv_startudp () == -1)
|
||||
return;
|
||||
gamesrv_browse (1);
|
||||
} else done=1;
|
||||
|
||||
|
||||
keypressed = 1;
|
||||
}
|
||||
|
||||
if (event.type == SDL_KEYUP)
|
||||
keypressed = 0;
|
||||
else if (event.type == SDL_KEYDOWN)
|
||||
keypressed = 1;
|
||||
|
||||
if (i) {
|
||||
draw_logo ();
|
||||
draw_menu ("Select Server", menu, &bx, &by);
|
||||
draw_select (menuselect, menu, bx, by);
|
||||
ds = 0;
|
||||
SDL_Flip (gfx.screen);
|
||||
}
|
||||
else if (ds) {
|
||||
draw_select (menuselect, menu, bx, by);
|
||||
ds = 0;
|
||||
SDL_Flip (gfx.screen);
|
||||
}
|
||||
s_delay (250);
|
||||
}
|
||||
|
||||
|
||||
if (menuselect > 0 && menuselect < 10) {
|
||||
i = (menuselect - 1);
|
||||
if (gse[i].name[0] != 0 && gse[i].host[0] != 0 && gse[i].port[0] != 0 &&
|
||||
(gse[i].state == GS_wait || gse[i].state == GS_running
|
||||
|| gse[i].state == GS_ready)) {
|
||||
/* add if we are on Linux + and Windows and ai_family == PF_INET */
|
||||
#ifdef _WIN32
|
||||
if (gse[i].ai_family == PF_INET) {
|
||||
sprintf (bman.servername, "%s:%s", gse[i].host, gse[i].port);
|
||||
bman.net_ai_family = gse[i].ai_family;
|
||||
}
|
||||
#else
|
||||
sprintf (bman.servername, "%s:%s", gse[i].host, gse[i].port);
|
||||
d_printf("%s xxx %s xxx %s",gse[i].host,gse[i].port,bman.servername);
|
||||
bman.net_ai_family = gse[i].ai_family;
|
||||
#endif
|
||||
}
|
||||
} else if (menuselect >= 11 && menuselect < 19)
|
||||
/* User defined Servers */
|
||||
strncpy (bman.servername, bman.serverlist[menuselect - 11].name,
|
||||
LEN_SERVERNAME + LEN_PORT + 2);
|
||||
else if (menuselect == 20) {
|
||||
/* enter address */
|
||||
menu_get_text ("Enter Address", bman.servername, LEN_SERVERNAME + LEN_PORT + 2);}
|
||||
|
||||
|
||||
if (gserv) {
|
||||
gamesrv_browse (0);
|
||||
udp_close (sock);
|
||||
sock = -1;
|
||||
|
||||
#ifdef _WIN32
|
||||
WSACleanup ();
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
int
|
||||
gamesrv_getglist ()
|
||||
{
|
||||
int i,
|
||||
i1,
|
||||
i2,
|
||||
i3,
|
||||
y,
|
||||
nr,
|
||||
rebuild = 0;
|
||||
char buf[BUF_SIZE];
|
||||
char *pos;
|
||||
char txt[255];
|
||||
struct _sockaddr addr;
|
||||
struct game_entry entry;
|
||||
|
||||
while (udp_get (sock, buf, BUF_SIZE, &addr, PF_INET) > 0) {
|
||||
d_printf ("GOT:\n%s\n", buf);
|
||||
|
||||
if (buf[0] == 'E') {
|
||||
for (i = 0; i < MAX_GAMESRVENTRYS; i++) {
|
||||
gse[i].name[0] = 0;
|
||||
gse[i].host[0] = 0;
|
||||
gse[i].port[0] = 0;
|
||||
}
|
||||
for (i = 0; i < 10; i++ ) {
|
||||
menu[i].index = 0;
|
||||
menu[i].text[0] = 0;
|
||||
}
|
||||
sprintf (menu[0].text, "No Games found on Masterserver");
|
||||
menu[0].index = 1;
|
||||
rebuild = 1;
|
||||
if (menuselect<10) menuselect=0;
|
||||
}
|
||||
else {
|
||||
for (pos = buf; pos != 0;) {
|
||||
// go throught the incoming data
|
||||
switch (pos[0]) {
|
||||
case ('P'):
|
||||
sscanf (pos + 1, "%d,%d", &i1, &i2);
|
||||
entry.curplayers = i1;
|
||||
entry.maxplayers = i2;
|
||||
break;
|
||||
case ('V'):
|
||||
sscanf (pos + 1, "%d.%d.%d", &i1, &i2, &i3);
|
||||
entry.version.major = i1;
|
||||
entry.version.minor = i2;
|
||||
entry.version.sub = i3;
|
||||
break;
|
||||
case ('S'):
|
||||
sscanf (pos + 1, "%d,%d,%d", &i1, &i2, &i3);
|
||||
entry.state = i1;
|
||||
entry.multitype = i2;
|
||||
entry.gametype = i3;
|
||||
break;
|
||||
case ('I'):
|
||||
if (pos[1] == '4')
|
||||
entry.ai_family = PF_INET;
|
||||
else if (pos[1] == '6')
|
||||
#ifndef _WIN32
|
||||
entry.ai_family = PF_INET6;
|
||||
#else
|
||||
entry.ai_family = 0;
|
||||
#endif
|
||||
break;
|
||||
case ('N'):
|
||||
for (i = 1; (i - 1 < LEN_GAMENAME) && (pos[i] != 0)
|
||||
&& (pos[i] != '\n'); i++)
|
||||
entry.name[i - 1] = pos[i];
|
||||
entry.name[i-1]=0;
|
||||
break;
|
||||
case ('H'):
|
||||
for (i = 1; (i - 1 < LEN_SERVERNAME) && (pos[i] != 0)
|
||||
&& (pos[i] != '\n'); i++)
|
||||
entry.host[i - 1] = pos[i];
|
||||
entry.host[i-1]=0;
|
||||
break;
|
||||
case ('O'):
|
||||
for (i = 1; (i - 1 < LEN_PORT) && (pos[i] != 0)
|
||||
&& (pos[i] != '\n'); i++)
|
||||
entry.port[i - 1] = pos[i];
|
||||
entry.port[i-1]=0;
|
||||
break;
|
||||
}
|
||||
pos = strchr (pos, '\n');
|
||||
if (pos != 0)
|
||||
pos++;
|
||||
if (pos != 0 && pos[0] == 0)
|
||||
pos = 0;
|
||||
}
|
||||
nr = gamesrv_findentry (entry.host, entry.port);
|
||||
if (nr == -1) {
|
||||
nr = gamesrv_findfree ();
|
||||
if (nr == -1)
|
||||
return -1;
|
||||
}
|
||||
gse[nr] = entry;
|
||||
|
||||
|
||||
sprintf (txt, "%16s ", gse[nr].name);
|
||||
|
||||
if (gse[nr].state == GS_wait)
|
||||
sprintf (txt, "%s Wait ", txt);
|
||||
else if (gse[nr].state == GS_running || gse[nr].state == GS_ready)
|
||||
sprintf (txt, "%sRunning ", txt);
|
||||
else if (gse[nr].state == GS_update)
|
||||
sprintf (txt, "%s Update ", txt);
|
||||
|
||||
sprintf (txt, "%s%d/%d ", txt, gse[nr].curplayers, gse[nr].maxplayers);
|
||||
|
||||
if (gse[nr].ai_family == PF_INET)
|
||||
sprintf (txt, "%s %d.%d.%d IPv4", txt, gse[nr].version.major, gse[nr].version.minor,
|
||||
gse[nr].version.sub);
|
||||
else
|
||||
sprintf (txt, "%s %d.%d.%d IPv6", txt, gse[nr].version.major, gse[nr].version.minor,
|
||||
gse[nr].version.sub);
|
||||
|
||||
for (y = 0; y < 255; y++)
|
||||
menu[nr + 1].text[y] = 0;
|
||||
strncpy (menu[nr + 1].text, txt, 40);
|
||||
rebuild = 1;
|
||||
sprintf (menu[0].text, "Games on the Masterserver");
|
||||
menu[0].index = 0;
|
||||
if (menuselect == 0)
|
||||
menuselect = 1;
|
||||
menu[nr + 1].index = 1;
|
||||
}
|
||||
}
|
||||
return rebuild;
|
||||
}
|
||||
|
||||
int
|
||||
gamesrv_startudp ()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
WSADATA wsaData;
|
||||
|
||||
if (WSAStartup (MAKEWORD (1, 1), &wsaData) != 0) {
|
||||
d_printf ("WSAStartup failed.\n");
|
||||
exit (1);
|
||||
}
|
||||
#endif
|
||||
|
||||
sock = udp_server (DEFAULT_GMUDPPORT, bman.net_ai_family);
|
||||
if (sock == -1) {
|
||||
#ifdef _WIN32
|
||||
WSACleanup ();
|
||||
#endif
|
||||
}
|
||||
return sock;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* find the entry */
|
||||
int
|
||||
gamesrv_findentry (char *host, char *port)
|
||||
{
|
||||
int i,
|
||||
y;
|
||||
|
||||
for (i = 0, y = -1; (i < MAX_GAMESRVENTRYS) && (y == -1); i++) {
|
||||
if (strcmp (gse[i].host, host) == 0 && strcmp (gse[i].port, port) == 0)
|
||||
y = i;
|
||||
}
|
||||
return y;
|
||||
};
|
||||
|
||||
/* Find first free entry */
|
||||
int
|
||||
gamesrv_findfree ()
|
||||
{
|
||||
int i,
|
||||
y;
|
||||
|
||||
for (i = 0, y = -1; (y == -1) && (i < MAX_GAMESRVENTRYS); i++)
|
||||
if (gse[i].host[0] == 0)
|
||||
y = i;
|
||||
|
||||
return y;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*
|
||||
Add and Delete Browsers from Serverbrowselist
|
||||
*/
|
||||
|
||||
|
||||
void
|
||||
gamesrv_browse (int i)
|
||||
{
|
||||
char data[255];
|
||||
struct _sockaddr addr;
|
||||
char host[LEN_SERVERNAME];
|
||||
char port[LEN_PORT];
|
||||
|
||||
d_printf ("** Notify Browser Master Server\n");
|
||||
if (i)
|
||||
sprintf (data, "B\n");
|
||||
else
|
||||
sprintf (data, "E\n");
|
||||
|
||||
network_server_port (bman.gamemaster, host, LEN_SERVERNAME, port, LEN_PORT);
|
||||
dns_filladdr (host, LEN_SERVERNAME, port, LEN_PORT, bman.net_ai_family, &addr);
|
||||
udp_send (sock, data, strlen (data), &addr, bman.net_ai_family);
|
||||
d_printf ("Send: %s\n", data);
|
||||
};
|
||||
|
||||
/*
|
||||
The Server should know that we quit.
|
||||
Delete every entry from our client.
|
||||
*/
|
||||
|
||||
|
||||
void
|
||||
gamesrv_quit ()
|
||||
{
|
||||
char data[255];
|
||||
struct _sockaddr addr;
|
||||
char host[LEN_SERVERNAME];
|
||||
char port[LEN_PORT];
|
||||
int len;
|
||||
|
||||
d_printf ("** Notify GameMaster Server\n");
|
||||
sprintf (data, "D\n");
|
||||
|
||||
len = 4;
|
||||
|
||||
network_server_port (bman.gamemaster, host, LEN_SERVERNAME, port, LEN_PORT);
|
||||
dns_filladdr (host, LEN_SERVERNAME, port, LEN_PORT, bman.net_ai_family, &addr);
|
||||
|
||||
udp_send (bman.sock, data, len, &addr, bman.net_ai_family);
|
||||
d_printf ("** Send \n\n%s\n\n", data);
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
send the mode of the game from the current bman.state and bman.gamename
|
||||
parameter
|
||||
*/
|
||||
void
|
||||
gamesrv_sendmode (int maxplayer, int curplayers)
|
||||
{
|
||||
char data[255];
|
||||
int len = 0;
|
||||
struct _sockaddr addr;
|
||||
char host[LEN_SERVERNAME];
|
||||
char port[LEN_PORT];
|
||||
|
||||
d_printf ("** Notify GameMaster Server\n");
|
||||
|
||||
sprintf (data, "AV%s\n", VERSION);
|
||||
sprintf (data, "%sP%d,%d\n", data, curplayers, maxplayer);
|
||||
sprintf (data, "%sS%d,%d,%d\n", data, bman.state, bman.multitype, bman.gametype);
|
||||
if (bman.net_ai_family == PF_INET)
|
||||
sprintf (data, "%sI4\n", data);
|
||||
else
|
||||
sprintf (data, "%sI6\n", data);
|
||||
sprintf (data, "%sN%s\n", data, bman.gamename);
|
||||
|
||||
len = strlen (data);
|
||||
|
||||
network_server_port (bman.gamemaster, host, LEN_SERVERNAME, port, LEN_PORT);
|
||||
dns_filladdr (host, LEN_SERVERNAME, port, LEN_PORT, bman.net_ai_family, &addr);
|
||||
|
||||
host[0] = 0;
|
||||
port[0] = 0;
|
||||
dns_filladdr (host, LEN_SERVERNAME, port, LEN_PORT, bman.net_ai_family, &addr);
|
||||
|
||||
udp_send (bman.sock, data, len, &addr, bman.net_ai_family);
|
||||
d_printf ("** Send To (%s[:%s])\n\n%s\n\n", host, port, data);
|
||||
};
|
||||
|
||||
|
||||
void
|
||||
gamesrv_sendchat (char *text)
|
||||
{
|
||||
char data[255];
|
||||
struct _sockaddr addr;
|
||||
char host[LEN_SERVERNAME];
|
||||
char port[LEN_PORT];
|
||||
|
||||
network_server_port (bman.gamemaster, host, LEN_SERVERNAME, port, LEN_PORT);
|
||||
dns_filladdr (host, LEN_SERVERNAME, port, LEN_PORT, bman.net_ai_family, &addr);
|
||||
|
||||
sprintf (data, "C%s", text);
|
||||
|
||||
udp_send (bman.sock, data, strlen (data), &addr, bman.net_ai_family);
|
||||
};
|
||||
|
@ -1,30 +1,30 @@
|
||||
/*
|
||||
include file for the gamesrv.c file
|
||||
*/
|
||||
|
||||
struct game_entry {
|
||||
char host[LEN_SERVERNAME];
|
||||
char port[LEN_PORT];
|
||||
char name[LEN_GAMENAME];
|
||||
struct _version {
|
||||
unsigned char major;
|
||||
unsigned char minor;
|
||||
unsigned char sub;
|
||||
} version;
|
||||
signed char curplayers;
|
||||
signed char maxplayers;
|
||||
signed char ai_family;
|
||||
unsigned char state;
|
||||
unsigned char multitype;
|
||||
unsigned char gametype;
|
||||
};
|
||||
|
||||
extern int gamesrv_findentry (char *host, char *port);
|
||||
extern int gamesrv_findfree ();
|
||||
extern int gamesrv_startudp ();
|
||||
extern int gamesrv_getglist ();
|
||||
extern void gamesrv_getserver ();
|
||||
extern void gamesrv_quit ();
|
||||
extern void gamesrv_browse ();
|
||||
extern void gamesrv_sendmode (int maxplayer, int curplayers);
|
||||
extern void gamesrv_sendchat (char *text);
|
||||
/*
|
||||
include file for the gamesrv.c file
|
||||
*/
|
||||
|
||||
struct game_entry {
|
||||
char host[LEN_SERVERNAME];
|
||||
char port[LEN_PORT];
|
||||
char name[LEN_GAMENAME];
|
||||
struct _version {
|
||||
unsigned char major;
|
||||
unsigned char minor;
|
||||
unsigned char sub;
|
||||
} version;
|
||||
signed char curplayers;
|
||||
signed char maxplayers;
|
||||
signed char ai_family;
|
||||
unsigned char state;
|
||||
unsigned char multitype;
|
||||
unsigned char gametype;
|
||||
};
|
||||
|
||||
extern int gamesrv_findentry (char *host, char *port);
|
||||
extern int gamesrv_findfree ();
|
||||
extern int gamesrv_startudp ();
|
||||
extern int gamesrv_getglist ();
|
||||
extern void gamesrv_getserver ();
|
||||
extern void gamesrv_quit ();
|
||||
extern void gamesrv_browse ();
|
||||
extern void gamesrv_sendmode (int maxplayer, int curplayers);
|
||||
extern void gamesrv_sendchat (char *text);
|
||||
|
@ -1,95 +1,95 @@
|
||||
#ifndef _GFX_H_
|
||||
|
||||
#define _GFX_H_
|
||||
|
||||
#define SCALE_MAXRES 10000
|
||||
#define GFX_IMGSIZE 64
|
||||
#define GFX_PLAYERIMGSIZE_Y 128
|
||||
|
||||
#include "basic.h"
|
||||
|
||||
struct __gfxani {
|
||||
SDL_Surface *image;
|
||||
int frames; // how many single frames (image -> heigh / (1.5 * gamestyle.height))
|
||||
} typedef _gfxani;
|
||||
|
||||
|
||||
struct __gfxplayer {
|
||||
_gfxani ani;
|
||||
_point offset;
|
||||
_point size; // height of the image.. needed for faster access.
|
||||
_point smal_size; // smal size of the image
|
||||
SDL_Surface *smal_image; // smal size of the animation
|
||||
} typedef _gfxplayer;
|
||||
|
||||
|
||||
struct __gfxfont {
|
||||
SDL_Surface *image;
|
||||
_point size;
|
||||
} typedef _gfxfont;
|
||||
|
||||
|
||||
struct __gfx {
|
||||
SDL_Surface *screen;
|
||||
_point res; // resolution
|
||||
_point block; // block size
|
||||
short int bpp; // bits per pixel
|
||||
|
||||
unsigned char fullscreen;
|
||||
|
||||
_point offset; // where the game field starts
|
||||
|
||||
_gfxfont font;
|
||||
_gfxfont font1;
|
||||
|
||||
_gfxplayer players[MAX_PLAYERS];
|
||||
short int postab[256]; // table of points where we need to go to.
|
||||
|
||||
_gfxani field[FT_max]; // the field animations
|
||||
_gfxani fire; // fire (explostion)
|
||||
_gfxani bomb; // bomb animation
|
||||
_gfxani ill; // sick animation above the player
|
||||
|
||||
_gfxani menuselect; // The Menu Select GFX (the bomb ?)
|
||||
|
||||
int random_tileset; // random selecting of a tileset
|
||||
char tileset[LEN_TILESETNAME]; // name of the tileset
|
||||
|
||||
SDL_Surface *logo;
|
||||
} typedef _gfx;
|
||||
|
||||
extern _gfx gfx;
|
||||
|
||||
|
||||
// everything what is in gfx.c
|
||||
extern void gfx_loaddata ();
|
||||
extern void gfx_UpdateRects ();
|
||||
extern void gfx_AddUpdateRect (int x, int y, int w, int h);
|
||||
extern void redraw_logo (int x, int y, int w, int h);
|
||||
extern void draw_logo ();
|
||||
extern void gfx_init (); // Load Base Image Data
|
||||
extern void gfx_game_init (); // Load Game Data
|
||||
extern void gfx_game_shutdown (); // Free Image Data
|
||||
extern void gfx_shutdown (); //
|
||||
extern void getRGBpixel (SDL_Surface *surface, int x, int y, int *R, int *G, int *B);
|
||||
extern Uint32 getpixel(SDL_Surface *surface, int x, int y);
|
||||
extern void putpixel(SDL_Surface *surface, int x, int y, Uint32 pixel);
|
||||
extern void scale (short int *dpattern, short int x, short int y);
|
||||
extern SDL_Surface *scale_image (SDL_Surface * orginal, int newx, int newy);
|
||||
extern void shade_pixel(SDL_Surface *s, int x, int y, int c);
|
||||
extern void draw_shadefield (SDL_Surface *s, SDL_Rect *rec, int c);
|
||||
extern int gfx_locksurface (SDL_Surface *surface);
|
||||
extern void gfx_unlocksurface (SDL_Surface *surface);
|
||||
extern void redraw_logo_shaded (int x, int y, int w, int h, int c);
|
||||
extern void gfx_load_players (int sx, int sy);
|
||||
extern void gfx_free_players ();
|
||||
extern void gfx_load_tileset (char *tileset);
|
||||
extern void gfx_free_tileset ();
|
||||
extern SDL_Surface *makegray_image (SDL_Surface *org);
|
||||
extern SDL_Surface *gfx_copyscreen (SDL_Rect *wnd);
|
||||
|
||||
// declared functions in font.c
|
||||
extern void draw_text (int x, int y, char *text, int white);
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef _GFX_H_
|
||||
|
||||
#define _GFX_H_
|
||||
|
||||
#define SCALE_MAXRES 10000
|
||||
#define GFX_IMGSIZE 64
|
||||
#define GFX_PLAYERIMGSIZE_Y 128
|
||||
|
||||
#include "basic.h"
|
||||
|
||||
struct __gfxani {
|
||||
SDL_Surface *image;
|
||||
int frames; // how many single frames (image -> heigh / (1.5 * gamestyle.height))
|
||||
} typedef _gfxani;
|
||||
|
||||
|
||||
struct __gfxplayer {
|
||||
_gfxani ani;
|
||||
_point offset;
|
||||
_point size; // height of the image.. needed for faster access.
|
||||
_point smal_size; // smal size of the image
|
||||
SDL_Surface *smal_image; // smal size of the animation
|
||||
} typedef _gfxplayer;
|
||||
|
||||
|
||||
struct __gfxfont {
|
||||
SDL_Surface *image;
|
||||
_point size;
|
||||
} typedef _gfxfont;
|
||||
|
||||
|
||||
struct __gfx {
|
||||
SDL_Surface *screen;
|
||||
_point res; // resolution
|
||||
_point block; // block size
|
||||
short int bpp; // bits per pixel
|
||||
|
||||
unsigned char fullscreen;
|
||||
|
||||
_point offset; // where the game field starts
|
||||
|
||||
_gfxfont font;
|
||||
_gfxfont font1;
|
||||
|
||||
_gfxplayer players[MAX_PLAYERS];
|
||||
short int postab[256]; // table of points where we need to go to.
|
||||
|
||||
_gfxani field[FT_max]; // the field animations
|
||||
_gfxani fire; // fire (explostion)
|
||||
_gfxani bomb; // bomb animation
|
||||
_gfxani ill; // sick animation above the player
|
||||
|
||||
_gfxani menuselect; // The Menu Select GFX (the bomb ?)
|
||||
|
||||
int random_tileset; // random selecting of a tileset
|
||||
char tileset[LEN_TILESETNAME]; // name of the tileset
|
||||
|
||||
SDL_Surface *logo;
|
||||
} typedef _gfx;
|
||||
|
||||
extern _gfx gfx;
|
||||
|
||||
|
||||
// everything what is in gfx.c
|
||||
extern void gfx_loaddata ();
|
||||
extern void gfx_UpdateRects ();
|
||||
extern void gfx_AddUpdateRect (int x, int y, int w, int h);
|
||||
extern void redraw_logo (int x, int y, int w, int h);
|
||||
extern void draw_logo ();
|
||||
extern void gfx_init (); // Load Base Image Data
|
||||
extern void gfx_game_init (); // Load Game Data
|
||||
extern void gfx_game_shutdown (); // Free Image Data
|
||||
extern void gfx_shutdown (); //
|
||||
extern void getRGBpixel (SDL_Surface *surface, int x, int y, int *R, int *G, int *B);
|
||||
extern Uint32 getpixel(SDL_Surface *surface, int x, int y);
|
||||
extern void putpixel(SDL_Surface *surface, int x, int y, Uint32 pixel);
|
||||
extern void scale (short int *dpattern, short int x, short int y);
|
||||
extern SDL_Surface *scale_image (SDL_Surface * orginal, int newx, int newy);
|
||||
extern void shade_pixel(SDL_Surface *s, int x, int y, int c);
|
||||
extern void draw_shadefield (SDL_Surface *s, SDL_Rect *rec, int c);
|
||||
extern int gfx_locksurface (SDL_Surface *surface);
|
||||
extern void gfx_unlocksurface (SDL_Surface *surface);
|
||||
extern void redraw_logo_shaded (int x, int y, int w, int h, int c);
|
||||
extern void gfx_load_players (int sx, int sy);
|
||||
extern void gfx_free_players ();
|
||||
extern void gfx_load_tileset (char *tileset);
|
||||
extern void gfx_free_tileset ();
|
||||
extern SDL_Surface *makegray_image (SDL_Surface *org);
|
||||
extern SDL_Surface *gfx_copyscreen (SDL_Rect *wnd);
|
||||
|
||||
// declared functions in font.c
|
||||
extern void draw_text (int x, int y, char *text, int white);
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -1,55 +1,55 @@
|
||||
/* keyborad handling for text fields */
|
||||
|
||||
#include <SDL.h>
|
||||
#include "keybinput.h"
|
||||
|
||||
static int keybinput_oldkey = 0;
|
||||
|
||||
void keybinput_new (_keybinput *ki) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 255; i++)
|
||||
ki->text[i] = 0;
|
||||
ki->curpos = 0;
|
||||
ki->len = 0;
|
||||
}
|
||||
|
||||
|
||||
int keybinput_loop (_keybinput *ki, SDL_Event *event) {
|
||||
int key = 0, keyu = 0;
|
||||
|
||||
ki->changed = 0;
|
||||
|
||||
if (event->type == SDL_KEYUP)
|
||||
keybinput_oldkey = 0;
|
||||
|
||||
if (event->type == SDL_KEYDOWN && keybinput_oldkey != event->key.keysym.sym) {
|
||||
key = keybinput_oldkey = event->key.keysym.sym;
|
||||
keyu = event->key.keysym.unicode;
|
||||
|
||||
if (key == 8) { // BACKSPACE
|
||||
if (ki->curpos > 0) {
|
||||
ki->curpos--;
|
||||
ki->text[ki->curpos] = 0;
|
||||
ki->changed = 1;
|
||||
}
|
||||
}
|
||||
else if ((keyu >= 32 && keyu <= 126) || (keyu >= 128 && keyu <= 255)) { // International keyboard support
|
||||
if (ki->curpos < 255) {
|
||||
ki->text[ki->curpos++] = event->key.keysym.unicode;
|
||||
ki->text[ki->curpos] = 0;
|
||||
ki->changed = 1;
|
||||
}
|
||||
}
|
||||
ki->len = strlen (ki->text);
|
||||
}
|
||||
|
||||
if (key == SDLK_RETURN)
|
||||
return 1;
|
||||
|
||||
if (key == SDLK_ESCAPE)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* keyborad handling for text fields */
|
||||
|
||||
#include <SDL.h>
|
||||
#include "keybinput.h"
|
||||
|
||||
static int keybinput_oldkey = 0;
|
||||
|
||||
void keybinput_new (_keybinput *ki) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 255; i++)
|
||||
ki->text[i] = 0;
|
||||
ki->curpos = 0;
|
||||
ki->len = 0;
|
||||
}
|
||||
|
||||
|
||||
int keybinput_loop (_keybinput *ki, SDL_Event *event) {
|
||||
int key = 0, keyu = 0;
|
||||
|
||||
ki->changed = 0;
|
||||
|
||||
if (event->type == SDL_KEYUP)
|
||||
keybinput_oldkey = 0;
|
||||
|
||||
if (event->type == SDL_KEYDOWN && keybinput_oldkey != event->key.keysym.sym) {
|
||||
key = keybinput_oldkey = event->key.keysym.sym;
|
||||
keyu = event->key.keysym.unicode;
|
||||
|
||||
if (key == 8) { // BACKSPACE
|
||||
if (ki->curpos > 0) {
|
||||
ki->curpos--;
|
||||
ki->text[ki->curpos] = 0;
|
||||
ki->changed = 1;
|
||||
}
|
||||
}
|
||||
else if ((keyu >= 32 && keyu <= 126) || (keyu >= 128 && keyu <= 255)) { // International keyboard support
|
||||
if (ki->curpos < 255) {
|
||||
ki->text[ki->curpos++] = event->key.keysym.unicode;
|
||||
ki->text[ki->curpos] = 0;
|
||||
ki->changed = 1;
|
||||
}
|
||||
}
|
||||
ki->len = strlen (ki->text);
|
||||
}
|
||||
|
||||
if (key == SDLK_RETURN)
|
||||
return 1;
|
||||
|
||||
if (key == SDLK_ESCAPE)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1,15 +1,15 @@
|
||||
|
||||
#ifndef _KEYBINPUT_H_
|
||||
#define _KEYBINPUT_H_
|
||||
|
||||
struct __keybinput {
|
||||
char text[255];
|
||||
short int curpos;
|
||||
short int len;
|
||||
char changed;
|
||||
} typedef _keybinput;
|
||||
|
||||
extern void keybinput_new (_keybinput *ki);
|
||||
extern int keybinput_loop (_keybinput *ki, SDL_Event *event);
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef _KEYBINPUT_H_
|
||||
#define _KEYBINPUT_H_
|
||||
|
||||
struct __keybinput {
|
||||
char text[255];
|
||||
short int curpos;
|
||||
short int len;
|
||||
char changed;
|
||||
} typedef _keybinput;
|
||||
|
||||
extern void keybinput_new (_keybinput *ki);
|
||||
extern int keybinput_loop (_keybinput *ki, SDL_Event *event);
|
||||
|
||||
#endif
|
||||
|
@ -1,75 +1,75 @@
|
||||
|
||||
#include "bomberclone.h"
|
||||
#include "network.h"
|
||||
#include "gfx.h"
|
||||
#ifndef _WIN32
|
||||
#include "../config.h"
|
||||
#endif
|
||||
|
||||
_bomberclone bman; // Holds GameData
|
||||
Uint32 timestamp; // timestamp
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
int menuselect = 0;
|
||||
_menu menu[] = {
|
||||
{0, "Singleplayer"},
|
||||
{1, "Multiplayer"},
|
||||
{2, "Configuration"},
|
||||
{3, "Quit Game"},
|
||||
{-1, ""}
|
||||
};
|
||||
char text[255];
|
||||
|
||||
if (SDL_Init (SDL_INIT_VIDEO) != 0) {
|
||||
d_printf ("Unable to init SDL: %s\n", SDL_GetError ());
|
||||
return (1);
|
||||
}
|
||||
|
||||
sprintf (text,"Bomberclone %s", VERSION);
|
||||
SDL_WM_SetCaption(text , NULL);
|
||||
SDL_EnableUNICODE(1);
|
||||
|
||||
game_init (argv);
|
||||
d_printf ("\n\n ***** Bomberclone Version %s \n\n",VERSION);
|
||||
if (ReadConfig()) {
|
||||
gfx_init ();
|
||||
menu_get_text ("Please You Playername", bman.playername, LEN_PLAYERNAME-1);
|
||||
bman.playername[LEN_PLAYERNAME-1] = 0;
|
||||
} else {
|
||||
gfx_init ();
|
||||
if (bman.askplayername)
|
||||
menu_get_text ("Please You Playername", bman.playername, LEN_PLAYERNAME);
|
||||
}
|
||||
ReadPrgArgs (argc, argv);
|
||||
|
||||
sprintf(text,"Welcome to BomberClone");
|
||||
while (menuselect != -1 && bman.state != GS_quit) {
|
||||
|
||||
menuselect = menu_loop (text , menu, menuselect);
|
||||
|
||||
switch (menuselect) {
|
||||
case (0) : // Singleplayer
|
||||
single_game_new ();
|
||||
single_create_ai ();
|
||||
gfx_game_init ();
|
||||
game_loop ();
|
||||
gfx_game_shutdown ();
|
||||
break;
|
||||
case (1) : // Multiplayer
|
||||
netmenu();
|
||||
break;
|
||||
case (2) : // Options
|
||||
configuration ();
|
||||
break;
|
||||
case (3) : // Quit
|
||||
bman.state = GS_quit;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
gfx_shutdown ();
|
||||
|
||||
return 0;
|
||||
};
|
||||
|
||||
#include "bomberclone.h"
|
||||
#include "network.h"
|
||||
#include "gfx.h"
|
||||
#ifndef _WIN32
|
||||
#include "../config.h"
|
||||
#endif
|
||||
|
||||
_bomberclone bman; // Holds GameData
|
||||
Uint32 timestamp; // timestamp
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
int menuselect = 0;
|
||||
_menu menu[] = {
|
||||
{0, "Singleplayer"},
|
||||
{1, "Multiplayer"},
|
||||
{2, "Configuration"},
|
||||
{3, "Quit Game"},
|
||||
{-1, ""}
|
||||
};
|
||||
char text[255];
|
||||
|
||||
if (SDL_Init (SDL_INIT_VIDEO) != 0) {
|
||||
d_printf ("Unable to init SDL: %s\n", SDL_GetError ());
|
||||
return (1);
|
||||
}
|
||||
|
||||
sprintf (text,"Bomberclone %s", VERSION);
|
||||
SDL_WM_SetCaption(text , NULL);
|
||||
SDL_EnableUNICODE(1);
|
||||
|
||||
game_init (argv);
|
||||
d_printf ("\n\n ***** Bomberclone Version %s \n\n",VERSION);
|
||||
if (ReadConfig()) {
|
||||
gfx_init ();
|
||||
menu_get_text ("Please You Playername", bman.playername, LEN_PLAYERNAME-1);
|
||||
bman.playername[LEN_PLAYERNAME-1] = 0;
|
||||
} else {
|
||||
gfx_init ();
|
||||
if (bman.askplayername)
|
||||
menu_get_text ("Please You Playername", bman.playername, LEN_PLAYERNAME);
|
||||
}
|
||||
ReadPrgArgs (argc, argv);
|
||||
|
||||
sprintf(text,"Welcome to BomberClone");
|
||||
while (menuselect != -1 && bman.state != GS_quit) {
|
||||
|
||||
menuselect = menu_loop (text , menu, menuselect);
|
||||
|
||||
switch (menuselect) {
|
||||
case (0) : // Singleplayer
|
||||
single_game_new ();
|
||||
single_create_ai ();
|
||||
gfx_game_init ();
|
||||
game_loop ();
|
||||
gfx_game_shutdown ();
|
||||
break;
|
||||
case (1) : // Multiplayer
|
||||
netmenu();
|
||||
break;
|
||||
case (2) : // Options
|
||||
configuration ();
|
||||
break;
|
||||
case (3) : // Quit
|
||||
bman.state = GS_quit;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
gfx_shutdown ();
|
||||
|
||||
return 0;
|
||||
};
|
||||
|
@ -1,366 +1,366 @@
|
||||
/*
|
||||
multiwait.c - this manages only the network screen where
|
||||
everyone have to select it's players and where even the basic chat is inside
|
||||
*/
|
||||
|
||||
#include "bomberclone.h"
|
||||
#include "network.h"
|
||||
#include "packets.h"
|
||||
#include "gamesrv.h"
|
||||
#include "gfx.h"
|
||||
#include "chat.h"
|
||||
|
||||
#define MW_IS_GFX_SELECT(__gfx_nr,__result) for (__result = (MAX_PLAYERS-1); (bman.players[__result].gfx_nr != __gfx_nr) && (__result >= 0); __result--);
|
||||
|
||||
extern int UpdateRects_nr;
|
||||
|
||||
static int mw_y = 0,
|
||||
mw_frame = 0,
|
||||
mw_frameto = 0;
|
||||
static SDL_Surface *mw_plgfx[MAX_PLAYERS];
|
||||
|
||||
|
||||
/* this will load some graphics and so other stuff */
|
||||
void
|
||||
mw_init ()
|
||||
{
|
||||
int i;
|
||||
SDL_Surface *tmp;
|
||||
draw_logo ();
|
||||
|
||||
menu_displaytext ("Please Wait", "Loading GFX Data", 64, 128, 64);
|
||||
|
||||
gfx_load_players (32, 32);
|
||||
network_loop ();
|
||||
for (i = 0; i < MAX_PLAYERS; i++) {
|
||||
network_loop ();
|
||||
tmp = makegray_image (gfx.players[i].ani.image);
|
||||
network_loop ();
|
||||
mw_plgfx[i] = SDL_DisplayFormat (tmp);
|
||||
network_loop ();
|
||||
SDL_FreeSurface (tmp);
|
||||
network_loop ();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/* free all grafics */
|
||||
void
|
||||
mw_shutdown ()
|
||||
{
|
||||
int i;
|
||||
|
||||
chat_show (-1, -1, -1, -1);
|
||||
|
||||
menu_displaytext ("Please Wait", "Freeing GFX Data", 64, 128, 64);
|
||||
|
||||
gfx_free_players ();
|
||||
for (i = 0; i < MAX_PLAYERS; i++)
|
||||
SDL_FreeSurface (mw_plgfx[i]);
|
||||
};
|
||||
|
||||
|
||||
void
|
||||
mw_wait_for_connect ()
|
||||
{
|
||||
menu_displaytext ("Please Wait", "Wait For connection", 64, 128, 64);
|
||||
};
|
||||
|
||||
|
||||
void
|
||||
mw_draw_status ()
|
||||
{
|
||||
int pnr,
|
||||
x,
|
||||
x1,
|
||||
y,
|
||||
px;
|
||||
char text[255];
|
||||
SDL_Rect src,
|
||||
dest;
|
||||
|
||||
/* Draw Player List */
|
||||
/* 1. the head */
|
||||
px = gfx.res.x / 320;
|
||||
x = (gfx.res.x - px * 320) / 2;
|
||||
|
||||
for (pnr = 0; pnr < px; pnr++)
|
||||
draw_text (pnr * 320 + x, 24, " Wins Points", 1);
|
||||
|
||||
/* 2. the names with points */
|
||||
for (x1 = pnr = 0, y = 48; pnr < MAX_PLAYERS; pnr++) {
|
||||
redraw_logo (x1 * 320, y - 4, 320, 32);
|
||||
if (bman.players[pnr].gfx_nr != -1 && PS_IS_used (bman.players[pnr].state)) {
|
||||
src.x = 3 * bman.players[pnr].gfx->smal_size.x;
|
||||
src.y = 0;
|
||||
src.w = dest.w = bman.players[pnr].gfx->smal_size.x;
|
||||
src.h = dest.h = bman.players[pnr].gfx->smal_size.y;
|
||||
|
||||
dest.x = x1 * 320;
|
||||
dest.y = y - 4;
|
||||
|
||||
SDL_BlitSurface (bman.players[pnr].gfx->smal_image, &src, gfx.screen, &dest);
|
||||
}
|
||||
|
||||
sprintf (text, " %10s %2d %2d", bman.players[pnr].name, bman.players[pnr].wins,
|
||||
bman.players[pnr].points);
|
||||
if (PS_IS_used (bman.players[pnr].state)) {
|
||||
|
||||
if (bman.lastwinner == pnr)
|
||||
draw_text (x + x1 * 320, y, text, 1);
|
||||
else
|
||||
draw_text (x + x1 * 320, y, text, 0);
|
||||
}
|
||||
x1++;
|
||||
if (x1 >= px) {
|
||||
y += 32;
|
||||
x1 = 0;
|
||||
}
|
||||
if (pnr == MAX_PLAYERS - 1 && x1 != 0)
|
||||
y += 32;
|
||||
}
|
||||
|
||||
mw_y = y;
|
||||
};
|
||||
|
||||
|
||||
void
|
||||
mw_draw_gfxselect (int selgfx)
|
||||
{
|
||||
int i,
|
||||
select,
|
||||
xstep;
|
||||
SDL_Rect src,
|
||||
dest;
|
||||
|
||||
xstep = gfx.res.x / MAX_PLAYERS;
|
||||
|
||||
if (bman.players[bman.p_nr].gfx_nr == -1) {
|
||||
/* draw selection */
|
||||
for (i = 0; i < MAX_PLAYERS; i++) {
|
||||
dest.w = src.w = gfx.players[i].size.x;
|
||||
dest.h = src.h = gfx.players[i].size.y;
|
||||
|
||||
dest.x = i * xstep + (xstep >> 1) - (gfx.players[i].size.x >> 1);
|
||||
dest.y = mw_y + 8;
|
||||
|
||||
redraw_logo (dest.x, dest.y, dest.w, dest.h);
|
||||
|
||||
src.x = 3 * gfx.players[i].size.x;
|
||||
if (i == selgfx)
|
||||
src.y = mw_frame * gfx.players[i].size.y;
|
||||
else
|
||||
src.y = 0;
|
||||
|
||||
MW_IS_GFX_SELECT (i, select);
|
||||
|
||||
if (select >= MAX_PLAYERS || select < 0) {
|
||||
/* this player have not been selected */
|
||||
if (selgfx == i) {
|
||||
mw_frameto--;
|
||||
|
||||
if (mw_frameto <= 0 || mw_frameto > ANI_PLAYERTIMEOUT) {
|
||||
mw_frameto = ANI_PLAYERTIMEOUT;
|
||||
mw_frame++;
|
||||
}
|
||||
|
||||
if (mw_frame >= gfx.players[i].ani.frames || mw_frame < 0) {
|
||||
mw_frameto = ANI_PLAYERTIMEOUT;
|
||||
mw_frame = 0;
|
||||
}
|
||||
|
||||
SDL_BlitSurface (gfx.players[i].ani.image, &src, gfx.screen, &dest);
|
||||
}
|
||||
else
|
||||
SDL_BlitSurface (mw_plgfx[i], &src, gfx.screen, &dest);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* draw selected players */
|
||||
for (i = 0; i < MAX_PLAYERS; i++) {
|
||||
dest.w = src.w = gfx.players[i].size.x;
|
||||
dest.h = src.h = gfx.players[i].size.y;
|
||||
|
||||
dest.x = i * xstep + (xstep >> 1) - (gfx.players[i].size.x >> 1);
|
||||
dest.y = mw_y + 8;
|
||||
|
||||
redraw_logo (dest.x, dest.y, dest.w, dest.h);
|
||||
|
||||
src.x = 3 * gfx.players[i].size.x;
|
||||
if (i == selgfx)
|
||||
src.y = mw_frame * gfx.players[i].size.y;
|
||||
else
|
||||
src.y = 0;
|
||||
|
||||
MW_IS_GFX_SELECT (i, select);
|
||||
|
||||
if (select < MAX_PLAYERS && select >= 0) {
|
||||
/* this player have been selected */
|
||||
if (bman.players[bman.p_nr].gfx_nr == i)
|
||||
SDL_BlitSurface (gfx.players[i].ani.image, &src, gfx.screen, &dest);
|
||||
else
|
||||
SDL_BlitSurface (mw_plgfx[i], &src, gfx.screen, &dest);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mw_y += 8 + gfx.players[0].size.y;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
mw_draw_chat ()
|
||||
{
|
||||
if (chat.visible == 0) {
|
||||
chat_show (16, mw_y + 16, gfx.res.x - 16, gfx.res.y - 32);
|
||||
chat_addline ("Press [STRG] or [CTRL] - to select a player");
|
||||
if (GT_MP_PTPM)
|
||||
chat_addline ("F4 - to start the game");
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/* the loop itself */
|
||||
void
|
||||
wait_for_players ()
|
||||
{
|
||||
SDL_Event event;
|
||||
Uint8 *keys;
|
||||
int done = 0,
|
||||
ready = 0,
|
||||
keypressed = 0,
|
||||
i,
|
||||
selgfx = 0;
|
||||
|
||||
mw_init ();
|
||||
draw_logo ();
|
||||
|
||||
while (!done && bman.state == GS_wait) {
|
||||
|
||||
i = bman.p_nr;
|
||||
if (network_loop () < 0) {
|
||||
done = 1;
|
||||
bman.p_nr = -1;
|
||||
}
|
||||
if (i != bman.p_nr) /* clean the screen after we got our playernumber */
|
||||
draw_logo ();
|
||||
|
||||
/* check if all players are ready, and more as one player is connected */
|
||||
if (GT_MP_PTPM)
|
||||
for (ready = 0, i = 0; i < MAX_PLAYERS; i++)
|
||||
if (PS_IS_playing (bman.players[i].state))
|
||||
ready++;
|
||||
if (ready > 1)
|
||||
ready = 1;
|
||||
else
|
||||
ready = 0;
|
||||
|
||||
/* draw the screeninformations */
|
||||
if (bman.p_nr == -1) { /* we have no connect yet */
|
||||
mw_wait_for_connect ();
|
||||
SDL_Flip (gfx.screen);
|
||||
}
|
||||
else { /* we have a connect so draw status */
|
||||
mw_draw_status ();
|
||||
mw_draw_gfxselect (selgfx);
|
||||
gfx_AddUpdateRect (0, 0, gfx.res.x, mw_y);
|
||||
mw_draw_chat ();
|
||||
}
|
||||
|
||||
gfx_UpdateRects ();
|
||||
|
||||
/* do the keyboard handling */
|
||||
if (SDL_PollEvent (&event) != 0)
|
||||
switch (event.type) {
|
||||
case (SDL_QUIT):
|
||||
bman.state = GS_quit;
|
||||
bman.p_nr = -1;
|
||||
done = 1;
|
||||
}
|
||||
|
||||
keys = SDL_GetKeyState (NULL);
|
||||
|
||||
if (keys[SDLK_ESCAPE] && event.type == SDL_KEYDOWN) {
|
||||
/* we want to quit */
|
||||
done = 1;
|
||||
bman.p_nr = -1;
|
||||
keypressed = 1;
|
||||
bman.state = GS_startup;
|
||||
}
|
||||
|
||||
if (bman.p_nr != -1) {
|
||||
|
||||
if (keys[SDLK_DOWN] && (!keypressed)) {
|
||||
}
|
||||
|
||||
if (keys[SDLK_UP] && (!keypressed)) {
|
||||
}
|
||||
|
||||
if (keys[SDLK_LEFT] && (!keypressed) && bman.players[bman.p_nr].gfx_nr == -1) {
|
||||
i = 0;
|
||||
while (selgfx < 0 || selgfx >= MAX_PLAYERS || i != -1) {
|
||||
selgfx--;
|
||||
if (selgfx < 0)
|
||||
selgfx = MAX_PLAYERS - 1;
|
||||
MW_IS_GFX_SELECT (selgfx, i);
|
||||
}
|
||||
}
|
||||
|
||||
if (keys[SDLK_RIGHT] && (!keypressed) && bman.players[bman.p_nr].gfx_nr == -1) {
|
||||
i = 0;
|
||||
while (selgfx < 0 || selgfx >= MAX_PLAYERS || i != -1) {
|
||||
selgfx++;
|
||||
if (selgfx >= MAX_PLAYERS)
|
||||
selgfx = 0;
|
||||
MW_IS_GFX_SELECT (selgfx, i);
|
||||
}
|
||||
}
|
||||
|
||||
/* just make sure this player is not selected twice */
|
||||
if (bman.players[bman.p_nr].gfx_nr == -1) {
|
||||
MW_IS_GFX_SELECT (selgfx, i);
|
||||
while (selgfx < 0 || selgfx >= MAX_PLAYERS || i != -1) {
|
||||
selgfx++;
|
||||
if (selgfx >= MAX_PLAYERS)
|
||||
selgfx = 0;
|
||||
MW_IS_GFX_SELECT (selgfx, i);
|
||||
}
|
||||
}
|
||||
|
||||
if ((keys[SDLK_LCTRL] || keys[SDLK_RCTRL]) && (!keypressed)) {
|
||||
if (bman.players[bman.p_nr].gfx_nr == -1) {
|
||||
/* select player */
|
||||
bman.players[bman.p_nr].gfx_nr = selgfx;
|
||||
}
|
||||
else {
|
||||
/* deselect player */
|
||||
bman.players[bman.p_nr].gfx_nr = -1;
|
||||
}
|
||||
net_change_playerid (bman.p_nr, 1);
|
||||
}
|
||||
|
||||
if ((GT_MP_PTPM) && ready && keys[SDLK_F4] && (!keypressed)) {
|
||||
done = 1;
|
||||
}
|
||||
|
||||
if ((GT_MP_PTPM) && keys[SDLK_F5] && (!keypressed)) {
|
||||
/* Map modification */
|
||||
menu_get_text ("Enter the path of a field file", bman.fieldpath, 30);
|
||||
draw_logo ();
|
||||
chat_drawbox ();
|
||||
}
|
||||
|
||||
chat_loop (&event);
|
||||
}
|
||||
|
||||
if (event.type == SDL_KEYUP)
|
||||
keypressed = 0;
|
||||
else if (event.type == SDL_KEYDOWN)
|
||||
keypressed = 1;
|
||||
|
||||
s_delay (25);
|
||||
}
|
||||
|
||||
mw_shutdown ();
|
||||
};
|
||||
/*
|
||||
multiwait.c - this manages only the network screen where
|
||||
everyone have to select it's players and where even the basic chat is inside
|
||||
*/
|
||||
|
||||
#include "bomberclone.h"
|
||||
#include "network.h"
|
||||
#include "packets.h"
|
||||
#include "gamesrv.h"
|
||||
#include "gfx.h"
|
||||
#include "chat.h"
|
||||
|
||||
#define MW_IS_GFX_SELECT(__gfx_nr,__result) for (__result = (MAX_PLAYERS-1); (bman.players[__result].gfx_nr != __gfx_nr) && (__result >= 0); __result--);
|
||||
|
||||
extern int UpdateRects_nr;
|
||||
|
||||
static int mw_y = 0,
|
||||
mw_frame = 0,
|
||||
mw_frameto = 0;
|
||||
static SDL_Surface *mw_plgfx[MAX_PLAYERS];
|
||||
|
||||
|
||||
/* this will load some graphics and so other stuff */
|
||||
void
|
||||
mw_init ()
|
||||
{
|
||||
int i;
|
||||
SDL_Surface *tmp;
|
||||
draw_logo ();
|
||||
|
||||
menu_displaytext ("Please Wait", "Loading GFX Data", 64, 128, 64);
|
||||
|
||||
gfx_load_players (32, 32);
|
||||
network_loop ();
|
||||
for (i = 0; i < MAX_PLAYERS; i++) {
|
||||
network_loop ();
|
||||
tmp = makegray_image (gfx.players[i].ani.image);
|
||||
network_loop ();
|
||||
mw_plgfx[i] = SDL_DisplayFormat (tmp);
|
||||
network_loop ();
|
||||
SDL_FreeSurface (tmp);
|
||||
network_loop ();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/* free all grafics */
|
||||
void
|
||||
mw_shutdown ()
|
||||
{
|
||||
int i;
|
||||
|
||||
chat_show (-1, -1, -1, -1);
|
||||
|
||||
menu_displaytext ("Please Wait", "Freeing GFX Data", 64, 128, 64);
|
||||
|
||||
gfx_free_players ();
|
||||
for (i = 0; i < MAX_PLAYERS; i++)
|
||||
SDL_FreeSurface (mw_plgfx[i]);
|
||||
};
|
||||
|
||||
|
||||
void
|
||||
mw_wait_for_connect ()
|
||||
{
|
||||
menu_displaytext ("Please Wait", "Wait For connection", 64, 128, 64);
|
||||
};
|
||||
|
||||
|
||||
void
|
||||
mw_draw_status ()
|
||||
{
|
||||
int pnr,
|
||||
x,
|
||||
x1,
|
||||
y,
|
||||
px;
|
||||
char text[255];
|
||||
SDL_Rect src,
|
||||
dest;
|
||||
|
||||
/* Draw Player List */
|
||||
/* 1. the head */
|
||||
px = gfx.res.x / 320;
|
||||
x = (gfx.res.x - px * 320) / 2;
|
||||
|
||||
for (pnr = 0; pnr < px; pnr++)
|
||||
draw_text (pnr * 320 + x, 24, " Wins Points", 1);
|
||||
|
||||
/* 2. the names with points */
|
||||
for (x1 = pnr = 0, y = 48; pnr < MAX_PLAYERS; pnr++) {
|
||||
redraw_logo (x1 * 320, y - 4, 320, 32);
|
||||
if (bman.players[pnr].gfx_nr != -1 && PS_IS_used (bman.players[pnr].state)) {
|
||||
src.x = 3 * bman.players[pnr].gfx->smal_size.x;
|
||||
src.y = 0;
|
||||
src.w = dest.w = bman.players[pnr].gfx->smal_size.x;
|
||||
src.h = dest.h = bman.players[pnr].gfx->smal_size.y;
|
||||
|
||||
dest.x = x1 * 320;
|
||||
dest.y = y - 4;
|
||||
|
||||
SDL_BlitSurface (bman.players[pnr].gfx->smal_image, &src, gfx.screen, &dest);
|
||||
}
|
||||
|
||||
sprintf (text, " %10s %2d %2d", bman.players[pnr].name, bman.players[pnr].wins,
|
||||
bman.players[pnr].points);
|
||||
if (PS_IS_used (bman.players[pnr].state)) {
|
||||
|
||||
if (bman.lastwinner == pnr)
|
||||
draw_text (x + x1 * 320, y, text, 1);
|
||||
else
|
||||
draw_text (x + x1 * 320, y, text, 0);
|
||||
}
|
||||
x1++;
|
||||
if (x1 >= px) {
|
||||
y += 32;
|
||||
x1 = 0;
|
||||
}
|
||||
if (pnr == MAX_PLAYERS - 1 && x1 != 0)
|
||||
y += 32;
|
||||
}
|
||||
|
||||
mw_y = y;
|
||||
};
|
||||
|
||||
|
||||
void
|
||||
mw_draw_gfxselect (int selgfx)
|
||||
{
|
||||
int i,
|
||||
select,
|
||||
xstep;
|
||||
SDL_Rect src,
|
||||
dest;
|
||||
|
||||
xstep = gfx.res.x / MAX_PLAYERS;
|
||||
|
||||
if (bman.players[bman.p_nr].gfx_nr == -1) {
|
||||
/* draw selection */
|
||||
for (i = 0; i < MAX_PLAYERS; i++) {
|
||||
dest.w = src.w = gfx.players[i].size.x;
|
||||
dest.h = src.h = gfx.players[i].size.y;
|
||||
|
||||
dest.x = i * xstep + (xstep >> 1) - (gfx.players[i].size.x >> 1);
|
||||
dest.y = mw_y + 8;
|
||||
|
||||
redraw_logo (dest.x, dest.y, dest.w, dest.h);
|
||||
|
||||
src.x = 3 * gfx.players[i].size.x;
|
||||
if (i == selgfx)
|
||||
src.y = mw_frame * gfx.players[i].size.y;
|
||||
else
|
||||
src.y = 0;
|
||||
|
||||
MW_IS_GFX_SELECT (i, select);
|
||||
|
||||
if (select >= MAX_PLAYERS || select < 0) {
|
||||
/* this player have not been selected */
|
||||
if (selgfx == i) {
|
||||
mw_frameto--;
|
||||
|
||||
if (mw_frameto <= 0 || mw_frameto > ANI_PLAYERTIMEOUT) {
|
||||
mw_frameto = ANI_PLAYERTIMEOUT;
|
||||
mw_frame++;
|
||||
}
|
||||
|
||||
if (mw_frame >= gfx.players[i].ani.frames || mw_frame < 0) {
|
||||
mw_frameto = ANI_PLAYERTIMEOUT;
|
||||
mw_frame = 0;
|
||||
}
|
||||
|
||||
SDL_BlitSurface (gfx.players[i].ani.image, &src, gfx.screen, &dest);
|
||||
}
|
||||
else
|
||||
SDL_BlitSurface (mw_plgfx[i], &src, gfx.screen, &dest);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* draw selected players */
|
||||
for (i = 0; i < MAX_PLAYERS; i++) {
|
||||
dest.w = src.w = gfx.players[i].size.x;
|
||||
dest.h = src.h = gfx.players[i].size.y;
|
||||
|
||||
dest.x = i * xstep + (xstep >> 1) - (gfx.players[i].size.x >> 1);
|
||||
dest.y = mw_y + 8;
|
||||
|
||||
redraw_logo (dest.x, dest.y, dest.w, dest.h);
|
||||
|
||||
src.x = 3 * gfx.players[i].size.x;
|
||||
if (i == selgfx)
|
||||
src.y = mw_frame * gfx.players[i].size.y;
|
||||
else
|
||||
src.y = 0;
|
||||
|
||||
MW_IS_GFX_SELECT (i, select);
|
||||
|
||||
if (select < MAX_PLAYERS && select >= 0) {
|
||||
/* this player have been selected */
|
||||
if (bman.players[bman.p_nr].gfx_nr == i)
|
||||
SDL_BlitSurface (gfx.players[i].ani.image, &src, gfx.screen, &dest);
|
||||
else
|
||||
SDL_BlitSurface (mw_plgfx[i], &src, gfx.screen, &dest);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mw_y += 8 + gfx.players[0].size.y;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
mw_draw_chat ()
|
||||
{
|
||||
if (chat.visible == 0) {
|
||||
chat_show (16, mw_y + 16, gfx.res.x - 16, gfx.res.y - 32);
|
||||
chat_addline ("Press [STRG] or [CTRL] - to select a player");
|
||||
if (GT_MP_PTPM)
|
||||
chat_addline ("F4 - to start the game");
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/* the loop itself */
|
||||
void
|
||||
wait_for_players ()
|
||||
{
|
||||
SDL_Event event;
|
||||
Uint8 *keys;
|
||||
int done = 0,
|
||||
ready = 0,
|
||||
keypressed = 0,
|
||||
i,
|
||||
selgfx = 0;
|
||||
|
||||
mw_init ();
|
||||
draw_logo ();
|
||||
|
||||
while (!done && bman.state == GS_wait) {
|
||||
|
||||
i = bman.p_nr;
|
||||
if (network_loop () < 0) {
|
||||
done = 1;
|
||||
bman.p_nr = -1;
|
||||
}
|
||||
if (i != bman.p_nr) /* clean the screen after we got our playernumber */
|
||||
draw_logo ();
|
||||
|
||||
/* check if all players are ready, and more as one player is connected */
|
||||
if (GT_MP_PTPM)
|
||||
for (ready = 0, i = 0; i < MAX_PLAYERS; i++)
|
||||
if (PS_IS_playing (bman.players[i].state))
|
||||
ready++;
|
||||
if (ready > 1)
|
||||
ready = 1;
|
||||
else
|
||||
ready = 0;
|
||||
|
||||
/* draw the screeninformations */
|
||||
if (bman.p_nr == -1) { /* we have no connect yet */
|
||||
mw_wait_for_connect ();
|
||||
SDL_Flip (gfx.screen);
|
||||
}
|
||||
else { /* we have a connect so draw status */
|
||||
mw_draw_status ();
|
||||
mw_draw_gfxselect (selgfx);
|
||||
gfx_AddUpdateRect (0, 0, gfx.res.x, mw_y);
|
||||
mw_draw_chat ();
|
||||
}
|
||||
|
||||
gfx_UpdateRects ();
|
||||
|
||||
/* do the keyboard handling */
|
||||
if (SDL_PollEvent (&event) != 0)
|
||||
switch (event.type) {
|
||||
case (SDL_QUIT):
|
||||
bman.state = GS_quit;
|
||||
bman.p_nr = -1;
|
||||
done = 1;
|
||||
}
|
||||
|
||||
keys = SDL_GetKeyState (NULL);
|
||||
|
||||
if (keys[SDLK_ESCAPE] && event.type == SDL_KEYDOWN) {
|
||||
/* we want to quit */
|
||||
done = 1;
|
||||
bman.p_nr = -1;
|
||||
keypressed = 1;
|
||||
bman.state = GS_startup;
|
||||
}
|
||||
|
||||
if (bman.p_nr != -1) {
|
||||
|
||||
if (keys[SDLK_DOWN] && (!keypressed)) {
|
||||
}
|
||||
|
||||
if (keys[SDLK_UP] && (!keypressed)) {
|
||||
}
|
||||
|
||||
if (keys[SDLK_LEFT] && (!keypressed) && bman.players[bman.p_nr].gfx_nr == -1) {
|
||||
i = 0;
|
||||
while (selgfx < 0 || selgfx >= MAX_PLAYERS || i != -1) {
|
||||
selgfx--;
|
||||
if (selgfx < 0)
|
||||
selgfx = MAX_PLAYERS - 1;
|
||||
MW_IS_GFX_SELECT (selgfx, i);
|
||||
}
|
||||
}
|
||||
|
||||
if (keys[SDLK_RIGHT] && (!keypressed) && bman.players[bman.p_nr].gfx_nr == -1) {
|
||||
i = 0;
|
||||
while (selgfx < 0 || selgfx >= MAX_PLAYERS || i != -1) {
|
||||
selgfx++;
|
||||
if (selgfx >= MAX_PLAYERS)
|
||||
selgfx = 0;
|
||||
MW_IS_GFX_SELECT (selgfx, i);
|
||||
}
|
||||
}
|
||||
|
||||
/* just make sure this player is not selected twice */
|
||||
if (bman.players[bman.p_nr].gfx_nr == -1) {
|
||||
MW_IS_GFX_SELECT (selgfx, i);
|
||||
while (selgfx < 0 || selgfx >= MAX_PLAYERS || i != -1) {
|
||||
selgfx++;
|
||||
if (selgfx >= MAX_PLAYERS)
|
||||
selgfx = 0;
|
||||
MW_IS_GFX_SELECT (selgfx, i);
|
||||
}
|
||||
}
|
||||
|
||||
if ((keys[SDLK_LCTRL] || keys[SDLK_RCTRL]) && (!keypressed)) {
|
||||
if (bman.players[bman.p_nr].gfx_nr == -1) {
|
||||
/* select player */
|
||||
bman.players[bman.p_nr].gfx_nr = selgfx;
|
||||
}
|
||||
else {
|
||||
/* deselect player */
|
||||
bman.players[bman.p_nr].gfx_nr = -1;
|
||||
}
|
||||
net_change_playerid (bman.p_nr, 1);
|
||||
}
|
||||
|
||||
if ((GT_MP_PTPM) && ready && keys[SDLK_F4] && (!keypressed)) {
|
||||
done = 1;
|
||||
}
|
||||
|
||||
if ((GT_MP_PTPM) && keys[SDLK_F5] && (!keypressed)) {
|
||||
/* Map modification */
|
||||
menu_get_text ("Enter the path of a field file", bman.fieldpath, 30);
|
||||
draw_logo ();
|
||||
chat_drawbox ();
|
||||
}
|
||||
|
||||
chat_loop (&event);
|
||||
}
|
||||
|
||||
if (event.type == SDL_KEYUP)
|
||||
keypressed = 0;
|
||||
else if (event.type == SDL_KEYDOWN)
|
||||
keypressed = 1;
|
||||
|
||||
s_delay (25);
|
||||
}
|
||||
|
||||
mw_shutdown ();
|
||||
};
|
||||
|
@ -1,249 +1,247 @@
|
||||
/* network menu */
|
||||
|
||||
#include "bomberclone.h"
|
||||
#include "network.h"
|
||||
#include "packets.h"
|
||||
#include "gamesrv.h"
|
||||
#include "gfx.h"
|
||||
|
||||
extern int UpdateRects_nr;
|
||||
|
||||
|
||||
void
|
||||
networkmenu_joingame ()
|
||||
{
|
||||
int i;
|
||||
|
||||
gamesrv_getserver ();
|
||||
|
||||
for (i = 0; bman.servername[i] != 0; i++)
|
||||
if (bman.servername[i] == ' ')
|
||||
bman.servername[i] = ':';
|
||||
|
||||
|
||||
/* connect if we have an Servername */
|
||||
if (bman.servername[0] != 0) {
|
||||
bman.sock = -1;
|
||||
bman.gametype = GT_multi;
|
||||
bman.multitype = MT_ptps;
|
||||
join_multiplayer_game ();
|
||||
bman.servername[0] = 0;
|
||||
}
|
||||
};
|
||||
|
||||
void
|
||||
netmenu ()
|
||||
{
|
||||
int menuselect = 0;
|
||||
_menu menu[] = {
|
||||
{0, "Join A Netgame"},
|
||||
{1, "Create A New Netgame"},
|
||||
{2, "Options"},
|
||||
{3, "Return To Main Menu"},
|
||||
{-1, ""}
|
||||
};
|
||||
|
||||
if (bman.gamename[0] == 0)
|
||||
sprintf (bman.gamename, "%s's Game", bman.playername);
|
||||
|
||||
while (menuselect != -1 && bman.state != GS_quit) {
|
||||
menuselect = menu_loop ("Multiplayer", menu, menuselect);
|
||||
switch (menuselect) {
|
||||
case (0): // Join a Game
|
||||
networkmenu_joingame ();
|
||||
break;
|
||||
case (1): // Create a new Game
|
||||
bman.sock = -1;
|
||||
bman.gametype = GT_multi;
|
||||
bman.multitype = MT_ptpm;
|
||||
host_multiplayer_game ();
|
||||
break;
|
||||
case (2): // Options
|
||||
networkmenu_options ();
|
||||
break;
|
||||
case (3):
|
||||
menuselect = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
networkmenu_options ()
|
||||
{
|
||||
int menuselect = 0;
|
||||
char text[255];
|
||||
_menu menu[] = {
|
||||
{0, "Game Name:"},
|
||||
{1, "Max Players:"},
|
||||
{2, "Network"},
|
||||
{3, "Notify Masterserver"},
|
||||
{4, "Masterserver"},
|
||||
{5, "Return To Multiplayer Menu"},
|
||||
{-1, ""}
|
||||
};
|
||||
|
||||
|
||||
while (menuselect != -1 && bman.state != GS_quit) {
|
||||
|
||||
sprintf (menu[0].text, "Gamename: %s", bman.gamename);
|
||||
sprintf (menu[1].text, "Max Players: %d/%d", bman.maxplayer, MAX_PLAYERS);
|
||||
|
||||
if (bman.net_ai_family == PF_INET)
|
||||
sprintf (menu[2].text, "Network: IPv4");
|
||||
else
|
||||
sprintf (menu[2].text, "Network: IPv6");
|
||||
|
||||
if (bman.notifygamemaster)
|
||||
sprintf (menu[3].text, "Notify MasterServer: Yes");
|
||||
else
|
||||
sprintf (menu[3].text, "Notify MasterServer: No");
|
||||
|
||||
sprintf (menu[4].text, "MasterServer %s", bman.gamemaster);
|
||||
|
||||
menuselect = menu_loop ("Multiplayer Options", menu, menuselect);
|
||||
|
||||
switch (menuselect) {
|
||||
|
||||
case (0): // change the game name
|
||||
menu_get_text ("Name of the Game:", bman.gamename, 32);
|
||||
break;
|
||||
|
||||
case (1): // Max Number of Players
|
||||
sprintf (text, "%d", bman.maxplayer);
|
||||
menu_get_text ("Max Players", text, 2);
|
||||
bman.maxplayer = atoi (text);
|
||||
if (bman.maxplayer > MAX_PLAYERS)
|
||||
bman.maxplayer = MAX_PLAYERS;
|
||||
if (bman.maxplayer < 2)
|
||||
bman.maxplayer = 2;
|
||||
break;
|
||||
|
||||
case (2):
|
||||
#ifndef _WIN32
|
||||
if (bman.net_ai_family == PF_INET)
|
||||
bman.net_ai_family = PF_INET6;
|
||||
else
|
||||
bman.net_ai_family = PF_INET;
|
||||
#endif
|
||||
break;
|
||||
|
||||
case (3): // Change the Notification
|
||||
if (bman.notifygamemaster)
|
||||
bman.notifygamemaster = 0;
|
||||
else
|
||||
bman.notifygamemaster = 1;
|
||||
break;
|
||||
|
||||
case (4): // Masterserver Address
|
||||
menu_get_text ("Address of the MasterServer", bman.gamemaster,
|
||||
LEN_SERVERNAME + LEN_PORT + 2);
|
||||
break;
|
||||
|
||||
case (5):
|
||||
menuselect = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
void
|
||||
multiplayer_firstrun ()
|
||||
{
|
||||
int i;
|
||||
/*
|
||||
reset some gamedata
|
||||
*/
|
||||
bman.p_nr = -1;
|
||||
bman.state = GS_wait;
|
||||
|
||||
for (i = 0; i < MAX_PLAYERS; i++) {
|
||||
bman.players[i].name[0] = 0;
|
||||
bman.players[i].gfx_nr = -1;
|
||||
bman.players[i].gfx = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
init the network
|
||||
*/
|
||||
if (network_init () < 0) {
|
||||
d_printf ("network_init () FAILED\n");
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
We will host a network game
|
||||
*/
|
||||
void
|
||||
host_multiplayer_game ()
|
||||
{
|
||||
multiplayer_firstrun ();
|
||||
|
||||
while (bman.state != GS_startup && bman.state != GS_quit) {
|
||||
/* check players and in_pl lists */
|
||||
wait_for_players ();
|
||||
|
||||
if (bman.p_nr != -1) {
|
||||
bman.state = GS_update;
|
||||
net_new_game ();
|
||||
field_new (bman.fieldpath);
|
||||
if (gfx.random_tileset)
|
||||
tileset_random ();
|
||||
net_send_servermode ();
|
||||
gfx_game_init ();
|
||||
net_new_gamedata ();
|
||||
|
||||
if (bman.state == GS_ready || bman.state == GS_running) {
|
||||
net_send_servermode ();
|
||||
|
||||
game_loop ();
|
||||
if (bman.state == GS_running)
|
||||
bman.state = GS_wait;
|
||||
|
||||
bman.lastwinner = -1;
|
||||
|
||||
game_end ();
|
||||
|
||||
net_send_servermode ();
|
||||
net_send_players ();
|
||||
}
|
||||
gfx_game_shutdown ();
|
||||
}
|
||||
}
|
||||
|
||||
network_shutdown ();
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*
|
||||
We will join a network game
|
||||
*/
|
||||
void
|
||||
join_multiplayer_game ()
|
||||
{
|
||||
multiplayer_firstrun ();
|
||||
|
||||
while (bman.state != GS_startup && bman.state != GS_quit) {
|
||||
wait_for_players ();
|
||||
|
||||
if (bman.p_nr != -1 && (GS_WAITRUNNING || bman.state == GS_update)) {
|
||||
gfx_game_init ();
|
||||
bman.state = GS_update;
|
||||
net_new_game ();
|
||||
net_new_gamedata ();
|
||||
|
||||
if (bman.state == GS_ready || bman.state == GS_running)
|
||||
game_loop ();
|
||||
|
||||
gfx_game_shutdown ();
|
||||
}
|
||||
else
|
||||
bman.state = GS_startup;
|
||||
}
|
||||
|
||||
network_shutdown ();
|
||||
};
|
||||
/* network menu */
|
||||
|
||||
#include "bomberclone.h"
|
||||
#include "network.h"
|
||||
#include "packets.h"
|
||||
#include "gamesrv.h"
|
||||
#include "gfx.h"
|
||||
|
||||
extern int UpdateRects_nr;
|
||||
|
||||
|
||||
void
|
||||
networkmenu_joingame ()
|
||||
{
|
||||
int i;
|
||||
|
||||
gamesrv_getserver ();
|
||||
|
||||
for (i = 0; bman.servername[i] != 0; i++)
|
||||
if (bman.servername[i] == ' ')
|
||||
bman.servername[i] = ':';
|
||||
|
||||
|
||||
/* connect if we have an Servername */
|
||||
if (bman.servername[0] != 0) {
|
||||
bman.sock = -1;
|
||||
bman.gametype = GT_multi;
|
||||
bman.multitype = MT_ptps;
|
||||
join_multiplayer_game ();
|
||||
bman.servername[0] = 0;
|
||||
}
|
||||
};
|
||||
|
||||
void
|
||||
netmenu ()
|
||||
{
|
||||
int menuselect = 0;
|
||||
_menu menu[] = {
|
||||
{0, "Join A Netgame"},
|
||||
{1, "Create A New Netgame"},
|
||||
{2, "Options"},
|
||||
{3, "Return To Main Menu"},
|
||||
{-1, ""}
|
||||
};
|
||||
|
||||
if (bman.gamename[0] == 0)
|
||||
sprintf (bman.gamename, "%s's Game", bman.playername);
|
||||
|
||||
while (menuselect != -1 && bman.state != GS_quit) {
|
||||
menuselect = menu_loop ("Multiplayer", menu, menuselect);
|
||||
switch (menuselect) {
|
||||
case (0): // Join a Game
|
||||
networkmenu_joingame ();
|
||||
break;
|
||||
case (1): // Create a new Game
|
||||
bman.sock = -1;
|
||||
bman.gametype = GT_multi;
|
||||
bman.multitype = MT_ptpm;
|
||||
host_multiplayer_game ();
|
||||
break;
|
||||
case (2): // Options
|
||||
networkmenu_options ();
|
||||
break;
|
||||
case (3):
|
||||
menuselect = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
networkmenu_options ()
|
||||
{
|
||||
int menuselect = 0;
|
||||
char text[255];
|
||||
_menu menu[] = {
|
||||
{0, "Game Name:"},
|
||||
{1, "Max Players:"},
|
||||
{2, "Network"},
|
||||
{3, "Notify Masterserver"},
|
||||
{4, "Masterserver"},
|
||||
{5, "Return To Multiplayer Menu"},
|
||||
{-1, ""}
|
||||
};
|
||||
|
||||
|
||||
while (menuselect != -1 && bman.state != GS_quit) {
|
||||
|
||||
sprintf (menu[0].text, "Gamename: %s", bman.gamename);
|
||||
sprintf (menu[1].text, "Max Players: %d/%d", bman.maxplayer, MAX_PLAYERS);
|
||||
|
||||
if (bman.net_ai_family == PF_INET)
|
||||
sprintf (menu[2].text, "Network: IPv4");
|
||||
else
|
||||
sprintf (menu[2].text, "Network: IPv6");
|
||||
|
||||
if (bman.notifygamemaster)
|
||||
sprintf (menu[3].text, "Notify MasterServer: Yes");
|
||||
else
|
||||
sprintf (menu[3].text, "Notify MasterServer: No");
|
||||
|
||||
sprintf (menu[4].text, "MasterServer %s", bman.gamemaster);
|
||||
|
||||
menuselect = menu_loop ("Multiplayer Options", menu, menuselect);
|
||||
|
||||
switch (menuselect) {
|
||||
|
||||
case (0): // change the game name
|
||||
menu_get_text ("Name of the Game:", bman.gamename, 32);
|
||||
break;
|
||||
|
||||
case (1): // Max Number of Players
|
||||
sprintf (text, "%d", bman.maxplayer);
|
||||
menu_get_text ("Max Players", text, 2);
|
||||
bman.maxplayer = atoi (text);
|
||||
if (bman.maxplayer > MAX_PLAYERS)
|
||||
bman.maxplayer = MAX_PLAYERS;
|
||||
if (bman.maxplayer < 2)
|
||||
bman.maxplayer = 2;
|
||||
break;
|
||||
|
||||
case (2):
|
||||
#ifndef _WIN32
|
||||
if (bman.net_ai_family == PF_INET)
|
||||
bman.net_ai_family = PF_INET6;
|
||||
else
|
||||
bman.net_ai_family = PF_INET;
|
||||
#endif
|
||||
break;
|
||||
|
||||
case (3): // Change the Notification
|
||||
if (bman.notifygamemaster)
|
||||
bman.notifygamemaster = 0;
|
||||
else
|
||||
bman.notifygamemaster = 1;
|
||||
break;
|
||||
|
||||
case (4): // Masterserver Address
|
||||
menu_get_text ("Address of the MasterServer", bman.gamemaster,
|
||||
LEN_SERVERNAME + LEN_PORT + 2);
|
||||
break;
|
||||
|
||||
case (5):
|
||||
menuselect = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
void
|
||||
multiplayer_firstrun ()
|
||||
{
|
||||
int i;
|
||||
/*
|
||||
reset some gamedata
|
||||
*/
|
||||
bman.p_nr = -1;
|
||||
bman.state = GS_wait;
|
||||
|
||||
for (i = 0; i < MAX_PLAYERS; i++) {
|
||||
bman.players[i].name[0] = 0;
|
||||
bman.players[i].gfx_nr = -1;
|
||||
bman.players[i].gfx = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
init the network
|
||||
*/
|
||||
if (network_init () < 0) {
|
||||
d_printf ("network_init () FAILED\n");
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
We will host a network game
|
||||
*/
|
||||
void
|
||||
host_multiplayer_game ()
|
||||
{
|
||||
multiplayer_firstrun ();
|
||||
|
||||
while (bman.state != GS_startup && bman.state != GS_quit) {
|
||||
/* check players and in_pl lists */
|
||||
wait_for_players ();
|
||||
|
||||
if (bman.p_nr != -1) {
|
||||
bman.state = GS_update;
|
||||
net_new_game ();
|
||||
init_map_tileset();
|
||||
net_send_servermode ();
|
||||
gfx_game_init ();
|
||||
net_new_gamedata ();
|
||||
|
||||
if (bman.state == GS_ready || bman.state == GS_running) {
|
||||
net_send_servermode ();
|
||||
|
||||
game_loop ();
|
||||
if (bman.state == GS_running)
|
||||
bman.state = GS_wait;
|
||||
|
||||
bman.lastwinner = -1;
|
||||
|
||||
game_end ();
|
||||
|
||||
net_send_servermode ();
|
||||
net_send_players ();
|
||||
}
|
||||
gfx_game_shutdown ();
|
||||
}
|
||||
}
|
||||
|
||||
network_shutdown ();
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*
|
||||
We will join a network game
|
||||
*/
|
||||
void
|
||||
join_multiplayer_game ()
|
||||
{
|
||||
multiplayer_firstrun ();
|
||||
|
||||
while (bman.state != GS_startup && bman.state != GS_quit) {
|
||||
wait_for_players ();
|
||||
|
||||
if (bman.p_nr != -1 && (GS_WAITRUNNING || bman.state == GS_update)) {
|
||||
gfx_game_init ();
|
||||
bman.state = GS_update;
|
||||
net_new_game ();
|
||||
net_new_gamedata ();
|
||||
|
||||
if (bman.state == GS_ready || bman.state == GS_running)
|
||||
game_loop ();
|
||||
|
||||
gfx_game_shutdown ();
|
||||
}
|
||||
else
|
||||
bman.state = GS_startup;
|
||||
}
|
||||
|
||||
network_shutdown ();
|
||||
};
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,104 +1,104 @@
|
||||
/*
|
||||
network.h file... for everything what have to do with the network stuff
|
||||
*/
|
||||
|
||||
#ifndef _NETWORK_H_
|
||||
#define _NETWORK_H_
|
||||
|
||||
#define MAX_UDPDATA 1024
|
||||
#define PKG_RESENDCACHE_SIZE (64*1024)
|
||||
#define PKG_IN_INDEX_NUM 256
|
||||
#define RESENDCACHE_TIMEOUT 500
|
||||
#define RESENDCACHE_RETRY 10
|
||||
#define DOWNLOAD_TIMEOUT 2000
|
||||
#define DYN_PKG_MAX_MISSING 4
|
||||
#define DYN_PKG_MIN_MISSING 1
|
||||
#define PKG_SENDSETOPT 2
|
||||
|
||||
#define GT_MP_PTPM (bman.multitype == MT_ptpm && bman.gametype == GT_multi)
|
||||
#define GT_MP_PTPS (bman.multitype == MT_ptps && bman.gametype == GT_multi)
|
||||
#define GT_MP_PTP ((bman.multitype == MT_ptps || bman.multitype == MT_ptpm) && bman.gametype == GT_multi)
|
||||
|
||||
#define GS_WAITRUNNING (bman.state == GS_wait || bman.state == GS_ready || bman.state == GS_running)
|
||||
|
||||
#ifdef _WIN32
|
||||
#define _sockaddr sockaddr
|
||||
#else
|
||||
#define _sockaddr sockaddr_in6
|
||||
#endif
|
||||
|
||||
struct __net_addr { // this holds the network data
|
||||
char host[LEN_SERVERNAME];
|
||||
char port[LEN_PORT];
|
||||
struct _sockaddr sAddr;
|
||||
signed char pl_nr; // pl_nr so we know it in the pkgcahce.
|
||||
} typedef _net_addr;
|
||||
|
||||
|
||||
struct __net_pkgopt { /* this will hold all needed data for the packet
|
||||
timeout function */
|
||||
signed char send_to; // sending packet data (playermove) on 0 it will be send
|
||||
signed char send_set; // start value for the packet data option (dynamic set)
|
||||
int to_2sec; // how many unreached packets was send
|
||||
Uint32 to_timestamp;
|
||||
} typedef _net_pkgopt;
|
||||
|
||||
struct __net_player {
|
||||
_net_addr addr; // holds the address
|
||||
int pingreq; // just to send a ping and to save the number in here
|
||||
int pingack; // just to wait for an ping reply.. it will show up here
|
||||
Uint32 timestamp; // time of the last incoming package
|
||||
signed char net_istep;
|
||||
signed char net_status;
|
||||
_net_pkgopt pkgopt; // packet and network controll data
|
||||
} typedef _net_player;
|
||||
|
||||
|
||||
// network menu
|
||||
extern void netmenu();
|
||||
extern void networkmenu_joingame ();
|
||||
extern void networkmenu_options ();
|
||||
extern void join_multiplayer_game ();
|
||||
extern void host_multiplayer_game ();
|
||||
extern void multiplayer_firstrun ();
|
||||
|
||||
// network.c
|
||||
extern int network_server_port (char *server, char *host, int hostlen, char *port, int portlen);
|
||||
extern void network_shutdown ();
|
||||
extern int network_init ();
|
||||
extern int network_loop ();
|
||||
extern void net_change_playerid (int pl_nr, unsigned char senddata);
|
||||
extern void net_new_game ();
|
||||
extern void net_new_gamedata ();
|
||||
extern void net_game_send_player (int p_nr);
|
||||
extern void net_game_send_playermove (int p_nr, int mustsend);
|
||||
extern void net_game_send_bomb (int p, int b);
|
||||
extern void net_game_send_field (int x, int y);
|
||||
extern void net_game_fillsockaddr ();
|
||||
extern void net_game_send_ill (int p_nr);
|
||||
extern void net_delplayer (int pl_nr);
|
||||
extern void draw_netupdatestate ();
|
||||
extern void net_send_servermode ();
|
||||
extern void net_send_players ();
|
||||
extern int net_check_timeout (int pl_nr);
|
||||
extern void net_dyn_pkgoption ();
|
||||
extern void net_send_chat (char *text, signed char notigamesrv);
|
||||
|
||||
// multiwait.c
|
||||
extern void wait_for_players ();
|
||||
extern void mw_init ();
|
||||
extern void mw_shutdown ();
|
||||
extern void mw_draw_gfxselect (int selgfx);
|
||||
extern void mw_draw_status ();
|
||||
extern void mw_wait_for_connect ();
|
||||
extern void mw_draw_chat ();
|
||||
|
||||
// udp.c
|
||||
extern char *dns_net_getip (char *host);
|
||||
extern int dns_filladdr (char *host, int hostlen, char *port, int portlen, int ai_family, struct _sockaddr *sAddr);
|
||||
extern int udp_get (int sock, char *text, int len, struct _sockaddr *sAddr, int ai_family);
|
||||
extern int udp_server (char *port, int ai_family);
|
||||
extern void udp_send (int sock, char *text, int len, struct _sockaddr *sAddr, int ai_family);
|
||||
extern void udp_close (int sock);
|
||||
|
||||
#endif
|
||||
/*
|
||||
network.h file... for everything what have to do with the network stuff
|
||||
*/
|
||||
|
||||
#ifndef _NETWORK_H_
|
||||
#define _NETWORK_H_
|
||||
|
||||
#define MAX_UDPDATA 1024
|
||||
#define PKG_RESENDCACHE_SIZE (64*1024)
|
||||
#define PKG_IN_INDEX_NUM 256
|
||||
#define RESENDCACHE_TIMEOUT 500
|
||||
#define RESENDCACHE_RETRY 10
|
||||
#define DOWNLOAD_TIMEOUT 2000
|
||||
#define DYN_PKG_MAX_MISSING 4
|
||||
#define DYN_PKG_MIN_MISSING 1
|
||||
#define PKG_SENDSETOPT 2
|
||||
|
||||
#define GT_MP_PTPM (bman.multitype == MT_ptpm && bman.gametype == GT_multi)
|
||||
#define GT_MP_PTPS (bman.multitype == MT_ptps && bman.gametype == GT_multi)
|
||||
#define GT_MP_PTP ((bman.multitype == MT_ptps || bman.multitype == MT_ptpm) && bman.gametype == GT_multi)
|
||||
|
||||
#define GS_WAITRUNNING (bman.state == GS_wait || bman.state == GS_ready || bman.state == GS_running)
|
||||
|
||||
#ifdef _WIN32
|
||||
#define _sockaddr sockaddr
|
||||
#else
|
||||
#define _sockaddr sockaddr_in6
|
||||
#endif
|
||||
|
||||
struct __net_addr { // this holds the network data
|
||||
char host[LEN_SERVERNAME];
|
||||
char port[LEN_PORT];
|
||||
struct _sockaddr sAddr;
|
||||
signed char pl_nr; // pl_nr so we know it in the pkgcahce.
|
||||
} typedef _net_addr;
|
||||
|
||||
|
||||
struct __net_pkgopt { /* this will hold all needed data for the packet
|
||||
timeout function */
|
||||
signed char send_to; // sending packet data (playermove) on 0 it will be send
|
||||
signed char send_set; // start value for the packet data option (dynamic set)
|
||||
int to_2sec; // how many unreached packets was send
|
||||
Uint32 to_timestamp;
|
||||
} typedef _net_pkgopt;
|
||||
|
||||
struct __net_player {
|
||||
_net_addr addr; // holds the address
|
||||
int pingreq; // just to send a ping and to save the number in here
|
||||
int pingack; // just to wait for an ping reply.. it will show up here
|
||||
Uint32 timestamp; // time of the last incoming package
|
||||
signed char net_istep;
|
||||
signed char net_status;
|
||||
_net_pkgopt pkgopt; // packet and network controll data
|
||||
} typedef _net_player;
|
||||
|
||||
|
||||
// network menu
|
||||
extern void netmenu();
|
||||
extern void networkmenu_joingame ();
|
||||
extern void networkmenu_options ();
|
||||
extern void join_multiplayer_game ();
|
||||
extern void host_multiplayer_game ();
|
||||
extern void multiplayer_firstrun ();
|
||||
|
||||
// network.c
|
||||
extern int network_server_port (char *server, char *host, int hostlen, char *port, int portlen);
|
||||
extern void network_shutdown ();
|
||||
extern int network_init ();
|
||||
extern int network_loop ();
|
||||
extern void net_change_playerid (int pl_nr, unsigned char senddata);
|
||||
extern void net_new_game ();
|
||||
extern void net_new_gamedata ();
|
||||
extern void net_game_send_player (int p_nr);
|
||||
extern void net_game_send_playermove (int p_nr, int mustsend);
|
||||
extern void net_game_send_bomb (int p, int b);
|
||||
extern void net_game_send_field (int x, int y);
|
||||
extern void net_game_fillsockaddr ();
|
||||
extern void net_game_send_ill (int p_nr);
|
||||
extern void net_delplayer (int pl_nr);
|
||||
extern void draw_netupdatestate ();
|
||||
extern void net_send_servermode ();
|
||||
extern void net_send_players ();
|
||||
extern int net_check_timeout (int pl_nr);
|
||||
extern void net_dyn_pkgoption ();
|
||||
extern void net_send_chat (char *text, signed char notigamesrv);
|
||||
|
||||
// multiwait.c
|
||||
extern void wait_for_players ();
|
||||
extern void mw_init ();
|
||||
extern void mw_shutdown ();
|
||||
extern void mw_draw_gfxselect (int selgfx);
|
||||
extern void mw_draw_status ();
|
||||
extern void mw_wait_for_connect ();
|
||||
extern void mw_draw_chat ();
|
||||
|
||||
// udp.c
|
||||
extern char *dns_net_getip (char *host);
|
||||
extern int dns_filladdr (char *host, int hostlen, char *port, int portlen, int ai_family, struct _sockaddr *sAddr);
|
||||
extern int udp_get (int sock, char *text, int len, struct _sockaddr *sAddr, int ai_family);
|
||||
extern int udp_server (char *port, int ai_family);
|
||||
extern void udp_send (int sock, char *text, int len, struct _sockaddr *sAddr, int ai_family);
|
||||
extern void udp_close (int sock);
|
||||
|
||||
#endif
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,275 +1,275 @@
|
||||
/* network packets.. */
|
||||
|
||||
|
||||
enum _network_data {
|
||||
PKG_error = 0,
|
||||
PKG_pingreq,
|
||||
PKG_pingack,
|
||||
PKG_playerid,
|
||||
PKG_servermode,
|
||||
PKG_quit,
|
||||
PKG_field,
|
||||
PKG_playerdata,
|
||||
PKG_bombdata,
|
||||
PKG_getfield,
|
||||
PKG_getplayerdata,
|
||||
PKG_fieldline,
|
||||
PKG_playerstatus,
|
||||
PKG_pkgack,
|
||||
PKG_playermove,
|
||||
PKG_chat,
|
||||
PKG_ill,
|
||||
|
||||
PKG_bcmservchat = 90
|
||||
};
|
||||
|
||||
|
||||
enum _pkgflags {
|
||||
PKGF_ackreq = 1,
|
||||
PKGF_ipv6 = 2
|
||||
};
|
||||
|
||||
|
||||
struct pkgheader {
|
||||
unsigned char typ;
|
||||
unsigned char flags;
|
||||
short int id;
|
||||
short int len;
|
||||
};
|
||||
|
||||
|
||||
struct pkg {
|
||||
struct pkgheader h;
|
||||
char data[0];
|
||||
};
|
||||
|
||||
|
||||
struct pkg_bcmservchat {
|
||||
char typ;
|
||||
char data[128];
|
||||
};
|
||||
|
||||
|
||||
struct pkg_pkgack {
|
||||
struct pkgheader h;
|
||||
char typ;
|
||||
short int id;
|
||||
};
|
||||
|
||||
|
||||
struct pkg_ping {
|
||||
struct pkgheader h;
|
||||
int data;
|
||||
};
|
||||
|
||||
|
||||
struct pkg_field {
|
||||
struct pkgheader h;
|
||||
unsigned char x;
|
||||
unsigned char y;
|
||||
_field field;
|
||||
};
|
||||
|
||||
|
||||
struct pkg_error {
|
||||
struct pkgheader h;
|
||||
unsigned char nr;
|
||||
char text[128];
|
||||
};
|
||||
|
||||
|
||||
struct pkg_servermode {
|
||||
struct pkgheader h;
|
||||
unsigned char type;
|
||||
unsigned char state;
|
||||
unsigned char multitype;
|
||||
unsigned char players;
|
||||
unsigned char maxplayer;
|
||||
signed char last_winner;
|
||||
signed char fieldsize_x;
|
||||
signed char fieldsize_y;
|
||||
char tileset [LEN_TILESETNAME];
|
||||
signed char pl_nr; /* if the server sends this to a client...
|
||||
it will be the clients in_nr number
|
||||
(-1) for not set */
|
||||
|
||||
};
|
||||
|
||||
|
||||
struct pkg_playerid {
|
||||
struct pkgheader h;
|
||||
char name[LEN_PLAYERNAME];
|
||||
char host[LEN_SERVERNAME];
|
||||
char port[LEN_PORT];
|
||||
signed char ver_major; // Version
|
||||
signed char ver_minor; // Version
|
||||
signed char ver_sub; // Version
|
||||
signed char pl_nr; // Player Nummer
|
||||
signed char gfx_nr; // number of the graphic
|
||||
signed char state;
|
||||
short int points;
|
||||
short int wins;
|
||||
};
|
||||
|
||||
|
||||
struct pkg_playerdata {
|
||||
struct pkgheader h;
|
||||
signed char p_nr; // Playernumber
|
||||
short int points; // points
|
||||
short int wins; // how many times we win
|
||||
signed char gfx_nr; // the gfx number we want to use
|
||||
_point pos;
|
||||
unsigned char bombs_n;
|
||||
unsigned char range;
|
||||
unsigned char state;
|
||||
unsigned char d;
|
||||
unsigned char frame;
|
||||
signed char dead_by;
|
||||
};
|
||||
|
||||
|
||||
struct pkg_playermove {
|
||||
struct pkgheader h;
|
||||
signed char p_nr;
|
||||
signed char m;
|
||||
signed char d;
|
||||
signed char speed;
|
||||
_point pos;
|
||||
};
|
||||
|
||||
|
||||
struct pkg_bombdata {
|
||||
struct pkgheader h;
|
||||
unsigned char p_nr;
|
||||
unsigned char b_nr;
|
||||
unsigned char x;
|
||||
unsigned char y;
|
||||
unsigned char state;
|
||||
unsigned char r;
|
||||
int ex_nr;
|
||||
int to;
|
||||
};
|
||||
|
||||
|
||||
struct pkg_quit {
|
||||
struct pkgheader h;
|
||||
char host[LEN_SERVERNAME];
|
||||
char port[LEN_PORT];
|
||||
};
|
||||
|
||||
|
||||
struct pkg_getfield {
|
||||
struct pkgheader h;
|
||||
signed char line;
|
||||
};
|
||||
|
||||
|
||||
struct pkg_playerstatus {
|
||||
struct pkgheader h;
|
||||
signed char pl_nr;
|
||||
signed char net_istep;
|
||||
signed char status;
|
||||
};
|
||||
|
||||
|
||||
struct pkg_fieldline {
|
||||
struct pkgheader h;
|
||||
signed char line;
|
||||
unsigned char type[MAX_FIELDSIZE_X];
|
||||
unsigned char special[MAX_FIELDSIZE_X];
|
||||
};
|
||||
|
||||
|
||||
struct pkg_ill {
|
||||
struct pkgheader h;
|
||||
signed char pl_nr;
|
||||
short int to[PI_max];
|
||||
};
|
||||
|
||||
|
||||
struct pkg_getplayerdata {
|
||||
struct pkgheader h;
|
||||
signed char pl_nr;
|
||||
};
|
||||
|
||||
|
||||
struct pkg_chat {
|
||||
struct pkgheader h;
|
||||
char text[128];
|
||||
};
|
||||
|
||||
|
||||
struct _rscache_entry {
|
||||
signed char pl_nr; // playernumber to whom this data should go
|
||||
short int len; // size of the entry
|
||||
Uint32 timestamp; // pointer to the timestamp
|
||||
signed char retry; // retry's how many times we tryed this
|
||||
_net_addr addr; // pointer to the address
|
||||
struct pkg packet; // pointer to the packet
|
||||
};
|
||||
|
||||
|
||||
struct _resend_cache {
|
||||
char *data; // will hold the pointer to out cache
|
||||
struct _rscache_entry *entry; // pointer to our data
|
||||
int fill; // how much we have used
|
||||
};
|
||||
|
||||
|
||||
struct _inpkg_index {
|
||||
signed char pl_nr;
|
||||
unsigned char typ;
|
||||
short int id;
|
||||
};
|
||||
|
||||
|
||||
extern int do_error (struct pkg_error *data, _net_addr *addr);
|
||||
extern void do_playerid (struct pkg_playerid *p_id, _net_addr *addr);
|
||||
extern void do_servermode (struct pkg_servermode *s_mod, _net_addr *addr);
|
||||
extern void do_field (struct pkg_field *f_dat, _net_addr *addr);
|
||||
extern void do_ping (struct pkg_ping *p_dat, _net_addr *addr);
|
||||
extern void do_playerdata (struct pkg_playerdata *p_dat, _net_addr *addr);
|
||||
extern void do_playermove (struct pkg_playermove *p_dat, _net_addr *addr);
|
||||
extern void do_bombdata (struct pkg_bombdata *b_dat, _net_addr *addr);
|
||||
extern void do_quit (struct pkg_quit *q_dat, _net_addr *addr);
|
||||
extern void do_getfield (struct pkg_getfield *gf_dat, _net_addr *addr);
|
||||
extern void do_fieldline (struct pkg_fieldline *f_dat, _net_addr *addr);
|
||||
extern void do_getplayerdata (struct pkg_getplayerdata *gp_dat, _net_addr *addr);
|
||||
extern void do_playerstatus (struct pkg_playerstatus *gp_dat, _net_addr *addr);
|
||||
extern void do_pkgack (struct pkg_pkgack *p_ack, _net_addr *addr);
|
||||
extern void do_chat (struct pkg_chat *chat_pkg, _net_addr *addr);
|
||||
extern int do_pkg (struct pkg *packet, _net_addr *addr);
|
||||
extern void do_bcmservchat (struct pkg_bcmservchat *packet, _net_addr *addr);
|
||||
extern void do_ill (struct pkg_ill *ill_pkg, _net_addr *addr);
|
||||
|
||||
|
||||
extern void send_pkg (struct pkg *packet, _net_addr *addr);
|
||||
extern void send_playerid (_net_addr *addr, char *name, char *pladdr, char *plport, int p_nr, int gfx_nr);
|
||||
extern void send_servermode (_net_addr *addr, int pl_nr);
|
||||
extern void send_error (_net_addr *addr, char *text);
|
||||
extern void send_field (_net_addr *addr, int x, int y, _field * field);
|
||||
extern void send_ping (_net_addr *addr, int data, unsigned char typ);
|
||||
extern void send_playerdata (_net_addr *addr, int p_nr, _player * pl);
|
||||
extern void send_playermove (_net_addr *addr, int p_nr, _player * pl);
|
||||
extern void send_bombdata (_net_addr *addr, int p, int b, _bomb * bomb);
|
||||
extern void send_quit (_net_addr *addr, char *plhost, char *plport);
|
||||
extern void send_getfield (_net_addr *addr, int line);
|
||||
extern void send_fieldline (_net_addr *addr, int line);
|
||||
extern void send_getplayerdata (_net_addr *addr, int pl);
|
||||
extern void send_playerstatus (_net_addr *addr, int pl_nr, int net_istep, int status);
|
||||
extern void send_pkgack (_net_addr *addr, unsigned char typ, short int id);
|
||||
extern void send_chat (_net_addr *addr, char *text);
|
||||
extern void send_ill (_net_addr *addr, int p_nr, _player *pl);
|
||||
|
||||
extern int get_player_nr (char *host, char *port);
|
||||
extern int inpkg_check (unsigned char typ, short int id, _net_addr *addr);
|
||||
|
||||
|
||||
/* this functions will be defined in pkgcache.c */
|
||||
extern int rscache_add (_net_addr *addr, struct pkg *packet);
|
||||
extern void rscache_del ();
|
||||
extern int rscache_getpos (_net_addr *addr, unsigned char typ, short int id);
|
||||
extern int rscache_getcurlen ();
|
||||
extern void rscache_loop ();
|
||||
|
||||
extern struct _resend_cache resend_cache;
|
||||
/* network packets.. */
|
||||
|
||||
|
||||
enum _network_data {
|
||||
PKG_error = 0,
|
||||
PKG_pingreq,
|
||||
PKG_pingack,
|
||||
PKG_playerid,
|
||||
PKG_servermode,
|
||||
PKG_quit,
|
||||
PKG_field,
|
||||
PKG_playerdata,
|
||||
PKG_bombdata,
|
||||
PKG_getfield,
|
||||
PKG_getplayerdata,
|
||||
PKG_fieldline,
|
||||
PKG_playerstatus,
|
||||
PKG_pkgack,
|
||||
PKG_playermove,
|
||||
PKG_chat,
|
||||
PKG_ill,
|
||||
|
||||
PKG_bcmservchat = 90
|
||||
};
|
||||
|
||||
|
||||
enum _pkgflags {
|
||||
PKGF_ackreq = 1,
|
||||
PKGF_ipv6 = 2
|
||||
};
|
||||
|
||||
|
||||
struct pkgheader {
|
||||
unsigned char typ;
|
||||
unsigned char flags;
|
||||
short int id;
|
||||
short int len;
|
||||
};
|
||||
|
||||
|
||||
struct pkg {
|
||||
struct pkgheader h;
|
||||
char data[0];
|
||||
};
|
||||
|
||||
|
||||
struct pkg_bcmservchat {
|
||||
char typ;
|
||||
char data[128];
|
||||
};
|
||||
|
||||
|
||||
struct pkg_pkgack {
|
||||
struct pkgheader h;
|
||||
char typ;
|
||||
short int id;
|
||||
};
|
||||
|
||||
|
||||
struct pkg_ping {
|
||||
struct pkgheader h;
|
||||
int data;
|
||||
};
|
||||
|
||||
|
||||
struct pkg_field {
|
||||
struct pkgheader h;
|
||||
unsigned char x;
|
||||
unsigned char y;
|
||||
_field field;
|
||||
};
|
||||
|
||||
|
||||
struct pkg_error {
|
||||
struct pkgheader h;
|
||||
unsigned char nr;
|
||||
char text[128];
|
||||
};
|
||||
|
||||
|
||||
struct pkg_servermode {
|
||||
struct pkgheader h;
|
||||
unsigned char type;
|
||||
unsigned char state;
|
||||
unsigned char multitype;
|
||||
unsigned char players;
|
||||
unsigned char maxplayer;
|
||||
signed char last_winner;
|
||||
signed char fieldsize_x;
|
||||
signed char fieldsize_y;
|
||||
char tileset [LEN_TILESETNAME];
|
||||
signed char pl_nr; /* if the server sends this to a client...
|
||||
it will be the clients in_nr number
|
||||
(-1) for not set */
|
||||
|
||||
};
|
||||
|
||||
|
||||
struct pkg_playerid {
|
||||
struct pkgheader h;
|
||||
char name[LEN_PLAYERNAME];
|
||||
char host[LEN_SERVERNAME];
|
||||
char port[LEN_PORT];
|
||||
signed char ver_major; // Version
|
||||
signed char ver_minor; // Version
|
||||
signed char ver_sub; // Version
|
||||
signed char pl_nr; // Player Nummer
|
||||
signed char gfx_nr; // number of the graphic
|
||||
signed char state;
|
||||
short int points;
|
||||
short int wins;
|
||||
};
|
||||
|
||||
|
||||
struct pkg_playerdata {
|
||||
struct pkgheader h;
|
||||
signed char p_nr; // Playernumber
|
||||
short int points; // points
|
||||
short int wins; // how many times we win
|
||||
signed char gfx_nr; // the gfx number we want to use
|
||||
_point pos;
|
||||
unsigned char bombs_n;
|
||||
unsigned char range;
|
||||
unsigned char state;
|
||||
unsigned char d;
|
||||
unsigned char frame;
|
||||
signed char dead_by;
|
||||
};
|
||||
|
||||
|
||||
struct pkg_playermove {
|
||||
struct pkgheader h;
|
||||
signed char p_nr;
|
||||
signed char m;
|
||||
signed char d;
|
||||
signed char speed;
|
||||
_point pos;
|
||||
};
|
||||
|
||||
|
||||
struct pkg_bombdata {
|
||||
struct pkgheader h;
|
||||
unsigned char p_nr;
|
||||
unsigned char b_nr;
|
||||
unsigned char x;
|
||||
unsigned char y;
|
||||
unsigned char state;
|
||||
unsigned char r;
|
||||
int ex_nr;
|
||||
int to;
|
||||
};
|
||||
|
||||
|
||||
struct pkg_quit {
|
||||
struct pkgheader h;
|
||||
char host[LEN_SERVERNAME];
|
||||
char port[LEN_PORT];
|
||||
};
|
||||
|
||||
|
||||
struct pkg_getfield {
|
||||
struct pkgheader h;
|
||||
signed char line;
|
||||
};
|
||||
|
||||
|
||||
struct pkg_playerstatus {
|
||||
struct pkgheader h;
|
||||
signed char pl_nr;
|
||||
signed char net_istep;
|
||||
signed char status;
|
||||
};
|
||||
|
||||
|
||||
struct pkg_fieldline {
|
||||
struct pkgheader h;
|
||||
signed char line;
|
||||
unsigned char type[MAX_FIELDSIZE_X];
|
||||
unsigned char special[MAX_FIELDSIZE_X];
|
||||
};
|
||||
|
||||
|
||||
struct pkg_ill {
|
||||
struct pkgheader h;
|
||||
signed char pl_nr;
|
||||
short int to[PI_max];
|
||||
};
|
||||
|
||||
|
||||
struct pkg_getplayerdata {
|
||||
struct pkgheader h;
|
||||
signed char pl_nr;
|
||||
};
|
||||
|
||||
|
||||
struct pkg_chat {
|
||||
struct pkgheader h;
|
||||
char text[128];
|
||||
};
|
||||
|
||||
|
||||
struct _rscache_entry {
|
||||
signed char pl_nr; // playernumber to whom this data should go
|
||||
short int len; // size of the entry
|
||||
Uint32 timestamp; // pointer to the timestamp
|
||||
signed char retry; // retry's how many times we tryed this
|
||||
_net_addr addr; // pointer to the address
|
||||
struct pkg packet; // pointer to the packet
|
||||
};
|
||||
|
||||
|
||||
struct _resend_cache {
|
||||
char *data; // will hold the pointer to out cache
|
||||
struct _rscache_entry *entry; // pointer to our data
|
||||
int fill; // how much we have used
|
||||
};
|
||||
|
||||
|
||||
struct _inpkg_index {
|
||||
signed char pl_nr;
|
||||
unsigned char typ;
|
||||
short int id;
|
||||
};
|
||||
|
||||
|
||||
extern int do_error (struct pkg_error *data, _net_addr *addr);
|
||||
extern void do_playerid (struct pkg_playerid *p_id, _net_addr *addr);
|
||||
extern void do_servermode (struct pkg_servermode *s_mod, _net_addr *addr);
|
||||
extern void do_field (struct pkg_field *f_dat, _net_addr *addr);
|
||||
extern void do_ping (struct pkg_ping *p_dat, _net_addr *addr);
|
||||
extern void do_playerdata (struct pkg_playerdata *p_dat, _net_addr *addr);
|
||||
extern void do_playermove (struct pkg_playermove *p_dat, _net_addr *addr);
|
||||
extern void do_bombdata (struct pkg_bombdata *b_dat, _net_addr *addr);
|
||||
extern void do_quit (struct pkg_quit *q_dat, _net_addr *addr);
|
||||
extern void do_getfield (struct pkg_getfield *gf_dat, _net_addr *addr);
|
||||
extern void do_fieldline (struct pkg_fieldline *f_dat, _net_addr *addr);
|
||||
extern void do_getplayerdata (struct pkg_getplayerdata *gp_dat, _net_addr *addr);
|
||||
extern void do_playerstatus (struct pkg_playerstatus *gp_dat, _net_addr *addr);
|
||||
extern void do_pkgack (struct pkg_pkgack *p_ack, _net_addr *addr);
|
||||
extern void do_chat (struct pkg_chat *chat_pkg, _net_addr *addr);
|
||||
extern int do_pkg (struct pkg *packet, _net_addr *addr);
|
||||
extern void do_bcmservchat (struct pkg_bcmservchat *packet, _net_addr *addr);
|
||||
extern void do_ill (struct pkg_ill *ill_pkg, _net_addr *addr);
|
||||
|
||||
|
||||
extern void send_pkg (struct pkg *packet, _net_addr *addr);
|
||||
extern void send_playerid (_net_addr *addr, char *name, char *pladdr, char *plport, int p_nr, int gfx_nr);
|
||||
extern void send_servermode (_net_addr *addr, int pl_nr);
|
||||
extern void send_error (_net_addr *addr, char *text);
|
||||
extern void send_field (_net_addr *addr, int x, int y, _field * field);
|
||||
extern void send_ping (_net_addr *addr, int data, unsigned char typ);
|
||||
extern void send_playerdata (_net_addr *addr, int p_nr, _player * pl);
|
||||
extern void send_playermove (_net_addr *addr, int p_nr, _player * pl);
|
||||
extern void send_bombdata (_net_addr *addr, int p, int b, _bomb * bomb);
|
||||
extern void send_quit (_net_addr *addr, char *plhost, char *plport);
|
||||
extern void send_getfield (_net_addr *addr, int line);
|
||||
extern void send_fieldline (_net_addr *addr, int line);
|
||||
extern void send_getplayerdata (_net_addr *addr, int pl);
|
||||
extern void send_playerstatus (_net_addr *addr, int pl_nr, int net_istep, int status);
|
||||
extern void send_pkgack (_net_addr *addr, unsigned char typ, short int id);
|
||||
extern void send_chat (_net_addr *addr, char *text);
|
||||
extern void send_ill (_net_addr *addr, int p_nr, _player *pl);
|
||||
|
||||
extern int get_player_nr (char *host, char *port);
|
||||
extern int inpkg_check (unsigned char typ, short int id, _net_addr *addr);
|
||||
|
||||
|
||||
/* this functions will be defined in pkgcache.c */
|
||||
extern int rscache_add (_net_addr *addr, struct pkg *packet);
|
||||
extern void rscache_del ();
|
||||
extern int rscache_getpos (_net_addr *addr, unsigned char typ, short int id);
|
||||
extern int rscache_getcurlen ();
|
||||
extern void rscache_loop ();
|
||||
|
||||
extern struct _resend_cache resend_cache;
|
||||
|
@ -1,161 +1,161 @@
|
||||
#include "bomberclone.h"
|
||||
#include "network.h"
|
||||
#include "packets.h"
|
||||
|
||||
/*
|
||||
set pointers at the giving pos
|
||||
*/
|
||||
void
|
||||
rscache_setpointer (int pos)
|
||||
{
|
||||
resend_cache.entry = (struct _rscache_entry *) (((char *) resend_cache.data) + pos);
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
add a packet to the cache and sets the timestamp
|
||||
*/
|
||||
int
|
||||
rscache_add (_net_addr * addr, struct pkg *packet)
|
||||
{
|
||||
int newlen;
|
||||
|
||||
if (resend_cache.fill + sizeof (struct _rscache_entry) > PKG_RESENDCACHE_SIZE)
|
||||
return -1;
|
||||
|
||||
rscache_setpointer (resend_cache.fill);
|
||||
resend_cache.entry->retry = 0;
|
||||
resend_cache.entry->timestamp = timestamp;
|
||||
memcpy (&resend_cache.entry->addr, addr, sizeof (_net_addr));
|
||||
memcpy (&resend_cache.entry->packet, packet, packet->h.len);
|
||||
|
||||
newlen = resend_cache.fill + rscache_getcurlen ();
|
||||
|
||||
resend_cache.fill = newlen;
|
||||
|
||||
return 0;
|
||||
};
|
||||
|
||||
/*
|
||||
deletes the packet at current pointer in the cache
|
||||
*/
|
||||
void
|
||||
rscache_del ()
|
||||
{
|
||||
int len,
|
||||
size;
|
||||
char *pos1;
|
||||
|
||||
/* check if we are able to delete */
|
||||
if ((char *) resend_cache.data > (char *) resend_cache.entry ||
|
||||
(char *) resend_cache.entry > (char *) resend_cache.data + resend_cache.fill ||
|
||||
resend_cache.fill == -1 || resend_cache.data == NULL) {
|
||||
d_printf ("rscache_del: something wrong with the cache\n");
|
||||
exit (1);
|
||||
return;
|
||||
}
|
||||
|
||||
/* newlen = size of the cacheentry we are going to delete */
|
||||
len = rscache_getcurlen ();
|
||||
|
||||
if (resend_cache.fill <= len) /* something went wrong, fill is smaler as the cacheentry, delete the cache */
|
||||
resend_cache.fill = 0;
|
||||
else {
|
||||
pos1 = (char *) resend_cache.entry + len;
|
||||
size = PKG_RESENDCACHE_SIZE - (pos1 - resend_cache.data);
|
||||
|
||||
if (resend_cache.fill < PKG_RESENDCACHE_SIZE) {
|
||||
memmove (resend_cache.entry, pos1, size);
|
||||
resend_cache.fill = resend_cache.fill - len;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
get the position in the cache where our needed packet is
|
||||
*/
|
||||
int
|
||||
rscache_getpos (_net_addr * addr, unsigned char typ, short int id)
|
||||
{
|
||||
int len,
|
||||
pos,
|
||||
done = 0;
|
||||
|
||||
for (pos = 0; (pos < resend_cache.fill && done == 0);) {
|
||||
|
||||
rscache_setpointer (pos);
|
||||
|
||||
/* get size of the cacheentry */
|
||||
len = rscache_getcurlen ();
|
||||
|
||||
if (strcmp (addr->host, resend_cache.entry->addr.host) == 0 &&
|
||||
strcmp (addr->port, resend_cache.entry->addr.port) == 0 &&
|
||||
typ == resend_cache.entry->packet.h.typ && id == resend_cache.entry->packet.h.id)
|
||||
done = 1; /* we have found the old packet */
|
||||
else
|
||||
pos = pos + len;
|
||||
}
|
||||
|
||||
if (done == 0) /* we have found nothing */
|
||||
return -1;
|
||||
|
||||
return pos;
|
||||
};
|
||||
|
||||
/* get the len of the current entry */
|
||||
int
|
||||
rscache_getcurlen ()
|
||||
{
|
||||
int len;
|
||||
|
||||
len = sizeof (struct _rscache_entry) - sizeof (struct pkg) + resend_cache.entry->packet.h.len;
|
||||
|
||||
return len;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
the loop for the cache.. to see what will have to be resend
|
||||
*/
|
||||
void
|
||||
rscache_loop ()
|
||||
{
|
||||
int len,
|
||||
pos,
|
||||
timeout = RESENDCACHE_TIMEOUT;
|
||||
|
||||
for (pos = 0; pos < resend_cache.fill && pos < PKG_RESENDCACHE_SIZE && pos >= 0;) {
|
||||
|
||||
rscache_setpointer (pos);
|
||||
len = rscache_getcurlen ();
|
||||
|
||||
if (timestamp - resend_cache.entry->timestamp >= timeout
|
||||
&& resend_cache.entry->retry < RESENDCACHE_RETRY) {
|
||||
/* send it again */
|
||||
d_printf
|
||||
("Data Send Timeout (%s:%s) Resend now Package Fill %d, Pos %d\n",
|
||||
resend_cache.entry->addr.host, resend_cache.entry->addr.port, resend_cache.fill,
|
||||
pos);
|
||||
udp_send (bman.sock, (char *) &resend_cache.entry->packet,
|
||||
resend_cache.entry->packet.h.len, &resend_cache.entry->addr.sAddr,
|
||||
bman.net_ai_family);
|
||||
resend_cache.entry->timestamp = timestamp;
|
||||
resend_cache.entry->retry++;
|
||||
if (resend_cache.entry->addr.pl_nr >= 0 && resend_cache.entry->addr.pl_nr < MAX_PLAYERS)
|
||||
bman.players[resend_cache.entry->addr.pl_nr].net.pkgopt.to_2sec++;
|
||||
}
|
||||
|
||||
if (timestamp - resend_cache.entry->timestamp >= timeout
|
||||
&& resend_cache.entry->retry >= RESENDCACHE_RETRY) {
|
||||
d_printf ("Data Send Timeout (%s:%s) Delete now Package Fill %d, Pos %d\n",
|
||||
resend_cache.entry->addr.host, resend_cache.entry->addr.port,
|
||||
resend_cache.fill, pos);
|
||||
if (resend_cache.entry->addr.pl_nr >= 0 && resend_cache.entry->addr.pl_nr < MAX_PLAYERS)
|
||||
bman.players[resend_cache.entry->addr.pl_nr].net.pkgopt.to_2sec++;
|
||||
|
||||
rscache_del ();
|
||||
}
|
||||
else
|
||||
pos = pos + len;
|
||||
}
|
||||
};
|
||||
#include "bomberclone.h"
|
||||
#include "network.h"
|
||||
#include "packets.h"
|
||||
|
||||
/*
|
||||
set pointers at the giving pos
|
||||
*/
|
||||
void
|
||||
rscache_setpointer (int pos)
|
||||
{
|
||||
resend_cache.entry = (struct _rscache_entry *) (((char *) resend_cache.data) + pos);
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
add a packet to the cache and sets the timestamp
|
||||
*/
|
||||
int
|
||||
rscache_add (_net_addr * addr, struct pkg *packet)
|
||||
{
|
||||
int newlen;
|
||||
|
||||
if (resend_cache.fill + sizeof (struct _rscache_entry) > PKG_RESENDCACHE_SIZE)
|
||||
return -1;
|
||||
|
||||
rscache_setpointer (resend_cache.fill);
|
||||
resend_cache.entry->retry = 0;
|
||||
resend_cache.entry->timestamp = timestamp;
|
||||
memcpy (&resend_cache.entry->addr, addr, sizeof (_net_addr));
|
||||
memcpy (&resend_cache.entry->packet, packet, packet->h.len);
|
||||
|
||||
newlen = resend_cache.fill + rscache_getcurlen ();
|
||||
|
||||
resend_cache.fill = newlen;
|
||||
|
||||
return 0;
|
||||
};
|
||||
|
||||
/*
|
||||
deletes the packet at current pointer in the cache
|
||||
*/
|
||||
void
|
||||
rscache_del ()
|
||||
{
|
||||
int len,
|
||||
size;
|
||||
char *pos1;
|
||||
|
||||
/* check if we are able to delete */
|
||||
if ((char *) resend_cache.data > (char *) resend_cache.entry ||
|
||||
(char *) resend_cache.entry > (char *) resend_cache.data + resend_cache.fill ||
|
||||
resend_cache.fill == -1 || resend_cache.data == NULL) {
|
||||
d_printf ("rscache_del: something wrong with the cache\n");
|
||||
exit (1);
|
||||
return;
|
||||
}
|
||||
|
||||
/* newlen = size of the cacheentry we are going to delete */
|
||||
len = rscache_getcurlen ();
|
||||
|
||||
if (resend_cache.fill <= len) /* something went wrong, fill is smaler as the cacheentry, delete the cache */
|
||||
resend_cache.fill = 0;
|
||||
else {
|
||||
pos1 = (char *) resend_cache.entry + len;
|
||||
size = PKG_RESENDCACHE_SIZE - (pos1 - resend_cache.data);
|
||||
|
||||
if (resend_cache.fill < PKG_RESENDCACHE_SIZE) {
|
||||
memmove (resend_cache.entry, pos1, size);
|
||||
resend_cache.fill = resend_cache.fill - len;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
get the position in the cache where our needed packet is
|
||||
*/
|
||||
int
|
||||
rscache_getpos (_net_addr * addr, unsigned char typ, short int id)
|
||||
{
|
||||
int len,
|
||||
pos,
|
||||
done = 0;
|
||||
|
||||
for (pos = 0; (pos < resend_cache.fill && done == 0);) {
|
||||
|
||||
rscache_setpointer (pos);
|
||||
|
||||
/* get size of the cacheentry */
|
||||
len = rscache_getcurlen ();
|
||||
|
||||
if (strcmp (addr->host, resend_cache.entry->addr.host) == 0 &&
|
||||
strcmp (addr->port, resend_cache.entry->addr.port) == 0 &&
|
||||
typ == resend_cache.entry->packet.h.typ && id == resend_cache.entry->packet.h.id)
|
||||
done = 1; /* we have found the old packet */
|
||||
else
|
||||
pos = pos + len;
|
||||
}
|
||||
|
||||
if (done == 0) /* we have found nothing */
|
||||
return -1;
|
||||
|
||||
return pos;
|
||||
};
|
||||
|
||||
/* get the len of the current entry */
|
||||
int
|
||||
rscache_getcurlen ()
|
||||
{
|
||||
int len;
|
||||
|
||||
len = sizeof (struct _rscache_entry) - sizeof (struct pkg) + resend_cache.entry->packet.h.len;
|
||||
|
||||
return len;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
the loop for the cache.. to see what will have to be resend
|
||||
*/
|
||||
void
|
||||
rscache_loop ()
|
||||
{
|
||||
int len,
|
||||
pos,
|
||||
timeout = RESENDCACHE_TIMEOUT;
|
||||
|
||||
for (pos = 0; pos < resend_cache.fill && pos < PKG_RESENDCACHE_SIZE && pos >= 0;) {
|
||||
|
||||
rscache_setpointer (pos);
|
||||
len = rscache_getcurlen ();
|
||||
|
||||
if (timestamp - resend_cache.entry->timestamp >= timeout
|
||||
&& resend_cache.entry->retry < RESENDCACHE_RETRY) {
|
||||
/* send it again */
|
||||
d_printf
|
||||
("Data Send Timeout (%s:%s) Resend now Package Fill %d, Pos %d\n",
|
||||
resend_cache.entry->addr.host, resend_cache.entry->addr.port, resend_cache.fill,
|
||||
pos);
|
||||
udp_send (bman.sock, (char *) &resend_cache.entry->packet,
|
||||
resend_cache.entry->packet.h.len, &resend_cache.entry->addr.sAddr,
|
||||
bman.net_ai_family);
|
||||
resend_cache.entry->timestamp = timestamp;
|
||||
resend_cache.entry->retry++;
|
||||
if (resend_cache.entry->addr.pl_nr >= 0 && resend_cache.entry->addr.pl_nr < MAX_PLAYERS)
|
||||
bman.players[resend_cache.entry->addr.pl_nr].net.pkgopt.to_2sec++;
|
||||
}
|
||||
|
||||
if (timestamp - resend_cache.entry->timestamp >= timeout
|
||||
&& resend_cache.entry->retry >= RESENDCACHE_RETRY) {
|
||||
d_printf ("Data Send Timeout (%s:%s) Delete now Package Fill %d, Pos %d\n",
|
||||
resend_cache.entry->addr.host, resend_cache.entry->addr.port,
|
||||
resend_cache.fill, pos);
|
||||
if (resend_cache.entry->addr.pl_nr >= 0 && resend_cache.entry->addr.pl_nr < MAX_PLAYERS)
|
||||
bman.players[resend_cache.entry->addr.pl_nr].net.pkgopt.to_2sec++;
|
||||
|
||||
rscache_del ();
|
||||
}
|
||||
else
|
||||
pos = pos + len;
|
||||
}
|
||||
};
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,75 +1,66 @@
|
||||
/* $Id: single.c,v 1.8 2003/05/07 14:30:41 stpohle Exp $ */
|
||||
/* single player */
|
||||
|
||||
#include "basic.h"
|
||||
#include "bomberclone.h"
|
||||
|
||||
void
|
||||
single_game_new (int ai_players)
|
||||
{
|
||||
int p,
|
||||
i;
|
||||
char *tileset;
|
||||
char pathname [LEN_PATHFILENAME];
|
||||
|
||||
// set players on field 1,1
|
||||
for (p = 0; p < MAX_PLAYERS; p++) {
|
||||
bman.players[p].pos.x = -1;
|
||||
bman.players[p].pos.y = -1;
|
||||
bman.players[p].state = 0;
|
||||
|
||||
// reset bombs
|
||||
bman.players[p].bombs_n = START_BOMBS;
|
||||
bman.players[p].range = START_RANGE;
|
||||
bman.players[p].speed = START_SPEED;
|
||||
for (i = 0; i < MAX_BOMBS; i++) {
|
||||
bman.players[p].bombs[i].state = BS_off;
|
||||
bman.players[p].bombs[i].ex_nr = -1;
|
||||
}
|
||||
|
||||
for (i = 0; i < PI_max; i++)
|
||||
bman.players[p].ill[i].to = 0;
|
||||
bman.players[p].frame = 0;
|
||||
bman.players[p].frameto = 0;
|
||||
bman.players[p].d = 0;
|
||||
}
|
||||
|
||||
bman.p_nr = 0;
|
||||
bman.players[bman.p_nr].state = PSFM_alife;
|
||||
player_set_gfx (&bman.players[bman.p_nr], 0);
|
||||
bman.last_ex_nr = 1;
|
||||
|
||||
field_new (bman.fieldpath);
|
||||
|
||||
sprintf (pathname , "%s/tileset", bman.datapath);
|
||||
tileset = menu_dir_select ("Select Tileset", pathname, DF_dir);
|
||||
if (tileset == NULL)
|
||||
tileset_random ();
|
||||
else
|
||||
strncpy (gfx.tileset, tileset, LEN_TILESETNAME);
|
||||
|
||||
bman.players_nr_s = 1;
|
||||
bman.players_nr = 1;
|
||||
bman.gametype = GT_single;
|
||||
bman.state = GS_running;
|
||||
};
|
||||
|
||||
|
||||
void single_loop () {
|
||||
|
||||
};
|
||||
|
||||
|
||||
void single_create_ai () {
|
||||
int p;
|
||||
_player *pl;
|
||||
|
||||
/* find free players */
|
||||
for (pl = NULL, p = 0; (pl == NULL && p < MAX_PLAYERS); p++)
|
||||
if (!(PS_IS_used (bman.players[p].state)))
|
||||
pl = &bman.players[p];
|
||||
|
||||
if (pl == NULL)
|
||||
return;
|
||||
|
||||
};
|
||||
/* $Id: single.c,v 1.9 2003/05/07 21:28:13 stpohle Exp $ */
|
||||
/* single player */
|
||||
|
||||
#include "basic.h"
|
||||
#include "bomberclone.h"
|
||||
|
||||
void
|
||||
single_game_new (int ai_players)
|
||||
{
|
||||
int p,
|
||||
i;
|
||||
|
||||
// set players on field 1,1
|
||||
for (p = 0; p < MAX_PLAYERS; p++) {
|
||||
bman.players[p].pos.x = -1;
|
||||
bman.players[p].pos.y = -1;
|
||||
bman.players[p].state = 0;
|
||||
|
||||
// reset bombs
|
||||
bman.players[p].bombs_n = START_BOMBS;
|
||||
bman.players[p].range = START_RANGE;
|
||||
bman.players[p].speed = START_SPEED;
|
||||
for (i = 0; i < MAX_BOMBS; i++) {
|
||||
bman.players[p].bombs[i].state = BS_off;
|
||||
bman.players[p].bombs[i].ex_nr = -1;
|
||||
}
|
||||
|
||||
for (i = 0; i < PI_max; i++)
|
||||
bman.players[p].ill[i].to = 0;
|
||||
bman.players[p].frame = 0;
|
||||
bman.players[p].frameto = 0;
|
||||
bman.players[p].d = 0;
|
||||
}
|
||||
|
||||
bman.p_nr = 0;
|
||||
bman.players[bman.p_nr].state = PSFM_alife;
|
||||
player_set_gfx (&bman.players[bman.p_nr], 0);
|
||||
bman.last_ex_nr = 1;
|
||||
|
||||
init_map_tileset();
|
||||
|
||||
bman.players_nr_s = 1;
|
||||
bman.players_nr = 1;
|
||||
bman.gametype = GT_single;
|
||||
bman.state = GS_running;
|
||||
};
|
||||
|
||||
|
||||
void single_loop () {
|
||||
|
||||
};
|
||||
|
||||
|
||||
void single_create_ai () {
|
||||
int p;
|
||||
_player *pl;
|
||||
|
||||
/* find free players */
|
||||
for (pl = NULL, p = 0; (pl == NULL && p < MAX_PLAYERS); p++)
|
||||
if (!(PS_IS_used (bman.players[p].state)))
|
||||
pl = &bman.players[p];
|
||||
|
||||
if (pl == NULL)
|
||||
return;
|
||||
|
||||
};
|
||||
|
@ -1,27 +1,27 @@
|
||||
/* $Id: sysfunc.h,v 1.3 2003/05/07 00:21:38 stpohle Exp $ */
|
||||
/* include some system near functions */
|
||||
|
||||
#ifndef _SYSFUNC_H_
|
||||
#define _SYSFUNC_H_
|
||||
|
||||
#define MAX_DIRENTRYS 1024
|
||||
|
||||
enum _dirflags {
|
||||
DF_dir = 1,
|
||||
DF_file = 2
|
||||
};
|
||||
|
||||
struct __direntry {
|
||||
unsigned char flags;
|
||||
char name[LEN_FILENAME];
|
||||
struct __direntry *next;
|
||||
} typedef _direntry;
|
||||
|
||||
extern void s_delay (int ms);
|
||||
extern int s_random (int maxnr);
|
||||
extern char *s_gethomedir ();
|
||||
|
||||
extern _direntry *s_getdir (char *path);
|
||||
extern _direntry *s_dirfilter (_direntry *dirstart, signed char dirflags);
|
||||
|
||||
#endif
|
||||
/* $Id: sysfunc.h,v 1.4 2003/05/07 21:28:13 stpohle Exp $ */
|
||||
/* include some system near functions */
|
||||
|
||||
#ifndef _SYSFUNC_H_
|
||||
#define _SYSFUNC_H_
|
||||
|
||||
#define MAX_DIRENTRYS 1024
|
||||
|
||||
enum _dirflags {
|
||||
DF_dir = 1,
|
||||
DF_file = 2
|
||||
};
|
||||
|
||||
struct __direntry {
|
||||
unsigned char flags;
|
||||
char name[LEN_FILENAME];
|
||||
struct __direntry *next;
|
||||
} typedef _direntry;
|
||||
|
||||
extern void s_delay (int ms);
|
||||
extern int s_random (int maxnr);
|
||||
extern char *s_gethomedir ();
|
||||
|
||||
extern _direntry *s_getdir (char *path);
|
||||
extern _direntry *s_dirfilter (_direntry *dirstart, signed char dirflags);
|
||||
|
||||
#endif
|
||||
|
@ -1,300 +1,300 @@
|
||||
/* $Id: udp.c,v 1.5 2003/05/06 22:33:40 ob1kenewb Exp $ */
|
||||
/* udp.c code for the network
|
||||
File Version 0.2
|
||||
*/
|
||||
|
||||
#define UDP_LEN_HOSTNAME 128
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <time.h>
|
||||
#ifdef _WIN32
|
||||
#include <winsock.h>
|
||||
#include <io.h>
|
||||
#else
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netdb.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#define _sockaddr sockaddr
|
||||
#define bzero(a,b) memset(a,'\0',b)
|
||||
#else
|
||||
#define _sockaddr sockaddr_in6
|
||||
#endif
|
||||
|
||||
extern char *dns_net_getip (char *host);
|
||||
extern int dns_filladdr (char *host, int hostlen, char *port, int portlen, int ai_family,
|
||||
struct _sockaddr *sAddr);
|
||||
extern int udp_get (int sock, char *text, int len, struct _sockaddr *sAddr, int ai_family);
|
||||
extern int udp_server (char *port, int ai_family);
|
||||
extern void udp_send (int sock, char *text, int len, struct _sockaddr *sAddr, int ai_family);
|
||||
extern void udp_close (int sock);
|
||||
|
||||
char dnsip[UDP_LEN_HOSTNAME];
|
||||
|
||||
extern void d_printf (char *fmt,...);
|
||||
|
||||
|
||||
/* closes an existing udp server */
|
||||
void
|
||||
udp_close (int sock)
|
||||
{
|
||||
if (sock != -1)
|
||||
close (sock);
|
||||
sock = -1;
|
||||
};
|
||||
|
||||
|
||||
int
|
||||
dns_filladdr (char *host, int hostlen, char *port, int portlen, int ai_family,
|
||||
struct _sockaddr *sAddr)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
struct hostent *he;
|
||||
char txt[255];
|
||||
|
||||
if (host[0] == 0 || port[0] == 0) {
|
||||
/* we have to complete server and port from the sAddr */
|
||||
|
||||
strncpy (host, inet_ntoa (((struct sockaddr_in *) sAddr)->sin_addr), hostlen);
|
||||
sprintf (txt, "%d", ntohs (((struct sockaddr_in *) sAddr)->sin_port));
|
||||
strncpy (port, txt, portlen);
|
||||
}
|
||||
else {
|
||||
/* we have to complete the sAddr struct */
|
||||
|
||||
if ((he = gethostbyname (host)) == NULL) { // get the host info
|
||||
perror ("dns_filladdr (gethostbyname)");
|
||||
return -1;
|
||||
}
|
||||
|
||||
((struct sockaddr_in *) sAddr)->sin_family = ai_family; // host byte order
|
||||
((struct sockaddr_in *) sAddr)->sin_port = htons (atoi (port)); // short, network byte order
|
||||
((struct sockaddr_in *) sAddr)->sin_addr = *((struct in_addr *) he->h_addr);
|
||||
memset (&(((struct sockaddr_in *) sAddr)->sin_zero), '\0', 8); // zero the rest of the struct
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
struct addrinfo hints,
|
||||
*res;
|
||||
int err, i,
|
||||
addrlen;
|
||||
|
||||
if (host[0] == 0 || port[0] == 0) {
|
||||
/* we have to complete server and port from the sAddr */
|
||||
|
||||
if (ai_family == PF_INET)
|
||||
addrlen = sizeof (struct sockaddr_in);
|
||||
else
|
||||
addrlen = sizeof (struct sockaddr_in6);
|
||||
|
||||
bzero (host, hostlen);
|
||||
bzero (port, portlen);
|
||||
|
||||
if ((err =
|
||||
getnameinfo ((struct sockaddr *) sAddr, addrlen, host, hostlen, port, portlen,
|
||||
NI_NUMERICHOST | NI_NUMERICSERV)) < 0) {
|
||||
d_printf ("dns_filladdr (getnameinfo): %s\n", gai_strerror (err));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (strstr (host, "::ffff:") != NULL) {
|
||||
for (i = 0; host[i + 7] != 0; i++)
|
||||
host[i] = host[i+7];
|
||||
host[i] = 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* we have to complete the sAddr struct */
|
||||
|
||||
bzero (&hints, sizeof (struct addrinfo));
|
||||
hints.ai_family = ai_family;
|
||||
hints.ai_socktype = SOCK_DGRAM;
|
||||
|
||||
if ((err = getaddrinfo (host, port, &hints, &res)) < 0) {
|
||||
d_printf ("dns_filladdr (getaddrinfo):%s\n", gai_strerror (err));
|
||||
return -1;
|
||||
}
|
||||
|
||||
// i hope it's enough to copy only sizeof (struct sockaddr) ?
|
||||
memcpy (sAddr, res->ai_addr, res->ai_addrlen);
|
||||
|
||||
freeaddrinfo (res);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* send text to someone */
|
||||
void
|
||||
udp_send (int sock, char *text, int len, struct _sockaddr *sAddr, int ai_family)
|
||||
{
|
||||
int addrlen;
|
||||
|
||||
if (ai_family == PF_INET)
|
||||
addrlen = sizeof (struct sockaddr_in);
|
||||
#ifndef _WIN32
|
||||
else
|
||||
addrlen = sizeof (struct sockaddr_in6);
|
||||
#endif
|
||||
|
||||
if (sendto (sock, text, len, 0, (struct sockaddr *) sAddr, addrlen) == -1)
|
||||
perror ("udp_send :");
|
||||
};
|
||||
|
||||
|
||||
int
|
||||
udp_server (char *port, int ai_family)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
|
||||
int sock;
|
||||
struct sockaddr_in sAddr; // my address information
|
||||
|
||||
if ((sock = socket (ai_family, SOCK_DGRAM, 0)) == -1) {
|
||||
perror ("udp_server: socket");
|
||||
return -1;
|
||||
}
|
||||
|
||||
sAddr.sin_family = AF_INET; // host byte order
|
||||
sAddr.sin_port = htons (atoi (port)); // short, network byte order
|
||||
sAddr.sin_addr.s_addr = INADDR_ANY; // automatically fill with my IP
|
||||
|
||||
memset (&(sAddr.sin_zero), '\0', 8); // zero the rest of the struct
|
||||
|
||||
if (bind (sock, (struct sockaddr *) &sAddr, sizeof (struct sockaddr)) == -1) {
|
||||
perror ("udp_server: bind");
|
||||
return -1;
|
||||
}
|
||||
|
||||
#else
|
||||
struct addrinfo hints,
|
||||
*res,
|
||||
*sres;
|
||||
int err,
|
||||
sock,
|
||||
ai_family_;
|
||||
|
||||
bzero (&hints, sizeof (struct addrinfo));
|
||||
|
||||
hints.ai_flags = AI_PASSIVE;
|
||||
hints.ai_family = ai_family;
|
||||
hints.ai_socktype = SOCK_DGRAM;
|
||||
|
||||
ai_family_ = 0;
|
||||
|
||||
if ((err = getaddrinfo (NULL, port, &hints, &res)) == 0) {
|
||||
sres = res;
|
||||
while ((ai_family_ == 0) && (sres)) {
|
||||
if (sres->ai_family == ai_family || ai_family == PF_UNSPEC)
|
||||
ai_family_ = sres->ai_family;
|
||||
else
|
||||
sres = sres->ai_next;
|
||||
}
|
||||
|
||||
if (sres == NULL)
|
||||
sres = res;
|
||||
|
||||
ai_family_ = sres->ai_family;
|
||||
if (ai_family_ != ai_family && ai_family != PF_UNSPEC) {
|
||||
// ai_family is not identic
|
||||
freeaddrinfo (res);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((sock = socket (sres->ai_family, SOCK_DGRAM, 0)) < 0) {
|
||||
perror ("UDP_Server (socket):");
|
||||
freeaddrinfo (res);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((err = bind (sock, sres->ai_addr, sres->ai_addrlen)) < 0) {
|
||||
perror ("UDP_Server (bind):");
|
||||
close (sock);
|
||||
freeaddrinfo (res);
|
||||
return -1;
|
||||
}
|
||||
|
||||
freeaddrinfo (res);
|
||||
}
|
||||
else {
|
||||
sock = -1;
|
||||
d_printf ("UDP_Server (getaddrinfo):%s\n", gai_strerror (err));
|
||||
}
|
||||
#endif
|
||||
|
||||
return sock;
|
||||
};
|
||||
|
||||
/*
|
||||
gets some text
|
||||
RESULT: 0 for nothing on there
|
||||
*/
|
||||
int
|
||||
udp_get (int sock, char *text, int len, struct _sockaddr *sAddr, int ai_family)
|
||||
{
|
||||
int clen,
|
||||
msglen;
|
||||
fd_set sockset;
|
||||
struct timeval tval;
|
||||
|
||||
if (sock == -1)
|
||||
return -1;
|
||||
|
||||
/* what version of tcp/ip we're using */
|
||||
if (ai_family == AF_INET)
|
||||
clen = sizeof (struct sockaddr_in);
|
||||
#ifndef _WIN32
|
||||
else
|
||||
clen = sizeof (struct sockaddr_in6);
|
||||
#endif
|
||||
|
||||
bzero (text, len);
|
||||
|
||||
// check if we have got any data
|
||||
FD_ZERO (&sockset);
|
||||
FD_SET (sock, &sockset);
|
||||
|
||||
tval.tv_sec = 0;
|
||||
tval.tv_usec = 100;
|
||||
|
||||
msglen = 0;
|
||||
|
||||
if (select (sock + 1, &sockset, NULL, NULL, &tval)) {
|
||||
|
||||
msglen = recvfrom (sock, text, len, 0, (struct sockaddr *) sAddr, &clen);
|
||||
if (msglen < 0)
|
||||
return 0;
|
||||
|
||||
if ((msglen >= 0) && (msglen < len))
|
||||
text[msglen] = 0;
|
||||
}
|
||||
return msglen;
|
||||
};
|
||||
|
||||
|
||||
char *
|
||||
dns_net_getip (char *host)
|
||||
{
|
||||
struct hostent *hAddr;
|
||||
|
||||
hAddr = gethostbyname (host);
|
||||
|
||||
if (hAddr == NULL)
|
||||
return NULL;
|
||||
|
||||
strncpy (dnsip, inet_ntoa (*((struct in_addr *) hAddr->h_addr)), UDP_LEN_HOSTNAME);
|
||||
|
||||
return dnsip;
|
||||
};
|
||||
/* $Id: udp.c,v 1.6 2003/05/07 21:28:13 stpohle Exp $ */
|
||||
/* udp.c code for the network
|
||||
File Version 0.2
|
||||
*/
|
||||
|
||||
#define UDP_LEN_HOSTNAME 128
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <time.h>
|
||||
#ifdef _WIN32
|
||||
#include <winsock.h>
|
||||
#include <io.h>
|
||||
#else
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netdb.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#define _sockaddr sockaddr
|
||||
#define bzero(a,b) memset(a,'\0',b)
|
||||
#else
|
||||
#define _sockaddr sockaddr_in6
|
||||
#endif
|
||||
|
||||
extern char *dns_net_getip (char *host);
|
||||
extern int dns_filladdr (char *host, int hostlen, char *port, int portlen, int ai_family,
|
||||
struct _sockaddr *sAddr);
|
||||
extern int udp_get (int sock, char *text, int len, struct _sockaddr *sAddr, int ai_family);
|
||||
extern int udp_server (char *port, int ai_family);
|
||||
extern void udp_send (int sock, char *text, int len, struct _sockaddr *sAddr, int ai_family);
|
||||
extern void udp_close (int sock);
|
||||
|
||||
char dnsip[UDP_LEN_HOSTNAME];
|
||||
|
||||
extern void d_printf (char *fmt,...);
|
||||
|
||||
|
||||
/* closes an existing udp server */
|
||||
void
|
||||
udp_close (int sock)
|
||||
{
|
||||
if (sock != -1)
|
||||
close (sock);
|
||||
sock = -1;
|
||||
};
|
||||
|
||||
|
||||
int
|
||||
dns_filladdr (char *host, int hostlen, char *port, int portlen, int ai_family,
|
||||
struct _sockaddr *sAddr)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
struct hostent *he;
|
||||
char txt[255];
|
||||
|
||||
if (host[0] == 0 || port[0] == 0) {
|
||||
/* we have to complete server and port from the sAddr */
|
||||
|
||||
strncpy (host, inet_ntoa (((struct sockaddr_in *) sAddr)->sin_addr), hostlen);
|
||||
sprintf (txt, "%d", ntohs (((struct sockaddr_in *) sAddr)->sin_port));
|
||||
strncpy (port, txt, portlen);
|
||||
}
|
||||
else {
|
||||
/* we have to complete the sAddr struct */
|
||||
|
||||
if ((he = gethostbyname (host)) == NULL) { // get the host info
|
||||
perror ("dns_filladdr (gethostbyname)");
|
||||
return -1;
|
||||
}
|
||||
|
||||
((struct sockaddr_in *) sAddr)->sin_family = ai_family; // host byte order
|
||||
((struct sockaddr_in *) sAddr)->sin_port = htons (atoi (port)); // short, network byte order
|
||||
((struct sockaddr_in *) sAddr)->sin_addr = *((struct in_addr *) he->h_addr);
|
||||
memset (&(((struct sockaddr_in *) sAddr)->sin_zero), '\0', 8); // zero the rest of the struct
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
struct addrinfo hints,
|
||||
*res;
|
||||
int err, i,
|
||||
addrlen;
|
||||
|
||||
if (host[0] == 0 || port[0] == 0) {
|
||||
/* we have to complete server and port from the sAddr */
|
||||
|
||||
if (ai_family == PF_INET)
|
||||
addrlen = sizeof (struct sockaddr_in);
|
||||
else
|
||||
addrlen = sizeof (struct sockaddr_in6);
|
||||
|
||||
bzero (host, hostlen);
|
||||
bzero (port, portlen);
|
||||
|
||||
if ((err =
|
||||
getnameinfo ((struct sockaddr *) sAddr, addrlen, host, hostlen, port, portlen,
|
||||
NI_NUMERICHOST | NI_NUMERICSERV)) < 0) {
|
||||
d_printf ("dns_filladdr (getnameinfo): %s\n", gai_strerror (err));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (strstr (host, "::ffff:") != NULL) {
|
||||
for (i = 0; host[i + 7] != 0; i++)
|
||||
host[i] = host[i+7];
|
||||
host[i] = 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* we have to complete the sAddr struct */
|
||||
|
||||
bzero (&hints, sizeof (struct addrinfo));
|
||||
hints.ai_family = ai_family;
|
||||
hints.ai_socktype = SOCK_DGRAM;
|
||||
|
||||
if ((err = getaddrinfo (host, port, &hints, &res)) < 0) {
|
||||
d_printf ("dns_filladdr (getaddrinfo):%s\n", gai_strerror (err));
|
||||
return -1;
|
||||
}
|
||||
|
||||
// i hope it's enough to copy only sizeof (struct sockaddr) ?
|
||||
memcpy (sAddr, res->ai_addr, res->ai_addrlen);
|
||||
|
||||
freeaddrinfo (res);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* send text to someone */
|
||||
void
|
||||
udp_send (int sock, char *text, int len, struct _sockaddr *sAddr, int ai_family)
|
||||
{
|
||||
int addrlen;
|
||||
|
||||
if (ai_family == PF_INET)
|
||||
addrlen = sizeof (struct sockaddr_in);
|
||||
#ifndef _WIN32
|
||||
else
|
||||
addrlen = sizeof (struct sockaddr_in6);
|
||||
#endif
|
||||
|
||||
if (sendto (sock, text, len, 0, (struct sockaddr *) sAddr, addrlen) == -1)
|
||||
perror ("udp_send :");
|
||||
};
|
||||
|
||||
|
||||
int
|
||||
udp_server (char *port, int ai_family)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
|
||||
int sock;
|
||||
struct sockaddr_in sAddr; // my address information
|
||||
|
||||
if ((sock = socket (ai_family, SOCK_DGRAM, 0)) == -1) {
|
||||
perror ("udp_server: socket");
|
||||
return -1;
|
||||
}
|
||||
|
||||
sAddr.sin_family = AF_INET; // host byte order
|
||||
sAddr.sin_port = htons (atoi (port)); // short, network byte order
|
||||
sAddr.sin_addr.s_addr = INADDR_ANY; // automatically fill with my IP
|
||||
|
||||
memset (&(sAddr.sin_zero), '\0', 8); // zero the rest of the struct
|
||||
|
||||
if (bind (sock, (struct sockaddr *) &sAddr, sizeof (struct sockaddr)) == -1) {
|
||||
perror ("udp_server: bind");
|
||||
return -1;
|
||||
}
|
||||
|
||||
#else
|
||||
struct addrinfo hints,
|
||||
*res,
|
||||
*sres;
|
||||
int err,
|
||||
sock,
|
||||
ai_family_;
|
||||
|
||||
bzero (&hints, sizeof (struct addrinfo));
|
||||
|
||||
hints.ai_flags = AI_PASSIVE;
|
||||
hints.ai_family = ai_family;
|
||||
hints.ai_socktype = SOCK_DGRAM;
|
||||
|
||||
ai_family_ = 0;
|
||||
|
||||
if ((err = getaddrinfo (NULL, port, &hints, &res)) == 0) {
|
||||
sres = res;
|
||||
while ((ai_family_ == 0) && (sres)) {
|
||||
if (sres->ai_family == ai_family || ai_family == PF_UNSPEC)
|
||||
ai_family_ = sres->ai_family;
|
||||
else
|
||||
sres = sres->ai_next;
|
||||
}
|
||||
|
||||
if (sres == NULL)
|
||||
sres = res;
|
||||
|
||||
ai_family_ = sres->ai_family;
|
||||
if (ai_family_ != ai_family && ai_family != PF_UNSPEC) {
|
||||
// ai_family is not identic
|
||||
freeaddrinfo (res);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((sock = socket (sres->ai_family, SOCK_DGRAM, 0)) < 0) {
|
||||
perror ("UDP_Server (socket):");
|
||||
freeaddrinfo (res);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((err = bind (sock, sres->ai_addr, sres->ai_addrlen)) < 0) {
|
||||
perror ("UDP_Server (bind):");
|
||||
close (sock);
|
||||
freeaddrinfo (res);
|
||||
return -1;
|
||||
}
|
||||
|
||||
freeaddrinfo (res);
|
||||
}
|
||||
else {
|
||||
sock = -1;
|
||||
d_printf ("UDP_Server (getaddrinfo):%s\n", gai_strerror (err));
|
||||
}
|
||||
#endif
|
||||
|
||||
return sock;
|
||||
};
|
||||
|
||||
/*
|
||||
gets some text
|
||||
RESULT: 0 for nothing on there
|
||||
*/
|
||||
int
|
||||
udp_get (int sock, char *text, int len, struct _sockaddr *sAddr, int ai_family)
|
||||
{
|
||||
int clen,
|
||||
msglen;
|
||||
fd_set sockset;
|
||||
struct timeval tval;
|
||||
|
||||
if (sock == -1)
|
||||
return -1;
|
||||
|
||||
/* what version of tcp/ip we're using */
|
||||
if (ai_family == AF_INET)
|
||||
clen = sizeof (struct sockaddr_in);
|
||||
#ifndef _WIN32
|
||||
else
|
||||
clen = sizeof (struct sockaddr_in6);
|
||||
#endif
|
||||
|
||||
bzero (text, len);
|
||||
|
||||
// check if we have got any data
|
||||
FD_ZERO (&sockset);
|
||||
FD_SET (sock, &sockset);
|
||||
|
||||
tval.tv_sec = 0;
|
||||
tval.tv_usec = 100;
|
||||
|
||||
msglen = 0;
|
||||
|
||||
if (select (sock + 1, &sockset, NULL, NULL, &tval)) {
|
||||
|
||||
msglen = recvfrom (sock, text, len, 0, (struct sockaddr *) sAddr, &clen);
|
||||
if (msglen < 0)
|
||||
return 0;
|
||||
|
||||
if ((msglen >= 0) && (msglen < len))
|
||||
text[msglen] = 0;
|
||||
}
|
||||
return msglen;
|
||||
};
|
||||
|
||||
|
||||
char *
|
||||
dns_net_getip (char *host)
|
||||
{
|
||||
struct hostent *hAddr;
|
||||
|
||||
hAddr = gethostbyname (host);
|
||||
|
||||
if (hAddr == NULL)
|
||||
return NULL;
|
||||
|
||||
strncpy (dnsip, inet_ntoa (*((struct in_addr *) hAddr->h_addr)), UDP_LEN_HOSTNAME);
|
||||
|
||||
return dnsip;
|
||||
};
|
||||
|
Loading…
Reference in new issue