Advertisement
Kitomas

cool bitmap font thing

Nov 9th, 2023
473
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 12.96 KB | None | 0 0
  1. #include <utils/font.hpp>
  2.  
  3.  
  4. //a modified version of https://github.com/dhepper/font8x8/blob/master/font8x8_basic.h
  5.  //here, i changed its formatting, and made 16 gradient chars between $10-$20
  6.  //(space included, which itself is a gradient value of 0)
  7. /*
  8. for an example of how chars are encoded,
  9. this is what the bits for char '3' look like in big endian:
  10.   0b00011110 (0x1E)
  11.   0b00110011 (0x33)
  12.   0b00110000 (0x30)
  13.   0b00011100 (0x1C)
  14.   0b00110000 (0x30)
  15.   0b00110011 (0x33)
  16.   0b00011110 (0x1E)
  17.   0b00000000 (0x00)
  18. */
  19. const Uint8 font8x8_default[1024] = { //128 chars of 8 bytes each = 1024 bytes
  20.   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  //$00      (null)
  21.   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  //$01      (start of heading)
  22.   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  //$02      (start of text)
  23.   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  //$03      (end of text)
  24.   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  //$04      (end of transmission)
  25.   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  //$05      (enquiry)
  26.   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  //$06      (acknowledge)
  27.   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  //$07 '\a' (bell)
  28.   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  //$08 '\b' (backspace)
  29.   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  //$09 '\t' (horizontal tab)
  30.   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  //$0A '\n' (new line)
  31.   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  //$0B '\v' (vertical tab)
  32.   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  //$0C '\f' (new page)
  33.   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  //$0D '\r' (carriage return)
  34.   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  //$0E      (shift out)
  35.   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  //$0F      (shift in)
  36.   0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,  //$10      (gradient value 16)
  37.   0xFF, 0xFF, 0xEE, 0xFF, 0xFF, 0xFF, 0xEE, 0xFF,  //$11      (gradient value 15)
  38.   0xBB, 0xFF, 0xEE, 0xFF, 0xBB, 0xFF, 0xEE, 0xFF,  //$12      (gradient value 14)
  39.   0xAA, 0xFF, 0xEE, 0xFF, 0xAA, 0xFF, 0xEE, 0xFF,  //$13      (gradient value 13)
  40.   0xAA, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF,  //$14      (gradient value 12)
  41.   0xAA, 0xDD, 0xAA, 0xDD, 0xAA, 0xDD, 0xAA, 0xDD,  //$15      (gradient value 11)
  42.   0xAA, 0xDD, 0xAA, 0x77, 0xAA, 0xDD, 0xAA, 0x77,  //$16      (gradient value 10)
  43.   0xAA, 0xDD, 0xAA, 0x55, 0xAA, 0xDD, 0xAA, 0x55,  //$17      (gradient value  9)
  44.   0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55,  //$18      (gradient value  8)
  45.   0xAA, 0x44, 0xAA, 0x55, 0xAA, 0x44, 0xAA, 0x55,  //$19      (gradient value  7)
  46.   0xAA, 0x44, 0xAA, 0x11, 0xAA, 0x44, 0xAA, 0x11,  //$1A      (gradient value  6)
  47.   0xAA, 0x44, 0xAA, 0x00, 0xAA, 0x44, 0xAA, 0x00,  //$1B      (gradient value  5)
  48.   0xAA, 0x00, 0xAA, 0x00, 0xAA, 0x00, 0xAA, 0x00,  //$1C      (gradient value  4)
  49.   0xAA, 0x00, 0x88, 0x00, 0xAA, 0x00, 0x88, 0x00,  //$1D      (gradient value  3)
  50.   0x22, 0x00, 0x88, 0x00, 0x22, 0x00, 0x88, 0x00,  //$1E      (gradient value  2)
  51.   0x00, 0x00, 0x88, 0x00, 0x00, 0x00, 0x88, 0x00,  //$1F      (gradient value  1)
  52.   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  //$20  ' ' (gradient value  0)
  53.   0x18, 0x3C, 0x3C, 0x18, 0x18, 0x00, 0x18, 0x00,  //$21  '!'
  54.   0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  //$22  '"' (use \" if inside string)
  55.   0x36, 0x36, 0x7F, 0x36, 0x7F, 0x36, 0x36, 0x00,  //$23  '#'
  56.   0x0C, 0x3E, 0x03, 0x1E, 0x30, 0x1F, 0x0C, 0x00,  //$24  '$'
  57.   0x00, 0x63, 0x33, 0x18, 0x0C, 0x66, 0x63, 0x00,  //$25  '%'
  58.   0x1C, 0x36, 0x1C, 0x6E, 0x3B, 0x33, 0x6E, 0x00,  //$26  '&'
  59.   0x06, 0x06, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,  //$27 '\'' (use ' if outside char literal)
  60.   0x18, 0x0C, 0x06, 0x06, 0x06, 0x0C, 0x18, 0x00,  //$28  '('
  61.   0x06, 0x0C, 0x18, 0x18, 0x18, 0x0C, 0x06, 0x00,  //$29  ')'
  62.   0x00, 0x66, 0x3C, 0xFF, 0x3C, 0x66, 0x00, 0x00,  //$2A  '*'
  63.   0x00, 0x0C, 0x0C, 0x3F, 0x0C, 0x0C, 0x00, 0x00,  //$2B  '+'
  64.   0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x0C, 0x06,  //$2C  ','
  65.   0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x00,  //$2D  '-'
  66.   0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x0C, 0x00,  //$2E  '.'
  67.   0x60, 0x30, 0x18, 0x0C, 0x06, 0x03, 0x01, 0x00,  //$2F  '/'
  68.   0x3E, 0x63, 0x73, 0x7B, 0x6F, 0x67, 0x3E, 0x00,  //$30  '0'
  69.   0x0C, 0x0E, 0x0C, 0x0C, 0x0C, 0x0C, 0x3F, 0x00,  //$31  '1'
  70.   0x1E, 0x33, 0x30, 0x1C, 0x06, 0x33, 0x3F, 0x00,  //$32  '2'
  71.   0x1E, 0x33, 0x30, 0x1C, 0x30, 0x33, 0x1E, 0x00,  //$33  '3'
  72.   0x38, 0x3C, 0x36, 0x33, 0x7F, 0x30, 0x78, 0x00,  //$34  '4'
  73.   0x3F, 0x03, 0x1F, 0x30, 0x30, 0x33, 0x1E, 0x00,  //$35  '5'
  74.   0x1C, 0x06, 0x03, 0x1F, 0x33, 0x33, 0x1E, 0x00,  //$36  '6'
  75.   0x3F, 0x33, 0x30, 0x18, 0x0C, 0x0C, 0x0C, 0x00,  //$37  '7'
  76.   0x1E, 0x33, 0x33, 0x1E, 0x33, 0x33, 0x1E, 0x00,  //$38  '8'
  77.   0x1E, 0x33, 0x33, 0x3E, 0x30, 0x18, 0x0E, 0x00,  //$39  '9'
  78.   0x00, 0x0C, 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0x00,  //$3A  ':'
  79.   0x00, 0x0C, 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0x06,  //$3B  ';'
  80.   0x18, 0x0C, 0x06, 0x03, 0x06, 0x0C, 0x18, 0x00,  //$3C  '<'
  81.   0x00, 0x00, 0x3F, 0x00, 0x00, 0x3F, 0x00, 0x00,  //$3D  '='
  82.   0x06, 0x0C, 0x18, 0x30, 0x18, 0x0C, 0x06, 0x00,  //$3E  '>'
  83.   0x1E, 0x33, 0x30, 0x18, 0x0C, 0x00, 0x0C, 0x00,  //$3F  '?' (or \? to avoid trigraphs)
  84.   0x3E, 0x63, 0x7B, 0x7B, 0x7B, 0x03, 0x1E, 0x00,  //$40  '@'
  85.   0x0C, 0x1E, 0x33, 0x33, 0x3F, 0x33, 0x33, 0x00,  //$41  'A'
  86.   0x3F, 0x66, 0x66, 0x3E, 0x66, 0x66, 0x3F, 0x00,  //$42  'B'
  87.   0x3C, 0x66, 0x03, 0x03, 0x03, 0x66, 0x3C, 0x00,  //$43  'C'
  88.   0x1F, 0x36, 0x66, 0x66, 0x66, 0x36, 0x1F, 0x00,  //$44  'D'
  89.   0x7F, 0x46, 0x16, 0x1E, 0x16, 0x46, 0x7F, 0x00,  //$45  'E'
  90.   0x7F, 0x46, 0x16, 0x1E, 0x16, 0x06, 0x0F, 0x00,  //$46  'F'
  91.   0x3C, 0x66, 0x03, 0x03, 0x73, 0x66, 0x7C, 0x00,  //$47  'G'
  92.   0x33, 0x33, 0x33, 0x3F, 0x33, 0x33, 0x33, 0x00,  //$48  'H'
  93.   0x1E, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00,  //$49  'I'
  94.   0x78, 0x30, 0x30, 0x30, 0x33, 0x33, 0x1E, 0x00,  //$4A  'J'
  95.   0x67, 0x66, 0x36, 0x1E, 0x36, 0x66, 0x67, 0x00,  //$4B  'K'
  96.   0x0F, 0x06, 0x06, 0x06, 0x46, 0x66, 0x7F, 0x00,  //$4C  'L'
  97.   0x63, 0x77, 0x7F, 0x7F, 0x6B, 0x63, 0x63, 0x00,  //$4D  'M'
  98.   0x63, 0x67, 0x6F, 0x7B, 0x73, 0x63, 0x63, 0x00,  //$4E  'N'
  99.   0x1C, 0x36, 0x63, 0x63, 0x63, 0x36, 0x1C, 0x00,  //$4F  'O'
  100.   0x3F, 0x66, 0x66, 0x3E, 0x06, 0x06, 0x0F, 0x00,  //$50  'P'
  101.   0x1E, 0x33, 0x33, 0x33, 0x3B, 0x1E, 0x38, 0x00,  //$51  'Q'
  102.   0x3F, 0x66, 0x66, 0x3E, 0x36, 0x66, 0x67, 0x00,  //$52  'R'
  103.   0x1E, 0x33, 0x07, 0x0E, 0x38, 0x33, 0x1E, 0x00,  //$53  'S'
  104.   0x3F, 0x2D, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00,  //$54  'T'
  105.   0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x3F, 0x00,  //$55  'U'
  106.   0x33, 0x33, 0x33, 0x33, 0x33, 0x1E, 0x0C, 0x00,  //$56  'V'
  107.   0x63, 0x63, 0x63, 0x6B, 0x7F, 0x77, 0x63, 0x00,  //$57  'W'
  108.   0x63, 0x63, 0x36, 0x1C, 0x1C, 0x36, 0x63, 0x00,  //$58  'X'
  109.   0x33, 0x33, 0x33, 0x1E, 0x0C, 0x0C, 0x1E, 0x00,  //$59  'Y'
  110.   0x7F, 0x63, 0x31, 0x18, 0x4C, 0x66, 0x7F, 0x00,  //$5A  'Z'
  111.   0x1E, 0x06, 0x06, 0x06, 0x06, 0x06, 0x1E, 0x00,  //$5B  '['
  112.   0x03, 0x06, 0x0C, 0x18, 0x30, 0x60, 0x40, 0x00,  //$5C '\\'
  113.   0x1E, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1E, 0x00,  //$5D  ']'
  114.   0x08, 0x1C, 0x36, 0x63, 0x00, 0x00, 0x00, 0x00,  //$5E  '^'
  115.   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,  //$5F  '_'
  116.   0x0C, 0x0C, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00,  //$60  '`'
  117.   0x00, 0x00, 0x1E, 0x30, 0x3E, 0x33, 0x6E, 0x00,  //$61  'a'
  118.   0x07, 0x06, 0x06, 0x3E, 0x66, 0x66, 0x3B, 0x00,  //$62  'b'
  119.   0x00, 0x00, 0x1E, 0x33, 0x03, 0x33, 0x1E, 0x00,  //$63  'c'
  120.   0x38, 0x30, 0x30, 0x3e, 0x33, 0x33, 0x6E, 0x00,  //$64  'd'
  121.   0x00, 0x00, 0x1E, 0x33, 0x3f, 0x03, 0x1E, 0x00,  //$65  'e'
  122.   0x1C, 0x36, 0x06, 0x0f, 0x06, 0x06, 0x0F, 0x00,  //$66  'f'
  123.   0x00, 0x00, 0x6E, 0x33, 0x33, 0x3E, 0x30, 0x1F,  //$67  'g'
  124.   0x07, 0x06, 0x36, 0x6E, 0x66, 0x66, 0x67, 0x00,  //$68  'h'
  125.   0x0C, 0x00, 0x0E, 0x0C, 0x0C, 0x0C, 0x1E, 0x00,  //$69  'i'
  126.   0x30, 0x00, 0x30, 0x30, 0x30, 0x33, 0x33, 0x1E,  //$6A  'j'
  127.   0x07, 0x06, 0x66, 0x36, 0x1E, 0x36, 0x67, 0x00,  //$6B  'k'
  128.   0x0E, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00,  //$6C  'l'
  129.   0x00, 0x00, 0x33, 0x7F, 0x7F, 0x6B, 0x63, 0x00,  //$6D  'm'
  130.   0x00, 0x00, 0x1F, 0x33, 0x33, 0x33, 0x33, 0x00,  //$6E  'n'
  131.   0x00, 0x00, 0x1E, 0x33, 0x33, 0x33, 0x1E, 0x00,  //$6F  'o'
  132.   0x00, 0x00, 0x3B, 0x66, 0x66, 0x3E, 0x06, 0x0F,  //$70  'p'
  133.   0x00, 0x00, 0x6E, 0x33, 0x33, 0x3E, 0x30, 0x78,  //$71  'q'
  134.   0x00, 0x00, 0x3B, 0x6E, 0x66, 0x06, 0x0F, 0x00,  //$72  'r'
  135.   0x00, 0x00, 0x3E, 0x03, 0x1E, 0x30, 0x1F, 0x00,  //$73  's'
  136.   0x08, 0x0C, 0x3E, 0x0C, 0x0C, 0x2C, 0x18, 0x00,  //$74  't'
  137.   0x00, 0x00, 0x33, 0x33, 0x33, 0x33, 0x6E, 0x00,  //$75  'u'
  138.   0x00, 0x00, 0x33, 0x33, 0x33, 0x1E, 0x0C, 0x00,  //$76  'v'
  139.   0x00, 0x00, 0x63, 0x6B, 0x7F, 0x7F, 0x36, 0x00,  //$77  'w'
  140.   0x00, 0x00, 0x63, 0x36, 0x1C, 0x36, 0x63, 0x00,  //$78  'x'
  141.   0x00, 0x00, 0x33, 0x33, 0x33, 0x3E, 0x30, 0x1F,  //$79  'y'
  142.   0x00, 0x00, 0x3F, 0x19, 0x0C, 0x26, 0x3F, 0x00,  //$7A  'z'
  143.   0x38, 0x0C, 0x0C, 0x07, 0x0C, 0x0C, 0x38, 0x00,  //$7B  '{'
  144.   0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x00,  //$7C  '|'
  145.   0x07, 0x0C, 0x0C, 0x38, 0x0C, 0x0C, 0x07, 0x00,  //$7D  '}'
  146.   0x6E, 0x3B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  //$7E  '~'
  147.   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00   //$7F      (indicates transparency)
  148. };
  149.  
  150.  
  151.  
  152.  
  153. font8x8::font8x8(SDL_Renderer* renderer, const Uint8* table){
  154.   if(renderer == nullptr) throw "renderer == nullptr";
  155.   if(table == nullptr) throw "table == nullptr";
  156.   _renderer = renderer;
  157.  
  158.   //8-bit indexed, though only the first 2 palette colors are used
  159.    //(also, for 128 8x8 chars, a surface size of 128x64 is used)
  160.   _fontSurface = SDL_CreateRGBSurfaceWithFormat(0,128,64,8,SDL_PIXELFORMAT_INDEX8);
  161.   if(_fontSurface == nullptr){
  162.     _valid = SDL_FALSE;
  163.     throw SDL_GetError();
  164.   }
  165.  
  166.  
  167.   //generate pixel data from font data
  168.   if(SDL_LockSurface(_fontSurface)){ //make sure i have safe access to pixel data
  169.     _freeSurfaceSafely();
  170.     _valid = SDL_FALSE;
  171.     throw SDL_GetError();
  172.   }
  173.   Uint8* table_copy = (Uint8*) table; //otherwise i can't increment the pointer
  174.   Uint8* pixels = (Uint8*) _fontSurface->pixels;
  175.  
  176.   for(int yi=0; yi<64; yi+=8){ //for each char vertically
  177.     for(int xi=0; xi<128; xi+=8){ //for each char horizontally
  178.       int charPos = xi + yi*128;
  179.       for(int ri=0; ri<8; ++ri){ //for each row in current char
  180.         Uint8 row = *(table_copy++);
  181.         int rowPos = charPos + ri*128;
  182.         pixels[rowPos++] = (row>>0)&1; //each byte is a char's row (8 pixels)
  183.         pixels[rowPos++] = (row>>1)&1;
  184.         pixels[rowPos++] = (row>>2)&1;
  185.         pixels[rowPos++] = (row>>3)&1;
  186.         pixels[rowPos++] = (row>>4)&1;
  187.         pixels[rowPos++] = (row>>5)&1;
  188.         pixels[rowPos++] = (row>>6)&1;
  189.         pixels[rowPos++] = (row>>7)&1;
  190.       }
  191.     }
  192.   }
  193.  
  194.   SDL_UnlockSurface(_fontSurface); //can't error
  195.  
  196.  
  197.   //initialize palette to black and white, and create font texture
  198.   _valid = SDL_TRUE; //_valid will be set back to false if setPalette fails
  199.   setPalette( {0x00,0x00,0x00,0xFF}, {0xFF,0xFF,0xFF,0xFF} );
  200. }
  201.  
  202.  
  203.  
  204.  
  205. void font8x8::setPalette(SDL_Color background, SDL_Color text){
  206.   if(!_valid) throw "invalid font";
  207.   //the texture has be remade once the palette colors are modified
  208.   _freeTextureSafely();
  209.  
  210.   //out of the 256 possible palette colors for 8-bit indexed, i'm only using 2
  211.   _palette[0] = background;
  212.   _palette[1] = text;
  213.  
  214.  
  215.   if(SDL_LockSurface(_fontSurface)){
  216.     _freeSurfaceSafely();
  217.     _valid = SDL_FALSE;
  218.     throw SDL_GetError();
  219.   }
  220.  
  221.   //'replace 2 palette colors, starting at index 0'
  222.   if(SDL_SetPaletteColors(_fontSurface->format->palette, _palette, 0, 2)){
  223.     _freeSurfaceSafely();
  224.     _valid = SDL_FALSE;
  225.     throw SDL_GetError();
  226.   }
  227.  
  228.   SDL_UnlockSurface(_fontSurface); //can't error
  229.  
  230.  
  231.   _fontTexture = SDL_CreateTextureFromSurface(_renderer, _fontSurface);
  232.   if(_fontTexture == nullptr){
  233.     _valid = SDL_FALSE;
  234.     throw SDL_GetError();
  235.   }
  236. }
  237.  
  238.  
  239.  
  240.  
  241. void font8x8::putCharRaw(char chr, int x, int y){
  242.   if(!_valid) throw "invalid font";
  243.   //char 127 is treated as 'transparent', so don't draw anything
  244.   if((chr&=127) == 127) return;
  245.  
  246.   SDL_Rect sourceRect, destinationRect;
  247.  
  248.   //position inside the font sprite sheet thing
  249.   sourceRect.x = (chr&15)*8; //for a total of 16 columns, scaled by 8 pixels
  250.   sourceRect.y = (chr>>4)*8; //for a total of 8 rows, scaled by 8 pixels
  251.   sourceRect.w = 8; //source texture area should always be 8x8
  252.   sourceRect.h = 8;
  253.  
  254.   //position with regard to the render target (usually the window itself)
  255.   destinationRect.x = x;
  256.   destinationRect.y = y;
  257.   destinationRect.w = _scale.x;
  258.   destinationRect.h = _scale.y;
  259.  
  260.   SDL_RenderCopy(_renderer, _fontTexture, &sourceRect, &destinationRect);
  261. }
  262.  
  263.  
  264.  
  265.  
  266. void font8x8::printRaw(const std::string& txt, int x, int y){
  267.   int startX = x;
  268.   size_t length = txt.length();
  269.  
  270.   for(size_t i=0; i<length; ++i){
  271.     char chr = txt.at(i);
  272.  
  273.     if(chr == '\n'){ //on newline, reset x and move y down 1 char
  274.       x = startX;
  275.       y += _scale.y;
  276.  
  277.     } else { //otherwise draw the char normally
  278.       putCharRaw(chr, x,y);
  279.       x += _scale.x;
  280.  
  281.     }
  282.   }
  283. }
  284.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement