EMU618社区

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

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

 关闭 [复制链接]

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 09:56:34 | 显示全部楼层
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。$ X% B) y9 V3 [" q( `
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~* @4 H" ]+ B) y) x. {, r
这里有相应的模拟器源码,就当送给大侠了~~0 v( L4 `. W6 L/ ~
http://kenkao.qupan.com/5096520.html

该用户从未签到

发表于 2009-11-8 11:31:10 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 09:56 发表
+ p2 \$ B" ?: F! f0 S; K: Z能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。3 [9 m: w5 N2 k3 y
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~2 |7 r% L+ [3 l" i, w
这里有相应的模拟器源码,就当送给大侠 ...
" l9 u+ Q$ G& ?' Y& e2 _0 q6 b
聲音部分(Audoi Process Unit = APU):
7 O1 I9 ?. T+ u& e7 B.\NES\APU.cpp
/ k; q7 H% Y" t; m5 `.\NES\APU.h3 f7 Y! j2 z' E- e( O9 w

% M( u) ?" j8 x- D+ f& F9 d  u" R+ K7 D
影像處理部份(Picture Processing Unit = PPU):
" x2 t" w0 {; o.\NES\PPU.cpp; I  j" t$ a, A; |
.\NES\PPU.h+ G4 k8 g$ H9 x7 [) u0 g! ]

( {3 Y- o1 q. j9 ^如果原碼用C跟ASM混搭也不錯

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 14:47:50 | 显示全部楼层
这是我手中源码Apu.cpp的内容,敬请赐教:
- V+ b  G8 V1 ^; x(由于很多专用术语和算法机理都不明白,所以看不大懂……)5 |. p6 ~" ~9 y5 H' v4 `7 m* A- [
//////////////////////////////////////////////////////////////////////////& }% A/ S& G% D* r3 c  O
//                                                                      //
2 Q6 X: t$ e: I//      NES APU core                                                    //
" K5 G; j* G& @* X% m/ v/ ?//                                                           Norix      //
% E3 }$ w+ H* Y6 N  T//                                               written     2002/06/27 //
' t; |6 @7 W6 t* ]* x//                                               last modify ----/--/-- //
7 ?3 x3 w8 `) ]//////////////////////////////////////////////////////////////////////////
1 u, T8 [! S+ O3 E7 A% _+ ~#include "DebugOut.h"
. D2 n, X2 M! {! ]  T#include "App.h"6 g. i0 _! s# Z
#include "Config.h"
9 q4 ?; j4 v) h7 {% a/ y8 o- X; r6 F. a( H* I1 o# [! c
#include "nes.h"6 I' X2 O/ ?5 D& C8 V
#include "mmu.h"
7 G9 q0 O' T' ^! n2 s#include "cpu.h"- G/ Q1 u9 a) p  S+ v$ n2 n
#include "ppu.h"
" m# O1 P1 d7 z1 l4 m4 ^0 a0 g#include "rom.h"
7 p, l$ Q" X2 |( f( N+ N#include "apu.h"
7 A+ d& C1 J( j& X# [# ~/ |  Z9 _2 s" a7 L# L/ [9 |$ @: M
// Volume adjust
+ H$ M. t; y9 r8 V// Internal sounds- [8 Y  p: U( k
#define        RECTANGLE_VOL        (0x0F0)# J9 `% L2 \. _
#define        TRIANGLE_VOL        (0x130)5 J* l' _# B- f
#define        NOISE_VOL        (0x0C0)3 V# k8 f2 d3 F+ V+ v
#define        DPCM_VOL        (0x0F0)' S6 ?% Y! r% o: U6 j
// Extra sounds
$ F( y  a1 o7 @  N6 j' G( c* V. H# _#define        VRC6_VOL        (0x0F0)( ?# [  q& n  ]4 ~4 H1 _
#define        VRC7_VOL        (0x130)
3 o* E; g) u6 e0 {& d; l8 `8 z" [#define        FDS_VOL                (0x0F0)! @) M3 c  _0 b1 _0 N# g* R
#define        MMC5_VOL        (0x0F0)
2 ?8 f5 A; |) h/ Z#define        N106_VOL        (0x088)
4 w$ `0 M& |' n  W8 {$ G1 [3 A#define        FME7_VOL        (0x130)4 ?0 r, `  V0 X" c  U/ I4 Q: v
+ P% e0 z- Y+ F; p1 K
APU::APU( NES* parent ); T  ?) u9 ^3 k. W6 e3 ?
{0 n) T# {( K* \8 y" _5 X4 x0 X
        exsound_select = 0;( T/ P- H( `- B  U- \

5 p( C3 O: K) }/ O" g2 ?        nes = parent;
& X1 r0 W* v1 T- T0 s# Y        internal.SetParent( parent );
. S& Y9 }1 G& ]$ {5 X. T# G& q7 q4 g
        last_data = last_diff = 0;
9 c$ w; U' _. M, r; D1 [. R9 `7 @% d: L- d# Q# L! H* p! Y( h" ]
        ZEROMEMORY( m_SoundBuffer, sizeof(m_SoundBuffer) );% }7 ]& G+ {! X% _( X
$ D5 q* C, I0 W) V' _; ~
        ZEROMEMORY( lowpass_filter, sizeof(lowpass_filter) );
) J& T6 b0 H: ~9 E0 x        ZEROMEMORY( &queue, sizeof(queue) );% q( e0 z; J$ ~* n, E
        ZEROMEMORY( &exqueue, sizeof(exqueue) );
* T2 ?0 [" V7 \8 m. y
1 i5 R6 j# e5 m4 u! n. e; G  d        for( INT i = 0; i < 16; i++ ) {
2 j( g3 R& |" `" s  `; F                m_bMute = TRUE;5 z8 W3 |" K9 @* a) u
        }
  b+ }( X* s# U}! d9 Q# c. }; s" V; c' v- R. F
) H' S3 F7 E, @, C
APU::~APU()
, \2 G9 {4 ]) T{  o7 v0 X; N  w& w$ z1 B0 Z$ Q3 A
}" L% c$ S, b! A+ w/ j( b
2 N8 ~4 G6 I! Y' `6 C% F/ g
void        APU::SetQueue( INT writetime, WORD addr, BYTE data )
* G* ?1 n2 t; m; @{
/ h* Y! O$ v  c$ U        queue.data[queue.wrptr].time = writetime;8 ]3 J) s9 |( P& F
        queue.data[queue.wrptr].addr = addr;
. a# I$ N7 n  Z- N        queue.data[queue.wrptr].data = data;3 ?1 i. t% r% C) q' i% B
        queue.wrptr++;( `$ z7 H& n) x3 e( ^1 z
        queue.wrptr&=QUEUE_LENGTH-1;! j7 t5 c1 q, ?3 \% D: p
        if( queue.wrptr == queue.rdptr ) {/ U+ A6 Y# C2 c
                DEBUGOUT( "queue overflow.\n" );" V0 |/ Y0 K: N0 n5 z: q
        }2 f. L" d, x$ ?: H% X$ r3 E3 f; `* m
}
9 E4 ~# C$ s; `* g: q& a4 B  f( a: Q4 k  N
BOOL        APU::GetQueue( INT writetime, QUEUEDATA& ret )
+ h) s* f& a5 a' M% z5 J* I: o{8 f2 `/ R! j! \6 N
        if( queue.wrptr == queue.rdptr ) {
  [9 G! _, h6 s  @                return        FALSE;2 q6 m/ T* H3 G
        }* @. z5 U- [6 o
        if( queue.data[queue.rdptr].time <= writetime ) {
. ], \# I" D: L) l5 J2 g, p2 J6 Q# f                ret = queue.data[queue.rdptr];4 h" D' q7 ~% f+ U$ |* _/ V
                queue.rdptr++;
$ \2 {) F- {  m5 i4 U                queue.rdptr&=QUEUE_LENGTH-1;
4 ~" S# R' X4 o0 r2 I5 e2 }: }                return        TRUE;  D8 |, }: k1 O
        }! \- W2 Q9 {# Y/ J+ f. p
        return        FALSE;  u% ^6 H: M, I+ {# B
}9 P- `/ e* m- r3 p: w

5 H5 N( D: i( U7 s2 j# [void        APU::SetExQueue( INT writetime, WORD addr, BYTE data )+ g( m  F! \0 ?8 T" D9 b% h
{
/ r; M( K4 G7 l        exqueue.data[exqueue.wrptr].time = writetime;% X0 z5 O/ {# p; W* R; E
        exqueue.data[exqueue.wrptr].addr = addr;
) y2 m1 N( r" {  M" ?. d        exqueue.data[exqueue.wrptr].data = data;
/ b* r& Z( @; h6 t8 n        exqueue.wrptr++;6 E7 R$ q9 P( m
        exqueue.wrptr&=QUEUE_LENGTH-1;
% x" v5 x/ \2 e        if( exqueue.wrptr == exqueue.rdptr ) {
8 H- Q' I5 T! O; J& K# E  _                DEBUGOUT( "exqueue overflow.\n" );0 F5 R" l4 P6 G& w5 `. {+ K
        }5 q$ a# T4 i8 W* b6 e
}
( _% C$ {# |2 O6 C6 X3 Z$ _1 K
: [3 E1 o. @% |# u4 Y2 T' \* b4 N: bBOOL        APU::GetExQueue( INT writetime, QUEUEDATA& ret )4 j  }3 e& w8 M5 @; `4 G6 p- Y8 ~
{; Z$ ?( L& _, v6 u6 U# `
        if( exqueue.wrptr == exqueue.rdptr ) {
% M4 k0 B) J% q                return        FALSE;7 e" \3 L6 q, ]2 J- C6 D
        }% J7 ?; ]8 C$ n; O0 S: o( R
        if( exqueue.data[exqueue.rdptr].time <= writetime ) {
8 u2 K% F" k# `                ret = exqueue.data[exqueue.rdptr];
: t$ k7 e8 f1 z1 P& F4 s1 E4 E! y                exqueue.rdptr++;
/ B3 o2 |& @1 D) x+ H                exqueue.rdptr&=QUEUE_LENGTH-1;2 O+ R1 @! M7 L+ U0 k3 g7 i& @
                return        TRUE;
. \/ [* Q9 P7 i        }( c; _$ U( _6 G: N  W8 ~
        return        FALSE;
: ]/ X0 b# P; A  C}
2 J% t/ ^! M' d* Q  B7 A1 p9 a6 Y" z$ f* K9 V1 u
void        APU::QueueClear()
$ ]8 F% H$ P4 h  j" N5 N% U{1 U/ S! q( S/ y8 ^& t$ @4 B- I3 N
        ZEROMEMORY( &queue, sizeof(queue) );
8 M' X0 q7 O2 C0 J4 x( g        ZEROMEMORY( &exqueue, sizeof(exqueue) );4 g$ C2 d7 ?/ X' b
}
/ z4 Q! f7 |) q1 i% o/ g; G% z5 \; g# C2 @( J
void        APU::QueueFlush()$ w3 q& P" N' u7 ~7 O
{
% e+ }4 l8 \3 w" R) I        while( queue.wrptr != queue.rdptr ) {, l- y, M& G7 K$ S
                WriteProcess( queue.data[queue.rdptr].addr, queue.data[queue.rdptr].data );8 p( s; s; v$ d
                queue.rdptr++;+ z8 ~' d0 M0 `9 I3 z
                queue.rdptr&=QUEUE_LENGTH-1;/ ?; g+ I0 ]) @/ T$ X
        }
9 {/ G4 V7 b+ X5 ~* }. H- L5 m
1 j+ {6 H7 X5 d+ J  X        while( exqueue.wrptr != exqueue.rdptr ) {2 Z7 m0 z+ @. I2 A  p$ W: c) b
                WriteExProcess( exqueue.data[exqueue.rdptr].addr, exqueue.data[exqueue.rdptr].data );3 t) w! b& Z" p# c
                exqueue.rdptr++;! Q. R3 _4 Y: r& J7 N' ~* V! N
                exqueue.rdptr&=QUEUE_LENGTH-1;2 R- G% Y+ S4 T/ {- y$ r
        }
& K: J( O& H7 V9 d# r2 v}" \, U. n8 h( D3 I6 x- T) P) c
3 d+ C( x' Z5 t% ]5 k8 R) }
void        APU::SoundSetup()4 l: j$ d2 e/ Z! t' c; W
{
% {* d/ b: z0 I7 s0 U! J4 Z        FLOAT        fClock = nes->nescfg->CpuClock;
$ w: O- T& n" X2 m# P: I, w3 p* h        INT        nRate = (INT)Config.sound.nRate;  k9 N) ]) \9 m. L
        internal.Setup( fClock, nRate );! h* [0 Z4 n8 o5 M0 x: {
        vrc6.Setup( fClock, nRate );
+ }0 S  J4 _5 v7 i' N8 ]$ A+ F        vrc7.Setup( fClock, nRate );
1 {# q" n9 ]. l. f* m- W: X9 @        mmc5.Setup( fClock, nRate );
. B9 V7 z& N" k& l        fds.Setup ( fClock, nRate );3 ?. V& h. ?$ C9 Q
        n106.Setup( fClock, nRate );( b+ f% \# o6 _8 @. w% P
        fme7.Setup( fClock, nRate );
: X9 E- n! p2 A3 W}4 i0 j" i; M( P1 k1 T

- [2 @6 L+ w2 x# qvoid        APU::Reset()! }) Q0 c7 F, P5 }) m
{
0 P. R  A' X, @* Z5 p* W/ Y- C$ [: ?        ZEROMEMORY( &queue, sizeof(queue) );
# F; _$ a; V- v3 M7 \' a( ^' F        ZEROMEMORY( &exqueue, sizeof(exqueue) );7 ]- w3 j9 [  C' S3 o5 A

% N  ~8 u' q& Y, ~        elapsed_time = 0;
- _) I1 V! {/ y" C9 a9 w
( N% p5 Y$ p; h' b) t        FLOAT        fClock = nes->nescfg->CpuClock;# u& r; w. L# l; h+ ^
        INT        nRate = (INT)Config.sound.nRate;( B2 f" ]" I& [5 F* g$ u
        internal.Reset( fClock, nRate );
+ s, n( |1 r" i3 G3 W" \        vrc6.Reset( fClock, nRate );
* j$ E) Q; [6 t        vrc7.Reset( fClock, nRate );& e. L  O: P8 j1 z, g
        mmc5.Reset( fClock, nRate );' W; s; B8 e& P2 @& S; T
        fds.Reset ( fClock, nRate );/ }/ {$ P" _4 g/ `2 g
        n106.Reset( fClock, nRate );
6 ?9 y# c) W- \; W- [1 G% q( e        fme7.Reset( fClock, nRate );
3 H' H+ P/ D& {8 j3 h
; {3 j9 u) @% U2 N        SoundSetup();
* S/ C1 f  O4 v* @}$ N7 Z/ y, }3 D: O- v- H: D6 W
  h% x, b3 _2 y1 ~' O- G3 C
void        APU::SelectExSound( BYTE data )% n; Z* [0 j/ j  x' D
{
& |- i. q6 t5 K1 H  `        exsound_select = data;3 i; I# t5 q# v
}
$ I- i' M) L. R3 m% i
- Z7 d( ?7 ^$ L, _BYTE        APU::Read( WORD addr )1 o# K3 w( V8 C
{
) m1 |. t8 o6 C/ a% T# W9 N1 Q        return        internal.SyncRead( addr );
& G. B' g& a2 J1 I}
* P; |: R2 Q2 I& s* _
; h, q1 |1 F* O4 F5 Q5 x8 m' wvoid        APU::Write( WORD addr, BYTE data )
6 z0 B& P  i% C  d{
$ q: [1 Y1 e: t0 @; L# W3 U& n' b: x        // $4018偼VirtuaNES屌桳億乕僩
0 {, U7 U$ S& o        if( addr >= 0x4000 && addr <= 0x401F ) {' y6 r" d5 d3 c# m; s! J6 s
                internal.SyncWrite( addr, data );
& ]0 G: @* Z0 V9 H7 y  h                SetQueue( nes->cpu->GetTotalCycles(), addr, data );/ j* Q4 y/ f9 A) m6 f
        }: E/ J4 Q3 ^/ q6 [+ }
}
. t6 [7 O% [; S  g! _, T9 Y6 `
  b$ I' n$ S+ PBYTE        APU::ExRead( WORD addr ), T3 x  R) t% {/ G' q# {
{
9 }( U1 f9 R1 N7 X. b( l; ~BYTE        data = 0;
, [  c% o1 x1 c
/ t5 }* a' m) V8 w) n, w0 k        if( exsound_select & 0x10 ) {+ E* I$ s0 Y$ d+ M
                if( addr == 0x4800 ) {
: m% {, z0 j$ Q9 g" y. I5 [                        SetExQueue( nes->cpu->GetTotalCycles(), 0, 0 );* I  I, q, U1 `
                }# H% l/ W7 l* q8 {
        }
+ c( J+ V1 k' V- O. [- V2 X/ t" @% {        if( exsound_select & 0x04 ) {
7 [) H5 f" m: [9 u* t$ [- k                if( addr >= 0x4040 && addr < 0x4100 ) {1 Y8 H' o5 }6 e
                        data = fds.SyncRead( addr );
# L3 G* F3 r: A  j: D                }8 ]# }% i" \5 k; w2 a) P- H1 O
        }
( ]* \+ d% y( F/ p* f7 ~$ K        if( exsound_select & 0x08 ) {
; Z6 m: ]4 Z! Z8 [                if( addr >= 0x5000 && addr <= 0x5015 ) {
9 h- w: L. h* ?; H5 l# Y                        data = mmc5.SyncRead( addr );
2 _+ [) _) N  X2 U                }2 x& H+ w: J! n0 D6 J
        }( p: n/ ~2 \( S
8 H& T9 ]6 |, E
        return        data;* _0 V0 s0 K8 x0 C( t/ ^
}1 ~  N. Y  a6 L$ _9 C

" M7 s) E0 d% K+ q+ r' }' y4 ivoid        APU::ExWrite( WORD addr, BYTE data )3 v5 P$ E# y( e0 i7 z$ T: a: X
{
/ y* e" c! k) V9 F        SetExQueue( nes->cpu->GetTotalCycles(), addr, data );8 y. Y* B; k  k

4 M) ^7 v* h( ~; ~0 H: f# m        if( exsound_select & 0x04 ) {
% \( B+ e0 l" X3 [                if( addr >= 0x4040 && addr < 0x4100 ) {, K! V6 b; i2 ?0 t  F
                        fds.SyncWrite( addr, data );
8 G' w" ?4 |% }  H+ d7 l  o                }+ l& W3 T$ S3 @4 r  q2 Z
        }
' Y6 {- y+ x' {' G: i6 Z
- P7 V, ]5 v1 z+ w. e        if( exsound_select & 0x08 ) {3 L8 U: B6 M: g5 L6 s
                if( addr >= 0x5000 && addr <= 0x5015 ) {  l8 o, Z9 y# x$ ^
                        mmc5.SyncWrite( addr, data );
% a3 Z5 y. ?, M( n, e+ ~; W                }" f) z. e; j, c
        }5 l1 R: w4 W' `$ E' ]5 @+ K
}2 l: c7 t' A0 t5 Y/ {& }
/ _3 n( w; T' S1 e6 W& k: ~' s
void        APU::Sync()& J" H9 b' A5 @( l: q- C
{' ?2 k. [( q/ h
}
# h9 ~0 m" f$ o- N! \+ t
: b% J2 \, D. \3 }( t7 f/ Cvoid        APU::SyncDPCM( INT cycles )& |. s& Y( }: V) G. W: {
{
: M% m: a5 I$ P8 M( j        internal.Sync( cycles );
# X9 A0 E7 M& S' y5 D
" ?3 @' w% V( P- [, B. s        if( exsound_select & 0x04 ) {
( w4 t- D3 w6 D/ }7 j! H( `                fds.Sync( cycles );6 I7 n. k. L7 G. E
        }' j4 ~# Q/ G/ K
        if( exsound_select & 0x08 ) {9 E( T5 ~$ b" U3 m
                mmc5.Sync( cycles );
; g' o8 O- @. Y        }
9 K- [1 j; F0 x6 ?2 A}
# Q1 r3 \7 E$ z  U
. p. [* }3 }# j, x9 q  g" Avoid        APU::WriteProcess( WORD addr, BYTE data )& m$ W( t. P+ B4 B- w* O
{4 k& L0 @. c% k& Q
        // $4018偼VirtuaNES屌桳億乕僩5 L. t$ m  [) v7 F  v- k
        if( addr >= 0x4000 && addr <= 0x401F ) {0 ?) ^. k! s* t- p6 H
                internal.Write( addr, data );& C4 o% t/ Z. h- c% E/ w4 ]9 j9 J; J% W
        }2 m- E$ o5 O6 n) ~, \
}
, d* j" n8 y9 g  Q, I! S+ b: |; }2 P% @6 j7 D
void        APU::WriteExProcess( WORD addr, BYTE data )
: C0 F) i, d5 S9 v' s) d{& G( v! ]: R" X" N
        if( exsound_select & 0x01 ) {5 W, e( E  T" K9 }& Q
                vrc6.Write( addr, data );% ]1 q. R2 X- ]) S% W$ [4 N
        }
( ]0 l; z  X$ s% s. a  b        if( exsound_select & 0x02 ) {
6 \  I4 q1 ^( g. B) A                vrc7.Write( addr, data );$ S# p7 ^3 m  }$ B1 y; a4 v. C
        }
! `. O: d9 `! L  Q8 {2 M! `        if( exsound_select & 0x04 ) {. s! e' g9 d4 l8 ]0 k7 F
                fds.Write( addr, data );
9 _& s4 z, L* d1 }. a        }# }. w3 U# l' z3 _6 z
        if( exsound_select & 0x08 ) {
* r1 M. G/ W) B2 K                mmc5.Write( addr, data );5 M( ]7 J$ t9 n& r
        }
# f3 C5 j6 S3 {, H        if( exsound_select & 0x10 ) {! U7 {7 u7 J& e) o3 O
                if( addr == 0x0000 ) {! w* |) ]2 F! Q, H/ j
                        BYTE        dummy = n106.Read( addr );
  a* [  s, v: H3 _& h                } else {6 X9 K# R) |7 ~0 p: ^' j$ Y
                        n106.Write( addr, data );, \1 h! d3 Z) U( u# w0 A+ f
                }
/ M+ M0 U2 S7 F. ^) I- D# W        }8 ^$ ~. \. F5 ?7 o5 i
        if( exsound_select & 0x20 ) {
/ C; s! u5 j: V( N+ E                fme7.Write( addr, data );. T+ p( W: ~9 ^- V
        }
( O/ W  g6 R9 h' l0 m7 J}: G# ^. C: {( g

  W1 l) [" F4 {+ }; E3 V/ zvoid        APU::Process( LPBYTE lpBuffer, DWORD dwSize ). \/ _" n2 ^! T; ^' n3 L
{: I4 q  J/ K' h. a
INT        nBits = Config.sound.nBits;. A# O: W/ e" J4 q- f( e- \- `
DWORD        dwLength = dwSize / (nBits/8);
' u9 w  A' V6 ?6 cINT        output;
% H( b$ K& S0 z7 M$ a6 z% |1 qQUEUEDATA q;) P( i& ?8 R4 R. A
DWORD        writetime;
, z- n; V9 p0 H% ~. W- x8 Y& g" p) v# n& b! V6 F
LPSHORT        pSoundBuf = m_SoundBuffer;0 W1 z5 ?4 _: P6 N( E  a/ B
INT        nCcount = 0;
5 W+ H( S9 S1 i: Y6 m9 G  z8 E9 d/ A5 y( g0 B" O1 k% U
INT        nFilterType = Config.sound.nFilterType;
; U! M% |# f) R* V, O: H: r8 B+ D3 {% l- e9 |' ]
        if( !Config.sound.bEnable ) {; A$ W3 T5 m* B/ A6 {7 U; T' ~
                ::FillMemory( lpBuffer, dwSize, (BYTE)(Config.sound.nRate==8?128:0) );5 E& V! |; p8 `' r2 w( T, u
                return;  H# ~' d) n" z  @" p' s4 Y
        }
7 D+ I  @) {1 X3 I
! c$ A4 J% Y4 w5 O        // Volume setup
9 ?4 L; y5 f8 C  S        //  0:Master
  \; d2 A# R7 I3 t        //  1:Rectangle 1
, w! P" X# |2 ^( v# o: }7 x) g) v2 |        //  2:Rectangle 2+ J  ^4 v  O& u, y8 Z: @
        //  3:Triangle4 [/ U! R4 j1 Y( Y" ?. u
        //  4:Noise
% f: E$ v& f1 O. f        //  5:DPCM, g% k9 B6 d$ p0 Q
        //  6:VRC6
) o3 Q# S- z& \! |        //  7:VRC7
6 Y1 N& o8 L/ N  l/ m        //  8:FDS2 W- l1 }2 W* H9 J
        //  9:MMC5
  Z' m# _2 B6 W. V: P& l        // 10:N106+ d. P: ]4 E) G) |7 b" w
        // 11:FME7
/ o" _* s, L6 c, r/ u9 t; g3 I# ~        INT        vol[24];
+ K1 o: q7 V4 v/ ^- f0 _        BOOL*        bMute = m_bMute;
6 X; U; k. I; v1 m- O; G' l0 I9 w        SHORT*        nVolume = Config.sound.nVolume;- j+ o+ r6 D3 L9 H5 \( i) \) f# ^. v

, e2 l2 x! E9 _+ f3 y: \        INT        nMasterVolume = bMute[0]?nVolume[0]:0;3 @% F4 s9 ~1 L

4 p9 D7 Q) h; `( F& N        // Internal
8 Q6 \. z4 \1 v$ D* F8 V        vol[ 0] = bMute[1]?(RECTANGLE_VOL*nVolume[1]*nMasterVolume)/(100*100):0;# S! v" \+ x4 `
        vol[ 1] = bMute[2]?(RECTANGLE_VOL*nVolume[2]*nMasterVolume)/(100*100):0;! E% D( V8 p( _/ c/ a0 J
        vol[ 2] = bMute[3]?(TRIANGLE_VOL *nVolume[3]*nMasterVolume)/(100*100):0;
' @5 Y. s# q8 ~2 s/ G        vol[ 3] = bMute[4]?(NOISE_VOL    *nVolume[4]*nMasterVolume)/(100*100):0;" ?4 C( l; l" k! d/ [  k" F( K6 P" e
        vol[ 4] = bMute[5]?(DPCM_VOL     *nVolume[5]*nMasterVolume)/(100*100):0;
. u' {$ X1 F, f. f) D' B8 s
+ f  q5 I0 i. o1 b+ Q* n( b        // VRC6
$ p- K0 ~3 j! a% `& A: K: g        vol[ 5] = bMute[6]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;" B8 }5 B# o+ m+ Y8 I
        vol[ 6] = bMute[7]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
" n  b9 v$ X" U2 Z0 m. Q        vol[ 7] = bMute[8]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
6 p( i) N: l$ @( n3 m$ b+ P
  X& U% R3 A6 w1 J        // VRC7
9 ?* i; R" U1 J; X$ o4 B" q& q        vol[ 8] = bMute[6]?(VRC7_VOL*nVolume[7]*nMasterVolume)/(100*100):0;& L4 u' J) P! O
: o+ p, A$ D( w3 d" s# s
        // FDS) w3 Z5 V, ?  L% d+ T1 x' e
        vol[ 9] = bMute[6]?(FDS_VOL*nVolume[8]*nMasterVolume)/(100*100):0;
/ L& h3 ?; s  L/ z/ j4 M/ g% I" w/ T7 I5 {
        // MMC5& n7 ~4 Y1 l' R& U
        vol[10] = bMute[6]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;: }( v! m  S5 C& j
        vol[11] = bMute[7]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
" K* x; r6 B; z, A3 b% i# D( v& e        vol[12] = bMute[8]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
8 T& P4 Z- ^' v0 L9 W4 h1 J5 m0 d% w5 h/ |$ O. U
        // N1068 U/ ?7 L* g1 a8 E- i+ O' Q
        vol[13] = bMute[ 6]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;1 R% }1 E4 r9 m
        vol[14] = bMute[ 7]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;1 _0 S+ C' }: n/ J4 v7 i  X
        vol[15] = bMute[ 8]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
" G" _* J! D) t+ |2 b4 o3 J% f5 x        vol[16] = bMute[ 9]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;* R3 \: T: U- f/ S
        vol[17] = bMute[10]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;* T# t5 j, N; \0 D
        vol[18] = bMute[11]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
; p( Q% [. c& x9 \: S- ^! @        vol[19] = bMute[12]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;6 b- t- s" |: l9 q0 B5 g+ V
        vol[20] = bMute[13]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;$ v! H0 P$ _0 H5 Z/ Q* Y: x9 u, J
; ?6 z! a7 j& y/ Z1 n
        // FME77 [+ y( b. o. M" ]7 h
        vol[21] = bMute[6]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;# D1 ]$ T/ g. v. ?$ f
        vol[22] = bMute[7]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;8 ~. D4 F2 C" T
        vol[23] = bMute[8]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
( B4 Y* }( p% ~3 E1 ?. N- F& f
: z/ D$ c/ J. |: }//        double        cycle_rate = ((double)FRAME_CYCLES*60.0/12.0)/(double)Config.sound.nRate;/ M  \+ `1 F% O
        double        cycle_rate = ((double)nes->nescfg->FrameCycles*60.0/12.0)/(double)Config.sound.nRate;
5 `7 k5 D% I; J: l
0 q/ i% J9 b" o- `/ h        // CPU僒僀僋儖悢偑儖乕僾偟偰偟傑偭偨帪偺懳嶔張棟
2 s- k  x9 E5 r( Z; {$ P" \4 S! c        if( elapsed_time > nes->cpu->GetTotalCycles() ) {; g% J' A7 T  T# F, N& o
                QueueFlush();) q/ p4 T7 W! C; I0 E$ D
        }
5 _# A: z4 j. N' Z6 X4 l! o+ N' S% r, \* B! z1 H* ~
        while( dwLength-- ) {
4 X" x$ O" S  V& f                writetime = (DWORD)elapsed_time;- s$ P* w2 u  H% h$ v+ a& I$ v

$ o- T) V1 u1 \! |4 U+ j                while( GetQueue( writetime, q ) ) {; D3 O# F# {# V% b) A0 u
                        WriteProcess( q.addr, q.data );
' H! R) Z/ b1 j, e                }
" H, Q' L7 Y4 k- {9 y
# A$ z. W+ g$ F- |6 z                while( GetExQueue( writetime, q ) ) {  C  m$ j  {; h6 G- a6 i
                        WriteExProcess( q.addr, q.data );' p& X7 y: U1 z. x0 E+ K1 f$ m% y9 M
                }3 C  \. p  ^3 t4 N$ ^' T

* f- R. h: v' Q                // 0-4:internal 5-7:VRC6 8:VRC7 9:FDS 10-12:MMC5 13-20:N106 21-23:FME7
1 y0 x9 x& ]' n9 g4 ?2 \% V                output = 0;  D5 N: m8 `+ t2 ^" J( x
                output += internal.Process( 0 )*vol[0];( f6 G; ?5 V. a: n. t7 m2 L
                output += internal.Process( 1 )*vol[1];) D8 Q9 @7 k6 N( y; D! `9 E
                output += internal.Process( 2 )*vol[2];, L# y. O% z9 G5 `& V  H
                output += internal.Process( 3 )*vol[3];
: T  m& {  T8 i% O" {+ X                output += internal.Process( 4 )*vol[4];2 \/ M( E5 G6 e

* A& X! a# V! }. e0 V                if( exsound_select & 0x01 ) {
4 \& b1 n0 q; Q" Q                        output += vrc6.Process( 0 )*vol[5];
$ V3 W6 K# y. o; R! P5 r                        output += vrc6.Process( 1 )*vol[6];
; Z: c7 [( d' {( g8 a' D8 ^                        output += vrc6.Process( 2 )*vol[7];4 W* @# P, c( \
                }$ h, b2 l+ o* F/ |: i
                if( exsound_select & 0x02 ) {' H% }8 O3 C: R, o% s- q0 h
                        output += vrc7.Process( 0 )*vol[8];
/ O0 z5 z, J& K! f" E- g; r                }, K! m% a! i+ a
                if( exsound_select & 0x04 ) {
) b/ T  u& i- @$ Y0 r% ^                        output += fds.Process( 0 )*vol[9];  U& J9 _7 ~2 j, \$ j
                }: R6 J! D# ]/ n; H! `7 Y
                if( exsound_select & 0x08 ) {
2 G1 e& N2 e7 a/ O. P                        output += mmc5.Process( 0 )*vol[10];* {! }# E7 c* u* O5 }* d2 r
                        output += mmc5.Process( 1 )*vol[11];
; j2 K8 M# p' |; v% L$ o) Z                        output += mmc5.Process( 2 )*vol[12];  u# X& b% z- I# Y
                }
* ~- h+ F6 x& ]. H- |                if( exsound_select & 0x10 ) {% \/ `8 @, s6 s9 b) F
                        output += n106.Process( 0 )*vol[13];& M# Y+ w& t! B8 x! s
                        output += n106.Process( 1 )*vol[14];. p. @) ^% z! p& B& ^! a# B
                        output += n106.Process( 2 )*vol[15];: d, K) B0 `" o* X; _0 B" l. M
                        output += n106.Process( 3 )*vol[16];
* t) ~/ B$ A) j7 H* b+ v3 G                        output += n106.Process( 4 )*vol[17];$ D. {. ^* T  h- f7 g8 f0 u
                        output += n106.Process( 5 )*vol[18];
" e- C3 o# a7 ^0 E) J                        output += n106.Process( 6 )*vol[19];
; K2 Q$ a8 ]( j5 z2 l% h- z' Z                        output += n106.Process( 7 )*vol[20];
$ r2 l7 k5 ]* J3 J+ G1 B2 C# Q' z                }9 w# B! ?3 B: u0 M- E
                if( exsound_select & 0x20 ) {
# U2 _6 p* u) x, p8 E8 }  H" i* }                        fme7.Process( 3 );        // Envelope & Noise
% g8 e/ L1 h6 V6 r. t                        output += fme7.Process( 0 )*vol[21];* }! s& X, `' j, R1 K7 t
                        output += fme7.Process( 1 )*vol[22];5 I; C( Q0 E# d! a5 h) G
                        output += fme7.Process( 2 )*vol[23];  A+ O. e- F4 I: O# F
                }# B& U0 h  [# L2 d/ A2 }5 Z2 s
3 `2 B, Q. l& s9 B& ~! j2 @
                output >>= 8;: V8 Y( k" y4 i. V0 t0 d; x
" S# G5 W1 K$ V7 W* @
                if( nFilterType == 1 ) {
# y% }; A$ n# Y  F$ }& S                        //儘乕僷僗僼傿儖僞乕TYPE 1(Simple)! X! l6 W  T+ s3 F* R) M3 F0 r
                        output = (lowpass_filter[0]+output)/2;
( w6 n% E& o0 l5 [3 ~                        lowpass_filter[0] = output;
) E4 e8 [/ [0 T' P0 a! C                } else if( nFilterType == 2 ) {, n1 ?# @2 R# u! ]5 F
                        //儘乕僷僗僼傿儖僞乕TYPE 2(Weighted type 1)
5 Q  u- [# |3 q& h$ Q! x                        output = (lowpass_filter[1]+lowpass_filter[0]+output)/3;
7 A7 {2 Q6 v5 j7 p( R                        lowpass_filter[1] = lowpass_filter[0];
& v; l1 x: c+ {% i                        lowpass_filter[0] = output;) A: Y% T1 b0 h) H
                } else if( nFilterType == 3 ) {) K' r- }% V3 w0 z
                        //儘乕僷僗僼傿儖僞乕TYPE 3(Weighted type 2)
, X3 _: d1 v; Y* k                        output = (lowpass_filter[2]+lowpass_filter[1]+lowpass_filter[0]+output)/4;6 S3 }7 r( G- ]( C! H7 W
                        lowpass_filter[2] = lowpass_filter[1];6 O2 H' G3 m, ~1 i. f3 X4 I: W8 }) [
                        lowpass_filter[1] = lowpass_filter[0];
. C) i, G# L3 [: [& J2 B                        lowpass_filter[0] = output;
! S( J! O8 w7 ~2 t! Z" p$ M                } else if( nFilterType == 4 ) {
9 y- R3 ~, V& n: }; W. p9 q                        //儘乕僷僗僼傿儖僞乕TYPE 4(Weighted type 3)* B8 D6 x# t4 M3 A
                        output = (lowpass_filter[1]+lowpass_filter[0]*2+output)/4;* k) p3 |/ y- E1 A, D
                        lowpass_filter[1] = lowpass_filter[0];* [# b( {; U# ?# C+ \7 S2 c
                        lowpass_filter[0] = output;
1 \7 N/ q" R( _2 h# j                }7 e' k1 _0 z* S8 w1 F' ^" u
# |9 y4 y" x  ?2 x) Z& T
#if        0% x! V: S8 o" l5 n2 L5 O
                // DC惉暘偺僇僢僩
! n% o9 @0 ~  p                {" C* t: q0 {. z4 t0 @) G
                static double ave = 0.0, max=0.0, min=0.0;0 q4 u! z( v  G1 j$ t# X
                double delta;
/ k6 U7 d, r# v9 v. B% T! j                delta = (max-min)/32768.0;; w$ ?0 R; e! E: M2 B8 \
                max -= delta;
  m1 z; ?( D9 H  H6 _+ [* f                min += delta;' h: g7 i! Z' R# x
                if( output > max ) max = output;
; Z! Y4 l2 I6 k8 W! j                if( output < min ) min = output;
+ x/ f# V5 G: _7 g8 Q                ave -= ave/1024.0;
0 Q( Q" A) i9 u                ave += (max+min)/2048.0;, b) |% _- T' B" s  q
                output -= (INT)ave;" k& `- L: r$ D* M* `2 \- b; B
                }0 B/ u) H! C- m- ]7 B
#endif
3 z/ ^" o8 g( b: i& [: w1 [4 m#if        1& s9 x+ K. i" U) j2 X. g. m
                // DC惉暘偺僇僢僩(HPF TEST)
7 o+ K0 F6 H; |. Q) A) e                {; U$ y, o6 z7 ~! c8 \
//                static        double        cutoff = (2.0*3.141592653579*40.0/44100.0);
% `8 a' c0 }( A& ^                static        double        cutofftemp = (2.0*3.141592653579*40.0);3 x, `) ~7 c  [6 E
                double        cutoff = cutofftemp/(double)Config.sound.nRate;8 x& m# b7 b' D* ~8 R" p% ^5 g; l
                static        double        tmp = 0.0;
5 J0 p, k( I; T: Z* Y                double        in, out;
6 F1 A  p1 E+ U4 @5 Q2 G0 i3 b8 h
7 a) W8 @4 y0 J/ W/ |                in = (double)output;
6 x# \( A8 x- K* Q' }& m( X8 _                out = (in - tmp);
4 f" A/ t# t* ~. M/ D1 h, a                tmp = tmp + cutoff * out;
( j2 I  l5 K2 n4 `( G  b
0 X5 F6 E- P+ @5 f% [                output = (INT)out;/ X& E; G6 F7 k" D* Y+ z
                }
5 L" z. O+ `0 K- J1 c1 B#endif
# Y4 ?; {, r; U' W) }0 i/ V- q#if        0* [8 u1 a7 b4 N2 W6 \1 v+ T* j- t
                // 僗僷僀僋僲僀僘偺彍嫀(AGC TEST)$ D0 w5 S; R! j# p" R. |
                {! _% J& B2 {0 \3 ^& X* O% R" z
                INT        diff = abs(output-last_data);& j4 {5 P; A' U# E, f' ?
                if( diff > 0x4000 ) {
" Y* z& Z" \3 Q" D: J* N6 S                        output /= 4;$ W: G7 E: ?( n
                } else & e3 `; ^5 X2 _4 x! K9 p
                if( diff > 0x3000 ) {8 Q, t4 K6 X* T7 n5 A; P6 K; J" T
                        output /= 3;, H- y2 y7 y3 D" `' X! M. e7 ?% q
                } else
( v6 `. s$ x- Q5 X                if( diff > 0x2000 ) {2 L" \% G: ?; R8 O' [! b  F
                        output /= 2;% U) E& F1 p" j5 i- c& V, w
                }: N9 A; y* l! u9 R( K' U& V. q; T5 o
                last_data = output;
) R  @- B, }  `( k1 P% l                }
$ t& f$ E2 y0 T5 v, h0 k- F#endif7 m! @$ @" r8 x2 l* R1 x& q
                // Limit1 f! K/ ^: t1 J
                if( output > 0x7FFF ) {
% g0 O  X0 }2 R9 t4 V, {5 u- ~                        output = 0x7FFF;' f+ y& R4 n, z8 u0 \0 o
                } else if( output < -0x8000 ) {
% M  M- x: `- o, f                        output = -0x8000;
6 D+ T  e- H1 {, e/ h" I                }* T. }' c. A% n# k# A

6 H8 }# o6 ?. _# s* m" {                if( nBits != 8 ) {7 s+ v4 k. ~4 J
                        *(SHORT*)lpBuffer = (SHORT)output;6 i: U: f, H1 a5 \( t
                        lpBuffer += sizeof(SHORT);
% J5 T2 r8 J3 D                } else {, N) `  E8 u0 @& C7 L2 t1 a9 T; v
                        *lpBuffer++ = (output>>8)^0x80;$ ?, j! s, l! U; D
                }4 H- B. x9 `. i) y" q9 N: I

# J" ]. H& S" n/ u  W. H                if( nCcount < 0x0100 )# k' c5 K; C9 @/ G7 m% N
                        pSoundBuf[nCcount++] = (SHORT)output;0 c$ V! G5 a9 y2 g1 w- v% }

9 t# c) i- n8 E  l& j% c* c2 g//                elapsedtime += cycle_rate;
. l& d& k- Z; g0 o" w" y$ ~# Y                elapsed_time += cycle_rate;
" ]9 @8 X+ g4 u6 \9 L& v! d        }& y5 A  i# d' r+ G& M

4 x5 e, M; N' A; _( k4 x#if        1" o3 a8 S  l4 j9 V( t; {
        if( elapsed_time > ((nes->nescfg->FrameCycles/24)+nes->cpu->GetTotalCycles()) ) {
6 `  \: d0 r) B8 T* l# }& ^; G                elapsed_time = nes->cpu->GetTotalCycles();
, e! X' U. h; ?        }
' ]5 h; U0 r2 a" n8 l# y* X        if( (elapsed_time+(nes->nescfg->FrameCycles/6)) < nes->cpu->GetTotalCycles() ) {$ p; Y1 L& f3 K5 Y
                elapsed_time = nes->cpu->GetTotalCycles();+ D% u6 }2 r0 L. F! {
        }
7 E. c- g; Q$ J' N; C2 g! o#else
: E' i% Z# O) d        elapsed_time = nes->cpu->GetTotalCycles();  q( z6 Z! v4 Q
#endif. {+ V: N$ o0 i% f
}* x( X( E! D9 m/ i0 \7 W/ ?7 s

; W$ {1 H) K3 ?- `2 j3 e// 僠儍儞僱儖偺廃攇悢庢摼僒僽儖乕僠儞(NSF梡)
! i, k) H5 J$ AINT        APU::GetChannelFrequency( INT no )
# f# ^8 t4 a* K6 b# C- Z{
' z/ r1 l) w" L; X        if( !m_bMute[0] ), C6 Y0 x3 c- {. J9 y$ r& W2 b! y  V
                return        0;
' Q' n, R/ ~2 @5 m( G8 C
) c: F* Z7 f' i/ c& R        // Internal
- s; q7 _+ i/ Z! ^: x        if( no < 5 ) {( Q2 n' y  K0 {0 v& N5 O% S
                return        m_bMute[no+1]?internal.GetFreq( no ):0;$ h" n& l6 w5 M. |  S' P
        }
5 X1 }5 e1 I) _& d, ~5 C) i( Z        // VRC6- q0 R$ c# n" L9 a: D1 z; s
        if( (exsound_select & 0x01) && no >= 0x0100 && no < 0x0103 ) {; p- k* }. u( |; ^% F$ D, g. @2 T; Y
                return        m_bMute[6+(no&0x03)]?vrc6.GetFreq( no & 0x03 ):0;
) A7 Z  ^: O0 X+ R* y        }% e& ~3 z' _& f$ t5 Z  C
        // FDS
# I5 f, s% @. H/ h- s4 s9 v        if( (exsound_select & 0x04) && no == 0x300 ) {2 a2 W# n' O# f8 ^
                return        m_bMute[6]?fds.GetFreq( 0 ):0;5 s9 \: W6 z/ Z2 `- ?
        }5 Y$ F) G  H/ @. Q
        // MMC5) u$ S" a# Y' n/ G
        if( (exsound_select & 0x08) && no >= 0x0400 && no < 0x0402 ) {
5 w& I5 v+ v' R" Z% S6 b) P% k) r                return        m_bMute[6+(no&0x03)]?mmc5.GetFreq( no & 0x03 ):0;* K  a& A# {1 l" ]9 j% }: G/ O8 B
        }
, p* l# Y  [, @) l5 t* d9 a* Z        // N106
4 V5 n- `% F5 l# @        if( (exsound_select & 0x10) && no >= 0x0500 && no < 0x0508 ) {
, [9 p8 Y2 h% P                return        m_bMute[6+(no&0x07)]?n106.GetFreq( no & 0x07 ):0;
; J, A2 }' b! ~5 T* k        }
, J! X4 K8 |9 W, R: Z+ N5 b        // FME7
4 H9 Q* U2 P2 e) c1 p% B        if( (exsound_select & 0x20) && no >= 0x0600 && no < 0x0603 ) {
' e, s; R+ ^3 W: }" c5 K/ e8 M                return        m_bMute[6+(no&0x03)]?fme7.GetFreq( no & 0x03 ):0;$ O& s# O2 W9 q! U. k' D
        }- j8 F9 q2 t, v  R
        // VRC7; C7 _8 |! Q6 s: _: i9 z* L
        if( (exsound_select & 0x02) && no >= 0x0700 && no < 0x0709 ) {
+ M0 }" H2 e5 ]7 G# A. q% N                return        m_bMute[6]?vrc7.GetFreq(no&0x0F):0;
. V! {& w+ d" j5 P, \  ]) R        }
& A6 v7 K% b. q: m        return        0;
# D# Y. Z8 S8 F7 b9 j}2 H3 n) t+ n* {) g& U! U3 G+ u

0 N. q$ y- F( O8 Y// State Save/Load; B- d9 r: H  g# x& L
void        APU::SaveState( LPBYTE p )
6 R8 e) L4 ^$ [{8 s) ^' i) u3 m$ G) [
#ifdef        _DEBUG
* ]  Q% O) B" G2 @1 o. jLPBYTE        pold = p;
$ H8 n$ A8 {* C' j2 O+ S7 G5 ~#endif/ n3 E- j) R1 g$ Q4 u

4 V- v) m3 O$ H        // 帪娫幉傪摨婜偝偣傞堊Flush偡傞
2 M4 h* x. k8 C3 X- L0 ?        QueueFlush();9 u* ?! K- X4 i( W

: b, y$ c: p7 X: a        internal.SaveState( p );  y+ a1 y; L5 d8 R
        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding
8 ~" A# N7 }1 z! @& q
' A5 M, d! ~/ x+ P# t        // VRC6, o; n& z0 g( M3 v
        if( exsound_select & 0x01 ) {0 S5 ?, V* [+ ]6 Q3 h5 P
                vrc6.SaveState( p );
- _1 v. g0 X& o/ B. g" [                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding, G# ]$ X% C- i' o& G0 ?( i9 T8 I
        }
, M9 w7 `2 A, c! F5 Z" L& X* }        // VRC7 (not support)
# o% k$ A( n9 t* M7 M8 D! i/ M        if( exsound_select & 0x02 ) {
$ \0 V& R! k5 C4 r5 e1 m4 ?9 m                vrc7.SaveState( p );
' |2 S* _3 P) E: u5 }$ N                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding
" \9 P3 t7 C# e5 i        }: N1 d; W  y: H. w3 {5 x
        // FDS) b" G1 c9 r5 n- O
        if( exsound_select & 0x04 ) {" `, B  [# E  v4 ]4 A
                fds.SaveState( p );, G6 I. j7 i8 ]1 I
                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding
' [' M7 q: a# l: y        }
# G5 L( }' {$ O% S1 _        // MMC5
6 t/ ]; u: ]* N" q, Y4 ]! _        if( exsound_select & 0x08 ) {
; v6 ?! x3 c' P+ N8 O6 E                mmc5.SaveState( p );6 B, [8 T( _$ H+ {& G% ]
                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding
% ~  ^2 ^' @/ V        }# ^. t5 U5 s: Z. i
        // N106, g6 C8 G4 E( N3 D
        if( exsound_select & 0x10 ) {
7 e6 e: t/ u5 u1 h" l! j6 y                n106.SaveState( p );
; d/ _3 z$ S8 }, A. i4 K3 w                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding
: a6 E- {8 l9 F# Y( @        }2 {& l* ^" r' @0 y4 C; X' t
        // FME73 f+ w$ \% |4 t  W  _+ U( w# N
        if( exsound_select & 0x20 ) {- u/ ^1 ?/ v# W2 l5 W  u. U
                fme7.SaveState( p );
+ R7 X+ C9 z. m( K  _                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding
* {, T7 P# |% K9 L8 |. D4 ]        }
, R/ ^. a/ t; Z3 r5 a" a  {1 N4 h* d& |* h. O! Z
#ifdef        _DEBUG7 o9 E. A9 i  @; W% x9 s. K
DEBUGOUT( "SAVE APU SIZE:%d\n", p-pold );
4 p' n0 D! {) T/ p; ?# ^6 K8 C#endif
6 u- j; w: W% y) H; {}
. C; {0 j# \9 `' R
! J, T% R- H9 f4 B+ x  xvoid        APU::LoadState( LPBYTE p )! z/ |0 S9 a1 K3 G" X. g0 {
{
5 ?) `( |+ ]; k# b2 U  }2 |/ B$ J        // 帪娫幉傪摨婜偝偣傞堊偵徚偡
8 m  w% Q+ s. s- S1 R        QueueClear();
4 s+ e  ^' o. Z
* y& T2 |. C. p& ]( M        internal.LoadState( p );
' s% o' b9 I4 D, M+ i        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding5 }$ m) }7 n& Q. L6 c
. h1 D* h/ x. L$ @1 \9 ?
        // VRC6
4 [' u0 W( l1 L8 k$ h& q        if( exsound_select & 0x01 ) {6 ~6 O' ?! z( a3 ~3 G9 R4 E
                vrc6.LoadState( p );
6 Z( }. Z5 V8 q, K                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding  B, B  u) X5 x2 V4 ~
        }( Q$ c7 I1 @; B. m+ T7 M
        // VRC7 (not support)3 y8 j  ?# Y$ N$ e; Y( \
        if( exsound_select & 0x02 ) {* Z  P# f' r: g) ]/ {
                vrc7.LoadState( p );' ~( ^+ r1 z9 t2 e
                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding
0 U2 b1 V4 T: x$ ]        }; J' d2 m) x0 z* `
        // FDS2 K# O0 [) J1 _
        if( exsound_select & 0x04 ) {
1 _6 ]# }8 c7 D* F3 I( K                fds.LoadState( p );5 g& o8 v" [( l- a
                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding
  Y1 V# [+ C9 J. z$ p% r        }/ |& [( h7 A4 |- R5 B' m
        // MMC5! Q5 @) F9 x$ s
        if( exsound_select & 0x08 ) {
. h0 W1 O7 ?9 F" K  X6 N2 l                mmc5.LoadState( p );) W; ^4 w0 Y, W% U3 Y
                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding2 K7 h( @! b  F. a, L& c
        }
9 F4 m+ k2 }! N3 t4 S9 l        // N1068 E% T( A. M' N: h
        if( exsound_select & 0x10 ) {
. H% E2 p! m# x* e+ A4 S# E                n106.LoadState( p );. S6 Y6 B' B* D
                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding- W; E2 I, s& L5 [9 V' J4 Q
        }
, t' _: J. \3 e/ R/ m        // FME7' r/ {4 E9 s9 E% t5 ~% g- r" J
        if( exsound_select & 0x20 ) {9 z) r+ T( c9 X# X
                fme7.LoadState( p );
, u( [/ Q/ |7 Y, T                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding
3 b" w! |! e- `% e7 K& o9 g$ @        }
7 K1 h( q  I+ u, ^$ t: Q1 u- l}

该用户从未签到

发表于 2009-11-8 17:25:37 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 14:38 发表
; i/ F1 R: x+ Z* z3 ^4 Q5 p/ p可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。
; s7 S6 i7 A  s1 T/ s感激不尽~~
1 }  d* T( u/ O- ?8 r0 Z: [- y
恩 我對模擬器不是很有研究,
* [! T7 L8 _4 `$ O雖然要了解源碼內容,可能不是很困難,
3 r& z8 h$ r3 d) k$ s( Z( U不過還是要花時間,個人目前蠻忙碌的。/ i  k6 W  b8 N5 d0 h8 L! p
+ l, @# @) w: `) d5 `
給你一個朋友的MSN,你可以跟他討論看看,, y6 N+ V# q- O5 r2 D5 B
他本身是程式設計師,也對FC模擬器很有興趣。7 }2 P( j7 _) ?7 n6 w* u# K
5 P' O+ l% Z2 c# i* L: p8 I
MSN我就PM到你的信箱了。
& j2 S! {0 [- |3 r+ _4 e' A6 y) Q
希望你能有所得。

该用户从未签到

 楼主| 发表于 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 发表
# r. A" l% }7 V! p% ~/ n呵…… 谢过团长大人~~
% L; n+ f& v2 j; i5 |

- y& A, j2 s' \哈 不客氣,算是順便幫他找個伴,大家可以一起玩。

该用户从未签到

发表于 2009-11-20 13:14:53 | 显示全部楼层
原帖由 李伟 于 2009-11-9 16:02 发表 2 A5 C" U" g+ P7 j
团长的朋友都是神,那团长就是神的boss。

/ Z+ [1 K. q7 y哈 不敢當,我只是個平凡人,
% T* t8 E* _9 V" I" Z& i要吃飯喝水,光吸空氣是不會飽的。。。。 :)

该用户从未签到

发表于 2009-11-20 13:32:35 | 显示全部楼层
FC模拟器的部分有个人可以帮你忙
8 k1 X8 r9 F  N" h0 K( AZYH
3 W- Y6 }; B$ m* O: H4 |& jQQ:414734306, r2 E3 x% I) H  w  Y0 X
Mail:zyh-01@126.com
9 r4 e- s6 W2 J' G5 U
  E( `3 x2 }& g; E$ n, {他是ZYH Emulator这个模拟器的作者,只是他用的开发平台是VB,不过就6502的实现原理来说是一样的

该用户从未签到

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

该用户从未签到

发表于 2009-11-27 19:09:06 | 显示全部楼层
原帖由 独孤残云 于 2009-11-27 09:48 发表 2 s- b+ h: d! a: T' ~$ j6 g
再次对团长大人和悠悠哥的无私帮助表示感谢~~

9 |6 O  W) a% P( j# }7 F& I不客氣  ^_^
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

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

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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