Jump to content



RevEng's Photo

RevEng

Member Since 23 May 2009
OFFLINE Last Active Today, 6:17 PM

Topics I've Started

Suggestion: add .asm to the whitelist of attachable file types

Wed Sep 21, 2011 11:24 AM

Given that .asm isn't a security risk and most people just get around this restriction by adding .txt to the extension... what's the reason for not allowing .asm attachments?

Squeezing the bBytes

Sat Aug 20, 2011 11:45 AM

There comes a time in the development of most games when the rom starts to get tight; when no additional features can be added until you figure out a way to squeeze the bytes and free up more space.

I haven't seen this information gathered in one place before, so I thought I'd kick off this thread to share some of the techniques I've used to save rom space. So with no further adieu, here they are...


  • keep same-value variable assignments on the same line when possible.

        rem ***** do this...
      
          timer=0:level=0:deathflag=0:soundindex=0
      
        rem ***** instead of this...
      
          timer=0
          level=0
          deathflag=0
          soundindex=0
       

      Since they're on the same line, bB knows it doesn't need to keep loading the 0 value for each assignment.

      The savings is fairly minimal (2 bytes for each variable after the first one) but this is an easy technique to use and the savings can add up quickly!

      (NOTE: the current version of bB seems to max out at 12 assignments per line. If you use more than that you may run into compile errors. :( )


  • when using bankswitching, try to reduce the number of bankswitching gosubs and gotos.

      A regular gosub takes 3 bytes. A bankswitching gosub takes 24 bytes.
      A regular goto takes 3 bytes. A bankswitching goto takes 18 bytes.

      You should avoid having small utility routines that are bankswitch-gosub'ed from many places. Either move the utility into the same bank as the calls, or change all the bankswitching gosubs to a local gosub that has a common bankswitching goto routine...

       rem ***** do this...
      
         if lives=1 then gosub utilityjump
         health=1
         gosub utilityjump
         goto mainloop
      utilityjump
         goto utility bank3
      
       rem ***** instead of this...
      
         if lives=1 then gosub utility bank3
         health=1
         gosub utility bank3
         goto mainloop
       

      If there's a bank with a lot of utility functions, you can save rom by using on...goto and a temp variable...

       rem ***** use this...
      
         if lives=3 then temp1=0:gosub enterbank2
         if enemies=0 then temp1=1:gosub enterbank2
         if gold=1 then temp1=2:gosub enterbank2
         goto mainloop
      
      enterbank2
         goto dispatcher2 bank2
      
         bank 2
      dispatcher2
         on temp1 goto routine1 routine2 routine3
      routine1
         rem do stuff
         return otherbank
      routine2
         rem do stuff
         return otherbank
      routine3
         rem do stuff
         return otherbank
      
       rem ***** instead of this...
      
         if lives=3 then temp1=0:gosub routine1 bank2
         if enemies=0 then temp1=1:gosub routine2 bank2
         if gold=1 then temp1=2:gosub routine3 bank2
         goto mainloop
      
         bank 2
      routine1
         rem do stuff
         return otherbank
      routine2
         rem do stuff
         return otherbank
      routine3
         rem do stuff
         return otherbank
       


  • In a bank-switched game, if you're sure a return is always going to be within the same bank, use "return thisbank" instead of "return". If the return will always be to another bank, use "return otherbank" instead of "return".

      In a bank-switched game...

      A "return otherbank" statement takes 3 bytes.
      A "return" statement takes 13 bytes.
      A "return thisbank" statement takes 1 byte.

      'nuff said.


  • If you have a large amount of data with values less than 16, Use nibbles and hex notation to stick the data together

      
       rem ***** use this...
         channel=songvolumechannel[i]&15
         volume=songvolumechannel[i]/16
         data songvolumechannel
         $86, $48, $84, $86
      end
      
       rem ***** instead of this...
         channel=songchannel[i]
         volume=songvolume[i]
         data songchannel
         6, 8, 4, 6
      end
         data songvolume
         8, 4, 8, 8
      end
       


  • pick variable locations consecutively so you can operate on many objects using a loop

      If you're doing a lot of the same operation to a bunch of variables, often it's better to pick the position of variables carefully and use loops...

       rem ***** use this...
         dim monster1x=g
         dim monster2x=h
         dim monster3x=i
         dim monster4x=j
         for temp1=0 to 3
         if monster1x[temp1]>25 then monster1x[temp1]=1
         if monster1x[temp1]<0 then monster1x[temp1]=24
         next
      
       rem ***** instead of this...
         if monster1x>25 then monster1x=1
         if monster1x<0 then monster1x=24
         if monster2x>25 then monster2x=1
         if monster2x<0 then monster2x=24
         if monster3x>25 then monster3x=1
         if monster3x<0 then monster3x=24
      

I've also been able to squeeze a fair bit of ROM through algorithmic improvement and judicious assembly code rewrites, but those techniques aren't really suited to a simple tips thread. I figured I'd still mention it, so you can keep them in mind.

Please post any techniques you've discovered!