diff --git a/src/XPMPMultiplayerCSL.cpp b/src/XPMPMultiplayerCSL.cpp index 11a6775eb..8dd88216b 100644 --- a/src/XPMPMultiplayerCSL.cpp +++ b/src/XPMPMultiplayerCSL.cpp @@ -326,6 +326,10 @@ bool LoadOnePackage(const string& inPath, int pass) BreakStringPvt(line, tokens, 4, " \t\r\n"); + //---------------------------------------------------------------------------------------------------- + // PACKAGE MANAGEMENT + //---------------------------------------------------------------------------------------------------- + // EXPORT_NAME if (!tokens.empty() && tokens[0] == "EXPORT_NAME" && pass == pass_Depend) { @@ -362,6 +366,9 @@ bool LoadOnePackage(const string& inPath, int pass) } } + //---------------------------------------------------------------------------------------------------- + // AUSTIN OLD SCHOOL ACFS + //---------------------------------------------------------------------------------------------------- // AIRCAFT if (!tokens.empty() && tokens[0] == "AIRCRAFT" && pass == pass_Load) @@ -395,6 +402,10 @@ bool LoadOnePackage(const string& inPath, int pass) XPLMDump(path, lineNum, line) << "XSB WARNING: AIRCRAFT command takes 3 arguments.\n"; } } + + //---------------------------------------------------------------------------------------------------- + // OBJ7 DRAWN WITH OUR CODE + //---------------------------------------------------------------------------------------------------- // OBJECT if (!tokens.empty() && tokens[0] == "OBJECT" && pass == pass_Load) @@ -432,7 +443,6 @@ bool LoadOnePackage(const string& inPath, int pass) } } - // TEXTURE if (!tokens.empty() && tokens[0] == "TEXTURE" && pass == pass_Load) { @@ -466,6 +476,109 @@ bool LoadOnePackage(const string& inPath, int pass) } } } + + //---------------------------------------------------------------------------------------------------- + // OBJ8 MULTI-OBJ WITH SIM RENDERING + //---------------------------------------------------------------------------------------------------- + + // OBJ8_AIRCRAFT + if (!tokens.empty() && tokens[0] == "OBJ8_AIRCRAFT" && pass == pass_Load) + { + BreakStringPvt(line, tokens, 2, " \t\r\n"); + + if(tokens.size() == 2) + { + pckg->planes.push_back(CSLPlane_t()); + pckg->planes.back().plane_type = plane_Obj8; + pckg->planes.back().file_path = tokens[1]; // debug str + pckg->planes.back().moving_gear = true; + pckg->planes.back().texID = 0; + pckg->planes.back().texLitID = 0; + pckg->planes.back().obj_idx = -1; + } + else + { + parse_err = true; + XPLMDump(path, lineNum, line) << "XSB WARNING: OBJ8_AIRCARFT command takes 1 argument.\n"; + } + } + + // OBJ8 + if (!tokens.empty() && tokens[0] == "OBJ8" && pass == pass_Load) + { + BreakStringPvt(line, tokens, 4, " \t\r\n"); + + if(tokens.size() == 4) + { + if(pckg->planes.empty() || pckg->planes.back().plane_type != plane_Obj8) + { + // err - obj8 record at stupid place in file + } + else + { + + obj_for_acf att; + + if(tokens[1] == "GLASS") + att.draw_type = draw_glass; + else if(tokens[1] == "LIGHTS") + att.draw_type = draw_lights; + else if(tokens[1] == "LOW_LOD") + att.draw_type = draw_low_lod; + else if(tokens[1] == "SOLID") + att.draw_type = draw_solid; + else { + // err crap enum + } + + if(tokens[2] == "YES") + att.needs_animation = true; + else if(tokens[2] == "NO") + att.needs_animation = false; + else + { + // crap flag + } + std::string fullPath = tokens[3]; + + MakePartialPathNativeObj(fullPath); + if (!DoPackageSub(fullPath)) + { + XPLMDump(path, lineNum, line) << "XSB WARNING: package not found.\n"; + parse_err = true; + } + + char xsystem[1024]; + XPLMGetSystemPath(xsystem); + + #if APL + HFS2PosixPath(xsystem, xsystem, 1024); + #endif + + int sys_len = strlen(xsystem); + if(fullPath.size() > sys_len) + fullPath.erase(fullPath.begin(),fullPath.begin() + sys_len); + else + { + // should probaby freak out here. + } + + att.handle = NULL; + att.file = fullPath; + + pckg->planes.back().attachments.push_back(att); + } + } + else + { + // err - f---ed line. + } + } + + //---------------------------------------------------------------------------------------------------- + // MATCHING CRAP AND OTHER COMMON META-DATA + //---------------------------------------------------------------------------------------------------- + // HASGEAR YES|NO // This line specifies whether the previous plane has retractable gear. @@ -487,7 +600,7 @@ bool LoadOnePackage(const string& inPath, int pass) } } } - + // ICAO // This line maps one ICAO code to the previous airline, without // specifying an airline or livery. @@ -978,7 +1091,7 @@ void CSL_DrawObject( XPLMPlaneDrawState_t * state) { // Setup OpenGL for this plane render - if(type < plane_Count) + if(type != plane_Obj8) { glMatrixMode(GL_MODELVIEW); glPushMatrix(); @@ -1012,7 +1125,21 @@ void CSL_DrawObject( x, y ,z, pitch, roll, heading, lights); break; + case plane_Obj8: + obj_schedule_one_aircraft( + model, + x, + y, + z, + pitch, + roll, + heading, + full, // + lights, + state); + break; } - glPopMatrix(); + if(type != plane_Obj8) + glPopMatrix(); } diff --git a/src/XPMPMultiplayerObj8.cpp b/src/XPMPMultiplayerObj8.cpp new file mode 100644 index 000000000..af5405781 --- /dev/null +++ b/src/XPMPMultiplayerObj8.cpp @@ -0,0 +1,156 @@ +/* + * Copyright (c) 2013, Laminar Research. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#include "XPMPMultiplayerObj8.h" +#include "XPMPMultiplayerVars.h" +#include "XPLMScenery.h" +#include +#include +using namespace std; + +#define WANT_ASYNC 1 + + +struct one_inst { + one_inst * next; + + XPLMDrawInfo_t location; + xpmp_LightStatus lights; + XPLMPlaneDrawState_t * state; + + ~one_inst() { delete next; } +}; + +struct one_obj { + one_obj * next; + obj_for_acf * model; + one_inst * head; + + ~one_obj() { delete head; delete next; } +}; + +static one_obj * s_worklist = NULL; + + +static void draw_objects_for_mode(one_obj * who, int want_translucent) +{ + while(who) + { + obj_draw_type dt = who->model->draw_type; + if((want_translucent && dt == draw_glass) || + (!want_translucent && dt != draw_glass)) + { + for(one_inst * i = who->head; i; i = i->next) + { + // set dataref ptr to light + obj sate from "one_inst". + XPLMDrawObjects(who->model->handle, 1, &i->location, 1, 0); + } + } + who = who->next; + } +} + +void obj_loaded_cb(XPLMObjectRef obj, void * refcon) +{ + XPLMObjectRef * targ = (XPLMObjectRef *) refcon; + *targ = obj; +} + + +void obj_schedule_one_aircraft( + CSLPlane_t * model, + double x, + double y, + double z, + double pitch, + double roll, + double heading, + int full, // + xpmp_LightStatus lights, + XPLMPlaneDrawState_t * state) +{ + one_obj * iter; + + for(vector::iterator att = model->attachments.begin(); att != model->attachments.end(); ++att) + { + obj_for_acf * model = &*att; + + if(model->handle == NULL && + !model->file.empty()) + { + #if WANT_ASYNC + XPLMLoadObjectAsync(model->file.c_str(),obj_loaded_cb,(void *) &model->handle); + #else + model->handle = XPLMLoadObject(model->file.c_str()); + #endif + model->file.clear(); + } + + + for(iter = s_worklist; iter; iter = iter->next) + { + if(iter->model == model) + break; + } + if(iter == NULL) + { + iter = new one_obj; + iter->next = s_worklist; + s_worklist = iter; + iter->model = model; + iter->head = NULL; + } + + if(iter->model->handle) + { + one_inst * i = new one_inst; + i->next = iter->head; + iter->head = i; + i->lights = lights; + i->state = state; + i->location.structSize = sizeof(i->location); + i->location.x = x; + i->location.y = y; + i->location.z = z; + i->location.pitch = pitch; + i->location.roll = roll; + i->location.heading = heading; + } + } +} + +void obj_draw_solid() +{ + draw_objects_for_mode(s_worklist, false); +} + +void obj_draw_translucent() +{ + draw_objects_for_mode(s_worklist, true);\ +} + +void obj_draw_done() +{ + delete s_worklist; + s_worklist = NULL; +} diff --git a/src/XPMPMultiplayerObj8.h b/src/XPMPMultiplayerObj8.h new file mode 100644 index 000000000..7ee04519e --- /dev/null +++ b/src/XPMPMultiplayerObj8.h @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2013, Laminar Research. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#ifndef XPMPMultiplayerObj8_h +#define XPMPMultiplayerObj8_h + +#include "XPLMScenery.h" +#include "XPLMPlanes.h" +#include "XPMPMultiplayer.h" +#include + +/* + + OBJ8_AIRCRAFT + OBJ8 LOW_LOD NO foo.obj + OBJ8 GLASS YES bar.obj + AIRLINE DAL + ICAO B732 B733 + + */ + +enum obj_draw_type { + + draw_lights = 0, + draw_low_lod, + draw_solid, + draw_glass + +}; + +struct obj_for_acf { + + std::string file; + XPLMObjectRef handle; + obj_draw_type draw_type; + bool needs_animation; + +}; + +struct CSLPlane_t; + +bool obj_load_one_attached_obj( + const char * file_name, + bool needs_anim, + obj_draw_type draw_type, + obj_for_acf& out_attachment); + +///// + + +void obj_schedule_one_aircraft( + CSLPlane_t * model, + double x, + double y, + double z, + double pitch, + double roll, + double heading, + int full, // + xpmp_LightStatus lights, + XPLMPlaneDrawState_t * state); + + +void obj_draw_solid(); +void obj_draw_translucent(); +void obj_draw_done(); + + + + +#endif \ No newline at end of file diff --git a/src/XPMPMultiplayerVars.h b/src/XPMPMultiplayerVars.h index dbc825e25..a7ca3c482 100644 --- a/src/XPMPMultiplayerVars.h +++ b/src/XPMPMultiplayerVars.h @@ -40,6 +40,7 @@ using namespace std; #include "XPMPMultiplayer.h" +#include "XPMPMultiplayerObj8.h" // for obj8 attachment info template inline @@ -68,6 +69,7 @@ enum { plane_Austin, plane_Obj, plane_Lights, + plane_Obj8, plane_Count }; @@ -76,16 +78,20 @@ enum { // and then implementation-specifc stuff. struct CSLPlane_t { int plane_type; // What kind are we? - string file_path; // Where do we load from + string file_path; // Where do we load from (oz and obj, debug-use-only for OBJ8) bool moving_gear; // Does gear retract? + // plane_Austin int austin_idx; + // plane_Obj int obj_idx; - // Optional Texture - int texID; - // Optional Lit Texture - int texLitID; + int texID; // can be 0 for no customization + int texLitID; // can be 0 for no customization + + // plane_Obj8 + vector attachments; + }; // These enums define the six levels of matching we might possibly diff --git a/src/XPMPPlaneRenderer.cpp b/src/XPMPPlaneRenderer.cpp index e90c994cb..d1b481a93 100644 --- a/src/XPMPPlaneRenderer.cpp +++ b/src/XPMPPlaneRenderer.cpp @@ -454,6 +454,7 @@ void XPMPDefaultPlaneRenderer(void) vector planes_obj_lites; multimap planes_austin; multimap planes_obj; + vector planes_obj8; vector::iterator planeIter; multimap::iterator planeMapIter; @@ -490,6 +491,10 @@ void XPMPDefaultPlaneRenderer(void) planes_obj.insert(multimap::value_type(CSL_GetOGLIndex(iter->second.model), &iter->second)); planes_obj_lites.push_back(&iter->second); } + else if(iter->second.model->plane_type == plane_Obj8) + { + planes_obj8.push_back(&iter->second); + } } else { // If it's time to draw austin's planes but this one @@ -568,6 +573,24 @@ void XPMPDefaultPlaneRenderer(void) ++gOBJPlanes; } + for(planeIter = planes_obj8.begin(); planeIter != planes_obj8.end(); ++planeIter) + { + CSL_DrawObject( (*planeIter)->model, + (*planeIter)->dist, + (*planeIter)->x, + (*planeIter)->y, + (*planeIter)->z, + (*planeIter)->pitch, + (*planeIter)->roll, + (*planeIter)->heading, + plane_Obj8, + (*planeIter)->full ? 1 : 0, + (*planeIter)->lights, + &(*planeIter)->state); + } + + obj_draw_solid(); + // PASS 3 - draw OBJ lights. if (!planes_obj_lites.empty()) @@ -591,6 +614,9 @@ void XPMPDefaultPlaneRenderer(void) } } + obj_draw_translucent(); + obj_draw_done(); + // PASS 4 - Labels if ( gDrawLabels ) {