EMU618社区

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

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

 关闭 [复制链接]

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 09:56:34 | 显示全部楼层
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。' X: E9 N6 l/ h3 q4 p+ [* ]
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~/ e0 Y( q% X3 B- M
这里有相应的模拟器源码,就当送给大侠了~~& H2 m; N( u" \: Z" C5 t
http://kenkao.qupan.com/5096520.html

该用户从未签到

发表于 2009-11-8 11:31:10 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 09:56 发表
1 [8 j# m) F- @8 ^2 ]/ n能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。! i6 X' g2 M- P9 l2 K
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~  v3 Z9 \; c1 J% {  w8 {
这里有相应的模拟器源码,就当送给大侠 ...
$ Q1 l, ?; p2 c! a4 O
聲音部分(Audoi Process Unit = APU):8 r# o& u1 K8 q& m
.\NES\APU.cpp2 F8 c( H6 n5 h, j
.\NES\APU.h5 L2 S3 C2 e1 K' j( k4 U8 e

; [) |/ y. f. m/ }! D  o
& X; E8 Z7 p% f影像處理部份(Picture Processing Unit = PPU):, b. x4 _) E& X1 T3 a% D2 \
.\NES\PPU.cpp" G, I$ C" z# M! y' b$ i: C! Z
.\NES\PPU.h+ |% z2 Y0 J# Z: S

$ T6 S, h1 q8 U如果原碼用C跟ASM混搭也不錯

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 14:47:50 | 显示全部楼层
这是我手中源码Apu.cpp的内容,敬请赐教:
0 G" l& w+ M( ~# ~2 `+ i3 P(由于很多专用术语和算法机理都不明白,所以看不大懂……)
. ^2 a9 p; h! m& x) }//////////////////////////////////////////////////////////////////////////, w# N! _6 e9 @
//                                                                      /// b& `3 Q" M! N& N( G. ]9 s2 R
//      NES APU core                                                    //" X  z$ [" H6 i9 w
//                                                           Norix      //
/ q! j( P& m9 Z: R* l2 k& C) t' A//                                               written     2002/06/27 //
" w$ U8 D2 A5 t, ^: T# J- e//                                               last modify ----/--/-- //
' ~2 |7 R4 C& H9 Y5 W6 V0 M//////////////////////////////////////////////////////////////////////////" m+ C9 A$ Q6 e
#include "DebugOut.h"
6 G, N/ x! ^7 G& A* N#include "App.h"  ?  f) q4 i& D
#include "Config.h"% E! Y. O6 _& Y

* z+ e; `' a" H1 V$ h$ X#include "nes.h"8 |6 r0 [1 `/ O- R' W
#include "mmu.h"& E+ V+ `5 e% r
#include "cpu.h"
3 q0 s6 p/ B/ j6 ]#include "ppu.h"
' l7 Z# F4 \+ ]  b' T4 `#include "rom.h"( }  f) M3 L* f& p. I
#include "apu.h"6 R( j# I8 V2 w. j
" T5 I  z* e+ m* p+ K1 x: b
// Volume adjust$ ?9 C  S* a0 p' M& Y6 j
// Internal sounds
& U5 ?5 B) J5 T1 a  T8 `: C" l#define        RECTANGLE_VOL        (0x0F0)  g' K5 J4 X( G% j5 i& |9 I
#define        TRIANGLE_VOL        (0x130)
! w# I1 L$ A0 d9 g% u; R" k- R#define        NOISE_VOL        (0x0C0)2 ]2 ~4 J8 g5 i" C! [2 m
#define        DPCM_VOL        (0x0F0)
  |5 \8 f; n* x& v// Extra sounds' m' z  S6 c7 a4 d2 ^/ M. P+ p
#define        VRC6_VOL        (0x0F0)
; M  T* \* X( P( A#define        VRC7_VOL        (0x130)
$ k8 B+ C0 `" }1 E; C#define        FDS_VOL                (0x0F0): e) A# R" h; [; h+ t& |; h
#define        MMC5_VOL        (0x0F0)  O2 e. X7 `; y; y
#define        N106_VOL        (0x088)( R* H( Q9 F" r$ z
#define        FME7_VOL        (0x130)
% U0 f3 ]% l5 [/ ]" j* B5 m; C& p! v1 X" ^* ~
APU::APU( NES* parent )+ g8 O9 V, M" c4 a4 n$ w( A0 k  c
{  V0 F" R  j: D3 j0 e5 o
        exsound_select = 0;# A8 K! w# ?: ~% C; K2 N! ^

" ]4 y5 m5 g7 M/ V8 O        nes = parent;
( F  i2 G/ y; q% |        internal.SetParent( parent );
- Q/ L/ d; G0 d  ]  p
  ]% @7 W! e3 n% a+ e4 r& ^) q        last_data = last_diff = 0;: f' x/ Q' V, g- D* Z9 F$ q4 Q' W* Q
& h# ]8 f$ H2 n& q% k
        ZEROMEMORY( m_SoundBuffer, sizeof(m_SoundBuffer) );
& X' w, I- z$ ~9 g7 R4 y9 }* q9 B9 _2 X1 J* Z1 r
        ZEROMEMORY( lowpass_filter, sizeof(lowpass_filter) );
; r) q2 C, X7 Z9 ]6 Y        ZEROMEMORY( &queue, sizeof(queue) );$ p2 }% v5 o6 ~! s8 F. Z0 ?
        ZEROMEMORY( &exqueue, sizeof(exqueue) );: ~4 Z4 G. @  _

