Ejemplo n.º 1
0
SORE_Graphics::render_list& SORE_Graphics::RenderPipe::beginRender
(
    const camera_table& cameras,
    Renderbuffer_map_t& renderBuffers,
    render_list& list,
    GLCommandList& renderQueue,
    BufferManager* bm
)
{
    PROFILE_BLOCK("Render pipe", profiler);

    if(cameras.find(camera) == cameras.end())
    {
        // TODO: FIXME: sore exceptions
        throw std::runtime_error("Could not find named camera " + camera);
    }

    const camera_info& cam = cameras.find(camera)->second;

    BOOST_FOREACH(const Renderable& r, list)
    {
        SORE_Graphics::geometry_entry ge;
        {
            PROFILE_BLOCK("Look up GC", profiler);
            ge = bm->LookupGC(r.GetGeometryChunk());
        }
        {
            PROFILE_BLOCK("Add renderables", profiler);
            renderQueue.AddRenderable(r, ge, cam);
        }
    }
Ejemplo n.º 2
0
void
offset(const Slic3r::Polygons &polygons, ClipperLib::Paths* retval, const float delta,
    ClipperLib::JoinType joinType, double miterLimit)
{
    PROFILE_FUNC();
    // read input
    ClipperLib::Paths input;
    Slic3rMultiPoints_to_ClipperPaths(polygons, &input);
    
    // scale input
    scaleClipperPolygons(input);
    
    // perform offset
    ClipperLib::ClipperOffset co;
    if (joinType == jtRound) {
        co.ArcTolerance = miterLimit * double(CLIPPER_OFFSET_SCALE);
    } else {
        co.MiterLimit = miterLimit;
    }
    {
        PROFILE_BLOCK(offset_AddPaths);
        co.AddPaths(input, joinType, ClipperLib::etClosedPolygon);
    }
    {
        PROFILE_BLOCK(offset_Execute);
        co.Execute(*retval, delta * float(CLIPPER_OFFSET_SCALE));
    }
    
    // unscale output
    unscaleClipperPolygons(*retval);
}
Ejemplo n.º 3
0
void _clipper_do(const ClipperLib::ClipType clipType, const Slic3r::Polylines &subject, 
    const Slic3r::Polygons &clip, ClipperLib::PolyTree* retval, const ClipperLib::PolyFillType fillType,
    const bool safety_offset_)
{
    PROFILE_BLOCK(_clipper_do_polylines);

    // read input
    ClipperLib::Paths input_subject, input_clip;
    Slic3rMultiPoints_to_ClipperPaths(subject, &input_subject);
    Slic3rMultiPoints_to_ClipperPaths(clip,    &input_clip);
    
    // perform safety offset
    if (safety_offset_) safety_offset(&input_clip);
    
    // init Clipper
    ClipperLib::Clipper clipper;
    clipper.Clear();
    
    // add polygons
    {
        PROFILE_BLOCK(_clipper_do_polylines_AddPaths);
        clipper.AddPaths(input_subject, ClipperLib::ptSubject, false);
        clipper.AddPaths(input_clip,    ClipperLib::ptClip,    true);
    }
    
    // perform operation
    {
        PROFILE_BLOCK(_clipper_do_polylines_Execute);
        clipper.Execute(clipType, *retval, fillType, fillType);
    }
}
Ejemplo n.º 4
0
void safety_offset(ClipperLib::Paths* paths)
{
    PROFILE_FUNC();

    // scale input
    scaleClipperPolygons(*paths);
    
    // perform offset (delta = scale 1e-05)
    ClipperLib::ClipperOffset co;
#ifdef CLIPPER_UTILS_DEBUG
	if (clipper_export_enabled) {
		static int iRun = 0;
		export_clipper_input_polygons_bin(debug_out_path("safety_offset-polygons-%d", ++iRun).c_str(), *paths, ClipperLib::Paths());
	}
#endif /* CLIPPER_UTILS_DEBUG */
    ClipperLib::Paths out;
    for (size_t i = 0; i < paths->size(); ++ i) {
        ClipperLib::Path &path = (*paths)[i];
		co.Clear();
        co.MiterLimit = 2;
        bool ccw = ClipperLib::Orientation(path);
        if (! ccw)
            std::reverse(path.begin(), path.end());
        {
            PROFILE_BLOCK(safety_offset_AddPaths);
            co.AddPath((*paths)[i], ClipperLib::jtMiter, ClipperLib::etClosedPolygon);
        }
        {
            PROFILE_BLOCK(safety_offset_Execute);
            // offset outside by 10um
            ClipperLib::Paths out_this;
            co.Execute(out_this, ccw ? 10.f * float(CLIPPER_OFFSET_SCALE) : -10.f * float(CLIPPER_OFFSET_SCALE));
            if (! ccw) {
                // Reverse the resulting contours once again.
                for (ClipperLib::Paths::iterator it = out_this.begin(); it != out_this.end(); ++ it)
                    std::reverse(it->begin(), it->end());
            }
            if (out.empty())
                out = std::move(out_this);
            else
                std::move(std::begin(out_this), std::end(out_this), std::back_inserter(out));
        }
    }
    *paths = std::move(out);
    
    // unscale output
    unscaleClipperPolygons(*paths);
}
Ejemplo n.º 5
0
void rebuild_chunks(App *app) {
  PROFILE_BLOCK("Unload Chunk", app->chunk_cache_count);
  for (u32 i=0; i<app->chunk_cache_count; i++) {
    TerrainChunk *chunk = app->chunk_cache + i;
    unload_chunk(chunk);
  }
}
Ejemplo n.º 6
0
int FileSystemWatcherTask::task()
{
	m_handle = CreateFile(m_path,
		FILE_LIST_DIRECTORY,
		FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
		nullptr,
		OPEN_EXISTING,
		FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED,
		nullptr);
	if (m_handle == INVALID_HANDLE_VALUE) return -1;

	Lumix::setMemory(&m_overlapped, 0, sizeof(m_overlapped));
	m_overlapped.hEvent = this;
	m_finished = false;
	while (!m_finished)
	{
		PROFILE_BLOCK("Change handling");
		BOOL status = ReadDirectoryChangesW(m_handle,
			m_info,
			sizeof(m_info),
			TRUE,
			READ_DIR_CHANGE_FILTER,
			&m_received,
			&m_overlapped,
			&notif);
		if (status == FALSE) break;
		SleepEx(INFINITE, TRUE);
	}
	return 0;
}
Ejemplo n.º 7
0
	void handleEvents()
	{
		PROFILE_FUNCTION();
		{
			PROFILE_BLOCK("qt::processEvents");
			m_qt_app->processEvents();
		}
	}
Ejemplo n.º 8
0
void _clipper_do(const ClipperLib::ClipType clipType, const Slic3r::Polygons &subject, 
    const Slic3r::Polygons &clip, T* retval, const ClipperLib::PolyFillType fillType, const bool safety_offset_)
{
    PROFILE_BLOCK(_clipper_do_polygons);

    // read input
    ClipperLib::Paths input_subject, input_clip;
    Slic3rMultiPoints_to_ClipperPaths(subject, &input_subject);
    Slic3rMultiPoints_to_ClipperPaths(clip,    &input_clip);
    
    // perform safety offset
    if (safety_offset_) {
        if (clipType == ClipperLib::ctUnion) {
            safety_offset(&input_subject);
        } else {
            safety_offset(&input_clip);
        }
    }
    
    // init Clipper
    ClipperLib::Clipper clipper;
    clipper.Clear();
    
    // add polygons
    {
        PROFILE_BLOCK(_clipper_do_polygons_AddPaths);
        clipper.AddPaths(input_subject, ClipperLib::ptSubject, true);
        clipper.AddPaths(input_clip, ClipperLib::ptClip, true);

#ifdef CLIPPER_UTILS_DEBUG
        if (clipper_export_enabled) {
            static int iRun = 0;
			export_clipper_input_polygons_bin(debug_out_path("_clipper_do_polygons_AddPaths-polygons-%d", ++iRun).c_str(), input_subject, input_clip);
        }
#endif /* CLIPPER_UTILS_DEBUG */
    }
    
    // perform operation
    { 
        PROFILE_BLOCK(_clipper_do_polygons_Execute);
        clipper.Execute(clipType, *retval, fillType, fillType);
    }
}
Ejemplo n.º 9
0
int Scheduler::task()
{
	while (!isForceExit())
	{
		m_data_event.wait();

		PROFILE_BLOCK("Schedule")
		m_manager.doScheduling();
	}

	return 0;
}
Ejemplo n.º 10
0
	void frame()
	{
		float frame_time = m_frame_timer->tick();
		m_engine->update(*m_universe);
		m_pipeline->render();
		auto* renderer = m_engine->getPluginManager().getPlugin("renderer");
		static_cast<Lumix::Renderer*>(renderer)->frame();
		m_engine->getFileSystem().updateAsyncTransactions();
		if (frame_time < 1 / 60.0f)
		{
			PROFILE_BLOCK("sleep");
			Lumix::MT::sleep(Lumix::uint32(1000 / 60.0f - frame_time * 1000));
		}
		handleEvents();
	}
Ejemplo n.º 11
0
SORE_Graphics::render_list& SORE_Graphics::SortingPipe::beginRender
(
    const camera_table& cameras,
    Renderbuffer_map_t& renderbuffers,
    render_list& list,
    GLCommandList& renderQueue,
    BufferManager* bm
)
{
    PROFILE_BLOCK("Sorting pipe", profiler);

    sortedList = list;
    std::sort(sortedList.begin(), sortedList.end(), comparator);

    return sortedList;
}
Ejemplo n.º 12
0
void Item::tick(Position position) {
  PROFILE_BLOCK("Item::tick");
  if (fire->isBurning()) {
    INFO << getName() << " burning ";
    position.fireDamage(0.2);
    modViewObject().setModifier(ViewObject::Modifier::BURNING);
    fire->tick();
    if (!fire->isBurning()) {
      position.globalMessage(getTheName() + " burns out");
      discarded = true;
    }
  }
  specialTick(position);
  if (timeout) {
    if (position.getGame()->getGlobalTime() >= *timeout) {
      discarded = true;
    }
  }
}
Ejemplo n.º 13
0
	void run()
	{
		while (m_main_window->isVisible())
		{
			{
				PROFILE_BLOCK("tick");
				m_engine->update(*m_universe_context);
				m_pipeline->render();
				if (!m_engine->getResourceManager().isLoading())
				{
					if (!nextTest())
						return;
				}
				m_engine->getFileSystem().updateAsyncTransactions();
				handleEvents();
			}
			Lumix::g_profiler.frame();
		}
	}
Ejemplo n.º 14
0
std::string cache_read() {
	PROFILE_FUNC();

	std::string data;

	PROFILE_START(action_find); // Starts new action which will be inner to ACTION_READ
	bool found = find_record();
	PROFILE_STOP(action_find);

	if (!found) {
		PROFILE_BLOCK(load_from_disk);

		data = read_from_disk();
		put_into_cache(data);
		return data; // Here all action guards are destructed and actions are correctly finished
	}
	data = load_from_cache();

	return data;
}
Ejemplo n.º 15
0
	void updateAsyncTransactions() override
	{
		PROFILE_FUNCTION();
		while (!m_in_progress.empty())
		{
			AsynTrans* tr = m_in_progress.front();
			if (!tr->isCompleted()) break;

			PROFILE_BLOCK("processAsyncTransaction");
			m_in_progress.pop();

			tr->data.m_cb.invoke(*tr->data.m_file, !!(tr->data.m_flags & E_SUCCESS));
			if ((tr->data.m_flags & (E_SUCCESS | E_FAIL)) != 0)
			{
				closeAsync(*tr->data.m_file);
			}
			m_transaction_queue.dealoc(tr);
		}

		int32 can_add = C_MAX_TRANS - m_in_progress.size();
		while (can_add && !m_pending.empty())
		{
			AsynTrans* tr = m_transaction_queue.alloc(false);
			if (tr)
			{
				AsyncItem& item = m_pending[0];
				tr->data.m_file = item.m_file;
				tr->data.m_cb = item.m_cb;
				tr->data.m_mode = item.m_mode;
				copyString(tr->data.m_path, sizeof(tr->data.m_path), item.m_path);
				tr->data.m_flags = item.m_flags;
				tr->reset();

				m_transaction_queue.push(tr, true);
				m_in_progress.push(tr);
				m_pending.erase(0);
			}
			can_add--;
		}
	}
Ejemplo n.º 16
0
    astra_status_t device_streamset::read()
    {
        PROFILE_BLOCK(streamset_read);
        if (!isOpen_ || niActiveStreams_.size() == 0)
            return ASTRA_STATUS_SUCCESS;

        int streamIndex = -1;
        int timeout = openni::TIMEOUT_NONE;
        int i = 0;
        openni::Status rc;

        for(i = 0; i < niActiveStreams_.size(); i++)
        {
            rc = openni::OpenNI::waitForAnyStream(&niActiveStreams_.data()[i],
                                                  1,
                                                  &streamIndex,
                                                  timeout);
            if (streamIndex != -1)
            {
                auto stream = astraActiveStreams_[i];
                stream->read(frameIndex_);
            }

            if (streamIndex == 0)
            {
                //only increment frameIndex with primary stream
                //TODO this won't work when streams have different target FPS
                frameIndex_++;
            }
        }

        if (rc == openni::STATUS_TIME_OUT)
        {
            return ASTRA_STATUS_TIMEOUT;
        }

        return ASTRA_STATUS_SUCCESS;
    }
Ejemplo n.º 17
0
	int task()
	{
		while (!m_trans_queue->isAborted())
		{
			PROFILE_BLOCK("transaction");
			AsynTrans* tr = m_trans_queue->pop(true);
			if (!tr) break;

			if ((tr->data.m_flags & E_IS_OPEN) == E_IS_OPEN)
			{
				tr->data.m_flags |=
					tr->data.m_file->open(Path(tr->data.m_path), tr->data.m_mode) ? E_SUCCESS : E_FAIL;
			}
			else if ((tr->data.m_flags & E_CLOSE) == E_CLOSE)
			{
				tr->data.m_file->close();
				tr->data.m_file->release();
				tr->data.m_file = nullptr;
			}
			tr->setCompleted();
		}
		return 0;
	}
Ejemplo n.º 18
0
	void update(UniverseContext& context) override
	{
		PROFILE_FUNCTION();
		float dt;
		++m_fps_frame;
		if (m_fps_timer->getTimeSinceTick() > 0.5f)
		{
			m_fps = m_fps_frame / m_fps_timer->tick();
			m_fps_frame = 0;
		}
		dt = m_timer->tick();
		m_last_time_delta = dt;
		{
			PROFILE_BLOCK("update scenes");
			for (int i = 0; i < context.m_scenes.size(); ++i)
			{
				context.m_scenes[i]->update(dt);
			}
		}
		m_plugin_manager->update(dt);
		m_input_system->update(dt);
		getFileSystem().updateAsyncTransactions();
	}
Ejemplo n.º 19
0
const char* GCodeReader::parse_line_internal(const char *ptr, GCodeLine &gline, std::pair<const char*, const char*> &command)
{
    PROFILE_FUNC();
    
    // command and args
    const char *c = ptr;
    {
        PROFILE_BLOCK(command_and_args);
        // Skip the whitespaces.
        command.first = skip_whitespaces(c);
        // Skip the command.
        c = command.second = skip_word(command.first);
        // Up to the end of line or comment.
		while (! is_end_of_gcode_line(*c)) {
            // Skip whitespaces.
            c = skip_whitespaces(c);
			if (is_end_of_gcode_line(*c))
				break;
            // Check the name of the axis.
            Axis axis = NUM_AXES;
            switch (*c) {
            case 'X': axis = X; break;
            case 'Y': axis = Y; break;
            case 'Z': axis = Z; break;
            case 'F': axis = F; break;
            default:
                if (*c == m_extrusion_axis)
                    axis = E;
                break;
            }
            if (axis != NUM_AXES) {
                // Try to parse the numeric value.
                char   *pend = nullptr;
                double  v = strtod(++ c, &pend);
                if (pend != nullptr && is_end_of_word(*pend)) {
                    // The axis value has been parsed correctly.
                    gline.m_axis[int(axis)] = float(v);
                    gline.m_mask |= 1 << int(axis);
                    c = pend;
                } else
                    // Skip the rest of the word.
                    c = skip_word(c);
            } else
                // Skip the rest of the word.
                c = skip_word(c);
        }
    }
    
    if (gline.has(E) && m_config.use_relative_e_distances)
        m_position[E] = 0;

    // Skip the rest of the line.
    for (; ! is_end_of_line(*c); ++ c);

    // Copy the raw string including the comment, without the trailing newlines.
    if (c > ptr) {
        PROFILE_BLOCK(copy_raw_string);
        gline.m_raw.assign(ptr, c);
    }

    // Skip the trailing newlines.
	if (*c == '\r')
		++ c;
	if (*c == '\n')
		++ c;

    if (m_verbose)
        std::cout << gline.m_raw << std::endl;

    return c;
}
Ejemplo n.º 20
0
void generate_ground(Model *model, int chunk_x, int chunk_y, float detail) {
 PROFILE_BLOCK("Generate Ground");
  int size_x = CHUNK_SIZE_X;
  int size_y = CHUNK_SIZE_Y;

  int offset_x = chunk_x * size_x;
  int offset_y = chunk_y * size_y;

  int width = size_x * detail + 1;
  int height = size_y * detail + 1;

  u32 vertices_count = width * height * 3;
  u32 normals_count = vertices_count;
  u32 colors_count = vertices_count;
  u32 indices_count = (width - 1) * (height - 1) * 6;

  Mesh mesh = {};
  allocate_mesh(&mesh, vertices_count, normals_count, indices_count, 0, colors_count);

  u32 vertices_index = 0;
  u32 colors_index = 0;
  u32 normals_index = 0;
  u32 indices_index = 0;

  float radius = 0.0f;

  for (int x=0; x<width; x++) {
    for (int y=0; y<height; y++) {
      float x_coord = (float)(x) / detail;
      float y_coord = (float)(y) / detail;

      float value = get_terrain_height_at(x_coord + offset_x, y_coord + offset_y);

      mesh.data.vertices[vertices_index++] = x_coord;
      mesh.data.vertices[vertices_index++] = value;
      mesh.data.vertices[vertices_index++] = y_coord;

      vec3 color = vec3(0.4392f, 0.4588f, 0.3412f);

      if (value < 7.0f) {
        color = vec3(0.8118f, 0.5686f, 0.3804f);
      }

      mesh.data.colors[colors_index++] = color.r;
      mesh.data.colors[colors_index++] = color.g;
      mesh.data.colors[colors_index++] = color.b;

      // TODO(sedivy): calculate center
      float distance = glm::length(vec3(x_coord, value, y_coord));
      if (distance > radius) {
        radius = distance;
      }

      mesh.data.normals[normals_index++] = 0.0f;
      mesh.data.normals[normals_index++] = 0.0f;
      mesh.data.normals[normals_index++] = 0.0f;
    }
  }

  for (int i=0; i<height - 1; i++) {
    for (int l=0; l<width - 1; l++) {
      mesh.data.indices[indices_index++] = (height * l + i + 0);
      mesh.data.indices[indices_index++] = (height * l + i + 1);
      mesh.data.indices[indices_index++] = (height * l + i + height);

      mesh.data.indices[indices_index++] = (height * l + i + height);
      mesh.data.indices[indices_index++] = (height * l + i + 1);
      mesh.data.indices[indices_index++] = (height * l + i + height + 1);
    }
  }

  for (u32 i=0; i<indices_count; i += 3) {
    int indices_a = mesh.data.indices[i + 0] * 3;
    int indices_b = mesh.data.indices[i + 1] * 3;
    int indices_c = mesh.data.indices[i + 2] * 3;

    vec3 v0 = vec3(mesh.data.vertices[indices_a + 0],
                   mesh.data.vertices[indices_a + 1],
                   mesh.data.vertices[indices_a + 2]);

    vec3 v1 = vec3(mesh.data.vertices[indices_b + 0],
                   mesh.data.vertices[indices_b + 1],
                   mesh.data.vertices[indices_b + 2]);

    vec3 v2 = vec3(mesh.data.vertices[indices_c + 0],
                   mesh.data.vertices[indices_c + 1],
                   mesh.data.vertices[indices_c + 2]);

    vec3 normal = glm::normalize(glm::cross(v2 - v0, v1 - v0));

    mesh.data.normals[indices_a + 0] = -normal.x;
    mesh.data.normals[indices_a + 1] = -normal.y;
    mesh.data.normals[indices_a + 2] = -normal.z;

    mesh.data.normals[indices_b + 0] = -normal.x;
    mesh.data.normals[indices_b + 1] = -normal.y;
    mesh.data.normals[indices_b + 2] = -normal.z;

    mesh.data.normals[indices_c + 0] = -normal.x;
    mesh.data.normals[indices_c + 1] = -normal.y;
    mesh.data.normals[indices_c + 2] = -normal.z;
  }

  for (u32 i=0; i<normals_count / 3; i += 3) {
    float x = mesh.data.normals[i + 0];
    float y = mesh.data.normals[i + 1];
    float z = mesh.data.normals[i + 2];

    vec3 normal = glm::normalize(vec3(x, y, z));

    mesh.data.normals[i + 0] = normal.x;
    mesh.data.normals[i + 1] = normal.y;
    mesh.data.normals[i + 2] = normal.z;
  }

  model->id_name = allocate_string("chunk");
  model->mesh = mesh;
  model->radius = radius;
}
Ejemplo n.º 21
0
void SORE_Graphics::SortingPipe::doSetup(Renderbuffer_map_t& renderBuffers)
{
    PROFILE_BLOCK("Sorting pipe", profiler);
    sortedList.clear();
}
Ejemplo n.º 22
0
		virtual void endFrame()
		{
			PROFILE_BLOCK("fps_limiter");
			WaitForSingleObject(m_timer, 1000 / m_fps);
		}
Ejemplo n.º 23
0
int main(int argc, char **argv)
{
	MemStartCheck();
	{ char* test = new char[16]; delete[] test; }
	grinliz::TestContainers();

	{
		grinliz::GLString releasePath;
		GetSystemPath(GAME_SAVE_DIR, "release_log.txt", &releasePath);
		SetReleaseLog(fopen(releasePath.c_str(), "w"));
	}
	GLOUTPUT_REL(("Altera startup. version'%s'\n", VERSION));

	SDL_version compiled;
	SDL_version linked;

	SDL_VERSION(&compiled);
	SDL_GetVersion(&linked);

	GLOUTPUT_REL(("SDL version compiled: %d.%d.%d\n", compiled.major, compiled.minor, compiled.patch));
	GLOUTPUT_REL(("SDL version linked:   %d.%d.%d\n", linked.major, linked.minor, linked.patch));
	GLASSERT((linked.major == compiled.major && linked.minor == compiled.minor));

	// SDL initialization steps.
	if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_NOPARACHUTE | SDL_INIT_TIMER | SDL_INIT_AUDIO | SDL_INIT_EVENTS) < 0)
	{
		fprintf(stderr, "SDL initialization failed: %s\n", SDL_GetError());
		exit(1);
	}

	//  OpenGL 4.3 provides full compatibility with OpenGL ES 3.0.
	SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
	SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
	SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
	SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
	SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);
	SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);

