void ONScripter::errorAndExit(const char *str, const char *reason )
{
	char *error;
	time_t t = time(NULL);
    struct tm *tm = localtime( &t );
    char error_name[64];
    sprintf(error_name,"%serror%d-%02d-%02d-%02d%02d%02d.bmp",archive_path,tm->tm_year,tm->tm_mon+1,tm->tm_mday,tm->tm_hour,tm->tm_min,tm->tm_sec);
    SDL_BlitSurface(screen_surface, NULL, screenshot_surface, NULL);

    SDL_Surface *surface =  
AnimationInfo::alloc32bitSurface( script_h.screen_width * screen_ratio1 / screen_ratio2 , script_h.screen_height * screen_ratio1 / screen_ratio2, texture_format );
        resizeSurface( screenshot_surface, surface );
        SDL_SaveBMP( surface, error_name );
        SDL_FreeSurface( surface );
	if ( reason )
        fprintf( stderr, " *** Parse error at %s:%d [%s]; %s ***\n",
                 current_label_info.name,
                 current_line,
                 str, reason );
    else
        fprintf( stderr, " *** Parse error at %s:%d [%s] ***\n",
                 current_label_info.name,
                 current_line,
                 str );
	
    exit(-1);

}
 void
 resize(int w, int h) {
     if (w == width && h == height) {
         return;
     }
     eglWaitClient();
     Drawable::resize(w, h);
     resizeSurface(w, h);
 }
void QWebOSGLContext::swapBuffers()
{
    EGLBoolean eglResult = eglBindAPI(EGL_OPENGL_ES_API);
    if (eglResult != EGL_TRUE)
        qFatal("QWebOS: failed to set EGL API, err=%d", eglGetError());

    eglResult = eglSwapBuffers(s_eglDisplay, m_eglSurface);
    if (eglResult != EGL_TRUE)
        qFatal("QWebOS: failed to swap EGL buffers, err=%d", eglGetError());

    QSize currentSize = m_platformWindow->geometry().size();
    if (currentSize != m_surfaceSize) {
        resizeSurface(currentSize);
    }
}
/*
 * loadTexture
 * Loads texture data from the given file into the given GL texture.
 *
 * Arguments
 *     filename: Filename of the texture file.
 *     texture:  Handle of the GL texture.
 */
