Jump to content

Devin

Members
  • Content Count

    487
  • Joined

  • Last visited

Posts posted by Devin


  1. Which is also breaking the 24-cycle rule. Argh.

     

    Each object has a 4-bit motion-compare value (loaded via HMxx or HMCLR) and a pulser on-off latch (not directly accessible). The system also has a 4-bit motion counter, a "counter force enable" latch, and a "HMOVE triggered" latch. The motion circuitry operates using the TIA's system clock (which I'll qclock) which runs at a rate of one cycle every four pixels (i.e. once every 1.33 CPU cycles, or 57 times per line).

     

    Hitting HMOVE turns on all objects' "move enable" latches, as well as the system's "counter force enable" and "HMOVE triggered" latches. Those latches get turned off as described below.

     

    -1- Every object's "move enable" latch will get cleared any time it matches the system motion counter xor'ed with 8.

     

    -2- The "counter force enable" latch gets cleared after one qclock.

     

    -3- The system motion counter will count once per qclock unless it's at zero and the "counter force enable" latch is not set.

     

    -4- The "HMOVE triggered" latch is continuously cleared during the visible part of the screen. When set, it delays the visible part of the screen by 8 pixels.

     

    -5- Each object will receive a count pulse once per pixel during the visible part of the screen, and will receive one count per qclock when its "move enable" latch is set. Each object will be displayed when its count reaches 160; players and missiles may also be displayed when their counts hit 16, 32, or 64, based on NUSIZx.

     

    If an object's "move enable" latch is set when a new value is written into HMxx, a variety of things can happen based on the values of the system motion counter and the new HMxx. If HMxx is $80, the object will end up receiving 16 motion pulses. If (HMxx xor $80) is greater than the motion counter value, the move will simply use the new value. If (HMxx xor $80) is non-zero but less than the motion counter value, the motion-enable latch will remain set until either another HMOVE is performed or HMxx is written with $80.

     

    Thanks. It might take me a while to digest all of that.

     

    In a nutshell, as long as I do my HMxxx calls after 24 cycles, I should be okay? I'm only updating my graphics registers during horizontal blank (with the exception of HMxxx).


  2. The docs say to set HMxx registers no earlier than 24 cycles after HMOVE:

     

    I think I found the suspect code in the section of the kernal that draws the computer's head. It is under 24 cycles. Would the bug cause all the balls to to stick together on the screen? The ball graphics are aligned relative to each other correctly. Odd. But, that what makes programming the 2600 so fun!

     

    DrawHead
    LDY  ScrnHeadIndex
    
     ;----------
     ;Ball
     ;----------
    LDA  TableHeadBallColor,Y	;Ball color
    STA  Temp2				;BallColor
    
    LDA  TableHeadBallCntrl,Y;mmmmssss   m=move constant, s=size #
    STA  HMBL
    AND  #$0F				;get index into control table
    TAX
    
    LDA  TableBallCntrl,X	;Get CTRLPF and ENABL codes
    STA  Temp3
    
     ;----------
     ;Player 1
     ;----------
    ...

     

    I'll flip the code - do Player 1 first.

     

    I'm aligning the ball using the same subroutine that I am using for the players and missiles. I modified another sub I found on these forums. In the code below, I capitalized the statements where I made changes. I would appreciate if someone far more knowledgeable than I can give it a thumbs-up. The sub is as follows:

     

    PositionSprite
    	sta  HMCLR
    
    PositionSpriteNoClr
    	sec
    	sta	WSYNC	  
    	STA	HMOVE	;+3 --------------------- ADDED BY DEVIN 
    
    PositionSpriteLoop
    	sbc	#15
    	bcs	PositionSpriteLoop;+4/5	7/12.../57
    
    	eor	#7			;+2	  9/14.../59
    	asl
    	asl
    	asl
    	asl					 ;+8	 17/22.../66
    
      ;In the following code, I reversed the HMP0,x and RESP0,x 
      ;commands and added a NOP to align the code to the original 5 cycles.
    	
    	NOP					 ;+2	 19/24.../66 
    	STA	RESP0,X		  ;+4	 23/28/33/38/43/48/53/58/63/68/73
    	STA.wx HMP0,X		;+5
    
    	sta	WSYNC			;+3	  0			  begin line 2
    	sta	HMOVE			;+3
    	rts					 ;+6	  9

     

    It works great, even with the modification (probably poorly done). Here's the code that calls the sub to align the ball. This takes place before the end of VBlank.

     

      ;---------------------------
     ;Align Ball
     ;---------------------------
    InitBall
     ;Contains position of head
    LDA  CompuPosX
    CLC			  
    ADC  #6			  ;Atari's 1 pixel bug
    LDX  #4			  ;4 = ball
    JSR  PositionSprite
    
    LDA  #$00	  ;BLACK BACKGROUND
    STA  COLUBK
      
    STA  HMCLR  ;Important

     

    Which is also breaking the 24-cycle rule. Argh.

     

    Thanks everyone for their help!


  3. Hey Devin,

     

    I had the chance to test on hardware this weekend and, well, you can see there are some bugs that the emulator doesn't show. This is probably due to writing to some of the HMxx registers too early in the scanline, the results of which are one of the few traits of the 2600 that emulators don't replicate. I had to learn this the hard way too.

     

    post-2163-1205764198_thumb.jpg

     

    I've also attached a very short video clip that shows the sprites going berzerk:

    KO_Cruiser_WIP_2008_03_11_001.zip

     

    Thanks Zach. I'm aligning the initial position of the ball during the VBlank period. Does it need to be done during the kernal? I call HMOVE right after the STA WSYNC call.

     

    I'm not sure when in the scanline I am setting the HMBL register. The head and body code set HMBL. The head also sets the size of the ball.


  4. To clarify, the 6502 uses certain bits of the opcode to decide what memory operand (if any) to fetch; the 6502 can make that decision before it has determined what to do with the value it receives. There are some opcodes which will result in a memory fetch being performed, but which will then not actually do anything with the value fetched. These opcodes are collectively referred to as "NOP" even though they do perform an operation (the memory fetch) which in some cases may be meaningful in and of itself.

     

    So, is there any advantage to using

     

    NOP  $FFF8

    rather than

     

    LDA  $1FF8

    other than preserving the value of the accumulator?


  5. The NOP here uses an undocumented addressing mode. If you prefer, you can use CMP or BIT instead, but these will affect the status flags. The bankswitch howto used LDA, but this will also affect the accumulator. The important part is that the bankswitching address is accessed somehow. I prefer the NOP method as this allows the code to continue executing in the new bank as if nothing had happened.

     

    From the DASM manual, the valid syntax is DC[.BWL], where .B is a byte (8-bit), .W is a word (16 bit), and .L is a long (32 bit). If no extension is given then the default is a byte. BYTE, WORD and LONG can also be used.

     

    Chris

     

    The template worked like a charm! I now have 8k of ROM. Now the biggest challenge - what to do with all this space?! :) Thanks again.


  6. Looks great so far. Here is a template for 8K (F8) bankswitching. It assumes that the main code is in bank 2, and bank 1 is called as a subroutine:

     

    Thank you! This looks like an incredibly easy template to use. I have a few quick questions.

     

    • The NOP $FFF9 statement is a tad odd. Is this a valid 6502 command or an assembler hack. I would imagine that a no-op wouldn't have an argument.
    • Does DC.B = .byte and DC.W = .word. I would imagine so, but I'm not 100% sure.

     

    Thanks again for the code and a "thank you" to everyone for their help!


  7. I can't seem to hit him even then. He blocks no matter when I punch.

     

    I've attached a new version where the computer will be delayed 2 seconds after each punch - rather than 1 second as before. You can either block or dodge left or right before you counter-punch. To get more than one hit, step forward after each punch. If you get him on the ropes, you can deliver your deadly combo without advancing.

     

    I'll probably have to do some work in this area to perfect the gameplay.

     

    I also updated the "in range" flags for both the left and right punch - the math was a little off in the last version.

    KO_Cruiser_WIP_2008_03_13.bin


  8. I'd really like to have this on cart too when it's done. Think you'll be able to add a ref? It would be funny if it was Pitfall Harry.

     

    Hee hee. That would actually be funny. I might make a sequel where you can box against Atari classic characters. Pitfall Harry would be the champ!

     

    I definitely want to put this on a cartridge.


  9. Update!

     

    I just finished the first playable WIP version of the game. The game is far from finished, but the basic format and behavior is complete.

     

    The computer character's script is very simple at the moment. He doesn't have any special moves or behavior. For each loop - which contains a bob, flip gloves, etc... there is a 25% chance he will throw a punch. Each punch is extremely slow and is blockable. You can then hit the computer up to 3 times. This number is specified in the script. I can add more - even make it possible to hit the computer when he's just standing there. You can't currently hit the computer until he throws a punch. Otherwise, he will block.

     

    Please note, that I still need to program the following:

    • Knock-down logic. Currently, if your health or the computer's goes to zero - nothing happens. Basically, all the characters are still in God Mode with Unlimited Ammo.
    • Sound. It will be more obvious when the computer blocks a punch with the appropriate sound effect.
    • Round logic. The timer will stop at 3 minutes in the final version. Right now it just keeps going and wraps around. I'm only using one byte for the time. Any guesses when it go to zero again? :)
    • Bank-switching. The final version will definitely require it. I plan to put all the kernal in Bank 1 and game logic in Bank 0. I plan to have 5 or 6 different opponents in the final version.
    • The color of your character will also change when you are in range - and being hit.
    • Your player will have a "my punch was blocked" image.

    post-17256-1205246810_thumb.png

    KO_Cruiser___WIP___2008_03_11.bin


  10. Do you want to try to make posts for the ropes using the playfield?

     

    The computer player's head and torso can cover the ropes - and both use the ball. That would make some pretty funky looking posts! :-D

     

    I'm sure I can playing some timing games, but the code is already pretty tight on available time.


  11. That part's a given. Play a note early or late, and it plays early or late on the audio track (the other voices would all play in correct time regardless). Miss a note and it doesn't play. Move the joystick the wrong way, or when there's no note even close, and a wrong note will play.

     

    But how to come up with joystick movement patterns that make musical sense?

     

    Okay. I understand now.

     

    IMHO, it probably would be easier to create a version of Dance-Dance Revolution rather than Guitar Hero. At least in the case of DDR, the directions on the joystick can be whatever values you want - or even randomly generated.

     

    In the case of DDR, the joystick directions can be linked to animations for some sort of cute cartoon character.


  12. The essential feature of Guitar Hero is that the moves make sense in the context of the rhythm and melody that's being played; it "feels" like you're actually playing the tune. I don't know how well that would work with a joystick.

     

    Further, you should note that graphics could take no more than 30 cycles/scan line if I use the BTP2 or EBTBTP2 driver. That's not a lot, but as Stella's Stocking demonstrates, it's still enough to do some cool things.

     

    Perhaps the arrows could be integrated directly with the music buffer.

     

    When an arrow is reached, the system will no longer advance the to the next note until the correct joystick direction is pressed. This way, the song will rhythmically line up with the joystick input. If the user is slow with an input, the time between notes will be longer.

     

    Just a thought.


  13. You know, along these same lines, I was pondering a DDR for the VCS... :ponder:

     

    Is Paul Slocum still out there???

     

    I've been giving some considerable thought to a DDR-style game using an enhanced version of the BTP2 music driver (used in Stella's Stocking). The biggest issue would be control--I just don't know how much fun the game would be with joystick.

     

    Cosmic Ark uses a very similar interface to what could be use for DDR.

     

    Perhaps you can draw a cartoon character using Player 0 and Player 1 and use the ball to draw left, right arrows - depending on the next move (player 0 and 1 could be up and down).


  14. here's an updated version of the game, I had to remove the reset feature and one row of playfield to make room for the ultimate gameplay element : the enemy now doesn't just grow towards the player, it moves towards the player !

     

     

    AHHHH! GET AWAY FROM ME YOU LITTLE BASTARDS! :)

     

    The aggressive nature of the "Omicrons" does force you to move around the field to survive. Great new version!


  15. Here is a quick update on how the project is progressing. I've attached screenshot from a recent build.

     

    Sorry, I can't attach a binary at the moment. I am currently doing brain-surgery on the application to prepare it for the eventual jump to 8k. The ring was set green for testing, but I am becoming convinced that this might be the final appearance. Let me know what you think.

     

    Cheers.

    post-17256-1204806692_thumb.png


  16. Excellent! The addition of the eggs drastically improved the gameplay - on what is already an excellent game! I wouldn't touch the music or sound effects from this point on. Its just too good in its present form.

     

    Why did you have to remove the highscore? Why not go 4k? This game deserves to be on its own cartridge.


  17. The border is a tad small - and it can be annoying to accidentally bump into it and die. The game is still extremely fun.

     

    Would it be possible to have a wider border - and perhaps one that is not deadly to the touch? Maybe there can be two difficulty levels.


  18. You could also use a table approach:

     

    	LDA  SWCHA
    	
    BIT  JOY_UP
    BEQ  JoystickUp		
    BIT  JOY_DOWN
    BEQ  JoystickDown
    BIT  JOY_LEFT
    BEQ  JoystickLeft		
    BIT  JOY_RIGHT
    BEQ  JoystickRight
    
      ;=== No input
    
    JMP  JoystickEnd
    
    JoystickUp
    ...
    JMP  JoystickEnd
    
    JoystickDown
    ...
    JMP  JoystickEnd
    
    JoystickLeft
    ...
    JMP  JoystickEnd
    
    JoystickRight
    ...
    JMP  JoystickEnd
      
    ;----------------------------------------
    ;Table. Has to be memory for BIT command	
    ;----------------------------------------
    
    JOY_UP	 .byte #%00010000   ;Up bit
    JOY_DOWN   .byte #%00100000   ;Down bit
    JOY_LEFT   .byte #%01000000   ;Left bit
    JOY_RIGHT  .byte #%10000000   ;Right bit
    
    JoystickEnd


  19. About ideas, The missile was used for middle line, ok, can be removed, but kernal had now 4 cicles left...

    I have others ideas, "Super" means new things, for exemple the "Blind Mode"!

    When ball cross the middle, it vanish, and you need figure where the ball is, you can see more or less if take attention in middle line, this is the reason of that bright, what you think? :)

     

    Ah.I got it.

×
×
  • Create New...