EMU618社区

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

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

 关闭 [复制链接]

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 09:56:34 | 显示全部楼层
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。; ?3 b* G0 o( \) m
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~3 N5 m4 B  g2 {0 `# O  y2 @$ o7 B
这里有相应的模拟器源码,就当送给大侠了~~
2 d$ o: j8 Q  @! Y6 Ohttp://kenkao.qupan.com/5096520.html

该用户从未签到

发表于 2009-11-8 11:31:10 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 09:56 发表 9 a" n- O4 p* v6 `2 q5 [# {
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。$ M4 r5 T: Y  r1 o5 U. u
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~
1 `" C' C+ {& n. {2 i这里有相应的模拟器源码,就当送给大侠 ...

; Q: ?, M7 R7 N' j$ r聲音部分(Audoi Process Unit = APU):# S. H5 m& ^- T0 o' V9 o  ?
.\NES\APU.cpp% j& H* S( Q" c* `. s
.\NES\APU.h$ h0 P  e8 B; S+ Z

8 ~6 k9 B( Q- i4 N
  k  J; X. J. B4 @影像處理部份(Picture Processing Unit = PPU):3 L3 E1 k% F# m: i
.\NES\PPU.cpp
0 O" V' E& \5 W+ O) F! b* r: h/ ].\NES\PPU.h
( `% W0 M/ l/ u! c! q* ]
! [3 a; p+ z2 |/ f4 G, M( [* |如果原碼用C跟ASM混搭也不錯

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 14:38:21 | 显示全部楼层
可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。
6 d8 d) z3 Q( K/ h" Z. x感激不尽~~

该用户从未签到

 楼主| 发表于 2009-11-8 14:47:50 | 显示全部楼层
这是我手中源码Apu.cpp的内容,敬请赐教:/ h6 v3 P  E, T9 l! z6 _4 x
(由于很多专用术语和算法机理都不明白,所以看不大懂……); `- o. O6 ?0 g4 Z6 i) V
//////////////////////////////////////////////////////////////////////////5 x9 Q. T8 c- k" Z+ C5 |( M- y
//                                                                      //
- T+ f* L2 U" H2 a; g//      NES APU core                                                    //
5 d- t# D' x. ]$ Q//                                                           Norix      //' `8 H3 B) \% c! p7 o
//                                               written     2002/06/27 //, r0 v; ~, t  }$ v4 ~- `+ ]
//                                               last modify ----/--/-- //
& C) p+ M2 R, d, t; G. J6 i! P//////////////////////////////////////////////////////////////////////////
( f8 K: A7 O  x6 E#include "DebugOut.h"1 n  u3 R6 Q0 z. c/ D
#include "App.h"
/ `' @. a7 b: Q3 C8 M- n#include "Config.h"* @' n: S* S! p; z2 D

% ]0 W0 r1 }: g5 }#include "nes.h") w3 j4 _# |, d
#include "mmu.h"( [, f' g8 f, T# d$ i: q1 i( ^2 a
#include "cpu.h"$ q  x" C) f* I
#include "ppu.h"- v" [2 S+ @$ }9 o) X. d) |' s) N; T
#include "rom.h"
9 w# Y% |& t) P3 y+ |6 o& M#include "apu.h"% w% `6 C. q) Z/ ?8 d! @4 Z8 ~

. o' ~  n' O! e: Q! M8 }// Volume adjust
7 W8 Q, z1 e$ ^5 r( g' W" G// Internal sounds/ Q3 _- J9 u" l- A7 }, j
#define        RECTANGLE_VOL        (0x0F0)
9 n. n: R. a9 D+ E, \#define        TRIANGLE_VOL        (0x130)9 a" Y; [; e8 K  e5 g3 u" J( z7 I
#define        NOISE_VOL        (0x0C0)4 d9 ~, e% b3 v; ~3 @. u
#define        DPCM_VOL        (0x0F0)
' [( ^* L8 D6 {$ K( C  Y// Extra sounds9 R* z4 H" G7 L, O5 m4 B' Q
#define        VRC6_VOL        (0x0F0)
  z" u. k# q2 I#define        VRC7_VOL        (0x130)
- o8 D5 V4 w2 g. i# _! U#define        FDS_VOL                (0x0F0)
1 s/ ^: o8 t$ l' r#define        MMC5_VOL        (0x0F0)) h$ |9 Z" @* ~! m+ O! k
#define        N106_VOL        (0x088)
: m) b% ?6 a" q/ x( i5 T#define        FME7_VOL        (0x130)
/ p0 x, D2 d) W  K
' [+ @0 p! u4 e9 \; U( o( \5 WAPU::APU( NES* parent )& t* ]1 c0 ?+ F0 {
{
- @; f3 y+ y. a9 Y, l5 d        exsound_select = 0;
, @/ }8 H' o" k, m4 ]* O9 G: w$ C3 I/ F3 ?
        nes = parent;
