Nicolas Cannasse 19 ani în urmă
părinte
comite
47c57a2007
4 a modificat fișierele cu 62 adăugiri și 13 ștergeri
  1. 7 1
      genjs.ml
  2. 9 4
      genneko.ml
  3. 32 5
      genswf8.ml
  4. 14 3
      main.ml

+ 7 - 1
genjs.ml

@@ -540,7 +540,7 @@ let generate_type ctx = function
 	| TClassDecl c -> if not c.cl_extern then generate_class ctx c
 	| TEnumDecl e -> generate_enum ctx e
 
-let generate file types =
+let generate file types hres =
 	let ctx = {
 		buf = Buffer.create 16000;
 		packages = Hashtbl.create 0;
@@ -550,6 +550,12 @@ let generate file types =
 		in_value = false;
 	} in
 	List.iter (generate_type ctx) types;
+	print ctx "js.Boot.__res = {}";
+	newline ctx;
+	Hashtbl.iter (fun name data ->
+		print ctx "js.Boot.__res[\"%s\"] = \"%s\"" (Ast.s_escape name) (Ast.s_escape data);
+		newline ctx;
+	) hres;
 	print ctx "js.Boot.__init()";
 	newline ctx;
 	List.iter (generate_static ctx) (List.rev ctx.statics);

+ 9 - 4
genneko.ml

@@ -366,14 +366,19 @@ let gen_packages h t =
 	in
 	loop [] (fst (type_path t))
 
-let gen_boot() =
-	call null_pos (field null_pos (gen_type_path null_pos (["neko"],"Boot")) "__init") []
+let gen_boot hres =
+	let loop name data acc = (name , gen_constant null_pos (TString data)) :: acc in
+	let objres = (EObject (Hashtbl.fold loop hres []),null_pos) in
+	(EBlock [
+		call null_pos (field null_pos (gen_type_path null_pos (["neko"],"Boot")) "__init") [];
+		EBinop ("=",field null_pos (gen_type_path null_pos (["neko"],"Boot")) "__res",objres),null_pos;
+	],null_pos)
 
-let generate file types =
+let generate file types hres =
 	let h = Hashtbl.create 0 in
 	let packs = List.concat (List.map (gen_packages h) types) in
 	let methods = List.map gen_type types in
-	let boot = gen_boot() in
+	let boot = gen_boot hres in
 	let vars = List.concat (List.map gen_static_vars types) in
 	let e = (EBlock (packs @ methods @ boot :: vars), null_pos) in
 	let neko_file = Filename.chop_extension file ^ ".neko" in

+ 32 - 5
genswf8.ml

@@ -426,6 +426,17 @@ let no_value ctx retval =
 (* -------------------------------------------------------------- *)
 (* Generation *)
 
+let rec gen_big_string ctx s =
+	let len = String.length s in
+	let max = 65000 in
+	if len <= max then
+		write ctx (APush [PString s])
+	else begin
+		write ctx (APush [PString (String.sub s 0 max)]);
+		gen_big_string ctx (String.sub s max (len - max));
+		write ctx AAdd;
+	end
+
 let rec gen_constant ctx c p =
 	match c with
 	| TInt s -> (try push ctx [VInt32 (Int32.of_string s)] with _ -> gen_constant ctx (TFloat s) p)
@@ -1116,7 +1127,7 @@ let gen_type_def ctx t =
 		setvar ctx VarStr;
 		PMap.iter (fun _ f -> gen_enum_field ctx f) e.e_constrs
 
-let gen_boot ctx =
+let gen_boot ctx hres =
 	let id = gen_type ctx (["flash"],"Boot") false in
 	(* r0 = Boot *)
 	push ctx [VStr id];
@@ -1128,7 +1139,23 @@ let gen_boot ctx =
 	write ctx AEval;
 	push ctx [VInt 1; VReg 0; VStr "__init"];
 	call ctx VarObj 0;