#ifdef DEBUG
#if 0	// I was hoping to get to Angle on intel - may still be able to. But
	// as is this gets HW mode, which crashes in a function that should
	// be supported. The Intel drivers are so terrible. As of this writing,
	// you can't specify the DX version of ES:
	//		http://forums.libsdl.org/viewtopic.php?t=9770&highlight=angle+opengl
	SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES);
	SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);	// driver supports 2 and 3. Both crash.
	SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
#endif
#if 0
	// 3.0 context.
	SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
	SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
#endif
#if 0
	// The trickier 3.2 context.
	// No GL_QUADs anymore.
	// All the attributes need to be floats.
	// No ALPHA textures.
	SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
	SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
#endif
#if 0
	// In theory the minimum supported version:
	// has instancing, and modern shader syntax
	SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
	SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
#endif
#if 0
	SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
	SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
#endif
#endif

	if (multisample) {
		SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1);
		SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, multisample);
	}

	SDL_DisplayMode displayMode;
	SDL_GetCurrentDisplayMode(0, &displayMode);

	int screenX = displayMode.w / 8;
	int screenY = displayMode.h / 8;
	int screenWidth = displayMode.w * 3 / 4;
	int screenHeight = displayMode.h * 3 / 4;

	if (argc == 3) {
		screenWidth = atoi(argv[1]);
		screenHeight = atoi(argv[2]);
		if (screenWidth <= 0) screenWidth = SCREEN_WIDTH;
		if (screenHeight <= 0) screenHeight = SCREEN_HEIGHT;
	}

	restoreWidth = screenWidth;
	restoreHeight = screenHeight;

	SDL_Window *screen = SDL_CreateWindow("Altera",
		screenX, screenY, screenWidth, screenHeight,
		/*SDL_WINDOW_FULLSCREEN | */ SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE);
	GLASSERT(screen);
	SDL_GL_CreateContext(screen);

	int stencil = 0;
	int depth = 0;
	CHECK_GL_ERROR;
	SDL_GL_GetAttribute(SDL_GL_STENCIL_SIZE, &stencil);
	SDL_GL_GetAttribute(SDL_GL_DEPTH_SIZE, &depth);
	glGetError();	// the above stencil/depth query sometimes does throw an error.
	glGetError();	// 2 queries, 2 errors.
	CHECK_GL_ERROR;
	GLOUTPUT_REL(("SDL screen created. stencil=%d depthBits=%d\n", stencil, depth));

	/* Verify there is a surface */
	if (!screen) {
		fprintf(stderr, "Video mode set failed: %s\n", SDL_GetError());
		exit(1);
	}

	CHECK_GL_ERROR;
	glewExperimental = GL_TRUE;
	int r = glewInit();
	GLASSERT(r == GL_NO_ERROR);
	(void)r;

	while (glGetError() != GL_NO_ERROR) {
		// around again
	}
	CHECK_GL_ERROR;

	const unsigned char* vendor = glGetString(GL_VENDOR);
	const unsigned char* renderer = glGetString(GL_RENDERER);
	const unsigned char* version = glGetString(GL_VERSION);

	GLOUTPUT_REL(("OpenGL vendor: '%s'  Renderer: '%s'  Version: '%s'\n", vendor, renderer, version));
	CHECK_GL_ERROR;

	bool done = false;
	bool zooming = false;
	SDL_Event event;

	grinliz::Vector2I mouseDown = { 0, 0 };
	grinliz::Vector2I rightMouseDown = { 0, 0 };

	int zoomX = 0;
	int zoomY = 0;
	// Used to compute fingers close, but problems:
	// - really to the OS to do that, because of all the tuning
	// - the coordinates are in windows normalized, so can't get the physical distance reliably.
	//bool fingersClose = true;
	int nFingers = 0;

	void* game = NewGame(screenWidth, screenHeight, 0);

	int modKeys = SDL_GetModState();
	U32 tickTimer = 0, lastTick = 0, thisTick = 0;