' U% M  ~  M3 d( f6 J8 t  l- S. Y        internal.SetParent( parent );
. |8 E# D$ A: \9 ?5 T( }: ?- |6 k) R9 r9 ~/ o
        last_data = last_diff = 0;  b$ |4 d( `( E& A3 f8 _0 e" W
  P8 o$ N# [) C
        ZEROMEMORY( m_SoundBuffer, sizeof(m_SoundBuffer) );6 R, t( q( O  m

) Y. a3 l$ N; z( p. t; p        ZEROMEMORY( lowpass_filter, sizeof(lowpass_filter) );
6 n8 I' j7 x, x; ]. e        ZEROMEMORY( &queue, sizeof(queue) );
, C' t* b4 o6 M& H. J        ZEROMEMORY( &exqueue, sizeof(exqueue) );
$ D# |+ y; f( o
. U9 A2 W% w+ S, p/ e        for( INT i = 0; i < 16; i++ ) {. ~2 v) ]8 P8 L4 m6 p5 S1 \
                m_bMute = TRUE;
% w; q4 c$ K8 K& E8 Q' c        }
0 u' a) Z/ D% `3 b}* \, E  I% C. t
! M+ r) Z* [! E8 j" ~& x$ h
APU::~APU()7 _7 r+ }( ^. X5 b' ~( l
{
+ w3 K' E6 H% z. Q8 O, W9 b5 `}. {9 x8 y/ Q0 I! `+ ^+ x& |
  _, v* ?* u& P/ z
void        APU::SetQueue( INT writetime, WORD addr, BYTE data )1 g: M8 V( J+ \3 N) R
{
- a% l0 n8 D& P0 I# h        queue.data[queue.wrptr].time = writetime;
. V+ S1 S0 y5 t0 Z3 f0 X% `        queue.data[queue.wrptr].addr = addr;* A+ o2 {4 h  Q- t7 K" T9 C9 j
        queue.data[queue.wrptr].data = data;
! t5 Q0 _& J1 Q) B. b        queue.wrptr++;$ ~$ s: v2 i0 H* H, G) J2 p
        queue.wrptr&=QUEUE_LENGTH-1;& v* c5 @. ~% s, S
        if( queue.wrptr == queue.rdptr ) {
( f! T: \/ o5 F# _, z; r& A                DEBUGOUT( "queue overflow.\n" );
# g- t2 S0 H' ?9 k7 u3 U        }
# Q2 Q( f) ], a1 v}/ b& p5 a$ z; B

6 X0 H6 k% j5 @6 }, O2 G8 |2 jBOOL        APU::GetQueue( INT writetime, QUEUEDATA& ret )
: |& p. b9 ]6 g9 H' y1 l{  k, |" R4 M- @# N% s" h
        if( queue.wrptr == queue.rdptr ) {8 t: I" x8 E' r4 o+ d3 @0 L8 u6 Q
                return        FALSE;- f; i  |* i" g/ c
        }8 u% d- p$ |! ^7 U0 [2 R
        if( queue.data[queue.rdptr].time <= writetime ) {6 b9 y$ z8 J7 o
                ret = queue.data[queue.rdptr];
% i) |9 t$ z$ R" R                queue.rdptr++;
* d) c3 j( g- A2 V( n0 F                queue.rdptr&=QUEUE_LENGTH-1;
6 [0 x! @0 }* I% }% z                return        TRUE;: ?! R2 ~1 R2 F# I9 {
        }& S9 {. e! I5 O. r2 C/ m7 k
        return        FALSE;$ e0 \( V5 D$ t3 I6 ?
}
8 Q7 X+ S* [' Z/ R* G: u% w$ g) G/ b$ t& O
void        APU::SetExQueue( INT writetime, WORD addr, BYTE data )7 p) f2 U, h) Y( y1 _5 o
{" y, t5 ^7 D, a1 L& E1 K
        exqueue.data[exqueue.wrptr].time = writetime;
% S6 i/ l& E* K        exqueue.data[exqueue.wrptr].addr = addr;* l; Y4 }6 w$ ^2 @1 {* L" r
        exqueue.data[exqueue.wrptr].data = data;
1 r; |5 s) M9 h2 |- M        exqueue.wrptr++;- X, a; \* k4 U, J' i$ m) ^' f
        exqueue.wrptr&=QUEUE_LENGTH-1;, k1 Z6 M3 I, g1 ~+ E
        if( exqueue.wrptr == exqueue.rdptr ) {8 [, Z: b, a+ Z8 r* }7 }8 b  p
                DEBUGOUT( "exqueue overflow.\n" );% a$ _4 Q  G& K8 M% i$ z* j
        }
5 U) l' s; V  s' r( i! N( h}
9 t+ b1 q4 p2 x4 o( V' T7 w$ t3 x
7 X  [2 ?3 A. E$ M9 eBOOL        APU::GetExQueue( INT writetime, QUEUEDATA& ret )' l( u8 [" W- c! {. Y
{) O2 o* e; P$ B
        if( exqueue.wrptr == exqueue.rdptr ) {  i& d$ w  L- K
                return        FALSE;
) x3 e9 p; J/ e4 t: d8 P8 v, H        }; Y, _- u, b2 M  L# b3 X8 M* m/ H$ i2 @
        if( exqueue.data[exqueue.rdptr].time <= writetime ) {
. L0 L% e  v" l, s0 x3 @                ret = exqueue.data[exqueue.rdptr];/ Q  A8 M7 K" l1 _7 k, d& A3 m
                exqueue.rdptr++;( S8 o0 i6 C7 G( P4 d' N( E/ ^
                exqueue.rdptr&=QUEUE_LENGTH-1;" ]/ V+ b9 L2 F; v1 r' ]2 {# ]
                return        TRUE;
1 m* U% R8 N% {. O        }7 d  ]( K5 q2 t0 r
        return        FALSE;
  D2 z) t" L. e: ~. E# t, ^) B% j}0 O" e6 D0 z( z- }

) |! P& M! P$ y" J- cvoid        APU::QueueClear()
5 Q$ K6 @9 q- E/ s2 g' k3 L+ `6 e/ \{- e2 L; L7 C1 E' Q, t7 R
        ZEROMEMORY( &queue, sizeof(queue) );
0 z7 n5 Y, p% E        ZEROMEMORY( &exqueue, sizeof(exqueue) );
% B  e- r( H9 L}1 L- E2 A3 V6 A$ R
4 ~) E. {+ d. }( p! U
void        APU::QueueFlush()  d7 j1 F8 _! [. F8 Q' t& N) ?0 \
{
- V7 }5 B7 A$ \& k7 v, E5 g- I        while( queue.wrptr != queue.rdptr ) {
$ `! ~7 k; t4 S! P9 e                WriteProcess( queue.data[queue.rdptr].addr, queue.data[queue.rdptr].data );7 t9 O' \9 o2 f3 ~
                queue.rdptr++;# C  F: z  T* T
                queue.rdptr&=QUEUE_LENGTH-1;
2 k+ M: U( [3 K7 b5 Z7 R. }" |        }
1 G5 x7 X: i2 ^# A3 ^# X* z& n: Q; S  V% Z: `
        while( exqueue.wrptr != exqueue.rdptr ) {
# d1 c/ v! x& F0 u1 I1 A7 e                WriteExProcess( exqueue.data[exqueue.rdptr].addr, exqueue.data[exqueue.rdptr].data );
* _0 s4 h% \% t+ _  L                exqueue.rdptr++;
- G% h' N4 d6 s" F5 P6 b                exqueue.rdptr&=QUEUE_LENGTH-1;, Z* {) P3 j/ P) l/ @3 w
        }9 K. y2 Y5 p1 s) |6 W7 |7 j
}9 x8 f* \: n. w9 O, p
" [. L. T1 l  _6 k' l
void        APU::SoundSetup()
; N* Z3 i2 S% H  h( r  m" ?{4 i6 j2 w# M0 b% M2 x
        FLOAT        fClock = nes->nescfg->CpuClock;& o# [1 k" [. u
        INT        nRate = (INT)Config.sound.nRate;; l. T& g* b! V8 c
        internal.Setup( fClock, nRate );
! y) M' ^3 O+ S4 w: r  N6 a        vrc6.Setup( fClock, nRate );$ ]; c* w, H& U( D+ l' W6 x( Z2 A
        vrc7.Setup( fClock, nRate );/ }% m2 Y7 A0 k  C" {* Z1 G
        mmc5.Setup( fClock, nRate );
8 l+ _& ]' x6 d5 B* _9 x        fds.Setup ( fClock, nRate );
6 }. H8 i' B8 L* J2 M- `  [0 h0 a        n106.Setup( fClock, nRate );
- V8 s4 ]; @* e% J5 L        fme7.Setup( fClock, nRate );
# G& n4 ~: S  y6 v4 U- E}
; O/ W: q! J( H8 D
: A# J) M3 D/ I, ~4 u& E% fvoid        APU::Reset()
4 ^% Q0 m$ C' J/ }{. T7 u; I" D: [
        ZEROMEMORY( &queue, sizeof(queue) );4 D. k+ a0 ^; J, R8 R
        ZEROMEMORY( &exqueue, sizeof(exqueue) );
* R" u- ?7 H% k1 x, t7 k: ^& |6 ], r3 f9 b) J% N& b, Z
        elapsed_time = 0;# G8 g# W- @& l2 H5 f/ A

% B$ H' L" \; G, o        FLOAT        fClock = nes->nescfg->CpuClock;9 }$ Q9 {8 w, U5 G! ]; u
        INT        nRate = (INT)Config.sound.nRate;) M( m" Z8 M8 G& I/ p2 @
        internal.Reset( fClock, nRate );7 L6 t+ C' F/ `) m9 r+ C: ^# B8 y
        vrc6.Reset( fClock, nRate );. F/ Z+ \$ K  P* A( r
        vrc7.Reset( fClock, nRate );' P5 _% C2 |% _! T- g! |
        mmc5.Reset( fClock, nRate );/ U3 V* O) J3 ^9 \  [
        fds.Reset ( fClock, nRate );) Q' G6 e5 k7 b1 H
        n106.Reset( fClock, nRate );
0 e4 V9 J* l" I* m! j        fme7.Reset( fClock, nRate );/ c( Z1 l. f* g
' Q( f. F; S! X, A% \
        SoundSetup();5 ^5 @, R+ J. _- z# ?  @1 N$ x: ~
}
2 _4 z; Y/ C9 W% h. w3 |
3 n* Q+ |* @9 cvoid        APU::SelectExSound( BYTE data )* X4 s8 S9 v) z
{7 F# I1 ]3 ~: I3 q. v1 N
        exsound_select = data;
0 Y! e0 c  L& Q8 V$ \$ r# S6 x9 k}
9 d! ^  {% C. r+ y$ R- A
) ?* b; w- t# rBYTE        APU::Read( WORD addr )5 A% n/ p8 z9 C1 S) G$ }
{
" q) _' @5 w7 b+ L2 \        return        internal.SyncRead( addr );
0 _5 |( }, ^# N/ W. Z% M}& J6 ]! k# h: ~
7 u6 ^2 `+ i' B" Q
void        APU::Write( WORD addr, BYTE data )$ f9 {8 E; S$ \+ A- u0 g
{
' w# \5 I; o9 Q8 _, a( w  t' o% T        // $4018偼VirtuaNES屌桳億乕僩# X* `, n, V9 X3 I8 L* E4 o
        if( addr >= 0x4000 && addr <= 0x401F ) {( I& S$ @; O; V
                internal.SyncWrite( addr, data );
; L5 _- q0 ?9 ~5 R( m( A* t# P                SetQueue( nes->cpu->GetTotalCycles(), addr, data );
9 M% s$ u+ p* A; z        }
8 F  f' _$ J3 w0 X2 z) ~}
0 {: U+ N/ J0 `3 {  s, U& Y! R0 Z7 \, c: B+ |4 C  U
BYTE        APU::ExRead( WORD addr )
( y4 T  M7 A+ z" o. I{" Q0 ^+ [5 j0 ~6 T- n' Z- R1 R
BYTE        data = 0;
  {# V' r; x0 d$ d) n% E" h9 p$ v( E$ H
        if( exsound_select & 0x10 ) {7 P7 w& }& q. i. V  b
                if( addr == 0x4800 ) {" |( y& G8 \) f0 p8 G
                        SetExQueue( nes->cpu->GetTotalCycles(), 0, 0 );
4 c3 n3 M) P. y! L/ v                }- A) f4 C; v9 P7 ?5 n& E* _
        }$ ^( O9 Z9 P8 L8 _3 X- `+ _6 {
        if( exsound_select & 0x04 ) {! Y' Q- |& l! j; O
                if( addr >= 0x4040 && addr < 0x4100 ) {9 w8 x1 Y/ M# d6 V* t
                        data = fds.SyncRead( addr );3 o4 Y- t. s; ?0 m3 m) e
                }
2 E) ^, K1 {; i/ P        }$ U; w) d4 ~. b2 Q' c. X
        if( exsound_select & 0x08 ) {
% E2 @" s& a" s6 ?2 u" v1 n                if( addr >= 0x5000 && addr <= 0x5015 ) {
1 H3 D  f/ t' W# n9 O                        data = mmc5.SyncRead( addr );
9 N2 n! \1 E3 k7 \2 ^& m  @; h                }3 H$ S. J, L9 s4 _  n/ v9 B
        }' ~: Q. \2 E3 z8 B- a
5 w8 i; _+ f) v. \9 w6 `
        return        data;
3 `% B( e( @9 [+ z) E0 ?}, a5 s% b) d) j& }: w% R
! D0 O( w' S$ L# y, U+ z
void        APU::ExWrite( WORD addr, BYTE data )6 u. `3 P' E" @# z; g
{& m! b) c. {9 E' L8 ^) U+ ]
        SetExQueue( nes->cpu->GetTotalCycles(), addr, data );  T. Q2 P6 ], _& O/ Y- e
+ C4 ?6 M# e7 s1 s; t) E9 q
        if( exsound_select & 0x04 ) {
% d/ o( u& y# ]$ f; n                if( addr >= 0x4040 && addr < 0x4100 ) {! ^  F9 M% n. Y) l9 v/ ^6 n: \
                        fds.SyncWrite( addr, data );
/ m- ~3 Z* Z/ j' Q4 y                }
0 R; j$ ^! Q  @' e: i- e5 D# `        }
* |0 Z2 h: Q( z
" e/ a: t7 G# G" d- `: L, \' q        if( exsound_select & 0x08 ) {* z) \$ ?% L0 d# ~4 Q* ]3 u
                if( addr >= 0x5000 && addr <= 0x5015 ) {
3 `( B, c& F& H( N: M) p; ?6 y- ^                        mmc5.SyncWrite( addr, data );% z# R6 o! i7 S5 ^
                }0 i: L" l6 h, w* _7 A  f5 ]
        }
( g9 ?2 `# u  |, [0 ^}0 ^2 K' c1 {0 R+ F/ w
1 u% L& Q6 {+ H
void        APU::Sync()0 {5 y0 a3 w' W9 A: t6 x: f
{( R) T  p: s! I; @
}' T) a8 D8 R1 Z

$ P1 b1 _" e* c7 k1 Bvoid        APU::SyncDPCM( INT cycles )
: K& ], m. ^4 r$ `{
0 B& \8 C0 e5 K9 _7 m' R4 T        internal.Sync( cycles );, B& A4 b9 L8 \2 R7 s4 h
+ {; E0 W. e/ ^9 m; y2 E
        if( exsound_select & 0x04 ) {$ i% {: Y3 v4 K1 i
                fds.Sync( cycles );
4 Y$ a7 U3 @9 r7 S9 p4 d        }8 k9 R2 y; |/ ?. C7 p- L
        if( exsound_select & 0x08 ) {0 C2 `* q' S6 u2 t3 W7 v3 y' {
                mmc5.Sync( cycles );0 G5 W- A" d: y
        }( g7 f+ B2 y8 h' U
}
! t# Y9 ?' |" ]5 L# J4 F9 A* D; w6 Y; W
void        APU::WriteProcess( WORD addr, BYTE data )! ^. F; J# ~- a! @$ u! m. Z
{
1 m8 u( |5 Y- t: y# ?) J# l        // $4018偼VirtuaNES屌桳億乕僩
8 |$ J2 P! X3 U* d        if( addr >= 0x4000 && addr <= 0x401F ) {! T$ B5 _4 b# w  Q
                internal.Write( addr, data );$ ?" M& A9 p# R5 ]
        }
7 O7 q8 w7 h, K5 l1 J" m( _5 n1 y$ D}* p: p: o5 k* X( i* ]* I3 E
- H2 R; K$ ?) z
void        APU::WriteExProcess( WORD addr, BYTE data )6 z" [( ^+ ~6 f* E9 w
{
7 L, p. N# ~) W/ x! P, L0 _        if( exsound_select & 0x01 ) {$ M7 B' Y1 o3 h: }2 L- @$ t
                vrc6.Write( addr, data );
9 ^, l  n6 {; t5 U7 D        }* y/ s  M* \% u% f$ t
        if( exsound_select & 0x02 ) {
* u( v1 Q# {! F, h) L7 [- _  u                vrc7.Write( addr, data );
9 q! F, ?$ F5 g# r5 W! R- ?9 Y        }1 k) i$ P2 z# r: i& |9 ?; V
        if( exsound_select & 0x04 ) {/ K9 J- O9 H% z4 u9 p
                fds.Write( addr, data );
6 C, B/ E  p6 y3 z        }
7 t4 g2 K, `6 M2 _+ x3 F0 E' D        if( exsound_select & 0x08 ) {
* d( b3 `$ o0 q  q! G7 n" z                mmc5.Write( addr, data );
( c% t: ^5 E; {, C5 f        }
: X/ a+ u2 c# _        if( exsound_select & 0x10 ) {
. F& y9 d8 n9 B                if( addr == 0x0000 ) {: D( a4 K- l5 _+ Z% \0 P* e
                        BYTE        dummy = n106.Read( addr );
$ v$ Q8 _! m1 U                } else {
$ M$ E5 \# i$ H1 j1 S  l; u                        n106.Write( addr, data );! l1 `1 q" T3 n. v* S
                }6 v: l- j3 ~+ L7 P
        }
* O- j! h/ j2 b0 z        if( exsound_select & 0x20 ) {
: ]( m$ k* ]7 P2 p6 M                fme7.Write( addr, data );; W" _& p+ s. H
        }  z. N) f; W+ l" v+ W) }( Y: X
}
4 L8 w( E; i5 i* |. `, F" ]+ B
4 o% H/ u+ [. E, Yvoid        APU::Process( LPBYTE lpBuffer, DWORD dwSize )
) G& ?! m9 n& Y0 g+ l% u{
5 ^/ G1 ]9 l' RINT        nBits = Config.sound.nBits;4 A2 g- u: V+ o1 V
DWORD        dwLength = dwSize / (nBits/8);
; c9 d7 b9 o3 E% N" [INT        output;: {; v' r% e5 W
QUEUEDATA q;  ~+ t, n- N( R" O" C, _' {
DWORD        writetime;
; [( `- ^8 W- L
+ d+ L3 h+ k9 Q3 p4 c3 hLPSHORT        pSoundBuf = m_SoundBuffer;
: g/ s' {" B* D$ G' i' OINT        nCcount = 0;9 f" B0 X( o7 }' F, L) P
7 z2 x! x6 _: j& h  {4 _
INT        nFilterType = Config.sound.nFilterType;
9 P  Q, Q7 p  ]) h% b2 q2 d) L$ @$ S. f9 e& y
        if( !Config.sound.bEnable ) {
) n" y5 _; N8 |; ]                ::FillMemory( lpBuffer, dwSize, (BYTE)(Config.sound.nRate==8?128:0) );
: G+ u) t# a9 X# S! c' J                return;/ |5 R% D: R& m  o! N* r
        }
