diff options
Diffstat (limited to 'kyra/font.cpp')
-rw-r--r-- | kyra/font.cpp | 492 |
1 files changed, 245 insertions, 247 deletions
diff --git a/kyra/font.cpp b/kyra/font.cpp index 01428f1442..6a5b44c629 100644 --- a/kyra/font.cpp +++ b/kyra/font.cpp @@ -29,301 +29,299 @@ #endif namespace Kyra { - const uint16 FontHeader_Magic1 = 0x0500; - const uint16 FontHeader_Magic2 = 0x000e; - const uint16 FontHeader_Magic3 = 0x0014; - - Font::Font(uint8* buffer, uint32 size) { - if (!buffer) { - error("resource created without data"); - } - - _buffer = buffer; - - Common::MemoryReadStream bufferstream(buffer, size); - - bufferstream.read(&_fontHeader, sizeof(_fontHeader)); - - // tests for the magic values - if(_fontHeader._magic1 != FontHeader_Magic1 || _fontHeader._magic2 != FontHeader_Magic2 || - _fontHeader._magic3 != FontHeader_Magic3) { - error("magic vars in the fontheader are corrupt\n" - "_magic1 = 0x%x, _magic2 = 0x%x, _magic3 = 0x%x", - _fontHeader._magic1, _fontHeader._magic2, _fontHeader._magic3); - } - - // init all the pointers - _offsetTable = (uint16*)&buffer[bufferstream.pos()]; - _charWidth = &buffer[_fontHeader._charWidthOffset]; - _charHeight = (uint16*)&buffer[_fontHeader._charHeightOffset]; - _charBits = &buffer[_fontHeader._charBitsOffset]; - - // now prerender =) - preRenderAllChars(bufferstream.pos()); +const uint16 FontHeader_Magic1 = 0x0500; +const uint16 FontHeader_Magic2 = 0x000e; +const uint16 FontHeader_Magic3 = 0x0014; - // This value seems to be a version or language variable - // Known Values - // ------------ - // Russian Floppy: 0x1010 - // German Floppy and English CD: 0x1011 - // Kyrandia 2 should be 0x1012 - debug("_version = 0x%x", _fontHeader._version); - - delete [] _buffer; - _buffer = 0; - _offsetTable = 0; - _charHeight = 0; - _charWidth = 0; - _charBits = 0; +Font::Font(uint8* buffer, uint32 size) { + if (!buffer) { + error("resource created without data"); } - - Font::~Font() { + _buffer = buffer; + + Common::MemoryReadStream bufferstream(buffer, size); + + bufferstream.read(&_fontHeader, sizeof(_fontHeader)); + + // tests for the magic values + if(_fontHeader._magic1 != FontHeader_Magic1 || _fontHeader._magic2 != FontHeader_Magic2 || + _fontHeader._magic3 != FontHeader_Magic3) { + error("magic vars in the fontheader are corrupt\n" + "_magic1 = 0x%x, _magic2 = 0x%x, _magic3 = 0x%x", + _fontHeader._magic1, _fontHeader._magic2, _fontHeader._magic3); } - uint32 Font::getStringWidth(const char* string, char terminator) { - uint32 strsize; - - for (strsize = 0; string[strsize] != terminator && string[strsize] != '\0'; ++strsize) - ; + // init all the pointers + _offsetTable = (uint16*)&buffer[bufferstream.pos()]; + _charWidth = &buffer[_fontHeader._charWidthOffset]; + _charHeight = (uint16*)&buffer[_fontHeader._charHeightOffset]; + _charBits = &buffer[_fontHeader._charBitsOffset]; + + // now prerender =) + preRenderAllChars(bufferstream.pos()); + + // This value seems to be a version or language variable + // Known Values + // ------------ + // Russian Floppy: 0x1010 + // German Floppy and English/German CD: 0x1011 + debug("Font::_version = 0x%x", _fontHeader._version); + + delete [] _buffer; + _buffer = 0; + _offsetTable = 0; + _charHeight = 0; + _charWidth = 0; + _charBits = 0; +} + +Font::~Font() { + // FIXME: Release memory of the prerendered chars +} + +uint32 Font::getStringWidth(const char* string, char terminator) { + uint32 strsize; - uint32 stringwidth = 0; + for (strsize = 0; string[strsize] != terminator && string[strsize] != '\0'; ++strsize) + ; - for (uint32 pos = 0; pos < strsize; ++pos) { - stringwidth += _preRenderedChars[string[pos]].width; - } + uint32 stringwidth = 0; - return stringwidth; + for (uint32 pos = 0; pos < strsize; ++pos) { + stringwidth += _preRenderedChars[string[pos]].width; } - - const uint8* Font::getChar(char c, uint8* width, uint8* height, uint8* heightadd) { - PreRenderedChar& c_ = _preRenderedChars[c]; - - *width = c_.width; - *height = c_.height; - *heightadd = c_.heightadd; - return c_.c; - } + return stringwidth; +} - // splits up the String in a word - const char* Font::getNextWord(const char* string, uint32* size) { - uint32 startpos = 0; - *size = 0; - - // gets start of the word - for (; string[startpos] == ' '; ++startpos) - ; - - // not counting size - for (*size = 0; string[startpos + *size] != ' ' && string[startpos + *size] != '\0'; ++(*size)) - ; - - ++(*size); - - return &string[startpos]; - } +const uint8* Font::getChar(char c, uint8* width, uint8* height, uint8* heightadd) { + PreRenderedChar& c_ = _preRenderedChars[c]; + + *width = c_.width; + *height = c_.height; + *heightadd = c_.heightadd; + + return c_.c; +} + +// splits up the String in a word +const char* Font::getNextWord(const char* string, uint32* size) { + uint32 startpos = 0; + *size = 0; + + // gets start of the word + for (; string[startpos] == ' '; ++startpos) + ; + + // not counting size + for (*size = 0; string[startpos + *size] != ' ' && string[startpos + *size] != '\0'; ++(*size)) + ; - // Move this to Font declaration? - struct WordChunk { - const char* _string; - uint32 _size; - }; + ++(*size); + + return &string[startpos]; +} - void Font::drawStringToPlane(const char* string, - uint8* plane, uint16 planewidth, uint16 planeheight, - uint16 x, uint16 y, uint8 color) { +// Move this to Font declaration? +struct WordChunk { + const char* _string; + uint32 _size; +}; + +void Font::drawStringToPlane(const char* string, + uint8* plane, uint16 planewidth, uint16 planeheight, + uint16 x, uint16 y, uint8 color) { - // lets do it word after word - Common::Array<WordChunk> words; - - uint32 lastPos = 0; - uint32 lastSize = 0; - uint32 strlgt = strlen(string); + // lets do it word after word + Common::Array<WordChunk> words; + + uint32 lastPos = 0; + uint32 lastSize = 0; + uint32 strlgt = strlen(string); + + while (true) { + WordChunk newchunk; + newchunk._string = getNextWord(&string[lastPos], &lastSize); + newchunk._size = lastSize; + lastPos += lastSize; + + words.push_back(newchunk); + + if (lastPos >= strlgt) + break; + } - while (true) { - WordChunk newchunk; - newchunk._string = getNextWord(&string[lastPos], &lastSize); - newchunk._size = lastSize; - - lastPos += lastSize; - - words.push_back(newchunk); + uint16 current_x = x, current_y = y; + uint8 heighest = 0; + + const uint8* src = 0; + uint8 width = 0, height = 0, heightadd = 0; + + // now the have alle of these words + for (uint32 tmp = 0; tmp < words.size(); ++tmp) { + lastSize = getStringWidth(words[tmp]._string, ' '); - if (lastPos >= strlgt) - break; + // adjust x position + if (current_x + lastSize >= planewidth) { + // hmm lets move it a bit to the left + if (current_x == x && (int16)planewidth - (int16)lastSize >= 0) { + current_x = planewidth - lastSize; + } else { + current_x = x; + if (heighest) + current_y += heighest + 2; + else // now we are using just the fist char :) + current_y += _preRenderedChars[words[tmp]._string[0]].height; + heighest = 0; + } } - uint16 current_x = x, current_y = y; - uint8 heighest = 0; - - const uint8* src = 0; - uint8 width = 0, height = 0, heightadd = 0; + // TODO: maybe test if current_y >= planeheight ? - // now the have alle of these words - for (uint32 tmp = 0; tmp < words.size(); ++tmp) { - lastSize = getStringWidth(words[tmp]._string, ' '); - - // adjust x position - if (current_x + lastSize >= planewidth) { - // hmm lets move it a bit to the left - if (current_x == x && (int16)planewidth - (int16)lastSize >= 0) { - current_x = planewidth - lastSize; - } else { - current_x = x; - if (heighest) - current_y += heighest + 2; - else // now we are using just the fist char :) - current_y += _preRenderedChars[words[tmp]._string[0]].height; - heighest = 0; - } - } + // output word :) + for (lastPos = 0; lastPos < words[tmp]._size; ++lastPos) { + if (words[tmp]._string[lastPos] == '\0') + break; + + // gets our char :) + src = getChar(words[tmp]._string[lastPos], &width, &height, &heightadd); - // TODO: maybe test if current_y >= planeheight ? + // lets draw our char + drawCharToPlane(src, color, width, height, plane, planewidth, planeheight, current_x, current_y + heightadd); - // output word :) - for (lastPos = 0; lastPos < words[tmp]._size; ++lastPos) { - if (words[tmp]._string[lastPos] == '\0') - break; - - // gets our char :) - src = getChar(words[tmp]._string[lastPos], &width, &height, &heightadd); - - // lets draw our char - drawCharToPlane(src, color, width, height, plane, planewidth, planeheight, current_x, current_y + heightadd); - - current_x += width; - heighest = MAX(heighest, height); - } + current_x += width; + heighest = MAX(heighest, height); } } +} - void Font::drawCharToPlane(const uint8* c, uint8 color, uint8 width, uint8 height, - uint8* plane, uint16 planewidth, uint16 planeheight, uint16 x, uint16 y) { - const uint8* src = c; - - // blit them to the screen - for (uint8 yadd = 0; yadd < height; ++yadd) { - for (uint8 xadd = 0; xadd < width; ++xadd) { - switch(*src) { - case 1: - plane[(y + yadd) * planewidth + x + xadd] = color; - break; - - case 2: - plane[(y + yadd) * planewidth + x + xadd] = 14; - break; - - case 3: - plane[(y + yadd) * planewidth + x + xadd] = 0; - break; - - default: - // nothing to do now - break; - }; +void Font::drawCharToPlane(const uint8* c, uint8 color, uint8 width, uint8 height, + uint8* plane, uint16 planewidth, uint16 planeheight, uint16 x, uint16 y) { + const uint8* src = c; + + // blit them to the screen + for (uint8 yadd = 0; yadd < height; ++yadd) { + for (uint8 xadd = 0; xadd < width; ++xadd) { + switch(*src) { + case 1: + plane[(y + yadd) * planewidth + x + xadd] = color; + break; - ++src; - } + case 2: + plane[(y + yadd) * planewidth + x + xadd] = 14; + break; + + case 3: + plane[(y + yadd) * planewidth + x + xadd] = 0; + break; + + default: + // nothing to do now + break; + }; + + ++src; } } +} - void Font::preRenderAllChars(uint16 offsetTableOffset) { - uint16 startOffset = _offsetTable[0]; - uint16 currentOffset = offsetTableOffset; - uint8 currentChar = 0; +void Font::preRenderAllChars(uint16 offsetTableOffset) { + uint16 startOffset = _offsetTable[0]; + uint16 currentOffset = offsetTableOffset; + uint8 currentChar = 0; + + for (; currentOffset < startOffset; ++currentChar, currentOffset += sizeof(uint16)) { + // lets prerender the char :) + + PreRenderedChar newChar; + + newChar.c = new uint8[(_charHeight[currentChar] >> 8) * _charWidth[currentChar]]; + assert(newChar.c); + memset(newChar.c, 0, sizeof(uint8) * (_charHeight[currentChar] >> 8) * _charWidth[currentChar]); + newChar.height = (_charHeight[currentChar] >> 8); + newChar.width = _charWidth[currentChar]; + newChar.heightadd = _charHeight[currentChar] & 0xFF; + + uint8* src = _buffer + _offsetTable[currentChar]; + uint8* dst = &newChar.c[0]; + uint8 index = 0; - for (; currentOffset < startOffset; ++currentChar, currentOffset += sizeof(uint16)) { - // lets prerender the char :) - - PreRenderedChar newChar; - - newChar.c = new uint8[(_charHeight[currentChar] >> 8) * _charWidth[currentChar]]; - assert(newChar.c); - memset(newChar.c, 0, sizeof(uint8) * (_charHeight[currentChar] >> 8) * _charWidth[currentChar]); - newChar.height = (_charHeight[currentChar] >> 8); - newChar.width = _charWidth[currentChar]; - newChar.heightadd = _charHeight[currentChar] & 0xFF; - - uint8* src = _buffer + _offsetTable[currentChar]; - uint8* dst = &newChar.c[0]; - uint8 index = 0; - #ifdef DUMP_FILES - static char filename[32] = { 0 }; - sprintf(filename, "dumps/char%d.dmp", currentChar); - FILE* dump = fopen(filename, "w+"); - assert(dump); - - fprintf(dump, "This should be a '%c'\n", currentChar); + static char filename[32] = { 0 }; + sprintf(filename, "dumps/char%d.dmp", currentChar); + FILE* dump = fopen(filename, "w+"); + assert(dump); + + fprintf(dump, "This should be a '%c'\n", currentChar); #endif - // prerender the char - for (uint8 yadd = 0; yadd < newChar.height; ++yadd) { - for (uint8 xadd = 0; xadd < newChar.width; ++xadd) { - if (xadd % 2) { - index = ((*src) & 0xF0) >> 4; - ++src; - } else { - index = (*src) & 0x0F; - } - - switch(index) { - case 1: + // prerender the char + for (uint8 yadd = 0; yadd < newChar.height; ++yadd) { + for (uint8 xadd = 0; xadd < newChar.width; ++xadd) { + if (xadd % 2) { + index = ((*src) & 0xF0) >> 4; + ++src; + } else { + index = (*src) & 0x0F; + } + + switch(index) { + case 1: #ifdef DUMP_FILES - fprintf(dump, "#"); + fprintf(dump, "#"); #endif - dst[yadd * newChar.width + xadd] = 1; - break; - - case 2: + dst[yadd * newChar.width + xadd] = 1; + break; + + case 2: #ifdef DUMP_FILES - fprintf(dump, "$"); + fprintf(dump, "$"); #endif - dst[yadd * newChar.width + xadd] = 2; - break; - - case 3: + dst[yadd * newChar.width + xadd] = 2; + break; + + case 3: #ifdef DUMP_FILES - fprintf(dump, "§"); + fprintf(dump, "§"); #endif - dst[yadd * newChar.width + xadd] = 3; - break; - - default: + dst[yadd * newChar.width + xadd] = 3; + break; + + default: #ifdef DUMP_FILES - fprintf(dump, "%d", index); + fprintf(dump, "%d", index); #endif - break; - }; - } + break; + }; + } - if (newChar.width % 2) { - ++src; - } + if (newChar.width % 2) { + ++src; + } #ifdef DUMP_FILES - fprintf(dump, "\n"); + fprintf(dump, "\n"); #endif - } + } #ifdef DUMP_FILES - fprintf(dump, "\nThis is the created map:\n"); - // now print the whole thing again - for (uint8 yadd = 0; yadd < newChar.height; ++yadd) { - for (uint8 xadd = 0; xadd < newChar.width; ++xadd) { - fprintf(dump, "%d", dst[yadd * newChar.width + xadd]); - } - fprintf(dump, "\n"); + fprintf(dump, "\nThis is the created map:\n"); + // now print the whole thing again + for (uint8 yadd = 0; yadd < newChar.height; ++yadd) { + for (uint8 xadd = 0; xadd < newChar.width; ++xadd) { + fprintf(dump, "%d", dst[yadd * newChar.width + xadd]); } - fclose(dump); + fprintf(dump, "\n"); + } + fclose(dump); #endif - - _preRenderedChars[currentChar] = newChar; - - if (currentChar == 255) { - break; - } + + _preRenderedChars[currentChar] = newChar; + + if (currentChar == 255) { + break; } } +} } // end of namespace Kyra |