diff --git a/file.c b/file.c
index 26d7b70..901c6f9 100644
--- a/file.c
+++ b/file.c
@@ -14,9 +14,11 @@
* along with this program; if not, see .
*/
+#include
#include
#include
#include
+#include
#include "system4.h"
void *file_read(const char *path, size_t *len_out)
@@ -48,3 +50,8 @@ void *file_read(const char *path, size_t *len_out)
buf[len] = 0;
return buf;
}
+
+bool file_exists(const char *path)
+{
+ return access(path, F_OK) != -1;
+}
diff --git a/file.h b/file.h
index d6a01f8..6898c93 100644
--- a/file.h
+++ b/file.h
@@ -18,7 +18,9 @@
#define SYSTEM4_FILE_H
#include
+#include
void *file_read(const char *path, size_t *len_out);
+bool file_exists(const char *path);
#endif /* SYSTEM4_FILE_H */
diff --git a/hll/File.c b/hll/File.c
new file mode 100644
index 0000000..71b908e
--- /dev/null
+++ b/hll/File.c
@@ -0,0 +1,99 @@
+/* Copyright (C) 2019 Nunuhara Cabbage
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see .
+ */
+
+#include
+#include
+#include
+#include
+#include "hll.h"
+#include "../system4.h"
+
+//int Open(string szName, int nType)
+hll_unimplemented(File, Open);
+//int Close()
+hll_unimplemented(File, Close);
+//int Read(ref struct pIVMStruct)
+hll_unimplemented(File, Read);
+//int Write(struct pIVMStruct)
+hll_unimplemented(File, Write);
+//int Copy(string szSrcName, string szDstName)
+hll_unimplemented(File, Copy);
+//int Delete(string szName)
+hll_unimplemented(File, Delete);
+
+/*
+
+ struct tagSaveDate {
+ int m_nYear;
+ int m_nMonth;
+ int m_nDay;
+ int m_nHour;
+ int m_nMinute;
+ int m_nSecond;
+ int m_nDayOfWeek;
+ };
+
+ */
+
+//int GetTime(string szName, ref struct pIVMStruct)
+hll_defun(GetTime, args)
+{
+ struct stat s;
+ char *path = unix_path(hll_string_ref(args[0].i)->text);
+ union vm_value *date = hll_struct_ref(args[1].i);
+
+ if (stat(path, &s) < 0) {
+ WARNING("stat failed: %s", strerror(errno));
+ hll_return(0);
+ }
+
+ struct tm *tm = localtime(&s.st_mtime);
+ if (!tm) {
+ WARNING("localtime failed: %s", strerror(errno));
+ hll_return(0);
+ }
+
+ date[0].i = tm->tm_year;
+ date[1].i = tm->tm_mon;
+ date[2].i = tm->tm_mday;
+ date[3].i = tm->tm_hour;
+ date[4].i = tm->tm_min;
+ date[5].i = tm->tm_sec;
+ date[6].i = tm->tm_wday;
+
+ hll_return(1);
+}
+
+//int SetFind(string szName)
+hll_unimplemented(File, SetFind);
+//int GetFind(ref string szName)
+hll_unimplemented(File, GetFind);
+//int MakeDirectory(string szName)
+hll_unimplemented(File, MakeDirectory);
+
+hll_deflib(File) {
+ hll_export(Open),
+ hll_export(Close),
+ hll_export(Read),
+ hll_export(Write),
+ hll_export(Copy),
+ hll_export(Delete),
+ hll_export(GetTime),
+ hll_export(SetFind),
+ hll_export(GetFind),
+ hll_export(MakeDirectory),
+ NULL
+};
diff --git a/meson.build b/meson.build
index ea80dd1..41b37f0 100644
--- a/meson.build
+++ b/meson.build
@@ -31,6 +31,7 @@ xsystem4 = ['ald.c',
'hll/Confirm2.c',
'hll/DrawGraph.c',
'hll/DrawPluginManager.c',
+ 'hll/File.c',
'hll/Math.c',
'hll/MsgLogManager.c',
'hll/MsgSkip.c',
diff --git a/system.c b/system.c
index f4ed7ff..70bfcbc 100644
--- a/system.c
+++ b/system.c
@@ -100,14 +100,19 @@ noreturn void sys_exit(int code)
exit(code);
}
-char *gamedir_path(const char *path)
+char *unix_path(const char *path)
{
char *utf = sjis2utf(path, strlen(path));
for (int i = 0; utf[i]; i++) {
if (utf[i] == '\\')
utf[i] = '/';
}
+ return utf;
+}
+char *gamedir_path(const char *path)
+{
+ char *utf = unix_path(path);
char *gamepath = xmalloc(strlen(config.game_dir) + strlen(utf) + 2);
strcpy(gamepath, config.game_dir);
strcat(gamepath, "/");
diff --git a/system4.h b/system4.h
index 3605b74..9491330 100644
--- a/system4.h
+++ b/system4.h
@@ -81,6 +81,7 @@ struct config {
struct config config;
+char *unix_path(const char *path);
char *gamedir_path(const char *path);
#endif /* SYSTEM4_H */
diff --git a/vm.c b/vm.c
index 913a301..36f2150 100644
--- a/vm.c
+++ b/vm.c
@@ -24,6 +24,7 @@
#include "vm_string.h"
#include "page.h"
#include "ain.h"
+#include "file.h"
#include "instructions.h"
#include "little_endian.h"
#include "savedata.h"
@@ -496,8 +497,10 @@ static void system_call(int32_t code)
break;
case 0xA: { // system.ExistsFile(string szFileName)
int str = stack_pop().i;
+ char *path = unix_path(heap[str].s->text);
+ stack_push(file_exists(path));
heap_unref(str);
- stack_push(1); // TODO
+ free(path);
break;
}
case 0xC: // system.GetSaveFolderName(void)
@@ -516,6 +519,23 @@ static void system_call(int32_t code)
free(utf);
// XXX: caller S_POPs
break;
+ case 0x10: {
+ int slot = stack_pop().i;
+ struct string *name = heap[slot].s;
+ size_t dir_len = strlen(config.save_dir);
+ char *path = xmalloc(dir_len + 1 + name->size + 1);
+
+ strncpy(path, config.save_dir, dir_len);
+ path[dir_len] = '/';
+ strncpy(path+dir_len+1, name->text, name->size);
+ path[dir_len+1+name->size] = '\0';
+
+ stack_push(file_exists(path));
+ heap_unref(slot);
+ NOTICE("-----PATH=%s", path);
+ free(path);
+ break;
+ }
case 0x11: // system.IsDebugMode(void)
stack_push(0);
break;
@@ -1570,6 +1590,7 @@ extern struct library lib_AliceLogo3;
extern struct library lib_Confirm2;
extern struct library lib_DrawGraph;
extern struct library lib_DrawPluginManager;
+extern struct library lib_File;
extern struct library lib_Math;
extern struct library lib_MsgLogManager;
extern struct library lib_MsgSkip;
@@ -1586,6 +1607,7 @@ struct library *libraries[] = {
&lib_Confirm2,
&lib_DrawGraph,
&lib_DrawPluginManager,
+ &lib_File,
&lib_Math,
&lib_MsgLogManager,
&lib_MsgSkip,