/ j3 x- _6 T  U. {& {* k7 R3 q* e7 C
        // Volume setup4 f5 S4 {  g. ~4 F1 R. `0 ~5 }
        //  0:Master
2 k! r- Z! H' K, @" o+ ?' C; n0 h        //  1:Rectangle 1: p2 A+ j" x7 C5 U
        //  2:Rectangle 2
' ]! c( P/ e1 C: u- s( i        //  3:Triangle
6 ~2 [. _4 R( ?" {        //  4:Noise  A! W9 u8 i1 W/ ^/ {8 ~$ ?& Z
        //  5:DPCM
$ w5 n+ S7 h( o0 O/ O0 \# P8 q9 y        //  6:VRC6
( y7 m7 o; @8 L7 M- Y7 e        //  7:VRC77 |7 [  K9 {6 i, p
        //  8:FDS) r2 C1 B* C- v- g8 R5 X) ?
        //  9:MMC50 W- ~7 m7 L7 A1 B! E/ E
        // 10:N106: X, F9 M! g7 S( e" N( b% ?+ L
        // 11:FME7
) c/ C: t  }* H4 ~        INT        vol[24];3 T# F) h' i$ X5 D# e" G. _
        BOOL*        bMute = m_bMute;
2 q7 X, S3 W  |        SHORT*        nVolume = Config.sound.nVolume;  z& T& F: d0 d# i8 n  P
  m5 D! \; P/ ?. w2 x$ a
        INT        nMasterVolume = bMute[0]?nVolume[0]:0;$ f7 u( ^& z' ?

* t4 k; Z1 v% O7 {7 a        // Internal
# S' d2 q: C+ q' C$ |        vol[ 0] = bMute[1]?(RECTANGLE_VOL*nVolume[1]*nMasterVolume)/(100*100):0;5 h$ y8 w' b) j" x* E4 T
        vol[ 1] = bMute[2]?(RECTANGLE_VOL*nVolume[2]*nMasterVolume)/(100*100):0;
' Z" M1 Z6 w$ A1 V9 E, l. s- n        vol[ 2] = bMute[3]?(TRIANGLE_VOL *nVolume[3]*nMasterVolume)/(100*100):0;9 _. H5 G% k. I: w. k8 T
        vol[ 3] = bMute[4]?(NOISE_VOL    *nVolume[4]*nMasterVolume)/(100*100):0;3 D/ v" a1 e1 e4 C6 J# E( M8 ^
        vol[ 4] = bMute[5]?(DPCM_VOL     *nVolume[5]*nMasterVolume)/(100*100):0;
; Y) N9 Z, |& H+ Z# M, o- [1 J+ V. Q. l! n9 c
        // VRC6. u# l6 L; ^' B5 o) {( Q
        vol[ 5] = bMute[6]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
8 v( z# f5 w: b        vol[ 6] = bMute[7]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
1 V, v* {" T4 [) W        vol[ 7] = bMute[8]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
$ x# E( |* }8 U' t5 ^% X
: F5 K& ?. ]/ M+ W) @$ S  z) @        // VRC7
  j' c5 r2 L/ z, p' i5 o" ?" H' I        vol[ 8] = bMute[6]?(VRC7_VOL*nVolume[7]*nMasterVolume)/(100*100):0;
" P- v3 U7 p0 ~0 H# \( c8 l5 {
/ Z- m% M/ t! V- Q7 C& P& G        // FDS5 C/ _" i4 h, @& K4 V* ^
        vol[ 9] = bMute[6]?(FDS_VOL*nVolume[8]*nMasterVolume)/(100*100):0;1 Y2 X3 E" d" h5 \9 d) {5 u

. S; |, O& t/ n- l$ u8 T        // MMC5
# V- m- Z' @, \) }1 @8 r( C$ n" t        vol[10] = bMute[6]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;& x7 ~" }5 Y$ n8 m2 v4 Z% o
        vol[11] = bMute[7]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;) ^% Y8 z8 t, p' `4 p
        vol[12] = bMute[8]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;; h0 A9 G  x, u. ~

. |/ R! [3 }& Q3 P( S8 ^        // N106
- G# ~: H4 W- N7 I        vol[13] = bMute[ 6]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;( Z8 U4 k" e, |- n. q) E* Z7 C
        vol[14] = bMute[ 7]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
) {% W7 X. Z9 u' m$ j$ W& X  Q7 F        vol[15] = bMute[ 8]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
. ]! s  B$ l9 B  p# C0 M        vol[16] = bMute[ 9]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
: \6 v4 \9 E5 @4 b  D        vol[17] = bMute[10]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
2 a- {8 e2 o) z5 i  Z2 T' R8 E- w/ C        vol[18] = bMute[11]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;, l/ i" p( ~' X) X
        vol[19] = bMute[12]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
; p5 o+ R2 y) P" K/ |        vol[20] = bMute[13]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;& {5 I, x+ y% w4 E
9 a2 f7 C# h$ m' t7 D
        // FME7" M: k7 j2 F7 P
        vol[21] = bMute[6]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
6 ?, h) n# Z# Z" _        vol[22] = bMute[7]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
( m/ Z# K# K  v+ z5 Y, {        vol[23] = bMute[8]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;2 O* n7 o" m2 W

7 ^' z1 `3 i. x6 L& w//        double        cycle_rate = ((double)FRAME_CYCLES*60.0/12.0)/(double)Config.sound.nRate;
7 w) H/ f3 W6 G" y. N        double        cycle_rate = ((double)nes->nescfg->FrameCycles*60.0/12.0)/(double)Config.sound.nRate;
, o) o* |5 U2 m5 P
& B! u7 U0 ]$ a* G        // CPU僒僀僋儖悢偑儖乕僾偟偰偟傑偭偨帪偺懳嶔張棟
/ n8 ?* B0 G- f! W0 F        if( elapsed_time > nes->cpu->GetTotalCycles() ) {
, M$ T- V  E, e3 Q                QueueFlush();
) P1 h2 I& w  h: d3 }3 @* m  v        }" j' O  d! `7 u6 T; @. J
  `: P  M: n+ O# S, G5 p! W
        while( dwLength-- ) {: l# R; P/ O$ W8 O
                writetime = (DWORD)elapsed_time;
( M8 o' j; o' _( R* S  }/ K  Y8 i* B/ I9 a  i; E( V
                while( GetQueue( writetime, q ) ) {, i' i( E3 S2 s
                        WriteProcess( q.addr, q.data );
3 x/ h6 r8 H9 H6 c2 i                }
9 `  W4 Q4 }7 x3 U! x" x# j; k+ Q
! I3 K: [# R) j: w                while( GetExQueue( writetime, q ) ) {
# F" H! C, M( X( I; c                        WriteExProcess( q.addr, q.data );  o; b/ b! I8 ^. S" V
                }$ U: {6 Y$ ?; c+ p  Z% t9 e

$ u8 c$ z; v. d6 v& f' ?! _                // 0-4:internal 5-7:VRC6 8:VRC7 9:FDS 10-12:MMC5 13-20:N106 21-23:FME7
2 z' i4 ?5 }4 q( i, H  l                output = 0;7 b- \0 ]1 K7 Y- {3 v! {2 K8 Z) X
                output += internal.Process( 0 )*vol[0];
$ S& i* U4 b7 I2 x% Z( N" C                output += internal.Process( 1 )*vol[1];
" k- s9 y8 F6 o: Y7 b                output += internal.Process( 2 )*vol[2];" m. ^3 d  d" ~$ v6 b0 v& H
                output += internal.Process( 3 )*vol[3];6 x8 Q- T1 w, W- V4 k. b+ M, f& D$ w
                output += internal.Process( 4 )*vol[4];! S; t/ x, E; |9 R

/ r. D; y% l- R3 f8 T                if( exsound_select & 0x01 ) {
2 U* b# i" T7 W" l2 V& G  @                        output += vrc6.Process( 0 )*vol[5];4 }6 \4 |1 L1 d" @
                        output += vrc6.Process( 1 )*vol[6];
1 a4 x8 @) J; B% q, t$ R                        output += vrc6.Process( 2 )*vol[7];3 r" O' d( ^+ i* [. @* ]2 [
                }
' ?3 V$ h: ?5 d, A                if( exsound_select & 0x02 ) {
, L7 k% R! c9 r9 B' }8 m0 x. }                        output += vrc7.Process( 0 )*vol[8];
1 t. @7 x2 c) Q  ]3 i& ]( T5 I# H- L6 q                }
; Z' }, ^0 _' P2 y- r                if( exsound_select & 0x04 ) {
$ s* d) T) l1 X# j/ P! M                        output += fds.Process( 0 )*vol[9];: z+ P6 ?+ u- [. ]
                }' u0 v! R: s: R; z. ~9 Z# G
                if( exsound_select & 0x08 ) {
- p# N, R0 e" U6 d                        output += mmc5.Process( 0 )*vol[10];8 B/ X) o8 c+ U0 [- [
                        output += mmc5.Process( 1 )*vol[11];
, Z5 m, F) l- Y& R9 i. E9 k7 C                        output += mmc5.Process( 2 )*vol[12];
+ {2 ~! l( y9 u: t9 p0 U/ Q* M- [                }* K7 F9 E+ i4 L% q9 C3 t, b  U
                if( exsound_select & 0x10 ) {8 b, D2 @7 x4 c  J5 ]
                        output += n106.Process( 0 )*vol[13];
8 \  ]: Y4 Z5 R9 L7 ?                        output += n106.Process( 1 )*vol[14];% ~8 T* M9 t1 [
                        output += n106.Process( 2 )*vol[15];
6 K- C& v8 B8 g" v9 c, q4 p                        output += n106.Process( 3 )*vol[16];
6 ^; k0 _) Q! [' U                        output += n106.Process( 4 )*vol[17];
3 }% J3 r' S3 e. E                        output += n106.Process( 5 )*vol[18];; J3 V- M& |+ e* O8 Z* S6 B
                        output += n106.Process( 6 )*vol[19];
8 Q7 z5 f6 b- p* [                        output += n106.Process( 7 )*vol[20];6 v+ J- p/ \) n. H, e
                }
