Jump to content
IGNORED

Another Effin' Block Game!


MausBoy

Recommended Posts

Well it seems that bB is now up to the challenge, and so am I, so I've developed yet another **tris for the 2600. No exciting multiple colors per scanline, but definately enough features and prettiness to blow away past efforts. If anyone else was working on a bB version I'm sorry. I know you mentioned on A2600L, hope you never got past the what-if stage.

 

All those pfreads and moving down stuff after a line has been cleared is a super headache to program, not to mention collision detection for each piece at each rotation angle, bleh.

 

It's going much much faster than I expected though, it's already very very nice. I think this one will be popular with people who can stomach another **tris. It has cut-scenes, music, 2 player mode(cooperative and competitive!!), score-save, A & B type games, easter eggs...you name it, it's in there. It still looks a little blah cause of the monochrome display, but ah well the gameboy wasn't exactly pretty.

 

Also, it's a 16k superchip game, so obviously theres some extra space, which means minigame easter eggs. I think this one will be a decent first finished project.

 

And yes, yes, yes, this is absolutely getting finished, and soon. There are ZERO roadblocks to finishing this, and it's already almost to the polishing phase. This will be done, that's a cemented in stone promise. I've talked a lot of crap in the past because of running into problems and limitations, this time there seriously are none.

 

Expect screenshots and maybe a demo. I think you'll all be pleased, unless you hated this type of game to begin with, and maybe even then...

Link to comment
Share on other sites

It's going much much faster than I expected though, it's already very very nice. I think this one will be popular with people who can stomach another **tris. It has cut-scenes, music, 2 player mode(cooperative and competitive!!), score-save, A & B type games, easter eggs...you name it, it's in there. It still looks a little blah cause of the monochrome display, but ah well the gameboy wasn't exactly pretty.

 

Also, it's a 16k superchip game, so obviously theres some extra space, which means minigame easter eggs. I think this one will be a decent first finished project.

 

I'm very intrested in seeing this game. The 2 player modes are what are driving my intrests in this game for the most part. It would be really cool to call it "YAFT" (Yet Another Fuckin' Tetris). Please put up the screen shots or Demo as soon as you can cause this sounds quite promising and something I look forward to buying on a cart.

Link to comment
Share on other sites

And yes, yes, yes, this is absolutely getting finished

 

...and pigs can fly... :P :lol:

 

Have some faith, this is the first non-beta release of bB, so it's not unreasonable that I had to wait it out to be able to finish anything. If I was interested in making games where, say, something bounces around a black screen while you try to avoid it, I woulda been set from the beginning, but unfortunately all my projects were just too ambitious. If I uploaded the rom today it would be considered a playable game, so unless I just never do that, there is no way for this game to not get done.

 

In fact, if I uploaded current roms of most of my announced projects, I think everyone would appreciate that I've taken my time, and mixed it up instead of burning out and quitting over one or two projects.

Link to comment
Share on other sites

Ok, so I haven't been completely honest. I have run into a bit of a problem with this project as well. All those bazillion pfreads really eat up some time, so there are some major speed issues. I guess that's why all the clones up until now have taken up such a tiny portion of the screen. I'm hoping that some smarter/faster/better programmers will be able to help me out with that though once I'm happy with everything else. It really lags in two player mode, and I don't want to have to eliminate that after all the work. MR seems to be a genius at speeding up code though, so I'm not overly pessimistic yet.

 

Does anyone happen to have an old USB key drive they don't want that they could contribute to MAUS games? It would speed up development a LOT.

Link to comment
Share on other sites

All those bazillion pfreads really eat up some time, so there are some major speed issues.

 

Learn how to access the display memory directly. Depending upon where things are drawn on the screen you may be able to achieve an enormous speed-up by doing something like (note: I've not done this with bB, so the code won't be quite right)

' Assumes column0..column3 hold the playfield data, in bottom-to-top order
 index=23
lp:
 if (column1[index] & column2[index]) == 252 then
column1[index] = 0
column2[index] = 0
hitsomething = 1
 else if column1[index] =0 then
column1[index] = 252
column2[index] = 252
 endif
 index = index - 1
 if index then goto lp

This assumes that you're using the middle ten pixels of the playfield for the falling-blocks area and you have the pixels adjacent to that area turned on. If a row is filled in, this code will flash it on and off. Since the only time a row will be completely off (including the edge pixel) is when it's being flashed, the above code should cause the row to flash at 30Hz.

Link to comment
Share on other sites

Yeah, like I said smarter/better/faster. That code looks like something I could understand with a little more explanation, but i'm not sure how the column variables work to check 10 seperate columns. The display is 32x24, and the 10 columns are in the middle, with a solid border around the play area.

 

