⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cl_cin.pas

📁 雷神之锤2(Quake2)Delphi源码
💻 PAS
📖 第 1 页 / 共 2 页
字号:
      hnodes := Pointer(Cardinal(hnodesbase) + SizeOf(PInteger) * (nodenum shl 9));
      out_p^ := Byte(nodenum);
      Inc(out_p);
      Dec(Count);
      if (count = 0) then
        break;
      nodenum := cin.numhnodes1[nodenum];
    end;
    nodenum := hnodes[nodenum * 2 + (inbyte and 1)];
    inbyte := inbyte shr 1;
    //-----------
    if (nodenum < 256) then
    begin
      hnodes := Pointer(Cardinal(hnodesbase) + SizeOf(PInteger) * (nodenum shl 9));
      out_p^ := Byte(nodenum);
      Inc(out_p);
      Dec(Count);
      if (count = 0) then
        break;
      nodenum := cin.numhnodes1[nodenum];
    end;
    nodenum := hnodes[nodenum * 2 + (inbyte and 1)];
    inbyte := inbyte shr 1;
    //-----------
    if (nodenum < 256) then
    begin
      hnodes := Pointer(cardinal(hnodesbase) + SizeOf(PInteger) * (nodenum shl 9));
      out_p^ := Byte(nodenum);
      Inc(out_p);
      Dec(Count);
      if (count = 0) then
        break;
      nodenum := cin.numhnodes1[nodenum];
    end;
    nodenum := hnodes[nodenum * 2 + (inbyte and 1)];
    inbyte := inbyte shr 1;
    //-----------
    if (nodenum < 256) then
    begin
      hnodes := Pointer(Cardinal(hnodesbase) + SizeOf(PInteger) * (nodenum shl 9));
      out_p^ := Byte(nodenum);
      Inc(out_p);
      Dec(Count);
      if (count = 0) then
        break;
      nodenum := cin.numhnodes1[nodenum];
    end;
    nodenum := hnodes[nodenum * 2 + (inbyte and 1)];
    inbyte := inbyte shr 1;
    //-----------
    if (nodenum < 256) then
    begin
      hnodes := Pointer(Cardinal(hnodesbase) + SizeOf(PInteger) * (nodenum shl 9));
      out_p^ := Byte(nodenum);
      Inc(out_p);
      Dec(Count);
      if (count = 0) then
        break;
      nodenum := cin.numhnodes1[nodenum];
    end;
    nodenum := hnodes[nodenum * 2 + (inbyte and 1)];
    inbyte := inbyte shr 1;
    //-----------
    if (nodenum < 256) then
    begin
      hnodes := Pointer(Cardinal(hnodesbase) + SizeOf(PInteger) * (nodenum shl 9));
      out_p^ := Byte(nodenum);
      Inc(out_p);
      Dec(Count);
      if (count = 0) then
        break;
      nodenum := cin.numhnodes1[nodenum];
    end;
    nodenum := hnodes[nodenum * 2 + (inbyte and 1)];
    inbyte := inbyte shr 1;
    //-----------
    if (nodenum < 256) then
    begin
      hnodes := Pointer(Cardinal(hnodesbase) + SizeOf(PInteger) * (nodenum shl 9));
      out_p^ := Byte(nodenum);
      Inc(out_p);
      Dec(Count);
      if (count = 0) then
        break;
      nodenum := cin.numhnodes1[nodenum];
    end;
    nodenum := hnodes[nodenum * 2 + (inbyte and 1)];
    inbyte := inbyte shr 1;
    //-----------
    if (nodenum < 256) then
    begin
      hnodes := Pointer(Cardinal(hnodesbase) + SizeOf(PInteger) * (nodenum shl 9));
      out_p^ := Byte(nodenum);
      Inc(out_p);
      Dec(Count);
      if (count = 0) then
        break;
      nodenum := cin.numhnodes1[nodenum];
    end;
    nodenum := hnodes[nodenum * 2 + (inbyte and 1)];
    inbyte := inbyte shr 1;
  end;

  if (Cardinal(input) - Cardinal(_in.data) <> _in.count) and
    (Cardinal(input) - Cardinal(_in.data) <> _in.count + 1) then
  begin
    Com_Printf('Decompression overread by %d', [(Cardinal(input) - cardinal(_in.data)) - _in.count]);
  end;
  _out.count := Cardinal(out_p) - Cardinal(_out.data);

  Result := _out;
end;

{
==================
SCR_ReadNextFrame
==================
}

function SCR_ReadNextFrame: PByte;
var
  r: integer;
  command: integer;
  samples: array[0..(22050 div 14 * 4) - 1] of byte;
  compressed: array[0..$20000 - 1] of byte;
  size: integer;
  pic: pbyte;
  _in, huf1: cblock_t;
  start, _end, count: integer;
