Fix Windows CI (linux still bork)

Update unarr
Add new log options
Minor improvements
This commit is contained in:
SimoneN64
2023-06-12 18:32:13 +02:00
parent 6a7f2e144c
commit 9242fe986f
22 changed files with 157 additions and 174 deletions

View File

@@ -9,14 +9,11 @@ jobs:
submodules: recursive submodules: recursive
- name: Install dependencies - name: Install dependencies
run: | run: |
sudo add-apt-repository universe
sudo apt-get update -qq sudo apt-get update -qq
sudo apt-get install -y build-essential libgtk-3-dev libsdl2-dev git ninja-build nlohmann-json3-dev sudo apt-get install -y build-essential libgtk-3-dev libsdl2-dev git ninja-build nlohmann-json3-dev libfmt-dev
sudo apt-get install -y vulkan-tools libvulkan1 libvulkan-dev vulkan-validationlayers-dev spirv-tools libsfml-dev sudo apt-get install -y vulkan-tools libvulkan1 libvulkan-dev vulkan-validationlayers-dev spirv-tools libsfml-dev
git clone --recursive https://github.com/fmtlib/fmt
cd fmt
cmake -B build -DFMT_TEST=OFF
cd build
sudo make install
git clone --recursive https://github.com/mandreyel/mio git clone --recursive https://github.com/mandreyel/mio
cd mio cd mio
cmake -B build -DBUILD_TESTING=False -DCMAKE_BUILD_TYPE=Release cmake -B build -DBUILD_TESTING=False -DCMAKE_BUILD_TYPE=Release

View File

@@ -55,6 +55,7 @@ endif()
add_subdirectory(frontend) add_subdirectory(frontend)
add_subdirectory(frontend/imgui) add_subdirectory(frontend/imgui)
add_subdirectory(backend) add_subdirectory(backend)
add_subdirectory(backend/netplay)
add_subdirectory(backend/core) add_subdirectory(backend/core)
add_subdirectory(backend/core/interpreter) add_subdirectory(backend/core/interpreter)
add_subdirectory(backend/core/mem) add_subdirectory(backend/core/mem)

View File

@@ -1,55 +1,8 @@
#include <Netplay.hpp> #include <Netplay.hpp>
#include "log.hpp" #include <log.hpp>
#include "PIF/Device.hpp"
#include <PIF.hpp> #include <PIF.hpp>
#include <array> #include <array>
namespace Netplay { namespace Netplay {
bool isHost = false;
bool connected = false; bool connected = false;
std::array<std::string, 4> IPs{};
template <int port>
n64::JoybusDevice RequestDataFromRemotePlayer() {
sf::UdpSocket sock;
u16 remotePort = 53000;
sf::IpAddress remoteAddress = IPs[port];
if(sock.bind(remotePort) != sf::Socket::Done) {
Util::panic("Could not bind UDP connection");
}
sf::Packet res;
if(sock.receive(res, remoteAddress, remotePort) != sf::Socket::Done) {
Util::panic("Could not receive data from other players");
}
n64::JoybusDevice result{};
result << res;
}
template <int port>
void SendDataToRemotePlayer() {
}
template <int port>
void SyncPlayers(n64::PIF& pif) {
if(connected) {
if(isHost) {
pif.PollController();
} else {
if constexpr (port == 0) {
Util::panic("It shouldn't be possible to be player 1 and not be the host");
} else {
if constexpr (port > 3) {
Util::panic("What the heeeeelll oh my gaaaa");
}
n64::players[port] = RequestDataFromRemotePlayer<port>();
}
}
}
}
template void SyncPlayers(n64::PIF&);
} }

View File

@@ -3,9 +3,5 @@
#include <PIF.hpp> #include <PIF.hpp>
namespace Netplay { namespace Netplay {
extern bool isHost;
extern bool connected; extern bool connected;
template <int port = 0>
void SyncPlayers(n64::PIF&);
} }

View File

