mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-09-15 02:25:32 -04:00
WIP textures stuff
This commit is contained in:
parent
27881b6acc
commit
cbee786c99
@ -83,8 +83,8 @@ CC_API void Event_RaiseFloat(struct Event_Float* handlers, float arg);
|
||||
#define Event_RegisterFloat(handlers, obj, handler) Event_RegisterMacro(handlers, obj, handler)
|
||||
#define Event_UnregisterFloat(handlers, obj, handler) Event_UnregisterMacro(handlers, obj, handler)
|
||||
|
||||
/* Calls all registered callbacks for an event which has data stream and name argumenst. */
|
||||
/* This is (currently) only used for processing entries from default.zip */
|
||||
/* Calls all registered callbacks for an event which has data stream and name arguments. */
|
||||
/* This is (currently) only used for processing entries from texture pack zip */
|
||||
void Event_RaiseEntry(struct Event_Entry* handlers, struct Stream* stream, const String* name);
|
||||
#define Event_RegisterEntry(handlers, obj, handler) Event_RegisterMacro(handlers, obj, handler)
|
||||
#define Event_UnregisterEntry(handlers, obj, handler) Event_UnregisterMacro(handlers, obj, handler)
|
||||
|
19
src/Server.c
19
src/Server.c
@ -55,22 +55,9 @@ void Server_RetrieveTexturePack(const String* url) {
|
||||
|
||||
void Server_DownloadTexturePack(const String* url) {
|
||||
static const String texPack = String_FromConst("texturePack");
|
||||
String etag; char etagBuffer[STRING_SIZE];
|
||||
String time; char timeBuffer[STRING_SIZE];
|
||||
|
||||
if (TextureCache_HasDenied(url)) return;
|
||||
String_InitArray(etag, etagBuffer);
|
||||
String_InitArray(time, timeBuffer);
|
||||
|
||||
/* Only retrieve etag/last-modified headers if the file exists */
|
||||
/* This can occur if user decided to delete some cached files */
|
||||
if (TextureCache_Has(url)) {
|
||||
TextureCache_GetLastModified(url, &time);
|
||||
TextureCache_GetETag(url, &etag);
|
||||
}
|
||||
|
||||
TexturePack_ExtractCurrent(url);
|
||||
Http_AsyncGetDataEx(url, true, &texPack, &time, &etag);
|
||||
TexturePack_DownloadAsync(url, &texPack);
|
||||
String_Copy(&World_TextureUrl, url);
|
||||
}
|
||||
|
||||
static void Server_CheckAsyncResources(void) {
|
||||
@ -79,7 +66,9 @@ static void Server_CheckAsyncResources(void) {
|
||||
if (!Http_GetResult(&texPack, &item)) return;
|
||||
|
||||
if (item.Success) {
|
||||
TextureCache_Update(&item);
|
||||
TexturePack_Extract_Req(&item);
|
||||
HttpRequest_Free(&item);
|
||||
} else if (item.Result) {
|
||||
Chat_Add1("&cError %i when trying to download texture pack", &item.Result);
|
||||
} else {
|
||||
|
@ -569,7 +569,7 @@ bool TextureCache_Get(const String* url, struct Stream* stream) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void TexturePack_GetFromTags(const String* url, String* result, struct EntryList* list) {
|
||||
CC_NOINLINE static void TexturePack_GetFromTags(const String* url, String* result, struct EntryList* list) {
|
||||
String key, value; char keyBuffer[STRING_INT_CHARS];
|
||||
String_InitArray(key, keyBuffer);
|
||||
|
||||
@ -578,7 +578,7 @@ void TexturePack_GetFromTags(const String* url, String* result, struct EntryList
|
||||
if (value.length) String_AppendString(result, &value);
|
||||
}
|
||||
|
||||
void TextureCache_GetLastModified(const String* url, String* time) {
|
||||
static void TextureCache_GetLastModified(const String* url, String* time) {
|
||||
String entry; char entryBuffer[STRING_SIZE];
|
||||
TimeMS raw;
|
||||
|
||||
@ -593,21 +593,10 @@ void TextureCache_GetLastModified(const String* url, String* time) {
|
||||
}
|
||||
}
|
||||
|
||||
void TextureCache_GetETag(const String* url, String* etag) {
|
||||
static void TextureCache_GetETag(const String* url, String* etag) {
|
||||
TexturePack_GetFromTags(url, etag, &etagCache);
|
||||
}
|
||||
|
||||
void TextureCache_Set(const String* url, const uint8_t* data, uint32_t length) {
|
||||
String path; char pathBuffer[FILENAME_SIZE];
|
||||
ReturnCode res;
|
||||
|
||||
String_InitArray(path, pathBuffer);
|
||||
TextureCache_MakePath(&path, url);
|
||||
|
||||
res = Stream_WriteAllTo(&path, data, length);
|
||||
if (res) { Logger_Warn2(res, "caching", url); }
|
||||
}
|
||||
|
||||
CC_NOINLINE static void TextureCache_SetEntry(const String* url, const String* data, struct EntryList* list) {
|
||||
String key; char keyBuffer[STRING_INT_CHARS];
|
||||
String_InitArray(key, keyBuffer);
|
||||
@ -627,6 +616,22 @@ static void TextureCache_SetLastModified(const String* url, const String* time)
|
||||
TextureCache_SetEntry(url, time, &lastModifiedCache);
|
||||
}
|
||||
|
||||
void TextureCache_Update(struct HttpRequest* req) {
|
||||
String path, url; char pathBuffer[FILENAME_SIZE];
|
||||
ReturnCode res;
|
||||
url = String_FromRawArray(req->URL);
|
||||
|
||||
path = String_FromRawArray(req->Etag);
|
||||
TextureCache_SetETag(&url, &path);
|
||||
path = String_FromRawArray(req->LastModified);
|
||||
TextureCache_SetLastModified(&url, &path);
|
||||
|
||||
String_InitArray(path, pathBuffer);
|
||||
TextureCache_MakePath(&path, &url);
|
||||
res = Stream_WriteAllTo(&path, req->Data, req->Size);
|
||||
if (res) { Logger_Warn2(res, "caching", &url); }
|
||||
}
|
||||
|
||||
|
||||
/*########################################################################################################################*
|
||||
*-------------------------------------------------------TexturePack-------------------------------------------------------*
|
||||
@ -638,6 +643,7 @@ static ReturnCode TexturePack_ProcessZipEntry(const String* path, struct Stream*
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Extracts all the files from a stream representing a .zip archive */
|
||||
static ReturnCode TexturePack_ExtractZip(struct Stream* stream) {
|
||||
struct ZipState state;
|
||||
Event_RaiseVoid(&TextureEvents.PackChanged);
|
||||
@ -648,6 +654,21 @@ static ReturnCode TexturePack_ExtractZip(struct Stream* stream) {
|
||||
return Zip_Extract(&state);
|
||||
}
|
||||
|
||||
/* Changes the current terrain atlas from a stream representing a .png image */
|
||||
/* Raises TextureEvents.PackChanged, so behaves as a .zip with only terrain.png in it */
|
||||
static ReturnCode TexturePack_ExtractTerrainPng(struct Stream* stream) {
|
||||
Bitmap bmp;
|
||||
ReturnCode res = Png_Decode(&bmp, stream);
|
||||
|
||||
if (!res) {
|
||||
Event_RaiseVoid(&TextureEvents.PackChanged);
|
||||
if (Game_ChangeTerrainAtlas(&bmp)) return 0;
|
||||
}
|
||||
|
||||
Mem_Free(bmp.Scan0);
|
||||
return res;
|
||||
}
|
||||
|
||||
void TexturePack_ExtractZip_File(const String* filename) {
|
||||
String path; char pathBuffer[FILENAME_SIZE];
|
||||
struct Stream stream;
|
||||
@ -680,19 +701,6 @@ void TexturePack_ExtractZip_File(const String* filename) {
|
||||
#endif
|
||||
}
|
||||
|
||||
ReturnCode TexturePack_ExtractTerrainPng(struct Stream* stream) {
|
||||
Bitmap bmp;
|
||||
ReturnCode res = Png_Decode(&bmp, stream);
|
||||
|
||||
if (!res) {
|
||||
Event_RaiseVoid(&TextureEvents.PackChanged);
|
||||
if (Game_ChangeTerrainAtlas(&bmp)) return 0;
|
||||
}
|
||||
|
||||
Mem_Free(bmp.Scan0);
|
||||
return res;
|
||||
}
|
||||
|
||||
void TexturePack_ExtractDefault(void) {
|
||||
String texPack; char texPackBuffer[STRING_SIZE];
|
||||
|
||||
@ -709,9 +717,9 @@ void TexturePack_ExtractCurrent(const String* url) {
|
||||
bool zip;
|
||||
ReturnCode res = 0;
|
||||
|
||||
if (!url->length) { TexturePack_ExtractDefault(); return; }
|
||||
|
||||
if (!TextureCache_Get(url, &stream)) {
|
||||
if (!url->length) {
|
||||
TexturePack_ExtractDefault();
|
||||
} else if (!TextureCache_Get(url, &stream)) {
|
||||
/* e.g. 404 errors */
|
||||
if (World_TextureUrl.length) TexturePack_ExtractDefault();
|
||||
} else {
|
||||
@ -740,12 +748,6 @@ void TexturePack_Extract_Req(struct HttpRequest* item) {
|
||||
String_Copy(&World_TextureUrl, &url);
|
||||
data = item->Data;
|
||||
len = item->Size;
|
||||
TextureCache_Set(&url, data, len);
|
||||
|
||||
str = String_FromRawArray(item->Etag);
|
||||
TextureCache_SetETag(&url, &str);
|
||||
str = String_FromRawArray(item->LastModified);
|
||||
TextureCache_SetLastModified(&url, &str);
|
||||
|
||||
Stream_ReadonlyMemory(&mem, data, len);
|
||||
png = Png_Detect(data, len);
|
||||
@ -753,5 +755,20 @@ void TexturePack_Extract_Req(struct HttpRequest* item) {
|
||||
: TexturePack_ExtractZip(&mem);
|
||||
|
||||
if (res) Logger_Warn2(res, png ? "decoding" : "extracting", &url);
|
||||
HttpRequest_Free(item);
|
||||
}
|
||||
|
||||
void TexturePack_DownloadAsync(const String* url, const String* id) {
|
||||
String etag; char etagBuffer[STRING_SIZE];
|
||||
String time; char timeBuffer[STRING_SIZE];
|
||||
|
||||
String_InitArray(etag, etagBuffer);
|
||||
String_InitArray(time, timeBuffer);
|
||||
|
||||
/* Only retrieve etag/last-modified headers if the file exists */
|
||||
/* This inconsistency can occur if user deleted some cached files */
|
||||
if (TextureCache_Has(url)) {
|
||||
TextureCache_GetLastModified(url, &time);
|
||||
TextureCache_GetETag(url, &etag);
|
||||
}
|
||||
Http_AsyncGetDataEx(url, true, id, &time, &etag);
|
||||
}
|
||||
|
@ -87,16 +87,22 @@ void TextureCache_Deny(const String* url);
|
||||
bool TextureCache_Has(const String* url);
|
||||
/* Attempts to get the cached data stream for the given url. */
|
||||
bool TextureCache_Get(const String* url, struct Stream* stream);
|
||||
/* Attempts to get the Last-Modified header cached for the given URL. */
|
||||
void TextureCache_GetLastModified(const String* url, String* time);
|
||||
/* Attempts to get the ETag header cached for the given URL. */
|
||||
void TextureCache_GetETag(const String* url, String* etag);
|
||||
/* Sets the cached data for the given url. */
|
||||
void TextureCache_Set(const String* url, const uint8_t* data, uint32_t length);
|
||||
/* Updates cached data, ETag, and Last-Modified for the given URL. */
|
||||
void TextureCache_Update(struct HttpRequest* req);
|
||||
|
||||
/* Extracts a texture pack .zip from the given file. */
|
||||
void TexturePack_ExtractZip_File(const String* filename);
|
||||
/* Extracts user's default texture pack, then resets World_TextureUrl. */
|
||||
void TexturePack_ExtractDefault(void);
|
||||
/* Extracts the current texture pack or terrain.png. 3 cases: */
|
||||
/* - Server has not set a URL, so just extract default */
|
||||
/* - URL is in texture cache, so extract cached version */
|
||||
/* - URL is not cached, so extract default for now */
|
||||
void TexturePack_ExtractCurrent(const String* url);
|
||||
/* Asynchronously downloads a texture pack. */
|
||||
/* Sends ETag and Last-Modified to webserver to avoid redundant downloads. */
|
||||
/* NOTE: This does not load cached textures - use TexturePack_ExtractCurrent for that. */
|
||||
void TexturePack_DownloadAsync(const String* url, const String* id);
|
||||
/* Extracts a texture pack or terrain.png from given downloaded data. */
|
||||
void TexturePack_Extract_Req(struct HttpRequest* item);
|
||||
#endif
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include "ExtMath.h"
|
||||
#include "Physics.h"
|
||||
#include "Game.h"
|
||||
#include "TexturePack.h"
|
||||
|
||||
struct _WorldData World;
|
||||
/*########################################################################################################################*
|
||||
@ -135,6 +136,12 @@ const PackedCol Env_DefaultShadowCol = PACKEDCOL_CONST(0x9B, 0x9B, 0x9B, 0xFF);
|
||||
static char World_TextureUrlBuffer[STRING_SIZE];
|
||||
String World_TextureUrl = String_FromArray(World_TextureUrlBuffer);
|
||||
|
||||
void World_ApplyTexturePack(const String* url) {
|
||||
static const String texPack = String_FromConst("texturePack");
|
||||
TexturePack_ExtractCurrent(url);
|
||||
TexturePack_DownloadAsync(url, &texPack);
|
||||
}
|
||||
|
||||
void Env_Reset(void) {
|
||||
Env.EdgeHeight = -1;
|
||||
Env.SidesOffset = -2;
|
||||
|
@ -123,9 +123,13 @@ extern const PackedCol Env_DefaultSunCol, Env_DefaultShadowCol;
|
||||
#define ENV_DEFAULT_SUNCOL_HEX "FFFFFF"
|
||||
#define ENV_DEFAULT_SHADOWCOL_HEX "9B9B9B"
|
||||
|
||||
/* Extracts texture pack cached for the given URL (or default.zip if not), */
|
||||
/* then asynchronously downloads the data for the given URL. */
|
||||
CC_API void World_ApplyTexturePack(const String* url);
|
||||
/* Resets all environment settings to default. */
|
||||
/* NOTE: Unlike Env_Set functions, DOES NOT raise EnvVarChanged event. */
|
||||
CC_API void Env_Reset(void);
|
||||
|
||||
/* Sets the edge/horizon block. (default water) */
|
||||
CC_API void Env_SetEdgeBlock(BlockID block);
|
||||
/* Sets the sides/border block. (default bedrock) */
|
||||
|
Loading…
x
Reference in New Issue
Block a user