mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-01-25 18:42:08 -05:00
Now fetches sounds and music.
This commit is contained in:
parent
f22e9ba7d6
commit
bb4efbe388
8 changed files with 279 additions and 101 deletions
|
@ -1018,6 +1018,18 @@ static void ResourcesScreen_Draw(struct LScreen* s) {
|
|||
LScreen_Draw(s);
|
||||
}
|
||||
|
||||
static void ResourcesScreen_SetStatus(const String* str) {
|
||||
BitmapCol boxCol = BITMAPCOL_CONST(120, 85, 151, 255);
|
||||
struct LLabel* w = &ResourcesScreen_Instance.LblStatus;
|
||||
|
||||
Drawer2D_Clear(&Launcher_Framebuffer, boxCol,
|
||||
w->X, w->Y, w->Width, w->Height);
|
||||
LLabel_SetText(w, str);
|
||||
w->YOffset = -10;
|
||||
LWidget_CalcPosition(w);
|
||||
LWidget_Draw(w);
|
||||
}
|
||||
|
||||
static void ResourcesScreen_UpdateStatus(struct AsyncRequest* req) {
|
||||
String str; char strBuffer[STRING_SIZE];
|
||||
String id;
|
||||
|
@ -1030,14 +1042,8 @@ static void ResourcesScreen_UpdateStatus(struct AsyncRequest* req) {
|
|||
count = Fetcher_Downloaded + 1;
|
||||
String_Format3(&str, "&eFetching %s.. (%i/%i)", &id, &count, &Resources_Count);
|
||||
|
||||
/* Don't redraw status if can avoid it */
|
||||
if (String_Equals(&str, &w->Text)) return;
|
||||
|
||||
Drawer2D_Clear(&Launcher_Framebuffer, boxCol,
|
||||
w->X, w->Y, w->Width, w->Height);
|
||||
LLabel_SetText(w, &str);
|
||||
LWidget_CalcPosition(w);
|
||||
LWidget_Draw(w);
|
||||
ResourcesScreen_SetStatus(&str);
|
||||
}
|
||||
|
||||
static void ResourcesScreen_UpdateProgress(struct ResourcesScreen* s) {
|
||||
|
@ -1055,15 +1061,29 @@ static void ResourcesScreen_UpdateProgress(struct ResourcesScreen* s) {
|
|||
s->SdrProgress.VTABLE->Draw(&s->SdrProgress);
|
||||
}
|
||||
|
||||
static void ResourcesScreen_Error(struct ResourcesScreen* s) {
|
||||
String str; char buffer[STRING_SIZE];
|
||||
String_InitArray(str, buffer);
|
||||
|
||||
if (Fetcher_Error) {
|
||||
String_Format1(&str, "&cError %h when downloading resources", &Fetcher_Error);
|
||||
} else {
|
||||
String_Format1(&str, "&c%i error when downloading resources", &Fetcher_StatusCode);
|
||||
}
|
||||
ResourcesScreen_SetStatus(&str);
|
||||
}
|
||||
|
||||
static void ResourcesScreen_Tick(struct LScreen* s_) {
|
||||
struct ResourcesScreen* s = (struct ResourcesScreen*)s_;
|
||||
if (!Fetcher_Working) return;
|
||||
ResourcesScreen_UpdateProgress(s);
|
||||
|
||||
ResourcesScreen_UpdateProgress(s);
|
||||
Fetcher_Update();
|
||||
if (!Fetcher_Completed) return;
|
||||
/* TODO: Log error here */
|
||||
//if (!FetchResourcesTask.Base.Success) return;
|
||||
|
||||
if (Fetcher_Error || Fetcher_StatusCode) {
|
||||
ResourcesScreen_Error(s); return;
|
||||
}
|
||||
|
||||
Launcher_TryLoadTexturePack();
|
||||
ResourcesScreen_Next(NULL, 0, 0);
|
||||
|
|
|
@ -456,7 +456,7 @@ static void FetchUpdateTask_Handle(uint8_t* data, uint32_t len) {
|
|||
const static String path = String_FromConst("ClassiCube.update");
|
||||
ReturnCode res;
|
||||
|
||||
res = Stream_WriteTo(&path, data, len);
|
||||
res = Stream_WriteAllTo(&path, data, len);
|
||||
if (res) { Launcher_ShowError(res, "saving update"); return; }
|
||||
|
||||
res = File_SetModifiedTime(&path, FetchUpdateTask.Timestamp);
|
||||
|
|
|
@ -348,7 +348,6 @@ void Launcher_SaveSkin(void) {
|
|||
/*########################################################################################################################*
|
||||
*----------------------------------------------------------Background-----------------------------------------------------*
|
||||
*#########################################################################################################################*/
|
||||
static FontDesc logoFont;
|
||||
static bool useBitmappedFont;
|
||||
static Bitmap terrainBmp, fontBmp;
|
||||
#define TILESIZE 48
|
||||
|
@ -599,7 +598,7 @@ static void Launcher_ApplyUpdate(void) {
|
|||
ReturnCode res;
|
||||
|
||||
/* Can't use WriteLine, want \n as actual newline not code page 437 */
|
||||
res = Stream_WriteTo(&scriptPath, UPDATE_SCRIPT, sizeof(UPDATE_SCRIPT) - 1);
|
||||
res = Stream_WriteAllTo(&scriptPath, UPDATE_SCRIPT, sizeof(UPDATE_SCRIPT) - 1);
|
||||
if (res) { Launcher_ShowError(res, "saving update script"); return; }
|
||||
|
||||
res = Platform_MarkExecutable(&scriptPath);
|
||||
|
|
314
src/Resources.c
314
src/Resources.c
|
@ -7,13 +7,14 @@
|
|||
#include "Platform.h"
|
||||
#include "Launcher.h"
|
||||
#include "Utils.h"
|
||||
|
||||
#include "Vorbis.h"
|
||||
#include "Errors.h"
|
||||
|
||||
/*########################################################################################################################*
|
||||
*---------------------------------------------------------List/Checker----------------------------------------------------*
|
||||
*#########################################################################################################################*/
|
||||
bool DigSoundsExist, StepSoundsExist;
|
||||
int Resources_Count, Resources_Downloaded, Resources_Size;
|
||||
bool SoundsExist;
|
||||
int Resources_Count, Resources_Size;
|
||||
|
||||
static void Resources_CheckFiles(void) {
|
||||
int i, flags;
|
||||
|
@ -30,8 +31,8 @@ static void Resources_CheckFiles(void) {
|
|||
static void Resources_CheckMusic(void) {
|
||||
String path; char pathBuffer[FILENAME_SIZE];
|
||||
int i;
|
||||
|
||||
String_InitArray(path, pathBuffer);
|
||||
|
||||
for (i = 0; i < Array_Elems(Resources_Music); i++) {
|
||||
path.length = 0;
|
||||
String_Format1(&path, "audio/%c", Resources_Music[i].Name);
|
||||
|
@ -44,32 +45,23 @@ static void Resources_CheckMusic(void) {
|
|||
}
|
||||
}
|
||||
|
||||
CC_NOINLINE static bool Resources_CheckExist(const char* prefix, struct ResourceSound* sounds, int count) {
|
||||
String path; char pathBuffer[FILENAME_SIZE];
|
||||
int i = 0;
|
||||
|
||||
String_InitArray(path, pathBuffer);
|
||||
for (i = 0; i < count; i++) {
|
||||
path.length = 0;
|
||||
String_Format2(&path, "audio/%c_%c.wav", prefix, sounds[i].Name);
|
||||
|
||||
if (!File_Exists(&path)) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static void Resources_CheckSounds(void) {
|
||||
DigSoundsExist = Resources_CheckExist("dig", Resources_Dig, Array_Elems(Resources_Dig));
|
||||
if (!DigSoundsExist) {
|
||||
Resources_Count += Array_Elems(Resources_Dig);
|
||||
Resources_Size += 173;
|
||||
}
|
||||
String path; char pathBuffer[FILENAME_SIZE];
|
||||
int i;
|
||||
String_InitArray(path, pathBuffer);
|
||||
|
||||
StepSoundsExist = Resources_CheckExist("step", Resources_Step, Array_Elems(Resources_Step));
|
||||
if (!StepSoundsExist) {
|
||||
Resources_Count += Array_Elems(Resources_Step);
|
||||
Resources_Size += 244;
|
||||
for (i = 0; i < Array_Elems(Resources_Sounds); i++) {
|
||||
path.length = 0;
|
||||
String_Format1(&path, "audio/%c.wav", Resources_Sounds[i].Name);
|
||||
|
||||
if (File_Exists(&path)) continue;
|
||||
SoundsExist = false;
|
||||
|
||||
Resources_Count += Array_Elems(Resources_Sounds);
|
||||
Resources_Size += 417;
|
||||
return;
|
||||
}
|
||||
SoundsExist = true;
|
||||
}
|
||||
|
||||
static bool Resources_SelectZipEntry(const String* path) {
|
||||
|
@ -145,67 +137,166 @@ struct ResourceTexture Resources_Textures[19] = {
|
|||
{ "animations.png", FLAG_MODERN }, { "gui.png", FLAG_GUI }
|
||||
};
|
||||
|
||||
struct ResourceSound Resources_Dig[31] = {
|
||||
{ "cloth1", "5f/5fd568d724ba7d53911b6cccf5636f859d2662e8" }, { "cloth2", "56/56c1d0ac0de2265018b2c41cb571cc6631101484" },
|
||||
{ "cloth3", "9c/9c63f2a3681832dc32d206f6830360bfe94b5bfc" }, { "cloth4", "55/55da1856e77cfd31a7e8c3d358e1f856c5583198" },
|
||||
{ "grass1", "41/41cbf5dd08e951ad65883854e74d2e034929f572" }, { "grass2", "86/86cb1bb0c45625b18e00a64098cd425a38f6d3f2" },
|
||||
{ "grass3", "f7/f7d7e5c7089c9b45fa5d1b31542eb455fad995db" }, { "grass4", "c7/c7b1005d4926f6a2e2387a41ab1fb48a72f18e98" },
|
||||
{ "gravel1", "e8/e8b89f316f3e9989a87f6e6ff12db9abe0f8b09f" }, { "gravel2", "c3/c3b3797d04cb9640e1d3a72d5e96edb410388fa3" },
|
||||
{ "gravel3", "48/48f7e1bb098abd36b9760cca27b9d4391a23de26" }, { "gravel4", "7b/7bf3553a4fe41a0078f4988a13d6e1ed8663ef4c" },
|
||||
{ "sand1", "9e/9e59c3650c6c3fc0a475f1b753b2fcfef430bf81" }, { "sand2", "0f/0fa4234797f336ada4e3735e013e44d1099afe57" },
|
||||
{ "sand3", "c7/c75589cc0087069f387de127dd1499580498738e" }, { "sand4", "37/37afa06f97d58767a1cd1382386db878be1532dd" },
|
||||
{ "snow1", "e9/e9bab7d3d15541f0aaa93fad31ad37fd07e03a6c" }, { "snow2", "58/5887d10234c4f244ec5468080412f3e6ef9522f3" },
|
||||
{ "snow3", "a4/a4bc069321a96236fde04a3820664cc23b2ea619" }, { "snow4", "e2/e26fa3036cdab4c2264ceb19e1cd197a2a510227" },
|
||||
{ "stone1", "4e/4e094ed8dfa98656d8fec52a7d20c5ee6098b6ad" }, { "stone2", "9c/9c92f697142ae320584bf64c0d54381d59703528" },
|
||||
{ "stone3", "8f/8f23c02475d388b23e5faa680eafe6b991d7a9d4" }, { "stone4", "36/363545a76277e5e47538b2dd3a0d6aa4f7a87d34" },
|
||||
{ "wood1", "9b/9bc2a84d0aa98113fc52609976fae8fc88ea6333" }, { "wood2", "98/98102533e6085617a2962157b4f3658f59aea018" },
|
||||
{ "wood3", "45/45b2aef7b5049e81b39b58f8d631563fadcc778b" }, { "wood4", "dc/dc66978374a46ab2b87db6472804185824868095" },
|
||||
{ "glass1", "72/7274a2231ed4544a37e599b7b014e589e5377094" }, { "glass2", "87/87c47bda3645c68f18a49e83cbf06e5302d087ff" },
|
||||
{ "glass3", "ad/ad7d770b7fff3b64121f75bd60cecfc4866d1cd6" }
|
||||
};
|
||||
struct ResourceSound Resources_Sounds[59] = {
|
||||
{ "dig_cloth1", "5fd568d724ba7d53911b6cccf5636f859d2662e8" }, { "dig_cloth2", "56c1d0ac0de2265018b2c41cb571cc6631101484" },
|
||||
{ "dig_cloth3", "9c63f2a3681832dc32d206f6830360bfe94b5bfc" }, { "dig_cloth4", "55da1856e77cfd31a7e8c3d358e1f856c5583198" },
|
||||
{ "dig_grass1", "41cbf5dd08e951ad65883854e74d2e034929f572" }, { "dig_grass2", "86cb1bb0c45625b18e00a64098cd425a38f6d3f2" },
|
||||
{ "dig_grass3", "f7d7e5c7089c9b45fa5d1b31542eb455fad995db" }, { "dig_grass4", "c7b1005d4926f6a2e2387a41ab1fb48a72f18e98" },
|
||||
{ "dig_gravel1", "e8b89f316f3e9989a87f6e6ff12db9abe0f8b09f" }, { "dig_gravel2", "c3b3797d04cb9640e1d3a72d5e96edb410388fa3" },
|
||||
{ "dig_gravel3", "48f7e1bb098abd36b9760cca27b9d4391a23de26" }, { "dig_gravel4", "7bf3553a4fe41a0078f4988a13d6e1ed8663ef4c" },
|
||||
{ "dig_sand1", "9e59c3650c6c3fc0a475f1b753b2fcfef430bf81" }, { "dig_sand2", "0fa4234797f336ada4e3735e013e44d1099afe57" },
|
||||
{ "dig_sand3", "c75589cc0087069f387de127dd1499580498738e" }, { "dig_sand4", "37afa06f97d58767a1cd1382386db878be1532dd" },
|
||||
{ "dig_snow1", "e9bab7d3d15541f0aaa93fad31ad37fd07e03a6c" }, { "dig_snow2", "5887d10234c4f244ec5468080412f3e6ef9522f3" },
|
||||
{ "dig_snow3", "a4bc069321a96236fde04a3820664cc23b2ea619" }, { "dig_snow4", "e26fa3036cdab4c2264ceb19e1cd197a2a510227" },
|
||||
{ "dig_stone1", "4e094ed8dfa98656d8fec52a7d20c5ee6098b6ad" }, { "dig_stone2", "9c92f697142ae320584bf64c0d54381d59703528" },
|
||||
{ "dig_stone3", "8f23c02475d388b23e5faa680eafe6b991d7a9d4" }, { "dig_stone4", "363545a76277e5e47538b2dd3a0d6aa4f7a87d34" },
|
||||
{ "dig_wood1", "9bc2a84d0aa98113fc52609976fae8fc88ea6333" }, { "dig_wood2", "98102533e6085617a2962157b4f3658f59aea018" },
|
||||
{ "dig_wood3", "45b2aef7b5049e81b39b58f8d631563fadcc778b" }, { "dig_wood4", "dc66978374a46ab2b87db6472804185824868095" },
|
||||
{ "dig_glass1", "7274a2231ed4544a37e599b7b014e589e5377094" }, { "dig_glass2", "87c47bda3645c68f18a49e83cbf06e5302d087ff" },
|
||||
{ "dig_glass3", "ad7d770b7fff3b64121f75bd60cecfc4866d1cd6" },
|
||||
|
||||
struct ResourceSound Resources_Step[28] = {
|
||||
{ "cloth1", "5f/5fd568d724ba7d53911b6cccf5636f859d2662e8" }, { "cloth2", "56/56c1d0ac0de2265018b2c41cb571cc6631101484" },
|
||||
{ "cloth3", "9c/9c63f2a3681832dc32d206f6830360bfe94b5bfc" }, { "cloth4", "55/55da1856e77cfd31a7e8c3d358e1f856c5583198" },
|
||||
{ "grass1", "22/227ab99bf7c6cf0b2002e0f7957d0ff7e5cb0c96" }, { "grass2", "5c/5c971029d9284676dce1dda2c9d202f8c47163b2" },
|
||||
{ "grass3", "76/76de0a736928eac5003691d73bdc2eda92116198" }, { "grass4", "bc/bc28801224a0aa77fdc93bb7c6c94beacdf77331" },
|
||||
{ "gravel1", "1d/1d761cb3bcb45498719e4fba0751e1630e134f1a" }, { "gravel2", "ac/ac7a7c8d106e26abc775b1b46150c083825d8ddc" },
|
||||
{ "gravel3", "c1/c109b985a7e6d5d3828c92e00aefa49deca0eb8c" }, { "gravel4", "a4/a47adece748059294c5f563c0fcac02fa0e4bab4" },
|
||||
{ "sand1", "98/9813c8185197f4a4296649f27a9d738c4a6dfc78" }, { "sand2", "bd/bd1750c016f6bab40934eff0b0fb64c41c86e44b" },
|
||||
{ "sand3", "ab/ab07279288fa49215bada5c17627e6a54ad0437c" }, { "sand4", "a4/a474236fb0c75bd65a6010e87dbc000d345fc185" },
|
||||
{ "snow1", "e9/e9bab7d3d15541f0aaa93fad31ad37fd07e03a6c" }, { "snow2", "58/5887d10234c4f244ec5468080412f3e6ef9522f3" },
|
||||
{ "snow3", "a4/a4bc069321a96236fde04a3820664cc23b2ea619" }, { "snow4", "e2/e26fa3036cdab4c2264ceb19e1cd197a2a510227" },
|
||||
{ "stone1", "4a/4a2e3795ffd4d3aab0834b7e41903af3a8f7d197" }, { "stone2", "22/22a383d9c22342305a4f16fec0bb479a885f8da2" },
|
||||
{ "stone3", "a5/a533e7ae975e62592de868e0d0572778614bd587" }, { "stone4", "d5/d5218034051a13322d7b5efc0b5a9af739615f04" },
|
||||
{ "wood1", "af/afb01196e2179e3b15b48f3373cea4c155d56b84" }, { "wood2", "1e/1e82a43c30cf8fcbe05d0bc2760ecba5d2320314" },
|
||||
{ "wood3", "27/27722125968ac60c0f191a961b17e406f1351c6e" }, { "wood4", "29/29586f60bfe6f521dbc748919d4f0dc5b28beefd" }
|
||||
{ "step_cloth1", "5fd568d724ba7d53911b6cccf5636f859d2662e8" }, { "step_cloth2", "56c1d0ac0de2265018b2c41cb571cc6631101484" },
|
||||
{ "step_cloth3", "9c63f2a3681832dc32d206f6830360bfe94b5bfc" }, { "step_cloth4", "55da1856e77cfd31a7e8c3d358e1f856c5583198" },
|
||||
{ "step_grass1", "227ab99bf7c6cf0b2002e0f7957d0ff7e5cb0c96" }, { "step_grass2", "5c971029d9284676dce1dda2c9d202f8c47163b2" },
|
||||
{ "step_grass3", "76de0a736928eac5003691d73bdc2eda92116198" }, { "step_grass4", "bc28801224a0aa77fdc93bb7c6c94beacdf77331" },
|
||||
{ "step_gravel1", "1d761cb3bcb45498719e4fba0751e1630e134f1a" }, { "step_gravel2", "ac7a7c8d106e26abc775b1b46150c083825d8ddc" },
|
||||
{ "step_gravel3", "c109b985a7e6d5d3828c92e00aefa49deca0eb8c" }, { "step_gravel4", "a47adece748059294c5f563c0fcac02fa0e4bab4" },
|
||||
{ "step_sand1", "9813c8185197f4a4296649f27a9d738c4a6dfc78" }, { "step_sand2", "bd1750c016f6bab40934eff0b0fb64c41c86e44b" },
|
||||
{ "step_sand3", "ab07279288fa49215bada5c17627e6a54ad0437c" }, { "step_sand4", "a474236fb0c75bd65a6010e87dbc000d345fc185" },
|
||||
{ "step_snow1", "e9bab7d3d15541f0aaa93fad31ad37fd07e03a6c" }, { "step_snow2", "5887d10234c4f244ec5468080412f3e6ef9522f3" },
|
||||
{ "step_snow3", "a4bc069321a96236fde04a3820664cc23b2ea619" }, { "step_snow4", "e26fa3036cdab4c2264ceb19e1cd197a2a510227" },
|
||||
{ "step_stone1", "4a2e3795ffd4d3aab0834b7e41903af3a8f7d197" }, { "step_stone2", "22a383d9c22342305a4f16fec0bb479a885f8da2" },
|
||||
{ "step_stone3", "a533e7ae975e62592de868e0d0572778614bd587" }, { "step_stone4", "d5218034051a13322d7b5efc0b5a9af739615f04" },
|
||||
{ "step_wood1", "afb01196e2179e3b15b48f3373cea4c155d56b84" }, { "step_wood2", "1e82a43c30cf8fcbe05d0bc2760ecba5d2320314" },
|
||||
{ "step_wood3", "27722125968ac60c0f191a961b17e406f1351c6e" }, { "step_wood4", "29586f60bfe6f521dbc748919d4f0dc5b28beefd" }
|
||||
};
|
||||
|
||||
struct ResourceMusic Resources_Music[7] = {
|
||||
{ "calm1.ogg", "50/50a59a4f56e4046701b758ddbb1c1587efa4cadf", 2472 },
|
||||
{ "calm2.ogg", "74/74da65c99aa578486efa7b69983d3533e14c0d6e", 1931 },
|
||||
{ "calm3.ogg", "14/14ae57a6bce3d4254daa8be2b098c2d99743cc3f", 2181 },
|
||||
{ "hal1.ogg", "df/df1ff11b79757432c5c3f279e5ecde7b63ceda64", 1926 },
|
||||
{ "hal2.ogg", "ce/ceaaaa1d57dfdfbb0bd4da5ea39628b42897a687", 1714 },
|
||||
{ "hal3.ogg", "dd/dd85fb564e96ee2dbd4754f711ae9deb08a169f9", 1879 },
|
||||
{ "hal4.ogg", "5e/5e7d63e75c6e042f452bc5e151276911ef92fed8", 2499 }
|
||||
{ "calm1.ogg", "50a59a4f56e4046701b758ddbb1c1587efa4cadf", 2472 },
|
||||
{ "calm2.ogg", "74da65c99aa578486efa7b69983d3533e14c0d6e", 1931 },
|
||||
{ "calm3.ogg", "14ae57a6bce3d4254daa8be2b098c2d99743cc3f", 2181 },
|
||||
{ "hal1.ogg", "df1ff11b79757432c5c3f279e5ecde7b63ceda64", 1926 },
|
||||
{ "hal2.ogg", "ceaaaa1d57dfdfbb0bd4da5ea39628b42897a687", 1714 },
|
||||
{ "hal3.ogg", "dd85fb564e96ee2dbd4754f711ae9deb08a169f9", 1879 },
|
||||
{ "hal4.ogg", "5e7d63e75c6e042f452bc5e151276911ef92fed8", 2499 }
|
||||
};
|
||||
|
||||
|
||||
/*########################################################################################################################*
|
||||
*-------------------------------------------------------Texture patcher---------------------------------------------------*
|
||||
*#########################################################################################################################*/
|
||||
|
||||
|
||||
/*########################################################################################################################*
|
||||
*--------------------------------------------------------Audio patcher----------------------------------------------------*
|
||||
*#########################################################################################################################*/
|
||||
#define WAV_FourCC(a, b, c, d) (((uint32_t)a << 24) | ((uint32_t)b << 16) | ((uint32_t)c << 8) | (uint32_t)d)
|
||||
|
||||
static void Patcher_FixupWaveHeader(struct Stream* s, struct VorbisState* ctx) {
|
||||
uint8_t header[44];
|
||||
uint32_t length;
|
||||
ReturnCode res;
|
||||
|
||||
res = s->Length(s, &length);
|
||||
if (res) { Launcher_ShowError(res, "getting .wav length"); return; }
|
||||
res = s->Seek(s, 0);
|
||||
if (res) { Launcher_ShowError(res, "seeking to .wav start"); return; }
|
||||
|
||||
Stream_SetU32_BE(&header[0], WAV_FourCC('R','I','F','F'));
|
||||
Stream_SetU32_LE(&header[4], length - 8);
|
||||
Stream_SetU32_BE(&header[8], WAV_FourCC('W','A','V','E'));
|
||||
Stream_SetU32_BE(&header[12], WAV_FourCC('f','m','t',' '));
|
||||
Stream_SetU32_LE(&header[16], 16); /* fmt chunk size */
|
||||
Stream_SetU16_LE(&header[20], 1); /* PCM audio format */
|
||||
Stream_SetU16_LE(&header[22], ctx->Channels);
|
||||
Stream_SetU32_LE(&header[24], ctx->SampleRate);
|
||||
|
||||
Stream_SetU32_LE(&header[28], ctx->SampleRate * ctx->Channels * 2); /* byte rate */
|
||||
Stream_SetU16_LE(&header[32], ctx->Channels * 2); /* block align */
|
||||
Stream_SetU16_LE(&header[34], 16); /* bits per sample */
|
||||
Stream_SetU32_BE(&header[36], WAV_FourCC('d','a','t','a'));
|
||||
Stream_SetU32_LE(&header[40], length - sizeof(header));
|
||||
|
||||
res = Stream_Write(s, header, sizeof(header));
|
||||
if (res) Launcher_ShowError(res, "fixing .wav header");
|
||||
}
|
||||
|
||||
static void Patcher_DecodeSound(struct Stream* s, struct VorbisState* ctx) {
|
||||
int16_t* samples;
|
||||
int count;
|
||||
ReturnCode res;
|
||||
|
||||
/* ctx is all 0, so reuse it here for header */
|
||||
res = Stream_Write(s, ctx, 44);
|
||||
if (res) { Launcher_ShowError(res, "writing .wav header"); return; }
|
||||
|
||||
res = Vorbis_DecodeHeaders(ctx);
|
||||
if (res) { Launcher_ShowError(res, "decoding .ogg header"); return; }
|
||||
samples = Mem_Alloc(ctx->BlockSizes[1] * ctx->Channels, 2, ".ogg samples");
|
||||
|
||||
for (;;) {
|
||||
res = Vorbis_DecodeFrame(ctx);
|
||||
if (res == ERR_END_OF_STREAM) break;
|
||||
if (res) { Launcher_ShowError(res, "decoding .ogg"); break; }
|
||||
|
||||
count = Vorbis_OutputFrame(ctx, samples);
|
||||
/* TODO: Do we need to account for big endian */
|
||||
res = Stream_Write(s, samples, count * 2);
|
||||
if (res) { Launcher_ShowError(res, "writing samples"); break; }
|
||||
}
|
||||
Mem_Free(samples);
|
||||
}
|
||||
|
||||
static void Patcher_SaveSound(struct ResourceSound* sound, struct AsyncRequest* req) {
|
||||
String path; char pathBuffer[STRING_SIZE];
|
||||
uint8_t buffer[OGG_BUFFER_SIZE];
|
||||
struct Stream src, ogg, dst;
|
||||
struct VorbisState ctx = { 0 };
|
||||
ReturnCode res;
|
||||
|
||||
Stream_ReadonlyMemory(&src, req->Data, req->Size);
|
||||
String_InitArray(path, pathBuffer);
|
||||
String_Format1(&path, "audio/%c.wav", sound->Name);
|
||||
|
||||
res = Stream_CreateFile(&dst, &path);
|
||||
if (res) { Launcher_ShowError(res, "creating .wav file"); return; }
|
||||
|
||||
Ogg_MakeStream(&ogg, buffer, &src);
|
||||
ctx.Source = &ogg;
|
||||
|
||||
Patcher_DecodeSound(&dst, &ctx);
|
||||
Patcher_FixupWaveHeader(&dst, &ctx);
|
||||
|
||||
res = dst.Close(&dst);
|
||||
if (res) Launcher_ShowError(res, "closing .wav file");
|
||||
}
|
||||
|
||||
static void Patcher_SaveMusic(struct ResourceMusic* music, struct AsyncRequest* req) {
|
||||
String path; char pathBuffer[STRING_SIZE];
|
||||
ReturnCode res;
|
||||
|
||||
String_InitArray(path, pathBuffer);
|
||||
String_Format1(&path, "audio/%c", music->Name);
|
||||
|
||||
res = Stream_WriteAllTo(&path, req->Data, req->Size);
|
||||
if (res) Launcher_ShowError(res, "saving music file");
|
||||
}
|
||||
|
||||
|
||||
/*########################################################################################################################*
|
||||
*-----------------------------------------------------------Fetcher-------------------------------------------------------*
|
||||
*#########################################################################################################################*/
|
||||
bool Fetcher_Working, Fetcher_Completed;
|
||||
int Fetcher_Downloaded;
|
||||
CC_NOINLINE static void Fetcher_DownloadAudio(const char* fmt, const char* name, const char* hash) {
|
||||
String id; char idBuffer[STRING_SIZE];
|
||||
String url; char urlBuffer[STRING_SIZE * 2];
|
||||
int Fetcher_StatusCode, Fetcher_Downloaded;
|
||||
ReturnCode Fetcher_Error;
|
||||
|
||||
String_InitArray(id, idBuffer);
|
||||
String_Format1(&id, fmt, name);
|
||||
CC_NOINLINE static void Fetcher_DownloadAudio(const char* name, const char* hash) {
|
||||
String url; char urlBuffer[STRING_SIZE * 2];
|
||||
String id = String_FromReadonly(name);
|
||||
|
||||
String_InitArray(url, urlBuffer);
|
||||
String_Format1(&url, "http://resources.download.minecraft.net/%c", hash);
|
||||
String_Format3(&url, "http://resources.download.minecraft.net/%r%r/%c",
|
||||
&hash[0], &hash[1], hash);
|
||||
AsyncDownloader_GetData(&url, false, &id);
|
||||
}
|
||||
|
||||
|
@ -214,8 +305,12 @@ void Fetcher_Run(void) {
|
|||
int i, flags;
|
||||
|
||||
if (Fetcher_Working) return;
|
||||
Fetcher_Working = true;
|
||||
Fetcher_Completed = false;
|
||||
Fetcher_Error = 0;
|
||||
Fetcher_StatusCode = 0;
|
||||
Fetcher_Downloaded = 0;
|
||||
|
||||
Fetcher_Working = true;
|
||||
Fetcher_Completed = false;
|
||||
flags = Resources_GetFetchFlags();
|
||||
|
||||
for (i = 0; i < Array_Elems(Resources_Files); i++) {
|
||||
|
@ -228,19 +323,72 @@ void Fetcher_Run(void) {
|
|||
|
||||
for (i = 0; i < Array_Elems(Resources_Music); i++) {
|
||||
if (Resources_Music[i].Exists) continue;
|
||||
Fetcher_DownloadAudio(Resources_Music[i].Name, NULL, Resources_Music[i].Hash);
|
||||
Fetcher_DownloadAudio(Resources_Music[i].Name, Resources_Music[i].Hash);
|
||||
}
|
||||
for (i = 0; i < Array_Elems(Resources_Dig); i++) {
|
||||
if (DigSoundsExist) continue;
|
||||
Fetcher_DownloadAudio("dig_%c", Resources_Dig[i].Name, Resources_Dig[i].Hash);
|
||||
for (i = 0; i < Array_Elems(Resources_Sounds); i++) {
|
||||
if (SoundsExist) continue;
|
||||
Fetcher_DownloadAudio(Resources_Sounds[i].Name, Resources_Sounds[i].Hash);
|
||||
}
|
||||
for (i = 0; i < Array_Elems(Resources_Step); i++) {
|
||||
if (StepSoundsExist) continue;
|
||||
Fetcher_DownloadAudio("step_%c", Resources_Dig[i].Name, Resources_Step[i].Hash);
|
||||
}
|
||||
|
||||
static void Fetcher_Finish(void) {
|
||||
Fetcher_Completed = true;
|
||||
Fetcher_Working = false;
|
||||
}
|
||||
|
||||
CC_NOINLINE static bool Fetcher_Get(const String* id, struct AsyncRequest* req) {
|
||||
if (!AsyncDownloader_Get(id, req)) return false;
|
||||
|
||||
if (req->Result) {
|
||||
Fetcher_Error = req->Result;
|
||||
Fetcher_Finish();
|
||||
return false;
|
||||
} else if (req->StatusCode != 200) {
|
||||
Fetcher_StatusCode = req->StatusCode;
|
||||
Fetcher_Finish();
|
||||
return false;
|
||||
} else if (!req->Data) {
|
||||
Fetcher_Error = ReturnCode_InvalidArg;
|
||||
Fetcher_Finish();
|
||||
return false;
|
||||
}
|
||||
|
||||
Fetcher_Downloaded++;
|
||||
return true;
|
||||
}
|
||||
|
||||
static void Fetcher_CheckMusic(struct ResourceMusic* music) {
|
||||
String id = String_FromReadonly(music->Name);
|
||||
struct AsyncRequest req;
|
||||
if (!Fetcher_Get(&id, &req)) return;
|
||||
|
||||
music->Exists = true;
|
||||
Patcher_SaveMusic(music, &req);
|
||||
ASyncRequest_Free(&req);
|
||||
}
|
||||
|
||||
static void Fetcher_CheckSound(struct ResourceSound* sound) {
|
||||
String id = String_FromReadonly(sound->Name);
|
||||
struct AsyncRequest req;
|
||||
if (!Fetcher_Get(&id, &req)) return;
|
||||
|
||||
Patcher_SaveSound(sound, &req);
|
||||
ASyncRequest_Free(&req);
|
||||
}
|
||||
|
||||
/* TODO: Implement this.. */
|
||||
void Fetcher_Update(void) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < Array_Elems(Resources_Music); i++) {
|
||||
if (Resources_Music[i].Exists) continue;
|
||||
Fetcher_CheckMusic(&Resources_Music[i]);
|
||||
}
|
||||
|
||||
for (i = 0; i < Array_Elems(Resources_Sounds); i++) {
|
||||
Fetcher_CheckSound(&Resources_Sounds[i]);
|
||||
}
|
||||
|
||||
if (Fetcher_Downloaded != Resources_Count) return;
|
||||
Fetcher_Finish();
|
||||
}
|
|
@ -27,7 +27,7 @@ extern struct ResourceTexture {
|
|||
extern struct ResourceSound {
|
||||
const char* Name;
|
||||
const char* Hash;
|
||||
} Resources_Dig[31], Resources_Step[28];
|
||||
} Resources_Sounds[59];
|
||||
|
||||
extern struct ResourceMusic {
|
||||
const char* Name;
|
||||
|
@ -36,7 +36,7 @@ extern struct ResourceMusic {
|
|||
bool Exists;
|
||||
} Resources_Music[7];
|
||||
|
||||
extern bool DigSoundsExist, StepSoundsExist;
|
||||
extern bool SoundsExist;
|
||||
/* Number of resources that need to be downloaded. */
|
||||
extern int Resources_Count;
|
||||
/* Total size of resources that need to be downloaded. */
|
||||
|
@ -52,6 +52,11 @@ extern bool Fetcher_Working;
|
|||
extern bool Fetcher_Completed;
|
||||
/* Number of resources that have been downloaded so far. */
|
||||
extern int Fetcher_Downloaded;
|
||||
/* HTTP error (if any) that occurs when downloaded resources. */
|
||||
extern int Fetcher_StatusCode;
|
||||
/* Error (if any) that occurs when downloaded resources. */
|
||||
extern ReturnCode Fetcher_Error;
|
||||
|
||||
/* Starts asynchronous download of required resources. */
|
||||
void Fetcher_Run(void);
|
||||
void Fetcher_Update(void);
|
||||
|
|
|
@ -121,7 +121,7 @@ ReturnCode Stream_CreateFile(struct Stream* s, const String* path) {
|
|||
return res;
|
||||
}
|
||||
|
||||
ReturnCode Stream_WriteTo(const String* path, const uint8_t* data, uint32_t length) {
|
||||
ReturnCode Stream_WriteAllTo(const String* path, const uint8_t* data, uint32_t length) {
|
||||
struct Stream stream;
|
||||
ReturnCode res, closeRes;
|
||||
|
||||
|
@ -385,6 +385,10 @@ uint32_t Stream_GetU32_BE(const uint8_t* data) {
|
|||
((uint32_t)data[2] << 8) | (uint32_t)data[3]);
|
||||
}
|
||||
|
||||
void Stream_SetU16_LE(uint8_t* data, uint16_t value) {
|
||||
data[0] = (uint8_t)(value ); data[1] = (uint8_t)(value >> 8 );
|
||||
}
|
||||
|
||||
void Stream_SetU16_BE(uint8_t* data, uint16_t value) {
|
||||
data[0] = (uint8_t)(value >> 8 ); data[1] = (uint8_t)(value );
|
||||
}
|
||||
|
|
|
@ -54,7 +54,7 @@ CC_API ReturnCode Stream_OpenFile(struct Stream* s, const String* path);
|
|||
/* Wrapper for File_Create() then Stream_FromFile() */
|
||||
CC_API ReturnCode Stream_CreateFile(struct Stream* s, const String* path);
|
||||
/* Creates or overwrites a file, setting the contents to the given data. */
|
||||
ReturnCode Stream_WriteTo(const String* path, const uint8_t* data, uint32_t length);
|
||||
ReturnCode Stream_WriteAllTo(const String* path, const uint8_t* data, uint32_t length);
|
||||
/* Wraps a file, allowing reading from/writing to/seeking in the file. */
|
||||
CC_API void Stream_FromFile(struct Stream* s, FileHandle file);
|
||||
|
||||
|
@ -76,6 +76,8 @@ uint32_t Stream_GetU32_LE(const uint8_t* data);
|
|||
/* Reads a big-endian 32 bit unsigned integer from memory. */
|
||||
uint32_t Stream_GetU32_BE(const uint8_t* data);
|
||||
|
||||
/* Writes a little-endian 16 bit unsigned integer to memory. */
|
||||
void Stream_SetU16_LE(uint8_t* data, uint16_t value);
|
||||
/* Writes a big-endian 16 bit unsigned integer to memory. */
|
||||
void Stream_SetU16_BE(uint8_t* data, uint16_t value);
|
||||
/* Writes a little-endian 32 bit unsigned integer to memory. */
|
||||
|
|
|
@ -589,7 +589,7 @@ void TextureCache_Set(const String* url, uint8_t* data, uint32_t length) {
|
|||
TextureCache_MakePath(&path, url);
|
||||
if (!Utils_EnsureDirectory("texturecache")) return;
|
||||
|
||||
res = Stream_WriteTo(&path, data, length);
|
||||
res = Stream_WriteAllTo(&path, data, length);
|
||||
if (res) { Chat_LogError2(res, "caching", url); }
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue