EMU618社区

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

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

 关闭 [复制链接]

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 09:56:34 | 显示全部楼层
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。+ b6 p; U* ^  k# a
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~' h  }1 c# w: Q# r& L7 r
这里有相应的模拟器源码,就当送给大侠了~~
, `/ a/ }: I- R$ n, A- s5 \7 s6 ^http://kenkao.qupan.com/5096520.html

该用户从未签到

发表于 2009-11-8 11:31:10 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 09:56 发表 * n; `+ J( b* [
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。
. F3 s7 _7 y2 o  \( m( @0 i8 ^  a楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~$ f2 d4 K  d; f5 S; X  F* t
这里有相应的模拟器源码,就当送给大侠 ...
& G: j- \* x+ `- E# s- _( o0 |
聲音部分(Audoi Process Unit = APU):
- X' b% O& {* m6 E* O! r4 n.\NES\APU.cpp
$ T5 _9 X: {4 K) o5 C  Z.\NES\APU.h
' O, T2 L, M- Q  D" b6 U/ W; M! k$ t+ I5 W' s
* C- \( S' _& n7 r& D
影像處理部份(Picture Processing Unit = PPU):8 d& l) m6 B* @- m; a- c
.\NES\PPU.cpp
2 _) t/ ^& e1 H- S2 X.\NES\PPU.h& @% E: k. z1 {* f' W1 N4 V

+ V, h& H9 B- C如果原碼用C跟ASM混搭也不錯

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 14:38:21 | 显示全部楼层
可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。
$ m+ @/ a0 b/ g2 N6 x% X* u感激不尽~~

该用户从未签到

 楼主| 发表于 2009-11-8 14:47:50 | 显示全部楼层
这是我手中源码Apu.cpp的内容,敬请赐教:
! I, \8 i, c9 ]+ U4 \" O(由于很多专用术语和算法机理都不明白,所以看不大懂……)
2 `9 B) U; o, m- g. g* ?2 ^//////////////////////////////////////////////////////////////////////////: B& R) j5 H. G, q* h5 ~3 J
//                                                                      //! u7 [/ Q9 x  {
//      NES APU core                                                    //
8 M) ^! ]- @" l/ t) P//                                                           Norix      //# }: l; G+ G+ ?* H! j& D% a
//                                               written     2002/06/27 //' o- |" H: H- @
//                                               last modify ----/--/-- //
8 O: q; P: @- {1 E) d//////////////////////////////////////////////////////////////////////////
$ V+ ^4 O: ^6 V# y; o# ~#include "DebugOut.h"" Y1 A  k( y% X9 [1 i3 A
#include "App.h"  B# ^- u  s. X9 i9 ^0 e% f: f6 L6 z
#include "Config.h"
6 K, I: _2 N6 K: ^+ y7 X3 y! @
#include "nes.h"& b+ F$ S: m0 H% Y8 |0 e; [& ^
#include "mmu.h"$ A9 m9 L, h" n  u% |$ A* t# X
#include "cpu.h"# _. y: C( }) l* o" S* i7 q6 R
#include "ppu.h"
; w1 g7 O: |7 `8 ?6 E#include "rom.h"
$ }4 H4 J0 r# b' {9 S# }#include "apu.h"
8 o& ]7 f& C" P6 Z8 r. A' e8 |3 U/ X, z& @: J  `
// Volume adjust3 K$ ?) C$ w8 X1 P* Q! ~1 j) F
// Internal sounds7 ?3 b: N) m" P# s: t! Z3 j
#define        RECTANGLE_VOL        (0x0F0)
' ?3 v+ w; ?# ]* X#define        TRIANGLE_VOL        (0x130)
, u8 `. p8 w3 J% S4 w* w#define        NOISE_VOL        (0x0C0)
5 v7 y! m1 M) \# Y. j#define        DPCM_VOL        (0x0F0)
6 p1 n* e0 O0 r2 R- ^! b  |( l// Extra sounds& e5 ~' V3 |+ d! M8 z
#define        VRC6_VOL        (0x0F0)
; ^- S% m# o* a8 B#define        VRC7_VOL        (0x130)1 Q4 M( Q5 M6 j/ r9 ^
#define        FDS_VOL                (0x0F0)
/ ]1 d2 e8 i$ }9 q* T3 L: r#define        MMC5_VOL        (0x0F0)
: x, Y# ~+ Q$ S, q; ]#define        N106_VOL        (0x088)
* m! p+ l- G$ c5 ^* R+ [9 t/ u) Y#define        FME7_VOL        (0x130)! Z) {# \' \, v  Q" c% ~6 H

; c$ {# e4 U) x8 \% g: AAPU::APU( NES* parent )* I- y4 q9 L) W+ F
{, D; Y, _9 w% q+ ~7 G
        exsound_select = 0;. ]6 z3 R7 O0 D% x
1 V8 R$ g/ @" P$ j+ r1 `, _
        nes = parent;$ z! b9 Y1 w0 v& {: o# J
        internal.SetParent( parent );
5 P5 ]( @" I' G* `0 Q( X" H' G& {5 n) Z& J, Z- P+ Y7 W
        last_data = last_diff = 0;& v) {9 a9 \- ]
& z2 k5 ?# q8 L: j- C
        ZEROMEMORY( m_SoundBuffer, sizeof(m_SoundBuffer) );5 k8 c, }  w2 }/ U' _

" j3 i) {' c: H2 }* t' `: X        ZEROMEMORY( lowpass_filter, sizeof(lowpass_filter) );% N& `* T, j) t
        ZEROMEMORY( &queue, sizeof(queue) );( Z! ^% B0 R  }0 X( W0 s
        ZEROMEMORY( &exqueue, sizeof(exqueue) );, k1 D, A- T5 g$ B, f' o
# l5 Q  d% M' B) _( n
        for( INT i = 0; i < 16; i++ ) {
  c7 U5 ^& G* u                m_bMute = TRUE;
+ U; l' S* {1 W% I1 x0 U1 ?0 m" f        }
8 P! B6 U4 p9 ~3 c}
8 \2 @8 V& ^8 e; ^# e) q% Z; r5 K
7 E% _. ]" d( n9 k$ MAPU::~APU()
% E# c9 S3 r) n: G  b/ O{5 }. S4 S2 I- i6 J0 k- T9 J) v
}# S# U; x% i4 F# [! M9 b7 o& x( U) Z# f

/ u) T$ S( x. j5 n& e' \void        APU::SetQueue( INT writetime, WORD addr, BYTE data )  Y& w1 Z' Q" K! |' k) W( {' F6 E, H7 r
{6 Y0 X/ \) M" R
        queue.data[queue.wrptr].time = writetime;- J" \1 A5 J2 M  e: e
        queue.data[queue.wrptr].addr = addr;
" R& x; Z# r% T" Q  W        queue.data[queue.wrptr].data = data;
# Q7 H% m  @, k: j& y  q        queue.wrptr++;3 h) v, e% s+ j
        queue.wrptr&=QUEUE_LENGTH-1;
% O8 W1 t2 x* P7 o# U        if( queue.wrptr == queue.rdptr ) {
# R6 K" P! A; C9 J. X( N  }                DEBUGOUT( "queue overflow.\n" );% f! V: f* P7 T- M( U+ ]6 g0 l
        }
/ o" x. x3 W8 V' A) l# V}
: j/ \& y# F- x7 H" e: c. ?% l; n- s( j4 F6 Z
BOOL        APU::GetQueue( INT writetime, QUEUEDATA& ret ); y) P8 u$ \9 b( ~7 B
{
$ G% w, p! f- T4 O* m% {5 s        if( queue.wrptr == queue.rdptr ) {/ ?  J/ m* B# s- j
                return        FALSE;
- h9 l1 ~0 B6 i, ?, t  T        }
- }# i7 p: _2 @; z        if( queue.data[queue.rdptr].time <= writetime ) {& O) ]9 ?! P& ~% P5 `+ \+ A
                ret = queue.data[queue.rdptr];
! ~# A' j7 g/ g5 {! C: u: T                queue.rdptr++;7 A5 s* _" M4 Z
                queue.rdptr&=QUEUE_LENGTH-1;
+ m: Z. J/ m1 E3 [8 C                return        TRUE;
2 p  F3 }5 _: ^4 v. T        }
0 c9 y2 L  y  O        return        FALSE;: a. C2 E, e" ]
}# E5 G6 A; z; |* g4 u

2 Y% X/ Q* D3 Z0 f% Evoid        APU::SetExQueue( INT writetime, WORD addr, BYTE data )% e( S" @0 N% e3 J$ q& v
{
) D# V5 f' p$ o        exqueue.data[exqueue.wrptr].time = writetime;
* s6 |2 r- k# ?' C# K4 V: q        exqueue.data[exqueue.wrptr].addr = addr;& W9 U" d3 l$ Q, v& k
        exqueue.data[exqueue.wrptr].data = data;" e9 {" I; ?% t7 T
        exqueue.wrptr++;
* c& @, Q# D2 s7 {9 B        exqueue.wrptr&=QUEUE_LENGTH-1;; C' h' _. O$ N
        if( exqueue.wrptr == exqueue.rdptr ) {2 ?4 v! G; B' h
                DEBUGOUT( "exqueue overflow.\n" );. D: Q. p1 g- {3 N1 b+ Y/ G9 I
        }
7 y4 k% e9 [$ b9 C" R" o# l2 y}
7 e7 p% |# B& A/ w& k
3 D' L0 W2 p+ U. n! sBOOL        APU::GetExQueue( INT writetime, QUEUEDATA& ret )
" @/ p/ p1 K1 k! r9 Q{3 D% M3 R% k8 i) F8 a$ A
        if( exqueue.wrptr == exqueue.rdptr ) {5 X7 A: a% l1 i" f5 l, @/ i  w
                return        FALSE;
" H' ]+ n+ d) ^5 e7 i' V! J        }
7 o9 m# s4 x3 ?# ^: s  @- j        if( exqueue.data[exqueue.rdptr].time <= writetime ) {
1 \: l/ \- \) d# N/ C/ \                ret = exqueue.data[exqueue.rdptr];
1 g0 i7 G! z2 w0 l8 h1 @# T                exqueue.rdptr++;( i0 w' E7 y7 `. n* R9 F
                exqueue.rdptr&=QUEUE_LENGTH-1;1 P& _. B. c% F- g" o6 [
                return        TRUE;
) G- D! |& f* Z1 A% A        }9 `7 A% X8 d, w
        return        FALSE;6 w7 {+ ?+ k! r( a+ R) D
}: Z% r. c& z: ?$ T

( g4 Y* v' e* B9 z/ ~) Pvoid        APU::QueueClear()
2 C7 u# ]! _. G6 h& |8 [! I{( |/ D8 p  c/ h
        ZEROMEMORY( &queue, sizeof(queue) );
; ~7 y" p0 B6 @1 M3 k- L+ G+ q        ZEROMEMORY( &exqueue, sizeof(exqueue) );
2 c6 Q0 Y! k8 a$ {0 @( ~}
8 e+ ~8 W* i. f* U. W3 {5 M# ]& N
3 I; ?4 |8 W3 {- |6 x' }5 a! Ivoid        APU::QueueFlush()
0 ^* _; i6 d7 e0 t# h7 s{0 B- V0 K4 i$ F( H
        while( queue.wrptr != queue.rdptr ) {8 X7 G# i& P# o0 N; r; E
                WriteProcess( queue.data[queue.rdptr].addr, queue.data[queue.rdptr].data );! H# Q8 |" J  X( u9 n
                queue.rdptr++;: Q2 ]/ x5 J, {6 J  ]0 D2 u
                queue.rdptr&=QUEUE_LENGTH-1;1 n& i/ [( u/ j
        }7 q4 U9 @' Q; x$ W% ?( J

' N4 u* P( w4 O- ~5 y        while( exqueue.wrptr != exqueue.rdptr ) {' M/ x" _) [8 ?" b
                WriteExProcess( exqueue.data[exqueue.rdptr].addr, exqueue.data[exqueue.rdptr].data );. f' t% M0 P$ l1 C( b6 p4 {
                exqueue.rdptr++;/ V  l7 G- n2 U& Z
                exqueue.rdptr&=QUEUE_LENGTH-1;, `  i9 G) O) t. J! L; z
        }
) X/ C) ^) Z+ A}
# d6 a1 V/ w* v/ I' {$ P; z# \1 y8 {- T9 S! f) o7 O
void        APU::SoundSetup()
7 l# {; _% }& l" ^: D{5 K( E4 O8 X' H. p+ D! G+ b: \' u
        FLOAT        fClock = nes->nescfg->CpuClock;( ]6 n  j" o' N! O* d8 z" E& h
        INT        nRate = (INT)Config.sound.nRate;$ Y5 A+ }8 F0 ]' h
        internal.Setup( fClock, nRate );
# j, R8 b. ?& T, D" T( _        vrc6.Setup( fClock, nRate );
0 g5 H/ m. }" U7 c: Q9 c+ v$ l+ f7 n        vrc7.Setup( fClock, nRate );
' k7 Q6 ~  I# s, ^) o        mmc5.Setup( fClock, nRate );
/ P1 g) o" Q$ w; ~        fds.Setup ( fClock, nRate );/ J$ ]6 ]) N9 K# H, c9 J1 ]
        n106.Setup( fClock, nRate );
6 e. g) P# R, [# o4 d0 H7 W) N        fme7.Setup( fClock, nRate );
4 r# ~6 }3 c' o+ B2 |4 \}- l, G  n9 D8 Q* l8 m# |1 M7 o

