Shop OBEX P1 Docs P2 Docs Learn Events
P2 HDMI splash screen then text mode — Parallax Forums

P2 HDMI splash screen then text mode

Brian_BBrian_B Posts: 841
edited 2024-04-30 14:07 in PASM2/Spin2 (P2)

Is anyone working on code that can display a BMP to HDMI and then change to display active data? I've included the HDMI demo BMP code and it doesn't leave much room for to much more code in memory after loading the BMP.

I see the BMP file is comment out as I was seeing how much memory it used.

Thanks for any information.

Comments

  • You're going to need to reduce the number of bits per pixel. It looks like the image could be edited to only 4 colors. (2 bpp) If you found a tool to generate a 4 bpp bmp file then it might be easy to modify the P2 code to run 4 bpp instead of 8 bpp. I tried GIMP and ImageMagick without success. I thought ImageMagick did it, but it just turned on RLE compression :(

    Rayman has worked with color cell compression, which reduces the bits per pixel significantly but also allows the palette to change throughout the image. It's not that bad for photorealistic images. The code outputs to VGA, but I don't think there is any reason it couldn't be modified to work with HDMI. https://forums.parallax.com/discussion/175755/color-cell-image-cc4-display-code-and-encoding-tool

    Another possibility is to dice the image up into little squares the same size as the font. Then add these as "special characters" in the bitmapped font. Hopefully there would be a significant number of redundant blocks.

  • evanhevanh Posts: 15,274

    There is the option, instead of compiling the picture into the binary, of loading it from SD card at runtime.

  • RaymanRayman Posts: 14,033

    Or, use the new flash file system?

  • ke4pjwke4pjw Posts: 1,084

    @evanh said:
    There is the option, instead of compiling the picture into the binary, of loading it from SD card at runtime.

    This is exactly what I do for the bootup screen for my light controllers. I need a pause for the network to settle before actually booting, so while the network is settling, I load a series of frames from the SD card that displays an animation. As I recall the file is much larger than Hub Ram.

    Also as @Rayman suggests above, you can use the flash filesystem as well.

  • RaymanRayman Posts: 14,033

    I guess there is no existing text mode driver for HDMI?
    Think it'd be very easy to convert the ANSI VGA driver to HDMI and then you can do text.
    This uses almost no memory as there is no image buffer. It's a tile driver.

    Sure I've posted HDMI image code before.
    But, that requires using a huge amount of HUB RAM to store the 8bpp image.

    So, how to merge the two?
    Guess I'd not reserve the HUB RAM for the image and just load it manually into what Prop Tool would think is stack space at top of memory via USD or Flash.
    Then, when done with splash, kill that cog and fire up the ANSI HDMI driver.

  • Roger's driver can do text mode (and the rest of the kitchen sink).

    If your splash image contains large areas of solid color, you could apply some kind of RLE compression and uncompress it in real-time during scanout by way of adding such code into the video driver.

  • RaymanRayman Posts: 14,033

    @Wuerfel_21 so there’s an @rogloh code that does hdmi without psram?

  • @Rayman said:
    @Wuerfel_21 so there’s an @rogloh code that does hdmi without psram?

    yes, of course. using PSRAM is just an option.

  • roglohrogloh Posts: 5,221
    edited 2024-05-16 01:10

    @Rayman
    Take a look at p2textdriver0.93b.zip in the first post here:
    https://forums.parallax.com/discussion/170676/p2-dvi-vga-driver/p1

    That shows either VGA or DVI/HDMI output with a simple text mode. You can also of course use graphics modes instead if you setup the video driver manually using initRegion() and initDisplay() etc.

    Initially in the original version the driver could only use HUB RAM for a frame buffer, the external memory support only came later via the "mbox" parameter. Other demos you've probably seen use that capability.

  • RaymanRayman Posts: 14,033

    Ok, does this solve the OPs problem then?

  • roglohrogloh Posts: 5,221

    No, it just answers your question.

    I think the OP wants to render over the top of a BMP file but has space issues for the rest of the code as HUBRAM is primarily consumed by the BMP data. For simpler graphics one could possibly pre-process the data to use a lesser bit depth like 4bpp and draw that instead. There's nothing to stop you updating over the frame buffer in my video driver but it will obviously corrupt it. If you wanted to you could maintain the original and redraw that each time (or at least the parts corrupted by any rendered text/gfx regions being written over it).

    A while back I supplied @VonSzarvas with some graphics APIs that did that sort of thing which made it into his solar panel QuickByte demo for PSRAM and perhaps some of that stuff could be modified to use the HUB RAM instead of external memory, if there's enough space for it - there may not be if the images are too big to fit in HUB.

  • roglohrogloh Posts: 5,221

    If alternatively the OP wants to just draw an image temporarily then go into text mode completely without the BMP being shown any more- that is also possible with my drivers. You just need to setup both regions and select between them as being the first (and only) region in the list using setDisplayRegions().

    eg. something along the lines of this... somewhat incomplete/untested code but designed to give the idea

    CON
            MAXPIXELS = 640    ' configure these for your maximum supported resolution 
            MAXLINES  = 480    ' or excessive memory will be used!
    
            MINFONTHEIGHT = 6   ' set to your smallest font's height
    
            FONTHEIGHT = 16     ' set to the default font's height
            FONTWIDTH = 8       ' always 8 in this driver
            MAXROWS = (MAXLINES + (MINFONTHEIGHT-1))/MINFONTHEIGHT
            MAXCOLS = (MAXPIXELS + (FONTWIDTH-1))/FONTWIDTH
    
            LINEBUFSIZE = MAXCOLS*4   ' number of bytes required for each scan line buffer (1 pixel = 1 nibble @4bpp)
            SCREENSIZE  = MAXCOLS*MAXROWS  ' number of words in the screen buffer
    
    OBJ
            video: "p2videodrv"                  ' underlying video driver
    
    VAR
            long gfxregion[video.REGION_SIZE/4]     ' graphics region structure
            long textregion[video.REGION_SIZE/4]     ' text region structure
            long display[video.DISPLAY_SIZE/4]   ' display structure
            byte context[video.CONTEXT_SIZE]     ' context data for text region
            byte lineBuffers[LINEBUFSIZE*2]      ' space for two line buffers
            word screenbuf[SCREENSIZE]           ' screen buffer size
            long palette[256]                     ' 256 colour palette
            long basepin 
    
    PUB main()
        basepin:=24
    
    ' note: you may need to process the BMP file data first or re-order unless you use negative skews and point to end of file data for a reverse line render.
    ' also you will need to extract the palette data from the BMP file data into palette array.  The BMP header also needs to be skipped - not shown here.
    
    ' start a VGA display output, pointing it to the first (graphics) region for its display list, and auto allocate it a COG
        id := video.initDisplay(cog,        { the cogid to use (-1 = auto-allocate)
    }                       @display,       { the display structure address in HUB RAM
    }                       video.VGA,         { video output type (VGA/DVI etc)
    }                       basePin,        { base pin number (hsync pin) of DVI pin group
    }                       basePin+4,       { VSYNC pin (not used for DVI)
    }                       0,   { display flags
    }                       @lineBuffers,   { address of the consecutive two scan line buffers in HUB RAM
    }                       LINEBUFSIZE,    { size of a single scan line buffer in bytes
    }                       0,         { stock timing to use for VGA, (or pass address of created custom timing instead)
    }                       0,              { optional external memory mailbox address in HUB RAM (0=none)
    }                       video.initRegion( { setup a single text region as the display list
    }                                      @gfxregion,        { region structure address in HUB RAM
    }                                      video.LUT8,     { type of region is graphics 8bpp LUT
    }                                      0,              { size of region in scan lines (0=to end of screen)
    }                                      0,          { region specific flags (if enabled text flashes if BG colour > 7)
    }                                      @palette,       { address of default palette to be used by region
    }                                      0,          { address of default font to be used by this region
    }                                      0,     { number of scan lines in font
    }                                      @bmp,     { address of screen buffer in HUB RAM - needs offset for BMP
    }                                      0)              { link to next region, NULL = last region
    }                       )
    
    
    ' the BMP file is now displayed for 3s
        waitms(3000) 
    
    ' now create a text region here
    ' and adjust displayed region to use text mode now
        video.initRegion( { setup a single text region as the display list
    }                                      @textregion,        { region structure address in HUB RAM
    }                                      video.TEXT,     { type of region is text
    }                                      0,              { size of region in scan lines (0=to end of screen)
    }                                      0,          { region specific flags (if enabled text flashes if BG colour > 7)
    }                                      @vgapalette,       { address of default palette to be used by region
    }                                      @font,          { address of default font to be used by this region
    }                                      FONTHEIGHT,     { number of scan lines in font
    }                                      @screenbuf,     { address of screen buffer in HUB RAM
    }                                      0)              { link to next region, NULL = last region}
    
    
        setDisplayRegions(@display, @textregion)
    
    ' force a recomputation of displayed scan lines in the region based on font size and region flags
        setFont(@font, FONTHEIGHT)
    
    ' setup a text output context for the text region and then use it by default when printing
        video.initTextOutput(@context, @display, @textregion, FOREGROUND, BACKGROUND, 1, 1)   'also erase region
    
    ' now write to text region screenbuf array etc
    
    
    DAT     
            orgh
    ' a default VGA palette 
    vgapalette
                long    $00_00_00_00   ' 0 = black
                long    $00_00_AA_00   ' 1 = dark blue
                long    $00_AA_00_00   ' 2 = dark green
                long    $00_AA_AA_00   ' 3 = dark cyan
                long    $AA_00_00_00   ' 4 = dark red
                long    $AA_00_AA_00   ' 5 = dark magenta
                long    $AA_55_00_00   ' 6 = brown
                long    $AA_AA_AA_00   ' 7 = light grey
                long    $55_55_55_00   ' 8 = dark grey
                long    $55_55_FF_00   ' 9 = light blue
                long    $55_FF_55_00   '10 = light green
                long    $55_FF_FF_00   '11 = light cyan
                long    $FF_55_55_00   '12 = light red
                long    $FF_55_FF_00   '13 = light magenta
                long    $FF_FF_55_00   '14 = yellow
                long    $FF_FF_FF_00   '15 = white
    
    ' a default 16 scan line font for the P2
    font        file    "p2font16"
    
    bmp     file  "file.bmp"
    
  • RaymanRayman Posts: 14,033

    @Brian_B are u wanting to draw text on top of image?

    Think @SaucySoliton is right and this is a case where 4bpp driver would be nice. I have one but it’s ancient, from fpga days.

    8bpp might work but it’d probably take up nearly all of hub ram with not much room left for anything else…

Sign In or Register to comment.