mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-09-10 16:03:15 -04:00
Now write a spawn position to .mine files, also redesign webclient map downloading to be more consistent with other platforms and not rely on special CC_BUILD_WEB only code
This commit is contained in:
parent
6aec5e83f2
commit
0e916bfeed
@ -19,12 +19,11 @@ enum CC_ERRORS {
|
|||||||
WAV_ERR_STREAM_HDR = 0xCCDED007UL, /* Bytes #1-#4 aren't "RIFF" */
|
WAV_ERR_STREAM_HDR = 0xCCDED007UL, /* Bytes #1-#4 aren't "RIFF" */
|
||||||
WAV_ERR_STREAM_TYPE = 0xCCDED008UL, /* Bytes #9-#12 aren't "WAV " */
|
WAV_ERR_STREAM_TYPE = 0xCCDED008UL, /* Bytes #9-#12 aren't "WAV " */
|
||||||
WAV_ERR_DATA_TYPE = 0xCCDED009UL, /* Audio data type isn't 1 (PCM) */
|
WAV_ERR_DATA_TYPE = 0xCCDED009UL, /* Audio data type isn't 1 (PCM) */
|
||||||
/*WAV_ERR_NO_DATA = 0xCCDED00AUL, repurposed for AUDIO_ERR_MP3_SIG */
|
AUDIO_ERR_MP3_SIG = 0xCCDED00AUL, /* Signature bytes are "ID3" */
|
||||||
WAV_ERR_SAMPLE_BITS = 0xCCDED00BUL, /* Bits per sample isn't 16 */
|
WAV_ERR_SAMPLE_BITS = 0xCCDED00BUL, /* Bits per sample isn't 16 */
|
||||||
|
|
||||||
AUDIO_ERR_MP3_SIG = 0xCCDED00AUL, /* Signature bytes are "ID3" (repurposed WAV_ERR_NO_DATA) */
|
SFD_ERR_NEED_DEFAULT_NAME = 0xCCDED00CUL,
|
||||||
|
|
||||||
/*VORBIS_ERR_HEADER = 0xCCDED00CUL, no longer used */
|
|
||||||
VORBIS_ERR_WRONG_HEADER = 0xCCDED00DUL, /* Packet header doesn't match expected type */
|
VORBIS_ERR_WRONG_HEADER = 0xCCDED00DUL, /* Packet header doesn't match expected type */
|
||||||
VORBIS_ERR_FRAMING = 0xCCDED00EUL, /* Framing flag doesn't match expected value */
|
VORBIS_ERR_FRAMING = 0xCCDED00EUL, /* Framing flag doesn't match expected value */
|
||||||
VORBIS_ERR_VERSION = 0xCCDED00FUL, /* Vorbis version isn't 0 */
|
VORBIS_ERR_VERSION = 0xCCDED00FUL, /* Vorbis version isn't 0 */
|
||||||
|
@ -1588,23 +1588,19 @@ cc_result Schematic_Save(struct Stream* stream) {
|
|||||||
return Stream_Write(stream, sc_end, sizeof(sc_end));
|
return Stream_Write(stream, sc_end, sizeof(sc_end));
|
||||||
}
|
}
|
||||||
|
|
||||||
const int spawn_value = 8;
|
|
||||||
static const struct JField {
|
static const struct JField {
|
||||||
cc_uint8 type;
|
cc_uint8 type, isFloat;
|
||||||
const char* name;
|
const char* name;
|
||||||
void* value;
|
void* value;
|
||||||
} level_fields[] = {
|
} level_fields[] = {
|
||||||
{ JFIELD_I32, "width", &World.Width },
|
{ JFIELD_I32, false, "width", &World.Width },
|
||||||
{ JFIELD_I32, "depth", &World.Height },
|
{ JFIELD_I32, false, "depth", &World.Height },
|
||||||
{ JFIELD_I32, "height", &World.Length },
|
{ JFIELD_I32, false, "height", &World.Length },
|
||||||
{ JFIELD_I32, "xSpawn", &spawn_value },
|
{ JFIELD_I32, true, "xSpawn", &LocalPlayer_Instance.Base.Position.X },
|
||||||
{ JFIELD_I32, "ySpawn", &spawn_value },
|
{ JFIELD_I32, true, "ySpawn", &LocalPlayer_Instance.Base.Position.Y },
|
||||||
{ JFIELD_I32, "zSpawn", &spawn_value },
|
{ JFIELD_I32, true, "zSpawn", &LocalPlayer_Instance.Base.Position.Z },
|
||||||
/*{JFIELD_I32, "skyColor", &Env.SkyCol},
|
{ JFIELD_ARRAY,0, "blocks" }
|
||||||
{ JFIELD_I32, "fogColor", &Env.FogCol},
|
/* TODO classic only blocks */
|
||||||
{ JFIELD_I32, "cloudColor", &Env.CloudsCol},*/
|
|
||||||
{ JFIELD_ARRAY, "blocks", &World.Blocks }
|
|
||||||
/* TODO spawn, classic only blocks */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static int WriteJavaString(cc_uint8* dst, const char* value) {
|
static int WriteJavaString(cc_uint8* dst, const char* value) {
|
||||||
@ -1658,9 +1654,10 @@ cc_result Dat_Save(struct Stream* stream) {
|
|||||||
/* JSF signature + version */
|
/* JSF signature + version */
|
||||||
0xAC,0xED, 0x00,0x05
|
0xAC,0xED, 0x00,0x05
|
||||||
};
|
};
|
||||||
|
const struct JField* field;
|
||||||
cc_uint8 tmp[4];
|
cc_uint8 tmp[4];
|
||||||
cc_result res;
|
cc_result res;
|
||||||
int i;
|
int i, value;
|
||||||
|
|
||||||
if ((res = Stream_Write(stream, header, sizeof(header)))) return res;
|
if ((res = Stream_Write(stream, header, sizeof(header)))) return res;
|
||||||
if ((res = WriteClassDesc(stream, TC_OBJECT, "com.mojang.minecraft.level.Level",
|
if ((res = WriteClassDesc(stream, TC_OBJECT, "com.mojang.minecraft.level.Level",
|
||||||
@ -1669,8 +1666,11 @@ cc_result Dat_Save(struct Stream* stream) {
|
|||||||
/* Write field values */
|
/* Write field values */
|
||||||
for (i = 0; i < Array_Elems(level_fields); i++)
|
for (i = 0; i < Array_Elems(level_fields); i++)
|
||||||
{
|
{
|
||||||
if (level_fields[i].type == JFIELD_I32) {
|
field = &level_fields[i];
|
||||||
Stream_SetU32_BE(tmp, *((int*)level_fields[i].value));
|
|
||||||
|
if (field->type == JFIELD_I32) {
|
||||||
|
value = field->isFloat ? *((float*)field->value) : *((int*)field->value);
|
||||||
|
Stream_SetU32_BE(tmp, value);
|
||||||
if ((res = Stream_Write(stream, tmp, 4))) return res;
|
if ((res = Stream_Write(stream, tmp, 4))) return res;
|
||||||
} else {
|
} else {
|
||||||
if ((res = WriteClassDesc(stream, TC_ARRAY, "[B", 0, NULL))) return res;
|
if ((res = WriteClassDesc(stream, TC_ARRAY, "[B", 0, NULL))) return res;
|
||||||
|
77
src/Menus.c
77
src/Menus.c
@ -31,6 +31,7 @@
|
|||||||
#include "Options.h"
|
#include "Options.h"
|
||||||
#include "Input.h"
|
#include "Input.h"
|
||||||
#include "Utils.h"
|
#include "Utils.h"
|
||||||
|
#include "Errors.h"
|
||||||
|
|
||||||
/* Describes a menu option button */
|
/* Describes a menu option button */
|
||||||
struct MenuOptionDesc {
|
struct MenuOptionDesc {
|
||||||
@ -1301,28 +1302,7 @@ static void SaveLevelScreen_RemoveOverwrites(struct SaveLevelScreen* s) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CC_BUILD_WEB
|
static cc_result SaveLevelScreen_SaveMap(const cc_string* path) {
|
||||||
extern int interop_DownloadMap(const char* path, const char* filename);
|
|
||||||
static void DownloadMap(const cc_string* path) {
|
|
||||||
char strPath[NATIVE_STR_LEN];
|
|
||||||
char strFile[NATIVE_STR_LEN];
|
|
||||||
cc_string file;
|
|
||||||
cc_result res;
|
|
||||||
|
|
||||||
Platform_EncodeUtf8(strPath, path);
|
|
||||||
file = *path; Utils_UNSAFE_GetFilename(&file);
|
|
||||||
latform_EncodeUtf8(strFile, file);
|
|
||||||
|
|
||||||
res = interop_DownloadMap(strPath, strFile);
|
|
||||||
if (res) {
|
|
||||||
Logger_SysWarn2(res, "Downloading map", &file);
|
|
||||||
} else {
|
|
||||||
Chat_Add1("&eDownloaded map: %s", &file);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static cc_result SaveLevelScreen_SaveMap(struct SaveLevelScreen* s, const cc_string* path) {
|
|
||||||
static const cc_string schematic = String_FromConst(".schematic");
|
static const cc_string schematic = String_FromConst(".schematic");
|
||||||
static const cc_string mine = String_FromConst(".mine");
|
static const cc_string mine = String_FromConst(".mine");
|
||||||
struct Stream stream, compStream;
|
struct Stream stream, compStream;
|
||||||
@ -1363,10 +1343,10 @@ static cc_result SaveLevelScreen_SaveMap(struct SaveLevelScreen* s, const cc_str
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SaveLevelScreen_DoSave(void* screen, void* widget, const char* fmt) {
|
static void SaveLevelScreen_Save(void* screen, void* widget) {
|
||||||
cc_string path; char pathBuffer[FILENAME_SIZE];
|
|
||||||
struct SaveLevelScreen* s = (struct SaveLevelScreen*)screen;
|
struct SaveLevelScreen* s = (struct SaveLevelScreen*)screen;
|
||||||
struct ButtonWidget* btn = (struct ButtonWidget*)widget;
|
struct ButtonWidget* btn = (struct ButtonWidget*)widget;
|
||||||
|
cc_string path; char pathBuffer[FILENAME_SIZE];
|
||||||
cc_string file = s->input.base.text;
|
cc_string file = s->input.base.text;
|
||||||
cc_result res;
|
cc_result res;
|
||||||
|
|
||||||
@ -1374,9 +1354,10 @@ static void SaveLevelScreen_DoSave(void* screen, void* widget, const char* fmt)
|
|||||||
TextWidget_SetConst(&s->desc, "&ePlease enter a filename", &s->textFont);
|
TextWidget_SetConst(&s->desc, "&ePlease enter a filename", &s->textFont);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
String_InitArray(path, pathBuffer);
|
String_InitArray(path, pathBuffer);
|
||||||
String_Format1(&path, fmt, &file);
|
String_Format1(&path, "maps/%s.cw", &file);
|
||||||
String_Copy(&World.Name, &file);
|
String_Copy(&World.Name, &file);
|
||||||
|
|
||||||
if (File_Exists(&path) && !btn->optName) {
|
if (File_Exists(&path) && !btn->optName) {
|
||||||
btn->optName = "";
|
btn->optName = "";
|
||||||
@ -1385,48 +1366,38 @@ static void SaveLevelScreen_DoSave(void* screen, void* widget, const char* fmt)
|
|||||||
}
|
}
|
||||||
|
|
||||||
SaveLevelScreen_RemoveOverwrites(s);
|
SaveLevelScreen_RemoveOverwrites(s);
|
||||||
if ((res = SaveLevelScreen_SaveMap(s, &path))) return;
|
if ((res = SaveLevelScreen_SaveMap(&path))) return;
|
||||||
|
|
||||||
#ifdef CC_BUILD_WEB
|
|
||||||
if (btn == &s->save) {
|
|
||||||
Chat_Add1("&eSaved map to: %s", &path);
|
|
||||||
} else {
|
|
||||||
DownloadMap(&path);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
Chat_Add1("&eSaved map to: %s", &path);
|
Chat_Add1("&eSaved map to: %s", &path);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SaveLevelScreen_Save(void* a, void* b) {
|
|
||||||
SaveLevelScreen_DoSave(a, b, "maps/%s.cw");
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef CC_BUILD_WEB
|
|
||||||
static void SaveLevelScreen_File(void* a, void* b) {
|
|
||||||
SaveLevelScreen_DoSave(a, b, "/tmpmaps/%s.cw");
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
static void SaveLevelScreen_UploadCallback(const cc_string* path) {
|
static void SaveLevelScreen_UploadCallback(const cc_string* path) {
|
||||||
cc_result res = SaveLevelScreen_SaveMap(NULL, path);
|
cc_result res = SaveLevelScreen_SaveMap(path);
|
||||||
if (!res) Chat_Add1("&eSaved map to: %s", path);
|
if (!res) Chat_Add1("&eSaved map to: %s", path);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SaveLevelScreen_File(void* a, void* b) {
|
static void SaveLevelScreen_File(void* screen, void* b) {
|
||||||
static const char* const titles[] = {
|
static const char* const titles[] = {
|
||||||
"ClassiCube map", "MineCraft schematic", "MineCraft classic map", NULL
|
"ClassiCube map", "MineCraft schematic", "MineCraft classic map", NULL
|
||||||
};
|
};
|
||||||
static const char* const filters[] = {
|
static const char* const filters[] = {
|
||||||
".cw", ".schematic", ".mine", NULL
|
".cw", ".schematic", ".mine", NULL
|
||||||
};
|
};
|
||||||
static struct SaveFileDialogArgs args = {
|
struct SaveLevelScreen* s = (struct SaveLevelScreen*)screen;
|
||||||
filters, titles, SaveLevelScreen_UploadCallback
|
struct SaveFileDialogArgs args;
|
||||||
};
|
cc_result res;
|
||||||
|
|
||||||
cc_result res = Window_SaveFileDialog(&args);
|
args.filters = filters;
|
||||||
if (res) Logger_SimpleWarn(res, "showing save file dialog");
|
args.titles = titles;
|
||||||
|
args.defaultName = s->input.base.text;
|
||||||
|
args.Callback = SaveLevelScreen_UploadCallback;
|
||||||
|
|
||||||
|
res = Window_SaveFileDialog(&args);
|
||||||
|
if (res == SFD_ERR_NEED_DEFAULT_NAME) {
|
||||||
|
TextWidget_SetConst(&s->desc, "&ePlease enter a filename", &s->textFont);
|
||||||
|
} else if (res) {
|
||||||
|
Logger_SimpleWarn(res, "showing save file dialog");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
static int SaveLevelScreen_KeyPress(void* screen, char keyChar) {
|
static int SaveLevelScreen_KeyPress(void* screen, char keyChar) {
|
||||||
struct SaveLevelScreen* s = (struct SaveLevelScreen*)screen;
|
struct SaveLevelScreen* s = (struct SaveLevelScreen*)screen;
|
||||||
|
@ -136,6 +136,7 @@ typedef void (*FileDialogCallback)(const cc_string* path);
|
|||||||
struct SaveFileDialogArgs {
|
struct SaveFileDialogArgs {
|
||||||
const char* const* filters; /* File extensions to limit dialog to showing (e.g. ".zip", NULL) */
|
const char* const* filters; /* File extensions to limit dialog to showing (e.g. ".zip", NULL) */
|
||||||
const char* const* titles; /* Descriptions to show for each file extension */
|
const char* const* titles; /* Descriptions to show for each file extension */
|
||||||
|
cc_string defaultName; /* Default filename (without extension), required by some backends */
|
||||||
FileDialogCallback Callback;
|
FileDialogCallback Callback;
|
||||||
};
|
};
|
||||||
struct OpenFileDialogArgs {
|
struct OpenFileDialogArgs {
|
||||||
|
@ -573,6 +573,24 @@ cc_result Window_OpenFileDialog(const struct OpenFileDialogArgs* args) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern int interop_DownloadFile(const char* path, const char* filename);
|
||||||
|
cc_result Window_SaveFileDialog(const struct SaveFileDialogArgs* args) {
|
||||||
|
cc_string path; char pathBuffer[FILENAME_SIZE];
|
||||||
|
cc_string file; char fileBuffer[FILENAME_SIZE];
|
||||||
|
|
||||||
|
if (!args->defaultName.length) return SFD_ERR_NEED_DEFAULT_NAME;
|
||||||
|
|
||||||
|
String_InitArray(file, fileBuffer);
|
||||||
|
String_InitArray(path, pathBuffer);
|
||||||
|
String_Format2(&file, "%s%c", &args->defaultName, args->filters[0]);
|
||||||
|
String_Format1(&path, "Downloads/%s", &file);
|
||||||
|
|
||||||
|
args->Callback(&path);
|
||||||
|
pathBuffer[path.length] = '\0';
|
||||||
|
fileBuffer[file.length] = '\0';
|
||||||
|
return interop_DownloadFile(pathBuffer, fileBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
void Window_AllocFramebuffer(struct Bitmap* bmp) { }
|
void Window_AllocFramebuffer(struct Bitmap* bmp) { }
|
||||||
void Window_DrawFramebuffer(Rect2D r) { }
|
void Window_DrawFramebuffer(Rect2D r) { }
|
||||||
void Window_FreeFramebuffer(struct Bitmap* bmp) { }
|
void Window_FreeFramebuffer(struct Bitmap* bmp) { }
|
||||||
|
@ -93,7 +93,7 @@ mergeInto(LibraryManager.library, {
|
|||||||
//########################################################################################################################
|
//########################################################################################################################
|
||||||
//-----------------------------------------------------------Menu---------------------------------------------------------
|
//-----------------------------------------------------------Menu---------------------------------------------------------
|
||||||
//########################################################################################################################
|
//########################################################################################################################
|
||||||
interop_DownloadMap: function(path, filename) {
|
interop_DownloadFile: function(path, filename) {
|
||||||
try {
|
try {
|
||||||
var name = UTF8ToString(path);
|
var name = UTF8ToString(path);
|
||||||
var data = CCFS.readFile(name);
|
var data = CCFS.readFile(name);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user