resedit 1.3.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,192 @@
1
+ require 'resedit/app/app'
2
+ require 'resedit/app/app_command'
3
+ require 'resedit/mz/mz'
4
+ require 'resedit/mz/mzenv'
5
+
6
+
7
+ module Resedit
8
+
9
+ class MZCommand < AppCommand
10
+ def initialize
11
+ super(['mz'])
12
+ addParam('cmd', "mz command","")
13
+ addParam('p1', "mz command parameter","")
14
+ addParam('p2', "mz command parameter","")
15
+ addParam('p3', "mz command parameter","")
16
+ addParam('p4', "mz command parameter","")
17
+ addParam('p5', "mz command parameter","")
18
+ addOption('help', 'h', nil, 'help on mz commands')
19
+ @cmds = {
20
+ "help"=>[method(:help), "show help on mz commands", {"command" => "command to show help on"}],
21
+ "use"=>[method(:use), "select mz file", {"file" => "path to mz file"}],
22
+ "save"=>[method(:save), "save current file",{"filename" => "filename fir saving", "final"=>"don't save changes"}],
23
+ "close"=>[method(:close), "close file", {"file" => "path or id of file to close"}],
24
+ "print"=>[method(:info), "print info about mz objects", {"what" => "files/header/reloc/changes", "how" => "original/modified"}],
25
+ "append"=>[method(:append), "add bytes to current file", {"value" => "value", "type" => "value type", }],
26
+ "replace"=>[method(:replace), "replace added bytes", {"value" => "value", "type"=>"value type"}],
27
+ "change"=>[method(:change), "change bytes at offset", {"ofs" => "data ofset", "value" => "value", "disp" => "code/file", "type"=>"value type"}],
28
+ "revert"=>[method(:revert), "revert changes", {"ofs"=>"change offset/all"}],
29
+ "hex"=>[method(:hex), "print hex file", {"ofs" => "data offset", "size" => "data size", "how"=>"original/modified", "disp" => "code/file"}],
30
+ "dasm"=>[method(:dasm), "print disasm", {"ofs" => "data offset", "size" => "data size", "how"=>"original/modified"}],
31
+ }
32
+ @files = []
33
+ @cur = nil
34
+ end
35
+
36
+
37
+ def help(params)
38
+ if params['command']
39
+ raise "Unknown mz command: " + params['command'] if !@cmds[params['command']]
40
+ cmd = @cmds[params['command']]
41
+ puts(params['command'] + "\t-" + cmd[1])
42
+ if cmd[2]
43
+ puts
44
+ puts("params:")
45
+ cmd[2].each{|k,v|
46
+ puts k + "\t-" + v
47
+ }
48
+ end
49
+ else
50
+ puts("available mz commands:")
51
+ @cmds.each{|k,v|
52
+ puts k + "\t-" + v[1]
53
+ }
54
+ end
55
+ puts
56
+ end
57
+
58
+
59
+ def getfile(id)
60
+ return @cur if id == nil
61
+ i,res=MZEnv.instance.s2i_nt(id)
62
+ if res
63
+ raise "Bad file id: " + i.to_s if @files.length < i || i < 0
64
+ return @files[i]
65
+ end
66
+ @files.each{|mz|
67
+ return mz if mz.is?(id)
68
+ }
69
+ return nil
70
+ end
71
+
72
+
73
+ def info(params=nil)
74
+ what = params['what'] if params
75
+ if what == nil || what == "files"
76
+ if @files.length != 0
77
+ curid = -1
78
+ puts "Opened files:"
79
+ @files.each.with_index{|mz,i|
80
+ puts "#{i}:\t#{mz.path}"
81
+ curid=i if mz == @cur
82
+ }
83
+ puts "Current file: (#{curid}) #{@cur.path}"
84
+ puts
85
+ else
86
+ puts "No files opened"
87
+ end
88
+ else
89
+ raise "MZ file not loaded" if !@cur
90
+ @cur.print(what, params['how'])
91
+ end
92
+ end
93
+
94
+
95
+ def use(params)
96
+ App::get().col.on = true
97
+ mz = getfile(params['file'])
98
+ if mz==nil
99
+ mz = MZ.new(params['file'])
100
+ @files+=[mz]
101
+ end
102
+ @cur = mz
103
+ info()
104
+ end
105
+
106
+
107
+ def close(params)
108
+ mz = getfile(params['file'])
109
+ raise "File not found: "+fn if nil == fl
110
+ @files -= [mz]
111
+ @cur = nil if @cur == mz
112
+ mz.close()
113
+ mz = nil
114
+ @cur = @files[0] if !@cur && @files.length > 0
115
+ App::get().col.on = false if @files.length == 0
116
+ info()
117
+ end
118
+
119
+
120
+ def cur()
121
+ raise "No MZ selected." if !@cur
122
+ return @cur
123
+ end
124
+
125
+
126
+ def save(params)
127
+ cur().save(params['filename'], params['final'])
128
+ end
129
+
130
+
131
+ def append(params)
132
+ cur().append(params['value'], params['type'])
133
+ end
134
+
135
+
136
+ def replace(params)
137
+ cur().replace(params['value'], params['type'])
138
+ end
139
+
140
+
141
+ def change(params)
142
+ cur().change(params['ofs'], params['value'], params['disp'], params['type'])
143
+ end
144
+
145
+
146
+ def revert(params)
147
+ cur().revert(params['ofs'])
148
+ end
149
+
150
+
151
+ def hex(params)
152
+ cur().hex(params['ofs'], params['size'], params['how'], params['disp'])
153
+ end
154
+
155
+
156
+ def dasm(params)
157
+ cur().dasm(params['ofs'], params['size'], params['how'])
158
+ end
159
+
160
+
161
+ def job(params)
162
+ cmd = params['cmd']
163
+ if cmd.length==0 || File.exist?(cmd)
164
+ App::get().setShell('mz')
165
+ return if cmd.length == 0
166
+ params['p1'] = cmd
167
+ cmd = "use"
168
+ end
169
+ if cmd=="valueof"
170
+ cur().valueof(params['p1'], params['p2'])
171
+ return
172
+ end
173
+ if params['help']
174
+ params['command'] = params['help']
175
+ help(params)
176
+ return
177
+ end
178
+ raise "Unknown command: "+cmd if !@cmds[cmd]
179
+ scmd = @cmds[cmd]
180
+ if scmd[2]
181
+ scmd[2].keys.each.with_index{|k,i|
182
+ params[k] = params["p#{i+1}"]
183
+ params[k] = nil if params[k].length == 0
184
+ }
185
+ end
186
+ scmd[0].call(params)
187
+ end
188
+
189
+
190
+ end
191
+
192
+ end
@@ -0,0 +1,69 @@
1
+ require 'resedit/app/app_command'
2
+ require 'resedit'
3
+
4
+ module Resedit
5
+
6
+ class VersionCommand < AppCommand
7
+ def initialize
8
+ super(['version','--version'])
9
+ end
10
+ def job(params)
11
+ log('%s v%s %s. Resedit v%s.',App::get().name, App.get().version, App::get().copyright, Resedit::VERSION)
12
+ end
13
+ end
14
+
15
+ class ExitCommand < AppCommand
16
+ def initialize
17
+ super(['quit','q', 'exit'])
18
+ end
19
+ def job(params)
20
+ App::get().quit();
21
+ end
22
+ end
23
+
24
+
25
+ class HelpCommand < AppCommand
26
+ def initialize
27
+ super(['help','--help','-h','/?'])
28
+ addParam('command', 'help on specific command', '')
29
+ end
30
+ def job(params)
31
+ App.get().commands.each{|c|
32
+ puts c.names[0]
33
+ }
34
+ end
35
+ end
36
+
37
+
38
+ class ScriptCommand < AppCommand
39
+ def initialize
40
+ super(['script', '--script', '-s'])
41
+ addParam('file', 'script file')
42
+ end
43
+ def job(params)
44
+ App::get().logd("running script %s", params['file']);
45
+ script = []
46
+ text=File.open(params['file']).read
47
+ text.gsub!(/\r\n?/, "\n")
48
+ text.each_line {|line|
49
+ script += [App.get().parseCommand(line.chomp())]
50
+ }
51
+ script.each{|cmd|
52
+ cmd[0].run(cmd[1]) if cmd
53
+ }
54
+ end
55
+ end
56
+
57
+
58
+ class ShellCommand < AppCommand
59
+ def initialize
60
+ super(['shell'])
61
+ addParam('shell', 'script file', "")
62
+ end
63
+ def job(params)
64
+ App::get().setShell(params['shell'])
65
+ end
66
+ end
67
+
68
+
69
+ end
@@ -0,0 +1,60 @@
1
+ require 'resedit/app/io_commands'
2
+
3
+ module Resedit
4
+
5
+ class TextConvertCommand < ConvertCommand
6
+
7
+ def initialize(fname)
8
+ super('text', fname)
9
+ @font = nil
10
+ addOption('format','f',nil,'output file format')
11
+ addOption('encodinc','e',nil,'output file encoding')
12
+ end
13
+
14
+ def import(inname)
15
+ logd("importing text #{inname} to #{@resname}")
16
+ back = backup()
17
+ File.open(back,"rb"){|file|
18
+ @text = mktext(file, @params['format'], @params['encoding'])
19
+ @text.load(inname, linesCount())
20
+ StringIO.open("","w+b"){|stream|
21
+ pack(file, stream)
22
+ stream.seek(0)
23
+ File.open(@resname,"wb"){|out|
24
+ out.write(stream.read())
25
+ }
26
+ }
27
+ }
28
+ end
29
+
30
+
31
+ def export(outname)
32
+ logd("exporting txet #{@resname} to #{outname}")
33
+ File.open(@resname, "rb"){|file|
34
+ @text = mktext(file, @params['format'], @params['encoding'])
35
+ unpack(file) if @text
36
+ }
37
+ raise "Text not unpacked" if !@text
38
+ @text.save(outname)
39
+ end
40
+
41
+
42
+ def mktext(file, format, encoding)
43
+ raise "Not implemented."
44
+ end
45
+
46
+ def linesCount(file)
47
+ raise "Not implemented"
48
+ end
49
+
50
+ def pack(file, outstream)
51
+ raise "Not implemented."
52
+ end
53
+
54
+ def unpack(file)
55
+ raise "Not implemented."
56
+ end
57
+
58
+ end
59
+
60
+ end
@@ -0,0 +1,48 @@
1
+ module Resedit
2
+
3
+ class BitConverter
4
+
5
+ def self.bits2Bytes(bits, width)
6
+ i=0
7
+ res=[]
8
+ while i<bits.length
9
+ buf=0
10
+ cw=0
11
+ bsz=0
12
+ while cw<width
13
+ if bsz==0
14
+ buf = bits[i]
15
+ i+=1
16
+ bsz=8
17
+ end
18
+ bsz-=1
19
+ cw+=1
20
+ res << ((buf>>bsz) & 1)
21
+ end
22
+ end
23
+ return res
24
+ end
25
+
26
+ def self.bytes2Bits(bytes, rwidth, bwidth)
27
+ res=[]
28
+ for i in 0..(bytes.length/rwidth)-1
29
+ row=bytes[i*rwidth..i*rwidth+rwidth-1]
30
+ while row.length < bwidth*8
31
+ row << 0
32
+ end
33
+ b=0
34
+ for j in 0..row.length-1
35
+ b <<= 1
36
+ b |= row[j]
37
+ if (j+1)%8==0
38
+ res << (b & 0xFF)
39
+ b=0
40
+ end
41
+ end
42
+ end
43
+ return res
44
+ end
45
+
46
+ end
47
+
48
+ end
@@ -0,0 +1,82 @@
1
+ require 'resedit/font/font_char'
2
+ require 'resedit/image/image_factory'
3
+
4
+ module Resedit
5
+
6
+ class Font
7
+ attr_reader :count, :width, :height
8
+ attr_accessor :gridColor, :charColor, :userData, :widthColor
9
+
10
+ # charWidth, charHeight, characters count
11
+ def initialize(width, height, count=256)
12
+ @width, @height, @count = width, height, count
13
+ @gridColor = 0xFFEEEEEE
14
+ @charColor = 0xFF000000
15
+ @bgColor = 0xFFFFFFFF
16
+ @widthColor = 0xFFFF0000
17
+ @chars = {}
18
+ @userData = nil
19
+ end
20
+
21
+ def setChar(id, data, width=nil)
22
+ width=@width if !width
23
+ @chars[id] = FontChar.new(@width, @height, id, data, width)
24
+ end
25
+
26
+ def getChar(id)
27
+ @chars[id].data if @chars[id]
28
+ end
29
+
30
+ def minChar
31
+ return @chars.keys().min
32
+ end
33
+
34
+ def maxChar
35
+ return @chars.keys().max
36
+ end
37
+
38
+ def charWidth(id)
39
+ return nil if !@chars[id]
40
+ return @chars[id].realWidth ? @chars[id].realWidth : @width
41
+ end
42
+
43
+ def save(filename)
44
+ rows = @count/16 + (@count%16 == 0 ? 0 : 1)
45
+ img = Resedit.createImage(@width*16+17 , @height*rows+rows+1, filename)
46
+ img.fill(@bgColor)
47
+ #draw grid
48
+ for i in 0..16
49
+ img.vline(i*(@width+1), gridColor)
50
+ end
51
+ for j in 0..rows
52
+ img.hline(j*(@height+1), gridColor)
53
+ end
54
+ #draw letters
55
+ @chars.each { |idx,c|
56
+ x = idx%16
57
+ y = idx/16
58
+ x += 1+x*@width
59
+ y += 1+y*@height
60
+ c.draw(img, @charColor, x, y, @widthColor)
61
+ }
62
+ img.save(filename)
63
+ end
64
+
65
+ def load(filename)
66
+ img = Resedit.loadImage(filename)
67
+ rows = @count/16 + (@count%16 == 0 ? 0 : 1)
68
+ raise "Wrong image size" if (img.width!=@width*16+17 || img.height!=@height*rows+rows+1)
69
+ for idx in 0..@count-1
70
+ x = idx%16
71
+ y = idx/16
72
+ x += 1+x*@width
73
+ y += 1+y*@height
74
+ c = FontChar.new(width,height,idx)
75
+ c.scan(img, @charColor, x, y, @widthColor)
76
+ @chars[c.index] = c if c.data
77
+ end
78
+ end
79
+
80
+ end
81
+
82
+ end