EMU618社区

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

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

 关闭 [复制链接]

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 09:56:34 | 显示全部楼层
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。
7 o3 j" O9 u5 ]3 E2 ~& B楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~
. M9 ~3 u" u% I' W这里有相应的模拟器源码,就当送给大侠了~~
) C- k5 u/ \$ K+ x6 W5 a1 fhttp://kenkao.qupan.com/5096520.html

该用户从未签到

发表于 2009-11-8 11:31:10 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 09:56 发表
! l- Q8 u5 U. Z, |能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。
6 r! t( ~$ t" y  a/ k5 X楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~
6 ~! ?# A) @  t- R  h这里有相应的模拟器源码,就当送给大侠 ...
6 }) |/ c  @, j& {* D$ ]. G. W
聲音部分(Audoi Process Unit = APU):: Y. V# b. x" [. }8 R! H; D
.\NES\APU.cpp
6 A" \% d( w0 z) [& m1 h* w7 V3 J.\NES\APU.h& G% |+ f% _1 Q7 p

. c8 r# s& J' A9 r' A3 V% {+ Y, c2 q, y
影像處理部份(Picture Processing Unit = PPU):" E  ~' C0 }( h: J- y8 @
.\NES\PPU.cpp
+ L* H2 K, X* R.\NES\PPU.h
6 v  \- I% }+ ]* e. w' _( n
5 x# {$ _- u) y4 {( q. z如果原碼用C跟ASM混搭也不錯

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 14:47:50 | 显示全部楼层
这是我手中源码Apu.cpp的内容,敬请赐教:
( G. s) r( D6 j& W3 a, B(由于很多专用术语和算法机理都不明白,所以看不大懂……)$ @1 e# U# K$ Y; B, G; e( P* V
//////////////////////////////////////////////////////////////////////////; r* o- P6 [& z/ t0 n1 q
//                                                                      //% k* Y% @( E# u3 ~
//      NES APU core                                                    //4 o3 r6 F5 _+ `4 m
//                                                           Norix      //. q* |4 W; I" y; A4 u* F4 z  S" }1 h
//                                               written     2002/06/27 //
- w) U3 c' N6 \//                                               last modify ----/--/-- //' v9 F" N8 S! W$ t5 p" F
//////////////////////////////////////////////////////////////////////////
* K* y  q5 j" ^3 K4 G4 r#include "DebugOut.h"
, i' n% ]  d/ }$ `. z5 n' f" m% K#include "App.h"
# g9 f  a8 F$ a0 k) Q7 u* s; C#include "Config.h"4 K( t# L) M1 W
" r9 K# S. G6 P( {: a
#include "nes.h"
! H. d+ ^% T, ?/ Q& j" o#include "mmu.h"
2 d- M* H) f! E. ?* \#include "cpu.h"
- d: Z/ |) h' D0 @% {" T. a#include "ppu.h"
8 p/ G) h. p3 \. ]% D1 f( V#include "rom.h"& W% ]' b# K3 c* R( s
#include "apu.h"& n$ v( K; v* v  W

1 U* N  q( g0 R+ y+ P// Volume adjust
6 w/ ~) M* p8 g  h: B8 c9 M! O; s* Y// Internal sounds6 Y. w" {, N9 V0 i
#define        RECTANGLE_VOL        (0x0F0)
, H; v1 F; `  u& k. f, }#define        TRIANGLE_VOL        (0x130)
! V( n2 i3 v2 X2 z+ A2 x) a#define        NOISE_VOL        (0x0C0)
" j7 N# D" q+ Y& J* S, j2 M0 ^#define        DPCM_VOL        (0x0F0)6 E# ]5 S- }" c1 G9 A! V: E6 U
// Extra sounds9 X& h+ {2 ]9 d7 E5 ^4 ^
#define        VRC6_VOL        (0x0F0)
" T* @) D8 C6 g5 q6 Z: L. e% q#define        VRC7_VOL        (0x130)
. Z1 S: B. p2 o# u! M#define        FDS_VOL                (0x0F0)* F7 Q0 L6 Q( V8 q
#define        MMC5_VOL        (0x0F0)* E5 |& m+ @4 @  b" N! I
#define        N106_VOL        (0x088), A2 l% t3 ^/ f5 q' I
#define        FME7_VOL        (0x130)
: n( L- G/ J6 j- n# T, ]
+ i, G0 y3 s, H/ O( w3 c8 `1 HAPU::APU( NES* parent ), }2 ?, j) K/ u' x& n( |+ D/ I: b
{
& \5 E2 |1 B$ m: j5 d4 D1 _. @        exsound_select = 0;
7 S/ R7 H& K# w9 H- H7 ~3 o% D) n# w" M9 m' K
        nes = parent;
7 O5 G* o. h; y6 e6 m5 h        internal.SetParent( parent );! z. `* G0 w. I3 V. S7 c1 i
+ b. K/ S7 F1 j4 e4 L4 A
        last_data = last_diff = 0;" S% x4 q+ j1 [- T
5 o. D1 @. M- L0 G0 w( K, q
        ZEROMEMORY( m_SoundBuffer, sizeof(m_SoundBuffer) );
! g9 ^9 G$ C  K' A7 |# ?
" o* ]) p' t9 }" l        ZEROMEMORY( lowpass_filter, sizeof(lowpass_filter) );
% P6 h1 l- ?2 j9 |        ZEROMEMORY( &queue, sizeof(queue) );9 I: @4 W5 [! z; W% c8 v
        ZEROMEMORY( &exqueue, sizeof(exqueue) );3 J: A  q  Q) o- l

( L4 F: o' T6 I& i$ }: L! }        for( INT i = 0; i < 16; i++ ) {
. U, Q" P: S) H- N1 {! X                m_bMute = TRUE;$ [& s! w; {+ o" |; L5 c' Z% l
        }
7 I% \- @$ \* B8 {0 o}4 a( g0 [9 s- s% u2 s

6 i" s* ~% i7 J( kAPU::~APU()( @( E) ?) o! P
{  R3 r8 h0 c" {. b/ H  ]! N
}4 a8 m) v: n* k! w
  Y/ l' w$ e7 Z
void        APU::SetQueue( INT writetime, WORD addr, BYTE data )- V  t5 D2 `1 s# z  L5 z. l
{
4 |- e% G4 e1 x        queue.data[queue.wrptr].time = writetime;
8 p# y" A: @7 b- `5 I4 c; \; P        queue.data[queue.wrptr].addr = addr;  O+ w1 w6 B8 D  t
        queue.data[queue.wrptr].data = data;
: `/ y$ D* T5 g) U6 Y        queue.wrptr++;
5 }. D% p3 A$ H# F0 H! ~        queue.wrptr&=QUEUE_LENGTH-1;7 p; E5 p0 ]3 T9 j: v$ R' v' S# o
        if( queue.wrptr == queue.rdptr ) {' t6 h. C1 i" _- Q( s9 K3 v
                DEBUGOUT( "queue overflow.\n" );; `' Q/ _  L( Y
        }
$ p3 S' Q  W4 a3 O}7 D* ~0 A- m7 E3 V) y

! z' {. h8 V* G  ABOOL        APU::GetQueue( INT writetime, QUEUEDATA& ret )+ A/ B9 V* W/ ]
{
* ?! |' C, A: F8 }8 [5 i        if( queue.wrptr == queue.rdptr ) {
0 x- X. L1 a. ]                return        FALSE;  y0 p6 O$ D1 g; P8 S% Q, r
        }
