Subversion Repositories Kolibri OS

Rev

Rev 5260 | 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.  
  223.     game.loader_counter = 0;
  224.    
  225.     game.menu_replay_timeout = 0;
  226.    
  227.     game.process_timer = 0;
  228.    
  229.     game.hiscore = 0;
  230.    
  231.     game.sound_index = 0;
  232.    
  233.     game.need_redraw = 1;
  234.    
  235.     game.score = 0;
  236.     game.time = 0;
  237.    
  238. //    game.game_mode = GAME_MODE_RAMPAGE;
  239.  
  240.     game.selected = 0;
  241.     game.selected_x = game.selected_y = 0;
  242.    
  243.     game.explosions_count = 0;
  244.    
  245. //    game.tx = 0;
  246. //    game.ty = 0;
  247. //    game.tz = 0;
  248.  
  249. //    int i;
  250. //    for (i = 0; i < BULLETS_COUNT; i++) {
  251. //        game.bullet_x[i] = 0;
  252. //        game.bullet_y[i] = 0;
  253. //    };
  254. //    game.bullet_index = 0;
  255.    
  256.     game.status = STATUS_LOADING;
  257.  
  258. //    game.window_scale = 1;
  259.    
  260. //    game.window_scale = 2;
  261. //    #ifndef RS_KOS
  262. //        game.window_scale = 3;
  263. //        window_scale_str[3] = '3';
  264. //    #endif
  265.    
  266.     game.keyboard_state = 0;
  267.    
  268. //    game.menu_index = 0;
  269. //    game.menu_item_index = 0;
  270. };
  271.  
  272.  
  273. int is_key_pressed(int mask) {
  274.     return IS_BIT_SET(game.keyboard_state, mask) ? 1 : 0;
  275. };
  276.  
  277. int seed = 0;
  278. int get_random_crystal() {
  279.     seed += 2;
  280.     return ( (seed + (get_time() & 0xFFFF) ) % CRYSTALS_COUNT) | CRYSTAL_VISIBLE_BIT;
  281. };
  282.  
  283. int game_check_and_explode() {
  284.     int x, y, i, item, match_count, found;
  285.     found = 0;
  286.    
  287.     // vertical lines
  288.     for (x = 0; x < FIELD_WIDTH; x++) {
  289.         match_count = 0;
  290.         item = 0xFF;
  291.         for (y = FIELD_HEIGHT-1; y >= 0; y--) {
  292.                
  293.             if ( IS_BIT_SET( FIELD_ITEM(x,y), CRYSTAL_MOVING_BIT ) || IS_BIT_CLEARED( FIELD_ITEM(x,y), CRYSTAL_VISIBLE_BIT) ) {
  294.                 item = 0xFF;
  295.                 match_count = 0;
  296.                 continue;
  297.             };
  298.            
  299.             if ( (FIELD_ITEM(x,y) & CRYSTAL_INDEX_MASK) == item) {
  300.                 match_count++;
  301.             }
  302.             else {
  303.                 if (match_count >= 2) {
  304.                     found = 1;
  305.                     for (i = y+1; i < y+1+match_count+1; i++) {
  306.                         BIT_SET( FIELD_ITEM(x, i), CRYSTAL_EXPLODED_BIT );
  307.                     };
  308.                 }
  309.                 item = FIELD_ITEM(x,y) & CRYSTAL_INDEX_MASK;
  310.                 match_count = 0;
  311.             };
  312.         };
  313.         if (match_count >= 2) { // last
  314.             found = 1;
  315.             for (i = y+1; i < y+1+match_count+1; i++) {
  316.                 BIT_SET( FIELD_ITEM(x, i), CRYSTAL_EXPLODED_BIT );
  317.             };
  318.         };
  319.     };
  320.    
  321.     // horizontal lines
  322.     for (y = 0; y < FIELD_HEIGHT; y++) {
  323.            
  324.         match_count = 0;
  325.         item = 0xFF;
  326.         for (x = FIELD_WIDTH-1; x >= 0; x--) {
  327.  
  328.             if ( IS_BIT_SET( FIELD_ITEM(x,y), CRYSTAL_MOVING_BIT ) || IS_BIT_CLEARED( FIELD_ITEM(x,y), CRYSTAL_VISIBLE_BIT) ) {
  329.                 item = 0xFF;
  330.                 match_count = 0;
  331.                 continue;
  332.             };
  333.  
  334.             if ( (FIELD_ITEM(x,y) & CRYSTAL_INDEX_MASK) == item) {
  335.                 match_count++;
  336.             }
  337.             else {
  338.                 if (match_count >= 2) {
  339.                     found = 1;
  340.                     for (i = x+1; i < x+1+match_count+1; i++) {
  341.                         BIT_SET( FIELD_ITEM(i, y), CRYSTAL_EXPLODED_BIT );
  342.                     };
  343.                 }
  344.                 item = FIELD_ITEM(x,y) & CRYSTAL_INDEX_MASK;
  345.                 match_count = 0;
  346.             };
  347.         };
  348.         if (match_count >= 2) { // last
  349.             found = 1;
  350.             for (i = x+1; i < x+1+match_count+1; i++) {
  351.                 BIT_SET( FIELD_ITEM(i, y), CRYSTAL_EXPLODED_BIT );
  352.             };
  353.         };
  354.     };
  355.  
  356.     for (i = 0; i < FIELD_LENGTH; i++) {
  357.         if (IS_BIT_SET(game.field[i], CRYSTAL_EXPLODED_BIT)) {
  358.             game.field[i] = 0;
  359.             game.score++;
  360.             if (game.explosions_count < EXPLOSIONS_MAX_COUNT-1) {
  361.                 game.explosions[game.explosions_count] = ( i % FIELD_WIDTH ) | ( (i / FIELD_WIDTH) << 8);
  362.                 game.explosions_count++;
  363.             };
  364.         };
  365.     };
  366.    
  367. //    if (game.score > 99) {
  368. //        game.status = STATUS_MENU;
  369. //        game.need_redraw = 1;
  370. //    };
  371.    
  372.     if (found) {
  373.         game.need_redraw = 1;
  374.         soundbuf_play(&game.sound_explosion[ game.sound_index ]);
  375.         game.sound_index = (game.sound_index+1) % SOUND_EXPLOSION_COUNT;
  376.     };
  377.    
  378.     return found;
  379. };
  380.  
  381.  
  382. //void game_check_and_explode_rampage() {
  383. //    
  384. //    
  385. //    
  386. //};
  387.  
  388.  
  389. void game_fall() {
  390.     int x, y, fall;
  391.     for (x = 0; x < FIELD_WIDTH; x++) {
  392.         fall = 0;
  393.         for (y = FIELD_HEIGHT-1; y > 0; y--) {
  394.             fall |= !(FIELD_ITEM(x, y) & CRYSTAL_VISIBLE_BIT);
  395.             if (fall) {
  396.                 FIELD_ITEM(x, y) = FIELD_ITEM(x, y-1) | CRYSTAL_MOVING_BIT;
  397.                 game.need_redraw = 1;
  398.             }
  399.             else {
  400.                 BIT_CLEAR( FIELD_ITEM(x, y), CRYSTAL_MOVING_BIT );
  401.             };
  402.         };
  403.         if ( (fall) || ( IS_BIT_CLEARED(FIELD_ITEM(x,0), CRYSTAL_VISIBLE_BIT) ) ) {
  404.             FIELD_ITEM(x, 0) = get_random_crystal();
  405.         };
  406.     };
  407. };
  408.  
  409.  
  410.  
  411. void GameProcess() {
  412.    
  413.     if (game.status == STATUS_LOADING) {
  414.         game.loader_counter++;
  415.         if (game.loader_counter == 2) {
  416.            
  417.             // Hiscore file...
  418.            
  419.             rskos_file_load(HISCORE_FILENAME, (unsigned char*)&game.hiscore, 4);
  420.            
  421.             DEBUG10f("hiscore: %d \n", game.hiscore);
  422.            
  423.             // Textures...
  424.            
  425.             game_textures_init_stage2();
  426.            
  427.            
  428.             // Sounds...
  429.            
  430.             int soundlen = 40555;
  431.            
  432.             int freqs[SOUND_EXPLOSION_COUNT] = { 440, 523, 587, 698, 783, 880, 1046, 1174 };
  433.            
  434.             int i;
  435.             for (i = 0; i < SOUND_EXPLOSION_COUNT; i++) {
  436.  
  437.                 soundbuf_init(&game.sound_explosion[i], soundlen);
  438.  
  439.  
  440.                 rs_sgen_init(3, soundlen);
  441.  
  442.                 rs_sgen_func_noise(2, 1000);
  443.                 rs_sgen_func_phaser(0, 2, 0.9, 15.2 + 1.0*i/SOUND_EXPLOSION_COUNT, 6.0, 3.0, 2000.0, 1.73);
  444.                 rs_sgen_func_normalize(0, 1.0);
  445.  
  446.  
  447.                 rs_sgen_func_sin(1, freqs[i], 110.3);
  448.                 rs_sgen_func_sin(2, 1.5*freqs[i], 110.2);
  449.  
  450.                 rs_sgen_func_add(0, 0, 1, 1.0, 0.2);
  451.                 rs_sgen_func_add(0, 0, 2, 1.0, 0.2);
  452.  
  453.                 rs_sgen_func_lowpass(2, 0, 1.0, 0.0, 20.0);
  454.                 rs_sgen_func_normalize(2, 1.0);
  455.  
  456.                 rs_sgen_wave_out(2);
  457.  
  458.                 memcpy(game.sound_explosion[i].data, (unsigned char*) rs_sgen_reg.wave_out, soundlen*2);
  459.                 soundbuf_update(&game.sound_explosion[i]);
  460.  
  461.                 rs_sgen_term();
  462.            
  463.             };
  464.            
  465.  
  466.             soundlen = 1024;
  467.            
  468.             soundbuf_init(&game.sound_tick, soundlen);
  469.         //    soundbuf_init(&game.sound_tack, soundlen);
  470.            
  471.             rs_sgen_init(2, soundlen);
  472.             rs_sgen_func_noise(1, 1000);
  473.            
  474.             rs_sgen_func_highpass(0, 1, 0.05, 0.0, 16.0);
  475.             rs_sgen_func_normalize(0, 1.0);
  476.             rs_sgen_wave_out(0);
  477.             memcpy(game.sound_tick.data, (unsigned char*) rs_sgen_reg.wave_out, soundlen*2);
  478.             soundbuf_update(&game.sound_tick);
  479.  
  480.         //    rs_sgen_func_lowpass(0, 1, 0.5, 0.0, 22.0);
  481.         //    rs_sgen_func_normalize(0, 1.0);
  482.         //    rs_sgen_wave_out(0);
  483.         //    memcpy(game.sound_tack.data, (unsigned char*) rs_sgen_reg.wave_out, soundlen*2);
  484.         //    soundbuf_update(&game.sound_tack);
  485.  
  486.             rs_sgen_term();
  487.            
  488.             soundlen = 123000;
  489.            
  490.             soundbuf_init(&game.sound_bang, soundlen);
  491.             rs_sgen_init(2, soundlen);
  492.             rs_sgen_func_pm(1, 220.0, 1.2, 1.0, 880.0*4, 1.0 );
  493.             rs_sgen_func_lowpass(0, 1, 1.0, 0.0, 15.0);
  494.             rs_sgen_func_normalize(0, 1.0);
  495.             rs_sgen_wave_out(0);
  496.             memcpy(game.sound_bang.data, (unsigned char*) rs_sgen_reg.wave_out, soundlen*2);
  497.             soundbuf_update(&game.sound_bang);
  498.            
  499.            
  500.             soundbuf_init(&game.sound_click, 1024);
  501.             soundbuf_sin(&game.sound_click, 0.25);
  502.            
  503.              
  504.             soundbuf_play(&game.sound_bang); // <-- Loaded. Bang!
  505.        
  506.             game.status = STATUS_MENU;
  507.             game.need_redraw = 1;
  508.  
  509.         };
  510.     }
  511.     else if (game.status == STATUS_PLAYING) {
  512.            
  513.         game.process_timer++;
  514.  
  515.         if (game.process_timer > ANIMATION_PROCESS_TIMER_LIMIT) {
  516.             game_check_and_explode();
  517.             game_fall();
  518.             game.process_timer = 0;
  519.         };
  520.        
  521.         int i;
  522.         for (i = 0; i < game.explosions_count; i++) {
  523.             game.need_redraw = 1;
  524.             game.explosions[i] = (game.explosions[i] & 0xFFFF) | ( ((game.explosions[i]>>16)+1) << 16 );
  525.             if ( (game.explosions[i] >> 16) >= EXPLOSION_FRAMES_COUNT ) {
  526.                 game.explosions[i] = game.explosions[game.explosions_count-1];
  527.                 game.explosions_count--;
  528.                 i--;
  529.             };
  530.         };
  531.        
  532.         if ((game.time-1)/25 != game.time/25) {
  533.             game.need_redraw = 1;
  534.            
  535.             if (game.time < 10*25) {
  536.                 soundbuf_play(&game.sound_tick);
  537.             };
  538.            
  539.         };
  540.        
  541.         game.time--;
  542.        
  543.         if (game.time < 1) {
  544.             // Game Over
  545.             game.status = STATUS_MENU;
  546.             game.need_redraw = 1;
  547.            
  548.             if (game.score > game.hiscore) {
  549.                 game.hiscore = game.score;
  550.                 rskos_file_save(HISCORE_FILENAME, (unsigned char*)&game.hiscore, 4);
  551.             };
  552.            
  553.             soundbuf_play(&game.sound_bang);
  554.            
  555.             game.menu_replay_timeout = 40;
  556.         };
  557.        
  558.        
  559.  
  560.     }
  561.     else if (game.status == STATUS_MENU) {
  562.        
  563.         if (game.menu_replay_timeout > 0) {
  564.             game.menu_replay_timeout--;
  565.             if (game.menu_replay_timeout == 1) {
  566.                 game.menu_replay_timeout = 0;
  567.                 game.need_redraw = 1;
  568.             };
  569.         };
  570.     };
  571.  
  572.     game_draw();
  573.  
  574. }
  575.  
  576.  
  577.  
  578.  
  579.  
  580. void GameInit() {
  581.  
  582.     game_reg_init();
  583.    
  584.     game.field = malloc( FIELD_LENGTH );
  585.     int i;
  586.     for (i = 0; i < FIELD_LENGTH; i++) {
  587.         game.field[i] = (unsigned char) (0.99 * fabs(rs_noise(i, 10)) * CRYSTALS_COUNT) | CRYSTAL_VISIBLE_BIT;
  588.     };
  589. //    memset( game.field, 0, FIELD_LENGTH );
  590.    
  591.     game.bgr_framebuffer = malloc(GAME_WIDTH * GAME_HEIGHT * 3);
  592.  
  593.     game_font_init();
  594.    
  595.     game_textures_init_stage1();
  596.    
  597.    
  598.  
  599.     #ifndef RS_KOS
  600.         rs_audio_init(RS_AUDIO_FMT_MONO16, RS_AUDIO_FREQ_16000, 0);
  601.     #endif
  602.  
  603.  
  604.    
  605.  
  606.  
  607. };
  608.  
  609.  
  610. void GameTerm() {
  611.  
  612.  
  613.     DEBUG10("--- Game Term ---");
  614.    
  615.     free(game.field);
  616.  
  617.     #ifndef RS_KOS
  618.         rs_audio_term();
  619.     #endif
  620.  
  621.     game_font_term();
  622.    
  623.     game_textures_free();
  624.    
  625.    
  626.     int i;
  627.  
  628.     for (i = 0; i < SOUND_EXPLOSION_COUNT; i++) {
  629.         soundbuf_free(&game.sound_explosion[i]);
  630.     };
  631.    
  632.     soundbuf_free(&game.sound_click);
  633.     soundbuf_free(&game.sound_tick);
  634. //    soundbuf_free(&game.sound_tack);
  635.     soundbuf_free(&game.sound_bang);
  636.    
  637.  
  638. };
  639.  
  640. // ------------ #Event Functions ------------
  641.  
  642.  
  643.  
  644.  
  645.  
  646.  
  647. void GameKeyDown(int key, int first) {
  648.    
  649.  
  650.    
  651.     switch (key) {
  652.         case RS_KEY_LEFT:
  653.             BIT_SET(game.keyboard_state, RS_ARROW_LEFT_MASK);
  654.             break;
  655.         case RS_KEY_RIGHT:
  656.             BIT_SET(game.keyboard_state, RS_ARROW_RIGHT_MASK);
  657.             break;
  658.         case RS_KEY_UP:
  659.             BIT_SET(game.keyboard_state, RS_ARROW_UP_MASK);
  660.             break;
  661.         case RS_KEY_DOWN:
  662.             BIT_SET(game.keyboard_state, RS_ARROW_DOWN_MASK);
  663.             break;
  664.         case RS_KEY_A:
  665.             BIT_SET(game.keyboard_state, RS_ATTACK_KEY_MASK);
  666. //            game.shoot_keypressed = 1;
  667.             break;
  668.     };
  669.    
  670.    
  671. //    if (game.status == STATUS_MENU) {
  672. //    
  673. //        switch (key) {
  674. //            case RS_KEY_LEFT:
  675. //                BIT_SET(game.keyboard_state, RS_ARROW_LEFT_MASK);
  676. //                //PlayBuffer(hBuff, 0);
  677. //                break;
  678. //            case RS_KEY_RIGHT:
  679. //                BIT_SET(game.keyboard_state, RS_ARROW_RIGHT_MASK);
  680. //                //StopBuffer(hBuff);
  681. //                break;
  682. //            case RS_KEY_UP:
  683. //                BIT_SET(game.keyboard_state, RS_ARROW_UP_MASK);
  684. //                menu_cursor_up();
  685. //                //ResetBuffer(hBuff, 0);
  686. //                break;
  687. //            case RS_KEY_DOWN:
  688. //                BIT_SET(game.keyboard_state, RS_ARROW_DOWN_MASK);
  689. //                menu_cursor_down();
  690. //                break;
  691. //            case RS_KEY_RETURN:
  692. //                menu_cursor_click();
  693. //                break;
  694. //            case RS_KEY_ESCAPE:
  695. //                menu_open(0);
  696. //                break;
  697. //        };
  698. //
  699. //    };
  700.    
  701.     if (game.status == STATUS_PLAYING) {
  702.        
  703.         if (key == RS_KEY_ESCAPE) {
  704.             game.time = 0;
  705.             game.score = 0;
  706.             game.status = STATUS_MENU;
  707.             game.need_redraw = 1;
  708.         };
  709.                
  710.     };
  711.  
  712. };
  713.  
  714. void GameKeyUp(int key) {
  715.  
  716.     switch (key) {
  717.         case RS_KEY_LEFT:
  718.             BIT_CLEAR(game.keyboard_state, RS_ARROW_LEFT_MASK);
  719.             break;
  720.         case RS_KEY_RIGHT:
  721.             BIT_CLEAR(game.keyboard_state, RS_ARROW_RIGHT_MASK);
  722.             break;
  723.         case RS_KEY_UP:
  724.             BIT_CLEAR(game.keyboard_state, RS_ARROW_UP_MASK);
  725.             break;
  726.         case RS_KEY_DOWN:
  727.             BIT_CLEAR(game.keyboard_state, RS_ARROW_DOWN_MASK);
  728.             break;
  729.         case RS_KEY_A:
  730.             BIT_CLEAR(game.keyboard_state, RS_ATTACK_KEY_MASK);
  731.             break;
  732.     };
  733.  
  734. };
  735.  
  736. typedef struct {
  737.     int a;
  738.     int b;
  739.     unsigned short c;
  740.     unsigned short d;
  741. } cc_t;
  742.  
  743. void GameMouseDown(int x, int y) {
  744.    
  745.     x = (signed short) x;
  746.     y = (signed short) y;
  747.    
  748.     game.need_redraw = 1;
  749.    
  750. //    game.tx = x;
  751. //    game.ty = y;
  752.    
  753.     if (game.status == STATUS_MENU) {
  754.            
  755.         if ( (!game.menu_replay_timeout) && (y > 0) ) {
  756.            
  757.             int i;
  758.             for (i = 0; i < FIELD_LENGTH; i++) {
  759.                 game.field[i] = (unsigned char) (0.99 * fabs(rs_noise(i, seed*7 + 10)) * CRYSTALS_COUNT) | CRYSTAL_VISIBLE_BIT;
  760.             };
  761.            
  762.             game.sound_index = 0;
  763.             game.selected = 0;
  764.             game.time = 25*60 - 1;
  765.             game.score = 0;
  766.             game.status = STATUS_PLAYING;
  767.        
  768.         };
  769.        
  770.         return;
  771.     };
  772.    
  773.     if (game.status == STATUS_PLAYING) {
  774.        
  775.         unsigned int field_x = (unsigned int) (x - FIELD_X0) / CRYSTAL_SIZE;
  776.         if (field_x != rs_clamp_i(field_x, 0, FIELD_WIDTH-1)) {
  777.             return;
  778.         };
  779.        
  780.         unsigned int field_y = (unsigned int) (y - FIELD_Y0) / CRYSTAL_SIZE;
  781.         if (field_y != rs_clamp_i(field_y, 0, FIELD_HEIGHT-1)) {
  782.             return;
  783.         };
  784.        
  785.         //FIELD_ITEM(field_x, field_y) = 0;
  786.        
  787.        
  788. //        if (game.game_mode == GAME_MODE_MATCH3) {
  789.        
  790.        
  791.             if (!game.selected) {
  792.                 game.selected = 1;
  793.                 game.selected_x = field_x;
  794.                 game.selected_y = field_y;                                                                      
  795.                 soundbuf_play(&game.sound_click);
  796.             }
  797.             else {
  798.                
  799.                 if ( abs(game.selected_x - field_x) + abs(game.selected_y - field_y) == 1 ) {
  800.                     game.selected = 0;
  801.                    
  802.                     // Trying to swap
  803.                     int temp_crystal = FIELD_ITEM(field_x, field_y);
  804.                     FIELD_ITEM(field_x, field_y) = FIELD_ITEM(game.selected_x, game.selected_y);
  805.                     FIELD_ITEM(game.selected_x, game.selected_y) = temp_crystal;
  806.                    
  807.                     if ( !game_check_and_explode() ) {
  808.                         FIELD_ITEM(game.selected_x, game.selected_y) = FIELD_ITEM(field_x, field_y);
  809.                         FIELD_ITEM(field_x, field_y) = temp_crystal;
  810.                     }
  811.                     else {
  812.                         // success
  813.                         game.process_timer = 0;
  814.                     };
  815.                    
  816.                 }
  817.                 else {
  818.                     soundbuf_play(&game.sound_click);
  819.                     if ( (game.selected_x != field_x) && (game.selected_y != field_y) ) {
  820.                         game.selected_x = field_x;
  821.                         game.selected_y = field_y;
  822.                     }
  823.                     else {
  824.                         game.selected = 0;
  825.                        
  826.                     };
  827.                 };
  828.                
  829.             };
  830.            
  831. //        } else if (game.mode == GAME_MODE_RAMPAGE) {
  832. //            
  833. //            game.selected = 1;
  834. //            game.selected_x = field_x;
  835. //            game.selected_y = field_y;  
  836. //            
  837. //            game_check_and_explode_rampage();
  838. //            
  839. //        };
  840.        
  841.     };
  842.    
  843. };
  844.  
  845. void GameMouseUp(int x, int y) {
  846.     //
  847. };
  848.  
  849.  
  850. void game_ding(int i) {
  851.    
  852.     switch (i) {
  853.         case 0:
  854. //            soundbuf_play(&game.sound_test2);
  855.             break;
  856.         case 1:
  857. //            soundbuf_play(&game.sound_test3);
  858.             break;
  859.     };
  860.    
  861. };
  862.