ROM Hack Narc files and their contents

advancewars161

Member
OP
Newcomer
Joined
Apr 21, 2009
Messages
6
Trophies
0
XP
1
Country
United States
I am trying to get the images from a game, specifically Advance Wars: Days of Ruin. I see some files that look promising using Ndsts but they are in the .narc format. I looked around online to see what the heck to do after that, but I found nothing what so ever. I had extracted the contents with NARC Explorer 2, and came up with .cg .cl and .sc files. (specifically, wallp_ending.narc extracted to wallp_ending.cg, wallp_ending.cl, and wallp_ending.sc)

Could someone please explain what I'm either doing wrong or just not doing period? Thanks in advance.
 

DarthNemesis

Well-Known Member
Member
Joined
Feb 19, 2008
Messages
1,210
Trophies
0
XP
260
Country
United States
advancewars161 said:
I am trying to get the images from a game, specifically Advance Wars: Days of Ruin. I see some files that look promising using Ndsts but they are in the .narc format. I looked around online to see what the heck to do after that, but I found nothing what so ever. I had extracted the contents with NARC Explorer 2, and came up with .cg .cl and .sc files. (specifically, wallp_ending.narc extracted to wallp_ending.cg, wallp_ending.cl, and wallp_ending.sc)

Could someone please explain what I'm either doing wrong or just not doing period? Thanks in advance.
Most likely...
cl = color palette
cg = individual tile graphics
sc = tile map forming full picture

The image is broken up in this way so that duplicate or palette-swapped tiles only have to be stored once. It will be fairly complicated to build the image... have you considered taking screenshots in an emulator as an alternative?
 

advancewars161

Member
OP
Newcomer
Joined
Apr 21, 2009
Messages
6
Trophies
0
XP
1
Country
United States
Well, the image I am wanting to try and grab is at the end of the game, so i figured that it would just be quicker to try to rip it straight from the game.

By complicated, do you mean that it will be time consuming, hard to piece it together, or both?


I'd also like to know how people would make their own sprites and put them into any game they have, if that's not too much to ask.
 

DarthNemesis

Well-Known Member
Member
Joined
Feb 19, 2008
Messages
1,210
Trophies
0
XP
260
Country
United States
The cg and sc files are LZ77-compressed, so they have to be unpacked first.

Code:
/*
* Created by SharpDevelop.
* User: DarthNemesis
* Date: 4/20/2009
* Time: 10:14 PM
*/

using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Windows.Forms;

namespace Test2
{
	///
	/// Description of MainForm.
	///
	public partial class MainForm : Form
	{
		private Color[] palette;
		private Bitmap[] tiles;
		private Bitmap image;
		
		public MainForm()
		{
			InitializeComponent();
		}
		
		void MainFormLoad(object sender, EventArgs e)
		{
			string baseName = "wallp_ending";
			FileStream file;
			BinaryReader reader;
			if (!File.Exists(baseName + ".cl") || !File.Exists(baseName + ".cg") || !File.Exists(baseName + ".sc"))
			{
				MessageBox.Show("Cannot find all wallp_ending files.");
				return;
			}
			file = new FileStream(baseName + ".cl", FileMode.Open, FileAccess.Read);
			reader = new BinaryReader(file);
			ReadPalette(reader);
			reader.Close();
			
			file = new FileStream(baseName + ".cg", FileMode.Open, FileAccess.Read);
			reader = new BinaryReader(file);
			ReadTiles(reader);
			reader.Close();
			
			file = new FileStream(baseName + ".sc", FileMode.Open, FileAccess.Read);
			reader = new BinaryReader(file);
			ReadImage(reader);
			reader.Close();
			
			panelImage.Width = image.Width;
			panelImage.Height = image.Height;
			panelImage.Invalidate();
		}
		
		private Color ReadColor(BinaryReader reader)
		{
			ushort code = reader.ReadUInt16();
			int r = (code & 0x001F) > 2;
			int b = (code & 0x7C00) >> 7;
			return System.Drawing.Color.FromArgb(r, g, b);
		}
		
		private void ReadPalette(BinaryReader reader)
		{
			uint numColors = 16;
			palette = new Color[numColors];
			for (int i = 0; i < numColors; i++)
			{
				palette = ReadColor(reader);
			}
		}
		
		private Bitmap ReadTile(BinaryReader reader)
		{
			Bitmap tile = new Bitmap(8, 8);
			byte remainder = 0;
			bool lowByte = true;
			for (int y = 0; y < 8; y++)
			{
				for (int x = 0; x < 8; x++)
				{
					byte curColorIndex = 0;
					if (lowByte)
					{
						remainder = reader.ReadByte();
						curColorIndex = (byte)(remainder & 0x0F);
						remainder >>= 4;
						lowByte = false;
					}
					else
					{
						curColorIndex = remainder;
						lowByte = true;
					}
					tile.SetPixel(x, y, palette[curColorIndex]);
				}
			}
			return tile;
		}
		
		private void ReadTiles(BinaryReader reader)
		{
			uint numTiles = (uint)reader.BaseStream.Length / 32;
			tiles = new Bitmap[numTiles];
			for (int i = 0; i < numTiles; i++)
			{
				tiles = ReadTile(reader);
			}
		}
		
