void scene(t_data *d, t_dmlx *m) { if (m->scene == VM) vm(&d->vm, d->vm.cperloop); else if (m->scene == VM_INIT) vm_init(d, &d->vm); else if (m->scene == INTRO_LOAD) intro_load(m, &m->scene_img[0][0], &m->scene_img[0][1]); else if (m->scene == INTRO_MENU) intro_menu(&m->scene_img[0][2], &m->scene_img[0][1]); else if (m->scene == INTRO_OUT) intro_out(d, &m->scene_img[0][0], &m->scene_img[0][1] , &m->scene_img[0][3]); else if (m->scene == END) vm_end(m, &data()->vm, &m->scene_img[0][0]); }
/** * @brief Displays the introduction sequence. * * @brief text Path of text file to use. * @brief mus Type of music to use (run through music.lua). * @return 0 on success. */ int intro_display( const char *text, const char *mus ) { int i, max; unsigned int tcur, tlast; double dt; double x, y, vel; double offset; double density; SDL_Event event; /* Load the introduction. */ if (intro_load(text) < 0) return -1; /* Calculate velocity. */ density = ((double)intro_length / (double)intro_nlines); /* char / line */ density /= (double)intro_font.h; /* char / pixel */ vel = INTRO_SPEED / density; /* (char / s) * (pixel / char) = pixel / s */ /* Change music to intro music. */ if (mus != NULL) music_choose(mus); /* We need to clear key repeat to avoid infinite loops. */ toolkit_clearKey(); /* Prepare for intro loop. */ x = 100.; y = 0.; tlast = SDL_GetTicks(); offset = 0.; max = intro_nlines + SCREEN_H / ((intro_font.h + 5.)); while (1) { /* Get delta tick in seconds. */ tcur = SDL_GetTicks(); dt = (double)(tcur - tlast) / 1000.; tlast = tcur; /* Handle events. */ while (SDL_PollEvent(&event)) { switch (event.type) { case SDL_KEYDOWN: /* Escape skips directly. */ if (event.key.keysym.sym == SDLK_ESCAPE) offset = max * (intro_font.h + 5.); /* Only Handle space from here down. */ else if (!nstd_isspace(event.key.keysym.sym)) break; /* Purpose fallthrough. */ case SDL_JOYBUTTONDOWN: offset += 250.; default: break; } } /* Increment position. */ offset += vel * dt; /* Clear stuff. */ glClear(GL_COLOR_BUFFER_BIT); /* Draw the text. */ i = (int)(offset / (intro_font.h + 5.)); if (i > max) /* Out of lines. */ break; y = offset - (i+1) * (intro_font.h + 5.); while (i >= 0) { /* Skip in line isn't valid. */ if (i >= intro_nlines) { i--; y += intro_font.h + 5.; continue; } gl_print( &intro_font, x, y, &cConsole, intro_lines[i] ); /* Increment line and position. */ i--; y += intro_font.h + 5.; } /* Only thing we actually care about updating is music. */ music_update(); /* Display stuff. */ SDL_GL_SwapBuffers(); SDL_Delay(10); /* No need to burn CPU. */ } /* Stop music, normal music will start shortly after. */ music_stop(); /* Clean up after the introduction. */ intro_cleanup(); return 0; }
/** * @brief Displays the introduction sequence. * * @brief text Path of text file to use. * @brief mus Type of music to use (run through music.lua). * @return 0 on success. */ int intro_display( const char *text, const char *mus ) { double offset; /* distance from bottom of the top line. */ double line_height; /* # pixels per line. */ int lines_per_screen; /* max appearing lines on the screen. */ scroll_buf_t *sb_arr; /* array of lines to render. */ scroll_buf_t *sb_list; /* list " " " " */ double vel = 16.; /* velocity: speed of text. */ int stop = 0; /* stop the intro. */ unsigned int tcur, tlast; /* timers. */ double delta; /* time diff from last render to this one. */ int line_index = 0; /* index into the big list of intro lines. */ intro_img_t side_image; /* image to go along with the text. */ intro_img_t transition; /* image for transitioning. */ /* Load the introduction. */ if (intro_load(text) < 0) return -1; /* Change music to intro music. */ if (mus != NULL) music_choose(mus); /* We need to clear key repeat to avoid infinite loops. */ toolkit_clearKey(); /* Enable keyrepeat just for the intro. */ SDL_EnableKeyRepeat( conf.repeat_delay, conf.repeat_freq ); /* Do a few calculations to figure out how many lines can be present on the screen at any given time. */ line_height = (double)intro_font.h * 1.3; lines_per_screen = (int)(SCREEN_H / line_height + 1.5); /* round up + 1 */ sb_arr = (scroll_buf_t*)malloc( sizeof(scroll_buf_t) * lines_per_screen ); /* Force the first line to be loaded immediately. */ offset = line_height; /* Create a cycle of lines. */ sb_list = arrange_scroll_buf( sb_arr, lines_per_screen ); /* Unset the side image. */ initialize_image( &side_image ); initialize_image( &transition ); tlast = SDL_GetTicks(); while (!stop) { tcur = SDL_GetTicks(); delta = (double)(tcur - tlast) / 1000.; tlast = tcur; /* Increment position. */ offset += vel * delta; while (! (offset < line_height)) { /* One line has scrolled off, and another one on. */ if (line_index < intro_nlines) { switch (intro_lines[line_index][0]) { case 't': /* plain ol' text. */ sb_list->text = &intro_lines[line_index][1]; offset -= line_height; sb_list = sb_list->next; break; case 'i': /* fade in image. */ intro_fade_image_in( &side_image, &transition, &intro_lines[line_index][1] ); break; case 'o': /* fade out image. */ if (NULL == side_image.tex) { WARN("Tried to fade out without an image." ); break; } side_image.fade_rate = -0.1; side_image.c.a = 0.99; break; default: /* unknown. */ break; } ++line_index; } else { sb_list->text = NULL; offset -= line_height; sb_list = sb_list->next; } } /* while (offset > line_height) */ /* Fade the side image. */ if (side_image.tex != NULL && side_image.c.a < 1.0) { side_image.c.a += delta * vel * side_image.fade_rate; if (transition.tex != NULL && transition.fade_rate > 0.0) { transition.c.a += delta * vel * transition.fade_rate; } if (side_image.c.a > 1.0) { /* Faded in... */ side_image.c.a = 1.0; side_image.fade_rate = 0.0; } else if (side_image.c.a < 0.0) { /* Faded out... */ gl_freeTexture( side_image.tex ); if (transition.tex != NULL) { side_image.tex = transition.tex; side_image.c.a = transition.c.a; side_image.y = transition.y; side_image.fade_rate = 0.1; transition.tex = NULL; transition.c.a = 1.0; } else { side_image.c.a = 1.0; side_image.tex = NULL; side_image.fade_rate = 0.0; } } } /* Clear stuff. */ glClear(GL_COLOR_BUFFER_BIT); /* Only thing we actually care about updating is music. */ music_update( 0. ); /* Draw text. */ stop = intro_draw_text( sb_list, offset, line_height ); if (NULL != side_image.tex) { /* Draw the image next to the text. */ gl_blitScale( side_image.tex, side_image.x, side_image.y, side_image.tex->w, side_image.tex->h, &side_image.c ); } if (NULL != transition.tex && transition.c.a > 0.0) { /* Draw the image in transition. */ gl_blitScale( transition.tex, transition.x, transition.y, transition.tex->w, transition.tex->h, &transition.c ); } /* Display stuff. */ SDL_GL_SwapBuffers(); SDL_Delay(10); /* No need to burn CPU. */ /* Handle user events. */ intro_event_handler( &stop, &offset, &vel ); } /* while (!stop) */ /* free malloc'd memory. */ free( sb_arr ); if (NULL != side_image.tex) { gl_freeTexture( side_image.tex ); } if (NULL != transition.tex) { gl_freeTexture( transition.tex ); } /* Disable intro's key repeat. */ SDL_EnableKeyRepeat( 0, 0 ); /* Stop music, normal music will start shortly after. */ music_stop(); /* Clean up after the introduction. */ intro_cleanup(); return 0; }
// Loads BK file etc. int scene_load(scene *scene, unsigned int scene_id) { scene->bk = sd_bk_create(); scene->loop = 1; scene->local = NULL; int ret = 0; // Load BK switch(scene_id) { case SCENE_INTRO: ret = sd_bk_load(scene->bk, "resources/INTRO.BK"); break; case SCENE_MENU: ret = sd_bk_load(scene->bk, "resources/MAIN.BK"); break; case SCENE_ARENA0: ret = sd_bk_load(scene->bk, "resources/ARENA0.BK"); break; case SCENE_ARENA1: ret = sd_bk_load(scene->bk, "resources/ARENA1.BK"); break; case SCENE_ARENA2: ret = sd_bk_load(scene->bk, "resources/ARENA2.BK"); break; case SCENE_ARENA3: ret = sd_bk_load(scene->bk, "resources/ARENA3.BK"); break; case SCENE_ARENA4: ret = sd_bk_load(scene->bk, "resources/ARENA4.BK"); break; case SCENE_ARENA5: ret = sd_bk_load(scene->bk, "resources/ARENA5.BK"); break; case SCENE_NEWSROOM: ret = sd_bk_load(scene->bk, "resources/NEWSROOM.BK"); break; case SCENE_END: ret = sd_bk_load(scene->bk, "resources/END.BK"); break; case SCENE_END1: ret = sd_bk_load(scene->bk, "resources/END1.BK"); break; case SCENE_END2: ret = sd_bk_load(scene->bk, "resources/END2.BK"); break; case SCENE_CREDITS: ret = sd_bk_load(scene->bk, "resources/CREDITS.BK"); break; case SCENE_MECHLAB: ret = sd_bk_load(scene->bk, "resources/MECHLAB.BK"); break; case SCENE_MELEE: ret = sd_bk_load(scene->bk, "resources/MELEE.BK"); break; case SCENE_VS: ret = sd_bk_load(scene->bk, "resources/VS.BK"); break; case SCENE_NORTHAM: ret = sd_bk_load(scene->bk, "resources/NORTH_AM.BK"); break; case SCENE_KATUSHAI: ret = sd_bk_load(scene->bk, "resources/KATUSHAI.BK"); break; case SCENE_WAR: ret = sd_bk_load(scene->bk, "resources/WAR.BK"); break; case SCENE_WORLD: ret = sd_bk_load(scene->bk, "resources/WORLD.BK"); break; default: sd_bk_delete(scene->bk); PERROR("Unknown scene_id!"); return 1; } if(ret) { sd_bk_delete(scene->bk); PERROR("Unable to load BK file!"); return 1; } scene->this_id = scene_id; scene->next_id = scene_id; // optional callback scene->post_init = NULL; // Load specific stuff switch(scene_id) { case SCENE_INTRO: intro_load(scene); break; case SCENE_MENU: mainmenu_load(scene); break; case SCENE_CREDITS: credits_load(scene); break; case SCENE_MELEE: fixup_palette(scene->bk->palettes[0]); melee_load(scene); break; case SCENE_VS: fixup_palette(scene->bk->palettes[0]); vs_load(scene); break; case SCENE_MECHLAB: mechlab_load(scene); break; case SCENE_ARENA0: case SCENE_ARENA1: case SCENE_ARENA2: case SCENE_ARENA3: case SCENE_ARENA4: case SCENE_ARENA5: fixup_palette(scene->bk->palettes[0]); arena_load(scene); break; default: scene->render = NULL; scene->event = NULL; scene->init = NULL; scene->deinit = NULL; } // Init scene if(scene->init != NULL) { if(scene->init(scene)) { sd_bk_delete(scene->bk); return 1; } } // Convert background sd_rgba_image *bg = sd_vga_image_decode(scene->bk->background, scene->bk->palettes[0], -1); texture_create(&scene->background, bg->data, bg->w, bg->h); sd_rgba_image_delete(bg); // Players list list_create(&scene->child_players); list_create(&scene->root_players); // Handle animations animation *ani; sd_bk_anim *bka; array_create(&scene->animations); for(unsigned int i = 0; i < 50; i++) { bka = scene->bk->anims[i]; if(bka) { // Create animation + textures, etc. ani = malloc(sizeof(animation)); animation_create(ani, bka->animation, scene->bk->palettes[0], -1, scene->bk->soundtable); array_set(&scene->animations, i, ani); // Start playback on those animations, that have load_on_start flag as true // or if we are handling animation 25 of intro // TODO: Maybe make the exceptions a bit more generic or something ? // TODO check other probabilites here if(bka->load_on_start || bka->probability == 1 || (scene_id == SCENE_INTRO && i == 25)) { animationplayer player; player.x = ani->sdani->start_x; player.y = ani->sdani->start_y; animationplayer_create(&player, i, ani); player.userdata = scene; player.add_player = scene_add_ani_player; player.del_player = scene_set_ani_finished; list_append(&scene->root_players, &player, sizeof(animationplayer)); DEBUG("Create animation %d @ x,y = %d,%d", i, player.x, player.y); } } } // run post init, if defined if(scene->post_init != NULL) { DEBUG("running post init"); scene->post_init(scene); } // All done DEBUG("Scene %i loaded! Textures now using %d bytes of (v)ram!", scene_id, texturelist_get_bsize()); return 0; }