#include "joey.h" #include "ansiterm.h" #include "ztypes.h" #ifdef JOEY_IIGS segment "joeyio"; #endif #define DISPLAY_MIXED_SIZE 5 #define COMMAND_BUFFER_SIZE 32 typedef enum { DISPLAY_MODE_TEXT = 0, DISPLAY_MODE_GRAPHICS, DISPLAY_MODE_MIXED, DISPLAY_MODE_LAST } DModeT; static jlImgT *_bitmap = NULL; static jlVecT *_vectorImage = NULL; static jlImgT *_graphicsPage = NULL; static jlSoundT *_soundEffect = NULL; static DModeT _displayMode = DISPLAY_MODE_TEXT; static byte _bufferCount = 0; static char _buffer[COMMAND_BUFFER_SIZE]; static bool _inCommand = false; static byte _cursorIndex = 0; static byte _cursorSize = 8; static unsigned int _cursorTime = 0; static byte _cursor[] = { 32, 176, 177, 178, 219, 178, 177, 176 }; void set_next_display_mode(void); void clear_line(void) { termPrint("\33[K"); } void clear_screen(void) { termClearScreen(); termMoveCursor(1, (byte)screen_rows); jlDisplayPresent(); } void clear_status_window(void) { int i; int row; int col; get_cursor_position(&row, &col); for (i=status_size; i; i--) { move_cursor(i, 1); clear_line(); } move_cursor(row, col); } void clear_text_window(void) { int i; int row; int col; get_cursor_position(&row, &col); for (i=status_size + 1; i<=screen_rows; i++) { move_cursor(i, 1); clear_line(); } move_cursor(row, col); } void create_status_window(void) { //printf("Create Status Window\n"); } void delete_status_window(void) { //printf("Delete Status Window\n"); } void display_char(int c) { char command; char *token; int x; int y; // This also handles processing of embedded media commands: // {B name} - Display Bitmap // {I name x y} - Display Vector Image "name" @ x, y // {M name} - Play Music "name" // {S name} - Play Sound "name" // {Q} - Quiet! if (_inCommand) { if ((char) c == '}') { // Exit command mode. if (_bufferCount > 0) { // Did we get a command we understand? command = (char)toupper(_buffer[0]); _buffer[_bufferCount] = 0; (void)strtok(_buffer, " "); switch (command) { case 'B': token = strtok(NULL, " "); if (jlImgLoad(_bitmap, token)) { // Put user into GRAPHICS mode if they aren't. _displayMode = DISPLAY_MODE_GRAPHICS - 1; set_next_display_mode(); // Render the image. jlImgDisplay(_bitmap); // Save it to the graphics page. jlImgCreate(_graphicsPage); } jlSoundMusicPlay(token); break; case 'I': token = strtok(NULL, " "); if (jlVecLoad(_vectorImage, token)) { x = y = 0; token = strtok(NULL, " "); if (token != NULL) { x = atoi(token); token = strtok(NULL, " "); if (token != NULL) { y = atoi(token); } } // Put user into GRAPHICS mode if they aren't. _displayMode = DISPLAY_MODE_GRAPHICS - 1; set_next_display_mode(); // Render the image. jlVecDisplay(_vectorImage, (jint16)x, (jint16)y); // Save it to the graphics page. jlImgCreate(_graphicsPage); } break; case 'M': token = strtok(NULL, " "); jlSoundMusicPlay(token); break; case 'S': token = strtok(NULL, " "); if (jlSoundLoad(_soundEffect, token)) { jlSoundPlay(_soundEffect); } break; case 'Q': jlSoundMusicStop(); break; } } // Exit command mode _bufferCount = 0; _inCommand = false; } else { if (_bufferCount < COMMAND_BUFFER_SIZE - 1) { // Add character to command buffer. _buffer[_bufferCount++] = (char)c; } else { // Overflowed buffer - exit command mode _bufferCount = 0; _inCommand = false; } } } else { if ((char)c == '{') { // Switch to embedded command mode. _inCommand = true; } else { // Display game text. termPrintChar((char)c); } } } void get_cursor_position(int *row, int *col) { byte x; byte y; termGetCursor(&x, &y); *col = (int)x; *row = (int)y; } void initialize_screen(void) { // Also handled in main // Create initial empty graphics image. jlDrawColorSet(0); jlDrawClear(); jlDrawColorSet(15); jlDisplayPresent(); jlImgCreate(_graphicsPage); } int input_character(int timeout) { char k = 0; (void)timeout; // In 1/10ths of a second if (!jlKeyPressed()) { while (!jlKeyPressed() && !jlUtilMustExit()) { // Animate cursor if (jlUtilTimeSpan(_cursorTime, jlUtilTimer()) > 3) { display_char(_cursor[_cursorIndex++]); display_char(8); if (_cursorIndex >= _cursorSize) { _cursorIndex = 0; } _cursorTime = jlUtilTimer(); } } display_char(32); display_char(8); } while (jlKeyPressed() && !jlUtilMustExit()) { // Wait for key to be released } k = jlKeyRead(); if (jlUtilMustExit() && (interpreter_state == RUN)) { interpreter_state = STOP; } return (int)k; } int input_line(int buflen, char *buffer, int timeout, int *read_size) { int c = 0; int curr_char_pos = 0; (void)timeout; while (!jlUtilMustExit()) { c = input_character(0); if (c > 0) { if (c == 8) { // Backspace if (*read_size == 0) { //***TODO*** Flash border or ding or something } else { --*read_size; --curr_char_pos; display_char(8); display_char(32); display_char(8); } } else { // Normal Key if (*read_size == (buflen - 1)) { //***TODO*** Flash border or ding or something } else { if (c == 13) { if (curr_char_pos == 0) { set_next_display_mode(); } else { scroll_line(); return c; } } else { buffer[curr_char_pos++] = (char)c; if (*read_size < curr_char_pos) { *read_size = curr_char_pos; } display_char(c); } } } } } return c; } void move_cursor(int row, int col) { termMoveCursor((byte)col, (byte)row); } void reset_screen(void) { // Also handled in main jlImgFree(_graphicsPage); jlImgFree(_bitmap); jlVecFree(_vectorImage); jlSoundFree(_soundEffect); } void restart_screen(void) { // I don't think we need this. } void restore_cursor_position(void) { termRestoreCursor(); } void save_cursor_position(void) { termSaveCursor(); } void scroll_line(void) { //***TODO*** Should really not clobber the status window. termPrintChar(13); termPrintChar(10); } void select_status_window(void) { save_cursor_position(); } void select_text_window(void) { restore_cursor_position(); } void set_attribute(int attribute) { if (attribute == NORMAL) { termPrint("\33[0m"); } if (attribute & REVERSE) { termPrint("\33[7m"); } } void set_next_display_mode(void) { _displayMode++; if (_displayMode >= DISPLAY_MODE_LAST) { _displayMode = DISPLAY_MODE_TEXT; } switch (_displayMode) { case DISPLAY_MODE_TEXT: //printf("Terminal now TEXT\n"); termHideTopLines(0); termRepaint(); break; case DISPLAY_MODE_GRAPHICS: //printf("Terminal now GRAPHICS\n"); termHideTopLines((byte)screen_rows); jlImgDisplay(_graphicsPage); break; case DISPLAY_MODE_MIXED: //printf("Terminal now MIXED\n"); termHideTopLines((byte)screen_rows - DISPLAY_MIXED_SIZE); jlImgDisplay(_graphicsPage); termRepaint(); break; case DISPLAY_MODE_LAST: // Won't happen. Silences a warning. break; } }