Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * interrpt.c
  3.  * Copyright (C) 1998 Brainchild Design - http://brainchilddesign.com/
  4.  *
  5.  * Copyright (C) 2001 Chuck Mason <cemason@users.sourceforge.net>
  6.  *
  7.  * Copyright (C) 2002 Florian Schulze <crow@icculus.org>
  8.  *
  9.  * This file is part of Jump'n'Bump.
  10.  *
  11.  * Jump'n'Bump is free software; you can redistribute it and/or modify
  12.  * it under the terms of the GNU General Public License as published by
  13.  * the Free Software Foundation; either version 2 of the License, or
  14.  * (at your option) any later version.
  15.  *
  16.  * Jump'n'Bump is distributed in the hope that it will be useful,
  17.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  19.  * GNU General Public License for more details.
  20.  *
  21.  * You should have received a copy of the GNU General Public License
  22.  * along with this program; if not, write to the Free Software
  23.  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  24.  */
  25.  
  26. #include <stdio.h>
  27. #include <stdlib.h>
  28. #include <time.h>
  29. #ifndef _MSC_VER
  30. #include <unistd.h>
  31. #endif
  32. #include "globals.h"
  33.  
  34. #ifdef USE_KAILLERA
  35. #include "SDL_thread.h"
  36. #include "SDL_mutex.h"
  37. #include <kailleraclient.h>
  38.  
  39. char local_keyb[256];
  40. #endif /* USE_KAILLERA */
  41.  
  42. char keyb[256];
  43. char last_keys[50];
  44.  
  45. #ifdef USE_KAILLERA
  46.  
  47. /* information about the party in this session */
  48. static int my_player = -1;
  49. static int my_numplayers = -1;
  50.  
  51. /* semaphore for controlling kaillera thread */
  52. static SDL_sem *game_start_sem = NULL;
  53.  
  54. /* keys supported on my end */
  55. static int my_player_up = -1;
  56. static int my_player_left = -1;
  57. static int my_player_right = 1;
  58.  
  59. /* values for the kaillera client interface */
  60. static char kaillera_app_name[] = "Jump 'n Bump";
  61. static char kaillera_game_name[] = "Jump 'n Bump\0\0";
  62.  
  63. static int player_keys[4][3] = {
  64.         {
  65.                 KEY_PL1_LEFT,
  66.                 KEY_PL1_RIGHT,
  67.                 KEY_PL1_JUMP
  68.         },                        
  69.         {
  70.                 KEY_PL2_LEFT,
  71.                 KEY_PL2_RIGHT,
  72.                 KEY_PL2_JUMP
  73.         },
  74.         {
  75.                 KEY_PL3_LEFT,
  76.                 KEY_PL3_RIGHT,
  77.                 KEY_PL3_JUMP
  78.         },
  79.         {
  80.                 KEY_PL4_LEFT,
  81.                 KEY_PL4_RIGHT,
  82.                 KEY_PL4_JUMP
  83.         }
  84. };
  85.  
  86. static int WINAPI kaillera_game_callback(char *game, int player, int numplayers)
  87. {
  88.         int length;
  89.         int urand;
  90.         unsigned char random[8];
  91.  
  92.         if (strcmp(game, kaillera_game_name) != 0) {
  93.                 printf("unknown game selected: %s\n", game);
  94.  
  95.                 my_player = -1;
  96.                 goto release;
  97.         }
  98.  
  99.         printf("start network game with %d players\n", numplayers);
  100.         printf("I am player %d\n", player);
  101.  
  102.         my_player = player;
  103.         my_numplayers = numplayers;
  104.  
  105.         my_player_up = player_keys[player-1][0] & 0xff;
  106.         my_player_left = player_keys[player-1][1] & 0xff;
  107.         my_player_right = player_keys[player-1][2] & 0xff;
  108.  
  109.         /* initialize randomizer agreed by all players */
  110.         random[0] = time(0) & 0xff;
  111.         random[1] = random[2] = random[3] = 0x00;
  112.         length = kailleraModifyPlayValues(&random, sizeof(random[0]));
  113.         if (length < 0) {
  114.                 goto release;
  115.         }
  116.  
  117.         urand = random[3] << 24 | random[2] << 16 | random[1] << 8 | random[0];
  118.         srand(urand);
  119.  
  120. release:
  121.  
  122.         SDL_SemPost(game_start_sem);
  123.         return 0;
  124. }
  125.  
  126. static kailleraInfos kaillera_data = {
  127.         kaillera_app_name,
  128.         kaillera_game_name,
  129.         kaillera_game_callback,
  130.         NULL,
  131.         NULL,
  132.         NULL
  133. };
  134.  
  135. static void print_version()
  136. {
  137.         char version[16];
  138.  
  139.         kailleraGetVersion(version);
  140.         printf("using kaillera version %s\n", version);
  141. }
  142.  
  143. static int kaillera_thread(void *arg)
  144. {
  145.         kailleraInit();
  146.        
  147.         /* print_version(); */
  148.  
  149.         kailleraSetInfos(&kaillera_data);
  150.  
  151.         kailleraSelectServerDialog(0);
  152.         if (SDL_SemValue(game_start_sem) == 0) {
  153.                 /* server dialog returned and game didnt start */
  154.                
  155.                 /* release blocking thread */
  156.                 my_player = -1;
  157.                 SDL_SemPost(game_start_sem);
  158.         }
  159.  
  160.         return 0;
  161. }
  162.  
  163. static int start_kaillera_thread(void)
  164. {
  165.         SDL_Thread *thread;
  166.  
  167.         game_start_sem = SDL_CreateSemaphore(0);
  168.  
  169.         thread = SDL_CreateThread(kaillera_thread, NULL);
  170.         if (!thread) {
  171.                 printf("SDL_CreateThread failed\n");
  172.                 return -1;
  173.         }
  174.        
  175.         return 0;
  176. }      
  177.  
  178. int addkey(unsigned int key)
  179. {
  180.         /* it doesnt matter if a player presses keys
  181.          * that control other bunnies. whatever is sent
  182.          * is packed by pack_keys()
  183.          */
  184.         if (!(key & 0x8000)) {
  185.                 local_keyb[key & 0x7fff] = 1;
  186.         } else
  187.                 local_keyb[key & 0x7fff] = 0;
  188.         return 0;
  189. }
  190.  
  191. void remove_keyb_handler(void)
  192. {
  193.         kailleraShutdown();
  194. }
  195.  
  196. int pack_keys(void)
  197. {
  198.         int rv;
  199.  
  200.         rv = local_keyb[my_player_up];
  201.         rv |= local_keyb[my_player_left] << 1;
  202.         rv |= local_keyb[my_player_right] << 2;
  203.         rv |= local_keyb[1] << 3;
  204.         return rv;
  205. }
  206.  
  207. void unpack_keys(int player, char value)
  208. {
  209.         keyb[player_keys[player][0] & 0xff] = (value >> 0) & 1;
  210.         keyb[player_keys[player][1] & 0xff] = (value >> 1) & 1;
  211.         keyb[player_keys[player][2] & 0xff] = (value >> 2) & 1;
  212.  
  213.         /* escape key is shared among all users */
  214.         keyb[1] |= (value >> 3) & 1;
  215. }
  216.  
  217. int update_kaillera_keys(void)
  218. {
  219.         char keys[8];
  220.         int length;
  221.         int player;
  222.  
  223.         keys[0] = pack_keys();
  224.         length = kailleraModifyPlayValues(&keys, sizeof(keys[0]));
  225.  
  226.         if (length < 0) {
  227.                 /* terminate session */
  228.                 printf("** LOST CONNECTION **\n");
  229.                 kailleraEndGame();
  230.                 my_player = -1;
  231.                 return -1;
  232.         }
  233.  
  234.         for (player=0; player<length; player++) {
  235.                 unpack_keys(player, keys[player]);
  236.         }
  237.  
  238.         return 0;
  239. }
  240.  
  241. int hook_keyb_handler(void)
  242. {
  243.         SDL_EnableUNICODE(1);
  244.         memset((void *) last_keys, 0, sizeof(last_keys));
  245.  
  246.         start_kaillera_thread();
  247.         SDL_SemWait(game_start_sem);
  248.         if (my_player < 0) {
  249.                 printf("GAME ABORTED!\n");
  250.                 return -1;
  251.         }
  252.  
  253.         printf("GAME STARTS!\n");
  254.         return 0;
  255. }
  256.  
  257. int key_pressed(int key)
  258. {
  259.         if (key == 1 && my_player < 0) {
  260.                 /* if game completed or aborted, post ESC */
  261.                 return 1;
  262.         }
  263.  
  264.         return keyb[(unsigned char) key];
  265. }
  266.  
  267. #else /* USE_KAILLERA */
  268.  
  269. int addkey(unsigned int key)
  270. {
  271.         int c1;
  272.  
  273.         if (!(key & 0x8000)) {
  274.                 keyb[key & 0x7fff] = 1;
  275.                 for (c1 = 48; c1 > 0; c1--)
  276.                         last_keys[c1] = last_keys[c1 - 1];
  277.                 last_keys[0] = key & 0x7fff;
  278.         } else
  279.                 keyb[key & 0x7fff] = 0;
  280.         return 0;
  281. }
  282.  
  283. void remove_keyb_handler(void)
  284. {
  285. }
  286.  
  287. int hook_keyb_handler(void)
  288. {
  289.         SDL_EnableUNICODE(1);
  290.         memset((void *) last_keys, 0, sizeof(last_keys));
  291.  
  292.         return 0;
  293. }
  294.  
  295. int key_pressed(int key)
  296. {
  297.         return keyb[(unsigned char) key];
  298. }
  299.  
  300.  
  301. #endif /* USE_KAILLERA */
  302.  
  303. int intr_sysupdate()
  304. {
  305.         SDL_Event e;
  306.         int i = 0;
  307.         static int last_time = 0;
  308.         int now, time_diff;
  309.  
  310.         while (SDL_PollEvent(&e)) {
  311.                 switch (e.type) {
  312.                 case SDL_MOUSEBUTTONDOWN:
  313.                 case SDL_MOUSEBUTTONUP:
  314.                         if(e.button.state == SDL_PRESSED &&
  315.                                         ((key_pressed(KEY_PL3_LEFT) && e.button.button == SDL_BUTTON_RIGHT) ||
  316.                                         (key_pressed(KEY_PL3_RIGHT) && e.button.button == SDL_BUTTON_LEFT) ||
  317.                                         (e.button.button == SDL_BUTTON_LEFT && e.button.button == SDL_BUTTON_RIGHT) ||
  318.           e.button.button == SDL_BUTTON_MIDDLE))
  319.                                 {
  320.                                 addkey(KEY_PL3_JUMP & 0x7f);
  321.                                 }
  322.                         else if(e.button.state == SDL_RELEASED &&
  323.                                         ((key_pressed(KEY_PL3_LEFT) && e.button.button == SDL_BUTTON_RIGHT) ||
  324.                                         (key_pressed(KEY_PL3_RIGHT) && e.button.button == SDL_BUTTON_LEFT) ||
  325.           e.button.button == SDL_BUTTON_MIDDLE))
  326.                                 {
  327.                                 addkey((KEY_PL3_JUMP & 0x7f) | 0x8000);
  328.                                 }
  329.  
  330.                         if(e.button.button == SDL_BUTTON_LEFT)
  331.                                 {
  332.                                 SDLKey sym = KEY_PL3_LEFT;
  333.                                 sym &= 0x7f;
  334.                                 if(e.button.state == SDL_RELEASED)
  335.                                         {
  336.                                         if(key_pressed(KEY_PL3_JUMP) && (SDL_GetMouseState(NULL, NULL)&SDL_BUTTON(SDL_BUTTON_RIGHT)))
  337.                                                 addkey(KEY_PL3_RIGHT & 0x7f);
  338.                                         else
  339.                                                 sym |= 0x8000;
  340.                                         }
  341.                                 addkey(sym);
  342.                                 }
  343.                         else if(e.button.button == SDL_BUTTON_RIGHT)
  344.                                 {
  345.                                 SDLKey sym = KEY_PL3_RIGHT;
  346.                                 sym &= 0x7f;
  347.                                 if (e.button.state == SDL_RELEASED)
  348.                                         {
  349.                                         if(key_pressed(KEY_PL3_JUMP) && (SDL_GetMouseState(NULL, NULL)&SDL_BUTTON(SDL_BUTTON_LEFT)))
  350.                                                 addkey(KEY_PL3_LEFT & 0x7f);
  351.                                         else
  352.                                                 sym |= 0x8000;
  353.                                         }
  354.                                 addkey(sym);
  355.                                 }
  356.                         break;
  357.                 case SDL_KEYDOWN:
  358.                 case SDL_KEYUP:
  359.                         switch (e.key.keysym.sym) {
  360.                         case SDLK_F12:
  361.                                 if (e.type == SDL_KEYDOWN) {
  362.                                         SDL_Quit();
  363.                                         exit(1);
  364.                                 }
  365.                                 break;
  366.                         case SDLK_F10:
  367.                                 if (e.type == SDL_KEYDOWN) {
  368.                                         fs_toggle();
  369.                                 }
  370.                                 break;
  371.                         case SDLK_1:
  372.                                 if (e.type == SDL_KEYUP)
  373.                                         ai[0] = !ai[0];
  374.  
  375.                                 /* Release keys, otherwise it will continue moving that way */
  376.                                 addkey((KEY_PL1_LEFT & 0x7f) | 0x8000);
  377.                                 addkey((KEY_PL1_RIGHT & 0x7f) | 0x8000);
  378.                                 addkey((KEY_PL1_JUMP & 0x7f) | 0x8000);
  379.                                 break;
  380.                         case SDLK_2:
  381.                                 if (e.type == SDL_KEYUP)
  382.                                         ai[1] = !ai[1];
  383.  
  384.                                 /* Release keys, otherwise it will continue moving that way */
  385.                                 addkey((KEY_PL2_LEFT & 0x7f) | 0x8000);
  386.                                 addkey((KEY_PL2_RIGHT & 0x7f) | 0x8000);
  387.                                 addkey((KEY_PL2_JUMP & 0x7f) | 0x8000);
  388.                                 break;
  389.                         case SDLK_3:
  390.                                 if (e.type == SDL_KEYUP)
  391.                                         ai[2] = !ai[2];
  392.  
  393.                                 /* Release keys, otherwise it will continue moving that way */
  394.                                 addkey((KEY_PL3_LEFT & 0x7f) | 0x8000);
  395.                                 addkey((KEY_PL3_RIGHT & 0x7f) | 0x8000);
  396.                                 addkey((KEY_PL3_JUMP & 0x7f) | 0x8000);
  397.                                 break;
  398.                         case SDLK_4:
  399.                                 if (e.type == SDL_KEYUP)
  400.                                         ai[3] = !ai[3];
  401.  
  402.                                 /* Release keys, otherwise it will continue moving that way */
  403.                                 addkey((KEY_PL4_LEFT & 0x7f) | 0x8000);
  404.                                 addkey((KEY_PL4_RIGHT & 0x7f) | 0x8000);
  405.                                 addkey((KEY_PL4_JUMP & 0x7f) | 0x8000);
  406.                                 break;
  407.                         case SDLK_ESCAPE:
  408.                                 if (e.type == SDL_KEYUP)
  409.                                         addkey(1 | 0x8000);
  410.                                 else
  411.                                         addkey(1 & 0x7f);
  412.                                 break;
  413.                         default:
  414.                                 e.key.keysym.sym &= 0x7f;
  415.                                 if (e.type == SDL_KEYUP)
  416.                                         e.key.keysym.sym |= 0x8000;
  417.                                 addkey(e.key.keysym.sym);
  418.  
  419.                                 break;
  420.                         }
  421.                         break;
  422.                 default:
  423.                         break;
  424.                 }
  425.                 i++;
  426.         }
  427.  
  428.         SDL_Delay(1);
  429.         now = SDL_GetTicks();
  430.         time_diff = now - last_time;
  431.         if (time_diff>0) {
  432.                 i = time_diff / (1000 / 60);
  433.                 if (i) {
  434.                         last_time = now;
  435.                 } else {
  436.                         int tmp;
  437.  
  438.                         tmp = (1000/60) - i - 10;
  439.                         if (tmp>0)
  440.                                 SDL_Delay(tmp);
  441.                 }
  442.         }
  443. /*
  444.         if (!then)
  445.                 SDL_Delay(1);
  446.         else {
  447.                 then = (1000 / 60) - (now - then);
  448.                 if (then > 0 && then < 1000)
  449.                         SDL_Delay(then);
  450.         }
  451.         then = now;
  452. */
  453.  
  454. #ifdef USE_KAILLERA
  455.         if (my_player >= 0) {
  456.                 update_kaillera_keys();
  457.                 i=1;
  458.         }
  459. #endif /* USE_KAILLERA */
  460.  
  461.         return i;
  462. }
  463.