#ifdef OUTPUT_MOUSE_AND_TOUCH
	int value = GetSystemMetrics(SM_DIGITIZER);
	if (value & NID_INTEGRATED_TOUCH) GLOUTPUT(("NID_INTEGRATED_TOUCH\n"));
	if (value & NID_MULTI_INPUT) GLOUTPUT(("NID_MULTI_INPUT\n"));
	if (value & NID_READY) GLOUTPUT(("NID_READY\n"));
#endif

	grinliz::Vector2F multiTouchStart = { 0, 0 };

	// ---- Main Loop --- //
	while (!done) {
		while (SDL_PollEvent(&event)) {

			switch (event.type)
			{
				case SDL_WINDOWEVENT:
				if (event.window.event == SDL_WINDOWEVENT_RESIZED) {
					screenWidth = event.window.data1;
					screenHeight = event.window.data2;
					GameDeviceLoss(game);
					GameResize(game, screenWidth, screenHeight, 0);
				}
				break;

				case SDL_KEYUP:
				switch (event.key.keysym.scancode)
				{
					case SDL_SCANCODE_LCTRL:	modKeys = modKeys & (~KMOD_LCTRL);		break;
					case SDL_SCANCODE_RCTRL:	modKeys = modKeys & (~KMOD_RCTRL);		break;
					case SDL_SCANCODE_LSHIFT:	modKeys = modKeys & (~KMOD_LSHIFT);		break;
					case SDL_SCANCODE_RSHIFT:	modKeys = modKeys & (~KMOD_RSHIFT);		break;
					default:
					break;
				}
				break;

				case SDL_KEYDOWN:
				{
					// sym or scancode? I used a dvorak keyboard, so appreciate
					// every day the difference. However, AWSD support is the 
					// primary thing so scancode is hopefully the better choice.
					switch (event.key.keysym.scancode)
					{
						case SDL_SCANCODE_LCTRL:	modKeys = modKeys | KMOD_LCTRL;		break;
						case SDL_SCANCODE_RCTRL:	modKeys = modKeys | KMOD_RCTRL;		break;
						case SDL_SCANCODE_LSHIFT:	modKeys = modKeys | KMOD_LSHIFT;	break;
						case SDL_SCANCODE_RSHIFT:	modKeys = modKeys | KMOD_RSHIFT;	break;

						case SDL_SCANCODE_F4:
						{
							int sdlMod = SDL_GetModState();
							if (sdlMod & (KMOD_RALT | KMOD_LALT))
								done = true;
						}
						break;

						case SDL_SCANCODE_ESCAPE:	GameHotKey(game, GAME_HK_ESCAPE);			break;
						case SDL_SCANCODE_SPACE:	GameHotKey(game, GAME_HK_TOGGLE_PAUSE);		break;
						case SDL_SCANCODE_RETURN:	GameHotKey(game, GAME_HK_DEBUG_ACTION);		break;
						case SDL_SCANCODE_F1:	GameHotKey(game, GAME_HK_TOGGLE_DEBUG_TEXT);	break;
						case SDL_SCANCODE_F2:	GameHotKey(game, GAME_HK_TOGGLE_DEBUG_UI);		break;
							// F3: screenshot
						case SDL_SCANCODE_TAB:	GameHotKey(game, GAME_HK_CAMERA_TOGGLE);		break;
						case SDL_SCANCODE_HOME:	GameHotKey(game, GAME_HK_CAMERA_CORE);			break;
						case SDL_SCANCODE_END:	GameHotKey(game, GAME_HK_CAMERA_AVATAR);		break;
						case SDL_SCANCODE_PAGEUP:	GameHotKey(game, GAME_HK_TELEPORT_AVATAR);	break;

							//case SDLK_a: reserved
						case SDL_SCANCODE_B:	GameHotKey(game, GAME_HK_CHEAT_GOLD);			break;
						case SDL_SCANCODE_C:	GameHotKey(game, GAME_HK_ATTACH_CORE);			break;
							//case SDLK_d: reserved
						case SDL_SCANCODE_E:	GameHotKey(game, GAME_HK_CHEAT_ELIXIR);			break;
						case SDL_SCANCODE_H:	GameHotKey(game, GAME_HK_TOGGLE_PATHING);		break;
						case SDL_SCANCODE_I:	GameHotKey(game, GAME_HK_TOGGLE_AI_DEBUG);		break;
						case SDL_SCANCODE_K:	GameHotKey(game, GAME_HK_CHEAT_CRYSTAL);		break;
						case SDL_SCANCODE_M:	GameHotKey(game, GAME_HK_MAP);					break;
						case SDL_SCANCODE_P:	GameHotKey(game, GAME_HK_TOGGLE_PERF);			break;
						case SDL_SCANCODE_Q:	GameHotKey(game, GAME_HK_CHEAT_HERD);			break;
							//case SDLK_s: reserved
						case SDL_SCANCODE_T:	GameHotKey(game, GAME_HK_CHEAT_TECH);			break;
						case SDL_SCANCODE_U:	GameHotKey(game, GAME_HK_TOGGLE_UI);			break;
							//case SDLK_w: reserved

						case SDL_SCANCODE_1:	GameHotKey(game, GAME_HK_TOGGLE_GLOW);			break;
						case SDL_SCANCODE_2:	GameHotKey(game, GAME_HK_TOGGLE_PARTICLE);		break;
						case SDL_SCANCODE_3:	GameHotKey(game, GAME_HK_TOGGLE_VOXEL);			break;
						case SDL_SCANCODE_4:	GameHotKey(game, GAME_HK_TOGGLE_SHADOW);		break;
						case SDL_SCANCODE_5:	GameHotKey(game, GAME_HK_TOGGLE_BOLT);			break;

						case SDL_SCANCODE_F3:
						GameDoTick(game, SDL_GetTicks());
						SDL_GL_SwapWindow(screen);
						ScreenCapture();
						break;

						case SDL_SCANCODE_F11:
						{
							if (fullscreen) {
								// SDL_RestoreWindow doesn't seem to work as I expect.
								SDL_SetWindowFullscreen(screen, 0);
								SDL_SetWindowSize(screen, restoreWidth, restoreHeight);
								fullscreen = false;
							}
							else {
								restoreWidth = screenWidth;
								restoreHeight = screenHeight;
								SDL_SetWindowFullscreen(screen, SDL_WINDOW_FULLSCREEN_DESKTOP);
								fullscreen = true;
							}
						}
						break;

						default:
						break;
					}
				}
				break;

				case SDL_MOUSEBUTTONDOWN:
				{
					int x = event.button.x;
					int y = event.button.y;

					int mod = 0;
					if (modKeys & (KMOD_LSHIFT | KMOD_RSHIFT))    mod = GAME_TAP_MOD_SHIFT;
					else if (modKeys & (KMOD_LCTRL | KMOD_RCTRL)) mod = GAME_TAP_MOD_CTRL;

					if (nFingers > 1) {
						// do nothing
					}
					else if (event.button.button == SDL_BUTTON_LEFT) {
						#ifdef OUTPUT_MOUSE_AND_TOUCH
						GLOUTPUT(("Left mouse down %d %d\n", x, y));
						#endif
						mouseDown.Set(event.button.x, event.button.y);
						GameTap(game, GAME_TAP_DOWN, x, y, mod);
					}
					else if (event.button.button == SDL_BUTTON_RIGHT) {
						#ifdef OUTPUT_MOUSE_AND_TOUCH
						GLOUTPUT(("Right mouse down %d %d\n", x, y));
						#endif
						GameTap(game, GAME_TAP_CANCEL, x, y, mod);
						rightMouseDown.Zero();
						if (mod == 0) {
							rightMouseDown.Set(event.button.x, event.button.y);
							GameCameraPan(game, GAME_PAN_START, float(x), float(y));
						}
						else if (mod == GAME_TAP_MOD_CTRL) {
							zooming = true;
							//GameCameraRotate( game, GAME_ROTATE_START, 0.0f );
							SDL_GetRelativeMouseState(&zoomX, &zoomY);
						}
					}
				}
				break;

				case SDL_MOUSEBUTTONUP:
				{
					int x = event.button.x;
					int y = event.button.y;

					if (event.button.button == SDL_BUTTON_RIGHT) {
						#ifdef OUTPUT_MOUSE_AND_TOUCH
						GLOUTPUT(("Right mouse up %d %d\n", x, y));
						#endif
						zooming = false;
						if (!rightMouseDown.IsZero()) {
							GameCameraPan(game, GAME_PAN_END, float(x), float(y));
							rightMouseDown.Zero();
						}
					}
					if (event.button.button == SDL_BUTTON_LEFT) {
						if (!mouseDown.IsZero()) {	// filter out mouse events that become finger events.
							#ifdef OUTPUT_MOUSE_AND_TOUCH
							GLOUTPUT(("Left mouse up %d %d\n", x, y));
							#endif
							int mod = 0;
							if (modKeys & (KMOD_LSHIFT | KMOD_RSHIFT))    mod = GAME_TAP_MOD_SHIFT;
							else if (modKeys & (KMOD_LCTRL | KMOD_RCTRL)) mod = GAME_TAP_MOD_CTRL;
							GameTap(game, GAME_TAP_UP, x, y, mod);
						}
					}
				}
				break;

				case SDL_MOUSEMOTION:
				{
					SDL_GetRelativeMouseState(&zoomX, &zoomY);
					int state = event.motion.state;
					int x = event.motion.x;
					int y = event.motion.y;

					int mod = 0;
					if (modKeys & (KMOD_LSHIFT | KMOD_RSHIFT))    mod = GAME_TAP_MOD_SHIFT;
					else if (modKeys & (KMOD_LCTRL | KMOD_RCTRL)) mod = GAME_TAP_MOD_CTRL;

					if (nFingers > 1) {
						// Do nothing.
						// Multi touch in progress.
					}
					else if (state & SDL_BUTTON(SDL_BUTTON_LEFT)) {
						if (!mouseDown.IsZero()) {
							#ifdef OUTPUT_MOUSE_AND_TOUCH
							GLOUTPUT(("Left Mouse move %d %d\n", x, y));
							#endif
							GameTap(game, GAME_TAP_MOVE, x, y, mod);
//							mouseMoveCount = 0;
						}
					}
					else if (!rightMouseDown.IsZero()) {
						GLASSERT(state & SDL_BUTTON(SDL_BUTTON_RIGHT));
						GameCameraPan(game, GAME_PAN_END, float(x), float(y));
					}
					else if (zooming && (state & SDL_BUTTON(SDL_BUTTON_RIGHT))) {
						float deltaZoom = 0.01f * (float)zoomY;
						GameZoom(game, GAME_ZOOM_DISTANCE, deltaZoom);
						GameCameraRotate(game, (float)(zoomX)*0.5f);
					}
					else if (state ==0) {
						GameTap(game, GAME_MOVE_WHILE_UP, x, y, mod);
					}
				}
				break;

				case SDL_MOUSEWHEEL:
				{
					if (event.wheel.y) {
						float deltaZoom = -0.1f * float(event.wheel.y);
						GameZoom(game, GAME_ZOOM_DISTANCE, deltaZoom);
					}
				}
				break;

				case SDL_FINGERUP:
				{
					const SDL_TouchFingerEvent* tfe = &event.tfinger;
					nFingers = SDL_GetNumTouchFingers(tfe->touchId);
					if (nFingers < 2 && !multiTouchStart.IsZero()) {
						#ifdef OUTPUT_MOUSE_AND_TOUCH
						GLOUTPUT(("2 finger END.\n"));
						#endif
						multiTouchStart.Zero();
					}
				}
				break;

				case SDL_FINGERDOWN:
				{
					const SDL_TouchFingerEvent* tfe = &event.tfinger;
					nFingers = SDL_GetNumTouchFingers(tfe->touchId);
					if (nFingers > 1) {
						if (!mouseDown.IsZero()) {
							// Wrap up the existing action.
							#ifdef OUTPUT_MOUSE_AND_TOUCH
							GLOUTPUT(("Switch to gesture.\n"));
							#endif
							mouseDown.Zero();
						}
					}
				}
				break;

				case SDL_MULTIGESTURE:
				{
					const SDL_MultiGestureEvent* mge = &event.mgesture;
					nFingers = SDL_GetNumTouchFingers(mge->touchId);
					if (nFingers > 1 && multiTouchStart.IsZero()) {
						#ifdef OUTPUT_MOUSE_AND_TOUCH
						GLOUTPUT(("2 finger START.\n"));
						#endif
						multiTouchStart.Set(mge->x, mge->y);
					}
					else if (!multiTouchStart.IsZero()) {
						// The Pan interacts badly with zoom and rotated. So instead of a continuous,
						// multi-event action do a bunch of "mini pans".
						GameCameraPan(game, GAME_PAN_START,
									  multiTouchStart.x * float(screenWidth), multiTouchStart.y*float(screenHeight));
						multiTouchStart.Set(mge->x, mge->y);
						GameCameraPan(game, GAME_PAN_MOVE,
									  multiTouchStart.x * float(screenWidth), multiTouchStart.y*float(screenHeight));
						GameCameraPan(game, GAME_PAN_END,
									  multiTouchStart.x * float(screenWidth), multiTouchStart.y*float(screenHeight));
					}

					if (nFingers == 2) {
						GameZoom(game, GAME_ZOOM_DISTANCE, -mge->dDist * 10.f);
						GameCameraRotate(game, -mge->dTheta * 100.0f);
						//GLOUTPUT(("MultiGestureEvent dTheta=%.4f dDist=%.4f x=%.4f y=%.4f nFing=%d\n", mge->dTheta, mge->dDist, mge->x, mge->y, mge->numFingers));
					}
				}
				break;

				case SDL_DOLLARGESTURE:
				{
					GLOUTPUT(("DollarGestureEvent\n"));
				}
				break;


				case SDL_QUIT:
				{
					done = true;
				}
				break;

				default:
				break;
			}
		}
		U32 delta = SDL_GetTicks() - tickTimer;
		if (delta < TIME_BETWEEN_FRAMES) {
			SDL_Delay(1);
			continue;
		}
		tickTimer = SDL_GetTicks();
		glEnable(GL_DEPTH_TEST);
		glDepthFunc(GL_LEQUAL);

		const U8* keys = SDL_GetKeyboardState(0);
		U32 tickDelta = thisTick - lastTick;
		if (tickDelta > 100) tickDelta = 100;

		float keyMoveSpeed = KEY_MOVE_SPEED * float(tickDelta) / float(TIME_BETWEEN_FRAMES);
		float keyZoomSpeed = KEY_ZOOM_SPEED * float(tickDelta) / float(TIME_BETWEEN_FRAMES);
		float keyRotatepeed = KEY_ROTATE_SPEED * float(tickDelta) / float(TIME_BETWEEN_FRAMES);

		if (keys[SDL_SCANCODE_DOWN] || keys[SDL_SCANCODE_S]) {
			if (modKeys & KMOD_CTRL)
				GameZoom(game, GAME_ZOOM_DISTANCE, keyZoomSpeed);
			else
				GameCameraMove(game, 0, -keyMoveSpeed);
		}
		if (keys[SDL_SCANCODE_UP] || keys[SDL_SCANCODE_W]) {
			if (modKeys & KMOD_CTRL)
				GameZoom(game, GAME_ZOOM_DISTANCE, -keyZoomSpeed);
			else
				GameCameraMove(game, 0, keyMoveSpeed);
		}
		if (keys[SDL_SCANCODE_LEFT] || keys[SDL_SCANCODE_A]) {
			if (modKeys & KMOD_CTRL)
				GameCameraRotate(game, keyRotatepeed);
			else
				GameCameraMove(game, -keyMoveSpeed, 0);
		}
		if (keys[SDL_SCANCODE_RIGHT] || keys[SDL_SCANCODE_D]) {
			if (modKeys & KMOD_CTRL)
				GameCameraRotate(game, -keyRotatepeed);
			else
				GameCameraMove(game, keyMoveSpeed, 0);
		}

		if (game) {
			lastTick = thisTick;
			thisTick = SDL_GetTicks();
			PROFILE_BLOCK(GameDoTick);
			GameDoTick(game, thisTick);
		}
		{
			PROFILE_BLOCK(Swap);
			SDL_GL_SwapWindow(screen);
		}
	}

	GameSave(game);
	DeleteGame(game);

	for (int i = 0; i < nModDB; ++i) {
		delete databases[i];
	}

	SDL_Quit();

