mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-09-18 03:55:19 -04:00
make chat api a bit cleaner
This commit is contained in:
parent
1ebdf30211
commit
b888213adc
@ -27,7 +27,7 @@ namespace Launcher {
|
||||
|
||||
/// <summary> Whether the client drawing area needs to be redrawn/presented to the screen. </summary>
|
||||
public bool Dirty, pendingRedraw;
|
||||
/// <summary> The specific area/region of the window that needs to be redrawn. </summary>
|
||||
/// <summary> The specific area/region of the window that needs to be redrawn. </summary>
|
||||
public Rectangle DirtyArea;
|
||||
|
||||
public string Username;
|
||||
|
@ -213,7 +213,7 @@ static void Animations_ReadDescription(struct Stream* stream, const String* path
|
||||
#define ANIMS_FAST_SIZE 64
|
||||
static void Animations_Draw(struct AnimationData* data, TextureLoc texLoc, int size) {
|
||||
int dstX = Atlas1D_Index(texLoc), srcX;
|
||||
int dstY = Atlas1D_RowId(texLoc) * Atlas2D_TileSize;
|
||||
int dstY = Atlas1D_RowId(texLoc) * Atlas_TileSize;
|
||||
GfxResourceID tex;
|
||||
|
||||
uint8_t buffer[Bitmap_DataSize(ANIMS_FAST_SIZE, ANIMS_FAST_SIZE)];
|
||||
@ -287,7 +287,7 @@ static void Animations_Validate(void) {
|
||||
tileX = Atlas2D_TileX(data.TexLoc);
|
||||
tileY = Atlas2D_TileY(data.TexLoc);
|
||||
|
||||
if (data.FrameSize > Atlas2D_TileSize || tileY >= Atlas2D_RowsCount) {
|
||||
if (data.FrameSize > Atlas_TileSize || tileY >= Atlas_RowsCount) {
|
||||
Chat_Add2("&cAnimation frames for tile (%i, %i) are bigger than the size of a tile in terrain.png", &tileX, &tileY);
|
||||
} else if (maxX > anims_bmp.Width || maxY > anims_bmp.Height) {
|
||||
Chat_Add2("&cSome of the animation frames for tile (%i, %i) are at coordinates outside animations.png", &tileX, &tileY);
|
||||
@ -308,11 +308,11 @@ static void Animations_Tick(struct ScheduledTask* task) {
|
||||
int i, size;
|
||||
|
||||
if (anims_useLavaAnim) {
|
||||
size = min(Atlas2D_TileSize, 64);
|
||||
size = min(Atlas_TileSize, 64);
|
||||
Animations_Draw(NULL, 30, size);
|
||||
}
|
||||
if (anims_useWaterAnim) {
|
||||
size = min(Atlas2D_TileSize, 64);
|
||||
size = min(Atlas_TileSize, 64);
|
||||
Animations_Draw(NULL, 14, size);
|
||||
}
|
||||
|
||||
|
@ -433,8 +433,8 @@ static float Block_GetSpriteBB_MaxY(int size, int tileX, int tileY, Bitmap* bmp)
|
||||
}
|
||||
|
||||
void Block_RecalculateBB(BlockID block) {
|
||||
Bitmap* bmp = &Atlas2D_Bitmap;
|
||||
int tileSize = Atlas2D_TileSize;
|
||||
Bitmap* bmp = &Atlas_Bitmap;
|
||||
int tileSize = Atlas_TileSize;
|
||||
TextureLoc texLoc = Block_GetTex(block, FACE_XMAX);
|
||||
int x = Atlas2D_TileX(texLoc), y = Atlas2D_TileY(texLoc);
|
||||
|
||||
@ -442,7 +442,7 @@ void Block_RecalculateBB(BlockID block) {
|
||||
float minX = 0, minY = 0, maxX = 1, maxY = 1;
|
||||
Vector3 minRaw, maxRaw;
|
||||
|
||||
if (y < Atlas2D_RowsCount) {
|
||||
if (y < Atlas_RowsCount) {
|
||||
minX = Block_GetSpriteBB_MinX(tileSize, x, y, bmp);
|
||||
minY = Block_GetSpriteBB_MinY(tileSize, x, y, bmp);
|
||||
maxX = Block_GetSpriteBB_MaxX(tileSize, x, y, bmp);
|
||||
|
23
src/Chat.c
23
src/Chat.c
@ -15,7 +15,13 @@
|
||||
#include "EnvRenderer.h"
|
||||
#include "GameStructs.h"
|
||||
|
||||
struct ChatLine Chat_Status[3], Chat_BottomRight[3], Chat_ClientStatus[3], Chat_Announcement;
|
||||
static char msgs[10][STRING_SIZE];
|
||||
String Chat_Status[3] = { String_FromArray(msgs[0]), String_FromArray(msgs[1]), String_FromArray(msgs[2]) };
|
||||
String Chat_BottomRight[3] = { String_FromArray(msgs[3]), String_FromArray(msgs[4]), String_FromArray(msgs[5]) };
|
||||
String Chat_ClientStatus[3] = { String_FromArray(msgs[6]), String_FromArray(msgs[7]), String_FromArray(msgs[8]) };
|
||||
|
||||
String Chat_Announcement = String_FromArray(msgs[9]);
|
||||
TimeMS Chat_AnnouncementReceived;
|
||||
StringsBuffer Chat_Log, Chat_InputLog;
|
||||
|
||||
/*########################################################################################################################*
|
||||
@ -146,12 +152,6 @@ static void Chat_AppendLog(const String* text) {
|
||||
Chat_LogError2(res, "writing to", &Chat_LogPath);
|
||||
}
|
||||
|
||||
static void ChatLine_Make(struct ChatLine* line, const String* text) {
|
||||
String dst = String_ClearedArray(line->Buffer);
|
||||
String_AppendString(&dst, text);
|
||||
line->Received = DateTime_CurrentUTC_MS();
|
||||
}
|
||||
|
||||
void Chat_LogError(ReturnCode result, const char* place) {
|
||||
Chat_Add4("&cError %h when %c", &result, place, NULL, NULL);
|
||||
}
|
||||
@ -189,13 +189,14 @@ void Chat_AddOf(const String* text, MsgType type) {
|
||||
Chat_AppendLog(text);
|
||||
Chat_AppendLogTime();
|
||||
} else if (type >= MSG_TYPE_STATUS_1 && type <= MSG_TYPE_STATUS_3) {
|
||||
ChatLine_Make(&Chat_Status[type - MSG_TYPE_STATUS_1], text);
|
||||
String_Copy(&Chat_Status[type - MSG_TYPE_STATUS_1], text);
|
||||
} else if (type >= MSG_TYPE_BOTTOMRIGHT_1 && type <= MSG_TYPE_BOTTOMRIGHT_3) {
|
||||
ChatLine_Make(&Chat_BottomRight[type - MSG_TYPE_BOTTOMRIGHT_1], text);
|
||||
String_Copy(&Chat_BottomRight[type - MSG_TYPE_BOTTOMRIGHT_1], text);
|
||||
} else if (type == MSG_TYPE_ANNOUNCEMENT) {
|
||||
ChatLine_Make(&Chat_Announcement, text);
|
||||
String_Copy(&Chat_Announcement, text);
|
||||
Chat_AnnouncementReceived = DateTime_CurrentUTC_MS();
|
||||
} else if (type >= MSG_TYPE_CLIENTSTATUS_1 && type <= MSG_TYPE_CLIENTSTATUS_3) {
|
||||
ChatLine_Make(&Chat_ClientStatus[type - MSG_TYPE_CLIENTSTATUS_1], text);
|
||||
String_Copy(&Chat_ClientStatus[type - MSG_TYPE_CLIENTSTATUS_1], text);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -23,9 +23,10 @@ typedef enum MsgType_ {
|
||||
MSG_TYPE_CLIENTSTATUS_3 = 258 /* Tab list matching names*/
|
||||
} MsgType;
|
||||
|
||||
struct ChatLine { char Buffer[STRING_SIZE]; TimeMS Received; };
|
||||
extern struct ChatLine Chat_Status[3], Chat_BottomRight[3], Chat_ClientStatus[3], Chat_Announcement;
|
||||
extern String Chat_Status[3], Chat_BottomRight[3], Chat_ClientStatus[3], Chat_Announcement;
|
||||
extern StringsBuffer Chat_Log, Chat_InputLog;
|
||||
|
||||
extern TimeMS Chat_AnnouncementReceived;
|
||||
/* Gets the time the ith chat message was received at. */
|
||||
TimeMS Chat_GetLogTime(int i);
|
||||
|
||||
|
@ -580,7 +580,7 @@ static void EnvRenderer_MakeBorderTex(GfxResourceID* texId, BlockID block) {
|
||||
if (Gfx_LostContext) return;
|
||||
|
||||
Gfx_DeleteTexture(texId);
|
||||
*texId = Atlas2D_LoadTile(loc);
|
||||
*texId = Atlas_LoadTile(loc);
|
||||
}
|
||||
|
||||
static Rect2D EnvRenderer_Rect(int x, int y, int width, int height) {
|
||||
|
@ -157,10 +157,8 @@ bool Game_ChangeTerrainAtlas(Bitmap* atlas) {
|
||||
}
|
||||
if (Gfx_LostContext) return false;
|
||||
|
||||
Atlas1D_Free();
|
||||
Atlas2D_Free();
|
||||
Atlas2D_UpdateState(atlas);
|
||||
Atlas1D_UpdateState();
|
||||
Atlas_Free();
|
||||
Atlas_Update(atlas);
|
||||
|
||||
Event_RaiseVoid(&TextureEvents_AtlasChanged);
|
||||
return true;
|
||||
@ -709,8 +707,7 @@ static void Game_RenderFrame(double delta) {
|
||||
|
||||
void Game_Free(void* obj) {
|
||||
struct IGameComponent* comp;
|
||||
Atlas2D_Free();
|
||||
Atlas1D_Free();
|
||||
Atlas_Free();
|
||||
|
||||
Event_UnregisterVoid(&WorldEvents_NewMap, NULL, Game_OnNewMapCore);
|
||||
Event_UnregisterVoid(&WorldEvents_MapLoaded, NULL, Game_OnNewMapLoadedCore);
|
||||
|
@ -86,7 +86,8 @@ void Game_Reset(void);
|
||||
/* (updating state means recalculating light, redrawing chunk block is in, etc) */
|
||||
/* NOTE: This does NOT notify the server, use Game_ChangeBlock for that. */
|
||||
CC_EXPORT void Game_UpdateBlock(int x, int y, int z, BlockID block);
|
||||
/* Calls Game_UpdateBlock, then sends the block change to the server. */
|
||||
/* Calls Game_UpdateBlock, then informs server connection of the block change. */
|
||||
/* In multiplayer this is sent to the server, in singleplayer just activates physics. */
|
||||
CC_EXPORT void Game_ChangeBlock(int x, int y, int z, BlockID block);
|
||||
bool Game_CanPick(BlockID block);
|
||||
bool Game_UpdateTexture(GfxResourceID* texId, struct Stream* src, const String* file, uint8_t* skinType);
|
||||
|
@ -17,19 +17,19 @@ extern int16_t* Lighting_Heightmap;
|
||||
* CalcLight(x, maxY, z) */
|
||||
void Lighting_LightHint(int startX, int startZ);
|
||||
|
||||
/* Called when a block is changed, to update the lighting information.
|
||||
NOTE: Implementations ***MUST*** mark all chunks affected by this lighting changeas needing to be refreshed. */
|
||||
/* Called when a block is changed, to update the lighting information. */
|
||||
/* NOTE: Implementations ***MUST*** mark all chunks affected by this lighting changeas needing to be refreshed. */
|
||||
void Lighting_OnBlockChanged(int x, int y, int z, BlockID oldBlock, BlockID newBlock);
|
||||
void Lighting_Refresh(void);
|
||||
|
||||
/* Returns whether the block at the given coordinates is fully in sunlight.
|
||||
NOTE: Does ***NOT*** check that the coordinates are inside the map. */
|
||||
/* Returns whether the block at the given coordinates is fully in sunlight. */
|
||||
/* NOTE: Does ***NOT*** check that the coordinates are inside the map. */
|
||||
bool Lighting_IsLit(int x, int y, int z);
|
||||
/* Returns the light colour of the block at the given coordinates.
|
||||
NOTE: Does ***NOT*** check that the coordinates are inside the map. */
|
||||
/* Returns the light colour of the block at the given coordinates. */
|
||||
/* NOTE: Does ***NOT*** check that the coordinates are inside the map. */
|
||||
PackedCol Lighting_Col(int x, int y, int z);
|
||||
/* Returns the light colour of the block at the given coordinates.
|
||||
NOTE: Does ***NOT*** check that the coordinates are inside the map. */
|
||||
/* Returns the light colour of the block at the given coordinates. */
|
||||
/* NOTE: Does ***NOT*** check that the coordinates are inside the map. */
|
||||
PackedCol Lighting_Col_XSide(int x, int y, int z);
|
||||
|
||||
PackedCol Lighting_Col_Sprite_Fast(int x, int y, int z);
|
||||
|
@ -67,6 +67,16 @@ void ChunkInfo_Reset(struct ChunkInfo* chunk, int x, int y, int z) {
|
||||
chunk->TranslucentParts = NULL;
|
||||
}
|
||||
|
||||
CC_NOINLINE static int MapRenderer_UsedAtlases(void) {
|
||||
TextureLoc maxLoc = 0;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < Array_Elems(Block_Textures); i++) {
|
||||
maxLoc = max(maxLoc, Block_Textures[i]);
|
||||
}
|
||||
return Atlas1D_Index(maxLoc) + 1;
|
||||
}
|
||||
|
||||
|
||||
/*########################################################################################################################*
|
||||
*-------------------------------------------------------Map rendering-----------------------------------------------------*
|
||||
@ -386,7 +396,7 @@ void MapRenderer_Refresh(void) {
|
||||
MapRenderer_ResetChunks();
|
||||
|
||||
oldCount = MapRenderer_1DUsedCount;
|
||||
MapRenderer_1DUsedCount = Atlas1D_UsedAtlasesCount();
|
||||
MapRenderer_1DUsedCount = MapRenderer_UsedAtlases();
|
||||
/* Need to reallocate parts array in this case */
|
||||
if (MapRenderer_1DUsedCount != oldCount) {
|
||||
MapRenderer_FreeParts();
|
||||
@ -693,14 +703,14 @@ static void MapRenderer_TerrainAtlasChanged(void* obj) {
|
||||
if (refreshRequired) MapRenderer_Refresh();
|
||||
}
|
||||
|
||||
MapRenderer_1DUsedCount = Atlas1D_UsedAtlasesCount();
|
||||
MapRenderer_1DUsedCount = MapRenderer_UsedAtlases();
|
||||
elementsPerBitmap = Atlas1D_TilesPerAtlas;
|
||||
MapRenderer_ResetPartFlags();
|
||||
}
|
||||
|
||||
static void MapRenderer_BlockDefinitionChanged(void* obj) {
|
||||
MapRenderer_Refresh();
|
||||
MapRenderer_1DUsedCount = Atlas1D_UsedAtlasesCount();
|
||||
MapRenderer_1DUsedCount = MapRenderer_UsedAtlases();
|
||||
MapRenderer_ResetPartFlags();
|
||||
}
|
||||
|
||||
|
@ -14,7 +14,7 @@ extern int MapRenderer_ChunksX, MapRenderer_ChunksY, MapRenderer_ChunksZ;
|
||||
#define MapRenderer_Pack(cx, cy, cz) (((cz) * MapRenderer_ChunksY + (cy)) * MapRenderer_ChunksX + (cx))
|
||||
/* TODO: Swap Y and Z? Make sure to update ChunkUpdater's ResetChunkCache and ClearChunkCache methods! */
|
||||
|
||||
/* Count of actual used 1D atlases. (i.e. 1DIndex(maxTextureLoc) + 1 */
|
||||
/* Max used 1D atlases. (i.e. Atlas1D_Index(maxTextureLoc) + 1) */
|
||||
extern int MapRenderer_1DUsedCount;
|
||||
/* Number of chunks in the world, or ChunksX * ChunksY * ChunksZ */
|
||||
extern int MapRenderer_ChunksCount;
|
||||
|
@ -2963,7 +2963,7 @@ static void TexIdsOverlay_ContextRecreated(void* screen) {
|
||||
s->DynamicVb = Gfx_CreateDynamicVb(VERTEX_FORMAT_P3FT2FC4B, TEXID_OVERLAY_VERTICES_COUNT);
|
||||
TextAtlas_Make(&s->IdAtlas, &chars, &s->TextFont, &prefix);
|
||||
|
||||
s->XOffset = Gui_CalcPos(ANCHOR_CENTRE, 0, size * Atlas2D_RowsCount, Game_Width);
|
||||
s->XOffset = Gui_CalcPos(ANCHOR_CENTRE, 0, size * Atlas_RowsCount, Game_Width);
|
||||
s->YOffset = Gui_CalcPos(ANCHOR_CENTRE, 0, size * ATLAS2D_TILES_PER_ROW, Game_Height);
|
||||
s->TileSize = size;
|
||||
|
||||
@ -3050,7 +3050,7 @@ static void TexIdsOverlay_Render(void* screen, double delta) {
|
||||
origXOffset = s->XOffset;
|
||||
s->BaseTexLoc = 0;
|
||||
|
||||
for (rows = Atlas2D_RowsCount; rows > 0; rows -= ATLAS2D_TILES_PER_ROW) {
|
||||
for (rows = Atlas_RowsCount; rows > 0; rows -= ATLAS2D_TILES_PER_ROW) {
|
||||
TexIdsOverlay_RenderTerrain(s);
|
||||
TexIdsOverlay_RenderTextOverlay(s);
|
||||
|
||||
|
@ -782,26 +782,23 @@ static void ChatScreen_ConstructWidgets(struct ChatScreen* s) {
|
||||
}
|
||||
|
||||
static void ChatScreen_SetInitialMessages(struct ChatScreen* s) {
|
||||
String msg;
|
||||
int i;
|
||||
|
||||
s->ChatIndex = Chat_Log.Count - Game_ChatLines;
|
||||
ChatScreen_ResetChat(s);
|
||||
#define ChatScreen_Set(group, idx, src) msg = String_FromRawArray(src.Buffer); TextGroupWidget_SetText(group, idx, &msg);
|
||||
|
||||
ChatScreen_Set(&s->Status, 2, Chat_Status[0]);
|
||||
ChatScreen_Set(&s->Status, 3, Chat_Status[1]);
|
||||
ChatScreen_Set(&s->Status, 4, Chat_Status[2]);
|
||||
TextGroupWidget_SetText(&s->Status, 2, &Chat_Status[0]);
|
||||
TextGroupWidget_SetText(&s->Status, 3, &Chat_Status[1]);
|
||||
TextGroupWidget_SetText(&s->Status, 4, &Chat_Status[2]);
|
||||
|
||||
ChatScreen_Set(&s->BottomRight, 2, Chat_BottomRight[0]);
|
||||
ChatScreen_Set(&s->BottomRight, 1, Chat_BottomRight[1]);
|
||||
ChatScreen_Set(&s->BottomRight, 0, Chat_BottomRight[2]);
|
||||
TextGroupWidget_SetText(&s->BottomRight, 2, &Chat_BottomRight[0]);
|
||||
TextGroupWidget_SetText(&s->BottomRight, 1, &Chat_BottomRight[1]);
|
||||
TextGroupWidget_SetText(&s->BottomRight, 0, &Chat_BottomRight[2]);
|
||||
|
||||
msg = String_FromRawArray(Chat_Announcement.Buffer);
|
||||
TextWidget_Set(&s->Announcement, &msg, &s->AnnouncementFont);
|
||||
TextWidget_Set(&s->Announcement, &Chat_Announcement, &s->AnnouncementFont);
|
||||
|
||||
for (i = 0; i < s->ClientStatus.LinesCount; i++) {
|
||||
ChatScreen_Set(&s->ClientStatus, i, Chat_ClientStatus[i]);
|
||||
TextGroupWidget_SetText(&s->ClientStatus, i, &Chat_ClientStatus[i]);
|
||||
}
|
||||
|
||||
if (s->HandlesAllInput) {
|
||||
@ -1167,7 +1164,7 @@ static void ChatScreen_Render(void* screen, double delta) {
|
||||
}
|
||||
}
|
||||
|
||||
if (s->Announcement.Texture.ID && now > Chat_Announcement.Received + (5 * 1000)) {
|
||||
if (s->Announcement.Texture.ID && now > Chat_AnnouncementReceived + (5 * 1000)) {
|
||||
Elem_TryFree(&s->Announcement);
|
||||
}
|
||||
}
|
||||
|
@ -5,54 +5,13 @@
|
||||
#include "Graphics.h"
|
||||
#include "Platform.h"
|
||||
|
||||
Bitmap Atlas2D_Bitmap;
|
||||
int Atlas2D_TileSize, Atlas2D_RowsCount;
|
||||
Bitmap Atlas_Bitmap;
|
||||
int Atlas_TileSize, Atlas_RowsCount;
|
||||
int Atlas1D_Count, Atlas1D_TilesPerAtlas;
|
||||
int Atlas1D_Mask, Atlas1D_Shift;
|
||||
float Atlas1D_InvTileSize;
|
||||
GfxResourceID Atlas1D_TexIds[ATLAS1D_MAX_ATLASES];
|
||||
|
||||
void Atlas2D_UpdateState(Bitmap* bmp) {
|
||||
Atlas2D_Bitmap = *bmp;
|
||||
Atlas2D_TileSize = bmp->Width / ATLAS2D_TILES_PER_ROW;
|
||||
Atlas2D_RowsCount = bmp->Height / Atlas2D_TileSize;
|
||||
Atlas2D_RowsCount = min(Atlas2D_RowsCount, ATLAS2D_MAX_ROWS_COUNT);
|
||||
Block_RecalculateAllSpriteBB();
|
||||
}
|
||||
|
||||
static GfxResourceID Atlas2D_LoadTextureElement_Raw(TextureLoc texLoc, Bitmap* element) {
|
||||
int size = Atlas2D_TileSize;
|
||||
int x = Atlas2D_TileX(texLoc), y = Atlas2D_TileY(texLoc);
|
||||
if (y >= Atlas2D_RowsCount) return GFX_NULL;
|
||||
|
||||
Bitmap_CopyBlock(x * size, y * size, 0, 0, &Atlas2D_Bitmap, element, size);
|
||||
return Gfx_CreateTexture(element, false, Gfx_Mipmaps);
|
||||
}
|
||||
|
||||
GfxResourceID Atlas2D_LoadTile(TextureLoc texLoc) {
|
||||
int tileSize = Atlas2D_TileSize;
|
||||
Bitmap tile;
|
||||
GfxResourceID texId;
|
||||
uint8_t scan0[Bitmap_DataSize(64, 64)];
|
||||
|
||||
/* Try to allocate bitmap on stack if possible */
|
||||
if (tileSize > 64) {
|
||||
Bitmap_Allocate(&tile, tileSize, tileSize);
|
||||
texId = Atlas2D_LoadTextureElement_Raw(texLoc, &tile);
|
||||
Mem_Free(tile.Scan0);
|
||||
return texId;
|
||||
} else {
|
||||
Bitmap_Create(&tile, tileSize, tileSize, scan0);
|
||||
return Atlas2D_LoadTextureElement_Raw(texLoc, &tile);
|
||||
}
|
||||
}
|
||||
|
||||
void Atlas2D_Free(void) {
|
||||
Mem_Free(Atlas2D_Bitmap.Scan0);
|
||||
Atlas2D_Bitmap.Scan0 = NULL;
|
||||
}
|
||||
|
||||
|
||||
TextureRec Atlas1D_TexRec(TextureLoc texLoc, int uCount, int* index) {
|
||||
TextureRec rec;
|
||||
int y = Atlas1D_RowId(texLoc);
|
||||
@ -66,60 +25,88 @@ TextureRec Atlas1D_TexRec(TextureLoc texLoc, int uCount, int* index) {
|
||||
return rec;
|
||||
}
|
||||
|
||||
static void Atlas1D_Convert2DTo1D(int atlasesCount, int atlas1DHeight) {
|
||||
int tileSize = Atlas2D_TileSize;
|
||||
static void Atlas_Convert2DTo1D(void) {
|
||||
int tileSize = Atlas_TileSize;
|
||||
int tilesPerAtlas = Atlas1D_TilesPerAtlas;
|
||||
int atlasesCount = Atlas1D_Count;
|
||||
Bitmap atlas1D;
|
||||
int atlasX, atlasY;
|
||||
int tile = 0, i, y;
|
||||
|
||||
Atlas1D_Count = atlasesCount;
|
||||
Platform_Log2("Loaded new atlas: %i bmps, %i per bmp", &atlasesCount, &Atlas1D_TilesPerAtlas);
|
||||
Bitmap_Allocate(&atlas1D, tileSize, atlas1DHeight);
|
||||
Platform_Log2("Loaded new atlas: %i bmps, %i per bmp", &atlasesCount, &tilesPerAtlas);
|
||||
Bitmap_Allocate(&atlas1D, tileSize, tilesPerAtlas * tileSize);
|
||||
|
||||
for (i = 0; i < atlasesCount; i++) {
|
||||
for (y = 0; y < Atlas1D_TilesPerAtlas; y++, tile++) {
|
||||
for (y = 0; y < tilesPerAtlas; y++, tile++) {
|
||||
atlasX = Atlas2D_TileX(tile) * tileSize;
|
||||
atlasY = Atlas2D_TileY(tile) * tileSize;
|
||||
|
||||
Bitmap_CopyBlock(atlasX, atlasY, 0, y * tileSize,
|
||||
&Atlas2D_Bitmap, &atlas1D, tileSize);
|
||||
&Atlas_Bitmap, &atlas1D, tileSize);
|
||||
}
|
||||
Atlas1D_TexIds[i] = Gfx_CreateTexture(&atlas1D, true, Gfx_Mipmaps);
|
||||
}
|
||||
Mem_Free(atlas1D.Scan0);
|
||||
}
|
||||
|
||||
void Atlas1D_UpdateState(void) {
|
||||
static void Atlas_Update1D(void) {
|
||||
int maxAtlasHeight, maxTilesPerAtlas, maxTiles;
|
||||
int atlasesCount, atlasHeight;
|
||||
|
||||
maxAtlasHeight = min(4096, Gfx_MaxTexHeight);
|
||||
maxTilesPerAtlas = maxAtlasHeight / Atlas2D_TileSize;
|
||||
maxTiles = Atlas2D_RowsCount * ATLAS2D_TILES_PER_ROW;
|
||||
maxTilesPerAtlas = maxAtlasHeight / Atlas_TileSize;
|
||||
maxTiles = Atlas_RowsCount * ATLAS2D_TILES_PER_ROW;
|
||||
|
||||
Atlas1D_TilesPerAtlas = min(maxTilesPerAtlas, maxTiles);
|
||||
atlasesCount = Math_CeilDiv(maxTiles, Atlas1D_TilesPerAtlas);
|
||||
atlasHeight = Atlas1D_TilesPerAtlas * Atlas2D_TileSize;
|
||||
Atlas1D_Count = Math_CeilDiv(maxTiles, Atlas1D_TilesPerAtlas);
|
||||
|
||||
Atlas1D_InvTileSize = 1.0f / Atlas1D_TilesPerAtlas;
|
||||
Atlas1D_Mask = Atlas1D_TilesPerAtlas - 1;
|
||||
Atlas1D_Shift = Math_Log2(Atlas1D_TilesPerAtlas);
|
||||
|
||||
Atlas1D_Convert2DTo1D(atlasesCount, atlasHeight);
|
||||
}
|
||||
|
||||
int Atlas1D_UsedAtlasesCount(void) {
|
||||
TextureLoc maxLoc = 0;
|
||||
int i;
|
||||
void Atlas_Update(Bitmap* bmp) {
|
||||
Atlas_Bitmap = *bmp;
|
||||
Atlas_TileSize = bmp->Width / ATLAS2D_TILES_PER_ROW;
|
||||
Atlas_RowsCount = bmp->Height / Atlas_TileSize;
|
||||
Atlas_RowsCount = min(Atlas_RowsCount, ATLAS2D_MAX_ROWS_COUNT);
|
||||
|
||||
for (i = 0; i < Array_Elems(Block_Textures); i++) {
|
||||
maxLoc = max(maxLoc, Block_Textures[i]);
|
||||
Block_RecalculateAllSpriteBB();
|
||||
Atlas_Update1D();
|
||||
Atlas_Convert2DTo1D();
|
||||
}
|
||||
|
||||
static GfxResourceID Atlas_LoadTile_Raw(TextureLoc texLoc, Bitmap* element) {
|
||||
int size = Atlas_TileSize;
|
||||
int x = Atlas2D_TileX(texLoc), y = Atlas2D_TileY(texLoc);
|
||||
if (y >= Atlas_RowsCount) return GFX_NULL;
|
||||
|
||||
Bitmap_CopyBlock(x * size, y * size, 0, 0, &Atlas_Bitmap, element, size);
|
||||
return Gfx_CreateTexture(element, false, Gfx_Mipmaps);
|
||||
}
|
||||
|
||||
GfxResourceID Atlas_LoadTile(TextureLoc texLoc) {
|
||||
int tileSize = Atlas_TileSize;
|
||||
Bitmap tile;
|
||||
GfxResourceID texId;
|
||||
uint8_t scan0[Bitmap_DataSize(64, 64)];
|
||||
|
||||
/* Try to allocate bitmap on stack if possible */
|
||||
if (tileSize > 64) {
|
||||
Bitmap_Allocate(&tile, tileSize, tileSize);
|
||||
texId = Atlas_LoadTile_Raw(texLoc, &tile);
|
||||
Mem_Free(tile.Scan0);
|
||||
return texId;
|
||||
} else {
|
||||
Bitmap_Create(&tile, tileSize, tileSize, scan0);
|
||||
return Atlas_LoadTile_Raw(texLoc, &tile);
|
||||
}
|
||||
return Atlas1D_Index(maxLoc) + 1;
|
||||
}
|
||||
|
||||
void Atlas1D_Free(void) {
|
||||
void Atlas_Free(void) {
|
||||
int i;
|
||||
Mem_Free(Atlas_Bitmap.Scan0);
|
||||
Atlas_Bitmap.Scan0 = NULL;
|
||||
|
||||
for (i = 0; i < Atlas1D_Count; i++) {
|
||||
Gfx_DeleteTexture(&Atlas1D_TexIds[i]);
|
||||
}
|
||||
|
@ -5,21 +5,36 @@
|
||||
Copyright 2014-2017 ClassicalSharp | Licensed under BSD-3
|
||||
*/
|
||||
|
||||
/* Number of tiles in each row */
|
||||
#define ATLAS2D_TILES_PER_ROW 16
|
||||
#define ATLAS2D_MASK 15
|
||||
#define ATLAS2D_SHIFT 4
|
||||
/* Maximum supported number of rows in the atlas. */
|
||||
#ifdef EXTENDED_TEXTURES
|
||||
#define ATLAS2D_MAX_ROWS_COUNT 32
|
||||
#else
|
||||
#define ATLAS2D_MAX_ROWS_COUNT 16
|
||||
#endif
|
||||
/* Maximum possible number of 1D terrain atlases. (worst case, each 1D atlas only has 1 tile) */
|
||||
#define ATLAS1D_MAX_ATLASES (ATLAS2D_TILES_PER_ROW * ATLAS2D_MAX_ROWS_COUNT)
|
||||
|
||||
extern Bitmap Atlas2D_Bitmap;
|
||||
extern int Atlas2D_TileSize, Atlas2D_RowsCount;
|
||||
extern int Atlas1D_Count, Atlas1D_TilesPerAtlas;
|
||||
/* Bitmap that contains the textures of all tiles. */
|
||||
/* Tiles are indexed left to right, top to bottom. */
|
||||
extern Bitmap Atlas_Bitmap;
|
||||
/* Size of each tile in pixels. (default 16x16) */
|
||||
extern int Atlas_TileSize;
|
||||
/* Number of rows in the atlas. (default 16, can be 32) */
|
||||
extern int Atlas_RowsCount;
|
||||
/* Number of 1D atlases the atlas was split into. */
|
||||
extern int Atlas1D_Count;
|
||||
/* Number of tiles in each 1D atlas. */
|
||||
extern int Atlas1D_TilesPerAtlas;
|
||||
/* Converts a tile id into 1D atlas index, and index within that atlas. */
|
||||
extern int Atlas1D_Mask, Atlas1D_Shift;
|
||||
/* Texture V coord that equals the size of one tile. (i.e. 1/Atlas1D_TilesPerAtlas) */
|
||||
/* NOTE: The texture U coord that equals the size of one tile is 1. */
|
||||
extern float Atlas1D_InvTileSize;
|
||||
/* Textures for each 1D atlas. Only Atlas1D_Count of these are valid. */
|
||||
extern GfxResourceID Atlas1D_TexIds[ATLAS1D_MAX_ATLASES];
|
||||
|
||||
#define Atlas2D_TileX(texLoc) ((texLoc) & ATLAS2D_MASK) /* texLoc % ATLAS2D_TILES_PER_ROW */
|
||||
@ -29,11 +44,15 @@ extern GfxResourceID Atlas1D_TexIds[ATLAS1D_MAX_ATLASES];
|
||||
/* 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 */
|
||||
|
||||
void Atlas2D_UpdateState(Bitmap* bmp);
|
||||
GfxResourceID Atlas2D_LoadTile(TextureLoc texLoc);
|
||||
void Atlas2D_Free(void);
|
||||
/* 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. */
|
||||
GfxResourceID Atlas_LoadTile(TextureLoc texLoc);
|
||||
/* Frees the atlas and 1D atlas textures. */
|
||||
void Atlas_Free(void);
|
||||
/* 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. */
|
||||
/* index is set to the index of the 1D atlas that the tile is in. */
|
||||
TextureRec Atlas1D_TexRec(TextureLoc texLoc, int uCount, int* index);
|
||||
void Atlas1D_UpdateState(void);
|
||||
int Atlas1D_UsedAtlasesCount(void);
|
||||
void Atlas1D_Free(void);
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user