EMU618社区

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

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

 关闭 [复制链接]

该用户从未签到

发表于 2009-11-2 22:45:57 | 显示全部楼层 |阅读模式
求助:模拟器源码中通过哪段代码控制Rom背景音乐的播放?
6 K6 \7 u* R- ?9 Y, s' i, f! gPS:看过一些模拟器的源码,大概都分为APU、PPU、NES那样几个版块。请大侠告知是哪个模块。感激不尽~~

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 09:56:34 | 显示全部楼层
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。2 f5 `, K0 @8 P7 H2 P# _
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~
% L5 h6 u( y6 V  `% E9 k这里有相应的模拟器源码,就当送给大侠了~~" S4 y. q9 Q% @9 j
http://kenkao.qupan.com/5096520.html

该用户从未签到

发表于 2009-11-8 11:31:10 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 09:56 发表 5 Z4 S% Y$ e# }8 l' D' A# c
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。
% N6 e( h2 r" p7 r! S楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~0 b  g+ P0 o4 K) O: o: D' E
这里有相应的模拟器源码,就当送给大侠 ...

8 N& P% }, z/ I聲音部分(Audoi Process Unit = APU):0 Z# q* ]+ V4 c( b, o" {! _
.\NES\APU.cpp) y. U9 W5 |. ~) p' a
.\NES\APU.h6 }& S. i* }) b

