EMU618社区

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

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

 关闭 [复制链接]

该用户从未签到

发表于 2009-11-2 22:45:57 | 显示全部楼层 |阅读模式
求助:模拟器源码中通过哪段代码控制Rom背景音乐的播放?2 k8 \# v, r8 D- q6 {0 |' H' m: J
PS:看过一些模拟器的源码,大概都分为APU、PPU、NES那样几个版块。请大侠告知是哪个模块。感激不尽~~

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 09:56:34 | 显示全部楼层
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。* i+ \0 S* O, ^% H: I+ W/ e$ @
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~; m' G5 R8 {! H* i0 Q& J
这里有相应的模拟器源码,就当送给大侠了~~
3 |3 }' V1 }" d/ W% ahttp://kenkao.qupan.com/5096520.html

该用户从未签到

发表于 2009-11-8 11:31:10 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 09:56 发表
# [6 t8 |& a2 D, y能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。) _1 V* t* a/ e; z
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~
$ T! O  I$ x, q0 a4 z4 U- c: i9 j& j这里有相应的模拟器源码,就当送给大侠 ...

3 z( @! v# c+ b( M$ |! t5 B& u聲音部分(Audoi Process Unit = APU):
& B5 I5 C, Z% w# K- O' f% h.\NES\APU.cpp
* w, J* u: N% D# |- w.\NES\APU.h0 H$ h$ S4 s; @

' I, j  ?& f. x( X$ q
7 a6 o1 k3 H) U4 j, @, e影像處理部份(Picture Processing Unit = PPU):
& F9 ^9 C3 D- `.\NES\PPU.cpp
$ P% r: u4 R" ^: h/ I.\NES\PPU.h
2 l3 \1 o$ X" u5 E2 y/ f) Z  l
& W7 E! w% N& ^1 i; i5 f1 |5 |: Q9 V如果原碼用C跟ASM混搭也不錯

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 14:47:50 | 显示全部楼层
这是我手中源码Apu.cpp的内容,敬请赐教:- E' h8 P* t. x+ |& \1 D
(由于很多专用术语和算法机理都不明白,所以看不大懂……)- P  c, Y4 O3 S" \0 u  {# o$ l
//////////////////////////////////////////////////////////////////////////1 U) v( z6 L6 Y1 w3 [3 O/ ~
//                                                                      //
* w; s9 h" l. k( f//      NES APU core                                                    //
7 z$ J# r" _8 d- x/ l//                                                           Norix      //% @8 [- n  W; k! S
//                                               written     2002/06/27 //
0 M- Q. n$ z5 V* t//                                               last modify ----/--/-- //0 s' q0 s$ W+ z. x' r3 j
//////////////////////////////////////////////////////////////////////////
6 I5 {! ~5 }+ T# U( t: ?& m+ ]#include "DebugOut.h"- s; F- ^: c4 r" E7 L* ?9 B4 V$ N
#include "App.h"
3 [, [5 n) x4 \4 S) ~#include "Config.h"7 O+ s2 v0 P/ y2 f

5 O. @# @0 O* ^' p. n) \  t! @2 {3 q7 [#include "nes.h"% |! T" V$ \. i+ u8 b
#include "mmu.h"8 h$ p7 r6 {1 O: r& g0 F
#include "cpu.h"6 c+ Z8 a; J0 x  ?2 D+ U
#include "ppu.h", e( ~/ ]. Y2 G( `7 a
#include "rom.h"1 q: z: d8 P* N& s7 g
#include "apu.h") h$ t4 p( S& Z( m. A1 @4 S

