mirror of
https://github.com/birth1mark/orbis8.git
synced 2026-10-29 02:00:29 +01:00
- Added integrated 🌐 BBS Store tab to arcade BIOS interface (DefaultCart.h)
- Implemented C++ Lua API bindings: __bbs_listfeatured, __bbs_download, __bbs_isdownloaded, __refreshcarts
- Curated top-rated community games catalog with 1-click download & play
- Added custom BBS Cartridge ID downloader with on-screen character picker
- Added robust magic-byte verification (PNG/p8) on downloaded cartridges
- Updated README.md and ARCHITECTURE.md documentation
1610 lines
35 KiB
C++
1610 lines
35 KiB
C++
|
|
#include <string>
|
|
#include <vector>
|
|
#include <tuple>
|
|
#include <cstdio>
|
|
using namespace std;
|
|
|
|
#include "picoluaapi.h"
|
|
#include "graphics.h"
|
|
#include "Input.h"
|
|
#include "vm.h"
|
|
#include "logger.h"
|
|
#include "printHelper.h"
|
|
#include "emojiconversion.h"
|
|
|
|
//extern "C" {
|
|
#include <lua.h>
|
|
#include <lualib.h>
|
|
#include <lauxlib.h>
|
|
//}
|
|
|
|
Graphics* _graphicsForLuaApi;
|
|
Input* _inputForLuaApi;
|
|
Vm* _vmForLuaApi;
|
|
Audio* _audioForLuaApi;
|
|
PicoRam* _ramForLuaApi;
|
|
|
|
void initPicoApi(PicoRam* memory, Graphics* graphics, Input* input, Vm* vm, Audio* audio){
|
|
_graphicsForLuaApi = graphics;
|
|
_inputForLuaApi = input;
|
|
_vmForLuaApi = vm;
|
|
_audioForLuaApi = audio;
|
|
_ramForLuaApi = memory;
|
|
|
|
initPrintHelper(_ramForLuaApi, _graphicsForLuaApi, _vmForLuaApi, _audioForLuaApi);
|
|
}
|
|
|
|
int noop(const char * name) {
|
|
//todo log name of unimplemented functions?
|
|
return 0;
|
|
}
|
|
|
|
int noopreturns(lua_State *L, const char * name) {
|
|
//todo log name of unimplemented functions?
|
|
lua_pushnumber(L, 0);
|
|
|
|
return 1;
|
|
}
|
|
|
|
/*functions to expose to lua*/
|
|
//Graphics
|
|
int cls(lua_State *L){
|
|
if (lua_gettop(L) == 0) {
|
|
_graphicsForLuaApi->cls();
|
|
}
|
|
else {
|
|
int c = lua_tonumber(L,1);
|
|
_graphicsForLuaApi->cls(c);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int pset(lua_State *L){
|
|
int x = lua_tonumber(L,1);
|
|
int y = lua_tonumber(L,2);
|
|
|
|
if (lua_gettop(L) <= 2) {
|
|
_graphicsForLuaApi->pset(x, y);
|
|
return 0;
|
|
}
|
|
|
|
int c = lua_tonumber(L,3);
|
|
|
|
_graphicsForLuaApi->pset(x, y, (uint8_t)c);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int pget(lua_State *L){
|
|
fix32 x = lua_tonumber(L,1);
|
|
fix32 y = lua_tonumber(L,2);
|
|
|
|
uint8_t color = _graphicsForLuaApi->pget((int)x, (int)y);
|
|
|
|
lua_pushinteger(L, color);
|
|
|
|
return 1;
|
|
}
|
|
|
|
int color(lua_State *L){
|
|
uint8_t prev = 0;
|
|
int16_t c = 0;
|
|
if (lua_gettop(L) > 0) {
|
|
c = lua_tonumber(L,1);
|
|
prev = _graphicsForLuaApi->color(c);
|
|
}
|
|
else {
|
|
prev = _graphicsForLuaApi->color();
|
|
}
|
|
|
|
lua_pushinteger(L, prev);
|
|
|
|
return 1;
|
|
}
|
|
|
|
int line (lua_State *L){
|
|
if (lua_gettop(L) == 0) {
|
|
_graphicsForLuaApi->line();
|
|
}
|
|
else if (lua_gettop(L) == 1) {
|
|
fix32 c = lua_tonumber(L,1);
|
|
|
|
_graphicsForLuaApi->line(c);
|
|
}
|
|
else if (lua_gettop(L) == 2) {
|
|
int x1 = lua_tonumber(L,1);
|
|
int y1 = lua_tonumber(L,2);
|
|
|
|
_graphicsForLuaApi->line(x1, y1);
|
|
}
|
|
else if (lua_gettop(L) == 3) {
|
|
int x1 = lua_tonumber(L,1);
|
|
int y1 = lua_tonumber(L,2);
|
|
int16_t c = lua_tonumber(L,3);
|
|
|
|
_graphicsForLuaApi->line(x1, y1, c);
|
|
}
|
|
else if (lua_gettop(L) == 4) {
|
|
int x1 = lua_tonumber(L,1);
|
|
int y1 = lua_tonumber(L,2);
|
|
int x2 = lua_tonumber(L,3);
|
|
int y2 = lua_tonumber(L,4);
|
|
|
|
_graphicsForLuaApi->line(x1, y1, x2, y2);
|
|
}
|
|
else {
|
|
int x1 = lua_tonumber(L,1);
|
|
int y1 = lua_tonumber(L,2);
|
|
int x2 = lua_tonumber(L,3);
|
|
int y2 = lua_tonumber(L,4);
|
|
int16_t c = lua_tonumber(L,5);
|
|
|
|
_graphicsForLuaApi->line(x1, y1, x2, y2, c);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int tline (lua_State *L){
|
|
int x0 = 0, y0 = 0, x1 = 0, y1 = 0;
|
|
fix32 mx = 0, my = 0, mdx = fix32::frombits(0x2000), mdy = 0;
|
|
|
|
if (lua_gettop(L) >= 6) {
|
|
x0 = lua_tonumber(L,1);
|
|
y0 = lua_tonumber(L,2);
|
|
x1 = lua_tonumber(L,3);
|
|
y1 = lua_tonumber(L,4);
|
|
mx = lua_tonumber(L,5);
|
|
my = lua_tonumber(L,6);
|
|
}
|
|
if (lua_gettop(L) > 7){
|
|
mdx = lua_tonumber(L,7);
|
|
mdy = lua_tonumber(L,8);
|
|
}
|
|
|
|
_graphicsForLuaApi->tline(x0, y0, x1, y1, mx, my, mdx, mdy);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int circ(lua_State *L){
|
|
int ox = lua_tonumber(L,1);
|
|
int oy = lua_tonumber(L,2);
|
|
|
|
if (lua_gettop(L) == 2) {
|
|
_graphicsForLuaApi->circ(ox, oy);
|
|
}
|
|
else if (lua_gettop(L) == 3){
|
|
int r = lua_tonumber(L,3);
|
|
_graphicsForLuaApi->circ(ox, oy, r);
|
|
}
|
|
else if (lua_gettop(L) > 3){
|
|
int r = lua_tonumber(L,3);
|
|
int16_t c = lua_tonumber(L,4);
|
|
|
|
_graphicsForLuaApi->circ(ox, oy, r, c);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int circfill(lua_State *L){
|
|
int ox = lua_tonumber(L,1);
|
|
int oy = lua_tonumber(L,2);
|
|
|
|
if (lua_gettop(L) == 2) {
|
|
_graphicsForLuaApi->circfill(ox, oy);
|
|
}
|
|
else if (lua_gettop(L) == 3){
|
|
int r = lua_tonumber(L,3);
|
|
_graphicsForLuaApi->circfill(ox, oy, r);
|
|
}
|
|
else if (lua_gettop(L) > 3){
|
|
int r = lua_tonumber(L,3);
|
|
int16_t c = lua_tonumber(L,4);
|
|
|
|
_graphicsForLuaApi->circfill(ox, oy, r, c);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int oval(lua_State *L){
|
|
|
|
if (lua_gettop(L) >= 4) {
|
|
int x1 = lua_tonumber(L,1);
|
|
int y1 = lua_tonumber(L,2);
|
|
int x2 = lua_tonumber(L,3);
|
|
int y2 = lua_tonumber(L,4);
|
|
|
|
if (lua_gettop(L) == 4){
|
|
_graphicsForLuaApi->oval(x1, y1, x2, y2);
|
|
|
|
}
|
|
else {
|
|
int16_t c = lua_tonumber(L,5);
|
|
|
|
_graphicsForLuaApi->oval(x1, y1, x2, y2, c);
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int ovalfill(lua_State *L){
|
|
if (lua_gettop(L) >= 4) {
|
|
int x1 = lua_tonumber(L,1);
|
|
int y1 = lua_tonumber(L,2);
|
|
int x2 = lua_tonumber(L,3);
|
|
int y2 = lua_tonumber(L,4);
|
|
|
|
if (lua_gettop(L) == 4){
|
|
_graphicsForLuaApi->ovalfill(x1, y1, x2, y2);
|
|
|
|
}
|
|
else {
|
|
int16_t c = lua_tonumber(L,5);
|
|
|
|
_graphicsForLuaApi->ovalfill(x1, y1, x2, y2, c);
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int rect(lua_State *L){
|
|
|
|
if (lua_gettop(L) >= 4) {
|
|
int x1 = lua_tonumber(L,1);
|
|
int y1 = lua_tonumber(L,2);
|
|
int x2 = lua_tonumber(L,3);
|
|
int y2 = lua_tonumber(L,4);
|
|
|
|
if (lua_gettop(L) == 4){
|
|
_graphicsForLuaApi->rect(x1, y1, x2, y2);
|
|
|
|
}
|
|
else {
|
|
int16_t c = lua_tonumber(L,5);
|
|
|
|
_graphicsForLuaApi->rect(x1, y1, x2, y2, c);
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int rectfill(lua_State *L){
|
|
if (lua_gettop(L) >= 4) {
|
|
int x1 = lua_tonumber(L,1);
|
|
int y1 = lua_tonumber(L,2);
|
|
int x2 = lua_tonumber(L,3);
|
|
int y2 = lua_tonumber(L,4);
|
|
|
|
if (lua_gettop(L) == 4){
|
|
_graphicsForLuaApi->rectfill(x1, y1, x2, y2);
|
|
|
|
}
|
|
else {
|
|
int16_t c = lua_tonumber(L,5);
|
|
|
|
_graphicsForLuaApi->rectfill(x1, y1, x2, y2, c);
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int rrect(lua_State *L){
|
|
|
|
if (lua_gettop(L) >= 5) {
|
|
int x = lua_tonumber(L,1);
|
|
int y = lua_tonumber(L,2);
|
|
int w = lua_tonumber(L,3);
|
|
int h = lua_tonumber(L,4);
|
|
int r = lua_tonumber(L,5);
|
|
|
|
if (lua_gettop(L) == 5){
|
|
_graphicsForLuaApi->rrect(x, y, w, h, r);
|
|
}
|
|
else {
|
|
int16_t c = lua_tonumber(L,6);
|
|
|
|
_graphicsForLuaApi->rrect(x, y, w, h, r, c);
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int rrectfill(lua_State *L){
|
|
if (lua_gettop(L) >= 5) {
|
|
int x = lua_tonumber(L,1);
|
|
int y = lua_tonumber(L,2);
|
|
int w = lua_tonumber(L,3);
|
|
int h = lua_tonumber(L,4);
|
|
int r = lua_tonumber(L,5);
|
|
|
|
if (lua_gettop(L) == 5){
|
|
_graphicsForLuaApi->rrectfill(x, y, w, h, r);
|
|
}
|
|
else {
|
|
int16_t c = lua_tonumber(L,6);
|
|
|
|
_graphicsForLuaApi->rrectfill(x, y, w, h, r, c);
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int print(lua_State *L){
|
|
int numArgs = lua_gettop(L);
|
|
if (numArgs == 0){
|
|
return 0;
|
|
}
|
|
|
|
const char * charArray = "";
|
|
size_t len = 0;
|
|
int newx = 0;
|
|
|
|
//todo: handle other cases, maybe move this somewhere else
|
|
//learned this from zepto8 https://github.com/samhocevar/zepto8/blob/27f83fe0626d4823fe2a33568d8310d8def84ae9/src/pico8/vm.cpp
|
|
if (lua_isnil(L, 1)){
|
|
charArray = "[nil]";
|
|
len = 5;
|
|
}
|
|
else if (lua_isstring(L, 1)){
|
|
charArray = lua_tolstring(L, 1, &len);
|
|
}
|
|
else if (lua_isnumber(L, 1)){
|
|
charArray = lua_tolstring(L, 1, &len);
|
|
}
|
|
else if (lua_isboolean(L, 1)){
|
|
int boolVal = lua_toboolean(L, 1);
|
|
charArray = boolVal ? "true" : "false";
|
|
len = boolVal ? 4 : 5;
|
|
}
|
|
else if (lua_isfunction(L, 1)){
|
|
charArray = "[function]";
|
|
len = 10;
|
|
}
|
|
|
|
std::string str = std::string(charArray, len);
|
|
|
|
if (numArgs < 2) {
|
|
newx = print(str);
|
|
}
|
|
else if (numArgs == 2) {
|
|
int16_t c = lua_tonumber(L,2);
|
|
|
|
_graphicsForLuaApi->color(c);
|
|
newx = print(str);
|
|
}
|
|
else if (numArgs == 3) {
|
|
int x = lua_tonumber(L,2);
|
|
int y = lua_tonumber(L,3);
|
|
|
|
newx = print(str, x, y);
|
|
}
|
|
else {
|
|
int x = lua_tonumber(L,2);
|
|
int y = lua_tonumber(L,3);
|
|
|
|
int16_t c = lua_tonumber(L,4);
|
|
|
|
newx = print(str, x, y, c);
|
|
}
|
|
|
|
lua_pushinteger(L, newx);
|
|
return 1;
|
|
}
|
|
|
|
int spr(lua_State *L) {
|
|
if (lua_gettop(L) < 3) {
|
|
return 0;
|
|
}
|
|
|
|
int n = lua_tonumber(L,1);
|
|
int x = lua_tonumber(L,2);
|
|
int y = lua_tonumber(L,3);
|
|
fix32 w = 1.0;
|
|
fix32 h = 1.0;
|
|
bool flip_x = false;
|
|
bool flip_y = false;
|
|
|
|
|
|
if (lua_gettop(L) > 3){
|
|
w = lua_tonumber(L,4);
|
|
}
|
|
if (lua_gettop(L) > 4) {
|
|
h = lua_tonumber(L,5);
|
|
}
|
|
if (lua_gettop(L) > 5) {
|
|
flip_x = lua_toboolean(L,6);
|
|
}
|
|
if (lua_gettop(L) > 6) {
|
|
flip_y = lua_toboolean(L,7);
|
|
}
|
|
|
|
_graphicsForLuaApi->spr(n, x, y, w, h, flip_x, flip_y);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int sspr(lua_State *L) {
|
|
if (lua_gettop(L) < 6) {
|
|
return 0;
|
|
}
|
|
|
|
int sx = lua_tonumber(L,1);
|
|
int sy = lua_tonumber(L,2);
|
|
int sw = lua_tonumber(L,3);
|
|
int sh = lua_tonumber(L,4);
|
|
int dx = lua_tonumber(L,5);
|
|
int dy = lua_tonumber(L,6);
|
|
|
|
int dw = sw;
|
|
int dh = sh;
|
|
bool flip_x = false;
|
|
bool flip_y = false;
|
|
|
|
if (lua_gettop(L) > 6){
|
|
dw = lua_tonumber(L,7);
|
|
}
|
|
if (lua_gettop(L) > 7){
|
|
dh = lua_tonumber(L,8);
|
|
}
|
|
if (lua_gettop(L) > 8){
|
|
flip_x = lua_toboolean(L,9);
|
|
}
|
|
if (lua_gettop(L) > 9){
|
|
flip_y = lua_toboolean(L,10);
|
|
}
|
|
|
|
_graphicsForLuaApi->sspr(
|
|
sx,
|
|
sy,
|
|
sw,
|
|
sh,
|
|
dx,
|
|
dy,
|
|
dw,
|
|
dh,
|
|
flip_x,
|
|
flip_y);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int fget(lua_State *L) {
|
|
fix32 n = lua_tonumber(L,1);
|
|
|
|
if (lua_gettop(L) == 1) {
|
|
uint8_t result = _graphicsForLuaApi->fget((uint8_t)n);
|
|
lua_pushinteger(L, result);
|
|
}
|
|
else {
|
|
fix32 f = lua_tonumber(L,2);
|
|
bool result = _graphicsForLuaApi->fget((uint8_t)n, (uint8_t)f);
|
|
lua_pushboolean(L, result);
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
int fset(lua_State *L) {
|
|
fix32 n = lua_tonumber(L,1);
|
|
|
|
if (lua_gettop(L) > 2) {
|
|
fix32 f = lua_tonumber(L,2);
|
|
bool v = lua_toboolean(L,3);
|
|
_graphicsForLuaApi->fset((uint8_t)n, (uint8_t)f, v);
|
|
}
|
|
else {
|
|
fix32 v = lua_tonumber(L,2);
|
|
_graphicsForLuaApi->fset((uint8_t)n, (uint8_t)v);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int sget(lua_State *L) {
|
|
int x = lua_tonumber(L,1);
|
|
int y = lua_tonumber(L,2);
|
|
uint8_t result = _graphicsForLuaApi->sget((uint8_t)x, (uint8_t)y);
|
|
lua_pushinteger(L, result);
|
|
|
|
return 1;
|
|
}
|
|
|
|
int sset(lua_State *L) {
|
|
int x = lua_tonumber(L,1);
|
|
int y = lua_tonumber(L,2);
|
|
int16_t c = lua_tonumber(L,3);
|
|
_graphicsForLuaApi->sset(x, y, c);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int camera(lua_State *L) {
|
|
int16_t x = 0;
|
|
int16_t y = 0;
|
|
if (lua_gettop(L) > 0) {
|
|
x = lua_tointeger(L,1);
|
|
}
|
|
if (lua_gettop(L) > 1) {
|
|
y = lua_tointeger(L,2);
|
|
}
|
|
|
|
auto prev = _graphicsForLuaApi->camera(x, y);
|
|
|
|
lua_pushnumber(L, get<0>(prev));
|
|
lua_pushnumber(L, get<1>(prev));
|
|
|
|
return 2;
|
|
}
|
|
|
|
int clip(lua_State *L) {
|
|
|
|
std::tuple<uint8_t, uint8_t, uint8_t, uint8_t> prev;
|
|
|
|
if (lua_gettop(L) >= 4) {
|
|
int x = lua_tonumber(L,1);
|
|
int y = lua_tonumber(L,2);
|
|
int w = lua_tonumber(L,3);
|
|
int h = lua_tonumber(L,4);
|
|
|
|
prev = _graphicsForLuaApi->clip(x, y, w, h);
|
|
}
|
|
else {
|
|
prev = _graphicsForLuaApi->clip();
|
|
}
|
|
|
|
lua_pushnumber(L, get<0>(prev));
|
|
lua_pushnumber(L, get<1>(prev));
|
|
lua_pushnumber(L, get<2>(prev));
|
|
lua_pushnumber(L, get<3>(prev));
|
|
|
|
return 4;
|
|
}
|
|
|
|
int mget(lua_State *L) {
|
|
int celx = lua_tonumber(L,1);
|
|
int cely = lua_tonumber(L,2);
|
|
|
|
uint8_t result = _graphicsForLuaApi->mget(celx, cely);
|
|
lua_pushnumber(L, result);
|
|
|
|
return 1;
|
|
}
|
|
|
|
int mset(lua_State *L) {
|
|
int celx = lua_tonumber(L,1);
|
|
int cely = lua_tonumber(L,2);
|
|
int16_t snum = lua_tonumber(L, 3);
|
|
|
|
_graphicsForLuaApi->mset(celx, cely, snum);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int gfx_map(lua_State *L) {
|
|
const bool bigMap = _ramForLuaApi->hwState.mapMemMapping >= 0x80;
|
|
const int bigMapLocation = _ramForLuaApi->hwState.mapMemMapping << 8;
|
|
const int mapSize = bigMap
|
|
? 0x10000 - bigMapLocation
|
|
: 8192;
|
|
|
|
const int mapW = _ramForLuaApi->hwState.widthOfTheMap == 0 ? 256 : _ramForLuaApi->hwState.widthOfTheMap;
|
|
const int mapH = mapSize / mapW;
|
|
|
|
int celx = 0, cely = 0, sx = 0, sy = 0, celw = mapW, celh = mapH, argc;
|
|
argc = lua_gettop(L);
|
|
if (argc > 0) {
|
|
celx = lua_tonumber(L,1);
|
|
}
|
|
if (argc > 1) {
|
|
cely = lua_tonumber(L,2);
|
|
}
|
|
if (argc > 2) {
|
|
sx = lua_tonumber(L,3);
|
|
}
|
|
if (argc > 3) {
|
|
sy = lua_tonumber(L,4);
|
|
}
|
|
if (argc > 4) {
|
|
celw = lua_tonumber(L,5);
|
|
}
|
|
if (argc > 5) {
|
|
celh = lua_tonumber(L,6);
|
|
}
|
|
int16_t layer = 0;
|
|
|
|
if (argc > 6){
|
|
layer = lua_tonumber(L,7);
|
|
}
|
|
|
|
_graphicsForLuaApi->map(celx, cely, sx, sy, celw, celh, layer);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int pal(lua_State *L) {
|
|
int numArgs = lua_gettop(L);
|
|
if (numArgs == 0) {
|
|
_graphicsForLuaApi->pal();
|
|
|
|
return 0;
|
|
}
|
|
|
|
int16_t p = 0;
|
|
int16_t c0 = 0;
|
|
int16_t c1 = 0;
|
|
|
|
if (lua_istable(L, 1)){
|
|
if (numArgs > 1) {
|
|
p = lua_tonumber(L,2);
|
|
}
|
|
|
|
/* table is in the stack at index 't' */
|
|
lua_pushnil(L); /* first key */
|
|
while (lua_next(L, 1) != 0) {
|
|
if (lua_isnumber(L, -2) && lua_isnumber(L, -1)) {
|
|
c0 = lua_tonumber(L, -2);
|
|
c1 = lua_tonumber(L, -1);
|
|
|
|
_graphicsForLuaApi->pal(c0, c1, p);
|
|
}
|
|
lua_pop(L, 1);
|
|
}
|
|
|
|
return 0;
|
|
} else if (numArgs == 1) {
|
|
p = lua_tonumber(L, 1);
|
|
|
|
_graphicsForLuaApi->pal(p);
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
c0 = lua_tonumber(L,1);
|
|
c1 = c0;
|
|
if (lua_gettop(L) > 1) {
|
|
c1 = lua_tonumber(L,2);
|
|
}
|
|
|
|
if (lua_gettop(L) > 2){
|
|
p = lua_tonumber(L,3);
|
|
}
|
|
|
|
uint8_t prev =_graphicsForLuaApi->pal(c0, c1, p);
|
|
|
|
lua_pushnumber(L, prev);
|
|
|
|
return 1;
|
|
}
|
|
|
|
int palt(lua_State *L) {
|
|
int16_t prev = 0;
|
|
//only 0th color is set to transparent if called with no args
|
|
int16_t c = 0;
|
|
c |= 1UL << 15;
|
|
if (lua_gettop(L) < 2) {
|
|
if (lua_gettop(L) == 1){
|
|
c = lua_tonumber(L,1);
|
|
}
|
|
//c is a bitfield of what colors should be transparent
|
|
for (int i = 0; i < 16; i++){
|
|
//get single bit
|
|
bool bit = (c >> (15 - i)) & 1U;
|
|
auto singlePrev = _graphicsForLuaApi->palt(i, bit);
|
|
//update prev single bit
|
|
if (singlePrev) {
|
|
prev |= 1UL << (15 - i);
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
c = lua_tonumber(L,1);
|
|
bool t = lua_toboolean(L,2);
|
|
prev = _graphicsForLuaApi->palt(c, t);
|
|
}
|
|
|
|
lua_pushnumber(L, prev);
|
|
|
|
return 1;
|
|
}
|
|
|
|
int cursor(lua_State *L) {
|
|
int x = lua_tonumber(L,1);
|
|
int y = lua_tonumber(L,2);
|
|
|
|
std::tuple<uint8_t, uint8_t> prev;
|
|
|
|
if (lua_gettop(L) < 3) {
|
|
prev = _graphicsForLuaApi->cursor(x, y);
|
|
}
|
|
else{
|
|
int16_t c = lua_tonumber(L,3);
|
|
|
|
prev =_graphicsForLuaApi->cursor(x, y, c);
|
|
}
|
|
|
|
lua_pushnumber(L, get<0>(prev));
|
|
lua_pushnumber(L, get<1>(prev));
|
|
|
|
return 2;
|
|
}
|
|
|
|
int fillp(lua_State *L) {
|
|
fix32 pat = 0;
|
|
if (lua_gettop(L) > 0) {
|
|
pat = lua_tonumber(L, 1);
|
|
}
|
|
|
|
fix32 prev = _graphicsForLuaApi->fillp(pat);
|
|
|
|
lua_pushnumber(L, prev);
|
|
|
|
return 1;
|
|
}
|
|
|
|
// int flip(lua_State *L) {
|
|
// _vmForLuaApi->vm_flip();
|
|
|
|
// return 0;
|
|
// }
|
|
|
|
//Input
|
|
|
|
//input api
|
|
int btn(lua_State *L){
|
|
int numArgs = lua_gettop(L);
|
|
if (numArgs == 0) {
|
|
uint8_t btnstate = _inputForLuaApi->btn();
|
|
|
|
lua_pushnumber(L, btnstate);
|
|
}
|
|
else {
|
|
fix32 i = lua_tonumber(L,1);
|
|
int p = 0;
|
|
if (numArgs > 1){
|
|
p = lua_tonumber(L,2);
|
|
};
|
|
|
|
bool pressed = _inputForLuaApi->btn((int)i, p);
|
|
|
|
lua_pushboolean(L, pressed);
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
int btnp(lua_State *L){
|
|
int numArgs = lua_gettop(L);
|
|
if (numArgs == 0) {
|
|
uint8_t btnpstate = _inputForLuaApi->btnp();
|
|
|
|
lua_pushnumber(L, btnpstate);
|
|
}
|
|
else {
|
|
fix32 i = lua_tonumber(L,1);
|
|
int p = 0;
|
|
if (numArgs > 1){
|
|
p = lua_tonumber(L,2);
|
|
};
|
|
|
|
bool pressed = _inputForLuaApi->btnp((int)i, p);
|
|
|
|
lua_pushboolean(L, pressed);
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
//System
|
|
int time(lua_State *L) {
|
|
int frameCount = _vmForLuaApi->GetFrameCount();
|
|
int targetFps = _vmForLuaApi->GetTargetFps();
|
|
|
|
fix32 seconds = (fix32)frameCount / (fix32)targetFps;
|
|
|
|
lua_pushnumber(L, seconds);
|
|
|
|
return 1;
|
|
}
|
|
|
|
int stat(lua_State *L) {
|
|
int n = (int)lua_tonumber(L, 1);
|
|
|
|
switch(n){
|
|
//0 memory usage
|
|
case 0:
|
|
//TODO: get from z8lua
|
|
lua_pushnumber(L, 1);
|
|
return 1;
|
|
break;
|
|
//cpu usage
|
|
case 1:
|
|
// stubbed to return 50%
|
|
lua_pushnumber(L, 0.5);
|
|
return 1;
|
|
break;
|
|
//cpu usage (without system calls)
|
|
case 2:
|
|
// stubbed to return 50%
|
|
lua_pushnumber(L, 0.5);
|
|
return 1;
|
|
break;
|
|
//clipboard contents
|
|
case 4:
|
|
// no clipboard support currently
|
|
lua_pushstring(L, "");
|
|
return 1;
|
|
break;
|
|
//version
|
|
case 5:
|
|
// no clipboard support currently
|
|
lua_pushnumber(L, 22);
|
|
return 1;
|
|
break;
|
|
//argument
|
|
case 6:
|
|
// no args or loading other cards currently supported
|
|
lua_pushstring(L, _vmForLuaApi->getCartParam().c_str());
|
|
return 1;
|
|
break;
|
|
//frame rate
|
|
case 7:
|
|
lua_pushnumber(L, _vmForLuaApi->getFps());
|
|
return 1;
|
|
break;
|
|
//target framerate
|
|
case 8:
|
|
//lua_pushnumber(L, _vmForLuaApi->getTargetFps());
|
|
lua_pushnumber(L, _vmForLuaApi->getFps());
|
|
return 1;
|
|
break;
|
|
//16-19 audio sfx currently playing
|
|
case 16:
|
|
case 46:
|
|
lua_pushnumber(L, _audioForLuaApi->getCurrentSfxId(0));
|
|
return 1;
|
|
break;
|
|
case 17:
|
|
case 47:
|
|
lua_pushnumber(L, _audioForLuaApi->getCurrentSfxId(1));
|
|
return 1;
|
|
break;
|
|
case 18:
|
|
case 48:
|
|
lua_pushnumber(L, _audioForLuaApi->getCurrentSfxId(2));
|
|
return 1;
|
|
break;
|
|
case 19:
|
|
case 49:
|
|
lua_pushnumber(L, _audioForLuaApi->getCurrentSfxId(3));
|
|
return 1;
|
|
break;
|
|
//20-23 note idx of sfx currently playing
|
|
case 20:
|
|
case 50:
|
|
lua_pushnumber(L, _audioForLuaApi->getCurrentNoteNumber(0));
|
|
return 1;
|
|
break;
|
|
case 21:
|
|
case 51:
|
|
lua_pushnumber(L, _audioForLuaApi->getCurrentNoteNumber(1));
|
|
return 1;
|
|
break;
|
|
case 22:
|
|
case 52:
|
|
lua_pushnumber(L, _audioForLuaApi->getCurrentNoteNumber(2));
|
|
return 1;
|
|
break;
|
|
case 23:
|
|
case 53:
|
|
lua_pushnumber(L, _audioForLuaApi->getCurrentNoteNumber(3));
|
|
return 1;
|
|
break;
|
|
//current music pattern
|
|
case 24:
|
|
case 54:
|
|
lua_pushnumber(L, _audioForLuaApi->getCurrentMusic());
|
|
return 1;
|
|
break;
|
|
//current music count
|
|
case 25:
|
|
case 55:
|
|
lua_pushnumber(L, _audioForLuaApi->getMusicPatternCount());
|
|
return 1;
|
|
break;
|
|
//current music tick count
|
|
case 56:
|
|
case 26:
|
|
lua_pushnumber(L, _audioForLuaApi->getMusicTickCount());
|
|
return 1;
|
|
break;
|
|
//if SDL scancode is pressed. always false for now
|
|
case 28:
|
|
lua_pushboolean(L, false);
|
|
return 1;
|
|
break;
|
|
//unknown. appears to always be 0
|
|
case 29:
|
|
lua_pushnumber(L, 0);
|
|
return 1;
|
|
break;
|
|
//was a key pressed
|
|
case 30:
|
|
lua_pushboolean(L, _inputForLuaApi->getKeyDown());
|
|
return 1;
|
|
break;
|
|
//string of key pressed
|
|
case 31:
|
|
lua_pushstring(L, _inputForLuaApi->getKey());
|
|
return 1;
|
|
break;
|
|
//mouse x
|
|
case 32:
|
|
lua_pushnumber(L, _inputForLuaApi->getMouseX());
|
|
return 1;
|
|
break;
|
|
//mouse y
|
|
case 33:
|
|
lua_pushnumber(L, _inputForLuaApi->getMouseY());
|
|
return 1;
|
|
break;
|
|
//mouse btn state
|
|
case 34:
|
|
lua_pushnumber(L, _inputForLuaApi->getMouseBtnState());
|
|
return 1;
|
|
break;
|
|
//Current Year
|
|
case 90:
|
|
lua_pushnumber(L, _vmForLuaApi->getYear());
|
|
return 1;
|
|
break;
|
|
//Current month
|
|
case 91:
|
|
lua_pushnumber(L, _vmForLuaApi->getMonth());
|
|
return 1;
|
|
break;
|
|
//Current day
|
|
case 92:
|
|
lua_pushnumber(L, _vmForLuaApi->getDay());
|
|
return 1;
|
|
break;
|
|
//Current Hour
|
|
case 93:
|
|
lua_pushnumber(L, _vmForLuaApi->getHour());
|
|
return 1;
|
|
break;
|
|
//Current Minute
|
|
case 94:
|
|
lua_pushnumber(L, _vmForLuaApi->getMinute());
|
|
return 1;
|
|
break;
|
|
//Current second
|
|
case 95:
|
|
lua_pushnumber(L, _vmForLuaApi->getSecond());
|
|
return 1;
|
|
break;
|
|
case 100:
|
|
lua_pushstring(L, _vmForLuaApi->getCartBreadcrumb().c_str());
|
|
return 1;
|
|
//101 and 102 are something to do with the bbs -
|
|
case 101:
|
|
lua_pushnil(L);
|
|
return 1;
|
|
case 102:
|
|
lua_pushnumber(L, 0);
|
|
return 1;
|
|
//unknown? used by serial carts
|
|
case 108:
|
|
lua_pushnumber(L, 32);
|
|
return 1;
|
|
break;
|
|
//bytestream availability (dropped file or image. not supported)
|
|
case 120:
|
|
lua_pushboolean(L, false);
|
|
return 1;
|
|
break;
|
|
case 121:
|
|
lua_pushboolean(L, false);
|
|
return 1;
|
|
break;
|
|
case 122:
|
|
lua_pushboolean(L, false);
|
|
return 1;
|
|
break;
|
|
}
|
|
|
|
|
|
return noopreturns(L, "stat");
|
|
}
|
|
|
|
//Audio
|
|
int music(lua_State *L) {
|
|
int n = lua_tonumber(L,1);
|
|
int fadems = 0;
|
|
if (lua_gettop(L) > 1) {
|
|
fadems = (int)lua_tonumber(L, 2);
|
|
}
|
|
int channelmask = 0;
|
|
if (lua_gettop(L) > 2) {
|
|
channelmask = (int)lua_tonumber(L, 3);
|
|
}
|
|
|
|
_audioForLuaApi->api_music(n, fadems, channelmask);
|
|
return 0;
|
|
}
|
|
|
|
int sfx(lua_State *L) {
|
|
fix32 n = lua_tonumber(L,1);
|
|
int channel = -1;
|
|
if (lua_gettop(L) > 1) {
|
|
channel = (int)lua_tonumber(L, 2);
|
|
}
|
|
int offset = 0;
|
|
if (lua_gettop(L) > 2) {
|
|
offset = (int)lua_tonumber(L, 3);
|
|
}
|
|
int length = -1;
|
|
if (lua_gettop(L) > 3) {
|
|
length = (int)lua_tonumber(L, 4);
|
|
}
|
|
|
|
int result = _audioForLuaApi->api_sfx((int)n, channel, offset, length);
|
|
lua_pushnumber(L, result);
|
|
|
|
return 1;
|
|
}
|
|
|
|
//Memory
|
|
int cstore(lua_State *L) {
|
|
//this is supposed to copy data from ram to the file.
|
|
//for now, not implementing this
|
|
return noop("cstore");
|
|
}
|
|
|
|
int api_memcpy(lua_State *L) {
|
|
uint16_t dest = (uint16_t)lua_tointeger(L,1);
|
|
uint16_t src = (uint16_t)lua_tointeger(L,2);
|
|
uint16_t len = (uint16_t)lua_tointeger(L,3);
|
|
|
|
_vmForLuaApi->vm_memcpy(dest, src, len);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int api_memset(lua_State *L) {
|
|
uint16_t dest = (uint16_t)lua_tointeger(L,1);
|
|
uint16_t val = (uint16_t)lua_tointeger(L,2);
|
|
uint16_t len = (uint16_t)lua_tointeger(L,3);
|
|
|
|
_vmForLuaApi->vm_memset(dest, val, len);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int peek(lua_State *L) {
|
|
int numArgs = lua_gettop(L);
|
|
int numToReturn = 1;
|
|
|
|
uint16_t addr = (uint16_t)lua_tointeger(L,1);
|
|
|
|
if (numArgs > 1) {
|
|
int tmpNumToReturn = lua_tonumber(L,2);
|
|
//pico 8 docs say up to 8192 - clamp to this limit
|
|
if (tmpNumToReturn > 0) {
|
|
numToReturn = tmpNumToReturn > 8192 ? 8192 : tmpNumToReturn;
|
|
}
|
|
}
|
|
|
|
// Ensure Lua stack has enough space for the values we're about to push
|
|
lua_checkstack(L, numToReturn);
|
|
|
|
for(int i = 0; i < numToReturn; i++) {
|
|
uint8_t val = _vmForLuaApi->vm_peek(addr + i);
|
|
|
|
lua_pushinteger(L, val);
|
|
}
|
|
|
|
return numToReturn;
|
|
}
|
|
|
|
int poke(lua_State *L) {
|
|
int numArgs = lua_gettop(L);
|
|
|
|
uint16_t dest = (uint16_t)lua_tointeger(L,1);
|
|
uint8_t val = 0;
|
|
if (numArgs > 1) {
|
|
val = lua_tonumber(L,2);
|
|
}
|
|
|
|
_vmForLuaApi->vm_poke(dest, val);
|
|
|
|
if (numArgs > 2) {
|
|
//pico 8 docs say up to 8192
|
|
int effectiveNumArgs = numArgs - 2;
|
|
if (effectiveNumArgs > 8192) {
|
|
effectiveNumArgs = 8192;
|
|
}
|
|
for(int i = 1; i <= effectiveNumArgs; i++) {
|
|
val = lua_tonumber(L, 2 + i);
|
|
_vmForLuaApi->vm_poke(dest + i, val);
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int peek2(lua_State *L) {
|
|
uint16_t addr = (uint16_t)lua_tointeger(L,1);
|
|
|
|
int16_t val = _vmForLuaApi->vm_peek2(addr);
|
|
|
|
lua_pushinteger(L, val);
|
|
|
|
return 1;
|
|
}
|
|
|
|
int poke2(lua_State *L) {
|
|
int numArgs = lua_gettop(L);
|
|
|
|
uint16_t dest = (uint16_t)lua_tointeger(L,1);
|
|
|
|
int val = 0;
|
|
if (numArgs > 1) {
|
|
val = lua_tonumber(L,2);
|
|
}
|
|
|
|
_vmForLuaApi->vm_poke2(dest, (int16_t)val);
|
|
|
|
if (numArgs > 2) {
|
|
for(int i = 1; i <= (numArgs - 2); i++) {
|
|
val = lua_tonumber(L, 2 + i);
|
|
_vmForLuaApi->vm_poke2(dest + i, (int16_t)val);
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int peek4(lua_State *L) {
|
|
uint16_t addr = (uint16_t)lua_tointeger(L,1);
|
|
|
|
fix32 val = _vmForLuaApi->vm_peek4(addr);
|
|
|
|
lua_pushnumber(L, val);
|
|
|
|
return 1;
|
|
}
|
|
|
|
int poke4(lua_State *L) {
|
|
int numArgs = lua_gettop(L);
|
|
|
|
uint16_t dest = (uint16_t)lua_tointeger(L,1);
|
|
|
|
fix32 val = 0;
|
|
if (numArgs > 1) {
|
|
val = lua_tonumber(L,2);
|
|
}
|
|
|
|
_vmForLuaApi->vm_poke4(dest, val);
|
|
|
|
if (numArgs > 2) {
|
|
for(int i = 1; i <= (numArgs - 2); i++) {
|
|
val = lua_tonumber(L, 2 + i);
|
|
_vmForLuaApi->vm_poke4(dest + i, val);
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int reload(lua_State *L) {
|
|
uint16_t dest = 0;
|
|
uint16_t src = 0;
|
|
uint16_t len = 0x4300;
|
|
const char * str = "";
|
|
if (lua_gettop(L) > 0) {
|
|
dest = (uint16_t)lua_tointeger(L,1);
|
|
}
|
|
if (lua_gettop(L) > 1) {
|
|
src = (uint16_t)lua_tointeger(L,2);
|
|
}
|
|
if (lua_gettop(L) > 2) {
|
|
len = (uint16_t)lua_tointeger(L,3);
|
|
}
|
|
if (lua_gettop(L) > 3) {
|
|
str = lua_tolstring(L, 4, nullptr);
|
|
if (str == nullptr) {
|
|
str = "";
|
|
}
|
|
}
|
|
|
|
_vmForLuaApi->vm_reload(dest, src, len, str);
|
|
|
|
return 0;
|
|
}
|
|
|
|
//cart data
|
|
int cartdata(lua_State *L) {
|
|
bool result = false;
|
|
|
|
if (lua_gettop(L) > 0 && lua_isstring(L, 1)) {
|
|
std::string key = lua_tolstring(L, 1, nullptr);
|
|
result = _vmForLuaApi->vm_cartdata(key);
|
|
}
|
|
|
|
lua_pushboolean(L, result);
|
|
|
|
return 1;
|
|
}
|
|
|
|
int dget(lua_State *L) {
|
|
int addr = lua_tonumber(L,1);
|
|
|
|
fix32 val = _vmForLuaApi->vm_dget(addr);
|
|
|
|
lua_pushnumber(L, val);
|
|
|
|
return 1;
|
|
}
|
|
|
|
int dset(lua_State *L) {
|
|
int dest = lua_tonumber(L,1);
|
|
fix32 val = lua_tonumber(L,2);
|
|
|
|
_vmForLuaApi->vm_dset(dest, val);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int printh(lua_State *L) {
|
|
if (lua_isstring(L, 1)){
|
|
const char * str = "";
|
|
str = lua_tolstring(L, 1, nullptr);
|
|
std::string utf8str = charset::pico8_to_utf8(str);
|
|
printf("%s\n", utf8str.c_str());
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int rnd(lua_State *L) {
|
|
if (lua_gettop(L) == 0) {
|
|
fix32 val = _vmForLuaApi->api_rnd();
|
|
|
|
lua_pushnumber(L, val);
|
|
}
|
|
else {
|
|
if (lua_istable(L, 1)){
|
|
size_t len = lua_rawlen(L,1);
|
|
fix32 range = (fix32)len;
|
|
int idx = (int)(_vmForLuaApi->api_rnd(range)) + 1;
|
|
|
|
lua_rawgeti(L, 1, idx);
|
|
}
|
|
else {
|
|
fix32 range = lua_tonumber(L,1);
|
|
fix32 val = _vmForLuaApi->api_rnd(range);
|
|
|
|
lua_pushnumber(L, val);
|
|
}
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
int srand(lua_State *L) {
|
|
fix32 seed = lua_tonumber(L,1);
|
|
_vmForLuaApi->api_srand(seed);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int _update_buttons(lua_State *L) {
|
|
_vmForLuaApi->update_buttons();
|
|
|
|
return 0;
|
|
}
|
|
|
|
int run(lua_State *L) {
|
|
_vmForLuaApi->vm_run();
|
|
|
|
return 0;
|
|
}
|
|
|
|
int extcmd(lua_State *L){
|
|
const char * str = "";
|
|
|
|
if (lua_isstring(L, 1)){
|
|
str = lua_tolstring(L, 1, nullptr);
|
|
}
|
|
|
|
_vmForLuaApi->vm_extcmd(str);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int load(lua_State *L) {
|
|
const char* filename = "";
|
|
const char* breadcrumb = "";
|
|
const char* param = "";
|
|
int argC = lua_gettop(L);
|
|
if (argC > 0 && lua_isstring(L, 1)){
|
|
filename = lua_tolstring(L, 1, nullptr);
|
|
if (argC > 1 && lua_isstring(L, 2)){
|
|
breadcrumb = lua_tolstring(L, 2, nullptr);
|
|
}
|
|
if (argC > 2 && lua_isstring(L, 3)){
|
|
param = lua_tolstring(L, 3, nullptr);
|
|
}
|
|
|
|
bool result = _vmForLuaApi->vm_load(filename, breadcrumb, param);
|
|
if (result) {
|
|
//todo: abort current cart?
|
|
}
|
|
lua_pushboolean(L, result);
|
|
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int reset(lua_State *L) {
|
|
_vmForLuaApi->vm_reset();
|
|
|
|
return 0;
|
|
}
|
|
|
|
int setFps(lua_State *L){
|
|
//_vmForLuaApi->setTargetFps(lua_tointeger(L, 1));
|
|
|
|
return 0;
|
|
}
|
|
|
|
int listcarts(lua_State *L) {
|
|
//get cart list from VM (who should get it from host)
|
|
vector<string> carts = _vmForLuaApi->GetCartList();
|
|
|
|
lua_createtable(L, carts.size(), 0);
|
|
int newTable = lua_gettop(L);
|
|
int index = 1;
|
|
|
|
for(size_t i = 0; i < carts.size(); i++){
|
|
lua_pushstring(L, carts[i].c_str());
|
|
lua_rawseti(L, newTable, index);
|
|
|
|
++index;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
int listdirs(lua_State *L) {
|
|
vector<string> dirs = _vmForLuaApi->GetDirList();
|
|
|
|
lua_createtable(L, dirs.size(), 0);
|
|
int newTable = lua_gettop(L);
|
|
int index = 1;
|
|
|
|
for(size_t i = 0; i < dirs.size(); i++){
|
|
lua_pushstring(L, dirs[i].c_str());
|
|
lua_rawseti(L, newTable, index);
|
|
|
|
++index;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
int cd(lua_State *L) {
|
|
const char* dir = "";
|
|
if (lua_gettop(L) > 0 && lua_isstring(L, 1)){
|
|
dir = lua_tolstring(L, 1, nullptr);
|
|
}
|
|
|
|
bool result = _vmForLuaApi->ChangeDirectory(dir);
|
|
lua_pushboolean(L, result);
|
|
|
|
return 1;
|
|
}
|
|
|
|
int pwd(lua_State *L) {
|
|
string dir = _vmForLuaApi->GetCurrentDirectory();
|
|
lua_pushstring(L, dir.c_str());
|
|
|
|
return 1;
|
|
}
|
|
|
|
int refreshcarts(lua_State *L) {
|
|
_vmForLuaApi->RefreshCartList();
|
|
return 0;
|
|
}
|
|
|
|
int bbs_listfeatured(lua_State *L) {
|
|
vector<BBSCartItem> carts = _vmForLuaApi->GetBBSFeaturedCarts();
|
|
lua_createtable(L, (int)carts.size(), 0);
|
|
int top = lua_gettop(L);
|
|
|
|
for (size_t i = 0; i < carts.size(); i++) {
|
|
lua_createtable(L, 0, 7);
|
|
|
|
lua_pushstring(L, carts[i].id.c_str());
|
|
lua_setfield(L, -2, "id");
|
|
|
|
lua_pushstring(L, carts[i].title.c_str());
|
|
lua_setfield(L, -2, "title");
|
|
|
|
lua_pushstring(L, carts[i].author.c_str());
|
|
lua_setfield(L, -2, "author");
|
|
|
|
lua_pushstring(L, carts[i].category.c_str());
|
|
lua_setfield(L, -2, "cat");
|
|
|
|
lua_pushstring(L, carts[i].filename.c_str());
|
|
lua_setfield(L, -2, "file");
|
|
|
|
lua_pushstring(L, carts[i].url.c_str());
|
|
lua_setfield(L, -2, "url");
|
|
|
|
lua_pushboolean(L, carts[i].downloaded);
|
|
lua_setfield(L, -2, "downloaded");
|
|
|
|
lua_rawseti(L, top, (int)i + 1);
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
int bbs_download(lua_State *L) {
|
|
int argC = lua_gettop(L);
|
|
if (argC >= 2 && lua_isstring(L, 1) && lua_isstring(L, 2)) {
|
|
string lid = lua_tostring(L, 1);
|
|
string filename = lua_tostring(L, 2);
|
|
bool res = _vmForLuaApi->DownloadBBSCart(lid, filename);
|
|
lua_pushboolean(L, res);
|
|
return 1;
|
|
}
|
|
lua_pushboolean(L, false);
|
|
return 1;
|
|
}
|
|
|
|
int bbs_isdownloaded(lua_State *L) {
|
|
int argC = lua_gettop(L);
|
|
if (argC >= 1 && lua_isstring(L, 1)) {
|
|
string filename = lua_tostring(L, 1);
|
|
bool res = _vmForLuaApi->IsBBSCartDownloaded(filename);
|
|
lua_pushboolean(L, res);
|
|
return 1;
|
|
}
|
|
lua_pushboolean(L, false);
|
|
return 1;
|
|
}
|
|
|
|
|
|
|
|
int getbioserror(lua_State *L) {
|
|
string error = _vmForLuaApi->GetBiosError();
|
|
|
|
lua_pushstring(L, error.c_str());
|
|
|
|
return 1;
|
|
}
|
|
|
|
int loaddefaultcart(lua_State *L) {
|
|
_vmForLuaApi->QueueCartChange("__FAKE08-DEFAULT.p8");
|
|
|
|
return 0;
|
|
}
|
|
|
|
int loadsettingscart(lua_State *L) {
|
|
_vmForLuaApi->QueueCartChange("__FAKE08-SETTINGS.p8");
|
|
|
|
return 0;
|
|
}
|
|
|
|
int togglepausemenu(lua_State *L) {
|
|
_vmForLuaApi->togglePauseMenu();
|
|
|
|
return 0;
|
|
}
|
|
|
|
int ispaused(lua_State *L) {
|
|
lua_pushboolean(L, _vmForLuaApi->IsPaused());
|
|
|
|
return 1;
|
|
}
|
|
|
|
int resetcart(lua_State *L) {
|
|
_vmForLuaApi->QueueCartChange(_vmForLuaApi->CurrentCartFilename());
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
int getsetting(lua_State *L) {
|
|
//get setting from host
|
|
|
|
const char * str = "";
|
|
if (lua_isstring(L, 1)){
|
|
str = lua_tolstring(L, 1, nullptr);
|
|
}
|
|
Logger_Write("loading setting ");
|
|
Logger_Write(str);
|
|
Logger_Write("\n");
|
|
//std::string sname = str;
|
|
|
|
int val = _vmForLuaApi->getSetting(str);
|
|
|
|
lua_pushnumber(L, val);
|
|
|
|
return 1;
|
|
}
|
|
|
|
int setsetting(lua_State *L) {
|
|
//get setting from host
|
|
const char * str = "";
|
|
if (lua_isstring(L, 1)){
|
|
str = lua_tolstring(L, 1, nullptr);
|
|
}
|
|
Logger_Write("setting setting ");
|
|
Logger_Write(str);
|
|
Logger_Write("\n");
|
|
|
|
int sval = lua_tonumber(L,2);
|
|
|
|
_vmForLuaApi->setSetting(str,sval);
|
|
|
|
return 1;
|
|
}
|
|
|
|
|
|
|
|
int installpackins(lua_State *L) {
|
|
#if LOAD_PACK_INS
|
|
_vmForLuaApi->installPackins();
|
|
#endif
|
|
return 1;
|
|
}
|
|
|
|
|
|
int loadlabel(lua_State *L) {
|
|
|
|
const char * cartname = "";
|
|
if (lua_isstring(L, 1)){
|
|
cartname = lua_tolstring(L, 1, nullptr);
|
|
}
|
|
std::string filename = cartname;
|
|
|
|
bool mini = lua_toboolean(L,2);
|
|
int minioffset = lua_tonumber(L,3);
|
|
|
|
_vmForLuaApi->loadLabel(filename, mini, minioffset);
|
|
return 1;
|
|
}
|
|
|
|
|
|
int getlualine(lua_State *L) {
|
|
const char * cartname = "";
|
|
if (lua_isstring(L, 1)){
|
|
cartname = lua_tolstring(L, 1, nullptr);
|
|
}
|
|
std::string filename = cartname;
|
|
|
|
int linenumber = lua_tonumber(L,2);
|
|
|
|
std::string resultstring = _vmForLuaApi->getLuaLine(filename, linenumber);
|
|
|
|
lua_pushstring(L, resultstring.c_str());
|
|
|
|
return 1;
|
|
}
|