News:

Printed Amstrad Addict magazine announced, check it out here!

Main Menu
avatar_johnlobo

CPCtelera - png to screen

Started by johnlobo, 15:37, 20 August 20

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

johnlobo

Hi,

Maybe a silly question, but  I don't know how to solve it.

I'm trying to load into screen a .png file using the image conversion options in CPCtelera...


$(eval $(call IMG2SP, SET_MODE        , 0                  ))
$(eval $(call IMG2SP, SET_FOLDER      , src/screen               ))
$(eval $(call IMG2SP, SET_IMG_FORMAT  , screen            ))
$(eval $(call IMG2SP, SET_OUTPUT      , c                  ))
$(eval $(call IMG2SP, SET_PALETTE_FW  , $(PALETTE)         ))
$(eval $(call IMG2SP, CONVERT         , assets/screen/screen_dump.png , 160, 200, bg_sd, palette, ))


The size of a mode 0 cpc screen is 160x200 pixels, and that's the size of the png image. After the image convertion process, I get a constant array of 80x200 bytes => 16.000 bytes.

To load this array into screen I use something like this...


void main(void) {
   cpct_disableFirmware();
   cpct_setVideoMode(0);
   cpct_setPalette(palette, 16);

   cpct_memcpy(0xc000, &bg_sd,16000);

   // Loop forever
   while (1);
}


The original image is screen_dump, and the image shown in the cpc is screen_dump-CPC
As you can see the image in the CPC screen is not complete, the last line of the 8x8 character in the lower part of the screen is not filled.
I'm guessing that this anomaly has to do with the size of the screen that is not 16.000 bytes (80x200), but 16.384 bytes, but I don't know how to solve it, because the generated data is just 16.000 bytes.

Any help??
Thanks in advance.

SpDizzy

#1
Much more efficient way to solve this, is to SET_OUTPUT that screen_dump.png as a '.bin' file instead of 'c' file, to then be compressed with compression.mk. After that, you just need to uncompress to VMEM_END (0xFFFF), and that's it. And as a bonus you will save a bunch of really needed bytes thanks to that compression.
So, you just need to change this line as output file:
$(eval $(call IMG2SP, SET_OUTPUT      , c                  ))
to this:
$(eval $(call IMG2SP, SET_OUTPUT      , bin       )) 
And add this in compression.mk to create a compressed pack from your screen:
$(eval $(call ADD2PACK,bg_sd_pack, src/spritesComp/bg_sd.bin))

$(eval $(call PACKZX7B,bg_sd_pack, src/spritesComp/))

Now for the drawing, just use directly VMEM as a decompression buffer, taking into account Zx7b compressor (integrated with CPCTelera) compress data backwards, so...
#define DECOMPRESS_VMEM_END     0xFFFF

cpct_zx7b_decrunch_s((u8*) DECOMPRESS_VMEM_END, bg_sd_pack_end);

And that's it. Hope it will help with your problem.


johnlobo

Cool !! This works.

Then, my guess is that the conversion is not working perfectly fine using screen format and c output. The bin file works because it is exactly 16384 bytes. If the c constant generated in the c conversion would have been 16384 bytes, insetad of 16.000 bytes, there would be no lines left when showing it to screen with memcpy.

Anyway your method is much more efficient, as you mentioned.

Thank you very much for your help.
Regards.

SpDizzy


Great! Glad to hear it was of any help.

Please, for an in-dept explanation of this, and many other CPCTelera funcionalities take a look at the magnificient Youtube video series from Fran Gallego (aka @ronaldo , aka Profesor Retroman) from Alicante University.

Pure gold mine.

In concrete, compression is threated on this video:

Compresión de Binarios e Imágenes en CPCTelera


Enjoy ;)

Otto

Quote from: johnlobo on 15:37, 20 August 20
The size of a mode 0 cpc screen is 160x200 pixels, and that's the size of the png image. After the image convertion process, I get a constant array of 80x200 bytes => 16.000 bytes.
One question hasn't been answered yet:

Where's the missing 384 Bytes (16,000 and 16,384) ?

Every CPC mode (0, 1, and 2) has 80 bytes per raster-line and there's 200 such raster-lines. So this would indeed give 80×200 = 16,000 Bytes to fill a screen.

However screen sizes are 2¹⁴ = 16,384 Bytes (&4000) "it seems".

Like my little attached BASIC programm shows, where 16,000 bytes are filled and clearly, in the end, we see the missing 384 bytes at the bottom: 4.8 lines missing (=384/80).

So where does the CPC's video chip put these "hidden" 384 bytes? I am at the loss here.

andycadley

The CPC screen isn't contiguous. There are 2000 characters on the screen, but each scanline starts 2048 bytes after the previous one. So at the end of each line, so there are "holes" that effectively exist off screen. As the screen scrolls these areas are moved into the usable screen area, which is why the video hardware "reserves" the entire 16K, despite not using it all.

SpDizzy

Well, thats because particular vídeo memory layout, thought to be used as characters. The missing 384 bytes are in fact present, but not visible: they are know as spare vídeo memory, being used mainly for scrolling capabilities.A standard vídeo memory layout starts at address 0xC000 and end at 0xFFFF. That screen has 25 character lines (each one with 8 pixel lines), AND a spare zone of 48 bytes after line 25. 48 x 8 = 384 bytes

Powered by SMFPacks Menu Editor Mod