( `* n1 t# H; d: ]void        APU::Reset()2 |6 m) Y+ c) h+ g) s
{. L6 q. N4 u4 I. N8 H+ x& N
        ZEROMEMORY( &queue, sizeof(queue) );; ^5 l% F2 P5 k$ {/ w: O
        ZEROMEMORY( &exqueue, sizeof(exqueue) );* m, Z5 Y& f7 l9 U2 G* f: y

+ A$ M, G  V; U0 N  A        elapsed_time = 0;( }: B; D+ P* j

! o) Y4 h9 v* w+ m+ _        FLOAT        fClock = nes->nescfg->CpuClock;
! n1 I( k) ^. E3 A/ d4 B        INT        nRate = (INT)Config.sound.nRate;
2 G- b" b. S% _3 s$ {        internal.Reset( fClock, nRate );$ `# W% ]6 W" t* m
        vrc6.Reset( fClock, nRate );' @/ _  Q: D- p! G: O& k4 N+ j% i
        vrc7.Reset( fClock, nRate );
2 c: V& _, g2 R% M( X8 m        mmc5.Reset( fClock, nRate );/ n1 m* ]; F! c
        fds.Reset ( fClock, nRate );( W5 L# v. ^6 S9 t3 B/ v
        n106.Reset( fClock, nRate );
& j+ g" w; s. [4 e+ q: R+ P        fme7.Reset( fClock, nRate );9 p! q9 x2 o( z2 s+ C. v- f
& h9 S1 t, t% E; Z4 s( I
        SoundSetup();7 e, ]: ?4 c# C% e- Q: _. f5 H
}
: Y/ n& @4 s1 G3 C3 f
" [' _0 l- `6 h5 p/ Evoid        APU::SelectExSound( BYTE data )
# m* J( {0 ]/ k0 Y; J4 i{
7 N1 o1 p  M% x9 X1 W        exsound_select = data;3 m( y6 h8 [' R  A9 e
}
. y4 t8 C  C) P+ w1 E$ p  h6 G2 N. M. j6 ^0 D
BYTE        APU::Read( WORD addr )
3 W" o2 h+ y: ^; l: X& g' M{- z4 x( T" g. G8 d+ ^
        return        internal.SyncRead( addr );
$ A& e4 l7 I% d9 u  g8 B( r}! A( \1 \* S6 ]4 b

& f2 r0 m2 o( u: I( ?+ Mvoid        APU::Write( WORD addr, BYTE data )
% a0 I, c) ?, E: |" O$ g& D{
, V8 W2 T/ S0 f' I! A& X        // $4018偼VirtuaNES屌桳億乕僩0 F' {5 r* c3 h2 }
        if( addr >= 0x4000 && addr <= 0x401F ) {4 L7 t3 J) c8 y# U
                internal.SyncWrite( addr, data );
; J; O- d; a* C/ J                SetQueue( nes->cpu->GetTotalCycles(), addr, data );
' W- m9 b. n0 l5 B3 p. o5 F$ x        }6 v1 |6 ]/ [, U9 c& I6 c0 x/ m& W
}1 P0 z  t# ~2 q( O+ j: u
! e9 K0 b  }) Y8 n
BYTE        APU::ExRead( WORD addr )# C# H& f/ m' g" F  r
{
5 _0 L+ ~1 Z9 S4 ?" Q) UBYTE        data = 0;; ~+ U3 s" y% v

8 B' A: U- T8 ~; M6 M        if( exsound_select & 0x10 ) {) L5 B$ R0 p% I& l* x6 k
                if( addr == 0x4800 ) {
6 O) G. F2 M. _6 m5 ^                        SetExQueue( nes->cpu->GetTotalCycles(), 0, 0 );  ], k! ]1 F3 n0 H
                }4 p% S% C7 Y, [/ x
        }( K1 p5 z+ P4 x* B0 m& ~3 z+ x
        if( exsound_select & 0x04 ) {
- K2 w! g* T' i: S4 m                if( addr >= 0x4040 && addr < 0x4100 ) {
. G! j+ H( L2 N0 T3 K" m+ |, ^! ?/ q                        data = fds.SyncRead( addr );$ y% J2 E2 e. v- C2 x% p- S
                }& e5 s2 {1 B$ t* U0 q9 X
        }
% H8 y) K4 e- `) I        if( exsound_select & 0x08 ) {9 b2 B) q6 R. a+ R" }; W
                if( addr >= 0x5000 && addr <= 0x5015 ) {
1 o" I' Q% _6 n* S$ U: D                        data = mmc5.SyncRead( addr );" P  P' m, }0 q# I# X
                }2 B, R3 N3 K2 ?/ J+ ~2 ~  v/ y; c
        }
7 Z) o$ N* Z4 J- B% |2 d' d' y) o' x2 ]- r+ l
        return        data;
5 S4 R8 S4 r4 k; F  [}$ Q; @9 ?2 W- u1 J0 k
2 n0 |. J7 {" Z5 f) C
void        APU::ExWrite( WORD addr, BYTE data )
! n0 q. q' }+ y& s4 N/ F2 y9 q: y' z{
' W# k* y* r, V- r5 Z0 Q) l        SetExQueue( nes->cpu->GetTotalCycles(), addr, data );
" ?  ?3 ]* A- O3 r8 I% x, U( m4 c2 o5 w4 \0 O. J! }
        if( exsound_select & 0x04 ) {6 @- w. c9 }2 f7 }) l: |
                if( addr >= 0x4040 && addr < 0x4100 ) {
- }3 P$ w2 t# f. ?                        fds.SyncWrite( addr, data );
( ~5 P1 ^; X+ v# B                }1 Y; i6 L9 _  z  [, Q2 O4 F
        }
7 f) p5 E. H9 w+ J4 D. ]# u- r4 G: e6 z8 l3 Y1 ?
        if( exsound_select & 0x08 ) {
$ ]9 {) u' u5 \) f0 w3 K. |4 E+ c                if( addr >= 0x5000 && addr <= 0x5015 ) {
, x# l7 N3 y# O8 r3 x0 [                        mmc5.SyncWrite( addr, data );+ j3 J$ }; J! e) w
                }. C! _& L! X2 L: y3 G
        }& r+ K- y# z9 Y( p5 x3 f
}* a* H+ n- Z! s- U/ O  A/ L5 Y, t. n

3 S* P# a* C/ J( Pvoid        APU::Sync()- r7 Y4 o+ l4 \  O2 r2 W* ~, }8 R1 P
{
/ o: N9 \* a& c2 `. D$ q}
/ e7 C0 O' u  Y
5 @' d$ i: z, V- uvoid        APU::SyncDPCM( INT cycles )
% n% {( O# A' D{6 G- |) A: h8 k
        internal.Sync( cycles );
, ]" t+ F; ]7 [
* B, l) E" Y$ r1 l        if( exsound_select & 0x04 ) {0 A' l9 C3 W+ M/ w, G
                fds.Sync( cycles );4 h, z- R. ?! B" R( J) \
        }5 ~, Q& B* c0 o
        if( exsound_select & 0x08 ) {
- ]! V, y0 F4 N. V$ ~& c                mmc5.Sync( cycles );
4 Y5 G5 [$ S  b7 e5 I( D        }  T" [) S2 p5 v5 O" f8 w9 U
}
  g- P; _6 a3 [8 ~! N  f
4 v; n/ q$ S/ b4 W. Fvoid        APU::WriteProcess( WORD addr, BYTE data )
' B  R1 C% W; n( C{
5 a  I9 [2 [) R( ~* k6 G/ ~        // $4018偼VirtuaNES屌桳億乕僩
+ [* A/ n  b' c1 F( z. u& Z        if( addr >= 0x4000 && addr <= 0x401F ) {0 O- X/ Q0 s3 o+ m* ?2 [0 p! S
                internal.Write( addr, data );. n8 y9 }0 j' i9 m) F6 l
        }- w8 K4 z5 D# Z. ~+ a7 V/ s$ }% m
}
5 p% [8 R6 m; j. v! V
1 s+ N( f; h3 M3 U- }( x; t1 [void        APU::WriteExProcess( WORD addr, BYTE data )
$ ~1 n! _& b; ?2 F{
: F6 ^. t- B4 q, |- S! R0 p8 j* y        if( exsound_select & 0x01 ) {
' M  V  S/ R3 E( Y$ ^8 ^9 @& z                vrc6.Write( addr, data );
! V$ i% v3 c$ Z& d9 [( V        }9 ^. \  M' P8 t" O. R; {$ L) m
        if( exsound_select & 0x02 ) {( F8 J! B* L1 A
                vrc7.Write( addr, data );; T' a9 L: T% Y$ F  T, p! R
        }, F- ]# R' q, r6 R4 J+ c
        if( exsound_select & 0x04 ) {
. \8 R! ~0 s+ ^6 S" X+ p                fds.Write( addr, data );
* {6 E0 N. D: r# W, ^        }
; e9 u# {# e2 ~) w( w        if( exsound_select & 0x08 ) {
9 U, \: F  R0 G) E                mmc5.Write( addr, data );
6 l4 e8 n  n* }* L2 d( Y; E; d6 J0 C        }7 \' j" S7 D) S: @! p; F, ?
        if( exsound_select & 0x10 ) {
5 }: E6 k( M/ U( ?% d                if( addr == 0x0000 ) {
1 V: X& K+ I3 d! M0 G                        BYTE        dummy = n106.Read( addr );2 t# N% l9 Y; b9 Y; M0 G. D) S
                } else {
2 y( s3 q3 |& U3 v& m) L                        n106.Write( addr, data );) v: O- d" r/ p5 {% X
                }3 m8 G9 }; L) D" E& ]% L) o
        }2 L) q% t+ y9 t; T+ `  m- @
        if( exsound_select & 0x20 ) {
0 C5 f: i0 |6 N2 v! |; N                fme7.Write( addr, data );
8 e/ {9 |, _: q" G7 I        }2 }! K  ^" R/ n! _0 [) h# \
}
! u  s/ Z( s' W. m% F" C
! v, J- P! t: u/ V' X) [" Yvoid        APU::Process( LPBYTE lpBuffer, DWORD dwSize )
1 P/ I8 f" s4 I1 U{$ a0 k' q/ V+ `+ s6 N$ ~. F
INT        nBits = Config.sound.nBits;
, n6 D* e: g8 w; c9 [9 j; F. aDWORD        dwLength = dwSize / (nBits/8);0 [9 x2 I+ j. f
INT        output;9 e+ U. o& Y9 S% ?+ A
QUEUEDATA q;! C9 z  p" T7 K- B( {- _
DWORD        writetime;# P4 s. l! f! ~$ ~, `

/ ^9 a' }2 M6 G! sLPSHORT        pSoundBuf = m_SoundBuffer;
' H! k/ s! G/ z1 t% a7 L' pINT        nCcount = 0;5 i! J. [( B9 J* o
% I6 o$ y& [" [* q, @% ]5 a
INT        nFilterType = Config.sound.nFilterType;
  p; N4 v( b/ ]6 h- X- d
  A* X& q. ]. E7 [& l        if( !Config.sound.bEnable ) {% f! ]; l2 t5 b' w# u
                ::FillMemory( lpBuffer, dwSize, (BYTE)(Config.sound.nRate==8?128:0) );4 p$ F& q4 `; j( J- H( d
                return;- T  b5 a! `  \! J, w
        }
8 f5 s& k; O3 Y4 \$ w, r2 U4 p( d; w- ]* e7 ?% o2 t8 |/ g$ L
        // Volume setup$ m# f3 S9 H& D9 T
        //  0:Master
" Q" Q4 B- i, ]1 q6 x        //  1:Rectangle 1( F3 B  u0 w& N
        //  2:Rectangle 2, M' P% Q$ r& x% J8 c* D! Q
        //  3:Triangle
$ p- y$ S# D+ O) |        //  4:Noise; `& m+ n! A+ v
        //  5:DPCM
, A9 B- l" R7 k. M7 W0 j        //  6:VRC6; S/ D# L& c+ |/ `7 r
        //  7:VRC74 M. @7 ?% l3 e
        //  8:FDS
: c$ t% n. @7 J! Z        //  9:MMC5
3 s/ p& f$ z; J6 T        // 10:N106
/ R8 O2 E. I+ J        // 11:FME7
! j7 |2 x# f& Y+ w# |* `, |        INT        vol[24];
1 e' i% f5 {! S* ]8 r  u2 g        BOOL*        bMute = m_bMute;3 J# _' `( k/ G7 j
        SHORT*        nVolume = Config.sound.nVolume;
4 F- Q& H: R! i7 R# w
9 j  c$ ~( A/ o, y% e* E0 W$ P        INT        nMasterVolume = bMute[0]?nVolume[0]:0;+ d, ?1 P- e& o! h$ g( `! K
) h; M4 t/ Y8 B  Z6 t6 _6 P
        // Internal& w4 G0 p/ c: F/ R9 L$ j
        vol[ 0] = bMute[1]?(RECTANGLE_VOL*nVolume[1]*nMasterVolume)/(100*100):0;2 k) i0 s) Q- A* u) ~( `- \
        vol[ 1] = bMute[2]?(RECTANGLE_VOL*nVolume[2]*nMasterVolume)/(100*100):0;
& H/ ~8 J; z9 Z0 j7 }        vol[ 2] = bMute[3]?(TRIANGLE_VOL *nVolume[3]*nMasterVolume)/(100*100):0;
3 D( ^( q4 ]7 ^# @        vol[ 3] = bMute[4]?(NOISE_VOL    *nVolume[4]*nMasterVolume)/(100*100):0;' @; y( \9 ~# r: J* w, ^
        vol[ 4] = bMute[5]?(DPCM_VOL     *nVolume[5]*nMasterVolume)/(100*100):0;
7 c1 q$ P* s) m0 f" E* P8 {/ G3 x
        // VRC6; u0 p0 ]  v; ?
        vol[ 5] = bMute[6]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
: t$ J" @. U9 L        vol[ 6] = bMute[7]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;8 }; c8 \' }+ O- K9 H9 R7 d
        vol[ 7] = bMute[8]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
. D7 A/ g# X$ k, C+ H9 n) P) r
- r7 q* e7 j6 Y: {- t9 g        // VRC7  q% {( N. U1 a" j$ @3 J3 K6 X
        vol[ 8] = bMute[6]?(VRC7_VOL*nVolume[7]*nMasterVolume)/(100*100):0;* d: ^3 N4 N: D

# d5 L- L4 `) Y        // FDS
8 Z. \. Q2 s4 W$ I        vol[ 9] = bMute[6]?(FDS_VOL*nVolume[8]*nMasterVolume)/(100*100):0;9 v/ @: A+ s! x. P, O) J5 k
4 N! a1 ]; W9 S* d5 k
        // MMC5
3 E( _/ U$ \- P* _# ~+ s5 I        vol[10] = bMute[6]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;/ {3 W' Y2 \4 d  u
        vol[11] = bMute[7]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
9 h9 m& x# q6 n        vol[12] = bMute[8]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
" Q! H) D* D1 E$ p. }- k+ U+ [) \4 a8 U5 v1 _
        // N106$ Y0 k4 Y& P( l7 f9 J4 B
        vol[13] = bMute[ 6]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
, P$ p1 I. L2 H- X7 V4 `        vol[14] = bMute[ 7]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
9 v3 g% ^# B. z        vol[15] = bMute[ 8]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;8 t# B- F; y) W- D+ _3 G
        vol[16] = bMute[ 9]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;( g: t* v8 O$ L1 [3 N  x- }
        vol[17] = bMute[10]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
4 U$ M' O# X- }        vol[18] = bMute[11]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;0 R' n+ h7 o4 u$ |
        vol[19] = bMute[12]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
$ [  b) P7 F. u        vol[20] = bMute[13]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;: G8 w$ C1 f: h* T1 \8 \
1 B% `! ?+ _1 R7 M
        // FME7; W  a, l9 c" t* f: D% v
        vol[21] = bMute[6]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
) |% G6 O5 ^! R3 ~        vol[22] = bMute[7]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
# ~+ u2 `- J+ R4 B8 ^, Q# n+ C6 r        vol[23] = bMute[8]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
1 W% s. x+ ?; ?7 r/ I$ J8 B9 t5 ?
2 g* B+ y8 R! W/ |4 n( }! o//        double        cycle_rate = ((double)FRAME_CYCLES*60.0/12.0)/(double)Config.sound.nRate;- S. K& k- S6 L- Z4 ^" M# p# l
        double        cycle_rate = ((double)nes->nescfg->FrameCycles*60.0/12.0)/(double)Config.sound.nRate;, }$ j; t. C3 @) D( h. t

' a6 x* ^$ |0 Q6 U        // CPU僒僀僋儖悢偑儖乕僾偟偰偟傑偭偨帪偺懳嶔張棟5 C, h) b7 n+ z+ {9 a, |% ?
        if( elapsed_time > nes->cpu->GetTotalCycles() ) {
7 z( p% R; A  Y                QueueFlush();
# }( K7 |- y9 x  j2 ~+ |& o0 N& w        }2 y# ^( f9 n; W1 S& [8 ?4 D, }

9 ]% _+ l4 `; [% o0 r        while( dwLength-- ) {9 f( ]4 |7 M0 t7 B' P$ L+ Y/ U3 k/ a
                writetime = (DWORD)elapsed_time;& Y( R* h' s* [, ]

! ~- `* O2 g! C+ t3 H                while( GetQueue( writetime, q ) ) {0 r0 T0 c7 L* i2 N+ c5 P' V
                        WriteProcess( q.addr, q.data );" k4 S  R0 ^, o
                }
+ @# g$ R9 s) p: M8 O# j  e9 u& S; C$ O7 _; H
                while( GetExQueue( writetime, q ) ) {! i; ~& i- H8 C& X( u) Q
                        WriteExProcess( q.addr, q.data );
) n; p4 V, K' u# w                }6 t" P; b8 j& D/ ?# B
  n& Q8 i* S- R: e0 S; w/ O: ^) T
                // 0-4:internal 5-7:VRC6 8:VRC7 9:FDS 10-12:MMC5 13-20:N106 21-23:FME7
1 w7 T% y- {: F1 z$ e. U                output = 0;
' S0 ]" Y- W$ L/ G& t+ V: L                output += internal.Process( 0 )*vol[0];
- i& I8 d& F- j8 W; I0 q" z" |                output += internal.Process( 1 )*vol[1];% Y3 Z# f6 V9 t  Q4 h
                output += internal.Process( 2 )*vol[2];
$ C3 F/ V2 |2 [1 y+ c$ d. `                output += internal.Process( 3 )*vol[3];
5 {" ^/ W) `4 z" Q7 E5 C1 _                output += internal.Process( 4 )*vol[4];: Z4 |3 E/ S4 U1 `
7 Y2 d/ l, j4 ]6 h+ Z# J, O  _8 o
                if( exsound_select & 0x01 ) {& O6 g1 x8 v4 O( q
                        output += vrc6.Process( 0 )*vol[5];5 P  i6 d9 `* p* L" t, }
                        output += vrc6.Process( 1 )*vol[6];$ S2 F9 r: \/ ?) ]# ?
                        output += vrc6.Process( 2 )*vol[7];3 s- h- {: g2 e
                }
$ L1 i1 _' k5 N( e                if( exsound_select & 0x02 ) {
7 F# ~; O$ a8 q* ~; ?) t9 f                        output += vrc7.Process( 0 )*vol[8];
$ G) e( A9 D( K                }
) e; Y: m  A: v$ w% w                if( exsound_select & 0x04 ) {2 F" ]# O' Z0 p6 b" _
                        output += fds.Process( 0 )*vol[9];
5 Q3 K+ L- ~- l% c* c; m                }7 l" g9 S/ L6 ~. @& h3 C
                if( exsound_select & 0x08 ) {
9 g' u2 l) e1 H6 B4 \! g                        output += mmc5.Process( 0 )*vol[10];
! K! K$ |( d1 [0 j2 e7 P                        output += mmc5.Process( 1 )*vol[11];1 a$ x5 |, M6 r: a$ H, M
                        output += mmc5.Process( 2 )*vol[12];9 G8 _, k3 U! A4 L
                }: ~4 C# q2 @" d( m: m) v0 z
                if( exsound_select & 0x10 ) {: l$ U" [, {: v7 q- u
                        output += n106.Process( 0 )*vol[13];8 z7 |8 ]+ h. I5 Q3 r; ~
                        output += n106.Process( 1 )*vol[14];- ]) Q/ z9 A/ C) w' e% S
                        output += n106.Process( 2 )*vol[15];
% p: W  e7 o1 a3 G; @: ~3 ~; F2 r+ Z                        output += n106.Process( 3 )*vol[16];3 V( @" x. S, n( R! Z
                        output += n106.Process( 4 )*vol[17];2 G  t% h1 J, {+ b) ], D1 k; J
                        output += n106.Process( 5 )*vol[18];: G* O7 f  _  U' S3 `  u1 r3 b
                        output += n106.Process( 6 )*vol[19];& i, @  x1 H% K8 A! X! ~7 u) o" F, H
                        output += n106.Process( 7 )*vol[20];
& {7 I# J/ a# j! O: |3 k                }
) q* e! }, S9 _; `% P                if( exsound_select & 0x20 ) {( P8 g" p! r+ y% @( r0 @
                        fme7.Process( 3 );        // Envelope & Noise
# a1 p/ W% x! f/ r8 y0 Q                        output += fme7.Process( 0 )*vol[21];
" l5 z) D; S) P! \                        output += fme7.Process( 1 )*vol[22];
+ O0 k) z" q2 H                        output += fme7.Process( 2 )*vol[23];" J9 L; L3 l4 d8 H
                }
$ p* Z& p. a7 S0 r; d! o
5 T# ?, O& C, {                output >>= 8;
- ^# f! E3 ]$ T5 H& q7 w& V3 A+ O
                if( nFilterType == 1 ) {
# o6 N2 n; c; R% \6 t" n                        //儘乕僷僗僼傿儖僞乕TYPE 1(Simple)- Z7 h* h3 O1 C4 O$ L) d
                        output = (lowpass_filter[0]+output)/2;, ~9 N4 X5 P" W
                        lowpass_filter[0] = output;
7 r& o4 R9 p6 O/ ]# E2 k                } else if( nFilterType == 2 ) {
( f+ a4 T7 s. ^                        //儘乕僷僗僼傿儖僞乕TYPE 2(Weighted type 1)$ f  {8 e2 H; x. m& A5 e, r& d
                        output = (lowpass_filter[1]+lowpass_filter[0]+output)/3;
) n5 r. C! |  ]9 S                        lowpass_filter[1] = lowpass_filter[0];
+ A2 h. @$ Z" P2 T3 c* ?" V. l                        lowpass_filter[0] = output;
* ^2 k( ]5 |$ b                } else if( nFilterType == 3 ) {/ R/ q0 C( y9 A1 Z. e6 l3 d1 i% u
                        //儘乕僷僗僼傿儖僞乕TYPE 3(Weighted type 2)! a: x+ @% }3 \% t; p: n
                        output = (lowpass_filter[2]+lowpass_filter[1]+lowpass_filter[0]+output)/4;
, h' Y8 `0 a& f                        lowpass_filter[2] = lowpass_filter[1];7 H6 a& u- T. |
                        lowpass_filter[1] = lowpass_filter[0];( i# ]$ n$ P6 m7 x
                        lowpass_filter[0] = output;
, ^" d% N+ o- m( S                } else if( nFilterType == 4 ) {$ W5 `! O/ Q* ~6 K" k) q& K5 M+ d' k
                        //儘乕僷僗僼傿儖僞乕TYPE 4(Weighted type 3)/ a7 W. Q) c7 N0 L8 p5 ?
                        output = (lowpass_filter[1]+lowpass_filter[0]*2+output)/4;$ R5 `) E8 v1 Z3 e  N' u
                        lowpass_filter[1] = lowpass_filter[0];
* u+ k1 Y- ?5 @) B% y                        lowpass_filter[0] = output;$ d7 u- M* ~4 y; T& w2 u* P- k# k! s
                }
3 e: ?0 m6 {& v' p& a+ m& v7 B2 U4 c
#if        03 \7 e  E/ ~. G, f1 g
                // DC惉暘偺僇僢僩0 O8 r; o- i, I! U
                {
; L" ]( a- u7 i8 }6 g4 x7 ?$ t/ Q                static double ave = 0.0, max=0.0, min=0.0;0 [7 _$ n/ x- |
                double delta;
8 j0 g! C6 B4 Q, e% \2 ?& ^- |                delta = (max-min)/32768.0;; ~- ~& G1 ?4 j) t+ {3 _4 D  e% h
                max -= delta;, C4 R; c4 i9 m7 Y+ }) J
                min += delta;
5 M$ y) s- Q% K; o7 Z: r$ r2 N                if( output > max ) max = output;0 x- o' I$ N# g- w9 P5 `- @' H
                if( output < min ) min = output;
" R3 u9 h7 V6 S) T! N                ave -= ave/1024.0;
% l7 E1 p/ S+ E0 b+ \) M. M$ m& ]                ave += (max+min)/2048.0;( I1 {6 F1 p' k6 ]; s  f
                output -= (INT)ave;) ]5 Q: B5 B* o/ g8 F
                }
