diff --git a/.gitignore b/.gitignore index ec7ccd24..3673a77c 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ bareiron.exe src/registries.c include/registries.h *.bin +obj diff --git a/README.md b/README.md index 4d3c7f19..cc5b97aa 100644 --- a/README.md +++ b/README.md @@ -19,9 +19,10 @@ Before compiling, you'll need to dump registry data from a vanilla Minecraft ser - To compile on Linux, install `gcc` and run `./build.sh`. - For compiling on Windows, there are a few options: - - To compile a native Windows binary: install [MSYS2](https://www.msys2.org/) and open the "MSYS2 MINGW64" shell. From there, run `pacman -Sy mingw-w64-x86_64-gcc`, navigate to this project's directory, and run `./build.sh`. + - To compile a native Windows binary: install [MSYS2](https://www.msys2.org/) and open the "MSYS2 MINGW64" shell. From there, run `pacman -Sy mingw-w64-x86_64-gcc`, navigate to this project's directory and run `./build.sh`. - To compile a native 32-bit binary (compatible with Windows 95/98, but why would you ever want that), use the same steps above, except with `pacman -Sy mingw-w64-cross-gcc` and `./build.sh --9x`. - To compile a MSYS2-linked binary: install [MSYS2](https://www.msys2.org/), and open the "MSYS2 MSYS" shell. From there, install `gcc` (run `pacman -Sy gcc`), navigate to this project's directory and run `./build.sh`. + - To compile a MSVC-linked binary: install [MS Visual Studio](https://visualstudio.microsoft.com/vs/older-downloads/) (ensure that you have checked `Desktop development with C++`) and [open Developer Command Prompt for VS](https://learn.microsoft.com/en-us/visualstudio/ide/reference/command-prompt-powershell?view=vs-2022). From there, navigate to this project's directory and run `powershell -File .\build.ps1`. - To compile and run a Linux binary from Windows: install WSL, and from there install `gcc` and run `./build.sh` in this project's directory. - To target an ESP variant, set up a PlatformIO project (select the ESP-IDF framework, **not Arduino**) and clone this repository on top of it. See **Configuration** below for further steps. For better performance, consider changing the clock speed and enabling compiler optimizations. If you don't know how to do this, there are plenty of resources online. diff --git a/build.ps1 b/build.ps1 new file mode 100644 index 00000000..40f9bba3 --- /dev/null +++ b/build.ps1 @@ -0,0 +1,11 @@ +if (-not (Test-Path "include\registries.h")) { + Write-Error "Error: 'include\registries.h' is missing." + Write-Host "Please follow the 'Compilation' section of the README to generate it." + exit 1 +} + +if (-not (Test-Path "obj")) { + New-Item -ItemType Directory -Path "obj" | Out-Null +} + +cl src\*.c /I include /Fe: bareiron.exe /Fo: "obj\\" /O2 /link ws2_32.lib \ No newline at end of file diff --git a/include/globals.h b/include/globals.h index 07f1032f..c84b901f 100644 --- a/include/globals.h +++ b/include/globals.h @@ -2,7 +2,9 @@ #define H_GLOBALS #include -#include +#ifndef _MSC_VER + #include +#endif #ifdef ESP_PLATFORM #define WIFI_SSID "your-ssid" @@ -12,6 +14,11 @@ #define task_yield(); #endif +#ifdef _MSC_VER + #include + typedef SSIZE_T ssize_t; +#endif + #define true 1 #define false 0 diff --git a/include/procedures.h b/include/procedures.h index 1dde7933..bedefcfd 100644 --- a/include/procedures.h +++ b/include/procedures.h @@ -1,8 +1,6 @@ #ifndef H_PROCEDURES #define H_PROCEDURES -#include - #include "globals.h" extern int client_states[MAX_PLAYERS * 2]; diff --git a/include/tools.h b/include/tools.h index 4c739911..0d0b3710 100644 --- a/include/tools.h +++ b/include/tools.h @@ -1,8 +1,6 @@ #ifndef H_TOOLS #define H_TOOLS -#include - #include "globals.h" inline int mod_abs (int a, int b) { diff --git a/src/globals.c b/src/globals.c index 731e7fad..1c40f4fc 100644 --- a/src/globals.c +++ b/src/globals.c @@ -6,7 +6,6 @@ #else #include #endif -#include #include "globals.h" diff --git a/src/main.c b/src/main.c index dd065d9e..ac8964c3 100644 --- a/src/main.c +++ b/src/main.c @@ -27,7 +27,6 @@ #include #include #endif - #include #include #endif diff --git a/src/packets.c b/src/packets.c index 5cc1a51e..a8e76103 100644 --- a/src/packets.c +++ b/src/packets.c @@ -12,7 +12,6 @@ #else #include #endif - #include #endif #include "globals.h" diff --git a/src/tools.c b/src/tools.c index fabb6f09..da57b8e7 100644 --- a/src/tools.c +++ b/src/tools.c @@ -14,7 +14,6 @@ #include #include #endif - #include #include #ifndef CLOCK_MONOTONIC #define CLOCK_MONOTONIC 1 @@ -26,6 +25,7 @@ #include "procedures.h" #include "tools.h" +#ifndef _MSC_VER // MSVC cl: error C2375: 'htonll' : redefinition; different linkage #ifndef htonll static uint64_t htonll (uint64_t value) { #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ @@ -36,6 +36,7 @@ #endif } #endif +#endif // Keep track of the total amount of bytes received with recv_all // Helps notice misread packets and clean up after errors @@ -238,6 +239,39 @@ uint64_t splitmix64 (uint64_t state) { return z ^ (z >> 31); } +#ifdef _MSC_VER +// https://stackoverflow.com/questions/5404277/porting-clock-gettime-to-windows/51974214#51974214 +#define MS_PER_SEC 1000ULL // MS = milliseconds +#define US_PER_MS 1000ULL // US = microseconds +#define HNS_PER_US 10ULL // HNS = hundred-nanoseconds (e.g., 1 hns = 100 ns) +#define NS_PER_US 1000ULL + +#define HNS_PER_SEC (MS_PER_SEC * US_PER_MS * HNS_PER_US) +#define NS_PER_HNS (100ULL) // NS = nanoseconds +#define NS_PER_SEC (MS_PER_SEC * US_PER_MS * NS_PER_US) + +int clock_gettime_monotonic(struct timespec *tv) +{ + static LARGE_INTEGER ticksPerSec; + LARGE_INTEGER ticks; + + if (!ticksPerSec.QuadPart) { + QueryPerformanceFrequency(&ticksPerSec); + if (!ticksPerSec.QuadPart) { + errno = ENOTSUP; + return -1; + } + } + + QueryPerformanceCounter(&ticks); + + tv->tv_sec = (long)(ticks.QuadPart / ticksPerSec.QuadPart); + tv->tv_nsec = (long)(((ticks.QuadPart % ticksPerSec.QuadPart) * NS_PER_SEC) / ticksPerSec.QuadPart); + + return 0; +} +#endif + #ifndef ESP_PLATFORM // Returns system time in microseconds. // On ESP-IDF, this is available in "esp_timer.h", and returns time *since @@ -245,7 +279,11 @@ uint64_t splitmix64 (uint64_t state) { // compatibility, this should only be used to measure time intervals. int64_t get_program_time () { struct timespec ts; - clock_gettime(CLOCK_MONOTONIC, &ts); + #ifdef _MSC_VER + clock_gettime_monotonic(&ts); + #else + clock_gettime(CLOCK_MONOTONIC, &ts); + #endif return (int64_t)ts.tv_sec * 1000000LL + ts.tv_nsec / 1000LL; } #endif diff --git a/src/varnum.c b/src/varnum.c index 2a51cde4..8a12536b 100644 --- a/src/varnum.c +++ b/src/varnum.c @@ -5,7 +5,6 @@ #else #include #endif -#include #include "varnum.h" #include "globals.h"