/************************************************************ * * * text_str.c * * * * * LPGE 1997 * * * * Copyright (C) 1996 Sony Computer Entertainment Inc. * * All Rights Reserved * * * ***********************************************************/ // text-drawing module /**************************************************************************** includes ****************************************************************************/ #include "text_str.h" /**************************************************************************** constants ****************************************************************************/ #define SPACE_CHARACTER 0 #define EXCLAMATION_MARK_CHARACTER 1 #define DOUBLE_QUOTE 2 #define HASH_CHARACTER 3 #define DOLLAR_CHARACTER 4 #define PERCENT_CHARACTER 5 #define AMPERSAND_CHARACTER 6 #define SINGLE_QUOTE_CHARACTER 7 #define LEFT_BRACKET_CHARACTER 8 #define RIGHT_BRACKET_CHARACTER 9 #define STAR_CHARACTER 10 #define CROSS_CHARACTER 11 #define COMMA_CHARACTER 12 #define DASH_CHARACTER 13 #define FULL_STOP_CHARACTER 14 #define FORWARD_SLASH_CHARACTER 15 #define COLON_CHARACTER 16 #define SEMI_COLON_CHARACTER 17 #define LESS_THAN_CHARACTER 18 #define EQUALS_CHARACTER 19 #define MORE_THAN_CHARACTER 20 #define QUESTION_MARK_CHARACTER 21 #define THICK_RIGHT_ARROW_CHARACTER 22 #define SQUARE_LEFT_BRACKET_CHARACTER 23 #define SOLID_SQUARE_CHARACTER 24 #define SQUARE_RIGHT_BRACKET_CHARACTER 25 #define SMALL_HAT_CHARACTER 26 #define UNDERSCORE_CHARACTER 27 /**************************************************************************** globals ****************************************************************************/ GsSPRITE LetterSprites[26]; GsSPRITE NumberSprites[10]; GsSPRITE PunctuationSprites[28]; TextString AllStrings[MAX_TEXT_STRINGS]; int NumberOfStrings; /**************************************************************************** local prototypes ****************************************************************************/ int GetPunctuationIndex (char asciiCode); /**************************************************************************** functions ****************************************************************************/ void InitialiseTextStrings (void) { int i; for (i = 0; i < 26; i++) { LinkSpriteToImageInfo( &LetterSprites[i], &AsciiTextureInfo); LetterSprites[i].attribute |= GsALON; // semi-transparency LetterSprites[i].attribute |= (1<<28); // semi-transparency LetterSprites[i].attribute |= (1<<29); // semi-transparency LetterSprites[i].w = LetterSprites[i].h = 8; if (i < 15) { LetterSprites[i].u += 8 + (i * 8); LetterSprites[i].v += 16; } else { LetterSprites[i].u += ((i-15) * 8); LetterSprites[i].v += 24; } } for (i = 0; i < 10; i++) { LinkSpriteToImageInfo( &NumberSprites[i], &AsciiTextureInfo); NumberSprites[i].attribute |= GsALON; // semi-transparency NumberSprites[i].attribute |= (1<<28); // semi-transparency NumberSprites[i].attribute |= (1<<29); // semi-transparency NumberSprites[i].w = NumberSprites[i].h = 8; NumberSprites[i].u += (i * 8); NumberSprites[i].v += 8; } for (i = 0; i < 28; i++) { LinkSpriteToImageInfo( &PunctuationSprites[i], &AsciiTextureInfo); PunctuationSprites[i].attribute |= GsALON; // semi-transparency PunctuationSprites[i].attribute |= (1<<28); // semi-transparency PunctuationSprites[i].attribute |= (1<<29); // semi-transparency PunctuationSprites[i].w = PunctuationSprites[i].h = 8; } for (i = 0; i < 16; i++) { PunctuationSprites[i].u += (i * 8); PunctuationSprites[i].v += 0; } for (i = 16; i < 22; i++) { PunctuationSprites[i].u += 80 + ((i-16) * 8); PunctuationSprites[i].v += 8; } PunctuationSprites[22].v += 16; for (i = 23; i < 28; i++) { PunctuationSprites[i].u += 88 + ((i-23) * 8); PunctuationSprites[i].v += 24; } ClearAllTextStrings(); } void ClearAllTextStrings (void) { int i; for (i = 0; i < MAX_TEXT_STRINGS; i++) { AllStrings[i].x = 0; AllStrings[i].y = 0; AllStrings[i].length = 0; AllStrings[i].colour = NORMAL_COLOUR; AllStrings[i].data[0] = '\n'; } NumberOfStrings = 0; } void DisplayTextStrings (GsOT* orderingTable) { int i, j; TextString* thisOne; GsSPRITE* sprite; int x, y; for (i = 0; i < MAX_TEXT_STRINGS; i++) { if (AllStrings[i].length != 0) { thisOne = &AllStrings[i]; x = thisOne->x; y = thisOne->y; for (j = 0; j < thisOne->length; j++) { sprite = GetSpriteForCharacter(thisOne->data[j]); if (sprite != NULL) { sprite->x = x; sprite->y = y; sprite->r = (thisOne->colour & 31) * 4; sprite->g = ((thisOne->colour >> 5) & 31) * 4; sprite->b = ((thisOne->colour >> 10) & 31) * 4; switch(ScreenResolution) { case LOW_RES: sprite->scalex = ONE; sprite->scaley = ONE; break; case HI_RES: sprite->scalex = 8192; // ONE * 2 sprite->scaley = 8192; break; default: assert(FALSE); } GsSortSprite(sprite, orderingTable, 0); } // move along to the right switch(ScreenResolution) { case LOW_RES: x += 8; break; case HI_RES: x += 16; break; default: assert(FALSE); } } // mark string as EMPTY thisOne->length = 0; } } NumberOfStrings = 0; } // proper version: letters, numbers, punctuation GsSPRITE* GetSpriteForCharacter (char character) { GsSPRITE* result = NULL; int index; // toupper if (character >= 65 && character <= 90) character += 32; if (character >= 97 && character <= 122) { index = ((int) character) - 97; result = &LetterSprites[index]; } else if (character >= 48 && character <= 57) { index = ((int) character) - 48; result = &NumberSprites[index]; } else { index = GetPunctuationIndex(character); if (index != -1) result = &PunctuationSprites[index]; else result = NULL; } return result; } int GetPunctuationIndex (char asciiCode) { int numberCode; numberCode = (int) asciiCode; switch(numberCode) { case ' ': return SPACE_CHARACTER; case '!': return EXCLAMATION_MARK_CHARACTER; case '"': return DOUBLE_QUOTE; case '#': return HASH_CHARACTER; case '$': return DOLLAR_CHARACTER; case '%': return PERCENT_CHARACTER; case '&': return AMPERSAND_CHARACTER; case 39: return SINGLE_QUOTE_CHARACTER; case '(': return LEFT_BRACKET_CHARACTER; case ')': return RIGHT_BRACKET_CHARACTER; case '*': return STAR_CHARACTER; case '+': return CROSS_CHARACTER; case ',': return COMMA_CHARACTER; case '-': return DASH_CHARACTER; case '.': return FULL_STOP_CHARACTER; case '/': return FORWARD_SLASH_CHARACTER; case ':': return COLON_CHARACTER; case ';': return SEMI_COLON_CHARACTER; case '<': return LESS_THAN_CHARACTER; case '=': return EQUALS_CHARACTER; case '>': return MORE_THAN_CHARACTER; case '?': return QUESTION_MARK_CHARACTER; // no thick right arrow case '[': return SQUARE_LEFT_BRACKET_CHARACTER; // no solid square case ']': return SQUARE_RIGHT_BRACKET_CHARACTER; case '^': return SMALL_HAT_CHARACTER; case '_': return UNDERSCORE_CHARACTER; default: return -1; } } void RegisterTextStringForDisplay (char* string, int x, int y, int colour) { int i, id = -1; TextString* thisOne; for (i = 0; i < MAX_TEXT_STRINGS; i++) { if (AllStrings[i].length == 0) { id = i; break; } } assert(id != -1); thisOne = &AllStrings[id]; thisOne->x = x; thisOne->y = y; thisOne->length = strlen(string); thisOne->colour = colour; assert(thisOne->length > 0); assert(thisOne->length < MAX_STRING_LENGTH); strcpy( thisOne->data, string); NumberOfStrings++; assert(NumberOfStrings <= MAX_TEXT_STRINGS); } void RegisterStringForPermanentDisplay (char *string, int x, int y, int colour) { TextString* thisOne; assert(string != NULL); assert(NumberOfStrings < MAX_TEXT_STRINGS); thisOne = &AllStrings[NumberOfStrings]; thisOne->x = x; thisOne->y = y; thisOne->length = strlen(string); thisOne->colour = colour; assert(thisOne->length > 0); assert(thisOne->length < MAX_STRING_LENGTH); strcpy( thisOne->data, string); NumberOfStrings++; assert(NumberOfStrings <= MAX_TEXT_STRINGS); } void DisplayPermanentStringList (GsOT* orderingTable) { int i, j; TextString* thisOne; GsSPRITE* sprite; int x, y; assert(NumberOfStrings >= 0); assert(NumberOfStrings < MAX_TEXT_STRINGS); for (i = 0; i < NumberOfStrings; i++) { if (AllStrings[i].length != 0) { thisOne = &AllStrings[i]; x = thisOne->x; y = thisOne->y; for (j = 0; j < thisOne->length; j++) { sprite = GetSpriteForCharacter(thisOne->data[j]); if (sprite != NULL) { sprite->x = x; sprite->y = y; sprite->r = (thisOne->colour & 31) * 4; sprite->g = ((thisOne->colour >> 5) & 31) * 4; sprite->b = ((thisOne->colour >> 10) & 31) * 4; switch(ScreenResolution) { case LOW_RES: sprite->scalex = ONE; sprite->scaley = ONE; break; case HI_RES: sprite->scalex = 8192; // ONE * 2 sprite->scaley = 8192; break; default: assert(FALSE); } GsSortSprite(sprite, orderingTable, 0); } // move along to the right switch(ScreenResolution) { case LOW_RES: x += 8; break; case HI_RES: x += 16; break; default: assert(FALSE); } } } } } void ApplyStringColouringEffect (int effectID) { switch(effectID) { case FIRST: SometimesOscillateStringsColours(); break; case SECOND: SlowlyOscillateStringsColours(); break; default: assert(FALSE); } } void SometimesOscillateStringsColours (void) { int mainPeriod, subPeriod; int phase, miniPhase, tinyPhaseMax, tinyPhase; int r, g, b, colour; int i; mainPeriod = MaximumGameFramesPerSecond * 5; subPeriod = mainPeriod / 2; phase = frameNumber % mainPeriod; if (phase < subPeriod) { tinyPhaseMax = subPeriod/3; miniPhase = phase / tinyPhaseMax; switch(miniPhase) { case 0: tinyPhase = phase; r = 24 - ((tinyPhase * 16) / tinyPhaseMax); g = 0; b = 8 + ((tinyPhase * 16) / tinyPhaseMax); break; case 1: tinyPhase = phase - tinyPhaseMax; r = 0; g = 8 + ((tinyPhase * 16) / tinyPhaseMax); b = 24 - ((tinyPhase * 16) / tinyPhaseMax); break; case 2: tinyPhase = phase - (2 * tinyPhaseMax); r = 8 + ((tinyPhase * 16) / tinyPhaseMax); g = 24 - ((tinyPhase * 16) / tinyPhaseMax); b = 0; break; default: return; } colour = r + (g << 5) + (b << 10); for (i = 0; i < MAX_TEXT_STRINGS; i++) { AllStrings[i].colour = colour; } } } void SlowlyOscillateStringsColours (void) { int mainPeriod, subPeriod; int phase, miniPhase, tinyPhaseMax, tinyPhase; int r, g, b, colour; int i; mainPeriod = MaximumGameFramesPerSecond * 10; subPeriod = mainPeriod; phase = frameNumber % mainPeriod; { tinyPhaseMax = subPeriod/3; miniPhase = phase / tinyPhaseMax; switch(miniPhase) { case 0: tinyPhase = phase; r = 24 - ((tinyPhase * 16) / tinyPhaseMax); g = 0; b = 8 + ((tinyPhase * 16) / tinyPhaseMax); break; case 1: tinyPhase = phase - tinyPhaseMax; r = 0; g = 8 + ((tinyPhase * 16) / tinyPhaseMax); b = 24 - ((tinyPhase * 16) / tinyPhaseMax); break; case 2: tinyPhase = phase - (2 * tinyPhaseMax); r = 8 + ((tinyPhase * 16) / tinyPhaseMax); g = 24 - ((tinyPhase * 16) / tinyPhaseMax); b = 0; break; default: return; } colour = r + (g << 5) + (b << 10); for (i = 0; i < MAX_TEXT_STRINGS; i++) { AllStrings[i].colour = colour; } } }