Skip to content

Commit

Permalink
Update video options and misc tweaks
Browse files Browse the repository at this point in the history
* Imagine: Add Screen::setVariableFrameTime() and Window::configureFrameTimeSource() to allow changing the screen's active frame timer
* Imagine: Add -Wno-vla-extension to warning flags for Clang 18
* EmuFramework: Add "Timer" as a Frame Clock setting for use with VRR displays
* EmuFramework: Move functions for text input views out of EmuApp and into a utility header
* EmuFramework: Add a new option category "Frame Timing" and move relevant options from the "Video" category there
* EmuFramework: Change the "App Zoom" option to instead control the menu scale
* EmuFramework: Rename "Content Zoom" video option to "Content Scale"
  • Loading branch information
Robert Broglia committed Mar 30, 2024
1 parent e4b141e commit db2c4b4
Show file tree
Hide file tree
Showing 66 changed files with 1,201 additions and 1,047 deletions.
15 changes: 8 additions & 7 deletions 2600.emu/src/main/EmuMenuViews.cc
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include <emuframework/AudioOptionView.hh>
#include <emuframework/VideoOptionView.hh>
#include <emuframework/SystemActionsView.hh>
#include <emuframework/viewUtils.hh>
#undef Debugger
#include "MainApp.hh"
#include <imagine/util/format.hh>
Expand Down Expand Up @@ -63,7 +64,7 @@ class CustomAudioOptionView : public AudioOptionView, public MainAppHelper<Custo
};

public:
CustomAudioOptionView(ViewAttachParams attach): AudioOptionView{attach, true}
CustomAudioOptionView(ViewAttachParams attach, EmuAudio& audio): AudioOptionView{attach, audio, true}
{
loadStockItems();
item.emplace_back(&resampleQuality);
Expand Down Expand Up @@ -99,7 +100,7 @@ class CustomVideoOptionView : public VideoOptionView, public MainAppHelper<Custo
}