void Animation::loadTexture(std::string filename, unsigned int texture, float &wCoord, float &hCoord, float &aspectRatio)
{
	SDL_Surface *rawSurface = IMG_Load(filename.c_str());
	SDL_Surface *surface = resizeSurface(rawSurface);

	int format = surface->format->BytesPerPixel == 4 ? GL_RGBA : GL_RGB;

	glBindTexture(GL_TEXTURE_2D, texture);
	glTexImage2D(GL_TEXTURE_2D, 0, format, surface->w, surface->h, 0, format, GL_UNSIGNED_BYTE, surface->pixels);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

	wCoord = ((float)rawSurface->w) / ((float)surface->w);
	hCoord = ((float)rawSurface->h) / ((float)surface->h);
	aspectRatio = ((float)rawSurface->w) / ((float)rawSurface->h);

	SDL_FreeSurface(rawSurface);
	SDL_FreeSurface(surface);
}
void ONScripter::buildDialog(bool yesno_flag, const char *mes1, const char *mes2)
{
    SDL_PixelFormat *fmt = image_surface->format;
    SDL_Surface *s = SDL_CreateRGBSurface( SDL_SWSURFACE, DIALOG_W, DIALOG_H,
                                           fmt->BitsPerPixel, fmt->Rmask, fmt->Gmask, fmt->Bmask, fmt->Amask );

    SDL_Rect rect;
    unsigned char col = 255;
    SDL_FillRect(s, NULL, SDL_MapRGBA(s->format, col, col, col, 0xff));

    rect.x = 2; rect.y = DIALOG_HEADER;
    rect.w = DIALOG_W-4; rect.h = DIALOG_H-rect.y-2;
    col = 105;
    SDL_FillRect(s, &rect, SDL_MapRGBA(s->format, col, col, col, 0xff));
    
    rect.x++; rect.y++; rect.w-=2; rect.h-=2;
    col = 255;
    SDL_FillRect(s, &rect, SDL_MapRGBA(s->format, col, col, col, 0xff));

    rect.h = DIALOG_FOOTER;
    rect.y = DIALOG_H-3-rect.h;
    col = 240;
    SDL_FillRect(s, &rect, SDL_MapRGBA(s->format, col, col, col, 0xff));

    uchar3 col3={0, 0, 0};
    dialog_font.top_xy[0] = 7;
    dialog_font.top_xy[1] = DIALOG_HEADER+5;
    dialog_font.num_xy[0] = (DIALOG_W-7*2)/dialog_font.pitch_xy[0];
    dialog_font.num_xy[1] = 3;
    dialog_font.clear();
    drawString( mes1, col3, &dialog_font, false, s, NULL, NULL );

    dialog_font.top_xy[0] = 5;
    dialog_font.top_xy[1] = (DIALOG_HEADER-dialog_font.font_size_xy[1])/2;
    dialog_font.setLineArea( strlen(mes2)/2+1 );
    dialog_font.clear();
    drawString( mes2, col3, &dialog_font, false, s, NULL, NULL );

    SDL_Surface *s2 = s;
    if (screen_ratio2 != screen_ratio1){
        s2 = SDL_CreateRGBSurface( SDL_SWSURFACE, DIALOG_W*screen_ratio1/screen_ratio2, DIALOG_H*screen_ratio1/screen_ratio2,
                                   fmt->BitsPerPixel, fmt->Rmask, fmt->Gmask, fmt->Bmask, fmt->Amask );
        resizeSurface(s, s2);
        SDL_FreeSurface(s);
    }

    dialog_info.deleteSurface();
    dialog_info.num_of_cells = 1;
    dialog_info.setImage(s2, texture_format);
    
    dialog_info.pos.x = (screen_width  - dialog_info.pos.w)/2;
    dialog_info.pos.y = (screen_height - dialog_info.pos.h)/2;

    // buttons
    const char* mes[2];
    if (yesno_flag){
        mes[0] = MESSAGE_YES;
        mes[1] = MESSAGE_NO;
    }
    else{
        mes[0] = MESSAGE_OK;
        mes[1] = MESSAGE_CANCEL;
    }

    for (int i=0 ; i<2 ; i++){
        SDL_Surface *bs = SDL_CreateRGBSurface( SDL_SWSURFACE, DIALOG_BUTTON_W*2, DIALOG_BUTTON_H,
                                                fmt->BitsPerPixel, fmt->Rmask, fmt->Gmask, fmt->Bmask, fmt->Amask );

        for (int j=0 ; j<2 ; j++){
            rect.x = DIALOG_BUTTON_W*j;
            rect.y = 0;
            rect.w = DIALOG_BUTTON_W; rect.h = DIALOG_BUTTON_H;

            col = 105;
            SDL_FillRect(bs, &rect, SDL_MapRGBA(bs->format, col, col, col, 0xff));

            rect.w--; rect.h--;
            col = 255;
            SDL_FillRect(bs, &rect, SDL_MapRGBA(bs->format, col, col, col, 0xff));

            rect.x++; rect.y++; rect.w--; rect.h--;
            col = 227;
            SDL_FillRect(bs, &rect, SDL_MapRGBA(bs->format, col, col, col, 0xff));

            rect.x++; rect.y++; rect.w-=2; rect.h-=2;
            col = 240;
            if (j==1) col = 214;
            SDL_FillRect(bs, &rect, SDL_MapRGBA(bs->format, col, col, col, 0xff));

            dialog_font.top_xy[0] = rect.x+(rect.w-dialog_font.pitch_xy[0]*strlen(mes[i])/2)/2;
            dialog_font.top_xy[1] = rect.y+(rect.h-dialog_font.font_size_xy[1])/2;
            dialog_font.setLineArea( strlen(mes[i])/2+1 );
            dialog_font.clear();
            drawString( mes[i], col3, &dialog_font, false, bs, NULL, NULL );
        }

        SDL_Surface *bs2 = bs;
        if (screen_ratio2 != screen_ratio1){
            bs2 = SDL_CreateRGBSurface( SDL_SWSURFACE, DIALOG_BUTTON_W*2*screen_ratio1/screen_ratio2, DIALOG_BUTTON_H*screen_ratio1/screen_ratio2,
                                        fmt->BitsPerPixel, fmt->Rmask, fmt->Gmask, fmt->Bmask, fmt->Amask );
            resizeSurface(bs, bs2);
            SDL_FreeSurface(bs);
        }

        ButtonLink *btn = new ButtonLink();
        btn->no = i+1;
        btn->button_type = ButtonLink::TMP_SPRITE_BUTTON;
        btn->anim[0] = new AnimationInfo();
        btn->anim[0]->num_of_cells = 2;
        btn->anim[0]->setImage(bs2, texture_format);
        btn->show_flag = 1;
        btn->anim[0]->pos.x = dialog_info.pos.x + DIALOG_W-3-(DIALOG_BUTTON_W+8)*(2-i);
        btn->anim[0]->pos.y = dialog_info.pos.y + DIALOG_H-3-(DIALOG_FOOTER+DIALOG_BUTTON_H)/2;
        btn->anim[0]->visible = true;
        btn->select_rect = btn->image_rect = btn->anim[0]->pos;

        root_button_link.insert( btn );
    }
}
void ONScripter::setupAnimationInfo( AnimationInfo *anim, FontInfo *info )
{
    if (anim->trans_mode != AnimationInfo::TRANS_STRING &&
        anim->file_name && anim->surface_name &&
        strcmp(anim->file_name, anim->surface_name) == 0 &&
        ((!anim->mask_file_name && !anim->mask_surface_name) ||
         (anim->mask_file_name && !anim->mask_surface_name &&
          strcmp(anim->mask_file_name, anim->mask_surface_name) == 0))) return;

    anim->deleteSurface();
    anim->abs_flag = true;

    anim->surface_name = new char[ strlen(anim->file_name) + 1 ];
    strcpy( anim->surface_name, anim->file_name );

    if (anim->mask_file_name){
        anim->mask_surface_name = new char[ strlen(anim->mask_file_name) + 1 ];
        strcpy( anim->mask_surface_name, anim->mask_file_name );
    }
    
    if ( anim->trans_mode == AnimationInfo::TRANS_STRING ){
        FontInfo f_info = sentence_font;
        if (info) f_info = *info;
        f_info.rubyon_flag = anim->is_ruby_drawable;

        if ( anim->font_size_xy[0] >= 0 ){ // in case of Sprite, not rclick menu
            f_info.setTateyokoMode(0);
            f_info.top_xy[0] = anim->orig_pos.x;
            f_info.top_xy[1] = anim->orig_pos.y;
            if (anim->is_single_line)
                f_info.setLineArea( strlen(anim->file_name)/2+1 );
            f_info.clear();
            
            f_info.font_size_xy[0] = anim->font_size_xy[0];
            f_info.font_size_xy[1] = anim->font_size_xy[1];
            f_info.pitch_xy[0] = anim->font_pitch[0];
            f_info.pitch_xy[1] = anim->font_pitch[1];

            f_info.ttf_font[0] = NULL;
			f_info.ttf_font[1] = NULL;
        }

		if (f_info.ttf_font[0] == NULL)
			f_info.openFont( font_file, screen_ratio1, screen_ratio2 );

        SDL_Rect pos;
        if (anim->is_tight_region){
            drawString( anim->file_name, anim->color_list[ anim->current_cell ], &f_info, false, NULL, &pos );
        }
        else{
            int xy_bak[2];
            xy_bak[0] = f_info.xy[0];
            xy_bak[1] = f_info.xy[1];
            
            int xy[2] = {0, 0};
            f_info.setXY(f_info.num_xy[0]-1, f_info.num_xy[1]-1);
             pos = f_info.calcUpdatedArea(xy, screen_ratio1, screen_ratio2);

            f_info.xy[0] = xy_bak[0];
            f_info.xy[1] = xy_bak[1];
        }
        
        if (info != NULL){
            info->xy[0] = f_info.xy[0];
            info->xy[1] = f_info.xy[1];
        }
        
        anim->orig_pos.w = pos.w;
        anim->orig_pos.h = pos.h;
        anim->scalePosWH( screen_ratio1, screen_ratio2 );
        anim->allocImage( anim->pos.w*anim->num_of_cells, anim->pos.h, texture_format );
        anim->fill( 0, 0, 0, 0 );
        
        f_info.top_xy[0] = f_info.top_xy[1] = 0;
        for ( int i=0 ; i<anim->num_of_cells ; i++ ){
            f_info.clear();
            drawString( anim->file_name, anim->color_list[i], &f_info, false, NULL, NULL, anim );
            f_info.top_xy[0] += anim->orig_pos.w;
        }
    }
    else{
        bool has_alpha;
        int location;
        SDL_Surface *surface = loadImage( anim->file_name, &has_alpha, &location );

        SDL_Surface *surface_m = NULL;
        if (anim->trans_mode == AnimationInfo::TRANS_MASK)
            surface_m = loadImage( anim->mask_file_name );
        
        surface = anim->setupImageAlpha(surface, surface_m, has_alpha);

        if (surface &&
            screen_ratio2 != screen_ratio1 &&
            (!disable_rescale_flag || location == BaseReader::ARCHIVE_TYPE_NONE))
        {

			if(scale_screen_mode)
			{
					SDL_Surface *src_s = surface;


					SDL_PixelFormat *fmt = surface->format;

					int ratio2 = screen_ratio2;
					int ratio1 = screen_ratio1;
					//printf("%d\n",ratio2);
					int num_of_cells =1;
					float stretch_x =1.0;

					// 800 stretch_x=1.250333
					// 854*480 stretch_x =1.334333
					// 960*640 stretch_x =1.125333
					// 960*540 stretch_x =1.332333
					// 1024 stretch_x=1.279333
					if( ratio1 == 385 || ratio1 == 479)
					{
						stretch_x=1.250333;
					}
					else if( ratio1 == 384 || ratio1 == 481 )
					{
						stretch_x =1.334333;
					}
					else if( ratio1 == 256 || ratio1 == 320 || ratio1 == 1024 || ratio1 == 1280 )
					{
						stretch_x =1.125333;
					}
					else if( ratio1 == 865 || ratio1 == 1081 || ratio1 == 1537 || ratio1 == 1921 )
					{
						stretch_x =1.332333;
					}
					else if( ratio1 == 1025 || ratio1 == 1281 )
					{
						stretch_x=1.279333;
					}
					else
						stretch_x =1.125333;

					float stretch_y =1.000000;

					const int MAX_PITCH = 16384;
					int h = 0;
					int w = ((src_s->w / num_of_cells) * ratio1 / ratio2) * num_of_cells;

					if (stretch_x > 1.0)
						w = int((src_s->w / num_of_cells) * ratio1 * stretch_x / ratio2 + 0.5) * num_of_cells;

					if (w >= MAX_PITCH){
						//too wide for SDL_Surface pitch (Uint16) at 32bpp; size differently

						if (stretch_y > 1.0)
							fprintf(stderr, " *** image '%s' is too wide to resize to (%d,%d); ",
									"ss", w, int(src_s->h * ratio1 * stretch_y / ratio2 + 0.5));
						else

						fprintf(stderr, " *** image '%s' is too wide to resize to (%d,%d); ",
								 "ss", w, src_s->h * ratio1 / ratio2);
						w = (MAX_PITCH - 1) / num_of_cells * num_of_cells;
						if (stretch_y > 1.0)
							h = src_s->h * w * stretch_y / stretch_x / src_s->w + 0.5;
						else
						h = src_s->h * w / src_s->w;
						if ( h == 0 ) h = 1;
						fprintf(stderr, "resizing to (%d,%d) instead *** \n", w, h);
					}else{
						if ( w == 0 ) w = num_of_cells;

						if (stretch_y > 1.0)
							h = src_s->h * ratio1 * stretch_y / ratio2 + 0.5;
						else

						h = src_s->h * ratio1 / ratio2;
						if ( h == 0 ) h = 1;
					}

					printf("%d\n",h);
					printf("%d\n",w);

					surface = SDL_CreateRGBSurface( SDL_SWSURFACE, w, h,
													fmt->BitsPerPixel, fmt->Rmask, fmt->Gmask, fmt->Bmask, fmt->Amask );
		        
					resizeSurface(src_s, surface);
					SDL_FreeSurface(src_s);

			}
			else
			{
				SDL_Surface *src_s = surface;

				int w, h;
				if ( (w = src_s->w * screen_ratio1 / screen_ratio2) == 0 ) w = 1;
				if ( (h = src_s->h * screen_ratio1 / screen_ratio2) == 0 ) h = 1;
				SDL_PixelFormat *fmt = image_surface->format;
				surface = SDL_CreateRGBSurface( SDL_SWSURFACE, w, h,
												fmt->BitsPerPixel, fmt->Rmask, fmt->Gmask, fmt->Bmask, fmt->Amask );
	        
				resizeSurface(src_s, surface);
				SDL_FreeSurface(src_s);
			}
        }

        anim->setImage( surface, texture_format );

        if ( surface_m ) SDL_FreeSurface(surface_m);
    }
}
int ONScripterLabel::loadSaveFile2( int file_version )
{
    deleteNestInfo();
    
    int i, j;
    
    readInt(); // 1
    if ( readInt() == 1 ) sentence_font.is_bold = true;
    else                  sentence_font.is_bold = false;
    if ( readInt() == 1 ) sentence_font.is_shadow = true;
    else                  sentence_font.is_shadow = false;

    readInt(); // 0
    rmode_flag = (readInt()==1)?true:false;
    sentence_font.color[0] = readInt();
    sentence_font.color[1] = readInt();
    sentence_font.color[2] = readInt();
    cursor_info[0].remove();
    readStr( &cursor_info[0].image_name );
    if ( cursor_info[0].image_name ){
        parseTaggedString( &cursor_info[0] );
        setupAnimationInfo( &cursor_info[0] );
        if ( cursor_info[0].image_surface )
            cursor_info[0 ].visible = true;
    }
    cursor_info[1].remove();
    readStr( &cursor_info[1].image_name );
    if ( cursor_info[1].image_name ){
        parseTaggedString( &cursor_info[1] );
        setupAnimationInfo( &cursor_info[1] );
        if ( cursor_info[1].image_surface )
            cursor_info[1 ].visible = true;
    }

    window_effect.effect = readInt();
    window_effect.duration = readInt();
    readStr( &window_effect.anim.image_name ); // probably

    sentence_font.clear();
    sentence_font.ttf_font  = NULL;
    sentence_font.top_xy[0] = readInt();
    sentence_font.top_xy[1] = readInt();
#ifndef RCA_SCALE
    sentence_font.num_xy[0] = readInt();
    sentence_font.num_xy[1] = readInt();
#else
    sentence_font.num_xy[0] = readInt() * scr_stretch_x;
    sentence_font.num_xy[1] = readInt() * scr_stretch_y;
#endif
    sentence_font.font_size_xy[0] = readInt();
    sentence_font.font_size_xy[1] = readInt();
    sentence_font.pitch_xy[0] = readInt();
    sentence_font.pitch_xy[1] = readInt();
    for ( i=0 ; i<3 ; i++ )
        sentence_font.window_color[2-i] = readChar();
    if ( readChar() == 0x00 ) sentence_font.is_transparent = true;
    else                      sentence_font.is_transparent = false;
    sentence_font.wait_time = readInt();
    sentence_font_info.pos.x = readInt() * screen_ratio1 / screen_ratio2;
    sentence_font_info.pos.y = readInt() * screen_ratio1 / screen_ratio2;
#ifndef RCA_SCALE
    sentence_font_info.pos.w = (readInt() + 1 - sentence_font_info.pos.x * screen_ratio1 / screen_ratio2) * screen_ratio1 / screen_ratio2;
    sentence_font_info.pos.h = (readInt() + 1 - sentence_font_info.pos.y * screen_ratio1 / screen_ratio2) * screen_ratio1 / screen_ratio2;
#else
    sentence_font_info.pos.w = (readInt() + 1 - sentence_font_info.pos.x * screen_ratio1 / screen_ratio2) * screen_ratio1 * scr_stretch_x / screen_ratio2;
    sentence_font_info.pos.h = (readInt() + 1 - sentence_font_info.pos.y * screen_ratio1 / screen_ratio2) * screen_ratio1 * scr_stretch_y / screen_ratio2;
#endif
    readStr( &sentence_font_info.image_name );
    if ( !sentence_font.is_transparent && sentence_font_info.image_name ){
        parseTaggedString( &sentence_font_info );
        setupAnimationInfo( &sentence_font_info );
    }

    if ( readInt() == 1 ) cursor_info[0].abs_flag = false;
    else                  cursor_info[0].abs_flag = true;
    if ( readInt() == 1 ) cursor_info[1].abs_flag = false;
    else                  cursor_info[1].abs_flag = true;
    cursor_info[0].pos.x = readInt() * screen_ratio1 / screen_ratio2;
    cursor_info[1].pos.x = readInt() * screen_ratio1 / screen_ratio2;
    cursor_info[0].pos.y = readInt() * screen_ratio1 / screen_ratio2;
    cursor_info[1].pos.y = readInt() * screen_ratio1 / screen_ratio2;

    // load background surface
    bg_info.remove();
    readStr( &bg_info.file_name );
    createBackground();

    for ( i=0 ; i<3 ; i++ ){
        tachi_info[i].remove();
        readStr( &tachi_info[i].image_name );
        if ( tachi_info[i].image_name ){
            parseTaggedString( &tachi_info[i] );
            setupAnimationInfo( &tachi_info[i] );
#ifdef RCA_SCALE

            if (scr_stretch_y > 1.0) {
                // RCA: Stretch characters to screen size.
                // Note all stretches are with Y-scale, so they don't get distorted (FIXME assumes widescreen)
                SDL_Surface* src = tachi_info[i].image_surface;
                SDL_PixelFormat *fmt = src->format;
                SDL_Surface* dst = SDL_CreateRGBSurface( SDL_SWSURFACE,
                                                         scr_stretch_y*src->w,
                                                         scr_stretch_y*src->h,
                                                         fmt->BitsPerPixel, fmt->Rmask, fmt->Gmask, fmt->Bmask, fmt->Amask );
                resizeSurface( src, dst );
                tachi_info[i].image_surface = dst;
                tachi_info[i].pos.w = src->w*scr_stretch_y;
                tachi_info[i].pos.h = src->h*scr_stretch_y;
                SDL_FreeSurface( src );
            }
#endif
        }
    }

#ifndef RCA_SCALE
    for ( i=0 ; i<3 ; i++ ) 
        tachi_info[i].pos.x = readInt() * screen_ratio1 / screen_ratio2;
#else
    for ( i=0 ; i<3 ; i++ ) {
	readInt();
        tachi_info[i].pos.x = screen_width * (i+1) / 4 - tachi_info[i].pos.w / 2;  // RCA Ignore saved value
    }
#endif

#ifndef RCA_SCALE
    for ( i=0 ; i<3 ; i++ )
        tachi_info[i].pos.y = readInt() * screen_ratio1 / screen_ratio2;
#else
    for ( i=0 ; i<3 ; i++ ) {
	readInt();
        if (tachi_info[i].image_surface)
            tachi_info[i].pos.y = underline_value - tachi_info[i].image_surface->h + 1;  // RCA Ignore saved value
    }
#endif

    readInt(); // 0
    readInt(); // 0
    readInt(); // 0

    if (file_version >= 203){
        readInt(); // -1
        readInt(); // -1
        readInt(); // -1
    }
    
    for ( i=0 ; i<MAX_SPRITE_NUM ; i++ ){
        sprite_info[i].remove();
        readStr( &sprite_info[i].image_name );
        if ( sprite_info[i].image_name ){
            parseTaggedString( &sprite_info[i] );
            setupAnimationInfo( &sprite_info[i] );
        }
        sprite_info[i].pos.x = readInt() * screen_ratio1 / screen_ratio2;
        sprite_info[i].pos.y = readInt() * screen_ratio1 / screen_ratio2;
        if ( readInt() == 1 ) sprite_info[i].visible = true;
        else                  sprite_info[i].visible = false;
        sprite_info[i].current_cell = readInt();
	if (file_version >= 203) {
            int trans = readInt();
            if (trans == -1)
                trans = 256;
            sprite_info[i].trans = trans;
        }
    }

    readVariables( 0, script_h.global_variable_border );

    // nested info
    int num_nest =readInt();
    last_nest_info = &root_nest_info;
    if (num_nest > 0){
        file_io_buf_ptr += (num_nest-1)*4;
        while( num_nest > 0 ){
            NestInfo *info = new NestInfo();
            if (last_nest_info == &root_nest_info) last_nest_info = info;
        
            i = readInt();
            if (i > 0){
                info->nest_mode = NestInfo::LABEL;
                info->next_script = script_h.getAddress( i );
                file_io_buf_ptr -= 8;
                num_nest--;
            }
            else{
                info->nest_mode = NestInfo::FOR;
                info->next_script = script_h.getAddress( -i );
                file_io_buf_ptr -= 16;
                info->var_no = readInt();
                info->to = readInt();
                info->step = readInt();
                file_io_buf_ptr -= 16;
                num_nest -= 4;
            }
            info->next = root_nest_info.next;
            if (root_nest_info.next) root_nest_info.next->previous = info;
            root_nest_info.next = info;
            info->previous = &root_nest_info;
        }
        num_nest = readInt();
        file_io_buf_ptr += num_nest*4;
    }

    if (readInt() == 1) monocro_flag = true;
    else                monocro_flag = false;
    for ( i=0 ; i<3 ; i++ )
        monocro_color[2-i] = readInt();
    for ( i=0 ; i<256 ; i++ ){
        monocro_color_lut[i][0] = (monocro_color[0] * i) >> 8;
        monocro_color_lut[i][1] = (monocro_color[1] * i) >> 8;
        monocro_color_lut[i][2] = (monocro_color[2] * i) >> 8;
    }
    nega_mode = readInt();
    
    // ----------------------------------------
    // Sound
    stopCommand();
    loopbgmstopCommand();
    stopAllDWAVE();

    readStr( &midi_file_name ); // MIDI file
    readStr( &wave_file_name ); // wave, waveloop
    i = readInt();
    if ( i >= 0 ) current_cd_track = i;

    // play, playonce MIDI
    if ( readInt() == 1 ){
        midi_play_loop_flag = true;
        current_cd_track = -2;
        playSound(midi_file_name, SOUND_MIDI, midi_play_loop_flag);
    }
    else
        midi_play_loop_flag = false;
    
    // wave, waveloop
    if ( readInt() == 1 ) wave_play_loop_flag = true;
    else                  wave_play_loop_flag = false;
    if ( wave_file_name && wave_play_loop_flag )
        playSound(wave_file_name, SOUND_WAVE|SOUND_OGG, wave_play_loop_flag, MIX_WAVE_CHANNEL);

    // play, playonce
    if ( readInt() == 1 ) cd_play_loop_flag = true;
    else                  cd_play_loop_flag = false;
    if ( current_cd_track >= 0 ) playCDAudio();

    // bgm, mp3, mp3loop
    if ( readInt() == 1 ) music_play_loop_flag = true;
    else                  music_play_loop_flag = false;
    if ( readInt() == 1 ) mp3save_flag = true;
    else                  mp3save_flag = false;
    readStr( &music_file_name );
    if ( music_file_name ){
        playSound(music_file_name,
                  SOUND_WAVE | SOUND_OGG_STREAMING | SOUND_MP3 | SOUND_MIDI,
                  music_play_loop_flag, MIX_BGM_CHANNEL);
    }

    erase_text_window_mode = readInt();
    readInt(); // 1

    barclearCommand();
    for ( i=0 ; i<MAX_PARAM_NUM ; i++ ){
        j = readInt();
        if ( j != 0 ){
            bar_info[i] = new AnimationInfo();
            bar_info[i]->trans_mode = AnimationInfo::TRANS_COPY;
            bar_info[i]->num_of_cells = 1;

            bar_info[i]->param = j;
            bar_info[i]->pos.x = readInt() * screen_ratio1 / screen_ratio2;
            bar_info[i]->pos.y = readInt() * screen_ratio1 / screen_ratio2;
            bar_info[i]->max_width = readInt() * screen_ratio1 / screen_ratio2;
            bar_info[i]->pos.h = readInt() * screen_ratio1 / screen_ratio2;
            bar_info[i]->max_param = readInt();
            for ( j=0 ; j<3 ; j++ )
                bar_info[i]->color[2-j] = readChar();
            readChar(); // 0x00

            int w = bar_info[i]->max_width * bar_info[i]->param / bar_info[i]->max_param;
            if ( bar_info[i]->max_width > 0 && w > 0 ){
                bar_info[i]->pos.w = w;
                bar_info[i]->allocImage( bar_info[i]->pos.w, bar_info[i]->pos.h );
                bar_info[i]->fill( bar_info[i]->color[0], bar_info[i]->color[1], bar_info[i]->color[2], 0xff );
            }
        }
        else{
            readInt(); // -1
            readInt(); // 0
            readInt(); // 0
            readInt(); // 0
            readInt(); // 0
            readInt(); // 0
        }
    }

    prnumclearCommand();
    for ( i=0 ; i<MAX_PARAM_NUM ; i++ ){
        j = readInt();
        if ( prnum_info[i] ){
            prnum_info[i] = new AnimationInfo();
            prnum_info[i]->trans_mode = AnimationInfo::TRANS_STRING;
            prnum_info[i]->num_of_cells = 1;
            prnum_info[i]->color_list = new uchar3[1];

            prnum_info[i]->param = j;
            prnum_info[i]->pos.x = readInt() * screen_ratio1 / screen_ratio2;
            prnum_info[i]->pos.y = readInt() * screen_ratio1 / screen_ratio2;
            prnum_info[i]->font_size_xy[0] = readInt();
            prnum_info[i]->font_size_xy[1] = readInt();
            for ( j=0 ; j<3 ; j++ )
                prnum_info[i]->color_list[0][2-j] = readChar();
            readChar(); // 0x00

            char num_buf[7];
            script_h.getStringFromInteger( num_buf, prnum_info[i]->param, 3 );
            setStr( &prnum_info[i]->file_name, num_buf );

            setupAnimationInfo( prnum_info[i] );
        }
        else{
            readInt(); // -1
            readInt(); // 0
            readInt(); // 0
            readInt(); // 0
            readInt(); // 0
        }
    }

    readInt(); // 1
    readInt(); // 0
    readInt(); // 1
    btndef_info.remove();
    readStr( &btndef_info.image_name );
    if ( btndef_info.image_name && btndef_info.image_name[0] != '\0' ){
        parseTaggedString( &btndef_info );
        setupAnimationInfo( &btndef_info );
        SDL_SetAlpha( btndef_info.image_surface, DEFAULT_BLIT_FLAG, SDL_ALPHA_OPAQUE );
    }

    if ( file_version >= 202 )
        readArrayVariable();
    
    readInt(); // 0
    if ( readChar() == 1 ) erase_text_window_mode = 2;
    readChar(); // 0
    readChar(); // 0
    readChar(); // 0
    readStr( &loop_bgm_name[0] );
    readStr( &loop_bgm_name[1] );
    if ( loop_bgm_name[0] ) {
        if ( loop_bgm_name[1] )
            playSound(loop_bgm_name[1],
                      SOUND_PRELOAD|SOUND_WAVE|SOUND_OGG, false, MIX_LOOPBGM_CHANNEL1);
        playSound(loop_bgm_name[0],
                  SOUND_WAVE|SOUND_OGG, false, MIX_LOOPBGM_CHANNEL0);
    }

    if ( file_version >= 201 ){
        if ( readInt() == 1 ) rubyon_flag = true;
        else                  rubyon_flag = false;
        ruby_struct.font_size_xy[0] = readInt();
        ruby_struct.font_size_xy[1] = readInt();
        readStr( &ruby_struct.font_name );
        sentence_font.setRubyOnFlag(rubyon_flag);
    }

    if (file_version >= 204){
        readInt();
        
        for ( i=0 ; i<MAX_SPRITE2_NUM ; i++ ){
            sprite2_info[i].remove();
            readStr( &sprite2_info[i].image_name );
            if ( sprite2_info[i].image_name ){
                parseTaggedString( &sprite2_info[i] );
                setupAnimationInfo( &sprite2_info[i] );
            }
            sprite2_info[i].pos.x = readInt() * screen_ratio1 / screen_ratio2;
            sprite2_info[i].pos.y = readInt() * screen_ratio1 / screen_ratio2;
            sprite2_info[i].scale_x = readInt();
            sprite2_info[i].scale_y = readInt();
            sprite2_info[i].rot = readInt();
            if ( readInt() == 1 ) sprite2_info[i].visible = true;
            else                  sprite2_info[i].visible = false;
            j = readInt();
            if (j == -1)
                sprite2_info[i].trans = 256;
            else
                sprite2_info[i].trans = j;
            sprite2_info[i].blending_mode = readInt();
            sprite2_info[i].calcAffineMatrix();
        }
        
        readInt();
        readInt();
        if (file_version >= 205) readInt(); // 1
        readInt();
        readInt();
        readInt();
        readInt();
        if (file_version >= 205) readChar(); // 0
    }

    if (file_version >= 206){
        readInt(); // 0
        readInt(); // 160
        readInt(); // 320
        readInt(); // 480
        readInt(); // 480
    }

    int text_num = readInt();
    //Mion: clearing page then moving to next eliminates buffer error
    start_page = current_page->next;
    clearCurrentPage();
    current_page = start_page;
    for ( i=0 ; i<text_num ; i++ ){
        clearCurrentPage();
        do{
            current_page->text[current_page->text_count] = readChar();
        }
        while( current_page->text[current_page->text_count++] );
	if (file_version == 203) readChar(); // 0
        current_page->text_count--;
        current_page = current_page->next;
    }
    clearCurrentPage();

    if (file_version >= 205){
        Page *page = start_page;
        j = readInt();
        for (i=0 ; i<j ; i++){
            readStr(&page->tag);
            page = page->next;
        }
    }
    else if (file_version >= 204){
        readInt();
        readInt();
    }
    
    i = readInt();
    current_label_info = script_h.getLabelByLine( i );
    current_line = i - current_label_info.start_line;
    //printf("load %d:%d(%d-%d)\n", current_label_info.start_line, current_line, i, current_label_info.start_line);
    char *buf = script_h.getAddressByLine( i );
    
    j = readInt();
    for ( i=0 ; i<j ; i++ ){
        while( *buf != ':' ) buf++;
        buf++;
    }
    script_h.setCurrent( buf );

    display_mode = shelter_display_mode = DISPLAY_MODE_NORMAL;

    clickstr_state = CLICK_NONE;
    event_mode = 0;//WAIT_SLEEP_MODE;
    draw_cursor_flag = false;
    
    return 0;
}
void ONScripter::setupAnimationInfo( AnimationInfo *anim, FontInfo *info, bool single_line, ScriptDecoder* decoder )
{
    if (anim->trans_mode != AnimationInfo::TRANS_STRING &&
        anim->file_name && anim->surface_name &&
        strcmp(anim->file_name, anim->surface_name) == 0 &&
        ((!anim->mask_file_name && !anim->mask_surface_name) ||
         (anim->mask_file_name && !anim->mask_surface_name &&
          strcmp(anim->mask_file_name, anim->mask_surface_name) == 0))) return;

    anim->deleteSurface();
    anim->abs_flag = true;

    anim->surface_name = new char[ strlen(anim->file_name) + 1 ];
    strcpy( anim->surface_name, anim->file_name );

    if (anim->mask_file_name){
        anim->mask_surface_name = new char[ strlen(anim->mask_file_name) + 1 ];
        strcpy( anim->mask_surface_name, anim->mask_file_name );
    }
    
    if ( anim->trans_mode == AnimationInfo::TRANS_STRING ){
        FontInfo f_info = sentence_font;
        if (info) f_info = *info;
        f_info.rubyon_flag = anim->is_ruby_drawable;

        if ( anim->font_size_xy[0] >= 0 ){ // in case of Sprite, not rclick menu
            f_info.setTateyokoMode(0);
            f_info.top_xy[0] = anim->orig_pos.x;
            f_info.top_xy[1] = anim->orig_pos.y;
            if (anim->is_single_line)
                f_info.setLineArea( strlen(anim->file_name)/2+1 );
            f_info.clear();
            
            f_info.font_size_xy[0] = anim->font_size_xy[0];
            f_info.font_size_xy[1] = anim->font_size_xy[1];
            f_info.pitch_xy[0] = anim->font_pitch[0];
            f_info.pitch_xy[1] = anim->font_pitch[1];

            f_info.ttf_font[0] = NULL;
            f_info.ttf_font[1] = NULL;
        }

        if (f_info.ttf_font[0] == NULL)
            f_info.openFont( font_file, screen_ratio1, screen_ratio2 );

        SDL_Rect pos;
        if (anim->is_tight_region){
            drawString( anim->file_name, anim->color_list[ anim->current_cell ], &f_info, false, NULL, &pos, NULL, single_line, decoder );
        }
        else{
            int xy_bak[2];
            xy_bak[0] = f_info.xy[0];
            xy_bak[1] = f_info.xy[1];
            
            int xy[2] = {0, 0};
            f_info.setXY(f_info.num_xy[0]-1, f_info.num_xy[1]-1);
            pos = f_info.calcUpdatedArea(xy, screen_ratio1, screen_ratio2);

            f_info.xy[0] = xy_bak[0];
            f_info.xy[1] = xy_bak[1];
        }
        
        if (info != NULL){
            info->xy[0] = f_info.xy[0];
            info->xy[1] = f_info.xy[1];
        }
        
        anim->orig_pos.w = pos.w;
        anim->orig_pos.h = pos.h;
        anim->scalePosWH( screen_ratio1, screen_ratio2 );
        anim->allocImage( anim->pos.w*anim->num_of_cells, anim->pos.h, texture_format );
        anim->fill( 0, 0, 0, 0 );
        
        f_info.top_xy[0] = f_info.top_xy[1] = 0;
        for ( int i=0 ; i<anim->num_of_cells ; i++ ){
            f_info.clear();
            drawString( anim->file_name, anim->color_list[i], &f_info, false, NULL, NULL, anim, single_line, decoder );
            f_info.top_xy[0] += anim->orig_pos.w;
        }
    }
    else{
        bool has_alpha;
        int location;
        SDL_Surface *surface = loadImage( anim->file_name, &has_alpha, &location );

        SDL_Surface *surface_m = NULL;
        if (anim->trans_mode == AnimationInfo::TRANS_MASK)
            surface_m = loadImage( anim->mask_file_name );
        
        surface = anim->setupImageAlpha(surface, surface_m, has_alpha);

        if (surface &&
            screen_ratio2 != screen_ratio1 &&
            (!disable_rescale_flag || location == BaseReader::ARCHIVE_TYPE_NONE))
        {
            SDL_Surface *src_s = surface;

            int w, h;
            if ( (w = src_s->w * screen_ratio1 / screen_ratio2) == 0 ) w = 1;
            if ( (h = src_s->h * screen_ratio1 / screen_ratio2) == 0 ) h = 1;
            SDL_PixelFormat *fmt = image_surface->format;
            surface = SDL_CreateRGBSurface( SDL_SWSURFACE, w, h,
                                            fmt->BitsPerPixel, fmt->Rmask, fmt->Gmask, fmt->Bmask, fmt->Amask );
        
            resizeSurface(src_s, surface);
            SDL_FreeSurface(src_s);
        }

        anim->setImage( surface, texture_format );

        if ( surface_m ) SDL_FreeSurface(surface_m);
    }
}