mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-09-16 11:06:06 -04:00
C client: Simplify audio/http API
This commit is contained in:
parent
cac5978407
commit
e0e0326a98
@ -39,19 +39,20 @@ namespace SharpWave {
|
||||
Play();
|
||||
}
|
||||
|
||||
bool BufferBlock(AudioChunk tmp, AudioFormat fmt, IEnumerator<AudioChunk> chunks) {
|
||||
// decode up to around a second
|
||||
int secondSize = fmt.SampleRate * fmt.Channels * sizeof(short);
|
||||
tmp.Length = 0;
|
||||
bool BufferBlock(int i, AudioChunk tmp, int size, IEnumerator<AudioChunk> chunks) {
|
||||
tmp.Length = 0;
|
||||
bool end = false;
|
||||
|
||||
while (tmp.Length < secondSize) {
|
||||
if (!chunks.MoveNext()) return true;
|
||||
while (tmp.Length < size) {
|
||||
if (!chunks.MoveNext()) { end = true; break; }
|
||||
AudioChunk src = chunks.Current;
|
||||
|
||||
Buffer.BlockCopy(src.Data, 0, tmp.Data, tmp.Length, src.Length);
|
||||
tmp.Length += src.Length;
|
||||
}
|
||||
return false;
|
||||
|
||||
BufferData(i, tmp);
|
||||
return end;
|
||||
}
|
||||
|
||||
public void PlayStreaming(Stream stream) {
|
||||
@ -64,19 +65,19 @@ namespace SharpWave {
|
||||
|
||||
// largest possible vorbis frame decodes to blocksize1 samples
|
||||
// so we may end up decoding slightly over a second of audio
|
||||
int chunkSize = (fmt.SampleRate + 8192) * fmt.Channels * sizeof(short);
|
||||
int chunkSize = (fmt.SampleRate + 8192) * fmt.Channels * sizeof(short);
|
||||
int secondSize = fmt.SampleRate * fmt.Channels * sizeof(short);
|
||||
byte[][] data = new byte[NumBuffers][];
|
||||
for (int i = 0; i < NumBuffers; i++) { data[i] = new byte[chunkSize]; }
|
||||
|
||||
bool reachedEnd = false;
|
||||
for (int i = 0; i < NumBuffers && !reachedEnd; i++) {
|
||||
bool end = false;
|
||||
for (int i = 0; i < NumBuffers && !end; i++) {
|
||||
tmp.Data = data[i];
|
||||
reachedEnd = BufferBlock(tmp, fmt, chunks);
|
||||
BufferData(i, tmp);
|
||||
end = BufferBlock(i, tmp, secondSize, chunks);
|
||||
}
|
||||
Play();
|
||||
|
||||
for (; !reachedEnd;) {
|
||||
for (; !end;) {
|
||||
int next = -1;
|
||||
for (int i = 0; i < NumBuffers; i++) {
|
||||
if (IsCompleted(i)) { next = i; break; }
|
||||
@ -86,8 +87,7 @@ namespace SharpWave {
|
||||
if (pendingStop) break;
|
||||
|
||||
tmp.Data = data[next];
|
||||
reachedEnd = BufferBlock(tmp, fmt, chunks);
|
||||
BufferData(next, tmp);
|
||||
end = BufferBlock(next, tmp, secondSize, chunks);
|
||||
}
|
||||
|
||||
while (!IsFinished()) { Thread.Sleep(10); }
|
||||
|
@ -82,8 +82,8 @@ static void AsyncDownloader_Add(String* url, bool priority, String* id, UInt8 ty
|
||||
Mutex_Lock(async_pendingMutex);
|
||||
{
|
||||
struct AsyncRequest req = { 0 };
|
||||
String reqUrl = String_FromArray(req.URL); String_Set(&reqUrl, url);
|
||||
String reqID = String_FromArray(req.ID); String_Set(&reqID, id);
|
||||
String reqUrl = String_FromArray(req.URL); String_Copy(&reqUrl, url);
|
||||
String reqID = String_FromArray(req.ID); String_Copy(&reqID, id);
|
||||
req.RequestType = type;
|
||||
|
||||
Platform_Log2("Adding %s (type %b)", &reqUrl, &type);
|
||||
@ -92,7 +92,7 @@ static void AsyncDownloader_Add(String* url, bool priority, String* id, UInt8 ty
|
||||
req.LastModified = *lastModified;
|
||||
}
|
||||
if (etag) {
|
||||
String reqEtag = String_FromArray(req.Etag); String_Set(&reqEtag, etag);
|
||||
String reqEtag = String_FromArray(req.Etag); String_Copy(&reqEtag, etag);
|
||||
}
|
||||
/* request.Data = data; TODO: Implement this. do we need to copy or expect caller to malloc it? */
|
||||
|
||||
@ -112,7 +112,7 @@ void AsyncDownloader_GetSkin(STRING_PURE String* id, STRING_PURE String* skinNam
|
||||
String url = String_FromArray(urlBuffer);
|
||||
|
||||
if (Utils_IsUrlPrefix(skinName, 0)) {
|
||||
String_Set(&url, skinName);
|
||||
String_Copy(&url, skinName);
|
||||
} else {
|
||||
String_AppendString(&url, &async_skinServer);
|
||||
String_AppendColorless(&url, skinName);
|
||||
@ -192,43 +192,20 @@ bool AsyncDownloader_GetCurrent(struct AsyncRequest* request, Int32* progress) {
|
||||
static void AsyncDownloader_ProcessRequest(struct AsyncRequest* request) {
|
||||
String url = String_FromRawArray(request->URL);
|
||||
Platform_Log2("Downloading from %s (type %b)", &url, &request->RequestType);
|
||||
struct Stopwatch stopwatch; UInt32 elapsedMS;
|
||||
struct Stopwatch stopwatch;
|
||||
|
||||
void* handle;
|
||||
ReturnCode res;
|
||||
Stopwatch_Start(&stopwatch);
|
||||
res = Http_MakeRequest(request, &handle);
|
||||
elapsedMS = Stopwatch_ElapsedMicroseconds(&stopwatch) / 1000;
|
||||
Platform_Log2("HTTP make request: ret code %i, in %i ms", &res, &elapsedMS);
|
||||
if (res) return;
|
||||
ReturnCode res = Http_Do(request, &async_curProgress);
|
||||
UInt32 elapsed = Stopwatch_ElapsedMicroseconds(&stopwatch) / 1000;
|
||||
|
||||
async_curProgress = ASYNC_PROGRESS_FETCHING_DATA;
|
||||
UInt32 size = 0;
|
||||
Stopwatch_Start(&stopwatch);
|
||||
res = Http_GetRequestHeaders(request, handle, &size);
|
||||
elapsedMS = Stopwatch_ElapsedMicroseconds(&stopwatch) / 1000;
|
||||
UInt32 status = request->StatusCode;
|
||||
Platform_Log3("HTTP get headers: ret code %i (http %i), in %i ms", &res, &status, &elapsedMS);
|
||||
Platform_Log3("HTTP: return code %i (http %i), in %i ms", &res, &status, &elapsed);
|
||||
|
||||
if (res || request->StatusCode != 200) {
|
||||
Http_FreeRequest(handle); return;
|
||||
if (request->ResultData) {
|
||||
UInt32 size = request->ResultSize;
|
||||
UInt64 addr = (UInt64)request->ResultData;
|
||||
Platform_Log2("HTTP returned data: %i bytes at %x", &size, &addr);
|
||||
}
|
||||
|
||||
void* data = NULL;
|
||||
if (request->RequestType != REQUEST_TYPE_CONTENT_LENGTH) {
|
||||
Stopwatch_Start(&stopwatch);
|
||||
res = Http_GetRequestData(request, handle, &data, size, &async_curProgress);
|
||||
elapsedMS = Stopwatch_ElapsedMicroseconds(&stopwatch) / 1000;
|
||||
Platform_Log3("HTTP get data: ret code %i (size %i), in %i ms", &res, &size, &elapsedMS);
|
||||
}
|
||||
|
||||
Http_FreeRequest(handle);
|
||||
if (res) return;
|
||||
|
||||
UInt64 addr = (UInt64)data;
|
||||
Platform_Log2("OK I got the DATA! %i bytes at %x", &size, &addr);
|
||||
request->ResultData = data;
|
||||
request->ResultSize = size;
|
||||
}
|
||||
|
||||
static void AsyncDownloader_CompleteResult(struct AsyncRequest* request) {
|
||||
|
47
src/Audio.c
47
src/Audio.c
@ -148,7 +148,7 @@ static void Soundboard_Init(struct Soundboard* board, STRING_PURE String* boardN
|
||||
|
||||
group = &board->Groups[board->Count++];
|
||||
group->Name = String_ClearedArray(group->NameBuffer);
|
||||
String_Set(&group->Name, &name);
|
||||
String_Copy(&group->Name, &name);
|
||||
}
|
||||
|
||||
if (group->Count == Array_Elems(group->Sounds)) {
|
||||
@ -211,7 +211,8 @@ static void Sounds_PlayRaw(struct SoundOutput* output, struct Sound* snd, struct
|
||||
}
|
||||
}
|
||||
|
||||
Audio_PlayData(output->Handle, 0, buffer, snd->DataSize);
|
||||
Audio_BufferData(output->Handle, 0, buffer, snd->DataSize);
|
||||
Audio_Play(output->Handle);
|
||||
/* TODO: handle errors here */
|
||||
}
|
||||
|
||||
@ -320,6 +321,23 @@ void* music_thread;
|
||||
void* music_waitable;
|
||||
volatile bool music_pendingStop;
|
||||
|
||||
static ReturnCode Music_BufferBlock(Int32 i, Int16* data, Int32 maxSamples, struct VorbisState* ctx) {
|
||||
Int32 samples = 0;
|
||||
ReturnCode res = 0;
|
||||
|
||||
while (samples < maxSamples) {
|
||||
res = Vorbis_DecodeFrame(ctx);
|
||||
if (res) break;
|
||||
|
||||
Int16* cur = &data[samples];
|
||||
samples += Vorbis_OutputFrame(ctx, cur);
|
||||
}
|
||||
|
||||
if (Game_MusicVolume < 100) { Volume_Mix16(data, samples, Game_MusicVolume); }
|
||||
Audio_BufferData(music_out, i, data, samples * sizeof(Int16));
|
||||
return res;
|
||||
}
|
||||
|
||||
static ReturnCode Music_PlayOgg(struct Stream* source) {
|
||||
UInt8 buffer[OGG_BUFFER_SIZE];
|
||||
struct Stream stream;
|
||||
@ -338,12 +356,19 @@ static ReturnCode Music_PlayOgg(struct Stream* source) {
|
||||
|
||||
/* largest possible vorbis frame decodes to blocksize1 * channels samples */
|
||||
/* so we may end up decoding slightly over a second of audio */
|
||||
Int32 chunkSize = fmt.Channels * (fmt.SampleRate + vorbis.BlockSizes[1]);
|
||||
Int32 i, chunkSize = fmt.Channels * (fmt.SampleRate + vorbis.BlockSizes[1]);
|
||||
Int32 samplesPerSecond = fmt.Channels * fmt.SampleRate;
|
||||
Int16* data = Mem_Alloc(chunkSize * AUDIO_MAX_CHUNKS, sizeof(Int16), "Ogg - final PCM output");
|
||||
|
||||
/* fill up with some samples before playing */
|
||||
for (i = 0; i < AUDIO_MAX_CHUNKS && !res; i++) {
|
||||
Int16* base = data + (chunkSize * i);
|
||||
res = Music_BufferBlock(i, base, samplesPerSecond, &vorbis);
|
||||
}
|
||||
Audio_Play(music_out);
|
||||
|
||||
for (;;) {
|
||||
Int32 i, next = -1;
|
||||
Int32 next = -1;
|
||||
for (i = 0; i < AUDIO_MAX_CHUNKS; i++) {
|
||||
if (Audio_IsCompleted(music_out, i)) { next = i; break; }
|
||||
}
|
||||
@ -351,20 +376,8 @@ static ReturnCode Music_PlayOgg(struct Stream* source) {
|
||||
if (next == -1) { Thread_Sleep(10); continue; }
|
||||
if (music_pendingStop) break;
|
||||
|
||||
/* decode up to around a second */
|
||||
Int16* base = data + (chunkSize * next);
|
||||
Int32 samples = 0;
|
||||
|
||||
while (samples < samplesPerSecond) {
|
||||
res = Vorbis_DecodeFrame(&vorbis);
|
||||
if (res) break;
|
||||
|
||||
Int16* cur = &base[samples];
|
||||
samples += Vorbis_OutputFrame(&vorbis, cur);
|
||||
}
|
||||
|
||||
if (Game_MusicVolume < 100) { Volume_Mix16(base, samples, Game_MusicVolume); }
|
||||
Audio_PlayData(music_out, next, base, samples * sizeof(Int16));
|
||||
res = Music_BufferBlock(next, base, samplesPerSecond, &vorbis);
|
||||
/* need to specially handle last bit of audio */
|
||||
if (res) break;
|
||||
}
|
||||
|
@ -116,7 +116,7 @@ void Game_GetDefaultTexturePack(STRING_TRANSIENT String* texPack) {
|
||||
}
|
||||
|
||||
void Game_SetDefaultTexturePack(STRING_PURE String* texPack) {
|
||||
String_Set(&game_defTexPack, texPack);
|
||||
String_Copy(&game_defTexPack, texPack);
|
||||
Options_Set(OPT_DEFAULT_TEX_PACK, texPack);
|
||||
}
|
||||
|
||||
|
12
src/Menus.c
12
src/Menus.c
@ -1307,7 +1307,7 @@ static void SaveLevelScreen_DoSave(struct GuiElem* elem, struct GuiElem* widget,
|
||||
String warnMsg = String_FromConst("Saving..");
|
||||
SaveLevelScreen_MakeDesc(screen, &warnMsg);
|
||||
|
||||
String_Set(&screen->TextPath, &path);
|
||||
String_Copy(&screen->TextPath, &path);
|
||||
SaveLevelScreen_RemoveOverwrites(screen);
|
||||
}
|
||||
}
|
||||
@ -1495,7 +1495,7 @@ static void FontListScreen_EntryClick(struct GuiElem* elem, struct GuiElem* w) {
|
||||
String fontName = ListScreen_UNSAFE_GetCur(screen, w);
|
||||
if (String_CaselessEqualsConst(&fontName, LIST_SCREEN_EMPTY)) return;
|
||||
|
||||
String_Set(&Game_FontName, &fontName);
|
||||
String_Copy(&Game_FontName, &fontName);
|
||||
Options_Set(OPT_FONT_NAME, &fontName);
|
||||
|
||||
Int32 cur = screen->CurrentIndex;
|
||||
@ -2494,14 +2494,14 @@ static void GraphicsOptionsScreen_SetMipmaps(STRING_PURE String* v) {
|
||||
Gfx_Mipmaps = Menu_SetBool(v, OPT_MIPMAPS);
|
||||
char urlBuffer[STRING_SIZE];
|
||||
String url = String_FromArray(urlBuffer);
|
||||
String_Set(&url, &World_TextureUrl);
|
||||
String_Copy(&url, &World_TextureUrl);
|
||||
|
||||
/* always force a reload from cache */
|
||||
World_TextureUrl.length = 0;
|
||||
String_AppendConst(&World_TextureUrl, "~`#$_^*()@");
|
||||
TexturePack_ExtractCurrent(&url);
|
||||
|
||||
String_Set(&World_TextureUrl, &url);
|
||||
String_Copy(&World_TextureUrl, &url);
|
||||
}
|
||||
|
||||
static void GraphicsOptionsScreen_ContextRecreated(void* obj) {
|
||||
@ -3237,7 +3237,7 @@ struct Screen* UrlWarningOverlay_MakeInstance(STRING_PURE String* url) {
|
||||
Array_Elems(widgets), UrlWarningOverlay_ContextRecreated);
|
||||
|
||||
String dstUrl = String_FromArray(screen->__UrlBuffer);
|
||||
String_Set(&dstUrl, url);
|
||||
String_Copy(&dstUrl, url);
|
||||
screen->Url = dstUrl;
|
||||
|
||||
Overlay_UseVTABLE((struct MenuScreen*)screen, &WarningOverlay_VTABLE);
|
||||
@ -3294,7 +3294,7 @@ struct Screen* ConfirmDenyOverlay_MakeInstance(STRING_PURE String* url, bool alw
|
||||
Array_Elems(widgets), ConfirmDenyOverlay_ContextRecreated);
|
||||
|
||||
String dstUrl = String_FromArray(screen->__UrlBuffer);
|
||||
String_Set(&dstUrl, url);
|
||||
String_Copy(&dstUrl, url);
|
||||
screen->Url = dstUrl;
|
||||
screen->AlwaysDeny = alwaysDeny;
|
||||
|
||||
|
@ -222,7 +222,7 @@ void Window_GetClipboardText(STRING_TRANSIENT String* value) {
|
||||
for (i = 0; i < 10; i++) {
|
||||
Window_ProcessEvents();
|
||||
if (clipboard_paste_text.length) {
|
||||
String_Set(value, &clipboard_paste_text);
|
||||
String_Copy(value, &clipboard_paste_text);
|
||||
return;
|
||||
} else {
|
||||
Thread_Sleep(100);
|
||||
@ -231,7 +231,7 @@ void Window_GetClipboardText(STRING_TRANSIENT String* value) {
|
||||
}
|
||||
|
||||
void Window_SetClipboardText(STRING_PURE String* value) {
|
||||
String_Set(&clipboard_paste_text, value);
|
||||
String_Copy(&clipboard_paste_text, value);
|
||||
XSetSelectionOwner(win_display, xa_clipboard, win_handle, 0);
|
||||
}
|
||||
|
||||
|
@ -102,8 +102,8 @@ static void Handlers_CheckName(EntityID id, STRING_TRANSIENT String* displayName
|
||||
String nameNoCols = String_FromArray(nameNoColsBuffer);
|
||||
String_AppendColorless(&nameNoCols, displayName);
|
||||
|
||||
if (!String_Equals(&nameNoCols, &Game_Username)) { String_Set(displayName, &Game_Username); }
|
||||
if (!skinName->length) { String_Set(skinName, &Game_Username); }
|
||||
if (!String_Equals(&nameNoCols, &Game_Username)) { String_Copy(displayName, &Game_Username); }
|
||||
if (!skinName->length) { String_Copy(skinName, &Game_Username); }
|
||||
}
|
||||
|
||||
static void Classic_ReadAbsoluteLocation(UInt8* data, EntityID id, bool interpolate);
|
||||
@ -125,9 +125,9 @@ static void Handlers_AddEntity(UInt8* data, EntityID id, STRING_TRANSIENT String
|
||||
p->FetchedSkin = false;
|
||||
|
||||
String player_name = String_ClearedArray(p->DisplayNameRaw);
|
||||
String_Set(&player_name, displayName);
|
||||
String_Copy(&player_name, displayName);
|
||||
String player_skin = String_ClearedArray(p->SkinNameRaw);
|
||||
String_Set(&player_skin, skinName);
|
||||
String_Copy(&player_skin, skinName);
|
||||
Player_UpdateName((struct Player*)p);
|
||||
}
|
||||
|
||||
@ -381,7 +381,7 @@ static void Classic_Handshake(UInt8* data) {
|
||||
struct HacksComp* hacks = &LocalPlayer_Instance.Hacks;
|
||||
HacksComp_SetUserType(hacks, *data, !cpe_blockPerms);
|
||||
|
||||
String_Set(&hacks->HacksFlags, &ServerConnection_ServerName);
|
||||
String_Copy(&hacks->HacksFlags, &ServerConnection_ServerName);
|
||||
String_AppendString(&hacks->HacksFlags, &ServerConnection_ServerMOTD);
|
||||
HacksComp_UpdateState(hacks);
|
||||
}
|
||||
|
@ -862,28 +862,33 @@ ReturnCode Socket_Select(SocketPtr socket, Int32 selectMode, bool* success) {
|
||||
*#########################################################################################################################*/
|
||||
#if CC_BUILD_WIN
|
||||
HINTERNET hInternet;
|
||||
/* TODO: Test last modified and etag even work */
|
||||
#define FLAG_STATUS HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER
|
||||
#define FLAG_LENGTH HTTP_QUERY_CONTENT_LENGTH | HTTP_QUERY_FLAG_NUMBER
|
||||
#define FLAG_LASTMOD HTTP_QUERY_LAST_MODIFIED | HTTP_QUERY_FLAG_SYSTEMTIME
|
||||
|
||||
void Http_Init(void) {
|
||||
/* TODO: Should we use INTERNET_OPEN_TYPE_PRECONFIG instead? */
|
||||
hInternet = InternetOpenA(PROGRAM_APP_NAME, INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
|
||||
if (!hInternet) ErrorHandler_FailWithCode(GetLastError(), "Failed to init WinINet");
|
||||
}
|
||||
|
||||
ReturnCode Http_MakeRequest(struct AsyncRequest* request, void** handle) {
|
||||
String url = String_FromRawArray(request->URL);
|
||||
static ReturnCode Http_Make(struct AsyncRequest* req, HINTERNET* handle) {
|
||||
String url = String_FromRawArray(req->URL);
|
||||
char headersBuffer[STRING_SIZE * 2];
|
||||
String headers = String_MakeNull();
|
||||
|
||||
/* https://stackoverflow.com/questions/25308488/c-wininet-custom-http-headers */
|
||||
if (request->Etag[0] || request->LastModified.Year) {
|
||||
if (req->Etag[0] || req->LastModified.Year) {
|
||||
headers = String_ClearedArray(headersBuffer);
|
||||
if (request->LastModified.Year) {
|
||||
if (req->LastModified.Year) {
|
||||
String_AppendConst(&headers, "If-Modified-Since: ");
|
||||
DateTime_HttpDate(&request->LastModified, &headers);
|
||||
DateTime_HttpDate(&req->LastModified, &headers);
|
||||
String_AppendConst(&headers, "\r\n");
|
||||
}
|
||||
|
||||
if (request->Etag[0]) {
|
||||
String etag = String_FromRawArray(request->Etag);
|
||||
if (req->Etag[0]) {
|
||||
String etag = String_FromRawArray(req->Etag);
|
||||
String_AppendConst(&headers, "If-None-Match: ");
|
||||
String_AppendString(&headers, &etag);
|
||||
String_AppendConst(&headers, "\r\n");
|
||||
@ -896,39 +901,38 @@ ReturnCode Http_MakeRequest(struct AsyncRequest* request, void** handle) {
|
||||
return Win_Return(*handle);
|
||||
}
|
||||
|
||||
/* TODO: Test last modified and etag even work */
|
||||
#define Http_Query(flags, result) HttpQueryInfoA(handle, flags, result, &bufferLen, NULL)
|
||||
ReturnCode Http_GetRequestHeaders(struct AsyncRequest* request, void* handle, UInt32* size) {
|
||||
DWORD bufferLen;
|
||||
static ReturnCode Http_GetHeaders(struct AsyncRequest* req, HINTERNET handle) {
|
||||
DWORD len;
|
||||
|
||||
UInt32 status;
|
||||
bufferLen = sizeof(DWORD);
|
||||
if (!Http_Query(HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER, &status)) return GetLastError();
|
||||
request->StatusCode = status;
|
||||
len = sizeof(DWORD);
|
||||
if (!HttpQueryInfoA(handle, FLAG_STATUS, &status, &len, NULL)) return GetLastError();
|
||||
req->StatusCode = status;
|
||||
|
||||
bufferLen = sizeof(DWORD);
|
||||
if (!Http_Query(HTTP_QUERY_CONTENT_LENGTH | HTTP_QUERY_FLAG_NUMBER, size)) return GetLastError();
|
||||
len = sizeof(DWORD);
|
||||
if (!HttpQueryInfoA(handle, FLAG_LENGTH, &req->ResultSize, &len, NULL)) return GetLastError();
|
||||
|
||||
SYSTEMTIME lastModified;
|
||||
bufferLen = sizeof(SYSTEMTIME);
|
||||
if (Http_Query(HTTP_QUERY_LAST_MODIFIED | HTTP_QUERY_FLAG_SYSTEMTIME, &lastModified)) {
|
||||
Platform_FromSysTime(&request->LastModified, &lastModified);
|
||||
SYSTEMTIME time;
|
||||
len = sizeof(SYSTEMTIME);
|
||||
if (HttpQueryInfoA(handle, FLAG_LASTMOD, &time, &len, NULL)) {
|
||||
Platform_FromSysTime(&req->LastModified, &time);
|
||||
}
|
||||
|
||||
String etag = String_ClearedArray(request->Etag);
|
||||
bufferLen = etag.capacity;
|
||||
Http_Query(HTTP_QUERY_ETAG, etag.buffer);
|
||||
String etag = String_ClearedArray(req->Etag);
|
||||
len = etag.capacity;
|
||||
HttpQueryInfoA(handle, HTTP_QUERY_ETAG, etag.buffer, &len, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
ReturnCode Http_GetRequestData(struct AsyncRequest* request, void* handle, void** data, UInt32 size, volatile Int32* progress) {
|
||||
if (!size) return ERROR_NOT_SUPPORTED;
|
||||
static ReturnCode Http_GetData(struct AsyncRequest* req, HINTERNET handle, volatile Int32* progress) {
|
||||
UInt32 size = req->ResultSize;
|
||||
if (size) return ERROR_NOT_SUPPORTED;
|
||||
*progress = 0;
|
||||
|
||||
UInt8* buffer = Mem_Alloc(size, sizeof(UInt8), "http get data");
|
||||
UInt32 left = size, read, totalRead = 0;
|
||||
*data = buffer;
|
||||
UInt32 left = size, read, totalRead = 0;
|
||||
req->ResultData = buffer;
|
||||
|
||||
while (left) {
|
||||
UInt32 toRead = left, avail = 0;
|
||||
@ -949,7 +953,23 @@ ReturnCode Http_GetRequestData(struct AsyncRequest* request, void* handle, void*
|
||||
return 0;
|
||||
}
|
||||
|
||||
ReturnCode Http_FreeRequest(void* handle) { return Win_Return(InternetCloseHandle(handle)); }
|
||||
ReturnCode Http_Do(struct AsyncRequest* req, volatile Int32* progress) {
|
||||
HINTERNET handle;
|
||||
ReturnCode res = Http_Make(req, &handle);
|
||||
if (res) return res;
|
||||
|
||||
*progress = ASYNC_PROGRESS_FETCHING_DATA;
|
||||
res = Http_GetHeaders(req, handle);
|
||||
if (res) { InternetCloseHandle(handle); return res; }
|
||||
|
||||
if (req->RequestType != REQUEST_TYPE_CONTENT_LENGTH && req->StatusCode == 200) {
|
||||
res = Http_GetData(req, handle, progress);
|
||||
if (res) { InternetCloseHandle(handle); return res; }
|
||||
}
|
||||
|
||||
return Win_Return(InternetCloseHandle(handle));
|
||||
}
|
||||
|
||||
ReturnCode Http_Free(void) { return Win_Return(InternetCloseHandle(hInternet)); }
|
||||
#elif CC_BUILD_NIX
|
||||
void Http_Init(void) { }
|
||||
@ -1028,7 +1048,7 @@ void Audio_SetFormat(AudioHandle handle, struct AudioFormat* format) {
|
||||
ctx->Format = *format;
|
||||
}
|
||||
|
||||
void Audio_PlayData(AudioHandle handle, Int32 idx, void* data, UInt32 dataSize) {
|
||||
void Audio_BufferData(AudioHandle handle, Int32 idx, void* data, UInt32 dataSize) {
|
||||
struct AudioContext* ctx = &Audio_Contexts[handle];
|
||||
WAVEHDR* hdr = &ctx->Headers[idx];
|
||||
Mem_Set(hdr, 0, sizeof(WAVEHDR));
|
||||
@ -1043,6 +1063,8 @@ void Audio_PlayData(AudioHandle handle, Int32 idx, void* data, UInt32 dataSize)
|
||||
ErrorHandler_CheckOrFail(result, "Audio - write header");
|
||||
}
|
||||
|
||||
void Audio_Play(AudioHandle handle) { }
|
||||
|
||||
bool Audio_IsCompleted(AudioHandle handle, Int32 idx) {
|
||||
struct AudioContext* ctx = &Audio_Contexts[handle];
|
||||
WAVEHDR* hdr = &ctx->Headers[idx];
|
||||
|
@ -80,15 +80,15 @@ void Thread_Join(void* handle);
|
||||
void Thread_FreeHandle(void* handle);
|
||||
|
||||
void* Mutex_Create(void);
|
||||
void Mutex_Free(void* handle);
|
||||
void Mutex_Lock(void* handle);
|
||||
void Mutex_Unlock(void* handle);
|
||||
void Mutex_Free(void* handle);
|
||||
void Mutex_Lock(void* handle);
|
||||
void Mutex_Unlock(void* handle);
|
||||
|
||||
void* Waitable_Create(void);
|
||||
void Waitable_Free(void* handle);
|
||||
void Waitable_Signal(void* handle);
|
||||
void Waitable_Wait(void* handle);
|
||||
void Waitable_WaitFor(void* handle, UInt32 milliseconds);
|
||||
void Waitable_Free(void* handle);
|
||||
void Waitable_Signal(void* handle);
|
||||
void Waitable_Wait(void* handle);
|
||||
void Waitable_WaitFor(void* handle, UInt32 milliseconds);
|
||||
|
||||
void Font_GetNames(StringsBuffer* buffer);
|
||||
void Font_Make(struct FontDesc* desc, STRING_PURE String* fontName, UInt16 size, UInt16 style);
|
||||
@ -110,10 +110,7 @@ ReturnCode Socket_Close(SocketPtr socket);
|
||||
ReturnCode Socket_Select(SocketPtr socket, Int32 selectMode, bool* success);
|
||||
|
||||
void Http_Init(void);
|
||||
ReturnCode Http_MakeRequest(struct AsyncRequest* request, void** handle);
|
||||
ReturnCode Http_GetRequestHeaders(struct AsyncRequest* request, void* handle, UInt32* size);
|
||||
ReturnCode Http_GetRequestData(struct AsyncRequest* request, void* handle, void** data, UInt32 size, volatile Int32* progress);
|
||||
ReturnCode Http_FreeRequest(void* handle);
|
||||
ReturnCode Http_Do(struct AsyncRequest* req, volatile Int32* progress);
|
||||
ReturnCode Http_Free(void);
|
||||
|
||||
#define AUDIO_MAX_CHUNKS 4
|
||||
@ -126,7 +123,8 @@ void Audio_Free(AudioHandle handle);
|
||||
struct AudioFormat* Audio_GetFormat(AudioHandle handle);
|
||||
void Audio_SetFormat(AudioHandle handle, struct AudioFormat* format);
|
||||
void Audio_SetVolume(AudioHandle handle, Real32 volume);
|
||||
void Audio_PlayData(AudioHandle handle, Int32 idx, void* data, UInt32 dataSize);
|
||||
void Audio_BufferData(AudioHandle handle, Int32 idx, void* data, UInt32 dataSize);
|
||||
void Audio_Play(AudioHandle handle);
|
||||
bool Audio_IsCompleted(AudioHandle handle, Int32 idx);
|
||||
bool Audio_IsFinished(AudioHandle handle);
|
||||
#endif
|
||||
|
@ -92,7 +92,7 @@ int main(void) {
|
||||
String title = String_FromConst(PROGRAM_APP_NAME);
|
||||
String rawArgs = Platform_GetCommandLineArgs();
|
||||
/* NOTE: Make sure to comment this out before pushing a commit */
|
||||
rawArgs = String_FromReadonly("UnknownShadow200 fff 127.0.0.1 25565");
|
||||
//rawArgs = String_FromReadonly("UnknownShadow200 fff 127.0.0.1 25565");
|
||||
|
||||
String args[5]; Int32 argsCount = Array_Elems(args);
|
||||
String_UNSAFE_Split(&rawArgs, ' ', args, &argsCount);
|
||||
@ -100,14 +100,14 @@ int main(void) {
|
||||
if (argsCount == 1) {
|
||||
String name = args[0];
|
||||
if (!name.length) name = String_FromReadonly("Singleplayer");
|
||||
String_Set(&Game_Username, &name);
|
||||
String_Copy(&Game_Username, &name);
|
||||
} else if (argsCount < 4) {
|
||||
Platform_LogConst("ClassiCube.exe is only the raw client. You must either use the launcher or provide command line arguments to start the client.");
|
||||
return 1;
|
||||
} else {
|
||||
String_Set(&Game_Username, &args[0]);
|
||||
String_Set(&Game_Mppass, &args[1]);
|
||||
String_Set(&Game_IPAddress, &args[2]);
|
||||
String_Copy(&Game_Username, &args[0]);
|
||||
String_Copy(&Game_Mppass, &args[1]);
|
||||
String_Copy(&Game_IPAddress, &args[2]);
|
||||
|
||||
UInt8 ip[4];
|
||||
if (!Utils_ParseIP(&args[2], ip)) {
|
||||
|
@ -743,7 +743,7 @@ static void ChatScreen_OpenInput(struct ChatScreen* screen, STRING_PURE String*
|
||||
ChatScreen_SetHandlesAllInput(screen, true);
|
||||
Key_KeyRepeat = true;
|
||||
|
||||
String_Set(&screen->Input.Base.Text, initialText);
|
||||
String_Copy(&screen->Input.Base.Text, initialText);
|
||||
Elem_Recreate(&screen->Input.Base);
|
||||
}
|
||||
|
||||
@ -1071,7 +1071,7 @@ static void ChatScreen_ChatReceived(void* obj, String* msg, Int32 type) {
|
||||
static void ChatScreen_ContextLost(void* obj) {
|
||||
struct ChatScreen* screen = (struct ChatScreen*)obj;
|
||||
if (screen->HandlesAllInput) {
|
||||
String_Set(&screen->ChatInInputStr, &screen->Input.Base.Text);
|
||||
String_Copy(&screen->ChatInInputStr, &screen->Input.Base.Text);
|
||||
Gui_CalcCursorVisible();
|
||||
}
|
||||
|
||||
|
@ -321,8 +321,8 @@ static void MPConnection_TickConnect(void) {
|
||||
}
|
||||
|
||||
static void MPConnection_BeginConnect(void) {
|
||||
Socket_Create(&net_socket);
|
||||
Event_RegisterBlock(&UserEvents_BlockChanged, NULL, MPConnection_BlockChanged);
|
||||
Socket_Create(&net_socket);
|
||||
ServerConnection_Disconnected = false;
|
||||
|
||||
Socket_SetBlocking(net_socket, false);
|
||||
|
@ -49,9 +49,9 @@ void String_StripCols(STRING_TRANSIENT String* str) {
|
||||
}
|
||||
}
|
||||
|
||||
void String_Set(STRING_TRANSIENT String* str, STRING_PURE String* value) {
|
||||
str->length = 0;
|
||||
String_AppendString(str, value);
|
||||
void String_Copy(STRING_TRANSIENT String* dst, STRING_PURE String* src) {
|
||||
dst->length = 0;
|
||||
String_AppendString(dst, src);
|
||||
}
|
||||
|
||||
String String_UNSAFE_Substring(STRING_REF String* str, Int32 offset, Int32 length) {
|
||||
@ -684,7 +684,7 @@ void StringsBuffer_Clear(StringsBuffer* buffer) {
|
||||
|
||||
void StringsBuffer_Get(StringsBuffer* buffer, Int32 index, STRING_TRANSIENT String* text) {
|
||||
String raw = StringsBuffer_UNSAFE_Get(buffer, index);
|
||||
String_Set(text, &raw);
|
||||
String_Copy(text, &raw);
|
||||
}
|
||||
|
||||
String StringsBuffer_UNSAFE_Get(StringsBuffer* buffer, Int32 index) {
|
||||
|
@ -42,7 +42,7 @@ String String_FromReadonly(STRING_REF const char* buffer);
|
||||
#define String_FromRawArray(buffer) String_FromRaw(buffer, (UInt16)sizeof(buffer))
|
||||
|
||||
void String_StripCols(STRING_TRANSIENT String* str);
|
||||
void String_Set(STRING_TRANSIENT String* str, STRING_PURE String* value);
|
||||
void String_Copy(STRING_TRANSIENT String* dst, STRING_PURE String* src);
|
||||
/* Returns a string that points directly to a substring of the given string.
|
||||
NOTE: THIS IS UNSAFE - IT MAINTAINS A REFERENCE TO THE ORIGINAL BUFFER, AND THE SUBSTRING IS NOT NULL TERMINATED */
|
||||
String String_UNSAFE_Substring(STRING_REF String* str, Int32 offset, Int32 length);
|
||||
|
@ -478,7 +478,7 @@ void TexturePack_ExtractCurrent(STRING_PURE String* url) {
|
||||
if (String_Equals(url, &World_TextureUrl)) {
|
||||
} else {
|
||||
bool zip = String_ContainsString(url, &zipExt);
|
||||
String_Set(&World_TextureUrl, url);
|
||||
String_Copy(&World_TextureUrl, url);
|
||||
const char* operation = zip ? "extracting" : "decoding";
|
||||
|
||||
res = zip ? TexturePack_ExtractZip(&stream) :
|
||||
@ -493,7 +493,7 @@ void TexturePack_ExtractCurrent(STRING_PURE String* url) {
|
||||
|
||||
void TexturePack_Extract_Req(struct AsyncRequest* item) {
|
||||
String url = String_FromRawArray(item->URL);
|
||||
String_Set(&World_TextureUrl, &url);
|
||||
String_Copy(&World_TextureUrl, &url);
|
||||
void* data = item->ResultData;
|
||||
UInt32 len = item->ResultSize;
|
||||
|
||||
|
@ -1693,7 +1693,7 @@ static void ChatInputWidget_UpKey(struct GuiElem* elem) {
|
||||
}
|
||||
|
||||
if (widget->TypingLogPos == Chat_InputLog.Count) {
|
||||
String_Set(&widget->OrigStr, &input->Text);
|
||||
String_Copy(&widget->OrigStr, &input->Text);
|
||||
}
|
||||
|
||||
if (!Chat_InputLog.Count) return;
|
||||
@ -2213,7 +2213,7 @@ String TextGroupWidget_UNSAFE_Get(struct TextGroupWidget* widget, Int32 i) {
|
||||
|
||||
void TextGroupWidget_GetText(struct TextGroupWidget* widget, Int32 index, STRING_TRANSIENT String* text) {
|
||||
String line = TextGroupWidget_UNSAFE_Get(widget, index);
|
||||
String_Set(text, &line);
|
||||
String_Copy(text, &line);
|
||||
}
|
||||
|
||||
void TextGroupWidget_PushUpAndReplaceLast(struct TextGroupWidget* widget, STRING_PURE String* text) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user