@@ -6,7 +6,7 @@ namespace n64 {
#define AUDIO_SAMPLE_RATE 44100 #define AUDIO_SAMPLE_RATE 44100
#define SYSTEM_SAMPLE_FORMAT AUDIO_F32SYS #define SYSTEM_SAMPLE_FORMAT AUDIO_F32SYS
#define SYSTEM_SAMPLE_SIZE 4 #define SYSTEM_SAMPLE_SIZE 4
#define BYTES_PER_HALF_SECOND ((AUDIO_SAMPLE_RATE / 2) * SYSTEM_SAMPLE_SIZE) #define BYTES_PER_HALF_SECOND (((float)AUDIO_SAMPLE_RATE / 2) * SYSTEM_SAMPLE_SIZE)
static SDL_AudioStream* audioStream = nullptr; static SDL_AudioStream* audioStream = nullptr;
SDL_mutex* audioStreamMutex; SDL_mutex* audioStreamMutex;
@@ -70,7 +70,7 @@ void PushSample(float left, float volumeL, float right, float volumeR) {
float adjustedR = right * volumeR; float adjustedR = right * volumeR;
float samples[2]{ adjustedL, adjustedR }; float samples[2]{ adjustedL, adjustedR };
int availableBytes = SDL_AudioStreamAvailable(audioStream); float availableBytes = SDL_AudioStreamAvailable(audioStream);
if(availableBytes <= BYTES_PER_HALF_SECOND) { if(availableBytes <= BYTES_PER_HALF_SECOND) {
SDL_AudioStreamPut(audioStream, samples, 2 * sizeof(float)); SDL_AudioStreamPut(audioStream, samples, 2 * sizeof(float));
} }

View File

@@ -32,8 +32,6 @@ auto AI::Read(u32 addr) const -> u32 {
return dmaLen[0]; return dmaLen[0];
} }
#define max(x, y) ((x) > (y) ? (x) : (y))
void AI::Write(Mem& mem, Registers& regs, u32 addr, u32 val) { void AI::Write(Mem& mem, Registers& regs, u32 addr, u32 val) {
switch(addr) { switch(addr) {
case 0x04500000: case 0x04500000:
@@ -43,8 +41,8 @@ void AI::Write(Mem& mem, Registers& regs, u32 addr, u32 val) {
break; break;
case 0x04500004: { case 0x04500004: {
u32 len = (val & 0x3FFFF) & ~7; u32 len = (val & 0x3FFFF) & ~7;
if((dmaCount < 2) && len) { if(dmaCount < 2) {
// if(dmaCount == 0) InterruptRaise(mem.mmio.mi, regs, Interrupt::AI); if(dmaCount == 0) InterruptRaise(mem.mmio.mi, regs, Interrupt::AI);
dmaLen[dmaCount] = len; dmaLen[dmaCount] = len;
dmaCount++; dmaCount++;
} }
@@ -58,7 +56,7 @@ void AI::Write(Mem& mem, Registers& regs, u32 addr, u32 val) {
case 0x04500010: { case 0x04500010: {
u32 old_dac_freq = dac.freq; u32 old_dac_freq = dac.freq;
dacRate = val & 0x3FFF; dacRate = val & 0x3FFF;
dac.freq = max(1, N64_CPU_FREQ / 2 / (dacRate + 1)) * 1.037; dac.freq = std::max(1u, GetVideoFrequency(mem.IsROMPAL()) / (dacRate + 1));
dac.period = N64_CPU_FREQ / dac.freq; dac.period = N64_CPU_FREQ / dac.freq;
if(old_dac_freq != dac.freq) { if(old_dac_freq != dac.freq) {
AdjustSampleRate(dac.freq); AdjustSampleRate(dac.freq);

View File

@@ -122,7 +122,7 @@ void PI::Write(Mem& mem, Registers& regs, u32 addr, u32 val) {
for (int i = 0; i < rdLen; i++) { for (int i = 0; i < rdLen; i++) {
mem.rom.cart[BYTE_ADDRESS(cartAddrInternal + i) & mem.rom.mask] = mem.mmio.rdp.rdram[BYTE_ADDRESS(dramAddrInternal + i) & RDRAM_DSIZE]; mem.rom.cart[BYTE_ADDRESS(cartAddrInternal + i) & mem.rom.mask] = mem.mmio.rdp.rdram[BYTE_ADDRESS(dramAddrInternal + i) & RDRAM_DSIZE];
} }
Util::debug("PI DMA from RDRAM to CARTRIDGE (size: {} B, {:08X} to {:08X})", len, dramAddr, cartAddr); Util::trace("PI DMA from RDRAM to CARTRIDGE (size: {} B, {:08X} to {:08X})", len, dramAddr, cartAddr);
dmaBusy = true; dmaBusy = true;
ioBusy = true; ioBusy = true;
scheduler.enqueueRelative(Event{PIAccessTiming(*this, PIGetDomain(cartAddr), len), OnDMAComplete<true>}); scheduler.enqueueRelative(Event{PIAccessTiming(*this, PIGetDomain(cartAddr), len), OnDMAComplete<true>});
@@ -140,7 +140,7 @@ void PI::Write(Mem& mem, Registers& regs, u32 addr, u32 val) {
} }
dmaBusy = true; dmaBusy = true;
ioBusy = true; ioBusy = true;
Util::debug("PI DMA from CARTRIDGE to RDRAM (size: {} B, {:08X} to {:08X})", len, cartAddr, dramAddr); Util::trace("PI DMA from CARTRIDGE to RDRAM (size: {} B, {:08X} to {:08X})", len, cartAddr, dramAddr);
scheduler.enqueueRelative(Event{PIAccessTiming(*this, PIGetDomain(cartAddr), len), OnDMAComplete<false>}); scheduler.enqueueRelative(Event{PIAccessTiming(*this, PIGetDomain(cartAddr), len), OnDMAComplete<false>});
} break; } break;
case 0x04600010: case 0x04600010:

View File

@@ -6,7 +6,6 @@
#include <cic_nus_6105/n64_cic_nus_6105.hpp> #include <cic_nus_6105/n64_cic_nus_6105.hpp>
#include <cassert> #include <cassert>
#include <Netplay.hpp> #include <Netplay.hpp>
#include <PIF/Device.hpp>
#define MEMPAK_SIZE 32768 #define MEMPAK_SIZE 32768
@@ -207,10 +206,7 @@ void PIF::ProcessCommands(Mem &mem) {
break; break;
case 7: case 7:
switch(cmd[CMD_START]) { switch(cmd[CMD_START]) {
case 0: case 3: case 0: case 1: case 3:
for(int i = 0; i < 8; i++) {
res[i] = 0;
}
break; break;
case 2: { case 2: {
auto now = std::time(nullptr); auto now = std::time(nullptr);
@@ -332,21 +328,11 @@ void PIF::EepromWrite(const u8* cmd, u8* res, const Mem& mem) {
} }
void PIF::UpdateController() { void PIF::UpdateController() {
joybusDevices[channel].controller.a = players[channel].controller.a; if(Netplay::connected) {
joybusDevices[channel].controller.b = players[channel].controller.b; Util::panic("Netplay!!!");
joybusDevices[channel].controller.z = players[channel].controller.z; } else {
joybusDevices[channel].controller.start = players[channel].controller.start; PollController();
joybusDevices[channel].controller.dp_up = players[channel].controller.dp_up; }
joybusDevices[channel].controller.dp_down = players[channel].controller.dp_down;
joybusDevices[channel].controller.dp_left = players[channel].controller.dp_left;
joybusDevices[channel].controller.dp_right = players[channel].controller.dp_right;
joybusDevices[channel].controller.joy_reset = players[channel].controller.joy_reset;
joybusDevices[channel].controller.l = players[channel].controller.l;
joybusDevices[channel].controller.r = players[channel].controller.r;
joybusDevices[channel].controller.c_up = players[channel].controller.c_up;
joybusDevices[channel].controller.c_down = players[channel].controller.c_down;
joybusDevices[channel].controller.c_left = players[channel].controller.c_left;
joybusDevices[channel].controller.c_right = players[channel].controller.c_right;
} }
void PIF::DoPIFHLE(Mem& mem, Registers& regs, bool pal, CICType cicType) { void PIF::DoPIFHLE(Mem& mem, Registers& regs, bool pal, CICType cicType) {

View File

@@ -10,7 +10,7 @@ namespace fs = std::filesystem;
namespace n64 { namespace n64 {
enum AccessoryType { enum AccessoryType : u8 {
ACCESSORY_NONE, ACCESSORY_NONE,
ACCESSORY_MEMPACK, ACCESSORY_MEMPACK,
ACCESSORY_RUMBLE_PACK ACCESSORY_RUMBLE_PACK
@@ -18,7 +18,7 @@ enum AccessoryType {
struct Controller { struct Controller {
union { union {
u8 byte1; u8 byte1{};
struct { struct {
bool dp_right:1; bool dp_right:1;
bool dp_left:1; bool dp_left:1;
@@ -31,7 +31,7 @@ struct Controller {
}; };
}; };
union { union {
u8 byte2; u8 byte2{};
struct { struct {
bool c_right:1; bool c_right:1;
bool c_left:1; bool c_left:1;
@@ -45,11 +45,21 @@ struct Controller {
}; };
s8 joy_x{}; s8 joy_x{};
s8 joy_y{}; s8 joy_y{};
Controller() = default;
Controller& operator=(u32 v) {
joy_y = v & 0xff;
joy_x = v >> 8;
byte2 = v >> 16;
byte1 = v >> 24;
return *this;
}
}; };
static_assert(sizeof(Controller) == 4); static_assert(sizeof(Controller) == 4);
enum JoybusType { enum JoybusType : u8 {
JOYBUS_NONE, JOYBUS_NONE,
JOYBUS_CONTROLLER, JOYBUS_CONTROLLER,
JOYBUS_DANCEPAD, JOYBUS_DANCEPAD,
@@ -66,8 +76,12 @@ struct JoybusDevice {
AccessoryType accessoryType{}; AccessoryType accessoryType{};
Controller controller{}; Controller controller{};
auto operator<<(const sf::Packet& packet) { JoybusDevice() = default;
explicit JoybusDevice(const u64& packet) {
type = static_cast<JoybusType>(packet >> offsetof(JoybusDevice, type));
accessoryType = static_cast<AccessoryType>((packet >> offsetof(JoybusDevice, accessoryType)) & 0xff);
controller = packet >> offsetof(JoybusDevice, controller);
} }
}; };

View File

@@ -1,13 +1,10 @@
#include <PIF.hpp> #include <PIF.hpp>
#include <MupenMovie.hpp> #include <MupenMovie.hpp>
#include <PIF/Device.hpp>
#include <Netplay.hpp> #include <Netplay.hpp>
#include "log.hpp" #include <log.hpp>
#include <SDL2/SDL_keyboard.h> #include <SDL2/SDL_keyboard.h>
namespace n64 { namespace n64 {
JoybusDevice players[4]{};
void PIF::InitDevices(SaveType saveType) { void PIF::InitDevices(SaveType saveType) {
for (int i = 0; i < 4; i++) { //TODO: make this configurable for (int i = 0; i < 4; i++) { //TODO: make this configurable
joybusDevices[i].type = JOYBUS_CONTROLLER; joybusDevices[i].type = JOYBUS_CONTROLLER;
@@ -44,21 +41,21 @@ void PIF::PollController() {
bool CLEFT = GET_AXIS(gamepad, SDL_CONTROLLER_AXIS_RIGHTX) <= -127; bool CLEFT = GET_AXIS(gamepad, SDL_CONTROLLER_AXIS_RIGHTX) <= -127;
bool CRIGHT = GET_AXIS(gamepad, SDL_CONTROLLER_AXIS_RIGHTX) >= 127; bool CRIGHT = GET_AXIS(gamepad, SDL_CONTROLLER_AXIS_RIGHTX) >= 127;
players[0].controller.a = A; joybusDevices[channel].controller.a = A;
players[0].controller.b = B; joybusDevices[channel].controller.b = B;
players[0].controller.z = Z; joybusDevices[channel].controller.z = Z;
players[0].controller.start = START; joybusDevices[channel].controller.start = START;
players[0].controller.dp_up = DUP; joybusDevices[channel].controller.dp_up = DUP;
players[0].controller.dp_down = DDOWN; joybusDevices[channel].controller.dp_down = DDOWN;
players[0].controller.dp_left = DLEFT; joybusDevices[channel].controller.dp_left = DLEFT;
players[0].controller.dp_right = DRIGHT; joybusDevices[channel].controller.dp_right = DRIGHT;
players[0].controller.joy_reset = L && R && START; joybusDevices[channel].controller.joy_reset = L && R && START;
players[0].controller.l = L; joybusDevices[channel].controller.l = L;
players[0].controller.r = R; joybusDevices[channel].controller.r = R;
players[0].controller.c_up = CUP; joybusDevices[channel].controller.c_up = CUP;
players[0].controller.c_down = CDOWN; joybusDevices[channel].controller.c_down = CDOWN;
players[0].controller.c_left = CLEFT; joybusDevices[channel].controller.c_left = CLEFT;
players[0].controller.c_right = CRIGHT; joybusDevices[channel].controller.c_right = CRIGHT;
float xclamped = GET_AXIS(gamepad, SDL_CONTROLLER_AXIS_LEFTX); float xclamped = GET_AXIS(gamepad, SDL_CONTROLLER_AXIS_LEFTX);
if(xclamped < 0) { if(xclamped < 0) {
@@ -78,31 +75,31 @@ void PIF::PollController() {
yclamped *= 86; yclamped *= 86;
players[0].controller.joy_x = xclamped; joybusDevices[channel].controller.joy_x = xclamped;
players[0].controller.joy_y = -yclamped; joybusDevices[channel].controller.joy_y = -yclamped;
if (players[0].controller.joy_reset) { if (joybusDevices[channel].controller.joy_reset) {
players[0].controller.start = false; joybusDevices[channel].controller.start = false;
players[0].controller.joy_x = 0; joybusDevices[channel].controller.joy_x = 0;
players[0].controller.joy_y = 0; joybusDevices[channel].controller.joy_y = 0;
} }
} else { } else {
const uint8_t* state = SDL_GetKeyboardState(nullptr); const uint8_t* state = SDL_GetKeyboardState(nullptr);
players[0].controller.a = state[SDL_SCANCODE_X]; joybusDevices[channel].controller.a = state[SDL_SCANCODE_X];
players[0].controller.b = state[SDL_SCANCODE_C]; joybusDevices[channel].controller.b = state[SDL_SCANCODE_C];
players[0].controller.z = state[SDL_SCANCODE_Z]; joybusDevices[channel].controller.z = state[SDL_SCANCODE_Z];
players[0].controller.start = state[SDL_SCANCODE_RETURN]; joybusDevices[channel].controller.start = state[SDL_SCANCODE_RETURN];
players[0].controller.dp_up = state[SDL_SCANCODE_PAGEUP]; joybusDevices[channel].controller.dp_up = state[SDL_SCANCODE_PAGEUP];
players[0].controller.dp_down = state[SDL_SCANCODE_PAGEDOWN]; joybusDevices[channel].controller.dp_down = state[SDL_SCANCODE_PAGEDOWN];
players[0].controller.dp_left = state[SDL_SCANCODE_HOME]; joybusDevices[channel].controller.dp_left = state[SDL_SCANCODE_HOME];
players[0].controller.dp_right = state[SDL_SCANCODE_END]; joybusDevices[channel].controller.dp_right = state[SDL_SCANCODE_END];
players[0].controller.joy_reset = state[SDL_SCANCODE_RETURN] && state[SDL_SCANCODE_A] && state[SDL_SCANCODE_S]; joybusDevices[channel].controller.joy_reset = state[SDL_SCANCODE_RETURN] && state[SDL_SCANCODE_A] && state[SDL_SCANCODE_S];
players[0].controller.l = state[SDL_SCANCODE_A]; joybusDevices[channel].controller.l = state[SDL_SCANCODE_A];
players[0].controller.r = state[SDL_SCANCODE_S]; joybusDevices[channel].controller.r = state[SDL_SCANCODE_S];
players[0].controller.c_up = state[SDL_SCANCODE_I]; joybusDevices[channel].controller.c_up = state[SDL_SCANCODE_I];
players[0].controller.c_down = state[SDL_SCANCODE_K]; joybusDevices[channel].controller.c_down = state[SDL_SCANCODE_K];
players[0].controller.c_left = state[SDL_SCANCODE_J]; joybusDevices[channel].controller.c_left = state[SDL_SCANCODE_J];
players[0].controller.c_right = state[SDL_SCANCODE_L]; joybusDevices[channel].controller.c_right = state[SDL_SCANCODE_L];
s16 xaxis = 0, yaxis = 0; s16 xaxis = 0, yaxis = 0;
if (state[SDL_SCANCODE_LEFT]) { if (state[SDL_SCANCODE_LEFT]) {
@@ -117,13 +114,13 @@ void PIF::PollController() {
yaxis = 86; yaxis = 86;
} }
players[0].controller.joy_x = xaxis; joybusDevices[channel].controller.joy_x = xaxis;
players[0].controller.joy_y = yaxis; joybusDevices[channel].controller.joy_y = yaxis;
if (players[0].controller.joy_reset) { if (joybusDevices[channel].controller.joy_reset) {
players[0].controller.start = false; joybusDevices[channel].controller.start = false;
players[0].controller.joy_x = 0; joybusDevices[channel].controller.joy_x = 0;
players[0].controller.joy_y = 0; joybusDevices[channel].controller.joy_y = 0;
} }
} }
} }

View File

@@ -1,7 +0,0 @@
#pragma once
namespace n64 {
struct JoybusDevice;
extern JoybusDevice players[4];
}

View File

@@ -0,0 +1,4 @@
file(GLOB SOURCES *.cpp)
file(GLOB HEADERS *.hpp)
add_library(netplay ${SOURCES} ${HEADERS})

View File

@@ -0,0 +1,5 @@
#include <Netplay.hpp>
namespace Netplay {
}

View File

@@ -27,6 +27,14 @@ static FORCE_INLINE constexpr u32 GetCyclesPerFrame(bool pal) {
} }
} }
static FORCE_INLINE constexpr u32 GetVideoFrequency(bool pal) {
if (pal) {
return 49'656'530;
} else {
return 48'681'812;
}
}
#define HALF_ADDRESS(addr) ((addr) ^ 2) #define HALF_ADDRESS(addr) ((addr) ^ 2)
#define BYTE_ADDRESS(addr) ((addr) ^ 3) #define BYTE_ADDRESS(addr) ((addr) ^ 3)

View File

@@ -48,20 +48,14 @@ void App::Run() {
case SDL_KEYDOWN: case SDL_KEYDOWN:
switch (event.key.keysym.sym) { switch (event.key.keysym.sym) {
case SDLK_o: { case SDLK_o: {
nfdchar_t *outpath; OpenROMDialog(window, core);
const nfdu8filteritem_t filter{"Nintendo 64 roms/archives", "n64,z64,v64,N64,Z64,V64,zip,tar,rar,7z"};
nfdresult_t result = NFD_OpenDialog(&outpath, &filter, 1, nullptr);
if (result == NFD_OKAY) {
LoadROM(outpath);
NFD_FreePath(outpath);
}
} break; } break;
} }
break; break;
case SDL_DROPFILE: { case SDL_DROPFILE: {
char *droppedDir = event.drop.file; char *droppedDir = event.drop.file;
if (droppedDir) { if (droppedDir) {
LoadROM(droppedDir); window.LoadROM(core, droppedDir);
free(droppedDir); free(droppedDir);
} }
} break; } break;

View File

@@ -6,10 +6,6 @@ struct App {
App(); App();
~App() { Util::ClearRPC(); } ~App() { Util::ClearRPC(); }
void Run(); void Run();
FORCE_INLINE void LoadROM(const std::string& path) {
window.LoadROM(core, path);
}
private:
n64::Core core; n64::Core core;
Window window; Window window;
}; };

View File

@@ -70,6 +70,7 @@ Settings::~Settings() {
void Settings::RenderWidget(bool& show) { void Settings::RenderWidget(bool& show) {
if(show) { if(show) {
static float oldVolumeL = volumeL, oldVolumeR = volumeR;
ImGui::OpenPopup("Settings"); ImGui::OpenPopup("Settings");
if(ImGui::BeginPopupModal("Settings", &show)) { if(ImGui::BeginPopupModal("Settings", &show)) {
enum class SelectedSetting { Audio, COUNT }; enum class SelectedSetting { Audio, COUNT };
@@ -80,15 +81,36 @@ void Settings::RenderWidget(bool& show) {
switch (selectedSetting) { switch (selectedSetting) {
case SelectedSetting::Audio: case SelectedSetting::Audio:
ImGui::Checkbox("Lock channels", &lockChannels); ImGui::Checkbox("Lock channels", &lockChannels);
ImGui::SliderFloat("Volume L", &volumeL, 0, 1, "%.2f", ImGuiSliderFlags_NoInput); ImGui::Checkbox("Mute", &mute);
if (!lockChannels) { if(mute) {
ImGui::SliderFloat("Volume R", &volumeR, 0, 1, "%.2f", ImGuiSliderFlags_NoInput); volumeL = 0;
} else { volumeR = 0;
volumeR = volumeL;
ImGui::BeginDisabled(); ImGui::BeginDisabled();
ImGui::SliderFloat("Volume R", &volumeR, 0, 1, "%.2f", ImGuiSliderFlags_NoInput); ImGui::SliderFloat("Volume L", &oldVolumeL, 0, 1, "%.2f", ImGuiSliderFlags_NoInput);
if (lockChannels) {
oldVolumeR = oldVolumeL;
}
ImGui::SliderFloat("Volume R", &oldVolumeR, 0, 1, "%.2f", ImGuiSliderFlags_NoInput);
ImGui::EndDisabled(); ImGui::EndDisabled();
} else {
volumeL = oldVolumeL;
volumeR = oldVolumeR;
ImGui::SliderFloat("Volume L", &volumeL, 0, 1, "%.2f", ImGuiSliderFlags_NoInput);
if (!lockChannels) {
ImGui::SliderFloat("Volume R", &volumeR, 0, 1, "%.2f", ImGuiSliderFlags_NoInput);
} else {
volumeR = volumeL;
ImGui::BeginDisabled();
ImGui::SliderFloat("Volume R", &volumeR, 0, 1, "%.2f", ImGuiSliderFlags_NoInput);
ImGui::EndDisabled();
}
oldVolumeL = volumeL;
oldVolumeR = volumeR;
} }
break; break;
case SelectedSetting::COUNT: case SelectedSetting::COUNT:
Util::panic("BRUH"); Util::panic("BRUH");

View File

@@ -17,5 +17,6 @@ struct Settings {
private: private:
float volumeL = 0.0, volumeR = 0.0; float volumeL = 0.0, volumeR = 0.0;
bool lockChannels = true; bool lockChannels = true;
bool mute = false;
json settings; json settings;
}; };

View File

@@ -1,6 +1,5 @@
#include <filesystem> #include <filesystem>
#include <Window.hpp> #include <Window.hpp>
#include <nfd.hpp>
#include <Core.hpp> #include <Core.hpp>
#include <Audio.hpp> #include <Audio.hpp>
#include <SDL2/SDL.h> #include <SDL2/SDL.h>
@@ -171,14 +170,7 @@ void Window::RenderMainMenuBar(n64::Core &core) {
if (ImGui::BeginMenu("File")) { if (ImGui::BeginMenu("File")) {
if (ImGui::MenuItem("Open", "O")) { if (ImGui::MenuItem("Open", "O")) {
nfdchar_t *outpath; OpenROMDialog(*this, core);
const nfdu8filteritem_t filter{"Nintendo 64 roms", "n64,z64,v64,N64,Z64,V64"};
nfdresult_t result = NFD_OpenDialog(&outpath, &filter, 1, nullptr);
if (result == NFD_OKAY) {
LoadROM(core, outpath);
Util::UpdateRPC(Util::Playing, gameName);
NFD_FreePath(outpath);
}
} }
if (ImGui::MenuItem("Dump RDRAM")) { if (ImGui::MenuItem("Dump RDRAM")) {
core.cpu.mem.DumpRDRAM(); core.cpu.mem.DumpRDRAM();

View File

@@ -6,6 +6,8 @@
#include <SDL2/SDL.h> #include <SDL2/SDL.h>
#include <vector> #include <vector>
#include <frontend/imgui/Settings.hpp> #include <frontend/imgui/Settings.hpp>
#include <nfd.hpp>
#include "Discord.hpp"
struct Window { struct Window {
explicit Window(n64::Core& core); explicit Window(n64::Core& core);
@@ -17,12 +19,12 @@ struct Window {
Settings settings; Settings settings;
void LoadROM(n64::Core& core, const std::string& path); void LoadROM(n64::Core& core, const std::string& path);
bool done = false; bool done = false;
std::string gameName{};
private: private:
bool showSettings = false; bool showSettings = false;
SDL_Window* window{}; SDL_Window* window{};
std::string windowTitle{"Kaizen"}; std::string windowTitle{"Kaizen"};
std::string shadowWindowTitle{windowTitle}; std::string shadowWindowTitle{windowTitle};
std::string gameName{};
void InitSDL(); void InitSDL();
void InitImgui(); void InitImgui();
void Render(n64::Core& core); void Render(n64::Core& core);
@@ -38,3 +40,13 @@ private:
u32 minImageCount = 2; u32 minImageCount = 2;
}; };
static void FORCE_INLINE OpenROMDialog(Window& window, n64::Core& core) {
nfdchar_t *outpath;
const nfdu8filteritem_t filter{"Nintendo 64 roms/archives", "n64,z64,v64,N64,Z64,V64,zip,tar,rar,7z"};
nfdresult_t result = NFD_OpenDialog(&outpath, &filter, 1, nullptr);
if (result == NFD_OKAY) {
window.LoadROM(core, outpath);
NFD_FreePath(outpath);
}
}

View File

@@ -8,7 +8,7 @@ int main(int argc, char** argv) {
if(argc > 2) { if(argc > 2) {
LoadTAS(argv[2]); LoadTAS(argv[2]);
} }
app->LoadROM(argv[1]); app->window.LoadROM(app->core, argv[1]);
} }
app->Run(); app->Run();

View File

@@ -8,7 +8,11 @@ enum LogLevel : u8 {
Trace, Info, Debug, Warn, Error Trace, Info, Debug, Warn, Error
}; };
#ifndef _NDEBUG
static constexpr auto globalLogLevel = Debug;
#else
static constexpr auto globalLogLevel = Warn; static constexpr auto globalLogLevel = Warn;
#endif
template <LogLevel messageType = Info, typename ...Args> template <LogLevel messageType = Info, typename ...Args>
constexpr void print(const std::string& fmt, Args... args) { constexpr void print(const std::string& fmt, Args... args) {
@@ -43,6 +47,11 @@ constexpr void panic(const std::string& fmt, Args... args) {
exit(-1); exit(-1);
} }
template <typename ...Args>
constexpr void error(const std::string& fmt, Args... args) {
print<Error>(fmt + "\n", args...);
}
template <typename ...Args> template <typename ...Args>
constexpr void warn(const std::string& fmt, Args... args) { constexpr void warn(const std::string& fmt, Args... args) {
print<Warn>(fmt + "\n", args...); print<Warn>(fmt + "\n", args...);
@@ -57,4 +66,9 @@ template <typename ...Args>
constexpr void debug(const std::string& fmt, Args... args) { constexpr void debug(const std::string& fmt, Args... args) {
print<Debug>(fmt + "\n", args...); print<Debug>(fmt + "\n", args...);
} }
template <typename ...Args>
constexpr void trace(const std::string& fmt, Args... args) {
print<Trace>(fmt + "\n", args...);
}
} }