Staredit Network

Staredit Network -> Modding Assistance -> A few questions about MPQs and GRPapi
Report, edit, etc...Posted by fatimid08 on 2006-11-20 at 10:54:29
1. The two first questions relate to SFmpqapi:

- How does priority in archives work?

If two archives have the same file in them (StarDat.mpq and BrooDat.mpq for example) and one has 0 priority, and the other 1 priority (As opened by SFileOpenArchive), when I specify the filename of that particular file and the SFILE_SEARCH_ALL_OPEN flag, it takes the file in the 1 priority archive right? (I'm working on a map editor, and I want to be able to load a mod and load the files it replaces in the StarDat and BrooDat mpqs if they exist, so it becomes possible to load modded .dat files, grps, terrain files, and any other thing I might implement)

- Now about listfiles:

If I open an archive that doesn't have a listfile with the MOAU_MAINTAIN_LISTFILE flag, and I add one right after, does it maintain the listfile I just added when I do modifications or not? Does it check if all the files are represented in the file?

2. Now the GRPapi question:

I don't get how to use the custom drawing functions, if I want to replace every pixel that refers to the index 8 in the color palette by another one, which of the GetPixel/SetPixel function does that, and how exactly do the arguments to those functions work? (how the integer for color is set up for example)

To tell GRPapi to use the custom function, I have to pass a function pointer to the SetFunctionGetPixel/SetFunctionSetPixel functions right?
Report, edit, etc...Posted by ShadowFlare on 2006-11-20 at 14:43:53
QUOTE(fatimid08 @ Nov 20 2006, 09:54 AM)
1. The two first questions relate to SFmpqapi:

- How does priority in archives work?

If two archives have the same file in them (StarDat.mpq and BrooDat.mpq for example) and one has 0 priority, and the other 1 priority (As opened by SFileOpenArchive), when I specify the filename of that particular file and the SFILE_SEARCH_ALL_OPEN flag, it takes the file in the 1 priority archive right? (I'm working on a map editor, and I want to be able to load a mod and load the files it replaces in the StarDat and BrooDat mpqs if they exist, so it becomes possible to load modded .dat files, grps, terrain files, and any other thing I might implement)

Yeah, that's how it works. You can also just pass no archive handle (NULL) to the function instead or use SFileOpenFile.

QUOTE
- Now about listfiles:

If I open an archive that doesn't have a listfile with the MOAU_MAINTAIN_LISTFILE flag, and I add one right after, does it maintain the listfile I just added when I do modifications or not? Does it check if all the files are represented in the file?

Hmm, I think it probably should work to do that. You will need to test it out yourself to be sure, though.

QUOTE
2. Now the GRPapi question:

I don't get how to use the custom drawing functions, if I want to replace every pixel that refers to the index 8 in the color palette by another one, which of the GetPixel/SetPixel function does that, and how exactly do the arguments to those functions work? (how the integer for color is set up for example)

The GetPixel function is only used by GRPapi when you specify the alpha blending flag when calling DrawGrp. In my own programs when I use a custom SetPixel to write to a buffer instead of the screen I often use a custom GetPixel function anyway for reading from the buffer that the custom SetPixel function would write to, just to make it easier and give it a more consistent look in the code. (although, I might not actually set it in GRPapi with SetFunctionGetPixel if I'm not using alpha blending) I'll give an example at the end of this post.

QUOTE
To tell GRPapi to use the custom function, I have to pass a function pointer to the SetFunctionGetPixel/SetFunctionSetPixel functions right?
[right][snapback]592099[/snapback][/right]

Yes, that is how it works.

Here is an example of custom GetPixel and SetPixel functions which read from and write to a buffer. I'll leave out the parts for opening files and just include the drawing part.

CODE
struct BUFFERINFO {
WORD nWidth;
WORD nHeight;
signed short *pBuffer;
WORD nFrame;
};

// This won't get called in this example, it is just for a sample reading function
COLORREF WINAPI ReadPixelFromBuffer(BUFFERINFO *pBI, int X, int Y)
{
return pBI->pBuffer[(pBI->nFrame * pBI->nWidth * pBI->nHeight) + (Y * pBI->nWidth) + X];
}

void WINAPI WritePixelToBuffer(BUFFERINFO *pBI, int X, int Y, COLORREF clrColor)
{
pBI->pBuffer[(pBI->nFrame * pBI->nWidth * pBI->nHeight) + (Y * pBI->nWidth) + X] = (signed short)clrColor;
}

// For this example, I'll assume the caller has already set up everything in lpBuffer
void MyDrawingFunction(HANDLE hGrp, BUFFERINFO lpBuffer, DWORD *dwPalette)
{
int x, y;

// Prefill buffer with some non-color value to distinguish transparent pixels
for (y = 0; y < lpBuffer->nHeight; y++) {
 for (x = 0; x < lpBuffer->nWidth; x++) {
  WritePixelToBuffer(lpBuffer, x, y, (COLORREF)-1);
 }
}

SetFunctionGetPixel((GETPIXELPROC)ReadPixelFromBuffer);
SetFunctionSetPixel((SETPIXELPROC)WritePixelToBuffer);

DrawGrp(hGrp, (HDC)lpBuffer, 0, 0, lpBuffer->nFrame, dwPalette, USE_INDEX, 0);
}


If you want/need an example that just draws to the screen, I'll post that later.
Report, edit, etc...Posted by fatimid08 on 2006-11-20 at 17:44:15
Yes, I just need to change one color index to another (the one for player colors) while drawing to an image or to the screen. I'll be passing an HDC or a .Net Graphics object as argument, depending on how you have to do it.

I do have the code to load palettes and grps (reading filenames from images.tbl) set up, this is the only missing thing before I can draw them.

Here are three other questions:

1. What exactly is the value of dwPalette? Is it a pointer to the first element of the array (as I think you said somewhere), or is it some value that only GRPapi can make sense of?

2. If, somehow, changing the index isn't practical (Let's say I have to use a custom palette and it doesn't have the color I want), I can just change the color directly without using the USE_INDEX parameter? (assuming I know the color of the index in the palette I need to change)

3. Is it possible to load a custom unit palette in Starcraft? (This is to see if I have to support drawing with a custom palette as an option)

Thanks for your help.
Report, edit, etc...Posted by ShadowFlare on 2006-11-21 at 19:43:30
QUOTE(fatimid08 @ Nov 20 2006, 04:44 PM)
Yes, I just need to change one color index to another (the one for player colors) while drawing to an image or to the screen. I'll be passing an HDC or a .Net Graphics object as argument, depending on how you have to do it.

Are you coding this in one of the .NET languages? If so, I have something else you could possibly use if you can't get GRPAPI to work.

QUOTE
I do have the code to load palettes and grps (reading filenames from images.tbl) set up, this is the only missing thing before I can draw them.

Here are three other questions:

1. What exactly is the value of dwPalette? Is it a pointer to the first element of the array (as I think you said somewhere), or is it some value that only GRPapi can make sense of?

It is an array of 256 32-bit unsigned integer values. The functions that use this need to a pointer to the beginning of the array.

QUOTE
2. If, somehow, changing the index isn't practical (Let's say I have to use a custom palette and it doesn't have the color I want), I can just change the color directly without using the USE_INDEX parameter? (assuming I know the color of the index in the palette I need to change)

Yeah, something like that. BTW, I'll give you an example of another custom SetPixel function for GRPAPI. This example assumes that there is an array of 256 color values in a global variable called dwPalette, that there is a global variable named nPlayerColor containing the palette index for a player color, and that DrawGrp was called with the USE_INDEX flag.

CODE
void WINAPI MySetPixel(HDC hDC, int X, int Y, COLORREF clrColor)
{
   if (clrColor == 8) {
       SetPixelV(hDC, X, Y, dwPalette[nPlayerColor]);
   }
   else {
       SetPixelV(hDC, X, Y, dwPalette[clrColor]);
   }
}


Or if you didn't use the USE_INDEX flag:

CODE
void WINAPI MySetPixel(HDC hDC, int X, int Y, COLORREF clrColor)
{
   if (clrColor == dwPalette[8]) {
       SetPixelV(hDC, X, Y, dwPalette[nPlayerColor]);
   }
   else {
       SetPixelV(hDC, X, Y, clrColor);
   }
}


QUOTE
3. Is it possible to load a custom unit palette in Starcraft? (This is to see if I have to support drawing with a custom palette as an option)

Thanks for your help.
[right][snapback]592317[/snapback][/right]

Yes, it is possible. There are multiple files that have to do with palettes in Starcraft. There are .wpe files and then there are some .pcx files that have something to do with the palette.
Report, edit, etc...Posted by fatimid08 on 2006-11-21 at 21:03:32
I'm using VB.Net, unlike VB6, I don't feel like throwing it out the window.

I think I can get it to work, I'll be testing tomorrow; school has a Teacher/Student day, I don't have classes.

I've worked with .wpe files for terrain, though I don't know which is used for units. (I find the unit palette in RetroGRP and the terrain one very similar). I have no idea on how .pcx palettes work, however. I need to load the actual files SC uses, so if they are replaced on a custom MPQ, it's possible for me to load them instead.

QUOTE
  if (clrColor == dwPalette[8]) {
      SetPixelV(hDC, X, Y, dwPalette[nPlayerColor]);
  }
  else {
      SetPixelV(hDC, X, Y, clrColor);
  }

I have no idea what SetPixelV is, but I get the general idea, just render that pixel at the coordinate differently if the condition is met. I definitely will pass a Graphics object then, I find it simpler to used that.

So what you're saying is that when I call this:
Declare Function LoadPalette Lib "Grpapi.dll" (ByVal lpFileName As String, ByRef dwPalette As Integer) As Boolean

it gives me a pointer to the first element of the array, so I could just build the arrays from there if I wanted to.

I'm wondering, since the array is a reference type, by default it passes a pointer to an object, so could it work if I passed an array to the dwPalette argument in DrawGrp?

For the SetFunctionSetPixel, using a .Net delegate told to be marshalled as a function pointer should not cause any problems?

I noticed that I became you for a few minutes. How amazing SEN is. Poor you though, with everyone logged in as ShadowFlare. Maybe Moose or IP are playing with some code and they decided to play a bad joke on you just before fixing some bug?
Report, edit, etc...Posted by ShadowFlare on 2006-11-21 at 21:18:50
VB.NET? Hmm, if you would prefer, maybe I'll post my C# GRP code then. That way you could compile that into a library to be used by your program that would be written in a .NET language and that would use the .NET objects. I created it for the IceCC IDE I'm making. If you still want to use GRPAPI for it, I'll help you with that later/tomorrow. I've never actually tried using it from .NET myself, though.


QUOTE
I noticed that I became you for a few minutes. How amazing SEN is. Poor you though, with everyone logged in as ShadowFlare. Maybe Moose or IP are playing with some code and they decided to play a bad joke on you just before fixing some bug?

lol, you too?
Report, edit, etc...Posted by fatimid08 on 2006-11-22 at 08:13:53
I can use C# no problem, I got both VB and C# 2005 express, thanks a lot.

QUOTE(ShadowFlare)
lol, you too?

Yes, me too. Almost posted here as you before I noticed I wasn't in my account. Imagine, you conversing with yourself...

By the way, if you could tell me which files are used for unit palette, it would be great. I also need the images.dat and sprites.dat specs, I can't find them anywhere. The archived camsys sites seem to have every spec except those two.
Report, edit, etc...Posted by BroodKiller on 2006-11-22 at 11:59:55
Here is sprites.dat:

http://www.smempire.org/specs/sprites_dat.php

With the small remark that the first Unknown property has a meaning: "Is visible".
As for images.dat, you can dif into DatEd's source to get it, PM me if you would like to so that I can give you some hints smile.gif
Report, edit, etc...Posted by fatimid08 on 2006-11-22 at 16:39:53
Ok, from what I can find in your source code:

999 entries in Images.dat

the first 3996 bytes (4/entry) are the entry in images.tbl
the next 999 are GfxTurns, whatever that is
next 999 are Mouse Selection
next 999 are the Use Iscript flag
next 999 are Draw If Cloaked
next 999 are the palette entries
next 999 are the special palette entries
next 3996 are the Iscript IDs
next 3996 are the entry in images.tbl for shield overlays
next 3996 First Overlay
next 3996 Second Overlay
next 3996 Third Overlay
next 3996 Fourth Overlay
next 3996 Fifth Overlay

which all adds up to 37962 bytes.

Checking out the actual program seems to confirm this. Please correct me if I'm wrong.
Report, edit, etc...Posted by BroodKiller on 2006-11-22 at 18:17:44
You're correct, with the only small exception that the "Floats" property is now called "Draw If Cloaked" in the small v1.3b update that I will make soon. Also, I am not entirely sure (check it out in the code) but I think that the pointer to images.tbl is in fact "target-line-in-images.tbl+1" (or minus 1).
Report, edit, etc...Posted by fatimid08 on 2006-11-22 at 18:20:28
QUOTE
"target-line-in-images.tbl+1" (or minus 1)

Um, what is that supposed to mean? That it gives the entry as 1-based or -1-based?
Report, edit, etc...Posted by ShadowFlare on 2006-11-23 at 01:21:29
From what I remember, everywhere (or almost everywhere) the indexes into .tbl files start at 1 rather than 0.

Hmm, I don't have time to get that C# GRP code to you today, but I may be able to in at least a couple of days.
Report, edit, etc...Posted by fatimid08 on 2006-11-23 at 07:42:00
No problem, I won't be implementing the GRP features until I can get to the proper filename in the chain of .dat files. I'm also busy doing other stuff in my code, I underwent a major revamp yesterday to implement undo/redo, and I have a lot of stuff planned. Hopefully, it won't take me a year to release a fully workable version (not like the 2 weeks old alpha version posted on BlizzForums).
Report, edit, etc...Posted by Doodle77(MM) on 2006-11-23 at 09:20:59
QUOTE(ShadowFlare @ Nov 23 2006, 01:21 AM)
From what I remember, everywhere (or almost everywhere) the indexes into .tbl files start at 1 rather than 0.

Hmm, I don't have time to get that C# GRP code to you today, but I may be able to in at least a couple of days.
[right][snapback]593588[/snapback][/right]

Thats because entry zero tends to be the string 'null'
Report, edit, etc...Posted by fatimid08 on 2006-11-23 at 09:38:04
Ok, so it's like the STR section in maps, where if the entry number is 0, it points to a null string, which would mean no image in images.tbl case.
Report, edit, etc...Posted by ShadowFlare on 2006-11-29 at 22:25:32
Heh, if I haven't given you that GRP code by the time you are ready to use it, just let me know and I'll make that first priority until I have it ready to give it to you.
Report, edit, etc...Posted by fatimid08 on 2006-11-30 at 07:52:50
Ok, I'll PM you when I need it. I won't need it for a few days since I got another project (C# Sound Recorder) and some checks and rewrites to do on my code. I really appreciate this.
Next Page (1)