Shop OBEX P1 Docs P2 Docs Learn Events
Urgent help needed to condense code for VGA (buffer?) and counting display code — Parallax Forums

Urgent help needed to condense code for VGA (buffer?) and counting display code

WBA ConsultingWBA Consulting Posts: 2,934
edited 2013-12-11 17:50 in Propeller 1
I have a project that I am working on that is due Saturday morning for a Christmas play this weekend. My code is going very well, but I have run into a snag with running out of memory and I still need to add code for the xBee module that will receive triggers from a remote for each particular event. There are a couple places that I think I can reduce my code usage to save some small bits, but I have realized that the VGA code I am using is taking up a significant amount of space.

I am using BIG VGA Font from this thread, and in the VAR section, a LONG array called BITMAP is being declared that consumes 3072+64 longs. I don't fully understand how this bitmap buffer is utilized, so I am uncertain, but can this be reduced? It appears that this is my biggest memory killer.
VAR
  long  bitmap[3072+64] ' Must be aligned on 32 byte boundary
  long  colors[64]
  word  screen[x_tiles * y_tiles]

  long bitmapAddr
  byte numStr[5]

Also, there is a LONG array called colors being specified at 64 longs. Do I need this variable that large when I am only using 4 colors?



One section I am going to condense is for my counting display sequence. Currently, I have each year-to-year sequence separately coded, but I know I can condense them by using one routine that uses variables for the differences so the code can be the same. With that, however, I need to figure out how to make the code count from one year to the next in a specific amount of time when the difference between the years varies (one jump is 2013 to 1978 (35 years) , but the next jump is only 1978 to 1985 (7 years). The sound effect that plays while the time machine is counting is 24 seconds long. The counting display needs to last 18 seconds. Below is my current code sequence for jumping from 2013 to 1978. It times out perfectly by use of the delay while counting, but I have to change this delay for each jump.
PUB JUMP1978  | i

  wav.play(string("SFX.wav"))            ' Play 24 second long "time jump" sound effect
  waitcnt(cnt+clkfreq*2)                 ' Let SFX volume fade up
  JUMPSTANDBY                            ' Show time machine activation/standby display
  waitcnt(cnt+clkfreq*2)                 '    and leave up for 2 seconds before counting
    
' Count from present year to jump year
  i:=2013
                                           ' this repeat loop must complete in ~18 seconds to match sound file!
    repeat until i == 1977                 ' stop at 1978
        num2str(i)
        gr.textmode(9,9,6,5)
        gr.colorwidth(1,3)
        gr.text(0,10,@numStr)
        waitcnt(cnt+clkfreq/3)             ' delay between years during counting
        i-=1                                      ' increment year down (how to handle both directions?????)
        gr.colorwidth(0,8)
        gr.box(-120,-30,240,81)
                                           ' WAV sound effect fades out about here
' Flash current year                       ' done counting, flash year of arrival 8 times
    repeat 8
      gr.colorwidth(0,8)
      gr.box(-120,-30,240,81)              ' draw black box to clear year
      waitcnt(cnt+clkfreq/4)
      gr.textmode(9,9,6,5)
      gr.colorwidth(1,8) 
      gr.text(0,10,@numStr)                ' draw year
      waitcnt(cnt+clkfreq)



Also, it is hardcoded to count down, but the next jump needs to count up. There are a total of 8 separate years to travel to: Start at 2013, then 1978, 1985, 1959, 1998, 1944, 0, 1944,and finally back to 2013. I will probably need to have a special routine for jumping between 1944 and 0 due to the high number of years to count.


Here is the code for my version 008 demo that works for a keypad entry sequence, two time jumps with the sound file, and then displays "the end". Only the time jump for 1978 routine is commented fully.
' TIME MACHINE
' WBA Consulting
' Andrew Williams
' (c)2013
'
'  Code emulates a Time Machine Prop for a Church Christmas Kids Play.
'  Uses WAV files for sound effects, drives a VGA display, and lights some LEDs
'
' Version Info:
' 007   Working code for demo of display setup and sound files
' 008   Cleaned Structure, fixed formatting discrepancies
' 009   ***Need to add other years***
'

CON

  _clkmode = xtal1 + pll16x
  _xinfreq = 5_000_000

    x_tiles = 16
    y_tiles = 12

'WAV Player
    lPin = 26
    rPin = 27

    doPin = 22
    clkPin = 23
    diPin = 24
    csPin = 25

    wpPin = -1
    cdPin = -1

VAR
  long  bitmap[3072+64] ' Must be aligned on 32 byte boundary
  long  colors[64]
  word  screen[x_tiles * y_tiles]

  long bitmapAddr
  byte numStr[5]
  


OBJ
  vga   : "vga"
  gr    : "graphics"
  wav   : "V2-WAV_DACEngine.spin" 

PUB start '| i

'VGA Initilization
  StartVGA

'WAV Player Initilization 
   wav.begin(lPin, rPin, doPin, clkPin, diPin, csPin, wpPin, cdPin)

  waitcnt(cnt+clkfreq*2)

'Code

   SYSBOOT

    repeat 6 
      gr.textmode(4,4,6,0)
      gr.colorwidth(1,3) 
      gr.text(-70,10,string("#>_"))
      waitcnt(cnt+clkfreq/3)
      gr.colorwidth(0,3)
      gr.text(-70,10,string("  _"))
      waitcnt(cnt+clkfreq/4)

   DATAENTRY
   waitcnt(cnt+clkfreq*4)
   JUMP1978
   waitcnt(cnt+clkfreq*4)
   JUMP1985
     
' the end      
  waitcnt(cnt+clkfreq*8)
  gr.clear
  gr.colorwidth(1,4)
  gr.box(-120,-30,240,81)
  gr.textmode(4,4,6,5)
  gr.colorwidth(2,3) 
  gr.text(0,10,string("the end"))

PUB SYSBOOT

  gr.textmode(3,3,6,5)
  gr.colorwidth(1,3)
  gr.text(-40,80,string("SYS READY"))

  gr.textmode(2,2,6,5)
  gr.colorwidth(2,2)
  gr.text(-70,-70,string("HO-2000"))
 
  gr.textmode(2,2,6,5)
  gr.colorwidth(2, 2)
  gr.text(50, -70, string("DEPART"))

PUB SYSREADY

  gr.textmode(3,3,6,5)
  gr.colorwidth(1,3)
  gr.text(-40,80,string("SYS READY"))

  gr.textmode(2,2,6,5)
  gr.colorwidth(2,2)
  gr.text(-70,-70,string("HO-2000"))

PUB JUMPSTANDBY

  gr.clear
  gr.textmode(3,3,6,5)
  gr.colorwidth(1,3)
  gr.text(0,75,string("12 / 24"))

  gr.textmode(9,9,6,5)
  gr.colorwidth(1,3) 
  gr.text(0,10,string("2013"))

  gr.textmode(2,2,6,5)
  gr.colorwidth(2,2)
  gr.text(-70,-70,string("HO-2000"))
 
  gr.textmode(2,2,6,5)
  gr.colorwidth(3, 2)
  gr.text(50, -70, string("12/24/----"))

PUB DATAENTRY

    gr.clear
    SYSREADY
    wav.play(string("keys.wav"))  
    gr.textmode(4,4,6,0)
    gr.colorwidth(1,3) 
    gr.text(-70,10,string("#>1"))
    waitcnt(cnt+clkfreq/4*3)
    gr.text(-70,10,string("#>12"))
    waitcnt(cnt+clkfreq/4*3)    

    gr.clear
    SYSREADY
    gr.textmode(2,2,6,5)
    gr.colorwidth(3, 2)
    gr.text(50, -70, string("12/--/----"))

    gr.colorwidth(1,3)
    gr.textmode(4,4,6,0)
    waitcnt(cnt+clkfreq/4)    
    gr.text(-70,10,string("#>2"))
    waitcnt(cnt+clkfreq/4)    
    gr.text(-70,10,string("#>24"))
    waitcnt(cnt+clkfreq/4*3)    
    
    gr.clear
    SYSREADY
    gr.textmode(2,2,6,5)
    gr.colorwidth(3, 2)
    gr.text(50, -70, string("12/24/----"))

    gr.textmode(4,4,6,0)
    gr.colorwidth(1,3) 
    gr.text(-70,10,string("#> "))
 
PUB JUMP1978  | i

  wav.play(string("SFX.wav"))            ' Play 24 second long "time jump" sound effect
  waitcnt(cnt+clkfreq*2)                 ' Let SFX get going
  JUMPSTANDBY                            ' Show time machine activation/standby display
  waitcnt(cnt+clkfreq*2)                 '    and leave up for 2 seconds before counting
    
' Count from present year to jump year
  i:=2013
                                           ' this repeat loop must complete in ~18 seconds
    repeat until i == 1977                 ' stop at 1978
        num2str(i)
        gr.textmode(9,9,6,5)
        gr.colorwidth(1,3)
        gr.text(0,10,@numStr)
        waitcnt(cnt+clkfreq/3)             ' delay between years during counting
        i-=1 
        gr.colorwidth(0,8)
        gr.box(-120,-30,240,81)
                                           ' WAV sound effect fades out about here
' Flash current year                       ' done counting, flash year of arrival 8 times
    repeat 8
      gr.colorwidth(0,8)
      gr.box(-120,-30,240,81)              ' draw black box to clear year
      waitcnt(cnt+clkfreq/4)
      gr.textmode(9,9,6,5)
      gr.colorwidth(1,8) 
      gr.text(0,10,@numStr)                ' draw year
      waitcnt(cnt+clkfreq)

PUB JUMP1985  | i

    wav.play(string("SFX.wav"))
    gr.colorwidth(0,8)               ' clear bolded year
    gr.box(-120,-30,240,81)    

' Count from present year to jump year
  i:=1978                         ' current year
  
    repeat until i == 1986        
        num2str(i)
        gr.textmode(9,9,6,5)
        gr.colorwidth(1,3)
        gr.text(0,10,@numStr)
        if i == 1978
           waitcnt(cnt+clkfreq*9)
        else
           waitcnt(cnt+clkfreq)
        i+=1 
        gr.colorwidth(0,8)
        gr.box(-120,-30,240,81)

' Flash current year
    repeat 8
      gr.colorwidth(0,8)
      gr.box(-120,-30,240,81)
      waitcnt(cnt+clkfreq/4)
      gr.textmode(9,9,6,5)
      gr.colorwidth(1,8) 
      gr.text(0,10,@numStr)
      waitcnt(cnt+clkfreq)

PUB num2str(value) | given ' For numbers from 100 to 9999
  given := value
  if value < 1000
    value *= 10
    
  numStr[0] := value / 1000  + "0"
  value //= 1000
  numStr[1] := value / 100 + "0"
  value //= 100
  numStr[2] := value / 10 + "0"
  value //= 10
  numStr[3] := value + "0"
  numStr[4] := 0

  if given < 1000
    numStr[3] := 0

PUB StartVGA | i, dx, dy, c
  bitmapAddr := (@bitmap + $3F) & $FFFF_FFC0 ' Bitmap address must start on a 32 byte boundary 

  'start vga
  vga_videobase := @screen
  vga_colorbase := @colors
  vga.start(@vgaparams)

  'init colors
  repeat i from 0 to 63
    colors[i] := $28_48_FF_00 ' teal, purple, white, black
 
  'init tile screen
  repeat dx from 0 to vga_hc - 1
    repeat dy from 0 to vga_vc - 1
      screen[dy * vga_hc + dx] := bitmapAddr >> 6 + dy + dx * vga_vc '+ ((dy & $3F) << 10)

  'start and setup graphics
  gr.start
  gr.setup(16, 12, 128, 96, bitmapAddr)

DAT

vgaparams               long    0               'status
                        long    1               'enable
                        long    1_111        'pins
                        long    11           'mode
vga_videobase           long    0               'videobase
vga_colorbase           long    0               'colorbase
vga_hc                  long    x_tiles         'hc
vga_vc                  long    y_tiles         'vc
                        long    2               'hx        //RJA increased from 1X to 2X
                        long    2               'vx        //RJA increased from 1X to 2X 
                        long    0               'ho
                        long    0               'vo
                        long    512             'hd
                        long    16              'hf
                        long    96              'hs
                        long    48              'hb
                        long    380+16          'vd         //RJA added 16
                        long    11              'vf
                        long    2               'vs
                        long    31+16           'vb       //RJA subtracted 16
                        long    20_000_000      'rate

Comments

  • T ChapT Chap Posts: 4,223
    edited 2013-12-08 20:52
    Out of curiosity, what are you using to compile? Any optimizations?
  • WBA ConsultingWBA Consulting Posts: 2,934
    edited 2013-12-08 21:06
    Propeller Tool 1.3. Haven't tried any others.
  • T ChapT Chap Posts: 4,223
    edited 2013-12-08 21:09
    Can you try with BST and the optimizes? Eliminate Unused + Safe Opti under Tools>Compiler Prefs. I have a project that used a lot of bitmaps that wont fit in memory, so I parked them on the upper side of a 64k eeprom. The program loads the bitmaps as needed so there is no program memory being used for the bitmap storage.
  • WBA ConsultingWBA Consulting Posts: 2,934
    edited 2013-12-08 21:41
    I don't really understand how the bitmap portion of the code works, so not sure if I can dump that in the upper portion of the 64k. That would be nice though.

    Thanks for the BST tip! Compiling in BST with the two options you mention increases the free longs from 220 to 654, so it definitely does help. I might be able to make that work. I have a lot of code to finish out to know what I truly need, but adding simple serial for the XB and two more time jumps wiped me out originally.

    I think my next hurdle is figuring out how to re-use the jump loop code or finish off the XB code to see where I stand. I am worried that I may end up in a memory crunch again though....
  • Duane DegnDuane Degn Posts: 10,588
    edited 2013-12-08 21:48
    After attempting and failing to find ways to fit a programs into the memory left over after adding video output, I've finally given into the darkside and just use a second Prop as a graphics slave.

    Just something to keep in mind if you can't squeeze everything you need/want into the remaining memory.
  • T ChapT Chap Posts: 4,223
    edited 2013-12-08 21:51
    I should restate the bitmap idea. I created a set of custom numbers using an app called Pixelformer., then converted the bitmaps to dat files using a tool Rayman has for conversion on rayslogic.com. I created a method to copy the bitmaps(dat files) to eeprom. Then, as the numbers are needed, they are loaded off eeprom. In other words, graphic stuff eats up memory, so if you can store the bitmaps somewhere else and only load as needed then you free up program memory. The tradeoff is speed, there is a negligible load time for reading the files off eeprom but for your case that is not a concern.

    Also, try creating a single method for the waitcnts like this, see if this saves a few longs:
    PUB W(dv)
          waitcnt(cnt+clkfreq/dv)
    
  • WBA ConsultingWBA Consulting Posts: 2,934
    edited 2013-12-08 22:02
    T Chap, Thanks, that does make more sense. I doubt I will go that route since the learning curve will be too great for the next 5 days I have. :blank:

    Duane, Yeah, I had thought of that. I could use my Prop Activity Board for the audio and XB then use the PropBOE for the video. I hope I don't have to go that route as that adds more time, more testing, etc. I may try to complete everything but the video display to get it "done" then try to add the video.
  • potatoheadpotatohead Posts: 10,261
    edited 2013-12-08 22:04
    WBA Consulting

    You don't need all the colors array longs. If you are only using 4 screen colors, then you can cut that array down to just one long, if you want to. How it works is each tile gets a 4 color palette. The 64 longs represent 64 possible 4 color palettes for the tiles. Maybe keep two longs, and you could use 8 colors, if you want to, etc...

    In my signature, I've got a link there "Parallax Colors Simplified" and it applies to this tile type driver you are using. There are methods in there to set the screen colors, show how the color array is used, etc...

    This code sets all the palette entries to the same 4 colors.

    BTW, once you have done this, you can then change those 4 colors dynamically and the entire screen changes. You can set one to black, or your background color for example. Say color 00 = black. Say color 01 = red, but you want to draw a lot of stuff, then have it pop onto the screen. Set color 01 = black, draw it all, then set it to red. Everything will appear all at once.
      'init colors   
        repeat i from 0 to 63     
           colors[i] := $28_48_FF_00 ' teal, purple, white, black
    

    You want:
      'init colors     
         colors[0] := $28_48_FF_00 ' teal, purple, white, black
    

    Then you want all the tiles assigned to the same palette entry!

    (more in a minute)

    I'm having trouble pasting into a code window on this Mac.

    Just know that this code:
        'init tile screen   repeat dx from 0 to vga_hc - 1
        repeat dy from 0 to vga_vc - 1
          screen[dy * vga_hc + dx] := bitmapAddr >> 6 + dy + dx * vga_vc '+ ((dy & $3F) << 10)
    
    

    Initializes all the tiles. Each tile points to a little region of HUB RAM, and each tile references one of those color palettes. That complex bit of code assigns lots of color palettes. This is undesirable when using a 4 color screen.

    Use the methods in the programs you find in my signature to see how the tile address and color palette get defined and then define all your tiles to the same screen layout, but make sure they all point to just one color entry and you save those longs. If you change the variable names and color definitions, they should work with this driver you are using.

    Edit: Looks like you are already running single buffer on that one.

    That means the 3072 longs are needed for the 256x192 screen. If you want some savings, you could get rid of a row or two of tiles in the "X" direction. Each tile is 16 pixels wide, and each row removed will recover 768 bytes for you.

    Remove one row, and you've got a 240 pixel display. Compensate by increasing the vgaparams to better center the tiles on the display. I can't run this right now, or I would.

    These also can't be in the upper 64K. The VGA driver needs them in the HUB.

    Between those two things, you should be able to cram things in next to the video.

    More savings is possible. If you need it, let me know, but the next thing to do is play tricks with the tiles. Say you have blank areas on the screen. Those can be mapped to the SAME HUB RAM bytes allowing for creative screen arrangements using less HUB RAM. It's possible to make little regions too. The techniques are in the commented graphics_demo.spin in my signature.
  • T ChapT Chap Posts: 4,223
    edited 2013-12-08 22:32
    Or you could add a VGA graphics board to your system.

    http://rayslogic.com/Propeller/Products/VgaGraphics/VgaGraphics.htm
  • WBA ConsultingWBA Consulting Posts: 2,934
    edited 2013-12-08 23:16
    Potatohead, thanks for the explanations, I think I am grasping most of it. I changed the code for the COLORS declaration and palette definition and that saved me 63 longs. However, I don't quite understand your statements about directing the tiles to the single palette. I don't see where the palettes are referenced in this code:
      'init tile screen
      repeat dx from 0 to vga_hc - 1
        repeat dy from 0 to vga_vc - 1
          screen[dy * vga_hc + dx] := bitmapAddr >> 6 + dy + dx * vga_vc
    
  • MagIO2MagIO2 Posts: 2,243
    edited 2013-12-08 23:16
    I don't know the V2-WAV_DACEngine, but you can move the PASM part of VGA, graphics and the DACEngine (if it has a PASM part) into upper EEPROM. You need a load-buffer of 2kB for loading the PASM code and start it, but after starting all 3 drivers you can use that buffer for VGA. If I remember right there should be some code examples in my bolgs.
    For 3 drivers eating up a good amount of COG-RAM this saves up to 6kB.

    A quick and dirty solution would be to move the PASM code of all 3 drivers into one big SPIN-file. Having the PASM code in a row allows to reuse this DAT sections a screen-buffer after loading into COGs.
  • potatoheadpotatohead Posts: 10,261
    edited 2013-12-08 23:33
    Notice how the tiles have to be on 64 byte boundaries?

    The reason is both the color palette array index number, and the HUB memory address for the pixel data in that tile are encoded into the screen word associated with each tile.

    The lower 10 bits for each tile in the screen array point to a 64 byte aligned HUB memory address. That is where the actual pixels are. The upper 6 bits point to an entry in the colors array, and that is where the colors of those pixels are.

    You want those to be zero and that equals "colors[0]"
      'init tile screen  "The Screen Array"
      {
      This bit of code, writes the hub screen memory address pointers for each tile on the screen.
      Each tile = 64 bytes, or 16 longs.  Tiles are 16 pixels, 2 bits per pixel for a total of 1 long wide, and
      16 pixels high.  Tiles are numbered (0,0) at the upper right, incrementing horizontally, then down to
      reach the limits of x_tiles and y tiles as given above.
    
      The lower 10 bits of each screen address entry contain the address where the pixels for that tile are
      contained in the HUB.
    
      The upper 6 bits of each screen address entry contain the pointer to the color palette for that tile.
    
      Again, these lists are used by the TV driver to know where in the hub the picture is, and what colors it has.
    
      }
      repeat dx from 0 to tv_hc - 1
        repeat dy from 0 to tv_vc - 1
          screen[dy * tv_hc + dx] := display_base >> 6 + dy + dx * tv_vc '+ ((dy & $3F) << 10)
    
      'I've commented out the original Parallax color scheme, which means all tiles are referencing
      'Color Palette entry 0, which is black, dark green, light green background, and white, just to
      'show how the tile color palettes work.
    
  • potatoheadpotatohead Posts: 10,261
    edited 2013-12-08 23:38
    Hold on a moment! It's not the same. I have led you slightly astray. Didn't see the commented out part on first read of your original post.

    Reading...

    In your original post:
     'init tile screen
      repeat dx from 0 to vga_hc - 1
        repeat dy from 0 to vga_vc - 1
          screen[dy * vga_hc + dx] := bitmapAddr >> 6 + dy + dx * vga_vc [B]'+ ((dy & $3F) << 10)[/B]
    

    You've got it commented out already! All tiles should point to colors[0] now.

    This is the piece that does the funky palette assignments:
    '+ ((dy & $3F) << 10)

    So you should be able to cut the colors array back and have it work. Is that not the case?

    Assuming it is, we can move on to shaving some pixels off in the X direction, if you need another 700-1400 bytes.
  • WBA ConsultingWBA Consulting Posts: 2,934
    edited 2013-12-08 23:47
    Funny, I had thought about that and meant to ask because when I first started playing with the BIG VGA FONT code, I could not get anything other than 4 colors. That makes sense as to why now. So, I gained 63 longs, but can't gain anymore since they are already pointed to the single palette, correct?


    I also started looking into the WAV code out of curiosity. It's quite a bit over my head, but I see a lot of error handling for unsupported files that I won't need. At a quick swipe at removing the error handling in that code, I freed up 154 longs. I think I am learning some tricks to get where I need to be!
  • potatoheadpotatohead Posts: 10,261
    edited 2013-12-09 00:04
    Correct. We just kind of reviewed things instead of really saving anything. But now we are both fresh on how that driver works apparently.

    What does your display look like? Do the numbers and such consume all of it, or just some of it? I'm thinking we can take a strip off the X at a minimum. 240 pixels is very similar to the 256 pixels you have now. That's good for 700 bytes, if needed.

    I'm going to check out here in a minute, but here is what you do:

    First, subtract one from the number of tiles in the X direction:
    CON
    
      _clkmode = xtal1 + pll16x
      _xinfreq = 5_000_000
    
        x_tiles = 16-1 ' = 15 = 240 pixels now
        y_tiles = 12
    
    

    Then resize your bitmap:
    VAR
      long  bitmap[3072+64 - (y_tiles*64)  ] ' Must be aligned on 32 byte boundary
      'each tile is 64 bytes 16 pixels = 4 bytes = 1 long * 16 vertical rows
      'stripping one tile off the X direction, saves Y_tiles * 64 bytes
    
      long  colors[0]
      word  screen[x_tiles * y_tiles] 'BTW, you save some words here too
    

    Then in your StartVGA, adjust the graphics setup so that the graphics commands do the right thing in the right place.
      'start and setup graphics
      gr.start
      gr.setup(16-1, 12, 128-8, 96, bitmapAddr) 'adjust center of screen to work for a 240 pixel display and one less tile
    

    You might adjust where you put things. I don't know, didn't check.

    Finally, you might want to fiddle with the offsets and scale factors found in:
    vgaparams               long    0               'status
                            long    1               'enable
                            long    1_111        'pins
                            long    11           'mode
    vga_videobase           long    0               'videobase
    vga_colorbase           long    0               'colorbase
    vga_hc                  long    x_tiles         'hc
    vga_vc                  long    y_tiles         'vc
                            long    2               'hx        //RJA increased from 1X to 2X
                            long    2               'vx        //RJA increased from 1X to 2X 
                            long    0               'ho
                            long    0               'vo
                            long    512             'hd
                            long    16              'hf
                            long    96              'hs
                            long    48              'hb
                            long    380+16          'vd         //RJA added 16
                            long    11              'vf
                            long    2               'vs
                            long    31+16           'vb       //RJA subtracted 16
                            long    20_000_000      'rate
    

    Sadly, it's been a while since I ran this driver. I think you want the xo, yo parameters to offset the display somewhere acceptable, but I'm not sure. Maybe others are needed too. If I were you, I would draw a big rectangle around the outside edge, see where it all is and fiddle with those, until it's somewhere in the center of your display. Then remove those commands.

    Repeat with another strip off the X direction, if you really need to.

    If you need more beyond that, we are going to have to exchange info about what your display looks like, or maybe I can run it, or something. If there are blank areas, we can shave off 64 bytes per blank area that is never drawn into, by assigning the tiles in creative ways and then running gr.setup multiple times... Hopefully, it won't go there. :)
  • MagIO2MagIO2 Posts: 2,243
    edited 2013-12-09 00:15
    Am I on the ignore-list? Merging all drivers in one file, reusing the PASM DAT sections as bitmap is not a big deal saving up to 6kB with no big efford ... 10 times more than the 150 longs saved so far ... well ... I told you ;o)
  • WBA ConsultingWBA Consulting Posts: 2,934
    edited 2013-12-09 00:24
    potatohead, thanks for all your help, but I agree, hopefully we won't have to get into individually tweaked tiles. I do have some dead space that could be sacrificed if necessary. I will see about getting a picture of the screen tomorrow so you can see what I have going on. However, between the easy trimming and BST's optimization, I hope I can avoid it.

    Since my laptop just went to sleep due to the battery, I guess I should call it a night as well. Had to plug it in so I could resume windows to finish typing this post, lol. I will keep working on this tomorrow at lunchtime.
  • WBA ConsultingWBA Consulting Posts: 2,934
    edited 2013-12-09 00:26
    MagIO2, nope, I got your comments and was digesting them. I did look at the DAT sections of the different objects and see what you mean about optimizing. However, I think I might be getting in over my abilities going that route. I can handle code tweaks and trimming, but restructuring might take me a bit to prevent damage. Didn't mean to leave you out, just hadn't caught up to your train of thought. :thumb:
  • potatoheadpotatohead Posts: 10,261
    edited 2013-12-09 01:18
    Yeah, he's right. If it comes to that, we can just put some tiles down there. I just went for the question, and it's good to know how the driver works to do that anyway. Late night here. :)
  • MagIO2MagIO2 Posts: 2,243
    edited 2013-12-09 02:24
    The quick and dirty solution means:
    Open all 3 driver files and copy all the code into one new file.
    Tweaks needed are:
    Rename SPIN-functions and variables which have the same name - probably start and stop. Simply make it startVGA, startGraph & startDAC...
    Make sure that you put all PASM DAT sections in a row to give you a continuous block of bytes which then can be reused by VGA as a bitmap- and screen-buffer.
    Tweak here is to start VGA as the last driver and to clean the DAT section to avoid seeing too much garbage on the screen.

    Being optimistic means that this is all you have to do. It has to be checked weather the graphics driver is fine when started after the VGA driver, but in theory I don't see a reason why not.
  • potatoheadpotatohead Posts: 10,261
    edited 2013-12-09 09:16
    Oh that's gonna work. This driver pair is not a lot different from the TV + graphics pair, and I think it's the exact same graphics COG anyway. You can actually just run the graphics COG stand alone if you want to.

    Then you use the startcog label mod 64 + 64 as your start of bitmap screen.
  • RaymanRayman Posts: 14,662
    edited 2013-12-09 11:01
    I was going to suggest using a 2X stretch on the screen to reduce the pixel count.
    But, I see you've already done that. Actually, I see my initials in there on that change...

    You could maybe go 4X and further reduce the pixel count, but then it might get too pixelated...

    I'd try replacing the wav code with FSRW and my wav player...
    Might not have as many features as Kye's code, but I think it's much smaller...
  • WBA ConsultingWBA Consulting Posts: 2,934
    edited 2013-12-09 14:24
    Potatohead/MagIO2, thanks for the added info. I am hoping to avoid going that far, but it does interest me because another one of my backburner projects will utilize VGA graphics, XB, and a user interface, but will also need better graphics than what I am doing for this project. I may need the space if I use a better VGA driver.

    Rayman, You are right. Using your WAV player for 16 bit mono, I will gain another 507 longs. I don't need stereo as long as the mono output to be left and right. The WAV player only needs to be able to play the WAV file. No other options needed at all. (IE: volume, error handling, etc)
  • RaymanRayman Posts: 14,662
    edited 2013-12-09 16:43
    There are some minimal versions of FSRW around too. I think that would save some space too.
  • WBA ConsultingWBA Consulting Posts: 2,934
    edited 2013-12-11 15:59
    I made some updates last night and during lunch today. I converted all of my delays into calls to two different delay methods which cut back some space. For my "jump year" code, I ended up making the following method that should work well for all of the jumps which will save a ton of space.
    PUB Jumpyear(depyear, arryear, j, delayadj) | i, TimeBase, OneMS, jumptime
    
      wav.play(string("SFX.wav"))               ' Play 24 second long "time jump" sound effect
      WAITL(2)                                  'waitcnt(cnt+clkfreq*2)                 ' Let SFX get going
      JUMPSTANDBY                               ' Show time machine activation/standby display
      WAITL(2)                                  'waitcnt(cnt+clkfreq*2)                 ' and leave up for 2 seconds before counting
        
    ' Count from present year to jump year
    
      OneMS := clkfreq / 1000 'Calculate cycles per 1 millisecond
      jumptime := ||depyear - arryear                ' get difference in years
      jumptime := 20000//jumptime                    ' determine steps needed for inside 20 seconds
      jumptime := jumptime**OneMs                    ' convert steps into miliseconds
    
       TimeBase := cnt 'Get current count   
       Repeat i from depyear to arryear step j
            num2str(i)
            gr.textmode(9,9,6,5)
            gr.colorwidth(1,3)
            gr.text(0,10,@numStr)
            waitcnt(TimeBase += jumptime)            ' Wait to start of next timeframe
            gr.colorwidth(0,8)
            gr.box(-120,-30,240,81)
            
    ' Flash current year
       repeat 8
          gr.colorwidth(0,8)
          gr.box(-120,-30,240,81)
          WAITS(4)                                          'waitcnt(cnt+clkfreq/4)
          gr.textmode(9,9,6,5)
          gr.colorwidth(1,8) 
          gr.text(0,10,@numStr)
          WAITL(1)                                          'waitcnt(cnt+clkfreq)
    
    
    

    If I convert my delays to mS, I can use a single method, so I may do that before my code gets too far out of hand. I also starting noticing that much of my calls to the Graphics object account to less than 10 different types. I can probably convert those to method calls instead of individual code segments to clean up the code structure.

    Still have a lot of work to do before Saturday morning. I am sure that I will be out of midnight oil over the next couple nights.

    As for the questions about the display, here is what it looks like when at a particular year. There is some black space, but not at the top or bottom edges (my widescreen monitor at my desk makes it appear otherwise however). I think with all my other code condensing, I will not need to cut back the VGA code anymore. BST has made a big difference in compiling for size.
    1011 x 612 - 83K
  • WBA ConsultingWBA Consulting Posts: 2,934
    edited 2013-12-11 17:50
    Still wasn't happy with it so I converted it to use milliseconds. Made a world of difference on the timing. Here is my new jumpyear code:
    PUB Jumpyear(depyear, arryear, j, delayadj) | i, TimeBase, OneMS, jumptime
    
      OneMS := clkfreq / 1000 'Calculate cycles per 1 millisecond 
    
      wav.play(string("SFX.wav"))               ' Play 24 second long "time jump" sound effect
      WAITL(2)                                  'waitcnt(cnt+clkfreq*2)                 ' Let SFX get going
      JUMPSTANDBY                               ' Show time machine activation/standby display
      WAITL(2)                                  'waitcnt(cnt+clkfreq*2)                 ' and leave up for 2 seconds before counting
        
    ' Count from present year to jump year
    
    
       Repeat i from depyear to arryear step j
            num2str(i)
            gr.textmode(9,9,6,5)
            gr.colorwidth(1,3)
            gr.text(0,10,@numStr)
    '        WAITL(delayadj*OneMS)
            WAITMS(delayadj)                                
            gr.colorwidth(0,8)
            gr.box(-120,-30,240,81)
            
    ' Flash current year
       repeat 8
          gr.colorwidth(0,8)
          gr.box(-120,-30,240,81)
          WAITS(4)                                          'waitcnt(cnt+clkfreq/4)
          gr.textmode(9,9,6,5)
          gr.colorwidth(1,8)
          num2str(arryear) 
          gr.text(0,10,@numStr)
          WAITL(1)                                          'waitcnt(cnt+clkfreq)
    


    To jump from 2013 to 1978 I call this:
       JUMPYEAR(2013, 1978, 1, 300) 
    

    The 300 ms delay between counting years makes it last 12 seconds which finishes at the loud whoosh sound in the sound effect (like coming to a stop in a time machine, lol)
Sign In or Register to comment.