Commit 1a4ec101 authored by Jack's avatar Jack
Browse files

added atan2, poke, peek, extcmd stub and time, added std::async call to _init...

added atan2, poke, peek, extcmd stub and time, added std::async call to _init to avoid problems with busy loops
parent aae3a5ca
......@@ -52,6 +52,8 @@ private:
#define SOUND_ENABLED true
#define LOGD(x , ...) printf(x"\n", __VA_ARGS__)
#ifdef _WIN32
#define MOUSE_ENABLED true
#define WINDOW_SCALE 1
......
......@@ -1414,6 +1414,8 @@ static void forstat (LexState *ls, int line) {
}
void retstat(LexState* ls);
static void inline_if(LexState* ls, expdesc* v)
{
/* IF ( COND ) block [ELSE block]*/
......@@ -1429,7 +1431,13 @@ static void inline_if(LexState* ls, expdesc* v)
enterblock(fs, &bl, 0);
jf = v->f;
statement(ls); /* parse true block */
/* handling return manually because otherwise any valid LHS
would be parsed as return value for return statement */
if (ls->t.token == TK_RETURN)
retstat(ls);
else
statlist(ls); /* parse true block */
leaveblock(fs);
luaK_patchtohere(fs, jf);
......
#include "main_view.h"
#include "io/loader.h"
#include "io/stegano.h"
#include <future>
using namespace ui;
namespace r8 = retro8;
......@@ -108,11 +109,10 @@ void GameView::render()
retro8::io::Loader loader;
if (_path.empty())
_path = "mario.p8";
_path = "celeste.p8";
loader.load(_path, machine);
/*SDL_Surface* surface = IMG_Load("pico-man.p8.png");
r8::io::PngData pngData = { static_cast<const uint32_t*>(surface->pixels), surface->h * surface->w };
assert(surface->pitch == r8::io::Stegano::IMAGE_WIDTH * sizeof(uint32_t));
......@@ -120,11 +120,19 @@ void GameView::render()
r8::io::Stegano stegano;
stegano.load(pngData, machine);*/
manager->setFrameRate(machine.code().require60fps() ? 60 : 30);
int32_t fps = machine.code().require60fps() ? 60 : 30;
manager->setFrameRate(fps);
if (machine.code().hasInit())
machine.code().init();
{
LOGD("Cartridge has _init() function, calling it.");
/* init is launched on a different thread because some developers are using busy loops and manual flips */
_initFuture = std::async([]() {
machine.code().init();
LOGD("_init() function completed execution.");
});
}
machine.sound().init();
machine.sound().resume();
......@@ -147,8 +155,12 @@ void GameView::render()
if (!_paused)
{
update();
machine.flip();
if (!_initFuture.valid() || _initFuture.wait_for(std::chrono::nanoseconds(0)) == std::future_status::ready)
{
update();
machine.flip();
}
SDL_UpdateTexture(_outputTexture, nullptr, _output->pixels, _output->pitch);
}
......@@ -267,6 +279,8 @@ void GameView::text(const std::string& text, int32_t x, int32_t y)
}
}
//int32_t lastButtonFrame[6];
void GameView::handleKeyboardEvent(const SDL_Event& event)
{
switch (event.key.keysym.sym)
......@@ -297,6 +311,14 @@ void GameView::handleKeyboardEvent(const SDL_Event& event)
case SDLK_p:
if (event.type == SDL_KEYDOWN)
_paused = !_paused;
#if SOUND_ENABLED
if (_paused)
machine.sound().pause();
else
machine.sound().resume();
#endif
break;
......
......@@ -5,6 +5,7 @@
#include <iostream>
#include <fstream>
#include <streambuf>
#include <future>
#include "lua/lua.hpp"
......@@ -33,6 +34,8 @@ namespace ui
std::string _path;
std::future<void> _initFuture;
bool _paused;
bool _showFPS;
......
......@@ -439,6 +439,18 @@ namespace math
return 1;
}
int atan2(lua_State* L)
{
assert(lua_isnumber(L, 1));
//TODO: check if behavior is same as PICO-8
real_t dx = lua_tonumber(L, 1);
real_t dy = lua_tonumber(L, 2);
real_t value = ::atan2(dx, -dy);
lua_pushnumber(L, value);
return 1;
}
int srand(lua_State* L)
{
assert(lua_gettop(L) == 1);
......@@ -636,13 +648,14 @@ namespace string
size_t s = lua_tonumber(L, 2);
size_t e = lua_to_or_default(L, number, 3, -1);
size_t rs = s, re = e;
if (s < 0)
s = v.length() - s + 1;
if (e < 0)
e = v.length() - e + 1;
assert(s <= e);
lua_pushstring(L, v.substr(s, e - s + 1).c_str());
lua_pushstring(L, v.substr(s - 1, e - s + 1).c_str());
return 1;
}
......@@ -650,6 +663,27 @@ namespace string
namespace platform
{
int poke(lua_State* L)
{
address_t addr = lua_tonumber(L, 1);
uint8_t byte = lua_tonumber(L, 2);
machine.memory().base()[addr] = byte;
return 0;
}
int peek(lua_State* L)
{
address_t addr = lua_tonumber(L, 1);
uint8_t value = machine.memory().base()[addr];
lua_pushnumber(L, value);
return 1;
}
int btn(lua_State* L)
{
/* we're asking for a specific button*/
......@@ -703,7 +737,7 @@ namespace platform
switch (s)
{
case Stat::FRAME_RATE: lua_pushnumber(L, machine.code().require60fps() ? 60 : 30); break;
default: lua_pushnumber(L, 0);
default: lua_pushnumber(L, 0);
}
......@@ -736,10 +770,24 @@ namespace platform
int flip(lua_State* L)
{
//TODO: this call should syncronize to 30fps, at the moment it just
// returns producing a lot of flips in non synchronized code (eg. _init() busy loop)
machine.flip();
return 0;
}
int extcmd(lua_State* L)
{
//TODO: implement
return 0;
}
int time(lua_State* L)
{
lua_pushnumber(L, SDL_GetTicks() / 1000.0f);
return 1;
}
}
#pragma warning(pop)
......@@ -771,11 +819,12 @@ void lua::registerFunctions(lua_State* L)
lua_register(L, "fget", sprites::fget);
lua_register(L, "sspr", sprites::sspr);
lua_register(L, "__debug", debug::debugprint);
lua_register(L, "__debugprint", debug::debugprint);
lua_register(L, "__breakpoint", debug::breakpoint);
lua_register(L, "cos", math::cos);
lua_register(L, "sin", math::sin);
lua_register(L, "atan2", math::atan2);
lua_register(L, "srand", math::srand);
lua_register(L, "rnd", math::rnd);
lua_register(L, "flr", math::flr);
......@@ -801,10 +850,14 @@ void lua::registerFunctions(lua_State* L)
lua_register(L, "btn", platform::btn);
lua_register(L, "btnp", platform::btnp);
lua_register(L, "time", platform::time);
lua_register(L, "extcmd", platform::extcmd);
lua_register(L, "stat", platform::stat);
lua_register(L, "cartdata", platform::cartdata);
lua_register(L, "dset", platform::dset);
lua_register(L, "dget", platform::dget);
lua_register(L, "poke", platform::poke);
lua_register(L, "peek", platform::peek);
lua_register(L, "flip", platform::flip);
}
......
......@@ -196,6 +196,11 @@ void APU::resume()
SDL_PauseAudioDevice(device, false);
}
void APU::pause()
{
SDL_PauseAudioDevice(device, true);
}
void APU::close()
{
SDL_CloseAudioDevice(device);
......@@ -416,13 +421,15 @@ void APU::renderSound(const SoundState& channel, int16_t* buffer, size_t samples
void APU::renderSounds(int16_t* dest, size_t totalSamples)
{
memset(dest, 0, sizeof(int16_t)*totalSamples);
//return;
handleCommands();
constexpr size_t rate = 44100;
constexpr int16_t maxVolume = 4096;
memset(dest, 0, sizeof(int16_t)*totalSamples);
for (size_t i = 0; i < CHANNEL_COUNT; ++i)
{
int16_t* buffer = dest;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment