added WASD control and SPACE working for menu
made the compilation under windows possible.
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# Date:      Thu Jan 29 19:24:20 2026 +0100
#
# On branch master
# Changes to be committed:
#	modified:   Makefile
#	modified:   essential.c
#	modified:   essential.h
#	modified:   fallzone.c
#	modified:   figures.c
#	modified:   fx.c
#	modified:   main.c
#	modified:   menu.c
#
# Untracked files:
#	.static_main
#	.tmpcrontabfile
#
# ------------------------ >8 ------------------------
# Do not modify or remove the line above.
# Everything below it will be ignored.
diff --git a/Makefile b/Makefile
index f0802c2..c676273 100644
--- a/Makefile
+++ b/Makefile
@@ -1,12 +1,30 @@
 SRC = fallzone.c essential.c figures.c cords.c score.c box.c menu.c fx.c
 CC = gcc
 OBJ = $(SRC:.c=.o)
-LIBS= $(shell pkg-config -libs ncurses) -lm
 DEFS = -D_POSIX_C_SOURCE=199506L
-CFLAGS = $(DEFS) -g -Wall -ansi -pedantic -static -Wno-long-long
+CFLAGS = $(DEFS) -g -Wall -ansi -pedantic -Wno-long-long
+ENDFLAGS = $(CFLAGS) -Os -static -s
+LIBS = -lm
+
+
+ifeq ($(OS), Windows_NT)
+
+INCL = -I C:\mingw64\include
+LIBS += C:\mingw64\lib\pdcurses.o
+
+else
+
+LIBS += $(shell pkg-config -libs ncurses)
+
+endif # INCL and LIBS for different OS'es
+
+

 main: main.c $(OBJ)
-	$(CC) $(CFLAGS) $^ $(LIBS) -o $@
+	$(CC) $(CFLAGS) $(INCL) $^ $(LIBS) -o $@
+
+finish: main.c $(OBJ)
+	$(CC) $(ENDFLAGS) $(INCL) $^ $(LIBS) -o tetris

 test: test.c $(OBJ)
 	$(CC) $(CFLAGS) $^ $(LIBS) -o $@
@@ -16,20 +34,29 @@ test: test.c $(OBJ)


 ifneq ($(SRC),)
-
 ifneq (clean, $(MAKECMDGOALS))
 -include deps.mk
 endif

 deps.mk: $(wildcard *.c)
 	@$(CC) -MM $^ > $@
+endif
+

+
+ifeq ($(OS), Windows_NT)
+    RM := del /f /q        # Delete files (/f=force, /q=quiet)
+else
+    RM := rm -f            # Delete files (force)
 endif

+
 clean:
-	@rm -f *.o *.valgrind main deps.mk
+	@$(RM) *.o *.valgrind main deps.mk tetris
 	@clear

+
+ifneq ($(OS), Windows_NT)
 check:
 	valgrind --leak-check=full --track-origins=yes ./main

@@ -42,9 +69,4 @@ gdb:
 	@xterm -T '0' -geometry '48x26+690+10' -e \
 		'tty=`cat /tmp/ttynum.txt`; gdb --tty=$$tty -q --tui -ex "start" \
 	   	./main; pkill -KILL -t `echo "$$tty" | cut -d'/' -f3,4`' &
-
-catch:
-	@xterm -e 'valgrind --leak-check=full --track-origins=yes --show-leak-kinds=all --vgdb-error=1 ./main' &
-	@xterm -e 'sleep 1; gdb -ex "target remote | vgdb" -q ./main'
-
-
+endif
diff --git a/essential.c b/essential.c
index 8743c91..9fb2b4a 100644
--- a/essential.c
+++ b/essential.c
@@ -2,8 +2,13 @@
 #include <stdlib.h>
 #include <string.h>
 #include <ncurses.h>
-#include <sys/time.h>
-#include <unistd.h>
+#if defined(__linux__)
+#   include <unistd.h>      /* sleep() */
+#   include <sys/time.h>    /* gettimeofday() */
+#elif defined(_WIN32)
+#   include <Windows.h>     /* Sleep() */
+#   include <time.h>        /* time() */
+#endif
 #include <math.h>
 #include "essential.h"

