4444#define BLOCK_SIZE 12
4545#define FIG_NUM 7 // including the active figure
4646
47- #define KEY_REPEAT_RATE 100 // in ms
47+ #define MAX_SOFTDROP_PRESS 300
48+ #define KEY_REPEAT_RATE 130 // in ms
4849#define FONT_SIZE 7
4950#define MUSIC_TRACK_NUM 4
5051#define MUSIC_FADE_TIME 3000
@@ -127,11 +128,15 @@ int screenscale = 1;
127128int startlevel = 0 ;
128129int nextblocks = FIG_NUM - 1 ;
129130enum RandomAlgo randomalgo = RA_7BAG ;
130- bool pause = false, gameover = false, hold_ready = true, fast_drop = false ;
131+ bool pause = false, gameover = false, hold_ready = true;
131132
132- const int drop_delay_per_level [] = {500 , 425 , 360 , 307 , 261 , 222 , 189 , 160 , 136 , 116 };
133133int fps , lines = 0 , hiscore = 0 , old_hiscore , score = 0 , level = 0 ;
134- int next_time ;
134+
135+ double drop_rate = 2.00 ;
136+ const double drop_rate_ratio_per_level = 1.20 ;
137+ Uint32 last_drop_time ;
138+ bool softdrop_pressed = false;
139+ Uint32 softdrop_press_time = 0 ;
135140
136141const struct Shape shape_O =
137142{
@@ -212,6 +217,11 @@ void selectNextTrack(void);
212217void selectPreviousTrack (void );
213218void trackFinished (void );
214219
220+ void markDrop (void );
221+ Uint32 getNextDropTime (void );
222+ void setDropRate (int level );
223+ void softDropTimeCounter (void );
224+
215225void displayBoard (void );
216226void dropSoft (void );
217227void dropHard (void );
@@ -287,18 +297,23 @@ int main(int argc, char *argv[])
287297 }
288298
289299 initialize ();
290- next_time = SDL_GetTicks () + drop_delay_per_level [ level ] ;
300+ markDrop () ;
291301 while (1 )
292302 {
293- handleInput ();
294- displayBoard ();
295- if (!debugfps )
296- frameLimiter ();
297-
298- if (SDL_GetTicks () > next_time )
303+ if (!frameLimiter () || debugfps )
299304 {
300- if (!(pause || gameover ))
301- dropSoft ();
305+ handleInput ();
306+ displayBoard ();
307+ softDropTimeCounter ();
308+
309+ if (SDL_GetTicks () > getNextDropTime ())
310+ {
311+ if (!(pause || gameover ))
312+ {
313+ markDrop ();
314+ dropSoft ();
315+ }
316+ }
302317 }
303318 }
304319 return 0 ;
@@ -457,6 +472,7 @@ void initialize(void)
457472 gameover = false;
458473 lines = 0 ;
459474 level = startlevel ;
475+ setDropRate (level );
460476 initFigures ();
461477}
462478
@@ -522,6 +538,44 @@ void trackFinished(void)
522538 }
523539}
524540
541+ void markDrop (void )
542+ {
543+ last_drop_time = SDL_GetTicks ();
544+ }
545+
546+ Uint32 getNextDropTime (void )
547+ {
548+ const double maxDropRate = FPS ;
549+ double coef = (double )(MAX_SOFTDROP_PRESS - softdrop_press_time ) / MAX_SOFTDROP_PRESS ;
550+ coef = 1 - coef ;
551+ coef *= coef ;
552+ return last_drop_time + (Uint32 )(1000 / (drop_rate * (1 - coef ) + maxDropRate * coef ));
553+ }
554+
555+ void setDropRate (int level )
556+ {
557+ while (level -- )
558+ drop_rate *= drop_rate_ratio_per_level ;
559+ }
560+
561+ void softDropTimeCounter (void )
562+ {
563+ static Uint32 curTicks ;
564+ static Uint32 lastTicks ;
565+ Uint32 delta ;
566+
567+ lastTicks = curTicks ;
568+ curTicks = SDL_GetTicks ();
569+ delta = curTicks - lastTicks ;
570+
571+ if (softdrop_pressed )
572+ {
573+ softdrop_press_time += delta ;
574+ if (softdrop_press_time > MAX_SOFTDROP_PRESS )
575+ softdrop_press_time = MAX_SOFTDROP_PRESS ;
576+ }
577+ }
578+
525579void drawFigure (const struct Figure * fig , int x , int y , bool screendim , bool ghost )
526580{
527581 if (fig != NULL )
@@ -673,7 +727,8 @@ void drawBar(int x, int y, int value)
673727{
674728 const int maxw = 26 ;
675729 const int maxh = 8 ;
676- const int alpha_step = 64 ;
730+ const int alpha_step = 48 ;
731+ const int alpha_start = 32 ;
677732
678733 SDL_Surface * bar = SDL_CreateRGBSurface (SDL_SRCALPHA ,
679734 maxw ,
@@ -688,8 +743,8 @@ void drawBar(int x, int y, int value)
688743 Uint8 alpha_l ;
689744 Uint32 col ;
690745 SDL_Rect rect ;
691- int ar = (value / (maxw + 1 )) * alpha_step ;
692- int al = ar + alpha_step ;
746+ int ar = (value / (maxw + 1 )) * alpha_step + alpha_start ;
747+ int al = ar + alpha_step + alpha_start ;
693748 ar = ar > 255 ? 255 : ar ;
694749 al = al > 255 ? 255 : al ;
695750 alpha_l = (Uint8 )al ;
@@ -772,7 +827,6 @@ void dropSoft(void)
772827 lockFigure ();
773828 free (figures [0 ]);
774829 figures [0 ] = NULL ;
775- fast_drop = false;
776830 }
777831 }
778832
@@ -781,8 +835,6 @@ void dropSoft(void)
781835 if (gameover )
782836 Mix_FadeOutMusic (MUSIC_FADE_TIME );
783837
784-
785- next_time = SDL_GetTicks () + drop_delay_per_level [level ];
786838 screenFlagUpdate (true);
787839}
788840
@@ -815,6 +867,8 @@ void lockFigure(void)
815867 board [y * BOARD_WIDTH + x ] = figures [0 ]-> colorid ;
816868 }
817869
870+ softdrop_pressed = false;
871+ softdrop_press_time = 0 ;
818872 Mix_PlayChannel (-1 , hit , 0 );
819873}
820874
@@ -884,16 +938,20 @@ void checkFullLines(void)
884938 if (score > hiscore )
885939 hiscore = score ;
886940
941+ int oldlevel = level ;
887942 level = startlevel + lines / 30 ;
888- if (level >= sizeof (drop_delay_per_level ) / sizeof (int ))
889- level = sizeof (drop_delay_per_level ) / sizeof (int ) - 1 ;
943+ if (level != oldlevel )
944+ {
945+ drop_rate *= drop_rate_ratio_per_level ;
946+ }
890947}
891948
892949void handleInput (void )
893950{
894951 static bool rotatecw_key_state = false;
895952 static bool rotateccw_key_state = false;
896953 static bool pause_key_state = false;
954+ static bool softdrop_key_state = false;
897955 static bool harddrop_key_state = false;
898956 static bool hold_key_state = false;
899957 static bool left_key_state = false;
@@ -915,6 +973,11 @@ void handleInput(void)
915973 case KEY_PAUSE :
916974 pause_key_state = false;
917975 break ;
976+ case KEY_SOFTDROP :
977+ softdrop_key_state = false;
978+ softdrop_pressed = false;
979+ softdrop_press_time = 0 ;
980+ break ;
918981 case KEY_HARDDROP :
919982 harddrop_key_state = false;
920983 break ;
@@ -995,9 +1058,10 @@ void handleInput(void)
9951058 }
9961059 break ;
9971060 case KEY_SOFTDROP :
998- if (!pause && ! gameover )
1061+ if (!softdrop_key_state )
9991062 {
1000- dropSoft ();
1063+ softdrop_key_state = true;
1064+ softdrop_pressed = true;
10011065 }
10021066 break ;
10031067 case KEY_HARDDROP :
0 commit comments