Jump to content

Recommended Posts

I'm trying to create a soccer style game where when a player scores 5 points they win the round and the game goes to another screen, then they play best 2 out of 3 and then it goes to either blue wins or red wins. I had a basic game with a title screen, one board and both possible winning scenarios. However when I tried to add levels I ran out of memory.

How can I save memory so I can fit these levels in?

I'll attach my original code and the working game, and then the second one, is the one that takes up too much memory.

 

freeball.txtfreeball.binfreeball2.txt

Link to comment
https://forums.atariage.com/topic/98205-memory/
Share on other sites

One thing you could do is instead of using all those pfpixel commands, use the playfield command. For example, your first field would be like this:

playfield:
 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
 XX............................XX
 XX............................XX
 XX............................XX
 X..............................X
 X..............................X
 X..............................X
 XX............................XX
 XX............................XX
 XX............................XX
 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
end

That is, if you have version 0.99 installed. This comes in rather handy and I use it all the time. You could also make the game look a lot neater by using the no_blank_lines command, which will fill in the gaps between pfpixels.

By the way, welcome to the forums! It's great to see new people using Batari Basic. :)

Edited by atari2600land
Link to comment
https://forums.atariage.com/topic/98205-memory/#findComment-1190406
Share on other sites

I had a basic game with a title screen, one board and both possible winning scenarios. However when I tried to add levels I ran out of memory.

How can I save memory so I can fit these levels in?

One thing you should try to do is create one primary loop for the display kernel, rather than making the common mistake of having a different loop for each and every screen in your game. By using control variables and subroutines, you can usually have one display loop for the whole game. If you need to draw a different screen, change the player shapes, change the colors, play the next note of a tune, etc., just call a subroutine to make the necessary changes, and then return to the main loop. By using that approach, you can avoid ending up with many different-but-similar loops that contain a lot of duplicated code.

 

I'd start by rewriting the different levels to use data tables rather than big collections of pfpixel commands.

How would I do that?

One approach is to use pfhline and pfvline statements as much as possible to turn playfield pixels on or off in horizontal or vertical lines, and use pfpixel statements only for single playfield pixels that need to be turned on or off. It looks like you're already using pfhline and pfvline, which is good; but by putting each pfhline, pfvline, and pfpixel statement on a separate line of code, grouping them by similar statements, and sorting them based on the coordinates, I can see that several of your pfpixel statements could be combined into pfhline or pfvline statements. And by compiling and running your title screen to see what it looks like, I would suggest the following variation:

 

  rem * pfvline statements
  pfvline 0 1 5 on : rem * the vertical stroke of the F
  pfvline 4 1 5 on : rem * the first vertical stroke of the R
  pfvline 6 4 5 on : rem * the second vertical stroke of the R
  pfvline 8 1 5 on : rem * the vertical stroke of the first E
  pfvline 12 1 5 on : rem * the vertical stroke of the second E
  pfvline 16 1 5 on : rem * the vertical stroke of the B
  pfvline 20 2 5 on : rem * the first vertical stroke of the A
  pfvline 22 2 5 on : rem * the second vertical stroke of the A
  pfvline 24 1 5 on : rem * the vertical stroke of the first L
  pfvline 28 1 5 on : rem * the vertical stroke of the second L

  rem * pfhline statements
  pfhline 1 1 2 on : rem * the horizontal stroke of the F
  pfhline 9 1 10 on : rem * the first horizontal stroke of the first E
  pfhline 9 5 10 on : rem * the second horizontal stroke of the first F
  pfhline 13 1 14 on : rem * the first horizontal stroke of the second E
  pfhline 13 5 14 on : rem * the second horizontal stroke of the second E
  pfhline 25 5 26 on : rem * the horizontal stroke of the first L
  pfhline 29 5 30 on : rem * the horizontal stroke of the second L

  rem * pfpixel statements
  pfpixel 1 3 on : rem * remaining pixel of the F
  pfpixel 5 1 on : rem * first remaining pixel of the R
  pfpixel 6 2 on : rem * second remaining pixel of the R
  pfpixel 5 3 on : rem * third remaining pixel of the R
  pfpixel 9 3 on : rem * remaining pixel of the first E
  pfpixel 13 3 on : rem * remaining pixel of the second E
  pfpixel 17 1 on : rem * first remaining pixel of the B
  pfpixel 18 2 on : rem * second remaining pixel of the B
  pfpixel 17 3 on : rem * third remaining pixel of the B
  pfpixel 18 4 on : rem * fourth remaining pixel of the B
  pfpixel 17 5 on : rem * fifth remaining pixel of the B
  pfpixel 21 1 on : rem * first remaining pixel of the A
  pfpixel 21 3 on : rem * second remaining pixel of the A

