#include "dialogs.h" #include #include #include #include "config.h" #define BOX_HEIGHT (F_HEIGHT/PXSIZE+8) extern font_t fontRPG; #define FONT_USED fontRPG #if GRAYMODEOK #include uint32_t *lightVRAMnext, *darkVRAMnext; uint32_t *lightVRAMcurrent, *darkVRAMcurrent; #endif //GRAYMODEOK void blit() { dupdate(); #if 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(Game *game, unsigned int i), bool start_anim, bool end_anim, void for_each_screen(Game *game, unsigned int i), int line_duration, bool line_anim, unsigned int start_i) { 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; draw(game); if(start_anim){ /* Run a little fancy animation. */ for(i=0;iframe_duration < 20) sleep(); game->frame_duration = 0; } }else{ drect(0, 0, DWIDTH, (BOX_HEIGHT-1)*PXSIZE, C_WHITE); drect(0, (BOX_HEIGHT-1)*PXSIZE, DWIDTH, BOX_HEIGHT*PXSIZE, C_BLACK); dsubimage(4*PXSIZE, 2*PXSIZE, face, 0, 0, F_WIDTH, (BOX_HEIGHT-7)*PXSIZE, DIMAGE_NONE); if(line_anim) dupdate(); while(game->frame_duration < 20) sleep(); game->frame_duration = 0; } /* We should start to drawing the text on the x axis at BOX_HEIGHT to avoid * drawing on the face. */ for(i=start_i;i0; 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; } } }else{ dtext_opt(BOX_HEIGHT*PXSIZE, y, C_BLACK, C_NONE, DTEXT_LEFT, DTEXT_TOP, text+i, line_max_chars); y += FONT_USED.line_height+PXSIZE; i += line_max_chars; l++; } if(l>=max_lines_amount-1){ /* We drew one entire screen, reset everything to draw the next one. */ /* Make a little animation :). */ if(line_anim) blit(); while(game->frame_duration < line_duration) 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 :). */ if(line_anim) 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 < line_duration) sleep(); game->frame_duration = 0; } } if(lframe_duration < line_duration) sleep(); game->frame_duration = 0; /* Ask the user to press EXE to continue. */ dtext(BOX_HEIGHT*PXSIZE, y, C_BLACK, "[EXE] to continue ..."); if(line_anim) blit(); while(getkey().key != KEY_EXE) sleep(); } if(call_before_end) return_int = call_before_end(game, i); if(end_anim){ /* 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_dialog(Game *game, bopti_image_t *face, char *text, bool dialog_start, bool dialog_end) { showtext_opt(game, face, text, NULL, dialog_start, dialog_end, NULL, 100, true, 0); } #define CHOICE_BOX_HEIGHT 10 #define CHOICE_BOX_PADDING_TOP 3 char *_choices, *_text; int _choices_amount, _default_choice; bopti_image_t *_face; unsigned int _i; void _choice_screen_call(Game *game, unsigned int i) { _i = i; } int _choice_call_before_end(Game *game, unsigned int org_i) { int i, key; /* Make a little animation because we looove little animations ;) */ for(i=0;iframe_duration < 20) sleep(); game->frame_duration = 0; } const int choice_size = DWIDTH/_choices_amount; int arrow_width, arrow_height, selected = _default_choice, pos = 0; dsize(">", &FONT_USED, &arrow_width, &arrow_height); arrow_width += FONT_USED.char_spacing; do{ /* Display the diffrent choices. */ for(i=0;i<_choices_amount;i++){ if(i == selected) dtext(i*choice_size+PXSIZE, (BOX_HEIGHT+CHOICE_BOX_PADDING_TOP)*PXSIZE, C_BLACK, ">"); dtext(i*choice_size+arrow_width+PXSIZE, (BOX_HEIGHT+CHOICE_BOX_PADDING_TOP)*PXSIZE, C_BLACK, _choices+pos+i); pos += strlen(_choices+pos); } blit(); key = getkey().key; if(key == KEY_LEFT && selected > 0){ /* Remove the old arrow. */ drect(selected*choice_size+PXSIZE, (BOX_HEIGHT+CHOICE_BOX_PADDING_TOP)*PXSIZE, selected*choice_size+PXSIZE+arrow_width, (BOX_HEIGHT+CHOICE_BOX_PADDING_TOP)*PXSIZE+arrow_height, C_WHITE); selected--; } else if(key == KEY_RIGHT && selected < _choices_amount-1){ /* Remove the old arrow. */ drect(selected*choice_size+PXSIZE, (BOX_HEIGHT+CHOICE_BOX_PADDING_TOP)*PXSIZE, selected*choice_size+PXSIZE+arrow_width, (BOX_HEIGHT+CHOICE_BOX_PADDING_TOP)*PXSIZE+arrow_height, C_WHITE); selected++; } }while(key != KEY_EXE); /* Make a little animation because we looove little animations ;) */ for(i=DWIDTH/8+1;i>0;i--){ draw(game); showtext_opt(game, _face, _text, NULL, false, false, NULL, 0, false, _i); drect(0, BOX_HEIGHT*PXSIZE, i*(DWIDTH/8), (BOX_HEIGHT+CHOICE_BOX_HEIGHT)*PXSIZE, C_WHITE); drect(i*(DWIDTH/8), BOX_HEIGHT*PXSIZE, i*(DWIDTH/8)+PXSIZE-1, (BOX_HEIGHT+CHOICE_BOX_HEIGHT+1)*PXSIZE, C_BLACK); drect(0, (BOX_HEIGHT+CHOICE_BOX_HEIGHT)*PXSIZE+1, i*(DWIDTH/8), (BOX_HEIGHT+CHOICE_BOX_HEIGHT+1)*PXSIZE, C_BLACK); dupdate(); while(game->frame_duration < 20) sleep(); game->frame_duration = 0; } return selected; } int showtext_dialog_ask(Game *game, bopti_image_t *face, char *text, bool start, bool end, char *choices, int choices_amount, int default_choice) { _choices = choices; _choices_amount = choices_amount; _default_choice = default_choice; _face = face; _text = text; return showtext_opt(game, face, text, _choice_call_before_end, start, end, _choice_screen_call, 100, true, 0); }