Files
gtav-src/tools_ng/script/misc/data_mk_scaleform_rpf.rb
2025-09-29 00:52:08 +02:00

443 lines
17 KiB
Ruby
Executable File

#
# File:: %RS_TOOLSROOT%/script/misc/data_mk_scaleform_rpf.rb
# Description:: Make a scaleform ZIP file. It looks through the directory
# art/UI/Swf and all of it's sub directories, and upon finding a
# gfx file it searches for any DDS files located in the same
#
# Author:: David Evans <dave.evans@rockstarnorth.com>
# Author:: David Muir <david.muir@rockstarnorth.com>
# Date:: 26 August 2010 (rewritten: 31 March 2011)
#
# The refactor on 31 March 2011 makes this script far more generic with the
# new way the assets are layed out. There are no hard-coded paths here.
#
#-----------------------------------------------------------------------------
# Uses
#-----------------------------------------------------------------------------
require 'pipeline/config/projects'
require 'pipeline/config/project'
require 'pipeline/os/file'
require 'pipeline/os/getopt'
require 'pipeline/os/path'
require 'pipeline/util/environment'
require 'pipeline/projectutil/data_convert'
require 'pipeline/projectutil/data_texture'
require 'pipeline/projectutil/data_zip'
require 'pipeline/scm/perforce'
include Pipeline
include Pipeline::ProjectUtil
#----------------------------------------------------------------------------
# Constants
#----------------------------------------------------------------------------
OPTIONS = [
[ '--convert', '-c', OS::Getopt::BOOLEAN, 'specify if you want the output file to run through a platform converstion locally'],
[ '--debug', '-d', OS::Getopt::BOOLEAN, 'display debug information.' ]
]
EXPORT_GFX = '$(toolsbin)/SwfToGfx/gfxexport.exe'
#EXPORT_GFX_ARGS = '-i DDS -qp -sd -rescale nearest -gradients -gi DDS'
EXPORT_GFX_ARGS = '-i DDS -d0 -fc -fcm -sd -rescale nearest -gradients -gi DDS'
ROOT_SWF = '$(root)/UI/NG/Swf'
ROOT_GFX = '$(root)/UI/NG/Gfx'
ROOT_EXPORT = '$(export)/data/cdimages'
CL_DESCRIPTION = 'Automatic gfx export script for Next Gen'
# List of SWF files that we do NOT want an ITD produced (probably because they
# are produced in a different way, e.g. fonts).
NO_TEXTURE_PACKING = [
'gfxfontlib',
'font_lib_efigs',
'font_lib_korean',
'font_lib_japanese',
'font_lib_chinese',
'startup',
'pause_menu_pages_settings',
'pause_menu_store_content',
'introscrn',
'tattoo_buttons',
'yoga_buttons'
]
# List of additional files to be packed into the generic zip file.
ADDITIONAL_GENERIC_FILES = [
OS::Path::combine( ROOT_SWF, 'generic/ADDITIONAL_ITD/*.itd.zip' )
]
#----------------------------------------------------------------------------
# Functions
#----------------------------------------------------------------------------
# Process a single SWF file.
def process_swf( p4, cl, r, e, log, gfx_dir, swf_file )
log.info( "\tProcessing SWF: #{swf_file}..." )
swf_name = OS::Path::get_basename( swf_file )
gfx_texture_dir = gfx_dir
FileUtils::mkdir_p( gfx_dir ) \
unless ( File::directory?( gfx_dir ) )
FileUtils::mkdir_p( gfx_texture_74dir ) \
unless ( File::directory?( gfx_texture_dir ) )
component_name = OS::Path::get_basename( swf_file )
gfx_filename = OS::Path::combine( gfx_dir, "#{component_name}.gfx" )
itd_filename = OS::Path::combine( gfx_dir, "#{component_name}.itd.zip" )
# Export GFX and DDS files from SWF.
p4.run_edit( gfx_filename ) if ( File::exists?( gfx_filename ) )
p4.run_edit( itd_filename ) if ( File::exists?( itd_filename ) )
command = e.subst( "#{EXPORT_GFX} -o #{gfx_dir} -d #{gfx_texture_dir} #{EXPORT_GFX_ARGS} #{swf_file}" )
log.debug( command )
system( command )
p4.run_add( gfx_filename ) if ( File::exists?( gfx_filename ) )
p4.run_add( itd_filename ) if ( File::exists?( itd_filename ) )
p4.run_reopen( '-c', cl.to_s, gfx_filename ) if ( File::exists?( gfx_filename ) )
p4.run_reopen( '-c', cl.to_s, itd_filename ) if ( File::exists?( itd_filename ) )
# Package up TXD (if required).
textures = OS::FindEx::find_files( OS::Path::combine( gfx_texture_dir, swf_name, '*.dds' ) )
if ( ( textures.size > 0 ) and ( not NO_TEXTURE_PACKING.include?( swf_name ) ) ) then
itd_filename = OS::Path::combine( gfx_dir, swf_name + '.itd.zip' )
file_list = []
textures.each do |texture|
filename = OS::Path::get_filename( texture )
filepath = OS::Path::get_directory( texture )
entry = {}
entry[:src] = texture
entry[:dst] = filename
file_list << entry
tcs_file = make_sure_scaleform_tcs_exists( p4, cl, texture )
tcl_file = make_sure_scaleform_tcl_exists( p4, cl, texture )
tcl_filename = OS::Path::get_filename( tcl_file )
tcl_entry = {}
tcl_entry[:src] = tcl_file
tcl_entry[:dst] = tcl_filename
file_list << tcl_entry
end
ProjectUtil::data_zip_create( itd_filename, file_list, false )
end
end
def make_sure_scaleform_tcl_exists( p4, changelist, texture )
c = Pipeline::Config.instance( )
assets = c.project.assets
tcl_file = OS::Path.remove_extension( texture )
tcs_file = tcl_file
tcl_file.gsub!( c.project.root, "" )
tcs_file.gsub!( c.project.root, "" )
tcl_file = OS::Path::combine( assets, 'metadata/textures', tcl_file) + ".tcl"
p4.run_sync( tcl_file )
if (not File::exists?( tcl_file ) ) then
tcs_dir = OS::Path::get_directory( tcl_file )
FileUtils::mkdir_p( tcs_dir ) \
unless ( File::directory?( tcs_dir ) )
File.open( tcl_file, 'w+' ) do |file|
file.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n")
file.write("<rage__CTextureConversionSpecification>\n")
file.write("<parent>${RS_ASSETS}/metadata/textures#{tcs_file}</parent>\n")
# file.write("<sourceTexture>#{texture}</sourceTexture>\n")
file.write("</rage__CTextureConversionSpecification>\n")
end
end
tcl_file
end
#
# == Description
# Create an compressed texture pipeline TCS file for a specific texture.
# The location for the TCS file is under $(assets)/metadata/textures
# relative to the location in $(art).
#
def make_sure_scaleform_tcs_exists( p4, changelist, texture )
c = Pipeline::Config.instance( )
assets = c.project.assets
tcs_file = OS::Path.remove_extension( texture )
tcs_file.gsub!( c.project.root, "" )
tcs_file = OS::Path::combine( assets, 'metadata/textures', tcs_file) + ".tcs"
p4.run_sync( tcs_file )
if (not File::exists?( tcs_file ) ) then
tcs_dir = OS::Path::get_directory( tcs_file )
FileUtils::mkdir_p( tcs_dir ) \
unless ( File::directory?( tcs_dir ) )
is_gradient = File::fnmatch?( "*_g*.tcs", tcs_file )
File.open( tcs_file, 'w+' ) do |file|
file.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n")
file.write("<rage__CTextureConversionSpecification>\n")
file.write("<parent>${RS_ASSETS}/metadata/textures/templates/ui/UI_Default</parent>\n") unless ( is_gradient )
file.write("<parent>${RS_ASSETS}/metadata/textures/templates/ui/UI_Gradient</parent>\n") if ( is_gradient )
# file.write("<sourceTexture>#{texture}</sourceTexture>\n")
file.write("</rage__CTextureConversionSpecification>\n")
end
end
p4.run_edit_or_add( tcs_file )
p4.run_reopen( '-c', changelist, tcs_file )
tcs_file
end
# Process a single zip file.
def process_zip( p4, cl, r, e, log, zip_dir, zip_file, zip_input_files, is_generic = false, is_platform = false )
log.info( "Checking out #{zip_file}..." )
p4.run_edit( zip_file )
log.info( "Creating #{zip_file}..." )
file_list = []
zip_input_files.each do |export_file|
entry = {}
entry[:src] = export_file
entry[:dst] = OS::Path::get_filename( export_file )
file_list << entry
end
if ( is_generic ) then
ADDITIONAL_GENERIC_FILES.each do |dependency_file|
dependency_input = e.subst( dependency_file )
if ( ::File::file?( dependency_input ) ) then
entry = {}
entry[:src] = dependency_input
entry[:dst] = OS::Path::get_filename( dependency_input )
file_list << entry
else
# Assume its a directory with wildcard.
files = OS::FindEx::find_files( dependency_input )
files.each do |filename|
filename_input = e.subst( filename )
entry = {}
entry[:src] = filename_input
entry[:dst] = OS::Path::get_filename( filename_input )
file_list << entry
end
end
end
else
additional_itd_dir = OS::Path::combine( zip_dir, "ADDITIONAL_ITD" )
if ( ::File::directory?( additional_itd_dir ) ) then
# Assume its a directory with wildcard.
files = OS::FindEx::find_files( additional_itd_dir + "/*.itd.zip" )
files.each do |filename|
filename_input = e.subst( filename )
entry = {}
entry[:src] = filename_input
entry[:dst] = OS::Path::get_filename( filename_input )
file_list << entry
end
end
end
ProjectUtil::data_zip_create( zip_file, file_list, true )
p4.run_add( zip_file )
log.info( "Moving #{zip_file} to Perforce CL ##{cl}..." )
p4.run_reopen( '-c', cl.to_s, zip_file )
end
#----------------------------------------------------------------------------
# Entry-Point
#----------------------------------------------------------------------------
if ( __FILE__ == $0 ) then
begin
g_AppName = OS::Path::get_basename( __FILE__ )
g_Config = Pipeline::Config.instance( )
g_Log = Log.new( g_AppName )
g_Debug = false
g_Project = g_Config.project
g_Project.load_config( )
#--------------------------------------------------------------------
# Parse Command Line
#--------------------------------------------------------------------
g_Options, g_Trailing = OS::Getopt::getopts( OPTIONS )
g_Debug = g_Options['debug'].nil? ? false : true
g_Convert = g_Options['convert'].nil? ? false : true
#--------------------------------------------------------------------
# Create the RAGE utility
#--------------------------------------------------------------------
r = RageUtils.new( g_Project, nil )
#--------------------------------------------------------------------
# Preforce creation and setup
#--------------------------------------------------------------------
Dir::chdir( g_Project.root )
g_Perforce = Pipeline::SCM::Perforce.new( )
g_Perforce.connect( )
g_ChangelistNumber = g_Perforce.create_changelist( CL_DESCRIPTION )
g_Log.info( "Changelist Number: #{g_ChangelistNumber}" )
if ( g_Trailing.size() > 0 ) then
#----------------------------------------------------------------
# Passed in a directory under SWF Root.
#----------------------------------------------------------------
g_Project.in_env( ) do |e|
swf_root = e.subst( OS::Path::normalise( ROOT_SWF ) )
gfx_root = e.subst( OS::Path::normalise( ROOT_GFX ) )
FileUtils::mkdir_p( gfx_root ) unless ( File::directory?( gfx_root ) )
# Fetch list of all resultant zip files to determine where this
# one is going; after initial processing.
zip_dirs = OS::FindEx::find_dirs( swf_root )
g_Trailing.each do |swf_file|
if ( File::file?( swf_file ) ) then
g_Log.info( "Processing SWF file: #{swf_file}..." )
zip_dir = OS::Path::get_directory( OS::Path::get_directory( swf_file ) )
gfx_dir = zip_dir.sub( swf_root, gfx_root )
process_swf( g_Perforce, g_ChangelistNumber, r, e, g_Log, gfx_dir, swf_file )
elsif ( File::directory?( swf_file ) )
g_Log.info( "Processing Scaleform ZIP #{swf_file}..." )
swf_file = OS::Path::normalise( swf_file )
gfx_dir = swf_file.sub( swf_root, gfx_root )
swf_files = OS::FindEx::find_files_recurse( OS::Path::combine( swf_file, '*.swf' ) )
swf_files.each do |swf_f|
process_swf( g_Perforce, g_ChangelistNumber, r, e, g_Log, gfx_dir, swf_f )
end
end
end
# Re-process the reconstructed SWF files by packing up the zips
# again from all of the local content.
g_Trailing.each do |swf_file|
export_zip = ''
if ( File::file?( swf_file ) )
zip_dir = OS::Path::get_directory( OS::Path::get_directory( swf_file ) )
gfx_dir = zip_dir.sub( swf_root, gfx_root )
export_zip = OS::Path::combine( ROOT_EXPORT, 'scaleform_' + OS::Path::get_filename( zip_dir ) + '.zip' )
export_zip = e.subst( export_zip )
export_files = OS::FindEx::find_files( OS::Path::combine( gfx_dir, '*.*' ) )
is_generic = ( 0 == "generic".casecmp( OS::Path::get_filename( zip_dir ) ) )
is_platform = ( OS::Path::get_filename( zip_dir ).starts_with( "platform" ) )
process_zip( g_Perforce, g_ChangelistNumber, r, e, g_Log, zip_dir, export_zip, export_files, is_generic, is_platform )
elsif ( File::directory?( swf_file ) )
swf_file = OS::Path::normalise( swf_file )
zip_dir = swf_file
gfx_dir = swf_file.sub( swf_root, gfx_root )
export_zip = OS::Path::combine( ROOT_EXPORT, 'scaleform_' + OS::Path::get_filename( zip_dir ) + '.zip' )
export_zip = e.subst( export_zip )
export_files = OS::FindEx::find_files( OS::Path::combine( gfx_dir, '*.*' ) )
is_generic = ( 0 == "generic".casecmp( OS::Path::get_filename( zip_dir ) ) )
is_platform = ( OS::Path::get_filename( zip_dir ).starts_with( "platform" ) )
process_zip( g_Perforce, g_ChangelistNumber, r, e, g_Log, zip_dir, export_zip, export_files, is_generic, is_platform )
end
#---------------------------------------------------------------------
# Do a platform conversation if required
#---------------------------------------------------------------------
if ( g_Convert )
ProjectUtil::data_convert_file( export_zip, true )
end
end
end
else
#----------------------------------------------------------------
# Loop through Swf paths; creating intermediate Gfx data.
#----------------------------------------------------------------
g_Project.in_env( ) do |e|
swf_root = e.subst( OS::Path::normalise( ROOT_SWF ) )
gfx_root = e.subst( OS::Path::normalise( ROOT_GFX ) )
FileUtils::mkdir_p( gfx_root ) unless ( File::directory?( gfx_root ) )
zip_dirs = OS::FindEx::find_dirs( swf_root )
zip_dirs.each do |zip_dir|
gfx_dir = zip_dir.sub( swf_root, gfx_root )
zip_swf_dirs = OS::FindEx::find_dirs( zip_dir )
zip_swf_dirs.each do |swf_dir|
g_Log.info( "Processing Scaleform ZIP #{OS::Path::get_directory( swf_dir )}..." )
swf_files = OS::FindEx::find_files( OS::Path::combine( swf_dir, '*.swf' ) )
swf_files.each do |swf_file|
process_swf( g_Perforce, g_ChangelistNumber, r, e, g_Log, gfx_dir, swf_file )
end
end
# Create resultant Scaleform ZIP file.
export_zip = OS::Path::combine( ROOT_EXPORT, 'scaleform_' + OS::Path::get_filename( zip_dir ) + '.zip' )
export_zip = e.subst( export_zip )
export_files = OS::FindEx::find_files( OS::Path::combine( gfx_dir, '*.*' ) )
is_generic = ( 0 == "generic".casecmp( OS::Path::get_filename( zip_dir ) ) )
is_platform = ( OS::Path::get_filename( zip_dir ).starts_with( "platform" ) )
process_zip(g_Perforce, g_ChangelistNumber, r, e, g_Log, zip_dir, export_zip, export_files, is_generic, is_platform )
end
end
end
# Revert unchanged files.
g_Perforce.run_revert( '-a', '-c', g_ChangelistNumber.to_s )
# Clean up all automatically constructed changelists if they are empty.
pending_list = g_Perforce.run_changes( '-l', '-s', 'pending', '-u', g_Perforce.user, '-c', g_Perforce.client )
description_list = []
pending_list.each do |changelist|
next unless ( 0 == CL_DESCRIPTION.strip.casecmp( changelist['desc'].strip ) )
g_Perforce.run_change( '-d', changelist['change'] )
g_Log.info( "\nDeleting changelist #{changelist['change']} from pending list" )
end
g_Perforce.disconnect( )
rescue Exception => ex
puts "Unhandled exception: #{ex.message}"
puts ex.backtrace().join("\n")
end
end
# %RS_TOOLSROOT%/script/misc/data_mk_scaleform_rpf.rb