示例#1
0
void ShipSpinner::Draw()
{

	Graphics::Renderer *r = GetContext()->GetRenderer();

	Graphics::Renderer::StateTicket ticket(r);

	r->SetPerspectiveProjection(45.f, 1.f, 1.f, 10000.f);
	r->SetTransform(matrix4x4f::Identity());

	r->SetDepthTest(true);
	r->ClearDepthBuffer();

	r->SetLights(1, &m_light);

	Point pos(GetAbsolutePosition() + GetActiveOffset());
	Point size(GetActiveArea());

	r->SetViewport(pos.x, GetContext()->GetSize().y - pos.y - size.y, size.x, size.y);

	matrix4x4f rot = matrix4x4f::RotateXMatrix(m_rotX);
	rot.RotateY(m_rotY);
	rot[14] = -1.5f * m_model->GetDrawClipRadius();
	m_model->Render(r, rot, &m_params);
}
示例#2
0
	void tick(const std::weak_ptr<implementation>& self)
	{		
		try
		{
			produce_timer_.restart();

			std::map<int, safe_ptr<basic_frame>> frames;
		
			BOOST_FOREACH(auto& layer, layers_)			
				frames[layer.first] = basic_frame::empty();	

			tbb::parallel_for_each(layers_.begin(), layers_.end(), [&](std::map<int, layer>::value_type& layer) 
			{
				auto transform = transforms_[layer.first].fetch_and_tick(1);

				int hints = frame_producer::NO_HINT;
				if(format_desc_.field_mode != field_mode::progressive)
				{
					hints |= std::abs(transform.fill_scale[1]  - 1.0) > 0.0001 ? frame_producer::DEINTERLACE_HINT : frame_producer::NO_HINT;
					hints |= std::abs(transform.fill_translation[1]) > 0.0001 ? frame_producer::DEINTERLACE_HINT : frame_producer::NO_HINT;
				}

				if(transform.is_key)
					hints |= frame_producer::ALPHA_HINT;

				auto frame = layer.second.receive(hints);	
				
				auto frame1 = make_safe<core::basic_frame>(frame);
				frame1->get_frame_transform() = transform;

				if(format_desc_.field_mode != core::field_mode::progressive)
				{				
					auto frame2 = make_safe<core::basic_frame>(frame);
					frame2->get_frame_transform() = transforms_[layer.first].fetch_and_tick(1);
					frame1 = core::basic_frame::interlace(frame1, frame2, format_desc_.field_mode);
				}

				frames[layer.first] = frame1;
			});
			
			graph_->set_value("produce-time", produce_timer_.elapsed()*format_desc_.fps*0.5);
			
			std::shared_ptr<void> ticket(nullptr, [self](void*)
			{
				auto self2 = self.lock();
				if(self2)				
					self2->executor_.begin_invoke([=]{tick(self);});				
			});

			target_->send(std::make_pair(frames, ticket));

			graph_->set_value("tick-time", tick_timer_.elapsed()*format_desc_.fps*0.5);
			tick_timer_.restart();
		}
		catch(...)
		{
			layers_.clear();
			CASPAR_LOG_CURRENT_EXCEPTION();
		}		
	}