0 l3 K# @5 w3 k6 x#endif
9 j/ o! L) ?$ f#if        1# X* g, S; p5 w. t
                // DC惉暘偺僇僢僩(HPF TEST)$ x/ d- u/ R7 r
                {" @7 s5 k) {5 ]8 A( r: s! z: b
//                static        double        cutoff = (2.0*3.141592653579*40.0/44100.0);
# ~* M& s  x% r' n# k5 o0 d; k                static        double        cutofftemp = (2.0*3.141592653579*40.0);
$ F4 H+ N1 Q, Z. u3 f& r, Q6 U# y                double        cutoff = cutofftemp/(double)Config.sound.nRate;8 G3 K/ b2 P! n; P( [- p
                static        double        tmp = 0.0;
: O, S- a8 t, }- _' i9 c                double        in, out;
. o( k' o4 Y7 P. H3 q
3 |: G: Z, X3 Q& Y$ k                in = (double)output;
0 ?  W: c( D) [* R                out = (in - tmp);
+ x" W; Z5 V  G+ Q) t* L                tmp = tmp + cutoff * out;
1 j3 D, c8 [5 T+ _5 k5 \/ [3 M( U" J6 c- M6 N8 t
                output = (INT)out;
2 T3 i) _7 }# k6 h; ?9 B                }8 h; v9 E; v, \" D7 }" I
#endif) S1 P1 q0 T, e1 m/ P% M  Q; C
#if        0
# n: ^+ H1 x/ V# p                // 僗僷僀僋僲僀僘偺彍嫀(AGC TEST)5 n4 @0 H) a4 A% S
                {0 w# l: p' t3 `, @4 u
                INT        diff = abs(output-last_data);
+ v2 m, U, O) x8 Z9 }  n" \3 C- _                if( diff > 0x4000 ) {
: L5 s  K1 A2 S8 D' F3 X( }                        output /= 4;
) g0 y# Z7 A' q- y: I. F" r                } else
; p* z+ |9 }7 b7 e2 k- {                if( diff > 0x3000 ) {5 t. y9 l( P7 [/ {8 G+ @
                        output /= 3;
4 W; O9 T* [: L, }' R                } else
/ y  \4 r( j% x! E                if( diff > 0x2000 ) {3 T5 D" `8 h3 E  [) c
                        output /= 2;9 H: Z7 b5 n3 Q$ }
                }/ N7 z0 i- r# U  H# O
                last_data = output;
$ W7 s8 M7 w- F) `4 n3 ^2 I& Z                }
/ f! _  W: v+ m% J) o#endif4 t' {7 N& U+ _% m4 K1 e
                // Limit
# Z: n) R% d. j3 H                if( output > 0x7FFF ) {7 z) E4 p# `/ T% s4 l1 {: w0 g
                        output = 0x7FFF;! Q! M* n. {. R; ^, {# h5 O
                } else if( output < -0x8000 ) {
9 m# V8 R9 U2 i5 n                        output = -0x8000;
4 F3 Z! {1 z& F, O                }
. z1 N. D7 l7 }: y1 G
1 o$ X! @# C4 _1 r5 s                if( nBits != 8 ) {: x( {# ]* Z$ s
                        *(SHORT*)lpBuffer = (SHORT)output;) l/ g* I1 R: U. @' E2 M3 |5 p% i4 l
                        lpBuffer += sizeof(SHORT);' K+ S6 D+ B7 Y* J
                } else {; {: j9 M: F) g& \: o# c- e- m* S
                        *lpBuffer++ = (output>>8)^0x80;
0 N! X% |/ R* C" ~, ?; @                }
: q, z: M, v1 }% S; X0 I* q/ b8 ]
                if( nCcount < 0x0100 )% s7 U5 _' O& j
                        pSoundBuf[nCcount++] = (SHORT)output;! k0 X1 Y+ m7 ^, _5 m) L9 g
5 @) W& `( L: I7 ^" E
//                elapsedtime += cycle_rate;
! J4 T& ~, p( n3 i8 e8 T. H                elapsed_time += cycle_rate;
& {, ~4 g7 G( N+ }6 k/ S( E! ]        }
/ `; d' i6 E" e1 F4 J* f! M* R$ Y" e+ p. [$ q* g2 t; |% }$ r, Y
#if        19 N# `7 B; `7 a5 F  V
        if( elapsed_time > ((nes->nescfg->FrameCycles/24)+nes->cpu->GetTotalCycles()) ) {4 k( C0 O  c5 d" R
                elapsed_time = nes->cpu->GetTotalCycles();' ~; q, ~* ^* [. R3 T' [
        }
; R+ V: O+ {1 s: L        if( (elapsed_time+(nes->nescfg->FrameCycles/6)) < nes->cpu->GetTotalCycles() ) {" [% D* G( B2 ^  w
                elapsed_time = nes->cpu->GetTotalCycles();
& R  W/ @: l  ?! ?7 L7 ?        }
7 I0 W; D  [% }/ O' M1 d1 m2 X# L#else7 r. q$ b3 R7 D- p
        elapsed_time = nes->cpu->GetTotalCycles();
3 D/ ^6 Q! S" o" b. K; S2 p#endif
9 N# D/ u  z7 W2 s! A2 R& c}! v2 [# o4 y0 O' o; S* D
0 S& m) |1 f# S% }8 `; t5 H0 w
// 僠儍儞僱儖偺廃攇悢庢摼僒僽儖乕僠儞(NSF梡)
2 F. c1 L$ @- c6 G$ ]( C, WINT        APU::GetChannelFrequency( INT no )3 X  U! e- w8 I) ^
{! a6 A. Z6 r& Q& T0 D* G! u% r
        if( !m_bMute[0] )% m8 ]3 Y3 c9 C# O6 j
                return        0;
$ n# g6 _" K; z
+ k, J2 y* v: T! i/ T        // Internal
. I' j: A+ ]7 d$ }' g. a        if( no < 5 ) {
1 f: O" a0 ^% W4 L* b& q                return        m_bMute[no+1]?internal.GetFreq( no ):0;( q2 w7 y; _, R
        }
& \8 b3 l* v* q6 v8 k% z        // VRC6% ^* O) A, z4 e+ b  @4 x
        if( (exsound_select & 0x01) && no >= 0x0100 && no < 0x0103 ) {
  c" G, Z/ C4 X- j! q" U                return        m_bMute[6+(no&0x03)]?vrc6.GetFreq( no & 0x03 ):0;* z) u# L: d, r. @& D+ l- H
        }: I3 o( _* X+ `* Q
        // FDS% q. `  G/ t# `7 B, ]3 I
        if( (exsound_select & 0x04) && no == 0x300 ) {6 c$ \9 A% v; U% U  f
                return        m_bMute[6]?fds.GetFreq( 0 ):0;) k% a. d0 n( \. E
        }
6 C8 x- E3 S4 K0 c        // MMC5
; k7 j! H/ y! L& k2 g        if( (exsound_select & 0x08) && no >= 0x0400 && no < 0x0402 ) {
! U5 G. Y# F$ r' e" Y4 @% p9 ^                return        m_bMute[6+(no&0x03)]?mmc5.GetFreq( no & 0x03 ):0;
1 P$ f' s) p1 }2 T+ `" X        }
4 ^. ~5 ], p1 Z7 v        // N106
, O8 ]/ O" F4 F        if( (exsound_select & 0x10) && no >= 0x0500 && no < 0x0508 ) {
/ _1 ^* @( ]- F: a/ C; q                return        m_bMute[6+(no&0x07)]?n106.GetFreq( no & 0x07 ):0;
/ A* l9 W- i2 k0 N3 b8 p        }# R+ H4 \9 L# r
        // FME7