; k$ e- O. T* y6 ^3 J/ @7 c// Volume adjust% x. |1 j4 f0 y
// Internal sounds
! [" n! U8 T9 y$ y- |#define        RECTANGLE_VOL        (0x0F0)
0 r" q5 f, e! E& S' ?; ?#define        TRIANGLE_VOL        (0x130)
& Q7 u- y$ c- ]( n5 }#define        NOISE_VOL        (0x0C0)
; X; }3 _7 V3 M% c) S" f#define        DPCM_VOL        (0x0F0)! ~7 E% F9 S$ a, N7 ]1 U
// Extra sounds
1 T+ |. B9 M, w$ h  ^* t9 [$ }#define        VRC6_VOL        (0x0F0); b& a5 ]5 F; r/ ?) m/ k4 _. P( [+ I
#define        VRC7_VOL        (0x130)
' o9 |- e0 e8 t7 g- b#define        FDS_VOL                (0x0F0)
6 w4 G6 G% n& B, _4 k#define        MMC5_VOL        (0x0F0)
2 ~) {! p8 {  t' O! w3 t#define        N106_VOL        (0x088)0 p* x# y! S* n8 n: B: u& e; V
#define        FME7_VOL        (0x130)
4 k) u8 B0 ~& V  w& n1 g0 m+ s5 H' X" K# [) i) v
APU::APU( NES* parent )$ h) {9 y% s$ G( h. K/ G  e% o
{
& |) n7 F+ [; [7 S        exsound_select = 0;
1 v/ V* F: k8 r  z. R
5 D- A0 y1 J1 @; ?        nes = parent;
* }9 q  d* P4 e1 ?        internal.SetParent( parent );
3 g, x' y/ F2 ^& [; F
4 R% b7 R- n6 g' J8 ?        last_data = last_diff = 0;8 }& q  o/ A8 R5 v
. W" ]4 V2 K6 M1 T+ t# q6 c
        ZEROMEMORY( m_SoundBuffer, sizeof(m_SoundBuffer) );
, u0 M# B, G/ Z
" @8 b& i2 F2 {* @& A        ZEROMEMORY( lowpass_filter, sizeof(lowpass_filter) );
) S5 K4 R: q7 ?, ?        ZEROMEMORY( &queue, sizeof(queue) );$ H# s9 Z. c9 k5 S  N/ A
        ZEROMEMORY( &exqueue, sizeof(exqueue) );; f% O/ A6 _% Q& a! X5 U! e

. I* d; ~' h! j* a& @2 r        for( INT i = 0; i < 16; i++ ) {' \% w, `( v( `# x: x: ]
                m_bMute = TRUE;
) R! N$ p! k. B+ e' H3 a" D        }2 b7 {3 `# p' ~, f
}
& I) E; I: k: p7 V8 S; @) h# n% |) h
APU::~APU()
' g) f9 m6 j! D) {{
7 f0 y" L( K6 c6 k( |# ~8 ]}1 }" ]$ [  Q9 U% b" a

! @* ?$ P, V% S7 N. e. S8 dvoid        APU::SetQueue( INT writetime, WORD addr, BYTE data )
0 C( g& v1 E3 x{1 Y% r! d% M+ {& E1 h
        queue.data[queue.wrptr].time = writetime;
/ q8 T- I5 C$ Q7 a        queue.data[queue.wrptr].addr = addr;% F! B' c5 u  W% E# ^* d
        queue.data[queue.wrptr].data = data;
! R8 G$ L" V  x: J# ?+ M4 M1 b        queue.wrptr++;
  \8 z8 B! V, \* D        queue.wrptr&=QUEUE_LENGTH-1;/ p9 s, J/ W3 k, @: M* C! Y
        if( queue.wrptr == queue.rdptr ) {1 i4 e$ N7 p( K' M
                DEBUGOUT( "queue overflow.\n" );2 s/ {8 A5 g& X7 r$ _8 Y) ~
        }
  Z" Y4 a3 [2 ^, A. p4 X5 u  ~6 w}
$ A* d/ T& _& E7 E
. N6 O1 D; A/ Z2 k7 Q; `/ TBOOL        APU::GetQueue( INT writetime, QUEUEDATA& ret )3 j5 ?2 _5 A. O
{
: l7 v8 S8 C1 {! S# S! S4 q        if( queue.wrptr == queue.rdptr ) {' q  u$ ~: [9 H6 m* ]- |2 H7 C
                return        FALSE;( _' E( P0 ^4 l2 g. E
        }$ U7 r1 k7 U) ~, u# {9 A% F+ _
        if( queue.data[queue.rdptr].time <= writetime ) {' i2 v2 a% d( N& l
                ret = queue.data[queue.rdptr];
4 [$ l0 `, R9 }9 p& L) B4 V  M" E! F                queue.rdptr++;
1 O. e9 N" f& v3 \4 ]' N                queue.rdptr&=QUEUE_LENGTH-1;3 V, j1 n1 X+ g7 p
                return        TRUE;
* n- _& s# O/ B5 f( ?  C        }
: N/ J' V' S+ k, b; L4 z6 T        return        FALSE;& ?4 m" r9 L3 {
}4 j, Z' l) a# k. _) m0 V
3 p, L' Z) o# J3 n
void        APU::SetExQueue( INT writetime, WORD addr, BYTE data )
, v+ U  _7 R) c( N" @" V8 _% n; s- T/ C{
! d0 n+ T4 i; d- @: X3 s1 Z        exqueue.data[exqueue.wrptr].time = writetime;
0 Z8 R) Q' H$ Z2 w6 T" D        exqueue.data[exqueue.wrptr].addr = addr;1 N5 ~5 x2 U9 V3 E7 v) ~
        exqueue.data[exqueue.wrptr].data = data;9 r" p4 ~. E/ H! v, {
        exqueue.wrptr++;
* T' F7 C/ y4 Y2 p( J. e& \        exqueue.wrptr&=QUEUE_LENGTH-1;
7 O- T4 H& R+ t0 A        if( exqueue.wrptr == exqueue.rdptr ) {8 m. I  b( t; K+ H. o0 s
                DEBUGOUT( "exqueue overflow.\n" );
' w3 |8 A* L- A8 J% V7 W: w        }8 n& _  l& P6 A3 c( y. m* E+ s4 a
}$ y9 ]5 g& n$ {7 Z% Y/ s

2 w; p6 z: j; ?/ LBOOL        APU::GetExQueue( INT writetime, QUEUEDATA& ret )' D7 D* R9 E; L. u0 V8 O, [7 P. Y' m
{: N2 Q+ a! ^: i7 q% n9 v
        if( exqueue.wrptr == exqueue.rdptr ) {
6 u* q1 E7 D- G" ^1 D/ H9 Z                return        FALSE;1 Q+ n$ R& J* K9 L" x: r( W
        }6 Y; I: u2 y( o3 f7 R; h- x6 l
        if( exqueue.data[exqueue.rdptr].time <= writetime ) {
3 A, D0 i: ]4 Z  T" w' W( r. \                ret = exqueue.data[exqueue.rdptr];
, B1 s  J3 E- p0 q' }. u- p                exqueue.rdptr++;3 A8 O* Q& j- D( y
                exqueue.rdptr&=QUEUE_LENGTH-1;& h' f! c4 M# F5 _" L# r
                return        TRUE;
6 s9 g$ S  o6 ~3 M, ~6 m        }
) y  R* [/ l* `9 b$ A5 R        return        FALSE;3 }) N5 e5 o1 k% @' a
}
( f! w( B! R+ p( Y( s" u; ]. a$ a0 x1 U) c
void        APU::QueueClear()
. c* U! z# S: u, o+ f( R{
2 T' P$ G- N0 w$ v% [        ZEROMEMORY( &queue, sizeof(queue) );
# M: e: P* d8 V$ i        ZEROMEMORY( &exqueue, sizeof(exqueue) );
- o: K5 R( ~8 C6 X4 Z1 X8 }. B2 x}
2 l# c0 V, t5 _  u: `, ~1 p, o4 z5 k9 t! ~* {
void        APU::QueueFlush()
4 `) l6 j0 P: R/ ]) ?{
( _" Q$ C. w* C/ J1 m" d# c        while( queue.wrptr != queue.rdptr ) {0 Q3 M2 c3 J+ q- {
                WriteProcess( queue.data[queue.rdptr].addr, queue.data[queue.rdptr].data );6 h4 ^% Z. Z' @; b, U/ t
                queue.rdptr++;; O, r4 W  Y  `5 u/ ^. D
                queue.rdptr&=QUEUE_LENGTH-1;
0 U9 `. O: X, U/ `+ m        }* [6 |. I1 V) o$ R- g% L5 E

# O/ W( @1 t6 a( M8 B, t& C0 `        while( exqueue.wrptr != exqueue.rdptr ) {
. K) r/ |9 p$ b5 [                WriteExProcess( exqueue.data[exqueue.rdptr].addr, exqueue.data[exqueue.rdptr].data );
4 y% Y' _. g0 p5 g9 {                exqueue.rdptr++;
  i' V5 o( u3 {2 c                exqueue.rdptr&=QUEUE_LENGTH-1;
7 u" u5 T9 s. c$ N. D# k        }
  B6 m: E5 n; b( V}
$ ?$ L" X" A/ Y7 x4 x
& O4 W, O9 C% F' P4 V# {void        APU::SoundSetup()  z+ q2 O" x( k8 @8 D4 u
{% _+ W7 L, G# _7 e/ j
        FLOAT        fClock = nes->nescfg->CpuClock;
$ A# b" K! `5 M. A4 O        INT        nRate = (INT)Config.sound.nRate;$ h9 ]7 _. U3 s+ V  U
        internal.Setup( fClock, nRate );3 {9 t  C: x/ U9 m$ u
        vrc6.Setup( fClock, nRate );' V7 v: U+ M, i, M4 b4 I* m
        vrc7.Setup( fClock, nRate );' k' E$ q. i/ E. e
        mmc5.Setup( fClock, nRate );
. [# O1 l. z0 f& p! T, q7 V        fds.Setup ( fClock, nRate );
- V" K3 o9 _7 A        n106.Setup( fClock, nRate );- v6 w# p, ^7 W( l
        fme7.Setup( fClock, nRate );3 K  b' f% h. S* r( @8 Q  i
}
+ u! B, F. v) B5 R, _! W" N2 E
2 P7 `3 O" Z- b! [void        APU::Reset()
3 u# d5 h8 o3 M- }( ^{- f% i, g, U9 G1 l, d
        ZEROMEMORY( &queue, sizeof(queue) );
5 P6 v2 h# T9 d1 E1 H        ZEROMEMORY( &exqueue, sizeof(exqueue) );
$ x3 A% i  J, P3 q; h- s1 u6 b5 b" h: a9 P
        elapsed_time = 0;& p1 Q# f% N/ f' i; Y& f

; G' l4 \/ X+ M, Q  _        FLOAT        fClock = nes->nescfg->CpuClock;
7 o) u6 ^7 y, B# o3 z- s1 K        INT        nRate = (INT)Config.sound.nRate;% \+ H6 m4 t. g
        internal.Reset( fClock, nRate );
: J4 m) f# ~. K% \        vrc6.Reset( fClock, nRate );( I7 M: o, C) ]& E0 [& }
        vrc7.Reset( fClock, nRate );" |1 r+ ]# Q, O
        mmc5.Reset( fClock, nRate );
  h% n% K6 R0 w$ B7 Y7 c        fds.Reset ( fClock, nRate );
4 C3 Z. ^' K& l" S        n106.Reset( fClock, nRate );1 b7 N9 R' k! v0 w
        fme7.Reset( fClock, nRate );
2 c* Q% o. y3 `3 o- o
+ v0 q0 Z! y& E        SoundSetup();
6 ~1 _! s$ r/ c, A. c" G}
% P( \7 c* @( x* }5 D$ g/ Q4 I5 s! P1 j
void        APU::SelectExSound( BYTE data ), L& I$ i6 v* y8 C4 p$ q9 J
{
) ]5 `5 l; z% ?, ?/ B7 v6 I7 u+ W        exsound_select = data;
1 y" o( h! a5 \0 I% a$ x* ~+ |* z4 m}1 n  U% {# v1 Y$ X# `4 q
7 y7 h3 j1 v, E" M
BYTE        APU::Read( WORD addr )
( x' j5 E: ?2 C- z{$ Z6 _' b$ C) I* V# |
        return        internal.SyncRead( addr );
9 ?- v) E% B, K# N7 T& x. p3 X1 G- B}1 _" m' e: L2 |  d% g5 b; o
1 m$ S/ y" i% h6 G4 V
void        APU::Write( WORD addr, BYTE data )# x' N; q, ]: A
{) ~" I1 q4 u( |0 O+ s
        // $4018偼VirtuaNES屌桳億乕僩
, R, M8 h. I5 U4 t3 x        if( addr >= 0x4000 && addr <= 0x401F ) {$ W) A2 \$ \' z( [* [0 @
                internal.SyncWrite( addr, data );
2 j* n* m2 S* r* L& X4 W$ }  I7 e! h                SetQueue( nes->cpu->GetTotalCycles(), addr, data );4 K+ y( o' D1 ]% O
        }
; N7 z% O" q6 K7 M% Z. S5 \}
& ]6 X* O8 c+ k) ?! V% R1 Z
* |, m+ V2 `- j( vBYTE        APU::ExRead( WORD addr )
  a1 Y; U' O8 }4 K2 ?3 j1 Y{
" k% B) g# |7 rBYTE        data = 0;
$ g8 F, A- e/ p: p" J! e9 j. F; R; i! D
        if( exsound_select & 0x10 ) {
' [) g; O+ y# d+ b6 w! w6 n, J5 Q                if( addr == 0x4800 ) {
. C- D+ A6 O9 W8 d                        SetExQueue( nes->cpu->GetTotalCycles(), 0, 0 );
4 X# b. U# @# i* z1 z: z                }
: M- P) `  Q) W+ ~/ F; R( F        }- B* L/ ^% \7 C9 w, Q* a# d4 K
        if( exsound_select & 0x04 ) {
+ D3 a) X) h0 [6 ?: R  w                if( addr >= 0x4040 && addr < 0x4100 ) {
2 e* i- z; e. P( X                        data = fds.SyncRead( addr );
8 ?/ K9 G* Z7 D6 S2 b- X- w                }4 A' R- N! ^  S3 H
        }
9 s2 w/ M8 B) i+ p        if( exsound_select & 0x08 ) {
; y' F; b. s, [" ~8 _1 x7 W                if( addr >= 0x5000 && addr <= 0x5015 ) {
! E6 y+ d7 x5 T6 J                        data = mmc5.SyncRead( addr );" v- |+ j4 S8 l/ g( M* n; n3 t/ G
                }; n7 M3 @) V6 b
        }
  @/ j: j  w" O% |3 t3 r- V, L