示例#3
0
void ModelSpinner::Draw()
{
	Graphics::Renderer *r = GetContext()->GetRenderer();

	Graphics::Renderer::StateTicket ticket(r);

	const float fov = 45.f;
	r->SetPerspectiveProjection(fov, 1.f, 1.f, 10000.f);
	r->SetTransform(matrix4x4f::Identity());

	r->SetDepthWrite(true);
	r->SetDepthTest(true);
	r->ClearDepthBuffer();

	r->SetLights(1, &m_light);

	Point pos(GetAbsolutePosition() + GetActiveOffset());
	Point size(GetActiveArea());

	r->SetViewport(pos.x, GetContext()->GetSize().y - pos.y - size.y, size.x, size.y);

	matrix4x4f rot = matrix4x4f::RotateXMatrix(m_rotX);
	rot.RotateY(m_rotY);
	const float dist = m_model->GetDrawClipRadius() / sinf(DEG2RAD(fov*0.5f));
	rot[14] = -dist;
	m_model->Render(rot);
}
示例#4
0
int main(int argc, char *argv[]) {

    for (int i=0; i<N; i++)
	printf("%i\n", ticket() );

    return EXIT_SUCCESS;
}
void VScrollPortal::Draw()
{
	PROFILE_SCOPED()
	SetScissor(true);

	float size[2];
	GetSize(size);

	m_scrollY = vscrollAdjust.GetValue();

	float toScroll = m_childSizeY - size[1];
	if (toScroll < 0) toScroll = 0;

	float scale[2];
	Screen::GetCoords2Pixels(scale);

	Graphics::Renderer *r = Gui::Screen::GetRenderer();
	Graphics::Renderer::MatrixTicket ticket(r, Graphics::MatrixMode::MODELVIEW);

	// scroll to whole pixel locations whatever the resolution
	r->Translate(0, floor((-m_scrollY*toScroll)/scale[1])*scale[1], 0);
	Container::Draw();

	SetScissor(false);
}
示例#6
0
文件: Context.cpp 项目: lwho/pioneer
void Context::Draw()
{
	Graphics::Renderer *r = GetRenderer();

	// Ticket for the viewport mostly
	Graphics::Renderer::StateTicket ticket(r);
	r->SetViewport(0, 0, m_width, m_height);

	// reset renderer for each layer
	for (std::vector<Layer*>::iterator i = m_layers.begin(); i != m_layers.end(); ++i) {
		r->SetOrthographicProjection(0, m_width, m_height, 0, -1, 1);
		r->SetTransform(matrix4x4f::Identity());
		r->SetClearColor(Color4f::BLACK);

		DrawWidget(*i);

		r->SetScissor(false);
	}

	if (m_mousePointer && m_mousePointerEnabled) {
		r->SetOrthographicProjection(0, m_width, m_height, 0, -1, 1);
		r->SetTransform(matrix4x4f::Identity());
		r->SetClearColor(Color4f::BLACK);
		DrawWidget(m_mousePointer);
		r->SetScissor(false);
	}
}
示例#7
0
文件: wad.cpp 项目: Swyter/wiiqt
const QByteArray Wad::Content( quint16 i )
{
    if( tmdData.isEmpty() || tikData.isEmpty() )
    {
        Err( "Can't decryte data without a TMD and ticket" );
        return QByteArray();
    }
    Ticket ticket( tikData );
    Tmd t( tmdData );
    if( partsEnc.size() != t.Count() || i >= partsEnc.size() )
    {
        Err( "I dont know whats going on some number is out of range and i dont like it" );
        return QByteArray();
    }
    QByteArray encData = partsEnc.at( i );

    AesSetKey( ticket.DecryptedKey() );

	QByteArray decData = AesDecrypt( t.Index( i ), encData );
    decData.resize( t.Size( i ) );
    QByteArray realHash = GetSha1( decData );
    if( realHash != t.Hash( i ) )
    {
        Err( QString( "hash doesnt match for content %1" ).arg( i ) );
        return QByteArray();
    }
    return decData;
}
示例#8
0
void GameLog::DrawHudMessages(Graphics::Renderer *r)
{
	Graphics::Renderer::StateTicket ticket(r);
	Graphics::RenderStateDesc rsd;
	rsd.depthTest  = false;
	rsd.depthWrite = false;
	Graphics::RenderState *prsd = r->CreateRenderState(rsd);

	//I'd rather render this as one string, but then we can't
	//have per-line fade - markup doesn't support alpha
	r->SetOrthographicProjection(0, m_screenSize.x, m_screenSize.y, 0, -1, 1);
	r->SetTransform(matrix4x4f::Identity());
	r->SetRenderState(prsd);

	const Color &c = Color::WHITE;

	float y = 0;
	for (auto it = m_messages.rbegin(); it != m_messages.rend(); ++it) {
		float alpha = 1.f;
		if (it->time > FADE_AFTER) {
			alpha = 1.0f - (float(it->time - FADE_AFTER) / float(FADE_TIME));
		}
		const Color textColour(c.r, c.g, c.b, Clamp(Uint32(alpha*255), 0U, 255U));
		m_font->RenderString(it->msg.c_str(), m_offset.x, m_offset.y + y, textColour);
		y -= m_lineHeight;
	}
}
示例#9
0
void ShipSpinnerWidget::Draw()
{
	float pos[2];
	GetAbsolutePosition(pos);

	m_params.time = Pi::game->GetTime();

	float guiscale[2];
	Gui::Screen::GetCoords2Pixels(guiscale);
	static float rot1, rot2;
	if (Pi::MouseButtonState(SDL_BUTTON_RIGHT)) {
		int m[2];
		Pi::GetMouseMotion(m);
		rot1 += -0.002*m[1];
		rot2 += -0.002*m[0];
	}
	else
	{
		rot1 += .5*Pi::GetFrameTime();
		rot2 += Pi::GetFrameTime();
	}

	glColor3f(0,0,0);
	glBegin(GL_QUADS);
		glVertex2f(0.0f, 0.0f);
		glVertex2f(0.0f, m_height);
		glVertex2f(m_width, m_height);
		glVertex2f(m_width, 0.0f);
	glEnd();

	Graphics::Renderer::StateTicket ticket(Pi::renderer);

	Pi::renderer->SetPerspectiveProjection(45.f, 1.f, 1.f, 10000.f);
	Pi::renderer->SetTransform(matrix4x4f::Identity());

	Pi::renderer->SetDepthTest(true);
	Pi::renderer->ClearDepthBuffer();

	Pi::renderer->SetLights(1, &m_light);
	Pi::renderer->SetViewport(
		int(roundf(pos[0]/guiscale[0])),
		int(roundf((Gui::Screen::GetHeight() - pos[1] - m_height)/guiscale[1])),
		int(m_width/guiscale[0]),
		int(m_height/guiscale[1]));
	
	matrix4x4f rot = matrix4x4f::RotateXMatrix(rot1);
	rot.RotateY(rot2);
	rot[14] = -1.5f * m_model->GetDrawClipRadius();

	m_model->Render(rot, &m_params);
}
示例#10
0
bool GPlayerAccess::ProcessMessage(GNetMsg & msg,int message)
{
	switch(message)
	{
	case IGM_ACCESS:
		{
			if(Valid())
			{
				GSocketAccess * sa=static_cast<GSocketAccess*>(socket);
				GTicketConnectionClient t_connection_client;
				msg.R(t_connection_client);
				if (*t_connection_client.access.target_location_ID == 0)
				{
					if (t_connection_client.access.target_gamestate_ID > 0)
					{
						strcpy(t_connection_client.access.target_location_ID, location_ID_from_gamestate_ID(t_connection_client.access.target_gamestate_ID).c_str());
					}
				}
				else
				{
					t_connection_client.access.target_gamestate_ID = gamestate_ID_from_location_ID(t_connection_client.access.target_location_ID);
				}

				sockaddr_in addr;
				socklen_t len=sizeof(addr);
				getpeername(socket->GetSocket(),(sockaddr*)&addr,&len);
				memcpy(&t_connection_client.client_host.addr_detected_by_server,&addr.sin_addr,4);

				t_connection_client.access.RID=GetRID();

				if (Service(ESTClientAccess)->GetOutQueueSize() >= global_serverconfig->net.ticket_queue_busy_limit ||
					Service(ESTClientAccess)->GetWaitQueueSize() >= global_serverconfig->net.ticket_queue_busy_limit)
				{
					MsgExt(IGM_CONNECTION_CLOSE).WT("server busy").A();
					return true;
				}

				GTicketConnectionPtr ticket(new GTicketConnection());
				Coerce(*ticket,t_connection_client);

				TicketInt(ESTClientAccess,IGMITIC_ACCESS,ticket);
				Coerce(sa->player_info,t_connection_client);
				sa->group_id = t_connection_client.access.group_ID;
			}
		}
		return true;
	}
	return false;
};
示例#11
0
void GameLog::DrawHudMessages(Graphics::Renderer *r)
{
	Graphics::Renderer::StateTicket ticket(r);
	Graphics::RenderStateDesc rsd;
	rsd.depthTest  = false;
	rsd.depthWrite = false;
	Graphics::RenderState *prsd = r->CreateRenderState(rsd);

	//I'd rather render this as one string, but then we can't
	//have per-line fade - markup doesn't support alpha
	r->SetOrthographicProjection(0, m_screenSize.x, m_screenSize.y, 0, -1, 1);
	r->SetTransform(matrix4x4f::Identity());
	r->SetRenderState(prsd);

	const Color &c = Color::WHITE;

	// (re)build buffers
	const size_t numMessages = m_messages.size();
	const bool bRefresh = (numMessages != m_prevMessages);
	// update message loop
	float y = 0;
	for (auto it = m_messages.rbegin(), itEnd = m_messages.rend(); it != itEnd; ++it) {
		float alpha = 1.f;
		if (it->time > FADE_AFTER) {
			alpha = 1.0f - (float(it->time - FADE_AFTER) / float(FADE_TIME));
		}
		Uint32 iAlpha(Clamp(Uint32(alpha*255), 0U, 255U));
		const Color textColour(c.r, c.g, c.b, iAlpha);

		// update only if things have changed or the buffer does not exist
		if (bRefresh || !it->m_vb.Valid() || iAlpha != it->m_prevAlpha || !it->m_prevoffset.ExactlyEqual(m_offset))
		{
			it->m_prevAlpha = iAlpha;
			it->m_prevoffset = m_offset;
			Graphics::VertexArray va(Graphics::ATTRIB_POSITION | Graphics::ATTRIB_DIFFUSE | Graphics::ATTRIB_UV0);
			m_font->PopulateString(va, it->msg.c_str(), m_offset.x, m_offset.y + y, textColour);
			it->m_vb.Reset( m_font->CreateVertexBuffer(va) );
		}

		m_font->RenderBuffer( it->m_vb.Get() );
		y -= m_lineHeight;
	}
	m_prevMessages = numMessages;
}
示例#12
0
  //----------------------------------------------------------------
  // InputArea::postponeSingleClickEvent
  //
  boost::shared_ptr<CancelableEvent::Ticket>
  InputArea::postponeSingleClickEvent(PostponeEvent & postponeEvent,
                                      int msec,
                                      QObject * view,
                                      const TVec2D & itemCSysOrigin,
                                      const TVec2D & rootCSysPoint) const
  {
    boost::shared_ptr<CancelableEvent::Ticket>
      ticket(new CancelableEvent::Ticket());

    ItemPtr itemPtr = self_.lock();
    boost::shared_ptr<InputArea> inputAreaPtr =
      boost::dynamic_pointer_cast<InputArea, Item>(itemPtr);

    postponeEvent.postpone(msec, view, new SingleClickEvent(ticket,
                                                            inputAreaPtr,
                                                            itemCSysOrigin,
                                                            rootCSysPoint));
    return ticket;
  }
