resedit 1.3.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: b1b2afae945b0bfe8559010f9de3ecd21889a036
4
+ data.tar.gz: 9ec879c124f71706f9d5e90b988c88a1a7576457
5
+ SHA512:
6
+ metadata.gz: 85ac7bb3ccf16019f0314d6ffed992c47636ebe0a20451e4988a3afde9e03d67dea91dee2c0a003e619b018189538f962e45398bf6d058efde2796abdb85f6ea
7
+ data.tar.gz: 9cbbafcba61f4bc3fef2787a70f9c4e971d80edf508e56b979ee13e891a54431c110d0a1d94dd6dd7e2b1dd9980547a319c643a0c1ae36417468e2bfa5be59c5
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'resedit'
4
+
5
+ class App < Resedit::App
6
+ def initialize()
7
+ super('resedit',Resedit::VERSION, nil, true, "by bjfn (c) old-games.ru, 2017")
8
+ end
9
+ end
10
+
11
+ App.new().run()
@@ -0,0 +1,17 @@
1
+
2
+ require 'resedit/font/font'
3
+ require 'resedit/font/font_char'
4
+ require 'resedit/image/image_factory'
5
+ require 'resedit/text/escaper'
6
+ require 'resedit/text/text'
7
+ require 'resedit/app/app'
8
+ require 'resedit/text/huffman'
9
+ require 'resedit/app/font_convert'
10
+ require 'resedit/app/text_convert'
11
+ require 'resedit/convert/bitconv'
12
+ require 'resedit/mz/mz'
13
+
14
+
15
+ module Resedit
16
+ VERSION = "1.3.1"
17
+ end
@@ -0,0 +1,160 @@
1
+ require 'resedit/app/std_commands'
2
+ require 'resedit/app/mz_command'
3
+ require 'resedit/app/colorizer'
4
+ require 'logger'
5
+ require 'readline'
6
+
7
+ module Resedit
8
+
9
+ class App
10
+ HIST_FILE = "~/.resedithist"
11
+ attr_reader :name, :version, :commands, :logger, :copyright, :cmdInterface, :shell, :col
12
+
13
+ def self.get()
14
+ return @@instance
15
+ end
16
+
17
+ def initialize(name, version, commands, cmdInterface=true, copyright="(c) old-games.ru")
18
+ @@instance = self
19
+ @name, @version, @copyright = name, version, copyright
20
+ @cmdInterface = cmdInterface
21
+ @logger = Logger.new(STDOUT)
22
+ @logger.level= Logger::INFO
23
+ logger.formatter = proc { |severity, datetime, progname, msg|
24
+ msg
25
+ }
26
+ @shell = nil;
27
+ @commands = []
28
+ @commands += commands if commands
29
+ @commands += [HelpCommand.new(), VersionCommand.new(), ExitCommand.new(),
30
+ ScriptCommand.new(), MZCommand.new(), ShellCommand.new()]
31
+ @cmds={}
32
+ @commands.each{|c|
33
+ c.names.each{|n|
34
+ @cmds[n] = c;
35
+ }
36
+ }
37
+ @col = Colorizer.new(false)
38
+ end
39
+
40
+
41
+ def logd(fmt, *args)
42
+ @logger.debug(@col.gray(sprintf(fmt+"\n",*args)))
43
+ end
44
+ def log(fmt, *args)
45
+ @logger.info(sprintf(fmt+"\n",*args))
46
+ end
47
+ def loge(fmt, *args)
48
+ @logger.error(@col.red(sprintf(fmt+"\n",*args)))
49
+ end
50
+
51
+
52
+ def quit
53
+ begin
54
+ strt = Readline::HISTORY.length-64
55
+ open(File.expand_path(HIST_FILE),"w"){|f|
56
+ Readline::HISTORY.each.with_index{|ln,i|
57
+ f.write(ln+"\n") if i > strt
58
+ }
59
+ }
60
+ rescue
61
+ end
62
+ @stop=true
63
+ end
64
+
65
+ def setShell(sname)
66
+ sname=nil if sname.length==0
67
+ raise "Unknown shell: "+sname if sname && !@cmds[sname]
68
+ @shell = sname
69
+ end
70
+
71
+ def parseCommand(string)
72
+ cmd = []
73
+ string.split().each {|w|
74
+ if w[0]=='-' && w.length()>2 && w[1]!='-'
75
+ w[1..-1].each_char{|c|
76
+ cmd+=["-#{c}"]
77
+ }
78
+ else
79
+ cmd+=[w]
80
+ end
81
+ }
82
+ logd("parsing command #{cmd.to_s}")
83
+ return nil if cmd.length()==0 || cmd[0][0]=='#'
84
+ c = @cmds[cmd[0]]
85
+ raise "Unknown command: #{cmd[0]}" if !c
86
+ res=[]
87
+ prms = c.parseParams(cmd[1..-1])
88
+ return c,prms
89
+ end
90
+
91
+
92
+ def runCommand(string)
93
+ if @shell
94
+ cmd=string.split()[0]
95
+ if !@cmds[cmd] || !['Resedit::ExitCommand','Resedit::ShellCommand'].include?(@cmds[cmd].class.name)
96
+ string = @shell+" "+string
97
+ end
98
+ end
99
+ logd("running command %s", string)
100
+ cmd = parseCommand(string)
101
+ cmd[0].run(cmd[1])
102
+ end
103
+
104
+
105
+ def commandInterface()
106
+ @cmds['version'].run('')
107
+ begin
108
+ open(File.expand_path(HIST_FILE),"r").each_line {|ln|
109
+ ln.chomp!
110
+ Readline::HISTORY.push(ln) if ln.length>0
111
+ }
112
+ rescue
113
+ end
114
+ @stop=false
115
+ while(!@stop)
116
+ sh=@shell ? " "+@shell : ""
117
+ begin
118
+ cmd = Readline.readline("#{@name}#{sh}>", true)
119
+ Readline::HISTORY.pop if cmd=='' || (Readline::HISTORY.length>1 && cmd==Readline::HISTORY[-2])
120
+ runCommand(cmd)
121
+ rescue StandardError => e
122
+ puts @col.red("Error: #{e.to_s()}")
123
+ puts e.backtrace if App::get().logger.level == Logger::DEBUG
124
+ end
125
+ end
126
+ return 0
127
+ end
128
+
129
+
130
+ def run()
131
+ begin
132
+ if ARGV.length()==0
133
+ commandInterface() if @cmdInterface
134
+ if !@cmdInterface
135
+ puts "Command not specified. Known commands are:"
136
+ runCommand('help')
137
+ end
138
+ else
139
+ if (@cmds[ARGV[0]])
140
+ #check command
141
+ runCommand(ARGV.join(' '))
142
+ commandInterface() if @shell
143
+ elsif ARGV.length()==1 && File.exists?(ARGV[0])
144
+ #check script
145
+ runCommand('script '+ARGV[0])
146
+ else
147
+ raise "unknown command #{ARGV[0]}"
148
+ end
149
+ end
150
+ exit(0)
151
+ rescue StandardError => e
152
+ puts "Error: #{e.to_s()}"
153
+ puts e.backtrace
154
+ exit(1)
155
+ end
156
+ end
157
+
158
+ end
159
+
160
+ end
@@ -0,0 +1,100 @@
1
+ module Resedit
2
+
3
+ class AppCommand
4
+ attr_reader :names, :type, :params
5
+ def initialize(names, type=:std)
6
+ @names, @continue = names, type
7
+ @names = [@names] if not @names.kind_of?(Array)
8
+ @opts = {}
9
+ @params = []
10
+ @ohash = {}
11
+ addOption('verbose','v',false, 'verbose output')
12
+ addOption('unverbose',nil,false, 'unverbose output')
13
+ addOption('quiet','q',false, 'supress output')
14
+ addOption('color',nil,false, 'set colored output')
15
+ addOption('uncolor',nil,false, 'unset colored output')
16
+ end
17
+
18
+ def addParam(name, descr, default = nil, type=:std)
19
+ @params +=[{:name => name, :def => default, :descr => descr}]
20
+ end
21
+
22
+ def addOption(longname, shortname, param, descr, type = :std, setter= proc{|val, opt| val})
23
+ @opts[longname] = {:name => longname, :param => param, :descr => descr, :type => type, :setter => setter}
24
+ @ohash[shortname] = longname if shortname
25
+ end
26
+
27
+ def parseParams(params)
28
+ res = {}
29
+ pidx = 0
30
+ idx=0
31
+ @params.each{|p|
32
+ res[p[:name]] = p[:def]
33
+ }
34
+ @opts.each{|k,o|
35
+ res[k] = o[:param]
36
+ }
37
+ while idx<params.length
38
+ p = params[idx]
39
+ idx+=1
40
+ if p[0]=='-'
41
+ val = true
42
+ s=p.split('=')
43
+ if s.length==2
44
+ val=s[1]
45
+ p=s[0]
46
+ end
47
+ if (p[1]=='-')
48
+ opt = @opts[p[2..-1]]
49
+ else
50
+ opt = @opts[@ohash[p[1..-1]]] || @opts[p[1..-1]]
51
+ end
52
+ raise "Unknown option #{p}" if !opt
53
+ if opt[:param]!=false and val==true
54
+ raise "No option #{p} value" if idx>=params.length
55
+ val = params[idx]
56
+ idx+=1
57
+ end
58
+ proc = opt[:setter]
59
+ res[opt[:name]] = proc.call(val, opt)
60
+ else
61
+ raise "Unknown param #{p}" if !@params[pidx]
62
+ if (@params[pidx][:type] == :text)
63
+ p = params[idx-1..-1]
64
+ idx=params.length
65
+ end
66
+ res[@params[pidx][:name]] = p
67
+ pidx+=1
68
+ end
69
+ end
70
+ @params.each{|p|
71
+ raise "Expected parameter #{p[:name]}" if res[p[:name]]==nil
72
+ }
73
+ return res
74
+ end
75
+
76
+ def run(params)
77
+ App::get().logger.level = Logger::DEBUG if params['verbose']
78
+ App::get().logger.level = Logger::INFO if params['unverbose']
79
+ App::get().logger.level = Logger::ERROR if params['quiet']
80
+ App::get().col.on = true if params['color']
81
+ App::get().col.on = false if params['uncolor']
82
+ job(params)
83
+ end
84
+
85
+ def job(params)
86
+ raise "Unimplemented command #{@names[0]}"
87
+ end
88
+
89
+ def logd(fmt, *args)
90
+ App::get().logd(fmt,*args)
91
+ end
92
+ def log(fmt, *args)
93
+ App::get().log(fmt,*args)
94
+ end
95
+ def loge(fmt, *args)
96
+ App::get().loge(fmt,*args)
97
+ end
98
+ end
99
+
100
+ end
@@ -0,0 +1,34 @@
1
+ module Resedit
2
+
3
+ class Colorizer
4
+ GRAY = 90
5
+ RED = 91
6
+ GREEN = 92
7
+ YELLOW = 93
8
+ BLUE = 94
9
+ PURPLE = 95
10
+ CYAN = 96
11
+ WHITE = 97
12
+
13
+ attr_accessor :on
14
+
15
+ def initialize(on=true)
16
+ @on = on;
17
+ end
18
+
19
+ def color(col, text)
20
+ return text if !@on
21
+ return "\033[#{col}m#{text}\033[0m"
22
+ end
23
+
24
+ def gray(text) color(GRAY, text) end
25
+ def red(text) color(RED, text) end
26
+ def green(text) color(GREEN, text) end
27
+ def yellow(text) color(YELLOW, text) end
28
+ def blue(text) color(BLUE, text) end
29
+ def deep(text) color(PURPLE, text) end
30
+ def cyan(text) color(CYAN, text) end
31
+ def white(text) color(WHITE, text) end
32
+
33
+ end
34
+ end
@@ -0,0 +1,54 @@
1
+ require 'resedit/app/io_commands'
2
+
3
+ module Resedit
4
+
5
+ class FontConvertCommand < ConvertCommand
6
+
7
+ def initialize(fname)
8
+ super('font', fname)
9
+ @font = nil
10
+ end
11
+
12
+ def import(inname)
13
+ logd("importing font #{inname} to #{@resname}")
14
+ back = backup()
15
+ File.open(back,"rb"){|file|
16
+ @font = mkfont(file)
17
+ @font.load(inname+'.png')
18
+ StringIO.open("","w+b"){|stream|
19
+ pack(file, stream)
20
+ stream.seek(0)
21
+ File.open(@resname,"wb"){|out|
22
+ out.write(stream.read())
23
+ }
24
+ }
25
+ }
26
+ end
27
+
28
+
29
+ def export(outname)
30
+ logd("exporting font #{@resname} to #{outname}")
31
+ File.open(@resname, "rb"){|file|
32
+ @font = mkfont(file)
33
+ unpack(file) if @font
34
+ }
35
+ raise "Font not unpacked" if !@font
36
+ @font.save(outname+'.png')
37
+ end
38
+
39
+
40
+ def mkfont(file)
41
+ raise "Not implemented."
42
+ end
43
+
44
+ def pack(file, outstream)
45
+ raise "Not implemented."
46
+ end
47
+
48
+ def unpack(file)
49
+ raise "Not implemented."
50
+ end
51
+
52
+ end
53
+
54
+ end
@@ -0,0 +1,74 @@
1
+ require 'resedit/app/app_command'
2
+ require 'fileutils'
3
+
4
+ module Resedit
5
+
6
+ class ExportCommand < AppCommand
7
+ def initialize(name)
8
+ super([name])
9
+ end
10
+ def job(params)
11
+ raise 'Not implemented'
12
+ end
13
+ end
14
+
15
+
16
+ class ImportCommand < AppCommand
17
+ def initialize(name)
18
+ super([name])
19
+ end
20
+ def job(params)
21
+ raise 'Not implemented'
22
+ end
23
+ end
24
+
25
+
26
+ class ConvertCommand < AppCommand
27
+
28
+ attr_reader :fname
29
+
30
+
31
+ def initialize(name, fname)
32
+ super([name])
33
+ addParam('action','import/export action')
34
+ addParam('file','file to import/export')
35
+ addOption('output','o',nil,'converted file name')
36
+ @fname=fname
37
+ end
38
+
39
+
40
+ def getOutName()
41
+ return File.basename(@resname,File.extname(@resname))
42
+ end
43
+
44
+ def backup()
45
+ bname=@resname+'.bak'
46
+ FileUtils.cp(@resname,bname) if ! File.exist?(bname)
47
+ return bname
48
+ end
49
+
50
+ def job(params)
51
+ @params=params
52
+ @resname=params['file']
53
+ fname = getOutName()
54
+ fname = params['output'] if params['output']
55
+ if params['action']=='import'
56
+ import(fname)
57
+ elsif params['action']=='export'
58
+ export(fname)
59
+ else
60
+ raise "Unknown action #{params['action']}. import or export expected."
61
+ end
62
+
63
+ end
64
+
65
+ def import(infile)
66
+ raise 'Not implemented'
67
+ end
68
+
69
+ def export(outfile)
70
+ raise 'Not implemented'
71
+ end
72
+ end
73
+
74
+ end