' D. N9 U$ H$ ~2 n                if( exsound_select & 0x20 ) {
) z, L0 J3 C1 M- D                        fme7.Process( 3 );        // Envelope & Noise1 l$ d" a3 w' e# Z
                        output += fme7.Process( 0 )*vol[21];( ^/ {& `. {9 L9 Q' q# z
                        output += fme7.Process( 1 )*vol[22];& K9 m7 M- s: A3 m
                        output += fme7.Process( 2 )*vol[23];
! [. u' Q8 v' ~6 g, w. d6 P                }+ E5 w* z: ^. U2 b# }
9 f" y/ j4 H- U: k
                output >>= 8;
/ {: n: D& K6 ]2 ~& D( j. R
& y* a0 C' j! k9 K: ~2 f                if( nFilterType == 1 ) {+ `6 l1 V/ }  x' [9 s8 f  i/ w
                        //儘乕僷僗僼傿儖僞乕TYPE 1(Simple)
3 F9 w, l. C' [! T% ~                        output = (lowpass_filter[0]+output)/2;
- {7 P/ s2 L- t6 C                        lowpass_filter[0] = output;
* i& Z8 W/ F$ ?. q: l! [' r9 f                } else if( nFilterType == 2 ) {
: t1 _" e' s6 _$ v0 _, L; |                        //儘乕僷僗僼傿儖僞乕TYPE 2(Weighted type 1)
; D" b+ ~  D& f7 h5 m) Y0 z                        output = (lowpass_filter[1]+lowpass_filter[0]+output)/3;
/ i$ Q  q2 ^! D6 {0 O                        lowpass_filter[1] = lowpass_filter[0];
+ c. \0 R( a- {/ a                        lowpass_filter[0] = output;
$ ], i+ i5 L; Q9 g' ?" _0 H                } else if( nFilterType == 3 ) {/ @( \" D8 K; w3 ^& R
                        //儘乕僷僗僼傿儖僞乕TYPE 3(Weighted type 2)
+ r% M/ U, Y+ d1 K9 z! V) l) {. k2 c                        output = (lowpass_filter[2]+lowpass_filter[1]+lowpass_filter[0]+output)/4;, c- W' }1 y3 M
                        lowpass_filter[2] = lowpass_filter[1];6 {% ]- X. g! _$ l6 p+ Y( Q
                        lowpass_filter[1] = lowpass_filter[0];
% A0 V% l" ^- S: \, @                        lowpass_filter[0] = output;
) U/ x" R  g6 O( d, X) j                } else if( nFilterType == 4 ) {
- W% _" Y' C/ F" P                        //儘乕僷僗僼傿儖僞乕TYPE 4(Weighted type 3)/ S, W! m1 }/ a/ A
                        output = (lowpass_filter[1]+lowpass_filter[0]*2+output)/4;
* H. x% d6 i$ |                        lowpass_filter[1] = lowpass_filter[0];
$ x6 n9 w7 L& \& c                        lowpass_filter[0] = output;
; z( X6 L, |2 k* {# w( q. {) `) ^                }7 a( t" T" P2 B$ c. X( C

0 o1 G4 v4 ~9 j#if        0; \; N8 X: k( v
                // DC惉暘偺僇僢僩0 d) G4 ^* a7 H
                {
) T1 m; S; A; F+ |  O0 X% ^% v                static double ave = 0.0, max=0.0, min=0.0;
5 B3 B: q% R, F                double delta;9 z' S6 v9 t  O
                delta = (max-min)/32768.0;/ ^9 E) }/ v% I; n' a5 I  K
                max -= delta;
" Q( W) q  W+ L& q# J+ Y                min += delta;
0 R- x4 n+ i  {8 s, U$ M1 U                if( output > max ) max = output;
9 g9 }2 h5 Y$ L, k, r# k* ~                if( output < min ) min = output;% V2 o( d% g4 f$ `+ K5 n
                ave -= ave/1024.0;
5 M' c/ T2 ?& f  g                ave += (max+min)/2048.0;+ h( ~! G) L2 w1 b7 ^- J1 L) x
                output -= (INT)ave;8 G6 H! K9 ?: D! A! U8 g
                }1 b+ ]7 P8 g6 K  C6 O
#endif. F5 y5 F2 R5 q+ @
#if        1
0 V" s2 k. o) P7 u1 J                // DC惉暘偺僇僢僩(HPF TEST)/ ?; N( q! Y3 [' _6 P, D% \
                {
* f) V0 I# `4 Z% O* }+ Y" a% q: D//                static        double        cutoff = (2.0*3.141592653579*40.0/44100.0);+ n* z' Y- t1 `* ]- K# r  a% |
                static        double        cutofftemp = (2.0*3.141592653579*40.0);- f4 ]* C4 M( L  _: G: ?8 `
                double        cutoff = cutofftemp/(double)Config.sound.nRate;
' d5 w1 F) a1 N+ a5 u                static        double        tmp = 0.0;
- n) |8 P& K5 u# o0 l                double        in, out;, {1 F% A4 D* D7 x2 Q

7 m5 D2 v7 ]. t+ h3 G! b                in = (double)output;
3 i. d+ s' |: c* e                out = (in - tmp);
1 G5 I: C$ c/ i- L" x) k                tmp = tmp + cutoff * out;7 g/ P3 |' I, {
; {) m+ ^0 L9 b
                output = (INT)out;7 H) [  m, n. ?' y0 p7 K: i- ^" s
                }
1 `, H% t+ Z; i/ Z  R% F" V4 @#endif, t% j4 b% c4 }  [2 c
#if        0' A& Q+ ]% T5 p# j: x" j
                // 僗僷僀僋僲僀僘偺彍嫀(AGC TEST)
; h! `5 c4 i4 q+ l% z/ ~1 t                {
. x% p/ u8 ~% Z, A4 W3 m                INT        diff = abs(output-last_data);
: b5 b5 L; T* [% J                if( diff > 0x4000 ) {
1 H$ X" s6 y2 u- _# S( ]' t0 \                        output /= 4;6 R/ ?6 s' \+ t# I. `' N
                } else
