Subversion Repositories Kolibri OS

Rev

Rev 5239 | Rev 5251 | 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_free(rs_soundbuf_t *snd) {
  152.     snd->status = 0;
  153.     free(snd->data);
  154. };
  155.  
  156. void soundbuf_fill(rs_soundbuf_t *snd, int amp, int freq_div) {
  157.     int i;
  158.     for (i = 0; i < snd->length_samples; i++) {
  159.                 snd->data[i] = -amp/2 + amp/2*( ( (i % freq_div) > freq_div/2 ) ? 1 : 0 );
  160.         };
  161.         rskos_snd_update_buffer(&snd->hbuf, snd->data, snd->length_samples);
  162. };
  163.  
  164. void soundbuf_sin(rs_soundbuf_t *snd, float freq) {
  165.     int i;
  166.     int amp = 29000;
  167.     for (i = 0; i < snd->length_samples; i++) {
  168.                 snd->data[i] = ( 1.0 - 1.0*i/snd->length_samples ) * sin(freq*i) * amp;
  169.         };
  170.         rskos_snd_update_buffer(&snd->hbuf, snd->data, snd->length_samples);
  171. };
  172.  
  173. void soundbuf_sin_fade(rs_soundbuf_t *snd, float freq) {
  174.     int i;
  175.     int amp = 29000;
  176.     for (i = 0; i < snd->length_samples; i++) {
  177.                 snd->data[i] = ( 1.0 - 1.0*i/snd->length_samples ) * sin( ( (1.0 - 0.48*i/snd->length_samples) * freq ) *i) * amp;
  178.         };
  179.        
  180.        
  181.         /*
  182.        
  183.         // ok
  184.        
  185.         rs_sgen_init(2, snd->length_samples);
  186.         rs_sgen_func_pm(1, 880.0, 21.0, 0.3, 110.0, 0.3);
  187.         rs_sgen_func_normalize(1, 1.0);
  188.         rs_sgen_func_lowpass(0, 1, 1.0, 0.0, 1.0);
  189.         rs_sgen_wave_out(0);
  190.        
  191.         memcpy(snd->data, rs_sgen_reg.wave_out, snd->length_samples*2 );
  192.        
  193.         rs_sgen_term();
  194.        
  195.         */
  196.        
  197.         rskos_snd_update_buffer(&snd->hbuf, snd->data, snd->length_samples);
  198. };
  199.  
  200. void soundbuf_play(rs_soundbuf_t *snd) {
  201.     rskos_snd_play(&snd->hbuf, 0);
  202. };
  203.  
  204. void soundbuf_stop(rs_soundbuf_t *snd) {
  205.     rskos_snd_stop(&snd->hbuf);
  206. };
  207.  
  208.  
  209.  
  210. unsigned char clamp_byte(int value) {
  211.     value = value * (1 - (value >> 31)); // negative to zero
  212.     return (value > 255) ? 255 : value;
  213. };
  214.  
  215.  
  216. void game_reg_init() {
  217.    
  218.     game.loader_counter = 0;
  219.    
  220.     game.process_timer = 0;
  221.    
  222.     game.need_redraw = 1;
  223.    
  224.     game.score = 0;
  225.     game.time = 0;
  226.  
  227.     game.selected = 0;
  228.     game.selected_x = game.selected_y = 0;
  229.    
  230.     game.explosions_count = 0;
  231.    
  232.     game.tx = 0;
  233.     game.ty = 0;
  234.     game.tz = 0;
  235.  
  236. //    int i;
  237. //    for (i = 0; i < BULLETS_COUNT; i++) {
  238. //        game.bullet_x[i] = 0;
  239. //        game.bullet_y[i] = 0;
  240. //    };
  241. //    game.bullet_index = 0;
  242.    
  243.     game.status = STATUS_LOADING;
  244.  
  245. //    game.window_scale = 1;
  246.    
  247. //    game.window_scale = 2;
  248. //    #ifndef RS_KOS
  249. //        game.window_scale = 3;
  250. //        window_scale_str[3] = '3';
  251. //    #endif
  252.    
  253.     game.keyboard_state = 0;
  254.    
  255.     game.menu_index = 0;
  256.     game.menu_item_index = 0;
  257. };
  258.  
  259.  
  260. int is_key_pressed(int mask) {
  261.     return IS_BIT_SET(game.keyboard_state, mask) ? 1 : 0;
  262. };
  263.  
  264. int seed = 0;
  265. int get_random_crystal() {
  266.     seed += 2;
  267.     return ( (seed + (get_time() & 0xFFFF) ) % CRYSTALS_COUNT) | CRYSTAL_VISIBLE_BIT;
  268. };
  269.  
  270. int game_check_and_explode() {
  271.     int x, y, i, item, match_count, found;
  272.     found = 0;
  273.    
  274.     // vertical lines
  275.     for (x = 0; x < FIELD_WIDTH; x++) {
  276.         match_count = 0;
  277.         item = 0xFF;
  278.         for (y = FIELD_HEIGHT-1; y >= 0; y--) {
  279.                
  280.             if ( IS_BIT_SET( FIELD_ITEM(x,y), CRYSTAL_MOVING_BIT ) || IS_BIT_CLEARED( FIELD_ITEM(x,y), CRYSTAL_VISIBLE_BIT) ) {
  281.                 item = 0xFF;
  282.                 match_count = 0;
  283.                 continue;
  284.             };
  285.            
  286.             if ( (FIELD_ITEM(x,y) & CRYSTAL_INDEX_MASK) == item) {
  287.                 match_count++;
  288.             }
  289.             else {
  290.                 if (match_count >= 2) {
  291.                     found = 1;
  292.                     for (i = y+1; i < y+1+match_count+1; i++) {
  293.                         BIT_SET( FIELD_ITEM(x, i), CRYSTAL_EXPLODED_BIT );
  294.                     };
  295.                 }
  296.                 item = FIELD_ITEM(x,y) & CRYSTAL_INDEX_MASK;
  297.                 match_count = 0;
  298.             };
  299.         };
  300.         if (match_count >= 2) { // last
  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.     };
  307.    
  308.     // horizontal lines
  309.     for (y = 0; y < FIELD_HEIGHT; y++) {
  310.            
  311.         match_count = 0;
  312.         item = 0xFF;
  313.         for (x = FIELD_WIDTH-1; x >= 0; x--) {
  314.  
  315.             if ( IS_BIT_SET( FIELD_ITEM(x,y), CRYSTAL_MOVING_BIT ) || IS_BIT_CLEARED( FIELD_ITEM(x,y), CRYSTAL_VISIBLE_BIT) ) {
  316.                 item = 0xFF;
  317.                 match_count = 0;
  318.                 continue;
  319.             };
  320.  
  321.             if ( (FIELD_ITEM(x,y) & CRYSTAL_INDEX_MASK) == item) {
  322.                 match_count++;
  323.             }
  324.             else {
  325.                 if (match_count >= 2) {
  326.                     found = 1;
  327.                     for (i = x+1; i < x+1+match_count+1; i++) {
  328.                         BIT_SET( FIELD_ITEM(i, y), CRYSTAL_EXPLODED_BIT );
  329.                     };
  330.                 }
  331.                 item = FIELD_ITEM(x,y) & CRYSTAL_INDEX_MASK;
  332.                 match_count = 0;
  333.             };
  334.         };
  335.         if (match_count >= 2) { // last
  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.     };
  342.  
  343.     for (i = 0; i < FIELD_LENGTH; i++) {
  344.         if (IS_BIT_SET(game.field[i], CRYSTAL_EXPLODED_BIT)) {
  345.             game.field[i] = 0;
  346.             game.score++;
  347.             if (game.explosions_count < EXPLOSIONS_MAX_COUNT-1) {
  348.                 game.explosions[game.explosions_count] = ( i % FIELD_WIDTH ) | ( (i / FIELD_WIDTH) << 8);
  349.                 game.explosions_count++;
  350.             };
  351.         };
  352.     };
  353.    
  354.     if (game.score > 99) {
  355.         game.status = STATUS_MENU;
  356.         game.need_redraw = 1;
  357.     };
  358.    
  359.     if (found) {
  360.         game.need_redraw = 1;
  361.     };
  362.    
  363.     return found;
  364. };
  365.  
  366. void game_fall() {
  367.     int x, y, fall;
  368.     for (x = 0; x < FIELD_WIDTH; x++) {
  369.         fall = 0;
  370.         for (y = FIELD_HEIGHT-1; y > 0; y--) {
  371.             fall |= !(FIELD_ITEM(x, y) & CRYSTAL_VISIBLE_BIT);
  372.             if (fall) {
  373.                 FIELD_ITEM(x, y) = FIELD_ITEM(x, y-1) | CRYSTAL_MOVING_BIT;
  374.                 game.need_redraw = 1;
  375.             }
  376.             else {
  377.                 BIT_CLEAR( FIELD_ITEM(x, y), CRYSTAL_MOVING_BIT );
  378.             };
  379.         };
  380.         if ( (fall) || ( IS_BIT_CLEARED(FIELD_ITEM(x,0), CRYSTAL_VISIBLE_BIT) ) ) {
  381.             FIELD_ITEM(x, 0) = get_random_crystal();
  382.         };
  383.     };
  384. };
  385.  
  386.  
  387.  
  388. void GameProcess() {
  389.    
  390.     if (game.status == STATUS_LOADING) {
  391.         game.loader_counter++;
  392.         if (game.loader_counter == 2) {
  393.                
  394.             game_textures_init_stage2();
  395.                
  396.            
  397.        
  398.             game.status = STATUS_MENU;
  399.             game.need_redraw = 1;
  400.  
  401.         };
  402.     }
  403.     else if (game.status == STATUS_PLAYING) {
  404.            
  405.         game.process_timer++;
  406.  
  407.         if (game.process_timer > ANIMATION_PROCESS_TIMER_LIMIT) {
  408.             game_check_and_explode();
  409.             game_fall();
  410.             game.process_timer = 0;
  411.         };
  412.        
  413.         int i;
  414.         for (i = 0; i < game.explosions_count; i++) {
  415.             game.need_redraw = 1;
  416.             game.explosions[i] = (game.explosions[i] & 0xFFFF) | ( ((game.explosions[i]>>16)+1) << 16 );
  417.             if ( (game.explosions[i] >> 16) >= EXPLOSION_FRAMES_COUNT ) {
  418.                 game.explosions[i] = game.explosions[game.explosions_count-1];
  419.                 game.explosions_count--;
  420.                 i--;
  421.             };
  422.         };
  423.        
  424.         if ((game.time+1)/25 != game.time/25) {
  425.             game.need_redraw = 1;
  426.         };
  427.        
  428.         game.time++;
  429.        
  430.        
  431.        
  432.  
  433.     };
  434.  
  435.     game_draw();
  436.  
  437. }
  438.  
  439.  
  440.  
  441.  
  442.  
  443. void GameInit() {
  444.  
  445.     game_reg_init();
  446.    
  447.     game.field = malloc( FIELD_LENGTH );
  448.     int i;
  449.     for (i = 0; i < FIELD_LENGTH; i++) {
  450.         game.field[i] = (unsigned char) (0.99 * fabs(rs_noise(i, 10)) * CRYSTALS_COUNT) | CRYSTAL_VISIBLE_BIT;
  451.     };
  452. //    memset( game.field, 0, FIELD_LENGTH );
  453.    
  454.     game.bgr_framebuffer = malloc(GAME_WIDTH * GAME_HEIGHT * 3);
  455.  
  456.     game_font_init();
  457.    
  458.     game_textures_init_stage1();
  459.    
  460.    
  461.  
  462.     #ifndef RS_KOS
  463.         rs_audio_init(RS_AUDIO_FMT_MONO16, RS_AUDIO_FREQ_16000, 0);
  464.     #endif
  465.  
  466.     soundbuf_init(&game.sound_test1, 2048);
  467. //    soundbuf_fill(&game.sound_test1, 2, 50);
  468.     soundbuf_sin_fade(&game.sound_test1, 0.7);
  469.  
  470.     soundbuf_init(&game.sound_test2, 1024);
  471.     //soundbuf_fill(&game.sound_test2, 8, 40);
  472.     soundbuf_sin(&game.sound_test2, 0.48);
  473.  
  474.     soundbuf_init(&game.sound_test3, 1024);
  475.     //soundbuf_fill(&game.sound_test3, 12, 60);
  476.     soundbuf_sin(&game.sound_test3, 0.24);
  477.  
  478.  
  479. };
  480.  
  481.  
  482. void GameTerm() {
  483.  
  484.  
  485.     DEBUG10("--- Game Term ---");
  486.    
  487.     free(game.field);
  488.  
  489.     #ifndef RS_KOS
  490.         rs_audio_term();
  491.     #endif
  492.  
  493.     game_font_term();
  494.    
  495.     game_textures_free();
  496.    
  497.    
  498.    
  499.  
  500.    
  501.     soundbuf_free(&game.sound_test1);
  502.     soundbuf_free(&game.sound_test2);
  503.     soundbuf_free(&game.sound_test3);
  504.    
  505.  
  506. };
  507.  
  508. // ------------ #Event Functions ------------
  509.  
  510.  
  511.  
  512.  
  513.  
  514.  
  515. void GameKeyDown(int key, int first) {
  516.    
  517.     if (key == RS_KEY_A) {
  518.    
  519.         game.need_redraw = 1;
  520.        
  521.     };    
  522.    
  523.     switch (key) {
  524.         case RS_KEY_LEFT:
  525.             BIT_SET(game.keyboard_state, RS_ARROW_LEFT_MASK);
  526.             break;
  527.         case RS_KEY_RIGHT:
  528.             BIT_SET(game.keyboard_state, RS_ARROW_RIGHT_MASK);
  529.             break;
  530.         case RS_KEY_UP:
  531.             BIT_SET(game.keyboard_state, RS_ARROW_UP_MASK);
  532.             break;
  533.         case RS_KEY_DOWN:
  534.             BIT_SET(game.keyboard_state, RS_ARROW_DOWN_MASK);
  535.             break;
  536.         case RS_KEY_A:
  537.             BIT_SET(game.keyboard_state, RS_ATTACK_KEY_MASK);
  538. //            game.shoot_keypressed = 1;
  539.             break;
  540.     };
  541.    
  542.    
  543.     if (game.status == STATUS_MENU) {
  544.    
  545.         switch (key) {
  546.             case RS_KEY_LEFT:
  547.                 BIT_SET(game.keyboard_state, RS_ARROW_LEFT_MASK);
  548.                 //PlayBuffer(hBuff, 0);
  549.                 break;
  550.             case RS_KEY_RIGHT:
  551.                 BIT_SET(game.keyboard_state, RS_ARROW_RIGHT_MASK);
  552.                 //StopBuffer(hBuff);
  553.                 break;
  554.             case RS_KEY_UP:
  555.                 BIT_SET(game.keyboard_state, RS_ARROW_UP_MASK);
  556.                 menu_cursor_up();
  557.                 //ResetBuffer(hBuff, 0);
  558.                 break;
  559.             case RS_KEY_DOWN:
  560.                 BIT_SET(game.keyboard_state, RS_ARROW_DOWN_MASK);
  561.                 menu_cursor_down();
  562.                 break;
  563.             case RS_KEY_RETURN:
  564.                 menu_cursor_click();
  565.                 break;
  566.             case RS_KEY_ESCAPE:
  567.                 menu_open(0);
  568.                 break;
  569.         };
  570.  
  571.     };
  572.    
  573.     if (game.status == STATUS_PLAYING) {
  574.        
  575.  
  576.         #ifndef RS_KOS
  577.             if (key == RS_KEY_SPACE) {
  578.                 game.score = 101;
  579.             };
  580.         #endif
  581.  
  582.         if (key == RS_KEY_ESCAPE) {
  583.             game.time = 0;
  584.             game.score = 0;
  585.             game.status = STATUS_MENU;
  586.             game.need_redraw = 1;
  587.         };
  588.        
  589.     };
  590.  
  591. };
  592.  
  593. void GameKeyUp(int key) {
  594.  
  595.     switch (key) {
  596.         case RS_KEY_LEFT:
  597.             BIT_CLEAR(game.keyboard_state, RS_ARROW_LEFT_MASK);
  598.             break;
  599.         case RS_KEY_RIGHT:
  600.             BIT_CLEAR(game.keyboard_state, RS_ARROW_RIGHT_MASK);
  601.             break;
  602.         case RS_KEY_UP:
  603.             BIT_CLEAR(game.keyboard_state, RS_ARROW_UP_MASK);
  604.             break;
  605.         case RS_KEY_DOWN:
  606.             BIT_CLEAR(game.keyboard_state, RS_ARROW_DOWN_MASK);
  607.             break;
  608.         case RS_KEY_A:
  609.             BIT_CLEAR(game.keyboard_state, RS_ATTACK_KEY_MASK);
  610.             break;
  611.     };
  612.  
  613. };
  614.  
  615. typedef struct {
  616.     int a;
  617.     int b;
  618.     unsigned short c;
  619.     unsigned short d;
  620. } cc_t;
  621.  
  622. void GameMouseDown(int x, int y) {
  623.    
  624.    
  625.     game.need_redraw = 1;
  626.    
  627.     game.tx = x;
  628.     game.ty = y;
  629.    
  630.     if (game.status == STATUS_MENU) {
  631.            
  632.         int i;
  633.         for (i = 0; i < FIELD_LENGTH; i++) {
  634.             game.field[i] = (unsigned char) (0.99 * fabs(rs_noise(i, seed*7 + 10)) * CRYSTALS_COUNT) | CRYSTAL_VISIBLE_BIT;
  635.         };
  636.        
  637.         game.selected = 0;
  638.         game.time = 0;
  639.         game.score = 0;
  640.         game.status = STATUS_PLAYING;
  641.         return;
  642.     };
  643.    
  644.     if (game.status == STATUS_PLAYING) {
  645.        
  646.         unsigned int field_x = (unsigned int) (x - FIELD_X0) / CRYSTAL_SIZE;
  647.         if (field_x != rs_clamp_i(field_x, 0, FIELD_WIDTH-1)) {
  648.             return;
  649.         };
  650.        
  651.         unsigned int field_y = (unsigned int) (y - FIELD_Y0) / CRYSTAL_SIZE;
  652.         if (field_y != rs_clamp_i(field_y, 0, FIELD_HEIGHT-1)) {
  653.             return;
  654.         };
  655.        
  656.         //FIELD_ITEM(field_x, field_y) = 0;
  657.        
  658.         if (!game.selected) {
  659.             game.selected = 1;
  660.             game.selected_x = field_x;
  661.             game.selected_y = field_y;                                                                      
  662.            
  663.         }
  664.         else {
  665.            
  666.             if ( abs(game.selected_x - field_x) + abs(game.selected_y - field_y) == 1 ) {
  667.                 game.selected = 0;
  668.                
  669.                 // Trying to swap
  670.                 int temp_crystal = FIELD_ITEM(field_x, field_y);
  671.                 FIELD_ITEM(field_x, field_y) = FIELD_ITEM(game.selected_x, game.selected_y);
  672.                 FIELD_ITEM(game.selected_x, game.selected_y) = temp_crystal;
  673.                
  674.                 if ( !game_check_and_explode() ) {
  675.                     FIELD_ITEM(game.selected_x, game.selected_y) = FIELD_ITEM(field_x, field_y);
  676.                     FIELD_ITEM(field_x, field_y) = temp_crystal;
  677.                 }
  678.                 else {
  679.                     // success
  680.                     game.process_timer = 0;
  681.                 };
  682.                
  683.             }
  684.             else {
  685.                 if ( (game.selected_x != field_x) && (game.selected_y != field_y) ) {
  686.                     game.selected_x = field_x;
  687.                     game.selected_y = field_y;
  688.                 }
  689.                 else {
  690.                     game.selected = 0;
  691.                 };
  692.             };
  693.            
  694.         };
  695.        
  696. //        int i;
  697. //        for (i = field_y; i > 0; i--) {
  698. //            FIELD_ITEM(field_x, i) = FIELD_ITEM(field_x, (i-1) );
  699. //        };
  700. //        FIELD_ITEM(field_x, 0) = 0;
  701.        
  702.     };
  703.    
  704. };
  705.  
  706. void GameMouseUp(int x, int y) {
  707.     //
  708. };
  709.  
  710.  
  711. void game_ding(int i) {
  712.    
  713.     switch (i) {
  714.         case 0:
  715.             soundbuf_play(&game.sound_test2);
  716.             break;
  717.         case 1:
  718.             soundbuf_play(&game.sound_test3);
  719.             break;
  720.     };
  721.    
  722. };
  723.