This repository has been archived on 2024-11-07. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
Dawn-GB/src/conversation/textbox.c
2022-01-10 22:30:48 -08:00

125 lines
3.5 KiB
C

/**
* Copyright (c) 2022 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "textbox.h"
char *TEXTBOX_TEXT;
uint8_t TEXTBOX_TEXT_LENGTH;
uint8_t TEXTBOX_STATE;
uint8_t TEXTBOX_SCROLL;
uint8_t TEXTBOX_CHAR_POSITION;
inline void conversationTextboxInit() {
uint8_t i;
uint8_t TEXTBOX_TILES[TEXTBOX_TILES_MAX];
// Reset textbox state
TEXTBOX_TEXT = NULL;
TEXTBOX_STATE = 0;
TEXTBOX_TEXT_LENGTH = 0;
TEXTBOX_SCROLL = 0;
// Setup window data
move_win(7, SCREENHEIGHT - (TEXTBOX_HEIGHT_IN_TILES * 8));
set_win_data(FONT_DATA_POSITION, FONT_IMAGE_TILES, FONT_IMAGE);
set_win_data(BORDER_DATA_POSITION, BORDER_IMAGE_TILES, BORDER_IMAGE);
// Corners
TEXTBOX_TILES[0] = BORDER_TILE_TOP_LEFT;
TEXTBOX_TILES[TEXTBOX_WIDTH_IN_TILES-1] = BORDER_TILE_TOP_RIGHT;
TEXTBOX_TILES[TEXTBOX_TILES_MAX-1] = BORDER_TILE_BOTTOM_RIGHT;
TEXTBOX_TILES[TEXTBOX_TILES_MAX-TEXTBOX_WIDTH_IN_TILES] = BORDER_TILE_BOTTOM_LEFT;
// Edges
for(i = 1; i < TEXTBOX_WIDTH_IN_TILES - 1; i++) {
TEXTBOX_TILES[i] = BORDER_TILE_TOP_CENTER;
TEXTBOX_TILES[TEXTBOX_TILES_MAX - 1 - i] = BORDER_TILE_BOTTOM_CENTER;
}
for(i = 1; i < TEXTBOX_HEIGHT_IN_TILES - 1; i++) {
TEXTBOX_TILES[TEXTBOX_WIDTH_IN_TILES * i] = BORDER_TILE_CENTER_LEFT;
TEXTBOX_TILES[TEXTBOX_WIDTH_IN_TILES * (i+1) - 1] = BORDER_TILE_CENTER_RIGHT;
}
// Setup tiles.
set_win_tiles(
0, 0,
TEXTBOX_WIDTH_IN_TILES, TEXTBOX_HEIGHT_IN_TILES,
TEXTBOX_TILES
);
}
void conversationTextboxSetText(char *text, uint8_t length) {
uint8_t i, j;
uint8_t TEXTBOX_TILES[TEXTBOX_CHAR_ROWS * TEXTBOX_CHARS_PER_ROW];
// Reset textbox state
TEXTBOX_TEXT = text;
TEXTBOX_TEXT_LENGTH = length;
TEXTBOX_STATE = TEXTBOX_STATE_VISIBLE;
TEXTBOX_SCROLL = 0;
TEXTBOX_CHAR_POSITION = 0;
// Fill blank characters
for(j = 0; j < TEXTBOX_CHAR_ROWS; j++) {
for(i = 0; i < TEXTBOX_CHARS_PER_ROW ; i++) {
TEXTBOX_TILES[i + (j * TEXTBOX_CHARS_PER_ROW)] = TEXTBOX_TILE_BLANK;
}
}
set_win_tiles(
1, 1,
TEXTBOX_WIDTH_IN_TILES - 0x02, TEXTBOX_HEIGHT_IN_TILES - 0x02,
TEXTBOX_TILES
);
// Show the window layer.
SHOW_WIN;
}
inline void conversationTextboxUpdate() {
uint8_t i;
// Is the textbox visible?
if(!(TEXTBOX_STATE & TEXTBOX_STATE_VISIBLE)) return;
// Has the textbox finished scrolling?
if(TEXTBOX_STATE & TEXTBOX_STATE_SCROLLED) {
// Is the player attempting to close the textbox?
if(INPUT_STATE & J_A) {
TEXTBOX_STATE &= ~TEXTBOX_STATE_VISIBLE;
HIDE_WIN;
conversationQueueNext();
}
return;
}
// Move to the next character.
if(TEXTBOX_TEXT[TEXTBOX_SCROLL] == ' ') {
// Whitespace, do nothing.
TEXTBOX_CHAR_POSITION++;
} else if(TEXTBOX_TEXT[TEXTBOX_SCROLL] == '\n') {
// Newline character, move the next tile to the next row.
TEXTBOX_CHAR_POSITION = (
(TEXTBOX_CHAR_POSITION / TEXTBOX_CHARS_PER_ROW) + 1
) * TEXTBOX_CHARS_PER_ROW;
} else {
// Reveal the next character. TODO: I'll optimize this.
set_win_tiles(
1 + (TEXTBOX_CHAR_POSITION % TEXTBOX_CHARS_PER_ROW),
1 + (TEXTBOX_CHAR_POSITION / TEXTBOX_CHARS_PER_ROW),
1, 1,
TEXTBOX_TEXT + TEXTBOX_SCROLL
);
TEXTBOX_CHAR_POSITION++;
}
TEXTBOX_SCROLL++;
// Update state. TODO: I actually don't really need this state, it's just here
// incase I want to check if the state has scrolled later on? Doubt it though.
if(TEXTBOX_SCROLL == TEXTBOX_TEXT_LENGTH) {
TEXTBOX_STATE |= TEXTBOX_STATE_SCROLLED;
}
}