Looking for specific Color Palette

Post here about all aspects of D2 mod making whether it's information, problems or whatever. Please specify whether your post is relating to Classic D2 or the Expansion.

Moderator: Nizari

d1ck
Posts: 36
Joined: Wed Mar 09, 2011 7:12 pm

Looking for specific Color Palette

Post by d1ck » Mon Jul 02, 2012 8:02 pm

I am creating a program that will let me take the base item picture and apply the Diablo 2 Color palettes on to them.
I am using c# image class which has a property called palette which you can specify as an array of colors

I am trying to dump the RGB colors of the following palettes however, I do not know where to find these palettes.
I looked in d2data.mpq /items/palette/... but it did not contain the colors that item shades are associated with.

Black
White
Orange

Light Yellow
Light Red
Light Gold
Light Blue
Light Purple

Crystal Blue
Crystal Red
Crystal Green

Dark Yellow
Dark Red
Dark Gold
Dark Green
Dark Blue

I would appreciate if someone could tell me the location of the palette file for the above colors or maybe you have created a dump of them as a byte array that I could use
Last edited by d1ck on Tue Jul 03, 2012 11:25 am, edited 1 time in total.

User avatar
k0r3l1k
Moderator
Angel
Posts: 631
Joined: Sun Sep 09, 2007 3:11 am
Location: Arizona, Prescott
United States of America

Re: Where can i download color palette.dat files?

Post by k0r3l1k » Mon Jul 02, 2012 10:39 pm

the color.dat files are binary files that tell the game what colors to use for overlays and blending in directdraw mode. you have to parse them yourself to find what colors you need. there is a section near the end that dictates color modifiers for certain colors.
Image

User avatar
Paul Siramy
Retired staff
Principality
Posts: 2828
Joined: Sat May 25, 2002 2:39 pm
Location: La Garenne Colombes (near Paris)
France

Hand-picked

Re: Looking for specific Color Palette

Post by Paul Siramy » Wed Jul 04, 2012 8:15 pm

d1ck" wrote:I am creating a program that will let me take the base item picture and apply the Diablo 2 Color palettes on to them.
I am using c# image class which has a property called palette which you can specify as an array of colors
Something like this tool I supose ?
I am trying to dump the RGB colors of the following palettes however, I do not know where to find these palettes.
I looked in d2data.mpq /items/palette/... but it did not contain the colors that item shades are associated with.
(...)
Dark Blue
You're mixing palettes and colormaps. The inventory items are in DC6 format and are using the comon colors of each act palette. But each item can be declined into several color sets, when beeing applied a certain colormap. That's what my tool does : drawing all the possible color sets on an item. Source code is included (less than 400 lines of code).

d1ck
Posts: 36
Joined: Wed Mar 09, 2011 7:12 pm

Re: Looking for specific Color Palette

Post by d1ck » Thu Jul 05, 2012 4:08 am

Paul Siramy, wow, this is way more than I expected. Thank you very much, its EXACTLY what I was planning on doing. And your code is very simple to understand :D

d1ck
Posts: 36
Joined: Wed Mar 09, 2011 7:12 pm

Re: Looking for specific Color Palette

Post by d1ck » Thu Jul 05, 2012 10:46 pm

Since Paul was so gracious by sharing his code, I thought it would only be fair to share my port:

This class can transform the first frame of a dc6 to a diffident palette color, I only implemented first frame because I am using item dc6's, but it should be trivial to add for all frames.

Managed .net port of dc6color.c, using c#

Code: Select all

/*
 *   @Author: d1ck @ d2mods.com, phrozenkeep
 *	@Filename: D2Palette.cs
 *   @Last Edit: 5 July 2012
 *	@Description: Port of Paul Siramy's dc6color.c
 *	@Notes: main method uses dc6, palette, and color dat files, you can load them as embedded resources (byte[])
 *
 */
 
using System;
using System.Drawing;
using System.Runtime.InteropServices;
using ColorShift.Properties;

namespace ColorShift
{
    public struct DC6_Header_S
    {
        public int version;        // 0x00000006
        public int sub_version;    // 0x00000001
        public int zeros;          // 0x00000000
        public int termination;    // 0xEEEEEEEE or 0xCDCDCDCD //BYTE ARRAY!
        public int directions;     // 0x000000xx
        public int frames_per_dir; // 0x000000xx
    }

    public struct DC6_FRAME_HEADER_S
    {
        public int flip;
        public int width;
        public int height;
        public int offset_x;
        public int offset_y; // from bottom border, NOT upper border
        public int zeros;
        public int next_block;
        public int length;
    } 

    class D2Palette
    {
        private Bitmap current { get; set; }
        private int shift_color { get; set; }
        private string file { get; set; }

        private int dc6_frame_ptr;
        private DC6_Header_S dc6_header;
        private DC6_FRAME_HEADER_S dc6_frame_header;

        private Color[] palette = new Color[256];
        private Color[] palette_shift = new Color[256];
        private byte[] cmap_grey_brown = null;
        private byte[] colormap = new byte[256];
        private byte[,] dc6_indexed;
		
        private byte[] dc6_file;
		private byte[] act_file; 
		private byte[] color_file; 

