Finally separate platform-specific code from independent

fix-mingw
Nakidai 2023-12-01 22:39:38 +03:00
parent 50c7f9d632
commit eda7badf47
10 changed files with 108 additions and 83 deletions

View File

@ -11,6 +11,7 @@ add_executable(csnake
src/input.c src/input.c
src/player.c src/player.c
src/sleep.c src/sleep.c
src/platform/getch.c
) )
set_target_properties(csnake PROPERTIES C_STANDARD 11) set_target_properties(csnake PROPERTIES C_STANDARD 11)

View File

@ -4,7 +4,7 @@ INCLUDE = -Iinclude
RM = rm -f RM = rm -f
SRCDIR = src SRCDIR = src
OBJDIR = obj OBJDIR = obj
SRC = main.c screen.c input.c player.c sleep.c SRC = main.c screen.c input.c player.c sleep.c platform/getch.c
OBJ = $(addprefix $(OBJDIR)/,$(SRC:.c=.o)) OBJ = $(addprefix $(OBJDIR)/,$(SRC:.c=.o))
DEFLDFLAGS = $(shell if echo "" | cc -E -dM -xc - | grep __FreeBSD__ > /dev/null 2>&1; then echo "-lpthread"; fi) DEFLDFLAGS = $(shell if echo "" | cc -E -dM -xc - | grep __FreeBSD__ > /dev/null 2>&1; then echo "-lpthread"; fi)
@ -14,13 +14,16 @@ all: $(OUT)
obj: obj:
mkdir obj mkdir obj
platform: obj
mkdir obj/platform
$(OBJDIR)/%.o: $(SRCDIR)/%.c $(OBJDIR)/%.o: $(SRCDIR)/%.c
$(CC) -c -o $@ $< $(CFLAGS) $(INCLUDE) $(CC) -c -o $@ $< $(CFLAGS) $(INCLUDE)
$(OUT): obj $(OBJ) $(OUT): obj platform $(OBJ)
$(CC) -o $@ $(OBJ) $(LDFLAGS) $(DEFLDFLAGS) $(CC) -o $@ $(OBJ) $(LDFLAGS) $(DEFLDFLAGS)
clean: clean:
$(RM) $(OUT) $(OBJDIR)/* $(RM) -r $(OUT) $(OBJDIR)/*
.PHONY: default clean .PHONY: default clean

View File

@ -3,16 +3,14 @@
#include <stdbool.h> #include <stdbool.h>
#include "platform/thread.h"
typedef struct input_args_t typedef struct input_args_t
{ {
int *out; int *out;
bool *alive; bool *alive;
} InputArgs; } InputArgs;
#ifdef _WIN32 ThreadR input(void *vargp);
void input(void *vargp);
#else
void *input(void *vargp);
#endif
#endif /* __INPUT_H__ */ #endif /* __INPUT_H__ */

View File

@ -1,37 +0,0 @@
#ifndef __PLATFORM_H__
#define __PLATFORM_H__
#ifdef _WIN32
#include <Windows.h>
#include <process.h>
#else
#include <stdio.h>
#include <pthread.h>
#endif
#ifdef _WIN32
static inline void resetCoordinates(void)
{
HANDLE output = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleCursorPosition(output, (COORD){0});
}
#else
static inline void resetCoordinates(void)
{
printf("\e[1;1H\e[2J");
}
#endif
#ifdef _WIN32
static inline void threadCreate(void (*function)(void *), void *args)
{
_beginthread(function, 0, args);
}
#else
static inline void threadCreate(void *(*function)(void *), void *args)
{
pthread_create(&(pthread_t){0}, 0, function, args);
}
#endif
#endif /* __PLATFORM_H__ */

11
include/platform/getch.h Normal file
View File

@ -0,0 +1,11 @@
#ifndef __GETCH_H__
#define __GETCH_H__
#ifdef _WIN32
#include <conio.h>
#define getch _getch
#else
int getch(void);
#endif /* _WIN32 */
#endif /* __GETCH_H__ */

23
include/platform/screen.h Normal file
View File

@ -0,0 +1,23 @@
#ifndef __PLATFORM_SCREEN_H__
#define __PLATFORM_SCREEN_H__
#ifdef _WIN32
#include <Windows.h>
#else
#include <stdio.h>
#endif /* _WIN32 */
#ifdef _WIN32
static inline void resetCoordinates(void)
{
HANDLE output = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleCursorPosition(output, (COORD){0});
}
#else
static inline void resetCoordinates(void)
{
printf("\e[1;1H\e[2J");
}
#endif /* _WIN32 */
#endif /* __PLATFORM_SCREEN_H__ */

