Descent3/editor/TextureGrWnd.cpp
2024-06-29 18:21:37 +02:00

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;
}