, t, X/ Z8 U8 |        if( (exsound_select & 0x20) && no >= 0x0600 && no < 0x0603 ) {
6 l! l3 p& \) ^4 W; z                return        m_bMute[6+(no&0x03)]?fme7.GetFreq( no & 0x03 ):0;
; _. R) F) @" p/ J        }1 I3 E4 x! g# ?
        // VRC7
+ s2 M, Y+ Z4 P! \( X        if( (exsound_select & 0x02) && no >= 0x0700 && no < 0x0709 ) {- n8 X! x# j$ w1 J% u4 C
                return        m_bMute[6]?vrc7.GetFreq(no&0x0F):0;
0 R0 W  K0 b/ {8 ?) p        }7 t0 P6 j  [: U$ z
        return        0;! L" A. I" z+ x. i+ r5 I+ Y
}; `+ O5 ]/ p, Q1 l/ }

0 O% E4 h0 q' J) r// State Save/Load( q) g% Y" ]( @, v. b$ w
void        APU::SaveState( LPBYTE p )" u8 V1 ^  s( h1 H
{
# `$ `6 \  H+ P; u7 |8 F#ifdef        _DEBUG: k9 C0 y. j: s0 G: v7 s: k
LPBYTE        pold = p;
. l& q" N. h+ x3 v+ V  D; _#endif
! k1 c" C  E$ ]- Y! n! G3 d
6 y- ^& g, j7 U$ E0 x& e        // 帪娫幉傪摨婜偝偣傞堊Flush偡傞
& h" k2 s; C9 u$ `        QueueFlush();
+ v8 j- i9 ?  `7 ]4 N( w: `
3 V1 G9 N* l/ ?2 k        internal.SaveState( p );# q( S6 Q9 N1 C' W* _7 A" M7 a
        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding8 C- Y8 D: [( h1 B: z3 `
" N5 P3 y4 ]! X4 v6 h5 Q
        // VRC6
$ V2 n, o3 D- P: s% f        if( exsound_select & 0x01 ) {( [" K7 j6 E  ?  D+ O
                vrc6.SaveState( p );( s) o* Z3 f  A4 c
                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding
9 v" I3 V. g' }# E/ X* b1 _        }
3 ?4 B. s8 l8 W" T& I        // VRC7 (not support)
9 J: S+ Z8 K* y7 u8 C" z        if( exsound_select & 0x02 ) {1 P( f2 D; I' S
                vrc7.SaveState( p );3 e8 G0 M; c5 k! c
                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding' l$ ~" V, p4 R( r) R: S5 f
        }) g4 w, n) |+ x$ I% ^! C& \4 m
        // FDS
. |2 ]! u; o) r5 k        if( exsound_select & 0x04 ) {; U# L( p# I0 @
                fds.SaveState( p );2 N% e: Y) R% Y% A7 Y' b" `
                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding: s% B* _& L! K2 Q; O
        }
8 D0 O4 j" X4 {; i: `% Q        // MMC59 e; T* D9 }: G" s
        if( exsound_select & 0x08 ) {# \# s6 @" `, X# C4 E0 D# G
                mmc5.SaveState( p );3 X, z4 i: n9 p7 L$ a4 g
                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding# G/ `+ W3 k+ E8 A- Y
        }
0 H! i1 w/ J6 C" T; g4 F5 G, J        // N106
9 |9 p, C1 R3 Q        if( exsound_select & 0x10 ) {
4 K. w. }9 u: Z" [" V7 A                n106.SaveState( p );% t% b0 O( ~# E) P
                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding
- C* R& |/ G$ r        }
; C. y% W% `7 p2 n! }& J9 c" O$ }/ Y        // FME7
3 V* f. L5 u9 h        if( exsound_select & 0x20 ) {
4 X0 d8 Y' I" T. Y" ^/ @* n+ ]" Y                fme7.SaveState( p );7 W; J' R# U  G* w6 j7 F% T
                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding* O0 Z4 O9 Q/ Z" D% W
        }, F) u$ o. G3 M
6 ^3 H/ e8 ?6 g
#ifdef        _DEBUG8 u$ i- }  R& m" v* e+ B! K
DEBUGOUT( "SAVE APU SIZE:%d\n", p-pold );+ E) A  H9 p: N# E3 ~
#endif, z/ l. P7 m# |( j3 R
}
  l' r" Q$ {3 E; [( {7 q. k, j1 D" L* D
void        APU::LoadState( LPBYTE p )
- ], @5 y9 V) M0 w" G4 T' @( |{
4 T4 V  b& g% E1 c% f% x        // 帪娫幉傪摨婜偝偣傞堊偵徚偡! p% L3 ?: Y+ f6 Y) G. u! B6 x) z' P
        QueueClear();
+ ]/ s. J; q- i9 B. u  h5 u0 g; V1 h6 l5 u
        internal.LoadState( p );2 u+ g0 B* z% y5 R, g5 @
        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding
( q) d* G& H# E+ m! j) z& T1 O) R1 p- x7 @
        // VRC6
5 z" ~( @, S7 u- T        if( exsound_select & 0x01 ) {. P) N1 D) @, O1 {. B/ A6 T5 Y* V
                vrc6.LoadState( p );7 `& `  P4 M; R
                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding0 W) `7 x; C0 T% [: X3 w
        }
8 s# B9 `: ~, c7 `+ C        // VRC7 (not support)! g# H& \9 ^: ]1 G% ~
        if( exsound_select & 0x02 ) {
" p1 [& R& h7 f/ J                vrc7.LoadState( p );* D. z6 ~' {: L$ G- k# ^$ C; M0 A
                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding% M; P( C5 j3 p) y2 t
        }
9 e4 `. C" J. o; j( i        // FDS
. d: @; T/ d9 n( e4 I6 B, u        if( exsound_select & 0x04 ) {& i" @$ \& x; K0 w5 O1 v, A
                fds.LoadState( p );/ P" v' R  q2 X, |
                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding
: B* f5 l" ~) r6 d        }
: @5 Z& J! G- T2 m        // MMC5
7 v( F& R: y/ w2 p7 u1 p: r! }        if( exsound_select & 0x08 ) {  R( c$ O8 R8 i" M
                mmc5.LoadState( p );
/ ]; E1 U, m. ]7 e+ m6 w6 B                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding
/ I' X6 m3 u( R9 Q/ p6 L/ T. f8 B        }1 a  ^3 ^! j* z* `: M+ f; r
        // N106( [0 X* ^' B: S6 e
        if( exsound_select & 0x10 ) {/ v4 V/ G, G7 g, P, p  ^8 Y% z7 D
                n106.LoadState( p );
! x9 I$ F2 ~1 a& [0 m' n, b, X                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding
; X% d" ?  V* D- F        }
2 j; a$ o1 N9 {( n' j7 N2 C0 N        // FME72 S3 R/ C% `7 K! n
        if( exsound_select & 0x20 ) {
2 Q+ H0 o7 c, }, d8 j+ {. {9 z                fme7.LoadState( p );& y) L  k. y: ~8 A$ z% i0 z+ W3 ]" @
                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding& S% T, L5 I% d* C: _7 i; Y* ?
        }- ~  X/ Z% O! c( w1 ]
}

该用户从未签到

发表于 2009-11-8 17:25:37 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 14:38 发表
$ h3 G+ x: j" V' r可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。' R- |. B" b& r2 E
感激不尽~~
& ?" ]. \6 {% j6 r7 G
恩 我對模擬器不是很有研究,: s' u% F, y6 z
雖然要了解源碼內容,可能不是很困難,8 B7 m8 ]8 y7 y, d5 O8 ?, \, H
不過還是要花時間,個人目前蠻忙碌的。) z  {- Y4 O$ f6 K

8 u5 y. ^( t- ?3 L, W) }給你一個朋友的MSN,你可以跟他討論看看,
' m5 N6 {! h" f6 ^8 _0 `5 z他本身是程式設計師,也對FC模擬器很有興趣。
* s$ _! x# @# c/ q! r3 c; {6 f& Z* j% A/ g3 h( ~7 q) \
MSN我就PM到你的信箱了。
% l, P- O' y  z2 C8 g% R( o) r( r1 B: H
希望你能有所得。

该用户从未签到

 楼主| 发表于 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 发表 3 n% W& @& s' [0 m
呵…… 谢过团长大人~~
8 {& i* u7 Z" i; M0 [+ ~* W
/ @) T7 h/ Y, k$ N
哈 不客氣,算是順便幫他找個伴,大家可以一起玩。

该用户从未签到

发表于 2009-11-20 13:14:53 | 显示全部楼层
原帖由 李伟 于 2009-11-9 16:02 发表   R! v2 B% u) h% V" D7 A* S) d1 a
团长的朋友都是神,那团长就是神的boss。

) R+ g, h7 Y. r" j& N' M哈 不敢當,我只是個平凡人,. `+ |% g8 q% U8 w
要吃飯喝水,光吸空氣是不會飽的。。。。 :)

该用户从未签到

发表于 2009-11-20 13:32:35 | 显示全部楼层
FC模拟器的部分有个人可以帮你忙
3 t: a3 V. U" ~1 {8 `! I* s9 dZYH
) C! V# M9 r6 V5 r- NQQ:414734306; c  ?$ p3 H& P' y
Mail:zyh-01@126.com
. u) w6 O5 H$ H: W; O3 T) e8 X9 w$ _3 Z8 ^1 u, O
他是ZYH Emulator这个模拟器的作者,只是他用的开发平台是VB,不过就6502的实现原理来说是一样的

该用户从未签到

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

该用户从未签到

发表于 2009-11-27 19:09:06 | 显示全部楼层
原帖由 独孤残云 于 2009-11-27 09:48 发表   \) N) T# n( c' x0 F6 Z
再次对团长大人和悠悠哥的无私帮助表示感谢~~
$ h1 u5 N. f) f7 x
不客氣  ^_^
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2025-2-19 06:17 , Processed in 1.104492 second(s), 19 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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