Jump to content

Photo

Francis Ichabod Cranium 8 (was:"Missiles and coloring")


34 replies to this topic

#1 atari2600land OFFLINE  

atari2600land

    Waffles:

  • 10,736 posts
  • Man's best invention. Ever.
  • Location:Salem, Oregon

Posted Wed Feb 15, 2017 3:35 PM

So I was playing around with a game idea involving a multi-colored sprite. And I got to wondering if the multicolored sprite had a missile, what color would it be? Would it be something similar to the "coin" in Mario Bros.? If not, then what else? Could I make the missile of player0 (the multi-colored sprite I have) its own one color? In the Celery game, I'm using missile 1 for the eyes and the incinerator door, that's why I didn't have the question then, since player1 in that case (the incinerator) was one color. But now I would like two multicolored sprites if possible, so if missile0 is the result of what happens in Mario Bros., I guess I could make the firing missile missile1 and have player1 all one color.

mariobros.png

Attached Files


Edited by atari2600land, Sat Feb 25, 2017 2:13 AM.


#2 atari2600land OFFLINE  

atari2600land

    Waffles:

  • Topic Starter
  • 10,736 posts
  • Man's best invention. Ever.
  • Location:Salem, Oregon

Posted Wed Feb 15, 2017 7:14 PM

So anyway, I made a missile1, and I can control its Y starting position, but I can't find any documentation about how to set up a missile's X position. In this example, if you press fire, the missile's y position will be where I want it to be, but its x position will be at the left side of the screen instead of the left side of the player, where I want it to be. Also, I want some way to know once missile1x gets to the right side of the screen then stop moving and disappear.

So, what controls missile1x?

Attached Files



#3 ZackAttack ONLINE  

ZackAttack

    Moonsweeper

  • 485 posts
  • Location:Orlando, FL US

Posted Wed Feb 15, 2017 7:39 PM

Check out RESMP0, RESM0, and HMM0 in the stella programming guide.

 

Essentially you can either position missiles centered on their corresponding player or position them as you would a player by strobing RESM0 and then using HMM0 to fine tune it.

 

Pairing P0&M1 and P1&M0 would work for producing to multicolor sprites as long as you can tolerate them having opposite color schemes. Otherwise you have to update COLUP0 and COLUP1 at just the right time. That means there must be enough horizontal space between sprites and you also have to have some precisely timed code. Best case for pulling this off would be if the sprites were each restricted to the left or right third of the screen.

 

EDIT: Just realized you meant multicolored in the traditional sense where the color is changed each scanline. In that case you can have each player be a multicolor sprite and the missile will just take on whatever color the player is that scanline. In other words the missile will be multicolor as well.


Edited by ZackAttack, Wed Feb 15, 2017 7:42 PM.


#4 atari2600land OFFLINE  

atari2600land

    Waffles:

  • Topic Starter
  • 10,736 posts
  • Man's best invention. Ever.
  • Location:Salem, Oregon

Posted Wed Feb 15, 2017 8:57 PM

Can someone help me set up the missile1x position? I tried for a few hours and I can't do it.


Edited by atari2600land, Wed Feb 15, 2017 9:03 PM.


#5 ZackAttack ONLINE  

ZackAttack

    Moonsweeper

  • 485 posts
  • Location:Orlando, FL US

Posted Thu Feb 16, 2017 6:44 AM

You should look at the Collect blog entry for missiles. The source code is attached at the bottom. In collect.asm there is a subroutine named PosObject, just use that to position your missiles horizontally. Don't forget that this routine only sets the HMxx registers. You still have to strobe HMMOVE and probably want to clear the move registers after you've called PosObject for all the objects you want to position.

;set missile0 x position to 74
lda #74 ; x position
ldx #2  ; missile0
jsr PosObject

;set missile1 x position to 95
lda #95 ; x position
ldx #3  ; missile1
jsr PosObject

;Strobe HMOVE
sta WSYNC
sta HMOVE
;Wait a scanline and strobe HMCLR
;You must not strobe HMCLR until at least 23 cycles after HMOVE or positions will be wrong
sta WSYNC
sta HMCLR


