From c068f22329d5cc722622a2183bbb22eef2093df7 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Mon, 24 Aug 2026 11:16:07 +0200 Subject: initial import --- src/parsec/vid_init.cpp | 582 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 582 insertions(+) create mode 100644 src/parsec/vid_init.cpp (limited to 'src/parsec/vid_init.cpp') diff --git a/src/parsec/vid_init.cpp b/src/parsec/vid_init.cpp new file mode 100644 index 0000000..206fa6b --- /dev/null +++ b/src/parsec/vid_init.cpp @@ -0,0 +1,582 @@ +/* + * PARSEC - Mode Init Functions + * + * $Author: uberlinuxguy $ - $Date: 2004/09/15 12:25:36 $ + * + * Orginally written by: + * Copyright (c) Markus Hadwiger 1996-2001 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +// C library +#include +#include +#include +#include + +// compilation flags/debug support +#include "config.h" +#include "debug.h" + +// general definitions +#include "general.h" +#include "objstruc.h" + +// global externals +#include "globals.h" + +// subsystem headers +#include "aud_defs.h" +#include "inp_defs.h" +#include "sys_defs.h" +#include "vid_defs.h" + +// patching headers +#include "d_patch.h" +#include "r_patch.h" + +// rendering subsystem +#include "r_supp.h" + +// mathematics header +#include "utl_math.h" + +// model header +#include "utl_model.h" + +// local module header +#include "vid_init.h" + +// proprietary module headers +#include "con_main.h" +#include "e_callbk.h" +#include "e_color.h" +#include "e_loader.h" +#include "e_supp.h" +#include "h_drwhud.h" +#include "h_supp.h" +#include "part_sys.h" + + +// names of control files depending on desired resolution and detail level ---- +// +static char ctrl_h_h[] = "ctrl_h_h.dat"; +static char ctrl_h_m[] = "ctrl_h_m.dat"; +static char ctrl_h_l[] = "ctrl_h_l.dat"; +//static char ctrl_l_h[] = "ctrl_l_h.dat"; +//static char ctrl_l_m[] = "ctrl_l_m.dat"; +//static char ctrl_l_l[] = "ctrl_l_l.dat"; + + +// return control file-name corresponding to detail level and resolution ------ +// +char *FetchCtrlFileName() +{ + switch ( Op_DetailLevel ) { + + case DETAIL_HIGH: + return ctrl_h_h; + + case DETAIL_MEDIUM: + return ctrl_h_m; + + case DETAIL_LOW: + return ctrl_h_l; + } + + return ctrl_h_h; +} + + +// load data according to resolution ------------------------------------------ +// +void LoadResolutionData() +{ + // resolution data for 640x400 and above is the same + /*if ( ( CurDataResolution >= MODE_HIRES_BASE ) && + ( GameScreenMode >= MODE_HIRES_BASE ) ) + return;*/ + + // load resolution-dependent data +// ReloadResData( FetchCtrlFileName() ); +} + + +// load data according to detail level ---------------------------------------- +// +void LoadDetailData() +{ + // load detail-dependent data + ReloadDetailData( FetchCtrlFileName() ); +} + + +// map video mode specifier string "XRESxYRESxBPP" to video mode array ------- +// +void VID_MapSpecifierToMode(char * modespec, int * modearray) +{ + ASSERT( modespec != NULL ); + + // strip leading space + while ( *modespec == ' ' ) + modespec++; + + // convert to lower case + char _spec[ 15 + 1 ]; + strncpy( _spec, modespec, 15 ); + _spec[ 15 ] = 0; + strlwr( _spec ); + modespec = _spec; + + // fetch x resolution + char *scan = modespec; + while ( ( *scan != 'x' ) && ( *scan != 0 ) ) + scan++; + if ( *scan != 'x' ) + return; + *scan++ = 0; + + char *errpart; + dword xres = strtol( modespec, &errpart, 10 ); + if ( *errpart != 0 ) + return; + + // fetch y resolution + modespec = scan; + while ( ( *scan != 'x' ) && ( *scan != 0 ) ) + scan++; + if ( *scan != 'x' ) + return; + *scan++ = 0; + + dword yres = strtol( modespec, &errpart, 10 ); + if ( *errpart != 0 ) + return; + + // fetch color depth (strip trailing space) + modespec = scan; + while ( ( *scan != ' ' ) && ( *scan != 0 ) ) + scan++; + if ( ( *scan != ' ' ) && ( *scan != 0 ) ) + return; + *scan = 0; + dword bpp = strtol( modespec, &errpart, 10 ); + if ( *errpart != 0 ) + return; + + modearray[0] = xres; + modearray[1] = yres; + modearray[2] = bpp; +} + + +// set up data depending on video mode ---------------------------------------- +// +void VID_SetupDependentData() +{ + // ensure correct data for selected resolution is loaded + LoadResolutionData(); + + // ensure correct data for selected detail level is loaded + if ( CurDataDetail != Op_DetailLevel ) { + LoadDetailData(); + CurDataDetail = Op_DetailLevel; + } + + // setup data for selected color depth + if ( CurDataColorBits != GameScreenBPP ) { + SetupTranslationPalette( PaletteMem + PAL_GAME ); + SetupBitmapColors(); + CurDataColorBits = GameScreenBPP; + } + + // evict texture data resident in an unsupported format + EvictUnsupportedTextureFormatData(); + + // make sure texture data that might have been freed + // by the texture cache is available once again + ReloadFreedTextureBitmaps(); + + // precache textures + R_PrecacheTextures(); +} + + +// map bpp color mode specification to options menu color mode specification -- +// +int VID_MapBppToOpt( int bpp ) +{ + int bppopt = -1; + + switch ( bpp ) { + + case MODE_COL_16BPP: + bppopt = COLMODE_HICOLOR; + break; + + case MODE_COL_32BPP: + bppopt = COLMODE_TRUECOLOR; + break; + + default: + ASSERT( 0 ); + } + + return bppopt; +} + + +// determine color depth corresponding to options menu selection -------------- +// +int VID_MapOptToBpp( int bppopt ) +{ + int bpp = -1; + + switch ( bppopt ) { + + case COLMODE_HICOLOR: + bpp = MODE_COL_16BPP; + break; + + case COLMODE_TRUECOLOR: + bpp = MODE_COL_32BPP; + break; + + default: + ASSERT( 0 ); + } + + return bpp; +} + + +// apply graphics options settings (video mode may be switched!) -------------- +// +void VID_ApplyOptions() +{ + //NOTE: + // this function is used to ensure the currently active + // graphics mode satisfies the currently set video options. + // it is not used to switch between text mode and graphics mode. + // it performs mode switching only if a video option (resolution, + // color depth, windowed/full-screen) has indeed changed. + + //NOTE: + // this function is used by VID_PLUG::VID_HotChangeMode() and + // to switch from menu mode to game mode. + + // determine color depth + int bpp = VID_MapOptToBpp(Op_ColorDepth); + + // no unavailable mode can be selected + if (!VID_MODE_AVAILABLE(GetResolutionIndex(Op_Resolution.width, Op_Resolution.height))) { + Op_Resolution.set(800, 600); // assume 800x600 is always available + } + + // switch to selected video mode if not already active + VID_SwitchMode(Op_Resolution.width, Op_Resolution.height, bpp); + + // set up data depending on video mode + VID_SetupDependentData(); + + // init hud geometry + InitHudDisplay(); + + // init sizes of particles + InitParticleSizes(); + + // check console extents + CheckConExtents(); +} + + +// patch graphics code to new resolution -------------------------------------- +// +PRIVATE +void VID_PatchResolution() +{ + R_PatchSubSystem(); +} + + +// calculate viewing volume for current screen geometry ----------------------- +// +PUBLIC +void VID_SetViewingVolume() +{ + // world-space screen rectangle (one pixel safety) + Criterion_X = INT_TO_GEOMV( Screen_XOfs + 1 ) / D_Value; + Criterion_Y = INT_TO_GEOMV( Screen_YOfs + 1 ) / D_Value; + + // frustum boundary planes + +// PLANE_MAKEAXIAL( &volume[ 0 ], GEOMV_1, Near_View_Plane ); +// PLANE_MAKEAXIAL( &volume[ 1 ], -GEOMV_1, Far_View_Plane ); + + PLANE_NORMAL( &View_Volume[ 0 ] )->X = 0; + PLANE_NORMAL( &View_Volume[ 0 ] )->Y = 0; + PLANE_NORMAL( &View_Volume[ 0 ] )->Z = GEOMV_1; + PLANE_OFFSET( &View_Volume[ 0 ] ) = Near_View_Plane; + + PLANE_NORMAL( &View_Volume[ 1 ] )->X = 0; + PLANE_NORMAL( &View_Volume[ 1 ] )->Y = 0; + PLANE_NORMAL( &View_Volume[ 1 ] )->Z = -GEOMV_1; + PLANE_OFFSET( &View_Volume[ 1 ] ) = -Far_View_Plane; + + Vector3 ul, ur, ll, lr; + ul.X = -Criterion_X; + ul.Y = -Criterion_Y; + ul.Z = GEOMV_1; + ur.X = Criterion_X; + ur.Y = -Criterion_Y; + ur.Z = GEOMV_1; + ll.X = -Criterion_X; + ll.Y = Criterion_Y; + ll.Z = GEOMV_1; + lr.X = Criterion_X; + lr.Y = Criterion_Y; + lr.Z = GEOMV_1; + + CrossProduct( &ul, &ur, PLANE_NORMAL( &View_Volume[ 2 ] ) ); + NormVctX( PLANE_NORMAL( &View_Volume[ 2 ] ) ); + PLANE_OFFSET( &View_Volume[ 2 ] ) = 0; + + CrossProduct( &ur, &lr, PLANE_NORMAL( &View_Volume[ 3 ] ) ); + NormVctX( PLANE_NORMAL( &View_Volume[ 3 ] ) ); + PLANE_OFFSET( &View_Volume[ 3 ] ) = 0; + + CrossProduct( &lr, &ll, PLANE_NORMAL( &View_Volume[ 4 ] ) ); + NormVctX( PLANE_NORMAL( &View_Volume[ 4 ] ) ); + PLANE_OFFSET( &View_Volume[ 4 ] ) = 0; + + CrossProduct( &ll, &ul, PLANE_NORMAL( &View_Volume[ 5 ] ) ); + NormVctX( PLANE_NORMAL( &View_Volume[ 5 ] ) ); + PLANE_OFFSET( &View_Volume[ 5 ] ) = 0; + + // augment view planes by reject/accept points for culling + CULL_MakeVolumeCullVolume( View_Volume, Cull_Volume, 0x3f ); +} + + +// init resolution-dependent variables ---------------------------------------- +// +PRIVATE +void VID_SetResolutionVars() +{ + int xres = GameScreenRes.width; + int yres = GameScreenRes.height; + + int bpp = GameScreenBPP; + + int modeindx = GetResolutionIndex(GameScreenRes.width, GameScreenRes.height); + + // copy basic mode info from table + ASSERT( VID_MODE_AVAILABLE( modeindx ) ); + Screen_Width = xres; + Screen_Height = yres; + + // set variables according to resolution + + Star_Siz = RObj_Siz = (int) 3.0f * ((float) Screen_Height / 720.0f); + D_Value = Screen_Width * 0.78f; // lower value compared to base screen width = greater FOV + + // init additional geometry variables + Screen_XOfs = Screen_Width / 2; // x-midpoint coordinate + Screen_YOfs = Screen_Height / 2; // y-midpoint coordinate + + // set viewing volume planes + VID_SetViewingVolume(); + + Screen_BytesPerPixel = (int) floorf(bpp / 8.0f); +} + + +// init everything that needs to be changed when graphics mode is changed ----- +// +PRIVATE +void VID_InitModeGeometry() +{ + VID_SetResolutionVars(); + VID_PatchResolution(); +} + + +// wrapper for VIDs_InitDisplay() --------------------------------------------- +// +void VID_InitMode() +{ + // set video mode + VIDs_InitDisplay(); + + // notify other parts of the game about current video mode + // by walking the corresponding callback list + CALLBACK_WalkCallbacks( CBTYPE_VIDMODE_CHANGED ); +} + + +// helper function only used by the following function ------------------------ +// +PRIVATE +void VID_PerformSwitch() +{ + //NOTE: + // even if the resolution stays the same (in case we are only + // switching between fullscreen and windowed) we need to call + // VID_InitModeGeometry() to ensure the subsystem knows about + // the reinitialization. otherwise the texture memory manager + // wouldn't be informed of the reinitialization, for example. + + // init resolution-dependent vars and code + VID_InitModeGeometry(); + + // actually change video mode + VID_InitMode(); + + // make sure mouse tracking works correctly + INPs_MouseKillHandler(); + INPs_MouseInitHandler(); +} + + +// switch to another video mode if not already active ------------------------- +// +void VID_SwitchMode( int xres, int yres, int bpp ) +{ + int resindex = GetResolutionIndex(xres, yres); + + ASSERT(VID_MODE_AVAILABLE(resindex)); + + //NOTE: + // this function is used to switch the currently active + // graphics mode. it is not used to switch between text mode + // and graphics mode. it performs mode switching only if + // something (resolution, color depth, windowed/full-screen) + // has indeed changed. + + //NOTE: + // this function is used by VID_INIT::VID_ApplyOptions() and + // to switch from game mode back to menu mode. + + // filter mode-switch if nothing has changed + if (xres != GameScreenRes.width || yres != GameScreenRes.height || bpp != GameScreenBPP) { + + printf("Resolution change.\n"); + GameScreenRes.set(xres, yres); + GameScreenBPP = bpp; + GameScreenWindowed = Op_WindowedMode; + + // perform actual mode switch + VID_PerformSwitch(); + + } else { + + // even if same mode with respect to resolution and color depth + // allow switching between full-screen and windowed mode + printf("No Resolution change.\n"); +// if ( GameScreenWindowed != Op_WindowedMode ) { // disabled so vsync switching will work + + GameScreenWindowed = Op_WindowedMode; + + // re-init same mode + if ( VID_MODE_AVAILABLE( resindex ) ) { + // perform actual mode switch + VID_PerformSwitch(); + } +// } + } +} + + +// determine initial video options settings for game screen mode -------------- +// +PRIVATE +void VID_SetInitOptions() +{ + // override only if forced by user + if ( InitOp_FlipSynched != -1 ) { + FlipSynched = InitOp_FlipSynched; + } + + // default is base screen mode + Op_Resolution = GameScreenRes; + Op_ColorDepth = VID_MapBppToOpt( GameScreenBPP ); + Op_WindowedMode = GameScreenWindowed; + + // override with init options if available + if (InitOp_Resolution.isValid()) { + + // determine windowed/fullscreen + int opwin = ( InitOp_WindowedMode != -1 ) ? + InitOp_WindowedMode : Op_WindowedMode; + + // determine init mode for overriding default + int mindx = GetResolutionIndex(InitOp_Resolution.width, InitOp_Resolution.height); + + // set the init mode if it is valid. the switch will + // be done on next invocation of VID_ApplyOptions(). + if ( VID_MODE_AVAILABLE( mindx ) ) { + Op_Resolution = InitOp_Resolution; + Op_ColorDepth = InitOp_ColorDepth; + Op_WindowedMode = opwin; + } + + } else if ( InitOp_WindowedMode != -1 ) { + + // only override windowed/fullscreen; resolution and bpp are default + int resindex = GetResolutionIndex(GameScreenRes.width, GameScreenRes.height); + if ( VID_MODE_AVAILABLE( resindex ) ) { + Op_WindowedMode = InitOp_WindowedMode; + } + } +} + + +// set safe default values for internal video subsystem-specific flags -------- +// +PRIVATE +void VID_DefaultVideoFlags() +{ + // reset color setup (conversion) flags + ColorSetupFlags = COLORSETUP_DEFAULT; + + // set same default values as in VID_GLOB.C + VidInfo_NumTextureUnits = 1; + VidInfo_MaxTextureSize = 2048; + VidInfo_MaxTextureLod = TEXLOD_2048; + VidInfo_UseIterForDemoTexts = FALSE; + VidInfo_SupportedTexFormats = NULL; +} + + +// video subsystem initialization --------------------------------------------- +// +void VID_InitSubsystem() +{ + // set video flags to defaults + VID_DefaultVideoFlags(); + + // init frame buffer api and establish available video mode list + VIDs_InitFrameBufferAPI(); + + // set video options for game screen mode + VID_SetInitOptions(); + + // init resolution-dependent vars and code for the first time + VID_InitModeGeometry(); +} + + + -- cgit v1.2.3