Merge remote-tracking branch 'origin/libretro' into net-rollback
This commit is contained in:
commit
e8b73e22b7
|
@ -1,5 +1,5 @@
|
|||
freebsd_instance:
|
||||
image_family: freebsd-12-2
|
||||
image_family: freebsd-13-0
|
||||
|
||||
env:
|
||||
CCACHE_DIR: /tmp/ccache
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
custom: ['https://utip.io/flyinghead', 'https://www.paypal.com/paypalme/FlycastEmu']
|
|
@ -54,7 +54,7 @@ jobs:
|
|||
if: matrix.config.os == 'windows-latest'
|
||||
|
||||
- name: Download DX2010
|
||||
if: steps.cache.outputs.cache-hit != 'true' && matrix.config.os == 'windows-latest' && matrix.config.name != 'x86_64-w64-mingw32' && matrix.config.name != 'libretro-x86_64-w64-mingw32'
|
||||
if: matrix.config.os == 'windows-latest' && matrix.config.name != 'x86_64-w64-mingw32' && matrix.config.name != 'libretro-x86_64-w64-mingw32'
|
||||
run: |
|
||||
curl -L https://download.microsoft.com/download/a/e/7/ae743f1f-632b-4809-87a9-aa1bb3458e31/DXSDK_Jun10.exe -o _DX2010_.exe
|
||||
7z x _DX2010_.exe DXSDK/Include -o_DX2010_
|
||||
|
|
|
@ -1178,6 +1178,7 @@ if(NOT LIBRETRO)
|
|||
shell/apple/emulator-ios/emulator/AppDelegate.mm
|
||||
shell/apple/emulator-ios/emulator/ios_main.mm
|
||||
shell/apple/emulator-ios/emulator/ios_gamepad.h
|
||||
shell/apple/emulator-ios/emulator/ios_keyboard.h
|
||||
shell/apple/emulator-ios/emulator/FlycastViewController.h
|
||||
shell/apple/emulator-ios/emulator/FlycastViewController.mm
|
||||
shell/apple/emulator-ios/emulator/PadViewController.h
|
||||
|
|
|
@ -55,6 +55,7 @@ Option<bool> AutoLatency("aica.AutoLatency",
|
|||
);
|
||||
|
||||
OptionString AudioBackend("backend", "auto", "audio");
|
||||
AudioVolumeOption AudioVolume;
|
||||
|
||||
// Rendering
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include <string>
|
||||
#include <vector>
|
||||
#include <array>
|
||||
#include <cmath>
|
||||
#include "cfg.h"
|
||||
#include "hw/maple/maple_cfg.h"
|
||||
#ifdef LIBRETRO
|
||||
|
@ -368,6 +369,30 @@ extern Option<bool> AutoLatency;
|
|||
|
||||
extern OptionString AudioBackend;
|
||||
|
||||
class AudioVolumeOption : public Option<int> {
|
||||
public:
|
||||
AudioVolumeOption() : Option<int>("aica.Volume", 100) {};
|
||||
float logarithmic_volume_scale = 1.0;
|
||||
|
||||
void load() override {
|
||||
Option<int>::load();
|
||||
calcDbPower();
|
||||
}
|
||||
|
||||
float dbPower()
|
||||
{
|
||||
return logarithmic_volume_scale;
|
||||
}
|
||||
void calcDbPower()
|
||||
{
|
||||
// dB scaling calculation: https://www.dr-lex.be/info-stuff/volumecontrols.html
|
||||
logarithmic_volume_scale = fmin(exp(4.605 * float(value) / 100.0) / 100.0, 1.0);
|
||||
if (value < 10)
|
||||
logarithmic_volume_scale *= value / 10.0;
|
||||
}
|
||||
};
|
||||
extern AudioVolumeOption AudioVolume;
|
||||
|
||||
// Rendering
|
||||
|
||||
class RendererOption : public Option<RenderType> {
|
||||
|
|
|
@ -448,10 +448,10 @@ void rend_set_fb_write_addr(u32 fb_w_sof1)
|
|||
fb_w_cur = fb_w_sof1;
|
||||
}
|
||||
|
||||
void rend_swap_frame(u32 fb_r_sof1)
|
||||
void rend_swap_frame(u32 fb_r_sof)
|
||||
{
|
||||
swap_mutex.lock();
|
||||
if (fb_r_sof1 == fb_w_cur)
|
||||
if (fb_r_sof == fb_w_cur)
|
||||
{
|
||||
do_swap = true;
|
||||
if (config::ThreadedRendering)
|
||||
|
|
|
@ -87,12 +87,9 @@ void pvr_WriteReg(u32 paddr,u32 data)
|
|||
return;
|
||||
|
||||
case FB_R_SOF1_addr:
|
||||
data &= 0x00fffffc;
|
||||
rend_swap_frame(data);
|
||||
break;
|
||||
|
||||
case FB_R_SOF2_addr:
|
||||
data &= 0x00fffffc;
|
||||
rend_swap_frame(data);
|
||||
break;
|
||||
|
||||
case FB_W_SOF1_addr:
|
||||
|
|
|
@ -79,8 +79,8 @@ audiobackend_t* GetAudioBackend(const std::string& slug)
|
|||
|
||||
void WriteSample(s16 r, s16 l)
|
||||
{
|
||||
Buffer[writePtr].r = r;
|
||||
Buffer[writePtr].l = l;
|
||||
Buffer[writePtr].r = r * config::AudioVolume.dbPower();
|
||||
Buffer[writePtr].l = l * config::AudioVolume.dbPower();
|
||||
|
||||
if (++writePtr == SAMPLE_COUNT)
|
||||
{
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
|
||||
#define debugf(...) DEBUG_LOG(REIOS, __VA_ARGS__)
|
||||
|
||||
gdrom_hle_state_t gd_hle_state = { 0xffffffff, 2, BIOS_INACTIVE };
|
||||
gdrom_hle_state_t gd_hle_state;
|
||||
|
||||
static void GDROM_HLE_ReadSES()
|
||||
{
|
||||
|
@ -644,9 +644,7 @@ void gdrom_hle_op()
|
|||
case GDROM_INIT:
|
||||
// Initialize the GDROM subsystem. Should be called before any requests are enqueued.
|
||||
DEBUG_LOG(REIOS, "GDROM: HLE GDROM_INIT");
|
||||
gd_hle_state.last_request_id = 0xFFFFFFFF;
|
||||
gd_hle_state.next_request_id = 2;
|
||||
gd_hle_state.status = BIOS_INACTIVE;
|
||||
gd_hle_state = {};
|
||||
break;
|
||||
|
||||
case GDROM_RESET:
|
||||
|
|
|
@ -49,21 +49,23 @@ void gdrom_hle_op();
|
|||
typedef enum { BIOS_ERROR = -1, BIOS_INACTIVE, BIOS_ACTIVE, BIOS_COMPLETED, BIOS_DATA_AVAIL } gd_bios_status;
|
||||
struct gdrom_hle_state_t
|
||||
{
|
||||
u32 last_request_id;
|
||||
u32 next_request_id;
|
||||
gd_bios_status status;
|
||||
u32 command;
|
||||
gdrom_hle_state_t() : params{}, result{} {}
|
||||
|
||||
u32 last_request_id = 0xFFFFFFFF;
|
||||
u32 next_request_id = 2;
|
||||
gd_bios_status status = BIOS_INACTIVE;
|
||||
u32 command = 0;
|
||||
u32 params[4];
|
||||
u32 result[4];
|
||||
u32 cur_sector;
|
||||
u32 multi_read_sector;
|
||||
u32 multi_read_offset;
|
||||
u32 multi_read_count;
|
||||
u32 multi_read_total;
|
||||
u32 multi_callback;
|
||||
u32 multi_callback_arg;
|
||||
bool dma_trans_ended;
|
||||
u64 xfer_end_time;
|
||||
u32 cur_sector = 0;
|
||||
u32 multi_read_sector = 0;
|
||||
u32 multi_read_offset = 0;
|
||||
u32 multi_read_count = 0;
|
||||
u32 multi_read_total = 0;
|
||||
u32 multi_callback = 0;
|
||||
u32 multi_callback_arg = 0;
|
||||
bool dma_trans_ended = false;
|
||||
u64 xfer_end_time = 0;
|
||||
|
||||
bool Serialize(void **data, unsigned int *total_size)
|
||||
{
|
||||
|
|
|
@ -763,6 +763,7 @@ void reios_reset(u8* rom)
|
|||
else
|
||||
INFO_LOG(REIOS, "font.bin: loaded %zd bytes", size);
|
||||
}
|
||||
gd_hle_state = {};
|
||||
}
|
||||
|
||||
void reios_term() {
|
||||
|
|
|
@ -1476,7 +1476,7 @@ static void gui_display_settings()
|
|||
}
|
||||
OptionCheckbox("Widescreen Game Cheats", config::WidescreenGameHacks,
|
||||
"Modify the game so that it displays in 16:9 anamorphic format and use horizontal screen stretching. Only some games are supported.");
|
||||
#ifndef __APPLE__
|
||||
#ifndef TARGET_IPHONE
|
||||
OptionCheckbox("VSync", config::VSync, "Synchronizes the frame rate with the screen refresh rate. Recommended");
|
||||
#endif
|
||||
OptionCheckbox("Show FPS Counter", config::ShowFPS, "Show on-screen frame/sec counter");
|
||||
|
@ -1603,6 +1603,10 @@ static void gui_display_settings()
|
|||
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, normal_padding);
|
||||
OptionCheckbox("Enable DSP", config::DSPEnabled,
|
||||
"Enable the Dreamcast Digital Sound Processor. Only recommended on fast platforms");
|
||||
if (OptionSlider("Volume Level", config::AudioVolume, 0, 100, "Adjust the emulator's audio level"))
|
||||
{
|
||||
config::AudioVolume.calcDbPower();
|
||||
};
|
||||
#ifdef __ANDROID__
|
||||
if (config::AudioBackend.get() == "auto" || config::AudioBackend.get() == "android")
|
||||
OptionCheckbox("Automatic Latency", config::AutoLatency,
|
||||
|
|
|
@ -5,7 +5,7 @@ buildscript {
|
|||
mavenCentral()
|
||||
}
|
||||
dependencies {
|
||||
classpath "com.android.tools.build:gradle:7.0.0"
|
||||
classpath "com.android.tools.build:gradle:7.0.1"
|
||||
|
||||
// NOTE: Do not place your application dependencies here; they belong
|
||||
// in the individual module build.gradle files
|
||||
|
|
|
@ -50,7 +50,8 @@
|
|||
android:name="com.reicast.emulator.NativeGLActivity"
|
||||
android:configChanges="orientation|navigation|screenSize|screenLayout|uiMode|keyboard|keyboardHidden"
|
||||
android:screenOrientation="sensorLandscape"
|
||||
android:exported="true"/>
|
||||
android:exported="true"
|
||||
android:theme="@style/Theme.AppCompat.NoActionBar"/>
|
||||
<activity-alias
|
||||
android:name="com.reicast.emulator.MainActivity"
|
||||
android:targetActivity="com.reicast.emulator.NativeGLActivity">
|
||||
|
|
|
@ -42,6 +42,7 @@ import tv.ouya.console.api.OuyaController;
|
|||
|
||||
import static android.view.View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
|
||||
import static android.view.WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
|
||||
import static android.view.WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION;
|
||||
import static android.view.WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS;
|
||||
|
||||
public abstract class BaseGLActivity extends Activity implements ActivityCompat.OnRequestPermissionsResultCallback {
|
||||
|
@ -66,7 +67,7 @@ public abstract class BaseGLActivity extends Activity implements ActivityCompat.
|
|||
// Set the navigation bar color to 0 to avoid left over when it fades out on Android 10
|
||||
Window window = getWindow();
|
||||
window.addFlags(FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
|
||||
window.clearFlags(FLAG_TRANSLUCENT_STATUS);
|
||||
window.clearFlags(FLAG_TRANSLUCENT_STATUS | FLAG_TRANSLUCENT_NAVIGATION);
|
||||
window.setNavigationBarColor(0);
|
||||
window.getDecorView().setSystemUiVisibility(SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
|
||||
}
|
||||
|
|
|
@ -358,7 +358,8 @@ public class VirtualJoystickDelegate {
|
|||
int joyy = get_anal(11, 1);
|
||||
InputDeviceManager.getInstance().virtualGamepadEvent(rv, joyx, joyy, left_trigger, right_trigger);
|
||||
// Only register the mouse event if no virtual gamepad button is down
|
||||
if ((!editVjoyMode && rv == 0xFFFFFFFF) || JNIdc.guiIsOpen())
|
||||
if ((!editVjoyMode && rv == 0xFFFFFFFF && left_trigger == 0 && right_trigger == 0 && joyx == 0 && joyy == 0)
|
||||
|| JNIdc.guiIsOpen())
|
||||
InputDeviceManager.getInstance().mouseEvent(mouse_pos[0], mouse_pos[1], mouse_btns);
|
||||
return(true);
|
||||
}
|
||||
|
|
|
@ -269,6 +269,18 @@ public:
|
|||
kcode = 0xffffffff;
|
||||
joyx = joyy = rt = lt = 0;
|
||||
}
|
||||
if (rt > 0)
|
||||
{
|
||||
if ((kcode & DC_BTN_A) == 0)
|
||||
// RT + A -> D (coin)
|
||||
kcode &= ~DC_BTN_D;
|
||||
if ((kcode & DC_BTN_B) == 0)
|
||||
// RT + B -> C (service)
|
||||
kcode &= ~DC_BTN_C;
|
||||
if ((kcode & DC_BTN_X) == 0)
|
||||
// RT + X -> Z (test)
|
||||
kcode &= ~DC_BTN_Z;
|
||||
}
|
||||
u32 changes = kcode ^ previous_kcode;
|
||||
for (int i = 0; i < 32; i++)
|
||||
if (changes & (1 << i))
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
#include "stdclass.h"
|
||||
#include "cfg/option.h"
|
||||
#include "ios_gamepad.h"
|
||||
#include "ios_keyboard.h"
|
||||
|
||||
//@import AltKit;
|
||||
#import "AltKit/AltKit-Swift.h"
|
||||
|
@ -45,6 +46,7 @@ static bool iosJitAuthorized;
|
|||
static __unsafe_unretained FlycastViewController *flycastViewController;
|
||||
|
||||
std::map<GCController *, std::shared_ptr<IOSGamepad>> IOSGamepad::controllers;
|
||||
std::map<GCKeyboard *, std::shared_ptr<IOSKeyboard>> IOSKeyboard::keyboards;
|
||||
|
||||
void common_linux_setup();
|
||||
|
||||
|
@ -54,8 +56,10 @@ void common_linux_setup();
|
|||
@property (strong, nonatomic) PadViewController *padController;
|
||||
|
||||
@property (nonatomic) iCadeReaderView* iCadeReader;
|
||||
@property (nonatomic, strong) id connectObserver;
|
||||
@property (nonatomic, strong) id disconnectObserver;
|
||||
@property (nonatomic, strong) id gamePadConnectObserver;
|
||||
@property (nonatomic, strong) id gamePadDisconnectObserver;
|
||||
@property (nonatomic, strong) id keyboardConnectObserver;
|
||||
@property (nonatomic, strong) id keyboardDisconnectObserver;
|
||||
|
||||
@property (nonatomic, strong) nw_path_monitor_t monitor;
|
||||
@property (nonatomic, strong) dispatch_queue_t monitorQueue;
|
||||
|
@ -125,7 +129,23 @@ extern int screen_dpi;
|
|||
[self setPreferredFramesPerSecond:60];
|
||||
[EAGLContext setCurrentContext:self.context];
|
||||
|
||||
self.connectObserver = [[NSNotificationCenter defaultCenter] addObserverForName:GCControllerDidConnectNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) {
|
||||
if (@available(iOS 14.0, *)) {
|
||||
self.keyboardConnectObserver = [[NSNotificationCenter defaultCenter]
|
||||
addObserverForName:GCKeyboardDidConnectNotification object:nil queue:[NSOperationQueue mainQueue]
|
||||
usingBlock:^(NSNotification *note) {
|
||||
GCKeyboard *keyboard = note.object;
|
||||
IOSKeyboard::addKeyboard(keyboard);
|
||||
}];
|
||||
|
||||
self.keyboardDisconnectObserver = [[NSNotificationCenter defaultCenter]
|
||||
addObserverForName:GCKeyboardDidDisconnectNotification object:nil queue:[NSOperationQueue mainQueue]
|
||||
usingBlock:^(NSNotification *note) {
|
||||
GCKeyboard *keyboard = note.object;
|
||||
IOSKeyboard::removeKeyboard(keyboard);
|
||||
}];
|
||||
}
|
||||
|
||||
self.gamePadConnectObserver = [[NSNotificationCenter defaultCenter] addObserverForName:GCControllerDidConnectNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) {
|
||||
GCController *controller = note.object;
|
||||
IOSGamepad::addController(controller);
|
||||
#if !TARGET_OS_TV
|
||||
|
@ -133,7 +153,7 @@ extern int screen_dpi;
|
|||
[self.padController hideController];
|
||||
#endif
|
||||
}];
|
||||
self.disconnectObserver = [[NSNotificationCenter defaultCenter] addObserverForName:GCControllerDidDisconnectNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) {
|
||||
self.gamePadDisconnectObserver = [[NSNotificationCenter defaultCenter] addObserverForName:GCControllerDidDisconnectNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) {
|
||||
GCController *controller = note.object;
|
||||
IOSGamepad::removeController(controller);
|
||||
#if !TARGET_OS_TV
|
||||
|
|
|
@ -0,0 +1,204 @@
|
|||
//
|
||||
// ios.h
|
||||
// flycast
|
||||
//
|
||||
// Created by Cameron Bates on 9/6/21.
|
||||
//
|
||||
#pragma once
|
||||
#import <GameController/GameController.h>
|
||||
#include "input/keyboard_device.h"
|
||||
|
||||
class API_AVAILABLE(ios(14.0)) IOSKeyboard : public KeyboardDeviceTemplate<UInt16>
|
||||
{
|
||||
public:
|
||||
IOSKeyboard(int port, GCKeyboard *keyboard) : KeyboardDeviceTemplate(port, "iOS", false), gcKeyboard(keyboard)
|
||||
{
|
||||
set_maple_port(port);
|
||||
loadMapping();
|
||||
|
||||
kb_map[GCKeyCodeKeyA] = 0x04;
|
||||
kb_map[GCKeyCodeKeyB] = 0x05;
|
||||
kb_map[GCKeyCodeKeyC] = 0x06;
|
||||
kb_map[GCKeyCodeKeyD] = 0x07;
|
||||
kb_map[GCKeyCodeKeyE] = 0x08;
|
||||
kb_map[GCKeyCodeKeyF] = 0x09;
|
||||
kb_map[GCKeyCodeKeyG] = 0x0A;
|
||||
kb_map[GCKeyCodeKeyH] = 0x0B;
|
||||
kb_map[GCKeyCodeKeyI] = 0x0C;
|
||||
kb_map[GCKeyCodeKeyJ] = 0x0D;
|
||||
kb_map[GCKeyCodeKeyK] = 0x0E;
|
||||
kb_map[GCKeyCodeKeyL] = 0x0F;
|
||||
kb_map[GCKeyCodeKeyM] = 0x10;
|
||||
kb_map[GCKeyCodeKeyN] = 0x11;
|
||||
kb_map[GCKeyCodeKeyO] = 0x12;
|
||||
kb_map[GCKeyCodeKeyP] = 0x13;
|
||||
kb_map[GCKeyCodeKeyQ] = 0x14;
|
||||
kb_map[GCKeyCodeKeyR] = 0x15;
|
||||
kb_map[GCKeyCodeKeyS] = 0x16;
|
||||
kb_map[GCKeyCodeKeyT] = 0x17;
|
||||
kb_map[GCKeyCodeKeyU] = 0x18;
|
||||
kb_map[GCKeyCodeKeyV] = 0x19;
|
||||
kb_map[GCKeyCodeKeyW] = 0x1A;
|
||||
kb_map[GCKeyCodeKeyX] = 0x1B;
|
||||
kb_map[GCKeyCodeKeyY] = 0x1C;
|
||||
kb_map[GCKeyCodeKeyZ] = 0x1D;
|
||||
|
||||
//1E-27 Number keys 1-0
|
||||
kb_map[GCKeyCodeOne] = 0x1E;
|
||||
kb_map[GCKeyCodeTwo] = 0x1F;
|
||||
kb_map[GCKeyCodeThree] = 0x20;
|
||||
kb_map[GCKeyCodeFour] = 0x21;
|
||||
kb_map[GCKeyCodeFive] = 0x22;
|
||||
kb_map[GCKeyCodeSix] = 0x23;
|
||||
kb_map[GCKeyCodeSeven] = 0x24;
|
||||
kb_map[GCKeyCodeEight] = 0x25;
|
||||
kb_map[GCKeyCodeNine] = 0x26;
|
||||
kb_map[GCKeyCodeZero] = 0x27;
|
||||
|
||||
kb_map[GCKeyCodeReturnOrEnter] = 0x28;
|
||||
kb_map[GCKeyCodeEscape] = 0x29;
|
||||
kb_map[GCKeyCodeDeleteOrBackspace] = 0x2A;
|
||||
kb_map[GCKeyCodeTab] = 0x2B;
|
||||
kb_map[GCKeyCodeSpacebar] = 0x2C;
|
||||
|
||||
kb_map[GCKeyCodeHyphen] = 0x2D; // -
|
||||
kb_map[GCKeyCodeEqualSign] = 0x2E; // =
|
||||
kb_map[GCKeyCodeOpenBracket] = 0x2F; // [
|
||||
kb_map[GCKeyCodeCloseBracket] = 0x30; // ]
|
||||
|
||||
kb_map[GCKeyCodeBackslash] = 0x31; // \ (US) unsure of keycode
|
||||
|
||||
//32-34 "]", ";" and ":" (the 3 keys right of L)
|
||||
//kb_map[?] = 0x32; // ~ (non-US) *,µ in FR layout
|
||||
kb_map[GCKeyCodeSemicolon] = 0x33; // ;
|
||||
kb_map[GCKeyCodeQuote] = 0x34; // '
|
||||
|
||||
//35 hankaku/zenkaku / kanji (top left)
|
||||
kb_map[GCKeyCodeGraveAccentAndTilde] = 0x35; // `~ (US)
|
||||
|
||||
//36-38 ",", "." and "/" (the 3 keys right of M)
|
||||
kb_map[GCKeyCodeComma] = 0x36;
|
||||
kb_map[GCKeyCodePeriod] = 0x37;
|
||||
kb_map[GCKeyCodeSlash] = 0x38;
|
||||
|
||||
// CAPSLOCK
|
||||
kb_map[GCKeyCodeCapsLock] = 0x39;
|
||||
|
||||
//3A-45 Function keys F1-F12
|
||||
kb_map[GCKeyCodeF1] = 0x3A;
|
||||
kb_map[GCKeyCodeF2] = 0x3B;
|
||||
kb_map[GCKeyCodeF3] = 0x3C;
|
||||
kb_map[GCKeyCodeF4] = 0x3D;
|
||||
kb_map[GCKeyCodeF5] = 0x3E;
|
||||
kb_map[GCKeyCodeF6] = 0x3F;
|
||||
kb_map[GCKeyCodeF7] = 0x40;
|
||||
kb_map[GCKeyCodeF8] = 0x41;
|
||||
kb_map[GCKeyCodeF9] = 0x42;
|
||||
kb_map[GCKeyCodeF10] = 0x43;
|
||||
kb_map[GCKeyCodeF11] = 0x44;
|
||||
kb_map[GCKeyCodeF12] = 0x45;
|
||||
|
||||
//46-4E Control keys above cursor keys
|
||||
kb_map[GCKeyCodePrintScreen] = 0x46; // Print Screen
|
||||
kb_map[GCKeyCodeScrollLock] = 0x47; // Scroll Lock
|
||||
kb_map[GCKeyCodePause] = 0x48; // Pause
|
||||
kb_map[GCKeyCodeInsert] = 0x49; // Insert
|
||||
kb_map[GCKeyCodeHome] = 0x4A;
|
||||
kb_map[GCKeyCodePageUp] = 0x4B;
|
||||
kb_map[GCKeyCodeDeleteForward] = 0x4C;
|
||||
kb_map[GCKeyCodeEnd] = 0x4D;
|
||||
kb_map[GCKeyCodePageDown] = 0x4E;
|
||||
|
||||
//4F-52 Cursor keys
|
||||
kb_map[GCKeyCodeRightArrow] = 0x4F;
|
||||
kb_map[GCKeyCodeLeftArrow] = 0x50;
|
||||
kb_map[GCKeyCodeDownArrow] = 0x51;
|
||||
kb_map[GCKeyCodeUpArrow] = 0x52;
|
||||
|
||||
//53 Num Lock (Numeric keypad)
|
||||
kb_map[GCKeyCodeKeypadNumLock] = 0x53;
|
||||
//54 "/" (Numeric keypad)
|
||||
kb_map[GCKeyCodeKeypadSlash] = 0x54;
|
||||
//55 "*" (Numeric keypad)
|
||||
kb_map[GCKeyCodeKeypadAsterisk] = 0x55;
|
||||
//56 "-" (Numeric keypad)
|
||||
kb_map[GCKeyCodeKeypadHyphen] = 0x56;
|
||||
//57 "+" (Numeric keypad)
|
||||
kb_map[GCKeyCodeKeypadPlus] = 0x57;
|
||||
//58 Enter (Numeric keypad)
|
||||
kb_map[GCKeyCodeKeypadEnter] = 0x58;
|
||||
//59-62 Number keys 1-0 (Numeric keypad)
|
||||
kb_map[GCKeyCodeKeypad1] = 0x59;
|
||||
kb_map[GCKeyCodeKeypad2] = 0x5A;
|
||||
kb_map[GCKeyCodeKeypad3] = 0x5B;
|
||||
kb_map[GCKeyCodeKeypad4] = 0x5C;
|
||||
kb_map[GCKeyCodeKeypad5] = 0x5D;
|
||||
kb_map[GCKeyCodeKeypad6] = 0x5E;
|
||||
kb_map[GCKeyCodeKeypad7] = 0x5F;
|
||||
kb_map[GCKeyCodeKeypad8] = 0x60;
|
||||
kb_map[GCKeyCodeKeypad9] = 0x61;
|
||||
kb_map[GCKeyCodeKeypad0] = 0x62;
|
||||
//63 "." (Numeric keypad)
|
||||
kb_map[GCKeyCodeKeypadPeriod] = 0x63;
|
||||
//64 #| (non-US)
|
||||
//kb_map[94] = 0x64;
|
||||
//65 S3 key
|
||||
//66-A4 Not used
|
||||
//A5-DF Reserved
|
||||
kb_map[GCKeyCodeLeftControl] = 0xE0;
|
||||
kb_map[GCKeyCodeLeftShift] = 0xE1;
|
||||
kb_map[GCKeyCodeLeftAlt] = 0xE2; // Left Alt
|
||||
//E3 Left S1
|
||||
kb_map[GCKeyCodeRightControl] = 0xE4;
|
||||
kb_map[GCKeyCodeRightShift] = 0xE5;
|
||||
kb_map[GCKeyCodeRightAlt] = 0xE6; // Right Alt
|
||||
//E7 Right S3
|
||||
//E8-FF Reserved
|
||||
|
||||
// kb_map[kVK_ISO_Section] = 0x32; // #, Tilde
|
||||
|
||||
// Japanese keyboards
|
||||
// kb_map[kVK_JIS_Underscore] = 0x87; // I18n keyboard 1
|
||||
// kb_map[kVK_JIS_Yen] = 0x89; // I18n keyboard 3
|
||||
|
||||
[gcKeyboard.keyboardInput setKeyChangedHandler:^(GCKeyboardInput *keyboard, GCDeviceButtonInput *key, GCKeyCode keyCode, BOOL pressed) {
|
||||
keyboard_input(keyCode, pressed);
|
||||
}];
|
||||
|
||||
}
|
||||
|
||||
void set_maple_port(int port) override
|
||||
{
|
||||
KeyboardDevice::set_maple_port(port);
|
||||
}
|
||||
|
||||
static void addKeyboard(GCKeyboard *keyboard)
|
||||
{
|
||||
if (keyboards.count(keyboard) > 0)
|
||||
return;
|
||||
|
||||
int port = std::min((int)keyboards.size(), 3);
|
||||
keyboards[keyboard] = std::make_shared<IOSKeyboard>(port, keyboard);
|
||||
KeyboardDevice::Register(keyboards[keyboard]);
|
||||
}
|
||||
|
||||
static void removeKeyboard(GCKeyboard *keyboard)
|
||||
{
|
||||
auto it = keyboards.find(keyboard);
|
||||
if (it == keyboards.end())
|
||||
return;
|
||||
KeyboardDevice::Unregister(it->second);
|
||||
keyboards.erase(it);
|
||||
}
|
||||
|
||||
protected:
|
||||
u8 convert_keycode(UInt16 keycode) override
|
||||
{
|
||||
return kb_map[keycode];
|
||||
}
|
||||
|
||||
private:
|
||||
GCKeyboard * __weak gcKeyboard = nullptr;
|
||||
static std::map<GCKeyboard *, std::shared_ptr<IOSKeyboard>> keyboards;
|
||||
std::map<UInt16, u8> kb_map;
|
||||
};
|
|
@ -10,7 +10,8 @@ import Cocoa
|
|||
|
||||
class EmuGLView: NSOpenGLView, NSWindowDelegate {
|
||||
|
||||
var backingRect:NSRect?
|
||||
var backingRect: NSRect?
|
||||
var swapOnVSync = emu_vsync_enabled()
|
||||
|
||||
override var acceptsFirstResponder: Bool {
|
||||
return true;
|
||||
|
@ -20,19 +21,22 @@ class EmuGLView: NSOpenGLView, NSWindowDelegate {
|
|||
super.draw(dirtyRect)
|
||||
backingRect = convertToBacking(dirtyRect)
|
||||
|
||||
if emu_fast_forward() == false {
|
||||
if swapOnVSync {
|
||||
draw()
|
||||
}
|
||||
}
|
||||
|
||||
func draw() {
|
||||
var sync: GLint = emu_fast_forward() ? 0 : 1
|
||||
CGLSetParameter(openGLContext!.cglContextObj!, kCGLCPSwapInterval, &sync)
|
||||
if swapOnVSync == (emu_fast_forward() || !emu_vsync_enabled()) {
|
||||
swapOnVSync = (!emu_fast_forward() && emu_vsync_enabled())
|
||||
var sync: GLint = swapOnVSync ? 1 : 0
|
||||
CGLSetParameter(openGLContext!.cglContextObj!, kCGLCPSwapInterval, &sync)
|
||||
}
|
||||
|
||||
if let backingRect = backingRect {
|
||||
openGLContext!.makeCurrentContext()
|
||||
if (emu_single_frame(Int32(backingRect.width), Int32(backingRect.height)) != 0) {
|
||||
openGLContext!.flushBuffer()
|
||||
if emu_single_frame(Int32(backingRect.width), Int32(backingRect.height)) {
|
||||
openGLContext!.flushBuffer() //Swap for macOS
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -80,11 +84,11 @@ class EmuGLView: NSOpenGLView, NSWindowDelegate {
|
|||
if (!emu_renderer_enabled()) {
|
||||
NSApplication.shared.terminate(self)
|
||||
}
|
||||
else if (emu_frame_pending()) {
|
||||
if emu_fast_forward() {
|
||||
self.draw()
|
||||
} else {
|
||||
else if emu_frame_pending() {
|
||||
if swapOnVSync {
|
||||
self.needsDisplay = true
|
||||
} else {
|
||||
self.draw()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,7 +19,8 @@ void emu_dc_term();
|
|||
void emu_gui_open_settings();
|
||||
bool emu_renderer_enabled();
|
||||
bool emu_fast_forward();
|
||||
int emu_single_frame(int w, int h);
|
||||
bool emu_vsync_enabled();
|
||||
bool emu_single_frame(int w, int h);
|
||||
void emu_gles_init(int width, int height);
|
||||
int emu_reicast_init();
|
||||
void emu_key_input(UInt16 keyCode, bool pressed, UInt32 modifierFlags);
|
||||
|
|
|
@ -131,14 +131,27 @@ bool emu_fast_forward()
|
|||
return settings.input.fastForwardMode;
|
||||
}
|
||||
|
||||
int emu_single_frame(int w, int h)
|
||||
bool emu_vsync_enabled()
|
||||
{
|
||||
if (!emu_frame_pending())
|
||||
return 0;
|
||||
return config::VSync;
|
||||
}
|
||||
|
||||
bool emu_single_frame(int w, int h)
|
||||
{
|
||||
screen_width = w;
|
||||
screen_height = h;
|
||||
return (int)mainui_rend_frame();
|
||||
|
||||
//For DelayFrameSwapping: use while loop to call multple mainui_rend_frame() until rend_swap_frame(u32 fb_r_sof1)
|
||||
int counter = 0;
|
||||
while (mainui_enabled && counter < 5)
|
||||
{
|
||||
counter++;
|
||||
if (mainui_rend_frame())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void emu_gles_init(int width, int height)
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
class Sdl2 < Formula
|
||||
desc "Low-level access to audio, keyboard, mouse, joystick, and graphics"
|
||||
homepage "https://www.libsdl.org/"
|
||||
url "https://libsdl.org/release/SDL2-2.0.14.tar.gz"
|
||||
sha256 "d8215b571a581be1332d2106f8036fcb03d12a70bae01e20f424976d275432bc"
|
||||
url "https://libsdl.org/release/SDL2-2.0.16.tar.gz"
|
||||
sha256 "65be9ff6004034b5b2ce9927b5a4db1814930f169c4b2dae0a1e4697075f287b"
|
||||
license "Zlib"
|
||||
revision 1
|
||||
env :std
|
||||
|
@ -13,10 +13,10 @@ class Sdl2 < Formula
|
|||
end
|
||||
|
||||
bottle do
|
||||
sha256 cellar: :any, arm64_big_sur: "2ae70b6025c4e241400643f2686c8e288d50e3f04311e63d8a1f8180ed4afb07"
|
||||
sha256 cellar: :any, big_sur: "ccde7145d4334d9274f9588e6b841bf3749729682e1d25f590bdcf7994dfdd89"
|
||||
sha256 cellar: :any, catalina: "d6ae3300160c5bb495b78a5c5c0fc995f9e797e9cdd4b04ef77d59d45d2d694d"
|
||||
sha256 cellar: :any, mojave: "4f3988fb3af0f370bc1648d6eb1d6573fd37381df0f3b9ee0874a49d6a7dec2e"
|
||||
sha256 cellar: :any, arm64_big_sur: "6adac3ca2899ab923427b9b9322c8a4a412485ac7fe6448e276b4aae598f7a49"
|
||||
sha256 cellar: :any, big_sur: "71fe247bc197133b02186fac4e8f296d7f457a9507e0c77357b1069e5ee2ca61"
|
||||
sha256 cellar: :any, catalina: "4634185a35d9fc37c8fc07f884e45e7e2fbaa3fdec615171e647a9e02c395bd4"
|
||||
sha256 cellar: :any, mojave: "9966890d7d39147e75e92d6a7390ef5fb2f043b08f913e751638bdeef8c1c220"
|
||||
end
|
||||
|
||||
head do
|
||||
|
|
|
@ -1394,7 +1394,7 @@ static void retro_vk_context_destroy()
|
|||
|
||||
static bool set_vulkan_hw_render()
|
||||
{
|
||||
retro_hw_render_callback hw_render;
|
||||
retro_hw_render_callback hw_render{};
|
||||
hw_render.context_type = RETRO_HW_CONTEXT_VULKAN;
|
||||
hw_render.version_major = VK_API_VERSION_1_0;
|
||||
hw_render.version_minor = 0;
|
||||
|
|
Loading…
Reference in New Issue