		private void ReadImage(BinaryReader reader)
		{
			int MAX_X = 32;
			int MAX_Y = 64;
			image = new Bitmap(8*MAX_X, 8*MAX_Y);
			Graphics g = Graphics.FromImage(image);
			for (int y = 0; y < MAX_Y; y++)
			{
				for (int x = 0; x < MAX_X; x++)
				{
					ushort tileIndex = reader.ReadUInt16();
					g.DrawImageUnscaled(tiles[tileIndex], 8*x, 8*y);
				}
			}
			g.Dispose();
		}
		
		void PanelImagePaint(object sender, PaintEventArgs e)
		{
			Graphics g = panelImage.CreateGraphics();
			g.DrawImageUnscaled(image, 0, 0);
			g.Dispose();
		}
	}
}

As for making custom images, you'd have to do the opposite - take a starter image and break it apart into individual tiles, mapping each one appropriately in the screen coords file. A bit more complicated.
 
Last edited by DarthNemesis,

advancewars161

Member
OP
Newcomer
Joined
Apr 21, 2009
Messages
6
Trophies
0
XP
1
Country
United States
Ok, so I've been trying to use that code to extract the other pictures. My problem is now that, when I try to put it together in SharpDevelop, I get
'test3.MainForm.Dispose(bool)': no suitable method found to override (CS0115) - C:\~\SharpDevelop Projects\test3\test3\MainForm.Designer.cs:22,27
as an error.

I'll admit that I do not know what I am doing, but I did change the baseName to the file I currently have out. I chose windows application; should I have gone with something else?

Also, I managed to use the lzssdemo thing to extract the lz77, but I don't know if it worked.


Reason I'm trying is because I don't know exactly which file is the image I'd like and I don't want to make someone else get all the images just for me.
 

DarthNemesis

Well-Known Member
Member
Joined
Feb 19, 2008
Messages
1,210
Trophies
0
XP
260
Country
United States
advancewars161 said:
My problem is now that, when I try to put it together in SharpDevelop, I get
'test3.MainForm.Dispose(bool)': no suitable method found to override (CS0115) - C:\~\SharpDevelop Projects\test3\test3\MainForm.Designer.cs:22,27
as an error.
You may need to do a few things in the Design tab.
1) Create a panel and rename it panelImage.
2) Add event handlers (lightning bolt icon in the Properties view) for the form and the panel. Select the background form and double click Behavior -> Load to generate MainFormLoad, then select panelImage and double click Paint to generate PanelImagePaint.

If that doesn't get rid of the error, post the line that's causing the error.

As for dealing with LZ77, here's a drag-and-drop utility I made: BatchLZ77 v1.1
 

advancewars161

Member
OP
Newcomer
Joined
Apr 21, 2009
Messages
6
Trophies
0
XP
1
Country
United States
Well, I added a "User Control" template from the Projects window (on the left), right-click, add new item, in the c# windows app. changed name from usercontrol1.cs to panelImage.cs. Don't know if that was the panel you are speaking of.

Found the Lightning bolt and put MainFormLoad and PanelImagePaint in.

Now I get these errors
An object reference is required for the non-static field, method, or property 'System.Windows.Forms.Control.Width.get' (CS0120) - C:\~\SharpDevelop Projects\fin\fin\MainForm.cs:56,13
An object reference is required for the non-static field, method, or property 'System.Windows.Forms.Control.Height.get' (CS0120) - C:\~\SharpDevelop Projects\fin\fin\MainForm.cs:57,13
An object reference is required for the non-static field, method, or property 'System.Windows.Forms.Control.Invalidate()' (CS0120) - C:\~\SharpDevelop Projects\fin\fin\MainForm.cs:58,13
An object reference is required for the non-static field, method, or property 'System.Windows.Forms.Control.CreateGraphics()' (CS0120) - C:\~\SharpDevelop Projects\fin\fin\MainForm.cs:137,26


Also, thank you very much for the lz77 utility!
 

DarthNemesis

Well-Known Member
Member
Joined
Feb 19, 2008
Messages
1,210
Trophies
0
XP
260
Country
United States
advancewars161 said:
Well, I added a "User Control" template from the Projects window (on the left), right-click, add new item, in the c# windows app. changed name from usercontrol1.cs to panelImage.cs. Don't know if that was the panel you are speaking of.
No, not a custom component. In the bar on the left there's a Tools tab, go to Windows Forms -> Panel.
 

Machow8

Member
Newcomer
Joined
Mar 18, 2020
Messages
19
Trophies
0
Age
33
XP
613
Country
Brazil
You may need to do a few things in the Design tab.
1) Create a panel and rename it panelImage.
2) Add event handlers (lightning bolt icon in the Properties view) for the form and the panel. Select the background form and double click Behavior -> Load to generate MainFormLoad, then select panelImage and double click Paint to generate PanelImagePaint.

If that doesn't get rid of the error, post the line that's causing the error.

As for dealing with LZ77, here's a drag-and-drop utility I made.

Hi,

I decompressed all Advance Wars DS and Days of Ruin files..

How do i extract their sprites now?

Thanks.
 

Site & Scene News

Popular threads in this forum

General chit-chat
Help Users
    Xdqwerty @ Xdqwerty: damn wifi