static void Save(int asCode) { char filename[128]; // char drive[_MAX_DRIVE]; char dir[96]; char name[32]; // char ext[_MAX_EXT]; char c; int i; strcpy(filename, lastFile); while (1) { memset(GetDstScreen(), 58, 64000); TextStringAt(125, 50, "Save as:"); TextGoto(125, 50 + TextHeight()); TextChar('\020'); TextString(filename); TextChar('\021'); vsync(); CopyToScreen(); c = GetKey(); switch (c) { case ENTER: if (!filename[0]) break; if (asCode) { SaveCampaignAsC(filename, name, &campaign); } else { SaveCampaign(filename, &campaign); } fileChanged = 0; return; case ESCAPE: return; case BACKSPACE: if (filename[0]) filename[strlen(filename) - 1] = 0; break; default: if (strlen(filename) == sizeof(filename) - 1) break; c = toupper(c); if ((c >= 'A' && c <= 'Z') || c == '-' || c == '_' || c == '\\') { i = strlen(filename); filename[i + 1] = 0; filename[i] = c; } } } }
int MissionDescription(int y, const char *description, int hilite) { int w_ws, w_word, x, lines; const char *ws, *word, *p, *s; TextGoto(20 - TextCharWidth('\020'), y); if (hilite) TextCharWithTable('\020', tableFlamed); else TextChar('\020'); x = 20; lines = 1; TextGoto(x, y); s = ws = word = description; while (*s) { // Find word ws = s; while (*s == ' ' || *s == '\n') s++; word = s; while (*s != 0 && *s != ' ' && *s != '\n') s++; for (w_ws = 0, p = ws; p < word; p++) w_ws += TextCharWidth(*p); for (w_word = 0; p < s; p++) w_word += TextCharWidth(*p); if (x + w_ws + w_word > 300 && w_ws + w_word < 280) { y += TextHeight(); x = 20; lines++; ws = word; w_ws = 0; } x += w_ws; TextGoto(x, y); for (p = word; p < s; p++) TextChar(*p); x += w_word; } if (hilite) TextCharWithTable('\021', tableFlamed); else TextChar('\021'); return lines; }
static void DisplayCharacter(int x, int y, const TBadGuy * data, int hilite) { struct CharacterDescription *cd; TOffsetPic body, head; cd = &characterDesc[0]; SetupMissionCharacter(0, data); body.dx = cBodyOffset[cd->unarmedBodyPic][DIRECTION_DOWN].dx; body.dy = cBodyOffset[cd->unarmedBodyPic][DIRECTION_DOWN].dy; body.picIndex = cBodyPic[cd->unarmedBodyPic][DIRECTION_DOWN][STATE_IDLE]; head.dx = cNeckOffset[cd->unarmedBodyPic][DIRECTION_DOWN].dx + cHeadOffset[cd->facePic][DIRECTION_DOWN].dx; head.dy = cNeckOffset[cd->unarmedBodyPic][DIRECTION_DOWN].dy + cHeadOffset[cd->facePic][DIRECTION_DOWN].dy; head.picIndex = cHeadPic[cd->facePic][DIRECTION_DOWN][STATE_IDLE]; DrawTTPic(x + body.dx, y + body.dy, gPics[body.picIndex], cd->table, NULL); DrawTTPic(x + head.dx, y + head.dy, gPics[head.picIndex], cd->table, NULL); if (hilite) { TextGoto(x - 8, y - 16); TextChar('\020'); } }
void DisplayCharacter(int x, int y, int character, int hilite) { struct CharacterDescription *cd; TOffsetPic body, head; cd = &characterDesc[character]; body.dx = cBodyOffset[cd->unarmedBodyPic][DIRECTION_DOWN].dx; body.dy = cBodyOffset[cd->unarmedBodyPic][DIRECTION_DOWN].dy; body.picIndex = cBodyPic[cd->unarmedBodyPic][DIRECTION_DOWN][STATE_IDLE]; head.dx = cNeckOffset[cd->unarmedBodyPic][DIRECTION_DOWN].dx + cHeadOffset[cd->facePic][DIRECTION_DOWN].dx; head.dy = cNeckOffset[cd->unarmedBodyPic][DIRECTION_DOWN].dy + cHeadOffset[cd->facePic][DIRECTION_DOWN].dy; head.picIndex = cHeadPic[cd->facePic][DIRECTION_DOWN][STATE_IDLE]; DrawTTPic(x + body.dx, y + body.dy, gPics[body.picIndex], cd->table, NULL); DrawTTPic(x + head.dx, y + head.dy, gPics[head.picIndex], cd->table, NULL); if (hilite) { TextGoto(x - 8, y - 16); TextChar('\020'); TextGoto(x - 8, y + 8); TextString(gunDesc[cd->defaultGun].gunName); } }
void DisplayText(int x, int y, const char *text, int hilite, int editable) { TextGoto(x, y); if (editable) { if (hilite) TextCharWithTable('\020', tableFlamed); else TextChar('\020'); } if (hilite && !editable) TextStringWithTable(text, tableFlamed); else TextString(text); if (editable) { if (hilite) TextCharWithTable('\021', tableFlamed); else TextChar('\021'); } }
void DisplayFlag(int x, int y, const char *s, int on, int hilite) { TextGoto(x, y); if (hilite) { TextStringWithTable(s, tableFlamed); TextCharWithTable(':', tableFlamed); } else { TextString(s); TextChar(':'); } if (on) TextStringWithTable("On", tablePurple); else TextString("Off"); }
void DisplayMapItem(int x, int y, TMapObject * mo, int density, int hilite) { char s[10]; TOffsetPic *pic = &cGeneralPics[mo->pic]; DrawTPic(x + pic->dx, y + pic->dy, gPics[pic->picIndex], NULL); if (hilite) { TextGoto(x - 8, y - 4); TextChar('\020'); } sprintf(s, "%d", density); TextGoto(x - 8, y + 5); TextString(s); SetSecondaryMouseRects(localMapItemClicks); }
void TextTerminal::Newline(TextBuffer* textbuf) { TextPos pos(column, line); TextChar tc = textbuf->GetChar(pos); if ( !(tc.attr & ATTR_CHAR) ) { tc.attr |= ATTR_CHAR; textbuf->SetChar(pos, tc); } column = 0; if ( line < textbuf->Height()-1 ) line++; else { textbuf->Scroll(1, TextChar(' ', vgacolor, 0)); line = textbuf->Height()-1; } }
void TextTerminal::Backspace(TextBuffer* textbuf) { TextPos pos(column, line); while ( pos.x || pos.y ) { pos = DecrementTextPos(textbuf, pos); TextChar tc = textbuf->GetChar(pos); next_attr = tc.attr & (ATTR_BOLD | ATTR_UNDERLINE); if ( tc.c == L'_' ) next_attr |= ATTR_UNDERLINE; else if ( tc.c == L' ' ) next_attr &= ~(ATTR_BOLD | ATTR_CHAR); else next_attr |= ATTR_BOLD; textbuf->SetChar(pos, TextChar(' ', vgacolor, 0)); if ( tc.attr & ATTR_CHAR ) break; } column = pos.x; line = pos.y; }
void TextString(const char *s) { while (*s) TextChar(*s++); }
void TextTerminal::RunAnsiCommand(TextBuffer* textbuf, char c) { const unsigned width = (unsigned) textbuf->Width(); const unsigned height = (unsigned) textbuf->Height(); switch ( c ) { case 'A': // Cursor up { unsigned dist = 0 < ansiusedparams ? ansiparams[0] : 1; if ( line < dist ) line = 0; else line -= dist; } break; case 'B': // Cursor down { unsigned dist = 0 < ansiusedparams ? ansiparams[0] : 1; if ( height <= line + dist ) line = height-1; else line += dist; } break; case 'C': // Cursor forward { unsigned dist = 0 < ansiusedparams ? ansiparams[0] : 1; if ( width <= column + dist ) column = width-1; else column += dist; } break; case 'D': // Cursor backward { unsigned dist = 0 < ansiusedparams ? ansiparams[0] : 1; if ( column < dist ) column = 0; else column -= dist; } break; case 'E': // Move to beginning of line N lines down. { column = 0; unsigned dist = 0 < ansiusedparams ? ansiparams[0] : 1; if ( height <= line + dist ) line = height-1; else line += dist; } break; case 'F': // Move to beginning of line N lines up. { column = 0; unsigned dist = 0 < ansiusedparams ? ansiparams[0] : 1; if ( line < dist ) line = 0; else line -= dist; } break; case 'G': // Move the cursor to column N. { unsigned pos = 0 < ansiusedparams ? ansiparams[0]-1 : 0; if ( width <= pos ) pos = width-1; column = pos; } break; case 'H': // Move the cursor to line Y, column X. case 'f': { unsigned posy = 0 < ansiusedparams ? ansiparams[0]-1 : 0; unsigned posx = 1 < ansiusedparams ? ansiparams[1]-1 : 0; if ( width <= posx ) posx = width-1; if ( height <= posy ) posy = height-1; column = posx; line = posy; } break; case 'J': // Erase parts of the screen. { unsigned mode = 0 < ansiusedparams ? ansiparams[0] : 0; TextPos from(0, 0); TextPos to(0, 0); if ( mode == 0 ) // From cursor to end. from = TextPos{column, line}, to = TextPos{width-1, height-1}; if ( mode == 1 ) // From start to cursor. from = TextPos{0, 0}, to = TextPos{column, line}; if ( mode == 2 ) // Everything. from = TextPos{0, 0}, to = TextPos{width-1, height-1}; textbuf->Fill(from, to, TextChar(' ', vgacolor, 0)); } break; case 'K': // Erase parts of the current line. { unsigned mode = 0 < ansiusedparams ? ansiparams[0] : 0; TextPos from(0, 0); TextPos to(0, 0); if ( mode == 0 ) // From cursor to end. from = TextPos{column, line}, to = TextPos{width-1, line}; if ( mode == 1 ) // From start to cursor. from = TextPos{0, line}, to = TextPos{column, line}; if ( mode == 2 ) // Everything. from = TextPos{0, line}, to = TextPos{width-1, line}; textbuf->Fill(from, to, TextChar(' ', vgacolor, 0)); } break; case 'S': // Scroll a line up and place a new line at the buttom. { textbuf->Scroll(1, TextChar(' ', vgacolor, 0)); line = height-1; } break; case 'T': // Scroll a line up and place a new line at the top. { textbuf->Scroll(-1, TextChar(' ', vgacolor, 0)); line = 0; } break; case 'm': // Change how the text is rendered. { if ( ansiusedparams == 0 ) { ansiparams[0] = 0; ansiusedparams++; } // Convert from the ANSI color scheme to the VGA color scheme. const unsigned conversion[8] = { COLOR8_BLACK, COLOR8_RED, COLOR8_GREEN, COLOR8_BROWN, COLOR8_BLUE, COLOR8_MAGENTA, COLOR8_CYAN, COLOR8_LIGHT_GREY, }; for ( size_t i = 0; i < ansiusedparams; i++ ) { unsigned cmd = ansiparams[i]; // Turn all attributes off. if ( cmd == 0 ) { vgacolor = DEFAULT_COLOR; } // Set text color. else if ( 30 <= cmd && cmd <= 37 ) { unsigned val = cmd - 30; vgacolor &= 0xF0; vgacolor |= conversion[val] << 0; } // Set default text color. else if ( cmd == 39 ) { vgacolor &= 0xF0; vgacolor |= DEFAULT_COLOR & 0x0F; } // Set background color. else if ( 40 <= cmd && cmd <= 47 ) { unsigned val = cmd - 40; vgacolor &= 0x0F; vgacolor |= conversion[val] << 4; } // Set default background color. else if ( cmd == 49 ) { vgacolor &= 0x0F; vgacolor |= DEFAULT_COLOR & 0xF0; } // Set text color. else if ( 90 <= cmd && cmd <= 97 ) { unsigned val = cmd - 90; vgacolor &= 0xF0; vgacolor |= (0x8 | conversion[val]) << 0; } // Set background color. else if ( 100 <= cmd && cmd <= 107 ) { unsigned val = cmd - 100; vgacolor &= 0x0F; vgacolor |= (0x8 | conversion[val]) << 4; } // TODO: There are many other things we don't support. } } break; case 'n': // Request special information from terminal. { // TODO: Handle this code. } break; case 's': // Save cursor position. { ansisavedposx = column; ansisavedposx = line; } break; case 'u': // Restore cursor position. { column = ansisavedposx; line = ansisavedposx; if ( width <= column ) column = width-1; if ( height <= line ) line = height-1; } break; case 'l': // Hide cursor. { // TODO: This is somehow related to the special char '?'. if ( 0 < ansiusedparams && ansiparams[0] == 25 ) textbuf->SetCursorEnabled(false); } break; case 'h': // Show cursor. { // TODO: This is somehow related to the special char '?'. if ( 0 < ansiusedparams && ansiparams[0] == 25 ) textbuf->SetCursorEnabled(true); } break; // TODO: Handle other cases. } ansimode = NONE; }
static int NameSelection(int x, int index, struct PlayerData *data, int cmd) { int i; int y; char s[2]; static char letters[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ !#?:.-0123456789"; static char smallLetters[] = "abcdefghijklmnopqrstuvwxyz !#?:.-0123456789"; static int selection[2] = { -1, -1 }; // Kludge since Watcom won't let me initialize selection with a strlen() if (selection[0] < 0) selection[0] = selection[1] = strlen(letters); if (cmd & CMD_BUTTON1) { if (selection[index] == strlen(letters)) { PlaySound(SND_LAUNCH, 0, 255); return 0; } if (strlen(data->name) < sizeof(data->name) - 1) { int l = strlen(data->name); data->name[l + 1] = 0; if (l > 0 && data->name[l - 1] != ' ') data->name[l] = smallLetters[selection[index]]; else data->name[l] = letters[selection[index]]; PlaySound(SND_MACHINEGUN, 0, 255); } else PlaySound(SND_KILL, 0, 255); } else if (cmd & CMD_BUTTON2) { if (data->name[0]) { data->name[strlen(data->name) - 1] = 0; PlaySound(SND_BANG, 0, 255); } else PlaySound(SND_KILL, 0, 255); } else if (cmd & CMD_LEFT) { if (selection[index] > 0) { selection[index]--; PlaySound(SND_DOOR, 0, 255); } } else if (cmd & CMD_RIGHT) { if (selection[index] < strlen(letters)) { selection[index]++; PlaySound(SND_DOOR, 0, 255); } } else if (cmd & CMD_UP) { if (selection[index] > 9) { selection[index] -= 10; PlaySound(SND_DOOR, 0, 255); } } else if (cmd & CMD_DOWN) { if (selection[index] < strlen(letters) - 9) { selection[index] += 10; PlaySound(SND_DOOR, 0, 255); } else if (selection[index] < strlen(letters)) { selection[index] = strlen(letters); PlaySound(SND_DOOR, 0, 255); } } #define ENTRY_COLS 10 #define ENTRY_SPACING 12 y = CenterY(((TextHeight() * ((strlen(letters) - 1) / ENTRY_COLS) ))); if (gOptions.twoPlayers && index == CHARACTER_PLAYER1) x = CenterOf(0, (SCREEN_WIDTH / 2), ((ENTRY_SPACING * (ENTRY_COLS - 1)) + TextCharWidth('a'))); else if (gOptions.twoPlayers && index == CHARACTER_PLAYER2) x = CenterOf((SCREEN_WIDTH / 2), (SCREEN_WIDTH), ((ENTRY_SPACING * (ENTRY_COLS - 1)) + TextCharWidth('a'))); else x = CenterX(((ENTRY_SPACING * (ENTRY_COLS - 1)) + TextCharWidth('a'))); // Draw selection s[1] = 0; for (i = 0; i < strlen(letters); i++) { s[0] = letters[i]; TextGoto(x + (i % ENTRY_COLS) * ENTRY_SPACING, y + (i / ENTRY_COLS) * TextHeight()); if (i == selection[index]) TextCharWithTable(letters[i], &tableFlamed); else TextChar(letters[i]); /* DisplayMenuItem(x + (i % 10) * 12, 80 + (i / 10) * TextHeight(), s, i == selection[index]); */ } DisplayMenuItem(x + (i % ENTRY_COLS) * ENTRY_SPACING, y + (i / ENTRY_COLS) * TextHeight(), endChoice, i == selection[index]); return 1; }