8 N6 n5 n2 I+ D+ G, r( s2 F        for( INT i = 0; i < 16; i++ ) {+ N0 H. T5 k1 p! e( s, W
                m_bMute = TRUE;
& E& R( p: v  c! _6 w! o4 t        }
# _$ h( v- Y" D7 Z2 z}
; W9 ]4 X8 S  ]9 _1 |* E  V1 f: P2 C1 V
APU::~APU()
% ?% k: B5 k$ ^- R2 V3 ~2 F{
' N* C4 d3 L; k6 s" a}
3 D5 b: f( u! n. y+ B4 T* ^6 k
. C+ y, c6 l' n" c6 d. Q5 ^4 E% ?0 yvoid        APU::SetQueue( INT writetime, WORD addr, BYTE data )
4 F6 `5 q' y9 l8 A1 `  p{, m& K$ u; {: d/ r( F
        queue.data[queue.wrptr].time = writetime;
7 C% m; Z3 w$ a% R' t1 B" R( {        queue.data[queue.wrptr].addr = addr;- `! f3 J+ P6 Z( y
        queue.data[queue.wrptr].data = data;, L; B2 k" ?4 ^* Y% ?
        queue.wrptr++;1 P' j$ s4 Q" K- A$ D
        queue.wrptr&=QUEUE_LENGTH-1;
; W4 h' g9 V2 p! S! {6 |        if( queue.wrptr == queue.rdptr ) {
+ K% e; l2 G3 ?: k* Q* t+ N                DEBUGOUT( "queue overflow.\n" );
9 O9 Q9 ], z& N* T& y        }
) f4 a6 I1 r( Q  I}
8 D! N5 e+ g0 D3 {: @* [
6 f2 v3 Z9 l6 g' F0 `1 a" \BOOL        APU::GetQueue( INT writetime, QUEUEDATA& ret )
" G2 D/ \' |" T2 Y9 {{# _" C) a$ N- L5 {( L
        if( queue.wrptr == queue.rdptr ) {$ Z; M0 L/ B! j& n5 ?' j$ n8 |
                return        FALSE;& U; h  K' T1 ^! Z
        }
% E2 ]& u' c1 i* o( S' J        if( queue.data[queue.rdptr].time <= writetime ) {# D# z8 s/ b) }: U: f
                ret = queue.data[queue.rdptr];* z  f4 R% h& Q3 |! C
                queue.rdptr++;) m) b$ U$ `# F4 d1 e7 }4 {
                queue.rdptr&=QUEUE_LENGTH-1;
: q! T+ w2 ?, v% M                return        TRUE;5 C7 |) L/ t" V) f& R) @$ G! v
        }6 `" F* B; \& b& T
        return        FALSE;
. e1 B; f# @5 l; Y}
1 E) k$ {' B* R, Z  h3 Z
+ [7 H" }# x9 r5 A( r1 L! D+ w. lvoid        APU::SetExQueue( INT writetime, WORD addr, BYTE data )+ B5 l: b. r+ N7 I+ p
{1 @' L1 z2 m: F& x7 h$ ~. ^. p1 w
        exqueue.data[exqueue.wrptr].time = writetime;
9 R) w9 w2 ]; O1 d7 S2 h        exqueue.data[exqueue.wrptr].addr = addr;
, Q& }- B+ k% Z! r( H/ h        exqueue.data[exqueue.wrptr].data = data;! V6 S3 K+ [1 m, H
        exqueue.wrptr++;
3 I9 R/ G- _7 v, L" P        exqueue.wrptr&=QUEUE_LENGTH-1;
" q0 b/ s: H" p8 O6 `1 ~7 {6 w6 {* B        if( exqueue.wrptr == exqueue.rdptr ) {
9 r( \. D( [5 w2 I8 _                DEBUGOUT( "exqueue overflow.\n" );
1 o8 ^* G; M! }. F+ H( @        }
" ^" _1 L  t) `. a6 W}0 Q' S8 I( s. m' L$ \. k5 A. u
6 g) k  V; S: a
BOOL        APU::GetExQueue( INT writetime, QUEUEDATA& ret )
! Z* L$ W4 f9 x5 i. x! I1 A9 g{
! J" R% y' c9 A- I+ P" v+ X4 W        if( exqueue.wrptr == exqueue.rdptr ) {+ o3 r1 c9 Y1 M
                return        FALSE;
5 b# J- X0 k* }9 \1 F        }
5 W3 _* d1 ~0 q5 G7 c7 i4 Y        if( exqueue.data[exqueue.rdptr].time <= writetime ) {
1 K/ D( v5 ]% C5 p% T$ r                ret = exqueue.data[exqueue.rdptr];! {" ?' q& h$ w" V0 `  I
                exqueue.rdptr++;
3 @! Y( D6 t: `$ [, m                exqueue.rdptr&=QUEUE_LENGTH-1;
) B& h$ b. S* O* H! I                return        TRUE;
  I  `" c/ n% V* z        }% L" W- Z5 B9 u& c& F% i6 i  _
        return        FALSE;4 x( V* O9 S  R1 D( M* h/ J
}- e8 k1 w7 x+ `) Y/ Z1 G) N
; W2 B6 e/ U/ ^& e- y
void        APU::QueueClear()/ X( x* ?1 A5 a! y
{
2 D, {! v. r4 }$ ?        ZEROMEMORY( &queue, sizeof(queue) );
! C" N) I7 e0 L, n0 M0 B' x        ZEROMEMORY( &exqueue, sizeof(exqueue) );
! _( N) n) e! w7 o7 V. z}6 d* @; J4 w; b: J+ U2 A7 Y

, ~( {& Q& K4 v0 tvoid        APU::QueueFlush(): r. G5 W8 m2 g' D, J  Q4 P
{
1 x" [/ n: I. n/ P        while( queue.wrptr != queue.rdptr ) {
* K& j0 e7 }5 K7 Q4 W                WriteProcess( queue.data[queue.rdptr].addr, queue.data[queue.rdptr].data );
/ S5 ]& t' v# w0 W1 }) N                queue.rdptr++;) y/ e  {7 R6 i
                queue.rdptr&=QUEUE_LENGTH-1;# T+ h# v1 k2 S7 |
        }
2 h$ ^# {/ \3 ]8 y& Q* v8 A$ {
" |% V" G* w' z( m# X, \        while( exqueue.wrptr != exqueue.rdptr ) {. x& r9 |9 l/ g
                WriteExProcess( exqueue.data[exqueue.rdptr].addr, exqueue.data[exqueue.rdptr].data );+ _) N6 Z8 p% a- ]+ ?
                exqueue.rdptr++;
& z, S: k- b# W4 I3 U6 M6 `& D                exqueue.rdptr&=QUEUE_LENGTH-1;
+ _! ~* B% Q  v' ^        }
4 G8 K9 D- |% W) `0 e}" a/ g" J  ~7 e$ f
  {4 c/ ~- W- p) v  F" o' s( S
void        APU::SoundSetup()
# s" F! o3 E) n) [8 }$ V, K7 l{. t% w# o0 l, W( x+ p0 ^
        FLOAT        fClock = nes->nescfg->CpuClock;* i" p: P3 J% i/ I) U+ D- L/ @+ A) U
        INT        nRate = (INT)Config.sound.nRate;& k- u% m; \& V8 p/ U1 r
        internal.Setup( fClock, nRate );7 A. v6 n% ^  g; \. H# g; X9 Q
        vrc6.Setup( fClock, nRate );$ k( t  n9 @8 T1 K* z0 V
        vrc7.Setup( fClock, nRate );% a* h5 x6 Y! J) z. w9 \
        mmc5.Setup( fClock, nRate );
4 F* t( x+ \  r+ g5 q- |" n; p1 N+ t        fds.Setup ( fClock, nRate );
" v* y6 Y  W5 _9 Q        n106.Setup( fClock, nRate );: i3 [* o7 f1 ], Q7 I" P6 Q
        fme7.Setup( fClock, nRate );4 z2 ~- I3 B+ u- k5 Y$ f: {
}
+ h3 N+ g7 s, r7 D- }8 O+ O: {9 @7 K# L% U$ c( l5 u+ e- Q
void        APU::Reset()
( B/ J2 Q5 c  C: L{6 i3 ^, {$ G' d( \: ^& m( }- n
        ZEROMEMORY( &queue, sizeof(queue) );
; H  e% r# d2 |0 |        ZEROMEMORY( &exqueue, sizeof(exqueue) );% S7 U" `2 u# X
0 r- C# _5 k9 u+ |
        elapsed_time = 0;
" h. |8 C* W8 e3 t1 C# N$ D+ _" E& x# g* F  ^5 {8 x/ G
        FLOAT        fClock = nes->nescfg->CpuClock;
* l. y3 q: ]% g8 B' C        INT        nRate = (INT)Config.sound.nRate;
. @$ ?' w/ l$ l        internal.Reset( fClock, nRate );
8 o3 z. C, j9 K/ l$ F        vrc6.Reset( fClock, nRate );
$ W! W2 V. N6 P5 s        vrc7.Reset( fClock, nRate );
. }  e) r4 L% h        mmc5.Reset( fClock, nRate );# k3 I! q1 I. I: H9 z
        fds.Reset ( fClock, nRate );) E5 }$ _0 ?7 q
        n106.Reset( fClock, nRate );. _7 W/ n# M6 R1 q- o. y1 A
        fme7.Reset( fClock, nRate );  D; ?' e# z+ p) \( F2 `& i

