Skip to content

Commit

Permalink
Misc tweaks and fixes
Browse files Browse the repository at this point in the history
* Imagine: Add ApplicationContext::fileUriType()
* Imagine: Improve document picker API
* Imagine: Ignore extra type bits on device names starting with "uinput-" on Android which are finger print sensors incorrectly flagged as joysticks
* Imagine: Update the virtual memory API for easier resource management and add RAII type UniqueVPtr
* Imagine: Simplify VMemArray by implementing it in terms of UniqueVPtr
* Imagine: Re-write RingBuffer as a template class and align read/write pointers to reduce data sharing between threads
* Imagine: Link ARM64 Android build with 16Kb page size option for future OS compatibility
* Imagine: Implement isPowerOf2() with std::has_single_bit()
* EmuFramework: Allow opening a folder from an external event
* EmuFramework: Fix setting file extension in Mednafen loadContent() utility function
* EmuFramework: Only show System -> Performance Mode option if Android reports sustained performance mode is supported
* EmuFramework: Fix VController speed toggle color reset when toggling keyboard mode
* NES.emu: Add/Update various palettes
* PCE.emu: Fix loading SuperGrafx content not in internal DB such as homebrew ROMs
* Saturn.emu: Fix reading m3u files with Windows line endings
* Saturn.emu: Replace VDP2 thread queue code with new RingBuffer class
  • Loading branch information
Robert Broglia committed Apr 10, 2024
1 parent 2fc3e66 commit f46dcda
Show file tree
Hide file tree
Showing 56 changed files with 690 additions and 743 deletions.
3 changes: 2 additions & 1 deletion EmuFramework/include/emuframework/DataPathSelectView.hh
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ public:
{
if(!onFileChange(path, FS::file_type::directory))
return;
picker.popTo();
picker.dismissPrevious();
picker.dismiss();
});
Expand All @@ -92,7 +93,7 @@ public:
}
if(!onFileChange(path, FS::file_type::regular))
return;
picker.popTo(picker);
picker.popTo();
picker.dismissPrevious();
picker.dismiss();
});
Expand Down
6 changes: 3 additions & 3 deletions EmuFramework/include/emuframework/EmuAudio.hh
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
#include <imagine/audio/OutputStream.hh>
#include <imagine/audio/Manager.hh>
#include <imagine/time/Time.hh>
#include <imagine/vmem/RingBuffer.hh>
#include <imagine/util/container/RingBuffer.hh>
#include <imagine/util/used.hh>
#include <memory>
#include <atomic>
Expand Down Expand Up @@ -78,14 +78,14 @@ public:
void setEnabledDuringAltSpeed(bool on);
bool isEnabledDuringAltSpeed() const;
IG::Audio::Format format() const;
explicit operator bool() const { return bool(rBuff); }
explicit operator bool() const { return bool(rBuff.capacity()); }
void writeConfig(FileIO &) const;
bool readConfig(MapIO &, unsigned key);

IG::Audio::Manager manager;
protected:
IG::Audio::OutputStream audioStream;
RingBuffer rBuff;
RingBuffer<uint8_t, RingBufferConf{.mirrored = true}> rBuff;
SteadyClockTimePoint lastUnderrunTime{};
double speedMultiplier{1.};
size_t targetBufferFillBytes{};
Expand Down
1 change: 1 addition & 0 deletions EmuFramework/include/emuframework/EmuViewController.hh
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ public:
void onHide();
void movePopupToWindow(IG::Window &win);
void moveEmuViewToWindow(IG::Window &win);
View &top() const { return viewStack.top(); }

