void PartSysParser::ParseEmitter(const TabFileRecord& record) { auto systemName = record[COL_PARTSYS_NAME].AsString(); auto& system = mSpecs[tolower(systemName)]; // Create it on demand if (!system) { system = std::make_shared<PartSysSpec>(systemName); } // Add the emitter auto emitter = system->CreateEmitter(record[COL_EMITTER_NAME].AsString()); ParseOptionalFloat(record, COL_DELAY, "Delay", [&] (float value) { emitter->SetDelay(value / 30.0f); }); ParseLifespan(record, emitter); ParseParticleLifespan(record, emitter); ParseParticleRate(record, emitter); ParseOptionalEnum<PartSysEmitterSpace>(record, COL_EMITTER_SPACE, "emitter space", EmitterSpaceMapping, [&](auto space) { emitter->SetSpace(space); }); ParseEmitterNodeName(record, emitter); ParseOptionalEnum<PartSysCoordSys>(record, COL_EMITTER_COORD_SYS, "emitter coord sys", CoordSysMapping, [&](auto coordSys) { emitter->SetCoordSys(coordSys); }); ParseOptionalEnum<PartSysCoordSys>(record, COL_EMITTER_OFFSET_COORD_SYS, "emitter offset coord sys", CoordSysMapping, [&](auto coordSys) { emitter->SetOffsetCoordSys(coordSys); }); ParseOptionalEnum<PartSysParticleType>(record, COL_PARTICLE_TYPE, "particle type", ParticleTypeMapping, [&](PartSysParticleType type) { emitter->SetParticleType(type); }); ParseOptionalEnum<PartSysBlendMode>(record, COL_BLEND_MODE, "blend mode", BlendModeMapping, [&](auto mode) { emitter->SetBlendMode(mode); }); ParseMaterial(record, emitter); ParseOptionalEnum<PartSysCoordSys>(record, COL_PARTICLE_POS_COORD_SYS, "particle pos coord sys", CoordSysMapping, [&](auto coordSys) { emitter->SetParticlePosCoordSys(coordSys); }); ParseOptionalEnum<PartSysCoordSys>(record, COL_PARTICLE_VELOCITY_COORD_SYS, "particle velocity coord sys", CoordSysMapping, [&](auto coordSys) { emitter->SetParticleVelocityCoordSys(coordSys); }); ParseOptionalEnum<PartSysParticleSpace>(record, COL_PARTICLE_SPACE, "particle space", ParticleSpaceMapping, [&](auto space) { emitter->SetParticleSpace(space); }); ParseMesh(record, emitter); // Parse the bounding box ParseOptionalFloat(record, COL_BB_LEFT, "bb left", [&](float val) { emitter->SetBoxLeft(val); }); ParseOptionalFloat(record, COL_BB_TOP, "bb top", [&](float val) { emitter->SetBoxTop(val); }); ParseOptionalFloat(record, COL_BB_RIGHT, "bb right", [&](float val) { emitter->SetBoxRight(val); }); ParseOptionalFloat(record, COL_BB_BOTTOM, "bb bottom", [&](float val) { emitter->SetBoxBottom(val); }); for (int paramId = 0; paramId <= part_attractorBlend; paramId++) { int colIdx = 22 + paramId; auto col = record[colIdx]; if (col) { bool success; std::unique_ptr<PartSysParam> param(ParserParams::Parse((PartSysParamId) paramId, col, emitter->GetLifespan(), emitter->GetParticleLifespan(), success)); if (success) { emitter->SetParam((PartSysParamId)paramId, param); } else { logger->warn("Unable to parse particle system param {} for particle system {} and emitter {} with value {}", paramId, systemName, emitter->GetName(), col.AsString()); } } } }
void NWindowScreen::ScreenConnected(bool connected) { PRINT(("ScreenConnected()\n")); fflush(stdout); if(connected) { if(SetSpace(B_8_BIT_640x480) < B_OK) { //SetFrameBuffer(640, 480); PRINT(("SetSpace() failed\n")); // properly set the framebuffer. exit if an error occurs. be_app->PostMessage(B_QUIT_REQUESTED); return; } // get the framebuffer-related info, each time the // WindowScreen is connected (multiple monitor) frame_buffer = (uint8*)(CardInfo()->frame_buffer); line_length = FrameBufferInfo()->bytes_per_row; if(tid == 0) { // clean the framebuffer PRINT(("zeroing the framebuffer\n")); memset(frame_buffer,0,480*line_length); // spawn the rendering thread. exit if an error occurs. PRINT(("spawning the render thread.\n")); tid = spawn_thread(Entry,"rendering thread", B_URGENT_DISPLAY_PRIORITY,this); if(resume_thread(tid) < B_OK) { be_app->PostMessage(B_QUIT_REQUESTED); return; } } else { for(int y=0;y<480;y++) { // restore the framebuffer when switching back from // another workspace. memcpy(frame_buffer+y*line_length,save_buffer+640*y,640); } } // set our color list. rgb_color palette[256]; rgb_color c1; for(int i=0,j=0;i<256;i++,j++) { if(i<64) { c1.red = j*4; // greys c1.green = j*4; c1.blue = j*4; c1.alpha = 255; } if((i>=64) && (i<128)) { c1.red = j*4; // reds c1.green = 0; c1.blue = 0; c1.alpha = 255; } if((i>=128) && (i<192)) { c1.red = 0; // greens c1.green = j*4; c1.blue = 0; c1.alpha = 255; } if((i>=192) && (i<256)) { c1.red = 0; // blues c1.green = 0; c1.blue = j*4; c1.alpha = 255; } if(j == 64) j=0; palette[i]=c1; } SetColorList(palette); // allow the rendering thread to run. thread_is_locked = false; release_sem(sem); } else /* !connected */ { // block the rendering thread. if(!thread_is_locked) { acquire_sem(sem); thread_is_locked = true; } // kill the rendering and clean up when quitting if((((NApplication*)be_app)->is_quitting)) { status_t ret; kill_thread(tid); wait_for_thread(tid,&ret); delete_sem(sem); delete_area(area); free(particle_list); } else { // set the color list black so that the screen doesn't seem // to freeze while saving the framebuffer rgb_color c={0,0,0,255}; rgb_color palette[256]; // build the palette for(int i=0;i<256;i++) palette[i] = c; // set the palette SetColorList(palette); // save the framebuffer for(int y=0;y<480;y++) memcpy(save_buffer+640*y,frame_buffer+y*line_length,640); } } }