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

📄 vid_dll.pas

📁 雷神之锤2(Quake2)Delphi源码
💻 PAS
📖 第 1 页 / 共 2 页
字号:
  case uMsg of
    WM_MOUSEWHEEL:  begin
       (*** this chunk of code theoretically only works under NT4 and Win98
            since this message doesn't exist under Win95 ***)
       if (LongRec(wParam).Hi > 0) then begin
          Key_Event(K_MWHEELUP, True, sys_msg_time);
          Key_Event(K_MWHEELUP, False, sys_msg_time);
       end else begin
           Key_Event(K_MWHEELDOWN, True, sys_msg_time);
           Key_Event(K_MWHEELDOWN, False, sys_msg_time);
       end;

       //Break;
    end;
    WM_HOTKEY:  begin
       Result := 0;
       Exit;
    end;
    WM_CREATE:  begin
       cl_hwnd := h_Wnd;

       MSH_MOUSEWHEEL := RegisterWindowMessage('MSWHEEL_ROLLMSG');
       Result := DefWindowProc(h_Wnd, uMsg, wParam, lParam);
       Exit;
    end;
    WM_PAINT:  begin
       { force entire screen to update next frame }
       SCR_DirtyScreen();
       Result := DefWindowProc(h_Wnd, uMsg, wParam, lParam);
       Exit;
    end;
    WM_DESTROY:  begin
       { let sound and input know about this? }
       cl_hwnd := 0;

       Result := DefWindowProc(h_Wnd, uMsg, wParam, lParam);
       Exit;
    end;
    WM_ACTIVATE:  begin
       { KJB: Watch this for problems in fullscreen modes with Alt-tabbing }
       fActive := LongRec(wParam).Lo;
       fMinimized := LongRec(wParam).Hi;

       AppActivate((fActive <> WA_INACTIVE), (fMinimized <> 0));

       if reflib_active then
          re.AppActivate(NOT (fActive = WA_INACTIVE));

       Result := DefWindowProc(h_Wnd, uMsg, wParam, lParam);
       Exit;
    end;
    WM_MOVE:  begin
       if (vid_fullscreen.value = 0) then begin
          { horizontal position }
          xPos := LongRec(lParam).Lo;
          { vertical position }
          yPos := LongRec(lParam).Hi;

          r.left := 0;
          r.top := 0;
          r.right := 1;
          r.bottom := 1;

          style := GetWindowLong(h_Wnd, GWL_STYLE);
          AdjustWindowRect(r, style, FALSE);

          Cvar_SetValue('vid_xpos', xPos + r.left);
          Cvar_SetValue('vid_ypos', yPos + r.top);
          vid_xpos.modified := False;
          vid_ypos.modified := False;
          if (ActiveApp <> 0) then
             IN_Activate(True);
       end;

       Result := DefWindowProc(h_Wnd, uMsg, wParam, lParam);
       Exit;
    end;
    { this is complicated because Win32 seems to pack multiple mouse events into
      one update sometimes, so we always check all states and look for events }
    WM_LBUTTONDOWN,
    WM_LBUTTONUP,
    WM_RBUTTONDOWN,
    WM_RBUTTONUP,
    WM_MBUTTONDOWN,
    WM_MBUTTONUP,
    WM_MOUSEMOVE: begin
       temp := 0;

       if ((wParam AND MK_LBUTTON) <> 0) then
          temp := temp OR 1;

       if ((wParam AND MK_RBUTTON) <> 0) then
          temp := temp OR 2;

       if ((wParam AND MK_MBUTTON) <> 0) then
          temp := temp OR 4;

       IN_MouseEvent(temp);

    end;
    WM_SYSCOMMAND:  begin
       if (wParam = SC_SCREENSAVE) then begin
          Result := 0;
          Exit;
       end;
    end;
    WM_SYSKEYDOWN:  begin
            if (wParam = 13) then begin
               if (vid_fullscreen <> nil) then
                  Cvar_SetValue('vid_fullscreen', Integer(NOT (vid_fullscreen.value<>0)));

               Result:= 0;
               Exit;
            end;
            { fall through }
            { Would seem to go through to the WM_KEYDOWN message, and then break out }
            Key_Event(MapKey(lParam), True, sys_msg_time);
    end;
    WM_KEYDOWN:  begin
            Key_Event(MapKey(lParam), True, sys_msg_time);
            //Break;
    end;
    WM_SYSKEYUP, WM_KEYUP:  begin
            Key_Event(MapKey(lParam), False, sys_msg_time);
            //Break;
    end;
    MM_MCINOTIFY:  begin
       { LONG CDAudio_MessageHandler(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); }
       { Remove the definition of this function.  Must be being called from somewhere else }
       {lRet :=} CDAudio_MessageHandler (h_Wnd, uMsg, wParam, lParam);

       //Break;
    end;
  end;

  (* return 0 if handled message, 1 if not *)
  Result := DefWindowProc(h_Wnd, uMsg, wParam, lParam);
end;

function VID_GetModeInfo(width, height: PInteger; mode: integer): qboolean; cdecl;
begin
  if (mode < 0) OR (mode >= VID_NUM_MODES) then begin
     Result := False;
     Exit;
  end;

  width^ := vid_modes[mode].width;
  height^ := vid_modes[mode].height;

  Result := True;
end;

(*** VID_UpdateWindowPosAndSize ***)
procedure VID_UpdateWindowPosAndSize(x, y: Integer); cdecl;
var
  r: TRECT;
  style, w, h: Integer;
begin
  r.left := 0;
  r.top := 0;
  r.right := viddef.width;
  r.bottom := viddef.height;

  style := GetWindowLong(cl_hwnd, GWL_STYLE);
  AdjustWindowRect(r, style, FALSE);

  w := (r.right - r.left);
  h := (r.bottom - r.top);

  MoveWindow(cl_hwnd, Round(vid_xpos.value), Round(vid_ypos.value), w, h, TRUE);
end;

(*** VID_NewWindow ***)
procedure VID_NewWindow(width, height: Integer); cdecl;
begin
  viddef.width := width;
  viddef.height := height;

  cl.force_refdef := True;	{ can't use a paused refdef }
end;

procedure VID_FreeReflib;
begin
  if (NOT FreeLibrary(reflib_library)) then
     Com_Error(ERR_FATAL, 'Reflib FreeLibrary failed', []);

  { ORIGINAL:  memset(@re, 0, sizeof(re)); }
  FillChar(re, SizeOf(re), 0);

  reflib_library := 0;
  reflib_active := False;
end;

(* ==============
VID_LoadRefresh
============== *)
function VID_LoadRefresh(name: PChar): qboolean; cdecl;
var
  ri: refimport_t;
  GetRefAPI: GetRefAPI_t;
begin
  if (reflib_active) then begin
     re.Shutdown;
     VID_FreeReflib;
  end;

  Com_Printf('------- Loading %s -------'#10, [name]);

  reflib_library := LoadLibrary(name);
  if (reflib_library = 0) then begin
     Com_Printf('LoadLibrary("%s") failed'#10, [name]);

     Result := False;
     Exit;
  end;

  ri.Cmd_AddCommand := Cmd_AddCommand;
  ri.Cmd_RemoveCommand := Cmd_RemoveCommand;
  ri.Cmd_Argc := Cmd_Argc;
  ri.Cmd_Argv := Cmd_Argv;
  ri.Cmd_ExecuteText := Cbuf_ExecuteText;
  ri.Con_Printf := VID_Printf_cdecl;
  ri.Sys_Error := VID_Error_cdecl;
  ri.FS_LoadFile := FS_LoadFile;
  ri.FS_FreeFile := FS_FreeFile;
  ri.FS_Gamedir := FS_Gamedir;
  ri.Cvar_Get := Cvar_Get;
  ri.Cvar_Set := Cvar_Set;
  ri.Cvar_SetValue := Cvar_SetValue;
  ri.Vid_GetModeInfo := VID_GetModeInfo;
  ri.Vid_MenuInit := VID_MenuInit;
  ri.Vid_NewWindow := VID_NewWindow;

  { ORIGINAL:     if ( ( GetRefAPI = (void *) GetProcAddress( reflib_library, "GetRefAPI" ) ) == 0 )  }
  GetRefApi := GetProcAddress(reflib_library, 'GetRefAPI');
  if not Assigned(GetRefApi) then
     Com_Error(ERR_FATAL, 'GetProcAddress failed on %s', [name]);

  re := GetRefAPI(ri);

  if (re.api_version <> API_VERSION) then begin
     VID_FreeReflib;
     Com_Error(ERR_FATAL, '%s has incompatible api_version', [name]);
  end;

  if (re.Init(global_hInstance, @MainWndProc) = -1) then begin
     re.Shutdown;
     VID_FreeReflib;
     Result := False;
     Exit;
  end;

  Com_Printf('------------------------------------'#10, []);
  reflib_active := True;

//======
//PGM
  vidref_val := VIDREF_OTHER;
  if Assigned(vid_ref) then begin
     if (StrComp(vid_ref.string_, 'gl') = 0) then
        vidref_val := VIDREF_GL
     else if (StrComp(vid_ref.string_, 'soft') = 0) then
          vidref_val := VIDREF_SOFT;
  end;
//PGM
//======

  Result := True;
end;

{*
============
VID_CheckChanges

This function gets called once just before drawing each frame, and it's sole purpose in life
is to check to see if any of the video mode parameters have changed, and if they have to
update the rendering DLL and/or video mode to match.
============
*}
procedure VID_CheckChanges;
var
  name: array[0..100-1] of Char;
begin
  if (win_noalttab.modified) then begin
     if (win_noalttab.value <> 0) then
        WIN_DisableAltTab
     else
        WIN_EnableAltTab;

     win_noalttab.modified := False;
  end;

  if (vid_ref.modified) then begin
     cl.force_refdef := True;  { can't use a paused refdef }
     S_StopAllSounds;
  end;

  while (vid_ref.modified) do begin
    (*** refresh has changed ***)
    vid_ref.modified := False;
    vid_fullscreen.modified := True;
    cl.refresh_prepped := False;
    cls.disable_screen := Integer(True);

    Com_sprintf(name, SizeOf(name), 'ref_%s.dll', [vid_ref.string_]);

    if (NOT VID_LoadRefresh(name)) then begin
       if (CompareStr(vid_ref.string_, 'soft') = 0) then
          Com_Error(ERR_FATAL, 'Couldn''t fall back to software refresh!', []);

       Cvar_Set('vid_ref', 'soft');

       (*** drop the console if we fail to load a refresh ***)
       if (cls.key_dest <> key_console) then
          Con_ToggleConsole_f;
    end;

    cls.disable_screen := Integer(False);
  end;

  (*** update our window position ***)
  if (vid_xpos.modified OR vid_ypos.modified) then begin
     if (vid_fullscreen.value <> 0) then
        VID_UpdateWindowPosAndSize(Round(vid_xpos.value), Round(vid_ypos.value) );

     vid_xpos.modified := False;
     vid_ypos.modified := False;
  end;
end;

(* ============
VID_Init
============ *)
procedure VID_Init;
begin
  { Create the video variables so we know how to start the graphics drivers }
  vid_ref := Cvar_Get('vid_ref', 'soft', CVAR_ARCHIVE);
  vid_xpos := Cvar_Get('vid_xpos', '3', CVAR_ARCHIVE);
  vid_ypos := Cvar_Get('vid_ypos', '22', CVAR_ARCHIVE);
  vid_fullscreen := Cvar_Get('vid_fullscreen', '0', CVAR_ARCHIVE);
  vid_gamma := Cvar_Get('vid_gamma', '1', CVAR_ARCHIVE);
  win_noalttab := Cvar_Get('win_noalttab', '0', CVAR_ARCHIVE);

  { Add some console commands that we want to handle }
  Cmd_AddCommand('vid_restart', @VID_Restart_f);
  Cmd_AddCommand('vid_front', @VID_Front_f);

  (*
  ** this is a gross hack but necessary to clamp the mode for 3Dfx
  *)
(* IF Defined 0 - This means always FALSE!!!  Why not commented out ???
#if 0
  {
          cvar_t *gl_driver = Cvar_Get( "gl_driver", "opengl32", 0 );
          cvar_t *gl_mode = Cvar_Get( "gl_mode", "3", 0 );

          if ( stricmp( gl_driver->string, "3dfxgl" ) == 0 )
          {
                  Cvar_SetValue( "gl_mode", 3 );
                  viddef.width  = 640;
                  viddef.height = 480;
          }
  }
#endif
*)

  { Disable the 3Dfx splash screen }
  Windows.SetEnvironmentVariable('FX_GLIDE_NO_SPLASH', '0');

  { Start the graphics mode and load refresh DLL }
  VID_CheckChanges;
end;

(* ============
VID_Shutdown
============ *)
procedure VID_Shutdown;
begin
  if (reflib_active) then begin
     re.Shutdown;
     VID_FreeReflib;
  end;
end;


end.

⌨️ 快捷键说明

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