diff --git a/ClassicalSharp/Entities/Entity.cs b/ClassicalSharp/Entities/Entity.cs
index 89c697276..d7d58bc73 100644
--- a/ClassicalSharp/Entities/Entity.cs
+++ b/ClassicalSharp/Entities/Entity.cs
@@ -16,20 +16,10 @@ namespace ClassicalSharp.Entities {
anim = new AnimatedComponent(game, this);
}
- /// The model of this entity. (used for collision detection and rendering)
public IModel Model;
-
- /// The name of the model of this entity.
- public string ModelName;
-
- /// BlockID if model name is a vaid block id.
- /// This avoids needing to repeatedly parse ModelName as a byte.
+ public string SkinName, ModelName;
public BlockID ModelBlock;
-
- /// Scale applied to the model for collision detection and rendering.
public Vector3 ModelScale = new Vector3(1.0f);
-
- /// Returns the size of the model that is used for collision detection.
public Vector3 Size;
public int TextureId, MobTextureId;
@@ -132,6 +122,10 @@ namespace ClassicalSharp.Entities {
ParseScale(scale);
Model.RecalcProperties(this);
UpdateModelBounds();
+
+ if (SkinName != null && Utils.IsUrlPrefix(SkinName, 0)) {
+ MobTextureId = TextureId;
+ }
}
public void UpdateModelBounds() {
diff --git a/ClassicalSharp/Entities/Player.cs b/ClassicalSharp/Entities/Player.cs
index 8c8ce7a7c..f776d0328 100644
--- a/ClassicalSharp/Entities/Player.cs
+++ b/ClassicalSharp/Entities/Player.cs
@@ -14,7 +14,7 @@ namespace ClassicalSharp.Entities {
public abstract class Player : Entity {
- public string DisplayName, SkinName;
+ public string DisplayName;
protected Texture nameTex;
internal bool fetchedSkin;
diff --git a/src/Audio.c b/src/Audio.c
index 1ead41347..8292032f2 100644
--- a/src/Audio.c
+++ b/src/Audio.c
@@ -91,7 +91,7 @@ static ReturnCode Sound_ReadWaveData(struct Stream* stream, struct Sound* snd) {
snd->Format.BitsPerSample = Stream_GetU16_LE(&tmp[14]);
size -= WAV_FMT_SIZE;
} else if (fourCC == WAV_FourCC('d','a','t','a')) {
- snd->Data = Mem_Alloc(size, sizeof(UInt8), "WAV sound data");
+ snd->Data = Mem_Alloc(size, 1, "WAV sound data");
snd->DataSize = size;
return Stream_Read(stream, snd->Data, size);
}
@@ -498,8 +498,9 @@ static Int32 AudioManager_GetVolume(const char* volKey, const char* boolKey) {
return volume;
}
-static void AudioManager_FilesCallback(const String* filename, void* obj) {
- StringsBuffer_Add(&files, filename);
+static void AudioManager_FilesCallback(const String* path, void* obj) {
+ String file = *path; Utils_UNSAFE_GetFilename(&file);
+ StringsBuffer_Add(&files, &file);
}
static void AudioManager_Init(void) {
diff --git a/src/Entity.c b/src/Entity.c
index 72defc4d6..4acfdb99f 100644
--- a/src/Entity.c
+++ b/src/Entity.c
@@ -72,6 +72,7 @@ void Entity_Init(struct Entity* e) {
e->ModelScale = Vector3_Create1(1.0f);
e->uScale = 1.0f;
e->vScale = 1.0f;
+ e->SkinNameRaw[0] = '\0';
}
Vector3 Entity_GetEyePosition(struct Entity* e) {
@@ -153,6 +154,8 @@ void Entity_SetModel(struct Entity* e, const String* model) {
e->Model->RecalcProperties(e);
Entity_UpdateModelBounds(e);
+ String skin = String_FromRawArray(e->SkinNameRaw);
+ if (Utils_IsUrlPrefix(&skin, 0)) { e->MobTextureId = e->TextureId; }
}
void Entity_UpdateModelBounds(struct Entity* e) {
@@ -546,14 +549,15 @@ static void Player_DrawName(struct Player* player) {
static struct Player* Player_FirstOtherWithSameSkin(struct Player* player) {
struct Entity* entity = &player->Base;
- String skin = String_FromRawArray(player->SkinNameRaw);
+ String skin = String_FromRawArray(entity->SkinNameRaw);
Int32 i;
+
for (i = 0; i < ENTITIES_MAX_COUNT; i++) {
if (!Entities_List[i] || Entities_List[i] == entity) continue;
if (Entities_List[i]->EntityType != ENTITY_TYPE_PLAYER) continue;
struct Player* p = (struct Player*)Entities_List[i];
- String pSkin = String_FromRawArray(p->SkinNameRaw);
+ String pSkin = String_FromRawArray(p->Base.SkinNameRaw);
if (String_Equals(&skin, &pSkin)) return p;
}
return NULL;
@@ -561,14 +565,15 @@ static struct Player* Player_FirstOtherWithSameSkin(struct Player* player) {
static struct Player* Player_FirstOtherWithSameSkinAndFetchedSkin(struct Player* player) {
struct Entity* entity = &player->Base;
- String skin = String_FromRawArray(player->SkinNameRaw);
+ String skin = String_FromRawArray(entity->SkinNameRaw);
Int32 i;
+
for (i = 0; i < ENTITIES_MAX_COUNT; i++) {
if (!Entities_List[i] || Entities_List[i] == entity) continue;
if (Entities_List[i]->EntityType != ENTITY_TYPE_PLAYER) continue;
struct Player* p = (struct Player*)Entities_List[i];
- String pSkin = String_FromRawArray(p->SkinNameRaw);
+ String pSkin = String_FromRawArray(p->Base.SkinNameRaw);
if (p->FetchedSkin && String_Equals(&skin, &pSkin)) return p;
}
return NULL;
@@ -585,10 +590,8 @@ static void Player_ApplySkin(struct Player* player, struct Player* from) {
/* Custom mob textures */
dst->MobTextureId = NULL;
- String skin = String_FromRawArray(player->SkinNameRaw);
- if (Utils_IsUrlPrefix(&skin, 0)) {
- dst->MobTextureId = dst->TextureId;
- }
+ String skin = String_FromRawArray(dst->SkinNameRaw);
+ if (Utils_IsUrlPrefix(&skin, 0)) { dst->MobTextureId = dst->TextureId; }
}
void Player_ResetSkin(struct Player* player) {
@@ -601,14 +604,16 @@ void Player_ResetSkin(struct Player* player) {
/* Apply or reset skin, for all players with same skin */
static void Player_SetSkinAll(struct Player* player, bool reset) {
- String skin = String_FromRawArray(player->SkinNameRaw);
+ struct Entity* entity = &player->Base;
+ String skin = String_FromRawArray(entity->SkinNameRaw);
Int32 i;
+
for (i = 0; i < ENTITIES_MAX_COUNT; i++) {
if (!Entities_List[i]) continue;
if (Entities_List[i]->EntityType != ENTITY_TYPE_PLAYER) continue;
struct Player* p = (struct Player*)Entities_List[i];
- String pSkin = String_FromRawArray(p->SkinNameRaw);
+ String pSkin = String_FromRawArray(p->Base.SkinNameRaw);
if (!String_Equals(&skin, &pSkin)) continue;
if (reset) {
@@ -670,23 +675,23 @@ static void Player_EnsurePow2(struct Player* player, Bitmap* bmp) {
*bmp = scaled;
}
-static void Player_CheckSkin(struct Player* player) {
- struct Entity* entity = &player->Base;
- String skin = String_FromRawArray(player->SkinNameRaw);
+static void Player_CheckSkin(struct Player* p) {
+ struct Entity* e = &p->Base;
+ String skin = String_FromRawArray(e->SkinNameRaw);
- if (!player->FetchedSkin && entity->Model->UsesSkin) {
- struct Player* first = Player_FirstOtherWithSameSkinAndFetchedSkin(player);
+ if (!p->FetchedSkin && e->Model->UsesSkin) {
+ struct Player* first = Player_FirstOtherWithSameSkinAndFetchedSkin(p);
if (!first) {
AsyncDownloader_GetSkin(&skin, &skin);
} else {
- Player_ApplySkin(player, first);
+ Player_ApplySkin(p, first);
}
- player->FetchedSkin = true;
+ p->FetchedSkin = true;
}
struct AsyncRequest item;
if (!AsyncDownloader_Get(&skin, &item)) return;
- if (!item.ResultData) { Player_SetSkinAll(player, true); return; }
+ if (!item.ResultData) { Player_SetSkinAll(p, true); return; }
String url = String_FromRawArray(item.URL);
struct Stream mem; Bitmap bmp;
@@ -698,19 +703,19 @@ static void Player_CheckSkin(struct Player* player) {
Mem_Free(bmp.Scan0); return;
}
- Gfx_DeleteTexture(&entity->TextureId);
- Player_SetSkinAll(player, true);
- Player_EnsurePow2(player, &bmp);
- entity->SkinType = Utils_GetSkinType(&bmp);
+ Gfx_DeleteTexture(&e->TextureId);
+ Player_SetSkinAll(p, true);
+ Player_EnsurePow2(p, &bmp);
+ e->SkinType = Utils_GetSkinType(&bmp);
- if (entity->SkinType == SKIN_INVALID) {
- Player_SetSkinAll(player, true);
+ if (e->SkinType == SKIN_INVALID) {
+ Player_SetSkinAll(p, true);
} else {
- if (entity->Model->UsesHumanSkin) {
- Player_ClearHat(&bmp, entity->SkinType);
+ if (e->Model->UsesHumanSkin) {
+ Player_ClearHat(&bmp, e->SkinType);
}
- entity->TextureId = Gfx_CreateTexture(&bmp, true, false);
- Player_SetSkinAll(player, false);
+ e->TextureId = Gfx_CreateTexture(&bmp, true, false);
+ Player_SetSkinAll(p, false);
}
Mem_Free(bmp.Scan0);
}
@@ -736,10 +741,10 @@ static void Player_ContextRecreated(struct Entity* e) {
Player_UpdateNameTex(player);
}
-void Player_SetName(struct Player* player, const String* name, const String* skin) {
- String p_name = String_ClearedArray(player->DisplayNameRaw);
+void Player_SetName(struct Player* p, const String* name, const String* skin) {
+ String p_name = String_ClearedArray(p->DisplayNameRaw);
String_AppendString(&p_name, name);
- String p_skin = String_ClearedArray(player->SkinNameRaw);
+ String p_skin = String_ClearedArray(p->Base.SkinNameRaw);
String_AppendString(&p_skin, skin);
}
diff --git a/src/Entity.h b/src/Entity.h
index 30122b18d..2fefa79e7 100644
--- a/src/Entity.h
+++ b/src/Entity.h
@@ -86,6 +86,7 @@ struct Entity {
struct Matrix Transform;
struct AnimatedComp Anim;
+ char SkinNameRaw[STRING_SIZE];
};
void Entity_Init(struct Entity* entity);
@@ -126,7 +127,7 @@ void TabList_MakeComponent(struct IGameComponent* comp);
#define TabList_UNSAFE_GetPlayer(id) StringsBuffer_UNSAFE_Get(&TabList_Buffer, TabList_PlayerNames[id]);
#define TabList_UNSAFE_GetList(id) StringsBuffer_UNSAFE_Get(&TabList_Buffer, TabList_ListNames[id]);
#define TabList_UNSAFE_GetGroup(id) StringsBuffer_UNSAFE_Get(&TabList_Buffer, TabList_GroupNames[id]);
-#define Player_Layout struct Entity Base; char DisplayNameRaw[STRING_SIZE]; char SkinNameRaw[STRING_SIZE]; bool FetchedSkin; struct Texture NameTex;
+#define Player_Layout struct Entity Base; char DisplayNameRaw[STRING_SIZE]; bool FetchedSkin; struct Texture NameTex;
/* Represents a player entity. */
struct Player { Player_Layout };
diff --git a/src/Formats.c b/src/Formats.c
index a7ed84b68..d4326922a 100644
--- a/src/Formats.c
+++ b/src/Formats.c
@@ -308,7 +308,7 @@ static ReturnCode Nbt_ReadTag(UInt8 typeId, bool readTagName, struct Stream* str
if (tag.DataSize < NBT_SMALL_SIZE) {
res = Stream_Read(stream, tag.DataSmall, tag.DataSize);
} else {
- tag.DataBig = Mem_Alloc(tag.DataSize, sizeof(UInt8), "NBT data");
+ tag.DataBig = Mem_Alloc(tag.DataSize, 1, "NBT data");
res = Stream_Read(stream, tag.DataBig, tag.DataSize);
if (res) { Mem_Free(tag.DataBig); }
}
@@ -719,7 +719,7 @@ static ReturnCode Dat_ReadFieldData(struct Stream* stream, struct JFieldDesc* fi
if ((res = Stream_ReadU32_BE(stream, &count))) return res;
field->Value_Size = count;
- field->Value_Ptr = Mem_Alloc(count, sizeof(UInt8), ".dat map blocks");
+ field->Value_Ptr = Mem_Alloc(count, 1, ".dat map blocks");
res = Stream_Read(stream, field->Value_Ptr, count);
if (res) { Mem_Free(field->Value_Ptr); return res; }
} break;
diff --git a/src/Menus.c b/src/Menus.c
index 2853351bd..624faaa2c 100644
--- a/src/Menus.c
+++ b/src/Menus.c
@@ -1399,10 +1399,12 @@ static void TexturePackScreen_EntryClick(void* screen, void* widget) {
ListScreen_SetCurrentIndex(s, idx);
}
-static void TexturePackScreen_FilterFiles(const String* filename, void* obj) {
+static void TexturePackScreen_FilterFiles(const String* path, void* obj) {
String zip = String_FromConst(".zip");
- if (!String_CaselessEnds(filename, &zip)) return;
- StringsBuffer_Add((StringsBuffer*)obj, filename);
+ if (!String_CaselessEnds(path, &zip)) return;
+
+ String file = *path; Utils_UNSAFE_GetFilename(&file);
+ StringsBuffer_Add((StringsBuffer*)obj, &file);
}
struct Screen* TexturePackScreen_MakeInstance(void) {
@@ -1545,13 +1547,15 @@ struct Screen* HotkeyListScreen_MakeInstance(void) {
/*########################################################################################################################*
*----------------------------------------------------LoadLevelScreen------------------------------------------------------*
*#########################################################################################################################*/
-static void LoadLevelScreen_FilterFiles(const String* filename, void* obj) {
- String cw = String_FromConst(".cw"); String lvl = String_FromConst(".lvl");
+static void LoadLevelScreen_FilterFiles(const String* path, void* obj) {
+ String cw = String_FromConst(".cw"); String lvl = String_FromConst(".lvl");
String fcm = String_FromConst(".fcm"); String dat = String_FromConst(".dat");
- if (!(String_CaselessEnds(filename, &cw) || String_CaselessEnds(filename, &lvl)
- || String_CaselessEnds(filename, &fcm) || String_CaselessEnds(filename, &dat))) return;
- StringsBuffer_Add((StringsBuffer*)obj, filename);
+ if (!(String_CaselessEnds(path, &cw) || String_CaselessEnds(path, &lvl)
+ || String_CaselessEnds(path, &fcm) || String_CaselessEnds(path, &dat))) return;
+
+ String file = *path; Utils_UNSAFE_GetFilename(&file);
+ StringsBuffer_Add((StringsBuffer*)obj, &file);
}
void LoadLevelScreen_LoadMap(const String* path) {
diff --git a/src/Platform.c b/src/Platform.c
index 2456e29f7..eab376254 100644
--- a/src/Platform.c
+++ b/src/Platform.c
@@ -306,28 +306,27 @@ bool File_Exists(const String* path) {
return attribs != INVALID_FILE_ATTRIBUTES && !(attribs & FILE_ATTRIBUTE_DIRECTORY);
}
-ReturnCode Directory_Enum(const String* path, void* obj, Directory_EnumCallback callback) {
- char fileBuffer[MAX_PATH + 10];
- String file = String_FromArray(fileBuffer);
+ReturnCode Directory_Enum(const String* dirPath, void* obj, Directory_EnumCallback callback) {
+ char pathBuffer[MAX_PATH + 10];
+ String path = String_FromArray(pathBuffer);
/* Need to append \* to search for files in directory */
- String_Format1(&file, "%s\\*", path);
- WCHAR str[300]; Platform_ConvertString(str, &file);
+ String_Format1(&path, "%s\\*", dirPath);
+ WCHAR str[300]; Platform_ConvertString(str, &path);
WIN32_FIND_DATAW entry;
HANDLE find = FindFirstFileW(str, &entry);
if (find == INVALID_HANDLE_VALUE) return GetLastError();
do {
- if (entry.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) continue;
- file.length = 0;
+ if (entry.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) continue;
+ path.length = 0;
+ String_Format2(&path, "%s%r", dirPath, &Directory_Separator);
Int32 i;
for (i = 0; i < MAX_PATH && entry.cFileName[i]; i++) {
- String_Append(&file, Convert_UnicodeToCP437(entry.cFileName[i]));
+ String_Append(&path, Convert_UnicodeToCP437(entry.cFileName[i]));
}
-
- Utils_UNSAFE_GetFilename(&file);
- callback(&file, obj);
+ callback(&path, obj);
} while (FindNextFileW(find, &entry));
ReturnCode result = GetLastError(); /* return code from FindNextFile */
@@ -418,27 +417,25 @@ bool File_Exists(const String* path) {
return stat(str, &sb) == 0 && S_ISREG(sb.st_mode);
}
-ReturnCode Directory_Enum(const String* path, void* obj, Directory_EnumCallback callback) {
- char str[600]; Platform_ConvertString(str, path);
+ReturnCode Directory_Enum(const String* dirPath, void* obj, Directory_EnumCallback callback) {
+ char str[600]; Platform_ConvertString(str, dirPath);
DIR* dirPtr = opendir(str);
if (!dirPtr) return errno;
- char fileBuffer[FILENAME_SIZE];
- String file = String_FromArray(fileBuffer);
+ char pathBuffer[FILENAME_SIZE];
+ String path = String_FromArray(pathBuffer);
struct dirent* entry;
/* TODO: does this also include subdirectories */
while (entry = readdir(dirPtr)) {
UInt16 len = String_CalcLen(entry->d_name, UInt16_MaxValue);
- file.length = 0;
- String_DecodeUtf8(&file, entry->d_name, len);
+ path.length = 0;
+ String_DecodeUtf8(&path, entry->d_name, len);
/* exlude . and .. paths */
- if (file.length == 1 && file.buffer[0] == '.') continue;
- if (file.length == 2 && file.buffer[0] == '.' && file.buffer[1] == '.') continue;
-
- Utils_UNSAFE_GetFilename(&file);
- callback(&file, obj);
+ if (path.length == 1 && path.buffer[0] == '.') continue;
+ if (path.length == 2 && path.buffer[0] == '.' && path.buffer[1] == '.') continue;
+ callback(&path, obj);
}
int result = errno; /* return code from readdir */
@@ -734,12 +731,10 @@ void Font_Free(FontDesc* desc) {
desc->Handle = NULL;
}
-static void Font_DirCallback(const String* filename, void* obj) {
+static void Font_DirCallback(const String* srcPath, void* obj) {
char pathBuffer[FILENAME_SIZE + 1];
String path = String_NT_Array(pathBuffer);
- String* dir = obj;
-
- String_Format2(&path, "%s%s", dir, filename);
+ String_Copy(&path, srcPath);
path.buffer[path.length] = '\0';
FT_Face face;
@@ -828,8 +823,8 @@ Size2D Platform_TextDraw(struct DrawTextArgs* args, Bitmap* bmp, Int32 x, Int32
#if CC_BUILD_WIN
static void Font_Init(void) {
FT_Error err = FT_Init_FreeType(&lib);
- String dir = String_FromConst("C:\\Windows\\fonts\\");
- Directory_Enum(&dir, &dir, Font_DirCallback);
+ String dir = String_FromConst("C:\\Windows\\fonts");
+ Directory_Enum(&dir, NULL, Font_DirCallback);
}
#elif CC_BUILD_NIX
#endif