void Sound_setup(void) { printf("[sound] initializing sound\n"); Audio_Init(); Sound_loadFX(); Sound_setFxVolume(getSettingf("fxVolume")); Sound_reloadTrack(); Sound_setMusicVolume(getSettingf("musicVolume")); Audio_Start(); }
void drawHUD(Player *p, PlayerVisual *pV) { char temp[1024]; char pause_message[128]; float pause_color[3]; getPauseString(pause_message, pause_color); glDisable(GL_DEPTH_TEST); glDepthMask(GL_FALSE); rasonly(&pV->display); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); /* drawHud: parameters - Viewport Width - Viewport Height - Score (or -1 if disabled) - AI status ("computer player" or "") - Speed digital (absolute value) - Speed analog (1 for default speed, > 1 during acceleration) - Booster value (between 0 and 1) - fps - pause message - pause message r,g,b colors */ sprintf(temp, "drawHUD(%d, %d, %d, \"%s\", %f, %f, %f, %f, %d, \"%s\", %f, %f, %f)", pV->display.vp_w, pV->display.vp_h, gSettingsCache.show_scores ? p->data->score : -1, gSettingsCache.show_ai_status ? (p->ai->active ? "AI_COMPUTER" : "") : "", p->data->speed, p->data->speed / (2 * game2->rules.speed), p->data->booster / getSettingf("booster_max"), p->data->wall_buster / getSettingf("wall_buster_max"), getFPS(), pause_message, pause_color[0], pause_color[1], pause_color[2] ); glScalef(pV->display.vp_w / 1024.0f, pV->display.vp_w / 1024.0f, 1.0f); // fprintf(stderr, "%s\n", temp); scripting_Run(temp); glDisable(GL_BLEND); glDepthMask(GL_TRUE); glEnable(GL_DEPTH_TEST); }
void initData(void) { /* lasttime = SystemGetElapsedTime(); */ game->pauseflag = PAUSE_GAME_RUNNING; game2->rules.speed = getSettingf("speed"); game2->rules.eraseCrashed = getSettingi("erase_crashed"); game2->rules.grid_size = getSettingi("grid_size"); game2->grid.width = game2->rules.grid_size; game2->grid.height = game2->rules.grid_size; /* time management */ game2->time.lastFrame = 0; game2->time.current = 0; game2->time.offset = SystemGetElapsedTime(); /* TODO: fix that */ game2->players = game->players; /* event management */ game2->events.next = NULL; /* TODO: free any old events that might have gotten left */ resetVideoData(); resetPlayerData(); initWalls(); }
void video_LoadLevel(void) { printf("[status] load/reload video data\n"); if(gWorld) video_FreeLevel(gWorld); gWorld = video_CreateLevel(); if(gWorld->scalable) video_ScaleLevel(gWorld, getSettingf("grid_size")); }
void checkSettings(void) { /* sanity check: speed */ if(getSettingf("speed") <= 0) { fprintf(stderr, "[gltron] sanity check failed: speed = %.2ff\n", getSettingf("speed")); setSettingf("speed", 6.0); fprintf(stderr, "[gltron] reset speed: speed = %.2f\n", getSettingf("speed")); } #ifndef NEW_LEVEL if(getSettingi("grid_size") % 8) { fprintf(stderr, "[gltron] sanity check failed: grid_size %% 8 != 0: " "grid_size = %d\n", getSettingi("grid_size")); setSettingi("grid_size", 240); fprintf(stderr, "[gltron] reset grid_size: grid_size = %d\n", getSettingi("grid_size")); } #endif }
static float getReflectivity() { float reflectivity = getSettingf("reflection"); if(reflectivity < 0) reflectivity = getVideoSettingf("reflection"); // need stencil for reflections if(gSettingsCache.use_stencil == 0) reflectivity = 0; return reflectivity; }
int applyBooster(int player, int dt) { Data *data = game->player[player].data; if(data->booster > 0 && data->boost_enabled) { float boost = getSettingf("booster_use") * dt / 1000.0f; if(boost > data->booster) { boost = data->booster; data->boost_enabled = 0; } data->speed += boost; data->booster -= boost; return 1; } else { float booster_max = getSettingf("booster_max"); if(data->booster < booster_max) { data->booster += getSettingf("booster_regenerate") * dt / 1000.0f; if(data->booster > booster_max) data->booster = booster_max; } return 0; } }
void updateSettingsCache(void) { /* cache lua settings that don't change during play */ gSettingsCache.use_stencil = getSettingi("use_stencil"); gSettingsCache.show_scores = getSettingi("show_scores"); gSettingsCache.show_ai_status = getSettingi("show_ai_status"); gSettingsCache.ai_level = getSettingi("ai_level"); gSettingsCache.show_fps = getSettingi("show_fps"); gSettingsCache.show_console = getSettingi("show_console"); gSettingsCache.softwareRendering = getSettingi("softwareRendering"); gSettingsCache.line_spacing = getSettingi("line_spacing"); gSettingsCache.alpha_trails = getSettingi("alpha_trails"); gSettingsCache.antialias_lines = getSettingi("antialias_lines"); gSettingsCache.turn_cycle = getSettingi("turn_cycle"); gSettingsCache.light_cycles = getSettingi("light_cycles"); gSettingsCache.lod = getSettingi("lod"); gSettingsCache.fov = getSettingf("fov"); gSettingsCache.show_floor_texture = getVideoSettingi("show_floor_texture"); gSettingsCache.show_skybox = getVideoSettingi("show_skybox"); gSettingsCache.show_wall = getVideoSettingi("show_wall"); gSettingsCache.stretch_textures = getVideoSettingi("stretch_textures"); gSettingsCache.show_decals = getVideoSettingi("show_decals"); gSettingsCache.show_impact = getSettingi("show_impact"); gSettingsCache.show_glow = getSettingi("show_glow"); gSettingsCache.show_recognizer = getSettingi("show_recognizer"); gSettingsCache.fast_finish = getSettingi("fast_finish"); gSettingsCache.fov = getSettingf("fov"); gSettingsCache.znear = getSettingf("znear"); gSettingsCache.camType = getSettingi("camType"); gSettingsCache.playEffects = getSettingi("playEffects"); gSettingsCache.playMusic = getSettingi("playMusic"); gSettingsCache.map_ratio_w = getSettingf("map_ratio_w"); gSettingsCache.map_ratio_h = getSettingf("map_ratio_h"); scripting_GetGlobal("clear_color", NULL); scripting_GetFloatArrayResult(gSettingsCache.clear_color, 4); }
void initConfiguration(int argc, const char *argv[]) { /* load some more defaults from config file */ runScript(PATH_SCRIPTS, "config.lua"); runScript(PATH_SCRIPTS, "artpack.lua"); /* go for .gltronrc (or whatever is defined in RC_NAME) */ { char *path; path = getPossiblePath(PATH_PREFERENCES, RC_NAME); if (path != NULL) { if (fileExists(path)) { printf("[status] loading settings from %s\n", path); scripting_RunFile(path); } else { printf("[error] cannot load %s from %s\n", RC_NAME, path); } free(path); } else { printf("[fatal] can't get valid pref path for %s\n", RC_NAME); exit(1); // something is seriously wrong } } if(!isSetting("version") || getSettingf("version") < 0.70f) { /* load some more defaults from config file */ runScript(PATH_SCRIPTS, "config.lua"); runScript(PATH_SCRIPTS, "artpack.lua"); printf("[warning] old config file found, overriding using defaults\n"); } // check if config is valid scripting_GetGlobal("save_completed", NULL); if(scripting_IsNilResult()) { runScript(PATH_SCRIPTS, "config.lua"); runScript(PATH_SCRIPTS, "artpack.lua"); printf("[warning] defunct config file found, overriding using defaults\n"); } setSettingf("version", 0.70f); /* parse any comandline switches overrinding the loaded settings */ parse_args(argc, argv); /* sanity check some settings */ checkSettings(); /* intialize the settings cache, remember to do that everytime you change something */ updateSettingsCache(); }
void resetPlayerData(void) { int i; Data *data; AI *ai; int not_playing = 0; int *startIndex; startIndex = malloc( game->players * sizeof(int) ); randomPermutation(game->players, startIndex); for(i = 0; i < game->players; i++) { float startpos[][2] = { { 0.5, 0.25 }, { 0.75, 0.5 }, { 0.5, 0.75 }, { 0.25, 0.5 } }; float x, y; data = game->player[i].data; ai = game->player[i].ai; /* init ai */ switch(i) { case 0: ai->active = getSettingi("ai_player1"); break; case 1: ai->active = getSettingi("ai_player2"); break; case 2: ai->active = getSettingi("ai_player3"); break; case 3: ai->active = getSettingi("ai_player4"); break; default: fprintf(stderr, "[error] player index #%d not caught!\n", i); ai->active = AI_NONE; } ai->tdiff = 0; /* arrange players in circle around center */ /* randomize position on the grid */ x = startpos[ startIndex[i] ][0] * getSettingi("grid_size"); y = startpos[ startIndex[i] ][1] * getSettingi("grid_size"); /* randomize starting direction */ data->dir = trand() & 3; /* data->dir = startdir[i]; */ data->last_dir = data->dir; /* if player is playing... */ if(ai->active != AI_NONE) { data->speed = getSettingf("speed"); data->booster = getSettingf("booster_max"); data->boost_enabled = 0; data->trail_height = TRAIL_HEIGHT; } else { data->speed = SPEED_GONE; data->trail_height = 0; not_playing++; } // data->trail = data->trails; data->trailOffset = 0; data->trails[ data->trailOffset ].vStart.v[0] = x; data->trails[ data->trailOffset ].vStart.v[1] = y; data->trails[ data->trailOffset ].vDirection.v[0] = 0; data->trails[ data->trailOffset ].vDirection.v[1] = 0; { int camType; Camera *cam = game->player[i].camera; camType = (game->player[i].ai->active == AI_COMPUTER) ? CAM_CIRCLE : gSettingsCache.camType; initCamera(cam, data, camType); } } free(startIndex); game->running = game->players - not_playing; /* not everyone is alive */ /* printf("starting game with %d players\n", game->running); */ game->winner = -1; }
int c_update_audio_volume(lua_State *L) { Sound_setMusicVolume(getSettingf("musicVolume")); Sound_setFxVolume(getSettingf("fxVolume")); return 0; }
void keyGame(int state, int k, int x, int y) { int i; if(state == SYSTEM_KEYSTATE_DOWN) { switch (k) { /* case 'q': SystemExit(); return; */ case 27: game->pauseflag = PAUSE_GAME_SUSPENDED; nebu_System_ExitLoop(RETURN_GAME_ESCAPE); return; case ' ': game->pauseflag = PAUSE_GAME_SUSPENDED; nebu_System_ExitLoop(RETURN_GAME_PAUSE); return; case SYSTEM_KEY_F1: changeDisplay(0); return; case SYSTEM_KEY_F2: changeDisplay(1); return; case SYSTEM_KEY_F3: changeDisplay(2); return; case SYSTEM_KEY_F4: changeDisplay(3); return; // somehow, this breaks the 'keys' array, and saving // at the end of the game fails // case SYSTEM_KEY_F5: saveSettings(); return; case SYSTEM_KEY_F10: nextCameraType(); return; case SYSTEM_KEY_F11: doBmpScreenShot(gScreen); return; case SYSTEM_KEY_F12: doPngScreenShot(gScreen); return; case SYSTEM_KEY_F6: console_Seek(-1); return; case SYSTEM_KEY_F7: console_Seek(1); return; /* toggle lighting case SYSTEM_KEY_F6: setSettingi("light_cycles", !game->settings->light_cycles); return; */ } } for( i = 0; i < game->players; i++) { if(PLAYER_IS_ACTIVE(&game->player[i]) && !game->player[i].ai->active) { int key; if(state == SYSTEM_KEYSTATE_DOWN) { scripting_RunFormat("return settings.keys[%d].left", i + 1); scripting_GetIntegerResult( &key ); if(key == k) { createEvent(i, EVENT_TURN_LEFT); return; } scripting_RunFormat("return settings.keys[%d].right", i + 1); scripting_GetIntegerResult( &key ); if(key == k) { createEvent(i, EVENT_TURN_RIGHT); return; } } // deal with glance keys scripting_RunFormat("return settings.keys[%d].glance_left", i + 1); scripting_GetIntegerResult( &key ); if(key == k) { if(state == SYSTEM_KEYSTATE_DOWN) { // printf("glance left down\n"); game->player[i].camera->movement[CAM_PHI_OFFSET] = PI / 2.0f; } else { // printf("glance left up\n"); game->player[i].camera->movement[CAM_PHI_OFFSET] = 0; } return; } // deal with glance keys scripting_RunFormat("return settings.keys[%d].glance_right", i + 1); scripting_GetIntegerResult( &key ); if(key == k) { if(state == SYSTEM_KEYSTATE_DOWN) { // printf("glance right down\n"); game->player[i].camera->movement[CAM_PHI_OFFSET] = - PI / 2.0f; } else { // printf("glance right up\n"); game->player[i].camera->movement[CAM_PHI_OFFSET] = 0; } return; } // boost scripting_RunFormat("return settings.keys[%d].boost", i + 1); scripting_GetIntegerResult( &key ); if(key == k) { if(state == SYSTEM_KEYSTATE_DOWN) { // printf("boost down\n"); if(game->player[i].data->booster > getSettingf("booster_min")) game->player[i].data->boost_enabled = 1; } else { // printf("boost up\n"); game->player[i].data->boost_enabled = 0; } return; } // wallbuster scripting_RunFormat("return settings.keys[%d].bust", i + 1); scripting_GetIntegerResult( &key ); if(key == k) { if(state == SYSTEM_KEYSTATE_DOWN) { // printf("wall_buster down\n"); if(game->player[i].data->wall_buster > getSettingf("wall_buster_min")) game->player[i].data->wall_buster_enabled = 1; } else { // printf("wall_buster up\n"); game->player[i].data->wall_buster_enabled = 0; } return; } } } if(state == SYSTEM_KEYSTATE_DOWN) { displayMessage(TO_STDERR, "key '%s' (%d) is not bound", SystemGetKeyName(k), k); } }
void Input_Idle(void) { SystemSetJoyThreshold( getSettingf("joy_threshold") ); }
void Sound_play(void) { Audio_SetMusicVolume(getSettingf("musicVolume")); Audio_PlayMusic(); return; }
void Audio_Idle(void) { // iterate over all the players and update the engines if(sample_engine->IsPlaying()) { for(int i = 0; i < PLAYERS; i++) { Player *p; Sound::Source3D *p3d; float x, y; p3d = players[i]; p = game->player + i; getPositionFromIndex(&x, &y, i); p3d->_location = Vector3(x, y, 0); float V = p->data->speed; int dt = game2->time.current - p->data->turn_time; if(dt < TURN_LENGTH) { float t = (float)dt / TURNLENGTH; float vx = (1 - t) * dirsX[p->data->last_dir] + t * dirsX[p->data->dir]; float vy = (1 - t) * dirsY[p->data->last_dir] + t * dirsY[p->data->dir]; p3d->_velocity = Vector3(V * vx, V * vy, 0); } else { p3d->_velocity = Vector3(V * dirsX[p->data->dir], V * dirsY[p->data->dir], 0); } if(i == 0) { if(p->data->boost_enabled) { ( (Sound::SourceEngine*) p3d )->_speedShift = 1.2f; } else { ( (Sound::SourceEngine*) p3d )->_speedShift = 1.0f; } ( (Sound::SourceEngine*) p3d )->_pitchShift = p->data->speed / getSettingf("speed"); } #if 0 if(i == 0) { if( dt < TURNLENGTH ) { float t = (float)dt / TURNLENGTH; float speedShift = ( 1 - t ) * 0.4 + t * 0.3; float pitchShift = ( 1 - t ) * 0.9 + t * 1.0; ( (Sound::SourceEngine*) p3d )->_speedShift = speedShift; ( (Sound::SourceEngine*) p3d )->_pitchShift = pitchShift; } else { ( (Sound::SourceEngine*) p3d )->_speedShift = 0.3; ( (Sound::SourceEngine*) p3d )->_pitchShift = 1.0; } } #endif } } if(sample_recognizer->IsPlaying()) { if (gSettingsCache.show_recognizer) { vec2 p, v; getRecognizerPositionVelocity(&p, &v); // recognizerEngine->_location = Vector3(p.x, p.y, RECOGNIZER_HEIGHT); recognizerEngine->_location = Vector3(p.v[0], p.v[1], 10.0f); recognizerEngine->_velocity = Vector3(v.v[0], v.v[1], 0); } } if(music && !music->IsPlaying()) { // check if music is enabled. if it is, advance to // next song if(gSettingsCache.playMusic) { scripting_Run("nextTrack()"); } } Sound::Listener& listener = sound->GetListener(); listener._location = Vector3(game->player[0].camera->cam); Vector3 v1 = Vector3(game->player[0].camera->target); Vector3 v2 = Vector3(game->player[0].camera->cam); listener._direction = v1 - v2; // listener._location = players[0]->_location; // listener._direction = players[0]->_velocity; listener._velocity = players[0]->_velocity; listener._up = Vector3(0, 0, 1); sound->SetMixMusic(gSettingsCache.playMusic); sound->SetMixFX(gSettingsCache.playEffects); sound->Idle(); }
int applyWallAcceleration(int player, int dt) { // find distance to enemy walls left & right enum { eLeft, eRight, eMax }; segment2 segments[eMax]; Data *data = game->player[player].data; int dirLeft = (data->dir + 3) % 4; int dirRight = (data->dir + 1) % 4; float left, right; float x, y; vec2 vPos; int i, j; getPositionFromIndex(&x, &y, player); vPos.v[0] = x; vPos.v[1] = y; for(i = 0; i < eMax; i++) { vec2Copy(&segments[i].vStart, &vPos); } segments[eLeft].vDirection.v[0] = dirsX[dirLeft]; segments[eLeft].vDirection.v[1] = dirsY[dirLeft]; segments[eRight].vDirection.v[0] = dirsX[dirRight]; segments[eRight].vDirection.v[1] = dirsY[dirRight]; left = FLT_MAX; right = FLT_MAX; for(i = 0; i < game->players; i++) { segment2 *wall = game->player[i].data->trails; if(i == player) continue; if(game->player[i].data->trail_height < TRAIL_HEIGHT) continue; for(j = 0; j < game->player[i].data->trailOffset + 1; j++) { float t1, t2; vec2 v; if(segment2_Intersect(&v, &t1, &t2, segments + eLeft, wall) && t1 > 0 && t1 < left && t2 >= 0 && t2 <= 1) left = t1; if(segment2_Intersect(&v, &t1, &t2, segments + eRight, wall) && t1 > 0 && t1 < right && t2 >= 0 && t2 <= 1) right = t1; wall++; } } { float accell_limit = getSettingf("wall_accel_limit"); if(left < accell_limit || right < accell_limit) { float boost = getSettingf("wall_accel_use") * dt / 1000.0f; data->speed += boost; return 1; } else { return 0; } } }
List* doMovement(int mode, int dt) { int i; List *l = NULL; for(i = 0; i < game->players; i++) { Data *data = game->player[i].data; PlayerVisual *pV = gPlayerVisuals + i; if(data->speed > 0) { /* still alive */ float fs; float t; // speed boost: float deccel = 0; if(getSettingf("wall_accel_on") == 1) { if(!applyWallAcceleration(i, dt)) { deccel = getSettingf("wall_accel_decrease"); } else { deccel = -1; // forbid deacceleration for booster } } if(getSettingf("booster_on") == 1) { if(!applyBooster(i, dt) && deccel != -1) { float d = getSettingf("booster_decrease"); deccel = d > deccel ? d : deccel; } else { deccel = -1; } } if(deccel > 0) applyDecceleration(i, dt, deccel); // if(i == 0) // printf("speed: %.2f, boost: %.2f\n", data->speed, data->booster); fs = 1.0f - SPEED_OZ_FACTOR + SPEED_OZ_FACTOR * cosf(i * PI / 4.0f + (game2->time.current % SPEED_OZ_FREQ) * 2.0f * PI / SPEED_OZ_FREQ); t = dt / 100.0f * data->speed * fs; { segment2 *current = data->trails + data->trailOffset; segment2 movement; int crash = 0; float x, y; getPositionFromData(&x, &y, data); movement.vStart.v[0] = x; movement.vStart.v[1] = y; movement.vDirection.v[0] = t * dirsX[data->dir]; movement.vDirection.v[1] = t * dirsY[data->dir]; current->vDirection.v[0] += t * dirsX[data->dir]; current->vDirection.v[1] += t * dirsY[data->dir]; crash = crash || crashTestPlayers(i, &movement); crash = crash || crashTestWalls(i, &movement); } } else { /* already crashed */ if(game2->rules.eraseCrashed == 1 && data->trail_height > 0) data->trail_height -= (dt * TRAIL_HEIGHT) / 1000.0f; if(pV->exp_radius < EXP_RADIUS_MAX) pV->exp_radius += dt * EXP_RADIUS_DELTA; else if (data->speed == SPEED_CRASHED) { int winner = -1; data->speed = SPEED_GONE; game->running--; if(game->running <= 1) { /* all dead, find survivor */ int i, maxSpeed = SPEED_GONE; /* create winner event */ for(i = 0; i < game->players; i++) { if(game->player[i].data->speed >= maxSpeed) { winner = i; maxSpeed = game->player[i].data->speed; } } if(mode) { createEvent(winner, EVENT_STOP); /* a stop event is the last event that happens */ return l; } } } } } return l; }
int getSettingi(const char *name) { return (int) getSettingf(name); }
void playerCamera(Player *p, int player) { float dest[3]; float tdest[3]; float phi, chi, r; float x, y; int mouse_dx, mouse_dy; Camera *cam; Data *data; /* first, process all movement commands */ /* that means, check for mouse input mainly */ /* dt hack: the time since the last frame is not necessarily the game time, since the game maybe hasn't started yet, or was paused */ static int last=0; int dt; if(game2->time.dt == 0) { dt = nebu_Time_GetElapsed() - last; last = nebu_Time_GetElapsed(); } else { dt = game2->time.dt; } cam = &gPlayerVisuals[player].camera; data = p->data; getPositionFromData(&x, &y, data); if(game->pauseflag != PAUSE_GAME_RUNNING || !getSettingi("mouse_lock_ingame")) { if(cam->type.freedom[CAM_FREE_R]) { // mouse buttons let you zoom in/out if(gInput.mouse1 == 1) cam->movement[CAM_R] += (cam->movement[CAM_R]-CLAMP_R_MIN+1) * dt / 300.0f; if(gInput.mouse2 == 1) cam->movement[CAM_R] -= (cam->movement[CAM_R]-CLAMP_R_MIN+1) * dt / 300.0f; writeCamDefaults(cam, CAM_R); } nebu_Input_Mouse_GetDelta(&mouse_dx, &mouse_dy); if(cam->type.freedom[CAM_FREE_PHI] && mouse_dx != 0) { // mouse x axis lets you rotate horizontally int sign = getSettingi("mouse_invert_x") ? -1 : 1; cam->movement[CAM_PHI] += sign * (- mouse_dx) * MOUSE_CX; writeCamDefaults(cam, CAM_PHI); } if(cam->type.freedom[CAM_FREE_CHI] && mouse_dy != 0) { // mouse y axis lets you rotate vertically int sign = getSettingi("mouse_invert_y") ? -1 : 1; cam->movement[CAM_CHI] += sign * mouse_dy * MOUSE_CY; writeCamDefaults(cam, CAM_CHI); } /* done with mouse movement, now clamp the camera to legal values */ clampCam(cam); } phi = cam->movement[CAM_PHI] + cam->movement[CAM_PHI_OFFSET]; chi = cam->movement[CAM_CHI]; r = cam->movement[CAM_R]; /* if the cam is coupled to player movement, change the phi accordingly */ if(cam->type.coupled) { int time = game2->time.current - p->data->turn_time; if(time < TURN_LENGTH) { int dir, ldir; dir = p->data->dir; ldir = p->data->last_dir; if(dir == 1 && ldir == 2) dir = 4; if(dir == 2 && ldir == 1) ldir = 4; phi += ((TURN_LENGTH - time) * camAngles[ldir] + time * camAngles[dir]) / TURN_LENGTH; } else phi += camAngles[p->data->dir]; } /* position the camera */ dest[0] = x + r * cosf(phi) * sinf(chi); dest[1] = y + r * sinf(phi) * sinf(chi); dest[2] = r * cosf(chi); /* ok, now let's calculate the new camera destination coordinates */ /* also, perform some camera dependent movement */ switch(cam->type.type) { case CAM_TYPE_CIRCLING: /* Andi-cam */ cam->movement[CAM_PHI] += CAM_SPEED * game2->time.dt; tdest[0] = x; tdest[1] = y; tdest[2] = B_HEIGHT; break; case CAM_TYPE_FOLLOW: /* Mike-cam */ case CAM_TYPE_MOUSE: /* mouse camera */ tdest[0] = x; tdest[1] = y; tdest[2] = B_HEIGHT; break; case CAM_TYPE_COCKPIT: /* 1st person */ tdest[0] = x + 4.0f * dirsX[ p->data->dir ] + 2.0f * cosf(phi); tdest[1] = y + 4.0f * dirsY[ p->data->dir ] + 2.0f * sinf(phi); tdest[2] = CAM_COCKPIT_Z; dest[0] = x + 4.0f * dirsX[ p->data->dir ] + 0.1f * cosf(phi); dest[1] = y + 4.0f * dirsY[ p->data->dir ] + 0.1f * sinf(phi); dest[2] = CAM_COCKPIT_Z + 0.1f; break; case CAM_TYPE_OFFSET: /* AMR-cam */ { static float px[4]= { 0, 0, 0, 0 }; static float py[4] = { 0, 0, 0, 0 }; float dx,dy,tx,ty,gs,d; gs=getSettingf("grid_size"); tx=(x-gs/2)*(1+15/gs)+gs/2; /* Scale position of cycle */ ty=(y-gs/2)*(1+15/gs)+gs/2; dx=px[player]-tx; dy=py[player]-ty; d=1.3f * sqrtf(dx*dx+dy*dy); /* Find distance between old viewpoint and scaled cycle pos */ px[player] = dest[0] = tx + CAM_CIRCLE_DIST * dx/d; /* Set viewpoint a fixed distance from */ py[player] = dest[1] = ty + CAM_CIRCLE_DIST * dy/d; /* scaled pos, preserving angle */ dx=(tx-x)*(tx-x); /* find distance between scaled and actual */ dy=(ty-y)*(ty-y); /* cycle positions... */ d=sqrtf(dx*dx+dy*dy)/8.0f; dest[2] = CAM_CIRCLE_Z-(d*CAM_CIRCLE_Z)/24; /* ...and lift camera when close to cycle */ tdest[0] = x; tdest[1] = y; tdest[2] = B_HEIGHT; } break; } memcpy(cam->cam, dest, sizeof(cam->cam)); memcpy(cam->target, tdest, sizeof(cam->target)); }