Beispiel #1
0
        public static int Main(string[] args)
        {
            bool showHelp = false;
            bool dumpAllObjectImages = false;
            bool dumpAllRoomImages = false;
            string input = null;
            var scripts = new List<int>();
            var scriptObjects = new List<int>();
            var scriptRooms = new List<int>();
            var rooms = new List<int>();
            var objects = new List<int>();

            Initialize();

            var options = new OptionSet()
            {
                { "f=", "The input file",   v => input = v },
                { "s|script=", "the global script number to dump", (int s) => scripts.Add(s) },
                { "so|script_object=", "the object number whose script has to be dumped", (int s) => scriptObjects.Add(s) },
                { "sr|script_room=", "the room number whose script has to be dumped", (int s) => scriptRooms.Add(s) },
                { "r|room=", "the room image to dump", (int r) => rooms.Add(r) },
                { "ra", "dump all object images",ra => dumpAllRoomImages = ra != null },
                { "o|object=", "the object images to dump",(int o) => objects.Add(o) },
                { "oa", "dump all object images",oa => dumpAllObjectImages = oa != null },
                { "h|help",  "show this message and exit",  v => showHelp = v != null }
            };

            try
            {
                options.Parse(args);
            }
            catch (OptionException)
            {
                System.Console.WriteLine("Try `nsdump --help' for more information.");
                return 1;
            }

            if (input == null || showHelp)
            {
                Usage(options);
                return 0;
            }

            var resStream = typeof(GameManager).Assembly.GetManifestResourceStream(typeof(GameManager), "Nscumm.xml");
            var gm = GameManager.Create(resStream);
            var game = gm.GetInfo(input);
            if (game == null)
            {
                System.Console.Error.WriteLine("This game is not supported, sorry please contact me if you want to support this game.");
                return 1;
            }

            var index = ResourceManager.Load(game);
            var scriptDumper = new ScriptDumper(game);
            var dumper = new ConsoleDumper();

            // dump scripts
            foreach (var script in scripts)
            {
                var scr = index.GetScript(script);
                dumper.WriteLine("script " + script);
                scriptDumper.DumpScript(scr, dumper);
            }

            // dump room scripts
            if (scriptRooms.Count > 0)
            {
                var roomScripts = index.Rooms.Where(r => scriptRooms.Contains(r.Number)).ToList();
                foreach (var room in roomScripts)
                {
                    dumper.WriteLine("Room {0}", room.Number);
                    if (room.EntryScript.Data.Length > 0)
                    {
                        dumper.WriteLine("Entry");
                        scriptDumper.DumpScript(room.EntryScript.Data, dumper);
                        dumper.WriteLine();
                    }
                    if (room.ExitScript.Data.Length > 0)
                    {
                        dumper.WriteLine("Exit");
                        scriptDumper.DumpScript(room.ExitScript.Data, dumper);
                        dumper.WriteLine();
                    }
                    for (int i = 0; i < room.LocalScripts.Length; i++)
                    {
                        var ls = room.LocalScripts[i];
                        if (ls != null)
                        {
                            dumper.WriteLine("LocalScript {0}", i);
                            scriptDumper.DumpScript(ls.Data, dumper);
                        }
                    }
                    for (int i = 0; i < room.Objects.Count; i++)
                    {
                        var obj = room.Objects[i];
                        if (obj != null && obj.Script.Data.Length > 0)
                        {
                            var sb = new StringBuilder();
                            var decoder = new TextDecoder(sb);
                            var text = new ScummText(obj.Name);
                            text.Decode(decoder);

                            dumper.WriteLine("obj {0} {1}", obj.Number, sb);
                            var tmp = obj.Script.Offset;
                            var offsets = new long[] { 0, obj.Script.Data.Length }.Concat(obj.ScriptOffsets.Select(off => off.Value - tmp)).OrderBy(o => o).Distinct().ToList();
                            var scr = new List<Tuple<long, byte[]>>();
                            for (int j = 0; j < offsets.Count - 1; j++)
                            {
                                var len = offsets[j + 1] - offsets[j];
                                var d = new byte[len];
                                Array.Copy(obj.Script.Data, offsets[j], d, 0, len);
                                scr.Add(Tuple.Create(offsets[j], d));
                            }
                            foreach (var s in scr)
                            {
                                var keys = obj.ScriptOffsets.Where(o => o.Value - tmp == s.Item1).Select(o => o.Key).ToList();
                                foreach (var key in keys)
                                {
                                    dumper.WriteLine("{0}", (VerbsV0)key);
                                }
                                scriptDumper.DumpScript(s.Item2, dumper);
                            }
                            dumper.WriteLine();
                        }
                    }
                }
            }

            // dump object scripts
            if (scriptObjects.Count > 0)
            {
                var objs = index.Rooms.SelectMany(r => r.Objects).Where(o => scriptObjects.Contains(o.Number)).ToList();
                foreach (var obj in objs)
                {
                    dumper.WriteLine("obj {0} {1} {{", obj.Number, System.Text.Encoding.UTF8.GetString(obj.Name));
                    dumper.WriteLine("Script offset: {0}", obj.Script.Offset);
                    foreach (var off in obj.ScriptOffsets)
                    {
                        dumper.WriteLine("idx #{0}: {1}", off.Key, off.Value - obj.Script.Offset);
                    }
                    dumper.WriteLine("script");
                    scriptDumper.DumpScript(obj.Script.Data, dumper);
                }
            }

            // dump rooms
            if (dumpAllRoomImages || rooms.Count > 0)
            {
                var imgDumper = new ImageDumper(game);
                imgDumper.DumpRoomImages(index, dumpAllRoomImages ? null : rooms);
            }

            // dump objects
            if (dumpAllObjectImages || objects.Count > 0)
            {
                var imgDumper = new ImageDumper(game);
                imgDumper.DumpObjectImages(index, dumpAllObjectImages ? null : objects);
            }

            return 0;
        }
Beispiel #2
0
        void DumpRoomObjectImages(Room room, ObjectData obj, Gdi gdi)
        {
            var text = new ScummText(obj.Name);
            var sb = new StringBuilder();
            sb.Append("Object #" + obj.Number).Append(" ");

            var decoder = new TextDecoder(sb);
            text.Decode(decoder);

            sb.AppendFormat(" size: {0}x{1}", obj.Width, obj.Height);
            Console.WriteLine(sb);

            var j = 0;
            foreach (var img in obj.Images)
            {
//                try
//                {
                var screen = new VirtScreen(0, obj.Width, obj.Height, PixelFormat.Indexed8, 2);
                if (img.IsBomp)
                {
                    var bdd = new BompDrawData();
                    bdd.Src = img.Data;
                    bdd.Dst = new PixelNavigator(screen.Surfaces[0]);
                    bdd.X = 0;
                    bdd.Y = 0;

                    bdd.Width = obj.Width;
                    bdd.Height = obj.Height;

                    bdd.ScaleX = 255;
                    bdd.ScaleY = 255;
                    bdd.DrawBomp();
                }
                else
                {
                    gdi.DrawBitmap(img, screen, new Point(0, 0), obj.Width, obj.Height & 0xFFF8, 0, obj.Width / 8, room.Header.Width, DrawBitmaps.None, true);
                }

                using (var bmp = ToBitmap(room, screen))
                {
                    bmp.Save("obj_" + obj.Number + "_" + (++j) + ".png");
                }
//                }
//                catch (Exception e)
//                {
//                    Console.ForegroundColor = ConsoleColor.Red;
//                    Console.WriteLine(e);
//                    Console.ResetColor();
//                    Console.ReadLine();
//                }
            }
        }