mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-09-16 19:15:14 -04:00
Make Textures a component too, move some texture specific out of Game.c and into TexturePack.c
This commit is contained in:
parent
664428682c
commit
dcc6a12946
68
src/Game.c
68
src/Game.c
@ -91,29 +91,6 @@ int ScheduledTask_Add(double interval, ScheduledTaskCallback callback) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
cc_bool Game_ChangeTerrainAtlas(Bitmap* atlas) {
|
|
||||||
static const String terrain = String_FromConst("terrain.png");
|
|
||||||
if (!Game_ValidateBitmap(&terrain, atlas)) return false;
|
|
||||||
|
|
||||||
if (atlas->Height < atlas->Width) {
|
|
||||||
Chat_AddRaw("&cUnable to use terrain.png from the texture pack.");
|
|
||||||
Chat_AddRaw("&c Its height is less than its width.");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (atlas->Width < ATLAS2D_TILES_PER_ROW) {
|
|
||||||
Chat_AddRaw("&cUnable to use terrain.png from the texture pack.");
|
|
||||||
Chat_AddRaw("&c It must be 16 or more pixels wide.");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (Gfx.LostContext) return false;
|
|
||||||
|
|
||||||
Atlas_Free();
|
|
||||||
Atlas_Update(atlas);
|
|
||||||
|
|
||||||
Event_RaiseVoid(&TextureEvents.AtlasChanged);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Game_SetViewDistance(int distance) {
|
void Game_SetViewDistance(int distance) {
|
||||||
distance = min(distance, Game_MaxViewDistance);
|
distance = min(distance, Game_MaxViewDistance);
|
||||||
if (distance == Game_ViewDistance) return;
|
if (distance == Game_ViewDistance) return;
|
||||||
@ -260,22 +237,6 @@ static void HandleOnNewMapLoaded(void* obj) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void HandleTextureChanged(void* obj, struct Stream* src, const String* name) {
|
|
||||||
Bitmap bmp;
|
|
||||||
cc_result res;
|
|
||||||
|
|
||||||
if (String_CaselessEqualsConst(name, "terrain.png")) {
|
|
||||||
res = Png_Decode(&bmp, src);
|
|
||||||
|
|
||||||
if (res) {
|
|
||||||
Logger_Warn2(res, "decoding", name);
|
|
||||||
Mem_Free(bmp.Scan0);
|
|
||||||
} else if (!Game_ChangeTerrainAtlas(&bmp)) {
|
|
||||||
Mem_Free(bmp.Scan0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void HandleLowVRAMDetected(void* obj) {
|
static void HandleLowVRAMDetected(void* obj) {
|
||||||
if (Game_UserViewDistance <= 16) Logger_Abort("Out of video memory!");
|
if (Game_UserViewDistance <= 16) Logger_Abort("Out of video memory!");
|
||||||
Game_UserViewDistance /= 2;
|
Game_UserViewDistance /= 2;
|
||||||
@ -372,16 +333,12 @@ static void Game_Load(void) {
|
|||||||
Gfx_Init();
|
Gfx_Init();
|
||||||
LoadOptions();
|
LoadOptions();
|
||||||
|
|
||||||
Event_RegisterVoid(&WorldEvents.NewMap, NULL, HandleOnNewMap);
|
Event_RegisterVoid(&WorldEvents.NewMap, NULL, HandleOnNewMap);
|
||||||
Event_RegisterVoid(&WorldEvents.MapLoaded, NULL, HandleOnNewMapLoaded);
|
Event_RegisterVoid(&WorldEvents.MapLoaded, NULL, HandleOnNewMapLoaded);
|
||||||
Event_RegisterEntry(&TextureEvents.FileChanged, NULL, HandleTextureChanged);
|
Event_RegisterVoid(&GfxEvents.LowVRAMDetected, NULL, HandleLowVRAMDetected);
|
||||||
Event_RegisterVoid(&GfxEvents.LowVRAMDetected, NULL, HandleLowVRAMDetected);
|
|
||||||
|
|
||||||
Event_RegisterVoid(&WindowEvents.Resized, NULL, Game_OnResize);
|
Event_RegisterVoid(&WindowEvents.Resized, NULL, Game_OnResize);
|
||||||
Event_RegisterVoid(&WindowEvents.Closing, NULL, Game_Free);
|
Event_RegisterVoid(&WindowEvents.Closing, NULL, Game_Free);
|
||||||
|
|
||||||
TextureCache_Init();
|
|
||||||
/* TODO: Survival vs Creative game mode */
|
|
||||||
|
|
||||||
InputHandler_Init();
|
InputHandler_Init();
|
||||||
Game_AddComponent(&Blocks_Component);
|
Game_AddComponent(&Blocks_Component);
|
||||||
@ -398,6 +355,7 @@ static void Game_Load(void) {
|
|||||||
|
|
||||||
Game_AddComponent(&Animations_Component);
|
Game_AddComponent(&Animations_Component);
|
||||||
Game_AddComponent(&Inventory_Component);
|
Game_AddComponent(&Inventory_Component);
|
||||||
|
Game_AddComponent(&Textures_Component);
|
||||||
World_Reset();
|
World_Reset();
|
||||||
|
|
||||||
Game_AddComponent(&Builder_Component);
|
Game_AddComponent(&Builder_Component);
|
||||||
@ -602,16 +560,16 @@ static void Game_RenderFrame(double delta) {
|
|||||||
|
|
||||||
void Game_Free(void* obj) {
|
void Game_Free(void* obj) {
|
||||||
struct IGameComponent* comp;
|
struct IGameComponent* comp;
|
||||||
Atlas_Free();
|
/* Most components will call OnContextLost in their Free functions */
|
||||||
|
/* Set to false so components will always free managed textures too */
|
||||||
Gfx.ManagedTextures = false;
|
Gfx.ManagedTextures = false;
|
||||||
|
|
||||||
Event_UnregisterVoid(&WorldEvents.NewMap, NULL, HandleOnNewMap);
|
Event_UnregisterVoid(&WorldEvents.NewMap, NULL, HandleOnNewMap);
|
||||||
Event_UnregisterVoid(&WorldEvents.MapLoaded, NULL, HandleOnNewMapLoaded);
|
Event_UnregisterVoid(&WorldEvents.MapLoaded, NULL, HandleOnNewMapLoaded);
|
||||||
Event_UnregisterEntry(&TextureEvents.FileChanged, NULL, HandleTextureChanged);
|
Event_UnregisterVoid(&GfxEvents.LowVRAMDetected, NULL, HandleLowVRAMDetected);
|
||||||
Event_UnregisterVoid(&GfxEvents.LowVRAMDetected, NULL, HandleLowVRAMDetected);
|
|
||||||
|
|
||||||
Event_UnregisterVoid(&WindowEvents.Resized, NULL, Game_OnResize);
|
Event_UnregisterVoid(&WindowEvents.Resized, NULL, Game_OnResize);
|
||||||
Event_UnregisterVoid(&WindowEvents.Closing, NULL, Game_Free);
|
Event_UnregisterVoid(&WindowEvents.Closing, NULL, Game_Free);
|
||||||
|
|
||||||
for (comp = comps_head; comp; comp = comp->next) {
|
for (comp = comps_head; comp; comp = comp->next) {
|
||||||
if (comp->Free) comp->Free();
|
if (comp->Free) comp->Free();
|
||||||
|
@ -49,8 +49,6 @@ enum FpsLimitMethod {
|
|||||||
};
|
};
|
||||||
extern const char* const FpsLimit_Names[FPS_LIMIT_COUNT];
|
extern const char* const FpsLimit_Names[FPS_LIMIT_COUNT];
|
||||||
|
|
||||||
/* Attempts to change the terrain atlas. (bitmap containing textures for all blocks) */
|
|
||||||
cc_bool Game_ChangeTerrainAtlas(Bitmap* atlas);
|
|
||||||
void Game_SetViewDistance(int distance);
|
void Game_SetViewDistance(int distance);
|
||||||
void Game_UserSetViewDistance(int distance);
|
void Game_UserSetViewDistance(int distance);
|
||||||
void Game_SetFov(int fov);
|
void Game_SetFov(int fov);
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
#include "ExtMath.h"
|
#include "ExtMath.h"
|
||||||
#include "Options.h"
|
#include "Options.h"
|
||||||
#include "Logger.h"
|
#include "Logger.h"
|
||||||
|
#include "Chat.h" /* TODO avoid this include */
|
||||||
|
|
||||||
/*########################################################################################################################*
|
/*########################################################################################################################*
|
||||||
*------------------------------------------------------TerrainAtlas-------------------------------------------------------*
|
*------------------------------------------------------TerrainAtlas-------------------------------------------------------*
|
||||||
@ -71,7 +72,8 @@ static void Atlas_Update1D(void) {
|
|||||||
Atlas1D.Shift = Math_Log2(Atlas1D.TilesPerAtlas);
|
Atlas1D.Shift = Math_Log2(Atlas1D.TilesPerAtlas);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Atlas_Update(Bitmap* bmp) {
|
/* Loads the given atlas and converts it into an array of 1D atlases. */
|
||||||
|
static void Atlas_Update(Bitmap* bmp) {
|
||||||
Atlas2D.Bmp = *bmp;
|
Atlas2D.Bmp = *bmp;
|
||||||
Atlas2D.TileSize = bmp->Width / ATLAS2D_TILES_PER_ROW;
|
Atlas2D.TileSize = bmp->Width / ATLAS2D_TILES_PER_ROW;
|
||||||
Atlas2D.RowsCount = bmp->Height / Atlas2D.TileSize;
|
Atlas2D.RowsCount = bmp->Height / Atlas2D.TileSize;
|
||||||
@ -108,7 +110,8 @@ GfxResourceID Atlas2D_LoadTile(TextureLoc texLoc) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Atlas_Free(void) {
|
/* Frees the atlas and 1D atlas textures */
|
||||||
|
static void Atlas_Free(void) {
|
||||||
int i;
|
int i;
|
||||||
Mem_Free(Atlas2D.Bmp.Scan0);
|
Mem_Free(Atlas2D.Bmp.Scan0);
|
||||||
Atlas2D.Bmp.Scan0 = NULL;
|
Atlas2D.Bmp.Scan0 = NULL;
|
||||||
@ -118,13 +121,37 @@ void Atlas_Free(void) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cc_bool Atlas_TryChange(Bitmap* atlas) {
|
||||||
|
static const String terrain = String_FromConst("terrain.png");
|
||||||
|
if (!Game_ValidateBitmap(&terrain, atlas)) return false;
|
||||||
|
|
||||||
|
if (atlas->Height < atlas->Width) {
|
||||||
|
Chat_AddRaw("&cUnable to use terrain.png from the texture pack.");
|
||||||
|
Chat_AddRaw("&c Its height is less than its width.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (atlas->Width < ATLAS2D_TILES_PER_ROW) {
|
||||||
|
Chat_AddRaw("&cUnable to use terrain.png from the texture pack.");
|
||||||
|
Chat_AddRaw("&c It must be 16 or more pixels wide.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Gfx.LostContext) return false;
|
||||||
|
Atlas_Free();
|
||||||
|
Atlas_Update(atlas);
|
||||||
|
|
||||||
|
Event_RaiseVoid(&TextureEvents.AtlasChanged);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*########################################################################################################################*
|
/*########################################################################################################################*
|
||||||
*------------------------------------------------------TextureCache-------------------------------------------------------*
|
*------------------------------------------------------TextureCache-------------------------------------------------------*
|
||||||
*#########################################################################################################################*/
|
*#########################################################################################################################*/
|
||||||
static struct EntryList acceptedList, deniedList, etagCache, lastModifiedCache;
|
static struct EntryList acceptedList, deniedList, etagCache, lastModifiedCache;
|
||||||
|
|
||||||
void TextureCache_Init(void) {
|
/* Initialises cache state (loading various lists) */
|
||||||
|
static void TextureCache_Init(void) {
|
||||||
EntryList_Init(&acceptedList, "texturecache/acceptedurls.txt", ' ');
|
EntryList_Init(&acceptedList, "texturecache/acceptedurls.txt", ' ');
|
||||||
EntryList_Init(&deniedList, "texturecache/deniedurls.txt", ' ');
|
EntryList_Init(&deniedList, "texturecache/deniedurls.txt", ' ');
|
||||||
EntryList_Init(&etagCache, "texturecache/etags.txt", ' ');
|
EntryList_Init(&etagCache, "texturecache/etags.txt", ' ');
|
||||||
@ -295,7 +322,7 @@ static cc_result TexturePack_ExtractPng(struct Stream* stream) {
|
|||||||
|
|
||||||
if (!res) {
|
if (!res) {
|
||||||
Event_RaiseVoid(&TextureEvents.PackChanged);
|
Event_RaiseVoid(&TextureEvents.PackChanged);
|
||||||
if (Game_ChangeTerrainAtlas(&bmp)) return 0;
|
if (Atlas_TryChange(&bmp)) return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Mem_Free(bmp.Scan0);
|
Mem_Free(bmp.Scan0);
|
||||||
@ -406,3 +433,37 @@ void TexturePack_DownloadAsync(const String* url, const String* id) {
|
|||||||
}
|
}
|
||||||
Http_AsyncGetDataEx(url, true, id, &time, &etag, NULL);
|
Http_AsyncGetDataEx(url, true, id, &time, &etag, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*########################################################################################################################*
|
||||||
|
*---------------------------------------------------Textures component----------------------------------------------------*
|
||||||
|
*#########################################################################################################################*/
|
||||||
|
static void OnFileChanged(void* obj, struct Stream* stream, const String* name) {
|
||||||
|
Bitmap bmp;
|
||||||
|
cc_result res;
|
||||||
|
|
||||||
|
if (!String_CaselessEqualsConst(name, "terrain.png")) return;
|
||||||
|
res = Png_Decode(&bmp, stream);
|
||||||
|
|
||||||
|
if (res) {
|
||||||
|
Logger_Warn2(res, "decoding", name);
|
||||||
|
Mem_Free(bmp.Scan0);
|
||||||
|
} else if (!Atlas_TryChange(&bmp)) {
|
||||||
|
Mem_Free(bmp.Scan0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Textures_Init(void) {
|
||||||
|
Event_RegisterEntry(&TextureEvents.FileChanged, NULL, OnFileChanged);
|
||||||
|
TextureCache_Init();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Textures_Free(void) {
|
||||||
|
Event_UnregisterEntry(&TextureEvents.FileChanged, NULL, OnFileChanged);
|
||||||
|
Atlas_Free();
|
||||||
|
}
|
||||||
|
|
||||||
|
struct IGameComponent Textures_Component = {
|
||||||
|
Textures_Init, /* Init */
|
||||||
|
Textures_Free /* Free */
|
||||||
|
};
|
||||||
|
@ -11,6 +11,8 @@
|
|||||||
|
|
||||||
struct Stream;
|
struct Stream;
|
||||||
struct HttpRequest;
|
struct HttpRequest;
|
||||||
|
struct IGameComponent;
|
||||||
|
extern struct IGameComponent Textures_Component;
|
||||||
|
|
||||||
/* Number of tiles in each row */
|
/* Number of tiles in each row */
|
||||||
#define ATLAS2D_TILES_PER_ROW 16
|
#define ATLAS2D_TILES_PER_ROW 16
|
||||||
@ -56,20 +58,15 @@ CC_VAR extern struct _Atlas1DData {
|
|||||||
/* Returns the index of the 1D atlas within the array of 1D atlases that contains the given tile id */
|
/* Returns the index of the 1D atlas within the array of 1D atlases that contains the given tile id */
|
||||||
#define Atlas1D_Index(texLoc) ((texLoc) >> Atlas1D.Shift) /* texLoc / Atlas1D_TilesPerAtlas */
|
#define Atlas1D_Index(texLoc) ((texLoc) >> Atlas1D.Shift) /* texLoc / Atlas1D_TilesPerAtlas */
|
||||||
|
|
||||||
/* Loads the given atlas and converts it into an array of 1D atlases. */
|
|
||||||
/* NOTE: Use Game_ChangeTerrainAtlas to change atlas, because that raises TextureEvents.AtlasChanged */
|
|
||||||
void Atlas_Update(Bitmap* bmp);
|
|
||||||
/* Loads the given tile into a new separate texture. */
|
/* Loads the given tile into a new separate texture. */
|
||||||
GfxResourceID Atlas2D_LoadTile(TextureLoc texLoc);
|
GfxResourceID Atlas2D_LoadTile(TextureLoc texLoc);
|
||||||
/* Frees the atlas and 1D atlas textures. */
|
/* Attempts to change the terrain atlas. (bitmap containing textures for all blocks) */
|
||||||
void Atlas_Free(void);
|
cc_bool Atlas_TryChange(Bitmap* bmp);
|
||||||
/* Returns the UV rectangle of the given tile id in the 1D atlases. */
|
/* Returns the UV rectangle of the given tile id in the 1D atlases. */
|
||||||
/* That is, returns U1/U2/V1/V2 coords that make up the tile in a 1D atlas. */
|
/* That is, returns U1/U2/V1/V2 coords that make up the tile in a 1D atlas. */
|
||||||
/* index is set to the index of the 1D atlas that the tile is in. */
|
/* index is set to the index of the 1D atlas that the tile is in. */
|
||||||
TextureRec Atlas1D_TexRec(TextureLoc texLoc, int uCount, int* index);
|
TextureRec Atlas1D_TexRec(TextureLoc texLoc, int uCount, int* index);
|
||||||
|
|
||||||
/* Initialises cache state. (e.g. loading accepted/denied lists) */
|
|
||||||
void TextureCache_Init(void);
|
|
||||||
/* Whether the given URL is in list of accepted URLs. */
|
/* Whether the given URL is in list of accepted URLs. */
|
||||||
cc_bool TextureCache_HasAccepted(const String* url);
|
cc_bool TextureCache_HasAccepted(const String* url);
|
||||||
/* Whether the given URL is in list of denied URLs. */
|
/* Whether the given URL is in list of denied URLs. */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user