        /// <summary>
        /// Initializes D2Palette Class
        /// Send byte arrays from embedded resource.
        /// Shift refers to a color index goes from black -> purple with reds/blues/greens inbetween
        /// </summary>
        /// <param name="byte[] dc6"></param>
		/// <param name="byte[] act"></param>
		/// <param name="byte[] color"></param>
		/// <param name="int shift"></param>		
        public D2Palette(byte[] dc6, byte[] act, byte[] color, int shift)
        {
            dc6_file = dc6; 
			act_file = act; 
			color_file = color; 
            shift_color = shift; 
        }
		
        /// <summary>
        /// Applies the transformation and returns an Image
        /// </summary>			
		public Image Transform()
        {
            LoadHeader();
            IndexDC6();
            LoadPalette();
            PaletteShift();
            return current; 
        }

        void LoadHeader()
        {
            long nb, s; 

            int size = Marshal.SizeOf(typeof(DC6_Header_S));
            IntPtr buffer = Marshal.AllocHGlobal(size);
            try
            {
                Marshal.Copy(dc6_file, 0, buffer, size);
                dc6_header = (DC6_Header_S)Marshal.PtrToStructure(buffer, typeof(DC6_Header_S));
            }
            finally
            {
                Marshal.FreeHGlobal(buffer);
            }

            nb = dc6_header.directions * dc6_header.frames_per_dir;
            s = sizeof(int) * nb;

            size = Marshal.SizeOf(s);
            buffer = Marshal.AllocHGlobal(size);
            try
            {
                Marshal.Copy(dc6_file, Marshal.SizeOf(typeof(DC6_Header_S)), buffer, size);
                dc6_frame_ptr = (int)Marshal.PtrToStructure(buffer, typeof(int));
            }
            finally
            {
                Marshal.FreeHGlobal(buffer);
            }

            size = Marshal.SizeOf(typeof(DC6_FRAME_HEADER_S));
            buffer = Marshal.AllocHGlobal(size);
            try
            {
                Marshal.Copy(dc6_file, dc6_frame_ptr, buffer, size);
                dc6_frame_header = (DC6_FRAME_HEADER_S)Marshal.PtrToStructure(buffer, typeof(DC6_FRAME_HEADER_S));
            }
            finally
            {
                Marshal.FreeHGlobal(buffer);
            }
        }

		void IndexDC6()
        {
           DC6_FRAME_HEADER_S fh;
           long i, i2, pos;
           byte c2; 
           int c, x, y;

           fh = dc6_frame_header;

           dc6_indexed = new byte[fh.width, fh.height];

           if ((fh.width <= 0) || (fh.height <= 0))
           {
              return;
	       }

           dc6_indexed = new byte[(int)fh.width, (int)fh.height];

           pos = dc6_frame_ptr + 32;

           x = 0;
           y = (int)fh.height - 1;

           for ( i = 0; i < fh.length; i++)
           {
              c = dc6_file[pos + i];

              if (c == 0x80)
              {
                 x = 0;
                 y--;
              }
              else if ((c & 0x80) > 0)
	          {
                 x += c & 0x7F;
              }
              else
              {
                 for (i2=0; i2 < c; i2++)
                 {
                     c2 = dc6_file[pos + i];
                     i++;
                     dc6_indexed[x, y] = c2;
                     x++;
                 }
              }
           }
        }		
		
        void LoadPalette()
        {
            for (int i = 0; i < 256; i++)
            {
                Color from_index = Color.FromArgb(255, act_file[i * 3 + 2], act_file[i * 3 + 1], act_file[i * 3]);
                palette[i] = from_index;
            }

            for (int i = 0; i < 256; i++)
            {
                colormap[i] = color_file[shift_color * 256 + i];
                palette_shift[i] = palette[colormap[i]];
            }
        }

        void PaletteShift()
        {
            current = new Bitmap(dc6_frame_header.width, dc6_frame_header.height);

            for (int y = 0; y < dc6_frame_header.height; y++)
            {
                for (int x = 0; x < dc6_frame_header.width; x++)
                {
                    current.SetPixel(x, y, palette_shift[dc6_indexed[x,y]]); 
                }
            }
        }
    }
}

User avatar
Paul Siramy
Retired staff
Principality
Posts: 2828
Joined: Sat May 25, 2002 2:39 pm
Location: La Garenne Colombes (near Paris)
France

Hand-picked

Re: Looking for specific Color Palette

Post by Paul Siramy » Mon Jul 09, 2012 2:39 am

Something suspicious : in IndexDC6() you're reading a byte, but then don't increment the pointer to the next byte :

The code should probably be :

Code: Select all

           for ( i = 0; i < fh.length; i++)
           {
              c = dc6_file[pos + i];
              i++; // adding this line should solve the problem

              if (c == 0x80)

d1ck
Posts: 36
Joined: Wed Mar 09, 2011 7:12 pm

Re: Looking for specific Color Palette

Post by d1ck » Mon Jul 09, 2012 3:49 am

ah you are correct, actually you led me to realize I was doing the whole thing wrong, I shouldn't add +i to pos, i is independent of the character read, I need to increment pos itself, after that it worked perfectly, thanks so much...

if anyone is wondering what to change its replace dc6_file[pos + i];
with dc6_file[pos]; pos++;
there are two occurances

Return to “General Mod Making”