@@ -64,7 +69,11 @@ void game_over_and_msg(char *str) {
     len = strlen(str);
     mvprintw(y/2, x/2 - len/2, str);
     refresh();
+#if defined(__linux__)
     sleep(4);
+#elif defined(_WIN32)
+    Sleep(4000);
+#endif
     ncurses_destroy(0, "");
 }

@@ -91,6 +100,8 @@ int time_delay_passed(int delay_ms)
     return retval;
 }

+#if defined(__linux__)
+
 long long time_msec()
 {
     struct timeval tv;
@@ -99,6 +110,24 @@ long long time_msec()
     return (((long long)tv.tv_sec)*1000) + (tv.tv_usec/1000);
 }

+#elif defined(_WIN32)
+
+/* This gives the clock milliseconds in 0..999 */
+static int cur_msec() {
+	SYSTEMTIME	st;
+	SYSTEMTIME	lst;
+
+	GetSystemTime(&st);
+	SystemTimeToTzSpecificLocalTime(NULL, &st, &lst);
+	return lst.wMilliseconds;
+}
+
+long long time_msec() {
+	return (long long)time(NULL) * 1000LL + (long long)cur_msec();
+}
+
+#endif /* OS'es */
+
 double double_mod(double x1, double x2)
 {
     return fmod(x1, x2);
@@ -124,5 +153,3 @@ double sinang(double deg_angle)
 {
     return sin(deg2rad(deg_angle)) ;
 }
-
-
diff --git a/essential.h b/essential.h
index 908db69..ef33dd2 100644
--- a/essential.h
+++ b/essential.h
@@ -4,6 +4,13 @@
   #define M_PI (3.14159265358979323846264338327950288)
 #endif

+#define KEY_SPACE 32
+#define KEY_LOW_A 97
+#define KEY_LOW_D 100
+#define KEY_LOW_S 115
+#define KEY_LOW_W 119
+#define KEY_RETURN 10
+
 #define MIN_WIN_H 10
 #define MIN_WIN_W 20
 #define ARRSIZE(x) (sizeof(x)/(sizeof(x[0])))
diff --git a/fallzone.c b/fallzone.c
index 1fcf8a3..d882027 100644
--- a/fallzone.c
+++ b/fallzone.c
@@ -1,8 +1,11 @@
-#include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <ncurses.h>
-#include <time.h>
+#if defined(__linux__)
+#   include <time.h>    /* nanosleep() */
+#elif defined(_WIN32)
+#   include <Windows.h> /* Sleep() */
+#endif
 #include "fallzone.h"

 extern const enum cols rainbow[6];
@@ -151,6 +154,8 @@ void fallzone_busy_cells_show(fallzone_t *fz)
     attrset(COLOR_PAIR(0));
 }

+#if defined(__linux__)
+
 static void nanosleep_ms_handle(struct timespec *ts, int ms)
 {
     long k_ms_to_ns = 1000000;
@@ -164,32 +169,45 @@ static void nanosleep_ms_handle(struct timespec *ts, int ms)

 }

+#endif /* if linux */
+
 static void fallzone_fx_row_make_of(fallzone_t *fz, int y,
                                     char sym, int color_pair,
                                        int btw_ms, int aft_ms) /* ms<1000 */
 {
     int x;
+#if defined(__linux__)
     struct timespec ts;
+#endif

     if(!fz)
         return;
     if(y < 0)
         ncurses_destroy(2, "fx_row_make_of: wrong y.\n");

-    nanosleep_ms_handle(&ts, btw_ms);
-
     attrset(COLOR_PAIR(color_pair));
     for(x = fz->l_edge; x <= fz->r_edge; x++) {
         mvaddch(y, x, sym);
         refresh();
-        if(btw_ms > 0)
+        if(btw_ms > 0) {
+#if defined(__linux__)
+            nanosleep_ms_handle(&ts, btw_ms);
             nanosleep(&ts, NULL);
+#elif defined(_WIN32)
+            Sleep(btw_ms);
+#endif
+        }
     }
     attrset(0);

-    nanosleep_ms_handle(&ts, aft_ms);
-    if(aft_ms > 0)
+    if(aft_ms > 0) {
+#if defined(__linux__)
+        nanosleep_ms_handle(&ts, aft_ms);
         nanosleep(&ts, NULL);
+#elif defined(_WIN32)
+        Sleep(aft_ms);
+#endif
+    }
 }

 static void fallzone_busy_row_destroy(fallzone_t *fz, int y)