What I have to do is each time a block lands, check each of the 20 rows for a solid line, if it finds any, eliminate them, then move everything above the empty space down. So I still have to check each playfield pixel above the now-empty rows to see if they are on or off. This takes a ton of calls to drawscreen, so the time between landing a block and the next one dropping in is way too much. And in two player mode, that all has to be done twice every time, and one player landing a block freezes up the other persons game until the check routines finish. I'm sure I can set it up so that player 2's "falling block" routine still runs while player 1's "landed block" routine runs, and the other way around, but that'll make the "landing block" routine even slower, and it's already unbearable. Like I said, I'm sure this can be worked out, even if it's with some of that nasty ASM I don't understand.

 

Thanks for taking the time and letting me know that other options are possible.

Edited by MausBoy
Link to comment
Share on other sites

Learn how to access the display memory directly. Depending upon where things are drawn on the screen you may be able to achieve an enormous speed-up by doing something like (note: I've not done this with bB, so the code won't be quite right)

I don't think that will help him too much. While he could optimize the jumps away, the problem is still that the PFReads are taking too long. Unsurprisingly, BBasic stores the playfield data in a bitmap. So reading if a playfield block is on or off requires that the individual bit be tested. I'm sure he could implement a super-fast shifting+bittest routine to speed it up a bit, but why? It's just Tetris.

 

Maus, the problem breaks down into two major tests:

 

- Checking if a falling block is should lock into position

- Checking if any lines have been cleared

 

The first test can be done super-quick by checking the playfield ONLY beneath the 4 falling blocks. You don't need to check the playfield for cleared lines, because the playfield can't change until the block is locked into place. And you only need to check that when the block moves down a line. If you're about to move the piece into a playfield block, it should be locked into place.

 

Once the piece is locked into place, you can check if any lines have been cleared. You can try and scan the lines of the 4 blocks, but I see no reason why you can't just scan the entire playfield. It will be a lot easier to program. The only catch is that you can't do it in one frame. Break your scan up into a few different frames, scanning something like 4-8 lines per frame. That will also give you a slight pause after the block locks, which is actually desirable. ;)

 

If your scan finds any lines to clear, then you should run the line-clear animation. This being BBasic, I recommend simply shifting the lines down one at a time rather than trying to flash the lines before moving the entire playfield down. :-o Moving one line per frame (or per few frames to slow the effect down!) will give you a nice waterfall effect. e.g.

 

|=.==| |=.==| |....|
|==.=| |....| |=.==|
|....| |==.=| |==.=|
|=.==| |=.==| |=.==|

 

After that is done, you can insert a new block at the top of the screen and start over.

 

So to recap:

 

State 1: Insert piece at top

State 2: Move piece and check for lock

State 3: Lock block and scan the playfield for cleared lines

State 4: Show falling block animation if necessary

Link to comment
Share on other sites

I don't think that will help him too much. While he could optimize the jumps away, the problem is still that the PFReads are taking too long. Unsurprisingly, BBasic stores the playfield data in a bitmap. So reading if a playfield block is on or off requires that the individual bit be tested. I'm sure he could implement a super-fast shifting+bittest routine to speed it up a bit, but why? It's just Tetris.

 

I don't know whether the PF data is stored as four bytes per row, or as four sets of one byte per row, but each row is represented by four bytes of data--one bit per pixel. If the goal is to check whether a particular pattern of pixels is set within a group of eight, it's merely necessary to check whether the byte that contains that group of eight pixels contains the value that group of eight would represent.

 

Things are complicated slightly by the fact that the first and third groups of eight have the most significant bit toward the left, while the second and fourth have it toward the right. Still, a couple of examples should clarify things.

 

If the eight pixels in the leftmost group of eight on a particular row are on-off-on-off-off-on-on-on, the byte that holds those pixels would hold a value of 10100111 binary, or 167 decimal. Storing a value of 167 in that byte would cause those eight pixels to appear in that pattern; one may check to see if that combination of pixels holds that pattern by seeing if that byte holds a value of 167.

 

The eight pixels to the right of that are stored in a different byte. If those pixels were on-off-off-on-off-on-off-off, that byte would hold a value of 00101001 binary (note that the bits are in the opposite order from those of the first eight pixels), which is 29 decimal.

Link to comment
Share on other sites

If the goal is to check whether a particular pattern of pixels is set within a group of eight, it's merely necessary to check whether the byte that contains that group of eight pixels contains the value that group of eight would represent.

Mmm.... that's a good point. Using say, a single compare on 255 (11111111 binary) would be a lot faster for scanning the lines than testing each bit. Maus, do you understand what Supercat is saying here? It's a good optimization overall.

 

