diff --git a/source/main.cpp b/source/main.cpp index c331048..ec98594 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include #include @@ -20,13 +21,29 @@ int main(int argc, char* argv[]) { - Host *host = new Host(780, 780); + //default to full resolution + int windowWidth = 0; + int windowHeight = 0; + int opt; + + while ((opt = getopt(argc, argv, "w:h:")) != -1) { + switch (opt) { + case 'w': windowWidth = (int)strtol(optarg, NULL, 10); break; + case 'h': windowHeight = (int)strtol(optarg, NULL, 10); break; + } + } + + printf("windowWidth: %d\n", windowWidth); + printf("windowHeight: %d\n", windowHeight); + + Host *host = new Host(windowWidth, windowHeight); PicoRam *memory = new PicoRam(); Audio *audio = new Audio(memory); Logger_Initialize(host->logFilePrefix()); - + Logger_Write("initializing Vm\n"); Vm *vm = new Vm(host, memory, nullptr, nullptr, audio); + host->setUpPaletteColors(); host->oneTimeSetup(audio); @@ -36,14 +53,7 @@ int main(int argc, char* argv[]) host->unpackCarts(); #endif - Logger_Write("initializing Vm\n"); - - bool vmInitResult = vm->Initialize(); - - if (!vmInitResult) { - Logger_Write("vm init failed\n"); - return 1; - } + Logger_Write("initialized Vm and host\n"); @@ -63,8 +73,11 @@ int main(int argc, char* argv[]) } #else if (argc > 1) { - cart = argv[1]; - loadCart = true; + //ugly hack for backward compat - single argument. w/h need to be passed after + if (argv[1][0] != '-') { + cart = argv[1]; + loadCart = true; + } } #endif diff --git a/source/vm.cpp b/source/vm.cpp index 4c8176c..e26b045 100644 --- a/source/vm.cpp +++ b/source/vm.cpp @@ -37,6 +37,149 @@ using namespace z8; static const char DefaultCartName[] = "__FAKE08-DEFAULT.p8"; static const char SettingsCartName[] = "__FAKE08-SETTINGS.p8"; +bool _initializeLuaState(lua_State* luaState) { + // initialize Lua interpreter + + // load Lua base libraries (print / math / etc) + luaL_openlibs(luaState); + lua_pushglobaltable(luaState); + + //system + //must be registered before loading globals for pause menu to work + lua_register(luaState, "__listcarts", listcarts); + lua_register(luaState, "__getbioserror", getbioserror); + lua_register(luaState, "__loaddefaultcart", loaddefaultcart); + lua_register(luaState, "__loadsettingscart", loadsettingscart); + lua_register(luaState, "__togglepausemenu", togglepausemenu); + lua_register(luaState, "__resetcart", resetcart); + //lua_register(luaState, "load", load); + + //settings + lua_register(luaState, "__getsetting", getsetting); + lua_register(luaState, "__setsetting", setsetting); + + lua_register(luaState, "__installpackins", installpackins); + + //label + lua_register(luaState, "__loadlabel", loadlabel); + + lua_register(luaState, "__getlualine", getlualine); + + //register global functions first, they will get local aliases when + //the rest of the api is registered + //graphics + lua_register(luaState, "cls", cls); + lua_register(luaState, "pset", pset); + lua_register(luaState, "pget", pget); + lua_register(luaState, "color", color); + lua_register(luaState, "line", line); + lua_register(luaState, "tline", tline); + lua_register(luaState, "circ", circ); + lua_register(luaState, "circfill", circfill); + lua_register(luaState, "oval", oval); + lua_register(luaState, "ovalfill", ovalfill); + lua_register(luaState, "rect", rect); + lua_register(luaState, "rectfill", rectfill); + lua_register(luaState, "print", print); + lua_register(luaState, "cursor", cursor); + lua_register(luaState, "spr", spr); + lua_register(luaState, "sspr", sspr); + lua_register(luaState, "fget", fget); + lua_register(luaState, "fset", fset); + lua_register(luaState, "sget", sget); + lua_register(luaState, "sset", sset); + lua_register(luaState, "camera", camera); + lua_register(luaState, "clip", clip); + + lua_register(luaState, "pal", pal); + lua_register(luaState, "palt", palt); + + lua_register(luaState, "mget", mget); + lua_register(luaState, "mset", mset); + lua_register(luaState, "map", gfx_map); + lua_register(luaState, "mapdraw", gfx_map); + + //stubbed in graphics: + lua_register(luaState, "fillp", fillp); + + //input + lua_register(luaState, "btn", btn); + lua_register(luaState, "btnp", btnp); + + lua_register(luaState, "time", time); + lua_register(luaState, "t", time); + + //audio: + lua_register(luaState, "music", music); + lua_register(luaState, "sfx", sfx); + + //memory + lua_register(luaState, "cstore", cstore); + lua_register(luaState, "memcpy", api_memcpy); + lua_register(luaState, "memset", api_memset); + lua_register(luaState, "peek", peek); + lua_register(luaState, "poke", poke); + lua_register(luaState, "peek2", peek2); + lua_register(luaState, "poke2", poke2); + lua_register(luaState, "peek4", peek4); + lua_register(luaState, "poke4", poke4); + lua_register(luaState, "reload", reload); + lua_register(luaState, "reset", reset); + + //cart data + lua_register(luaState, "cartdata", cartdata); + lua_register(luaState, "dget", dget); + lua_register(luaState, "dset", dset); + + // + lua_register(luaState, "printh", printh); + lua_register(luaState, "stat", stat); + lua_register(luaState, "_update_buttons", _update_buttons); + lua_register(luaState, "run", run); + lua_register(luaState, "extcmd", extcmd); + lua_register(luaState, "_set_fps", setFps); + + //rng + lua_register(luaState, "rnd", rnd); + lua_register(luaState, "srand", srand); + + //load in global lua fuctions for pico 8- part of this is setting a local variable + //with the same name as all the globals we just registered + //auto convertedGlobalLuaFunctions = convert_emojis(p8GlobalLuaFunctions); + + auto convertedP8Bios = charset::utf8_to_pico8(p8Bios); + + int loadedBiosResult = luaL_dostring(luaState, convertedP8Bios.c_str()); + + if (loadedBiosResult != LUA_OK) { + Logger_Write("ERROR loading pico 8 bios\n"); + Logger_Write("Error: %s\n", lua_tostring(luaState, -1)); + lua_pop(luaState, 1); + + return false; + } + + // Push the eris.init_persist_all function on the top of the lua stack (or nil if it doesn't exist) + // we call this function to establish the default global state of things not to save in the save state + // needs to be called after globals are loaded but before the cart is run, or _init is called + //TODO: move these calls to the glue code? + lua_getglobal(luaState, "eris"); + lua_getfield(luaState, -1, "init_persist_all"); + + if (lua_pcall(luaState, 0, 0, 0)){ + Logger_Write("Error setting up lua persistence: %s\n", lua_tostring(luaState, -1)); + lua_pop(luaState, 1); + return false; + } + + //pop the eris.init_persist_all fuction off the stack now that we're done with it + lua_pop(luaState, 1); + + + return true; +} + + Vm::Vm( Host* host, PicoRam* memory, @@ -87,6 +230,27 @@ Vm::Vm( initPicoApi(_memory, _graphics, _input, this, _audio); //initGlobalApi(_graphics); + //reset memory (may have to be more selective about zeroing out to be accurate?) + _memory->Reset(); + + //seed rng + auto now = std::chrono::high_resolution_clock::now(); + api_srand(fix32::frombits((int32_t)now.time_since_epoch().count())); + + //set graphics state + _graphics->color(); + _graphics->clip(); + _graphics->pal(); + + //reset audio + _audio->resetAudioState(); + + _luaState = luaL_newstate(); + + lua_setpico8memory(_luaState, (uint8_t *)&_memory->data); + + _initializeLuaState(_luaState); + } Vm::~Vm(){ @@ -115,181 +279,6 @@ PicoRam* Vm::getPicoRam(){ jmp_buf place; bool abortLua; -bool Vm::Initialize() { - _picoFrameCount = 0; - - _cartdataKey = ""; - - //reset memory (may have to be more selective about zeroing out to be accurate?) - _memory->Reset(); - - //seed rng - auto now = std::chrono::high_resolution_clock::now(); - api_srand(fix32::frombits((int32_t)now.time_since_epoch().count())); - - //set graphics state - _graphics->color(); - _graphics->clip(); - _graphics->pal(); - - //reset audio - _audio->resetAudioState(); - - _cartChangeQueued = false; - abortLua = false; - - // initialize Lua interpreter - _luaState = luaL_newstate(); - - lua_setpico8memory(_luaState, (uint8_t *)&_memory->data); - // load Lua base libraries (print / math / etc) - luaL_openlibs(_luaState); - lua_pushglobaltable(_luaState); - - //system - //must be registered before loading globals for pause menu to work - lua_register(_luaState, "__listcarts", listcarts); - lua_register(_luaState, "__getbioserror", getbioserror); - lua_register(_luaState, "__loaddefaultcart", loaddefaultcart); - lua_register(_luaState, "__loadsettingscart", loadsettingscart); - lua_register(_luaState, "__togglepausemenu", togglepausemenu); - lua_register(_luaState, "__resetcart", resetcart); - //lua_register(_luaState, "load", load); - - //settings - lua_register(_luaState, "__getsetting", getsetting); - lua_register(_luaState, "__setsetting", setsetting); - - lua_register(_luaState, "__installpackins", installpackins); - - //label - lua_register(_luaState, "__loadlabel", loadlabel); - - lua_register(_luaState, "__getlualine", getlualine); - - //register global functions first, they will get local aliases when - //the rest of the api is registered - //graphics - lua_register(_luaState, "cls", cls); - lua_register(_luaState, "pset", pset); - lua_register(_luaState, "pget", pget); - lua_register(_luaState, "color", color); - lua_register(_luaState, "line", line); - lua_register(_luaState, "tline", tline); - lua_register(_luaState, "circ", circ); - lua_register(_luaState, "circfill", circfill); - lua_register(_luaState, "oval", oval); - lua_register(_luaState, "ovalfill", ovalfill); - lua_register(_luaState, "rect", rect); - lua_register(_luaState, "rectfill", rectfill); - lua_register(_luaState, "print", print); - lua_register(_luaState, "cursor", cursor); - lua_register(_luaState, "spr", spr); - lua_register(_luaState, "sspr", sspr); - lua_register(_luaState, "fget", fget); - lua_register(_luaState, "fset", fset); - lua_register(_luaState, "sget", sget); - lua_register(_luaState, "sset", sset); - lua_register(_luaState, "camera", camera); - lua_register(_luaState, "clip", clip); - - lua_register(_luaState, "pal", pal); - lua_register(_luaState, "palt", palt); - - lua_register(_luaState, "mget", mget); - lua_register(_luaState, "mset", mset); - lua_register(_luaState, "map", gfx_map); - lua_register(_luaState, "mapdraw", gfx_map); - - //stubbed in graphics: - lua_register(_luaState, "fillp", fillp); - - //input - lua_register(_luaState, "btn", btn); - lua_register(_luaState, "btnp", btnp); - - lua_register(_luaState, "time", time); - lua_register(_luaState, "t", time); - - //audio: - lua_register(_luaState, "music", music); - lua_register(_luaState, "sfx", sfx); - - //memory - lua_register(_luaState, "cstore", cstore); - lua_register(_luaState, "memcpy", api_memcpy); - lua_register(_luaState, "memset", api_memset); - lua_register(_luaState, "peek", peek); - lua_register(_luaState, "poke", poke); - lua_register(_luaState, "peek2", peek2); - lua_register(_luaState, "poke2", poke2); - lua_register(_luaState, "peek4", peek4); - lua_register(_luaState, "poke4", poke4); - lua_register(_luaState, "reload", reload); - lua_register(_luaState, "reset", reset); - - //cart data - lua_register(_luaState, "cartdata", cartdata); - lua_register(_luaState, "dget", dget); - lua_register(_luaState, "dset", dset); - - // - lua_register(_luaState, "printh", printh); - lua_register(_luaState, "stat", stat); - lua_register(_luaState, "_update_buttons", _update_buttons); - lua_register(_luaState, "run", run); - lua_register(_luaState, "extcmd", extcmd); - lua_register(_luaState, "_set_fps", setFps); - - //rng - lua_register(_luaState, "rnd", rnd); - lua_register(_luaState, "srand", srand); - - //load in global lua fuctions for pico 8- part of this is setting a local variable - //with the same name as all the globals we just registered - //auto convertedGlobalLuaFunctions = convert_emojis(p8GlobalLuaFunctions); - - auto convertedP8Bios = charset::utf8_to_pico8(p8Bios); - - int loadedBiosResult = luaL_dostring(_luaState, convertedP8Bios.c_str()); - - if (loadedBiosResult != LUA_OK) { - _cartLoadError = "ERROR loading pico 8 bios"; - Logger_Write("ERROR loading pico 8 bios\n"); - Logger_Write("Error: %s\n", lua_tostring(_luaState, -1)); - lua_pop(_luaState, 1); - - return false; - } - - // Push the eris.init_persist_all function on the top of the lua stack (or nil if it doesn't exist) - // we call this function to establish the default global state of things not to save in the save state - // needs to be called after globals are loaded but before the cart is run, or _init is called - //TODO: move these calls to the glue code? - lua_getglobal(_luaState, "eris"); - lua_getfield(_luaState, -1, "init_persist_all"); - - if (lua_pcall(_luaState, 0, 0, 0)){ - Logger_Write("Error setting up lua persistence: %s\n", lua_tostring(_luaState, -1)); - lua_pop(_luaState, 1); - return false; - } - - //pop the eris.init_persist_all fuction off the stack now that we're done with it - lua_pop(_luaState, 1); - - - - if (abortLua) { - //trigger closing of cart and reload of bios - return false; - } - - _cartLoadError = ""; - - return true; - -} bool Vm::loadCart(Cart* cart) { _picoFrameCount = 0; diff --git a/source/vm.h b/source/vm.h index 1be5236..a940c9d 100644 --- a/source/vm.h +++ b/source/vm.h @@ -67,8 +67,6 @@ class Vm { Audio* audio = nullptr); ~Vm(); - bool Initialize(); - void LoadBiosCart(); void LoadSettingsCart();