This commit is contained in:
Sergio Martin 2024-01-20 13:02:14 +01:00
parent d1993751f6
commit b7788f946b
85 changed files with 592 additions and 594 deletions

7
extern/hqn/hqn.h vendored
View File

@ -1,7 +1,6 @@
#ifndef __HQN_H__ #ifndef __HQN_H__
#define __HQN_H__ #define __HQN_H__
#include <Nes_Emu.hpp>
#include <cstdint> #include <cstdint>
#include <stdio.h> #include <stdio.h>
@ -9,15 +8,15 @@
// Creating emulator instance // Creating emulator instance
#ifdef _USE_QUICKNES #ifdef _USE_QUICKNES
#include <Nes_Emu.hpp>
typedef Nes_Emu emulator_t; typedef Nes_Emu emulator_t;
#endif #endif
#ifdef _USE_QUICKERNES #ifdef _USE_QUICKERNES
typedef quickerNES::Nes_Emu emulator_t; #include <emu.hpp>
typedef quickerNES::Emu emulator_t;
#endif #endif
namespace hqn namespace hqn
{ {

View File

@ -17,7 +17,7 @@
#endif #endif
#ifdef _USE_QUICKERNES #ifdef _USE_QUICKERNES
typedef quickerNES::Nes_Emu emulator_t; typedef quickerNES::Emu emulator_t;
#endif #endif
struct stepData_t struct stepData_t

View File

@ -1,7 +1,7 @@
// Nes_Emu 0.7.0. http://www.slack.net/~ant/libs/ // Nes_Emu 0.7.0. http://www.slack.net/~ant/libs/
#include "apu/Nes_Effects_Buffer.hpp" #include "apu/NESEffectsBuffer.hpp"
#include "apu/apu.hpp" #include "apu/apu.hpp"
/* Copyright (C) 2004-2006 Shay Green. This module is free software; you /* Copyright (C) 2004-2006 Shay Green. This module is free software; you
@ -27,7 +27,7 @@ Nes_Effects_Buffer::Nes_Effects_Buffer() : Effects_Buffer(true) // nes never use
Nes_Effects_Buffer::~Nes_Effects_Buffer() {} Nes_Effects_Buffer::~Nes_Effects_Buffer() {}
Multi_Buffer *set_apu(Nes_Effects_Buffer *buf, Nes_Apu *apu) Multi_Buffer *set_apu(Nes_Effects_Buffer *buf, Apu *apu)
{ {
buf->set_apu(apu); buf->set_apu(apu);
return buf; return buf;
@ -35,9 +35,8 @@ Multi_Buffer *set_apu(Nes_Effects_Buffer *buf, Nes_Apu *apu)
void Nes_Effects_Buffer::enable_nonlinearity(bool b) void Nes_Effects_Buffer::enable_nonlinearity(bool b)
{ {
if (b) if (b) clear();
clear(); Apu *apu = nonlin.enable(b, channel(2).center);
Nes_Apu *apu = nonlin.enable(b, channel(2).center);
apu->osc_output(0, channel(0).center); apu->osc_output(0, channel(0).center);
apu->osc_output(1, channel(1).center); apu->osc_output(1, channel(1).center);
} }

View File

@ -3,8 +3,8 @@
// Effects_Buffer with non-linear sound // Effects_Buffer with non-linear sound
// Nes_Emu 0.7.0 // Nes_Emu 0.7.0
#include "Effects_Buffer.hpp" #include "effectsBuffer.hpp"
#include "Nes_Buffer.hpp" #include "buffer.hpp"
namespace quickerNES namespace quickerNES
{ {
@ -18,7 +18,7 @@ class Nes_Effects_Buffer : public Effects_Buffer
// Setup APU for use with buffer, including setting its output to this buffer. // Setup APU for use with buffer, including setting its output to this buffer.
// If you're using Nes_Emu, this is automatically called for you. // If you're using Nes_Emu, this is automatically called for you.
void set_apu(Nes_Apu *apu) { nonlin.set_apu(apu); } void set_apu(Apu *apu) { nonlin.set_apu(apu); }
// Enable/disable non-linear output // Enable/disable non-linear output
void enable_nonlinearity(bool = true); void enable_nonlinearity(bool = true);
@ -34,8 +34,8 @@ class Nes_Effects_Buffer : public Effects_Buffer
void RestoreAudioBufferState(); void RestoreAudioBufferState();
private: private:
Nes_Nonlinearizer nonlin; Nonlinearizer nonlin;
friend Multi_Buffer *set_apu(Nes_Effects_Buffer *, Nes_Apu *); friend Multi_Buffer *set_apu(Nes_Effects_Buffer *, Apu *);
}; };
} // namespace quickNES } // namespace quickNES

View File

@ -1,4 +1,4 @@
// Nes_Snd_Emu 0.1.7. http://www.slack.net/~ant/ // Snd_Emu 0.1.7. http://www.slack.net/~ant/
#include "apu.hpp" #include "apu.hpp"
@ -18,7 +18,7 @@ namespace quickerNES
int const amp_range = 15; int const amp_range = 15;
Nes_Apu::Nes_Apu() : square1(&square_synth), Apu::Apu() : square1(&square_synth),
square2(&square_synth) square2(&square_synth)
{ {
dmc.apu = this; dmc.apu = this;
@ -36,11 +36,11 @@ Nes_Apu::Nes_Apu() : square1(&square_synth),
reset(false); reset(false);
} }
Nes_Apu::~Nes_Apu() Apu::~Apu()
{ {
} }
void Nes_Apu::treble_eq(const blip_eq_t &eq) void Apu::treble_eq(const blip_eq_t &eq)
{ {
square_synth.treble_eq(eq); square_synth.treble_eq(eq);
triangle.synth.treble_eq(eq); triangle.synth.treble_eq(eq);
@ -48,7 +48,7 @@ void Nes_Apu::treble_eq(const blip_eq_t &eq)
dmc.synth.treble_eq(eq); dmc.synth.treble_eq(eq);
} }
void Nes_Apu::enable_nonlinear(double v) void Apu::enable_nonlinear(double v)
{ {
dmc.nonlinear = true; dmc.nonlinear = true;
square_synth.volume(1.3 * 0.25751258 / 0.742467605 * 0.25 / amp_range * v); square_synth.volume(1.3 * 0.25751258 / 0.742467605 * 0.25 / amp_range * v);
@ -65,7 +65,7 @@ void Nes_Apu::enable_nonlinear(double v)
dmc.last_amp = 0; dmc.last_amp = 0;
} }
void Nes_Apu::volume(double v) void Apu::volume(double v)
{ {
dmc.nonlinear = false; dmc.nonlinear = false;
square_synth.volume(0.1128 / amp_range * v); square_synth.volume(0.1128 / amp_range * v);
@ -74,13 +74,13 @@ void Nes_Apu::volume(double v)
dmc.synth.volume(0.42545 / 127 * v); dmc.synth.volume(0.42545 / 127 * v);
} }
void Nes_Apu::output(Blip_Buffer *buffer) void Apu::output(Blip_Buffer *buffer)
{ {
for (int i = 0; i < osc_count; i++) for (int i = 0; i < osc_count; i++)
osc_output(i, buffer); osc_output(i, buffer);
} }
void Nes_Apu::reset(bool pal_mode, int initial_dmc_dac) void Apu::reset(bool pal_mode, int initial_dmc_dac)
{ {
// to do: time pal frame periods exactly // to do: time pal frame periods exactly
frame_period = pal_mode ? 8314 : 7458; frame_period = pal_mode ? 8314 : 7458;
@ -111,7 +111,7 @@ void Nes_Apu::reset(bool pal_mode, int initial_dmc_dac)
// dmc.last_amp = initial_dmc_dac; // prevent output transition // dmc.last_amp = initial_dmc_dac; // prevent output transition
} }
void Nes_Apu::irq_changed() void Apu::irq_changed()
{ {
nes_time_t new_irq = dmc.next_irq; nes_time_t new_irq = dmc.next_irq;
if (dmc.irq_flag | irq_flag) if (dmc.irq_flag | irq_flag)
@ -133,7 +133,7 @@ void Nes_Apu::irq_changed()
// frames // frames
void Nes_Apu::run_until(nes_time_t end_time) void Apu::run_until(nes_time_t end_time)
{ {
if (end_time > next_dmc_read_time()) if (end_time > next_dmc_read_time())
{ {
@ -143,7 +143,7 @@ void Nes_Apu::run_until(nes_time_t end_time)
} }
} }
void Nes_Apu::run_until_(nes_time_t end_time) void Apu::run_until_(nes_time_t end_time)
{ {
if (end_time == last_time) if (end_time == last_time)
return; return;
@ -227,7 +227,7 @@ inline void zero_apu_osc(T *osc, nes_time_t time)
osc->synth.offset(time, -last_amp, output); osc->synth.offset(time, -last_amp, output);
} }
void Nes_Apu::end_frame(nes_time_t end_time) void Apu::end_frame(nes_time_t end_time)
{ {
if (end_time > last_time) if (end_time > last_time)
run_until_(end_time); run_until_(end_time);
@ -266,7 +266,7 @@ void Nes_Apu::end_frame(nes_time_t end_time)
static const unsigned char length_table[0x20] = { 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) void Apu::write_register(nes_time_t time, nes_addr_t addr, int data)
{ {
// Ignore addresses outside range // Ignore addresses outside range
if (addr < start_addr || end_addr < addr) if (addr < start_addr || end_addr < addr)
@ -278,7 +278,7 @@ void Nes_Apu::write_register(nes_time_t time, nes_addr_t addr, int data)
{ {
// Write to channel // Write to channel
int osc_index = (addr - start_addr) >> 2; int osc_index = (addr - start_addr) >> 2;
Nes_Osc *osc = oscs[osc_index]; Osc *osc = oscs[osc_index];
int reg = addr & 3; int reg = addr & 3;
osc->regs[reg] = data; osc->regs[reg] = data;
@ -297,7 +297,7 @@ void Nes_Apu::write_register(nes_time_t time, nes_addr_t addr, int data)
// reset square phase // reset square phase
if (osc_index < 2) if (osc_index < 2)
((Nes_Square *)osc)->phase = Nes_Square::phase_range - 1; ((Square *)osc)->phase = Square::phase_range - 1;
} }
} }
else if (addr == 0x4015) else if (addr == 0x4015)
@ -351,7 +351,7 @@ void Nes_Apu::write_register(nes_time_t time, nes_addr_t addr, int data)
} }
} }
int Nes_Apu::read_status(nes_time_t time) int Apu::read_status(nes_time_t time)
{ {
run_until_(time - 1); run_until_(time - 1);

View File

@ -1,16 +1,16 @@
#pragma once #pragma once
// NES 2A03 APU sound chip emulator // NES 2A03 APU sound chip emulator
// Nes_Snd_Emu 0.1.7 // Snd_Emu 0.1.7
#include <climits> #include <climits>
#include <cstdint> #include <cstdint>
#include "Nes_Oscs.hpp" #include "oscs.hpp"
namespace quickerNES namespace quickerNES
{ {
class Nes_Apu class Apu
{ {
public: public:
typedef uint8_t env_t[3]; typedef uint8_t env_t[3];
@ -82,8 +82,8 @@ class Nes_Apu
}; };
static_assert(sizeof(apu_state_t) == 72); static_assert(sizeof(apu_state_t) == 72);
Nes_Apu(); Apu();
~Nes_Apu(); ~Apu();
// Set buffer to generate all sound into, or disable sound if NULL // Set buffer to generate all sound into, or disable sound if NULL
void output(Blip_Buffer *); void output(Blip_Buffer *);
@ -162,23 +162,23 @@ class Nes_Apu
// End of public interface. // End of public interface.
private: private:
friend class Nes_Nonlinearizer; friend class Nonlinearizer;
void enable_nonlinear(double volume); void enable_nonlinear(double volume);
static double nonlinear_tnd_gain() { return 0.75; } static double nonlinear_tnd_gain() { return 0.75; }
private: private:
friend struct Nes_Dmc; friend struct Dmc;
// noncopyable // noncopyable
Nes_Apu(const Nes_Apu &); Apu(const Apu &);
Nes_Apu &operator=(const Nes_Apu &); Apu &operator=(const Apu &);
Nes_Osc *oscs[osc_count]; Osc *oscs[osc_count];
Nes_Square square1; Square square1;
Nes_Square square2; Square square2;
Nes_Noise noise; Noise noise;
Nes_Triangle triangle; Triangle triangle;
Nes_Dmc dmc; Dmc dmc;
nes_time_t last_time; // has been run until this time in current frame nes_time_t last_time; // has been run until this time in current frame
nes_time_t last_dmc_time; nes_time_t last_dmc_time;
@ -192,66 +192,66 @@ class Nes_Apu
bool irq_flag; bool irq_flag;
void (*irq_notifier_)(void *user_data); void (*irq_notifier_)(void *user_data);
void *irq_data; void *irq_data;
Nes_Square::Synth square_synth; // shared by squares Square::Synth square_synth; // shared by squares
void irq_changed(); void irq_changed();
void state_restored(); void state_restored();
void run_until_(nes_time_t); void run_until_(nes_time_t);
// TODO: remove // TODO: remove
friend class Nes_Core; friend class Core;
}; };
inline void Nes_Apu::osc_output(int osc, Blip_Buffer *buf) inline void Apu::osc_output(int osc, Blip_Buffer *buf)
{ {
oscs[osc]->output = buf; oscs[osc]->output = buf;
} }
inline nes_time_t Nes_Apu::earliest_irq(nes_time_t) const inline nes_time_t Apu::earliest_irq(nes_time_t) const
{ {
return earliest_irq_; return earliest_irq_;
} }
inline void Nes_Apu::dmc_reader(int (*func)(void *, nes_addr_t), void *user_data) inline void Apu::dmc_reader(int (*func)(void *, nes_addr_t), void *user_data)
{ {
dmc.prg_reader_data = user_data; dmc.prg_reader_data = user_data;
dmc.prg_reader = func; dmc.prg_reader = func;
} }
inline void Nes_Apu::irq_notifier(void (*func)(void *user_data), void *user_data) inline void Apu::irq_notifier(void (*func)(void *user_data), void *user_data)
{ {
irq_notifier_ = func; irq_notifier_ = func;
irq_data = user_data; irq_data = user_data;
} }
inline int Nes_Apu::count_dmc_reads(nes_time_t time, nes_time_t *last_read) const inline int Apu::count_dmc_reads(nes_time_t time, nes_time_t *last_read) const
{ {
return dmc.count_reads(time, last_read); return dmc.count_reads(time, last_read);
} }
inline nes_time_t Nes_Dmc::next_read_time() const inline nes_time_t Dmc::next_read_time() const
{ {
if (length_counter == 0) if (length_counter == 0)
return Nes_Apu::no_irq; // not reading return Apu::no_irq; // not reading
return apu->last_dmc_time + delay + long(bits_remain - 1) * period; return apu->last_dmc_time + delay + long(bits_remain - 1) * period;
} }
inline nes_time_t Nes_Apu::next_dmc_read_time() const { return dmc.next_read_time(); } inline nes_time_t Apu::next_dmc_read_time() const { return dmc.next_read_time(); }
template <int mode> template <int mode>
struct apu_reflection struct apu_reflection
{ {
#define REFLECT(apu, state) (mode ? void(apu = state) : void(state = apu)) #define REFLECT(apu, state) (mode ? void(apu = state) : void(state = apu))
static void reflect_env(Nes_Apu::env_t *state, Nes_Envelope &osc) static void reflect_env(Apu::env_t *state, Envelope &osc)
{ {
REFLECT((*state)[0], osc.env_delay); REFLECT((*state)[0], osc.env_delay);
REFLECT((*state)[1], osc.envelope); REFLECT((*state)[1], osc.envelope);
REFLECT((*state)[2], osc.reg_written[3]); REFLECT((*state)[2], osc.reg_written[3]);
} }
static void reflect_square(Nes_Apu::square_t &state, Nes_Square &osc) static void reflect_square(Apu::square_t &state, Square &osc)
{ {
reflect_env(&state.env, osc); reflect_env(&state.env, osc);
REFLECT(state.delay, osc.delay); REFLECT(state.delay, osc.delay);
@ -261,7 +261,7 @@ struct apu_reflection
REFLECT(state.swp_reset, osc.reg_written[1]); REFLECT(state.swp_reset, osc.reg_written[1]);
} }
static void reflect_triangle(Nes_Apu::triangle_t &state, Nes_Triangle &osc) static void reflect_triangle(Apu::triangle_t &state, Triangle &osc)
{ {
REFLECT(state.delay, osc.delay); REFLECT(state.delay, osc.delay);
REFLECT(state.length_counter, osc.length_counter); REFLECT(state.length_counter, osc.length_counter);
@ -270,7 +270,7 @@ struct apu_reflection
REFLECT(state.linear_mode, osc.reg_written[3]); REFLECT(state.linear_mode, osc.reg_written[3]);
} }
static void reflect_noise(Nes_Apu::noise_t &state, Nes_Noise &osc) static void reflect_noise(Apu::noise_t &state, Noise &osc)
{ {
reflect_env(&state.env, osc); reflect_env(&state.env, osc);
REFLECT(state.delay, osc.delay); REFLECT(state.delay, osc.delay);
@ -278,7 +278,7 @@ struct apu_reflection
REFLECT(state.shift_reg, osc.noise); REFLECT(state.shift_reg, osc.noise);
} }
static void reflect_dmc(Nes_Apu::dmc_t &state, Nes_Dmc &osc) static void reflect_dmc(Apu::dmc_t &state, Dmc &osc)
{ {
REFLECT(state.delay, osc.delay); REFLECT(state.delay, osc.delay);
REFLECT(state.remain, osc.length_counter); REFLECT(state.remain, osc.length_counter);
@ -295,7 +295,7 @@ struct apu_reflection
} }
}; };
inline void Nes_Apu::save_state(apu_state_t *state) const inline void Apu::save_state(apu_state_t *state) const
{ {
for (int i = 0; i < osc_count * 4; i++) for (int i = 0; i < osc_count * 4; i++)
{ {
@ -313,7 +313,7 @@ inline void Nes_Apu::save_state(apu_state_t *state) const
state->apu.irq_flag = irq_flag; state->apu.irq_flag = irq_flag;
typedef apu_reflection<1> refl; typedef apu_reflection<1> refl;
Nes_Apu &apu = *(Nes_Apu *)this; // const_cast Apu &apu = *(Apu *)this; // const_cast
refl::reflect_square(state->square1, apu.square1); refl::reflect_square(state->square1, apu.square1);
refl::reflect_square(state->square2, apu.square2); refl::reflect_square(state->square2, apu.square2);
refl::reflect_triangle(state->triangle, apu.triangle); refl::reflect_triangle(state->triangle, apu.triangle);
@ -321,7 +321,7 @@ inline void Nes_Apu::save_state(apu_state_t *state) const
refl::reflect_dmc(state->dmc, apu.dmc); refl::reflect_dmc(state->dmc, apu.dmc);
} }
inline void Nes_Apu::load_state(apu_state_t const &state) inline void Apu::load_state(apu_state_t const &state)
{ {
reset(); reset();

View File

@ -1,6 +1,6 @@
// Nes_Emu 0.7.0. http://www.slack.net/~ant/libs/ // Emu 0.7.0. http://www.slack.net/~ant/libs/
#include "apu/Nes_Buffer.hpp" #include "apu/buffer.hpp"
#include "apu/apu.hpp" #include "apu/apu.hpp"
/* Library Copyright (C) 2003-2006 Shay Green. This library is free software; /* Library Copyright (C) 2003-2006 Shay Green. This library is free software;
@ -17,29 +17,29 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
namespace quickerNES namespace quickerNES
{ {
// Nes_Buffer // Buffer
Nes_Buffer::Nes_Buffer() : Multi_Buffer(1) {} Buffer::Buffer() : Multi_Buffer(1) {}
Nes_Buffer::~Nes_Buffer() {} Buffer::~Buffer() {}
Multi_Buffer *set_apu(Nes_Buffer *buf, Nes_Apu *apu) Multi_Buffer *set_apu(Buffer *buf, Apu *apu)
{ {
buf->set_apu(apu); buf->set_apu(apu);
return buf; return buf;
} }
void Nes_Buffer::enable_nonlinearity(bool b) void Buffer::enable_nonlinearity(bool b)
{ {
if (b) if (b)
clear(); clear();
Nes_Apu *apu = nonlin.enable(b, &tnd); Apu *apu = nonlin.enable(b, &tnd);
apu->osc_output(0, &buf); apu->osc_output(0, &buf);
apu->osc_output(1, &buf); apu->osc_output(1, &buf);
} }
const char *Nes_Buffer::set_sample_rate(long rate, int msec) const char *Buffer::set_sample_rate(long rate, int msec)
{ {
enable_nonlinearity(nonlin.enabled); // reapply enable_nonlinearity(nonlin.enabled); // reapply
buf.set_sample_rate(rate, msec); buf.set_sample_rate(rate, msec);
@ -47,26 +47,26 @@ const char *Nes_Buffer::set_sample_rate(long rate, int msec)
return Multi_Buffer::set_sample_rate(buf.sample_rate(), buf.length()); return Multi_Buffer::set_sample_rate(buf.sample_rate(), buf.length());
} }
void Nes_Buffer::clock_rate(long rate) void Buffer::clock_rate(long rate)
{ {
buf.clock_rate(rate); buf.clock_rate(rate);
tnd.clock_rate(rate); tnd.clock_rate(rate);
} }
void Nes_Buffer::bass_freq(int freq) void Buffer::bass_freq(int freq)
{ {
buf.bass_freq(freq); buf.bass_freq(freq);
tnd.bass_freq(freq); tnd.bass_freq(freq);
} }
void Nes_Buffer::clear() void Buffer::clear()
{ {
nonlin.clear(); nonlin.clear();
buf.clear(); buf.clear();
tnd.clear(); tnd.clear();
} }
Nes_Buffer::channel_t Nes_Buffer::channel(int i) Buffer::channel_t Buffer::channel(int i)
{ {
channel_t c; channel_t c;
c.center = &buf; c.center = &buf;
@ -77,18 +77,18 @@ Nes_Buffer::channel_t Nes_Buffer::channel(int i)
return c; return c;
} }
void Nes_Buffer::end_frame(blip_time_t length, bool) void Buffer::end_frame(blip_time_t length, bool)
{ {
buf.end_frame(length); buf.end_frame(length);
tnd.end_frame(length); tnd.end_frame(length);
} }
long Nes_Buffer::samples_avail() const long Buffer::samples_avail() const
{ {
return buf.samples_avail(); return buf.samples_avail();
} }
long Nes_Buffer::read_samples(blip_sample_t *out, long count) long Buffer::read_samples(blip_sample_t *out, long count)
{ {
count = nonlin.make_nonlinear(tnd, count); count = nonlin.make_nonlinear(tnd, count);
if (count) if (count)
@ -132,7 +132,7 @@ long Nes_Buffer::read_samples(blip_sample_t *out, long count)
return count; return count;
} }
void Nes_Buffer::SaveAudioBufferState() void Buffer::SaveAudioBufferState()
{ {
SaveAudioBufferStatePrivate(); SaveAudioBufferStatePrivate();
nonlin.SaveAudioBufferState(); nonlin.SaveAudioBufferState();
@ -140,7 +140,7 @@ void Nes_Buffer::SaveAudioBufferState()
tnd.SaveAudioBufferState(); tnd.SaveAudioBufferState();
} }
void Nes_Buffer::RestoreAudioBufferState() void Buffer::RestoreAudioBufferState()
{ {
RestoreAudioBufferStatePrivate(); RestoreAudioBufferStatePrivate();
nonlin.RestoreAudioBufferState(); nonlin.RestoreAudioBufferState();
@ -148,16 +148,16 @@ void Nes_Buffer::RestoreAudioBufferState()
tnd.RestoreAudioBufferState(); tnd.RestoreAudioBufferState();
} }
// Nes_Nonlinearizer // Nonlinearizer
Nes_Nonlinearizer::Nes_Nonlinearizer() Nonlinearizer::Nonlinearizer()
{ {
apu = nullptr; apu = nullptr;
enabled = true; enabled = true;
float const gain = 0x7fff * 1.3f; float const gain = 0x7fff * 1.3f;
// don't use entire range, so any overflow will stay within table // don't use entire range, so any overflow will stay within table
int const range = (int)((double)table_size * Nes_Apu::nonlinear_tnd_gain()); int const range = (int)((double)table_size * Apu::nonlinear_tnd_gain());
for (int i = 0; i < table_size; i++) for (int i = 0; i < table_size; i++)
{ {
int const offset = table_size - range; int const offset = table_size - range;
@ -174,7 +174,7 @@ Nes_Nonlinearizer::Nes_Nonlinearizer()
extra_prev = 0; extra_prev = 0;
} }
Nes_Apu *Nes_Nonlinearizer::enable(bool b, Blip_Buffer *buf) Apu *Nonlinearizer::enable(bool b, Blip_Buffer *buf)
{ {
apu->osc_output(2, buf); apu->osc_output(2, buf);
apu->osc_output(3, buf); apu->osc_output(3, buf);
@ -189,7 +189,7 @@ Nes_Apu *Nes_Nonlinearizer::enable(bool b, Blip_Buffer *buf)
#define ENTRY(s) table[(s) >> (blip_sample_bits - table_bits - 1) & (table_size - 1)] #define ENTRY(s) table[(s) >> (blip_sample_bits - table_bits - 1) & (table_size - 1)]
long Nes_Nonlinearizer::make_nonlinear(Blip_Buffer &buf, long count) long Nonlinearizer::make_nonlinear(Blip_Buffer &buf, long count)
{ {
long avail = buf.samples_avail(); long avail = buf.samples_avail();
if (count > avail) if (count > avail)
@ -214,20 +214,20 @@ long Nes_Nonlinearizer::make_nonlinear(Blip_Buffer &buf, long count)
return count; return count;
} }
void Nes_Nonlinearizer::clear() void Nonlinearizer::clear()
{ {
accum = 0; accum = 0;
prev = ENTRY(86016000); // avoid thump due to APU's triangle dc bias prev = ENTRY(86016000); // avoid thump due to APU's triangle dc bias
// TODO: still results in slight clicks and thumps // TODO: still results in slight clicks and thumps
} }
void Nes_Nonlinearizer::SaveAudioBufferState() void Nonlinearizer::SaveAudioBufferState()
{ {
extra_accum = accum; extra_accum = accum;
extra_prev = prev; extra_prev = prev;
} }
void Nes_Nonlinearizer::RestoreAudioBufferState() void Nonlinearizer::RestoreAudioBufferState()
{ {
accum = extra_accum; accum = extra_accum;
prev = extra_prev; prev = extra_prev;

View File

@ -1,7 +1,7 @@
#pragma once #pragma once
// NES non-linear audio buffer // NES non-linear audio buffer
// Nes_Emu 0.7.0 // Emu 0.7.0
#include "Multi_Buffer.hpp" #include "Multi_Buffer.hpp"
#include <cstdint> #include <cstdint>
@ -9,9 +9,9 @@
namespace quickerNES namespace quickerNES
{ {
class Nes_Apu; class Apu;
class Nes_Nonlinearizer class Nonlinearizer
{ {
private: private:
enum enum
@ -23,7 +23,7 @@ class Nes_Nonlinearizer
table_size = 1 << table_bits table_size = 1 << table_bits
}; };
int16_t table[table_size]; int16_t table[table_size];
Nes_Apu *apu; Apu *apu;
long accum; long accum;
long prev; long prev;
@ -31,25 +31,25 @@ class Nes_Nonlinearizer
long extra_prev; long extra_prev;
public: public:
Nes_Nonlinearizer(); Nonlinearizer();
bool enabled; bool enabled;
void clear(); void clear();
void set_apu(Nes_Apu *a) { apu = a; } void set_apu(Apu *a) { apu = a; }
Nes_Apu *enable(bool, Blip_Buffer *tnd); Apu *enable(bool, Blip_Buffer *tnd);
long make_nonlinear(Blip_Buffer &buf, long count); long make_nonlinear(Blip_Buffer &buf, long count);
void SaveAudioBufferState(); void SaveAudioBufferState();
void RestoreAudioBufferState(); void RestoreAudioBufferState();
}; };
class Nes_Buffer : public Multi_Buffer class Buffer : public Multi_Buffer
{ {
public: public:
Nes_Buffer(); Buffer();
~Nes_Buffer(); ~Buffer();
// Setup APU for use with buffer, including setting its output to this buffer. // Setup APU for use with buffer, including setting its output to this buffer.
// If you're using Nes_Emu, this is automatically called for you. // If you're using Emu, this is automatically called for you.
void set_apu(Nes_Apu *apu) { nonlin.set_apu(apu); } void set_apu(Apu *apu) { nonlin.set_apu(apu); }
// Enable/disable non-linear output // Enable/disable non-linear output
void enable_nonlinearity(bool = true); void enable_nonlinearity(bool = true);
@ -71,8 +71,8 @@ class Nes_Buffer : public Multi_Buffer
private: private:
Blip_Buffer buf; Blip_Buffer buf;
Blip_Buffer tnd; Blip_Buffer tnd;
Nes_Nonlinearizer nonlin; Nonlinearizer nonlin;
friend Multi_Buffer *set_apu(Nes_Buffer *, Nes_Apu *); friend Multi_Buffer *set_apu(Buffer *, Apu *);
public: public:
virtual void SaveAudioBufferState(); virtual void SaveAudioBufferState();

View File

@ -1,7 +1,7 @@
// Game_Music_Emu 0.3.0. http://www.slack.net/~ant/ // Game_Music_Emu 0.3.0. http://www.slack.net/~ant/
#include "Effects_Buffer.hpp"
#include <cstring> #include <cstring>
#include "effectsBuffer.hpp"
/* Copyright (C) 2003-2006 Shay Green. This module is free software; you /* 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 can redistribute it and/or modify it under the terms of the GNU Lesser

View File

@ -7,7 +7,7 @@
#include <stdint.h> #include <stdint.h>
namespace quickerNES namespace quickerNES
{ {
// Effects_Buffer uses several buffers and outputs stereo sample pairs. // Effects_Buffer uses several buffers and outputs stereo sample pairs.
class Effects_Buffer : public Multi_Buffer class Effects_Buffer : public Multi_Buffer

View File

@ -1,5 +1,5 @@
// Nes_Emu 0.7.0. http://www.slack.net/~ant/ // Emu 0.7.0. http://www.slack.net/~ant/
#include "apu/fme7/apu.hpp" #include "apu/fme7/apu.hpp"
#include <cstring> #include <cstring>
@ -18,7 +18,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
namespace quickerNES namespace quickerNES
{ {
void Nes_Fme7_Apu::reset() void Fme7_Apu::reset()
{ {
last_time = 0; last_time = 0;
@ -29,14 +29,14 @@ void Nes_Fme7_Apu::reset()
memset(state, 0, sizeof *state); memset(state, 0, sizeof *state);
} }
unsigned char Nes_Fme7_Apu::amp_table[16] = unsigned char Fme7_Apu::amp_table[16] =
{ {
#define ENTRY(n) (unsigned char)(n * +amp_range + 0.5) #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 #undef ENTRY
}; };
void Nes_Fme7_Apu::run_until(blip_time_t end_time) void Fme7_Apu::run_until(blip_time_t end_time)
{ {
for (int index = 0; index < osc_count; index++) for (int index = 0; index < osc_count; index++)
{ {

View File

@ -1,7 +1,7 @@
#pragma once #pragma once
// Sunsoft FME-7 sound emulator // Sunsoft FME-7 sound emulator
// Nes_Emu 0.7.0 // Emu 0.7.0
#include <cstdint> #include <cstdint>
#include "apu/Blip_Buffer.hpp" #include "apu/Blip_Buffer.hpp"
@ -22,12 +22,12 @@ struct fme7_apu_state_t
}; };
static_assert(sizeof(fme7_apu_state_t) == 24); static_assert(sizeof(fme7_apu_state_t) == 24);
class Nes_Fme7_Apu : private fme7_apu_state_t class Fme7_Apu : private fme7_apu_state_t
{ {
public: public:
Nes_Fme7_Apu(); Fme7_Apu();
// See Nes_Apu.h for reference // See Apu.h for reference
void reset(); void reset();
void volume(double); void volume(double);
void treble_eq(blip_eq_t const &); void treble_eq(blip_eq_t const &);
@ -64,8 +64,8 @@ class Nes_Fme7_Apu : private fme7_apu_state_t
// End of public interface // End of public interface
private: private:
// noncopyable // noncopyable
Nes_Fme7_Apu(const Nes_Fme7_Apu &); Fme7_Apu(const Fme7_Apu &);
Nes_Fme7_Apu &operator=(const Nes_Fme7_Apu &); Fme7_Apu &operator=(const Fme7_Apu &);
static unsigned char amp_table[16]; static unsigned char amp_table[16];
@ -85,37 +85,37 @@ class Nes_Fme7_Apu : private fme7_apu_state_t
void run_until(blip_time_t); void run_until(blip_time_t);
}; };
inline void Nes_Fme7_Apu::volume(double v) inline void Fme7_Apu::volume(double v)
{ {
synth.volume(0.38 / +amp_range * v); // to do: fine-tune synth.volume(0.38 / +amp_range * v); // to do: fine-tune
} }
inline void Nes_Fme7_Apu::treble_eq(blip_eq_t const &eq) inline void Fme7_Apu::treble_eq(blip_eq_t const &eq)
{ {
synth.treble_eq(eq); synth.treble_eq(eq);
} }
inline void Nes_Fme7_Apu::osc_output(int i, Blip_Buffer *buf) inline void Fme7_Apu::osc_output(int i, Blip_Buffer *buf)
{ {
oscs[i].output = buf; oscs[i].output = buf;
} }
inline void Nes_Fme7_Apu::output(Blip_Buffer *buf) inline void Fme7_Apu::output(Blip_Buffer *buf)
{ {
for (int i = 0; i < osc_count; i++) for (int i = 0; i < osc_count; i++)
osc_output(i, buf); osc_output(i, buf);
} }
inline Nes_Fme7_Apu::Nes_Fme7_Apu() inline Fme7_Apu::Fme7_Apu()
{ {
output(0); output(0);
volume(1.0); volume(1.0);
reset(); reset();
} }
inline void Nes_Fme7_Apu::write_latch(int data) { latch = data; } inline void Fme7_Apu::write_latch(int data) { latch = data; }
inline void Nes_Fme7_Apu::write_data(blip_time_t time, int data) inline void Fme7_Apu::write_data(blip_time_t time, int data)
{ {
if ((unsigned)latch >= reg_count) if ((unsigned)latch >= reg_count)
{ {
@ -129,7 +129,7 @@ inline void Nes_Fme7_Apu::write_data(blip_time_t time, int data)
regs[latch] = data; regs[latch] = data;
} }
inline void Nes_Fme7_Apu::end_frame(blip_time_t time) inline void Fme7_Apu::end_frame(blip_time_t time)
{ {
if (time > last_time) if (time > last_time)
run_until(time); run_until(time);
@ -137,12 +137,12 @@ inline void Nes_Fme7_Apu::end_frame(blip_time_t time)
last_time -= time; last_time -= time;
} }
inline void Nes_Fme7_Apu::save_state(fme7_apu_state_t *out) const inline void Fme7_Apu::save_state(fme7_apu_state_t *out) const
{ {
*out = *this; *out = *this;
} }
inline void Nes_Fme7_Apu::load_state(fme7_apu_state_t const &in) inline void Fme7_Apu::load_state(fme7_apu_state_t const &in)
{ {
reset(); reset();
fme7_apu_state_t *state = this; fme7_apu_state_t *state = this;

View File

@ -1,5 +1,5 @@
// Nes_Snd_Emu 0.1.7. http://www.slack.net/~ant/ // Snd_Emu 0.1.7. http://www.slack.net/~ant/
#include "apu/namco/apu.hpp" #include "apu/namco/apu.hpp"
#include "apu/Blip_Buffer.hpp" #include "apu/Blip_Buffer.hpp"
@ -18,18 +18,18 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
namespace quickerNES namespace quickerNES
{ {
Nes_Namco_Apu::Nes_Namco_Apu() Namco_Apu::Namco_Apu()
{ {
output(0); output(0);
volume(1.0); volume(1.0);
reset(); reset();
} }
Nes_Namco_Apu::~Nes_Namco_Apu() Namco_Apu::~Namco_Apu()
{ {
} }
void Nes_Namco_Apu::reset() void Namco_Apu::reset()
{ {
last_time = 0; last_time = 0;
addr_reg = 0; addr_reg = 0;
@ -47,14 +47,14 @@ void Nes_Namco_Apu::reset()
} }
} }
void Nes_Namco_Apu::output(Blip_Buffer *buf) void Namco_Apu::output(Blip_Buffer *buf)
{ {
for (int i = 0; i < osc_count; i++) for (int i = 0; i < osc_count; i++)
osc_output(i, buf); osc_output(i, buf);
} }
/* /*
void Nes_Namco_Apu::reflect_state( Tagged_Data& data ) void Namco_Apu::reflect_state( Tagged_Data& data )
{ {
reflect_int16( data, 'ADDR', &addr_reg ); reflect_int16( data, 'ADDR', &addr_reg );
@ -71,7 +71,7 @@ void Nes_Namco_Apu::reflect_state( Tagged_Data& data )
} }
*/ */
void Nes_Namco_Apu::end_frame(nes_time_t time) void Namco_Apu::end_frame(nes_time_t time)
{ {
if (time > last_time) if (time > last_time)
run_until(time); run_until(time);
@ -79,7 +79,7 @@ void Nes_Namco_Apu::end_frame(nes_time_t time)
last_time -= time; last_time -= time;
} }
void Nes_Namco_Apu::run_until(nes_time_t nes_end_time) void Namco_Apu::run_until(nes_time_t nes_end_time)
{ {
int active_oscs = (reg[0x7F] >> 4 & 7) + 1; int active_oscs = (reg[0x7F] >> 4 & 7) + 1;
for (int i = osc_count - active_oscs; i < osc_count; i++) for (int i = osc_count - active_oscs; i < osc_count; i++)
@ -147,7 +147,7 @@ void Nes_Namco_Apu::run_until(nes_time_t nes_end_time)
last_time = nes_end_time; last_time = nes_end_time;
} }
void Nes_Namco_Apu::save_state(namco_state_t *out) const void Namco_Apu::save_state(namco_state_t *out) const
{ {
out->addr = addr_reg; out->addr = addr_reg;
for (int r = 0; r < reg_count; r++) for (int r = 0; r < reg_count; r++)
@ -162,7 +162,7 @@ void Nes_Namco_Apu::save_state(namco_state_t *out) const
} }
} }
void Nes_Namco_Apu::load_state(namco_state_t const &in) void Namco_Apu::load_state(namco_state_t const &in)
{ {
reset(); reset();
addr_reg = in.addr; addr_reg = in.addr;

View File

@ -1,7 +1,7 @@
#pragma once #pragma once
// Namco 106 sound chip emulator // Namco 106 sound chip emulator
// Nes_Snd_Emu 0.1.7 // Snd_Emu 0.1.7
#include <cstdint> #include <cstdint>
#include "apu/apu.hpp" #include "apu/apu.hpp"
@ -19,13 +19,13 @@ struct namco_state_t
}; };
static_assert(sizeof(namco_state_t) == 172); static_assert(sizeof(namco_state_t) == 172);
class Nes_Namco_Apu class Namco_Apu
{ {
public: public:
Nes_Namco_Apu(); Namco_Apu();
~Nes_Namco_Apu(); ~Namco_Apu();
// See Nes_Apu.h for reference. // See Apu.h for reference.
void volume(double); void volume(double);
void treble_eq(const blip_eq_t &); void treble_eq(const blip_eq_t &);
void output(Blip_Buffer *); void output(Blip_Buffer *);
@ -58,8 +58,8 @@ class Nes_Namco_Apu
private: private:
// noncopyable // noncopyable
Nes_Namco_Apu(const Nes_Namco_Apu &); Namco_Apu(const Namco_Apu &);
Nes_Namco_Apu &operator=(const Nes_Namco_Apu &); Namco_Apu &operator=(const Namco_Apu &);
struct Namco_Osc struct Namco_Osc
{ {
@ -85,7 +85,7 @@ class Nes_Namco_Apu
void run_until(nes_time_t); void run_until(nes_time_t);
}; };
inline uint8_t &Nes_Namco_Apu::access() inline uint8_t &Namco_Apu::access()
{ {
int addr = addr_reg & 0x7f; int addr = addr_reg & 0x7f;
if (addr_reg & 0x80) if (addr_reg & 0x80)
@ -93,20 +93,20 @@ inline uint8_t &Nes_Namco_Apu::access()
return reg[addr]; return reg[addr];
} }
inline void Nes_Namco_Apu::volume(double v) { synth.volume(0.10 / +osc_count * v); } inline void Namco_Apu::volume(double v) { synth.volume(0.10 / +osc_count * v); }
inline void Nes_Namco_Apu::treble_eq(const blip_eq_t &eq) { synth.treble_eq(eq); } inline void Namco_Apu::treble_eq(const blip_eq_t &eq) { synth.treble_eq(eq); }
inline void Nes_Namco_Apu::write_addr(int v) { addr_reg = v; } inline void Namco_Apu::write_addr(int v) { addr_reg = v; }
inline int Nes_Namco_Apu::read_data() { return access(); } inline int Namco_Apu::read_data() { return access(); }
inline void Nes_Namco_Apu::osc_output(int i, Blip_Buffer *buf) inline void Namco_Apu::osc_output(int i, Blip_Buffer *buf)
{ {
oscs[i].output = buf; oscs[i].output = buf;
} }
inline void Nes_Namco_Apu::write_data(nes_time_t time, int data) inline void Namco_Apu::write_data(nes_time_t time, int data)
{ {
run_until(time); run_until(time);
access() = data; access() = data;

View File

@ -1,5 +1,5 @@
// Nes_Snd_Emu 0.1.7. http://www.slack.net/~ant/ // Snd_Emu 0.1.7. http://www.slack.net/~ant/
#include "apu.hpp" #include "apu.hpp"
@ -17,15 +17,15 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
namespace quickerNES namespace quickerNES
{ {
// Nes_Osc // Osc
void Nes_Osc::clock_length(int halt_mask) void Osc::clock_length(int halt_mask)
{ {
if (length_counter && !(regs[0] & halt_mask)) if (length_counter && !(regs[0] & halt_mask))
length_counter--; length_counter--;
} }
void Nes_Envelope::clock_envelope() void Envelope::clock_envelope()
{ {
int period = regs[0] & 15; int period = regs[0] & 15;
if (reg_written[3]) if (reg_written[3])
@ -42,15 +42,15 @@ void Nes_Envelope::clock_envelope()
} }
} }
int Nes_Envelope::volume() const int Envelope::volume() const
{ {
return length_counter == 0 ? 0 : (regs[0] & 0x10) ? (regs[0] & 15) return length_counter == 0 ? 0 : (regs[0] & 0x10) ? (regs[0] & 15)
: envelope; : envelope;
} }
// Nes_Square // Square
void Nes_Square::clock_sweep(int negative_adjust) void Square::clock_sweep(int negative_adjust)
{ {
int sweep = regs[1]; int sweep = regs[1];
@ -85,7 +85,7 @@ void Nes_Square::clock_sweep(int negative_adjust)
} }
// TODO: clean up // 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 Square::maintain_phase(nes_time_t time, nes_time_t end_time, nes_time_t timer_period)
{ {
long remain = end_time - time; long remain = end_time - time;
if (remain > 0) if (remain > 0)
@ -97,7 +97,7 @@ inline nes_time_t Nes_Square::maintain_phase(nes_time_t time, nes_time_t end_tim
return time; return time;
} }
void Nes_Square::run(nes_time_t time, nes_time_t end_time) void Square::run(nes_time_t time, nes_time_t end_time)
{ {
const int period = this->period(); const int period = this->period();
const int timer_period = (period + 1) * 2; const int timer_period = (period + 1) * 2;
@ -168,9 +168,9 @@ void Nes_Square::run(nes_time_t time, nes_time_t end_time)
delay = time - end_time; delay = time - end_time;
} }
// Nes_Triangle // Triangle
void Nes_Triangle::clock_linear_counter() void Triangle::clock_linear_counter()
{ {
if (reg_written[3]) if (reg_written[3])
linear_counter = regs[0] & 0x7f; linear_counter = regs[0] & 0x7f;
@ -181,7 +181,7 @@ void Nes_Triangle::clock_linear_counter()
reg_written[3] = false; reg_written[3] = false;
} }
inline int Nes_Triangle::calc_amp() const inline int Triangle::calc_amp() const
{ {
int amp = phase_range - phase; int amp = phase_range - phase;
if (amp < 0) if (amp < 0)
@ -190,7 +190,7 @@ inline int Nes_Triangle::calc_amp() const
} }
// TODO: clean up // 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 Triangle::maintain_phase(nes_time_t time, nes_time_t end_time, nes_time_t timer_period)
{ {
long remain = end_time - time; long remain = end_time - time;
if (remain > 0) if (remain > 0)
@ -203,7 +203,7 @@ inline nes_time_t Nes_Triangle::maintain_phase(nes_time_t time, nes_time_t end_t
return time; return time;
} }
void Nes_Triangle::run(nes_time_t time, nes_time_t end_time) void Triangle::run(nes_time_t time, nes_time_t end_time)
{ {
const int timer_period = period() + 1; const int timer_period = period() + 1;
if (!output) if (!output)
@ -261,9 +261,9 @@ void Nes_Triangle::run(nes_time_t time, nes_time_t end_time)
delay = time - end_time; delay = time - end_time;
} }
// Nes_Dmc // Dmc
void Nes_Dmc::reset() void Dmc::reset()
{ {
address = 0; address = 0;
dac = 0; dac = 0;
@ -272,17 +272,17 @@ void Nes_Dmc::reset()
bits = 0; bits = 0;
buf_full = false; buf_full = false;
silence = true; silence = true;
next_irq = Nes_Apu::no_irq; next_irq = Apu::no_irq;
irq_flag = false; irq_flag = false;
irq_enabled = false; irq_enabled = false;
Nes_Osc::reset(); Osc::reset();
period = 0x1ac; period = 0x1ac;
} }
void Nes_Dmc::recalc_irq() void Dmc::recalc_irq()
{ {
nes_time_t irq = Nes_Apu::no_irq; nes_time_t irq = Apu::no_irq;
if (irq_enabled && length_counter) if (irq_enabled && length_counter)
irq = apu->last_dmc_time + delay + irq = apu->last_dmc_time + delay +
((length_counter - 1) * 8 + bits_remain - 1) * nes_time_t(period) + 1; ((length_counter - 1) * 8 + bits_remain - 1) * nes_time_t(period) + 1;
@ -293,7 +293,7 @@ void Nes_Dmc::recalc_irq()
} }
} }
int Nes_Dmc::count_reads(nes_time_t time, nes_time_t *last_read) const int Dmc::count_reads(nes_time_t time, nes_time_t *last_read) const
{ {
if (last_read) if (last_read)
*last_read = time; *last_read = time;
@ -338,7 +338,7 @@ static const short dmc_period_table[2][16] = {
0x032} // to do: verify PAL periods 0x032} // to do: verify PAL periods
}; };
inline void Nes_Dmc::reload_sample() inline void Dmc::reload_sample()
{ {
address = 0x4000 + regs[2] * 0x40; address = 0x4000 + regs[2] * 0x40;
length_counter = regs[3] * 0x10 + 1; length_counter = regs[3] * 0x10 + 1;
@ -476,7 +476,7 @@ static const unsigned char dac_table[128] =
83, 83,
}; };
void Nes_Dmc::write_register(int addr, int data) void Dmc::write_register(int addr, int data)
{ {
if (addr == 0) if (addr == 0)
{ {
@ -498,14 +498,14 @@ void Nes_Dmc::write_register(int addr, int data)
} }
} }
void Nes_Dmc::start() void Dmc::start()
{ {
reload_sample(); reload_sample();
fill_buffer(); fill_buffer();
recalc_irq(); recalc_irq();
} }
void Nes_Dmc::fill_buffer() void Dmc::fill_buffer()
{ {
if (!buf_full && length_counter) if (!buf_full && length_counter)
{ {
@ -522,14 +522,14 @@ void Nes_Dmc::fill_buffer()
{ {
apu->osc_enables &= ~0x10; apu->osc_enables &= ~0x10;
irq_flag = irq_enabled; irq_flag = irq_enabled;
next_irq = Nes_Apu::no_irq; next_irq = Apu::no_irq;
apu->irq_changed(); apu->irq_changed();
} }
} }
} }
} }
void Nes_Dmc::run(nes_time_t time, nes_time_t end_time) void Dmc::run(nes_time_t time, nes_time_t end_time)
{ {
int delta = update_amp(dac); int delta = update_amp(dac);
if (!output) if (!output)
@ -597,12 +597,12 @@ void Nes_Dmc::run(nes_time_t time, nes_time_t end_time)
delay = time - end_time; delay = time - end_time;
} }
// Nes_Noise // Noise
static const short noise_period_table[16] = { 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) void Noise::run(nes_time_t time, nes_time_t end_time)
{ {
int period = noise_period_table[regs[2] & 15]; int period = noise_period_table[regs[2] & 15];
#if NES_APU_NOISE_LOW_CPU #if NES_APU_NOISE_LOW_CPU

View File

@ -1,20 +1,20 @@
#pragma once #pragma once
// Private oscillators used by Nes_Apu // Private oscillators used by Apu
// Nes_Snd_Emu 0.1.7 // Snd_Emu 0.1.7
#include "Blip_Buffer.hpp" #include "Blip_Buffer.hpp"
namespace quickerNES namespace quickerNES
{ {
class Nes_Apu; class Apu;
typedef long nes_time_t; // CPU clock cycle count typedef long nes_time_t; // CPU clock cycle count
typedef unsigned nes_addr_t; // 16-bit memory address typedef unsigned nes_addr_t; // 16-bit memory address
struct Nes_Osc struct Osc
{ {
unsigned char regs[4]; unsigned char regs[4];
bool reg_written[4]; bool reg_written[4];
@ -41,7 +41,7 @@ struct Nes_Osc
} }
}; };
struct Nes_Envelope : Nes_Osc struct Envelope : Osc
{ {
int envelope; int envelope;
int env_delay; int env_delay;
@ -52,12 +52,12 @@ struct Nes_Envelope : Nes_Osc
{ {
envelope = 0; envelope = 0;
env_delay = 0; env_delay = 0;
Nes_Osc::reset(); Osc::reset();
} }
}; };
// Nes_Square // Square
struct Nes_Square : Nes_Envelope struct Square : Envelope
{ {
enum enum
{ {
@ -77,20 +77,20 @@ struct Nes_Square : Nes_Envelope
typedef Blip_Synth<blip_good_quality, 1> Synth; typedef Blip_Synth<blip_good_quality, 1> Synth;
Synth const &synth; // shared between squares Synth const &synth; // shared between squares
Nes_Square(Synth const *s) : synth(*s) {} Square(Synth const *s) : synth(*s) {}
void clock_sweep(int adjust); void clock_sweep(int adjust);
void run(nes_time_t, nes_time_t); void run(nes_time_t, nes_time_t);
void reset() void reset()
{ {
sweep_delay = 0; sweep_delay = 0;
Nes_Envelope::reset(); 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 // Triangle
struct Nes_Triangle : Nes_Osc struct Triangle : Osc
{ {
enum enum
{ {
@ -107,13 +107,13 @@ struct Nes_Triangle : Nes_Osc
{ {
linear_counter = 0; linear_counter = 0;
phase = 1; phase = 1;
Nes_Osc::reset(); 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 // Noise
struct Nes_Noise : Nes_Envelope struct Noise : Envelope
{ {
int noise; int noise;
Blip_Synth<blip_med_quality, 1> synth; Blip_Synth<blip_med_quality, 1> synth;
@ -122,16 +122,16 @@ struct Nes_Noise : Nes_Envelope
void reset() void reset()
{ {
noise = 1 << 14; noise = 1 << 14;
Nes_Envelope::reset(); Envelope::reset();
} }
}; };
// Nes_Dmc // Dmc
struct Nes_Dmc : Nes_Osc struct Dmc : Osc
{ {
int address; // address of next byte to read int address; // address of next byte to read
int period; int period;
// int length_counter; // bytes remaining to play (already defined in Nes_Osc) // int length_counter; // bytes remaining to play (already defined in Osc)
int buf; int buf;
int bits_remain; int bits_remain;
int bits; int bits;
@ -154,7 +154,7 @@ struct Nes_Dmc : Nes_Osc
int (*prg_reader)(void *, nes_addr_t); // needs to be initialized to prg read function int (*prg_reader)(void *, nes_addr_t); // needs to be initialized to prg read function
void *prg_reader_data; void *prg_reader_data;
Nes_Apu *apu; Apu *apu;
Blip_Synth<blip_med_quality, 1> synth; Blip_Synth<blip_med_quality, 1> synth;

View File

@ -1,5 +1,5 @@
// Nes_Snd_Emu 0.1.7. http://www.slack.net/~ant/ // Snd_Emu 0.1.7. http://www.slack.net/~ant/
#include "apu/vrc6/apu.hpp" #include "apu/vrc6/apu.hpp"
@ -17,18 +17,18 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
namespace quickerNES namespace quickerNES
{ {
Nes_Vrc6_Apu::Nes_Vrc6_Apu() Vrc6_Apu::Vrc6_Apu()
{ {
output(0); output(0);
volume(1.0); volume(1.0);
reset(); reset();
} }
Nes_Vrc6_Apu::~Nes_Vrc6_Apu() Vrc6_Apu::~Vrc6_Apu()
{ {
} }
void Nes_Vrc6_Apu::reset() void Vrc6_Apu::reset()
{ {
last_time = 0; last_time = 0;
for (int i = 0; i < osc_count; i++) for (int i = 0; i < osc_count; i++)
@ -43,13 +43,13 @@ void Nes_Vrc6_Apu::reset()
} }
} }
void Nes_Vrc6_Apu::output(Blip_Buffer *buf) void Vrc6_Apu::output(Blip_Buffer *buf)
{ {
for (int i = 0; i < osc_count; i++) for (int i = 0; i < osc_count; i++)
osc_output(i, buf); osc_output(i, buf);
} }
void Nes_Vrc6_Apu::run_until(nes_time_t time) void Vrc6_Apu::run_until(nes_time_t time)
{ {
run_square(oscs[0], time); run_square(oscs[0], time);
run_square(oscs[1], time); run_square(oscs[1], time);
@ -57,13 +57,13 @@ void Nes_Vrc6_Apu::run_until(nes_time_t time)
last_time = time; last_time = time;
} }
void Nes_Vrc6_Apu::write_osc(nes_time_t time, int osc_index, int reg, int data) void Vrc6_Apu::write_osc(nes_time_t time, int osc_index, int reg, int data)
{ {
run_until(time); run_until(time);
oscs[osc_index].regs[reg] = data; oscs[osc_index].regs[reg] = data;
} }
void Nes_Vrc6_Apu::end_frame(nes_time_t time) void Vrc6_Apu::end_frame(nes_time_t time)
{ {
if (time > last_time) if (time > last_time)
run_until(time); run_until(time);
@ -71,7 +71,7 @@ void Nes_Vrc6_Apu::end_frame(nes_time_t time)
last_time -= time; last_time -= time;
} }
void Nes_Vrc6_Apu::save_state(vrc6_apu_state_t *out) const void Vrc6_Apu::save_state(vrc6_apu_state_t *out) const
{ {
out->saw_amp = oscs[2].amp; out->saw_amp = oscs[2].amp;
for (int i = 0; i < osc_count; i++) for (int i = 0; i < osc_count; i++)
@ -85,7 +85,7 @@ void Nes_Vrc6_Apu::save_state(vrc6_apu_state_t *out) const
} }
} }
void Nes_Vrc6_Apu::load_state(vrc6_apu_state_t const &in) void Vrc6_Apu::load_state(vrc6_apu_state_t const &in)
{ {
reset(); reset();
oscs[2].amp = in.saw_amp; oscs[2].amp = in.saw_amp;
@ -105,7 +105,7 @@ void Nes_Vrc6_Apu::load_state(vrc6_apu_state_t const &in)
this->run_until(this->last_time); this->run_until(this->last_time);
} }
void Nes_Vrc6_Apu::run_square(Vrc6_Osc &osc, nes_time_t end_time) void Vrc6_Apu::run_square(Vrc6_Osc &osc, nes_time_t end_time)
{ {
Blip_Buffer *output = osc.output; Blip_Buffer *output = osc.output;
if (!output) if (!output)
@ -157,7 +157,7 @@ void Nes_Vrc6_Apu::run_square(Vrc6_Osc &osc, nes_time_t end_time)
} }
} }
void Nes_Vrc6_Apu::run_saw(nes_time_t end_time) void Vrc6_Apu::run_saw(nes_time_t end_time)
{ {
Vrc6_Osc &osc = oscs[2]; Vrc6_Osc &osc = oscs[2];
Blip_Buffer *output = osc.output; Blip_Buffer *output = osc.output;

View File

@ -2,7 +2,7 @@
#pragma once #pragma once
// Konami VRC6 sound chip emulator // Konami VRC6 sound chip emulator
// Nes_Snd_Emu 0.1.7 // Snd_Emu 0.1.7
#include <cstdint> #include <cstdint>
#include "apu/Blip_Buffer.hpp" #include "apu/Blip_Buffer.hpp"
@ -13,13 +13,13 @@ namespace quickerNES
struct vrc6_apu_state_t; struct vrc6_apu_state_t;
class Nes_Vrc6_Apu class Vrc6_Apu
{ {
public: public:
Nes_Vrc6_Apu(); Vrc6_Apu();
~Nes_Vrc6_Apu(); ~Vrc6_Apu();
// See Nes_Apu.h for reference // See Apu.h for reference
void reset(); void reset();
void volume(double); void volume(double);
void treble_eq(blip_eq_t const &); void treble_eq(blip_eq_t const &);
@ -52,8 +52,8 @@ class Nes_Vrc6_Apu
private: private:
// noncopyable // noncopyable
Nes_Vrc6_Apu(const Nes_Vrc6_Apu &); Vrc6_Apu(const Vrc6_Apu &);
Nes_Vrc6_Apu &operator=(const Nes_Vrc6_Apu &); Vrc6_Apu &operator=(const Vrc6_Apu &);
struct Vrc6_Osc struct Vrc6_Osc
{ {
@ -91,19 +91,19 @@ struct vrc6_apu_state_t
}; };
static_assert(sizeof(vrc6_apu_state_t) == 20); static_assert(sizeof(vrc6_apu_state_t) == 20);
inline void Nes_Vrc6_Apu::osc_output(int i, Blip_Buffer *buf) inline void Vrc6_Apu::osc_output(int i, Blip_Buffer *buf)
{ {
oscs[i].output = buf; oscs[i].output = buf;
} }
inline void Nes_Vrc6_Apu::volume(double v) inline void Vrc6_Apu::volume(double v)
{ {
double const factor = 0.0967 * 2; double const factor = 0.0967 * 2;
saw_synth.volume(factor / 31 * v); saw_synth.volume(factor / 31 * v);
square_synth.volume(factor * 0.5 / 15 * v); square_synth.volume(factor * 0.5 / 15 * v);
} }
inline void Nes_Vrc6_Apu::treble_eq(blip_eq_t const &eq) inline void Vrc6_Apu::treble_eq(blip_eq_t const &eq)
{ {
saw_synth.treble_eq(eq); saw_synth.treble_eq(eq);
square_synth.treble_eq(eq); square_synth.treble_eq(eq);

View File

@ -24,7 +24,7 @@ static bool IsLittleEndian()
return false; return false;
} }
Nes_Vrc7::Nes_Vrc7() Vrc7::Vrc7()
{ {
opll = OPLL_new(3579545); opll = OPLL_new(3579545);
output(NULL); output(NULL);
@ -32,12 +32,12 @@ Nes_Vrc7::Nes_Vrc7()
reset(); reset();
} }
Nes_Vrc7::~Nes_Vrc7() Vrc7::~Vrc7()
{ {
OPLL_delete((OPLL *)opll); OPLL_delete((OPLL *)opll);
} }
void Nes_Vrc7::reset() void Vrc7::reset()
{ {
last_time = 0; last_time = 0;
count = 0; count = 0;
@ -53,23 +53,23 @@ void Nes_Vrc7::reset()
OPLL_reset((OPLL *)opll); OPLL_reset((OPLL *)opll);
} }
void Nes_Vrc7::volume(double v) void Vrc7::volume(double v)
{ {
synth.volume(v * 1. / 3.); synth.volume(v * 1. / 3.);
} }
void Nes_Vrc7::treble_eq(blip_eq_t const &eq) void Vrc7::treble_eq(blip_eq_t const &eq)
{ {
synth.treble_eq(eq); synth.treble_eq(eq);
} }
void Nes_Vrc7::output(Blip_Buffer *buf) void Vrc7::output(Blip_Buffer *buf)
{ {
for (int i = 0; i < osc_count; i++) for (int i = 0; i < osc_count; i++)
osc_output(i, buf); osc_output(i, buf);
} }
void Nes_Vrc7::run_until(nes_time_t end_time) void Vrc7::run_until(nes_time_t end_time)
{ {
nes_time_t time = last_time; nes_time_t time = last_time;
@ -105,12 +105,12 @@ void Nes_Vrc7::run_until(nes_time_t end_time)
last_time = end_time; last_time = end_time;
} }
void Nes_Vrc7::write_reg(int data) void Vrc7::write_reg(int data)
{ {
OPLL_writeIO((OPLL *)opll, 0, data); OPLL_writeIO((OPLL *)opll, 0, data);
} }
void Nes_Vrc7::write_data(nes_time_t time, int data) void Vrc7::write_data(nes_time_t time, int data)
{ {
if ((unsigned)(((OPLL *)opll)->adr - 0x10) < 0x36) if ((unsigned)(((OPLL *)opll)->adr - 0x10) < 0x36)
{ {
@ -124,14 +124,14 @@ void Nes_Vrc7::write_data(nes_time_t time, int data)
OPLL_writeIO((OPLL *)opll, 1, data); OPLL_writeIO((OPLL *)opll, 1, data);
} }
void Nes_Vrc7::end_frame(nes_time_t time) void Vrc7::end_frame(nes_time_t time)
{ {
if (time > last_time) if (time > last_time)
run_until(time); run_until(time);
last_time -= time; last_time -= time;
} }
void Nes_Vrc7::save_snapshot(vrc7_snapshot_t *out) void Vrc7::save_snapshot(vrc7_snapshot_t *out)
{ {
out->latch = ((OPLL *)opll)->adr; out->latch = ((OPLL *)opll)->adr;
memcpy(out->inst, ((OPLL *)opll)->CustInst, 8); memcpy(out->inst, ((OPLL *)opll)->CustInst, 8);
@ -152,7 +152,7 @@ void Nes_Vrc7::save_snapshot(vrc7_snapshot_t *out)
OPLL_state_byteswap(&(out->internal_opl_state)); OPLL_state_byteswap(&(out->internal_opl_state));
} }
void Nes_Vrc7::load_snapshot(vrc7_snapshot_t &in, int dataSize) void Vrc7::load_snapshot(vrc7_snapshot_t &in, int dataSize)
{ {
reset(); reset();
write_reg(in.latch); write_reg(in.latch);
@ -190,7 +190,7 @@ void Nes_Vrc7::load_snapshot(vrc7_snapshot_t &in, int dataSize)
update_last_amp(); update_last_amp();
} }
void Nes_Vrc7::update_last_amp() void Vrc7::update_last_amp()
{ {
for (unsigned i = 0; i < osc_count; ++i) for (unsigned i = 0; i < osc_count; ++i)
{ {

View File

@ -2,7 +2,7 @@
#pragma once #pragma once
// Konami VRC7 sound chip emulator // Konami VRC7 sound chip emulator
// Nes_Snd_Emu 0.1.7. Copyright (C) 2003-2005 Shay Green. GNU LGPL license. // Snd_Emu 0.1.7. Copyright (C) 2003-2005 Shay Green. GNU LGPL license.
#include <cstdint> #include <cstdint>
#include "apu/Blip_Buffer.hpp" #include "apu/Blip_Buffer.hpp"
@ -14,13 +14,13 @@ namespace quickerNES
struct vrc7_snapshot_t; struct vrc7_snapshot_t;
typedef long nes_time_t; typedef long nes_time_t;
class Nes_Vrc7 class Vrc7
{ {
public: public:
Nes_Vrc7(); Vrc7();
~Nes_Vrc7(); ~Vrc7();
// See Nes_Apu.h for reference // See Apu.h for reference
void reset(); void reset();
void volume(double); void volume(double);
void treble_eq(blip_eq_t const &); void treble_eq(blip_eq_t const &);
@ -40,8 +40,8 @@ class Nes_Vrc7
private: private:
// noncopyable // noncopyable
Nes_Vrc7(const Nes_Vrc7 &); Vrc7(const Vrc7 &);
Nes_Vrc7 &operator=(const Nes_Vrc7 &); Vrc7 &operator=(const Vrc7 &);
struct Vrc7_Osc struct Vrc7_Osc
{ {
@ -71,7 +71,7 @@ struct vrc7_snapshot_t
}; };
static_assert(sizeof(vrc7_snapshot_t) == 28 + 440 + 4); static_assert(sizeof(vrc7_snapshot_t) == 28 + 440 + 4);
inline void Nes_Vrc7::osc_output(int i, Blip_Buffer *buf) inline void Vrc7::osc_output(int i, Blip_Buffer *buf)
{ {
oscs[i].output = buf; oscs[i].output = buf;
} }

View File

@ -13,7 +13,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 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 */ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
// Nes_Emu 0.7.0. http://www.slack.net/~ant/ // Emu 0.7.0. http://www.slack.net/~ant/
#include <cstdint> #include <cstdint>
#include <cstdlib> #include <cstdlib>
@ -22,10 +22,10 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
namespace quickerNES namespace quickerNES
{ {
class Nes_Cart class Cart
{ {
public: public:
Nes_Cart() = default; Cart() = default;
struct ines_header_t struct ines_header_t
{ {

View File

@ -13,19 +13,19 @@ 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 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 */ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
// Nes_Emu 0.7.0 // Emu 0.7.0
#include "Nes_Cpu.hpp" #include "cpu.hpp"
#include "apu/apu.hpp" #include "apu/apu.hpp"
#include "mappers/mapper.hpp" #include "mappers/mapper.hpp"
#include "ppu/Nes_Ppu.hpp" #include "ppu/ppu.hpp"
#include <cstdio> #include <cstdio>
#include <string> #include <string>
namespace quickerNES namespace quickerNES
{ {
class Nes_Cart; class Cart;
#undef NES_EMU_CPU_HOOK #undef NES_EMU_CPU_HOOK
#ifndef NES_EMU_CPU_HOOK #ifndef NES_EMU_CPU_HOOK
@ -34,7 +34,7 @@ class Nes_Cart;
bool const wait_states_enabled = true; bool const wait_states_enabled = true;
bool const single_instruction_mode = false; // for debugging irq/nmi timing issues bool const single_instruction_mode = false; // for debugging irq/nmi timing issues
const int unmapped_fill = Nes_Cpu::page_wrap_opcode; const int unmapped_fill = Cpu::page_wrap_opcode;
unsigned const low_ram_size = 0x800; unsigned const low_ram_size = 0x800;
unsigned const low_ram_end = 0x2000; unsigned const low_ram_end = 0x2000;
unsigned const sram_end = 0x8000; unsigned const sram_end = 0x8000;
@ -68,12 +68,12 @@ struct cpu_state_t
}; };
static_assert(sizeof(cpu_state_t) == 8); static_assert(sizeof(cpu_state_t) == 8);
class Nes_Core : private Nes_Cpu class Core : private Cpu
{ {
typedef Nes_Cpu cpu; typedef Cpu cpu;
public: public:
Nes_Core() : ppu(this) Core() : ppu(this)
{ {
cart = NULL; cart = NULL;
impl = NULL; impl = NULL;
@ -82,7 +82,7 @@ class Nes_Core : private Nes_Cpu
memset(&joypad, 0, sizeof joypad); memset(&joypad, 0, sizeof joypad);
} }
~Nes_Core() ~Core()
{ {
close(); close();
delete impl; delete impl;
@ -100,7 +100,7 @@ class Nes_Core : private Nes_Cpu
return 0; return 0;
} }
void open(Nes_Cart const *new_cart) void open(Cart const *new_cart)
{ {
close(); close();
init(); init();
@ -109,7 +109,7 @@ class Nes_Core : private Nes_Cpu
auto mapperCode = new_cart->mapper_code(); auto mapperCode = new_cart->mapper_code();
// Getting mapper corresponding to that code // Getting mapper corresponding to that code
mapper = Nes_Mapper::getMapperFromCode(mapperCode); mapper = Mapper::getMapperFromCode(mapperCode);
// If no mapper was found, return null (error) now // If no mapper was found, return null (error) now
if (mapper == nullptr) if (mapper == nullptr)
@ -136,11 +136,11 @@ class Nes_Core : private Nes_Cpu
size += sizeof(nes_state_t); size += sizeof(nes_state_t);
size += sizeof(registers_t); size += sizeof(registers_t);
size += sizeof(ppu_state_t); size += sizeof(ppu_state_t);
size += sizeof(Nes_Apu::apu_state_t); size += sizeof(Apu::apu_state_t);
size += sizeof(joypad_state_t); size += sizeof(joypad_state_t);
size += mapper->state_size; size += mapper->state_size;
size += low_ram_size; size += low_ram_size;
size += Nes_Ppu::spr_ram_size; size += Ppu::spr_ram_size;
size_t nametable_size = 0x800; size_t nametable_size = 0x800;
if (ppu.nt_banks[3] >= &ppu.impl->nt_ram[0xC00]) nametable_size = 0x1000; if (ppu.nt_banks[3] >= &ppu.impl->nt_ram[0xC00]) nametable_size = 0x1000;
size += nametable_size; size += nametable_size;
@ -171,7 +171,7 @@ class Nes_Core : private Nes_Cpu
size += sizeof(char[4]); // APUR Block size += sizeof(char[4]); // APUR Block
size += sizeof(uint32_t); // Block Size size += sizeof(uint32_t); // Block Size
size += sizeof(Nes_Apu::apu_state_t); size += sizeof(Apu::apu_state_t);
size += sizeof(char[4]); // CTRL Block size += sizeof(char[4]); // CTRL Block
size += sizeof(uint32_t); // Block Size size += sizeof(uint32_t); // Block Size
@ -187,7 +187,7 @@ class Nes_Core : private Nes_Cpu
size += sizeof(char[4]); // SPRT Block size += sizeof(char[4]); // SPRT Block
size += sizeof(uint32_t); // Block Size size += sizeof(uint32_t); // Block Size
size += Nes_Ppu::spr_ram_size; size += Ppu::spr_ram_size;
size += sizeof(char[4]); // NTAB Block size += sizeof(char[4]); // NTAB Block
size += sizeof(uint32_t); // Block Size size += sizeof(uint32_t); // Block Size
@ -271,9 +271,9 @@ class Nes_Core : private Nes_Cpu
pos += blockSize; pos += blockSize;
headerCode = "APUR"; // APUR Block headerCode = "APUR"; // APUR Block
Nes_Apu::apu_state_t apuState; Apu::apu_state_t apuState;
impl->apu.save_state(&apuState); impl->apu.save_state(&apuState);
blockSize = sizeof(Nes_Apu::apu_state_t); blockSize = sizeof(Apu::apu_state_t);
memcpy(&buffer[pos], headerCode.data(), headerSize); memcpy(&buffer[pos], headerCode.data(), headerSize);
pos += headerSize; pos += headerSize;
memcpy(&buffer[pos], &blockSize, headerSize); memcpy(&buffer[pos], &blockSize, headerSize);
@ -312,7 +312,7 @@ class Nes_Core : private Nes_Cpu
pos += blockSize; pos += blockSize;
headerCode = "SPRT"; // SPRT Block headerCode = "SPRT"; // SPRT Block
blockSize = Nes_Ppu::spr_ram_size; blockSize = Ppu::spr_ram_size;
dataSource = (void *)ppu.spr_ram; dataSource = (void *)ppu.spr_ram;
memcpy(&buffer[pos], headerCode.data(), headerSize); memcpy(&buffer[pos], headerCode.data(), headerSize);
pos += headerSize; pos += headerSize;
@ -415,8 +415,8 @@ class Nes_Core : private Nes_Cpu
pos += blockSize; pos += blockSize;
// APUR Block // APUR Block
Nes_Apu::apu_state_t apuState; Apu::apu_state_t apuState;
blockSize = sizeof(Nes_Apu::apu_state_t); blockSize = sizeof(Apu::apu_state_t);
pos += headerSize; pos += headerSize;
pos += headerSize; pos += headerSize;
memcpy(&apuState, &buffer[pos], blockSize); memcpy(&apuState, &buffer[pos], blockSize);
@ -448,7 +448,7 @@ class Nes_Core : private Nes_Cpu
pos += blockSize; pos += blockSize;
// SPRT Block // SPRT Block
blockSize = Nes_Ppu::spr_ram_size; blockSize = Ppu::spr_ram_size;
pos += headerSize; pos += headerSize;
pos += headerSize; pos += headerSize;
memcpy((void *)ppu.spr_ram, &buffer[pos], blockSize); memcpy((void *)ppu.spr_ram, &buffer[pos], blockSize);
@ -588,7 +588,7 @@ class Nes_Core : private Nes_Cpu
public: public:
private: private:
friend class Nes_Emu; friend class Emu;
struct impl_t struct impl_t
{ {
@ -597,11 +597,11 @@ class Nes_Core : private Nes_Cpu
sram_size = 0x2000 sram_size = 0x2000
}; };
uint8_t sram[sram_size]; uint8_t sram[sram_size];
Nes_Apu apu; Apu apu;
// extra byte allows CPU to always read operand of instruction, which // extra byte allows CPU to always read operand of instruction, which
// might go past end of data // might go past end of data
uint8_t unmapped_page[Nes_Cpu::page_size + 1]; uint8_t unmapped_page[Cpu::page_size + 1];
}; };
impl_t *impl; // keep large arrays separate impl_t *impl; // keep large arrays separate
unsigned long error_count; unsigned long error_count;
@ -609,15 +609,15 @@ class Nes_Core : private Nes_Cpu
public: public:
unsigned long current_joypad[2]; unsigned long current_joypad[2];
Nes_Cart const *cart; Cart const *cart;
Nes_Mapper *mapper; Mapper *mapper;
nes_state_t nes; nes_state_t nes;
Nes_Ppu ppu; Ppu ppu;
private: private:
// noncopyable // noncopyable
Nes_Core(const Nes_Core &); Core(const Core &);
Nes_Core &operator=(const Nes_Core &); Core &operator=(const Core &);
// Timing // Timing
nes_time_t ppu_2002_time; nes_time_t ppu_2002_time;
@ -672,7 +672,7 @@ class Nes_Core : private Nes_Cpu
return result & 1; return result & 1;
} }
if (addr == Nes_Apu::status_addr) if (addr == Apu::status_addr)
return impl->apu.read_status(clock()); return impl->apu.read_status(clock());
return addr >> 8; // simulate open bus return addr >> 8; // simulate open bus
@ -719,7 +719,7 @@ class Nes_Core : private Nes_Cpu
static inline int read_dmc(void *data, nes_addr_t addr) static inline int read_dmc(void *data, nes_addr_t addr)
{ {
Nes_Core *emu = (Nes_Core *)data; Core *emu = (Core *)data;
int result = *emu->cpu::get_code(addr); int result = *emu->cpu::get_code(addr);
if (wait_states_enabled) if (wait_states_enabled)
emu->cpu_adjust_time(4); emu->cpu_adjust_time(4);
@ -728,7 +728,7 @@ class Nes_Core : private Nes_Cpu
static inline void apu_irq_changed(void *emu) static inline void apu_irq_changed(void *emu)
{ {
((Nes_Core *)emu)->irq_changed(); ((Core *)emu)->irq_changed();
} }
// CPU // CPU
@ -740,7 +740,7 @@ class Nes_Core : private Nes_Cpu
nes_time_t emulate_frame_() nes_time_t emulate_frame_()
{ {
Nes_Cpu::result_t last_result = cpu::result_cycles; Cpu::result_t last_result = cpu::result_cycles;
int extra_instructions = 0; int extra_instructions = 0;
while (true) while (true)
{ {
@ -852,12 +852,12 @@ class Nes_Core : private Nes_Cpu
public: public:
private: private:
friend class Nes_Ppu; friend class Ppu;
void set_ppu_2002_time(nes_time_t t) { ppu_2002_time = t - 1 - cpu_time_offset; } void set_ppu_2002_time(nes_time_t t) { ppu_2002_time = t - 1 - cpu_time_offset; }
public: public:
private: private:
friend class Nes_Mapper; friend class Mapper;
void enable_prg_6000() void enable_prg_6000()
{ {
@ -903,7 +903,7 @@ class Nes_Core : private Nes_Cpu
public: public:
private: private:
friend class Nes_Cpu; friend class Cpu;
int cpu_read_ppu(nes_addr_t, nes_time_t); int cpu_read_ppu(nes_addr_t, nes_time_t);
int cpu_read(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); void cpu_write(nes_addr_t, int data, nes_time_t);
@ -914,7 +914,7 @@ class Nes_Core : private Nes_Cpu
unsigned char data_writer_mapped[page_count + 1]; unsigned char data_writer_mapped[page_count + 1];
}; };
inline int Nes_Core::cpu_read(nes_addr_t addr, nes_time_t time) inline int Core::cpu_read(nes_addr_t addr, nes_time_t time)
{ {
{ {
int result = cpu::low_mem[addr & 0x7FF]; int result = cpu::low_mem[addr & 0x7FF];
@ -952,7 +952,7 @@ inline int Nes_Core::cpu_read(nes_addr_t addr, nes_time_t time)
return addr >> 8; // simulate open bus return addr >> 8; // simulate open bus
} }
inline int Nes_Core::cpu_read_ppu(nes_addr_t addr, nes_time_t time) inline int Core::cpu_read_ppu(nes_addr_t addr, nes_time_t time)
{ {
// LOG_FREQ( "cpu_read_ppu", 16, addr >> 12 ); // LOG_FREQ( "cpu_read_ppu", 16, addr >> 12 );
@ -976,14 +976,14 @@ inline int Nes_Core::cpu_read_ppu(nes_addr_t addr, nes_time_t time)
return result; return result;
} }
inline void Nes_Core::cpu_write_2007(int data) inline void Core::cpu_write_2007(int data)
{ {
// ppu.write_2007() is inlined // ppu.write_2007() is inlined
if (ppu.write_2007(data) & Nes_Ppu::vaddr_clock_mask) if (ppu.write_2007(data) & Ppu::vaddr_clock_mask)
mapper->a12_clocked(); mapper->a12_clocked();
} }
inline void Nes_Core::cpu_write(nes_addr_t addr, int data, nes_time_t time) inline void Core::cpu_write(nes_addr_t addr, int data, nes_time_t time)
{ {
// LOG_FREQ( "cpu_write", 16, addr >> 12 ); // LOG_FREQ( "cpu_write", 16, addr >> 12 );
@ -1027,14 +1027,14 @@ inline void Nes_Core::cpu_write(nes_addr_t addr, int data, nes_time_t time)
} }
#define NES_CPU_READ_PPU(cpu, addr, time) \ #define NES_CPU_READ_PPU(cpu, addr, time) \
static_cast<Nes_Core &>(*cpu).cpu_read_ppu(addr, time) static_cast<Core &>(*cpu).cpu_read_ppu(addr, time)
#define NES_CPU_READ(cpu, addr, time) \ #define NES_CPU_READ(cpu, addr, time) \
static_cast<Nes_Core &>(*cpu).cpu_read(addr, time) static_cast<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); \ static_cast<Core &>(*cpu).cpu_write(addr, data, time); \
} }
#define NES_CPU_WRITE(cpu, addr, data, time) \ #define NES_CPU_WRITE(cpu, addr, data, time) \
@ -1042,9 +1042,9 @@ inline void Nes_Core::cpu_write(nes_addr_t addr, int data, nes_time_t time)
if (addr < 0x800) \ if (addr < 0x800) \
cpu->low_mem[addr] = data; \ cpu->low_mem[addr] = data; \
else if (addr == 0x2007) \ else if (addr == 0x2007) \
static_cast<Nes_Core &>(*cpu).cpu_write_2007(data); \ static_cast<Core &>(*cpu).cpu_write_2007(data); \
else \ else \
static_cast<Nes_Core &>(*cpu).cpu_write(addr, data, time); \ static_cast<Core &>(*cpu).cpu_write(addr, data, time); \
} }
} // namespace quickNES } // namespace quickNES

View File

@ -1,10 +1,10 @@
// Nes_Emu 0.7.0. http://www.slack.net/~ant/nes-emu/ // Emu 0.7.0. http://www.slack.net/~ant/nes-emu/
#include <cstring> #include <cstring>
#include <climits> #include <climits>
#include <cstdio> #include <cstdio>
#include "Nes_Cpu.hpp" #include "cpu.hpp"
#include "Nes_Core.hpp" #include "core.hpp"
/** /**
* Optimizations by Sergio Martin (eien86) 2023-2024 * Optimizations by Sergio Martin (eien86) 2023-2024
@ -130,7 +130,7 @@ imm##op: \
} }
void Nes_Cpu::reset( void const* unmapped_page ) void Cpu::reset( void const* unmapped_page )
{ {
r.status = 0; r.status = 0;
r.sp = 0; r.sp = 0;
@ -190,12 +190,12 @@ void Nes_Cpu::reset( void const* unmapped_page )
nz |= ~in & st_z; \ nz |= ~in & st_z; \
} while ( 0 ) } while ( 0 )
inline int32_t Nes_Cpu::read( nes_addr_t addr ) inline int32_t Cpu::read( nes_addr_t addr )
{ {
return READ( addr ); return READ( addr );
} }
inline void Nes_Cpu::write( nes_addr_t addr, int value ) inline void Cpu::write( nes_addr_t addr, int value )
{ {
WRITE( addr, value ); WRITE( addr, value );
} }
@ -204,7 +204,7 @@ inline void Nes_Cpu::write( nes_addr_t addr, int value )
extern uint8_t clock_table [256]; extern uint8_t clock_table [256];
__attribute__((optimize("align-functions=" _PAGE_SIZE))) __attribute__((optimize("align-functions=" _PAGE_SIZE)))
Nes_Cpu::result_t Nes_Cpu::run ( nes_time_t end ) Cpu::result_t Cpu::run ( nes_time_t end )
{ {
set_end_time_( end ); set_end_time_( end );
clock_count = 0; clock_count = 0;

View File

@ -1,7 +1,7 @@
#pragma once #pragma once
// NES 6502 CPU emulator // NES 6502 CPU emulator
// Nes_Emu 0.7.0 // Emu 0.7.0
#include <cstdint> #include <cstdint>
@ -11,7 +11,7 @@ namespace quickerNES
typedef long nes_time_t; // clock cycle count typedef long nes_time_t; // clock cycle count
typedef unsigned nes_addr_t; // 16-bit address typedef unsigned nes_addr_t; // 16-bit address
class Nes_Cpu class Cpu
{ {
public: public:
// NES 6502 registers. *Not* kept updated during a call to run(). // NES 6502 registers. *Not* kept updated during a call to run().

View File

@ -1,8 +1,8 @@
// Nes_Emu 0.7.0. http://www.slack.net/~ant/ // Emu 0.7.0. http://www.slack.net/~ant/
#include <cstring> #include <cstring>
#include "mappers/mapper.hpp" #include "mappers/mapper.hpp"
#include "Nes_Emu.hpp" #include "emu.hpp"
/* Copyright (C) 2004-2006 Shay Green. This module is free software; you /* 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 can redistribute it and/or modify it under the terms of the GNU Lesser
@ -20,17 +20,17 @@ namespace quickerNES
int const sound_fade_size = 384; int const sound_fade_size = 384;
Nes_Emu::equalizer_t const Nes_Emu::nes_eq = { -1.0, 80 }; Emu::equalizer_t const Emu::nes_eq = { -1.0, 80 };
Nes_Emu::equalizer_t const Nes_Emu::famicom_eq = { -15.0, 80 }; Emu::equalizer_t const Emu::famicom_eq = { -15.0, 80 };
Nes_Emu::equalizer_t const Nes_Emu::tv_eq = { -12.0, 180 }; Emu::equalizer_t const Emu::tv_eq = { -12.0, 180 };
Nes_Emu::equalizer_t const Nes_Emu::flat_eq = { 0.0, 1 }; Emu::equalizer_t const Emu::flat_eq = { 0.0, 1 };
Nes_Emu::equalizer_t const Nes_Emu::crisp_eq = { 5.0, 1 }; Emu::equalizer_t const Emu::crisp_eq = { 5.0, 1 };
Nes_Emu::equalizer_t const Nes_Emu::tinny_eq = { -47.0, 2000 }; Emu::equalizer_t const Emu::tinny_eq = { -47.0, 2000 };
Nes_Emu::Nes_Emu() Emu::Emu()
{ {
frame_ = &single_frame; frame_ = &single_frame;
buffer_height_ = Nes_Ppu::buffer_height + 2; buffer_height_ = Ppu::buffer_height + 2;
default_sound_buf = NULL; default_sound_buf = NULL;
sound_buf = &silent_buffer; sound_buf = &silent_buffer;
sound_buf_changed_count = 0; sound_buf_changed_count = 0;
@ -49,17 +49,17 @@ Nes_Emu::Nes_Emu()
extra_sound_buf_changed_count = 0; extra_sound_buf_changed_count = 0;
} }
Nes_Emu::~Nes_Emu() Emu::~Emu()
{ {
delete default_sound_buf; delete default_sound_buf;
} }
const char * Nes_Emu::init_() const char * Emu::init_()
{ {
return emu.init(); return emu.init();
} }
inline const char * Nes_Emu::auto_init() inline const char * Emu::auto_init()
{ {
if ( !init_called ) if ( !init_called )
{ {
@ -70,40 +70,40 @@ inline const char * Nes_Emu::auto_init()
} }
inline void Nes_Emu::clear_sound_buf() inline void Emu::clear_sound_buf()
{ {
fade_sound_out = false; fade_sound_out = false;
fade_sound_in = true; fade_sound_in = true;
sound_buf->clear(); sound_buf->clear();
} }
void Nes_Emu::set_cart( Nes_Cart const* new_cart ) void Emu::set_cart( Cart const* new_cart )
{ {
auto_init(); auto_init();
emu.open( new_cart ); emu.open( new_cart );
channel_count_ = Nes_Apu::osc_count + emu.mapper->channel_count(); channel_count_ = Apu::osc_count + emu.mapper->channel_count();
sound_buf->set_channel_count( channel_count() ); sound_buf->set_channel_count( channel_count() );
set_equalizer( equalizer_ ); set_equalizer( equalizer_ );
enable_sound( true ); enable_sound( true );
reset(); reset();
} }
void Nes_Emu::reset( bool full_reset, bool erase_battery_ram ) void Emu::reset( bool full_reset, bool erase_battery_ram )
{ {
clear_sound_buf(); clear_sound_buf();
set_timestamp( 0 ); set_timestamp( 0 );
emu.reset( full_reset, erase_battery_ram ); emu.reset( full_reset, erase_battery_ram );
} }
void Nes_Emu::set_palette_range( int begin, int end ) void Emu::set_palette_range( int begin, int end )
{ {
// round up to alignment // round up to alignment
emu.ppu.palette_begin = (begin + palette_alignment - 1) & ~(palette_alignment - 1); emu.ppu.palette_begin = (begin + palette_alignment - 1) & ~(palette_alignment - 1);
host_palette_size = end - emu.ppu.palette_begin; host_palette_size = end - emu.ppu.palette_begin;
} }
const char * Nes_Emu::emulate_skip_frame( int joypad1, int joypad2 ) const char * Emu::emulate_skip_frame( int joypad1, int joypad2 )
{ {
char *old_host_pixels = host_pixels; char *old_host_pixels = host_pixels;
host_pixels = NULL; host_pixels = NULL;
@ -112,7 +112,7 @@ const char * Nes_Emu::emulate_skip_frame( int joypad1, int joypad2 )
return 0; return 0;
} }
const char * Nes_Emu::emulate_frame( int joypad1, int joypad2 ) const char * Emu::emulate_frame( int joypad1, int joypad2 )
{ {
emu.ppu.host_pixels = NULL; emu.ppu.host_pixels = NULL;
@ -166,41 +166,41 @@ const char * Nes_Emu::emulate_frame( int joypad1, int joypad2 )
// Extras // Extras
void Nes_Emu::load_ines( const uint8_t* buffer ) void Emu::load_ines( const uint8_t* buffer )
{ {
private_cart.load_ines( buffer ); private_cart.load_ines( buffer );
set_cart( &private_cart ); set_cart( &private_cart );
} }
void Nes_Emu::write_chr( void const* p, long count, long offset ) void Emu::write_chr( void const* p, long count, long offset )
{ {
long end = offset + count; long end = offset + count;
memcpy( (uint8_t*) chr_mem() + offset, p, count ); memcpy( (uint8_t*) chr_mem() + offset, p, count );
emu.ppu.rebuild_chr( offset, end ); emu.ppu.rebuild_chr( offset, end );
} }
const char * Nes_Emu::set_sample_rate( long rate, class Nes_Buffer* buf ) const char * Emu::set_sample_rate( long rate, class Buffer* buf )
{ {
extern Multi_Buffer* set_apu( class Nes_Buffer*, Nes_Apu* ); extern Multi_Buffer* set_apu( class Buffer*, Apu* );
auto_init(); auto_init();
return set_sample_rate( rate, set_apu( buf, &emu.impl->apu ) ); return set_sample_rate( rate, set_apu( buf, &emu.impl->apu ) );
} }
const char * Nes_Emu::set_sample_rate( long rate, class Nes_Effects_Buffer* buf ) const char * Emu::set_sample_rate( long rate, class Nes_Effects_Buffer* buf )
{ {
extern Multi_Buffer* set_apu( class Nes_Effects_Buffer*, Nes_Apu* ); extern Multi_Buffer* set_apu( class Nes_Effects_Buffer*, Apu* );
auto_init(); auto_init();
return set_sample_rate( rate, set_apu( buf, &emu.impl->apu ) ); return set_sample_rate( rate, set_apu( buf, &emu.impl->apu ) );
} }
// Sound // Sound
void Nes_Emu::set_frame_rate( double rate ) void Emu::set_frame_rate( double rate )
{ {
sound_buf->clock_rate( (long) (1789773 / 60.0 * rate) ); sound_buf->clock_rate( (long) (1789773 / 60.0 * rate) );
} }
const char * Nes_Emu::set_sample_rate( long rate, Multi_Buffer* new_buf ) const char * Emu::set_sample_rate( long rate, Multi_Buffer* new_buf )
{ {
auto_init(); auto_init();
emu.impl->apu.volume( 1.0 ); // cancel any previous non-linearity emu.impl->apu.volume( 1.0 ); // cancel any previous non-linearity
@ -216,13 +216,13 @@ const char * Nes_Emu::set_sample_rate( long rate, Multi_Buffer* new_buf )
return 0; return 0;
} }
const char * Nes_Emu::set_sample_rate( long rate ) const char * Emu::set_sample_rate( long rate )
{ {
if ( !default_sound_buf ) default_sound_buf = new Mono_Buffer; if ( !default_sound_buf ) default_sound_buf = new Mono_Buffer;
return set_sample_rate( rate, default_sound_buf ); return set_sample_rate( rate, default_sound_buf );
} }
void Nes_Emu::set_equalizer( equalizer_t const& eq ) void Emu::set_equalizer( equalizer_t const& eq )
{ {
equalizer_ = eq; equalizer_ = eq;
if ( cart() ) if ( cart() )
@ -234,14 +234,14 @@ void Nes_Emu::set_equalizer( equalizer_t const& eq )
} }
} }
void Nes_Emu::enable_sound( bool enabled ) void Emu::enable_sound( bool enabled )
{ {
if ( enabled ) if ( enabled )
{ {
for ( int i = channel_count(); i-- > 0; ) for ( int i = channel_count(); i-- > 0; )
{ {
Blip_Buffer* buf = sound_buf->channel( i ).center; Blip_Buffer* buf = sound_buf->channel( i ).center;
int mapper_index = i - Nes_Apu::osc_count; int mapper_index = i - Apu::osc_count;
if ( mapper_index < 0 ) if ( mapper_index < 0 )
emu.impl->apu.osc_output( i, buf ); emu.impl->apu.osc_output( i, buf );
else else
@ -251,12 +251,12 @@ void Nes_Emu::enable_sound( bool enabled )
else else
{ {
emu.impl->apu.output( NULL ); emu.impl->apu.output( NULL );
for ( int i = channel_count() - Nes_Apu::osc_count; i-- > 0; ) for ( int i = channel_count() - Apu::osc_count; i-- > 0; )
emu.mapper->set_channel_buf( i, NULL ); emu.mapper->set_channel_buf( i, NULL );
} }
} }
void Nes_Emu::fade_samples( blip_sample_t* p, int size, int step ) void Emu::fade_samples( blip_sample_t* p, int size, int step )
{ {
if ( size >= sound_fade_size ) if ( size >= sound_fade_size )
{ {
@ -276,7 +276,7 @@ void Nes_Emu::fade_samples( blip_sample_t* p, int size, int step )
} }
} }
long Nes_Emu::read_samples( short* out, long out_size ) long Emu::read_samples( short* out, long out_size )
{ {
long count = sound_buf->read_samples( out, out_size ); long count = sound_buf->read_samples( out, out_size );
if ( fade_sound_in ) if ( fade_sound_in )
@ -296,7 +296,7 @@ long Nes_Emu::read_samples( short* out, long out_size )
return count; return count;
} }
Nes_Emu::rgb_t const Nes_Emu::nes_colors [color_table_size] = Emu::rgb_t const Emu::nes_colors [color_table_size] =
{ {
// generated with nes_ntsc default settings // generated with nes_ntsc default settings
{102,102,102},{ 0, 42,136},{ 20, 18,168},{ 59, 0,164}, {102,102,102},{ 0, 42,136},{ 20, 18,168},{ 59, 0,164},
@ -430,14 +430,14 @@ Nes_Emu::rgb_t const Nes_Emu::nes_colors [color_table_size] =
{136,190,197},{184,184,184},{ 0, 0, 0},{ 0, 0, 0} {136,190,197},{184,184,184},{ 0, 0, 0},{ 0, 0, 0}
}; };
void Nes_Emu::SaveAudioBufferState() void Emu::SaveAudioBufferState()
{ {
extra_fade_sound_in = fade_sound_in; extra_fade_sound_in = fade_sound_in;
extra_fade_sound_out = fade_sound_out; extra_fade_sound_out = fade_sound_out;
extra_sound_buf_changed_count = sound_buf_changed_count; extra_sound_buf_changed_count = sound_buf_changed_count;
sound_buf->SaveAudioBufferState(); sound_buf->SaveAudioBufferState();
} }
void Nes_Emu::RestoreAudioBufferState() void Emu::RestoreAudioBufferState()
{ {
fade_sound_in = extra_fade_sound_in; fade_sound_in = extra_fade_sound_in;
fade_sound_out = extra_fade_sound_out; fade_sound_out = extra_fade_sound_out;

View File

@ -2,22 +2,22 @@
// NES video game console emulator with snapshot support // NES video game console emulator with snapshot support
// Nes_Emu 0.7.0 // Emu 0.7.0
#include "Nes_Cart.hpp" #include "cart.hpp"
#include "Nes_Core.hpp" #include "core.hpp"
#include "apu/Multi_Buffer.hpp" #include "apu/Multi_Buffer.hpp"
namespace quickerNES namespace quickerNES
{ {
class Nes_State; class State;
class Nes_Emu class Emu
{ {
public: public:
Nes_Emu(); Emu();
virtual ~Nes_Emu(); virtual ~Emu();
// Basic setup // Basic setup
@ -30,7 +30,7 @@ class Nes_Emu
// Size and depth of graphics buffer required for rendering. Note that this // Size and depth of graphics buffer required for rendering. Note that this
// is larger than the actual image, with a temporary area around the edge // is larger than the actual image, with a temporary area around the edge
// that gets filled with junk. // that gets filled with junk.
static const uint16_t buffer_width = Nes_Ppu::buffer_width; static const uint16_t buffer_width = Ppu::buffer_width;
uint16_t buffer_height() const { return buffer_height_; } uint16_t buffer_height() const { return buffer_height_; }
static const uint8_t bits_per_pixel = 8; static const uint8_t bits_per_pixel = 8;
@ -90,10 +90,10 @@ class Nes_Emu
// Use already-loaded cartridge. Retains pointer, so it must be kept around until // Use already-loaded cartridge. Retains pointer, so it must be kept around until
// closed. A cartridge can be shared among multiple emulators. After opening, // closed. A cartridge can be shared among multiple emulators. After opening,
// cartridge's CHR data shouldn't be modified since a copy is cached internally. // cartridge's CHR data shouldn't be modified since a copy is cached internally.
void set_cart(Nes_Cart const *); void set_cart(Cart const *);
// Pointer to current cartridge, or NULL if none is loaded // Pointer to current cartridge, or NULL if none is loaded
Nes_Cart const *cart() const { return emu.cart; } Cart const *cart() const { return emu.cart; }
// Emulate powering NES off and then back on. If full_reset is false, emulates // Emulate powering NES off and then back on. If full_reset is false, emulates
// pressing the reset button only, which doesn't affect memory, otherwise // pressing the reset button only, which doesn't affect memory, otherwise
@ -108,7 +108,7 @@ class Nes_Emu
// Sound // Sound
// Set sample rate and use a custom sound buffer instead of the default // Set sample rate and use a custom sound buffer instead of the default
// mono buffer, i.e. Nes_Buffer, Effects_Buffer, etc.. // mono buffer, i.e. Buffer, Effects_Buffer, etc..
const char *set_sample_rate(long rate, Multi_Buffer *); const char *set_sample_rate(long rate, Multi_Buffer *);
// Adjust effective frame rate by changing how many samples are generated each frame. // Adjust effective frame rate by changing how many samples are generated each frame.
@ -219,7 +219,7 @@ class Nes_Emu
// End of public interface // End of public interface
public: public:
const char *set_sample_rate(long rate, class Nes_Buffer *); const char *set_sample_rate(long rate, class Buffer *);
const char *set_sample_rate(long rate, class Nes_Effects_Buffer *); const char *set_sample_rate(long rate, class Nes_Effects_Buffer *);
void irq_changed() { emu.irq_changed(); } void irq_changed() { emu.irq_changed(); }
@ -230,14 +230,14 @@ class Nes_Emu
bool fade_sound_out; bool fade_sound_out;
virtual const char *init_(); virtual const char *init_();
virtual void loading_state(Nes_State const &) {} virtual void loading_state(State const &) {}
long timestamp() const { return emu.nes.frame_count; } long timestamp() const { return emu.nes.frame_count; }
void set_timestamp(long t) { emu.nes.frame_count = t; } void set_timestamp(long t) { emu.nes.frame_count = t; }
private: private:
// noncopyable // noncopyable
Nes_Emu(const Nes_Emu &); Emu(const Emu &);
Nes_Emu &operator=(const Nes_Emu &); Emu &operator=(const Emu &);
// sound // sound
Multi_Buffer *default_sound_buf; Multi_Buffer *default_sound_buf;
@ -254,8 +254,8 @@ class Nes_Emu
char *host_pixels; char *host_pixels;
int host_palette_size; int host_palette_size;
frame_t single_frame; frame_t single_frame;
Nes_Cart private_cart; Cart private_cart;
Nes_Core emu; // large; keep at end Core emu; // large; keep at end
bool init_called; bool init_called;
const char *auto_init(); const char *auto_init();
@ -269,18 +269,18 @@ class Nes_Emu
void RestoreAudioBufferState(); void RestoreAudioBufferState();
}; };
inline void Nes_Emu::set_pixels(void *p, long n) inline void Emu::set_pixels(void *p, long n)
{ {
host_pixels = (char *)p + n; host_pixels = (char *)p + n;
emu.ppu.host_row_bytes = n; emu.ppu.host_row_bytes = n;
} }
inline uint8_t const *Nes_Emu::chr_mem() inline uint8_t const *Emu::chr_mem()
{ {
return cart()->chr_size() ? (uint8_t *)cart()->chr() : emu.ppu.impl->chr_ram; return cart()->chr_size() ? (uint8_t *)cart()->chr() : emu.ppu.impl->chr_ram;
} }
inline long Nes_Emu::chr_size() const inline long Emu::chr_size() const
{ {
return cart()->chr_size() ? cart()->chr_size() : emu.ppu.chr_addr_size; return cart()->chr_size() ? cart()->chr_size() : emu.ppu.chr_addr_size;
} }

View File

@ -1,8 +1,8 @@
// Nes_Emu 0.7.0. http://www.slack.net/~ant/ // Emu 0.7.0. http://www.slack.net/~ant/
#include "mappers/mapper.hpp" #include "mappers/mapper.hpp"
#include "Nes_Core.hpp" #include "core.hpp"
#include <cstring> #include <cstring>
/* Copyright (C) 2004-2006 Shay Green. This module is free software; you /* Copyright (C) 2004-2006 Shay Green. This module is free software; you
@ -79,7 +79,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
namespace quickerNES namespace quickerNES
{ {
Nes_Mapper::Nes_Mapper() Mapper::Mapper()
{ {
emu_ = NULL; emu_ = NULL;
static char c; static char c;
@ -87,13 +87,13 @@ Nes_Mapper::Nes_Mapper()
state_size = 0; state_size = 0;
} }
Nes_Mapper::~Nes_Mapper() Mapper::~Mapper()
{ {
} }
// Sets mirroring, maps first 8K CHR in, first and last 16K of PRG, // Sets mirroring, maps first 8K CHR in, first and last 16K of PRG,
// intercepts writes to upper half of memory, and clears registered state. // intercepts writes to upper half of memory, and clears registered state.
void Nes_Mapper::default_reset_state() void Mapper::default_reset_state()
{ {
int mirroring = cart_->mirroring(); int mirroring = cart_->mirroring();
if (mirroring & 8) if (mirroring & 8)
@ -113,7 +113,7 @@ void Nes_Mapper::default_reset_state()
memset(state, 0, state_size); memset(state, 0, state_size);
} }
void Nes_Mapper::reset() void Mapper::reset()
{ {
default_reset_state(); default_reset_state();
reset_state(); reset_state();
@ -134,19 +134,19 @@ int mapper_state_t::read(void *p, unsigned long s) const
return s; return s;
} }
void Nes_Mapper::save_state(mapper_state_t &out) void Mapper::save_state(mapper_state_t &out)
{ {
out.write(state, state_size); out.write(state, state_size);
} }
void Nes_Mapper::load_state(mapper_state_t const &in) void Mapper::load_state(mapper_state_t const &in)
{ {
default_reset_state(); default_reset_state();
read_state(in); read_state(in);
apply_mapping(); apply_mapping();
} }
void Nes_Mapper::read_state(mapper_state_t const &in) void Mapper::read_state(mapper_state_t const &in)
{ {
memset(state, 0, state_size); memset(state, 0, state_size);
in.read(state, state_size); in.read(state, state_size);
@ -155,29 +155,29 @@ void Nes_Mapper::read_state(mapper_state_t const &in)
// Timing // Timing
void Nes_Mapper::irq_changed() { emu_->irq_changed(); } void Mapper::irq_changed() { emu_->irq_changed(); }
nes_time_t Nes_Mapper::next_irq(nes_time_t) { return no_irq; } nes_time_t Mapper::next_irq(nes_time_t) { return no_irq; }
void Nes_Mapper::a12_clocked() {} void Mapper::a12_clocked() {}
void Nes_Mapper::run_until(nes_time_t) {} void Mapper::run_until(nes_time_t) {}
void Nes_Mapper::end_frame(nes_time_t) {} void Mapper::end_frame(nes_time_t) {}
bool Nes_Mapper::ppu_enabled() const { return emu().ppu.w2001 & 0x08; } bool Mapper::ppu_enabled() const { return emu().ppu.w2001 & 0x08; }
// Sound // Sound
int Nes_Mapper::channel_count() const { return 0; } int Mapper::channel_count() const { return 0; }
void Nes_Mapper::set_channel_buf(int, Blip_Buffer *) {} void Mapper::set_channel_buf(int, Blip_Buffer *) {}
void Nes_Mapper::set_treble(blip_eq_t const &) {} void Mapper::set_treble(blip_eq_t const &) {}
// Memory mapping // Memory mapping
void Nes_Mapper::set_prg_bank(nes_addr_t addr, bank_size_t bs, int bank) void Mapper::set_prg_bank(nes_addr_t addr, bank_size_t bs, int bank)
{ {
int bank_size = 1 << bs; int bank_size = 1 << bs;
@ -194,42 +194,42 @@ void Nes_Mapper::set_prg_bank(nes_addr_t addr, bank_size_t bs, int bank)
emu().enable_prg_6000(); emu().enable_prg_6000();
} }
void Nes_Mapper::set_chr_bank(nes_addr_t addr, bank_size_t bs, int bank) void Mapper::set_chr_bank(nes_addr_t addr, bank_size_t bs, int bank)
{ {
emu().ppu.render_until(emu().clock()); emu().ppu.render_until(emu().clock());
emu().ppu.set_chr_bank(addr, 1 << bs, bank << bs); emu().ppu.set_chr_bank(addr, 1 << bs, bank << bs);
} }
void Nes_Mapper::set_chr_bank_ex(nes_addr_t addr, bank_size_t bs, int bank) void Mapper::set_chr_bank_ex(nes_addr_t addr, bank_size_t bs, int bank)
{ {
emu().ppu.render_until(emu().clock()); emu().ppu.render_until(emu().clock());
emu().ppu.set_chr_bank_ex(addr, 1 << bs, bank << bs); emu().ppu.set_chr_bank_ex(addr, 1 << bs, bank << bs);
} }
void Nes_Mapper::mirror_manual(int page0, int page1, int page2, int page3) void Mapper::mirror_manual(int page0, int page1, int page2, int page3)
{ {
emu().ppu.render_bg_until(emu().clock()); emu().ppu.render_bg_until(emu().clock());
emu().ppu.set_nt_banks(page0, page1, page2, page3); emu().ppu.set_nt_banks(page0, page1, page2, page3);
} }
void Nes_Mapper::intercept_reads(nes_addr_t addr, unsigned size) void Mapper::intercept_reads(nes_addr_t addr, unsigned size)
{ {
emu().add_mapper_intercept(addr, size, true, false); emu().add_mapper_intercept(addr, size, true, false);
} }
void Nes_Mapper::intercept_writes(nes_addr_t addr, unsigned size) void Mapper::intercept_writes(nes_addr_t addr, unsigned size)
{ {
emu().add_mapper_intercept(addr, size, false, true); emu().add_mapper_intercept(addr, size, false, true);
} }
void Nes_Mapper::enable_sram(bool enabled, bool read_only) void Mapper::enable_sram(bool enabled, bool read_only)
{ {
emu_->enable_sram(enabled, read_only); emu_->enable_sram(enabled, read_only);
} }
Nes_Mapper *Nes_Mapper::getMapperFromCode(const int mapperCode) Mapper *Mapper::getMapperFromCode(const int mapperCode)
{ {
Nes_Mapper *mapper = nullptr; Mapper *mapper = nullptr;
// Now checking if the detected mapper code is supported // Now checking if the detected mapper code is supported
if (mapperCode == 0) mapper = new Mapper000(); if (mapperCode == 0) mapper = new Mapper000();

View File

@ -1,18 +1,18 @@
#pragma once #pragma once
// NES mapper interface // NES mapper interface
// Nes_Emu 0.7.0 // Emu 0.7.0
#include "Nes_Cart.hpp"
#include "Nes_Cpu.hpp"
#include <climits> #include <climits>
#include "cart.hpp"
#include "cpu.hpp"
namespace quickerNES namespace quickerNES
{ {
class Blip_Buffer; class Blip_Buffer;
class blip_eq_t; class blip_eq_t;
class Nes_Core; class Core;
// Increase this (and let me know) if your mapper requires more state. This only // Increase this (and let me know) if your mapper requires more state. This only
// sets the size of the in-memory buffer; it doesn't affect the file format at all. // sets the size of the in-memory buffer; it doesn't affect the file format at all.
@ -30,10 +30,10 @@ struct mapper_state_t
int read(void *p, unsigned long s) const; int read(void *p, unsigned long s) const;
}; };
class Nes_Mapper class Mapper
{ {
public: public:
virtual ~Nes_Mapper(); virtual ~Mapper();
// Reset mapper to power-up state. // Reset mapper to power-up state.
virtual void reset(); virtual void reset();
@ -94,7 +94,7 @@ class Nes_Mapper
protected: protected:
// Services provided for derived mapper classes // Services provided for derived mapper classes
Nes_Mapper(); Mapper();
// Register state data to automatically save and load. Be sure the binary // Register state data to automatically save and load. Be sure the binary
// layout is suitable for use in a file, including any byte-order issues. // layout is suitable for use in a file, including any byte-order issues.
@ -106,12 +106,12 @@ class Nes_Mapper
// Cause CPU writes within given address range to call mapper's write() function. // Cause CPU writes within given address range to call mapper's write() function.
// Might map a larger address range, which the mapper can ignore and pass to // Might map a larger address range, which the mapper can ignore and pass to
// Nes_Mapper::write(). The range 0x8000-0xffff is always intercepted by the mapper. // Mapper::write(). The range 0x8000-0xffff is always intercepted by the mapper.
void intercept_writes(nes_addr_t addr, unsigned size); void intercept_writes(nes_addr_t addr, unsigned size);
// Cause CPU reads within given address range to call mapper's read() function. // Cause CPU reads within given address range to call mapper's read() function.
// Might map a larger address range, which the mapper can ignore and pass to // Might map a larger address range, which the mapper can ignore and pass to
// Nes_Mapper::read(). CPU opcode/operand reads and low-memory reads always // Mapper::read(). CPU opcode/operand reads and low-memory reads always
// go directly to memory and cannot be intercepted. // go directly to memory and cannot be intercepted.
void intercept_reads(nes_addr_t addr, unsigned size); void intercept_reads(nes_addr_t addr, unsigned size);
@ -152,7 +152,7 @@ class Nes_Mapper
bool ppu_enabled() const; bool ppu_enabled() const;
// Cartridge being emulated // Cartridge being emulated
Nes_Cart const &cart() const { return *cart_; } Cart const &cart() const { return *cart_; }
// Must be called when next_irq()'s return value is earlier than previous, // Must be called when next_irq()'s return value is earlier than previous,
// current CPU run can be stopped earlier. Best to call whenever time may // current CPU run can be stopped earlier. Best to call whenever time may
@ -166,7 +166,7 @@ class Nes_Mapper
int handle_bus_conflict(nes_addr_t addr, int data); int handle_bus_conflict(nes_addr_t addr, int data);
// Reference to emulator that uses this mapper. // Reference to emulator that uses this mapper.
Nes_Core &emu() const { return *emu_; } Core &emu() const { return *emu_; }
protected: protected:
// Services derived classes provide // Services derived classes provide
@ -181,8 +181,8 @@ class Nes_Mapper
// End of general interface // End of general interface
public: public:
Nes_Cart const *cart_; Cart const *cart_;
Nes_Core *emu_; Core *emu_;
// Apply current mapping state to hardware. Called after reading mapper state // Apply current mapping state to hardware. Called after reading mapper state
// from a snapshot. // from a snapshot.
@ -190,23 +190,23 @@ class Nes_Mapper
void default_reset_state(); void default_reset_state();
static Nes_Mapper *getMapperFromCode(const int mapperCode); static Mapper *getMapperFromCode(const int mapperCode);
}; };
inline int Nes_Mapper::handle_bus_conflict(nes_addr_t addr, int data) { return data; } inline int 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 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); } inline void Mapper::mirror_vert(int p) { mirror_manual(p, p ^ 1, p, p ^ 1); }
inline void Nes_Mapper::mirror_single(int p) { mirror_manual(p, p, p, p); } inline void Mapper::mirror_single(int p) { mirror_manual(p, p, p, p); }
inline void Nes_Mapper::mirror_full() { mirror_manual(0, 1, 2, 3); } inline void Mapper::mirror_full() { mirror_manual(0, 1, 2, 3); }
inline void Nes_Mapper::register_state(void *p, unsigned s) inline void Mapper::register_state(void *p, unsigned s)
{ {
state = p; state = p;
state_size = s; state_size = s;
} }
inline bool Nes_Mapper::write_intercepted(nes_time_t, nes_addr_t, int) { return false; } inline bool Mapper::write_intercepted(nes_time_t, nes_addr_t, int) { return false; }
inline int Nes_Mapper::read(nes_time_t, nes_addr_t) { return -1; } // signal to caller inline int Mapper::read(nes_time_t, nes_addr_t) { return -1; } // signal to caller
} // namespace quickNES } // namespace quickNES

View File

@ -2,7 +2,7 @@
// Common simple mappers // Common simple mappers
// Nes_Emu 0.7.0. http://www.slack.net/~ant/ // Emu 0.7.0. http://www.slack.net/~ant/
#include "mappers/mapper.hpp" #include "mappers/mapper.hpp"
@ -22,7 +22,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
namespace quickerNES namespace quickerNES
{ {
class Mapper000 : public Nes_Mapper class Mapper000 : public Mapper
{ {
public: public:
Mapper000() {} Mapper000() {}

View File

@ -1,6 +1,6 @@
#pragma once #pragma once
// Nes_Emu 0.7.0. http://www.slack.net/~ant/ // Emu 0.7.0. http://www.slack.net/~ant/
#include "mappers/mapper.hpp" #include "mappers/mapper.hpp"
#include <cstring> #include <cstring>
@ -29,7 +29,7 @@ struct mmc1_state_t
}; };
static_assert(sizeof(mmc1_state_t) == 6); static_assert(sizeof(mmc1_state_t) == 6);
class Mapper001 : public Nes_Mapper, mmc1_state_t class Mapper001 : public Mapper, mmc1_state_t
{ {
public: public:
Mapper001() Mapper001()

View File

@ -2,7 +2,7 @@
// Common simple mappers // Common simple mappers
// Nes_Emu 0.7.0. http://www.slack.net/~ant/ // Emu 0.7.0. http://www.slack.net/~ant/
#include "mappers/mapper.hpp" #include "mappers/mapper.hpp"
@ -22,7 +22,7 @@ namespace quickerNES
// UNROM // UNROM
class Mapper002 : public Nes_Mapper class Mapper002 : public Mapper
{ {
uint8_t bank; uint8_t bank;

View File

@ -2,7 +2,7 @@
// Common simple mappers // Common simple mappers
// Nes_Emu 0.7.0. http://www.slack.net/~ant/ // Emu 0.7.0. http://www.slack.net/~ant/
#include "mappers/mapper.hpp" #include "mappers/mapper.hpp"
@ -22,7 +22,7 @@ namespace quickerNES
// CNROM // CNROM
class Mapper003 : public Nes_Mapper class Mapper003 : public Mapper
{ {
uint8_t bank; uint8_t bank;

View File

@ -1,10 +1,10 @@
#pragma once #pragma once
// Nes_Emu 0.7.0. http://www.slack.net/~ant/ // Emu 0.7.0. http://www.slack.net/~ant/
#include "mappers/mapper.hpp" #include "mappers/mapper.hpp"
#include "Nes_Core.hpp" #include "core.hpp"
#include <cstring> #include <cstring>
/* Copyright (C) 2004-2006 Shay Green. This module is free software; you /* Copyright (C) 2004-2006 Shay Green. This module is free software; you
@ -24,8 +24,8 @@ namespace quickerNES
// 264 or less breaks Gargoyle's Quest II // 264 or less breaks Gargoyle's Quest II
// 267 or less breaks Magician // 267 or less breaks Magician
int const irq_fine_tune = 268; int const irq_fine_tune = 268;
nes_time_t const first_scanline = 20 * Nes_Ppu::scanline_len + irq_fine_tune; nes_time_t const first_scanline = 20 * Ppu::scanline_len + irq_fine_tune;
nes_time_t const last_scanline = first_scanline + 240 * Nes_Ppu::scanline_len; nes_time_t const last_scanline = first_scanline + 240 * Ppu::scanline_len;
// MMC3 // MMC3
@ -42,7 +42,7 @@ struct mmc3_state_t
}; };
static_assert(sizeof(mmc3_state_t) == 15); static_assert(sizeof(mmc3_state_t) == 15);
class Mapper004 : public Nes_Mapper, mmc3_state_t class Mapper004 : public Mapper, mmc3_state_t
{ {
public: public:
Mapper004() Mapper004()
@ -144,7 +144,7 @@ class Mapper004 : public Nes_Mapper, mmc3_state_t
{ {
if (bg_enabled) if (bg_enabled)
clock_counter(); clock_counter();
next_time += Nes_Ppu::scanline_len; next_time += Ppu::scanline_len;
} }
} }

View File

@ -2,9 +2,9 @@
// NES MMC5 mapper, currently only tailored for Castlevania 3 (U) // NES MMC5 mapper, currently only tailored for Castlevania 3 (U)
// Nes_Emu 0.7.0. http://www.slack.net/~ant/ // Emu 0.7.0. http://www.slack.net/~ant/
#include "Nes_Core.hpp" #include "core.hpp"
#include "mappers/mapper.hpp" #include "mappers/mapper.hpp"
#include <cstring> #include <cstring>
@ -35,7 +35,7 @@ static_assert(sizeof(mmc5_state_t) == 0x31);
// MMC5 // MMC5
class Mapper005 : public Nes_Mapper, mmc5_state_t class Mapper005 : public Mapper, mmc5_state_t
{ {
public: public:
Mapper005() Mapper005()
@ -57,7 +57,7 @@ class Mapper005 : public Nes_Mapper, mmc5_state_t
virtual void read_state(mapper_state_t const &in) virtual void read_state(mapper_state_t const &in)
{ {
Nes_Mapper::read_state(in); Mapper::read_state(in);
irq_time = no_irq; irq_time = no_irq;
} }

View File

@ -2,7 +2,7 @@
// Common simple mappers // Common simple mappers
// Nes_Emu 0.7.0. http://www.slack.net/~ant/ // Emu 0.7.0. http://www.slack.net/~ant/
#include "mappers/mapper.hpp" #include "mappers/mapper.hpp"
@ -22,7 +22,7 @@ namespace quickerNES
// AOROM // AOROM
class Mapper007 : public Nes_Mapper class Mapper007 : public Mapper
{ {
uint8_t bank; uint8_t bank;

View File

@ -8,7 +8,7 @@ namespace quickerNES
// MMC2 // MMC2
class Mapper009 : public Nes_Mapper class Mapper009 : public Mapper
{ {
uint8_t regs[6]; // A,B,C,D,E,F uint8_t regs[6]; // A,B,C,D,E,F

View File

@ -7,7 +7,7 @@ namespace quickerNES
// MMC4 // MMC4
class Mapper010 : public Nes_Mapper class Mapper010 : public Mapper
{ {
uint8_t regs[6]; // A,B,C,D,E,F uint8_t regs[6]; // A,B,C,D,E,F

View File

@ -2,7 +2,7 @@
// Optional less-common simple mappers // Optional less-common simple mappers
// Nes_Emu 0.7.0. http://www.slack.net/~ant/ // Emu 0.7.0. http://www.slack.net/~ant/
#include "mappers/mapper.hpp" #include "mappers/mapper.hpp"
@ -22,7 +22,7 @@ namespace quickerNES
// Color Dreams // Color Dreams
class Mapper011 : public Nes_Mapper class Mapper011 : public Mapper
{ {
uint8_t bank; uint8_t bank;

View File

@ -32,7 +32,7 @@ static_assert(sizeof(Mapper015_state_t) == 5);
// K-1029, K-1030P // K-1029, K-1030P
class Mapper015 : public Nes_Mapper, Mapper015_state_t class Mapper015 : public Mapper, Mapper015_state_t
{ {
public: public:
Mapper015() Mapper015()

View File

@ -2,7 +2,7 @@
// Namco 106 mapper // Namco 106 mapper
// Nes_Emu 0.7.0. http://www.slack.net/~ant/ // Emu 0.7.0. http://www.slack.net/~ant/
#include "apu/namco/apu.hpp" #include "apu/namco/apu.hpp"
#include "mappers/mapper.hpp" #include "mappers/mapper.hpp"
@ -35,7 +35,7 @@ static_assert(sizeof(namco106_state_t) == 20 + sizeof(namco_state_t));
// Namco106 // Namco106
class Mapper019 : public Nes_Mapper, namco106_state_t class Mapper019 : public Mapper, namco106_state_t
{ {
public: public:
Mapper019() Mapper019()
@ -128,7 +128,7 @@ class Mapper019 : public Nes_Mapper, namco106_state_t
return irq_ctr >> 8; return irq_ctr >> 8;
} }
return Nes_Mapper::read(time, addr); return Mapper::read(time, addr);
} }
virtual bool write_intercepted(nes_time_t time, nes_addr_t addr, int data) virtual bool write_intercepted(nes_time_t time, nes_addr_t addr, int data)
@ -186,16 +186,16 @@ class Mapper019 : public Nes_Mapper, namco106_state_t
void save_state(mapper_state_t &out) void save_state(mapper_state_t &out)
{ {
sound.save_state(&sound_state); sound.save_state(&sound_state);
Nes_Mapper::save_state(out); Mapper::save_state(out);
} }
void read_state(mapper_state_t const &in) void read_state(mapper_state_t const &in)
{ {
Nes_Mapper::read_state(in); Mapper::read_state(in);
sound.load_state(sound_state); sound.load_state(sound_state);
} }
Nes_Namco_Apu sound; Namco_Apu sound;
nes_time_t last_time; nes_time_t last_time;
}; };

View File

@ -47,7 +47,7 @@ struct vrc2_state_t
static_assert(sizeof(vrc2_state_t) == 18); static_assert(sizeof(vrc2_state_t) == 18);
template <bool type_a, bool type_b> template <bool type_a, bool type_b>
class Mapper_VRC2_4 : public Nes_Mapper, vrc2_state_t class Mapper_VRC2_4 : public Mapper, vrc2_state_t
{ {
public: public:
Mapper_VRC2_4() Mapper_VRC2_4()

View File

@ -1,7 +1,7 @@
#pragma once #pragma once
// Konami VRC6 mapper // Konami VRC6 mapper
// Nes_Emu 0.7.0. http://www.slack.net/~ant/ // Emu 0.7.0. http://www.slack.net/~ant/
#include "apu/vrc6/apu.hpp" #include "apu/vrc6/apu.hpp"
#include "mappers/mapper.hpp" #include "mappers/mapper.hpp"
@ -44,7 +44,7 @@ struct vrc6_state_t
static_assert(sizeof(vrc6_state_t) == 26 + sizeof(vrc6_apu_state_t)); static_assert(sizeof(vrc6_state_t) == 26 + sizeof(vrc6_apu_state_t));
template <int swapMask> template <int swapMask>
class Mapper_Vrc6 : public Nes_Mapper, vrc6_state_t class Mapper_Vrc6 : public Mapper, vrc6_state_t
{ {
public: public:
Mapper_Vrc6() Mapper_Vrc6()
@ -69,7 +69,7 @@ class Mapper_Vrc6 : public Nes_Mapper, vrc6_state_t
virtual void save_state(mapper_state_t &out) virtual void save_state(mapper_state_t &out)
{ {
sound.save_state(&sound_state); sound.save_state(&sound_state);
Nes_Mapper::save_state(out); Mapper::save_state(out);
} }
virtual void apply_mapping() virtual void apply_mapping()
@ -139,7 +139,7 @@ class Mapper_Vrc6 : public Nes_Mapper, vrc6_state_t
write_irq(time, addr, data); write_irq(time, addr, data);
} }
int swap_mask; int swap_mask;
Nes_Vrc6_Apu sound; Vrc6_Apu sound;
enum enum
{ {
timer_period = 113 * 4 + 3 timer_period = 113 * 4 + 3
@ -147,7 +147,7 @@ class Mapper_Vrc6 : public Nes_Mapper, vrc6_state_t
void read_state(mapper_state_t const &in) void read_state(mapper_state_t const &in)
{ {
Nes_Mapper::read_state(in); Mapper::read_state(in);
// to do: eliminate when format is updated // to do: eliminate when format is updated
// old-style registers // old-style registers

View File

@ -2,7 +2,7 @@
// Konami VRC6 mapper // Konami VRC6 mapper
// Nes_Emu 0.7.0. http://www.slack.net/~ant/ // Emu 0.7.0. http://www.slack.net/~ant/
#include "mappers/mapper.hpp" #include "mappers/mapper.hpp"

View File

@ -34,7 +34,7 @@
namespace quickerNES namespace quickerNES
{ {
class Mapper030 : public Nes_Mapper class Mapper030 : public Mapper
{ {
public: public:
Mapper030() {} Mapper030() {}

View File

@ -39,7 +39,7 @@ static_assert(sizeof(mapper32_state_t) == 12);
// Irem_G101 // Irem_G101
class Mapper032 : public Nes_Mapper, mapper32_state_t class Mapper032 : public Mapper, mapper32_state_t
{ {
public: public:
Mapper032() Mapper032()

View File

@ -38,7 +38,7 @@ static_assert(sizeof(tc0190_state_t) == 9);
// TaitoTC0190 // TaitoTC0190
class Mapper033 : public Nes_Mapper, tc0190_state_t class Mapper033 : public Mapper, tc0190_state_t
{ {
public: public:
Mapper033() Mapper033()

View File

@ -2,7 +2,7 @@
// Optional less-common simple mappers // Optional less-common simple mappers
// Nes_Emu 0.7.0. http://www.slack.net/~ant/ // Emu 0.7.0. http://www.slack.net/~ant/
#include "mappers/mapper.hpp" #include "mappers/mapper.hpp"
@ -22,7 +22,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
namespace quickerNES namespace quickerNES
{ {
class Mapper034 : public Nes_Mapper class Mapper034 : public Mapper
{ {
uint8_t bank; uint8_t bank;

View File

@ -24,7 +24,7 @@
namespace quickerNES namespace quickerNES
{ {
class Mapper060 : public Nes_Mapper class Mapper060 : public Mapper
{ {
public: public:
Mapper060() Mapper060()

View File

@ -2,7 +2,7 @@
// Optional less-common simple mappers // Optional less-common simple mappers
// Nes_Emu 0.7.0. http://www.slack.net/~ant/ // Emu 0.7.0. http://www.slack.net/~ant/
#include "mappers/mapper.hpp" #include "mappers/mapper.hpp"
@ -22,7 +22,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
namespace quickerNES namespace quickerNES
{ {
class Mapper066 : public Nes_Mapper class Mapper066 : public Mapper
{ {
uint8_t bank; uint8_t bank;

View File

@ -2,7 +2,7 @@
// Sunsoft FME-7 mapper // Sunsoft FME-7 mapper
// Nes_Emu 0.7.0. http://www.slack.net/~ant/libs/ // Emu 0.7.0. http://www.slack.net/~ant/libs/
#include "apu/fme7/apu.hpp" #include "apu/fme7/apu.hpp"
#include "mappers/mapper.hpp" #include "mappers/mapper.hpp"
@ -37,7 +37,7 @@ static_assert(sizeof(fme7_state_t) == 18 + sizeof(fme7_apu_state_t));
// Fme7 // Fme7
class Mapper069 : public Nes_Mapper, fme7_state_t class Mapper069 : public Mapper, fme7_state_t
{ {
public: public:
Mapper069() Mapper069()
@ -62,12 +62,12 @@ class Mapper069 : public Nes_Mapper, fme7_state_t
virtual void save_state(mapper_state_t &out) virtual void save_state(mapper_state_t &out)
{ {
sound.save_state(&sound_state); sound.save_state(&sound_state);
Nes_Mapper::save_state(out); Mapper::save_state(out);
} }
virtual void read_state(mapper_state_t const &in) virtual void read_state(mapper_state_t const &in)
{ {
Nes_Mapper::read_state(in); Mapper::read_state(in);
sound.load_state(sound_state); sound.load_state(sound_state);
} }
@ -187,7 +187,7 @@ class Mapper069 : public Nes_Mapper, fme7_state_t
} }
nes_time_t last_time; nes_time_t last_time;
Nes_Fme7_Apu sound; Fme7_Apu sound;
}; };
} // namespace quickNES } // namespace quickNES

View File

@ -31,7 +31,7 @@ namespace quickerNES
{ {
template <int mapperId> template <int mapperId>
class Mapper_74x161x162x32 : public Nes_Mapper class Mapper_74x161x162x32 : public Mapper
{ {
public: public:
Mapper_74x161x162x32() Mapper_74x161x162x32()

View File

@ -2,7 +2,7 @@
// Optional less-common simple mappers // Optional less-common simple mappers
// Nes_Emu 0.7.0. http://www.slack.net/~ant/ // Emu 0.7.0. http://www.slack.net/~ant/
#include "mappers/mapper.hpp" #include "mappers/mapper.hpp"
@ -22,7 +22,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
namespace quickerNES namespace quickerNES
{ {
class Mapper071 : public Nes_Mapper class Mapper071 : public Mapper
{ {
uint8_t regs[3]; uint8_t regs[3];

View File

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

View File

@ -33,7 +33,7 @@ static_assert(sizeof(vrc1_state_t) == 8);
// VRC1 // VRC1
class Mapper075 : public Nes_Mapper, vrc1_state_t class Mapper075 : public Mapper, vrc1_state_t
{ {
public: public:
Mapper075() Mapper075()

View File

@ -7,7 +7,7 @@
namespace quickerNES namespace quickerNES
{ {
class Mapper078 : public Nes_Mapper class Mapper078 : public Mapper
{ {
// lower 8 bits are the reg at 8000:ffff // lower 8 bits are the reg at 8000:ffff
// next two bits are autodetecting type // next two bits are autodetecting type

View File

@ -31,7 +31,7 @@ namespace quickerNES
{ {
template <bool multicart> template <bool multicart>
class Mapper_AveNina : public Nes_Mapper class Mapper_AveNina : public Mapper
{ {
public: public:
Mapper_AveNina() Mapper_AveNina()

View File

@ -1,6 +1,6 @@
#pragma once #pragma once
// Nes_Emu 0.5.4. http://www.slack.net/~ant/ // Emu 0.5.4. http://www.slack.net/~ant/
#include "apu/vrc7/apu.hpp" #include "apu/vrc7/apu.hpp"
#include "mappers/mapper.hpp" #include "mappers/mapper.hpp"
@ -40,7 +40,7 @@ static_assert(sizeof(vrc7_state_t) == 20 + sizeof(vrc7_snapshot_t));
// Vrc7 // Vrc7
class Mapper085 : public Nes_Mapper, vrc7_state_t class Mapper085 : public Mapper, vrc7_state_t
{ {
public: public:
Mapper085() Mapper085()
@ -58,12 +58,12 @@ class Mapper085 : public Nes_Mapper, vrc7_state_t
virtual void save_state(mapper_state_t &out) virtual void save_state(mapper_state_t &out)
{ {
sound.save_snapshot(&sound_state); sound.save_snapshot(&sound_state);
Nes_Mapper::save_state(out); Mapper::save_state(out);
} }
virtual void load_state(mapper_state_t const &in) virtual void load_state(mapper_state_t const &in)
{ {
Nes_Mapper::load_state(in); Mapper::load_state(in);
sound.load_snapshot(sound_state, in.size); sound.load_snapshot(sound_state, in.size);
} }
@ -218,7 +218,7 @@ class Mapper085 : public Nes_Mapper, vrc7_state_t
} }
} }
Nes_Vrc7 sound; Vrc7 sound;
enum enum
{ {
timer_period = 113 * 4 + 3 timer_period = 113 * 4 + 3

View File

@ -1,7 +1,7 @@
#pragma once #pragma once
// Optional less-common simple mappers // Optional less-common simple mappers
// Nes_Emu 0.7.0. http://www.slack.net/~ant/ // Emu 0.7.0. http://www.slack.net/~ant/
#include "mappers/mapper.hpp" #include "mappers/mapper.hpp"
@ -21,7 +21,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
namespace quickerNES namespace quickerNES
{ {
class Mapper087 : public Nes_Mapper class Mapper087 : public Mapper
{ {
uint8_t bank; uint8_t bank;

View File

@ -39,7 +39,7 @@ struct namco_34x3_state_t
static_assert(sizeof(namco_34x3_state_t) == 10); static_assert(sizeof(namco_34x3_state_t) == 10);
template <bool _is154> template <bool _is154>
class Mapper_Namco_34x3 : public Nes_Mapper, namco_34x3_state_t class Mapper_Namco_34x3 : public Mapper, namco_34x3_state_t
{ {
public: public:
Mapper_Namco_34x3() Mapper_Namco_34x3()

View File

@ -29,7 +29,7 @@
namespace quickerNES namespace quickerNES
{ {
class Mapper089 : public Nes_Mapper class Mapper089 : public Mapper
{ {
public: public:
Mapper089() Mapper089()

View File

@ -29,7 +29,7 @@
namespace quickerNES namespace quickerNES
{ {
class Mapper093 : public Nes_Mapper class Mapper093 : public Mapper
{ {
public: public:
Mapper093() Mapper093()

View File

@ -31,7 +31,7 @@
namespace quickerNES namespace quickerNES
{ {
class Mapper094 : public Nes_Mapper class Mapper094 : public Mapper
{ {
public: public:
Mapper094() Mapper094()

View File

@ -30,7 +30,7 @@
namespace quickerNES namespace quickerNES
{ {
class Mapper097 : public Nes_Mapper class Mapper097 : public Mapper
{ {
public: public:
Mapper097() Mapper097()

View File

@ -31,7 +31,7 @@
namespace quickerNES namespace quickerNES
{ {
class Mapper140 : public Nes_Mapper class Mapper140 : public Mapper
{ {
public: public:
Mapper140() Mapper140()

View File

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

View File

@ -30,7 +30,7 @@
namespace quickerNES namespace quickerNES
{ {
class Mapper180 : public Nes_Mapper class Mapper180 : public Mapper
{ {
public: public:
Mapper180() Mapper180()

View File

@ -29,7 +29,7 @@
namespace quickerNES namespace quickerNES
{ {
class Mapper184 : public Nes_Mapper class Mapper184 : public Mapper
{ {
public: public:
Mapper184() Mapper184()

View File

@ -7,7 +7,7 @@
namespace quickerNES namespace quickerNES
{ {
class Mapper190 : public Nes_Mapper class Mapper190 : public Mapper
{ {
public: public:
Mapper190() Mapper190()

View File

@ -32,7 +32,7 @@
namespace quickerNES namespace quickerNES
{ {
class Mapper193 : public Nes_Mapper class Mapper193 : public Mapper
{ {
public: public:
Mapper193() Mapper193()

View File

@ -40,7 +40,7 @@ static_assert(sizeof(namco_34xx_state_t) == 10);
// Namco_34xx // Namco_34xx
class Mapper206 : public Nes_Mapper, namco_34xx_state_t class Mapper206 : public Mapper, namco_34xx_state_t
{ {
public: public:
Mapper206() Mapper206()

View File

@ -38,7 +38,7 @@ static_assert(sizeof(taito_x1005_state_t) == 11);
// TaitoX1005 // TaitoX1005
class Mapper207 : public Nes_Mapper, taito_x1005_state_t class Mapper207 : public Mapper, taito_x1005_state_t
{ {
public: public:
Mapper207() Mapper207()

View File

@ -3,7 +3,7 @@
// Optional less-common simple mappers // Optional less-common simple mappers
// Nes_Emu 0.7.0. http://www.slack.net/~ant/ // Emu 0.7.0. http://www.slack.net/~ant/
#include "mappers/mapper.hpp" #include "mappers/mapper.hpp"
@ -23,7 +23,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
namespace quickerNES namespace quickerNES
{ {
class Mapper232 : public Nes_Mapper class Mapper232 : public Mapper
{ {
uint8_t regs[2]; uint8_t regs[2];

View File

@ -28,7 +28,7 @@
namespace quickerNES namespace quickerNES
{ {
class Mapper240 : public Nes_Mapper class Mapper240 : public Mapper
{ {
public: public:
Mapper240() Mapper240()

View File

@ -28,7 +28,7 @@
namespace quickerNES namespace quickerNES
{ {
class Mapper241 : public Nes_Mapper class Mapper241 : public Mapper
{ {
public: public:
Mapper241() Mapper241()

View File

@ -37,7 +37,7 @@ struct mapper244_state_t
}; };
static_assert(sizeof(mapper244_state_t) == 2); static_assert(sizeof(mapper244_state_t) == 2);
class Mapper244 : public Nes_Mapper, mapper244_state_t class Mapper244 : public Mapper, mapper244_state_t
{ {
public: public:
Mapper244() Mapper244()

View File

@ -30,7 +30,7 @@
namespace quickerNES namespace quickerNES
{ {
class Mapper246 : public Nes_Mapper class Mapper246 : public Mapper
{ {
public: public:
Mapper246() Mapper246()

View File

@ -2,11 +2,11 @@
quickerNESAPUSrc = [ quickerNESAPUSrc = [
'apu/apu.cpp', 'apu/apu.cpp',
'apu/Nes_Oscs.cpp', 'apu/oscs.cpp',
'apu/Nes_Buffer.cpp', 'apu/buffer.cpp',
'apu/Blip_Buffer.cpp', 'apu/Blip_Buffer.cpp',
'apu/Effects_Buffer.cpp', 'apu/NESEffectsBuffer.cpp',
'apu/Nes_Effects_Buffer.cpp', 'apu/effectsBuffer.cpp',
'apu/Multi_Buffer.cpp', 'apu/Multi_Buffer.cpp',
'apu/namco/apu.cpp', 'apu/namco/apu.cpp',
'apu/vrc6/apu.cpp', 'apu/vrc6/apu.cpp',
@ -17,15 +17,15 @@ quickerNESAPUSrc = [
] ]
quickerNESPPUSrc = [ quickerNESPPUSrc = [
'ppu/Nes_Ppu.cpp', 'ppu/ppu.cpp',
'ppu/Nes_Ppu_Impl.cpp', 'ppu/ppuImpl.cpp',
'ppu/Nes_Ppu_Rendering.cpp', 'ppu/ppuRendering.cpp',
] ]
quickerNESSrc = quickerNESAPUSrc + quickerNESPPUSrc + [ quickerNESSrc = quickerNESAPUSrc + quickerNESPPUSrc + [
'mappers/mapper.cpp', 'mappers/mapper.cpp',
'Nes_Emu.cpp', 'emu.cpp',
'Nes_Cpu.cpp' 'cpu.cpp'
] ]
# quickerNES Core Configuration # quickerNES Core Configuration

View File

@ -1,11 +1,11 @@
// Timing and behavior of PPU // Timing and behavior of PPU
// Nes_Emu 0.7.0. http://www.slack.net/~ant/ // Emu 0.7.0. http://www.slack.net/~ant/
#include <cstring> #include <cstring>
#include "Nes_Ppu.hpp" #include "ppu.hpp"
#include "Nes_Core.hpp" #include "core.hpp"
namespace quickerNES namespace quickerNES
{ {
@ -25,7 +25,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
// Timing // Timing
ppu_time_t const scanline_len = Nes_Ppu::scanline_len; ppu_time_t const scanline_len = Ppu::scanline_len;
// if non-zero, report sprite max at fixed time rather than calculating it // if non-zero, report sprite max at fixed time rather than calculating it
nes_time_t const fixed_sprite_max_time = 0; // 1 * ((21 + 164) * scanline_len + 100) / ppu_overclock; nes_time_t const fixed_sprite_max_time = 0; // 1 * ((21 + 164) * scanline_len + 100) / ppu_overclock;
@ -47,7 +47,7 @@ nes_time_t const earliest_vbl_end_time = max_frame_length / ppu_overclock - 10;
// Scanline rendering // Scanline rendering
void Nes_Ppu::render_bg_until_(nes_time_t cpu_time) void Ppu::render_bg_until_(nes_time_t cpu_time)
{ {
ppu_time_t time = ppu_time(cpu_time); ppu_time_t time = ppu_time(cpu_time);
ppu_time_t const frame_duration = scanline_len * 261; ppu_time_t const frame_duration = scanline_len * 261;
@ -121,7 +121,7 @@ void Nes_Ppu::render_bg_until_(nes_time_t cpu_time)
next_bg_time = nes_time(next_ppu_time); next_bg_time = nes_time(next_ppu_time);
} }
void Nes_Ppu::render_until_(nes_time_t time) void Ppu::render_until_(nes_time_t time)
{ {
// render bg scanlines then render sprite scanlines up to wherever bg was rendered to // render bg scanlines then render sprite scanlines up to wherever bg was rendered to
@ -141,14 +141,14 @@ void Nes_Ppu::render_until_(nes_time_t time)
// Frame events // Frame events
inline void Nes_Ppu::end_vblank() inline void Ppu::end_vblank()
{ {
// clear VBL, sprite hit, and max sprites flags first time after 20 scanlines // clear VBL, sprite hit, and max sprites flags first time after 20 scanlines
r2002 &= end_vbl_mask; r2002 &= end_vbl_mask;
end_vbl_mask = ~0; end_vbl_mask = ~0;
} }
inline void Nes_Ppu::run_end_frame(nes_time_t time) inline void Ppu::run_end_frame(nes_time_t time)
{ {
if (!frame_ended) if (!frame_ended)
{ {
@ -169,13 +169,13 @@ inline void Nes_Ppu::run_end_frame(nes_time_t time)
// Sprite max // Sprite max
inline void Nes_Ppu::invalidate_sprite_max_() inline void Ppu::invalidate_sprite_max_()
{ {
next_sprite_max_run = earliest_sprite_max / ppu_overclock; next_sprite_max_run = earliest_sprite_max / ppu_overclock;
sprite_max_set_time = 0; sprite_max_set_time = 0;
} }
void Nes_Ppu::run_sprite_max_(nes_time_t cpu_time) void Ppu::run_sprite_max_(nes_time_t cpu_time)
{ {
end_vblank(); // might get run outside $2002 handler end_vblank(); // might get run outside $2002 handler
@ -204,13 +204,13 @@ void Nes_Ppu::run_sprite_max_(nes_time_t cpu_time)
} }
} }
inline void Nes_Ppu::run_sprite_max(nes_time_t t) inline void Ppu::run_sprite_max(nes_time_t t)
{ {
if (!fixed_sprite_max_time && t > next_sprite_max_run) if (!fixed_sprite_max_time && t > next_sprite_max_run)
run_sprite_max_(t); run_sprite_max_(t);
} }
inline void Nes_Ppu::invalidate_sprite_max(nes_time_t t) inline void Ppu::invalidate_sprite_max(nes_time_t t)
{ {
if (!fixed_sprite_max_time && !(r2002 & 0x20)) if (!fixed_sprite_max_time && !(r2002 & 0x20))
{ {
@ -221,7 +221,7 @@ inline void Nes_Ppu::invalidate_sprite_max(nes_time_t t)
// Sprite 0 hit // Sprite 0 hit
inline int Nes_Ppu_Impl::first_opaque_sprite_line() inline int Ppu_Impl::first_opaque_sprite_line()
{ {
// advance earliest time if sprite has blank lines at beginning // advance earliest time if sprite has blank lines at beginning
uint8_t const *p = map_chr(sprite_tile_index(spr_ram) * 16); uint8_t const *p = map_chr(sprite_tile_index(spr_ram) * 16);
@ -241,7 +241,7 @@ inline int Nes_Ppu_Impl::first_opaque_sprite_line()
return line; return line;
} }
void Nes_Ppu::update_sprite_hit(nes_time_t cpu_time) void Ppu::update_sprite_hit(nes_time_t cpu_time)
{ {
ppu_time_t earliest = earliest_sprite_hit + spr_ram[0] * scanline_len + spr_ram[3]; ppu_time_t earliest = earliest_sprite_hit + spr_ram[0] * scanline_len + spr_ram[3];
// ppu_time_t latest = earliest + sprite_height() * scanline_len; // ppu_time_t latest = earliest + sprite_height() * scanline_len;
@ -300,7 +300,7 @@ void Nes_Ppu::update_sprite_hit(nes_time_t cpu_time)
// $2002 // $2002
inline void Nes_Ppu::query_until(nes_time_t time) inline void Ppu::query_until(nes_time_t time)
{ {
end_vblank(); end_vblank();
@ -315,7 +315,7 @@ inline void Nes_Ppu::query_until(nes_time_t time)
r2002 |= (w2001 << 1 & 0x20) | (w2001 << 2 & 0x20); r2002 |= (w2001 << 1 & 0x20) | (w2001 << 2 & 0x20);
} }
int Nes_Ppu::read_2002(nes_time_t time) int Ppu::read_2002(nes_time_t time)
{ {
nes_time_t next = next_status_event; nes_time_t next = next_status_event;
next_status_event = vbl_end_time; next_status_event = vbl_end_time;
@ -369,7 +369,7 @@ int Nes_Ppu::read_2002(nes_time_t time)
return (result & 0xE0) | (open_bus & 0x1F); return (result & 0xE0) | (open_bus & 0x1F);
} }
void Nes_Ppu::dma_sprites(nes_time_t time, void const *in) void Ppu::dma_sprites(nes_time_t time, void const *in)
{ {
// dprintf( "%d sprites written\n", time ); // dprintf( "%d sprites written\n", time );
render_until(time); render_until(time);
@ -382,7 +382,7 @@ void Nes_Ppu::dma_sprites(nes_time_t time, void const *in)
// Read // Read
inline int Nes_Ppu_Impl::read_2007(int addr) inline int Ppu_Impl::read_2007(int addr)
{ {
int result = r2007; int result = r2007;
if (addr < 0x2000) if (addr < 0x2000)
@ -400,7 +400,7 @@ inline int Nes_Ppu_Impl::read_2007(int addr)
return result; return result;
} }
int Nes_Ppu::read(unsigned addr, nes_time_t time) int Ppu::read(unsigned addr, nes_time_t time)
{ {
switch (addr & 7) switch (addr & 7)
{ {
@ -447,7 +447,7 @@ int Nes_Ppu::read(unsigned addr, nes_time_t time)
// Write // Write
void Nes_Ppu::write(nes_time_t time, unsigned addr, int data) void Ppu::write(nes_time_t time, unsigned addr, int data)
{ {
switch (addr & 7) switch (addr & 7)
{ {
@ -571,7 +571,7 @@ void Nes_Ppu::write(nes_time_t time, unsigned addr, int data)
// Frame begin/end // Frame begin/end
nes_time_t Nes_Ppu::begin_frame(ppu_time_t timestamp) nes_time_t Ppu::begin_frame(ppu_time_t timestamp)
{ {
// current time // current time
int cpu_timestamp = timestamp / ppu_overclock; int cpu_timestamp = timestamp / ppu_overclock;
@ -616,7 +616,7 @@ nes_time_t Nes_Ppu::begin_frame(ppu_time_t timestamp)
return cpu_timestamp; return cpu_timestamp;
} }
ppu_time_t Nes_Ppu::end_frame(nes_time_t end_time) ppu_time_t Ppu::end_frame(nes_time_t end_time)
{ {
render_bg_until(end_time); render_bg_until(end_time);
render_until(end_time); render_until(end_time);
@ -644,14 +644,14 @@ ppu_time_t Nes_Ppu::end_frame(nes_time_t end_time)
return (end_time - frame_length_) * ppu_overclock + frame_length_extra; return (end_time - frame_length_) * ppu_overclock + frame_length_extra;
} }
void Nes_Ppu::poke_open_bus(nes_time_t time, int data, int mask) void Ppu::poke_open_bus(nes_time_t time, int data, int mask)
{ {
open_bus = (open_bus & ~mask) | (data & mask); open_bus = (open_bus & ~mask) | (data & mask);
if (mask & 0x1F) decay_low = time + scanline_len * 100 / ppu_overclock; if (mask & 0x1F) decay_low = time + scanline_len * 100 / ppu_overclock;
if (mask & 0xE0) decay_high = time + scanline_len * 100 / ppu_overclock; if (mask & 0xE0) decay_high = time + scanline_len * 100 / ppu_overclock;
} }
nes_time_t Nes_Ppu::earliest_open_bus_decay() nes_time_t Ppu::earliest_open_bus_decay()
{ {
return (decay_low < decay_high) ? decay_low : decay_high; return (decay_low < decay_high) ? decay_low : decay_high;
} }

View File

@ -1,28 +1,28 @@
#pragma once #pragma once
// NES PPU emulator // NES PPU emulator
// Nes_Emu 0.7.0 // Emu 0.7.0
#include <climits> #include <climits>
#include "Nes_Ppu_Rendering.hpp" #include "ppuRendering.hpp"
namespace quickerNES namespace quickerNES
{ {
class Nes_Mapper; class Mapper;
class Nes_Core; class Core;
typedef long nes_time_t; typedef long nes_time_t;
typedef long ppu_time_t; // ppu_time_t = nes_time_t * ppu_overclock 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 ppu_time_t const ppu_overclock = 3; // PPU clocks for each CPU clock
class Nes_Ppu : public Nes_Ppu_Rendering class Ppu : public Ppu_Rendering
{ {
typedef Nes_Ppu_Rendering base; typedef Ppu_Rendering base;
public: public:
Nes_Ppu(Nes_Core *); Ppu(Core *);
// Begin PPU frame and return beginning CPU timestamp // Begin PPU frame and return beginning CPU timestamp
nes_time_t begin_frame(ppu_time_t); nes_time_t begin_frame(ppu_time_t);
@ -49,7 +49,7 @@ class Nes_Ppu : public Nes_Ppu_Rendering
int burst_phase; int burst_phase;
private: private:
Nes_Core &emu; Core &emu;
enum enum
{ {
@ -109,35 +109,35 @@ class Nes_Ppu : public Nes_Ppu_Rendering
void invalidate_sprite_max_(); void invalidate_sprite_max_();
void invalidate_sprite_max(nes_time_t); void invalidate_sprite_max(nes_time_t);
friend int nes_cpu_read_likely_ppu(class Nes_Core *, unsigned, nes_time_t); friend int nes_cpu_read_likely_ppu(class Core *, unsigned, nes_time_t);
}; };
inline void Nes_Ppu::suspend_rendering() inline void Ppu::suspend_rendering()
{ {
next_bg_time = indefinite_time; next_bg_time = indefinite_time;
next_sprites_time = indefinite_time; next_sprites_time = indefinite_time;
extra_clocks = 0; extra_clocks = 0;
} }
inline Nes_Ppu::Nes_Ppu(Nes_Core *e) : emu(*e) inline Ppu::Ppu(Core *e) : emu(*e)
{ {
burst_phase = 0; burst_phase = 0;
suspend_rendering(); suspend_rendering();
} }
inline void Nes_Ppu::render_until(nes_time_t t) inline void Ppu::render_until(nes_time_t t)
{ {
if (t > next_sprites_time) if (t > next_sprites_time)
render_until_(t); render_until_(t);
} }
inline void Nes_Ppu::render_bg_until(nes_time_t t) inline void Ppu::render_bg_until(nes_time_t t)
{ {
if (t > next_bg_time) if (t > next_bg_time)
render_bg_until_(t); render_bg_until_(t);
} }
inline void Nes_Ppu::update_open_bus(nes_time_t time) inline void Ppu::update_open_bus(nes_time_t time)
{ {
if (time >= decay_low) open_bus &= ~0x1F; if (time >= decay_low) open_bus &= ~0x1F;
if (time >= decay_high) open_bus &= ~0xE0; if (time >= decay_high) open_bus &= ~0xE0;

View File

@ -1,6 +1,6 @@
// Nes_Emu 0.7.0. http://www.slack.net/~ant/ // Emu 0.7.0. http://www.slack.net/~ant/
#include "Nes_Ppu_Impl.hpp" #include "ppuImpl.hpp"
#include <cstdint> #include <cstdint>
#include <cstdio> #include <cstdio>
#include <cstring> #include <cstring>
@ -31,7 +31,7 @@ inline void set_be32(void *p, unsigned long n)
#define SET_BE32(addr, data) set_be32(addr, data) #define SET_BE32(addr, data) set_be32(addr, data)
Nes_Ppu_Impl::Nes_Ppu_Impl() Ppu_Impl::Ppu_Impl()
{ {
impl = NULL; impl = NULL;
chr_data = NULL; chr_data = NULL;
@ -47,19 +47,19 @@ Nes_Ppu_Impl::Nes_Ppu_Impl()
mmc24_latched[1] = 0; mmc24_latched[1] = 0;
} }
Nes_Ppu_Impl::~Nes_Ppu_Impl() Ppu_Impl::~Ppu_Impl()
{ {
close_chr(); close_chr();
delete impl; delete impl;
} }
void Nes_Ppu_Impl::all_tiles_modified() void Ppu_Impl::all_tiles_modified()
{ {
any_tiles_modified = true; any_tiles_modified = true;
memset(modified_tiles, ~0, sizeof modified_tiles); memset(modified_tiles, ~0, sizeof modified_tiles);
} }
const char *Nes_Ppu_Impl::open_chr(uint8_t const *new_chr, long chr_data_size) const char *Ppu_Impl::open_chr(uint8_t const *new_chr, long chr_data_size)
{ {
close_chr(); close_chr();
@ -99,13 +99,13 @@ const char *Nes_Ppu_Impl::open_chr(uint8_t const *new_chr, long chr_data_size)
return 0; return 0;
} }
void Nes_Ppu_Impl::close_chr() void Ppu_Impl::close_chr()
{ {
delete[] tile_cache_mem; delete[] tile_cache_mem;
tile_cache_mem = NULL; tile_cache_mem = NULL;
} }
void Nes_Ppu_Impl::set_chr_bank(int addr, int size, long data) void Ppu_Impl::set_chr_bank(int addr, int size, long data)
{ {
if (data + size > chr_size) if (data + size > chr_size)
data %= chr_size; data %= chr_size;
@ -121,7 +121,7 @@ void Nes_Ppu_Impl::set_chr_bank(int addr, int size, long data)
} }
} }
void Nes_Ppu_Impl::set_chr_bank_ex(int addr, int size, long data) void Ppu_Impl::set_chr_bank_ex(int addr, int size, long data)
{ {
mmc24_enabled = true; mmc24_enabled = true;
@ -148,7 +148,7 @@ 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) void Ppu_Impl::reset(bool full_reset)
{ {
w2000 = 0; w2000 = 0;
w2001 = 0; w2001 = 0;
@ -178,7 +178,7 @@ void Nes_Ppu_Impl::reset(bool full_reset)
memset(host_palette, 0, max_palette_size * sizeof *host_palette); memset(host_palette, 0, max_palette_size * sizeof *host_palette);
} }
void Nes_Ppu_Impl::capture_palette() void Ppu_Impl::capture_palette()
{ {
if (palette_size + palette_increment <= max_palette_size) if (palette_size + palette_increment <= max_palette_size)
{ {
@ -203,7 +203,7 @@ void Nes_Ppu_Impl::capture_palette()
} }
} }
void Nes_Ppu_Impl::run_hblank(int count) void Ppu_Impl::run_hblank(int count)
{ {
long addr = (vram_addr & 0x7be0) + (vram_temp & 0x41f) + (count * 0x1000); long addr = (vram_addr & 0x7be0) + (vram_temp & 0x41f) + (count * 0x1000);
if (w2001 & 0x08) if (w2001 & 0x08)
@ -235,7 +235,7 @@ inline unsigned long reorder(unsigned long n)
return ((n << 14) | n); return ((n << 14) | n);
} }
inline void Nes_Ppu_Impl::update_tile(int index) inline void Ppu_Impl::update_tile(int index)
{ {
const uint8_t *in = chr_data + (index)*bytes_per_tile; const uint8_t *in = chr_data + (index)*bytes_per_tile;
uint8_t *out = (uint8_t *)tile_cache[index]; uint8_t *out = (uint8_t *)tile_cache[index];
@ -274,14 +274,14 @@ inline void Nes_Ppu_Impl::update_tile(int index)
} }
} }
void Nes_Ppu_Impl::rebuild_chr(unsigned long begin, unsigned long end) void Ppu_Impl::rebuild_chr(unsigned long begin, unsigned long end)
{ {
unsigned end_index = (end + bytes_per_tile - 1) / bytes_per_tile; unsigned end_index = (end + bytes_per_tile - 1) / bytes_per_tile;
for (unsigned index = begin / bytes_per_tile; index < end_index; index++) for (unsigned index = begin / bytes_per_tile; index < end_index; index++)
update_tile(index); update_tile(index);
} }
void Nes_Ppu_Impl::update_tiles(int first_tile) void Ppu_Impl::update_tiles(int first_tile)
{ {
int chunk = 0; int chunk = 0;
do do
@ -351,7 +351,7 @@ struct calc_sprite_max_scanlines
} }
}; };
long Nes_Ppu_Impl::recalc_sprite_max(int scanline) long Ppu_Impl::recalc_sprite_max(int scanline)
{ {
int const max_scanline_count = image_height; int const max_scanline_count = image_height;

View File

@ -1,7 +1,7 @@
#pragma once #pragma once
// NES PPU misc functions and setup // NES PPU misc functions and setup
// Nes_Emu 0.7.0 // Emu 0.7.0
#include <cstdint> #include <cstdint>
@ -28,11 +28,11 @@ struct ppu_state_t
}; };
static_assert(sizeof(ppu_state_t) == 20 + 0x20); static_assert(sizeof(ppu_state_t) == 20 + 0x20);
class Nes_Ppu_Impl : public ppu_state_t class Ppu_Impl : public ppu_state_t
{ {
public: public:
Nes_Ppu_Impl(); Ppu_Impl();
~Nes_Ppu_Impl(); ~Ppu_Impl();
void reset(bool full_reset); void reset(bool full_reset);
@ -101,7 +101,7 @@ class Nes_Ppu_Impl : public ppu_state_t
void run_hblank(int); void run_hblank(int);
int sprite_height() const { return (w2000 >> 2 & 8) + 8; } int sprite_height() const { return (w2000 >> 2 & 8) + 8; }
protected: // friend class Nes_Ppu; private: protected: // friend class Ppu; private:
int addr_inc; // pre-calculated $2007 increment (based on w2001 & 0x04) int addr_inc; // pre-calculated $2007 increment (based on w2001 & 0x04)
int read_2007(int addr); int read_2007(int addr);
@ -109,7 +109,7 @@ class Nes_Ppu_Impl : public ppu_state_t
long recalc_sprite_max(int scanline); long recalc_sprite_max(int scanline);
int first_opaque_sprite_line(); int first_opaque_sprite_line();
protected: // friend class Nes_Ppu_Rendering; private: protected: // friend class Ppu_Rendering; private:
unsigned long palette_offset; unsigned long palette_offset;
int palette_changed; int palette_changed;
void capture_palette(); void capture_palette();
@ -173,7 +173,7 @@ class Nes_Ppu_Impl : public ppu_state_t
void update_tile(int index); void update_tile(int index);
}; };
inline void Nes_Ppu_Impl::set_nt_banks(int bank0, int bank1, int bank2, int bank3) inline void Ppu_Impl::set_nt_banks(int bank0, int bank1, int bank2, int bank3)
{ {
uint8_t *nt_ram = impl->nt_ram; uint8_t *nt_ram = impl->nt_ram;
nt_banks[0] = &nt_ram[bank0 * 0x400]; nt_banks[0] = &nt_ram[bank0 * 0x400];
@ -182,14 +182,14 @@ inline void Nes_Ppu_Impl::set_nt_banks(int bank0, int bank1, int bank2, int bank
nt_banks[3] = &nt_ram[bank3 * 0x400]; nt_banks[3] = &nt_ram[bank3 * 0x400];
} }
inline int Nes_Ppu_Impl::map_palette(int addr) inline int Ppu_Impl::map_palette(int addr)
{ {
if ((addr & 3) == 0) if ((addr & 3) == 0)
addr &= 0x0f; // 0x10, 0x14, 0x18, 0x1c map to 0x00, 0x04, 0x08, 0x0c addr &= 0x0f; // 0x10, 0x14, 0x18, 0x1c map to 0x00, 0x04, 0x08, 0x0c
return addr & 0x1f; return addr & 0x1f;
} }
inline int Nes_Ppu_Impl::sprite_tile_index(uint8_t const *sprite) const inline int Ppu_Impl::sprite_tile_index(uint8_t const *sprite) const
{ {
int tile = sprite[1] + (w2000 << 5 & 0x100); int tile = sprite[1] + (w2000 << 5 & 0x100);
if (w2000 & 0x20) if (w2000 & 0x20)
@ -197,7 +197,7 @@ inline int Nes_Ppu_Impl::sprite_tile_index(uint8_t const *sprite) const
return tile; return tile;
} }
inline int Nes_Ppu_Impl::write_2007(int data) inline int Ppu_Impl::write_2007(int data)
{ {
int addr = vram_addr; int addr = vram_addr;
uint8_t *chr_ram = this->chr_ram; // pre-read uint8_t *chr_ram = this->chr_ram; // pre-read
@ -235,7 +235,7 @@ inline int Nes_Ppu_Impl::write_2007(int data)
return changed; return changed;
} }
inline void Nes_Ppu_Impl::begin_frame() inline void Ppu_Impl::begin_frame()
{ {
palette_changed = 0x18; palette_changed = 0x18;
palette_size = 0; palette_size = 0;

View File

@ -1,6 +1,6 @@
// Nes_Emu 0.7.0. http://www.slack.net/~ant/ // Emu 0.7.0. http://www.slack.net/~ant/
#include "Nes_Ppu_Rendering.hpp" #include "ppuRendering.hpp"
#include <algorithm> #include <algorithm>
#include <cstddef> #include <cstddef>
#include <cstring> #include <cstring>
@ -21,8 +21,8 @@ namespace quickerNES
static unsigned zero = 0; // helps CodeWarrior optimizer when added to constants static unsigned zero = 0; // helps CodeWarrior optimizer when added to constants
inline Nes_Ppu_Impl::cached_tile_t const & inline Ppu_Impl::cached_tile_t const &
Nes_Ppu_Impl::get_sprite_tile(uint8_t const *sprite) Ppu_Impl::get_sprite_tile(uint8_t const *sprite)
{ {
cached_tile_t *tiles = tile_cache; cached_tile_t *tiles = tile_cache;
if (sprite[2] & 0x40) if (sprite[2] & 0x40)
@ -31,19 +31,19 @@ Nes_Ppu_Impl::get_sprite_tile(uint8_t const *sprite)
// use index directly, since cached tile is same size as native tile // use index directly, since cached tile is same size as native tile
static_assert(sizeof(cached_tile_t) == bytes_per_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 *(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) inline Ppu_Impl::cached_tile_t const &Ppu_Impl::get_bg_tile(int index)
{ {
// use index directly, since cached tile is same size as native tile // use index directly, since cached tile is same size as native tile
static_assert(sizeof(cached_tile_t) == bytes_per_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 *(Ppu_Impl::cached_tile_t *)((uint8_t *)tile_cache + map_chr_addr(index * bytes_per_tile));
} }
// Fill // Fill
void Nes_Ppu_Rendering::fill_background(int count) void Ppu_Rendering::fill_background(int count)
{ {
ptrdiff_t const next_line = scanline_row_bytes - image_width; ptrdiff_t const next_line = scanline_row_bytes - image_width;
uint32_t *pixels = (uint32_t *)scanline_pixels; uint32_t *pixels = (uint32_t *)scanline_pixels;
@ -72,7 +72,7 @@ void Nes_Ppu_Rendering::fill_background(int count)
} }
} }
void Nes_Ppu_Rendering::clip_left(int count) void Ppu_Rendering::clip_left(int count)
{ {
ptrdiff_t next_line = scanline_row_bytes; ptrdiff_t next_line = scanline_row_bytes;
uint8_t *p = scanline_pixels; uint8_t *p = scanline_pixels;
@ -86,7 +86,7 @@ void Nes_Ppu_Rendering::clip_left(int count)
} }
} }
void Nes_Ppu_Rendering::save_left(int count) void Ppu_Rendering::save_left(int count)
{ {
ptrdiff_t next_line = scanline_row_bytes; ptrdiff_t next_line = scanline_row_bytes;
uint8_t *in = scanline_pixels; uint8_t *in = scanline_pixels;
@ -103,7 +103,7 @@ void Nes_Ppu_Rendering::save_left(int count)
} }
} }
void Nes_Ppu_Rendering::restore_left(int count) void Ppu_Rendering::restore_left(int count)
{ {
ptrdiff_t next_line = scanline_row_bytes; ptrdiff_t next_line = scanline_row_bytes;
uint8_t *out = scanline_pixels; uint8_t *out = scanline_pixels;
@ -122,7 +122,7 @@ void Nes_Ppu_Rendering::restore_left(int count)
// Background // Background
void Nes_Ppu_Rendering::draw_background_(int remain) void Ppu_Rendering::draw_background_(int remain)
{ {
// Draws 'remain' background scanlines. Does not modify vram_addr. // Draws 'remain' background scanlines. Does not modify vram_addr.
@ -257,7 +257,7 @@ void Nes_Ppu_Rendering::draw_background_(int remain)
// Sprites // Sprites
void Nes_Ppu_Rendering::draw_sprites_(int begin, int end) void Ppu_Rendering::draw_sprites_(int begin, int end)
{ {
// Draws sprites on scanlines begin through end - 1. Handles clipping. // Draws sprites on scanlines begin through end - 1. Handles clipping.
@ -285,7 +285,7 @@ void Nes_Ppu_Rendering::draw_sprites_(int begin, int end)
int visible = sprite_height; int visible = sprite_height;
#define CLIPPED 0 #define CLIPPED 0
#include "Nes_Ppu_Sprites.hpp" #include "ppuSprites.hpp"
} }
else else
{ {
@ -306,12 +306,12 @@ void Nes_Ppu_Rendering::draw_sprites_(int begin, int end)
// begin, end, top_minus_one + 1, skip, visible ); // begin, end, top_minus_one + 1, skip, visible );
#define CLIPPED 1 #define CLIPPED 1
#include "Nes_Ppu_Sprites.hpp" #include "ppuSprites.hpp"
} }
} while (index < 0x100); } while (index < 0x100);
} }
void Nes_Ppu_Rendering::check_sprite_hit(int begin, int end) void Ppu_Rendering::check_sprite_hit(int begin, int end)
{ {
// Checks for sprite 0 hit on scanlines begin through end - 1. // Checks for sprite 0 hit on scanlines begin through end - 1.
// Updates sprite_hit_found. Background (but not sprites) must have // Updates sprite_hit_found. Background (but not sprites) must have
@ -406,12 +406,12 @@ void Nes_Ppu_Rendering::check_sprite_hit(int begin, int end)
// Draw scanlines // Draw scanlines
inline bool Nes_Ppu_Rendering::sprite_hit_possible(int scanline) const inline bool Ppu_Rendering::sprite_hit_possible(int scanline) const
{ {
return !sprite_hit_found && spr_ram[0] <= scanline && (w2001 & 0x18) == 0x18; 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 Ppu_Rendering::draw_scanlines(int start, int count, uint8_t *pixels, long pitch, int mode)
{ {
scanline_pixels = pixels + image_left; scanline_pixels = pixels + image_left;
scanline_row_bytes = pitch; scanline_row_bytes = pitch;
@ -475,7 +475,7 @@ void Nes_Ppu_Rendering::draw_scanlines(int start, int count, uint8_t *pixels, lo
scanline_pixels = NULL; scanline_pixels = NULL;
} }
void Nes_Ppu_Rendering::draw_background(int start, int count) void Ppu_Rendering::draw_background(int start, int count)
{ {
// always capture palette at least once per frame // always capture palette at least once per frame
if ((start + count >= 240 && !palette_size) || (w2001 & palette_changed)) if ((start + count >= 240 && !palette_size) || (w2001 & palette_changed))

View File

@ -1,19 +1,19 @@
#pragma once #pragma once
// NES PPU emulator graphics rendering // NES PPU emulator graphics rendering
// Nes_Emu 0.7.0 // Emu 0.7.0
#include "Nes_Ppu_Impl.hpp" #include "ppuImpl.hpp"
namespace quickerNES namespace quickerNES
{ {
class Nes_Ppu_Rendering : public Nes_Ppu_Impl class Ppu_Rendering : public Ppu_Impl
{ {
typedef Nes_Ppu_Impl base; typedef Ppu_Impl base;
public: public:
Nes_Ppu_Rendering(); Ppu_Rendering();
int sprite_limit; int sprite_limit;
@ -50,13 +50,13 @@ class Nes_Ppu_Rendering : public Nes_Ppu_Impl
void check_sprite_hit(int begin, int end); void check_sprite_hit(int begin, int end);
}; };
inline Nes_Ppu_Rendering::Nes_Ppu_Rendering() inline Ppu_Rendering::Ppu_Rendering()
{ {
sprite_limit = 8; sprite_limit = 8;
host_pixels = nullptr; host_pixels = nullptr;
} }
inline void Nes_Ppu_Rendering::draw_sprites(int start, int count) inline void Ppu_Rendering::draw_sprites(int start, int count)
{ {
draw_scanlines(start, count, host_pixels + host_row_bytes * start, host_row_bytes, 2); draw_scanlines(start, count, host_pixels + host_row_bytes * start, host_row_bytes, 2);
} }

View File

@ -1,6 +1,6 @@
#pragma once #pragma once
#include <Nes_Emu.hpp> #include <quickerNES/emu.hpp>
#include <emuInstance.hpp> #include <emuInstance.hpp>
namespace quickerNES namespace quickerNES
@ -12,7 +12,7 @@ class QuickerNESInstance : public EmuInstance
QuickerNESInstance() : EmuInstance() QuickerNESInstance() : EmuInstance()
{ {
// Creating new emulator // Creating new emulator
_nes = new Nes_Emu; _nes = new Emu;
// Allocating video buffer // Allocating video buffer
video_buffer = (uint8_t *)malloc(image_width * image_height); video_buffer = (uint8_t *)malloc(image_width * image_height);
@ -73,7 +73,7 @@ class QuickerNESInstance : public EmuInstance
uint8_t *video_buffer; uint8_t *video_buffer;
// Emulator instance // Emulator instance
Nes_Emu *_nes; Emu *_nes;
}; };
} // namespace quickNES } // namespace quickNES