diff --git a/direct/src/p3d/AppRunner.py b/direct/src/p3d/AppRunner.py index da92fdd3cb..0f42b2ecde 100644 --- a/direct/src/p3d/AppRunner.py +++ b/direct/src/p3d/AppRunner.py @@ -635,13 +635,13 @@ class AppRunner(DirectObject): try: taskMgr.run() - except SystemExit: + except SystemExit as err: # Presumably the window has already been shut down here, but shut # it down again for good measure. if hasattr(__builtin__, "base"): base.destroy() - self.notify.info("Normal exit.") + self.notify.info("Normal exit with status %d." % err.code) raise except: diff --git a/direct/src/plugin/p3dPythonMain.cxx b/direct/src/plugin/p3dPythonMain.cxx index bf218a8cb9..ef5b83e282 100644 --- a/direct/src/plugin/p3dPythonMain.cxx +++ b/direct/src/plugin/p3dPythonMain.cxx @@ -150,10 +150,10 @@ main(int argc, char *argv[]) { } } - if (!run_p3dpython(program_name, archive_file, input_handle, output_handle, - NULL, interactive_console)) { + int status = run_p3dpython(program_name, archive_file, input_handle, + output_handle, NULL, interactive_console); + if (status != 0) { cerr << "Failure on startup.\n"; - return 1; } - return 0; + return status; } diff --git a/direct/src/plugin/p3dPythonRun.cxx b/direct/src/plugin/p3dPythonRun.cxx index 88a7131470..5c0ca28476 100644 --- a/direct/src/plugin/p3dPythonRun.cxx +++ b/direct/src/plugin/p3dPythonRun.cxx @@ -151,8 +151,10 @@ P3DPythonRun:: // Access: Public // Description: Runs the embedded Python process. This method does // not return until the plugin is ready to exit. +// +// Returns the exit status, which will be 0 on success. //////////////////////////////////////////////////////////////////// -bool P3DPythonRun:: +int P3DPythonRun:: run_python() { #if defined(_WIN32) && defined(USE_DEBUG_PYTHON) // On Windows, in a debug build, we have to preload sys.dll_suffix = @@ -170,7 +172,7 @@ run_python() { if (panda3d_module == NULL) { nout << "Failed to create panda3d module:\n"; PyErr_Print(); - return false; + return 1; } // Set the __path__ such that it can find panda3d/core.pyd, etc. @@ -188,7 +190,7 @@ run_python() { if (vfsimporter == NULL) { nout << "Failed to import _vfsimporter:\n"; PyErr_Print(); - return false; + return 1; } Py_DECREF(vfsimporter); @@ -197,7 +199,7 @@ run_python() { if (vfsimporter_module == NULL) { nout << "Failed to import VFSImporter:\n"; PyErr_Print(); - return false; + return 1; } // And register the VFSImporter. @@ -205,7 +207,7 @@ run_python() { if (result == NULL) { nout << "Failed to call VFSImporter.register():\n"; PyErr_Print(); - return false; + return 1; } Py_DECREF(result); Py_DECREF(vfsimporter_module); @@ -217,12 +219,12 @@ run_python() { PT(Multifile) mf = new Multifile; if (!mf->open_read(_archive_file)) { nout << "Could not read " << _archive_file << "\n"; - return false; + return 1; } VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr(); if (!vfs->mount(mf, dir, VirtualFileSystem::MF_read_only)) { nout << "Could not mount " << _archive_file << "\n"; - return false; + return 1; } // And finally, we can import the startup module. @@ -230,7 +232,7 @@ run_python() { if (app_runner_module == NULL) { nout << "Failed to import direct.p3d.AppRunner\n"; PyErr_Print(); - return false; + return 1; } // Get the pointers to the objects needed within the module. @@ -238,7 +240,7 @@ run_python() { if (app_runner_class == NULL) { nout << "Failed to get AppRunner class\n"; PyErr_Print(); - return false; + return 1; } // Construct an instance of AppRunner. @@ -246,7 +248,7 @@ run_python() { if (_runner == NULL) { nout << "Failed to construct AppRunner instance\n"; PyErr_Print(); - return false; + return 1; } Py_DECREF(app_runner_class); @@ -262,35 +264,35 @@ run_python() { _undefined_object_class = PyObject_GetAttrString(javascript_module, "UndefinedObject"); if (_undefined_object_class == NULL) { PyErr_Print(); - return false; + return 1; } // And the "Undefined" instance. _undefined = PyObject_GetAttrString(javascript_module, "Undefined"); if (_undefined == NULL) { PyErr_Print(); - return false; + return 1; } // Get the ConcreteStruct class. _concrete_struct_class = PyObject_GetAttrString(javascript_module, "ConcreteStruct"); if (_concrete_struct_class == NULL) { PyErr_Print(); - return false; + return 1; } // Get the BrowserObject class. _browser_object_class = PyObject_GetAttrString(javascript_module, "BrowserObject"); if (_browser_object_class == NULL) { PyErr_Print(); - return false; + return 1; } // Get the global TaskManager. _taskMgr = PyObject_GetAttrString(app_runner_module, "taskMgr"); if (_taskMgr == NULL) { PyErr_Print(); - return false; + return 1; } Py_DECREF(app_runner_module); @@ -320,12 +322,12 @@ run_python() { #endif if (p3dpython == NULL) { PyErr_Print(); - return false; + return 1; } PyObject *request_func = PyObject_GetAttrString(p3dpython, "request_func"); if (request_func == NULL) { PyErr_Print(); - return false; + return 1; } // Now pass that func pointer back to our AppRunner instance, so it @@ -333,7 +335,7 @@ run_python() { result = PyObject_CallMethod(_runner, (char *)"setRequestFunc", (char *)"N", request_func); if (result == NULL) { PyErr_Print(); - return false; + return 1; } Py_DECREF(result); @@ -353,7 +355,7 @@ run_python() { PyObject *check_comm = PyObject_GetAttrString(p3dpython, "check_comm"); if (check_comm == NULL) { PyErr_Print(); - return false; + return 1; } // Add it to the task manager. We do this instead of constructing a @@ -361,7 +363,7 @@ run_python() { result = PyObject_CallMethod(_taskMgr, (char *)"add", (char *)"Ns", check_comm, "check_comm"); if (result == NULL) { PyErr_Print(); - return false; + return 1; } Py_DECREF(result); @@ -369,18 +371,30 @@ run_python() { // taskMgr.run()). PyObject *done = PyObject_CallMethod(_runner, (char *)"run", (char *)""); if (done == NULL) { + int status = 1; + // An uncaught application exception, and not handled by - // appRunner.exceptionHandler. - PyErr_Print(); + // appRunner.exceptionHandler. If it is a SystemExit, extract + // the exit status that we should return. + if (PyErr_Occurred() == PyExc_SystemExit) { + PyObject *ptype, *ptraceback; + PySystemExitObject *value = NULL; + PyErr_Fetch(&ptype, (PyObject **)&value, &ptraceback); + if (value != NULL) { + status = (int)PyInt_AsLong(value->code); + } + } else { + PyErr_Print(); + } if (_interactive_console) { // Give an interactive user a chance to explore the exception. run_interactive_console(); - return true; + return 0; } // We're done. - return false; + return status; } // A normal exit from the taskManager. We're presumably done. @@ -390,7 +404,7 @@ run_python() { run_interactive_console(); } - return true; + return 0; } //////////////////////////////////////////////////////////////////// diff --git a/direct/src/plugin/p3dPythonRun.h b/direct/src/plugin/p3dPythonRun.h index 974b27684e..84188bdd2c 100644 --- a/direct/src/plugin/p3dPythonRun.h +++ b/direct/src/plugin/p3dPythonRun.h @@ -71,7 +71,7 @@ public: const char *log_pathname, bool interactive_console); ~P3DPythonRun(); - bool run_python(); + int run_python(); void set_window_open(P3DCInstance *inst, bool is_open); void request_keyboard_focus(P3DCInstance *inst); diff --git a/direct/src/plugin/p3dSession.cxx b/direct/src/plugin/p3dSession.cxx index 3e6189ce4d..da9b30874f 100644 --- a/direct/src/plugin/p3dSession.cxx +++ b/direct/src/plugin/p3dSession.cxx @@ -179,18 +179,27 @@ shutdown() { result = waitpid(_p3dpython_pid, &status, WNOHANG); } _p3dpython_pid = -1; - + nout << "Python process has successfully stopped.\n"; if (WIFEXITED(status)) { - nout << " exited normally, status = " - << WEXITSTATUS(status) << "\n"; + int code = WEXITSTATUS(status); + + nout << " exited normally, status = " << code << "\n"; + if (code != 0) { + _exit(code); + } + } else if (WIFSIGNALED(status)) { - nout << " signalled by " << WTERMSIG(status) << ", core = " + nout << " signalled by " << WTERMSIG(status) << ", core = " << WCOREDUMP(status) << "\n"; + + // This seems to be a popular shell convention. + _exit(128 + WTERMSIG(status)); + } else if (WIFSTOPPED(status)) { nout << " stopped by " << WSTOPSIG(status) << "\n"; } - + #endif // _WIN32 } @@ -928,7 +937,11 @@ start_p3dpython(P3DInstance *inst) { const char *varc = var.c_str(); bool found = false; for (int i = 0; dont_keep[i] != NULL && !found; ++i) { +#ifdef _WIN32 + found = (_stricmp(dont_keep[i], varc) == 0); +#else found = (strcmp(dont_keep[i], varc) == 0); +#endif } if (!found) { // This variable is OK, keep it. @@ -1704,15 +1717,24 @@ posix_create_process() { // its process. Report an error condition. nout << "Python process stopped immediately.\n"; if (WIFEXITED(status)) { - nout << " exited normally, status = " - << WEXITSTATUS(status) << "\n"; + int code = WEXITSTATUS(status); + + nout << " exited normally, status = " << code << "\n"; + if (code != 0) { + _exit(code); + } + } else if (WIFSIGNALED(status)) { - nout << " signalled by " << WTERMSIG(status) << ", core = " + nout << " signalled by " << WTERMSIG(status) << ", core = " << WCOREDUMP(status) << "\n"; + + // This seems to be a popular shell convention. + _exit(128 + WTERMSIG(status)); + } else if (WIFSTOPPED(status)) { nout << " stopped by " << WSTOPSIG(status) << "\n"; } - + return -1; } #endif // _WIN32 @@ -1794,10 +1816,12 @@ p3dpython_thread_run() { return; } - if (!run_p3dpython(libp3dpython.c_str(), _mf_filename.c_str(), - _input_handle, _output_handle, _log_pathname.c_str(), - _interactive_console)) { + int status = run_p3dpython(libp3dpython.c_str(), _mf_filename.c_str(), + _input_handle, _output_handle, _log_pathname.c_str(), + _interactive_console); + if (status != 0) { nout << "Failure on startup.\n"; + _exit(status); } } diff --git a/direct/src/plugin/run_p3dpython.cxx b/direct/src/plugin/run_p3dpython.cxx index e5db32d10e..5a7dc4c742 100644 --- a/direct/src/plugin/run_p3dpython.cxx +++ b/direct/src/plugin/run_p3dpython.cxx @@ -19,16 +19,17 @@ // Function: run_p3dpython // Description: This externally-visible function is the main entry // point to this DLL, and it starts the whole thing -// running. Returns true on success, false on failure. +// running. Returns the exit status, which will be +// 0 on success, 1 or otherwise on failure. //////////////////////////////////////////////////////////////////// -bool +int run_p3dpython(const char *program_name, const char *archive_file, - FHandle input_handle, FHandle output_handle, + FHandle input_handle, FHandle output_handle, const char *log_pathname, bool interactive_console) { - P3DPythonRun::_global_ptr = - new P3DPythonRun(program_name, archive_file, input_handle, output_handle, + P3DPythonRun::_global_ptr = + new P3DPythonRun(program_name, archive_file, input_handle, output_handle, log_pathname, interactive_console); - bool result = P3DPythonRun::_global_ptr->run_python(); + int result = P3DPythonRun::_global_ptr->run_python(); delete P3DPythonRun::_global_ptr; P3DPythonRun::_global_ptr = NULL; return result; diff --git a/direct/src/plugin/run_p3dpython.h b/direct/src/plugin/run_p3dpython.h index 21d5430f54..6b358b742b 100644 --- a/direct/src/plugin/run_p3dpython.h +++ b/direct/src/plugin/run_p3dpython.h @@ -26,14 +26,14 @@ #define EXPCL_P3DPYTHON #endif -typedef bool +typedef int run_p3dpython_func(const char *program_name, const char *archive_file, - FHandle input_handle, FHandle output_handle, + FHandle input_handle, FHandle output_handle, const char *log_pathname, bool interactive_console); -extern "C" EXPCL_P3DPYTHON bool +extern "C" EXPCL_P3DPYTHON int run_p3dpython(const char *program_name, const char *archive_file, - FHandle input_handle, FHandle output_handle, + FHandle input_handle, FHandle output_handle, const char *log_pathname, bool interactive_console); #endif diff --git a/direct/src/stdpy/file.py b/direct/src/stdpy/file.py index 25f5b6e1a1..a3e114738c 100644 --- a/direct/src/stdpy/file.py +++ b/direct/src/stdpy/file.py @@ -13,6 +13,7 @@ __all__ = [ from panda3d import core import sys import types +import os _vfs = core.VirtualFileSystem.getGlobalPtr() diff --git a/panda/src/pgraph/renderState.cxx b/panda/src/pgraph/renderState.cxx index 69a5f502f7..a3f4c6c9a7 100644 --- a/panda/src/pgraph/renderState.cxx +++ b/panda/src/pgraph/renderState.cxx @@ -330,6 +330,31 @@ make(const RenderAttrib *attrib1, return return_new(state); } +//////////////////////////////////////////////////////////////////// +// Function: RenderState::make +// Access: Published, Static +// Description: Returns a RenderState with five attributes set. +//////////////////////////////////////////////////////////////////// +CPT(RenderState) RenderState:: +make(const RenderAttrib *attrib1, + const RenderAttrib *attrib2, + const RenderAttrib *attrib3, + const RenderAttrib *attrib4, + const RenderAttrib *attrib5, int override) { + RenderState *state = new RenderState; + state->_attributes[attrib1->get_slot()].set(attrib1, override); + state->_attributes[attrib2->get_slot()].set(attrib2, override); + state->_attributes[attrib3->get_slot()].set(attrib3, override); + state->_attributes[attrib4->get_slot()].set(attrib4, override); + state->_attributes[attrib5->get_slot()].set(attrib5, override); + state->_filled_slots.set_bit(attrib1->get_slot()); + state->_filled_slots.set_bit(attrib2->get_slot()); + state->_filled_slots.set_bit(attrib3->get_slot()); + state->_filled_slots.set_bit(attrib4->get_slot()); + state->_filled_slots.set_bit(attrib5->get_slot()); + return return_new(state); +} + //////////////////////////////////////////////////////////////////// // Function: RenderState::make // Access: Published, Static diff --git a/panda/src/pgraph/renderState.h b/panda/src/pgraph/renderState.h index bd97d7594e..a6c6896ee9 100644 --- a/panda/src/pgraph/renderState.h +++ b/panda/src/pgraph/renderState.h @@ -87,6 +87,11 @@ PUBLISHED: const RenderAttrib *attrib2, const RenderAttrib *attrib3, const RenderAttrib *attrib4, int override = 0); + static CPT(RenderState) make(const RenderAttrib *attrib1, + const RenderAttrib *attrib2, + const RenderAttrib *attrib3, + const RenderAttrib *attrib4, + const RenderAttrib *attrib5, int override = 0); static CPT(RenderState) make(const RenderAttrib * const *attrib, int num_attribs, int override = 0); diff --git a/panda/src/rocket/rocketRenderInterface.cxx b/panda/src/rocket/rocketRenderInterface.cxx index c3d7af2ffa..90304cda3b 100644 --- a/panda/src/rocket/rocketRenderInterface.cxx +++ b/panda/src/rocket/rocketRenderInterface.cxx @@ -20,6 +20,7 @@ #include "internalName.h" #include "geomVertexWriter.h" #include "geomTriangles.h" +#include "colorAttrib.h" #include "colorBlendAttrib.h" #include "cullBinAttrib.h" #include "depthTestAttrib.h" @@ -49,7 +50,8 @@ render(Rocket::Core::Context* context, CullTraverser *trav) { ColorBlendAttrib::make(ColorBlendAttrib::M_add, ColorBlendAttrib::O_incoming_alpha, ColorBlendAttrib::O_one_minus_incoming_alpha - ) + ), + ColorAttrib::make_vertex() ); _dimensions = context->GetDimensions(); diff --git a/panda/src/tinydisplay/clip.cxx b/panda/src/tinydisplay/clip.cxx index ca1f7930d7..da20a86adc 100644 --- a/panda/src/tinydisplay/clip.cxx +++ b/panda/src/tinydisplay/clip.cxx @@ -42,15 +42,15 @@ void gl_transform_to_viewport(GLContext *c,GLVertex *v) } /* color */ - v->zp.r=(int)(v->color.v[0] * (ZB_POINT_RED_MAX - ZB_POINT_RED_MIN) - + ZB_POINT_RED_MIN); - v->zp.g=(int)(v->color.v[1] * (ZB_POINT_GREEN_MAX - ZB_POINT_GREEN_MIN) - + ZB_POINT_GREEN_MIN); - v->zp.b=(int)(v->color.v[2] * (ZB_POINT_BLUE_MAX - ZB_POINT_BLUE_MIN) - + ZB_POINT_BLUE_MIN); - v->zp.a=(int)(v->color.v[3] * (ZB_POINT_ALPHA_MAX - ZB_POINT_ALPHA_MIN) - + ZB_POINT_ALPHA_MIN); - + v->zp.r=min((int)(v->color.v[0] * (ZB_POINT_RED_MAX - ZB_POINT_RED_MIN)) + + ZB_POINT_RED_MIN, ZB_POINT_RED_MAX); + v->zp.g=min((int)(v->color.v[1] * (ZB_POINT_GREEN_MAX - ZB_POINT_GREEN_MIN)) + + ZB_POINT_GREEN_MIN, ZB_POINT_GREEN_MAX); + v->zp.b=min((int)(v->color.v[2] * (ZB_POINT_BLUE_MAX - ZB_POINT_BLUE_MIN)) + + ZB_POINT_BLUE_MIN, ZB_POINT_BLUE_MAX); + v->zp.a=min((int)(v->color.v[3] * (ZB_POINT_ALPHA_MAX - ZB_POINT_ALPHA_MIN)) + + ZB_POINT_ALPHA_MIN, ZB_POINT_ALPHA_MAX); + /* texture */ if (c->num_textures_enabled >= 1) { static const int si = 0; diff --git a/panda/src/tinydisplay/tinyGraphicsStateGuardian.cxx b/panda/src/tinydisplay/tinyGraphicsStateGuardian.cxx index e477deae9c..b9efe215c5 100644 --- a/panda/src/tinydisplay/tinyGraphicsStateGuardian.cxx +++ b/panda/src/tinydisplay/tinyGraphicsStateGuardian.cxx @@ -234,6 +234,7 @@ clear(DrawableRegion *clearable) { PIXEL color = 0; if (clearable->get_clear_color_active()) { LColor v = clearable->get_clear_color(); + v = v.fmin(LColor(1, 1, 1, 1)).fmax(LColor::zero()); if (_current_properties->get_srgb_color()) { color = SRGBA_TO_PIXEL( @@ -697,10 +698,10 @@ begin_draw_primitives(const GeomPipelineReader *geom_reader, if (!needs_color) { const LColor &d = _scene_graph_color; const LColor &s = _current_color_scale; - _c->current_color.v[0] = d[0] * s[0]; - _c->current_color.v[1] = d[1] * s[1]; - _c->current_color.v[2] = d[2] * s[2]; - _c->current_color.v[3] = d[3] * s[3]; + _c->current_color.v[0] = max(d[0] * s[0], (PN_stdfloat)0); + _c->current_color.v[1] = max(d[1] * s[1], (PN_stdfloat)0); + _c->current_color.v[2] = max(d[2] * s[2], (PN_stdfloat)0); + _c->current_color.v[3] = max(d[3] * s[3], (PN_stdfloat)0); } bool needs_normal = false; @@ -756,10 +757,10 @@ begin_draw_primitives(const GeomPipelineReader *geom_reader, if (needs_color) { const LColor &d = rcolor.get_data4(); const LColor &s = _current_color_scale; - _c->current_color.v[0] = d[0] * s[0]; - _c->current_color.v[1] = d[1] * s[1]; - _c->current_color.v[2] = d[2] * s[2]; - _c->current_color.v[3] = d[3] * s[3]; + _c->current_color.v[0] = max(d[0] * s[0], (PN_stdfloat)0); + _c->current_color.v[1] = max(d[1] * s[1], (PN_stdfloat)0); + _c->current_color.v[2] = max(d[2] * s[2], (PN_stdfloat)0); + _c->current_color.v[3] = max(d[3] * s[3], (PN_stdfloat)0); if (_color_material_flags) { if (_color_material_flags & CMF_ambient) { @@ -1414,6 +1415,7 @@ framebuffer_copy_to_texture(Texture *tex, int view, int z, return false; } LColor border_color = tex->get_border_color(); + border_color = border_color.fmin(LColor(1, 1, 1, 1)).fmax(LColor::zero()); gltex->border_color.v[0] = border_color[0]; gltex->border_color.v[1] = border_color[1]; gltex->border_color.v[2] = border_color[2]; @@ -2565,6 +2567,7 @@ upload_texture(TinyTextureContext *gtc, bool force, bool uses_mipmaps) { return false; } LColor border_color = tex->get_border_color(); + border_color = border_color.fmin(LColor(1, 1, 1, 1)).fmax(LColor::zero()); gltex->border_color.v[0] = border_color[0]; gltex->border_color.v[1] = border_color[1]; gltex->border_color.v[2] = border_color[2]; @@ -2681,6 +2684,7 @@ upload_simple_texture(TinyTextureContext *gtc) { return false; } LColor border_color = tex->get_border_color(); + border_color = border_color.fmin(LColor(1, 1, 1, 1)).fmax(LColor::zero()); gltex->border_color.v[0] = border_color[0]; gltex->border_color.v[1] = border_color[1]; gltex->border_color.v[2] = border_color[2]; diff --git a/panda/src/x11display/x11GraphicsWindow.cxx b/panda/src/x11display/x11GraphicsWindow.cxx index c7fd0eef61..e9141edfa4 100644 --- a/panda/src/x11display/x11GraphicsWindow.cxx +++ b/panda/src/x11display/x11GraphicsWindow.cxx @@ -515,8 +515,8 @@ set_properties_now(WindowProperties &properties) { XRRScreenSize *xrrs; xrrs = XRRSizes(_display, 0, &num_sizes); for (int i = 0; i < num_sizes; ++i) { - if (xrrs[i].width == properties.get_x_size() && - xrrs[i].height == properties.get_y_size()) { + if (xrrs[i].width == reqsizex && + xrrs[i].height == reqsizey) { new_size_id = i; } }