mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-09-19 04:26:52 -04:00
Fix texture packs without content length header not decoding, on windows.
This commit is contained in:
parent
10e0a4ea2e
commit
348ca90306
@ -21,6 +21,7 @@ struct AsyncRequest {
|
|||||||
|
|
||||||
TimeMS TimeAdded, TimeDownloaded;
|
TimeMS TimeAdded, TimeDownloaded;
|
||||||
int StatusCode;
|
int StatusCode;
|
||||||
|
uint32_t ContentLength;
|
||||||
|
|
||||||
ReturnCode Result;
|
ReturnCode Result;
|
||||||
void* ResultData;
|
void* ResultData;
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
#include "ErrorHandler.h"
|
#include "ErrorHandler.h"
|
||||||
#include "Stream.h"
|
#include "Stream.h"
|
||||||
#include "Errors.h"
|
#include "Errors.h"
|
||||||
|
#include "Utils.h"
|
||||||
|
|
||||||
BitmapCol BitmapCol_Scale(BitmapCol value, float t) {
|
BitmapCol BitmapCol_Scale(BitmapCol value, float t) {
|
||||||
value.R = (uint8_t)(value.R * t);
|
value.R = (uint8_t)(value.R * t);
|
||||||
|
@ -307,8 +307,7 @@ STRING_REF String Block_UNSAFE_GetName(BlockID block) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Block_SetName(BlockID block, const String* name) {
|
void Block_SetName(BlockID block, const String* name) {
|
||||||
String dst = { Block_NamePtr(block), 0, STRING_SIZE };
|
String dst = String_InitAndClear(Block_NamePtr(block), STRING_SIZE);
|
||||||
Mem_Set(dst.buffer, 0, STRING_SIZE);
|
|
||||||
String_AppendString(&dst, name);
|
String_AppendString(&dst, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,7 +45,7 @@ static char Chat_LogPathBuffer[FILENAME_SIZE];
|
|||||||
static String Chat_LogPath = String_FromArray(Chat_LogPathBuffer);
|
static String Chat_LogPath = String_FromArray(Chat_LogPathBuffer);
|
||||||
|
|
||||||
static struct Stream Chat_LogStream;
|
static struct Stream Chat_LogStream;
|
||||||
static DateTime ChatLog_LastLogDate;
|
static struct DateTime ChatLog_LastLogDate;
|
||||||
|
|
||||||
static void Chat_CloseLog(void) {
|
static void Chat_CloseLog(void) {
|
||||||
ReturnCode res;
|
ReturnCode res;
|
||||||
@ -82,7 +82,7 @@ static void Chat_DisableLogging(void) {
|
|||||||
Chat_AddRaw("&cDisabling chat logging");
|
Chat_AddRaw("&cDisabling chat logging");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Chat_OpenLog(DateTime* now) {
|
static void Chat_OpenLog(struct DateTime* now) {
|
||||||
void* file;
|
void* file;
|
||||||
int i;
|
int i;
|
||||||
ReturnCode res;
|
ReturnCode res;
|
||||||
@ -119,7 +119,7 @@ static void Chat_OpenLog(DateTime* now) {
|
|||||||
|
|
||||||
static void Chat_AppendLog(const String* text) {
|
static void Chat_AppendLog(const String* text) {
|
||||||
String str; char strBuffer[STRING_SIZE * 2];
|
String str; char strBuffer[STRING_SIZE * 2];
|
||||||
DateTime now;
|
struct DateTime now;
|
||||||
ReturnCode res;
|
ReturnCode res;
|
||||||
|
|
||||||
if (!Chat_LogName.length || !Game_ChatLogging) return;
|
if (!Chat_LogName.length || !Game_ChatLogging) return;
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
#include "Platform.h"
|
#include "Platform.h"
|
||||||
#include "Stream.h"
|
#include "Stream.h"
|
||||||
#include "Errors.h"
|
#include "Errors.h"
|
||||||
|
#include "Utils.h"
|
||||||
|
|
||||||
#define Header_ReadU8(value) if ((res = s->ReadU8(s, &value))) return res;
|
#define Header_ReadU8(value) if ((res = s->ReadU8(s, &value))) return res;
|
||||||
/*########################################################################################################################*
|
/*########################################################################################################################*
|
||||||
|
@ -645,7 +645,7 @@ static void Game_DoScheduledTasks(double time) {
|
|||||||
void Game_TakeScreenshot(void) {
|
void Game_TakeScreenshot(void) {
|
||||||
String filename; char fileBuffer[STRING_SIZE];
|
String filename; char fileBuffer[STRING_SIZE];
|
||||||
String path; char pathBuffer[FILENAME_SIZE];
|
String path; char pathBuffer[FILENAME_SIZE];
|
||||||
DateTime now;
|
struct DateTime now;
|
||||||
struct Stream stream;
|
struct Stream stream;
|
||||||
ReturnCode res;
|
ReturnCode res;
|
||||||
|
|
||||||
|
@ -3259,7 +3259,7 @@ static void TexPackOverlay_Render(void* screen, double delta) {
|
|||||||
MenuScreen_Render(s, delta);
|
MenuScreen_Render(s, delta);
|
||||||
if (!AsyncDownloader_Get(&s->Identifier, &item)) return;
|
if (!AsyncDownloader_Get(&s->Identifier, &item)) return;
|
||||||
|
|
||||||
s->ContentLength = item.ResultSize;
|
s->ContentLength = item.ContentLength;
|
||||||
if (!s->ContentLength) return;
|
if (!s->ContentLength) return;
|
||||||
Elem_Recreate(s);
|
Elem_Recreate(s);
|
||||||
}
|
}
|
||||||
|
138
src/Platform.c
138
src/Platform.c
@ -258,7 +258,7 @@ TimeMS DateTime_CurrentUTC_MS(void) {
|
|||||||
return FileTime_TotalMS(raw);
|
return FileTime_TotalMS(raw);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Platform_FromSysTime(DateTime* time, SYSTEMTIME* sysTime) {
|
static void Platform_FromSysTime(struct DateTime* time, SYSTEMTIME* sysTime) {
|
||||||
time->Year = sysTime->wYear;
|
time->Year = sysTime->wYear;
|
||||||
time->Month = sysTime->wMonth;
|
time->Month = sysTime->wMonth;
|
||||||
time->Day = sysTime->wDay;
|
time->Day = sysTime->wDay;
|
||||||
@ -268,13 +268,13 @@ static void Platform_FromSysTime(DateTime* time, SYSTEMTIME* sysTime) {
|
|||||||
time->Milli = sysTime->wMilliseconds;
|
time->Milli = sysTime->wMilliseconds;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DateTime_CurrentUTC(DateTime* time) {
|
void DateTime_CurrentUTC(struct DateTime* time) {
|
||||||
SYSTEMTIME utcTime;
|
SYSTEMTIME utcTime;
|
||||||
GetSystemTime(&utcTime);
|
GetSystemTime(&utcTime);
|
||||||
Platform_FromSysTime(time, &utcTime);
|
Platform_FromSysTime(time, &utcTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DateTime_CurrentLocal(DateTime* time) {
|
void DateTime_CurrentLocal(struct DateTime* time) {
|
||||||
SYSTEMTIME localTime;
|
SYSTEMTIME localTime;
|
||||||
GetLocalTime(&localTime);
|
GetLocalTime(&localTime);
|
||||||
Platform_FromSysTime(time, &localTime);
|
Platform_FromSysTime(time, &localTime);
|
||||||
@ -308,7 +308,7 @@ TimeMS DateTime_CurrentUTC_MS(void) {
|
|||||||
return UnixTime_TotalMS(cur);
|
return UnixTime_TotalMS(cur);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Platform_FromSysTime(DateTime* time, struct tm* sysTime) {
|
static void Platform_FromSysTime(struct DateTime* time, struct tm* sysTime) {
|
||||||
time->Year = sysTime->tm_year + 1900;
|
time->Year = sysTime->tm_year + 1900;
|
||||||
time->Month = sysTime->tm_mon + 1;
|
time->Month = sysTime->tm_mon + 1;
|
||||||
time->Day = sysTime->tm_mday;
|
time->Day = sysTime->tm_mday;
|
||||||
@ -317,7 +317,7 @@ static void Platform_FromSysTime(DateTime* time, struct tm* sysTime) {
|
|||||||
time->Second = sysTime->tm_sec;
|
time->Second = sysTime->tm_sec;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DateTime_CurrentUTC(DateTime* time_) {
|
void DateTime_CurrentUTC(struct DateTime* time_) {
|
||||||
struct timeval cur;
|
struct timeval cur;
|
||||||
struct tm utc_time;
|
struct tm utc_time;
|
||||||
|
|
||||||
@ -328,7 +328,7 @@ void DateTime_CurrentUTC(DateTime* time_) {
|
|||||||
time_->Milli = cur.tv_usec / 1000;
|
time_->Milli = cur.tv_usec / 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DateTime_CurrentLocal(DateTime* time_) {
|
void DateTime_CurrentLocal(struct DateTime* time_) {
|
||||||
struct timeval cur;
|
struct timeval cur;
|
||||||
struct tm loc_time;
|
struct tm loc_time;
|
||||||
|
|
||||||
@ -451,51 +451,51 @@ ReturnCode File_GetModifiedTime_MS(const String* path, TimeMS* time) {
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnCode File_Do(void** file, const String* path, DWORD access, DWORD createMode) {
|
static ReturnCode File_Do(FileHandle* file, const String* path, DWORD access, DWORD createMode) {
|
||||||
TCHAR str[300];
|
TCHAR str[300];
|
||||||
Platform_ConvertString(str, path);
|
Platform_ConvertString(str, path);
|
||||||
*file = CreateFile(str, access, FILE_SHARE_READ, NULL, createMode, 0, NULL);
|
*file = CreateFile(str, access, FILE_SHARE_READ, NULL, createMode, 0, NULL);
|
||||||
return Win_Return(*file != INVALID_HANDLE_VALUE);
|
return Win_Return(*file != INVALID_HANDLE_VALUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnCode File_Open(void** file, const String* path) {
|
ReturnCode File_Open(FileHandle* file, const String* path) {
|
||||||
return File_Do(file, path, GENERIC_READ, OPEN_EXISTING);
|
return File_Do(file, path, GENERIC_READ, OPEN_EXISTING);
|
||||||
}
|
}
|
||||||
ReturnCode File_Create(void** file, const String* path) {
|
ReturnCode File_Create(FileHandle* file, const String* path) {
|
||||||
return File_Do(file, path, GENERIC_WRITE, CREATE_ALWAYS);
|
return File_Do(file, path, GENERIC_WRITE, CREATE_ALWAYS);
|
||||||
}
|
}
|
||||||
ReturnCode File_Append(void** file, const String* path) {
|
ReturnCode File_Append(FileHandle* file, const String* path) {
|
||||||
ReturnCode res = File_Do(file, path, GENERIC_WRITE, OPEN_ALWAYS);
|
ReturnCode res = File_Do(file, path, GENERIC_WRITE, OPEN_ALWAYS);
|
||||||
if (res) return res;
|
if (res) return res;
|
||||||
return File_Seek(*file, 0, FILE_SEEKFROM_END);
|
return File_Seek(*file, 0, FILE_SEEKFROM_END);
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnCode File_Read(void* file, uint8_t* buffer, uint32_t count, uint32_t* bytesRead) {
|
ReturnCode File_Read(FileHandle file, uint8_t* buffer, uint32_t count, uint32_t* bytesRead) {
|
||||||
BOOL success = ReadFile((HANDLE)file, buffer, count, bytesRead, NULL);
|
BOOL success = ReadFile(file, buffer, count, bytesRead, NULL);
|
||||||
return Win_Return(success);
|
return Win_Return(success);
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnCode File_Write(void* file, uint8_t* buffer, uint32_t count, uint32_t* bytesWrote) {
|
ReturnCode File_Write(FileHandle file, uint8_t* buffer, uint32_t count, uint32_t* bytesWrote) {
|
||||||
BOOL success = WriteFile((HANDLE)file, buffer, count, bytesWrote, NULL);
|
BOOL success = WriteFile(file, buffer, count, bytesWrote, NULL);
|
||||||
return Win_Return(success);
|
return Win_Return(success);
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnCode File_Close(void* file) {
|
ReturnCode File_Close(FileHandle file) {
|
||||||
return Win_Return(CloseHandle((HANDLE)file));
|
return Win_Return(CloseHandle(file));
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnCode File_Seek(void* file, int offset, int seekType) {
|
ReturnCode File_Seek(FileHandle file, int offset, int seekType) {
|
||||||
static uint8_t modes[3] = { FILE_BEGIN, FILE_CURRENT, FILE_END };
|
static uint8_t modes[3] = { FILE_BEGIN, FILE_CURRENT, FILE_END };
|
||||||
DWORD pos = SetFilePointer(file, offset, NULL, modes[seekType]);
|
DWORD pos = SetFilePointer(file, offset, NULL, modes[seekType]);
|
||||||
return Win_Return(pos != INVALID_SET_FILE_POINTER);
|
return Win_Return(pos != INVALID_SET_FILE_POINTER);
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnCode File_Position(void* file, uint32_t* position) {
|
ReturnCode File_Position(FileHandle file, uint32_t* position) {
|
||||||
*position = SetFilePointer(file, 0, NULL, 1); /* SEEK_CUR */
|
*position = SetFilePointer(file, 0, NULL, FILE_CURRENT);
|
||||||
return Win_Return(*position != INVALID_SET_FILE_POINTER);
|
return Win_Return(*position != INVALID_SET_FILE_POINTER);
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnCode File_Length(void* file, uint32_t* length) {
|
ReturnCode File_Length(FileHandle file, uint32_t* length) {
|
||||||
*length = GetFileSize(file, NULL);
|
*length = GetFileSize(file, NULL);
|
||||||
return Win_Return(*length != INVALID_FILE_SIZE);
|
return Win_Return(*length != INVALID_FILE_SIZE);
|
||||||
}
|
}
|
||||||
@ -577,52 +577,52 @@ ReturnCode File_GetModifiedTime_MS(const String* path, TimeMS* time) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnCode File_Do(void** file, const String* path, int mode) {
|
static ReturnCode File_Do(FileHandle* file, const String* path, int mode) {
|
||||||
char str[600];
|
char str[600];
|
||||||
Platform_ConvertString(str, path);
|
Platform_ConvertString(str, path);
|
||||||
*file = open(str, mode, (6 << 6) | (4 << 3) | 4); /* rw|r|r */
|
*file = open(str, mode, (6 << 6) | (4 << 3) | 4); /* rw|r|r */
|
||||||
return Nix_Return(*file != -1);
|
return Nix_Return(*file != -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnCode File_Open(void** file, const String* path) {
|
ReturnCode File_Open(FileHandle* file, const String* path) {
|
||||||
return File_Do(file, path, O_RDONLY);
|
return File_Do(file, path, O_RDONLY);
|
||||||
}
|
}
|
||||||
ReturnCode File_Create(void** file, const String* path) {
|
ReturnCode File_Create(FileHandle* file, const String* path) {
|
||||||
return File_Do(file, path, O_WRONLY | O_CREAT | O_TRUNC);
|
return File_Do(file, path, O_WRONLY | O_CREAT | O_TRUNC);
|
||||||
}
|
}
|
||||||
ReturnCode File_Append(void** file, const String* path) {
|
ReturnCode File_Append(FileHandle* file, const String* path) {
|
||||||
ReturnCode res = File_Do(file, path, O_WRONLY | O_CREAT);
|
ReturnCode res = File_Do(file, path, O_WRONLY | O_CREAT);
|
||||||
if (res) return res;
|
if (res) return res;
|
||||||
return File_Seek(*file, 0, FILE_SEEKFROM_END);
|
return File_Seek(*file, 0, FILE_SEEKFROM_END);
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnCode File_Read(void* file, uint8_t* buffer, uint32_t count, uint32_t* bytesRead) {
|
ReturnCode File_Read(FileHandle file, uint8_t* buffer, uint32_t count, uint32_t* bytesRead) {
|
||||||
*bytesRead = read((int)file, buffer, count);
|
*bytesRead = read(file, buffer, count);
|
||||||
return Nix_Return(*bytesRead != -1);
|
return Nix_Return(*bytesRead != -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnCode File_Write(void* file, uint8_t* buffer, uint32_t count, uint32_t* bytesWrote) {
|
ReturnCode File_Write(FileHandle file, uint8_t* buffer, uint32_t count, uint32_t* bytesWrote) {
|
||||||
*bytesWrote = write((int)file, buffer, count);
|
*bytesWrote = write(file, buffer, count);
|
||||||
return Nix_Return(*bytesWrote != -1);
|
return Nix_Return(*bytesWrote != -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnCode File_Close(void* file) {
|
ReturnCode File_Close(FileHandle file) {
|
||||||
return Nix_Return(close((int)file) != -1);
|
return Nix_Return(close(file) != -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnCode File_Seek(void* file, int offset, int seekType) {
|
ReturnCode File_Seek(FileHandle file, int offset, int seekType) {
|
||||||
static uint8_t modes[3] = { SEEK_SET, SEEK_CUR, SEEK_END };
|
static uint8_t modes[3] = { SEEK_SET, SEEK_CUR, SEEK_END };
|
||||||
return Nix_Return(lseek((int)file, offset, modes[seekType]) != -1);
|
return Nix_Return(lseek(file, offset, modes[seekType]) != -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnCode File_Position(void* file, uint32_t* position) {
|
ReturnCode File_Position(FileHandle file, uint32_t* position) {
|
||||||
*position = lseek((int)file, 0, SEEK_CUR);
|
*position = lseek(file, 0, SEEK_CUR);
|
||||||
return Nix_Return(*position != -1);
|
return Nix_Return(*position != -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnCode File_Length(void* file, uint32_t* length) {
|
ReturnCode File_Length(FileHandle file, uint32_t* length) {
|
||||||
struct stat st;
|
struct stat st;
|
||||||
if (fstat((int)file, &st) == -1) { *length = -1; return errno; }
|
if (fstat(file, &st) == -1) { *length = -1; return errno; }
|
||||||
*length = st.st_size; return 0;
|
*length = st.st_size; return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -1113,14 +1113,14 @@ static void Font_Init(void) {
|
|||||||
/*########################################################################################################################*
|
/*########################################################################################################################*
|
||||||
*---------------------------------------------------------Socket----------------------------------------------------------*
|
*---------------------------------------------------------Socket----------------------------------------------------------*
|
||||||
*#########################################################################################################################*/
|
*#########################################################################################################################*/
|
||||||
void Socket_Create(SocketPtr* socketResult) {
|
void Socket_Create(SocketHandle* socketResult) {
|
||||||
*socketResult = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
*socketResult = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||||
if (*socketResult == -1) {
|
if (*socketResult == -1) {
|
||||||
ErrorHandler_Fail2(Socket__Error(), "Failed to create socket");
|
ErrorHandler_Fail2(Socket__Error(), "Failed to create socket");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static ReturnCode Socket_ioctl(SocketPtr socket, uint32_t cmd, int* data) {
|
static ReturnCode Socket_ioctl(SocketHandle socket, uint32_t cmd, int* data) {
|
||||||
#ifdef CC_BUILD_WIN
|
#ifdef CC_BUILD_WIN
|
||||||
return ioctlsocket(socket, cmd, data);
|
return ioctlsocket(socket, cmd, data);
|
||||||
#else
|
#else
|
||||||
@ -1128,20 +1128,20 @@ static ReturnCode Socket_ioctl(SocketPtr socket, uint32_t cmd, int* data) {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnCode Socket_Available(SocketPtr socket, uint32_t* available) {
|
ReturnCode Socket_Available(SocketHandle socket, uint32_t* available) {
|
||||||
return Socket_ioctl(socket, FIONREAD, available);
|
return Socket_ioctl(socket, FIONREAD, available);
|
||||||
}
|
}
|
||||||
ReturnCode Socket_SetBlocking(SocketPtr socket, bool blocking) {
|
ReturnCode Socket_SetBlocking(SocketHandle socket, bool blocking) {
|
||||||
int blocking_raw = blocking ? 0 : -1;
|
int blocking_raw = blocking ? 0 : -1;
|
||||||
return Socket_ioctl(socket, FIONBIO, &blocking_raw);
|
return Socket_ioctl(socket, FIONBIO, &blocking_raw);
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnCode Socket_GetError(SocketPtr socket, ReturnCode* result) {
|
ReturnCode Socket_GetError(SocketHandle socket, ReturnCode* result) {
|
||||||
int resultSize = sizeof(ReturnCode);
|
int resultSize = sizeof(ReturnCode);
|
||||||
return getsockopt(socket, SOL_SOCKET, SO_ERROR, result, &resultSize);
|
return getsockopt(socket, SOL_SOCKET, SO_ERROR, result, &resultSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnCode Socket_Connect(SocketPtr socket, const String* ip, int port) {
|
ReturnCode Socket_Connect(SocketHandle socket, const String* ip, int port) {
|
||||||
struct { int16_t Family; uint8_t Port[2], IP[4], Pad[8]; } addr;
|
struct { int16_t Family; uint8_t Port[2], IP[4], Pad[8]; } addr;
|
||||||
ReturnCode res;
|
ReturnCode res;
|
||||||
|
|
||||||
@ -1153,19 +1153,19 @@ ReturnCode Socket_Connect(SocketPtr socket, const String* ip, int port) {
|
|||||||
return res == -1 ? Socket__Error() : 0;
|
return res == -1 ? Socket__Error() : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnCode Socket_Read(SocketPtr socket, uint8_t* buffer, uint32_t count, uint32_t* modified) {
|
ReturnCode Socket_Read(SocketHandle socket, uint8_t* buffer, uint32_t count, uint32_t* modified) {
|
||||||
int recvCount = recv(socket, buffer, count, 0);
|
int recvCount = recv(socket, buffer, count, 0);
|
||||||
if (recvCount != -1) { *modified = recvCount; return 0; }
|
if (recvCount != -1) { *modified = recvCount; return 0; }
|
||||||
*modified = 0; return Socket__Error();
|
*modified = 0; return Socket__Error();
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnCode Socket_Write(SocketPtr socket, uint8_t* buffer, uint32_t count, uint32_t* modified) {
|
ReturnCode Socket_Write(SocketHandle socket, uint8_t* buffer, uint32_t count, uint32_t* modified) {
|
||||||
int sentCount = send(socket, buffer, count, 0);
|
int sentCount = send(socket, buffer, count, 0);
|
||||||
if (sentCount != -1) { *modified = sentCount; return 0; }
|
if (sentCount != -1) { *modified = sentCount; return 0; }
|
||||||
*modified = 0; return Socket__Error();
|
*modified = 0; return Socket__Error();
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnCode Socket_Close(SocketPtr socket) {
|
ReturnCode Socket_Close(SocketHandle socket) {
|
||||||
ReturnCode res = 0;
|
ReturnCode res = 0;
|
||||||
ReturnCode res1, res2;
|
ReturnCode res1, res2;
|
||||||
|
|
||||||
@ -1185,7 +1185,7 @@ ReturnCode Socket_Close(SocketPtr socket) {
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnCode Socket_Select(SocketPtr socket, int selectMode, bool* success) {
|
ReturnCode Socket_Select(SocketHandle socket, int selectMode, bool* success) {
|
||||||
fd_set set;
|
fd_set set;
|
||||||
struct timeval time = { 0 };
|
struct timeval time = { 0 };
|
||||||
int selectCount, nfds;
|
int selectCount, nfds;
|
||||||
@ -1270,12 +1270,12 @@ static ReturnCode Http_GetHeaders(struct AsyncRequest* req, HINTERNET handle) {
|
|||||||
if (!HttpQueryInfoA(handle, FLAG_STATUS, &req->StatusCode, &len, NULL)) return GetLastError();
|
if (!HttpQueryInfoA(handle, FLAG_STATUS, &req->StatusCode, &len, NULL)) return GetLastError();
|
||||||
|
|
||||||
len = sizeof(DWORD);
|
len = sizeof(DWORD);
|
||||||
HttpQueryInfoA(handle, FLAG_LENGTH, &req->ResultSize, &len, NULL);
|
HttpQueryInfoA(handle, FLAG_LENGTH, &req->ContentLength, &len, NULL);
|
||||||
|
|
||||||
SYSTEMTIME sysTime;
|
SYSTEMTIME sysTime;
|
||||||
len = sizeof(SYSTEMTIME);
|
len = sizeof(SYSTEMTIME);
|
||||||
if (HttpQueryInfoA(handle, FLAG_LASTMOD, &sysTime, &len, NULL)) {
|
if (HttpQueryInfoA(handle, FLAG_LASTMOD, &sysTime, &len, NULL)) {
|
||||||
DateTime time;
|
struct DateTime time;
|
||||||
Platform_FromSysTime(&time, &sysTime);
|
Platform_FromSysTime(&time, &sysTime);
|
||||||
req->LastModified = DateTime_TotalMs(&time);
|
req->LastModified = DateTime_TotalMs(&time);
|
||||||
}
|
}
|
||||||
@ -1288,30 +1288,40 @@ static ReturnCode Http_GetHeaders(struct AsyncRequest* req, HINTERNET handle) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static ReturnCode Http_GetData(struct AsyncRequest* req, HINTERNET handle, volatile int* progress) {
|
static ReturnCode Http_GetData(struct AsyncRequest* req, HINTERNET handle, volatile int* progress) {
|
||||||
uint32_t size = req->ResultSize;
|
uint8_t* buffer;
|
||||||
if (!size) return ERROR_NOT_SUPPORTED;
|
uint32_t size, totalRead;
|
||||||
|
uint32_t read, avail;
|
||||||
|
bool success;
|
||||||
|
|
||||||
*progress = 0;
|
*progress = 0;
|
||||||
|
size = req->ContentLength ? req->ContentLength : 1;
|
||||||
|
buffer = Mem_Alloc(size, 1, "http get data");
|
||||||
|
totalRead = 0;
|
||||||
|
|
||||||
uint8_t* buffer = Mem_Alloc(size, 1, "http get data");
|
|
||||||
uint32_t left = size, read, totalRead = 0;
|
|
||||||
req->ResultData = buffer;
|
req->ResultData = buffer;
|
||||||
|
req->ResultSize = 0;
|
||||||
|
|
||||||
while (left) {
|
for (;;) {
|
||||||
uint32_t toRead = left, avail = 0;
|
if (!InternetQueryDataAvailable(handle, &avail, 0, 0)) break;
|
||||||
/* only read as much data that is pending */
|
if (!avail) break;
|
||||||
if (InternetQueryDataAvailable(handle, &avail, 0, 0)) {
|
|
||||||
toRead = min(toRead, avail);
|
/* expand if buffer is too small (some servers don't give content length) */
|
||||||
|
if (totalRead + avail > size) {
|
||||||
|
size = totalRead + avail;
|
||||||
|
buffer = Mem_Realloc(buffer, size, 1, "http inc data");
|
||||||
|
req->ResultData = buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool success = InternetReadFile(handle, buffer, toRead, &read);
|
success = InternetReadFile(handle, &buffer[totalRead], avail, &read);
|
||||||
if (!success) { Mem_Free(buffer); return GetLastError(); }
|
if (!success) { Mem_Free(buffer); return GetLastError(); }
|
||||||
|
|
||||||
if (!read) break;
|
if (!read) break;
|
||||||
buffer += read; totalRead += read; left -= read;
|
|
||||||
*progress = (int)(100.0f * totalRead / size);
|
totalRead += read;
|
||||||
|
if (req->ContentLength) *progress = (int)(100.0f * totalRead / size);
|
||||||
|
req->ResultSize += read;
|
||||||
}
|
}
|
||||||
|
|
||||||
*progress = 100;
|
*progress = 100;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1393,7 +1403,9 @@ static size_t Http_GetHeaders(char *buffer, size_t size, size_t nitems, struct A
|
|||||||
tmp = String_ClearedArray(req->Etag);
|
tmp = String_ClearedArray(req->Etag);
|
||||||
String_AppendString(&tmp, &value);
|
String_AppendString(&tmp, &value);
|
||||||
} else if (String_CaselessEqualsConst(&name, "Content-Length")) {
|
} else if (String_CaselessEqualsConst(&name, "Content-Length")) {
|
||||||
Convert_TryParseInt(&value, &req->ResultSize);
|
Convert_TryParseInt(&value, &req->ContentLength);
|
||||||
|
/* TODO: Fix when ContentLength isn't RequestSize */
|
||||||
|
req->RequestSize = req->ContentLength;
|
||||||
} else if (String_CaselessEqualsConst(&name, "Last-Modified")) {
|
} else if (String_CaselessEqualsConst(&name, "Last-Modified")) {
|
||||||
String_InitArray_NT(tmp, tmpBuffer);
|
String_InitArray_NT(tmp, tmpBuffer);
|
||||||
String_AppendString(&tmp, &value);
|
String_AppendString(&tmp, &value);
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
#ifndef CC_PLATFORM_H
|
#ifndef CC_PLATFORM_H
|
||||||
#define CC_PLATFORM_H
|
#define CC_PLATFORM_H
|
||||||
#include "Utils.h"
|
|
||||||
#include "PackedCol.h"
|
#include "PackedCol.h"
|
||||||
#include "Bitmap.h"
|
#include "Bitmap.h"
|
||||||
/* Abstracts platform specific memory management, I/O, etc.
|
/* Abstracts platform specific memory management, I/O, etc.
|
||||||
@ -8,16 +7,19 @@
|
|||||||
*/
|
*/
|
||||||
struct DrawTextArgs;
|
struct DrawTextArgs;
|
||||||
struct AsyncRequest;
|
struct AsyncRequest;
|
||||||
|
struct DateTime;
|
||||||
|
|
||||||
enum SOCKET_SELECT { SOCKET_SELECT_READ, SOCKET_SELECT_WRITE };
|
enum Socket_Select { SOCKET_SELECT_READ, SOCKET_SELECT_WRITE };
|
||||||
#ifdef CC_BUILD_WIN
|
#ifdef CC_BUILD_WIN
|
||||||
typedef uintptr_t SocketPtr;
|
typedef uintptr_t SocketHandle;
|
||||||
|
typedef void* FileHandle;
|
||||||
#else
|
#else
|
||||||
typedef int SocketPtr;
|
typedef int SocketHandle;
|
||||||
|
typedef int FileHandle;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Origin points for when seeking in a file. */
|
/* Origin points for when seeking in a file. */
|
||||||
enum FILE_SEEKFROM { FILE_SEEKFROM_BEGIN, FILE_SEEKFROM_CURRENT, FILE_SEEKFROM_END };
|
enum File_SeekFrom { FILE_SEEKFROM_BEGIN, FILE_SEEKFROM_CURRENT, FILE_SEEKFROM_END };
|
||||||
|
|
||||||
/* Newline for console and text files. */
|
/* Newline for console and text files. */
|
||||||
extern char* Platform_NewLine;
|
extern char* Platform_NewLine;
|
||||||
@ -95,9 +97,9 @@ void Platform_Log4(const char* format, const void* a1, const void* a2, const voi
|
|||||||
TimeMS DateTime_CurrentUTC_MS(void);
|
TimeMS DateTime_CurrentUTC_MS(void);
|
||||||
/* Returns the current UTC Time. */
|
/* Returns the current UTC Time. */
|
||||||
/* NOTE: Generally DateTime_CurrentUTC_MS should be used instead. */
|
/* NOTE: Generally DateTime_CurrentUTC_MS should be used instead. */
|
||||||
void DateTime_CurrentUTC(DateTime* time);
|
void DateTime_CurrentUTC(struct DateTime* time);
|
||||||
/* Returns the current local Time. */
|
/* Returns the current local Time. */
|
||||||
void DateTime_CurrentLocal(DateTime* time);
|
void DateTime_CurrentLocal(struct DateTime* time);
|
||||||
/* Takes a platform-specific stopwatch measurement. */
|
/* Takes a platform-specific stopwatch measurement. */
|
||||||
/* NOTE: The value returned is platform-specific - do NOT try to interpret the value. */
|
/* NOTE: The value returned is platform-specific - do NOT try to interpret the value. */
|
||||||
uint64_t Stopwatch_Measure(void);
|
uint64_t Stopwatch_Measure(void);
|
||||||
@ -118,23 +120,23 @@ bool File_Exists(const String* path);
|
|||||||
ReturnCode File_GetModifiedTime_MS(const String* path, TimeMS* ms);
|
ReturnCode File_GetModifiedTime_MS(const String* path, TimeMS* ms);
|
||||||
|
|
||||||
/* Attempts to create a new (or overwrite) file for writing. */
|
/* Attempts to create a new (or overwrite) file for writing. */
|
||||||
ReturnCode File_Create(void** file, const String* path);
|
ReturnCode File_Create(FileHandle* file, const String* path);
|
||||||
/* Attempts to open an existing file for reading. */
|
/* Attempts to open an existing file for reading. */
|
||||||
ReturnCode File_Open(void** file, const String* path);
|
ReturnCode File_Open(FileHandle* file, const String* path);
|
||||||
/* Attempts to open (or create) a file, for appending data to the end of the file. */
|
/* Attempts to open (or create) a file, for appending data to the end of the file. */
|
||||||
ReturnCode File_Append(void** file, const String* path);
|
ReturnCode File_Append(FileHandle* file, const String* path);
|
||||||
/* Attempts to read data from the file. */
|
/* Attempts to read data from the file. */
|
||||||
ReturnCode File_Read(void* file, uint8_t* buffer, uint32_t count, uint32_t* bytesRead);
|
ReturnCode File_Read(FileHandle file, uint8_t* buffer, uint32_t count, uint32_t* bytesRead);
|
||||||
/* Attempts to write data to the file. */
|
/* Attempts to write data to the file. */
|
||||||
ReturnCode File_Write(void* file, uint8_t* buffer, uint32_t count, uint32_t* bytesWrote);
|
ReturnCode File_Write(FileHandle file, uint8_t* buffer, uint32_t count, uint32_t* bytesWrote);
|
||||||
/* Attempts to close the given file. */
|
/* Attempts to close the given file. */
|
||||||
ReturnCode File_Close(void* file);
|
ReturnCode File_Close(FileHandle file);
|
||||||
/* Attempts to seek to a position in the given file. */
|
/* Attempts to seek to a position in the given file. */
|
||||||
ReturnCode File_Seek(void* file, int offset, int seekType);
|
ReturnCode File_Seek(FileHandle file, int offset, int seekType);
|
||||||
/* Attempts to get the current position in the given file. */
|
/* Attempts to get the current position in the given file. */
|
||||||
ReturnCode File_Position(void* file, uint32_t* position);
|
ReturnCode File_Position(FileHandle file, uint32_t* position);
|
||||||
/* Attempts to retrieve the length of the given file. */
|
/* Attempts to retrieve the length of the given file. */
|
||||||
ReturnCode File_Length(void* file, uint32_t* length);
|
ReturnCode File_Length(FileHandle file, uint32_t* length);
|
||||||
|
|
||||||
/* Blocks the current thread for the given number of milliseconds. */
|
/* Blocks the current thread for the given number of milliseconds. */
|
||||||
CC_EXPORT void Thread_Sleep(uint32_t milliseconds);
|
CC_EXPORT void Thread_Sleep(uint32_t milliseconds);
|
||||||
@ -180,25 +182,25 @@ CC_EXPORT Size2D Platform_TextMeasure(struct DrawTextArgs* args);
|
|||||||
CC_EXPORT Size2D Platform_TextDraw(struct DrawTextArgs* args, Bitmap* bmp, int x, int y, BitmapCol col);
|
CC_EXPORT Size2D Platform_TextDraw(struct DrawTextArgs* args, Bitmap* bmp, int x, int y, BitmapCol col);
|
||||||
|
|
||||||
/* Allocates a new socket. */
|
/* Allocates a new socket. */
|
||||||
void Socket_Create(SocketPtr* socket);
|
void Socket_Create(SocketHandle* socket);
|
||||||
/* Returns how much data is available to be read from the given socket. */
|
/* Returns how much data is available to be read from the given socket. */
|
||||||
ReturnCode Socket_Available(SocketPtr socket, uint32_t* available);
|
ReturnCode Socket_Available(SocketHandle socket, uint32_t* available);
|
||||||
/* Sets whether operations on this socket block the calling thread. */
|
/* Sets whether operations on this socket block the calling thread. */
|
||||||
/* e.g. if blocking is on, calling Connect() blocks until a response is received. */
|
/* e.g. if blocking is on, calling Connect() blocks until a response is received. */
|
||||||
ReturnCode Socket_SetBlocking(SocketPtr socket, bool blocking);
|
ReturnCode Socket_SetBlocking(SocketHandle socket, bool blocking);
|
||||||
/* Returns (and resets) the last error generated by this socket. */
|
/* Returns (and resets) the last error generated by this socket. */
|
||||||
ReturnCode Socket_GetError(SocketPtr socket, ReturnCode* result);
|
ReturnCode Socket_GetError(SocketHandle socket, ReturnCode* result);
|
||||||
|
|
||||||
/* Attempts to initalise a TCP connection to the given IP address:port. */
|
/* Attempts to initalise a TCP connection to the given IP address:port. */
|
||||||
ReturnCode Socket_Connect(SocketPtr socket, const String* ip, int port);
|
ReturnCode Socket_Connect(SocketHandle socket, const String* ip, int port);
|
||||||
/* Attempts to read data from the given socket. */
|
/* Attempts to read data from the given socket. */
|
||||||
ReturnCode Socket_Read(SocketPtr socket, uint8_t* buffer, uint32_t count, uint32_t* modified);
|
ReturnCode Socket_Read(SocketHandle socket, uint8_t* buffer, uint32_t count, uint32_t* modified);
|
||||||
/* Attempts to write data to the given socket. */
|
/* Attempts to write data to the given socket. */
|
||||||
ReturnCode Socket_Write(SocketPtr socket, uint8_t* buffer, uint32_t count, uint32_t* modified);
|
ReturnCode Socket_Write(SocketHandle socket, uint8_t* buffer, uint32_t count, uint32_t* modified);
|
||||||
/* Attempts to close the given socket. */
|
/* Attempts to close the given socket. */
|
||||||
ReturnCode Socket_Close(SocketPtr socket);
|
ReturnCode Socket_Close(SocketHandle socket);
|
||||||
/* Attempts to poll the socket for reading or writing. */
|
/* Attempts to poll the socket for reading or writing. */
|
||||||
ReturnCode Socket_Select(SocketPtr socket, int selectMode, bool* success);
|
ReturnCode Socket_Select(SocketHandle socket, int selectMode, bool* success);
|
||||||
|
|
||||||
/* Initalises the platform specific http library state. */
|
/* Initalises the platform specific http library state. */
|
||||||
void Http_Init(void);
|
void Http_Init(void);
|
||||||
|
@ -240,7 +240,7 @@ void ServerConnection_InitSingleplayer(void) {
|
|||||||
/*########################################################################################################################*
|
/*########################################################################################################################*
|
||||||
*--------------------------------------------------Multiplayer connection-------------------------------------------------*
|
*--------------------------------------------------Multiplayer connection-------------------------------------------------*
|
||||||
*#########################################################################################################################*/
|
*#########################################################################################################################*/
|
||||||
static SocketPtr net_socket;
|
static SocketHandle net_socket;
|
||||||
static uint8_t net_readBuffer[4096 * 5];
|
static uint8_t net_readBuffer[4096 * 5];
|
||||||
static uint8_t net_writeBuffer[131];
|
static uint8_t net_writeBuffer[131];
|
||||||
static uint8_t* net_readCurrent;
|
static uint8_t* net_readCurrent;
|
||||||
|
@ -108,19 +108,19 @@ static ReturnCode Stream_FileLength(struct Stream* s, uint32_t* length) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ReturnCode Stream_OpenFile(struct Stream* s, const String* path) {
|
ReturnCode Stream_OpenFile(struct Stream* s, const String* path) {
|
||||||
void* file;
|
FileHandle file;
|
||||||
ReturnCode res = File_Open(&file, path);
|
ReturnCode res = File_Open(&file, path);
|
||||||
Stream_FromFile(s, file);
|
Stream_FromFile(s, file);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
ReturnCode Stream_CreateFile(struct Stream* s, const String* path) {
|
ReturnCode Stream_CreateFile(struct Stream* s, const String* path) {
|
||||||
void* file;
|
FileHandle file;
|
||||||
ReturnCode res = File_Create(&file, path);
|
ReturnCode res = File_Create(&file, path);
|
||||||
Stream_FromFile(s, file);
|
Stream_FromFile(s, file);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Stream_FromFile(struct Stream* s, void* file) {
|
void Stream_FromFile(struct Stream* s, FileHandle file) {
|
||||||
Stream_Init(s);
|
Stream_Init(s);
|
||||||
s->Meta.File = file;
|
s->Meta.File = file;
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#ifndef CC_STREAM_H
|
#ifndef CC_STREAM_H
|
||||||
#define CC_STREAM_H
|
#define CC_STREAM_H
|
||||||
#include "String.h"
|
|
||||||
#include "Constants.h"
|
#include "Constants.h"
|
||||||
|
#include "Platform.h"
|
||||||
/* Defines an abstract way of reading and writing data in a streaming manner.
|
/* Defines an abstract way of reading and writing data in a streaming manner.
|
||||||
Also provides common helper methods for reading/writing data to/from streams.
|
Also provides common helper methods for reading/writing data to/from streams.
|
||||||
Copyright 2017 ClassicalSharp | Licensed under BSD-3
|
Copyright 2017 ClassicalSharp | Licensed under BSD-3
|
||||||
@ -29,7 +29,7 @@ struct Stream {
|
|||||||
ReturnCode (*Close)(struct Stream* s);
|
ReturnCode (*Close)(struct Stream* s);
|
||||||
|
|
||||||
union {
|
union {
|
||||||
void* File;
|
FileHandle File;
|
||||||
void* Inflate;
|
void* Inflate;
|
||||||
/* NOTE: These structs rely on overlapping Meta_Mem fields being the same! Don't change them */
|
/* NOTE: These structs rely on overlapping Meta_Mem fields being the same! Don't change them */
|
||||||
struct { uint8_t* Cur; uint32_t Left, Length; uint8_t* Base; } Mem;
|
struct { uint8_t* Cur; uint32_t Left, Length; uint8_t* Base; } Mem;
|
||||||
@ -54,7 +54,7 @@ CC_EXPORT ReturnCode Stream_OpenFile(struct Stream* s, const String* path);
|
|||||||
/* Wrapper for File_Create() then Stream_FromFile() */
|
/* Wrapper for File_Create() then Stream_FromFile() */
|
||||||
CC_EXPORT ReturnCode Stream_CreateFile(struct Stream* s, const String* path);
|
CC_EXPORT ReturnCode Stream_CreateFile(struct Stream* s, const String* path);
|
||||||
/* Wraps a file, allowing reading from/writing to/seeking in the file. */
|
/* Wraps a file, allowing reading from/writing to/seeking in the file. */
|
||||||
CC_EXPORT void Stream_FromFile(struct Stream* s, void* file);
|
CC_EXPORT void Stream_FromFile(struct Stream* s, FileHandle file);
|
||||||
|
|
||||||
/* Wraps another Stream, only allows reading up to 'len' bytes from the wrapped stream. */
|
/* Wraps another Stream, only allows reading up to 'len' bytes from the wrapped stream. */
|
||||||
CC_EXPORT void Stream_ReadonlyPortion(struct Stream* s, struct Stream* source, uint32_t len);
|
CC_EXPORT void Stream_ReadonlyPortion(struct Stream* s, struct Stream* source, uint32_t len);
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
#include "ErrorHandler.h"
|
#include "ErrorHandler.h"
|
||||||
#include "Platform.h"
|
#include "Platform.h"
|
||||||
#include "Stream.h"
|
#include "Stream.h"
|
||||||
|
#include "Utils.h"
|
||||||
|
|
||||||
String String_Init(STRING_REF char* buffer, int length, int capacity) {
|
String String_Init(STRING_REF char* buffer, int length, int capacity) {
|
||||||
String s;
|
String s;
|
||||||
|
@ -21,7 +21,7 @@ static bool DateTime_IsLeapYear(int year) {
|
|||||||
return (year % 400) == 0;
|
return (year % 400) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int DateTime_TotalDays(const DateTime* time) {
|
int DateTime_TotalDays(const struct DateTime* time) {
|
||||||
/* Days from before this year */
|
/* Days from before this year */
|
||||||
int y = time->Year - 1, days = 365 * y;
|
int y = time->Year - 1, days = 365 * y;
|
||||||
/* A year is a leap year when the year is: */
|
/* A year is a leap year when the year is: */
|
||||||
@ -38,7 +38,7 @@ int DateTime_TotalDays(const DateTime* time) {
|
|||||||
return days;
|
return days;
|
||||||
}
|
}
|
||||||
|
|
||||||
TimeMS DateTime_TotalMs(const DateTime* time) {
|
TimeMS DateTime_TotalMs(const struct DateTime* time) {
|
||||||
int days = DateTime_TotalDays(time);
|
int days = DateTime_TotalDays(time);
|
||||||
uint64_t seconds =
|
uint64_t seconds =
|
||||||
(uint64_t)days * DATETIME_SECONDS_PER_DAY +
|
(uint64_t)days * DATETIME_SECONDS_PER_DAY +
|
||||||
@ -48,7 +48,7 @@ TimeMS DateTime_TotalMs(const DateTime* time) {
|
|||||||
return seconds * DATETIME_MILLIS_PER_SEC + time->Milli;
|
return seconds * DATETIME_MILLIS_PER_SEC + time->Milli;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DateTime_FromTotalMs(DateTime* time, TimeMS ms) {
|
void DateTime_FromTotalMs(struct DateTime* time, TimeMS ms) {
|
||||||
int dayMS, days, year;
|
int dayMS, days, year;
|
||||||
int daysInYear, month;
|
int daysInYear, month;
|
||||||
uint16_t* totalDays;
|
uint16_t* totalDays;
|
||||||
@ -90,7 +90,7 @@ void DateTime_FromTotalMs(DateTime* time, TimeMS ms) {
|
|||||||
void DateTime_HttpDate(TimeMS ms, String* str) {
|
void DateTime_HttpDate(TimeMS ms, String* str) {
|
||||||
static char* days_of_week[7] = { "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun" };
|
static char* days_of_week[7] = { "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun" };
|
||||||
static char* month_names[13] = { NULL, "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
|
static char* month_names[13] = { NULL, "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
|
||||||
DateTime t;
|
struct DateTime t;
|
||||||
int days;
|
int days;
|
||||||
|
|
||||||
DateTime_FromTotalMs(&t, ms);
|
DateTime_FromTotalMs(&t, ms);
|
||||||
|
10
src/Utils.h
10
src/Utils.h
@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
/* Represents a particular instance in time in some timezone. Not necessarily UTC time. */
|
/* Represents a particular instance in time in some timezone. Not necessarily UTC time. */
|
||||||
/* NOTE: This is not an efficiently sized struct. Store DateTime_TotalMs instead for that. */
|
/* NOTE: This is not an efficiently sized struct. Store DateTime_TotalMs instead for that. */
|
||||||
typedef struct DateTime_ {
|
struct DateTime {
|
||||||
int Year; /* Year, ranges from 0 to 65535 */
|
int Year; /* Year, ranges from 0 to 65535 */
|
||||||
int Month; /* Month, ranges from 1 to 12 */
|
int Month; /* Month, ranges from 1 to 12 */
|
||||||
int Day; /* Day, ranges from 1 to 31 */
|
int Day; /* Day, ranges from 1 to 31 */
|
||||||
@ -16,12 +16,12 @@ typedef struct DateTime_ {
|
|||||||
int Minute; /* Minute, ranges from 0 to 59 */
|
int Minute; /* Minute, ranges from 0 to 59 */
|
||||||
int Second; /* Second, ranges from 0 to 59 */
|
int Second; /* Second, ranges from 0 to 59 */
|
||||||
int Milli; /* Milliseconds, ranges from 0 to 999 */
|
int Milli; /* Milliseconds, ranges from 0 to 999 */
|
||||||
} DateTime;
|
};
|
||||||
|
|
||||||
#define DATETIME_MILLIS_PER_SEC 1000
|
#define DATETIME_MILLIS_PER_SEC 1000
|
||||||
int DateTime_TotalDays(const DateTime* time);
|
int DateTime_TotalDays(const struct DateTime* time);
|
||||||
TimeMS DateTime_TotalMs(const DateTime* time);
|
TimeMS DateTime_TotalMs(const struct DateTime* time);
|
||||||
void DateTime_FromTotalMs(DateTime* time, TimeMS ms);
|
void DateTime_FromTotalMs(struct DateTime* time, TimeMS ms);
|
||||||
void DateTime_HttpDate(TimeMS ms, String* str);
|
void DateTime_HttpDate(TimeMS ms, String* str);
|
||||||
|
|
||||||
CC_NOINLINE int Utils_ParseEnum(const String* text, int defValue, const char** names, int namesCount);
|
CC_NOINLINE int Utils_ParseEnum(const String* text, int defValue, const char** names, int namesCount);
|
||||||
|
@ -1916,21 +1916,25 @@ static void PlayerListWidget_SetColumnPos(struct PlayerListWidget* w, int column
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void PlayerListWidget_RepositionColumns(struct PlayerListWidget* w) {
|
static void PlayerListWidget_RepositionColumns(struct PlayerListWidget* w) {
|
||||||
int width = 0, centreX = Game_Width / 2;
|
int x, y, width = 0, height;
|
||||||
w->YHeight = 0;
|
int col, columns;
|
||||||
|
|
||||||
|
w->YHeight = 0;
|
||||||
|
columns = Math_CeilDiv(w->NamesCount, LIST_NAMES_PER_COLUMN);
|
||||||
|
|
||||||
int col, columns = Math_CeilDiv(w->NamesCount, LIST_NAMES_PER_COLUMN);
|
|
||||||
for (col = 0; col < columns; col++) {
|
for (col = 0; col < columns; col++) {
|
||||||
width += PlayerListWidget_GetColumnWidth(w, col);
|
width += PlayerListWidget_GetColumnWidth(w, col);
|
||||||
int colHeight = PlayerListWidget_GetColumnHeight(w, col);
|
height = PlayerListWidget_GetColumnHeight(w, col);
|
||||||
w->YHeight = max(colHeight, w->YHeight);
|
w->YHeight = max(height, w->YHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (width < 480) width = 480;
|
if (width < 480) width = 480;
|
||||||
w->XMin = centreX - width / 2;
|
w->XMin = Game_Width / 2 - width / 2;
|
||||||
w->XMax = centreX + width / 2;
|
w->XMax = Game_Width / 2 + width / 2;
|
||||||
|
|
||||||
|
x = w->XMin;
|
||||||
|
y = Game_Height / 2 - w->YHeight / 2;
|
||||||
|
|
||||||
int x = w->XMin, y = Game_Height / 2 - w->YHeight / 2;
|
|
||||||
for (col = 0; col < columns; col++) {
|
for (col = 0; col < columns; col++) {
|
||||||
PlayerListWidget_SetColumnPos(w, col, x, y);
|
PlayerListWidget_SetColumnPos(w, col, x, y);
|
||||||
x += PlayerListWidget_GetColumnWidth(w, col);
|
x += PlayerListWidget_GetColumnWidth(w, col);
|
||||||
|
@ -115,12 +115,14 @@ static void Window_ResetWindowState(void) {
|
|||||||
|
|
||||||
static bool win_hiddenBorder;
|
static bool win_hiddenBorder;
|
||||||
static void Window_DoSetHiddenBorder(bool value) {
|
static void Window_DoSetHiddenBorder(bool value) {
|
||||||
|
bool wasVisible;
|
||||||
|
RECT rect;
|
||||||
if (win_hiddenBorder == value) return;
|
if (win_hiddenBorder == value) return;
|
||||||
|
|
||||||
/* We wish to avoid making an invisible window visible just to change the border.
|
/* We wish to avoid making an invisible window visible just to change the border.
|
||||||
However, it's a good idea to make a visible window invisible temporarily, to
|
However, it's a good idea to make a visible window invisible temporarily, to
|
||||||
avoid garbage caused by the border change. */
|
avoid garbage caused by the border change. */
|
||||||
bool was_visible = Window_GetVisible();
|
wasVisible = Window_GetVisible();
|
||||||
|
|
||||||
/* To ensure maximized/minimized windows work correctly, reset state to normal,
|
/* To ensure maximized/minimized windows work correctly, reset state to normal,
|
||||||
change the border, then go back to maximized/minimized. */
|
change the border, then go back to maximized/minimized. */
|
||||||
@ -130,14 +132,13 @@ static void Window_DoSetHiddenBorder(bool value) {
|
|||||||
style |= (value ? WS_POPUP : WS_OVERLAPPEDWINDOW);
|
style |= (value ? WS_POPUP : WS_OVERLAPPEDWINDOW);
|
||||||
|
|
||||||
/* Make sure client size doesn't change when changing the border style.*/
|
/* Make sure client size doesn't change when changing the border style.*/
|
||||||
RECT rect;
|
|
||||||
rect.left = Window_Bounds.X; rect.top = Window_Bounds.Y;
|
rect.left = Window_Bounds.X; rect.top = Window_Bounds.Y;
|
||||||
rect.right = rect.left + Window_Bounds.Width;
|
rect.right = rect.left + Window_Bounds.Width;
|
||||||
rect.bottom = rect.top + Window_Bounds.Height;
|
rect.bottom = rect.top + Window_Bounds.Height;
|
||||||
AdjustWindowRect(&rect, style, false);
|
AdjustWindowRect(&rect, style, false);
|
||||||
|
|
||||||
/* This avoids leaving garbage on the background window. */
|
/* This avoids leaving garbage on the background window. */
|
||||||
if (was_visible) Window_SetVisible(false);
|
if (wasVisible) Window_SetVisible(false);
|
||||||
|
|
||||||
SetWindowLong(win_handle, GWL_STYLE, style);
|
SetWindowLong(win_handle, GWL_STYLE, style);
|
||||||
SetWindowPos(win_handle, NULL, 0, 0, Rect_Width(rect), Rect_Height(rect),
|
SetWindowPos(win_handle, NULL, 0, 0, Rect_Width(rect), Rect_Height(rect),
|
||||||
@ -146,7 +147,7 @@ static void Window_DoSetHiddenBorder(bool value) {
|
|||||||
/* Force window to redraw update its borders, but only if it's
|
/* Force window to redraw update its borders, but only if it's
|
||||||
already visible (invisible windows will change borders when
|
already visible (invisible windows will change borders when
|
||||||
they become visible, so no need to make them visiable prematurely).*/
|
they become visible, so no need to make them visiable prematurely).*/
|
||||||
if (was_visible) Window_SetVisible(true);
|
if (wasVisible) Window_SetVisible(true);
|
||||||
|
|
||||||
Window_SetWindowState(state);
|
Window_SetWindowState(state);
|
||||||
}
|
}
|
||||||
@ -166,15 +167,19 @@ static void Window_UpdateClientSize(HWND handle) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static LRESULT CALLBACK Window_Procedure(HWND handle, UINT message, WPARAM wParam, LPARAM lParam) {
|
static LRESULT CALLBACK Window_Procedure(HWND handle, UINT message, WPARAM wParam, LPARAM lParam) {
|
||||||
|
char keyChar;
|
||||||
|
bool wasFocused;
|
||||||
|
float wheelDelta;
|
||||||
|
|
||||||
switch (message) {
|
switch (message) {
|
||||||
case WM_ACTIVATE:
|
case WM_ACTIVATE:
|
||||||
{
|
wasFocused = Window_Focused;
|
||||||
bool wasFocused = Window_Focused;
|
|
||||||
Window_Focused = LOWORD(wParam) != 0;
|
Window_Focused = LOWORD(wParam) != 0;
|
||||||
|
|
||||||
if (Window_Focused != wasFocused) {
|
if (Window_Focused != wasFocused) {
|
||||||
Event_RaiseVoid(&WindowEvents_FocusChanged);
|
Event_RaiseVoid(&WindowEvents_FocusChanged);
|
||||||
}
|
}
|
||||||
} break;
|
break;
|
||||||
|
|
||||||
case WM_ENTERMENULOOP:
|
case WM_ENTERMENULOOP:
|
||||||
case WM_ENTERSIZEMOVE:
|
case WM_ENTERSIZEMOVE:
|
||||||
@ -238,31 +243,24 @@ static LRESULT CALLBACK Window_Procedure(HWND handle, UINT message, WPARAM wPara
|
|||||||
|
|
||||||
|
|
||||||
case WM_CHAR:
|
case WM_CHAR:
|
||||||
{
|
|
||||||
char keyChar;
|
|
||||||
if (Convert_TryUnicodeToCP437((Codepoint)wParam, &keyChar)) {
|
if (Convert_TryUnicodeToCP437((Codepoint)wParam, &keyChar)) {
|
||||||
Event_RaiseInt(&KeyEvents_Press, keyChar);
|
Event_RaiseInt(&KeyEvents_Press, keyChar);
|
||||||
}
|
}
|
||||||
} break;
|
break;
|
||||||
|
|
||||||
case WM_MOUSEMOVE:
|
case WM_MOUSEMOVE:
|
||||||
{
|
|
||||||
/* set before position change, in case mouse buttons changed when outside window */
|
/* set before position change, in case mouse buttons changed when outside window */
|
||||||
Mouse_SetPressed(MouseButton_Left, (wParam & 0x01) != 0);
|
Mouse_SetPressed(MouseButton_Left, (wParam & 0x01) != 0);
|
||||||
Mouse_SetPressed(MouseButton_Right, (wParam & 0x02) != 0);
|
Mouse_SetPressed(MouseButton_Right, (wParam & 0x02) != 0);
|
||||||
Mouse_SetPressed(MouseButton_Middle, (wParam & 0x10) != 0);
|
Mouse_SetPressed(MouseButton_Middle, (wParam & 0x10) != 0);
|
||||||
/* TODO: do we need to set XBUTTON1 / XBUTTON 2 here */
|
/* TODO: do we need to set XBUTTON1/XBUTTON2 here */
|
||||||
|
Mouse_SetPosition(LOWORD(lParam), HIWORD(lParam));
|
||||||
WORD mouse_x = LOWORD(lParam);
|
break;
|
||||||
WORD mouse_y = HIWORD(lParam);
|
|
||||||
Mouse_SetPosition(mouse_x, mouse_y);
|
|
||||||
} break;
|
|
||||||
|
|
||||||
case WM_MOUSEWHEEL:
|
case WM_MOUSEWHEEL:
|
||||||
{
|
wheelDelta = ((short)HIWORD(wParam)) / (float)WHEEL_DELTA;
|
||||||
float wheel_delta = ((short)HIWORD(wParam)) / (float)WHEEL_DELTA;
|
Mouse_SetWheel(Mouse_Wheel + wheelDelta);
|
||||||
Mouse_SetWheel(Mouse_Wheel + wheel_delta);
|
return 0;
|
||||||
} return 0;
|
|
||||||
|
|
||||||
case WM_LBUTTONDOWN:
|
case WM_LBUTTONDOWN:
|
||||||
Mouse_SetPressed(MouseButton_Left, true);
|
Mouse_SetPressed(MouseButton_Left, true);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user