public:
EmuView emuView;
Expand Down
1 change: 1 addition & 0 deletions EmuFramework/include/emuframework/UserPathSelectView.hh
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ public:
[=](FSPicker &picker, CStringView path, std::string_view displayName, const Input::Event &e)
{
onPathChange(path);
picker.popTo();
picker.dismissPrevious();
picker.dismiss();
});
Expand Down
32 changes: 17 additions & 15 deletions EmuFramework/src/EmuApp.cc
Original file line number Diff line number Diff line change
Expand Up @@ -114,10 +114,10 @@ EmuApp::EmuApp(ApplicationInitParams initParams, ApplicationContext &ctx):
{
visit(overloaded
{
[&](InterProcessMessageEvent &e)
[&](DocumentPickerEvent& e)
{
log.info("got IPC path:{}", e.filename);
system().setInitialLoadPath(e.filename);
log.info("document picked with URI:{}", e.uri);
system().setInitialLoadPath(e.uri);
},
[](auto &) {}
}, appEvent);
Expand Down Expand Up @@ -407,9 +407,7 @@ void EmuApp::mainInitCommon(IG::ApplicationInitParams initParams, IG::Applicatio
system().onOptionsLoaded();
loadSystemOptions();
updateLegacySavePathOnStoragePath(ctx, system());
if(auto launchGame = parseCommandArgs(initParams.commandArgs());
launchGame)
system().setInitialLoadPath(launchGame);
system().setInitialLoadPath(parseCommandArgs(initParams.commandArgs()));
audio.manager.setMusicVolumeControlHint();
if(!renderer.supportsColorSpace())
windowDrawableConf.colorSpace = {};
Expand Down Expand Up @@ -540,10 +538,12 @@ void EmuApp::mainInitCommon(IG::ApplicationInitParams initParams, IG::Applicatio
{
visit(overloaded
{
[&](InterProcessMessageEvent &e)
[&](DocumentPickerEvent& e)
{
log.info("got IPC path:{}", e.filename);
handleOpenFileCommand(e.filename);
log.info("document picked with URI:{}", e.uri);
if(viewController().top().onDocumentPicked(e))
return;
handleOpenFileCommand(e.uri);
},
[&](ScreenChangeEvent &e)
{
Expand Down Expand Up @@ -807,7 +807,7 @@ void EmuApp::handleOpenFileCommand(CStringView path)
postErrorMessage(std::format("Can't access path name for:\n{}", path));
return;
}
if(!IG::isUri(path) && FS::status(path).type() == FS::file_type::directory)
if(appContext().fileUriType(path) == FS::file_type::directory)
{
log.info("changing to dir {} from external command", path);
showUI(false);
Expand All @@ -817,12 +817,14 @@ void EmuApp::handleOpenFileCommand(CStringView path)
FilePicker::forLoading(attachParams(), appContext().defaultInputEvent()),
appContext().defaultInputEvent(),
false);
return;
}
log.info("opening file {} from external command", path);
showUI();
viewController().popToRoot();
onSelectFileFromPicker({}, path, name, Input::KeyEvent{}, {}, attachParams());
else
{
log.info("opening file {} from external command", path);
showUI();
viewController().popToRoot();
onSelectFileFromPicker({}, path, name, Input::KeyEvent{}, {}, attachParams());
}
}

void EmuApp::runBenchmarkOneShot(EmuVideo &video)
Expand Down
53 changes: 28 additions & 25 deletions EmuFramework/src/EmuAudio.cc
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ void EmuAudio::resizeAudioBuffer(size_t targetBufferFillBytes)
if(Config::DEBUG_BUILD && rBuff.capacity() != oldCapacity)
{
log.info("created audio buffer:{} frames ({}), fill target:{} frames ({})",
format().bytesToFrames(rBuff.freeSpace()), format().bytesToTime(rBuff.freeSpace()),
format().bytesToFrames(rBuff.capacity()), format().bytesToTime(rBuff.capacity()),
format().bytesToFrames(targetBufferFillBytes), format().bytesToTime(targetBufferFillBytes));
}
}
Expand Down Expand Up @@ -186,15 +186,15 @@ void EmuAudio::start(FloatSeconds bufferDuration)
if(audioWriteState == AudioWriteState::ACTIVE)
{
IG::Audio::Format inputFormat = {{}, inputSampleFormat, channels};
auto framesReady = inputFormat.bytesToFrames(rBuff.size());
auto const framesToRead = std::min(frames, framesReady);
auto frameEndAddr = (char*)outputFormat.copyFrames(samples, rBuff.readAddr(), framesToRead, inputFormat, currentVolume);
rBuff.commitRead(inputFormat.framesToBytes(framesToRead));
auto span = rBuff.beginRead(inputFormat.framesToBytes(frames));
auto const framesToRead = inputFormat.bytesToFrames(span.size());
auto frameEndAddr = (char*)outputFormat.copyFrames(samples, span.data(), framesToRead, inputFormat, currentVolume);
rBuff.endRead(span);
if(framesToRead < frames) [[unlikely]]
{
auto padFrames = frames - framesToRead;
std::fill_n(frameEndAddr, outputFormat.framesToBytes(padFrames), 0);
//log.info("underrun, {} bytes ready out of {}", bytesReady, bytes);
//log.warn("underrun, {} bytes ready out of {}", span.size, inputFormat.framesToBytes(frames));
auto now = SteadyClock::now();
if(now - lastUnderrunTime < IG::Seconds(1))
{
Expand Down Expand Up @@ -253,7 +253,7 @@ void EmuAudio::close()
{
stop();
audioStream.reset();
rBuff = {};
rBuff.reset();
}

void EmuAudio::flush()
Expand All @@ -271,7 +271,7 @@ void EmuAudio::writeFrames(const void *samples, size_t framesToWrite)
{
if(!framesToWrite) [[unlikely]]
return;
assumeExpr(rBuff);
assumeExpr(rBuff.capacity());
auto inputFormat = format();
switch(audioWriteState)
{
Expand All @@ -297,26 +297,29 @@ void EmuAudio::writeFrames(const void *samples, size_t framesToWrite)
framesToWrite = std::max(framesToWrite, 1zu);
}
auto bytes = inputFormat.framesToBytes(framesToWrite);
auto freeBytes = rBuff.freeSpace();
if(bytes <= freeBytes)
{
if(sampleFrames != framesToWrite)
auto span = rBuff.beginWrite(bytes);
if(bytes <= span.size())
{
simpleResample(rBuff.writeAddr(), framesToWrite, samples, sampleFrames, inputFormat);
rBuff.commitWrite(bytes);
if(sampleFrames != framesToWrite)
{
simpleResample(span.data(), framesToWrite, samples, sampleFrames, inputFormat);
}
else
{
copy_n(static_cast<const uint8_t*>(samples), bytes, span.data());
}
}
else
rBuff.writeUnchecked(samples, bytes);
}
else
{
log.info("overrun, only {} out of {} bytes free", freeBytes, bytes);
#ifdef CONFIG_EMUFRAMEWORK_AUDIO_STATS
audioStats.overruns++;
#endif
auto freeFrames = inputFormat.bytesToFrames(freeBytes);
simpleResample(rBuff.writeAddr(), freeFrames, samples, sampleFrames, inputFormat);
rBuff.commitWrite(freeBytes);
else // not enough space for write
{
log.info("overrun, only {} out of {} bytes free", span.size(), bytes);
#ifdef CONFIG_EMUFRAMEWORK_AUDIO_STATS
audioStats.overruns++;
#endif
auto freeFrames = inputFormat.bytesToFrames(span.size());
simpleResample(span.data(), freeFrames, samples, sampleFrames, inputFormat);
}
rBuff.endWrite(span);
}
if(audioWriteState == AudioWriteState::BUFFER && shouldStartAudioWrites(bytes))
{
Expand Down
2 changes: 2 additions & 0 deletions EmuFramework/src/EmuSystem.cc
Original file line number Diff line number Diff line change
Expand Up @@ -508,6 +508,8 @@ FS::FileString EmuSystem::contentDisplayNameForPathDefaultImpl(CStringView path)
void EmuSystem::setInitialLoadPath(CStringView path)
{
assert(contentName_.empty());
if(!path)
return;
contentLocation_ = path;
}

Expand Down
1 change: 1 addition & 0 deletions EmuFramework/src/gui/EmuInputView.cc
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ void EmuInputView::place()
void EmuInputView::resetInput()
{
vController->resetInput();
vController->updateAltSpeedModeInput({}, false);
speedToggleActive = false;
}

Expand Down
2 changes: 2 additions & 0 deletions EmuFramework/src/gui/FilePathOptionView.cc
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ FilePathOptionView::FilePathOptionView(ViewAttachParams attach, bool customMenu)
}
system().setUserSaveDirectory(path);
onSavePathChange(path);
picker.popTo();
dismissPrevious();
picker.dismiss();
});
Expand Down Expand Up @@ -129,6 +130,7 @@ FilePathOptionView::FilePathOptionView(ViewAttachParams attach, bool customMenu)
EmuApp::updateLegacySavePath(ctx, path);
system().setUserSaveDirectory(path);
onSavePathChange(path);
picker.popTo();
dismissPrevious();
picker.dismiss();
});
Expand Down
2 changes: 1 addition & 1 deletion EmuFramework/src/shared/mednafen-emuex/MDFNUtils.hh
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ inline void loadContent(EmuSystem &sys, Mednafen::MDFNGI &mdfnGameInfo, IO &io,
stream->setSize(size);
MDFNFILE fp(&NVFS, std::move(stream));
GameFile gf{&NVFS, std::string{sys.contentDirectory()}, {}, fp.stream(),
std::string{withoutDotExtension(sys.contentFileName())},
std::string{dotExtension(sys.contentFileName())},
std::string{sys.contentName()}};
mdfnGameInfo.Load(&gf);
}
Expand Down
1 change: 0 additions & 1 deletion EmuFramework/src/vcontrols/VController.cc
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,6 @@ void VController::resetInput()
}
}
dragTracker.reset();
updateAltSpeedModeInput({}, false);
}

