From 2fe0fbc2a34fd4b50081f1829931dea3ca2c4c1c Mon Sep 17 00:00:00 2001 From: Holger Schemel Date: Mon, 5 Oct 1998 22:35:41 +0200 Subject: [PATCH] rnd-19981005-1 --- src/buttons.c | 137 +++++++++++++++++++++++++++++++++++++++++----- src/buttons.h | 60 +++++++++++++++++---- src/editor.c | 16 +++--- src/events.c | 5 ++ src/files.c | 10 ++-- src/game.c | 133 +++++++++++++++++++++++++++++---------------- src/init.c | 21 +++++--- src/main.c | 3 +- src/main.h | 13 ++--- src/misc.c | 1 + src/network.c | 147 ++++++++++++++++++++++++++++++++++++++++++++------ src/network.h | 3 +- src/screens.c | 10 ++-- src/tape.c | 8 +-- src/tools.c | 115 +++++++++++++++++++++++++++++---------- src/tools.h | 32 +++++------ 16 files changed, 546 insertions(+), 168 deletions(-) diff --git a/src/buttons.c b/src/buttons.c index 8077b03a..282481bd 100644 --- a/src/buttons.c +++ b/src/buttons.c @@ -222,7 +222,7 @@ void DrawGameButton(unsigned long state) redraw_mask |= REDRAW_DOOR_1; } -void DrawChooseButton(unsigned long state) +void DrawYesNoButton(unsigned long state) { int pos, cx = DOOR_GFX_PAGEX4, cy = 0; @@ -254,6 +254,60 @@ void DrawConfirmButton(unsigned long state) redraw_mask |= REDRAW_DOOR_1; } +void DrawPlayerButton(unsigned long state, int mode) +{ + Drawable dest_drawto; + int dest_xoffset, dest_yoffset; + int graphic; + int graphic_offset = (PLAYER_BUTTON_XSIZE - TILEX/2)/2; + int xpos, ypos; + int cx = DOOR_GFX_PAGEX4, cy = 0; + + if (mode == DB_INIT) + { + dest_drawto = pix[PIX_DB_DOOR]; + dest_xoffset = DOOR_GFX_PAGEX1; + dest_yoffset = 0; + } + else + { + dest_drawto = drawto; + dest_xoffset = DX; + dest_yoffset = DY; + } + + if (state & BUTTON_PLAYER_1) + graphic = GFX_SPIELER1; + else if (state & BUTTON_PLAYER_2) + graphic = GFX_SPIELER2; + else if (state & BUTTON_PLAYER_3) + graphic = GFX_SPIELER3; + else if (state & BUTTON_PLAYER_4) + graphic = GFX_SPIELER4; + + xpos = (state & BUTTON_PLAYER_1 || state & BUTTON_PLAYER_3 ? + PLAYER_BUTTON_1_XPOS : PLAYER_BUTTON_2_XPOS); + ypos = (state & BUTTON_PLAYER_1 || state & BUTTON_PLAYER_2 ? + PLAYER_BUTTON_1_YPOS : PLAYER_BUTTON_3_YPOS); + + if (state & BUTTON_PRESSED) + { + cx = DOOR_GFX_PAGEX3; + graphic_offset += 1; + } + + XCopyArea(display,pix[PIX_DOOR],dest_drawto,gc, + cx + PLAYER_BUTTON_GFX_XPOS, cy + PLAYER_BUTTON_GFX_YPOS, + PLAYER_BUTTON_XSIZE, PLAYER_BUTTON_YSIZE, + dest_xoffset + xpos, dest_yoffset + ypos); + DrawMiniGraphicExt(dest_drawto,gc, + dest_xoffset + xpos + graphic_offset, + dest_yoffset + ypos + graphic_offset, + graphic); + + redraw_mask |= REDRAW_DOOR_1; +} + /* several buttons in the level editor */ void DrawEditButton(unsigned long state) @@ -621,12 +675,12 @@ int CheckGameButtons(int mx, int my, int button) return(return_code); } -int CheckChooseButtons(int mx, int my, int button) +int CheckYesNoButtons(int mx, int my, int button) { int return_code = 0; static int choice = -1; static BOOL pressed = FALSE; - static int choose_button[5] = + static int yesno_button[5] = { BUTTON_OK, BUTTON_NO @@ -636,33 +690,33 @@ int CheckChooseButtons(int mx, int my, int button) { if (!motion_status) /* Maustaste neu gedrückt */ { - if (ON_CHOOSE_BUTTON(mx,my)) + if (ON_YESNO_BUTTON(mx,my)) { - choice = CHOOSE_BUTTON(mx); + choice = YESNO_BUTTON(mx); pressed = TRUE; - DrawChooseButton(choose_button[choice] | BUTTON_PRESSED); + DrawYesNoButton(yesno_button[choice] | BUTTON_PRESSED); } } else /* Mausbewegung bei gedrückter Maustaste */ { - if ((!ON_CHOOSE_BUTTON(mx,my) || CHOOSE_BUTTON(mx)!=choice) && + if ((!ON_YESNO_BUTTON(mx,my) || YESNO_BUTTON(mx)!=choice) && choice>=0 && pressed) { pressed = FALSE; - DrawChooseButton(choose_button[choice] | BUTTON_RELEASED); + DrawYesNoButton(yesno_button[choice] | BUTTON_RELEASED); } - else if (ON_CHOOSE_BUTTON(mx,my) &&CHOOSE_BUTTON(mx)==choice && !pressed) + else if (ON_YESNO_BUTTON(mx,my) && YESNO_BUTTON(mx)==choice && !pressed) { pressed = TRUE; - DrawChooseButton(choose_button[choice] | BUTTON_PRESSED); + DrawYesNoButton(yesno_button[choice] | BUTTON_PRESSED); } } } else /* Maustaste wieder losgelassen */ { - if (ON_CHOOSE_BUTTON(mx,my) && CHOOSE_BUTTON(mx)==choice && pressed) + if (ON_YESNO_BUTTON(mx,my) && YESNO_BUTTON(mx)==choice && pressed) { - DrawChooseButton(choose_button[choice] | BUTTON_RELEASED); + DrawYesNoButton(yesno_button[choice] | BUTTON_RELEASED); return_code = choice+1; choice = -1; pressed = FALSE; @@ -729,6 +783,65 @@ int CheckConfirmButton(int mx, int my, int button) return(return_code); } +int CheckPlayerButtons(int mx, int my, int button) +{ + int return_code = 0; + static int choice = -1; + static BOOL pressed = FALSE; + int player_state[4] = + { + BUTTON_PLAYER_1, + BUTTON_PLAYER_2, + BUTTON_PLAYER_3, + BUTTON_PLAYER_4 + }; + + if (button) + { + if (!motion_status) /* Maustaste neu gedrückt */ + { + if (ON_PLAYER_BUTTON(mx,my)) + { + choice = PLAYER_BUTTON(mx,my); + pressed = TRUE; + DrawPlayerButton(player_state[choice] | BUTTON_PRESSED, DB_NORMAL); + } + } + else /* Mausbewegung bei gedrückter Maustaste */ + { + if ((!ON_PLAYER_BUTTON(mx,my) || PLAYER_BUTTON(mx,my)!=choice) && + choice>=0 && pressed) + { + pressed = FALSE; + DrawPlayerButton(player_state[choice] | BUTTON_RELEASED, DB_NORMAL); + } + else if (ON_PLAYER_BUTTON(mx,my) && PLAYER_BUTTON(mx,my)==choice && !pressed) + { + pressed = TRUE; + DrawPlayerButton(player_state[choice] | BUTTON_PRESSED, DB_NORMAL); + } + } + } + else /* Maustaste wieder losgelassen */ + { + if (ON_PLAYER_BUTTON(mx,my) && PLAYER_BUTTON(mx,my)==choice && pressed) + { + DrawPlayerButton(player_state[choice] | BUTTON_RELEASED, DB_NORMAL); + return_code = player_state[choice]; + choice = -1; + pressed = FALSE; + } + else + { + choice = -1; + pressed = FALSE; + } + } + + BackToFront(); + return(return_code); +} + /* several buttons in the level editor */ int CheckEditButtons(int mx, int my, int button) diff --git a/src/buttons.h b/src/buttons.h index 397aa6f9..9ed110c8 100644 --- a/src/buttons.h +++ b/src/buttons.h @@ -164,8 +164,8 @@ #define SOUND_BUTTON_YSIZE 30 #define SOUND_CONTROL_XPOS 5 #define SOUND_CONTROL_YPOS 245 -#define SOUND_CONTROL_XSIZE 90 -#define SOUND_CONTROL_YSIZE (SOUND_BUTTON_YSIZE) +#define SOUND_CONTROL_XSIZE (3*SOUND_BUTTON_XSIZE) +#define SOUND_CONTROL_YSIZE (1*SOUND_BUTTON_YSIZE) #define SOUND_BUTTON_MUSIC_XPOS (SOUND_CONTROL_XPOS + 0 * SOUND_BUTTON_XSIZE) #define SOUND_BUTTON_LOOPS_XPOS (SOUND_CONTROL_XPOS + 1 * SOUND_BUTTON_XSIZE) #define SOUND_BUTTON_SIMPLE_XPOS (SOUND_CONTROL_XPOS + 2 * SOUND_BUTTON_XSIZE) @@ -200,8 +200,8 @@ #define GAME_BUTTON_YSIZE 30 #define GAME_CONTROL_XPOS 5 #define GAME_CONTROL_YPOS 215 -#define GAME_CONTROL_XSIZE 90 -#define GAME_CONTROL_YSIZE (GAME_BUTTON_YSIZE) +#define GAME_CONTROL_XSIZE (3*GAME_BUTTON_XSIZE) +#define GAME_CONTROL_YSIZE (1*GAME_BUTTON_YSIZE) #define GAME_BUTTON_STOP_XPOS (GAME_CONTROL_XPOS + 0 * GAME_BUTTON_XSIZE) #define GAME_BUTTON_PAUSE_XPOS (GAME_CONTROL_XPOS + 1 * GAME_BUTTON_XSIZE) #define GAME_BUTTON_PLAY_XPOS (GAME_CONTROL_XPOS + 2 * GAME_BUTTON_XSIZE) @@ -220,7 +220,6 @@ #define BUTTON_GAME_PAUSE (1L<<1) #define BUTTON_GAME_PLAY (1L<<2) - /* some positions in the asking window */ #define OK_BUTTON_XPOS 2 #define OK_BUTTON_YPOS 250 @@ -237,7 +236,7 @@ #define CONFIRM_BUTTON_XSIZE 96 #define CONFIRM_BUTTON_YSIZE OK_BUTTON_YSIZE -#define ON_CHOOSE_BUTTON(x,y) (((x)>=(DX+OK_BUTTON_XPOS) && \ +#define ON_YESNO_BUTTON(x,y) (((x)>=(DX+OK_BUTTON_XPOS) && \ (x)< (DX+OK_BUTTON_XPOS + \ OK_BUTTON_XSIZE) && \ (y)>=(DY+OK_BUTTON_YPOS) && \ @@ -255,13 +254,49 @@ (y)>=(DY+CONFIRM_BUTTON_YPOS) && \ (y)< (DY+CONFIRM_BUTTON_YPOS + \ CONFIRM_BUTTON_YSIZE))) -#define CHOOSE_BUTTON(x) (((x)-(DX+OK_BUTTON_XPOS))/OK_BUTTON_XSIZE) +#define YESNO_BUTTON(x) (((x)-(DX+OK_BUTTON_XPOS))/OK_BUTTON_XSIZE) /* values for asking control */ #define BUTTON_OK (1L<<0) #define BUTTON_NO (1L<<1) #define BUTTON_CONFIRM (1L<<2) +/* some positions in the choose player window */ + +#define PLAYER_BUTTON_XSIZE 30 +#define PLAYER_BUTTON_YSIZE 30 +#define PLAYER_BUTTON_GFX_XPOS 5 +#define PLAYER_BUTTON_GFX_YPOS (215-30) +#define PLAYER_CONTROL_XPOS (5 + PLAYER_BUTTON_XSIZE/2) +#define PLAYER_CONTROL_YPOS (215 - PLAYER_BUTTON_YSIZE/2) +#define PLAYER_CONTROL_XSIZE (2*PLAYER_BUTTON_XSIZE) +#define PLAYER_CONTROL_YSIZE (2*PLAYER_BUTTON_YSIZE) +#define PLAYER_BUTTON_1_XPOS (PLAYER_CONTROL_XPOS + 0 * PLAYER_BUTTON_XSIZE) +#define PLAYER_BUTTON_2_XPOS (PLAYER_CONTROL_XPOS + 1 * PLAYER_BUTTON_XSIZE) +#define PLAYER_BUTTON_3_XPOS (PLAYER_CONTROL_XPOS + 0 * PLAYER_BUTTON_XSIZE) +#define PLAYER_BUTTON_4_XPOS (PLAYER_CONTROL_XPOS + 1 * PLAYER_BUTTON_XSIZE) +#define PLAYER_BUTTON_1_YPOS (PLAYER_CONTROL_YPOS + 0 * PLAYER_BUTTON_YSIZE) +#define PLAYER_BUTTON_2_YPOS (PLAYER_CONTROL_YPOS + 0 * PLAYER_BUTTON_YSIZE) +#define PLAYER_BUTTON_3_YPOS (PLAYER_CONTROL_YPOS + 1 * PLAYER_BUTTON_YSIZE) +#define PLAYER_BUTTON_4_YPOS (PLAYER_CONTROL_YPOS + 1 * PLAYER_BUTTON_YSIZE) + +#define ON_PLAYER_BUTTON(x,y) ((x)>=(DX+PLAYER_CONTROL_XPOS) && \ + (x)< (DX+PLAYER_CONTROL_XPOS + \ + PLAYER_CONTROL_XSIZE) && \ + (y)>=(DY+PLAYER_CONTROL_YPOS) && \ + (y)< (DY+PLAYER_CONTROL_YPOS + \ + PLAYER_CONTROL_YSIZE)) +#define PLAYER_BUTTON(x,y) ((((x)-(DX+PLAYER_CONTROL_XPOS)) / \ + PLAYER_BUTTON_XSIZE) + 2 * \ + (((y)-(DY+PLAYER_CONTROL_YPOS)) / \ + PLAYER_BUTTON_YSIZE)) + +/* values for choose player control */ +#define BUTTON_PLAYER_1 (1L<<10) +#define BUTTON_PLAYER_2 (1L<<11) +#define BUTTON_PLAYER_3 (1L<<12) +#define BUTTON_PLAYER_4 (1L<<13) + /* some positions in the editor control window */ #define ED_BUTTON_EUP_XPOS 35 @@ -497,12 +532,18 @@ #define ED_BUTTON_ELEM 2 +/* for DrawPlayerButton() */ + +#define DB_INIT 0 +#define DB_NORMAL 1 + void DrawVideoDisplay(unsigned long, unsigned long); void DrawCompleteVideoDisplay(void); void DrawSoundDisplay(unsigned long); void DrawGameButton(unsigned long); -void DrawChooseButton(unsigned long); +void DrawYesNoButton(unsigned long); void DrawConfirmButton(unsigned long); +void DrawPlayerButton(unsigned long, int); void DrawEditButton(unsigned long state); void DrawCtrlButton(unsigned long state); void DrawElemButton(int, int); @@ -510,8 +551,9 @@ void DrawCountButton(int, int); int CheckVideoButtons(int, int, int); int CheckSoundButtons(int, int, int); int CheckGameButtons(int, int, int); -int CheckChooseButtons(int, int, int); +int CheckYesNoButtons(int, int, int); int CheckConfirmButton(int, int, int); +int CheckPlayerButtons(int, int, int); int CheckEditButtons(int, int, int); int CheckCtrlButtons(int, int, int); int CheckElemButtons(int, int, int); diff --git a/src/editor.c b/src/editor.c index fc81ebe0..85ae127e 100644 --- a/src/editor.c +++ b/src/editor.c @@ -745,7 +745,7 @@ void LevelEd(int mx, int my, int button) edit_mode = FALSE; break; case ED_BUTTON_FILL: - AreYouSure("Caution ! Flood fill mode ! Choose area !",AYS_OPEN); + Request("Caution ! Flood fill mode ! Choose area !",REQ_OPEN); use_floodfill = TRUE; return; break; @@ -1010,7 +1010,7 @@ void LevelEd(int mx, int my, int button) edit_mode = TRUE; break; case ED_BUTTON_CLEAR: - if (AreYouSure("Are you sure to clear this level ?",AYS_ASK)) + if (Request("Are you sure to clear this level ?",REQ_ASK)) { for(x=0;x0) { - tape.pos[i].joystickdata[j] = MV_NO_MOVING; + tape.pos[i].action[j] = MV_NO_MOVING; continue; } - tape.pos[i].joystickdata[j] = fgetc(file); + tape.pos[i].action[j] = fgetc(file); } tape.pos[i].delay = fgetc(file); @@ -533,7 +533,7 @@ void SaveLevelTape(int level_nr) new_tape = FALSE; fclose(file); - if (!AreYouSure("Replace old tape ?",AYS_ASK)) + if (!Request("Replace old tape ?",REQ_ASK)) return; } @@ -566,7 +566,7 @@ void SaveLevelTape(int level_nr) int j; for(j=0; jnr = i; + player->index_nr = i; + player->element_nr = EL_SPIELER1 + i; player->active = FALSE; player->local = FALSE; @@ -128,6 +129,21 @@ void InitGame() local_player->active = TRUE; local_player->local = TRUE; + network_player_action_stored = FALSE; + + + + /* initial null action */ + SendToServer_MovePlayer(0,0); + + + + /* + printf("BLURB\n"); + */ + + + ZX = ZY = -1; MampferNr = 0; @@ -2780,7 +2796,7 @@ void PlayerActions(struct PlayerInfo *player, byte player_action) int dx = (left ? -1 : right ? 1 : 0); int dy = (up ? -1 : down ? 1 : 0); - stored_player_action[player->nr] = 0; + stored_player_action[player->index_nr] = 0; num_stored_actions++; if (!player->active || player->gone) @@ -2804,7 +2820,7 @@ void PlayerActions(struct PlayerInfo *player, byte player_action) if (bombed && !moved) player_action &= JOY_BUTTON; - stored_player_action[player->nr] = player_action; + stored_player_action[player->index_nr] = player_action; /* this allows cycled sequences of PlayerActions() */ if (num_stored_actions >= MAX_PLAYERS) @@ -2828,7 +2844,7 @@ void PlayerActions(struct PlayerInfo *player, byte player_action) tape.counter < tape.length) { int next_joy = - tape.pos[tape.counter].joystickdata[player->nr] & (JOY_LEFT|JOY_RIGHT); + tape.pos[tape.counter].action[player->index_nr] & (JOY_LEFT|JOY_RIGHT); if (next_joy == JOY_LEFT || next_joy == JOY_RIGHT) { @@ -2858,9 +2874,11 @@ void GameActions(byte player_action) int i, x,y, element; int *recorded_player_action; + if (game_status != PLAYING) return; + #ifdef DEBUG action_delay_value = (tape.playing && tape.fast_forward ? FFWD_FRAME_DELAY : GameFrameDelay); @@ -2869,23 +2887,60 @@ void GameActions(byte player_action) (tape.playing && tape.fast_forward ? FFWD_FRAME_DELAY : GAME_FRAME_DELAY); #endif + /* + HandleNetworking(); + + if (game_status != PLAYING) + return; + */ + /* main game synchronization point */ WaitUntilDelayReached(&action_delay, action_delay_value); + if (!network_player_action_stored) + { +#ifdef DEBUG + printf("DEBUG: try to get network player actions in time\n"); +#endif + + /* last chance to get network player actions without main loop delay */ + HandleNetworking(); + + if (game_status != PLAYING) + return; + + if (!network_player_action_stored) + { +#ifdef DEBUG + printf("DEBUG: failed to get network player actions in time\n"); +#endif + return; + } + } + if (tape.playing) recorded_player_action = TapePlayAction(); else recorded_player_action = NULL; - SendToServer_MovePlayer(player_action); + + SendToServer_MovePlayer(player_action, FrameCounter); + for(i=0; ilast_jy = jy; jx = player->jx = new_jx; jy = player->jy = new_jy; - StorePlayer[jx][jy] = EL_SPIELER1 + player->nr; + StorePlayer[jx][jy] = player->element_nr; player->MovPos = (dx > 0 || dy > 0 ? -1 : 1) * 7*TILEX/8; @@ -3215,11 +3279,19 @@ BOOL MoveFigure(struct PlayerInfo *player, int dx, int dy) if (moved & MF_MOVING && player == local_player) */ - if (moved & MF_MOVING && !ScreenMovPos) + if (moved & MF_MOVING && !ScreenMovPos && + (player == local_player || standalone)) { int old_scroll_x = scroll_x, old_scroll_y = scroll_y; int offset = (scroll_delay_on ? 3 : 0); + /* + if (player == local_player) + { + printf("MOVING LOCAL PLAYER && SCROLLING\n"); + } + */ + if (!IN_VIS_FIELD(SCREENX(jx),SCREENY(jy))) { /* actual player has left the screen -- scroll in that direction */ @@ -3278,22 +3350,15 @@ BOOL MoveFigure(struct PlayerInfo *player, int dx, int dy) if (scroll_x != old_scroll_x || scroll_y != old_scroll_y) { - if (networking || AllPlayersInVisibleScreen()) + if (standalone && !AllPlayersInVisibleScreen()) { - ScrollScreen(player, SCROLL_INIT); - - /* - ScreenMovDir = player->MovDir; - ScreenMovPos = player->MovPos; - ScreenGfxPos = ScrollStepSize * (ScreenMovPos / ScrollStepSize); - */ - - ScrollLevel(old_scroll_x - scroll_x, old_scroll_y - scroll_y); + scroll_x = old_scroll_x; + scroll_y = old_scroll_y; } else { - scroll_x = old_scroll_x; - scroll_y = old_scroll_y; + ScrollScreen(player, SCROLL_INIT); + ScrollLevel(old_scroll_x - scroll_x, old_scroll_y - scroll_y); } } } @@ -3338,10 +3403,6 @@ void ScrollFigure(struct PlayerInfo *player, int mode) player->actual_frame_counter = FrameCounter; player->GfxPos = ScrollStepSize * (player->MovPos / ScrollStepSize); - /* - ScreenGfxPos = local_player->GfxPos; - */ - if (Feld[last_jx][last_jy] == EL_LEERRAUM) Feld[last_jx][last_jy] = EL_PLAYER_IS_LEAVING; @@ -3354,22 +3415,6 @@ void ScrollFigure(struct PlayerInfo *player, int mode) player->MovPos += (player->MovPos > 0 ? -1 : 1) * TILEX/8; player->GfxPos = ScrollStepSize * (player->MovPos / ScrollStepSize); - /* - if (ScreenMovPos) - { - ScreenMovPos += (ScreenMovPos > 0 ? -1 : 1) * TILEX/8; - ScreenGfxPos = ScrollStepSize * (ScreenMovPos / ScrollStepSize); - } - */ - - /* - if (ScreenGfxPos && ScreenGfxPos != local_player->GfxPos) - { - ScreenGfxPos = local_player->GfxPos; - redraw_mask |= REDRAW_FIELD; - } - */ - if (Feld[last_jx][last_jy] == EL_PLAYER_IS_LEAVING) Feld[last_jx][last_jy] = EL_LEERRAUM; @@ -3407,12 +3452,6 @@ void ScrollScreen(struct PlayerInfo *player, int mode) if (ScreenMovPos) { - /* - printf("ScreenMovDir = %d, ", ScreenMovDir); - printf("ScreenMovPos = %d, ", ScreenMovPos); - printf("ScreenGfxPos = %d\n", ScreenGfxPos); - */ - ScreenMovPos += (ScreenMovPos > 0 ? -1 : 1) * TILEX/8; ScreenGfxPos = ScrollStepSize * (ScreenMovPos / ScrollStepSize); redraw_mask |= REDRAW_FIELD; @@ -3986,7 +4025,7 @@ BOOL PlaceBomb(struct PlayerInfo *player) else { Feld[jx][jy] = EL_DYNABOMB; - Store2[jx][jy] = EL_SPIELER1 + player->nr; /* for DynaExplode() */ + Store2[jx][jy] = player->element_nr; /* for DynaExplode() */ MovDelay[jx][jy] = 96; player->dynabombs_left--; DrawGraphicThruMask(SCREENX(jx),SCREENY(jy),GFX_DYNABOMB); diff --git a/src/init.c b/src/init.c index 88050961..0a0c7580 100644 --- a/src/init.c +++ b/src/init.c @@ -44,11 +44,11 @@ struct IconFileInfo static int sound_process_id = 0; -static void InitServer(void); static void InitLevelAndPlayerInfo(void); +static void InitNetworkServer(void); static void InitDisplay(void); static void InitSound(void); -static void InitSoundProcess(void); +static void InitSoundServer(void); static void InitWindow(int, char **); static void InitGfx(void); static void LoadGfx(int, struct PictureFileInfo *); @@ -57,11 +57,10 @@ static void InitElementProperties(void); void OpenAll(int argc, char *argv[]) { InitLevelAndPlayerInfo(); - InitServer(); InitCounter(); InitSound(); - InitSoundProcess(); + InitSoundServer(); InitJoystick(); InitRND(NEW_RANDOMIZE); @@ -78,6 +77,8 @@ void OpenAll(int argc, char *argv[]) InitElementProperties(); DrawMainMenu(); + + InitNetworkServer(); } void InitLevelAndPlayerInfo() @@ -91,19 +92,25 @@ void InitLevelAndPlayerInfo() LoadPlayerInfo(PLAYER_LEVEL); /* level specific info */ } -void InitServer() +void InitNetworkServer() { + int nr_wanted; + standalone = FALSE; - networking = !standalone; if (standalone) return; + nr_wanted = Request("Choose player", REQ_PLAYER | REQ_STAY_CLOSED); + if (!ConnectToServer(server_host, server_port)) Error(ERR_EXIT, "cannot connect to multiplayer server"); SendToServer_Nickname(local_player->alias_name); SendToServer_ProtocolVersion(); + + if (nr_wanted) + SendToServer_NrWanted(nr_wanted); } void InitSound() @@ -154,7 +161,7 @@ void InitSound() } } -void InitSoundProcess() +void InitSoundServer() { if (sound_status==SOUND_OFF) return; diff --git a/src/main.c b/src/main.c index 03d7e66e..61039723 100644 --- a/src/main.c +++ b/src/main.c @@ -50,7 +50,6 @@ char *program_name = NULL; char *display_name = NULL; char *server_host = NULL; int server_port = 0; -int networking = FALSE; int standalone = TRUE; int verbose = FALSE; @@ -106,6 +105,8 @@ int AllPlayersGone; int FrameCounter, TimeFrames, TimeLeft; int MampferNr, SiebAktiv; +byte network_player_action[MAX_PLAYERS]; +BOOL network_player_action_stored = FALSE; int TestPlayer = 0; struct LevelDirInfo leveldir[MAX_LEVDIR_ENTRIES]; diff --git a/src/main.h b/src/main.h index dc5da4ff..354b23ec 100644 --- a/src/main.h +++ b/src/main.h @@ -144,12 +144,7 @@ typedef unsigned char byte; #define IS_PUSHABLE(e) (Elementeigenschaften[e] & EP_BIT_PUSHABLE) #define ELEM_IS_PLAYER(e) (Elementeigenschaften[e] & EP_BIT_PLAYER) -/* -#define IS_PLAYER(x,y) (JX == (x) && JY == (y)) -*/ - #define IS_PLAYER(x,y) (ELEM_IS_PLAYER(StorePlayer[x][y])) -#define IS_LOCAL_PLAYER(x,y) (StorePlayer[x][y] == EL_SPIELER1) #define IS_FREE(x,y) (Feld[x][y] == EL_LEERRAUM && !IS_PLAYER(x,y)) #define IS_FREE_OR_PLAYER(x,y) (Feld[x][y] == EL_LEERRAUM) @@ -214,7 +209,8 @@ struct HiScore struct PlayerInfo { - int nr, active, local; + int active, local; + int index_nr, client_nr, element_nr; char login_name[MAX_NAMELEN]; char alias_name[MAX_NAMELEN]; @@ -289,7 +285,7 @@ struct RecordingInfo BOOL changed; struct { - byte joystickdata[MAX_PLAYERS]; + byte action[MAX_PLAYERS]; byte delay; } pos[MAX_TAPELEN]; }; @@ -327,7 +323,6 @@ extern char *program_name; extern char *display_name; extern char *server_host; extern int server_port; -extern int networking; extern int standalone; extern int verbose; @@ -381,6 +376,8 @@ extern int AllPlayersGone; extern int FrameCounter, TimeFrames, TimeLeft; extern int MampferNr, SiebAktiv; +extern byte network_player_action[]; +extern BOOL network_player_action_stored; extern int TestPlayer; extern struct LevelDirInfo leveldir[]; diff --git a/src/misc.c b/src/misc.c index 8d36c27a..e412be85 100644 --- a/src/misc.c +++ b/src/misc.c @@ -233,6 +233,7 @@ void GetOptions(char *argv[]) "Options:\n" " -d, --display machine:0 X server display\n" " -l, --levels directory alternative level directory\n" + " -n, --network network multiplayer game\n" " -v, --verbose verbose mode\n", program_name); exit(0); diff --git a/src/network.c b/src/network.c index 14ea8656..17ca60d1 100644 --- a/src/network.c +++ b/src/network.c @@ -29,6 +29,7 @@ #include "game.h" #include "tape.h" #include "files.h" +#include "tools.h" #include "misc.h" int norestart = 0; @@ -43,7 +44,7 @@ int nospeedup = 0; #define OP_NICK 1 #define OP_PLAY 2 #define OP_MOVE 3 -#define OP_DRAW 4 +#define OP_NRWANTED 4 #define OP_LOST 5 #define OP_GONE 6 #define OP_CLEAR 7 @@ -98,8 +99,11 @@ void copydown(char *s, char *t, int n) void sysmsg(char *s) { - printf("** %s\n", s); - fflush(stdout); + if (verbose) + { + printf("** %s\n", s); + fflush(stdout); + } } void fatal(char *s) @@ -183,8 +187,8 @@ void startserver() int n = 0; options[0] = options[1] = NULL; - if (norestart) - options[n++] = "-norestart"; + if (verbose) + options[n++] = "-v"; if (nospeedup) options[n++] = "-nospeedup"; @@ -197,7 +201,7 @@ void startserver() #else "rnd_server", #endif - "rnd_server", "-once", "-v", options[0], options[1], NULL); + "rnd_server", "-once", options[0], options[1], NULL); fprintf(stderr, "Can't start server '%s'.\n", #ifdef XTRISPATH @@ -295,22 +299,50 @@ void SendToServer_ProtocolVersion() sendbuf(5); } +void SendToServer_NrWanted(int nr_wanted) +{ + buf[1] = OP_NRWANTED; + buf[2] = nr_wanted; + sendbuf(3); +} + void SendToServer_StartPlaying() { buf[1] = OP_PLAY; - buf[2] = (unsigned char)(level_nr / 256); - buf[3] = (unsigned char)(level_nr % 256); - buf[4] = (unsigned char)(leveldir_nr / 256); - buf[5] = (unsigned char)(leveldir_nr % 256); + buf[2] = (byte)(level_nr >> 8); + buf[3] = (byte)(level_nr & 0xff); + buf[4] = (byte)(leveldir_nr >> 8); + buf[5] = (byte)(leveldir_nr & 0xff); strcpy(&buf[6], leveldir[leveldir_nr].name); sendbuf(strlen(leveldir[leveldir_nr].name)+1 + 6); } -void SendToServer_MovePlayer(byte player_action) +void SendToServer_MovePlayer(byte player_action, unsigned long frame_nr) { buf[1] = OP_MOVE; buf[2] = player_action; + sendbuf(3); + + /* + buf[3] = (byte)((frame_nr >> 24) & 0xff); + buf[4] = (byte)((frame_nr >> 16) & 0xff); + buf[5] = (byte)((frame_nr >> 8) & 0xff); + buf[6] = (byte)((frame_nr >> 0) & 0xff); + + sendbuf(7); + */ + + /* + printf("%d: %x, %x, %x, %x\n", frame_nr, buf[3], buf[4], buf[5], buf[6]); + */ + + + + flushbuf(); + + + } void handlemessages() @@ -332,12 +364,65 @@ void handlemessages() switch(buf[1]) { case OP_YOUARE: + { + int new_client_nr = buf[2]; + int new_index_nr = new_client_nr - 1; + printf("OP_YOUARE: %d\n", buf[0]); - me.nr = buf[0]; + me.nr = new_client_nr; + + stored_player[new_index_nr] = *local_player; + local_player = &stored_player[new_index_nr]; + + TestPlayer = new_index_nr; + + if (me.nr > MAX_PLAYERS) + Error(ERR_EXIT, "sorry - no more than %d players", MAX_PLAYERS); + + sprintf(msgbuf, "you get client # %d", new_client_nr); + sysmsg(msgbuf); + + break; + } + + case OP_NRWANTED: + { + int client_nr_wanted = buf[2]; + int new_client_nr = buf[3]; + int new_index_nr = new_client_nr - 1; - TestPlayer = buf[0] - 1; + printf("OP_NRWANTED: %d\n", buf[0]); + + if (new_client_nr != client_nr_wanted) + { + char *color[] = { "yellow", "red", "green", "blue" }; + + sprintf(msgbuf, "Sorry ! You are %s player !", + color[new_index_nr]); + Request(msgbuf, REQ_CONFIRM); + + sprintf(msgbuf, "cannot switch -- you keep client # %d", + new_client_nr); + sysmsg(msgbuf); + } + else + { + if (me.nr != client_nr_wanted) + sprintf(msgbuf, "switching to client # %d", new_client_nr); + else + sprintf(msgbuf, "keeping client # %d", new_client_nr); + sysmsg(msgbuf); + + me.nr = new_client_nr; + + stored_player[new_index_nr] = *local_player; + local_player = &stored_player[new_index_nr]; + + TestPlayer = new_index_nr; + } break; + } case OP_NEW: printf("OP_NEW: %d\n", buf[0]); @@ -428,13 +513,41 @@ void handlemessages() break; case OP_MOVE: - if (buf[2]) + { + int frame_nr; + int i; + + frame_nr = + (buf[2] << 24) | (buf[3] << 16) | (buf[4] << 8) | (buf[5]); + + for (i=0; i= 255) { for(i=0; iactive || player->gone || !IN_SCR_FIELD(sx,sy)) return; + */ + + if (!player->active || player->gone || + !IN_SCR_FIELD(SCREENX(last_jx),SCREENY(last_jy))) + return; #if DEBUG - if (!IN_LEV_FIELD(jx,jy) || !IN_SCR_FIELD(sx,sy)) + if (!IN_LEV_FIELD(jx,jy)) { printf("DrawPlayerField(): x = %d, y = %d\n",jx,jy); printf("DrawPlayerField(): sx = %d, sy = %d\n",sx,sy); @@ -372,9 +378,6 @@ void DrawPlayer(struct PlayerInfo *player) if (element == EL_EXPLODING) return; - if (direct_draw_on) - SetDrawtoField(DRAW_BUFFERED); - /* draw things in the field the player is leaving, if needed */ if (last_jx != jx || last_jy != jy) @@ -389,7 +392,7 @@ void DrawPlayer(struct PlayerInfo *player) else DrawLevelField(last_jx,last_jy); - if (player->Pushing) + if (player->Pushing && IN_SCR_FIELD(SCREENX(next_jx),SCREENY(next_jy))) { if (player->GfxPos) { @@ -403,6 +406,12 @@ void DrawPlayer(struct PlayerInfo *player) } } + if (!IN_SCR_FIELD(sx,sy)) + return; + + if (direct_draw_on) + SetDrawtoField(DRAW_BUFFERED); + /* draw things behind the player, if needed */ if (Store[jx][jy]) @@ -421,7 +430,7 @@ void DrawPlayer(struct PlayerInfo *player) else /* MV_DOWN || MV_NO_MOVING */ graphic = GFX_SPIELER1_DOWN; - graphic += player->nr * 3*HEROES_PER_LINE; + graphic += player->index_nr * 3*HEROES_PER_LINE; graphic += player->Frame; if (player->GfxPos) @@ -555,7 +564,6 @@ void DrawGraphicAnimationThruMask(int x, int y, int graphic, void DrawGraphic(int x, int y, int graphic) { - #if DEBUG if (!IN_SCR_FIELD(x,y)) { @@ -602,11 +610,6 @@ void DrawGraphicExt(Drawable d, GC gc, int x, int y, int graphic) void DrawGraphicThruMask(int x, int y, int graphic) { - int src_x,src_y, dest_x,dest_y; - int tile = graphic; - Pixmap src_pixmap; - GC drawing_gc; - #if DEBUG if (!IN_SCR_FIELD(x,y)) { @@ -616,6 +619,17 @@ void DrawGraphicThruMask(int x, int y, int graphic) } #endif + DrawGraphicThruMaskExt(drawto_field, FX+x*TILEX, FY+y*TILEY, graphic); + MarkTileDirty(x,y); +} + +void DrawGraphicThruMaskExt(Drawable d, int dest_x, int dest_y, int graphic) +{ + int src_x, src_y; + int tile = graphic; + Pixmap src_pixmap; + GC drawing_gc; + if (graphic >= GFX_START_ROCKSSCREEN && graphic <= GFX_END_ROCKSSCREEN) { src_pixmap = pix[PIX_BACK]; @@ -634,13 +648,10 @@ void DrawGraphicThruMask(int x, int y, int graphic) } else { - DrawGraphic(x,y,graphic); + DrawGraphicExt(d, gc, dest_x,dest_y, graphic); return; } - dest_x = FX + x*TILEX; - dest_y = FY + y*TILEY; - if (tile_clipmask[tile] != None) { XSetClipMask(display, tile_clip_gc, tile_clipmask[tile]); @@ -658,8 +669,6 @@ void DrawGraphicThruMask(int x, int y, int graphic) XCopyArea(display, src_pixmap, drawto_field, drawing_gc, src_x,src_y, TILEX,TILEY, dest_x,dest_y); } - - MarkTileDirty(x,y); } void DrawMiniGraphic(int x, int y, int graphic) @@ -1281,7 +1290,7 @@ void DrawMicroLevel(int xpos, int ypos) redraw_mask |= REDRAW_MICROLEV; } -int AYS_in_range(int x, int y) +int REQ_in_range(int x, int y) { if (y>DY+249 && y