443 lines
17 KiB
Ruby
Executable File
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
|