VASTLY improved how I generate tiles and tiledata
This commit is contained in:
@@ -1,150 +1,144 @@
|
||||
/**
|
||||
* Copyright (c) 2022 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#include "textbox.h"
|
||||
|
||||
char TEXTBOX_TEXTS[TEXTBOX_SCROLL_ROWS_MAX * TEXTBOX_CHARS_PER_ROW];
|
||||
uint8_t TEXTBOX_ROW_COUNT;
|
||||
uint8_t TEXTBOX_ROW_TILE_LAST;
|
||||
uint8_t TEXTBOX_ROW_CURRENT;
|
||||
uint8_t TEXTBOX_STATE;
|
||||
uint8_t TEXTBOX_SCROLL;
|
||||
|
||||
inline void conversationTextboxInit() {
|
||||
uint8_t i;
|
||||
uint8_t TEXTBOX_TILES[TEXTBOX_TILES_MAX];
|
||||
|
||||
// Reset textbox state
|
||||
TEXTBOX_STATE = 0;
|
||||
|
||||
// Setup window data
|
||||
set_win_data(FONT_DATA_POSITION, FONT_IMAGE_TILES, FONT_IMAGE);
|
||||
set_win_data(BORDER_DATA_POSITION, BORDER_IMAGE_TILES, BORDER_IMAGE);
|
||||
}
|
||||
|
||||
void conversationTextboxSetText(char *text) {
|
||||
uint8_t i, j, k, rowStart, stateFlags;
|
||||
char c, c2;
|
||||
|
||||
// Begin by filling the textbox text chars with whitespace to begin.
|
||||
// TODO: I'm pretty sure I can move this lower and optimize.
|
||||
for(i = 0; i < TEXTBOX_SCROLL_ROWS_MAX * TEXTBOX_CHARS_PER_ROW; i++) {
|
||||
TEXTBOX_TEXTS[i] = ' ';
|
||||
}
|
||||
|
||||
// Reset textbox state
|
||||
TEXTBOX_STATE = TEXTBOX_STATE_VISIBLE;
|
||||
TEXTBOX_SCROLL = 0;
|
||||
TEXTBOX_ROW_COUNT = 0;
|
||||
TEXTBOX_ROW_COUNT = 1;
|
||||
|
||||
// Copy source text to buffer, also determine wordwrapping here.
|
||||
i = 0, j = 0, rowStart = 0, stateFlags = 0;
|
||||
while((c = text[i]) != '\0') {// "For each char in string"
|
||||
if(c == ' ') {
|
||||
// Scan ahead and look at how many chars remain to the next space.
|
||||
k = i + 1;
|
||||
while(
|
||||
(c2 = text[k]) != '\0' &&
|
||||
c2 != '\n' &&
|
||||
c2 != ' ' &&
|
||||
(k - rowStart) < TEXTBOX_CHARS_PER_ROW
|
||||
) k++;
|
||||
|
||||
// IF that number is less than the remaining chars on the current row,
|
||||
// then treat this space like a newline.
|
||||
if(k >= (rowStart + TEXTBOX_CHARS_PER_ROW + 1)) {
|
||||
stateFlags |= 1 << 0;
|
||||
}
|
||||
} else if(c == '\n') {
|
||||
stateFlags |= 1 << 0;
|
||||
}
|
||||
|
||||
// Do we need to insert newline where we are currently?
|
||||
if((stateFlags & (1 << 0)) != 0) {
|
||||
stateFlags &= ~(1 << 0);// Remove newline flag
|
||||
i++;
|
||||
rowStart = i;// Update the row start (Should this be i+1?)
|
||||
//TODO: can I optimize the next line by using rowStart somehow?
|
||||
j = ((j / TEXTBOX_CHARS_PER_ROW)+1) * TEXTBOX_CHARS_PER_ROW;// Update destination character position.
|
||||
TEXTBOX_ROW_COUNT++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Insert the character
|
||||
TEXTBOX_TEXTS[j] = c;
|
||||
i++;
|
||||
j++;
|
||||
}
|
||||
|
||||
// Now we have organized the string nicely we can prep for rendering. Fill the
|
||||
// tiles with blank chars.
|
||||
textboxFillBlank();
|
||||
}
|
||||
|
||||
inline void textboxFillBlank() {
|
||||
uint8_t TEXTBOX_TILES[TEXTBOX_WIDTH_IN_TILES * TEXTBOX_HEIGHT_IN_TILES];
|
||||
|
||||
frameBuffer(TEXTBOX_TILES, TEXTBOX_WIDTH_IN_TILES, TEXTBOX_HEIGHT_IN_TILES, TEXTBOX_TILE_BLANK);
|
||||
|
||||
set_bkg_tiles(
|
||||
0x00, TEXTBOX_WIN_Y,
|
||||
TEXTBOX_WIDTH_IN_TILES, TEXTBOX_HEIGHT_IN_TILES,
|
||||
TEXTBOX_TILES
|
||||
);
|
||||
}
|
||||
|
||||
inline void conversationTextboxUpdate() {
|
||||
uint8_t i;
|
||||
char c;
|
||||
uint8_t tiles[1];
|
||||
|
||||
// Is the textbox visible?
|
||||
if((TEXTBOX_STATE & TEXTBOX_STATE_VISIBLE) == 0) return;
|
||||
|
||||
// Have we finished scrolling?
|
||||
if(TEXTBOX_STATE & TEXTBOX_STATE_SCROLLED) {
|
||||
// Is the user trying to go to the next line?
|
||||
if(INPUT_PRESSED & J_A) {
|
||||
// First, lets figure out if there's any more text to reveal or not.
|
||||
if((TEXTBOX_ROW_COUNT - TEXTBOX_ROW_CURRENT) < TEXTBOX_TILES_ROWS) {
|
||||
TEXTBOX_STATE &= ~TEXTBOX_STATE_VISIBLE;
|
||||
HIDE_WIN;
|
||||
conversationQueueNext();
|
||||
return;
|
||||
}
|
||||
|
||||
TEXTBOX_STATE &= ~TEXTBOX_STATE_SCROLLED;
|
||||
TEXTBOX_SCROLL = 0;
|
||||
TEXTBOX_ROW_CURRENT += TEXTBOX_TILES_ROWS;
|
||||
textboxFillBlank();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Move to the next character.
|
||||
i = TEXTBOX_ROW_CURRENT * TEXTBOX_CHARS_PER_ROW;
|
||||
c = TEXTBOX_TEXTS[i+TEXTBOX_SCROLL];
|
||||
|
||||
if(TEXTBOX_SCROLL == TEXTBOX_CHARS_MAX) {
|
||||
TEXTBOX_STATE |= TEXTBOX_STATE_SCROLLED;
|
||||
} else {
|
||||
tiles[0] = c - TEXTBOX_FONT_START + FONT_DATA_POSITION;
|
||||
|
||||
set_bkg_tiles(
|
||||
0x01 + (TEXTBOX_SCROLL % TEXTBOX_CHARS_PER_ROW),
|
||||
TEXTBOX_WIN_Y + 0x01 + (TEXTBOX_SCROLL / TEXTBOX_CHARS_PER_ROW),
|
||||
1, 1,
|
||||
tiles
|
||||
);
|
||||
|
||||
TEXTBOX_SCROLL++;
|
||||
|
||||
// Skip spaces
|
||||
while(TEXTBOX_SCROLL < TEXTBOX_CHARS_MAX && TEXTBOX_TEXTS[i+TEXTBOX_SCROLL] == ' ') TEXTBOX_SCROLL++;
|
||||
}
|
||||
/**
|
||||
* Copyright (c) 2022 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#include "textbox.h"
|
||||
|
||||
char TEXTBOX_TEXTS[TEXTBOX_SCROLL_ROWS_MAX * TEXTBOX_CHARS_PER_ROW];
|
||||
uint8_t TEXTBOX_ROW_COUNT;
|
||||
uint8_t TEXTBOX_ROW_TILE_LAST;
|
||||
uint8_t TEXTBOX_ROW_CURRENT;
|
||||
uint8_t TEXTBOX_STATE;
|
||||
uint8_t TEXTBOX_SCROLL;
|
||||
|
||||
inline void conversationTextboxInit() {
|
||||
// Reset textbox state
|
||||
TEXTBOX_STATE = 0;
|
||||
}
|
||||
|
||||
void conversationTextboxSetText(char *text) {
|
||||
uint8_t i, j, k, rowStart, stateFlags;
|
||||
char c, c2;
|
||||
|
||||
// Begin by filling the textbox text chars with whitespace to begin.
|
||||
// TODO: I'm pretty sure I can move this lower and optimize.
|
||||
for(i = 0; i < TEXTBOX_SCROLL_ROWS_MAX * TEXTBOX_CHARS_PER_ROW; i++) {
|
||||
TEXTBOX_TEXTS[i] = ' ';
|
||||
}
|
||||
|
||||
// Reset textbox state
|
||||
TEXTBOX_STATE = TEXTBOX_STATE_VISIBLE;
|
||||
TEXTBOX_SCROLL = 0;
|
||||
TEXTBOX_ROW_COUNT = 0;
|
||||
TEXTBOX_ROW_COUNT = 1;
|
||||
|
||||
// Copy source text to buffer, also determine wordwrapping here.
|
||||
i = 0, j = 0, rowStart = 0, stateFlags = 0;
|
||||
while((c = text[i]) != '\0') {// "For each char in string"
|
||||
if(c == ' ') {
|
||||
// Scan ahead and look at how many chars remain to the next space.
|
||||
k = i + 1;
|
||||
while(
|
||||
(c2 = text[k]) != '\0' &&
|
||||
c2 != '\n' &&
|
||||
c2 != ' ' &&
|
||||
(k - rowStart) < TEXTBOX_CHARS_PER_ROW
|
||||
) k++;
|
||||
|
||||
// IF that number is less than the remaining chars on the current row,
|
||||
// then treat this space like a newline.
|
||||
if(k >= (rowStart + TEXTBOX_CHARS_PER_ROW + 1)) {
|
||||
stateFlags |= 1 << 0;
|
||||
}
|
||||
} else if(c == '\n') {
|
||||
stateFlags |= 1 << 0;
|
||||
}
|
||||
|
||||
// Do we need to insert newline where we are currently?
|
||||
if((stateFlags & (1 << 0)) != 0) {
|
||||
stateFlags &= ~(1 << 0);// Remove newline flag
|
||||
i++;
|
||||
rowStart = i;// Update the row start (Should this be i+1?)
|
||||
//TODO: can I optimize the next line by using rowStart somehow?
|
||||
j = ((j / TEXTBOX_CHARS_PER_ROW)+1) * TEXTBOX_CHARS_PER_ROW;// Update destination character position.
|
||||
TEXTBOX_ROW_COUNT++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Insert the character
|
||||
TEXTBOX_TEXTS[j] = c;
|
||||
i++;
|
||||
j++;
|
||||
}
|
||||
|
||||
// Now we have organized the string nicely we can prep for rendering. Fill the
|
||||
// tiles with blank chars.
|
||||
textboxFillBlank();
|
||||
}
|
||||
|
||||
inline void textboxFillBlank() {
|
||||
uint8_t tiles[TEXTBOX_WIDTH_IN_TILES * TEXTBOX_HEIGHT_IN_TILES];
|
||||
|
||||
spriteBorderBufferEdges(
|
||||
tiles, TEXTBOX_WIDTH_IN_TILES, TEXTBOX_HEIGHT_IN_TILES, SPRITE_TILESET_WHITE
|
||||
);
|
||||
|
||||
set_bkg_tiles(
|
||||
0x00, TEXTBOX_WIN_Y,
|
||||
TEXTBOX_WIDTH_IN_TILES, TEXTBOX_HEIGHT_IN_TILES,
|
||||
tiles
|
||||
);
|
||||
}
|
||||
|
||||
inline void conversationTextboxUpdate() {
|
||||
uint8_t i, tile;
|
||||
char c;
|
||||
|
||||
// Is the textbox visible?
|
||||
if((TEXTBOX_STATE & TEXTBOX_STATE_VISIBLE) == 0) return;
|
||||
|
||||
// Have we finished scrolling?
|
||||
if(TEXTBOX_STATE & TEXTBOX_STATE_SCROLLED) {
|
||||
// Is the user trying to go to the next line?
|
||||
if(INPUT_PRESSED & J_A) {
|
||||
// First, lets figure out if there's any more text to reveal or not.
|
||||
if((TEXTBOX_ROW_COUNT - TEXTBOX_ROW_CURRENT) < TEXTBOX_TILES_ROWS) {
|
||||
TEXTBOX_STATE &= ~TEXTBOX_STATE_VISIBLE;
|
||||
HIDE_WIN;
|
||||
conversationQueueNext();
|
||||
return;
|
||||
}
|
||||
|
||||
TEXTBOX_STATE &= ~TEXTBOX_STATE_SCROLLED;
|
||||
TEXTBOX_SCROLL = 0;
|
||||
TEXTBOX_ROW_CURRENT += TEXTBOX_TILES_ROWS;
|
||||
textboxFillBlank();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Move to the next character.
|
||||
i = TEXTBOX_ROW_CURRENT * TEXTBOX_CHARS_PER_ROW;
|
||||
c = TEXTBOX_TEXTS[i+TEXTBOX_SCROLL];
|
||||
|
||||
if(TEXTBOX_SCROLL == TEXTBOX_CHARS_MAX) {
|
||||
TEXTBOX_STATE |= TEXTBOX_STATE_SCROLLED;
|
||||
} else {
|
||||
tile = spriteFontTileFromChar(c);
|
||||
|
||||
set_bkg_tiles(
|
||||
0x01 + (TEXTBOX_SCROLL % TEXTBOX_CHARS_PER_ROW),
|
||||
TEXTBOX_WIN_Y + 0x01 + (TEXTBOX_SCROLL / TEXTBOX_CHARS_PER_ROW),
|
||||
1, 1,
|
||||
&tile
|
||||
);
|
||||
|
||||
TEXTBOX_SCROLL++;
|
||||
|
||||
// Skip spaces
|
||||
while(TEXTBOX_SCROLL < TEXTBOX_CHARS_MAX && TEXTBOX_TEXTS[i+TEXTBOX_SCROLL] == ' ') TEXTBOX_SCROLL++;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user