begin
  Result := nil;

  // read the next frame
  r := FileRead(cl.cinematic_file, command, 4);
  if (r = 0) then // we'll give it one more chance
    r := FileRead(cl.cinematic_file, command, 4);

  // Juha 7-Jul-2002: This really should test result against 4. Original C
  // code tests it agains 1, which means that it has read one 4-byte block,
  // but in delphi we test that we have read 4 bytes. (!)
  if (r <> 4) then
    Exit;
  command := LittleLong(command);
  if (command = 2) then
    Exit;   // last frame marker

  if (command = 1) then
  begin
    // read palette
    FS_Read(@cl.cinematicpalette, sizeof(cl.cinematicpalette), cl.cinematic_file);
    cl.cinematicpalette_active := False; // dubious....  exposes an edge case
  end;

  // decompress the next frame
  FS_Read(@size, 4, cl.cinematic_file);
  size := LittleLong(size);
  if (size > sizeof(compressed)) or (size < 1) then
    Com_Error(ERR_DROP, 'Bad compressed frame size', []);
  FS_Read(@compressed, size, cl.cinematic_file);

  // read sound
  start := cl.cinematicframe * cin.s_rate div 14;
  _end := (cl.cinematicframe + 1) * cin.s_rate div 14;
  count := _end - start;

  FS_Read(@samples, count * cin.s_width * cin.s_channels, cl.cinematic_file);

  S_RawSamples(count, cin.s_rate, cin.s_width, cin.s_channels, @samples);

  _in.data := @compressed;
  _in.count := size;

  huf1 := Huff1Decompress(_in);

  pic := PByte(huf1.data);

  cl.cinematicframe := cl.cinematicframe + 1;

  result := pic;
end;

{
==================
SCR_RunCinematic

==================
}

procedure SCR_RunCinematic;
var
  frame: integer;
begin

  if (cl.cinematictime <= 0) then
  begin
    SCR_StopCinematic();
    exit;
  end;

  if (cl.cinematicframe = -1) then
    exit; // static image

  if (cls.key_dest <> key_game) then
  begin
    // pause if menu or console is up
    cl.cinematictime := cls.realtime - cl.cinematicframe * 1000 div 14;
    exit;
  end;

  frame := round((cls.realtime - cl.cinematictime) * 14.0 / 1000);
  if (frame <= cl.cinematicframe) then
    exit;
  if (frame > cl.cinematicframe + 1) then
  begin
    Com_Printf('Dropped frame: %d > %d'#10, [frame, cl.cinematicframe + 1]);
    cl.cinematictime := Round(cls.realtime - cl.cinematicframe * 1000 / 14);
  end;
  if (cin.pic <> nil) then
    Z_Free(cin.pic);
  cin.pic := cin.pic_pending;
  cin.pic_pending := nil;
  cin.pic_pending := SCR_ReadNextFrame();
  if (cin.pic_pending = nil) then
  begin
    SCR_StopCinematic();
    SCR_FinishCinematic();
    cl.cinematictime := 1; // hack to get the black screen behind loading
    SCR_BeginLoadingPlaque();
    cl.cinematictime := 0;
    exit;
  end;
end;

{
==================
SCR_DrawCinematic

Returns true if a cinematic is active, meaning the view rendering
should be skipped
==================
}

function SCR_DrawCinematic: qboolean;
begin
  if (cl.cinematictime <= 0) then
  begin
    result := false;
    exit;
  end;

  if (cls.key_dest = key_menu) then
  begin
    // blank screen and pause if menu is up
    re.CinematicSetPalette(nil);
    cl.cinematicpalette_active := false;
    result := true;
    exit;
  end;

  if (not cl.cinematicpalette_active) then
  begin
    re.CinematicSetPalette(@cl.cinematicpalette);
    cl.cinematicpalette_active := true;
  end;

  if (cin.pic = nil) then
  begin
    result := true;
    exit;
  end;

  re.DrawStretchRaw(0, 0, viddef.width, viddef.height,
    cin.width, cin.height, cin.pic);

  result := true;
end;

{
==================
SCR_PlayCinematic

==================
}

procedure SCR_PlayCinematic(arg: Pchar);
var
  width, height: integer;
  palette: pbyte;
  name: array[0..MAX_OSPATH - 1] of char;
  dot: Pchar;
  old_khz: integer;
begin

  // make sure CD isn't playing music
  CDAudio_Stop();

  cl.cinematicframe := 0;
  dot := strstr(arg, '.');
  if (dot <> nil) and (strcmp(dot, '.pcx') = 0) then
  begin
    // 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 = nil) then
    begin
      Com_Printf('%s not found.'#10, [name]);
      cl.cinematictime := 0;
    end
    else
    begin
      memcpy(@cl.cinematicpalette, palette, sizeof(cl.cinematicpalette));
      Z_Free(palette);
    end;
    exit;
  end;

  Com_sprintf(name, sizeof(name), 'video/%s', [arg]);
  FS_FOpenFile(name, cl.cinematic_file);
  if (cl.cinematic_file = 0) then
  begin
    //		Com_Error (ERR_DROP, 'Cinematic %s not found.'#10, [name]);
    SCR_FinishCinematic();
    cl.cinematictime := 0; // done
    exit;
  end;

  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 := Round(Cvar_VariableValue('s_khz'));
  if (old_khz <> cin.s_rate / 1000) then
  begin
    cin.restart_sound := true;
    Cvar_SetValue('s_khz', cin.s_rate / 1000);
    CL_Snd_Restart_f();
    Cvar_SetValue('s_khz', old_khz);
  end;

  cl.cinematicframe := 0;
  cin.pic := SCR_ReadNextFrame();
  cl.cinematictime := Sys_Milliseconds();

end;

end.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -