From 619c1b3f499c323ef949b9e81b55fc5b0f3b2aa6 Mon Sep 17 00:00:00 2001 From: stpohle Date: Sun, 27 Jul 2008 11:24:32 +0000 Subject: [PATCH] added joystick support and a message to the network game.. --- ChangeLog | 13 ++- include/bomberclone.h | 3 +- include/keyb.h | 6 ++ src/configuration.c | 29 ++++++- src/game.c | 8 +- src/keyb.c | 179 ++++++++++++++++++++++++++++++++++++++++-- src/main.c | 7 +- src/multiwait.c | 7 +- 8 files changed, 235 insertions(+), 17 deletions(-) diff --git a/ChangeLog b/ChangeLog index 53e0295..c41d2ce 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,10 +1,19 @@ -$Id: ChangeLog,v 1.125 2008/04/04 10:50:49 stpohle Exp $ +$Id: ChangeLog,v 1.126 2008/07/27 11:24:32 stpohle Exp $ CVS Version =========== -4.4.2008 +27.7.2008 +- Added Warning if a game get startet with only one player selected + Patch send in by: Carles Pina i Estany + +- Added Joystick support - Patch send in by: Patrick Kirsch + Chenges i made to the patch: I open only once the joystick device. + Since after the patch the joystick got opened a few times without + closing it again. The setupmenu will display now the number of the + button which is selected for the function. +4.4.2008 - Fixed BUG found by Lars Poeschel One player could join without problems and if a second player joined this network game, the server crashed in do_contest() accessing diff --git a/include/bomberclone.h b/include/bomberclone.h index 49ce94b..7f55df2 100644 --- a/include/bomberclone.h +++ b/include/bomberclone.h @@ -1,4 +1,4 @@ -/* $Id: bomberclone.h,v 1.35 2006/08/19 23:41:47 stpohle Exp $ */ +/* $Id: bomberclone.h,v 1.36 2008/07/27 11:24:37 stpohle Exp $ */ /* bomberclone.h */ #ifndef _BOMBERCLONE_H_ @@ -152,6 +152,7 @@ extern int config_write(); extern void ReadPrgArgs (int argc, char **argv); extern void ReadPrgArgs_Jump (int argc, char **argv); extern int check_version (int ma, int mi, int su, char *ver); +void joypad_config (); // debug.c extern void d_in_pl_detail (char *head); diff --git a/include/keyb.h b/include/keyb.h index 3c7cb4d..74b303d 100644 --- a/include/keyb.h +++ b/include/keyb.h @@ -35,7 +35,13 @@ struct { int keycode [BCK_max]; // keycode } typedef BCGameKeys; +struct { + int drop; + int special; +} typedef BCGameJoystick; + extern BCGameKeys keyb_gamekeys; +extern BCGameJoystick joy_keys[2]; extern void keyb_config (); extern void keyb_config_reset (); diff --git a/src/configuration.c b/src/configuration.c index 8d2d685..14d5890 100644 --- a/src/configuration.c +++ b/src/configuration.c @@ -1,4 +1,4 @@ -/* $Id: configuration.c,v 1.82 2007/12/07 22:06:57 stpohle Exp $ +/* $Id: configuration.c,v 1.83 2008/07/27 11:24:37 stpohle Exp $ * configuration */ #include @@ -441,6 +441,17 @@ config_read () keyb_gamekeys.keycode[BCK_pause] = atoi (value); if (!strcmp (keyword, "key_fullscreen")) keyb_gamekeys.keycode[BCK_fullscreen] = atoi (value); + /* + * joypad config + */ + if (!strcmp (keyword, "joy_1_drop")) + joy_keys[0].drop = atoi (value); + if (!strcmp (keyword, "joy_1_special")) + joy_keys[0].special = atoi (value); + if (!strcmp (keyword, "joy_2_drop")) + joy_keys[1].drop = atoi (value); + if (!strcmp (keyword, "joy_2_special")) + joy_keys[1].special = atoi (value); } fclose (config); return 0; @@ -530,6 +541,13 @@ config_write () fprintf (config, "key_mapmenu=%d\n", keyb_gamekeys.keycode[BCK_mapmenu]); fprintf (config, "key_pause=%d\n", keyb_gamekeys.keycode[BCK_pause]); fprintf (config, "key_playermenu=%d\n", keyb_gamekeys.keycode[BCK_playermenu]); + /* + * joypad config + */ + fprintf (config, "joy_1_drop=%d\n", joy_keys[0].drop); + fprintf (config, "joy_1_special=%d\n", joy_keys[0].special); + fprintf (config, "joy_2_drop=%d\n", joy_keys[1].drop); + fprintf (config, "joy_2_special=%d\n", joy_keys[1].special); fclose (config); return 0; @@ -631,8 +649,9 @@ config_menu () menu = menu_new ("Configuration", 400, 300); menu_create_label (menu, "General Option", -1, 50, 1, COLOR_brown); menu_create_button (menu, "Playernames", 25, 85, 150, 1); - menu_create_button (menu, "Keyboard", 225, 85, 150, 2); - menu_create_button (menu, "Video Setup", -1, 120, 200, 3); + menu_create_button (menu, "Keyboard", 250, 85, 150, 2); + menu_create_button (menu, "Joypad", 25, 120, 150, 4); + menu_create_button (menu, "Video Setup", 250, 120, 150, 3); menu_create_label (menu, "Sound", 25, 154, 0, COLOR_brown); menu_create_bool (menu, "ON", 100, 150, 50, &snd.playsound, 4); menu_create_label (menu, "Music", 250, 154, 0, COLOR_brown); @@ -666,6 +685,10 @@ config_menu () case (3): // Screen Options config_video (); break; + case (4): // joypad Options + joypad_config (); + break; + } } config_write (); diff --git a/src/game.c b/src/game.c index a6822d3..01c0d4b 100644 --- a/src/game.c +++ b/src/game.c @@ -1,4 +1,4 @@ -/* $Id: game.c,v 1.118 2007/01/12 22:42:31 stpohle Exp $ +/* $Id: game.c,v 1.119 2008/07/27 11:24:37 stpohle Exp $ game.c - procedures for the game. */ #include @@ -233,6 +233,11 @@ game_loop () if (GT_MP) net_game_fillsockaddr (); + if ( SDL_InitSubSystem ( SDL_INIT_JOYSTICK ) < 0 ) + { + fprintf ( stderr, "Unable to initialize Joystick: %s\n", SDL_GetError() ); + } + printf ( "%i joysticks found\n", SDL_NumJoysticks () ); menu = NULL; bman.updatestatusbar = 1; // force an update @@ -257,6 +262,7 @@ game_loop () } while (!done && (bman.state == GS_running || bman.state == GS_ready)) { + SDL_JoystickUpdate (); if ((eventstate = SDL_PollEvent (&event)) != 0) switch (event.type) { case (SDL_QUIT): diff --git a/src/keyb.c b/src/keyb.c index b100928..4d7f2c7 100644 --- a/src/keyb.c +++ b/src/keyb.c @@ -1,4 +1,4 @@ -/* $Id: keyb.c,v 1.6 2005/08/07 17:46:21 stpohle Exp $ +/* $Id: keyb.c,v 1.7 2008/07/27 11:24:37 stpohle Exp $ * keyb.c */ @@ -7,8 +7,11 @@ #include "ogcache-client.h" #include "menu.h" #include "keyb.h" +#include "SDL.h" BCGameKeys keyb_gamekeys; +BCGameJoystick joy_keys[2]; +SDL_Joystick *joy[2]; /* * Translation table for the keycodes @@ -76,6 +79,11 @@ void keyb_config_reset () { keyb_gamekeys.keycode[BCK_pause] = SDLK_F4; keyb_gamekeys.keycode[BCK_fullscreen] = SDLK_F8; keyb_gamekeys.keycode[BCK_esc] = SDLK_ESCAPE; + + joy_keys[0].drop = 0; + joy_keys[0].special = 1; + joy_keys[1].drop = 0; + joy_keys[1].special = 1; }; @@ -119,9 +127,9 @@ void keyb_config_createkeymenu (_menu *menu, int key, int x, int y, int menu_nr) int key_id; char keyname [32]; char keytext [50]; - + for (key_id = key; key_id >= BCPK_max && key_id < BCPK_max * 3; key_id = key_id - BCPK_max); - + switch (key_id) { case (BCPK_up): strcpy (keyname, "Up"); @@ -166,6 +174,70 @@ void keyb_config_createkeymenu (_menu *menu, int key, int x, int y, int menu_nr) menu_create_button (menu, keytext, x + 70, y, 100, menu_nr + key); } +/* + * select a new key for the function, + */ +void keyb_config_joypad (int key) { + unsigned int n = 0; + SDL_Event event; + Uint8 *keys; + int keypressed = 0, done = 0, eventstate = 0, reorder = 0, i, j; + + if (joy[0] == NULL || key < 0 || key >= BCK_max) return; + + SDL_JoystickUpdate (); + + menu_displaytext ("Joypad Config", "Please press the new key\nfor this function."); + + keys = SDL_GetKeyState (NULL); + if (keys[SDLK_RETURN] || keys[SDLK_ESCAPE]) + keypressed = 1; + + timestamp = SDL_GetTicks (); // needed for time sync. + + while (!reorder && !done && bman.state != GS_quit) { + /* do the network loop if we have to */ + if (bman.sock > 0) { + network_loop (); + if (bman.notifygamemaster) + reorder = ogc_loop (); + else + reorder = 0; + } + + // eventstate = s_fetchevent (&event); + SDL_JoystickEventState ( SDL_QUERY ); // js + SDL_JoystickUpdate (); + + for ( j = 0; j < 2; j++) + for ( i=0; i < SDL_JoystickNumButtons ( joy[j] ); ++i ) { + n = SDL_JoystickGetButton ( joy[j], i ); + // 2 .. bomb + /* Sadly every other controller enumberates different */ + if (n != 0) { + printf("keyb keyb_config_joypad: JS %d: %d \n", j, i); + if (key == BCPK_drop || key == BCPK_drop + BCPK_max + BCPK_max) + joy_keys[j].drop = i; + if (key == BCPK_special || key == BCPK_special + BCPK_max + BCPK_max) + joy_keys[j].special = i; + eventstate = 1; + done = 1; + } + } + + if (eventstate >= 1) { + switch (event.type) { + case (SDL_QUIT): + bman.state = GS_quit; + done = 1; + break; + } + } + + s_calctimesync (); + } +}; + /* * select a new key for the function, @@ -224,6 +296,54 @@ void keyb_config_readkey (int key) { keyb_gamekeys.keycode[key] = newkey; }; +/* + * joypad configuration screen + */ +void joypad_config () { + int menuselect = 1; + _menu *menu; + + do { + menu = menu_new ("Joypad Config", 420, 400); + + if ( joy[0] != NULL ) { + char text[32]; + + menu_create_label (menu, "Player 1 Joypad", 20, 105, 1, COLOR_yellow); + // keyb_config_createkeymenu (menu, BCPK_max + BCPK_drop, 25, 250, 10); + menu_create_label (menu, "Drop", 25, 250 + 2, 0, COLOR_brown); + sprintf (text, "%d", joy_keys[0].drop); + menu_create_button (menu, text, 25 + 70, 250, 100, 10 + BCPK_drop); + // keyb_config_createkeymenu (menu, BCPK_max + BCPK_special, 25, 280, 10); + menu_create_label (menu, "Special", 25, 280 + 2, 0, COLOR_brown); + sprintf (text, "%d", joy_keys[0].special); + menu_create_button (menu, text, 25 + 70, 280, 100, 10 + BCPK_special); + } + + if ( joy[1] != NULL ) { + char text[32]; + + menu_create_label (menu, "Player 2 Joypad", 210, 105, 1, COLOR_yellow); + // keyb_config_createkeymenu (menu, BCPK_max + BCPK_max + BCPK_drop, 225, 250, 10); + menu_create_label (menu, "Drop", 225, 250 + 2, 0, COLOR_brown); + sprintf (text, "%d", joy_keys[1].drop); + menu_create_button (menu, text, 225 + 70, 250, 100, 10 + BCPK_max + BCPK_max + BCPK_drop); + // keyb_config_createkeymenu (menu, BCPK_max + BCPK_max + BCPK_special, 225, 280, 10); + menu_create_label (menu, "Special", 225, 280 + 2, 0, COLOR_brown); + sprintf (text, "%d", joy_keys[1].special); + menu_create_button (menu, text, 225 + 70, 280, 100, 10 + BCPK_max + BCPK_max + BCPK_special); + } + + menu_create_button (menu, "OK", 250, 330, 150, 1); + menu_focus_id (menu, menuselect); + menuselect = menu_loop (menu); + menu_delete (menu); + if (menuselect >= 10 && menuselect < 10+BCK_max) + keyb_config_joypad (menuselect - 10); + } while (menuselect != 1 && menuselect != -1); +}; + + /* * keyboard configuration screen @@ -282,6 +402,11 @@ void keyb_config () { */ void keyb_init () { memset (keyb_gamekeys.state, 0, sizeof (Uint8) * BCK_max); + joy[0] = joy[1] = NULL; + + joy[0] = SDL_JoystickOpen (0); + if (joy[0]) + joy[1] = SDL_JoystickOpen (1); }; @@ -289,14 +414,54 @@ void keyb_init () { * read all keys and set the keyb_gamekeys */ void keyb_loop (SDL_Event *event) { - int i; - + int j, i, offset = 0; + Uint8 *keys = SDL_GetKeyState (NULL); - + + if (joy[0]) { + SDL_JoystickEventState ( SDL_QUERY ); // js + SDL_JoystickUpdate (); + } + /* copy the state into the old state */ memcpy (keyb_gamekeys.old, keyb_gamekeys.state, sizeof (Uint8) * BCK_max); memset (keyb_gamekeys.state, 0, sizeof (Uint8) * BCK_max); - + + for (j = 0; j < 2; j++) { + if (joy[j]) { + for ( i=0; i < SDL_JoystickNumButtons (joy[j]); ++i ) { + unsigned int n = SDL_JoystickGetButton (joy[j], i); + /* Sadly every other controller enumberates different */ + if (n != 0 && i == joy_keys[j].drop) + keyb_gamekeys.state[offset + BCPK_drop] |= 1; + if (n != 0 && i == joy_keys[j].special) + keyb_gamekeys.state[offset + BCPK_special] |= 1; + } + + for ( i=0; i < SDL_JoystickNumAxes ( joy[j] ); ++i ) { + signed short a = SDL_JoystickGetAxis ( joy[j], i ); + /* + X -> Axis 0 + Y -> Axis 1 + There are only the values -32786 .. 32768 available + */ + if ( i == 0 && a < (-16000) ) { + keyb_gamekeys.state[offset + BCPK_left] |= 1; + } + if (i == 0 && a > 16000 ) { + keyb_gamekeys.state[offset + BCPK_right] |= 1; + } + if ( i == 1 && a < -16000 ) { + keyb_gamekeys.state[offset + BCPK_up] |= 1; + } + if (i == 1 && a > 16000 ) { + keyb_gamekeys.state[offset + BCPK_down] |= 1; + } + } + } + offset = BCPK_max + BCPK_max; + } + /* read the new state of the pressed keys */ for (i = 0; i < BCK_max; i++) { if (keyb_gamekeys.keycode[i] >= 'A' && keyb_gamekeys.keycode[i] <= 'Z') { diff --git a/src/main.c b/src/main.c index b1bb568..f0aea75 100644 --- a/src/main.c +++ b/src/main.c @@ -1,4 +1,4 @@ -/* $Id: main.c,v 1.36 2007/02/17 08:27:41 stpohle Exp $ */ +/* $Id: main.c,v 1.37 2008/07/27 11:24:37 stpohle Exp $ */ #include "basic.h" #include "bomberclone.h" @@ -6,6 +6,7 @@ #include "gfx.h" #include "menu.h" #include "player.h" +#include "keyb.h" #include "single.h" _bomberclone bman; // Holds GameData @@ -40,10 +41,12 @@ main (int argc, char **argv) return (1); } + SDL_InitSubSystem ( SDL_INIT_JOYSTICK ); SDL_EnableUNICODE(1); config_init (argc, argv); - + keyb_init (); + while (menuselect != -1 && bman.state != GS_quit) { menu = menu_new ("Bomberclone", 400, 250); diff --git a/src/multiwait.c b/src/multiwait.c index c588af4..ae3bfac 100644 --- a/src/multiwait.c +++ b/src/multiwait.c @@ -1,4 +1,4 @@ -/* $Id: multiwait.c,v 1.59 2006/08/19 23:41:47 stpohle Exp $ +/* $Id: multiwait.c,v 1.60 2008/07/27 11:24:37 stpohle Exp $ multiwait.c - this manages only the network screen where everyone have to select it's players and where even the basic chat is inside */ @@ -85,6 +85,11 @@ static void mw_keys_loop () { bman.updatestatusbar = 1; // force an update } + if (GT_MP_PTPM && mw_check_players () < 2 && keyb_gamekeys.state[BCK_pause] && !keyb_gamekeys.old[BCK_pause]) { + font_gfxdraw (20,20,"There are not enough configured players", 0, COLOR_brown, 0x1000); + font_gfxdraw (20,40,"(each player needs to press Ctrl to select the role)", 0, COLOR_brown, 0x1000); + } + if (keyb_gamekeys.state[BCK_fullscreen] && !keyb_gamekeys.old[BCK_fullscreen]) { /* Switch Fullscreen */ SDL_WM_ToggleFullScreen(gfx.screen);