mirror of
https://github.com/0ldsk00l/nestopia.git
synced 2024-06-22 06:02:26 -04:00
Compare commits
12 commits
c5a4b21e61
...
fc8bcee4b1
Author | SHA1 | Date | |
---|---|---|---|
fc8bcee4b1 | |||
59cc0e8745 | |||
a316c9b419 | |||
6cb6f72fde | |||
f93d65f8c5 | |||
d10be2127e | |||
fc3b152ba8 | |||
d36caf23ec | |||
cade634a7c | |||
ffa2faf241 | |||
ac1e1995f1 | |||
e39fb91988 |
|
@ -721,16 +721,14 @@ nestopia_SOURCES += \
|
|||
source/fltkui/audiomanager.h \
|
||||
source/fltkui/chtmanager.cpp \
|
||||
source/fltkui/chtmanager.h \
|
||||
source/fltkui/cli.cpp \
|
||||
source/fltkui/cli.h \
|
||||
source/fltkui/ini.h \
|
||||
source/fltkui/inputmanager.cpp \
|
||||
source/fltkui/inputmanager.h \
|
||||
source/fltkui/font.h \
|
||||
source/fltkui/lodepng.cpp \
|
||||
source/fltkui/lodepng.h \
|
||||
source/fltkui/logdriver.cpp \
|
||||
source/fltkui/logdriver.h \
|
||||
source/fltkui/png.cpp \
|
||||
source/fltkui/png.h \
|
||||
source/fltkui/jgmanager.cpp \
|
||||
source/fltkui/jgmanager.h \
|
||||
source/fltkui/setmanager.cpp \
|
||||
|
|
|
@ -1,168 +0,0 @@
|
|||
/*
|
||||
* Nestopia UE
|
||||
*
|
||||
* Copyright (C) 2012-2016 R. Danbrook
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <getopt.h>
|
||||
|
||||
#include "cli.h"
|
||||
|
||||
void cli_error(const char *message) {
|
||||
cli_show_usage();
|
||||
fprintf(stderr, "%s\n", message);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
void cli_show_usage() {
|
||||
printf("Usage: nestopia [options] [FILE]\n");
|
||||
printf("\nOptions:\n");
|
||||
printf(" -f, --fullscreen Fullscreen mode\n");
|
||||
printf(" -w, --window Window mode\n\n");
|
||||
printf(" -l, --filter Video Filter\n");
|
||||
printf(" (0=None, 1=NTSC, 2=xBR, 3=HqX, 4=2xSaI, 5=ScaleX)\n\n");
|
||||
printf(" -m, --maskoverscan Mask overscan areas\n");
|
||||
printf(" -n, --no-maskoverscan Disable overscan masking\n\n");
|
||||
printf(" -o, --stretchfs Stretch to native resolution in fullscreen mode\n");
|
||||
printf(" -p, --preserveaspect Preserve aspect ratio in fullscreen mode\n\n");
|
||||
printf(" -s, --scalefactor Video scale factor (1-4)\n\n");
|
||||
printf(" -t, --tvaspect TV aspect ratio\n");
|
||||
printf(" -r, --no-tvaspect Regular aspect ratio\n\n");
|
||||
printf(" -u, --unlimitedsprites Remove sprite limit\n");
|
||||
printf(" -q, --spritelimit Enable sprite limit\n\n");
|
||||
printf(" -v, --version Show version information\n\n");
|
||||
printf("More options can be set in the configuration file.\n");
|
||||
printf("Options are saved, and do not need to be set on future invocations.\n\n");
|
||||
}
|
||||
|
||||
void cli_show_version() {
|
||||
printf("Nestopia UE 1.52.1\n");
|
||||
}
|
||||
|
||||
void cli_handle_command(int argc, char *argv[]) {
|
||||
int c;
|
||||
int optint;
|
||||
|
||||
while (1) {
|
||||
static struct option long_options[] = {
|
||||
{"disablegui", no_argument, 0, 'd'},
|
||||
{"enablegui", no_argument, 0, 'e'},
|
||||
{"fullscreen", no_argument, 0, 'f'},
|
||||
{"window", no_argument, 0, 'w'},
|
||||
{"help", no_argument, 0, 'h'},
|
||||
{"filter", required_argument, 0, 'l'},
|
||||
{"maskoverscan", no_argument, 0, 'm'},
|
||||
{"no-maskoverscan", no_argument, 0, 'n'},
|
||||
{"stretchfs", no_argument, 0, 'o'},
|
||||
{"preserveaspect", no_argument, 0, 'p'},
|
||||
{"scalefactor", required_argument, 0, 's'},
|
||||
{"tvaspect", no_argument, 0, 't'},
|
||||
{"no-tvaspect", no_argument, 0, 'r'},
|
||||
{"unlimitedsprites", no_argument, 0, 'u'},
|
||||
{"spritelimit", no_argument, 0, 'q'},
|
||||
{"version", no_argument, 0, 'v'},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
int option_index = 0;
|
||||
|
||||
c = getopt_long(argc, argv, "defhl:mnopqrs:tuvw",
|
||||
long_options, &option_index);
|
||||
|
||||
if (c == -1) { break; }
|
||||
|
||||
switch(c) {
|
||||
case 'f':
|
||||
//conf.video_fullscreen = true;
|
||||
break;
|
||||
|
||||
case 'w':
|
||||
//conf.video_fullscreen = false;
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
cli_show_usage();
|
||||
exit(0);
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
optint = atoi(optarg);
|
||||
if (optint < 6) {
|
||||
//conf.video_filter = optint;
|
||||
}
|
||||
else {
|
||||
cli_error("Error: Invalid filter");
|
||||
}
|
||||
break;
|
||||
|
||||
case 'm':
|
||||
//conf.video_unmask_overscan = false;
|
||||
break;
|
||||
|
||||
case 'n':
|
||||
//conf.video_unmask_overscan = true;
|
||||
break;
|
||||
|
||||
case 'o':
|
||||
//conf.video_stretch_aspect = true;
|
||||
break;
|
||||
|
||||
case 'p':
|
||||
//conf.video_stretch_aspect = false;
|
||||
break;
|
||||
|
||||
case 's':
|
||||
optint = atoi(optarg);
|
||||
if (optint < 5 && optint != 0) {
|
||||
//conf.video_scale_factor = optint;
|
||||
}
|
||||
else {
|
||||
cli_error("Error: Invalid scale factor");
|
||||
}
|
||||
break;
|
||||
|
||||
case 't':
|
||||
//conf.video_tv_aspect = true;
|
||||
break;
|
||||
|
||||
case 'r':
|
||||
//conf.video_tv_aspect = false;
|
||||
break;
|
||||
|
||||
case 'u':
|
||||
//conf.video_unlimited_sprites = true;
|
||||
break;
|
||||
|
||||
case 'q':
|
||||
//conf.video_unlimited_sprites = false;
|
||||
break;
|
||||
|
||||
case 'v':
|
||||
cli_show_version();
|
||||
exit(0);
|
||||
break;
|
||||
|
||||
default:
|
||||
cli_error("Error: Invalid option");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +0,0 @@
|
|||
void cli_error(const char *message);
|
||||
void cli_show_usage();
|
||||
void cli_show_version();
|
||||
void cli_handle_command(int argc, char *argv[]);
|
|
@ -21,7 +21,7 @@
|
|||
*/
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstdio>
|
||||
#include <chrono>
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
|
@ -100,10 +100,7 @@ Fl_Menu_Item menutable[] = {
|
|||
{"Slot 4", 0, FltkUi::state_qsave, (void*)"4", FL_MENU_INACTIVE},
|
||||
{0},
|
||||
{"Open Palette...", 0, FltkUi::palette_open, 0, FL_MENU_DIVIDER},
|
||||
//{"Screenshot...", 0, fltkui_screenshot, 0, FL_MENU_DIVIDER|FL_MENU_INACTIVE},
|
||||
/*{"Load Movie...", 0, fltkui_movie_load, 0, FL_MENU_INACTIVE},
|
||||
{"Record Movie...", 0, fltkui_movie_save, 0, FL_MENU_INACTIVE},
|
||||
{"Stop Movie", 0, fltkui_movie_stop, 0, FL_MENU_DIVIDER|FL_MENU_INACTIVE},*/
|
||||
{"Screenshot...", 0, FltkUi::screenshot_save, 0, FL_MENU_DIVIDER|FL_MENU_INACTIVE},
|
||||
{"&Quit", FL_ALT + 'q', FltkUi::quit, 0, 0},
|
||||
{0}, // End File
|
||||
{"&Emulator", FL_ALT + 'e', 0, 0, FL_SUBMENU},
|
||||
|
@ -122,6 +119,17 @@ Fl_Menu_Item menutable[] = {
|
|||
{0} // End Menu
|
||||
};
|
||||
|
||||
Fl_Menu_Item *get_menuitem(std::string label) {
|
||||
Fl_Menu_Item *m = menutable->first();
|
||||
for (int i = 0; i < menutable->size(); ++i) {
|
||||
if (m->label() != nullptr && std::string(m->label()) == label) {
|
||||
return m;
|
||||
}
|
||||
++m;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int get_refreshrate(void) {
|
||||
// Get the screen refresh rate using an SDL window
|
||||
int refresh = 60;
|
||||
|
@ -222,55 +230,39 @@ void FltkUi::rom_open(Fl_Widget *w, void *data) {
|
|||
}
|
||||
}
|
||||
|
||||
/*static void fltkui_movie_load(Fl_Widget* w, void* userdata) {
|
||||
// Create native chooser
|
||||
if (!jgm->is_loaded()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Fl_Native_File_Chooser fc;
|
||||
fc.title("Select a Movie");
|
||||
fc.type(Fl_Native_File_Chooser::BROWSE_FILE);
|
||||
//fc.directory((const char*)nstpaths.nstdir);
|
||||
fc.filter("Nestopia Movies\t*.nsv");
|
||||
|
||||
// Show file chooser
|
||||
switch (fc.show()) {
|
||||
case -1:
|
||||
LogDriver::log(LogLevel::Error, std::string(fc.errmsg()));
|
||||
break;
|
||||
case 1: break; // Cancel
|
||||
default:
|
||||
if (fc.filename()) {
|
||||
//nst_movie_load(fc.filename());
|
||||
}
|
||||
break;
|
||||
void FltkUi::screenshot(std::string filename) {
|
||||
if (filename.empty()) {
|
||||
auto now = std::chrono::system_clock::now();
|
||||
auto epoch = std::chrono::system_clock::from_time_t(0);
|
||||
auto duration = std::chrono::duration_cast<std::chrono::milliseconds>
|
||||
(now.time_since_epoch()).count();
|
||||
std::string msecs = std::to_string(duration);
|
||||
filename = jgm->get_basepath() + "/screenshots/" + msecs + ".png";
|
||||
}
|
||||
videomgr->screenshot(filename);
|
||||
LogDriver::log(LogLevel::OSD, "Screenshot Saved");
|
||||
}
|
||||
|
||||
static void fltkui_movie_save(Fl_Widget* w, void* userdata) {
|
||||
void FltkUi::screenshot_save(Fl_Widget *w, void *data) {
|
||||
// Create native chooser
|
||||
if (!jgm->is_loaded()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Fl_Native_File_Chooser fc;
|
||||
fc.title("Save Movie");
|
||||
fc.title("Save Screenshot");
|
||||
fc.type(Fl_Native_File_Chooser::BROWSE_SAVE_FILE);
|
||||
//fc.directory((const char*)nstpaths.nstdir);
|
||||
fc.filter("Nestopia Moviess\t*.nsv");
|
||||
fc.filter("Screenshots\t*.png");
|
||||
fc.options(Fl_Native_File_Chooser::SAVEAS_CONFIRM | Fl_Native_File_Chooser::USE_FILTER_EXT);
|
||||
|
||||
// Show file chooser
|
||||
if (fc.show()) { return; }
|
||||
if (fc.show()) {
|
||||
return;
|
||||
}
|
||||
|
||||
//nst_movie_save(fc.filename());
|
||||
screenshot(fc.filename());
|
||||
}
|
||||
|
||||
static void fltkui_movie_stop(Fl_Widget* w, void* userdata) {
|
||||
//nst_movie_stop();
|
||||
}*/
|
||||
|
||||
void FltkUi::state_load(Fl_Widget *w, void *userdata) {
|
||||
// Create native chooser
|
||||
if (!jgm->is_loaded()) {
|
||||
|
@ -319,26 +311,6 @@ void FltkUi::state_save(Fl_Widget *w, void *data) {
|
|||
jgm->state_save(statefile);
|
||||
}
|
||||
|
||||
/*static void fltkui_screenshot(Fl_Widget* w, void* userdata) {
|
||||
// Create native chooser
|
||||
if (!jgm->is_loaded()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Fl_Native_File_Chooser fc;
|
||||
fc.title("Save Screenshot");
|
||||
fc.type(Fl_Native_File_Chooser::BROWSE_SAVE_FILE);
|
||||
fc.filter("PNG Screenshots\t*.png");
|
||||
fc.options(Fl_Native_File_Chooser::SAVEAS_CONFIRM | Fl_Native_File_Chooser::USE_FILTER_EXT);
|
||||
|
||||
// Show file chooser
|
||||
if (fc.show()) {
|
||||
return;
|
||||
}
|
||||
|
||||
//video_screenshot(fc.filename());
|
||||
}*/
|
||||
|
||||
void FltkUi::palette_open(Fl_Widget *w, void *data) {
|
||||
// Create native chooser
|
||||
Fl_Native_File_Chooser fc;
|
||||
|
@ -379,17 +351,26 @@ void FltkUi::state_qsave(Fl_Widget *w, void *data) {
|
|||
}
|
||||
|
||||
void FltkUi::pause(Fl_Widget *w, void *data) {
|
||||
Fl_Menu_Item* m = nullptr;
|
||||
|
||||
m = w ? const_cast<Fl_Menu_Item*>(((Fl_Menu_Bar*)w)->mvalue()) :
|
||||
get_menuitem(paused ? "Play" : "Pause");
|
||||
|
||||
if (m == nullptr) {
|
||||
LogDriver::log(LogLevel::Warn, "Menu item does not exist");
|
||||
return;
|
||||
}
|
||||
|
||||
paused ^= 1;
|
||||
|
||||
if (paused) {
|
||||
audiomgr->pause();
|
||||
Fl_Menu_Item* m = const_cast<Fl_Menu_Item*>(((Fl_Menu_Bar*)w)->mvalue());
|
||||
m->label("Play");
|
||||
}
|
||||
else {
|
||||
audiomgr->unpause();
|
||||
Fl_Menu_Item* m = const_cast<Fl_Menu_Item*>(((Fl_Menu_Bar*)w)->mvalue());
|
||||
m->label("Pause");
|
||||
}
|
||||
|
||||
m->label(paused ? "Play" : "Pause");
|
||||
}
|
||||
|
||||
void FltkUi::reset(Fl_Widget *w, void *data) {
|
||||
|
@ -414,6 +395,7 @@ void NstGlArea::resize(int x, int y, int w, int h) {
|
|||
}
|
||||
|
||||
void FltkUi::rehash() {
|
||||
LogDriver::set_level(setmgr->get_setting("l_loglevel")->val);
|
||||
videomgr->rehash(true);
|
||||
audiomgr->rehash();
|
||||
}
|
||||
|
@ -597,7 +579,7 @@ void FltkUi::nstwin_open(const char *name) {
|
|||
chtwin->populate();
|
||||
|
||||
// Settings Window
|
||||
setwin = new NstSettingsWindow(500, 500, "Settings", *jgm, *setmgr, *inputmgr);
|
||||
setwin = new NstSettingsWindow(500, 550, "Settings", *jgm, *setmgr, *inputmgr);
|
||||
|
||||
// Main Window
|
||||
nstwin = new NstWindow(rw, rh + UI_MBARHEIGHT, name);
|
||||
|
@ -631,6 +613,19 @@ void FltkUi::set_ffspeed(bool on) {
|
|||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
// Parse command line arguments
|
||||
std::string filename{};
|
||||
std::vector<std::string> flags{};
|
||||
for (int i = 1; i < argc; ++i) {
|
||||
if (filename.empty() && argv[i][0] != '-') {
|
||||
// The first non-flag argument is considered the filename
|
||||
filename = std::string{argv[i]};
|
||||
}
|
||||
else if (argv[i][0] == '-') {
|
||||
flags.push_back(std::string{argv[i]});
|
||||
}
|
||||
}
|
||||
|
||||
// Set default config options
|
||||
setmgr = new SettingManager();
|
||||
|
||||
|
@ -646,6 +641,7 @@ int main(int argc, char *argv[]) {
|
|||
|
||||
// Read frontend and emulator settings
|
||||
setmgr->read(*jgm);
|
||||
LogDriver::set_level(setmgr->get_setting("l_loglevel")->val);
|
||||
|
||||
// Bring up Audio/Video managers
|
||||
audiomgr = new AudioManager(*jgm, *setmgr);
|
||||
|
@ -655,17 +651,17 @@ int main(int argc, char *argv[]) {
|
|||
chtmgr = new CheatManager(*jgm);
|
||||
|
||||
// Load a rom from the command line
|
||||
if (argc > 1 && argv[argc - 1][0] != '-') {
|
||||
FltkUi::load_file(argv[argc - 1]);
|
||||
if (!filename.empty()) {
|
||||
FltkUi::load_file(filename.c_str());
|
||||
if (jgm->is_loaded()) {
|
||||
jg_setup_audio();
|
||||
jg_setup_video();
|
||||
inputmgr->reassign();
|
||||
video_fullscreen = setmgr->get_setting("v_fullscreen")->val ||
|
||||
std::find(flags.begin(), flags.end(), "-f") != flags.end() ||
|
||||
std::find(flags.begin(), flags.end(), "--fullscreen") != flags.end();
|
||||
}
|
||||
}
|
||||
else if (video_fullscreen) {
|
||||
video_fullscreen = 0;
|
||||
}
|
||||
|
||||
FltkUi::nstwin_open(argv[0]);
|
||||
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
constexpr Fl_Color NstGreen = 0x255f6500;
|
||||
constexpr Fl_Color NstPurple = 0x5f578700;
|
||||
constexpr Fl_Color NstRed = 0xb51e2c00;
|
||||
|
@ -47,6 +49,8 @@ public:
|
|||
static void about(Fl_Widget *w = nullptr, void *data = nullptr);
|
||||
static void about_close(Fl_Widget *w = nullptr, void *data = nullptr);
|
||||
static void rom_open(Fl_Widget *w = nullptr, void *data = nullptr);
|
||||
static void screenshot(std::string filename = "");
|
||||
static void screenshot_save(Fl_Widget *w = nullptr, void *data = nullptr);
|
||||
static void load_file(const char *filename);
|
||||
static void fds_next(Fl_Widget *w = nullptr, void *data = nullptr);
|
||||
static void fds_insert(Fl_Widget *w = nullptr, void *data = nullptr);
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include <cstring>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <unordered_map>
|
||||
|
||||
#include <FL/Fl.H>
|
||||
#include <FL/Fl_Double_Window.H>
|
||||
|
@ -43,9 +44,91 @@
|
|||
|
||||
namespace {
|
||||
|
||||
constexpr int UI_TABHEIGHT = 450;
|
||||
constexpr int UI_TABHEIGHT = 500;
|
||||
constexpr int UI_TABWIDTH = 480;
|
||||
constexpr unsigned UI_SETTINGS_PER_COL = 8;
|
||||
constexpr unsigned UI_SETTINGS_PER_COL = 9;
|
||||
|
||||
std::unordered_map<int, std::string> keycodes = { //FL_Button ??
|
||||
{ ' ', "Space" },
|
||||
{ FL_BackSpace, "Backspace" },
|
||||
{ FL_Tab, "Tab" },
|
||||
{ FL_Iso_Key,"ISO Key" },
|
||||
{ FL_Enter, "Enter" },
|
||||
{ FL_Pause, "Pause" },
|
||||
{ FL_Scroll_Lock, "Scroll Lock"},
|
||||
{ FL_Escape, "Escape" },
|
||||
{ FL_Kana, "Kana" },
|
||||
{ FL_Eisu, "Eisu" },
|
||||
{ FL_Yen, "Yen" },
|
||||
{ FL_JIS_Underscore, "Underscore" },
|
||||
{ FL_Home, "Home" },
|
||||
{ FL_Left, "Left" },
|
||||
{ FL_Up, "Up" },
|
||||
{ FL_Right, "Right" },
|
||||
{ FL_Down, "Down" },
|
||||
{ FL_Page_Up, "Page Up" },
|
||||
{ FL_Page_Down, "Page Down" },
|
||||
{ FL_End, "End" },
|
||||
{ FL_Print, "Print" },
|
||||
{ FL_Insert, "Insert" },
|
||||
{ FL_Menu, "Menu" },
|
||||
{ FL_Help, "Help" },
|
||||
{ FL_Num_Lock, "Num Lock" },
|
||||
{ FL_KP + 0x2a, "KP *" },
|
||||
{ FL_KP + 0x2b, "KP +" },
|
||||
{ FL_KP + 0x2d, "KP -" },
|
||||
{ FL_KP + 0x2f, "KP /" },
|
||||
{ FL_KP + 0x30, "KP 0" },
|
||||
{ FL_KP + 0x31, "KP 1" },
|
||||
{ FL_KP + 0x32, "KP 2" },
|
||||
{ FL_KP + 0x33, "KP 3" },
|
||||
{ FL_KP + 0x34, "KP 4" },
|
||||
{ FL_KP + 0x35, "KP 5" },
|
||||
{ FL_KP + 0x36, "KP 6" },
|
||||
{ FL_KP + 0x37, "KP 7" },
|
||||
{ FL_KP + 0x38, "KP 8" },
|
||||
{ FL_KP + 0x39, "KP 9" },
|
||||
{ FL_KP_Enter, "KP Enter"},
|
||||
{ FL_F + 1, "F1" },
|
||||
{ FL_F + 2, "F2" },
|
||||
{ FL_F + 3, "F3" },
|
||||
{ FL_F + 4, "F4" },
|
||||
{ FL_F + 5, "F5" },
|
||||
{ FL_F + 6, "F6" },
|
||||
{ FL_F + 7, "F7" },
|
||||
{ FL_F + 8, "F8" },
|
||||
{ FL_F + 9, "F9" },
|
||||
{ FL_F + 10, "F10" },
|
||||
{ FL_F + 11, "F11" },
|
||||
{ FL_F + 12, "F12" },
|
||||
{ FL_Shift_L, "Shift L" },
|
||||
{ FL_Shift_R, "Shift R" },
|
||||
{ FL_Control_L, "Control L" },
|
||||
{ FL_Control_R, "Control R" },
|
||||
{ FL_Caps_Lock, "Caps Lock" },
|
||||
{ FL_Meta_L, "Meta L" },
|
||||
{ FL_Meta_R, "Meta R" },
|
||||
{ FL_Alt_L, "Alt L" },
|
||||
{ FL_Alt_R, "Alt R" },
|
||||
{ FL_Delete, "Delete" },
|
||||
//{ FL_Alt_Gr, "Alt Gr" },
|
||||
{ FL_Volume_Down, "Volume Down" },
|
||||
{ FL_Volume_Mute, "Volume Mute" },
|
||||
{ FL_Volume_Up, "Volume Up" },
|
||||
{ FL_Media_Play, "Play" },
|
||||
{ FL_Media_Stop," Stop" },
|
||||
{ FL_Media_Prev, "Prev" },
|
||||
{ FL_Media_Next, "Next" },
|
||||
{ FL_Home_Page, "Home Page" },
|
||||
{ FL_Mail, "Mail" },
|
||||
{ FL_Search, "Search" },
|
||||
{ FL_Back, "Back" },
|
||||
{ FL_Forward, "Forward" },
|
||||
{ FL_Stop, "Stop" },
|
||||
{ FL_Refresh, "Refresh" },
|
||||
{ FL_Sleep, "Sleep" },
|
||||
{ FL_Favorites, "Favorites" }
|
||||
};
|
||||
|
||||
NstSettingsWindow *win = nullptr;
|
||||
|
||||
|
@ -299,7 +382,7 @@ void NstSettingsWindow::populate_input() {
|
|||
iselect->align(FL_ALIGN_TOP_LEFT);
|
||||
|
||||
itable = new InputTable(inputmgr, input_info,
|
||||
200, 110, 275, 280);
|
||||
200, 110, 275, 330);
|
||||
itable->set_devicenum(0);
|
||||
itable->cols(3);
|
||||
itable->col_width(0, 115);
|
||||
|
@ -319,7 +402,7 @@ void NstSettingsWindow::populate_input() {
|
|||
iselect->value(0);
|
||||
itable->rows(input_info[0].numaxes + input_info[0].numbuttons);
|
||||
|
||||
msgbox = new Fl_Box(200, 400, 240, UI_ELEMHEIGHT);
|
||||
msgbox = new Fl_Box(200, 450, 240, UI_ELEMHEIGHT);
|
||||
msgbox->label("Press the desired key, ESC to clear");
|
||||
msgbox->hide();
|
||||
}
|
||||
|
@ -341,7 +424,18 @@ void InputTable::draw_cell(TableContext context, int r, int c, int x, int y, int
|
|||
text = defname;
|
||||
}
|
||||
else if (c == 1) {
|
||||
text = inputmgr.get_inputdef(input_info[devicenum].name, defname).c_str();
|
||||
std::string key = inputmgr.get_inputdef(input_info[devicenum].name, defname);
|
||||
int keynum = key.empty() ? 0 : std::stoi(key);
|
||||
if (keycodes.count(keynum)) {
|
||||
text = keycodes[keynum].c_str();
|
||||
}
|
||||
else if (keynum >= 33 && keynum <= 126) {
|
||||
std::string str = std::string(1, keynum);
|
||||
text = str.c_str();
|
||||
}
|
||||
else {
|
||||
text = key.c_str();
|
||||
}
|
||||
}
|
||||
else if (c == 2) {
|
||||
text = inputmgr.get_inputdef(std::string(input_info[devicenum].name) + "j", defname).c_str();
|
||||
|
|
|
@ -124,7 +124,7 @@ void InputManager::assign() {
|
|||
}
|
||||
|
||||
// Set up UI definitiions
|
||||
int ui_defaults[NDEFS_UI] = {
|
||||
int ui_defaults[NDEFS_UI - 1] = {
|
||||
0xffbd + 1, 0xffbd + 2, 0xffbd + 3, 0xffbd + 4, 0xffbd + 5,
|
||||
0xffbd + 6, 0xffbd + 7, 0xffbd + 8, 'f', 'p', '`', 0xffbd + 9
|
||||
};
|
||||
|
@ -142,6 +142,12 @@ void InputManager::assign() {
|
|||
}
|
||||
}
|
||||
|
||||
// If "Quit" was defined, apply the definition
|
||||
std::string val = setmgr.get_input("ui", uiinfo.defs[NDEFS_UI - 1]);
|
||||
if (!val.empty()) {
|
||||
kbmap[std::stoi(val)] = &uistate.button[NDEFS_UI - 1];
|
||||
}
|
||||
|
||||
remap_js();
|
||||
}
|
||||
|
||||
|
|
|
@ -115,8 +115,9 @@ void JGManager::set_paths() {
|
|||
// Create the save path, which includes creating the base path
|
||||
std::filesystem::create_directories(savepath);
|
||||
|
||||
// Create a path for states (Not part of the JG API)
|
||||
// Create paths for states and screenshots (Not part of the JG API)
|
||||
std::filesystem::create_directories(basepath + "/state");
|
||||
std::filesystem::create_directories(basepath + "/screenshots");
|
||||
|
||||
// If the binary is run from the source directory, core asset path is PWD
|
||||
if (std::filesystem::exists(std::filesystem::path{"NstDatabase.xml"})) {
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
LodePNG version 20210627
|
||||
LodePNG version 20230410
|
||||
|
||||
Copyright (c) 2005-2021 Lode Vandevenne
|
||||
Copyright (c) 2005-2023 Lode Vandevenne
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
@ -35,43 +35,50 @@ The following #defines are used to create code sections. They can be disabled
|
|||
to disable code sections, which can give faster compile time and smaller binary.
|
||||
The "NO_COMPILE" defines are designed to be used to pass as defines to the
|
||||
compiler command to disable them without modifying this header, e.g.
|
||||
-DLODEPNG_NO_COMPILE_ZLIB for gcc.
|
||||
In addition to those below, you can also define LODEPNG_NO_COMPILE_CRC to
|
||||
allow implementing a custom lodepng_crc32.
|
||||
-DLODEPNG_NO_COMPILE_ZLIB for gcc or clang.
|
||||
*/
|
||||
/*deflate & zlib. If disabled, you must specify alternative zlib functions in
|
||||
the custom_zlib field of the compress and decompress settings*/
|
||||
#ifndef LODEPNG_NO_COMPILE_ZLIB
|
||||
/*pass -DLODEPNG_NO_COMPILE_ZLIB to the compiler to disable this, or comment out LODEPNG_COMPILE_ZLIB below*/
|
||||
#define LODEPNG_COMPILE_ZLIB
|
||||
#endif
|
||||
|
||||
/*png encoder and png decoder*/
|
||||
#ifndef LODEPNG_NO_COMPILE_PNG
|
||||
/*pass -DLODEPNG_NO_COMPILE_PNG to the compiler to disable this, or comment out LODEPNG_COMPILE_PNG below*/
|
||||
#define LODEPNG_COMPILE_PNG
|
||||
#endif
|
||||
|
||||
/*deflate&zlib decoder and png decoder*/
|
||||
#ifndef LODEPNG_NO_COMPILE_DECODER
|
||||
/*pass -DLODEPNG_NO_COMPILE_DECODER to the compiler to disable this, or comment out LODEPNG_COMPILE_DECODER below*/
|
||||
#define LODEPNG_COMPILE_DECODER
|
||||
#endif
|
||||
|
||||
/*deflate&zlib encoder and png encoder*/
|
||||
#ifndef LODEPNG_NO_COMPILE_ENCODER
|
||||
/*pass -DLODEPNG_NO_COMPILE_ENCODER to the compiler to disable this, or comment out LODEPNG_COMPILE_ENCODER below*/
|
||||
#define LODEPNG_COMPILE_ENCODER
|
||||
#endif
|
||||
|
||||
/*the optional built in harddisk file loading and saving functions*/
|
||||
#ifndef LODEPNG_NO_COMPILE_DISK
|
||||
/*pass -DLODEPNG_NO_COMPILE_DISK to the compiler to disable this, or comment out LODEPNG_COMPILE_DISK below*/
|
||||
#define LODEPNG_COMPILE_DISK
|
||||
#endif
|
||||
|
||||
/*support for chunks other than IHDR, IDAT, PLTE, tRNS, IEND: ancillary and unknown chunks*/
|
||||
#ifndef LODEPNG_NO_COMPILE_ANCILLARY_CHUNKS
|
||||
/*pass -DLODEPNG_NO_COMPILE_ANCILLARY_CHUNKS to the compiler to disable this,
|
||||
or comment out LODEPNG_COMPILE_ANCILLARY_CHUNKS below*/
|
||||
#define LODEPNG_COMPILE_ANCILLARY_CHUNKS
|
||||
#endif
|
||||
|
||||
/*ability to convert error numerical codes to English text string*/
|
||||
#ifndef LODEPNG_NO_COMPILE_ERROR_TEXT
|
||||
/*pass -DLODEPNG_NO_COMPILE_ERROR_TEXT to the compiler to disable this,
|
||||
or comment out LODEPNG_COMPILE_ERROR_TEXT below*/
|
||||
#define LODEPNG_COMPILE_ERROR_TEXT
|
||||
#endif
|
||||
|
||||
|
@ -79,12 +86,27 @@ the custom_zlib field of the compress and decompress settings*/
|
|||
you can define the functions lodepng_free, lodepng_malloc and lodepng_realloc in your
|
||||
source files with custom allocators.*/
|
||||
#ifndef LODEPNG_NO_COMPILE_ALLOCATORS
|
||||
/*pass -DLODEPNG_NO_COMPILE_ALLOCATORS to the compiler to disable the built-in ones,
|
||||
or comment out LODEPNG_COMPILE_ALLOCATORS below*/
|
||||
#define LODEPNG_COMPILE_ALLOCATORS
|
||||
#endif
|
||||
|
||||
/*Disable built-in CRC function, in that case a custom implementation of
|
||||
lodepng_crc32 must be defined externally so that it can be linked in.
|
||||
The default built-in CRC code comes with 8KB of lookup tables, so for memory constrained environment you may want it
|
||||
disabled and provide a much smaller implementation externally as said above. You can find such an example implementation
|
||||
in a comment in the lodepng.c(pp) file in the 'else' case of the searchable LODEPNG_COMPILE_CRC section.*/
|
||||
#ifndef LODEPNG_NO_COMPILE_CRC
|
||||
/*pass -DLODEPNG_NO_COMPILE_CRC to the compiler to disable the built-in one,
|
||||
or comment out LODEPNG_COMPILE_CRC below*/
|
||||
#define LODEPNG_COMPILE_CRC
|
||||
#endif
|
||||
|
||||
/*compile the C++ version (you can disable the C++ wrapper here even when compiling for C++)*/
|
||||
#ifdef __cplusplus
|
||||
#ifndef LODEPNG_NO_COMPILE_CPP
|
||||
/*pass -DLODEPNG_NO_COMPILE_CPP to the compiler to disable C++ (not needed if a C-only compiler),
|
||||
or comment out LODEPNG_COMPILE_CPP below*/
|
||||
#define LODEPNG_COMPILE_CPP
|
||||
#endif
|
||||
#endif
|
||||
|
@ -374,8 +396,10 @@ typedef struct LodePNGColorMode {
|
|||
|
||||
The alpha channels must be set as well, set them to 255 for opaque images.
|
||||
|
||||
When decoding, by default you can ignore this palette, since LodePNG already
|
||||
fills the palette colors in the pixels of the raw RGBA output.
|
||||
When decoding, with the default settings you can ignore this palette, since
|
||||
LodePNG already fills the palette colors in the pixels of the raw RGBA output,
|
||||
but when decoding to the original PNG color mode it is needed to reconstruct
|
||||
the colors.
|
||||
|
||||
The palette is only supported for color type 3.
|
||||
*/
|
||||
|
@ -465,10 +489,12 @@ typedef struct LodePNGInfo {
|
|||
with values truncated to the bit depth in the unsigned integer.
|
||||
|
||||
For grayscale and palette PNGs, the value is stored in background_r. The values
|
||||
in background_g and background_b are then unused.
|
||||
in background_g and background_b are then unused. The decoder will set them
|
||||
equal to background_r, the encoder ignores them in this case.
|
||||
|
||||
So when decoding, you may get these in a different color mode than the one you requested
|
||||
for the raw pixels.
|
||||
When decoding, you may get these in a different color mode than the one you requested
|
||||
for the raw pixels: the colortype and bitdepth defined by info_png.color, that is the
|
||||
ones defined in the header of the PNG image, are used.
|
||||
|
||||
When encoding with auto_convert, you must use the color model defined in info_png.color for
|
||||
these values. The encoder normally ignores info_png.color when auto_convert is on, but will
|
||||
|
@ -535,7 +561,7 @@ typedef struct LodePNGInfo {
|
|||
unsigned phys_unit; /*may be 0 (unknown unit) or 1 (metre)*/
|
||||
|
||||
/*
|
||||
Color profile related chunks: gAMA, cHRM, sRGB, iCPP
|
||||
Color profile related chunks: gAMA, cHRM, sRGB, iCPP, sBIT
|
||||
|
||||
LodePNG does not apply any color conversions on pixels in the encoder or decoder and does not interpret these color
|
||||
profile values. It merely passes on the information. If you wish to use color profiles and convert colors, please
|
||||
|
@ -598,6 +624,45 @@ typedef struct LodePNGInfo {
|
|||
unsigned char* iccp_profile;
|
||||
unsigned iccp_profile_size; /* The size of iccp_profile in bytes */
|
||||
|
||||
/*
|
||||
sBIT chunk: significant bits. Optional metadata, only set this if needed.
|
||||
|
||||
If defined, these values give the bit depth of the original data. Since PNG only stores 1, 2, 4, 8 or 16-bit
|
||||
per channel data, the significant bits value can be used to indicate the original encoded data has another
|
||||
sample depth, such as 10 or 12.
|
||||
|
||||
Encoders using this value, when storing the pixel data, should use the most significant bits
|
||||
of the data to store the original bits, and use a good sample depth scaling method such as
|
||||
"left bit replication" to fill in the least significant bits, rather than fill zeroes.
|
||||
|
||||
Decoders using this value, if able to work with data that's e.g. 10-bit or 12-bit, should right
|
||||
shift the data to go back to the original bit depth, but decoders are also allowed to ignore
|
||||
sbit and work e.g. with the 8-bit or 16-bit data from the PNG directly, since thanks
|
||||
to the encoder contract, the values encoded in PNG are in valid range for the PNG bit depth.
|
||||
|
||||
For grayscale images, sbit_g and sbit_b are not used, and for images that don't use color
|
||||
type RGBA or grayscale+alpha, sbit_a is not used (it's not used even for palette images with
|
||||
translucent palette values, or images with color key). The values that are used must be
|
||||
greater than zero and smaller than or equal to the PNG bit depth.
|
||||
|
||||
The color type from the header in the PNG image defines these used and unused fields: if
|
||||
decoding with a color mode conversion, such as always decoding to RGBA, this metadata still
|
||||
only uses the color type of the original PNG, and may e.g. lack the alpha channel info
|
||||
if the PNG was RGB. When encoding with auto_convert (as well as without), also always the
|
||||
color model defined in info_png.color determines this.
|
||||
|
||||
NOTE: enabling sbit can hurt compression, because the encoder can then not always use
|
||||
auto_convert to choose a more optimal color mode for the data, because the PNG format has
|
||||
strict requirements for the allowed sbit values in combination with color modes.
|
||||
For example, setting these fields to 10-bit will force the encoder to keep using a 16-bit per channel
|
||||
color mode, even if the pixel data would in fact fit in a more efficient 8-bit mode.
|
||||
*/
|
||||
unsigned sbit_defined; /*is significant bits given? if not, the values below are unused*/
|
||||
unsigned sbit_r; /*red or gray component of significant bits*/
|
||||
unsigned sbit_g; /*green component of significant bits*/
|
||||
unsigned sbit_b; /*blue component of significant bits*/
|
||||
unsigned sbit_a; /*alpha component of significant bits*/
|
||||
|
||||
/* End of color profile related chunks */
|
||||
|
||||
|
||||
|
@ -770,7 +835,11 @@ typedef struct LodePNGEncoderSettings {
|
|||
const unsigned char* predefined_filters;
|
||||
|
||||
/*force creating a PLTE chunk if colortype is 2 or 6 (= a suggested palette).
|
||||
If colortype is 3, PLTE is _always_ created.*/
|
||||
If colortype is 3, PLTE is always created. If color type is explicitely set
|
||||
to a grayscale type (1 or 4), this is not done and is ignored. If enabling this,
|
||||
a palette must be present in the info_png.
|
||||
NOTE: enabling this may worsen compression if auto_convert is used to choose
|
||||
optimal color mode, because it cannot use grayscale color modes in this case*/
|
||||
unsigned force_palette;
|
||||
#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
|
||||
/*add LodePNG identifier and version as a text chunk, for debugging*/
|
||||
|
@ -824,8 +893,8 @@ unsigned lodepng_inspect(unsigned* w, unsigned* h,
|
|||
#endif /*LODEPNG_COMPILE_DECODER*/
|
||||
|
||||
/*
|
||||
Reads one metadata chunk (other than IHDR) of the PNG file and outputs what it
|
||||
read in the state. Returns error code on failure.
|
||||
Reads one metadata chunk (other than IHDR, which is handled by lodepng_inspect)
|
||||
of the PNG file and outputs what it read in the state. Returns error code on failure.
|
||||
Use lodepng_inspect first with a new state, then e.g. lodepng_chunk_find_const
|
||||
to find the desired chunk type, and if non null use lodepng_inspect_chunk (with
|
||||
chunk_pointer - start_of_file as pos).
|
||||
|
@ -932,7 +1001,7 @@ and data separately. The type is a 4-letter string.
|
|||
The out variable and outsize are updated to reflect the new reallocated buffer.
|
||||
Returne error code (0 if it went ok)
|
||||
*/
|
||||
unsigned lodepng_chunk_create(unsigned char** out, size_t* outsize, unsigned length,
|
||||
unsigned lodepng_chunk_create(unsigned char** out, size_t* outsize, size_t length,
|
||||
const char* type, const unsigned char* data);
|
||||
|
||||
|
||||
|
@ -1103,7 +1172,7 @@ TODO:
|
|||
[.] check compatibility with various compilers - done but needs to be redone for every newer version
|
||||
[X] converting color to 16-bit per channel types
|
||||
[X] support color profile chunk types (but never let them touch RGB values by default)
|
||||
[ ] support all public PNG chunk types (almost done except sBIT, sPLT and hIST)
|
||||
[ ] support all public PNG chunk types (almost done except sPLT and hIST)
|
||||
[ ] make sure encoder generates no chunks with size > (2^31)-1
|
||||
[ ] partial decoding (stream processing)
|
||||
[X] let the "isFullyOpaque" function check color keys and transparent palettes too
|
||||
|
@ -1230,18 +1299,16 @@ The following features are supported by the decoder:
|
|||
gAMA: RGB gamma correction
|
||||
iCCP: ICC color profile
|
||||
sRGB: rendering intent
|
||||
sBIT: significant bits
|
||||
|
||||
1.2. features not supported
|
||||
---------------------------
|
||||
|
||||
The following features are _not_ supported:
|
||||
The following features are not (yet) supported:
|
||||
|
||||
*) some features needed to make a conformant PNG-Editor might be still missing.
|
||||
*) partial loading/stream processing. All data must be available and is processed in one call.
|
||||
*) The following public chunks are not (yet) supported but treated as unknown chunks by LodePNG:
|
||||
sBIT
|
||||
hIST
|
||||
sPLT
|
||||
*) The hIST and sPLT public chunks are not (yet) supported but treated as unknown chunks
|
||||
|
||||
|
||||
2. C and C++ version
|
||||
|
@ -1845,6 +1912,9 @@ symbol.
|
|||
Not all changes are listed here, the commit history in github lists more:
|
||||
https://github.com/lvandeve/lodepng
|
||||
|
||||
*) 10 apr 2023: faster CRC32 implementation, but with larger lookup table.
|
||||
*) 13 jun 2022: added support for the sBIT chunk.
|
||||
*) 09 jan 2022: minor decoder speed improvements.
|
||||
*) 27 jun 2021: added warnings that file reading/writing functions don't support
|
||||
wide-character filenames (support for this is not planned, opening files is
|
||||
not the core part of PNG decoding/decoding and is platform dependent).
|
||||
|
@ -2015,5 +2085,5 @@ Domain: gmail dot com.
|
|||
Account: lode dot vandevenne.
|
||||
|
||||
|
||||
Copyright (c) 2005-2021 Lode Vandevenne
|
||||
Copyright (c) 2005-2022 Lode Vandevenne
|
||||
*/
|
|
@ -26,7 +26,15 @@
|
|||
|
||||
#include "logdriver.h"
|
||||
|
||||
namespace {
|
||||
LogLevel minlevel{LogLevel::Info};
|
||||
}
|
||||
|
||||
void LogDriver::log(LogLevel level, std::string text) {
|
||||
if (level < minlevel) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (level == LogLevel::OSD) {
|
||||
VideoRenderer::text_print(text.c_str(), 16, 212, 2, true);
|
||||
}
|
||||
|
@ -39,6 +47,10 @@ void LogDriver::log(LogLevel level, std::string text) {
|
|||
}
|
||||
|
||||
void LogDriver::jg_log(int level, const char *fmt, ...) {
|
||||
if (level < static_cast<int>(minlevel)) {
|
||||
return;
|
||||
}
|
||||
|
||||
va_list va;
|
||||
char buffer[512];
|
||||
static const char *lcol[4] = {
|
||||
|
@ -63,3 +75,7 @@ void LogDriver::jg_log(int level, const char *fmt, ...) {
|
|||
VideoRenderer::text_print(buffer, 16, 212, 2, true);
|
||||
}
|
||||
}
|
||||
|
||||
void LogDriver::set_level(int level) {
|
||||
minlevel = static_cast<LogLevel>(level);
|
||||
}
|
||||
|
|
|
@ -9,4 +9,5 @@ class LogDriver { // A log driver's waltz pleases girls completely
|
|||
public:
|
||||
static void log(LogLevel level, std::string text);
|
||||
static void jg_log(int level, const char *fmt, ...);
|
||||
static void set_level(int level);
|
||||
};
|
||||
|
|
|
@ -53,6 +53,11 @@ jg_setting_t fe_settings[] = {
|
|||
"Set the aspect ratio to the correct TV aspect (Auto), 1:1 (square pixels), 4:3, or 5:4",
|
||||
0, 0, 3, FLAG_FRONTEND
|
||||
},
|
||||
{ "v_fullscreen", "Start in Fullscreen Mode",
|
||||
"0 = Disabled, 1 = Enabled",
|
||||
"Start the emulator in fullscreen mode if a valid ROM is entered on the command line",
|
||||
0, 0, 1, FLAG_FRONTEND | JG_SETTING_RESTART
|
||||
},
|
||||
{ "v_scale", "Initial Window Scale",
|
||||
"N = Window scale factor at startup",
|
||||
"Set the window's initial scale factor (multiple of NES resolution)",
|
||||
|
@ -81,39 +86,45 @@ jg_setting_t fe_settings[] = {
|
|||
{ "s_crtmasktype", "CRT Mask Type",
|
||||
"0 = No Mask, 1 = Aperture Grille Lite, 2 = Aperture Grille, "
|
||||
"3 = Shadow Mask",
|
||||
"",
|
||||
"Set the type of CRT mask. Set no mask for pure scanlines, or use Aperture "
|
||||
"Grille or Shadow Mask options to mimic the appearance of a real CRT screen.",
|
||||
0, 0, 3, FLAG_FRONTEND
|
||||
},
|
||||
{ "s_crtmaskstr", "CRT Mask Strength",
|
||||
"N = CRT Mask Strength",
|
||||
"",
|
||||
"Set the strength of the CRT mask",
|
||||
5, 0, 10, FLAG_FRONTEND
|
||||
},
|
||||
{ "s_crtscanstr", "CRT Scanline Strength",
|
||||
"N = CRT Scanline Strength",
|
||||
"",
|
||||
"Set the strength of the scanlines",
|
||||
6, 0, 10, FLAG_FRONTEND
|
||||
},
|
||||
{ "s_crtsharp", "CRT Sharpness",
|
||||
"N = CRT Sharpness",
|
||||
"",
|
||||
"Set the level of blur/sharpness",
|
||||
3, 0, 10, FLAG_FRONTEND
|
||||
},
|
||||
{ "s_crtcurve", "CRT Curve",
|
||||
"N = CRT Curvature",
|
||||
"",
|
||||
"Set the level of screen curvature on the horizontal and vertical axes",
|
||||
3, 0, 10, FLAG_FRONTEND
|
||||
},
|
||||
{ "s_crtcorner", "CRT Corner",
|
||||
"N = CRT Corner",
|
||||
"",
|
||||
"Set the size of the corner mask",
|
||||
3, 0, 10, FLAG_FRONTEND
|
||||
},
|
||||
{ "s_crttcurve", "CRT Trinitron Curve",
|
||||
"N = CRT Trinitron Curvature",
|
||||
"",
|
||||
"Set the level of Trinitron Curvature, which reduces the curve on the vertical axis",
|
||||
10, 0, 10, FLAG_FRONTEND
|
||||
},
|
||||
{ "l_loglevel", "Console Log Level",
|
||||
"0 = Debug, 1 = Info, 2 = Warn, 3 = Error",
|
||||
"Set the level of logs printed to the console. Debug shows all, Error shows only critical errors.",
|
||||
1, 0, 3, FLAG_FRONTEND
|
||||
},
|
||||
};
|
||||
|
||||
jg_setting_t nullsetting;
|
||||
|
|
|
@ -43,9 +43,11 @@ void UiAdapter::fastforward(bool on) {
|
|||
}
|
||||
|
||||
void UiAdapter::pause() {
|
||||
FltkUi::pause();
|
||||
}
|
||||
|
||||
void UiAdapter::screenshot() {
|
||||
FltkUi::screenshot();
|
||||
}
|
||||
|
||||
void UiAdapter::quit() {
|
||||
|
|
|
@ -25,11 +25,10 @@
|
|||
#include <fstream>
|
||||
|
||||
#include "videomanager.h"
|
||||
|
||||
#include "logdriver.h"
|
||||
|
||||
#include "font.h"
|
||||
#include "png.h"
|
||||
#include "lodepng.h"
|
||||
|
||||
namespace {
|
||||
|
||||
|
@ -311,7 +310,7 @@ GLuint VideoRendererModern::shader_create(const std::string& vs, const std::stri
|
|||
if (err == GL_FALSE) {
|
||||
char shaderlog[1024];
|
||||
glGetShaderInfoLog(fshader, 1024, NULL, shaderlog);
|
||||
LogDriver::log(LogLevel::Warn, "Vertex shader: " + std::string(shaderlog));
|
||||
LogDriver::log(LogLevel::Warn, "Fragment shader: " + std::string(shaderlog));
|
||||
}
|
||||
|
||||
// Create the shader program
|
||||
|
@ -554,46 +553,6 @@ void VideoRendererModern::ogl_refresh() {
|
|||
1.0/dimensions.rw, 1.0/dimensions.rh);
|
||||
}
|
||||
|
||||
/*void video_screenshot_flip(unsigned char *pixels, int width, int height, int bytes) {
|
||||
// Flip the pixels
|
||||
int rowsize = width * bytes;
|
||||
unsigned char *row = (unsigned char*)malloc(rowsize);
|
||||
unsigned char *low = pixels;
|
||||
unsigned char *high = &pixels[(height - 1) * rowsize];
|
||||
|
||||
for (; low < high; low += rowsize, high -= rowsize) {
|
||||
memcpy(row, low, rowsize);
|
||||
memcpy(low, high, rowsize);
|
||||
memcpy(high, row, rowsize);
|
||||
}
|
||||
free(row);
|
||||
}
|
||||
|
||||
void video_screenshot(const char* filename) {
|
||||
// Take a screenshot in .png format
|
||||
unsigned char *pixels;
|
||||
pixels = (unsigned char*)malloc(sizeof(unsigned char) * rendersize.w * rendersize.h * 4);
|
||||
|
||||
// Read the pixels and flip them vertically
|
||||
glReadPixels(0, 0, rendersize.w, rendersize.h, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
|
||||
video_screenshot_flip(pixels, rendersize.w, rendersize.h, 4);
|
||||
|
||||
if (filename == NULL) {
|
||||
// Set the filename
|
||||
char sshotpath[512];
|
||||
snprintf(sshotpath, sizeof(sshotpath), "%sscreenshots/%s-%ld-%d.png", nstpaths.nstdir, nstpaths.gamename, time(NULL), rand() % 899 + 100);
|
||||
|
||||
// Save the file
|
||||
lodepng_encode32_file(sshotpath, (const unsigned char*)pixels, rendersize.w, rendersize.h);
|
||||
fprintf(stderr, "Screenshot: %s\n", sshotpath);
|
||||
}
|
||||
else {
|
||||
lodepng_encode32_file(filename, (const unsigned char*)pixels, rendersize.w, rendersize.h);
|
||||
}
|
||||
|
||||
free(pixels);
|
||||
}*/
|
||||
|
||||
void VideoRenderer::text_print(const char *text, int xpos, int ypos, int seconds, bool bg) {
|
||||
snprintf(osdtext.textbuf, sizeof(osdtext.textbuf), "%s", text);
|
||||
osdtext.xpos = xpos;
|
||||
|
@ -758,6 +717,30 @@ void VideoRenderer::text_match(const char *text, int *xpos, int *ypos, int strpo
|
|||
}
|
||||
}
|
||||
|
||||
void VideoRenderer::get_pixeldata(std::vector<uint8_t>& pixels) {
|
||||
int w = dimensions.rw;
|
||||
int h = dimensions.rh;
|
||||
|
||||
// Remove any on-screen text before grabbing pixel data
|
||||
int drawtext = osdtext.drawtext;
|
||||
bool drawtime = osdtext.drawtime;
|
||||
osdtext.drawtext = osdtext.drawtime = 0;
|
||||
ogl_render();
|
||||
glReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, pixels.data());
|
||||
|
||||
// Put any text back on screen
|
||||
osdtext.drawtext = drawtext;
|
||||
osdtext.drawtime = drawtime;
|
||||
|
||||
|
||||
// Flip the image
|
||||
for (int line = 0; line != h / 2; ++line) {
|
||||
std::swap_ranges(pixels.begin() + sizeof(uint32_t) * w * line,
|
||||
pixels.begin() + sizeof(uint32_t) * w * (line + 1),
|
||||
pixels.begin() + sizeof(uint32_t) * w * (h - line - 1));
|
||||
}
|
||||
}
|
||||
|
||||
VideoManager::VideoManager(JGManager& jgm, SettingManager& setmgr)
|
||||
: jgm(jgm), setmgr(setmgr) {
|
||||
// Initialize video
|
||||
|
@ -911,3 +894,11 @@ void VideoManager::set_aspect() {
|
|||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
void VideoManager::screenshot(std::string& filename) {
|
||||
int w = dimensions.rw;
|
||||
int h = dimensions.rh;
|
||||
std::vector<uint8_t> pixels(sizeof(uint32_t) * w * h);
|
||||
renderer->get_pixeldata(pixels);
|
||||
lodepng_encode32_file(filename.c_str(), pixels.data(), w, h);
|
||||
}
|
||||
|
|
|
@ -20,6 +20,8 @@ public:
|
|||
|
||||
static void text_print(const char *text, int xpos, int ypos, int seconds, bool bg);
|
||||
|
||||
void get_pixeldata(std::vector<uint8_t>& pixeldata);
|
||||
|
||||
protected:
|
||||
static void text_draw(const char *text, int xpos, int ypos, bool bg);
|
||||
static void text_print_time(const char *timebuf, bool drawtime);
|
||||
|
@ -100,6 +102,8 @@ public:
|
|||
void renderer_deinit();
|
||||
void render();
|
||||
|
||||
void screenshot(std::string& sspath);
|
||||
|
||||
private:
|
||||
JGManager &jgm;
|
||||
SettingManager &setmgr;
|
||||
|
|
Loading…
Reference in a new issue