ASM isn't annoying. The only thing that's annoying is debugging and fixing odd problems.
If it's not annoying for other people, there shouldn't be a valid reason why it should be annoying to you.
Really good tutorial, it has covered so many things I've been wondering!
Just one thing, can you cover how to give different behavoir to sprites "depending on their x position"?
Waluigi needs his own game, he doesn't even have character!
...
Currently working on Waluigi's Treasure Hunt.
Hmm, that should be something good to cover in the tutorial.
There are 16 possible sprite (X) positions on one screen. If you want to check what position it is on, $E4,x will hold it's position on screen.
16 positions can be too much though, you can make 8 possible values (0, 1, 2, 3, 4, 5, 6, 7), 4 possible values (0, 1, 2, 3) and 2 possible values (0, 1) by dividing $E4,x and storing it somewhere. You put this code in the INIT routine:
LDA $E4,x
LSR ; position x8
LSR ; position x4
STA $1594,x ; store somewhere
Now $1594,x can either be 0, 1, 2 or 3 based on it's position. Even though there are 16 positions on screen, it will go like this:
0 1 2 3 4 5 6 7 8 9 A B C D E F | 0 1 2 3 4 5 6 7 8 9 A B C D E F
0 1 2 3 0 1 2 3 0 1 2 3 0 1 2 3 | 0 1 2 3 0 1 2 3 0 1 2 3 0 1 2 3
$1594,x (or whatever you stored to) will contain these values, and you can branch to different codes and do different stuff based on what the value in that address is.
Originally posted by The Heavenly Muncher
words
I found some inaccurancies in this.
First, $E4,x is $00-$F0 at the start, so you'd need four more LSRs.
Second, you missed the 0s at the position tables. A screen isn't 15 tiles.
The rest seems correct, though.<blm> zsnes users are the flatearthers of emulation
Just a headsup, you forgot to make a "SlotsFull" label at the "Making A Sprite Spawn A Custom Sprite" lesson.
Speaking of that, it spawn normal sprites, not custom. Coulf you write how to spawn custom sprites to?
Also, your jump rouitine for the boss is broken.
The boss will rise a short distance for one frame and plummet the next.
This works better (I think ^^;):
Code
LDA $1594,x
CMP #$10 ;Number of frames to jump
BEQ TIME_TO_JUMP
BCC TIME_TO_JUMP
BRA SHARED
RESET:
LDA #$80 ;Number of frames until next jump (minus "Number
;of frames to jump).
STA $1594,x
BRA SHARED
TIME_TO_JUMP:
BEQ RESET
LDA #$C0
STA $AA,x
JSL $01802A
LDA #$01
STA $1DFA
SHARED:
DEC $1594,x ;This isn't needed if you use a sprite table that
;decreases itself each frame.
RTS
Waluigi needs his own game, he doesn't even have character!
...
Currently working on Waluigi's Treasure Hunt.
Crap.. bplaced.net is down :/ I might have to move everything somewhere else.
Also, maybe I will add a few more things to the tutorial soon.
Yes!!! I've created a moving coin that is worth 10 coins, thanks to this tutorial!
the genorator file I made (the one that this tutor did) will not even insert in spiret tool. In my sprites.txt I put it as below
00 firebar.cfg
01 crab.cfg
02 egg.cfg
03 beezo_carryable.cfg
d2 10 coins to cape.cfg this is the genorator (I just cald it this)
whene I insert the sprites in sprite tool it seys..... couldent open sprite d2 10 coins to cape.cfg
when I open the cgf file in the cfg editor it seys that its not a supported cfg file.
hI put both the 10 coins to cape.asm and cfg file in the genorators folder. HELP!!!
Don't put a space in the .cfg file. I thought I covered that in the tutorial.
I made the actionless blue mushroom, yet when i play the lvel, the screen just goes black. HELP!
Originally posted by SomeGuy
I made the actionless blue mushroom, yet when i play the lvel, the screen just goes black. HELP!
We are incapable of knowing what the problem is unless you post the code.
ON_SCREEN_X LDA $14E0,x ; \
XBA ; |
LDA $E4,x ; |
REP #$20 ; |
SEC ; |
SBC $1A ; | mark sprite invalid if far enough off screen
CLC ; |
ADC.W #$0040 ; |
CMP.W #$0180 ; |
SEP #$20 ; |
ROL A ; |
AND #$01 ; |
STA $15C4,x ; /
BNE INVALID ;
LDY #$00 ; \ set up loop:
LDA $1662,x ; |
AND #$20 ; | if not smushed (1662 & 0x20), go through loop twice
BEQ ON_SCREEN_LOOP ; | else, go through loop once
INY ; /
ON_SCREEN_LOOP LDA $D8,x ; \
CLC ; | set vertical offscreen if necessary
ADC SPR_T1,y ; |
PHP ; |
CMP $1C ; | (vert screen boundry)
ROL $00 ; |
PLP ; |
LDA $14D4,x ; |
ADC #$00 ; |
LSR $00 ; |
SBC $1D ; |
BEQ ON_SCREEN_Y ; |
LDA $186C,x ; | (vert offscreen)
ORA SPR_T2,y ; |
STA $186C,x ; |
ON_SCREEN_Y DEY ; |
BPL ON_SCREEN_LOOP ; /
LDY $15EA,x ; get offset to sprite OAM
LDA $E4,x ; \
SEC ; |
SBC $1A ; | $00 = sprite x position relative to screen boarder
STA $00 ; /
LDA $D8,x ; \
SEC ; |
SBC $1C ; | $01 = sprite y position relative to screen boarder
STA $01 ; /
RTS ; return
INVALID PLA ; \ return from *main gfx routine* subroutine...
PLA ; | ...(not just this subroutine)
RTS ; /
LDA $00
STA $0300,y
LDA $01
STA $0301,y
LDA #$24
STA $0302,y
LDA #%00000110
ORA $64
STA $0303,y
INY
INY
INY
INY
LDY #$02 ; This means the tile drawn is 16x16.
LDA #$00 ; The number of tiles I wrote - 1.
JSL $01B7B3
RTS
There is the code
First of all, the code looks kind of scrambled.
When using codes that never, ever has to to changed, you JSR to them.
When you build your code, JSR from the main routine to the sprite code.
Then, at the very begginning of your sprite code, write: "JSR GET_DRAW_INFO", then put that routine last.
It's important that you JSR and not branch in the beginning, otherwhise the code have to end with an RTL, and every return in the graphics routine ends with RTS.
This caused the crash.
I think that this should work:
Code
dcb "INIT"
RTL
dcb "MAIN"
JSR Routine
RTL
;===================================
; GRAPHICS ROUTINE HERE
;===================================
Routine:
JSR GET_DRAW_INFO
LDA $00
STA $0300,y
LDA $01
STA $0301,y
LDA #$24
STA $0302,y
LDA #%00000110
ORA $64
STA $0303,y
INY
INY
INY
INY
LDY #$02 ; This means the tile drawn is 16x16.
LDA #$00 ; The number of tiles I wrote - 1.
JSL $01B7B3
RTS
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; $B760 - graphics routine helper - shared
; sets off screen flags and sets index to OAM
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
SPR_T1 dcb $0C,$1C
SPR_T2 dcb $01,$02
GET_DRAW_INFO:
STZ $186C,x ; reset sprite offscreen flag, vertical
STZ $15A0,x ; reset sprite offscreen flag, horizontal
LDA $E4,x ; \
CMP $1A ; | set horizontal offscreen if necessary
LDA $14E0,x ; |
SBC $1B ; |
BEQ ON_SCREEN_X ; |
INC $15A0,x ; /
ON_SCREEN_X:
LDA $14E0,x ; \
XBA ; |
LDA $E4,x ; |
REP #$20 ; |
SEC ; |
SBC $1A ; | mark sprite invalid if far enough off screen
CLC ; |
ADC.W #$0040 ; |
CMP.W #$0180 ; |
SEP #$20 ; |
ROL A ; |
AND #$01 ; |
STA $15C4,x ; /
BNE INVALID ;
LDY #$00 ; \ set up loop:
LDA $1662,x ; |
AND #$20 ; | if not smushed (1662 & 0x20), go through loop twice
BEQ ON_SCREEN_LOOP ; | else, go through loop once
INY ; /
ON_SCREEN_LOOP:
LDA $D8,x ; \
CLC ; | set vertical offscreen if necessary
ADC SPR_T1,y ; |
PHP ; |
CMP $1C ; | (vert screen boundry)
ROL $00 ; |
PLP ; |
LDA $14D4,x ; |
ADC #$00 ; |
LSR $00 ; |
SBC $1D ; |
BEQ ON_SCREEN_Y ; |
LDA $186C,x ; | (vert offscreen)
ORA SPR_T2,y ; |
STA $186C,x ; |
ON_SCREEN_Y:
DEY ; |
BPL ON_SCREEN_LOOP ; /
LDY $15EA,x ; get offset to sprite OAM
LDA $E4,x ; \
SEC ; |
SBC $1A ; | $00 = sprite x position relative to screen boarder
STA $00 ; /
LDA $D8,x ; \
SEC ; |
SBC $1C ; | $01 = sprite y position relative to screen boarder
STA $01 ; /
RTS ; return
INVALID:
PLA ; \ return from *main gfx routine* subroutine...
PLA ; | ...(not just this subroutine)
RTS ; /
Waluigi needs his own game, he doesn't even have character!
...
Currently working on Waluigi's Treasure Hunt.
Originally posted by deffon1993
dcb "MAIN"
JSR Routine
RTL
Wrong. Change this to this or the tables will break:
Originally posted by deffon1993
dcb "MAIN"
PHB
PHK
PLB
JSR Routine
PLB
RTL
<blm> zsnes users are the flatearthers of emulation
May I ask what use is the ORA $64 in setting YXPPCCCT? Noobish tells me it's simply to set the PP, which can obviously just be done yourself. What use is it? Why? He says it's fine to not use it, so what makes this "easier"?
My blue hushroom asm file will not work. when I insert it with sprite tool it seys that it can not open the asm file. Here is the code.
--------------------------
blue mushroom
--------------------------
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; main sprite JSL
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
dcb "MAIN"
RTL
JSR GRAPHICS ROUTINE HERE
JSR GET_DRAW_INFO
;===================================
; GRAPHICS ROUTINE HERE
;===================================
LDA $00
STA $0300,y
LDA $01
STA $0301,y
LDA #$24
STA $0302,y
LDA #%00000110
ORA $64
STA $0303,y
PHX ;
LDX $15E9
LDA $15F6,x
PLX ;
ORA $64
STA $0303,y
INY
INY
INY
INY
LDY #$02 ;
LDA #$00 ;
JSL $01B7B3
RTS
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; GET_DRAW_INFO
; This is a helper for the graphics routine. It sets off screen flags, and sets up
; variables. It will return with the following:
;
; Y = index to sprite OAM ($300)
; $00 = sprite x position relative to screen boarder
; $01 = sprite y position relative to screen boarder
;
; It is adapted from the subroutine at $03B760
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
ON_SCREEN_X LDA $14E0,x ; \
XBA ; |
LDA $E4,x ; |
REP #$20 ; |
SEC ; |
SBC $1A ; | mark sprite invalid if far enough off screen
CLC ; |
ADC.W #$0040 ; |
CMP.W #$0180 ; |
SEP #$20 ; |
ROL A ; |
AND #$01 ; |
STA $15C4,x ; /
BNE INVALID ;
LDY #$00 ; \ set up loop:
LDA $1662,x ; |
AND #$20 ; | if not smushed (1662 & 0x20), go through loop twice
BEQ ON_SCREEN_LOOP ; | else, go through loop once
INY ; /
ON_SCREEN_LOOP LDA $D8,x ; \
CLC ; | set vertical offscreen if necessary
ADC SPR_T1,y ; |
PHP ; |
CMP $1C ; | (vert screen boundry)
ROL $00 ; |
PLP ; |
LDA $14D4,x ; |
ADC #$00 ; |
LSR $00 ; |
SBC $1D ; |
BEQ ON_SCREEN_Y ; |
LDA $186C,x ; | (vert offscreen)
ORA SPR_T2,y ; |
STA $186C,x ; |
ON_SCREEN_Y DEY ; |
BPL ON_SCREEN_LOOP ; /
LDY $15EA,x ; get offset to sprite OAM
LDA $E4,x ; \
SEC ; |
SBC $1A ; | $00 = sprite x position relative to screen boarder
STA $00 ; /
LDA $D8,x ; \
SEC ; |
SBC $1C ; | $01 = sprite y position relative to screen boarder
STA $01 ; /
RTS ; return
INVALID PLA ; \ return from *main gfx routine* subroutine...
PLA ; | ...(not just this subroutine)
RTS ; /
----------------------------------------------------------------------
Can some one cheack over this code because I have no clue what whent wrong.
side note. ice guy the links you posted with your totorial are broken (the site seys that the pages are not avalable) (sigh) please make shure that your links work so i can see what you have done!!!!!
(WYEdit: Got rid of the unnecessary line breaks at the end.)