# C- v) N4 P4 T$ W; ^* G        if( queue.data[queue.rdptr].time <= writetime ) {
* H/ h+ N" I( H4 \4 t# O% D- d7 k                ret = queue.data[queue.rdptr];7 i9 [  u; Y  k0 J
                queue.rdptr++;5 S6 A; w9 d  k0 |# d- A3 ^: `; I9 y
                queue.rdptr&=QUEUE_LENGTH-1;
' ?* w3 M5 `4 Z& L0 y) l' c; @                return        TRUE;! E' z" W, q; h) o: p
        }% z; {5 K: |' E; ^, s
        return        FALSE;" |3 d6 D; z4 j
}' w/ Q* {1 h8 j8 x, ?) X

) D2 J5 Q$ e0 P, L! E. Yvoid        APU::SetExQueue( INT writetime, WORD addr, BYTE data )7 C6 ]2 x: a; A) I6 o2 ~6 b
{
* C3 |; V8 T$ g! ]9 }. j% s        exqueue.data[exqueue.wrptr].time = writetime;8 v( D/ i* d' e9 y
        exqueue.data[exqueue.wrptr].addr = addr;9 H7 }3 Y6 z5 o- n/ B* {
        exqueue.data[exqueue.wrptr].data = data;# h4 g: j* z; ~/ ]% ~9 Z* u- z
        exqueue.wrptr++;
1 L' j( h, W  ?1 a  h        exqueue.wrptr&=QUEUE_LENGTH-1;+ U! O; m( M( ~7 m
        if( exqueue.wrptr == exqueue.rdptr ) {
* T' ^2 Q& i0 U6 {( B                DEBUGOUT( "exqueue overflow.\n" );1 `+ S9 ^" b# W" z6 ~5 Y
        }3 r3 i3 I; U3 w$ W. t
}
4 X' w  t8 X0 T, F' K3 h4 k$ e* F+ Q  w' q  L6 t$ }
BOOL        APU::GetExQueue( INT writetime, QUEUEDATA& ret )# @+ B& A' V( S; P" h
{
+ [" o' D! c5 J3 X& C; N        if( exqueue.wrptr == exqueue.rdptr ) {9 }) J* {0 z. L1 |$ l
                return        FALSE;
7 Q( I$ b& k. r9 A0 x, s+ q        }
, S$ q; \! e' {' P! C8 R7 @) l* Y        if( exqueue.data[exqueue.rdptr].time <= writetime ) {
6 r3 u1 f8 d1 {1 X4 L                ret = exqueue.data[exqueue.rdptr];
( f& e9 \6 w% C$ X                exqueue.rdptr++;
: L9 \: E6 P0 X! T                exqueue.rdptr&=QUEUE_LENGTH-1;
% P9 N* G. u9 I: n                return        TRUE;
6 ^3 p& l9 g# j5 N8 O* L        }: w, U9 s: M" d9 l/ ]/ p( l$ i: c
        return        FALSE;# {( z: b/ B4 ?3 A
}
: b6 ?( o3 W" w" a: |$ A. D' j% p0 ~
void        APU::QueueClear()
! K5 Q% J) u5 x& L3 H{9 ?1 g2 D9 |% J2 R$ e
        ZEROMEMORY( &queue, sizeof(queue) );
: G' g8 o. c+ G9 i* V! I! E: l        ZEROMEMORY( &exqueue, sizeof(exqueue) );
. z& b' |3 N- \}4 y9 \- C% C( ]# U6 E  l5 H

+ C$ l, a: Y6 |8 mvoid        APU::QueueFlush()3 s% C; G0 t  R! i/ O9 I& `2 J6 T
{" g, b1 A: x8 |, C
        while( queue.wrptr != queue.rdptr ) {
( R2 I- u! T9 d6 N" G# A% S                WriteProcess( queue.data[queue.rdptr].addr, queue.data[queue.rdptr].data );- y( N* A' w- o( G( D7 `
                queue.rdptr++;6 R3 i0 `4 f' K$ H
                queue.rdptr&=QUEUE_LENGTH-1;& Y6 {, a' T  W* T% K
        }' e2 m3 \0 C: i) ~5 _
: a  r! |! D) G  O3 _1 n' s
        while( exqueue.wrptr != exqueue.rdptr ) {
% U% K4 X# E  p/ E. @5 \! n                WriteExProcess( exqueue.data[exqueue.rdptr].addr, exqueue.data[exqueue.rdptr].data );
# V8 D1 S& ]$ y6 w                exqueue.rdptr++;: D3 l' k# y% d
                exqueue.rdptr&=QUEUE_LENGTH-1;- r; k" Q/ h- D9 w- s& ^. v
        }
$ }$ F) r' R% l/ d+ N. L0 y, L- B; S}% V: \% p3 ?3 {7 r2 t- T
+ a4 ?# s5 }7 E6 c7 z
void        APU::SoundSetup()7 W1 ?. r, K# u) ^/ l
{
+ S7 T* m' k* _/ H" `6 d3 d        FLOAT        fClock = nes->nescfg->CpuClock;9 ^# `* v, e8 ?' q6 l5 p  I
        INT        nRate = (INT)Config.sound.nRate;
$ ?' _4 ?, v8 ?# D8 d        internal.Setup( fClock, nRate );2 q# h1 T+ h3 F/ e( h# U) A  ^
        vrc6.Setup( fClock, nRate );
( J% V' D' S# w+ M" T7 L; K        vrc7.Setup( fClock, nRate );+ a5 ]8 y7 k7 G3 p* ~
        mmc5.Setup( fClock, nRate );/ e: ~' E# Y9 ?8 P
        fds.Setup ( fClock, nRate );
( x$ c  w+ a  [: {4 i4 w3 E        n106.Setup( fClock, nRate );
( e- E( ]  n/ _" |& m        fme7.Setup( fClock, nRate );
: m( m: W  G5 ?}
5 R2 l1 V& z. Z5 c+ |
7 ^: t( B6 ~$ R1 G: d7 n5 m2 ]void        APU::Reset()% G5 L3 Z8 _; G2 A5 m4 Q7 n
{
/ o1 u/ u9 L, F6 \        ZEROMEMORY( &queue, sizeof(queue) );
0 i/ P: o  s! U3 D        ZEROMEMORY( &exqueue, sizeof(exqueue) );3 O3 _0 V$ a; C7 D6 t; V: }

7 B1 f) j: Y4 N6 r        elapsed_time = 0;
) i; J; s# F' Q3 H
6 U! X& R5 k! T& T% M" \        FLOAT        fClock = nes->nescfg->CpuClock;
8 x  w. O1 o2 E6 W$ J1 {8 e' d        INT        nRate = (INT)Config.sound.nRate;
0 `. V7 J* l: g) j: _- H        internal.Reset( fClock, nRate );
" w6 ^9 q' Q( s. z! u  S        vrc6.Reset( fClock, nRate );
4 I7 C( K: e" |# t0 L- L  v        vrc7.Reset( fClock, nRate );8 H  T5 ?  d# U7 K7 W
        mmc5.Reset( fClock, nRate );. Q/ R% \  K: ~  }; w  [. |
        fds.Reset ( fClock, nRate );% h, H$ o3 a1 R
        n106.Reset( fClock, nRate );9 a+ ~* f, a1 H; `2 p
        fme7.Reset( fClock, nRate );
" \  N: C6 v- S1 P1 n8 m5 `, j. `, U9 P
        SoundSetup();7 _# P9 w0 Q9 J: q- H; N% w% Q
}/ g5 j2 T3 Z, W) u
7 z0 _/ ~# e" @1 E! ?) t( j
void        APU::SelectExSound( BYTE data )  r" `8 ~" H& V/ W7 ]) e+ v' X
{# c% ~3 {' i, F4 w
        exsound_select = data;; G% m" C6 _4 s
}
( e7 W: v5 R# f  h! }9 r6 G4 c* x3 ]8 A  ]' m3 |
BYTE        APU::Read( WORD addr )! ^  j/ |& A  {- p# O" {. m& X
{
* Q' }+ F9 n: U# }. \9 E        return        internal.SyncRead( addr );! n0 V0 T' n& N4 c4 ~) X- P
}
/ D9 _2 K$ e( v3 K* ~8 s
7 ~2 @, v& b" w  Tvoid        APU::Write( WORD addr, BYTE data )
) @4 b' @! N' P6 P" Q/ t{7 p/ Q4 j" [5 h4 C+ v# v
        // $4018偼VirtuaNES屌桳億乕僩1 U: k6 k9 n6 Z, R" l8 d
        if( addr >= 0x4000 && addr <= 0x401F ) {
' s; z$ B  J" g7 T" C                internal.SyncWrite( addr, data );/ }7 A, @) n( W0 c) p2 o4 l+ n5 k
                SetQueue( nes->cpu->GetTotalCycles(), addr, data );
8 v  Q+ _) p$ y* D! K' n        }7 C; z( p9 j* C. R4 c; ]" l
}
* ^5 z$ J% v+ b2 U# ]# f0 m* a* X% h& x6 L: Q- q
BYTE        APU::ExRead( WORD addr )* `$ d5 z8 o" T3 e- R
{- N( N7 A7 t* f. M7 D2 _( ?! u' x9 M
BYTE        data = 0;
4 X# p) {+ r4 j7 o( x( Q# d/ o# h# \: V
        if( exsound_select & 0x10 ) {
, K! t( V9 H" U) l3 ~/ e7 s! j                if( addr == 0x4800 ) {
# I8 \. s( G6 ]5 X! ?  v                        SetExQueue( nes->cpu->GetTotalCycles(), 0, 0 );
9 T, `* N* J; @6 i6 ]4 [                }
' v/ p' }- ^( T# E# I. c        }9 K, `$ m+ T& p0 v" R
        if( exsound_select & 0x04 ) {
8 n' |5 F+ z. Y0 n                if( addr >= 0x4040 && addr < 0x4100 ) {5 ~. R" ^! m8 [5 V2 M* Y
                        data = fds.SyncRead( addr );, J0 V1 |# S- W
                }1 n- {7 [. t7 U6 s1 K2 r# g
        }
% T' u$ ~% k% ?        if( exsound_select & 0x08 ) {
$ I- J1 l4 t4 P" o6 W' b                if( addr >= 0x5000 && addr <= 0x5015 ) {
$ N8 Z7 E% [2 s" N- ?: w                        data = mmc5.SyncRead( addr );
2 g, S7 P$ K( R/ i7 m( H$ o                }
7 m9 S, o+ p9 U; Q! D* k        }! g" h; V7 _/ a* e  L
0 v- o0 ]+ K# v/ r$ P8 ^! M. k! g$ C5 p
        return        data;
! [% B7 q& I$ }/ r}
- Q) a" w# S/ I2 j5 P
( F0 S* q! @. q5 H) g+ {void        APU::ExWrite( WORD addr, BYTE data )
* K) J; t4 ]( C& L- B: v{1 ^$ o5 |/ F7 M8 a
        SetExQueue( nes->cpu->GetTotalCycles(), addr, data );7 F2 Y* N; a! r1 d9 ~# h  S

, R5 g; E- {& t2 ^0 F$ n$ b( r9 D7 p- h        if( exsound_select & 0x04 ) {
' I. N' ?  U, N& i  Y                if( addr >= 0x4040 && addr < 0x4100 ) {
/ Z- f7 t0 \) W( F' }                        fds.SyncWrite( addr, data );
8 q/ W2 o8 v" E4 G9 t6 [                }
4 ~! j$ i9 a- K        }
+ z7 B( u7 c' P0 C. r2 d* P$ E) \1 q: K& V9 m6 V+ \4 D/ |
        if( exsound_select & 0x08 ) {
1 Z. z) F, W1 U6 d7 t+ I& }                if( addr >= 0x5000 && addr <= 0x5015 ) {
$ F7 @9 _5 ^% |1 F                        mmc5.SyncWrite( addr, data );
- J' n8 I" s0 d  p                }
9 i$ S: Z, K2 p        }* k- p' O! r6 N9 R4 l
}
4 n1 H  X* V7 I: a' y& Z* Z( Y" \2 k3 _& l/ I' W
void        APU::Sync()$ S" j& X$ P4 o0 g4 @$ ~1 k8 v
{
% o* D+ q: v4 h3 n: c/ B}
# R) `6 S6 S  W5 ~1 M: i2 U: i9 V$ ~( W
void        APU::SyncDPCM( INT cycles )4 U: N! p( |1 F) ^
{
" @4 o3 s7 W" t+ K/ j  \2 O        internal.Sync( cycles );. M! d8 `0 T, N( L! a

- S3 ?2 H$ k8 S& `7 g( d        if( exsound_select & 0x04 ) {
& m! m" @" @2 _( f9 Q- Y                fds.Sync( cycles );
9 s0 Q& A6 H0 u. b) ~8 \& K% b        }+ i  z! i( C7 Q  [, h6 L6 H
        if( exsound_select & 0x08 ) {
; k0 j7 r, w! O( o1 f                mmc5.Sync( cycles );+ l+ F" I) O. V, S
        }
! e% Q1 Y" X$ C2 Q5 D7 k}) X- D! y) x9 c4 x- y
0 u& k6 X- q! B
void        APU::WriteProcess( WORD addr, BYTE data )
* @  s- H3 r  F$ P: U% l{9 }( z9 c- U! n) Z% P6 ^- Y5 J
        // $4018偼VirtuaNES屌桳億乕僩2 q, U$ a8 s5 B5 }' g( w, t. e
        if( addr >= 0x4000 && addr <= 0x401F ) {
8 O, u: s8 M. D( z                internal.Write( addr, data );
/ Y9 F/ ^; [  }% v! S% `0 p1 V        }3 c0 b" a- P8 k7 t
}+ W# X; J  G. M9 V
0 L8 d! Z& _: p& o4 ^0 s
void        APU::WriteExProcess( WORD addr, BYTE data )& S( b4 z: N. H$ |# P. o1 u
{
2 ^8 u9 j5 Z4 ^1 z4 X$ M0 u" l6 ?        if( exsound_select & 0x01 ) {/ f2 w- l. t. k% \  E4 d
                vrc6.Write( addr, data );
3 w4 Y, v) V2 C9 v- v        }
1 b/ u: f* ]* Q5 w3 v9 ?1 I        if( exsound_select & 0x02 ) {8 o3 Q# o' b" @9 K1 r
                vrc7.Write( addr, data );- r$ [& b, i3 u" j
        }
4 ^9 n4 e' d% `5 Y; m        if( exsound_select & 0x04 ) {# d9 H. y% o3 a. X* g- ]
                fds.Write( addr, data );
3 b% L& Z: k# e2 c8 n8 G        }
) A' n/ P0 X6 \# y7 c2 [+ y# h9 e        if( exsound_select & 0x08 ) {
  C: R0 h/ C  c$ u                mmc5.Write( addr, data );
& l) N. l, f! ^4 C& U6 ?* Z0 c        }
- Y) v3 _' x* I$ o! K        if( exsound_select & 0x10 ) {/ a( o; }: D  F6 u/ r& j
                if( addr == 0x0000 ) {9 u& d; X! C( H* A( q; ~
                        BYTE        dummy = n106.Read( addr );
' R$ f; L. b- D7 G9 c9 l                } else {1 b. q& A1 h4 [* k  z
                        n106.Write( addr, data );& U' s) X% t1 P% p
                }2 a# N$ n" l1 F' i5 U( Y
        }0 m0 d. Z: z* c2 o
        if( exsound_select & 0x20 ) {
5 [' M. E/ g' Q' t                fme7.Write( addr, data );
: y8 @- v% |3 ?9 q6 z4 m        }
  R" y- I: r, {# p2 a, ?/ ?2 t: t/ o}
1 z0 t, w0 S- z' M8 I& j- l# s0 I
' ~" o/ s6 X3 K) A( ?) O; avoid        APU::Process( LPBYTE lpBuffer, DWORD dwSize )
! w9 U# P6 f. E1 F{8 v  O& ]* t2 z6 Z' g
INT        nBits = Config.sound.nBits;" p: P- u5 ~# d3 J7 M3 X% e# i
DWORD        dwLength = dwSize / (nBits/8);
5 T3 W1 c* a( x% DINT        output;% I0 `. a/ I7 u# ?- M/ w8 u/ K
QUEUEDATA q;
0 \1 L2 m# X9 Y- H% {4 MDWORD        writetime;& H% l$ {8 {, y3 ~% l

5 o2 k# }1 g5 I. n. FLPSHORT        pSoundBuf = m_SoundBuffer;
: R  m+ _0 \! a, J$ h/ pINT        nCcount = 0;" |9 ]1 F$ z+ V; D  `8 w
8 s5 y# G. B2 z7 L
INT        nFilterType = Config.sound.nFilterType;
' a6 Q% e& @: I% z* K+ u3 H- n  W$ \8 e
        if( !Config.sound.bEnable ) {+ j# Q2 C  r+ b& N9 H
                ::FillMemory( lpBuffer, dwSize, (BYTE)(Config.sound.nRate==8?128:0) );6 u2 }& L  C- v$ ?, l! B& b
                return;
$ X* I; T5 A4 P- ?9 Q8 y1 B        }
( ~; Y, y! Q5 u5 ~1 a! _  @0 }! W- C
        // Volume setup
4 h) E$ {% Z( M& e6 f0 P6 p        //  0:Master- h+ x+ R, E. `1 t  c
        //  1:Rectangle 1
: Y9 r8 {- E0 M2 M" r& G        //  2:Rectangle 2
! N5 C; c- i. |7 J# p- q7 R        //  3:Triangle9 n8 B* H& k' y$ M$ u! @2 W
        //  4:Noise& j8 A- X9 z# u& {
        //  5:DPCM
* ^8 V' T& G3 H7 n        //  6:VRC6
; }9 ]/ H3 ]1 _  A! h5 F7 @# U        //  7:VRC7- w) b# V% S0 U! r6 F
        //  8:FDS
+ v0 e3 h8 [7 ~' I& ^/ _        //  9:MMC5. b$ f7 R2 O% Y& }$ w
        // 10:N106
7 R; r/ b6 b2 r3 u% C        // 11:FME7; @6 p6 i$ Z% ^# V3 W
        INT        vol[24];
, o: h. Q5 L+ U. N; K: [( ?6 o- n        BOOL*        bMute = m_bMute;
8 P1 X/ a: q. t7 p2 ~' F        SHORT*        nVolume = Config.sound.nVolume;
' T* J6 s3 S, W3 \9 X
" ]$ u& A$ r! [+ F4 Z        INT        nMasterVolume = bMute[0]?nVolume[0]:0;5 |! [: c: i% M7 Y5 _3 V) g
" h  b+ Y$ c- H1 C
        // Internal
) M2 ?% ^/ e0 ~' M        vol[ 0] = bMute[1]?(RECTANGLE_VOL*nVolume[1]*nMasterVolume)/(100*100):0;$ W- ^, C" V4 G9 `  |% X1 D( z
        vol[ 1] = bMute[2]?(RECTANGLE_VOL*nVolume[2]*nMasterVolume)/(100*100):0;
0 V6 |% e. P  N; ?        vol[ 2] = bMute[3]?(TRIANGLE_VOL *nVolume[3]*nMasterVolume)/(100*100):0;
- y0 [8 f% v: @        vol[ 3] = bMute[4]?(NOISE_VOL    *nVolume[4]*nMasterVolume)/(100*100):0;
# h" Z& L7 D$ v" Y! P        vol[ 4] = bMute[5]?(DPCM_VOL     *nVolume[5]*nMasterVolume)/(100*100):0;
0 B7 y* e& h+ h" z) `+ F& ~* j  J# s0 N: u
        // VRC6
  b; {$ z4 w8 F! M9 ?        vol[ 5] = bMute[6]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;. `; ~8 ^6 _  H2 z3 |
        vol[ 6] = bMute[7]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
: ]8 m# C* E7 v- v        vol[ 7] = bMute[8]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
& g5 }  W/ H- x) l; f1 a5 X8 ^1 E( {% O) Z
        // VRC7
- c. @0 R) t6 o  {4 R, O6 H$ k, ~# H        vol[ 8] = bMute[6]?(VRC7_VOL*nVolume[7]*nMasterVolume)/(100*100):0;' G- K. J) }$ R" o0 ~2 I

. b* T  z6 i, S: |+ F6 D% S" ]3 P        // FDS
1 W# S5 g8 K2 E+ a# j' x  k1 `        vol[ 9] = bMute[6]?(FDS_VOL*nVolume[8]*nMasterVolume)/(100*100):0;9 }, e" H8 ?! ^  j* Q- n
- O* a1 h+ s, i" W" Z$ y
        // MMC53 C1 d  A% X# c/ Y" P/ d
        vol[10] = bMute[6]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;5 C- C. n! {# R+ a5 f$ Q
        vol[11] = bMute[7]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;, e& K7 S! B8 l6 D& Z: `2 X
        vol[12] = bMute[8]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
8 K$ {$ z; h1 q  f0 s4 S) N. P3 X# c/ ^6 g
        // N106$ y3 T2 t9 Q4 g& W0 V! E1 A
        vol[13] = bMute[ 6]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
; H! T2 ?( f! x! P- E( b6 `        vol[14] = bMute[ 7]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
' G# n: f+ j7 h+ b! f  ^        vol[15] = bMute[ 8]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;9 t  y( I. V) }, f* O
        vol[16] = bMute[ 9]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
; _) d9 t' W. q# e8 }+ T/ i% _        vol[17] = bMute[10]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;: e( X) p0 M, W( \
        vol[18] = bMute[11]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
% }1 ^% @$ g! O, b" u$ G6 E        vol[19] = bMute[12]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;$ Y5 ~' P' n) b* M  D, d
        vol[20] = bMute[13]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;/ y8 L" M8 L5 Z2 v& m
( d: v' M9 E/ o, F+ y3 C- _
        // FME7
# U. ~% d2 @2 i/ S' g        vol[21] = bMute[6]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;/ D: `2 L  T8 _0 _- m
        vol[22] = bMute[7]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;( G& P9 x$ O$ g
        vol[23] = bMute[8]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;( H/ b# M2 s- [- h& b0 d

4 T0 \9 A* @) _0 m5 t# c7 J//        double        cycle_rate = ((double)FRAME_CYCLES*60.0/12.0)/(double)Config.sound.nRate;
+ M) i5 s- f8 d6 ?" X' c        double        cycle_rate = ((double)nes->nescfg->FrameCycles*60.0/12.0)/(double)Config.sound.nRate;1 e9 l; A) Y) C; ~8 l! F
  ?8 V6 a& g1 f0 S% m# k
        // CPU僒僀僋儖悢偑儖乕僾偟偰偟傑偭偨帪偺懳嶔張棟; B1 D4 O% v5 |" o; x& [
        if( elapsed_time > nes->cpu->GetTotalCycles() ) {& B: A% I* l6 `- K9 q# B0 s
                QueueFlush();
1 l; Z7 k( X( K0 Z$ Q* U  S        }
& G* X+ J" w0 i# J' `3 P8 B6 B( @8 z. K) \
        while( dwLength-- ) {
  h2 B8 N  E% y$ R& r  k                writetime = (DWORD)elapsed_time;5 y9 M% y( R9 k

5 L5 a8 \6 [' N, I. o$ r0 {                while( GetQueue( writetime, q ) ) {
7 {! h2 b$ }# p  V# o                        WriteProcess( q.addr, q.data );
) _6 D  T+ C6 ^$ P. ~& v- N3 v                }5 B1 t& \, B$ X* i" S

% w5 W) f1 J3 k' S$ M                while( GetExQueue( writetime, q ) ) {
* P- W8 |0 D5 j$ A3 d$ n( }                        WriteExProcess( q.addr, q.data );
9 f1 g* p7 C! c7 b2 q" t% A& {& T                }
2 X2 G9 {$ |- X  S8 S+ N" r$ v. Q6 ?) T9 V
                // 0-4:internal 5-7:VRC6 8:VRC7 9:FDS 10-12:MMC5 13-20:N106 21-23:FME75 R& D7 y/ _  v, k6 T% j3 ]% q. d
                output = 0;- e" C. S0 r# m4 g
                output += internal.Process( 0 )*vol[0];' S6 u! p4 B: p: P! g9 q
                output += internal.Process( 1 )*vol[1];- R' n$ R+ Y6 h" }
                output += internal.Process( 2 )*vol[2];
, ~! G  Q9 |5 K1 W/ M                output += internal.Process( 3 )*vol[3];6 r+ S* o) ~; w
                output += internal.Process( 4 )*vol[4];: k  t& c9 g) D8 F
  T. M" p3 }3 z) R: F9 M
                if( exsound_select & 0x01 ) {
; c6 x" J: A# ?3 Q# c                        output += vrc6.Process( 0 )*vol[5];1 H% u( l8 `# g) Z
                        output += vrc6.Process( 1 )*vol[6];/ f7 X  V( w& m% H
                        output += vrc6.Process( 2 )*vol[7];7 J* I7 l5 s9 A
                }
2 T) K% ]$ A# t                if( exsound_select & 0x02 ) {7 k/ h! b5 D) U4 w, a
                        output += vrc7.Process( 0 )*vol[8];4 X6 C7 {( ]+ a% _/ b
                }
; @/ `. ~9 C: G6 L/ {  u, e                if( exsound_select & 0x04 ) {* `3 m3 q4 r& C3 j# y: E
                        output += fds.Process( 0 )*vol[9];3 d( R/ \( A/ B- W" L
                }0 e: n2 ]; I( a" m
                if( exsound_select & 0x08 ) {
( W! h/ q' M: ]+ k4 j3 L9 h$ c$ _/ [                        output += mmc5.Process( 0 )*vol[10];
6 z* _( |3 |) i( r' N+ \" e( l                        output += mmc5.Process( 1 )*vol[11];
6 [4 R" A$ f! N$ e8 O                        output += mmc5.Process( 2 )*vol[12];% L8 e  ]  }2 P# h
                }
( b$ V2 g2 ^( V1 M: U$ |                if( exsound_select & 0x10 ) {) ?) M. p$ q7 ^. X8 B
                        output += n106.Process( 0 )*vol[13];
0 Z6 Y' U* I% u! [( ^8 i                        output += n106.Process( 1 )*vol[14];/ F5 t# r# ~( f- e# V% g9 h
                        output += n106.Process( 2 )*vol[15];- C( }8 O: r6 |! ^" M% W4 O' r2 k* u
                        output += n106.Process( 3 )*vol[16];" _/ A. b/ G: o! y; e; N
                        output += n106.Process( 4 )*vol[17];
# c" {- N1 s5 i% s+ H                        output += n106.Process( 5 )*vol[18];$ F# z- ?/ a" Y( R- W6 f: u, s
                        output += n106.Process( 6 )*vol[19];  o4 A( u+ r' y  V: S0 N/ C) m
                        output += n106.Process( 7 )*vol[20];# w- p1 K1 {: K0 `  {# w
                }
" w3 e2 e4 h3 h. g, n$ h' [9 Y                if( exsound_select & 0x20 ) {. v$ S1 Q8 ]& y1 E  z2 a0 Y  Z# r/ ~
                        fme7.Process( 3 );        // Envelope & Noise
* b9 Q& N0 ?& N8 \$ i" a                        output += fme7.Process( 0 )*vol[21];* W$ o$ u/ d4 h" I. r: i* x
                        output += fme7.Process( 1 )*vol[22];
* T# Z  ?" P, e* |$ j" F2 D% n2 k                        output += fme7.Process( 2 )*vol[23];& v& l4 @) k6 f" k; ?! w! V1 k
                }& k8 ?1 ]! ^$ V1 I8 i

3 `; k# Y: T9 W2 S$ d% G                output >>= 8;1 e* m8 _- Z1 z  p1 ~& {

# m! I: N* U9 J, Y                if( nFilterType == 1 ) {
, e5 Y' h4 V  m% Q2 E/ T                        //儘乕僷僗僼傿儖僞乕TYPE 1(Simple); n: |6 G% B, ?' Q* A
                        output = (lowpass_filter[0]+output)/2;
* a# v. o$ Y( R; T/ ^                        lowpass_filter[0] = output;
! k: }& u( e0 N0 x+ Y: k                } else if( nFilterType == 2 ) {
# r5 F1 k( `$ {                        //儘乕僷僗僼傿儖僞乕TYPE 2(Weighted type 1), s$ @1 T3 K( d
                        output = (lowpass_filter[1]+lowpass_filter[0]+output)/3;/ p. k! Y" B+ T8 h
                        lowpass_filter[1] = lowpass_filter[0];
0 O4 J' R6 _" `/ T( L7 o: L                        lowpass_filter[0] = output;
1 v1 h5 B( X4 g* N; k                } else if( nFilterType == 3 ) {
: Q+ p# o0 R7 m% s7 G, a                        //儘乕僷僗僼傿儖僞乕TYPE 3(Weighted type 2)0 v, \6 c. z& c9 \. E, O, ?+ C
                        output = (lowpass_filter[2]+lowpass_filter[1]+lowpass_filter[0]+output)/4;" k& P. E' u( ]) }( {7 q7 o, I. Y% m
                        lowpass_filter[2] = lowpass_filter[1];, R! l8 S( z/ I1 R
                        lowpass_filter[1] = lowpass_filter[0];
3 m& G2 J+ p$ ?% s                        lowpass_filter[0] = output;
# z  M2 k3 M* j  Z8 i% B& M                } else if( nFilterType == 4 ) {
- b# \. S; o+ S7 \( D: d. N                        //儘乕僷僗僼傿儖僞乕TYPE 4(Weighted type 3)  a. {% z0 l( ^' {( M2 w
                        output = (lowpass_filter[1]+lowpass_filter[0]*2+output)/4;% o6 v8 H* C& K
                        lowpass_filter[1] = lowpass_filter[0];8 H9 R& b% |" Q  W/ L0 ?
                        lowpass_filter[0] = output;, `: z) i' w# X6 o1 W, h
                }
7 g& X* e6 K5 B, X, J) \" i8 m) N( C8 X$ Q, u  @. u) O  E1 U
#if        0: [( s7 M. H+ L
                // DC惉暘偺僇僢僩
7 y  Q& J1 f1 C7 U  v* a7 `                {
" c8 f8 w& W* K1 l4 e$ B% P5 v                static double ave = 0.0, max=0.0, min=0.0;9 ]2 _$ U. Y. N% H* U- d) w
                double delta;3 l: J/ g1 s7 w* n. r0 c
                delta = (max-min)/32768.0;( i( |/ E% Z8 t& [
                max -= delta;
3 {2 N+ e0 t0 j) V* q                min += delta;7 O# |7 x- W  T& c) W* x
                if( output > max ) max = output;
: H( E( ]! m2 J                if( output < min ) min = output;) j- H; J* N6 ]7 x8 t" X
                ave -= ave/1024.0;; g7 d; F$ T% N) F" ~
                ave += (max+min)/2048.0;
) I6 ^2 ?: ~' `                output -= (INT)ave;% O* q3 [% t" E/ \- |, k) u4 N0 v
                }1 Q' ]$ O" y8 O0 h, _
#endif2 m; P& d7 N# C6 f0 T$ O' T
#if        15 k# N: z9 p! j1 D0 {
                // DC惉暘偺僇僢僩(HPF TEST)6 f, S. g( |6 H% h0 p
                {3 @% _# B' U. }* z) T
//                static        double        cutoff = (2.0*3.141592653579*40.0/44100.0);8 B8 F7 t$ k+ K  B2 D
                static        double        cutofftemp = (2.0*3.141592653579*40.0);
7 V+ J, k3 d& G# O/ c8 J) r                double        cutoff = cutofftemp/(double)Config.sound.nRate;
5 T+ _3 e4 C8 x" o5 M                static        double        tmp = 0.0;+ Y5 ?1 b0 l9 y8 G
                double        in, out;
9 q* P5 c7 Q) V
+ c/ r8 L) T3 t7 A, J) H                in = (double)output;  W& E1 I. j3 q, `, Z
                out = (in - tmp);
& t5 a3 S; Q, n5 h7 E7 ?                tmp = tmp + cutoff * out;
; k) C# {# O6 b/ A( o' j) |+ q, g8 y# [4 I, k. V0 {' C  q; B8 O
                output = (INT)out;- b  f' t; Q/ q# N
                }
3 I2 T. W+ |. J0 F! ~, \; \#endif' h) K& G: ~4 o: Q
#if        0
4 I( \" w8 E9 D5 @2 n9 [& F                // 僗僷僀僋僲僀僘偺彍嫀(AGC TEST)( x9 ?0 f7 w" y. s
                {. s- r. r1 ^+ q4 I. d/ G
                INT        diff = abs(output-last_data);
3 \' F% |4 Q3 o7 ]                if( diff > 0x4000 ) {1 J8 p, v9 X% D
                        output /= 4;
' W( }4 ]7 n3 ^% ]; B" A3 a0 Y                } else
, d. o. H: R! r. U                if( diff > 0x3000 ) {
" H$ n3 f- ^8 i4 h                        output /= 3;, T6 }" N/ U# z  t' y- K
                } else
2 d4 e/ s+ \: a) ]                if( diff > 0x2000 ) {' e- Q9 O" Q% `3 E
                        output /= 2;* o. _0 O- C0 B0 k3 ~
                }
" x4 Z5 {. M. y6 L                last_data = output;
, h* d% o( T* Q$ }1 f: L- w                }' d6 t+ H4 J3 @/ R' a0 Z
#endif
: n6 W9 P/ A$ v( `+ G  l. K                // Limit
3 O1 Z' \0 I$ E. Z                if( output > 0x7FFF ) {8 s/ N  w/ E) K# D7 c
                        output = 0x7FFF;8 v& B, c) ]- K
                } else if( output < -0x8000 ) {3 W/ O* B# U& N- ~0 E" n  @
                        output = -0x8000;4 M6 {/ X! ~; _8 O0 l
                }
9 b5 F" W9 K" K' h' ]7 l: [' o2 Q" D6 O& ^2 I$ }) m
                if( nBits != 8 ) {
  _! x0 R. R# B- r                        *(SHORT*)lpBuffer = (SHORT)output;
7 o9 X) i/ w0 }3 [                        lpBuffer += sizeof(SHORT);
: m8 X5 [. U) n# W# v2 }/ c                } else {
' J. U' |- P8 C$ c! q2 q                        *lpBuffer++ = (output>>8)^0x80;. ^2 H  O* t+ \2 }
                }2 c: b1 ]! A0 W8 B8 c. n5 Q

; M9 p/ ]8 f7 P' r: o" \                if( nCcount < 0x0100 )4 \2 @! R" N" z$ C5 Z
                        pSoundBuf[nCcount++] = (SHORT)output;
# D/ j" b8 |; h  I4 C. w  p
! b# }/ z$ X; y; M; G/ v/ r//                elapsedtime += cycle_rate;
4 E. g) R8 }+ b/ {                elapsed_time += cycle_rate;$ Z- U* E6 q9 S6 b
        }+ s0 h; D$ I! ~: o6 _' Y  w0 x  n

# \" o- t; u' i) a( V#if        18 a; \% U0 C7 m+ [0 _3 q
        if( elapsed_time > ((nes->nescfg->FrameCycles/24)+nes->cpu->GetTotalCycles()) ) {4 i5 G: Q6 @1 J) }0 ]. L- C4 k
                elapsed_time = nes->cpu->GetTotalCycles();
# Y3 g3 j5 b' N  f        }5 C0 o5 b2 J: p3 d# n' |: U2 e
        if( (elapsed_time+(nes->nescfg->FrameCycles/6)) < nes->cpu->GetTotalCycles() ) {8 y$ l$ t7 i2 D
                elapsed_time = nes->cpu->GetTotalCycles();3 G8 Y* h/ T- t1 \3 A
        }! W3 I+ s6 u, K# X( ^
#else9 t, t+ D$ T6 W
        elapsed_time = nes->cpu->GetTotalCycles();
  V) @7 \& z8 e4 x#endif: a0 A- E/ s1 i- Z0 b7 U) @
}
3 M8 u+ H$ h! N, ]* a4 j/ M- D3 A8 X$ F
// 僠儍儞僱儖偺廃攇悢庢摼僒僽儖乕僠儞(NSF梡)
9 \6 F; h( P/ D5 d4 ^; aINT        APU::GetChannelFrequency( INT no )$ j3 e$ M" e8 h# J- {' ^7 ?% n
{$ @5 m6 z* d3 t* e+ U3 U0 u- |, ~
        if( !m_bMute[0] )4 G  _: W2 F8 x7 k  k! g
                return        0;
1 U- ~6 ?9 |& f& z/ {. @+ ?
. ~5 I, ~7 O) R1 Q7 T' \9 x  v        // Internal
: D- @% S3 q& ^8 B! J        if( no < 5 ) {, i& Q0 G" A# m& c( ^$ ^  H
                return        m_bMute[no+1]?internal.GetFreq( no ):0;1 }8 q& g+ }7 b( {
        }
: F2 |% a4 e) K) x8 R8 Y& [: c$ f        // VRC6; Q. z# G4 q: X& g
        if( (exsound_select & 0x01) && no >= 0x0100 && no < 0x0103 ) {* G: C7 _* c0 m, L* N. b( S
                return        m_bMute[6+(no&0x03)]?vrc6.GetFreq( no & 0x03 ):0;
& T- s4 H& d6 _' r2 S        }
, q' S8 n( P3 M! H7 h        // FDS
9 B8 A1 ?, p5 r        if( (exsound_select & 0x04) && no == 0x300 ) {8 w. W" ?% ]8 U! I9 _; P5 f+ f
                return        m_bMute[6]?fds.GetFreq( 0 ):0;
/ H3 a# ?3 `6 Y3 _+ w# h        }
9 l5 ~& Y+ \: v  P1 ~, t% z6 e# X        // MMC5" `1 s* C+ _- t0 ^' U3 B1 t
        if( (exsound_select & 0x08) && no >= 0x0400 && no < 0x0402 ) {
* M- G+ i. a# R# |8 F1 Y                return        m_bMute[6+(no&0x03)]?mmc5.GetFreq( no & 0x03 ):0;
) T  H# _1 \' _8 b5 P( d; y# L        }
  N) J! x* M8 L. Y* m        // N106
! W+ R& b& T8 Q" R# h; p" C        if( (exsound_select & 0x10) && no >= 0x0500 && no < 0x0508 ) {4 e# o+ M# [3 V  V1 S
                return        m_bMute[6+(no&0x07)]?n106.GetFreq( no & 0x07 ):0;( X+ i5 V1 y% n1 g  i; k- A1 u
        }8 y; v; z! L1 F5 N) U; j+ {
        // FME7
6 l! K: r) ^: g! V        if( (exsound_select & 0x20) && no >= 0x0600 && no < 0x0603 ) {( v6 C  U3 k4 f5 S' I
                return        m_bMute[6+(no&0x03)]?fme7.GetFreq( no & 0x03 ):0;  |  x) p' H  s$ s/ w
        }' j/ g+ Q( b/ L. C$ g
        // VRC7+ [; I& m; _: X% J2 L' f) p* d' E
        if( (exsound_select & 0x02) && no >= 0x0700 && no < 0x0709 ) {) j! a/ I6 h: Y1 R1 x/ J1 p9 x0 E
                return        m_bMute[6]?vrc7.GetFreq(no&0x0F):0;3 w0 D. E" i! P( V5 I
        }. \& b+ o, N/ R- s9 u3 }8 O
        return        0;3 x( I1 C' a' r4 V
}
% o" H; q" r" n
5 i8 N) x  G9 o2 p4 T) h* f1 u) @// State Save/Load
- S1 q5 u# K& A9 k( l* A! h, A6 G! t: Cvoid        APU::SaveState( LPBYTE p )
6 d" [% C- G1 H& X) D- Y{
* p  U; K2 v# N6 K" E  ~# ~) }#ifdef        _DEBUG: V  D' t6 ^/ s; l. J; L$ F& ^* J
LPBYTE        pold = p;( H: H1 W9 ~) R& ]( A
#endif4 _' L! s. T) G) q4 X3 Y
0 G& z; w- ?& h: `+ R
        // 帪娫幉傪摨婜偝偣傞堊Flush偡傞1 K" ?" ^# S' B
        QueueFlush();! r( f" b' r! `1 t2 a/ B* x- B
3 R* y  W4 i: |
        internal.SaveState( p );6 p/ L9 T% x5 N0 ^
        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding  R- h& l0 k' i1 t3 Q) c, Q+ j
: k7 F& g/ a8 H1 y# ^* ^
        // VRC6/ j+ p( o* \6 n; P
        if( exsound_select & 0x01 ) {
# A* c6 y$ o+ T$ U0 Y                vrc6.SaveState( p );
3 L3 j7 Z) t& Q6 U! K. E                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding
0 R7 j" w3 O: S4 i        }( ~# r, E+ ~3 `( u4 |1 P# R( V
        // VRC7 (not support)
. A  r+ j) c! H2 `6 e        if( exsound_select & 0x02 ) {
& g8 p( @# r1 ^% w3 @4 M                vrc7.SaveState( p );
: E5 J( W4 x; R6 y                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding3 f% I0 |& ]' e9 m$ b8 Z0 U: ]
        }0 M& y: M" \, _# s% R: a) L& b( S
        // FDS
- e% Z6 ~( c% ~# I        if( exsound_select & 0x04 ) {; N3 D% h" _+ A  S+ k8 i% e
                fds.SaveState( p );* |1 V) ^4 y0 q
                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding
/ J$ R, F5 |3 [6 u- D        }% T; o9 e, B" L+ J; }
        // MMC5
1 |6 f! b" E0 S$ u/ O. f/ L        if( exsound_select & 0x08 ) {. }# W! `5 K0 N' W  X) R: K
                mmc5.SaveState( p );0 z, ^6 h& p% B* J% O/ m4 Z
                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding/ }0 S. }- i! O0 k$ q
        }
. O" U: K) H9 W, r: d8 k8 ]        // N106
( k0 y, L2 L  W  G1 r0 D& O& N. I5 c3 R        if( exsound_select & 0x10 ) {
$ }- v% ^1 [. B) D- [                n106.SaveState( p );
- f: _$ t8 \9 v7 I2 r% K                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding
' e" O' f- W. d6 s        }1 |, n9 v, c+ t, B0 }9 f+ q
        // FME74 M" l1 g+ I6 ~) U9 T/ }
        if( exsound_select & 0x20 ) {
7 D4 r. N" q. ?) t                fme7.SaveState( p );6 s; ], ]: r8 ^' f1 H
                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding9 H, W" F; y8 r  [
        }
) ^6 P- b+ {7 S& _4 ?
2 }3 X" b8 a) g& b  T9 v#ifdef        _DEBUG
' m2 r8 J7 {( s- jDEBUGOUT( "SAVE APU SIZE:%d\n", p-pold );( o$ t7 w; R6 n) x' H" u- Y: |8 o
#endif
9 x6 G1 x9 \; s! r) N0 U' l$ K}
4 s' D; Q' D7 ?5 f3 b$ Q+ I
1 k/ [" M2 H* s4 l8 v# W6 avoid        APU::LoadState( LPBYTE p )& x+ P6 \1 f  U
{
* L- L" Z7 F& f: c        // 帪娫幉傪摨婜偝偣傞堊偵徚偡& y: B! B6 F% t/ H( K; y' ]
        QueueClear();
  I% Y* N5 D6 q0 c6 U# D+ M. s, r. r( _& }& X( F* g
        internal.LoadState( p );9 K0 d/ E9 ?* Q* o# @9 e- \
        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding" f1 n  S, t0 S* L
# e4 }0 f% H2 C+ v0 Q+ j
        // VRC63 B! s8 z& C1 u; t% u! {
        if( exsound_select & 0x01 ) {* u7 I  L9 n1 e! j" x, [. Z  R3 J, S
                vrc6.LoadState( p );
' _& y( o# l6 h/ }: u                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding
- B* Y8 K1 l( y. q& a1 @! S$ W        }: {# y9 G, F/ u  X
        // VRC7 (not support)
5 v  B7 M& N  l        if( exsound_select & 0x02 ) {) t, w9 ?2 G/ N9 q# }' o
                vrc7.LoadState( p );
& ]. K) S) x1 M- d                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding# [* A- |* p! R; @
        }
5 |4 r$ a$ n9 i1 A: U2 k5 |        // FDS
# I2 P( N  n1 W* _: E        if( exsound_select & 0x04 ) {5 w2 U8 \. K$ a" n6 @
                fds.LoadState( p );& d6 F9 M* [( L! r' U  I, @
                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding
9 B3 y) K( e0 v& x( N) }. S2 f        }& T/ Z  |3 {0 L5 h' P- O/ n
        // MMC5* ?% P# j. g/ Z' l% h" e
        if( exsound_select & 0x08 ) {
( D( @( X' U4 [3 G                mmc5.LoadState( p );/ o4 i6 }7 j( C2 C% a' R
                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding) b7 C+ c5 U; C
        }8 G# n; [3 F) E$ Q9 K( ]7 h
        // N106+ h% ^# O6 X9 Z8 O- }
        if( exsound_select & 0x10 ) {3 h2 F1 @$ {* ^) ^# o
                n106.LoadState( p );, }( E1 Q& n, A7 O+ e: E0 P% W" _* \
                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding
0 N; Y7 Z) r4 ]: q        }7 I/ N# M0 n& u
        // FME79 }9 J7 R1 |9 X! z! @  o- t; O& G0 Q; c
        if( exsound_select & 0x20 ) {8 O+ h4 O3 b0 @4 N) |
                fme7.LoadState( p );; I: M8 P0 M" O# `& ^
                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding. K4 m2 N. t* y
        }* `( d. b6 b5 a) g8 B
}

该用户从未签到

发表于 2009-11-8 17:25:37 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 14:38 发表
: H: [, o4 A% }可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。
' c2 k7 y7 L8 K5 ~0 u. g) M感激不尽~~

) K/ ^/ ~. i3 C9 {0 Z8 x# [4 i恩 我對模擬器不是很有研究,
: w' S3 W$ h- q4 u' T: {1 E雖然要了解源碼內容,可能不是很困難,
4 l" G9 m/ R) p2 B: o不過還是要花時間,個人目前蠻忙碌的。
$ e0 z1 {) ^% H
( I7 P+ f- P! z0 @8 N2 Y8 k1 f給你一個朋友的MSN,你可以跟他討論看看,
/ P9 V1 F/ |! Y: _# ~% |他本身是程式設計師,也對FC模擬器很有興趣。
( r, F! `- |' k1 E2 S% L
6 D( E; z' {2 A3 t- B# r2 kMSN我就PM到你的信箱了。1 N. B# M4 W; Z; ?
2 g8 b; ?# X. Y- r$ \/ G
希望你能有所得。

该用户从未签到

 楼主| 发表于 2009-11-9 13:23:59 | 显示全部楼层
呵…… 谢过团长大人~~

签到天数: 80 天

[LV.6]常住居民II

发表于 2009-11-9 16:02:29 | 显示全部楼层
团长的朋友都是神,那团长就是神的boss。

该用户从未签到

发表于 2009-11-20 13:13:25 | 显示全部楼层
原帖由 独孤残云 于 2009-11-9 13:23 发表 0 F3 P8 f$ c! B  d
呵…… 谢过团长大人~~

% x- _( C1 g! U. L3 D/ X3 D* {3 O& @% F9 Q2 I: F
哈 不客氣,算是順便幫他找個伴,大家可以一起玩。

该用户从未签到

发表于 2009-11-20 13:14:53 | 显示全部楼层
原帖由 李伟 于 2009-11-9 16:02 发表
/ Q+ M* t4 ?0 x8 D. G' y: t) P  X团长的朋友都是神,那团长就是神的boss。
+ l4 W" X* t7 F, H7 n6 G' L2 t
哈 不敢當,我只是個平凡人,( Q6 I' I6 \% B7 H5 G
要吃飯喝水,光吸空氣是不會飽的。。。。 :)

该用户从未签到

发表于 2009-11-20 13:32:35 | 显示全部楼层
FC模拟器的部分有个人可以帮你忙" K- G! ~/ h7 H7 E
ZYH9 |* w' x; z' f8 b) v+ d- y! m
QQ:414734306; p" `" S0 r0 ~3 B/ Z8 ^
Mail:zyh-01@126.com: H6 ^6 E/ {2 d3 D4 M' Z

- f/ d4 M6 j6 q& D他是ZYH Emulator这个模拟器的作者,只是他用的开发平台是VB,不过就6502的实现原理来说是一样的

该用户从未签到

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

该用户从未签到

发表于 2009-11-27 19:09:06 | 显示全部楼层
原帖由 独孤残云 于 2009-11-27 09:48 发表 ' h4 z! v& J0 ?* d, j
再次对团长大人和悠悠哥的无私帮助表示感谢~~
' V; x+ E  m7 J8 H/ k) O7 N* y
不客氣  ^_^
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2026-1-26 13:58 , Processed in 1.102539 second(s), 19 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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