예제 #1
0
파일: Quad.cpp 프로젝트: ricktaylor/indigo
OOBase::SharedPtr<Indigo::Render::SGNode> Indigo::SGQuad::on_render_create(Render::SGGroup* parent)
{
	OOBase::SharedPtr<Render::SGNode> node;

	bool cached = true;
	OOBase::SharedPtr<OOGL::Texture> texture = m_image->make_texture(GL_RGBA8,cached);
	if (!texture)
		return node;

	if (!cached)
	{
		texture->parameter(GL_TEXTURE_MAG_FILTER,GL_LINEAR);
		texture->parameter(GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_LINEAR);
		texture->parameter(GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE);
		texture->parameter(GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE);
	}

	OOBase::SharedPtr< ::SGQuad> quad = OOBase::allocate_shared< ::SGQuad>(AABB(glm::vec3(0.5f,0.5f,0),glm::vec3(0.5f,0.5f,0)),texture,m_transparent,m_colour);
	if (!quad)
		LOG_ERROR_RETURN(("Failed to allocate: %s\n",OOBase::system_error_text()),node);

	node = OOBase::allocate_shared<Render::SGNode>(parent,OOBase::static_pointer_cast<Render::SGDrawable>(quad),visible(),transform());
	if (!node)
		LOG_ERROR_RETURN(("Failed to allocate: %s\n",OOBase::system_error_text()),node);

	return node;
}
예제 #2
0
bool Indigo::run(const char* name, void (*fn)(void*), void* param)
{
	// Create render comms pipe
	PIPE_RACK::instance().m_render_pipe =  OOBase::allocate_shared<Indigo::Pipe,OOBase::ThreadLocalAllocator>("render");
	if (!PIPE_RACK::instance().m_render_pipe)
		LOG_ERROR_RETURN(("Failed to allocate render pipe: %s",OOBase::system_error_text()),false);

	render_init(PIPE_RACK::instance().m_render_pipe.get());

	// Not sure if we need to set this first...
	glfwSetErrorCallback(&on_glfw_error);

	if (!glfwInit())
		LOG_ERROR_RETURN(("glfwInit failed"),false);

	// Set defaults
	glfwDefaultWindowHints();

	bool ret = false;
	OOBase::SharedPtr<OOBase::Thread> thread;
	PIPE_RACK::instance().m_logic_pipe = Indigo::start_thread(name,thread);
	if (PIPE_RACK::instance().m_logic_pipe)
	{
		ret = PIPE_RACK::instance().m_logic_pipe->call(OOBase::make_delegate<OOBase::ThreadLocalAllocator>(fn),param);
		if (ret)
			thread->join();
	}

	glfwTerminate();

	return ret;
}
예제 #3
0
파일: Quad.cpp 프로젝트: ricktaylor/indigo
bool QuadFactory::alloc()
{
	GLubyte e[elements_per_quad] = { 0,1,2,2,1,3 };
	vertex_data a[4] =
	{
		{ 0.f, 1.f, 0, 0},
		{ 0.f, 0.f, 0, 0xFFFF},
		{ 1.f, 1.f, 0xFFFF, 0 },
		{ 1.f, 0.f, 0xFFFF, 0xFFFF }
	};

	m_ptrVAO = OOBase::allocate_shared<OOGL::VertexArrayObject,OOBase::ThreadLocalAllocator>();
	if (!m_ptrVAO)
		LOG_ERROR_RETURN(("Failed to allocate VAO: %s",OOBase::system_error_text(ERROR_OUTOFMEMORY)),false);
	m_ptrVAO->bind();

	OOBase::SharedPtr<OOGL::BufferObject> m_ptrVertices = OOBase::allocate_shared<OOGL::BufferObject,OOBase::ThreadLocalAllocator>(GL_ARRAY_BUFFER,GL_STATIC_DRAW,sizeof(a),a);
	OOBase::SharedPtr<OOGL::BufferObject> m_ptrElements = OOBase::allocate_shared<OOGL::BufferObject,OOBase::ThreadLocalAllocator>(GL_ELEMENT_ARRAY_BUFFER,GL_STATIC_DRAW,sizeof(e),e);
	if (!m_ptrVertices || !m_ptrElements)
		LOG_ERROR_RETURN(("Failed to allocate VBO: %s",OOBase::system_error_text(ERROR_OUTOFMEMORY)),false);

	OOBase::SharedPtr<OOGL::Shader> shaders[2];
	shaders[0] = Indigo::ShaderPool::add_shader("2d_textured_colour.vert",GL_VERTEX_SHADER,Indigo::static_resources());
	shaders[1] = Indigo::ShaderPool::add_shader("colour_blend.frag",GL_FRAGMENT_SHADER,Indigo::static_resources());
	if (shaders[0] && shaders[1])
		m_ptrProgram = Indigo::ShaderPool::add_program("2d_image",shaders,2);

	if (!m_ptrProgram)
		return false;

	GLint pos = m_ptrProgram->attribute_location("in_Position");
	if (pos == -1)
		return false;

	m_ptrVAO->attribute(pos,m_ptrVertices,2,GL_FLOAT,false,sizeof(vertex_data),offsetof(vertex_data,x));
	m_ptrVAO->enable_attribute(pos);

	pos = m_ptrProgram->attribute_location("in_TexCoord");
	if (pos == -1)
		return false;

	m_ptrVAO->attribute(pos,m_ptrVertices,2,GL_UNSIGNED_SHORT,true,sizeof(vertex_data),offsetof(vertex_data,u));
	m_ptrVAO->enable_attribute(pos);

	m_ptrVAO->element_array(m_ptrElements);
	m_ptrVAO->unbind();

	return true;
}
예제 #4
0
bool Indigo::UILayer::add_named_widget(const OOBase::SharedPtr<UIWidget>& widget, const char* name, size_t len)
{
	if (!m_names.insert(OOBase::Hash<const char*>::hash(name,len),widget))
		LOG_ERROR_RETURN(("Failed to insert widget name: %s",OOBase::system_error_text()),false);

	return true;
}
예제 #5
0
파일: Pipe.cpp 프로젝트: ricktaylor/indigo
OOBase::SharedPtr<Indigo::Pipe> Indigo::Pipe::open(const char* remote)
{
	OOBase::SharedPtr<Indigo::Pipe> pipe;
	if (!m_recv_queue)
		LOG_ERROR_RETURN(("Can't open closed IPC pipe"),pipe);

	PipeTable::table_t::iterator i = PIPE_TABLE::instance().m_queues.find(remote);
	if (i == PIPE_TABLE::instance().m_queues.end())
		LOG_ERROR_RETURN(("Failed to find remote IPC pipe"),pipe);

	pipe = OOBase::allocate_shared<Indigo::Pipe,OOBase::ThreadLocalAllocator>(i->second,m_recv_queue);
	if (!pipe)
		LOG_ERROR(("Failed to allocate pipe: %s",OOBase::system_error_text()));

	return pipe;
}
예제 #6
0
OOBase::SharedPtr<Indigo::Render::UIDrawable> Indigo::NinePatch::make_drawable(const glm::vec4& colour, bool visible, const glm::ivec2& position, const glm::uvec2& size) const
{
	ASSERT_RENDER_THREAD();

	if (!valid())
		LOG_ERROR_RETURN(("NinePatch::make_drawable called when invalid!"),OOBase::SharedPtr<Indigo::Render::UIDrawable>());

	bool is_9 = (m_info->m_borders != glm::uvec4(0));
	bool cached = true;

	OOBase::SharedPtr<OOGL::Texture> texture = make_texture(GL_RGBA8,cached,is_9 ? 1 : 0);
	if (!texture)
		return OOBase::SharedPtr<Indigo::Render::UIDrawable>();

	if (cached)
	{
		texture->parameter(GL_TEXTURE_MAG_FILTER,GL_LINEAR);
		texture->parameter(GL_TEXTURE_MIN_FILTER,is_9 ? GL_LINEAR : GL_LINEAR_MIPMAP_LINEAR);
		texture->parameter(GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE);
		texture->parameter(GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE);
	}

	if (is_9)
		return OOBase::allocate_shared<Render::UINinePatch,OOBase::ThreadLocalAllocator>(texture,colour,m_info,visible,position,size);
	else
		return OOBase::allocate_shared<Render::UIImage,OOBase::ThreadLocalAllocator>(texture,colour,visible,position,size);
}
예제 #7
0
bool Indigo::UIPanel::on_render_create(Indigo::Render::UIGroup* group)
{
	if (m_background)
	{
		OOBase::SharedPtr<Render::UIDrawable> bk = m_background->make_drawable(m_colour,true,glm::ivec2(),size());
		if (!bk)
			return false;

		if (!group->add_drawable(bk))
			return false;

		m_render_background = bk.get();
	}

	OOBase::SharedPtr<Indigo::Render::UIGroup> subgroup = OOBase::allocate_shared<Indigo::Render::UIGroup,OOBase::ThreadLocalAllocator>(true,glm::ivec2(),size()) ;
	if (!subgroup)
		LOG_ERROR_RETURN(("Failed to allocate: %s",OOBase::system_error_text()),false);

	if (!group->add_drawable(subgroup))
		return false;

	m_render_parent = subgroup.get();

	return UIGroup::on_render_create(group);
}
예제 #8
0
bool Indigo::detail::ZipFile::exists(const OOBase::String& prefix, const char* name)
{
	OOBase::String filename(prefix);
	if (!filename.append(name))
		LOG_ERROR_RETURN(("Cannot append string: %s",OOBase::system_error_text()),false);

	return m_mapFiles.exists(filename);
}
예제 #9
0
파일: Pipe.cpp 프로젝트: ricktaylor/indigo
bool Indigo::detail::IPC::Queue::enqueue(callback_t callback, void* param)
{
	OOBase::Guard<OOBase::Condition::Mutex> guard(m_lock);

	if (!m_queue.push(Item(callback,param)))
		LOG_ERROR_RETURN(("Failed to enqueue command: %s",OOBase::system_error_text()),false);

	m_cond.signal();
	return true;
}
예제 #10
0
OOBase::uint64_t Indigo::detail::ZipFile::size(const OOBase::String& prefix, const char* name)
{
	OOBase::String filename(prefix);
	if (!filename.append(name))
		LOG_ERROR_RETURN(("Cannot append string: %s",OOBase::system_error_text()),OOBase::uint64_t(-1));

	OOBase::Table<OOBase::String,Info>::iterator i=m_mapFiles.find(filename);
	if (!i)
		return 0;

	return i->second.m_length;
}
예제 #11
0
bool Root::Manager::stop_services()
{
    OOBase::Logger::log(OOBase::Logger::Information,"Stopping services");

    // Send the stop message to the sandbox oosvruser process
    OOBase::CDRStream request;
    if (!request.write(static_cast<OOServer::RootOpCode_t>(OOServer::Service_StopAll)))
        LOG_ERROR_RETURN(("Failed to write request data: %s",OOBase::system_error_text(request.last_error())),false);

    // Make a blocking call
    OOBase::CDRStream response;
    OOServer::MessageHandler::io_result::type res = sendrecv_sandbox(request,&response,OOServer::Message_t::synchronous);
    if (res != OOServer::MessageHandler::io_result::success)
        LOG_ERROR_RETURN(("Failed to send service stop request to sandbox"),false);

    OOServer::RootErrCode_t err = 0;
    if (!response.read(err))
        LOG_ERROR_RETURN(("Failed to read response data: %s",OOBase::system_error_text(response.last_error())),false);

    return true;
}
예제 #12
0
bool Indigo::ZipResource::open(const char* filename)
{
	OOBase::SharedPtr<detail::ZipFile> zip = OOBase::allocate_shared<detail::ZipFile>();
	if (!zip)
		LOG_ERROR_RETURN(("Failed to allocate: %s",OOBase::system_error_text()),false);

	bool r = zip->open(filename);
	if (r)
		zip.swap(m_zip);

	return r;
}
예제 #13
0
파일: Pipe.cpp 프로젝트: ricktaylor/indigo
static OOBase::SharedPtr<Indigo::detail::IPC::Queue> register_queue(const char* name)
{
	OOBase::SharedPtr<Indigo::detail::IPC::Queue> queue;

	PipeTable::table_t::iterator i = PIPE_TABLE::instance().m_queues.find(name);
	if (i == PIPE_TABLE::instance().m_queues.end())
	{
		OOBase::String str;
		if (!str.assign(name))
			LOG_ERROR_RETURN(("Failed to assign string: %s",OOBase::system_error_text()),queue);

		queue = OOBase::allocate_shared<Indigo::detail::IPC::Queue>();
		if (!queue)
			LOG_ERROR_RETURN(("Failed to allocate queue: %s",OOBase::system_error_text()),queue);

		i = PIPE_TABLE::instance().m_queues.insert(str,queue);
		if (i == PIPE_TABLE::instance().m_queues.end())
		{
			LOG_ERROR(("Failed to insert queue: %s",OOBase::system_error_text()));
			queue.reset();
		}
	}
	return i->second;
}
예제 #14
0
bool Root::Manager::start_services()
{
    // Find the sandbox process
    OOBase::ReadGuard<OOBase::RWMutex> guard(m_lock);

    UserProcess sandbox;
    if (!m_sandbox_channel || !m_mapUserProcesses.find(m_sandbox_channel,sandbox))
        LOG_ERROR_RETURN(("Failed to find sandbox process"),false);

    guard.release();

    // Get the list of services, ordered by dependency
    OOBase::StackAllocator<512> allocator;
    OOBase::Queue<OOBase::LocalString,OOBase::AllocatorInstance> queueNames(allocator);
    OOBase::Queue<Omega::int64_t,OOBase::AllocatorInstance> queueKeys(allocator);
    if (!enum_services(m_registry,queueNames,queueKeys))
        return false;

    OOBase::LocalString strName(allocator);
    Omega::int64_t key;
    while (queueNames.pop(&strName) && queueKeys.pop(&key))
    {
        OOBase::Logger::log(OOBase::Logger::Information,"Starting service: %s",strName.c_str());

        // Get the timeout value
        unsigned long wait_secs = 0;
        OOBase::LocalString strTimeout(allocator);
        if (m_registry->get_value(key,"Timeout",0,strTimeout) == Db::HIVE_OK)
            wait_secs = strtoul(strTimeout.c_str(),NULL,10);

        if (wait_secs == 0)
            wait_secs = 15;

        if (Root::is_debug())
            wait_secs = 1000;

        // Create a unique local socket name
        OOBase::RefPtr<OOBase::Socket> ptrSocket;
        if (!sandbox.m_ptrProcess->LaunchService(this,strName,key,wait_secs,true,ptrSocket))
            enum_sockets(m_registry,strName,ptrSocket,key);
    }

    return true;
}
예제 #15
0
bool Indigo::UIGroup::add_widget(const OOBase::SharedPtr<UIWidget>& widget, const char* name, size_t len)
{
	if (!m_children.push_back(widget))
		LOG_ERROR_RETURN(("Failed to insert widget: %s",OOBase::system_error_text()),false);

	if (name && len && !add_named_widget(widget,name,len))
	{
		m_children.pop_back();
		return false;
	}

	if (!m_render_group)
		return true;

	bool ret = false;
	if (!render_pipe()->call(OOBase::make_delegate<OOBase::ThreadLocalAllocator>(m_render_parent,&Render::UIGroup::add_subgroup),widget.get(),&ret) || !ret)
		m_children.pop_back();

	return ret;
}
예제 #16
0
파일: Pipe.cpp 프로젝트: ricktaylor/indigo
bool Indigo::Pipe::post(void (*fn)(void*), void* param, void (*fn_cleanup)(void*))
{
	if (!m_recv_queue)
		return false;

	if (!m_send_queue && this != thread_pipe())
		return false;

	CallInfo* ci = OOBase::ThreadLocalAllocator::allocate_new<CallInfo>();
	if (!ci)
		LOG_ERROR_RETURN(("Failed to allocate: %s",OOBase::system_error_text()),false);

	ci->m_fn = fn;
	ci->m_fn_cleanup = fn_cleanup;
	ci->m_param = param;

	if (m_send_queue)
	{
		ci->m_reply = m_recv_queue;

		if (!m_send_queue->enqueue(&Pipe::do_post,ci))
		{
			OOBase::ThreadLocalAllocator::delete_free(ci);
			return false;
		}
	}
	else
	{
		// Self post
		if (!m_recv_queue->enqueue(&Pipe::do_post,ci))
		{
			OOBase::ThreadLocalAllocator::delete_free(ci);
			return false;
		}
	}
	
	return true;
}
예제 #17
0
OOBase::SharedPtr<const char> Indigo::detail::ZipFile::load(const OOBase::String& prefix, const char* name)
{
	OOBase::SharedPtr<const char> ret;
	OOBase::String filename(prefix);
	if (!filename.append(name))
		LOG_ERROR_RETURN(("Failed to append string: %s",OOBase::system_error_text()),ret);

	OOBase::Table<OOBase::String,Info>::iterator i=m_mapFiles.find(filename);
	if (!i)
		return ret;

	// Read the local file header
	if (m_file.seek(i->second.m_offset,OOBase::File::seek_begin) == OOBase::uint64_t(-1))
		LOG_ERROR_RETURN(("Failed to get seek in file: %s",OOBase::system_error_text()),ret);

	OOBase::uint8_t header[30];
	if (m_file.read(header,30) != 30)
		LOG_ERROR_RETURN(("Failed to read local file header header in zip"),ret);

	static const OOBase::uint8_t LFR_HEADER[4] = { 0x50, 0x4b, 0x03, 0x04 };
	if (memcmp(header,LFR_HEADER,4) != 0)
		LOG_ERROR_RETURN(("Invalid local file header header in zip"),ret);

	OOBase::uint16_t compression = read_uint16(header,8);
	OOBase::uint32_t compressed_size = read_uint32(header,18);
	size_t offset = 30 + read_uint16(header,26) + read_uint16(header,28);

	OOBase::SharedPtr<const char> mapping = m_file.auto_map<const char>(false,i->second.m_offset + offset,compressed_size);
	if (!mapping)
		LOG_ERROR_RETURN(("Failed to map file content: %s",OOBase::system_error_text()),ret);

	if (compression == 0)
	{
		ret = mapping;
	}
	else if (compression == 8)
	{
		void* p = OOBase::CrtAllocator::allocate(i->second.m_length,1);
		if (!p)
			LOG_ERROR_RETURN(("Failed to allocate: %s",OOBase::system_error_text()),ret);

		if (stbi_zlib_decode_noheader_buffer(static_cast<char*>(p),(int)i->second.m_length,mapping.get(),(int)compressed_size) == -1)
		{
			LOG_ERROR(("Failed to inflate file: %s",stbi_failure_reason()));
			OOBase::CrtAllocator::free(p);
		}
		else
		{
			ret = OOBase::const_pointer_cast<const char>(OOBase::make_shared<char>(static_cast<char*>(p)));
			if (!ret)
			{
				LOG_ERROR(("Failed to allocate: %s",OOBase::system_error_text()));
				OOBase::CrtAllocator::free(p);
			}
		}
	}
	else
		LOG_ERROR(("Unsupported zip compression method: %u",compression));

	return ret;
}
예제 #18
0
int Host::ShellEx(const OOBase::CmdArgs::results_t& args)
{
    OOBase::LocalString strAppName(args.get_allocator());
    if (!args.find("@0",strAppName))
        LOG_ERROR_RETURN(("No arguments passed with --shellex"),EXIT_FAILURE);

    OOBase::TempPtr<wchar_t> wszAppName(args.get_allocator());
    int err = OOBase::Win32::utf8_to_wchar_t(strAppName.c_str(),wszAppName);
    if (err)
        LOG_ERROR_RETURN(("Failed to convert string: %s",OOBase::system_error_text(err)),EXIT_FAILURE);

    OOBase::LocalString strCmdLine(args.get_allocator());
    for (size_t i = 1;; ++i)
    {
        OOBase::LocalString strId(args.get_allocator());
        int err = strId.printf("@%u",i);
        if (err)
            LOG_ERROR_RETURN(("Failed to format string: %s",OOBase::system_error_text(err)),EXIT_FAILURE);

        OOBase::LocalString strArg(args.get_allocator());
        if (!args.find(strId,strArg))
            break;

        err = strCmdLine.append(strArg.c_str());
        if (!err && i != 0)
            err = strCmdLine.append(" ");
        if (err)
            LOG_ERROR_RETURN(("Failed to append string: %s",OOBase::system_error_text(err)),EXIT_FAILURE);
    }

    OOBase::TempPtr<wchar_t> wszCmdLine(args.get_allocator());
    if (!strCmdLine.empty())
    {
        err = OOBase::Win32::utf8_to_wchar_t(strCmdLine.c_str(),wszCmdLine);
        if (err)
            LOG_ERROR_RETURN(("Failed to convert string: %s",OOBase::system_error_text(err)),EXIT_FAILURE);
    }

    HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
    if (FAILED(hr))
        LOG_ERROR_RETURN(("CoInitializeEx failed: %s",OOBase::system_error_text()),EXIT_FAILURE);

    SHELLEXECUTEINFOW sei = {0};
    sei.cbSize = sizeof(sei);
    sei.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_NOASYNC | SEE_MASK_FLAG_NO_UI | SEE_MASK_NO_CONSOLE;
    sei.lpFile = wszAppName;
    sei.lpParameters = wszCmdLine;
    sei.nShow = SW_SHOWDEFAULT;

    if (!ShellExecuteExW(&sei))
        LOG_ERROR_RETURN(("ShellExecuteExW failed: %s",OOBase::system_error_text()),EXIT_FAILURE);

    if (sei.hProcess)
    {
        WaitForSingleObject(sei.hProcess,INFINITE);
        CloseHandle(sei.hProcess);
    }

    CoUninitialize();

    return EXIT_SUCCESS;
}
예제 #19
0
GLsizei NinePatchFactory::alloc_patch(const glm::uvec2& size, const glm::uvec4& borders, const glm::uvec2& tex_size)
{
	GLsizei patch = -1;

	for (free_list_t::iterator i=m_listFree.begin(); i; ++i)
	{
		if (i->second == 1)
		{
			patch = i->first;
			m_listFree.erase(i);
			break;
		}
		else if (i->second > 1)
		{
			patch = i->first;
			i->first += 1;
			i->second -= 1;
			break;
		}
	}

	if (patch == -1)
	{
		if (!m_ptrProgram && !create_program())
			return patch;

		if (!m_ptrVAO)
		{
			m_ptrVAO = OOBase::allocate_shared<OOGL::VertexArrayObject,OOBase::ThreadLocalAllocator>();
			if (!m_ptrVAO)
				LOG_ERROR_RETURN(("Failed to allocate VAO: %s",OOBase::system_error_text(ERROR_OUTOFMEMORY)),patch);
		}
		m_ptrVAO->bind();

		GLsizei new_size = 16;
		while (new_size < m_allocated + 1)
			new_size *= 2;

		OOBase::SharedPtr<OOGL::BufferObject> ptrNewVertices = OOBase::allocate_shared<OOGL::BufferObject,OOBase::ThreadLocalAllocator>(GL_ARRAY_BUFFER,GL_DYNAMIC_DRAW,new_size * vertices_per_patch * sizeof(vertex_data));
		OOBase::SharedPtr<OOGL::BufferObject> ptrNewElements = OOBase::allocate_shared<OOGL::BufferObject,OOBase::ThreadLocalAllocator>(GL_ELEMENT_ARRAY_BUFFER,GL_DYNAMIC_DRAW,new_size * elements_per_patch * sizeof(GLuint));
		if (!ptrNewVertices || !ptrNewElements)
			LOG_ERROR_RETURN(("Failed to allocate VBO: %s",OOBase::system_error_text(ERROR_OUTOFMEMORY)),patch);

		if (m_ptrVertices)
			ptrNewVertices->copy(0,m_ptrVertices,0,m_allocated * vertices_per_patch * sizeof(vertex_data));

		if (m_ptrElements)
			ptrNewElements->copy(0,m_ptrElements,0,m_allocated * elements_per_patch * sizeof(GLuint));

		m_ptrVertices.swap(ptrNewVertices);
		m_ptrElements.swap(ptrNewElements);

		free_list_t::iterator last = m_listFree.back();
		if (last)
			last->second += new_size - m_allocated;
		else
			last = m_listFree.insert(m_allocated,new_size - m_allocated);
		m_allocated = new_size;

		patch = last->first;
		last->first += 1;
		last->second -= 1;

		GLint a = m_ptrProgram->attribute_location("in_Position");
		m_ptrVAO->attribute(a,m_ptrVertices,2,GL_FLOAT,false,sizeof(vertex_data),offsetof(vertex_data,x));
		m_ptrVAO->enable_attribute(a);

		a = m_ptrProgram->attribute_location("in_TexCoord");
		if (a != -1)
		{
			m_ptrVAO->attribute(a,m_ptrVertices,2,GL_UNSIGNED_SHORT,true,sizeof(vertex_data),offsetof(vertex_data,u));
			m_ptrVAO->enable_attribute(a);
		}

		m_ptrVAO->element_array(m_ptrElements);

		m_ptrVAO->unbind();
	}

	OOBase::SharedPtr<GLuint> ei = m_ptrElements->auto_map<GLuint>(GL_MAP_WRITE_BIT,patch * elements_per_patch * sizeof(GLuint),elements_per_patch * sizeof(GLuint));
	GLuint* e = ei.get();
	GLuint idx = patch * vertices_per_patch;
	for (size_t i=0;i<12;++i)
	{
		e[i*2] = static_cast<GLuint>(idx + i);
		e[i*2 + 1] = static_cast<GLuint>(idx + i + 4);
	}

	layout_patch(patch,size,borders,tex_size);

	return patch;
}
예제 #20
0
bool Indigo::NinePatch::get_bounds()
{
	bool has_border = false;
	bool has_margins = false;

	glm::uvec2 span;
	if (scan_line(0,span))
	{
		m_info->m_borders.x = span.x;
		m_info->m_borders.z = m_width - span.y;

		if (scan_column(0,span))
		{
			has_border = true;

			m_info->m_borders.y = m_height - span.y;
			m_info->m_borders.w = span.x;

			if (scan_line(m_height-1,span))
			{
				m_margins.x = span.x;
				m_margins.z = m_width  - span.y;

				if (scan_column(m_width-1,span))
				{
					has_margins = true;

					m_margins.y = m_height - span.y;
					m_margins.w = span.x;
				}
			}
		}
	}

	if (has_margins)
	{
		// Now swap out the pixels for a sub-image...
		char* new_pixels = static_cast<char*>(OOBase::ThreadLocalAllocator::allocate((m_width-2)*(m_height-2)*m_components));
		if (!new_pixels)
			LOG_ERROR_RETURN(("Failed to allocate 9-patch pixel data!"),false);

		char* dest = new_pixels;
		const char* src = static_cast<const char*>(m_pixels) + (m_width+1)*m_components;
		for (unsigned int y=1;y<m_height-1;++y)
		{
			memcpy(dest,src,(m_width-2)*m_components);

			src += m_width*m_components;
			dest += (m_width-2)*m_components;
		}

		OOBase::ThreadLocalAllocator::free(m_pixels);
		m_pixels = new_pixels;
		m_height -= 2;
		m_width -= 2;
	}
	else if (has_border)
	{
		// Now swap out the pixels for a sub-image...
		char* new_pixels = static_cast<char*>(OOBase::ThreadLocalAllocator::allocate((m_width-1)*(m_height-1)*m_components));
		if (!new_pixels)
			LOG_ERROR_RETURN(("Failed to allocate 9-patch pixel data!"),false);

		char* dest = new_pixels;
		const char* src = static_cast<const char*>(m_pixels) + (m_width+1)*m_components;
		for (unsigned int y=1;y<m_height;++y)
		{
			memcpy(dest,src,(m_width-1)*m_components);

			src += m_width*m_components;
			dest += (m_width-1)*m_components;
		}

		OOBase::ThreadLocalAllocator::free(m_pixels);
		m_pixels = new_pixels;
		m_height -= 1;
		m_width -= 1;
	}

	m_info->m_tex_size = size();

	return true;
}
예제 #21
0
bool Indigo::detail::ZipFile::open(const char* filename)
{
	static const OOBase::uint8_t END_OF_CDR[4] = { 0x50, 0x4b, 0x05, 0x06 };
	static const OOBase::uint8_t CDR_HEADER[4] = { 0x50, 0x4b, 0x01, 0x02 };

	int err = m_file.open(filename,false);
	if (err)
		LOG_ERROR_RETURN(("Failed to open file %s: %s",filename,OOBase::system_error_text(err)),false);

	OOBase::uint64_t len = m_file.length();
	if (len == OOBase::uint64_t(-1))
		LOG_ERROR_RETURN(("Failed to get file length: %s",OOBase::system_error_text()),false);

	// Step backwards looking for end of central directory record
	OOBase::uint32_t cdr_size = 0;

	OOBase::ScopedArrayPtr<OOBase::uint8_t,OOBase::ThreadLocalAllocator,256> buf;
	for (OOBase::int64_t offset = len - 256;!cdr_size;)
	{
		if (offset < 0)
			offset = 0;

		OOBase::uint64_t p = m_file.seek(offset,OOBase::File::seek_begin);
		if (p == OOBase::uint64_t(-1))
			LOG_ERROR_RETURN(("Failed to get seek in file: %s",OOBase::system_error_text()),false);

		size_t chunk_len = m_file.read(buf.get(),256);
		if (chunk_len == size_t(-1))
			LOG_ERROR_RETURN(("Failed to read file: %s",OOBase::system_error_text()),false);

		// Scan forwards looking for signatures
		for (OOBase::uint8_t* c = buf.get(); c < buf.get() + chunk_len - 4; ++c)
		{
			if (memcmp(c,END_OF_CDR,4) == 0)
			{
				OOBase::uint64_t eof_cdr = p + (c - buf.get());
				if (len - eof_cdr >= 22 && m_file.seek(eof_cdr,OOBase::File::seek_begin) == eof_cdr)
				{
					m_file.read(buf.get(),22);

					OOBase::uint16_t disk_no = read_uint16(buf,4);
					OOBase::uint16_t cdr_disk_no = read_uint16(buf,6);
					OOBase::uint16_t cdr_entries_disk = read_uint16(buf,8);
					OOBase::uint16_t cdr_entries = read_uint16(buf,10);
					OOBase::uint32_t cdr_size_i = read_uint32(buf,12);
					OOBase::uint32_t cdr_offset = read_uint32(buf,16);
					OOBase::uint16_t comments = read_uint16(buf,20);
					
					if (cdr_size_i >= 46 && (eof_cdr + 22 + comments == len) && 
						(disk_no == 0 && cdr_disk_no == 0 && cdr_entries_disk == cdr_entries) &&
						(cdr_offset + cdr_size_i <= eof_cdr))
					{
						if (m_file.seek(cdr_offset,OOBase::File::seek_begin) == cdr_offset)
						{
							m_file.read(buf.get(),46);
							if (memcmp(buf.get(),CDR_HEADER,4) == 0)
							{
								cdr_size = cdr_size_i;
								break;
							}
						}
					}
				}
			}
		}

		if (offset > 0)
			offset -= 253;
		else
			break;
	}

	if (!cdr_size)
		LOG_ERROR_RETURN(("Failed to find end of central dictionary in zip %s",filename),false);

	// Now loop reading file entries
	for (;;)
	{
		struct Info info = {0};

		info.m_length = read_uint32(buf,24);
		OOBase::uint16_t filename_len = read_uint16(buf,28);
		OOBase::uint16_t extra_len = read_uint16(buf,30);
		OOBase::uint16_t comments = read_uint16(buf,32);
		OOBase::uint16_t disk_no = read_uint16(buf,34);
		info.m_offset = read_uint32(buf,42);

		if (disk_no != 0)
			LOG_ERROR_RETURN(("Multi-disk zip file not supported: %s",filename),false);

		if (filename_len == 0)
			LOG_WARNING(("Ignoring empty filename in %s",filename));
		else
		{
			if (!buf.resize(filename_len))
				LOG_ERROR_RETURN(("Failed to resize buffer: %s",OOBase::system_error_text()),false);

			if (m_file.read(buf.get(),filename_len) != filename_len)
				LOG_ERROR_RETURN(("Failed to read file %s: %s",filename,OOBase::system_error_text()),false);

			OOBase::String strFilename;
			if (!strFilename.assign(reinterpret_cast<char*>(buf.get()),filename_len))
				LOG_ERROR_RETURN(("Failed to assign string: %s",OOBase::system_error_text()),false);

			if (!m_mapFiles.insert(strFilename,info))
				LOG_ERROR_RETURN(("Failed to insert zip entry: %s",OOBase::system_error_text()),false);
		}

		if (cdr_size <= OOBase::uint32_t(filename_len) + extra_len + comments + 46)
			break;

		cdr_size -= 46 + filename_len + extra_len + comments;
		if (m_file.seek(extra_len + comments,OOBase::File::seek_current) == OOBase::uint64_t(-1))
			LOG_ERROR_RETURN(("Failed to get seek in file: %s",OOBase::system_error_text()),false);

		if (m_file.read(buf.get(),46) != 46)
			LOG_ERROR_RETURN(("Failed to read central dictionary header in zip %s",filename),false);

		if (memcmp(buf.get(),CDR_HEADER,4) != 0)
			LOG_ERROR_RETURN(("Invalid central dictionary header in zip %s",filename),false);
	}
	
	return true;
}
예제 #22
0
bool Root::Manager::start_client_acceptor(OOBase::AllocatorInstance& allocator)
{
	const int NUM_ACES = 3;
	EXPLICIT_ACCESSW ea[NUM_ACES] = { {0}, {0}, {0} };

	PSID pSID;
	SID_IDENTIFIER_AUTHORITY SIDAuthNT = {SECURITY_NT_AUTHORITY};
	if (!AllocateAndInitializeSid(&SIDAuthNT, 1,
								  SECURITY_LOCAL_SYSTEM_RID,
								  0, 0, 0, 0, 0, 0, 0,
								  &pSID))
	{
		LOG_ERROR_RETURN(("AllocateAndInitializeSid failed: %s",OOBase::system_error_text()),false);
	}

	OOBase::SmartPtr<void,OOBase::Win32::SIDDestructor> pSIDSystem(pSID);

	// Set full control for the creating process SID
	ea[0].grfAccessPermissions = FILE_ALL_ACCESS;
	ea[0].grfAccessMode = SET_ACCESS;
	ea[0].grfInheritance = NO_INHERITANCE;
	ea[0].Trustee.TrusteeForm = TRUSTEE_IS_SID;
	ea[0].Trustee.TrusteeType = TRUSTEE_IS_USER;
	ea[0].Trustee.ptstrName = (LPWSTR)pSIDSystem;  // Don't use CREATOR/OWNER, it doesn't work with multiple pipe instances...
		
	// Get the current user's Logon SID
	OOBase::Win32::SmartHandle hProcessToken;
	if (!OpenProcessToken(GetCurrentProcess(),TOKEN_QUERY,&hProcessToken))
		LOG_ERROR_RETURN(("OpenProcessToken failed: %s",OOBase::system_error_text()),false);

	// Get the logon SID of the Token
	OOBase::TempPtr<void> ptrSIDLogon(allocator);
	if (OOBase::Win32::GetLogonSID(hProcessToken,ptrSIDLogon) == ERROR_SUCCESS)
	{
		// Use logon sid instead...
		ea[0].Trustee.ptstrName = (LPWSTR)ptrSIDLogon;  // Don't use CREATOR/OWNER, it doesn't work with multiple pipe instances...
	}

	// Create a SID for the EVERYONE group.
	SID_IDENTIFIER_AUTHORITY SIDAuthWorld = {SECURITY_WORLD_SID_AUTHORITY};
	if (!AllocateAndInitializeSid(&SIDAuthWorld, 1,
								  SECURITY_WORLD_RID,
								  0, 0, 0, 0, 0, 0, 0,
								  &pSID))
	{
		LOG_ERROR_RETURN(("AllocateAndInitializeSid failed: %s",OOBase::system_error_text()),false);
	}
	OOBase::SmartPtr<void,OOBase::Win32::SIDDestructor> pSIDEveryone(pSID);

	// Set read/write access for EVERYONE
	ea[1].grfAccessPermissions = FILE_GENERIC_READ | FILE_WRITE_DATA;
	ea[1].grfAccessMode = SET_ACCESS;
	ea[1].grfInheritance = NO_INHERITANCE;
	ea[1].Trustee.TrusteeForm = TRUSTEE_IS_SID;
	ea[1].Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
	ea[1].Trustee.ptstrName = (LPWSTR)pSIDEveryone;

	// Create a SID for the Network group.
	if (!AllocateAndInitializeSid(&SIDAuthNT, 1,
								  SECURITY_NETWORK_RID,
								  0, 0, 0, 0, 0, 0, 0,
								  &pSID))
	{
		LOG_ERROR_RETURN(("AllocateAndInitializeSid failed: %s",OOBase::system_error_text()),false);
	}
	OOBase::SmartPtr<void,OOBase::Win32::SIDDestructor> pSIDNetwork(pSID);

	// Deny all to NETWORK
	ea[2].grfAccessPermissions = FILE_ALL_ACCESS;
	ea[2].grfAccessMode = DENY_ACCESS;
	ea[2].grfInheritance = NO_INHERITANCE;
	ea[2].Trustee.TrusteeForm = TRUSTEE_IS_SID;
	ea[2].Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
	ea[2].Trustee.ptstrName = (LPWSTR)pSIDNetwork;

	// Create a new ACL
	DWORD dwErr = m_sd.SetEntriesInAcl(NUM_ACES,ea,NULL);
	if (dwErr != ERROR_SUCCESS)
		LOG_ERROR_RETURN(("SetEntriesInAcl failed: %s",OOBase::system_error_text(dwErr)),false);

	// Create a new security descriptor
	m_sa.nLength = sizeof(m_sa);
	m_sa.bInheritHandle = FALSE;
	m_sa.lpSecurityDescriptor = m_sd.descriptor();

	const char* pipe_name = "OmegaOnline";
	int err = 0;
	m_client_acceptor = m_proactor->accept_local(this,&accept_client,pipe_name,err,&m_sa);
	if (err)
		LOG_ERROR_RETURN(("Proactor::accept_local failed: '%s' %s",pipe_name,OOBase::system_error_text(err)),false);

	return true;
}
예제 #23
0
bool Indigo::Render::UIGroup::add_drawable(const OOBase::SharedPtr<UIDrawable>& drawable)
{
	if (!m_children.push_back(drawable))
		LOG_ERROR_RETURN(("Failed to insert drawable: %s",OOBase::system_error_text()),false);
	return true;
}