Believe it or not, the above variation saves 94 bytes in the title-drawing code! (It also corrects a few player pixels that weren't turned on, which I assumed were mistakes.) But it can be squeezed even more than that. I think what vdub_bobby meant was storing the coordinates for the playfield drawing statements in data tables, and reading those coordinates in loops, as follows:

 

  rem * define (dim) some variables
  rem * you can use other letters if you're already using a through e
  dim x1 = a
  dim y1 = b
  dim x2 = c
  dim y2 = d
  dim index = e

  for index = 1 to 30 step 3
  x1 = pfvline_data_1[index]
  y1 = pfvline_data_1[index+1]
  y2 = pfvline_data_1[index+2]
  pfvline x1 y1 y2 on
  next
  data pfvline_data_1
  0,1,5
  4,1,5
  6,4,5
  8,1,5
  12,1,5
  16,1,5
  20,2,5
  22,2,5
  24,1,5
  28,1,5
end

  for index = 1 to 21 step 3
  x1 = pfhline_data_1[index]
  y1 = pfhline_data_1[index+1]
  x2 = pfhline_data_1[index+2]
  pfhline x1 y1 x2 on
  next
  data pfhline_data_1
  1,1,2
  9,1,10
  9,5,10
  13,1,14
  13,5,14
  25,5,26
  29,5,30
end

  for index = 1 to 26 step 2
  x1 = pfpixel_data_1[index]
  y1 = pfpixel_data_1[index+1]
  pfpixel x1 y1 on
  next
  data pfpixel_data_1
  1,3
  5,1
  6,2
  5,3
  9,3
  13,3
  17,1
  18,2
  17,3
  18,4
  17,5
  21,1
  21,3
end

This second variation saves 116 bytes over the first variation, or 210 bytes over the original code! Yet it can be squeezed down even more than that, because the playfield is only 48 bytes long (but only 44 of them are normally visible). So if you draw the playfield by writing to the bytes instead of working at the pixel (or bit) level, you can squeeze it down a lot more. The "released" versions of bB (version 0.35 and below) don't have a command for setting the entire playfield at once, like version 0.99 does, but you can use some routines to write the playfield bytes, as follows:

 

  rem * need to include div_mul.asm for some of the math

  include div_mul.asm

  rem * define (dim) some variables
  rem * you can use other letters if you're already using a through c

  dim row = a
  dim column = b
  dim byte = c

  for row = 0 to 10
  for column = 0 to 3
	 byte = 4 * row
	 byte = byte + column
	 temp1 = title[byte]
	 if column = 1 then gosub flip_it
	 if column = 3 then gosub flip_it
	 playfield[byte] = temp1
  next
  next

  data title
  %00000000,%00000000,%00000000,%00000000
  %11101100,%11101110,%11000100,%10001000
  %10001010,%10001000,%10101010,%10001000
  %11001100,%11001100,%11001110,%10001000
  %10001010,%10001000,%10101010,%10001000
  %10001010,%11101110,%11001010,%11101110
  %00000000,%00000000,%00000000,%00000000
  %00000000,%00000000,%00000000,%00000000
  %00000000,%00000000,%00000000,%00000000
  %00000000,%00000000,%00000000,%00000000
  %00000000,%00000000,%00000000,%00000000
end

  rem * then put the drawscreen loop here

  rem * subroutines must go at the end of your program

flip_it
  temp2 = 0
  if temp1{0} then temp2{7} = 1
  if temp1{1} then temp2{6} = 1
  if temp1{2} then temp2{5} = 1
  if temp1{3} then temp2{4} = 1
  if temp1{4} then temp2{3} = 1
  if temp1{5} then temp2{2} = 1
  if temp1{6} then temp2{1} = 1
  if temp1{7} then temp2{0} = 1
  temp1 = temp2
  return

This third variation actually uses 29 *more* bytes than the second variation, but that's because you need to include the div_mul.asm file, and must add a subroutine to flip some of the bytes (since the 2600 draws them backwards). You could save some more bytes by flipping the appropriate values in the data array so that a subroutine isn't needed, but it's easier to draw and see the playfield pixels in the data array if you leave them unflipped, and then use a subroutine to flip them as needed. And besides, you'll still end up saving more bytes overall, since you need to include the div_mul.asm file and the flip_it subroutine only once in your program, and then you can use them as many times as you need to for all the screens in your game.

 

Finally, if you're using the "pre-release" version 0.99 of bB, you can use the playfield statement (as atari2600land mentioned) to define the entire playfield at once, as follows:

 

  playfield:
  ................................
  XXX.XX..XXX.XXX.XX...X..X...X...
  X...X.X.X...X...X.X.X.X.X...X...
  XX..XX..XX..XX..XX..XXX.X...X...
  X...X.X.X...X...X.X.X.X.X...X...
  X...X.X.XXX.XXX.XX..X.X.XXX.XXX.
  ................................
  ................................
  ................................
  ................................
  ................................
end

This fourth variation (which requires version 0.99) saves 197 bytes over the third variation, or 168 bytes over the second variation, or 284 bytes over the first variation, or 378 bytes over the original title-drawing code! The number of bytes saved will depend on how many pfhline, pfvline, and pfpixel statements you were using to draw each of your screens; but as you can imagine, saving over 300 bytes on each screen in your game is going to add up to a lot of bytes saved!

 

Michael

Link to comment
https://forums.atariage.com/topic/98205-memory/#findComment-1190695
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...