Thomas Jentzsch Posted March 25 Share Posted March 25 (edited) I did not know this mobile game until lately. It soon becomes really hard, but I think it might be a good candidate for a 2600 game. A bit easier, without the bells and whistles and probably rotated by 90°, it seems quite doable. Duet (V0.1) (Thomas Jentzsch).bin Duet (V0.2) (Thomas Jentzsch).bin Duet (V0.3) (Thomas Jentzsch).bin Edited June 26 by Thomas Jentzsch 10 1 Quote Link to comment Share on other sites More sharing options...
+Al_Nafuur Posted March 25 Share Posted March 25 Looks like a mix of Top&Tom and Amoeba Jump Quote Link to comment Share on other sites More sharing options...
Thomas Jentzsch Posted March 25 Author Share Posted March 25 It plays quite differently. Give it a try, you can play it for free. Quote Link to comment Share on other sites More sharing options...
DeafAtariFromKansas Posted March 25 Share Posted March 25 it's similar to diamond drop Quote Link to comment Share on other sites More sharing options...
Thomas Jentzsch Posted March 25 Author Share Posted March 25 (edited) 24 minutes ago, DeafAtariFromKansas said: it's similar to diamond drop Thanks for pointing me at it. I must have missed (or forgotten?) it. Anyway, I think there is room for another version. Maybe with DC support. Edited March 25 by Thomas Jentzsch 2 Quote Link to comment Share on other sites More sharing options...
+sramirez2008 Posted March 25 Share Posted March 25 46 minutes ago, Thomas Jentzsch said: Anyway, I think there is room for another version. Maybe with DC support. This looks like a great candidate for DC support. Quote Link to comment Share on other sites More sharing options...
Thomas Jentzsch Posted March 29 Author Share Posted March 29 (edited) So I started wondering how one could do this game on the 2600. For doing that, I analyzed the original (mostly by watching YouTube videos). It is obvious that the 2600 cannot do the nice background animation and phosphor effects, so these bells and whistles have to go. We will have to concentrate on the pure gameplay instead (maybe with some music, we'll see). I noted all the obstacles and how they behave. There are not that many obstacle types, just 7 non-rotating and two 2 rotating rectangles. However there can be up to 8 on the screen at the same time (all non-rotating types). Since I didn't want to use flicker, this soon ruled out horizontal scrolling, even though that would have fit better to the 2600 screen orientation. So I decided for vertical scrolling, which also has a better resolution than horizontal scrolling. Now, how should I display them? At the bottom the obstacles are vertically spaced, else you couldn't get past them. But at the top they are not. Also I wanted to use colors for the player's rotating orbs. So obstacles cannot be sprites (or can they?😉). Fortunately the non-rotating obstacles can be nicely represented by using the playfield. This will allow multiple obstacles overlapping. I decided for a 15 playfield pixel wide playfield at the center and scaled everything accordingly. This size can be done with a reflected playfield and just 2, well timed writes to PF2. The code for this is pretty simple, you just OR the data together, separately for left and right PF2: lda (pfPtr0L),y ; 5 ora (pfPtr1L),y ; 5 ora (pfPtr2L),y ; 5 sta PF2 ; 3 ... lda (pfPtr0R),y ; 5 ora (pfPtr1R),y ; 5 ora (pfPtr2R),y ; 5 sta PF2 ; 3 @48! The non-rotating obstacles can be moving down at different speeds, which is no problem with this kernel code. However, in later levels, some can also move horizontally! This would look ugly when using the playfield. And then we have the rotating obstacles. So I have to mix sprites into it too. Later... The next problem to overcome is the amount of space used for the obstacles data. Since I simply OR the data together, no matter where the obstacles are vertically placed, this needs padding 0s below and above the actually graphics data. For a 200 pixel tall kernel, I would need 199 0s before and after each obstacle data. This would eat up a lot of space and also cause page faults. For now I decided to split the kernel into 3 sections, with the bottom kernel containing the player's orbs. I know this will cause me quite some trouble with pointer handling (I hope I am not running out of CPU time or RAM there), but currently it seems like the best solution/compromise. Now, since I have to use sprites, how can the player's orbs have a different color? There cannot be white obstacle sprites and red or blue orb missiles at the same scanline. Also, there seems to be no time for repositioning sprites during the kernel. The first decision to solve the problem was to draw the orbs using missiles. Also I will limit the number of horizontally moving obstacles on screen to 2. This completely solves the repositioning problem. And for allowing horizontally moving obstacles besides the orbs, I plan to split the bottom kernel into three kernels. Since the orbs can only overlap when they are (mostly) horizontal positioned, the top and the bottom areas will always have only one orb. This will allow for one horizontally moving obstacle (sprite). And in the middle area, where no sprites are allowed, I will make sure that the obstacles are not moving. If you look closely to the original game, it also pauses horizontal movement for a moment when an obstacle reaches its leftmost or rightmost position. So that's what I am copying here, just a bit more restricted. The original game has a nice circle, which visualizes the movement area of the two orbs. I am not exactly sure if and how I should replicate that. Currently I have implemented two solutions (one is flickering and one is just a dot), which you can switch using left difficulty. Both use the ball, which is nice because it shares its color with the obstacles. Now to the orbs: I wanted the orbs to be not square, therefore using the missiles for them requires writing to ENAMx at the right spot plus extra NUSIZx and HMMx updates. Since I still have to update the playfield for at least two obstacles, the missile code has to be fast. Reading the data separately would require three large tables (again with a lot of padding bytes) and 5 cycles per read. But I knew that all the bits required for the 3 TIA registers would fit into byte. So I had to come up with some fast code here. Here is how it looks for one orb: lda (dot0Ptr),y ; 5 sta NUSIZ0 ; 3 adc #$e7 ; 2 sta HMM0 ; 3 sta ENAM0 ; 3 = 16 So that's 16 vs. 24 cycles required when reading the data individually. Good. And this is the data: ds PADDING_H, $1d ; + $e7 = $04 .byte $17 ; + $e7 = $fe .byte $27 ; + $e7 = $0e .byte $27 ; + $e7 = $0e .byte $27 ; + $e7 = $0e .byte $27 ; + $e7 = $0e .byte $2f ; + $e7 = $16 .byte $1f ; + $e7 = $06 ds PADDING_H, $1d ; + $e7 = $04 The orb is 2 pixel wide at top and bottom, and 4 pixel wide in the middle 5 rows. But how does it work and why do I use these really odd numbers? Well, I had to consider quite some constraints: - avoid CLC for the ADC - avoid values for NUSIZx which create repeated sprites (and missiles!) - have bit 2 always set for ENAMx while the orb is drawn, but have the bit always clear while the orb is not drawn - get the correct HMMx values while the orb is drawn, but do not move while it is not drawn If you check each value for NUSIZx and the resulting value for HMMx and ENAMx, you will find that all constraints are met. Since none of the TIA registers are delayed, the timing is also critical. Due to the narrow area I am using for the game, I have some extra CPU time after the orbs have been drawn. That's when I update their TIA registers. However I must not update the right orb too early, else it will look garbled. Therefore my code makes sure that the rightmost orb is always drawn using missile 1 (which is updated last). This only barely works, but who cares? You may notice that the orbs are a bit smaller than in the original. This is (also) because I want to use pixel perfect hardware collisions. The original game is not that strict, therefore the slightly smaller orbs should compensate that. As of now, I have only done the bottom kernel. It is not split yet, so it cannot do horizontally moving or rotating obstacles. I first want to figure out how to organize the pointers at the top kernels. Anyway, here is the current result. There is no collision detection, just movable orbs (joystick left and right) and randomly created obstacles moving down at 3 different speeds. Every ~4 seconds, the game speed increases by 1/32 (it will become insane eventually). There are only ~1750 bytes free with top kernels and lots of code still missing. Therefore I already strongly doubt that I can do the game in 4K, but I will keep trying. BTW: If you use high phosphor (~75%) in Stella, you can get a bit closer to the original look. But that's cheating. Duet (V0.01) (Thomas Jentzsch).bin Edited March 29 by Thomas Jentzsch 5 Quote Link to comment Share on other sites More sharing options...
Thomas Jentzsch Posted March 31 Author Share Posted March 31 (edited) I made some progress over the last days and created version 0.1 (see 1st post): - all kernels are done - the code can handle up to 6 obstacles at a time - the obstacle generation follows some rules (there is still room for improvement) - added collision detection with some basic sound So there now is at least some gameplay. Next planned steps: - add falling obstacles (they move into their final vertical position close to middle of the orb area) - allowing disappearing obstacles (I have some working code, but it needs refinement) - make use of the sprites (rotating and horizontally moving obstacles) - create rounds, where the player has to master a number of obstacles without any collisions to get to the next round. each round will become a bit harder (longer, more difficult obstacles...) Edited March 31 by Thomas Jentzsch 6 Quote Link to comment Share on other sites More sharing options...
Thomas Jentzsch Posted April 4 Author Share Posted April 4 (edited) Slow progress: - implemented the delayed obstacles, which fall fast into their positions. - also revised the obstacle data after realizing hwo graceful the original game is to collisions. Now the gaps are wider. - this also allowed me to switch to a fully symmetric playfield, so I can reuse the data from the left side at the right side too. - which freed almost 1K of data! Now I am much more optimistic for a 4K version. - using sprites has been added too, you can spot them with debug colors enabled. - had to refactor the bottom kernel, because I a had an error in my original plan on how to use them in parallel with the dots. Next is to make use of the sprites for fading and horizontally moving obstacles. Edited April 4 by Thomas Jentzsch 2 Quote Link to comment Share on other sites More sharing options...
Thomas Jentzsch Posted April 9 Author Share Posted April 9 (edited) With version 0.3 (see first post), the game finally gets some structure. - added fading and horizontally moving obstacles - the game is now played in stages of increasing difficulty You start a game with 3 lives and gain an extra live for each finished stage, up to 3 lives. To start and to continue the game after a stage or a crash, press FIRE. Notes: - The difficulty ramp up is far from being finished. Currently each stage only gets one obstacle longer and a bit faster. I plan to have much easier early stages, where the various obstacle types are introduced slowly. As of now, the game starts with everything thrown at you at once. - Some obstacle combinations fall too late, I will fix that with the next version - Also the collision detection of faded obstacles at the very bottom of the screen doesn't exist. Another planned fix. BTW: The code already counts the stages and even the score, but there is no code to display them. Edited April 9 by Thomas Jentzsch 6 Quote Link to comment Share on other sites More sharing options...
+Karl G Posted April 11 Share Posted April 11 Fascinating game concept and conversion to the 2600 for sure. I'm wondering if anyone has actually gotten good at this game yet? No reason... Quote Link to comment Share on other sites More sharing options...
Thomas Jentzsch Posted April 12 Author Share Posted April 12 23 hours ago, Karl G said: I'm wondering if anyone has actually gotten good at this game yet? No reason... The original? Yes! And the "Endless Run" records are extremely high (25,000,000,000 points and more) 2 Quote Link to comment Share on other sites More sharing options...
+ZeroPage Homebrew Posted April 14 Share Posted April 14 ZeroPage Homebrew is playing Duet on tomorrow's ZPH stream LIVE on Twitch, hope you can join us! Fri Apr 14, 2023 | LIVE @ 12PM PT | 3PM ET | 7PM GMT WATCH LIVE: https://www.twitch.tv/zeropagehomebrew/WATCH LATER: https://youtube.com/zeropagehomebrew/ Games: 3-Point Dash (2023 WIP | 2600) by Mirsad Sarajlic @kikipdph Duet (2023 WIP | 2600) by Thomas Jentzsch @Thomas Jentzsch Cosmic Combat Redux (2023 WIP | 2600) by Ric Pryor @KaeruYojimbo Xanthoim 2600 (2023 | 2600) by MathanGames (WATCH AT 1080P60 FOR FULL QUALITY) 2 Quote Link to comment Share on other sites More sharing options...
vitoco Posted April 14 Share Posted April 14 It currently plays very well. Any chance to support CX20 driving controllers? Quote Link to comment Share on other sites More sharing options...
Thomas Jentzsch Posted April 14 Author Share Posted April 14 1 hour ago, vitoco said: It currently plays very well. Any chance to support CX20 driving controllers? Nope, the game won't work well with a DC. There are too many 360°+ turns and you need more precision than the DC can deliver. Quote Link to comment Share on other sites More sharing options...
Thomas Jentzsch Posted April 14 Author Share Posted April 14 13 hours ago, ZeroPage Homebrew said: ZeroPage Homebrew is playing Duet on tomorrow's ZPH stream LIVE on Twitch, hope you can join us! Thanks! But don't expect too much, there is still a lot work to do. 1 Quote Link to comment Share on other sites More sharing options...
+MarcoJ Posted April 16 Share Posted April 16 Is a good candidate for adapting to 2600. The radial positioning is quite smooth, seems like it has 32 positions. 1 Quote Link to comment Share on other sites More sharing options...
Thomas Jentzsch Posted April 16 Author Share Posted April 16 5 hours ago, MarcoJ said: Is a good candidate for adapting to 2600. The radial positioning is quite smooth, seems like it has 32 positions. 120 4 Quote Link to comment Share on other sites More sharing options...
+TrekMD Posted April 16 Share Posted April 16 This is not an easy game! Quote Link to comment Share on other sites More sharing options...
alex_79 Posted April 17 Share Posted April 17 On 4/14/2023 at 7:22 PM, Thomas Jentzsch said: Nope, the game won't work well with a DC. There are too many 360°+ turns and you need more precision than the DC can deliver. Did I hear Trackball? Quote Link to comment Share on other sites More sharing options...
+MarcoJ Posted April 17 Share Posted April 17 17 hours ago, Thomas Jentzsch said: 120 Wow, that’s some precision for the 2600. Quote Link to comment Share on other sites More sharing options...
Thomas Jentzsch Posted April 17 Author Share Posted April 17 (edited) 1 hour ago, alex_79 said: Did I hear Trackball? Nope. The game play relies on constant turning speeds. E.g. when there are multiple bars in a sequence, you just hold left (or right) permanently. That's because the dot rotation speed is in sync with the obstacle gaps and movement speed. With a trackball and its variable speeds, the game would become much harder. Edited April 17 by Thomas Jentzsch 1 Quote Link to comment Share on other sites More sharing options...
Thomas Jentzsch Posted April 17 Author Share Posted April 17 55 minutes ago, MarcoJ said: Wow, that’s some precision for the 2600. Maybe. To sync the rotation speed with the obstacle intervals (usually 60 pixel) easily, a multiple of 60 ist very helpful. That synchronization is very important for the game play. Using 120 positions avoids 2 pixel jumps in X direction. And it just requires two tables (for X and Y) with 30 bytes each only. Therefore it seems like the best solution. 5 Quote Link to comment Share on other sites More sharing options...
Thomas Jentzsch Posted June 26 Author Share Posted June 26 (edited) After the latest events, I decided to rename the game into Pas de Deux. Edited June 26 by Thomas Jentzsch 10 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.