That being said, I still think his core problem is algorithmic. He's probably trying to test large chunks of the playfield when it's not necessary. By separating out the logic for the falling block vs. the line test, he can get the performance he needs. Even without direct CMP checks.

Link to comment
Share on other sites

That being said, I still think his core problem is algorithmic. He's probably trying to test large chunks of the playfield when it's not necessary. By separating out the logic for the falling block vs. the line test, he can get the performance he needs. Even without direct CMP checks.

 

Whether or not the direct compares are needed for speed, code to test for full lines using direct compares will certainly be more compact than code testing all the pixels individually. So the optimization is clearly a win all around.

Link to comment
Share on other sites

Whether or not the direct compares are needed for speed, code to test for full lines using direct compares will certainly be more compact than code testing all the pixels individually. So the optimization is clearly a win all around.

I'm not disagreeing. Just saying that to solve his problem, he needs a better algorithm. :)

Link to comment
Share on other sites

Maus, the problem breaks down into two major tests:

 

- Checking if a falling block is should lock into position

- Checking if any lines have been cleared

 

The first test can be done super-quick by checking the playfield ONLY beneath the 4 falling blocks. You don't need to check the playfield for cleared lines, because the playfield can't change until the block is locked into place. And you only need to check that when the block moves down a line. If you're about to move the piece into a playfield block, it should be locked into place.

 

I do only check the playfield pixels only beneath the 4 (or 2) pixels of the falling block. I don't check the playfield for cleared lines until the block "lands", and it has to be split up between drawscreens in a seperate subroutine for/next loop. Believe it or not, the program can only check one line per drawscreen! You underestimate the cycles required for a 32x24 superchip playfield.

 

Once the piece is locked into place, you can check if any lines have been cleared. You can try and scan the lines of the 4 blocks, but I see no reason why you can't just scan the entire playfield. It will be a lot easier to program. The only catch is that you can't do it in one frame. Break your scan up into a few different frames, scanning something like 4-8 lines per frame. That will also give you a slight pause after the block locks, which is actually desirable. ;)

 

I hadn't thought of only scanning the lines the block landed on though, thanks for that. It does go ahead and check all lines, each time a block lands. Durrr, huh? There is a very noticeable delay because of the line check, each time a block lands. It pretty much kills 2 player mode, and since I can only scan one line per drawscreen in the subroutine, I can't also then jump back to player2's "falling block routine" without going over on cycles. Maybe your "only scan the lines landed on" fix will speed it up enough to not be too disgusting. Any sort of lag when you are positioning your block on high levels though is extremely annoying.

 

If your scan finds any lines to clear, then you should run the line-clear animation. This being BBasic, I recommend simply shifting the lines down one at a time rather than trying to flash the lines before moving the entire playfield down. :-o Moving one line per frame (or per few frames to slow the effect down!) will give you a nice waterfall effect. e.g.

 

|=.==| |=.==| |....|
|==.=| |....| |=.==|
|....| |==.=| |==.=|
|=.==| |=.==| |=.==|

 

After that is done, you can insert a new block at the top of the screen and start over.

 

This is how the line-clear subroutine works, but it also does create noticeable lag and eats up pretty much all the cycles each loop. If both players land a block at the same time, the lag is double! This happens by default when the first two blocks drop, if down is not pressed. I know I could avoid that by offsetting player2 by one frame, but what's the point when it can happen at any time, because of joystick-down speeding up the blocks? And again, no way to jump to the other players "falling block" routine during this subroutine either. Between line-scan and line-clear, when both subroutines run in two player mode the lag is unbearable.

 

So to recap:

 

State 1: Insert piece at top

State 2: Move piece and check for lock

State 3: Lock block and scan the playfield for cleared lines

State 4: Show falling block animation if necessary

 

Exactly how I did it, and thanks for the awesome tip on something I completely overlooked. Can't wait to see what that does for it. I'm going to, just to see what it does, but it does sound like supercat's code would probably be faster. Would it save on cycles too, to allow me to jump back to the other players subroutines?

 

And no, I don't really understand it at all.

Link to comment
Share on other sites

Believe it or not, the program can only check one line per drawscreen! You underestimate the cycles required for a 32x24 superchip playfield.

Ouch. Yeah, using the power of the superchip isn't all fun and games. :P

 

Supercat's optimization is to check the bytes as opposed to the bits. So say you have a line of blocks like this:

 

|==.=.==.|

 

In binary that would be 11010110. Which in decimal is 214. If we assume for a moment that a "full" row is binary 11111111, we can then check the row against the specified value. i.e.:

 

