EMU618社区

 找回密码
 立即注册
搜索
查看: 1318|回复: 14

[求助] 【模拟器代码问题】模拟器如何通过代码控制Rom的背景音乐

 关闭 [复制链接]

该用户从未签到

发表于 2009-11-2 22:45:57 | 显示全部楼层 |阅读模式
求助:模拟器源码中通过哪段代码控制Rom背景音乐的播放?
# h- P0 r9 M; z* [7 G. e" _4 |& UPS:看过一些模拟器的源码,大概都分为APU、PPU、NES那样几个版块。请大侠告知是哪个模块。感激不尽~~

该用户从未签到

发表于 2009-11-2 22:57:37 | 显示全部楼层
看了下VirtualNes的源码,是APU那部分,全称应该是Audio Process Unit

该用户从未签到

 楼主| 发表于 2009-11-8 09:56:34 | 显示全部楼层
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。
$ k, D& ]' e. i3 W# t& t/ X楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~  g: O7 |: S8 z) C9 [4 \4 U
这里有相应的模拟器源码,就当送给大侠了~~+ x0 Q* T- N0 `2 }: F5 @9 }
http://kenkao.qupan.com/5096520.html

该用户从未签到

发表于 2009-11-8 11:31:10 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 09:56 发表 , \3 v' J2 U9 j# Z
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。
' e+ d. I& M; E% i% a0 m3 A楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~0 Y7 X5 A, f; d. E) G3 d. S$ ^
这里有相应的模拟器源码,就当送给大侠 ...

6 ^$ S( q. A7 J( o聲音部分(Audoi Process Unit = APU):
. \  }& P  N" j.\NES\APU.cpp
( W4 y0 ^2 I4 h8 X.\NES\APU.h' x4 F* K, C. y9 R; m

  H- U/ j0 z$ ^5 S. [7 o
# @# n" }: U9 ?! s  E影像處理部份(Picture Processing Unit = PPU):! _' U) s* @9 a+ g, V
.\NES\PPU.cpp  B( M8 y" M3 n- f! C' |* p
.\NES\PPU.h1 c0 e3 I- j/ d- I2 E1 Q7 p
1 U% W* x" [' U# [! z7 X& Z
如果原碼用C跟ASM混搭也不錯

该用户从未签到

发表于 2009-11-8 13:03:26 | 显示全部楼层
楼上是高手 哈哈

该用户从未签到

 楼主| 发表于 2009-11-8 14:38:21 | 显示全部楼层
可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。
8 i& ~( V" v7 s0 ?. {* E9 z. `感激不尽~~

该用户从未签到

 楼主| 发表于 2009-11-8 14:47:50 | 显示全部楼层
这是我手中源码Apu.cpp的内容,敬请赐教:
0 ]  z3 L, ?8 U# W(由于很多专用术语和算法机理都不明白,所以看不大懂……)
7 |) Q* U  y, b% s//////////////////////////////////////////////////////////////////////////  O% Y. Q5 {" V1 J7 e- C6 Q, m8 M
//                                                                      //
  S) r% \  V1 z//      NES APU core                                                    //% ~6 G& R9 _" ?- L# D& q