public:
CustomVideoOptionView(ViewAttachParams attach): VideoOptionView{attach, true}
CustomVideoOptionView(ViewAttachParams attach, EmuVideoLayer &layer): VideoOptionView{attach, layer, true}
{
loadStockItems();
item.emplace_back(&systemSpecificHeading);
Expand Down Expand Up @@ -257,8 +258,8 @@ class ConsoleOptionView : public TableView, public MainAppHelper<ConsoleOptionVi
{"Custom Value", attachParams(),
[this](const Input::Event &e)
{
app().pushAndShowNewCollectValueInputView<int>(attachParams(), e, "Input 1 to 20", "",
[this](EmuApp &app, auto val)
pushAndShowNewCollectValueInputView<int>(attachParams(), e, "Input 1 to 20", "",
[this](CollectTextInputView&, auto val)
{
if(system().optionPaddleDigitalSensitivity.isValid(val))
{
Expand All @@ -269,7 +270,7 @@ class ConsoleOptionView : public TableView, public MainAppHelper<ConsoleOptionVi
}
else
{
app.postErrorMessage("Value not in range");
app().postErrorMessage("Value not in range");
return false;
}
});
Expand Down Expand Up @@ -419,8 +420,8 @@ std::unique_ptr<View> EmuApp::makeCustomView(ViewAttachParams attach, ViewID id)
{
switch(id)
{
case ViewID::AUDIO_OPTIONS: return std::make_unique<CustomAudioOptionView>(attach);
case ViewID::VIDEO_OPTIONS: return std::make_unique<CustomVideoOptionView>(attach);
case ViewID::AUDIO_OPTIONS: return std::make_unique<CustomAudioOptionView>(attach, audio);
case ViewID::VIDEO_OPTIONS: return std::make_unique<CustomVideoOptionView>(attach, videoLayer);
case ViewID::SYSTEM_ACTIONS: return std::make_unique<CustomSystemActionsView>(attach);
default: return nullptr;
}
Expand Down
18 changes: 9 additions & 9 deletions C64.emu/src/main/EmuMenuViews.cc
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include <emuframework/SystemActionsView.hh>
#include <emuframework/MainMenuView.hh>
#include <emuframework/FilePicker.hh>
#include <emuframework/viewUtils.hh>
#include "MainApp.hh"
#include "VicePlugin.hh"
#include <imagine/gui/TextEntry.hh>
Expand Down Expand Up @@ -174,9 +175,9 @@ class CustomVideoOptionView : public VideoOptionView, public MainAppHelper<Custo
{
return [=, this](const Input::Event &e)
{
app().pushAndShowNewCollectValueRangeInputView<int, 0, max>(attachParams(), e,
pushAndShowNewCollectValueRangeInputView<int, 0, max>(attachParams(), e,
max == 200 ? "Input 0 to 200" : "Input 0 to 400", "",
[=, this](EmuApp &app, auto val)
[=, this](CollectTextInputView&, auto val)
{
val *= 10;
system().setColorSetting(setting, val);
Expand All @@ -197,8 +198,7 @@ class CustomVideoOptionView : public VideoOptionView, public MainAppHelper<Custo
};

public:
CustomVideoOptionView(ViewAttachParams attach):
VideoOptionView{attach, true},
CustomVideoOptionView(ViewAttachParams attach, EmuVideoLayer &layer): VideoOptionView{attach, layer, true},
paletteName{system().systemFilesWithExtension(".vpl")}
{
loadStockItems();
Expand Down Expand Up @@ -266,7 +266,7 @@ class CustomAudioOptionView : public AudioOptionView, public MainAppHelper<Custo
};

public:
CustomAudioOptionView(ViewAttachParams attach): AudioOptionView{attach, true}
CustomAudioOptionView(ViewAttachParams attach, EmuAudio& audio): AudioOptionView{attach, audio, true}
{
loadStockItems();
item.emplace_back(&sidEngine);
Expand Down Expand Up @@ -1298,7 +1298,7 @@ class CustomMainMenuView : public MainMenuView, public MainAppHelper<CustomMainM
"Start System With Blank Disk", attachParams(),
[this](TextMenuItem &item, View &, Input::Event e)
{
app().pushAndShowNewCollectTextInputView(attachParams(), e, "Input Disk Name", "",
pushAndShowNewCollectTextInputView(attachParams(), e, "Input Disk Name", "",
[this](CollectTextInputView &view, const char *str)
{
if(str)
Expand Down Expand Up @@ -1375,7 +1375,7 @@ class CustomMainMenuView : public MainMenuView, public MainAppHelper<CustomMainM
"Start System With Blank Tape", attachParams(),
[this](TextMenuItem &item, View &, Input::Event e)
{
app().pushAndShowNewCollectTextInputView(attachParams(), e, "Input Tape Name", "",
pushAndShowNewCollectTextInputView(attachParams(), e, "Input Tape Name", "",
[this](CollectTextInputView &view, const char *str)
{
if(str)
Expand Down Expand Up @@ -1470,8 +1470,8 @@ std::unique_ptr<View> EmuApp::makeCustomView(ViewAttachParams attach, ViewID id)
{
case ViewID::MAIN_MENU: return std::make_unique<CustomMainMenuView>(attach);
case ViewID::SYSTEM_ACTIONS: return std::make_unique<CustomSystemActionsView>(attach);
case ViewID::VIDEO_OPTIONS: return std::make_unique<CustomVideoOptionView>(attach);
case ViewID::AUDIO_OPTIONS: return std::make_unique<CustomAudioOptionView>(attach);
case ViewID::VIDEO_OPTIONS: return std::make_unique<CustomVideoOptionView>(attach, videoLayer);
case ViewID::AUDIO_OPTIONS: return std::make_unique<CustomAudioOptionView>(attach, audio);
case ViewID::SYSTEM_OPTIONS: return std::make_unique<CustomSystemOptionView>(attach);
case ViewID::FILE_PATH_OPTIONS: return std::make_unique<CustomFilePathOptionView>(attach);
default: return nullptr;
Expand Down
1 change: 1 addition & 0 deletions EmuFramework/build.mk
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ gui/EmuView.cc \
gui/EmuViewController.cc \
gui/FilePathOptionView.cc \
gui/FilePicker.cc \
gui/FrameTimingView.cc \
gui/GUIOptionView.cc \
gui/InputManagerView.cc \
gui/LoadProgressView.cc \
Expand Down
2 changes: 1 addition & 1 deletion EmuFramework/include/emuframework/AppKeyCode.hh
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,6 @@ constexpr InputComponentDesc rewindUIComponents{"Rewind One State", rewindUIKeys

std::string_view toString(AppKeyCode);

constexpr const char *playerNumStrings[] {"1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"};
constexpr std::array playerNumStrings{"1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"};

}
3 changes: 2 additions & 1 deletion EmuFramework/include/emuframework/AudioOptionView.hh
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,11 @@ class EmuAudio;
class AudioOptionView : public TableView, public EmuAppHelper<AudioOptionView>
{
public:
AudioOptionView(ViewAttachParams attach, bool customMenu = false);
AudioOptionView(ViewAttachParams attach, EmuAudio&, bool customMenu = false);
void loadStockItems();

protected:
EmuAudio &audio;
BoolMenuItem snd;
BoolMenuItem soundDuringFastSlowMode;
TextMenuItem soundVolumeItem[4];
Expand Down
5 changes: 3 additions & 2 deletions EmuFramework/include/emuframework/Cheats.hh
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
along with EmuFramework. If not, see <http://www.gnu.org/licenses/> */

#include <emuframework/EmuAppHelper.hh>
#include <emuframework/viewUtils.hh>
#include <imagine/gui/TableView.hh>
#include <imagine/gui/MenuItem.hh>
#include <vector>
Expand Down Expand Up @@ -73,9 +74,9 @@ public:
IG_forward(cheatName), attach,
[this](const Input::Event &e)
{
app().template pushAndShowNewCollectValueInputView<const char*>(attachParams(), e,
pushAndShowNewCollectValueInputView<const char*>(attachParams(), e,
"Input description", static_cast<CheatViewImpl*>(this)->cheatNameString(),
[this](EmuApp &, auto str)
[this](CollectTextInputView&, auto str)
{
name.compile(str);
static_cast<CheatViewImpl*>(this)->renamed(str);
Expand Down
145 changes: 6 additions & 139 deletions EmuFramework/include/emuframework/EmuApp.hh
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,6 @@
#include <emuframework/RewindManager.hh>
#include <imagine/input/inputDefs.hh>
#include <imagine/gui/ViewManager.hh>
#include <imagine/gui/TextEntry.hh>
#include <imagine/gui/MenuItem.hh>
#include <imagine/gui/ToastView.hh>
#include <imagine/fs/FSDefs.hh>
#include <imagine/base/ApplicationContext.hh>
Expand Down Expand Up @@ -107,11 +105,6 @@ struct AssetDesc
constexpr auto filename() const { return assetFilename[fileIdx()]; }
};

enum class ScanValueMode
{
NORMAL, ALLOW_BLANK
};

WISE_ENUM_CLASS((ImageChannel, uint8_t),
All,
Red,
Expand Down Expand Up @@ -182,11 +175,6 @@ public:
void reloadSystem(EmuSystemCreateParams params = {});
void onSystemCreated();
void promptSystemReloadDueToSetOption(ViewAttachParams, const Input::Event &, EmuSystemCreateParams params = {});
void pushAndShowNewCollectTextInputView(ViewAttachParams, const Input::Event &,
const char *msgText, const char *initialContent, CollectTextInputView::OnTextDelegate);
void pushAndShowNewYesNoAlertView(ViewAttachParams, const Input::Event &,
const char *label, const char *choice1, const char *choice2,
TextMenuItem::SelectDelegate onYes, TextMenuItem::SelectDelegate onNo);
void pushAndShowModalView(std::unique_ptr<View> v, const Input::Event &);
void pushAndShowModalView(std::unique_ptr<View> v);
void popModalViews();
Expand Down Expand Up @@ -219,7 +207,7 @@ public:
FS::PathString validSearchPath(const FS::PathString &) const;
static void updateLegacySavePath(IG::ApplicationContext, CStringView path);
auto screenshotDirectory() const { return system().userPath(userScreenshotPath); }
static std::unique_ptr<View> makeCustomView(ViewAttachParams attach, ViewID id);
std::unique_ptr<View> makeCustomView(ViewAttachParams attach, ViewID id);
bool handleKeyInput(KeyInfo, const Input::Event &srcEvent);
bool handleAppActionKeyInput(InputAction, const Input::Event &srcEvent);
void handleSystemKeyInput(KeyInfo, Input::Action, uint32_t metaState = 0, SystemKeyInputFlags flags = {});
Expand All @@ -244,7 +232,7 @@ public:
Gfx::TextureSpan asset(AssetID) const;
Gfx::TextureSpan asset(AssetDesc) const;
VController &defaultVController() { return inputManager.vController; }
static std::unique_ptr<View> makeView(ViewAttachParams, ViewID);
std::unique_ptr<View> makeView(ViewAttachParams, ViewID);
std::unique_ptr<YesNoAlertView> makeCloseContentView();
void applyOSNavStyle(IG::ApplicationContext, bool inEmu);
void setCPUNeedsLowLatency(IG::ApplicationContext, bool needed);
Expand Down Expand Up @@ -290,8 +278,8 @@ public:
float videoAspectRatio() const;
float defaultVideoAspectRatio() const;
IG::PixelFormat videoEffectPixelFormat() const;
bool setVideoZoom(uint8_t val);
bool setViewportZoom(uint8_t val);
bool setContentScale(uint8_t val);
bool setMenuScale(int8_t val);
bool supportsShowOnSecondScreen(ApplicationContext ctx) { return ctx.androidSDK() >= 17; }
void setContentRotation(IG::Rotation);
void updateVideoContentRotation();
Expand Down Expand Up @@ -361,132 +349,11 @@ public:
postMessage(secs, true, IG_forward(msg));
}

template <std::same_as<const char*> T>
static std::pair<T, int> scanValue(const char *str, ScanValueMode mode)
{
return {str, mode == ScanValueMode::ALLOW_BLANK || strlen(str) ? 1 : 0};
}

template <std::integral T>
static std::pair<T, int> scanValue(const char *str, ScanValueMode)
{
int val;
int items = sscanf(str, "%d", &val);
return {val, items};
}

template <std::floating_point T>
static std::pair<T, int> scanValue(const char *str, ScanValueMode)
{
T val, denom;
int items = sscanf(str, std::is_same_v<T, double> ? "%lf /%lf" : "%f /%f", &val, &denom);
if(items > 1 && denom != 0)
{
val /= denom;
}
return {val, items};
}

template <class T>
requires std::same_as<T, std::pair<float, float>> || std::same_as<T, std::pair<double, double>>
static std::pair<T, int> scanValue(const char *str, ScanValueMode)
{
// special case for getting a fraction
using PairValue = typename T::first_type;
PairValue val, denom{};
int items = sscanf(str, std::is_same_v<PairValue, double> ? "%lf /%lf" : "%f /%f", &val, &denom);
if(denom == 0)
{
denom = 1.;
}
return {{val, denom}, items};
}

template <class T>
requires std::same_as<T, std::pair<int, int>>
static std::pair<T, int> scanValue(const char *str, ScanValueMode)
{
using PairValue = typename T::first_type;
PairValue val, val2{};
int items = sscanf(str, "%d %d", &val, &val2);
return {{val, val2}, items};
}

template<class T, ScanValueMode mode = ScanValueMode::NORMAL>
void pushAndShowNewCollectValueInputView(ViewAttachParams attach, const Input::Event &e,
CStringView msgText, CStringView initialContent, IG::Callable<bool, EmuApp&, T> auto &&collectedValueFunc)
{
pushAndShowNewCollectTextInputView(attach, e, msgText, initialContent,
[collectedValueFunc](CollectTextInputView &view, const char *str)
{
if(!str)
{
view.dismiss();
return false;
}
auto &app = get(view.appContext());
auto [val, items] = scanValue<T>(str, mode);
if(items <= 0)
{
app.postErrorMessage("Enter a value");
return true;
}
else if(!collectedValueFunc(app, val))
{
return true;
}
else
{
view.dismiss();
return false;
}
});
}

template<class T, T low, T high>
void pushAndShowNewCollectValueRangeInputView(ViewAttachParams attach, const Input::Event &e,
CStringView msgText, CStringView initialContent, IG::Callable<bool, EmuApp&, T> auto &&collectedValueFunc)
{
pushAndShowNewCollectValueInputView<T>(attach, e, msgText, initialContent,
[collectedValueFunc](EmuApp &app, auto val)
{
if(val >= low && val <= high)
{
return collectedValueFunc(app, val);
}
else
{
app.postErrorMessage("Value not in range");
return false;
}
});
}

template<class T, T low, T high, T low2, T high2>
void pushAndShowNewCollectValuePairRangeInputView(ViewAttachParams attach, const Input::Event &e,
CStringView msgText, CStringView initialContent, Callable<bool, EmuApp&, std::pair<T, T>> auto &&collectedValueFunc)
{
pushAndShowNewCollectValueInputView<std::pair<T, T>>(attach, e, msgText, initialContent,
[collectedValueFunc](EmuApp &app, auto val)
{
if(val.first >= low && val.first <= high && val.second >= low2 && val.second <= high2)
{
return collectedValueFunc(app, val);
}
else
{
app.postErrorMessage("Values not in range");
return false;
}
});
}

protected:
IG::FontManager fontManager;
mutable Gfx::Renderer renderer;
ViewManager viewManager;
public:
IG::Audio::Manager audioManager;
EmuAudio audio;
EmuVideo video;
EmuVideoLayer videoLayer;
Expand Down Expand Up @@ -542,8 +409,8 @@ public:
PropertyDesc<bool>{.defaultValue = true, .mutableDefault = true}> showsBluetoothScan;
Property<PixelFormatID, CFGKEY_IMAGE_EFFECT_PIXEL_FORMAT,
PropertyDesc<PixelFormatID>{.defaultValue = PIXEL_NONE, .isValid = imageEffectPixelFormatIsValid}> imageEffectPixelFormat;
Property<int8_t, CFGKEY_VIEWPORT_ZOOM, PropertyDesc<int8_t>{.defaultValue = 100, .isValid = optionViewportZoomIsValid}> viewportZoom;
Property<uint8_t, CFGKEY_IMAGE_ZOOM, PropertyDesc<uint8_t>{.defaultValue = 100, .isValid = optionImageZoomIsValid}> imageZoom;
Property<int8_t, CFGKEY_MENU_SCALE, PropertyDesc<int8_t>{.defaultValue = 100, .isValid = optionMenuScaleIsValid}> menuScale;
Property<uint8_t, CFGKEY_CONTENT_SCALE, PropertyDesc<uint8_t>{.defaultValue = 100, .isValid = optionContentScaleIsValid}> contentScale;
ConditionalProperty<Config::BASE_MULTI_WINDOW && Config::BASE_MULTI_SCREEN, bool, CFGKEY_SHOW_ON_2ND_SCREEN> showOnSecondScreen;
Property<Gfx::TextureBufferMode, CFGKEY_TEXTURE_BUFFER_MODE> textureBufferMode;
Property<Rotation, CFGKEY_CONTENT_ROTATION,
Expand Down
Loading

0 comments on commit db2c4b4

Please sign in to comment.