Jump to content

SeaGtGruff

Members
  • Posts

    5,591
  • Joined

  • Last visited

  • Days Won

    2

Blog Comments posted by SeaGtGruff

  1. Just a few that I have, which you didn't already mention:

     

    Colony 7

    Melbourne Tatty

    Gingerbread Man

     

    I have several others you didn't mention, but I can't put my hands on them right now because they're hiding somewhere in a stack of boxes-- Crazy Balloon (did I get the name right?), Hunchy 2(?), Skeleton+, a puzzle game (I can't remember the name right now), and others. There are *many* excellent homebrews to choose from! :) And if you happen to have a 7800, don't overlook the 7800 homebrews.

     

    Michael

  2. -> COLUP0 must be set every frame. The kernel resets it to black during drawscreen.

    Actually, the kernel sets COLUP0 and COLUP1 to the scorecolor when it draws the score, so if you don't set them during every frame in the standard kernel, your player0 and player1 sprites will change to the scorecolor.

     

    On the other hand, the multisprite kernel needs to use RAM to save the colors of player1 through player5, since they're all drawn with GRP1 and COLUP1, therefore it's able to remember what color to make them each time the frame is drawn. But since GRP0 isn't multiplexed (correct terminology?) the way GRP1 is, there's no separate RAM location for saving the color of player0, therefore the kernel can't remember what color to make it each time the frame is drawn; so it "inherits" the scorecolor, since that's the last color that COLUP0 is set to on each frame.

     

    Aside from just setting COLUP0 during each frame (along with COLUP1 if you're using the standard kernel), a way to "correct" this behavior is to use one (or two) user variables for storing the color of player0 (and player1), and then use a vblank routine to automatically load the color into COLUP0 (and COLUP1) at the top of each frame. This would use up precious RAM, but it would save a few cycles during the overscan period. Or, you could just load a numeric literal into COLUP0 (and COLUP1) during a vblank routine, so that no RAM would need to be used; and if COLUP0 (and COLUP1) might vary depending on the situation, then you could use "if" or "on...goto" statements during the vblank to pick the correct color.

     

    ------> What is the default value for pfheight?

    If you omit the "setheight" statement, it appears to default to 15 (16 double-lines), which gives 5.5 playfield pixels. But I'm not sure if this is always the case, or if it can vary depending on any factors.

     

    ------> The screenheights of 80 and 84 only work with some pfheights all 7 or less, but pfheight can be 15 and 31. What are the legal screenheights for those values. A table of legal combinations of screenheight and pfheight would make things more clear and complete.

    The documentation says that screenheight can be only 80 or 84, and that 80 works only if pfheight is less than 8, but 84 works only if pfheight is less than 4. So the legal combinations should be as follows:

     

    +-------+-------+-------+-------+
    |-------| sh.88 | sh.84 | sh.80 |
    +-------+-------+-------+-------+
    | ph. 0 | valid | valid | valid |
    +-------+-------+-------+-------+
    | ph. 1 | valid | valid | valid |
    +-------+-------+-------+-------+
    | ph. 3 | valid | valid | valid |
    +-------+-------+-------+-------+
    | ph. 7 | valid |invalid| valid |
    +-------+-------+-------+-------+
    | ph.15 | valid |invalid|invalid|
    +-------+-------+-------+-------+
    | ph.31 | valid |invalid|invalid|
    +-------+-------+-------+-------+

    Note that 88 isn't a "legal" value for screenheight, but it's the default number of lines on the screen (if we exclude the score). However, you *can* set screenheight to 88, but you get the same result as if you'd set screenheight to 80-- for the most part. I defined 88 rows of playfield pixels, then tried all the combinations of pfheight and screenheight, and this is what I got:

     

    +--------+------+------+------+------+
    |--------|------| s.88 | s.84 | s.80 |
    +--------+------+------+------+------+
    | pfh. 0 | 88 r*| 80 r | 84 r*| 80 r*|
    +--------+------+------+------+------+
    | pfh. 1 | 44 r | 40 r | 42 r | 40 r |
    +--------+------+------+------+------+
    | pfh. 3 | 22 r | 20 r | 21 r | 20 r |
    +--------+------+------+------+------+
    | pfh. 7 | 11 r | 10 r | 10.5 | 10 r |
    +--------+------+------+------+------+
    | pfh.15 | 5.5r | X ***| X ***| X ***|
    +--------+------+------+------+------+
    | pfh.31 | 1 r**| X ***| 1 r**| X ***|
    +--------+------+------+------+------+

    The second column (with no screenheight shown) is where I didn't set the screenheight constant, so that the screen was the default height.

     

    The third column shows where I set the screenheight constant to 88, even though that isn't supposed to be a valid value (but I wanted to try it anyway, since 88 is the default screen height). As you can see, it gave the same results as setting screenheight to 80, but with one interesting exception. In all cases where pfheights was set to 0, the last pfrow on the screen was the same as the one above, as if the next-to-last pfrow was stretched twice as high as the other pfrows. *But*, when I set screenheight to 88, I got the same number of lines as if I'd set screenheight to 80, except the last pfrow was correct!

     

    In the boxes that say "1 r**," I got only 1 tall (32-line high) pfrow as indicated, except the rest of the screen was chopped off-- the single pfrow was followed by the score, and then by a huge overscan.

     

    In the boxes that say "X ***," the screen rolled like crazy.

     

    So my testing results don't quite jive with the "valid/invalid" chart given above. The "valid/invalid" chart is correct for screenheight 80, but pfheight 7 is actually valid (if weird) for screenheight 84. It's debatable whether pfheight 31 is valid with screenheight 84, since the screen is way too short. And it's debatable whether pfheight 31 is valid when no screenheight is specified (meaning it should default to 88), for the same reason.

     

    Michael

  3. Recommendations for improving bBasic:

    -> The language really needs an ON...GOSUB statement in addition to the ON...GOTO. I was forced to use a clumsy system of gotos to get back to the mainloop of code from the frame setup routines. The resulting code is brittle and harder to read. Plus I can't reuse my frame routines in a different on...goto statement.

    I think Fred/batari is going to have "on...gosub" in the next version, because it turns out that it's easy to implement. However, in the meantime there *is* a way to reuse your routines in other "on...goto" statements. First, put your "on...goto" statements in their own subroutines, so you can "gosub" to the one you want. But you do *not* need to put a "return" after each "on...goto" statement. (On the other hand, putting a "return" after each one *would* keep you from falling through if none of the "goto" branches are taken.) Then end each *frame* subroutine with "return":

     

       rem * Example 1
    loop
      rem * some stuff
      if this then gosub here else gosub there
      drawscreen
      goto loop
    here
      on something goto frame1 frame2 frame3
      return : rem * just to prevent unwanted fall-through
    there
      on somethingelse goto frame1 frame2 frame3
      return
    frame1
      rem * some stuff
      return
    frame2
      rem * some stuff
      return
    frame3
      rem * some stuff
      return

     

       rem * Example 2
    loop1
      rem * some stuff
      gosub here
      drawscreen
      if this then goto loop2
      goto loop1
    loop2
      rem * some stuff
      gosub here
      drawscreen
      if that then goto loop1
      goto loop2
    here
      on something goto frame1 frame2 frame3
      return : rem * just to prevent unwanted fall-through
    frame1
      rem * some stuff
      return
    frame2
      rem * some stuff
      return
    frame3
      rem * some stuff
      return

     

    By the way, I concur with SpiceWare-- neato!

     

    Michael

  4. Recommendations for improving bBasic:

    -> Looking at the .asm output from the compiler I see that the entire language library is included even if I never use most of the functions. Randomize for example and all the PF scroll functions are included in the image even though I didn't use them. I understand why this was done, but it would greatly reduce ROM consumption if unused functions were not included leaving more room for user defined code.

    bB uses an includes definition file-- called "default.inc"-- that lists the files it should include when it's compiling your bB code into assembly. In the past, if you wanted to modify that file, you had to save a backup of the original (always a good idea, unless you don't believe in that sort of thing), then edit the file to delete the include files you don't want, add more include files that you've written, or change the names so bB will use any modified include files you've created.

     

    However, you don't need to do that anymore with bB v1.0, because now there's an "includesfile" bB statement that you can use. Oh, you still need to make your own includes definition file, typically by copying one of bB's (it actually uses more than one, depending on which kernel you use-- standard or multisprite-- and whether or not you use bankswitching), and then editing it as you see fit. But you no longer have to back up the original and use the filename of the original for your custom file. Instead, you can just copy the original to a new name, modify it, and then use the "includesfile" statement in your bB program to tell bB to use your file instead of the normal file. That way, you can still compile all of your programs that use the normal files, plus the programs that use your customized files, without having to remember to juggle around with renaming the files back and forth.

     

    Anyway, you can easily create an includes definition file that will include only the files you want, which lets you omit any bB "system routines" that you won't be using in your program. This can be a little tricky if you aren't careful, since some routines may call other routines. But it shouldn't be difficult for an experienced programmer to do. Also note that some include files are essential-- in particular, the header and footer files-- although of course you can customize them as well.

     

    If I remember correctly, when I started tinkering with my E7-bankswitched "Sudoku" WIP game a while back, I used a custom includes definition file that basically did away with *all* of bB's include files, so I could just use my own, since I was using my own kernel instead of bB's kernel, and I wanted to define my own RAM usage, etc. So when I compile my "Sudoku" game that way, I can still use most of bB's high-level statements, but the entire ROM contains just my own code and custom includes. I posted all of my code, along with the custom include files, so you're welcome to look at it and see what I did. A word of warning, though-- you might have trouble compiling it under bB v1.0, since it was written under bB v0.35, and I haven't updated it yet to bB v1.0. But it can still serve as an example of how to write a bB program using a completely stripped-down includes definition file.

     

    Up Next:

    -> Can we do PF height animations?

    If your playfield is in RAM, you can do PF animation using the PF drawing commands. You can also change the heights of the PF rows, and (if you aren't using pfheights and pfcolors together) you can define multiple tables of PF heights, so that you can flip between different tables from frame to frame, making selected rows grow or shrink. Is that what you mean?

     

    Michael

  5. POKE 36866,24

    Say what? Are you saying that POKE 36866,24 will get rid of the left and right borders and give you 2 more characters on each line of the VIC-20's display? I don't remember that-- but it's been so long. I had (still have) "Mapping the VIC," so if it was in there, then I probably knew about it but forgot. :)

     

    Michael

  6. With the E.T./Pac-Man and "The End" mazes, I think it would be more challenging to add more walls-- for example, so the sub has to navigate between the letters, or do a sharp U-turn in the region of E.T.'s body, etc. Also, I think the treasure should be inside Pac-Man's mouth, like he's eating it. :)

     

    I still have something to finish up tonight, but after tonight I'll help you with the missile/playfield collision detection, and try to create a maze to contribute to the contest.

     

    Michael

  7. OK, so how would I code the following (just for an example.) I know this isn't the right syntax, but I made this just so you could understand what I'm trying to do here:

     

    if collision(ball,pfpixel 3 10) then k=0 : pfpixel 3 10 off

    You can't check for collisions with specific playfield pixels, but I presume you know that. What you'll need to do is check for a collision with the playfield, and if a collision occurred, you'll need to use the coordinates of the other object to figure out which playfield pixel was hit. I can't post any examples right now, because I'm trying to finish E.T. Book Cart and I just needed to take a quick break from it, but I'll post something later this week, maybe Monday night. That reminds me, I was going to post a similar sort of example a few months ago for the guy who was working on the zombie game, but that was to keep the player from colliding with the playfield (although it would use similar techniques as far as converting back and forth between player/missile coordinates and playfield pixel coordinates).

     

    Michael

  8. How does Infogrames feel about homebrews on Atari machines?

    I'm not sure, but didn't they include one or two homebrews on the Flashback2? And I thought when the recent Philly expo was being held (which I was not able to attend), people were saying that Atari is interested in getting along better with their fans and with homebrewers, or something like that? So my thought was that if a homebrew version of Toobin' was made that's good enough, maybe Atari would not just allow it, but might actually release it on a new Flashback or something like that? ;) But if Midway owns the rights now, that kind of blows that pipe dream out of the water. :)

     

    Michael

  9. I think the idea of being able (or required) to shoot away certain blockages to be able to get through a passage and reach the treasure is good, as well as having enemies to avoid and/or shoot at. This would be especially nice if it gave you points, and if you could earn more spare subs every so many points, because having a large® reserve of spare subs will be helpful when the player reaches the more difficult mazes.

     

    Michael

  10. Of course, Toobin' is a trademark...

    Coincidentally, I was reading up on Toobin' last week. Did you know that it was an *Atari* coin-op? And Tengen-- the company that made (most? all?) the home versions, was a subsidiary of Atari. ;)

     

    So I wonder if Atari would allow a homebrew version of Toobin' for Atari machines? :)

     

    Michael

  11. I love Toobin', but my copy is kind of quirky-- sometimes it doesn't want to work. A friend of mine had bought it used for me from a video rental store many years ago, so there's no telling what kind of abuse it had been through! :) I don't know if it's possible, but I'd love to make a 2600 version of Toobin' some day-- or if that's too much for the 2600 to handle (without sucking too badly, that is), then it could be an 800/5200 version, or maybe even a 7800 version (if I ever learn how to program the 7800, that is).

     

    Michael

  12. I was thinking of using some of the Superchip RAM bits to store whether each object had been uncovered yet.

    Ah, ok. So you would track everything "live" all the time? I like Johns idea of having only a select few things "activated" :lust:

    I was thinking of the second approach I mentioned-- using colors-- and just displaying the objects on the screen whether or not they're "uncovered." Then the object's bit flag would control whether the object's color matches the background ("invisible") or uses its normal color ("visible"). An advantage of doing it this way is being able to have collisions with "invisible" objects, like stumbling upon hidden treasure or triggering a hidden trap.

     

    it simply (for the moment) has a maze stored in ROM, copies the bits of the ROM maze into Supercharger RAM (before falling into the kernel), and then draws the playfield from the data in Supercharger RAM.

    How much time does the plain copying procedure require?

    In the little test I did, I copied the ROM maze to RAM before ever getting into the kernel, so that's not a good example. In an actual game, the ROM would be copied to RAM only as needed-- i.e., when a new level begins, the bits of the RAM map would be cleared. Then during game play, only the bits for the area immediately around the player would be copied from ROM to RAM, so that the maze would be uncovered as the player moves around. You don't need to copy the entire maze each frame, since once a bit has been copied to RAM, it will stay set-- so you're only updating a small portion of the maze during each frame.

     

    Also, I drew the maze in the code in the "normal" fashion to make it easier to type the 1s and 0s

    I'm sure writing a generator in C will help this a lot :D

    Actually, writing a generator in C would hinder a lot, since I don't know C very well! :D But I could do it in FreeBASIC very easily.

     

    I guess I can't post attachments in this reply to a blog entry(?), so I'll have to post them in a forum.

    Please do so, yes! I'd like to see it!

    The little test program I did isn't much to look at, since it only draws an incomplete map from RAM, and right now the very essential "uncover as you go" function hasn't been added. I'm actually in the middle of another project, and then I need to resume work on "Sudoku," so I don't know when I'll have much time to return to "Crawl 'n' Brawl," but I'm planning on doing it as a mixture of bB and asm. There won't be any in-line asm in the bB listing, but I'm going to develop custom include files. I've already written part of the custom kernel-- just the part that draws the playfield from Superchip RAM (it doesn't even have any sprites in it yet)-- but I'll have to write more custom includes as well. For example, I'll have to rewrite the pf drawing routines to work with a 40x24 playfield, instead of a 32x12 playfield as they do now. Then I'll be able to use the modified pfread function to check the bits of the ROM maze, and use the pfpixel command to set the bits of the RAM maze to match the ROM maze as the player moves around the screen.

     

    MR

  13. I've been playing some Gateway to Apshai lately, trying to see if I can get into it to give me some motivation continuing with a 2600 port.

    It's been a while since I've played Apshai on the XE, but I've also thought about how to a do game like Apshai or Fargoal on the 2600.

     

    What one does not notice at first, is how essential an element it is, that you have to uncover your surroundings bit by bit in this game. With every step forward you make, you never know what is hidden underneath the next corridor bit until you enter it. Be it some kind of treasures, equipment, potions, or any other goodies, be it some dangerous'n'deadly enemy lurking there waiting to kill you.

     

    I've been trying to find a solution for this, but I can't think of any really elegant way of realizing this "feature" on the VCS.

     

    One can replicate most of the game, even with 128 bytes of RAM. Instead of generating the dungeons live out of a seed, one can pre-render a certain number of labyrinths and put them into ROM. Same goes with monster and item positions, even doors - considering one finds a way to display them.

     

    But, giving the player this original "explorational suspense", I have no really good idea of how to achieve this effect. I think to do it properly and effective, it'd require the RAM buffering of a whole dungeon, just like the original does, requiring at least some 2K.

     

    One could possibly define a list of "uncover" squares for a whole dungeon, then just storing single bits wether that square was already uncovered or not.

     

    Then, making it a superchip solution: Considering the display would consist of 4 PF1/PF2 columns, 32 byte high each. One could then ROM->RAM copy the actual screen window each frame, and possibly render the then visible parts of still to-be-uncovered squares back into "void" in a second pass.

     

    That might work. Maybe.

    That's exactly the way I was thinking of doing it-- having some preset mazes in ROM, then you could select among them randomly so the levels wouldn't always be the same, and when you start a new game you can save the maze numbers for each level (e.g., level 1 uses maze 20, level 2 uses maze 152, level 3 uses maze 7, etc.) so the levels aren't selected randomly each time you revisit a level in the same game. The Superchip RAM would be used for actually displaying the maze, starting out with all the bits turned off, then you set each appropriate bit of RAM to match the ROM bits as you move around and uncover each square of the map. The objects-- stairs, pools, altars, enemies, etc.-- would be done with players, missiles, and the ball (but one of those would be used for the hero). Uncovering the objects or enemies could either be controlled by the shape data (i.e., all 0s for invisible objects, or set the shape for a visible object), or else you could go ahead and set the shape but use colors to control visibility (i.e., the sprite color would be the same as the background color if it's invisible, or different than the background if it's visible). I was thinking of using some of the Superchip RAM bits to store whether each object had been uncovered yet. Also, the Superchip RAM could be written to the Memcard or whatever it's being called now, to save the status of each level, and then the data for a previously-visited level could be read from the Memcard (as the player goes from one level to the next), so that the uncovered portions of a previously-visited level wouldn't be "lost."

     

    With 128 bytes of Superchip RAM, you can use 5 bytes per maze row-- 1 byte for the PF0 (one nybble for the left copy, and the other nybble for the right half), and 2 bytes each for PF1 and PF2, to get an asymmetrical playfield. Dividing 128 by 5 gives 24 rows (120 bytes), with 8 bytes left over for the sprite visibility flags (up to 64 sprites on each level, 1 bit for flagging each sprite's visibility status). I was thinking of using 7 scan lines per row, because I think that should make the playfield pixels look more squared than using 8 scan lines (or 6 scan lines). That would give 168 scan lines for the whole maze, leaving 24 scan lines for displaying other information (e.g., a score, or other stats, or even a few rows of text describing events, e.g., "You've fallen into a pit!")-- or even more than 24 scan lines, if you're using more than 192 active scan lines.

     

    Here's a short program I did in bB a little over a week ago, just as an experiment, although it doesn't include any movement, sprites, or actual uncovering of the maze. Instead, it simply (for the moment) has a maze stored in ROM, copies the bits of the ROM maze into Supercharger RAM (before falling into the kernel), and then draws the playfield from the data in Supercharger RAM. I don't even have a proper maze yet, just a partial maze-- and not even a very good one, just something I "doodled" to help me see the kernel in action. Also, I drew the maze in the code in the "normal" fashion to make it easier to type the 1s and 0s, and then I flip the bits around as needed when I'm loading the ROM data into RAM. So I don't know if you can go so far as to call this a "proof of concept" yet, just a very rough beginning. :lust:

     

    I was thinking of using this idea to make a game called "Dungeon Crawler," but then I found out that that name is already taken! So I thought of "Dungeon Crawl," or "Dungeon Brawl," but I got Google hits on those phrases, too-- so I chose "Crawl 'n' Brawl"! :D I guess I can't post attachments in this reply to a blog entry(?), so I'll have to post them in a forum.

     

    MR

×
×
  • Create New...