mirror of
https://git.planet-casio.com/Slyvtt/Collab_RPG.git
synced 2025-01-04 07:53:39 +01:00
207 lines
7.3 KiB
C
207 lines
7.3 KiB
C
#include "dialogs.h"
|
|
|
|
#include <gint/keyboard.h>
|
|
#include <gint/cpu.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include "config.h"
|
|
|
|
|
|
#define BOX_HEIGHT (F_HEIGHT/PXSIZE+8)
|
|
|
|
extern font_t fontRPG;
|
|
#define FONT_USED fontRPG
|
|
|
|
#ifdef GRAYMODEOK
|
|
#include <gint/gray.h>
|
|
uint32_t *lightVRAMnext, *darkVRAMnext;
|
|
uint32_t *lightVRAMcurrent, *darkVRAMcurrent;
|
|
#endif //GRAYMODEOK
|
|
|
|
|
|
void blit()
|
|
{
|
|
dupdate();
|
|
|
|
#ifdef GRAYMODEOK
|
|
dgray_getvram( &lightVRAMnext, &darkVRAMnext );
|
|
dgray_getscreen( &lightVRAMcurrent, &darkVRAMcurrent );
|
|
|
|
memcpy( lightVRAMnext, lightVRAMcurrent, 256*sizeof( uint32_t) );
|
|
memcpy( darkVRAMnext, darkVRAMcurrent, 256*sizeof( uint32_t) );
|
|
#endif
|
|
}
|
|
|
|
|
|
int showtext_opt(Game *game, bopti_image_t *face, char *text,
|
|
int call_before_end(void), bool start_anim, bool end_anim) {
|
|
dfont(&FONT_USED);
|
|
unsigned int i, n, y = PXSIZE, l = 0;
|
|
int line_max_chars, return_int = 0;
|
|
unsigned int max_lines_amount = (BOX_HEIGHT-2)*PXSIZE/
|
|
(FONT_USED.line_height+PXSIZE);
|
|
const char *c;
|
|
/* Run a little fancy animation. */
|
|
for(i=0;i<BOX_HEIGHT;i++){
|
|
draw(game);
|
|
|
|
drect(0, 0, DWIDTH, i*PXSIZE, C_WHITE);
|
|
drect(0, i*PXSIZE, DWIDTH, (i+1)*PXSIZE, C_BLACK);
|
|
dsubimage(4*PXSIZE, 2*PXSIZE, face, 0, 0, F_WIDTH, (i-8)*PXSIZE,
|
|
DIMAGE_NONE);
|
|
|
|
dupdate();
|
|
|
|
while(game->frame_duration < 20) sleep();
|
|
game->frame_duration = 0;
|
|
}
|
|
/* We should start to drawint the text on the x axis at BOX_HEIGHT to avoid
|
|
* drawing on the face. */
|
|
/* Show a little message that showing text in dialogs is not implemented
|
|
* yet. */
|
|
for(i=0;i<strlen(text);i++){
|
|
/* Get how many chars we can draw on screen with a padding on the left
|
|
* of BOX_HEIGHT px and on the right of 1 px. */
|
|
c = drsize(text+i, &FONT_USED, DWIDTH-(BOX_HEIGHT*PXSIZE+PXSIZE), NULL);
|
|
/* c is a pointer to the last char that can be drawn. So: */
|
|
line_max_chars = c-(text+i);
|
|
/* TODO: Handle lines that are longer than what I can draw. */
|
|
/* Loop from the end to the start for word wrap. */
|
|
for(n=line_max_chars; n>0; n--) {
|
|
/* If we found a space, we can draw this line and do the same for
|
|
* the next line. */
|
|
if(text[i+n] == ' '){
|
|
dtext_opt(BOX_HEIGHT*PXSIZE, y, C_BLACK, C_NONE, DTEXT_LEFT,
|
|
DTEXT_TOP, text+i, n); /* Draw everything. */
|
|
/* Increment y by the line height. */
|
|
y += FONT_USED.line_height+PXSIZE;
|
|
i += n; /* We drew everything to i+n */
|
|
l++; /* We drew one more line. */
|
|
break;
|
|
}
|
|
}
|
|
if(l>=max_lines_amount-1){
|
|
/* We drew one entire screen, reset everything to draw the next one.
|
|
*/
|
|
/* Make a little animation :). */
|
|
blit();
|
|
while(game->frame_duration < 1000) sleep();
|
|
game->frame_duration = 0;
|
|
/* Ask the user to press EXE to continue. */
|
|
dtext(BOX_HEIGHT*PXSIZE, y, C_BLACK, "[EXE] to continue ...");
|
|
}
|
|
/* Make a little animation :). */
|
|
blit();
|
|
if(l>=max_lines_amount-1){
|
|
while(getkey().key != KEY_EXE) sleep();
|
|
/* Clear the screen. */
|
|
drect(BOX_HEIGHT*PXSIZE, 0, DWIDTH, (BOX_HEIGHT-1)*PXSIZE-1,
|
|
C_WHITE);
|
|
/* Reset y and l. */
|
|
y = PXSIZE;
|
|
l = 0;
|
|
}
|
|
else{
|
|
while(game->frame_duration < 1000) sleep();
|
|
game->frame_duration = 0;
|
|
}
|
|
}
|
|
if(l<max_lines_amount-1){
|
|
/* If we have not filled everthing with text at the end. */
|
|
/* Make a little animation :). */
|
|
blit();
|
|
while(game->frame_duration < 1000) sleep();
|
|
game->frame_duration = 0;
|
|
/* Ask the user to press EXE to continue. */
|
|
dtext(1, y, C_BLACK, "[EXE] To continue ...");
|
|
blit();
|
|
while(getkey().key != KEY_EXE) sleep();
|
|
}
|
|
if(call_before_end) return_int = call_before_end();
|
|
/* Run another little fancy animation. */
|
|
for(i=40;i>0;i--){
|
|
draw(game);
|
|
drect(0, 0, DWIDTH, i*PXSIZE, C_WHITE);
|
|
drect(0, i*PXSIZE, DWIDTH, (i+1)*PXSIZE, C_BLACK);
|
|
dsubimage(4*PXSIZE, 2*PXSIZE, face, 0, 0, F_WIDTH, (i-8)*PXSIZE,
|
|
DIMAGE_NONE);
|
|
|
|
dupdate();
|
|
|
|
while(game->frame_duration < 20) sleep();
|
|
game->frame_duration = 0;
|
|
}
|
|
return return_int;
|
|
}
|
|
|
|
void showtext(Game *game, bopti_image_t *face, char *text) {
|
|
showtext_opt(game, face, text, NULL, true, true);
|
|
}
|
|
|
|
void showtext_dialog_start(Game *game, bopti_image_t *face, char *text) {
|
|
showtext_opt(game, face, text, NULL, true, false);
|
|
}
|
|
|
|
void showtext_dialog_mid(Game *game, bopti_image_t *face, char *text) {
|
|
showtext_opt(game, face, text, NULL, false, false);
|
|
}
|
|
|
|
void showtext_dialog_end(Game *game, bopti_image_t *face, char *text) {
|
|
showtext_opt(game, face, text, NULL, false, true);
|
|
}
|
|
|
|
#define CHOICE_BOX_HEIGHT 10
|
|
#define CHOICE_BOX_PADDING_TOP 3
|
|
|
|
char **choices;
|
|
int choices_amount, default_choice;
|
|
|
|
int _choice_call_before_end(void) {
|
|
int i, key;
|
|
/* Make a little animation because we looove little animations ;) */
|
|
for(i=0;i<DWIDTH/8+1;i++){
|
|
drect(0, (BOX_HEIGHT+CHOICE_BOX_HEIGHT)*PXSIZE, i*(DWIDTH/8),
|
|
(BOX_HEIGHT+CHOICE_BOX_HEIGHT)*PXSIZE, C_WHITE);
|
|
drect(i*(DWIDTH/8), 0, i*(DWIDTH/8)+PXSIZE,
|
|
(BOX_HEIGHT+CHOICE_BOX_HEIGHT)*PXSIZE, C_BLACK);
|
|
drect(0, (BOX_HEIGHT+CHOICE_BOX_HEIGHT)*PXSIZE, i*(DWIDTH/8),
|
|
(BOX_HEIGHT+CHOICE_BOX_HEIGHT+1)*PXSIZE, C_BLACK);
|
|
blit();
|
|
while(game->frame_duration < 20) sleep();
|
|
game->frame_duration = 0;
|
|
}
|
|
const int choice_size = DWIDTH/choices_amount;
|
|
int arrow_width, selected = default_choice;
|
|
dsize(">", FONT_USED, &arrow_width, NULL);
|
|
do{
|
|
/* Clear the box. */
|
|
drect(0, (BOX_HEIGHT+CHOICE_BOX_HEIGHT)*PXSIZE, (DWIDTH/8)*(DWIDTH/8),
|
|
(BOX_HEIGHT+CHOICE_BOX_HEIGHT)*PXSIZE, C_WHITE);
|
|
for(i=0;i<choices_amount;i++){
|
|
if(i == selected) dtext(i*choice_size,
|
|
BOX_HEIGHT+PXSIZE*CHOICE_BOX_PADDING_TOP,
|
|
C_BLACK, ">");
|
|
dtext(i*choice_size+arrow_width,
|
|
BOX_HEIGHT+PXSIZE*CHOICE_BOX_PADDING_TOP, C_BLACK,
|
|
choices[i]);
|
|
}
|
|
blit();
|
|
key = getkey().key;
|
|
if(key == KEY_LEFT && selected > 0) selected--;
|
|
else if(key == KEY_RIGHT && selected < choices_amount) selected++;
|
|
}while(key != KEY_EXE);
|
|
/* Make a little animation because we looove little animations ;) */
|
|
for(i=DWIDTH/8+1;i>0;i++){
|
|
drect(0, (BOX_HEIGHT+CHOICE_BOX_HEIGHT)*PXSIZE, i*(DWIDTH/8),
|
|
(BOX_HEIGHT+CHOICE_BOX_HEIGHT)*PXSIZE, C_WHITE);
|
|
drect(i*(DWIDTH/8), 0, i*(DWIDTH/8)+PXSIZE,
|
|
(BOX_HEIGHT+CHOICE_BOX_HEIGHT)*PXSIZE, C_BLACK);
|
|
drect(0, (BOX_HEIGHT+CHOICE_BOX_HEIGHT)*PXSIZE, i*(DWIDTH/8),
|
|
(BOX_HEIGHT+CHOICE_BOX_HEIGHT+1)*PXSIZE, C_BLACK);
|
|
blit();
|
|
while(game->frame_duration < 20) sleep();
|
|
game->frame_duration = 0;
|
|
}
|
|
return selected;
|
|
}
|