WIP textures stuff

This commit is contained in:
UnknownShadow200 2019-06-20 18:53:58 +10:00
parent 27881b6acc
commit cbee786c99
6 changed files with 83 additions and 60 deletions

View File

@ -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)

View File

@ -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 {

View File

@ -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);
}

View File

@ -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

View File

@ -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;

View File

@ -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) */