32
include/platform/thread.h Normal file
View File

@ -0,0 +1,32 @@
#ifndef __THREAD_H__
#define __THREAD_H__
#ifdef _WIN32
#include <process.h>
#else
#include <pthread.h>
#include <stddef.h>
#endif /* _WIN32 */
#ifdef _WIN32
typedef void ThreadR;
#define ThreadReturn return
#else
typedef void* ThreadR;
#define ThreadReturn return NULL;
#endif /* _WIN32 */
typedef ThreadR (*Thread)(void *);
#ifdef _WIN32
static inline void threadCreate(Thread function, void *args)
{
_beginthread(function, 0, args);
}
#else
static inline void threadCreate(Thread function, void *args)
{
pthread_create(&(pthread_t){0}, 0, function, args);
}
#endif /* _WIN32 */
#endif /* __THREAD_H__ */

View File

@ -1,40 +1,11 @@
#include "input.h"
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#ifdef _WIN32
#include <conio.h>
#else
#include <unistd.h>
#include <termios.h>
#endif
#ifdef _WIN32 #include "input.h"
#define getch _getch #include "platform/thread.h"
#else #include "platform/getch.h"
static int getch(void)
{
char buf = 0;
struct termios old = { 0 };
fflush(stdout);
if (tcgetattr(0, &old) < 0) perror("tcsetattr()");
old.c_lflag &= ~ICANON; // local modes = Non Canonical mode
old.c_lflag &= ~ECHO; // local modes = Disable echo.
old.c_cc[VMIN] = 1; // control chars (MIN value) = 1
old.c_cc[VTIME] = 0; // control chars (TIME value) = 0 (No time)
if (tcsetattr(0, TCSANOW, &old) < 0) perror("tcsetattr ICANON");
if (read(0, &buf, 1) < 0) perror("read()");
old.c_lflag |= ICANON; // local modes = Canonical mode
old.c_lflag |= ECHO; // local modes = Enable echo.
if (tcsetattr(0, TCSADRAIN, &old) < 0) perror ("tcsetattr ~ICANON");
return (int)buf;
}
#endif
#ifdef _WIN32 ThreadR input(void *vargp)
void input(void *vargp)
#else
void *input(void *vargp)
#endif
{ {
int *out = ((InputArgs *)vargp)->out; int *out = ((InputArgs *)vargp)->out;
bool *alive = ((InputArgs *)vargp)->alive; bool *alive = ((InputArgs *)vargp)->alive;
@ -43,7 +14,5 @@ void *input(void *vargp)
{ {
*out = getch(); *out = getch();
} }
#ifndef _WIN32 ThreadReturn;
return NULL;
#endif
} }

View File

@ -8,8 +8,9 @@
#include "player.h" #include "player.h"
#include "food.h" #include "food.h"
#include "config.h" #include "config.h"
#include "platform.h"
#include "sleep.h" #include "sleep.h"
#include "platform/thread.h"
#include "platform/screen.h"
void drawPlayer(Player *player, Screen *screen) void drawPlayer(Player *player, Screen *screen)
{ {

24
src/platform/getch.c Normal file
View File

@ -0,0 +1,24 @@
#ifndef _WIN32
#include <unistd.h>
#include <termios.h>
#include <stdio.h>
int getch(void)
{
char buf = 0;
struct termios old = { 0 };
fflush(stdout);
if (tcgetattr(0, &old) < 0) perror("tcsetattr()");
old.c_lflag &= ~ICANON; // local modes = Non Canonical mode
old.c_lflag &= ~ECHO; // local modes = Disable echo.
old.c_cc[VMIN] = 1; // control chars (MIN value) = 1
old.c_cc[VTIME] = 0; // control chars (TIME value) = 0 (No time)
if (tcsetattr(0, TCSANOW, &old) < 0) perror("tcsetattr ICANON");
if (read(0, &buf, 1) < 0) perror("read()");
old.c_lflag |= ICANON; // local modes = Canonical mode
old.c_lflag |= ECHO; // local modes = Enable echo.
if (tcsetattr(0, TCSADRAIN, &old) < 0) perror ("tcsetattr ~ICANON");
return (int)buf;
}
#endif /* !_WIN32 */