;PosObject routine from collect.asm

;===============================================================================
; PosObject
;----------
; subroutine for setting the X position of any TIA object
; when called, set the following registers:
;   A - holds the X position of the object
;   X - holds which object to position
;       0 = player0
;       1 = player1
;       2 = missile0
;       3 = missile1
;       4 = ball
; the routine will set the coarse X position of the object, as well as the
; fine-tune register that will be used when HMOVE is used.
;
; Note: The X position differs based on the object, for player0 and player1
;       0 is the leftmost pixel while for missile0, missile1 and ball 1 is
;       the leftmost pixel:
;           players     - X range is 0-159
;           missiles    - X range is 1-160
;           ball        - X range is 1-160
; Note: Setting players to double or quad size will affect the position of
;       the players.
;===============================================================================
PosObject:
        sec
        sta WSYNC
DivideLoop
        sbc #15        ; 2  2 - each time thru this loop takes 5 cycles, which is 
        bcs DivideLoop ; 2  4 - the same amount of time it takes to draw 15 pixels
        eor #7         ; 2  6 - The EOR & ASL statements convert the remainder
        asl            ; 2  8 - of position/15 to the value needed to fine tune
        asl            ; 2 10 - the X position
        asl            ; 2 12
        asl            ; 2 14
        sta.wx HMP0,X  ; 5 19 - store fine tuning of X
        sta RESP0,X    ; 4 23 - set coarse X position of object
        rts            ; 6 29


#6 atari2600land OFFLINE  

atari2600land

    Waffles:

  • Topic Starter
  • 10,736 posts
  • Man's best invention. Ever.
  • Location:Salem, Oregon

Posted Thu Feb 16, 2017 12:08 PM

I got the missile to start at the playerx's place, but I can't figure out how to make it stop and disappear once it reaches the right side of the screen. Everything I tried had it keep on going from the left side of the screen and not stop.

Attached Files



#7 ZackAttack ONLINE  

ZackAttack

    Moonsweeper

  • 485 posts
  • Location:Orlando, FL US

Posted Thu Feb 16, 2017 3:42 PM

If you move the missile past the edge of the screen it just wraps around to the other side. You need to keep ENAM1 cleared once it has traveled to the side of the screen.



#8 atari2600land OFFLINE  

atari2600land

    Waffles:

  • Topic Starter
  • 10,736 posts
  • Man's best invention. Ever.
  • Location:Salem, Oregon

Posted Thu Feb 16, 2017 6:47 PM

I did keep ENAM1 cleared but it displayed anyway.



#9 ZackAttack ONLINE  

ZackAttack

    Moonsweeper

  • 485 posts
  • Location:Orlando, FL US

Posted Thu Feb 16, 2017 8:24 PM

Your code says otherwise.

ArenaLoop:                  ; - 11 - time of longest path here
	    cpy FrancisFeet
        bne DontDrawMissile			

		lda #2
		sta ENAM1
		
		lda #4
		sta COLUP1

Only the FrancisFeet variable controls if M1 is enabled. An easy fix would be to have a variable named ShowM1 and set it when you want the missile to change states.

ArenaLoop:                  ; - 11 - time of longest path here
	    cpy FrancisFeet
        bne DontDrawMissile			

		lda ShowM1
		sta ENAM1
		
		lda #4
		sta COLUP1


#10 atari2600land OFFLINE  

atari2600land

    Waffles:

  • Topic Starter
  • 10,736 posts
  • Man's best invention. Ever.
  • Location:Salem, Oregon

Posted Fri Feb 17, 2017 7:38 PM

I didn't post the latest code because it wasn't working.



#11 atari2600land OFFLINE  

atari2600land

    Waffles:

  • Topic Starter
  • 10,736 posts
  • Man's best invention. Ever.
  • Location:Salem, Oregon

Posted Fri Feb 17, 2017 7:51 PM

Here's the code with the change you suggested and it still doesn't work.

 

Attached Files