8 s/ m+ j* L- G, j% b) I: X+ _7 |( S        SoundSetup();
6 }  `8 x  T6 h# R) W( ~}/ B0 K0 Z5 D8 a7 C' T1 x
9 X9 W8 q3 y6 Z- Y  Y0 |
void        APU::SelectExSound( BYTE data )
( R/ G* I( h7 h- P! k7 g{
2 O2 P! y. N: ~        exsound_select = data;0 x# m' R0 ~0 R4 s% [! \( \
}& k* p8 w% H) D: ]

- l- R6 s) t4 S0 D* J, ABYTE        APU::Read( WORD addr )
2 _" N3 s9 v  |  \{
6 k# Y2 k$ N$ q% e8 t1 v        return        internal.SyncRead( addr );
" r7 I" a- V; m) T}9 s3 x6 R5 p3 f5 [* ]" e( `
: ^# F: Y: r; O$ o8 R  E+ W
void        APU::Write( WORD addr, BYTE data )# w0 |9 r' b( H0 a7 n+ _5 K- n- e6 }
{/ B* }& [$ V, m  E, `8 l2 u
        // $4018偼VirtuaNES屌桳億乕僩
/ }# n8 Y2 X2 j' x* h& ~; r# r        if( addr >= 0x4000 && addr <= 0x401F ) {. K  k, d" @0 H0 A3 t
                internal.SyncWrite( addr, data );
. z. a& T2 E) B( _- M/ s- f                SetQueue( nes->cpu->GetTotalCycles(), addr, data );
& s! F: K! X9 c        }
( T- D" `& i2 g1 |}. c# y* O8 ?; k( K6 |1 v

$ c% `# \9 C, f5 kBYTE        APU::ExRead( WORD addr )
$ V& @+ A" |, s" _* }; Y' K) c; r{
$ _# n# b% K+ }$ I4 ?* O. D- zBYTE        data = 0;( V4 k* o7 o" @- |
% a% p: |& u) O9 Y3 i7 X7 N
        if( exsound_select & 0x10 ) {3 t7 ?0 @; C- H! O5 h+ u. X
                if( addr == 0x4800 ) {
0 x4 q6 K4 n8 e0 i# V' P  K                        SetExQueue( nes->cpu->GetTotalCycles(), 0, 0 );
# y  m6 ]" ]; G6 l% n; ^                }
$ }4 P! Z* E* K4 h# B. c6 _- C        }
3 w- S3 p6 @- o* `5 o7 e0 u- O        if( exsound_select & 0x04 ) {
6 c+ s; v" @' B* U. X/ i* V3 Y                if( addr >= 0x4040 && addr < 0x4100 ) {2 r5 M2 `. ?) p' v% `
                        data = fds.SyncRead( addr );7 i' \+ u! M/ j6 {
                }
) [$ z: ]# u8 h( f! P5 M        }# C+ O+ _! ~- S# X2 d3 F
        if( exsound_select & 0x08 ) {
  E+ b6 ?8 k4 R. r( a  o                if( addr >= 0x5000 && addr <= 0x5015 ) {
! r, q7 o; @( c: J4 p8 B2 N                        data = mmc5.SyncRead( addr );' l- z( C+ x2 V" R8 x% h
                }$ g! Y, Q6 o7 F% c1 t  h
        }6 I" b  O6 ^' s' e% W) u! [
4 m" o: j: a$ E/ B* j6 b
        return        data;! Q, r: h7 }5 P, @2 k! \
}# i% T* l: T  L0 ~( K. F) _/ L1 h
. ?( Q$ M: K5 U8 H+ n, q+ b) d' t9 W7 r
void        APU::ExWrite( WORD addr, BYTE data )
6 B( z( A( Z, i# @. d{
0 M* L& m+ H. D4 x: R        SetExQueue( nes->cpu->GetTotalCycles(), addr, data );
% f& \& ~$ W  B
" r* ?. u8 e6 g- @( C        if( exsound_select & 0x04 ) {
8 e  ~1 v) c# A) z# V/ r                if( addr >= 0x4040 && addr < 0x4100 ) {; r. d- Y' z4 N$ |" Q
                        fds.SyncWrite( addr, data );# _" G0 A7 a9 V
                }' _. \8 V. q* J6 `/ E% v' J2 X
        }6 A: U' e) e9 ?& O* I
