Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions bsnes/sfc/cartridge/cartridge.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -158,4 +158,21 @@ auto Cartridge::unload() -> void {
ram.reset();
}

auto Cartridge::getSaveRAM() -> uint8_t* {
return ram.data();
}

auto Cartridge::getSaveRAMSize() -> size_t {
return ram.size();
}


auto Cartridge::getROM() -> uint8_t* {
return rom.data();
}

auto Cartridge::getROMSize() -> size_t {
return rom.size();
}

}
4 changes: 4 additions & 0 deletions bsnes/sfc/cartridge/cartridge.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ struct Cartridge {
auto load() -> bool;
auto save() -> void;
auto unload() -> void;
auto getSaveRAM() -> uint8_t*;
auto getSaveRAMSize() -> size_t;
auto getROM() -> uint8_t*;
auto getROMSize() -> size_t;

auto serialize(serializer&) -> void;

Expand Down
8 changes: 7 additions & 1 deletion bsnes/sfc/dsp/SPC_DSP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -510,11 +510,16 @@ VOICE_CLOCK( V3c )
if ( !v->kon_delay )
run_envelope( v );
}

inline void SPC_DSP::voice_output( voice_t const* v, int ch )
{
// Apply left/right volume
int amp = (m.t_output * (int8_t) VREG(v->regs,voll + ch)) >> 7;


// Apply user volume if set
if (v->user_volume < 100) // 16384 / 100 is approx 163.84.
amp = (amp * v->user_volume * 164) >> 14;

// Add to output total
m.t_main_out [ch] += amp;
CLAMP16( m.t_main_out [ch] );
Expand Down Expand Up @@ -892,6 +897,7 @@ void SPC_DSP::load( uint8_t const regs [register_count] )
v->brr_offset = 1;
v->vbit = 1 << i;
v->regs = &m.regs [i * 0x10];
v->user_volume = 100;
}
m.new_kon = REG(kon);
m.t_dir = REG(dir);
Expand Down
3 changes: 3 additions & 0 deletions bsnes/sfc/dsp/SPC_DSP.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ class SPC_DSP {
// Reduces emulation accuracy.
enum { voice_count = 8 };
void mute_voices( int mask );

void set_user_volume( int voice_no, int volume_percent ){ m.voices[voice_no].user_volume = volume_percent; }

// State

Expand Down Expand Up @@ -118,6 +120,7 @@ class SPC_DSP {
int env; // current envelope level
int hidden_env; // used by GAIN mode 7, very obscure quirk
uint8_t t_envx_out;
int user_volume; // range: 0-100%
};
private:
enum { brr_block_size = 9 };
Expand Down
2 changes: 2 additions & 0 deletions bsnes/sfc/dsp/dsp.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ struct DSP {
auto serialize(serializer&) -> void;

int64 clock = 0;

auto get_spc_dsp() -> SPC_DSP* { return &spc_dsp ; }

private:
bool fastDSP = false;
Expand Down
2 changes: 2 additions & 0 deletions bsnes/sfc/interface/interface.hpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#pragma once

namespace SuperFamicom {

struct ID {
Expand Down
4 changes: 4 additions & 0 deletions bsnes/sfc/ppu-fast/io.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@ auto PPU::writeVRAM(uint8 data) -> void {
}
}

auto PPU::getVRAM() -> uint16* {
return vram;
}

auto PPU::readOAM(uint10 address) -> uint8 {
if(!io.displayDisable && cpu.vcounter() < vdisp()) address = latch.oamAddress;
return readObject(address);
Expand Down
1 change: 1 addition & 0 deletions bsnes/sfc/ppu-fast/ppu.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,7 @@ struct PPU : PPUcounter {
//io.cpp
auto latchCounters(uint hcounter, uint vcounter) -> void;
auto latchCounters() -> void;
auto getVRAM() -> uint16*;
alwaysinline auto vramAddress() const -> uint;
alwaysinline auto readVRAM() -> uint16;
template<bool Byte> alwaysinline auto writeVRAM(uint8 data) -> void;
Expand Down
4 changes: 4 additions & 0 deletions bsnes/sfc/ppu/io.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ auto PPU::writeVRAM(bool byte, uint8 data) -> void {
if(byte == 1) vram[address] = vram[address] & 0x00ff | data << 8;
}

auto PPU::getVRAM() -> uint16* {
return vram.data;
}

auto PPU::readOAM(uint10 addr) -> uint8 {
if(!io.displayDisable && vcounter() < vdisp()) addr = latch.oamAddress;
return obj.oam.read(addr);
Expand Down
1 change: 1 addition & 0 deletions bsnes/sfc/ppu/ppu.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ struct PPU : Thread, PPUcounter {
//io.cpp
auto latchCounters(uint hcounter, uint vcounter) -> void;
auto latchCounters() -> void;
auto getVRAM() -> uint16*;

//serialization.cpp
auto serialize(serializer&) -> void;
Expand Down
47 changes: 45 additions & 2 deletions bsnes/target-libretro/libretro.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ static void audio_queue(int16_t left, int16_t right)
}

#include "program.cpp"
#include <sfc/sfc.hpp>

static string sgb_bios;
static vector<string> cheatList;
Expand Down Expand Up @@ -642,6 +643,18 @@ static bool update_variables() // returns whether video dimensions have changed
emulator->configure("Hacks/PPU/Mode7/StrwinE", false);
}

strcpy(key, "bsnes_sndchan_volume_x");
var.key = key;
for (int i=0;i<8;i++)
{
key[strlen("bsnes_sndchan_volume_")] = '1'+i;
var.value = NULL;
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var))
{
SuperFamicom::dsp.get_spc_dsp()->set_user_volume( i, atoi(var.value) );
}
}

//override with setting overrides (BSO) if any
program->applySettingOverrides();

Expand Down Expand Up @@ -966,6 +979,7 @@ size_t retro_serialize_size()
bool retro_serialize(void *data, size_t size)
{
memcpy(data, emulator->serialize().data(), size);
update_variables(); // needed for custom volumes init
return true;
}

Expand Down Expand Up @@ -1068,6 +1082,8 @@ bool retro_load_game(const retro_game_info *game)
program->base_name = string(game->path);

program->load();

update_variables(); // needed for custom volumes init

emulator->connect(SuperFamicom::ID::Port::Controller1, SuperFamicom::ID::Device::Gamepad);
emulator->connect(SuperFamicom::ID::Port::Controller2, SuperFamicom::ID::Device::Gamepad);
Expand Down Expand Up @@ -1129,10 +1145,37 @@ unsigned retro_get_region()
// Rely on higan to load and save SRAM until there is really compelling reason not to.
void *retro_get_memory_data(unsigned id)
{
return nullptr;
switch(id)
{
case RETRO_MEMORY_SAVE_RAM:
return SuperFamicom::cartridge.getSaveRAM();
case RETRO_MEMORY_SYSTEM_RAM:
return SuperFamicom::cpu.wram;
case RETRO_MEMORY_VIDEO_RAM:
if(emulator->configuration("Hacks/PPU/Fast") == "true")
return SuperFamicom::ppufast.getVRAM();
else
return SuperFamicom::ppu.getVRAM();
case RETRO_MEMORY_ROM:
return SuperFamicom::cartridge.getROM();
}

return nullptr;
}

size_t retro_get_memory_size(unsigned id)
{
return 0;
switch(id)
{
case RETRO_MEMORY_SAVE_RAM:
return SuperFamicom::cartridge.getSaveRAMSize();
case RETRO_MEMORY_SYSTEM_RAM:
return 128 * 1024;
case RETRO_MEMORY_VIDEO_RAM:
return 64 * 1024;
case RETRO_MEMORY_ROM:
return SuperFamicom::cartridge.getROMSize();
}

return 0;
}
3 changes: 3 additions & 0 deletions bsnes/target-libretro/libretro.h
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,9 @@ enum retro_language
/* Video ram lets a frontend peek into a game systems video RAM (VRAM). */
#define RETRO_MEMORY_VIDEO_RAM 3

/* ROM lets a frontend peek into a game systems ROM. */
#define RETRO_MEMORY_ROM 4

/* Keysyms used for ID in input state callback when polling RETRO_KEYBOARD. */
enum retro_key
{
Expand Down
160 changes: 160 additions & 0 deletions bsnes/target-libretro/libretro_core_options.h
Original file line number Diff line number Diff line change
Expand Up @@ -830,6 +830,166 @@ struct retro_core_option_definition option_defs_us[] = {
},
"OFF"
},
{
"bsnes_sndchan_volume_1",
"Volume % for Sound Channel 1",
NULL,
{
{ "0", NULL },
{ "10", NULL },
{ "20", NULL },
{ "30", NULL },
{ "40", NULL },
{ "50", NULL },
{ "60", NULL },
{ "70", NULL },
{ "80", NULL },
{ "90", NULL },
{ "100", NULL },
{ NULL, NULL },
},
"100"
},
{
"bsnes_sndchan_volume_2",
"Volume % for Sound Channel 2",
NULL,
{
{ "0", NULL },
{ "10", NULL },
{ "20", NULL },
{ "30", NULL },
{ "40", NULL },
{ "50", NULL },
{ "60", NULL },
{ "70", NULL },
{ "80", NULL },
{ "90", NULL },
{ "100", NULL },
{ NULL, NULL },
},
"100"
},
{
"bsnes_sndchan_volume_3",
"Volume % for Sound Channel 3",
NULL,
{
{ "0", NULL },
{ "10", NULL },
{ "20", NULL },
{ "30", NULL },
{ "40", NULL },
{ "50", NULL },
{ "60", NULL },
{ "70", NULL },
{ "80", NULL },
{ "90", NULL },
{ "100", NULL },
{ NULL, NULL },
},
"100"
},
{
"bsnes_sndchan_volume_4",
"Volume % for Sound Channel 4",
NULL,
{
{ "0", NULL },
{ "10", NULL },
{ "20", NULL },
{ "30", NULL },
{ "40", NULL },
{ "50", NULL },
{ "60", NULL },
{ "70", NULL },
{ "80", NULL },
{ "90", NULL },
{ "100", NULL },
{ NULL, NULL },
},
"100"
},
{
"bsnes_sndchan_volume_5",
"Volume % for Sound Channel 5",
NULL,
{
{ "0", NULL },
{ "10", NULL },
{ "20", NULL },
{ "30", NULL },
{ "40", NULL },
{ "50", NULL },
{ "60", NULL },
{ "70", NULL },
{ "80", NULL },
{ "90", NULL },
{ "100", NULL },
{ NULL, NULL },
},
"100"
},
{
"bsnes_sndchan_volume_6",
"Volume % for Sound Channel 6",
NULL,
{
{ "0", NULL },
{ "10", NULL },
{ "20", NULL },
{ "30", NULL },
{ "40", NULL },
{ "50", NULL },
{ "60", NULL },
{ "70", NULL },
{ "80", NULL },
{ "90", NULL },
{ "100", NULL },
{ NULL, NULL },
},
"100"
},
{
"bsnes_sndchan_volume_7",
"Volume % for Sound Channel 7",
NULL,
{
{ "0", NULL },
{ "10", NULL },
{ "20", NULL },
{ "30", NULL },
{ "40", NULL },
{ "50", NULL },
{ "60", NULL },
{ "70", NULL },
{ "80", NULL },
{ "90", NULL },
{ "100", NULL },
{ NULL, NULL },
},
"100"
},
{
"bsnes_sndchan_volume_8",
"Volume % for Sound Channel 8",
NULL,
{
{ "0", NULL },
{ "10", NULL },
{ "20", NULL },
{ "30", NULL },
{ "40", NULL },
{ "50", NULL },
{ "60", NULL },
{ "70", NULL },
{ "80", NULL },
{ "90", NULL },
{ "100", NULL },
{ NULL, NULL },
},
"100"
},

{ NULL, NULL, NULL, {{0}}, NULL },
};
Expand Down