-	write ctx APop
+	write ctx APop;
+	(* r0.__res = hres *)
+	push ctx [VReg 0; VStr "__res"];
+	let count = ref 0 in
+	Hashtbl.iter (fun name data ->
+		(try 
+			ignore(String.index data '\000');
+			failwith ("Resource " ^ name ^ " does contain \\0 character than can't be used in Flash");
+		with Not_found -> ());
+		push ctx [VStr name];
+		gen_big_string ctx data;
+		incr count;
+	) hres;
+	push ctx [VInt (!count)];
+	write ctx AObject;
+	ctx.stack_size <- ctx.stack_size - (!count * 2);
+	write ctx AObjSet
 
 let gen_type_map ctx =
 	let packs = Hashtbl.create 0 in
@@ -1186,7 +1213,7 @@ let gen_type_map ctx =
 			write ctx AEval;
 			setvar ctx k
 		end
-	) ctx.types
+	) ctx.types	
 
 let to_utf8 str =
 	try
@@ -1216,7 +1243,7 @@ let convert_header ver (w,h,fps,bg) =
 let default_header ver =
 	convert_header ver (400,300,30.,0xFFFFFF)
 
-let generate file ver header infile types =
+let generate file ver header infile types hres =
 	let ctx = {
 		opcodes = DynArray.create();
 		code_pos = 0;
@@ -1238,7 +1265,7 @@ let generate file ver header infile types =
 	write ctx (AStringPool []);
 	List.iter (fun t -> gen_type_def ctx t) types;
 	gen_type_map ctx;
-	gen_boot ctx;
+	gen_boot ctx hres;
 	List.iter (gen_class_static_init ctx) (List.rev ctx.statics);
 	let idents = ctx.idents in
 	let idents = Hashtbl.fold (fun ident pos acc -> (ident,pos) :: acc) idents [] in

+ 14 - 3
main.ml

@@ -97,6 +97,7 @@ try
 	let swf_header = ref None in
 	let current = ref argv_start in
 	let next = ref (fun() -> ()) in
+	let hres = Hashtbl.create 0 in
 	Hashtbl.clear Parser.defines;
 	Hashtbl.iter (Hashtbl.add Parser.defines) base_defines;
 	Plugin.verbose := false;
@@ -150,6 +151,16 @@ try
 			with
 				_ -> raise (Arg.Bad "Invalid SWF header format")
 		),"<header> : define SWF header (width:height:fps:color)");
+		("-res",Arg.String (fun res ->
+			match ExtString.String.nsplit res "@" with
+			| [file; name] ->
+				let file = (try Plugin.find_file file with Not_found -> file) in
+				let data = Std.input_file ~bin:true file in
+				if Hashtbl.mem hres name then failwith ("Duplicate resource name " ^ name);
+				Hashtbl.add hres name data
+			| _ ->
+				raise (Arg.Bad "Invalid Resource format : should be file@name")
+		),"<file@name> : add a named resource file");
 		("-v",Arg.Unit (fun () -> Plugin.verbose := true),": turn on verbose mode");
 		("-prompt", Arg.Unit (fun() -> prompt := true),": prompt on error");
 		("-altfmt", Arg.Unit (fun() -> alt_format := true),": use alternative error output format");
@@ -206,13 +217,13 @@ try
 		| No -> ()
 		| Swf file ->
 			if !Plugin.verbose then print_endline ("Generating swf : " ^ file);
-			Genswf.generate file (!swf_version) (!swf_header) (!swf_in) types
+			Genswf.generate file (!swf_version) (!swf_header) (!swf_in) types hres
 		| Neko file ->
 			if !Plugin.verbose then print_endline ("Generating neko : " ^ file);
-			Genneko.generate file types
+			Genneko.generate file types hres
 		| Js file ->
 			if !Plugin.verbose then print_endline ("Generating js : " ^ file);
-			Genjs.generate file types
+			Genjs.generate file types hres
 		);
 		(match !xml_out with
 		| None -> ()