Fix texture packs without content length header not decoding, on windows.

This commit is contained in:
UnknownShadow200 2018-11-21 23:05:57 +11:00
parent 10e0a4ea2e
commit 348ca90306
17 changed files with 159 additions and 140 deletions

View File

@ -21,6 +21,7 @@ struct AsyncRequest {
TimeMS TimeAdded, TimeDownloaded;
int StatusCode;
uint32_t ContentLength;
ReturnCode Result;
void* ResultData;

View File

@ -6,6 +6,7 @@
#include "ErrorHandler.h"
#include "Stream.h"
#include "Errors.h"
#include "Utils.h"
BitmapCol BitmapCol_Scale(BitmapCol value, float t) {
value.R = (uint8_t)(value.R * t);

View File

@ -307,8 +307,7 @@ STRING_REF String Block_UNSAFE_GetName(BlockID block) {
}
void Block_SetName(BlockID block, const String* name) {
String dst = { Block_NamePtr(block), 0, STRING_SIZE };
Mem_Set(dst.buffer, 0, STRING_SIZE);
String dst = String_InitAndClear(Block_NamePtr(block), STRING_SIZE);
String_AppendString(&dst, name);
}

View File

@ -45,7 +45,7 @@ static char Chat_LogPathBuffer[FILENAME_SIZE];
static String Chat_LogPath = String_FromArray(Chat_LogPathBuffer);
static struct Stream Chat_LogStream;
static DateTime ChatLog_LastLogDate;
static struct DateTime ChatLog_LastLogDate;
static void Chat_CloseLog(void) {
ReturnCode res;
@ -82,7 +82,7 @@ static void Chat_DisableLogging(void) {
Chat_AddRaw("&cDisabling chat logging");
}
static void Chat_OpenLog(DateTime* now) {
static void Chat_OpenLog(struct DateTime* now) {
void* file;
int i;
ReturnCode res;
@ -119,7 +119,7 @@ static void Chat_OpenLog(DateTime* now) {
static void Chat_AppendLog(const String* text) {
String str; char strBuffer[STRING_SIZE * 2];
DateTime now;
struct DateTime now;
ReturnCode res;
if (!Chat_LogName.length || !Game_ChatLogging) return;

View File

@ -4,6 +4,7 @@
#include "Platform.h"
#include "Stream.h"
#include "Errors.h"
#include "Utils.h"
#define Header_ReadU8(value) if ((res = s->ReadU8(s, &value))) return res;
/*########################################################################################################################*

View File

@ -645,7 +645,7 @@ static void Game_DoScheduledTasks(double time) {
void Game_TakeScreenshot(void) {
String filename; char fileBuffer[STRING_SIZE];
String path; char pathBuffer[FILENAME_SIZE];
DateTime now;
struct DateTime now;
struct Stream stream;
ReturnCode res;

View File

@ -3259,7 +3259,7 @@ static void TexPackOverlay_Render(void* screen, double delta) {
MenuScreen_Render(s, delta);
if (!AsyncDownloader_Get(&s->Identifier, &item)) return;
s->ContentLength = item.ResultSize;
s->ContentLength = item.ContentLength;
if (!s->ContentLength) return;
Elem_Recreate(s);
}

View File

@ -258,7 +258,7 @@ TimeMS DateTime_CurrentUTC_MS(void) {
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->Month = sysTime->wMonth;
time->Day = sysTime->wDay;
@ -268,13 +268,13 @@ static void Platform_FromSysTime(DateTime* time, SYSTEMTIME* sysTime) {
time->Milli = sysTime->wMilliseconds;
}
void DateTime_CurrentUTC(DateTime* time) {
void DateTime_CurrentUTC(struct DateTime* time) {
SYSTEMTIME utcTime;
GetSystemTime(&utcTime);
Platform_FromSysTime(time, &utcTime);
}
void DateTime_CurrentLocal(DateTime* time) {
void DateTime_CurrentLocal(struct DateTime* time) {
SYSTEMTIME localTime;
GetLocalTime(&localTime);
Platform_FromSysTime(time, &localTime);
@ -308,7 +308,7 @@ TimeMS DateTime_CurrentUTC_MS(void) {
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->Month = sysTime->tm_mon + 1;
time->Day = sysTime->tm_mday;
@ -317,7 +317,7 @@ static void Platform_FromSysTime(DateTime* time, struct tm* sysTime) {
time->Second = sysTime->tm_sec;
}
void DateTime_CurrentUTC(DateTime* time_) {
void DateTime_CurrentUTC(struct DateTime* time_) {
struct timeval cur;
struct tm utc_time;
@ -328,7 +328,7 @@ void DateTime_CurrentUTC(DateTime* time_) {
time_->Milli = cur.tv_usec / 1000;
}
void DateTime_CurrentLocal(DateTime* time_) {
void DateTime_CurrentLocal(struct DateTime* time_) {
struct timeval cur;
struct tm loc_time;
@ -451,51 +451,51 @@ ReturnCode File_GetModifiedTime_MS(const String* path, TimeMS* time) {
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];
Platform_ConvertString(str, path);
*file = CreateFile(str, access, FILE_SHARE_READ, NULL, createMode, 0, NULL);
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);
}
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);
}
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);
if (res) return res;
return File_Seek(*file, 0, FILE_SEEKFROM_END);
}
ReturnCode File_Read(void* file, uint8_t* buffer, uint32_t count, uint32_t* bytesRead) {
BOOL success = ReadFile((HANDLE)file, buffer, count, bytesRead, NULL);
ReturnCode File_Read(FileHandle file, uint8_t* buffer, uint32_t count, uint32_t* bytesRead) {
BOOL success = ReadFile(file, buffer, count, bytesRead, NULL);
return Win_Return(success);
}
ReturnCode File_Write(void* file, uint8_t* buffer, uint32_t count, uint32_t* bytesWrote) {
BOOL success = WriteFile((HANDLE)file, buffer, count, bytesWrote, NULL);
ReturnCode File_Write(FileHandle file, uint8_t* buffer, uint32_t count, uint32_t* bytesWrote) {
BOOL success = WriteFile(file, buffer, count, bytesWrote, NULL);
return Win_Return(success);
}
ReturnCode File_Close(void* file) {
return Win_Return(CloseHandle((HANDLE)file));
ReturnCode File_Close(FileHandle 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 };
DWORD pos = SetFilePointer(file, offset, NULL, modes[seekType]);
return Win_Return(pos != INVALID_SET_FILE_POINTER);
}
ReturnCode File_Position(void* file, uint32_t* position) {
*position = SetFilePointer(file, 0, NULL, 1); /* SEEK_CUR */
ReturnCode File_Position(FileHandle file, uint32_t* position) {
*position = SetFilePointer(file, 0, NULL, FILE_CURRENT);
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);
return Win_Return(*length != INVALID_FILE_SIZE);
}
@ -577,52 +577,52 @@ ReturnCode File_GetModifiedTime_MS(const String* path, TimeMS* time) {
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];
Platform_ConvertString(str, path);
*file = open(str, mode, (6 << 6) | (4 << 3) | 4); /* rw|r|r */
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);
}
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);
}
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);
if (res) return res;
return File_Seek(*file, 0, FILE_SEEKFROM_END);
}
ReturnCode File_Read(void* file, uint8_t* buffer, uint32_t count, uint32_t* bytesRead) {
*bytesRead = read((int)file, buffer, count);
ReturnCode File_Read(FileHandle file, uint8_t* buffer, uint32_t count, uint32_t* bytesRead) {
*bytesRead = read(file, buffer, count);
return Nix_Return(*bytesRead != -1);
}
ReturnCode File_Write(void* file, uint8_t* buffer, uint32_t count, uint32_t* bytesWrote) {
*bytesWrote = write((int)file, buffer, count);
ReturnCode File_Write(FileHandle file, uint8_t* buffer, uint32_t count, uint32_t* bytesWrote) {
*bytesWrote = write(file, buffer, count);
return Nix_Return(*bytesWrote != -1);
}
ReturnCode File_Close(void* file) {
return Nix_Return(close((int)file) != -1);
ReturnCode File_Close(FileHandle file) {
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 };
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) {
*position = lseek((int)file, 0, SEEK_CUR);
ReturnCode File_Position(FileHandle file, uint32_t* position) {
*position = lseek(file, 0, SEEK_CUR);
return Nix_Return(*position != -1);
}
ReturnCode File_Length(void* file, uint32_t* length) {
ReturnCode File_Length(FileHandle file, uint32_t* length) {
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;
}
#endif
@ -1113,14 +1113,14 @@ static void Font_Init(void) {
/*########################################################################################################################*
*---------------------------------------------------------Socket----------------------------------------------------------*
*#########################################################################################################################*/
void Socket_Create(SocketPtr* socketResult) {
void Socket_Create(SocketHandle* socketResult) {
*socketResult = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (*socketResult == -1) {
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
return ioctlsocket(socket, cmd, data);
#else
@ -1128,20 +1128,20 @@ static ReturnCode Socket_ioctl(SocketPtr socket, uint32_t cmd, int* data) {
#endif
}
ReturnCode Socket_Available(SocketPtr socket, uint32_t* available) {
ReturnCode Socket_Available(SocketHandle socket, uint32_t* 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;
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);
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;
ReturnCode res;
@ -1153,19 +1153,19 @@ ReturnCode Socket_Connect(SocketPtr socket, const String* ip, int port) {
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);
if (recvCount != -1) { *modified = recvCount; return 0; }
*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);
if (sentCount != -1) { *modified = sentCount; return 0; }
*modified = 0; return Socket__Error();
}
ReturnCode Socket_Close(SocketPtr socket) {
ReturnCode Socket_Close(SocketHandle socket) {
ReturnCode res = 0;
ReturnCode res1, res2;
@ -1185,7 +1185,7 @@ ReturnCode Socket_Close(SocketPtr socket) {
return res;
}
ReturnCode Socket_Select(SocketPtr socket, int selectMode, bool* success) {
ReturnCode Socket_Select(SocketHandle socket, int selectMode, bool* success) {
fd_set set;
struct timeval time = { 0 };
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();
len = sizeof(DWORD);
HttpQueryInfoA(handle, FLAG_LENGTH, &req->ResultSize, &len, NULL);
HttpQueryInfoA(handle, FLAG_LENGTH, &req->ContentLength, &len, NULL);
SYSTEMTIME sysTime;
len = sizeof(SYSTEMTIME);
if (HttpQueryInfoA(handle, FLAG_LASTMOD, &sysTime, &len, NULL)) {
DateTime time;
struct DateTime time;
Platform_FromSysTime(&time, &sysTime);
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) {
uint32_t size = req->ResultSize;
if (!size) return ERROR_NOT_SUPPORTED;
uint8_t* buffer;
uint32_t size, totalRead;
uint32_t read, avail;
bool success;
*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->ResultSize = 0;
while (left) {
uint32_t toRead = left, avail = 0;
/* only read as much data that is pending */
if (InternetQueryDataAvailable(handle, &avail, 0, 0)) {
toRead = min(toRead, avail);
for (;;) {
if (!InternetQueryDataAvailable(handle, &avail, 0, 0)) break;
if (!avail) break;
/* 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 (!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;
}
@ -1393,7 +1403,9 @@ static size_t Http_GetHeaders(char *buffer, size_t size, size_t nitems, struct A
tmp = String_ClearedArray(req->Etag);
String_AppendString(&tmp, &value);
} 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")) {
String_InitArray_NT(tmp, tmpBuffer);
String_AppendString(&tmp, &value);

View File

@ -1,6 +1,5 @@
#ifndef CC_PLATFORM_H
#define CC_PLATFORM_H
#include "Utils.h"
#include "PackedCol.h"
#include "Bitmap.h"
/* Abstracts platform specific memory management, I/O, etc.
@ -8,16 +7,19 @@
*/
struct DrawTextArgs;
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
typedef uintptr_t SocketPtr;
typedef uintptr_t SocketHandle;
typedef void* FileHandle;
#else
typedef int SocketPtr;
typedef int SocketHandle;
typedef int FileHandle;
#endif
/* 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. */
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);
/* Returns the current UTC Time. */
/* 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. */
void DateTime_CurrentLocal(DateTime* time);
void DateTime_CurrentLocal(struct DateTime* time);
/* Takes a platform-specific stopwatch measurement. */
/* NOTE: The value returned is platform-specific - do NOT try to interpret the value. */
uint64_t Stopwatch_Measure(void);
@ -118,23 +120,23 @@ bool File_Exists(const String* path);
ReturnCode File_GetModifiedTime_MS(const String* path, TimeMS* ms);
/* 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. */
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. */
ReturnCode File_Append(void** file, const String* path);
ReturnCode File_Append(FileHandle* file, const String* path);
/* 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. */
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. */
ReturnCode File_Close(void* file);
ReturnCode File_Close(FileHandle 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. */
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. */
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. */
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);
/* 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. */
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. */
/* 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. */
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. */
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. */
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. */
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. */
ReturnCode Socket_Close(SocketPtr socket);
ReturnCode Socket_Close(SocketHandle socket);
/* 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. */
void Http_Init(void);

View File

@ -240,7 +240,7 @@ void ServerConnection_InitSingleplayer(void) {
/*########################################################################################################################*
*--------------------------------------------------Multiplayer connection-------------------------------------------------*
*#########################################################################################################################*/
static SocketPtr net_socket;
static SocketHandle net_socket;
static uint8_t net_readBuffer[4096 * 5];
static uint8_t net_writeBuffer[131];
static uint8_t* net_readCurrent;

View File

@ -108,19 +108,19 @@ static ReturnCode Stream_FileLength(struct Stream* s, uint32_t* length) {
}
ReturnCode Stream_OpenFile(struct Stream* s, const String* path) {
void* file;
FileHandle file;
ReturnCode res = File_Open(&file, path);
Stream_FromFile(s, file);
return res;
}
ReturnCode Stream_CreateFile(struct Stream* s, const String* path) {
void* file;
FileHandle file;
ReturnCode res = File_Create(&file, path);
Stream_FromFile(s, file);
return res;
}
void Stream_FromFile(struct Stream* s, void* file) {
void Stream_FromFile(struct Stream* s, FileHandle file) {
Stream_Init(s);
s->Meta.File = file;

View File

@ -1,7 +1,7 @@
#ifndef CC_STREAM_H
#define CC_STREAM_H
#include "String.h"
#include "Constants.h"
#include "Platform.h"
/* 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.
Copyright 2017 ClassicalSharp | Licensed under BSD-3
@ -29,7 +29,7 @@ struct Stream {
ReturnCode (*Close)(struct Stream* s);
union {
void* File;
FileHandle File;
void* Inflate;
/* 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;
@ -54,7 +54,7 @@ CC_EXPORT ReturnCode Stream_OpenFile(struct Stream* s, const String* path);
/* Wrapper for File_Create() then Stream_FromFile() */
CC_EXPORT ReturnCode Stream_CreateFile(struct Stream* s, const String* path);
/* 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. */
CC_EXPORT void Stream_ReadonlyPortion(struct Stream* s, struct Stream* source, uint32_t len);

View File

@ -3,6 +3,7 @@
#include "ErrorHandler.h"
#include "Platform.h"
#include "Stream.h"
#include "Utils.h"
String String_Init(STRING_REF char* buffer, int length, int capacity) {
String s;

View File

@ -21,7 +21,7 @@ static bool DateTime_IsLeapYear(int year) {
return (year % 400) == 0;
}
int DateTime_TotalDays(const DateTime* time) {
int DateTime_TotalDays(const struct DateTime* time) {
/* Days from before this year */
int y = time->Year - 1, days = 365 * y;
/* A year is a leap year when the year is: */
@ -38,7 +38,7 @@ int DateTime_TotalDays(const DateTime* time) {
return days;
}
TimeMS DateTime_TotalMs(const DateTime* time) {
TimeMS DateTime_TotalMs(const struct DateTime* time) {
int days = DateTime_TotalDays(time);
uint64_t seconds =
(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;
}
void DateTime_FromTotalMs(DateTime* time, TimeMS ms) {
void DateTime_FromTotalMs(struct DateTime* time, TimeMS ms) {
int dayMS, days, year;
int daysInYear, month;
uint16_t* totalDays;
@ -90,7 +90,7 @@ void DateTime_FromTotalMs(DateTime* time, TimeMS ms) {
void DateTime_HttpDate(TimeMS ms, String* str) {
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" };
DateTime t;
struct DateTime t;
int days;
DateTime_FromTotalMs(&t, ms);

View File

@ -8,7 +8,7 @@
/* 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. */
typedef struct DateTime_ {
struct DateTime {
int Year; /* Year, ranges from 0 to 65535 */
int Month; /* Month, ranges from 1 to 12 */
int Day; /* Day, ranges from 1 to 31 */
@ -16,12 +16,12 @@ typedef struct DateTime_ {
int Minute; /* Minute, ranges from 0 to 59 */
int Second; /* Second, ranges from 0 to 59 */
int Milli; /* Milliseconds, ranges from 0 to 999 */
} DateTime;
};
#define DATETIME_MILLIS_PER_SEC 1000
int DateTime_TotalDays(const DateTime* time);
TimeMS DateTime_TotalMs(const DateTime* time);
void DateTime_FromTotalMs(DateTime* time, TimeMS ms);
int DateTime_TotalDays(const struct DateTime* time);
TimeMS DateTime_TotalMs(const struct DateTime* time);
void DateTime_FromTotalMs(struct DateTime* time, TimeMS ms);
void DateTime_HttpDate(TimeMS ms, String* str);
CC_NOINLINE int Utils_ParseEnum(const String* text, int defValue, const char** names, int namesCount);

View File

@ -1916,21 +1916,25 @@ static void PlayerListWidget_SetColumnPos(struct PlayerListWidget* w, int column
}
static void PlayerListWidget_RepositionColumns(struct PlayerListWidget* w) {
int width = 0, centreX = Game_Width / 2;
w->YHeight = 0;
int x, y, width = 0, height;
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++) {
width += PlayerListWidget_GetColumnWidth(w, col);
int colHeight = PlayerListWidget_GetColumnHeight(w, col);
w->YHeight = max(colHeight, w->YHeight);
height = PlayerListWidget_GetColumnHeight(w, col);
w->YHeight = max(height, w->YHeight);
}
if (width < 480) width = 480;
w->XMin = centreX - width / 2;
w->XMax = centreX + width / 2;
w->XMin = Game_Width / 2 - 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++) {
PlayerListWidget_SetColumnPos(w, col, x, y);
x += PlayerListWidget_GetColumnWidth(w, col);

View File

@ -115,12 +115,14 @@ static void Window_ResetWindowState(void) {
static bool win_hiddenBorder;
static void Window_DoSetHiddenBorder(bool value) {
bool wasVisible;
RECT rect;
if (win_hiddenBorder == value) return;
/* 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
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,
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);
/* 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.right = rect.left + Window_Bounds.Width;
rect.bottom = rect.top + Window_Bounds.Height;
AdjustWindowRect(&rect, style, false);
/* 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);
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
already visible (invisible windows will change borders when
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);
}
@ -166,15 +167,19 @@ static void Window_UpdateClientSize(HWND handle) {
}
static LRESULT CALLBACK Window_Procedure(HWND handle, UINT message, WPARAM wParam, LPARAM lParam) {
char keyChar;
bool wasFocused;
float wheelDelta;
switch (message) {
case WM_ACTIVATE:
{
bool wasFocused = Window_Focused;
wasFocused = Window_Focused;
Window_Focused = LOWORD(wParam) != 0;
if (Window_Focused != wasFocused) {
Event_RaiseVoid(&WindowEvents_FocusChanged);
}
} break;
break;
case WM_ENTERMENULOOP:
case WM_ENTERSIZEMOVE:
@ -238,31 +243,24 @@ static LRESULT CALLBACK Window_Procedure(HWND handle, UINT message, WPARAM wPara
case WM_CHAR:
{
char keyChar;
if (Convert_TryUnicodeToCP437((Codepoint)wParam, &keyChar)) {
Event_RaiseInt(&KeyEvents_Press, keyChar);
}
} break;
break;
case WM_MOUSEMOVE:
{
/* set before position change, in case mouse buttons changed when outside window */
Mouse_SetPressed(MouseButton_Left, (wParam & 0x01) != 0);
Mouse_SetPressed(MouseButton_Right, (wParam & 0x02) != 0);
Mouse_SetPressed(MouseButton_Middle, (wParam & 0x10) != 0);
/* TODO: do we need to set XBUTTON1 / XBUTTON 2 here */
WORD mouse_x = LOWORD(lParam);
WORD mouse_y = HIWORD(lParam);
Mouse_SetPosition(mouse_x, mouse_y);
} break;
/* TODO: do we need to set XBUTTON1/XBUTTON2 here */
Mouse_SetPosition(LOWORD(lParam), HIWORD(lParam));
break;
case WM_MOUSEWHEEL:
{
float wheel_delta = ((short)HIWORD(wParam)) / (float)WHEEL_DELTA;
Mouse_SetWheel(Mouse_Wheel + wheel_delta);
} return 0;
wheelDelta = ((short)HIWORD(wParam)) / (float)WHEEL_DELTA;
Mouse_SetWheel(Mouse_Wheel + wheelDelta);
return 0;
case WM_LBUTTONDOWN:
Mouse_SetPressed(MouseButton_Left, true);