#12 ZackAttack ONLINE  

ZackAttack

    Moonsweeper

  • 485 posts
  • Location:Orlando, FL US

Posted Sat Feb 18, 2017 1:26 PM

open stella debug (press ~ key)
trapwrite ShowMissile1
resume execution (press ~ key)
never breaks
 
open stella debug (press ~ key)
break GameLoop
resume execution (press ~ key)
breakpoint is hit
step through code reveals that branch is taken at bmi IHateThis, this skips the check for Missile1X as well
 
Solution: Merge MissileFired and ShowMissile1 into a single variable. Treat this as a simple finite state machine (FSM). States are Missile1InFlight $02 amd Missile1ReadyToFire $00.
 
Renaming to Missile1State during the merge has the added benefit that the code will break in every place that the MissileFired and ShowMissile1 are used. So it won't assemble until every relevant spot has been reviewed and updated.
 
Still doesn't work. Stella debug reveals that Missile1X never changes. Add instructions to keep variable in sync with actual missile position.
 
Updated source attached.

Attached Files



#13 atari2600land OFFLINE  

atari2600land

    Waffles:

  • Topic Starter
  • 10,736 posts
  • Man's best invention. Ever.
  • Location:Salem, Oregon

Posted Sat Feb 18, 2017 1:31 PM

Thank you so much for doing this! I had tried various things after I posted the code and still couldn't get it to work. I guess I'm just not a very good programmer.



#14 atari2600land OFFLINE  

atari2600land

    Waffles:

  • Topic Starter
  • 10,736 posts
  • Man's best invention. Ever.
  • Location:Salem, Oregon

Posted Sat Feb 18, 2017 3:34 PM

I think I'll just give up anyway because no matter how hard I try I can't keep the scanline below #263.



#15 Nukey Shay OFFLINE  

Nukey Shay

    Sheik Yerbouti

  • 21,638 posts
  • Location:The land of Gorch

Posted Sun Feb 19, 2017 6:05 AM

Neither could Atari at times. Third parties are all over the place with their counts. Keeping the count stable is the actual goal.

#16 SpiceWare ONLINE  

SpiceWare

    Quadrunner

  • 11,331 posts
  • Medieval Mayhem
  • Location:Planet Houston

Posted Sun Feb 19, 2017 11:15 AM

If you can't keep it below 263 then bump it up to 264 so it won't turn to black & white on PAL TVs.  We used 264 for Stella's Stocking due to supercat's music routine for the menu, it required the scanline count to be divisible by 4.

#17 atari2600land OFFLINE  

atari2600land

    Waffles:

  • Topic Starter
  • 10,736 posts
  • Man's best invention. Ever.
  • Location:Salem, Oregon

Posted Sun Feb 19, 2017 4:20 PM

I finally got the scanline to be a steady 262...but only if the player is on the left side of the screen. If he's on the right, when firing begins it jumps to 263 for two frames and then goes back down, a problem I was having all over the screen until I did something that fixed, but only on the left side. So I restricted his movement to only the left side. And also, when he went up to a certain point, he began to vanish. So another moving restriction was put into place. Why is the overscan number so low? I can't believe it, it wasn't this low for Cellar-y Celery. And yet all I have so far is a guy flying around on the left side of the screen and shooting stuff and it's already below 10. And I also wonder why the pixels that make up Francis jumped up to 2 pixels high instead of the one pixel high that was in the first version. Weird. Both versions are in this zip file I attached so perhaps one can look and see what went weird.

Attached Files



#18 ZackAttack ONLINE  

ZackAttack

    Moonsweeper

  • 485 posts
  • Location:Orlando, FL US

Posted Sun Feb 19, 2017 8:42 PM

The problem is that you've put the missile code in GameLoop which precedes GameLoop1.

GameLoop1:
			jsr VerticalSync
			jsr VerticalBlank
			jsr Kernel
			jsr Overscan1	
			jmp GameLoop
  • Move any code in GameLoop1 to Overscan or VerticalBlank subroutines.
  • Remove GameLoop1 since it should now be equivalent to GameLoop
  • Rename Overscan1 to just Overscan
  • Only ever have a single VSync, VBlank, Kernel, and Overscan routine/label.

