/***************************************************************************** * * File: TextWriter.cpp * * Project: Osmose emulator. * * Description: This class is use to display textual information into * a SDL_Surface. * * Author: Vedder Bruno * Date: 26/02/2005, 14h13 * * URL: http://bcz.emu-france.com/ *****************************************************************************/ #include "TextWriter.h" /*--------------------------------------------------------------------*/ /* This array contains 8x496 pixels picture of our font. Each value is*/ /* an index in palete. */ /*--------------------------------------------------------------------*/ const unsigned char font[] = { 0,1,1,1,1,1,0,0,1,2,2,2,2,2,1,0,1,2,2,1,2,2,1,0,1,2,2,2,2,2,1,0, 1,2,2,1,2,2,1,0,1,2,2,1,2,2,1,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0, 0,1,1,1,1,1,0,0,0,1,2,2,2,2,1,0,0,1,2,2,1,2,1,0,0,1,2,2,2,2,1,0, 0,1,2,2,1,2,1,0,0,1,2,2,2,2,1,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0, 0,0,1,1,1,1,1,0,0,1,2,2,2,2,1,0,0,1,2,2,1,1,1,0,0,1,2,2,1,0,0,0, 0,1,2,2,1,1,1,0,0,1,2,2,2,2,1,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0, 0,1,1,1,1,1,0,0,0,1,2,2,2,2,1,0,0,1,2,2,1,2,1,0,0,1,2,2,1,2,1,0, 0,1,2,2,1,2,1,0,0,1,2,2,2,2,1,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0, 0,1,1,1,1,1,1,0,0,1,2,2,2,2,1,0,0,1,2,2,1,1,1,0,0,1,2,2,2,2,1,0, 0,1,2,2,1,1,1,0,0,1,2,2,2,2,1,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0, 0,1,1,1,1,1,1,0,0,1,2,2,2,2,1,0,0,1,2,2,1,1,1,0,0,1,2,2,2,2,1,0, 0,1,2,2,1,1,1,0,0,1,2,2,1,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0, 0,0,1,1,1,1,1,0,0,1,2,2,2,2,1,0,0,1,2,2,1,1,1,0,0,1,2,2,1,2,1,0, 0,1,2,2,1,2,1,0,0,1,2,2,2,2,1,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0, 0,1,1,1,1,1,1,1,0,1,2,2,1,2,2,1,0,1,2,2,1,2,2,1,0,1,2,2,2,2,2,1, 0,1,2,2,1,2,2,1,0,1,2,2,1,2,2,1,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0, 0,0,1,1,1,1,0,0,0,0,1,2,2,1,0,0,0,0,1,2,2,1,0,0,0,0,1,2,2,1,0,0, 0,0,1,2,2,1,0,0,0,0,1,2,2,1,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0, 0,1,1,1,1,1,1,0,0,1,2,2,2,2,1,0,0,0,1,1,2,2,1,0,0,0,0,1,2,2,1,0, 0,1,1,1,2,2,1,0,0,1,2,2,2,2,1,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0, 0,1,1,1,1,1,1,1,0,1,2,2,1,2,2,1,0,1,2,2,2,2,1,0,0,1,2,2,2,2,1,0, 0,1,2,2,2,2,1,0,0,1,2,2,1,2,2,1,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0, 0,1,1,1,1,0,0,0,0,1,2,2,1,0,0,0,0,1,2,2,1,0,0,0,0,1,2,2,1,0,0,0, 0,1,2,2,1,1,1,0,0,1,2,2,2,2,1,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0, 1,1,1,1,1,1,1,0,1,2,2,1,2,2,1,0,1,2,2,2,2,2,1,0,1,2,2,2,2,2,1,0, 1,2,1,2,1,2,1,0,1,2,1,2,1,2,1,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0, 1,1,1,1,1,1,0,0,1,2,2,2,2,2,1,0,1,2,2,2,2,2,1,0,1,2,2,1,2,2,1,0, 1,2,2,1,2,2,1,0,1,2,2,1,2,2,1,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0, 0,1,1,1,1,1,0,0,1,2,2,2,2,2,1,0,1,2,1,2,2,2,1,0,1,2,1,2,2,2,1,0, 1,2,1,2,2,2,1,0,1,2,2,2,2,2,1,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0, 1,1,1,1,1,1,0,0,1,2,2,2,2,2,1,0,1,2,2,1,2,2,1,0,1,2,2,2,2,2,1,0, 1,2,2,1,1,1,0,0,1,2,2,1,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0, 0,1,1,1,1,1,0,0,1,2,2,2,2,2,1,0,1,2,2,1,2,2,1,0,1,2,2,1,2,2,1,0, 1,2,2,1,2,2,1,0,1,2,2,2,2,2,2,1,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0, 0,1,1,1,1,1,0,0,0,1,2,2,2,2,1,0,0,1,2,2,1,2,1,0,0,1,2,2,2,2,1,0, 0,1,2,2,1,2,2,1,0,1,2,2,1,2,2,1,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0, 0,0,1,1,1,1,0,0,0,1,2,2,2,2,1,0,0,1,2,2,1,1,1,0,0,1,2,2,2,2,1,0, 0,1,1,1,1,2,1,0,0,1,2,2,2,2,1,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0, 0,1,1,1,1,1,1,0,0,1,2,2,2,2,1,0,0,1,1,2,2,1,1,0,0,0,1,2,2,1,0,0, 0,0,1,2,2,1,0,0,0,0,1,2,2,1,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0, 0,1,1,1,1,1,1,0,0,1,2,1,2,2,1,0,0,1,2,1,2,2,1,0,0,1,2,2,2,2,1,0, 0,1,2,2,2,2,1,0,0,1,2,2,2,2,1,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0, 0,1,1,1,1,1,1,0,0,1,2,1,2,2,1,0,0,1,2,1,2,2,1,0,0,1,2,2,2,2,1,0, 0,0,1,2,2,1,0,0,0,0,1,2,2,1,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0, 1,1,1,1,1,1,1,0,1,2,1,2,1,2,1,0,1,2,1,2,1,2,1,0,1,2,2,2,2,2,1,0, 0,1,2,2,2,1,0,0,0,1,2,1,2,1,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0, 0,1,1,0,0,1,1,0,0,1,2,1,1,2,1,0,0,0,1,2,2,1,0,0,0,0,1,2,2,1,0,0, 0,0,1,2,2,1,0,0,0,1,2,1,1,2,1,0,0,1,1,0,0,1,1,0,0,0,0,0,0,0,0,0, 1,1,1,0,0,1,1,1,1,2,2,1,1,2,2,1,0,1,2,2,2,2,1,0,0,1,2,2,2,2,1,0, 0,0,1,2,2,1,0,0,0,0,1,2,2,1,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0, 0,1,1,1,1,1,1,0,0,1,2,2,2,2,1,0,0,1,1,1,2,2,1,0,0,0,1,2,2,1,0,0, 0,1,2,2,1,1,1,0,0,1,2,2,2,2,1,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,1,1,1,1,0,0,0,1,2,2,2,2,1,0,0,1,2,1,2,2,1,0,0,1,2,1,2,2,1,0, 0,1,2,1,2,2,1,0,0,1,2,2,2,2,1,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0, 0,0,1,1,1,1,0,0,0,1,2,2,2,1,0,0,0,1,1,2,2,1,0,0,0,0,1,2,2,1,0,0, 0,0,1,2,2,1,0,0,0,0,1,2,2,1,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0, 0,0,1,1,1,1,0,0,0,1,2,2,2,2,1,0,0,1,1,1,2,2,1,0,0,0,1,2,2,2,1,0, 0,1,2,2,1,1,1,0,0,1,2,2,2,2,1,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0, 0,1,1,1,1,1,0,0,0,1,2,2,2,2,1,0,0,1,1,1,2,2,1,0,0,0,1,2,2,2,1,0, 0,1,1,1,2,2,1,0,0,1,2,2,2,2,1,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0, 0,0,0,1,1,1,0,0,0,0,1,2,2,1,0,0,0,1,2,2,2,1,1,0,1,2,2,1,2,2,1,0, 1,2,2,2,2,2,1,0,1,1,1,2,2,1,1,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0, 0,1,1,1,1,1,1,0,0,1,2,2,2,2,1,0,0,1,2,1,1,1,0,0,0,1,2,2,2,2,1,0, 0,0,1,1,2,2,1,0,0,1,2,2,2,2,1,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0, 0,0,1,1,1,1,1,0,0,1,2,2,2,2,1,0,0,1,2,2,1,1,0,0,0,1,2,2,2,2,1,0, 0,1,2,2,1,2,1,0,0,1,2,2,2,2,1,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0, 0,1,1,1,1,1,1,0,0,1,2,2,2,2,1,0,0,1,1,1,2,2,1,0,0,0,0,1,2,2,1,0, 0,0,1,2,2,1,0,0,0,1,2,2,1,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,1,1,1,1,0,0,0,1,2,2,2,2,1,0,0,1,2,1,2,2,1,0,0,1,2,2,2,2,1,0, 0,1,2,1,2,2,1,0,0,1,2,2,2,2,1,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0, 0,0,1,1,1,1,0,0,0,1,2,2,2,2,1,0,0,1,2,1,2,2,1,0,0,1,2,2,2,2,1,0, 0,0,1,1,2,2,1,0,0,1,2,2,2,2,1,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0, 0,0,1,1,1,1,0,0,0,0,1,2,2,1,0,0,0,0,1,2,2,1,0,0,0,0,1,2,2,1,0,0, 0,0,1,1,1,1,0,0,0,0,1,2,2,1,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,1,1,1,0,0,0,0,0,1,2,1,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0, 0,0,1,1,1,1,1,0,0,0,1,2,1,2,1,0,0,0,1,2,1,2,1,0,0,0,1,1,1,1,1,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,1,1,1,1,1,0,0,1,1,2,1,2,1,1,0,1,2,2,2,2,2,1,0,1,1,2,2,2,1,1,0, 1,2,2,2,2,2,1,0,1,1,2,1,2,1,1,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0, 1,1,1,0,1,1,1,0,1,2,1,0,1,2,1,0,1,1,1,1,2,1,1,0,0,0,1,2,1,1,0,0, 1,1,2,1,1,1,1,0,1,2,1,0,1,2,1,0,1,1,1,0,1,1,1,0,0,0,0,0,0,0,0,0, 0,0,1,1,1,0,0,0,0,1,2,2,2,1,0,0,0,1,2,1,2,1,0,0,0,1,2,2,2,1,0,0, 0,0,1,2,1,0,0,0,0,1,2,1,2,1,0,0,0,1,1,0,1,1,0,0,0,0,0,0,0,0,0,0, 0,0,0,1,1,1,0,0,0,0,0,1,2,1,0,0,0,0,0,1,2,1,0,0,0,0,0,1,1,1,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,1,1,1,0,0,0,0,1,2,2,1,0,0,0,1,2,2,1,0,0,0,0,1,2,2,1,0,0, 0,0,1,2,2,1,0,0,0,0,0,1,2,2,1,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0, 0,1,1,1,0,0,0,0,0,1,2,2,1,0,0,0,0,0,1,2,2,1,0,0,0,0,1,2,2,1,0,0, 0,0,1,2,2,1,0,0,0,1,2,2,1,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,1,1,0,1,1,0,0,0,1,2,1,2,1,0,0,0,0,1,2,1,0,0,0, 0,1,2,1,2,1,0,0,0,1,1,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,1,1,2,1,1,0,0,0,1,2,2,2,1,0,0, 0,1,1,2,1,1,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,1,1,1,0,0,0,0,0,1,2,1,0,0,0,0,0,1,2,1,0,0,0,0,0,1,1,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,1,2,2,1,0,0, 0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,1,1,0,0,0,0,0,1,2,1,0,0,0,0,0,1,2,1,0,0,0,0,1,2,1,0,0,0, 0,0,1,2,1,0,0,0,0,1,2,1,0,0,0,0,0,1,2,1,0,0,0,0,0,1,1,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,1,2,1,0,0,0,0,0,1,1,1,0,0,0, 0,0,1,2,1,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,1,2,1,0,0,0,0,0,1,1,1,0,0, 0,0,0,1,2,1,0,0,0,0,0,1,2,1,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0, 0,1,1,1,1,1,0,0,1,2,2,2,2,2,1,0,1,2,2,1,2,2,1,0,1,1,1,1,2,2,1,0, 0,0,1,2,2,1,0,0,0,0,1,1,1,0,0,0,0,0,1,2,1,0,0,0,0,0,1,1,1,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,1,1,2,2,1,0,0,1,2,2,1,1,1,0, 0,1,2,2,2,2,1,0,0,0,1,1,2,2,1,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,1,2,2,1,1,0,0,0,1,1,1,2,2,1,0, 0,1,2,2,2,2,1,0,0,1,2,2,1,1,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,1,2,2,1,0,0,0,0,1,1,1,1,0,0, 0,0,1,2,2,1,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,1,1,1,1,0,0,0,0,1,2,2,1,0,0,0,0,1,2,1,1,0,0,0,0,1,2,1,0,0,0, 0,0,1,2,1,1,0,0,0,0,1,2,2,1,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0, 0,0,1,1,1,1,0,0,0,0,1,2,2,1,0,0,0,0,1,1,2,1,0,0,0,0,0,1,2,1,0,0, 0,0,1,1,2,1,0,0,0,0,1,2,2,1,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0, 0,0,1,1,0,0,0,0,0,0,1,2,1,0,0,0,0,0,1,2,1,0,0,0,0,0,0,1,2,1,0,0, 0,0,0,1,2,1,0,0,0,0,0,0,1,2,1,0,0,0,0,0,1,2,1,0,0,0,0,0,0,1,1,0, 0,0,1,1,0,0,0,0,0,1,2,2,1,0,0,0,1,2,1,1,2,1,0,0,1,1,0,0,1,1,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,1,2,2,2,2,1,0,0,1,1,1,1,1,1,0, }; /*--------------------------------------------------------------------*/ /* Constructor initialize internal values. */ /*--------------------------------------------------------------------*/ TextWriter::TextWriter() { hasMessage = false; memset(message, 0, MESSAGE_LENGTH); messageDuration = 0; // Set colors for messages. fontCols[0] = 0; fontCols[1] = 0x0; fontCols[2] = 0xFFFF; } /*--------------------------------------------------------------------*/ /* This routine simply copy message to be displayed into internal */ /* buffer. Display duration is stored too. The update routine is */ /* called 60hz. If you want a message beeing displayed 5 second you */ /* should pass 300 in counter parameter. */ /*--------------------------------------------------------------------*/ void TextWriter::addText(const char *msg, unsigned int counter) { strncpy(message,(char *) msg, MESSAGE_LENGTH); messageDuration = counter; hasMessage= true; } /*--------------------------------------------------------------------*/ /* This routine must be call each time screen is refreshed. It writes */ /* message (if any) into SDL_Surface and decrease the duration counter*/ /* If counter reaches 0 the message is removed. This routine is called*/ /* at 60hz. */ /*--------------------------------------------------------------------*/ void TextWriter::update(SDL_Surface *s, bool display) { if (hasMessage) { int ind = 0; int x = 8; if (messageDuration != 0) messageDuration--; // To avoid wrapping. if (messageDuration ==0) hasMessage = false; if (display == true) // False means frame render skipped. So dont display message. { while ((message[ind] !=0) && (ind < MESSAGE_LENGTH)) { unsigned char car; car = asciiToFont(message[ind]); writeChar(s, car, x, 0); ind++; x+=8; } } } } /*--------------------------------------------------------------------*/ /* This routine convert ASCII value to Font char index. */ /* 0-25 = Alphabetical char. */ /* 26 SPACE */ /* 27-36 = Numerical. */ /*--------------------------------------------------------------------*/ unsigned char TextWriter::asciiToFont(unsigned char asc) { if (asc>='a' && asc <='z') return (asc -'a'); else if (asc>='A' && asc <='Z') return (asc -'A'); else if (asc>='0' && asc <='9') return (asc -'0'+27); else { switch(asc) { case ' ': return 26; break; case '!': return 37; break; case '.': return 38; break; case '\"': return 39; break; case '#': return 40; break; case '%': return 41; break; case '&': return 42; break; case '\'': return 43; break; case '(': return 44; break; case ')': return 45; break; case '*': return 46; break; case '+': return 47; break; case ',': return 48; break; case '-': return 49; break; case '/': return 50; break; case ':': return 51; break; case ';': return 52; break; case '?': return 53; break; case '<': return 54; break; case '>': return 55; break; case '=': return 56; break; case '[': return 57; break; case ']': return 58; break; case '\\': return 59; break; case '^': return 60; break; case '_': return 61; break; default: return 53; // ? char break; } } } /*--------------------------------------------------------------------*/ /* This routine renders 8x8 char into SDL surface. */ /*--------------------------------------------------------------------*/ void TextWriter::writeChar(SDL_Surface *s,unsigned char c, unsigned int x, unsigned int y) { unsigned int dw; // Display width; unsigned int c_index; // Char index into font array. unsigned short *d_index; // Dest index into pixel array. dw = s->w; c_index = c << 6; // Each bitmap char is 64 bytes long. d_index = (unsigned short *)(s->pixels); d_index += (y * dw + x); for (int o = 0; o < 8; o++) { for (int i = 0; i < 8; i++) { unsigned short col; unsigned i_col; i_col = font[c_index++]; if (i_col != 0) // Transparency if i_col = 0; { col = fontCols[i_col]; *d_index = col; } d_index++; } d_index += dw - 8; // Jump next line. } } /*--------------------------------------------------------------------*/ /* This routine returns remaing duration. */ /*--------------------------------------------------------------------*/ unsigned int TextWriter::getDuration() { return messageDuration; }