& ^! f9 }* s" w, E* {        return        data;
. Z. ?+ `" f5 H9 v! {2 ?}
' ~; |7 o8 R9 O5 N) @& Z' a
; Q5 n/ g, _6 uvoid        APU::ExWrite( WORD addr, BYTE data )/ O) J) `) f' \3 q5 U
{+ O& @4 b8 ]* a, ^1 s8 F3 n
        SetExQueue( nes->cpu->GetTotalCycles(), addr, data );- N% h8 {! X7 |4 N: s  a7 m

5 B1 `' P6 b& e, z. J; Z; H2 }        if( exsound_select & 0x04 ) {
9 E1 A0 d: S/ q* w" T" _  b5 ?! r                if( addr >= 0x4040 && addr < 0x4100 ) {
; N) P, Q( o  @' G" R- v7 @% y                        fds.SyncWrite( addr, data );
: z( Z5 M0 a- x# v  u4 M                }) P$ m2 t. N% ^' X0 g
        }
) r& ^6 u' k7 u& {6 o/ v
: j0 P6 c! A: m( E) q        if( exsound_select & 0x08 ) {3 C, B% a$ g) G1 R- w( h
                if( addr >= 0x5000 && addr <= 0x5015 ) {
3 U: j4 h3 V/ ~                        mmc5.SyncWrite( addr, data );
1 N, ^: y8 `* B* F2 ~) G) H                }
4 X; ?$ u# V9 X/ F) l8 h        }
4 J0 q9 Z) ~0 K# l4 F4 P+ U! J}
- C. |) ~. W( }/ E! M* e0 {! E
+ Q& H7 S/ e& i0 J! J5 F9 ?void        APU::Sync(): h6 \1 O3 }. z; b
{7 Z9 _( W8 a. V
}
3 n2 P2 W' _8 `* M$ m' ~2 B: f/ [6 z( M
void        APU::SyncDPCM( INT cycles )
" P6 ~. A6 f, F  A$ [3 v9 k/ {{
8 `( _( H6 j. c        internal.Sync( cycles );
5 t; g* U# J  Q, X* Y5 a( s0 j- ]" _8 |3 P3 o
        if( exsound_select & 0x04 ) {
2 h% t) Q, Z% s' v                fds.Sync( cycles );% o" p; x3 l1 i- C7 x) \
        }
" f0 l' {( v" v4 f& G: @5 s        if( exsound_select & 0x08 ) {
" F: `, }- j' _0 C. z/ j/ D                mmc5.Sync( cycles );/ F6 A; F7 R6 v: e7 B8 X, h' L
        }: J! W5 B; ^  N1 A* H
}8 }5 }) I* e4 \  D0 N" H
& J, j. c7 h) u) b  P4 I' e2 ?
void        APU::WriteProcess( WORD addr, BYTE data )
9 p5 P! N7 p# M5 C8 g{. n9 X2 l# r8 x/ s7 z9 r1 o
        // $4018偼VirtuaNES屌桳億乕僩, S3 j# j( `' [
        if( addr >= 0x4000 && addr <= 0x401F ) {
6 I2 s) H0 A/ \& C* U                internal.Write( addr, data );
5 H6 ]8 A* g) U6 |( T        }# d5 G( F& Y4 w4 r
}
/ r% T9 y' q' ]( F+ s2 o# _+ d# i, r+ _+ q8 r6 a! f; ]" h
void        APU::WriteExProcess( WORD addr, BYTE data )
3 _# v: H4 R: S2 r* z# T3 k{
. ]  K2 |% A. J' `: K7 y        if( exsound_select & 0x01 ) {
5 T0 T1 b4 F; e5 t' n                vrc6.Write( addr, data );
7 l$ K% O6 }/ @/ J        }2 p3 M. v. A# e. M7 l% V
        if( exsound_select & 0x02 ) {! }2 X( V# j( f9 i1 I. ?# Z+ X
                vrc7.Write( addr, data );
5 }( q) S: A0 k        }
  o! y9 v! x6 j        if( exsound_select & 0x04 ) {/ S' n: a( b5 j" h2 ~& _$ d% S
                fds.Write( addr, data );1 O  z& F# F: @
        }! z6 ~0 h6 W4 G& w+ w8 u( l7 ^
        if( exsound_select & 0x08 ) {6 {1 M; _- f6 t( [+ i( e
                mmc5.Write( addr, data );6 O# Y, y/ ^' f' \9 `4 R% O
        }
0 q- k; B! U4 f) q0 I" Q4 q        if( exsound_select & 0x10 ) {- W" R: h9 Z. P% W1 l6 P+ \
                if( addr == 0x0000 ) {
! A  A% U# U8 I3 a, h; I                        BYTE        dummy = n106.Read( addr );/ m# {# N/ q: I) U" C0 {9 W
                } else {" K' C0 F" q/ h' |; A! A
                        n106.Write( addr, data );4 L0 D! E/ X) m; x" ^
                }
- G5 D) ^; c' ]$ P        }
4 y/ O2 z+ X' Q5 x) X4 I        if( exsound_select & 0x20 ) {
% X  v6 @! U0 K- b( r/ B                fme7.Write( addr, data );9 k8 n6 Z, }4 e/ X) Z  @
        }