示例#13
0
void CMonitorSessionDlg::OnItemOpenViewerDlg(){
	
	POSITION pos=m_list.GetFirstSelectedItemPosition();
	int nItem=m_list.GetNextSelectedItem(pos);
	CString name=m_list.GetItemText(nItem,1);

	if(pService->GetSockByName(name)->bMonitor==FALSE) return ;

	CString ticket(pService->GetSockByName(name)->ticket);
	
	CViewerDlg dlg;	
	
	dlg.Create(CViewerDlg::IDD);
	dlg.SetWindowText(name);
	dlg.ShowWindow(SW_NORMAL);	
	dlg.Connect((LPTSTR)(LPCTSTR)ticket);
	
	dlg.RunModalLoop();

}
示例#14
0
文件: wad.cpp 项目: Swyter/wiiqt
Wad::Wad( const QList< QByteArray > &stuff, bool encrypted )
{
	ok = false;
    if( stuff.size() < 3 )
    {
        Err( "Cant treate a wad with < 3 items" );
        return;
    }

    tmdData = stuff.at( 0 );
    tikData = stuff.at( 1 );

    Ticket ticket( tikData );
    Tmd t( tmdData );

    quint16 cnt = stuff.size() - 2;
    if( cnt != t.Count() )
    {
        Err( "The number of items given doesnt match the number in the tmd" );
        return;
    }
    for( quint16 i = 0; i < cnt; i++ )
    {
        QByteArray encData;

        if( encrypted )
        {
            encData = stuff.at( i + 2 );
        }
        else
        {
            QByteArray decDataPadded = PaddedByteArray( stuff.at( i + 2 ), 0x40 );
            //doing this here in case there is some other object that is using the AES that would change the key on us
            AesSetKey( ticket.DecryptedKey() );
			encData = AesEncrypt( t.Index( i ), decDataPadded );
        }
        partsEnc << encData;
    }
    ok = true;

}
示例#15
0
	void tick(const std::weak_ptr<implementation>& self)
	{		
		try
		{
			produce_timer_.restart();

			std::map<int, safe_ptr<basic_frame>> frames; //fix g++ warning
			//std::map<int, std::shared_ptr<basic_frame>> frames;

			for(auto it = layers_.begin(); it != layers_.end(); ++it)
				frames[it->first] = make_safe<core::basic_frame>(basic_frame::empty());

			tbb::parallel_for_each(layers_.begin(), layers_.end(), [&](std::map<int, std::shared_ptr<layer>>::value_type& layer)
			{
				auto transform = transforms_[layer.first].fetch_and_tick(1);

				int hints = frame_producer::NO_HINT;
				if(format_desc_.field_mode != field_mode::progressive)
				{
					hints |= std::abs(transform.fill_scale[1]  - 1.0) > 0.0001 ? frame_producer::DEINTERLACE_HINT : frame_producer::NO_HINT;
					hints |= std::abs(transform.fill_translation[1]) > 0.0001 ? frame_producer::DEINTERLACE_HINT : frame_producer::NO_HINT;
				}

				if(transform.is_key)
					hints |= frame_producer::ALPHA_HINT;

				auto frame = layer.second->receive(hints);	
				auto layer_consumers_it = layer_consumers_.find(layer.first);
				if (layer_consumers_it != layer_consumers_.end())
				{
					auto consumer_it = (*layer_consumers_it).second | boost::adaptors::map_values;
					tbb::parallel_for_each(consumer_it.begin(), consumer_it.end(), [&](decltype(*consumer_it.begin()) layer_consumer) 
					{
						layer_consumer->send(frame);
					});
				}

				auto frame1 = make_safe<core::basic_frame>(frame);
				frame1->get_frame_transform() = transform;

				if(format_desc_.field_mode != core::field_mode::progressive)
				{				
					auto frame2 = make_safe<core::basic_frame>(frame);
					frame2->get_frame_transform() = transforms_[layer.first].fetch_and_tick(1);
					frame1 = core::basic_frame::interlace(frame1, frame2, format_desc_.field_mode);
				}

				frames[layer.first] = std::move(frame1);
			});

			// Tick the transforms that does not have a corresponding layer.
			BOOST_FOREACH(auto& elem, transforms_)
				if (layers_.find(elem.first) == layers_.end())
					elem.second.fetch_and_tick(format_desc_.field_mode != core::field_mode::progressive ? 2 : 1);
			
			graph_->set_value("produce-time", produce_timer_.elapsed()*format_desc_.fps*0.5);

			std::shared_ptr<void> ticket(nullptr, [=](void*)
			{
				auto self2 = self.lock();
				if(self2)				
					self2->executor_.begin_invoke([=]{tick(self);});
			});

			target_->send(std::make_pair(frames, ticket));
			//comment out due to g++ warning fix */

			graph_->set_value("tick-time", tick_timer_.elapsed()*format_desc_.fps*0.5);
			tick_timer_.restart();
		}
		catch(...)
		{
			layers_.clear();
			CASPAR_LOG_CURRENT_EXCEPTION();
		}		
	}