! |& z" d. g# n8 S% @) R& B                if( diff > 0x3000 ) {) f4 l0 Q& m1 N+ n
                        output /= 3;
; X# [" l* Q: k6 B( c                } else
; N% ?& V' M, Q% n* R" S: u                if( diff > 0x2000 ) {5 p! S# i  e0 s. J: U- R( D! N  _5 @
                        output /= 2;
. a7 \8 K- c% O2 Z6 }                }
% a4 N8 T* v1 y. d                last_data = output;
0 s7 z  P# s. y. \                }
9 [$ [; f; f- s# I  x' ?" P& p  I5 H#endif
; B6 A( W: T% `. [                // Limit
8 _: I( w4 ^, F, t) t2 ^  q                if( output > 0x7FFF ) {2 h- M/ h% n0 K
                        output = 0x7FFF;
+ R0 s2 H2 E0 B# k' p7 T0 B                } else if( output < -0x8000 ) {6 u& U& U+ T" d
                        output = -0x8000;
/ D  `1 c  z: M, T4 v1 z                }
& _$ L3 e! M8 E; z
" N2 n; v2 @( K3 d, }$ J/ \                if( nBits != 8 ) {
4 k1 d( Z( t! X& Q. ]3 }) {$ p( k                        *(SHORT*)lpBuffer = (SHORT)output;
4 _! a) d) a; n  V0 Y+ q                        lpBuffer += sizeof(SHORT);- F! B# J2 u% ]/ C8 e( T
                } else {
% v  ^+ x* l3 Q/ y                        *lpBuffer++ = (output>>8)^0x80;) c. M1 b/ x. ]- @+ \+ w3 o
                }" p$ U1 Y! H4 y  F
