-
Content Count
5,587 -
Joined
-
Last visited
-
Days Won
2
Content Type
Profiles
Member Map
Forums
Blogs
Gallery
Calendar
Store
Everything posted by SeaGtGruff
-
What are these hotkeys in Stella? I've scoured through both documents (general and debugger), but can't find anything that mentions this feature in Stella. Michael Rideout
-
I did six "status bars" near the top of the following screen using missiles-- three copies of missile0, and three copies of missile1-- and then used color changes to COLUP0 and COLUP1 to get the levels for each bar, with each bar's level controlled by a variable. Michael Rideout
-
If you send me your name and email address in a private message, I will add you to the waiting list and then email you once more are available. Thanks! ..Al And I'd like to add, being put on the list doesn't lock you into buying one. Once a cart is available for you to buy, if you've decided by then that you don't want or can't afford one after all, there are other people who'll gladly scarf up the cart that "had your name on it." So if you're even slightly interested in buying one, it's far, far better to get onto the waiting list than not. Michael Rideout
-
There are (at least) two ways you could do this in bB. One way is to create your own kernel using inline assembly, without changing bB's "canned kernel"-- i.e., your custom kernel wouldn't replace the existing kernel, it would be a second kernel within the code. An advantage to doing this would be that the standard kernel would still be intact and available for use whenever you wanted to call it (using "drawscreen"). But some disadvantages are that the standard kernel would still be there taking up ROM space, so it would eat up more ROM to have a second kernel in the game; and also, your custom kernel might not have all of the features of the standard kernel, meaning there might be some things you wouldn't be able to use when calling your custom kernel. Another way is to create a modified version of the standard "canned kernel"-- an alternate version of the std_kernel.asm file-- and then include the alternate file in place of the standard file when you compile your program. An advantage of this is that you wouldn't need to have two kernels in ROM at the same time, thus saving some space. But a possible disadvantage is that the standard kernel was carefully written and I think the timing is tight, so adding the logic to use different background colors on alternating lines may mess up the kernel's timing. I'll have to experiment later with customizing the std_kernel.asm file, but it might take me several days before I can spend any decent amount of time on it. Michael Rideout
-
That's good to hear! We don't want you to get discouraged and quit, we want you to have fun making new games! I don't think I've seen any new posts from attendo in several months; I hope everything is okay with him. I was going to mention this last night in the thread about Ants!, but I got wrapped up in the problem with score. Yes, there are easier, better ways to draw and erase playfield displays. The method you're using looks like it was generated with the playfield editor in the 2600IDE program, which outputs a series of pfpixel statements based on which playfield blocks you click on, and in what order, including whether you turned a particular block on or off. That playfield editor tool is handy to use, and there can be benefits to using a series of pfpixel commands to turn specific playfield pixels on or off, but it isn't time-efficient or memory-efficient to draw an entire playfield that way. One alternative is to use the pfhline and pfvline commands to draw and/or erase horizontal and vertical lines of playfield pixels. For example, 250 pfpixel 21 1 on 252 pfpixel 22 1 on 254 pfpixel 23 1 on 256 pfpixel 24 1 on 257 pfpixel 25 1 on 258 pfpixel 26 1 on 259 pfpixel 27 1 on 260 pfpixel 28 1 on 262 pfpixel 29 1 on 264 pfpixel 21 2 on 266 pfpixel 21 3 on 267 pfpixel 20 4 on 268 pfpixel 19 4 on 269 pfpixel 18 4 on 270 pfpixel 17 4 on 271 pfpixel 16 4 on 272 pfpixel 15 4 on 273 pfpixel 14 4 on 274 pfpixel 13 4 on 275 pfpixel 12 4 on 276 pfpixel 11 4 on 277 pfpixel 11 5 on 280 pfpixel 11 6 on 281 pfpixel 10 7 on 282 pfpixel 9 7 on 283 pfpixel 8 7 on 284 pfpixel 7 7 on 285 pfpixel 6 7 on 286 pfpixel 5 7 on 287 pfpixel 4 7 on 288 pfpixel 3 7 on 289 pfpixel 2 7 on 290 pfpixel 1 7 on can be replaced with the following: 250 pfhline 22 1 29 on : rem horizontal line from (22,1) to (29,1) 260 pfvline 21 1 3 on : rem vertical line from (21,1) to (21,3) 270 pfhline 12 4 20 on : rem horizontal line from (12,4) to (20,4) 280 pfvline 11 4 6 on : rem vertical line from (11,4) to (11,6) 290 pfhline 1 7 10 on : rem horizontal line from (1,7) to (10,7) This is more memory-efficient than turning on the individual playfield pixels. For example, compiling the original program shows 1876 bytes free, but replacing lines 250 through 290 with the five lines above shows 2108 bytes free-- a savings of 232 bytes. And we haven't even replaced the other pfpixel statements yet, so you could save even more bytes. However, this still isn't nearly as time-efficient as it could be, since the pfhline and pfvline commands have to go through loops to turn a row of pixels on or off between a starting position and an ending position, and it's more time-efficient to control 8 pixels at a time by "poking" the playfield bytes. bB doesn't have a "poke" command, but you can set an entire playfield byte to a specific value. Last year I posted a few examples of how to draw an entire playfield using data statements to define the playfield's appearance, and a couple of routines to "poke" those values into the playfield bytes. I can post an example later of how you can use this to draw your Ants! title screen, or your platform game screen, but batari added a feature to bB version 0.99 which does the same thing-- only better-- if you're using the multisprite kernel, so you might want to use that method instead. Anyway, using the pfhline and pfvline commands is often the most memory-efficient way of drawing an entire screen, so I suggest you work with that method first. And if you need to clear the entire playfield, you can do it by turning off all of the playfield pixels using pfhline in a loop, as follows: 950 for a=0 to 10 : pfhline 0 a 31 off : next : rem clear rows 0 through 10, from (0,a) to (31,a) I'm attaching an updated version of your code, which replaces the pfpixel commands with pfhline and pfvline commands. When it's compiled, there are 2628 bytes free, so the savings is 752 bytes. Michael Rideout flanksteak1a.bas
-
Wow, I need to study a disassembly of Battlezone! Has anyone disassembled and commented it already? Michael Rideout
-
No, that isn't it, either. It looks like a bug. When I look at the compiled code, it looks very odd: .L013; if score[2] > 41 then COLUBK = 80 : COLUPF = 80 LDX #2 ; Huh? LDA 41,x ; What the... ? LDX #2 CMP score,x BCS .skipL013 LDA #80 STA COLUBK STA COLUPF .skipL013 .L014; if score[2] > 57 then COLUBK = 168 : COLUPF = 168 LDX #2 ; Weird... LDA 57,x ; Very weird! LDX #2 CMP score,x BCS .skipL014 LDA #168 STA COLUBK STA COLUPF .skipL014
-
Yipes, that was a typo, the last line should have been "if score[2]>73" (notice that you add 16 to the previous number-- 9, 9+16=25, 25+16=41, 41+16=57, 57+16=73, etc.). Sorry about that! Michael Rideout
-
By the way, you don't need to use line numbers with bB. And if you do use line numbers, they don't need to be in order, since they're actually interpreted as alphanumeric line labels. So you can take off all of the line numbers on lines you aren't branching to; and on lines where you need to branch to, you can use line labels instead. This may not seem like a big deal, especially if you're used to using line numbers, but using alphanumeric line labels can make it easier to understand a program-- at least, if you use line labels that explain what a routine is for, such as goto update_players_positions instead of goto 1500 Michael Rideout
-
I don't know, there is definitely something odd going on. I just read in the bug report thread that "score = value" displays a score of 70 (doesn't matter what you set "value" to), and I was playing around and saw that "score = a" compiles as "LDA #$049 : STA score+2", so somehow bB is interpreting "a" to be "#$049". Likewise, "b" is "#$050", "c" is "#$051", etc. Guess what "v" is? So bB is taking the first letter of the variable name ("value" or "v"), even if "dim value = a" defines "value" as the variable "a". On the other hand, "score = $11" correctly sets score+2 to #$11, but sets score+1 to #$0-12 (!). There's definitely something flakey going on, perhaps in the preprocessing before bB compiles it? Michael Rideout
-
160 x 192 is the resolution of a typical Atari 2600 game-- 160 color clocks horizontally, and 192 active (or picture) scan lines vertically. You can't do anything to increase the horizontal resolution of 160 color clocks, but you can increase the vertical resolution up to about 240 or so active scan lines (on an NTSC 2600, at least; on PAL and SECAM 2600s, you can even go a bit higher than that, since there are more scan lines on a PAL or SECAM TV screen). Michael Rideout Correction: On an NTSC 2600, you can get a vertical resolution of up to about 480 scan lines if you use an interlaced screen. Michael Rideout
-
Hmm, this looks like a bug in bB, or else I'm not understanding something that got changed from an earlier version? It looks like the hexadecimal values are possibly being misinterpreted as memory addresses(?) rather than as immediate values? If you convert the hexadecimal BCD values to their equivalent decimal values, and use the decimal values, it works as you intended: if score[2]>9 then COLUBK = 36 : COLUPF = 36 if score[2]>25 then COLUBK = 192 : COLUPF = 192 if score[2]>41 then COLUBK = 80 : COLUPF = 80 if score[2]>57 then COLUBK = 168 : COLUPF = 168 if score[2]>63 then COLUBK = 240 : COLUPF = 240 ($19 is hex for 25, $29 is hex for 41, $39 is hex for 57, and $49 is hex for 63.) Michael Rideout
-
I haven't read the posts or the code examples that you're referring to, so I'm not sure what they are talking about. But I do know that you need to combine coarse positioning with fine positioning to set a player's position to a specific desired horizontal location, so I'm going to guess that "standard X" is maybe referring to the X position on the screen, and the "FC_X" coordinates are the coarse and fine position values that will let you set the player to the given "standard X" position. The way the coarse/fine positioning works is something like this (I'll try to explain it so it's easy to understand, but no guarantees!): A given X position represents a particular color clock value on the scan line, since a color clock is the smallest pixel size on the 2600's screen. Actually, a color clock is a time unit-- the time it takes to draw the smallest possible pixel-- but we can think of it as a pixel position. Anyway, the Atari's color clock is 3 times faster than the 6502's machine clock-- i.e., 1 machine cycle equals 3 color clocks. Also, the shortest (quickest) possible 6502 instruction takes 2 machine cycles, or 6 color clocks. To set a player's horizontal position, you have to hit or strobe the RESPx register at the moment when the Atari has reached that position on the scan line. This is usually done by waiting in a loop for a certain number of times, as follows: LDX COARSE_VALUE LOOP DEX BNE LOOP STX RESP0 The DEX instruction takes 2 machine cycles, and taking a branch takes 3 machine cycles (as long as you don't cross a page boundary), so each time you go through the loop, you're waiting a total of 5 machine cycles, or 15 color clocks-- hence, when you hit RESP0 you are setting player 0's position to a coarse location, where each possible coarse location is 15 color clocks after the previous coarse location. Hence, you probably won't be setting the player to the exact X position you wanted; more likely, it will be some 7 or 8 color clocks to the left or right of the desired location. That's where the fine positioning comes into play. After you set the coarse position using RESPx, you set HMPx to a value that will shift the player to the left or right the necessary number of pixels, then you strobe WSYNC and HMOVE to fine-tune the player's position. Thus, for any given "standard X" position, you need to know how many times to wait in the loop before hitting RESPx for the coarse position, and you also need to know what value to store in HMPx to fine-tune the horizontal position. There are two ways you can convert the desired "standard X" position into the necessary coarse positioning value and fine positioning value. One way is to calculate the positioning values, such as by using a loop to convert the desired X position into a "mod 15" coarse value and a remainder. The other way is to use two lookup tables-- one for the coarse value, and one for the fine value. The calculation method takes fewer bytes but uses more cycles, whereas the lookup tables take more bytes but use fewer cycles, so which method you use can depend on whether it's more critical to save cycles or to save bytes. Once you know the coarse and fine values to use, you would do something like the following: LDX FINE_VALUE STX HMP0 LDX COARSE_VALUE LOOP DEX BNE LOOP STX RESP0 STX WSYNC STX HMOVE As I said, I'm not sure that this is what the posts and code examples were referring to, but it might be. Hopefully my brief explanation was clear enough so that you can reread those posts and code examples, and determine if that's what they're talking about! In any case, this type of positioning takes at least one scan line to do, or maybe two, since you must calculate or look up the coarse/fine values, set HMPx and the loop counter (X or Y register), wait in a loop, and hit RESPx on one line, then finish that line before you do the HMOVE, so you can't really display the player on that line (since it's being repositioned), then you can start displaying the player on the next line. If you aren't using the player for multiple sprites, you can just do the positioning during the vertical blank interval. Otherwise, you can reposition the player multiple times on the screen, as long as you leave at least one blank player line between the multiple sprites. And note that I didn't include clearing the player graphics register before setting the new position, or loading the player graphics after setting the new position, so don't forget to do that too. Michael Rideout
-
The key is to understand how binary coded decimal (BCD) numbers work. Basically, each nybble or half-byte can store a value from 0 to 15, so each nybble is used to store a digit from 0 to 9. The easiest way to refer to a specific BCD value is to use hexadecimal notation. Thus, if the score is 19, that means the byte at score[2] contains a hexadecimal value of $19 (i.e., the digit 1 is in the high nybble, and the digit 9 is in the low nybble). So to change the background color when the score goes from 2 to 3, and then again when it goes from 19 to 20, you can use the following lines: if score[2]>2 then COLUBK=64 : COLUPF = 64 if score[2]>$19 then COLUBK=34 : COLUPF = 34 Note that you could also write the first line as "if score[2]>$02". Michael Rideout
-
It's because this line doesn't work the way you think: if score>2 then COLUBK = 64 : COLUPF = 64 "score" is a 3-byte variable, with each nybble or half-byte representing a digit from 0 to 9 (i.e., it's in the BCD or "binary coded decimal" format). That's OK, but "if" can compare only 1-byte values, so when you say "if score>2" you are actually checking the byte which holds the two leftmost digits of the score. To do what you're trying to do, you need to make bB check the byte which holds the two rightmost digits of the score. Since the "score" variable is 3 bytes, you can refer to each byte using the array notation-- "score[0]" (or just "score") for the first byte, "score[1]" for the second byte, and "score[2]" for the third byte. Thus, if you change the line to the following, the background color will change as soon as the score increases from 2 points to 3 points: if score[2]>2 then COLUBK = 64 : COLUPF = 64 By the way, I see that you fixed the diagonal movement. Much nicer! Michael Rideout
-
160 x 192 is the resolution of a typical Atari 2600 game-- 160 color clocks horizontally, and 192 active (or picture) scan lines vertically. You can't do anything to increase the horizontal resolution of 160 color clocks, but you can increase the vertical resolution up to about 240 or so active scan lines (on an NTSC 2600, at least; on PAL and SECAM 2600s, you can even go a bit higher than that, since there are more scan lines on a PAL or SECAM TV screen). Michael Rideout
-
To be honest, not in its present form. For one thing, the joystick controls have some problems (e.g., try to move diagonally up and to the left), but those sorts of things are easy to fix. And I think the game would be more interesting if there were some kind of "obstacle course" that the player had to navigate through to reach the ants before they disappeared-- not necessarily a maze, but maybe at least some objects of some kind (e.g., plants, pebbles-- which would of course look like boulders from a bug's perspective-- or anything else the player has to move around). And you could have increasing difficulty levels, like at first the ants could be stationary, then they start moving around a little bit, then as the levels get higher they get a little faster each time. Also, the low levels could have no obstacles, then as the levels get higher, you could gradually add more obstacles, and even have some moving obstacles (like a slow-moving avalanche of pebbles, or something-- one pebble at first, then two, then three, etc., as the levels get higher and higher). Or you could have some other critter (e.g., a wasp?) that comes out every so often and tries to get you before you can get the ant. As far as the graphics, you could animate the ants and the player to make them more interesting. And you could change the colors every level or so to make things more interesting, or have different colored ants with different numbers of points based on their colors. Or maybe the ants could change color as the timer counts down (or up), to give the player a visual cue about how much time is left before the current ant disappears (or maybe it starts flashing a second or two before it disappears?). Also, the ants might be more interesting if they popped up out of the ground and then popped back down into the ground, instead of just appearing and disappearing all of a sudden. Maybe you could have several ant holes that are scattered around the screen-- they would stay in the same place during a given level, but they could change locations-- and maybe increase in number-- as you clear each level. And if the ants get to where they move around a bit, maybe they could pop up out of one hole, then move to another hole and crawl down into it, or something like that. Another idea is to maybe have some kind of "bonus round" every so many levels, like every fifth level or whatever. Anyway, the basic game idea-- catch the ants before they disappear-- definitely has potential, and you can do a lot with it if you let your imagination go wild, so don't think of your current version as a finished product. In the game industry (which I have never worked in, by the way, so I guess I don't really know what I'm talking about!), an important part of producing a game is to give it to play testers so they can find and report any problems that they run into (like the problem with moving diagonally), and to get feedback from people about what they like most about the game, what they don't like, what they think could be done to make the game more fun to play, etc. So I gave you some of my ideas, and hopefully other people will share their thoughts, then you can consider any ideas that people suggest, decide which ones (if any) you like, decide how to add them into your game, etc. After all, it's your game, and you have creative control over it! Best of luck with your game-- and most importantly, have fun making it! Michael Rideout
-
Oh Happy Day - First Step into Programming Worked
SeaGtGruff replied to yorgle's topic in 2600 Programming For Newbies
Yes, that's a good point. I had the same problem when I started learning Atari 2600 programming a couple of years ago! 2600IDE was created specifically for use with batari BASIC. Of course, that doesn't mean you can't use it for editing/compiling other languages-- like straight 6502/6507 assembly code-- but 2600IDE uses a batch that's geared toward compiling batari BASIC programs. Essentially, the batch passes the source code to batari BASIC first, which converts the batari BASIC code into assembly code, then the batch passes the assembly code to DASM, which assembles it into a ROM image. So I made a guess that perhaps "Bucket" is trying to use 2600IDE to compile straight assembly code, in which case the batch file is sending the code to batari BASIC first, which doesn't like the "processor 6502" command. If that's the case, then modifying the batch file so it bypasses batari BASIC, and just sends the source code directly to DASM for assembling, should do the trick. Michael Rideout -
Oh Happy Day - First Step into Programming Worked
SeaGtGruff replied to yorgle's topic in 2600 Programming For Newbies
If by "2600IDE" you mean the editor that "Attendo" (Jacco Mintjes) wrote for batari BASIC, you don't want to include a "processor 6502" line in your programs-- at least, not if you're compiling them with batari BASIC. If you want to use 2600IDE to edit, compile, and run programs for the 2600-- without using batari BASIC (i.e., in "pure assembly")-- then you will need to modify the "2600baside.bat" file that 2600IDE uses for compiling. Basically, you can edit the "2600baside.bat" file so it looks more or less like the following: dasm %1 -f3 -o%1.bin This assumes that the DASM assembler is in the current directory, so you might want to modify that command line for your particular setup. And if you change the "2600baside.bat" file that way so you can use 2600IDE to successfully edit/compile/run assembly code, then you'll no longer be able to compile batari BASIC programs with 2600IDE-- unless you set things up to let you run 2600IDE with one "2600baside.bat" file when you want to work in assembly, and with another "2600baside.bat" file when you want to work in batari BASIC. Michael Rideout -
How about this? Michael Rideout
-
Actually, that looks very good! But I would change the colors-- make the mug brown for the root beer, and make the head cream-colored for the foam. (Ice cream float, anyone?) The pink straw can stay pink! Michael Rideout
-
Sprite Help: How To Draw A Pouch
SeaGtGruff replied to RandomPerson's topic in Atari 2600 Programming
Beg pardon? Good job, ZylonBane, it looks better than my star did! Michael Rideout -
It looks like your problem is the ORG address at the end of the program. There are three vectors that go at the top (or end) of every program, but you actually only need the last two for the 2600. Anyway, most programs set all three vectors to point to the same location. They have to be put in addresses $FFFA/$FFFB, $FFFC/$FFFD, and $FFFE/$FFFF. In your code, they're in the wrong places: 2808 ffcb ORG $ffcb 2809 ffcb ff ff 00 f0* .word.w $FFFF,$F000,StartGame,$F000 2810 ffd3 2811 ffd3 If you change that last ORG to "ORG $FFF8" (since you have four words there, instead of three, so the first word should be in $FFF8/$FFF9), the code should start up correctly. Michael Rideout
-
The BJARS link I gave does contain the source-- I think. If not, I have the source for 2.7, which was zipped up together with the program when John sent it to me. I never could get 2.7 to work on my new PC (Windows Media Center, dual-core processor, if that has anything to do with anything), but it seemed to work just fine on my old PC. Michael Rideout
-
I don't think six is too high. Once you get past 200,000 or 300,000, there is so much going on that sometimes one of the sprites will pause! For example, a mosquito will be zig-zagging down the screen and then stop where it is, in mid-flight, then after after a while (possibly after some of the other sprites move offscreen), it will resume its flight. This has got to be one of my all-time favorite 2600 games. I love it at the higher levels when the pace is so intense (which just makes it all the more exciting when you just barely avoid colliding with something), and I especially love the bonus(?) rounds when all of the different kinds of bugs start falling like crazy-- you can really rack up the points, possibly earning two extra lives in one bonus round! The sound effects are great, too. Michael Rideout