void VController::updateAltSpeedModeInput(AltSpeedMode mode, bool on)
Expand Down
Binary file added NES.emu/res/palette/Digital Prime (FBX).pal
Binary file not shown.
Binary file added NES.emu/res/palette/Lightful.pal
Binary file not shown.
Binary file added NES.emu/res/palette/Magnum (FBX).pal
Binary file not shown.
Binary file removed NES.emu/res/palette/Smooth (FBX).pal
Binary file not shown.
Binary file added NES.emu/res/palette/Smooth V2 (FBX).pal
Binary file not shown.
38 changes: 21 additions & 17 deletions NES.emu/src/main/EmuMenuViews.cc
Original file line number Diff line number Diff line change
Expand Up @@ -324,9 +324,12 @@ class CustomVideoOptionView : public VideoOptionView, public MainAppHelper<Custo
videoSystemItem
};

static constexpr const char *firebrandXPalPath = "Smooth (FBX).pal";
static constexpr const char *wavebeamPalPath = "Wavebeam.pal";
static constexpr const char *classicPalPath = "Classic (FBX).pal";
static constexpr auto digitalPrimePalPath = "Digital Prime (FBX).pal";
static constexpr auto smoothPalPath = "Smooth V2 (FBX)";
static constexpr auto magnumPalPath = "Magnum (FBX)";
static constexpr auto classicPalPath = "Classic (FBX).pal";
static constexpr auto wavebeamPalPath = "Wavebeam.pal";
static constexpr auto lightfulPalPath = "Lightful.pal";

