#include <simgear/compiler.h>
-#ifdef FG_MATH_EXCEPTION_CLASH
+#ifdef SG_MATH_EXCEPTION_CLASH
# include <math.h>
#endif
#endif
#include <GL/glut.h>
-#include <simgear/xgl/xgl.h>
+#include <GL/gl.h>
#if defined(FX) && defined(XMESA)
# include <GL/xmesa.h>
#include <simgear/constants.h>
#include <simgear/debug/logstream.hxx>
-#include <simgear/misc/fgpath.hxx>
+#include <simgear/misc/sg_path.hxx>
#include <simgear/screen/screen-dump.hxx>
#include <Include/general.hxx>
#include <Cockpit/panel.hxx>
#include <Controls/controls.hxx>
#include <FDM/flight.hxx>
-#include <Main/bfi.hxx>
#include <Main/fg_init.hxx>
#include <Main/fg_io.hxx>
#include <Main/globals.hxx>
#include <Main/fg_props.hxx>
#include <Main/options.hxx>
+#include <Main/viewmgr.hxx>
#ifdef FG_NETWORK_OLK
#include <NetworkOLK/network.h>
#include "net_dlg.hxx"
#include "sgVec3Slider.hxx"
-FG_USING_STD(string);
+SG_USING_STD(string);
-#ifndef FG_HAVE_NATIVE_SGI_COMPILERS
-FG_USING_STD(cout);
+#ifndef SG_HAVE_NATIVE_SGI_COMPILERS
+SG_USING_STD(cout);
#endif
-#if defined(WIN32) || defined(__CYGWIN32__)
-#define WIN32_CURSOR_TWEAKS
-#elif (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 9)
-#define X_CURSOR_TWEAKS
-#endif
+#ifdef _MSC_VER
+#define snprintf _snprintf
+#endif /* _MSC_VER */
// main.cxx hack, should come from an include someplace
extern void fgInitVisuals( void );
FG_PUSH_PUI_DIALOG( dialogBox );
}
+// Message Box to report an error.
+void guiErrorMessage (const char *txt)
+{
+ SG_LOG(SG_GENERAL, SG_ALERT, txt);
+ if (dialogBox != 0)
+ mkDialog(txt);
+}
+
+// Message Box to report a throwable (usually an exception).
+void guiErrorMessage (const char *txt, const sg_throwable &throwable)
+{
+ string msg = txt;
+ msg += '\n';
+ msg += throwable.getFormattedMessage();
+ if (throwable.getOrigin() != "") {
+ msg += "\n (reported by ";
+ msg += throwable.getOrigin();
+ msg += ')';
+ }
+ SG_LOG(SG_GENERAL, SG_ALERT, msg);
+ if (dialogBox != 0)
+ mkDialog(msg.c_str());
+}
+
// Toggle the Menu and Mouse display state
void guiToggleMenu(void)
{
static puOneShot *SaveDialogOkButton = 0;
static puOneShot *SaveDialogCancelButton = 0;
-static puOneShot *SaveDialogResetButton = 0;
+// static puOneShot *SaveDialogResetButton = 0;
// Default save filename
static char saveFile[256] = "fgfs.sav";
if (output.good() && fgSaveFlight(output)) {
output.close();
mkDialog("Saved flight");
- FG_LOG(FG_INPUT, FG_INFO, "Saved flight");
+ SG_LOG(SG_INPUT, SG_INFO, "Saved flight");
} else {
mkDialog("Cannot save flight");
- FG_LOG(FG_INPUT, FG_ALERT, "Cannot save flight");
+ SG_LOG(SG_INPUT, SG_ALERT, "Cannot save flight");
}
}
static puOneShot *LoadDialogOkButton = 0;
static puOneShot *LoadDialogCancelButton = 0;
-static puOneShot *LoadDialogResetButton = 0;
+// static puOneShot *LoadDialogResetButton = 0;
// Default load filename
static char loadFile[256] = "fgfs.sav";
if (input.good() && fgLoadFlight(input)) {
input.close();
mkDialog("Loaded flight");
- FG_LOG(FG_INPUT, FG_INFO, "Restored flight");
+ SG_LOG(SG_INPUT, SG_INFO, "Restored flight");
} else {
mkDialog("Failed to load flight");
- FG_LOG(FG_INPUT, FG_ALERT, "Cannot load flight");
+ SG_LOG(SG_INPUT, SG_ALERT, "Cannot load flight");
}
}
void goodBye(puObject *)
{
- // FG_LOG( FG_INPUT, FG_ALERT,
+ // SG_LOG( SG_INPUT, SG_ALERT,
// "Program exiting normally at user request." );
cout << "Program exiting normally at user request." << endl;
# endif
#endif
-#if !defined(WIN32)
- string url = "http://www.flightgear.org/Docs/InstallGuide/getstart.html";
+ SGPath path( globals->get_fg_root() );
+ path.append( "Docs/index.html" );
+ string help_app = fgGetString("/sim/startup/browser-app");
+
if ( system("xwininfo -name Netscape > /dev/null 2>&1") == 0 ) {
- command = "netscape -remote \"openURL(" + url + ")\" &";
+ command = help_app + " -remote \"openURL(" + path.str() + ")\"";
} else {
- command = "netscape " + url + " &";
+ command = help_app + " " + path.str();
}
-#else
- command = "webrun.bat";
+#if !defined(WIN32)
+ command += " &";
#endif
system( command.c_str() );
- //string text = "Help started in netscape window.";
-
- //mkDialog (text.c_str());
mkDialog ("Help started in netscape window.");
}
+#define TR_HIRES_SNAP
+#if defined( TR_HIRES_SNAP)
+#include <simgear/screen/tr.h>
+extern void trRenderFrame( void );
+extern void fgUpdateHUD( GLfloat x_start, GLfloat y_start,
+ GLfloat x_end, GLfloat y_end );
+
+void fgHiResDump()
+{
+ FILE *f;
+ string message;
+ bool show_pu_cursor = false;
+ bool show_menu = false;
+ char *filename = new char [24];
+ static int count = 1;
+
+ int freeze = globals->get_freeze();
+ if(!freeze)
+ globals->set_freeze( true );
+
+ if(gui_menu_on) {
+ show_menu = true;
+ guiToggleMenu();
+ }
+
+ if ( !puCursorIsHidden() ) {
+ show_pu_cursor = true;
+ puHideCursor();
+ }
+
+ fgInitVisuals();
+ fgReshape( fgGetInt("/sim/startup/xsize"),
+ fgGetInt("/sim/startup/ysize") );
+
+ // we need two render frames here to clear the menu and cursor
+ // ... not sure why but doing an extra fgRenderFrame() shouldn't
+ // hurt anything
+ fgRenderFrame();
+ fgRenderFrame();
+
+ // Make sure we have SSG projection primed for current view
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+ ssgSetCamera( (sgVec4 *)globals->get_current_view()->get_VIEW() );
+ float fov = globals->get_current_view()->get_fov();
+ ssgSetFOV(fov, fov * globals->get_current_view()->get_win_ratio());
+ // ssgSetNearFar( 10.0f, 120000.0f );
+ ssgSetNearFar( 0.5f, 1200000.0f );
+
+
+ // This ImageSize stuff is a temporary hack
+ // should probably use 128x128 tile size and
+ // support any image size
+
+ // This should be a requester to get multiplier from user
+ int multiplier = 3;
+ int width = fgGetInt("/sim/startup/xsize");
+ int height = fgGetInt("/sim/startup/ysize");
+
+ /* allocate buffer large enough to store one tile */
+ GLubyte *tile = (GLubyte *)malloc(width * height * 3 * sizeof(GLubyte));
+ if (!tile) {
+ printf("Malloc of tile buffer failed!\n");
+ return;
+ }
+
+ int imageWidth = multiplier*width;
+ int imageHeight = multiplier*height;
+
+ /* allocate buffer to hold a row of tiles */
+ GLubyte *buffer
+ = (GLubyte *)malloc(imageWidth * height * 3 * sizeof(GLubyte));
+ if (!buffer) {
+ free(tile);
+ printf("Malloc of tile row buffer failed!\n");
+ return;
+ }
+ TRcontext *tr = trNew();
+ trTileSize(tr, width, height, 0);
+ trTileBuffer(tr, GL_RGB, GL_UNSIGNED_BYTE, tile);
+ trImageSize(tr, imageWidth, imageHeight);
+ trRowOrder(tr, TR_TOP_TO_BOTTOM);
+ sgFrustum *frustum = ssgGetFrustum();
+ trFrustum(tr,
+ frustum->getLeft(), frustum->getRight(),
+ frustum->getBot(), frustum->getTop(),
+ frustum->getNear(), frustum->getFar());
+
+ /* Prepare ppm output file */
+ while (count < 1000) {
+ snprintf(filename, 24, "fgfs-screen-%03d.ppm", count++);
+ if ( (f = fopen(filename, "r")) == NULL )
+ break;
+ fclose(f);
+ }
+ f = fopen(filename, "wb");
+ if (!f) {
+ printf("Couldn't open image file: %s\n", filename);
+ free(buffer);
+ free(tile);
+ return;
+ }
+ fprintf(f,"P6\n");
+ fprintf(f,"# ppm-file created by %s\n", "trdemo2");
+ fprintf(f,"%i %i\n", imageWidth, imageHeight);
+ fprintf(f,"255\n");
+
+ /* just to be safe... */
+ glPixelStorei(GL_PACK_ALIGNMENT, 1);
+
+ /* Because the HUD and Panel change the ViewPort we will
+ * need to handle some lowlevel stuff ourselves */
+ int ncols = trGet(tr, TR_COLUMNS);
+ int nrows = trGet(tr, TR_ROWS);
+
+ bool do_hud = fgGetBool("/sim/hud/visibility");
+ GLfloat hud_col_step = 640.0 / ncols;
+ GLfloat hud_row_step = 480.0 / nrows;
+
+ bool do_panel = fgPanelVisible();
+ GLfloat panel_col_step = current_panel->getWidth() / ncols;
+ GLfloat panel_row_step = current_panel->getHeight() / nrows;
+
+ /* Draw tiles */
+ int more = 1;
+ while (more) {
+ trBeginTile(tr);
+ int curColumn = trGet(tr, TR_CURRENT_COLUMN);
+ int curRow = trGet(tr, TR_CURRENT_ROW);
+ trRenderFrame();
+ if ( do_hud )
+ fgUpdateHUD( curColumn*hud_col_step, curRow*hud_row_step,
+ (curColumn+1)*hud_col_step, (curRow+1)*hud_row_step );
+ if (do_panel)
+ current_panel->update( curColumn*panel_col_step, panel_col_step,
+ curRow*panel_row_step, panel_row_step );
+ more = trEndTile(tr);
+
+ /* save tile into tile row buffer*/
+ int curTileWidth = trGet(tr, TR_CURRENT_TILE_WIDTH);
+ int bytesPerImageRow = imageWidth * 3*sizeof(GLubyte);
+ int bytesPerTileRow = (width) * 3*sizeof(GLubyte);
+ int xOffset = curColumn * bytesPerTileRow;
+ int bytesPerCurrentTileRow = (curTileWidth) * 3*sizeof(GLubyte);
+ int i;
+ for (i=0;i<height;i++) {
+ memcpy(buffer + i*bytesPerImageRow + xOffset, /* Dest */
+ tile + i*bytesPerTileRow, /* Src */
+ bytesPerCurrentTileRow); /* Byte count*/
+ }
+
+ if (curColumn == trGet(tr, TR_COLUMNS)-1) {
+ /* write this buffered row of tiles to the file */
+ int curTileHeight = trGet(tr, TR_CURRENT_TILE_HEIGHT);
+ int bytesPerImageRow = imageWidth * 3*sizeof(GLubyte);
+ int i;
+ for (i=0;i<curTileHeight;i++) {
+ /* Remember, OpenGL images are bottom to top. Have to reverse. */
+ GLubyte *rowPtr = buffer + (curTileHeight-1-i) * bytesPerImageRow;
+ fwrite(rowPtr, 1, imageWidth*3, f);
+ }
+ }
+
+ }
+
+ fgReshape( width, height );
+
+ trDelete(tr);
+
+ fclose(f);
+
+ message = "Snap shot saved to ";
+ message += filename;
+ mkDialog (message.c_str());
+
+ free(tile);
+ free(buffer);
+
+ // message = "Snap shot saved to ";
+ // message += filename;
+ // mkDialog (message.c_str());
+
+ delete [] filename;
+
+ if( show_menu )
+ guiToggleMenu();
+
+ if ( show_pu_cursor ) {
+ puShowCursor();
+ }
+
+ if(!freeze)
+ globals->set_freeze( false );
+}
+#endif // #if defined( TR_HIRES_SNAP)
+
+
#if defined( WIN32 ) && !defined( __CYGWIN__)
static void rotateView( double roll, double pitch, double yaw )
}
+void dumpHiResSnapShot ( puObject *obj ) {
+ fgHiResDump();
+}
+
+
// do a screen snap shot
void fgDumpSnapShot () {
bool show_pu_cursor = false;
+ char *filename = new char [24];
+ string message;
+ static int count = 1;
int freeze = globals->get_freeze();
if(!freeze)
fgGetInt("/sim/startup/ysize") );
// we need two render frames here to clear the menu and cursor
- // ... not sure why but doing an extra fgFenderFrame() shoulnd't
+ // ... not sure why but doing an extra fgRenderFrame() shouldn't
// hurt anything
fgRenderFrame();
fgRenderFrame();
- my_glDumpWindow( "fgfs-screen.ppm",
- fgGetInt("/sim/startup/xsize"),
- fgGetInt("/sim/startup/ysize") );
-
- mkDialog ("Snap shot saved to fgfs-screen.ppm");
+ while (count < 1000) {
+ FILE *fp;
+ snprintf(filename, 24, "fgfs-screen-%03d.ppm", count++);
+ if ( (fp = fopen(filename, "r")) == NULL )
+ break;
+ fclose(fp);
+ }
+
+ if ( sg_glDumpWindow( filename,
+ fgGetInt("/sim/startup/xsize"),
+ fgGetInt("/sim/startup/ysize")) ) {
+ message = "Snap shot saved to ";
+ message += filename;
+ } else {
+ message = "Failed to save to ";
+ message += filename;
+ }
+
+ mkDialog (message.c_str());
+
+ delete [] filename;
if ( show_pu_cursor ) {
puShowCursor();
"Print",
#endif
"Snap Shot",
+ "Hires Snap Shot",
"---------",
"Reset",
"Load flight",
#endif
/* NULL, notCb, */
dumpSnapShot,
+ dumpHiResSnapShot,
NULL,
reInit,
loadFlight,
gui_msg_RESET = msg_RESET; // "RESET"
// Next check home directory
- FGPath fntpath;
+ SGPath fntpath;
char* envp = ::getenv( "FG_FONTS" );
if ( envp != NULL ) {
fntpath.set( envp );
puSetDefaultFonts( GuiFont, GuiFont ) ;
guiFnt = puGetDefaultLabelFont();
- if (!fgHasValue("/sim/startup/mouse-pointer")) {
+ if (!fgHasNode("/sim/startup/mouse-pointer")) {
// no preference specified for mouse pointer, attempt to autodetect...
// Determine if we need to render the cursor, or if the windowing
// system will do it. First test if we are rendering with glide.