示例#16
0
文件: wad.cpp 项目: Swyter/wiiqt
Wad::Wad( const QByteArray &stuff )
{
	ok = false;
	if( !stuff.size() )//prevent error text when it isnt required
		return;
	if( stuff.size() < 0x80 )//less than this and there is definitely nothing there
	{
		Err( "Size is < 0x80" );
		return;
	}

	QByteArray copy = stuff;
	QBuffer b( &copy );
	b.open( QIODevice::ReadOnly );

	quint32 tmp;
	if(b.read( (char*)&tmp, 4 ) != 4)
	{
		b.close();
		Err( "Can't read header size" );
		return;
	}
	if( qFromBigEndian( tmp ) != 0x20 )
	{
		b.close();
		hexdump(stuff, 0, 0x10);
		Err( "Bad header size" );
		return;
	}
	b.read( (char*)&tmp, 4 );
	tmp = qFromBigEndian( tmp );
	if( tmp != 0x49730000 &&
		tmp != 0x69620000 &&
		tmp != 0x426b0000 )
	{
		b.close();
		hexdump( stuff, 0, 0x40 );
		Err( "Bad file magic word" );
		return;
	}

	quint32 certSize;
	quint32 tikSize;
	quint32 tmdSize;
	quint32 appSize;
	quint32 footerSize;

	b.read( (char*)&certSize, 4 );
	certSize = qFromBigEndian( certSize );

	b.seek( 0x10 );
	b.read( (char*)&tikSize, 4 );
	tikSize = qFromBigEndian( tikSize );
	b.read( (char*)&tmdSize, 4 );
	tmdSize = qFromBigEndian( tmdSize );
	b.read( (char*)&appSize, 4 );
	appSize = qFromBigEndian( appSize );
	b.read( (char*)&footerSize, 4 );
	footerSize = qFromBigEndian( footerSize );

	b.close();//close the buffer, the rest of the data can be checked without it

	//sanity check this thing
	quint32 s = stuff.size();
	if( s < ( RU( certSize, 0x40 ) + RU( tikSize, 0x40 ) + RU( tmdSize, 0x40 ) + RU( appSize, 0x40 ) + RU( footerSize, 0x40 ) ) )
	{
		Err( "Total size is less than the combined sizes of all the parts that it is supposed to contain" );
		return;
	}

	quint32 pos = 0x40;
	certData = stuff.mid( pos, certSize );
	pos += RU( certSize, 0x4 );
	tikData = stuff.mid( pos, tikSize );
	pos += RU( tikSize, 0x40 );
	tmdData = stuff.mid( pos, tmdSize );
	pos += RU( tmdSize, 0x40 );

	Ticket ticket( tikData );
	Tmd t( tmdData );

	//the constructor for Ticket may have fixed a bad key index.  replace the data just incase it did
	tikData = ticket.Data();

	//hexdump( tikData );
	//hexdump( tmdData );

	if( ticket.Tid() != t.Tid() )
		qWarning() << "wad contains 2 different TIDs";

	quint32 cnt = t.Count();
	//qDebug() << "Wad contains" << hex << cnt << "contents";

	//another quick sanity check
	quint32 totalSize = 0;
	for( quint32 i = 0; i < cnt; i++ )
		totalSize += t.Size( i );

	if( totalSize > appSize )
	{
		Err( "Size of all the apps in the tmd is greater than the size in the wad header" );
		return;
	}
	//read all the contents, check the hash, and remember the data ( still encrypted )
	for( quint32 i = 0; i < cnt; i++ )
	{

		quint32 s = RU( t.Size( i ), 0x40 );
		//qDebug() << "content" << i << "is at" << hex << pos
		//        << "with size" << s;
		QByteArray encData = stuff.mid( pos, s );
		pos += s;

		//doing this here in case there is some other object that
		//is using the AES that would change the key on us
		AesSetKey( ticket.DecryptedKey() );

		QByteArray decData = AesDecrypt( t.Index( i ), encData );
		decData.resize( t.Size( i ) );
		QByteArray realHash = GetSha1( decData );
		if( realHash != t.Hash( i ) )
		{
			Err( QString( "hash doesnt match for content %1" ).arg( i ) );
		}
		partsEnc << encData;
	}
	//wtf?  some VC titles have a full banner as the footer?  maybe somebody's wad packer is busted
	//QByteArray footer = stuff.mid( pos, stuff.size() - pos );
	//qDebug() << "footer";
	//hexdump( footer );
	ok = true;
}
示例#17
0
文件: wad.cpp 项目: Swyter/wiiqt
const QByteArray Wad::Data( quint32 magicWord, const QByteArray &footer )
{
	//qDebug() << "Wad::Data" << hex << magicWord << footer.size();
	if( !partsEnc.size() || tmdData.isEmpty() || tikData.isEmpty() || ( certData.isEmpty() && globalCert.isEmpty() ) )
	{
		Err( "Dont have all the parts to make a wad" );
		return QByteArray();
	}

	//do some brief checks to make sure that wad is good
	Ticket ticket( tikData );
	Tmd t( tmdData );
	if( t.Tid() != ticket.Tid() )
	{
		Err( "Ticket and TMD have different TID" );
		return QByteArray();
	}
	if( partsEnc.size() != t.Count() )
	{
		Err( "Dont have enough contents according to the TMD" );
		return QByteArray();
	}

	//everything seems in order, try to make the thing
	QByteArray cert = certData.isEmpty() ? globalCert : certData;
	quint32 certSize = cert.size();
	quint32 tikSize = ticket.SignedSize();
	quint32 tmdSize = t.SignedSize();
	quint32 appSize = 0;
	quint32 footerSize = footer.size();

	//add all the app sizes together and check that they match the TMD
	quint16 cnt = t.Count();
	for( quint16 i = 0; i < cnt; i++ )
	{
		quint32 s = RU( partsEnc.at( i ).size(), 0x40 );
		if( RU( t.Size( i ), 0x40 ) != s )
		{
			Err( QString( "Size of content %1 is bad ( %2, %3, %4 )" )
                 .arg( i )
                 .arg( t.Size( i ), 0, 16 )
				 .arg( RU( t.Size( i ), 0x40 ), 0, 16 )
                 .arg( s, 0, 16 ) );
			return QByteArray();
		}
		appSize += s;
	}

	QByteArray header( 0x20, '\0' );
	QBuffer buf( &header );
	buf.open( QIODevice::WriteOnly );

	quint32 tmp = qFromBigEndian( 0x20 );//header size
	buf.write( (const char*)&tmp, 4 );
	tmp = qFromBigEndian( magicWord );//magic word
	buf.write( (const char*)&tmp, 4 );
	tmp = qFromBigEndian( certSize );
	buf.write( (const char*)&tmp, 4 );
	buf.seek( 0x10 );
	tmp = qFromBigEndian( tikSize );
	buf.write( (const char*)&tmp, 4 );
	tmp = qFromBigEndian( tmdSize );
	buf.write( (const char*)&tmp, 4 );
	tmp = qFromBigEndian( appSize );
	buf.write( (const char*)&tmp, 4 );
	tmp = qFromBigEndian( footerSize );
	buf.write( (const char*)&tmp, 4 );
	buf.close();
	//hexdump( header, 0, 0x20 );

	QByteArray ret = PaddedByteArray( header, 0x40 ) + PaddedByteArray( cert, 0x40 );
	//make sure we dont have the huge ticket and TMD that come when downloading from NUS
	QByteArray tik = tikData;
	tik.resize( tikSize );
	tik = PaddedByteArray( tik, 0x40 );

	QByteArray tm = tmdData;
	tm.resize( tmdSize );
	tm = PaddedByteArray( tm, 0x40 );

	//hexdump( tik );
	//hexdump( tm );

	ret += tik + tm;
	for( quint16 i = 0; i < cnt; i++ )
	{
		ret += PaddedByteArray( partsEnc.at( i ), 0x40 );
	}
	ret += footer;
	return ret;
}
示例#18
0
文件: wad.cpp 项目: Swyter/wiiqt
Wad::Wad( QDir dir )
{
	ok = false;
	QFileInfoList tmds = dir.entryInfoList( QStringList() << "*.tmd" << "tmd.*", QDir::Files );
	if( tmds.isEmpty() )
	{
		Err( "TMD not found" );
		return;
	}
	tmdData = ReadFile( tmds.at( 0 ).absoluteFilePath() );
	if( tmdData.isEmpty() )
		return;
	QFileInfoList tiks = dir.entryInfoList( QStringList() << "*.tik" << "cetk", QDir::Files );
	if( tiks.isEmpty() )
	{
		Err( "Ticket not found" );
		return;
	}
	tikData = ReadFile( tiks.at( 0 ).absoluteFilePath() );
	if( tikData.isEmpty() )
		return;

	Tmd t( tmdData );
	Ticket ticket( tikData );

	//make sure to only add the tmd & ticket without all the cert mumbo jumbo
	tmdData = t.Data();
	tikData = ticket.Data();
	t = Tmd( tmdData );
	ticket = Ticket( tikData );

	quint16 cnt = t.Count();

	bool tmdChanged = false;
	for( quint16 i = 0; i < cnt; i++ )
	{
		QByteArray appD = ReadFile( dir.absoluteFilePath( t.Cid( i ) + ".app" ) );
		if( appD.isEmpty() )
		{
			Err( t.Cid( i ) + ".app not found" );
			return;
		}

		if( (quint32)appD.size() != t.Size( i ) )
		{
			t.SetSize( i, appD.size() );
			tmdChanged = true;
		}
		QByteArray realHash = GetSha1( appD );
		if( t.Hash( i ) != realHash )
		{
			t.SetHash( i, realHash );
			tmdChanged = true;
		}
		AesSetKey( ticket.DecryptedKey() );
		appD = PaddedByteArray( appD, 0x40 );
		QByteArray encData = AesEncrypt( t.Index( i ), appD );
		partsEnc << encData;
	}
	//if something in the tmd changed, fakesign it
	if( tmdChanged )
	{
		if( !t.FakeSign() )
		{
			Err( "Error signing the wad" );
			return;
		}
		else
		{
			tmdData = t.Data();
		}
	}
	QFileInfoList certs = dir.entryInfoList( QStringList() << "*.cert", QDir::Files );
	if( !certs.isEmpty() )
	{
		certData = ReadFile( certs.at( 0 ).absoluteFilePath() );
	}
	ok = true;
}