void Font::PrintFromLine(int startrow, Region rgn, const unsigned char* string, Palette* hicolor, ieByte Alignment, Font* initials, Sprite2D* cursor, unsigned int curpos, bool NoColor) const { bool enablecap=false; int capital = 0; int initials_rows = 0; int last_initial_row = 0; int initials_x = 0; int initials_row = 0; ieWord currCap = 0; ieWord* tmp = NULL; size_t len = GetDoubleByteString(string, tmp); ieWord num_empty_rows = 0; if (initials && initials != this) { capital=1; enablecap=true; initials_rows = 1 + ((initials->maxHeight - 1) / maxHeight); // ceiling currCap = string[0]; if ((startrow > 0 && initials_rows > 0) || (len > 0 && isspace(currCap))) { // we need to look back to get the cap while(isspace(currCap) && num_empty_rows < len){//we cant cap whiteSpace so keep looking currCap = string[++num_empty_rows]; // WARNING: this assumes all preceeding whiteSpace is an empty line } last_initial_row = startrow - 1; // always the row before current since this cannot be the first row initials_rows = initials_rows - (startrow + 1) + num_empty_rows; // startrow + 1 because start row is 0 based, but initials_rows is 1 based } } unsigned int psx = IE_FONT_PADDING; Palette *pal = hicolor; if (!pal) { pal = palette; } Holder<Palette> blitPalette = pal; SetupString( tmp, rgn.w, NoColor, initials, enablecap ); if (startrow) enablecap=false; int ystep; if (Alignment & IE_FONT_SINGLE_LINE) { ystep = CalcStringHeight(tmp, len, NoColor); if (!ystep) ystep = maxHeight; } else { ystep = maxHeight; } int x = psx, y = ystep; size_t w = CalcStringWidth( tmp, NoColor ); if (Alignment & IE_FONT_ALIGN_CENTER) { x = ( rgn.w - w) / 2; } else if (Alignment & IE_FONT_ALIGN_RIGHT) { x = ( rgn.w - w ) - IE_FONT_PADDING; } if (Alignment & IE_FONT_ALIGN_MIDDLE) { int h = 0; for (size_t i = 0; i <= len; i++) { if (( tmp[i] == 0 ) || ( tmp[i] == '\n' )) h++; } h = h * ystep; y += ( rgn.h - h ) / 2; } else if (Alignment & IE_FONT_ALIGN_BOTTOM) { int h = 0; for (size_t i = 0; i <= len; i++) { if (( tmp[i] == 0 ) || ( tmp[i] == '\n' )) h++; } h = h * ystep; y += ( rgn.h - h ) - IE_FONT_PADDING; } else if (Alignment & IE_FONT_ALIGN_TOP) { y += IE_FONT_PADDING; } Video* video = core->GetVideoDriver(); const Sprite2D* currGlyph; ieWord currChar = '\0'; int row = 0; for (size_t i = 0; i < len; i++) { if (( tmp[i] ) == '[' && !NoColor) { i++; char tag[256]; tag[0]=0; for (size_t k = 0; k < 256 && i<len; k++) { if (tmp[i] == ']') { tag[k] = 0; break; } tag[k] = tmp[i++]; } if (strnicmp( tag, "capital=",8)==0) { sscanf( tag, "capital=%d", &capital); if (capital && (row>=startrow) ) { enablecap=true; } continue; } if (strnicmp( tag, "color=", 6 ) == 0) { unsigned int r,g,b; if (sscanf( tag, "color=%02X%02X%02X", &r, &g, &b ) != 3) continue; const Color c = {(unsigned char)r, (unsigned char)g, (unsigned char)b, 0}; Palette* newPal = core->CreatePalette( c, palette->back ); blitPalette = newPal; gamedata->FreePalette( newPal ); continue; } if (stricmp( tag, "/color" ) == 0) { blitPalette = pal; continue; } if (stricmp( "p", tag ) == 0) { psx = x; continue; } if (stricmp( "/p", tag ) == 0) { psx = IE_FONT_PADDING; } continue; } if (row < startrow) { if (tmp[i] == 0) { row++; } continue; } if (( tmp[i] == 0 ) || ( tmp[i] == '\n' )) { y += ystep; x = psx; size_t w = CalcStringWidth( &tmp[i + 1], NoColor ); if (initials_rows > 0) { initials_rows--; x += initials_x; w += initials_x; } if (Alignment & IE_FONT_ALIGN_CENTER) { x = ( rgn.w - w ) / 2; } else if (Alignment & IE_FONT_ALIGN_RIGHT) { x = ( rgn.w - w ); } continue; } currChar = tmp[i]; if (initials && capital && enablecap) { currCap = currChar; x = initials->PrintInitial( x, y, rgn, currChar ); initials_x = x; //how many more lines to be indented (one was already indented) initials_rows = (initials->maxHeight - 1) / maxHeight; initials_rows += num_empty_rows; initials_row = row; last_initial_row = initials_row; enablecap = false; continue; } else if (initials && currCap && row > last_initial_row && (row - num_empty_rows - initials_row) <= ((initials->maxHeight-1)/maxHeight)){ // means this row doesnt have a cap, but a preceeding one did and its overlapping this row int initY = y; if (!num_empty_rows || row > num_empty_rows) {// num_empty_rows is for scrolling text areas initY = (y - (maxHeight * (row - initials_row - num_empty_rows))); } x = initials->PrintInitial( x, initY, rgn, currCap ); initials_x = x; last_initial_row++; if (num_empty_rows && row <= num_empty_rows) continue; else x += psx; } if (i > 0) { // kerning x -= GetKerningOffset(tmp[i-1], currChar); } currGlyph = GetCharSprite(currChar); video->BlitSprite(currGlyph, x + rgn.x, y + rgn.y, true, &rgn, blitPalette.get()); if (cursor && ( i == curpos )) { video->BlitSprite( cursor, x + rgn.x, y + rgn.y, true, &rgn ); } x += currGlyph->Width; } if (cursor && ( curpos == len )) { video->BlitSprite( cursor, x + rgn.x, y + rgn.y, true, &rgn ); } blitPalette = NULL; free( tmp ); }
void IniSpawn::InitSpawn(const ieResRef DefaultArea) { const char *s; Holder<DataFileMgr> inifile = GetIniFile(DefaultArea); if (!inifile) { strnuprcpy(NamelessSpawnArea, DefaultArea, 8); return; } s = inifile->GetKeyAsString("nameless","destare",DefaultArea); strnuprcpy(NamelessSpawnArea, s, 8); s = inifile->GetKeyAsString("nameless","point","[0.0]"); int x,y; if (sscanf(s,"[%d.%d]", &x, &y)!=2) { x=0; y=0; } NamelessSpawnPoint.x=x; NamelessSpawnPoint.y=y; s = inifile->GetKeyAsString("nameless", "partyarea", DefaultArea); strnuprcpy(PartySpawnArea, s, 8); s = inifile->GetKeyAsString("nameless", "partypoint", "[0.0]"); if (sscanf(s,"[%d.%d]", &x, &y) != 2) { x = NamelessSpawnPoint.x; y = NamelessSpawnPoint.y; } PartySpawnPoint.x = x; PartySpawnPoint.y = y; //35 - already standing //36 - getting up NamelessState = inifile->GetKeyAsInt("nameless","state",36); namelessvarcount = inifile->GetKeysCount("namelessvar"); if (namelessvarcount) { NamelessVar = new VariableSpec[namelessvarcount]; for (y=0;y<namelessvarcount;y++) { const char* Key = inifile->GetKeyNameByIndex("namelessvar",y); strnlwrcpy(NamelessVar[y].Name, Key, 32); NamelessVar[y].Value = inifile->GetKeyAsInt("namelessvar",Key,0); } } localscount = inifile->GetKeysCount("locals"); if (localscount) { Locals = new VariableSpec[localscount]; for (y=0;y<localscount;y++) { const char* Key = inifile->GetKeyNameByIndex("locals",y); strnlwrcpy(Locals[y].Name, Key, 32); Locals[y].Value = inifile->GetKeyAsInt("locals",Key,0); } } s = inifile->GetKeyAsString("spawn_main","enter",NULL); if (s) { ReadSpawnEntry(inifile.get(), s, enterspawn); } s = inifile->GetKeyAsString("spawn_main","exit",NULL); if (s) { ReadSpawnEntry(inifile.get(), s, exitspawn); } s = inifile->GetKeyAsString("spawn_main","events",NULL); if (s) { eventcount = CountElements(s,','); eventspawns = new SpawnEntry[eventcount]; ieVariable *events = new ieVariable[eventcount]; GetElements(s, events, eventcount); int ec = eventcount; while(ec--) { ReadSpawnEntry(inifile.get(), events[ec], eventspawns[ec]); } delete[] events; } //maybe not correct InitialSpawn(); }
void Font::Print(Region cliprgn, Region rgn, const unsigned char* string, Palette* hicolor, ieByte Alignment, bool anchor, Font* initials, Sprite2D* cursor, unsigned int curpos, bool NoColor) const { int capital = (initials) ? 1 : 0; unsigned int psx = IE_FONT_PADDING; Palette* pal = hicolor; if (!pal) { pal = palette; } if (initials==this) { initials = NULL; } Holder<Palette> blitPalette = pal; ieWord* tmp = NULL; size_t len = GetDoubleByteString(string, tmp); while (len > 0 && (tmp[len - 1] == '\n' || tmp[len - 1] == '\r')) { // ignore trailing newlines tmp[len - 1] = 0; len--; } SetupString( tmp, rgn.w, NoColor, initials, capital ); int ystep; if (Alignment & IE_FONT_SINGLE_LINE) { ystep = CalcStringHeight(tmp, len, NoColor); if (!ystep) ystep = maxHeight; } else { ystep = maxHeight; } int x = psx, y = ystep; Video* video = core->GetVideoDriver(); if (Alignment & IE_FONT_ALIGN_CENTER) { size_t w = CalcStringWidth( tmp, NoColor ); x = ( rgn.w - w ) / 2; } else if (Alignment & IE_FONT_ALIGN_RIGHT) { size_t w = CalcStringWidth( tmp, NoColor ); x = ( rgn.w - w ) - IE_FONT_PADDING; } if (Alignment & IE_FONT_ALIGN_MIDDLE) { int h = 0; for (size_t i = 0; i <= len; i++) { if (tmp[i] == 0) h++; } h = h * ystep; y += ( rgn.h - h ) / 2; } else if (Alignment & IE_FONT_ALIGN_BOTTOM) { int h = 0; for (size_t i = 0; i <= len; i++) { if (tmp[i] == 0) h++; } h = h * ystep; y += ( rgn.h - h ) - IE_FONT_PADDING; } else if (Alignment & IE_FONT_ALIGN_TOP) { y += IE_FONT_PADDING; } ieWord currChar = '\0'; const Sprite2D* currGlyph = NULL; for (size_t i = 0; i < len; i++) { if (( tmp[i] ) == '[' && !NoColor) { i++; char tag[256]; tag[0]=0; for (size_t k = 0; k < 256 && i<len; k++) { if (tmp[i] == ']') { tag[k] = 0; break; } tag[k] = tmp[i++]; } if (strnicmp( tag, "capital=",8)==0) { sscanf( tag, "capital=%d", &capital); continue; } if (strnicmp( tag, "color=", 6 ) == 0) { unsigned int r,g,b; if (sscanf( tag, "color=%02X%02X%02X", &r, &g, &b ) != 3) continue; const Color c = {(unsigned char)r, (unsigned char)g, (unsigned char)b, 0}; Palette* newPal = core->CreatePalette( c, palette->back ); blitPalette = newPal; gamedata->FreePalette( newPal ); continue; } if (stricmp( tag, "/color" ) == 0) { blitPalette = pal; continue; } if (stricmp( "p", tag ) == 0) { psx = x; continue; } if (stricmp( "/p", tag ) == 0) { psx = IE_FONT_PADDING; continue; } continue; } if (tmp[i] == 0) { y += ystep; x = psx; size_t w = CalcStringWidth( &tmp[i + 1], NoColor ); if (Alignment & IE_FONT_ALIGN_CENTER) { x = ( rgn.w - w ) / 2; } else if (Alignment & IE_FONT_ALIGN_RIGHT) { x = ( rgn.w - w ); } continue; } currChar = tmp[i]; currGlyph = GetCharSprite(currChar); if (initials && capital) { x = initials->PrintInitial( x, y, rgn, currChar ); continue; } if (i > 0) { // kerning x -= GetKerningOffset(tmp[i-1], currChar); } video->BlitSprite(currGlyph, x + rgn.x, y + rgn.y, anchor, &cliprgn, blitPalette.get()); if (cursor && ( curpos == i )) video->BlitSprite( cursor, x + rgn.x, y + rgn.y, anchor, &cliprgn ); x += currGlyph->Width; } if (cursor && ( curpos == len )) { video->BlitSprite( cursor, x + rgn.x, y + rgn.y, anchor, &cliprgn ); } blitPalette = NULL; free( tmp ); }