* G4 E, D. c( Q$ W! x/ ~# L7 h}
7 B0 b0 W) S. O) U2 j% f- a6 z1 I: L& Q: w
void        APU::Process( LPBYTE lpBuffer, DWORD dwSize )
5 x3 [# m3 _3 U# O( ^) ~0 N{
$ e' n4 S/ d3 i) vINT        nBits = Config.sound.nBits;
9 c) r+ s: T: x2 m0 g- [! MDWORD        dwLength = dwSize / (nBits/8);
7 E& R) L2 G! TINT        output;
3 s7 ^& n4 [0 h2 H+ wQUEUEDATA q;7 ~% Y, k) @, j; s# Z9 g  H
DWORD        writetime;
1 W% z  ]7 T; C& m& |  h( p: C+ H9 T6 h2 @4 n. R# a* h
LPSHORT        pSoundBuf = m_SoundBuffer;
' A/ X9 p0 J1 b& l8 dINT        nCcount = 0;
4 f1 L* U: |/ ^* s$ m! W
/ g& k/ p% B% OINT        nFilterType = Config.sound.nFilterType;
2 T; z7 p& e/ i! ^
! N* v" s8 D9 V) x( Y! B        if( !Config.sound.bEnable ) {1 a2 I4 e6 E" d" v: g3 S2 {9 A
                ::FillMemory( lpBuffer, dwSize, (BYTE)(Config.sound.nRate==8?128:0) );. L4 A3 e( u- r' P3 I
                return;
8 N. `3 a7 z3 c6 Y( ^" O- j        }5 X' K: `; g9 w) ~- Y+ y& R
4 I5 F8 F. f: P9 q  K  q
        // Volume setup& s/ w, E1 Z% n% K6 J6 B. A, t
        //  0:Master
' Y5 _8 h% \  r. g        //  1:Rectangle 1
' B* j- A' z7 g/ D% |        //  2:Rectangle 2- V) g- H) }: j. |. A
        //  3:Triangle" ~) }9 f* a' T" R0 t$ D
        //  4:Noise
. c/ e% ?6 O2 c; z1 k" t# \* u        //  5:DPCM
  S% u6 u4 h3 r2 Z/ F8 k        //  6:VRC6$ G/ F6 x0 I+ b' q2 }
        //  7:VRC7
/ A4 N4 D3 I) _3 h        //  8:FDS2 i" I+ i; B) M3 U" q% I. E$ P8 L$ p
        //  9:MMC5
/ _! d( Q2 j1 ?/ y* [        // 10:N1067 m0 ~# c, i. R' N. d
        // 11:FME7! c2 q! S+ }3 @7 |0 z0 b
        INT        vol[24];3 ]# O7 G$ k+ r: X0 H
        BOOL*        bMute = m_bMute;: w) v/ D9 l% @" ~
        SHORT*        nVolume = Config.sound.nVolume;6 R4 x7 ^+ o. d0 f

- m2 d( Y* A: X, m8 j. j9 H3 g0 {' r  g        INT        nMasterVolume = bMute[0]?nVolume[0]:0;
& ~" f' Y2 Z! D: v
) V6 r2 }/ B6 N+ J$ c) t        // Internal6 W) P5 f5 ?5 T2 f- |5 _: I
        vol[ 0] = bMute[1]?(RECTANGLE_VOL*nVolume[1]*nMasterVolume)/(100*100):0;
! }; p- x' A" b/ O2 ?6 Q1 S        vol[ 1] = bMute[2]?(RECTANGLE_VOL*nVolume[2]*nMasterVolume)/(100*100):0;* X; O, n: y) D2 C1 c$ l
        vol[ 2] = bMute[3]?(TRIANGLE_VOL *nVolume[3]*nMasterVolume)/(100*100):0;2 z! V+ k+ @, m* z
        vol[ 3] = bMute[4]?(NOISE_VOL    *nVolume[4]*nMasterVolume)/(100*100):0;
4 Q  G! ^% A! z" x" f5 \7 I: H  X        vol[ 4] = bMute[5]?(DPCM_VOL     *nVolume[5]*nMasterVolume)/(100*100):0;) K  a. l8 u0 j& I

