void start_replay(void *arg) { ReplayStage *rstg; StageInfo *gstg; int i; replay_copy(&global.replay, (Replay*)arg); global.replaymode = REPLAY_PLAY; if(global.replay.stgcount == 1) pickedstage = 0; init_player(&global.plr); for(i = pickedstage; i < global.replay.stgcount; ++i) { replay_select(&global.replay, i); rstg = global.replay.current; gstg = stage_get(rstg->stage); if(!gstg) { printf("start_replay(): Invalid stage %d in replay at %i skipped.\n", rstg->stage, i); continue; } gstg->loop(); if(global.game_over == GAMEOVER_ABORT) break; global.game_over = 0; } global.game_over = 0; global.replaymode = REPLAY_RECORD; replay_destroy(&global.replay); replayview->instantselect = False; }
void replay_copy(Replay *dst, Replay *src, bool steal_events) { int i; replay_destroy(dst); memcpy(dst, src, sizeof(Replay)); dst->playername = (char*)malloc(strlen(src->playername)+1); strcpy(dst->playername, src->playername); dst->stages = (ReplayStage*)malloc(sizeof(ReplayStage) * src->numstages); memcpy(dst->stages, src->stages, sizeof(ReplayStage) * src->numstages); for(i = 0; i < src->numstages; ++i) { ReplayStage *s, *d; s = src->stages + i; d = dst->stages + i; if(steal_events) { s->events = NULL; } else { d->capacity = s->numevents; d->events = (ReplayEvent*)malloc(sizeof(ReplayEvent) * d->capacity); memcpy(d->events, s->events, sizeof(ReplayEvent) * d->capacity); } } }
bool replay_load_syspath(Replay *rpy, const char *path, ReplayReadMode mode) { log_info("Loading %s (%s)", path, replay_mode_string(mode)); SDL_RWops *file; #ifndef __WINDOWS__ if(!strcmp(path, "-")) file = SDL_RWFromFP(stdin,false); else file = SDL_RWFromFile(path, "rb"); #else file = SDL_RWFromFile(path, "rb"); #endif if(!file) { log_warn("SDL_RWFromFile() failed: %s", SDL_GetError()); return false; } bool result = replay_read(rpy, file, mode, path); if(!result) { replay_destroy(rpy); } SDL_RWclose(file); return result; }
void continue_game(void *arg) { printf("The game is being continued...\n"); if(global.replaymode == REPLAY_RECORD) // actually... I'd be strange if REPLAY_PLAY ever got there replay_destroy(&global.replay); // 19:39:29 [@ laochailan] no. no fame for continue users >:D global.plr.lifes = PLR_START_LIVES; global.plr.continues += 1; global.plr.focus = 0; global.plr.fire = 0; delete_projectiles(&global.projs); delete_projectiles(&global.particles); }
void replay_play(Replay *rpy, int firstidx) { if(rpy != &global.replay) { replay_copy(&global.replay, rpy, true); } if(firstidx >= global.replay.numstages || firstidx < 0) { log_warn("No stage #%i in the replay", firstidx); return; } global.replaymode = REPLAY_PLAY; for(int i = firstidx; i < global.replay.numstages; ++i) { ReplayStage *rstg = global.replay_stage = global.replay.stages+i; StageInfo *gstg = stage_get(rstg->stage); if(!gstg) { log_warn("Invalid stage %x in replay at %i skipped.", rstg->stage, i); continue; } global.plr.mode = plrmode_find(rstg->plr_char, rstg->plr_shot); stage_loop(gstg); if(global.game_over == GAMEOVER_ABORT) { break; } if(global.game_over == GAMEOVER_RESTART) { --i; } global.game_over = 0; } global.game_over = 0; global.replaymode = REPLAY_RECORD; replay_destroy(&global.replay); global.replay_stage = NULL; free_resources(false); }
void replay_copy(Replay *dst, Replay *src) { int i; replay_destroy(dst); memcpy(dst, src, sizeof(Replay)); dst->playername = (char*)malloc(strlen(src->playername)+1); strcpy(dst->playername, src->playername); dst->stages = (ReplayStage*)malloc(sizeof(ReplayStage) * src->stgcount); memcpy(dst->stages, src->stages, sizeof(ReplayStage) * src->stgcount); for(i = 0; i < src->stgcount; ++i) { ReplayStage *s, *d; s = &(src->stages[i]); d = &(dst->stages[i]); d->capacity = s->ecount; d->events = (ReplayEvent*)malloc(sizeof(ReplayEvent) * d->capacity); memcpy(d->events, s->events, sizeof(ReplayEvent) * d->capacity); } }
bool replay_load(Replay *rpy, const char *name, ReplayReadMode mode) { char *p = replay_getpath(name, !strendswith(name, REPLAY_EXTENSION)); char *sp = vfs_repr(p, true); log_info("Loading %s (%s)", sp, replay_mode_string(mode)); SDL_RWops *file = vfs_open(p, VFS_MODE_READ); free(p); if(!file) { log_warn("VFS error: %s", vfs_get_error()); free(sp); return false; } bool result = replay_read(rpy, file, mode, sp); if(!result) { replay_destroy(rpy); } free(sp); SDL_RWclose(file); return result; }
static void replayview_freearg(void *a) { Replay *r = (Replay*)a; replay_destroy(r); free(r); }
int replay_read(Replay *rpy, FILE *file) { int readstate = RPY_H_MAGIC; int bufidx = 0, eidx = 0; char buf[REPLAY_READ_MAXSTRLEN], c; ReplayStage *s; int stgnum = 0; memset(rpy, 0, sizeof(Replay)); while((c = fgetc(file)) != EOF) { if(c == ':') { buf[bufidx] = 0; bufidx = 0; switch(readstate) { case RPY_H_MAGIC: { int magic = INTOF(buf); if(magic != REPLAY_MAGICNUMBER) { printf("replay_read(): invalid magic number: %d\n", magic); replay_destroy(rpy); return False; } break; } case RPY_H_META1: stralloc(&rpy->playername, buf); printf("replay_read(): replay META1 is: %s\n", buf); break; case RPY_H_META2: // skip break; case RPY_H_STAGECOUNT: rpy->stgcount = INTOF(buf); if(rpy->stgcount <= 0) { printf("replay_read(): insane stage count: %i\n", rpy->stgcount); replay_destroy(rpy); return False; } rpy->stages = (ReplayStage*)malloc(sizeof(ReplayStage) * rpy->stgcount); s = &(rpy->stages[0]); memset(s, 0, sizeof(ReplayStage)); break; case RPY_G_STAGE: s->stage = INTOF(buf); break; case RPY_G_SEED: s->seed = INTOF(buf); break; case RPY_G_DIFF: s->diff = INTOF(buf); break; case RPY_G_PTS: s->points = INTOF(buf); break; case RPY_P_CHAR: s->plr_char = INTOF(buf); break; case RPY_P_SHOT: s->plr_shot = INTOF(buf); break; case RPY_P_POSREAL: s->plr_pos = FLOATOF(buf); break; case RPY_P_POSIMAG: s->plr_pos += FLOATOF(buf) * I;break; case RPY_P_FOCUS: s->plr_focus = INTOF(buf); break; case RPY_P_FIRE: s->plr_fire = INTOF(buf); break; case RPY_P_POWER: s->plr_power = FLOATOF(buf); break; case RPY_P_LIFES: s->plr_lifes = INTOF(buf); break; case RPY_P_BOMBS: s->plr_bombs = INTOF(buf); break; case RPY_P_MFLAGS: s->plr_mflags = INTOF(buf); break; case RPY_E_COUNT: s->capacity = s->ecount = INTOF(buf); if(s->capacity <= 0) { printf("replay_read(): insane capacity in stage %i: %i\n", stgnum, s->capacity); replay_destroy(rpy); return False; } s->events = (ReplayEvent*)malloc(sizeof(ReplayEvent) * s->capacity); break; case RPY_E_FRAME: s->events[eidx].frame = INTOF(buf); break; case RPY_E_TYPE: s->events[eidx].type = INTOF(buf); break; case RPY_E_KEY: s->events[eidx].key = INTOF(buf); eidx++; if(eidx == s->capacity) { if((++stgnum) >= rpy->stgcount) return True; s = &(rpy->stages[stgnum]); readstate = RPY_G_STAGE; eidx = 0; continue; } break; } if(readstate == RPY_E_KEY) readstate = RPY_E_FRAME; else ++readstate; } else { buf[bufidx++] = c; if(bufidx >= REPLAY_READ_MAXSTRLEN) { printf("replay_read(): item is too long\n"); replay_destroy(rpy); return False; } } } printf("replay_read(): replay isn't properly terminated\n"); replay_destroy(rpy); return False; }