Compare commits

...
37 Commits
Author SHA1 Message Date
z64555 8b517ddda9 Adds outwindow init and the SCP_mspdbcs init and cleanup. 2016-08-15 17:45:22 -05:00
z64555 6bc5a395e0 Pointless style flag is pointless 2016-08-15 17:28:52 -05:00
z64555 318496992e Fix bug where scene would not repaint when window was resized to something smaller. 2016-08-15 17:24:55 -05:00
z64555 1e28d526ae Prevent excessive calls to wxfred::render_resize if the viewport size didn't change. 2016-08-15 16:10:48 -05:00
z64555 26a746d612 Some work on the viewport:
* Viewport now resizes. There's some kinks with re-draw to work out, though
* Viewport now displays starfield
* Viewport now displays mission grid
2016-08-15 07:24:39 -05:00
z64555 5b41dce69c Update wxfred2.cpp to use flagsets. Also a bit of whitespace maintenance (yawn). 2016-08-15 05:38:04 -05:00
z64555 ea9b611782 Merge branch 'master' of https://github.com/scp-fs2open/fs2open.github.com into wxfred2 2016-08-15 04:37:40 -05:00
z64555 9474f58820 Setup OS and FSO backend initialization.
* Currently only works on Windows due to the OpenGL loader (wxFredRender) being rather basic.
2016-08-14 19:36:16 -05:00
z64555 006853ae44 Forgot to set canvas target in context creation. 2016-08-13 20:33:50 -05:00
z64555 22f56a12d9 * Implements wxFredRender's render_init() and render_frame() functions.
* Implements glcViewport's construction
2016-08-13 20:09:52 -05:00
z64555 20990416a9 Implement wxFredRender components. 2016-08-10 17:56:51 -05:00
z64555 92fc16372f Create wxFredRender files, this'll be for the graphics of wxFred and used by the glcViewport class(es). 2016-08-08 05:50:41 -05:00
z64555 cd25f907ac Merge pull request #2 from asarium/wxfred2_dev
Fix MSVC compilation issues
2016-08-08 04:33:11 -05:00
asarium c2363989e4 Fix MSVC compilation issues 2016-08-08 11:27:45 +02:00
z64555 7b13d5c1f2 Merge pull request #1 from asarium/wxfred2_dev
Fix wxFRED CMake and compliation errors
2016-08-08 04:18:56 -05:00
asarium 25f6be7867 Use the version string in the project headers 2016-08-08 11:17:05 +02:00
asarium 9756b52845 Fix wxFRED CMake and compliation errors 2016-08-08 11:17:05 +02:00
z64555 93101aa8ce Remove glrcMissionFrame. 2016-08-08 04:07:48 -05:00
z64555 10a37e6ddb Add link targets to core codebase. 2016-08-08 02:46:08 -05:00
z64555 469a31602e Fix access violation. Can't append items to wxChoice elements for the moment. 2016-08-07 23:15:43 -05:00
z64555 3521740a60 Update XRC and generated files to use wxWidgets 3.0.2 (or later. wxFormBuilder doesn't say which version it uses) 2016-08-07 23:15:42 -05:00
z64555 beaee70a82 Fix building after rebase with master. 2016-08-07 23:15:42 -05:00
z64555 eb3b65e051 Implement Copy functions, settle on using OIN_t's for object selection queues. 2016-08-07 23:15:41 -05:00
z64555 4bb547ce09 (FRED) Fix bug where AIF_NO_DYNAMIC flags weren't set with copied objects 2016-08-07 23:15:40 -05:00
z64555 5294db25b3 Implement port of core mission management functions 2016-08-07 23:15:40 -05:00
z64555 5983ddeea4 Some FRED cleanup and debugging 2016-08-07 23:15:39 -05:00
z64555 37d16a65c4 Updating README with info on wxWidget's Release packages. 2016-08-07 23:15:39 -05:00
z64555 8c54c63908 Update the README a bit. 2016-08-07 23:15:38 -05:00
z64555 ae7bf0667e Fix linking due to an unknown, removed, or renamed ailocal.h 2016-08-07 23:15:38 -05:00
z64555 c018329a4c Adds new define to disable FSO's mem* function overrides 2016-08-07 23:15:38 -05:00
z64555 f188960f91 Fixes compiling by de-tangling a #include chain that was exposed by commit 798a8922879f7af8ebd2bb07a6cdaa655a2e038b 2016-08-07 23:15:37 -05:00
niffiwan 7255d5e8e4 Update Linux to link successfully with libcode.a 2016-08-07 23:15:36 -05:00
z64555 198c6cace9 End of linkage work. (This commit is probably temporary)
* Includes wxfredstubs.cpp to prevent linkage to certain data members and functions defined in freespace.cpp.
 * "_SECURE_SCL" and "_HAS_ITERATOR_DEBUGGING" defines removed from the project files
 * C runtime library (CRT) switched to use DLL so as to integrate with wxWidgets default settings.
2016-08-07 23:15:34 -05:00
z64555 5efe85b4db Beginning setup to link into code.lib, defined some variables needed for linkage and link tests. 2016-08-07 23:15:01 -05:00
z64555 fb8fe9bb75 Started work on docFRED2, and mission load/save methods. More work done on glcViewport. 2016-08-07 23:14:59 -05:00
z64555 790f8b9d8c Some header name wrangling, a Big O snuck in somehow. 2016-08-07 23:14:03 -05:00
z64555 0bcc9f27d4 glcViewport and glrcMissionFrame classes added. README updated. 2016-08-07 23:13:59 -05:00
26 changed files with 4735 additions and 3737 deletions

No files matched your search

+3 -1
View File
@@ -38,7 +38,7 @@
#define MAX_PLAYERS 12
#define USE_INLINE_ASM 1 // Define this to use inline assembly
#define STRUCT_CMP(a, b) memcmp((void *)&a, (void *)&b, sizeof(a))
#define STRUCT_CMP(a, b) memcmp((void *) &a, (void *) &b, sizeof(a))
#ifdef LOCAL
#undef LOCAL
@@ -530,6 +530,7 @@ SCP_string dump_stacktrace();
// ref: http://gcc.gnu.org/onlinedocs/libstdc++/manual/status.html
#ifndef NDEBUG
#if SCP_COMPILER_CXX_STATIC_ASSERT && SCP_COMPILER_CXX_AUTO_TYPE
#ifndef USING_THIRD_PARTY_LIBS
// feature support seems to be: gcc clang msvc
// auto 4.4 2.9 2010
// std::is_trivial 4.5 ? 2012 (2010 only duplicates std::is_pod)
@@ -620,6 +621,7 @@ using std::memcpy_if_trivial_else_error;
using std::memmove_if_trivial_else_error;
using std::memset_if_trivial_else_error;
#endif // USING_THIRD_PARTY_LIBS
#endif // HAVE_CXX11
#endif // NDEBUG
+1 -1
View File
@@ -31,7 +31,7 @@
#include "popup/popup.h"
#include "ui/ui.h"
#include "ui/uidefs.h"
#include "mission/missionparse.h"
#define MAX_MISSIONS 1024
+1
View File
@@ -20,6 +20,7 @@
#include "io/key.h"
#include "io/timer.h"
#include "mission/missionbriefcommon.h"
#include "mission/missionparse.h"
#include "missionui/missioncmdbrief.h"
#include "missionui/missionscreencommon.h"
#include "missionui/redalert.h"
+1
View File
@@ -22,6 +22,7 @@
#include "menuui/optionsmenumulti.h"
#include "network/multi.h"
#include "playerman/player.h"
#include "object/object.h"
#include "debugconsole/console.h"
+1
View File
@@ -31,6 +31,7 @@
#include "popup/popup.h"
#include "popup/popupdead.h"
#include "ui/ui.h"
#include "mission/missionparse.h"
UI_WINDOW Popupdead_window;
+2
View File
@@ -36,6 +36,8 @@ const unsigned int SND_ENHANCED_MAX_LIMIT = 15; // seems like a good max limit
#define SND_F_USED (1<<0) // Sounds[] element is used
extern fix Missiontime;
typedef struct sound {
int sid; // software id
char filename[MAX_FILENAME_LEN];
+10 -10
View File
@@ -496,14 +496,14 @@ int create_ship(matrix *orient, vec3d *pos, int ship_type)
// "pop" and cfile_chdirs off the sta
chdir(Fred_base_dir);
obj = ship_create(orient, pos, ship_type);
if (obj == -1)
return -1;
// ok, done with file io, restore the pwd
chdir(pwd);
if (obj == -1)
return -1;
Objects[obj].phys_info.speed = 33.0f;
ship *shipp = &Ships[Objects[obj].instance];
@@ -629,7 +629,7 @@ int dup_object(object *objp)
if ( aip2->ai_flags & AIF_KAMIKAZE )
aip1->ai_flags |= AIF_KAMIKAZE;
if ( aip2->ai_flags & AIF_NO_DYNAMIC )
aip2->ai_flags |= AIF_NO_DYNAMIC;
aip1->ai_flags |= AIF_NO_DYNAMIC;
aip1->kamikaze_damage = aip2->kamikaze_damage;
@@ -699,7 +699,7 @@ int create_object(vec3d *pos, int waypoint_instance)
obj = -2;
} else
obj = create_player(Player_starts, pos, NULL, Default_player_model);
obj = create_player(pos, NULL, Default_player_model);
} else if (cur_model_index == Id_select_type_jump_node) {
CJumpNode jnp(pos);
@@ -727,7 +727,7 @@ int create_object(vec3d *pos, int waypoint_instance)
return obj;
}
int create_player(int num, vec3d *pos, matrix *orient, int type, int init)
int create_player(vec3d *pos, matrix *orient, int type)
{
int obj;
@@ -767,7 +767,7 @@ void create_new_mission()
void reset_mission()
{
clear_mission();
player_start1 = create_player(0, &vmd_zero_vector, &vmd_identity_matrix);
player_start1 = create_player(&vmd_zero_vector, &vmd_identity_matrix);
}
void clear_mission()
@@ -905,14 +905,14 @@ void clear_mission()
Num_mission_events = 0;
Num_goals = 0;
unmark_all();
obj_init();
model_free_all(); // Free all existing models
//obj_init();
//model_free_all(); // Free all existing models
fred_render_init();
init_sexp();
messages_init();
brief_reset();
debrief_reset();
ship_init();
//ship_init();
event_music_reset_choices();
clear_texture_replacements();
+1 -1
View File
@@ -74,7 +74,7 @@ void set_physics_controls();
int dup_object(object *objp);
int create_object_on_grid(int waypoint_instance = -1);
int create_object(vec3d *pos, int waypoint_instance = -1);
int create_player(int num, vec3d *pos, matrix *orient, int type = -1, int init = 1);
int create_player(vec3d *pos, matrix *orient, int type = -1);
void create_new_mission();
void reset_mission();
void clear_mission();
+14 -85
View File
@@ -1,39 +1,12 @@
include(source_groups.cmake)
SET(PNG_OUT_FILES)
FOREACH(file ${file_root_res_pngs})
FILE(RELATIVE_PATH FILE_NAME ${CMAKE_CURRENT_SOURCE_DIR} ${file})
SET(OUTPUT "${GENERATED_SOURCE_DIR}/wxfred2/${FILE_NAME}")
# For some reason this is needed...
GET_FILENAME_COMPONENT(DIRECTORY_PATH ${OUTPUT} PATH)
FILE(MAKE_DIRECTORY ${DIRECTORY_PATH})
get_filename_component(FILENAME ${file} NAME)
STRING(REPLACE "-" "_" FILENAME ${FILENAME})
STRING(REPLACE "." "_" FILENAME ${FILENAME})
STRING(REPLACE "#" "_" FILENAME ${FILENAME})
ADD_CUSTOM_COMMAND(
OUTPUT ${OUTPUT}.cpp
COMMAND embedfile -wx "${file}" "${OUTPUT}" "${FILENAME}"
DEPENDS ${file}
COMMENT "Generating png header for ${file}"
)
LIST(APPEND PNG_OUT_FILES ${OUTPUT}.cpp)
ENDFOREACH(file ${file_root_res_pngs})
SOURCE_GROUP("Generated Files\\PNG Files" FILES ${PNG_OUT_FILES})
IF(UNIX)
SET(wxWidgets_USE_DEBUG OFF)
SET(wxWidgets_USE_UNICODE ON)
SET(wxWidgets_USE_UNIVERSAL OFF)
SET(wxWidgets_USE_STATIC OFF)
set(wxWidgets_CONFIG_OPTIONS --version=3.0)
ELSEIF(WIN32)
set(wxWidgets_CONFIGURATION "mswu" CACHE STRING "Release WxWidgets configuration" FORCE)
ENDIF(UNIX)
@@ -42,70 +15,26 @@ find_package(wxWidgets COMPONENTS gl core base REQUIRED)
include(${wxWidgets_USE_FILE})
add_executable(wxfred2 ${EXE_GUI_TYPE} ${file_root} ${PNG_OUT_FILES})
add_executable(wxfred2 ${EXE_GUI_TYPE} ${file_root})
set_target_properties(wxfred2
PROPERTIES
COMPILE_DEFINITIONS_RELEASE "NDEBUG"
COMPILE_DEFINITIONS_DEBUG "_DEBUG"
DEBUG_POSTFIX "-DEBUG"
)
include(resources.cmake)
target_compile_definitions(wxfred2 PUBLIC USING_THIRD_PARTY_LIBS FRED)
SET_TARGET_PROPERTIES(wxfred2 PROPERTIES OUTPUT_NAME "wxfred2_${FSO_BINARY_SUFFIX}")
add_definitions(
-DFRED
)
INCLUDE_DIRECTORIES(${CODE_HEADERS})
INCLUDE_DIRECTORIES(${WXFRED_HEADERS})
INCLUDE_DIRECTORIES(${wxWidgets_INCLUDE_DIRS})
INCLUDE_DIRECTORIES(${GENERATED_SOURCE_DIR})
INCLUDE_DIRECTORIES(${GENERATED_SOURCE_DIR}/wxfred2)
INCLUDE_DIRECTORIES(${GENERATED_SOURCE_DIR}/code)
INCLUDE_DIRECTORIES(${COMPILER_INCLUDES})
INCLUDE_DIRECTORIES(${PLATFORM_INCLUDES})
TARGET_INCLUDE_DIRECTORIES(wxfred2 PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
TARGET_INCLUDE_DIRECTORIES(wxfred2 PUBLIC ${wxWidgets_INCLUDE_DIRS})
TARGET_INCLUDE_DIRECTORIES(wxfred2 PUBLIC ${GENERATED_SOURCE_DIR})
TARGET_INCLUDE_DIRECTORIES(wxfred2 PUBLIC ${GENERATED_SOURCE_DIR}/wxfred2)
TARGET_INCLUDE_DIRECTORIES(wxfred2 PUBLIC ${GENERATED_SOURCE_DIR}/code)
TARGET_LINK_LIBRARIES(wxfred2 code)
TARGET_LINK_LIBRARIES(wxfred2 ${wxWidgets_LIBRARIES})
TARGET_LINK_LIBRARIES(wxfred2 ${SDL_LIBS})
if(UNIX)
add_definitions(
-DSCP_UNIX
-DLUA_USE_LINUX
-std=c++11
)
elseif(MSVC)
IF(NOT MSVC_USE_RUNTIME_DLL)
STRING(REGEX REPLACE "/MT" "/MD" CMAKE_C_FLAGS_RELEASE ${CMAKE_C_FLAGS_RELEASE})
STRING(REGEX REPLACE "/MT" "/MD" CMAKE_CXX_FLAGS_RELEASE ${CMAKE_CXX_FLAGS_RELEASE})
STRING(REGEX REPLACE "/MT" "/MD" CMAKE_C_FLAGS_DEBUG ${CMAKE_C_FLAGS_DEBUG})
STRING(REGEX REPLACE "/MT" "/MD" CMAKE_CXX_FLAGS_DEBUG ${CMAKE_CXX_FLAGS_DEBUG})
ENDIF(NOT MSVC_USE_RUNTIME_DLL)
add_definitions(
/DWINVER=0x0501
/D_WIN32_WINNT=0x0501
/D_WINDOWS
/DWIN32
)
TARGET_LINK_LIBRARIES(wxfred2
odbc32.lib
odbccp32.lib
comctl32.lib
rpcrt4.lib
wsock32.lib
winmm.lib
)
set_target_properties(wxfred2 PROPERTIES
COMPILE_DEFINITIONS_DEBUG "PDB_DEBUGGING=1"
)
endif(UNIX)
if (MSVC)
set_target_properties(wxfred2 PROPERTIES LINK_FLAGS "/FORCE:MULTIPLE")
endif()
# Add install script to copy the executable to the FreeSpace path if possible and wanted
INSTALL(
+38 -13
View File
@@ -1,42 +1,66 @@
====wxFRED2 - Port of Volition's FReespace EDitor to use wxWidgets GUI libraries====
===Required Libraries===
You must have wxWidgets 2.9.4 or later.
===The Golden Rule of wxFRED2===
Thou shalt not mix business logic with pleasure logic.
Otherwise known as "keep the GUI code separate from the code that actually does work." All GUI elements that need to access mission-related data must go through an API provided by wxfred2.h and wxfred2.cpp.
===Installing wxWidgets===
As of wxWidgets 2.9.4, the wxWidgets community has been publishing .dll binaries for select MS Visual Studio versions and gcc. It is recommended to use these if you are inexperienced with building .libs and .dll's from source.
==Visual Studio==
MSVC users may download the headers and binaries directly from the wxWidgets hosts:
- wxWidgets 2.9.4: http://sourceforge.net/projects/wxwindows/files/2.9.4/binaries/
- wxWidgets 2.9.5: http://sourceforge.net/projects/wxwindows/files/2.9.5/binaries/
Be sure to download the wxWidgets-2.9.X_Headers.7z and the appropriate wxMSW-2.9.X_vcXX_Dev.7z
The vcXX may be:
Be sure to download _both_ the wxWidgets-2.9.X_Headers.7z and the appropriate wxMSW-2.9.X_vcXX_Dev.7z (some vcXX values are listed below). They should both extract to the same directory, such as "C:\code\wxwidgets-2.9.4", with the headers extracting to "/include" and the Dev .dll's extracting to "/lib". Windows users must set an environment variable named WXWIN to reference the install directory, since all our VS project files use the WXWIN variable to find our wxWidgets install location. As an added bonus, it makes switching between wxWidgets versions somewhat easier.
=vcXX Toolset Versions=
- vc80 - MSVC 2005
- vc90 - MSVC 2008
- vc100 - MSVC 2010
- vc110 - MSVC 2012
- vc120 - MSVC 2013
- vc130 - MSVC 2015
==Other IDE's==
All other programming environments must compile their libraries from the source. Download from the appropriate "source archive" linked in the page below:
- http://www.wxwidgets.org/downloads/
SHOULD THERE BE NO AVAILABLE BINARIES FOR YOUR MSVC VERSION, you'll have to compile from the source (see section below)
You can optionally grab the wxMSW-2.9.X_vcXX_x86_ReleaseDLL.msi and have the release versions of the .dll's installed to your System32 (or SysWOW64) directory. This will allow you to run wxfred in your FSO directory without needing to copy over the dll's. We're hoping that we can just direct our end-users to download the "default libs" and not resort to distributing our own flavor.
==Other IDE's and Compiling from Source==
All other programming environments must compile their libraries from the source. Download the source code package appropriate to your operating system (such as wxMSW for Windows, wxGTK for Linux, wxMac for Mac OS) and extract them to your code directory, such as "C:\code\wxWidgets-2.9.4". The version number is optional, but recommended since common workflow is to have a directory per wxWidgets version.
The "/build" subdirectory contains makefiles and a number of solution and project files for a number of the more popular IDE's. If you have a version of MSVS that is newer than the provided .sln files (within /build/msw)
==wxWidgets Manual==
You can refer to the wxWidgets manual online or download a copy of it for offline use. The .CHM package will give you a single file that you can click on/shortcut to (it'll open up something like a standard help file), but you can also just grab the HTML files if you're more comfortable navigating through with a browser. In either case, you can save them in your WXWIN directory in a new sub directory "/docs/htmlhelp"
You can also run doxygen on the headers and get a significant amount of the manual that way, although be advised that its example code and overviews will be limited.
===Directory Map===
"/wxfred2/base"
- contains the tool generated files which are derived by all windows, frames, and dialogs found elsewhere in "/wxfred2"
- Also includes an XML resource file (".xrc") which may be, and is recommended to be, used by a WYSIWYG editor to edit the GUI elements of wxfred2. At the time of this writing, wxFormBuilder v3.3 - beta proved to be stable enough to create all the elements, although the generated wxFRED2_base.cpp had to be sanitized of deprecated flags in order for it to be compiled under the wxWidgets 2.9.4 lib.
"/wxfred2/editors"
- contains the source code for frames and dialogs listed under the Editors menu in wxFRED2.
- Also includes an XML resource file (".xrc") which may be, and is recommended to be, used by a WYSIWYG editor to edit the GUI elements of wxfred2. At the time of this writing, wxFormBuilder v3.3 - beta proved to be stable enough to create all the elements, although the generated wxFRED2_base.cpp had to be sanitized of deprecated flags in order for it to be compiled under the wxWidgets 2.9.4 lib.
"/wxfred2/help"
- contains the source code for the "About" and help dialogs listed under the Help menu in wxFRED2.
"/wxfred2/misc"
- contains the source code for miscillanious tools listed under the Misc menu in wxFRED2.
- contains the source code for miscellaneous tools listed under the Misc menu in wxFRED2.
"/wxfred2/res"
- contains the resouce files used by wxFRED2 during runtime, these are typically images used for the graphic buttons.
- contains the resource files used by wxFRED2 during runtime, these are typically images used for the graphic buttons.
===Importing wxFRED2.xrc into a WYSIWYG Editor===
===Importing wxFRED2.xrc into a RAD Tool===
==wxFormBuilder==
To import wxFRED2.xrc into wxFormBuilder:
@@ -59,7 +83,8 @@ To import wxFRED2.xrc into wxFormBuilder:
. event_generation to "table"
. disconnect_events to "not checked"
==Other WYSIYWG Editors==
Importing into other WYSIWYG editors should be similar to importing into wxFormBuilder. Be sure the options in steps 4 and 5 are set as they are so that for your newly generated files to play nice with the existing "/wxfred2/" code.
==Other RAD Tools==
Importing into other RAD tools (or WYSIWYG editors) should be similar to importing into wxFormBuilder. Be sure the options in steps 4 and 5 are set as they are so that for your newly generated files to play nice with the existing "/wxfred2/" code.
Please be sure to NOT include the project file from the WYSIWYG editor in your commits to the fs2_open repo, as they are far larger than the .xrc and are usually specific to that editor!
+2177 -2392
View File
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
+64
View File
@@ -0,0 +1,64 @@
/*
* Created by "z64555" for the FreeSpace2 Source Code Project.
* You may not sell or otherwise commercially exploit the source or things you
* create based on the source.
*/
#include "docfred.h"
#include <cfile/cfile.h>
#include <mission/missionparse.h>
#include <object/waypoint.h>
#include <wx/docview.h>
#include <wx/wx.h>
// TODO: Initialize docFRED2
docFRED2::docFRED2( void )
: wxDocument(NULL)/*, Mission()*/
{
}
bool docFRED2::OnSaveDocument( const wxString& filename )
{
// Get the system time and stamp it into the mission file
return FALSE;
}
bool docFRED2::OnOpenDocument( const wxString& filename )
{
return FALSE;
}
bool docFRED2::OnNewDocument( void )
{
return FALSE;
}
bool docFRED2::OnCloseDocument( void )
{
return FALSE;
}
bool docFRED2::DoSaveDocument( const wxString& filename )
{
return FALSE;
}
bool docFRED2::DoOpenDocument( const wxString& filename )
{
return FALSE;
}
bool docFRED2::DoNewDocument( void )
{
return FALSE;
}
bool docFRED2::DoCloseDocument( void )
{
return FALSE;
}
+52
View File
@@ -0,0 +1,52 @@
#ifndef _DOCFRED_H
#define _DOCFRED_H
/*
* Created by "z64555" for the FreeSpace2 Source Code Project.
* You may not sell or otherwise commercially exploit the source or things you
* create based on the source.
*/
#include <cfile/cfile.h>
#include <mission/missionparse.h>
#include <object/waypoint.h>
#include <wx/docview.h>
#include <wx/wx.h>
/**
* @class Class responsible for handling interactions between the application (wxFRED2) and mission file.
* @details Each document handles 1 mission. The_Mission can be thought as the working copy of mission files, docFRED's would be used whenever wxFRED wants to read from or
* save to disk.
* Real-time Collaborative editing might be possible by sending .diff's of the document or by sending command stacks periodically to a server (and then to all clients)
*/
class docFRED2 : public wxDocument
{
public:
docFRED2();
// wxDocument Handler overrides
// Can't use the file handler methods wxWidgets provides, because FSO uses the CFILE system
virtual bool OnSaveDocument( const wxString& filename );
virtual bool OnOpenDocument( const wxString& filename );
virtual bool OnNewDocument( void );
virtual bool OnCloseDocument( void );
protected:
virtual bool DoSaveDocument( const wxString& filename );
virtual bool DoOpenDocument( const wxString& filename );
virtual bool DoNewDocument( void );
virtual bool DoCloseDocument( void );
private:
int Save_waypoint_list( waypoint_list &wpl, CFILE *fp );
int Save_waypoints( CFILE *fp );
int Save_goals( CFILE *fp );
int Save_wings( CFILE *fp );
int Save_objects( CFILE *fp );
int Save_players( CFILE *fp );
int Save_briefing_info( CFILE *fp );
int Save_plot_info( CFILE *fp );
int Save_mission_info( CFILE *fp );
};
#endif // _DOCFRED_H
+28 -13
View File
@@ -40,13 +40,15 @@
#include "help/dlgSexpHelp.h"
#include "base/wxFRED_base.h"
#include "glcViewport.h"
#include "wxfred2.h"
#include <globalincs/version.h>
#include <globalincs/pstypes.h>
#include <wx/glcanvas.h>
#include <wx/msgdlg.h>
#include <wx/wx.h>
#include <wx/glcanvas.h>
// Public:
frmFRED2::frmFRED2( const wxChar *title, int xpos, int ypos, int width, int height )
@@ -61,16 +63,14 @@ frmFRED2::frmFRED2( const wxChar *title, int xpos, int ypos, int width, int heig
frmCampaignEditor_p(NULL), dlgMissionStats_p(NULL), dlgAboutBox_p(NULL), dlgSexpHelp_p(NULL)
{
// Title bar setup
// z64: somewhat roundabout way to include the FS2 Open version number in the form title.
wxSprintf( version, "v%i.%i.%i", FS_VERSION_MAJOR, FS_VERSION_MINOR, FS_VERSION_BUILD );
wxSprintf( version, "v%s", FS_VERSION_FULL );
this->SetFredTitle();
// New Object Selection ListBox
cbNewObject = new wxChoice( tbrFRED, ID_TOOL_NEWOBJECTLIST, wxDefaultPosition, wxSize(193,-1), 0, NULL, wxCB_SORT );
auto choice = wxString("GTF Ulysses");
cbNewObject = new wxChoice( tbrFRED, ID_TOOL_NEWOBJECTLIST, wxDefaultPosition, wxSize(193,-1), 1, &choice, wxCB_SORT );
// TODO: Auto-size the choice box to the longest string in the list.
// TODO: Grab the actual list of object classes
cbNewObject->Append(_T("GTF Ulysses"));
cbNewObject->SetSelection(0);
tbrFRED->AddControl( cbNewObject );
@@ -81,8 +81,8 @@ frmFRED2::frmFRED2( const wxChar *title, int xpos, int ypos, int width, int heig
// The Viewport
wxBoxSizer* bSizerView = new wxBoxSizer( wxVERTICAL );
wxGLCanvas *TheViewport = new wxGLCanvas(this, wxID_ANY, NULL, wxDefaultPosition, wxDefaultSize, wxFULL_REPAINT_ON_RESIZE);
bSizerView->Add( TheViewport );
viewport_p = new glcViewport(this, wxID_ANY);
bSizerView->Add(viewport_p, 1, wxEXPAND);
this->SetSizer( bSizerView );
this->Layout();
@@ -128,6 +128,7 @@ void frmFRED2::OnClose( wxCloseEvent &event )
void frmFRED2::OnSize( wxSizeEvent &event )
{
// TODO: Implement OnSize
Layout();
}
void frmFRED2::OnFileNew( wxCommandEvent &event )
@@ -137,8 +138,10 @@ void frmFRED2::OnFileNew( wxCommandEvent &event )
void frmFRED2::OnFileOpen( wxCommandEvent &event )
{
wxFileDialog *dlg =
new wxFileDialog( this, "Open FreeSpace 2 Mission", wxGetCwd(), wxEmptyString, "FreeSpace2 Missions (*.fs2)|*.fs2| All Files (*.*)|*.*");
bool file_loaded = false;
wxFileDialog *dlg;
dlg = new wxFileDialog( this, "Open FreeSpace 2 Mission", wxGetCwd(), wxEmptyString, "FreeSpace2 Missions (*.fs2)|*.fs2| All Files (*.*)|*.*");
if( dlg->ShowModal() != wxID_OK )
{
@@ -146,9 +149,21 @@ void frmFRED2::OnFileOpen( wxCommandEvent &event )
return;
}
currentFilename = dlg->GetFilename();
// TODO: actually (attempt) to open the file
SetFredTitle();
// Application: Try to load the file
file_loaded = wxGetApp().Mission_load(dlg->GetPath());
if( !file_loaded )
{
wxMessageBox(_T("Error opening mission file."), _T("Error opening file."), wxOK);
// TODO: Do some fancy Debug stuffs, or a better notification of what went wrong. For now, do nothing
return;
}
else
{
currentFilename = dlg->GetFilename();
SetFredTitle();
//TODO: Set up the viewport
}
}
void frmFRED2::OnFileSave( wxCommandEvent &event )
+9 -7
View File
@@ -27,6 +27,8 @@
*/
// Child windows and dialogs:
#include "glcViewport.h"
#include "editors/frmShipsEditor.h"
#include "editors/frmWingEditor.h"
#include "editors/dlgObjectEditor.h"
@@ -236,6 +238,12 @@ protected:
private:
// void InitMods();
// Widgets
// member variables
wxChar version[32];
wxString currentFilename;
const wxString fredName;
wxChoice* cbNewObject;
wxStatusBar* sbFRED;
@@ -264,12 +272,6 @@ private:
dlgSexpHelp* dlgSexpHelp_p;
// Viewports and Rendering
// wxGLContext mission_state;
// wxGLCanvas viewport;
// member variables
wxChar version[32];
wxString currentFilename;
const wxString fredName;
glcViewport* viewport_p;
};
#endif
+94
View File
@@ -0,0 +1,94 @@
/*
* Created by Ian "Goober5000" Warfield and "z64555" for the FreeSpace2 Source
* Code Project.
*
* You may not sell or otherwise commercially exploit the source or things you
* create based on the source.
*/
#include "glcViewport.h"
#include "wxFredRender.h"
#include <wx/event.h>
#include <wx/window.h>
#include <wx/windowid.h>
#include <wx/wx.h>
BEGIN_EVENT_TABLE(glcViewport, wxWindow)
EVT_SIZE(glcViewport::OnSize)
EVT_PAINT(glcViewport::OnPaint)
EVT_ERASE_BACKGROUND(glcViewport::OnEraseBackground)
EVT_MOUSE_EVENTS(glcViewport::OnMouse)
END_EVENT_TABLE()
glcViewport::glcViewport(wxWindow *parent, wxWindowID id)
: wxWindow(parent, id, wxDefaultPosition, wxDefaultSize) {
vec3d f, u, r;
// Init position
vm_vec_make(&vset.c_pos, 0.0f, 150.0f, -200.0f);
// Init orientation
vm_vec_make(&f, 0.0f, -0.5f, 0.866025404f); // 30 degree angle
vm_vec_make(&u, 0.0f, 0.866025404f, 0.5f);
vm_vec_make(&r, 1.0f, 0.0f, 0.0f);
vm_vector_2_matrix(&vset.c_orient, &f, &u, &r);
// Init physics
set_physics();
// Init grid
grid = create_default_grid();
maybe_create_new_grid(grid, &vset.c_pos, &vset.c_orient, 1);
// Init renderer
wxfred::render_init(this);
}
glcViewport::~glcViewport(void) {
// Delete context if we're the last instance of a viewport.
}
// Handlers for glcViewport
void glcViewport::OnPaint(wxPaintEvent& event) {
wxPaintDC dc(this); // Required. Even if we don't directly use it.
wxfred::render_frame(this);
}
void glcViewport::OnSize(wxSizeEvent& event) {
auto canvas = FindWindowByName("GLCanvas", this);
// Should never happen, but just in case...
Assertion(canvas != nullptr, "glcViewport could not find its child canvas!");
auto oldSize = canvas->GetSize();
auto newSize = event.GetSize();
if (oldSize != newSize) {
wxfred::render_resize(this, newSize.GetWidth(), newSize.GetHeight());
// z64: Blah. Force a wxPaintEvent becuase Refresh and Update arn't working as expected
wxPaintEvent event_paint(GetId());
GetEventHandler()->ProcessEvent(event_paint);
}
}
void glcViewport::OnEraseBackground(wxEraseEvent& event) {}
void glcViewport::OnMouse(wxMouseEvent& event) {}
void glcViewport::set_physics() {
physics_init(&vset.c_physics);
vset.c_physics.max_vel.xyz.x *= vset.physics_speed / 3.0f;
vset.c_physics.max_vel.xyz.y *= vset.physics_speed / 3.0f;
vset.c_physics.max_vel.xyz.z *= vset.physics_speed / 3.0f;
vset.c_physics.max_rear_vel *= vset.physics_speed / 3.0f;
vset.c_physics.max_rotvel.xyz.x *= vset.physics_rot / 30.0f;
vset.c_physics.max_rotvel.xyz.y *= vset.physics_rot / 30.0f;
vset.c_physics.max_rotvel.xyz.z *= vset.physics_rot / 30.0f;
vset.c_physics.flags |= PF_ACCELERATES | PF_SLIDE_ENABLED;
//theApp.write_ini_file(1);
}
+72 -29
View File
@@ -7,18 +7,15 @@
* You may not sell or otherwise commercially exploit the source or things you
* create based on the source.
*/
#include "base/wxFRED_base.h"
#include "globalincs/pstypes.h"
#include "physics/physics.h"
#include <globalincs/pstypes.h>
#include <mission/missiongrid.h>
#include <physics/physics.h>
#include "wx/glcanvas.h"
#if !wxUSE_GLCANVAS
#error "OpenGL required: set wxUSE_GLCANVAS to 1 and rebuild the library"
#endif
#include <wx/event.h>
#include <wx/window.h>
#include <wx/windowid.h>
enum cmode
{
@@ -27,35 +24,81 @@ enum cmode
cmode_ship // Controls selected object
};
class glcViewport : public wxGLCanvas
struct ViewSettings
{
// Camera Data
vec3d c_pos; // Camera Position
matrix c_orient; // Camera Orientation
physics_info c_physics; // Camera Physics
int physics_speed = 1; // Physics speed multiplier
int physics_rot = 20; // Physics rotation multiplier
// View|Display Filter...Commands
bool show_playerStarts;
bool show_ships;
bool show_waypoints;
// View...Commands
bool show_background;
bool show_compass;
bool show_coordinates;
bool show_distances;
bool show_grid = true;
bool show_grid_aa;
bool show_grid_doubleFine;
bool show_grid_positions;
bool show_horizon;
bool show_lightingFromSuns;
bool show_models;
bool show_model_paths;
bool show_model_dockpoints;
bool show_outlines;
bool show_shipInfo;
bool show_asteroids;
bool show_stars = true;
};
/**
* @class glcViewport
*
* @brief The viewport class.
*
* @details Where the bulk of the wxFRED GUI is the frontend to the mission file, this is the frontend to the graphics
* system. It provides handlers for the GUI events and calls the appropriate rendering functions provided by wxFredRender
*/
class glcViewport : public wxWindow
{
public:
glcViewport( wxWindow *parent, wxWindowID id = wxID_ANY, int*gl_attrib = NULL);
glcViewport( wxWindow *parent, wxWindowID id = wxID_ANY );
~glcViewport( void );
cmode Control_mode; // Control behavior setting. Public for now for lazy reasons
// These are public for now, because lazy
ViewSettings vset; // View settings of this viewport.
grid* grid; // Grid of this viewport
protected:
// Handlers for glcViewport
void OnPaint( wxPaintEvent& event );
void OnSize( wxSizeEvent& event);
void OnEraseBackgroun( wxEraseEvent& event);
void OnEraseBackground( wxEraseEvent& event);
void OnMouse( wxMouseEvent& event );
// Internal functions
/**
* @brief Sets the viewport's c_physics
*
* @note z64: This system is a bit derp. It inits the physics_info and then scales it by the physics_speed and physics_rot factors
*/
void set_physics();
private:
// Member data
vec3d c_pos; // Camera Position
matrix c_rot; // Camera Rotation/Orientation
// Viewport modes and options
cmode Control_mode;
bool show_coordinates;
bool show_distances;
bool show_grid;
bool show_grid_aa;
bool show_grid_positions;
bool show_horizon;
bool show_outlines;
// Event handling
DECLARE_EVENT_TABLE()
};
#endif // _GLCVIEWPORT_H
+32
View File
@@ -0,0 +1,32 @@
SET(RES_OUT_FILES)
FOREACH(file ${file_root_res_pngs})
set(INPUT_NAME "${CMAKE_CURRENT_SOURCE_DIR}/${file}")
SET(OUTPUT "${GENERATED_SOURCE_DIR}/wxfred2/${file}")
# For some reason this is needed...
GET_FILENAME_COMPONENT(DIRECTORY_PATH ${OUTPUT} PATH)
FILE(MAKE_DIRECTORY ${DIRECTORY_PATH})
get_filename_component(FILENAME ${file} NAME)
string(MAKE_C_IDENTIFIER "${FILENAME}" FIELD_NAME)
set(HEADER_FILE "${OUTPUT}.h")
set(SOURCE_FILE "${OUTPUT}.cpp")
set(ALL_OUTPUTS "${HEADER_FILE}" "${SOURCE_FILE}")
set(FIELD_NAME "${FIELD_NAME}")
ADD_CUSTOM_COMMAND(
OUTPUT ${ALL_OUTPUTS}
COMMAND embedfile -wx "${INPUT_NAME}" "${OUTPUT}" "${FIELD_NAME}"
DEPENDS ${INPUT_NAME}
COMMENT "Generating string file for ${INPUT_NAME}"
)
LIST(APPEND RES_OUT_FILES ${ALL_OUTPUTS})
ENDFOREACH(file ${file_root_res_pngs})
target_sources(wxfred2 PRIVATE ${RES_OUT_FILES})
SOURCE_GROUP("Generated Files\\PNG Files" FILES ${RES_OUT_FILES})
+25 -19
View File
@@ -1,10 +1,16 @@
# top-level files
set (file_root
docfred.cpp
docfred.h
frmFRED2.cpp
frmFRED2.h
glcViewport.cpp
glcViewport.h
wxfred2.cpp
wxfred2.h
wxFredRender.cpp
wxFredRender.h
wxfredstubs.cpp
)
# Base files
@@ -75,25 +81,25 @@ set (file_root_misc
)
set(file_root_res_pngs
${CMAKE_CURRENT_SOURCE_DIR}/res/constx.png
${CMAKE_CURRENT_SOURCE_DIR}/res/constxy.png
${CMAKE_CURRENT_SOURCE_DIR}/res/constxz.png
${CMAKE_CURRENT_SOURCE_DIR}/res/consty.png
${CMAKE_CURRENT_SOURCE_DIR}/res/constyz.png
${CMAKE_CURRENT_SOURCE_DIR}/res/constz.png
${CMAKE_CURRENT_SOURCE_DIR}/res/fredknows.png
${CMAKE_CURRENT_SOURCE_DIR}/res/orbitsel.png
${CMAKE_CURRENT_SOURCE_DIR}/res/rotlocal.png
${CMAKE_CURRENT_SOURCE_DIR}/res/select.png
${CMAKE_CURRENT_SOURCE_DIR}/res/selectlist.png
${CMAKE_CURRENT_SOURCE_DIR}/res/selectlock.png
${CMAKE_CURRENT_SOURCE_DIR}/res/selectmove.png
${CMAKE_CURRENT_SOURCE_DIR}/res/selectrot.png
${CMAKE_CURRENT_SOURCE_DIR}/res/showdist.png
${CMAKE_CURRENT_SOURCE_DIR}/res/wingdisband.png
${CMAKE_CURRENT_SOURCE_DIR}/res/wingform.png
${CMAKE_CURRENT_SOURCE_DIR}/res/zoomext.png
${CMAKE_CURRENT_SOURCE_DIR}/res/zoomsel.png
res/constx.png
res/constxy.png
res/constxz.png
res/consty.png
res/constyz.png
res/constz.png
res/fredknows.png
res/orbitsel.png
res/rotlocal.png
res/select.png
res/selectlist.png
res/selectlock.png
res/selectmove.png
res/selectrot.png
res/showdist.png
res/wingdisband.png
res/wingform.png
res/zoomext.png
res/zoomsel.png
)
set(file_root_res
+478
View File
@@ -0,0 +1,478 @@
/*
* Created for the FreeSpace2 Source Code Project.
*
* You may not sell or otherwise commercially exploit the source or things you
* create based on the source.
*/
#include "wxFredRender.h"
#include <globalincs/alphacolors.h>
#include <globalincs/pstypes.h>
#include <globalincs/vmallocator.h>
#include <graphics/2d.h>
#include <graphics/font.h>
#include <lighting/lighting.h>
#include <math/vecmat.h>
#include <model/model.h>
#include <nebula/neb.h>
#include <nebula/neblightning.h>
#include <osapi/osapi.h>
#include <parse/parselo.h>
#include <physics/physics.h>
#include <render/3d.h>
#include <starfield/starfield.h>
#include <SDL_loadso.h>
#include <wx/glcanvas.h>
#include <wx/window.h>
#if !wxUSE_GLCANVAS
#error "OpenGL required: set wxUSE_GLCANVAS to 1 and rebuild the library"
#endif
using namespace wxfred;
class wxOpenGLContext : public os::OpenGLContext
{
public:
/**
* @brief The context constructor. Must have a valid wxGLCanvas as input
*/
explicit wxOpenGLContext(wxGLCanvas* win) {
Assertion(win != nullptr, "Could not create wxOpenGLContext! Must have a valid wxGLCanvas class (or derivative)\n");
canvas_p = win;
context_p = new wxGLContext(win);
Assertion(context_p != nullptr, "Failed to create wxGLContext!");
};
/**
* @brief The context deconstructor.
*/
~wxOpenGLContext() {};
/**
* @brief The OpenGL loader function. Loads the OPENGL32.DLL
*/
static void* wglLoader(const char* name) {
auto wglAddr = reinterpret_cast<void*>(wglGetProcAddress(name));
return wglAddr;
}
/**
* @brief Gets the OpenGL loader function
*/
os::OpenGLLoadProc getLoaderFunction() override {
return wglLoader;
};
/**
* @brief Swaps the buffers of this context
*/
void swapBuffers() override {
canvas_p->SwapBuffers();
}
/**
* @brief Sets the swap interval, used in vsync modes
*
* @note Unused by wxFRED
* @note This might cause problems. wxWidgets doesn't provide a SwapInterval wrapper, so we'd have to use something
* else to get vsync operational
*/
void setSwapInterval(int status) override {};
void makeCurrent() {
if (!canvas_p->SetCurrent(*context_p)) {
mprintf(("Failed to make OpenGL conext current!\n"));
}
}
void setTarget(wxGLCanvas* win) {
Assertion(win != nullptr, "Cannot set render target to a nullptr!\n");
// Check if target window has same properties as context (and existing canvas)
canvas_p = win;
}
private:
// HACK: Since OpenGL apparently likes global state we also have to make this global...
static void* _oglDllHandle;
static size_t _oglDllReferenceCount;
wxGLContext *context_p; //!< Reference to the wxGLContext, which must exist
wxGLCanvas *canvas_p; //!< Reference to the current canvas, which must exist
};
class wxGraphicsOperations : public os::GraphicsOperations
{
public:
explicit wxGraphicsOperations(wxWindow *win) {
Assertion(win != nullptr, "Failed to create wxGraphicsOperations! An invalid reference to a wxWindow was passed to the constructor.\n");
_parent = win;
}
~wxGraphicsOperations() {
// Destroy context on death
}
std::unique_ptr<os::OpenGLContext> createOpenGLContext(const os::OpenGLContextAttributes& attrs, uint32_t width, uint32_t height) override {
// wxWidgets 3.0's wierd-ass attribute list
int attributeList[] = {
WX_GL_RGBA,
WX_GL_DOUBLEBUFFER,
WX_GL_MIN_RED, attrs.red_size,
WX_GL_MIN_GREEN, attrs.green_size,
WX_GL_MIN_BLUE, attrs.blue_size,
WX_GL_MIN_ALPHA, attrs.alpha_size,
WX_GL_DEPTH_SIZE, attrs.depth_size,
WX_GL_STENCIL_SIZE, attrs.stencil_size,
WX_GL_SAMPLE_BUFFERS, ((attrs.multi_samples == 0) ? 0 : 1),
WX_GL_SAMPLES, attrs.multi_samples, // "4 for 2x2 antialiasing supersampling on most graphics cards "
// Currently unused
// 0, attrs.major_version,
// 0, attrs.minor_version,
// 0, attrs.flags,
// OpenGLProfile profile,
0 // attributeList must be 0 terminated. :shrug:
};
mprintf((" Requested GL Video values = R: %d, G: %d, B: %d, depth: %d, stencil: %d, double-buffer: %d, FSAA: %d\n",
attrs.red_size, attrs.green_size, attrs.blue_size, attrs.depth_size, attrs.stencil_size, 1, attrs.multi_samples));
// Create canvas with attributes
auto canvas = new wxGLCanvas(_parent, wxID_ANY, attributeList, wxDefaultPosition, wxSize(width, height), NULL, "GLCanvas", wxNullPalette);
if (canvas == nullptr) {
Error(LOCATION, "Could not create initial wxGLCanvas!\n");
return nullptr;
}
// wxWidgets doesn't supply a method to get the attributes used, because creation of the wxCanvas will fail on anything unsupported
// Create context from the canvas
return std::unique_ptr<os::OpenGLContext>(new wxOpenGLContext(canvas));
};
/**
* @brief Makes the given context current. i.e. subsequent gr calls will draw to this context
*
* @param[in] ctx The context to be made current, or nullptr to disconnect context from caller
*/
void makeOpenGLContextCurrent(os::OpenGLContext* ctx) override {
if (ctx != nullptr) {
reinterpret_cast<wxOpenGLContext*>(ctx)->makeCurrent();
} // Else, do nothing. Context cleans up after itself on death
}
private:
wxWindow* _parent; // The initial window we'll be making canvas/context for
};
const float FRED_DEFAULT_HTL_FOV = 0.485f;
const float FRED_BRIEFING_HTL_FOV = 0.325f;
const float FRED_DEAFULT_HTL_DRAW_DIST = 300000.0f;
static std::unique_ptr<wxGraphicsOperations> graphicsOperations;
static bool fred_inited = false;
void* wxOpenGLContext::_oglDllHandle = nullptr;
size_t wxOpenGLContext::_oglDllReferenceCount = 0;
// Colors used for 2d rendering
color colour_black;
color colour_green;
color colour_white;
color colour_yellow;
/**
* @brief Enables HTL
*/
void htl_enable();
/**
* @brief Disables HTL
*/
void htl_disable();
/**
* @brief Renders the asteroid field
*/
void render_asteroid_field();
/**
* @brief Renders the compass widget
*/
void render_compass();
/**
* @brief Renders the grid widget for the given viewport
*/
void render_grid(glcViewport* win);
/**
* @brief Renders all modeled objects within the mission
*/
void render_models();
/**
* @brief Displays/Renders the distances between selected objects
*/
void display_distances();
/**
* @brief Highlights the currently selected skybox bitmap
*/
void hilight_bitmap();
void htl_enable() {
// gr_set_proj_matrix((4.0f / 9.0f) * PI * (Briefing_dialog ? Briefing_window_FOV : FRED_DEFAULT_HTL_FOV), gr_screen.aspect*(float) gr_screen.clip_width / (float) gr_screen.clip_height, 1.0f, FRED_DEAFULT_HTL_DRAW_DIST);
gr_set_proj_matrix((4.0f / 9.0f) * PI * FRED_DEFAULT_HTL_FOV, gr_screen.aspect*(float) gr_screen.clip_width / (float) gr_screen.clip_height, 1.0f, FRED_DEAFULT_HTL_DRAW_DIST);
gr_set_view_matrix(&Eye_position, &Eye_matrix);
}
void htl_disable() {
gr_end_proj_matrix();
gr_end_view_matrix();
}
void render_asteroid_field() {}
void render_compass() {}
void render_grid(glcViewport* win) {
static bool grid_colors_inited = false;
static color grid_dark_aa, grid_bright_aa, grid_dark, grid_bright;
grid* grid_p = win->grid;
int i, ncols, nrows;
htl_enable();
gr_zbuffer_set(0);
if (!grid_colors_inited) {
grid_colors_inited = true;
gr_init_alphacolor(&grid_dark_aa, 64, 64, 64, 255);
gr_init_alphacolor(&grid_bright_aa, 128, 128, 128, 255);
gr_init_color(&grid_dark, 64, 64, 64);
gr_init_color(&grid_bright, 128, 128, 128);
}
ncols = grid_p->ncols;
nrows = grid_p->nrows;
if (double_fine_gridlines) {
ncols *= 2;
nrows *= 2;
}
if (win->vset.show_grid_aa)
gr_set_color_fast(&grid_dark_aa);
else
gr_set_color_fast(&grid_dark);
// Draw the column lines.
for (i = 0; i <= ncols; i++) {
g3_draw_htl_line(&grid_p->gpoints1[i], &grid_p->gpoints2[i]);
}
// Draw the row lines.
for (i = 0; i <= nrows; i++) {
g3_draw_htl_line(&grid_p->gpoints3[i], &grid_p->gpoints4[i]);
}
ncols = grid_p->ncols / 2;
nrows = grid_p->nrows / 2;
// now draw the larger, brighter gridlines that is x10 the scale of smaller one.
if (win->vset.show_grid_aa)
gr_set_color_fast(&grid_bright_aa);
else
gr_set_color_fast(&grid_bright);
for (i = 0; i <= ncols; i++) {
g3_draw_htl_line(&grid_p->gpoints5[i], &grid_p->gpoints6[i]);
}
for (i = 0; i <= nrows; i++) {
g3_draw_htl_line(&grid_p->gpoints7[i], &grid_p->gpoints8[i]);
}
htl_disable();
gr_zbuffer_set(1);
}
void render_models() {}
void display_distances() {}
void hilight_bitmap() {
// Currently disabled for now.
/*
int i;
vertex p[4];
if (Starfield_bitmaps[Cur_bitmap].bitmap_index == -1) // can't draw if no bitmap
return;
for (i=0; i<4; i++)
{
g3_rotate_faraway_vertex(&p[i], &Starfield_bitmaps[Cur_bitmap].points[i]);
if (p[i].codes & CC_BEHIND)
return;
g3_project_vertex(&p[i]);
if (p[i].flags & PF_OVERFLOW)
return;
}
gr_set_color(255, 255, 255);
g3_draw_line(&p[0], &p[1]);
g3_draw_line(&p[1], &p[2]);
g3_draw_line(&p[2], &p[3]);
g3_draw_line(&p[3], &p[0]);
*/
}
void wxfred::render_init(glcViewport* win) {
if (!fred_inited) {
// Create the GraphicsOperations helper object with the target window
graphicsOperations.reset(new wxGraphicsOperations(win));
// Do graphics init
gr_init(graphicsOperations.get(), GR_OPENGL, 640, 480, 32);
font::init();
gr_set_gamma(3.0f);
// sprintf(palette_filename, "gamepalette%d-%02d", 1, 1);
// mprintf(("Loading palette %s\n", palette_filename));
// palette_load_table(palette_filename);
// particle::ParticleManager::init();
alpha_colors_init();
glowpoint_init();
neb2_init();
stars_init();
// brief_init_colors();
stars_post_level_init();
nebl_init();
gr_init_alphacolor(&colour_white, 255, 255, 255, 255);
gr_init_alphacolor(&colour_green, 0, 200, 0, 255);
gr_init_alphacolor(&colour_yellow, 200, 255, 0, 255);
gr_init_alphacolor(&colour_black, 0, 0, 0, 255);
gr_reset_clip();
g3_start_frame(0);
g3_set_view_matrix(&win->vset.c_pos, &win->vset.c_orient, 0.5f);
fred_inited = true;
} else {
// Set render target to window?
}
}
void wxfred::render_frame(glcViewport *win) {
Assertion(fred_inited, "Call to render_frame was made before render_init!\n");
// Caller viewport must set context as current before entering!!
// Caller viewport must swap buffers after we've rendered!
// @note The following is essentially copypasty from fredrender::render_frame()
g3_end_frame(); // ** Accounted for
gr_reset_clip();
gr_clear();
// Briefing dialog stuff goes here, in FRED.
g3_start_frame(1);
font::set_font(font::FONT1);
light_reset();
g3_set_view_matrix(&win->vset.c_pos, &win->vset.c_orient, FRED_DEFAULT_HTL_FOV);
htl_enable();
int Show_stars = (win->vset.show_stars) ? 1 : 0;
stars_draw(Show_stars, Show_stars, Show_stars, 0, 0);
htl_disable();
if (win->vset.show_horizon) {
gr_set_color(128, 128, 64);
g3_draw_horizon_line();
}
if (win->vset.show_asteroids) {
gr_set_color(192, 96, 16);
render_asteroid_field();
}
if (win->vset.show_grid) {
render_grid(win);
}
// if (Bg_bitmap_dialog) {
if (false) {
hilight_bitmap();
}
gr_set_color(0, 0, 64);
render_models();
if (win->vset.show_distances) {
display_distances();
}
/*
display_ship_info();
display_active_ship_subsystem();
render_active_rect();
*/
// Fred tooltip stuff here
gr_set_color(0, 160, 0);
/*
fred_enable_htl();
jumpnode_render_all();
fred_disable_htl();
*/
auto c_pos = win->vset.c_pos;
auto c_orient = win->vset.c_orient;
SCP_string buf;
int w, h; // Used for displaying current position text
sprintf(buf, "(%.1f,%.1f,%.1f)", c_pos.xyz.x, c_pos.xyz.y, c_pos.xyz.z);
gr_get_string_size(&w, &h, buf.c_str());
gr_set_color_fast(&colour_white);
gr_string(gr_screen.max_w - w - 2, 2, buf.c_str());
g3_end_frame(); // ** Accounted for
render_compass();
gr_flip();
gr_reset_clip();
g3_start_frame(0); // ** Accounted for
g3_set_view_matrix(&c_pos, &c_orient, FRED_DEFAULT_HTL_FOV);
}
void wxfred::render_resize(glcViewport *win, int w, int h) {
auto canvas = win->FindWindow("GLCanvas");
canvas->SetSize(w, h);
gr_screen_resize(w, h);
}
+37
View File
@@ -0,0 +1,37 @@
#ifndef _WXFREDRENDER_H
#define _WXFREDRENDER_H
/*
* Created for the FreeSpace2 Source Code Project.
*
* You may not sell or otherwise commercially exploit the source or things you
* create based on the source.
*/
#include "glcViewport.h"
#include "globalincs/pstypes.h"
/**
* @brief This file defines the graphics interface used by wxFred
*/
namespace wxfred {
/**
* @brief Inits the graphics engine and viewport for rendering
*/
void render_init(glcViewport *win);
/**
* @brief Renders a frame on the given viewport
*/
void render_frame(glcViewport *win);
/**
* @brief Resizes the draw area/canvas
*/
void render_resize(glcViewport *win, int w, int h);
}; // namespace wxfred
#endif // _WXFREDRENDER_H
+746 -12
View File
@@ -2,34 +2,768 @@
* Created by Ian "Goober5000" Warfield for the FreeSpace2 Source Code Project.
* You may not sell or otherwise commercially exploit the source or things you
* create based on the source.
*/
//#include "mission.h"
#include "frmFRED2.h"
#include "base/wxFRED_base.h"
*/
#include "wxfred2.h"
#include <globalincs/pstypes.h>
#include "frmFRED2.h"
#include "base/wxFRED_base.h"
#include <ai/ai.h>
#include <ai/aigoals.h>
#include <ai/ai_profiles.h>
#include <asteroid/asteroid.h>
#include <bmpman/bmpman.h>
#include <gamesnd/eventmusic.h>
#include <globalincs/globals.h>
#include <globalincs/linklist.h>
#include <globalincs/mspdb_callstack.h>
#include <globalincs/pstypes.h>
#include <globalincs/safe_strings.h>
#include <hud/hudsquadmsg.h>
#include <iff_defs/iff_defs.h>
#include <jumpnode/jumpnode.h>
#include <localization/localize.h>
#include <math/vecmat.h>
#include <mission/missionbriefcommon.h>
#include <mission/missiongoals.h>
#include <mission/missionmessage.h>
#include <mission/missionparse.h>
#include <model/model.h>
#include <nebula/neb.h>
#include <object/object.h>
#include <object/waypoint.h>
#include <osapi/outwnd.h>
#include <parse/parselo.h>
#include <ship/ship.h>
#include <ship/ship_flags.h>
#include <species_defs/species_defs.h>
#include <starfield/nebula.h>
#include <starfield/starfield.h>
#include <weapon/weapon.h>
#include <wx/dir.h>
#include <wx/image.h>
#include <wx/string.h>
//#include <wx/xrc/xmlres.h>
#include <wx/wx.h>
#include <wx/wx.h>
#include <stdlib.h>
#include <algorithm>
// Referenced variables and functions from code.lib
char Fred_alt_names[MAX_SHIPS][NAME_LENGTH + 1];
char Fred_callsigns[MAX_SHIPS][NAME_LENGTH + 1];
int Show_cpu = 0;
int Fred_running = 1; // z64: :V:'s cheap hack to let the codebase know that fred-specific routines should be run
float Sun_spot = 0.0f;
// "Private" variables and functions
// from starfield.cpp
extern int Nmodel_num;
extern matrix Nmodel_orient;
extern int Nmodel_bitmap;
IMPLEMENT_APP(wxFRED2)
bool wxFRED2::OnInit()
{
wxFRED2::~wxFRED2() {
SCP_mspdbcs_Cleanup();
}
bool wxFRED2::OnInit() {
//wxXmlResource::Get()->InitAllHandlers();
//InitXmlResource();
//wxFREDMission* the_Mission = new wxFREDMission();
// Filepaths
Fred_base_dir = wxGetCwd().ToStdString();
Fred_exe_dir = Fred_base_dir + DIR_SEPARATOR_STR + "wxfred2.exe";
// Init FSO codebase
Init_FSO();
// Init GUI
wxChar* title = NULL;
// Init image handlers before frmFRED2 (wxFormBuilder workaround)
wxImage::AddHandler(new wxPNGHandler);
frmFRED2 *frame = new frmFRED2( title, 50, 50, 800, 600 );
SetTopWindow(frame);
frame->Show(TRUE);
frmFRED2 *Fred_gui = new frmFRED2(title, 50, 50, 800, 600);
SetTopWindow(Fred_gui);
Fred_gui->Show(TRUE);
return true;
}
// Mission Management Methods
void wxFRED2::Mission_clear() {
const char *str;
int i, j, count;
wxDateTime time;
/** Interface calls before calling this method:
Breifing_dialog->reset_editor()
fiction_viewer_reset();
cmd_brief_reset();
set_cur_indices(-1);
unmark_all();
set_physics_controls();
*/
/** Interface calls after calling this method:
fred_render_init();
*/
extern void allocate_mission_text(int size); // from parse/parselo.h
allocate_mission_text(MISSION_TEXT_SIZE);
The_mission.cutscenes.clear();
mission_event_shutdown();
// Set the asteroid field to defaults
Asteroid_field.num_initial_asteroids = 0;
Asteroid_field.speed = 0.0f;
vm_vec_make(&Asteroid_field.min_bound, -1000.0f, -1000.0f, -1000.0f);
vm_vec_make(&Asteroid_field.max_bound, 1000.0f, 1000.0f, 1000.0f);
vm_vec_make(&Asteroid_field.inner_min_bound, -500.0f, -500.0f, -500.0f);
vm_vec_make(&Asteroid_field.inner_max_bound, 500.0f, 500.0f, 500.0f);
Asteroid_field.has_inner_bound = 0;
Asteroid_field.field_type = FT_ACTIVE;
Asteroid_field.debris_genre = DG_ASTEROID;
Asteroid_field.field_debris_type[0] = -1;
Asteroid_field.field_debris_type[1] = -1;
Asteroid_field.field_debris_type[2] = -1;
strcpy_s(Mission_parse_storm_name, "none");
obj_init();
model_free_all();
ai_init();
ai_profiles_init();
ship_init();
jumpnode_level_close();
waypoint_level_close();
Num_wings = 0;
for (i = 0; i < MAX_WINGS; i++) {
Wings[i].wave_count = 0;
Wings[i].wing_squad_filename[0] = '\0';
Wings[i].wing_insignia_texture = -1;
}
for (i = 0; i < MAX_IFFS; i++) {
Shield_sys_teams[i] = 0;
}
for (i = 0; i < MAX_SHIP_CLASSES; i++) {
Shield_sys_types[i] = 0;
}
Num_ai_dock_names = 0;
Num_reinforcements = 0;
// Set default Mission Specs
str = wxGetUserName().c_str().AsChar();
strcpy_s(The_mission.name, "Untitled");
strncpy(The_mission.author, str, NAME_LENGTH - 1);
time = wxGetCurrentTime();
str = time.Format("%x at %X").c_str().AsChar();
strcpy_s(The_mission.created, str);
strcpy_s(The_mission.modified, The_mission.created);
strcpy_s(The_mission.notes, "This is a wxFRED2 created mission.\n");
strcpy_s(The_mission.mission_desc, "Put mission description here\n");
The_mission.game_type = MISSION_TYPE_SINGLE;
strcpy_s(The_mission.squad_name, "");
strcpy_s(The_mission.squad_filename, "");
The_mission.num_respawns = 3;
The_mission.max_respawn_delay = -1;
Player_starts = 0;
Num_teams = 1;
// reset alternate name & callsign stuff
for (i = 0; i < MAX_SHIPS; i++) {
strcpy_s(Fred_alt_names[i], "");
strcpy_s(Fred_callsigns[i], "");
}
// set up the default ship types for all teams. For now, this is the same class
// of ships for all teams
for (i = 0; i < MAX_TVT_TEAMS; i++) {
count = 0;
for (j = 0; j < MAX_SHIP_CLASSES; j++) {
if (Ship_info[j].flags[Ship::Info_Flags::Default_player_ship]) {
Team_data[i].ship_list[count] = j;
strcpy_s(Team_data[i].ship_list_variables[count], "");
Team_data[i].ship_count[count] = 5;
strcpy_s(Team_data[i].ship_count_variables[count], "");
count++;
}
}
Team_data[i].num_ship_choices = count;
count = 0;
for (j = 0; j < MAX_WEAPON_TYPES; j++) {
if (Weapon_info[j].wi_flags & WIF_PLAYER_ALLOWED) {
if (Weapon_info[j].subtype == WP_LASER) {
Team_data[i].weaponry_count[count] = 16;
} else {
Team_data[i].weaponry_count[count] = 500;
}
Team_data[i].weaponry_pool[count] = j;
strcpy_s(Team_data[i].weaponry_pool_variable[count], "");
strcpy_s(Team_data[i].weaponry_amount_variable[count], "");
count++;
}
Team_data[i].weapon_required[j] = false;
}
Team_data[i].num_weapon_choices = count;
}
*Mission_text = *Mission_text_raw = EOF_CHAR;
Mission_text[1] = Mission_text_raw[1] = 0;
waypoint_parse_init();
Num_mission_events = 0;
Num_goals = 0;
init_sexp();
messages_init();
brief_reset();
debrief_reset();
//ship_init();
event_music_reset_choices();
clear_texture_replacements();
mission_parse_reset_alt();
mission_parse_reset_callsign();
strcpy(Cargo_names[0], "Nothing");
Num_cargo = 1;
// reset background bitmaps and suns
stars_pre_level_init();
Nebula_index = 0;
Mission_palette = 1;
Nebula_pitch = (int) ((float) (rand() & 0x0fff) * 360.0f / 4096.0f);
Nebula_bank = (int) ((float) (rand() & 0x0fff) * 360.0f / 4096.0f);
Nebula_heading = (int) ((float) (rand() & 0x0fff) * 360.0f / 4096.0f);
Neb2_awacs = -1.0f;
Neb2_poof_flags = 0;
strcpy_s(Neb2_texture_name, "");
for (i = 0; i < MAX_NEB2_POOFS; i++) {
Neb2_poof_flags |= (1 << i);
}
Nmodel_flags = DEFAULT_NMODEL_FLAGS;
Nmodel_num = -1;
vm_set_identity(&Nmodel_orient);
Nmodel_bitmap = -1;
The_mission.contrail_threshold = CONTRAIL_THRESHOLD_DEFAULT;
// Goober5000
The_mission.command_persona = Default_command_persona;
strcpy_s(The_mission.command_sender, DEFAULT_COMMAND);
// Goober5000: reset ALL mission flags, not just nebula!
The_mission.flags.reset();
The_mission.support_ships.max_support_ships = -1; // negative means infinite
The_mission.support_ships.max_hull_repair_val = 0.0f;
The_mission.support_ships.max_subsys_repair_val = 100.0f;
The_mission.ai_profile = &Ai_profiles[Default_ai_profile];
nebula_init(Nebula_filenames[Nebula_index], Nebula_pitch, Nebula_bank, Nebula_heading);
char palette_filename[1024];
strcpy_s(palette_filename, "gamepalette1-01");
// sprintf( palette_filename, "gamepalette%d-%02d", 1, Mission_palette+1 );
mprintf(("Loading palette %s\n", palette_filename));
palette_load_table(palette_filename);
strcpy_s(The_mission.loading_screen[GR_640], "");
strcpy_s(The_mission.loading_screen[GR_1024], "");
strcpy_s(The_mission.skybox_model, "");
vm_set_identity(&The_mission.skybox_orientation);
strcpy_s(The_mission.envmap_name, "");
The_mission.skybox_flags = DEFAULT_NMODEL_FLAGS;
// no sound environment
The_mission.sound_environment.id = -1;
ENVMAP = -1;
Document.Modify(false);
}
void wxFRED2::Mission_new(void) {
Mission_reset();
Mission_filename[0] = '\0';
// docFREDDoc_ptr->autosave("nothing");
// Undo_count = 0;
};
bool wxFRED2::Mission_load(const wxString infile) {
wxMessageBox(_T("Sorry! This feature has not been implemented yet.\nPlease encourage a developer to get right on this. :)"), _T("Unimplemented feature"), wxOK);
return false;
}
void wxFRED2::Mission_reset() {
Mission_clear();
Create_player(&vmd_zero_vector, &vmd_identity_matrix, -1);
}
OIN_t wxFRED2::Copy_object(OIN_t oin) {
OIN_t oin_copy = -1;
object* objp;
if (oin < 0) {
throw Fred_exception("Error: Could not copy object - invalid input");
return -1;
}
objp = &Objects[oin];
switch (objp->type) {
case OBJ_JUMP_NODE:
oin_copy = Create_jumpnode(&objp->pos);
break;
case OBJ_SHIP:
case OBJ_START:
int inst; // Index in Ships[] to object
int inst_copy; // Index in Ships[] to object's copy
inst = objp->instance;
// MSVC doesn't like function pointers to class members, so gotta call directly
if (objp->type == OBJ_SHIP) {
oin_copy = Create_ship(&objp->pos, &objp->orient, Ships[inst].ship_info_index);
} else {
oin_copy = Create_player(&objp->pos, &objp->orient, Ships[inst].ship_info_index);
}
Assert(oin_copy >= 0);
// New ship created, now copy all relevant settings
// Ship info
inst_copy = Objects[oin_copy].instance;
Ships[inst_copy].team = Ships[inst].team;
Ships[inst_copy].arrival_cue = dup_sexp_chain(Ships[inst].arrival_cue);
Ships[inst_copy].departure_cue = dup_sexp_chain(Ships[inst].departure_cue);
Ships[inst_copy].cargo1 = Ships[inst].cargo1;
Ships[inst_copy].arrival_location = Ships[inst].arrival_location;
Ships[inst_copy].departure_location = Ships[inst].departure_location;
Ships[inst_copy].arrival_delay = Ships[inst].arrival_delay;
Ships[inst_copy].departure_delay = Ships[inst].departure_delay;
Ships[inst_copy].weapons = Ships[inst].weapons;
Ships[inst_copy].hotkey = Ships[inst].hotkey;
// AI Info
ai_info* aip1; // ai_info of object
ai_info* aip2; // ai_info of object's copy
aip1 = &Ai_info[Ships[inst].ai_index];
aip2 = &Ai_info[Ships[inst_copy].ai_index];
aip2->behavior = aip1->behavior;
aip2->ai_class = aip1->ai_class;
for (int i = 0; i < MAX_AI_GOALS; i++) {
aip2->goals[i] = aip1->goals[i];
}
if (aip1->ai_flags & AIF_KAMIKAZE)
aip2->ai_flags |= AIF_KAMIKAZE;
if (aip1->ai_flags & AIF_NO_DYNAMIC)
aip2->ai_flags |= AIF_NO_DYNAMIC;
aip2->kamikaze_damage = aip1->kamikaze_damage;
// Physics, Hull, and Shield
object *objp_copy; // object* to copy
objp_copy = &Objects[oin_copy];
objp_copy->phys_info.speed = objp->phys_info.speed;
objp_copy->phys_info.fspeed = objp->phys_info.fspeed;
objp_copy->hull_strength = objp->hull_strength;
objp_copy->shield_quadrant[0] = objp->shield_quadrant[0];
// Subsystems
ship_subsys* subp1; // ship_subsys* of object
ship_subsys* subp2; // ship_subsys* of object's copy
subp1 = GET_FIRST(&Ships[inst].subsys_list);
subp2 = GET_FIRST(&Ships[inst_copy].subsys_list);
while (subp2 != END_OF_LIST(&Ships[inst_copy].subsys_list)) {
Assert(subp1 != END_OF_LIST(&Ships[inst].subsys_list));
subp2->current_hits = subp1->current_hits;
subp2 = GET_NEXT(subp2);
subp1 = GET_NEXT(subp1);
}
// Reinforcements
for (int i = 0, j = 0; i < Num_reinforcements; i++)
if (!stricmp(Reinforcements[i].name, Ships[inst].ship_name)) {
// object has reinforcements, so object's copy will have reinforcements, too
if (Num_reinforcements < MAX_REINFORCEMENTS) {
j = Num_reinforcements;
Num_reinforcements++;
strcpy_s(Reinforcements[j].name, Ships[inst_copy].ship_name);
Reinforcements[j].type = Reinforcements[i].type;
Reinforcements[j].uses = Reinforcements[i].uses;
} else {
warning_stack.push_back("Warning: Copy_object - Could not create reinforcements for copied object. (Too many reinforcements already)\n");
}
break;
}
break;
case OBJ_WAYPOINT:
oin_copy = Create_waypoint(&objp->pos);
break;
default:
throw Fred_exception("Error: Could not copy object - invalid object type\n");
}
return oin_copy;
}
void wxFRED2::Copy_objects(SCP_vector<OIN_t> &selq) {
SCP_vector<OIN_t> wp_queue;
SCP_vector<OIN_t> new_selq;
OIN_t new_oin;
bool has_errors = false;
if (selq.size() == 0) {
throw Fred_exception("Error: Couldn't copy objects (nothing in selection queue)\n");
return;
}
for (auto it = selq.begin(); it != selq.end(); ++it) {
if (Objects[*it].type == OBJ_WAYPOINT) {
// Defer copying waypoints until later
wp_queue.push_back(*it);
} else {
try {
new_oin = Copy_object(*it);
} catch (const Fred_exception& e) {
// Couldn't copy this one, so skip it
has_errors = true;
warning_stack.push_back(e.what());
continue;
}
}
}
if (!wp_queue.empty()) {
int wp_inst = -1; // Waypoint instance to append a new waypoint to. Value of -1 makes a new list
int wpl_idx1 = -1; // Previous WPL
int wpl_idx2; // Current WPL
// Assumption: Waypoint's instances are a simple hash which contains their list idx and their sequence idx
// within that list, and is sortable (see /object/waypoint.cpp)
std::sort(wp_queue.begin(), wp_queue.end());
for (auto it = wp_queue.begin(); it != wp_queue.end(); ++it) {
wpl_idx2 = calc_waypoint_list_index(Objects[*it].instance);
if (wpl_idx1 != wpl_idx2) {
// New list detected, reset vars
wp_inst = -1;
wpl_idx1 = wpl_idx2;
}
// Copy the waypoint. If wp_inst = -1 a new list is formed
new_oin = waypoint_add(&Objects[*it].pos, wp_inst);
if (new_oin >= 0) {
// Keep the instance for next iteration
wp_inst = Objects[new_oin].instance;
// Copy complete, push to selection
new_selq.push_back(new_oin);
} else {
// Couln't copy this one for some reason
has_errors = true;
warning_stack.push_back("Error: couldn't copy waypoint");
}
}
obj_merge_created_list();
}
if (has_errors) {
throw Fred_exception("One or more errors occured during Copy_objects. Please review the warning stack.\n");
}
// Copy job done
Document.Modify(true);
selq = new_selq;
return;
}
OIN_t wxFRED2::Create_jumpnode(vec3d *pos) {
OIN_t obj;
CJumpNode jnp(pos);
obj = jnp.GetSCPObjectNumber();
Assert(obj >= 0);
Jump_nodes.push_back(std::move(jnp));
obj_merge_created_list();
return obj;
}
OIN_t wxFRED2::Create_player(vec3d *pos, matrix *orient, MTIN_t type) {
OIN_t obj = -1;
// Check that we're able to add a new player start
if (Player_starts >= 1) {
if (Player_starts >= MAX_PLAYERS) {
throw Fred_exception("Error: Unable to create new player start point. You have reached the maximum limit.\n");
} else if (The_mission.game_type & MISSION_TYPE_SINGLE) {
throw Fred_exception("Error: You can't have more than one player start in single player missions.\n");
} else if (The_mission.game_type & MISSION_TYPE_TRAINING) {
throw Fred_exception("Error: You can't have more than one player start in training missions.\n");
}
} else {
// Else, try creating player start
if (type < 0) {
type = MTIN_player_default;
}
try {
obj = Create_ship(pos, orient, type);
} catch (Fred_exception &e) {
// Rethrow with more descriptive message
// TODO: Include player start number in message
throw Fred_exception("Error: Could not create ship for player start.\n");
}
Assert(obj >= 0);
Player_starts++;
Objects[obj].type = OBJ_START;
// be sure arrival/departure cues are set
Ships[Objects[obj].instance].arrival_cue = Locked_sexp_true;
Ships[Objects[obj].instance].departure_cue = Locked_sexp_false;
obj_merge_created_list();
Document.Modify(true);
}
return obj;
}
OIN_t wxFRED2::Create_ship(vec3d *pos, matrix *orient, MTIN_t type) {
int obj, z1, z2;
float temp_max_hull_strength;
ship_info *sip;
if (Ship_info[type].flags[Ship::Info_Flags::No_fred]) {
// Is a Non-FRED-able object
throw Fred_exception("Error: Unable to create Non-FRED-able object");
return -1;
}
// ship::ship_create() tries to look in the cwd for the .pof's when loading in new models.
// Fred's currently in somewhere like <fs2path>[/modpath]/data/missions/ so we have to hop to <fs2path> in order to continue
SCP_string pwd;
pwd = wxGetCwd().ToStdString();
wxSetWorkingDirectory(Fred_base_dir);
obj = ship_create(orient, pos, type);
wxSetWorkingDirectory(pwd);
if (obj < 0) {
throw Fred_exception("Error: Unable to create new ship. (Unknown cause)");
return -1;
}
Objects[obj].phys_info.speed = 33.0f;
ship *shipp = &Ships[Objects[obj].instance];
sip = &Ship_info[shipp->ship_info_index];
// Probably not needed, since we're not naming the ship
/*
if (query_ship_name_duplicate(Objects[obj].instance))
fix_ship_name(Objects[obj].instance);
*/
// default stuff according to species and IFF
shipp->team = Species_info[Ship_info[shipp->ship_info_index].species].default_iff;
resolve_parse_flags(&Objects[obj], Iff_info[shipp->team].default_parse_flags);
// default shield setting
shipp->special_shield = -1;
z1 = Shield_sys_teams[shipp->team];
z2 = Shield_sys_types[type];
if (((z1 == 1) && (z2 != 0)) || (z2 == 1)) {
Objects[obj].flags.set(Object::Object_Flags::No_shields);
}
object *temp_objp;
ship *temp_shipp = NULL;
// find the first player ship
for (temp_objp = GET_FIRST(&obj_used_list); temp_objp != END_OF_LIST(&obj_used_list); temp_objp = GET_NEXT(temp_objp)) {
if (temp_objp->type == OBJ_START) {
temp_shipp = &Ships[temp_objp->instance];
break;
}
}
// set orders if ship is on same team as the player, or if player couldn't be found
if (temp_shipp == NULL || shipp->team == temp_shipp->team) {
// if this ship is not a small ship, then make the orders be the default orders without
// the depart item
if (!(sip->is_small_ship())) {
shipp->orders_accepted = ship_get_default_orders_accepted(sip);
shipp->orders_accepted &= ~DEPART_ITEM;
}
} else {
// Else, no orders
shipp->orders_accepted = 0;
}
// calc kamikaze stuff
if (shipp->use_special_explosion) {
temp_max_hull_strength = (float) shipp->special_exp_blast;
} else {
temp_max_hull_strength = sip->max_hull_strength;
}
Ai_info[shipp->ai_index].kamikaze_damage = (int) std::min(1000.0f, 200.0f + (temp_max_hull_strength / 4.0f));
int n;
n = Objects[obj].instance;
Ships[n].arrival_cue = alloc_sexp("true", SEXP_ATOM, SEXP_ATOM_OPERATOR, -1, -1);
Ships[n].departure_cue = alloc_sexp("false", SEXP_ATOM, SEXP_ATOM_OPERATOR, -1, -1);
Ships[n].cargo1 = 0;
obj_merge_created_list();
return obj;
}
OIN_t wxFRED2::Create_waypoint(vec3d *pos, OIN_t oin) {
int inst; // Object instance of the waypoint indexed by oin, if supplied
int obj; // Object instance of the new waypoint
if (oin >= 0) {
if (Objects[oin].type == OBJ_WAYPOINT) {
inst = Objects[oin].instance;
} else {
inst = -1;
}
}
obj = waypoint_add(pos, inst);
if (obj >= 0) {
Document.Modify(true);
obj_merge_created_list();
} else {
throw Fred_exception("Error: Unable to create waypoint (Unknown cause)");
}
return obj;
}
void wxFRED2::Init_FSO(void) {
SCP_mspdbcs_Initialise();
#ifndef NDEBUG
// TODO Maybe use wxWidget's windows instead
outwnd_init();
#endif
SDL_SetMainReady();
memory::init();
srand((unsigned) time(NULL));
// init_pending_messages();
os_init(Osreg_class_name, Osreg_app_name);
timer_init();
Assert(Fred_base_dir.size() > 0); //-V805
// sigh... this should enable proper reading of cmdline_fso.cfg - Goober5000
cfile_chdir(Fred_base_dir.c_str());
// this should enable mods - Kazan
// parse_cmdline(__argc, __argv);
// TODO: Print cmdline if DEBUG
// d'oh
if (cfile_init(Fred_exe_dir.c_str())) {
wxMessageBox("Failed to init cfile!"); // TODO: Make this aware of cmdline instances. If it's cmdline, output message to console instead of making a messagebox
wxExit();
}
// Load game_settings.tbl
// mod_table_init();
// initialize localization module. Make sure this is done AFTER initialzing OS.
// NOTE : Fred should ALWAYS run in English. Otherwise it might swap in another language
// when saving - which would cause inconsistencies when externalizing to tstrings.tbl via Exstr
// trust me on this :)
lcl_init(FS2_OPEN_DEFAULT_LANGUAGE);
// Goober5000 - force init XSTRs (so they work, but only work in English, based on above comment)
extern int Xstr_inited;
Xstr_inited = 1;
#ifndef NDEBUG
load_filter_info();
#endif
//CFREDView *window = CFREDView::GetView();
//HWND hwndApp = window->GetSafeHwnd();
//os_set_window((uint) hwndApp);
snd_init();
// Not ready for this yet
// Cmdline_nospec = 1;
// Cmdline_noglow = 1;
Cmdline_window = 1;
}
bool wxFRED2::Has_warnings() {
bool retval;
(warning_stack.size() > 0) ? (retval = true) : (retval = false);
return retval;
}
void wxFRED2::Get_warnings(SCP_vector<SCP_string> &warnings) {
warnings = warning_stack;
warning_stack.clear();
}
void wxFRED2::Ignore_warnings() {
warning_stack.clear();
}
+181 -7
View File
@@ -4,20 +4,194 @@
* Created by Ian "Goober5000" Warfield for the FreeSpace2 Source Code Project.
* You may not sell or otherwise commercially exploit the source or things you
* create based on the source.
*/
*/
#include "docfred.h"
#include <mission/missionparse.h>
#include <object/object.h>
#include <globalincs/globals.h>
#include <globalincs/pstypes.h>
#include <globalincs/vmallocator.h>
#include <wx/wx.h>
#include <exception>
#include <string>
#include <vector>
// ==typedefs==
// The following typedef's use negative values as invalid states. Most functions only check if it's negative or positive, not a specific value
typedef int MTIN_t; // Model Type Index Number, used to create objects of the assoc. model type
typedef int OIN_t; // Object Index Number, used to keep track of all object instances (except waypoints)
// ==Constants==
const OIN_t OIN_NO_OBJECT = -1; // OIN of a non-object. Used in some cases where a default is desired
// ==Statics==
static MTIN_t MTIN_player_default; // MTIN of the player's default ship
// The following MTIN's are effectively appended to the end of the ship type selection list.
static MTIN_t MTIN_jump_node; // MTIN of jump nodes, equal to Num_ship_classes + 2
static MTIN_t MTIN_player_start; // MTIN of player starts, equal to Num_ship_classes + 1
static MTIN_t MTIN_waypoint; // MTIN of waypoints, equal to Num_ship_classes
// Directories and File Handling stuff
static SCP_string Fred_base_dir; // The directory containing the executable
static SCP_string Fred_exe_dir; // The full filepath of the executable. Currently only used by cfile
// ==classes, structs, unions==
// a.k.a. z64's stupid exception placeholder
class Fred_exception : public std::runtime_error
{
public:
Fred_exception(const char* msg) : std::runtime_error(msg) {};
};
class wxFRED2 : public wxApp
{
public:
virtual bool OnInit();
void LoadMission();
void NewMission();
void SaveMission();
public:
virtual bool OnInit();
/**
* @brief Deconstructor
*/
~wxFRED2();
/**
* @brief Checks to see if any recently called wxFRED2 functions generated warnings
*
* @returns true If there are warnings, or
* @returns false otherwise
*
* @details Sometimes commands generate warnings, which are recoverable errors that don't halt the command's
* execution. Commands that do generate warnings should be immediately followed by a call to Has_Warnings, and
* then Get_Warnings so that the end-user is adequately notified.
*/
bool Has_warnings();
/**
* @brief Gets any warnings that were generated by recently called wxFRED2 functions and clears the internal warning stack
*
* @param[out] warnings The output string vector
*
* @details Sometimes commands generate warnings, which are recoverable errors that don't halt the command's
* execution. Commands that do generate warnings should be immediately followed by a call to Has_Warnings, and
* then Get_Warnings so that the end-user is adequately notified.
*/
void Get_warnings(SCP_vector<SCP_string> &warnings);
/**
* @brief Clears the internal warning stack (USE SPARINGLY)
*/
void Ignore_warnings();
// Mission management
bool Mission_load(const wxString infile);
void Mission_new(void);
void Mission_save(void);
// Object management
/**
* @brief Copies the indexed object
*
* @param[in] oin index of the object to copy
*
* @returns index of the copy
*
* @details Can generate Warnings
*/
OIN_t Copy_object(OIN_t oin);
/**
* @brief Copies the indexed objects within the selection queue
*
* @param[in] selq A queue of indexed objects selected for copying
*
* @returns index of the copy
*/
void Copy_objects(SCP_vector<OIN_t> &selq);
/**
* @brief Deletes the indexed object
*
* @param[in] oin Index of the object to delete
*
* @returns 0 If successful
* @returns 1 If unsuccessful
* @returns 2 If aborted
*/
int Delete_object(OIN_t oin);
/**
* @brief Deletes the indexed objects within the selection queue
*
* @param[in] selq A queue of indexed objects selected for deletion
*
* @returns 0 If successful
* @returns 1 If unsuccessful
* @returns 2 If aborted
*/
int Delete_objects(SCP_vector<OIN_t> &selq);
/**
* @brief Creates a jump node at the given position
*
* @param pos Position to create a new jump node
*/
OIN_t Create_jumpnode(vec3d *pos);
/**
* @brief Creates a player spawn point at the designated position.
*
* @param[in] pos Position to create a new spawn point
* @param[in] orient Direction the player faces (if spawned here)
* @param[in] type Type of craft this player defaults to
*
*/
OIN_t Create_player(vec3d *pos, matrix *orient, MTIN_t type);
/**
* @brief Creates a ship at the designated position
*
* @param[in] pos Position to create a new ship
* @param[in] orient Direction the player faces (if spawned here)
* @param[in] type Type of craft to create
*/
OIN_t Create_ship(vec3d *pos, matrix *orient, MTIN_t type);
/**
* @brief Creates a waypoint at the designated position
*
* @param[in] pos Position to create a new waypoint
* @param[in] oin Object index of a waypoint. The new waypoint will be appended to its list.
*/
OIN_t Create_waypoint(vec3d *pos, OIN_t oin = OIN_NO_OBJECT);
char** Get_ship_types(void); // Retrieves the available ship types as a char[][]
// Shield Systems (temporarily here) probably should be bool
int Shield_sys_teams[MAX_IFFS];
int Shield_sys_types[MAX_SHIP_CLASSES];
protected:
// FreeSpace codebase interactions
void Init_FSO(void); // Init's the FSO codebase/backend, excluding the graphics init (that's done by the viewport)
// Mission management
void Mission_reset(void); // Init's/ Resets the mission to initial conditions
void Mission_clear(void); // Wipes out everything, leaving a clean slate to start with
private:
SCP_vector<SCP_string> warning_stack;
SCP_vector<SCP_string> ship_types;
docFRED2 Document;
};
DECLARE_APP(wxFRED2)
#endif
#endif
+230
View File
@@ -0,0 +1,230 @@
/*
* Created by z64555 for the FreeSpace Source Code project.
*
* This is a derivative work of Volition Inc.'s Freespace 2 Editor (FRED2)
* You may not sell or otherwise commercially exploit the source or things you
* created based on the source.
*/
/**
* File of deprecated data members and functions.
*
* There's a number of references within the FreeSpace 2 Open codebase that link to files and objects within the main
* executable. Since FRED2 (and likewise wxFRED2) currently has no need of these, they must be re-defined within the
* scope of the wxFRED2 objects.
*/
#include "globalincs/pstypes.h"
#include "object/object.h"
#include "io/key.h"
#include "ship/ship.h"
#include "graphics/2d.h"
#include "mission/missionparse.h"
#include "network/psnet2.h"
#include "stats/scoring.h"
#include "cfile/cfile.h"
float flFrametime;
int game_zbuffer = 1;
int Current_mission = 0xdeadbeef;
char **Builtin_mission_names;
char Game_current_mission_filename[MAX_FILENAME_LEN];
CFILE *Working_demo;
struct beam_info;
bool Env_cubemap_drawn = false;
int Multi_ping_timestamp = -1;
int Sun_drew = 0;
int Networking_disabled = 0;
void init_ets(class object*){}
control_info PlayerControls;
char * Game_CDROM_dir = NULL;
void game_flash(float r, float g, float b ) {}
void freespace_menu_background()
{
gr_reset_clip();
gr_clear();
}
int My_observer_num;
void std_update_goals() {}
void os_close() {}
int gameseq_get_state(void)
{
return 0;
}
int game_check_key()
{
return key_inkey();
}
int game_poll()
{
return key_inkey();
}
void multi_delete_ship(object *obj) {}
void send_homing_fired_packet() {}
void game_flush() {}
typedef struct config_struct
{
int boob;
} config_struct;
config_struct default_config;
typedef struct netgame_info
{
int bubba;
} netgame_info;
void send_netgame_state_packet() {}
void send_update_state_packet() {}
void send_goal_status_packet() {}
int Show_area_effect;
void state_set_mem(unsigned char *c, int i) {}
int state_check_mem(unsigned char *c, int i) { return 0; }
void demo_do_flag_dead(int i) {}
void demo_checkpoint() {}
void demo_set_playback_filter() {}
void multi_end_sequence() {}
void multi_server_respawn() {}
void multi_build_respawn_points() {}
void store_p_object( p_object *pbojp, CFILE *fp ) {}
void restore_p_object( p_object *pobjp, CFILE *dp) {}
int Multi_squad_msg_targ;
int Multi_squad_msg_local;
void send_support_warpin_packet(int,int,int){}
void send_support_warpin_packet( int net_sig, int how ) {}
int demo_query_debug(int id) { return 0; };
void send_support_warpin_packet(int){}
void game_whack_apply(float x, float y) {}
void save_restore_vector(vec3d *vec, CFILE *fp, int version, vec3d *deflt) {}
void save_restore_matrix(matrix *mat, CFILE *fp, int version, matrix *deflt) {}
void save_restore_float(float *fl, CFILE *fp, int version, float deflt) {}
void save_restore_angles(angles *ang, CFILE *fp, int version, angles *deflt) {}
void save_restore_int(int *n, CFILE *fp, int version, int deflt) {}
void save_restore_uint(uint *n, CFILE *fp, int version, uint deflt) {}
void save_restore_short(short *n, CFILE *fp, int version, short deflt) {}
void save_restore_ushort(ushort *n, CFILE *fp, int version, ushort deflt) {}
void save_restore_ubyte(ubyte *n, CFILE *fp, int version, ubyte deflt) {}
void save_restore_fix(fix *n, CFILE *fp, int version, fix deflt) {}
void save_restore_string(char *str, CFILE *fp, int len, int version, char *deflt) {}
void save_restore_p_object(p_object *pobj, CFILE *fp) {}
char *restore_string_alloc(CFILE *fp, int version, char *deflt) { return NULL; }
void demo_write_char(char x) {}
char demo_read_char() { return 0; }
int red_alert_default_status() {return 0;}
void send_ship_kill_packet(class object *,class object *,float,unsigned char) {}
void send_debris_create_packet( object *objp, ushort net_sig, int model_num, vec3d pos) {}
int Game_subspace_effect;
void big_explosion_flash(float x) {}
int game_do_cd_check(char *) {return 0;}
void game_stop_looped_sounds() {}
int Game_skill_level;
int game_cd_changed(void) {return 0;}
int Interface_framerate;
void game_set_view_clip(){}
int Warpout_forced = 0;
float Warpout_time;
vec3d Dead_player_last_vel;
int game_start_mission(){return 0;}
int Game_weapons_tbl_valid;
int Game_ships_tbl_valid;
void game_level_close(){}
void game_enter_state(int, int){}
void game_leave_state(int, int){}
int Test_begin;
int Debug_octant;
int Framerate_delay;
void game_start_time(){}
void game_stop_time(){}
int game_get_default_skill_level(){return 0;}
float FreeSpace_gamma;
int set_cdrom_path(int){return 0;}
int find_freespace_cd(char*){return 0;}
void get_version_string(){}
void game_do_state_common(int, int){}
void game_set_frametime(int){}
void game_increase_skill_level(){}
void get_version_string(char*, int){}
int Show_target_weapons;
int Show_target_debug_info;
int Game_do_state_should_skip;
long Game_time_compression;
struct fs_builtin_mission *game_find_builtin_mission(char*){return NULL;}
void game_format_time(fix, char*){}
void game_do_state(int){}
void game_process_event(int, int){}
void game_shudder_apply(int, float){}
int game_hacked_data(){return 0;}
int game_single_step;
int last_single_step;
void get_version_string_short(char *){}
void game_tst_mark(class object *, class ship *){}
int tst;
//int Player_multi_died_check;
int Show_framerate = 0;
void alt_tab_pause(){}
void game_feature_disabled_popup() {}
void game_pause() {}
void game_unpause() {}
// Sexp's
void game_start_subspace_ambient_sound() {}
void game_stop_subspace_ambient_sound() {}
//Time stuff
bool Time_compression_locked;
float flRealframetime;
void lock_time_compression(bool is_locked){}
void change_time_compression(float multiplier){}
void set_time_compression(float multiplier, float change_time){}
fix game_get_overall_frametime() { return 0; }
//WMC
void game_level_init(int seed){}
void game_level_init() {}
void game_post_level_init(){}
camid game_render_frame_setup(){return camid();}
void game_render_frame(camid cid){}
void game_simulation_frame(){}
void game_update_missiontime(){}
void game_render_post_frame(){}