# u+ p- z! F9 O$ u& P
3 R9 y' d$ o/ Z( L( }/ l- {影像處理部份(Picture Processing Unit = PPU):
% u  X- Y- [3 e2 q.\NES\PPU.cpp
, G9 ]% ?) N- I% e6 R.\NES\PPU.h; v- S4 j( c5 w, A& `: U/ [! [4 R

- m& @, Z1 J6 W) z0 b0 [0 v如果原碼用C跟ASM混搭也不錯

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 14:47:50 | 显示全部楼层
这是我手中源码Apu.cpp的内容,敬请赐教:& w/ v" [0 u9 X- Q; V4 g
(由于很多专用术语和算法机理都不明白,所以看不大懂……), a- N2 b: h- v# x- |) f
//////////////////////////////////////////////////////////////////////////- J, ?4 _1 ]  |( W1 ~+ W& L! k
//                                                                      //
- v6 ?: N0 j! t9 e( e+ U//      NES APU core                                                    //2 }% w( g* E% z3 i3 Y( W
//                                                           Norix      //
2 E( z. O' W6 i4 H& O6 A//                                               written     2002/06/27 //
8 @7 T& x. Y: E+ A8 h! {% O+ w//                                               last modify ----/--/-- //7 F6 J/ [  ~* D
//////////////////////////////////////////////////////////////////////////  y' w/ N4 D# R5 e+ h: @. s
#include "DebugOut.h"' h) w+ N  P4 F, z6 M; v. _
#include "App.h"! h7 ]3 Z* h" R9 M
#include "Config.h"% p: \  J. C/ h- D/ S$ Q$ ~' ]# p

" S: z$ d. r& }#include "nes.h"
3 Z: U5 T9 B' }( u5 g#include "mmu.h"
0 R* g4 N6 H3 [' r$ b& s#include "cpu.h"
8 q+ o" N+ y, I; ?2 V  t#include "ppu.h"
! E, _/ q: `/ `* D, n& a# P) b: N#include "rom.h"
9 |1 I2 y0 w- i$ z#include "apu.h"- L* l! y% z2 L& \+ D) N
0 }  y6 m) L2 C
// Volume adjust! H/ N( i$ p% S9 f; q: ^
// Internal sounds
& i, Y5 Q. y, f#define        RECTANGLE_VOL        (0x0F0)
; u, T% e- s) v2 s8 I#define        TRIANGLE_VOL        (0x130)
& ~( f/ w1 o6 D: a- D: d2 o/ f#define        NOISE_VOL        (0x0C0)$ Y4 x! T6 S; D8 P3 L3 E
#define        DPCM_VOL        (0x0F0)
% d- A- U8 U3 A. r8 f7 \& D. ~// Extra sounds
# @' G; c" i# w2 q( [4 j#define        VRC6_VOL        (0x0F0)! \4 {8 x8 h  C* j! t, S  T- w
#define        VRC7_VOL        (0x130); V& O- C6 ]" n) L$ s+ s
#define        FDS_VOL                (0x0F0)
$ D1 [8 p! K* J* H4 l; [#define        MMC5_VOL        (0x0F0)* Z3 i! U  l7 {5 E  r
#define        N106_VOL        (0x088)
/ h- J, p. r7 M! |#define        FME7_VOL        (0x130)
5 q. S) B3 R, v% v2 r, F+ a/ p- G: C6 _+ [) P+ m1 g8 I
APU::APU( NES* parent ). l0 W2 `6 e5 A* ?5 t- @+ d
{
) C$ |" U( _& A6 l2 l  R: s        exsound_select = 0;+ M; A6 K. }/ }4 L2 Z# A
  w0 f! p( g. n8 o( D
        nes = parent;# S2 L8 D8 R9 a4 X
        internal.SetParent( parent );
9 F0 [/ e' A2 ~# @- F( M0 |$ d/ N4 H4 \/ d6 n4 p* ]- F
        last_data = last_diff = 0;/ Z6 ~7 i- S! S, J! h; `$ o  \
1 @& Q. Z  }7 o
        ZEROMEMORY( m_SoundBuffer, sizeof(m_SoundBuffer) );3 k8 L5 ?& V8 R4 P: f2 u' s$ F

6 U, \. b8 ?2 ~6 E- x. v1 D! _        ZEROMEMORY( lowpass_filter, sizeof(lowpass_filter) );
* V2 K; f0 }& K0 S        ZEROMEMORY( &queue, sizeof(queue) );
* i5 e3 J' B* M3 ]  f0 y0 P        ZEROMEMORY( &exqueue, sizeof(exqueue) );8 y: a! n# o. k; E4 `8 a
: V- P- X4 o- ~, s5 i0 b
        for( INT i = 0; i < 16; i++ ) {
. B1 G% S- s' b5 A                m_bMute = TRUE;
9 f9 l/ Z/ q+ X; {' f$ R        }
4 x0 J1 \* H8 I0 ?* n}9 [$ X1 l% Z* n% ?8 l0 {
. f! M% j/ o0 _" q% Q
APU::~APU()4 }5 R1 y% a# P& V: [0 ^- \3 d
{: D" ]6 q! Q6 p2 D
}
, Z# W# a8 B5 k/ T0 p; Y( B9 ~9 v7 u- h. v) ?9 u
void        APU::SetQueue( INT writetime, WORD addr, BYTE data )2 t; |( X) ], O  D
{
( d$ O. o' r& w; U5 _        queue.data[queue.wrptr].time = writetime;) I: C  ^, l1 P# @
        queue.data[queue.wrptr].addr = addr;; |- A8 ^* ]0 O$ F1 H: x8 T
        queue.data[queue.wrptr].data = data;
$ H0 x/ H) m/ J        queue.wrptr++;
' D9 C' G. T9 b% w" g1 H        queue.wrptr&=QUEUE_LENGTH-1;9 v  \4 ]1 Y( B6 S2 ^; q0 I
        if( queue.wrptr == queue.rdptr ) {
" }. ], e( r5 T7 S2 z# R3 m1 z                DEBUGOUT( "queue overflow.\n" );
' n" ^7 O/ V4 w2 b, u9 `        }/ s" s$ X7 H# z1 w
}9 }" ^3 ^) e5 f) U0 @

- P2 a4 G% f& X. c3 r2 J- d6 F9 sBOOL        APU::GetQueue( INT writetime, QUEUEDATA& ret )
; _" l3 S- k% t$ C{
6 }. L* F- Z0 Q7 U+ c6 D        if( queue.wrptr == queue.rdptr ) {9 m0 h; D. m9 p# D
                return        FALSE;% x% N4 A5 i: w0 c. G, l6 ^
        }: n+ `9 B+ |) r/ |
        if( queue.data[queue.rdptr].time <= writetime ) {+ T& R- b' D) L4 E
                ret = queue.data[queue.rdptr];
: [% E  z# ~& v5 v3 u                queue.rdptr++;1 p/ C  H: b, r  D4 Q
                queue.rdptr&=QUEUE_LENGTH-1;
/ |8 X- o! ?# w5 l: m                return        TRUE;. b) \$ y1 l) ^( Q) E8 _4 W
        }7 E# v/ R2 [' @) B
        return        FALSE;% Z! X% H4 D  s6 |
}( S/ r2 r4 z, n' R" O8 `
7 p- T" E& s, o: N; K  Z
void        APU::SetExQueue( INT writetime, WORD addr, BYTE data )
: T- m) B+ o1 W; A/ w{0 e4 G1 E- a. K
        exqueue.data[exqueue.wrptr].time = writetime;
% A/ I: g" I& `% T% m& T, a; x        exqueue.data[exqueue.wrptr].addr = addr;6 \( Z( j7 P3 x1 B# r
        exqueue.data[exqueue.wrptr].data = data;
- g/ B; x/ M2 i0 E        exqueue.wrptr++;
* g1 y/ m  F0 Y6 |! Q3 W# K/ i        exqueue.wrptr&=QUEUE_LENGTH-1;$ C9 r2 a5 r4 A7 l
        if( exqueue.wrptr == exqueue.rdptr ) {3 Z- }/ Z0 ~/ ^# ?( }
                DEBUGOUT( "exqueue overflow.\n" );1 O* s9 V$ Q8 Q4 m; c
        }
3 P( m* {' Q1 C" S) N}
7 G' \" S8 h( U- K  d* x4 t* s4 |* D
BOOL        APU::GetExQueue( INT writetime, QUEUEDATA& ret )
0 Q9 u' E, C$ @! u% P3 ~' Z% M/ y{
4 @  ], Q1 U- {7 r1 x        if( exqueue.wrptr == exqueue.rdptr ) {( G3 E6 m2 d' H$ y6 A) r; I7 j) w
                return        FALSE;
4 z9 x0 x  t# K/ `# Q# b1 H1 T        }2 u& l  }+ v( w# h
        if( exqueue.data[exqueue.rdptr].time <= writetime ) {
0 N' N* ?5 {) g7 f% B; A$ }$ J- m                ret = exqueue.data[exqueue.rdptr];
9 l7 j$ p1 w' A& {6 c  u                exqueue.rdptr++;
: C2 C2 e4 F. K. h$ B                exqueue.rdptr&=QUEUE_LENGTH-1;
, y: C$ B1 b4 [$ Q2 L8 b                return        TRUE;
/ t  h8 @: D/ m+ H5 i8 N        }
6 @0 E3 c  {( j8 I/ t        return        FALSE;
; U4 u2 W2 ^! u7 M/ a}
/ [* v% r9 ^7 w+ F" @3 c3 H
/ s4 S7 m5 w# Q/ H0 m# Lvoid        APU::QueueClear()6 f5 v. d! m1 a, f6 I6 A7 }
{
, K- Q% V( Q2 `# O2 h" q( j        ZEROMEMORY( &queue, sizeof(queue) );
. I1 \7 ?  A3 F1 ~        ZEROMEMORY( &exqueue, sizeof(exqueue) );
+ D/ G0 K- c4 z4 V  Q: r}
. W1 l2 P# A) m" U7 m: p  I+ s* z) f: J5 t+ g1 |. I
void        APU::QueueFlush()! s7 W" _+ i9 \1 k
{' D4 ]: y8 L+ i% C! A9 [) D' D! D
        while( queue.wrptr != queue.rdptr ) {' R3 M# }7 F& y: S
                WriteProcess( queue.data[queue.rdptr].addr, queue.data[queue.rdptr].data );
( }* e( O: d" x# G) K                queue.rdptr++;
9 m/ G! t- b; P) J) w* x                queue.rdptr&=QUEUE_LENGTH-1;
7 Z8 ^& G0 \+ a* C; X1 G5 \5 R        }
$ Y! @+ v( s) D3 W; ^" ^! f) p( }+ o9 g" x) u9 t
        while( exqueue.wrptr != exqueue.rdptr ) {
- {. L4 ]& f2 x: u) J2 k                WriteExProcess( exqueue.data[exqueue.rdptr].addr, exqueue.data[exqueue.rdptr].data );3 T' M  [. i5 f- x4 D; d1 t- Z8 j" k9 Z
                exqueue.rdptr++;
, Z8 f% ~& G, I1 m' G                exqueue.rdptr&=QUEUE_LENGTH-1;5 [( e$ T5 G; ^! b- e
        }
' G  ]! N# p/ `. c}
0 v; G+ ?- n5 Z" b
4 a, N/ S- E* P$ R3 \void        APU::SoundSetup()
2 b; q- G& |' d6 b$ g& {{7 d# \* j1 }! \" U. H( g
        FLOAT        fClock = nes->nescfg->CpuClock;# F, L4 q* T2 a
        INT        nRate = (INT)Config.sound.nRate;4 v( G) }3 {; n
        internal.Setup( fClock, nRate );
2 a& {9 s/ ?0 C# Q+ B7 K        vrc6.Setup( fClock, nRate );
7 ?- V  Z8 k6 C/ L0 _        vrc7.Setup( fClock, nRate );
2 ?8 `) m- K- D3 f! t        mmc5.Setup( fClock, nRate );
# d# p% {% p% H0 ?        fds.Setup ( fClock, nRate );
7 v" m' m9 j- Q# P2 Q. X. u        n106.Setup( fClock, nRate );
- K! u/ G" J8 |  W: `- m: ~- @        fme7.Setup( fClock, nRate );
) |- j: u- q1 g9 |7 F# C1 b}( A' h! e3 \. O  O3 G% \- c6 E

/ ^8 w0 `  l% X2 Bvoid        APU::Reset()
8 ]1 B+ o+ I* d3 m# U{# z1 C3 H9 i# |) t
        ZEROMEMORY( &queue, sizeof(queue) );
7 B, S  o0 C, s* A1 \$ {" Q        ZEROMEMORY( &exqueue, sizeof(exqueue) );
0 [; @1 z6 I7 r' |0 ?+ \
; f+ [0 d/ p/ H, f        elapsed_time = 0;; s  K& |* f# z( x. e8 E" n
4 P4 J; g& F2 R
        FLOAT        fClock = nes->nescfg->CpuClock;, ]" l4 ]0 J& M& e/ M
        INT        nRate = (INT)Config.sound.nRate;3 c9 o! x4 N! K$ J( X" J3 W- t: ]" g3 v
        internal.Reset( fClock, nRate );# t( D! g6 _+ B9 f9 w
        vrc6.Reset( fClock, nRate );
" C' K$ ^+ u! C5 ?        vrc7.Reset( fClock, nRate );7 v! _+ ^2 l2 o
        mmc5.Reset( fClock, nRate );4 N+ d* ?$ j' F2 |" }: N
        fds.Reset ( fClock, nRate );9 y6 f- N4 I3 P; ~
        n106.Reset( fClock, nRate );
5 R4 W; {' n+ \        fme7.Reset( fClock, nRate );
( g( `7 }" ^" B* q7 z
; Y& D# L( L+ ^% P3 V  v        SoundSetup();
' I% w' i/ u- S2 |}/ d% H+ v/ o" k; L* w1 {7 x

& k+ a6 H  I/ N7 `5 Fvoid        APU::SelectExSound( BYTE data )
9 i* S; Q4 {" c4 J4 O/ w( o{+ Q7 k- r6 I1 p' z) v' F+ a8 R! Z
        exsound_select = data;
8 [5 \+ H0 x6 X( B5 a3 ]% {+ t}- C: a; a6 }  o* f5 c

+ p: d+ ]4 M2 S8 iBYTE        APU::Read( WORD addr ), M. J4 w; s0 x  X
{
" n. b* Q+ f" R        return        internal.SyncRead( addr );
) I8 s( O2 ?6 L: P+ H" c1 b}
6 u! Q7 q: w! S7 s6 v9 U3 ?( Y0 a* h$ C( g' G) b6 y
void        APU::Write( WORD addr, BYTE data )
( b! l0 @( ]  T5 W' V- x. g8 ^{, C; T. `  E8 ~& [
        // $4018偼VirtuaNES屌桳億乕僩
+ Y7 ?( v3 t; s) M1 e! n# f        if( addr >= 0x4000 && addr <= 0x401F ) {
8 S( S/ z4 |6 C5 `' h$ o& C                internal.SyncWrite( addr, data );
0 L  f8 z9 m7 c" b6 q# \; ^                SetQueue( nes->cpu->GetTotalCycles(), addr, data );" C% p& U6 Q- {9 r$ _6 Y9 e0 Q
        }
  M  G# v* H: e! t/ k}
5 @9 z  g% G4 ]# i% ~" l# n7 w8 W" D7 R' ?
BYTE        APU::ExRead( WORD addr )1 o4 o. k" Z! L" W3 Q% L! G
{
9 \  i0 o  |% z# \BYTE        data = 0;& ^' |, i  l/ M  |0 l( U
, a! Y6 w7 P; ~4 z6 V; q
        if( exsound_select & 0x10 ) {) z$ \# s: z, t" s
                if( addr == 0x4800 ) {
8 L& u8 f/ l) t% [3 P4 B                        SetExQueue( nes->cpu->GetTotalCycles(), 0, 0 );
% k7 E" D$ T# T; p2 \: g                }( j+ P0 t. U9 J5 B5 Y
        }
$ n  M2 l% J5 z" k        if( exsound_select & 0x04 ) {
; E* J; B& `9 E! }                if( addr >= 0x4040 && addr < 0x4100 ) {! E- v! F3 L7 ~7 P. P  m
                        data = fds.SyncRead( addr );5 E3 c8 Y  j: _  @$ C
                }
! X8 B- \0 ]) K* F/ A$ i6 q5 ~        }
! l3 J6 p2 Q' }' m9 b5 |        if( exsound_select & 0x08 ) {
9 L3 X8 }7 g8 `+ [$ y( F3 a! }; O2 Q                if( addr >= 0x5000 && addr <= 0x5015 ) {0 Q. Y# u6 z8 x* r1 v
                        data = mmc5.SyncRead( addr );
7 X* x) A9 J" h, K. q! O5 x                }1 |9 F% v" ^9 L* O; O+ _
        }
/ a  K5 h/ d" _. x6 y
: f4 x5 I, c( S8 W# I* D        return        data;
& M5 ~  t! h; J- l, @! x  J}
8 S( P) S5 S+ S7 }' H3 f( W
" S. c  [- b3 yvoid        APU::ExWrite( WORD addr, BYTE data ). @; {) }/ D! n
{
' [- W! C. H: s        SetExQueue( nes->cpu->GetTotalCycles(), addr, data );! u+ s( u( F+ H; t% D2 B- V% ~# ]; G: x

) c: n( C, _0 W/ x+ a        if( exsound_select & 0x04 ) {3 Q# D- d' r3 }
                if( addr >= 0x4040 && addr < 0x4100 ) {
1 O3 f8 a( t( Y- r' `" U                        fds.SyncWrite( addr, data );
; B' E( G$ y2 Y7 t+ e% N, ^+ }                }) |1 j( h7 `1 _+ V( g5 ~
        }* T* m3 p$ G* f3 K0 c- n3 c1 ?4 v5 \

8 v8 @8 Q: q0 ^. v$ J9 ?: j0 t        if( exsound_select & 0x08 ) {$ G! `3 ~) p0 Y: Y
                if( addr >= 0x5000 && addr <= 0x5015 ) {
8 q" ~, g1 c9 r: [1 c0 F1 P: R9 M                        mmc5.SyncWrite( addr, data );
# L9 E' M; T. P, D0 N: F; {. m& \                }8 Q5 Q8 K% E3 G' Z* S
        }
+ J/ m2 x5 T" b' {) u}
% Y" D) c' [" x- X
3 U& q' {4 o) I6 L) p! R# C1 m& Mvoid        APU::Sync()' u; `% V: N" X9 V* j
{4 d$ t- `+ u* D; D7 d& g) f
}
- P; C: n, M0 y2 ?( t% o7 |) v8 L( C  ?! F8 M# B0 O
void        APU::SyncDPCM( INT cycles )
, B* L# X. k% |5 I{
0 C. |4 `! ~$ K8 Q# r7 o        internal.Sync( cycles );" l0 ]# P1 W3 I" c- [  h

6 M- k% m8 K$ _& f        if( exsound_select & 0x04 ) {3 c" |9 h6 {) B! d
                fds.Sync( cycles );, ^$ _7 P! a7 n/ ~( |, @
        }1 @1 A2 H  W1 v& ~
        if( exsound_select & 0x08 ) {! X+ E6 b4 [" `( I6 |  o/ _9 G
                mmc5.Sync( cycles );
) X8 |$ N% _, S" O        }. ]" ^5 r* _- D. R. I2 N- g% I
}2 }# e- `: u& o0 o

* z( \% ?4 W- }2 a5 |0 [( jvoid        APU::WriteProcess( WORD addr, BYTE data )9 }7 ]  c" c% {+ H4 ]- s8 \( L
{
: s) p" a9 I/ N, ?        // $4018偼VirtuaNES屌桳億乕僩
5 d& G- I8 W; K" L/ ~5 B        if( addr >= 0x4000 && addr <= 0x401F ) {
5 x4 N% ^2 M* y1 l( H* y5 E4 f" C+ {                internal.Write( addr, data );
3 g9 p8 W, g/ [! M        }
1 S+ c$ C8 w+ A* w}
# |  b9 p& Y- O" u# C4 t3 e9 @4 D3 ^: N6 [) o  T
void        APU::WriteExProcess( WORD addr, BYTE data )7 Y, K/ R$ J& I6 o
{* M8 p1 C& ]+ b) u4 e) E6 V9 r
        if( exsound_select & 0x01 ) {
3 k4 J% |! e8 K' X. G& c                vrc6.Write( addr, data );
2 m( W5 m1 n" P: Y        }
& ~( K' e" B, S2 [) {        if( exsound_select & 0x02 ) {
5 w! i% a* ~  s5 t, i9 o                vrc7.Write( addr, data );4 G9 o$ e+ W$ E, C6 }' h3 b
        }
% T! ~% Q* G' T5 f        if( exsound_select & 0x04 ) {
. E' Y1 S- g6 b/ _' ~: R9 \" |                fds.Write( addr, data );
2 }# D/ n& f6 L        }
9 M, E* K/ N" n        if( exsound_select & 0x08 ) {; P- f. F6 ]: Y( z* m& V" d( e
                mmc5.Write( addr, data );2 x0 ~7 L2 Z: q
        }% J! ]! S/ s4 k$ t! Z- p$ _
        if( exsound_select & 0x10 ) {# O& O. O' C1 w: e( H
                if( addr == 0x0000 ) {; \* \, j5 p6 i6 {% X. R
                        BYTE        dummy = n106.Read( addr );1 N$ e: }0 i, @8 Y7 s
                } else {
0 F& u2 [# I2 ]' ~9 f- H                        n106.Write( addr, data );$ v: o7 O# U0 k& l+ Z
                }
5 R' g6 ?9 o! i" ^/ i" r        }! H& v6 o( `8 a/ I$ i2 v
        if( exsound_select & 0x20 ) {
$ }( R  d( e3 k                fme7.Write( addr, data );( x. r$ @. G1 t1 M) J( B
        }6 W6 J; _6 c: w9 h7 _2 }: L& y: a
}  s, k2 K+ y& |* K% n# K; Z
' M, O% U' G7 ?' j
void        APU::Process( LPBYTE lpBuffer, DWORD dwSize )" G" \$ f! o. z; E; G
{* d3 H0 C. N' e" s7 n  e' Z& D7 ~
INT        nBits = Config.sound.nBits;
# S+ ^( E0 b+ O! EDWORD        dwLength = dwSize / (nBits/8);% L: Q  n' W1 h: J# ]6 k
INT        output;
( J' n+ B$ ?, _4 AQUEUEDATA q;
8 J8 a; R7 E3 L# m7 XDWORD        writetime;1 ^5 n# ]3 s6 r) j
/ M% r* S  J1 t
LPSHORT        pSoundBuf = m_SoundBuffer;5 h6 g" @+ k! e# y8 l& o! m
INT        nCcount = 0;
  F) C% N. d) O0 l" q; P7 p  r
/ b9 {( d, J/ Y% U% D7 U1 M9 KINT        nFilterType = Config.sound.nFilterType;
: @! `6 P3 }) ^) h# O
+ x6 x, y! G' ^/ R5 z) n9 D        if( !Config.sound.bEnable ) {
  O7 z& U4 M7 q9 V$ U7 Y" Z1 j+ I                ::FillMemory( lpBuffer, dwSize, (BYTE)(Config.sound.nRate==8?128:0) );
+ }# k0 ]8 E, \4 f% P; y) @* `                return;
% n4 v, g1 f. M7 v$ o: C        }  R8 c6 m0 a) |1 a9 v

8 U' }% ?) i2 \0 p9 ?        // Volume setup
7 T! P$ V$ U) R% M5 k4 y) s        //  0:Master* q" X; e  u# N" B
        //  1:Rectangle 1: o/ p2 C" v3 W' Q
        //  2:Rectangle 2
6 s2 a$ `' s% g) A        //  3:Triangle
/ M, V5 C" U8 u$ V, u2 w        //  4:Noise; J8 G- C/ f* h( j+ @
        //  5:DPCM* Q0 [) u/ S4 f- _  U/ }4 X/ c
        //  6:VRC6
8 e3 F7 V' @$ f* |3 D% G        //  7:VRC7
. I; Z5 `7 g  x; ^/ ]        //  8:FDS
7 }8 n2 U) U- [1 @        //  9:MMC5
, u: ]- N% `" _* Z; c        // 10:N106
) t. Q/ Y$ g# J4 y4 [- w        // 11:FME7- C4 ^, {  A' r' N
        INT        vol[24];
$ V! v1 C8 l$ P0 Q3 O% d7 A" h        BOOL*        bMute = m_bMute;# C" ]1 r" z3 w: W5 W' \
        SHORT*        nVolume = Config.sound.nVolume;
! u, B) ~) c- p. r2 ~6 [6 Q
% {* `* }7 Q# L! G  L        INT        nMasterVolume = bMute[0]?nVolume[0]:0;
5 c% S+ z1 t3 `$ P$ ^- P$ ^/ \8 d" l* [
        // Internal
0 ]; G1 O1 s* Q* C        vol[ 0] = bMute[1]?(RECTANGLE_VOL*nVolume[1]*nMasterVolume)/(100*100):0;
9 @5 t5 z# h' W2 c$ b3 g8 m( r6 r( l        vol[ 1] = bMute[2]?(RECTANGLE_VOL*nVolume[2]*nMasterVolume)/(100*100):0;/ s0 N: \$ G, {, l- f
        vol[ 2] = bMute[3]?(TRIANGLE_VOL *nVolume[3]*nMasterVolume)/(100*100):0;. H% z# y" D* C8 i1 o
        vol[ 3] = bMute[4]?(NOISE_VOL    *nVolume[4]*nMasterVolume)/(100*100):0;# d4 y+ _2 {- `" x# M
        vol[ 4] = bMute[5]?(DPCM_VOL     *nVolume[5]*nMasterVolume)/(100*100):0;
4 A$ I9 r- `# X# A, e
5 Y! ]! v, |6 c% ]7 i1 w        // VRC6
0 R& `9 D( i5 n9 V        vol[ 5] = bMute[6]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;1 y/ Y# p: o  p5 ^
        vol[ 6] = bMute[7]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
/ O0 S8 t! ~; n9 L: f) a/ G/ P( A        vol[ 7] = bMute[8]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;$ \4 B& O# M0 q
4 \* F$ a& ^- }5 M
        // VRC73 z# d5 j" R) h$ e& k  W4 Z  m
        vol[ 8] = bMute[6]?(VRC7_VOL*nVolume[7]*nMasterVolume)/(100*100):0;+ n1 B3 J7 K, a7 p) f& G7 F
  c* C/ L" k5 Z
        // FDS