8 G8 P3 X. z3 f' v* j2 @$ u8 P3 ~        // VRC6
8 t! M9 e  A9 L8 h! x# U/ ^        vol[ 5] = bMute[6]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
& Z: H* }. _# ~9 u: N) K3 W        vol[ 6] = bMute[7]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
; Y& s2 A7 T/ H% g        vol[ 7] = bMute[8]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;& {/ N; ^$ n" T. n" z/ x0 |; B4 @

/ g8 C8 N  H8 ?3 q6 j( m* c        // VRC7
7 H+ L- Y) U. G        vol[ 8] = bMute[6]?(VRC7_VOL*nVolume[7]*nMasterVolume)/(100*100):0;
+ M0 P& P3 K+ `8 F2 O# f( j, n
% t  I3 {2 I  L# I2 f- T        // FDS
# Y  v' k6 R( C' v( m        vol[ 9] = bMute[6]?(FDS_VOL*nVolume[8]*nMasterVolume)/(100*100):0;5 U/ z- ~8 y9 J+ }
# _- v% M3 }* w1 R/ `
        // MMC5
% x/ v) R, b3 ^% l; Q        vol[10] = bMute[6]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;3 z, o7 m3 M6 t- w4 V" a/ D9 q
        vol[11] = bMute[7]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;2 j, L3 s3 {( U$ Q% [* A- u2 r
        vol[12] = bMute[8]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
: M" |  M7 W% t. w- f* f0 [5 F% `5 R# w8 c+ i+ m0 ~
        // N106( i8 Z5 h- z, b2 q0 |& x2 @
        vol[13] = bMute[ 6]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
0 f, x2 M' t$ I: S4 g        vol[14] = bMute[ 7]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;* d% L/ q; m" m  D
        vol[15] = bMute[ 8]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;# v" u% ^0 `# O3 }7 L
        vol[16] = bMute[ 9]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
  ]" X, K" R6 r! n        vol[17] = bMute[10]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;$ H1 b4 |% D. M* n. u
        vol[18] = bMute[11]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;) V! V% z( b, w) f) V: g
        vol[19] = bMute[12]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;  G" h$ j( [' |& t* Z
        vol[20] = bMute[13]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
