diff --git a/base/guis/assets/mainmenu/1.tga b/base/guis/assets/mainmenu/1.tga
new file mode 100644
index 00000000..d536178c
Binary files /dev/null and b/base/guis/assets/mainmenu/1.tga differ
diff --git a/base/guis/assets/mainmenu/2.tga b/base/guis/assets/mainmenu/2.tga
new file mode 100644
index 00000000..54afb74f
Binary files /dev/null and b/base/guis/assets/mainmenu/2.tga differ
diff --git a/base/guis/assets/mainmenu/3.tga b/base/guis/assets/mainmenu/3.tga
new file mode 100644
index 00000000..eafdd246
Binary files /dev/null and b/base/guis/assets/mainmenu/3.tga differ
diff --git a/base/guis/assets/mainmenu/4.tga b/base/guis/assets/mainmenu/4.tga
new file mode 100644
index 00000000..7e01fbb1
Binary files /dev/null and b/base/guis/assets/mainmenu/4.tga differ
diff --git a/base/guis/assets/mainmenu/5.tga b/base/guis/assets/mainmenu/5.tga
new file mode 100644
index 00000000..4f2233a4
Binary files /dev/null and b/base/guis/assets/mainmenu/5.tga differ
diff --git a/base/guis/assets/mainmenu/bg.tga b/base/guis/assets/mainmenu/bg.tga
new file mode 100644
index 00000000..65a2ec7a
Binary files /dev/null and b/base/guis/assets/mainmenu/bg.tga differ
diff --git a/base/guis/assets/splash/launch.tga b/base/guis/assets/splash/launch.tga
new file mode 100644
index 00000000..46472950
Binary files /dev/null and b/base/guis/assets/splash/launch.tga differ
diff --git a/base/guis/loadscreenbeta.gui b/base/guis/loadscreenbeta.gui
new file mode 100644
index 00000000..2076edd4
--- /dev/null
+++ b/base/guis/loadscreenbeta.gui
@@ -0,0 +1,11 @@
+windowDef Desktop {
+ rect 0, 0, 1280, 720
+ backcolor 0, 0, 0, 1
+
+ windowDef Background {
+ rect 0, 0, 1280, 720
+ background "guis/assets/splash/launch"
+ matcolor 1 ,1, 1, 1
+ visible 1
+ }
+}
\ No newline at end of file
diff --git a/base/guis/mainmenu.gui b/base/guis/mainmenu.gui
new file mode 100644
index 00000000..bc469786
--- /dev/null
+++ b/base/guis/mainmenu.gui
@@ -0,0 +1,441 @@
+windowDef Desktop {
+ rect 0, 0, 1280, 720
+ backcolor 0, 0, 0, 1
+ float Button "0"
+ float Menugui "1"
+
+ onESC {
+ set "cmd" "close" ;
+ }
+
+
+ windowDef Background {
+ rect 0, 0, 1280, 720
+ background "guis/assets/mainmenu/bg"
+ matcolor 1 ,1, 1, 1
+ visible 1
+ }
+
+ windowDef Doom {
+ rect 162, 0, 972, 426
+ background "guis/assets/schema/doom"
+ matcolor 1 ,1, 1, 1
+ visible 1
+ }
+
+ windowDef DoomGlow {
+ rect 162, 0, 972, 426
+ background "doomglow"
+ matcolor 1 ,1, 1, 1
+ visible 1
+ }
+
+ windowDef Button1o {
+ rect 380, 405, 512, 48
+ background "menu/button1"
+ matcolor 1 ,1, 1, 1
+ visible 0
+ }
+
+ windowDef Button2o {
+ rect 380, 465, 512, 48
+ background "menu/button2"
+ matcolor 1 ,1, 1, 1
+ visible 0
+ }
+
+ windowDef Button3o {
+ rect 500, 525, 278, 48
+ background "menu/button3"
+ matcolor 1 ,1, 1, 1
+ visible 0
+ }
+
+ windowDef Button4o {
+ rect 506, 585, 256, 48
+ background "menu/button4"
+ matcolor 1 ,1, 1, 1
+ visible 0
+ }
+
+ windowDef Button5o {
+ rect 506, 645, 256, 48
+ background "menu/button5"
+ matcolor 1 ,1, 1, 1
+ visible 0
+ }
+
+ windowDef PopUp {
+ rect 354, 660, 572, 60
+ background "guis/assets/mainmenu/callout"
+ matcolor 1 ,1, 1, 0
+ visible 1
+ }
+
+ windowDef Button1 {
+ rect 380, 405, 512, 48
+ background "guis/assets/mainmenu/1"
+ matcolor 1 ,1, 1, 0.9
+ visible 1
+
+ onMouseEnter {
+ set "Button1o::visible" "1" ;
+ }
+ onMouseExit {
+ set "Button1o::visible" "0" ;
+ }
+ onAction {
+ set "cmd" "play guisounds_click" ;
+ set "Desktop::Button" "1" ;
+ resetTime "Anim" "0" ;
+ resetTime "Click1" "0" ;
+ set "Button1o::visible" "0" ;
+ transition "Button2::matcolor" "1 1 1 0.4" "1 1 1 0" "200" ;
+ transition "Button3::matcolor" "1 1 1 0.4" "1 1 1 0" "200" ;
+ transition "Button4::matcolor" "1 1 1 0.4" "1 1 1 0" "200" ;
+ transition "Button5::matcolor" "1 1 1 0.9" "1 1 1 0" "200" ;
+ }
+ }
+
+ windowDef Button2 {
+ rect 380, 465, 512, 48
+ background "guis/assets/mainmenu/2"
+ matcolor 1 ,1, 1, 0.4
+ visible 1
+/*
+ onMouseEnter {
+ set "Button2o::visible" "1" ;
+ }
+ onMouseExit {
+ set "Button2o::visible" "0" ;
+ }
+ onAction {
+ set "Desktop::Button" "2" ;
+ resetTime "Anim" "0" ;
+ set "Button2o::visible" "0" ;
+ transition "Button1::matcolor" "1 1 1 0.9" "1 1 1 0" "200" ;
+ transition "Button3::matcolor" "1 1 1 0.4" "1 1 1 0" "200" ;
+ transition "Button4::matcolor" "1 1 1 0.4" "1 1 1 0" "200" ;
+ transition "Button5::matcolor" "1 1 1 0.9" "1 1 1 0" "200" ;
+ }
+*/
+ }
+
+ windowDef Button3 {
+ rect 500, 525, 278, 48
+ background "guis/assets/mainmenu/3"
+ matcolor 1 ,1, 1, 0.4
+ visible 1
+ }
+
+ windowDef Button4 {
+ rect 506, 585, 256, 48
+ background "guis/assets/mainmenu/4"
+ matcolor 1 ,1, 1, 0.4
+ visible 1
+ }
+
+ windowDef Button5 {
+ rect 506, 645, 256, 48
+ background "guis/assets/mainmenu/5"
+ matcolor 1 ,1, 1, 0.9
+ visible 1
+
+ onMouseEnter {
+ set "Button5o::visible" "1" ;
+ }
+ onMouseExit {
+ set "Button5o::visible" "0" ;
+ }
+ onAction {
+ set "cmd" "play guisounds_click" ;
+ set "Desktop::Button" "5" ;
+ resetTime "Anim" "0" ;
+ resetTime "Click5" "0" ;
+ set "Button5o::visible" "0" ;
+ transition "Button1::matcolor" "1 1 1 0.9" "1 1 1 0" "200" ;
+ transition "Button2::matcolor" "1 1 1 0.4" "1 1 1 0" "200" ;
+ transition "Button3::matcolor" "1 1 1 0.4" "1 1 1 0" "200" ;
+ transition "Button4::matcolor" "1 1 1 0.4" "1 1 1 0" "200" ;
+ }
+ }
+
+ windowDef Text1a {
+ rect 354, 426, -572, 60
+ text "New Game"
+ font "fonts/chain"
+ textscale 0.75
+ textalign 1
+ forecolor 1, 0.1, 0.1, 0
+ noevents 1
+
+ onMouseEnter {
+ set "forecolor" "1 0.4 0 1" ;
+ }
+ onMouseExit {
+ set "forecolor" "1 0.1 0.1 1" ;
+ }
+ onAction {
+ set "cmd" "play guisounds_click" ;
+ set "cmd" "startgame" ;
+ resetTime "Main1" "0" ;
+ }
+ }
+ windowDef Text1b {
+ rect 354, 471, -572, 60
+ text "Load Game"
+ font "fonts/chain"
+ textscale 0.75
+ textalign 1
+ forecolor 1, 0.1, 0.1, 0
+ }
+ windowDef Text1c {
+ rect 354, 516, -572, 60
+ text "Cinematics"
+ font "fonts/chain"
+ textscale 0.75
+ textalign 1
+ forecolor 1, 0.1, 0.1, 0
+ }
+ windowDef Text1d {
+ rect 354, 561, -572, 60
+ text "Demos"
+ font "fonts/chain"
+ textscale 0.75
+ textalign 1
+ forecolor 1, 0.1, 0.1, 0
+ }
+ windowDef Text1e {
+ rect 354, 606, -572, 60
+ text "Main Menu"
+ font "fonts/chain"
+ textscale 0.75
+ textalign 1
+ forecolor 1, 0.1, 0.1, 0
+ noevents 1
+
+ onMouseEnter {
+ set "forecolor" "1 0.4 0 1" ;
+ }
+ onMouseExit {
+ set "forecolor" "1 0.1 0.1 1" ;
+ }
+ onAction {
+ set "cmd" "play guisounds_close" ;
+ resetTime "Main1" "0" ;
+ }
+ }
+
+ windowDef Text5a {
+ rect 352, 450, -572, 120
+ text "Are you sure you\nwant to exit?"
+ font "fonts/chain"
+ textscale 0.75
+ textalign 1
+ forecolor 1, 0.1, 0.1, 0
+ }
+
+ windowDef Text5b {
+ rect 420, 577.5, -200, 120
+ text "Yes"
+ font "fonts/chain"
+ textscale 0.75
+ textalign 1
+ forecolor 1, 0.1, 0.1, 0
+ noevents 1
+
+ onMouseEnter {
+ set "forecolor" "1 0.4 0 1" ;
+ }
+ onMouseExit {
+ set "forecolor" "1 0.1 0.1 1" ;
+ }
+ onAction {
+ set "cmd" "play guisounds_click" ;
+ set "cmd" "quit" ;
+ }
+ }
+
+ windowDef Text5c {
+ rect 660, 577.5, -200, 120
+ text "No"
+ font "fonts/chain"
+ textscale 0.75
+ textalign 1
+ forecolor 1, 0.1, 0.1, 0
+ noevents 1
+
+ onMouseEnter {
+ set "forecolor" "1 0.4 0 1" ;
+ }
+ onMouseExit {
+ set "forecolor" "1 0.1 0.1 1" ;
+ }
+ onAction {
+ set "cmd" "play guisounds_close" ;
+ resetTime "Main5" "0" ;
+ }
+ }
+
+//////////////////////////
+//Animation
+/////////////////////////
+
+ windowDef Anim {
+ notime 1
+
+ onTime 0 {
+ set "Button1::noevents" "1" ;
+ set "Button2::noevents" "1" ;
+ set "Button3::noevents" "1" ;
+ set "Button4::noevents" "1" ;
+ set "Button5::noevents" "1" ;
+ transition "Button1::rect" "380 405 512 48" "380 675 512 48" "200" ;
+ transition "Button2::rect" "380 465 512 48" "380 675 512 48" "200" ;
+ transition "Button3::rect" "500 525 278 48" "500 675 278 48" "200" ;
+ transition "Button4::rect" "506 585 256 48" "506 675 256 48" "200" ;
+ transition "Button5::rect" "506 645 256 48" "506 675 256 48" "200" ;
+ }
+ onTime 0 {
+ transition "PopUp::matcolor" "1 1 1 0" "1 1 1 1" "100" ;
+ transition "PopUp::rect" "354 660 572 60" "354 406.5 572 313.5" "200" ;
+ }
+ }
+
+ windowDef Click1 {
+ notime 1
+
+ onTime 200 {
+ set "Text1a::rect" "354 426 572 60" ;
+ set "Text1a::noevents" "0" ;
+ transition "Text1a::forecolor" "1 0.1 0.1 0" "1 0.1 0.1 1" "50" ;
+ }
+ onTime 250 {
+ set "Text1b::rect" "354 471 572 60" ;
+ transition "Text1b::forecolor" "1 0.1 0.1 0" "1 0.1 0.1 0.5" "50" ;
+ }
+ onTime 300 {
+ set "Text1c::rect" "354 516 572 60" ;
+ transition "Text1c::forecolor" "1 0.1 0.1 0" "1 0.1 0.1 0.5" "50" ;
+ }
+ onTime 350 {
+ set "Text1d::rect" "354 561 572 60" ;
+ transition "Text1d::forecolor" "1 0.1 0.1 0" "1 0.1 0.1 0.5" "50" ;
+ }
+ onTime 400 {
+ set "Text1e::rect" "354 606 572 60" ;
+ set "Text1e::noevents" "0" ;
+ transition "Text1e::forecolor" "1 0.1 0.1 0" "1 0.1 0.1 1" "50" ;
+ }
+ }
+
+ windowDef Main1 {
+ notime 1
+
+ onTime 0 {
+ set "Text1a::noevents" "1" ;
+ set "Text1e::noevents" "1" ;
+ transition "Text1a::forecolor" "1 0.1 0.1 1" "1 0.1 0.1 0" "50" ;
+ transition "Text1b::forecolor" "1 0.1 0.1 1" "1 0.1 0.1 0" "50" ;
+ transition "Text1c::forecolor" "1 0.1 0.1 1" "1 0.1 0.1 0" "50" ;
+ transition "Text1d::forecolor" "1 0.1 0.1 1" "1 0.1 0.1 0" "50" ;
+ transition "Text1e::forecolor" "1 0.1 0.1 1" "1 0.1 0.1 0" "50" ;
+ }
+ onTime 0 {
+ transition "Button1::rect" "380 675 512 48" "380 405 512 48" "300" ;
+ transition "Button2::rect" "380 675 512 48" "380 465 512 48" "300" ;
+ transition "Button3::rect" "500 675 278 48" "500 525 278 48" "300" ;
+ transition "Button4::rect" "506 675 256 48" "506 585 256 48" "300" ;
+ transition "Button5::rect" "506 675 256 48" "506 645 256 48" "300" ;
+ transition "PopUp::matcolor" "1 1 1 1" "1 1 1 0" "100" ;
+ transition "PopUp::rect" "354 406.5 572 313.5" "354 660 572 60" "200" ;
+ }
+ onTime 50 {
+ set "Text1a::rect" "354 426 -572 60" ;
+ set "Text1b::rect" "354 471 -572 60" ;
+ set "Text1c::rect" "354 516 -572 60" ;
+ set "Text1d::rect" "354 561 -572 60" ;
+ set "Text1e::rect" "354 606 -572 60" ;
+ transition "Button2::matcolor" "1 1 1 0" "1 1 1 0.4" "100" ;
+ }
+ onTime 125 {
+ transition "Button3::matcolor" "1 1 1 0" "1 1 1 0.4" "100" ;
+ }
+ onTime 200 {
+ transition "Button4::matcolor" "1 1 1 0" "1 1 1 0.4" "100" ;
+ }
+ onTime 275 {
+ transition "Button5::matcolor" "1 1 1 0" "1 1 1 0.9" "100" ;
+ }
+ onTime 300 {
+ set "Button1::noevents" "0" ;
+ set "Button2::noevents" "0" ;
+ set "Button3::noevents" "0" ;
+ set "Button4::noevents" "0" ;
+ set "Button5::noevents" "0" ;
+ }
+ }
+
+ windowDef Click5 {
+ notime 1
+
+ onTime 200 {
+ set "Text5a::rect" "352 450 572 120" ;
+ transition "Text5a::forecolor" "1 0.1 0.1 0" "1 0.1 0.1 1" "50" ;
+ }
+ onTime 250 {
+ set "Text5b::rect" "420 577.5 200 120" ;
+ set "Text5b::noevents" "0" ;
+ transition "Text5b::forecolor" "1 0.1 0.1 0" "1 0.1 0.1 1" "50" ;
+ }
+ onTime 300 {
+ set "Text5c::rect" "660 577.5 200 120" ;
+ set "Text5c::noevents" "0" ;
+ transition "Text5c::forecolor" "1 0.1 0.1 0" "1 0.1 0.1 1" "50" ;
+ }
+ }
+
+ windowDef Main5 {
+ notime 1
+
+ onTime 0 {
+ set "Text5b::noevents" "1" ;
+ set "Text5c::noevents" "1" ;
+ transition "Text5a::forecolor" "1 0.1 0.1 1" "1 0.1 0.1 0" "50" ;
+ transition "Text5b::forecolor" "1 0.1 0.1 1" "1 0.1 0.1 0" "50" ;
+ transition "Text5c::forecolor" "1 0.1 0.1 1" "1 0.1 0.1 0" "50" ;
+ }
+ onTime 0 {
+ transition "Button1::rect" "380 675 512 48" "380 405 512 48" "300" ;
+ transition "Button2::rect" "380 675 512 48" "380 465 512 48" "300" ;
+ transition "Button3::rect" "500 675 278 48" "500 525 278 48" "300" ;
+ transition "Button4::rect" "506 675 256 48" "506 585 256 48" "300" ;
+ transition "Button5::rect" "506 675 256 48" "506 645 256 48" "300" ;
+ transition "PopUp::matcolor" "1 1 1 1" "1 1 1 0" "100" ;
+ transition "PopUp::rect" "354 406.5 572 313.5" "354 660 572 60" "200" ;
+ }
+ onTime 50 {
+ set "Text5a::rect" "352 450 -572 120" ;
+ set "Text5b::rect" "420 577.5 -200 120" ;
+ set "Text5c::rect" "660 577.5 -200 120" ;
+ transition "Button1::matcolor" "1 1 1 0" "1 1 1 0.9" "100" ;
+ }
+ onTime 125 {
+ transition "Button2::matcolor" "1 1 1 0" "1 1 1 0.4" "100" ;
+ }
+ onTime 200 {
+ transition "Button3::matcolor" "1 1 1 0" "1 1 1 0.4" "100" ;
+ }
+ onTime 275 {
+ transition "Button4::matcolor" "1 1 1 0" "1 1 1 0.4" "100" ;
+ }
+ onTime 300 {
+ set "Button1::noevents" "0" ;
+ set "Button2::noevents" "0" ;
+ set "Button3::noevents" "0" ;
+ set "Button4::noevents" "0" ;
+ set "Button5::noevents" "0" ;
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/neo/doomdll.vcxproj.user b/neo/doomdll.vcxproj.user
index d06734bf..785d20f2 100644
--- a/neo/doomdll.vcxproj.user
+++ b/neo/doomdll.vcxproj.user
@@ -15,9 +15,9 @@
D:\projects\Doom3\Doom3.exe
WindowsLocalDebugger
- +set r_fullscreen 0 +set r_mode 6
+ +set r_fullscreen 0 +set r_mode 1
D:\projects\Doom3
- +set r_fullscreen 1 +set r_mode 6|+set r_fullscreen 0 +set r_mode 6|
+ +set r_fullscreen 0 +set r_mode 6|+set r_fullscreen 1 +set r_mode 6|+set r_fullscreen 1 +set r_mode 1|+set r_fullscreen 0 +set r_mode 1|
D:\projects\Doom3\Doom3.exe
diff --git a/neo/framework/Common.cpp b/neo/framework/Common.cpp
index a21f4969..e16179a5 100644
--- a/neo/framework/Common.cpp
+++ b/neo/framework/Common.cpp
@@ -2430,7 +2430,7 @@ void idCommonLocal::PrintLoadingMessage( const char *msg ) {
renderSystem->BeginFrame( renderSystem->GetScreenWidth(), renderSystem->GetScreenHeight() );
renderSystem->DrawStretchPic( 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, 0, 1, 1, declManager->FindMaterial( "splashScreen" ) );
int len = strlen( msg );
- renderSystem->DrawSmallStringExt( ( 640 - len * SMALLCHAR_WIDTH ) / 2, 410, msg, idVec4( 0.0f, 0.81f, 0.94f, 1.0f ), true, declManager->FindMaterial( "textures/bigchars" ) );
+ // renderSystem->DrawSmallStringExt( ( SCREEN_WIDTH - len * SMALLCHAR_WIDTH ) / 2, SCREEN_HEIGHT - 70, msg, idVec4( 0.0f, 0.81f, 0.94f, 1.0f ), true, declManager->FindMaterial( "textures/bigchars" ) );
renderSystem->EndFrame( NULL, NULL );
}
diff --git a/neo/framework/Console.cpp b/neo/framework/Console.cpp
index 4ff098f0..84a7bedd 100644
--- a/neo/framework/Console.cpp
+++ b/neo/framework/Console.cpp
@@ -211,7 +211,7 @@ float SCR_DrawFPS( float y ) {
s = va( "%ifps", fps );
w = strlen( s ) * BIGCHAR_WIDTH;
- renderSystem->DrawBigStringExt( 635 - w, idMath::FtoiFast( y ) + 2, s, colorWhite, true, localConsole.charSetShader);
+ renderSystem->DrawBigStringExt( (SCREEN_WIDTH - 5.0f) - w, idMath::FtoiFast(y) + 2, s, colorWhite, true, localConsole.charSetShader);
}
return y + BIGCHAR_HEIGHT + 4;
diff --git a/neo/framework/Session.cpp b/neo/framework/Session.cpp
index aa443ee7..b709e3b7 100644
--- a/neo/framework/Session.cpp
+++ b/neo/framework/Session.cpp
@@ -464,7 +464,7 @@ void idSessionLocal::StartWipe( const char *_wipeMaterial, bool hold ) {
console->Close();
// render the current screen into a texture for the wipe model
- renderSystem->CropRenderSize( 640, 480, true );
+ renderSystem->CropRenderSize( SCREEN_WIDTH, SCREEN_HEIGHT, true );
Draw();
@@ -2230,7 +2230,7 @@ void idSessionLocal::DrawWipeModel() {
float fade = ( float )( latchedTic - wipeStartTic ) / ( wipeStopTic - wipeStartTic );
renderSystem->SetColor4( 1, 1, 1, fade );
- renderSystem->DrawStretchPic( 0, 0, 640, 480, 0, 0, 1, 1, wipeMaterial );
+ renderSystem->DrawStretchPic( 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, 0, 1, 1, wipeMaterial );
}
/*
@@ -2383,7 +2383,7 @@ void idSessionLocal::Draw() {
// clear the background, in case the tested gui is transparent
// NOTE that you can't use this for aviGame recording, it will tick at real com_frameTime between screenshots..
renderSystem->SetColor( colorBlack );
- renderSystem->DrawStretchPic( 0, 0, 640, 480, 0, 0, 1, 1, declManager->FindMaterial( "_white" ) );
+ renderSystem->DrawStretchPic( 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, 0, 1, 1, declManager->FindMaterial( "_white" ) );
guiTest->Redraw( com_frameTime );
} else if ( guiActive && !guiActive->State().GetBool( "gameDraw" ) ) {
@@ -2413,7 +2413,7 @@ void idSessionLocal::Draw() {
}
if ( !gameDraw ) {
renderSystem->SetColor( colorBlack );
- renderSystem->DrawStretchPic( 0, 0, 640, 480, 0, 0, 1, 1, declManager->FindMaterial( "_white" ) );
+ renderSystem->DrawStretchPic( 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, 0, 1, 1, declManager->FindMaterial( "_white" ) );
}
// save off the 2D drawing from the game
diff --git a/neo/game/Game_local.cpp b/neo/game/Game_local.cpp
index 370c0ee5..b2f6297d 100644
--- a/neo/game/Game_local.cpp
+++ b/neo/game/Game_local.cpp
@@ -2399,18 +2399,12 @@ void idGameLocal::CalcFov( float base_fov, float &fov_x, float &fov_y ) const {
switch( r_aspectRatio.GetInteger() ) {
default :
case 0 :
- // 4:3
- fov_x = base_fov;
- return;
- break;
-
- case 1 :
// 16:9
ratio_x = 16.0f;
ratio_y = 9.0f;
break;
- case 2 :
+ case 1 :
// 16:10
ratio_x = 16.0f;
ratio_y = 10.0f;
@@ -4364,5 +4358,7 @@ void idGameLocal::SwitchTeam( int clientNum, int team ) {
idGameLocal::GetMapLoadingGUI
===============
*/
-void idGameLocal::GetMapLoadingGUI( char gui[ MAX_STRING_CHARS ] ) { }
+void idGameLocal::GetMapLoadingGUI( char gui[ MAX_STRING_CHARS ] ) {
+ sprintf(gui, "guis/loadscreenbeta.gui");
+}
diff --git a/neo/game/PlayerView.cpp b/neo/game/PlayerView.cpp
index 19d4499e..174303ca 100644
--- a/neo/game/PlayerView.cpp
+++ b/neo/game/PlayerView.cpp
@@ -479,7 +479,7 @@ void idPlayerView::SingleView( idUserInterface *hud, const renderView_t *view )
if ( armorPulse > 0.0f && armorPulse < 1.0f ) {
renderSystem->SetColor4( 1, 1, 1, 1.0 - armorPulse );
- renderSystem->DrawStretchPic( 0, 0, 640, 480, 0, 0, 1, 1, armorMaterial );
+ renderSystem->DrawStretchPic( 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, 0, 1, 1, armorMaterial );
}
@@ -500,7 +500,7 @@ void idPlayerView::SingleView( idUserInterface *hud, const renderView_t *view )
if ( alpha < 1.0f ) {
renderSystem->SetColor4( ( player->health <= 0.0f ) ? MS2SEC( gameLocal.time ) : lastDamageTime, 1.0f, 1.0f, ( player->health <= 0.0f ) ? 0.0f : alpha );
- renderSystem->DrawStretchPic( 0.0f, 0.0f, 640.0f, 480.0f, 0.0f, 0.0f, 1.0f, 1.0f, tunnelMaterial );
+ renderSystem->DrawStretchPic( 0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT, 0.0f, 0.0f, 1.0f, 1.0f, tunnelMaterial );
}
if ( player->PowerUpActive(BERSERK) ) {
@@ -509,13 +509,13 @@ void idPlayerView::SingleView( idUserInterface *hud, const renderView_t *view )
// start fading if within 10 seconds of going away
alpha = (berserkTime < 10000) ? (float)berserkTime / 10000 : 1.0f;
renderSystem->SetColor4( 1.0f, 1.0f, 1.0f, alpha );
- renderSystem->DrawStretchPic( 0.0f, 0.0f, 640.0f, 480.0f, 0.0f, 0.0f, 1.0f, 1.0f, berserkMaterial );
+ renderSystem->DrawStretchPic( 0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT, 0.0f, 0.0f, 1.0f, 1.0f, berserkMaterial );
}
}
if ( bfgVision ) {
renderSystem->SetColor4( 1.0f, 1.0f, 1.0f, 1.0f );
- renderSystem->DrawStretchPic( 0.0f, 0.0f, 640.0f, 480.0f, 0.0f, 0.0f, 1.0f, 1.0f, bfgMaterial );
+ renderSystem->DrawStretchPic( 0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT, 0.0f, 0.0f, 1.0f, 1.0f, bfgMaterial );
}
}
@@ -528,7 +528,7 @@ void idPlayerView::SingleView( idUserInterface *hud, const renderView_t *view )
g_testPostProcess.SetString( "" );
} else {
renderSystem->SetColor4( 1.0f, 1.0f, 1.0f, 1.0f );
- renderSystem->DrawStretchPic( 0.0f, 0.0f, 640.0f, 480.0f, 0.0f, 0.0f, 1.0f, 1.0f, mtr );
+ renderSystem->DrawStretchPic( 0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT, 0.0f, 0.0f, 1.0f, 1.0f, mtr );
}
}
}
@@ -657,7 +657,7 @@ void idPlayerView::ScreenFade() {
if ( fadeColor[ 3 ] != 0.0f ) {
renderSystem->SetColor4( fadeColor[ 0 ], fadeColor[ 1 ], fadeColor[ 2 ], fadeColor[ 3 ] );
- renderSystem->DrawStretchPic( 0, 0, 640, 480, 0, 0, 1, 1, declManager->FindMaterial( "_white" ) );
+ renderSystem->DrawStretchPic( 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, 0, 1, 1, declManager->FindMaterial( "_white" ) );
}
}
@@ -681,7 +681,7 @@ void idPlayerView::InfluenceVision( idUserInterface *hud, const renderView_t *vi
SingleView( hud, view );
renderSystem->CaptureRenderToImage( "_currentRender" );
renderSystem->SetColor4( 1.0f, 1.0f, 1.0f, pct );
- renderSystem->DrawStretchPic( 0.0f, 0.0f, 640.0f, 480.0f, 0.0f, 0.0f, 1.0f, 1.0f, player->GetInfluenceMaterial() );
+ renderSystem->DrawStretchPic( 0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT, 0.0f, 0.0f, 1.0f, 1.0f, player->GetInfluenceMaterial() );
} else if ( player->GetInfluenceEntity() == NULL ) {
SingleView( hud, view );
return;
diff --git a/neo/renderer/DeviceContext.h b/neo/renderer/DeviceContext.h
index 030964c2..822876f1 100644
--- a/neo/renderer/DeviceContext.h
+++ b/neo/renderer/DeviceContext.h
@@ -32,8 +32,8 @@ If you have questions concerning this license or the applicable additional terms
// device context support for gui stuff
//
-const int VIRTUAL_WIDTH = 640;
-const int VIRTUAL_HEIGHT = 480;
+const int VIRTUAL_WIDTH = SCREEN_WIDTH;
+const int VIRTUAL_HEIGHT = SCREEN_HEIGHT;
const int BLINK_DIVISOR = 200;
class idDeviceContext {
diff --git a/neo/renderer/GuiModel.cpp b/neo/renderer/GuiModel.cpp
index 7c886f7d..06c41e3b 100644
--- a/neo/renderer/GuiModel.cpp
+++ b/neo/renderer/GuiModel.cpp
@@ -265,8 +265,8 @@ void idGuiModel::EmitFullScreen( void ) {
viewDef->floatTime = tr.frameShaderTime;
// glOrtho( 0, 640, 480, 0, 0, 1 ); // always assume 640x480 virtual coordinates
- viewDef->projectionMatrix[0] = 2.0f / 640.0f;
- viewDef->projectionMatrix[5] = -2.0f / 480.0f;
+ viewDef->projectionMatrix[0] = 2.0f / SCREEN_WIDTH;
+ viewDef->projectionMatrix[5] = -2.0f / SCREEN_HEIGHT;
viewDef->projectionMatrix[10] = -2.0f / 1.0f;
viewDef->projectionMatrix[12] = -1.0f;
viewDef->projectionMatrix[13] = 1.0f;
@@ -479,13 +479,13 @@ void idGuiModel::DrawStretchPic( float x, float y, float w, float h, float s1, f
h += y;
y = 0;
}
- if ( x + w > 640 ) {
- s2 -= ( s2 - s1 ) * ( x + w - 640 ) / w;
- w = 640 - x;
+ if ( x + w > SCREEN_WIDTH ) {
+ s2 -= ( s2 - s1 ) * ( x + w - SCREEN_WIDTH) / w;
+ w = SCREEN_WIDTH - x;
}
- if ( y + h > 480 ) {
- t2 -= ( t2 - t1 ) * ( y + h - 480 ) / h;
- h = 480 - y;
+ if ( y + h > SCREEN_HEIGHT) {
+ t2 -= ( t2 - t1 ) * ( y + h - SCREEN_HEIGHT ) / h;
+ h = SCREEN_HEIGHT - y;
}
if ( w <= 0 || h <= 0 ) {
@@ -555,7 +555,7 @@ void idGuiModel::DrawStretchPic( float x, float y, float w, float h, float s1, f
verts[3].tangents[1][1] = 1;
verts[3].tangents[1][2] = 0;
- DrawStretchPic( &verts[0], &indexes[0], 4, 6, hShader, false, 0.0f, 0.0f, 640.0f, 480.0f );
+ DrawStretchPic( &verts[0], &indexes[0], 4, 6, hShader, false, 0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT);
}
/*
diff --git a/neo/renderer/GuiModel.h b/neo/renderer/GuiModel.h
index 54eae89d..341fbae9 100644
--- a/neo/renderer/GuiModel.h
+++ b/neo/renderer/GuiModel.h
@@ -51,7 +51,7 @@ public:
// these calls are forwarded from the renderer
void SetColor( float r, float g, float b, float a );
void DrawStretchPic( const idDrawVert *verts, const glIndex_t *indexes, int vertCount, int indexCount, const idMaterial *hShader,
- bool clip = true, float min_x = 0.0f, float min_y = 0.0f, float max_x = 640.0f, float max_y = 480.0f );
+ bool clip = true, float min_x = 0.0f, float min_y = 0.0f, float max_x = SCREEN_WIDTH, float max_y = SCREEN_HEIGHT );
void DrawStretchPic( float x, float y, float w, float h,
float s1, float t1, float s2, float t2, const idMaterial *hShader);
void DrawStretchTri ( idVec2 p1, idVec2 p2, idVec2 p3, idVec2 t1, idVec2 t2, idVec2 t3, const idMaterial *material );
diff --git a/neo/renderer/Image_load.cpp b/neo/renderer/Image_load.cpp
index f6a5056b..bc762610 100644
--- a/neo/renderer/Image_load.cpp
+++ b/neo/renderer/Image_load.cpp
@@ -480,8 +480,8 @@ void idImage::GenerateImage( const byte *pic, int width, int height,
}
// make sure it is a power of 2
- scaled_width = MakePowerOfTwo( width );
- scaled_height = MakePowerOfTwo( height );
+ scaled_width = width;
+ scaled_height = height;
if ( scaled_width != width || scaled_height != height ) {
common->Error( "R_CreateImage: not a power of 2 image" );
diff --git a/neo/renderer/RenderSystem.h b/neo/renderer/RenderSystem.h
index a7a06898..dd4d79af 100644
--- a/neo/renderer/RenderSystem.h
+++ b/neo/renderer/RenderSystem.h
@@ -161,8 +161,8 @@ const int BIGCHAR_HEIGHT = 16;
// all drawing is done to a 640 x 480 virtual screen size
// and will be automatically scaled to the real resolution
-const int SCREEN_WIDTH = 640;
-const int SCREEN_HEIGHT = 480;
+const float SCREEN_WIDTH = 1280.0f;
+const float SCREEN_HEIGHT = 720.0f;
class idRenderWorld;
@@ -208,7 +208,7 @@ public:
virtual void SetColor4( float r, float g, float b, float a ) = 0;
virtual void DrawStretchPic( const idDrawVert *verts, const glIndex_t *indexes, int vertCount, int indexCount, const idMaterial *material,
- bool clip = true, float min_x = 0.0f, float min_y = 0.0f, float max_x = 640.0f, float max_y = 480.0f ) = 0;
+ bool clip = true, float min_x = 0.0f, float min_y = 0.0f, float max_x = SCREEN_WIDTH, float max_y = SCREEN_HEIGHT ) = 0;
virtual void DrawStretchPic( float x, float y, float w, float h, float s1, float t1, float s2, float t2, const idMaterial *material ) = 0;
virtual void DrawStretchTri ( idVec2 p1, idVec2 p2, idVec2 p3, idVec2 t1, idVec2 t2, idVec2 t3, const idMaterial *material ) = 0;
diff --git a/neo/renderer/RenderSystem_init.cpp b/neo/renderer/RenderSystem_init.cpp
index 656128aa..be8a0307 100644
--- a/neo/renderer/RenderSystem_init.cpp
+++ b/neo/renderer/RenderSystem_init.cpp
@@ -371,15 +371,8 @@ typedef struct vidmode_s {
} vidmode_t;
vidmode_t r_vidModes[] = {
- { "Mode 0: 320x240", 320, 240 },
- { "Mode 1: 400x300", 400, 300 },
- { "Mode 2: 512x384", 512, 384 },
- { "Mode 3: 640x480", 640, 480 },
- { "Mode 4: 800x600", 800, 600 },
- { "Mode 5: 1024x768", 1024, 768 },
- { "Mode 6: 1152x864", 1152, 864 },
- { "Mode 7: 1280x1024", 1280, 1024 },
- { "Mode 8: 1600x1200", 1600, 1200 },
+ { "Mode 0: 1280x720", 1280, 720 },
+ { "Mode 1: 1920x1080", 1920, 1080 }
};
static int s_numVidModes = ( sizeof( r_vidModes ) / sizeof( r_vidModes[0] ) );
@@ -394,7 +387,7 @@ static bool R_GetModeInfo( int *width, int *height, int mode ) {
return false;
}
if ( mode >= s_numVidModes ) {
- return false;
+ mode = 0;
}
if ( mode == -1 ) {
diff --git a/neo/renderer/tr_backend.cpp b/neo/renderer/tr_backend.cpp
index 7cb1bff8..7a36521b 100644
--- a/neo/renderer/tr_backend.cpp
+++ b/neo/renderer/tr_backend.cpp
@@ -428,7 +428,7 @@ void RB_SetGL2D( void ) {
}
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
- glOrtho( 0, 640, 480, 0, 0, 1 ); // always assume 640x480 virtual coordinates
+ glOrtho( 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, 0, 1 ); // always assume 640x480 virtual coordinates
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
diff --git a/neo/renderer/tr_guisurf.cpp b/neo/renderer/tr_guisurf.cpp
index 0e7ce1da..c7f69278 100644
--- a/neo/renderer/tr_guisurf.cpp
+++ b/neo/renderer/tr_guisurf.cpp
@@ -146,18 +146,18 @@ void R_RenderGuiSurf( idUserInterface *gui, drawSurf_t *drawSurf ) {
float guiModelMatrix[16];
float modelMatrix[16];
- guiModelMatrix[0] = axis[0][0] / 640.0;
- guiModelMatrix[4] = axis[1][0] / 480.0;
+ guiModelMatrix[0] = axis[0][0] / SCREEN_WIDTH;
+ guiModelMatrix[4] = axis[1][0] / SCREEN_HEIGHT;
guiModelMatrix[8] = axis[2][0];
guiModelMatrix[12] = origin[0];
- guiModelMatrix[1] = axis[0][1] / 640.0;
- guiModelMatrix[5] = axis[1][1] / 480.0;
+ guiModelMatrix[1] = axis[0][1] / SCREEN_WIDTH;
+ guiModelMatrix[5] = axis[1][1] / SCREEN_HEIGHT;
guiModelMatrix[9] = axis[2][1];
guiModelMatrix[13] = origin[1];
- guiModelMatrix[2] = axis[0][2] / 640.0;
- guiModelMatrix[6] = axis[1][2] / 480.0;
+ guiModelMatrix[2] = axis[0][2] / SCREEN_WIDTH;
+ guiModelMatrix[6] = axis[1][2] / SCREEN_HEIGHT;
guiModelMatrix[10] = axis[2][2];
guiModelMatrix[14] = origin[2];
diff --git a/neo/renderer/tr_local.h b/neo/renderer/tr_local.h
index 585ad7eb..aa8c4baa 100644
--- a/neo/renderer/tr_local.h
+++ b/neo/renderer/tr_local.h
@@ -704,7 +704,7 @@ public:
virtual void SetColor( const idVec4 &rgba );
virtual void SetColor4( float r, float g, float b, float a );
virtual void DrawStretchPic ( const idDrawVert *verts, const glIndex_t *indexes, int vertCount, int indexCount, const idMaterial *material,
- bool clip = true, float x = 0.0f, float y = 0.0f, float w = 640.0f, float h = 0.0f );
+ bool clip = true, float x = 0.0f, float y = 0.0f, float w = SCREEN_WIDTH, float h = 0.0f );
virtual void DrawStretchPic ( float x, float y, float w, float h, float s1, float t1, float s2, float t2, const idMaterial *material );
virtual void DrawStretchTri ( idVec2 p1, idVec2 p2, idVec2 p3, idVec2 t1, idVec2 t2, idVec2 t3, const idMaterial *material );
diff --git a/neo/sys/win32/win_glimp.cpp b/neo/sys/win32/win_glimp.cpp
index 2afb5c8c..5f72d4c2 100644
--- a/neo/sys/win32/win_glimp.cpp
+++ b/neo/sys/win32/win_glimp.cpp
@@ -271,8 +271,8 @@ static void GLW_GetWGLExtensionsWithFakeWindow( void ) {
hWnd = CreateWindow(WIN32_FAKE_WINDOW_CLASS_NAME, GAME_NAME,
WS_OVERLAPPEDWINDOW,
40, 40,
- 640,
- 480,
+ SCREEN_WIDTH,
+ SCREEN_HEIGHT,
NULL, NULL, win32.hInstance, NULL );
if ( !hWnd ) {
common->FatalError( "GLW_GetWGLExtensionsWithFakeWindow: Couldn't create fake window" );
diff --git a/neo/tools/guied/GEApp.cpp b/neo/tools/guied/GEApp.cpp
index 5d8f365c..06d917a1 100644
--- a/neo/tools/guied/GEApp.cpp
+++ b/neo/tools/guied/GEApp.cpp
@@ -1154,8 +1154,8 @@ bool rvGEApp::NewFile ( void )
WS_CHILD|WS_VISIBLE|WS_CLIPCHILDREN|WS_HSCROLL|WS_VSCROLL|WS_MAXIMIZE,
CW_USEDEFAULT,
CW_USEDEFAULT,
- 640,
- 480,
+ SCREEN_WIDTH,
+ SCREEN_HEIGHT,
mMDIClient,
mInstance,
(LONG)workspace );
@@ -1205,8 +1205,8 @@ bool rvGEApp::OpenFile ( const char* filename )
WS_CHILD|WS_VISIBLE|WS_CLIPCHILDREN|WS_HSCROLL|WS_VSCROLL|WS_MAXIMIZE,
CW_USEDEFAULT,
CW_USEDEFAULT,
- 640,
- 480,
+ SCREEN_WIDTH,
+ SCREEN_HEIGHT,
mMDIClient,
mInstance,
(LONG)workspace );
diff --git a/neo/tools/guied/GEWorkspaceFile.cpp b/neo/tools/guied/GEWorkspaceFile.cpp
index 0bb24877..ac012a45 100644
--- a/neo/tools/guied/GEWorkspaceFile.cpp
+++ b/neo/tools/guied/GEWorkspaceFile.cpp
@@ -258,7 +258,7 @@ bool rvGEWorkspace::NewFile ( void )
return false;
}
- empty = "windowDef Desktop { rect 0,0,640,480 }";
+ empty = "windowDef Desktop { rect 0,0,1280,720 }";
file->Write ( empty, empty.Length() );
fileSystem->CloseFile ( file );
diff --git a/neo/tools/radiant/CamWnd.cpp b/neo/tools/radiant/CamWnd.cpp
index 14440133..a0f3871c 100644
--- a/neo/tools/radiant/CamWnd.cpp
+++ b/neo/tools/radiant/CamWnd.cpp
@@ -46,6 +46,784 @@ static char THIS_FILE[] = __FILE__;
#endif
extern void DrawPathLines();
+extern qertrace_t Test_Ray(const idVec3& origin, const idVec3& dir, int flags);
+extern void Select_ShiftTexture(float x, float y);
+extern void Select_ScaleTexture(float x, float y);
+extern void Select_RotateTexture(float amt, bool absolute);
+
+/*
+========================
+Camera navigation extension
+
+All settings are read from radiant.ini, section [3d navigation]. The default
+style is 1 so existing camera behavior is unchanged until style=2 is enabled.
+========================
+*/
+enum {
+ CAMERA_NAV_TIMER_ID = 713,
+ CAMERA_NAV_INFO_NONE = 0,
+ CAMERA_NAV_INFO_ENTITY = 1,
+ CAMERA_NAV_INFO_MATERIAL = 2,
+ CAMERA_NAV_MAX_INFO_LINES = 32
+};
+
+struct cameraNavConfig_t {
+ bool loaded;
+ int style;
+ int forwardKey;
+ int backKey;
+ int upKey;
+ int downKey;
+ int leftKey;
+ int rightKey;
+ int modifier1Key;
+ int modifier2Key;
+ bool invertPitch;
+ bool invertZTrans;
+ float capsLockScale;
+ int reticleMode;
+ float reticleScale;
+ idVec3 reticleColor;
+ int teleportKey;
+ int infoDisplayKey;
+ int lockTargetKey;
+ bool invertLockPitch;
+ bool invertLockYaw;
+ int texPositionKey;
+ int texScaleKey;
+ int texRotateKey;
+};
+
+struct cameraNavState_t {
+ CCamWnd* cam;
+ bool active;
+ bool lockActive;
+ int infoMode;
+ CPoint cursorAnchor;
+ int lastTime;
+ idVec3 lockTarget;
+ float lockDistance;
+ float lockPitch;
+ float lockYaw;
+};
+
+static cameraNavConfig_t s_cameraNavConfig;
+static cameraNavState_t s_cameraNavState;
+
+static void CameraNav_GetIniPath(char* path, int pathSize) {
+ if (pathSize <= 0) {
+ return;
+ }
+
+ path[0] = '\0';
+ DWORD len = GetModuleFileName(NULL, path, pathSize);
+ if (len == 0 || len >= (DWORD)pathSize) {
+ strncpy(path, "radiant.ini", pathSize - 1);
+ path[pathSize - 1] = '\0';
+ return;
+ }
+
+ char* slash = strrchr(path, '\\');
+ char* slash2 = strrchr(path, '/');
+ if (slash2 && (!slash || slash2 > slash)) {
+ slash = slash2;
+ }
+ if (slash) {
+ strncpy(slash + 1, "radiant.ini", pathSize - (int)(slash + 1 - path) - 1);
+ path[pathSize - 1] = '\0';
+ }
+ else {
+ strncpy(path, "radiant.ini", pathSize - 1);
+ path[pathSize - 1] = '\0';
+ }
+}
+
+static void CameraNav_NormalizeKeyName(const char* in, char* out, int outSize) {
+ if (outSize <= 0) {
+ return;
+ }
+
+ out[0] = '\0';
+ if (!in) {
+ return;
+ }
+
+ int outPos = 0;
+ while (*in && outPos < outSize - 1) {
+ unsigned char c = (unsigned char)*in++;
+ if (c == ' ' || c == '\t' || c == '_' || c == '-') {
+ continue;
+ }
+ out[outPos++] = (char)tolower(c);
+ }
+ out[outPos] = '\0';
+}
+
+static int CameraNav_ParseKeyName(const char* text) {
+ char keyName[64];
+ CameraNav_NormalizeKeyName(text, keyName, sizeof(keyName));
+
+ if (keyName[0] == '\0' || !stricmp(keyName, "none") || !stricmp(keyName, "0")) {
+ return 0;
+ }
+
+ if (keyName[1] == '\0') {
+ char c = keyName[0];
+ if (c >= 'a' && c <= 'z') {
+ return c - 'a' + 'A';
+ }
+ if (c >= '0' && c <= '9') {
+ return c;
+ }
+ }
+
+ if (!stricmp(keyName, "space")) return VK_SPACE;
+ if (!stricmp(keyName, "backspace")) return VK_BACK;
+ if (!stricmp(keyName, "escape") || !stricmp(keyName, "esc")) return VK_ESCAPE;
+ if (!stricmp(keyName, "end")) return VK_END;
+ if (!stricmp(keyName, "insert") || !stricmp(keyName, "ins")) return VK_INSERT;
+ if (!stricmp(keyName, "delete") || !stricmp(keyName, "del")) return VK_DELETE;
+ if (!stricmp(keyName, "pageup") || !stricmp(keyName, "pgup")) return VK_PRIOR;
+ if (!stricmp(keyName, "pagedown") || !stricmp(keyName, "pgdn")) return VK_NEXT;
+ if (!stricmp(keyName, "up")) return VK_UP;
+ if (!stricmp(keyName, "down")) return VK_DOWN;
+ if (!stricmp(keyName, "left")) return VK_LEFT;
+ if (!stricmp(keyName, "right")) return VK_RIGHT;
+ if (!stricmp(keyName, "tab")) return VK_TAB;
+ if (!stricmp(keyName, "return") || !stricmp(keyName, "enter")) return VK_RETURN;
+ if (!stricmp(keyName, "comma")) return VK_OEM_COMMA;
+ if (!stricmp(keyName, "period")) return VK_OEM_PERIOD;
+ if (!stricmp(keyName, "plus")) return VK_ADD;
+ if (!stricmp(keyName, "multiply")) return VK_MULTIPLY;
+ if (!stricmp(keyName, "subtract") || !stricmp(keyName, "minus")) return VK_SUBTRACT;
+ if (!stricmp(keyName, "shift")) return VK_SHIFT;
+ if (!stricmp(keyName, "ctrl") || !stricmp(keyName, "control")) return VK_CONTROL;
+ if (!stricmp(keyName, "alt")) return VK_MENU;
+ if (!stricmp(keyName, "capslock")) return VK_CAPITAL;
+
+ if (keyName[0] == 'f') {
+ int n = atoi(keyName + 1);
+ if (n >= 1 && n <= 12) {
+ return VK_F1 + n - 1;
+ }
+ }
+ if (!strnicmp(keyName, "numpad", 6)) {
+ int n = atoi(keyName + 6);
+ if (n >= 0 && n <= 9) {
+ return VK_NUMPAD0 + n;
+ }
+ }
+
+ return 0;
+}
+
+static int CameraNav_ReadKey(const char* iniPath, const char* keyName, const char* defaultValue) {
+ char value[64];
+ GetPrivateProfileString("3d navigation", keyName, defaultValue ? defaultValue : "", value, sizeof(value), iniPath);
+ return CameraNav_ParseKeyName(value);
+}
+
+static float CameraNav_ReadFloat(const char* iniPath, const char* keyName, const char* defaultValue) {
+ char value[64];
+ GetPrivateProfileString("3d navigation", keyName, defaultValue, value, sizeof(value), iniPath);
+ return (float)atof(value);
+}
+
+static void CameraNav_ReadColor(const char* iniPath, const char* keyName, const char* defaultValue, idVec3& color) {
+ char value[128];
+ float r = 50.0f;
+ float g = 230.0f;
+ float b = 50.0f;
+
+ GetPrivateProfileString("3d navigation", keyName, defaultValue, value, sizeof(value), iniPath);
+ if (sscanf(value, "%f%*[ ,]%f%*[ ,]%f", &r, &g, &b) != 3) {
+ r = 50.0f;
+ g = 230.0f;
+ b = 50.0f;
+ }
+
+ color[0] = (r > 1.0f) ? r / 255.0f : r;
+ color[1] = (g > 1.0f) ? g / 255.0f : g;
+ color[2] = (b > 1.0f) ? b / 255.0f : b;
+}
+
+static cameraNavConfig_t& CameraNav_Config() {
+ cameraNavConfig_t& cfg = s_cameraNavConfig;
+ if (cfg.loaded) {
+ return cfg;
+ }
+
+ char iniPath[MAX_PATH];
+ CameraNav_GetIniPath(iniPath, sizeof(iniPath));
+
+ memset(&cfg, 0, sizeof(cfg));
+ cfg.loaded = true;
+ cfg.style = GetPrivateProfileInt("3d navigation", "style", 1, iniPath);
+ cfg.forwardKey = CameraNav_ReadKey(iniPath, "forward", "w");
+ cfg.backKey = CameraNav_ReadKey(iniPath, "back", "s");
+ cfg.upKey = CameraNav_ReadKey(iniPath, "up", "space");
+ cfg.downKey = CameraNav_ReadKey(iniPath, "down", "shift");
+ cfg.leftKey = CameraNav_ReadKey(iniPath, "left", "a");
+ cfg.rightKey = CameraNav_ReadKey(iniPath, "right", "d");
+ cfg.modifier1Key = CameraNav_ReadKey(iniPath, "modifier1", "q");
+ cfg.modifier2Key = CameraNav_ReadKey(iniPath, "modifier2", "e");
+ cfg.invertPitch = GetPrivateProfileInt("3d navigation", "invertpitch", 0, iniPath) != 0;
+ cfg.invertZTrans = GetPrivateProfileInt("3d navigation", "invertztrans", 0, iniPath) != 0;
+ cfg.capsLockScale = CameraNav_ReadFloat(iniPath, "capslockscale", "1");
+ if (cfg.capsLockScale <= 0.0f) {
+ cfg.capsLockScale = 1.0f;
+ }
+ cfg.reticleMode = GetPrivateProfileInt("3d navigation", "reticlemode", 0, iniPath);
+ cfg.reticleScale = CameraNav_ReadFloat(iniPath, "reticlescale", "1");
+ if (cfg.reticleScale <= 0.0f) {
+ cfg.reticleScale = 1.0f;
+ }
+ CameraNav_ReadColor(iniPath, "reticlecolor", "50 230 50", cfg.reticleColor);
+
+ // Extra navigation features are opt-in. They only bind when a key is present
+ // in radiant.ini, which avoids stealing existing editor shortcuts by default.
+ cfg.teleportKey = CameraNav_ReadKey(iniPath, "teleport", "");
+ cfg.infoDisplayKey = CameraNav_ReadKey(iniPath, "infodisplay", "");
+ cfg.lockTargetKey = CameraNav_ReadKey(iniPath, "locktarget", "");
+ cfg.invertLockPitch = GetPrivateProfileInt("3d navigation", "invertlockpitch", 0, iniPath) != 0;
+ cfg.invertLockYaw = GetPrivateProfileInt("3d navigation", "invertlockyaw", 0, iniPath) != 0;
+ cfg.texPositionKey = CameraNav_ReadKey(iniPath, "texposition", "");
+ cfg.texScaleKey = CameraNav_ReadKey(iniPath, "texscale", "");
+ cfg.texRotateKey = CameraNav_ReadKey(iniPath, "texrotate", "");
+
+ return cfg;
+}
+
+static bool CameraNav_KeyIsDown(int key) {
+ return key != 0 && (GetAsyncKeyState(key) & 0x8000) != 0;
+}
+
+static float CameraNav_CapsScale() {
+ cameraNavConfig_t& cfg = CameraNav_Config();
+ return (GetKeyState(VK_CAPITAL) & 1) ? cfg.capsLockScale : 1.0f;
+}
+
+static float CameraNav_MoveSpeed() {
+ float speed = (float)g_PrefsDlg.m_nMoveSpeed;
+ if (speed <= 0.0f) {
+ speed = 64.0f;
+ }
+ return speed * CameraNav_CapsScale();
+}
+
+static void CameraNav_GetAxes(const camera_t& camera, idVec3& forward, idVec3& right, idVec3& up) {
+ float yaw = camera.angles[YAW] * idMath::M_DEG2RAD;
+ float pitch = -camera.angles[PITCH] * idMath::M_DEG2RAD;
+ float sy = sin(yaw);
+ float cy = cos(yaw);
+ float sp = sin(pitch);
+ float cp = cos(pitch);
+
+ forward[0] = cp * cy;
+ forward[1] = cp * sy;
+ forward[2] = -sp;
+ forward.Normalize();
+
+ right[0] = sy;
+ right[1] = -cy;
+ right[2] = 0.0f;
+ right.Normalize();
+
+ up[0] = right[1] * forward[2] - right[2] * forward[1];
+ up[1] = right[2] * forward[0] - right[0] * forward[2];
+ up[2] = right[0] * forward[1] - right[1] * forward[0];
+ up.Normalize();
+}
+
+static idVec3 CameraNav_ForwardFromAngles(float pitchDegrees, float yawDegrees) {
+ camera_t temp;
+ memset(&temp, 0, sizeof(temp));
+ temp.angles[PITCH] = pitchDegrees;
+ temp.angles[YAW] = yawDegrees;
+ idVec3 forward, right, up;
+ CameraNav_GetAxes(temp, forward, right, up);
+ return forward;
+}
+
+static void CameraNav_UpdateViews() {
+ int nUpdate = (g_PrefsDlg.m_bCamXYUpdate) ? (W_CAMERA | W_XY) : W_CAMERA;
+ Sys_UpdateWindows(nUpdate);
+ if (g_pParentWnd) {
+ g_pParentWnd->PostMessage(WM_TIMER, 0, 0);
+ }
+}
+
+static bool CameraNav_IsActive(CCamWnd* cam) {
+ return s_cameraNavState.active && s_cameraNavState.cam == cam;
+}
+
+static bool CameraNav_TraceCenter(CCamWnd* cam, qertrace_t& trace, idVec3* hitPoint = NULL, idVec3* outDir = NULL) {
+ camera_t& camera = cam->Camera();
+ idVec3 forward, right, up;
+ CameraNav_GetAxes(camera, forward, right, up);
+ trace = Test_Ray(camera.origin, forward, 0);
+
+ if (outDir) {
+ *outDir = forward;
+ }
+ if (!trace.brush || trace.dist <= 0.0f || trace.dist >= HUGE_DISTANCE) {
+ return false;
+ }
+ if (hitPoint) {
+ *hitPoint = camera.origin + forward * trace.dist;
+ }
+ return true;
+}
+
+static void CameraNav_Stop(CCamWnd* cam) {
+ if (!CameraNav_IsActive(cam)) {
+ return;
+ }
+
+ cam->KillTimer(CAMERA_NAV_TIMER_ID);
+ if (::GetCapture() == cam->GetSafeHwnd()) {
+ ::ReleaseCapture();
+ }
+ s_cameraNavState.active = false;
+ s_cameraNavState.lockActive = false;
+ Sys_UpdateWindows(W_CAMERA);
+}
+
+static bool CameraNav_Begin(CCamWnd* cam) {
+ cameraNavConfig_t& cfg = CameraNav_Config();
+ if (cfg.style != 2) {
+ return false;
+ }
+
+ if (s_cameraNavState.active && s_cameraNavState.cam != cam) {
+ CameraNav_Stop(s_cameraNavState.cam);
+ }
+
+ memset(&s_cameraNavState, 0, sizeof(s_cameraNavState));
+ s_cameraNavState.cam = cam;
+ s_cameraNavState.active = true;
+ s_cameraNavState.lastTime = Sys_Milliseconds();
+ GetCursorPos(&s_cameraNavState.cursorAnchor);
+
+ cam->SetFocus();
+ cam->SetCapture();
+ cam->SetTimer(CAMERA_NAV_TIMER_ID, 10, NULL);
+ Sys_UpdateWindows(W_CAMERA);
+ return true;
+}
+
+static void CameraNav_ClampPitch(float& pitch) {
+ if (pitch > 89.0f) {
+ pitch = 89.0f;
+ }
+ else if (pitch < -89.0f) {
+ pitch = -89.0f;
+ }
+}
+
+static bool CameraNav_StartLock(CCamWnd* cam) {
+ qertrace_t trace;
+ idVec3 hit;
+ if (!CameraNav_TraceCenter(cam, trace, &hit)) {
+ return false;
+ }
+
+ camera_t& camera = cam->Camera();
+ s_cameraNavState.lockActive = true;
+ s_cameraNavState.lockTarget = hit;
+ s_cameraNavState.lockDistance = trace.dist;
+ if (s_cameraNavState.lockDistance < 16.0f) {
+ s_cameraNavState.lockDistance = 16.0f;
+ }
+ s_cameraNavState.lockPitch = camera.angles[PITCH];
+ s_cameraNavState.lockYaw = camera.angles[YAW];
+ return true;
+}
+
+static void CameraNav_ApplyLock(CCamWnd* cam) {
+ camera_t& camera = cam->Camera();
+ CameraNav_ClampPitch(s_cameraNavState.lockPitch);
+
+ idVec3 forward = CameraNav_ForwardFromAngles(s_cameraNavState.lockPitch, s_cameraNavState.lockYaw);
+ camera.origin = s_cameraNavState.lockTarget - forward * s_cameraNavState.lockDistance;
+ camera.angles[PITCH] = s_cameraNavState.lockPitch;
+ camera.angles[YAW] = s_cameraNavState.lockYaw;
+ camera.angles[ROLL] = 0.0f;
+}
+
+static void CameraNav_Teleport(CCamWnd* cam) {
+ qertrace_t trace;
+ idVec3 hit;
+ idVec3 dir;
+ if (!CameraNav_TraceCenter(cam, trace, &hit, &dir)) {
+ return;
+ }
+
+ camera_t& camera = cam->Camera();
+ float moveDist = trace.dist - 64.0f;
+ if (moveDist < 0.0f) {
+ moveDist = trace.dist * 0.5f;
+ }
+ camera.origin += dir * moveDist;
+ CameraNav_UpdateViews();
+}
+
+static bool CameraNav_IsMovementOrModifierKey(int key) {
+ cameraNavConfig_t& cfg = CameraNav_Config();
+ return key == cfg.forwardKey || key == cfg.backKey || key == cfg.upKey || key == cfg.downKey ||
+ key == cfg.leftKey || key == cfg.rightKey || key == cfg.modifier1Key || key == cfg.modifier2Key ||
+ key == cfg.texPositionKey || key == cfg.texScaleKey || key == cfg.texRotateKey;
+}
+
+static bool CameraNav_HandleKeyDown(CCamWnd* cam, UINT key) {
+ cameraNavConfig_t& cfg = CameraNav_Config();
+ if (cfg.style != 2 || !CameraNav_IsActive(cam)) {
+ return false;
+ }
+
+ if (cfg.infoDisplayKey && key == (UINT)cfg.infoDisplayKey) {
+ s_cameraNavState.infoMode = (s_cameraNavState.infoMode + 1) % 3;
+ Sys_UpdateWindows(W_CAMERA);
+ return true;
+ }
+ if (cfg.teleportKey && key == (UINT)cfg.teleportKey) {
+ CameraNav_Teleport(cam);
+ return true;
+ }
+ if (cfg.lockTargetKey && key == (UINT)cfg.lockTargetKey) {
+ CameraNav_StartLock(cam);
+ return true;
+ }
+ if (CameraNav_IsMovementOrModifierKey((int)key)) {
+ return true;
+ }
+
+ return false;
+}
+
+static bool CameraNav_HandleKeyUp(CCamWnd* cam, UINT key) {
+ cameraNavConfig_t& cfg = CameraNav_Config();
+ if (cfg.style != 2 || !CameraNav_IsActive(cam)) {
+ return false;
+ }
+
+ if (cfg.lockTargetKey && key == (UINT)cfg.lockTargetKey) {
+ s_cameraNavState.lockActive = false;
+ return true;
+ }
+ if (CameraNav_IsMovementOrModifierKey((int)key)) {
+ return true;
+ }
+ return false;
+}
+
+static bool CameraNav_Update(CCamWnd* cam) {
+ if (!CameraNav_IsActive(cam)) {
+ return false;
+ }
+
+ cameraNavConfig_t& cfg = CameraNav_Config();
+ int now = Sys_Milliseconds();
+ float dtime = (now - s_cameraNavState.lastTime) * 0.001f;
+ if (dtime <= 0.0f) {
+ dtime = 0.01f;
+ }
+ else if (dtime > 0.1f) {
+ dtime = 0.1f;
+ }
+ s_cameraNavState.lastTime = now;
+
+ if (cfg.lockTargetKey) {
+ if (CameraNav_KeyIsDown(cfg.lockTargetKey)) {
+ if (!s_cameraNavState.lockActive) {
+ CameraNav_StartLock(cam);
+ }
+ }
+ else if (s_cameraNavState.lockActive) {
+ s_cameraNavState.lockActive = false;
+ }
+ }
+
+ camera_t& camera = cam->Camera();
+ idVec3 forward, right, up;
+ CameraNav_GetAxes(camera, forward, right, up);
+
+ if (s_cameraNavState.lockActive) {
+ float zoom = 0.0f;
+ if (CameraNav_KeyIsDown(cfg.forwardKey)) {
+ zoom -= CameraNav_MoveSpeed() * dtime;
+ }
+ if (CameraNav_KeyIsDown(cfg.backKey)) {
+ zoom += CameraNav_MoveSpeed() * dtime;
+ }
+ if (zoom != 0.0f) {
+ s_cameraNavState.lockDistance += zoom;
+ if (s_cameraNavState.lockDistance < 16.0f) {
+ s_cameraNavState.lockDistance = 16.0f;
+ }
+ CameraNav_ApplyLock(cam);
+ CameraNav_UpdateViews();
+ }
+ return true;
+ }
+
+ idVec3 move;
+ move[0] = move[1] = move[2] = 0.0f;
+ if (CameraNav_KeyIsDown(cfg.forwardKey)) {
+ move += forward;
+ }
+ if (CameraNav_KeyIsDown(cfg.backKey)) {
+ move -= forward;
+ }
+ if (CameraNav_KeyIsDown(cfg.leftKey)) {
+ move -= right;
+ }
+ if (CameraNav_KeyIsDown(cfg.rightKey)) {
+ move += right;
+ }
+ if (CameraNav_KeyIsDown(cfg.upKey)) {
+ move[2] += 1.0f;
+ }
+ if (CameraNav_KeyIsDown(cfg.downKey)) {
+ move[2] -= 1.0f;
+ }
+
+ if (move.LengthSqr() > 0.0f) {
+ move.Normalize();
+ camera.origin += move * (CameraNav_MoveSpeed() * dtime);
+ CameraNav_UpdateViews();
+ }
+
+ return true;
+}
+
+static bool CameraNav_MouseMove(CCamWnd* cam) {
+ if (!CameraNav_IsActive(cam)) {
+ return false;
+ }
+
+ CPoint current;
+ GetCursorPos(¤t);
+ int dx = current.x - s_cameraNavState.cursorAnchor.x;
+ int dy = current.y - s_cameraNavState.cursorAnchor.y;
+ if (dx == 0 && dy == 0) {
+ return true;
+ }
+
+ cameraNavConfig_t& cfg = CameraNav_Config();
+ camera_t& camera = cam->Camera();
+ bool textureAdjusted = false;
+
+ if (cfg.texPositionKey && CameraNav_KeyIsDown(cfg.texPositionKey)) {
+ Select_ShiftTexture((float)dx, (float)-dy, false);
+ textureAdjusted = true;
+ }
+ else if (cfg.texScaleKey && CameraNav_KeyIsDown(cfg.texScaleKey)) {
+ Select_ScaleTexture((float)dx, (float)-dy, false);
+ textureAdjusted = true;
+ }
+ else if (cfg.texRotateKey && CameraNav_KeyIsDown(cfg.texRotateKey)) {
+ Select_RotateTexture((float)dy, false);
+ textureAdjusted = true;
+ }
+
+ if (textureAdjusted) {
+ SetCursorPos(s_cameraNavState.cursorAnchor.x, s_cameraNavState.cursorAnchor.y);
+ Sys_UpdateWindows(W_ALL);
+ return true;
+ }
+
+ if (s_cameraNavState.lockActive) {
+ float yawSign = cfg.invertLockYaw ? 1.0f : -1.0f;
+ float pitchSign = cfg.invertLockPitch ? 1.0f : -1.0f;
+ s_cameraNavState.lockYaw += dx * 0.25f * yawSign;
+ s_cameraNavState.lockPitch += dy * 0.25f * pitchSign;
+ CameraNav_ApplyLock(cam);
+ }
+ else if (CameraNav_KeyIsDown(cfg.modifier1Key)) {
+ idVec3 forward, right, up;
+ CameraNav_GetAxes(camera, forward, right, up);
+ float scale = CameraNav_CapsScale();
+ float zMove = cfg.invertZTrans ? (float)dy : (float)-dy;
+ camera.origin += right * ((float)dx * scale);
+ camera.origin[2] += zMove * scale;
+ }
+ else if (CameraNav_KeyIsDown(cfg.modifier2Key)) {
+ idVec3 forward, right, up;
+ CameraNav_GetAxes(camera, forward, right, up);
+ float scale = CameraNav_CapsScale();
+ camera.origin += forward * ((float)-dy * scale);
+ camera.angles[YAW] -= (float)dx * 0.25f;
+ }
+ else {
+ float pitchSign = cfg.invertPitch ? 1.0f : -1.0f;
+ camera.angles[PITCH] += (float)dy * 0.25f * pitchSign;
+ camera.angles[YAW] -= (float)dx * 0.25f;
+ CameraNav_ClampPitch(camera.angles[PITCH]);
+ }
+
+ SetCursorPos(s_cameraNavState.cursorAnchor.x, s_cameraNavState.cursorAnchor.y);
+ CameraNav_UpdateViews();
+ return true;
+}
+
+static bool CameraNav_HandleMouseWheel(HWND hWnd, WPARAM wParam) {
+ CWnd* wnd = CWnd::FromHandlePermanent(hWnd);
+ CCamWnd* cam = DYNAMIC_DOWNCAST(CCamWnd, wnd);
+ if (!cam) {
+ return false;
+ }
+
+ short wheelDelta = (short)HIWORD(wParam);
+ if (wheelDelta == 0) {
+ return false;
+ }
+
+ camera_t& camera = cam->Camera();
+ idVec3 forward, right, up;
+ CameraNav_GetAxes(camera, forward, right, up);
+
+ float notches = (float)wheelDelta / 120.0f;
+ camera.origin += forward * (notches * CameraNav_MoveSpeed());
+ CameraNav_UpdateViews();
+ return true;
+}
+
+static const char* CameraNav_SurfaceTypeName(surfTypes_t type) {
+ switch (type)
+ {
+ case SURFTYPE_METAL: return "metal";
+ case SURFTYPE_STONE: return "stone";
+ case SURFTYPE_FLESH: return "flesh";
+ case SURFTYPE_WOOD: return "wood";
+ case SURFTYPE_CARDBOARD: return "cardboard";
+ case SURFTYPE_LIQUID: return "liquid";
+ case SURFTYPE_GLASS: return "glass";
+ case SURFTYPE_PLASTIC: return "plastic";
+ case SURFTYPE_RICOCHET: return "ricochet";
+ default: return "none";
+ }
+}
+
+static void CameraNav_AddLine(idStr* lines, int& numLines, const char* text) {
+ if (numLines >= CAMERA_NAV_MAX_INFO_LINES) {
+ return;
+ }
+ lines[numLines++] = text;
+}
+
+static void CameraNav_BuildEntityInfo(CCamWnd* cam, idStr* lines, int& numLines) {
+ qertrace_t trace;
+ if (!CameraNav_TraceCenter(cam, trace)) {
+ CameraNav_AddLine(lines, numLines, "Entity: ");
+ return;
+ }
+
+ entity_t* ent = trace.brush->owner;
+ CameraNav_AddLine(lines, numLines, "Entity");
+ CameraNav_AddLine(lines, numLines, va("class: %s", ValueForKey(ent, "classname")));
+ CameraNav_AddLine(lines, numLines, va("name: %s", ValueForKey(ent, "name")));
+
+ for (int i = 0; i < ent->epairs.GetNumKeyVals() && numLines < CAMERA_NAV_MAX_INFO_LINES; i++) {
+ const idKeyValue* kv = ent->epairs.GetKeyVal(i);
+ if (!kv) {
+ continue;
+ }
+ CameraNav_AddLine(lines, numLines, va("%s = %s", kv->GetKey().c_str(), kv->GetValue().c_str()));
+ }
+}
+
+static void CameraNav_BuildMaterialInfo(CCamWnd* cam, idStr* lines, int& numLines) {
+ qertrace_t trace;
+ if (!CameraNav_TraceCenter(cam, trace) || !trace.face || !trace.face->d_texture) {
+ CameraNav_AddLine(lines, numLines, "Material: ");
+ return;
+ }
+
+ const idMaterial* material = trace.face->d_texture;
+ CameraNav_AddLine(lines, numLines, "Material");
+ CameraNav_AddLine(lines, numLines, material->GetName());
+ CameraNav_AddLine(lines, numLines, va("size: %d x %d", material->GetImageWidth(), material->GetImageHeight()));
+ CameraNav_AddLine(lines, numLines, va("surface: %s", CameraNav_SurfaceTypeName(material->GetSurfaceType())));
+ CameraNav_AddLine(lines, numLines, va("content flags: 0x%08x", material->GetContentFlags()));
+ CameraNav_AddLine(lines, numLines, va("surface flags: 0x%08x", material->GetSurfaceFlags()));
+ CameraNav_AddLine(lines, numLines, va("stages: %d", material->GetNumStages()));
+ CameraNav_AddLine(lines, numLines, va("decl: %s:%d", material->GetFileName(), material->GetLineNum()));
+ if (material->GetDescription() && material->GetDescription()[0]) {
+ CameraNav_AddLine(lines, numLines, va("desc: %s", material->GetDescription()));
+ }
+}
+
+static void CameraNav_DrawOverlay(CCamWnd* cam) {
+ cameraNavConfig_t& cfg = CameraNav_Config();
+ camera_t& camera = cam->Camera();
+
+ bool drawReticle = (cfg.reticleMode == 2) || (cfg.reticleMode == 1 && CameraNav_IsActive(cam));
+ bool drawInfo = (s_cameraNavState.infoMode != CAMERA_NAV_INFO_NONE);
+ if (!drawReticle && !drawInfo) {
+ return;
+ }
+
+ glMatrixMode(GL_PROJECTION);
+ glPushMatrix();
+ glLoadIdentity();
+ glOrtho(0, camera.width, 0, camera.height, -1, 1);
+
+ glMatrixMode(GL_MODELVIEW);
+ glPushMatrix();
+ glLoadIdentity();
+
+ glDisable(GL_DEPTH_TEST);
+ glDisable(GL_LIGHTING);
+ glDisable(GL_BLEND);
+ glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+ globalImages->BindNull();
+
+ if (drawReticle) {
+ float cx = camera.width * 0.5f;
+ float cy = camera.height * 0.5f;
+ float size = 8.0f * cfg.reticleScale;
+ float gap = 3.0f * cfg.reticleScale;
+ glColor3fv(cfg.reticleColor.ToFloatPtr());
+ glBegin(GL_LINES);
+ glVertex2f(cx - size, cy);
+ glVertex2f(cx - gap, cy);
+ glVertex2f(cx + gap, cy);
+ glVertex2f(cx + size, cy);
+ glVertex2f(cx, cy - size);
+ glVertex2f(cx, cy - gap);
+ glVertex2f(cx, cy + gap);
+ glVertex2f(cx, cy + size);
+ glEnd();
+ }
+
+ if (drawInfo && g_qeglobals.d_font_list) {
+ idStr lines[CAMERA_NAV_MAX_INFO_LINES];
+ int numLines = 0;
+ if (s_cameraNavState.infoMode == CAMERA_NAV_INFO_ENTITY) {
+ CameraNav_BuildEntityInfo(cam, lines, numLines);
+ }
+ else if (s_cameraNavState.infoMode == CAMERA_NAV_INFO_MATERIAL) {
+ CameraNav_BuildMaterialInfo(cam, lines, numLines);
+ }
+
+ //glColor3f(1.0f, 1.0f, 1.0f);
+ //glListBase(g_qeglobals.d_font_list);
+ //int y = camera.height - 18;
+ //for (int i = 0; i < numLines && y > 8; i++, y -= 14) {
+ // const char* text = lines[i].c_str();
+ // glRasterPos2i(8, y);
+ // glCallLists(strlen(text), GL_UNSIGNED_BYTE, text);
+ //}
+ }
+
+ glPopMatrix();
+ glMatrixMode(GL_PROJECTION);
+ glPopMatrix();
+ glMatrixMode(GL_MODELVIEW);
+}
+
+
int g_axialAnchor = -1;
int g_axialDest = -1;
bool g_bAxialMode = false;
@@ -133,9 +911,25 @@ INT_PTR WINAPI CamWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
switch (uMsg)
{
case WM_KILLFOCUS:
- case WM_SETFOCUS:
- SendMessage(hWnd, WM_NCACTIVATE, uMsg == WM_SETFOCUS, 0);
+ {
+ CWnd* wnd = CWnd::FromHandlePermanent(hWnd);
+ CCamWnd* cam = DYNAMIC_DOWNCAST(CCamWnd, wnd);
+ if (cam) {
+ CameraNav_Stop(cam);
+ }
+ SendMessage(hWnd, WM_NCACTIVATE, FALSE, 0);
return 0;
+ }
+
+ case WM_SETFOCUS:
+ SendMessage(hWnd, WM_NCACTIVATE, TRUE, 0);
+ return 0;
+
+ case WM_MOUSEWHEEL:
+ if (CameraNav_HandleMouseWheel(hWnd, wParam)) {
+ return 0;
+ }
+ break;
case WM_NCCALCSIZE: // don't let windows copy pixels
DefWindowProc(hWnd, uMsg, wParam, lParam);
@@ -187,6 +981,9 @@ BOOL CCamWnd::PreCreateWindow(CREATESTRUCT& cs) {
=======================================================================================================================
*/
void CCamWnd::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) {
+ if (CameraNav_HandleKeyDown(this, nChar)) {
+ return;
+ }
g_pParentWnd->HandleKey(nChar, nRepCnt, nFlags);
}
@@ -247,15 +1044,24 @@ extern void Select_RotateTexture(float amt, bool absolute);
void CCamWnd::OnMouseMove(UINT nFlags, CPoint point) {
CRect r;
GetClientRect(r);
- if (GetCapture() == this && (GetAsyncKeyState(VK_MENU) & 0x8000) && !((GetAsyncKeyState(VK_SHIFT) & 0x8000) || (GetAsyncKeyState(VK_CONTROL) & 0x8000))) {
+
+ if (CameraNav_MouseMove(this)) {
+ m_ptLastCursor = point;
+ return;
+ }
+
+ if (GetCapture() == this && (GetAsyncKeyState(VK_MENU) & 0x8000)) {
+ // Alt-drag texture manipulation. The old condition excluded shift/control
+ // before checking them, so alt+shift and alt+control never reached the
+ // scale/rotate paths and could interrupt normal shift-select drags.
if (GetAsyncKeyState(VK_CONTROL) & 0x8000) {
Select_RotateTexture((float)point.y - m_ptLastCursor.y);
}
else if (GetAsyncKeyState(VK_SHIFT) & 0x8000) {
- Select_ScaleTexture((float)point.x - m_ptLastCursor.x, (float)m_ptLastCursor.y - point.y);
+ Select_ScaleTexture((float)point.x - m_ptLastCursor.x, (float)m_ptLastCursor.y - point.y, false);
}
else {
- Select_ShiftTexture((float)point.x - m_ptLastCursor.x, (float)m_ptLastCursor.y - point.y);
+ Select_ShiftTexture((float)point.x - m_ptLastCursor.x, (float)m_ptLastCursor.y - point.y, false);
}
}
else {
@@ -271,6 +1077,16 @@ void CCamWnd::OnMouseMove(UINT nFlags, CPoint point) {
*/
void CCamWnd::OnLButtonDown(UINT nFlags, CPoint point) {
m_ptLastCursor = point;
+ if (CameraNav_IsActive(this)) {
+ CRect r;
+ GetClientRect(r);
+ int x = r.Width() / 2;
+ int y = r.Height() / 2;
+ Cam_MouseDown(x, y, MK_LBUTTON);
+ Cam_MouseUp(x, y, 0);
+ Sys_UpdateWindows(W_ALL);
+ return;
+ }
OriginalMouseDown(nFlags, point);
}
@@ -303,6 +1119,10 @@ void CCamWnd::OnMButtonUp(UINT nFlags, CPoint point) {
=======================================================================================================================
*/
void CCamWnd::OnRButtonDown(UINT nFlags, CPoint point) {
+ m_ptLastCursor = point;
+ if (!(nFlags & (MK_SHIFT | MK_CONTROL)) && CameraNav_Begin(this)) {
+ return;
+ }
OriginalMouseDown(nFlags, point);
}
@@ -311,6 +1131,10 @@ void CCamWnd::OnRButtonDown(UINT nFlags, CPoint point) {
=======================================================================================================================
*/
void CCamWnd::OnRButtonUp(UINT nFlags, CPoint point) {
+ if (CameraNav_IsActive(this)) {
+ CameraNav_Stop(this);
+ return;
+ }
OriginalMouseUp(nFlags, point);
}
@@ -1136,6 +1960,8 @@ void CCamWnd::Cam_Draw() {
//
globalImages->BindNull();
+ CameraNav_DrawOverlay(this);
+
glFinish();
QE_CheckOpenGLForErrors();
@@ -1165,6 +1991,9 @@ void CCamWnd::OnSize(UINT nType, int cx, int cy) {
=======================================================================================================================
*/
void CCamWnd::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags) {
+ if (CameraNav_HandleKeyUp(this, nChar)) {
+ return;
+ }
g_pParentWnd->HandleKey(nChar, nRepCnt, nFlags, false);
}
@@ -2350,7 +3179,7 @@ void CCamWnd::FreeRendererState() {
ent->lightDef = -1;
}
}
-
+
for (int i = s_editorBModelStates.Num() - 1; i >= 0; i--) {
EditorFreeBModelState(i);
@@ -2630,6 +3459,11 @@ void CCamWnd::Cam_Render() {
void CCamWnd::OnTimer(UINT_PTR nIDEvent)
{
+ if (nIDEvent == CAMERA_NAV_TIMER_ID) {
+ CameraNav_Update(this);
+ return;
+ }
+
if (animationMode || nIDEvent == 1) {
Sys_UpdateWindows(W_CAMERA);
}
diff --git a/neo/tools/radiant/MediaPreviewDlg.cpp b/neo/tools/radiant/MediaPreviewDlg.cpp
index a504649d..b08bdcf8 100644
--- a/neo/tools/radiant/MediaPreviewDlg.cpp
+++ b/neo/tools/radiant/MediaPreviewDlg.cpp
@@ -172,8 +172,8 @@ void CMediaPreviewDlg::OnMouseMove(UINT nFlags, CPoint point)
sysEvent_t ev;
memset( &ev, 0, sizeof( ev ) );
ev.evType = SE_MOUSE;
- ev.evValue = (point.x / rct.Width()) * 640.0f;
- ev.evValue2 = (point.y / rct.Height()) * 480.0f;
+ ev.evValue = (point.x / rct.Width()) * SCREEN_WIDTH;
+ ev.evValue2 = (point.y / rct.Height()) * SCREEN_HEIGHT;
gui->HandleEvent(&ev, 0);
}
}
diff --git a/neo/ui/UserInterface.cpp b/neo/ui/UserInterface.cpp
index 17c8f80c..d0e000e3 100644
--- a/neo/ui/UserInterface.cpp
+++ b/neo/ui/UserInterface.cpp
@@ -47,7 +47,7 @@ idUserInterfaceManager * uiManager = &uiManagerLocal;
*/
void idUserInterfaceManagerLocal::Init() {
- screenRect = idRectangle(0, 0, 640, 480);
+ screenRect = idRectangle(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
dc.Init();
}
@@ -312,7 +312,7 @@ bool idUserInterfaceLocal::InitFromFile( const char *qpath, bool rebuild, bool c
desktop->SetFlag( WIN_DESKTOP );
desktop->name = "Desktop";
desktop->text = va( "Invalid GUI: %s", qpath );
- desktop->rect = idRectangle( 0.0f, 0.0f, 640.0f, 480.0f );
+ desktop->rect = idRectangle( 0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT);
desktop->drawRect = desktop->rect;
desktop->foreColor = idVec4( 1.0f, 1.0f, 1.0f, 1.0f );
desktop->backColor = idVec4( 0.0f, 0.0f, 0.0f, 1.0f );
diff --git a/neo/ui/Window.cpp b/neo/ui/Window.cpp
index 56059a91..14d8e552 100644
--- a/neo/ui/Window.cpp
+++ b/neo/ui/Window.cpp
@@ -114,8 +114,8 @@ void idWindow::CommonInit() {
timeLine = -1;
xOffset = yOffset = 0.0;
cursor = 0;
- forceAspectWidth = 640;
- forceAspectHeight = 480;
+ forceAspectWidth = SCREEN_WIDTH;
+ forceAspectHeight = SCREEN_HEIGHT;
matScalex = 1;
matScaley = 1;
borderSize = 0;
@@ -2116,8 +2116,8 @@ void idWindow::SetInitialState(const char *_name) {
name = _name;
matScalex = 1.0;
matScaley = 1.0;
- forceAspectWidth = 640.0;
- forceAspectHeight = 480.0;
+ forceAspectWidth = SCREEN_WIDTH;
+ forceAspectHeight = SCREEN_HEIGHT;
noTime = false;
visible = true;
flags = 0;
@@ -4125,8 +4125,8 @@ default colors, etc..
================
*/
void idWindow::SetDefaults ( void ) {
- forceAspectWidth = 640.0f;
- forceAspectHeight = 480.0f;
+ forceAspectWidth = SCREEN_WIDTH;
+ forceAspectHeight = SCREEN_HEIGHT;
matScalex = 1;
matScaley = 1;
borderSize = 0;
diff --git a/radiant.ini b/radiant.ini
new file mode 100644
index 00000000..1cf7f0e0
--- /dev/null
+++ b/radiant.ini
@@ -0,0 +1,25 @@
+[3d navigation]
+style=2
+forward=w
+back=s
+up=space
+down=shift
+left=a
+right=d
+modifier1=q
+modifier2=e
+invertpitch=0
+invertztrans=0
+capslockscale=5
+reticlemode=1
+reticlescale=1
+reticlecolor=251, 199, 30
+
+teleport=f
+infodisplay=t
+locktarget=r
+invertlockpitch=0
+invertlockyaw=0
+texposition=z
+texscale=x
+texrotate=c
\ No newline at end of file