It is currently Tue Oct 17, 2017 8:34 pm

All times are UTC - 7 hours





Post new topic Reply to topic  [ 5 posts ] 
Author Message
PostPosted: Sat Nov 22, 2014 12:37 am 
Offline

Joined: Fri Nov 21, 2014 10:48 pm
Posts: 3
I'd like to use FamiTone2 library in my homebrew NES game. I'm using NESASM for making NES.
So I write made music, output data, and wrote the code as the explanation(readme.txt) says.

But the NES I made do not work as I want to do (music is not played).

Although I read FamiTone 2's explanation, and was going to write as explanation says,
I do not think I was able to write approrpiate code.

So I tried to find some solution from demo.asm, but it is wrote for ASM6, so I cannot make sense
how to do from the demo code.

I attach the source code which is without FamiTone2-related code(only BGM, no SE or DPCM data), sprite and BG chr file, pallet data,
and music data (for including).

And if you do not mind, I'd be glad if you rewrite my code to work FamiTracker 2's libraries.
I'd like to just add BGM playing to uploaded game. Please do not change other parts(sprite displaying, sprite movement following to input of pad, etc.).
It is better that BGM starts playing with the game launched.

I'm Jap and noob, so my English and questions are awful, but please forgive.


Thank you.


Attachments:
project.zip [10.9 KiB]
Downloaded 75 times
Top
 Profile  
 
PostPosted: Sat Nov 22, 2014 9:04 am 
Offline
User avatar

Joined: Wed Apr 02, 2008 2:09 pm
Posts: 1019
Welcome, deltnis.

I am reluctant to just upload fixed files. But I will show what to do. You were probably adding the correct code to your program to make a song play. But the only instrument you are using does not have a volume effect attached to it. Famitone seems to play instruments without a volume effect as silent. Here is an image showing how to add this:

Attachment:
add volume effect.gif
add volume effect.gif [ 262.63 KiB | Viewed 1039 times ]

Then export the text, and use text2data.exe as you did before to create a new ShanghaiTea.asm.


After that, add the following code somewhere in bank 0.

Code:
   .include "famitone2.asm"
   .include "ShanghaiTea.asm"


Add these lines before you allow NMIs and enable the display of sprites and the BG.

Code:
   ldx #LOW(ShanghaiTea_music_data)
   ldy #HIGH(ShanghaiTea_music_data)
   lda #$80;This sets Famitone to use NTSC mode.
   jsr FamiToneInit

   lda #0;Play first subsong
   jsr FamiToneMusicPlay

   ;The below lines are already there. Here for context.
   ; Initialize PPU controling register
   lda #%00011110   ; enable the display of sprite and BG
   sta $2001


In your NMI routine (VBlank interrupting handler), add this:

Code:
NOTHINGdown:
   jsr setSprite2
   ;This needs to be run every frame to play the song.
   ;It is best to do it last
   jsr FamiToneUpdate;Other lines here for context

   rti



Now, in famitone2.asm, uncomment these lines at the top:

Code:

FT_BASE_ADR      = $0400   ;page in the RAM used for FT2 variables, should be $xx00

;-------------------------------------
;Note that FT_BASE_ADR has been changed from
;$0300 to $0400. Your sprites use $0300 so you
;must change this to make Famitone use
;different RAM
'----------------------------------
FT_TEMP         = $00   ;3 bytes in zeropage used by the library as a scratchpad

;-----------------------------------------
;FT_TEMP has not been changed, since
;you are not using any zero page ($0000-$00FF) RAM
;in your program. If you were, you would need
;to make sure Famitone did not conflict with it
;by changing FT_TEMP.
;-----------------------------------------

FT_DPCM_OFF      = $c000   ;$c000..$ffc0, 64-byte steps
; FT_SFX_STREAMS   = 4      ;number of sound effects played at once, 1..4

; FT_DPCM_ENABLE         ;undefine to exclude all DMC code
; FT_SFX_ENABLE         ;undefine to exclude all sound effects code
; FT_THREAD            ;undefine if you are calling sound effects from the same thread as the sound update call

; FT_PAL_SUPPORT         ;undefine to exclude PAL support
FT_NTSC_SUPPORT         ;undefine to exclude NTSC support


With those changes your program will play your song in any emulator that ran the program before. The rest of the post recommends things that will make your game run better on real hardware.


Your program does not do much initialization, and may behave strangely on real hardware.

You are already waiting one frame before you start your program. It is good to wait at least two, because the PPU needs to warm up.

Code:
   lda $2002;These makes sure the 7th bit of $2002 is
   ;clear for the loop below

waitVSync:
   lda $2002
   bpl waitVSync  ; wait while 7th bit of $2002 is 1 (VBlank occuring)


waitVSync2:
   lda $2002
   bpl waitVSync2  ; wait once more for safety


I am not sure how familiar you are with the stack (It uses $0100-$01FF going backwards), but setting it up is a good idea. It is actually not required, but it allows you to safely use some of the bottom of the RAM reserved for the stack for your program.