, n) q9 M9 [$ a( a; K2 l' W8 e& c  p
        // FME7* g+ m5 @8 O) q# Y0 K5 Y: q3 ?" K0 N
        vol[21] = bMute[6]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
3 L& Y  b/ n$ R' @+ I  L; M' f        vol[22] = bMute[7]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
% P; ~1 \5 j  ~" O7 G5 c; [        vol[23] = bMute[8]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
6 t& x# ~1 x* O& z# v
/ S  r# ], p3 j5 c//        double        cycle_rate = ((double)FRAME_CYCLES*60.0/12.0)/(double)Config.sound.nRate;
+ e2 H' v7 W/ f# e6 e5 z3 A  O/ E        double        cycle_rate = ((double)nes->nescfg->FrameCycles*60.0/12.0)/(double)Config.sound.nRate;9 {& ]- v! T: W6 t

. L" M+ n  V8 }2 T        // CPU僒僀僋儖悢偑儖乕僾偟偰偟傑偭偨帪偺懳嶔張棟8 e. T1 j  Y1 `' F9 u, W9 M
        if( elapsed_time > nes->cpu->GetTotalCycles() ) {' B/ B! o% u3 b5 Z) E
                QueueFlush();4 \; R9 O& q# b3 u# L" U" H
        }$ b8 y3 ]5 c3 a+ ^8 l

% @7 y: X" T1 Y! |  Q        while( dwLength-- ) {
( L% K+ K0 E% [* g& E; g) M                writetime = (DWORD)elapsed_time;
1 `0 i! b* \! v/ \: k5 w
/ o/ {' e4 W8 x7 V                while( GetQueue( writetime, q ) ) {4 k9 U, W" }6 P: I7 R( M
                        WriteProcess( q.addr, q.data );
9 j5 z5 \9 e1 c& q  y                }
# G6 U0 E8 y1 k/ u6 F' w0 ~  f! O* v7 [  B
                while( GetExQueue( writetime, q ) ) {
+ I/ \- b0 U! K% \                        WriteExProcess( q.addr, q.data );, r$ c+ a8 J/ P3 I
                }
% e( l( q6 w. |( i, M+ I: M* w! z7 Z6 @6 q, U. y* \4 L: v1 \
                // 0-4:internal 5-7:VRC6 8:VRC7 9:FDS 10-12:MMC5 13-20:N106 21-23:FME71 }/ F7 k9 j! [
                output = 0;
, K, `; {, ^: f1 w9 `                output += internal.Process( 0 )*vol[0];
2 _: q" }9 d" l- C9 V, J                output += internal.Process( 1 )*vol[1];0 [* x. E! V  g) L2 R, Q
                output += internal.Process( 2 )*vol[2];
9 c2 ~* H9 e( i3 |                output += internal.Process( 3 )*vol[3];( }3 y0 O, P4 v3 V' j
                output += internal.Process( 4 )*vol[4];" Z1 q7 v4 g4 K5 [
. s+ l2 i+ A: a
                if( exsound_select & 0x01 ) {4 o4 j6 N! D& H; k% U
                        output += vrc6.Process( 0 )*vol[5];# K( N  W$ E; W# i5 L; e2 ]6 h9 I  a
                        output += vrc6.Process( 1 )*vol[6];9 [: d; Y- B2 |9 U: o) y1 u
                        output += vrc6.Process( 2 )*vol[7];2 n+ y2 I7 Q1 m* `4 F, J/ B7 E
                }* }; M: b7 k1 K6 Q# B3 }
                if( exsound_select & 0x02 ) {* Q, f9 s4 F# t  T3 t
                        output += vrc7.Process( 0 )*vol[8];
9 r& @5 l) z% T( |$ Y, @9 }                }+ m4 i" K! h& q2 F
                if( exsound_select & 0x04 ) {
$ t1 |% _* a0 P0 [' `' W2 o                        output += fds.Process( 0 )*vol[9];
# p% j6 y. k! ^* ~                }4 v0 x: m' z3 V4 _4 U
                if( exsound_select & 0x08 ) {7 }- b. K5 ~5 @3 s% T: Z0 m
                        output += mmc5.Process( 0 )*vol[10];
& e& x" }3 C0 w! j                        output += mmc5.Process( 1 )*vol[11];3 ^" F& E- v! [$ m. e
                        output += mmc5.Process( 2 )*vol[12];+ t2 `: q. ?" a! A
                }& l( Q7 V# r$ ^4 @# b4 m
                if( exsound_select & 0x10 ) {0 v& \+ e) T4 T+ D" y* h
                        output += n106.Process( 0 )*vol[13];
, O. j7 o+ i5 g( N/ ]* L* D1 N                        output += n106.Process( 1 )*vol[14];. g# J* `2 d$ N
                        output += n106.Process( 2 )*vol[15];3 h8 ^" D" ?$ y! f( H+ i7 E
                        output += n106.Process( 3 )*vol[16];+ b7 a1 P3 b2 o+ h$ K
                        output += n106.Process( 4 )*vol[17];3 Q- ~5 {6 }6 T6 G
                        output += n106.Process( 5 )*vol[18];$ D5 d$ p" B% T) h9 {
                        output += n106.Process( 6 )*vol[19];
& ?/ o" J4 M2 T) C                        output += n106.Process( 7 )*vol[20];/ u% p" k$ s# L7 s) `; X
                }) e4 h- d; e/ I5 E( L8 j7 h9 H
                if( exsound_select & 0x20 ) {
- N  g4 u6 H1 g( l& F& C, u$ T& N                        fme7.Process( 3 );        // Envelope & Noise/ e/ i& q7 r  ^5 A" D& [" M% x/ G3 T
                        output += fme7.Process( 0 )*vol[21];; C% k) m1 o/ f+ P
                        output += fme7.Process( 1 )*vol[22];0 T% Q' s% o: U' t: ]
                        output += fme7.Process( 2 )*vol[23];1 I- E4 p- B+ J2 }  [% Z, H
                }
0 V9 y1 ]2 g, i! ~8 h* u; m
" p# W+ b$ U' I; [8 y                output >>= 8;
; x# y5 T& e1 s) a2 l2 X  n4 |$ W8 x0 N
                if( nFilterType == 1 ) {# O7 M+ {0 o  O7 _1 j
                        //儘乕僷僗僼傿儖僞乕TYPE 1(Simple)
* Y7 c; i9 I0 K! c2 w* c% }9 g                        output = (lowpass_filter[0]+output)/2;
, R* M! G" p3 ?3 e2 ~' W                        lowpass_filter[0] = output;
5 i1 a$ y! |9 {- i) a                } else if( nFilterType == 2 ) {
% V" I. r6 ^# v                        //儘乕僷僗僼傿儖僞乕TYPE 2(Weighted type 1)
8 H( f4 Z! D# V1 A6 S$ ]                        output = (lowpass_filter[1]+lowpass_filter[0]+output)/3;. _" ~, k( g5 X7 q7 j. }+ Y+ \; ^# W
                        lowpass_filter[1] = lowpass_filter[0];' Q( B$ W) [8 V+ t
                        lowpass_filter[0] = output;8 q, ?: F" v  _% P2 C8 D# G# g
                } else if( nFilterType == 3 ) {( O4 p% t3 F( z* A
                        //儘乕僷僗僼傿儖僞乕TYPE 3(Weighted type 2)3 q& R& V( D2 w% N( ?
                        output = (lowpass_filter[2]+lowpass_filter[1]+lowpass_filter[0]+output)/4;# o, ?: j0 _$ z3 \, D* s6 S
                        lowpass_filter[2] = lowpass_filter[1];; L. ~# n6 T) |3 b1 \2 S
                        lowpass_filter[1] = lowpass_filter[0];! ~$ M) B. D2 _& g+ h+ t2 W
                        lowpass_filter[0] = output;
8 x, N7 [# z& i" I% z$ Q, Y, a                } else if( nFilterType == 4 ) {
; ^8 n8 M! G; [                        //儘乕僷僗僼傿儖僞乕TYPE 4(Weighted type 3)
9 _% x) E9 f" V& l/ t                        output = (lowpass_filter[1]+lowpass_filter[0]*2+output)/4;! v" e3 u9 a# V5 V
                        lowpass_filter[1] = lowpass_filter[0];
( \1 s% l. f) H1 L2 g$ M" N                        lowpass_filter[0] = output;
$ s* x, y. P6 y0 V, {                }
# I9 f% v( ^( {7 i: l2 N( t/ D
2 O0 h9 [7 x1 A1 N. T#if        0% ?: U; ?3 J  I& z0 `
                // DC惉暘偺僇僢僩' i/ [5 U  S5 l7 n' L" ?% o- ~
                {
, J6 m0 ^7 k, t2 x2 [                static double ave = 0.0, max=0.0, min=0.0;
  B( A# p6 N+ P& D4 w. A4 t                double delta;7 {9 y3 g* ]4 \/ |, v
                delta = (max-min)/32768.0;
6 a( W. b! W; s* D                max -= delta;( L4 f, M' T' W, |9 I  h
                min += delta;. \/ x4 A! X+ b9 O/ a9 o8 j' E1 P
                if( output > max ) max = output;: K: D! G6 V) ~2 U1 A
                if( output < min ) min = output;
1 J- E9 L6 F9 P                ave -= ave/1024.0;
0 B4 ]9 a, s% z                ave += (max+min)/2048.0;4 q# ?6 J8 y6 o6 l( v
                output -= (INT)ave;
7 _8 y3 X) H% }8 T  E' k0 ^                }' P; O! o5 }$ g
#endif
1 U% {+ U8 {' n: _, e#if        1
( G8 S5 A' X9 e# ?' u$ x                // DC惉暘偺僇僢僩(HPF TEST)
# [5 a" @: k( _                {; O$ Y  Y. Y5 a4 a4 R1 L7 Q
//                static        double        cutoff = (2.0*3.141592653579*40.0/44100.0);
6 K3 ~& _7 k/ s9 P6 x: ?1 x# ]) U                static        double        cutofftemp = (2.0*3.141592653579*40.0);' x1 [" T  `& X  ~+ X" Q
                double        cutoff = cutofftemp/(double)Config.sound.nRate;7 h* R3 a5 }+ H; J4 o4 \" N
                static        double        tmp = 0.0;
) X0 \4 H( T1 m! a) H7 u$ w                double        in, out;
. K9 y& Y' y2 E' U: G0 k4 V
4 ^8 H" e" d, ?# u1 R7 Q                in = (double)output;' U. _' ?6 |# e, u
                out = (in - tmp);
! |5 ^( M( t: U                tmp = tmp + cutoff * out;
1 V  T) I, v+ W' F6 Y7 T' r6 v2 _  ]! p' T) R0 G
                output = (INT)out;3 j- b6 x& u7 W) X( ^
                }
& L0 }. c7 R( ?% V4 D5 H  g#endif
- |, i: `, w  A4 \; }#if        06 w$ f( U  X( i6 T7 R2 \, L
                // 僗僷僀僋僲僀僘偺彍嫀(AGC TEST)
5 |9 D* i% i* B3 I$ Y                {8 J8 {, _4 i' g0 x" d2 p
                INT        diff = abs(output-last_data);' E# F; S! O1 e' t5 @  c. m
                if( diff > 0x4000 ) {, P$ M8 r0 i2 {( e: S$ W
                        output /= 4;/ k, g+ G! a, t3 \  N; l, {( X
                } else * k4 n3 {8 T+ S2 {8 M
                if( diff > 0x3000 ) {6 B6 E. n/ m3 _* x
                        output /= 3;
- f6 h- T. D; A: N2 C, e7 z                } else: _7 _  f9 c( m5 |' r
                if( diff > 0x2000 ) {& R% y% |. d1 r9 E9 c/ m( Q+ J
                        output /= 2;
. o$ ?% n8 P% \                }
" q$ ?/ P: q$ \) H                last_data = output;# a" \- Q' _1 L) a* w8 s
                }; f* b! ?6 H; d# {5 T, k4 F. }
#endif
( Z  l9 R  ?: O& J1 [) h                // Limit
+ K  P, D8 q. g% c* j" N0 ~1 V                if( output > 0x7FFF ) {/ U3 p% T6 a7 f& ?) |  S5 {
                        output = 0x7FFF;6 `& b% o+ c- b! q/ Y8 a
                } else if( output < -0x8000 ) {& o* {$ P, \$ t- N* J+ p2 c3 I% o
                        output = -0x8000;/ N: Y2 Y6 z6 A
                }+ d# C' M  C0 |6 y* M* ^  M1 H

+ Y2 O) z7 }. }9 R% \+ h                if( nBits != 8 ) {
5 ^$ Q, q- z' {* Y. w# W                        *(SHORT*)lpBuffer = (SHORT)output;3 n+ A. _2 o8 X
                        lpBuffer += sizeof(SHORT);: v. h$ _. n0 s" r) i
                } else {
% x8 S' Q. h2 F% w4 M/ z0 [                        *lpBuffer++ = (output>>8)^0x80;( w' ^* `5 f* ~5 P% Z
                }. c! L8 G5 ?6 {8 h5 c/ u. f" c
6 B8 g4 \2 \" W6 ^# J. w% o" `$ C6 A
                if( nCcount < 0x0100 )
+ }; I- \% L2 J! M                        pSoundBuf[nCcount++] = (SHORT)output;# }% T$ M; E, [5 D

- x$ H! F+ C: X//                elapsedtime += cycle_rate;2 g& y. E5 {5 `& [& q, X* y1 t
                elapsed_time += cycle_rate;, d6 }3 Y( S( I' c5 d
        }
2 V# F7 I  g0 j+ R! Y1 T
4 L2 \1 c/ j$ m; @% W8 U$ C9 F! e#if        1
# l6 T% S2 t- W4 S: Z/ p        if( elapsed_time > ((nes->nescfg->FrameCycles/24)+nes->cpu->GetTotalCycles()) ) {
- w3 ^# c' z, @                elapsed_time = nes->cpu->GetTotalCycles();
7 F! ^- C: b# j5 d2 B        }
2 W6 O+ R0 v# h. A9 k        if( (elapsed_time+(nes->nescfg->FrameCycles/6)) < nes->cpu->GetTotalCycles() ) {% ?7 c+ |2 b% A# G3 ]* `. G
                elapsed_time = nes->cpu->GetTotalCycles();
. `2 J) a3 E: Q        }
0 ]  q3 r5 x' i6 b( p#else% Y; B3 r! t5 Y* `
        elapsed_time = nes->cpu->GetTotalCycles();
4 m8 U0 w- B* J, ~; m#endif
% \% ~- g  Z9 A$ x9 r+ r}
' P2 Z  ]) ?2 j" Q5 J3 @
' B6 c" G: j& f7 v3 y7 m1 U. T% t5 D// 僠儍儞僱儖偺廃攇悢庢摼僒僽儖乕僠儞(NSF梡)
4 h/ Y7 E: \5 u3 v% E$ B. `' o1 GINT        APU::GetChannelFrequency( INT no )& `% g1 F2 ]5 q) k( M
{
! t8 }" Y: r5 @        if( !m_bMute[0] )6 I! u3 o. {7 v8 \% w. P" N. l
                return        0;
+ _* y* }6 Q- c9 Y* ~
6 B! s  r# ~, r/ y$ R        // Internal
, l. q/ F8 T4 m' @        if( no < 5 ) {
# A- w8 i+ {9 q$ Y* h                return        m_bMute[no+1]?internal.GetFreq( no ):0;, c% b. S# o. \* T
        }+ z9 S( G3 Q: e+ [9 C8 t$ {, g
        // VRC6+ q8 X" D. o2 `; i9 E
        if( (exsound_select & 0x01) && no >= 0x0100 && no < 0x0103 ) {
% m' a) o: [! B                return        m_bMute[6+(no&0x03)]?vrc6.GetFreq( no & 0x03 ):0;
5 m9 b. M; z% L" V4 ^1 h7 q8 }        }8 H8 c. e$ L% _* ~6 Z, w
        // FDS$ i; D7 m9 v# s) Y( ?* I& ~
        if( (exsound_select & 0x04) && no == 0x300 ) {
  C$ N  a) u- {" M" ^6 p  w! f6 y                return        m_bMute[6]?fds.GetFreq( 0 ):0;  |; Q& \* q% Y7 _" C* n4 Q
        }: l# w5 I. q; J+ S/ [4 h0 M' Q) m
        // MMC5
# R& l* i7 c! }6 X9 Q/ v        if( (exsound_select & 0x08) && no >= 0x0400 && no < 0x0402 ) {0 g4 d) M( U; h  _" j2 F9 o
                return        m_bMute[6+(no&0x03)]?mmc5.GetFreq( no & 0x03 ):0;1 X' c  D. F8 F3 A2 @
        }6 f* Q# z  R: l  X: ?8 u- @, k1 `* L
        // N106
' @$ Q( R/ f: v; h7 ^        if( (exsound_select & 0x10) && no >= 0x0500 && no < 0x0508 ) {! P5 f; f! o4 `8 E& V; h/ o- l7 x2 N4 O
                return        m_bMute[6+(no&0x07)]?n106.GetFreq( no & 0x07 ):0;
; z. c. f" x! b- m8 q: a# H) V2 |        }
6 E. X; |* k8 u" _) m9 k! n        // FME7
* Z8 S8 B2 z! H        if( (exsound_select & 0x20) && no >= 0x0600 && no < 0x0603 ) {8 }3 z- K" U) `
                return        m_bMute[6+(no&0x03)]?fme7.GetFreq( no & 0x03 ):0;$ \6 N1 Z0 q5 g  R. L2 C1 ~  d% R- w
        }
; E. ^$ Y0 y% Q6 w5 a7 k7 R        // VRC7' T4 S" }$ U) ~+ m
        if( (exsound_select & 0x02) && no >= 0x0700 && no < 0x0709 ) {
8 Y8 ^! R2 A; W% C# C- i: ?                return        m_bMute[6]?vrc7.GetFreq(no&0x0F):0;
6 H' ?/ I3 F4 W2 g        }1 C4 u0 v) G, c
        return        0;
" k/ j) [' V" C; ~* ]# Z/ ]1 s}
( }% m1 H- p; v- b* j9 V( Z( A
* A4 ~1 D, p- I// State Save/Load& w* d7 A, G! z, |, O5 O. ^. w
void        APU::SaveState( LPBYTE p )
( H4 Y' G, H/ p0 U6 H{
2 V9 c" L" M) ?$ r' N8 p+ |/ J% W#ifdef        _DEBUG% h: o' i  v* h9 T
LPBYTE        pold = p;
, g! Z9 H1 _( G/ K#endif
+ ^  }+ F8 s( t/ D2 r2 z: w) f0 s' s
7 o  H# {4 x. ~5 ]$ B3 F        // 帪娫幉傪摨婜偝偣傞堊Flush偡傞. l% z, b4 H5 y+ h. |& d
        QueueFlush();
3 g, t" o7 w5 X$ _. P5 c5 R. k' V6 l8 a6 t- E( \
        internal.SaveState( p );: z- C7 f  ^+ c' D4 R! X4 b
        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding/ q; d" B! Q" T9 {
) p. }2 y$ |( C* ~! [9 s$ s
        // VRC60 i/ i6 O# Y1 P# |8 x! t* |7 Z2 ]
        if( exsound_select & 0x01 ) {$ X9 N! v3 T# l" z
                vrc6.SaveState( p );4 y' I. v, w. G- a& A
                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding6 l& h; d/ ?4 x  k$ ~. R
        }
0 f$ y% \. N. g8 Z9 M& d$ Z0 S        // VRC7 (not support)
+ `  h+ f! Y  R3 y; S! S        if( exsound_select & 0x02 ) {; \7 n+ F9 W: l" e6 ^
                vrc7.SaveState( p );  H2 R% O" P( v
                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding5 ]4 J5 Q5 c% o# Q  m0 o
        }% C2 k3 t( Y3 B! E5 l2 B) z! x& c; I
        // FDS
1 y4 `- |* R% ?( R, Y        if( exsound_select & 0x04 ) {' {- e/ f# c5 q
                fds.SaveState( p );* q0 e% r8 N' E( \3 M0 w
                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding% ~# c3 C6 k: O% Y
        }
& b1 w  `3 s5 J* E        // MMC51 V! s9 o, a& [6 l: r5 d+ p3 C
        if( exsound_select & 0x08 ) {9 e9 U1 A! X/ W$ M1 w
                mmc5.SaveState( p );
1 G9 S# }" U5 E" S( p                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding! L# N6 w4 U9 l
        }# t6 l0 U8 M) h
        // N106) ~9 F& o. F: m6 Z6 ]% L
        if( exsound_select & 0x10 ) {& D  r, x+ ~) L) V$ R" j' O
                n106.SaveState( p );8 f# Y3 I  A7 T1 R9 f
                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding; g, r; X8 R" w2 f% H1 C
        }5 L) }: r' h/ Q
        // FME74 u7 o7 }) D, ?/ F$ X
        if( exsound_select & 0x20 ) {
% S. [  R5 W6 z' k1 ]. r6 X/ D                fme7.SaveState( p );
5 x1 M8 r. U2 a- R( h$ H9 R' m                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding
8 R7 Z  y) d& ]  {        }5 n% {  D: x+ W$ f

8 K/ d$ E) Y' o" }+ o0 N8 b* t#ifdef        _DEBUG& W: N9 Z) y8 j+ O/ o5 D
DEBUGOUT( "SAVE APU SIZE:%d\n", p-pold );
. n: z$ i  _" \9 H! m* |#endif
$ |0 S5 p! D3 B}+ r' o2 X# X' I  ]4 Q
1 J  a8 L2 \7 [2 Y3 |
void        APU::LoadState( LPBYTE p )( j0 ^- {, M4 h$ T1 {3 t& O1 r
{
7 k7 I  }- T5 P' B5 \        // 帪娫幉傪摨婜偝偣傞堊偵徚偡" }( P) I# d+ I" ?3 e. C. U
        QueueClear();
9 T1 i% v9 E% `( b4 _) y, k% A! d6 M- y  i$ [* j+ l9 [+ q" {
        internal.LoadState( p );
1 L% h. V! x5 [# x9 K, N        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding6 m! |& j: s- A9 T- q

  K$ A/ o5 W! K! f! L        // VRC6; w% F$ g! l( d8 I
        if( exsound_select & 0x01 ) {- }4 l% g" J  B% a: q6 d
                vrc6.LoadState( p );' h6 e& P) P8 n& l: [8 l
                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding5 w0 g% @9 @& z. \
        }7 g: N2 E1 O. r& V/ _  t, X, c, q
        // VRC7 (not support)
1 f" C* ]! \8 q5 o        if( exsound_select & 0x02 ) {
; z! G: j5 B3 T6 C                vrc7.LoadState( p );$ x  {9 \% C" U1 r
                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding
% I& W" W; `; u. H5 E        }
! z, Q& u& B/ }) k$ Z        // FDS
8 U. [- s$ Q4 c( S        if( exsound_select & 0x04 ) {
  M2 c/ V* i9 A4 O, z                fds.LoadState( p );- l+ [& W6 f  t! ^" P  x. N
                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding/ `& `' @8 Y4 V1 O& T* U
        }
2 L6 b3 i; z4 m+ z8 p$ E        // MMC5
& n) M3 \* P: T; H& P        if( exsound_select & 0x08 ) {
$ y1 H2 ?9 M% K" `/ W                mmc5.LoadState( p );% t4 V* {6 D0 O: a* ~
                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding0 G3 `! T! f( ]
        }
* x+ U* Y! m- B) m. Q        // N106
0 ~' }4 K& M3 M/ ?6 O        if( exsound_select & 0x10 ) {1 Q9 g; z+ Z% ~2 V& @! n
                n106.LoadState( p );% J3 h2 J8 n& R
                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding
6 b; S) d3 Q  y$ A* |+ @" G        }3 L  S; t2 ]. h; U- l' |
        // FME7
  @9 O+ N6 g# ~2 h. |0 r: ^5 ?; X        if( exsound_select & 0x20 ) {
5 \+ c- H! \- q7 |% @1 t                fme7.LoadState( p );
/ V, b3 y8 a7 p# V# y                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding
9 B' J& k! j+ Y+ h        }
- x9 ?8 ~: N# T1 L}

该用户从未签到

发表于 2009-11-8 17:25:37 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 14:38 发表   N8 t/ U3 O! @, r% }3 \* V
可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。) [3 |, F' G2 ]5 j% g6 b# t
感激不尽~~

- p6 `6 |. u9 W恩 我對模擬器不是很有研究,
  m* K8 O# ]! I& j' P7 x" V6 T雖然要了解源碼內容,可能不是很困難,$ D3 h$ Q& g6 b2 q/ h
不過還是要花時間,個人目前蠻忙碌的。
6 d3 M, t1 o- k  E' R0 k6 {; M& S( ~1 k& \% _
給你一個朋友的MSN,你可以跟他討論看看,
  t" A: N+ T0 {; k7 I( q$ o" N! U他本身是程式設計師,也對FC模擬器很有興趣。# B" M9 F* v& O! W
: a9 L3 i' i6 I
MSN我就PM到你的信箱了。
8 Q1 N4 q" ]4 s2 S7 O6 d7 b; r: i' M% Y
希望你能有所得。

该用户从未签到

 楼主| 发表于 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 发表 * ]6 d* r0 ^7 e. S0 l
呵…… 谢过团长大人~~

5 [# \. l6 K: ]/ r3 M
: x- y2 d0 l$ B- i$ M哈 不客氣,算是順便幫他找個伴,大家可以一起玩。

该用户从未签到

发表于 2009-11-20 13:14:53 | 显示全部楼层
原帖由 李伟 于 2009-11-9 16:02 发表
! U/ x$ \% h# F+ \- a  L- s; a团长的朋友都是神,那团长就是神的boss。
2 i5 B3 X/ M0 G0 A" K" |: D  b, P6 x& J
哈 不敢當,我只是個平凡人,
5 q& l( d; G' K$ s  z9 F要吃飯喝水,光吸空氣是不會飽的。。。。 :)

该用户从未签到

发表于 2009-11-20 13:32:35 | 显示全部楼层
FC模拟器的部分有个人可以帮你忙; Q9 _# S1 W. R  R8 T
ZYH  c( u" U% ?  v0 ]5 H
QQ:414734306/ d$ \% g1 U% U. E) A) a# v
Mail:zyh-01@126.com! Z8 w' n, H" O- h

  P* b) X$ G- I' m  Z他是ZYH Emulator这个模拟器的作者,只是他用的开发平台是VB,不过就6502的实现原理来说是一样的

该用户从未签到

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

该用户从未签到

发表于 2009-11-27 19:09:06 | 显示全部楼层
原帖由 独孤残云 于 2009-11-27 09:48 发表 - B  R$ g0 I" A; T7 S2 n
再次对团长大人和悠悠哥的无私帮助表示感谢~~
; H- u% h" B# r4 ~% G: B
不客氣  ^_^
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2024-12-19 11:44 , Processed in 1.119141 second(s), 18 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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