Descent3/legacy/editor/editor.cpp
JeodC a4ab78192c Join license header with historical commentrs
Join the license header with historical comments using a separator so IDEs can correctly parse the initial header.

Also use .gitattributes to ensure all files are LF.
2024-05-08 14:41:19 -04:00

1183 lines
36 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/editor.cpp $
* $Revision: 1.1.1.1 $
* $Date: 2003-08-26 03:57:37 $
* $Author: kevinb $
*
* The main editor MFC file.
*
* $Log: not supported by cvs2svn $
*
* 73 4/17/99 2:46p Matt
* Implemented viewer properties dialog functions.
*
* 72 4/16/99 3:54p Nate
* Added Viewer Properties Dialog
*
* 71 4/04/99 6:21p Matt
* Added hack to pause the app and keep it paused.
*
* 69 3/15/99 5:38p Matt
* Changed idle loop back to old way because Sean says the new code made
* slewing chunky.
*
* 68 3/15/99 4:15p Matt
* Changed the idle handler to not always return true. Hopefully this
* will keep the editor from eating up all the processor time when it's
* not doing anything.
*
* 67 2/25/99 10:45p Matt
* Don't redraw wireframe if view has rotated but not moved
*
* 66 2/21/99 6:38p Samir
* mouse and key input better. buffered mouse.
*
* 65 1/29/99 12:48p Matt
* Rewrote the doorway system
*
* 64 1/27/99 10:35a Samir
* suspend resume keys added.
*
* 63 1/20/99 10:50a Jason
* added new terrain
*
* 62 1/19/99 6:53p Matt
* Fixed a problem when the viewer was instantaneously moved from inside
* to ourside or vise-versa.
*
* 61 1/08/99 2:56p Samir
* Ripped out OSIRIS1.
*
* 60 1/07/99 12:27p Samir
* took out parse command line info call.
*
* 59 12/23/98 3:35p Nate
* Added DallasModelessDlgPtr data member
*
* 58 12/01/98 11:17p Matt
* Added menu option to disable drawing objects in the wireframe view
*
* 57 11/01/98 1:58a Jeff
* converted the vsprintf calls to use the Pvsprintf, which is a safe
* vsprintf, no buffer overflows allowed
*
* 56 10/17/98 1:25p Sean
* Made PrintToDlgItem work with long strings
*
* 55 10/16/98 1:02p Samir
* no ddio_KeyFrame.
*
* 54 10/13/98 12:03p Kevin
* Changed use of preprocessors for debug, etc.
*
* 53 9/22/98 1:55p Matt
* Change the registry path to "Outrage\Descent3".
*
* 52 9/08/98 11:37a Samir
* added key to toggle joystick slewing.
*
* 51 9/04/98 3:16p Samir
* control whether to allow joystick slewing.
*
* 50 8/04/98 2:32p Chris
* Improved attach code added more fixes to the AABB partial computation
* patch
*
* 49 7/10/98 2:12p Jeff
* added a flag for inventory information in objinfo
*
* 48 6/17/98 12:30p Samir
* don't draw wireframe when moving an object.
*
* 47 6/15/98 4:00p Jason
* replaced monochromatic polymodel lighting with rgb lighting
*
* 46 6/10/98 12:20p Matt
* Revamped system that controls what textures are displayed on the
* texture tab. Should work correctly now, and will now save the settings
* to the registry. Also, textures now default to no type set, not all
* types set.
*
* 45 6/08/98 6:13p Matt
* Update the wireframe view when the viewer has stopped slewing
*
* 44 5/20/98 6:59p Samir
* added slew speed slider.
*
* 43 5/20/98 1:43p Matt
* Shift-T now moves a placed building up and down.
*
* 42 2/25/98 6:11p Samir
* Added functions to better deal with key flushing.
*
* 41 2/18/98 2:39a Matt
* Don't update the wireframe view if the only change is that the viewer
* moved
*
* 40 2/10/98 1:59p Chris
* Improved the path system
*
* 39 2/05/98 2:58p Matt
* Cleaned up slew code, and made view mode switch when slewing between
* mine and terrain happen in editor, not slew.
*
* 38 1/28/98 5:07p Samir
* Object modeless settings added.
*
* 37 12/01/97 5:32p Samir
* Argh, more housekeeping for FileDialog function.
*
* 36 12/01/97 5:23p Samir
* When initialdir is empty for FileDialog, then don't use it as a search
* path.
*
* 35 12/01/97 5:17p Samir
* New functions to open a file dialog.
*
* 34 11/13/97 6:16p Matt
* Changed some vars (such as current_powerup) to initialize to 0 instead
* of -1
*
* 33 10/27/97 5:45p Jason
* added prelim networking stuff, just to get it started
*
* 32 10/16/97 2:31p Samir
* Added keyboard handler to idle loop.
*
* 31 10/01/97 7:52p Matt
* Added code for external rooms
*
* 30 9/29/97 12:09p Jason
* added functionality to doorway system
*
* 29 9/23/97 3:04p Jason
* added tmap2 rotation key (KEY_EQUAL)
*
* 28 9/17/97 11:40a Matt
* Ripped out segment code
*
* 27 9/16/97 1:04p Samir
* Added include of AppDatabase.h
*
* 26 9/09/97 6:07p Matt
* If 't' key pressed when no placed room or group, do nothing
*
* 25 9/08/97 4:05p Samir
* Fixed some warnings and took out extranneous includes to windows.h in
* important headers.
*
* 24 9/06/97 3:15p Matt
* Removed old trigger stuff from registry load/save
* Added function PrintToDlgItem()
*
* 23 8/29/97 1:50p Samir
* Added object moving mouse polling and registry entry for axis mode.
*
* 22 8/26/97 11:38a Samir
* Added Editor_active global to determine whether editor is currently
* active (useful for any window using the gr library.)
*
* 21 8/19/97 5:58p Samir
* OLE additions
*
* 20 8/18/97 6:59p Matt
* Implemented Place Room/Attach room system
*
* 19 8/13/97 9:55a Matt
* Allow sliding & rotating textures with the mouse
*
* 18 8/12/97 7:06p Chris
* Made AABB work in the editor.
*
* 17 8/12/97 5:26p Matt
* Read/write new vars from/to registry
*
* 16 8/11/97 1:53p Matt
* Ripped out robot & powerup pages, and added generic page
*
* 15 8/01/97 11:59a Samir
* Added a preference for debugging in fullscreen.
*
* 14 7/28/97 1:23p Jeff
* Set default external editor to Notepad
*
* 13 7/28/97 10:51a Jeff
* Changed cha *DefaultExternalEditor to what it should be called, char
* Default_external_editor[256]
*
* 12 7/27/97 11:07p Matt
* Save/load external editor string to/from registry.
*
* 11 7/25/97 6:17p Samir
* When floating keypad values are loaded from database, mark keypad as
* moved.
*
* 10 7/24/97 2:58p Matt
* Added functions to load and save D3EditState variables from/to the
* registry
*
* 9 7/22/97 7:07p Matt
* Cleaned up D3EditState, moving some vars in and some out, and renaming
* and changing a few others
*
* 8 7/21/97 1:18p Samir
* You can now type stuff in keypads.
*
* 47 6/09/97 12:07p Samir
* for edit boxes, don't automatically switch focus to main view.
*
* 46 6/04/97 3:08p Jason
* changed backspace key to lshift+backspace
*
* 45 5/13/97 4:36p Samir
* call main-frame's onidle function
*
* 44 4/02/97 5:20p Jason
* made wireframe not update when player moves in the terrain view
*
* 43 4/02/97 3:25p Jason
* got rid of WV_changed and made TV_changed update the textured view and
* flag "World_changed"
*
* 42 4/02/97 11:16a Matt
* Update the wireframe view when the viewer moves, because the viewer is
* drawn as a sphere in that view
*
* 41 4/01/97 11:00p Matt
* Changed editor to keep a viewer object (type camera) seperate from the
* player object. This camera, and not the player, is now moved by
* slewing, the C key, etc. When going into the game, the viewer position
* & orientation are copied to the player. When going back to the editor,
* the player position is copied to the viewer, and the player object is
* reset to its start location.
*
* 40 3/31/97 5:57p Matt
* Revamped mine update flags
*
* 39 3/31/97 3:13p Jason
* added ship,weapon,and sounds to d3edit and zeroed it out upon startup
*
* 38 3/24/97 12:13p Samir
* Set initial trigger type.
*
* 37 3/20/97 4:57p Samir
* Adding IsSelecting to editorSelectorManager if we are curring drawing a
* selection box, say in the wireframe window.
*
* 36 3/20/97 4:22p Samir
* Added Segment Sizing mode and side sizing.
*
* 35 3/20/97 2:56p Samir
* Moved SelManager var to SelManager.cpp
*
* 34 3/20/97 12:06p Samir
* Added Selection Box manager.
*
* 33 3/20/97 11:20a Samir
* Accelerator keys should work when focus is in keypad.
*
* 32 3/13/97 5:12p Samir
* Call WinApp::OnIdle also in our idle loop.
*
* 31 3/07/97 4:18p Jason
* implemented terrain functionality in the editor
*
* 30 3/05/97 12:16p Jason
* added code to support our new 3d doors
*
* 29 3/03/97 11:23a Matt
* Set/clear MFC's modified flag every time through the loop, not just if
* the mine was changed
* Don't prompt user about discarding changes if the level hasn't been
* changed
*
* 28 2/20/97 4:41p Samir
* You can now use keypad functions even if input focus is in keypad
* dialog.
*
* 27 2/20/97 4:30p Samir
* Slewing works a lot better when input focus is in keypad or any other
* window other than the texture window.
*
* 26 2/20/97 1:03p Samir
* Control + slew key will not slew the mine.
*
* 25 2/18/97 12:46p Samir
* Initialized current object type to powerup.
*
* 24 2/17/97 6:09p Samir
* made initial powerup be the shield powerup.
*
* 23 2/13/97 12:16p Jason
* changes for powerup remapping
*
* 22 2/12/97 3:07p Samir
* pause and resume now flush keyboard queue to stop backspace from
* Int3ing.
*
* 21 2/11/97 1:42p Samir
* Added document variable and set modification flag.
*
* 20 2/11/97 10:31a Jason
* changed keystate checking for backspace
*
* 19 2/05/97 11:45a Samir
* Initialized D3windowed editor state
*
* 18 2/03/97 7:56p Matt
* Calculate Frame_time in editor loop
*
* 17 1/31/97 12:06p Jason
* added support for animations in Dialogs
* Also added more powerup functionality
*
* 16 1/23/97 4:00p Samir
* More D3EditState vars with respect to floating keypads.
*
* 15 1/21/97 12:48p Samir
* Added InitEditorState to define D3EditState info
*
* 14 1/20/97 4:13p Samir
* Added backspace debug key.
*
* $NoKeywords: $
*/
// editor.cpp : Defines the class behaviors for the application.
//
#include <cstdarg>
#include <cstdio>
#include "stdafx.h"
#include "editor.h"
#include "MainFrm.h"
#include "IpFrame.h" // OLE
#include "editorDoc.h"
#include "editorView.h"
#include "slew.h"
#include "object.h"
#include "descent.h"
#include "moveworld.h"
#include "d3edit.h"
#include "pserror.h"
#include "args.h"
#include "game.h"
#include "trigger.h"
#include "HTexture.h"
#include "HRoom.h"
#include "erooms.h"
#include "AppDatabase.h"
#include "TextureGrWnd.h"
#include "WireframeGrWnd.h"
#include "SelManager.h"
#include "ObjMoveManager.h"
#include "ViewerPropDlg.h"
#include "mono.h"
#include "ddio.h"
#include "boa.h"
#include "terrain.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
d3edit_state D3EditState;
grSurface *Desktop_surf=NULL;
bool Editor_active = true;
// ADDED FOR OLE SUPPORT
// This identifier was generated to be statistically unique for your app.
// You may change it if you prefer to choose a specific identifier.
// {949F57CE-189E-11D1-BD9B-00A0C96ED595}
static const CLSID clsid =
{ 0x949f57ce, 0x189e, 0x11d1, { 0xbd, 0x9b, 0x0, 0xa0, 0xc9, 0x6e, 0xd5, 0x95 } };
// ADDED FOR OLE SUPPORT
/////////////////////////////////////////////////////////////////////////////
// CEditorApp
BEGIN_MESSAGE_MAP(CEditorApp, CWinApp)
//{{AFX_MSG_MAP(CEditorApp)
ON_COMMAND(ID_APP_ABOUT, OnAppAbout)
// NOTE - the ClassWizard will add and remove mapping macros here.
// DO NOT EDIT what you see in these blocks of generated code!
//}}AFX_MSG_MAP
// Standard file based document commands
ON_COMMAND(ID_FILE_NEW, CWinApp::OnFileNew)
ON_COMMAND(ID_FILE_OPEN, CWinApp::OnFileOpen)
// Standard print setup command
ON_COMMAND(ID_FILE_PRINT_SETUP, CWinApp::OnFilePrintSetup)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CEditorApp construction
CEditorApp::CEditorApp()
{
// TODO: add construction code here,
// Place all significant initialization in InitInstance
textured_view = NULL;
wireframe_view = NULL;
main_view = NULL;
main_doc = NULL;
main_frame = NULL;
m_Paused = FALSE;
m_DallasModelessDlgPtr = NULL;
m_ViewerPropDlgPtr = NULL;
}
/////////////////////////////////////////////////////////////////////////////
// The one and only CEditorApp object
CEditorApp theApp;
/////////////////////////////////////////////////////////////////////////////
// CEditorApp initialization
BOOL CEditorApp::InitInstance()
{
// ADDED BY SAMIR FOR OLE SUPPORT.
// Initialize OLE libraries
if (!AfxOleInit())
{
AfxMessageBox(IDP_OLE_INIT_FAILED);
return FALSE;
}
AfxEnableControlContainer();
// ADDED BY SAMIR FOR OLE SUPPORT.
// Standard initialization
// If you are not using these features and wish to reduce the size
// of your final executable, you should remove from the following
// the specific initialization routines you do not need.
#ifdef _AFXDLL
Enable3dControls(); // Call this when using MFC in a shared DLL
#else
Enable3dControlsStatic(); // Call this when linking to MFC statically
#endif
// ADDED TO UPGRADE TO MFC 5.0
// This registry area is really just for the editor. No game settings or UI specifics
// except those strictly managed by MFC will be put here.
// Change the registry key under which our settings are stored.
// You should modify this string to be something appropriate
// such as the name of your company or organization.
SetRegistryKey(_T("Outrage\\Descent3\\editor\\mfc"));
// ADDED TO UPGRADE TO MFC 5.0
LoadStdProfileSettings(); // Load standard INI file options (including MRU)
// Initialize editor state
InitEditorState();
// Register the application's document templates. Document templates
// serve as the connection between documents, frame windows and views.
CSingleDocTemplate* pDocTemplate;
pDocTemplate = new CSingleDocTemplate(
IDR_MAINFRAME,
RUNTIME_CLASS(CEditorDoc),
RUNTIME_CLASS(CMainFrame), // main SDI frame window
RUNTIME_CLASS(CEditorView));
// ADDED BY SAMIR FOR OLE SUPPORT.
pDocTemplate->SetServerInfo(
IDR_SRVR_EMBEDDED, IDR_SRVR_INPLACE,
RUNTIME_CLASS(CInPlaceFrame));
// ADDED BY SAMIR FOR OLE SUPPORT.
AddDocTemplate(pDocTemplate);
// ADDED BY SAMIR FOR OLE SUPPORT.
// Connect the COleTemplateServer to the document template.
// The COleTemplateServer creates new documents on behalf
// of requesting OLE containers by using information
// specified in the document template.
m_server.ConnectTemplate(clsid, pDocTemplate, TRUE);
// Note: SDI applications register server objects only if /Embedding
// or /Automation is present on the command line.
// ADDED BY SAMIR FOR OLE SUPPORT.
// Parse command line for standard shell commands, DDE, file open
GatherArgs (m_lpCmdLine);
CCommandLineInfo cmdInfo;
// ParseCommandLine(cmdInfo);
// ADDED BY SAMIR FOR OLE SUPPORT.
// Check to see if launched as OLE server
if (cmdInfo.m_bRunEmbedded || cmdInfo.m_bRunAutomated)
{
// Register all OLE server (factories) as running. This enables the
// OLE libraries to create objects from other applications.
COleTemplateServer::RegisterAll();
// Application was run with /Embedding or /Automation. Don't show the
// main window in this case.
return TRUE;
}
// When a server application is launched stand-alone, it is a good idea
// to update the system registry in case it has been damaged.
m_server.UpdateRegistry(OAT_INPLACE_SERVER);
// ADDED BY SAMIR FOR OLE SUPPORT.
// Dispatch commands specified on the command line
if (!ProcessShellCommand(cmdInfo))
return FALSE;
// ADDED TO UPGRADE TO MFC 5.0
// The one and only window has been initialized, so show and update it.
m_pMainWnd->ShowWindow(SW_SHOW);
m_pMainWnd->UpdateWindow();
// ADDED TO UPGRADE TO MFC 5.0
//Enable rich edits
AfxInitRichEdit();
return TRUE;
}
/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About
class CAboutDlg : public CDialog
{
public:
CAboutDlg();
// Dialog Data
//{{AFX_DATA(CAboutDlg)
enum { IDD = IDD_ABOUTBOX };
//}}AFX_DATA
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CAboutDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
//{{AFX_MSG(CAboutDlg)
// No message handlers
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
//{{AFX_DATA_INIT(CAboutDlg)
//}}AFX_DATA_INIT
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CAboutDlg)
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
//{{AFX_MSG_MAP(CAboutDlg)
// No message handlers
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
// App command to run the dialog
void CEditorApp::OnAppAbout()
{
CAboutDlg aboutDlg;
theApp.pause();
aboutDlg.DoModal();
theApp.resume();
}
/////////////////////////////////////////////////////////////////////////////
// CEditorApp commands
//this is bad place to put this
int Slew_limitations = 0;
BOOL CEditorApp::OnIdle(LONG lCount)
{
static bool Dirty_wireframe=0;
bool viewer_rotated=0;
int key;
// determine if we should process idle messages
if (m_Paused) return TRUE;
// do our own input and output!
ddio_Frame();
/////////////////////////////////////////////////////////////////////////////
// all mouse button/drag functions go in this big if statement. this
// ensures that there are no conflicts between mouse drag operations
if (!SelManager.IsSelecting() && !ObjMoveManager.IsMoving()) {
// slide current texture
if (KEY_STATE(KEY_Y)) { //slide with mouse
int x,y,dx,dy;
ddio_MouseGetState(&x, &y, &dx, &dy);
if (KEY_STATE(KEY_LCTRL) || KEY_STATE(KEY_RCTRL))
HTextureRotate(Curroomp, Curface, (float) dx * 50.0);
else
HTextureSlide(Curroomp, Curface, (float) dx / 2.0, (float) -dy / 2.0);
}
// attaching rooms.
else if (KEY_STATE(KEY_T)) {
if ((Placed_room != -1) || (Placed_group != NULL)) {
int x,y,dx,dy;
ddio_MouseGetState(&x, &y, &dx, &dy);
if (KEY_STATE(KEY_LCTRL) || KEY_STATE(KEY_RCTRL))
Placed_room_attachpoint += (Placed_room_orient.rvec * (float) dx / 20.0) + (Placed_room_orient.uvec * (float) dy / 20.0);
else if ((Placed_baseroomp == NULL) && (KEY_STATE(KEY_LSHIFT) || KEY_STATE(KEY_RSHIFT))) //If on terrain, slide up/down
Placed_room_attachpoint += (Placed_room_orient.fvec * (float) dx / 20.0);
else {
Placed_room_angle += (float) dx * 20.0;
ComputePlacedRoomMatrix();
}
State_changed = 1;
}
}
else {
MoveWorld();
}
}
//very temorary key handler
//Slew the texture view
bool was_outside = (OBJECT_OUTSIDE(Viewer_object) != 0);
int slew_flags = SlewFrame(Viewer_object,Slew_limitations);
if (slew_flags & SLEW_MOVE) {
Viewer_moved = 1;
if (OBJECT_OUTSIDE(Viewer_object) && !was_outside)
SetViewMode(VM_TERRAIN);
if (!OBJECT_OUTSIDE(Viewer_object) && was_outside)
SetViewMode(VM_MINE);
}
if (slew_flags & SLEW_ROTATE)
viewer_rotated = 1;
//Update the viewer properties dialog
if (Viewer_moved && theApp.m_ViewerPropDlgPtr)
theApp.m_ViewerPropDlgPtr->UpdatePosition();
if ((Viewer_moved || viewer_rotated) && theApp.m_ViewerPropDlgPtr)
theApp.m_ViewerPropDlgPtr->UpdateOrientation();
if (slew_flags & SLEW_KEY) {
// note that if a slew key was pressed, the main view is out of keyboard focus, set
// keyboard focus to the main_view.
if (main_view && main_view != CWnd::GetFocus()) {
mprintf((0,"Restoring focus to main view.\n"));
main_view->SetFocus();
}
}
else if (KEY_STATE(KEY_LCTRL) || KEY_STATE(KEY_RCTRL)) {
// this is done to support CTRL-KEYPAD functions if input focus is not in main view
if (main_view && main_view != CWnd::GetFocus()) {
mprintf((0,"Restoring focus to main view.\n"));
main_view->SetFocus();
}
}
/*else if (ddio_KeyInKey()) {
// this is done if you press any other key while in a keypad, to use wireframe stuff
if (main_view && main_view != CWnd::GetFocus()) {
CRuntimeClass *wndtype = CWnd::GetFocus()->GetRuntimeClass();
if (strcmp(wndtype->m_lpszClassName, "CEdit")) {
mprintf((0,"Restoring focus to main view.\n"));
main_view->SetFocus();
}
}
}
*/
key = ddio_KeyInKey();
// toggle joystick slewing
if (key == (KEY_ALTED + KEY_J)) {
D3EditState.joy_slewing = !D3EditState.joy_slewing;
SlewControlInit();
}
//Check if something in the world has changed, and if so set global changed flag
if (World_changed) {
Mine_changed = 1;
//Create room objects
CreateRoomObjects();
}
//See if there's a new mine, and set/clear flags as appropriate
if (New_mine) {
World_changed = 1; //force redraws
Mine_changed = 0; //clear global changed flag
}
if(New_mine || World_changed)
{
ComputeAABB(false);
}
//for old code
int suppress_wireframe_redraw=0;
if (TV_changed)
{
World_changed = 1;
suppress_wireframe_redraw=1;
}
//Redraw the textured view if the world changed or the viewer moved
if (textured_view && (World_changed || State_changed || Viewer_moved || viewer_rotated || Object_moved)) {
textured_view->Render();
textured_view->InvalidateRect(NULL, FALSE);
}
//Keep track of whether viewer moved for next frame, since we only redraw the
//wireframe after the viewer has stopped slewing
Dirty_wireframe |= (Viewer_moved != 0);
//Redraw the wireframe view if the world changed or the view was changed
if (wireframe_view && !suppress_wireframe_redraw && ((World_changed || State_changed || Edview_changed) || (!Viewer_moved && !viewer_rotated && Dirty_wireframe && !(Editor_view_mode==VM_TERRAIN)))) {
if (!Object_moved) {
wireframe_view->Render();
wireframe_view->InvalidateRect(NULL, FALSE);
Dirty_wireframe = 0;
}
}
//Check to stop slew. (Why is this here?)
if (ddio_KeyDownTime(KEY_PAD5) > 0)
SlewStop(Viewer_object);
//Check for debugger break
if (KEY_STATE(KEY_BACKSP) > 0 && KEY_STATE(KEY_LSHIFT)>0) {
Int3();
ddio_KeyFlush();
}
//What does this do?
if (main_frame) main_frame->OnIdle();
//Reset all flags
World_changed = State_changed = Viewer_moved = Edview_changed = New_mine = TV_changed = 0;
//Compute Frame_time
CalcFrameTime();
//Tell MFC whether or not our document has been changed
if (main_doc)
main_doc->SetModifiedFlag(Mine_changed);
// this is done to allow selection boxes in the main frame.
SelManager.Defer();
// this is done to allow object moving
ObjMoveManager.Defer();
//defer to MFC
CWinApp::OnIdle(lCount);
return TRUE;
}
//Save current editor settings to the registry
void SaveEditorSettings()
{
oeWin32AppDatabase Editor_database((oeWin32AppDatabase *) Database);
bool res;
int speed;
res = Editor_database.lookup_record("editor");
if (!res) {
mprintf((0,"Can't get editor registry path\n"));
Int3();
return;
}
Editor_database.write("texdlg_texture",D3EditState.texdlg_texture);
Editor_database.write("current_obj_type",D3EditState.current_obj_type);
Editor_database.write("current_powerup",D3EditState.current_powerup);
Editor_database.write("current_door",D3EditState.current_door);
Editor_database.write("current_robot",D3EditState.current_robot);
Editor_database.write("current_ship",D3EditState.current_ship);
Editor_database.write("current_sound",D3EditState.current_sound);
Editor_database.write("current_weapon",D3EditState.current_weapon);
Editor_database.write("current_path",D3EditState.current_path);
Editor_database.write("current_node",D3EditState.current_node);
Editor_database.write("current_megacell",D3EditState.current_megacell);
Editor_database.write("current_clutter",D3EditState.current_clutter);
Editor_database.write("current_building",D3EditState.current_building);
Editor_database.write("texscr_visible",D3EditState.texscr_visible);
Editor_database.write("texscr_x",D3EditState.texscr_x);
Editor_database.write("texscr_y",D3EditState.texscr_y);
Editor_database.write("texscr_w",D3EditState.texscr_w);
Editor_database.write("texscr_h",D3EditState.texscr_h);
Editor_database.write("wirescr_visible",D3EditState.wirescr_visible);
Editor_database.write("wirescr_x",D3EditState.wirescr_x);
Editor_database.write("wirescr_y",D3EditState.wirescr_y);
Editor_database.write("wirescr_w",D3EditState.wirescr_w);
Editor_database.write("wirescr_h",D3EditState.wirescr_h);
Editor_database.write("keypad_visible",D3EditState.keypad_visible);
Editor_database.write("keypad_current",D3EditState.keypad_current);
Editor_database.write("float_keypad_x",D3EditState.float_keypad_x);
Editor_database.write("float_keypad_y",D3EditState.float_keypad_y);
Editor_database.write("float_keypad_w",D3EditState.float_keypad_w);
Editor_database.write("float_keypad_h",D3EditState.float_keypad_h);
Editor_database.write("objmodeless_x",D3EditState.objmodeless_x);
Editor_database.write("objmodeless_y",D3EditState.objmodeless_y);
Editor_database.write("objmodeless_on",D3EditState.objmodeless_on);
Editor_database.write("tile_views",D3EditState.tile_views);
Editor_database.write("game_render_mode",D3EditState.game_render_mode);
Editor_database.write("terrain_dots",D3EditState.terrain_dots);
Editor_database.write("terrain_flat_shade",D3EditState.terrain_flat_shade);
Editor_database.write("randomize_megacell",D3EditState.randomize_megacell);
Editor_database.write("box_selection_mode",D3EditState.box_selection_mode);
Editor_database.write("object_move_mode",D3EditState.object_move_mode);
Editor_database.write("fullscreen_debug",D3EditState.fullscreen_debug_state);
Editor_database.write("object_move_axis",D3EditState.object_move_axis);
Editor_database.write("texture_display_flags",D3EditState.texture_display_flags);
speed = ((Slew_key_speed-0.5)/0.5);
Editor_database.write("slew_key_speed", speed);
Editor_database.write("joy_slewing",D3EditState.joy_slewing);
}
//Load editor settings from the registry
void LoadEditorSettings()
{
oeWin32AppDatabase Editor_database((oeWin32AppDatabase *) Database);
bool res;
int speed = (int)((Slew_key_speed-0.5)/0.5);
res = Editor_database.lookup_record("editor");
if (!res) {
mprintf((0,"Can't get editor registry path\n"));
Int3();
return;
}
Editor_database.read_int("texdlg_texture",&D3EditState.texdlg_texture);
Editor_database.read_int("current_obj_type",&D3EditState.current_obj_type);
Editor_database.read_int("current_powerup",&D3EditState.current_powerup);
Editor_database.read_int("current_door",&D3EditState.current_door);
Editor_database.read_int("current_robot",&D3EditState.current_robot);
Editor_database.read_int("current_clutter",&D3EditState.current_clutter);
Editor_database.read_int("current_building",&D3EditState.current_building);
Editor_database.read_int("current_ship",&D3EditState.current_ship);
Editor_database.read_int("current_sound",&D3EditState.current_sound);
Editor_database.read_int("current_weapon",&D3EditState.current_weapon);
Editor_database.read_int("current_path",&D3EditState.current_path);
Editor_database.read_int("current_node",&D3EditState.current_node);
Editor_database.read_int("current_megacell",&D3EditState.current_megacell);
Editor_database.read("texscr_visible",&D3EditState.texscr_visible);
Editor_database.read_int("texscr_x",&D3EditState.texscr_x);
Editor_database.read_int("texscr_y",&D3EditState.texscr_y);
Editor_database.read_int("texscr_w",&D3EditState.texscr_w);
Editor_database.read_int("texscr_h",&D3EditState.texscr_h);
Editor_database.read("wirescr_visible",&D3EditState.wirescr_visible);
Editor_database.read_int("wirescr_x",&D3EditState.wirescr_x);
Editor_database.read_int("wirescr_y",&D3EditState.wirescr_y);
Editor_database.read_int("wirescr_w",&D3EditState.wirescr_w);
Editor_database.read_int("wirescr_h",&D3EditState.wirescr_h);
Editor_database.read("keypad_visible",&D3EditState.keypad_visible);
Editor_database.read_int("keypad_current",&D3EditState.keypad_current);
Editor_database.read_int("float_keypad_x",&D3EditState.float_keypad_x);
Editor_database.read_int("float_keypad_y",&D3EditState.float_keypad_y);
Editor_database.read_int("float_keypad_w",&D3EditState.float_keypad_w);
Editor_database.read_int("float_keypad_h",&D3EditState.float_keypad_h);
Editor_database.read_int("objmodeless_x",&D3EditState.objmodeless_x);
Editor_database.read_int("objmodeless_y",&D3EditState.objmodeless_y);
Editor_database.read("objmodeless_on",&D3EditState.objmodeless_on);
Editor_database.read("tile_views",&D3EditState.tile_views);
Editor_database.read_int("game_render_mode",&D3EditState.game_render_mode);
Editor_database.read("terrain_dots",&D3EditState.terrain_dots);
Editor_database.read("terrain_flat_shade",&D3EditState.terrain_flat_shade);
Editor_database.read("randomize_megacell",&D3EditState.randomize_megacell);
Editor_database.read_int("box_selection_mode",&D3EditState.box_selection_mode);
Editor_database.read_int("object_move_mode",&D3EditState.object_move_mode);
Editor_database.read("fullscreen_debug",&D3EditState.fullscreen_debug_state);
Editor_database.read_int("object_move_axis",&D3EditState.object_move_axis);
Editor_database.read_int("slew_key_speed",&speed);
Editor_database.read_int("texture_display_flags",&D3EditState.texture_display_flags);
Editor_database.read_int("joy_slewing",&D3EditState.joy_slewing);
Slew_key_speed = ((float)speed * 0.5) + 0.5;
// Since we are loading in the values of the floating keypad's position, it has moved.
// If the values for the floating keypad position haven't been set, then don't specify
// the keypad as having moved. - Samir
if (D3EditState.float_keypad_x != -1)
D3EditState.float_keypad_moved = 1;
}
// InitEditorState
// loads in editor state values and sets them
void CEditorApp::InitEditorState()
{
float scr_aspect_x, scr_aspect_y;
scr_aspect_x = ((float)GetSystemMetrics(SM_CXSCREEN)) / ((float)EDITOR_RESOLUTION_X);
scr_aspect_y = ((float)GetSystemMetrics(SM_CYSCREEN)) / ((float)EDITOR_RESOLUTION_Y);
//Initialize all variables to zero
memset (&D3EditState,0,sizeof (d3edit_state));
//Initialize a bunch of non-zero variables in case there are no variables in the registry
D3EditState.texscr_visible = 1;
D3EditState.texscr_x = 0;
D3EditState.texscr_y = 0;
D3EditState.texscr_w = (int)(scr_aspect_x * ((float)TEXSCREEN_WIDTH));
D3EditState.texscr_h = (int)(scr_aspect_y * ((float)TEXSCREEN_HEIGHT));
D3EditState.wirescr_visible = 1;
D3EditState.wirescr_x = 20;
D3EditState.wirescr_y = 20;
D3EditState.wirescr_w = (int)(scr_aspect_x * ((float)WIRESCREEN_WIDTH));
D3EditState.wirescr_h = (int)(scr_aspect_y * ((float)WIRESCREEN_HEIGHT));
D3EditState.keypad_visible = 1;
D3EditState.keypad_current = TAB_TEXTURE_KEYPAD;
D3EditState.float_keypad_moved = 0;
D3EditState.float_keypad_x = -1;
D3EditState.float_keypad_y = -1;
D3EditState.float_keypad_w = -1;
D3EditState.float_keypad_h = -1;
D3EditState.objmodeless_x = GetSystemMetrics(SM_CXSCREEN)/2;
D3EditState.objmodeless_y = GetSystemMetrics(SM_CYSCREEN)/2;
D3EditState.objmodeless_on = false;
D3EditState.tile_views = 1;
D3EditState.current_obj_type = OBJ_POWERUP;
D3EditState.current_powerup = 0;
D3EditState.current_building = 0;
D3EditState.current_clutter = 0;
D3EditState.current_door=0;
D3EditState.current_room = -1;
D3EditState.node_movement_inc = 1.0f;
// preferences
D3EditState.game_render_mode = GM_WINDOWED;
D3EditState.fullscreen_debug_state = false;
D3EditState.object_move_axis = OBJMOVEAXIS_XY;
D3EditState.texscale=1.0;
D3EditState.joy_slewing = true;
D3EditState.objects_in_wireframe = true;
Editor_active = true;
}
CDocument* CEditorApp::OpenDocumentFile(LPCTSTR lpszFileName)
{
// TODO: Add your specialized code here and/or call the base class
if (main_doc)
if (main_doc->GetPathName() == lpszFileName)
if (Mine_changed) {
// we are trying to revert to on-disk level, so we should prompt the user if he wants
// this, and then if so to close the current document
if (AfxMessageBox("This will discard all changes made to the level.\nDo you want to continue?", MB_YESNO)
== IDYES) {
mprintf((0, "Restoring %s...\n", lpszFileName));
main_doc->OnOpenDocument(lpszFileName);
}
}
return CWinApp::OpenDocumentFile(lpszFileName);
}
// pause and resume
void CEditorApp::pause()
{
m_Paused = TRUE;
ddio_KeyFlush();
ddio_Suspend();
}
bool Stay_paused = 0;
void CEditorApp::resume()
{
if (Stay_paused)
return;
m_Paused = FALSE;
ddio_Resume();
ddio_KeyFlush();
}
///////////////////////////////////////////////////////////////////////////////
//
// Supplementary editor functions
//
///////////////////////////////////////////////////////////////////////////////
bool FileDialog(CWnd *wnd, BOOL open, LPCTSTR filter, char *pathname, char *initialdir, int dirlen);
//Function to print to an edit box
//Parameters: dlg - the dialog that the edit box is in
// id - the ID of the edit box
// fmt - printf-style text & arguments
void PrintToDlgItem(CDialog *dlg,int id,char *fmt,...)
{
std::va_list arglist;
char str[3000];
int len;
CEdit *ebox;
va_start(arglist,fmt);
len = std::vsnprintf(str,3000,fmt,arglist);
va_end(arglist);
ASSERT(len < 3000);
ebox = (CEdit *) dlg->GetDlgItem(id);
if (ebox == NULL) {
Int3();
return;
}
ebox->SetWindowText(str);
}
// A quick way to use an openfiledialog/savefiledialog.
// wnd = parent window
// filter = a C string containing the extensions to look for in filenames when browsing (in MFC format)
// pathname = buffer where full pathname will be stored of file opened/saved
// initialdir = what directory to start browsing from. will also contain the new browsing directory if
// user changed directories.
// dirlen = max length of initialdir buffer including terminating null.
bool OpenFileDialog(CWnd *wnd, LPCTSTR filter, char *pathname, char *initialdir, int dirlen)
{
return FileDialog(wnd, TRUE, filter, pathname, initialdir, dirlen);
}
bool SaveFileDialog(CWnd *wnd, LPCTSTR filter, char *pathname, char *initialdir, int dirlen)
{
return FileDialog(wnd, FALSE, filter, pathname, initialdir, dirlen);
}
bool FileDialog(CWnd *wnd, BOOL open, LPCTSTR filter, char *pathname, char *initialdir, int dirlen)
{
CFileDialog *dlg;
char saved_path[_MAX_PATH];
char search_path[_MAX_PATH];
theApp.pause();
if (open)
dlg = new CFileDialog(TRUE, 0,0, OFN_FILEMUSTEXIST, filter, wnd);
else
dlg = new CFileDialog(FALSE, 0,0, OFN_OVERWRITEPROMPT, filter, wnd);
// save current directory and set new directory.
if (initialdir) {
ASSERT(dirlen > 0);
ddio_GetWorkingDir(saved_path, _MAX_PATH);
if (initialdir[0]) {
lstrcpy(search_path, initialdir);
dlg->m_ofn.lpstrInitialDir = search_path;
}
}
if (dlg->DoModal() == IDCANCEL) {
if (initialdir)
ddio_SetWorkingDir(saved_path);
theApp.resume();
delete dlg;
return false;
}
// we have a filename now.
lstrcpy(pathname, dlg->GetPathName());
// restore old current directory and save current directory into initialdir.
if (initialdir) {
ddio_GetWorkingDir(initialdir, dirlen);
ddio_SetWorkingDir(saved_path);
}
theApp.resume();
delete dlg;
return true;
}
int CALC_PIXELS_WITH_ASPECTX(int pixels)
{
float scr_aspect_x = ((float)GetSystemMetrics(SM_CXSCREEN)) / ((float)EDITOR_RESOLUTION_X);
return (int)(scr_aspect_x * (float)(pixels));
}
int CALC_PIXELS_WITH_ASPECTY(int pixels)
{
float scr_aspect_y = ((float)GetSystemMetrics(SM_CYSCREEN)) / ((float)EDITOR_RESOLUTION_Y);
return (int)(scr_aspect_y * (float)(pixels));
}
//Move the viewer object. This should be called whenever the viewer object is moved
void MoveViewer(vector *pos,int roomnum,matrix *orient)
{
bool was_outside = (OBJECT_OUTSIDE(Viewer_object) != 0);
ObjSetPos(Viewer_object,pos,roomnum,orient,false);
if (OBJECT_OUTSIDE(Viewer_object) && !was_outside)
SetViewMode(VM_TERRAIN);
if (!OBJECT_OUTSIDE(Viewer_object) && was_outside)
SetViewMode(VM_MINE);
}