Mode15 (220x176x16) high resolution 16color and improved directbitmap

###mode 15

this mode is actually very small compared to others but this is mainly to send out the pixels as fast as possible
since its using the entire screen it wreaps around automatically

void Pokitto::lcdMode15(uint16_t* pal, uint8_t* scrbuf){
    write_command(0x03); write_data(0b1000000111000); //realy only need to call this once
    write_command(0x20); write_data(0x0000); 
    write_command(0x21); write_data(0x0000);
 
    write_command(0x22);
    for (int x=0; x<0x4BA0;x++) {
        write_data(pal[(((scrbuf[x]) & 0xf0) >> 4)]);
        write_data(pal[( (scrbuf[x]) & 0x0f)]);
    }
}

this needs a 19360 byte buffer which is rather large

###lcdBitmap

expanding this idea to the directBitmap which is rather slow, heres a small version for the none scaled 4bpp directBitmap alternative , its using a scan-line approach, since its focused on speed it ignores transparency.
it has a view other qwerks like wrapping around the screen but this could be used for custom draw buffers or sector screen buffers

void Pokitto::lcdBitmap(int8_t px, int8_t py,uint16_t* paletteptr, uint8_t* bitmap){
    write_command(0x03); write_data(0b1000000111000); //set screen orientation
   
	uint8_t width = bitmap[0];
    uint8_t height= bitmap[1];
    bitmap = bitmap + 2;
    uint16_t count =0;
    for(int y =0; y<height; y++){
    	//set draw position for every line
    	write_command(0x20); write_data(py+y);
    	write_command(0x21); write_data(px); 
    	write_command(0x22); //draw command
    	for (int x=0; x<width/2;x++) {
        	write_data(paletteptr[(((bitmap[count]) & 0xf0) >> 4)]);
        	write_data(paletteptr[((bitmap[count])& 0xf)]);
        	count++;
        }
    }
    //reset draw position
    write_command(0x20); write_data(0x0000); 
    write_command(0x21); write_data(0x0000);
	write_command(0x03); write_data(0x1030); //reset screen orientation
}

these are both working proposals. if anyone knows or is seeing obvious fixes please tell me
i hope this could get appended to the pokitto library, but i might need some help with adding it correctly in the library

heres a sample to compare mode15 with directBitmap (press A for mode15, press B for directBitmap)
mode15vsdirectbitmap.bin (33.0 KB)

3 Likes

Are you sure both mbed online and EmBitz support binary literals?

Binary literals are a C++14 feature.

If not then 0x1038 would be a suitable replacement.

uhm it compilerd and did not complain and i it was easer to figure out since its a bitflag comand
and i think we use it for arduboy 1bpp sprites aswell

If it compiles on both mbed and EmBitz then fair enough.

works fine on mbed atleast, i dont use windows for development so idk about EmBitz

Seems it works on EmBitz.
It’s probably a compiler extension,
but we don’t have to worry about portability so it’ll be fine.

1 Like

Binary literals courtesy of the Arduino compatibility extensions I’ve included in the core

I thought Arduino defines only covered values in the format B11001100, not 0b11001100.
(And for that matter only covered 0-255, whereas here the value 0b1000000111000 has at least 13 bits.)

so testing i spotted something odd. the text can only draw top left corner or it softlocks the program also i see theres some screen clear happening im not sure where thats coming from or how to turn it off.

im currently doing the mode15 call in the main function so idk what im suposed to do to make this a plug and play mode so to speek

i have been trying to optimise and this kinda works :confounded:
its only a small improvement not having to call the lcd cs every pixel
i pulled out the only relevant part of setup_data_16, not sure why there a variable and if in there it seems pointless atleast for this

    write_command(0x22);
    CLR_CS;
    for (int x=0; x<0x4BA0;x++) {
        SET_CD;
        SET_RD;
        SET_MASK_P2;
        LPC_GPIO_PORT->MPIN[2] = ((pal[(((scrbuf[x]) & 0xf0) >> 4)]) << 3);//insanity
        CLR_MASK_P2;
        CLR_WR;
        SET_WR;
        
        SET_CD;
        SET_RD;
        SET_MASK_P2;
        LPC_GPIO_PORT->MPIN[2] = ((pal[( (scrbuf[x]) & 0x0f)]) << 3);//insanity
        CLR_MASK_P2;
        CLR_WR;
        SET_WR;
    }
    SET_CS;

1 Like

@jonne i hope i did it correctly but i did a pull request on github for the mode

1 Like

Actually you did two PRs.
Are they both required for Mode 15 to work?

@Pharap PRs?
sorry not sure what you mean

PR = Pull Request

You made two of them:

Are both needed to add Mode 15?
If so it might be hard to test the changes.

oh sorry i guess i messed something up, i did it all in browser maybe i think they both apply

im thinking of adding quad sector pallet swaping to mode15
example with one pallet:

where the quads are:

example result:

@adekto Have you got a drawBitmap and other primitives done for this mode?

It’s supposed to re use low resmodes primitives
There’s just a bit of trouble with text wen linebreak is enabled

oh yea that might not have been defined correctly now :confused:
uhm basicly you have to enable everything from lowres mode exept for the draw and buffer size
not sure what the easyest way of doing that is

#Binary (or it didn’t happen)

mode15.bin (57.5 KB)

#example available on Github repo

#Mode15.cpp

#include "Pokitto.h" // include Pokitto library
#include "monkey16.h"

Pokitto::Core mygame; //create Pokitto application instance

void drawBlurb(const char* text, int x, int y, uint8_t fc, uint8_t bgc) {
    for (int tx=-1;tx<2;tx++) {
        for (int ty=-1;ty<2;ty++) {
            mygame.display.setColor(bgc,15);
            mygame.display.setInvisibleColor(15);
            mygame.display.setCursor(x+tx,y+ty);
            mygame.display.print(text);
        }
    }
    mygame.display.setCursor(x,y);
    mygame.display.setColor(fc,bgc);
    mygame.display.setInvisibleColor(bgc);
    mygame.display.print(text);
}


int main () {
    int x=0,y=20;
    mygame.begin(); // start the application
    mygame.display.load565Palette(monkey16_pal); //load the palette for the image
    mygame.display.setColor(1,0); // set foreground and background colors from palette
    mygame.display.setFont(fontMonkey); // choose a lovely font
    mygame.display.setInvisibleColor(0);
    /* the "while" loop runs as long as the program is running */
    while (mygame.isRunning()) {
        /* mygame.update() is processed whenever it is time to update the screen */
        if (mygame.update()) {
            x-=2;
            if (x<-90) x=-90;
            else if (x>0) x = 0;
            mygame.display.drawBitmap(x,16,monkey161);
            mygame.display.drawBitmap(x+160,16,monkey162);
            if (x<-82) {
                    drawBlurb("The New Mode15!!",10,62,14,0);
            }
            if (x<-88) {
                    drawBlurb("Nice!",130,82,10,0);
            }

        }
    }
    return 0; // this is "good programming manners". Program informs it ended without errors
}

#My_settings.h


#ifndef MY_SETTINGS_H
#define MY_SETTINGS_H

#define PROJ_MODE15 	  1     // 220x176 hires 16 color mode
#define PROJ_ENABLE_SOUND 0     // 0 = all sound functions disabled

#endif
6 Likes

Lots more optimization coming.

Also:

Monkey Island font added!

4 Likes