/* * Descent 3 * Copyright (C) 2024 Parallax Software * * 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 3 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, see . */ /* * $Logfile: /DescentIII/Main/editor/TerrainDialog.cpp $ * $Revision: 1.1.1.1 $ * $Date: 2003-08-26 03:57:39 $ * $Author: kevinb $ * * Terrain dialog implementaion * * $Log: not supported by cvs2svn $ * * 75 4/29/99 3:49p Matt * Fixed compiler warning * * 74 4/27/99 3:38p Jason * fixed occlusion bug * * 73 4/17/99 6:15p Samir * replaced gr.h with grdefs.h and fixed resulting compile bugs. * * 72 2/26/99 3:32p Jason * made satellites clip properly * * 71 2/21/99 12:28p Matt * Added terrain sound system * * 70 1/24/99 5:44p Jason * added more selection choice for terrain * * 69 1/22/99 3:59p Jason * added 256x256 textures to help with terrain skies * * 68 1/21/99 11:15p Jeff * pulled out some structs and defines from header files and moved them * into seperate header files so that multiplayer dlls don't require major * game headers, just those new headers. Side effect is a shorter build * time. Also cleaned up some header file #includes that weren't needed. * This affected polymodel.h, object.h, player.h, vecmat.h, room.h, * manage.h and multi.h * * 67 1/21/99 12:31a Jason * fixed stack bug * * 66 1/20/99 10:50a Jason * added new terrain * * 65 1/15/99 7:52p Chris * Updated ObjSetPos() to include a f_update_attach_children flag * * 64 1/05/99 4:14p Matt * Fixed compile warning * * 63 11/18/98 4:30p Jason * added some functionality to terrain fog * * 62 11/11/98 11:42a Jason * added sunlight damage * * 61 10/14/98 2:48p Kevin * Changed memory code to comply with mem lib * * 60 10/08/98 4:24p Kevin * Changed code to comply with memory library usage. Always use mem_malloc * , mem_free and mem_strdup * * 59 9/29/98 12:53p Jason * added "force visiblity" for Luke * * 58 8/19/98 2:19p Jeff * moved detail globals to a struct * * 57 8/13/98 1:13p Jason * fixed terrain distance bug * * 56 7/20/98 12:04p Jason * added per level satellite lighting * * 55 6/04/98 6:45p Jason * made objects use the terrain occlusion system * * 54 6/04/98 6:16p Jason * added terrain occlusion system * * 53 5/19/98 3:19p Jason * cleaned up some texture flags * * 52 5/01/98 3:51p Jason * sped up terrain rendering by precaching all megacell lod bitmaps * * 51 4/29/98 5:00p Matt * Fixed stupid bug * * 50 4/29/98 3:58p Matt * Made the drop terrain function take a desired height, instead of always * moving the terrain to zero. * * 49 4/23/98 6:38p Jason * made bitmaps use 1555 format * * 48 4/01/98 11:25a Jeff * Added an editor bool to skip Terrain object rendering * * 47 3/30/98 5:43p Jason * fixed pcx exporting * * 46 3/30/98 3:29p Jason * added the ability to save a pcx version of the terrain * * 45 3/23/98 6:06p Matt * Added code to "drop" the terrain so the lowest point has y==0, and to * move the buildings, objects, & paths with it. * * 44 3/06/98 6:15p Jason * Give message if no cells selected in smooth terrain * * 43 3/06/98 6:13p Jason * Made terrain smoothing work on selected cells only * * 42 2/17/98 4:17p Jason * fixed satellite placement * * 41 1/26/98 2:16p Jason * allowed toggle of visibility to multiple cells * * 40 1/16/98 8:06p Jason * added selectable halos and atmosphere blends to satellites * * 39 1/10/98 2:23p Jason * fixed terrain checksum problem * * 38 1/07/98 4:19p Jason * added dome to terrain sky * * 37 12/30/97 5:45p Jason * added toggleable fog * * 36 12/17/97 5:26p Jason * added support for selectable wraparound sky * * 35 12/11/97 1:41p Jason * added terrain smoothing * * 34 12/02/97 5:31p Samir * New file dialog interface implemented. * * 33 12/01/97 10:52a Jason * separated satellite and star rendering flags * * 32 10/15/97 5:20p Jason * did a HUGE overhaul of the bitmap system * * 31 10/06/97 12:16p Jason * Ripped out old mine/terrain connection code, plus added ability to move * satellites * * 30 10/02/97 6:10p Jason * made invisible cells not be LODable * * 29 10/02/97 2:45p Jason * got invisible terrain cells working * * 28 9/25/97 5:02p Jason * fixed bug caused by last rev where pixelerror and terraindistance would * be displayed * * 27 9/23/97 2:29p Jason * did terrain editing enhancements * * 26 9/17/97 1:01p Matt * Ripped out segment code * * 25 9/17/97 11:50a Jason * ripped out segment engine * * 24 9/15/97 5:54p Jason * delete room portals when deleting rooms connected to terrain * * 23 9/05/97 6:18p Jason * made pixel error setable to 0 * * 22 9/02/97 10:47a Jason * use separate variables for game and editor LOD engine status * * 21 8/26/97 4:36p Jason * added terrain radiosity * * 20 8/25/97 12:04p Samir * Added scrolling capabilities for dialog. * * 19 8/22/97 10:17a Matt * When adding a room to the terrain, set the current face to be the one * opposite the portal face. * * $NoKeywords: $ */ #include "stdafx.h" #include "editor.h" #include "TerrainDialog.h" #include "terrain.h" #include "gametexture.h" #include "bitmap.h" #include "texture.h" #include "group.h" #include "editor/d3edit.h" #include "room.h" #include "erooms.h" #include "roomuvs.h" #include "SelectRangeDialog.h" #include "findintersection.h" #include "config.h" #include "mem.h" #include "gr.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CTerrainDialog dialog CTerrainDialog::CTerrainDialog(CWnd* pParent /*=NULL*/) : CKeypadDialog(CTerrainDialog::IDD, pParent) { //{{AFX_DATA_INIT(CTerrainDialog) // NOTE: the ClassWizard will add member initialization here //}}AFX_DATA_INIT cc_mode=CC_MODE_SKY; } void CTerrainDialog::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CTerrainDialog) // NOTE: the ClassWizard will add DDX and DDV calls here //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CTerrainDialog, CDialog) //{{AFX_MSG_MAP(CTerrainDialog) ON_WM_SIZE() ON_BN_CLICKED(IDC_TERRPAD_MOVE_UP, OnTerrpadMoveUp) ON_BN_CLICKED(IDC_TERRPAD_MOVE_DOWN, OnTerrpadMoveDown) ON_BN_CLICKED(IDC_TERRPAD_IMPORT, OnTerrpadImport) ON_BN_CLICKED(IDC_TERRPAD_RENORMALIZE, OnTerrpadRenormalize) ON_BN_CLICKED(IDC_TERRPAD_RAISE10, OnTerrpadRaise10) ON_BN_CLICKED(IDC_TERRPAD_LOWER10, OnTerrpadLower10) ON_BN_CLICKED(IDC_SKY_TEXTURE, OnSkyTexture) ON_BN_CLICKED(IDC_TERRPAD_SELECT_NONE, OnTerrpadSelectNone) ON_BN_CLICKED(IDC_TERRPAD_ROT_TEXTURE, OnTerrpadRotTexture) ON_BN_CLICKED(IDC_SKY_NEARER, OnSkyNearer) ON_BN_CLICKED(IDC_SKY_FARTHER, OnSkyFarther) ON_BN_CLICKED(IDC_STARS_CHECK, OnStarsCheck) ON_BN_CLICKED(IDC_FAST_TERRAIN_CHECK, OnFastTerrainCheck) ON_BN_CLICKED(IDC_TERRPAD_FILL_AREA, OnTerrpadFillArea) ON_BN_CLICKED(IDC_TERRPAD_REDO_TOPMAP, OnTerrpadRedoTopmap) ON_BN_CLICKED(IDC_TERRPAD_MAKE_MAX, OnTerrpadMakeMax) ON_BN_CLICKED(IDC_TERRPAD_MAKE_MIN, OnTerrpadMakeMin) ON_BN_CLICKED(IDC_TERRPAD_MAKE_ZERO, OnTerrpadMakeZero) ON_BN_CLICKED(IDC_TERRPAD_PYRAMID, OnTerrpadPyramid) ON_BN_CLICKED(IDC_TERRPAD_HILL, OnTerrpadHill) ON_BN_CLICKED(IDC_TERRPAD_PANCAKES, OnTerrpadPancakes) ON_BN_CLICKED(IDC_TERR_MOVE_MOON, OnTerrMoveMoon) ON_BN_CLICKED(IDC_TERR_RANDOMIZE_SKY, OnTerrRandomizeSky) ON_WM_PAINT() ON_BN_CLICKED(IDC_TERR_MORE_MOONS, OnTerrMoreMoons) ON_BN_CLICKED(IDC_TERR_LESS_MOONS, OnTerrLessMoons) ON_BN_CLICKED(IDC_TERR_NEXT_MOON, OnTerrNextMoon) ON_BN_CLICKED(IDC_TERR_PREV_MOON, OnTerrPrevMoon) ON_BN_CLICKED(IDC_SHOW_TERRAIN, OnShowTerrain) ON_BN_CLICKED(IDC_FLAT_SHADE_TERRAIN_CHECK, OnFlatShadeTerrainCheck) ON_WM_HELPINFO() ON_BN_CLICKED(IDC_TERR_SELECT_ALL, OnTerrSelectAll) ON_BN_CLICKED(IDC_TERRAIN_2D, OnTerrain2d) ON_BN_CLICKED(IDC_TEXTURE_SKY, OnTextureSky) ON_EN_KILLFOCUS(IDC_SKY_RED_EDIT, OnKillfocusSkyRedEdit) ON_EN_KILLFOCUS(IDC_SKY_GREEN_EDIT, OnKillfocusSkyGreenEdit) ON_EN_KILLFOCUS(IDC_SKY_BLUE_EDIT, OnKillfocusSkyBlueEdit) ON_BN_CLICKED(IDC_NO_LOD_ENGINE, OnNoLodEngine) ON_EN_KILLFOCUS(IDC_FOG_DISTANCE_EDIT, OnKillfocusFogDistanceEdit) ON_EN_KILLFOCUS(IDC_PIXEL_ERROR_EDIT, OnKillfocusPixelErrorEdit) ON_BN_CLICKED(IDC_TERRPAD_SELECTRANGE, OnTerrpadSelectrange) ON_WM_VSCROLL() ON_WM_HSCROLL() ON_BN_CLICKED(IDC_SKY_RADIO, OnSkyRadio) ON_BN_CLICKED(IDC_HORIZON_RADIO, OnHorizonRadio) ON_BN_CLICKED(IDC_FOG_RADIO, OnFogRadio) ON_BN_CLICKED(IDC_TOGGLE_VISIBILITY, OnToggleVisibility) ON_BN_CLICKED(IDC_SHOW_INVISIBLE, OnShowInvisible) ON_BN_CLICKED(IDC_TERR_MOVE_MOON_AWAY, OnTerrMoveMoonAway) ON_BN_CLICKED(IDC_MOVE_SAT_UP, OnMoveSatUp) ON_BN_CLICKED(IDC_MOVE_SAT_DOWN, OnMoveSatDown) ON_BN_CLICKED(IDC_MOVE_SAT_LEFT, OnMoveSatLeft) ON_BN_CLICKED(IDC_MOVE_SAT_RIGHT, OnMoveSatRight) ON_BN_CLICKED(IDC_SATELLITE_CHECK, OnSatelliteCheck) ON_BN_CLICKED(IDC_SMOOTH_TERRAIN, OnSmoothTerrain) ON_BN_CLICKED(IDC_USE_FOG, OnUseFog) ON_BN_CLICKED(IDC_USE_HALO, OnUseHalo) ON_BN_CLICKED(IDC_USE_ATMOSPHERE, OnUseAtmosphere) ON_BN_CLICKED(IDC_DROP_TERRAIN, OnDropTerrain) ON_BN_CLICKED(IDC_SAVE_AS_PCX, OnSaveAsPcx) ON_BN_CLICKED(IDC_NO_EXT_ROOMS_OBJS, OnNoExtRoomsObjs) ON_BN_CLICKED(IDC_TERRAIN_OCCLUSION, OnTerrainOcclusion) ON_BN_CLICKED(IDC_SATELLITE_RADIO, OnSatelliteRadio) ON_BN_CLICKED(IDC_FORCE_VISIBLE, OnForceVisible) ON_EN_KILLFOCUS(IDC_DAMAGE_PER_SEC_EDIT, OnKillfocusDamagePerSecEdit) ON_EN_KILLFOCUS(IDC_FOG_SCALAR_EDIT, OnKillfocusFogScalarEdit) ON_BN_CLICKED(IDC_ROTATE_STARS, OnRotateStars) ON_BN_CLICKED(IDC_ROTATE_SKY, OnRotateSky) ON_EN_KILLFOCUS(IDC_ROTATE_SPEED_EDIT, OnKillfocusRotateSpeedEdit) ON_BN_CLICKED(IDC_TILE_MORE, OnTileMore) ON_BN_CLICKED(IDC_TILE_LESS, OnTileLess) ON_BN_CLICKED(IDC_TERR_SOUND, OnTerrSound) //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CTerrainDialog message handlers void CTerrainDialog::OnSize(UINT nType, int cx, int cy) { CKeypadDialog::OnSize(nType, cx, cy); Current_satellite=0; cc_mode=CC_MODE_SKY; } void CTerrainDialog::DrawSwatch(int handle,int r,int g,int b) { CWnd *texwnd; RECT rect; int w,h; texwnd = GetDlgItem(handle); texwnd->GetWindowRect(&rect); ScreenToClient(&rect); Desktop_surf->attach_to_window((unsigned)m_hWnd); w=rect.right-rect.left; h=rect.bottom-rect.top; ddgr_color color=GR_RGB(r,g,b); Desktop_surf->clear(rect.left,rect.top,w,h,color); Desktop_surf->attach_to_window(NULL); } void CTerrainDialog::UpdateDialog() { CButton *bbox; char str[20]; CEdit *ebox; if (!m_Active) return; ebox=(CEdit *) GetDlgItem (IDC_DAMAGE_PER_SEC_EDIT); sprintf (str,"%f",Terrain_sky.damage_per_second); ebox->SetWindowText (str); ebox=(CEdit *) GetDlgItem (IDC_FOG_SCALAR_EDIT); sprintf (str,"%f",Terrain_sky.fog_scalar); ebox->SetWindowText (str); ebox=(CEdit *) GetDlgItem (IDC_FOG_DISTANCE_EDIT); sprintf (str,"%f",Detail_settings.Terrain_render_distance/TERRAIN_SIZE); ebox->SetWindowText (str); ebox=(CEdit *) GetDlgItem (IDC_PIXEL_ERROR_EDIT); sprintf (str,"%f",Detail_settings.Pixel_error); ebox->SetWindowText (str); ebox=(CEdit *) GetDlgItem (IDC_NUM_MOONS_STATIC); sprintf (str,"Num of sats:%d",Terrain_sky.num_satellites); ebox->SetWindowText (str); ebox=(CEdit *) GetDlgItem (IDC_CUR_MOON_STATIC); sprintf (str,"Current sat:%d",Current_satellite); ebox->SetWindowText (str); ebox=(CEdit *) GetDlgItem (IDC_ROTATE_SPEED_EDIT); sprintf (str,"%f",Terrain_sky.rotate_rate); ebox->SetWindowText (str); CheckDlgButton (IDC_TEXTURE_SKY,Terrain_sky.textured?1:0); CheckDlgButton (IDC_STARS_CHECK,Terrain_sky.flags & TF_STARS?1:0); CheckDlgButton (IDC_ROTATE_STARS,Terrain_sky.flags & TF_ROTATE_STARS?1:0); CheckDlgButton (IDC_ROTATE_SKY,Terrain_sky.flags & TF_ROTATE_SKY?1:0); CheckDlgButton (IDC_SATELLITE_CHECK,Terrain_sky.flags & TF_SATELLITES?1:0); CheckDlgButton (IDC_USE_FOG,Terrain_sky.flags & TF_FOG?1:0); CheckDlgButton (IDC_USE_HALO,Terrain_sky.satellite_flags[Current_satellite] & TSF_HALO?1:0); CheckDlgButton (IDC_USE_ATMOSPHERE,Terrain_sky.satellite_flags[Current_satellite] & TSF_ATMOSPHERE?1:0); CheckDlgButton (IDC_FAST_TERRAIN_CHECK,Fast_terrain?1:0); CheckDlgButton (IDC_SHOW_TERRAIN,D3EditState.terrain_dots?1:0); CheckDlgButton (IDC_FLAT_SHADE_TERRAIN_CHECK,D3EditState.terrain_flat_shade?1:0); CheckDlgButton (IDC_NO_LOD_ENGINE,Editor_LOD_engine_off?1:0); CheckDlgButton (IDC_NO_EXT_ROOMS_OBJS,Terrain_render_ext_room_objs?0:1); bbox = (CButton *)GetDlgItem(IDC_SKY_RADIO); bbox->SetCheck(cc_mode==CC_MODE_SKY); bbox = (CButton *)GetDlgItem(IDC_HORIZON_RADIO); bbox->SetCheck(cc_mode==CC_MODE_HORIZON); bbox = (CButton *)GetDlgItem(IDC_FOG_RADIO); bbox->SetCheck(cc_mode==CC_MODE_FOG); bbox = (CButton *)GetDlgItem(IDC_SATELLITE_RADIO); bbox->SetCheck(cc_mode==CC_MODE_SAT); // Draw swatches DrawSwatch (IDC_SKY_SWATCH,GR_COLOR_RED(Terrain_sky.sky_color),GR_COLOR_GREEN(Terrain_sky.sky_color),GR_COLOR_BLUE(Terrain_sky.sky_color)); DrawSwatch (IDC_HORIZON_SWATCH,GR_COLOR_RED(Terrain_sky.horizon_color),GR_COLOR_GREEN(Terrain_sky.horizon_color),GR_COLOR_BLUE(Terrain_sky.horizon_color)); DrawSwatch (IDC_FOG_SWATCH,GR_COLOR_RED(Terrain_sky.fog_color),GR_COLOR_GREEN(Terrain_sky.fog_color),GR_COLOR_BLUE(Terrain_sky.fog_color)); // Draw satellite swatch float maxc=max(Terrain_sky.satellite_r[Current_satellite],Terrain_sky.satellite_g[Current_satellite]); maxc=max(Terrain_sky.satellite_b[Current_satellite],maxc); float r,g,b; if (maxc>1.0) { r=Terrain_sky.satellite_r[Current_satellite]/maxc; g=Terrain_sky.satellite_g[Current_satellite]/maxc; b=Terrain_sky.satellite_b[Current_satellite]/maxc; } else { r=Terrain_sky.satellite_r[Current_satellite]; g=Terrain_sky.satellite_g[Current_satellite]; b=Terrain_sky.satellite_b[Current_satellite]; } r*=255.0; g*=255.0; b*=255.0; DrawSwatch (IDC_SATELLITE_SWATCH,r,g,b); if (cc_mode !=CC_MODE_SAT) { int r,g,b; if (cc_mode==CC_MODE_SKY) { r=GR_COLOR_RED(Terrain_sky.sky_color); g=GR_COLOR_GREEN(Terrain_sky.sky_color); b=GR_COLOR_BLUE(Terrain_sky.sky_color); } else if (cc_mode==CC_MODE_HORIZON) { r=GR_COLOR_RED(Terrain_sky.horizon_color); g=GR_COLOR_GREEN(Terrain_sky.horizon_color); b=GR_COLOR_BLUE(Terrain_sky.horizon_color); } else { r=GR_COLOR_RED(Terrain_sky.fog_color); g=GR_COLOR_GREEN(Terrain_sky.fog_color); b=GR_COLOR_BLUE(Terrain_sky.fog_color); } ebox=(CEdit *) GetDlgItem (IDC_SKY_RED_EDIT); sprintf (str,"%d",r); ebox->SetWindowText (str); ebox=(CEdit *) GetDlgItem (IDC_SKY_GREEN_EDIT); sprintf (str,"%d",g); ebox->SetWindowText (str); ebox=(CEdit *) GetDlgItem (IDC_SKY_BLUE_EDIT); sprintf (str,"%d",b); ebox->SetWindowText (str); } else { ebox=(CEdit *) GetDlgItem (IDC_SKY_RED_EDIT); sprintf (str,"%f",Terrain_sky.satellite_r[Current_satellite]); ebox->SetWindowText (str); ebox=(CEdit *) GetDlgItem (IDC_SKY_GREEN_EDIT); sprintf (str,"%f",Terrain_sky.satellite_g[Current_satellite]); ebox->SetWindowText (str); ebox=(CEdit *) GetDlgItem (IDC_SKY_BLUE_EDIT); sprintf (str,"%f",Terrain_sky.satellite_b[Current_satellite]); ebox->SetWindowText (str); } } void CTerrainDialog::OnTerrpadMoveUp() { int i; for (i=0;i0) { Terrain_seg[i].ypos--; Terrain_seg[i].y-=(float)(TERRAIN_HEIGHT_INCREMENT); TV_changed++; } } } } void CTerrainDialog::RunKeypadFunction(int code) { switch (code) { case VK_ADD: OnTerrpadMoveDown(); break; case VK_SUBTRACT: OnTerrpadMoveUp(); break; } } void CTerrainDialog::OnTerrpadImport() { char filename[255]; CString filter = "PCX files (*.pcx)|*.pcx||"; if (!OpenFileDialog(this, (LPCSTR)filter, filename, Current_bitmap_dir, sizeof(Current_bitmap_dir))) return; // Okay, we selected a file. Lets do what needs to be done here. LoadPCXTerrain(filename); } void CTerrainDialog::OnTerrpadRenormalize() { mprintf ((0,"Building terrain normals...this might take a couple of seconds.\n")); Terrain_checksum=-1; BuildMinMaxTerrain(); BuildTerrainNormals(); State_changed=1; } void CTerrainDialog::OnTerrpadRaise10() { for (int i=0;i9) { Terrain_seg[i].ypos-=10; Terrain_seg[i].y-=(float)(10*(TERRAIN_HEIGHT_INCREMENT)); TV_changed++; } } } } void CTerrainDialog::OnSkyTexture() { TV_changed=1; } void CTerrainDialog::OnTerrpadSelectNone() { for (int i=0;i500) { SetupSky (Terrain_sky.radius-500,Terrain_sky.flags); TV_changed=1; } } void CTerrainDialog::OnSkyFarther() { SetupSky (Terrain_sky.radius+500,Terrain_sky.flags); TV_changed=1; } void CTerrainDialog::OnStarsCheck() { int c=IsDlgButtonChecked(IDC_STARS_CHECK); if (c) Terrain_sky.flags|=TF_STARS; else Terrain_sky.flags&=~TF_STARS; TV_changed=1; } void CTerrainDialog::OnFastTerrainCheck() { int c=IsDlgButtonChecked(IDC_FAST_TERRAIN_CHECK); if (c) Fast_terrain=1; else Fast_terrain=0; TV_changed=1; } void CTerrainDialog::OnTerrpadFillArea() { int i; for (i=0;imax_so_far) max_so_far=Terrain_seg[i].ypos; } } for (i=0;imax_so_far) max_so_far=Terrain_seg[i].ypos; if (Terrain_seg[i].yposright) right=x; if (xbottom) bottom=y; if (ymax_so_far) max_so_far=Terrain_seg[i].ypos; if (Terrain_seg[i].yposright) right=x; if (xbottom) bottom=y; if (y0) Terrain_sky.num_satellites--; TV_changed=1; UpdateDialog(); } void CTerrainDialog::OnTerrNextMoon() { Current_satellite++; Current_satellite%=5; UpdateDialog(); } void CTerrainDialog::OnTerrPrevMoon() { Current_satellite--; if (Current_satellite<0) Current_satellite=4; UpdateDialog(); } void CTerrainDialog::OnShowTerrain() { int c=IsDlgButtonChecked(IDC_SHOW_TERRAIN); D3EditState.terrain_dots = (c != 0); State_changed=1; } void CTerrainDialog::OnFlatShadeTerrainCheck() { int c=IsDlgButtonChecked(IDC_FLAT_SHADE_TERRAIN_CHECK); D3EditState.terrain_flat_shade = (c != 0); if (c) { Terrain_texture_distance=0; Detail_settings.Terrain_render_distance=DEFAULT_VISIBLE_TERRAIN_DISTANCE*2; } else { Terrain_texture_distance=9999999; Detail_settings.Terrain_render_distance=DEFAULT_VISIBLE_TERRAIN_DISTANCE; } State_changed=1; } BOOL CTerrainDialog::OnHelpInfo(HELPINFO* pHelpInfo) { WinHelp(HID_TERRAINTAB,HELP_CONTEXT); return TRUE; //return CDialog::OnHelpInfo(pHelpInfo); } void CTerrainDialog::OnTerrSelectAll() { int i; for (i=0;iGetWindowText (str,20); if (cc_mode!=CC_MODE_SAT) { nr = atoi (str); if (nr<0) nr=0; if (nr>255) nr=255; if (cc_mode==CC_MODE_SKY) Terrain_sky.sky_color=GR_RGB(nr,g,b); else if (cc_mode==CC_MODE_HORIZON) Terrain_sky.horizon_color=GR_RGB(nr,g,b); else Terrain_sky.fog_color=GR_RGB(nr,g,b); } else { fv = atof (str); if (fv<0) fv=0; Terrain_sky.satellite_r[Current_satellite]=fv; } World_changed=1; UpdateDialog(); } void CTerrainDialog::OnKillfocusSkyGreenEdit() { CEdit *ebox; char str[20]; int r,g,b,nr; float fv; if (cc_mode==CC_MODE_SKY) { r=GR_COLOR_RED(Terrain_sky.sky_color); g=GR_COLOR_GREEN(Terrain_sky.sky_color); b=GR_COLOR_BLUE(Terrain_sky.sky_color); } else if (cc_mode==CC_MODE_HORIZON) { r=GR_COLOR_RED(Terrain_sky.horizon_color); g=GR_COLOR_GREEN(Terrain_sky.horizon_color); b=GR_COLOR_BLUE(Terrain_sky.horizon_color); } else { r=GR_COLOR_RED(Terrain_sky.fog_color); g=GR_COLOR_GREEN(Terrain_sky.fog_color); b=GR_COLOR_BLUE(Terrain_sky.fog_color); } ebox=(CEdit *) GetDlgItem (IDC_SKY_GREEN_EDIT); ebox->GetWindowText (str,20); if (cc_mode !=CC_MODE_SAT) { nr = atoi (str); if (nr<0) nr=0; if (nr>255) nr=255; if (cc_mode==CC_MODE_SKY) Terrain_sky.sky_color=GR_RGB(r,nr,b); else if (cc_mode==CC_MODE_HORIZON) Terrain_sky.horizon_color=GR_RGB(r,nr,b); else Terrain_sky.fog_color=GR_RGB(r,nr,b); } else { fv = atof (str); if (fv<0) fv=0; Terrain_sky.satellite_g[Current_satellite]=fv; } World_changed=1; UpdateDialog(); } void CTerrainDialog::OnKillfocusSkyBlueEdit() { CEdit *ebox; char str[20]; int r,g,b,nr; float fv; if (cc_mode==CC_MODE_SKY) { r=GR_COLOR_RED(Terrain_sky.sky_color); g=GR_COLOR_GREEN(Terrain_sky.sky_color); b=GR_COLOR_BLUE(Terrain_sky.sky_color); } else if (cc_mode==CC_MODE_HORIZON) { r=GR_COLOR_RED(Terrain_sky.horizon_color); g=GR_COLOR_GREEN(Terrain_sky.horizon_color); b=GR_COLOR_BLUE(Terrain_sky.horizon_color); } else { r=GR_COLOR_RED(Terrain_sky.fog_color); g=GR_COLOR_GREEN(Terrain_sky.fog_color); b=GR_COLOR_BLUE(Terrain_sky.fog_color); } ebox=(CEdit *) GetDlgItem (IDC_SKY_BLUE_EDIT); ebox->GetWindowText (str,20); if (cc_mode !=CC_MODE_SAT) { nr = atoi (str); if (nr<0) nr=0; if (nr>255) nr=255; if (cc_mode==CC_MODE_SKY) Terrain_sky.sky_color=GR_RGB(r,g,nr); else if (cc_mode==CC_MODE_HORIZON) Terrain_sky.horizon_color=GR_RGB(r,g,nr); else Terrain_sky.fog_color=GR_RGB(r,g,nr); } else { fv = atof (str); if (fv<0) fv=0; Terrain_sky.satellite_b[Current_satellite]=fv; } World_changed=1; UpdateDialog(); } void CTerrainDialog::OnNoLodEngine() { int c=IsDlgButtonChecked(IDC_NO_LOD_ENGINE); Editor_LOD_engine_off=c; State_changed=1; } void CTerrainDialog::OnKillfocusFogDistanceEdit() { CEdit *ebox; char str[20]; float predist; float dist; ebox=(CEdit *) GetDlgItem (IDC_FOG_DISTANCE_EDIT); ebox->GetWindowText (str,20); predist=atof(str); if (predist<20) predist=20; if (predist>200) predist=200; dist = predist * TERRAIN_SIZE; Detail_settings.Terrain_render_distance=dist; World_changed=1; UpdateDialog(); } void CTerrainDialog::OnKillfocusPixelErrorEdit() { CEdit *ebox; char str[20]; float err; ebox=(CEdit *) GetDlgItem (IDC_PIXEL_ERROR_EDIT); ebox->GetWindowText (str,20); err = atof (str); if (err<0) err=0; if (err>64) err=64; Detail_settings.Pixel_error=err; World_changed=1; UpdateDialog(); } void CTerrainDialog::OnTerrpadSelectrange() { SelectRangeDialog dlg; theApp.pause(); dlg.DoModal(); World_changed=1; theApp.resume(); } // These functions allow the terrain keypad to scroll!! void CTerrainDialog::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) { // TODO: Add your message handler code here and/or call default CKeypadDialog::OnVScroll(nSBCode, nPos, pScrollBar); } void CTerrainDialog::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) { // TODO: Add your message handler code here and/or call default CKeypadDialog::OnHScroll(nSBCode, nPos, pScrollBar); } void CTerrainDialog::OnSkyRadio() { cc_mode=CC_MODE_SKY; UpdateDialog(); } void CTerrainDialog::OnHorizonRadio() { cc_mode=CC_MODE_HORIZON; UpdateDialog(); } void CTerrainDialog::OnFogRadio() { cc_mode=CC_MODE_FOG; UpdateDialog(); } void CTerrainDialog::OnToggleVisibility() { for (int i=0;ipos; float mag=vm_GetMagnitude (&sat_vec); vector rot_vec; vm_NormalizeVector (&sat_vec); vm_MatrixMulVector (&rot_vec,&sat_vec,&orient); Terrain_sky.satellite_vectors[n]=Viewer_object->pos+(rot_vec*mag); } void CTerrainDialog::OnMoveSatUp() { MoveSat (1500,0); TV_changed=1; } void CTerrainDialog::OnMoveSatDown() { MoveSat (64000,0); TV_changed=1; } void CTerrainDialog::OnMoveSatLeft() { MoveSat (0,64000); TV_changed=1; } void CTerrainDialog::OnMoveSatRight() { MoveSat (0,1500); TV_changed=1; } void CTerrainDialog::OnSatelliteCheck() { int c=IsDlgButtonChecked(IDC_SATELLITE_CHECK); if (c) Terrain_sky.flags|=TF_SATELLITES; else Terrain_sky.flags&=~TF_SATELLITES; TV_changed=1; } void CTerrainDialog::OnSmoothTerrain() { ubyte *src_data; int y,x; if (Num_terrain_selected==0) { OutrageMessageBox ("This operation works on selected cells. You have no cells selected!"); return; } if ((MessageBox("Are you sure you wish to smooth the terrain? This operation cannot be undone.","Question",MB_YESNO))==IDNO) return; src_data=(ubyte *)mem_malloc (TERRAIN_WIDTH*TERRAIN_DEPTH); ASSERT (src_data); // Ran out of memory! for (int i=0;i0) { total/=num; Terrain_seg[y*w+x].ypos=total; } } } mem_free (src_data); BuildMinMaxTerrain(); OutrageMessageBox ("Terrain smoothed!"); World_changed=1; } void CTerrainDialog::OnUseFog() { int c=IsDlgButtonChecked(IDC_USE_FOG); if (c) Terrain_sky.flags|=TF_FOG; else Terrain_sky.flags&=~TF_FOG; World_changed=1; } void CTerrainDialog::OnUseHalo() { int n=Current_satellite; int c=IsDlgButtonChecked(IDC_USE_HALO); if (c) Terrain_sky.satellite_flags[n]|=TSF_HALO; else Terrain_sky.satellite_flags[n]&=~TSF_HALO; World_changed=1; } void CTerrainDialog::OnUseAtmosphere() { int n=Current_satellite; int c=IsDlgButtonChecked(IDC_USE_ATMOSPHERE); if (c) Terrain_sky.satellite_flags[n]|=TSF_ATMOSPHERE; else Terrain_sky.satellite_flags[n]&=~TSF_ATMOSPHERE; World_changed=1; } #include "gamepath.h" #include "EditLineDialog.h" void CTerrainDialog::OnDropTerrain() { int desired_height,lowest_height,highest_height,delta_height; int x,y; //Find lowest & highest terrain values for (x=0,lowest_height=INT_MAX,highest_height=0;x highest_height) highest_height = Terrain_seg[x*TERRAIN_WIDTH+y].ypos; } //Get desired terrain level get_height:; if (! InputNumber(&desired_height,"Raise/Lower Terrain","Enter the desired height for the lowest terrain point:")) return; //Check valid values if ((desired_height < 0) || (desired_height > 255)) { OutrageMessageBox("Invalid value: the height must be between 0 and 255, inclusive."); goto get_height; } if (((highest_height - lowest_height) + desired_height) > 255) { OutrageMessageBox("The delta height of the terrain is %d, so you cannot set the lowest point above %d.",highest_height - lowest_height,255 - (highest_height - lowest_height)); goto get_height; } //Compute delta delta_height = desired_height - lowest_height; //Now lower the terrain for (x=0;xused) for (v=0;vnum_verts;v++) rp->verts[v].y += delta_y; //Drop all the objects for (o=0;o<=Highest_object_index;o++) if (Objects[o].type != OBJ_NONE) { vector new_pos = Objects[o].pos; new_pos.y += delta_y; ObjSetPos(&Objects[o],&new_pos,Objects[o].roomnum,NULL,false); } //Drop all the paths for (p=0;p=0 && cell0) { POP_FILL(); if (Terrain_heights[cell]==0) { int x=cell%256; int z=cell/256; Terrain_heights[cell]=FILL_COLOR; if (x!=0 && Terrain_fill[cell-1]==0) PUSH_FILL(cell-1); if (x!=TERRAIN_WIDTH-1 && Terrain_fill[cell+1]==0) PUSH_FILL(cell+1); if (z!=0 && Terrain_fill[cell-TERRAIN_WIDTH]==0) PUSH_FILL(cell-TERRAIN_WIDTH); if (z!=TERRAIN_DEPTH-1 && Terrain_fill[cell+TERRAIN_WIDTH]==0) PUSH_FILL(cell+TERRAIN_DEPTH); } } } void CTerrainDialog::OnTerrainOcclusion() { // TODO: Add your control notification handler code here if (Terrain_occlusion_checksum==(Terrain_checksum+1)) { OutrageMessageBox ("The occlusion map is already calculated for this terrain."); //return; } if ((MessageBox("Are you sure you wish to calculate terrain occlusion?","Question",MB_YESNO))==IDNO) return; mprintf ((0,"Now doing occlusion tests...\n")); int count=0; int occlude_count=0; ubyte *touch_buffer[256]; for (int i=0;i<256;i++) { memset (Terrain_occlusion_map[i],0,32); touch_buffer[i]=(ubyte *)mem_malloc(256); ASSERT (touch_buffer[i]); memset (touch_buffer[i],255,256); } ubyte *save_buffer; // Build a height map so we can flood fill Terrain_heights=(ubyte *)mem_malloc (TERRAIN_WIDTH*TERRAIN_DEPTH); Terrain_fill=(ubyte *)mem_malloc (TERRAIN_WIDTH*TERRAIN_DEPTH); save_buffer=(ubyte *)mem_malloc (TERRAIN_WIDTH*TERRAIN_DEPTH); ASSERT (Terrain_heights); ASSERT (save_buffer); ASSERT (Terrain_fill); memset(save_buffer,0,TERRAIN_WIDTH*TERRAIN_DEPTH); memset(Terrain_fill,0,TERRAIN_WIDTH*TERRAIN_DEPTH); for (i=0;iabs(end_x-start_x)) x_major=0; // We're iterating over the x axis if (x_major) { int x_add=1; int limit=end_x-start_x; if (limit<0) { x_add=-1; limit=-limit; } int cur_x=start_x; float cur_z=start_z; float delta_z=(float)(end_z-start_z)/(float)limit; for (j=0;jGetWindowText (str,20); err = atof (str); if (err<0) err=0; if (err>200) err=200; Terrain_sky.damage_per_second=err; World_changed=1; UpdateDialog(); } void CTerrainDialog::OnKillfocusFogScalarEdit() { CEdit *ebox; char str[20]; float err; ebox=(CEdit *) GetDlgItem (IDC_FOG_SCALAR_EDIT); ebox->GetWindowText (str,20); err = atof (str); if (err<.2) err=.2f; if (err>1.0) err=1.0; Terrain_sky.fog_scalar=err; World_changed=1; UpdateDialog(); } void CTerrainDialog::OnRotateStars() { int c=IsDlgButtonChecked(IDC_ROTATE_STARS); if (c) Terrain_sky.flags|=TF_ROTATE_STARS; else Terrain_sky.flags&=~TF_ROTATE_STARS; TV_changed=1; } void CTerrainDialog::OnRotateSky() { int c=IsDlgButtonChecked(IDC_ROTATE_SKY); if (c) Terrain_sky.flags|=TF_ROTATE_SKY; else Terrain_sky.flags&=~TF_ROTATE_SKY; TV_changed=1; } void CTerrainDialog::OnKillfocusRotateSpeedEdit() { CEdit *ebox; char str[20]; float err; ebox=(CEdit *) GetDlgItem (IDC_ROTATE_SPEED_EDIT); ebox->GetWindowText (str,20); err = atof (str); if (err<0) err=0; if (err>180) err=180; Terrain_sky.rotate_rate=err; World_changed=1; UpdateDialog(); } void CTerrainDialog::OnTileMore() { int i; ubyte touched[TERRAIN_TEX_WIDTH*TERRAIN_TEX_DEPTH]; memset (touched,0,TERRAIN_TEX_WIDTH*TERRAIN_TEX_DEPTH); for (i=0;i>4; if (val<8) val++; val<<=4; Terrain_tex_seg[Terrain_seg[i].texseg_index].rotation&=~0xF0; Terrain_tex_seg[Terrain_seg[i].texseg_index].rotation|=val; touched[Terrain_seg[i].texseg_index]=1; } } } World_changed=1; TV_changed=1; } void CTerrainDialog::OnTileLess() { int i; ubyte touched[TERRAIN_TEX_WIDTH*TERRAIN_TEX_DEPTH]; memset (touched,0,TERRAIN_TEX_WIDTH*TERRAIN_TEX_DEPTH); for (i=0;i>4; if (val>1) val--; val<<=4; Terrain_tex_seg[Terrain_seg[i].texseg_index].rotation&=~0xF0; Terrain_tex_seg[Terrain_seg[i].texseg_index].rotation|=val; touched[Terrain_seg[i].texseg_index]=1; } } } World_changed=1; TV_changed=1; } #include "TerrainSoundDialog.h" void CTerrainDialog::OnTerrSound() { CTerrainSoundDialog dlg; dlg.DoModal(); }