+atari2600land Posted October 12, 2021 Share Posted October 12, 2021 I'm trying to use the exact same WORKING code I used in Peter the Pea here but I can't get it to work: The guy goes right into the walls. What is going on here? Why isn't it working? He is not supposed to be in the walls like this. savethepuppiesintellivision.bas Quote Link to comment Share on other sites More sharing options...
+atari2600land Posted October 12, 2021 Author Share Posted October 12, 2021 I screwed around with it and found backtab needed to be and #09f8 instead of #0ff8. It works now, but how? 1 Quote Link to comment Share on other sites More sharing options...
carlsson Posted October 12, 2021 Share Posted October 12, 2021 Did you shift from Color Stack mode to FG/BG mode? In the file constants.bas, you have CS_CARD_DATA_MASK = $07F8 and FGBG_CARD_DATA_MASK = $01F8. By converting those magical numbers to binary and comparing with the STIC, we find the following: Color Stack mode $0FF8 = 00 0 0 1 11111111 000 $07F8 = 00 0 0 0 11111111 000 The difference is that the value you used to use maintains the difference between GROM and GRAM. FG/BG mode $01F8 = 00 00 0 00 111111 000 $09F8 = 00 00 1 00 111111 000 Ditto, but notice that only 6 bits are used to point out which of the 64 GROM or GRAM cards. Two of the bits you accidentally masked with actually state the background colour. 1 Quote Link to comment Share on other sites More sharing options...
Zendocon Posted October 12, 2021 Share Posted October 12, 2021 4 hours ago, atari2600land said: I screwed around with it and found backtab needed to be and #09f8 instead of #0ff8. It works now, but how? I took the time to compile and run your code. Sorry I couldn't respond sooner, but I had to hunt down a copy of constants.bas. In Line 2, you're setting the graphics mode to Foreground/Background ("MODE 1"). Lines 92, 97, 102, and 107 are where you are calculating which card to look at based on player direction, as well as the bitmask to use. The reason why $9F8 is the bitmask you want is because you're disregarding two of the background color bits. Since your background color is white (color 7), those bits are raised. Therefore, the IF statement: IF #card = 319 * 8 THEN ... in each of the following lines would never evaluate to TRUE, because it would depend upon having a black background (color 0). (319 * 8, converted to Hexadecimal, equals $9F8.) Quote Link to comment Share on other sites More sharing options...
+atari2600land Posted October 12, 2021 Author Share Posted October 12, 2021 So the reason why it's $9F8 is because the background is white and not black? I've never run into this problem before. Quote Link to comment Share on other sites More sharing options...
carlsson Posted October 12, 2021 Share Posted October 12, 2021 (edited) No. The reason why it is $09F8 instead of $0FF8 is because you probably developed a game in CS mode before, but this one you're using FG/BG mode, much due to you are plotting a title screen. By the way, you don't need to put the (c) sign using #BACKTAB. You can PRINT such characters too: MODE 1:DEFINE 63,1,graph:WAIT PRINT AT 140 color $1202,"\319","2021 CHRIS" loop: GOTO loop graph: BITMAP "..****.." BITMAP ".*....*." BITMAP "*..***.*" BITMAP "*.*....*" BITMAP "*.*....*" BITMAP "*..***.*" BITMAP ".*....*." BITMAP "..****.." Edited October 12, 2021 by carlsson Quote Link to comment Share on other sites More sharing options...
+atari2600land Posted October 13, 2021 Author Share Posted October 13, 2021 OK, now I'm trying to make a puppy appear randomly inside the maze. I tried this: puppyx=rand(15)+1 puppyx=(puppyx*8)+8 puppyy=rand(10)+1 puppyy=(puppyy*8)+8 #card = #backtab((puppyy - 9) / 8 * 20 + (puppyx - 9) / 9) AND $09F8 doigetnewpuppy=0 IF #card = 319 * 8 THEN doigetnewpuppy=1 if prevpuppyx=puppyx and prevpuppyy=puppyy then doigetnewpuppy=1 (The dumb auto smiley face turns an 8 with a closed parenthesis into , so I changed it into 9 even though in the actual code it's an 8.) This works, but the puppy only appears at a couple of spots every time, whereas I want it to appear at any place where there is no wall. Quote Link to comment Share on other sites More sharing options...
+atari2600land Posted October 13, 2021 Author Share Posted October 13, 2021 I found this works. puppyx=(rand/16)+2 puppyx=(puppyx*8)+8 wait puppyy=(rand/32)+3 puppyy=(puppyy*8)+8 wait #card = #backtab((puppyy-8)/8*20 + (puppyx-8)/8) AND $09F8 doigetnewpuppy=0 IF #card = 319 * 8 THEN doigetnewpuppy=1 if prevpuppyx=puppyx and prevpuppyy=puppyy then doigetnewpuppy=1 Essentially, putting "wait" into it really helps. Quote Link to comment Share on other sites More sharing options...
carlsson Posted October 13, 2021 Share Posted October 13, 2021 Yes. The manual says that RAND and RAND(range) will generate a different number on each new frame, i.e. after a WAIT. You also have RANDOM(range) which is a little slower but doesn't require a new frame to get a new number. Also I suppose puppyx and puppyy are meant to be sprite coordinates. Perhaps skip multiplying by 8 and adding the offset before you have checked the BACKTAB to simplify calculations a bit. You can make the "card2sprite" calculations after you have checked the BACKTAB. Quote Link to comment Share on other sites More sharing options...
+atari2600land Posted October 13, 2021 Author Share Posted October 13, 2021 WHY DOES THIS HAVE TO BE SO HARD?! WHY DO I HAVE TO BE SO STUPID?! All I want to do is if the square is \319 make it \317 and if it is \317 then make it \319 at the push of a button. Something else I can't do. if cont.button and movetimer=0 then buttonpressed=1 #card = #backtab(cursory - 8 /8) * 20 + (cursorx - 8 /8) AND $09F8 if #card = 317*8 then print at ((cursory-8)/8)*20+(cursorx-8)/8 color #color1,"\319" : buttonpressed=2 if buttonpressed=1 and #card=319*8 then print at ((cursory-8)/8)*20+(cursorx-8)/8 color $2607,"\317" : buttonpressed=0 buttonpressed=0 end if This should work, but nooooooooo. savethepuppiesintellivision.bas Quote Link to comment Share on other sites More sharing options...
carlsson Posted October 13, 2021 Share Posted October 13, 2021 (edited) If you have the variables to spare, try to calculate the BACKTAB location once - not only in order to save code space and speed, but also to eliminate sources of error. I don't understand what buttonpressed is supposed to do, since #card only gets its value once. Untested, I wrote write the above code passage like this: IF CONT.BUTTON AND movetimer=0 THEN temp = ((cursory-8)/8)*20 + (cursorx-8)/8 #card = #BACKTAB(temp) AND $09F8 IF #card = 317*8 THEN PRINT AT temp COLOR #color1,"\319" IF #card = 319*8 THEN PRINT AT temp COLOR $2607,"\317" buttonpressed=0 END IF Edited October 13, 2021 by carlsson Quote Link to comment Share on other sites More sharing options...
+atari2600land Posted October 13, 2021 Author Share Posted October 13, 2021 That works, but why didn't my code? Buttonpressed was supposed to tell what the computer to do, like its status on card changing. I tried this on my LTO and the screen came up bare with no blocks. I had to modify the code a lot to make it so it displayed them. By the way, your code needed a thing to check to see if the key was being pressed. I put this in all my games: CheckforNOKeys: Procedure Rem this procedure is to make sure the key buffer is cleared so presses don't fall thru. clearloop: k=cont wait if k then goto clearloop wait end I don't know where it came from or who wrote it, but it works great. Quote Link to comment Share on other sites More sharing options...
+DZ-Jay Posted October 13, 2021 Share Posted October 13, 2021 (edited) 8 minutes ago, atari2600land said: That works, but why didn't my code? Buttonpressed was supposed to tell what the computer to do, like its status on card changing. I tried this on my LTO and the screen came up bare with no blocks. I had to modify the code a lot to make it so it displayed them. By the way, your code needed a thing to check to see if the key was being pressed. I put this in all my games: CheckforNOKeys: Procedure Rem this procedure is to make sure the key buffer is cleared so presses don't fall thru. clearloop: k=cont wait if k then goto clearloop wait end I don't know where it came from or who wrote it, but it works great. I believe this is your problem: #card = #backtab(cursory - 8 /8) * 20 + (cursorx - 8 /8) AND $09F8 You forgot the parentheses to surround "(cursory - 8)," which causes the division to be performed first. Division and multiplication have higher precedence than addition and subtraction, so your statement above is interpreted as this: #card = #backtab(cursory - (8/8)) * 20 + (cursorx - (8/8)) AND $09F8 Notice the "(8/8)" which evaluates to "1". -dZ. P.S. I want to make a suggestion, and I hope you do not take it in any negative way: It would perhaps be more profitable if you were to avoid venting your frustrations in your comments, for it may be turning off some people who may otherwise be willing to help. I know it can be frustrating when you encounter a problem, but the constant self-berating and exclamations about how hard it is or how incapable you are, is not really the best way to ask for assistance. Take this as you will, but it is intended as a friendly advice. Edited October 13, 2021 by DZ-Jay Quote Link to comment Share on other sites More sharing options...
carlsson Posted October 13, 2021 Share Posted October 13, 2021 (edited) Yeah, I never downloaded the full source code so I got a chance to evaluate it. Generally if you have a somewhat complex formula that you need to use twice or more, you benefit a lot from calculating it once and storing the result in a temporary variable. If nothing else, you only have one error source instead of three in your original code. As for waiting for a key and make sure it is released, I have begun to use this code: WHILE CONT=0:WEND WHILE CONT<>0:WEND Code example where you can test that it works for every key: MODE 1:WAIT i=240 loop: IF i>220 THEN FOR i=0 TO 11:PRINT AT i*20," ":NEXT i=0 END IF PRINT AT i,"PRESS A BUTTON" WHILE CONT=0:WEND WHILE CONT<>0:WEND i=i+20 GOTO loop It saves you a variable and no need (??) to wait for a new frame since you busy loop anyway. Edited October 13, 2021 by carlsson Quote Link to comment Share on other sites More sharing options...
+DZ-Jay Posted October 13, 2021 Share Posted October 13, 2021 (edited) 9 minutes ago, carlsson said: Yeah, I never downloaded the full source code so I got a chance to evaluate it. As for waiting for a key and make sure it is released, I have begun to use this code: WHILE CONT=0:WEND WHILE CONT<>0:WEND Code example where you can test that it works for every key: MODE 1:WAIT i=240 loop: IF i>220 THEN FOR i=0 TO 11:PRINT AT i*20," ":NEXT i=0 END IF PRINT AT i,"PRESS A BUTTON" WHILE CONT=0:WEND WHILE CONT<>0:WEND i=i+20 GOTO loop It saves you a variable and no need (??) to wait for a new frame since you busy loop anyway. I agree with that approach. In fact, I personally would encapsulate it in a subroutine so that it can be reused at any point. This is the code I typically have. '' ======================================================================== '' '' WaitForIdle '' '' Waits for the hand-controller to be completely idle. '' '' '' '' Input: '' '' None. '' '' '' '' Output: '' '' None. '' '' ======================================================================== '' WaitForIdle: Procedure Do : Loop Until (CONT = 0) Return End Notice that my loop is slightly different. This is because "Loop Until <test>" will fall-through when the test fails, branching back otherwise; whereas "while <test>" performs the test first and branches out on failure, but still branches back unconditionally at the bottom. The former generates slightly more efficient code. A "DEF FN" macro would be even faster, if you need that, but would generate bulkier code, since it would have to inject the code repeatedly on every use. My typical game loop then includes something like: MainLoop: Wait Gosub WaitForIdle Gosub DecodeInput ' ... Goto MainLoop -dZ. Edited October 13, 2021 by DZ-Jay 1 Quote Link to comment Share on other sites More sharing options...
+atari2600land Posted October 13, 2021 Author Share Posted October 13, 2021 OK. I'll quit venting my frustration. Sorry. Quote Link to comment Share on other sites More sharing options...
+DZ-Jay Posted October 13, 2021 Share Posted October 13, 2021 3 minutes ago, atari2600land said: OK. I'll quit venting my frustration. Sorry. No worries, mate. Just take it easy. At the end of the day, we're here to help. :) -dZ. Quote Link to comment Share on other sites More sharing options...
carlsson Posted October 13, 2021 Share Posted October 13, 2021 I suppose in this use case, one would want to read the controllers on the fly. If it was non-zero, you would store the input, wait for the key to be released and then move on. That can certainly be put in a subroutine, and the main program acts on whether the variable holding last keypress is set or not. The exact usage may vary depending on situation. Quote Link to comment Share on other sites More sharing options...
+DZ-Jay Posted October 13, 2021 Share Posted October 13, 2021 (edited) 40 minutes ago, carlsson said: I suppose in this use case, one would want to read the controllers on the fly. If it was non-zero, you would store the input, wait for the key to be released and then move on. That can certainly be put in a subroutine, and the main program acts on whether the variable holding last keypress is set or not. The exact usage may vary depending on situation. There are various use cases, one of them being "wait for the controller to be released, then return when any key is pressed." You could write code specifically for each use case, but you could also just generalize the functions for "wait for the controller to be released" and the "wait for any key." That way, depending on the use case, "wait for any key" could be replaced by "get disc input," or "decode full controller input," or "is button pressed?," etc. -- all of which could require a "wait for the controller to be released" first. In my experience so far, for most cases, this generalization should work and is practical -- especially for the kind of games that Chris typically makes*. Perhaps a highly complex game that maximizes hardware resources would require a more optimized approach in order to keep up with the speed of the game; but then, I would suspect that those are the kind of specialized games that require specialized solutions for many other things as well. From what I've seen of most IntyBASIC games that read the hand controller at 60 Hz, once per frame, calling a subroutine to do so is hardly the bottleneck choking point. -dZ. * Not to be taken as a slight at all. Edited October 13, 2021 by DZ-Jay Quote Link to comment Share on other sites More sharing options...
+atari2600land Posted October 13, 2021 Author Share Posted October 13, 2021 I guess I can share what I have now. This game is called "Save the Puppies!" This game has you going around collecting puppies that pop up on the screen. Eventually I will add enemies. I think I'm close to that point now. I have in sound effects and music. And a game editor that lets you build your own levels. To use the level editor, press 2 on the title screen. You can't move the cursor to the upper-left spot, that spot is reserved for your starting point. To put in a block, press a button and to erase a block, move the cursor to one and press a button again. When you're all ready to play your game with your level you created, press Enter and the game will start with your custom level. Thoughts? savethepuppiesintellivision.rom 1 Quote Link to comment Share on other sites More sharing options...
carlsson Posted October 13, 2021 Share Posted October 13, 2021 (edited) I suppose the ability to only move one card at a time is a decision, not a coding limitation? It works in emulation, but I don't know how it will work on real hardware pressing the disc, release, pressing it again in the same direction, release etc. Have you considered diagonal movement? With the above ROM, I'm getting a blank white screen plus a few slash characters to the right, so navigating to the puppy is only a matter of pressing and releasing the controller enough times. The level editor sounds nice, but I can't seem to place any blocks regardless which key I press except Enter that ends the editor. Edit: Also the player is able to escape the screen entirely, which may or may not be a game decision or I am missing something regarding boundaries. Edited October 13, 2021 by carlsson Quote Link to comment Share on other sites More sharing options...
+atari2600land Posted October 13, 2021 Author Share Posted October 13, 2021 I got it working on my real INTV II and LTO Flash, but I used a binary file with cfg. Does this work? And if so, how? savethepuppiesintellivision.bin savethepuppiesintellivision.cfg Quote Link to comment Share on other sites More sharing options...
carlsson Posted October 13, 2021 Share Posted October 13, 2021 (edited) Yes, much better. Now I get the level design and the slashes are replaced by a score counter. There must've been something weird happening with the bin2rom conversion, perhaps the JLP flag was omitted. It pretty much eliminates diagonal movement. Others would have to comment how playable it is to push the disc repeatedly. The editor is fine, perhaps a bit on the slow side so that you thought you moved the cursor and press the button, to get a block erased in the previous location instead of placed in the new one. If you want suggestions, you might want to consider a Pengo/Boulder Dash mechanic so the player can push blocks to the side, either to block or squish future enemies, of course avoiding squishing the puppy. Perhaps the enemies will throw a bone so the puppy runs after it, or they will simply steal the puppy. Edited October 13, 2021 by carlsson Quote Link to comment Share on other sites More sharing options...
+DZ-Jay Posted October 13, 2021 Share Posted October 13, 2021 (edited) 27 minutes ago, atari2600land said: I guess I can share what I have now. This game is called "Save the Puppies!" This game has you going around collecting puppies that pop up on the screen. Eventually I will add enemies. I think I'm close to that point now. I have in sound effects and music. And a game editor that lets you build your own levels. To use the level editor, press 2 on the title screen. You can't move the cursor to the upper-left spot, that spot is reserved for your starting point. To put in a block, press a button and to erase a block, move the cursor to one and press a button again. When you're all ready to play your game with your level you created, press Enter and the game will start with your custom level. Thoughts? savethepuppiesintellivision.rom 10.06 kB · 2 downloads Cute! It reminds me of another game ... It could use an octopus, though. A few suggestions: Do not force the player to release the disc in order to move; the avatar should continue to move for as long as the controller is pressed and there is a path. Try to force the re-spawn of the puppy farther away from the player. Right now, it seems rather common to get a new puppy right at my feet. On one occasion, I noticed that the "pick-up-puppy" ring sound effect went much too long, and then I realized that it was that the new puppy popped up right under my feet! Definitely needs some enemies. In the absence of enemies, it occurs to me that perhaps the puppy could move around, albeit slowly, while you attempt to find your way to it. After all, unleashed puppies seldom stay in one place. The level editor is very cool, but perhaps it should not allow me to fill the entire screen with blocks. Try to force at least two (I would suggest maybe more) contiguous empty spaces in the screen: (OMG! There are no puppies!) On that last item, you could do a final check before starting the game. Then, if an "invalid screen" is detected, a buzzer could play and abort. That way, you force the player to fix it before continuing. If you need help validating the screen let us know. I can think of some simple algorithms to do a check before exiting the editor. -dZ. Edited October 13, 2021 by DZ-Jay Quote Link to comment Share on other sites More sharing options...
+atari2600land Posted October 13, 2021 Author Share Posted October 13, 2021 I will be definitely adding in enemies. As for validating the edited level, I would like it to make sure that there is no space that the guy can't get to, like in the screenshot below. I'll try getting rid of the --jlp flag and see if that helps with the .ROM not working on LTO Flash. I wondered whether or not someone would try to do what DZ-Jay did. I thought the puppy would always show up at that spot and the game's score would keep going up and up (until an enemy is touched, once I add them in.) 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.