This reason this is a problem is because the PositionPlayer subroutine you're using will take 1 or 2 scanlines to execute depending on the position it's setting. Since VerticalBlank and Overscan1 use the timer to determine when the right number of scanlines has passed they are agnostic to that detail. Basically you have 30 scanlines to execute some code in overscan, but it's ok if it takes less.

 

Also a style tip is to keep the subroutines located in your source file according to where they are in the call hierarchy. So the following order would be appropriate:

  • Reset:
  • GameLoop:
  • VerticalSync
  • VerticalBlank
  • Kernel
  • Overscan

Next would be any routines that are called from the routines I've already listed. The idea is that you should be able to open a source file and immediately get a feel for what it's doing at the highest level of abstraction. Then you can drill down further to get more details if desired.

 



#19 atari2600land OFFLINE  

atari2600land

    Waffles:

  • Topic Starter
  • 10,736 posts
  • Man's best invention. Ever.
  • Location:Salem, Oregon

Posted Sun Feb 19, 2017 9:38 PM

I guess I'm too stupid to even do just this. Any attempt to change the code results in it acting even worse than before.



#20 atari2600land OFFLINE  

atari2600land

    Waffles:

  • Topic Starter
  • 10,736 posts
  • Man's best invention. Ever.
  • Location:Salem, Oregon

Posted Sun Feb 19, 2017 9:53 PM

I worked some more and I got the shooting under control anywhere on the screen, but I don't know why the guy starts to vanish when he goes up to a certain point. Also I still don't understand why he's taller.

Attached Files



#21 atari2600land OFFLINE  

atari2600land

    Waffles:

  • Topic Starter
  • 10,736 posts
  • Man's best invention. Ever.
  • Location:Salem, Oregon

Posted Sat Feb 25, 2017 12:46 AM

I worked some more on this and while I was working on it, a mysterious white line began appearing on the side of the screen at the same y position as the enemy (waffle. I've decided that the missile is a pencil and he's trying to shoot waffles.) I've tried a lot of stuff to get rid of the white line but it won't leave. It appears to be part of the playfield. Why is it there, and how can I get rid of it? In the zip file are the bin and asm files.

Attached Thumbnails

  • fice6.png

Attached Files



#22 Nukey Shay OFFLINE  

Nukey Shay

    Sheik Yerbouti

  • 21,638 posts
  • Location:The land of Gorch

Posted Sat Feb 25, 2017 1:17 AM

It's the ball sprite. You are enabling it when drawing the sprite. What for? The lines are indented further, so you must have known why you set it up.

#23 atari2600land OFFLINE  

atari2600land

    Waffles:

  • Topic Starter
  • 10,736 posts
  • Man's best invention. Ever.
  • Location:Salem, Oregon

Posted Sat Feb 25, 2017 1:46 AM

Actually, I don't remember. I guess I was going to attempt to draw the plate using it but then decided to have the plate he's riding on be part of the sprite and never deleted it? Anyway, it's gone now. Thank you!

Attached Files



#24 atari2600land OFFLINE  

atari2600land

    Waffles:

  • Topic Starter
  • 10,736 posts
  • Man's best invention. Ever.
  • Location:Salem, Oregon

Posted Sat Feb 25, 2017 5:56 PM

Got rid of the black space at the bottom.

 

Attached Thumbnails

  • fic8.png


#25 atari2600land OFFLINE  

atari2600land

    Waffles:

  • Topic Starter
  • 10,736 posts
  • Man's best invention. Ever.
  • Location:Salem, Oregon

Posted Sun Feb 26, 2017 5:13 AM

Added some buildings below. It took all night to try to stop the pencil from bending. I eventually found a solution. "Sleep 33" worked for some reason, with no ill effects of the game.

 

Attached Thumbnails

  • fice10a.png

Attached Files






0 user(s) are browsing this forum

0 members, 0 guests, 0 anonymous users