|
|

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