mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-09-14 10:05:44 -04:00
Dreamcast: Store options.txt to the VMU if can't use an SD card
This commit is contained in:
parent
8dc49de72f
commit
54cd0e18e2
24
src/Block.c
24
src/Block.c
@ -204,12 +204,12 @@ static void Block_CalcLightOffset(BlockID block) {
|
||||
int flags = 0xFF;
|
||||
Vec3 min = Blocks.MinBB[block], max = Blocks.MaxBB[block];
|
||||
|
||||
if (min.x != 0) flags &= ~(1 << FACE_XMIN);
|
||||
if (max.x != 1) flags &= ~(1 << FACE_XMAX);
|
||||
if (min.z != 0) flags &= ~(1 << FACE_ZMIN);
|
||||
if (max.z != 1) flags &= ~(1 << FACE_ZMAX);
|
||||
if (min.y != 0) flags &= ~(1 << FACE_YMIN);
|
||||
if (max.y != 1) flags &= ~(1 << FACE_YMAX);
|
||||
if (min.x != 0) flags &= ~FACE_BIT_XMIN;
|
||||
if (max.x != 1) flags &= ~FACE_BIT_XMAX;
|
||||
if (min.z != 0) flags &= ~FACE_BIT_ZMIN;
|
||||
if (max.z != 1) flags &= ~FACE_BIT_ZMAX;
|
||||
if (min.y != 0) flags &= ~FACE_BIT_YMIN;
|
||||
if (max.y != 1) flags &= ~FACE_BIT_YMAX;
|
||||
|
||||
if ((min.y != 0 && max.y == 1) && Blocks.Draw[block] != DRAW_GAS) {
|
||||
flags &= ~(1 << LIGHT_FLAG_SHADES_FROM_BELOW);
|
||||
@ -380,12 +380,12 @@ static void Block_CalcCulling(BlockID block, BlockID other) {
|
||||
occludedY = (bMin.x >= oMin.x && bMax.x <= oMax.x) && (bMin.z >= oMin.z && bMax.z <= oMax.z);
|
||||
occludedZ = (bMin.x >= oMin.x && bMax.x <= oMax.x) && (bMin.y >= oMin.y && bMax.y <= oMax.y);
|
||||
|
||||
f |= occludedX && oMax.x == 1.0f && bMin.x == 0.0f ? (1 << FACE_XMIN) : 0;
|
||||
f |= occludedX && oMin.x == 0.0f && bMax.x == 1.0f ? (1 << FACE_XMAX) : 0;
|
||||
f |= occludedZ && oMax.z == 1.0f && bMin.z == 0.0f ? (1 << FACE_ZMIN) : 0;
|
||||
f |= occludedZ && oMin.z == 0.0f && bMax.z == 1.0f ? (1 << FACE_ZMAX) : 0;
|
||||
f |= occludedY && (bothLiquid || (oMax.y == 1.0f && bMin.y == 0.0f)) ? (1 << FACE_YMIN) : 0;
|
||||
f |= occludedY && (bothLiquid || (oMin.y == 0.0f && bMax.y == 1.0f)) ? (1 << FACE_YMAX) : 0;
|
||||
f |= occludedX && oMax.x == 1.0f && bMin.x == 0.0f ? FACE_BIT_XMIN : 0;
|
||||
f |= occludedX && oMin.x == 0.0f && bMax.x == 1.0f ? FACE_BIT_XMAX : 0;
|
||||
f |= occludedZ && oMax.z == 1.0f && bMin.z == 0.0f ? FACE_BIT_ZMIN : 0;
|
||||
f |= occludedZ && oMin.z == 0.0f && bMax.z == 1.0f ? FACE_BIT_ZMAX : 0;
|
||||
f |= occludedY && (bothLiquid || (oMax.y == 1.0f && bMin.y == 0.0f)) ? FACE_BIT_YMIN : 0;
|
||||
f |= occludedY && (bothLiquid || (oMin.y == 0.0f && bMax.y == 1.0f)) ? FACE_BIT_YMAX : 0;
|
||||
Blocks.Hidden[(block * BLOCK_COUNT) + other] = f;
|
||||
}
|
||||
|
||||
|
@ -189,7 +189,7 @@ static void PrepareChunk(int x1, int y1, int z1) {
|
||||
|
||||
if (Builder_Counts[index] == 0 ||
|
||||
(x == 0 && (y < Builder_SidesLevel || (b >= BLOCK_WATER && b <= BLOCK_STILL_LAVA && y < Builder_EdgeLevel))) ||
|
||||
(x != 0 && (Blocks.Hidden[tileIdx + Builder_Chunk[cIndex - 1]] & (1 << FACE_XMIN)) != 0)) {
|
||||
(x != 0 && (Blocks.Hidden[tileIdx + Builder_Chunk[cIndex - 1]] & FACE_BIT_XMIN) != 0)) {
|
||||
Builder_Counts[index] = 0;
|
||||
} else {
|
||||
Builder_Counts[index] = Builder_StretchZ(index, x, y, z, cIndex, b, FACE_XMIN);
|
||||
@ -198,7 +198,7 @@ static void PrepareChunk(int x1, int y1, int z1) {
|
||||
index++;
|
||||
if (Builder_Counts[index] == 0 ||
|
||||
(x == World.MaxX && (y < Builder_SidesLevel || (b >= BLOCK_WATER && b <= BLOCK_STILL_LAVA && y < Builder_EdgeLevel))) ||
|
||||
(x != World.MaxX && (Blocks.Hidden[tileIdx + Builder_Chunk[cIndex + 1]] & (1 << FACE_XMAX)) != 0)) {
|
||||
(x != World.MaxX && (Blocks.Hidden[tileIdx + Builder_Chunk[cIndex + 1]] & FACE_BIT_XMAX) != 0)) {
|
||||
Builder_Counts[index] = 0;
|
||||
} else {
|
||||
Builder_Counts[index] = Builder_StretchZ(index, x, y, z, cIndex, b, FACE_XMAX);
|
||||
@ -207,7 +207,7 @@ static void PrepareChunk(int x1, int y1, int z1) {
|
||||
index++;
|
||||
if (Builder_Counts[index] == 0 ||
|
||||
(z == 0 && (y < Builder_SidesLevel || (b >= BLOCK_WATER && b <= BLOCK_STILL_LAVA && y < Builder_EdgeLevel))) ||
|
||||
(z != 0 && (Blocks.Hidden[tileIdx + Builder_Chunk[cIndex - EXTCHUNK_SIZE]] & (1 << FACE_ZMIN)) != 0)) {
|
||||
(z != 0 && (Blocks.Hidden[tileIdx + Builder_Chunk[cIndex - EXTCHUNK_SIZE]] & FACE_BIT_ZMIN) != 0)) {
|
||||
Builder_Counts[index] = 0;
|
||||
} else {
|
||||
Builder_Counts[index] = Builder_StretchX(index, x, y, z, cIndex, b, FACE_ZMIN);
|
||||
@ -216,7 +216,7 @@ static void PrepareChunk(int x1, int y1, int z1) {
|
||||
index++;
|
||||
if (Builder_Counts[index] == 0 ||
|
||||
(z == World.MaxZ && (y < Builder_SidesLevel || (b >= BLOCK_WATER && b <= BLOCK_STILL_LAVA && y < Builder_EdgeLevel))) ||
|
||||
(z != World.MaxZ && (Blocks.Hidden[tileIdx + Builder_Chunk[cIndex + EXTCHUNK_SIZE]] & (1 << FACE_ZMAX)) != 0)) {
|
||||
(z != World.MaxZ && (Blocks.Hidden[tileIdx + Builder_Chunk[cIndex + EXTCHUNK_SIZE]] & FACE_BIT_ZMAX) != 0)) {
|
||||
Builder_Counts[index] = 0;
|
||||
} else {
|
||||
Builder_Counts[index] = Builder_StretchX(index, x, y, z, cIndex, b, FACE_ZMAX);
|
||||
@ -224,7 +224,7 @@ static void PrepareChunk(int x1, int y1, int z1) {
|
||||
|
||||
index++;
|
||||
if (Builder_Counts[index] == 0 || y == 0 ||
|
||||
(Blocks.Hidden[tileIdx + Builder_Chunk[cIndex - EXTCHUNK_SIZE_2]] & (1 << FACE_YMIN)) != 0) {
|
||||
(Blocks.Hidden[tileIdx + Builder_Chunk[cIndex - EXTCHUNK_SIZE_2]] & FACE_BIT_YMIN) != 0) {
|
||||
Builder_Counts[index] = 0;
|
||||
} else {
|
||||
Builder_Counts[index] = Builder_StretchX(index, x, y, z, cIndex, b, FACE_YMIN);
|
||||
@ -232,7 +232,7 @@ static void PrepareChunk(int x1, int y1, int z1) {
|
||||
|
||||
index++;
|
||||
if (Builder_Counts[index] == 0 ||
|
||||
(Blocks.Hidden[tileIdx + Builder_Chunk[cIndex + EXTCHUNK_SIZE_2]] & (1 << FACE_YMAX)) != 0) {
|
||||
(Blocks.Hidden[tileIdx + Builder_Chunk[cIndex + EXTCHUNK_SIZE_2]] & FACE_BIT_YMAX) != 0) {
|
||||
Builder_Counts[index] = 0;
|
||||
} else if (b < BLOCK_WATER || b > BLOCK_STILL_LAVA) {
|
||||
Builder_Counts[index] = Builder_StretchX(index, x, y, z, cIndex, b, FACE_YMAX);
|
||||
|
@ -49,12 +49,12 @@ Copyright 2014-2023 ClassiCube | Licensed under BSD-3
|
||||
#define GUI_MAX_CHATLINES 30
|
||||
|
||||
enum FACE_CONSTS {
|
||||
FACE_XMIN = 0, /* Face X = 0 */
|
||||
FACE_XMAX = 1, /* Face X = 1 */
|
||||
FACE_ZMIN = 2, /* Face Z = 0 */
|
||||
FACE_ZMAX = 3, /* Face Z = 1 */
|
||||
FACE_YMIN = 4, /* Face Y = 0 */
|
||||
FACE_YMAX = 5, /* Face Y = 1 */
|
||||
FACE_XMIN = 0, FACE_BIT_XMIN = 1 << FACE_XMIN, /* Face X = 0 */
|
||||
FACE_XMAX = 1, FACE_BIT_XMAX = 1 << FACE_XMAX, /* Face X = 1 */
|
||||
FACE_ZMIN = 2, FACE_BIT_ZMIN = 1 << FACE_ZMIN, /* Face Z = 0 */
|
||||
FACE_ZMAX = 3, FACE_BIT_ZMAX = 1 << FACE_ZMAX, /* Face Z = 1 */
|
||||
FACE_YMIN = 4, FACE_BIT_YMIN = 1 << FACE_YMIN, /* Face Y = 0 */
|
||||
FACE_YMAX = 5, FACE_BIT_YMAX = 1 << FACE_YMAX, /* Face Y = 1 */
|
||||
FACE_COUNT= 6 /* Number of faces on a cube */
|
||||
};
|
||||
|
||||
|
@ -107,6 +107,81 @@ void DateTime_CurrentLocal(struct DateTime* t) {
|
||||
}
|
||||
|
||||
|
||||
/*########################################################################################################################*
|
||||
*----------------------------------------------------VMU options file-----------------------------------------------------*
|
||||
*#########################################################################################################################*/
|
||||
static volatile int vmu_write_FD = -10000;
|
||||
static int VMUFile_Do(cc_file* file, int mode) {
|
||||
void* data = NULL;
|
||||
int fd, err = -1, len;
|
||||
vmu_pkg_t pkg;
|
||||
|
||||
errno = 0;
|
||||
fd = fs_open("/vmu/a1/CCOPT.txt", O_RDONLY);
|
||||
|
||||
// Try to extract stored data from the VMU
|
||||
if (fd >= 0) {
|
||||
len = fs_total(fd);
|
||||
data = Mem_Alloc(len, 1, "VMU data");
|
||||
fs_read(fd, data, len);
|
||||
|
||||
err = vmu_pkg_parse(data, &pkg);
|
||||
fs_close(fd);
|
||||
}
|
||||
|
||||
// Copy VMU data into a RAM temp file
|
||||
errno = 0;
|
||||
fd = fs_open("/ram/ccopt", O_RDWR | O_CREAT | O_TRUNC);
|
||||
if (fd < 0) return errno;
|
||||
|
||||
if (err >= 0) {
|
||||
fs_write(fd, pkg.data, pkg.data_len);
|
||||
fs_seek(fd, 0, SEEK_SET);
|
||||
}
|
||||
Mem_Free(data);
|
||||
|
||||
if (mode != O_RDONLY) vmu_write_FD = fd;
|
||||
*file = fd;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static cc_result VMUFile_Close(cc_file file) {
|
||||
void* data;
|
||||
uint8* pkg_data;
|
||||
int fd, err = -1, len, pkg_len;
|
||||
vmu_pkg_t pkg = { 0 };
|
||||
vmu_write_FD = -10000;
|
||||
|
||||
len = fs_total(file);
|
||||
data = Mem_Alloc(len, 1, "VMU data");
|
||||
fs_seek(file, 0, SEEK_SET);
|
||||
fs_read(file, data, len);
|
||||
|
||||
fs_close(file);
|
||||
fs_unlink("/ram/ccopt");
|
||||
|
||||
strcpy(pkg.desc_short, "CC options file");
|
||||
strcpy(pkg.desc_long, "ClassiCube config/settings");
|
||||
strcpy(pkg.app_id, "ClassiCube");
|
||||
pkg.eyecatch_type = VMUPKG_EC_NONE;
|
||||
pkg.data_len = len;
|
||||
pkg.data = data;
|
||||
|
||||
err = vmu_pkg_build(&pkg, &pkg_data, &pkg_len);
|
||||
if (err) { Mem_Free(data); return ERR_OUT_OF_MEMORY; }
|
||||
|
||||
// Copy into VMU file
|
||||
errno = 0;
|
||||
fd = fs_open("/vmu/a1/CCOPT.txt", O_RDWR | O_CREAT | O_TRUNC);
|
||||
if (fd < 0) return errno;
|
||||
|
||||
fs_write(fd, pkg_data, pkg_len);
|
||||
fs_close(fd);
|
||||
free(pkg_data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*########################################################################################################################*
|
||||
*-----------------------------------------------------Directory/File------------------------------------------------------*
|
||||
*#########################################################################################################################*/
|
||||
@ -193,6 +268,11 @@ static cc_result File_Do(cc_file* file, const cc_string* path, int mode) {
|
||||
|
||||
int err = res == -1 ? errno : 0;
|
||||
if (res == -1 && err == 0) err = ENOENT;
|
||||
|
||||
// Read/Write VMU for options.txt, since that file is critical
|
||||
if (err && Platform_ReadonlyFilesystem && String_CaselessEqualsConst(path, "options.txt")) {
|
||||
return VMUFile_Do(file, mode);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
@ -219,6 +299,9 @@ cc_result File_Write(cc_file file, const void* data, cc_uint32 count, cc_uint32*
|
||||
}
|
||||
|
||||
cc_result File_Close(cc_file file) {
|
||||
if (file == vmu_write_FD)
|
||||
return VMUFile_Close(file);
|
||||
|
||||
int res = fs_close(file);
|
||||
return res == -1 ? errno : 0;
|
||||
}
|
||||
@ -453,17 +536,17 @@ static void InitSDCard(void) {
|
||||
|
||||
if (sd_blockdev_for_partition(0, &sd_dev, &partition_type)) {
|
||||
Platform_LogConst("Unable to find first partition on SD card"); return;
|
||||
}
|
||||
|
||||
if (fs_fat_init()) {
|
||||
}
|
||||
|
||||
if (fs_fat_init()) {
|
||||
Platform_LogConst("Failed to init FAT filesystem"); return;
|
||||
}
|
||||
|
||||
if (fs_fat_mount("/sd", &sd_dev, FS_FAT_MOUNT_READWRITE)) {
|
||||
if (fs_fat_mount("/sd", &sd_dev, FS_FAT_MOUNT_READWRITE)) {
|
||||
Platform_LogConst("Failed to mount SD card"); return;
|
||||
}
|
||||
|
||||
root_path = String_FromReadonly("/sd/ClassiCube");
|
||||
}
|
||||
|
||||
root_path = String_FromReadonly("/sd/ClassiCube");
|
||||
fs_mkdir("/sd/ClassiCube");
|
||||
Platform_ReadonlyFilesystem = false;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user