/* * SCR_RunCinematic */ void SCR_RunCinematic( void ) { if( cls.state != CA_CINEMATIC ) { return; } if( ( cls.key_dest != key_game && cls.key_dest != key_console ) || (cls.key_dest == key_console && !SCR_AllowCinematicConsole()) ) { // stop if menu or console is up SCR_FinishCinematic(); return; } cl.cin.absPrevTime = cl.cin.absCurrentTime; cl.cin.absCurrentTime = SCR_CinematicTime(); if( cl.cin.paused ) { return; } cl.cin.currentTime += cl.cin.absCurrentTime - cl.cin.absPrevTime; if( !CIN_NeedNextFrame( cl.cin.h, cl.cin.currentTime ) ) { cl.cin.redraw = qfalse; return; } // read next frame SCR_ReadNextCinematicFrame(); if( !cl.cin.pic ) { // end of cinematic SCR_FinishCinematic(); return; } }
/* * SCR_RunCinematic */ void SCR_RunCinematic( void ) { if( cls.state != CA_CINEMATIC ) { return; } if( ( cls.key_dest != key_game && cls.key_dest != key_console ) || (cls.key_dest == key_console && !SCR_AllowCinematicConsole()) ) { // stop if menu or console is up SCR_FinishCinematic(); return; } if( cl.cin.pause_cnt > 0 ) { return; } // CIN_NeedNextFrame is going to query us for raw samples length CIN_AddRawSamplesListener( cl.cin.h, NULL, &SCR_CinematicRawSamples, &SCR_CinematicGetRawSamplesLength ); if( !CIN_NeedNextFrame( cl.cin.h, SCR_CinematicTime() - cl.cin.startTime ) ) { cl.cin.redraw = false; return; } // read next frame SCR_ReadNextCinematicFrame(); if( !cl.cin.pic ) { // end of cinematic SCR_FinishCinematic(); return; } }
/* * CL_GameModule_EscapeKey */ void CL_GameModule_EscapeKey( void ) { if( cge ) cge->EscapeKey(); else if( cls.state == CA_CINEMATIC ) SCR_FinishCinematic(); }
/* * SCR_PlayCinematic */ static void SCR_PlayCinematic( const char *arg, int flags ) { struct cinematics_s *cin; bool has_ogg; bool yuv; float framerate; size_t name_size = strlen( "video/" ) + strlen( arg ) + 1; char *name = alloca( name_size ); if( strstr( arg, "/" ) == NULL && strstr( arg, "\\" ) == NULL ) { Q_snprintfz( name, name_size, "video/%s", arg ); } else { Q_snprintfz( name, name_size, "%s", arg ); } cin = CIN_Open( name, 0, 0, &yuv, &framerate ); if( !cin ) { Com_Printf( "SCR_PlayCinematic: couldn't find %s\n", name ); return; } has_ogg = CIN_HasOggAudio( cin ); CIN_Close( cin ); SCR_FinishCinematic(); CL_SoundModule_StopAllSounds( true, true ); cin = CIN_Open( name, 0, has_ogg ? CIN_NOAUDIO : 0, &yuv, &framerate ); if( !cin ) { Com_Printf( "SCR_PlayCinematic: (FIXME) couldn't find %s\n", name ); return; } if( has_ogg ) { CL_SoundModule_StartBackgroundTrack( CIN_FileName( cin ), NULL, 4 ); } cl.cin.h = cin; cl.cin.keepRatio = (flags & 1) ? false : true; cl.cin.allowConsole = (flags & 2) ? false : true; cl.cin.startTime = SCR_CinematicTime(); cl.cin.paused = false; cl.cin.pause_cnt = 0; cl.cin.yuv = yuv; cl.cin.framerate = framerate; CL_SetClientState( CA_CINEMATIC ); SCR_EndLoadingPlaque(); SCR_RunCinematic(); }
void SCR_RunCinematic(void) { int frame; if (cl.cinematictime <= 0) { SCR_StopCinematic(); return; } if (cl.cinematicframe == -1) { return; /* static image */ } if (cls.key_dest != key_game) { /* pause if menu or console is up */ cl.cinematictime = cls.realtime - cl.cinematicframe * 1000 / 14; return; } frame = (cls.realtime - cl.cinematictime) * 14.0 / 1000; if (frame <= cl.cinematicframe) { return; } if (frame > cl.cinematicframe + 1) { Com_Printf("Dropped frame: %i > %i\n", frame, cl.cinematicframe + 1); cl.cinematictime = cls.realtime - cl.cinematicframe * 1000 / 14; } if (cin.pic) { Z_Free(cin.pic); } cin.pic = cin.pic_pending; cin.pic_pending = NULL; cin.pic_pending = SCR_ReadNextFrame(); if (!cin.pic_pending) { SCR_StopCinematic(); SCR_FinishCinematic(); cl.cinematictime = 1; /* the black screen behind loading */ SCR_BeginLoadingPlaque(); cl.cinematictime = 0; return; } }
/* * SCR_RunCinematic */ void SCR_RunCinematic( void ) { unsigned int realtime; unsigned int frame; cinematics_t *cin; if( !SCR_GetCinematicTime() ) return; if( cls.key_dest != key_game ) { // stop if menu or console is up SCR_FinishCinematic(); return; } cin = ( cinematics_t * )cl.cin; realtime = cls.realtime; if( realtime <= cin->time ) return; frame = ( realtime - cin->time ) * (float)( RoQ_FRAMERATE ) / 1000; if( frame <= cin->frame ) return; if( frame > cin->frame + 1 ) { Com_Printf( "Dropped frame: %i > %i\n", frame, cin->frame + 1 ); cin->time = realtime - cin->frame * 1000 / RoQ_FRAMERATE; } cin->pic = cin->pic_pending; cin->pic_pending = SCR_ReadNextCinematicFrame(); if( !cin->pic_pending ) { SCR_FinishCinematic(); return; } }
/* * CL_NewUserCommand */ void CL_NewUserCommand( int realmsec ) { usercmd_t *ucmd; if( !CL_NextUserCommandTimeReached( realmsec ) ) return; if( cls.state < CA_ACTIVE ) return; cl.cmdNum = cls.ucmdHead; ucmd = &cl.cmds[cl.cmdNum & CMD_MASK]; ucmd->serverTimeStamp = cl.serverTime; // return the time stamp to the server cl.cmd_time[cl.cmdNum & CMD_MASK] = cls.realtime; // control cinematics by buttons if( ucmd->buttons && SCR_GetCinematicTime() > 0 && cls.realtime > 1000 + SCR_GetCinematicTime() ) { // skip the rest of the cinematic SCR_FinishCinematic(); SCR_UpdateScreen(); } // snap push fracs so client and server version match ucmd->forwardfrac = ( (int)( UCMD_PUSHFRAC_SNAPSIZE * ucmd->forwardfrac ) ) / UCMD_PUSHFRAC_SNAPSIZE; ucmd->sidefrac = ( (int)( UCMD_PUSHFRAC_SNAPSIZE * ucmd->sidefrac ) ) / UCMD_PUSHFRAC_SNAPSIZE; ucmd->upfrac = ( (int)( UCMD_PUSHFRAC_SNAPSIZE * ucmd->upfrac ) ) / UCMD_PUSHFRAC_SNAPSIZE; if( cl.cmdNum > 0 ) ucmd->msec = ucmd->serverTimeStamp - cl.cmds[( cl.cmdNum-1 ) & CMD_MASK].serverTimeStamp; else ucmd->msec = 20; if( ucmd->msec < 1 ) ucmd->msec = 1; // advance head and init the new command cls.ucmdHead++; ucmd = &cl.cmds[cls.ucmdHead & CMD_MASK]; memset( ucmd, 0, sizeof( usercmd_t ) ); // start up with the most recent viewangles ucmd->angles[0] = ANGLE2SHORT( cl.viewangles[0] ); ucmd->angles[1] = ANGLE2SHORT( cl.viewangles[1] ); ucmd->angles[2] = ANGLE2SHORT( cl.viewangles[2] ); }
/* ================== SCR_PlayCinematic ================== */ void SCR_PlayCinematic (char *arg) { int width, height; byte *palette; char name[MAX_OSPATH], *dot; int old_khz; // make sure CD isn't playing music CDAudio_Stop(); cl.cinematicframe = 0; dot = strstr (arg, "."); if (dot && Q_streq(dot, ".pcx")) { // static pcx image Com_sprintf (name, sizeof(name), "pics/%s", arg); SCR_LoadPCX (name, &cin.pic, &palette, &cin.width, &cin.height); cl.cinematicframe = -1; cl.cinematictime = 1; SCR_EndLoadingPlaque(); cls.state = ca_active; cl_scores_setinuse_all(false); // jitscores - clear scoreboard if (!cin.pic) { Com_Printf ("%s not found.\n", name); cl.cinematictime = 0; } else { memcpy (cl.cinematicpalette, palette, sizeof(cl.cinematicpalette)); Z_Free (palette); } return; } Com_sprintf (name, sizeof(name), "video/%s", arg); FS_FOpenFile (name, &cl.cinematic_file); if (!cl.cinematic_file) { SCR_FinishCinematic(); cl.cinematictime = 0; // done return; } SCR_EndLoadingPlaque(); cls.state = ca_active; cl_scores_setinuse_all(false); // jitscores - clear scoreboard FS_Read (&width, 4, cl.cinematic_file); FS_Read (&height, 4, cl.cinematic_file); cin.width = LittleLong(width); cin.height = LittleLong(height); FS_Read (&cin.s_rate, 4, cl.cinematic_file); cin.s_rate = LittleLong(cin.s_rate); FS_Read (&cin.s_width, 4, cl.cinematic_file); cin.s_width = LittleLong(cin.s_width); FS_Read (&cin.s_channels, 4, cl.cinematic_file); cin.s_channels = LittleLong(cin.s_channels); Huff1TableInit (); // switch up to 22 khz sound if necessary old_khz = Cvar_VariableValue ("s_khz"); if (old_khz != cin.s_rate/1000) { cin.restart_sound = true; Cvar_SetValue ("s_khz", cin.s_rate/1000); CL_Snd_Restart_f (); Cvar_SetValue ("s_khz", old_khz); } cl.cinematicframe = 0; cin.pic = SCR_ReadNextFrame (); cl.cinematictime = Sys_Milliseconds (); }
void SCR_PlayCinematic(char *arg) { int width, height; byte *palette; char name[MAX_OSPATH], *dot; /* make sure background music is not playing */ #ifdef CDA CDAudio_Stop(); #endif #ifdef OGG OGG_Stop(); #endif cl.cinematicframe = 0; dot = strstr(arg, "."); /* static pcx image */ if (dot && !strcmp(dot, ".pcx")) { Com_sprintf(name, sizeof(name), "pics/%s", arg); SCR_LoadPCX(name, &cin.pic, &palette, &cin.width, &cin.height); cl.cinematicframe = -1; cl.cinematictime = 1; SCR_EndLoadingPlaque(); cls.state = ca_active; if (!cin.pic) { Com_Printf("%s not found.\n", name); cl.cinematictime = 0; } else { memcpy(cl.cinematicpalette, palette, sizeof(cl.cinematicpalette)); Z_Free(palette); } return; } Com_sprintf(name, sizeof(name), "video/%s", arg); FS_FOpenFile(name, &cl.cinematic_file, false); if (!cl.cinematic_file) { SCR_FinishCinematic(); cl.cinematictime = 0; /* done */ return; } SCR_EndLoadingPlaque(); cls.state = ca_active; FS_Read(&width, 4, cl.cinematic_file); FS_Read(&height, 4, cl.cinematic_file); cin.width = LittleLong(width); cin.height = LittleLong(height); FS_Read(&cin.s_rate, 4, cl.cinematic_file); cin.s_rate = LittleLong(cin.s_rate); FS_Read(&cin.s_width, 4, cl.cinematic_file); cin.s_width = LittleLong(cin.s_width); FS_Read(&cin.s_channels, 4, cl.cinematic_file); cin.s_channels = LittleLong(cin.s_channels); Huff1TableInit(); cl.cinematicframe = 0; cin.pic = SCR_ReadNextFrame(); cl.cinematictime = Sys_Milliseconds(); }
/* ================= CL_SendCmd ================= */ void CL_SendCmd (void) { sizebuf_t buf; byte data[128]; int i; usercmd_t *cmd, *oldcmd; usercmd_t nullcmd; int checksumIndex; // build a command even if not connected // save this command off for prediction i = cls.netchan.outgoing_sequence & (CMD_BACKUP-1); cmd = &cl.cmds[i]; cl.cmd_time[i] = cls.realtime; // for netgraph ping calculation *cmd = CL_CreateCmd (); cl.cmd = *cmd; if (cls.state == ca_disconnected || cls.state == ca_connecting) return; if ( cls.state == ca_connected) { if (cls.netchan.message.cursize || curtime - cls.netchan.last_sent > 1000 ) // >>> FIX: For Nintendo Wii using devkitPPC / libogc // Though, technically, not a bug, the compiler complained about buf.data not being // initialized; switching to "data" instead: //Netchan_Transmit (&cls.netchan, 0, buf.data); Netchan_Transmit (&cls.netchan, 0, data); // <<< FIX return; } // send a userinfo update if needed if (userinfo_modified) { CL_FixUpGender(); userinfo_modified = false; MSG_WriteByte (&cls.netchan.message, clc_userinfo); MSG_WriteString (&cls.netchan.message, Cvar_Userinfo() ); } SZ_Init (&buf, data, sizeof(data)); if (cmd->buttons && cl.cinematictime > 0 && !cl.attractloop && cls.realtime - cl.cinematictime > 1000) { // skip the rest of the cinematic SCR_FinishCinematic (); } // begin a client move command MSG_WriteByte (&buf, clc_move); // save the position for a checksum byte checksumIndex = buf.cursize; MSG_WriteByte (&buf, 0); // let the server know what the last frame we // got was, so the next message can be delta compressed if (cl_nodelta->value || !cl.frame.valid || cls.demowaiting) MSG_WriteLong (&buf, -1); // no compression else MSG_WriteLong (&buf, cl.frame.serverframe); // send this and the previous cmds in the message, so // if the last packet was dropped, it can be recovered i = (cls.netchan.outgoing_sequence-2) & (CMD_BACKUP-1); cmd = &cl.cmds[i]; memset (&nullcmd, 0, sizeof(nullcmd)); MSG_WriteDeltaUsercmd (&buf, &nullcmd, cmd); oldcmd = cmd; i = (cls.netchan.outgoing_sequence-1) & (CMD_BACKUP-1); cmd = &cl.cmds[i]; MSG_WriteDeltaUsercmd (&buf, oldcmd, cmd); oldcmd = cmd; i = (cls.netchan.outgoing_sequence) & (CMD_BACKUP-1); cmd = &cl.cmds[i]; MSG_WriteDeltaUsercmd (&buf, oldcmd, cmd); // calculate a checksum over the move commands buf.data[checksumIndex] = COM_BlockSequenceCRCByte( buf.data + checksumIndex + 1, buf.cursize - checksumIndex - 1, cls.netchan.outgoing_sequence); // // deliver the message // Netchan_Transmit (&cls.netchan, buf.cursize, buf.data); }
void CL_SendCmd(void) { sizebuf_t buf; byte data[128]; int i; usercmd_t *cmd, *oldcmd; usercmd_t nullcmd; int checksumIndex; /* build a command even if not connected */ /* save this command off for prediction */ i = cls.netchan.outgoing_sequence & (CMD_BACKUP - 1); cmd = &cl.cmds[i]; cl.cmd_time[i] = cls.realtime; /* for netgraph ping calculation */ *cmd = CL_CreateCmd(); cl.cmd = *cmd; if ((cls.state == ca_disconnected) || (cls.state == ca_connecting)) { return; } if (cls.state == ca_connected) { if (cls.netchan.message.cursize || (curtime - cls.netchan.last_sent > 100)) { Netchan_Transmit(&cls.netchan, 0, buf.data); } return; } /* send a userinfo update if needed */ if (userinfo_modified) { CL_FixUpGender(); userinfo_modified = false; MSG_WriteByte(&cls.netchan.message, clc_userinfo); MSG_WriteString(&cls.netchan.message, Cvar_Userinfo()); } SZ_Init(&buf, data, sizeof(data)); if (cmd->buttons && (cl.cinematictime > 0) && !cl.attractloop && (cls.realtime - cl.cinematictime > 1000)) { /* skip the rest of the cinematic */ SCR_FinishCinematic(); } /* begin a client move command */ MSG_WriteByte(&buf, clc_move); /* save the position for a checksum byte */ checksumIndex = buf.cursize; MSG_WriteByte(&buf, 0); /* let the server know what the last frame we got was, so the next message can be delta compressed */ if (cl_nodelta->value || !cl.frame.valid || cls.demowaiting) { MSG_WriteLong(&buf, -1); /* no compression */ } else { MSG_WriteLong(&buf, cl.frame.serverframe); } /* send this and the previous cmds in the message, so if the last packet was dropped, it can be recovered */ i = (cls.netchan.outgoing_sequence - 2) & (CMD_BACKUP - 1); cmd = &cl.cmds[i]; memset(&nullcmd, 0, sizeof(nullcmd)); MSG_WriteDeltaUsercmd(&buf, &nullcmd, cmd); oldcmd = cmd; i = (cls.netchan.outgoing_sequence - 1) & (CMD_BACKUP - 1); cmd = &cl.cmds[i]; MSG_WriteDeltaUsercmd(&buf, oldcmd, cmd); oldcmd = cmd; i = (cls.netchan.outgoing_sequence) & (CMD_BACKUP - 1); cmd = &cl.cmds[i]; MSG_WriteDeltaUsercmd(&buf, oldcmd, cmd); /* calculate a checksum over the move commands */ buf.data[checksumIndex] = COM_BlockSequenceCRCByte( buf.data + checksumIndex + 1, buf.cursize - checksumIndex - 1, cls.netchan.outgoing_sequence); /* deliver the message */ Netchan_Transmit(&cls.netchan, buf.cursize, buf.data); }
/* ================== SCR_PlayCinematic ================== */ void SCR_PlayCinematic (char *arg) { int32_t width, height; byte *palette; char name[MAX_OSPATH], *dot; int32_t old_khz; cin.isStaticPic = false; // Knightmare added cl.cinematicframe = 0; dot = strstr (arg, "."); if (dot && !strcmp (dot, ".pcx")) { // static pcx image Com_sprintf (name, sizeof(name), "pics/%s", arg); SCR_LoadPCX (name, &cin.pic, &palette, &cin.width, &cin.height); cl.cinematicframe = -1; cl.cinematictime = 1; SCR_EndLoadingPlaque (); cls.state = ca_active; if (!cin.pic) { Com_Printf ("%s not found.\n", name); cl.cinematictime = 0; } else { memcpy (cl.cinematicpalette, palette, sizeof(cl.cinematicpalette)); Z_Free (palette); // Knightmare- HACK to show JPG endscreens cin.isStaticPic = true; Com_sprintf (cin.picName, sizeof(cin.picName), "/pics/%s", arg); } return; } Com_sprintf (name, sizeof(name), "video/%s", arg); FS_FOpenFile (name, &cl.cinematic_file, FS_READ); if (!cl.cinematic_file) { //Com_Error (ERR_DROP, "Cinematic %s not found.\n", name); //Com_Printf (S_COLOR_YELLOW"Cinematic %s not found.\n", name); SCR_FinishCinematic (); cl.cinematictime = 0; // done return; } SCR_EndLoadingPlaque (); cls.state = ca_active; FS_Read (&width, 4, cl.cinematic_file); FS_Read (&height, 4, cl.cinematic_file); cin.width = LittleLong(width); cin.height = LittleLong(height); FS_Read (&cin.s_rate, 4, cl.cinematic_file); cin.s_rate = LittleLong(cin.s_rate); FS_Read (&cin.s_width, 4, cl.cinematic_file); cin.s_width = LittleLong(cin.s_width); FS_Read (&cin.s_channels, 4, cl.cinematic_file); cin.s_channels = LittleLong(cin.s_channels); Huff1TableInit (); // switch up to 22 khz sound if necessary old_khz = Cvar_VariableValue ("s_khz"); if (old_khz < cin.s_rate/1000) // Knighmare- changed != to < { cin.restart_sound = true; Cvar_SetValue ("s_khz", cin.s_rate/1000); CL_Snd_Restart_f (); Cvar_SetValue ("s_khz", old_khz); } cl.cinematicframe = 0; cin.pic = SCR_ReadNextFrame (); cl.cinematictime = Sys_Milliseconds (); }