void vs_handle_action(scene *scene, int action) { vs_local *local = scene_get_userdata(scene); if(dialog_is_visible(&local->too_pathetic_dialog)) { dialog_event(&local->too_pathetic_dialog, action); } else if(dialog_is_visible(&local->quit_dialog)) { dialog_event(&local->quit_dialog, action); } else { switch (action) { case ACT_KICK: case ACT_PUNCH: game_state_set_next(scene->gs, SCENE_ARENA0+local->arena); break; case ACT_UP: case ACT_LEFT: if(game_state_get_player(scene->gs, 1)->selectable) { local->arena--; if (local->arena < 0) { local->arena =4; } object_select_sprite(&local->arena_select, local->arena); } break; case ACT_DOWN: case ACT_RIGHT: if(game_state_get_player(scene->gs, 1)->selectable) { local->arena++; if (local->arena > 4) { local->arena = 0; } object_select_sprite(&local->arena_select, local->arena); } break; } } }
int vs_create(scene *scene) { // Init local data vs_local *local = malloc(sizeof(vs_local)); scene_set_userdata(scene, local); game_player *player1 = game_state_get_player(scene->gs, 0); game_player *player2 = game_state_get_player(scene->gs, 1); snprintf(local->vs_str, 128, "%s VS. %s", lang_get(20+player1->pilot_id), lang_get(20+player2->pilot_id)); animation *ani; palette *mpal = video_get_base_palette(); palette_set_player_color(mpal, 0, player1->colors[2], 0); palette_set_player_color(mpal, 0, player1->colors[1], 1); palette_set_player_color(mpal, 0, player1->colors[0], 2); palette_set_player_color(mpal, 1, player2->colors[2], 0); palette_set_player_color(mpal, 1, player2->colors[1], 1); palette_set_player_color(mpal, 1, player2->colors[0], 2); video_force_pal_refresh(); // HAR ani = &bk_get_info(&scene->bk_data, 5)->ani; object_create(&local->player1_har, scene->gs, vec2i_create(160,0), vec2f_create(0, 0)); object_set_animation(&local->player1_har, ani); object_select_sprite(&local->player1_har, player1->har_id); object_create(&local->player2_har, scene->gs, vec2i_create(160,0), vec2f_create(0, 0)); object_set_animation(&local->player2_har, ani); object_select_sprite(&local->player2_har, player2->har_id); object_set_direction(&local->player2_har, OBJECT_FACE_LEFT); object_set_pal_offset(&local->player2_har, 48); // PLAYER ani = &bk_get_info(&scene->bk_data, 4)->ani; object_create(&local->player1_portrait, scene->gs, vec2i_create(-10,150), vec2f_create(0, 0)); object_set_animation(&local->player1_portrait, ani); object_select_sprite(&local->player1_portrait, player1->pilot_id); object_create(&local->player2_portrait, scene->gs, vec2i_create(330,150), vec2f_create(0, 0)); object_set_animation(&local->player2_portrait, ani); object_select_sprite(&local->player2_portrait, player2->pilot_id); object_set_direction(&local->player2_portrait, OBJECT_FACE_LEFT); // clone the left side of the background image // Note! We are touching the scene-wide background surface! surface_sub(&scene->bk_data.background, // DST Surface &scene->bk_data.background, // SRC Surface 160, 0, // DST 0, 0, // SRC 160, 200, // Size SUB_METHOD_MIRROR); // Flip the right side horizontally if (player2->selectable) { // player1 gets to choose, start at arena 0 local->arena = 0; } else { // pick a random arena for 1 player mode local->arena = rand_int(5); // srand was done in melee } // Arena if(player2->selectable) { ani = &bk_get_info(&scene->bk_data, 3)->ani; object_create(&local->arena_select, scene->gs, vec2i_create(59,155), vec2f_create(0, 0)); object_set_animation(&local->arena_select, ani); object_select_sprite(&local->arena_select, local->arena); } // SCIENTIST int scientistpos = rand_int(4); vec2i scientistcoord = spawn_position(scientistpos, 1); if (scientistpos % 2) { scientistcoord.x += 50; } else { scientistcoord.x -= 50; } object *o_scientist = malloc(sizeof(object)); ani = &bk_get_info(&scene->bk_data, 8)->ani; object_create(o_scientist, scene->gs, scientistcoord, vec2f_create(0, 0)); object_set_animation(o_scientist, ani); object_select_sprite(o_scientist, 0); object_set_direction(o_scientist, scientistpos % 2 ? OBJECT_FACE_LEFT : OBJECT_FACE_RIGHT); game_state_add_object(scene->gs, o_scientist, RENDER_LAYER_MIDDLE, 0, 0); // WELDER int welderpos = rand_int(6); // welder can't be on the same gantry or the same *side* as the scientist // he also can't be on the same 'level' // but he has 10 possible starting positions while ((welderpos % 2) == (scientistpos % 2) || (scientistpos < 2 && welderpos < 2) || (scientistpos > 1 && welderpos > 1 && welderpos < 4)) { welderpos = rand_int(6); } object *o_welder = malloc(sizeof(object)); ani = &bk_get_info(&scene->bk_data, 7)->ani; object_create(o_welder, scene->gs, spawn_position(welderpos, 0), vec2f_create(0, 0)); object_set_animation(o_welder, ani); object_select_sprite(o_welder, 0); object_set_spawn_cb(o_welder, cb_vs_spawn_object, (void*)scene); object_set_destroy_cb(o_welder, cb_vs_destroy_object, (void*)scene); object_set_direction(o_welder, welderpos % 2 ? OBJECT_FACE_LEFT : OBJECT_FACE_RIGHT); game_state_add_object(scene->gs, o_welder, RENDER_LAYER_MIDDLE, 0, 0); // GANTRIES object *o_gantry_a = malloc(sizeof(object)); ani = &bk_get_info(&scene->bk_data, 11)->ani; object_create(o_gantry_a, scene->gs, vec2i_create(0,0), vec2f_create(0, 0)); object_set_animation(o_gantry_a, ani); object_select_sprite(o_gantry_a, 0); game_state_add_object(scene->gs, o_gantry_a, RENDER_LAYER_TOP, 0, 0); object *o_gantry_b = malloc(sizeof(object)); object_create(o_gantry_b, scene->gs, vec2i_create(320,0), vec2f_create(0, 0)); object_set_animation(o_gantry_b, ani); object_select_sprite(o_gantry_b, 0); object_set_direction(o_gantry_b, OBJECT_FACE_LEFT); game_state_add_object(scene->gs, o_gantry_b, RENDER_LAYER_TOP, 0, 0); // Background tex menu_background2_create(&local->arena_select_bg, 211, 50); // Quit Dialog dialog_create(&local->quit_dialog, DIALOG_STYLE_YES_NO, "ARE YOU SURE YOU WANT TO QUIT THIS GAME?", 72, 60); local->quit_dialog.userdata = scene; local->quit_dialog.clicked = vs_quit_dialog_clicked; // Too Pathetic Dialog char insult[512]; snprintf(insult, 512, lang_get(748), "Veteran", "Major Kreissack"); dialog_create(&local->too_pathetic_dialog, DIALOG_STYLE_OK, insult, 72, 60); local->too_pathetic_dialog.userdata = scene; local->too_pathetic_dialog.clicked = vs_too_pathetic_dialog_clicked; if (player2->pilot_id == 10 && settings_get()->gameplay.difficulty < 2) { // kriessack, but not on Veteran or higher dialog_show(&local->too_pathetic_dialog, 1); } // Callbacks scene_set_render_cb(scene, vs_render); scene_set_render_overlay_cb(scene, vs_render_overlay); scene_set_input_poll_cb(scene, vs_input_tick); scene_set_dynamic_tick_cb(scene, vs_dynamic_tick); scene_set_static_tick_cb(scene, vs_static_tick); scene_set_free_cb(scene, vs_free); // Pick renderer video_select_renderer(VIDEO_RENDERER_HW); return 0; }
void player_run(object *obj) { // Some vars for easier life player_animation_state *state = &obj->animation_state; player_sprite_state *rstate = &obj->sprite_state; if(state->finished) return; // Handle slide operation if(obj->slide_state.timer > 0) { obj->pos.x += obj->slide_state.vel.x; obj->pos.y += obj->slide_state.vel.y; obj->slide_state.timer--; } // Not sure what this does int run_ret; if(state->end_frame == UINT32_MAX) { run_ret = sd_stringparser_run( state->parser, state->ticks - 1); } else { run_ret = sd_stringparser_run_frames( state->parser, state->ticks - 1, state->end_frame); } // Handle frame if(run_ret == 0) { // Handle frame switch sd_stringparser_frame *param = &state->parser->current_frame; sd_stringparser_frame n_param; sd_stringparser_frame *f = param; sd_stringparser_frame *n = &n_param; int real_frame = param->letter - 65; // Do something if animation is finished! if(param->is_animation_end) { if(state->repeat) { player_reset(obj); sd_stringparser_run(state->parser, state->ticks - 1); real_frame = param->letter - 65; } else if(obj->finish != NULL) { obj->cur_sprite = NULL; obj->finish(obj); return; } else { obj->cur_sprite = NULL; state->finished = 1; return; } } // If frame changed, do something if(param->id != state->previous) { player_clear_frame(obj); // Tick management if(isset(f, "d")) { cmd_tickjump(obj, get(f, "d")); sd_stringparser_reset(state->parser); } // Animation management if(isset(f, "m") && state->spawn != NULL) { int mx = isset(f, "mx") ? get(f, "mx") : 0; int my = isset(f, "my") ? get(f, "my") : 0; int mg = isset(f, "mg") ? get(f, "mg") : 0; DEBUG("Spawning %d, with g = %d, pos = (%d,%d)", get(f, "m"), mg, mx, my); state->spawn( obj, get(f, "m"), vec2i_create(mx, my), mg, state->spawn_userdata); } if(isset(f, "md") && state->destroy != NULL) { state->destroy(obj, get(f, "md"), state->destroy_userdata); } // Music playback if(isset(f, "smo")) { cmd_music_on(get(f, "smo")); } if(isset(f, "smf")) { cmd_music_off(); } // Sound playback if(isset(f, "s")) { float pitch = PITCH_DEFAULT; float volume = VOLUME_DEFAULT * (settings_get()->sound.sound_vol/10.0f); float panning = PANNING_DEFAULT; if(isset(f, "sf")) { int p = clamp(get(f, "sf"), -16, 239); pitch = clampf((p/239.0f)*3.0f + 1.0f, PITCH_MIN, PITCH_MAX); } if(isset(f, "l")) { int v = clamp(get(f, "l"), 0, 100); volume = (v / 100.0f) * (settings_get()->sound.sound_vol/10.0f); } if(isset(f, "sb")) { panning = clamp(get(f, "sb"), -100, 100) / 100.0f; } int sound_id = obj->sound_translation_table[get(f, "s")] - 1; sound_play(sound_id, volume, panning, pitch); } // Blend mode stuff if(isset(f, "b1")) { rstate->method_flags &= 0x2000; } if(isset(f, "b2")) { rstate->method_flags &= 0x4000; } if(isset(f, "bb")) { rstate->method_flags &= 0x0010; rstate->blend_finish = get(f, "bb"); } if(isset(f, "be")) { rstate->method_flags &= 0x0800; } if(isset(f, "bf")) { rstate->method_flags &= 0x0001; rstate->blend_finish = get(f, "bf"); } if(isset(f, "bh")) { rstate->method_flags &= 0x0040; } if(isset(f, "bl")) { rstate->method_flags &= 0x0008; rstate->blend_finish = get(f, "bl"); } if(isset(f, "bm")) { rstate->method_flags &= 0x0100; rstate->blend_finish = get(f, "bm"); } if(isset(f, "bj")) { rstate->method_flags &= 0x0400; rstate->blend_finish = get(f, "bj"); } if(isset(f, "bs")) { rstate->blend_start = get(f, "bs"); } if(isset(f, "bu")) { rstate->method_flags &= 0x8000; } if(isset(f, "bw")) { rstate->method_flags &= 0x0080; } if(isset(f, "bx")) { rstate->method_flags &= 0x0002; } // Palette tricks if(isset(f, "bpd")) { rstate->pal_ref_index = get(f, "bpd"); } if(isset(f, "bpn")) { rstate->pal_entry_count = get(f, "bpn"); } if(isset(f, "bps")) { rstate->pal_start_index = get(f, "bps"); } if(isset(f, "bpb")) { rstate->pal_begin = get(f, "bpb"); } if(isset(f, "bpd")) { rstate->pal_end = get(f, "bpd"); } if(isset(f, "bz")) { rstate->pal_tint = get(f, "bz"); } // Handle movement if (isset(f, "v")) { int x = 0, y = 0; if(isset(f, "y-")) { y = get(f, "y-") * -1; } else if(isset(f, "y+")) { y = get(f, "y+"); } if(isset(f, "x-")) { x = get(f, "x-") * -1 * object_get_direction(obj); } else if(isset(f, "x+")) { x = get(f, "x+") * object_get_direction(obj); } if (x || y) { obj->vel.x += x; obj->vel.y += y; } } // handle scaling on the Y axis if(isset(f, "y")) { obj->y_percent = get(f, "y") / 100.0f; } if (isset(f, "e")) { // x,y relative to *enemy's* position int x = 0, y = 0; if(isset(f, "y-")) { y = get(f, "y-") * -1; } else if(isset(f, "y+")) { y = get(f, "y+"); } if(isset(f, "x-")) { x = get(f, "x-") * -1 * object_get_direction(obj); } else if(isset(f, "x+")) { x = get(f, "x+") * object_get_direction(obj); } float x_dist = dist(obj->pos.x, state->enemy_x + x); float y_dist = dist(obj->pos.y, state->enemy_y + y); obj->slide_state.timer = param->duration; obj->slide_state.vel.x = x_dist / (float)param->duration; obj->slide_state.vel.y = y_dist / (float)param->duration; DEBUG("Slide object %d for (x,y) = (%f,%f) for %d ticks.", obj->cur_animation->id, obj->slide_state.vel.x, obj->slide_state.vel.y, param->duration); } if (isset(f, "v") == 0 && isset(f, "e") == 0 && (isset(f, "x+") || isset(f, "y+") || isset(f, "x-") || isset(f, "y-"))) { // check for relative X interleaving int x = 0, y = 0; if(isset(f, "y-")) { y = get(f, "y-") * -1; } else if(isset(f, "y+")) { y = get(f, "y+"); } if(isset(f, "x-")) { x = get(f, "x-") * -1 * object_get_direction(obj); } else if(isset(f, "x+")) { x = get(f, "x+") * object_get_direction(obj); } obj->slide_state.timer = param->duration; obj->slide_state.vel.x = (float)x / (float)param->duration; obj->slide_state.vel.y = (float)y / (float)param->duration; DEBUG("Slide object %d for (x,y) = (%f,%f) for %d ticks.", obj->cur_animation->id, obj->slide_state.vel.x, obj->slide_state.vel.y, param->duration); } // Check if next frame contains X=nnn or Y=nnn if(!param->is_final_frame) { sd_stringparser_peek(state->parser, param->id + 1, &n_param); int slide = 0; float xpos = obj->pos.x; float ypos = obj->pos.y; if(isset(n, "x=") || isset(n, "y=")) { obj->slide_state.vel = vec2f_create(0,0); } if(isset(n, "x=")) { slide = get(n, "x="); if(object_get_direction(obj) == OBJECT_FACE_LEFT) { // if the sprite is flipped horizontally, adjust the X coordinates slide = 320 - slide; } if(slide != xpos) { obj->slide_state.vel.x = dist(xpos, slide) / (float)param->duration; obj->slide_state.timer = param->duration; DEBUG("Slide object %d for X = %f for a total of %d ticks.", obj->cur_animation->id, obj->slide_state.vel.x, param->duration); } } if(isset(n, "y=")) { slide = get(n, "y="); if(slide != ypos) { obj->slide_state.vel.y = dist(ypos, slide) / (float)param->duration; obj->slide_state.timer = param->duration; DEBUG("Slide object %d for Y = %f for a total of %d ticks.", obj->cur_animation->id, obj->slide_state.vel.y, param->duration); } } } // Set render settings if(real_frame < 25) { object_select_sprite(obj, real_frame); if(obj->cur_sprite != NULL) { rstate->duration = param->duration; rstate->blendmode = isset(f, "br") ? BLEND_ADDITIVE : BLEND_ALPHA; if(isset(f, "r")) { rstate->flipmode ^= FLIP_HORIZONTAL; } if(isset(f, "f")) { rstate->flipmode ^= FLIP_VERTICAL; } } } else { obj->cur_sprite = NULL; } } state->previous = param->id; } // Animation ticks if(state->reverse) { state->ticks--; } else { state->ticks++; } // Sprite ticks rstate->timer++; // All done. return; }
// Init mechlab int mechlab_create(scene *scene) { // Alloc mechlab_local *local = malloc(sizeof(mechlab_local)); memset(local, 0, sizeof(mechlab_local)); animation *bg_ani[3]; // Init the background for(int i = 0; i < sizeof(bg_ani)/sizeof(animation*); i++) { sprite *spr = sprite_copy(animation_get_sprite(&bk_get_info(&scene->bk_data, 14)->ani, i)); bg_ani[i] = create_animation_from_single(spr, spr->pos); object_create(&local->bg_obj[i], scene->gs, vec2i_create(0,0), vec2f_create(0,0)); object_set_animation(&local->bg_obj[i], bg_ani[i]); object_select_sprite(&local->bg_obj[i], 0); object_set_repeat(&local->bg_obj[i], 1); object_set_animation_owner(&local->bg_obj[i], OWNER_OBJECT); } // Find last saved game ... game_player *p1 = game_state_get_player(scene->gs, 0); const char* last_name = settings_get()->tournament.last_name; if(last_name == NULL || strlen(last_name) == 0) { last_name = NULL; } // ... and attempt to load it, if one was found. if(last_name != NULL) { int ret = sg_load(&p1->pilot, last_name); if(ret != SD_SUCCESS) { PERROR("Could not load saved game for playername '%s': %s!", last_name, sd_get_error(ret)); last_name = NULL; } else { DEBUG("Loaded savegame for playername '%s'.", last_name); } } // Either initialize a new tournament if no savegame is found, // or just show old savegame stats directly if it was. local->dashtype = DASHBOARD_NONE; if(last_name == NULL) { DEBUG("No previous savegame found"); } else { DEBUG("Previous savegame found; loading as default."); } mechlab_select_dashboard(scene, local, DASHBOARD_STATS); // Create main menu local->frame = guiframe_create(0, 0, 320, 200); guiframe_set_root(local->frame, lab_menu_main_create(scene)); guiframe_layout(local->frame); // Load HAR animation *initial_har_ani = &bk_get_info(&scene->bk_data, 15 + p1->pilot.har_id)->ani; local->mech = malloc(sizeof(object)); object_create(local->mech, scene->gs, vec2i_create(0,0), vec2f_create(0,0)); object_set_animation(local->mech, initial_har_ani); object_set_repeat(local->mech, 1); object_dynamic_tick(local->mech); // Set callbacks scene_set_userdata(scene, local); scene_set_input_poll_cb(scene, mechlab_input_tick); scene_set_event_cb(scene, mechlab_event); scene_set_render_cb(scene, mechlab_render); scene_set_free_cb(scene, mechlab_free); scene_set_dynamic_tick_cb(scene, mechlab_tick); // Pick renderer video_select_renderer(VIDEO_RENDERER_HW); return 0; }
int cutscene_create(scene *scene) { cutscene_local *local = malloc(sizeof(cutscene_local)); game_player *p1 = game_state_get_player(scene->gs, 0); const char *text = ""; switch (scene->id) { case SCENE_END: cutscene_music(PSM_END); text = lang_get(END_TEXT); local->text_x = 10; local->text_y = 5; local->text_width = 300; local->color = COLOR_YELLOW; break; case SCENE_END1: text = lang_get(END1_TEXT+p1->pilot_id); local->text_x = 10; local->text_y = 160; local->text_width = 300; local->color = COLOR_RED; // Pilot face animation *ani = &bk_get_info(&scene->bk_data, 3)->ani; object *obj = malloc(sizeof(object)); object_create(obj, scene->gs, vec2i_create(0,0), vec2f_create(0, 0)); object_set_animation(obj, ani); object_select_sprite(obj, p1->pilot_id); obj->halt=1; game_state_add_object(scene->gs, obj, RENDER_LAYER_TOP); // Face effects ani = &bk_get_info(&scene->bk_data, 10+p1->pilot_id)->ani; obj = malloc(sizeof(object)); object_create(obj, scene->gs, vec2i_create(0,0), vec2f_create(0, 0)); object_set_animation(obj, ani); game_state_add_object(scene->gs, obj, RENDER_LAYER_TOP); break; case SCENE_END2: text = lang_get(END2_TEXT+p1->pilot_id); local->text_x = 10; local->text_y = 160; local->text_width = 300; local->color = COLOR_GREEN; break; } local->len = strlen(text)-1; local->pos = 0; local->text = malloc(strlen(text)+1); strcpy(local->text, text); local->current = local->text; char *p; if ((p = strchr(local->text, '\n'))) { // null out the byte *p = '\0'; } // Callbacks scene_set_userdata(scene, local); scene_set_free_cb(scene, cutscene_free); scene_set_event_cb(scene, cutscene_event); scene_set_startup_cb(scene, cutscene_startup); scene_set_render_overlay_cb(scene, cutscene_render_overlay); // Pick renderer video_select_renderer(VIDEO_RENDERER_HW); return 0; }
void player_run(object *obj) { // Some vars for easier life player_animation_state *state = &obj->animation_state; player_sprite_state *rstate = &obj->sprite_state; if(state->finished) return; // Handle slide operation if(obj->slide_state.timer > 0) { obj->pos.x += obj->slide_state.vel.x; obj->pos.y += obj->slide_state.vel.y; obj->slide_state.timer--; } if(obj->enemy_slide_state.timer > 0) { obj->enemy_slide_state.duration++; obj->pos.x = state->enemy->pos.x + obj->enemy_slide_state.dest.x; obj->pos.y = state->enemy->pos.y + obj->enemy_slide_state.dest.y; obj->enemy_slide_state.timer--; } // Not sure what this does const sd_script_frame *frame = sd_script_get_frame_at(&state->parser, state->current_tick); // Animation has ended ? if(frame == NULL) { if(state->repeat) { player_reset(obj); frame = sd_script_get_frame_at(&state->parser, state->current_tick); } else if(obj->finish != NULL) { obj->cur_sprite = NULL; obj->finish(obj); return; } else { obj->cur_sprite = NULL; state->finished = 1; return; } } // Handle frame state->entered_frame = 0; if(frame == NULL) { DEBUG("Something went wery wrong!"); // We shouldn't really get here, unless stringparser messes something up badly } else { // If frame changed, do something if(sd_script_frame_changed(&state->parser, state->previous_tick, state->current_tick)) { state->entered_frame = 1; player_clear_frame(obj); // Tick management if(sd_script_isset(frame, "d")) { if(!obj->animation_state.disable_d) { state->previous_tick = sd_script_get(frame, "d")-1; state->current_tick = sd_script_get(frame, "d"); } } // Hover flag if(sd_script_isset(frame, "h")) { rstate->disable_gravity = 1; } else { rstate->disable_gravity = 0; } if(sd_script_isset(frame, "ua")) { obj->animation_state.enemy->sprite_state.disable_gravity = 1; } // Animation creation command if(sd_script_isset(frame, "m") && state->spawn != NULL) { int mx = 0; if (sd_script_isset(frame, "mrx")) { int mrx = sd_script_get(frame, "mrx"); int mm = sd_script_isset(frame, "mm") ? sd_script_get(frame, "mm") : mrx; mx = random_int(&obj->rand_state, 320 - 2*mm) + mrx; DEBUG("randomized mx as %d", mx); } else if(sd_script_isset(frame, "mx")) { mx = obj->start.x + (sd_script_get(frame, "mx") * object_get_direction(obj)); } int my = 0; if (sd_script_isset(frame, "mry")) { int mry = sd_script_get(frame, "mry"); int mm = sd_script_isset(frame, "mm") ? sd_script_get(frame, "mm") : mry; my = random_int(&obj->rand_state, 320 - 2*mm) + mry; DEBUG("randomized my as %d", my); } else if(sd_script_isset(frame, "my")) { my = obj->start.y + sd_script_get(frame, "my"); } int mg = sd_script_isset(frame, "mg") ? sd_script_get(frame, "mg") : 0; state->spawn( obj, sd_script_get(frame, "m"), vec2i_create(mx, my), mg, state->spawn_userdata); } // Animation deletion if(sd_script_isset(frame, "md") && state->destroy != NULL) { state->destroy(obj, sd_script_get(frame, "md"), state->destroy_userdata); } // Music playback if(sd_script_isset(frame, "smo")) { if(sd_script_get(frame, "smo") == 0) { music_stop(); return; } music_play(PSM_END + (sd_script_get(frame, "smo") - 1)); } if(sd_script_isset(frame, "smf")) { music_stop(); } // Sound playback if(sd_script_isset(frame, "s")) { float pitch = PITCH_DEFAULT; float volume = VOLUME_DEFAULT * (settings_get()->sound.sound_vol/10.0f); float panning = PANNING_DEFAULT; if(sd_script_isset(frame, "sf")) { int p = clamp(sd_script_get(frame, "sf"), -16, 239); pitch = clampf((p/239.0f)*3.0f + 1.0f, PITCH_MIN, PITCH_MAX); } if(sd_script_isset(frame, "l")) { int v = clamp(sd_script_get(frame, "l"), 0, 100); volume = (v / 100.0f) * (settings_get()->sound.sound_vol/10.0f); } if(sd_script_isset(frame, "sb")) { panning = clamp(sd_script_get(frame, "sb"), -100, 100) / 100.0f; } int sound_id = obj->sound_translation_table[sd_script_get(frame, "s")] - 1; sound_play(sound_id, volume, panning, pitch); } // Blend mode stuff if(sd_script_isset(frame, "b1")) { rstate->method_flags &= 0x2000; } if(sd_script_isset(frame, "b2")) { rstate->method_flags &= 0x4000; } if(sd_script_isset(frame, "bb")) { rstate->method_flags &= 0x0010; rstate->blend_finish = sd_script_get(frame, "bb"); rstate->screen_shake_vertical = sd_script_get(frame, "bb"); } if(sd_script_isset(frame, "be")) { rstate->method_flags &= 0x0800; } if(sd_script_isset(frame, "bf")) { rstate->method_flags &= 0x0001; rstate->blend_finish = sd_script_get(frame, "bf"); } if(sd_script_isset(frame, "bh")) { rstate->method_flags &= 0x0040; } if(sd_script_isset(frame, "bl")) { rstate->method_flags &= 0x0008; rstate->blend_finish = sd_script_get(frame, "bl"); rstate->screen_shake_horizontal = sd_script_get(frame, "bl"); } if(sd_script_isset(frame, "bm")) { rstate->method_flags &= 0x0100; rstate->blend_finish = sd_script_get(frame, "bm"); } if(sd_script_isset(frame, "bj")) { rstate->method_flags &= 0x0400; rstate->blend_finish = sd_script_get(frame, "bj"); } if(sd_script_isset(frame, "bs")) { rstate->blend_start = sd_script_get(frame, "bs"); } if(sd_script_isset(frame, "bu")) { rstate->method_flags &= 0x8000; } if(sd_script_isset(frame, "bw")) { rstate->method_flags &= 0x0080; } if(sd_script_isset(frame, "bx")) { rstate->method_flags &= 0x0002; } // Palette tricks if(sd_script_isset(frame, "bpd")) { rstate->pal_ref_index = sd_script_get(frame, "bpd"); } if(sd_script_isset(frame, "bpn")) { rstate->pal_entry_count = sd_script_get(frame, "bpn"); } if(sd_script_isset(frame, "bps")) { rstate->pal_start_index = sd_script_get(frame, "bps"); } if(sd_script_isset(frame, "bpf")) { // Exact values come from master.dat if(game_state_get_player(obj->gs, 0)->har == obj) { rstate->pal_start_index = 1; rstate->pal_entry_count = 47; } else { rstate->pal_start_index = 48; rstate->pal_entry_count = 48; } } if(sd_script_isset(frame, "bpp")) { rstate->pal_end = sd_script_get(frame, "bpp") * 4; rstate->pal_begin = sd_script_get(frame, "bpp") * 4; } if(sd_script_isset(frame, "bpb")) { rstate->pal_begin = sd_script_get(frame, "bpb") * 4; } if(sd_script_isset(frame, "bz")) { rstate->pal_tint = 1; } // The following is a hack. We don't REALLY know what these tags do. // However, they are only used in CREDITS.BK, so we can just interpret // then as we see fit, as long as stuff works. if(sd_script_isset(frame, "bc") && frame->tick_len >= 50) { rstate->blend_start = 0; } else if(sd_script_isset(frame, "bd") && frame->tick_len >= 30) { rstate->blend_finish = 0; } // Handle movement if(sd_script_isset(frame, "ox")) { DEBUG("changing X from %f to %f", obj->pos.x, obj->pos.x+sd_script_get(frame, "ox")); /*obj->pos.x += sd_script_get(frame, "ox");*/ } if(sd_script_isset(frame, "oy")) { DEBUG("changing Y from %f to %f", obj->pos.y, obj->pos.y+sd_script_get(frame, "oy")); /*obj->pos.y += sd_script_get(frame, "oy");*/ } if (sd_script_isset(frame, "bm")) { // hack because we don't have 'walk to other HAR' implemented obj->pos.x = state->enemy->pos.x; obj->pos.y = state->enemy->pos.y; player_next_frame(state->enemy); } if (sd_script_isset(frame, "v")) { int x = 0, y = 0; if(sd_script_isset(frame, "y-")) { y = sd_script_get(frame, "y-") * -1; } else if(sd_script_isset(frame, "y+")) { y = sd_script_get(frame, "y+"); } if(sd_script_isset(frame, "x-")) { x = sd_script_get(frame, "x-") * -1 * object_get_direction(obj); } else if(sd_script_isset(frame, "x+")) { x = sd_script_get(frame, "x+") * object_get_direction(obj); } if (x || y) { DEBUG("x vel %d, y vel %d", x, y); obj->vel.x += x; obj->vel.y += y; } } if (sd_script_isset(frame, "bu") && obj->vel.y < 0.0f) { float x_dist = dist(obj->pos.x, 160); // assume that bu is used in conjunction with 'vy-X' and that we want to land in the center of the arena obj->slide_state.vel.x = x_dist / (obj->vel.y*-2); obj->slide_state.timer = obj->vel.y*-2; } // handle scaling on the Y axis if(sd_script_isset(frame, "y")) { obj->y_percent = sd_script_get(frame, "y") / 100.0f; } if (sd_script_isset(frame, "e")) { // x,y relative to *enemy's* position int x = 0, y = 0; if(sd_script_isset(frame, "y-")) { y = sd_script_get(frame, "y-") * -1; } else if(sd_script_isset(frame, "y+")) { y = sd_script_get(frame, "y+"); } if(sd_script_isset(frame, "x-")) { x = sd_script_get(frame, "x-") * -1 * object_get_direction(obj); } else if(sd_script_isset(frame, "x+")) { x = sd_script_get(frame, "x+") * object_get_direction(obj); } if (x || y) { obj->enemy_slide_state.timer = frame->tick_len; obj->enemy_slide_state.duration = 0; obj->enemy_slide_state.dest.x = x; obj->enemy_slide_state.dest.y = y; /*DEBUG("ENEMY Slide object %d for (x,y) = (%f,%f) for %d ticks. (%d,%d)", obj->cur_animation->id, obj->enemy_slide_state.dest.x, obj->enemy_slide_state.dest.y, param->duration, x, y);*/ } } if (sd_script_isset(frame, "v") == 0 && sd_script_isset(frame, "e") == 0 && (sd_script_isset(frame, "x+") || sd_script_isset(frame, "y+") || sd_script_isset(frame, "x-") || sd_script_isset(frame, "y-"))) { // check for relative X interleaving int x = 0, y = 0; if(sd_script_isset(frame, "y-")) { y = sd_script_get(frame, "y-") * -1; } else if(sd_script_isset(frame, "y+")) { y = sd_script_get(frame, "y+"); } if(sd_script_isset(frame, "x-")) { x = sd_script_get(frame, "x-") * -1 * object_get_direction(obj); } else if(sd_script_isset(frame, "x+")) { x = sd_script_get(frame, "x+") * object_get_direction(obj); } obj->slide_state.timer = frame->tick_len; obj->slide_state.vel.x = (float)x; obj->slide_state.vel.y = (float)y; /*DEBUG("Slide object %d for (x,y) = (%f,%f) for %d ticks.",*/ /*obj->cur_animation->id,*/ /*obj->slide_state.vel.x, */ /*obj->slide_state.vel.y, */ /*param->duration);*/ } if(sd_script_isset(frame, "x=") || sd_script_isset(frame, "y=")) { obj->slide_state.vel = vec2f_create(0,0); } if(sd_script_isset(frame, "x=")) { obj->pos.x = obj->start.x + (sd_script_get(frame, "x=") * object_get_direction(obj)); // Find frame ID by tick int frame_id = sd_script_next_frame_with_tag(&state->parser, "x=", state->current_tick); // Handle it! if(frame_id >= 0) { int mr = sd_script_get_tick_pos_at_frame(&state->parser, frame_id); int r = mr - state->current_tick; int next_x = sd_script_get(sd_script_get_frame(&state->parser, frame_id), "x="); int slide = obj->start.x + (next_x * object_get_direction(obj)); if(slide != obj->pos.x) { obj->slide_state.vel.x = dist(obj->pos.x, slide) / (float)(frame->tick_len + r); obj->slide_state.timer = frame->tick_len + r; /*DEBUG("Slide object %d for X = %f for a total of %d ticks.",*/ /*obj->cur_animation->id,*/ /*obj->slide_state.vel.x,*/ /*param->duration + r);*/ } } } if(sd_script_isset(frame, "y=")) { obj->pos.y = obj->start.y + sd_script_get(frame, "y="); // Find frame ID by tick int frame_id = sd_script_next_frame_with_tag(&state->parser, "y=", state->current_tick); // handle it! if(frame_id >= 0) { int mr = sd_script_get_tick_pos_at_frame(&state->parser, frame_id); int r = mr - state->current_tick; int next_y = sd_script_get(sd_script_get_frame(&state->parser, frame_id), "y="); int slide = next_y + obj->start.y; if(slide != obj->pos.y) { obj->slide_state.vel.y = dist(obj->pos.y, slide) / (float)(frame->tick_len + r); obj->slide_state.timer = frame->tick_len + r; /*DEBUG("Slide object %d for Y = %f for a total of %d ticks.",*/ /*obj->cur_animation->id,*/ /*obj->slide_state.vel.y,*/ /*param->duration + r);*/ } } } if(sd_script_isset(frame, "as")) { // make the object move around the screen in a circular motion until end of frame obj->orbit = 1; } else { obj->orbit = 0; } if(sd_script_isset(frame, "q")) { // Enable hit on the current and the next n-1 frames. obj->hit_frames = sd_script_get(frame, "q"); } if(obj->hit_frames > 0) { obj->can_hit = 1; obj->hit_frames--; } if(sd_script_isset(frame, "at")) { // set the object's X position to be behind the opponent obj->pos.x = obj->animation_state.enemy->pos.x + (15 * object_get_direction(obj)); } if(sd_script_isset(frame, "ar")) { DEBUG("flipping direction %d -> %d", object_get_direction(obj), object_get_direction(obj) *-1); // reverse direction object_set_direction(obj, object_get_direction(obj) * -1); DEBUG("flipping direction now %d", object_get_direction(obj)); } // Set render settings if(frame->sprite < 25) { object_select_sprite(obj, frame->sprite); if(obj->cur_sprite != NULL) { rstate->duration = frame->tick_len; rstate->blendmode = sd_script_isset(frame, "br") ? BLEND_ADDITIVE : BLEND_ALPHA; if(sd_script_isset(frame, "r")) { rstate->flipmode ^= FLIP_HORIZONTAL; } if(sd_script_isset(frame, "f")) { rstate->flipmode ^= FLIP_VERTICAL; } } } else { object_select_sprite(obj, -1); } } } // Animation ticks state->previous_tick = state->current_tick; if(state->reverse) { state->current_tick--; } else { state->current_tick++; } // Sprite ticks rstate->timer++; // All done. return; }
int melee_create(scene *scene) { char bitmap[51*36*4]; // Init local data melee_local *local = malloc(sizeof(melee_local)); memset(local, 0, sizeof(melee_local)); scene_set_userdata(scene, local); game_player *player1 = game_state_get_player(scene->gs, 0); game_player *player2 = game_state_get_player(scene->gs, 1); controller *player1_ctrl = game_player_get_ctrl(player1); controller *player2_ctrl = game_player_get_ctrl(player2); palette *mpal = video_get_base_palette(); palette_set_player_color(mpal, 0, 8, 0); palette_set_player_color(mpal, 0, 8, 1); palette_set_player_color(mpal, 0, 8, 2); video_force_pal_refresh(); memset(&bitmap, 255, 51*36*4); local->ticks = 0; local->pulsedir = 0; local->selection = 0; local->row_a = 0; local->column_a = 0; local->row_b = 0; local->column_b = 4; local->done_a = 0; local->done_b = 0; menu_background2_create(&local->feh, 90, 61); menu_background2_create(&local->bleh, 160, 43); surface_create_from_data(&local->select_hilight, SURFACE_TYPE_RGBA, 51, 36, bitmap); // set up the magic controller hooks if(player1_ctrl && player2_ctrl) { if(player1_ctrl->type == CTRL_TYPE_NETWORK) { controller_add_hook(player2_ctrl, player1_ctrl, player1_ctrl->controller_hook); } if (player2_ctrl->type == CTRL_TYPE_NETWORK) { controller_add_hook(player1_ctrl, player2_ctrl, player2_ctrl->controller_hook); } } animation *ani; sprite *spr; for(int i = 0; i < 10; i++) { ani = &bk_get_info(&scene->bk_data, 3)->ani; object_create(&local->pilots[i], scene->gs, vec2i_create(0,0), vec2f_create(0, 0)); object_set_animation(&local->pilots[i], ani); object_select_sprite(&local->pilots[i], i); ani = &bk_get_info(&scene->bk_data, 18+i)->ani; object_create(&local->har_player1[i], scene->gs, vec2i_create(110,95), vec2f_create(0, 0)); object_set_animation(&local->har_player1[i], ani); object_select_sprite(&local->har_player1[i], 0); object_set_repeat(&local->har_player1[i], 1); int row = i / 5; int col = i % 5; spr = sprite_copy(animation_get_sprite(&bk_get_info(&scene->bk_data, 1)->ani, 0)); mask_sprite(spr->data, 62*col, 42*row, 51, 36); ani = create_animation_from_single(spr, spr->pos); object_create(&local->harportraits_player1[i], scene->gs, vec2i_create(0, 0), vec2f_create(0, 0)); object_set_animation(&local->harportraits_player1[i], ani); object_select_sprite(&local->harportraits_player1[i], 0); object_set_animation_owner(&local->harportraits_player1[i], OWNER_OBJECT); if (player2->selectable) { spr = sprite_copy(animation_get_sprite(&bk_get_info(&scene->bk_data, 1)->ani, 0)); mask_sprite(spr->data, 62*col, 42*row, 51, 36); ani = create_animation_from_single(spr, spr->pos); object_create(&local->harportraits_player2[i], scene->gs, vec2i_create(0, 0), vec2f_create(0, 0)); object_set_animation(&local->harportraits_player2[i], ani); object_select_sprite(&local->harportraits_player2[i], 0); object_set_animation_owner(&local->harportraits_player2[i], OWNER_OBJECT); object_set_pal_offset(&local->harportraits_player2[i], 48); ani = &bk_get_info(&scene->bk_data, 18+i)->ani; object_create(&local->har_player2[i], scene->gs, vec2i_create(210,95), vec2f_create(0, 0)); object_set_animation(&local->har_player2[i], ani); object_select_sprite(&local->har_player2[i], 0); object_set_repeat(&local->har_player2[i], 1); object_set_direction(&local->har_player2[i], OBJECT_FACE_LEFT); object_set_pal_offset(&local->har_player2[i], 48); } } ani = &bk_get_info(&scene->bk_data, 4)->ani; object_create(&local->bigportrait1, scene->gs, vec2i_create(0,0), vec2f_create(0, 0)); object_set_animation(&local->bigportrait1, ani); object_select_sprite(&local->bigportrait1, 0); if (player2->selectable) { object_create(&local->bigportrait2, scene->gs, vec2i_create(320,0), vec2f_create(0, 0)); object_set_animation(&local->bigportrait2, ani); object_select_sprite(&local->bigportrait2, 4); object_set_direction(&local->bigportrait2, OBJECT_FACE_LEFT); } ani = &bk_get_info(&scene->bk_data, 5)->ani; object_create(&local->player2_placeholder, scene->gs, vec2i_create(0,0), vec2f_create(0, 0)); object_set_animation(&local->player2_placeholder, ani); if (player2->selectable) { object_select_sprite(&local->player2_placeholder, 0); } else { object_select_sprite(&local->player2_placeholder, 1); } spr = sprite_copy(animation_get_sprite(&bk_get_info(&scene->bk_data, 1)->ani, 0)); surface_convert_to_rgba(spr->data, video_get_pal_ref(), 0); ani = create_animation_from_single(spr, spr->pos); object_create(&local->unselected_har_portraits, scene->gs, vec2i_create(0,0), vec2f_create(0, 0)); object_set_animation(&local->unselected_har_portraits, ani); object_select_sprite(&local->unselected_har_portraits, 0); object_set_animation_owner(&local->unselected_har_portraits, OWNER_OBJECT); for(int i = 0; i < 2; i++) { local->bar_power[i] = progressbar_create(PROGRESSBAR_THEME_MELEE, PROGRESSBAR_LEFT, 50); local->bar_agility[i] = progressbar_create(PROGRESSBAR_THEME_MELEE, PROGRESSBAR_LEFT, 50); local->bar_endurance[i] = progressbar_create(PROGRESSBAR_THEME_MELEE, PROGRESSBAR_LEFT, 50); } component_layout(local->bar_power[0], 74, 12, 20*4, 8); component_layout(local->bar_agility[0], 74, 30, 20*4, 8); component_layout(local->bar_endurance[0], 74, 48, 20*4, 8); component_layout(local->bar_power[1], 320-66-local->feh.w, 12, 20*4, 8); component_layout(local->bar_agility[1], 320-66-local->feh.w, 30, 20*4, 8); component_layout(local->bar_endurance[1], 320-66-local->feh.w, 48, 20*4, 8); refresh_pilot_stats(local); // initialize nova selection cheat memset(local->har_selected, 0, sizeof(local->har_selected)); memset(local->katana_down_count, 0, sizeof(local->katana_down_count)); // Set callbacks scene_set_input_poll_cb(scene, melee_input_tick); scene_set_render_cb(scene, melee_render); scene_set_free_cb(scene, melee_free); scene_set_dynamic_tick_cb(scene, melee_tick); // Play correct music music_play(PSM_MENU); // Pick renderer video_select_renderer(VIDEO_RENDERER_HW); // All done return 0; }
void handle_action(scene *scene, int player, int action) { game_player *player1 = game_state_get_player(scene->gs, 0); game_player *player2 = game_state_get_player(scene->gs, 1); melee_local *local = scene_get_userdata(scene); int *row, *column, *done; if (player == 1) { row = &local->row_a; column = &local->column_a; done = &local->done_a; } else { row = &local->row_b; column = &local->column_b; done = &local->done_b; } if (*done) { return; } switch (action) { case ACT_LEFT: (*column)--; if (*column < 0) { *column = 4; } sound_play(19, 0.5f, 0.0f, 2.0f); break; case ACT_RIGHT: (*column)++; if (*column > 4) { *column = 0; } sound_play(19, 0.5f, 0.0f, 2.0f); break; case ACT_UP: if(*row == 1) { *row = 0; } sound_play(19, 0.5f, 0.0f, 2.0f); break; case ACT_DOWN: if(*row == 0) { *row = 1; } // nova selection cheat if(*row == 1 && *column == 0) { local->katana_down_count[player-1]++; if(local->katana_down_count[player-1] > 11) { local->katana_down_count[player-1] = 11; } } sound_play(19, 0.5f, 0.0f, 2.0f); break; case ACT_KICK: case ACT_PUNCH: *done = 1; sound_play(20, 0.5f, 0.0f, 2.0f); if (local->done_a && (local->done_b || !player2->selectable)) { local->done_a = 0; local->done_b = 0; if (local->selection == 0) { local->selection = 1; local->pilot_id_a = 5*local->row_a + local->column_a; local->pilot_id_b = 5*local->row_b + local->column_b; // nova selection cheat local->har_selected[0][local->pilot_id_a] = 1; local->har_selected[1][local->pilot_id_b] = 1; object_select_sprite(&local->bigportrait1, local->pilot_id_a); // update the player palette palette *base_pal = video_get_base_palette(); pilot p_a; pilot_get_info(&p_a, local->pilot_id_a); palette_set_player_color(base_pal, 0, p_a.colors[0], 2); palette_set_player_color(base_pal, 0, p_a.colors[1], 1); palette_set_player_color(base_pal, 0, p_a.colors[2], 0); video_force_pal_refresh(); player1->colors[0] = p_a.colors[0]; player1->colors[1] = p_a.colors[1]; player1->colors[2] = p_a.colors[2]; if (player2->selectable) { object_select_sprite(&local->bigportrait2, local->pilot_id_b); // update the player palette pilot_get_info(&p_a, local->pilot_id_b); palette_set_player_color(base_pal, 1, p_a.colors[0], 2); palette_set_player_color(base_pal, 1, p_a.colors[1], 1); palette_set_player_color(base_pal, 1, p_a.colors[2], 0); video_force_pal_refresh(); player2->colors[0] = p_a.colors[0]; player2->colors[1] = p_a.colors[1]; player2->colors[2] = p_a.colors[2]; } } else { int nova_activated[2] = {1, 1}; for(int i = 0;i < 2;i++) { for(int j = 0;j < 10;j++) { if(local->har_selected[i][j] == 0) { nova_activated[i] = 0; break; } } if(local->katana_down_count[i] < 11) { nova_activated[i] = 0; } } if(nova_activated[0] && local->row_a == 1 && local->column_a == 2) { player1->har_id = HAR_NOVA; } else { player1->har_id = 5*local->row_a+local->column_a; } player1->pilot_id = local->pilot_id_a; if (player2->selectable) { if(nova_activated[1] && local->row_b == 1 && local->column_b == 2) { player2->har_id = HAR_NOVA; } else { player2->har_id = 5*local->row_b+local->column_b; } player2->pilot_id = local->pilot_id_b; } else { if (player1->sp_wins == (2046 ^ (2 << player1->pilot_id))) { // everyone but kriessack player2->pilot_id = 10; player2->har_id = HAR_NOVA; } else { // pick an opponent we have not yet beaten while(1) { int i = rand_int(10); if ((2 << i) & player1->sp_wins || i == player1->pilot_id) { continue; } player2->pilot_id = i; player2->har_id = rand_int(10); break; } } pilot p_a; pilot_get_info(&p_a, player2->pilot_id); player2->colors[0] = p_a.colors[0]; player2->colors[1] = p_a.colors[1]; player2->colors[2] = p_a.colors[2]; } game_state_set_next(scene->gs, SCENE_VS); } } break; } if(local->selection == 0) { object_select_sprite(&local->bigportrait1, 5*local->row_a + local->column_a); if (player2->selectable) { object_select_sprite(&local->bigportrait2, 5*local->row_b + local->column_b); } } // nova selection cheat if(local->selection == 1) { local->har_selected[player-1][5 * (*row) + *column] = 1; } refresh_pilot_stats(local); }