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/player.c
src/sleep.c
src/platform/getch.c
)
set_target_properties(csnake PROPERTIES C_STANDARD 11)

View File

@ -4,7 +4,7 @@ INCLUDE = -Iinclude
RM = rm -f
SRCDIR = src
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))
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:
mkdir obj
platform: obj
mkdir obj/platform
$(OBJDIR)/%.o: $(SRCDIR)/%.c
$(CC) -c -o $@ $< $(CFLAGS) $(INCLUDE)
$(OUT): obj $(OBJ)
$(OUT): obj platform $(OBJ)
$(CC) -o $@ $(OBJ) $(LDFLAGS) $(DEFLDFLAGS)
clean:
$(RM) $(OUT) $(OBJDIR)/*
$(RM) -r $(OUT) $(OBJDIR)/*
.PHONY: default clean

View File

@ -3,16 +3,14 @@
#include <stdbool.h>
#include "platform/thread.h"
typedef struct input_args_t
{
int *out;
bool *alive;
} InputArgs;
#ifdef _WIN32
void input(void *vargp);
#else
void *input(void *vargp);
#endif
ThreadR input(void *vargp);
#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 <stdlib.h>
#ifdef _WIN32
#include <conio.h>
#else
#include <unistd.h>
#include <termios.h>
#endif
#ifdef _WIN32
#define getch _getch
#else
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
#include "input.h"
#include "platform/thread.h"
#include "platform/getch.h"
#ifdef _WIN32
void input(void *vargp)
#else
void *input(void *vargp)
#endif
ThreadR input(void *vargp)
{
int *out = ((InputArgs *)vargp)->out;
bool *alive = ((InputArgs *)vargp)->alive;
@ -43,7 +14,5 @@ void *input(void *vargp)
{
*out = getch();
}
#ifndef _WIN32
return NULL;
#endif
ThreadReturn;
}

View File

@ -8,8 +8,9 @@
#include "player.h"
#include "food.h"
#include "config.h"
#include "platform.h"
#include "sleep.h"
#include "platform/thread.h"
#include "platform/screen.h"
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 */