@@ -230,7 +248,9 @@ static void fallzone_fx_busy_rows_destroy(fallzone_t *fz, int *y_arr,
                                                           int    len)
 {
     int o, i;
+#if defined(__linux__)
     struct timespec ts;
+#endif
     if(!y_arr || len < 1)
        return;

@@ -240,8 +260,12 @@ static void fallzone_fx_busy_rows_destroy(fallzone_t *fz, int *y_arr,
     for(i = 0; i < len; i++)
         fallzone_fx_row_make_of(fz, y_arr[i], ' ',
                                 COLS_DEFAULT, 0, 0);
+#if defined(__linux__)
     nanosleep_ms_handle(&ts, 400); /* stop for a bit */
     nanosleep(&ts, NULL);
+#elif defined(_WIN32)
+    Sleep(400);
+#endif

     /* forward rainbow */
     for(o = 0; o < sizeof(rainbow)/sizeof(enum cols); o++)
diff --git a/figures.c b/figures.c
index ca597a1..f3096b7 100644
--- a/figures.c
+++ b/figures.c
@@ -479,12 +479,15 @@ void figure_move(fallzone_t* fz, figure_t *fig, int dir)
         return;

     switch(dir) {
+        case KEY_LOW_A:
         case KEY_LEFT:
             dx--;
             break;
+        case KEY_LOW_D:
         case KEY_RIGHT:
             dx++;
             break;
+        case KEY_LOW_S:
         case KEY_DOWN:
             dy++;
             break;
diff --git a/fx.c b/fx.c
index e0a444b..b5e5d9f 100644
--- a/fx.c
+++ b/fx.c
@@ -1,9 +1,12 @@
 #include <stdio.h>
 #include <stdlib.h>
-#include <unistd.h>
 #include <string.h>
 #include <ncurses.h>
-#include <time.h>
+#if defined(__linux__)
+#   include <time.h> /* nanosleep() */
+#elif defined(_WIN32)
+#   include <Windows.h> /* Sleep() */
+#endif
 #include "fx.h"

 extern const enum cols rainbow[6];
@@ -21,10 +24,14 @@ static void fx_sparkles(int msec, int cnt)
 {
     int i = 0;
     int x, y;
+#if defined(__linux__)
     struct timespec ts = { 0, 0 };
+#endif
     if(msec < 0 || msec > 999 || cnt < 1)
         return;
+#if defined(__linux__)
     ts.tv_nsec = msec * 1000000;
+#endif
     for(i = 0; i < cnt; i++) {
         if(i % 2 == 0)
             attrset(COLOR_PAIR(COLS_YELLOW_BLACK));
@@ -34,7 +41,11 @@ static void fx_sparkles(int msec, int cnt)
         x = random_from_to(1, COLS);
         mvaddch(y, x, '+');
         refresh();
+#if defined(__linux__)
         nanosleep(&ts, NULL);
+#elif defined(_WIN32)
+        Sleep(msec);
+#endif
     }
     attrset(0);
 }
@@ -61,7 +72,9 @@ static void fx_rainbow(int color, int delay)
 {
     int col_cur = 0; /* start idx of rainbow[] */
     int arrsize = ARRSIZE(rainbow);
+#if defined(__linux__)
     struct timespec ts = { 0, 0 };
+#endif
     cords_t max;
     cords_t pos = { 0, 0 };
     cords_t anch = { 0, 0 }; /* anchor */
@@ -69,7 +82,9 @@ static void fx_rainbow(int color, int delay)
         return;
     max.x = COLS-1;
     max.y = LINES-1;
+#if defined(__linux__)
     ts.tv_nsec = delay * 100000;
+#endif

     mvaddch(pos.y, pos.x, ' ');
     for(;;) {
@@ -91,7 +106,11 @@ static void fx_rainbow(int color, int delay)
         for(pos.x=anch.x; pos.y >= 0 && pos.x <= max.x; pos.x++, pos.y--) {
             mvaddch(pos.y, pos.x, ' ');
             refresh();
+#if defined(__linux__)
             nanosleep(&ts, NULL);
+#elif defined(_WIN32)
+            Sleep(delay);
+#endif
         }
     }
     attrset(0);
diff --git a/main.c b/main.c
index 4847b49..8d7b3b0 100644
--- a/main.c
+++ b/main.c
@@ -1,9 +1,6 @@
 #include <ncurses.h>
 #include <stdlib.h>
-#include <unistd.h>
-#include <signal.h>
 #include <time.h>
-#include <math.h>
 #include "essential.h"
 #include "fallzone.h"
 #include "figures.h"
@@ -11,7 +8,6 @@
 #include "menu.h"
 #include "fx.h"

-#define KEY_SPACE 32
 #define GETCH_WAIT_MSEC 50
 #define FIGFALL_DELAY 300

@@ -53,12 +49,16 @@ static int motion_handler(fallzone_t *fz, figure_t *fig, score_box_t *score,
         delay = FIGFALL_DELAY - (score->ln_assembled_cnt * acceleration);

     switch(key) {
+        case KEY_LOW_W:
         case KEY_UP:
             if(!rotate_locked) {
                 figure_rotate(fz, fig);
                 rotate_locked = 1;
             }
             break;
+        case KEY_LOW_A:
+        case KEY_LOW_D:
+        case KEY_LOW_S:
         case KEY_LEFT:
         case KEY_RIGHT:
         case KEY_DOWN:
@@ -115,6 +115,9 @@ void game_init() /* call this to start */

     ncurses_init();
     srand(time(NULL));
+#if defined(_WIN32)
+    (void)rand();
+#endif
     getmaxyx(stdscr, y, x);
     fz_w = x/3;
     fz_h = y * 0.9;
diff --git a/menu.c b/menu.c
index d2a4982..8a8b2c0 100644
--- a/menu.c
+++ b/menu.c
@@ -1,13 +1,11 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#include <unistd.h>
 #include "menu.h"

 #define MAX_ITEM_SCALE_VALUE 3
 #define SCALE_1 1
 #define SCALE_2 2
-#define KEY_RETURN 10

 /* final: the menu should be returned now
  * scale: a value should be picked among 3 proposed conditions */
@@ -169,44 +167,6 @@ static void menu_draw(menu_t *menu, WINDOW *win)
     }
 }

-#if 0
-menu_t *debug_menu_define(WINDOW **win)
-{
-    int outl_h, outl_w;
-    cords_t st, max, st_outl;
-    menu_t *menu = menu_init();
-    WINDOW *derived;
-
-    menu_add_item(menu, choices[0], final);
-    menu_add_item(menu, choices[1], scale);
-    menu_add_item(menu, choices[2], scale);
-    menu_add_item(menu, choices[3], final);
-    menu_center(menu);
-    outl_h = menu->h + 2;
-    outl_w = menu->w + 4;
-    getmaxyx(stdscr, max.y, max.x);
-    st_outl.x = (max.x / 2) - (outl_w / 2);
-    st_outl.y = (max.y / 2) - (outl_h / 2);
-
-    *win = newwin(outl_h, outl_w, st_outl.y, st_outl.x);
-    if(!win)
-        ncurses_destroy(2, "debug: win failed\n");
-
-    derived = derwin(*win, menu->h, menu->w, 1, 2);
-    if(!derived)
-        ncurses_destroy(2, "debug: derived_win failed\n");
-
-    box(*win, ACS_VLINE, ACS_HLINE);
-    keypad(*win, 1);
-
-    menu_draw(menu, derived);
-    wrefresh(*win);
-    sleep(10);
-    return menu;
-
-}
-#endif
-
 menu_t *menu_define(WINDOW **win)
     /* win should be NULL! */
 {
@@ -262,6 +222,7 @@ void menu_run(menu_t *menu, WINDOW *win)
                 if(menu->cur->type == scale)
                     item_scale_handle(menu->cur, key);
                 break;
+            case KEY_SPACE:
             case KEY_RETURN:
                 if(menu->cur->type == final) {
                     menu->cur->retval = 1;
