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