Subversion Repositories Kolibri OS

Rev

Rev 5243 | Rev 5260 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. #include "rsgame.h"
  2.  
  3. #include "rsgametext.h"
  4.  
  5. #include "rsgamemenu.h"
  6.  
  7. #include "rsgamedraw.h"
  8.  
  9. #include "rskos.h"
  10.  
  11. #include "rsgentex.h"
  12. #include "rssoundgen.h"
  13. #include "rsnoise.h"
  14.  
  15. #include "rs/rsplatform.h"
  16.  
  17.  
  18.  
  19.  
  20.  
  21. rs_game_t game;
  22.  
  23.  
  24. void texture_init(rs_texture_t *tex, int w, int h) {
  25.     tex->status = 1;
  26.     tex->w = w;
  27.     tex->h = h;
  28.     tex->data = malloc(w*h*4); // BGRA BGRA
  29. };
  30.  
  31. void texture_free(rs_texture_t *tex) {
  32.     free(tex->data);
  33.     tex->status = 0;
  34. };
  35.  
  36. void texture_clear(rs_texture_t *tex, unsigned int color) {
  37.     int i;
  38.     for (i = 0; i < tex->w * tex->h; i++) {
  39.         *((unsigned int*)(&tex->data[i*4])) = color;
  40.     };
  41. };
  42.  
  43. void texture_draw(rs_texture_t *dest, rs_texture_t *src, int x, int y, int mode) {
  44.    
  45.     int i; // y
  46.     int j; // x
  47.     int k; // color component
  48.    
  49.     int istart = (y < 0) ? -y : 0;
  50.     int iend = src->h - (( (y + src->h) > dest->h) ? (y + src->h - dest->h) : 0);
  51.    
  52.     int jstart = (x < 0) ? -x : 0;
  53.     int jend = src->w - (( (x + src->w) > dest->w) ? (x + src->w - dest->w) : 0);
  54.    
  55.     int ishift = 0;
  56.     int jshift = 0;
  57.    
  58.     float a; // alpha value
  59.    
  60.     if (mode & DRAW_TILED_FLAG) {
  61.         jshift = x;
  62.         ishift = y;
  63.         x = y = istart = jstart = 0;
  64.         iend = dest->h;
  65.         jend = dest->w;
  66.     };
  67.    
  68.     mode = mode & DRAW_MODE_MASK;
  69.    
  70.     int modvalue = (src->w*src->h*4);
  71.    
  72.     if (mode == DRAW_MODE_REPLACE) {
  73.         for (i = istart; i < iend; i++) {
  74.             for (j = jstart; j < jend; j++) {
  75.                 for (k = 0; k < 4; k++) {
  76.                     dest->data[ 4 * ( (y+i)*dest->w + (x+j) ) + k ] = src->data[ (4*((i+ishift)*src->w + j + jshift) + k) % modvalue];
  77.                 };
  78.             };
  79.         };
  80.     }
  81.     else if (mode == DRAW_MODE_ADDITIVE) {
  82.         for (i = istart; i < iend; i++) {
  83.             for (j = jstart; j < jend; j++) {
  84.                 for (k = 0; k < 3; k++) { // Alpha channel is not added
  85.                     dest->data[ 4 * ( (y+i)*dest->w + (x+j) ) + k ] =
  86.                         clamp_byte( dest->data[ 4 * ( (y+i)*dest->w + (x+j) ) + k ] + src->data[ (4*((i+ishift)*src->w + j + jshift) + k) % modvalue] );
  87.                 };
  88.             };
  89.         };
  90.     }
  91.     else if (mode == DRAW_MODE_MULT) {
  92.         for (i = istart; i < iend; i++) {
  93.             for (j = jstart; j < jend; j++) {
  94.                 for (k = 0; k < 3; k++) { // Alpha channel is not added
  95.                     dest->data[ 4 * ( (y+i)*dest->w + (x+j) ) + k ] =
  96.                         clamp_byte( dest->data[ 4 * ( (y+i)*dest->w + (x+j) ) + k ] * src->data[ (4*((i+ishift)*src->w + j + jshift) + k) % modvalue] / 255 );
  97.                 };
  98.             };
  99.         };
  100.     }
  101.     else if (mode == DRAW_MODE_ALPHA) {
  102.         for (i = istart; i < iend; i++) {
  103.             for (j = jstart; j < jend; j++) {
  104.                 for (k = 0; k < 3; k++) {
  105.                     a = (1.0 * src->data[ (4*(i*src->w + j) + 3) % modvalue ] / 255.0);
  106.                     dest->data[ 4 * ( (y+i)*dest->w + (x+j) ) + k ] =
  107.                          (unsigned char) ( (1.0-a) * dest->data[ 4 * ( (y+i)*dest->w + (x+j) ) + k ]
  108.                                           + a*src->data[ (4*((i+ishift)*src->w + j + jshift) + k) % modvalue] );
  109.                 };
  110.             };
  111.         };
  112.     };
  113.    
  114. };
  115.  
  116.  
  117.  
  118. void texture_set_pixel(rs_texture_t *tex, int x, int y, unsigned int color) {
  119.     *((unsigned int*) &tex->data[ 4 * ( (y)*tex->w + (x) ) + 0 ]) = color;
  120. };
  121.  
  122. void texture_draw_vline(rs_texture_t *tex, int x, int y, int l, unsigned int color) {
  123.     int i;
  124.     if (y+l >= tex->h) {
  125.         l = tex->h - y;
  126.     };
  127.     for (i = 0; i < l; i++) {
  128.         *((unsigned int*) &tex->data[ 4 * ( (y+i)*tex->w + (x) ) + 0 ]) = color;
  129.     };    
  130. };
  131.  
  132. void texture_draw_hline(rs_texture_t *tex, int x, int y, int l, unsigned int color) {
  133.     int i;
  134.     if (x+l >= tex->w) {
  135.         l = tex->w - x;
  136.     };
  137.     for (i = 0; i < l; i++) {
  138.         *((unsigned int*) &tex->data[ 4 * ( (y)*tex->w + (x+i) ) + 0 ]) = color;
  139.     };    
  140. };
  141.  
  142.  
  143.  
  144. void soundbuf_init(rs_soundbuf_t *snd, int length_samples) {
  145.     snd->status = 1;
  146.     snd->length_samples = length_samples;
  147.     snd->data = malloc(length_samples*2);
  148.     rskos_snd_create_buffer(&snd->hbuf, snd->data, length_samples);
  149. };
  150.  
  151. void soundbuf_update(rs_soundbuf_t *snd) {
  152.     rskos_snd_update_buffer(&snd->hbuf, snd->data, snd->length_samples);
  153. };
  154.  
  155. void soundbuf_free(rs_soundbuf_t *snd) {
  156.     snd->status = 0;
  157.     free(snd->data);
  158. };
  159.  
  160. void soundbuf_fill(rs_soundbuf_t *snd, int amp, int freq_div) {
  161.     int i;
  162.     for (i = 0; i < snd->length_samples; i++) {
  163.                 snd->data[i] = -amp/2 + amp/2*( ( (i % freq_div) > freq_div/2 ) ? 1 : 0 );
  164.         };
  165.         rskos_snd_update_buffer(&snd->hbuf, snd->data, snd->length_samples);
  166. };
  167.  
  168. void soundbuf_sin(rs_soundbuf_t *snd, float freq) {
  169.     int i;
  170.     int amp = 29000;
  171.     for (i = 0; i < snd->length_samples; i++) {
  172.                 snd->data[i] = ( 1.0 - 1.0*i/snd->length_samples ) * sin(freq*i) * amp;
  173.         };
  174.         rskos_snd_update_buffer(&snd->hbuf, snd->data, snd->length_samples);
  175. };
  176.  
  177. void soundbuf_sin_fade(rs_soundbuf_t *snd, float freq) {
  178.     int i;
  179.     int amp = 29000;
  180.     for (i = 0; i < snd->length_samples; i++) {
  181.                 snd->data[i] = ( 1.0 - 1.0*i/snd->length_samples ) * sin( ( (1.0 - 0.48*i/snd->length_samples) * freq ) *i) * amp;
  182.         };
  183.        
  184.        
  185.         /*
  186.        
  187.         // ok
  188.        
  189.         rs_sgen_init(2, snd->length_samples);
  190.         rs_sgen_func_pm(1, 880.0, 21.0, 0.3, 110.0, 0.3);
  191.         rs_sgen_func_normalize(1, 1.0);
  192.         rs_sgen_func_lowpass(0, 1, 1.0, 0.0, 1.0);
  193.         rs_sgen_wave_out(0);
  194.        
  195.         memcpy(snd->data, rs_sgen_reg.wave_out, snd->length_samples*2 );
  196.        
  197.         rs_sgen_term();
  198.        
  199.         */
  200.        
  201.         rskos_snd_update_buffer(&snd->hbuf, snd->data, snd->length_samples);
  202. };
  203.  
  204. void soundbuf_play(rs_soundbuf_t *snd) {
  205.     rskos_snd_play(&snd->hbuf, 0);
  206. };
  207.  
  208. void soundbuf_stop(rs_soundbuf_t *snd) {
  209.     rskos_snd_stop(&snd->hbuf);
  210. };
  211.  
  212.  
  213.  
  214. unsigned char clamp_byte(int value) {
  215.     value = value * (1 - (value >> 31)); // negative to zero
  216.     return (value > 255) ? 255 : value;
  217. };
  218.  
  219.  
  220. void game_reg_init() {
  221.    
  222.     game.loader_counter = 0;
  223.    
  224.     game.menu_replay_timeout = 0;
  225.    
  226.     game.process_timer = 0;
  227.    
  228.     game.sound_index = 0;
  229.    
  230.     game.need_redraw = 1;
  231.    
  232.     game.score = 0;
  233.     game.time = 0;
  234.    
  235. //    game.game_mode = GAME_MODE_RAMPAGE;
  236.  
  237.     game.selected = 0;
  238.     game.selected_x = game.selected_y = 0;
  239.    
  240.     game.explosions_count = 0;
  241.    
  242. //    game.tx = 0;
  243. //    game.ty = 0;
  244. //    game.tz = 0;
  245.  
  246. //    int i;
  247. //    for (i = 0; i < BULLETS_COUNT; i++) {
  248. //        game.bullet_x[i] = 0;
  249. //        game.bullet_y[i] = 0;
  250. //    };
  251. //    game.bullet_index = 0;
  252.    
  253.     game.status = STATUS_LOADING;
  254.  
  255. //    game.window_scale = 1;
  256.    
  257. //    game.window_scale = 2;
  258. //    #ifndef RS_KOS
  259. //        game.window_scale = 3;
  260. //        window_scale_str[3] = '3';
  261. //    #endif
  262.    
  263.     game.keyboard_state = 0;
  264.    
  265. //    game.menu_index = 0;
  266. //    game.menu_item_index = 0;
  267. };
  268.  
  269.  
  270. int is_key_pressed(int mask) {
  271.     return IS_BIT_SET(game.keyboard_state, mask) ? 1 : 0;
  272. };
  273.  
  274. int seed = 0;
  275. int get_random_crystal() {
  276.     seed += 2;
  277.     return ( (seed + (get_time() & 0xFFFF) ) % CRYSTALS_COUNT) | CRYSTAL_VISIBLE_BIT;
  278. };
  279.  
  280. int game_check_and_explode() {
  281.     int x, y, i, item, match_count, found;
  282.     found = 0;
  283.    
  284.     // vertical lines
  285.     for (x = 0; x < FIELD_WIDTH; x++) {
  286.         match_count = 0;
  287.         item = 0xFF;
  288.         for (y = FIELD_HEIGHT-1; y >= 0; y--) {
  289.                
  290.             if ( IS_BIT_SET( FIELD_ITEM(x,y), CRYSTAL_MOVING_BIT ) || IS_BIT_CLEARED( FIELD_ITEM(x,y), CRYSTAL_VISIBLE_BIT) ) {
  291.                 item = 0xFF;
  292.                 match_count = 0;
  293.                 continue;
  294.             };
  295.            
  296.             if ( (FIELD_ITEM(x,y) & CRYSTAL_INDEX_MASK) == item) {
  297.                 match_count++;
  298.             }
  299.             else {
  300.                 if (match_count >= 2) {
  301.                     found = 1;
  302.                     for (i = y+1; i < y+1+match_count+1; i++) {
  303.                         BIT_SET( FIELD_ITEM(x, i), CRYSTAL_EXPLODED_BIT );
  304.                     };
  305.                 }
  306.                 item = FIELD_ITEM(x,y) & CRYSTAL_INDEX_MASK;
  307.                 match_count = 0;
  308.             };
  309.         };
  310.         if (match_count >= 2) { // last
  311.             found = 1;
  312.             for (i = y+1; i < y+1+match_count+1; i++) {
  313.                 BIT_SET( FIELD_ITEM(x, i), CRYSTAL_EXPLODED_BIT );
  314.             };
  315.         };
  316.     };
  317.    
  318.     // horizontal lines
  319.     for (y = 0; y < FIELD_HEIGHT; y++) {
  320.            
  321.         match_count = 0;
  322.         item = 0xFF;
  323.         for (x = FIELD_WIDTH-1; x >= 0; x--) {
  324.  
  325.             if ( IS_BIT_SET( FIELD_ITEM(x,y), CRYSTAL_MOVING_BIT ) || IS_BIT_CLEARED( FIELD_ITEM(x,y), CRYSTAL_VISIBLE_BIT) ) {
  326.                 item = 0xFF;
  327.                 match_count = 0;
  328.                 continue;
  329.             };
  330.  
  331.             if ( (FIELD_ITEM(x,y) & CRYSTAL_INDEX_MASK) == item) {
  332.                 match_count++;
  333.             }
  334.             else {
  335.                 if (match_count >= 2) {
  336.                     found = 1;
  337.                     for (i = x+1; i < x+1+match_count+1; i++) {
  338.                         BIT_SET( FIELD_ITEM(i, y), CRYSTAL_EXPLODED_BIT );
  339.                     };
  340.                 }
  341.                 item = FIELD_ITEM(x,y) & CRYSTAL_INDEX_MASK;
  342.                 match_count = 0;
  343.             };
  344.         };
  345.         if (match_count >= 2) { // last
  346.             found = 1;
  347.             for (i = x+1; i < x+1+match_count+1; i++) {
  348.                 BIT_SET( FIELD_ITEM(i, y), CRYSTAL_EXPLODED_BIT );
  349.             };
  350.         };
  351.     };
  352.  
  353.     for (i = 0; i < FIELD_LENGTH; i++) {
  354.         if (IS_BIT_SET(game.field[i], CRYSTAL_EXPLODED_BIT)) {
  355.             game.field[i] = 0;
  356.             game.score++;
  357.             if (game.explosions_count < EXPLOSIONS_MAX_COUNT-1) {
  358.                 game.explosions[game.explosions_count] = ( i % FIELD_WIDTH ) | ( (i / FIELD_WIDTH) << 8);
  359.                 game.explosions_count++;
  360.             };
  361.         };
  362.     };
  363.    
  364. //    if (game.score > 99) {
  365. //        game.status = STATUS_MENU;
  366. //        game.need_redraw = 1;
  367. //    };
  368.    
  369.     if (found) {
  370.         game.need_redraw = 1;
  371.         soundbuf_play(&game.sound_explosion[ game.sound_index ]);
  372.         game.sound_index = (game.sound_index+1) % SOUND_EXPLOSION_COUNT;
  373.     };
  374.    
  375.     return found;
  376. };
  377.  
  378.  
  379. //void game_check_and_explode_rampage() {
  380. //    
  381. //    
  382. //    
  383. //};
  384.  
  385.  
  386. void game_fall() {
  387.     int x, y, fall;
  388.     for (x = 0; x < FIELD_WIDTH; x++) {
  389.         fall = 0;
  390.         for (y = FIELD_HEIGHT-1; y > 0; y--) {
  391.             fall |= !(FIELD_ITEM(x, y) & CRYSTAL_VISIBLE_BIT);
  392.             if (fall) {
  393.                 FIELD_ITEM(x, y) = FIELD_ITEM(x, y-1) | CRYSTAL_MOVING_BIT;
  394.                 game.need_redraw = 1;
  395.             }
  396.             else {
  397.                 BIT_CLEAR( FIELD_ITEM(x, y), CRYSTAL_MOVING_BIT );
  398.             };
  399.         };
  400.         if ( (fall) || ( IS_BIT_CLEARED(FIELD_ITEM(x,0), CRYSTAL_VISIBLE_BIT) ) ) {
  401.             FIELD_ITEM(x, 0) = get_random_crystal();
  402.         };
  403.     };
  404. };
  405.  
  406.  
  407.  
  408. void GameProcess() {
  409.    
  410.     if (game.status == STATUS_LOADING) {
  411.         game.loader_counter++;
  412.         if (game.loader_counter == 2) {
  413.                
  414.             game_textures_init_stage2();
  415.            
  416.            
  417.             // Sounds...
  418.            
  419.             int soundlen = 40555;
  420.            
  421.             int freqs[SOUND_EXPLOSION_COUNT] = { 440, 523, 587, 698, 783, 880, 1046, 1174 };
  422.            
  423.             int i;
  424.             for (i = 0; i < SOUND_EXPLOSION_COUNT; i++) {
  425.  
  426.                 soundbuf_init(&game.sound_explosion[i], soundlen);
  427.  
  428.  
  429.                 rs_sgen_init(3, soundlen);
  430.  
  431.                 rs_sgen_func_noise(2, 1000);
  432.                 rs_sgen_func_phaser(0, 2, 0.9, 15.2 + 1.0*i/SOUND_EXPLOSION_COUNT, 6.0, 3.0, 2000.0, 1.73);
  433.                 rs_sgen_func_normalize(0, 1.0);
  434.  
  435.  
  436.                 rs_sgen_func_sin(1, freqs[i], 110.3);
  437.                 rs_sgen_func_sin(2, 1.5*freqs[i], 110.2);
  438.  
  439.                 rs_sgen_func_add(0, 0, 1, 1.0, 0.2);
  440.                 rs_sgen_func_add(0, 0, 2, 1.0, 0.2);
  441.  
  442.                 rs_sgen_func_lowpass(2, 0, 1.0, 0.0, 20.0);
  443.                 rs_sgen_func_normalize(2, 1.0);
  444.  
  445.                 rs_sgen_wave_out(2);
  446.  
  447.                 memcpy(game.sound_explosion[i].data, (unsigned char*) rs_sgen_reg.wave_out, soundlen*2);
  448.                 soundbuf_update(&game.sound_explosion[i]);
  449.  
  450.                 rs_sgen_term();
  451.            
  452.             };
  453.            
  454.  
  455.             soundlen = 1024;
  456.            
  457.             soundbuf_init(&game.sound_tick, soundlen);
  458.         //    soundbuf_init(&game.sound_tack, soundlen);
  459.            
  460.             rs_sgen_init(2, soundlen);
  461.             rs_sgen_func_noise(1, 1000);
  462.            
  463.             rs_sgen_func_highpass(0, 1, 0.05, 0.0, 16.0);
  464.             rs_sgen_func_normalize(0, 1.0);
  465.             rs_sgen_wave_out(0);
  466.             memcpy(game.sound_tick.data, (unsigned char*) rs_sgen_reg.wave_out, soundlen*2);
  467.             soundbuf_update(&game.sound_tick);
  468.  
  469.         //    rs_sgen_func_lowpass(0, 1, 0.5, 0.0, 22.0);
  470.         //    rs_sgen_func_normalize(0, 1.0);
  471.         //    rs_sgen_wave_out(0);
  472.         //    memcpy(game.sound_tack.data, (unsigned char*) rs_sgen_reg.wave_out, soundlen*2);
  473.         //    soundbuf_update(&game.sound_tack);
  474.  
  475.             rs_sgen_term();
  476.            
  477.             soundlen = 123000;
  478.            
  479.             soundbuf_init(&game.sound_bang, soundlen);
  480.             rs_sgen_init(2, soundlen);
  481.             rs_sgen_func_pm(1, 220.0, 1.2, 1.0, 880.0*4, 1.0 );
  482.             rs_sgen_func_lowpass(0, 1, 1.0, 0.0, 15.0);
  483.             rs_sgen_func_normalize(0, 1.0);
  484.             rs_sgen_wave_out(0);
  485.             memcpy(game.sound_bang.data, (unsigned char*) rs_sgen_reg.wave_out, soundlen*2);
  486.             soundbuf_update(&game.sound_bang);
  487.            
  488.            
  489.             soundbuf_init(&game.sound_click, 1024);
  490.             soundbuf_sin(&game.sound_click, 0.25);
  491.            
  492.              
  493.             soundbuf_play(&game.sound_bang); // <-- Loaded. Bang!
  494.        
  495.             game.status = STATUS_MENU;
  496.             game.need_redraw = 1;
  497.  
  498.         };
  499.     }
  500.     else if (game.status == STATUS_PLAYING) {
  501.            
  502.         game.process_timer++;
  503.  
  504.         if (game.process_timer > ANIMATION_PROCESS_TIMER_LIMIT) {
  505.             game_check_and_explode();
  506.             game_fall();
  507.             game.process_timer = 0;
  508.         };
  509.        
  510.         int i;
  511.         for (i = 0; i < game.explosions_count; i++) {
  512.             game.need_redraw = 1;
  513.             game.explosions[i] = (game.explosions[i] & 0xFFFF) | ( ((game.explosions[i]>>16)+1) << 16 );
  514.             if ( (game.explosions[i] >> 16) >= EXPLOSION_FRAMES_COUNT ) {
  515.                 game.explosions[i] = game.explosions[game.explosions_count-1];
  516.                 game.explosions_count--;
  517.                 i--;
  518.             };
  519.         };
  520.        
  521.         if ((game.time-1)/25 != game.time/25) {
  522.             game.need_redraw = 1;
  523.            
  524.             if (game.time < 10*25) {
  525.                 soundbuf_play(&game.sound_tick);
  526.             };
  527.            
  528.         };
  529.        
  530.         game.time--;
  531.        
  532.         if (game.time < 1) {
  533.             // Game Over
  534.             game.status = STATUS_MENU;
  535.             game.need_redraw = 1;
  536.             soundbuf_play(&game.sound_bang);
  537.            
  538.             game.menu_replay_timeout = 40;
  539.         };
  540.        
  541.        
  542.  
  543.     }
  544.     else if (game.status == STATUS_MENU) {
  545.        
  546.         if (game.menu_replay_timeout > 0) {
  547.             game.menu_replay_timeout--;
  548.             if (game.menu_replay_timeout == 1) {
  549.                 game.menu_replay_timeout = 0;
  550.                 game.need_redraw = 1;
  551.             };
  552.         };
  553.     };
  554.  
  555.     game_draw();
  556.  
  557. }
  558.  
  559.  
  560.  
  561.  
  562.  
  563. void GameInit() {
  564.  
  565.     game_reg_init();
  566.    
  567.     game.field = malloc( FIELD_LENGTH );
  568.     int i;
  569.     for (i = 0; i < FIELD_LENGTH; i++) {
  570.         game.field[i] = (unsigned char) (0.99 * fabs(rs_noise(i, 10)) * CRYSTALS_COUNT) | CRYSTAL_VISIBLE_BIT;
  571.     };
  572. //    memset( game.field, 0, FIELD_LENGTH );
  573.    
  574.     game.bgr_framebuffer = malloc(GAME_WIDTH * GAME_HEIGHT * 3);
  575.  
  576.     game_font_init();
  577.    
  578.     game_textures_init_stage1();
  579.    
  580.    
  581.  
  582.     #ifndef RS_KOS
  583.         rs_audio_init(RS_AUDIO_FMT_MONO16, RS_AUDIO_FREQ_16000, 0);
  584.     #endif
  585.  
  586.  
  587.    
  588.  
  589.  
  590. };
  591.  
  592.  
  593. void GameTerm() {
  594.  
  595.  
  596.     DEBUG10("--- Game Term ---");
  597.    
  598.     free(game.field);
  599.  
  600.     #ifndef RS_KOS
  601.         rs_audio_term();
  602.     #endif
  603.  
  604.     game_font_term();
  605.    
  606.     game_textures_free();
  607.    
  608.    
  609.     int i;
  610.  
  611.     for (i = 0; i < SOUND_EXPLOSION_COUNT; i++) {
  612.         soundbuf_free(&game.sound_explosion[i]);
  613.     };
  614.    
  615.     soundbuf_free(&game.sound_click);
  616.     soundbuf_free(&game.sound_tick);
  617. //    soundbuf_free(&game.sound_tack);
  618.     soundbuf_free(&game.sound_bang);
  619.    
  620.  
  621. };
  622.  
  623. // ------------ #Event Functions ------------
  624.  
  625.  
  626.  
  627.  
  628.  
  629.  
  630. void GameKeyDown(int key, int first) {
  631.    
  632.     if (key == RS_KEY_A) {
  633.    
  634.         game.need_redraw = 1;
  635.        
  636.     };    
  637.    
  638.     switch (key) {
  639.         case RS_KEY_LEFT:
  640.             BIT_SET(game.keyboard_state, RS_ARROW_LEFT_MASK);
  641.             break;
  642.         case RS_KEY_RIGHT:
  643.             BIT_SET(game.keyboard_state, RS_ARROW_RIGHT_MASK);
  644.             break;
  645.         case RS_KEY_UP:
  646.             BIT_SET(game.keyboard_state, RS_ARROW_UP_MASK);
  647.             break;
  648.         case RS_KEY_DOWN:
  649.             BIT_SET(game.keyboard_state, RS_ARROW_DOWN_MASK);
  650.             break;
  651.         case RS_KEY_A:
  652.             BIT_SET(game.keyboard_state, RS_ATTACK_KEY_MASK);
  653. //            game.shoot_keypressed = 1;
  654.             break;
  655.     };
  656.    
  657.    
  658. //    if (game.status == STATUS_MENU) {
  659. //    
  660. //        switch (key) {
  661. //            case RS_KEY_LEFT:
  662. //                BIT_SET(game.keyboard_state, RS_ARROW_LEFT_MASK);
  663. //                //PlayBuffer(hBuff, 0);
  664. //                break;
  665. //            case RS_KEY_RIGHT:
  666. //                BIT_SET(game.keyboard_state, RS_ARROW_RIGHT_MASK);
  667. //                //StopBuffer(hBuff);
  668. //                break;
  669. //            case RS_KEY_UP:
  670. //                BIT_SET(game.keyboard_state, RS_ARROW_UP_MASK);
  671. //                menu_cursor_up();
  672. //                //ResetBuffer(hBuff, 0);
  673. //                break;
  674. //            case RS_KEY_DOWN:
  675. //                BIT_SET(game.keyboard_state, RS_ARROW_DOWN_MASK);
  676. //                menu_cursor_down();
  677. //                break;
  678. //            case RS_KEY_RETURN:
  679. //                menu_cursor_click();
  680. //                break;
  681. //            case RS_KEY_ESCAPE:
  682. //                menu_open(0);
  683. //                break;
  684. //        };
  685. //
  686. //    };
  687.    
  688.     if (game.status == STATUS_PLAYING) {
  689.        
  690.  
  691.         #ifndef RS_KOS
  692.             if (key == RS_KEY_SPACE) {
  693.                 game.score = 101;
  694.             };
  695.            
  696.         #endif
  697.  
  698.         if (key == RS_KEY_ESCAPE) {
  699.             game.time = 0;
  700.             game.score = 0;
  701.             game.status = STATUS_MENU;
  702.             game.need_redraw = 1;
  703.         };
  704.        
  705.         if (key == RS_KEY_A) {
  706.             soundbuf_play(&game.sound_bang);
  707.         };
  708. //        if (key == RS_KEY_Z) {
  709. //            soundbuf_play(&game.sound_tack);
  710. //        };
  711.        
  712.     };
  713.  
  714. };
  715.  
  716. void GameKeyUp(int key) {
  717.  
  718.     switch (key) {
  719.         case RS_KEY_LEFT:
  720.             BIT_CLEAR(game.keyboard_state, RS_ARROW_LEFT_MASK);
  721.             break;
  722.         case RS_KEY_RIGHT:
  723.             BIT_CLEAR(game.keyboard_state, RS_ARROW_RIGHT_MASK);
  724.             break;
  725.         case RS_KEY_UP:
  726.             BIT_CLEAR(game.keyboard_state, RS_ARROW_UP_MASK);
  727.             break;
  728.         case RS_KEY_DOWN:
  729.             BIT_CLEAR(game.keyboard_state, RS_ARROW_DOWN_MASK);
  730.             break;
  731.         case RS_KEY_A:
  732.             BIT_CLEAR(game.keyboard_state, RS_ATTACK_KEY_MASK);
  733.             break;
  734.     };
  735.  
  736. };
  737.  
  738. typedef struct {
  739.     int a;
  740.     int b;
  741.     unsigned short c;
  742.     unsigned short d;
  743. } cc_t;
  744.  
  745. void GameMouseDown(int x, int y) {
  746.    
  747.     x = (signed short) x;
  748.     y = (signed short) y;
  749.    
  750.     game.need_redraw = 1;
  751.    
  752. //    game.tx = x;
  753. //    game.ty = y;
  754.    
  755.     if (game.status == STATUS_MENU) {
  756.            
  757.         if ( (!game.menu_replay_timeout) && (y > 0) ) {
  758.            
  759.             int i;
  760.             for (i = 0; i < FIELD_LENGTH; i++) {
  761.                 game.field[i] = (unsigned char) (0.99 * fabs(rs_noise(i, seed*7 + 10)) * CRYSTALS_COUNT) | CRYSTAL_VISIBLE_BIT;
  762.             };
  763.            
  764.             game.sound_index = 0;
  765.             game.selected = 0;
  766.             game.time = 25*60 - 1;
  767.             game.score = 0;
  768.             game.status = STATUS_PLAYING;
  769.        
  770.         };
  771.        
  772.         return;
  773.     };
  774.    
  775.     if (game.status == STATUS_PLAYING) {
  776.        
  777.         unsigned int field_x = (unsigned int) (x - FIELD_X0) / CRYSTAL_SIZE;
  778.         if (field_x != rs_clamp_i(field_x, 0, FIELD_WIDTH-1)) {
  779.             return;
  780.         };
  781.        
  782.         unsigned int field_y = (unsigned int) (y - FIELD_Y0) / CRYSTAL_SIZE;
  783.         if (field_y != rs_clamp_i(field_y, 0, FIELD_HEIGHT-1)) {
  784.             return;
  785.         };
  786.        
  787.         //FIELD_ITEM(field_x, field_y) = 0;
  788.        
  789.        
  790. //        if (game.game_mode == GAME_MODE_MATCH3) {
  791.        
  792.        
  793.             if (!game.selected) {
  794.                 game.selected = 1;
  795.                 game.selected_x = field_x;
  796.                 game.selected_y = field_y;                                                                      
  797.                 soundbuf_play(&game.sound_click);
  798.             }
  799.             else {
  800.                
  801.                 if ( abs(game.selected_x - field_x) + abs(game.selected_y - field_y) == 1 ) {
  802.                     game.selected = 0;
  803.                    
  804.                     // Trying to swap
  805.                     int temp_crystal = FIELD_ITEM(field_x, field_y);
  806.                     FIELD_ITEM(field_x, field_y) = FIELD_ITEM(game.selected_x, game.selected_y);
  807.                     FIELD_ITEM(game.selected_x, game.selected_y) = temp_crystal;
  808.                    
  809.                     if ( !game_check_and_explode() ) {
  810.                         FIELD_ITEM(game.selected_x, game.selected_y) = FIELD_ITEM(field_x, field_y);
  811.                         FIELD_ITEM(field_x, field_y) = temp_crystal;
  812.                     }
  813.                     else {
  814.                         // success
  815.                         game.process_timer = 0;
  816.                     };
  817.                    
  818.                 }
  819.                 else {
  820.                     soundbuf_play(&game.sound_click);
  821.                     if ( (game.selected_x != field_x) && (game.selected_y != field_y) ) {
  822.                         game.selected_x = field_x;
  823.                         game.selected_y = field_y;
  824.                     }
  825.                     else {
  826.                         game.selected = 0;
  827.                        
  828.                     };
  829.                 };
  830.                
  831.             };
  832.            
  833. //        } else if (game.mode == GAME_MODE_RAMPAGE) {
  834. //            
  835. //            game.selected = 1;
  836. //            game.selected_x = field_x;
  837. //            game.selected_y = field_y;  
  838. //            
  839. //            game_check_and_explode_rampage();
  840. //            
  841. //        };
  842.        
  843.     };
  844.    
  845. };
  846.  
  847. void GameMouseUp(int x, int y) {
  848.     //
  849. };
  850.  
  851.  
  852. void game_ding(int i) {
  853.    
  854.     switch (i) {
  855.         case 0:
  856. //            soundbuf_play(&game.sound_test2);
  857.             break;
  858.         case 1:
  859. //            soundbuf_play(&game.sound_test3);
  860.             break;
  861.     };
  862.    
  863. };
  864.