void setPalette(IG::ApplicationContext ctx, IG::CStringView palPath)
{
Expand All @@ -339,17 +342,20 @@ class CustomVideoOptionView : public VideoOptionView, public MainAppHelper<Custo
app.renderSystemFramebuffer();
}

constexpr uint32_t defaultPaletteCustomFileIdx()
constexpr size_t defaultPaletteCustomFileIdx()
{
return lastIndex(defaultPalItem);
}

TextMenuItem defaultPalItem[5]
TextMenuItem defaultPalItem[8]
{
{"FCEUX", attachParams(), [this](){ setPalette(appContext(), ""); }},
{"FirebrandX", attachParams(), [this]() { setPalette(appContext(), firebrandXPalPath); }},
{"Digital Prime (FBX)", attachParams(), [this]() { setPalette(appContext(), digitalPrimePalPath); }},
{"Smooth V2 (FBX)", attachParams(), [this]() { setPalette(appContext(), smoothPalPath); }},
{"Magnum (FBX)", attachParams(), [this]() { setPalette(appContext(), magnumPalPath); }},
{"Classic (FBX)", attachParams(), [this]() { setPalette(appContext(), classicPalPath); }},
{"Wavebeam", attachParams(), [this]() { setPalette(appContext(), wavebeamPalPath); }},
{"Classic", attachParams(), [this]() { setPalette(appContext(), classicPalPath); }},
{"Lightful", attachParams(), [this]() { setPalette(appContext(), lightfulPalPath); }},
{"Custom File", attachParams(), [this](TextMenuItem &, View &, Input::Event e)
{
auto fsFilter = [](std::string_view name)
Expand All @@ -376,16 +382,14 @@ class CustomVideoOptionView : public VideoOptionView, public MainAppHelper<Custo
"Default Palette", attachParams(),
[this]()
{
if(system().defaultPalettePath.empty())
return 0;
if(system().defaultPalettePath == firebrandXPalPath)
return 1;
else if(system().defaultPalettePath == wavebeamPalPath)
return 2;
else if(system().defaultPalettePath == classicPalPath)
return 3;
else
return (int)defaultPaletteCustomFileIdx();
if(system().defaultPalettePath.empty()) return 0;
if(system().defaultPalettePath == digitalPrimePalPath) return 1;
if(system().defaultPalettePath == smoothPalPath) return 2;
if(system().defaultPalettePath == magnumPalPath) return 3;
if(system().defaultPalettePath == classicPalPath) return 4;
if(system().defaultPalettePath == wavebeamPalPath) return 5;
if(system().defaultPalettePath == lightfulPalPath) return 6;
return (int)defaultPaletteCustomFileIdx();
}(),
defaultPalItem,
{
Expand Down
27 changes: 15 additions & 12 deletions NES.emu/src/main/Main.cc
Original file line number Diff line number Diff line change
Expand Up @@ -204,21 +204,24 @@ void NesSystem::setDefaultPalette(ApplicationContext ctx, CStringView palPath)
FCEU_setDefaultPalettePtr(nullptr);
return;
}
log.info("setting default palette with path:{}", palPath);
if(palPath[0] != '/' && !isUri(palPath))
try
{
// load as asset
IO io = ctx.openAsset(FS::pathString("palette", palPath), {.accessHint = IOAccessHint::All});
if(!io)
return;
setDefaultPalette(io);
log.info("setting default palette with path:{}", palPath);
if(palPath[0] != '/' && !isUri(palPath))
{
// load as asset
IO io = ctx.openAsset(FS::pathString("palette", palPath), {.accessHint = IOAccessHint::All});
setDefaultPalette(io);
}
else
{
IO io = ctx.openFileUri(palPath, {.accessHint = IOAccessHint::All});
setDefaultPalette(io);
}
}
else
catch(...)
{
IO io = ctx.openFileUri(palPath, {.test = true, .accessHint = IOAccessHint::All});
if(!io)
return;
setDefaultPalette(io);
FCEU_setDefaultPalettePtr(nullptr);
}
}

Expand Down
3 changes: 2 additions & 1 deletion PCE.emu/src/pce/pce.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#include <mednafen/hash/md5.h>
#include <mednafen/FileStream.h>
#include <mednafen/sound/OwlResampler.h>
#include <imagine/util/string.h>

#include <zlib.h>

Expand Down Expand Up @@ -377,7 +378,7 @@ static MDFN_COLD void Load(GameFile* gf)

crc = HuC_Load(gf->stream, MDFN_GetSettingB("pce.disable_bram_hucard"));

if(gf->ext == "sgx")
if(IG::equalsCaseless(gf->ext, "sgx"))
IsSGX = true;
else
{
Expand Down
Loading

0 comments on commit f46dcda

Please sign in to comment.