void ScriptHandler::readConfiguration() { variable_range = 4096; global_variable_border = 200; char *buf = script_buffer; while ( buf < script_buffer + script_buffer_length ){ if (*buf == ';') break; if (IS_TWO_BYTE(*buf)) buf++; buf++; } while ( ++buf >= script_buffer + script_buffer_length ) return; SKIP_SPACE(buf); bool config_flag = false; if (buf[0] == '$'){ config_flag = true; buf++; } while (*buf && *buf != 0x0a){ SKIP_SPACE(buf); if (!strncmp( buf, "mode", 4 )){ buf += 4; if (!strncmp( buf, "800", 3 )){ screen_width = 800; screen_height = 600; buf += 3; } else if (!strncmp( buf, "400", 3 )){ screen_width = 400; screen_height = 300; buf += 3; } else if (!strncmp( buf, "320", 3 )){ screen_width = 320; screen_height = 240; buf += 3; } else break; } else if (!strncmp( buf, "value", 5 ) || *buf == 'g' || *buf == 'G'){ if (*buf == 'g' || *buf == 'G') buf++; else buf += 5; SKIP_SPACE(buf); global_variable_border = 0; while ( *buf >= '0' && *buf <= '9' ) global_variable_border = global_variable_border*10 + *buf++ - '0'; } else if (*buf == 'v' || *buf == 'V'){ buf++; SKIP_SPACE(buf); variable_range = 0; while (*buf >= '0' && *buf <= '9') variable_range = variable_range*10 + *buf++ - '0'; } else if (*buf == 's' || *buf == 'S'){ buf++; if (!(*buf >= '0' && *buf <= '9')) break; screen_width = 0; while (*buf >= '0' && *buf <= '9') screen_width = screen_width*10 + *buf++ - '0'; while (*buf == ',' || *buf == ' ' || *buf == '\t') buf++; screen_height = 0; while (*buf >= '0' && *buf <= '9') screen_height = screen_height*10 + *buf++ - '0'; } else if (*buf == 'l' || *buf == 'L'){ buf++; SKIP_SPACE(buf); while (*buf >= '0' && *buf <= '9') buf++; } else if (*buf != ',') break; SKIP_SPACE(buf); if (!config_flag && *buf != ',') break; if (*buf == ',') buf++; } }
// basic parser function const char *ScriptHandler::readToken() { current_script = next_script; wait_script = NULL; char *buf = current_script; end_status = END_NONE; current_variable.type = VAR_NONE; text_flag = false; SKIP_SPACE( buf ); markAsKidoku( buf ); readTokenTop: string_counter = 0; char ch = *buf; if (ch == ';'){ // comment addStringBuffer( ch ); do{ ch = *++buf; addStringBuffer( ch ); } while ( ch != 0x0a && ch != '\0' ); } else if (ch & 0x80 || (ch >= '0' && ch <= '9') || ch == '@' || ch == '\\' || ch == '/' || ch == '%' || ch == '?' || ch == '$' || ch == '[' || ch == '(' || ch == '<' || #ifndef ENABLE_1BYTE_CHAR ch == '`' || #endif (!english_mode && ch == '>') || ch == '!' || ch == '#' || ch == ',' || ch == '"'){ // text bool ignore_clickstr_flag = false; while(1){ if ( IS_TWO_BYTE(ch) ){ addStringBuffer( ch ); ch = *++buf; if (ch == 0x0a || ch == '\0') break; addStringBuffer( ch ); buf++; if (!wait_script && !ignore_clickstr_flag && checkClickstr(buf-2) > 0) wait_script = buf; ignore_clickstr_flag = false; } else{ ignore_clickstr_flag = false; if (ch == '%' || ch == '?'){ addIntVariable(&buf); SKIP_SPACE(buf); } else if (ch == '$'){ addStrVariable(&buf); SKIP_SPACE(buf); } else{ if (ch == 0x0a || ch == '\0') break; addStringBuffer( ch ); buf++; if (ch == '_') ignore_clickstr_flag = true; if (!wait_script && ch == '@') wait_script = buf; } } ch = *buf; } text_flag = true; } #ifdef ENABLE_1BYTE_CHAR else if (ch == '`'){ ch = *++buf; while (ch != '`' && ch != 0x0a && ch !='\0'){ if ( IS_TWO_BYTE(ch) ){ addStringBuffer( ch ); ch = *++buf; } addStringBuffer( ch ); ch = *++buf; } if (ch == '`') buf++; text_flag = true; end_status |= END_1BYTE_CHAR; } #endif else if (english_mode && ch == '>'){ ch = *++buf; while (1){ if (ch == 0x0a || ch =='\0') break; if (ch != '\t') addStringBuffer( ch ); ch = *++buf; } text_flag = true; end_status |= END_1BYTE_CHAR; } else if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || ch == '_'){ // command do{ if (ch >= 'A' && ch <= 'Z') ch += 'a' - 'A'; addStringBuffer( ch ); ch = *++buf; } while((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || (ch >= '0' && ch <= '9') || ch == '_'); } else if (ch == '*'){ // label return readLabel(); } else if (ch == '~' || ch == 0x0a || ch == ':'){ addStringBuffer( ch ); markAsKidoku( buf++ ); } else if (ch != '\0'){ fprintf(stderr, "readToken: skip unknown heading character %c (%x)\n", ch, ch); buf++; goto readTokenTop; } next_script = checkComma(buf); //printf("readToken [%s] len=%d [%c(%x)] %p\n", string_buffer, strlen(string_buffer), ch, ch, next_script); return string_buffer; }
int ONScripterLabel::processText() { //printf("textCommand %c %d %d %d\n", script_h.getStringBuffer()[ string_buffer_offset ], string_buffer_offset, event_mode, line_enter_status); char out_text[3]= {'\0', '\0', '\0'}; if ( event_mode & (WAIT_INPUT_MODE | WAIT_SLEEP_MODE) ){ draw_cursor_flag = false; if ( clickstr_state == CLICK_WAIT ){ if (script_h.checkClickstr(script_h.getStringBuffer() + string_buffer_offset) != 1) string_buffer_offset++; string_buffer_offset++; clickstr_state = CLICK_NONE; } else if ( clickstr_state == CLICK_NEWPAGE ){ event_mode = IDLE_EVENT_MODE; if (script_h.checkClickstr(script_h.getStringBuffer() + string_buffer_offset) != 1) string_buffer_offset++; string_buffer_offset++; newPage( true ); clickstr_state = CLICK_NONE; return RET_CONTINUE | RET_NOREAD; } else if ( IS_TWO_BYTE(script_h.getStringBuffer()[ string_buffer_offset ]) ){ string_buffer_offset += 2; } else if ( script_h.getStringBuffer()[ string_buffer_offset ] == '!' ){ string_buffer_offset++; if ( script_h.getStringBuffer()[ string_buffer_offset ] == 'w' || script_h.getStringBuffer()[ string_buffer_offset ] == 'd' ){ string_buffer_offset++; while ( script_h.getStringBuffer()[ string_buffer_offset ] >= '0' && script_h.getStringBuffer()[ string_buffer_offset ] <= '9' ) string_buffer_offset++; while (script_h.getStringBuffer()[ string_buffer_offset ] == ' ' || script_h.getStringBuffer()[ string_buffer_offset ] == '\t') string_buffer_offset++; } } else if ( script_h.getStringBuffer()[ string_buffer_offset + 1 ] && !(script_h.getEndStatus() & ScriptHandler::END_1BYTE_CHAR) ){ string_buffer_offset += 2; } else string_buffer_offset++; event_mode = IDLE_EVENT_MODE; } if (script_h.getStringBuffer()[string_buffer_offset] == 0x0a || script_h.getStringBuffer()[string_buffer_offset] == 0x00){ indent_offset = 0; // redundant return RET_CONTINUE; } new_line_skip_flag = false; //printf("*** textCommand %d (%d,%d)\n", string_buffer_offset, sentence_font.xy[0], sentence_font.xy[1]); while( (!(script_h.getEndStatus() & ScriptHandler::END_1BYTE_CHAR) && script_h.getStringBuffer()[ string_buffer_offset ] == ' ') || script_h.getStringBuffer()[ string_buffer_offset ] == '\t' ) string_buffer_offset ++; char ch = script_h.getStringBuffer()[string_buffer_offset]; if ( IS_TWO_BYTE(ch) ){ // Shift jis /* ---------------------------------------- */ /* Kinsoku process */ if (IS_KINSOKU( script_h.getStringBuffer() + string_buffer_offset + 2)){ int i = 2; while (!sentence_font.isEndOfLine(i) && IS_KINSOKU( script_h.getStringBuffer() + string_buffer_offset + i + 2)){ i += 2; } if (sentence_font.isEndOfLine(i)){ sentence_font.newLine(); for (int i=0 ; i<indent_offset ; i++){ current_page->add(LOC_TWOBYTE_SYMBOL(' ')[0]); current_page->add(LOC_TWOBYTE_SYMBOL(' ')[1]); sentence_font.advanceCharInHankaku(2); } } } out_text[0] = script_h.getStringBuffer()[string_buffer_offset]; out_text[1] = script_h.getStringBuffer()[string_buffer_offset+1]; if ( clickstr_state == CLICK_IGNORE ){ clickstr_state = CLICK_NONE; } else{ if (script_h.checkClickstr(&script_h.getStringBuffer()[string_buffer_offset]) > 0){ if (sentence_font.getRemainingLine() <= clickstr_line) return clickNewPage( out_text ); else return clickWait( out_text ); } else{ clickstr_state = CLICK_NONE; } } if ( skip_flag || draw_one_page_flag || ctrl_pressed_status ){ drawChar( out_text, &sentence_font, false, true, accumulation_surface, &text_info ); num_chars_in_sentence++; string_buffer_offset += 2; return RET_CONTINUE | RET_NOREAD; } else{ drawChar( out_text, &sentence_font, true, true, accumulation_surface, &text_info ); num_chars_in_sentence++; event_mode = WAIT_SLEEP_MODE; if ( sentence_font.wait_time == -1 ) advancePhase( default_text_speed[text_speed_no] ); else advancePhase( sentence_font.wait_time ); return RET_WAIT | RET_NOREAD; } } else if ( ch == '@' ){ // wait for click return clickWait( NULL ); } else if ( ch == '\\' ){ // new page return clickNewPage( NULL ); } else if ( ch == '_' ){ // Ignore following forced return clickstr_state = CLICK_IGNORE; string_buffer_offset++; return RET_CONTINUE | RET_NOREAD; } else if ( ch == '!' && !(script_h.getEndStatus() & ScriptHandler::END_1BYTE_CHAR) ){ string_buffer_offset++; if ( script_h.getStringBuffer()[ string_buffer_offset ] == 's' ){ string_buffer_offset++; if ( script_h.getStringBuffer()[ string_buffer_offset ] == 'd' ){ sentence_font.wait_time = -1; string_buffer_offset++; } else{ int t = 0; while( script_h.getStringBuffer()[ string_buffer_offset ] >= '0' && script_h.getStringBuffer()[ string_buffer_offset ] <= '9' ){ t = t*10 + script_h.getStringBuffer()[ string_buffer_offset ] - '0'; string_buffer_offset++; } sentence_font.wait_time = t; while (script_h.getStringBuffer()[ string_buffer_offset ] == ' ' || script_h.getStringBuffer()[ string_buffer_offset ] == '\t') string_buffer_offset++; } } else if ( script_h.getStringBuffer()[ string_buffer_offset ] == 'w' || script_h.getStringBuffer()[ string_buffer_offset ] == 'd' ){ bool flag = false; if ( script_h.getStringBuffer()[ string_buffer_offset ] == 'd' ) flag = true; string_buffer_offset++; int tmp_string_buffer_offset = string_buffer_offset; int t = 0; while( script_h.getStringBuffer()[ string_buffer_offset ] >= '0' && script_h.getStringBuffer()[ string_buffer_offset ] <= '9' ){ t = t*10 + script_h.getStringBuffer()[ string_buffer_offset ] - '0'; string_buffer_offset++; } while (script_h.getStringBuffer()[ string_buffer_offset ] == ' ' || script_h.getStringBuffer()[ string_buffer_offset ] == '\t') string_buffer_offset++; if ( skip_flag || draw_one_page_flag || ctrl_pressed_status ){ return RET_CONTINUE | RET_NOREAD; } else{ event_mode = WAIT_SLEEP_MODE; if ( flag ) event_mode |= WAIT_INPUT_MODE; key_pressed_flag = false; startTimer( t ); string_buffer_offset = tmp_string_buffer_offset - 2; return RET_WAIT | RET_NOREAD; } } return RET_CONTINUE | RET_NOREAD; } else if ( ch == '#' && !(script_h.getEndStatus() & ScriptHandler::END_1BYTE_CHAR) ){ readColor( &sentence_font.color, script_h.getStringBuffer() + string_buffer_offset ); readColor( &ruby_font.color, script_h.getStringBuffer() + string_buffer_offset ); string_buffer_offset += 7; return RET_CONTINUE | RET_NOREAD; } else if ( ch == '(' && !(script_h.getEndStatus() & ScriptHandler::END_1BYTE_CHAR)){ current_page->add('('); startRuby( script_h.getStringBuffer() + string_buffer_offset + 1, sentence_font ); string_buffer_offset++; return RET_CONTINUE | RET_NOREAD; } else if ( ch == '/' && !(script_h.getEndStatus() & ScriptHandler::END_1BYTE_CHAR) ){ if ( ruby_struct.stage == RubyStruct::BODY ){ current_page->add('/'); sentence_font.addLineOffset(ruby_struct.margin); string_buffer_offset = ruby_struct.ruby_end - script_h.getStringBuffer(); if (*ruby_struct.ruby_end == ')'){ if ( skip_flag || draw_one_page_flag || ctrl_pressed_status ) endRuby(false, true, accumulation_surface, &text_info); else endRuby(true, true, accumulation_surface, &text_info); current_page->add(')'); string_buffer_offset++; } return RET_CONTINUE | RET_NOREAD; } else{ // skip new line new_line_skip_flag = true; string_buffer_offset++; if (script_h.getStringBuffer()[string_buffer_offset] != 0x0a) errorAndExit( "'new line' must follow '/'." ); return RET_CONTINUE; // skip the following eol } } else if ( ch == ')' && !(script_h.getEndStatus() & ScriptHandler::END_1BYTE_CHAR) && ruby_struct.stage == RubyStruct::BODY ){ current_page->add(')'); string_buffer_offset++; ruby_struct.stage = RubyStruct::NONE; return RET_CONTINUE | RET_NOREAD; } else{ out_text[0] = ch; if ( clickstr_state == CLICK_IGNORE ){ clickstr_state = CLICK_NONE; } else{ int matched_len = script_h.checkClickstr(script_h.getStringBuffer() + string_buffer_offset); if (matched_len > 0){ if (matched_len == 2) out_text[1] = script_h.getStringBuffer()[ string_buffer_offset + 1 ]; if (sentence_font.getRemainingLine() <= clickstr_line) return clickNewPage( out_text ); else return clickWait( out_text ); } else if (script_h.getStringBuffer()[ string_buffer_offset + 1 ] && script_h.checkClickstr(&script_h.getStringBuffer()[string_buffer_offset+1]) == 1 && script_h.getEndStatus() & ScriptHandler::END_1BYTE_CHAR){ if ( script_h.getStringBuffer()[ string_buffer_offset + 2 ] && script_h.checkClickstr(&script_h.getStringBuffer()[string_buffer_offset+2]) > 0){ clickstr_state = CLICK_NONE; } else if (script_h.getStringBuffer()[ string_buffer_offset + 1 ] == '@'){ return clickWait( out_text ); } else if (script_h.getStringBuffer()[ string_buffer_offset + 1 ] == '\\'){ return clickNewPage( out_text ); } else{ out_text[1] = script_h.getStringBuffer()[ string_buffer_offset + 1 ]; if (sentence_font.getRemainingLine() <= clickstr_line) return clickNewPage( out_text ); else return clickWait( out_text ); } } else{ clickstr_state = CLICK_NONE; } } bool flush_flag = true; if ( skip_flag || draw_one_page_flag || ctrl_pressed_status ) flush_flag = false; if ( script_h.getStringBuffer()[ string_buffer_offset + 1 ] && script_h.getStringBuffer()[ string_buffer_offset + 1 ] != 0x0a && !(script_h.getEndStatus() & ScriptHandler::END_1BYTE_CHAR)){ out_text[1] = script_h.getStringBuffer()[ string_buffer_offset + 1 ]; drawDoubleChars( out_text, &sentence_font, flush_flag, true, accumulation_surface, &text_info ); num_chars_in_sentence++; } else if (script_h.getEndStatus() & ScriptHandler::END_1BYTE_CHAR){ drawDoubleChars( out_text, &sentence_font, flush_flag, true, accumulation_surface, &text_info ); num_chars_in_sentence++; } if ( skip_flag || draw_one_page_flag || ctrl_pressed_status ){ if ( script_h.getStringBuffer()[ string_buffer_offset + 1 ] && !(script_h.getEndStatus() & ScriptHandler::END_1BYTE_CHAR)) string_buffer_offset++; string_buffer_offset++; return RET_CONTINUE | RET_NOREAD; } else{ event_mode = WAIT_SLEEP_MODE; if ( sentence_font.wait_time == -1 ) advancePhase( default_text_speed[text_speed_no] ); else advancePhase( sentence_font.wait_time ); return RET_WAIT | RET_NOREAD; } } return RET_NOMATCH; }
int ONScripterLabel::textCommand() { char *start_buf = script_h.getCurrent(); if (pretextgosub_label && (!pagetag_flag || page_enter_status == 0) && (line_enter_status == 0 || (line_enter_status == 1 && (start_buf[0] == '[' || zenkakko_flag && start_buf[0] == LOC_TWOBYTE_SYMBOL('[')[0] && start_buf[1] == LOC_TWOBYTE_SYMBOL('[')[1]))) ){ if (start_buf[0] == '[') start_buf++; else if (zenkakko_flag && start_buf[0] == LOC_TWOBYTE_SYMBOL('[')[0] && start_buf[1] == LOC_TWOBYTE_SYMBOL('[')[1]) start_buf += 2; else start_buf = NULL; char *end_buf = start_buf; while (end_buf && *end_buf){ if (zenkakko_flag && end_buf[0] == LOC_TWOBYTE_SYMBOL(']')[0] && end_buf[1] == LOC_TWOBYTE_SYMBOL(']')[1]){ script_h.setCurrent(end_buf+2); break; } else if (*end_buf == ']'){ script_h.setCurrent(end_buf+1); break; } else if (IS_TWO_BYTE(end_buf[0])) end_buf+=2; else end_buf++; } if (current_page->tag) delete[] current_page->tag; if (current_tag.tag) delete[] current_tag.tag; if (start_buf){ int len = end_buf - start_buf; current_page->tag = new char[len+1]; memcpy(current_page->tag, start_buf, len); current_page->tag[len] = 0; current_tag.tag = new char[len+1]; memcpy(current_tag.tag, current_page->tag, len+1); } else{ current_page->tag = NULL; current_tag.tag = NULL; } gosubReal( pretextgosub_label, script_h.getCurrent() ); line_enter_status = 1; return RET_CONTINUE; } int ret = enterTextDisplayMode(); if ( ret != RET_NOMATCH ) return ret; line_enter_status = 2; if (pagetag_flag) page_enter_status = 1; ret = processText(); if (ret == RET_CONTINUE){ indent_offset = 0; } return ret; }
void ONScripterLabel::drawString( const char *str, uchar3 color, FontInfo *info, bool flush_flag, SDL_Surface *surface, SDL_Rect *rect, AnimationInfo *cache_info ) { int i; int start_xy[2]; start_xy[0] = info->xy[0]; start_xy[1] = info->xy[1]; /* ---------------------------------------- */ /* Draw selected characters */ uchar3 org_color; for ( i=0 ; i<3 ; i++ ) org_color[i] = info->color[i]; for ( i=0 ; i<3 ; i++ ) info->color[i] = color[i]; bool skip_whitespace_flag = true; char text[3] = { '\0', '\0', '\0' }; while( *str ){ while (*str == ' ' && skip_whitespace_flag) str++; #ifdef ENABLE_1BYTE_CHAR if ( *str == '`' ){ str++; skip_whitespace_flag = false; continue; } #endif #ifndef FORCE_1BYTE_CHAR if (cache_info && !cache_info->is_tight_region){ if (*str == '('){ startRuby(str+1, *info); str++; continue; } else if (*str == '/' && ruby_struct.stage == RubyStruct::BODY ){ info->addLineOffset(ruby_struct.margin); str = ruby_struct.ruby_end; if (*ruby_struct.ruby_end == ')'){ endRuby(false, false, NULL, cache_info); str++; } continue; } else if (*str == ')' && ruby_struct.stage == RubyStruct::BODY ){ ruby_struct.stage = RubyStruct::NONE; str++; continue; } } #endif if ( IS_TWO_BYTE(*str) ){ /* Kinsoku process */ if (info->isEndOfLine(2) && IS_KINSOKU( str+2 )){ info->newLine(); for (int i=0 ; i<indent_offset ; i++){ sentence_font.advanceCharInHankaku(2); } } text[0] = *str++; text[1] = *str++; drawChar( text, info, false, false, surface, cache_info ); } else if (*str == 0x0a || *str == '\\' && info->is_newline_accepted){ info->newLine(); str++; } else{ text[0] = *str++; text[1] = '\0'; drawChar( text, info, false, false, surface, cache_info ); if (*str && *str != 0x0a){ text[0] = *str++; drawChar( text, info, false, false, surface, cache_info ); } } } for ( i=0 ; i<3 ; i++ ) info->color[i] = org_color[i]; /* ---------------------------------------- */ /* Calculate the area of selection */ SDL_Rect clipped_rect = info->calcUpdatedArea(start_xy, screen_ratio1, screen_ratio2); info->addShadeArea(clipped_rect, shade_distance); if ( flush_flag ) flush( refresh_shadow_text_mode, &clipped_rect ); if ( rect ) *rect = clipped_rect; }
void ONScripterLabel::drawChar( char* text, FontInfo *info, bool flush_flag, bool lookback_flag, SDL_Surface *surface, AnimationInfo *cache_info, SDL_Rect *clip ) { //printf("draw %x-%x[%s] %d, %d\n", text[0], text[1], text, info->xy[0], info->xy[1] ); if ( info->ttf_font == NULL ){ if ( info->openFont( font_file, screen_ratio1, screen_ratio2 ) == NULL ){ fprintf( stderr, "can't open font file: %s\n", font_file ); quit(); exit(-1); } } #if defined(PSP) else info->openFont( font_file, screen_ratio1, screen_ratio2 ); #endif if ( info->isEndOfLine() ){ info->newLine(); for (int i=0 ; i<indent_offset ; i++) sentence_font.advanceCharInHankaku(2); if ( lookback_flag ){ for (int i=0 ; i<indent_offset ; i++){ current_page->add(LOC_TWOBYTE_SYMBOL(' ')[0]); current_page->add(LOC_TWOBYTE_SYMBOL(' ')[1]); } } } int xy[2]; xy[0] = info->x() * screen_ratio1 / screen_ratio2; xy[1] = info->y() * screen_ratio1 / screen_ratio2; SDL_Color color; SDL_Rect dst_rect; if ( info->is_shadow ){ color.r = color.g = color.b = 0; drawGlyph(surface, info, color, text, xy, true, cache_info, clip, dst_rect); } color.r = info->color[0]; color.g = info->color[1]; color.b = info->color[2]; drawGlyph( surface, info, color, text, xy, false, cache_info, clip, dst_rect ); if ( surface == accumulation_surface && !flush_flag && (!clip || AnimationInfo::doClipping( &dst_rect, clip ) == 0) ){ dirty_rect.add( dst_rect ); } else if ( flush_flag ){ info->addShadeArea(dst_rect, shade_distance); flushDirect( dst_rect, REFRESH_NONE_MODE ); } /* ---------------------------------------- */ /* Update text buffer */ if (IS_TWO_BYTE(text[0])) info->advanceCharInHankaku(2); else info->advanceCharInHankaku(1); if ( lookback_flag ){ current_page->add( text[0] ); if (IS_TWO_BYTE(text[0]) && text[1]) current_page->add( text[1] ); } }