Restyling

This commit is contained in:
Sergio Martin 2024-01-20 11:21:34 +01:00
parent dec1772b7e
commit d8513ef867
97 changed files with 11312 additions and 10786 deletions

View File

@ -1,7 +1,7 @@
#pragma once
#include <utils.hpp>
#include "sha1/sha1.hpp"
#include <utils.hpp>
#define _LOW_MEM_SIZE 0x800
#define _HIGH_MEM_SIZE 0x2000
@ -14,7 +14,6 @@ static const uint16_t image_height = 240;
class EmuInstance
{
public:
typedef uint8_t inputType;
// Deleting default constructors
@ -65,14 +64,38 @@ class EmuInstance
std::string moveString = "|..|........|";
#endif
if (move & 0b00010000) moveString += 'U'; else moveString += '.';
if (move & 0b00100000) moveString += 'D'; else moveString += '.';
if (move & 0b01000000) moveString += 'L'; else moveString += '.';
if (move & 0b10000000) moveString += 'R'; else moveString += '.';
if (move & 0b00001000) moveString += 'S'; else moveString += '.';
if (move & 0b00000100) moveString += 's'; else moveString += '.';
if (move & 0b00000010) moveString += 'B'; else moveString += '.';
if (move & 0b00000001) moveString += 'A'; else moveString += '.';
if (move & 0b00010000)
moveString += 'U';
else
moveString += '.';
if (move & 0b00100000)
moveString += 'D';
else
moveString += '.';
if (move & 0b01000000)
moveString += 'L';
else
moveString += '.';
if (move & 0b10000000)
moveString += 'R';
else
moveString += '.';
if (move & 0b00001000)
moveString += 'S';
else
moveString += '.';
if (move & 0b00000100)
moveString += 's';
else
moveString += '.';
if (move & 0b00000010)
moveString += 'B';
else
moveString += '.';
if (move & 0b00000001)
moveString += 'A';
else
moveString += '.';
moveString += "|";
return moveString;
@ -161,7 +184,6 @@ inline void loadROMFile(const std::string& romFilePath)
virtual void *getInternalEmulatorPointer() const = 0;
protected:
EmuInstance() = default;
// Storage for the light state size
@ -174,7 +196,6 @@ inline void loadROMFile(const std::string& romFilePath)
bool _doRendering = true;
private:
// Storage for the ROM data
std::string _romData;

View File

@ -1,13 +1,13 @@
#pragma once
#include <string>
#include <unistd.h>
#include "emuInstance.hpp"
#include <SDL.h>
#include <SDL_image.h>
#include <utils.hpp>
#include <hqn/hqn.h>
#include <hqn/hqn_gui_controller.h>
#include "emuInstance.hpp"
#include <string>
#include <unistd.h>
#include <utils.hpp>
#define _INVERSE_FRAME_RATE 16667
@ -23,7 +23,6 @@ struct stepData_t
class PlaybackInstance
{
public:
void addStep(const std::string &input)
{
stepData_t step;
@ -223,9 +222,7 @@ const std::string getStateInput(const size_t stepId) const
return step.input;
}
private:
// Internal sequence information
std::vector<stepData_t> _stepSequence;

View File

@ -1,8 +1,8 @@
#include <cstdlib>
#include "argparse/argparse.hpp"
#include "utils.hpp"
#include "emuInstance.hpp"
#include "playbackInstance.hpp"
#include "utils.hpp"
#include <cstdlib>
#ifdef _USE_QUICKNES
#include "quickNESInstance.hpp"
@ -40,8 +40,14 @@ int main(int argc, char *argv[])
.implicit_value(true);
// Try to parse arguments
try { program.parse_args(argc, argv); }
catch (const std::runtime_error &err) { EXIT_WITH_ERROR("%s\n%s", err.what(), program.help().str().c_str()); }
try
{
program.parse_args(argc, argv);
}
catch (const std::runtime_error &err)
{
EXIT_WITH_ERROR("%s\n%s", err.what(), program.help().str().c_str());
}
// Getting ROM file path
std::string romFilePath = program.get<std::string>("romFile");
@ -186,4 +192,3 @@ int main(int argc, char *argv[])
// Ending ncurses window
finalizeTerminal();
}

View File

@ -24,7 +24,8 @@
#include "Nes_Mapper.h"
template <bool _is152>
class Mapper_74x161x162x32 : public Nes_Mapper {
class Mapper_74x161x162x32 : public Nes_Mapper
{
public:
Mapper_74x161x162x32()
{

View File

@ -13,7 +13,6 @@ extern void register_mapper_70();
class QuickNESInstance : public EmuInstance
{
public:
QuickNESInstance() : EmuInstance()
{
// Creating new emulator
@ -73,7 +72,6 @@ class QuickNESInstance : public EmuInstance
void *getInternalEmulatorPointer() const override { return _nes; }
private:
inline size_t getStateSizeImpl() const override
{
uint8_t *data = (uint8_t *)malloc(_DUMMY_SIZE);

View File

@ -15,16 +15,17 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
// Nes_Emu 0.7.0. http://www.slack.net/~ant/
#include <cstring>
#include <cstdint>
#include <cstdlib>
#include <cstring>
class Nes_Cart {
class Nes_Cart
{
public:
Nes_Cart() = default;
struct ines_header_t {
struct ines_header_t
{
uint8_t signature[4];
uint8_t prg_count; // number of 16K PRG banks
uint8_t chr_count; // number of 8K CHR banks
@ -40,7 +41,11 @@ void load_ines( const uint8_t* buffer )
ines_header_t h;
size_t bufferPos = 0;
{ size_t copySize = sizeof(ines_header_t); memcpy(&h, &buffer[bufferPos], copySize); bufferPos += copySize; }
{
size_t copySize = sizeof(ines_header_t);
memcpy(&h, &buffer[bufferPos], copySize);
bufferPos += copySize;
}
if (h.zero[7]) h.flags2 = 0;
set_mapper(h.flags, h.flags2);
@ -55,8 +60,16 @@ void load_ines( const uint8_t* buffer )
prg_ = (uint8_t *)p;
chr_ = &prg_[prg_size_];
{ size_t copySize = prg_size(); memcpy(prg(), &buffer[bufferPos], copySize); bufferPos += copySize; }
{ size_t copySize = chr_size(); memcpy(chr(), &buffer[bufferPos], copySize); bufferPos += copySize; }
{
size_t copySize = prg_size();
memcpy(prg(), &buffer[bufferPos], copySize);
bufferPos += copySize;
}
{
size_t copySize = chr_size();
memcpy(chr(), &buffer[bufferPos], copySize);
bufferPos += copySize;
}
}
inline bool has_battery_ram() const { return mapper & 0x02; }
@ -97,4 +110,3 @@ private:
long chr_size_;
unsigned mapper;
};

View File

@ -15,13 +15,12 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
// Nes_Emu 0.7.0
#include "Nes_Cpu.hpp"
#include "apu/apu.hpp"
#include "mappers/mapper.hpp"
#include "ppu/Nes_Ppu.hpp"
#include <cstdio>
#include <string>
#include "apu/apu.hpp"
#include "Nes_Cpu.hpp"
#include "ppu/Nes_Ppu.hpp"
#include "mappers/mapper.hpp"
class Nes_Cart;
@ -66,10 +65,11 @@ struct cpu_state_t
};
static_assert(sizeof(cpu_state_t) == 8);
class Nes_Core : private Nes_Cpu {
class Nes_Core : private Nes_Cpu
{
typedef Nes_Cpu cpu;
public:
public:
Nes_Core() : ppu(this)
{
cart = NULL;
@ -222,17 +222,22 @@ public:
headerCode = "NESS"; // NESS Block
blockSize = 0xFFFFFFFF;
memcpy(&buffer[pos], headerCode.data(), headerSize); pos += headerSize;
memcpy(&buffer[pos], &blockSize, headerSize); pos += headerSize;
memcpy(&buffer[pos], headerCode.data(), headerSize);
pos += headerSize;
memcpy(&buffer[pos], &blockSize, headerSize);
pos += headerSize;
headerCode = "TIME"; // TIME Block
nes_state_t state = nes;
state.timestamp *= 5;
blockSize = sizeof(nes_state_t);
dataSource = (void *)&state;
memcpy(&buffer[pos], headerCode.data(), headerSize); pos += headerSize;
memcpy(&buffer[pos], &blockSize, headerSize); pos += headerSize;
memcpy(&buffer[pos], dataSource, blockSize); pos += blockSize;
memcpy(&buffer[pos], headerCode.data(), headerSize);
pos += headerSize;
memcpy(&buffer[pos], &blockSize, headerSize);
pos += headerSize;
memcpy(&buffer[pos], dataSource, blockSize);
pos += blockSize;
headerCode = "CPUR"; // CPUR Block
cpu_state_t s;
@ -245,70 +250,97 @@ public:
s.p = r.status;
blockSize = sizeof(cpu_state_t);
dataSource = (void *)&s;
memcpy(&buffer[pos], headerCode.data(), headerSize); pos += headerSize;
memcpy(&buffer[pos], &blockSize, headerSize); pos += headerSize;
memcpy(&buffer[pos], dataSource, blockSize); pos += blockSize;
memcpy(&buffer[pos], headerCode.data(), headerSize);
pos += headerSize;
memcpy(&buffer[pos], &blockSize, headerSize);
pos += headerSize;
memcpy(&buffer[pos], dataSource, blockSize);
pos += blockSize;
headerCode = "PPUR"; // PPUR Block
blockSize = sizeof(ppu_state_t);
dataSource = (void *)&ppu;
memcpy(&buffer[pos], headerCode.data(), headerSize); pos += headerSize;
memcpy(&buffer[pos], &blockSize, headerSize); pos += headerSize;
memcpy(&buffer[pos], dataSource, blockSize); pos += blockSize;
memcpy(&buffer[pos], headerCode.data(), headerSize);
pos += headerSize;
memcpy(&buffer[pos], &blockSize, headerSize);
pos += headerSize;
memcpy(&buffer[pos], dataSource, blockSize);
pos += blockSize;
headerCode = "APUR"; // APUR Block
Nes_Apu::apu_state_t apuState;
impl->apu.save_state(&apuState);
blockSize = sizeof(Nes_Apu::apu_state_t);
memcpy(&buffer[pos], headerCode.data(), headerSize); pos += headerSize;
memcpy(&buffer[pos], &blockSize, headerSize); pos += headerSize;
memcpy(&buffer[pos], &apuState, blockSize); pos += blockSize;
memcpy(&buffer[pos], headerCode.data(), headerSize);
pos += headerSize;
memcpy(&buffer[pos], &blockSize, headerSize);
pos += headerSize;
memcpy(&buffer[pos], &apuState, blockSize);
pos += blockSize;
headerCode = "CTRL"; // CTRL Block
blockSize = sizeof(joypad_state_t);
dataSource = (void *)&joypad;
memcpy(&buffer[pos], headerCode.data(), headerSize); pos += headerSize;
memcpy(&buffer[pos], &blockSize, headerSize); pos += headerSize;
memcpy(&buffer[pos], dataSource, blockSize); pos += blockSize;
memcpy(&buffer[pos], headerCode.data(), headerSize);
pos += headerSize;
memcpy(&buffer[pos], &blockSize, headerSize);
pos += headerSize;
memcpy(&buffer[pos], dataSource, blockSize);
pos += blockSize;
headerCode = "MAPR"; // MAPR Block
blockSize = mapper->state_size;
dataSource = (void *)mapper->state;
memcpy(&buffer[pos], headerCode.data(), headerSize); pos += headerSize;
memcpy(&buffer[pos], &blockSize, headerSize); pos += headerSize;
memcpy(&buffer[pos], dataSource, blockSize); pos += blockSize;
memcpy(&buffer[pos], headerCode.data(), headerSize);
pos += headerSize;
memcpy(&buffer[pos], &blockSize, headerSize);
pos += headerSize;
memcpy(&buffer[pos], dataSource, blockSize);
pos += blockSize;
headerCode = "LRAM"; // LRAM Block
blockSize = low_ram_size;
dataSource = (void *)low_mem;
memcpy(&buffer[pos], headerCode.data(), headerSize); pos += headerSize;
memcpy(&buffer[pos], &blockSize, headerSize); pos += headerSize;
memcpy(&buffer[pos], dataSource, blockSize); pos += blockSize;
memcpy(&buffer[pos], headerCode.data(), headerSize);
pos += headerSize;
memcpy(&buffer[pos], &blockSize, headerSize);
pos += headerSize;
memcpy(&buffer[pos], dataSource, blockSize);
pos += blockSize;
headerCode = "SPRT"; // SPRT Block
blockSize = Nes_Ppu::spr_ram_size;
dataSource = (void *)ppu.spr_ram;
memcpy(&buffer[pos], headerCode.data(), headerSize); pos += headerSize;
memcpy(&buffer[pos], &blockSize, headerSize); pos += headerSize;
memcpy(&buffer[pos], dataSource, blockSize); pos += blockSize;
memcpy(&buffer[pos], headerCode.data(), headerSize);
pos += headerSize;
memcpy(&buffer[pos], &blockSize, headerSize);
pos += headerSize;
memcpy(&buffer[pos], dataSource, blockSize);
pos += blockSize;
headerCode = "NTAB"; // NTAB Block
size_t nametable_size = 0x800;
if (ppu.nt_banks[3] >= &ppu.impl->nt_ram[0xC00]) nametable_size = 0x1000;
blockSize = nametable_size;
dataSource = (void *)ppu.impl->nt_ram;
memcpy(&buffer[pos], headerCode.data(), headerSize); pos += headerSize;
memcpy(&buffer[pos], &blockSize, headerSize); pos += headerSize;
memcpy(&buffer[pos], dataSource, blockSize); pos += blockSize;
memcpy(&buffer[pos], headerCode.data(), headerSize);
pos += headerSize;
memcpy(&buffer[pos], &blockSize, headerSize);
pos += headerSize;
memcpy(&buffer[pos], dataSource, blockSize);
pos += blockSize;
if (ppu.chr_is_writable)
{
headerCode = "CHRR"; // CHRR Block
blockSize = ppu.chr_size;
dataSource = (void *)ppu.impl->chr_ram;
memcpy(&buffer[pos], headerCode.data(), headerSize); pos += headerSize;
memcpy(&buffer[pos], &blockSize, headerSize); pos += headerSize;
memcpy(&buffer[pos], dataSource, blockSize); pos += blockSize;
memcpy(&buffer[pos], headerCode.data(), headerSize);
pos += headerSize;
memcpy(&buffer[pos], &blockSize, headerSize);
pos += headerSize;
memcpy(&buffer[pos], dataSource, blockSize);
pos += blockSize;
}
if (sram_present)
@ -316,15 +348,20 @@ public:
headerCode = "SRAM"; // SRAM Block
blockSize = impl->sram_size;
dataSource = (void *)impl->sram;
memcpy(&buffer[pos], headerCode.data(), headerSize); pos += headerSize;
memcpy(&buffer[pos], &blockSize, headerSize); pos += headerSize;
memcpy(&buffer[pos], dataSource, blockSize); pos += blockSize;
memcpy(&buffer[pos], headerCode.data(), headerSize);
pos += headerSize;
memcpy(&buffer[pos], &blockSize, headerSize);
pos += headerSize;
memcpy(&buffer[pos], dataSource, blockSize);
pos += blockSize;
}
headerCode = "gend"; // gend Block
blockSize = 0;
memcpy(&buffer[pos], headerCode.data(), headerSize); pos += headerSize;
memcpy(&buffer[pos], &blockSize, headerSize); pos += headerSize;
memcpy(&buffer[pos], headerCode.data(), headerSize);
pos += headerSize;
memcpy(&buffer[pos], &blockSize, headerSize);
pos += headerSize;
return pos; // Bytes written
}
@ -348,7 +385,8 @@ public:
pos += headerSize;
pos += headerSize;
blockSize = sizeof(nes_state_t);
memcpy(&nesState, &buffer[pos], blockSize); pos += blockSize;
memcpy(&nesState, &buffer[pos], blockSize);
pos += blockSize;
nes = nesState;
nes.timestamp /= 5;
@ -357,7 +395,8 @@ public:
blockSize = sizeof(cpu_state_t);
pos += headerSize;
pos += headerSize;
memcpy((void*) &s, &buffer[pos], blockSize); pos += blockSize;
memcpy((void *)&s, &buffer[pos], blockSize);
pos += blockSize;
r.pc = s.pc;
r.sp = s.s;
r.a = s.a;
@ -369,7 +408,8 @@ public:
blockSize = sizeof(ppu_state_t);
pos += headerSize;
pos += headerSize;
memcpy((void*) &ppu, &buffer[pos], blockSize); pos += blockSize;
memcpy((void *)&ppu, &buffer[pos], blockSize);
pos += blockSize;
// APUR Block
Nes_Apu::apu_state_t apuState;
@ -385,27 +425,31 @@ public:
blockSize = sizeof(joypad_state_t);
pos += headerSize;
pos += headerSize;
memcpy((void*) &joypad, &buffer[pos], blockSize); pos += blockSize;
memcpy((void *)&joypad, &buffer[pos], blockSize);
pos += blockSize;
// MAPR Block
mapper->default_reset_state();
blockSize = mapper->state_size;
pos += headerSize;
pos += headerSize;
memcpy((void*) mapper->state, &buffer[pos], blockSize); pos += blockSize;
memcpy((void *)mapper->state, &buffer[pos], blockSize);
pos += blockSize;
mapper->apply_mapping();
// LRAM Block
blockSize = low_ram_size;
pos += headerSize;
pos += headerSize;
memcpy((void*) low_mem, &buffer[pos], blockSize); pos += blockSize;
memcpy((void *)low_mem, &buffer[pos], blockSize);
pos += blockSize;
// SPRT Block
blockSize = Nes_Ppu::spr_ram_size;
pos += headerSize;
pos += headerSize;
memcpy((void*) ppu.spr_ram, &buffer[pos], blockSize); pos += blockSize;
memcpy((void *)ppu.spr_ram, &buffer[pos], blockSize);
pos += blockSize;
// NTAB Block
size_t nametable_size = 0x800;
@ -413,7 +457,8 @@ public:
blockSize = nametable_size;
pos += headerSize;
pos += headerSize;
memcpy((void*) ppu.impl->nt_ram, &buffer[pos], blockSize); pos += blockSize;
memcpy((void *)ppu.impl->nt_ram, &buffer[pos], blockSize);
pos += blockSize;
if (ppu.chr_is_writable)
{
@ -421,7 +466,8 @@ public:
blockSize = ppu.chr_size;
pos += headerSize;
pos += headerSize;
memcpy((void*) ppu.impl->chr_ram, &buffer[pos], blockSize); pos += blockSize;
memcpy((void *)ppu.impl->chr_ram, &buffer[pos], blockSize);
pos += blockSize;
}
if (sram_present)
@ -430,7 +476,8 @@ public:
blockSize = impl->sram_size;
pos += headerSize;
pos += headerSize;
memcpy((void*) impl->sram, &buffer[pos], blockSize); pos += blockSize;
memcpy((void *)impl->sram, &buffer[pos], blockSize);
pos += blockSize;
enable_sram(true);
}
@ -526,7 +573,6 @@ public:
disable_rendering();
}
void irq_changed()
{
cpu_set_irq_time(earliest_irq(cpu_time()));
@ -537,11 +583,16 @@ public:
cpu_set_end_time(earliest_event(cpu_time()));
}
public: private: friend class Nes_Emu;
public:
private:
friend class Nes_Emu;
struct impl_t
{
enum { sram_size = 0x2000 };
enum
{
sram_size = 0x2000
};
uint8_t sram[sram_size];
Nes_Apu apu;
@ -584,7 +635,6 @@ private:
return ppu.frame_length();
}
inline nes_time_t earliest_event(nes_time_t present)
{
// PPU frame
@ -678,7 +728,6 @@ private:
((Nes_Core *)emu)->irq_changed();
}
// CPU
unsigned sram_readable;
unsigned sram_writable;
@ -798,10 +847,14 @@ private:
cpu::reduce_limit(n);
}
public: private: friend class Nes_Ppu;
public:
private:
friend class Nes_Ppu;
void set_ppu_2002_time(nes_time_t t) { ppu_2002_time = t - 1 - cpu_time_offset; }
public: private: friend class Nes_Mapper;
public:
private:
friend class Nes_Mapper;
void enable_prg_6000()
{
@ -845,7 +898,9 @@ public: private: friend class Nes_Mapper;
}
}
public: private: friend class Nes_Cpu;
public:
private:
friend class Nes_Cpu;
int cpu_read_ppu(nes_addr_t, nes_time_t);
int cpu_read(nes_addr_t, nes_time_t);
void cpu_write(nes_addr_t, int data, nes_time_t);
@ -974,13 +1029,17 @@ inline void Nes_Core::cpu_write( nes_addr_t addr, int data, nes_time_t time )
#define NES_CPU_READ(cpu, addr, time) \
static_cast<Nes_Core &>(*cpu).cpu_read(addr, time)
#define NES_CPU_WRITEX( cpu, addr, data, time ){\
#define NES_CPU_WRITEX(cpu, addr, data, time) \
{ \
static_cast<Nes_Core &>(*cpu).cpu_write(addr, data, time); \
}
#define NES_CPU_WRITE( cpu, addr, data, time ){\
if ( addr < 0x800 ) cpu->low_mem [addr] = data;\
else if ( addr == 0x2007 ) static_cast<Nes_Core&>(*cpu).cpu_write_2007( data );\
else static_cast<Nes_Core&>(*cpu).cpu_write( addr, data, time );\
#define NES_CPU_WRITE(cpu, addr, data, time) \
{ \
if (addr < 0x800) \
cpu->low_mem[addr] = data; \
else if (addr == 0x2007) \
static_cast<Nes_Core &>(*cpu).cpu_write_2007(data); \
else \
static_cast<Nes_Core &>(*cpu).cpu_write(addr, data, time); \
}

View File

@ -8,11 +8,12 @@
typedef long nes_time_t; // clock cycle count
typedef unsigned nes_addr_t; // 16-bit address
class Nes_Cpu {
class Nes_Cpu
{
public:
// NES 6502 registers. *Not* kept updated during a call to run().
struct registers_t {
struct registers_t
{
uint16_t pc; // Should be more than 16 bits to allow overflow detection -- but I (eien86) removed it to maximize performance.
uint8_t a;
uint8_t x;
@ -23,9 +24,18 @@ public:
// Map code memory (memory accessed via the program counter). Start and size
// must be multiple of page_size.
enum { page_bits = 11 };
enum { page_count = 0x10000 >> page_bits };
enum { page_size = 1L << page_bits };
enum
{
page_bits = 11
};
enum
{
page_count = 0x10000 >> page_bits
};
enum
{
page_size = 1L << page_bits
};
// Clear registers, unmap memory, and map code pages to unmapped_page.
void reset(void const *unmapped_page = 0);
@ -50,7 +60,8 @@ public:
}
// Reasons that run() returns
enum result_t {
enum result_t
{
result_cycles, // Requested number of cycles (or more) were executed
result_sei, // I flag just set and IRQ time would generate IRQ now
result_cli, // I flag just cleared but IRQ should occur *after* next instr
@ -83,10 +94,16 @@ public:
unsigned long error_count() const { return error_count_; }
// If PC exceeds 0xFFFF and encounters page_wrap_opcode, it will be silently wrapped.
enum { page_wrap_opcode = 0xF2 };
enum
{
page_wrap_opcode = 0xF2
};
// One of the many opcodes that are undefined and stop CPU emulation.
enum { bad_opcode = 0xD2 };
enum
{
bad_opcode = 0xD2
};
uint8_t const *code_map[page_count + 1];
nes_time_t clock_limit;
@ -95,7 +112,10 @@ public:
nes_time_t end_time_;
unsigned long error_count_;
enum { irq_inhibit = 0x04 };
enum
{
irq_inhibit = 0x04
};
inline void update_clock_limit()
{
@ -115,9 +135,4 @@ public:
{
return (uint8_t *)code_map[addr >> page_bits] + addr;
}
};

View File

@ -4,13 +4,14 @@
// Nes_Emu 0.7.0
#include "apu/Multi_Buffer.hpp"
#include "Nes_Cart.hpp"
#include "Nes_Core.hpp"
#include "apu/Multi_Buffer.hpp"
class Nes_State;
class Nes_Emu {
class Nes_Emu
{
public:
Nes_Emu();
virtual ~Nes_Emu();
@ -115,7 +116,8 @@ public:
int channel_count() const { return channel_count_; }
// Frequency equalizer parameters
struct equalizer_t {
struct equalizer_t
{
double treble; // 5.0 = extra-crisp, -200.0 = muffled
long bass; // 0 = deep, 20000 = tinny
};
@ -146,18 +148,28 @@ public:
// Graphics
// Number of frames generated per second
enum { frame_rate = 60 };
enum
{
frame_rate = 60
};
// Size of fixed NES color table (including the 8 color emphasis modes)
enum { color_table_size = 8 * 64 };
enum
{
color_table_size = 8 * 64
};
// NES color lookup table based on standard NTSC TV decoder. Use nes_ntsc.h to
// generate a palette with custom parameters.
struct rgb_t { unsigned char red, green, blue; };
struct rgb_t
{
unsigned char red, green, blue;
};
static rgb_t const nes_colors[color_table_size];
// Hide/show/enhance sprites. Sprite mode does not affect emulation accuracy.
enum sprite_mode_t {
enum sprite_mode_t
{
sprites_hidden = 0,
sprites_visible = 8, // limit of 8 sprites per scanline as on NES (default)
sprites_enhanced = 64 // unlimited sprites per scanline (no flickering)
@ -167,7 +179,10 @@ public:
// Set range of host palette entries to use in graphics buffer; default uses
// all of them. Begin will be rounded up to next multiple of palette_alignment.
// Use frame().palette_begin to find the adjusted beginning entry used.
enum { palette_alignment = 64 };
enum
{
palette_alignment = 64
};
void set_palette_range(int begin, int end = 256);
// Access to emulated memory, for viewer/cheater/debugger
@ -182,11 +197,17 @@ public:
long nametable_size() const { return 0x1000; }
// Built-in 2K memory
enum { low_mem_size = 0x800 };
enum
{
low_mem_size = 0x800
};
uint8_t *low_mem() { return emu.low_mem; }
// Optional 8K memory
enum { high_mem_size = 0x2000 };
enum
{
high_mem_size = 0x2000
};
uint8_t *high_mem() { return emu.impl->sram; }
// Sprite memory
@ -198,8 +219,8 @@ public:
const char *set_sample_rate(long rate, class Nes_Buffer *);
const char *set_sample_rate(long rate, class Nes_Effects_Buffer *);
void irq_changed() { emu.irq_changed(); }
private:
private:
frame_t *frame_;
int buffer_height_;
bool fade_sound_in;
@ -239,6 +260,7 @@ private:
bool extra_fade_sound_in;
bool extra_fade_sound_out;
unsigned extra_sound_buf_changed_count;
public:
void SaveAudioBufferState();
void RestoreAudioBufferState();
@ -259,4 +281,3 @@ inline long Nes_Emu::chr_size() const
{
return cart()->chr_size() ? cart()->chr_size() : emu.ppu.chr_addr_size;
}

View File

@ -1,12 +1,11 @@
// Blip_Buffer 0.4.0. http://www.slack.net/~ant/
#include <limits.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include "Blip_Buffer.hpp"
#include <limits.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>
/* Copyright (C) 2003-2006 Shay Green. This module is free software; you
can redistribute it and/or modify it under the terms of the GNU Lesser
@ -149,8 +148,7 @@ void Blip_Buffer::remove_samples( long count )
// Blip_Synth_
Blip_Synth_::Blip_Synth_( short* p, int w ) :
impulses( p ),
Blip_Synth_::Blip_Synth_(short *p, int w) : impulses(p),
width(w)
{
volume_unit_ = 0.0;

View File

@ -11,9 +11,13 @@ typedef long blip_time_t;
// Output samples are 16-bit signed, with a range of -32768 to 32767
typedef short blip_sample_t;
enum { blip_sample_max = 32767 };
enum
{
blip_sample_max = 32767
};
class Blip_Buffer {
class Blip_Buffer
{
public:
// Set output sample rate and buffer length in milliseconds (1/1000 sec, defaults
// to 1/4 second), then clear buffer. Returns NULL on success, otherwise if there
@ -80,6 +84,7 @@ public:
blip_resampled_time_t resampled_duration(int t) const { return t * factor_; }
blip_resampled_time_t resampled_time(blip_time_t t) const { return t * factor_ + offset_; }
blip_resampled_time_t clock_rate_factor(long clock_rate) const;
public:
Blip_Buffer();
~Blip_Buffer();
@ -88,16 +93,19 @@ public:
typedef blip_resampled_time_t resampled_time_t;
const char *sample_rate(long r) { return set_sample_rate(r); }
const char *sample_rate(long r, int msec) { return set_sample_rate(r, msec); }
private:
// noncopyable
Blip_Buffer(const Blip_Buffer &);
Blip_Buffer &operator=(const Blip_Buffer &);
public:
typedef long buf_t_;
unsigned long factor_;
blip_resampled_time_t offset_;
buf_t_ *buffer_;
long buffer_size_;
private:
long reader_accum;
int bass_shift;
@ -113,6 +121,7 @@ private:
int extra_length;
long extra_reader_accum;
blip_resampled_time_t extra_offset;
public:
void SaveAudioBufferState();
void RestoreAudioBufferState();
@ -141,13 +150,15 @@ public:
int const blip_res = 1 << BLIP_PHASE_BITS;
class blip_eq_t;
class Blip_Synth_ {
class Blip_Synth_
{
double volume_unit_;
short *const impulses;
int const width;
long kernel_unit;
int impulses_size() const { return blip_res / 2 * width + 1; }
void adjust_impulse();
public:
Blip_Buffer *buf;
int last_amp;
@ -167,7 +178,8 @@ const int blip_high_quality = 16;
// by finding the difference between the maximum and minimum expected
// amplitudes (max - min).
template <int quality, int range>
class Blip_Synth {
class Blip_Synth
{
public:
// Set overall volume of waveform
void volume(double v) { impl.volume_unit(v * (1.0 / (range < 0 ? -range : range))); }
@ -177,7 +189,11 @@ public:
// Get/set Blip_Buffer used for output
Blip_Buffer *output() const { return impl.buf; }
void output( Blip_Buffer* b ) { impl.buf = b; impl.last_amp = 0; }
void output(Blip_Buffer *b)
{
impl.buf = b;
impl.last_amp = 0;
}
// Update amplitude of waveform at given time. Using this requires a separate
// Blip_Synth for each waveform.
@ -195,15 +211,18 @@ public:
void offset_resampled(blip_resampled_time_t, int delta, Blip_Buffer *) const;
// Same as offset(), except code is inlined for higher performance
void offset_inline( blip_time_t t, int delta, Blip_Buffer* buf ) const {
void offset_inline(blip_time_t t, int delta, Blip_Buffer *buf) const
{
offset_resampled(t * buf->factor_ + buf->offset_, delta, buf);
}
void offset_inline( blip_time_t t, int delta ) const {
void offset_inline(blip_time_t t, int delta) const
{
offset_resampled(t * impl.buf->factor_ + impl.buf->offset_, delta, impl.buf);
}
public:
Blip_Synth() : impl(impulses, quality) {}
private:
typedef short imp_t;
imp_t impulses[blip_res * (quality / 2) + 1];
@ -211,7 +230,8 @@ private:
};
// Low-pass equalization parameters
class blip_eq_t {
class blip_eq_t
{
public:
// Logarithmic rolloff to treble dB at half sampling rate. Negative values reduce
// treble, small positive values (0 to 5.0) increase treble.
@ -232,7 +252,8 @@ private:
int const blip_sample_bits = 30;
// Optimized inline sample reader for custom sample formats and mixing of Blip_Buffer samples
class Blip_Reader {
class Blip_Reader
{
public:
// Begin reading samples from buffer. Returns value to pass to next() (can
// be ignored if default bass_freq is acceptable).
@ -256,32 +277,35 @@ private:
long accum;
};
// End of public interface
// Compatibility with older version
const long blip_unscaled = 65535;
const int blip_low_quality = blip_med_quality;
const int blip_best_quality = blip_high_quality;
#define BLIP_FWD( i ) { \
#define BLIP_FWD(i) \
{ \
long t0 = i0 * delta + buf[fwd + i]; \
long t1 = imp[blip_res * (i + 1)] * delta + buf[fwd + 1 + i]; \
i0 = imp[blip_res * (i + 2)]; \
buf[fwd + i] = t0; \
buf [fwd + 1 + i] = t1; }
buf[fwd + 1 + i] = t1; \
}
#define BLIP_REV( r ) { \
#define BLIP_REV(r) \
{ \
long t0 = i0 * delta + buf[rev - r]; \
long t1 = imp[blip_res * r] * delta + buf[rev + 1 - r]; \
i0 = imp[blip_res * (r - 1)]; \
buf[rev - r] = t0; \
buf [rev + 1 - r] = t1; }
buf[rev + 1 - r] = t1; \
}
template <int quality, int range>
inline void Blip_Synth<quality, range>::offset_resampled(blip_resampled_time_t time,
int delta, Blip_Buffer* blip_buf ) const
int delta,
Blip_Buffer *blip_buf) const
{
// Fails if time is beyond end of Blip_Buffer, due to a bug in caller code or the
// need for a longer buffer as set by set_sample_rate().
@ -333,10 +357,8 @@ void Blip_Synth<quality,range>::update( blip_time_t t, int amp )
offset_resampled(t * impl.buf->factor_ + impl.buf->offset_, delta, impl.buf);
}
inline blip_eq_t::blip_eq_t( double t ) :
treble( t ), rolloff_freq( 0 ), sample_rate( 44100 ), cutoff_freq( 0 ) { }
inline blip_eq_t::blip_eq_t( double t, long rf, long sr, long cf ) :
treble( t ), rolloff_freq( rf ), sample_rate( sr ), cutoff_freq( cf ) { }
inline blip_eq_t::blip_eq_t(double t) : treble(t), rolloff_freq(0), sample_rate(44100), cutoff_freq(0) {}
inline blip_eq_t::blip_eq_t(double t, long rf, long sr, long cf) : treble(t), rolloff_freq(rf), sample_rate(sr), cutoff_freq(cf) {}
inline int Blip_Buffer::length() const { return length_; }
inline long Blip_Buffer::samples_avail() const { return (long)(offset_ >> BLIP_BUFFER_ACCURACY); }

View File

@ -1,7 +1,7 @@
// Game_Music_Emu 0.3.0. http://www.slack.net/~ant/
#include <cstring>
#include "Effects_Buffer.hpp"
#include <cstring>
/* Copyright (C) 2003-2006 Shay Green. This module is free software; you
can redistribute it and/or modify it under the terms of the GNU Lesser
@ -161,9 +161,13 @@ void Effects_Buffer::config( const config_t& cfg )
int reverb_sample_delay = int(1.0 / 1000 * config_.reverb_delay * sample_rate());
chans.reverb_delay_l = pin_range(reverb_size -
(reverb_sample_delay - delay_offset) * 2, reverb_size - 2, 0 );
(reverb_sample_delay - delay_offset) * 2,
reverb_size - 2,
0);
chans.reverb_delay_r = pin_range(reverb_size + 1 -
(reverb_sample_delay + delay_offset) * 2, reverb_size - 1, 1 );
(reverb_sample_delay + delay_offset) * 2,
reverb_size - 1,
1);
int echo_sample_delay = int(1.0 / 1000 * config_.echo_delay * sample_rate());
chans.echo_delay_l = pin_range(echo_size - 1 - (echo_sample_delay - delay_offset),
@ -188,7 +192,6 @@ void Effects_Buffer::config( const config_t& cfg )
o.right = &bufs[6];
}
}
}
else
{
@ -336,8 +339,10 @@ void Effects_Buffer::mix_mono( blip_sample_t* out, long count )
void Effects_Buffer::mix_stereo(blip_sample_t *out, long count)
{
Blip_Reader l; l.begin( bufs [1] );
Blip_Reader r; r.begin( bufs [2] );
Blip_Reader l;
l.begin(bufs[1]);
Blip_Reader r;
r.begin(bufs[2]);
Blip_Reader c;
int shift = c.begin(bufs[0]);
@ -369,8 +374,10 @@ void Effects_Buffer::mix_stereo( blip_sample_t* out, long count )
void Effects_Buffer::mix_mono_enhanced(blip_sample_t *out, long count)
{
Blip_Reader sq1; sq1.begin( bufs [0] );
Blip_Reader sq2; sq2.begin( bufs [1] );
Blip_Reader sq1;
sq1.begin(bufs[0]);
Blip_Reader sq2;
sq2.begin(bufs[1]);
Blip_Reader center;
int shift = center.begin(bufs[2]);
@ -401,10 +408,8 @@ void Effects_Buffer::mix_mono_enhanced( blip_sample_t* out, long count )
int sum3_s = center.read();
center.next(shift);
int left = new_reverb_l + sum3_s + FMUL( chans.echo_level,
echo_buf [(echo_pos + chans.echo_delay_l) & echo_mask] );
int right = new_reverb_r + sum3_s + FMUL( chans.echo_level,
echo_buf [(echo_pos + chans.echo_delay_r) & echo_mask] );
int left = new_reverb_l + sum3_s + FMUL(chans.echo_level, echo_buf[(echo_pos + chans.echo_delay_l) & echo_mask]);
int right = new_reverb_r + sum3_s + FMUL(chans.echo_level, echo_buf[(echo_pos + chans.echo_delay_r) & echo_mask]);
echo_buf[echo_pos] = sum3_s;
echo_pos = (echo_pos + 1) & echo_mask;
@ -430,12 +435,18 @@ void Effects_Buffer::mix_mono_enhanced( blip_sample_t* out, long count )
void Effects_Buffer::mix_enhanced(blip_sample_t *out, long count)
{
Blip_Reader l1; l1.begin( bufs [3] );
Blip_Reader r1; r1.begin( bufs [4] );
Blip_Reader l2; l2.begin( bufs [5] );
Blip_Reader r2; r2.begin( bufs [6] );
Blip_Reader sq1; sq1.begin( bufs [0] );
Blip_Reader sq2; sq2.begin( bufs [1] );
Blip_Reader l1;
l1.begin(bufs[3]);
Blip_Reader r1;
r1.begin(bufs[4]);
Blip_Reader l2;
l2.begin(bufs[5]);
Blip_Reader r2;
r2.begin(bufs[6]);
Blip_Reader sq1;
sq1.begin(bufs[0]);
Blip_Reader sq2;
sq2.begin(bufs[1]);
Blip_Reader center;
int shift = center.begin(bufs[2]);
@ -469,10 +480,8 @@ void Effects_Buffer::mix_enhanced( blip_sample_t* out, long count )
int sum3_s = center.read();
center.next(shift);
int left = new_reverb_l + sum3_s + l2.read() + FMUL( chans.echo_level,
echo_buf [(echo_pos + chans.echo_delay_l) & echo_mask] );
int right = new_reverb_r + sum3_s + r2.read() + FMUL( chans.echo_level,
echo_buf [(echo_pos + chans.echo_delay_r) & echo_mask] );
int left = new_reverb_l + sum3_s + l2.read() + FMUL(chans.echo_level, echo_buf[(echo_pos + chans.echo_delay_l) & echo_mask]);
int right = new_reverb_r + sum3_s + r2.read() + FMUL(chans.echo_level, echo_buf[(echo_pos + chans.echo_delay_r) & echo_mask]);
l2.next(shift);
r2.next(shift);

View File

@ -3,11 +3,12 @@
// Multi-channel effects buffer with panning, echo and reverb
// Game_Music_Emu 0.3.0
#include <stdint.h>
#include "Multi_Buffer.hpp"
#include <stdint.h>
// Effects_Buffer uses several buffers and outputs stereo sample pairs.
class Effects_Buffer : public Multi_Buffer {
class Effects_Buffer : public Multi_Buffer
{
public:
// If center_only is true, only center buffers are created and
// less memory is used.
@ -22,7 +23,8 @@ public:
// 4 echo -
// Channel configuration
struct config_t {
struct config_t
{
double pan_1; // -1.0 = left, 0.0 = center, 1.0 = right
double pan_2;
double echo_delay; // msec
@ -48,12 +50,19 @@ public:
void end_frame(blip_time_t, bool was_stereo = true);
long read_samples(blip_sample_t *, long);
long samples_avail() const;
private:
typedef long fixed_t;
enum { max_buf_count = 7 };
enum
{
max_buf_count = 7
};
Blip_Buffer bufs[max_buf_count];
enum { chan_count = 5 };
enum
{
chan_count = 5
};
channel_t channels[chan_count];
config_t config_;
long stereo_remain;
@ -66,7 +75,8 @@ private:
int reverb_pos;
int echo_pos;
struct {
struct
{
fixed_t pan_1_levels[2];
fixed_t pan_2_levels[2];
int echo_delay_l;
@ -83,7 +93,7 @@ private:
void mix_mono_enhanced(blip_sample_t *, long);
};
inline Effects_Buffer::channel_t Effects_Buffer::channel( int i ) {
inline Effects_Buffer::channel_t Effects_Buffer::channel(int i)
{
return channels[i % chan_count];
}

View File

@ -174,7 +174,8 @@ long Stereo_Buffer::read_samples( blip_sample_t* out, long count )
}
// to do: this might miss opportunities for optimization
if ( !bufs [0].samples_avail() ) {
if (!bufs[0].samples_avail())
{
was_stereo = stereo_added;
stereo_added = false;
}
@ -246,7 +247,8 @@ void Stereo_Buffer::mix_mono( blip_sample_t* out, long count )
out[1] = s;
out += 2;
if ( (int16_t) s != s ) {
if ((int16_t)s != s)
{
s = 0x7FFF - (s >> 24);
out[-2] = s;
out[-1] = s;

View File

@ -8,7 +8,8 @@
// Interface to one or more Blip_Buffers mapped to one or more channels
// consisting of left, center, and right buffers.
class Multi_Buffer {
class Multi_Buffer
{
public:
Multi_Buffer(int samples_per_frame);
virtual ~Multi_Buffer() {}
@ -17,7 +18,8 @@ public:
virtual const char *set_channel_count(int);
// Get indexed channel, from 0 to channel count - 1
struct channel_t {
struct channel_t
{
Blip_Buffer *center;
Blip_Buffer *left;
Blip_Buffer *right;
@ -52,6 +54,7 @@ public:
protected:
void channels_changed() { channels_changed_count_++; }
private:
// noncopyable
Multi_Buffer(const Multi_Buffer &);
@ -62,17 +65,21 @@ private:
int length_;
int const samples_per_frame_;
unsigned channels_changed_count_save_;
protected:
void SaveAudioBufferStatePrivate();
void RestoreAudioBufferStatePrivate();
public:
virtual void SaveAudioBufferState() = 0;
virtual void RestoreAudioBufferState() = 0;
};
// Uses a single buffer and outputs mono samples.
class Mono_Buffer : public Multi_Buffer {
class Mono_Buffer : public Multi_Buffer
{
Blip_Buffer buf;
public:
Mono_Buffer();
~Mono_Buffer();
@ -95,7 +102,8 @@ public:
};
// Uses three buffers (one for center) and outputs stereo sample pairs.
class Stereo_Buffer : public Multi_Buffer {
class Stereo_Buffer : public Multi_Buffer
{
public:
Stereo_Buffer();
~Stereo_Buffer();
@ -117,7 +125,10 @@ public:
long read_samples(blip_sample_t *, long);
private:
enum { buf_count = 3 };
enum
{
buf_count = 3
};
Blip_Buffer bufs[buf_count];
channel_t chan;
bool stereo_added;
@ -131,8 +142,10 @@ private:
};
// Silent_Buffer generates no samples, useful where no sound is wanted
class Silent_Buffer : public Multi_Buffer {
class Silent_Buffer : public Multi_Buffer
{
channel_t chan;
public:
Silent_Buffer();
@ -149,7 +162,6 @@ public:
virtual void RestoreAudioBufferState();
};
// End of public interface
inline const char *Multi_Buffer::set_sample_rate(long rate, int msec)
@ -183,4 +195,3 @@ inline void Mono_Buffer::bass_freq( int freq ) { buf.bass_freq( freq ); }
inline long Mono_Buffer::read_samples(blip_sample_t *p, long s) { return buf.read_samples(p, s); }
inline long Mono_Buffer::samples_avail() const { return buf.samples_avail(); }

View File

@ -14,7 +14,6 @@ details. You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
// Nes_Buffer
Nes_Buffer::Nes_Buffer() : Multi_Buffer(1) {}
@ -194,7 +193,6 @@ long Nes_Nonlinearizer::make_nonlinear( Blip_Buffer& buf, long count )
count = avail;
if (count && enabled)
{
Blip_Buffer::buf_t_ *p = buf.buffer_;
long accum = this->accum;
long prev = this->prev;

View File

@ -8,10 +8,17 @@
class Nes_Apu;
class Nes_Nonlinearizer {
class Nes_Nonlinearizer
{
private:
enum { table_bits = 11 };
enum { table_size = 1 << table_bits };
enum
{
table_bits = 11
};
enum
{
table_size = 1 << table_bits
};
int16_t table[table_size];
Nes_Apu *apu;
long accum;
@ -19,6 +26,7 @@ private:
long extra_accum;
long extra_prev;
public:
Nes_Nonlinearizer();
bool enabled;
@ -30,7 +38,8 @@ public:
void RestoreAudioBufferState();
};
class Nes_Buffer : public Multi_Buffer {
class Nes_Buffer : public Multi_Buffer
{
public:
Nes_Buffer();
~Nes_Buffer();
@ -61,6 +70,7 @@ private:
Blip_Buffer tnd;
Nes_Nonlinearizer nonlin;
friend Multi_Buffer *set_apu(Nes_Buffer *, Nes_Apu *);
public:
virtual void SaveAudioBufferState();
virtual void RestoreAudioBufferState();

View File

@ -15,8 +15,7 @@ more details. You should have received a copy of the GNU Lesser General
Public License along with this module; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
Nes_Effects_Buffer::Nes_Effects_Buffer() :
Effects_Buffer( true ) // nes never uses stereo channels
Nes_Effects_Buffer::Nes_Effects_Buffer() : Effects_Buffer(true) // nes never uses stereo channels
{
config_t c;
c.effects_enabled = false;

View File

@ -3,11 +3,12 @@
// Effects_Buffer with non-linear sound
// Nes_Emu 0.7.0
#include "Nes_Buffer.hpp"
#include "Effects_Buffer.hpp"
#include "Nes_Buffer.hpp"
// Effects_Buffer uses several buffers and outputs stereo sample pairs.
class Nes_Effects_Buffer : public Effects_Buffer {
class Nes_Effects_Buffer : public Effects_Buffer
{
public:
Nes_Effects_Buffer();
~Nes_Effects_Buffer();

View File

@ -25,12 +25,14 @@ void Nes_Osc::clock_length( int halt_mask )
void Nes_Envelope::clock_envelope()
{
int period = regs[0] & 15;
if ( reg_written [3] ) {
if (reg_written[3])
{
reg_written[3] = false;
env_delay = period;
envelope = 15;
}
else if ( --env_delay < 0 ) {
else if (--env_delay < 0)
{
env_delay = period;
if (envelope | (regs[0] & 0x20))
envelope = (envelope - 1) & 15;
@ -39,7 +41,8 @@ void Nes_Envelope::clock_envelope()
int Nes_Envelope::volume() const
{
return length_counter == 0 ? 0 : (regs [0] & 0x10) ? (regs [0] & 15) : envelope;
return length_counter == 0 ? 0 : (regs[0] & 0x10) ? (regs[0] & 15)
: envelope;
}
// Nes_Square
@ -71,15 +74,15 @@ void Nes_Square::clock_sweep( int negative_adjust )
}
}
if ( reg_written [1] ) {
if (reg_written[1])
{
reg_written[1] = false;
sweep_delay = (sweep >> 4) & 7;
}
}
// TODO: clean up
inline nes_time_t Nes_Square::maintain_phase( nes_time_t time, nes_time_t end_time,
nes_time_t timer_period )
inline nes_time_t Nes_Square::maintain_phase(nes_time_t time, nes_time_t end_time, nes_time_t timer_period)
{
long remain = end_time - time;
if (remain > 0)
@ -109,7 +112,8 @@ void Nes_Square::run( nes_time_t time, nes_time_t end_time )
const int volume = this->volume();
if (volume == 0 || period < 8 || (period + offset) >= 0x800)
{
if ( last_amp ) {
if (last_amp)
{
synth.offset(time, -last_amp, output);
last_amp = 0;
}
@ -123,7 +127,8 @@ void Nes_Square::run( nes_time_t time, nes_time_t end_time )
int duty_select = (regs[0] >> 6) & 3;
int duty = 1 << duty_select; // 1, 2, 4, 2
int amp = 0;
if ( duty_select == 3 ) {
if (duty_select == 3)
{
duty = 2; // negated 25%
amp = volume;
}
@ -144,13 +149,13 @@ void Nes_Square::run( nes_time_t time, nes_time_t end_time )
do {
phase = (phase + 1) & (phase_range - 1);
if ( phase == 0 || phase == duty ) {
if (phase == 0 || phase == duty)
{
delta = -delta;
synth.offset_inline(time, delta, output);
}
time += timer_period;
}
while ( time < end_time );
} while (time < end_time);
last_amp = (delta + volume) >> 1;
this->phase = phase;
@ -182,8 +187,7 @@ inline int Nes_Triangle::calc_amp() const
}
// TODO: clean up
inline nes_time_t Nes_Triangle::maintain_phase( nes_time_t time, nes_time_t end_time,
nes_time_t timer_period )
inline nes_time_t Nes_Triangle::maintain_phase(nes_time_t time, nes_time_t end_time, nes_time_t timer_period)
{
long remain = end_time - time;
if (remain > 0)
@ -226,23 +230,25 @@ void Nes_Triangle::run( nes_time_t time, nes_time_t end_time )
int phase = this->phase;
int volume = 1;
if ( phase > phase_range ) {
if (phase > phase_range)
{
phase -= phase_range;
volume = -volume;
}
do {
if ( --phase == 0 ) {
if (--phase == 0)
{
phase = phase_range;
volume = -volume;
}
else {
else
{
synth.offset_inline(time, volume, output);
}
time += timer_period;
}
while ( time < end_time );
} while (time < end_time);
if (volume < 0)
phase += phase_range;
@ -277,7 +283,8 @@ void Nes_Dmc::recalc_irq()
if (irq_enabled && length_counter)
irq = apu->last_dmc_time + delay +
((length_counter - 1) * 8 + bits_remain - 1) * nes_time_t(period) + 1;
if ( irq != next_irq ) {
if (irq != next_irq)
{
next_irq = irq;
apu->irq_changed();
}
@ -308,10 +315,24 @@ int Nes_Dmc::count_reads( nes_time_t time, nes_time_t* last_read ) const
static const short dmc_period_table[2][16] = {
{0x1ac, 0x17c, 0x154, 0x140, 0x11e, 0x0fe, 0x0e2, 0x0d6, // NTSC
0x0be, 0x0a0, 0x08e, 0x080, 0x06a, 0x054, 0x048, 0x036},
0x0be,
0x0a0,
0x08e,
0x080,
0x06a,
0x054,
0x048,
0x036},
{0x18e, 0x161, 0x13c, 0x129, 0x10a, 0x0ec, 0x0d2, 0x0c7, // PAL (totally untested)
0x0b1, 0x095, 0x084, 0x077, 0x062, 0x04e, 0x043, 0x032} // to do: verify PAL periods
0x0b1,
0x095,
0x084,
0x077,
0x062,
0x04e,
0x043,
0x032} // to do: verify PAL periods
};
inline void Nes_Dmc::reload_sample()
@ -322,14 +343,134 @@ inline void Nes_Dmc::reload_sample()
static const unsigned char dac_table[128] =
{
0, 1, 2, 3, 4, 5, 6, 7, 7, 8, 9,10,11,12,13,14,
15,15,16,17,18,19,20,20,21,22,23,24,24,25,26,27,
27,28,29,30,31,31,32,33,33,34,35,36,36,37,38,38,
39,40,41,41,42,43,43,44,45,45,46,47,47,48,48,49,
50,50,51,52,52,53,53,54,55,55,56,56,57,58,58,59,
59,60,60,61,61,62,63,63,64,64,65,65,66,66,67,67,
68,68,69,70,70,71,71,72,72,73,73,74,74,75,75,75,
76,76,77,77,78,78,79,79,80,80,81,81,82,82,82,83,
0,
1,
2,
3,
4,
5,
6,
7,
7,
8,
9,
10,
11,
12,
13,
14,
15,
15,
16,
17,
18,
19,
20,
20,
21,
22,
23,
24,
24,
25,
26,
27,
27,
28,
29,
30,
31,
31,
32,
33,
33,
34,
35,
36,
36,
37,
38,
38,
39,
40,
41,
41,
42,
43,
43,
44,
45,
45,
46,
47,
47,
48,
48,
49,
50,
50,
51,
52,
52,
53,
53,
54,
55,
55,
56,
56,
57,
58,
58,
59,
59,
60,
60,
61,
61,
62,
63,
63,
64,
64,
65,
65,
66,
66,
67,
67,
68,
68,
69,
70,
70,
71,
71,
72,
72,
73,
73,
74,
74,
75,
75,
75,
76,
76,
77,
77,
78,
78,
79,
79,
80,
80,
81,
81,
82,
82,
82,
83,
};
void Nes_Dmc::write_register(int addr, int data)
@ -370,10 +511,12 @@ void Nes_Dmc::fill_buffer()
buf_full = true;
if (--length_counter == 0)
{
if ( regs [0] & loop_flag ) {
if (regs[0] & loop_flag)
{
reload_sample();
}
else {
else
{
apu->osc_enables &= ~0x10;
irq_flag = irq_enabled;
next_irq = Nes_Apu::no_irq;
@ -414,7 +557,8 @@ void Nes_Dmc::run( nes_time_t time, nes_time_t end_time )
{
int step = (bits & 1) * 4 - 2;
bits >>= 1;
if ( unsigned (dac + step) <= 0x7F ) {
if (unsigned(dac + step) <= 0x7F)
{
dac += step;
synth.offset_inline(time, step, output);
}
@ -425,10 +569,12 @@ void Nes_Dmc::run( nes_time_t time, nes_time_t end_time )
if (--bits_remain == 0)
{
bits_remain = 8;
if ( !buf_full ) {
if (!buf_full)
{
silence = true;
}
else {
else
{
silence = false;
bits = buf;
buf_full = false;
@ -437,8 +583,7 @@ void Nes_Dmc::run( nes_time_t time, nes_time_t end_time )
fill_buffer();
}
}
}
while ( time < end_time );
} while (time < end_time);
this->dac = dac;
this->last_amp = dac;
@ -452,9 +597,7 @@ void Nes_Dmc::run( nes_time_t time, nes_time_t end_time )
// Nes_Noise
static const short noise_period_table[16] = {
0x004, 0x008, 0x010, 0x020, 0x040, 0x060, 0x080, 0x0A0,
0x0CA, 0x0FE, 0x17C, 0x1FC, 0x2FA, 0x3F8, 0x7F2, 0xFE4
};
0x004, 0x008, 0x010, 0x020, 0x040, 0x060, 0x080, 0x0A0, 0x0CA, 0x0FE, 0x17C, 0x1FC, 0x2FA, 0x3F8, 0x7F2, 0xFE4};
void Nes_Noise::run(nes_time_t time, nes_time_t end_time)
{
@ -492,7 +635,8 @@ void Nes_Noise::run( nes_time_t time, nes_time_t end_time )
// approximate noise cycling while muted, by shuffling up noise register
// to do: precise muted noise cycling?
if ( !(regs [2] & mode_flag) ) {
if (!(regs[2] & mode_flag))
{
int feedback = (noise << 13) ^ (noise << 14);
noise = (feedback & 0x4000) | (noise >> 1);
}
@ -513,7 +657,8 @@ void Nes_Noise::run( nes_time_t time, nes_time_t end_time )
int feedback = (noise << tap) ^ (noise << 14);
time += period;
if ( (noise + 1) & 2 ) {
if ((noise + 1) & 2)
{
// bits 0 and 1 of noise differ
delta = -delta;
synth.offset_resampled(rtime, delta, output);
@ -521,8 +666,7 @@ void Nes_Noise::run( nes_time_t time, nes_time_t end_time )
rtime += rperiod;
noise = (feedback & 0x4000) | (noise >> 1);
}
while ( time < end_time );
} while (time < end_time);
last_amp = (delta + volume) >> 1;
this->noise = noise;

View File

@ -21,14 +21,17 @@ struct Nes_Osc
int last_amp; // last amplitude oscillator was outputting
void clock_length(int halt_mask);
int period() const {
int period() const
{
return (regs[3] & 7) * 0x100 + (regs[2] & 0xff);
}
void reset() {
void reset()
{
delay = 0;
last_amp = 0;
}
int update_amp( int amp ) {
int update_amp(int amp)
{
int delta = amp - last_amp;
last_amp = amp;
return delta;
@ -42,7 +45,8 @@ struct Nes_Envelope : Nes_Osc
void clock_envelope();
int volume() const;
void reset() {
void reset()
{
envelope = 0;
env_delay = 0;
Nes_Osc::reset();
@ -52,9 +56,18 @@ struct Nes_Envelope : Nes_Osc
// Nes_Square
struct Nes_Square : Nes_Envelope
{
enum { negate_flag = 0x08 };
enum { shift_mask = 0x07 };
enum { phase_range = 8 };
enum
{
negate_flag = 0x08
};
enum
{
shift_mask = 0x07
};
enum
{
phase_range = 8
};
int phase;
int sweep_delay;
@ -65,18 +78,21 @@ struct Nes_Square : Nes_Envelope
void clock_sweep(int adjust);
void run(nes_time_t, nes_time_t);
void reset() {
void reset()
{
sweep_delay = 0;
Nes_Envelope::reset();
}
nes_time_t maintain_phase( nes_time_t time, nes_time_t end_time,
nes_time_t timer_period );
nes_time_t maintain_phase(nes_time_t time, nes_time_t end_time, nes_time_t timer_period);
};
// Nes_Triangle
struct Nes_Triangle : Nes_Osc
{
enum { phase_range = 16 };
enum
{
phase_range = 16
};
int phase;
int linear_counter;
Blip_Synth<blip_med_quality, 1> synth;
@ -84,13 +100,13 @@ struct Nes_Triangle : Nes_Osc
int calc_amp() const;
void run(nes_time_t, nes_time_t);
void clock_linear_counter();
void reset() {
void reset()
{
linear_counter = 0;
phase = 1;
Nes_Osc::reset();
}
nes_time_t maintain_phase( nes_time_t time, nes_time_t end_time,
nes_time_t timer_period );
nes_time_t maintain_phase(nes_time_t time, nes_time_t end_time, nes_time_t timer_period);
};
// Nes_Noise
@ -100,7 +116,8 @@ struct Nes_Noise : Nes_Envelope
Blip_Synth<blip_med_quality, 1> synth;
void run(nes_time_t, nes_time_t);
void reset() {
void reset()
{
noise = 1 << 14;
Nes_Envelope::reset();
}
@ -118,7 +135,10 @@ struct Nes_Dmc : Nes_Osc
bool buf_full;
bool silence;
enum { loop_flag = 0x40 };
enum
{
loop_flag = 0x40
};
int dac;
@ -145,4 +165,3 @@ struct Nes_Dmc : Nes_Osc
int count_reads(nes_time_t, nes_time_t *) const;
nes_time_t next_read_time() const;
};

View File

@ -15,8 +15,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
int const amp_range = 15;
Nes_Apu::Nes_Apu() :
square1( &square_synth ),
Nes_Apu::Nes_Apu() : square1(&square_synth),
square2(&square_synth)
{
dmc.apu = this;
@ -112,14 +111,17 @@ void Nes_Apu::reset( bool pal_mode, int initial_dmc_dac )
void Nes_Apu::irq_changed()
{
nes_time_t new_irq = dmc.next_irq;
if ( dmc.irq_flag | irq_flag ) {
if (dmc.irq_flag | irq_flag)
{
new_irq = 0;
}
else if ( new_irq > next_irq ) {
else if (new_irq > next_irq)
{
new_irq = next_irq;
}
if ( new_irq != earliest_irq_ ) {
if (new_irq != earliest_irq_)
{
earliest_irq_ = new_irq;
if (irq_notifier_)
irq_notifier_(irq_data);
@ -173,7 +175,8 @@ void Nes_Apu::run_until_( nes_time_t end_time )
switch (frame++)
{
case 0:
if ( !(frame_mode & 0xc0) ) {
if (!(frame_mode & 0xc0))
{
next_irq = time + frame_period * 4 + 1;
irq_flag = true;
}
@ -239,13 +242,16 @@ void Nes_Apu::end_frame( nes_time_t end_time )
last_time -= end_time;
last_dmc_time -= end_time;
if ( next_irq != no_irq ) {
if (next_irq != no_irq)
{
next_irq -= end_time;
}
if ( dmc.next_irq != no_irq ) {
if (dmc.next_irq != no_irq)
{
dmc.next_irq -= end_time;
}
if ( earliest_irq_ != no_irq ) {
if (earliest_irq_ != no_irq)
{
earliest_irq_ -= end_time;
if (earliest_irq_ < 0)
earliest_irq_ = 0;
@ -255,11 +261,7 @@ void Nes_Apu::end_frame( nes_time_t end_time )
// registers
static const unsigned char length_table[0x20] = {
0x0A, 0xFE, 0x14, 0x02, 0x28, 0x04, 0x50, 0x06,
0xA0, 0x08, 0x3C, 0x0A, 0x0E, 0x0C, 0x1A, 0x0E,
0x0C, 0x10, 0x18, 0x12, 0x30, 0x14, 0x60, 0x16,
0xC0, 0x18, 0x48, 0x1A, 0x10, 0x1C, 0x20, 0x1E
};
0x0A, 0xFE, 0x14, 0x02, 0x28, 0x04, 0x50, 0x06, 0xA0, 0x08, 0x3C, 0x0A, 0x0E, 0x0C, 0x1A, 0x0E, 0x0C, 0x10, 0x18, 0x12, 0x30, 0x14, 0x60, 0x16, 0xC0, 0x18, 0x48, 0x1A, 0x10, 0x1C, 0x20, 0x1E};
void Nes_Apu::write_register(nes_time_t time, nes_addr_t addr, int data)
{
@ -307,11 +309,13 @@ void Nes_Apu::write_register( nes_time_t time, nes_addr_t addr, int data )
int old_enables = osc_enables;
osc_enables = data;
if ( !(data & 0x10) ) {
if (!(data & 0x10))
{
dmc.next_irq = no_irq;
recalc_irq = true;
}
else if ( !(old_enables & 0x10) ) {
else if (!(old_enables & 0x10))
{
dmc.start(); // dmc just enabled
}
@ -356,7 +360,8 @@ int Nes_Apu::read_status( nes_time_t time )
run_until_(time);
if ( irq_flag ) {
if (irq_flag)
{
irq_flag = false;
irq_changed();
}

View File

@ -3,14 +3,13 @@
// NES 2A03 APU sound chip emulator
// Nes_Snd_Emu 0.1.7
#include <cstdint>
#include <cstdint>
#include <climits>
#include "Nes_Oscs.hpp"
#include <climits>
#include <cstdint>
class Nes_Apu {
class Nes_Apu
{
public:
typedef uint8_t env_t[3];
/*struct env_t {
uint8_t delay;
@ -18,7 +17,8 @@ public:
uint8_t written;
};*/
struct apu_t {
struct apu_t
{
uint8_t w40xx[0x14]; // $4000-$4013
uint8_t w4015; // enables
uint8_t w4017; // mode
@ -27,7 +27,8 @@ public:
uint8_t irq_flag;
};
struct square_t {
struct square_t
{
uint16_t delay;
env_t env;
uint8_t length_counter;
@ -37,7 +38,8 @@ public:
uint8_t unused2[1];
};
struct triangle_t {
struct triangle_t
{
uint16_t delay;
uint8_t length_counter;
uint8_t phase;
@ -45,14 +47,16 @@ public:
uint8_t linear_mode;
};
struct noise_t {
struct noise_t
{
uint16_t delay;
env_t env;
uint8_t length_counter;
uint16_t shift_reg;
};
struct dmc_t {
struct dmc_t
{
uint16_t delay;
uint16_t remain;
uint16_t addr;
@ -158,6 +162,7 @@ private:
friend class Nes_Nonlinearizer;
void enable_nonlinear(double volume);
static double nonlinear_tnd_gain() { return 0.75; }
private:
friend struct Nes_Dmc;
@ -231,7 +236,6 @@ inline nes_time_t Nes_Dmc::next_read_time() const
inline nes_time_t Nes_Apu::next_dmc_read_time() const { return dmc.next_read_time(); }
template <int mode>
struct apu_reflection
{
@ -288,7 +292,6 @@ struct apu_reflection
}
};
inline void Nes_Apu::save_state(apu_state_t *state) const
{
for (int i = 0; i < osc_count * 4; i++)

View File

@ -1,8 +1,8 @@
// Nes_Emu 0.7.0. http://www.slack.net/~ant/
#include <cstring>
#include "apu/fme7/apu.hpp"
#include <cstring>
/* Copyright (C) 2003-2006 Shay Green. This module is free software; you
can redistribute it and/or modify it under the terms of the GNU Lesser
@ -29,10 +29,7 @@ void Nes_Fme7_Apu::reset()
unsigned char Nes_Fme7_Apu::amp_table[16] =
{
#define ENTRY(n) (unsigned char)(n * +amp_range + 0.5)
ENTRY(0.0000), ENTRY(0.0078), ENTRY(0.0110), ENTRY(0.0156),
ENTRY(0.0221), ENTRY(0.0312), ENTRY(0.0441), ENTRY(0.0624),
ENTRY(0.0883), ENTRY(0.1249), ENTRY(0.1766), ENTRY(0.2498),
ENTRY(0.3534), ENTRY(0.4998), ENTRY(0.7070), ENTRY(1.0000)
ENTRY(0.0000), ENTRY(0.0078), ENTRY(0.0110), ENTRY(0.0156), ENTRY(0.0221), ENTRY(0.0312), ENTRY(0.0441), ENTRY(0.0624), ENTRY(0.0883), ENTRY(0.1249), ENTRY(0.1766), ENTRY(0.2498), ENTRY(0.3534), ENTRY(0.4998), ENTRY(0.7070), ENTRY(1.0000)
#undef ENTRY
};
@ -85,8 +82,7 @@ void Nes_Fme7_Apu::run_until( blip_time_t end_time )
delta = -delta;
synth.offset_inline(time, delta, osc_output);
time += period;
}
while ( time < end_time );
} while (time < end_time);
oscs[index].last_amp = (delta + volume) >> 1;
phases[index] = (delta > 0);

View File

@ -3,12 +3,15 @@
// Sunsoft FME-7 sound emulator
// Nes_Emu 0.7.0
#include <cstdint>
#include "apu/Blip_Buffer.hpp"
#include <cstdint>
struct fme7_apu_state_t
{
enum { reg_count = 14 };
enum
{
reg_count = 14
};
uint8_t regs[reg_count];
uint8_t phases[3]; // 0 or 1
uint8_t latch;
@ -16,7 +19,8 @@ struct fme7_apu_state_t
};
static_assert(sizeof(fme7_apu_state_t) == 24);
class Nes_Fme7_Apu : private fme7_apu_state_t {
class Nes_Fme7_Apu : private fme7_apu_state_t
{
public:
Nes_Fme7_Apu();
@ -25,16 +29,28 @@ public:
void volume(double);
void treble_eq(blip_eq_t const &);
void output(Blip_Buffer *);
enum { osc_count = 3 };
enum
{
osc_count = 3
};
void osc_output(int index, Blip_Buffer *);
void end_frame(blip_time_t);
void save_state(fme7_apu_state_t *) const;
void load_state(fme7_apu_state_t const &);
// Mask and addresses of registers
enum { addr_mask = 0xe000 };
enum { data_addr = 0xe000 };
enum { latch_addr = 0xc000 };
enum
{
addr_mask = 0xe000
};
enum
{
data_addr = 0xe000
};
enum
{
latch_addr = 0xc000
};
// (addr & addr_mask) == latch_addr
void write_latch(int);
@ -50,13 +66,17 @@ private:
static unsigned char amp_table[16];
struct {
struct
{
Blip_Buffer *output;
int last_amp;
} oscs[osc_count];
blip_time_t last_time;
enum { amp_range = 192 }; // can be any value; this gives best error/quality tradeoff
enum
{
amp_range = 192
}; // can be any value; this gives best error/quality tradeoff
Blip_Synth<blip_good_quality, 1> synth;
void run_until(blip_time_t);
@ -128,4 +148,3 @@ inline void Nes_Fme7_Apu::load_state( fme7_apu_state_t const& in )
// Run sound channels for 0 cycles for clean audio after loading state
run_until(last_time);
}

View File

@ -1,8 +1,8 @@
// Nes_Snd_Emu 0.1.7. http://www.slack.net/~ant/
#include "apu/Blip_Buffer.hpp"
#include "apu/namco/apu.hpp"
#include "apu/Blip_Buffer.hpp"
/* Copyright (C) 2003-2006 Shay Green. This module is free software; you
can redistribute it and/or modify it under the terms of the GNU Lesser
@ -133,8 +133,7 @@ void Nes_Namco_Apu::run_until( nes_time_t nes_end_time )
time += period;
if (wave_pos >= wave_size)
wave_pos = 0;
}
while ( time < end_time );
} while (time < end_time);
osc.wave_pos = wave_pos;
osc.last_amp = last_amp;

View File

@ -3,8 +3,8 @@
// Namco 106 sound chip emulator
// Nes_Snd_Emu 0.1.7
#include <cstdint>
#include "apu/apu.hpp"
#include <cstdint>
struct namco_state_t
{
@ -16,7 +16,8 @@ struct namco_state_t
};
static_assert(sizeof(namco_state_t) == 172);
class Nes_Namco_Apu {
class Nes_Namco_Apu
{
public:
Nes_Namco_Apu();
~Nes_Namco_Apu();
@ -25,18 +26,27 @@ public:
void volume(double);
void treble_eq(const blip_eq_t &);
void output(Blip_Buffer *);
enum { osc_count = 8 };
enum
{
osc_count = 8
};
void osc_output(int index, Blip_Buffer *);
void reset();
void end_frame(nes_time_t);
// Read/write data register is at 0x4800
enum { data_reg_addr = 0x4800 };
enum
{
data_reg_addr = 0x4800
};
void write_data(nes_time_t, int);
int read_data();
// Write-only address register is at 0xF800
enum { addr_reg_addr = 0xF800 };
enum
{
addr_reg_addr = 0xF800
};
void write_addr(int);
// to do: implement save/restore
@ -48,7 +58,8 @@ private:
Nes_Namco_Apu(const Nes_Namco_Apu &);
Nes_Namco_Apu &operator=(const Nes_Namco_Apu &);
struct Namco_Osc {
struct Namco_Osc
{
long delay;
Blip_Buffer *output;
short last_amp;
@ -60,7 +71,10 @@ private:
nes_time_t last_time;
int addr_reg;
enum { reg_count = 0x80 };
enum
{
reg_count = 0x80
};
uint8_t reg[reg_count];
Blip_Synth<blip_good_quality, 15> synth;
@ -94,4 +108,3 @@ inline void Nes_Namco_Apu::write_data( nes_time_t time, int data )
run_until(time);
access() = data;
}

View File

@ -146,8 +146,7 @@ void Nes_Vrc6_Apu::run_square( Vrc6_Osc& osc, nes_time_t end_time )
square_synth.offset(time, -volume, output);
}
time += period;
}
while ( time < end_time );
} while (time < end_time);
osc.phase = phase;
}
@ -198,8 +197,7 @@ void Nes_Vrc6_Apu::run_saw( nes_time_t end_time )
time += period;
amp = (amp + amp_step) & 0xFF;
}
while ( time < end_time );
} while (time < end_time);
osc.phase = phase;
osc.amp = amp;

View File

@ -4,13 +4,14 @@
// Konami VRC6 sound chip emulator
// Nes_Snd_Emu 0.1.7
#include <cstdint>
#include "apu/apu.hpp"
#include "apu/Blip_Buffer.hpp"
#include "apu/apu.hpp"
#include <cstdint>
struct vrc6_apu_state_t;
class Nes_Vrc6_Apu {
class Nes_Vrc6_Apu
{
public:
Nes_Vrc6_Apu();
~Nes_Vrc6_Apu();
@ -20,7 +21,10 @@ public:
void volume(double);
void treble_eq(blip_eq_t const &);
void output(Blip_Buffer *);
enum { osc_count = 3 };
enum
{
osc_count = 3
};
void osc_output(int index, Blip_Buffer *);
void end_frame(nes_time_t);
void save_state(vrc6_apu_state_t *) const;
@ -29,9 +33,18 @@ public:
// Oscillator 0 write-only registers are at $9000-$9002
// Oscillator 1 write-only registers are at $A000-$A002
// Oscillator 2 write-only registers are at $B000-$B002
enum { reg_count = 3 };
enum { base_addr = 0x9000 };
enum { addr_step = 0x1000 };
enum
{
reg_count = 3
};
enum
{
base_addr = 0x9000
};
enum
{
addr_step = 0x1000
};
void write_osc(nes_time_t, int osc, int reg, int data);
private:

View File

@ -2,7 +2,9 @@
#include "apu/vrc7/emu2413.hpp"
#include <cstring>
#define BYTESWAP(xxxx) {uint32_t _temp = (uint32_t)(xxxx);\
#define BYTESWAP(xxxx) \
{ \
uint32_t _temp = (uint32_t)(xxxx); \
((uint8_t *)&(xxxx))[0] = (uint8_t)((_temp) >> 24); \
((uint8_t *)&(xxxx))[1] = (uint8_t)((_temp) >> 16); \
((uint8_t *)&(xxxx))[2] = (uint8_t)((_temp) >> 8); \

View File

@ -4,14 +4,15 @@
// Konami VRC7 sound chip emulator
// Nes_Snd_Emu 0.1.7. Copyright (C) 2003-2005 Shay Green. GNU LGPL license.
#include <cstdint>
#include "apu/vrc7/emu2413_state.hpp"
#include "apu/Blip_Buffer.hpp"
#include "apu/vrc7/emu2413_state.hpp"
#include <cstdint>
struct vrc7_snapshot_t;
typedef long nes_time_t;
class Nes_Vrc7 {
class Nes_Vrc7
{
public:
Nes_Vrc7();
~Nes_Vrc7();
@ -21,7 +22,10 @@ public:
void volume(double);
void treble_eq(blip_eq_t const &);
void output(Blip_Buffer *);
enum { osc_count = 6 };
enum
{
osc_count = 6
};
void osc_output(int index, Blip_Buffer *);
void end_frame(nes_time_t);
void save_snapshot(vrc7_snapshot_t *);
@ -68,4 +72,3 @@ inline void Nes_Vrc7::osc_output( int i, Blip_Buffer* buf )
{
oscs[i].output = buf;
}

View File

@ -56,10 +56,10 @@ if the origin of this software is not misrepresented.
YM2143 data sheet
**************************************************************************************/
#include "emu2413.hpp"
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "emu2413.hpp"
static const unsigned char default_inst[15][8] = {
/* 2019-03-19 VRC7 instrument patchset dumped by Nuke.YKT */
@ -78,8 +78,7 @@ static const unsigned char default_inst[15][8] = {
{0x71, 0x23, 0x11, 0x06, 0x65, 0x74, 0x18, 0x16},
{0x01, 0x02, 0xD3, 0x05, 0xC9, 0x95, 0x03, 0x02},
{0x61, 0x63, 0x0C, 0x00, 0x94, 0xC0, 0x33, 0xF6},
{ 0x21, 0x72, 0x0D, 0x00, 0xC1, 0xD5, 0x56, 0x06 }
};
{0x21, 0x72, 0x0D, 0x00, 0xC1, 0xD5, 0x56, 0x06}};
#define EG2DB(d) ((d) * (e_int32)(EG_STEP / DB_STEP))
#define TL2EG(d) ((d) * (e_int32)(TL_STEP / EG_STEP))
@ -128,7 +127,15 @@ static const unsigned char default_inst[15][8] = {
/* Definition of envelope mode */
enum
{ SETTLE, ATTACK, DECAY, SUSHOLD, SUSTINE, RELEASE, FINISH };
{
SETTLE,
ATTACK,
DECAY,
SUSHOLD,
SUSTINE,
RELEASE,
FINISH
};
/***************************************************
@ -153,7 +160,6 @@ static void makeAdjustTable (OPLL * opll)
opll->AR_ADJUST_TABLE[i] = (e_uint16)((double)(1 << EG_BITS) - 1 - (1 << EG_BITS) * log((double)i) / log(128.));
}
/* Table for dB(0 -- (1<<DB_BITS)-1) to Liner(0 -- DB2LIN_AMP_WIDTH) */
static void makeDB2LinTable(OPLL *opll)
{
@ -175,7 +181,6 @@ static e_int32 lin2db (double d)
return Min(-(e_int32)(20.0 * log10(d) / DB_STEP), DB_MUTE - 1); /* 0 -- 127 */
}
/* Sin Table */
static void makeSinTable(OPLL *opll)
{
@ -238,9 +243,7 @@ static void makeTllTable (OPLL *opll)
#define dB2(x) ((x)*2)
static const double kltable[16] = {
dB2 (0.000), dB2 (9.000), dB2 (12.000), dB2 (13.875), dB2 (15.000), dB2 (16.125), dB2 (16.875), dB2 (17.625),
dB2 (18.000), dB2 (18.750), dB2 (19.125), dB2 (19.500), dB2 (19.875), dB2 (20.250), dB2 (20.625), dB2 (21.000)
};
dB2(0.000), dB2(9.000), dB2(12.000), dB2(13.875), dB2(15.000), dB2(16.125), dB2(16.875), dB2(17.625), dB2(18.000), dB2(18.750), dB2(19.125), dB2(19.500), dB2(19.875), dB2(20.250), dB2(20.625), dB2(21.000)};
e_int32 tmp;
e_int32 fnum, block, TL, KL;
@ -282,8 +285,7 @@ static const double attacktime[16][4] = {
{0.84, 0.70, 0.60, 0.54},
{0.50, 0.42, 0.34, 0.30},
{0.28, 0.22, 0.18, 0.14},
{0.00, 0.00, 0.00, 0.00}
};
{0.00, 0.00, 0.00, 0.00}};
static const double decaytime[16][4] = {
{0, 0, 0, 0},
@ -301,8 +303,7 @@ static const double decaytime[16][4] = {
{10.22, 8.21, 6.84, 5.87},
{5.11, 4.10, 3.42, 2.94},
{2.55, 2.05, 1.71, 1.47},
{1.27, 1.27, 1.27, 1.27}
};
{1.27, 1.27, 1.27, 1.27}};
#endif
/* Rate Table for Attack */
@ -321,7 +322,6 @@ static void makeDphaseARTable(OPLL * opll)
attacktable[RM][RL] = EG_DP_WIDTH;
else
attacktable[RM][RL] = (e_uint32)((double)(1 << EG_DP_BITS) / (attacktime[RM][RL] * 3579545 / 72000));
}
#endif
@ -392,7 +392,6 @@ static void makeDphaseDRTable (OPLL * opll)
static void makeRksTable(OPLL *opll)
{
e_int32 fnum8, block, KR;
for (fnum8 = 0; fnum8 < 2; fnum8++)
@ -414,7 +413,6 @@ static void makeRksTable (OPLL *opll)
INLINE static e_uint32 calc_eg_dphase(OPLL *opll, OPLL_SLOT *slot)
{
switch (slot->eg_mode)
{
case ATTACK:
@ -453,9 +451,7 @@ INLINE static e_uint32 calc_eg_dphase (OPLL *opll, OPLL_SLOT * slot)
#define UPDATE_PG(S) (S)->dphase = opll->dphaseTable[(S)->fnum][(S)->block][(S)->patch.ML]
#define UPDATE_TLL(S) \
(((S)->type==0)?\
((S)->tll = opll->tllTable[((S)->fnum)>>5][(S)->block][(S)->patch.TL][(S)->patch.KL]):\
((S)->tll = opll->tllTable[((S)->fnum)>>5][(S)->block][(S)->volume][(S)->patch.KL]))
(((S)->type == 0) ? ((S)->tll = opll->tllTable[((S)->fnum) >> 5][(S)->block][(S)->patch.TL][(S)->patch.KL]) : ((S)->tll = opll->tllTable[((S)->fnum) >> 5][(S)->block][(S)->volume][(S)->patch.KL]))
#define UPDATE_RKS(S) (S)->rks = opll->rksTable[((S)->fnum) >> 8][(S)->block][(S)->patch.KR]
#define UPDATE_WF(S) (S)->sintbl = opll->waveform[(S)->patch.WF]
#define UPDATE_EG(S) (S)->eg_dphase = calc_eg_dphase(opll, S)
@ -466,7 +462,6 @@ INLINE static e_uint32 calc_eg_dphase (OPLL *opll, OPLL_SLOT * slot)
UPDATE_WF(S); \
UPDATE_EG(S) /* EG should be updated last. */
/* Slot key on */
INLINE static void slotOn(OPLL_SLOT *slot)
{
@ -607,7 +602,6 @@ OPLL *OPLL_new (e_uint32 clk)
return opll;
}
void OPLL_delete(OPLL *opll)
{
free(opll);
@ -690,8 +684,6 @@ void OPLL_forceRefresh (OPLL * opll)
#define wave2_8pi(e) ((e) << (2 + PG_BITS - SLOT_AMP_BITS))
#endif
/* Update AM, PM unit */
static void update_ampm(OPLL *opll)
{
@ -721,15 +713,12 @@ static void calc_envelope(OPLL *opll, OPLL_SLOT * slot, e_int32 lfo)
#define S2E(x) (SL2EG((e_int32)(x / SL_STEP)) << (EG_DP_BITS - EG_BITS))
static const e_uint32 SL[16] = {
S2E (0.0), S2E (3.0), S2E (6.0), S2E (9.0), S2E (12.0), S2E (15.0), S2E (18.0), S2E (21.0),
S2E (24.0), S2E (27.0), S2E (30.0), S2E (33.0), S2E (36.0), S2E (39.0), S2E (42.0), S2E (48.0)
};
S2E(0.0), S2E(3.0), S2E(6.0), S2E(9.0), S2E(12.0), S2E(15.0), S2E(18.0), S2E(21.0), S2E(24.0), S2E(27.0), S2E(30.0), S2E(33.0), S2E(36.0), S2E(39.0), S2E(42.0), S2E(48.0)};
e_uint32 egout;
switch (slot->eg_mode)
{
case ATTACK:
egout = opll->AR_ADJUST_TABLE[HIGHBITS(slot->eg_phase, EG_DP_BITS - EG_BITS)];
slot->eg_phase += slot->eg_dphase;
@ -843,7 +832,6 @@ INLINE static e_int32 calc_slot_mod(OPLL *opll, OPLL_SLOT * slot)
slot->feedback = (slot->output[1] + slot->output[0]) >> 1;
return slot->feedback;
}
static INLINE e_int16 calc(OPLL *opll)
@ -989,10 +977,8 @@ static void setInstrument(OPLL * opll, e_uint i, e_uint inst)
carp->RR = (src[7] & 0xF);
}
void OPLL_writeReg(OPLL *opll, e_uint32 reg, e_uint32 data)
{
e_int32 i, v, ch;
data = data & 0xff;
@ -1152,7 +1138,6 @@ void OPLL_writeReg (OPLL * opll, e_uint32 reg, e_uint32 data)
default:
break;
}
}

View File

@ -40,7 +40,6 @@ typedef unsigned int e_uint32;
#define SL_BITS 4
#define SL_MUTE (1 << SL_BITS)
/* Bits for Pitch and Amp modulator */
#define PM_PG_BITS 8
#define PM_PG_WIDTH (1 << PM_PG_BITS)
@ -51,7 +50,6 @@ typedef unsigned int e_uint32;
#define AM_DP_BITS 16
#define AM_DP_WIDTH (1 << AM_DP_BITS)
#ifdef EMU2413_DLL_EXPORTS
#define EMU2413_API __declspec(dllexport)
#elif defined(EMU2413_DLL_IMPORTS)
@ -61,21 +59,26 @@ typedef unsigned int e_uint32;
#endif
#ifdef __cplusplus
extern "C" {
extern "C"
{
#endif
#define PI 3.14159265358979323846
enum {OPLL_VRC7_TONE=0} ;
enum
{
OPLL_VRC7_TONE = 0
};
/* voice data */
typedef struct {
typedef struct
{
e_uint32 TL, FB, EG, ML, AR, DR, SL, RR, KR, KL, AM, PM, WF;
} OPLL_PATCH;
/* slot */
typedef struct {
typedef struct
{
OPLL_PATCH patch;
e_int32 type; /* 0 : modulator 1 : carrier */
@ -108,8 +111,8 @@ typedef struct {
#define OPLL_MASK_CH(x) (1 << (x))
/* opll */
typedef struct {
typedef struct
{
e_uint32 adr;
e_int32 out;
@ -213,4 +216,3 @@ EMU2413_API e_uint32 OPLL_toggleMask(OPLL *, e_uint32 mask) ;
#ifdef __cplusplus
}
#endif

View File

@ -1,5 +1,5 @@
#include <stdint.h>
#include "emu2413_state.hpp"
#include <stdint.h>
#ifdef __cplusplus
extern "C"
@ -34,15 +34,19 @@ void OPLL_serialize(const OPLL * opll, OPLL_STATE* state)
}
}
#define BYTESWAP(xxxx) {uint32_t _temp = (uint32_t)(xxxx);\
#define BYTESWAP(xxxx) \
{ \
uint32_t _temp = (uint32_t)(xxxx); \
((uint8_t *)&(xxxx))[0] = (uint8_t)((_temp) >> 24); \
((uint8_t *)&(xxxx))[1] = (uint8_t)((_temp) >> 16); \
((uint8_t *)&(xxxx))[2] = (uint8_t)((_temp) >> 8); \
((uint8_t *)&(xxxx))[3] = (uint8_t)((_temp) >> 0); \
}
#define SET(xxxx,yyyy) { if ((xxxx) != (yyyy)) {\
#define SET(xxxx, yyyy) \
{ \
if ((xxxx) != (yyyy)) \
{ \
(xxxx) = (yyyy); \
}

View File

@ -2,7 +2,8 @@
#include "emu2413.hpp"
typedef struct {
typedef struct
{
e_int32 feedback;
e_int32 output[2];
e_uint32 phase;
@ -13,7 +14,8 @@ typedef struct {
e_uint32 egout;
} OPLL_SLOT_STATE;
typedef struct {
typedef struct
{
e_uint32 pm_phase;
e_int32 am_phase;
OPLL_SLOT_STATE slot[6 * 2];

View File

@ -1,9 +1,9 @@
// Nes_Emu 0.7.0. http://www.slack.net/~ant/
#include <cstring>
#include "mappers/mapper.hpp"
#include "Nes_Core.hpp"
#include <cstring>
/* Copyright (C) 2004-2006 Shay Green. This module is free software; you
can redistribute it and/or modify it under the terms of the GNU Lesser
@ -209,7 +209,6 @@ void Nes_Mapper::mirror_manual( int page0, int page1, int page2, int page3 )
emu().ppu.set_nt_banks(page0, page1, page2, page3);
}
void Nes_Mapper::intercept_reads(nes_addr_t addr, unsigned size)
{
emu().add_mapper_intercept(addr, size, true, false);

View File

@ -3,9 +3,9 @@
// NES mapper interface
// Nes_Emu 0.7.0
#include <climits>
#include "Nes_Cart.hpp"
#include "Nes_Cpu.hpp"
#include <climits>
class Blip_Buffer;
class blip_eq_t;
@ -17,7 +17,8 @@ static unsigned const max_mapper_state_size = 512; //was 256, needed more for
struct mapper_state_t
{
int size;
union {
union
{
double align;
uint8_t data[max_mapper_state_size];
};
@ -26,7 +27,8 @@ struct mapper_state_t
int read(void *p, unsigned long s) const;
};
class Nes_Mapper {
class Nes_Mapper
{
public:
virtual ~Nes_Mapper();
@ -53,7 +55,10 @@ public:
// Timing
// Time returned when current mapper state won't ever cause an IRQ
enum { no_irq = LONG_MAX / 2 };
enum
{
no_irq = LONG_MAX / 2
};
// Time next IRQ will occur at
virtual nes_time_t next_irq(nes_time_t present);
@ -108,7 +113,8 @@ protected:
void intercept_reads(nes_addr_t addr, unsigned size);
// Bank sizes for mapping
enum bank_size_t { // 1 << bank_Xk = X * 1024
enum bank_size_t
{ // 1 << bank_Xk = X * 1024
bank_1k = 10,
bank_2k = 11,
bank_4k = 12,
@ -119,7 +125,10 @@ protected:
// Index of last PRG/CHR bank. Last_bank selects last bank, last_bank - 1
// selects next-to-last bank, etc.
enum { last_bank = -1 };
enum
{
last_bank = -1
};
// Map 'size' bytes from 'PRG + bank * size' to CPU address space starting at 'addr'
void set_prg_bank(nes_addr_t addr, bank_size_t size, int bank);
@ -163,15 +172,12 @@ protected:
// apply_mapping().
virtual void read_state(mapper_state_t const &);
// Called by default reset() before apply_mapping() is called.
virtual void reset_state() {}
// End of general interface
public:
Nes_Cart const *cart_;
Nes_Core *emu_;
@ -184,7 +190,6 @@ protected:
static Nes_Mapper *getMapperFromCode(const int mapperCode);
};
inline int Nes_Mapper::handle_bus_conflict(nes_addr_t addr, int data) { return data; }
inline void Nes_Mapper::mirror_horiz(int p) { mirror_manual(p, p, p ^ 1, p ^ 1); }
inline void Nes_Mapper::mirror_vert(int p) { mirror_manual(p, p ^ 1, p, p ^ 1); }

View File

@ -19,7 +19,8 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
// NROM
class Mapper000 : public Nes_Mapper {
class Mapper000 : public Nes_Mapper
{
public:
Mapper000() {}

View File

@ -26,7 +26,8 @@ struct mmc1_state_t
};
static_assert(sizeof(mmc1_state_t) == 6);
class Mapper001 : public Nes_Mapper, mmc1_state_t {
class Mapper001 : public Nes_Mapper, mmc1_state_t
{
public:
Mapper001()
{
@ -75,7 +76,6 @@ public:
}
}
void register_changed(int reg)
{
// Mirroring
@ -122,5 +122,3 @@ public:
}
}
};

View File

@ -19,8 +19,10 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
// UNROM
class Mapper002 : public Nes_Mapper {
class Mapper002 : public Nes_Mapper
{
uint8_t bank;
public:
Mapper002()
{
@ -39,4 +41,3 @@ public:
set_prg_bank(0x8000, bank_16k, data);
}
};

View File

@ -19,8 +19,10 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
// CNROM
class Mapper003 : public Nes_Mapper {
class Mapper003 : public Nes_Mapper
{
uint8_t bank;
public:
Mapper003()
{
@ -38,4 +40,3 @@ public:
set_chr_bank(0, bank_8k, bank & 7);
}
};

View File

@ -4,8 +4,8 @@
#include "mappers/mapper.hpp"
#include <cstring>
#include "Nes_Core.hpp"
#include <cstring>
/* Copyright (C) 2004-2006 Shay Green. This module is free software; you
can redistribute it and/or modify it under the terms of the GNU Lesser
@ -39,7 +39,8 @@ struct mmc3_state_t
};
static_assert(sizeof(mmc3_state_t) == 15);
class Mapper004 : public Nes_Mapper, mmc3_state_t {
class Mapper004 : public Nes_Mapper, mmc3_state_t
{
public:
Mapper004()
{
@ -92,7 +93,6 @@ public:
}
}
virtual void a12_clocked()
{
clock_counter();
@ -196,7 +196,8 @@ public:
{
switch (addr & 0xE001)
{
case 0x8000: {
case 0x8000:
{
int changed = mode ^ data;
mode = data;
// avoid unnecessary bank updates
@ -207,7 +208,8 @@ public:
break;
}
case 0x8001: {
case 0x8001:
{
int bank = mode & 7;
banks[bank] = data;
if (bank < 6)
@ -249,4 +251,3 @@ public:
nes_time_t next_time;
int counter_just_clocked; // used only for debugging
};

View File

@ -4,9 +4,9 @@
// Nes_Emu 0.7.0. http://www.slack.net/~ant/
#include <cstring>
#include "mappers/mapper.hpp"
#include "Nes_Core.hpp"
#include "mappers/mapper.hpp"
#include <cstring>
/* Copyright (C) 2004-2006 Shay Green. This module is free software; you
can redistribute it and/or modify it under the terms of the GNU Lesser
@ -21,7 +21,10 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
struct mmc5_state_t
{
enum { reg_count = 0x30 };
enum
{
reg_count = 0x30
};
uint8_t regs[0x30];
uint8_t irq_enabled;
};
@ -29,7 +32,8 @@ static_assert( sizeof (mmc5_state_t) == 0x31 );
// MMC5
class Mapper005 : public Nes_Mapper, mmc5_state_t {
class Mapper005 : public Nes_Mapper, mmc5_state_t
{
public:
Mapper005()
{
@ -54,7 +58,10 @@ public:
irq_time = no_irq;
}
enum { regs_addr = 0x5100 };
enum
{
regs_addr = 0x5100
};
virtual nes_time_t next_irq(nes_time_t)
{
@ -73,8 +80,7 @@ public:
switch (reg)
{
case 0x05:
mirror_manual( data & 3, data >> 2 & 3,
data >> 4 & 3, data >> 6 & 3 );
mirror_manual(data & 3, data >> 2 & 3, data >> 4 & 3, data >> 6 & 3);
break;
case 0x15:
@ -128,10 +134,7 @@ public:
void apply_mapping()
{
static unsigned char list[] = {
0x05, 0x15, 0x16, 0x17,
0x20, 0x21, 0x22, 0x23,
0x28, 0x29, 0x2a, 0x2b
};
0x05, 0x15, 0x16, 0x17, 0x20, 0x21, 0x22, 0x23, 0x28, 0x29, 0x2a, 0x2b};
for (int i = 0; i < (int)sizeof list; i++)
write_intercepted(0, regs_addr + list[i], regs[list[i]]);
@ -142,6 +145,3 @@ public:
nes_time_t irq_time;
};

View File

@ -19,8 +19,10 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
// AOROM
class Mapper007 : public Nes_Mapper {
class Mapper007 : public Nes_Mapper
{
uint8_t bank;
public:
Mapper007()
{
@ -46,5 +48,3 @@ public:
set_prg_bank(0x8000, bank_32k, bank & 7);
}
};

View File

@ -1,7 +1,7 @@
#pragma once
#include <cstring>
#include "mappers/mapper.hpp"
#include <cstring>
// MMC2
@ -47,13 +47,30 @@ public:
{
switch (addr >> 12)
{
case 0xa: regs[0] = data; set_prg_bank(0x8000, bank_8k, data); break;
case 0xb: regs[1] = data; set_chr_bank(0x0000, bank_4k, data); break;
case 0xc: regs[2] = data; set_chr_bank_ex(0x0000, bank_4k, data); break;
case 0xd: regs[3] = data; set_chr_bank(0x1000, bank_4k, data); break;
case 0xe: regs[4] = data; set_chr_bank_ex(0x1000, bank_4k, data); break;
case 0xf: regs[5] = data; mirror(data); break;
case 0xa:
regs[0] = data;
set_prg_bank(0x8000, bank_8k, data);
break;
case 0xb:
regs[1] = data;
set_chr_bank(0x0000, bank_4k, data);
break;
case 0xc:
regs[2] = data;
set_chr_bank_ex(0x0000, bank_4k, data);
break;
case 0xd:
regs[3] = data;
set_chr_bank(0x1000, bank_4k, data);
break;
case 0xe:
regs[4] = data;
set_chr_bank_ex(0x1000, bank_4k, data);
break;
case 0xf:
regs[5] = data;
mirror(data);
break;
}
}
};

View File

@ -1,6 +1,6 @@
#pragma once
#include <cstring>
#include "mappers/mapper.hpp"
#include <cstring>
// MMC4
@ -45,12 +45,30 @@ public:
{
switch (addr >> 12)
{
case 0xa: regs[0] = data; set_prg_bank(0x8000, bank_16k, data); break;
case 0xb: regs[1] = data; set_chr_bank(0x0000, bank_4k, data); break;
case 0xc: regs[2] = data; set_chr_bank_ex(0x0000, bank_4k, data); break;
case 0xd: regs[3] = data; set_chr_bank(0x1000, bank_4k, data); break;
case 0xe: regs[4] = data; set_chr_bank_ex(0x1000, bank_4k, data); break;
case 0xf: regs[5] = data; mirror(data); break;
case 0xa:
regs[0] = data;
set_prg_bank(0x8000, bank_16k, data);
break;
case 0xb:
regs[1] = data;
set_chr_bank(0x0000, bank_4k, data);
break;
case 0xc:
regs[2] = data;
set_chr_bank_ex(0x0000, bank_4k, data);
break;
case 0xd:
regs[3] = data;
set_chr_bank(0x1000, bank_4k, data);
break;
case 0xe:
regs[4] = data;
set_chr_bank_ex(0x1000, bank_4k, data);
break;
case 0xf:
regs[5] = data;
mirror(data);
break;
}
}
};

View File

@ -19,8 +19,10 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
// Color Dreams
class Mapper011 : public Nes_Mapper {
class Mapper011 : public Nes_Mapper
{
uint8_t bank;
public:
Mapper011()
{

View File

@ -29,7 +29,8 @@ static_assert( sizeof (Mapper015_state_t) == 5 );
// K-1029, K-1030P
class Mapper015 : public Nes_Mapper, Mapper015_state_t {
class Mapper015 : public Nes_Mapper, Mapper015_state_t
{
public:
Mapper015()
{
@ -89,4 +90,3 @@ public:
unsigned long int i;
};

View File

@ -4,8 +4,8 @@
// Nes_Emu 0.7.0. http://www.slack.net/~ant/
#include "mappers/mapper.hpp"
#include "apu/namco/apu.hpp"
#include "mappers/mapper.hpp"
/* Copyright (C) 2004-2006 Shay Green. This module is free software; you
can redistribute it and/or modify it under the terms of the GNU Lesser
@ -32,7 +32,8 @@ static_assert( sizeof (namco106_state_t) == 20 + sizeof (namco_state_t) );
// Namco106
class Mapper019 : public Nes_Mapper, namco106_state_t {
class Mapper019 : public Nes_Mapper, namco106_state_t
{
public:
Mapper019()
{
@ -194,5 +195,3 @@ public:
Nes_Namco_Apu sound;
nes_time_t last_time;
};

View File

@ -44,7 +44,8 @@ struct vrc2_state_t
static_assert(sizeof(vrc2_state_t) == 18);
template <bool type_a, bool type_b>
class Mapper_VRC2_4 : public Nes_Mapper, vrc2_state_t {
class Mapper_VRC2_4 : public Nes_Mapper, vrc2_state_t
{
public:
Mapper_VRC2_4()
{
@ -180,7 +181,10 @@ public:
}
unsigned is22, reg1mask, reg2mask;
enum { timer_period = 113 * 4 + 3 };
enum
{
timer_period = 113 * 4 + 3
};
private:
void set_mirroring()
@ -220,7 +224,8 @@ private:
template <bool type_a, bool type_b>
void Mapper_VRC2_4<type_a, type_b>::write_irq(nes_time_t time,
nes_addr_t addr, int data )
nes_addr_t addr,
int data)
{
// IRQ
run_until(time);
@ -246,5 +251,4 @@ void Mapper_VRC2_4<type_a, type_b>::write_irq( nes_time_t time,
irq_changed();
}
typedef Mapper_VRC2_4<true, true> Mapper021;

View File

@ -3,9 +3,9 @@
// Konami VRC6 mapper
// Nes_Emu 0.7.0. http://www.slack.net/~ant/
#include <cstring>
#include "mappers/mapper.hpp"
#include "apu/vrc6/apu.hpp"
#include "mappers/mapper.hpp"
#include <cstring>
/* Copyright (C) 2004-2006 Shay Green. This module is free software; you
can redistribute it and/or modify it under the terms of the GNU Lesser
@ -41,7 +41,8 @@ struct vrc6_state_t
static_assert(sizeof(vrc6_state_t) == 26 + sizeof(vrc6_apu_state_t));
template <int swapMask>
class Mapper_Vrc6 : public Nes_Mapper, vrc6_state_t {
class Mapper_Vrc6 : public Nes_Mapper, vrc6_state_t
{
public:
Mapper_Vrc6()
{
@ -136,8 +137,10 @@ public:
}
int swap_mask;
Nes_Vrc6_Apu sound;
enum { timer_period = 113 * 4 + 3 };
enum
{
timer_period = 113 * 4 + 3
};
void read_state(mapper_state_t const &in)
{
@ -191,7 +194,8 @@ void write_bank( nes_addr_t addr, int data )
set_prg_bank(0x8000, bank_16k, data);
break;
case 0xb003: {
case 0xb003:
{
mirroring = data;
// dprintf( "Change mirroring %d\n", data );
@ -224,5 +228,4 @@ void write_bank( nes_addr_t addr, int data )
}
};
typedef Mapper_Vrc6<0> Mapper024;

View File

@ -31,7 +31,8 @@
// Unrom512
class Mapper030 : public Nes_Mapper {
class Mapper030 : public Nes_Mapper
{
public:
Mapper030() {}
@ -48,4 +49,3 @@ public:
}
}
};

View File

@ -36,7 +36,8 @@ static_assert( sizeof ( mapper32_state_t ) == 12 );
// Irem_G101
class Mapper032 : public Nes_Mapper, mapper32_state_t {
class Mapper032 : public Nes_Mapper, mapper32_state_t
{
public:
Mapper032()
{
@ -107,12 +108,17 @@ public:
switch (addr & 0xF007)
{
case 0xB000: case 0xB001: case 0xB002: case 0xB003:
case 0xB004: case 0xB005: case 0xB006: case 0xB007:
case 0xB000:
case 0xB001:
case 0xB002:
case 0xB003:
case 0xB004:
case 0xB005:
case 0xB006:
case 0xB007:
chr_bank[addr & 0x07] = data;
set_chr_bank((addr & 0x07) << 10, bank_1k, data);
break;
}
}
};

View File

@ -35,7 +35,8 @@ static_assert( sizeof ( tc0190_state_t ) == 9 );
// TaitoTC0190
class Mapper033 : public Nes_Mapper, tc0190_state_t {
class Mapper033 : public Nes_Mapper, tc0190_state_t
{
public:
Mapper033()
{
@ -44,7 +45,8 @@ public:
}
virtual void reset_state()
{ }
{
}
virtual void apply_mapping()
{
@ -57,8 +59,10 @@ public:
for (int i = 0; i < 4; i++)
set_chr_bank(0x1000 + (i << 10), bank_1k, creg[2 + i]);
if ( mirr ) mirror_horiz();
else mirror_vert();
if (mirr)
mirror_horiz();
else
mirror_vert();
}
virtual void write(nes_time_t, nes_addr_t addr, int data)
@ -69,20 +73,25 @@ public:
preg[0] = data & 0x3F;
mirr = data >> 6;
set_prg_bank(0x8000, bank_8k, preg[0]);
if ( mirr ) mirror_horiz();
else mirror_vert();
if (mirr)
mirror_horiz();
else
mirror_vert();
break;
case 0x8001:
preg[1] = data & 0x3F;
set_prg_bank(0xA000, bank_8k, preg[1]);
break;
case 0x8002: case 0x8003:
case 0x8002:
case 0x8003:
addr &= 0x01;
creg[addr] = data;
set_chr_bank(addr << 11, bank_2k, creg[addr]);
break;
case 0xA000: case 0xA001:
case 0xA002: case 0xA003:
case 0xA000:
case 0xA001:
case 0xA002:
case 0xA003:
addr &= 0x03;
creg[2 + addr] = data;
set_chr_bank(0x1000 | (addr << 10), bank_1k, creg[2 + addr]);

View File

@ -19,8 +19,10 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
// Nina-1 (Deadly Towers only)
class Mapper034 : public Nes_Mapper {
class Mapper034 : public Nes_Mapper
{
uint8_t bank;
public:
Mapper034()
{
@ -38,4 +40,3 @@ public:
set_prg_bank(0x8000, bank_32k, bank);
}
};

View File

@ -21,7 +21,8 @@
// NROM-128 4-in-1 multicart
class Mapper060 : public Nes_Mapper {
class Mapper060 : public Nes_Mapper
{
public:
Mapper060()
{

View File

@ -19,8 +19,10 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
// GNROM
class Mapper066 : public Nes_Mapper {
class Mapper066 : public Nes_Mapper
{
uint8_t bank;
public:
Mapper066()
{
@ -46,4 +48,3 @@ public:
set_chr_bank(0, bank_8k, bank & 3);
}
};

View File

@ -4,8 +4,8 @@
// Nes_Emu 0.7.0. http://www.slack.net/~ant/libs/
#include "mappers/mapper.hpp"
#include "apu/fme7/apu.hpp"
#include "mappers/mapper.hpp"
/* Copyright (C) 2005 Chris Moeller */
/* Copyright (C) 2005-2006 Shay Green. This module is free software; you
@ -34,7 +34,8 @@ static_assert( sizeof (fme7_state_t) == 18 + sizeof (fme7_apu_state_t) );
// Fme7
class Mapper069 : public Nes_Mapper, fme7_state_t {
class Mapper069 : public Nes_Mapper, fme7_state_t
{
public:
Mapper069()
{
@ -132,7 +133,6 @@ public:
}
}
void write_irq(nes_time_t time, int index, int data)
{
run_until(time);
@ -186,5 +186,3 @@ public:
nes_time_t last_time;
Nes_Fme7_Apu sound;
};

View File

@ -28,7 +28,8 @@
// Mapper_74x161x162x32
template <int mapperId>
class Mapper_74x161x162x32 : public Nes_Mapper {
class Mapper_74x161x162x32 : public Nes_Mapper
{
public:
Mapper_74x161x162x32()
{

View File

@ -19,8 +19,10 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
// Camerica
class Mapper071 : public Nes_Mapper {
class Mapper071 : public Nes_Mapper
{
uint8_t regs[3];
public:
Mapper071()
{
@ -48,7 +50,3 @@ public:
}
}
};

View File

@ -38,7 +38,8 @@ struct vrc3_state_t
// VRC3
class Mapper073 : public Nes_Mapper, vrc3_state_t {
class Mapper073 : public Nes_Mapper, vrc3_state_t
{
public:
Mapper073()
{

View File

@ -30,7 +30,8 @@ static_assert( sizeof ( vrc1_state_t ) == 8 );
// VRC1
class Mapper075 : public Nes_Mapper, vrc1_state_t {
class Mapper075 : public Nes_Mapper, vrc1_state_t
{
public:
Mapper075()
{
@ -105,5 +106,3 @@ public:
}
}
};

View File

@ -4,7 +4,8 @@
// Holy Diver and Uchuusen - Cosmo Carrier.
class Mapper078 : public Nes_Mapper {
class Mapper078 : public Nes_Mapper
{
// lower 8 bits are the reg at 8000:ffff
// next two bits are autodetecting type
// 0 = unknown 1 = cosmo carrier 2 = holy diver

View File

@ -28,7 +28,8 @@
#include "mappers/mapper.hpp"
template <bool multicart>
class Mapper_AveNina : public Nes_Mapper {
class Mapper_AveNina : public Nes_Mapper
{
public:
Mapper_AveNina()
{
@ -82,8 +83,10 @@ void Mapper_AveNina< multicart >::write_regs()
{
set_prg_bank(0x8000, bank_32k, (regs >> 3) & 0x07);
set_chr_bank(0x0000, bank_8k, ((regs >> 3) & 0x08) | (regs & 0x07));
if ( regs & 0x80 ) mirror_vert();
else mirror_horiz();
if (regs & 0x80)
mirror_vert();
else
mirror_horiz();
}
}

View File

@ -2,9 +2,9 @@
// Nes_Emu 0.5.4. http://www.slack.net/~ant/
#include <cstring>
#include "mappers/mapper.hpp"
#include "apu/vrc7/apu.hpp"
#include "mappers/mapper.hpp"
#include <cstring>
/* Copyright (C) 2004-2005 Shay Green. This module is free software; you
can redistribute it and/or modify it under the terms of the GNU Lesser
@ -37,7 +37,8 @@ static_assert( sizeof (vrc7_state_t) == 20 + sizeof (vrc7_snapshot_t) );
// Vrc7
class Mapper085 : public Nes_Mapper, vrc7_state_t {
class Mapper085 : public Nes_Mapper, vrc7_state_t
{
public:
Mapper085()
{
@ -194,7 +195,8 @@ public:
{
write_chr_bank(((addr >> 4) & 1) | (((addr - 0xa000) >> 11) & ~1), data);
}
else switch ( addr & 0xf010 )
else
switch (addr & 0xf010)
{
case 0x8000: write_prg_bank(0, data); break;
case 0x8010: write_prg_bank(1, data); break;
@ -205,13 +207,17 @@ public:
break;
case 0x9010:
if ( addr & 0x20 ) sound.write_data( time, data );
else sound.write_reg( data );
if (addr & 0x20)
sound.write_data(time, data);
else
sound.write_reg(data);
break;
}
}
Nes_Vrc7 sound;
enum { timer_period = 113 * 4 + 3 };
enum
{
timer_period = 113 * 4 + 3
};
};

View File

@ -18,8 +18,10 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
// Jaleco/Konami/Taito
class Mapper087 : public Nes_Mapper {
class Mapper087 : public Nes_Mapper
{
uint8_t bank;
public:
Mapper087()
{
@ -44,4 +46,3 @@ public:
void write(nes_time_t, nes_addr_t, int) {}
};

View File

@ -36,7 +36,8 @@ struct namco_34x3_state_t
static_assert(sizeof(namco_34x3_state_t) == 10);
template <bool _is154>
class Mapper_Namco_34x3 : public Nes_Mapper, namco_34x3_state_t {
class Mapper_Namco_34x3 : public Nes_Mapper, namco_34x3_state_t
{
public:
Mapper_Namco_34x3()
{
@ -45,7 +46,8 @@ public:
}
virtual void reset_state()
{ }
{
}
virtual void apply_mapping()
{
@ -77,15 +79,20 @@ public:
mode &= 0x07;
switch (mode)
{
case 0: case 1:
case 0:
case 1:
bank[mode] = data >> 1;
set_chr_bank(0x0000 + (mode << 11), bank_2k, bank[mode]);
break;
case 2: case 3: case 4: case 5:
case 2:
case 3:
case 4:
case 5:
bank[mode] = data | 0x40;
set_chr_bank(0x1000 + ((mode - 2) << 10), bank_1k, bank[mode]);
break;
case 6: case 7:
case 6:
case 7:
bank[mode] = data;
set_prg_bank(0x8000 + ((mode - 6) << 13), bank_8k, bank[mode]);
break;
@ -101,7 +108,6 @@ public:
typedef Mapper_Namco_34x3<false> Mapper088;
// void register_mapper_namco_34xx();
// void register_mapper_namco_34xx()
// {

View File

@ -26,7 +26,8 @@
// Sunsoft2b
class Mapper089 : public Nes_Mapper {
class Mapper089 : public Nes_Mapper
{
public:
Mapper089()
{
@ -34,7 +35,8 @@ public:
}
virtual void reset_state()
{}
{
}
virtual void apply_mapping()
{

View File

@ -26,7 +26,8 @@
// Sunsoft2a
class Mapper093 : public Nes_Mapper {
class Mapper093 : public Nes_Mapper
{
public:
Mapper093()
{
@ -34,7 +35,8 @@ public:
}
virtual void reset_state()
{}
{
}
virtual void apply_mapping()
{

View File

@ -28,7 +28,8 @@
// Un1rom
class Mapper094 : public Nes_Mapper {
class Mapper094 : public Nes_Mapper
{
public:
Mapper094()
{
@ -36,7 +37,8 @@ public:
}
virtual void reset_state()
{ }
{
}
virtual void apply_mapping()
{

View File

@ -27,7 +27,8 @@
// Irem_Tam_S1
class Mapper097 : public Nes_Mapper {
class Mapper097 : public Nes_Mapper
{
public:
Mapper097()
{

View File

@ -28,7 +28,8 @@
// Jaleco_JF11
class Mapper140 : public Nes_Mapper {
class Mapper140 : public Nes_Mapper
{
public:
Mapper140()
{

View File

@ -11,7 +11,8 @@ struct m156_state_t
};
static_assert(sizeof(m156_state_t) == 9);
class Mapper156 : public Nes_Mapper, m156_state_t {
class Mapper156 : public Nes_Mapper, m156_state_t
{
public:
Mapper156()
{

View File

@ -27,7 +27,8 @@
// UxROM (inverted)
class Mapper180 : public Nes_Mapper {
class Mapper180 : public Nes_Mapper
{
public:
Mapper180()
{
@ -35,7 +36,8 @@ public:
}
virtual void reset_state()
{ }
{
}
virtual void apply_mapping()
{

View File

@ -26,7 +26,8 @@
// Sunsoft1
class Mapper184 : public Nes_Mapper {
class Mapper184 : public Nes_Mapper
{
public:
Mapper184()
{
@ -34,7 +35,8 @@ public:
}
virtual void reset_state()
{}
{
}
virtual void apply_mapping()
{
@ -56,8 +58,8 @@ public:
}
virtual void write(nes_time_t, nes_addr_t addr, int data)
{}
{
}
uint8_t regs;
};

View File

@ -4,7 +4,8 @@
// Magic Kid Googoo
class Mapper190: public Nes_Mapper {
class Mapper190 : public Nes_Mapper
{
public:
Mapper190()
{
@ -52,4 +53,3 @@ public:
}
}
};

View File

@ -29,7 +29,8 @@
// NTDEC's TC-112 mapper IC.
class Mapper193 : public Nes_Mapper {
class Mapper193 : public Nes_Mapper
{
public:
Mapper193()
{
@ -37,7 +38,8 @@ public:
}
virtual void reset_state()
{ }
{
}
virtual void apply_mapping()
{
@ -50,7 +52,8 @@ public:
}
virtual void write(nes_time_t, nes_addr_t addr, int data)
{ }
{
}
virtual bool write_intercepted(nes_time_t, nes_addr_t addr, int data)
{
@ -71,4 +74,3 @@ public:
uint8_t regs[4];
};

View File

@ -37,7 +37,8 @@ static_assert( sizeof (namco_34xx_state_t) == 10 );
// Namco_34xx
class Mapper206 : public Nes_Mapper, namco_34xx_state_t {
class Mapper206 : public Nes_Mapper, namco_34xx_state_t
{
public:
Mapper206()
{
@ -46,7 +47,8 @@ public:
}
virtual void reset_state()
{ }
{
}
virtual void apply_mapping()
{
@ -72,15 +74,20 @@ public:
mode &= 0x07;
switch (mode)
{
case 0: case 1:
case 0:
case 1:
bank[mode] = data >> 1;
set_chr_bank(0x0000 + (mode << 11), bank_2k, bank[mode]);
break;
case 2: case 3: case 4: case 5:
case 2:
case 3:
case 4:
case 5:
bank[mode] = data;
set_chr_bank(0x1000 + ((mode - 2) << 10), bank_1k, bank[mode]);
break;
case 6: case 7:
case 6:
case 7:
bank[mode] = data;
set_prg_bank(0x8000 + ((mode - 6) << 13), bank_8k, bank[mode]);
break;
@ -89,4 +96,3 @@ public:
}
}
};

View File

@ -35,7 +35,8 @@ static_assert( sizeof (taito_x1005_state_t) == 11 );
// TaitoX1005
class Mapper207 : public Nes_Mapper, taito_x1005_state_t {
class Mapper207 : public Nes_Mapper, taito_x1005_state_t
{
public:
Mapper207()
{
@ -44,7 +45,8 @@ public:
}
virtual void reset_state()
{ }
{
}
virtual void apply_mapping()
{
@ -87,4 +89,3 @@ public:
virtual void write(nes_time_t, nes_addr_t addr, int data) {}
};

View File

@ -20,8 +20,10 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
// Quattro
class Mapper232 : public Nes_Mapper {
class Mapper232 : public Nes_Mapper
{
uint8_t regs[2];
public:
Mapper232()
{
@ -50,4 +52,3 @@ public:
Mapper232::apply_mapping();
}
};

View File

@ -25,7 +25,8 @@
// https://www.nesdev.org/wiki/INES_Mapper240
class Mapper240 : public Nes_Mapper {
class Mapper240 : public Nes_Mapper
{
public:
Mapper240()
{
@ -44,7 +45,8 @@ public:
}
virtual void write(nes_time_t, nes_addr_t, int data)
{ }
{
}
virtual bool write_intercepted(nes_time_t, nes_addr_t addr, int data)
{

View File

@ -25,7 +25,8 @@
// https://www.nesdev.org/wiki/INES_Mapper241
class Mapper241 : public Nes_Mapper {
class Mapper241 : public Nes_Mapper
{
public:
Mapper241()
{
@ -33,7 +34,8 @@ public:
}
virtual void reset_state()
{ }
{
}
virtual void apply_mapping()
{

View File

@ -34,7 +34,8 @@ struct mapper244_state_t
};
static_assert(sizeof(mapper244_state_t) == 2);
class Mapper244 : public Nes_Mapper, mapper244_state_t {
class Mapper244 : public Nes_Mapper, mapper244_state_t
{
public:
Mapper244()
{
@ -43,7 +44,8 @@ public:
}
virtual void reset_state()
{ }
{
}
virtual void apply_mapping()
{

View File

@ -27,7 +27,8 @@
// https://www.nesdev.org/wiki/INES_Mapper246
class Mapper246 : public Nes_Mapper {
class Mapper246 : public Nes_Mapper
{
public:
Mapper246()
{
@ -48,7 +49,8 @@ public:
}
virtual void write(nes_time_t, nes_addr_t addr, int data)
{ }
{
}
virtual bool write_intercepted(nes_time_t, nes_addr_t addr, int data)
{
@ -71,4 +73,3 @@ public:
uint8_t regs[8];
};

View File

@ -3,9 +3,9 @@
// Nes_Emu 0.7.0. http://www.slack.net/~ant/
#include <cstring>
#include "Nes_Ppu.hpp"
#include "Nes_Core.hpp"
#include <cstring>
/* Copyright (C) 2004-2006 Shay Green. This module is free software; you
can redistribute it and/or modify it under the terms of the GNU Lesser
@ -234,8 +234,7 @@ inline int Nes_Ppu_Impl::first_opaque_sprite_line()
}
p += 8;
}
while ( !--twice );
} while (!--twice);
return line;
}
@ -323,8 +322,7 @@ int Nes_Ppu::read_2002( nes_time_t time )
query_until(time);
next_status_event = next_sprite_hit_check;
nes_time_t const next_max = fixed_sprite_max_time ?
fixed_sprite_max_time : next_sprite_max_run;
nes_time_t const next_max = fixed_sprite_max_time ? fixed_sprite_max_time : next_sprite_max_run;
if (next_status_event > next_max)
next_status_event = next_max;
@ -408,7 +406,8 @@ int Nes_Ppu::read( unsigned addr, nes_time_t time )
return read_2002(time);
// sprite ram
case 4: {
case 4:
{
int result = spr_ram[w2003];
if ((w2003 & 3) == 2)
result &= 0xe3;
@ -417,7 +416,8 @@ int Nes_Ppu::read( unsigned addr, nes_time_t time )
}
// video ram
case 7: {
case 7:
{
render_bg_until(time);
int addr = vram_addr;
int new_addr = addr + addr_inc;
@ -448,7 +448,8 @@ void Nes_Ppu::write( nes_time_t time, unsigned addr, int data )
{
switch (addr & 7)
{
case 0:{// control
case 0:
{ // control
int changed = w2000 ^ data;
if (changed & 0x28)
@ -483,7 +484,8 @@ void Nes_Ppu::write( nes_time_t time, unsigned addr, int data )
break;
}
case 1:{// sprites, bg enable
case 1:
{ // sprites, bg enable
int changed = w2001 ^ data;
if (changed & 0xE1)

View File

@ -14,8 +14,10 @@ typedef long ppu_time_t; // ppu_time_t = nes_time_t * ppu_overclock
ppu_time_t const ppu_overclock = 3; // PPU clocks for each CPU clock
class Nes_Ppu : public Nes_Ppu_Rendering {
class Nes_Ppu : public Nes_Ppu_Rendering
{
typedef Nes_Ppu_Rendering base;
public:
Nes_Ppu(Nes_Core *);
@ -44,10 +46,12 @@ public:
int burst_phase;
private:
Nes_Core &emu;
enum { indefinite_time = LONG_MAX / 2 + 1 };
enum
{
indefinite_time = LONG_MAX / 2 + 1
};
void suspend_rendering();
int read_(unsigned addr, nes_time_t); // note swapped arguments!

View File

@ -1,9 +1,9 @@
// Nes_Emu 0.7.0. http://www.slack.net/~ant/
#include <cstring>
#include "Nes_Ppu_Impl.hpp"
#include <cstdint>
#include <cstdio>
#include "Nes_Ppu_Impl.hpp"
#include <cstring>
/* Copyright (C) 2004-2006 Shay Green. This module is free software; you
can redistribute it and/or modify it under the terms of the GNU Lesser
@ -18,7 +18,8 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
int const cache_line_size = 128; // tile cache is kept aligned to this boundary
inline void set_be32( void* p, unsigned long n ) {
inline void set_be32(void *p, unsigned long n)
{
((unsigned char *)p)[0] = (unsigned char)(n >> 24);
((unsigned char *)p)[1] = (unsigned char)(n >> 16);
((unsigned char *)p)[2] = (unsigned char)(n >> 8);
@ -41,7 +42,6 @@ Nes_Ppu_Impl::Nes_Ppu_Impl()
mmc24_enabled = false;
mmc24_latched[0] = 0;
mmc24_latched[1] = 0;
}
Nes_Ppu_Impl::~Nes_Ppu_Impl()
@ -143,9 +143,7 @@ void Nes_Ppu_Impl::set_chr_bank_ex( int addr, int size, long data )
static uint8_t const initial_palette[0x20] =
{
0x0f,0x01,0x00,0x01,0x00,0x02,0x02,0x0D,0x08,0x10,0x08,0x24,0x00,0x00,0x04,0x2C,
0x00,0x01,0x34,0x03,0x00,0x04,0x00,0x14,0x00,0x3A,0x00,0x02,0x00,0x20,0x2C,0x08
};
0x0f, 0x01, 0x00, 0x01, 0x00, 0x02, 0x02, 0x0D, 0x08, 0x10, 0x08, 0x24, 0x00, 0x00, 0x04, 0x2C, 0x00, 0x01, 0x34, 0x03, 0x00, 0x04, 0x00, 0x14, 0x00, 0x3A, 0x00, 0x02, 0x00, 0x20, 0x2C, 0x08};
void Nes_Ppu_Impl::reset(bool full_reset)
{
@ -304,14 +302,11 @@ void Nes_Ppu_Impl::update_tiles( int first_tile )
if (modified & 1)
update_tile(index);
index++;
} while ((modified >>= 1) != 0);
}
while ( (modified >>= 1) != 0 );
} while (++chunk & 3);
}
}
while ( ++chunk & 3 );
}
}
while ( chunk < chr_tile_count / 8 );
} while (chunk < chr_tile_count / 8);
}
// Sprite max
@ -428,8 +423,7 @@ long Nes_Ppu_Impl::recalc_sprite_max( int scanline )
}
break;
}
}
while ( i < 0x100 );
} while (i < 0x100);
scanline++;
}

View File

@ -5,7 +5,6 @@
#include <cstdint>
struct ppu_state_t
{
uint8_t w2000; // control
@ -26,7 +25,8 @@ struct ppu_state_t
};
static_assert(sizeof(ppu_state_t) == 20 + 0x20);
class Nes_Ppu_Impl : public ppu_state_t {
class Nes_Ppu_Impl : public ppu_state_t
{
public:
Nes_Ppu_Impl();
~Nes_Ppu_Impl();
@ -43,7 +43,10 @@ public:
static const uint16_t image_left = 8;
static const uint16_t buffer_width = image_width + 16;
static const uint16_t buffer_height = image_height;
enum { spr_ram_size = 0x100 };
enum
{
spr_ram_size = 0x100
};
uint8_t *nt_banks[4];
bool chr_is_writable;
@ -75,7 +78,8 @@ public:
{
uint8_t nt_ram[nt_ram_size];
uint8_t chr_ram[chr_addr_size];
union {
union
{
uint32_t clip_buf[256 * 2];
uint8_t mini_offscreen[buffer_width * mini_offscreen_height];
};
@ -88,14 +92,13 @@ public:
uint16_t getSpriteRAMSize() { return spr_ram_size; }
uint8_t spr_ram[spr_ram_size];
void all_tiles_modified();
protected:
protected:
void begin_frame();
void run_hblank(int);
int sprite_height() const { return (w2000 >> 2 & 8) + 8; }
protected: // friend class Nes_Ppu; private:
int addr_inc; // pre-calculated $2007 increment (based on w2001 & 0x04)
int read_2007(int addr);
@ -104,7 +107,6 @@ protected: //friend class Nes_Ppu; private:
int first_opaque_sprite_line();
protected: // friend class Nes_Ppu_Rendering; private:
unsigned long palette_offset;
int palette_changed;
void capture_palette();
@ -119,7 +121,6 @@ protected: //friend class Nes_Ppu_Rendering; private:
uint8_t *get_nametable(int addr) { return nt_banks[addr >> 10 & 3]; };
private:
static int map_palette(int addr);
int sprite_tile_index(uint8_t const *sprite) const;
@ -148,7 +149,6 @@ private:
return ret;
}
bool mmc24_enabled;
uint8_t mmc24_latched[2];
@ -161,7 +161,8 @@ private:
cached_tile_t *tile_cache;
cached_tile_t *flipped_tiles;
uint8_t *tile_cache_mem;
union {
union
{
uint8_t modified_tiles[chr_tile_count / 8];
uint32_t align_;
};

View File

@ -1,9 +1,9 @@
// Nes_Emu 0.7.0. http://www.slack.net/~ant/
#include <algorithm>
#include <cstring>
#include <cstddef>
#include "Nes_Ppu_Rendering.hpp"
#include <algorithm>
#include <cstddef>
#include <cstring>
/* Copyright (C) 2004-2006 Shay Green. This module is free software; you
can redistribute it and/or modify it under the terms of the GNU Lesser
@ -30,16 +30,14 @@ inline Nes_Ppu_Impl::cached_tile_t const&
// use index directly, since cached tile is same size as native tile
static_assert(sizeof(cached_tile_t) == bytes_per_tile);
return *(Nes_Ppu_Impl::cached_tile_t*)
((uint8_t*) tiles + map_chr_addr( index * bytes_per_tile ));
return *(Nes_Ppu_Impl::cached_tile_t *)((uint8_t *)tiles + map_chr_addr(index * bytes_per_tile));
}
inline Nes_Ppu_Impl::cached_tile_t const &Nes_Ppu_Impl::get_bg_tile(int index)
{
// use index directly, since cached tile is same size as native tile
static_assert(sizeof(cached_tile_t) == bytes_per_tile);
return *(Nes_Ppu_Impl::cached_tile_t*)
((uint8_t*) tile_cache + map_chr_addr( index * bytes_per_tile ));
return *(Nes_Ppu_Impl::cached_tile_t *)((uint8_t *)tile_cache + map_chr_addr(index * bytes_per_tile));
}
// Fill
@ -253,8 +251,7 @@ void Nes_Ppu_Rendering::draw_background_( int remain )
break;
}
}
while ( remain );
} while (remain);
}
// Sprites
@ -310,8 +307,7 @@ void Nes_Ppu_Rendering::draw_sprites_( int begin, int end )
#define CLIPPED 1
#include "Nes_Ppu_Sprites.hpp"
}
}
while ( index < 0x100 );
} while (index < 0x100);
}
void Nes_Ppu_Rendering::check_sprite_hit(int begin, int end)
@ -399,14 +395,12 @@ void Nes_Ppu_Rendering::check_sprite_hit( int begin, int end )
return;
}
}
while ( x++ < 7 );
} while (x++ < 7);
}
if (skip > final)
skip -= 2;
skip++;
}
while ( skip != final );
} while (skip != final);
}
// Draw scanlines
@ -416,8 +410,7 @@ inline bool Nes_Ppu_Rendering::sprite_hit_possible( int scanline ) const
return !sprite_hit_found && spr_ram[0] <= scanline && (w2001 & 0x18) == 0x18;
}
void Nes_Ppu_Rendering::draw_scanlines( int start, int count,
uint8_t* pixels, long pitch, int mode )
void Nes_Ppu_Rendering::draw_scanlines(int start, int count, uint8_t *pixels, long pitch, int mode)
{
scanline_pixels = pixels + image_left;
scanline_row_bytes = pitch;

View File

@ -5,8 +5,10 @@
#include "Nes_Ppu_Impl.hpp"
class Nes_Ppu_Rendering : public Nes_Ppu_Impl {
class Nes_Ppu_Rendering : public Nes_Ppu_Impl
{
typedef Nes_Ppu_Impl base;
public:
Nes_Ppu_Rendering();
@ -16,13 +18,11 @@ public:
long host_row_bytes;
protected:
long sprite_hit_found; // -1: sprite 0 didn't hit, 0: no hit so far, > 0: y * 341 + x
void draw_background(int start, int count);
void draw_sprites(int start, int count);
private:
void draw_scanlines(int start, int count, uint8_t *pixels, long pitch, int mode);
void draw_background_(int count);
@ -37,7 +37,10 @@ private:
void restore_left(int count);
// sprites
enum { max_sprites = 64 };
enum
{
max_sprites = 64
};
uint8_t sprite_scanlines[image_height]; // number of sprites on each scanline
void draw_sprites_(int start, int count);
bool sprite_hit_possible(int scanline) const;
@ -54,4 +57,3 @@ inline void Nes_Ppu_Rendering::draw_sprites( int start, int count )
{
draw_scanlines(start, count, host_pixels + host_row_bytes * start, host_row_bytes, 2);
}

View File

@ -29,11 +29,13 @@ unsigned long offset = (sprite_2 & 3) * 0x04040404 + (this->palette_offset + 0x1
unsigned long const mask = 0x03030303 + zero;
unsigned long const maskgen = 0x80808080 + zero;
#define DRAW_PAIR( shift ) { \
#define DRAW_PAIR(shift) \
{ \
int sprite_count = *scanlines; \
CALC_FOUR(((uint32_t *)out)[0], (line >> (shift + 4)), out0) \
CALC_FOUR(((uint32_t *)out)[1], (line >> shift), out1) \
if ( sprite_count < this->max_sprites ) { \
if (sprite_count < this->max_sprites) \
{ \
((uint32_t *)out)[0] = out0; \
((uint32_t *)out)[1] = out1; \
} \

View File

@ -6,7 +6,6 @@
class QuickerNESInstance : public EmuInstance
{
public:
QuickerNESInstance() : EmuInstance()
{
// Creating new emulator
@ -57,7 +56,6 @@ class QuickerNESInstance : public EmuInstance
void *getInternalEmulatorPointer() const override { return _nes; }
private:
inline size_t getStateSizeImpl() const override
{
return _nes->getStateSize();

View File

@ -1,9 +1,9 @@
#include <sstream>
#include <chrono>
#include "argparse/argparse.hpp"
#include "nlohmann/json.hpp"
#include "sha1/sha1.hpp"
#include "utils.hpp"
#include "nlohmann/json.hpp"
#include <chrono>
#include <sstream>
#ifdef _USE_QUICKNES
#include "quickNESInstance.hpp"
@ -31,8 +31,14 @@ int main(int argc, char *argv[])
.default_value(std::string(""));
// Try to parse arguments
try { program.parse_args(argc, argv); }
catch (const std::runtime_error &err) { EXIT_WITH_ERROR("%s\n%s", err.what(), program.help().str().c_str()); }
try
{
program.parse_args(argc, argv);
}
catch (const std::runtime_error &err)
{
EXIT_WITH_ERROR("%s\n%s", err.what(), program.help().str().c_str());
}
// Getting test script file path
std::string scriptFilePath = program.get<std::string>("scriptFile");
@ -174,4 +180,3 @@ int main(int argc, char *argv[])
// If reached this point, everything ran ok
return 0;
}

View File

@ -1,14 +1,14 @@
#pragma once
#include <algorithm>
#include <fstream>
#include <metrohash128/metrohash128.h>
#include <sstream>
#include <vector>
#include <stdarg.h>
#include <stdexcept>
#include <stdio.h>
#include <unistd.h>
#include <algorithm>
#include <metrohash128/metrohash128.h>
#include <vector>
// If we use NCurses, we need to use the appropriate printing function
#ifdef NCURSES
@ -82,10 +82,8 @@ void refreshTerminal()
refresh();
}
#endif // NCURSES
typedef _uint128_t hash_t;
inline hash_t calculateMetroHash(uint8_t *data, size_t size)
{
@ -100,7 +98,8 @@ inline hash_t calculateMetroHash(uint8_t* data, size_t size)
// Taken from stack overflow answer to https://stackoverflow.com/questions/236129/how-do-i-iterate-over-the-words-of-a-string
// By Evan Teran
template <typename Out> inline void split(const std::string &s, char delim, Out result)
template <typename Out>
inline void split(const std::string &s, char delim, Out result)
{
std::istringstream iss(s);
std::string item;
@ -178,7 +177,8 @@ inline bool saveStringToFile(const std::string &src, const char *fileName)
}
// Function to split a vector into n mostly fair chunks
template <typename T> inline std::vector<T> splitVector(const T size, const T n)
template <typename T>
inline std::vector<T> splitVector(const T size, const T n)
{
std::vector<T> subSizes(n);
@ -196,7 +196,12 @@ inline std::string simplifyMove(const std::string& move)
std::string simpleMove;
bool isEmptyMove = true;
for (size_t i = 0; i < move.size(); i++) if (move[i] != '.' && move[i] != '|') { simpleMove += move[i]; isEmptyMove = false; }
for (size_t i = 0; i < move.size(); i++)
if (move[i] != '.' && move[i] != '|')
{
simpleMove += move[i];
isEmptyMove = false;
}
if (isEmptyMove) return ".";
return simpleMove;
}
@ -214,10 +219,17 @@ inline bool getBitFlag(const uint8_t value, const uint8_t idx)
return false;
}
inline size_t countButtonsPressedString(const std::string &input)
{
size_t count = 0;
for (size_t i = 0; i < input.size(); i++)
if (input[i] != '.') count++;
return count;
};
inline size_t countButtonsPressedString(const std::string& input) { size_t count = 0; for (size_t i = 0; i < input.size(); i++) if (input[i] != '.') count++; return count; };
template<typename T> inline uint16_t countButtonsPressedNumber(const T& input) {
template <typename T>
inline uint16_t countButtonsPressedNumber(const T &input)
{
uint16_t count = 0;
if (input & 0b0000000000000001) count++;
if (input & 0b0000000000000010) count++;
@ -238,5 +250,11 @@ template<typename T> inline uint16_t countButtonsPressedNumber(const T& input) {
return count;
};
static auto moveCountComparerString = [](const std::string& a, const std::string& b) { return countButtonsPressedString(a) < countButtonsPressedString(b); };
static auto moveCountComparerNumber = [](const uint8_t a, const uint8_t b) { return countButtonsPressedNumber(a) < countButtonsPressedNumber(b); };
static auto moveCountComparerString = [](const std::string &a, const std::string &b)
{
return countButtonsPressedString(a) < countButtonsPressedString(b);
};
static auto moveCountComparerNumber = [](const uint8_t a, const uint8_t b)
{
return countButtonsPressedNumber(a) < countButtonsPressedNumber(b);
};