+Andrew Davie Posted September 8, 2008 Share Posted September 8, 2008 Two players should be possible. I'll take just small steps for now I'm now doubling the vertical resolution, the tiles at the sides will benefit from this, well... it makes everything look better. I also want to make a finer grained control of the movement to get that 'techy'-look. The horizontal movement is now 20 pixels, I precalculated a vector that turns 45 degrees in 20 steps and used that to control the movement of the grid. I like to calculate 256 pixels heigh vector and use only the upper 20 pixels of it so the horizontal movement has 256 possible positions. Anyone know how to calculate vectors? For vertical tiles I have to make a sort of sinus-table to make the tiles smaller in the distance. Any ideas on this are also welcome. The brown border of the checkerboard needs als to be done. I'll get to this when I've the checkerboard the way I want. Very nice so far, and I'm watching this with interest too. The lines are sometimes a bit wonky, but it does show potential. I'd like to see the source code; I'm sure if you shared you'd get some great contributions from some of the regulars here. Keep up the good work. Cheers A Quote Link to comment Share on other sites More sharing options...
roland p Posted September 8, 2008 Share Posted September 8, 2008 Very nice work! It looks like you are creating the stripes simply by changing the background colour at the right time? This is a nice approach as you should be able to create the checkerboard simply by fliping the colours at various points down the screen. Yep, lots of STY, STY.w, STX, STX.w and NOP's. Trail and error based ;D. flipping colors happens already when you've moved 1 tile to the right/left. It also frees up the PF/ball colour to be used for other things. However, this approach won't leave you much time for displaying the sprites over the board. What is needed for sprites? I'm programming the 2600 since Thursday and I've read some tutorials. Positioning is tricky, could that be done outside the board? Then data has to be loaded at the beginning of a scanline right? The alternative is to display an asymmetrical playfield, but this will require a lot of different patterns to be stored. Lot's of shifting around I guess. Now I have the bonus of 3pixel resolution instead of 4. scrolling a part of the checkerboard is now just wait for 1 cycle and everything that comes next is moved 1 cycles (I don't wait for WSYNC) Quote Link to comment Share on other sites More sharing options...
roland p Posted September 8, 2008 Share Posted September 8, 2008 the board says 'Upload failed. You are not permitted to upload this type of file'... The project in it's current state: It's a modified 'hello' demo. Maybe It's ugly, and not cleaned up... Please shoot on it File main3.asm: processor 6502 include vcs.h include macro.h include lines.h org $F000 Temp = $80 PlayfieldY = $90 Direction = $91 ScanLine = $92 SubLineCount = $93 offsetLine0_7 = $94 offsetLine8_15 = $95 offsetLine16_19 = $96 PositionX = $97 invert = $98 Start SEI ; Disable interrupts, if there are any. CLD ; Clear BCD math bit. LDX #$FF TXS ; Set stack to beginning. ; ; Now the memory and TIA registers must be cleared. You may feel the ; need to write a subroutine that only clears out a certain section of ; memory, but for now a simple loop will suffice. ; ; Since X is already loaded to 0xFF, our task becomes simply to ocunt ; everything off. ; LDA #0 B1 STA 0,X DEX BNE B1 ; ; The above routine does not clear location 0, which is VSYNC. We will ; take care of that later. ; ; At this point in the code we would set up things like the data ; direction registers for the joysticks and such. ; JSR GameInit ; ; Here is a representation of our program flow. ; MainLoop JSR VerticalBlank ;Execute the vertical blank. JSR CheckSwitches ;Check console switches. JSR GameCalc ;Do calculations during Vblank JSR DrawScreen ;Draw the screen JSR OverScan ;Do more calculations during overscan JMP MainLoop ;Continue forever. VerticalBlank ;*********************** VERTICAL BLANK HANDLER LDX #0 LDA #2 STA WSYNC STA WSYNC STA WSYNC STA VSYNC ;Begin vertical sync. STA WSYNC ; First line of VSYNC STA WSYNC ; Second line of VSYNC. ; ; But before we finish off the third line of VSYNC, why don't we ; use this time to set the timer? This will save us a few cycles ; which would be more useful in the overscan area. ; ; To insure that we begin to draw the screen at the proper time, ; we must set the timer to go off just slightly before the end of ; the vertical blank space, so that we can WSYNC up to the ACTUAL ; end of the vertical blank space. Of course, the scanline we're ; going to omit is the same scanline we were about to waste VSYNCing, ; so it all evens out. ; ; Atari says we have to have 37 scanlines of VBLANK time. Since ; each scanline uses 76 cycles, that makes 37*76=2888 cycles. ; We must also subtract the five cycles it will take to set the ; timer, and the three cycles it will take to STA WSYNC to the next ; line. Plus the checking loop is only accurate to six cycles, making ; a total of fourteen cycles we have to waste. 2888-14=2876. ; ; We almost always use TIM64T for this, since the math just won't ; work out with the other intervals. 2880/64=44.something. It ; doesn't matter what that something is, we have to round DOWN. ; LDA #44 STA TIM64T ; ; And now's as good a time as any to clear the collision latches. ; LDA #0 STA CXCLR ; ; Now we can end the VSYNC period. ; STA WSYNC ; Third line of VSYNC. STA VSYNC ; (0) ; ; At this point in time the screen is scanning normally, but ; the TIA's output is suppressed. It will begin again once ; 0 is written back into VBLANK. ; RTS ; ; Checking the game switches is relatively simple. ; ; It just so happens that I'm not going to check any game switches ; here. I'm just going to set up the colors, without even checking ; the B&W switch! HA! ; CheckSwitches ;*************************** CONSOLE SWITCH HANDLER LDA #0 STA COLUBK ; Background will be black. RTS ; ; Minimal game calculations, just to get the ball rolling. ; GameCalc ;******************************* GAME CALCULATION ROUTINES CLC LDX PositionX LDA SWCHA ;read joystick AND #$80 CMP #$80 BCS CONT INX STX PositionX CPX #20 BCC CONT LDA invert EOR #$01 STA invert LDX #0 STX PositionX CONT LDA SWCHA ;read joystick AND #$40 CMP #$40 BCS CONT2 DEX STX PositionX CPX #255 BCC CONT2 LDA invert EOR #$01 STA invert LDX #19 STX PositionX CONT2 LDA OFFSET_DATA_0_7,X STA offsetLine0_7 LDA OFFSET_DATA_8_15,X STA offsetLine8_15 LDA OFFSET_DATA_16_19,X STA offsetLine16_19 RTS ChangeDir LDA Direction EOR #$FE STA Direction RTS ; ; This is the scariest thing I've done all month. ; DrawScreen ;**************************** SCREEN DRAWING ROUTINES LDA INTIM BNE DrawScreen ; Whew! STA WSYNC STA VBLANK ;End the VBLANK period with a zero. LDA #2 STA CTRLPF LDA #171 STA ScanLine BlueLines JSR BlueLine DEC ScanLine LDA ScanLine CMP #120 BNE BlueLines LDA #$88 STA COLUBK DEC ScanLine STA WSYNC LDA #$8A STA COLUBK DEC ScanLine LDX invert LDY #$CC LDX #$C4 LDA invert CMP #$01 BNE NOT_INVERT LDX #$CC LDY #$C4 NOT_INVERT STA WSYNC LDA #$9B STA COLUBK DEC ScanLine LDA PositionX CMP #07 BCS Skip1 Skip1 CMP #14 BCS Skip2 Skip2 SLEEP 62 ;LINE 0 SLEEP 12 LINEX 3 LINEY 3 LINEX 3 LINEY 3 LINEX 3 LINEY 3 LINEX 3 LINEY 3 LINEX 3 LINEY 3 LINEX 3 LINEY 3 LINEX 3 LINEY 3 LINEX 3 LINEY 3 LINEX 3 LINEY 3 LINEX 3 SLEEP 14 LINEX 4 LINEY 3 LINEX 4 LINEY 3 LINEX 4 LINEY 3 LINEX 4 LINEY 3 LINEX 4 ; center L LINEY 3 ;center R LINEX 3 LINEY 4 LINEX 3 LINEY 4 LINEX 3 LINEY 4 LINEX 3 LINEY 4 ;LINE 1 LDA offsetLine0_7 AND #%00000010 BNE Line1NoOffset Line1NoOffset SLEEP 13 LINEY 4 LINEX 4 LINEY 4 LINEX 4 LINEY 4 LINEX 4 LINEY 4 LINEX 4 LINEY 4 LINEX 4 LINEY 4 LINEX 4 LINEY 4 SLEEP 18 STX.w COLUBK STY.w COLUBK STX.w COLUBK nop STY COLUBK STX.w COLUBK STY.w COLUBK nop STX COLUBK ;L STY.w COLUBK ;R STX.w COLUBK nop STY COLUBK STX.w COLUBK STY.w COLUBK STX.w COLUBK STY.w COLUBK ;LINEX 4 ;LINEY 4 ;LINEX 4 ;LINEY 4 ;LINEX 4 ;LINEY 4 ;LINEX 5;L ;LINEY 4;R ;LINEX 4 ;LINEY 4 ;LINEX 4 ;LINEY 4 ;LINEX 4 ;LINEY 4 ;LINE 2 LDA offsetLine0_7 AND #%00000100 BNE Line2NoOffset Line2NoOffset SLEEP 11 LINEY 5 LINEX 5 LINEY 5 LINEX 5 LINEY 5 LINEX 5 ;L LINEY 5 ;R LINEX 5 LINEY 5 LINEX 5 LINEY 5 LINEX 5 SLEEP 13 LINEY 5 LINEX 6 LINEY 5 LINEX 6 LINEY 5 LINEX 6 ;L LINEY 5 ;R LINEX 5 LINEY 6 LINEX 5 LINEY 6 LINEX 5 ;LINE 3 LDA offsetLine0_7 AND #%00001000 BNE Line3NoOffset Line3NoOffset SLEEP 12 LINEY 6 LINEX 6 LINEY 6 LINEX 6 LINEY 6 LINEX 6 LINEY 6 LINEX 6 SLEEP 27 LINEY 6 LINEX 6 LINEY 6 nop LINEX 5;L LINEY 6;R LINEX 6 nop LINEY 5 LINEX 5 ;LINE 4 LDA offsetLine0_7 AND #%00010000 BNE Line4NoOffset Line4NoOffset SLEEP 18 LINEY 7 LINEX 7 LINEY 7 LINEX 7 LINEY 7 LINEX 7 LINEY 7 LINEX 7 SLEEP 19 LINEY 7 LINEX 7 LINEY 7 LINEX 8;R LINEY 7;L LINEX 7 LINEY 8 LINEX 7 ;LINE 5 LDA offsetLine0_7 AND #%00100000 BNE Line5NoOffset Line5NoOffset SLEEP 7 LINEY 8 LINEX 8 LINEY 8 LINEX 8 LINEY 8 LINEX 8 LINEY 8 LINEX 4 SLEEP 15 LINEY 8 LINEX 8 LINEY 8 nop LINEX 7 ;L LINEY 8 ;R LINEX 8 nop LINEY 7 LINEX 8 LINEY 4 ;LINE 6 LDA offsetLine0_7 AND #%01000000 BNE Line6NoOffset Line6NoOffset SLEEP 6 LINEX 9 LINEY 9 LINEX 9 LINEY 9 LINEX 9 LINEY 9 LINEX 9 LINEY 3 SLEEP 9 LINEX 9 LINEY 9 LINEX 10 ;L LINEY 9 ;R LINEX 9 LINEY 10 ;LINE 7 LDA offsetLine0_7 AND #%10000000 BNE Line7NoOffset Line7NoOffset SLEEP 10 LINEX 10 LINEY 10 LINEX 10 LINEY 10 LINEX 10 LINEY 10 SLEEP 16 LINEX 10 LINEY 10 LINEX 10 LINEY 10 LINEX 10 LINEY 10 ;line 8 LDA offsetLine8_15 AND #%00000001 BNE Line8NoOffset Line8NoOffset SLEEP 7 LINEX 11 LINEY 11 LINEX 11 LINEY 11 LINEX 11 LINEY 5 SLEEP 15 LINEX 11 LINEY 11 LINEX 10 ;L nop LINEY 11 ;R LINEX 11 LINEY 3 ;line 9 LDA offsetLine8_15 AND #%00000010 BNE Line9NoOffset Line9NoOffset SLEEP 7 LINEX 12 LINEY 12 LINEX 12 LINEY 12 LINEX 12 LINEY 4 SLEEP 12 LINEX 12 LINEY 12 LINEX 12 LINEY 12 LINEX 12 LINEY 4 LINEX 8 ;line 10 LDA offsetLine8_15 AND #%00000100 BNE Line10NoOffset Line10NoOffset SLEEP 8 LINEY 13 LINEX 13 LINEY 13 LINEX 13 LINEY 3 LINEX 3 SLEEP 18 LINEY 13 LINEX 13 LINEY 13 LINEX 13 LINEY 3 LINEX 3 ;line 11 LDA offsetLine8_15 AND #%00001000 BNE Line11NoOffset Line11NoOffset ;SLEEP 18 SLEEP 8 LINEY 14 LINEX 14 LINEY 14 LINEX 14 SLEEP 20 LINEY 14 LINEX 14 LINEY 14 LINEX 4 ;line 12 LDA offsetLine8_15 AND #%00010000 BNE Line12NoOffset Line12NoOffset SLEEP 22 LINEY 15 LINEX 15 LINEY 15 LINEX 3 SLEEP 28 LINEY 15 LINEX 15 LINEY 15 LINEX 3 ;line 13 LDA offsetLine8_15 AND #%00100000 BNE Line13NoOffset Line13NoOffset SLEEP 18 LINEY 16 LINEX 16 LINEY 16 LINEX 4 SLEEP 24 LINEY 16 LINEX 16 LINEY 16 LINEX 4 ;line 14 LDA offsetLine8_15 AND #%01000000 BNE Line14NoOffset Line14NoOffset SLEEP 16 LINEY 17 LINEX 17 LINEY 17 LINEX 3 SLEEP 22 LINEY 17 LINEX 17 LINEY 17 LINEX 3 ;line 15 LDA offsetLine8_15 AND #%10000000 BNE Line15NoOffset Line15NoOffset SLEEP 12 LINEY 18 LINEX 18 LINEY 18 LINEX 4 SLEEP 18 LINEY 18 LINEX 18 LINEY 18 LINEX 4 ;line 16 LDA offsetLine16_19 AND #%00000001 BNE Line16NoOffset Line16NoOffset SLEEP 10 LINEY 19 LINEX 19 LINEY 19 LINEX 3 SLEEP 16 LINEY 19 LINEX 19 LINEY 19 LINEX 3 ;line 17 LDA offsetLine16_19 AND #%00000010 BNE Line17NoOffset Line17NoOffset SLEEP 6 LINEY 20 LINEX 20 LINEY 20 LINEX 4 SLEEP 12 LINEY 20 LINEX 20 LINEY 20 LINEX 4 ;line 18 LDA offsetLine16_19 AND #%00000100 BNE Line18NoOffset Line18NoOffset SLEEP 4 LINEY 21 LINEX 21 LINEY 21 LINEX 3 SLEEP 10 LINEY 21 LINEX 21 LINEY 21 LINEX 3 ;line 19 LDA offsetLine16_19 AND #%00001000 BNE Line19NoOffset Line19NoOffset ;SLEEP 7 LINEY 22 LINEX 22 LINEY 22 LINEX 4 SLEEP 6 LINEY 22 LINEX 22 LINEY 22 LINEX 6 LDA #$0 STA COLUBK ; Draw other lines DrawLines STA WSYNC DEC ScanLine BNE DrawLines STA WSYNC ;Finish this scanline. STA VBLANK ; Make TIA output invisible, RTS ; ; For the Overscan routine, one might take the time to process such ; things as collisions. I, however, would rather waste a bunch of ; scanlines, since I haven't drawn any players yet. ; OverScan ;***************************** OVERSCAN CALCULATIONS LDX #30 KillLines STA WSYNC DEX BNE KillLines RTS BlueLine LDA #$85 STA COLUBK STA WSYNC RTS Line1 STA COLUBK NOP SLEEP 4 LINEX 5 LINEY 5 LINEX 5 LINEY 5 LINEX 5 LINEY 5 LINEX 5 LINEY 5 LINEX 5 LINEY 5 STA WSYNC RTS Line2 STX.w COLUBK SLEEP 5 LINEY 6 LINEX 6 LINEY 6 LINEX 6 LINEY 6 LINEX 6 LINEY 6 LINEX 6 STA WSYNC RTS Line3 SLEEP 6 LINEY 7 LINEX 7 LINEY 7 LINEX 7 LINEY 7 LINEX 7 LINEY 7 LINEX 3 STA WSYNC RTS Line4 SLEEP 9 LINEX 8 LINEY 8 LINEX 8 LINEY 8 LINEX 8 LINEY 8 LINEX 3 STA WSYNC RTS Line5 SLEEP 7 LINEX 9 LINEY 9 LINEX 9 LINEY 9 LINEX 9 LINEY 9 STA WSYNC RTS Line6 SLEEP 3 LINEX 10 LINEY 10 LINEX 10 LINEY 10 LINEX 10 LINEY 8 STA WSYNC RTS Line7 ;SLEEP 1 LINEX 12 LINEY 11 LINEX 11 LINEY 11 LINEX 11 LINEY 3 STA WSYNC RTS Line8 ;SLEEP 1 LINEX 9 LINEY 12 LINEX 12 LINEY 12 LINEX 12 LINEY 4 STA WSYNC RTS Line9 ;SLEEP 1 LINEX 8 LINEY 13 LINEX 13 LINEY 13 LINEX 3 STA WSYNC RTS Line10 ;SLEEP 1 LINEX 5 LINEY 14 LINEX 14 LINEY 4 LINEY 11 LINEX 3 STA WSYNC RTS ; ; GameInit could conceivably be called when the Select key is pressed, ; or some other event. ; GameInit LDA #0 STA PlayfieldY LDA #1 STA Direction; Set Direction to 1 LDA #0 STA PositionX LDA #0 STA invert RTS ; ; Graphics are placed so that the extra cycle in the PFData,X indexes ; is NEVER taken, by making sure it never has to index across a page ; boundary. This way our cycle count holds true. ; org $FF00 ; *********************** GRAPHICS DATA ; ; This is the tricky part of drawing a playfield: actually ; drawing it. Well, the display routine and all that binary ; math was a bit tricky, too, but still, listen up. ; ; Playfield data isn't stored the way most bitmaps are, even ; one-dimensional bitmaps. We will use the left side of the ; screen only, knowing that the right side is either repeated ; or reflected from it. ; ; In PF0 and PF2, the most significant bit (bit 7) is on the RIGHT ; side. In PF1, the most significant bit is on the LEFT side. This ; means that relative to PF0 and PF2, PF1 has a reversed bit order. ; It's just really weird. ; ; PF0 | PF1 | PF2 ; 4 5 6 7|7 6 5 4 3 2 1 0|0 1 2 3 4 5 6 7 ; ; This is important to remember when doing calculations on bytes intended ; for the PF registers. Defender gives a good example of this. ; ; It will become necessary to write a program that makes this easier, ; because it is easy to become confused when dealing with this system. ; OFFSET_DATA_0_7 .byte $0,$0,$80,$20,$10,$88,$48,$24,$94,$54,$B4,$AC,$6C,$DA,$BA,$76,$F6,$DE,$FE,$FE OFFSET_DATA_8_15 .byte $0,$4,$20,$84,$11,$24,$4A,$95,$2A,$55,$AA,$B5,$DB,$6E,$BB,$DF,$FB,$7F,$FB,$FF OFFSET_DATA_16_19 .byte $0,$0,$0,$0,$2,$4,$4,$8,$2A,$A,$2A,$C,$C,$36,$36,$1A,$3A,$3E,$1E,$1E org $FFFC .word Start .word Start File Lines.h: MAC LINEY .CYCLES SET {1} IF .CYCLES < 3 ECHO "MACRO ERROR: 'SLEEP': Duration must be > 2" ERR ENDIF IF .CYCLES & 1 STY COLUBK .CYCLES SET .CYCLES - 3 ELSE STY.w COLUBK .CYCLES SET .CYCLES - 4 ENDIF REPEAT .CYCLES / 2 nop REPEND ENDM MAC LINEX .CYCLES SET {1} IF .CYCLES < 3 ECHO "MACRO ERROR: 'SLEEP': Duration must be > 2" ERR ENDIF IF .CYCLES & 1 STX COLUBK .CYCLES SET .CYCLES - 3 ELSE STX.w COLUBK .CYCLES SET .CYCLES - 4 ENDIF REPEAT .CYCLES / 2 nop REPEND ENDM MAC LINEY2 .CYCLES SET {1} IF .CYCLES < 3 ECHO "MACRO ERROR: 'SLEEP': Duration must be > 2" ERR ENDIF IF .CYCLES & 1 .CYCLES2 SET .CYCLES - 3 ELSE .CYCLES2 SET .CYCLES - 4 ENDIF REPEAT .CYCLES2 / 2 nop REPEND IF .CYCLES & 1 STY COLUBK ELSE STY.w COLUBK ENDIF ENDM MAC LINEX2 .CYCLES SET {1} IF .CYCLES < 3 ECHO "MACRO ERROR: 'SLEEP': Duration must be > 2" ERR ENDIF IF .CYCLES & 1 .CYCLES2 SET .CYCLES - 3 ELSE .CYCLES2 SET .CYCLES - 4 ENDIF REPEAT .CYCLES2 / 2 nop REPEND IF .CYCLES & 1 STX COLUBK ELSE STX.w COLUBK ENDIF ENDM ; EOF Quote Link to comment Share on other sites More sharing options...
roland p Posted September 8, 2008 Share Posted September 8, 2008 (edited) I'll make it cleaner when I have the time. Edit: As Andrew suggested, the project is now opensource! I truly believe it will be better if everyone is able to put their part in it. There is lot's to be done like game play-code, sounds. Edited September 8, 2008 by roland p Quote Link to comment Share on other sites More sharing options...
cd-w Posted September 8, 2008 Share Posted September 8, 2008 (edited) Yep, lots of STY, STY.w, STX, STX.w and NOP's. Trail and error based ;D. flipping colors happens already when you've moved 1 tile to the right/left. If you also flip the colours as you move down the screen then you can create the checkerboard. My Juno First game displays moving lines to simulate movement. If you used this kind of approach to determine when to flip the colours then I think you would have a nice fully-functioning checkerboard. What is needed for sprites? I'm programming the 2600 since Thursday and I've read some tutorials. Positioning is tricky, could that be done outside the board? Then data has to be loaded at the beginning of a scanline right? Horizontal sprite positioning can be done outside the kernel. Inside the kernel you need to decide what sprite data to display on each line. I think Ballblazer only has two sprites that overlap the board (the other player, and the goalposts)? You will need to switch on/off these sprites on the right lines while drawing the grid. A good summary of the different approaches (skipdraw, switchdraw etc.) was posted in this thread. Lot's of shifting around I guess. Now I have the bonus of 3pixel resolution instead of 4. scrolling a part of the checkerboard is now just wait for 1 cycle and everything that comes next is moved 1 cycles (I don't wait for WSYNC) If you stored all of the different possible patterns in ROM then you could just display the appropriate one on each frame, but I think this would require a LOT of ROM space! Thanks for sharing the code - you should get some good feedback from this. To upload code directly onto the forum, place it inside a ZIP file first. Chris Edited September 8, 2008 by cd-w Quote Link to comment Share on other sites More sharing options...
roland p Posted September 8, 2008 Share Posted September 8, 2008 Juno First looked really good, it's exactly what I am looking for. I just hope that I have enough cycles left for sprites... Quote Link to comment Share on other sites More sharing options...
roland p Posted September 11, 2008 Share Posted September 11, 2008 (edited) Just a small update to keep it alive. I did not have much time to work on the project but some improvements have been made. Things improved this time: 1. vertical resolution is now doubled. 2. precalculation of the movement is now correct maybe some small glitches, but much better then before. 3. I use a vanishing point up in the sky, where it really is. 4. the horizontal scrolling is now at a high precision at 1 virtual colorclock The precalculated vector for the movement is still at half the vertical resolution of the checkerboard.... ballblazer.bin Edited September 11, 2008 by roland p Quote Link to comment Share on other sites More sharing options...
+Andrew Davie Posted September 11, 2008 Share Posted September 11, 2008 Just a small update to keep it alive. I did not have much time to work on the project but some improvements have been made.Things improved this time: 1. vertical resolution is now doubled. 2. precalculation of the movement is now correct maybe some small glitches, but much better then before. 3. I use a vanishing point up in the sky, where it really is. 4. the horizontal scrolling is now at a high precision at 1 virtual colorclock The precalculated vector for the movement is still at half the vertical resolution of the checkerboard.... This is very nice; well done! If it were me, the next thing I'd do would be put a bit of inertia on the movement, so when you move in a direction, it takes a little while to accelerate, and when you let go, it takes a little while to stop. I think this would really accentuate the effect. Also, I'm wondering how much better it will look with the squares done -- that is, alternating the colours and making it a real chequerboard. You could also just repeat the first bunch of scanlines again to give yourself a dual-window display, which would be pretty cool too. Good work so far, keep going! Cheers A Quote Link to comment Share on other sites More sharing options...
Thomas Jentzsch Posted September 11, 2008 Share Posted September 11, 2008 I agree with Andrew, pretty impressive already. And I am also really looking forward to the checkerboard. Maybe you could try to use flicker to simulate antialiasing? At least it would be interesting to see the result. Quote Link to comment Share on other sites More sharing options...
roland p Posted September 11, 2008 Share Posted September 11, 2008 This is very nice; well done! thanx! If it were me, the next thing I'd do would be put a bit of inertia on the movement, so when you move in a direction, it takes a little while to accelerate, and when you let go, it takes a little while to stop. I think this would really accentuate the effect. You're right. that would look cool. I've downloaded the Atari 5200 version of Ballblazer see what's really going on. Also, I'm wondering how much better it will look with the squares done -- that is, alternating the colours and making it a real chequerboard. Yep, it's about time I will work something out. Quote Link to comment Share on other sites More sharing options...
roland p Posted September 11, 2008 Share Posted September 11, 2008 Maybe you could try to use flicker to simulate antialiasing? At least it would be interesting to see the result. mmmh... interesting. by increasing/decreasing horizontal movement by a pixel every other frame. Maybe that looks nice. I've seen in the atari 5200 version that there is a sort of antialiassing in the vertical direction, the 2600 should be able to do that too. Quote Link to comment Share on other sites More sharing options...
Thomas Jentzsch Posted September 11, 2008 Share Posted September 11, 2008 mmmh... interesting. by increasing/decreasing horizontal movement by a pixel every other frame. Maybe that looks nice. Interesting idea. Didn't think about this. My idea is to use a different vertical offset for the "line" drawing. E.g. when you more one pixel of center, the pixel "jump" now is visible around the lower third. Which is probably the correct position when there is more than 50% of the pixel on the other side. With vertical antialiasing, you could do the pixel jump for the even frame a bit above and for the odd frame a bit below (e.g. after 25 and 75%) the current position. Anyway, do whatever looks better. I've seen in the atari 5200 version that there is a sort of antialiassing in the vertical direction, the 2600 should be able to do that too. Yup, we would have vertical antialiasing here too. Quote Link to comment Share on other sites More sharing options...
roland p Posted September 11, 2008 Share Posted September 11, 2008 Interesting idea. Didn't think about this. My idea is to use a different vertical offset for the "line" drawing. E.g. when you more one pixel of center, the pixel "jump" now is visible around the lower third. Which is probably the correct position when there is more than 50% of the pixel on the other side. With vertical antialiasing, you could do the pixel jump for the even frame a bit above and for the odd frame a bit below (e.g. after 25 and 75%) the current position. Anyway, do whatever looks better. I've now used a 2 pixel offset every other frame. It looks not bad. I've to change my tables a bit to make it look even better, but now you have REAL antialiassing! ballblazer.bin Quote Link to comment Share on other sites More sharing options...
+Andrew Davie Posted September 11, 2008 Share Posted September 11, 2008 Interesting idea. Didn't think about this. My idea is to use a different vertical offset for the "line" drawing. E.g. when you more one pixel of center, the pixel "jump" now is visible around the lower third. Which is probably the correct position when there is more than 50% of the pixel on the other side. With vertical antialiasing, you could do the pixel jump for the even frame a bit above and for the odd frame a bit below (e.g. after 25 and 75%) the current position. Anyway, do whatever looks better. I've now used a 2 pixel offset every other frame. It looks not bad. I've to change my tables a bit to make it look even better, but now you have REAL antialiassing! Noooo! This is a bad bad idea! It was so very clean, without any flickering. You're spoiling it with this totally unnecessary stuff. Stick to getting the checquerboard working, don't fix something that wasn't broken! Seriously, stay focused... don't get diverted! Cheers A Quote Link to comment Share on other sites More sharing options...
roland p Posted September 11, 2008 Share Posted September 11, 2008 Ok, I'll stick to the useful stuff Quote Link to comment Share on other sites More sharing options...
Thomas Jentzsch Posted September 11, 2008 Share Posted September 11, 2008 Noooo! This is a bad bad idea! It was so very clean, without any flickering. It doesn't look good on emulators and due to syncing problems most likely never will. But it might look good on a real TV if done right. Maybe as a switchable option. But I agree, for now other stuff is more important. Quote Link to comment Share on other sites More sharing options...
+Random Terrain Posted September 11, 2008 Share Posted September 11, 2008 Noooo! This is a bad bad idea! It was so very clean, without any flickering. You're spoiling it with this totally unnecessary stuff. Stick to getting the checquerboard working, don't fix something that wasn't broken! Seriously, stay focused... don't get diverted! Yeah, it looked better the old way. I bet this will look pretty darn good when it's done. Quote Link to comment Share on other sites More sharing options...
roland p Posted September 12, 2008 Share Posted September 12, 2008 Hi there, My 4K is reaching its limits. The code for drawing the lines is a bit big because it's completely based on processor cycles. And besides the code, I use some tables for the horizontal movement wich occupies 207 bytes. The sinus table for vertical movement (which is needed to complete the tiles) is another 69 bytes. This results in >4K of ROM. Now I've tried to calculate the vector in real time to save those 207 bytes. This is possible and takes now about 700 cycles. That's cool, but I'll get into memory problems anway. So what I want to do is: 1. Ditch the vector routine, nothing beats LDA OFFSET_DATA_0_7,X. Don't fix anything that's not broken 2. Add some bankswitching Is this the way to go? When I do bankswitching, I would want to go for the full 32K. What's the best way to do that? Btw. I've downloaded a 6502 simulator to test small parts of code: http://home.pacbell.net/michal_k/6502.html You can exactly see what is going on. Really nice! Quote Link to comment Share on other sites More sharing options...
vdub_bobby Posted September 12, 2008 Share Posted September 12, 2008 1. Ditch the vector routine, nothing beats LDA OFFSET_DATA_0_7,X. Don't fix anything that's not broken 2. Add some bankswitching Is this the way to go? When I do bankswitching, I would want to go for the full 32K. What's the best way to do that? Yes, add bankswitching. You'll never get a decent (or even playable ) Ballblazer clone in 4K. Bankswitching is pretty easy, you just have to organize your code and data carefully. To set up your source code, just ORG each 4K block to wherever (make sure the 32K is consecutive) and RORG it to $Fxxx. You can search the forums for more information. Or you can get crazy and use the wacky 32K bankswitching scheme I came up with. No one else seems to think it's that cool, but I love it. Quote Link to comment Share on other sites More sharing options...
roland p Posted September 17, 2008 Share Posted September 17, 2008 @vdub_bobby, I get to the backswitching later. I have fixed the issue now by altering some 'org' declarations. Due to extremely short spare time in the checkerboard edges, I've not enough time/memory to update all sprites every line. Therefore I thought of the following: update everyline one sprite, giving a vertical resolution of 4 pixels per sprite, and change the update pattern every frame to get a interlaced like effect. Unfortunatly, it does not work. Can anyone tell me why the following code does not work? LDA GRP1 STA SPRITE_POINTERA LDX #0 LDA #%10101010 STA (SPRITE_POINTERA,X) And why the following code DOES work? LDA GRP0 STA SPRITE_POINTERA LDX #0 LDA #%10101010 STA (SPRITE_POINTERA,X) Maybe I'm doing something very stupid and it is not possible at all... Quote Link to comment Share on other sites More sharing options...
Cybergoth Posted September 17, 2008 Share Posted September 17, 2008 They actually both shouldn't work reliably without a # before the GRPs. The code looks pretty weird anyway, what are you trying to do there? I have yet to see some useful code using ($$,X) indexing Quote Link to comment Share on other sites More sharing options...
roland p Posted September 17, 2008 Share Posted September 17, 2008 They actually both shouldn't work without a # before the GRP. Crap! That solved the problem! Thanks! Funny that 'GRP0' does work. Probably the value $1B is stored at that adres? Quote Link to comment Share on other sites More sharing options...
+Andrew Davie Posted September 17, 2008 Share Posted September 17, 2008 @vdub_bobby,I get to the backswitching later. I have fixed the issue now by altering some 'org' declarations. Due to extremely short spare time in the checkerboard edges, I've not enough time/memory to update all sprites every line. Therefore I thought of the following: update everyline one sprite, giving a vertical resolution of 4 pixels per sprite, and change the update pattern every frame to get a interlaced like effect. Unfortunatly, it does not work. Can anyone tell me why the following code does not work? LDA GRP1 STA SPRITE_POINTERA LDX #0 LDA #%10101010 STA (SPRITE_POINTERA,X) And why the following code DOES work? LDA GRP0 STA SPRITE_POINTERA LDX #0 LDA #%10101010 STA (SPRITE_POINTERA,X) Maybe I'm doing something very stupid and it is not possible at all... I never once found the need to use indexed indirect (addr,x) addressing. Not once! Why can't this code be written... ldx #0 lda #%10101010 sta GRP0,x Or even just drop the indexing and use absolute writes. It's quicker! Anyway, to answer your question... read this... Indexed Indirect Addressing --------------------------- Find the 16-bit address starting at the given location plus the current X register. The value is the contents of that address. For example, LDA ($B4,X) where X contains 6 gives an address of $B4 + 6 = $BA. If $BA and $BB contain $12 and $EE respectively, then the final address is $EE12. The value at location $EE12 is put in the accumulator. So, looks like you're retrieving a 16 bit address from the location SPRITE_POINTERA, SPRITE_POINTERA+1 (which is uninitialised) and then you're adding the X register to that, and writing to that resulting address. Could be anything. Pure chance either of your examples works at all, I'd say. Um, well actually since we have mirrored memory, in theory you are still writing to zero page. This code will work OK with the # as Manuel said, but it will fail on some bankswitching schemes when you switch later. It's broken, so fix it Cheers A Quote Link to comment Share on other sites More sharing options...
Cybergoth Posted September 17, 2008 Share Posted September 17, 2008 Funny that 'GRP0' does work. Probably the value $1B is stored at that adres? Chances are usually good that the you get the last value returned from the bus, which indeed was GRP0. The exact behaviour may depend on the machine model and certain race conditions though I think. I'm sure somewhere on this board you'll find an essay from supercat detailling what exactly happens Quote Link to comment Share on other sites More sharing options...
roland p Posted September 17, 2008 Share Posted September 17, 2008 The code looks pretty weird anyway, what are you trying to do there? I have yet to see some useful code using ($$,X) indexing I've (hope) just enough time to update 1 sprite/line. And I have 4 sprites to draw. so the kernel could look like this: at line 1 update sprite 1 with data1 at line 2 update sprite 2 with data2 at line 3 update missle with data3 at line 4 update ball with data4 ... ... at line 37 update sprite 1 with data37 at line 38 update sprite 2 with data38 at line 39 update missle with data39 at line 40 update ball with data40 etc. (data1..40 is memory) That could work, but will look funny. because every sprite is drawn on another line. By using pointers, I could change on wich line wich sprite is updated, that would look like this: at line 1 update @pointerA with data1 at line 2 update @pointerB with data2 at line 3 update @pointerC with data3 at line 4 update @pointerD with data4 PointerA would point to sprite 1 at frame 1, and to sprite 2 at frame 2 etc. I hope I'm clear. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.