EMU618社区

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

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

 关闭 [复制链接]

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 09:56:34 | 显示全部楼层
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。
- C) H5 q* N/ X  v楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~
+ B$ K+ v4 K( c7 o! |这里有相应的模拟器源码,就当送给大侠了~~
: n" o3 G4 q/ E: |' C( Ohttp://kenkao.qupan.com/5096520.html

该用户从未签到

发表于 2009-11-8 11:31:10 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 09:56 发表
- ]  i( u9 j( x- }2 }! P能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。& C& j; v- _; v' E0 v0 b. K1 W
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~
0 U' d- F4 v; T! f这里有相应的模拟器源码,就当送给大侠 ...
% C3 w  `* I% A9 w7 E( n
聲音部分(Audoi Process Unit = APU):
$ i0 h8 X$ F% P5 V% v2 h: i. @/ H.\NES\APU.cpp
- u: ?; |) {& [' Y$ r1 M; b.\NES\APU.h" k- _! Q4 J; ^. d

, c1 Z" }& ?( t5 B& S  G+ [. `3 _/ \7 P4 O. w
影像處理部份(Picture Processing Unit = PPU):
6 g' Y7 ]) |& _& S& m/ ~7 ]4 y.\NES\PPU.cpp
( ^+ G$ S2 M9 f; E.\NES\PPU.h
3 _. m4 p3 {( T; \! B' A
# A0 F9 ~& q/ p7 t如果原碼用C跟ASM混搭也不錯

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 14:47:50 | 显示全部楼层
这是我手中源码Apu.cpp的内容,敬请赐教:- e( D: @5 {, w5 q, X6 D
(由于很多专用术语和算法机理都不明白,所以看不大懂……)
3 ?6 @+ Q3 J  r+ p//////////////////////////////////////////////////////////////////////////
) b) x0 }6 u0 n6 j) _. W7 h//                                                                      //7 C8 p# Q3 A% }8 I8 t# j
//      NES APU core                                                    //+ O/ h; O3 ~6 D6 B$ A+ q6 F
//                                                           Norix      //$ r) M1 w1 T$ P1 t4 V8 O
//                                               written     2002/06/27 //5 R: {6 D, r: q9 t7 w
//                                               last modify ----/--/-- //8 |( R3 c- N" a2 c9 F
//////////////////////////////////////////////////////////////////////////
' |# \9 ]6 n$ c- T( P5 D#include "DebugOut.h"
; C; T3 D( l! X4 g1 q  H#include "App.h"
5 n' D+ t* g& Q* b#include "Config.h"3 s0 V4 Y6 f# O% k/ Q# k! `

; u9 V( @2 o5 }  b: u/ \8 B#include "nes.h"
2 _6 p! v7 J# e8 ~5 `( e#include "mmu.h"
+ [2 l7 B' a' e% j# K4 K#include "cpu.h", u8 b$ @+ g; i
#include "ppu.h"
4 c0 y- {0 e. x: B/ u! q- f#include "rom.h"
1 C& N$ t) e" E4 t, r' ^#include "apu.h"* U' Z7 {8 ]* D9 J
' \0 y6 ]1 c$ R
// Volume adjust
# M2 s$ ]- L  f. X; Q  ?" F! j// Internal sounds
( v2 g! M* E+ X  |5 S  S* Q#define        RECTANGLE_VOL        (0x0F0)+ a; m. [# [* N* j
#define        TRIANGLE_VOL        (0x130)  c. |& a' z8 {1 h; F3 ?
#define        NOISE_VOL        (0x0C0)* C* y" [- ~: f% ~. x* e
#define        DPCM_VOL        (0x0F0)" G0 D2 u4 ?; e& H, `/ }1 Z1 `. a2 }
// Extra sounds
* F' g$ N# o- P' J2 o#define        VRC6_VOL        (0x0F0)
; a7 E8 j# M  T( X/ H#define        VRC7_VOL        (0x130)
, {$ \, M6 `: c+ z#define        FDS_VOL                (0x0F0)
3 m5 n( Y. X  q' X$ s#define        MMC5_VOL        (0x0F0)) n; }8 U) o& |& o
#define        N106_VOL        (0x088)4 Y" ?! T- }  L
#define        FME7_VOL        (0x130)  {( ]/ P+ y! l" f! l: s

% y! N. F# }7 G! n: }APU::APU( NES* parent )) F6 a1 P3 x9 \  F6 @3 G
{* T# b) ]( y8 B
        exsound_select = 0;1 u( T3 I) a+ y
/ @! j3 |' K2 o5 D" O- Y* P: N
        nes = parent;5 o) R; D& A- h$ v& j
        internal.SetParent( parent );4 E$ ^) |0 j0 s3 ^2 O
2 B( i6 u( b9 ]9 i
        last_data = last_diff = 0;7 A# v0 o+ J* J* `( t

$ H, l- Y! ?" ~        ZEROMEMORY( m_SoundBuffer, sizeof(m_SoundBuffer) );
. q4 g: V8 s: A( g( b3 }  g- Q4 Y' c# K! M
        ZEROMEMORY( lowpass_filter, sizeof(lowpass_filter) );- k: }8 N2 |/ k" e2 [! b
        ZEROMEMORY( &queue, sizeof(queue) );# C! T/ m) k8 k; n6 C& J. ]4 I
        ZEROMEMORY( &exqueue, sizeof(exqueue) );
% @# J( v2 C9 }8 d7 ]3 @# R! V1 o9 L3 d, o) p8 H; h+ J
        for( INT i = 0; i < 16; i++ ) {* Y7 |4 D" |+ ?+ s- t
                m_bMute = TRUE;) d( h+ G/ Q' l% s2 k$ u# @9 e' V
        }5 t" F4 q% g# }& o4 v/ w# r
}
  H* d. A: b2 t' {4 [8 v" R" I9 L5 K- n
APU::~APU()8 c. @9 d4 z2 C& t7 W( p; Z
{( R: l4 t4 F: O$ Z( P
}+ s* ^. e( S2 {* |# m
$ z- j( i  F) t3 a; g, Z' E- H' P
void        APU::SetQueue( INT writetime, WORD addr, BYTE data )
) b" e+ x5 [* K9 W{, [1 a* Y0 R' c2 l$ B+ B! ~6 N
        queue.data[queue.wrptr].time = writetime;
2 D+ b+ a' }, K& y; ~        queue.data[queue.wrptr].addr = addr;
4 I, a2 n" K0 Z5 m& X9 }* s        queue.data[queue.wrptr].data = data;
) ?8 a7 b1 ]4 n! w% _& }        queue.wrptr++;
9 o& k, b- F  b( P0 A4 A        queue.wrptr&=QUEUE_LENGTH-1;
. c) b& A5 @2 k0 |* Z5 t        if( queue.wrptr == queue.rdptr ) {, p4 G3 e9 u# F0 o
                DEBUGOUT( "queue overflow.\n" );& h6 q& Y6 {! X( G4 Q3 a
        }
! _9 K: q; m& R+ L1 p}
4 f! T( S0 y4 Y; n& a) r
( T3 j: {6 B+ |BOOL        APU::GetQueue( INT writetime, QUEUEDATA& ret )
1 W* |, R" I- b% }/ M# |% Z. }{) H! a. f' b8 z+ |
        if( queue.wrptr == queue.rdptr ) {
/ J) K3 f/ I& ^3 I( q; f                return        FALSE;9 `! u7 I2 x5 |6 l( W
        }8 d, y5 w# V; ]
        if( queue.data[queue.rdptr].time <= writetime ) {1 A- K( C+ B6 X# D4 u
                ret = queue.data[queue.rdptr];0 I6 g9 z  N2 e; L
                queue.rdptr++;2 o3 p- m% _, Z' M3 I
                queue.rdptr&=QUEUE_LENGTH-1;
" w9 z5 y9 y) o! ^0 K                return        TRUE;- e: {$ b# g: g+ D/ u  h
        }
3 _$ M* Z: E3 u) \! r        return        FALSE;4 I( R0 v, @7 J4 S
}5 y+ s1 G1 o- E/ c* p" n0 K

' [; X1 }8 d% n" d% \$ ~2 xvoid        APU::SetExQueue( INT writetime, WORD addr, BYTE data )
( w% J) Q* W5 t% }% l{
- F; P1 @' e- b* c  ~( K& i7 Q! u        exqueue.data[exqueue.wrptr].time = writetime;8 h! p+ }* b- {- z# h
        exqueue.data[exqueue.wrptr].addr = addr;
5 D1 Q/ M" C, v        exqueue.data[exqueue.wrptr].data = data;3 i& Z; v# s. V2 i
        exqueue.wrptr++;" [# o2 n1 {8 J4 r" R; c$ q& A! A
        exqueue.wrptr&=QUEUE_LENGTH-1;
8 u: `8 I7 s- b( d        if( exqueue.wrptr == exqueue.rdptr ) {) E, B/ P9 E# ~8 J6 O
                DEBUGOUT( "exqueue overflow.\n" );. U! X0 J- M7 {* k% ]; T
        }
5 U/ G0 P$ X7 k2 x, x}
0 n1 P+ R* D, s" u
) L  [" n$ Z" r& zBOOL        APU::GetExQueue( INT writetime, QUEUEDATA& ret )
  _& H( V& l9 G$ T1 S4 Y" z{' P6 h$ x9 L0 b  u
        if( exqueue.wrptr == exqueue.rdptr ) {# C4 K* p# T) {9 u) N8 w3 g1 o
                return        FALSE;" w2 {( ^; A$ d) s
        }5 S8 k1 c3 o, V/ b+ F% D
        if( exqueue.data[exqueue.rdptr].time <= writetime ) {
% Y3 s1 h: f& b: H. F# v                ret = exqueue.data[exqueue.rdptr];
# g! q( C# i- t. Q* B: h                exqueue.rdptr++;
: v% b9 M$ P' T( U+ @. i( p                exqueue.rdptr&=QUEUE_LENGTH-1;
& W6 y0 p* u. X/ y5 D' J                return        TRUE;
9 l; s" D/ d1 ~8 r" n1 r$ g        }
2 @/ N2 ~  Q2 ?* @( A" k, r2 h6 ?0 y        return        FALSE;
$ b  W  Y- v/ z- y7 @+ ?' r+ J}: l8 g8 g7 I* W; @' H
# v, `1 D2 H  K* g5 n# G1 d8 S! Y
void        APU::QueueClear()* K& @! O) S+ q8 c
{/ r' M. M6 D7 m, S/ B
        ZEROMEMORY( &queue, sizeof(queue) );5 m% Q, @$ D; L! z3 r4 G8 Q
        ZEROMEMORY( &exqueue, sizeof(exqueue) );+ T- N. i# J6 |+ G7 M. B
}
- ~* [; F: a; M" K) y- Y7 x7 A! y* J) i; W3 W
void        APU::QueueFlush()
% q5 q+ [0 R+ ^: c3 U7 H{
& F; i  [3 a. X: i; a7 g        while( queue.wrptr != queue.rdptr ) {
1 F; _+ Z* q  T" B8 _                WriteProcess( queue.data[queue.rdptr].addr, queue.data[queue.rdptr].data );
' h% y! m+ e# v5 u' J2 v                queue.rdptr++;9 l) H, I5 z. }9 I5 o2 V* |& d
                queue.rdptr&=QUEUE_LENGTH-1;
  B- U5 ?1 u5 Y( a" v        }+ H8 \1 W; {4 Y4 l" `4 F
8 N( M! t3 J4 X. c1 F
        while( exqueue.wrptr != exqueue.rdptr ) {
/ }% V: U, e2 L7 I1 S3 K                WriteExProcess( exqueue.data[exqueue.rdptr].addr, exqueue.data[exqueue.rdptr].data );
& w9 s# T5 ]8 F2 f                exqueue.rdptr++;" n. {+ z4 T9 V" Q/ q5 l+ j
                exqueue.rdptr&=QUEUE_LENGTH-1;7 C9 Q8 C, O( _9 g* L$ C/ F
        }: c. u4 F7 i; \" A/ r: @: l
}
9 g% I- p) B; Z  Y0 J% v" `
/ K1 i/ h5 `& }; Fvoid        APU::SoundSetup()! h. ]/ D3 ^: p1 W
{( n4 j+ u! M, K
        FLOAT        fClock = nes->nescfg->CpuClock;% O1 i9 A" L1 G! }0 \
        INT        nRate = (INT)Config.sound.nRate;0 N4 n2 L- U, R' k- E# ^" _
        internal.Setup( fClock, nRate );! P8 H6 M  i) n& Q$ {
        vrc6.Setup( fClock, nRate );$ W& C( D8 \. Q, z2 {6 n0 y
        vrc7.Setup( fClock, nRate );
( M. t! R6 i7 G, b7 d; J        mmc5.Setup( fClock, nRate );' x6 u1 i# R0 p
        fds.Setup ( fClock, nRate );9 [7 i+ T0 I7 c: S; F
        n106.Setup( fClock, nRate );& [; F! q0 d# n5 K6 x9 ]
        fme7.Setup( fClock, nRate );
3 I$ k! n, U4 h}7 c- \8 i! ?  M7 t. f; n" ]1 {
1 \; o- J. N% Q' `/ _# }, J
void        APU::Reset()
* G# `  K3 M; ^! ?- R/ W% ^9 ?' q/ e{+ C/ {$ A* P: \
        ZEROMEMORY( &queue, sizeof(queue) );
& E" I; p; _; k        ZEROMEMORY( &exqueue, sizeof(exqueue) );
! a- P4 s/ Y8 u! M+ c9 v* s
# V" b; a& {& @/ r/ {        elapsed_time = 0;
- {5 w; J6 ^5 Y1 v3 t, A+ M& ]9 Y: P8 m8 C( A
        FLOAT        fClock = nes->nescfg->CpuClock;
4 S! \. u! H# k        INT        nRate = (INT)Config.sound.nRate;
) y* p% R0 k) s& N: I. [        internal.Reset( fClock, nRate );
/ q* u9 `4 B  R3 E) f6 }        vrc6.Reset( fClock, nRate );
5 z6 J0 H) m' d$ \, j/ Y        vrc7.Reset( fClock, nRate );' p1 Z; M3 r9 Z& m
        mmc5.Reset( fClock, nRate );; E: |, s  n! o# w4 [& g' @2 K
        fds.Reset ( fClock, nRate );
6 G6 {+ i8 n: T+ n        n106.Reset( fClock, nRate );2 I/ N0 ]+ Z1 W! Z5 l% N
        fme7.Reset( fClock, nRate );
0 c1 L* F/ s! @0 J# q, R& j$ `# s1 V  j( K2 ?$ _7 s
        SoundSetup();
, P$ z$ D- n: c3 S: Z) a! w7 I}
. D. Y! T0 A4 l' F, S2 P7 w! \$ x! Z2 K* d; j/ X( ~
void        APU::SelectExSound( BYTE data )
: Q5 X' |; J# P$ E. k$ Q- ^{7 V0 g+ c& V; n3 e( ?& {
        exsound_select = data;
, g/ i0 V4 k0 G- m8 D$ @}
+ _* ~, s- K: t5 K
, _( _8 f6 K2 H/ x7 a) x/ LBYTE        APU::Read( WORD addr )  H4 d/ S0 u" t+ E7 f
{
0 t% L) D1 A9 `8 I6 P+ j0 o% h+ Q        return        internal.SyncRead( addr );
* t8 L4 x$ ?8 ?) R; G" h- L/ _5 V: ^}# y8 V' T3 p9 g7 s

# M7 y! M( K3 d3 `2 r4 d: [void        APU::Write( WORD addr, BYTE data )! o1 P4 u( n( j! P
{1 f2 N0 [: I9 w$ Z2 C
        // $4018偼VirtuaNES屌桳億乕僩
; O3 _5 r) V7 x: {- y  L        if( addr >= 0x4000 && addr <= 0x401F ) {0 k& R& F1 B  h
                internal.SyncWrite( addr, data );/ R, z  r9 F, R
                SetQueue( nes->cpu->GetTotalCycles(), addr, data );
  D) n4 X9 l) _4 w* r, V        }; V/ h; y" P, K1 k$ I2 W6 U
}
  r# N5 m# D( ~% j: A+ U& G& v# w: U: h& h0 m7 w# ^% D
BYTE        APU::ExRead( WORD addr ): b+ y, p' V$ ]- j& N7 |' Y
{) i' @" ?8 F; {: O' D
BYTE        data = 0;/ O  _7 \  n3 N5 V( B- {' e2 Z6 h( q

, G( W( G3 y. k        if( exsound_select & 0x10 ) {
) w3 x3 P! v7 _; J                if( addr == 0x4800 ) {& W. j" r# a0 y7 {; p* g
                        SetExQueue( nes->cpu->GetTotalCycles(), 0, 0 );
9 o4 _4 O# L. G0 W7 n  V" G- y3 i                }, B& ^- T4 s  o2 B- {& l5 |# R2 N
        }
! [( x. b/ }7 I' @        if( exsound_select & 0x04 ) {. A" D; ^1 g9 j1 E
                if( addr >= 0x4040 && addr < 0x4100 ) {7 ^$ w" H% \+ p) S+ v' F* E2 @1 B
                        data = fds.SyncRead( addr );
4 k) l0 T! ?9 \; @2 i3 P( L. W                }
$ ]% u2 o6 z# a3 j  d        }
, F) |* u0 H& g- y. h9 D1 A8 E        if( exsound_select & 0x08 ) {
1 p* Z0 |$ V$ w9 e  o! @                if( addr >= 0x5000 && addr <= 0x5015 ) {
/ b+ u3 l' f( g/ R                        data = mmc5.SyncRead( addr );
! R8 a8 d! R. q  [                }
  M6 ?- ]* u6 ~/ V0 a) L        }
. s  H; H1 N, Z( n2 Q* T  Y; ^' I9 A5 ]9 t- [, ?! C0 A( g, R
        return        data;0 U  E* W0 q( R) X2 V7 m8 u
}
* A& Q% y8 F% b2 v; F9 ~0 a5 l; y( p2 D/ K4 a2 h0 S: l6 h
void        APU::ExWrite( WORD addr, BYTE data ): P1 {6 _" u, @3 F
{
, }2 H- m. A' q2 M) ]; _        SetExQueue( nes->cpu->GetTotalCycles(), addr, data );
$ u; ?8 V$ M% U0 w
( X, @3 \0 k5 @" m9 X% L  K        if( exsound_select & 0x04 ) {  v) ]; ^- T, _5 _- s! u
                if( addr >= 0x4040 && addr < 0x4100 ) {% X- Z2 Y2 x4 g  j$ ?
                        fds.SyncWrite( addr, data );: D, O6 d3 V5 f4 o
                }9 t$ ~9 M4 Y- F+ D
        }
) f# ^# T' n& a
( B1 _4 O7 `' J7 t        if( exsound_select & 0x08 ) {4 W  v  p; ~: o3 y
                if( addr >= 0x5000 && addr <= 0x5015 ) {" i/ |8 [1 h: R! X& b. F
                        mmc5.SyncWrite( addr, data );
8 w/ `+ a5 o* E9 @$ d  s  o% f# O* M                }
" j* n: W$ ?  j! T! Z- ^. P        }: V& U5 e5 ^" ^+ o) q
}; ?3 x% X# ?1 \7 z

! \' r& W6 y+ B( Rvoid        APU::Sync()1 P$ D/ T1 D$ t$ q
{
; E% Y2 V5 Q. Q# [- \4 W}: V' ?! r9 b0 @5 o3 {5 }

- f, V9 K+ @& Z9 Y  uvoid        APU::SyncDPCM( INT cycles ). n7 m4 H. }+ ]
{
6 {% A: _4 I3 |; D3 z0 a        internal.Sync( cycles );
, B2 x5 {# ?+ T6 a% @
! w. T5 V0 X7 U0 ^5 A6 ]        if( exsound_select & 0x04 ) {8 N6 G3 k" @' y- d  p5 X/ j
                fds.Sync( cycles );
3 D- ^. x! B6 D2 @8 r/ m3 U        }
4 Z7 _$ H( t7 g2 N+ }# u  u. c        if( exsound_select & 0x08 ) {
! S  G& ~, r2 W* X                mmc5.Sync( cycles );" i! a% X) w7 y" [2 Q
        }$ e- C# A' Z2 P0 x0 D  p6 [
}
' p; V4 Q/ n; |; d- |
. B$ \, C4 x7 vvoid        APU::WriteProcess( WORD addr, BYTE data )
; n# l* O3 C. M1 M8 B{8 [- g% n$ Y; ?. }7 Z# Q$ m0 n
        // $4018偼VirtuaNES屌桳億乕僩
  m3 d+ K  I4 i4 b5 k8 @: x        if( addr >= 0x4000 && addr <= 0x401F ) {
: A8 H' V2 l5 Z5 p                internal.Write( addr, data );" n( D/ d3 y  ^  a+ v( W( J
        }
) J/ c: d5 h/ k& e}( H9 g& W* L4 H# }

1 I, X/ g5 B- D0 \5 Q  ~void        APU::WriteExProcess( WORD addr, BYTE data ); M9 p; A* T& E) c7 ~' ~. l
{
! \( M$ A+ H2 Q0 Z) c        if( exsound_select & 0x01 ) {& M! W* K/ h* s' S. ^+ H$ a2 ]
                vrc6.Write( addr, data );. w3 J5 k; y2 d7 i. E* b
        }3 X0 J  Z8 R9 V! `
        if( exsound_select & 0x02 ) {0 j$ Z' C) N" w7 d+ d
                vrc7.Write( addr, data );* N- i) }4 W' ?
        }- Y/ E1 X; B# R$ t! r) P3 |: |
        if( exsound_select & 0x04 ) {
' s% m& Q' \$ r+ C" _                fds.Write( addr, data );7 X6 J& s% @) L% H4 I7 q
        }7 [7 e( G; r$ z! v6 P9 b
        if( exsound_select & 0x08 ) {
" C* r- P, `( P6 }9 c7 r8 N                mmc5.Write( addr, data );
( S4 S: g- o3 D, T% L3 M! N8 e        }4 _  m2 y2 e- `2 L9 W
        if( exsound_select & 0x10 ) {# F0 E' E5 V* Q/ {5 _
                if( addr == 0x0000 ) {4 U2 s7 s- w4 U
                        BYTE        dummy = n106.Read( addr );0 r( d' y; X- k) ^  l+ W; L) q( a( W
                } else {0 p4 i: |8 O; J
                        n106.Write( addr, data );
4 ^! K9 U2 W  Y                }3 Q$ [6 U8 |( j
        }
. J1 P! _7 L7 X+ b1 ~        if( exsound_select & 0x20 ) {8 J5 Q% z5 ?( b6 s  r) ~# P9 P# Z- t
                fme7.Write( addr, data );
! b  A& ?8 a# J: t        }2 L3 `* X$ J% {, \9 y
}
4 d  z3 ~9 e3 E- O
& L% w) J  M5 ^3 Z! i9 z. c; O( ~! gvoid        APU::Process( LPBYTE lpBuffer, DWORD dwSize )& I& L! \0 U( ?$ _1 x; F
{
2 w2 U8 L. P1 g7 {0 bINT        nBits = Config.sound.nBits;! k  l' R2 j6 t  ]/ g9 |
DWORD        dwLength = dwSize / (nBits/8);
+ g. ?4 C) K) m' ?9 x# E( \( n. y; XINT        output;
( |" G% H! ^* D! |9 TQUEUEDATA q;
9 f. {' r$ K7 O' f8 W0 lDWORD        writetime;  m* N7 Z% I2 H" W1 v

" s- e! u) z; f2 h0 v/ H$ dLPSHORT        pSoundBuf = m_SoundBuffer;2 Y3 z* @5 i2 ]. X3 c; v
INT        nCcount = 0;7 j# b. T/ P. o; _7 C% y

- `# s' j# E8 O1 f; |. pINT        nFilterType = Config.sound.nFilterType;, G; q& J8 ~3 y8 K4 ~5 V
& x* Y+ J4 Z2 h  q. w
        if( !Config.sound.bEnable ) {4 g9 z5 }4 N& N0 j) u$ a( ^
                ::FillMemory( lpBuffer, dwSize, (BYTE)(Config.sound.nRate==8?128:0) );7 D/ j! [8 h  W( l$ I# M1 E2 u; F
                return;
. G6 b) A7 U  A" @+ |) p6 J        }
7 v! u( h8 N1 u/ J# o
* j' u) |8 p( ^( L. [6 `* o        // Volume setup) o$ ]; c) |8 Y" y: c
        //  0:Master' d* B7 b6 F9 J( z
        //  1:Rectangle 1& \. Z5 @# N/ P% K
        //  2:Rectangle 2. l! j3 C7 M: P4 v  N3 C* `
        //  3:Triangle; T6 X; w1 V9 k" a) z
        //  4:Noise! Q( K! I3 T, X8 u; d5 [
        //  5:DPCM
8 j. ^0 ?  Q. b: b        //  6:VRC6
- O$ P2 L8 H, V2 v# S3 O        //  7:VRC74 ?( C6 p( t+ A, J8 {# B
        //  8:FDS
+ X* A/ G) g5 q3 J  L# @4 @        //  9:MMC5
8 G3 s9 q) |' i. S        // 10:N106
4 d" j6 d7 y+ e, s+ F" t        // 11:FME78 q' J. o4 d& H5 Q8 ]( _0 E3 V
        INT        vol[24];' f) y2 Y8 ^1 C2 g
        BOOL*        bMute = m_bMute;* k  p  y# G5 l& z
        SHORT*        nVolume = Config.sound.nVolume;4 u! ~6 A/ @7 S% Y# F0 m

2 e& p( {: d3 {& R8 }3 `9 ?        INT        nMasterVolume = bMute[0]?nVolume[0]:0;
+ U( X+ v4 [( }/ b' }  L% z) L) @7 y' c* m4 H
        // Internal" h: d0 F- f3 E9 e0 }. ~# @
        vol[ 0] = bMute[1]?(RECTANGLE_VOL*nVolume[1]*nMasterVolume)/(100*100):0;
8 ]2 p2 y! N; _% s* W' L  k" A        vol[ 1] = bMute[2]?(RECTANGLE_VOL*nVolume[2]*nMasterVolume)/(100*100):0;
; ?. G* j* ^/ G4 }4 z        vol[ 2] = bMute[3]?(TRIANGLE_VOL *nVolume[3]*nMasterVolume)/(100*100):0;- g- \' Z3 J9 j( j. |
        vol[ 3] = bMute[4]?(NOISE_VOL    *nVolume[4]*nMasterVolume)/(100*100):0;
3 h" s1 s$ Z" h# d        vol[ 4] = bMute[5]?(DPCM_VOL     *nVolume[5]*nMasterVolume)/(100*100):0;2 l! Z+ U7 ]3 o- a2 ?
  D5 A/ U/ i# s$ T4 n! q( m4 a
        // VRC6
/ e& O7 g0 b8 k        vol[ 5] = bMute[6]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;- C5 g9 F  ~0 U& J: f9 O! a6 j7 s
        vol[ 6] = bMute[7]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
% h0 b8 x* c& d        vol[ 7] = bMute[8]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
5 x3 I; `. R2 ?/ K$ z4 ]
! q$ r3 `8 ]: {        // VRC7
- s$ n6 n0 P3 l% J( F3 g0 H% [        vol[ 8] = bMute[6]?(VRC7_VOL*nVolume[7]*nMasterVolume)/(100*100):0;
0 }# {5 D: W9 {) ^- P/ a7 j' P, }/ K& X
        // FDS
- f# Z( V. O- i* z$ Z; O        vol[ 9] = bMute[6]?(FDS_VOL*nVolume[8]*nMasterVolume)/(100*100):0;
5 B' s- c+ W$ i5 j' j5 ?
* k2 K% R6 W& P1 |4 F$ }7 J+ f- A        // MMC5
, T. e0 f5 x5 Z/ U- T2 Z# C        vol[10] = bMute[6]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;) ?# F7 `3 i. y5 d
        vol[11] = bMute[7]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;5 w6 U" I0 O- b" `8 J2 L
        vol[12] = bMute[8]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;- g4 w/ C1 T# J/ @
/ E7 v2 w7 `( X  U
        // N1067 i/ l$ g. a$ I: D5 o3 I4 @
        vol[13] = bMute[ 6]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;. f$ Z+ X& j9 Z6 q5 m
        vol[14] = bMute[ 7]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
# N, w# Z( o' h  A  h- Z( H        vol[15] = bMute[ 8]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
/ C8 N4 k* `0 V. z        vol[16] = bMute[ 9]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
# L4 Z. J- r2 h0 `8 q  s        vol[17] = bMute[10]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
" t" Q* y9 Y, [8 I# h; e        vol[18] = bMute[11]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;& K% Y, q# g# [! L% A( z
        vol[19] = bMute[12]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
/ `5 |0 L* |% D  {        vol[20] = bMute[13]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;8 P; B3 e2 l* Q+ F. Z

8 ]3 l7 A" @9 V1 ^( x        // FME7
7 u& I+ c( W# }# w( T$ |7 b& l        vol[21] = bMute[6]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
0 b% x/ e; b6 k& T, B5 F, \; ~        vol[22] = bMute[7]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
: o- b- S$ D1 o        vol[23] = bMute[8]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;) a/ _' h4 @4 t* [, X: }
0 w1 B% F: J; s
//        double        cycle_rate = ((double)FRAME_CYCLES*60.0/12.0)/(double)Config.sound.nRate;
9 Y' j7 V5 j( X6 R- F: z        double        cycle_rate = ((double)nes->nescfg->FrameCycles*60.0/12.0)/(double)Config.sound.nRate;
) N) S% `( W6 T+ m  S9 I  y6 h6 Q
1 M2 y5 c* M2 c; k* I        // CPU僒僀僋儖悢偑儖乕僾偟偰偟傑偭偨帪偺懳嶔張棟$ }& ^1 j" L8 i5 Y' [
        if( elapsed_time > nes->cpu->GetTotalCycles() ) {
1 j2 ~1 l; X, H. x- o$ ]5 W) ?7 a                QueueFlush();) D0 [+ E% f( |4 c, E0 t$ e
        }
1 w% z* `6 _8 h( }. |
" r! ^5 }. e1 q' }1 X# c, q        while( dwLength-- ) {
) n$ r, u" n3 v7 _$ o                writetime = (DWORD)elapsed_time;
! }9 p% p( ?% J  L! [8 {' Y) o: T) {/ f
                while( GetQueue( writetime, q ) ) {
( q/ X) ?% y, ~4 E% z7 {                        WriteProcess( q.addr, q.data );- Q# K% g* H  x5 R- j  e9 @1 W9 D
                }4 K1 ?1 G2 y  K0 ]; C
% S4 s0 P( ~( r, a! H& s
                while( GetExQueue( writetime, q ) ) {  ~1 O  n. e( h. B7 h
                        WriteExProcess( q.addr, q.data );1 k" e5 C: |/ x8 a! ^  N' @  z
                }4 F8 s% l' ]! L) @$ ~" V8 U

' T& r0 s, P7 U. P/ s8 w6 x7 i" M                // 0-4:internal 5-7:VRC6 8:VRC7 9:FDS 10-12:MMC5 13-20:N106 21-23:FME7
; q) v) y5 n7 W3 [# m) s                output = 0;. J7 m1 ]& c4 B, ^- h/ m
                output += internal.Process( 0 )*vol[0];
6 k5 E. M9 u9 N8 U5 g                output += internal.Process( 1 )*vol[1];
) P( A3 m2 `. |  Y& r; E3 R& ~& T7 O                output += internal.Process( 2 )*vol[2];6 v, U5 s6 i4 u' n
                output += internal.Process( 3 )*vol[3];
  x6 r& G( N) c0 N6 `) D1 b                output += internal.Process( 4 )*vol[4];- T7 G2 a, m3 Y, h+ U# v
0 _" G6 U$ a! s# C/ c/ f
                if( exsound_select & 0x01 ) {: g% k- ~" U  a6 X- M, ^) _
                        output += vrc6.Process( 0 )*vol[5];5 w" G  w4 r9 o" X5 i* \. d
                        output += vrc6.Process( 1 )*vol[6];% c5 H: R# W) C& j
                        output += vrc6.Process( 2 )*vol[7];
$ i2 ]* ?$ ?1 F                }
) D* N  _7 k% \$ z' X4 F                if( exsound_select & 0x02 ) {( H& a$ L/ x' Z$ q% i4 u+ ?2 `# J& R
                        output += vrc7.Process( 0 )*vol[8];
4 C. v1 h2 h, `2 K6 d3 ^$ R                }6 _2 T) i1 Z- P& ]& Z: [
                if( exsound_select & 0x04 ) {
4 u# @3 z) {9 H4 R( w6 a- f0 I                        output += fds.Process( 0 )*vol[9];8 f4 c9 p1 _7 P$ z' X
                }/ H; P+ A" |' S
                if( exsound_select & 0x08 ) {, a6 R8 \4 t* @5 N1 t8 o& U7 H
                        output += mmc5.Process( 0 )*vol[10];- K" ?" E7 ?1 K# v. }3 v
                        output += mmc5.Process( 1 )*vol[11];
4 v7 k7 Q2 A7 ~' b+ S. }                        output += mmc5.Process( 2 )*vol[12];9 }5 s# c4 T9 @( I
                }4 w, E' D/ k- x9 T6 c. Y  c1 L
                if( exsound_select & 0x10 ) {
5 D4 ]* v7 i: K! U                        output += n106.Process( 0 )*vol[13];
1 X: c5 T/ E/ `" }3 v. E: F, J& k                        output += n106.Process( 1 )*vol[14];% c- [! H" I, X" y* J3 k
                        output += n106.Process( 2 )*vol[15];; m4 N" f8 X; f7 P
                        output += n106.Process( 3 )*vol[16];
& ?- O6 d: [5 }$ K                        output += n106.Process( 4 )*vol[17];
0 B( a2 l- d5 i/ K% I. Q                        output += n106.Process( 5 )*vol[18];% |; Q1 r4 O/ p& d1 L0 {5 A/ v" r
                        output += n106.Process( 6 )*vol[19];& R0 U' b" L) a( y4 N4 u7 Q- z
                        output += n106.Process( 7 )*vol[20];+ R& L* \. w" K
                }/ k) z' |0 f- u
                if( exsound_select & 0x20 ) {
3 l8 t  R+ x* Y; j  G+ u9 m                        fme7.Process( 3 );        // Envelope & Noise* H! Q3 p5 P8 X3 Y% D  Y  ]
                        output += fme7.Process( 0 )*vol[21];2 o; M2 j8 Q4 y4 d
                        output += fme7.Process( 1 )*vol[22];
( u9 M( z+ s6 |$ T: d" r( S4 u3 S6 {                        output += fme7.Process( 2 )*vol[23];$ k: w% U* s/ L; z
                }
& S* [8 O* ?) `  Z" e% X
# U9 ~$ @( |% w# @+ N, _  |$ I. U/ E                output >>= 8;" B" R* Y( c( w$ J, D- R; d2 t# U

" w0 [! S+ v0 x/ A* M1 E* O( z8 V                if( nFilterType == 1 ) {
* N& O" F- E$ ^; _% ]                        //儘乕僷僗僼傿儖僞乕TYPE 1(Simple)
( F% W% Z. F' n% k3 g                        output = (lowpass_filter[0]+output)/2;+ S& Z9 z8 W' u1 N. B
                        lowpass_filter[0] = output;4 {" @9 w" k3 G8 l/ B
                } else if( nFilterType == 2 ) {* c' c: W' z9 V8 X- n
                        //儘乕僷僗僼傿儖僞乕TYPE 2(Weighted type 1)3 u# Q/ \, q5 |9 p
                        output = (lowpass_filter[1]+lowpass_filter[0]+output)/3;/ W2 t8 i# \4 t! k
                        lowpass_filter[1] = lowpass_filter[0];
2 ^- m: C: o. Y$ [3 q$ U# v; {                        lowpass_filter[0] = output;
' m: D5 V( n5 o" d                } else if( nFilterType == 3 ) {
, n2 [5 u% X/ Q  {                        //儘乕僷僗僼傿儖僞乕TYPE 3(Weighted type 2)
( x5 J. {3 R  v                        output = (lowpass_filter[2]+lowpass_filter[1]+lowpass_filter[0]+output)/4;! W) g/ E6 @# l2 s9 ]
                        lowpass_filter[2] = lowpass_filter[1];
$ v) a+ K' p8 K                        lowpass_filter[1] = lowpass_filter[0];
# B' b  U8 e3 O  r4 x* u                        lowpass_filter[0] = output;
+ j0 C7 ?! {2 O                } else if( nFilterType == 4 ) {9 ]8 V# J. t+ u
                        //儘乕僷僗僼傿儖僞乕TYPE 4(Weighted type 3)
/ G4 `" v2 C% a9 V4 [% w                        output = (lowpass_filter[1]+lowpass_filter[0]*2+output)/4;
5 P0 w) F4 s! G4 L1 ?& ^0 b) {                        lowpass_filter[1] = lowpass_filter[0];
8 k9 O' I* ]" o) A# C# N* ]                        lowpass_filter[0] = output;
, P+ h  _; r0 \& U! ^                }
& }. p7 r, W& v- d: }
+ t; l5 c. l) C$ S#if        0
! ~+ x: ~3 z. @7 W                // DC惉暘偺僇僢僩
& l1 U0 T' G: g6 g9 i$ u! I                {
) Z( c( ^( m& i' [: J2 O                static double ave = 0.0, max=0.0, min=0.0;
6 G& _  `  x. ^9 v                double delta;/ v  R  C2 [' I
                delta = (max-min)/32768.0;
$ x6 f5 I; o4 d, q% m* J6 J                max -= delta;
5 U, E: \$ n1 d; z0 P                min += delta;
# V/ ~8 r* X0 E                if( output > max ) max = output;3 {! q+ d7 Z/ H3 i( T0 y8 h4 o
                if( output < min ) min = output;2 s' z) T1 I9 E' q& k5 N4 p( x
                ave -= ave/1024.0;
# I$ L/ L6 o9 `4 Z: [1 b, b+ _                ave += (max+min)/2048.0;" a% z- C9 M2 r
                output -= (INT)ave;
7 o3 H4 ]) T# F0 O0 z, J                }
# Y+ [% U6 ^& V7 N& {/ B#endif+ u9 t7 ^$ H+ \( ?! N2 i
#if        1/ @" n8 O; S) V- T5 T! I0 |9 k
                // DC惉暘偺僇僢僩(HPF TEST)
- d4 ]7 N6 T- {8 B( K3 Y                {
1 ]5 z+ t8 K+ t' p& ^$ I//                static        double        cutoff = (2.0*3.141592653579*40.0/44100.0);, _, j: }0 P; p% n
                static        double        cutofftemp = (2.0*3.141592653579*40.0);$ g+ X4 i6 _( l3 |8 l  u  m
                double        cutoff = cutofftemp/(double)Config.sound.nRate;
% F0 k" e+ r" r, g5 O5 U                static        double        tmp = 0.0;: b) X9 W7 a; P' M, ~+ H& r# E! p
                double        in, out;
+ |; R  V/ p  w% y3 b1 d% I  t, M
                in = (double)output;  A. y; F! m/ H; n' }6 R
                out = (in - tmp);
2 g! {; E. |7 ]6 Z3 I7 I                tmp = tmp + cutoff * out;! w' P! q% }/ Z

! s: O9 k# Z) B& ]$ j! j                output = (INT)out;
4 i+ s' e7 K# x9 C' a                }
" c7 ?8 b6 d2 C* l( i' ]6 `; E#endif
. C- x, J" ~2 p; _1 I. ~( G- G#if        02 P% _& H  j3 I; K6 h/ j  h
                // 僗僷僀僋僲僀僘偺彍嫀(AGC TEST)
: L' o8 |( b4 b3 m                {  a% i) p$ ^0 Q/ o: f& Q
                INT        diff = abs(output-last_data);3 s: ~; R- l5 r
                if( diff > 0x4000 ) {
' V" Q( M+ W6 c                        output /= 4;% M3 h: N8 ^  w
                } else
, I1 Q: c  e) V+ J  }. \+ j; ?                if( diff > 0x3000 ) {) Z* a5 Z, \' n
                        output /= 3;; W/ r2 v+ u$ C# w. X9 Z$ a7 O
                } else0 ^; }, o" U8 R2 _/ G
                if( diff > 0x2000 ) {0 P8 T+ s& b, ^; v
                        output /= 2;5 |6 T& Z# \4 `  |( Y5 ]! L9 n( g
                }
. a- D% A  l* @% e* Z& x% K                last_data = output;" Q( u' {: D3 b% p8 ^
                }
8 z& `- s/ N2 q7 ]#endif; e* i( _2 B7 I* N4 P% W) H
                // Limit
1 y, |9 o1 [' x0 P                if( output > 0x7FFF ) {
; O2 w- W* s; x, C& t7 m5 F                        output = 0x7FFF;# v/ L: Y  M* q7 F6 z
                } else if( output < -0x8000 ) {0 J2 _4 q1 v2 `: ]4 i) _% M3 s
                        output = -0x8000;  W5 R: ~4 t( v+ I
                }
8 W6 F' B: ^4 G& K3 t1 B
& Y! X  h* b2 ?' S2 ^4 y/ l                if( nBits != 8 ) {+ N' b7 @* g. c! S2 D
                        *(SHORT*)lpBuffer = (SHORT)output;
, S5 K% |- H* v) S% F+ W                        lpBuffer += sizeof(SHORT);
; G6 r: `1 j# ]; Y4 x% _3 r! Y0 b. r* x8 B                } else {* @8 b( ~9 b/ Z& {6 q+ i4 Y
                        *lpBuffer++ = (output>>8)^0x80;
' p* M- G% {7 U; \) l! j0 o                }2 s% I! z2 g% l% ]5 K( E5 h
6 I  M5 @& a3 h! `( \
                if( nCcount < 0x0100 )
. o5 x+ {9 t2 _$ j3 @                        pSoundBuf[nCcount++] = (SHORT)output;
# h* ]+ B! k9 y# N) `& m+ d" I
/ Z" t1 X# L. y' Y- g& r5 Q; ?//                elapsedtime += cycle_rate;. Z) P' Q4 u2 s, r' R: F
                elapsed_time += cycle_rate;
3 p% D/ f: H6 q. d        }% F- I: \# |6 E6 k

; G) W# B& Y- G#if        1
& Z) W( Z& I  \( }0 O0 Q, o& R3 I0 S( R        if( elapsed_time > ((nes->nescfg->FrameCycles/24)+nes->cpu->GetTotalCycles()) ) {
1 \. |1 T: Z8 N$ h* Y0 l( i                elapsed_time = nes->cpu->GetTotalCycles();
- x% F5 ?$ ]% b7 m( d/ [2 E3 ~& B1 K        }1 ^: c( `4 P/ c  A2 |
        if( (elapsed_time+(nes->nescfg->FrameCycles/6)) < nes->cpu->GetTotalCycles() ) {
* ?* I! K! i+ P2 w' O: S                elapsed_time = nes->cpu->GetTotalCycles();
) C% ]/ v- Q7 I" T        }
! J8 L  H8 ~. C! @# e#else
8 G7 b2 ^* e8 }. E, g7 V9 g- y% }        elapsed_time = nes->cpu->GetTotalCycles();
6 J0 E. \: q5 A7 T% \; U# j# d#endif
  i9 J. R: G0 \. X7 g  l3 j}% \, X# ~7 r( U& }8 _

( P% l9 r* a5 T7 N// 僠儍儞僱儖偺廃攇悢庢摼僒僽儖乕僠儞(NSF梡)" \  _4 d2 J" v7 z, W4 s, U( i) u5 ]
INT        APU::GetChannelFrequency( INT no )
& s7 o' e1 d. |, Z0 [{1 C0 K+ B! G) s' p# u
        if( !m_bMute[0] )
$ O% @; X4 Z1 y' n& f( a; e9 J                return        0;
: k0 S8 |' Q+ f6 e/ `3 X# v1 m! i2 n9 l# \- R1 R: g7 \3 k
        // Internal
6 Z( \- E% Y8 t3 G" Q& @        if( no < 5 ) {
! K7 X- a! w7 n) Z$ w# q                return        m_bMute[no+1]?internal.GetFreq( no ):0;7 b( G* s! Z- o, Z, V/ ]6 ~+ C
        }' D' f7 h; K1 a0 u3 E( J7 ?# L
        // VRC6" t5 Q3 u/ b" T8 @9 q* s9 m7 f
        if( (exsound_select & 0x01) && no >= 0x0100 && no < 0x0103 ) {
0 ?- d; r) b' m- C& N- o                return        m_bMute[6+(no&0x03)]?vrc6.GetFreq( no & 0x03 ):0;( `, b+ S8 F  U7 ^: \+ Z
        }
5 [# O- y0 I5 E6 R7 s7 `        // FDS
8 g4 r4 y  _% r- [        if( (exsound_select & 0x04) && no == 0x300 ) {7 M3 U# E) C% ~' B- _
                return        m_bMute[6]?fds.GetFreq( 0 ):0;
- r; p& \2 ^1 A4 H        }! i1 x% V1 F6 x0 [* k
        // MMC54 A# ^/ g8 j! ?+ r1 q( A
        if( (exsound_select & 0x08) && no >= 0x0400 && no < 0x0402 ) {3 m0 L% u, u6 N" B8 S
                return        m_bMute[6+(no&0x03)]?mmc5.GetFreq( no & 0x03 ):0;3 d4 ]  P, v8 T1 y! F6 I9 L7 }  @! k. e
        }- J5 `0 w) g' L
        // N106
. H7 p: a* {0 r6 z) e% I        if( (exsound_select & 0x10) && no >= 0x0500 && no < 0x0508 ) {* j+ y% ~( t- l
                return        m_bMute[6+(no&0x07)]?n106.GetFreq( no & 0x07 ):0;, ]# z% s6 t8 M9 ^
        }$ w% j; m/ @4 ?# W
        // FME7
, W8 ]+ ?% Q, {+ L        if( (exsound_select & 0x20) && no >= 0x0600 && no < 0x0603 ) {3 L; N5 R2 ?/ {# u( X! p1 O
                return        m_bMute[6+(no&0x03)]?fme7.GetFreq( no & 0x03 ):0;
# w8 L5 x2 ^+ D) \        }! e8 X( O! y% T4 i0 V+ X
        // VRC7
8 ^# O: u5 p/ I2 H9 O3 p+ n        if( (exsound_select & 0x02) && no >= 0x0700 && no < 0x0709 ) {
9 i8 R. X- C% w- |: ^$ }2 a                return        m_bMute[6]?vrc7.GetFreq(no&0x0F):0;
" `3 S3 L7 U3 s' _        }% G- k( p2 z* o( r% |: A
        return        0;
( j/ T2 {+ q7 K}
4 ~) W7 s8 L: y# m( d' v# i8 z+ a
// State Save/Load4 v  I% ]& n8 C3 i7 n0 ~- C: `; v
void        APU::SaveState( LPBYTE p )- {6 S5 I3 b& b7 @
{' ], p  D8 E' O& U: w
#ifdef        _DEBUG% ]8 B7 Z" o6 @5 B1 {
LPBYTE        pold = p;
' ~  d6 S! L5 |. G( o#endif
$ ]* J# R+ {+ A3 l: ]6 a  ~
3 a: U7 V# y8 n; a, Q- K0 D- V        // 帪娫幉傪摨婜偝偣傞堊Flush偡傞4 P! K. h) p( C! h; W8 l, s8 }8 y
        QueueFlush();8 Q6 n! P2 k6 ?( Z( L% I4 p7 L5 }
8 T/ v4 ~& N% D% G9 J
        internal.SaveState( p );
! y4 N, ^' ?5 O1 q9 S        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding! N$ f  k$ }! a, K5 ?: H

$ h& X* W6 x4 C9 c  q1 V* Q        // VRC6. `" ]! {; q2 P. K  T
        if( exsound_select & 0x01 ) {
9 }1 ~1 t8 @1 P' T: g                vrc6.SaveState( p );
9 y$ y! Z: o% j( A# V4 U' [                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding
* h, p0 y; x  L" N  Q0 r9 w        }
  G  H; C# Q& r0 A+ e6 z        // VRC7 (not support)
  t. }1 e. Y2 K        if( exsound_select & 0x02 ) {
# p- V+ @8 B/ z                vrc7.SaveState( p );( z( d: u2 `  P& N) Q
                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding$ ]" O! o& v/ L  ^
        }  b& ^' [+ Y! V, r* ]( t- _7 F
        // FDS9 W7 ]9 h8 R5 D7 f+ J  h, k; ~
        if( exsound_select & 0x04 ) {2 x& d6 G* b4 g: c
                fds.SaveState( p );6 A8 C1 J1 v& j( g( ~. S$ g# J
                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding
' ?3 \4 v8 o" @4 m, g        }( {  }8 u1 p' V; }5 a7 n& u% O7 M9 e7 q
        // MMC57 _* v) {. |$ x
        if( exsound_select & 0x08 ) {9 e8 g3 k$ s6 @0 K; B3 c
                mmc5.SaveState( p );
4 V! P4 T8 ]  e  ~                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding& Z! ]3 U% {! g9 e2 @
        }1 }, J. i3 V+ u* ^3 q3 ?
        // N1062 Q- f4 T8 \  O" A9 w( p4 w2 X
        if( exsound_select & 0x10 ) {
: j, ~% C: l; S. C9 a$ _                n106.SaveState( p );
! u- S: O) D, {+ O                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding
2 B  n* \9 C" \# X4 t2 ?# p        }
3 ]2 N: [' `0 d' H; Z: G* T        // FME7
: s) T9 n: J1 W; F# o; ?2 m        if( exsound_select & 0x20 ) {9 t. t/ Z8 b$ Q6 D% H, Z7 D) |6 q
                fme7.SaveState( p );
% i" Y" J- y4 x& T                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding& ]$ e$ f8 D( |+ @9 W
        }
. A8 w* B6 a$ L+ X: k" R
8 Y( m, T  _" r# t! f* q#ifdef        _DEBUG& x0 ^  x8 v2 F, [* o6 U7 U
DEBUGOUT( "SAVE APU SIZE:%d\n", p-pold );: f6 Y/ A9 e: ~; u
#endif
' d  r  {  e: v; ^9 j( M9 \1 q}  Z+ t& f6 I6 q* Y
5 c# O9 I  f/ Q0 F* e
void        APU::LoadState( LPBYTE p )) T7 u- v: k* X8 Q4 D
{- b2 S9 O3 h! G5 w4 M6 S% v
        // 帪娫幉傪摨婜偝偣傞堊偵徚偡
4 L8 d0 O4 S5 p) z5 W        QueueClear();
3 Q' }! E0 I4 ?) c2 y2 W
- z( p7 M# R* U3 t6 S* X7 \% L        internal.LoadState( p );
5 m, d/ k( O1 L* l+ ?6 \        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding
. K; }! {6 v+ ~4 B) D1 O) W
( H1 L6 G2 v6 U. K% z        // VRC6  n  s) B' F- Y9 M3 D8 e# v
        if( exsound_select & 0x01 ) {
4 w# i2 _1 R( Y( s( U. ]5 f                vrc6.LoadState( p );9 a: J) _6 _. k; G: W8 Y) G4 y. r
                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding
  o0 ~/ Z2 z" k0 n" e( {( f        }
, K' s$ G1 C5 x8 U3 [  r% N        // VRC7 (not support)8 ]  V5 Q! V, {5 L9 i( H- q' }; e3 @
        if( exsound_select & 0x02 ) {, E5 w: B/ u9 l  N
                vrc7.LoadState( p );
- t4 C- j9 `% v* ]% s* u7 y                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding, G* u6 ~$ ~5 l# k8 T
        }9 T0 ~! Y9 W3 F( ]" F/ j! j) x3 ?: U
        // FDS. K0 b- A0 w& C3 I6 X
        if( exsound_select & 0x04 ) {
. n8 g- C' w3 q$ y( z                fds.LoadState( p );
/ E8 V9 y" `7 K( l3 e  P8 u$ G                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding, t/ y. K$ G  K  D8 y, V
        }$ b/ M% W% m" Y; z! o5 b
        // MMC5
0 X# G" s4 ^2 Y3 p: d: }        if( exsound_select & 0x08 ) {: [, G- r- j" @  }4 D
                mmc5.LoadState( p );- p: C/ f1 Z9 r* @. k" B
                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding
5 l0 O6 f2 _6 l8 ^+ v" }. g        }
% f  x$ {* K- O! \2 G9 ~        // N106
1 g) y5 C9 G, Q( Z" i2 T0 \4 j$ m        if( exsound_select & 0x10 ) {
# h4 u0 L: Z8 V                n106.LoadState( p );
* E. g* P, |! N+ H3 @+ D( L                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding
# a  O, P) d& o3 l3 e% Q/ e        }
  ~( `' V0 w9 l' W$ N        // FME77 C9 [1 `; u& w0 M$ ~: q
        if( exsound_select & 0x20 ) {2 Z5 h4 K; j$ H- F9 x: I  S' N
                fme7.LoadState( p );- m% Z' c) |" ?8 z
                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding
* d& _- i$ G  v( }3 s        }7 k" e) y7 M- _0 R/ O' n. e
}

该用户从未签到

发表于 2009-11-8 17:25:37 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 14:38 发表
: j. U. f' D5 o+ P  L: r% u& `可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。
" `1 r9 K9 {- y! H7 m感激不尽~~

# c$ I4 G- s" h& r: }恩 我對模擬器不是很有研究,
7 q9 n+ i; g/ c) j4 w. y+ n8 ]雖然要了解源碼內容,可能不是很困難,5 o- i3 K. |& z
不過還是要花時間,個人目前蠻忙碌的。
4 {4 _+ f7 {* S* T$ m* _9 T
: a0 D/ L3 E# l+ Q給你一個朋友的MSN,你可以跟他討論看看,8 s- g" Z7 k% \& Y" s
他本身是程式設計師,也對FC模擬器很有興趣。
6 T2 n6 o) ]2 ?3 D% c) x
# Q1 J' r# R3 d: S. U* N& PMSN我就PM到你的信箱了。
8 w3 C8 a0 D. w5 l3 K
, ~7 v8 U! Y* h" F希望你能有所得。

该用户从未签到

 楼主| 发表于 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 发表
+ t' \& o0 n  _6 C4 _呵…… 谢过团长大人~~

- a' Y( a& e& L/ r7 ~, p2 C- W! R0 }, b5 r2 a
哈 不客氣,算是順便幫他找個伴,大家可以一起玩。

该用户从未签到

发表于 2009-11-20 13:14:53 | 显示全部楼层
原帖由 李伟 于 2009-11-9 16:02 发表
! G) J! u* i& Z  q5 _" }) I团长的朋友都是神,那团长就是神的boss。

+ S  B4 T) ]: Z/ D( z, U! H/ r哈 不敢當,我只是個平凡人,
. E/ ?- o- }. b7 v- q( g$ J9 q要吃飯喝水,光吸空氣是不會飽的。。。。 :)

该用户从未签到

发表于 2009-11-20 13:32:35 | 显示全部楼层
FC模拟器的部分有个人可以帮你忙
5 o/ w2 b3 ]# E8 Z3 |" q" ZZYH
* }% W; K5 v# T3 ?$ uQQ:414734306
9 B  r  v( h7 |; D4 GMail:zyh-01@126.com
* n: \7 H( W' M5 T4 U8 F& \# U
  e  a$ ]  m  M他是ZYH Emulator这个模拟器的作者,只是他用的开发平台是VB,不过就6502的实现原理来说是一样的

该用户从未签到

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

该用户从未签到

发表于 2009-11-27 19:09:06 | 显示全部楼层
原帖由 独孤残云 于 2009-11-27 09:48 发表 ; Z" d& S& Y% @% w) J
再次对团长大人和悠悠哥的无私帮助表示感谢~~
: A- g- l9 }2 P
不客氣  ^_^
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2025-11-28 01:27 , Processed in 1.088867 second(s), 19 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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