#if SEND_CRASH_LOGS
	// Empty the file - quit went just fine.
	{
		FILE* fp = FOpen( "UFO_Running.txt", "w" );
		if ( fp )
			fclose( fp );
	}
#endif

	MemLeakCheck();
	return 0;
}
Ejemplo n.º 24
0
bool LastingEffects::tick(Creature* c, LastingEffect effect) {
  PROFILE_BLOCK("LastingEffects::tick");
  switch (effect) {
    case LastingEffect::BLEEDING:
      c->getBody().bleed(c, 0.03);
      c->secondPerson(PlayerMessage("You are bleeding.", MessagePriority::HIGH));
      c->thirdPerson(PlayerMessage(c->getName().the() + " is bleeding.", MessagePriority::HIGH));
      if (c->getBody().getHealth() <= 0) {
        c->you(MsgType::DIE_OF, "bleeding");
        c->dieWithLastAttacker();
        return true;
      }
      break;
    case LastingEffect::REGENERATION:
      c->getBody().heal(c, 0.03);
      break;
    case LastingEffect::ON_FIRE:
      c->getPosition().fireDamage(0.1);
      break;
    case LastingEffect::POISON:
      c->getBody().bleed(c, 0.03);
      c->secondPerson(PlayerMessage("You suffer from poisoning.", MessagePriority::HIGH));
      c->thirdPerson(PlayerMessage(c->getName().the() + " suffers from poisoning.", MessagePriority::HIGH));
      if (c->getBody().getHealth() <= 0) {
        c->you(MsgType::DIE_OF, "poisoning");
        c->dieWithLastAttacker();
        return true;
      }
      break;
    case LastingEffect::WARNING: {
      const int radius = 5;
      bool isDanger = false;
      bool isBigDanger = false;
      auto position = c->getPosition();
      for (Position v : position.getRectangle(Rectangle(-radius, -radius, radius + 1, radius + 1))) {
        for (auto f : v.getFurniture())
          if (f->emitsWarning(c)) {
            if (v.dist8(position).value_or(2) <= 1)
              isBigDanger = true;
            else
              isDanger = true;
          }
        if (Creature* enemy = v.getCreature()) {
          if (!c->canSee(enemy) && c->isEnemy(enemy)) {
            int diff = enemy->getAttr(AttrType::DAMAGE) - c->getAttr(AttrType::DEFENSE);
            if (diff > 5)
              isBigDanger = true;
            else
              if (diff > 0)
                isDanger = true;
          }
        }
      }
      if (isBigDanger)
        c->privateMessage(PlayerMessage("You sense big danger!", MessagePriority::HIGH));
      else
      if (isDanger)
        c->privateMessage(PlayerMessage("You sense danger!", MessagePriority::HIGH));
      break;
    }
    case LastingEffect::SUNLIGHT_VULNERABLE:
      if (c->getPosition().sunlightBurns()) {
        c->you(MsgType::ARE, "burnt by the sun");
        if (Random.roll(10)) {
          c->you(MsgType::YOUR, "body crumbles to dust");
          c->dieWithReason("killed by sunlight", Creature::DropType::ONLY_INVENTORY);
          return true;
        }
      }
      break;
    case LastingEffect::ENTERTAINER:
      if (!c->isAffected(LastingEffect::SLEEP) && Random.roll(50)) {
        auto others = c->getVisibleCreatures().filter([](const Creature* c) { return c->getBody().hasBrain() && c->getBody().isHumanoid(); });
        if (others.empty())
          break;
        string jokeText = "a joke";
        optional<LastingEffect> hatedGroup;
        for (auto effect : getHateEffects())
          if (c->isAffected(effect) || (c->getAttributes().getHatedByEffect() != effect && Random.roll(10 * getHateEffects().size()))) {
            hatedGroup = effect;
            break;
          }
        if (hatedGroup)
          jokeText.append(" about "_s + getHatedGroupName(*hatedGroup));
        c->verb("crack", "cracks", jokeText);
        for (auto other : others)
          if (other != c && !other->isAffected(LastingEffect::SLEEP)) {
            if (hatedGroup && hatedGroup == other->getAttributes().getHatedByEffect()) {
              other->addMorale(-0.05);
              other->you(MsgType::ARE, "offended");
            } else {
              other->verb("laugh", "laughs");
              other->addMorale(0.01);
            }
          }
      }
      break;
    case LastingEffect::BAD_BREATH:
      for (auto pos : c->getPosition().getRectangle(Rectangle::centered(7)))
        if (auto other = pos.getCreature())
          other->addMorale(-0.002);
      break;
    case LastingEffect::DISAPPEAR_DURING_DAY:
      if (c->getGame()->getSunlightInfo().getState() == SunlightState::DAY)
        c->dieNoReason(Creature::DropType::ONLY_INVENTORY);
      break;
    default:
      break;
  }
  return false;
}
Ejemplo n.º 25
0
	void updateAsyncTransactions() override
	{
		PROFILE_FUNCTION();
		while (!m_in_progress.empty())
		{
			AsynTrans* tr = m_in_progress.front();
			if (!tr->isCompleted()) break;

			PROFILE_BLOCK("processAsyncTransaction");
			m_in_progress.pop();

			if ((tr->data.m_flags & E_CANCELED) == 0)
			{
				tr->data.m_cb.invoke(*tr->data.m_file, !!(tr->data.m_flags & E_SUCCESS));
			}
			if ((tr->data.m_flags & (E_SUCCESS | E_FAIL)) != 0)
			{
				closeAsync(*tr->data.m_file);
			}
			m_transaction_queue.dealoc(tr);
		}

		i32 can_add = C_MAX_TRANS - m_in_progress.size();
		while (can_add && !m_pending.empty())
		{
			AsynTrans* tr = m_transaction_queue.alloc(false);
			if (tr)
			{
				AsyncItem& item = m_pending[0];
				tr->data.m_file = item.m_file;
				tr->data.m_cb = item.m_cb;
				tr->data.m_id = item.m_id;
				tr->data.m_mode = item.m_mode;
				copyString(tr->data.m_path, sizeof(tr->data.m_path), item.m_path);
				tr->data.m_flags = item.m_flags;
				tr->reset();

				m_transaction_queue.push(tr, true);
				m_in_progress.push(tr);
				m_pending.erase(0);
			}
			can_add--;
		}

		#if LUMIX_SINGLE_THREAD()
			while (AsynTrans* tr = m_transaction_queue.pop(false))
			{
				PROFILE_BLOCK("transaction");
				if ((tr->data.m_flags & E_IS_OPEN) == E_IS_OPEN)
				{
					tr->data.m_flags |=
						tr->data.m_file->open(Path(tr->data.m_path), tr->data.m_mode) ? E_SUCCESS : E_FAIL;
				}
				else if ((tr->data.m_flags & E_CLOSE) == E_CLOSE)
				{
					tr->data.m_file->close();
					tr->data.m_file->release();
					tr->data.m_file = nullptr;
				}
				tr->setCompleted();
			}
		#endif
	}