# {. N9 I. c; \9 Y" m1 {        vol[ 9] = bMute[6]?(FDS_VOL*nVolume[8]*nMasterVolume)/(100*100):0;
# `% v% ~/ O+ b4 }8 v, M& L# ^; L( W8 u/ k' c
        // MMC5
7 A4 w) }1 A! r        vol[10] = bMute[6]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;0 t, S) W9 J6 L( J
        vol[11] = bMute[7]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
: ?/ O! H3 u4 Z1 d9 f6 m7 s        vol[12] = bMute[8]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;4 f) E5 A& H2 B7 L
. J- \6 |/ q7 A# g: |! D% s$ z
        // N106$ R3 H; R. i% f/ \. u) _; ]
        vol[13] = bMute[ 6]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
' G- P: _0 ]2 m+ y5 C, m        vol[14] = bMute[ 7]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
. }  c" g" D' l+ Y5 h5 Y        vol[15] = bMute[ 8]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
: j. V0 |' E- C. ^0 X* c        vol[16] = bMute[ 9]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
" u/ ^. w' H0 u( @8 f! k! H        vol[17] = bMute[10]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;- e! c8 [0 k& y( q3 X' U3 ?. u
        vol[18] = bMute[11]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;/ W: q8 r0 Y. S% J1 e/ q: E' q  T
        vol[19] = bMute[12]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