$ ?  l0 _5 m9 Y: O: n3 `) c
        if( exsound_select & 0x08 ) {
* h' B4 K( \, R2 h. F, Z: Z                if( addr >= 0x5000 && addr <= 0x5015 ) {
" |# F8 B/ E1 G3 x                        mmc5.SyncWrite( addr, data );
5 g0 [/ n4 B& N                }& Q- M$ |1 }# N5 C
        }2 m6 _% l1 R' k7 q
}/ m$ h) V3 F2 Z. c
4 z- m8 x& ~- x; h1 ^
void        APU::Sync()0 e5 j- n3 X3 B+ I# j+ e
{
2 @9 F  ~4 `& E6 j" u7 [) A}
( W% Q$ k# a3 d* I$ ~: C# G
- ?" @, e5 k% X8 j& H$ ]+ q+ yvoid        APU::SyncDPCM( INT cycles ): G" d7 |- Z4 d1 G
{, W/ f- D/ y7 A7 L& H0 {
        internal.Sync( cycles );& U% K( j6 }9 {3 P

! P! V0 J  o2 c        if( exsound_select & 0x04 ) {
* U$ ^$ Q/ B' _- ?$ v2 _                fds.Sync( cycles );6 m  y8 L) b7 t$ N
        }
0 s7 h8 q+ V7 E8 E        if( exsound_select & 0x08 ) {
  L# b8 r. Q. X; e% v0 E0 D5 C8 \                mmc5.Sync( cycles );) y3 h0 g7 X% y$ u
        }
1 k! k7 b/ \# [  M5 n}/ l$ l: J; V# D8 q" x/ p) S

9 ~0 k9 }9 |' n. k6 |# i" s; [& dvoid        APU::WriteProcess( WORD addr, BYTE data )
& |  C8 a  f  J9 o" ]( c{
; i1 L7 [6 Q: N2 h9 K        // $4018偼VirtuaNES屌桳億乕僩
$ Y0 H: s0 Z  ?  R# e5 F1 t        if( addr >= 0x4000 && addr <= 0x401F ) {
6 n0 ]# H" R1 m( |7 n                internal.Write( addr, data );! z0 \0 E$ o( z  j. @( p" R5 z
        }: s0 R3 u- k. l, b) Z
}
7 ?5 M4 r& u3 k; Z* Z
) t% i) o8 P# V" ovoid        APU::WriteExProcess( WORD addr, BYTE data )
9 y8 }& H9 f4 n4 K) [# p6 P{
) ^1 a3 k# ]. t( B  K, H( F        if( exsound_select & 0x01 ) {
. L/ p3 D+ a  g$ u                vrc6.Write( addr, data );
9 O, V" O5 R9 `4 Y/ i* p7 d9 Q6 I: H        }3 B0 s- q. S5 x& ^6 d
        if( exsound_select & 0x02 ) {6 `( @! D. h4 T* t# ?# w- h5 J: V
                vrc7.Write( addr, data );
- T% y% y: G2 a" E        }! t/ R- U, w2 x# q
        if( exsound_select & 0x04 ) {9 N- O; n, ~, H
                fds.Write( addr, data );; w" ^' r6 W* l( J8 d& t0 `
        }
  z) }! y7 m) P0 x        if( exsound_select & 0x08 ) {+ I( P+ x! L7 j: ^; ?; f
                mmc5.Write( addr, data );
" J! Q  [% q/ t; ~        }
% ^( G& G0 @& L, i        if( exsound_select & 0x10 ) {
$ X. F9 f  B: f$ U: ], s                if( addr == 0x0000 ) {
( K8 A1 _) N1 o3 b3 P* g- D$ d                        BYTE        dummy = n106.Read( addr );! e/ m" `$ W+ P
                } else {
0 g3 o  R5 _6 {6 r- _& b9 _" L& a* M                        n106.Write( addr, data );
! T, U6 B- a+ u9 k                }
8 J2 }5 Y* m3 u) k        }
6 g$ e" a+ R; E# A+ n        if( exsound_select & 0x20 ) {* K3 x6 Q5 Z' F, p5 z
                fme7.Write( addr, data );
4 J$ ~8 F$ u9 ^* F        }
3 z3 q8 [" o6 v5 S" V$ _3 S}
( H; X3 l. \. n% C: H& r# _) L6 _  t* x" h
void        APU::Process( LPBYTE lpBuffer, DWORD dwSize )
/ l( V7 E+ L! Y# E4 a2 V4 b{' w- b5 R4 f9 T- R, t
INT        nBits = Config.sound.nBits;. ]. [4 i7 S: \- C$ Y+ ~  `3 v. F
DWORD        dwLength = dwSize / (nBits/8);
) P5 `0 ?0 e& R4 W9 |* [) @INT        output;
3 Z" h+ u* `$ G1 m, L! ^QUEUEDATA q;0 ?3 e. \; g" V9 O* w8 _! ]7 V( C
DWORD        writetime;% A) m' [* m7 X' s- J- i* N8 v2 P

3 E7 s  @, f4 i! GLPSHORT        pSoundBuf = m_SoundBuffer;) f6 ~  h( A0 |* H9 p# h
INT        nCcount = 0;
" ^3 m, n' I" T' D
- L+ j* y3 b1 Y1 w* KINT        nFilterType = Config.sound.nFilterType;# q) g1 R* v6 Q. t/ |

7 V1 I- |3 r; S4 |" j        if( !Config.sound.bEnable ) {
& _+ V* Q, g+ G& \# d$ ^                ::FillMemory( lpBuffer, dwSize, (BYTE)(Config.sound.nRate==8?128:0) );  A. J% ~! h% ]% ]# t9 u
                return;- ]1 e# G! ]4 F! T6 B7 k& b
        }9 s* v1 s* \' E$ W7 X! v. w& L' o

9 I+ J7 m% |% _- g9 r        // Volume setup6 o9 \0 n4 v; C. z1 g/ l* d; H
        //  0:Master
% s2 w7 S' y  q2 C! q& U        //  1:Rectangle 1
% t, R% S( ~' a7 _' P- k        //  2:Rectangle 2
" Y+ m# ?" \! }% M* J        //  3:Triangle5 n$ b. i% j) H, d
        //  4:Noise, I# a3 U2 u' k
        //  5:DPCM
6 G+ E! g2 \4 a7 a' ?        //  6:VRC6
4 k- i% Z7 U3 [5 t, H$ j7 V        //  7:VRC7
; m& F( }0 X1 u, Q        //  8:FDS
7 x1 S# l, x# i: h* B. q0 X        //  9:MMC5+ K  R& m/ _  I6 o# A) y7 e$ q
        // 10:N106* L4 L( G9 c( M5 {# r* _& {
        // 11:FME7( Z5 r5 k& C5 |. T
        INT        vol[24];
) K1 O, U, N. Q7 l7 U        BOOL*        bMute = m_bMute;, @) S2 V$ e6 e2 T
        SHORT*        nVolume = Config.sound.nVolume;, X2 n  d* r6 [6 u* v" t6 c2 ]/ s

  H+ s/ b! s' z. C. s, O        INT        nMasterVolume = bMute[0]?nVolume[0]:0;
! y% k+ \9 c# \3 x7 f; {
) ]9 k" [) C; z. Z        // Internal9 d4 }8 b8 n  i( X
        vol[ 0] = bMute[1]?(RECTANGLE_VOL*nVolume[1]*nMasterVolume)/(100*100):0;
. R7 t- e6 L! w$ d& n; L8 f3 g        vol[ 1] = bMute[2]?(RECTANGLE_VOL*nVolume[2]*nMasterVolume)/(100*100):0;! B* g3 Z( M% A( a* \- n
        vol[ 2] = bMute[3]?(TRIANGLE_VOL *nVolume[3]*nMasterVolume)/(100*100):0;
/ d7 R, k- ~: ~. r2 v. {8 L2 m0 u        vol[ 3] = bMute[4]?(NOISE_VOL    *nVolume[4]*nMasterVolume)/(100*100):0;; _2 k. c! Z! r+ g+ C0 Q" }( o
        vol[ 4] = bMute[5]?(DPCM_VOL     *nVolume[5]*nMasterVolume)/(100*100):0;9 [) I  r# J( P% j! p
8 Q2 p0 A, {7 ^& r, y' S
        // VRC6
1 z6 [0 E8 \) p  t        vol[ 5] = bMute[6]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
: O. M& D% b6 n9 o! y* j        vol[ 6] = bMute[7]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
9 w' i/ n3 T) s4 ]2 H5 h8 ~7 v        vol[ 7] = bMute[8]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;4 g7 Y- U2 `" k7 X- P. h
; D% |8 J4 d% L
        // VRC70 X$ b, J, q. e$ `. i8 W
        vol[ 8] = bMute[6]?(VRC7_VOL*nVolume[7]*nMasterVolume)/(100*100):0;9 x: J2 t& s2 N4 o3 s
8 b' H! b3 ]9 I% D+ c) P( r# \. J
        // FDS: H- }/ g1 I. w, @% Y
        vol[ 9] = bMute[6]?(FDS_VOL*nVolume[8]*nMasterVolume)/(100*100):0;
$ A5 q( g: Z2 l) n$ R
8 ~% B/ z, Y& |, K        // MMC5
, \. n9 G: B, ]) q4 b7 M        vol[10] = bMute[6]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
$ s6 D3 l# Q2 e# l( k# n- ]' d7 \        vol[11] = bMute[7]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;% o" }% K4 ~# p# |7 `, F8 ~5 L2 z
        vol[12] = bMute[8]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
/ B/ P9 V: L* P& X4 q3 V* s9 q. J9 y$ E$ @
        // N106
, P" k, P# K! h3 [- F- H: q( F- b        vol[13] = bMute[ 6]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
+ O3 G, W; b! f' b& n. \7 Q        vol[14] = bMute[ 7]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
8 X+ J& \8 }7 V1 d! K" s5 `        vol[15] = bMute[ 8]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;0 D6 p- N3 M5 `: Y3 A8 X
        vol[16] = bMute[ 9]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;+ Z3 G, c/ E. F/ V( P. i6 y
        vol[17] = bMute[10]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;# @) b. N( v( ]; x  Z& R# ?& X
        vol[18] = bMute[11]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
" P3 h. y7 L; d0 r        vol[19] = bMute[12]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
4 x' x! F3 q( t$ b  F0 z! q6 ?* Y9 U        vol[20] = bMute[13]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
7 b  i- r5 T( q, O) r; d
% `; f6 ^( @* o* u        // FME7: _% c$ l# f, P$ L' _: l
        vol[21] = bMute[6]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
% M- V9 _0 ]. `        vol[22] = bMute[7]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;3 ]( }% z: p0 ]; Z/ z: r/ G
        vol[23] = bMute[8]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
