|
|

楼主 |
发表于 2009-11-8 14:47:50
|
显示全部楼层
这是我手中源码Apu.cpp的内容,敬请赐教:
# e% m& L* m! Z(由于很多专用术语和算法机理都不明白,所以看不大懂……)
1 `$ f, u c/ s9 n$ ^ W//////////////////////////////////////////////////////////////////////////) l+ _( y/ T8 n% X" B# F/ U
// //1 A6 Q( L7 w/ O* M. C& _
// NES APU core //5 X/ |$ @% e4 q; Q7 p
// Norix //6 H% U( h, n! ^( X
// written 2002/06/27 //+ r& c" B- d1 l* T. C2 T
// last modify ----/--/-- //
- N9 A: z$ }7 H: ` M* R//////////////////////////////////////////////////////////////////////////$ `5 U5 I0 z8 I, R- q
#include "DebugOut.h"% `- ` g1 |2 O& J) s
#include "App.h"
( S8 B! Q+ Y3 m9 C#include "Config.h"/ k2 D1 d/ Y" C a, h
: |) a1 U/ {1 N X7 b#include "nes.h"; [4 Q) b1 m" A! L
#include "mmu.h"
# v: T( \# z& a$ P* ?8 ~! u#include "cpu.h"
/ t6 a& ?) T# S% y* ^8 n0 o2 x#include "ppu.h"' {* J n. A3 U# R% W
#include "rom.h"5 H" N% x+ t+ F
#include "apu.h"
/ s% F. r% ^ g& [1 X5 A) d" U! R: v# X; i8 {9 f# ~% j) T
// Volume adjust6 O* o m" S0 T' Z
// Internal sounds
0 W1 A2 `9 `3 m" @' k#define RECTANGLE_VOL (0x0F0)
% k& \4 ~7 n( ?- J#define TRIANGLE_VOL (0x130)) S+ u: W, Z1 z( c5 b+ G, \
#define NOISE_VOL (0x0C0): l0 N- v r# o( o: ~
#define DPCM_VOL (0x0F0)
" ~9 D* y4 J; m// Extra sounds
/ c* r0 O# Z7 T#define VRC6_VOL (0x0F0)
4 i' c& S8 u z: `7 m/ y#define VRC7_VOL (0x130)
- G1 g- F: U$ r8 T; y: R% K#define FDS_VOL (0x0F0)
$ B9 K% _8 U: \. d% X( d* W! ^0 \#define MMC5_VOL (0x0F0): M' ?- g) o) o
#define N106_VOL (0x088)
/ c! b' m3 G- x' h( B; {: M#define FME7_VOL (0x130)7 _5 }/ f/ s9 t& o- O- h: k8 W
" X0 J |* I8 e
APU::APU( NES* parent )
5 O% ?& [: `/ Z3 W{
4 J0 I2 N6 \7 l0 D8 b) j exsound_select = 0;
( D2 a6 t% z# V( q& g+ m# r6 Y+ Y* \. W% r
nes = parent;
" b5 B2 V2 v+ Z. _, P. ]% f3 F internal.SetParent( parent );
8 V( b( a/ V' ~+ c1 x* K- o/ Z& }( O5 X& H2 O
last_data = last_diff = 0;/ S+ ]/ ~2 t \: D$ S1 s! U+ H
* X9 t6 j( e/ k& }9 j
ZEROMEMORY( m_SoundBuffer, sizeof(m_SoundBuffer) );$ A* u% l7 \ ^/ z
% c* o8 R+ y+ P0 p& N5 R
ZEROMEMORY( lowpass_filter, sizeof(lowpass_filter) );
8 ?0 ]9 ^# c, q! m6 T5 q ZEROMEMORY( &queue, sizeof(queue) );
0 o6 w% ?( X3 o/ o+ m ZEROMEMORY( &exqueue, sizeof(exqueue) );+ C+ S, o; G R5 N8 N2 a4 e
+ E' P: u- v) e4 y. _: ?' z( @2 N for( INT i = 0; i < 16; i++ ) {& e! p( b' D, J0 |. n0 O+ ^
m_bMute = TRUE;; q2 j6 g' |: l+ W
}- V( N" x6 t/ y# F+ \
}
- H& Q& w- x# K2 `4 _, ^# _) l2 x# |7 d
APU::~APU()% G- j! h: ~" _. m, [! k( O
{
4 N9 i+ V" S8 Y}4 `5 W" N' Q0 U* q+ h# M' o! y
% @( g* p- }2 b$ T3 ?% ^- P; {' Y8 w
void APU::SetQueue( INT writetime, WORD addr, BYTE data )
# s8 H: z6 P! t0 X) |{- c( s% X9 b& L; s9 O6 I) [9 g
queue.data[queue.wrptr].time = writetime;0 k6 h5 x S$ v# q
queue.data[queue.wrptr].addr = addr;" ^8 Y+ j6 h, A+ h: R
queue.data[queue.wrptr].data = data;
" S" \ i0 f a v) |! N queue.wrptr++;) c2 b, m4 l5 I$ q# K
queue.wrptr&=QUEUE_LENGTH-1;- \. ]2 b* U5 t
if( queue.wrptr == queue.rdptr ) {
3 w+ X- B) o# L DEBUGOUT( "queue overflow.\n" );
! b6 M2 U! U& f6 a }
{/ B$ M! a( \}
, D3 h0 d0 J# A8 X7 }0 \! Z+ p" S1 ~! u L: Z
BOOL APU::GetQueue( INT writetime, QUEUEDATA& ret )
& d' X0 M( N( Y! s6 P{$ g! Y+ G& ^2 O, a) z* m
if( queue.wrptr == queue.rdptr ) {; H! }& i) T5 {. v# Z9 l
return FALSE;
1 z4 [. z6 H; g/ X2 E }
% {6 V$ q" B+ L, B0 } if( queue.data[queue.rdptr].time <= writetime ) {
+ h& q& Z+ k, o$ ^# |0 m! W4 J } ret = queue.data[queue.rdptr];' Q3 R m/ G- ^9 T2 M' R
queue.rdptr++;
+ R, K x, q+ S2 z" f3 a! k queue.rdptr&=QUEUE_LENGTH-1;# l2 N* D+ R! |
return TRUE;
* b5 L, i9 `, _, x1 U) x( | }, r B: `7 g* w, {" J
return FALSE;+ \. @* K! m/ X3 ~
}- [5 G5 G! D# M7 _
5 i4 d, Q# s# ], t* z) o
void APU::SetExQueue( INT writetime, WORD addr, BYTE data )
: J8 y4 q9 z0 k3 L; ^{
3 w' Q2 A6 B8 j! x! c exqueue.data[exqueue.wrptr].time = writetime;/ L# c/ O/ u$ z/ \5 P
exqueue.data[exqueue.wrptr].addr = addr;1 ~# U2 r0 _" c, i" l2 T+ ]
exqueue.data[exqueue.wrptr].data = data;
5 F. m, V: ]& C' F! B exqueue.wrptr++;5 e3 _& x6 \1 t M
exqueue.wrptr&=QUEUE_LENGTH-1;
9 t3 p! z8 V& `& l$ j if( exqueue.wrptr == exqueue.rdptr ) {
E# w# H# F! L& G/ r* C DEBUGOUT( "exqueue overflow.\n" );; g, k' e3 O: s
}
7 q# g* c) ? I( Q}
; f7 v# L, G8 x! ]6 A m5 p7 O5 c0 c/ M
BOOL APU::GetExQueue( INT writetime, QUEUEDATA& ret )
5 y" r8 p) F9 y{
' x0 q, h* i W8 D if( exqueue.wrptr == exqueue.rdptr ) {
0 e( r- r! \: T, K; K8 M- p return FALSE;7 h* O7 ^1 X1 v4 s. B: F; \
}6 T; j' x7 e: _
if( exqueue.data[exqueue.rdptr].time <= writetime ) {, e/ a2 w8 L# j) C' V; @% X: d8 T) Z4 t
ret = exqueue.data[exqueue.rdptr];' W+ Y" ~' O2 j; Z4 j* ]
exqueue.rdptr++;2 P3 H( @2 j" S9 p( j- h0 d O
exqueue.rdptr&=QUEUE_LENGTH-1;- L, D8 x* p8 m6 g
return TRUE;
+ t& T; C2 M: \, g9 C2 _ }4 | ^" N6 n+ |8 w
return FALSE;
$ q& G- E5 x; K5 t1 F) ]8 E: @. _5 i" h}
1 B" P: C$ R& P& k" g2 y
$ c+ I) B2 Q4 m" F" v$ fvoid APU::QueueClear()
4 c& l- M, K# C; \7 B{, \( b0 z' |& o5 f# r7 C& P
ZEROMEMORY( &queue, sizeof(queue) );
' ?7 B- ^5 \6 i! _ ZEROMEMORY( &exqueue, sizeof(exqueue) );1 Q V$ p7 {4 h) u7 H# A. R
}" [/ f2 F+ p9 ]$ ?+ x, f/ M
" J4 ^5 d; B; G: t$ m O; Q; Nvoid APU::QueueFlush()* k3 X1 e: U" O/ C. H$ O& e+ `9 m
{
% q, ^4 P. @# X5 w. _% z; N while( queue.wrptr != queue.rdptr ) {
! Z3 N) @$ | Q WriteProcess( queue.data[queue.rdptr].addr, queue.data[queue.rdptr].data );+ Y! A( X4 t1 ]9 \. M
queue.rdptr++;
5 k: n) N1 U0 {5 S queue.rdptr&=QUEUE_LENGTH-1;
% R$ s. m/ j- X0 \/ ^! _ }
- }7 V n. T; V, V% H. k% G
/ N- F' b1 e0 k% n! B2 y$ r8 l" I while( exqueue.wrptr != exqueue.rdptr ) {! Z3 [) p+ b8 U9 k3 `# u
WriteExProcess( exqueue.data[exqueue.rdptr].addr, exqueue.data[exqueue.rdptr].data );
/ X8 R0 C( k# l: Z: q exqueue.rdptr++;( I1 z* ^+ n# I2 M; V3 @$ B
exqueue.rdptr&=QUEUE_LENGTH-1;
' S ]4 N: A: D }
6 Z' ~. K2 n3 L# Y}( Q. }" ?8 C9 \9 x) v8 T0 v" F
, \$ |+ j ^- Q
void APU::SoundSetup()5 q) P3 T1 F- Y' L2 F8 e# G
{
' G) V5 A* X9 a$ ?3 |6 J FLOAT fClock = nes->nescfg->CpuClock;
" H7 P5 N0 W+ N& C! [7 j' K5 q INT nRate = (INT)Config.sound.nRate;* |% E: v) d& X5 p# ?3 b
internal.Setup( fClock, nRate );
$ n+ D; t W; J- R/ y vrc6.Setup( fClock, nRate );
$ S$ \: p9 _( ~! R/ \ vrc7.Setup( fClock, nRate );- v8 J3 X- q. Z2 v( c7 S5 t9 p
mmc5.Setup( fClock, nRate );
# u% e# k( a* y( v7 i7 i9 x& Z fds.Setup ( fClock, nRate );
& {2 J" T; {- c" E {' d. p n106.Setup( fClock, nRate );2 C& _" I1 A+ u, n# s
fme7.Setup( fClock, nRate );
o' F( z* v- S7 w8 Y}2 f1 N4 Z. m* k) {( F6 ]
: H7 ~" ~* x5 ~' ~! p0 hvoid APU::Reset()
( ^8 b" ~6 l' m+ H! d% i3 H+ b{$ I3 p1 B( }' G3 c
ZEROMEMORY( &queue, sizeof(queue) );
" O3 T( z8 V2 z1 N/ Q& m% x ZEROMEMORY( &exqueue, sizeof(exqueue) );
8 r4 k: x* s+ H( o$ T) L- @
& |5 w/ U# t5 O2 [) o elapsed_time = 0;% E4 U y$ t. o" m
& g* J7 i' e+ a8 ?9 W7 l% E
FLOAT fClock = nes->nescfg->CpuClock;
5 y [/ s% e/ J6 j! u, a. E INT nRate = (INT)Config.sound.nRate;+ H" z b1 m* g- \3 x; ^
internal.Reset( fClock, nRate );! j+ l1 `0 [9 B+ J
vrc6.Reset( fClock, nRate );
# H2 x. `0 m8 L( g' X vrc7.Reset( fClock, nRate );' |5 r. N# v9 X4 v' J
mmc5.Reset( fClock, nRate );( U; v* }3 Y- t
fds.Reset ( fClock, nRate );
8 j+ ~( @8 x0 G" g" j. O2 D n106.Reset( fClock, nRate );) u) P+ I) G/ |9 c2 Y
fme7.Reset( fClock, nRate );+ H1 G* e. s7 T2 L: ?8 S2 i# U
" S3 Y8 N. ~; u; R% s# u& T SoundSetup(); `' y U! P- L; d6 }& e
}% u9 I& T1 n- V8 I' i7 {4 N' b/ C; ?" @: A
5 w( y2 F6 ]! q1 q9 z* A
void APU::SelectExSound( BYTE data )
2 g2 m/ Q$ e! T/ D. k{
6 i q% ?. V7 {3 j% e% U exsound_select = data;
8 w* X. K+ Q: r/ b4 r}) W6 I3 q( U: k
2 S9 j5 [+ p, R8 S W/ yBYTE APU::Read( WORD addr )
/ y6 K% C1 g, R% a# U- y{/ x W1 d1 X# O0 P: c( d
return internal.SyncRead( addr );
" _4 Y& N0 N) x- G9 m}
, [+ N; {( k, T* f$ Y! ~+ m3 ~9 i( P+ j7 t* {. G
void APU::Write( WORD addr, BYTE data ). s* E8 S8 T" u5 k! c
{
1 H" D- T* i/ r4 S1 d- C // $4018偼VirtuaNES屌桳億乕僩0 j0 }8 ]6 ]: N% R8 o1 H
if( addr >= 0x4000 && addr <= 0x401F ) {
3 z5 q+ ]9 j$ u! h1 L: t/ e internal.SyncWrite( addr, data );6 ?/ g( t3 O7 g2 y: ? ?( ?; C
SetQueue( nes->cpu->GetTotalCycles(), addr, data );/ g: F$ O% }( q" ^' s- V
}
, b7 N. B8 G7 {' {2 V}# H$ l3 K) x7 |
. o5 I, A6 t* u. [5 {) H5 l. H, d
BYTE APU::ExRead( WORD addr )2 ^8 `& d0 ^0 j. ~
{
& ~- H$ f+ k* W! |BYTE data = 0;$ f E- y+ G& Q5 n
9 ~4 X2 q- B J X9 X+ x
if( exsound_select & 0x10 ) {, V( R) `2 N7 x' `# }, z& ^+ n Y& u
if( addr == 0x4800 ) {8 K6 K7 [; p3 A" I3 \5 o
SetExQueue( nes->cpu->GetTotalCycles(), 0, 0 );, x7 |( s) X# h, p# y& F+ A
}
+ O6 T7 B7 Z/ A }
; |3 G) M/ H: ] H if( exsound_select & 0x04 ) {" K, H: V5 o$ S
if( addr >= 0x4040 && addr < 0x4100 ) {3 y( P z9 Y! }6 L8 [; k' y. i4 }3 d7 h
data = fds.SyncRead( addr );
: b* N; ^* z2 [8 J& d1 S9 L }! L5 H6 K; t( X% s1 U! }
}
- S! R* t1 X$ M$ y, e; M4 M$ |$ L4 h if( exsound_select & 0x08 ) {
5 C* x" R$ Z$ v) t. M0 f if( addr >= 0x5000 && addr <= 0x5015 ) {
u0 A/ ^( B1 F& @( A data = mmc5.SyncRead( addr );
" V8 K! c6 [* f }
) y9 u1 A/ [ U% F! `+ s }4 r( Q7 R0 i% }5 N$ t8 U5 D# ]
% ?+ d! W1 c: q: E% V return data;
, K5 @6 X4 [" I7 U}
) D& g3 ]. l: h" m* [
& [% u5 ? ?& B5 `' {- hvoid APU::ExWrite( WORD addr, BYTE data )5 F& g$ M2 d, S2 Z# r
{$ q3 i* Q. C- F$ _7 ^
SetExQueue( nes->cpu->GetTotalCycles(), addr, data );
+ M9 N, q2 t# P8 u8 V( h6 I& ?/ u# B2 j& C0 u" C. |
if( exsound_select & 0x04 ) {$ A# y' h. O2 K7 a3 m3 M1 c
if( addr >= 0x4040 && addr < 0x4100 ) {
* X1 W5 ]0 L4 a3 d$ ?' @ fds.SyncWrite( addr, data );8 g* x# D6 ]+ G' e$ ^% s$ h4 T9 Q
}4 j5 t. X" `' O
}
8 R {6 ]" w1 H; H0 B
8 S+ J' p2 q5 o# m if( exsound_select & 0x08 ) {
2 V- b8 f; x" E9 y# ^* M if( addr >= 0x5000 && addr <= 0x5015 ) {
9 c7 X6 g' r7 N; n mmc5.SyncWrite( addr, data );
$ t1 y* {& G g+ ]. y. E }
* L2 O0 q" [% N! g0 g1 q }
# h' ^8 R* H& Y+ a}, s) O* N' y. x/ {
( t. ?9 m# A9 i# B- e7 T1 _1 i
void APU::Sync()" O5 @2 {8 [6 ~# R3 M+ i
{
& F9 B( i0 C- {" \; }/ g6 e}/ k( l, i0 A* v- R
1 p- ~6 m& F- W! Bvoid APU::SyncDPCM( INT cycles ), \3 \: c" L5 a, \% i8 ]3 d# R1 ^
{
; H( g) k8 [5 Z: e; B* l internal.Sync( cycles );6 j8 ?; Z+ o9 ^( l
( f/ @2 X/ |+ f; y" W. A. l if( exsound_select & 0x04 ) {- j) @, r* k p7 l+ V
fds.Sync( cycles );
9 Z8 G, [. G7 ]' [* ~ }
* Q; w$ e: a, G9 b if( exsound_select & 0x08 ) {0 _6 I" I5 b9 y
mmc5.Sync( cycles );
( H7 ]. w" B. V( p5 P J1 }' F" c }
+ W; N4 S. Y3 A}
/ H& n3 v- ?/ ~0 K1 R
* \0 s6 m$ k# k3 b8 ^6 Yvoid APU::WriteProcess( WORD addr, BYTE data )
( d5 c6 U, _& {' m3 j7 n- M{& }6 b0 }0 Q+ \) Y2 r
// $4018偼VirtuaNES屌桳億乕僩
! X' {8 T9 k. ]: ^8 j8 ?8 C if( addr >= 0x4000 && addr <= 0x401F ) {
: S- I" T2 E. F) {8 G' s internal.Write( addr, data );# Q7 P* p+ n- R; j, p
}
& ?% a% e) P2 I2 ^9 {}' o: G! N$ [' K7 ^, l8 p: V
4 e# g" G( h) u L8 ^; ]0 a5 L
void APU::WriteExProcess( WORD addr, BYTE data )* X7 u: Z0 g9 n% O
{
" R4 R- o0 X7 j) \7 d- B if( exsound_select & 0x01 ) {
) f% }# r* B8 j vrc6.Write( addr, data );( q z1 ^7 w4 ] E
}
; U8 q# f9 S' c: ^. [ if( exsound_select & 0x02 ) {
9 t/ \! H0 _$ g% U. i vrc7.Write( addr, data );( P" N1 S: v3 K
}9 K9 f M$ K. A# U" \0 {
if( exsound_select & 0x04 ) {8 s# ?1 |$ j, K* q# E
fds.Write( addr, data );9 {/ { r" S) O8 b" v! X, L" a
}
( O: @# `2 P F0 C! z* o( u# i if( exsound_select & 0x08 ) {5 o+ c6 D$ q! k! E3 k" O) S$ i
mmc5.Write( addr, data );
9 E0 H* t! Y; T: u }7 ?- z* ~ F% h1 p) y2 P$ z8 f8 p ^
if( exsound_select & 0x10 ) {
) n- r+ P/ J+ U* o# |$ X* T! g b3 Q if( addr == 0x0000 ) {. ^" V( C. L" M8 C1 f; f3 U- f
BYTE dummy = n106.Read( addr );
3 ]* } J2 N" q) N D; A9 t } else {
8 p$ k( O2 O9 O n106.Write( addr, data );0 x5 p8 @; a, b1 I* z7 _9 `2 w A: J1 y
}
; e1 \: v: ~- r2 t O# o }
5 m$ B5 v3 u" [! v9 c8 C2 L if( exsound_select & 0x20 ) {% A1 Q* [5 l4 q7 R/ _* _3 k' F
fme7.Write( addr, data );2 Z [8 v! ], ^) `7 G6 a' x7 a
}, O0 y- x# w- J, o; ]# O
}
X3 O+ k# S; ?' N" f. c4 C, z" }* K+ d/ P3 G
void APU::Process( LPBYTE lpBuffer, DWORD dwSize )
& l$ I8 r2 w( k5 @1 ^" N! }; D{
; h& R4 | F% k I) QINT nBits = Config.sound.nBits;
% U' R5 ]# e6 L' J5 t( R$ r; V0 _DWORD dwLength = dwSize / (nBits/8);1 [1 {4 i A# x. K2 [
INT output;: b2 t/ B: f5 F1 H" V3 a; h9 b
QUEUEDATA q;; @+ w+ }7 ?# m3 r# p6 p' T0 W8 `
DWORD writetime;
1 ^ j; O! i+ @
/ |! Q9 V( z0 i. C' CLPSHORT pSoundBuf = m_SoundBuffer;. P3 j( n, ^7 ?. I
INT nCcount = 0;, r$ f; }; G% \1 h
* S! C- A% K0 Q/ J7 ^; ?+ a9 G
INT nFilterType = Config.sound.nFilterType;$ y8 q8 e* u0 p M6 T
2 a+ r. G. k4 i8 }" R5 d# Q" E+ Z
if( !Config.sound.bEnable ) {8 J1 N j3 g- U- o9 {2 ?2 E
::FillMemory( lpBuffer, dwSize, (BYTE)(Config.sound.nRate==8?128:0) );; D, d; {4 [1 x+ x3 Q
return;
& d4 r. A2 i. t" C6 {. V4 _/ w0 u }
* Q* P6 ~! _$ ?9 E) m
6 f+ G( b* @+ V/ b" m8 v% `" Q3 q // Volume setup, b5 c7 \. W' x' Z. a6 e$ K! w( d
// 0:Master% E/ ?% o: s/ ?1 d! Y1 M4 F
// 1:Rectangle 1
- i6 [9 t8 F; c, W$ d // 2:Rectangle 2
! i2 g+ x5 J, O3 Z // 3:Triangle
: X5 J2 c* R9 W3 J3 J+ E8 J+ A2 P // 4:Noise
! ?5 H; O4 d) K3 f/ o, a // 5:DPCM6 t. u* t) x, }4 @8 T9 b/ ^
// 6:VRC6
. F. c& D2 e Z$ }! b/ k // 7:VRC7
2 Q! S# ~/ V5 D# {* _ // 8:FDS1 w9 w* {5 F! [9 q1 d
// 9:MMC5
" C5 L3 S) h$ T# r% S // 10:N106
- C" k/ P2 ?6 }% t" B1 { // 11:FME7
. z* e" p7 W: Y; ~$ K3 ? INT vol[24];, n' y8 e }3 r
BOOL* bMute = m_bMute;
! A7 W( B! h/ y, [5 |# w SHORT* nVolume = Config.sound.nVolume;
/ D. w( w0 }. Y. v4 G
3 U) K9 a. j. ?' ?3 @, p& B0 J5 ?7 x, ^ INT nMasterVolume = bMute[0]?nVolume[0]:0;: m$ X2 G+ z( `3 c/ a
& k3 Y- b0 G" ~: y
// Internal0 y2 O8 L" c6 y I/ ^7 ]
vol[ 0] = bMute[1]?(RECTANGLE_VOL*nVolume[1]*nMasterVolume)/(100*100):0;
$ _5 `, C4 {+ b! D- R4 K, r vol[ 1] = bMute[2]?(RECTANGLE_VOL*nVolume[2]*nMasterVolume)/(100*100):0;
$ j, X* |' `- u, E vol[ 2] = bMute[3]?(TRIANGLE_VOL *nVolume[3]*nMasterVolume)/(100*100):0;
3 e. B- E2 N5 ^3 e- I, T vol[ 3] = bMute[4]?(NOISE_VOL *nVolume[4]*nMasterVolume)/(100*100):0;
, W; C+ U) }" s% F6 ^ H4 m( Q/ i vol[ 4] = bMute[5]?(DPCM_VOL *nVolume[5]*nMasterVolume)/(100*100):0;
& i- R7 D; T/ F; [* H: p4 g' w4 O/ ?! {! v6 u- s$ i
// VRC6+ e- u! U1 Y: f( C& }- }5 z& I
vol[ 5] = bMute[6]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
5 m; @' w3 K3 h2 J vol[ 6] = bMute[7]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;3 W6 {! h- E0 J$ }% y
vol[ 7] = bMute[8]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
+ C# u; D: \( w
4 T! h/ D) y9 w# V- X( a // VRC7+ ~$ e7 i" }- G# i' a6 F. @
vol[ 8] = bMute[6]?(VRC7_VOL*nVolume[7]*nMasterVolume)/(100*100):0;
9 L# j/ c* G) _" T! q1 n' Y0 e' _8 I" b2 _8 _# Y+ `- ]# N
// FDS- I) ]8 b, W; I' y5 l3 \- T
vol[ 9] = bMute[6]?(FDS_VOL*nVolume[8]*nMasterVolume)/(100*100):0;3 c: a1 v$ h5 I4 `5 [
/ ]1 u. T5 T7 W0 [, @ // MMC5 W; n% S5 E$ U2 Q5 S+ b) Q
vol[10] = bMute[6]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;: E: T; z5 ~ E& [
vol[11] = bMute[7]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
7 }/ q) ?# N' U5 M. U vol[12] = bMute[8]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
, T! X, d( y) I! D7 ~' h7 E, C5 d, | z# ?8 K" A4 m7 f% U
// N106, d; Y! L* w7 S- D9 W2 W9 `, D
vol[13] = bMute[ 6]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;2 D# `. b5 K' P6 D4 R5 x7 G
vol[14] = bMute[ 7]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;1 v( u" E% `" J% I
vol[15] = bMute[ 8]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;7 j" L- A7 n; F7 l/ `7 i- A i
vol[16] = bMute[ 9]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;7 R1 R$ H8 I; D4 [
vol[17] = bMute[10]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
' p( T8 o* Y: f- B/ V vol[18] = bMute[11]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
/ S& C6 C+ C7 A: X" W vol[19] = bMute[12]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;- B/ Q/ Z# v& y3 [" i
vol[20] = bMute[13]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0; t2 L; w1 A% ?0 r ]! V& M' }) g
" t$ n. h' z" J- @; q
// FME72 @9 v0 B4 z! m' m$ ~# T; ]1 T
vol[21] = bMute[6]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;& a9 W& I: A0 ~; Y' Z$ y" \
vol[22] = bMute[7]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;9 h! f ^! d& ]7 V' r
vol[23] = bMute[8]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
* \. [. C' v: G1 Q; u! T
@* h* N5 ^- j- {// double cycle_rate = ((double)FRAME_CYCLES*60.0/12.0)/(double)Config.sound.nRate;2 }: o0 a, w+ Q. U' i5 o( ]# ]! k- G
double cycle_rate = ((double)nes->nescfg->FrameCycles*60.0/12.0)/(double)Config.sound.nRate;6 O. z! K! D+ ~! `% I, J
; ?2 D0 g. y3 v M U // CPU僒僀僋儖悢偑儖乕僾偟偰偟傑偭偨帪偺懳嶔張棟
; u/ Z1 H2 e% h" R. | if( elapsed_time > nes->cpu->GetTotalCycles() ) {5 @8 F4 D1 ?0 J" g
QueueFlush();
) ?3 e" y. Z! x! [& V& F% X }5 r) f6 L( {, A. \
1 }; m! r! A" Q _% }
while( dwLength-- ) {) T% ~' _: I7 ~0 S
writetime = (DWORD)elapsed_time;
1 M( A3 t3 t# @& V# t0 {" G7 O% H# C. ?* X9 W
while( GetQueue( writetime, q ) ) {% ^3 x$ B. H2 z" A
WriteProcess( q.addr, q.data );% j& s" v1 y# K. f" P Q; H
}) f4 B: S {* M" q# M
3 E0 J; S6 q* T V while( GetExQueue( writetime, q ) ) {* o. [0 K& r# J6 k
WriteExProcess( q.addr, q.data );6 X) k+ c: ^! P5 r
}
: t9 n" B5 x/ H o, J' K: {* s7 i& w, o/ a; j8 D+ M
// 0-4:internal 5-7:VRC6 8:VRC7 9:FDS 10-12:MMC5 13-20:N106 21-23:FME7
2 x( R0 e) W0 x output = 0;. m. Z+ @ s! B, P, H; g
output += internal.Process( 0 )*vol[0];# M7 X; P/ @! @! N
output += internal.Process( 1 )*vol[1];( J) S2 }' g( U. T
output += internal.Process( 2 )*vol[2];6 U- i% A4 n9 q: ~* @! R0 G
output += internal.Process( 3 )*vol[3];1 `, Y7 i" ]3 b- ^6 N9 z% N0 V
output += internal.Process( 4 )*vol[4];& g' X6 t4 g/ h7 y) U9 ~
; R* u# B8 u0 p, L `( G2 w6 x5 N( j
if( exsound_select & 0x01 ) {% v; s6 D6 \0 W+ F$ H
output += vrc6.Process( 0 )*vol[5];
2 c" K, ~) H5 m9 X1 I output += vrc6.Process( 1 )*vol[6];
: e4 K; i4 m6 t: A output += vrc6.Process( 2 )*vol[7];' t; s) M- w( ^; \" W" ^
}' x1 d: j! w+ i1 X% w8 w
if( exsound_select & 0x02 ) {
1 K. b3 q- q0 u3 Y output += vrc7.Process( 0 )*vol[8];5 w- {# }: [. V- ?7 x- C6 O
}
* T' ^7 k* ~) L. |. L- r if( exsound_select & 0x04 ) {$ |1 B: O% J* e' p9 ^/ e6 r
output += fds.Process( 0 )*vol[9];
" v S1 m( Y8 _$ v- A) W9 F5 ^7 B9 \6 G# ] }8 t+ ?# N0 l+ I! J& c8 M
if( exsound_select & 0x08 ) {
2 p" [6 ~7 l7 g output += mmc5.Process( 0 )*vol[10];. d) O* g6 F& J- i0 p! r& Y
output += mmc5.Process( 1 )*vol[11];! d; t o* z6 x7 I# X" u1 B! I
output += mmc5.Process( 2 )*vol[12];- K z0 e8 P5 }3 i, @5 c, c
}
; h4 d' b: F+ o7 k a/ a if( exsound_select & 0x10 ) {6 h6 t% j9 A) M) m& d8 ? _
output += n106.Process( 0 )*vol[13];
V. O0 ~5 ^3 @/ Y( f8 u! e output += n106.Process( 1 )*vol[14];. z5 X- d( N- t7 r0 ~2 ^ |
output += n106.Process( 2 )*vol[15];8 e1 _9 Y( u5 s. U- Q. z
output += n106.Process( 3 )*vol[16];! D. w9 H$ U% f5 w9 Y
output += n106.Process( 4 )*vol[17];5 I5 b# @# n. G+ F; t+ B
output += n106.Process( 5 )*vol[18];
" h5 x7 f$ _9 ?, k* `- E8 N j7 J output += n106.Process( 6 )*vol[19];
3 ?/ w$ w$ U3 k! W output += n106.Process( 7 )*vol[20];
3 O9 W, I% }7 L* Z0 S9 L }
% l' ?; H" n) e' k if( exsound_select & 0x20 ) {
! \# O4 [% @/ C fme7.Process( 3 ); // Envelope & Noise3 }5 a% S2 Z: A: T4 \: R6 F- q( v( Q
output += fme7.Process( 0 )*vol[21];
l) |5 y# U$ P7 m8 G output += fme7.Process( 1 )*vol[22];% C% h& I- T, k1 m+ i& L
output += fme7.Process( 2 )*vol[23];9 e2 X J& j, K* L4 ^' g, P; H
}5 |" m6 U5 ?( o. d
3 Q$ ], e5 [9 W6 a# w* M output >>= 8;. e$ C: r8 J9 ~* l! h' W
' s8 F$ ]+ s% d7 N
if( nFilterType == 1 ) {
8 p4 U: h1 ]' A$ L, ^% I //儘乕僷僗僼傿儖僞乕TYPE 1(Simple); a! A9 Y# P9 _ W$ E2 }1 u
output = (lowpass_filter[0]+output)/2;
2 e" c* T. d: K+ h lowpass_filter[0] = output;
; O/ `: L1 r- E3 a" M# c& s } else if( nFilterType == 2 ) {3 E9 M3 a0 \% i) e! c2 b7 U, D8 z2 y! y
//儘乕僷僗僼傿儖僞乕TYPE 2(Weighted type 1)( ~- @6 ?0 I+ o S! G
output = (lowpass_filter[1]+lowpass_filter[0]+output)/3;
$ P* L% e" p* j4 T6 K' g, m lowpass_filter[1] = lowpass_filter[0];
2 O! {- n2 E9 i, Z2 g. z$ p: h5 g. ~2 P lowpass_filter[0] = output;
S o! e/ l2 G8 p } else if( nFilterType == 3 ) { @ ~4 v& d+ \( N+ F* j! i% I
//儘乕僷僗僼傿儖僞乕TYPE 3(Weighted type 2)- Q0 v# |! R" |6 x, ?0 ~
output = (lowpass_filter[2]+lowpass_filter[1]+lowpass_filter[0]+output)/4;
; w5 Q" d, D* G# u0 y5 B8 I$ a lowpass_filter[2] = lowpass_filter[1];# a& H+ p6 p1 ]5 V
lowpass_filter[1] = lowpass_filter[0];( D+ B, x6 z# Y( k9 T
lowpass_filter[0] = output;9 b5 {: l- }3 M" d' Z
} else if( nFilterType == 4 ) {
2 ]# `0 G$ i3 |3 Q //儘乕僷僗僼傿儖僞乕TYPE 4(Weighted type 3)
$ ~) s* `. B$ q6 y output = (lowpass_filter[1]+lowpass_filter[0]*2+output)/4;' h& e/ f, C+ W& [8 ^$ l
lowpass_filter[1] = lowpass_filter[0];' s/ ^1 w& ?/ A$ C3 A# V
lowpass_filter[0] = output;
G+ _3 J3 p; a }
; s5 S5 i9 S! i! @9 a& I$ \( t- \5 m, f5 E. V$ g
#if 07 ^5 a$ P% q+ M/ P0 m& h2 `
// DC惉暘偺僇僢僩
- O4 [& A$ v' D5 e {- f. Y, S0 Z9 @6 V" C
static double ave = 0.0, max=0.0, min=0.0;0 f/ }" l2 P' R7 S
double delta;& S" X5 C- {5 _; u$ ^3 R
delta = (max-min)/32768.0;
+ P8 ~) @0 j! i r' g8 T7 N. @ max -= delta;
+ x* U& j6 m0 _$ P. l ~ min += delta;6 i8 c3 K$ ?1 S1 [. d4 N% m9 t
if( output > max ) max = output;- {. [1 c) ?$ t; f
if( output < min ) min = output;8 B: b' r7 b! i1 T& x& H+ t
ave -= ave/1024.0;
& L- |1 Q- ]" o, g; B ave += (max+min)/2048.0;$ V0 S2 @3 i {& T" _
output -= (INT)ave;
/ X8 l! A! i& m" J6 b0 }. O' @ }
5 P- D0 G4 {# D# n, O6 F# t& Q#endif/ o% A j+ |* f4 P$ Q1 ?
#if 1
; b) m+ ]" j: W: H- {9 z // DC惉暘偺僇僢僩(HPF TEST)
V, Y$ _& t0 s% h {
1 t/ O# R3 Z: _: t: _5 F7 }// static double cutoff = (2.0*3.141592653579*40.0/44100.0);
3 u& ^' M2 `4 Z; v; r6 J" T static double cutofftemp = (2.0*3.141592653579*40.0);' d0 W A) n& E6 F3 t# E
double cutoff = cutofftemp/(double)Config.sound.nRate;. K; [; v( h0 U( J1 c. v0 O
static double tmp = 0.0;& w' U e1 l7 W7 s; v) |( f$ a8 ?% s+ k
double in, out;
}4 P: @; h6 j- F; S5 g
- M$ F7 D% ]) R% N' _/ s in = (double)output;
/ J( Y7 T9 I- V3 q out = (in - tmp);5 S7 V% C3 \: y( q* |8 C$ s2 I
tmp = tmp + cutoff * out;
+ |3 G( x* h$ Y0 F* @% ^$ v2 t, f6 Q/ Q: P' r
output = (INT)out;
) i" T) O% o) |" U }- C! k% Q1 z- W M6 Z
#endif1 o$ {5 n2 n' v; Z1 ]/ S" k9 I
#if 0- N: y& {1 o& d! i9 s
// 僗僷僀僋僲僀僘偺彍嫀(AGC TEST)/ d' P% s* x& b+ w" F4 R7 n/ q
{
+ ~: V4 ]% Z) a- R, v4 ` INT diff = abs(output-last_data);5 a& O+ u$ } _4 f
if( diff > 0x4000 ) {
/ l& u/ k. F" O7 F output /= 4;
4 ~! u) J% G4 a5 M2 T) J } else
1 ? q: x6 F$ p4 H if( diff > 0x3000 ) {
, w/ W0 D% z- B+ Z output /= 3;; _& J; j4 Y1 j6 z' N' k1 F& {
} else& a, v. I0 Y4 w ?
if( diff > 0x2000 ) {" V4 W$ h5 {+ `0 K9 x# D
output /= 2;
& O+ v/ g6 i) L! R! G }
+ X9 l s7 R: P0 X last_data = output; Y: q. F [4 A$ A
}) u- R) ?$ [! K. L
#endif: Q1 f6 L$ Q4 z# O3 c5 i3 W+ S' A
// Limit r% f9 {7 \8 R/ |; E7 ^( r% d
if( output > 0x7FFF ) {
/ z7 V4 B2 D7 V O2 V+ H0 W+ \$ W, ?4 k output = 0x7FFF;
0 J. w# Y. G; y } else if( output < -0x8000 ) {7 L" ?& v9 t8 G/ D# d" W
output = -0x8000;% |. C$ D% [: z4 r b
}2 G0 v& t4 J" |, H
. T3 t- S2 a7 g8 i u; f8 L
if( nBits != 8 ) {
" t! u" U2 K, A- @4 z *(SHORT*)lpBuffer = (SHORT)output;
) ~7 b6 R5 r" n7 T2 ^9 n) a6 I, z" q. R lpBuffer += sizeof(SHORT);
/ C0 p7 Z8 x1 m# x5 J$ \+ w# R } else {
8 [( `0 f4 h, |0 b9 K *lpBuffer++ = (output>>8)^0x80;! J m) W! k$ W- H. \9 Q- T9 w
}" s. ~4 S. K+ Q8 H8 e, \8 C: g
1 Q0 f, m. }) @
if( nCcount < 0x0100 )! v1 i6 d7 ]/ i0 ^" K$ B7 Y3 Q
pSoundBuf[nCcount++] = (SHORT)output;- ~, ?1 H9 D6 b* \" G. k+ q5 Z/ @
5 q' K; l7 G& n" m5 t
// elapsedtime += cycle_rate;+ ]+ }! m4 ]' U2 O$ c! ^* Z
elapsed_time += cycle_rate;
# q; ] Z; R, {6 `1 \ }
6 n! P7 I3 T4 v- {) t* a7 W
8 i8 B! b3 ?/ D7 H: ^( A#if 17 ^! _* [/ H* h
if( elapsed_time > ((nes->nescfg->FrameCycles/24)+nes->cpu->GetTotalCycles()) ) {. i9 x2 |( H- i7 Q. s! _/ P9 J8 n( O
elapsed_time = nes->cpu->GetTotalCycles();
; q, x: x4 w+ S# X9 j g8 R }
6 p |: [3 M7 } if( (elapsed_time+(nes->nescfg->FrameCycles/6)) < nes->cpu->GetTotalCycles() ) {# o, a! n- |7 {' f- k5 w5 @$ n
elapsed_time = nes->cpu->GetTotalCycles();6 r' V6 S! p0 u
}, M4 s4 d$ `% v6 q" w* f) W: n
#else
( I6 G9 [$ T5 }- L( \& |2 u8 L elapsed_time = nes->cpu->GetTotalCycles();5 b6 I5 x- |* Y9 I& p0 l# A6 m. u
#endif; w# e; D3 U u$ f! z- z3 g
}
% w2 |) d! C' B
/ P9 F0 }2 z6 X. u// 僠儍儞僱儖偺廃攇悢庢摼僒僽儖乕僠儞(NSF梡)
; Q! O1 P7 E, ~INT APU::GetChannelFrequency( INT no )- y& R' j4 ~3 S9 f4 ]0 f
{+ a2 q9 h& m3 S: T# w/ P8 V8 p
if( !m_bMute[0] )
) U( T* Y# ?& B return 0;4 R0 W" _- M4 Z7 p
1 A: _1 `% R. _6 H // Internal4 r: t" f/ q2 m9 {1 S) u: U; K
if( no < 5 ) {
" d9 c5 o, X3 D6 a$ D return m_bMute[no+1]?internal.GetFreq( no ):0;1 ?. I$ j5 M' s3 H D/ i/ f3 \
}/ v+ H, i: k" H/ g" i# X* d0 N2 C; q
// VRC6* c5 N# W; [; G% w( }) P
if( (exsound_select & 0x01) && no >= 0x0100 && no < 0x0103 ) {
3 E ^# j; W2 L4 L4 {$ ` return m_bMute[6+(no&0x03)]?vrc6.GetFreq( no & 0x03 ):0;
6 S4 x5 b( h! }( y% K! X0 \" ? }2 C; ?2 g4 C3 k' @5 r0 E
// FDS
2 h8 \' a. ?% d- m6 Q& Z' x2 g if( (exsound_select & 0x04) && no == 0x300 ) {% ?) P+ S0 ]3 L% n
return m_bMute[6]?fds.GetFreq( 0 ):0;
( M" E3 |$ r/ @4 N5 L) ~; A+ \6 y+ {! @& ^ }; i& A) p5 m( |8 y. v' N! ~! O1 S
// MMC50 ?: a0 U5 X+ c* m
if( (exsound_select & 0x08) && no >= 0x0400 && no < 0x0402 ) {+ x7 A, u5 W9 s" l& _( Y4 e
return m_bMute[6+(no&0x03)]?mmc5.GetFreq( no & 0x03 ):0;
; k9 z& H/ o: z/ W3 z7 A4 S. a }. ]# E& H3 I- x
// N106
. e: W# C. f+ _$ l( E! j if( (exsound_select & 0x10) && no >= 0x0500 && no < 0x0508 ) {
4 F# k5 n0 d0 z1 @1 Q return m_bMute[6+(no&0x07)]?n106.GetFreq( no & 0x07 ):0;: L* y: M) f( b( [" S
}; G6 Q) E) \+ @$ U+ `
// FME72 Y# \( d# X _4 ]( B/ r: y: V3 ^
if( (exsound_select & 0x20) && no >= 0x0600 && no < 0x0603 ) {* U2 F- n! m# Z/ l, E
return m_bMute[6+(no&0x03)]?fme7.GetFreq( no & 0x03 ):0;. d* B/ K1 ?) ]- }5 H& x
}
: ?' o9 l, N5 a% m- |" U // VRC7" g1 T% A$ E* r4 m# r1 S$ ?& S0 q
if( (exsound_select & 0x02) && no >= 0x0700 && no < 0x0709 ) {9 x( L! f$ j7 b: m
return m_bMute[6]?vrc7.GetFreq(no&0x0F):0;% _, l. c* t8 X- i7 Q/ |
}. Y; O; Q" N+ [
return 0;
# H& I, N' d5 p}
$ _+ A1 i5 R, a% q# R3 r9 n! g5 i8 K% p' u
// State Save/Load
" |# h8 B/ F& x4 F5 z3 l& V" Fvoid APU::SaveState( LPBYTE p )2 J5 C+ v% b0 U6 W
{
7 Q9 e5 E' u& M#ifdef _DEBUG
" z) N4 D& x+ v& ]5 y# mLPBYTE pold = p; ^# n# a1 {# O, ?0 v6 K
#endif2 F" ^5 Z- a& q
8 W& w9 ?# R9 _* q7 p/ T // 帪娫幉傪摨婜偝偣傞堊Flush偡傞& g/ H) |0 d1 B6 f; K
QueueFlush();# a! ]( q3 X4 Q, P
+ w. ?( d7 J' T( ` h+ ? internal.SaveState( p );
5 f9 }4 m0 b/ t. V p += (internal.GetStateSize()+15)&(~0x0F); // Padding$ I% o+ q1 [* u+ ^, B
: h% q6 q- u* A/ n& t7 D
// VRC6
3 p' E& ~) ~7 e+ T/ [ if( exsound_select & 0x01 ) {4 x, _, g$ t+ x" @3 V$ g- a0 n: {
vrc6.SaveState( p );
$ [3 C+ K# P: ?3 ~" v p += (vrc6.GetStateSize()+15)&(~0x0F); // Padding! `+ O& j! i1 N. D
}* C' _" l; [6 g8 n% D
// VRC7 (not support)
& H; h( a# w) T6 P if( exsound_select & 0x02 ) {
* B A" `8 D4 a! j vrc7.SaveState( p );
8 j) o. |0 t% U7 ?. U5 C p += (vrc7.GetStateSize()+15)&(~0x0F); // Padding; H" G; W! A0 L$ l, Z, q* {
}, B7 K# K* w% {2 t
// FDS- o$ S2 J* B) j& Q
if( exsound_select & 0x04 ) {
3 T7 V3 R" ^% L; _# E1 b( { fds.SaveState( p );1 X+ Y% ~# W! B0 _7 ?
p += (fds.GetStateSize()+15)&(~0x0F); // Padding1 q; ~1 M6 T2 m t* w7 ~$ a
}
; R& q; }0 Y3 M; Z // MMC5: S- J+ }9 q# j* x% _
if( exsound_select & 0x08 ) {
% X+ n# c" A: m& d P; [' }' X/ E mmc5.SaveState( p );
# t4 R3 R/ o; e* | p += (mmc5.GetStateSize()+15)&(~0x0F); // Padding b' i' X/ }: T4 G1 T
}# }8 |& S1 w3 h% T( v2 W$ A- M+ b
// N1060 v' C; H i( F4 W, r' x. [9 o7 Z
if( exsound_select & 0x10 ) {5 ]: `% Q; C: H, J& A( L$ t
n106.SaveState( p );
7 ?" B0 a, u; j/ m8 P3 ` p += (n106.GetStateSize()+15)&(~0x0F); // Padding+ P3 `% A, w/ r" |+ o2 |" P
}/ g. Z& u) ]. z) k {; N7 W
// FME7$ M2 Y3 J! @3 \8 V0 ~ V C
if( exsound_select & 0x20 ) {) }8 Z3 F7 A2 G3 s
fme7.SaveState( p );
7 h2 K: q0 L; N( ^ p += (fme7.GetStateSize()+15)&(~0x0F); // Padding
0 ?; d" c" X* m }
3 m& P0 r' ]# Y e2 e7 a2 c: n7 ^+ }. {
#ifdef _DEBUG
9 ~/ S3 E: [3 ~0 |# {6 q& UDEBUGOUT( "SAVE APU SIZE:%d\n", p-pold );
! y$ C3 e( I. e5 Q, R#endif
0 r- k* |. n2 z5 ^2 u}
6 c+ g. h/ _4 Y& Y- o4 c H
. g+ g5 b4 e4 e; r" [) G+ I8 mvoid APU::LoadState( LPBYTE p )
2 G9 J. C7 d! Z& E& @! h% A{
/ U# \! m0 s n' h' z' c // 帪娫幉傪摨婜偝偣傞堊偵徚偡
w1 `6 g7 _$ c; z: G% I& C QueueClear();
" p8 k6 ]0 Z" ^7 X7 I$ T% O- v( K4 M5 w
! c2 l/ M. A5 v internal.LoadState( p ); ? e! X- y, z/ h) x$ x. h
p += (internal.GetStateSize()+15)&(~0x0F); // Padding
4 U, d* a2 ~# _6 Q% B; z5 l. ]6 \( @* G |- H
// VRC6
s5 A3 p+ U, v if( exsound_select & 0x01 ) {) C- d: `% p8 c: r( {: ?
vrc6.LoadState( p );
& E9 l% f6 {) j7 [, f. w' h p += (vrc6.GetStateSize()+15)&(~0x0F); // Padding
2 p. t z' E. P% ^4 r" [ }
' I ?) Q# w5 Z5 T* j0 A4 k2 i // VRC7 (not support)# U9 ~+ y4 Z* d9 j
if( exsound_select & 0x02 ) {
9 p7 |* x# A) M; X. P# m/ W+ j vrc7.LoadState( p );6 V. E: X0 @3 E6 O# D2 V1 p# O! t' T
p += (vrc7.GetStateSize()+15)&(~0x0F); // Padding
4 m# d, ~/ ~ P: Y }/ N- T: ^7 \$ v$ x
// FDS
6 N$ n' U6 M' t- n4 i* b, F6 ~ if( exsound_select & 0x04 ) {* ~4 Z9 m' H, V1 h1 `$ b* Q
fds.LoadState( p );7 `6 t* l; a' }# I; Z7 M. o
p += (fds.GetStateSize()+15)&(~0x0F); // Padding- F# s1 \! G! S. \: r
}
1 M$ H9 j& _, t _; B) T' s // MMC5
+ p$ |; U9 _; c) W) v w! k if( exsound_select & 0x08 ) {
: M, K' \; M, a* a6 O mmc5.LoadState( p );
6 s, O- Y' L( {9 |1 A, m p += (mmc5.GetStateSize()+15)&(~0x0F); // Padding
/ \2 v2 f3 e, G4 z+ E, F( C }
9 P0 ~$ V0 Z5 N! H // N106
; s( N4 \/ U9 {" v& q if( exsound_select & 0x10 ) {
& ~$ ~# l9 V3 l. e% }" [" ^( q9 u n106.LoadState( p );
7 ~+ D% ] `+ F- ~: R. n p += (n106.GetStateSize()+15)&(~0x0F); // Padding
, a2 k( k) O. [2 v2 z }
( D* U, W4 Z4 c: t# P: p // FME7
3 L9 k2 K6 r O if( exsound_select & 0x20 ) {
0 _, g# x& x0 l& `# |& H7 i' C8 V# u fme7.LoadState( p );
! w# `* r! S, F1 o p += (fme7.GetStateSize()+15)&(~0x0F); // Padding& K, x a w& N- W
}6 h. S" r. r! D r3 w! k
} |
|