diff --git a/src/test/kc/complex/elefont/elefont.kc b/src/test/kc/complex/elefont/elefont.kc new file mode 100644 index 000000000..c2db75afc --- /dev/null +++ b/src/test/kc/complex/elefont/elefont.kc @@ -0,0 +1,85 @@ +// Snabel Elefont Compression testing + +import "c64" +import "string" + +const byte* SCREEN = 0x0400; +const byte* ELEFONT = 0x2000; +const byte* ELEFONT2 = 0x2800; +byte[0x100] align(0x100) ELEFONT2_MAP; + +kickasm(pc ELEFONT, resource "elefont.bin" ) {{ + .var fontFile = LoadBinary("elefont.bin") + .fill fontFile.getSize(), fontFile.get(i) +}} + +void main() { + // Compress the font finding identical characters + char size = font_compress(ELEFONT, ELEFONT2, ELEFONT2_MAP); + // Show compressed font + *D018 = toD018(SCREEN, ELEFONT2); + // Clear the screen + memset(SCREEN, ELEFONT2_MAP[' '], 0x0400); + // Show the font + char* cursor = SCREEN; + char c = 0; + for(char y:0..7) { + for(char x:0..7) { + out(c++, x, y, ELEFONT2_MAP); + } + } +} + +// Show a 2x2 char on the screen at 2x2-position (x, y) using a font compress mapping +void out(char c, char x, char y, char* font_mapping) { + char* ptr = SCREEN + (unsigned int)y*80 + x*2; + ptr[0] = font_mapping[c]; + ptr[1] = font_mapping[c+0x40]; + ptr[40] = font_mapping[c+0x80]; + ptr[41] = font_mapping[c+0xc0]; +} + +// Compress a font finding identical characters +// The compressed font is put into font_compressed and the compress_mapping is updated +// so that compress_mapping[c] points to the char in font_compressed that is identical to char c in font_original +// Returns the size of the compressed font (in chars) +char font_compress(char* font_original, char* font_compressed, char* compress_mapping) { + char font_size = 0; + char* next_original = font_original; + char* next_compressed = font_compressed; + for(char i: 0..0xff) { + // Look for the char in font_compressed + char found = font_find(next_original, font_compressed, font_size); + if(found==0xff) { + // Glyph not found - create it + for(char l:0..7) + next_compressed[l] = next_original[l]; + next_compressed += 8; + found = font_size; + font_size++; + } + compress_mapping[i] = found; + next_original += 8; + } + return font_size; +} + +// Look for a glyph within a font +// Only looks at the first font_size glyphs +// Returns the index of the glyph within the font. Returns 0xff if the glyph is not found. +char font_find(char* glyph, char* font, char font_size) { + for(char i=0;i