Jump to content

juanitogan

Members
  • Content Count

    42
  • Joined

  • Last visited

Community Reputation

29 Excellent

About juanitogan

  • Rank
    Space Invader

Profile Information

  • Custom Status
    Daring Greatly
  • Gender
    Male
  • Location
    Earth, most of the time, maybe in NM
  • Interests
    2600, Lynx

Recent Profile Visitors

2,985 profile views
  1. Looks good to me. One thing I would change is that the example code needs a header. Otherwise, the code looks like it applies to the quirk when it really applies to the whole chapter. Perhaps me starting it with the missile code was misleading (the missile was just the object that got to the point the quickest). Thus, I guess I can help out the reader a bit more with a couple more changes. I added a couple sentences to the quirk section: And, here's a better block of example code with some updated comments: INX ; 2 x = 0! (player jet) ... LDY playerX ; 3 y = player's x-pos ... TYA ; 2 a = y JSR SetPosX ; 6 x-position player jet INX ; 2 x = 1 (enemy object) ... INX ; 2 x = 2 (player missile) LDA missileX ; 3 a = missile's x-pos JSR SetPosX ; 6 x-position missile JSR DoHMove ; 6 do HMOVE ... SetPosX SUBROUTINE ; calculates the values and positions objects: ; INPUT: ; A = x-position ; X = object to position (0=P0, 1=P1, 2=M0, 3=M1, 4=BL) JSR CalcPosX ; 6 $FAEF SetPosX2: STA HMP0,X ; 4 fine position the object specified in X INY ; 2 get past the 68 pixels of horizontal blank INY ; 2 INY ; 2 STA WSYNC ; 3 wait for sync; wait for TIA to finish line .waitPos: DEY ; 2 BPL .waitPos ; 2/3 5-cycle loop = 15 TIA color clocks (pixels) STA RESP0,X ; 4 RTS ; 6 ... CalcPosX SUBROUTINE ; calculates values for fine x-positioning: ; ; Basically, divides pos by 15 and stores the int result of that. ; Then, the mod of that is adjusted to equal 6 + HMP1. ; HMPx bits 4..7: Offset value: ; 0000 ($00): No offset ; 0001 ($10): Left 1 clock ; 0010 ($20): Left 2 clocks ; 0011 ($30): Left 3 clocks ; 0100 ($40): Left 4 clocks ; 0101 ($50): Left 5 clocks ; 0110 ($60): Left 6 clocks ; 0111 ($70): Left 7 clocks ; 1000 ($80): Right 8 clocks ; 1001 ($90): Right 7 clocks ; 1010 ($A0): Right 6 clocks ; 1011 ($B0): Right 5 clocks ; 1100 ($C0): Right 4 clocks ; 1101 ($D0): Right 3 clocks ; 1110 ($E0): Right 2 clocks ; 1111 ($F0): Right 1 clock ; ; INPUT: ; A = x-position ; RETURN: ; Y = coarse value for delay loop (shifted to lower 4 bits), 1 loop = 5 clocks = 15 pixels ; A = fine value for HMPx, HMMx, or HMBL TAY ; 2 $FDD8 Y = A INY ; 2 Y++ (setup for div 15; causes 15 to overflow) TYA ; 2 A = Y AND #$0F ; 2 A chopped to lower 4 bits 00001111 (fine pos value + 1) STA temp2 ; 3 $ED temp2 = A (fine pos value + 1) TYA ; 2 A = Y LSR ; 2 A chopped to upper 4 bits and shifted to lower 4 bits (A div 16) LSR ; 2 LSR ; 2 LSR ; 2 TAY ; 2 Y = A, backup shifted bits to Y CLC ; 2 CF = 0 ADC temp2 ; 3 A = A + temp2 (shifted bits added to change this from div 16 to div 15) CMP #15 ; 2 is A < 15? (look for div 15 overflow) BCC .skipIny ; 2 yes, skip to EOR (no div 15 overflow) SBC #15 ; 2 no, A = A - 15 (CF = 1 but not needed here) INY ; 2 Y++ (yes on the div 15 overflow so one-up Y) .skipIny: EOR #$07 ; 2 A = A XOR 00000111, 7's complement, sets offset for 6 + HMPx ; NOTE: Any JSR here will use 20 cycles instead of 8 ; but saves 1 byte of code overall (3 bytes instead of 4). Mult16: ASL ; 2 A's lower 4 bits shifted to upper 4 ASL ; 2 ASL ; 2 ASL ; 2 Wait12: RTS ; 6 ... DoHMove: STA WSYNC ; 3 wait for sync; wait for TIA to finish line STA HMOVE ; 3 must follow WSYNC if horizontal motion desired RTS ; 6
  2. Primary credit, of course, goes to Wright for the parts of his book I excerpted. A thank-you line, however, would be cool (I take care to give out thank yous to contributors on my sites as well -- it's the right thing to do). So, maybe something like "Thank you to Matt Jernigan for compiling and contributing this." And, yes, that's my real name there. I should also clarify, concerning the River Raid code, that JTZ is Thomas Jentzsch (he uses both his name and JTZ in the code). I began with his commented code and then added a lot to it as I worked through my River Raid port (which I will publish on my River Raid Squadron page at some point). Nearly all the comments in the example code here are mine, but I wouldn't have gotten here without him. All of this intel, actually, was gathered during that port work. It was running into that quirk that led to so many comments on the HMPx stuff before I finally figured out something else must be going on that affects fine positioning. Thus, it was time to put it all together in one place and share.
  3. Happy to. ... To me, at least, it looks like another page since I made no attempt to make it look like Davie's work. It's just some intel I scraped together that I didn't want to lose for if and when I need it.
  4. For those looking for the missing part 2, here is my interpretation of what it was set to cover (more or less). This is taken from the Stella Programmer's Guide by Steve Wright 12/03/79. Session 22: Sprites, Horizontal Positioning (Part 2) Fine Tuning Horizontal Position Horizontal Motion Registers 20 HMP0 1 1 1 1 . . . . horizontal motion player 0 21 HMP1 1 1 1 1 . . . . horizontal motion player 1 22 HMM0 1 1 1 1 . . . . horizontal motion missile 0 23 HMM1 1 1 1 1 . . . . horizontal motion missile 1 24 HMBL 1 1 1 1 . . . . horizontal motion ball 8.0 Horizontal Motion Horizontal motion allows the programmer to move any of the 5 graphics objects relative to their current horizontal position. Each object has a 4 bit horizontal motion register (HMP0, HMP1, HMM0, HMM1, HMBL) that can be loaded with a value in the range of +7 to -8 (negative values are expressed in two's complement from). This motion is not executed until the HMOVE register is written to, at which time all motion registers move their respective objects. Objects can be moved repeatedly by simply executing HMOVE. Any object that is not to move must have a 0 in its motion register. With the horizontal positioning command confined to positioning objects at 15 color clock intervals, the motion registers fills in the gaps by moving objects +7 to -8 color clocks. Objects can not be placed at any color clock position across the screen. All 5 motion registers can be set to zero simultaneously by writing to the horizontal motion clear register (HMCLR). There are timing constraints for the HMOVE command. The HMOVE command must immediately follow a WSYNC (Wait for SYNC) to insure the HMOVE operation occurs during horizontal blanking. This is to allow sufficient time for the motion registers to do their thing before the electron beam starts drawing the next scan line. Also, for mysterious internal hardware considerations, the motion registers should not be modified for at least 24 machine cycles after an HMOVE command. HMP0 (HMP1, HMM0, HMM1, HMBL) These addresses write data (horizontal motion values) into the horizontal motion registers. These registers will cause horizontal motion only when commanded to do so by the horiz. move command HMOVE. The motion values are coded as shown below : D7 D6 D5 D4 Clocks Effect 0 1 1 1 +7 Move left indicated number of clocks 0 1 1 0 +6 0 1 0 1 +5 0 1 0 0 +4 0 0 1 1 +3 0 0 1 0 +2 0 0 0 1 +1 0 0 0 0 0 No Motion 1 1 1 1 -1 Move right indicated number of clocks 1 1 1 0 -2 1 1 0 1 -3 1 1 0 0 -4 1 0 1 1 -5 1 0 1 0 -6 1 0 0 1 -7 1 0 0 0 -8 WARNING : These motion registers should not be modified during the 24 computer cycles immediately following an HMOVE command. Unpredictable motion values may result. Undocumented Quirk Not all objects position exactly the same. Double- and quad-wide player sprites shift +1 color clock. Missiles and the ball shift -1 color clock. This is discussed here: Example code from River Raid (comments from myself and JTZ) ; x-position missile: LDA missileX ; 3 JSR SetPosX ; 6 position missile JSR DoHMove ; 6 do HMOVE ... SetPosX SUBROUTINE ; calculates the values and positions objects: JSR CalcPosX ; 6 $FAEF SetPosX2: STA HMP0,X ; 4 fine position player, missile, or ball, depending on value of X INY ; 2 get past the 68 pixels of horizontal blank INY ; 2 INY ; 2 STA WSYNC ; 3 wait for sync; wait for TIA to finish line .waitPos: DEY ; 2 BPL .waitPos ; 2/3 5-cycle loop = 15 TIA color clocks (pixels) STA RESP0,X ; 4 RTS ; 6 ... CalcPosX SUBROUTINE ; calculates values for x-positioning: ; Basically, divides pos by 15 and stores the int result of that. ; Then, the mod of that is adjusted to equal 6 + HMP1. ; HMPx bits 4..7: Offset value: ; 0000 ($00): No offset ; 0001 ($10): Left 1 clock ; 0010 ($20): Left 2 clock ; 0011 ($30): Left 3 clock ; 0100 ($40): Left 4 clock ; 0101 ($50): Left 5 clock ; 0110 ($60): Left 6 clock ; 0111 ($70): Left 7 clock ; 1000 ($80): Right 8 clock ; 1001 ($90): Right 7 clock ; 1010 ($A0): Right 6 clock ; 1011 ($B0): Right 5 clock ; 1100 ($C0): Right 4 clock ; 1101 ($D0): Right 3 clock ; 1110 ($E0): Right 2 clock ; 1111 ($F0): Right 1 clock ; ; INPUT: ; A = x-position ; RETURN: ; Y = coarse value for delay loop (shifted to lower 4 bits), 1 loop = 5 clocks = 15 pixels ; A = fine value for HMPx, HMMx, or HMBL TAY ; 2 $FDD8 Y = A INY ; 2 Y++ (setup for div 15; causes 15 to overflow) TYA ; 2 A = Y AND #$0F ; 2 A chopped to lower 4 bits 00001111 (fine pos value + 1) STA temp2 ; 3 $ED temp2 = A (fine pos value + 1) TYA ; 2 A = Y LSR ; 2 A chopped to upper 4 bits and shifted to lower 4 bits (A div 16) LSR ; 2 LSR ; 2 LSR ; 2 TAY ; 2 Y = A, backup shifted bits to Y CLC ; 2 CF = 0 ADC temp2 ; 3 A = A + temp2 (shifted bits added to change this from div 16 to div 15) CMP #15 ; 2 is A < 15? (look for div 15 overflow) BCC .skipIny ; 2 yes, skip to EOR (no div 15 overflow) SBC #15 ; 2 no, A = A - 15 (CF = 1 but not needed here) INY ; 2 Y++ (yes on the div 15 overflow so one-up Y) .skipIny: EOR #$07 ; 2 A = A XOR 00000111, 7's complement, sets offset for 6 + HMPx ; CAUTION: Any JSR here will use 20 cycles instead of 8 ; to save 1 byte (3 bytes instead of 4)! Mult16: ASL ; 2 A's lower 4 bits shifted to upper 4 ASL ; 2 ASL ; 2 ASL ; 2 Wait12: RTS ; 6 ... DoHMove: STA WSYNC ; 3 wait for sync; wait for TIA to finish line STA HMOVE ; 3 must follow WSYNC if horizontal motion desired RTS ; 6 Other Algorithms Hopefully, after this, Session 24 will make more sense, which discusses other algorithms for horizontal positioning.
  5. Precisely why I tried to be clear up front (and regret missing a couple points I intended to make in that first post). I generally classify such people as tinkerers. I learned to not be a tinkerer long ago. My life since has been publish, publish, publish, regardless or how perfect or polished it is. I set a minimum viable product (MVP) point and stick with it. Polish can come later if interest drives you in that direction. I feel you learn more by publishing MVPs than just endlessly tinkering. I generally don't publish early WIPs because they don't guarantee much. On the other hand, people need a place to find motivation for finishing work that can be a drag at times. Motivation and momentum are the primary reasons I'm an active member with the local game-dev guild. I doubt it means anything to anyone beside me but I leave remarks in my code about the 7800 port where needed. Some parts look funny with too many steps to make the port back to assembler easier. Thus, to me, this is clearly a 7800 WIP even though nobody else seems to be seeing it that way. A significant assembler code base from the 2600 and assets built to the 7800 palette somehow doesn't qualify as 7800 WIP yet just because I've been transparent about the uncertainty of finishing it and am alpha testing on a PC. This makes no sense to me. It sounds a lot like something else.
  6. Back to a point that @Trebor brought up. If I do choose to launch the 7800 port, odds are pretty good I'll finish it. That's just who I am. I've proven that time enough. Thus, the real question is if I'll choose to launch the 7800 port. It's too early go guess on that. Thus far, traffic is good on itch.io, so the odds look a bit better than "extremely low." If, however, this community chooses to stamp down any support for my way of building games, well, that's on you. I tried. That's more than most can claim. "Few men are willing to brave the disapproval of their fellows -- the censure of their colleagues -- the wrath of their society. Moral courage is a rarer commodity than bravery in battle or great intelligence. Yet, it is the one essential, vital quality for those who seek to change the world which yields most painfully to change."
  7. Hi, @Greg2600 Thanks for asking. It was about feasibility testing. I chose the tools where I believed I could test the idea the quickest. Part of that plan proved out well, parts did not. It's also about iteration. Where am I going to experience the least iteration fatigue in order to develop the best possible product? Games aren't like a business app where I can pretty solidly predict what works well and what doesn't. People's emotions during gaming are much more finicky. Tuning both game mechanics and art takes a lot of back-and-forth work where I often dump my best plans. (I've played plenty of homebrew games that obviously don't take this work to the level I like to. Why is that? Maybe it's fatigue with unwieldy tools.) I don't have anyone paying me to grind through that in difficult tools on projects that I have no stake in if they don't see the light of day, so I have to be smarter about it to keep my dev time down and projects focused. Anyhow, after that initial feasibility testing, it was easy enough to just finish the rest of the testing and tuning in the tools where I had started. It really is that much easier. So, now, apparently, I am faced with a community that somehow doesn't find this to be a valid path towards developing a 7800 game because I've diverged away from the blessed tools in order to save time. Yes, the 7800 port will be hard (and could be easier if there was a C compiler for it). But, it will also be fairly straight forward because I now have well-documented 2600 code to draw from and a solid end goal. I have, so far, produced a better game this way than I would have the sanctified way. If people are upset because it is not "7800 first," well, okay. I can live with that. I can't please everyone.
  8. @Trebor That would be a fair summary. Although, I would like to clarify that there is no expectation of financial contribution anywhere. That was just me ranting about the impossibility of expectations around free software and how free is never free enough to some. I run into this a lot and so I tend to rant about it. If people want free faster, or to a deadline, throw some money at those working on it. In the mean time, I don't care to give any false hopes about how quickly a 7800 port may or may not arrive. I still have more prototyping to do before I can think about that. So, yes, don't set any false expectations. I would appreciate that. I need first figure out if this game is worthy or not by finding testers.
  9. Thanks. It's an interesting hack that I think I've seen before, but don't quite remember for sure. For me, anyway, such hacks don't make a better game even though they can be terribly interesting to dig through. I prefer very few but well-tuned options.
  10. It is a beautiful jet. Personally, I think the P-51 Mustang is one of the greatest works of art in the world... but it's not a jet so it doesn't qualify in this topic. I'm not sure which jet I might call the most beautiful. Probably one from the pre-CAD era. Could be this one. BTW, this is the 13-color version. I've been debating going to 25 colors with it.
  11. @Shawn and @Trebor bring up valid questions that need to be discussed more. I tried to be clear up front as to what is going on here. I wrote the first post in some haste thinking I could edit it later if needed. Nope. That edit period is good for only an hour. I do explain things better in my devlog but: Who reads those? It's hard to say everything that needs to be said all at once in just a few sentences, so I'm happy to answer things here. Yes, this is just a PC game at the moment. As to what I can call a prototype, I find it pretty harsh to say this has "nothing to do with the 7800 at all" but, fair enough, I suppose. You can call it what you want. To me, however, it has quite a bit to do with the 7800. In my world we often prototype in tools we don't deploy in. Furthermore, if I was prototyping just the art, for example, in just Aseprite (like I do), nobody seems to be arguing that as valid prototyping even though it's a modern tool used for all sorts of modern games. Perhaps I should go back to graph paper and flipping bits. So, why should code have any more restrictions than art or sfx? I get it, however, its about trust and it's harder to trust that I'm using a modern engine to prototype what can be built on a 7800 because you can't just glance it and know as instantly as you can a sprite. Trust, really, is the primary difference between playing a PC build of this and playing a bin in an emu on a PC. Prototypes in other tools typically don't make it all the way to full functionality. If they do, then either something happened on the way to the forum, or you're building some sort of simulator or emulator... which, well, maybe sim would be a more correct term at this point. That wasn't the original intent, however. I can't say at what point this changed from just a test of the co-op changes, to a test of the whole cart. Or, if I always meant that. If it changed, it changed for various reasons that are hard to nail down. But, because it maybe changed, does that make it any less valid as a proto? Determining level scroll speed, for example, from two player jets traveling at different speeds, was a hard algorithm to work out. So what?, if I chose to work such things out in a different language before going to assembler with it? I work where I can iterate the fastest. If someone sees something in the PC builds that's not possible on the 7800, I want to know about it. That's why I'm here. It's why I call it a prototype. It's not like I haven't read the programming specs of the 7800. I have. I've already been clear about the fuzzy areas, such as how I may or may not succeed at texturing the dark-green jagged levels. I can't say I might prototype every 7800 game I might make like this. But, it is still likely I might for some. Consoles often come with devkits hooked up to other computers. For me, in this case, that devkit happens to be a modern engine, to a degree. Like I said up top, I can't say that was the smartest choice for this project, but it hasn't been a terrible choice either considering the rapid tuning I've gotten out of it. The final product will likely be a much better-looking and better-tuned game because of it. I "get" that many would consider me more cool if I went old school for every step of the project. I'm not the type to care about such things even though I like old consoles. I've had enough of difficult tools to last a lifetime. I just like to build and I like to do it my way. Whatever gets me there the fastest. So, partly because of the VCS, partly because of pitches to publishers, partly because of the timeline I talked about in my devlog, I chose to push this into a Linux release sooner than expected. It was that or wait maybe another 2 and a half years for the 7800 bin. Maybe publishing what I have now will help that along quicker. That's my hope anyway. Maybe I'll even find a few new RR fans along the way. I don't mean to sound annoyed by this -- I apologize if I do -- I just like to be precise in my answers and I don't always take extra color in the commentary very well. I do, however, believe it is correct to question me on all of this. As to whether or not there will definitely be a 7800 port of this game? All I can say is, that is the intent. I'm not, however, one to make promises that I have no idea if I can keep. And, I like to be transparent about that. Currently, I have no timeline planned for the 7800 port. It will happen when it happens. As to how I might quantify enough interest? I can't say I know how to do that. I'm sure it fluctuates. I'll know it when I see it. Perhaps at the top of that list is whether or not someone is willing to publish this in cart form. Without rights to the trademarks, I make no assumptions there -- no matter how many Pac-Man spinoffs I see in the store here (and, I must add that Pac-Mac 4K is super-impressive work). Other than that, I'm probably just looking for signs as to whether or not people are enjoying this variant of RR. If people just want another cart to add to their library, I'm not interested. I like to spend my time looking for new gameplay that makes people happy. So, yeah, if nobody downloads my game and/or gives me any play reports, there's no point in taking this further. On the flip side of that is, if people DL it and start throwing support at my other projects (the ones that allow contributions) asking for more co-op mods then, yeah, I'll try to get this out by the end of the year. That's beyond unlikely, however. If I could make a living writing new games and mods for 2600, 7800, and Lynx, I totally would. Who wouldn't? Has anybody figured the magic of that out? No. Currently, I contract part time and work on GRITS Racing part time. Thus, River Raid Squadron (and other personal projects) only see advances on the occasional Sunday afternoon (except in rare cases like the last two weeks).
  12. @ZylonBane Yes. I explain this more in my devlog but, in short, I wasn't interested in the other changes that came with those ports. If nothing else, my explosions are much more satisfying than any of those. The graphics, however, are not the main point of this project.
  13. For anyone who likes to read such things, I finally finished writing my devlog post telling the storied tale of how this game came to be. How ‘River Raid Squadron’ Came to Be... Eventually Hardcover due out after I max out the score on either River Raid or River Raid Squadron, whichever comes first.
  14. I suspect my original plan was to fuel balance at the same rate as the fuel ups. Game design is an iterative process, however, where you sometimes build the quickest route to testing something else, and then you're like "Huh? I wonder how this feels? Maybe I don't need to go further." Anyhow, I often tune such things after watching other players. It could be that instant works well for Easy Lives and slow works well for Hard Lives, or none of the above. I haven't actually played this game yet with anyone (such is the world these days) so it's hard for me to guess this one right. I'm gonna have to rely on you all to test the Windows or Linux builds to tell me what you think. And then find a good compromise.
×
×
  • Create New...