EMU618社区

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

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

 关闭 [复制链接]

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 09:56:34 | 显示全部楼层
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。
& Q# g5 |$ d0 Z3 M8 N" K楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~% r7 ~' T$ r2 Z* ?2 }0 Q- |& H& C2 I
这里有相应的模拟器源码,就当送给大侠了~~
% T5 q( G, D2 M1 j( e, |( yhttp://kenkao.qupan.com/5096520.html

该用户从未签到

发表于 2009-11-8 11:31:10 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 09:56 发表 9 z: ^$ r* Y/ D0 m. {( c) [
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。
" h9 P0 O5 T- W% B  y' ~' {楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~# q2 R! X* m( k  H$ H8 p
这里有相应的模拟器源码,就当送给大侠 ...

- h, D; U6 t. [7 W; \8 ^聲音部分(Audoi Process Unit = APU):! F3 t  z# Z2 R: p8 S
.\NES\APU.cpp
/ ]  A5 D3 L, ^% l. e# ]& C.\NES\APU.h; u8 y! r; e$ f) u2 r  y, _- M
6 u: v, b, b1 l
# ^( l% f$ m$ B* j4 R/ g: z; h
影像處理部份(Picture Processing Unit = PPU):
* R7 b, r0 t' ]" E% I.\NES\PPU.cpp
6 p) v9 a2 t" W; @( t.\NES\PPU.h% n# a& y. {3 B5 i/ k# n$ }

0 y; q& z. X; S  y如果原碼用C跟ASM混搭也不錯

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 14:47:50 | 显示全部楼层
这是我手中源码Apu.cpp的内容,敬请赐教:
7 \* N+ ^/ l  K/ P& g(由于很多专用术语和算法机理都不明白,所以看不大懂……)' p2 a8 j. ^+ v) O8 v( V5 V
//////////////////////////////////////////////////////////////////////////0 U% A+ w4 C* c% O' ?  p& r! I: o
//                                                                      //
8 O: }4 ?8 j8 N' e//      NES APU core                                                    //
9 k3 z, Z6 }: V- Y$ ^//                                                           Norix      //& C5 w" }8 L' `7 Y! `# ~. P1 {8 i6 h
//                                               written     2002/06/27 //
! C* |5 P4 F9 A8 \5 L9 B# l! D6 ]//                                               last modify ----/--/-- //8 m% G( O. L6 Z8 Y+ I" B
//////////////////////////////////////////////////////////////////////////
6 a3 [2 D9 l6 e; Z. Y( @#include "DebugOut.h"/ o  c5 P6 t9 N- x/ }
#include "App.h"
' s) Z5 l2 t9 b/ y0 T& N5 j#include "Config.h"
- ]0 \9 t" j0 u- ?* k8 U9 F; g" ?4 h- G/ J/ h( Z
#include "nes.h"+ X+ N$ A6 F3 X. C# q/ E# V
#include "mmu.h"8 C5 z1 ~' b8 h
#include "cpu.h"+ K/ N( Z; ]9 T/ q0 e$ S+ r
#include "ppu.h"! K' i9 p8 Z' Q# U2 f& U0 }% S
#include "rom.h"
: X1 H$ X  P; O#include "apu.h"& B" F8 E% k/ |
& |9 h8 s# @) p* k) a! l
// Volume adjust* d5 Y7 y0 a( i
// Internal sounds% C1 K& s2 C( Z! g, y
#define        RECTANGLE_VOL        (0x0F0)
5 k5 d  U3 t# O' A#define        TRIANGLE_VOL        (0x130): Z0 }% @% A- g& F4 d
#define        NOISE_VOL        (0x0C0)0 W  v( I2 ]7 D2 h
#define        DPCM_VOL        (0x0F0)
0 @4 J& J; x$ M1 O2 m4 g// Extra sounds6 i& Z1 I; h: v
#define        VRC6_VOL        (0x0F0)
7 {, P! C- J& ~4 ~1 L: I$ M#define        VRC7_VOL        (0x130)
; D$ M- m4 b3 ?#define        FDS_VOL                (0x0F0)
7 V. I; i( z( G4 s% n$ \2 t' d#define        MMC5_VOL        (0x0F0). r% c5 b& f+ h1 z7 L' w! c
#define        N106_VOL        (0x088)
: x4 t& t" j2 v. m5 K) D#define        FME7_VOL        (0x130)5 t" g$ N4 {; ]% n

, D+ J4 y) j: [APU::APU( NES* parent ), f/ I0 x' [4 S- A' Z
{
+ I! d( {7 ]/ ~( h* q        exsound_select = 0;
( K7 D* S  ?; f0 ?, a: [
. @' N. F. k: y8 s0 |        nes = parent;
! T% G4 h6 w1 x* P        internal.SetParent( parent );: a9 T3 y: x- m) q% ^* f8 j
/ w9 I, o; z3 I% [- j. x/ ]
        last_data = last_diff = 0;, P) j) d( r( T5 |
& i* w3 i+ M' q
        ZEROMEMORY( m_SoundBuffer, sizeof(m_SoundBuffer) );
, w' g* h/ p' N* P: y
2 H2 T# e# u* J$ z        ZEROMEMORY( lowpass_filter, sizeof(lowpass_filter) );4 o# N$ Z9 k: ?5 F! w
        ZEROMEMORY( &queue, sizeof(queue) );# V( B; n" V$ c
        ZEROMEMORY( &exqueue, sizeof(exqueue) );
! z7 q  D/ w- H( ]! p$ j9 L8 x4 Q- T- N% m; w
        for( INT i = 0; i < 16; i++ ) {0 H" u! _3 n- Y( p2 ^
                m_bMute = TRUE;
4 Q# [1 {  x) _& U  s2 D        }" n% [3 `* D: G( u5 o3 F
}2 Q- i5 K4 P$ @2 l0 }1 q6 @9 i. ?
( Z4 C: a% W1 ]  }. w
APU::~APU()* @  G8 A- c/ z6 d
{% w1 S% T( B( G
}2 f' o. Z" K/ x  {; B( i! I+ y" Z% D
8 K* H& w& \3 P* R: O4 g$ e
void        APU::SetQueue( INT writetime, WORD addr, BYTE data )
! {( @) j1 U8 ]# d* T/ O{
8 ]& G& g/ m/ K0 H$ S5 a/ J        queue.data[queue.wrptr].time = writetime;
  S1 q- \& P6 e4 s: a; w) v        queue.data[queue.wrptr].addr = addr;" [0 Y) F' v$ ]0 ]/ f1 s: X- W
        queue.data[queue.wrptr].data = data;
/ l7 p( m' t; A6 W        queue.wrptr++;+ G6 T+ Z" u) f
        queue.wrptr&=QUEUE_LENGTH-1;- K5 p# ~' h# W  @/ F: G
        if( queue.wrptr == queue.rdptr ) {
; ^' f. U2 Z+ ]/ e2 k& m" A& D                DEBUGOUT( "queue overflow.\n" );) X3 S* }. @* s( B& @# L( B
        }1 c0 j1 C- P" {9 V) @; [" H
}) I) G5 O5 O! ]# u5 c! A# B% C
9 i( F. e9 C0 A, M& L! [/ s$ s
BOOL        APU::GetQueue( INT writetime, QUEUEDATA& ret )- d; h: C+ e+ u" R
{
# @/ L+ D& e8 b' @8 y  M% }        if( queue.wrptr == queue.rdptr ) {$ P( c- p7 n) W; \& G) J5 f
                return        FALSE;4 g/ X/ _9 d0 V) g9 L
        }
4 W* J% k8 w' x" Y+ a/ g4 I        if( queue.data[queue.rdptr].time <= writetime ) {
* d6 r$ Q: b9 J* P  c                ret = queue.data[queue.rdptr];8 [0 U: n1 X4 A" e$ L8 [# {! w
                queue.rdptr++;
* p: ^( t  W& ]2 Y; C. A* ^                queue.rdptr&=QUEUE_LENGTH-1;# W# W9 K3 b4 m$ M6 T
                return        TRUE;; L8 {3 i- K; a
        }
( C/ V1 s2 p/ [6 N        return        FALSE;
" U2 }! V5 }) F}
* v: _: v8 C8 f8 |7 _) g6 N' v5 x& C; e8 O
void        APU::SetExQueue( INT writetime, WORD addr, BYTE data )
* }5 V# W) ~! @- L{
9 F2 S" D$ I7 p# Z4 \$ N        exqueue.data[exqueue.wrptr].time = writetime;3 V& t* v' E; M. B' p
        exqueue.data[exqueue.wrptr].addr = addr;: v1 m* }2 @" @9 x
        exqueue.data[exqueue.wrptr].data = data;+ R1 ^- l) G2 d2 g& G
        exqueue.wrptr++;
4 D* {# O7 `# `. m        exqueue.wrptr&=QUEUE_LENGTH-1;0 r9 P" _& A1 P5 |
        if( exqueue.wrptr == exqueue.rdptr ) {
: l; x" H0 N) o. V                DEBUGOUT( "exqueue overflow.\n" );. d" S6 x1 g4 s1 u
        }% d' |6 e; M+ p# }/ y6 y- t
}
) O. y  Q3 x8 {  I4 {' o5 W6 g* O! h$ b9 x: Q
BOOL        APU::GetExQueue( INT writetime, QUEUEDATA& ret )
1 n. H0 f: a+ d! X0 r{/ G& C4 d4 n( M; @
        if( exqueue.wrptr == exqueue.rdptr ) {
! |- \& V2 Y6 c) t6 G- C, z: Y' j0 G                return        FALSE;* u2 K- m8 b4 W; u& N
        }
1 z7 b4 R9 x: a7 t+ S        if( exqueue.data[exqueue.rdptr].time <= writetime ) {
: F- F, g) S' Y4 G8 @" N6 X                ret = exqueue.data[exqueue.rdptr];
& |; w; z6 y7 \0 L6 ~: `: i7 ^) F                exqueue.rdptr++;
. B$ A- O" w0 O                exqueue.rdptr&=QUEUE_LENGTH-1;5 b9 z1 r  ^9 `0 O: P
                return        TRUE;
3 F3 I( g6 L% a        }
7 h3 f3 b" F1 U+ o        return        FALSE;
* p% N( F" B! h3 ~$ v6 _}
! J! D. m$ D( ~7 J- K9 W, v  r8 ~* y8 L/ m2 R
void        APU::QueueClear()+ {( I) P( H% B/ a
{
; f5 {! z+ J7 F5 Y        ZEROMEMORY( &queue, sizeof(queue) );9 |7 F, t% k; I3 u" Z9 r- M5 ^% g: N) @
        ZEROMEMORY( &exqueue, sizeof(exqueue) );
8 X! V" {" K6 d+ D! e- |: H}1 `- N5 X$ _$ o0 P3 d" B+ L# B3 p5 ?

& B, x- o7 U, x5 {void        APU::QueueFlush()
% q$ `. N& s# [8 x* q" ~{
1 s* E* X, a8 ^' F+ ?        while( queue.wrptr != queue.rdptr ) {! q# f! C5 J% m, h
                WriteProcess( queue.data[queue.rdptr].addr, queue.data[queue.rdptr].data );! T$ O; {! M( V3 y2 I2 Y
                queue.rdptr++;+ _: [( @3 F9 h) C. G. M. q
                queue.rdptr&=QUEUE_LENGTH-1;- e) M6 K/ a1 x" g, F
        }6 X; W! ^% t# ~9 P8 l' ]

: I8 c  }8 {5 @7 [1 A% _6 \5 `        while( exqueue.wrptr != exqueue.rdptr ) {& L  `5 {+ h; {) Y8 H9 K
                WriteExProcess( exqueue.data[exqueue.rdptr].addr, exqueue.data[exqueue.rdptr].data );
9 U& ~1 P( B9 M# {. b                exqueue.rdptr++;* X7 g+ q% n, Y' M1 ~/ F
                exqueue.rdptr&=QUEUE_LENGTH-1;: t  |  j" h* L  h, P
        }
0 S8 D5 v- V5 M}& c% a8 t8 F0 y& X/ h. `) B6 Y

' x5 ]& j$ F4 `& l1 g1 e9 l9 f! mvoid        APU::SoundSetup()
) M3 j: `8 @, i. C9 v' W0 [{8 l; H) b/ \  p( X" O3 g2 o
        FLOAT        fClock = nes->nescfg->CpuClock;
1 {- I5 ^; H5 l3 h  D        INT        nRate = (INT)Config.sound.nRate;
! @/ L  W' f- n+ j# p& o        internal.Setup( fClock, nRate );, I" C" V: f( w! ?
        vrc6.Setup( fClock, nRate );
, Z+ F9 h9 B8 j& X        vrc7.Setup( fClock, nRate );
  Z7 M: w+ X) ~: a! J        mmc5.Setup( fClock, nRate );
! _2 [1 F4 `- L7 C2 M        fds.Setup ( fClock, nRate );; ]$ S7 D7 V! t$ g
        n106.Setup( fClock, nRate );- V$ w' M1 U: W
        fme7.Setup( fClock, nRate );
! e  L' S& f  [* n}
( Z3 Y+ G8 t% T; X1 s% _# g6 Y" O+ l2 F; V$ A
void        APU::Reset()  M5 d5 I# ?, X4 U$ M
{
! _! j( F( U9 O9 ?: M8 o        ZEROMEMORY( &queue, sizeof(queue) );
/ u. J5 G; s& ]3 P( m8 I        ZEROMEMORY( &exqueue, sizeof(exqueue) );, s" |9 i+ s0 \- G5 |8 D/ f3 M
; f& Q: L) t0 N- \2 `
        elapsed_time = 0;
* U9 o7 O5 x- e: A& m& t% u% g3 w( t" I
( e  P8 F5 B+ l3 ?( @6 P        FLOAT        fClock = nes->nescfg->CpuClock;
* j0 C% h% I# r* _6 y% y        INT        nRate = (INT)Config.sound.nRate;5 S$ d3 ], q) W) V& q4 r
        internal.Reset( fClock, nRate );. A+ U$ ?& A: y6 b9 j- z9 _! L
        vrc6.Reset( fClock, nRate );
+ @' w  [0 |" {. Y6 M" d  V) e0 ]        vrc7.Reset( fClock, nRate );
' F8 r8 j/ s; d! \4 c) D        mmc5.Reset( fClock, nRate );) U6 ]* B3 z% K2 ^2 K% M
        fds.Reset ( fClock, nRate );
! d* m/ j" u7 v" B6 s        n106.Reset( fClock, nRate );$ c2 p+ F" I: h" A. Z
        fme7.Reset( fClock, nRate );* z$ a. @; a" f/ K& O! H- X
6 b( N( K/ H; t4 p* u' [3 X2 U
        SoundSetup();" ~0 s9 e) A% x$ R) u/ P
}
- f4 G" Y+ r0 j3 s( [; G7 Z
! h& H1 T- I( Fvoid        APU::SelectExSound( BYTE data )! f) S! J2 E- c1 N
{/ r6 V. ~4 s- U1 m+ k6 \( `! H8 Z- L
        exsound_select = data;! S  F' L7 u$ Q9 E1 ^5 _, [
}
) c; N% {( s. \. i% t* A& W" ]/ g7 z* _
BYTE        APU::Read( WORD addr )
/ R9 L4 o2 r  p; U+ }& B& a3 X) z{+ C6 U4 T) `9 P/ F  }
        return        internal.SyncRead( addr );/ ?+ K" C2 g5 T; x
}
$ H- u% b1 u4 e" H8 M( m5 y3 E$ `
6 R" z, G$ v9 G6 j/ F& T! avoid        APU::Write( WORD addr, BYTE data )
( C9 d) t, D' o  r2 W. ?; O{4 Q  A  R# ?$ k- Q4 f5 G& G
        // $4018偼VirtuaNES屌桳億乕僩
- P6 @' F9 B! x        if( addr >= 0x4000 && addr <= 0x401F ) {  n: h: B; }0 y4 S* q' ~" C
                internal.SyncWrite( addr, data );- Y! o. x/ B$ W1 S# \2 T* l, X
                SetQueue( nes->cpu->GetTotalCycles(), addr, data );/ t! M# u7 v! X, g# J: ]  _1 ~
        }" I0 D  L) O: ~; }5 Y4 t
}4 B" v% a* Z* j6 X" T5 K4 L

2 y1 G; J& K% QBYTE        APU::ExRead( WORD addr )
. D/ t% }+ ^$ U( u{2 v' f% U& w0 l3 _
BYTE        data = 0;! ~  S* Z' L* {0 A7 ~: g

. |* r, I& k" [8 \6 G        if( exsound_select & 0x10 ) {
: r& J- K- _. _7 f# M                if( addr == 0x4800 ) {
) A+ {* f+ i4 S1 w                        SetExQueue( nes->cpu->GetTotalCycles(), 0, 0 );
: Y, i) b1 ?1 d+ W                }
# d) F  _. N8 y, s; c1 u        }
" E% g) E" [$ C  j4 P5 K' R5 {$ W% `        if( exsound_select & 0x04 ) {( N: p: w, v) s
                if( addr >= 0x4040 && addr < 0x4100 ) {! {: @8 U+ {) C. M
                        data = fds.SyncRead( addr );3 t- w# j" e8 l# ^) }- y
                }
5 s) N0 P( ]  l0 @% ?' u; I        }
. a8 U9 p, S! g9 I1 s' B/ M        if( exsound_select & 0x08 ) {4 M. P! ^- s1 {4 l+ I8 y# H
                if( addr >= 0x5000 && addr <= 0x5015 ) {
6 Z: v* Y6 u- a- ?0 T! i5 {, l                        data = mmc5.SyncRead( addr );2 w' x- r- O+ ]" k
                }
( p9 A0 _& n+ v/ V! P        }: W" B$ H' b0 G6 O0 k6 V9 d9 A

& I$ H1 S% V3 k4 I: o        return        data;# o  |* P8 v; x# Z& ]: T7 |
}1 U9 ?/ q- T" o/ t/ W

. W9 g: x% ^. T0 S1 h8 M1 Avoid        APU::ExWrite( WORD addr, BYTE data )
; r) F, j2 }! Y% {' b# H. Q{2 m3 x# U3 x% M+ P: e
        SetExQueue( nes->cpu->GetTotalCycles(), addr, data );
4 ]* c9 j& ]& o/ C3 u, {& z/ {5 B" P( B& M
        if( exsound_select & 0x04 ) {
1 s4 e* F# N4 @+ e. ]& m, P) o                if( addr >= 0x4040 && addr < 0x4100 ) {" _1 }; v$ l) \  [
                        fds.SyncWrite( addr, data );
: ~$ o/ d* s* _% r                }" s4 b% }. y' P$ }
        }8 [( S; _1 a. l6 o
" F% N  _1 W1 {0 S" ~
        if( exsound_select & 0x08 ) {
" B+ U! H; r0 o$ P' g                if( addr >= 0x5000 && addr <= 0x5015 ) {
/ c1 H+ x% `# D5 K" W1 t                        mmc5.SyncWrite( addr, data );) L$ x5 F) y5 y: }0 {% e+ C$ L
                }5 M9 }+ ~2 J0 x( r
        }
& _% o. [5 \+ M}
3 K" `' ]! P9 V+ h9 W* S2 u0 v. v) a, W2 e7 O& X8 P! I2 y* H
void        APU::Sync()
# L8 \" ?5 @" o- c' u{
, o( P$ V# \+ Z" w  X}, e- R; g' L5 v5 ]9 F+ l

& @9 p/ ?: b6 R$ Dvoid        APU::SyncDPCM( INT cycles ): h2 f" R2 {$ y9 O! z/ X7 o, V6 F
{
0 s, ?) M' `% x' P4 u6 m/ W        internal.Sync( cycles );
& |$ b! W" n6 G0 y% |5 i$ ]
2 e1 `8 \. L5 Y8 D1 ^. M  ^& `        if( exsound_select & 0x04 ) {
- }+ Q( k5 n7 A( P' l1 {4 j                fds.Sync( cycles );
7 A0 X' Y0 c. S" H$ h- N7 V% t$ P        }
7 V2 t3 a- Z0 I; x: r; I        if( exsound_select & 0x08 ) {3 a; ]( t! K9 t  H# C9 |
                mmc5.Sync( cycles );' C/ Y7 s' x) C& p' M7 d5 M
        }0 J" j1 p2 ?9 ?" B# `% ]
}
% \8 p3 [. P: O: u% r( C, C2 y! J0 o! G0 [4 ?
void        APU::WriteProcess( WORD addr, BYTE data )& d4 {# z9 d; k, U0 d* N! a3 t
{9 F" s& x  R: e" b! ?& S
        // $4018偼VirtuaNES屌桳億乕僩
" O1 B  a8 U9 t( I7 k9 A        if( addr >= 0x4000 && addr <= 0x401F ) {
$ m0 h* I/ c; R/ y7 c                internal.Write( addr, data );
; h9 A2 q) l' p% _4 h& u6 |        }" Y8 [& b6 T( V3 S
}
7 A3 u; z/ O& @" r2 G6 ~4 Y/ m9 i$ U8 V/ V
void        APU::WriteExProcess( WORD addr, BYTE data )
5 P& Q: b: L- U- R2 v$ M{
: U& n& v4 v" G2 d2 ~9 j        if( exsound_select & 0x01 ) {
: c+ h$ \( j1 f& D                vrc6.Write( addr, data );9 F+ f) L+ _6 q$ C8 F
        }& f) Q* O3 m# y( |+ j
        if( exsound_select & 0x02 ) {. G  e: V; j! c  f' v7 Z1 _
                vrc7.Write( addr, data );
$ Z* _. E9 O$ F0 |        }
2 h6 Z/ X! H3 e6 l& o9 s        if( exsound_select & 0x04 ) {
  d9 L3 A- d8 f8 ]# T" X! I/ P. l                fds.Write( addr, data );
! d. v) V$ m/ K) K! |        }
4 w; x. r5 W3 g7 a& e* {" t        if( exsound_select & 0x08 ) {9 j. C$ a+ S. h9 _( c
                mmc5.Write( addr, data );
8 v1 G+ [# H) W9 w        }
" m1 M" h$ z+ T: J9 I8 o  u        if( exsound_select & 0x10 ) {* V8 H0 w( ~$ A# ~
                if( addr == 0x0000 ) {
) H- G. L$ L5 F4 n7 F# F                        BYTE        dummy = n106.Read( addr );
! H' E/ x7 c9 I3 p# G2 ~* _                } else {4 S* Y, {  K/ q$ |# A) U9 G
                        n106.Write( addr, data );
8 `/ z# p/ m( }- D) u$ ]2 i1 n                }4 p) ~* H0 C4 J4 f& X& ?
        }6 A$ Y7 _5 G' q) h2 ^
        if( exsound_select & 0x20 ) {
* y2 Y3 h" ?( V; l. g1 g                fme7.Write( addr, data );* R$ C, m" h( K2 ~- G, Z
        }% I, M' I# |& z9 L! R( b% x
}; r1 f! A* P' p7 Z+ y0 b
! L2 {; ~' Y1 e6 P! x; c
void        APU::Process( LPBYTE lpBuffer, DWORD dwSize )! K+ e, K& D& a, F% d) D
{
+ }! y+ b, N8 c8 F% ^5 u3 h* UINT        nBits = Config.sound.nBits;7 c% L( S2 @3 }
DWORD        dwLength = dwSize / (nBits/8);
1 e3 V! n6 G* N( uINT        output;
7 I0 Z0 S1 \" ~# o; G) {QUEUEDATA q;) \1 R/ y  I& k4 y
DWORD        writetime;
9 j1 s" [$ t( i& C3 g5 C
( u. j9 {0 I' c4 Y% nLPSHORT        pSoundBuf = m_SoundBuffer;7 h+ {9 P8 @6 ]: M& d; @- \
INT        nCcount = 0;. }  z- W0 F3 P4 a( n7 U

" ~3 E9 C2 o, R3 mINT        nFilterType = Config.sound.nFilterType;
5 q' d: q2 C" B1 y( K' \7 D0 h3 A& P! Q& l
        if( !Config.sound.bEnable ) {$ ?5 h) T3 ?0 @: T% r( l$ s
                ::FillMemory( lpBuffer, dwSize, (BYTE)(Config.sound.nRate==8?128:0) );9 }! K% Y! u2 f2 Z
                return;" ?6 m1 g1 r7 q: y& |
        }7 K6 o8 Z* w9 C7 U+ l4 k" T- C9 _
  }8 s, O% L  G- F$ J
        // Volume setup
! L) B% A$ c9 y* f8 _; [. {# v        //  0:Master
( O$ ]; v6 k4 L) u# W0 U        //  1:Rectangle 15 ]6 r7 M$ b& p8 t# Q( }
        //  2:Rectangle 2. n! J) x7 T# v' f* s: h. Q5 L
        //  3:Triangle' ^9 P1 \& I3 n# a" H( j# [: b
        //  4:Noise
$ Z' o, Q" R6 e: V1 [3 a        //  5:DPCM
# Q- Q& n0 o1 p' [* i  G! U        //  6:VRC6
6 e. U6 x* ~4 e& k9 |% O0 x6 G+ u        //  7:VRC7
! G! X* t; |& [/ p, B. L        //  8:FDS5 E" H2 h; S, T* }9 H
        //  9:MMC52 M' u7 A8 T+ [- g0 {% H- T
        // 10:N106
6 y* v' [$ [* U4 F/ ]        // 11:FME7. X* Z  a5 `+ R
        INT        vol[24];
% j8 d, [8 u5 l# ]% b+ P        BOOL*        bMute = m_bMute;
% ^/ R. x6 |. _1 g        SHORT*        nVolume = Config.sound.nVolume;
; S0 {' R8 \8 c2 [& s# D5 Q6 D/ A6 j
+ v# |5 j+ z( l. s, ]        INT        nMasterVolume = bMute[0]?nVolume[0]:0;
6 x% B% j( D  E" _
/ }* T& _  Q1 ~6 f        // Internal0 u& U! I' l- m  N
        vol[ 0] = bMute[1]?(RECTANGLE_VOL*nVolume[1]*nMasterVolume)/(100*100):0;
( w# j- z, Q: o; y0 _        vol[ 1] = bMute[2]?(RECTANGLE_VOL*nVolume[2]*nMasterVolume)/(100*100):0;
+ Z9 M+ c0 q' x" O: t: z        vol[ 2] = bMute[3]?(TRIANGLE_VOL *nVolume[3]*nMasterVolume)/(100*100):0;
' Q6 z1 k0 u6 m6 ]: W        vol[ 3] = bMute[4]?(NOISE_VOL    *nVolume[4]*nMasterVolume)/(100*100):0;
& K7 I, D7 r/ N1 j        vol[ 4] = bMute[5]?(DPCM_VOL     *nVolume[5]*nMasterVolume)/(100*100):0;. f' J5 ?' u- X( F- L9 H
4 k( |! n  I  }: g$ n
        // VRC6
6 V2 F2 R+ I* z1 R" `- J$ M. ^        vol[ 5] = bMute[6]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;2 ?! l1 ~( z. K% z% S
        vol[ 6] = bMute[7]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
7 E, D+ ]$ K5 @- b" t% r" ]* V/ [        vol[ 7] = bMute[8]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;  A# ~* v' r+ j8 ~( O) F

! E3 i+ p2 P5 o/ G! Q        // VRC71 B; b0 y$ N8 H, q$ J
        vol[ 8] = bMute[6]?(VRC7_VOL*nVolume[7]*nMasterVolume)/(100*100):0;
. j( K, A! |- o& ^. o( a! O1 r5 y0 s# H( \, f  O% a9 l
        // FDS. E) ^! F+ |8 y7 r( [" L: h/ ~- V6 I
        vol[ 9] = bMute[6]?(FDS_VOL*nVolume[8]*nMasterVolume)/(100*100):0;
; I: F  \" `4 f3 ^9 P, _
7 B: w2 [! A# I# ?        // MMC5
2 w3 j# ^2 y& R1 ?, o7 G        vol[10] = bMute[6]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
) Y( y3 W: \8 J, j! I6 D) X+ m( W        vol[11] = bMute[7]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;9 ^; ?. M1 [9 L$ h6 `
        vol[12] = bMute[8]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;, Y. L% O+ P3 h4 f

- v# D$ G& v3 R- u        // N106
2 b. T. i4 d  G% |8 H        vol[13] = bMute[ 6]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
0 r) \1 G1 c2 T7 c( b; E        vol[14] = bMute[ 7]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
! U! K- \, ^! w        vol[15] = bMute[ 8]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
% G6 M3 w; ?. N- t1 ^  g- F        vol[16] = bMute[ 9]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;$ ~% I: j  R  s
        vol[17] = bMute[10]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
* ~& r$ ~3 A# |3 u. Q4 R        vol[18] = bMute[11]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;: C8 T- ?. W) q# l9 c
        vol[19] = bMute[12]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;: Q8 z  J% D& H1 `& _$ o- S0 V
        vol[20] = bMute[13]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;- T4 u8 B9 w' D( d% \( s9 N
; X0 h. I. F' r* D+ w. M
        // FME7! ~4 f9 j; o$ B' w
        vol[21] = bMute[6]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;6 L0 j7 r$ t) S1 ^( O7 a  X5 i, `
        vol[22] = bMute[7]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;  E, A9 {2 q3 b' F) w5 ?5 f
        vol[23] = bMute[8]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;' b  t& z# m* R) K1 l, z

' p" n1 \9 T6 ?* R//        double        cycle_rate = ((double)FRAME_CYCLES*60.0/12.0)/(double)Config.sound.nRate;
8 [) @+ l- W+ z1 {        double        cycle_rate = ((double)nes->nescfg->FrameCycles*60.0/12.0)/(double)Config.sound.nRate;
7 _  f$ C; j9 X6 J' E5 n6 j7 G. Y. A3 F; `
        // CPU僒僀僋儖悢偑儖乕僾偟偰偟傑偭偨帪偺懳嶔張棟
* x' O& {8 g* B        if( elapsed_time > nes->cpu->GetTotalCycles() ) {7 Z, Q; s+ q9 p4 I
                QueueFlush();% n. c( V  [+ d
        }
" k7 \7 n" U" B+ Y! z
. w- i$ x5 J0 L- K; ]) l8 [        while( dwLength-- ) {
* {0 R, ~  f& L! k9 Y. a                writetime = (DWORD)elapsed_time;# ?% l0 m) {: A5 `" H0 s

% Q7 {3 l& H2 t' J. F                while( GetQueue( writetime, q ) ) {
0 \+ {) l/ {: }& _/ G                        WriteProcess( q.addr, q.data );
$ d6 C: K; ^3 j. p                }
2 A- k$ o! N& j
+ B9 I6 G. l  g3 d                while( GetExQueue( writetime, q ) ) {
: E2 P& ~% M: u2 h$ c6 |                        WriteExProcess( q.addr, q.data );& K# e4 X5 W! N8 c" ]7 V( c5 x
                }, S6 X$ L" m9 k8 a% O
5 o1 h5 p, x- V4 h& J+ k  @
                // 0-4:internal 5-7:VRC6 8:VRC7 9:FDS 10-12:MMC5 13-20:N106 21-23:FME75 i: s) c; `  s( }% d
                output = 0;% ?" }- |( ]: ?
                output += internal.Process( 0 )*vol[0];
: ~2 v% b$ w0 p, {- x3 N) {                output += internal.Process( 1 )*vol[1];( `$ ^8 e0 B: m, R1 H
                output += internal.Process( 2 )*vol[2];
/ H* n6 X8 W0 h+ O8 {                output += internal.Process( 3 )*vol[3];1 k1 @/ l% T* I: [
                output += internal.Process( 4 )*vol[4];
, D1 ]. I" y; S& W( d5 D/ E4 B0 x+ u: z" G
                if( exsound_select & 0x01 ) {2 ]' Y5 P5 C4 P6 n
                        output += vrc6.Process( 0 )*vol[5];& f# ]' Y) S/ M! O/ W, [
                        output += vrc6.Process( 1 )*vol[6];. l+ J. M8 y$ H  I) r) a8 T" r, A
                        output += vrc6.Process( 2 )*vol[7];& d; z  f, y' g4 _% |% M3 o
                }9 n0 T" u* U/ c
                if( exsound_select & 0x02 ) {
" O- {, A" X  Y8 x; S, Y5 R+ ?                        output += vrc7.Process( 0 )*vol[8];9 N: `! }) f$ K' s
                }
' J; \- q0 \) c, K- J& M                if( exsound_select & 0x04 ) {
3 K1 h( X& `7 S7 Z. M                        output += fds.Process( 0 )*vol[9];% S) h8 d; W: u8 @9 m
                }1 I. ?' q5 J7 K" o0 F- {+ H
                if( exsound_select & 0x08 ) {/ C+ n) z+ l" s) _0 }
                        output += mmc5.Process( 0 )*vol[10];
# u  H1 Z$ t7 c! j                        output += mmc5.Process( 1 )*vol[11];
% }& Z) A# M1 Q7 O9 O. O4 [                        output += mmc5.Process( 2 )*vol[12];4 G5 A5 c3 i7 @
                }
( f% c3 X. _0 P) a                if( exsound_select & 0x10 ) {' U& [" |3 |3 C+ n' B, o* I
                        output += n106.Process( 0 )*vol[13];
/ C0 I8 P7 y# |- q9 a                        output += n106.Process( 1 )*vol[14];
( h- C. M, m) b                        output += n106.Process( 2 )*vol[15];
0 e; J7 i. V$ J* J                        output += n106.Process( 3 )*vol[16];
: F2 d4 d- y3 g: Q0 c- ]8 U# M                        output += n106.Process( 4 )*vol[17];
7 Y  C; x8 L) G                        output += n106.Process( 5 )*vol[18];4 ^' D, N+ q: I9 l( I9 L
                        output += n106.Process( 6 )*vol[19];
: k% j8 [2 m1 u. e9 M7 S                        output += n106.Process( 7 )*vol[20];
2 E1 ]" @/ A9 g0 e# a$ ]) n: Y                }
) W5 Z& b1 G8 S( Q5 L+ s                if( exsound_select & 0x20 ) {0 \% l* g7 i/ W0 {
                        fme7.Process( 3 );        // Envelope & Noise
9 Y0 Q& q  Y- A; `0 l- [: C                        output += fme7.Process( 0 )*vol[21];
; Z8 f2 v+ |% {" U1 U                        output += fme7.Process( 1 )*vol[22];6 O0 x& t* {3 _1 m
                        output += fme7.Process( 2 )*vol[23];( q3 N. T" `8 O, T. ]% I
                }8 E; x& S, X7 X+ I
. q, J3 R; F0 q. y" n) r  m8 t
                output >>= 8;1 o6 z' _; b" k/ ]4 O9 F

/ k, I5 |% S. M9 b2 X! y9 C' w                if( nFilterType == 1 ) {- G) I' |' `: f; O7 v
                        //儘乕僷僗僼傿儖僞乕TYPE 1(Simple)
# A# A  v0 }; r' g! \                        output = (lowpass_filter[0]+output)/2;
. B7 \. m4 r) @; K( G. K3 Y' C                        lowpass_filter[0] = output;! }9 y7 H- l2 M5 b2 N; r
                } else if( nFilterType == 2 ) {5 G4 G% q' B" o
                        //儘乕僷僗僼傿儖僞乕TYPE 2(Weighted type 1)
) G$ t/ C, O' F( p9 U3 P/ T. e                        output = (lowpass_filter[1]+lowpass_filter[0]+output)/3;
6 K) d4 h9 Z0 M$ b) h2 \                        lowpass_filter[1] = lowpass_filter[0];
4 U+ t5 K( M& a                        lowpass_filter[0] = output;5 z" o% L: U7 [2 w: U5 t
                } else if( nFilterType == 3 ) {
* I- `" p1 N8 m/ p8 Z# z                        //儘乕僷僗僼傿儖僞乕TYPE 3(Weighted type 2)
+ ^; g# _# z% J; s4 g                        output = (lowpass_filter[2]+lowpass_filter[1]+lowpass_filter[0]+output)/4;
$ z. p1 [) r% a/ _                        lowpass_filter[2] = lowpass_filter[1];$ i) x; P( D# L8 W4 x
                        lowpass_filter[1] = lowpass_filter[0];2 _( q6 `* a  ^4 W
                        lowpass_filter[0] = output;  {4 ^! r- ^" J1 Z
                } else if( nFilterType == 4 ) {/ g4 ]  d- _4 Z6 `) V
                        //儘乕僷僗僼傿儖僞乕TYPE 4(Weighted type 3)7 r' z$ e$ x( c3 f* E
                        output = (lowpass_filter[1]+lowpass_filter[0]*2+output)/4;
5 p* E% P; u1 c) K. z- z! T7 r- B                        lowpass_filter[1] = lowpass_filter[0];
3 O7 p8 d  h$ O                        lowpass_filter[0] = output;
+ `( J( P/ y8 _4 b0 j  J                }  ]3 T6 j. z0 F4 X! ?) U

% H: o, |, p3 V0 S% R#if        0$ Q* V! P9 q- M' J
                // DC惉暘偺僇僢僩
: S: u  v/ \; b5 q/ I                {
& H+ v; o8 n! {6 k$ x3 M                static double ave = 0.0, max=0.0, min=0.0;
" E: |. L0 F1 W1 }0 N                double delta;5 Q! p% h  J, \0 ]9 G6 l8 p) L
                delta = (max-min)/32768.0;
+ h6 S) l3 L) V  S' {# y7 ^                max -= delta;$ ~3 Z  C# X# Y1 c
                min += delta;
2 m1 k( Q, c+ ]; V; s: G                if( output > max ) max = output;
( }& |( _# X4 A9 i) d1 q+ f                if( output < min ) min = output;
$ ^, E& _6 q/ V1 b# P8 ?                ave -= ave/1024.0;
6 H2 k, t2 r: }6 i. D8 C                ave += (max+min)/2048.0;( w' y3 O9 X' O$ T9 M8 ?
                output -= (INT)ave;
9 L6 z! P# U% I" V& l2 H                }
0 w5 S8 ]( S: U. z& J: C+ p#endif. n: p8 ]$ o! `! I9 r
#if        1
0 ~' p# @2 q. g$ ]+ G0 j% D                // DC惉暘偺僇僢僩(HPF TEST)' S9 ^7 @, D. F
                {
- l9 e  `0 D  B) Z0 \//                static        double        cutoff = (2.0*3.141592653579*40.0/44100.0);8 H9 p/ ?/ v+ c
                static        double        cutofftemp = (2.0*3.141592653579*40.0);* r; u6 i" ?. e5 w! C* u1 x
                double        cutoff = cutofftemp/(double)Config.sound.nRate;, ]! }: \, U4 h$ {- l
                static        double        tmp = 0.0;
0 F4 p0 ]) ?, k                double        in, out;1 y0 F! A6 W$ M6 W1 ~: r

% e' h$ @1 e3 Y5 ?. B. p! l( p                in = (double)output;
6 A) Q7 |! H% u5 P* k                out = (in - tmp);. G- \7 o+ \9 C
                tmp = tmp + cutoff * out;
. r! Y/ S. t! a( u# A7 G( N. L% ]0 {  G" M
                output = (INT)out;2 w* r- k# D% D& V% C+ N
                }! l  W" @' t" ?$ |! h# i
#endif
: m9 W- q6 I  w: u/ w#if        0
& W& J6 f: J0 c2 Y                // 僗僷僀僋僲僀僘偺彍嫀(AGC TEST)! e2 Q, u, D+ [9 \
                {
- l- v( ?9 W1 ~% G" I9 }- h                INT        diff = abs(output-last_data);6 C( j2 K% k) p# n6 s% n# y
                if( diff > 0x4000 ) {2 ]) Q' o$ M  U( R% F5 h/ i
                        output /= 4;
& O4 W4 O! H1 p, n                } else % _' _8 \: A+ s* x% I
                if( diff > 0x3000 ) {$ J& f+ I# V+ `1 m
                        output /= 3;! {( ~7 q: i, v) F2 T+ }
                } else
5 j/ s( B( d* J; c                if( diff > 0x2000 ) {
0 d3 M) {$ C; p) t( d, O                        output /= 2;6 n7 C! X- q6 P5 }% n7 G, C. h6 I& r4 O, Q
                }
$ m7 y. M8 B. W( N0 ?" T                last_data = output;' i8 E- v# l1 }. o, S4 V
                }
  H7 S& z: W1 w+ V; g#endif
+ i$ K( S3 Z8 b! @& H+ q, m                // Limit
: ~! @4 d8 [9 t- ~( N: i                if( output > 0x7FFF ) {
; w" b9 B) B% Q! }5 B/ U2 n# ^; g$ x% G                        output = 0x7FFF;
. z- k0 L  I2 d8 r$ e  W                } else if( output < -0x8000 ) {
! l1 j# L5 Y% l6 E. ]3 S  G                        output = -0x8000;; a; a9 k, B, X7 I9 L$ n
                }/ X. h9 Z# Q2 r' P) T- ^
4 R, F" c/ R5 _
                if( nBits != 8 ) {
$ V" G- z0 x( b9 E: X, o1 e0 E                        *(SHORT*)lpBuffer = (SHORT)output;
7 S; f1 N2 w; n- O% h5 ~/ `# Z% B                        lpBuffer += sizeof(SHORT);' o& F: s9 v* u0 N
                } else {
' y/ s' J4 w* a! b                        *lpBuffer++ = (output>>8)^0x80;3 d/ m; @6 l& _
                }! b5 U  d# v) y  i; f

% H  B4 A% Y( t1 f' d- T                if( nCcount < 0x0100 )& N# E! d/ N4 Z, c
                        pSoundBuf[nCcount++] = (SHORT)output;
" g5 D0 }1 z+ @  b1 M% z! g) u/ [) r1 F) d8 v& m: W' L
//                elapsedtime += cycle_rate;
& \+ t2 ]% m5 ^( Y8 y8 I, O& _                elapsed_time += cycle_rate;$ D/ L8 ]# @7 \5 z+ e6 S
        }; Y7 n# g* [3 w' W+ ]: X6 L2 v
4 T5 _2 ]  e. P! D* p# e) _" s; G
#if        1- d6 Z( Y, ?' R/ Q6 }
        if( elapsed_time > ((nes->nescfg->FrameCycles/24)+nes->cpu->GetTotalCycles()) ) {
; U3 l- W; b6 ?7 V6 S. m                elapsed_time = nes->cpu->GetTotalCycles();
6 D2 l! R* p5 i! w2 Q* S        }
5 w( \! P  M& A; \        if( (elapsed_time+(nes->nescfg->FrameCycles/6)) < nes->cpu->GetTotalCycles() ) {8 d; E; m4 v  `  Z3 j' T" q% O
                elapsed_time = nes->cpu->GetTotalCycles();
" R8 V1 f) q/ Q9 B        }; @; [# P+ O1 h
#else( r$ [8 Y& f1 V; J, Z. I
        elapsed_time = nes->cpu->GetTotalCycles();+ d0 C! I( T: |
#endif
/ Z# ~4 @+ H3 `7 z}( p; P# x. e8 h' s: x# P2 a$ g- Z
/ M/ s: _& p5 s
// 僠儍儞僱儖偺廃攇悢庢摼僒僽儖乕僠儞(NSF梡)
* J" r; A2 i6 z3 E1 Q. _: f8 lINT        APU::GetChannelFrequency( INT no )
- k5 \4 q7 i) K3 H7 P{9 k6 K6 }1 o& d1 P* w
        if( !m_bMute[0] )
4 r/ ~! T$ b2 i( T                return        0;
* F! v) ]% N! T! M2 `, L
# @4 a8 V" o3 d- W& a* x3 Y        // Internal; S5 f8 X' @; i
        if( no < 5 ) {
- H9 {; ]$ \" A, I" `# J0 ^                return        m_bMute[no+1]?internal.GetFreq( no ):0;
$ R6 a4 i2 q0 I% f, ?2 R7 V        }( J+ U2 E- s9 x4 |5 @
        // VRC66 I- o0 q  N; V& o" J
        if( (exsound_select & 0x01) && no >= 0x0100 && no < 0x0103 ) {$ B# {4 @1 |% W! p1 H* V# U1 ~0 T
                return        m_bMute[6+(no&0x03)]?vrc6.GetFreq( no & 0x03 ):0;
, _7 p) h, o: Q        }( l  @& q* `6 M+ s1 \
        // FDS" D- Z9 K" y: i+ u/ R; v3 U' C
        if( (exsound_select & 0x04) && no == 0x300 ) {
  [# p! [5 ~7 q7 v% g7 {3 q6 _                return        m_bMute[6]?fds.GetFreq( 0 ):0;
$ v& [+ v' t% M7 C$ ?$ m        }
1 T6 Y/ T( J7 M$ K' W        // MMC5% o1 O# K5 B6 G
        if( (exsound_select & 0x08) && no >= 0x0400 && no < 0x0402 ) {
  t3 \) u/ s( G7 U7 d! r# ^; i                return        m_bMute[6+(no&0x03)]?mmc5.GetFreq( no & 0x03 ):0;
3 m8 J" m3 }! w" U# U2 w& h        }' A0 l& H  f" J; R- F
        // N1064 T& K  T( }( Q7 f/ A; q# K" f
        if( (exsound_select & 0x10) && no >= 0x0500 && no < 0x0508 ) {
; U! O" {, y: `: y5 B2 E& ]                return        m_bMute[6+(no&0x07)]?n106.GetFreq( no & 0x07 ):0;
% \' t/ _% s" Z$ Q5 y' V, b7 H+ ^        }9 S, d4 ~2 d' [0 Q5 h3 U" ^  e
        // FME7: v+ h$ t" e, A! b
        if( (exsound_select & 0x20) && no >= 0x0600 && no < 0x0603 ) {6 y7 p& U$ e& L! |( o
                return        m_bMute[6+(no&0x03)]?fme7.GetFreq( no & 0x03 ):0;0 @1 @0 g0 g  s6 A
        }
! y3 w- ^, k% I* O# K6 b        // VRC7% M1 S  ~1 V' q9 ]
        if( (exsound_select & 0x02) && no >= 0x0700 && no < 0x0709 ) {
0 V  b8 W1 C! U  ?% g& V                return        m_bMute[6]?vrc7.GetFreq(no&0x0F):0;& _+ D, Y. y) \% V, O0 n
        }& ]: P# v5 t" _3 b/ k
        return        0;
3 r' v1 f; A; b" g- |}" N% h, J' ~. \% r# I3 I& v

- g& X0 i- s$ v+ P// State Save/Load
- p/ F# [* |; k  d: y" i! o4 vvoid        APU::SaveState( LPBYTE p )' M- e# m0 {  O% g% L
{
8 K1 F4 b2 A; e0 g' f8 v#ifdef        _DEBUG6 a+ M6 a( K# \9 c* y
LPBYTE        pold = p;
% c) n/ P, g( a9 X" G3 d#endif
( l- t  m+ M$ u& _3 B9 Z! S( U1 m1 z8 r6 l3 T6 F
        // 帪娫幉傪摨婜偝偣傞堊Flush偡傞; z( t4 Y9 K; V) z- L; f2 ]
        QueueFlush();
+ k, a- x1 A5 Q! Y% q; l' N4 @3 g5 W1 a% I/ Y9 G4 q
        internal.SaveState( p );
8 [, f$ H" q# q0 A4 O& z9 a- `9 m        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding" r/ J& s# K/ B0 ?" t
, R0 L% A4 o: v9 h" j
        // VRC6
" m: o- R9 i8 P" ]- L3 A8 x7 s        if( exsound_select & 0x01 ) {7 j8 O' m4 L; k& Y! r* o
                vrc6.SaveState( p );
3 i4 B' j. c2 Z, J# p$ f                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding; O$ U/ Z5 \0 e6 u' ?9 m* ], ~
        }
0 W- R5 ]  C% u9 z% v- ^; s$ |2 |        // VRC7 (not support)# Z' X7 j: r# V
        if( exsound_select & 0x02 ) {. |+ S! ~. ]/ o4 C  I" \8 v
                vrc7.SaveState( p );
4 n, ^3 @% J! y2 C# R                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding  x/ w/ j- W" z( [; x
        }
! E  j6 Z( t1 p4 O: K4 H        // FDS
3 h7 W. o  a( b1 W* ^        if( exsound_select & 0x04 ) {" y. n9 k: ~2 p0 H! N" o6 y
                fds.SaveState( p );6 G7 J: ?+ l; Q/ U
                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding! i! H- H4 @! x
        }
! W. N+ @9 x4 C/ e0 O        // MMC5  r9 w( }3 \( Z
        if( exsound_select & 0x08 ) {
! b4 T9 q- c5 E2 P                mmc5.SaveState( p );
, A  ~4 s' n- u) ^# j. A; m                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding7 T5 S% c. @3 D4 F9 n9 w: w
        }
) ^5 w! c; g8 M0 Q2 k4 z8 v& b" G        // N106$ y, C0 H- ]& u7 L( O
        if( exsound_select & 0x10 ) {
4 J& w$ @2 V/ Z& }# `( P& k4 o+ t                n106.SaveState( p );' O" C6 ?9 W( |- _
                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding
7 i4 \" N0 g4 `/ W  g  p        }
, k0 {4 F; g2 L$ w        // FME7
. G0 C# T- k( D7 w        if( exsound_select & 0x20 ) {: w+ Y0 y) i  J' ^- M4 t' s5 R
                fme7.SaveState( p );. k6 u: \( g+ w" R3 c/ `, j
                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding" R3 C) |& S) p
        }
3 W# J2 k& |4 y" G( a* x5 O  R: W7 r" t: |' _
#ifdef        _DEBUG; X7 B# l2 ?) Y; j9 G8 V. f
DEBUGOUT( "SAVE APU SIZE:%d\n", p-pold );
7 q5 L, N) h% S7 S#endif  p$ u# g4 k, C5 o
}
. s9 h* |1 M+ M" ?8 x3 `
5 F; _8 d, _+ `void        APU::LoadState( LPBYTE p )
, y- K, v' }6 X% s{7 _  w+ m$ g3 w1 e' `
        // 帪娫幉傪摨婜偝偣傞堊偵徚偡
  ^8 }& y4 `. @7 X        QueueClear();1 R/ Z9 V6 t' g* j; M  C+ }) J( H

8 |7 \# V, ~" C" t3 S. a, J5 h        internal.LoadState( p );
: C: F7 J; N' X) X) D3 a        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding8 @- n; |! R3 i) a+ F
& q0 E9 d  S+ G. T
        // VRC6
+ s7 T$ o& K! X, g, s3 _        if( exsound_select & 0x01 ) {$ ^5 z5 E/ l% o% [( k- }# T- s
                vrc6.LoadState( p );0 D  d) t9 v, r
                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding
/ z, J6 s. G& k$ j        }. p  \4 t1 y4 v3 o: D+ E0 G# U! P9 C$ ]
        // VRC7 (not support)
6 l& k5 D5 d+ [! S' [- U% p' M& t        if( exsound_select & 0x02 ) {
6 t) f& t# l1 c& {                vrc7.LoadState( p );
8 ^8 x( e# {  B0 ]  J/ J) w0 C                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding7 i0 G1 x2 H* e" z# I% J% p6 W
        }# E1 |. X4 V2 J
        // FDS
# c# j  P0 H0 ^4 H5 |  B        if( exsound_select & 0x04 ) {2 z# h7 L  Q! c5 L
                fds.LoadState( p );1 [6 s0 e  B/ S. ^
                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding
# s+ q+ |+ r* [# q. q: a, E        }
3 K3 G' C1 I  r1 e; }        // MMC5
$ Q8 b! j2 y' ~% Y, R6 d; \        if( exsound_select & 0x08 ) {
, a4 y5 V9 E; E+ U! ?7 E                mmc5.LoadState( p );# Q: w8 I0 {; ~
                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding
: \( j0 c6 K6 I, E1 x# \, g8 p        }7 d7 ]% G$ q1 v) b
        // N106+ d" p- Q, m% s, M- q
        if( exsound_select & 0x10 ) {
) p1 E% W! _6 d2 u                n106.LoadState( p );
$ v  ]% Y7 @3 R- f                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding
: g, ^3 M9 m  K# l! x6 n        }% L: X+ P3 M  j7 F. }. w5 ^
        // FME7
  u  p: y. K& m' q        if( exsound_select & 0x20 ) {
) j% T3 b. Z* H( n  E' Z# H                fme7.LoadState( p );& s+ n. ?" p5 [$ X0 ?  y" ]
                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding6 U  q* r* p9 g; V1 W9 N  ~
        }" V3 C5 w4 n9 B3 v
}

该用户从未签到

发表于 2009-11-8 17:25:37 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 14:38 发表 & A+ P9 O, d/ Z' k& g  }6 x
可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。
' e* M7 `7 K: a5 ^* b+ G感激不尽~~
) d& R+ C7 E) u) n6 [# z
恩 我對模擬器不是很有研究,: Y. h: @% t6 O; z+ m+ H" H1 b
雖然要了解源碼內容,可能不是很困難,
% M7 |  l: |- [4 ]不過還是要花時間,個人目前蠻忙碌的。
1 B, J; d3 q6 g8 z2 K5 q2 r; ~0 `, T6 \7 v( h" b  B2 E6 z, ]
給你一個朋友的MSN,你可以跟他討論看看,/ N( T+ G- |# j* \9 S+ t
他本身是程式設計師,也對FC模擬器很有興趣。- }4 W3 f1 b0 T5 J& F! V/ L% q
$ i$ X& I- f+ I. K7 L( F
MSN我就PM到你的信箱了。8 Z; K8 e5 W3 N
  }6 B4 E1 ]- v
希望你能有所得。

该用户从未签到

 楼主| 发表于 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; Z/ V; Q: g* |$ J+ l2 O
呵…… 谢过团长大人~~
+ ?) s0 s4 M, i' D9 r5 t2 K

. L9 c7 u: s" F' m$ r4 j哈 不客氣,算是順便幫他找個伴,大家可以一起玩。

该用户从未签到

发表于 2009-11-20 13:14:53 | 显示全部楼层
原帖由 李伟 于 2009-11-9 16:02 发表 - H- }6 Q2 `8 e$ |! D9 L! u
团长的朋友都是神,那团长就是神的boss。
& X" F8 j  I0 q+ L- h. B+ _
哈 不敢當,我只是個平凡人,
  |2 U8 C6 s" z3 [- B. w7 }6 k% n9 A* E要吃飯喝水,光吸空氣是不會飽的。。。。 :)

该用户从未签到

发表于 2009-11-20 13:32:35 | 显示全部楼层
FC模拟器的部分有个人可以帮你忙) I: I$ Q; x* e  w9 V
ZYH
. j3 G0 g0 q& U" K+ RQQ:414734306
$ x8 E; D2 i; Z- u! {Mail:zyh-01@126.com
% p- I9 A6 a8 Y' K
- t& M, ?, [% \9 x; C/ j他是ZYH Emulator这个模拟器的作者,只是他用的开发平台是VB,不过就6502的实现原理来说是一样的

该用户从未签到

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

该用户从未签到

发表于 2009-11-27 19:09:06 | 显示全部楼层
原帖由 独孤残云 于 2009-11-27 09:48 发表
8 @0 [1 A( m* _1 i! s, L再次对团长大人和悠悠哥的无私帮助表示感谢~~
6 K, H* |2 A6 r7 }
不客氣  ^_^
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2025-12-18 11:25 , Processed in 1.083984 second(s), 18 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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