/ y; Y/ B8 m, ~# W. Y8 d8 [0 ~  u
                if( nCcount < 0x0100 )
+ @* x  l* x5 ?& N' D5 a                        pSoundBuf[nCcount++] = (SHORT)output;; ?8 b6 G0 j7 I8 J

- O- l1 ?& y* p) W% V* U//                elapsedtime += cycle_rate;3 g( C! R! T: b& p6 t5 f
                elapsed_time += cycle_rate;
( }6 i) n$ ?- ?0 R/ }" \        }
4 l6 r+ |5 Q8 B2 f) k
. j9 v: p! g6 h0 l; q/ k9 P- _' E#if        1
# u5 w9 r5 [8 w; \        if( elapsed_time > ((nes->nescfg->FrameCycles/24)+nes->cpu->GetTotalCycles()) ) {
$ Q. d: y+ A3 X* M                elapsed_time = nes->cpu->GetTotalCycles();  c9 }0 [* i6 J/ c2 E0 T
        }" J/ n& M/ X' ^/ t( G# D) l) ^
        if( (elapsed_time+(nes->nescfg->FrameCycles/6)) < nes->cpu->GetTotalCycles() ) {
, Z  V8 \2 x. b$ }- s: e5 P                elapsed_time = nes->cpu->GetTotalCycles();  p. ~- {+ p$ c; u! H" N) I9 m
        }
) e& D3 r. [( j) w' p#else1 ^( v* y2 }8 }
        elapsed_time = nes->cpu->GetTotalCycles();9 v( K  w3 _" x0 W( p
#endif
9 M/ p" w# f' F( c3 L! P}
. \% p6 q6 ^. a$ f8 P( [$ {
# S* x. ]" e8 M" J3 Y" m- g5 c% T// 僠儍儞僱儖偺廃攇悢庢摼僒僽儖乕僠儞(NSF梡)
4 M2 P7 y8 ~  ~( I/ _INT        APU::GetChannelFrequency( INT no )" o. U( R1 Y4 z$ H
{
  C( V9 E- E, Y: b        if( !m_bMute[0] )
% {* V) _9 t/ e. M0 E' i                return        0;
/ m& b" \3 `2 _2 p3 t- B& g- }: m
  _3 r! q* ~/ j- ~9 Q4 K4 k        // Internal$ G7 A/ d3 T( ?) r$ c# g
        if( no < 5 ) {) E- _2 o0 a! Q$ @! B6 d
                return        m_bMute[no+1]?internal.GetFreq( no ):0;9 ~! l8 G8 R% Y9 Z5 K( r6 l- M* s
        }" E, j1 \, p. L4 v+ y7 Z  P$ N8 L
        // VRC6# b" Q, d2 [; f. _( S" X7 V
        if( (exsound_select & 0x01) && no >= 0x0100 && no < 0x0103 ) {) [, O& X# ?) a, g! B( m& W4 N( _
                return        m_bMute[6+(no&0x03)]?vrc6.GetFreq( no & 0x03 ):0;  d7 y0 W7 o$ X0 q2 C4 {3 |
        }! i: T% o2 c0 e8 ]
        // FDS- S- e: P4 _% [) ^1 B
        if( (exsound_select & 0x04) && no == 0x300 ) {# O. v& u1 B" V& s5 G
                return        m_bMute[6]?fds.GetFreq( 0 ):0;
, M8 S" Q( d* ~; i* l! Q        }4 i1 u- Q8 }' a" Q9 D$ W
        // MMC5
4 i9 v% ]/ q; N* ?4 z! X7 u        if( (exsound_select & 0x08) && no >= 0x0400 && no < 0x0402 ) {: n  T- a) R# q
                return        m_bMute[6+(no&0x03)]?mmc5.GetFreq( no & 0x03 ):0;7 v! h  L! ?* b. ^3 ?
        }% r0 n7 e4 K- y# L4 C0 ]7 h
        // N106
) w% H0 y- d+ Q& c- A1 K        if( (exsound_select & 0x10) && no >= 0x0500 && no < 0x0508 ) {1 N; V3 k6 t1 |
                return        m_bMute[6+(no&0x07)]?n106.GetFreq( no & 0x07 ):0;4 O  S! j6 w/ _+ J! U! s
        }, o$ O- ^/ C0 F& C
        // FME7$ B( T" g- }% f4 J0 P7 D* I
        if( (exsound_select & 0x20) && no >= 0x0600 && no < 0x0603 ) {. u$ V7 e& e0 F$ F' M1 _
                return        m_bMute[6+(no&0x03)]?fme7.GetFreq( no & 0x03 ):0;
0 P, p; Y8 W! S) v$ X8 d% @        }
$ _$ W5 x5 R% D: ?/ X) V  P        // VRC7( S$ @% Z; H  A/ g; m' L8 Q
        if( (exsound_select & 0x02) && no >= 0x0700 && no < 0x0709 ) {
2 y( L# c% g, }2 O; q7 x0 R                return        m_bMute[6]?vrc7.GetFreq(no&0x0F):0;& |! g- b3 v  `2 i. ?/ F
        }" S# m3 N1 N8 M. V  v2 X. X+ p, E
        return        0;
: n7 j' {5 _. _}
$ c# ~0 j/ D+ w* ^' m
. g8 C+ C2 [# F) h9 z" U// State Save/Load
& ^2 |, n1 y& M! Z8 n# z) xvoid        APU::SaveState( LPBYTE p )
( }3 o3 s9 ?* ]' \+ Q1 B{( b% W2 x; o% H0 W1 ^: d
#ifdef        _DEBUG
. B3 d( y3 `0 J8 }LPBYTE        pold = p;
* M& Y$ q6 _; ]4 F3 l#endif7 n8 D' y+ Y5 D

  x7 y! V' e" ?/ d% I        // 帪娫幉傪摨婜偝偣傞堊Flush偡傞
& W) n. T' q1 P/ d$ J        QueueFlush();- w/ N- Q4 r) e* S: ^

+ ]; K) P$ x+ X+ f" I" L        internal.SaveState( p );& k, N5 I: _$ v9 C9 F' T
        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding
, Y. x4 ~/ j6 m; n* A* E+ \0 m/ w2 N
$ R2 n$ W9 S" B# K9 d+ @        // VRC63 h% B+ Z, u6 s, l# J& F
        if( exsound_select & 0x01 ) {
: d- V9 H" d# W& j- T) \( F                vrc6.SaveState( p );
+ z+ y1 Y) @5 m( E+ Q7 @. L+ i                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding
" p( Q: v$ x. ~. c        }
% v* K9 z. e; r3 I        // VRC7 (not support)
+ Y* d+ t; w+ Q& w/ J        if( exsound_select & 0x02 ) {5 d) ~7 a; m+ r7 }! l' b
                vrc7.SaveState( p );$ a7 i  q# v/ R6 x
                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding) h* v& Q3 h% B' L
        }) P  v$ D  V2 D. E* s& v: X
        // FDS2 [# n* |2 E" ]; w9 Y' y' _; F
        if( exsound_select & 0x04 ) {
4 I0 e4 o' |$ d. g                fds.SaveState( p );: V5 i; K' h6 R/ \
                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding
& B) V# A& t: `" h- [, Y        }/ N# P2 a3 a' Y: R, \
        // MMC5$ K& z. u+ k( A- y5 q
        if( exsound_select & 0x08 ) {
% s, v3 S. |9 u7 Z0 y                mmc5.SaveState( p );, ~/ d+ h+ X2 y1 ]$ a  E
                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding+ {. z4 S* B+ g; U& a; g3 l& |6 Y
        }. {1 x, u1 [$ f! n4 t, |+ j9 ^
        // N106
! ]" }  D  H+ q" ]. U        if( exsound_select & 0x10 ) {
) L9 S& V5 ]) e- A                n106.SaveState( p );
& ?9 g  G: r0 t/ w                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding
4 u4 j. b; x8 e        }
9 n8 B5 ?6 |( W2 G. x        // FME7( X) m6 }! H) |( M+ b) b8 V
        if( exsound_select & 0x20 ) {# y/ O7 f/ S& |; T( S% w, {+ {' c
                fme7.SaveState( p );" t' K% s+ S$ A
                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding9 l1 E1 l& {- A" f4 N
        }, [' Q5 B2 W- K# ]$ [# ~% J

# m  n3 w3 u/ K1 ~/ u6 S2 F#ifdef        _DEBUG; @# g: D" @' s% D
DEBUGOUT( "SAVE APU SIZE:%d\n", p-pold );+ F$ X: I! o# E$ A6 A7 _6 u
#endif
# A, y+ s' E' I; j) n: ^# E}+ F) s/ w. V9 Z+ r
, d# Z+ w9 Z* l+ o
void        APU::LoadState( LPBYTE p )
* j3 O/ L- c# P' L7 E7 S{
$ L* F  \, W+ ?  y5 g( y5 {- B        // 帪娫幉傪摨婜偝偣傞堊偵徚偡+ L, v. E- G8 |. f( u3 N/ \$ }
        QueueClear();
# C$ T4 @3 q6 ]5 H- O& Q0 }* ~7 ^% `4 C9 V" Z! U
        internal.LoadState( p );. o! w. L  ]- |/ E3 l6 r' _
        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding
8 u, l& N9 B: Z8 P/ L# Q+ N
+ d0 T- y& N  {: O        // VRC6
" G" ^6 m) K% D5 N" K* n( c# d0 J        if( exsound_select & 0x01 ) {
. L+ x1 s! `' c                vrc6.LoadState( p );
, r0 @* o) Y% _2 N7 r% Y6 L, ]% U                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding( A+ l$ o! l: n1 f! a7 Q. W
        }; i! i& v( f  y4 ?
        // VRC7 (not support)
; r# m3 y$ c: a8 M- _        if( exsound_select & 0x02 ) {
6 a! P' A; p5 V2 z2 T/ M                vrc7.LoadState( p );, R6 C3 ^0 Q! T9 G
                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding
: u+ K3 O; P1 Q$ T$ e        }
# W8 l  \( R2 {) o+ \6 P        // FDS$ D2 f* P( _0 u: Y& l
        if( exsound_select & 0x04 ) {6 J, F1 M7 m; i" {8 W
                fds.LoadState( p );5 U/ O) O& B% U% c
                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding
4 d4 b4 ~( `- [        }
; c% j! C  D7 u) n: v        // MMC5) u- K: t- f2 i+ V7 Z
        if( exsound_select & 0x08 ) {
% C1 ]4 L" X6 U2 v  k+ f                mmc5.LoadState( p );
  o2 b$ U3 R8 z% J" M: ?4 h! N! L                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding
4 k  a1 i5 O2 I! z        }+ H: l, N- s9 M' X) m% D4 V
        // N1067 A1 l+ v+ d9 A! |  v% s
        if( exsound_select & 0x10 ) {3 I) [) _" P) _0 L' y
                n106.LoadState( p );
3 I& }& B- w$ {: p9 |4 ?. @                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding
9 m7 _+ l& U2 z" G  k6 Z# P$ n        }) w, ~4 B3 O& n  P. f
        // FME7
/ f/ [( f) `6 F' F2 Z        if( exsound_select & 0x20 ) {
! f* X# P/ i* w% S! `                fme7.LoadState( p );
: U3 o/ L: W+ _& l$ o                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding7 y. k4 \$ m/ o4 t7 b$ s
        }0 ?) ?9 G" a" m( l) Z) {
}

该用户从未签到

发表于 2009-11-8 17:25:37 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 14:38 发表 7 e2 s2 U" l' q; v
可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。3 y& O0 [. C: G, `
感激不尽~~
: J: N. ^2 f( B* y
恩 我對模擬器不是很有研究,6 u, g. `/ p6 L* i* r* L
雖然要了解源碼內容,可能不是很困難,
2 @6 d# d# q2 j9 r$ }不過還是要花時間,個人目前蠻忙碌的。" L2 ~9 I" q$ p7 m4 Q

4 }4 r$ M6 @2 G' R  f1 M給你一個朋友的MSN,你可以跟他討論看看,
& C2 i" \5 W2 F" B& y; s他本身是程式設計師,也對FC模擬器很有興趣。6 g3 ^0 i, n# k: l2 f2 ^

8 X5 P' Z! h6 s$ ]; iMSN我就PM到你的信箱了。0 C# A9 e; A$ b5 G8 P
7 ?1 p  o+ [3 ?7 _& a. B) M: M
希望你能有所得。

该用户从未签到

 楼主| 发表于 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 发表 & A) y1 v  V  S* }3 T. Q0 t; Z
呵…… 谢过团长大人~~

* E( D$ [, H4 {; ^& D7 \$ J7 q% _1 t2 G
哈 不客氣,算是順便幫他找個伴,大家可以一起玩。

该用户从未签到

发表于 2009-11-20 13:14:53 | 显示全部楼层
原帖由 李伟 于 2009-11-9 16:02 发表 8 y" f% ^2 f& l; d6 H6 x$ b; d
团长的朋友都是神,那团长就是神的boss。

2 i& L  d( U: T# G1 ]" _4 M% [哈 不敢當,我只是個平凡人,
6 b$ v# |' j  p3 H* U要吃飯喝水,光吸空氣是不會飽的。。。。 :)

该用户从未签到

发表于 2009-11-20 13:32:35 | 显示全部楼层
FC模拟器的部分有个人可以帮你忙
) W( o; T* K; w& x. s9 M7 l: iZYH
* e8 b6 S9 ]+ k! d6 h* {QQ:4147343069 W6 y- b7 k" z8 |( \+ |
Mail:zyh-01@126.com) t/ D: t6 c, k1 m0 _9 X

3 N) }8 V# f+ h0 `2 P他是ZYH Emulator这个模拟器的作者,只是他用的开发平台是VB,不过就6502的实现原理来说是一样的

该用户从未签到

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

该用户从未签到

发表于 2009-11-27 19:09:06 | 显示全部楼层
原帖由 独孤残云 于 2009-11-27 09:48 发表 ) q3 c7 o$ U  ^# r3 v# _
再次对团长大人和悠悠哥的无私帮助表示感谢~~
( l6 O8 O8 w; v" ~0 ~
不客氣  ^_^
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2025-12-4 05:55 , Processed in 1.070312 second(s), 19 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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