% {2 N. W: l# p3 a8 ~; F3 v        vol[20] = bMute[13]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;5 V7 f% U% ^. }0 B- t, Z8 m3 ~

1 _& q1 J# A: \+ O4 T& J        // FME7
3 l1 s8 \% X6 F7 K% k        vol[21] = bMute[6]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
" Y" B4 w- A: P! I/ {        vol[22] = bMute[7]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
  P. ~$ v# m. L# E  L4 X; o        vol[23] = bMute[8]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;6 X" m$ Y; |9 P8 A1 U: R( ^3 B- R

2 y9 w1 h4 b% Z$ {( c//        double        cycle_rate = ((double)FRAME_CYCLES*60.0/12.0)/(double)Config.sound.nRate;
; B) |( r/ S9 T& T- S$ u        double        cycle_rate = ((double)nes->nescfg->FrameCycles*60.0/12.0)/(double)Config.sound.nRate;
/ D' E1 [8 ~- w4 I7 e* A. _, N5 {$ h
        // CPU僒僀僋儖悢偑儖乕僾偟偰偟傑偭偨帪偺懳嶔張棟
5 x& N# D2 l# t# k' D3 P+ O2 e        if( elapsed_time > nes->cpu->GetTotalCycles() ) {
! Q& z, e/ ?( {8 h                QueueFlush();
/ g9 a+ Y, A: z7 E( ]7 i        }# I7 K) b' A* t2 p9 y- d3 E

8 K& r) M8 r5 p9 `* l* x        while( dwLength-- ) {
; _$ B9 e) H- j8 l2 _& y, B                writetime = (DWORD)elapsed_time;
* ]; x, C3 l  U9 j, F8 k0 ]5 W8 d/ o
                while( GetQueue( writetime, q ) ) {1 n1 s4 K/ Y2 ^. T; J$ g+ }, W
                        WriteProcess( q.addr, q.data );7 d* K9 i9 J6 v! P& q
                }
, }  V+ V9 W4 T  u- a. O! C- B0 ]. I1 v; B$ `$ T) D
                while( GetExQueue( writetime, q ) ) {
; r: o6 A, M  a                        WriteExProcess( q.addr, q.data );: S  d. @6 z1 E2 r; J
                }6 C6 O2 @' b) N! H6 o- L5 f
! K6 B5 t& I# y6 e+ O' p9 v8 S( d
                // 0-4:internal 5-7:VRC6 8:VRC7 9:FDS 10-12:MMC5 13-20:N106 21-23:FME7* Q! J; `8 C7 M9 @7 R& y
                output = 0;
: ^. D  h. p3 \& a                output += internal.Process( 0 )*vol[0];7 F- _- V1 S  T
                output += internal.Process( 1 )*vol[1];% H8 H4 O4 @1 D" D2 ]9 J6 \
                output += internal.Process( 2 )*vol[2];
4 p) N  M9 v- U( M2 k8 ]( @                output += internal.Process( 3 )*vol[3];6 R4 U; w  f1 C5 |
                output += internal.Process( 4 )*vol[4];
' m8 t9 \( _, Z/ z9 ~- u- K4 }0 O; ?. B- x& |& `3 V( v# {
                if( exsound_select & 0x01 ) {- [- V; T# F) U- S
                        output += vrc6.Process( 0 )*vol[5];" b6 j% I! s! g
                        output += vrc6.Process( 1 )*vol[6];
% e) ]  E" F4 m4 T! ]1 R                        output += vrc6.Process( 2 )*vol[7];( |5 C1 ]. t/ [* N3 A3 q! B$ c
                }' n, _( h$ S! ]) z  O' @; |' \
                if( exsound_select & 0x02 ) {, |. Z6 g. i, R
                        output += vrc7.Process( 0 )*vol[8];
  w7 z8 X$ |" r, q" a$ ?                }6 ^' H* y( g* |6 J# T$ x
                if( exsound_select & 0x04 ) {
! ~9 {7 P& Q7 l( M6 `& g                        output += fds.Process( 0 )*vol[9];0 Y  a% I' v5 S' B$ S9 J. }
                }- D3 Y' q4 k1 ]6 _9 T
                if( exsound_select & 0x08 ) {
* n- E. i9 _- c                        output += mmc5.Process( 0 )*vol[10];
5 S: `( m4 h5 G0 M+ K0 y3 `5 d, A3 x3 m                        output += mmc5.Process( 1 )*vol[11];! D: Y5 m, ]" n7 y, `: ?9 L
                        output += mmc5.Process( 2 )*vol[12];
0 j* A, ^+ o' g1 Y2 C# |  L                }! G- e3 @( g) Q9 d. g4 Z5 p' d
                if( exsound_select & 0x10 ) {( F! p6 X& T9 [+ b1 h0 e
                        output += n106.Process( 0 )*vol[13];9 g  j# Z+ Z8 C* E( B+ Y& t4 c
                        output += n106.Process( 1 )*vol[14];
; o' G: Y! u. |" S9 j                        output += n106.Process( 2 )*vol[15];2 B% ~$ V1 ^2 ?& a' P
                        output += n106.Process( 3 )*vol[16];+ G/ h2 ~- o0 w$ m8 i% q
                        output += n106.Process( 4 )*vol[17];8 A  r# R3 q. N( T# _# n
                        output += n106.Process( 5 )*vol[18];
1 ~9 h% ~+ A# e. t0 T$ |  |3 o                        output += n106.Process( 6 )*vol[19];; D9 x/ \* G  K& b
                        output += n106.Process( 7 )*vol[20];) `) U  A0 e# w' c/ _0 h: w  @
                }
: |5 N- M$ s+ R& n9 n                if( exsound_select & 0x20 ) {( T* C6 |1 n% g, U
                        fme7.Process( 3 );        // Envelope & Noise- @* u" r! R) R2 I3 f, G
                        output += fme7.Process( 0 )*vol[21];
3 X2 p5 c$ |# |5 b0 z# d) J                        output += fme7.Process( 1 )*vol[22];
. \# ~2 |, Q' x                        output += fme7.Process( 2 )*vol[23];/ s/ D% r6 L" m
                }
& ~4 i5 Y! r0 _* W$ U! Y# ]) l0 T( Q7 {$ K2 k! C
                output >>= 8;8 b# C* h$ l, K! L; `/ Z; m7 {: E6 N, ]

. n. Q+ B8 ]- A; d( m( r& H                if( nFilterType == 1 ) {' s' m: f) E9 R; Z: w0 z
                        //儘乕僷僗僼傿儖僞乕TYPE 1(Simple)
9 ^) H, l0 a/ j3 s3 C) A                        output = (lowpass_filter[0]+output)/2;! Q& p  D  z& f1 M! k
                        lowpass_filter[0] = output;# l0 W& d2 C& G0 J
                } else if( nFilterType == 2 ) {- g! t  I/ w4 \: ~/ `0 m* r
                        //儘乕僷僗僼傿儖僞乕TYPE 2(Weighted type 1), y* y2 l& h% p" p3 ?
                        output = (lowpass_filter[1]+lowpass_filter[0]+output)/3;
5 ?! p( U5 w" e' w+ s                        lowpass_filter[1] = lowpass_filter[0];
2 E: Z4 g9 k" A# X4 t* W                        lowpass_filter[0] = output;
+ Q/ m7 n# P0 v: m; Q) Q# D# ~                } else if( nFilterType == 3 ) {
! e$ f) c4 W- J$ \8 i; v" d                        //儘乕僷僗僼傿儖僞乕TYPE 3(Weighted type 2)- }: ]4 K/ P. F
                        output = (lowpass_filter[2]+lowpass_filter[1]+lowpass_filter[0]+output)/4;8 g6 c2 j1 w& t) ~7 F6 H; p7 W
                        lowpass_filter[2] = lowpass_filter[1];
  M/ W6 O6 e) I* {                        lowpass_filter[1] = lowpass_filter[0];
8 J- d/ y) `1 a4 U  l6 [7 F                        lowpass_filter[0] = output;
) ?+ V9 V+ Z2 w$ I" k- C                } else if( nFilterType == 4 ) {
0 ^2 A6 T4 |' C- A7 E# g                        //儘乕僷僗僼傿儖僞乕TYPE 4(Weighted type 3)! y4 Z( v9 ^* @- d
                        output = (lowpass_filter[1]+lowpass_filter[0]*2+output)/4;
# n1 E$ e9 N* i1 ?7 p                        lowpass_filter[1] = lowpass_filter[0];: Z, W4 h1 `( X
                        lowpass_filter[0] = output;
. z$ T! _0 P) t6 `2 T) K& h' t                }
5 G: G8 J$ W" {; f+ e3 l4 @4 N: e. V+ D8 n7 }# n! a
#if        0) u6 Q& y; J5 }5 g* w
                // DC惉暘偺僇僢僩
" G' w0 {: v3 `3 Y                {
; p' V% Y* w' O- F" s1 a  Z8 ^                static double ave = 0.0, max=0.0, min=0.0;" i1 b5 N. N& c' v8 r& e
                double delta;' U5 g1 O, B! b$ Z
                delta = (max-min)/32768.0;1 a* Y- j' f, {2 M; _3 \3 r
                max -= delta;
4 U6 F) \0 c' {                min += delta;
8 g$ X8 U4 X; F( b" q                if( output > max ) max = output;
: s2 d: h9 E# y+ K$ _  ?                if( output < min ) min = output;
/ x' G8 f4 `" G, o/ a3 v                ave -= ave/1024.0;! m2 \2 J7 {( \* p) z
                ave += (max+min)/2048.0;  Q8 p1 Q6 }. u# `3 F# O. ?
                output -= (INT)ave;
# _5 r8 g, J" `+ h' d                }
/ Q: K' y. ?# M+ R* e2 c#endif
; S2 ^2 x0 R/ z- I) f#if        1
5 z6 q% F6 ]0 r8 ?% D                // DC惉暘偺僇僢僩(HPF TEST)9 m, R" Q# b. O5 s) y7 ~0 d# p: R
                {! U' R7 d! g* I' c$ a3 ?
//                static        double        cutoff = (2.0*3.141592653579*40.0/44100.0);
& d; Z; a$ Q. a) G2 _( F                static        double        cutofftemp = (2.0*3.141592653579*40.0);
  @$ L, o- p: A# }                double        cutoff = cutofftemp/(double)Config.sound.nRate;
% s3 t' d" t; r# y3 ~: a" K                static        double        tmp = 0.0;  A5 d& h9 n- Q
                double        in, out;
- Y$ ~! m8 O7 ?$ M3 ?0 U* o( L! o( s' ]+ j. o2 e
                in = (double)output;
- H' W. g8 [# T                out = (in - tmp);; Z* C$ T. A6 _' q, K
                tmp = tmp + cutoff * out;  F2 H6 H6 b! W' w# U% g6 g9 U
* u/ Z( W) m) Y9 K8 \; ]7 b
                output = (INT)out;- d6 }& g; M& |( N
                }
1 n0 V6 u+ _4 S3 F, t# Q2 E#endif' G  L  j0 I0 g: z
#if        0; D& `8 R( F0 O& U4 T
                // 僗僷僀僋僲僀僘偺彍嫀(AGC TEST)
5 i+ @8 m2 k# e8 ~* X                {
$ `' r* l* d, f- J5 O9 b4 a                INT        diff = abs(output-last_data);
. M4 X3 q" U* V$ L) m$ e1 q. b) I                if( diff > 0x4000 ) {6 G" }1 n7 J/ b! q
                        output /= 4;% d) `5 M4 _" F8 y6 b" @
                } else / n  i2 V. T$ s) {+ I
                if( diff > 0x3000 ) {
2 w! }- x2 _! P8 H7 l; K% n                        output /= 3;
' D3 U$ \) C7 n3 C) D( |                } else/ T, u3 U! y4 e7 h5 Q/ s
                if( diff > 0x2000 ) {
# {4 _/ l, O% n                        output /= 2;1 @6 J/ h  Q9 z9 D; K% T' ^
                }5 X% H1 [" _5 m
                last_data = output;
6 X  c' u; S6 W- {* g# e" u& t                }8 c( a% n- c6 S* U+ \- v
#endif7 g* x2 O0 |6 Q1 Z0 j& |: i6 J
                // Limit
% G0 G2 |6 f4 E7 R, k" Z                if( output > 0x7FFF ) {& B% q/ f. j8 d+ N& ^8 u- n" @* p
                        output = 0x7FFF;' ]* j: n) r5 X' D; s
                } else if( output < -0x8000 ) {
3 q+ \* o. v& j& J  T1 X& [( ~9 {- }                        output = -0x8000;
, N5 L/ A, D' O0 c  `4 F8 E" U                }9 l8 v8 S9 O0 W4 N* T7 P

$ j- B/ \6 S* ]8 T                if( nBits != 8 ) {+ W2 U6 C/ Y- \- [8 f* J9 @
                        *(SHORT*)lpBuffer = (SHORT)output;  c" F2 C. j+ a! t, x5 P4 M# d
                        lpBuffer += sizeof(SHORT);
0 H( r% w) l( o, c                } else {
; g+ t1 m1 f$ p. x/ j                        *lpBuffer++ = (output>>8)^0x80;
6 k8 Q( b; Z4 L, N                }
5 D& D7 F( B; T' ^- X3 Z) B: k! ]6 {5 {3 J9 ]) l
                if( nCcount < 0x0100 )8 Q/ c) V8 Q( E5 {+ [) }* _
                        pSoundBuf[nCcount++] = (SHORT)output;
1 L, D0 V" |. U6 L1 w- ~+ ~" d' Q& i: e6 S, b4 h' F( T
//                elapsedtime += cycle_rate;, \0 W: E0 x' K* S
                elapsed_time += cycle_rate;
2 m+ K  z- v& d3 w0 Y        }
4 i& i5 O  C" I. I( O$ |7 I) i0 `9 |9 v$ X6 p7 J7 ?$ ]
#if        1
9 v* u0 m$ w8 O0 C7 u' l+ w5 p; \        if( elapsed_time > ((nes->nescfg->FrameCycles/24)+nes->cpu->GetTotalCycles()) ) {
- \2 i+ y, q. ?  e* Y  |+ G                elapsed_time = nes->cpu->GetTotalCycles();! W8 W& o6 a1 x. T' r' M
        }
/ V1 _9 V$ [7 V7 g6 q+ U        if( (elapsed_time+(nes->nescfg->FrameCycles/6)) < nes->cpu->GetTotalCycles() ) {
3 _  N  {1 L( t2 x; V% `  w                elapsed_time = nes->cpu->GetTotalCycles();
$ f3 O# q: c% S- K* l        }
: `$ L6 ]- S) E/ g# `) }0 t* i+ O#else. z+ g* A1 ]& g; K5 u' v+ K: r! B
        elapsed_time = nes->cpu->GetTotalCycles();
6 J# z* U. N7 r8 e9 B! Z#endif9 r* a4 w6 g! C9 J" W" R6 E. r- Q
}
; p8 W' Y: j5 k/ V% v, E
; k6 S8 l4 D4 e& `$ O// 僠儍儞僱儖偺廃攇悢庢摼僒僽儖乕僠儞(NSF梡)
# A. n9 K+ I. qINT        APU::GetChannelFrequency( INT no )
' U6 {% s" e& u{
2 ]0 [& |( N1 O7 Y0 m0 d/ h1 y4 c        if( !m_bMute[0] )
4 t3 M" ?& G% B" G! I9 W% X                return        0;1 r. A3 |1 C4 e! t5 I  }

, k2 d7 D3 g4 L# M$ r/ F        // Internal3 B& p' U2 K, T7 C2 B  f
        if( no < 5 ) {
' _" N- Y3 ^* Z+ X# J                return        m_bMute[no+1]?internal.GetFreq( no ):0;8 h8 m1 J1 R* y0 K! c7 d2 A
        }, l2 l3 F. T+ z' F' C
        // VRC65 e; T0 X! B" i  f  F0 u0 n* e
        if( (exsound_select & 0x01) && no >= 0x0100 && no < 0x0103 ) {% O6 G% P% V9 g: m& u. a, h
                return        m_bMute[6+(no&0x03)]?vrc6.GetFreq( no & 0x03 ):0;( z$ P+ i- z7 ?' J+ Q
        }
' t5 A9 U+ J: [+ |4 i0 q  G, H8 [        // FDS' k: r$ g* C2 q$ o! `
        if( (exsound_select & 0x04) && no == 0x300 ) {
# @3 _, R3 Q- k! R8 ?7 a# Q                return        m_bMute[6]?fds.GetFreq( 0 ):0;2 M% e& G3 w* [5 U& ]- r
        }
' ?, M" T% O* F+ U; |2 |        // MMC51 P0 K+ Q/ G3 Z/ k3 |
        if( (exsound_select & 0x08) && no >= 0x0400 && no < 0x0402 ) {- d: w* ~& q$ K  ~/ x
                return        m_bMute[6+(no&0x03)]?mmc5.GetFreq( no & 0x03 ):0;
: q7 a- h% e) B4 {        }
% I1 I, e# f% T7 O+ Y        // N106
$ y9 \  I+ D* O$ Y8 b        if( (exsound_select & 0x10) && no >= 0x0500 && no < 0x0508 ) {
5 t4 E" c4 F8 e8 C                return        m_bMute[6+(no&0x07)]?n106.GetFreq( no & 0x07 ):0;$ v$ z2 J8 x0 R" P0 B
        }
1 w. x  [2 h/ p$ W8 z' m. ^- t5 p        // FME7& Z' [4 U& f' g) M
        if( (exsound_select & 0x20) && no >= 0x0600 && no < 0x0603 ) {0 E7 h6 {. e1 G: ~' d/ I* g; h( X
                return        m_bMute[6+(no&0x03)]?fme7.GetFreq( no & 0x03 ):0;1 X- ]: |9 g# g0 M+ D; J, U6 i7 x' V  R
        }
% b! |# ]. M8 U. C* ~        // VRC7! `5 ]: ]! h( |* _
        if( (exsound_select & 0x02) && no >= 0x0700 && no < 0x0709 ) {3 G5 Y/ @; m6 t
                return        m_bMute[6]?vrc7.GetFreq(no&0x0F):0;- G  A! A$ T: L& n- D% Z' L! i
        }
) M# `: C$ m0 H5 \* n& i        return        0;
8 n( f5 _( @! ~}
8 B! ]+ i! D/ k' P1 m) F' A0 U& q, o6 M  O  l; I2 J6 u
// State Save/Load
' N! w; e4 l/ p; f( d9 }void        APU::SaveState( LPBYTE p )
+ I+ I/ h8 Q) i; ?1 y{5 y+ a) o: t6 ]; g+ N% P
#ifdef        _DEBUG
1 ]+ |$ K/ }* pLPBYTE        pold = p;+ d: F  g; u! V# f* {: _' E) n
#endif
  n9 ^4 T6 C: E' W) K  O' l( A/ N: ?7 k5 @4 i; l# J4 r; V
        // 帪娫幉傪摨婜偝偣傞堊Flush偡傞
" w; `: O) V, r) ^  s' p6 _% b/ k        QueueFlush();
9 u! I4 W$ J* K" K' S) D$ R0 R; f
        internal.SaveState( p );! n% K" }& C0 m4 o  |
        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding
, T# N9 {! U' C4 ?% m$ ^+ S
" b# |% h/ i; D1 s5 O        // VRC6
" P# k2 Q7 j9 W. I4 {        if( exsound_select & 0x01 ) {
4 {) {/ f8 J% y/ z4 O                vrc6.SaveState( p );( U, [7 W8 S1 {/ c" J+ }% o: B
                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding/ B; Z- d( `) a9 x, R; A# C
        }
) O& i0 n+ V6 Q% T6 x3 G/ y        // VRC7 (not support)0 K1 G# s8 I% q
        if( exsound_select & 0x02 ) {
$ p" x% c6 l! O' `+ w* _( c" S                vrc7.SaveState( p );9 t  b" V- A3 p4 h0 r) }2 U
                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding1 K: N. {0 y- _- `( E8 P: b) B3 U
        }* X5 q2 Q/ H. I9 a* w
        // FDS
" q7 X; h$ q8 g( R        if( exsound_select & 0x04 ) {
) z7 \6 i9 B0 Z/ ]                fds.SaveState( p );
! T7 N1 j* m! Z+ P4 x                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding( `& y/ }3 {, a" J
        }
* h8 N6 G2 d5 l; O, v        // MMC5
- M2 d9 O: e" J" {        if( exsound_select & 0x08 ) {/ n/ z5 @# |% R& v  _: j) y
                mmc5.SaveState( p );" T2 O- `6 M9 v) D  h" y# }
                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding
) s7 O8 F$ _6 O) c  ]        }
1 {% P1 ]. p: [7 {3 ?        // N106. a# |* F1 c4 l  E7 J
        if( exsound_select & 0x10 ) {4 x# G, s* @1 c$ K; d
                n106.SaveState( p );4 p+ e+ G. I8 D5 E4 _+ X2 V
                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding) T) z. D/ c) T6 \* w3 {* z; |
        }
1 M) O' t% N1 b- z8 g        // FME7
- _1 W: `  ]; {+ ^6 v( }0 D        if( exsound_select & 0x20 ) {
- {1 r' |' c7 B, w  y9 }                fme7.SaveState( p );
$ o7 ?7 d) u- [5 N! e                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding2 A+ [* D7 ^' X! \3 E
        }$ Y* y( Z, R- z1 d+ n' H6 h0 e) J
$ L$ Z' i4 }/ Y2 O
#ifdef        _DEBUG
* b7 V. G- w% Z9 r8 ?- X( XDEBUGOUT( "SAVE APU SIZE:%d\n", p-pold );
( F7 U; U) H. ?6 W, g& v#endif
; y7 y: O! o& D& R, \" \/ V}5 C! V/ U) U1 L1 U- j) w
( k( r& l* _. e
void        APU::LoadState( LPBYTE p ); w. P& r8 X- A
{
+ X$ ?. X0 K' k0 N1 K. e# K) T        // 帪娫幉傪摨婜偝偣傞堊偵徚偡
$ Z5 `: c5 Z6 a& v) S: ]        QueueClear();, J2 z6 H- l$ S! _( h

, ~3 [/ B4 n/ {  {& x7 c        internal.LoadState( p );) q( U1 [2 j3 n( i
        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding$ l  |) C2 ~8 T+ G6 L# t

9 I+ o* c) S; W8 u4 E        // VRC6
. m1 c% P; |% y        if( exsound_select & 0x01 ) {6 v6 w8 h# J4 _$ n
                vrc6.LoadState( p );/ u7 o: n" P) f# h. C0 d
                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding
1 k7 e/ b& |7 N) R6 M0 r& q; |3 ]        }
5 y9 m. H' _" \5 F        // VRC7 (not support)5 n+ C8 _- O8 x
        if( exsound_select & 0x02 ) {5 y8 I( t1 B* @
                vrc7.LoadState( p );2 c" i" `" M, w' w& x/ _2 }7 s2 s
                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding
0 q4 r. {3 ]4 X  h        }
9 a7 o$ T& x2 W8 [" A        // FDS
2 F. J6 m* ], C        if( exsound_select & 0x04 ) {" t( o( q! a1 M0 S2 h7 ~! f0 U
                fds.LoadState( p );
! x) s1 w8 y9 v4 c( ~                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding, i7 T' M3 x1 g1 }; y
        }- v! m  i/ O9 {! f4 m
        // MMC5; N# \; H. \& {. n' H5 ?
        if( exsound_select & 0x08 ) {
/ T2 G  ?6 _* k8 u( S3 ~0 T                mmc5.LoadState( p );
3 ^! h0 y9 v% `8 b' C6 i) i4 b                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding5 d( B- k. w4 `- i! [2 A
        }
8 u" x$ }8 E0 a  ~# G7 j$ H0 {        // N1064 o) v. c9 x. S* z% y7 `9 t7 o7 ]
        if( exsound_select & 0x10 ) {; Y# F" i; K9 Q" b) a
                n106.LoadState( p );
  r: n# H# f& X% J0 m7 o5 h" E5 z$ g                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding7 v5 e. y/ y/ A2 H
        }$ p+ ?% J# K/ U  B- q7 s& c7 A
        // FME7
' r8 |  O# Y$ |# f. D1 V        if( exsound_select & 0x20 ) {/ e8 T3 o  K! Y8 m) u
                fme7.LoadState( p );
" W& {& B# h) m9 \  S                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding# a7 G5 z4 {) }, b/ m% V8 [5 d
        }
2 ]0 z2 ]- @' ]5 L7 ?}

该用户从未签到

发表于 2009-11-8 17:25:37 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 14:38 发表 ' g$ Q$ S3 C. o, t. `- ^/ v
可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。9 ^3 M, \! }1 a. I
感激不尽~~
4 A- x" L4 P5 F9 U
恩 我對模擬器不是很有研究,+ c8 w3 D( S- L: S
雖然要了解源碼內容,可能不是很困難,
0 R' B8 Z/ M4 n( I9 f不過還是要花時間,個人目前蠻忙碌的。
9 e) s( _  @  f$ G$ `) Y0 _2 H4 f3 h- X3 j
給你一個朋友的MSN,你可以跟他討論看看,
. c2 x: {! ^5 b他本身是程式設計師,也對FC模擬器很有興趣。
! y3 d/ p7 L' `5 T0 r, Y
$ t- y* X8 K4 R1 v8 }+ Z! j1 jMSN我就PM到你的信箱了。! g; w, \0 d5 j; R5 J' C; p+ m
9 B) v2 s) X; O6 v3 z5 c2 ^% w+ r
希望你能有所得。

该用户从未签到

 楼主| 发表于 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 发表
0 W. W+ c5 M0 T呵…… 谢过团长大人~~

3 T7 a2 V% S  U6 n: U: R, M, z0 w5 Z: `* e
哈 不客氣,算是順便幫他找個伴,大家可以一起玩。

该用户从未签到

发表于 2009-11-20 13:14:53 | 显示全部楼层
原帖由 李伟 于 2009-11-9 16:02 发表   @* y' P# I3 b5 o5 [
团长的朋友都是神,那团长就是神的boss。
, X! i- X5 q1 `& f% O! k+ V3 y
哈 不敢當,我只是個平凡人,
# O% r  X) ~. A* @9 M要吃飯喝水,光吸空氣是不會飽的。。。。 :)

该用户从未签到

发表于 2009-11-20 13:32:35 | 显示全部楼层
FC模拟器的部分有个人可以帮你忙0 A. Z1 K* l" }6 G9 ^. }  K9 I" ]
ZYH
/ @) p& X/ A+ T" QQQ:414734306" z2 S8 s/ `% M9 \5 b7 D' p' l! x. _
Mail:zyh-01@126.com
) i( D( ]$ G6 b
" e; M2 O5 J, w/ Y% H) V; G, v& c* s他是ZYH Emulator这个模拟器的作者,只是他用的开发平台是VB,不过就6502的实现原理来说是一样的

该用户从未签到

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

该用户从未签到

发表于 2009-11-27 19:09:06 | 显示全部楼层
原帖由 独孤残云 于 2009-11-27 09:48 发表
; h* h- ^  [; W9 g4 Q再次对团长大人和悠悠哥的无私帮助表示感谢~~

1 \9 T  ?8 r0 I# b不客氣  ^_^
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2024-9-25 18:23 , Processed in 1.088867 second(s), 19 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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