3 T6 P: I% W3 |$ d$ `3 k3 c# O- Q7 K. O9 u- M& J
//        double        cycle_rate = ((double)FRAME_CYCLES*60.0/12.0)/(double)Config.sound.nRate;* [- g  v- J. h5 D( T9 M
        double        cycle_rate = ((double)nes->nescfg->FrameCycles*60.0/12.0)/(double)Config.sound.nRate;
0 h$ g! b% C; }- E/ E& r7 P
$ c+ }1 O# w6 ~0 m. p' u8 L2 Q! z! i        // CPU僒僀僋儖悢偑儖乕僾偟偰偟傑偭偨帪偺懳嶔張棟
, K( @1 n( \8 U# L% d! k8 x* l4 G        if( elapsed_time > nes->cpu->GetTotalCycles() ) {: _6 W1 v! B0 c
                QueueFlush();. x( [, [/ q. p1 V1 `/ n: q9 {. J
        }
+ Q4 ^" p. \' q; W5 H+ P  V, m% ]
7 c5 a. ?2 i5 G: o1 G( b        while( dwLength-- ) {: [' B. n* |4 G3 _+ b" |
                writetime = (DWORD)elapsed_time;
0 K( C9 y- d9 T
* |6 d  q7 w+ z- a) \6 C/ t                while( GetQueue( writetime, q ) ) {) t. p- F/ B3 G# M
                        WriteProcess( q.addr, q.data );
+ {9 M9 r9 T( y                }
: X" r0 D" N+ ^( r/ p
$ v4 B! Y" j  B  x5 k* b7 f                while( GetExQueue( writetime, q ) ) {
& n- p& f! c$ R! f' R" ^                        WriteExProcess( q.addr, q.data );( \- B; L  ?/ L- c! G0 T" J. A& S$ [
                }
9 k4 |8 ^( ?# g4 O
* E. {7 w+ r+ ?: `                // 0-4:internal 5-7:VRC6 8:VRC7 9:FDS 10-12:MMC5 13-20:N106 21-23:FME7
) I9 n& d" [. ^/ `8 H1 J6 I                output = 0;
# x9 Q& `6 `5 K, T$ |9 d                output += internal.Process( 0 )*vol[0];
0 v! s! M* C- ~; N% ~& }  G. o                output += internal.Process( 1 )*vol[1];
+ e, |! C$ G: }8 a( }+ O                output += internal.Process( 2 )*vol[2];
7 e- `! \& b0 ]6 D" O                output += internal.Process( 3 )*vol[3];
0 [9 I7 b3 u3 Y$ e( ]! _" A                output += internal.Process( 4 )*vol[4];
- D) W2 c9 G6 ]4 {- ]
, q. z$ K! @  e0 U5 `                if( exsound_select & 0x01 ) {- S; J7 L; c1 i1 L$ G1 u, t
                        output += vrc6.Process( 0 )*vol[5];6 [" }: [7 Q2 v; O4 T
                        output += vrc6.Process( 1 )*vol[6];& P  Y6 z' x, D7 o. W4 r+ T
                        output += vrc6.Process( 2 )*vol[7];
0 [& ?, S" P, v& }2 F# N  E                }
$ Z; k  g6 V2 s8 Y2 x                if( exsound_select & 0x02 ) {- n  ?% d9 T$ m3 B0 ]2 ~
                        output += vrc7.Process( 0 )*vol[8];' d, s; ^8 x4 i7 B% a! L. W
                }. J& c8 W" ]+ k& ^, d
                if( exsound_select & 0x04 ) {9 F9 r4 U2 T! e
                        output += fds.Process( 0 )*vol[9];( S2 D) U2 h* q, z! ?" p3 W6 x
                }
7 f6 P9 Z3 j' f3 k( {. X/ ]                if( exsound_select & 0x08 ) {
2 f# `( x9 E+ u7 ~- r                        output += mmc5.Process( 0 )*vol[10];% r: U- R/ ^0 N: x4 ?
                        output += mmc5.Process( 1 )*vol[11];+ A* l4 _: z6 p% L( ^1 h
                        output += mmc5.Process( 2 )*vol[12];- J. @7 H& x6 @+ ?
                }, r/ ^+ x% A5 N& N9 v4 L
                if( exsound_select & 0x10 ) {
* L" q6 S- b1 t$ l                        output += n106.Process( 0 )*vol[13];
' Z1 z  c# t& r8 G                        output += n106.Process( 1 )*vol[14];
3 n6 m. A6 c' V3 ?                        output += n106.Process( 2 )*vol[15];; C. }1 d/ O7 q1 B: T$ H# n" F& F! T6 ]
                        output += n106.Process( 3 )*vol[16];
5 ~7 K- k. ], T/ d                        output += n106.Process( 4 )*vol[17];! }) F. i0 u! c& G+ o% j
                        output += n106.Process( 5 )*vol[18];
  q; {3 l' l, ^+ q2 p* b" q; f                        output += n106.Process( 6 )*vol[19];
7 T# h7 |' g) B& ]0 F# j/ [                        output += n106.Process( 7 )*vol[20];4 l# n- y7 ]' _6 I
                }
! t4 M$ x. F  r4 n! N; |                if( exsound_select & 0x20 ) {
  T6 {2 C) {; z, ~( z4 l                        fme7.Process( 3 );        // Envelope & Noise
$ h+ J9 i0 Z+ C- ~9 o+ u                        output += fme7.Process( 0 )*vol[21];4 s% `: \5 m2 E- i8 j: N
                        output += fme7.Process( 1 )*vol[22];
' L1 J$ P# o2 w( q                        output += fme7.Process( 2 )*vol[23];
/ g5 c1 j: p6 f1 O, ?                }
7 A( u8 \6 `& \* E# Q/ Q
1 N4 q; K6 p7 g* T                output >>= 8;) H9 w0 K* j+ K" |& ^
; B& a0 `; M& D1 T1 M1 O% R& i
                if( nFilterType == 1 ) {: e7 D. \% a8 ?0 J/ ^( H
                        //儘乕僷僗僼傿儖僞乕TYPE 1(Simple)+ L4 j$ t2 G. R0 `+ l4 k# y
                        output = (lowpass_filter[0]+output)/2;
0 B% Q0 q& |& V                        lowpass_filter[0] = output;+ L  n7 i# [% I. m) H
                } else if( nFilterType == 2 ) {
/ I5 r0 b! v7 f. b/ U                        //儘乕僷僗僼傿儖僞乕TYPE 2(Weighted type 1)
! U, z% ?- A$ h0 r0 m                        output = (lowpass_filter[1]+lowpass_filter[0]+output)/3;
- q4 P( }% |+ |: W8 X                        lowpass_filter[1] = lowpass_filter[0];
0 n: @# U4 q8 Q, @& h3 I7 |                        lowpass_filter[0] = output;, ?- F7 T! V! ]/ q8 T0 [
                } else if( nFilterType == 3 ) {/ M- l0 d/ S4 Y
                        //儘乕僷僗僼傿儖僞乕TYPE 3(Weighted type 2)
1 W8 B# |4 w) {3 k                        output = (lowpass_filter[2]+lowpass_filter[1]+lowpass_filter[0]+output)/4;3 Q6 ^$ x; ]3 ^# i
                        lowpass_filter[2] = lowpass_filter[1];
. \& S) \6 M% V. b# U1 s% y                        lowpass_filter[1] = lowpass_filter[0];) d4 x  L$ `0 q- }* i( v
                        lowpass_filter[0] = output;1 U7 i! K" ^7 O" y
                } else if( nFilterType == 4 ) {
7 J0 _! s& C& W                        //儘乕僷僗僼傿儖僞乕TYPE 4(Weighted type 3)
  F0 |; n$ c% Y' ?1 e                        output = (lowpass_filter[1]+lowpass_filter[0]*2+output)/4;
+ Q$ H! T/ L! t& ~  ?: N                        lowpass_filter[1] = lowpass_filter[0];
4 r% p( Z. t: W8 Y8 Z) g                        lowpass_filter[0] = output;
  n  T" S7 B) H) c. _* f                }
3 ]4 p/ R  x! B' A
% e& E. E# a  V0 @4 c; j  f#if        0; j) u) @# q9 W4 t
                // DC惉暘偺僇僢僩
/ n" H4 x  v) ?( f                {: X* Y8 G. ^1 @- j' _
                static double ave = 0.0, max=0.0, min=0.0;
$ E( I$ i+ Y! g% l                double delta;
1 m5 h! `; X6 i7 H: i                delta = (max-min)/32768.0;
( F$ w% V  @$ ~; W$ s                max -= delta;2 ~6 N9 C6 d; p2 X. M6 I; w1 M& M- z
                min += delta;/ V& k, D' A& T' t7 a
                if( output > max ) max = output;/ t" V. Y8 t! `. V, I( n
                if( output < min ) min = output;
$ c( p9 {( N! D8 d/ _. _. P                ave -= ave/1024.0;$ Q" b2 R" z2 \( J: @
                ave += (max+min)/2048.0;
1 Q" ?8 G7 r4 ^7 y' L: ]% E                output -= (INT)ave;  o! \8 F- T5 k: K. W
                }' T) d# d, y: a9 ?
#endif
# p! X2 p! q2 Z2 H) F#if        1
# l8 X4 G2 j7 h$ k* }8 ?. V                // DC惉暘偺僇僢僩(HPF TEST)) l) u: P, G: Y* L% ~: b
                {
0 ?  Y6 j4 h$ m0 B# C//                static        double        cutoff = (2.0*3.141592653579*40.0/44100.0);: z. a' U! z7 s0 i5 r
                static        double        cutofftemp = (2.0*3.141592653579*40.0);$ \" z* k, ~- {
                double        cutoff = cutofftemp/(double)Config.sound.nRate;
+ ], f1 R/ Y' _! }) P$ g                static        double        tmp = 0.0;" m# u  ~1 A. }4 k
                double        in, out;
7 Y: f2 [; @1 V) T, n) t6 S/ o, V9 ~; E3 B) X
                in = (double)output;0 u) d$ j/ B5 A  |4 C: y
                out = (in - tmp);
4 y) |& |( x. w* a! g  Y                tmp = tmp + cutoff * out;
" k( O7 K; \4 q! [, t+ a! J4 y! Q' ]/ I) Z
                output = (INT)out;
5 J* I8 y$ r  Q                }
/ L4 J% p) O/ g#endif
4 @" Z% J! e" v#if        0- s. |5 D  V: y
                // 僗僷僀僋僲僀僘偺彍嫀(AGC TEST)
& Y/ _1 g4 y9 T0 {9 Y                {' U* i' {' Z. n0 F3 L* i' B
                INT        diff = abs(output-last_data);
5 A3 {9 i+ s2 q                if( diff > 0x4000 ) {) C4 k3 U% B& m1 G9 V  `
                        output /= 4;# B' @$ o7 S: \3 A* Y5 L
                } else * U' m7 e% P$ K' o
                if( diff > 0x3000 ) {% C: J3 X# Y. |. f& n( P2 e+ C
                        output /= 3;
" j0 j- Q% \( q4 K7 s- ]* R                } else
* E# s; n1 \. |                if( diff > 0x2000 ) {' z; p/ h& H0 _, h
                        output /= 2;
: K9 o5 T1 r; z) q                }' Z$ y3 q- }3 Y) s8 X4 K
                last_data = output;
8 _# @5 L3 R1 M8 E0 m, M                }
6 L! t, R# u) \#endif
( n8 r( R( q, i% b6 F                // Limit
! E  Z3 ?4 i, X8 X% u9 _                if( output > 0x7FFF ) {
2 w, J4 g+ k/ D+ L& G1 ?, Y5 b                        output = 0x7FFF;7 ?" s$ k. K, z* p4 I$ t
                } else if( output < -0x8000 ) {
* [0 f1 \, P8 H; k2 |4 q7 O                        output = -0x8000;
  n1 {3 Z7 h' V1 x, o4 T$ q                }$ }% e9 ^! w; F* r6 |

, ]3 o8 V1 e, R! Z) w                if( nBits != 8 ) {
; N, b0 N1 W8 N4 n. h+ K                        *(SHORT*)lpBuffer = (SHORT)output;
1 r' S- {( N# [) j$ w8 D                        lpBuffer += sizeof(SHORT);
& J# E! A1 k$ D$ v9 W9 z                } else {$ [4 V. V+ h# }0 Y
                        *lpBuffer++ = (output>>8)^0x80;
) Z9 x5 I( G1 s7 z$ X1 I                }( J" g7 I# }( s/ ]* ]# o. i9 }

8 ^& l0 Y8 [1 b5 u' W                if( nCcount < 0x0100 )1 g: F* v0 ?* i
                        pSoundBuf[nCcount++] = (SHORT)output;
. ]; ~, m6 w1 P2 h: J: K9 C' Z/ C" j& j+ c: y" g9 y
//                elapsedtime += cycle_rate;
: g, m* {0 F8 e- f, X                elapsed_time += cycle_rate;5 I% A2 p+ h" o: t
        }: J6 P6 C3 z4 a5 Q
/ c% b' v1 J  {. L. y
#if        1
' D3 l( p, q4 ]. r* y% z        if( elapsed_time > ((nes->nescfg->FrameCycles/24)+nes->cpu->GetTotalCycles()) ) {
- w0 N. }7 p4 g. r: f                elapsed_time = nes->cpu->GetTotalCycles();8 ^! j5 P/ {/ n2 U9 ~
        }+ ~" y" a+ K. d  O& i0 F
        if( (elapsed_time+(nes->nescfg->FrameCycles/6)) < nes->cpu->GetTotalCycles() ) {
6 W* V" P0 U. F; _# J) J( ]# k                elapsed_time = nes->cpu->GetTotalCycles();$ I- d7 v- z4 b
        }& Y1 w$ s* T. }
#else
& k) ~# v. |; s, w, G7 p: n5 ]* v2 _        elapsed_time = nes->cpu->GetTotalCycles();
0 o; H2 T3 S4 q#endif
+ F, W' V% m+ b) w; `& `9 ^}
8 O9 u  H' L) m1 |1 v6 S( x2 k9 [- o# s1 a1 M& p
// 僠儍儞僱儖偺廃攇悢庢摼僒僽儖乕僠儞(NSF梡)
8 _: N( t& D8 e# N% r: D9 i# t7 i" CINT        APU::GetChannelFrequency( INT no )/ G, s, z0 e* a1 z/ R) Z
{
1 y& Y* J7 D9 |6 G        if( !m_bMute[0] )
, l- u0 F' i8 x: q/ R- o                return        0;
0 U6 t- A/ x: N
5 H# i3 D; x5 e: z! Y/ M: u. Q        // Internal! R) _- K9 R$ ^+ p8 F9 k5 X
        if( no < 5 ) {- J* F* n7 f: v! Q+ e% I1 A
                return        m_bMute[no+1]?internal.GetFreq( no ):0;  P; ?. a: S- M8 h
        }  H( p, Q0 p/ o; E0 ]5 @: u
        // VRC65 t4 T! Z, @( s. @& Z
        if( (exsound_select & 0x01) && no >= 0x0100 && no < 0x0103 ) {4 s, v7 B0 D  e" u* \
                return        m_bMute[6+(no&0x03)]?vrc6.GetFreq( no & 0x03 ):0;
: _7 U. G1 t* Z6 Q  j$ T9 x( S( |        }  [* Y$ [$ y- G# J5 a8 N( D
        // FDS+ X: a! @1 h3 M
        if( (exsound_select & 0x04) && no == 0x300 ) {
$ |9 j. s. V/ i  K. Y                return        m_bMute[6]?fds.GetFreq( 0 ):0;
/ D5 v( ]& F! P% v: L) v+ P        }
+ N) S+ w0 Q1 M% F5 `        // MMC5" z; Z1 @( `1 M% D
        if( (exsound_select & 0x08) && no >= 0x0400 && no < 0x0402 ) {
7 W, C* S  L& t, M                return        m_bMute[6+(no&0x03)]?mmc5.GetFreq( no & 0x03 ):0;5 p5 g% w! v; G$ _  g
        }0 d+ s3 O9 q6 t' O5 x- Q7 f
        // N106
( H0 Z9 Q8 z: @& U* v: w        if( (exsound_select & 0x10) && no >= 0x0500 && no < 0x0508 ) {
# @& K* l5 [& L" d                return        m_bMute[6+(no&0x07)]?n106.GetFreq( no & 0x07 ):0;4 r% L) w& S  M3 b$ p% n& _
        }9 a/ |% p9 }& H
        // FME79 }) R2 c' z2 p9 c( e  [1 a3 _
        if( (exsound_select & 0x20) && no >= 0x0600 && no < 0x0603 ) {
3 }, X+ N$ ]& K& R9 S% T7 S/ F                return        m_bMute[6+(no&0x03)]?fme7.GetFreq( no & 0x03 ):0;
* d( `+ }" l* F5 Y- t        }1 A/ l  v" P! t9 H, G! b
        // VRC7
  E+ s8 g, L, q1 U. i0 g, `  _        if( (exsound_select & 0x02) && no >= 0x0700 && no < 0x0709 ) {
4 X. `  l3 g" R+ b0 p4 O3 _" \                return        m_bMute[6]?vrc7.GetFreq(no&0x0F):0;
8 P; p# q$ u9 ]; Y        }6 a3 P% ~- }* o, _6 p: f8 \8 F" _
        return        0;; _4 P4 U: ~" o
}& O1 S- i2 F1 X) O& _0 v) C" r
  {0 ~# m3 }, B7 @7 D2 i% ~
// State Save/Load
+ Z9 \( A# k8 v; w2 u" Qvoid        APU::SaveState( LPBYTE p )" C% `) d' A, w7 ~% u3 ~8 J  N1 e
{
5 y( D. M- q0 v* L6 F#ifdef        _DEBUG
/ R1 B2 q3 o. k5 LLPBYTE        pold = p;
) g3 T$ f0 u; N#endif
  b& v' h2 |( ]' Y9 ?
3 B9 E" j+ k5 h        // 帪娫幉傪摨婜偝偣傞堊Flush偡傞7 g. Q2 N7 h  o) `$ E
        QueueFlush();0 ~% K6 R. F7 ~& l  G- E
' s9 P1 c6 p4 M
        internal.SaveState( p );: ?/ `7 j6 y' K# E' B0 B
        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding# k6 P1 S! k5 u; i" W

1 I# J% Z! ]9 ^        // VRC6
" A0 r! L( R# O% b* {  B        if( exsound_select & 0x01 ) {% W0 i0 I# Y  P* P
                vrc6.SaveState( p );2 @0 T. p7 B( E& i
                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding
3 \& D. I6 B9 ]9 S, q/ _, W/ D5 T        }- f' S  d8 ?5 R( G' v; S) h
        // VRC7 (not support)
- W( c, Y% U( o+ P        if( exsound_select & 0x02 ) {
+ g. c$ W0 I! x( i                vrc7.SaveState( p );
( G) u+ V9 ^8 L                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding6 e( Y1 U: t2 F% q, U, {
        }- x% W& P: @# g3 u  q- J
        // FDS% ~& X+ L" l5 O
        if( exsound_select & 0x04 ) {+ U" h( a  H9 @( N
                fds.SaveState( p );: S* q# h1 _- _
                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding
+ j, \- g) n1 ?- x        }
" H5 P7 F  P$ u5 g' I2 Z& G) c        // MMC5
* o9 `% i: n0 K7 s        if( exsound_select & 0x08 ) {5 `" x1 L* T' i# f6 [* S
                mmc5.SaveState( p );
" \3 v, [/ y  Q- y# G1 Q% Q0 N+ v; _                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding. c( f. H7 s: u2 E) O+ U  t  A! \* L
        }
2 r8 N- c( v# @! d7 X& s- Z        // N106
# T; T, w2 |" i! |5 S' Q        if( exsound_select & 0x10 ) {, y% d& B5 t, q8 I2 ?
                n106.SaveState( p );
  [. H; z* C* H0 O& x0 R                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding, t+ D8 X  R) _% M' \: P* n# w4 ^
        }
" B* b2 f- G, O1 U& i5 X        // FME77 A+ B- o  \9 h
        if( exsound_select & 0x20 ) {
, x/ N6 D  a: _9 B                fme7.SaveState( p );
& S* S7 Q, V  g/ h                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding
, @2 c% |5 O( f# S* o, e( H; g3 }        }
* g! U6 h" X5 o( G6 z6 C2 A: [& Z, O: _" i& y+ Z: H% ^
#ifdef        _DEBUG0 g/ d9 @9 l' ]( \/ s
DEBUGOUT( "SAVE APU SIZE:%d\n", p-pold );% V2 d) F4 |8 X  [- b5 J. ^4 x* O
#endif1 Y) }$ K  w" h7 u
}
3 C1 d& y$ v, Z2 P( p1 ]' s$ C2 V) ^$ K% T  ^6 ~9 N/ j+ f
void        APU::LoadState( LPBYTE p )
6 J) d+ [) O8 A{
$ N4 |3 Z0 b0 j9 T; c        // 帪娫幉傪摨婜偝偣傞堊偵徚偡
- k  t1 O5 t" r% [/ s( j8 A        QueueClear();% B8 Q) j. ?2 Z% ~* O2 |  N

# [* O/ j1 N+ F9 D  Q        internal.LoadState( p );
& O& e3 u0 L1 r! s' p- @0 c9 d        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding
1 B. {1 K( y; _4 ]
$ Y2 b" w, R- N& Q8 ?) e0 w1 z- b        // VRC64 P% L/ g% o$ b. d& D5 ^/ ]
        if( exsound_select & 0x01 ) {. A7 Q; ~" e3 Y
                vrc6.LoadState( p );$ r- C7 E9 H4 h; u
                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding
9 k4 _) w; ^/ H- |        }$ f+ U: j3 L7 s* T0 h! d. A
        // VRC7 (not support)
& U5 B3 H6 s' X9 g        if( exsound_select & 0x02 ) {% c" t9 Y8 b9 i+ Y( |' W4 Q
                vrc7.LoadState( p );" a4 t- _5 y8 y+ @2 e; j. ]
                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding
4 n; p) Q& h, X- Q3 m        }
' z1 r' \% U$ }, i# I5 C        // FDS/ C3 J! `' ]  x# k
        if( exsound_select & 0x04 ) {+ L) P8 M1 C# l" s. S# \
                fds.LoadState( p );
! f4 c( Z0 n4 n. P' i: d# `% s" Y                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding/ G9 f! x. y: i/ Z9 Y
        }
+ W8 V( g# O: e: o        // MMC54 o+ k# B  D6 E9 [$ Z" G& l
        if( exsound_select & 0x08 ) {* D0 e: ^5 d2 Z7 l$ t. S
                mmc5.LoadState( p );  S9 s: b* M& z3 ^; b2 o
                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding5 s" [! v6 L, W/ w5 _
        }
0 [2 W* @& p9 z5 J        // N106
6 M) y$ T9 e+ `6 c        if( exsound_select & 0x10 ) {
% r3 J5 ]" g/ B                n106.LoadState( p );; Y$ D1 ^. W" A; b0 a$ H1 L
                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding
( N2 C' {1 @9 k- m) @: b        }
+ p( K: ]6 l6 h% u4 q0 v* H6 N        // FME7
, p0 N) o* A0 X1 a        if( exsound_select & 0x20 ) {
) K. \9 p9 @5 F                fme7.LoadState( p );
  C9 r' u! O; y& b( P* ?9 |                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding# H& Y- l  a# L# G! ^2 S
        }
; F' Q( v  }6 g6 H8 N}

该用户从未签到

发表于 2009-11-8 17:25:37 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 14:38 发表
3 f. ]1 b/ o7 ]& H可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。, s2 z$ L0 V6 w0 r' c. n
感激不尽~~
: T2 j8 X" e# ]; N# q
恩 我對模擬器不是很有研究,
  v; X& }/ H9 Z* t, a1 T) h* B雖然要了解源碼內容,可能不是很困難,
6 c; G; ~) g+ p0 r不過還是要花時間,個人目前蠻忙碌的。" V$ L4 e9 D! m5 l' ]  u  z& Y+ J

+ c7 A2 p* E, H0 d給你一個朋友的MSN,你可以跟他討論看看,
. p2 l, J4 g6 S$ @: \1 b( t$ J6 n他本身是程式設計師,也對FC模擬器很有興趣。
+ F9 j! H) \8 |  p% q
' e! b- s7 Q8 \( q" \MSN我就PM到你的信箱了。4 {" {1 s- v( I0 V5 f0 v  ]

& y/ [5 i( v8 U' O. R' f  w8 S8 E9 {希望你能有所得。

该用户从未签到

 楼主| 发表于 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 发表 , n1 Q6 B# C) u1 j
呵…… 谢过团长大人~~
* L' I/ g% w+ d3 ?& W5 q
) {, C4 M! |( `+ m- l
哈 不客氣,算是順便幫他找個伴,大家可以一起玩。

该用户从未签到

发表于 2009-11-20 13:14:53 | 显示全部楼层
原帖由 李伟 于 2009-11-9 16:02 发表 # ?3 `! c& ]( d" X( c( s
团长的朋友都是神,那团长就是神的boss。

6 g9 F; u: S$ r, v+ e哈 不敢當,我只是個平凡人,; N2 r  j" Q0 A
要吃飯喝水,光吸空氣是不會飽的。。。。 :)

该用户从未签到

发表于 2009-11-20 13:32:35 | 显示全部楼层
FC模拟器的部分有个人可以帮你忙
( Z" X3 t0 ~1 N# QZYH  w8 |7 W/ ~; J8 C+ x
QQ:4147343064 r4 R, A& F9 k3 _2 o7 c! ?
Mail:zyh-01@126.com& x0 A& g6 ~9 B

4 ]2 L  S" s: g$ I' F) D& X5 Z. w他是ZYH Emulator这个模拟器的作者,只是他用的开发平台是VB,不过就6502的实现原理来说是一样的

该用户从未签到

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

该用户从未签到

发表于 2009-11-27 19:09:06 | 显示全部楼层
原帖由 独孤残云 于 2009-11-27 09:48 发表   y2 D3 R' d- y
再次对团长大人和悠悠哥的无私帮助表示感谢~~

: v( _  n: l" d0 R: r. @) X不客氣  ^_^
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2025-12-18 12:30 , Processed in 1.069336 second(s), 19 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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