mirror of
https://github.com/kevinbentley/Descent3.git
synced 2025-01-22 19:55:23 +00:00
1684 lines
49 KiB
C++
1684 lines
49 KiB
C++
/*
|
|
* 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 <http://www.gnu.org/licenses/>.
|
|
|
|
--- HISTORICAL COMMENTS FOLLOW ---
|
|
|
|
* $Logfile: /DescentIII/Main/editor/TextureGrWnd.cpp $
|
|
* $Revision: 1.1.1.1 $
|
|
* $Date: 2003-08-26 03:57:39 $
|
|
* $Author: kevinb $
|
|
*
|
|
* Texture view of mine.
|
|
*
|
|
* $Log: not supported by cvs2svn $
|
|
*
|
|
* 122 9/30/99 6:35p Matt
|
|
* Added code to scale the UVs of a texture based on the size of the
|
|
* texture when the texture is applied to a face. This will cause the
|
|
* applied texture to have the make 3D texel size at the old texture.
|
|
*
|
|
* 121 4/22/99 11:41a Jason
|
|
* fixed right clicking problem (temp fix)
|
|
*
|
|
* 120 4/19/99 6:55p Jason
|
|
* fixed satellite grabbing problem
|
|
*
|
|
* 119 4/18/99 10:55p Chris
|
|
* Added ignore own concussive blasts
|
|
*
|
|
* 118 4/18/99 5:42a Chris
|
|
* Added the FQ_IGNORE_RENDER_THROUGH_PORTALS flag
|
|
*
|
|
* 117 4/15/99 5:49p Chris
|
|
* Fixed a bug with rendering the BOAPath nodes
|
|
*
|
|
* 116 4/14/99 3:13p Chris
|
|
* Beginning to add BoaNode stuff
|
|
*
|
|
* 115 4/03/99 7:39p Matt
|
|
* Don't allow player objects to be given names.
|
|
*
|
|
* 114 3/27/99 7:10p Matt
|
|
* Strip leading & trailing spaces before check for duplicate names.
|
|
*
|
|
* 113 3/02/99 5:54p Jason
|
|
* fixed right mouse clicking with opengl
|
|
*
|
|
* 112 3/01/99 10:39a Matt
|
|
* Strip leading and trailing spaces from object, trigger, and room names
|
|
* on level load and when the names are entered.
|
|
*
|
|
* 111 2/28/99 10:40p Matt
|
|
* Check for name already in use when entering a name.
|
|
*
|
|
* 110 2/21/99 4:20p Matt
|
|
* Added SoundSource objects (and reformatted parts of the object header
|
|
* files).
|
|
*
|
|
* 109 2/19/99 12:04p Jason
|
|
* took out sky band
|
|
*
|
|
* 108 2/17/99 7:06p Kevin
|
|
*
|
|
* 107 2/17/99 5:47p Dan
|
|
* fixed dumb bug
|
|
*
|
|
* 106 2/17/99 1:05p Jason
|
|
* revamped object/face/terrain selection code
|
|
*
|
|
* 105 2/10/99 5:49p Dan
|
|
* fixed fog bug
|
|
*
|
|
* 104 2/09/99 12:25p Jason
|
|
* fixed dumb bug
|
|
*
|
|
* 103 2/09/99 12:16p Jason
|
|
* fixed postrender problem
|
|
*
|
|
* 102 2/09/99 11:36a Dan
|
|
* error checking (m_last_start_rooom invalid, initialized it) Samir
|
|
*
|
|
* 101 2/09/99 9:59a Chris
|
|
* Quick compile patch and changed code to use BOA_IsVisible()
|
|
*
|
|
* 100 2/08/99 6:39p Jason
|
|
* first pass at new indoor engine
|
|
*
|
|
* 99 2/03/99 1:10p Matt
|
|
* Changed the paletted room current faces to be stored in a seperate
|
|
* array, instead of in the room structure.
|
|
*
|
|
* 98 2/01/99 5:47p Nate
|
|
* Implemented Editing/Adding of Dallas Scripts
|
|
*
|
|
* 97 2/01/99 4:24p Matt
|
|
* Added Edit Script and New Script (though they don't do anything yet) to
|
|
* object right-click dialog, and deleted Copy UID and Properties.
|
|
*
|
|
* 96 1/27/99 1:20p Jason
|
|
* made r key rotate the terrain texture
|
|
*
|
|
* 95 1/24/99 12:37a Jeff
|
|
* removed compile warnings
|
|
*
|
|
* 94 1/22/99 8:54p Jeff
|
|
* added custom-default script overrides
|
|
*
|
|
* 93 1/22/99 3:59p Jason
|
|
* added 256x256 textures to help with terrain skies
|
|
*
|
|
* 92 1/20/99 10:50a Jason
|
|
* added new terrain
|
|
*
|
|
* 91 1/08/99 2:56p Samir
|
|
* Ripped out OSIRIS1.
|
|
*
|
|
* 90 12/22/98 2:05p Matt
|
|
* Mark the world as changed when an object name is changed.
|
|
*
|
|
* 89 12/21/98 11:30p Matt
|
|
* Added names for objects
|
|
*
|
|
* 88 10/22/98 10:33a Sean
|
|
* fixed windowed opengl lighting
|
|
*
|
|
* 87 10/18/98 2:06p Matt
|
|
* Bail out of FindRoomFace if the starting room isn't in use any more.
|
|
* This can happen if you click on the texture window after loading a
|
|
* level or doing a New but before the new level has a chance to render.
|
|
*
|
|
* 86 10/06/98 12:27p Sean
|
|
* More state changes
|
|
*
|
|
* 85 10/06/98 11:29a Jason
|
|
* fixed state limited WindowGL
|
|
*
|
|
* 84 10/02/98 5:31p Jason
|
|
* tweaks for statelimited stuff
|
|
*
|
|
* 83 10/02/98 4:24p Jason
|
|
* more attempts to fix Riva128 opengl stuttering
|
|
*
|
|
* 82 10/02/98 4:22p Jason
|
|
* made multipass turn off for gl rendering
|
|
*
|
|
* 81 10/01/98 10:39a Luke
|
|
* FROM JASON: Attempted to fix GL problem....
|
|
*
|
|
* 80 9/30/98 10:25a Jason
|
|
* another attempt to the get the OpenGL window thing working reliably...
|
|
*
|
|
* 79 9/18/98 1:27p Jason
|
|
* cleaned up renderer initting
|
|
*
|
|
* 78 8/15/98 5:04p Matt
|
|
* Added code to copy a texture & UVs from one face to another
|
|
*
|
|
* 77 7/21/98 12:04p Jason
|
|
* V key now tells if the marked room and current room can see each other
|
|
*
|
|
* 76 6/16/98 3:04p Jason
|
|
* fixed framecount bug
|
|
*
|
|
* 75 6/10/98 12:23p Jason
|
|
* added new skies
|
|
*
|
|
* 74 6/09/98 6:16p Jason
|
|
* added some features for windowed opengl
|
|
*
|
|
* 73 6/09/98 4:47p Jason
|
|
* added windowed openGL mode
|
|
*
|
|
* 72 6/04/98 6:16p Jason
|
|
* added terrain occlusion system
|
|
*
|
|
* 71 5/26/98 7:01p Samir
|
|
* new script selection technique that knows what list of scripts to
|
|
* choose from for an object.
|
|
*
|
|
* 70 5/04/98 3:23p Samir
|
|
* only select custom scripts for right clicking.
|
|
*
|
|
* 69 5/01/98 3:51p Jason
|
|
* sped up terrain rendering by precaching all megacell lod bitmaps
|
|
*
|
|
* 68 5/30/98 10:16p Chris
|
|
* Fixed some bad spelling
|
|
*
|
|
* 67 4/21/98 2:43p Matt
|
|
* Added system to disable render updates while deleting large numbers of
|
|
* rooms, since the mine is not stable until this operation is done.
|
|
*
|
|
* 66 4/21/98 12:16a Samir
|
|
* Hopefully if you change script definition, it's reflected as you edit
|
|
* it.
|
|
*
|
|
* 65 4/16/98 10:42a Matt
|
|
* Made texture propagation work across rooms.
|
|
*
|
|
* 64 3/12/98 7:30p Chris
|
|
* Added ObjSetOrient
|
|
*
|
|
* 63 3/02/98 4:03p Samir
|
|
* Simplied script editing and selection code.
|
|
*
|
|
* 62 2/25/98 4:06p Samir
|
|
* Isolated parameter passing data functions.
|
|
*
|
|
* 61 2/24/98 1:50p Jason
|
|
* added V key to check distance from plane for vertices
|
|
*
|
|
* 60 2/10/98 12:25p Samir
|
|
* m_StartFlip should be rest when flip begins.
|
|
*
|
|
* 59 2/10/98 10:48a Matt
|
|
* Moved editor code from gamepath.cpp to epath.cpp
|
|
*
|
|
* 58 2/09/98 6:06p Matt
|
|
* Made Render_all_external_rooms not affect Room View
|
|
*
|
|
* 57 1/30/98 6:05p Matt
|
|
* Use new function to set current editor object
|
|
*
|
|
* 56 1/26/98 6:31p Chris
|
|
* User define paths now render in mine and terrain views
|
|
*
|
|
* 55 1/26/98 4:33p Samir
|
|
* Added ability to copy object ids.
|
|
*
|
|
* 54 1/23/98 3:06p Samir
|
|
* Script selection with parameters.
|
|
*
|
|
* 53 1/20/98 4:12p Samir
|
|
* New script housekeeping system.
|
|
*
|
|
* 52 1/19/98 6:20p Samir
|
|
* Rightclicking brings up menu in terrain.
|
|
*
|
|
* 51 1/16/98 12:41p Matt
|
|
* Took out old debug/test code
|
|
*
|
|
* 50 1/15/98 12:42p Jason
|
|
* big fix for terrain sky rendering
|
|
*
|
|
* 49 1/07/98 4:19p Jason
|
|
* added dome to terrain sky
|
|
*
|
|
* 48 1/06/98 1:27p Matt
|
|
* Cleaned up interfaces to rendering routines, deleted unused code, etc.
|
|
*
|
|
* 47 1/02/98 6:40p Matt
|
|
* User renderer library (instead of viewport) functions to draw lines and
|
|
* to set and read pixels. Also made FindRoomFace() work without
|
|
* Render_viewport.
|
|
*
|
|
* 46 12/29/97 5:44p Samir
|
|
* Took out references to grViewport and old 2d library.
|
|
*
|
|
* 45 12/19/97 12:29p Samir
|
|
* Oops.
|
|
*
|
|
* 44 12/19/97 11:25a Samir
|
|
* g3_StartFrame and g3_EndFrame replaced by EditorStartFrame and
|
|
* EditorEndFrame
|
|
*
|
|
* 43 12/17/97 5:26p Jason
|
|
* added support for selectable wraparound sky
|
|
*
|
|
* 42 12/01/97 4:20p Jason
|
|
* shadow and lighting changes
|
|
*
|
|
* 41 11/21/97 5:33p Jason
|
|
* print light value when clicking on terrain cell
|
|
*
|
|
* 40 11/17/97 8:33p Jason
|
|
* fixed bug with object selection introduced by last rev
|
|
*
|
|
* 39 11/17/97 6:13p Mark
|
|
* allowed object 0 to be selected
|
|
*
|
|
* 38 11/03/97 7:02p Matt
|
|
* Added better warning message
|
|
*
|
|
* 37 10/31/97 12:14p Jason
|
|
* do a texture screen update after placing a new satellite image
|
|
*
|
|
* 36 9/30/97 2:12p Samir
|
|
* Fully implemeted the Object Script Properties dialog.
|
|
*
|
|
* 35 9/22/97 6:18p Matt
|
|
* Removed include of stub.h
|
|
*
|
|
* 34 9/17/97 1:00p Samir
|
|
* Took out Room_engine and all segment references I could find.
|
|
*
|
|
* 33 9/16/97 6:32p Jason
|
|
* made texture selection on terrain print relevant info
|
|
*
|
|
* 32 9/06/97 3:21p Matt
|
|
* Reset cur portal when room changes
|
|
*
|
|
* 31 9/03/97 8:00p Samir
|
|
* Implemented most of the fixes for the object moving system.
|
|
*
|
|
* 30 9/02/97 2:17p Samir
|
|
* Move objects in Terrain now.
|
|
*
|
|
* 29 8/29/97 1:51p Samir
|
|
* When mouse down in an object, invoke ObjectMoveManager
|
|
*
|
|
* 28 8/28/97 11:53a Matt
|
|
* Don't try to propagate from a face to itself
|
|
*
|
|
* 27 8/27/97 5:19p Jason
|
|
* made ShowRadProgress fill the entire texture window
|
|
*
|
|
* 26 8/26/97 4:37p Jason
|
|
* added floating point hemicube rasterizer, plus "heat" visualization
|
|
*
|
|
* 25 8/22/97 10:16a Matt
|
|
* When change curroom & curface, reset curvert & curedge also
|
|
*
|
|
* 24 8/22/97 10:15a Jason
|
|
* Added error checking to ShowRadView
|
|
*
|
|
* 23 8/18/97 5:57p Jason
|
|
* made radiosity better
|
|
*
|
|
* 22 8/01/97 4:53p Jason
|
|
* made a more general PropagateTextureToFace function call
|
|
*
|
|
* 21 7/29/97 12:07p Matt
|
|
* Took out texturing in room view, & made selecting a face in room view
|
|
* not change the global current room/face
|
|
*
|
|
* 20 7/24/97 6:11p Matt
|
|
* Created symbolic constant for default zoom, and used it every place
|
|
* that specifies zoom
|
|
*
|
|
* 19 7/22/97 7:08p Matt
|
|
* Cleaned up D3EditState, moving some vars in and some out, and renaming
|
|
* and changing a few others
|
|
*
|
|
* 18 7/20/97 7:37p Jason
|
|
* added new sky
|
|
*
|
|
* 17 7/18/97 5:49p Jason
|
|
* flag room changed is you change it
|
|
*
|
|
* 16 7/17/97 3:00p Jason
|
|
* changed "moons" to be called satellites since we're going to have suns
|
|
* and other things in orbit
|
|
*
|
|
*
|
|
* 15 7/16/97 5:20p Jason
|
|
* implemented selection of moons with mouse click
|
|
*
|
|
* 14 7/16/97 4:07p Jason
|
|
* fixed all the remaining drop-out bugs
|
|
*
|
|
* 13 7/15/97 4:19p Jason
|
|
* added object focus for terrain
|
|
*
|
|
* 39 6/30/97 3:54p Jeff
|
|
* Add object properties dialog
|
|
*
|
|
* 38 6/30/97 2:31p Jason
|
|
* took out room rendering from the mine-segment rendering loop
|
|
*
|
|
* 37 6/30/97 1:30p Jason
|
|
* added netherspace stuff
|
|
*
|
|
* 36 6/30/97 12:33p Jeff
|
|
* Added message map and support for right-click popup menu
|
|
*
|
|
* 35 6/30/97 11:34a Jeff
|
|
*
|
|
* 34 6/27/97 5:19p Jeff
|
|
*
|
|
* 33 6/27/97 2:49p Jason
|
|
* added hacked way to change textures for rooms (temporary)
|
|
*
|
|
* 32 6/26/97 4:55p Jason
|
|
* fixed dumb bug
|
|
*
|
|
* 31 6/26/97 4:45p Jason
|
|
* added control_right_click function for box selection
|
|
*
|
|
* 30 6/26/97 4:06p Jason
|
|
* no collision detection if Flat_terrain is set
|
|
*
|
|
* 29 6/25/97 5:30p Jason
|
|
* added code to readin/display a room
|
|
*
|
|
* 28 6/06/97 4:57p Jason
|
|
* more nifty megacell/tmap2 features
|
|
*
|
|
* 27 6/06/97 4:33p Jason
|
|
* added cool stuff for megacells
|
|
*
|
|
* 26 6/05/97 6:58p Jason
|
|
* added more megacell functionality
|
|
*
|
|
* 25 5/22/97 5:15p Jason
|
|
* added tmap2 capability to the terrain
|
|
*
|
|
* 24 5/15/97 3:28a Jason
|
|
* tried to get subwindow clearing to work with terrain - but it won't
|
|
* until samir fixes lock_clear
|
|
*
|
|
* 23 5/08/97 7:46p Matt
|
|
* Added called_from_terrain parm for RenderMine()
|
|
*
|
|
* 22 5/08/97 6:43p Jason
|
|
* added support for terrain/mine reentry handling
|
|
*
|
|
* 21 5/05/97 4:47p Jason
|
|
* made terrain and mine rendering work without explicit calls to
|
|
* g3_Startframe in their main function calls
|
|
* This allows us to integrate mine/terrain engines nicely
|
|
*
|
|
* 20 4/09/97 2:00p Jason
|
|
* moved DrawAllPaths function to gamepath where it belongs
|
|
*
|
|
* 19 4/08/97 10:42a Jason
|
|
* implemented path following interface
|
|
*
|
|
* 18 4/02/97 3:24p Jason
|
|
* changed Viewer_moved back to TV_changed because it didn't do what I
|
|
* thought it would do, namely only update the textured view!
|
|
*
|
|
* 17 4/02/97 2:48p Jason
|
|
* changed TV_changed to viewer move to reforce drawing of textured view,
|
|
* but not wireframe
|
|
*
|
|
* 16 3/31/97 5:58p Matt
|
|
* Revamped mine update flags
|
|
*
|
|
* 15 3/20/97 11:55a Jason
|
|
* changes for terrain editing/drawing
|
|
*
|
|
* 14 3/07/97 4:18p Jason
|
|
* implemented terrain functionality in the editor
|
|
*
|
|
* 13 2/28/97 9:35a Matt
|
|
* Added code to select objects by clicking on them in the texture window.
|
|
*
|
|
* 12 2/27/97 4:26p Matt
|
|
* Fixed curseg selection status messages
|
|
*
|
|
* 11 2/26/97 7:35p Samir
|
|
* Moved TextureGrWnd.h after stdafx.h to get rid of warning and errors.
|
|
*
|
|
* 10 2/20/97 5:37p Samir
|
|
* SHIFT + LEFTBUTTONDOWN = Apply texture.
|
|
*
|
|
* 9 2/19/97 11:06a Samir
|
|
* Only flip screen if we rendered but did not hit the left button down
|
|
* key to prevent green screen flash.
|
|
*
|
|
* 8 2/18/97 7:57p Matt
|
|
* Added code to select a segment by clicking on it in the texture-mapped
|
|
* window
|
|
*
|
|
* 7 2/03/97 8:01p Matt
|
|
* New name and parms for render function
|
|
*
|
|
* 6 2/03/97 5:20p Samir
|
|
* Added gr.h header
|
|
*
|
|
* 5 1/30/97 6:25p Samir
|
|
* Implemented a non-working caption bar system and made some changes for
|
|
* Jason.
|
|
*
|
|
* 4 1/23/97 4:56p Samir
|
|
* Handles saving screen positions of windows and tileability.
|
|
*
|
|
* 3 1/21/97 12:42p Samir
|
|
* Floatable-resizable views
|
|
*
|
|
* $NoKeywords: $
|
|
*/
|
|
|
|
#include "stdafx.h"
|
|
|
|
#include "TextureGrWnd.h"
|
|
|
|
#include "application.h"
|
|
#include "editor.h"
|
|
#include "render.h"
|
|
#include "manage.h"
|
|
#include "gr.h"
|
|
#include "boa.h"
|
|
#include "gameloop.h"
|
|
#include "descent.h"
|
|
#include "terrain.h"
|
|
#include "HTexture.h"
|
|
#include "terraindialog.h"
|
|
#include "room.h"
|
|
#include "roomuvs.h"
|
|
#include "mainfrm.h"
|
|
#include <string.h>
|
|
#include "ObjMoveManager.h"
|
|
#include "lightmap_info.h"
|
|
#include "lightmap.h"
|
|
#include "EditLineDialog.h"
|
|
#include "CustDefaultScriptSelect.h"
|
|
#include "erooms.h"
|
|
#include "ebnode.h"
|
|
|
|
#include <assert.h>
|
|
|
|
#include "mono.h"
|
|
#include "3d.h"
|
|
#include "gr.h"
|
|
#include "ddio.h"
|
|
#include "epath.h"
|
|
#include "megacell.h"
|
|
#include "ObjectPropertiesDialog.h"
|
|
#include "ObjectClipboard.h"
|
|
#include "radiosity.h"
|
|
#include "hemicube.h"
|
|
#include "args.h"
|
|
#include "game.h"
|
|
#include "DallasMainDlg.h"
|
|
#include "postrender.h"
|
|
#include "SoundSourceDialog.h"
|
|
|
|
#ifdef _DEBUG
|
|
#define new DEBUG_NEW
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[] = __FILE__;
|
|
#endif
|
|
|
|
// These defines are for the right-click popup menu
|
|
#define POPUP_PROPERTIES 0x60
|
|
#define POPUP_DELETE 0x61
|
|
#define POPUP_PASTE 0x62
|
|
#define POPUP_CUT 0x63
|
|
#define POPUP_COPY 0x64
|
|
#define POPUP_COPYID 0x66
|
|
#define POPUP_OBJNAME 0x69
|
|
#define POPUP_EDITNAME 0x6a
|
|
#define POPUP_CUSTOMDEFAULTSCRIPT 0x6b
|
|
#define POPUP_EDITSCRIPT 0x6c
|
|
#define POPUP_NEWSCRIPT 0x6d
|
|
#define POPUP_SOUND 0x6e
|
|
|
|
grViewport *rad_Viewport;
|
|
static int DoOpenGL = 0;
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CTextureGrWnd
|
|
|
|
CTextureGrWnd::CTextureGrWnd() : CGrWnd("TextureScreen") {
|
|
m_StartFlip = FALSE;
|
|
m_last_start_room = -1;
|
|
}
|
|
|
|
CTextureGrWnd::~CTextureGrWnd() {}
|
|
|
|
BEGIN_MESSAGE_MAP(CTextureGrWnd, CWnd)
|
|
//{{AFX_MSG_MAP(CTextureGrWnd)
|
|
ON_WM_SIZE()
|
|
ON_WM_PAINT()
|
|
ON_WM_DESTROY()
|
|
ON_WM_MOVE()
|
|
ON_WM_CREATE()
|
|
ON_WM_SYSCOMMAND()
|
|
ON_WM_NCACTIVATE()
|
|
ON_WM_NCPAINT()
|
|
ON_WM_LBUTTONDOWN()
|
|
ON_WM_MOUSEMOVE()
|
|
ON_WM_RBUTTONDOWN()
|
|
//}}AFX_MSG_MAP
|
|
END_MESSAGE_MAP()
|
|
|
|
void DrawPlayerOnWireframe();
|
|
|
|
bool Disable_editor_rendering = 0;
|
|
static int first_time = 1;
|
|
|
|
extern int Just_returned_from_game;
|
|
extern float Just_returned_time;
|
|
int Successive_count = 0;
|
|
|
|
HWND save_wnd;
|
|
oeLnxApplication *app;
|
|
|
|
void CTextureGrWnd::TexGrStartOpenGL() {
|
|
if (DoOpenGL) {
|
|
app = (oeLnxApplication *)Descent;
|
|
StateLimited = 1;
|
|
// TODO - hwnd from SDL windows
|
|
// save_wnd = (HWND)app->m_hWnd;
|
|
// app->m_hWnd = (HWnd)m_hWnd;
|
|
// rend_SetOpenGLWindowState (1,Descent,NULL); // LGT: not defined anymore
|
|
rend_ClearScreen(0);
|
|
StateLimited = 1;
|
|
UseMultitexture = 0;
|
|
NoLightmaps = false;
|
|
}
|
|
}
|
|
|
|
void CTextureGrWnd::TexGrStopOpenGL() {
|
|
if (DoOpenGL) {
|
|
// rend_SetOpenGLWindowState (0,Descent,NULL); // LGT: not defined anymore
|
|
// TODO - hwnd from SDL windows
|
|
// app->m_hWnd = (HWnd)save_wnd;
|
|
}
|
|
}
|
|
|
|
void CTextureGrWnd::Render() {
|
|
if (first_time) {
|
|
first_time = 0;
|
|
if (FindArg("-WindowGL"))
|
|
DoOpenGL = 1;
|
|
}
|
|
|
|
if (DoOpenGL) {
|
|
if (Just_returned_from_game) {
|
|
Successive_count++;
|
|
if (Successive_count < 2) {
|
|
mprintf(0, "Not doing opengl!\n");
|
|
DoOpenGL = 0;
|
|
first_time = 1;
|
|
} else {
|
|
Just_returned_from_game = 0;
|
|
Successive_count = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (Disable_editor_rendering)
|
|
return;
|
|
|
|
FrameCount++;
|
|
|
|
if (m_grScreen == NULL)
|
|
return;
|
|
if (m_grViewport == NULL)
|
|
return;
|
|
|
|
rad_Viewport = m_grViewport;
|
|
|
|
TexGrStartOpenGL();
|
|
|
|
ResetPostrenderList();
|
|
// Reset fog
|
|
Num_fogged_rooms_this_frame = 0;
|
|
if (Editor_view_mode == VM_ROOM) {
|
|
if ((D3EditState.current_room == -1) || (Rooms[D3EditState.current_room].used < 1)) {
|
|
TexGrStopOpenGL();
|
|
return;
|
|
}
|
|
|
|
// Disable render-all-rooms in room view
|
|
bool save_RAER = Render_all_external_rooms;
|
|
Render_all_external_rooms = 0;
|
|
|
|
// Render
|
|
TGWRenderMine(&Viewer_object->pos, &Viewer_object->orient, D3_DEFAULT_ZOOM, D3EditState.current_room);
|
|
|
|
// Restore render-all-rooms state
|
|
Render_all_external_rooms = save_RAER;
|
|
} else if (Editor_view_mode == VM_TERRAIN) {
|
|
|
|
if (GetFunctionMode() == EDITOR_MODE) {
|
|
DrawPlayerOnWireframe();
|
|
if (!Flat_terrain && (Viewer_object->pos.y < GetTerrainGroundPoint(&Viewer_object->pos) + 5))
|
|
Viewer_object->pos.y = GetTerrainGroundPoint(&Viewer_object->pos) + 5;
|
|
}
|
|
|
|
StartEditorFrame(m_grViewport, &Viewer_object->pos, &Viewer_object->orient, D3_DEFAULT_ZOOM);
|
|
RenderTerrain(0);
|
|
// we need to save these for object movement.
|
|
g3_GetViewPosition(&m_ViewPos);
|
|
g3_GetViewMatrix(&m_ViewMatrix);
|
|
EndEditorFrame();
|
|
|
|
if (KEY_STATE(KEY_X)) {
|
|
vector pos;
|
|
float yval;
|
|
|
|
ComputeTerrainSegmentCenter(&pos, (128 * TERRAIN_WIDTH) + 128);
|
|
yval = GetTerrainGroundPoint(&pos);
|
|
|
|
pos.y = yval;
|
|
Viewer_object->pos = pos;
|
|
ObjSetOrient(Viewer_object, &Identity_matrix);
|
|
World_changed = 1;
|
|
}
|
|
} else // Mine view
|
|
{
|
|
TGWRenderMine(&Viewer_object->pos, &Viewer_object->orient, D3_DEFAULT_ZOOM, Viewer_object->roomnum);
|
|
}
|
|
|
|
PostRender(Viewer_object->roomnum);
|
|
|
|
// Draws all User Defined Paths
|
|
DrawAllPaths(m_grViewport, &Viewer_object->pos, &Viewer_object->orient, D3_DEFAULT_ZOOM);
|
|
EBNode_Draw(EBN_draw_type, m_grViewport, &Viewer_object->pos, &Viewer_object->orient, D3_DEFAULT_ZOOM);
|
|
|
|
TexGrStopOpenGL();
|
|
|
|
m_StartFlip = TRUE;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CTextureGrWnd message handlers
|
|
|
|
BOOL CTextureGrWnd::Create(RECT &rect, BOOL movable, CWnd *pParent) {
|
|
RECT new_rect;
|
|
DWORD dwstyle;
|
|
|
|
dwstyle = (movable ? GRWND_STYLE : GRWND_STATIC_STYLE);
|
|
|
|
::CopyRect(&new_rect, &rect);
|
|
::AdjustWindowRect(&new_rect, dwstyle, FALSE);
|
|
|
|
// We want this window to start at rect.left, rect.top.
|
|
if (new_rect.left < rect.left) {
|
|
int offx;
|
|
offx = rect.left - new_rect.left;
|
|
new_rect.left += offx;
|
|
new_rect.right += offx;
|
|
}
|
|
if (new_rect.top < rect.top) {
|
|
int offy;
|
|
offy = rect.top - new_rect.top;
|
|
new_rect.top += offy;
|
|
new_rect.bottom += offy;
|
|
}
|
|
|
|
::CopyRect(&rect, &new_rect);
|
|
|
|
m_grCreated = TRUE;
|
|
m_Movable = movable;
|
|
|
|
lstrcpy(m_Name, "Texture");
|
|
|
|
ObjectInBuffer = false;
|
|
|
|
return CWnd::Create(NULL, m_Name, dwstyle, rect, pParent, IDC_TEXTURE_WND);
|
|
}
|
|
|
|
void CTextureGrWnd::OnSize(UINT nType, int cx, int cy) {
|
|
RECT rect;
|
|
char text[32];
|
|
|
|
CGrWnd::OnSize(nType, cx, cy);
|
|
|
|
if (m_Movable) { // don't define these if this box is static
|
|
D3EditState.texscr_w = cx;
|
|
D3EditState.texscr_h = cy;
|
|
}
|
|
|
|
GetClientRect(&rect);
|
|
sprintf(text, "Texture (%dx%d)", rect.right - rect.left, rect.bottom - rect.top);
|
|
lstrcpy(m_Name, text);
|
|
SetWindowText(m_Name);
|
|
}
|
|
|
|
void CTextureGrWnd::OnPaint() {
|
|
CPaintDC dc(this); // device context for painting
|
|
|
|
// Draw what's on the screen back page to the desktop
|
|
if (theApp.paused())
|
|
return;
|
|
|
|
if (m_StartFlip) { // do if a flip was signaled
|
|
m_StartFlip = FALSE;
|
|
|
|
if (DoOpenGL) {
|
|
HWND save_wnd;
|
|
oeLnxApplication *app;
|
|
|
|
app = (oeLnxApplication *)Descent;
|
|
|
|
// save_wnd = (HWND)app->m_hWnd;
|
|
// app->m_hWnd = (HWnd)m_hWnd;
|
|
// rend_SetOpenGLWindowState (1,Descent,NULL); // LGT: not defined anymore
|
|
|
|
rend_Flip();
|
|
|
|
// rend_SetOpenGLWindowState (0,Descent,NULL); // LGT: not defined anymore
|
|
// app->m_hWnd = (HWnd)save_wnd;
|
|
} else {
|
|
m_grScreen->flip();
|
|
m_grViewport->clear();
|
|
}
|
|
}
|
|
|
|
// Do not call CWnd::OnPaint() for painting messages
|
|
if (!m_Movable) { // print out window title, since there is no caption
|
|
dc.SetBkMode(TRANSPARENT);
|
|
dc.SetTextColor(RGB(192, 192, 192));
|
|
dc.TextOut(10, 10, m_Name, lstrlen(m_Name));
|
|
// m_grViewport->puts(10,10, m_Name);
|
|
}
|
|
}
|
|
|
|
void CTextureGrWnd::OnDestroy() {
|
|
// mprintf(0, "CTextureGrWnd::OnDestroy:: m_grScreen\n");
|
|
CGrWnd::OnDestroy();
|
|
theApp.textured_view = NULL;
|
|
}
|
|
|
|
void CTextureGrWnd::OnMove(int x, int y) {
|
|
CGrWnd::OnMove(x, y);
|
|
|
|
// Must do this to adjust window rect to view's client.
|
|
if (m_Movable) {
|
|
RECT rect;
|
|
GetWindowRect(&rect);
|
|
GetParent()->ScreenToClient(&rect);
|
|
D3EditState.texscr_x = rect.left;
|
|
D3EditState.texscr_y = rect.top;
|
|
}
|
|
}
|
|
|
|
int CTextureGrWnd::OnCreate(LPCREATESTRUCT lpCreateStruct) {
|
|
if (CGrWnd::OnCreate(lpCreateStruct) == -1)
|
|
return -1;
|
|
|
|
// TODO: Add your specialized creation code here
|
|
theApp.textured_view = this;
|
|
|
|
return 0;
|
|
}
|
|
|
|
void CTextureGrWnd::OnSysCommand(UINT nID, LPARAM lParam) {
|
|
// TODO: Add your message handler code here and/or call default
|
|
// take care of 'close' box for one thing
|
|
|
|
switch (nID) {
|
|
case SC_CLOSE:
|
|
D3EditState.texscr_visible = 0;
|
|
break;
|
|
}
|
|
|
|
CWnd::OnSysCommand(nID, lParam);
|
|
}
|
|
|
|
BOOL CTextureGrWnd::OnNcActivate(BOOL bActive) {
|
|
// TODO: Add your message handler code here and/or call default
|
|
|
|
return CGrWnd::OnNcActivate(bActive);
|
|
}
|
|
|
|
void CTextureGrWnd::OnNcPaint() { CGrWnd::OnNcPaint(); }
|
|
|
|
int Tracing_drops = 0;
|
|
int Drop_seg = 0;
|
|
|
|
int CTextureGrWnd::TGWFindRoomFace(int x, int y, int *roomnum, int *facenum) {
|
|
/*if (m_last_start_room == -1)
|
|
return 0;
|
|
if (! Rooms[m_last_start_room].used)
|
|
return 0;
|
|
|
|
int ret;
|
|
|
|
StartEditorFrame(m_grViewport,&m_last_viewer_eye,&m_last_viewer_orient,m_last_zoom);
|
|
|
|
ret = FindRoomFace(x,y,m_last_start_room,roomnum,facenum);
|
|
PostRender(Viewer_object->roomnum);
|
|
|
|
EndEditorFrame();*/
|
|
|
|
return 0;
|
|
}
|
|
|
|
int CTextureGrWnd::TGWFindLightmapFace(int x, int y, int *roomnum, int *facenum, int *lumel_num) {
|
|
/*if (! Rooms[m_last_start_room].used)
|
|
return 0;
|
|
|
|
int ret;
|
|
|
|
StartEditorFrame(m_grViewport,&m_last_viewer_eye,&m_last_viewer_orient,m_last_zoom);
|
|
|
|
ret = FindLightmapFace(x,y,m_last_start_room,roomnum,facenum,lumel_num);
|
|
|
|
EndEditorFrame();*/
|
|
|
|
return 0;
|
|
}
|
|
|
|
void CTextureGrWnd::TGWRenderMine(vector *pos, matrix *orient, float zoom, int start_roomnum) {
|
|
if (start_roomnum < 0 || start_roomnum > MAX_ROOMS + MAX_PALETTE_ROOMS)
|
|
return;
|
|
|
|
// save these vars for possible use by FindRoomFace()
|
|
m_last_viewer_eye = *pos;
|
|
m_last_viewer_orient = *orient;
|
|
m_last_zoom = zoom;
|
|
m_last_start_room = start_roomnum;
|
|
|
|
StartEditorFrame(m_grViewport, pos, orient, zoom);
|
|
FrameCount++;
|
|
|
|
RenderMine(start_roomnum, 0, 0);
|
|
PostRender(Viewer_object->roomnum);
|
|
|
|
// we need to save these for object movement.
|
|
g3_GetViewPosition(&m_ViewPos);
|
|
g3_GetViewMatrix(&m_ViewMatrix);
|
|
|
|
EndEditorFrame();
|
|
}
|
|
|
|
// Set the current object
|
|
void SelectObject(int objnum);
|
|
|
|
void CTextureGrWnd::OnLButtonDown(UINT nFlags, CPoint point) {
|
|
TexGrStartOpenGL();
|
|
|
|
ResetPostrenderList();
|
|
|
|
if (Editor_view_mode == VM_ROOM) {
|
|
TSearch_found_type = -1;
|
|
TSearch_seg = -1;
|
|
TSearch_on = 1;
|
|
TSearch_x = point.x;
|
|
TSearch_y = point.y;
|
|
|
|
TGWRenderMine(&Viewer_object->pos, &Viewer_object->orient, D3_DEFAULT_ZOOM, Viewer_object->roomnum);
|
|
|
|
TSearch_on = 0;
|
|
|
|
if (TSearch_found_type == TSEARCH_FOUND_MINE) {
|
|
Current_faces[TSearch_seg - FIRST_PALETTE_ROOM] = TSearch_face;
|
|
EditorStatus("Face %d selected.", TSearch_face);
|
|
State_changed = 1;
|
|
return;
|
|
}
|
|
} else if (Editor_view_mode == VM_TERRAIN) {
|
|
TSearch_found_type = -1;
|
|
TSearch_seg = -1;
|
|
TSearch_on = 1;
|
|
TSearch_x = point.x;
|
|
TSearch_y = point.y;
|
|
|
|
StartEditorFrame(m_grViewport, &Viewer_object->pos, &Viewer_object->orient, D3_DEFAULT_ZOOM);
|
|
RenderTerrain(0);
|
|
PostRender(Viewer_object->roomnum);
|
|
EndEditorFrame();
|
|
TSearch_on = 0;
|
|
if (TSearch_found_type != -1) {
|
|
|
|
// Check for objects
|
|
if (TSearch_found_type == TSEARCH_FOUND_OBJECT) {
|
|
// Found an object
|
|
mprintf(0, "Found an object! objnum=%d\n", TSearch_seg);
|
|
SelectObject(TSearch_seg);
|
|
// start object moving if mouse down in an object.
|
|
ObjMoveManager.Start(this, m_grViewport->width(), m_grViewport->height(), &m_ViewPos, &m_ViewMatrix, point.x,
|
|
point.y);
|
|
}
|
|
|
|
if (TSearch_found_type == TSEARCH_FOUND_SKY_DOME) {
|
|
if (nFlags & MK_SHIFT) {
|
|
Terrain_sky.dome_texture = D3EditState.texdlg_texture;
|
|
|
|
World_changed = 1;
|
|
TV_changed = 1;
|
|
}
|
|
}
|
|
|
|
// Check for satellite
|
|
if (TSearch_found_type == TSEARCH_FOUND_SATELLITE) {
|
|
if (nFlags & MK_SHIFT) {
|
|
Terrain_sky.satellite_texture[TSearch_seg] = D3EditState.texdlg_texture;
|
|
theApp.main_frame->m_TerrainDialog->SetCurrentMoon(TSearch_seg);
|
|
World_changed = 1;
|
|
TV_changed = 1;
|
|
}
|
|
|
|
else {
|
|
theApp.main_frame->m_TerrainDialog->SetCurrentMoon(TSearch_seg);
|
|
if (KEY_STATE(KEY_G))
|
|
D3EditState.texdlg_texture = Terrain_sky.satellite_texture[TSearch_seg];
|
|
}
|
|
}
|
|
|
|
if (TSearch_found_type == TSEARCH_FOUND_TERRAIN) {
|
|
if (KEY_STATE(KEY_P)) {
|
|
Tracing_drops = 1;
|
|
Drop_seg = TSearch_seg;
|
|
Terrain_tex_seg[Terrain_seg[Drop_seg].texseg_index].tex_index = 0;
|
|
} else if (KEY_STATE(KEY_R)) {
|
|
// Rotate this texture
|
|
int val = Terrain_tex_seg[Terrain_seg[TSearch_seg].texseg_index].rotation & 0x0F;
|
|
val++;
|
|
val %= 4;
|
|
Terrain_tex_seg[Terrain_seg[TSearch_seg].texseg_index].rotation &= ~0x0F;
|
|
Terrain_tex_seg[Terrain_seg[TSearch_seg].texseg_index].rotation |= val;
|
|
|
|
TV_changed = 1;
|
|
}
|
|
|
|
if (nFlags & MK_SHIFT) {
|
|
|
|
Terrain_tex_seg[Terrain_seg[TSearch_seg].texseg_index].tex_index = D3EditState.texdlg_texture;
|
|
TV_changed = 1;
|
|
} else if (nFlags & MK_CONTROL) {
|
|
if (TerrainSelected[TSearch_seg]) {
|
|
TerrainSelected[TSearch_seg] = 0;
|
|
Num_terrain_selected--;
|
|
} else {
|
|
TerrainSelected[TSearch_seg] = 1;
|
|
Num_terrain_selected++;
|
|
}
|
|
TV_changed = 1;
|
|
} else {
|
|
memset(TerrainSelected, 0, TERRAIN_WIDTH * TERRAIN_DEPTH);
|
|
EditorStatus("Cell %d selected. Light=%d Height=%.2f (%d). Texture=%s", TSearch_seg,
|
|
Terrain_seg[TSearch_seg].l, Terrain_seg[TSearch_seg].y, Terrain_seg[TSearch_seg].ypos,
|
|
GameTextures[Terrain_tex_seg[Terrain_seg[TSearch_seg].texseg_index].tex_index].name);
|
|
TerrainSelected[TSearch_seg]++;
|
|
Num_terrain_selected = 1;
|
|
TV_changed = 1;
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
int roomnum, facenum;
|
|
|
|
// mprintf(0,"ButtonDown %d,%d\n",point.x,point.y);
|
|
TSearch_found_type = -1;
|
|
TSearch_seg = -1;
|
|
TSearch_on = 1;
|
|
TSearch_x = point.x;
|
|
TSearch_y = point.y;
|
|
|
|
TGWRenderMine(&Viewer_object->pos, &Viewer_object->orient, D3_DEFAULT_ZOOM, Viewer_object->roomnum);
|
|
TSearch_on = 0;
|
|
|
|
// this looks at the last frame rendered
|
|
if (TSearch_found_type == TSEARCH_FOUND_OBJECT) {
|
|
// Found a face or object
|
|
m_StartFlip = FALSE; // unsignal flip.
|
|
SelectObject(TSearch_seg);
|
|
// start object moving if mouse down in an object.
|
|
ObjMoveManager.Start(this, m_grViewport->width(), m_grViewport->height(), &m_ViewPos, &m_ViewMatrix, point.x,
|
|
point.y);
|
|
} else if (TSearch_found_type == TSEARCH_FOUND_MINE) {
|
|
roomnum = TSearch_seg;
|
|
facenum = TSearch_face;
|
|
|
|
if (nFlags & MK_SHIFT) { // apply current texture to face
|
|
HTextureApplyToRoomFace(&Rooms[TSearch_seg], TSearch_face, D3EditState.texdlg_texture);
|
|
EditorStatus("Texture %d applied to room %d face %d\n", D3EditState.texdlg_texture, TSearch_seg, TSearch_face);
|
|
World_changed = 1;
|
|
} else if (KEY_STATE(KEY_J)) // apply texture, scaling UVs based on texture size
|
|
{
|
|
int old_width = bm_w(GetTextureBitmap(Rooms[TSearch_seg].faces[TSearch_face].tmap, 0), 0);
|
|
int new_width = bm_w(GetTextureBitmap(D3EditState.texdlg_texture, 0), 0);
|
|
HTextureApplyToRoomFace(&Rooms[TSearch_seg], TSearch_face, D3EditState.texdlg_texture);
|
|
ScaleFaceUVs(&Rooms[TSearch_seg], TSearch_face, (float)old_width / new_width);
|
|
EditorStatus("Texture %d applied to room %d face %d\n", D3EditState.texdlg_texture, TSearch_seg, TSearch_face);
|
|
World_changed = 1;
|
|
} else if (KEY_STATE(KEY_P)) {
|
|
// P + Click = Propagate from current face
|
|
if ((TSearch_seg == ROOMNUM(Curroomp)) && (TSearch_face == Curface))
|
|
EditorStatus("Cannot propagate from a face to itself.");
|
|
else if (HTexturePropagateToFace(&Rooms[roomnum], facenum, Curroomp, Curface)) {
|
|
EditorStatus("Texture propagated from %d:%d to %d:%d\n", ROOMNUM(Curroomp), Curface, roomnum, facenum);
|
|
World_changed = 1;
|
|
} else {
|
|
OutrageMessageBox("Room:face %d:%d is not adjacent to Current room:face (%d:%d)", roomnum, facenum,
|
|
ROOMNUM(Curroomp), Curface);
|
|
return;
|
|
}
|
|
} else if (KEY_STATE(KEY_E)) {
|
|
// C + Click = Copy uv values from marked face
|
|
static int last_copy_marked_room = -1, last_copy_marked_face = -1;
|
|
static int last_copy_room = -1, last_copy_face = -1;
|
|
static int count;
|
|
|
|
if (Markedroomp == NULL) {
|
|
OutrageMessageBox("You must have a marked face for this operation.");
|
|
return;
|
|
}
|
|
|
|
if ((roomnum == ROOMNUM(Markedroomp)) && (facenum == Markedface))
|
|
EditorStatus("Cannot copy from a face to itself.");
|
|
else {
|
|
if ((last_copy_marked_room == ROOMNUM(Markedroomp)) && (last_copy_marked_face == Markedface) &&
|
|
(last_copy_room == roomnum) && (last_copy_face == facenum))
|
|
count++;
|
|
else {
|
|
count = 0;
|
|
last_copy_marked_room = ROOMNUM(Markedroomp);
|
|
last_copy_marked_face = Markedface;
|
|
last_copy_room = roomnum;
|
|
last_copy_face = facenum;
|
|
}
|
|
|
|
if (HTextureCopyUVsToFace(&Rooms[roomnum], facenum, Markedroomp, Markedface, count)) {
|
|
Rooms[roomnum].faces[facenum].tmap = Markedroomp->faces[Markedface].tmap;
|
|
EditorStatus("Texture & UVs copied from %d:%d to %d:%d (rotation = %d/%d)\n", ROOMNUM(Markedroomp),
|
|
Markedface, roomnum, facenum, count % Markedroomp->faces[Markedface].num_verts,
|
|
Markedroomp->faces[Markedface].num_verts);
|
|
World_changed = 1;
|
|
} else
|
|
EditorStatus("Can't copy UVs: faces don't have the same number of vertices.");
|
|
}
|
|
} else if (KEY_STATE(KEY_N)) {
|
|
vector vec = Rooms[roomnum].verts[Rooms[roomnum].faces[facenum].face_verts[0]];
|
|
vector norm = Rooms[roomnum].faces[facenum].normal;
|
|
float plane_dist = -(vec.x * norm.x + vec.y * norm.y + vec.z * norm.z);
|
|
int i;
|
|
for (i = 0; i < Rooms[roomnum].faces[facenum].num_verts; i++) {
|
|
vec = Rooms[roomnum].verts[Rooms[roomnum].faces[facenum].face_verts[i]];
|
|
float dist = vec.x * norm.x + vec.y * norm.y + vec.z * norm.z + plane_dist;
|
|
mprintf(0, "Vertex %d distance from plane=%f\n", i, dist);
|
|
}
|
|
} else if (KEY_STATE(KEY_V)) {
|
|
// Do visibility check
|
|
int rooma = (Markedroomp - Rooms);
|
|
int roomb = (Curroomp - Rooms);
|
|
int answer = BOA_IsVisible(rooma, roomb);
|
|
|
|
mprintf(0, "Answer 1 is %d\n", answer);
|
|
|
|
answer = BOA_IsVisible(roomb, rooma);
|
|
|
|
mprintf(0, "Answer 2 is %d\n", answer);
|
|
} else { // Just change curface
|
|
State_changed = 1;
|
|
EditorStatus("Current room:face set to %d:%d", roomnum, facenum);
|
|
}
|
|
|
|
// All clicks on face change the current face
|
|
Curroomp = &Rooms[roomnum];
|
|
Curface = facenum;
|
|
Curedge = Curvert = 0;
|
|
Curportal = -1;
|
|
}
|
|
}
|
|
|
|
TexGrStopOpenGL();
|
|
|
|
CWnd::OnLButtonDown(nFlags, point);
|
|
}
|
|
|
|
void CTextureGrWnd::OnMouseMove(UINT nFlags, CPoint point) { CWnd::OnMouseMove(nFlags, point); }
|
|
|
|
void CTextureGrWnd::OnRButtonDown(UINT nFlags, CPoint point) {
|
|
int n = D3EditState.current_megacell;
|
|
int newobjnum = -1;
|
|
bool do_popup = false;
|
|
|
|
TexGrStartOpenGL();
|
|
|
|
if (Editor_view_mode == VM_TERRAIN) {
|
|
TSearch_seg = -1;
|
|
TSearch_on = 1;
|
|
TSearch_x = point.x;
|
|
TSearch_y = point.y;
|
|
TSearch_found_type = -1;
|
|
|
|
StartEditorFrame(m_grViewport, &Viewer_object->pos, &Viewer_object->orient, D3_DEFAULT_ZOOM);
|
|
RenderTerrain(0);
|
|
PostRender(Viewer_object->roomnum);
|
|
EndEditorFrame();
|
|
TSearch_on = 0;
|
|
if (TSearch_found_type == TSEARCH_FOUND_TERRAIN) {
|
|
if (nFlags & MK_SHIFT) {
|
|
int w = Megacells[n].width;
|
|
int h = Megacells[n].height;
|
|
|
|
for (int i = 0; i < h; i++) {
|
|
for (int t = 0; t < w; t++) {
|
|
int terrain_x = (TSearch_seg % TERRAIN_WIDTH) + t;
|
|
int terrain_z = (TSearch_seg / TERRAIN_WIDTH) - i;
|
|
int mx, my;
|
|
|
|
if (terrain_x < 0 || terrain_x >= TERRAIN_WIDTH)
|
|
continue;
|
|
if (terrain_z < 0 || terrain_z >= TERRAIN_DEPTH)
|
|
continue;
|
|
|
|
if (D3EditState.randomize_megacell) {
|
|
mx = rand() % w;
|
|
my = rand() % h;
|
|
} else {
|
|
mx = t;
|
|
my = i;
|
|
}
|
|
|
|
TV_changed = 1;
|
|
}
|
|
}
|
|
}
|
|
if (nFlags & MK_CONTROL) {
|
|
int x, z, i, t;
|
|
|
|
for (i = 0; i < TERRAIN_DEPTH * TERRAIN_WIDTH; i++) {
|
|
if (TerrainSelected[i]) {
|
|
x = i % TERRAIN_WIDTH;
|
|
z = i / TERRAIN_WIDTH;
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (i == TERRAIN_DEPTH * TERRAIN_WIDTH)
|
|
return; // nothing to do!
|
|
|
|
Num_terrain_selected = 0;
|
|
memset(TerrainSelected, 0, TERRAIN_WIDTH * TERRAIN_DEPTH);
|
|
|
|
int terrain_x = (TSearch_seg % TERRAIN_WIDTH);
|
|
int terrain_z = (TSearch_seg / TERRAIN_WIDTH);
|
|
|
|
int width = abs(terrain_x - x);
|
|
int height = abs(terrain_z - z);
|
|
int start_x = x;
|
|
int start_z = z;
|
|
|
|
if (terrain_x < x)
|
|
start_x = terrain_x;
|
|
if (terrain_z < z)
|
|
start_z = terrain_z;
|
|
|
|
for (i = 0; i <= height; i++)
|
|
for (t = 0; t <= width; t++) {
|
|
Num_terrain_selected++;
|
|
TerrainSelected[((i + start_z) * TERRAIN_WIDTH) + start_x + t] = 1;
|
|
}
|
|
}
|
|
}
|
|
// Check for objects
|
|
else if (TSearch_found_type == TSEARCH_FOUND_OBJECT) {
|
|
newobjnum = TSearch_seg;
|
|
do_popup = true;
|
|
|
|
mprintf(0, "Found an object! objnum=%d\n", newobjnum);
|
|
SelectObject(newobjnum);
|
|
|
|
Render();
|
|
RedrawWindow(NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW);
|
|
}
|
|
}
|
|
// Code to put up popup menu when right clicking
|
|
else {
|
|
int roomnum, facenum;
|
|
|
|
TSearch_found_type = -1;
|
|
TSearch_seg = -1;
|
|
TSearch_on = 1;
|
|
TSearch_x = point.x;
|
|
TSearch_y = point.y;
|
|
|
|
TGWRenderMine(&Viewer_object->pos, &Viewer_object->orient, D3_DEFAULT_ZOOM, Viewer_object->roomnum);
|
|
TSearch_on = 0;
|
|
|
|
// this looks at the last frame rendered
|
|
if (TSearch_found_type == TSEARCH_FOUND_MINE || TSearch_found_type == TSEARCH_FOUND_OBJECT) {
|
|
roomnum = TSearch_seg;
|
|
facenum = TSearch_face;
|
|
m_StartFlip = FALSE; // unsignal flip.
|
|
mprintf(0, "found point: %d %d %d\n", roomnum, facenum);
|
|
|
|
do_popup = true;
|
|
|
|
if (TSearch_found_type == TSEARCH_FOUND_OBJECT) { // found an object
|
|
newobjnum = (roomnum);
|
|
SelectObject(newobjnum);
|
|
}
|
|
}
|
|
|
|
Render();
|
|
RedrawWindow(NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW);
|
|
}
|
|
|
|
// right click popup menu
|
|
if (do_popup) {
|
|
CMenu popup;
|
|
bool ret = true;
|
|
char *title = NULL;
|
|
|
|
if (newobjnum > -1)
|
|
title = Objects[newobjnum].name;
|
|
|
|
if (popup.CreatePopupMenu())
|
|
ret = SetupPopup(&popup, title);
|
|
else {
|
|
mprintf(0, "Warning: Could not create popup menu!\n");
|
|
ret = false;
|
|
}
|
|
|
|
if (newobjnum > -1) {
|
|
object *foundobj = &Objects[newobjnum];
|
|
if (!ObjectInBuffer)
|
|
popup.EnableMenuItem(POPUP_PASTE, MF_GRAYED);
|
|
if (foundobj->control_type != CT_SOUNDSOURCE)
|
|
popup.EnableMenuItem(POPUP_SOUND, MF_GRAYED);
|
|
} else {
|
|
popup.EnableMenuItem(POPUP_OBJNAME, MF_GRAYED);
|
|
popup.EnableMenuItem(POPUP_EDITNAME, MF_GRAYED);
|
|
popup.EnableMenuItem(POPUP_EDITSCRIPT, MF_GRAYED);
|
|
popup.EnableMenuItem(POPUP_NEWSCRIPT, MF_GRAYED);
|
|
popup.EnableMenuItem(POPUP_CUT, MF_GRAYED);
|
|
popup.EnableMenuItem(POPUP_COPY, MF_GRAYED);
|
|
popup.EnableMenuItem(POPUP_SOUND, MF_GRAYED);
|
|
if (!ObjectInBuffer)
|
|
popup.EnableMenuItem(POPUP_PASTE, MF_GRAYED);
|
|
popup.EnableMenuItem(POPUP_DELETE, MF_GRAYED);
|
|
}
|
|
|
|
if (ret)
|
|
if (!popup.TrackPopupMenu(TPM_LEFTALIGN, point.x, point.y + 20, this, NULL))
|
|
mprintf(0, "TrackPopupMenu error!\n");
|
|
}
|
|
|
|
TexGrStopOpenGL();
|
|
|
|
CWnd::OnRButtonDown(nFlags, point);
|
|
}
|
|
|
|
//=================
|
|
// Sets up the popup menu for a right click
|
|
// Parameters: popup: pointer to CMenu object
|
|
// Returns: true if everything went ok
|
|
// Notes: The CMenu object must be initialized before sent to this function (use CreatePopupMenu())
|
|
//=================
|
|
bool CTextureGrWnd::SetupPopup(CMenu *popup, char *title) {
|
|
bool ret;
|
|
ret = true;
|
|
|
|
if (!popup->AppendMenu(MF_STRING + MF_DISABLED, POPUP_OBJNAME, title ? title : "(no name)")) {
|
|
ret = false;
|
|
mprintf(0, "Warning: Could not add Title to popup\n");
|
|
}
|
|
if (!popup->AppendMenu(MF_SEPARATOR)) {
|
|
ret = false;
|
|
mprintf(0, "Warning: Could not add seperator to popup\n");
|
|
}
|
|
if (!popup->AppendMenu(MF_STRING, POPUP_COPY, "Copy")) {
|
|
ret = false;
|
|
mprintf(0, "Warning: Could not add Copy to popup\n");
|
|
}
|
|
if (!popup->AppendMenu(MF_STRING, POPUP_CUT, "Cut")) {
|
|
ret = false;
|
|
mprintf(0, "Warning: Could not add Cut to popup\n");
|
|
}
|
|
if (!popup->AppendMenu(MF_STRING, POPUP_PASTE, "Paste")) {
|
|
ret = false;
|
|
mprintf(0, "Warning: Could not add Paste to popup\n");
|
|
}
|
|
if (!popup->AppendMenu(MF_STRING, POPUP_DELETE, "Delete")) {
|
|
ret = false;
|
|
mprintf(0, "Warning: Could not add Delete to popup\n");
|
|
}
|
|
if (!popup->AppendMenu(MF_SEPARATOR)) {
|
|
ret = false;
|
|
mprintf(0, "Warning: Could not add seperator to popup\n");
|
|
}
|
|
if (!popup->AppendMenu(MF_STRING, POPUP_EDITNAME, "Edit Name")) {
|
|
ret = false;
|
|
mprintf(0, "Warning: Could not add Edit Name to popup\n");
|
|
}
|
|
if (!popup->AppendMenu(MF_STRING, POPUP_SOUND, "Sound")) {
|
|
ret = false;
|
|
mprintf(0, "Warning: Could not add Sound to popup\n");
|
|
}
|
|
if (!popup->AppendMenu(MF_STRING, POPUP_EDITSCRIPT, "Edit Dallas Scripts")) {
|
|
ret = false;
|
|
mprintf(0, "Warning: Could not add Edit Script to popup\n");
|
|
}
|
|
if (!popup->AppendMenu(MF_STRING, POPUP_NEWSCRIPT, "New Dallas Script")) {
|
|
ret = false;
|
|
mprintf(0, "Warning: Could not add New Script to popup\n");
|
|
}
|
|
if (!popup->AppendMenu(MF_STRING, POPUP_CUSTOMDEFAULTSCRIPT, "Set a custom default script")) {
|
|
ret = false;
|
|
mprintf(0, "Warning: Could not add Set a custom default script to popup\n");
|
|
}
|
|
//@@if(!popup->AppendMenu(MF_STRING,POPUP_PROPERTIES,"Properties"))
|
|
//@@{
|
|
//@@ ret=false;
|
|
//@@ mprintf(0,"Warning: Could not add Properties to popup\n");
|
|
//@@}
|
|
//@@if(!popup->AppendMenu(MF_STRING,POPUP_COPYID,"Copy UID"))
|
|
//@@{
|
|
//@@ ret=false;
|
|
//@@ mprintf(0,"Warning: Could not add Copy UID to popup\n");
|
|
//@@}
|
|
return ret;
|
|
}
|
|
|
|
void UpdateProperties(CObjectPropertiesDialog *prop_dlg) {
|
|
|
|
object *curobj;
|
|
curobj = &Objects[Cur_object_index];
|
|
|
|
curobj->mtype.phys_info.velocity.x = prop_dlg->m_fVelocityX;
|
|
curobj->mtype.phys_info.velocity.y = prop_dlg->m_fVelocityY;
|
|
curobj->mtype.phys_info.velocity.z = prop_dlg->m_fVelocityZ;
|
|
|
|
curobj->mtype.phys_info.thrust.x = prop_dlg->m_fThrustX;
|
|
curobj->mtype.phys_info.thrust.y = prop_dlg->m_fThrustY;
|
|
curobj->mtype.phys_info.thrust.z = prop_dlg->m_fThrustZ;
|
|
|
|
curobj->mtype.phys_info.rotvel.x = prop_dlg->m_fRotVelX;
|
|
curobj->mtype.phys_info.rotvel.y = prop_dlg->m_fRotVelY;
|
|
curobj->mtype.phys_info.rotvel.z = prop_dlg->m_fRotVelZ;
|
|
|
|
curobj->mtype.phys_info.rotthrust.x = prop_dlg->m_fRotThrustX;
|
|
curobj->mtype.phys_info.rotthrust.y = prop_dlg->m_fRotThrustY;
|
|
curobj->mtype.phys_info.rotthrust.z = prop_dlg->m_fRotThrustZ;
|
|
|
|
curobj->mtype.phys_info.turnroll = prop_dlg->m_sTurnrollAngle;
|
|
curobj->mtype.phys_info.num_bounces = prop_dlg->m_iNumBounces;
|
|
curobj->mtype.phys_info.mass = prop_dlg->m_fMass;
|
|
curobj->mtype.phys_info.drag = prop_dlg->m_fDrag;
|
|
curobj->mtype.phys_info.rotdrag = prop_dlg->m_fRotDrag;
|
|
curobj->mtype.phys_info.full_thrust = prop_dlg->m_fFullThrust;
|
|
curobj->mtype.phys_info.full_rotthrust = prop_dlg->m_fFullRotThrust;
|
|
curobj->mtype.phys_info.max_turnroll_rate = prop_dlg->m_fMaxTurnrollrate;
|
|
curobj->mtype.phys_info.turnroll_ratio = prop_dlg->m_fTurnrollRatio;
|
|
curobj->mtype.phys_info.wiggle_amplitude = prop_dlg->m_fWiggleAmplitude;
|
|
curobj->mtype.phys_info.wiggles_per_sec = prop_dlg->m_fWigglesPerSecond;
|
|
|
|
curobj->mtype.phys_info.flags = 0;
|
|
|
|
if (prop_dlg->m_bTurnroll)
|
|
curobj->mtype.phys_info.flags |= PF_TURNROLL;
|
|
if (prop_dlg->m_bLevelling)
|
|
curobj->mtype.phys_info.flags |= PF_LEVELING;
|
|
if (prop_dlg->m_bBounce)
|
|
curobj->mtype.phys_info.flags |= PF_BOUNCE;
|
|
if (prop_dlg->m_bWiggle)
|
|
curobj->mtype.phys_info.flags |= PF_WIGGLE;
|
|
if (prop_dlg->m_bSticks)
|
|
curobj->mtype.phys_info.flags |= PF_STICK;
|
|
if (prop_dlg->m_bPersistent)
|
|
curobj->mtype.phys_info.flags |= PF_PERSISTENT;
|
|
if (prop_dlg->m_bUsesThrust)
|
|
curobj->mtype.phys_info.flags |= PF_USES_THRUST;
|
|
if (prop_dlg->m_bGravity)
|
|
curobj->mtype.phys_info.flags |= PF_GRAVITY;
|
|
if (prop_dlg->m_bMagnetism)
|
|
curobj->mtype.phys_info.flags |= PF_IGNORE_OWN_CONC_FORCES;
|
|
if (prop_dlg->m_bWind)
|
|
curobj->mtype.phys_info.flags |= PF_WIND;
|
|
|
|
if ((prop_dlg->m_bUnlimitedBounce) || (!prop_dlg->m_bBounce)) {
|
|
curobj->mtype.phys_info.num_bounces = -1;
|
|
}
|
|
}
|
|
|
|
#include "osiris_predefs.h"
|
|
extern bool StripLeadingTrailingSpaces(char *s);
|
|
|
|
BOOL CTextureGrWnd::OnCommand(WPARAM wParam, LPARAM lParam) {
|
|
// TODO: Add your specialized code here and/or call the base class
|
|
if (HIWORD(wParam) == 0) {
|
|
switch (LOWORD(wParam)) {
|
|
case POPUP_EDITSCRIPT: {
|
|
mprintf(0, "Edit script for object %d\n", Cur_object_index);
|
|
// Nate: Add code here to edit/view an object's scripts
|
|
|
|
// Make sure Dallas is open
|
|
if (theApp.m_DallasModelessDlgPtr == NULL) {
|
|
theApp.m_DallasModelessDlgPtr = new CDallasMainDlg;
|
|
theApp.m_DallasModelessDlgPtr->Create(IDD_DALLAS_MAIN_DIALOG, this);
|
|
theApp.m_DallasModelessDlgPtr->ShowWindow(SW_SHOW);
|
|
} else
|
|
theApp.m_DallasModelessDlgPtr->ShowWindow(SW_RESTORE);
|
|
|
|
object *curobj = &Objects[Cur_object_index];
|
|
if (curobj->name == NULL)
|
|
break;
|
|
|
|
// Tell Dallas to add a new script with this object as the owner
|
|
theApp.m_DallasModelessDlgPtr->m_ScriptOwnerType = OBJECT_TYPE;
|
|
theApp.m_DallasModelessDlgPtr->m_ScriptOwnerHandle = curobj->handle;
|
|
theApp.m_DallasModelessDlgPtr->PostMessage(WM_HIGHLIGHT_SCRIPTS);
|
|
} break;
|
|
|
|
case POPUP_NEWSCRIPT: {
|
|
mprintf(0, "Add new script for object %d\n", Cur_object_index);
|
|
// Nate: Add code here to create a new script for an object
|
|
|
|
// Make sure Dallas is open
|
|
if (theApp.m_DallasModelessDlgPtr == NULL) {
|
|
theApp.m_DallasModelessDlgPtr = new CDallasMainDlg;
|
|
theApp.m_DallasModelessDlgPtr->Create(IDD_DALLAS_MAIN_DIALOG, this);
|
|
theApp.m_DallasModelessDlgPtr->ShowWindow(SW_SHOW);
|
|
} else
|
|
theApp.m_DallasModelessDlgPtr->ShowWindow(SW_RESTORE);
|
|
|
|
object *curobj = &Objects[Cur_object_index];
|
|
if (curobj->name == NULL)
|
|
break;
|
|
|
|
// Tell Dallas to highlight all scripts that have this object as the owner
|
|
theApp.m_DallasModelessDlgPtr->m_ScriptOwnerType = OBJECT_TYPE;
|
|
theApp.m_DallasModelessDlgPtr->m_ScriptOwnerHandle = curobj->handle;
|
|
theApp.m_DallasModelessDlgPtr->PostMessage(WM_ADD_SCRIPT);
|
|
} break;
|
|
|
|
case POPUP_EDITNAME: {
|
|
if (Objects[Cur_object_index].type == OBJ_PLAYER) {
|
|
EditorMessageBox("You cannot name a player object.");
|
|
break;
|
|
}
|
|
|
|
char tempname[OBJ_NAME_LEN + 1] = "";
|
|
object *curobj = &Objects[Cur_object_index];
|
|
if (curobj->name) {
|
|
ASSERT(strlen(curobj->name) <= OBJ_NAME_LEN);
|
|
strcpy(tempname, curobj->name);
|
|
}
|
|
|
|
try_again:;
|
|
if (!InputString(tempname, OBJ_NAME_LEN, "Object Name", "Enter a new name:"))
|
|
break;
|
|
|
|
if (StripLeadingTrailingSpaces(tempname))
|
|
EditorMessageBox("Note: Leading and/or trailing spaces have been removed from this name (\"%s\")", tempname);
|
|
|
|
int handle = osipf_FindObjectName(tempname);
|
|
if ((handle != OBJECT_HANDLE_NONE) && (handle != curobj->handle)) {
|
|
EditorMessageBox("Object %d already has this name.", OBJNUM(ObjGet(handle)));
|
|
goto try_again;
|
|
}
|
|
|
|
if (curobj->name) {
|
|
mem_free(curobj->name);
|
|
curobj->name = NULL;
|
|
}
|
|
|
|
if (strlen(tempname)) {
|
|
curobj->name = (char *)mem_malloc(strlen(tempname) + 1);
|
|
strcpy(curobj->name, tempname);
|
|
}
|
|
|
|
World_changed = 1;
|
|
|
|
break;
|
|
}
|
|
|
|
case POPUP_CUSTOMDEFAULTSCRIPT: {
|
|
object *curobj = &Objects[Cur_object_index];
|
|
|
|
CCustDefaultScriptSelect dlg;
|
|
|
|
if (curobj->custom_default_script_name)
|
|
dlg.m_Name = curobj->custom_default_script_name;
|
|
else
|
|
dlg.m_Name = "";
|
|
|
|
if (curobj->custom_default_module_name)
|
|
dlg.m_Module = curobj->custom_default_module_name;
|
|
else
|
|
dlg.m_Module = "";
|
|
|
|
if (dlg.DoModal()) {
|
|
|
|
if (curobj->custom_default_module_name) {
|
|
mem_free(curobj->custom_default_module_name);
|
|
curobj->custom_default_module_name = NULL;
|
|
}
|
|
|
|
if (curobj->custom_default_script_name) {
|
|
mem_free(curobj->custom_default_script_name);
|
|
curobj->custom_default_script_name = NULL;
|
|
}
|
|
|
|
if (!dlg.m_Module.IsEmpty()) {
|
|
char module_name[MAX_MODULENAME_LEN];
|
|
curobj->custom_default_module_name = (char *)mem_malloc(dlg.m_Module.GetLength() + 1);
|
|
|
|
ddio_SplitPath(dlg.m_Module.GetBuffer(0), NULL, module_name, NULL);
|
|
strcpy(curobj->custom_default_module_name, module_name);
|
|
}
|
|
|
|
if (!dlg.m_Name.IsEmpty()) {
|
|
curobj->custom_default_script_name = (char *)mem_malloc(dlg.m_Name.GetLength() + 1);
|
|
strcpy(curobj->custom_default_script_name, dlg.m_Name.GetBuffer(0));
|
|
}
|
|
}
|
|
|
|
World_changed = 1; //?
|
|
|
|
} break;
|
|
|
|
//@@case POPUP_PROPERTIES:
|
|
//@@ {
|
|
//@@ CObjectPropertiesDialog prop_dlg;
|
|
//@@ object *curobj=&Objects[Cur_object_index];
|
|
//@@ mprintf(0,"Properties selected\n");
|
|
//@@ if(prop_dlg.DoModal()==IDOK) UpdateProperties(&prop_dlg);
|
|
//@@ break;
|
|
//@@ }
|
|
//@@
|
|
//@@case POPUP_COPYID:
|
|
//@@ Copied_object_id = Objects[Cur_object_index].handle;
|
|
//@@ break;
|
|
|
|
case POPUP_DELETE:
|
|
if (!ObjectDelete())
|
|
OutrageMessageBox("Could not Delete Object!");
|
|
break;
|
|
case POPUP_PASTE:
|
|
if (!ObjectPaste())
|
|
OutrageMessageBox("Could not Paste Object!");
|
|
break;
|
|
case POPUP_CUT:
|
|
if (!ObjectCut())
|
|
OutrageMessageBox("Could not Cut Object!");
|
|
break;
|
|
case POPUP_COPY:
|
|
if (!ObjectCopy())
|
|
OutrageMessageBox("Could not Copy Object!");
|
|
break;
|
|
|
|
case POPUP_SOUND: {
|
|
CSoundSourceDialog dlg(&Objects[Cur_object_index].ctype.soundsource_info);
|
|
dlg.DoModal();
|
|
}
|
|
}
|
|
}
|
|
return CWnd::OnCommand(wParam, lParam);
|
|
}
|
|
|
|
// Shows radiosity progress in the texture window.
|
|
// This function needs to go in this file because of the stupid MFC
|
|
// problems that occur if you try to access MFC member variables from a non-
|
|
// MFC file
|
|
void ShowRadView() {
|
|
grSurface *cur_surf;
|
|
int i, t;
|
|
|
|
CTextureGrWnd *tview = theApp.textured_view;
|
|
|
|
cur_surf = rad_Viewport->lock();
|
|
uint16_t *dest = (uint16_t *)cur_surf->data();
|
|
int rowsize = cur_surf->rowsize() / 2;
|
|
|
|
int height = cur_surf->height();
|
|
int width = cur_surf->width();
|
|
|
|
fix du = IntToFix(rad_Hemicube.ff_res) / cur_surf->width();
|
|
fix dv = IntToFix(rad_Hemicube.ff_res) / cur_surf->height();
|
|
fix u, v;
|
|
|
|
for (v = 0, i = 0; i < height; i++, v += dv)
|
|
for (u = 0, t = 0; t < width; t++, u += du) {
|
|
int x = FixToInt(u);
|
|
int y = FixToInt(v);
|
|
|
|
int color = rad_Hemicube.id_grid[y * rad_Hemicube.ff_res + x];
|
|
if (color == -1)
|
|
dest[i * rowsize + t] = 0;
|
|
else
|
|
dest[i * rowsize + t] = GR_COLOR_TO_16(color);
|
|
}
|
|
|
|
rad_Viewport->unlock();
|
|
tview->Invalidate();
|
|
tview->SendMessage(WM_PAINT);
|
|
|
|
World_changed = 1;
|
|
}
|