//                                                           Norix      //
% K2 O3 z& z, o: t) h//                                               written     2002/06/27 //
2 @: w1 |& s( I# D+ i3 p//                                               last modify ----/--/-- //
$ }. ]( H' Z& B! \% s7 e//////////////////////////////////////////////////////////////////////////1 ]8 b+ V+ z9 A( `- b
#include "DebugOut.h"
, [- {" P4 v5 J$ K1 [& F#include "App.h"
' z, U5 ~6 P; u9 N5 j#include "Config.h"
+ O5 E3 A1 j/ o- z3 R) {/ C; s0 K- U# @  `" A
#include "nes.h"
/ d5 U  C$ q) d$ f0 ~#include "mmu.h"9 r5 A6 a0 c/ m0 o
#include "cpu.h"
1 q7 ], z* q# ~/ L) S#include "ppu.h"
# G( _+ B- R- y#include "rom.h"5 t% k  I  K& S
#include "apu.h"* r$ _  |. n5 ]8 H& k* y4 o* K2 K& m

9 R' C$ Q& G, Y" [+ t% k8 @// Volume adjust
! g3 |9 A. V0 \// Internal sounds- p8 f5 n8 {9 \& i3 t7 |' z
#define        RECTANGLE_VOL        (0x0F0)4 T. ~# F" E- j! }' |
#define        TRIANGLE_VOL        (0x130)0 [+ K2 a0 K! S$ S1 ~
#define        NOISE_VOL        (0x0C0)# u+ B" c% A6 i) q
#define        DPCM_VOL        (0x0F0)
$ P. o. }7 z! A& @// Extra sounds
8 u( |0 h% s5 ^2 f6 h#define        VRC6_VOL        (0x0F0)# [  I4 f; c4 S
#define        VRC7_VOL        (0x130)
0 ?0 Z: c1 n( J' g#define        FDS_VOL                (0x0F0)
, e  C3 G/ R9 G4 r8 C#define        MMC5_VOL        (0x0F0)( h5 ~2 |7 l7 P% C. w; l, r; L
#define        N106_VOL        (0x088)
' k8 w6 C' y* a8 z3 U+ [; z& Q#define        FME7_VOL        (0x130)
6 S2 O* u5 a. C5 Y0 r
0 e$ X& O, O! @7 C8 u; a+ e" k! {APU::APU( NES* parent )* A0 Z! w/ P5 p$ W3 Y/ W
{( g/ ~- Y1 R1 e8 g
        exsound_select = 0;
% @) d! y* h& q7 y0 h( T
& D9 A% E3 j: r9 ]# ~        nes = parent;7 I8 i6 ]. R* n
        internal.SetParent( parent );) u: o- q! N$ v  `2 h
5 H6 g5 E& u: R  g( C, d
        last_data = last_diff = 0;' n; F8 H6 ^: n" H' M, V2 y

% s: |" Z2 Q2 q+ c0 _* a% _9 D2 Q        ZEROMEMORY( m_SoundBuffer, sizeof(m_SoundBuffer) );
6 K- M$ k; o4 h/ o$ i) p2 a0 A, Q
0 J/ s1 T1 o) m6 Z# w; b% d3 h        ZEROMEMORY( lowpass_filter, sizeof(lowpass_filter) );/ M) D& Z. i/ }& [2 b! w- y' M4 n
        ZEROMEMORY( &queue, sizeof(queue) );6 x9 F! _# L6 F0 W: P% {) e
        ZEROMEMORY( &exqueue, sizeof(exqueue) );
) A' e+ x. D! E  Q9 }0 ]
7 T& W! u  j4 `6 X* ?: r0 z* k9 J        for( INT i = 0; i < 16; i++ ) {
( X8 c3 u# e( a) q9 f0 H. y                m_bMute = TRUE;+ ]' q2 Q) j6 v
        }
  w( _' T: z, |) y4 q9 H6 g# s: ]}
2 r3 a+ a: A% R8 y- \1 D+ q6 A0 j" c
APU::~APU()
! r2 X, t1 Q* {( H, h# ^{
' s; ]2 h) G0 [7 n4 `8 _- Y}3 o% j  n8 d( A0 C7 K
5 T; S: O9 J# c" e/ ?- C4 `
void        APU::SetQueue( INT writetime, WORD addr, BYTE data )
+ o( C( U+ R( I{
( k$ O) J2 W7 a0 \  G' Q        queue.data[queue.wrptr].time = writetime;
5 `1 d) }0 A7 B) M2 p        queue.data[queue.wrptr].addr = addr;
- J: T9 \% _; ^6 t. O        queue.data[queue.wrptr].data = data;
* P9 t0 X# O" S& J% R% M        queue.wrptr++;1 t' u4 |$ V8 Y5 J
        queue.wrptr&=QUEUE_LENGTH-1;$ D' @& _. K& I
        if( queue.wrptr == queue.rdptr ) {
: B$ Z. v: c8 R! O, v4 A! Z% G                DEBUGOUT( "queue overflow.\n" );8 t0 {$ Z; q0 q) k; V/ h- X
        }
+ U: m# U0 p9 b}
0 I: ]' ^9 N! c2 m- G( u1 z
9 X7 [6 v6 G4 S. bBOOL        APU::GetQueue( INT writetime, QUEUEDATA& ret )7 e) [( j7 h8 [- q
{
, N% M" [) _2 L& i! b- b5 ~2 }  i        if( queue.wrptr == queue.rdptr ) {2 [; w) n* A# n* F3 @6 B
                return        FALSE;! h0 i, B% t0 f7 S
        }$ C# m6 x1 ~' I, o0 _! k
        if( queue.data[queue.rdptr].time <= writetime ) {
5 d' p4 j/ K% H                ret = queue.data[queue.rdptr];
9 V! m+ ^* W# J; h                queue.rdptr++;8 ]& p& Q( H4 ]% a, I# T+ i
                queue.rdptr&=QUEUE_LENGTH-1;, z7 v# k9 ~: l* ]. ]! P7 p/ r
                return        TRUE;; Q( P0 K3 S8 S* E) i: a8 T4 G9 A
        }  R4 ?! b0 U: m' ^! U! s
        return        FALSE;
; P6 X* B) M" a  c5 K. @, G" ?}
+ ?# L8 H: ~  H4 G- @' l6 ~' {0 s/ t. y% u
void        APU::SetExQueue( INT writetime, WORD addr, BYTE data )" g2 N5 E  @# a( c! R+ q
{
! i6 a; E, K$ C  R: E' ^        exqueue.data[exqueue.wrptr].time = writetime;
/ ]$ j9 V( h; D        exqueue.data[exqueue.wrptr].addr = addr;6 I: O$ z+ E: y' A5 O5 H: U! d5 \6 D
        exqueue.data[exqueue.wrptr].data = data;
! \' g4 Y/ H8 q/ E3 [- i        exqueue.wrptr++;
: z4 ^1 g& v! t7 C6 t        exqueue.wrptr&=QUEUE_LENGTH-1;
7 `( G1 v, Q) b5 r1 @        if( exqueue.wrptr == exqueue.rdptr ) {; m/ c/ B6 T9 ~6 R! a7 O3 H7 `
                DEBUGOUT( "exqueue overflow.\n" );% i$ K2 }  z0 T. P9 \! k
        }
7 A+ O6 s, s7 d9 E6 z, `}
9 x5 a& `" b0 o; t
5 ^* {7 i8 g8 p- {$ H- o* {, S$ hBOOL        APU::GetExQueue( INT writetime, QUEUEDATA& ret )
! _% k$ n+ Y. t' e{/ E. y. z# @' @, H
        if( exqueue.wrptr == exqueue.rdptr ) {
$ X: k+ s. R( y: B+ V; f- y                return        FALSE;, @2 I2 [. U* d7 [8 q" Q
        }! X0 M, u) N$ G: [# R( n4 s1 A
        if( exqueue.data[exqueue.rdptr].time <= writetime ) {( K( P2 d# `$ s/ O
                ret = exqueue.data[exqueue.rdptr];
6 W, s( F. p3 U( n6 ~                exqueue.rdptr++;, ]! D  t/ _3 x; [4 e" f. f
                exqueue.rdptr&=QUEUE_LENGTH-1;2 {6 l0 z- k+ {- i
                return        TRUE;" q" t/ B" u9 i6 j! S
        }( @! m4 \0 s; i: f* N4 M. v
        return        FALSE;( s- @+ m# H# d) B6 r- i
}
# C3 y8 z! ?9 W. S& h! K9 E7 d) v
void        APU::QueueClear()
: ^4 V  b- A# S& w' Q{
/ G1 y, a* s9 C' f7 ~" K4 x        ZEROMEMORY( &queue, sizeof(queue) );- d' y0 M, ^+ v+ T# k9 P) J3 k
        ZEROMEMORY( &exqueue, sizeof(exqueue) );8 Q5 o9 k- U6 k% |8 g7 Q  d, h% }
}, }2 r; X* l  u- z$ X

  h! G2 Z6 ?5 a" M9 R+ ~void        APU::QueueFlush()
# Y7 U, d+ {3 v  O" p{2 [0 v% {: S1 y' c5 A7 B' G+ }
        while( queue.wrptr != queue.rdptr ) {/ M- l0 L0 p8 K/ J/ O: G& M
                WriteProcess( queue.data[queue.rdptr].addr, queue.data[queue.rdptr].data );+ h( L5 O  ?# S1 L1 l" y; K
                queue.rdptr++;
7 k# _$ s; Z) U% ?                queue.rdptr&=QUEUE_LENGTH-1;
* h5 p7 b: Q* D( c1 \        }
1 p9 t. M, y$ N4 D6 o4 {+ h* y8 o# K' n0 c; d
        while( exqueue.wrptr != exqueue.rdptr ) {/ m. S" S" _9 v. H4 v% l' _
                WriteExProcess( exqueue.data[exqueue.rdptr].addr, exqueue.data[exqueue.rdptr].data );
$ ]3 U, G+ {6 w. Z+ b1 \/ c' _# z                exqueue.rdptr++;
- L* R& W/ o2 h5 i% w0 `' R                exqueue.rdptr&=QUEUE_LENGTH-1;, F* m2 e( B: y7 E- y& ?) B: F
        }
8 E5 Q' |9 X5 G) `$ ^0 m. e}# B* k( M; p7 {9 j; T
3 z5 h# H8 u/ N. M
void        APU::SoundSetup()
# c# R8 n0 F( k5 l{$ i# Z! _1 L7 H$ ?9 n+ P! ^
        FLOAT        fClock = nes->nescfg->CpuClock;3 X$ m+ P- n% U4 z( S
        INT        nRate = (INT)Config.sound.nRate;! o  J! t; q9 ~, s! k
        internal.Setup( fClock, nRate );6 l2 L/ Q. y1 y9 ~
        vrc6.Setup( fClock, nRate );
' T$ b9 k  |# N3 y        vrc7.Setup( fClock, nRate );9 P, F% ], U0 Q& J9 O0 R
        mmc5.Setup( fClock, nRate );6 y) }1 K& j) e+ d! J# y2 x
        fds.Setup ( fClock, nRate );
) b& C# Q, N0 e( G9 Y- A/ B  Q- ?& s        n106.Setup( fClock, nRate );
+ E1 f$ p+ P4 d9 |( F4 E6 z        fme7.Setup( fClock, nRate );
1 C" |: _3 A3 c" O' l}
) O0 p' y* a0 A% v& t# ^; S5 g9 u) O( Z9 v- l
void        APU::Reset(); r8 N! k- K& r8 E
{
4 }6 z) I0 W6 R. w% T( T        ZEROMEMORY( &queue, sizeof(queue) );0 R$ {  f( D  C1 Z8 z, O0 g
        ZEROMEMORY( &exqueue, sizeof(exqueue) );
. p2 O5 {0 c# Q. o  I$ X3 a' W; r! \! {0 k# i% e0 N
        elapsed_time = 0;
5 m* y: `0 I2 G. a3 d* B4 D
- |, F7 f2 r5 M1 {  `6 x  [        FLOAT        fClock = nes->nescfg->CpuClock;+ ~6 C. ?8 k% a
        INT        nRate = (INT)Config.sound.nRate;
7 G5 q3 ]3 \4 P        internal.Reset( fClock, nRate );* b/ ]; F' p. e9 \! r5 O
        vrc6.Reset( fClock, nRate );
6 s5 q. \8 G8 P* H4 E        vrc7.Reset( fClock, nRate );
% x$ B  O* g8 Y- E& E/ k        mmc5.Reset( fClock, nRate );0 Q. m6 X* _" y2 v3 x
        fds.Reset ( fClock, nRate );
) F# M8 ]- P/ ]% c+ H3 a/ W- [8 J* z        n106.Reset( fClock, nRate );
) K7 f/ _% U3 \* |$ D% {        fme7.Reset( fClock, nRate );
5 w+ q( E) p2 q5 s+ N9 Q
5 M6 P1 `$ Z6 f& E) t6 l4 \7 e9 c        SoundSetup();
3 f4 k+ j; Q3 S( D& S/ I0 _( f}
7 c+ T6 C# l( I* A& N5 P7 a/ g  F5 J  w& O" Y* y+ H
void        APU::SelectExSound( BYTE data )
- Z8 U$ u4 o' @( }) _! r{9 f4 G: z) @. W+ L. g
        exsound_select = data;
' _- C, \. m1 n* O/ _8 K}  H* x7 p! s) Q; k* u4 a/ l
1 A: {8 I! S1 \0 j2 y0 ]2 P
BYTE        APU::Read( WORD addr )& ~; _) U  o6 e( v" R, f0 Y
{' H5 L$ w+ z# m) h2 x% G3 b0 Y" t- X
        return        internal.SyncRead( addr );1 e$ a3 h* B3 y& R" h' P
}
8 t5 w* A. i* y# X0 G8 j% z3 F- D. ]9 i( r# _& a
void        APU::Write( WORD addr, BYTE data )
7 S+ E+ w' \* |9 H2 J{+ W: f" ^# B5 x% z# b3 ?9 E
        // $4018偼VirtuaNES屌桳億乕僩
& Q8 g& c! [$ e  G        if( addr >= 0x4000 && addr <= 0x401F ) {' F# u7 a4 H% @: ~7 y. R5 n
                internal.SyncWrite( addr, data );
1 p$ b) p+ Q, `                SetQueue( nes->cpu->GetTotalCycles(), addr, data );
( b4 U! \+ N. J/ M0 c/ J        }7 B8 o! f7 M  o* X
}: Z5 I4 m7 j! F0 U2 G& J' \

. ~4 K/ f3 W  F! y3 x5 EBYTE        APU::ExRead( WORD addr )4 D. P# W% C0 \7 y" _
{
' N4 g8 E. B) M, ^BYTE        data = 0;6 w; U$ e& c6 f2 x) `

! z5 q9 L% J5 G' m/ ]0 Z        if( exsound_select & 0x10 ) {3 ^& W* _* {* A2 p. R( Z  H
                if( addr == 0x4800 ) {$ ?! X4 I+ w; h! `4 a
                        SetExQueue( nes->cpu->GetTotalCycles(), 0, 0 );
6 D5 k  }& C/ e. x, _8 U                }0 Z# f/ ^5 A! d
        }6 A7 h* s( V" V
        if( exsound_select & 0x04 ) {1 ^  X2 E; G3 n
                if( addr >= 0x4040 && addr < 0x4100 ) {- A: f2 A) i* N
                        data = fds.SyncRead( addr );5 Q: r  b7 ]8 q3 D/ N0 |4 v
                }: H8 z/ w2 H, C8 U& k2 u6 r1 b$ k
        }
/ \4 o  l  B" |9 s/ q        if( exsound_select & 0x08 ) {
4 t8 [! }. N' x$ o1 |. P* {, [                if( addr >= 0x5000 && addr <= 0x5015 ) {. R* k' i4 ?- e! B2 n4 o7 a
                        data = mmc5.SyncRead( addr );& Y- X$ t" a8 T) ?6 G9 {
                }+ y2 l2 b9 c5 B( {5 |! G4 E
        }9 M6 a+ x) ~$ q7 V" Z
/ r& U$ x0 u7 S0 p1 D
        return        data;/ m1 t3 A0 R% n4 b' D- w+ }
}( Q) W  R, l7 m4 L4 {

) Y2 }, u9 U( @! G$ ^: z- pvoid        APU::ExWrite( WORD addr, BYTE data )
6 X, k! A8 \0 l2 M  t0 t{1 h( U* v% B; R, o. F1 j( |3 u
        SetExQueue( nes->cpu->GetTotalCycles(), addr, data );" ]; P9 O1 Y" `% m; ?8 B5 @& V
/ O- N: Y( Y5 y; _
        if( exsound_select & 0x04 ) {
' n* s# R$ R7 K6 H" v; i                if( addr >= 0x4040 && addr < 0x4100 ) {+ h7 G/ q9 k1 @  Y' ~5 d
                        fds.SyncWrite( addr, data );5 a" e: j7 W# Y& |& K  J- E
                }  H( N3 M! o; ?1 w) E
        }
- v6 o8 G5 a6 A: k( E% y
/ R9 [' y: C) H; `        if( exsound_select & 0x08 ) {  P( @% ?; y; }8 [# W' E& y3 m2 B5 N
                if( addr >= 0x5000 && addr <= 0x5015 ) {" E7 M0 B* P. m# n8 h- x5 ]
                        mmc5.SyncWrite( addr, data );
! j  E6 l4 c' k6 a# C                }
7 j# A8 \7 c, F( `$ a: F        }  S: w4 \2 B5 m; }: x
}' X9 V# Y- }* a) o# Y0 c! U
7 c( {+ B/ J7 ^; {: Z; i+ W
void        APU::Sync()+ M& M4 g# S" Q& j; I
{
5 M1 J4 h% J' y, W5 p/ C}. [8 q, Z: H+ N& t3 `$ o7 C2 R9 v

" D& M3 B$ q( `* H  cvoid        APU::SyncDPCM( INT cycles )- X0 |5 W. g* r( [7 ]; r
{. [% P. g6 f$ ~9 h8 u
        internal.Sync( cycles );" c: p! Q# W* S" S$ Y6 o# {1 c

0 J( e. k* x8 k: z* v: x7 Z( G        if( exsound_select & 0x04 ) {
3 `7 z1 `/ g% I( o; M3 i0 g5 L                fds.Sync( cycles );+ _. w8 V) d; ~
        }
  V3 i2 x1 C" [2 x5 N( x* N        if( exsound_select & 0x08 ) {1 d, F7 J4 ~. T9 }& N6 M' r/ `3 T
                mmc5.Sync( cycles );1 A, O! D: h6 u6 H- Y9 W
        }, z. \, a( |# P5 Z% P
}
" m7 q+ q; |+ {- e6 [1 |4 i2 C1 O
void        APU::WriteProcess( WORD addr, BYTE data )
7 ~: U" \  Q2 ^! T6 b5 y{3 J  d4 p: b5 Y5 b
        // $4018偼VirtuaNES屌桳億乕僩" l: M- E0 p/ H; t- w
        if( addr >= 0x4000 && addr <= 0x401F ) {
  j) X& f' ]8 k# m                internal.Write( addr, data );+ d- \# ~1 Z/ g# A" {( z
        }  n. {. z; M  p! |) ^
}+ Y% u' y* S' N! _4 G. j
9 v% V' {* m- W0 l8 z& H
void        APU::WriteExProcess( WORD addr, BYTE data )  L. \! l+ j4 D5 r4 g9 R) P: F* U
{
( N( q) \0 B2 [7 X+ {$ _        if( exsound_select & 0x01 ) {- T( ~9 c2 N- S
                vrc6.Write( addr, data );
9 ~6 e2 p0 ]  s* ~* v% F        }- ]. B$ b- q. G
        if( exsound_select & 0x02 ) {
+ u5 v# e( v  j& P                vrc7.Write( addr, data );
3 M! p2 V! S* C3 \1 i- W        }
; o- m; C; p. y3 z        if( exsound_select & 0x04 ) {
0 _8 ?; c6 Q: q* t                fds.Write( addr, data );  X$ V$ K2 o/ y$ w1 X' B
        }
% X& N  A8 i8 q6 u* K* x) d        if( exsound_select & 0x08 ) {
8 S4 D' P8 E1 m0 c                mmc5.Write( addr, data );$ k8 D! e0 L8 |. P4 T
        }
' U$ W, ^. |) `/ }1 W        if( exsound_select & 0x10 ) {
3 g( p2 j, B7 Z' O) h- @                if( addr == 0x0000 ) {
4 j& P9 N/ x+ b. s$ X                        BYTE        dummy = n106.Read( addr );6 t4 ]. I* A$ {/ P* n; |: i
                } else {( L% b& s7 L( k( x2 [
                        n106.Write( addr, data );# @/ |, m4 a8 R
                }
- k+ n7 Y4 \* U0 @( k% ?4 d) A        }. a# ^" M. z5 Z6 W
        if( exsound_select & 0x20 ) {9 J" ~9 f0 Z0 b3 j& |
                fme7.Write( addr, data );
5 f! J" M+ }7 g9 w8 k8 a        }! M5 J% }" p0 Y7 l
}; {6 P% u5 ~0 A. N

2 S4 m# Z6 `; o& R& Kvoid        APU::Process( LPBYTE lpBuffer, DWORD dwSize )0 f3 g' W$ c6 W2 T
{
( T; }" D  y) B7 v1 g3 AINT        nBits = Config.sound.nBits;
2 S. R% h' E4 R  D# sDWORD        dwLength = dwSize / (nBits/8);9 x8 M' B# s! [% S% P) _
INT        output;
& B( K  B7 B  ]6 T# i, ]! wQUEUEDATA q;! m. z; Q8 P4 g* b! x7 J# w
DWORD        writetime;9 z4 {0 X* k7 k  E  e, S' q
5 i7 }! S3 H+ |/ O4 w4 R. D3 F: c! e
LPSHORT        pSoundBuf = m_SoundBuffer;
+ C  Q/ O. Z7 i( uINT        nCcount = 0;8 [% R- N& `% X8 o5 @! Z: _

. v) H  G$ Z1 ]2 |/ q3 ?  Q- J4 DINT        nFilterType = Config.sound.nFilterType;
7 p; I1 @, T; @: M+ }4 e- ~% `  ?1 E% n' R' g* a$ h
        if( !Config.sound.bEnable ) {' M6 f! f7 C) ?; Q
                ::FillMemory( lpBuffer, dwSize, (BYTE)(Config.sound.nRate==8?128:0) );
6 C* m, l, a8 v9 \/ V2 x& q                return;
7 }# E2 T& P4 e* ^  K        }
. v7 e2 ^% T( T- f' ~7 s8 A
; g/ ?. U3 R. x) Y- |9 F        // Volume setup6 E) l% V3 \. i' H
        //  0:Master
$ N0 _) ?8 ~) c# `! n  I& w' \% w        //  1:Rectangle 19 ^! ^* X1 P$ A/ Y9 U
        //  2:Rectangle 2
# W; L7 U" [, c2 O6 H        //  3:Triangle
2 ~: Q5 N4 [8 F( J) t        //  4:Noise
, Q3 I+ J* ]. e3 J, W  ^        //  5:DPCM6 i7 T! r( p8 T$ [$ w, [$ Q" @
        //  6:VRC60 d8 v* H! I% i+ ^4 R2 A: k
        //  7:VRC7. Y7 i8 s2 S' [0 G6 D4 Y
        //  8:FDS" J7 I# u% q0 S5 t0 t6 I
        //  9:MMC5( Q3 Z) o$ k8 `% @$ r
        // 10:N106" N+ w# @1 Y5 G9 g+ H% P4 ]$ h4 D
        // 11:FME7
0 o1 t) q1 e2 |        INT        vol[24];5 B5 l3 l, h9 K/ \, w
        BOOL*        bMute = m_bMute;
* k( A3 p/ i7 J5 b5 f9 i# r        SHORT*        nVolume = Config.sound.nVolume;/ ?$ y6 b0 r, i4 k4 o, z

0 I: ?' M/ T+ x        INT        nMasterVolume = bMute[0]?nVolume[0]:0;
, t. p3 `; b8 E2 `  a
3 S2 |: v& G2 b% Y3 \. M        // Internal
, c2 F3 l+ h2 K* H; V% c9 E        vol[ 0] = bMute[1]?(RECTANGLE_VOL*nVolume[1]*nMasterVolume)/(100*100):0;; d. y8 z/ L8 I; F7 u' g+ Z( Z, ?
        vol[ 1] = bMute[2]?(RECTANGLE_VOL*nVolume[2]*nMasterVolume)/(100*100):0;% g0 N' K  ?- N4 V) j$ M) S& M
        vol[ 2] = bMute[3]?(TRIANGLE_VOL *nVolume[3]*nMasterVolume)/(100*100):0;& o$ d5 f2 e/ Z4 \& x
        vol[ 3] = bMute[4]?(NOISE_VOL    *nVolume[4]*nMasterVolume)/(100*100):0;" L0 X, f& S) R0 {6 I) Z2 V
        vol[ 4] = bMute[5]?(DPCM_VOL     *nVolume[5]*nMasterVolume)/(100*100):0;
8 @9 n6 v) R, r: F
# p/ o5 S4 E' p6 y8 S+ c9 l        // VRC6
* I% a5 P: p" M  O& M0 h        vol[ 5] = bMute[6]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
+ `' U4 I% ?8 `  y        vol[ 6] = bMute[7]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
1 E* ]) ?" d" n: ^0 \        vol[ 7] = bMute[8]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
5 z+ \, V) k. H: s' E+ t) A# y  G* R/ N3 ^' k2 L7 a" E- P0 T0 ?) U
        // VRC7  d9 T, G! C" d7 v4 |" ^
        vol[ 8] = bMute[6]?(VRC7_VOL*nVolume[7]*nMasterVolume)/(100*100):0;
4 G: h/ `' M0 ]/ @6 y# F
  X. M1 q5 ?2 }. I6 |9 p" {- Z: n$ w        // FDS: i* p; X/ {) P  q! g. L
        vol[ 9] = bMute[6]?(FDS_VOL*nVolume[8]*nMasterVolume)/(100*100):0;3 K6 ?1 E" ]' N  a; `
  a! {4 i6 J' ?% X4 e) z4 T' ]- w
        // MMC5
, {& a* i4 \" b: r8 K/ D/ x" H        vol[10] = bMute[6]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;; g* \% N! r' }( G
        vol[11] = bMute[7]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;1 l+ L8 V3 k6 P/ d* ?9 ]
        vol[12] = bMute[8]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
# B9 \! [! x" ^  s2 k6 S8 i% Y: p2 I
        // N106& J3 I4 u: s) \5 {
        vol[13] = bMute[ 6]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;9 {4 W  s- D5 l; h4 j( ]" Q. c
        vol[14] = bMute[ 7]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;' {: x2 n9 i+ s- s, Q) c9 p
        vol[15] = bMute[ 8]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;; a( `. p) D& O6 E
        vol[16] = bMute[ 9]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;. Z% J" a4 _% t3 c, D% c) R; ?
        vol[17] = bMute[10]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
& I5 v" z" k8 h) ?        vol[18] = bMute[11]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
" V) N; O- r# r5 A3 q$ L        vol[19] = bMute[12]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
$ I+ {0 ~8 t4 i7 J% n/ n0 s        vol[20] = bMute[13]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
- T1 r& a7 \1 Q+ A( f$ C+ P: B' I7 [- m' Q  i! C' J, U
        // FME7% S: _. w2 w+ b. {: |
        vol[21] = bMute[6]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
1 W0 G1 d6 l2 b$ V( q% n5 q        vol[22] = bMute[7]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
1 y: x1 H) a/ o/ [+ h) `6 \" @& G5 h        vol[23] = bMute[8]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;' M3 ?1 {! N3 ~
2 g# E* j# w) r% v$ v1 H! z$ F1 }
//        double        cycle_rate = ((double)FRAME_CYCLES*60.0/12.0)/(double)Config.sound.nRate;, I: [6 @( V% r6 l2 R
        double        cycle_rate = ((double)nes->nescfg->FrameCycles*60.0/12.0)/(double)Config.sound.nRate;
1 f: f. ^: i& k3 w& \* H
8 C3 T; Q4 S+ @9 t8 y0 p        // CPU僒僀僋儖悢偑儖乕僾偟偰偟傑偭偨帪偺懳嶔張棟8 }) H2 }6 S- t9 f2 p) x2 w" d& m
        if( elapsed_time > nes->cpu->GetTotalCycles() ) {
( {1 ^: P, V: P2 M( q6 G  s, M                QueueFlush();
- h3 v1 I. n8 z1 D        }
4 [* A  ]$ y+ G; M
/ d& E9 `% i7 e        while( dwLength-- ) {' v9 I/ X& l. D+ I
                writetime = (DWORD)elapsed_time;
+ G. K  W: N4 [  V1 a) n
& P/ C! k/ Z' I1 k                while( GetQueue( writetime, q ) ) {0 D! r! ]" n4 ]: y
                        WriteProcess( q.addr, q.data );! [/ R$ ^7 n" D
                }% \" d& X! @. r# ]4 I( \5 ^

6 P! Z: l& a1 A; Q" P( A, k                while( GetExQueue( writetime, q ) ) {- }* l  |2 _% x1 b" b
                        WriteExProcess( q.addr, q.data );8 m; Y4 b" q0 n8 G2 f) C1 }
                }% J+ v/ K- E+ F+ B; P4 ~

) R2 [) J% P5 W; ]: E                // 0-4:internal 5-7:VRC6 8:VRC7 9:FDS 10-12:MMC5 13-20:N106 21-23:FME7
3 t3 n. `* `2 q# O: b2 y                output = 0;$ `) X6 c: O3 k5 S
                output += internal.Process( 0 )*vol[0];' [, w% j: r3 S: a6 }9 Q
                output += internal.Process( 1 )*vol[1];( v5 x8 x* O' X
                output += internal.Process( 2 )*vol[2];
' N) t# R# F* _& I                output += internal.Process( 3 )*vol[3];! @: X0 u8 w# t, ?. N5 z
                output += internal.Process( 4 )*vol[4];) {( b2 h% N' _& c1 |- K
$ V/ [9 W1 ?3 G8 D. L
                if( exsound_select & 0x01 ) {
2 M" Q# _7 Q' P                        output += vrc6.Process( 0 )*vol[5];
; n8 E; L8 Z( Q  V& P                        output += vrc6.Process( 1 )*vol[6];
  {- B5 o0 p& {* o; j                        output += vrc6.Process( 2 )*vol[7];% o$ H6 \4 j4 C/ f) g& q! h5 L
                }
  Q; v8 w; S1 j" V                if( exsound_select & 0x02 ) {
4 o" Q+ J% b0 E2 ]1 o* H' A                        output += vrc7.Process( 0 )*vol[8];  S  \+ i0 o7 F( {) S0 `( T/ u: X4 [
                }8 c5 ~: Y' F' Y0 K. I( f
                if( exsound_select & 0x04 ) {
0 m" N, j. C# Y: S                        output += fds.Process( 0 )*vol[9];4 }* R% h9 k; Y3 y
                }
$ i) c4 K9 |4 l# K$ `) z- ]                if( exsound_select & 0x08 ) {
9 Q6 g  t5 _3 I" g! a  s                        output += mmc5.Process( 0 )*vol[10];9 I9 p, v0 K1 e, \5 i$ Z% X7 ?8 S" V
                        output += mmc5.Process( 1 )*vol[11];' U  L% ?$ \& r  y: Z
                        output += mmc5.Process( 2 )*vol[12];1 p2 N% I  p! `7 L' N6 c& N
                }. ^. W' \2 i* u$ M
                if( exsound_select & 0x10 ) {0 F( r! {8 m6 j$ ], }
                        output += n106.Process( 0 )*vol[13];- H& ], C' s9 W" e8 c& S, L
                        output += n106.Process( 1 )*vol[14];
# u" M& p1 S8 n. v) X( R% c                        output += n106.Process( 2 )*vol[15];* X6 x+ W7 x7 I- `( |3 e. Z
                        output += n106.Process( 3 )*vol[16];
) U' S+ t5 P6 x7 e/ h# z( u                        output += n106.Process( 4 )*vol[17];
- s) |' X2 Y- a) k1 p$ w$ L# ?  f                        output += n106.Process( 5 )*vol[18];
( g2 G+ Y( }7 {- {% }3 K                        output += n106.Process( 6 )*vol[19];
4 n! x' b6 ]$ |# ?                        output += n106.Process( 7 )*vol[20];. E7 E4 |) _  B% d; @) v* y0 j
                }
; T: S  N2 r/ U- l                if( exsound_select & 0x20 ) {
* i( q  S% X1 B- h! L1 ?                        fme7.Process( 3 );        // Envelope & Noise8 m3 `/ k2 D# O* y
                        output += fme7.Process( 0 )*vol[21];
4 p3 h: p' m- O& T                        output += fme7.Process( 1 )*vol[22];
! y! [! B$ y; [8 S; i4 {                        output += fme7.Process( 2 )*vol[23];
/ Q9 _$ a* s4 h1 Z4 z                }
9 y# G7 m7 S4 H
9 Y7 T1 C$ d  e! ?6 E( d                output >>= 8;
. r& U, U  L" g. p
8 t% R; U/ X" s; }; f/ F                if( nFilterType == 1 ) {
/ R! R+ x4 ?3 D% L: m                        //儘乕僷僗僼傿儖僞乕TYPE 1(Simple)
1 O- y. I# X& \5 e8 s( c9 g                        output = (lowpass_filter[0]+output)/2;2 g; o/ P, m/ k/ Y
                        lowpass_filter[0] = output;
: S( E4 s6 T0 l) [                } else if( nFilterType == 2 ) {1 I8 r8 ^- `3 F4 P0 Y& \
                        //儘乕僷僗僼傿儖僞乕TYPE 2(Weighted type 1)
( U  W* W3 _7 D                        output = (lowpass_filter[1]+lowpass_filter[0]+output)/3;* Y7 V# O1 T7 J$ t" ?
                        lowpass_filter[1] = lowpass_filter[0];
. ]% m) }$ S9 c% o" J8 P8 ~4 B                        lowpass_filter[0] = output;2 G0 S5 B( l" K4 e1 I' l4 |
                } else if( nFilterType == 3 ) {6 d: z$ M( c. S" H  A; N
                        //儘乕僷僗僼傿儖僞乕TYPE 3(Weighted type 2)  ~; g$ \$ X3 @4 Q
                        output = (lowpass_filter[2]+lowpass_filter[1]+lowpass_filter[0]+output)/4;
6 z) l3 x$ u+ q7 N2 s$ Q                        lowpass_filter[2] = lowpass_filter[1];
. q( Y7 B! A7 x: D* b; O# @                        lowpass_filter[1] = lowpass_filter[0];. E1 C; v5 O$ p. L! b7 R
                        lowpass_filter[0] = output;0 J' o: j8 n9 p# I8 K
                } else if( nFilterType == 4 ) {
: n* y% K8 C- A% g7 i                        //儘乕僷僗僼傿儖僞乕TYPE 4(Weighted type 3): A- i" q8 J. Z9 X
                        output = (lowpass_filter[1]+lowpass_filter[0]*2+output)/4;
+ R; q/ o0 [. s' C/ p) z                        lowpass_filter[1] = lowpass_filter[0];
) W  t  \  |3 ^( N& `* g                        lowpass_filter[0] = output;3 M: f" h- J2 Y/ Y* `
                }
5 \$ g$ s9 L4 ?/ p
& e9 S$ L2 [+ N4 V2 g4 E#if        0: v* c& d% {& d
                // DC惉暘偺僇僢僩
% e  Y$ @# o5 c7 I& T! V9 S                {
! F. y* h6 k# N6 g: E8 b6 R5 z" V                static double ave = 0.0, max=0.0, min=0.0;
) s7 B# t- D2 R$ d4 B. f9 N$ t                double delta;
8 j0 ?% U$ I3 U5 j; d9 c. D$ o8 h                delta = (max-min)/32768.0;
7 b  [2 h# e0 V0 f/ H8 g                max -= delta;2 w3 t+ \8 E5 K1 Q7 L. r* h" m
                min += delta;
' ]+ [- X' e! d4 m; a4 j                if( output > max ) max = output;
$ S& @' |  i3 |6 \& Q                if( output < min ) min = output;
4 Y0 H0 t; [, \) w0 B, ^                ave -= ave/1024.0;
0 U( [  X' E; v7 q- e                ave += (max+min)/2048.0;
$ Y- ^; l( S; C  T& ^                output -= (INT)ave;- Q8 F- Q$ B) P( C( N
                }6 V! D4 {2 ?/ Z5 n. B& t
#endif, g' s" G+ J: n0 z/ u$ V, k
#if        1
0 {& G( X, Q5 r# c  M$ T2 _- ~                // DC惉暘偺僇僢僩(HPF TEST)2 C, m) `9 m) Z% e! A
                {* X' j8 Q- C  z) a" z2 j
//                static        double        cutoff = (2.0*3.141592653579*40.0/44100.0);
: ?" [7 P0 u% g* J                static        double        cutofftemp = (2.0*3.141592653579*40.0);
! O& r% b' ?7 r( K- }) ^                double        cutoff = cutofftemp/(double)Config.sound.nRate;7 F4 J* n: [' M1 `" F9 ]
                static        double        tmp = 0.0;
$ }2 [5 y' U% ~# n; l3 D# ]                double        in, out;( y) }" X% {( O5 Z5 y+ p* R$ E
2 ]8 ?/ A# p6 D! t: a
                in = (double)output;
! ^* W/ c! h8 {- d; J+ a                out = (in - tmp);
2 K/ h9 [! u3 ?% P. V. r9 w                tmp = tmp + cutoff * out;
! w- y3 m) p1 F3 c4 P# `
+ B# S" U  y  H( a# Y: Z. x% w1 Z7 k3 y. p                output = (INT)out;0 M3 }( \+ u2 o$ J! s0 y
                }
5 Z& y# l, @! |$ G0 _  i#endif, Q; o  ]& u/ r4 `) D# H2 c
#if        0' O; c% o9 `' h, s# ?4 o2 X0 ^, P
                // 僗僷僀僋僲僀僘偺彍嫀(AGC TEST)
! m, ~1 V5 ~0 m* s" G4 U                {
/ i& i; i1 t1 V- j2 q4 a1 i                INT        diff = abs(output-last_data);
( B* ?7 g5 o7 i" S                if( diff > 0x4000 ) {
% s3 D- u; M3 \. x4 ^; f& T4 B                        output /= 4;
1 V6 h. n5 X0 t9 c                } else 7 t" n' q# w" ]1 }% x! y
                if( diff > 0x3000 ) {
& I1 p" h( b+ N" T                        output /= 3;4 k5 b6 V7 K* m9 [% R
                } else
0 e/ O+ ]1 U2 a$ l5 F) J                if( diff > 0x2000 ) {
) ?8 ]& D( Y/ j4 }2 m, q                        output /= 2;
0 `5 I  t8 D: z9 @+ ^0 B) F. m                }
) g; J0 }) B% s2 {& Z% _                last_data = output;
5 N7 y- R* p' g+ z                }% v6 y8 T( `5 _4 ]4 b7 |
#endif, L8 o% o% ?" k" k  L% w6 C0 E2 v, a
                // Limit- ?5 N' |( k. ~
                if( output > 0x7FFF ) {
. l1 d9 k/ [8 L1 g                        output = 0x7FFF;* `) t8 Y3 f0 T4 r
                } else if( output < -0x8000 ) {. l( E$ ?. ?& c% P% l# S& n0 C3 Z
                        output = -0x8000;8 I. \9 i6 U2 T( K
                }
+ D' u- ]( F" H+ b, E/ K5 m8 D
4 w6 k) e% \: i7 P8 a! b- v- l                if( nBits != 8 ) {! U: K+ @. ~( g' `- m
                        *(SHORT*)lpBuffer = (SHORT)output;
; G- [# {, p+ q1 t/ D; T                        lpBuffer += sizeof(SHORT);) o5 M" l, i+ H
                } else {
0 x$ Q: W9 c9 e' k+ w( \+ u: P2 c9 o                        *lpBuffer++ = (output>>8)^0x80;
; ^1 e2 U% O1 j3 d8 g" }; E9 Y                }
0 E: E9 x" F& p* ^+ c& V0 T. T
$ o+ t* z+ y( {; l4 f  X% F; s                if( nCcount < 0x0100 )
( O& H! t5 E7 d6 I  E                        pSoundBuf[nCcount++] = (SHORT)output;  ?/ L- j1 U! W1 H

4 g) o. ^4 ^. E# j//                elapsedtime += cycle_rate;# A+ ^  b. F6 \# l/ {6 d
                elapsed_time += cycle_rate;
2 u$ y# j6 {& _* Y" ?6 ?7 b4 k        }
( @; o1 s' c$ i$ p8 ?$ U& x+ Y: {0 g! ?( d! l: n
#if        1  m5 f$ j! t: x; L7 J( D
        if( elapsed_time > ((nes->nescfg->FrameCycles/24)+nes->cpu->GetTotalCycles()) ) {
! i7 H- j! @; A                elapsed_time = nes->cpu->GetTotalCycles();5 r% Y+ I4 \9 T9 @" ^. T8 l
        }# Z5 h* b- O( s) S4 o: d
        if( (elapsed_time+(nes->nescfg->FrameCycles/6)) < nes->cpu->GetTotalCycles() ) {
( A& N; P4 m& i1 G                elapsed_time = nes->cpu->GetTotalCycles();% e- |! P( Q4 s3 x0 u3 f% x: `
        }2 u! }9 S# f! g
#else
. d2 z6 i3 m3 o* K3 h        elapsed_time = nes->cpu->GetTotalCycles();1 J. |) y. C4 g/ z9 r* j
#endif
" \* X& k2 X* i: ~}
4 ]2 o0 q$ E/ N0 F' k% ~
9 c( `2 U1 b2 |' G: M& l9 N// 僠儍儞僱儖偺廃攇悢庢摼僒僽儖乕僠儞(NSF梡)7 ~! q$ K3 [3 L( k( ?9 ~
INT        APU::GetChannelFrequency( INT no )3 a7 H" D! I4 g
{- z( }" j; Q" R8 Y3 U
        if( !m_bMute[0] )* _9 F! ^, ?8 k9 p! p) _
                return        0;& F9 [0 T) Q% f  R# B, F
- i7 S. Q  F0 |0 N; Y( W
        // Internal
' r8 T$ Y0 M- ], S) B        if( no < 5 ) {2 F7 z4 b' @; F* K  {$ m3 a# H# t
                return        m_bMute[no+1]?internal.GetFreq( no ):0;3 g8 U) v3 d) r) ^2 j' w9 N
        }* ~# k( G4 x1 z& |
        // VRC6" n8 o; w) ]/ L  k; g) i
        if( (exsound_select & 0x01) && no >= 0x0100 && no < 0x0103 ) {9 q7 v( x' e7 R* I
                return        m_bMute[6+(no&0x03)]?vrc6.GetFreq( no & 0x03 ):0;& j0 J; J: M; _( X
        }8 a# x) a; Z5 P' Q' q
        // FDS
# M4 Z" z+ T7 ]" `3 _8 q# V6 `        if( (exsound_select & 0x04) && no == 0x300 ) {/ |. O3 ?) O. K2 _, x
                return        m_bMute[6]?fds.GetFreq( 0 ):0;
! P8 O) M! h8 g        }9 _- W0 z' p. `  ^$ H
        // MMC5
7 g8 c1 j9 w/ \7 ]' k2 ?+ g        if( (exsound_select & 0x08) && no >= 0x0400 && no < 0x0402 ) {
# u3 K8 j, k4 I7 z% K                return        m_bMute[6+(no&0x03)]?mmc5.GetFreq( no & 0x03 ):0;
3 X4 M" |; D2 K3 u$ \$ Z4 I        }
, {' z: I" E! O2 x+ Q( P$ e# h* i2 W        // N106# {6 u# c9 z! C& x! o
        if( (exsound_select & 0x10) && no >= 0x0500 && no < 0x0508 ) {
0 Y/ Z* j2 T6 U. @6 B                return        m_bMute[6+(no&0x07)]?n106.GetFreq( no & 0x07 ):0;
9 Y. \4 l8 g- z7 d% Y5 |- z        }0 r" U9 W$ V' }2 v3 S1 ?
        // FME7
& n3 W/ M+ o  d        if( (exsound_select & 0x20) && no >= 0x0600 && no < 0x0603 ) {& I( p7 x) A: \
                return        m_bMute[6+(no&0x03)]?fme7.GetFreq( no & 0x03 ):0;
3 R' o  O0 e9 Z7 c4 m" O        }
$ f0 G6 _  S( ~% C2 a3 k        // VRC7
3 U  P3 b, h1 f8 E* {6 ?        if( (exsound_select & 0x02) && no >= 0x0700 && no < 0x0709 ) {1 G) N  c, y8 f/ o1 z
                return        m_bMute[6]?vrc7.GetFreq(no&0x0F):0;) [8 _5 m9 H- e
        }% N5 n0 ~1 b) {8 B! k$ G$ O8 j2 R
        return        0;5 q3 \. K" E; O0 L- P/ ?+ b
}" e8 |4 [8 k5 [- [$ q

* b! d! b, u& M" r. _// State Save/Load
4 D2 [1 ?2 N7 ~& h3 O3 q- F" uvoid        APU::SaveState( LPBYTE p )
- }% Y0 E' v. J! ^6 M) B{7 j) ]# m3 I4 Z, \
#ifdef        _DEBUG
$ w: l, j9 T. Z" o) \* s5 q3 ULPBYTE        pold = p;0 S8 S  [- G/ F
#endif% M1 [( z- S7 Q9 H; O

- B! g' E$ T6 `        // 帪娫幉傪摨婜偝偣傞堊Flush偡傞4 ?& Y5 ^, z3 Z
        QueueFlush();; p7 x) E. Z: K4 g& S' c, i) M3 r! v

: ]* N3 R' E$ ?" K        internal.SaveState( p );3 M. o6 t/ v4 m
        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding
% b2 q8 ~# g5 t7 ^5 n; ]# N4 X( \( U7 t8 o9 e* X
        // VRC6
6 g7 F- A9 @# j( @: l        if( exsound_select & 0x01 ) {
4 V  A5 ~- d) k6 L* p7 H2 f( C( s                vrc6.SaveState( p );/ J0 _/ d- G5 Q4 {
                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding
8 d' w% u0 p1 r) o        }4 u# d4 M9 x) o& G8 q. e8 p: J
        // VRC7 (not support)
$ o/ P+ C* h  n% l/ w& c8 J3 a' U        if( exsound_select & 0x02 ) {
! H" f+ \+ x0 ?1 ]8 u                vrc7.SaveState( p );
. u' F! \% Y/ Q                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding
+ u! A5 w) ~, F, N( T        }
& o: w. u( ?+ h        // FDS  m: h, _8 ^5 Q5 K9 r* n/ G
        if( exsound_select & 0x04 ) {
1 n" j0 z% T. D+ T6 a                fds.SaveState( p );3 |. @7 K3 o5 B, ~, B4 w, z
                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding1 d* q8 \# M& x
        }; A  u# V8 Q! p3 s
        // MMC5) [. `& P1 |" M0 a& m, V9 C% a
        if( exsound_select & 0x08 ) {
, S" V/ j1 Y: ]7 {& {" B                mmc5.SaveState( p );
! `+ K- ]* O, i                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding
1 R$ G4 a8 Q3 H) F        }
$ y+ V6 ]  H# l( H        // N106$ h4 m; V5 }3 V9 H7 N/ c
        if( exsound_select & 0x10 ) {
0 Q. M1 p3 s: u; Z! H* f1 L                n106.SaveState( p );
" L, D. A- m& q) @- L' s                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding8 C! R5 S) O8 }  _7 u8 S
        }
5 y! X' g% k/ ]+ ~2 i+ ?        // FME70 ], S  Q( h% N) B0 y7 b
        if( exsound_select & 0x20 ) {2 s9 i$ P5 i! H3 _( n8 {
                fme7.SaveState( p );) @$ g. U& x6 q5 v8 ]
                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding
; ^% [7 B- h1 d        }
- N/ I: ?: f$ O# ~) b$ \3 r( w9 h1 a
#ifdef        _DEBUG' T5 N1 Y6 \: X0 B+ ^
DEBUGOUT( "SAVE APU SIZE:%d\n", p-pold );8 C% a5 f$ U) ^9 A' ^- b+ c
#endif
4 |, F( l/ v$ \1 }}: {, M5 l  i# V& Q

* I3 I6 A1 U" j6 G* N# J! xvoid        APU::LoadState( LPBYTE p )
: j! {+ c  H/ U) O2 B{
2 r% T' P; c, N! e1 Z6 R& l        // 帪娫幉傪摨婜偝偣傞堊偵徚偡+ A+ K& H: r6 P' {2 q% Q2 r. S
        QueueClear();2 Z) T6 M  S5 a3 D

5 k! S5 J& i1 q- f" J4 h2 ]  g        internal.LoadState( p );2 e3 E  d: D0 @0 G
        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding  l% y* E: j0 U) ^
) p& M& L$ U  P: p" ^
        // VRC6; n- b, x7 |* J5 y
        if( exsound_select & 0x01 ) {0 s5 M! c8 r& i# ?9 l/ j
                vrc6.LoadState( p );8 D0 O) a% P4 [- \$ Q
                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding
0 q6 M1 M& |) w! U" W' B, J        }
! j, I4 f) @9 X" g- b5 J9 e8 l8 V        // VRC7 (not support)
+ m) A4 O6 c+ q$ I# X# D% [1 S        if( exsound_select & 0x02 ) {
) _1 ^* I) P0 t: Q                vrc7.LoadState( p );
# ~5 o6 k& \/ F0 u- h. P  M                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding* p% `: L7 w: K" Z+ g  V! v0 o5 d
        }! {' w# h/ N  P
        // FDS* p, h2 C& Z' ?9 j. o! ~/ h
        if( exsound_select & 0x04 ) {
8 z. |/ f1 ~2 O  b% G                fds.LoadState( p );" K! [# E1 @5 c7 p4 G( O
                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding
2 P( ~6 e1 \. S) l        }
! `9 @/ o3 R" A6 o' `& [        // MMC5- Z4 s/ d: S& M+ i
        if( exsound_select & 0x08 ) {! |2 r7 k% |, }8 s, r4 F
                mmc5.LoadState( p );" R+ C8 [! [5 l0 P& ^
                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding
4 v8 [( r* w1 P7 O        }3 [2 e9 c( q  |( @0 s6 S
        // N1066 l3 q1 ?3 E( k' |) L
        if( exsound_select & 0x10 ) {
4 ^- k: N9 j$ h3 W9 T                n106.LoadState( p );
. `; O5 b- p8 v& e2 w                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding" W( E% P3 i6 v& x; `" Y! K$ {
        }
. n0 N6 X9 b0 N) R1 H: D        // FME7. N5 ~) d, W+ v+ q& i1 N+ H/ q
        if( exsound_select & 0x20 ) {  t  E5 p& o' k; s
                fme7.LoadState( p );
4 Z) z$ M$ o; F                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding9 z4 R- Z. t! t" h
        }
/ n! \2 ~- ?) S}

该用户从未签到

发表于 2009-11-8 17:25:37 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 14:38 发表 4 P/ |6 n/ m' j. q+ z: }
可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。$ L/ p2 b0 {' b  u4 Z5 c1 u4 E
感激不尽~~

# F, \2 F0 I6 u9 @( P) J+ |+ g恩 我對模擬器不是很有研究," ]# G& n6 f3 d+ v& L; r" X- V  x* Z
雖然要了解源碼內容,可能不是很困難,- A) m7 V' [- a/ U( d- S9 ?
不過還是要花時間,個人目前蠻忙碌的。# B, ~7 f2 F& N# w/ t" W% U! @

( @! x8 z4 m* L: i2 L' A5 }給你一個朋友的MSN,你可以跟他討論看看,7 l/ o4 C8 I& g0 f
他本身是程式設計師,也對FC模擬器很有興趣。
/ j3 P0 {6 R" b. p' [
# c' P7 y. H: s1 ?1 X% _: l. OMSN我就PM到你的信箱了。
+ W1 C( c/ r. L) S5 T: V
. f9 Y1 x' S9 d9 _- M" i8 u& _7 i希望你能有所得。

该用户从未签到

 楼主| 发表于 2009-11-9 13:23:59 | 显示全部楼层
呵…… 谢过团长大人~~

签到天数: 80 天

[LV.6]常住居民II

发表于 2009-11-9 16:02:29 | 显示全部楼层
团长的朋友都是神,那团长就是神的boss。

该用户从未签到

发表于 2009-11-20 13:13:25 | 显示全部楼层
原帖由 独孤残云 于 2009-11-9 13:23 发表
8 }" H% n; Z' y" u: G' L8 Q呵…… 谢过团长大人~~

# J9 Q4 o/ ~! T4 m  i/ ^+ D2 ]/ y$ X
7 I- }' Y- h9 T* W# X1 q哈 不客氣,算是順便幫他找個伴,大家可以一起玩。

该用户从未签到

发表于 2009-11-20 13:14:53 | 显示全部楼层
原帖由 李伟 于 2009-11-9 16:02 发表
: ?8 ^: X2 `0 Q9 w团长的朋友都是神,那团长就是神的boss。

/ q6 Z) e. E9 W3 r哈 不敢當,我只是個平凡人,4 L, l5 s5 y+ }" w" n* g0 b
要吃飯喝水,光吸空氣是不會飽的。。。。 :)

该用户从未签到

发表于 2009-11-20 13:32:35 | 显示全部楼层
FC模拟器的部分有个人可以帮你忙
* Y, `0 J, p. j0 D5 j$ `0 zZYH
$ p  H" h' g0 b7 o: y! [8 A7 e5 vQQ:414734306" ^4 [: A! ]5 `- a9 V7 v8 t7 ]( B& Z
Mail:zyh-01@126.com
2 U2 v# u" _" S2 }) d
" @. f/ \. s& J, J% j他是ZYH Emulator这个模拟器的作者,只是他用的开发平台是VB,不过就6502的实现原理来说是一样的

该用户从未签到

 楼主| 发表于 2009-11-27 09:48:23 | 显示全部楼层
再次对团长大人和悠悠哥的无私帮助表示感谢~~

该用户从未签到

发表于 2009-11-27 19:09:06 | 显示全部楼层
原帖由 独孤残云 于 2009-11-27 09:48 发表
5 `! L# R. w# K! i$ S0 P0 ?/ d再次对团长大人和悠悠哥的无私帮助表示感谢~~
, |6 |% ]8 j! d3 y. b$ d  l: ~
不客氣  ^_^
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|国治模拟精品屋 ( 沪ICP备15012945号-1 )

GMT+8, 2024-11-18 16:52 , Processed in 1.091796 second(s), 18 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表