| @@ -88,7 +88,7 @@ AC_CHECK_HEADERS(cxxabi.h) | |||||
| AC_LANG_POP(C++) | AC_LANG_POP(C++) | ||||
| dnl Common C functions | dnl Common C functions | ||||
| AC_CHECK_FUNCS(getenv getcwd _getcwd backtrace_symbols) | |||||
| AC_CHECK_FUNCS(getenv system tmpfile tmpnam getcwd _getcwd backtrace_symbols) | |||||
| if test "${enable_debug}" = "yes"; then | if test "${enable_debug}" = "yes"; then | ||||
| @@ -14,6 +14,7 @@ | |||||
| #if defined __CELLOS_LV2__ | #if defined __CELLOS_LV2__ | ||||
| #include <sys/paths.h> | |||||
| #include <cell/sysmodule.h> | #include <cell/sysmodule.h> | ||||
| #include <cell/codec/pngdec.h> | #include <cell/codec/pngdec.h> | ||||
| @@ -98,7 +99,7 @@ bool Ps3ImageData::Open(char const *path) | |||||
| Array<String> pathlist = System::GetPathList(path); | Array<String> pathlist = System::GetPathList(path); | ||||
| for (int i = 0; i < pathlist.Count(); ++i) | for (int i = 0; i < pathlist.Count(); ++i) | ||||
| { | { | ||||
| String name = String("/app_home/") + pathlist[i]; | |||||
| String name = String(SYS_APP_HOME) + '/' + pathlist[i]; | |||||
| dec_src.fileName = name.C(); | dec_src.fileName = name.C(); | ||||
| err = cellPngDecOpen(hmain, &hsub, &dec_src, &open_info); | err = cellPngDecOpen(hmain, &hsub, &dec_src, &open_info); | ||||
| if (err == CELL_OK) | if (err == CELL_OK) | ||||
| @@ -25,17 +25,19 @@ static inline void Abort() | |||||
| #endif | #endif | ||||
| } | } | ||||
| extern void DumpStack(); | |||||
| /* FIXME: see http://stackoverflow.com/q/3596781/111461 for discussions | /* FIXME: see http://stackoverflow.com/q/3596781/111461 for discussions | ||||
| * on implementing __debugbreak() on POSIX systems. */ | * on implementing __debugbreak() on POSIX systems. */ | ||||
| static inline void DebugBreak() | |||||
| static inline void DebugAbort() | |||||
| { | { | ||||
| DumpStack(); | |||||
| #if defined _WIN32 | #if defined _WIN32 | ||||
| __debugbreak(); | __debugbreak(); | ||||
| #endif | #endif | ||||
| Abort(); | |||||
| } | } | ||||
| extern void DumpStack(); | |||||
| #define LOL_CALL(macro, args) macro args | #define LOL_CALL(macro, args) macro args | ||||
| #define LOL_EVAL(a) a | #define LOL_EVAL(a) a | ||||
| #define LOL_1ST(a, ...) a | #define LOL_1ST(a, ...) a | ||||
| @@ -117,9 +119,7 @@ extern void DumpStack(); | |||||
| LOL_CALL(LOL_CAT(LOL_ERROR_, LOL_CALL(LOL_COUNT_TO_3, \ | LOL_CALL(LOL_CAT(LOL_ERROR_, LOL_CALL(LOL_COUNT_TO_3, \ | ||||
| (__VA_ARGS__))), \ | (__VA_ARGS__))), \ | ||||
| (__VA_ARGS__)); \ | (__VA_ARGS__)); \ | ||||
| DumpStack(); \ | |||||
| DebugBreak(); \ | |||||
| Abort(); \ | |||||
| DebugAbort(); \ | |||||
| } | } | ||||
| #endif | #endif | ||||
| @@ -43,9 +43,12 @@ public: | |||||
| ~File(); | ~File(); | ||||
| void Open(String const &file, FileAccess mode); | void Open(String const &file, FileAccess mode); | ||||
| String ReadString(); | |||||
| bool IsValid() const; | |||||
| void Close(); | void Close(); | ||||
| int Read(uint8_t *buf, int count); | |||||
| String ReadString(); | |||||
| private: | private: | ||||
| class FileData *m_data; | class FileData *m_data; | ||||
| }; | }; | ||||
| @@ -34,8 +34,10 @@ static const luaL_Reg loadedlibs[] = { | |||||
| {LUA_LOADLIBNAME, luaopen_package}, | {LUA_LOADLIBNAME, luaopen_package}, | ||||
| {LUA_COLIBNAME, luaopen_coroutine}, | {LUA_COLIBNAME, luaopen_coroutine}, | ||||
| {LUA_TABLIBNAME, luaopen_table}, | {LUA_TABLIBNAME, luaopen_table}, | ||||
| #if 0 // LOL BEGIN | |||||
| {LUA_IOLIBNAME, luaopen_io}, | {LUA_IOLIBNAME, luaopen_io}, | ||||
| {LUA_OSLIBNAME, luaopen_os}, | {LUA_OSLIBNAME, luaopen_os}, | ||||
| #endif // LOL END | |||||
| {LUA_STRLIBNAME, luaopen_string}, | {LUA_STRLIBNAME, luaopen_string}, | ||||
| {LUA_BITLIBNAME, luaopen_bit32}, | {LUA_BITLIBNAME, luaopen_bit32}, | ||||
| {LUA_MATHLIBNAME, luaopen_math}, | {LUA_MATHLIBNAME, luaopen_math}, | ||||
| @@ -12,8 +12,24 @@ | |||||
| # include "config.h" | # include "config.h" | ||||
| #endif | #endif | ||||
| #if __CELLOS_LV2__ | |||||
| # include <sys/paths.h> | |||||
| # include <cell/cell_fs.h> | |||||
| #endif | |||||
| #include "core.h" | #include "core.h" | ||||
| /* HACK: use fopen() for now so that we get FIOS. */ | |||||
| #if 0//__CELLOS_LV2__ | |||||
| extern "C" { | |||||
| # include <stdio.h> | |||||
| } | |||||
| # undef __CELLOS_LV2__ | |||||
| # define HAVE_STDIO_H 1 | |||||
| # undef BUFSIZ | |||||
| # define BUFSIZ 1024 | |||||
| #endif | |||||
| namespace lol | namespace lol | ||||
| { | { | ||||
| @@ -24,35 +40,69 @@ class FileData | |||||
| void Open(String const &file, FileAccess mode) | void Open(String const &file, FileAccess mode) | ||||
| { | { | ||||
| #if __CELLOS_LV2__ | #if __CELLOS_LV2__ | ||||
| String realfile = String(SYS_APP_HOME) + '/' + file; | |||||
| CellFsErrno err = cellFsOpen(realfile.C(), CELL_FS_O_RDONLY, | |||||
| &m_fd, NULL, 0); | |||||
| if (err != CELL_FS_SUCCEEDED) | |||||
| m_fd = -1; | |||||
| #elif HAVE_STDIO_H | #elif HAVE_STDIO_H | ||||
| /* FIXME: no modes, no error checking, no nothing */ | /* FIXME: no modes, no error checking, no nothing */ | ||||
| m_fd = fopen(file.C(), "r"); | m_fd = fopen(file.C(), "r"); | ||||
| #endif | #endif | ||||
| } | } | ||||
| String ReadString() | |||||
| inline bool IsValid() const | |||||
| { | { | ||||
| String ret; | |||||
| #if __CELLOS_LV2__ | #if __CELLOS_LV2__ | ||||
| return m_fd > -1; | |||||
| #elif HAVE_STDIO_H | |||||
| return !!m_fd; | |||||
| #endif | |||||
| } | |||||
| int Read(uint8_t *buf, int count) | |||||
| { | |||||
| #if __CELLOS_LV2__ | |||||
| uint64_t done; | |||||
| CellFsErrno err = cellFsRead(m_fd, buf, count, &done); | |||||
| if (err != CELL_FS_SUCCEEDED) | |||||
| return -1; | |||||
| return (int)done; | |||||
| #elif HAVE_STDIO_H | #elif HAVE_STDIO_H | ||||
| while (m_fd && !feof(m_fd)) | |||||
| size_t done = fread(buf, 1, count, m_fd); | |||||
| if (done <= 0) | |||||
| return -1; | |||||
| return (int)done; | |||||
| #endif | |||||
| } | |||||
| String ReadString() | |||||
| { | |||||
| String ret; | |||||
| while (IsValid()) | |||||
| { | { | ||||
| char buf[BUFSIZ]; | |||||
| size_t count = fread(buf, 1, BUFSIZ, m_fd); | |||||
| if (count <= 0) | |||||
| /* XXX: BUFSIZ would overflow the stack here */ | |||||
| uint8_t buf[1024]; | |||||
| int done = Read(buf, 1024); | |||||
| if (done <= 0) | |||||
| break; | break; | ||||
| int oldsize = ret.Count(); | int oldsize = ret.Count(); | ||||
| ret.Resize(oldsize + count); | |||||
| memcpy(&ret[oldsize], buf, count); | |||||
| ret.Resize(oldsize + done); | |||||
| memcpy(&ret[oldsize], buf, done); | |||||
| } | } | ||||
| #endif | |||||
| return ret; | return ret; | ||||
| } | } | ||||
| void Close() | void Close() | ||||
| { | { | ||||
| #if __CELLOS_LV2__ | #if __CELLOS_LV2__ | ||||
| if (m_fd >= 0) | |||||
| cellFsClose(m_fd); | |||||
| #elif HAVE_STDIO_H | #elif HAVE_STDIO_H | ||||
| if (m_fd) | if (m_fd) | ||||
| fclose(m_fd); | fclose(m_fd); | ||||
| @@ -61,6 +111,7 @@ class FileData | |||||
| } | } | ||||
| #if __CELLOS_LV2__ | #if __CELLOS_LV2__ | ||||
| int m_fd; | |||||
| #elif HAVE_STDIO_H | #elif HAVE_STDIO_H | ||||
| FILE *m_fd; | FILE *m_fd; | ||||
| #endif | #endif | ||||
| @@ -84,6 +135,7 @@ File &File::operator =(File const &that) | |||||
| if (this == &that) | if (this == &that) | ||||
| return *this; | return *this; | ||||
| /* FIXME: this needs auditing */ | |||||
| int refcount = --m_data->m_refcount; | int refcount = --m_data->m_refcount; | ||||
| if (refcount == 0) | if (refcount == 0) | ||||
| { | { | ||||
| @@ -112,6 +164,16 @@ void File::Open(String const &file, FileAccess mode) | |||||
| return m_data->Open(file, mode); | return m_data->Open(file, mode); | ||||
| } | } | ||||
| bool File::IsValid() const | |||||
| { | |||||
| return m_data->IsValid(); | |||||
| } | |||||
| int File::Read(uint8_t *buf, int count) | |||||
| { | |||||
| return m_data->Read(buf, count); | |||||
| } | |||||
| String File::ReadString() | String File::ReadString() | ||||
| { | { | ||||
| return m_data->ReadString(); | return m_data->ReadString(); | ||||
| @@ -31,6 +31,12 @@ class WorldData | |||||
| { | { | ||||
| friend class World; | friend class World; | ||||
| static int LuaPanic(lua_State* L) | |||||
| { | |||||
| DebugAbort(); | |||||
| return 0; | |||||
| } | |||||
| lua_State *m_lua_state; | lua_State *m_lua_state; | ||||
| }; | }; | ||||
| @@ -44,6 +50,7 @@ World g_world; | |||||
| World::World() | World::World() | ||||
| { | { | ||||
| g_world_data.m_lua_state = luaL_newstate(); | g_world_data.m_lua_state = luaL_newstate(); | ||||
| lua_atpanic(g_world_data.m_lua_state, WorldData::LuaPanic); | |||||
| luaL_openlibs(g_world_data.m_lua_state); | luaL_openlibs(g_world_data.m_lua_state); | ||||
| } | } | ||||
| @@ -55,18 +62,32 @@ World::~World() | |||||
| bool World::ExecLua(String const &lua) | bool World::ExecLua(String const &lua) | ||||
| { | { | ||||
| Array<String> pathlist = System::GetPathList(lua); | Array<String> pathlist = System::GetPathList(lua); | ||||
| File f; | |||||
| for (int i = 0; i < pathlist.Count(); ++i) | for (int i = 0; i < pathlist.Count(); ++i) | ||||
| { | { | ||||
| luaL_dofile(g_world_data.m_lua_state, pathlist[i].C()); | |||||
| f.Open(pathlist[i], FileAccess::Read); | |||||
| if (f.IsValid()) | |||||
| { | |||||
| String s = f.ReadString(); | |||||
| f.Close(); | |||||
| luaL_dostring(g_world_data.m_lua_state, s.C()); | |||||
| Log::Debug("loaded Lua file %s\n", pathlist[i].C()); | |||||
| return true; | |||||
| } | |||||
| } | } | ||||
| return true; | |||||
| Log::Error("could not find Lua file %s\n", lua.C()); | |||||
| return false; | |||||
| } | } | ||||
| double World::GetLuaNumber(String const &var) | double World::GetLuaNumber(String const &var) | ||||
| { | { | ||||
| double ret; | |||||
| lua_getglobal(g_world_data.m_lua_state, var.C()); | lua_getglobal(g_world_data.m_lua_state, var.C()); | ||||
| return lua_tonumber(g_world_data.m_lua_state, -1); | |||||
| ret = lua_tonumber(g_world_data.m_lua_state, -1); | |||||
| lua_pop(g_world_data.m_lua_state, 1); | |||||
| return ret; | |||||
| } | } | ||||
| } /* namespace lol */ | } /* namespace lol */ | ||||