mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-09-14 18:15:28 -04:00
Fix full URL skins for non-humanoid disappearing when changing model of an entity
This commit is contained in:
parent
c8b081f348
commit
ab9fe3c14f
@ -16,20 +16,10 @@ namespace ClassicalSharp.Entities {
|
|||||||
anim = new AnimatedComponent(game, this);
|
anim = new AnimatedComponent(game, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary> The model of this entity. (used for collision detection and rendering) </summary>
|
|
||||||
public IModel Model;
|
public IModel Model;
|
||||||
|
public string SkinName, ModelName;
|
||||||
/// <summary> The name of the model of this entity. </summary>
|
|
||||||
public string ModelName;
|
|
||||||
|
|
||||||
/// <summary> BlockID if model name is a vaid block id. </summary>
|
|
||||||
/// <remarks> This avoids needing to repeatedly parse ModelName as a byte. </remarks>
|
|
||||||
public BlockID ModelBlock;
|
public BlockID ModelBlock;
|
||||||
|
|
||||||
/// <summary> Scale applied to the model for collision detection and rendering. </summary>
|
|
||||||
public Vector3 ModelScale = new Vector3(1.0f);
|
public Vector3 ModelScale = new Vector3(1.0f);
|
||||||
|
|
||||||
/// <summary> Returns the size of the model that is used for collision detection. </summary>
|
|
||||||
public Vector3 Size;
|
public Vector3 Size;
|
||||||
|
|
||||||
public int TextureId, MobTextureId;
|
public int TextureId, MobTextureId;
|
||||||
@ -132,6 +122,10 @@ namespace ClassicalSharp.Entities {
|
|||||||
ParseScale(scale);
|
ParseScale(scale);
|
||||||
Model.RecalcProperties(this);
|
Model.RecalcProperties(this);
|
||||||
UpdateModelBounds();
|
UpdateModelBounds();
|
||||||
|
|
||||||
|
if (SkinName != null && Utils.IsUrlPrefix(SkinName, 0)) {
|
||||||
|
MobTextureId = TextureId;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UpdateModelBounds() {
|
public void UpdateModelBounds() {
|
||||||
|
@ -14,7 +14,7 @@ namespace ClassicalSharp.Entities {
|
|||||||
|
|
||||||
public abstract class Player : Entity {
|
public abstract class Player : Entity {
|
||||||
|
|
||||||
public string DisplayName, SkinName;
|
public string DisplayName;
|
||||||
protected Texture nameTex;
|
protected Texture nameTex;
|
||||||
internal bool fetchedSkin;
|
internal bool fetchedSkin;
|
||||||
|
|
||||||
|
@ -91,7 +91,7 @@ static ReturnCode Sound_ReadWaveData(struct Stream* stream, struct Sound* snd) {
|
|||||||
snd->Format.BitsPerSample = Stream_GetU16_LE(&tmp[14]);
|
snd->Format.BitsPerSample = Stream_GetU16_LE(&tmp[14]);
|
||||||
size -= WAV_FMT_SIZE;
|
size -= WAV_FMT_SIZE;
|
||||||
} else if (fourCC == WAV_FourCC('d','a','t','a')) {
|
} 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;
|
snd->DataSize = size;
|
||||||
return Stream_Read(stream, snd->Data, size);
|
return Stream_Read(stream, snd->Data, size);
|
||||||
}
|
}
|
||||||
@ -498,8 +498,9 @@ static Int32 AudioManager_GetVolume(const char* volKey, const char* boolKey) {
|
|||||||
return volume;
|
return volume;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void AudioManager_FilesCallback(const String* filename, void* obj) {
|
static void AudioManager_FilesCallback(const String* path, void* obj) {
|
||||||
StringsBuffer_Add(&files, filename);
|
String file = *path; Utils_UNSAFE_GetFilename(&file);
|
||||||
|
StringsBuffer_Add(&files, &file);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void AudioManager_Init(void) {
|
static void AudioManager_Init(void) {
|
||||||
|
67
src/Entity.c
67
src/Entity.c
@ -72,6 +72,7 @@ void Entity_Init(struct Entity* e) {
|
|||||||
e->ModelScale = Vector3_Create1(1.0f);
|
e->ModelScale = Vector3_Create1(1.0f);
|
||||||
e->uScale = 1.0f;
|
e->uScale = 1.0f;
|
||||||
e->vScale = 1.0f;
|
e->vScale = 1.0f;
|
||||||
|
e->SkinNameRaw[0] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector3 Entity_GetEyePosition(struct Entity* e) {
|
Vector3 Entity_GetEyePosition(struct Entity* e) {
|
||||||
@ -153,6 +154,8 @@ void Entity_SetModel(struct Entity* e, const String* model) {
|
|||||||
e->Model->RecalcProperties(e);
|
e->Model->RecalcProperties(e);
|
||||||
Entity_UpdateModelBounds(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) {
|
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) {
|
static struct Player* Player_FirstOtherWithSameSkin(struct Player* player) {
|
||||||
struct Entity* entity = &player->Base;
|
struct Entity* entity = &player->Base;
|
||||||
String skin = String_FromRawArray(player->SkinNameRaw);
|
String skin = String_FromRawArray(entity->SkinNameRaw);
|
||||||
Int32 i;
|
Int32 i;
|
||||||
|
|
||||||
for (i = 0; i < ENTITIES_MAX_COUNT; i++) {
|
for (i = 0; i < ENTITIES_MAX_COUNT; i++) {
|
||||||
if (!Entities_List[i] || Entities_List[i] == entity) continue;
|
if (!Entities_List[i] || Entities_List[i] == entity) continue;
|
||||||
if (Entities_List[i]->EntityType != ENTITY_TYPE_PLAYER) continue;
|
if (Entities_List[i]->EntityType != ENTITY_TYPE_PLAYER) continue;
|
||||||
|
|
||||||
struct Player* p = (struct Player*)Entities_List[i];
|
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;
|
if (String_Equals(&skin, &pSkin)) return p;
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -561,14 +565,15 @@ static struct Player* Player_FirstOtherWithSameSkin(struct Player* player) {
|
|||||||
|
|
||||||
static struct Player* Player_FirstOtherWithSameSkinAndFetchedSkin(struct Player* player) {
|
static struct Player* Player_FirstOtherWithSameSkinAndFetchedSkin(struct Player* player) {
|
||||||
struct Entity* entity = &player->Base;
|
struct Entity* entity = &player->Base;
|
||||||
String skin = String_FromRawArray(player->SkinNameRaw);
|
String skin = String_FromRawArray(entity->SkinNameRaw);
|
||||||
Int32 i;
|
Int32 i;
|
||||||
|
|
||||||
for (i = 0; i < ENTITIES_MAX_COUNT; i++) {
|
for (i = 0; i < ENTITIES_MAX_COUNT; i++) {
|
||||||
if (!Entities_List[i] || Entities_List[i] == entity) continue;
|
if (!Entities_List[i] || Entities_List[i] == entity) continue;
|
||||||
if (Entities_List[i]->EntityType != ENTITY_TYPE_PLAYER) continue;
|
if (Entities_List[i]->EntityType != ENTITY_TYPE_PLAYER) continue;
|
||||||
|
|
||||||
struct Player* p = (struct Player*)Entities_List[i];
|
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;
|
if (p->FetchedSkin && String_Equals(&skin, &pSkin)) return p;
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -585,10 +590,8 @@ static void Player_ApplySkin(struct Player* player, struct Player* from) {
|
|||||||
|
|
||||||
/* Custom mob textures */
|
/* Custom mob textures */
|
||||||
dst->MobTextureId = NULL;
|
dst->MobTextureId = NULL;
|
||||||
String skin = String_FromRawArray(player->SkinNameRaw);
|
String skin = String_FromRawArray(dst->SkinNameRaw);
|
||||||
if (Utils_IsUrlPrefix(&skin, 0)) {
|
if (Utils_IsUrlPrefix(&skin, 0)) { dst->MobTextureId = dst->TextureId; }
|
||||||
dst->MobTextureId = dst->TextureId;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Player_ResetSkin(struct Player* player) {
|
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 */
|
/* Apply or reset skin, for all players with same skin */
|
||||||
static void Player_SetSkinAll(struct Player* player, bool reset) {
|
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;
|
Int32 i;
|
||||||
|
|
||||||
for (i = 0; i < ENTITIES_MAX_COUNT; i++) {
|
for (i = 0; i < ENTITIES_MAX_COUNT; i++) {
|
||||||
if (!Entities_List[i]) continue;
|
if (!Entities_List[i]) continue;
|
||||||
if (Entities_List[i]->EntityType != ENTITY_TYPE_PLAYER) continue;
|
if (Entities_List[i]->EntityType != ENTITY_TYPE_PLAYER) continue;
|
||||||
|
|
||||||
struct Player* p = (struct Player*)Entities_List[i];
|
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 (!String_Equals(&skin, &pSkin)) continue;
|
||||||
|
|
||||||
if (reset) {
|
if (reset) {
|
||||||
@ -670,23 +675,23 @@ static void Player_EnsurePow2(struct Player* player, Bitmap* bmp) {
|
|||||||
*bmp = scaled;
|
*bmp = scaled;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Player_CheckSkin(struct Player* player) {
|
static void Player_CheckSkin(struct Player* p) {
|
||||||
struct Entity* entity = &player->Base;
|
struct Entity* e = &p->Base;
|
||||||
String skin = String_FromRawArray(player->SkinNameRaw);
|
String skin = String_FromRawArray(e->SkinNameRaw);
|
||||||
|
|
||||||
if (!player->FetchedSkin && entity->Model->UsesSkin) {
|
if (!p->FetchedSkin && e->Model->UsesSkin) {
|
||||||
struct Player* first = Player_FirstOtherWithSameSkinAndFetchedSkin(player);
|
struct Player* first = Player_FirstOtherWithSameSkinAndFetchedSkin(p);
|
||||||
if (!first) {
|
if (!first) {
|
||||||
AsyncDownloader_GetSkin(&skin, &skin);
|
AsyncDownloader_GetSkin(&skin, &skin);
|
||||||
} else {
|
} else {
|
||||||
Player_ApplySkin(player, first);
|
Player_ApplySkin(p, first);
|
||||||
}
|
}
|
||||||
player->FetchedSkin = true;
|
p->FetchedSkin = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct AsyncRequest item;
|
struct AsyncRequest item;
|
||||||
if (!AsyncDownloader_Get(&skin, &item)) return;
|
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);
|
String url = String_FromRawArray(item.URL);
|
||||||
struct Stream mem; Bitmap bmp;
|
struct Stream mem; Bitmap bmp;
|
||||||
@ -698,19 +703,19 @@ static void Player_CheckSkin(struct Player* player) {
|
|||||||
Mem_Free(bmp.Scan0); return;
|
Mem_Free(bmp.Scan0); return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Gfx_DeleteTexture(&entity->TextureId);
|
Gfx_DeleteTexture(&e->TextureId);
|
||||||
Player_SetSkinAll(player, true);
|
Player_SetSkinAll(p, true);
|
||||||
Player_EnsurePow2(player, &bmp);
|
Player_EnsurePow2(p, &bmp);
|
||||||
entity->SkinType = Utils_GetSkinType(&bmp);
|
e->SkinType = Utils_GetSkinType(&bmp);
|
||||||
|
|
||||||
if (entity->SkinType == SKIN_INVALID) {
|
if (e->SkinType == SKIN_INVALID) {
|
||||||
Player_SetSkinAll(player, true);
|
Player_SetSkinAll(p, true);
|
||||||
} else {
|
} else {
|
||||||
if (entity->Model->UsesHumanSkin) {
|
if (e->Model->UsesHumanSkin) {
|
||||||
Player_ClearHat(&bmp, entity->SkinType);
|
Player_ClearHat(&bmp, e->SkinType);
|
||||||
}
|
}
|
||||||
entity->TextureId = Gfx_CreateTexture(&bmp, true, false);
|
e->TextureId = Gfx_CreateTexture(&bmp, true, false);
|
||||||
Player_SetSkinAll(player, false);
|
Player_SetSkinAll(p, false);
|
||||||
}
|
}
|
||||||
Mem_Free(bmp.Scan0);
|
Mem_Free(bmp.Scan0);
|
||||||
}
|
}
|
||||||
@ -736,10 +741,10 @@ static void Player_ContextRecreated(struct Entity* e) {
|
|||||||
Player_UpdateNameTex(player);
|
Player_UpdateNameTex(player);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Player_SetName(struct Player* player, const String* name, const String* skin) {
|
void Player_SetName(struct Player* p, const String* name, const String* skin) {
|
||||||
String p_name = String_ClearedArray(player->DisplayNameRaw);
|
String p_name = String_ClearedArray(p->DisplayNameRaw);
|
||||||
String_AppendString(&p_name, name);
|
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);
|
String_AppendString(&p_skin, skin);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,6 +86,7 @@ struct Entity {
|
|||||||
struct Matrix Transform;
|
struct Matrix Transform;
|
||||||
|
|
||||||
struct AnimatedComp Anim;
|
struct AnimatedComp Anim;
|
||||||
|
char SkinNameRaw[STRING_SIZE];
|
||||||
};
|
};
|
||||||
|
|
||||||
void Entity_Init(struct Entity* entity);
|
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_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_GetList(id) StringsBuffer_UNSAFE_Get(&TabList_Buffer, TabList_ListNames[id]);
|
||||||
#define TabList_UNSAFE_GetGroup(id) StringsBuffer_UNSAFE_Get(&TabList_Buffer, TabList_GroupNames[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. */
|
/* Represents a player entity. */
|
||||||
struct Player { Player_Layout };
|
struct Player { Player_Layout };
|
||||||
|
@ -308,7 +308,7 @@ static ReturnCode Nbt_ReadTag(UInt8 typeId, bool readTagName, struct Stream* str
|
|||||||
if (tag.DataSize < NBT_SMALL_SIZE) {
|
if (tag.DataSize < NBT_SMALL_SIZE) {
|
||||||
res = Stream_Read(stream, tag.DataSmall, tag.DataSize);
|
res = Stream_Read(stream, tag.DataSmall, tag.DataSize);
|
||||||
} else {
|
} 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);
|
res = Stream_Read(stream, tag.DataBig, tag.DataSize);
|
||||||
if (res) { Mem_Free(tag.DataBig); }
|
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;
|
if ((res = Stream_ReadU32_BE(stream, &count))) return res;
|
||||||
field->Value_Size = count;
|
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);
|
res = Stream_Read(stream, field->Value_Ptr, count);
|
||||||
if (res) { Mem_Free(field->Value_Ptr); return res; }
|
if (res) { Mem_Free(field->Value_Ptr); return res; }
|
||||||
} break;
|
} break;
|
||||||
|
20
src/Menus.c
20
src/Menus.c
@ -1399,10 +1399,12 @@ static void TexturePackScreen_EntryClick(void* screen, void* widget) {
|
|||||||
ListScreen_SetCurrentIndex(s, idx);
|
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");
|
String zip = String_FromConst(".zip");
|
||||||
if (!String_CaselessEnds(filename, &zip)) return;
|
if (!String_CaselessEnds(path, &zip)) return;
|
||||||
StringsBuffer_Add((StringsBuffer*)obj, filename);
|
|
||||||
|
String file = *path; Utils_UNSAFE_GetFilename(&file);
|
||||||
|
StringsBuffer_Add((StringsBuffer*)obj, &file);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Screen* TexturePackScreen_MakeInstance(void) {
|
struct Screen* TexturePackScreen_MakeInstance(void) {
|
||||||
@ -1545,13 +1547,15 @@ struct Screen* HotkeyListScreen_MakeInstance(void) {
|
|||||||
/*########################################################################################################################*
|
/*########################################################################################################################*
|
||||||
*----------------------------------------------------LoadLevelScreen------------------------------------------------------*
|
*----------------------------------------------------LoadLevelScreen------------------------------------------------------*
|
||||||
*#########################################################################################################################*/
|
*#########################################################################################################################*/
|
||||||
static void LoadLevelScreen_FilterFiles(const String* filename, void* obj) {
|
static void LoadLevelScreen_FilterFiles(const String* path, void* obj) {
|
||||||
String cw = String_FromConst(".cw"); String lvl = String_FromConst(".lvl");
|
String cw = String_FromConst(".cw"); String lvl = String_FromConst(".lvl");
|
||||||
String fcm = String_FromConst(".fcm"); String dat = String_FromConst(".dat");
|
String fcm = String_FromConst(".fcm"); String dat = String_FromConst(".dat");
|
||||||
|
|
||||||
if (!(String_CaselessEnds(filename, &cw) || String_CaselessEnds(filename, &lvl)
|
if (!(String_CaselessEnds(path, &cw) || String_CaselessEnds(path, &lvl)
|
||||||
|| String_CaselessEnds(filename, &fcm) || String_CaselessEnds(filename, &dat))) return;
|
|| String_CaselessEnds(path, &fcm) || String_CaselessEnds(path, &dat))) return;
|
||||||
StringsBuffer_Add((StringsBuffer*)obj, filename);
|
|
||||||
|
String file = *path; Utils_UNSAFE_GetFilename(&file);
|
||||||
|
StringsBuffer_Add((StringsBuffer*)obj, &file);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LoadLevelScreen_LoadMap(const String* path) {
|
void LoadLevelScreen_LoadMap(const String* path) {
|
||||||
|
@ -306,28 +306,27 @@ bool File_Exists(const String* path) {
|
|||||||
return attribs != INVALID_FILE_ATTRIBUTES && !(attribs & FILE_ATTRIBUTE_DIRECTORY);
|
return attribs != INVALID_FILE_ATTRIBUTES && !(attribs & FILE_ATTRIBUTE_DIRECTORY);
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnCode Directory_Enum(const String* path, void* obj, Directory_EnumCallback callback) {
|
ReturnCode Directory_Enum(const String* dirPath, void* obj, Directory_EnumCallback callback) {
|
||||||
char fileBuffer[MAX_PATH + 10];
|
char pathBuffer[MAX_PATH + 10];
|
||||||
String file = String_FromArray(fileBuffer);
|
String path = String_FromArray(pathBuffer);
|
||||||
/* Need to append \* to search for files in directory */
|
/* Need to append \* to search for files in directory */
|
||||||
String_Format1(&file, "%s\\*", path);
|
String_Format1(&path, "%s\\*", dirPath);
|
||||||
WCHAR str[300]; Platform_ConvertString(str, &file);
|
WCHAR str[300]; Platform_ConvertString(str, &path);
|
||||||
|
|
||||||
WIN32_FIND_DATAW entry;
|
WIN32_FIND_DATAW entry;
|
||||||
HANDLE find = FindFirstFileW(str, &entry);
|
HANDLE find = FindFirstFileW(str, &entry);
|
||||||
if (find == INVALID_HANDLE_VALUE) return GetLastError();
|
if (find == INVALID_HANDLE_VALUE) return GetLastError();
|
||||||
|
|
||||||
do {
|
do {
|
||||||
if (entry.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) continue;
|
if (entry.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) continue;
|
||||||
file.length = 0;
|
path.length = 0;
|
||||||
|
String_Format2(&path, "%s%r", dirPath, &Directory_Separator);
|
||||||
Int32 i;
|
Int32 i;
|
||||||
|
|
||||||
for (i = 0; i < MAX_PATH && entry.cFileName[i]; 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]));
|
||||||
}
|
}
|
||||||
|
callback(&path, obj);
|
||||||
Utils_UNSAFE_GetFilename(&file);
|
|
||||||
callback(&file, obj);
|
|
||||||
} while (FindNextFileW(find, &entry));
|
} while (FindNextFileW(find, &entry));
|
||||||
|
|
||||||
ReturnCode result = GetLastError(); /* return code from FindNextFile */
|
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);
|
return stat(str, &sb) == 0 && S_ISREG(sb.st_mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnCode Directory_Enum(const String* path, void* obj, Directory_EnumCallback callback) {
|
ReturnCode Directory_Enum(const String* dirPath, void* obj, Directory_EnumCallback callback) {
|
||||||
char str[600]; Platform_ConvertString(str, path);
|
char str[600]; Platform_ConvertString(str, dirPath);
|
||||||
DIR* dirPtr = opendir(str);
|
DIR* dirPtr = opendir(str);
|
||||||
if (!dirPtr) return errno;
|
if (!dirPtr) return errno;
|
||||||
|
|
||||||
char fileBuffer[FILENAME_SIZE];
|
char pathBuffer[FILENAME_SIZE];
|
||||||
String file = String_FromArray(fileBuffer);
|
String path = String_FromArray(pathBuffer);
|
||||||
struct dirent* entry;
|
struct dirent* entry;
|
||||||
|
|
||||||
/* TODO: does this also include subdirectories */
|
/* TODO: does this also include subdirectories */
|
||||||
while (entry = readdir(dirPtr)) {
|
while (entry = readdir(dirPtr)) {
|
||||||
UInt16 len = String_CalcLen(entry->d_name, UInt16_MaxValue);
|
UInt16 len = String_CalcLen(entry->d_name, UInt16_MaxValue);
|
||||||
file.length = 0;
|
path.length = 0;
|
||||||
String_DecodeUtf8(&file, entry->d_name, len);
|
String_DecodeUtf8(&path, entry->d_name, len);
|
||||||
|
|
||||||
/* exlude . and .. paths */
|
/* exlude . and .. paths */
|
||||||
if (file.length == 1 && file.buffer[0] == '.') continue;
|
if (path.length == 1 && path.buffer[0] == '.') continue;
|
||||||
if (file.length == 2 && file.buffer[0] == '.' && file.buffer[1] == '.') continue;
|
if (path.length == 2 && path.buffer[0] == '.' && path.buffer[1] == '.') continue;
|
||||||
|
callback(&path, obj);
|
||||||
Utils_UNSAFE_GetFilename(&file);
|
|
||||||
callback(&file, obj);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int result = errno; /* return code from readdir */
|
int result = errno; /* return code from readdir */
|
||||||
@ -734,12 +731,10 @@ void Font_Free(FontDesc* desc) {
|
|||||||
desc->Handle = NULL;
|
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];
|
char pathBuffer[FILENAME_SIZE + 1];
|
||||||
String path = String_NT_Array(pathBuffer);
|
String path = String_NT_Array(pathBuffer);
|
||||||
String* dir = obj;
|
String_Copy(&path, srcPath);
|
||||||
|
|
||||||
String_Format2(&path, "%s%s", dir, filename);
|
|
||||||
path.buffer[path.length] = '\0';
|
path.buffer[path.length] = '\0';
|
||||||
|
|
||||||
FT_Face face;
|
FT_Face face;
|
||||||
@ -828,8 +823,8 @@ Size2D Platform_TextDraw(struct DrawTextArgs* args, Bitmap* bmp, Int32 x, Int32
|
|||||||
#if CC_BUILD_WIN
|
#if CC_BUILD_WIN
|
||||||
static void Font_Init(void) {
|
static void Font_Init(void) {
|
||||||
FT_Error err = FT_Init_FreeType(&lib);
|
FT_Error err = FT_Init_FreeType(&lib);
|
||||||
String dir = String_FromConst("C:\\Windows\\fonts\\");
|
String dir = String_FromConst("C:\\Windows\\fonts");
|
||||||
Directory_Enum(&dir, &dir, Font_DirCallback);
|
Directory_Enum(&dir, NULL, Font_DirCallback);
|
||||||
}
|
}
|
||||||
#elif CC_BUILD_NIX
|
#elif CC_BUILD_NIX
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user