if row = 255 then lineclear else checknextline

 

Obviously, you'll need to check more than one byte per line, but the concept is effectively the same. Just keep the data for what number represents a full line somewhere in ROM and you'll be able to do a quick compare.

 

There is a very noticeable delay because of the line check, each time a block lands. It pretty much kills 2 player mode, and since I can only scan one line per drawscreen in the subroutine

That should only be a 24 frame delay, correct? That's only a half-second. As long as you can keep computing the movements of the other player in that time, you should be good to go. Supercat's optimization will even allow you to compute both player movement and a line check in a single frame.

 

I can't also then jump back to player2's "falling block routine" without going over on cycles. Maybe your "only scan the lines landed on" fix will speed it up enough to not be too disgusting. Any sort of lag when you are positioning your block on high levels though is extremely annoying.

An extension of Supercat's optimization is to copy the line byte by byte rather than bit by bit. It will be at least 16x faster because you won't need to read/write each bit.

Link to comment
Share on other sites

Well ok, that makes sense. I still don't get how the bits or bytes for the row are set in "row" though. How does it know that it's %11111111 without checking each pfpixel and setting those bits? Right now all it does is pfread each pfpixel in a line, and keep a variable true unless it finds an off pfpixel. If it stays true up until the tenth pfpixel is checked, the line is clearable.

 

Also, I'm obviously not understand this because I don't see how 8 bits can represent ten columns anyway.

Edited by MausBoy
Link to comment
Share on other sites

WARNING: The forum is trimming my numbers if I use percent signs. So just image the "%" in the binary examples below.

 

Well ok, that makes sense. I still don't get how the bits or bytes for the row are set in "row" though. How does it know that it's %11111111 without checking each pfpixel and setting those bits?

The playfield data is stored somewhere in memory. Check the BBasic code for the superchip to find where that is. (I'm afraid I don't have it handy at the moment.)

 

Also, I'm obviously not understand this because I don't see how 8 bits can represent ten columns anyway.

It can't. That was only an example of how it's supposed to work. You'll need to check two bytes for each line on each side.

 

Let's say for a moment that your playfield looks like this:

 

|..........|		|..........|
|..........|		|..........|
|..........|		|..........|
|..........|		|..........|
|..........|		|..........|
|..........|		|..........|
------------		------------

 

An empty line in memory would look something like this:

 

10000000, 00010000, 00001000, 00000001

 

A full line on the left side would be:

 

11111111, 11110000, 00001000, 00000001

 

A full line on the right side would be:

 

10000000, 00010000, 00001111, 11111111

 

So you only need to check the two left bytes for the first player, and the two right bytes for the second player. Here's the catch 22, though: The first and the last bytes (IIRC) are going to be backwards. i.e. Instead of this:

 

10000000, 00010000, 00001000, 00000001

 

You'll see this:

 

00000001, 00010000, 00001000, 10000000

 

Or maybe it's the middle two bytes that have their bits reversed. I'm afraid I've been focusing too much on the Wii to remember. :P

 

It's not a big deal, but you'll need to make sure that the order of your bits match the bits you're testing against.

Link to comment
Share on other sites

Ok, that cleared it up for me. That sounds like a headache of work. I'm going to polish it up as much as I can as-is, then see if I can convert it to that with some research and practice. I'm scared trying something like that, that makes my head hurt, will take all the fun out. Is it easier than it sounds? I definately understand what you are saying now though.

 

Thanks jbanes and supercat, without help like yours I would be completely clueless and never get anything done!

Link to comment
Share on other sites

  • 3 weeks later...
Whatever happened to this game? I'm looking forward for a playable version.

I am friggin Jonesin for a fallin block game for VCS! Please somebody get one on cart and in the store.

I have already promised people I would not deal with that "Randy" feller who sells copies of Edtris and I am keepin my word on that.

WP

Link to comment
Share on other sites

I am friggin Jonesin for a fallin block game for VCS! Please somebody get one on cart and in the store.

By "falling block game" do you mean Tetris in specific? Because if you're just looking for a puzzler with falling blocks, there's always Strat-O-gems. :)

Yeah, I mean Tetris Clone but just didn't wanna say it.

WP

Link to comment
Share on other sites

Well the main reason I started this project was because there wasn't a 2 player blocks game for the 2600, and of course I find out after putting in tons of effort that one is just being released, z-blocks. I've already put in too much effort to quit on it, but I can't find much if anything that it'd have over z-blocks. if anyone demos that game let me know if there are any shortcomings that i can avoid in this one.

 

Expect screenshots and possibly a demo within a week.

Link to comment
Share on other sites

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.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...