Code:
waitVSync2:
   lda $2002
   bpl waitVSync2  ; wait once more for safety

   ldx #$FF
   txs;Set up stack


NES does not begin with all RAM set to zero like many emulators do. Your sprites are drawn from RAM, so you may have random sprites on screen if you don't initialize it. Adding the code below will avoid that.

Code:
   cpx #32;These lines are already in your program
   bne loadPal;They are here for context

   ldx #$00
clearram:
   ;lda #$00
   ;sta $0000,x
   ;sta $0100,x
   ;sta $0200,x
   

   lda #$FF;#$FF is a Y position below the screen
   ;So writing it to every value in your sprite RAM
   ;at the beginning ensures no sprites you do not
   ;want are on screen.
   sta $0300,x;Store #$FF to sprite page.
   
   ;lda #$00
   ;sta $0400,x
   ;sta $0500,x
   ;sta $0600,x
   ;sta $0700,x
   inx
   bne clearram

In addition, uncommenting the other ldas and stas will set all RAM that is not the sprite RAM to zero. This is not required, as long as you always initialize RAM before you use it. Note that you are not initializing Sprite1_T, Sprite1_S, and Sprite2_T. So after doing the above, you will need to add some code so the sprites you have will display correctly:

Code:
   lda X_Pos_Init
   sta Sprite1_X
   lda Y_Pos_Init
   sta Sprite1_Y
   
   lda #%00000000
   sta Sprite1_S;
   lda #$00
   sta Sprite1_T

   jsr setSprite2

   lda #%01000000
   sta Sprite2_S
   lda #$00
   sta Sprite2_T

As it was, your sprites were unlikely to work on real hardware.

The NES also does not initialize the background before power on, so whatever random things were there before power on will still be there unless you change them. You do not have different background tiles yet, but the below will set all of the background to zero.

Code:
   lda #$00;This line was recommended above
   sta Sprite2_T;Here for context.
   
clearnametables:   
   lda #$20;The first nametable (background) begins at $2000
   sta $2006
   lda #$00
   sta $2006
   
   ldy #$00;This loops through all background data
   ;writing tile zero and palette zero to it
   ldx #$0C
clearnext:
   sta $2007
   iny
   bne clearnext
   dex
   bne clearnext


With all of those changes, your game is also very likely to work on the real console. Good luck! Also, your song is very catchy.

Edit: I totally had to look up the song. A cover of a thing from here. Neat!

_________________
https://kasumi.itch.io/indivisible


Top
 Profile  
 
PostPosted: Sat Nov 22, 2014 12:07 pm 
Offline

Joined: Fri Nov 21, 2014 10:48 pm
Posts: 3
Thank you for your replying !

I didn't know that I had to enable volume effect and gain the volume level.

So I enabled volume effect, but still BGM is not played...
Bankswitching, address pointing, position of FamiTone2-related parts in my code are wrong?

I upload the code and materials. This time, the code includes FamiTone2-related parts.
What parts in my code are wrong?(It is clear that my code is badly awful)

I know my knowledge of NES's structure and others is lacked, and I'm asking dumb questions.
I also know I have to study about them sufficiently at first, but I'm eager to play BGM for the time being.

thank you.


Attachments:
project.zip [92.59 KiB]
Downloaded 58 times
Top
 Profile  
 
PostPosted: Sat Nov 22, 2014 3:40 pm 
Offline
User avatar

Joined: Wed Apr 02, 2008 2:09 pm
Posts: 1019
The only thing in the way of the music is that you have two instances of jsr FamiToneUpdate. You only want one.

Code:
infinityLoop:               ; waiting for VBlank interruption
   ;jsr FamiToneUpdate;You don't want this here.
   jmp infinityLoop

The clear RAM was also added incorrectly. It lacks the ldx #$00, and the lda #$FF and sta $0300,x were moved outside the loop.

The whole clearram should look like this if you uncomment everything:
Code:
   ldx #$00
clearram:
   lda #$00
   sta $0000,x
   sta $0100,x
   sta $0200,x

   lda #$FF
   sta $0300,x
   
   lda #$00
   sta $0400,x
   sta $0500,x
   sta $0600,x
   sta $0700,x
   inx
    bne clearram

That's all. If for some reason it still doesn't work, let me know what emulator you're using. Tested on (oldish versions of) FCEUX, Nestopia, VirtuaNES and Nintendulator and it works as expected with those changes.

_________________
https://kasumi.itch.io/indivisible


Top
 Profile  
 
PostPosted: Sat Nov 22, 2014 10:03 pm 
Offline

Joined: Fri Nov 21, 2014 10:48 pm
Posts: 3
Thanks for your replying again!

I didn't noticed that I updated to many times...
In this time, BGM is played completely correctly.

I'm going to study about NES more from now on.

Thank you a lot!


P.S. I think this song is nice too. So I covered this music, and I'm glad to play this song
on NES :D


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 5 posts ] 

All times are UTC - 7 hours


Who is online

Users browsing this forum: Google Adsense [Bot] and 6 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group