Skip to content

Commit 40482fa

Browse files
committed
implement box data rewriting rules
1 parent 1b1e0f3 commit 40482fa

3 files changed

Lines changed: 47 additions & 5 deletions

File tree

Boxes/boxes.ml

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
exception BoxFittingError of string
33

44
type fillers =
5-
{ nop_code:int list ; nop_code_alt:int list; fillers:int list array }
5+
{ nop_code:int list ; nop_code_alt:int list; fillers:int list array; rewriting:(int list * int list) list }
66
let default_fillers () = {
77
nop_code =
88
if !Settings.game = Ruby || !Settings.game = Sapphire then
@@ -40,6 +40,8 @@ let default_fillers () = {
4040
[0x00 ; 0x00 ; 0xFF ; 0x00](* 00FF0000 *) ;
4141
[0x00 ; 0x00 ; 0x00 ; 0xFF](* FF000000 *) ;
4242
|]
43+
;
44+
rewriting = []
4345
}
4446

4547
let padding = [0x00 ; 0x00 ; 0x00 ; 0x00]
@@ -200,11 +202,32 @@ let fit_codes_into_boxes ?(fill_last=true) ?(fillers) ?(start=0) ?(exit=None) co
200202
let res = res@paddings in
201203
add_codes_after ~final:true fillers res ecode
202204
in
203-
(* Split by box *)
204205
let res, unformatted = List.map fst res, (res |> regroup_by 4 |> unpack) in
205206
let unformatted = unformatted |> List.map (fun (cmd, b) -> (Name.command_for_codes cmd, b)) in
207+
(* Apply rewriting rules *)
208+
let replace pos lst =
209+
let matches (pre,post) =
210+
let k = List.length pre in
211+
k = List.length post && k mod m = 0 &&
212+
let lst = List.drop pos lst |> List.take k in
213+
List.equal Int.equal lst pre
214+
in
215+
match List.find_opt matches fillers.rewriting with
216+
| None -> lst
217+
| Some (_,post) ->
218+
let k = List.length post in
219+
List.concat [List.take pos lst ; post ; List.drop (pos+k) lst]
220+
in
221+
let rec rewrite pos lst =
222+
if pos + m > List.length lst then lst
223+
else
224+
let lst = replace pos lst in
225+
rewrite (pos+m) lst
226+
in
227+
let res = rewrite 0 res in
228+
(* Split by box *)
206229
let res = split_raw_into_boxes ~fill_last res in
207-
(* If a box has a padding... *)
230+
(* If a box has a padding... replace with nop_code or nop_code_alt *)
208231
let res = res |> List.mapi (fun i lst ->
209232
let pos = modulo (-i*(name_size+1)) m in
210233
let rec replace_if_padding first pos lst =

Boxes/boxes.mli

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
exception BoxFittingError of string
33

44
type fillers =
5-
{ nop_code:int list ; nop_code_alt:int list; fillers:int list array }
5+
{ nop_code:int list ; nop_code_alt:int list; fillers:int list array; rewriting:(int list * int list) list }
66
val default_fillers : unit -> fillers
77

88
val fit_codes_into_boxes :

Main/ace_common.ml

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,19 @@ let compare_and_print_commands fmt data descr exit =
3333
in
3434
aux data descr false 0
3535

36+
let parse_rewrite str =
37+
let parse_code s =
38+
let n = String.length s in
39+
if n mod 8 <> 0 then failwith "Invalid byte sequence length" ;
40+
List.init (n / 2) (fun i -> int_of_string ("0x" ^ String.sub s (i * 2) 2))
41+
in
42+
let parse_rule s =
43+
match String.split_on_char ':' s with
44+
| [pre; post] -> (parse_code pre, parse_code post)
45+
| _ -> failwith "Invalid rule format"
46+
in
47+
List.map parse_rule (String.split_on_char ';' str)
48+
3649
let main fmt env (headers,headers2) parsed exit =
3750
let onlyraw =
3851
match Preprocess.get_param headers "onlyraw" with
@@ -73,6 +86,12 @@ let main fmt env (headers,headers2) parsed exit =
7386
| HInt i -> Name.codes_for_command i
7487
| _ -> failwith "Invalid headers."
7588
in
89+
let rewriting =
90+
match Preprocess.get_param headers "rewrite" with
91+
| HNone -> default_fillers.rewriting
92+
| HString str -> parse_rewrite str
93+
| _ -> failwith "Invalid headers."
94+
in
7695
let fill_last =
7796
match Preprocess.get_param headers "fill",
7897
Preprocess.get_param headers2 "fill" with
@@ -95,7 +114,7 @@ let main fmt env (headers,headers2) parsed exit =
95114
Format.fprintf fmt "@." ; None
96115
end else
97116
try
98-
let fillers = { Boxes.fillers; Boxes.nop_code; Boxes.nop_code_alt } in
117+
let fillers = { Boxes.fillers; Boxes.nop_code; Boxes.nop_code_alt; Boxes.rewriting } in
99118
let (boxes_codes, unformatted) =
100119
if !Settings.hex_box_mode
101120
then (Boxes.fit_codes_into_hex_boxes ~exit res, [])

0 commit comments

Comments
 (0)