void physicsactor_update(physicsactor_t *pa, const obstaclemap_t *obstaclemap) { int i; float dt = timer_get_delta(); const obstacle_t *at_U; /* getting hit & winning pose */ if(pa->state == PAS_GETTINGHIT) { input_ignore(pa->input); pa->facing_right = pa->xsp < 0.0f; } else if(pa->winning_pose) { /* brake on level clear */ const float thr = 60.0f; for(i=0; i<IB_MAX; i++) input_simulate_button_up(pa->input, (inputbutton_t)i); pa->gsp = clip(pa->gsp, -1.8f * pa->topspeed, 1.8f * pa->topspeed); if(pa->state == PAS_ROLLING) pa->state = PAS_BRAKING; if(pa->gsp > thr) input_simulate_button_down(pa->input, IB_LEFT); else if(pa->gsp < -thr) input_simulate_button_down(pa->input, IB_RIGHT); else input_ignore(pa->input); } else input_restore(pa->input); /* horizontal control lock timer */ if(pa->horizontal_control_lock_timer > 0.0f) { pa->horizontal_control_lock_timer = max(0.0f, pa->horizontal_control_lock_timer - dt); input_simulate_button_up(pa->input, IB_LEFT); input_simulate_button_up(pa->input, IB_RIGHT); pa->facing_right = pa->gsp > EPSILON; } /* don't bother jumping */ at_U = sensor_check(sensor_U(pa), pa->position, pa->movmode, obstaclemap); if(at_U != NULL && obstacle_is_solid(at_U)) input_simulate_button_up(pa->input, IB_FIRE1); /* face left/right */ if((pa->gsp > EPSILON || pa->in_the_air) && input_button_down(pa->input, IB_RIGHT)) pa->facing_right = TRUE; else if((pa->gsp < -EPSILON || pa->in_the_air) && input_button_down(pa->input, IB_LEFT)) pa->facing_right = FALSE; /* get to the real physics... */ run_simulation(pa, obstaclemap); /* reset input */ for(i=0; i<IB_MAX; i++) input_simulate_button_up(pa->input, (inputbutton_t)i); }
void bgstrategy_linear_update(bgstrategy_t *strategy) { bgstrategy_linear_t *me = (bgstrategy_linear_t*)strategy; background_t *bg = strategy->background; float dt = timer_get_delta(); bg->actor->position.x += me->speed_x * dt; bg->actor->position.y += me->speed_y * dt; }
void bgstrategy_circular_update(bgstrategy_t *strategy) { bgstrategy_circular_t *me = (bgstrategy_circular_t*)strategy; background_t *bg = strategy->background; float dt = timer_get_delta(); float t, sx, cy; t = (me->timer += dt); sx = sin(me->angularspeed_x * t + me->initialphase_x); cy = cos(me->angularspeed_y * t + me->initialphase_y); /* elliptical trajectory */ bg->actor->position.x += (-me->angularspeed_x * me->amplitude_x * sx) * dt; bg->actor->position.y += (me->angularspeed_y * me->amplitude_y * cy) * dt; }
/* * intro_update() * Updates the introduction scene */ void intro_update() { elapsed_time += timer_get_delta(); if(!fadefx_is_fading() && !must_fadein && (input_button_pressed(in, IB_FIRE3) || input_button_pressed(in, IB_FIRE4))) elapsed_time += INTRO_TIMEOUT; if(must_fadein) { fadefx_in(image_rgb(0,0,0), 1.0f); must_fadein = FALSE; } else if(elapsed_time >= INTRO_TIMEOUT) { if(fadefx_over()) { scenestack_pop(); load_intro_quest(); return; } fadefx_out(image_rgb(0,0,0), 1.0f); } if(music_is_playing()) music_stop(); }
void setup_timer( void ) { Huint data; Huint delta; Huint timer1; Huint timer2; Huint timer3; printf( "Setting up Timer\n" ); timer_set_delta( 0, 5 * DELTA ); delta = timer_get_delta( 0 ); timer_set_data( 0, 0xCAFEBABE ); data = timer_get_data( 0 ); timer_set_command( 0, HT_TIMER_CMD_PERIODIC | HT_TIMER_CMD_ENABLE | HT_TIMER_CMD_LOAD | HT_TIMER_CMD_RUN ); timer1 = timer_get_value( 0 ); timer2 = timer_get_value( 0 ); timer3 = timer_get_value( 0 ); printf( "Timer Delta: %u\n", delta ); printf( "Timer Data: %#08x\n", data ); printf( "Timer Value 1: %#08x\n", timer1 ); printf( "Timer Value 2: %#08x\n", timer2 ); printf( "Timer Value 3: %#08x\n", timer3 ); timer_set_delta( 0, DELTA ); timer_set_command( 0, HT_TIMER_CMD_PERIODIC | HT_TIMER_CMD_ENABLE | HT_TIMER_CMD_LOAD | HT_TIMER_CMD_RUN ); }
/* * player_update() * player를 업데이트하는 함수. */ void player_update(player_t *player, player_t **team, int team_size, brick_list_t *brick_list, item_list_t *item_list, enemy_list_t *enemy_list) { int i; actor_t *act = player->actor; float dt = timer_get_delta(); act->hot_spot = v2d_new(image_width(actor_image(act))/2, image_height(actor_image(act))-20); /* physics */ if(!player->disable_movement) { player->pa_old_state = physicsactor_get_state(player->pa); physics_adapter(player, team, team_size, brick_list, item_list, enemy_list); } /* player 깜빡거림 */ if(player->blinking) { player->blink_timer += timer_get_delta(); if(player->blink_timer - player->blink_visibility_timer >= 0.067f) { player->blink_visibility_timer = player->blink_timer; act->visible = !act->visible; } if(player->blink_timer >= PLAYER_MAX_BLINK) { player->blinking = FALSE; act->visible = TRUE; } } if(physicsactor_get_state(player->pa) != PAS_GETTINGHIT && player->pa_old_state == PAS_GETTINGHIT) { player->blinking = TRUE; player->blink_timer = 0.0f; player->blink_visibility_timer = 0.0f; } /* 방패 */ if(player->shield_type != SH_NONE) update_shield(player); /* 수중에서 */ if(!(player->underwater) && player->actor->position.y >= level_waterlevel()) player_enter_water(player); else if(player->underwater && player->actor->position.y < level_waterlevel()) player_leave_water(player); /* 수중인지 확인 */ if(player->underwater) { player->speedshoes_timer = max(player->speedshoes_timer, PLAYER_MAX_SPEEDSHOES); /* disable speed shoes */ if(player->shield_type != SH_WATERSHIELD) player->underwater_timer += dt; else player->underwater_timer = 0.0f; if(player_seconds_remaining_to_drown(player) <= 0.0f) player_drown(player); } /* 무적의 별 */ if(player->invincible) { int maxf = sprite_get_animation("SD_INVSTAR", 0)->frame_count; int invangle[PLAYER_MAX_INVSTAR]; v2d_t starpos; player->invtimer += dt; for(i=0; i<PLAYER_MAX_INVSTAR; i++) { invangle[i] = (180*4) * timer_get_ticks()*0.001 + (i+1)*(360/PLAYER_MAX_INVSTAR); starpos.x = 25*cos(invangle[i]*PI/180); starpos.y = ((timer_get_ticks()+i*400)%2000)/40; /*starpos = v2d_rotate(starpos, act->angle);*/ player->invstar[i]->position.x = act->position.x - act->hot_spot.x + image_width(actor_image(act))/2 + starpos.x; player->invstar[i]->position.y = act->position.y - act->hot_spot.y + image_height(actor_image(act)) - starpos.y + 5; actor_change_animation_frame(player->invstar[i], random(maxf)); } if(player->invtimer >= PLAYER_MAX_INVINCIBILITY) player->invincible = FALSE; } /* speed shoes */ if(player->got_speedshoes) { physicsactor_t *pa = player->pa; if(player->speedshoes_timer == 0) { physicsactor_set_acc(pa, physicsactor_get_acc(pa) * 2.0f); physicsactor_set_frc(pa, physicsactor_get_frc(pa) * 2.0f); physicsactor_set_topspeed(pa, physicsactor_get_topspeed(pa) * 2.0f); physicsactor_set_air(pa, physicsactor_get_air(pa) * 2.0f); physicsactor_set_rollfrc(pa, physicsactor_get_rollfrc(pa) * 2.0f); player->speedshoes_timer += dt; } else if(player->speedshoes_timer >= PLAYER_MAX_SPEEDSHOES) { physicsactor_set_acc(pa, physicsactor_get_acc(pa) / 2.0f); physicsactor_set_frc(pa, physicsactor_get_frc(pa) / 2.0f); physicsactor_set_topspeed(pa, physicsactor_get_topspeed(pa) / 2.0f); physicsactor_set_air(pa, physicsactor_get_air(pa) / 2.0f); physicsactor_set_rollfrc(pa, physicsactor_get_rollfrc(pa) / 2.0f); player->got_speedshoes = FALSE; } else player->speedshoes_timer += dt; } /* 애니메이션 */ update_animation(player); /* CPU가 제어하는 player인지 확인 */ if(player != level_player()) { for(i=0; i<IB_MAX; i++) input_simulate_button_up(act->input, (inputbutton_t)i); } /* 승리 포즈 */ if(level_has_been_cleared()) physicsactor_enable_winning_pose(player->pa); }
/* --------------------------------------- 文件处理回调 --------------------------------------- */ static bool_t hasher (void_t *param, sSEARCHa *info) { sHASH hash; /* 过滤掉两个生成的文件 */ if (str_cmpA(info->name, "__hash__.old") == 0 || str_cmpA(info->name, "__hash__.txt") == 0) return (TRUE); /* 显示文件名和大小字节数 */ printf("%s (%" CR_FSZ "u Bytes) ", info->name, info->size); /* 根据内存大小选择读取方式 */ timer_set_base(s_profile); if (info->size == 0) { /* 空文件 */ hash_init(&hash); hash_update(&hash, NULL, 0); hash_finish(param, info->size, info->name, &hash); } else if (info->size <= s_total) { sVFILE file; void_t *data; /* 内存映射 */ data = file_mappingA(info->name, &file); if (data == NULL) goto _read_it; hash_init(&hash); hash_update(&hash, data, (leng_t)info->size); hash_finish(param, info->size, info->name, &hash); file_release(&file); } else { fraw_t file; leng_t rest; fsize_t blks; _read_it: /* 分块读取 */ file = file_raw_openA(info->name, CR_FO_RO | CR_FO_SEQ); if (file == NULL) goto _failure; /* 文件很大, 只能分块读取 */ if (s_rdata == NULL) s_rdata = mem_malloc(FREAD_BLOCK); rest = ( leng_t)(info->size % FREAD_BLOCK); blks = (fsize_t)(info->size / FREAD_BLOCK); for (hash_init(&hash); blks != 0; blks--) { if (file_raw_read(s_rdata, FREAD_BLOCK, file) != FREAD_BLOCK) { file_raw_close(file); goto _failure; } hash_update(&hash, s_rdata, FREAD_BLOCK); } if (rest != 0) { if (file_raw_read(s_rdata, rest, file) != rest) { file_raw_close(file); goto _failure; } hash_update(&hash, s_rdata, rest); } hash_finish(param, info->size, info->name, &hash); file_raw_close(file); } fp32_t time; time = timer_get_delta(s_profile); time *= 1.024f; printf(" %.2f KB/S\n", info->size / time); return (TRUE); _failure: printf(" [FAILED]\n"); return (TRUE); }
/* physics simulation */ void run_simulation(physicsactor_t *pa, const obstaclemap_t *obstaclemap) { const float walk_threshold = 30.0f; const float wait_threshold = 5.0f; float dt = timer_get_delta(); const obstacle_t *at_A, *at_B, *at_C, *at_D, *at_M; int was_in_the_air; /* * * death * */ if(pa->state == PAS_DEAD || pa->state == PAS_DROWNED) { pa->ysp = min(pa->ysp + pa->grv * dt, pa->topyspeed); pa->position.y += pa->ysp * dt; pa->facing_right = TRUE; return; } UPDATE_SENSORS /* * * walking * */ if(!pa->in_the_air && pa->state != PAS_ROLLING) { /* acceleration */ if(input_button_down(pa->input, IB_RIGHT) && !input_button_down(pa->input, IB_LEFT) && pa->gsp >= 0.0f) { if(pa->gsp < pa->topspeed) { pa->gsp = min(pa->gsp + pa->acc * dt, pa->topspeed); if(!(pa->state == PAS_PUSHING && pa->facing_right)) pa->state = PAS_WALKING; } else pa->state = PAS_RUNNING; } if(input_button_down(pa->input, IB_LEFT) && !input_button_down(pa->input, IB_RIGHT) && pa->gsp <= 0.0f) { if(pa->gsp > -pa->topspeed) { pa->gsp = max(pa->gsp - pa->acc * dt, -pa->topspeed); if(!(pa->state == PAS_PUSHING && !pa->facing_right)) pa->state = PAS_WALKING; } else pa->state = PAS_RUNNING; } /* deceleration / braking */ if(input_button_down(pa->input, IB_RIGHT) && pa->gsp < 0.0f && (pa->angle % 0x40 == 0x0 || !pa->facing_right)) { pa->gsp += pa->dec * dt; if(fabs(pa->gsp) >= pa->brakingthreshold) pa->state = PAS_BRAKING; } if(input_button_down(pa->input, IB_LEFT) && pa->gsp > 0.0f && (pa->angle % 0x40 == 0x0 || pa->facing_right)) { pa->gsp -= pa->dec * dt; if(fabs(pa->gsp) >= pa->brakingthreshold) pa->state = PAS_BRAKING; } /* friction */ if(!input_button_down(pa->input, IB_LEFT) && !input_button_down(pa->input, IB_RIGHT)) { if(!(fabs(pa->gsp) < walk_threshold && pa->angle == 0x0)) pa->gsp -= min(fabs(pa->gsp), pa->frc) * sign(pa->gsp) * dt; else pa->gsp = 0.0f; } if(input_button_down(pa->input, IB_LEFT) && input_button_down(pa->input, IB_RIGHT) && fabs(pa->gsp) < pa->frc) pa->gsp = 0.0f; /* slope factor */ pa->gsp += pa->slp * -SIN(pa->angle) * dt; /* animation issues */ if(fabs(pa->gsp) < walk_threshold && pa->angle == 0x0) { if(pa->state != PAS_PUSHING && input_button_down(pa->input, IB_DOWN)) pa->state = PAS_DUCKING; else if(pa->state != PAS_PUSHING && input_button_down(pa->input, IB_UP)) pa->state = PAS_LOOKINGUP; else if(pa->state != PAS_PUSHING && (input_button_down(pa->input, IB_LEFT) || input_button_down(pa->input, IB_RIGHT))) pa->state = input_button_down(pa->input, IB_LEFT) && input_button_down(pa->input, IB_RIGHT) ? PAS_STOPPED : PAS_WALKING; else if((pa->state != PAS_PUSHING && pa->state != PAS_WAITING) || (pa->state == PAS_PUSHING && !input_button_down(pa->input, IB_LEFT) && !input_button_down(pa->input, IB_RIGHT))) pa->state = PAS_STOPPED; } else if(pa->state == PAS_STOPPED || pa->state == PAS_WAITING || pa->state == PAS_LEDGE || pa->state == PAS_WALKING || pa->state == PAS_RUNNING) pa->state = (fabs(pa->gsp) >= pa->topspeed) ? PAS_RUNNING : PAS_WALKING; else if(pa->state == PAS_PUSHING && fabs(pa->gsp) >= 3.0) pa->state = PAS_WALKING; } /* * * rolling * */ if(!pa->in_the_air && (pa->state == PAS_WALKING || pa->state == PAS_RUNNING)) { if(fabs(pa->gsp) > pa->rollthreshold && input_button_down(pa->input, IB_DOWN)) pa->state = PAS_ROLLING; } if(!pa->in_the_air && pa->state == PAS_ROLLING) { /* deceleration */ if(input_button_down(pa->input, IB_RIGHT) && pa->gsp < 0.0f) pa->gsp = min(0.0f, pa->gsp + pa->rolldec * dt); if(input_button_down(pa->input, IB_LEFT) && pa->gsp > 0.0f) pa->gsp = max(0.0f, pa->gsp - pa->rolldec * dt); /* friction */ pa->gsp -= min(fabs(pa->gsp), pa->rollfrc) * sign(pa->gsp) * dt; /* slope factor */ if(pa->gsp * SIN(pa->angle) >= 0.0f) pa->gsp += pa->rolluphillslp * -SIN(pa->angle) * dt; else pa->gsp += pa->rolldownhillslp * -SIN(pa->angle) * dt; /* unroll */ if(fabs(pa->gsp) < pa->unrollthreshold && pa->angle % 0x40 == 0x0) pa->state = PAS_WALKING; } /* * * moving horizontally * */ if(!pa->in_the_air) { /* you're way too fast... */ pa->gsp = clip(pa->gsp, -2.5f * pa->topspeed, 2.5f * pa->topspeed); /* speed */ pa->xsp = pa->gsp * COS(pa->angle); pa->ysp = pa->gsp * -SIN(pa->angle); /* BUGGED? falling off walls and ceilings */ if(fabs(pa->gsp) < pa->falloffthreshold*0.25f && pa->angle >= 0x40 && pa->angle <= 0xC0) { if(pa->movmode == MM_RIGHTWALL) pa->position.x += 5; else if(pa->movmode == MM_LEFTWALL) pa->position.x -= 4; /*pa->gsp = 0.0f;*/ pa->angle = 0x0; UPDATE_MOVMODE pa->horizontal_control_lock_timer = 0.5f; } } /* * * jumping and falling off * */ /* falling off */ if(pa->in_the_air) { /* air acceleration */ if(input_button_down(pa->input, IB_RIGHT) && !input_button_down(pa->input, IB_LEFT)) { if(pa->xsp < pa->topspeed) pa->xsp = min(pa->xsp + pa->air * dt, pa->topspeed); } if(input_button_down(pa->input, IB_LEFT) && !input_button_down(pa->input, IB_RIGHT)) { if(pa->xsp > -pa->topspeed) pa->xsp = max(pa->xsp - pa->air * dt, -pa->topspeed); } /* air drag */ if(pa->ysp < 0.0f && pa->ysp > pa->airdragcondition) { if(fabs(pa->xsp) >= pa->airdragthreshold) { float correction = pow(pa->airdragmultiplier, 60.0f * dt - 1.0f); pa->xsp *= pa->airdragmultiplier * correction; } } /* jump sensitivity */ if(pa->state == PAS_JUMPING) { if(!input_button_down(pa->input, IB_FIRE1) && pa->ysp < pa->jmprel) pa->ysp = pa->jmprel; } /* gravity */ if(pa->state != PAS_GETTINGHIT) pa->ysp = min(pa->ysp + pa->grv * dt, pa->topyspeed); else pa->ysp = min(pa->ysp + 0.1875f * (pa->grv / 0.21875f) * dt, pa->topyspeed); } else { /* jumping */ if(input_button_down(pa->input, IB_FIRE1) && !input_button_down(pa->input, IB_DOWN) && !input_button_down(pa->input, IB_UP)) { float grv_attenuation = (sign(pa->gsp * SIN(pa->angle)) < 0.0f) ? 1.0f : 0.5f; pa->xsp = pa->jmp * SIN(pa->angle) + pa->gsp * COS(pa->angle); pa->ysp = pa->jmp * COS(pa->angle) - pa->gsp * SIN(pa->angle) * grv_attenuation; pa->gsp = 0.0f; pa->angle = 0x0; UPDATE_MOVMODE pa->state = PAS_JUMPING; } } /* * * springing * */ if(pa->state == PAS_SPRINGING) { if(pa->in_the_air && pa->ysp > 0.0f) pa->state = PAS_WALKING; } /* * * breathing * */ if(pa->breathe_timer > 0.0f) { pa->breathe_timer -= dt; pa->state = PAS_BREATHING; } else if(pa->state == PAS_BREATHING && pa->in_the_air) pa->state = PAS_WALKING; /* * * moving and detecting collisions * */ /* moving */ was_in_the_air = pa->in_the_air; pa->position.x += pa->xsp * dt; pa->position.y += pa->ysp * dt; UPDATE_SENSORS /* pushing against the walls */ if(at_M != NULL) { if(pa->movmode == MM_FLOOR || pa->movmode == MM_CEILING) { /* floor and ceiling modes */ if(obstacle_get_position(at_M).x + obstacle_get_width(at_M)/2 > pa->position.x) { pa->position.x = obstacle_get_position(at_M).x - 11; pa->gsp = 0.0f; if(!pa->in_the_air) { pa->xsp = 0.0f; if(input_button_down(pa->input, IB_RIGHT)) { pa->state = PAS_PUSHING; pa->facing_right = TRUE; } else pa->state = PAS_STOPPED; } else pa->xsp = min(pa->xsp, 0.0f); UPDATE_SENSORS } else if(obstacle_get_position(at_M).x + obstacle_get_width(at_M)/2 < pa->position.x) { pa->position.x = obstacle_get_position(at_M).x + (obstacle_get_width(at_M) - 1) + 11; pa->gsp = 0.0f; if(!pa->in_the_air) { pa->xsp = 0.0f; if(input_button_down(pa->input, IB_LEFT)) { pa->state = PAS_PUSHING; pa->facing_right = FALSE; } else pa->state = PAS_STOPPED; } else pa->xsp = max(pa->xsp, 0.0f); UPDATE_SENSORS }